cfengine-3.24.2/0000755000000000000000000000000015010704323013351 5ustar00rootroot00000000000000cfengine-3.24.2/cf-upgrade/0000755000000000000000000000000015010704323015366 5ustar00rootroot00000000000000cfengine-3.24.2/cf-upgrade/log.h0000644000000000000000000000265515010704253016332 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef LOG_H #define LOG_H #include typedef enum { LogCritical, LogNormal, LogVerbose, LogDebug } LogLevel; /** @brief Initializes log system. @param path Log file */ void logInit(); /** @brief Finishes the log system. */ void logFinish(); /** @brief Write a log entry. @param level Log level. @param format Format of the entry @param ... */ void log_entry(LogLevel level, char *format, ...); #endif // LOG_H cfengine-3.24.2/cf-upgrade/Makefile.am0000644000000000000000000000274115010704253017430 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # bin_PROGRAMS = cf-upgrade LIBS= # This tool should not link to anything AM_LDFLAGS= AM_CPPFLAGS=-I$(top_srcdir)/libntech/libutils # platform.h LDADD=../libntech/libcompat/libcompat.la cf_upgrade_SOURCES = \ alloc-mini.c alloc-mini.h \ command_line.c command_line.h \ configuration.c configuration.h \ log.c log.h \ process.c process.h \ update.c update.h \ cf-upgrade.c CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-upgrade/command_line.h0000644000000000000000000000321215010704253020164 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef COMMAND_LINE_H #define COMMAND_LINE_H #include /* * Upper boundary on the number of command line options. * We have 5 modifiers with one argument each (5 * 2 = 10). Then we have * a maximum of CF_UPGRADE_MAX_ARGUMENTS for the upgrade utility itself. */ #define COMMAND_LINE_OPTIONS (10 + CF_UPGRADE_MAX_ARGUMENTS) /** @brief Parsing of the command line arguments. @param argc Number or arguments. @param argv Array containing the arguments. @param configuration Structure containing the configuration @return 0 if successful, -1 if error. */ int parse(int argc, char *argv[], Configuration **configuration); #endif // COMMAND_LINE_H cfengine-3.24.2/cf-upgrade/update.c0000644000000000000000000002550115010704253017021 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include extern char **environ; #ifndef __MINGW32__ /* Unix implementation */ int private_copy_to_temporary_location(const char *source, const char *destination) { struct stat source_stat; int source_fd = -1; int destination_fd = -1; source_fd = open(source, O_RDONLY); if (source_fd < 0) { goto bad_nofd; } fstat(source_fd, &source_stat); unlink (destination); destination_fd = open(destination, O_WRONLY|O_CREAT|O_EXCL, S_IRWXU|S_IRGRP|S_IROTH); if (destination_fd < 0) { goto bad_onefd; } char buffer[1024]; int so_far = 0; do { int this_read = 0; int this_write = 0; this_read = read(source_fd, buffer, sizeof(buffer)); if (this_read < 0) { log_entry(LogCritical, "Failed to read from %s (read so far: %d)", source, so_far); goto bad_twofd; } this_write = write(destination_fd, buffer, this_read); if (this_write < 0) { log_entry(LogCritical, "Failed to write to %s (written so far: %d)", destination, so_far); goto bad_twofd; } if (this_write != this_read) { log_entry(LogCritical, "Short write: read: %d, written: %d (prior progress: %d)", this_read, this_write, so_far); goto bad_twofd; } so_far += this_read; } while (so_far < source_stat.st_size); fsync(destination_fd); close(source_fd); close(destination_fd); return 0; bad_twofd: close(destination_fd); unlink(destination); bad_onefd: close(source_fd); bad_nofd: return -1; } #else /* Windows implementation */ int private_copy_to_temporary_location(const char *source, const char *destination) { struct stat source_stat; int result = 0; int source_fd = -1; int destination_fd = -1; source_fd = open(source, O_BINARY|O_RDONLY); if (source_fd < 0) { goto bad_nofd; } result = fstat(source_fd, &source_stat); unlink (destination); destination_fd = open(destination, O_BINARY|O_WRONLY|O_CREAT|O_EXCL, S_IRWXU); if (destination_fd < 0) { goto bad_onefd; } char buffer[1024]; int so_far = 0; int this_read; do { this_read = read(source_fd, buffer, sizeof(buffer)); if (this_read < 0) { log_entry(LogCritical, "Failed to read from %s (read so far: %d)", source, so_far); goto bad_twofd; } else if (this_read > 0) /* Successful read() */ { so_far += this_read; int this_write = write(destination_fd, buffer, this_read); if (this_write < 0) { log_entry(LogCritical, "Failed to write to %s (written so far: %d)", destination, so_far); goto bad_twofd; } else if (this_write != this_read) { log_entry(LogCritical, "Short write: read: %d, written: %d (prior progress: %d)", this_read, this_write, so_far); goto bad_twofd; } } } while (this_read > 0); assert(this_read == 0); if (so_far != source_stat.st_size) { log_entry(LogCritical, "Unexpected, file is at EOF while %d out of %d bytes have been read", so_far, source_stat.st_size); log_entry(LogCritical, "Trying to continue, maybe it changed size while reading"); } close(source_fd); close(destination_fd); return 0; bad_twofd: close(destination_fd); unlink(destination); bad_onefd: close(source_fd); bad_nofd: return -1; } #endif int copy_to_temporary_location(const char *source, const char *destination) { if (!source || !destination) { return -1; } return private_copy_to_temporary_location(source, destination); } int perform_backup(const char *backup_tool, const char *backup_path, const char *cfengine) { char **args = NULL; char *envp[] = { NULL }; args = xcalloc(4 + 1, sizeof(char *)); args[0] = xstrdup(backup_tool); args[1] = xstrdup("BACKUP"); args[2] = xstrdup(backup_path); args[3] = xstrdup(cfengine); args[4] = NULL; int result = 0; result = run_process_wait(backup_tool, args, envp); free (args[0]); free (args[1]); free (args[2]); free (args[3]); free (args); return result; } int perform_restore(const char *backup_tool, const char *backup_path, const char *cfengine) { char **args = NULL; char *envp[] = { NULL }; args = xcalloc(4 + 1, sizeof(char *)); args[0] = xstrdup(backup_tool); args[1] = xstrdup("RESTORE"); args[2] = xstrdup(backup_path); args[3] = xstrdup(cfengine); args[4] = NULL; int result = 0; result = run_process_wait(backup_tool, args, envp); free (args[0]); free (args[1]); free (args[2]); free (args[3]); free (args); return result; } /* * The update loop goes like this: * 1. Copy this program to a temporary location (by default /tmp/cf-upgrade). * 2. Execute this program requesting to perform the upgrade. * The following steps happen on the new copy: * 3. Run the backup script. * 4. Run the upgrade command. * 4a If success, finish. * 4b If failure, run the restore command from the backup script. */ int RunUpdate(const Configuration *configuration) { if (!configuration) { return -1; } int result = 0; bool upgrade = ConfigurationPerformUpdate(configuration); if (upgrade) { /* Perform the upgrade */ /* first perform the backup */ const char *backup_path = ConfigurationBackupPath(configuration); const char *backup_tool = ConfigurationBackupTool(configuration); const char *cfengine = ConfigurationCFEnginePath(configuration); log_entry(LogVerbose, "Performing backup of '%s' to '%s' using '%s'", cfengine, backup_path, backup_tool); result = perform_backup(backup_tool, backup_path, cfengine); if (result != 0) { log_entry(LogCritical, "Failed to backup %s to %s using %s", cfengine, backup_path, backup_tool); return -1; } log_entry(LogVerbose, "Backup successful"); /* run the upgrade process */ const char *command = ConfigurationCommand(configuration); char *args[CF_UPGRADE_MAX_ARGUMENTS + 1]; int i = 0; int total = ConfigurationNumberOfArguments(configuration); for (i = 0; i < total; ++i) { args[i] = xstrdup(ConfigurationArgument(configuration, i)); } args[total] = NULL; log_entry(LogVerbose, "Running upgrade command: %s", command); result = run_process_wait(command, args, environ); /* Check that everything went according to plan */ if (result == 0) { log_entry(LogNormal, "Upgrade succeeded!"); return 0; } else { log_entry(LogCritical, "Upgrade failed! Performing restore..."); /* Well, that is why we have a backup */ result = perform_restore(backup_tool, backup_path, cfengine); if (result == 0) { log_entry(LogNormal, "Restore successful. " "CFEngine has been successfully reverted to the previous version."); return -1; } else { log_entry(LogCritical, "Failed to restore %s from %s using %s. " "Your CFEngine installation might be damaged now.", cfengine, backup_path, backup_tool); return -2; } } } else { /* Copy and run the copy */ const char *copy = ConfigurationCopy(configuration); const char *current = ConfigurationCFUpgrade(configuration); log_entry(LogVerbose, "Copying '%s' to '%s'", current, copy); result = copy_to_temporary_location(current, copy); if (result < 0) { log_entry (LogCritical, "Could not copy %s to %s", current, copy); return -1; } /* prepare the data for running the copy */ char *args[COMMAND_LINE_OPTIONS + 1]; int counter = 0; args[counter++] = xstrdup(ConfigurationCopy(configuration)); args[counter++] = xstrdup("-b"); args[counter++] = xstrdup(ConfigurationBackupTool(configuration)); args[counter++] = xstrdup("-f"); args[counter++] = xstrdup(ConfigurationCFEnginePath(configuration)); args[counter++] = xstrdup("-s"); args[counter++] = xstrdup(ConfigurationBackupPath(configuration)); /* set the perform update flag and copy the arguments */ args[counter++] = xstrdup("-x"); int i = 0; int total = ConfigurationNumberOfArguments(configuration); for (i = 0; i < total; ++i) { args[counter + i] = xstrdup(ConfigurationArgument(configuration, i)); } /* Replace current process with the copy. */ args[counter + total] = NULL; log_entry(LogVerbose, "Reexecuting cf-upgrade from the copy: %s", copy); /* Effectively this does execvp(), i.e. preserves current environment. */ result = run_process_replace(copy, args, environ); } assert(false); /* unreachable */ return -1; } cfengine-3.24.2/cf-upgrade/update.h0000644000000000000000000000264215010704253017027 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef UPDATE_H #define UPDATE_H #include /** @brief Update logic Although cf-update is a lightweight tool, there is some logic that makes sure that the update process goes according to plan. */ /** @brief Run update process with the corresponding parameters @param configuration Update configuration @return 0 if successful, -1 if not. */ int RunUpdate(const Configuration *configuration); #endif // UPDATE_H cfengine-3.24.2/cf-upgrade/cf-upgrade.c0000644000000000000000000000440415010704253017553 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #define CF_UPGRADE_VERSION "1.0.0" void usage() { puts("Usage: cf-upgrade [-c copy] <-b backup tool> <-s backup path> " "[-f CFEngine Folder] <-i command + arguments>"); puts("Usage: cf-upgrade -h: help"); puts("Usage: cf-upgrade -v: version"); puts("More detailed help can be found in the accompanying README.md file."); } int main(int argc, char **argv) { int result = 0; Configuration *configuration = NULL; logInit(); log_entry(LogVerbose, "Starting %s", argv[0]); result = parse(argc, argv, &configuration); if (result < 0) { usage(); return 1; } if (ConfigurationVersion(configuration)) { char version[] = CF_UPGRADE_VERSION; printf("cf-upgrade %s\n", version); return 0; } if (ConfigurationHelp(configuration)) { usage(); return 0; } result = RunUpdate(configuration); log_entry(LogVerbose, "Finished %s", argv[0]); logFinish(); return (result == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } cfengine-3.24.2/cf-upgrade/configuration.c0000644000000000000000000001463015010704253020407 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #define CF_UPGRADE_COPY "/tmp/cf-upgrade" #define CF_UPGRADE_CFENGINE "/var/cfengine/" struct Configuration { char *cf_upgrade; /*!< Path to cf-upgrade binary */ char *backup_tool; /*!< Path to the backup script */ char *backup_path; /*!< Path to the backup archive */ char *copy_path; /*!< Path to the copy of cf-upgrade, default /tmp/cf-upgrade */ char *cfengine_path; /*!< CFEngine folder, default /var/cfengine */ int number_of_arguments; /*!< Number of arguments to the upgrade command */ bool perform_update; /*!< Internal flag, whether to copy and fork or not */ char *arguments[CF_UPGRADE_MAX_ARGUMENTS]; /*!< upgrade command and arguments */ bool help; /*!< Internal flag, whether to print the help message or not */ bool version; /*!< Internal flag, whether to print the version or not */ }; Configuration *ConfigurationNew() { Configuration *configuration = NULL; configuration = xcalloc(1, sizeof(Configuration)); configuration->copy_path = xstrdup(CF_UPGRADE_COPY); configuration->cfengine_path = xstrdup(CF_UPGRADE_CFENGINE); return configuration; } void ConfigurationDestroy(Configuration **configuration) { if (!configuration || !*configuration) { return; } Configuration *config = *configuration; for (int i = 0; i < config->number_of_arguments; ++i) { free(config->arguments[i]); config->arguments[i] = NULL; } free(config->cf_upgrade); free(config->backup_path); free(config->backup_tool); free(config->copy_path); free(config->cfengine_path); free(config); *configuration = NULL; } const char *ConfigurationBackupTool(const Configuration *configuration) { return configuration ? configuration->backup_tool : NULL; } void ConfigurationSetBackupTool(Configuration *configuration, char *path) { if (!configuration || !path) { return; } free (configuration->backup_tool); configuration->backup_tool = xstrdup(path); } const char *ConfigurationBackupPath(const Configuration *configuration) { return configuration ? configuration->backup_path : NULL; } void ConfigurationSetBackupPath(Configuration *configuration, char *path) { if (!configuration || !path) { return; } free (configuration->backup_path); configuration->backup_path = xstrdup(path); } const char *ConfigurationCopy(const Configuration *configuration) { return configuration ? configuration->copy_path : NULL; } void ConfigurationSetCopy(Configuration *configuration, char *path) { if (!configuration || !path) { return; } free (configuration->copy_path); configuration->copy_path = xstrdup(path); } const char *ConfigurationCFUpgrade(const Configuration *configuration) { return configuration ? configuration->cf_upgrade : NULL; } void ConfigurationSetCFUpgrade(Configuration *configuration, char *path) { if (!configuration || !path) { return; } free (configuration->cf_upgrade); configuration->cf_upgrade = xstrdup(path); } const char *ConfigurationCFEnginePath(const Configuration *configuration) { return configuration ? configuration->cfengine_path : NULL; } void ConfigurationSetCFEnginePath(Configuration *configuration, char *path) { if (!configuration || !path) { return; } free (configuration->cfengine_path); configuration->cfengine_path = xstrdup(path); } const char *ConfigurationCommand(const Configuration *configuration) { return configuration ? configuration->arguments[0] : NULL; } const char *ConfigurationArgument(const Configuration *configuration, int number) { if (!configuration || (number < 0) || (number >= configuration->number_of_arguments)) { return NULL; } return configuration->arguments[number]; } void ConfigurationAddArgument(Configuration *configuration, char *argument) { if (!configuration || !argument) { return; } if (configuration->number_of_arguments < CF_UPGRADE_MAX_ARGUMENTS) { configuration->arguments[configuration->number_of_arguments] = xstrdup(argument); ++configuration->number_of_arguments; } else { log_entry(LogCritical, "A maximum of %d arguments can be specified, aborting", CF_UPGRADE_MAX_ARGUMENTS); exit(EXIT_FAILURE); } } int ConfigurationNumberOfArguments(const Configuration *configuration) { return configuration ? configuration->number_of_arguments : -1; } bool ConfigurationPerformUpdate(const Configuration *configuration) { return configuration ? configuration->perform_update : false; } void ConfigurationSetPerformUpdate(Configuration *configuration, bool perform) { if (configuration) { configuration->perform_update = perform; } } bool ConfigurationVersion(Configuration *configuration) { return configuration ? configuration->version : false; } void ConfigurationSetVersion(Configuration *configuration, bool version) { if (configuration) { configuration->version = version; } } bool ConfigurationHelp(Configuration *configuration) { return configuration ? configuration->help : false; } void ConfigurationSetHelp(Configuration *configuration, bool help) { if (configuration) { configuration->help = help; } } cfengine-3.24.2/cf-upgrade/process.h0000644000000000000000000000412715010704253017223 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef PROCESS_H #define PROCESS_H #define RUN_PROCESS_FAILURE_VALUE -10 #define RUN_PROCESS_FAILURE(x) \ (x == RUN_PROCESS_FAILURE_VALUE) ? true : false; /** @brief Runs the specified process by replacing the current one. @param command Full path of the command to run. @param args Arguments for the program @param envp Environment to use. @return The exit status of the process or a negative value in case of error. @remarks This function does not return, unless there was an error. */ int run_process_replace(const char *command, char **args, char **envp); /** @brief Runs the specified process and redirects the output to a file, waiting for the process to terminate. @param command Full path of the command to run. @param args Arguments for the program @param envp Environment to use. @return The exit status of the process or a negative value in case of error. @remarks Use RUN_PROCESS_FAILURE with the return value of this method to detect if the error was caused by the process or the function itself. */ int run_process_wait(const char *command, char **args, char **envp); #endif // PROCESS_H cfengine-3.24.2/cf-upgrade/alloc-mini.h0000644000000000000000000000231115010704253017562 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef ALLOC_H #define ALLOC_H /* * Copied from libutils to avoid having a dependency to it. */ #include void *xcalloc(size_t nmemb, size_t size); void *xmalloc(size_t size); char *xstrdup(const char *str); #endif cfengine-3.24.2/cf-upgrade/log.c0000644000000000000000000001004215010704253016312 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_LOG_ENTRY_SIZE 4096 static FILE *LOG_STREAM = NULL; static LogLevel CURRENT_LEVEL = LogVerbose; static char *prepare_message(char *format, va_list args) { char *message = NULL; int message_size = 0; char timestamp[] = "YYYY/MM/DD HH:MM:SS"; char buffer[MAX_LOG_ENTRY_SIZE]; struct tm now; time_t now_seconds = time(NULL); gmtime_r(&now_seconds, &now); int timestamp_size = sizeof(timestamp); message_size = vsnprintf(buffer, MAX_LOG_ENTRY_SIZE - 1, format, args); strftime(timestamp, timestamp_size, "%Y/%m/%d %H:%M:%S", &now); /* '[' + ']' + ' ' + '\0' */ const size_t buf_size = message_size + timestamp_size + 3 + 1; message = xmalloc(buf_size); snprintf(message, buf_size, "[%s] %s", timestamp, buffer); return message; } static void write_console_log_entry(const char *message) { puts(message); } static void write_file_log_entry(const char *message) { if (LOG_STREAM != NULL) { fputs(message, LOG_STREAM); fputs("\n", LOG_STREAM); fflush(LOG_STREAM); } } static void private_log_init() { char path[] = "cf-upgrade-YYYYMMDD-HHMMSS.log"; struct tm now; time_t now_seconds = time(NULL); gmtime_r(&now_seconds, &now); int log_fd = -1; strftime(path, sizeof(path), "cf-upgrade-%Y%m%d-%H%M%S.log", &now); #ifndef __MINGW32__ log_fd = open(path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); #else log_fd = open(path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); #endif if (log_fd < 0) { puts("Could not initialize log file, only console messages will be printed"); return; } #ifndef __MINGW32__ /* * cf-upgrade spawns itself, therefore to avoid log confusion we need to * make sure that the log is closed when we call exeve. */ int result = 0; result = fcntl(log_fd, F_GETFD); if (result < 0) { puts("Could not initialize log file, only console messages will be printed"); return; } result = fcntl(log_fd, F_SETFD, result | FD_CLOEXEC); if (result < 0) { puts("Could not initialize log file, only console messages will be printed"); return; } #endif LOG_STREAM = fdopen(log_fd, "a"); } void logInit() { private_log_init(); } void logFinish() { if (LOG_STREAM) { fclose(LOG_STREAM); } } void log_entry(LogLevel level, char *format, ...) { if (level > CURRENT_LEVEL) { return; } va_list ap; va_start(ap, format); char *message = prepare_message(format, ap); va_end(ap); switch (level) { case LogCritical: case LogNormal: case LogVerbose: write_console_log_entry(message); write_file_log_entry(message); break; case LogDebug: write_file_log_entry(message); break; } free(message); } cfengine-3.24.2/cf-upgrade/Makefile.in0000644000000000000000000006004215010704300017430 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = cf-upgrade$(EXEEXT) subdir = cf-upgrade ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_cf_upgrade_OBJECTS = alloc-mini.$(OBJEXT) command_line.$(OBJEXT) \ configuration.$(OBJEXT) log.$(OBJEXT) process.$(OBJEXT) \ update.$(OBJEXT) cf-upgrade.$(OBJEXT) cf_upgrade_OBJECTS = $(am_cf_upgrade_OBJECTS) cf_upgrade_LDADD = $(LDADD) cf_upgrade_DEPENDENCIES = ../libntech/libcompat/libcompat.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cf_upgrade_SOURCES) DIST_SOURCES = $(cf_upgrade_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = # This tool should not link to anything LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ AM_LDFLAGS = AM_CPPFLAGS = -I$(top_srcdir)/libntech/libutils # platform.h LDADD = ../libntech/libcompat/libcompat.la cf_upgrade_SOURCES = \ alloc-mini.c alloc-mini.h \ command_line.c command_line.h \ configuration.c configuration.h \ log.c log.h \ process.c process.h \ update.c update.h \ cf-upgrade.c CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-upgrade/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-upgrade/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-upgrade$(EXEEXT): $(cf_upgrade_OBJECTS) $(cf_upgrade_DEPENDENCIES) $(EXTRA_cf_upgrade_DEPENDENCIES) @rm -f cf-upgrade$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_upgrade_OBJECTS) $(cf_upgrade_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc-mini.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-upgrade.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command_line.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/configuration.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-upgrade/alloc-mini.c0000644000000000000000000000337015010704253017563 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /* * Copied from libutils to avoid having a dependency to it. */ static void *CheckResult(void *ptr, const char *fn, bool check_result) { if ((ptr == NULL) && (check_result)) { fputs(fn, stderr); fputs(": Unable to allocate memory\n", stderr); exit(255); /* no cleanup() functions are registered so exit() is OK */ } return ptr; } void *xmalloc(size_t size) { return CheckResult(malloc(size), "xmalloc", size != 0); } void *xcalloc(size_t nmemb, size_t size) { return CheckResult(calloc(nmemb, size), "xcalloc", (nmemb != 0) && (size != 0)); } char *xstrdup(const char *str) { return CheckResult(strdup(str), "xstrdup", true); } cfengine-3.24.2/cf-upgrade/command_line.c0000644000000000000000000001174015010704253020164 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #define COPY_PARAM "-c" #define BACKUP_TOOL_PARAM "-b" #define BACKUP_PATH_PARAM "-s" #define CFENGINE_PATH "-f" #define UPDATE_ARGS "-i" #define UPDATE_2ND_ARGS "-x" #define HELP_REQUESTED "-h" #define VERSION_REQUESTED "-v" int parse(int argc, char *argv[], Configuration **configuration) { if (!configuration || !argv || (argc < 2)) { log_entry(LogDebug, "configuration or argv are NULL"); return -1; } /* Create the configuration structure */ *configuration = ConfigurationNew(); /* The first value is the current executable */ ConfigurationSetCFUpgrade(*configuration, argv[0]); /* Some flags to check for errors */ bool backup_tool = false; bool command_arguments = false; bool backup_path = false; int i = 1; do { char *current = argv[i]; log_entry(LogDebug, "current: %s", current); if (0 == strcmp(COPY_PARAM, current)) { char *copy = argv[i + 1]; log_entry(LogDebug, "copy: %s", copy); ConfigurationSetCopy(*configuration, copy); i += 2; } else if (0 == strcmp(HELP_REQUESTED, current)) { log_entry(LogDebug, "help requested"); ConfigurationSetHelp(*configuration, 1); return 0; } else if (0 == strcmp(VERSION_REQUESTED, current)) { log_entry(LogDebug, "version requested"); ConfigurationSetVersion(*configuration, 1); return 0; } else if (0 == strcmp(BACKUP_TOOL_PARAM, current)) { char *path = argv[i + 1]; log_entry(LogDebug, "backup tool: %s", path); ConfigurationSetBackupTool(*configuration, path); i += 2; backup_tool = 1; } else if (0 == strcmp(BACKUP_PATH_PARAM, current)) { char *path = argv[i + 1]; log_entry(LogDebug, "backup path: %s", path); ConfigurationSetBackupPath(*configuration, path); i += 2; backup_path = true; } else if (0 == strcmp(CFENGINE_PATH, current)) { char *path = argv[i + 1]; log_entry(LogDebug, "cfengine path: %s", path); ConfigurationSetCFEnginePath(*configuration, path); i += 2; } /* * Once we find the -i/-x command we stop parsing and assume that * the rest is just update command and its arguments. */ else if (0 == strcmp(UPDATE_ARGS, current)) { log_entry(LogDebug, "Copying and forking"); int j = 0; for (j = i + 1; j < argc; ++j) { command_arguments = 1; char *argument = argv[j]; log_entry(LogDebug, "argument: %s", argument); ConfigurationAddArgument(*configuration, argument); } break; } else if (0 == strcmp(UPDATE_2ND_ARGS, current)) { log_entry(LogDebug, "Performing upgrade"); int j = 0; for (j = i + 1; j < argc; ++j) { command_arguments = 1; char *argument = argv[j]; log_entry(LogDebug, "argument: %s", argument); ConfigurationAddArgument(*configuration, argument); } ConfigurationSetPerformUpdate(*configuration, true); break; } else { log_entry (LogCritical, "Unrecognized option: %s", current); ConfigurationDestroy(configuration); return -1; } } while (i < argc); if (!backup_tool || !command_arguments || !backup_path) { log_entry(LogCritical, "Need to specify -s, -b and -i"); ConfigurationDestroy(configuration); return -1; } log_entry(LogDebug, "parsed %d options", i); return 0; } cfengine-3.24.2/cf-upgrade/process.c0000644000000000000000000002217715010704253017223 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* Different includes for Unix and Windows */ #ifndef __MINGW32__ #include #else /* * According to the documentation, the access rights given to the caller * process (what would be the parent process in Unix) suffered a modification * in Windows 2008 and upwards. The ALL_ACCESS flag changed value, therefore * to keep backward compatibility we need to define the supported OS to the * lowest OS level we want to support. * If this is not defined, then we will have problems in Windows 2003. * Yes, this is the right value there is no WIN2003 flag. */ #define _WIN32_WINNT _WIN32_WINNT_WINXP #include #include #include #endif // __MINGW32__ This covers both 32 and 64 bits MinGW #ifndef __MINGW32__ /* Unix implementation */ int private_run_process_replace(const char *command, char **args, char **envp) { /* Execute the command */ execve(command, args, envp); /* If we reach here, then we have already failed */ log_entry(LogCritical, "Temporary copy failed to run, aborting"); return -1; } /* * Due to differences between Unixes and Windows, this code can only * be compiled in Unix. * Basically this code waits for the child process to die and then * returns the status. In Windows we cannot do that because Windows does * not have that kind of information. And the only kind of information * that is available is by using their calls, therefore we implement this * differently for Windows. * This site contains more information: * http://www.interopcommunity.com/dictionary/waitpid-entry.php */ int private_run_process_wait(const char *command, char **args, char **envp) { char *filename = basename(xstrdup(command)); const time_t now_seconds = time(NULL); struct tm now; gmtime_r(&now_seconds, &now); size_t filenamelog_size = (strlen(filename) + strlen("-YYYYMMDD-HHMMSS") + strlen(".log") + 1); char *filenamelog = xmalloc(filenamelog_size); snprintf(filenamelog, filenamelog_size, "%s-%04d%02d%02d-%02d%02d%02d.log", filename, now.tm_year + 1900, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec); int exit_status = 0; pid_t child = fork(); if (child < 0) { log_entry(LogCritical, "Could not fork child process: %s", command); return RUN_PROCESS_FAILURE_VALUE; } else if (child == 0) { execve(command, args, envp); /* If we reach here, the we failed */ log_entry(LogCritical, "Could not execute helper process %s", command); exit(-1); } else { /* Parent */ int status = -1; free(filenamelog); waitpid(child, &status, 0); if (WIFEXITED(status)) { exit_status = WEXITSTATUS(status); } } return exit_status; } #else /* * Windows implementations. * The Windows implementations were taken from Microsoft's documentation and * modified accordingly to fit our purposes. */ static void args_to_command_line(char *command_line, char **args, unsigned long command_line_size) { /* * Windows does not use an array for the command line arguments, but * a string. Therefore we need to revert the parsing we did before and * build the string. */ /* TODO put arguments in quotes! */ command_line[0] = '\0'; char *arg; while ((arg = *args) != NULL) { strlcat(command_line, arg, command_line_size); /* Add a space before the next argument */ strlcat(command_line, " ", command_line_size); args++; } } int private_run_process_replace(const char *command, char **args, char **envp) { STARTUPINFO si; PROCESS_INFORMATION pi; char command_line[32768]; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); ZeroMemory( command_line, sizeof(command_line) ); args_to_command_line(command_line, args, sizeof(command_line)); log_entry(LogVerbose, "Creating process with command line: %s", command_line); // Start the child process. if( !CreateProcess( command, // No module name (use command line) command_line, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { log_entry(LogCritical, "Temporary copy failed to run, aborting"); return -1; } /* * The fork-exec paradigm does not exist in Windows. Basically once a process * is created, there is no parent-child relationship as in Unix, the two * processes are independent. So, now we just need to exit the parent process * and hope for the best. Notice that if the process failed to start we * would have caught it in the if loop above. */ exit(EXIT_SUCCESS); } /* * There is an interesting difference in the Windows way of doing things versus * the Unix way. On Windows, programs usually do not use STDOUT or STDERR because * they have other reporting mechanisms. In addition the installers we run * are run using the silent flags, so they do not disturb the user. Therefore * there is no need to redirect the output to a log file. */ int private_run_process_wait(const char *command, char **args, char **envp) { STARTUPINFO si; PROCESS_INFORMATION pi; char command_line[32768]; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); ZeroMemory( command_line, sizeof(command_line) ); args_to_command_line(command_line, args, sizeof(command_line)); log_entry(LogVerbose, "Creating process with command line: %s", command_line); // Start the child process. if( !CreateProcess( command, // No module name (use command line) command_line, // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { log_entry(LogCritical, "Could not create child process: %s", command); return RUN_PROCESS_FAILURE_VALUE; } // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); /* Get exit status */ DWORD exit_status = 0; if ( !GetExitCodeProcess( pi.hProcess, &exit_status) ) { log_entry(LogCritical, "Could not get exit status from process: %s", command); } // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); return (int)exit_status; } #endif int run_process_replace(const char *command, char **args, char **envp) { if (!command || !args || !envp) { return -1; } return private_run_process_replace(command, args, envp); } int run_process_wait(const char *command, char **args, char **envp) { if (!command || !args || !envp) { return RUN_PROCESS_FAILURE_VALUE; } return private_run_process_wait(command, args, envp); } cfengine-3.24.2/cf-upgrade/configuration.h0000644000000000000000000001305415010704253020413 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CONFIGURATION_H #define CONFIGURATION_H #include #define CF_UPGRADE_MAX_ARGUMENTS 32 typedef struct Configuration Configuration; /** @brief Creates a new Configuration structure. @return A new Configuration structure or NULL in case of error. */ Configuration *ConfigurationNew(); /** @brief Destroys a Configuration structure. @param configuration Structure to be destroyed. */ void ConfigurationDestroy(Configuration **configuration); /** @brief Backup tool path. @param configuration Structure. @return The path of the backup tool, or NULL in case of error. */ const char *ConfigurationBackupTool(const Configuration *configuration); /** @brief Sets the backup tool path. @param configuration Structure. @param path Path of the backup tool. */ void ConfigurationSetBackupTool(Configuration *configuration, char *path); /** @brief Path to create the backup archive. @param configuration Structure. @return A const char to the path of the backup or NULL in case of error. */ const char *ConfigurationBackupPath(const Configuration *configuration); /** @brief Sets the path to write the backup archive. @param configuration Structure. @param path Path to the backup archive. */ void ConfigurationSetBackupPath(Configuration *configuration, char *path); /** @brief Path to cf-upgrade. @param configuration Structure. @return A const char to the path of cf-upgrade or NULL in case of error. */ const char *ConfigurationCFUpgrade(const Configuration *configuration); /** @brief Sets the path to cf-upgrade. @param configuration Structure. @param path Path to cf-upgrade. */ void ConfigurationSetCFUpgrade(Configuration *configuration, char *path); /** @brief Path to the copy of cf-upgrade. @param configuration Structure. @return A const char to the path of the copy or NULL in case of error. */ const char *ConfigurationCopy(const Configuration *configuration); /** @brief Sets the path to the copy of cf-update. @param configuration Structure. @param path Path to the copy of cf-update. */ void ConfigurationSetCopy(Configuration *configuration, char *path); /** @brief CFEngine path, by default /var/cfengine. @param configuration Structure. @return A const char to the path of CFEngine or NULL in case of error. */ const char *ConfigurationCFEnginePath(const Configuration *configuration); /** @brief Sets the CFEngine path. @param configuration Structure. @param path Path to CFEngine. */ void ConfigurationSetCFEnginePath(Configuration *configuration, char *path); /** @brief Command to run to perform the actual update. @param configuration Structure. @return A const char to the command to run the update process. */ const char *ConfigurationCommand(const Configuration *configuration); /** @brief Arguments for the update command. @param configuration Structure. @return A const char pointer the nth Argument. */ const char *ConfigurationArgument(const Configuration *configuration, int number); /** @brief Sets the arguments for the update command. @remarks At most 31 parameters can be passed to the update command. @param configuration Structure. @param argument The argument to add to the arguments. */ void ConfigurationAddArgument(Configuration *configuration, char *argument); /** @brief Number of arguments to the upgrade command. @param configuration Structure. @return The number of arguments for the update command or -1 in case of error. */ int ConfigurationNumberOfArguments(const Configuration *configuration); /** @brief Whether we should perform update or copy. @param configuration Structure. @return True if update, false otherwise. */ bool ConfigurationPerformUpdate(const Configuration *configuration); /** @brief Sets whether we should perform update or copy. @param configuration Structure. @param perform True if update should be performed. */ void ConfigurationSetPerformUpdate(Configuration *configuration, bool perform); /** @brief cf-upgrade version @param configuration @return True if version was requested, false in other case. */ bool ConfigurationVersion(Configuration *configuration); /** @brief Sets the version requested flag. @param configuration */ void ConfigurationSetVersion(Configuration *configuration, bool version); /** @brief cf-upgrade help @param configuration @return True if help was requested, false in other case. */ bool ConfigurationHelp(Configuration *configuration); /** @brief Sets the help requested flag. @param configuration */ void ConfigurationSetHelp(Configuration *configuration, bool help); #endif // CONFIGURATION_H cfengine-3.24.2/cf-execd/0000755000000000000000000000000015010704322015026 5ustar00rootroot00000000000000cfengine-3.24.2/cf-execd/execd-config.c0000644000000000000000000001434315010704253017535 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include /* CFS_CONTROLBODY, SERVER_CONTROL_CFRUNCOMMAND */ #include /* ExpandScalar() */ /* Get a number in the interval [0, 1) for a calculation of a pseudo-random delay */ static double GetSplay(void) { char splay[CF_BUFSIZE]; snprintf(splay, CF_BUFSIZE, "%s+%s+%ju", VFQNAME, VIPADDRESS, (uintmax_t)getuid()); return ((double) MIN(StringHash(splay, 0), UINT_MAX - 1)) / UINT_MAX; } ExecdConfig *ExecdConfigNew(const EvalContext *ctx, const Policy *policy) { ExecdConfig *execd_config = xcalloc(1, sizeof(ExecdConfig)); execd_config->schedule = StringSetNew(); StringSetAdd(execd_config->schedule, xstrdup("Min00")); StringSetAdd(execd_config->schedule, xstrdup("Min05")); StringSetAdd(execd_config->schedule, xstrdup("Min10")); StringSetAdd(execd_config->schedule, xstrdup("Min15")); StringSetAdd(execd_config->schedule, xstrdup("Min20")); StringSetAdd(execd_config->schedule, xstrdup("Min25")); StringSetAdd(execd_config->schedule, xstrdup("Min30")); StringSetAdd(execd_config->schedule, xstrdup("Min35")); StringSetAdd(execd_config->schedule, xstrdup("Min40")); StringSetAdd(execd_config->schedule, xstrdup("Min45")); StringSetAdd(execd_config->schedule, xstrdup("Min50")); StringSetAdd(execd_config->schedule, xstrdup("Min55")); execd_config->splay_time = 0; execd_config->log_facility = xstrdup("LOG_USER"); execd_config->runagent_allow_users = StringSetNew(); Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_EXECUTOR); if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_executor"); DataType t; const void *value = EvalContextVariableGet(ctx, ref, &t); VarRefDestroy(ref); if (t == CF_DATA_TYPE_NONE) { ProgrammingError("Unknown attribute '%s' in control body," " should have already been stopped by the parser", cp->lval); } if (StringEqual(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_EXECUTORFACILITY].lval)) { free(execd_config->log_facility); execd_config->log_facility = xstrdup(value); Log(LOG_LEVEL_DEBUG, "executorfacility '%s'", execd_config->log_facility); } else if (StringEqual(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SPLAYTIME].lval)) { int time = IntFromString(value); execd_config->splay_time = (int) (time * SECONDS_PER_MINUTE * GetSplay()); } else if (StringEqual(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SCHEDULE].lval)) { Log(LOG_LEVEL_DEBUG, "Loading user-defined schedule..."); StringSetClear(execd_config->schedule); for (const Rlist *rp = value; rp; rp = rp->next) { StringSetAdd(execd_config->schedule, xstrdup(RlistScalarValue(rp))); Log(LOG_LEVEL_DEBUG, "Adding '%s'", RlistScalarValue(rp)); } } else if (StringEqual(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_RUNAGENT_ALLOW_USERS].lval)) { assert(t == CF_DATA_TYPE_STRING_LIST); /* should be enforced by parser */ for (const Rlist *rp = value; rp; rp = rp->next) { Log(LOG_LEVEL_DEBUG, "User '%s' allowed to use the runagent.socket", RlistScalarValue(rp)); StringSetAdd(execd_config->runagent_allow_users, xstrdup(RlistScalarValue(rp))); } } } } /* We need to pull the 'cfruncommand' value from 'body control server' for * local run-agent requests. */ constraints = ControlBodyConstraints(policy, AGENT_TYPE_SERVER); if (constraints != NULL) { const size_t length = SeqLength(constraints); for (size_t i = 0; i < length; i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } if (StringEqual(cp->lval, CFS_CONTROLBODY[SERVER_CONTROL_CFRUNCOMMAND].lval)) { assert(cp->rval.type == RVAL_TYPE_SCALAR); execd_config->local_run_command = ExpandScalar(ctx, NULL, NULL, RvalScalarValue(cp->rval), NULL); break; } } } return execd_config; } void ExecdConfigDestroy(ExecdConfig *execd_config) { if (execd_config != NULL) { free(execd_config->log_facility); StringSetDestroy(execd_config->schedule); StringSetDestroy(execd_config->runagent_allow_users); free(execd_config->local_run_command); } free(execd_config); } cfengine-3.24.2/cf-execd/cf-execd-runner.h0000644000000000000000000000225015010704253020166 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CF_EXECD_RUNNER_H #define CFENGINE_CF_EXECD_RUNNER_H #include void LocalExec(const ExecConfig *config); int ConnectToSmtpSocket(const ExecConfig *config); #endif cfengine-3.24.2/cf-execd/Makefile.am0000644000000000000000000000417215010704253017071 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-execd.la libcf-execd-test.la AM_CPPFLAGS = \ -I$(srcdir)/../libpromises \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libenv \ -I$(srcdir)/../cf-check \ $(PCRE2_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(PCRE2_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(PTHREAD_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_execd_la_LIBADD = ../libpromises/libpromises.la libcf_execd_la_SOURCES = \ cf-execd.c cf-execd.h \ cf-execd-runner.c cf-execd-runner.h \ exec-config.c exec-config.h \ execd-config.c execd-config.h if !WINDOWS libcf_execd_la_SOURCES += cf-execd-runagent.c cf-execd-runagent.h endif libcf_execd_test_la_SOURCES = $(libcf_execd_la_SOURCES) libcf_execd_test_la_LIBADD = $(libcf_execd_la_LIBADD) libcf_execd_test_la_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_CF_EXECD if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-execd # Workaround for automake madness (try removing it if you want to know why). cf_execd_CFLAGS = $(AM_CFLAGS) cf_execd_LDADD = libcf-execd.la endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-execd/cf-execd-runner.c0000644000000000000000000006164515010704253020176 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* StringMatchFullWithPrecompiledRegex() */ #include /* LoadProcessTable()/SelectProcesses() */ #include /*******************************************************************/ static const int INF_LINES = -2; /*******************************************************************/ static void MailResult(const ExecConfig *config, const char *file); static bool Dialogue(int sd, const char *s); /******************************************************************************/ # if defined(__MINGW32__) static void *ThreadUniqueName(void) { return pthread_self().p; } # else /* __MINGW32__ */ static void *ThreadUniqueName(void) { return (void *)pthread_self(); } # endif /* __MINGW32__ */ static const char *TwinFilename(void) { #if defined(_WIN32) return "bin-twin/cf-agent.exe"; #else return "bin/cf-twin"; #endif } static const char *AgentFilename(void) { #if defined(_WIN32) return "bin/cf-agent.exe"; #else return "bin/cf-agent"; #endif } static bool TwinExists(void) { char twinfilename[CF_BUFSIZE]; struct stat sb; snprintf(twinfilename, CF_BUFSIZE, "%s/%s", GetWorkDir(), TwinFilename()); MapName(twinfilename); return (stat(twinfilename, &sb) == 0) && (IsExecutable(twinfilename)); } /* Buffer has to be at least CF_BUFSIZE bytes long */ static void ConstructFailsafeCommand(bool scheduled_run, char *buffer) { bool twin_exists = TwinExists(); const char* const workdir = GetWorkDir(); snprintf(buffer, CF_BUFSIZE, "\"%s%c%s\" -f failsafe.cf " "&& \"%s%c%s\" -Dfrom_cfexecd%s", workdir, FILE_SEPARATOR, twin_exists ? TwinFilename() : AgentFilename(), workdir, FILE_SEPARATOR, AgentFilename(), scheduled_run ? ",scheduled_run" : ""); } #ifndef __MINGW32__ #if defined(__hpux) && defined(__GNUC__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" // Avoid spurious HP-UX GCC type-pun warning on FD_SET() macro #endif static bool IsReadReady(int fd, int timeout_sec) { fd_set rset; FD_ZERO(&rset); FD_SET(fd, &rset); struct timeval tv = { .tv_sec = timeout_sec, .tv_usec = 0, }; int ret = select(fd + 1, &rset, NULL, NULL, &tv); if(ret < 0) { Log(LOG_LEVEL_ERR, "IsReadReady: Failed checking for data. (select: %s)", GetErrorStr()); return false; } if(FD_ISSET(fd, &rset)) { return true; } if(ret == 0) // timeout { return false; } // can we get here? Log(LOG_LEVEL_ERR, "IsReadReady: Unknown outcome (ret > 0 but our only fd is not set). (select: %s)", GetErrorStr()); return false; } #if defined(__hpux) && defined(__GNUC__) #pragma GCC diagnostic warning "-Wstrict-aliasing" #endif #endif /* __MINGW32__ */ void LocalExec(const ExecConfig *config) { time_t starttime = time(NULL); void *thread_name = ThreadUniqueName(); { char starttime_str[64]; cf_strtimestamp_local(starttime, starttime_str); Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); Log(LOG_LEVEL_VERBOSE, " LocalExec(%sscheduled) at %s", config->scheduled_run ? "" : "not ", starttime_str); Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); } /* Need to make sure we have LD_LIBRARY_PATH here or children will die */ char cmd[CF_BUFSIZE]; if (strlen(config->exec_command) > 0) { strlcpy(cmd, config->exec_command, CF_BUFSIZE); } else { ConstructFailsafeCommand(config->scheduled_run, cmd); } char esc_command[CF_BUFSIZE]; strlcpy(esc_command, MapName(cmd), CF_BUFSIZE); char filename[CF_BUFSIZE]; { // 2 underscores, longest 64 bit integer, -1 for NUL byte, 26 for ctime (including NUL) char line[2 + sizeof("-9223372036854775808") - 1 + 26]; snprintf(line, sizeof(line), "_%jd_%s", (intmax_t) starttime, CanonifyName(ctime(&starttime))); { char canonified_fq_name[sizeof(VFQNAME)]; strlcpy(canonified_fq_name, config->fq_name, sizeof(canonified_fq_name)); CanonifyNameInPlace(canonified_fq_name); snprintf(filename, CF_BUFSIZE, "%s/outputs/cf_%s_%s_%p", GetWorkDir(), canonified_fq_name, line, thread_name); MapName(filename); } } /* What if no more processes? Could sacrifice and exec() - but we need a sentinel */ FILE *fp = safe_fopen(filename, "w"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open '%s' - aborting exec. (fopen: %s)", filename, GetErrorStr()); return; } /* * Don't inherit this file descriptor on fork/exec */ if (fileno(fp) != -1) { SetCloseOnExec(fileno(fp), true); } Log(LOG_LEVEL_VERBOSE, "Command => %s", cmd); FILE *pp = cf_popen_sh(esc_command, "r"); if (!pp) { Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", cmd, GetErrorStr()); fclose(fp); return; } Log(LOG_LEVEL_VERBOSE, "Command is executing...%s", esc_command); int count = 0; int complete = false; size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); while (!IsPendingTermination()) { if (!IsReadReady(fileno(pp), config->agent_expireafter * SECONDS_PER_MINUTE)) { char errmsg[] = "cf-execd: timeout waiting for output from agent" " (agent_expireafter=%d) - terminating it\n"; fprintf(fp, errmsg, config->agent_expireafter); /* Trim '\n' before Log()ing. */ errmsg[strlen(errmsg) - 1] = '\0'; Log(LOG_LEVEL_NOTICE, errmsg, config->agent_expireafter); count++; pid_t pid_shell; if (PipeToPid(&pid_shell, pp)) { /* Default to killing the shell process (if we fail to get * more precise target). */ pid_t pid_to_kill = pid_shell; #ifndef __MINGW32__ /* The agent command is executed in a shell. Trying to kill the * shell may end up sending it SIGKILL which is not propagated * to the subprocesses of the shell and thus the cf-agent * process. The shell, however, creates a new process group * (with the PGID equal to the PID of the child process) for the * agent which then allows us to kill the whole process group * here. */ /* We need to determine the PID of the agent (and thus its * process group) first.*/ ClearProcessTable(); if (LoadProcessTable()) { ProcessSelect ps = PROCESS_SELECT_INIT; ps.min_ppid = pid_shell; ps.max_ppid = pid_shell; Item *procs = SelectProcesses(".*" /* any command */, &ps, true /* apply ps */); if (procs != NULL) { pid_to_kill = procs->counter; /* There should only be one child process of the shell * running by default. But it doesn't apply to all * values of exec_command in general. */ assert(procs->next == NULL); } } /* kill(-pid) is actually kill(pgid=pid) and kill(pid, 0) just * checks if it's possible to send signals to pid (or pgid in * our case). Kill the whole process group if possible. */ if ((getpgid(pid_to_kill) == pid_to_kill) && (kill(-pid_to_kill, 0) == 0)) { pid_to_kill = -pid_to_kill; } #endif ProcessSignalTerminate(pid_to_kill); } else { Log(LOG_LEVEL_ERR, "Could not get PID of agent"); } break; } ssize_t res = CfReadLine(&line, &line_size, pp); if (res == -1) { if (feof(pp)) { complete = true; } else { Log(LOG_LEVEL_ERR, "Unable to read output from command '%s'. (cfread: %s)", cmd, GetErrorStr()); } break; } const char *sp = line; while (*sp != '\0' && isspace(*sp)) { sp++; } if (*sp != '\0') /* line isn't entirely blank */ { /* Need space for 2x buffer and null byte. */ char line_escaped[res * 2 + 1]; memcpy(line_escaped, line, res + 1); ssize_t replace_res = StringReplace(line_escaped, sizeof(line_escaped), "%", "%%"); if (replace_res == -1) { ProgrammingError("StringReplace(): buffer overflow in %s", __FILE__); line[0] = '\0'; continue; } fprintf(fp, "%s\n", line_escaped); count++; /* If we can't send mail, log to syslog */ if (strlen(config->mail_to_address) == 0) { strncat(line_escaped, "\n", sizeof(line_escaped) - 1 - strlen(line_escaped)); if ((strchr(line_escaped, '\n')) == NULL) { line_escaped[sizeof(line_escaped) - 2] = '\n'; } Log(LOG_LEVEL_INFO, "%s", line_escaped); } line[0] = '\0'; } } free(line); cf_pclose(pp); Log(LOG_LEVEL_VERBOSE, complete ? "Command is complete" : "Terminated command"); if (count) { Log(LOG_LEVEL_DEBUG, "Closing fp"); fclose(fp); Log(LOG_LEVEL_VERBOSE, "Mailing result"); MailResult(config, filename); } else { Log(LOG_LEVEL_VERBOSE, "No output"); unlink(filename); fclose(fp); } } // Returns true if line is filtered, IOW should not be included. static bool LineIsFiltered(const ExecConfig *config, const char *line) { // Check whether the line matches mail filters int include_filter_len = SeqLength(config->mailfilter_include_regex); int exclude_filter_len = SeqLength(config->mailfilter_exclude_regex); // Count messages as matched in include set if there is no include set. bool included = (include_filter_len == 0); bool excluded = false; if (include_filter_len > 0) { for (int i = 0; i < include_filter_len; i++) { if (StringMatchFullWithPrecompiledRegex(SeqAt(config->mailfilter_include_regex, i), line)) { included = true; } } } if (exclude_filter_len > 0) { for (int i = 0; i < exclude_filter_len; i++) { if (StringMatchFullWithPrecompiledRegex(SeqAt(config->mailfilter_exclude_regex, i), line)) { excluded = true; } } } return !included || excluded; } static bool CompareResultEqualOrFiltered(const ExecConfig *config, const char *filename, const char *prev_file) { Log(LOG_LEVEL_VERBOSE, "Comparing files %s with %s", prev_file, filename); bool rtn = true; FILE *old_fp = safe_fopen(prev_file, "r"); FILE *new_fp = safe_fopen(filename, "r"); if (new_fp) { // Match timestamps and remove them. Not Y21K safe! :-) Regex *regex = CompileRegex(LOGGING_TIMESTAMP_REGEX); if (!regex) { UnexpectedError("Compiling regular expression failed"); rtn = false; } size_t old_line_size = CF_BUFSIZE; char *old_line = xmalloc(old_line_size); size_t new_line_size = CF_BUFSIZE; char *new_line = xmalloc(new_line_size); bool any_new_msg_present = false; while (regex) { char *old_msg = NULL; if (old_fp) { while (CfReadLine(&old_line, &old_line_size, old_fp) >= 0) { if (!LineIsFiltered(config, old_line)) { old_msg = old_line; break; } } } char *new_msg = NULL; while (CfReadLine(&new_line, &new_line_size, new_fp) >= 0) { if (!LineIsFiltered(config, new_line)) { any_new_msg_present = true; new_msg = new_line; break; } } if (!old_msg || !new_msg) { // Return difference in most cases, when there is a new // message line, but if there isn't one, return equal, even // if strictly speaking they aren't, since we don't want to // send an empty email. if (any_new_msg_present && old_msg != new_msg) { rtn = false; } break; } // Remove timestamps from lines before comparison. char *index; if (StringMatchWithPrecompiledRegex(regex, old_msg, NULL, NULL)) { index = strstr(old_msg, ": "); if (index != NULL) { old_msg = index + 2; } } if (StringMatchWithPrecompiledRegex(regex, new_msg, NULL, NULL)) { index = strstr(new_msg, ": "); if (index != NULL) { new_msg = index + 2; } } if (strcmp(old_msg, new_msg) != 0) { rtn = false; break; } } free(old_line); free(new_line); RegexDestroy(regex); } else { /* no previous file */ rtn = false; } if (old_fp) { fclose(old_fp); } if (new_fp) { fclose(new_fp); } ThreadLock(cft_count); /* replace old file with new*/ unlink(prev_file); if (!LinkOrCopy(filename, prev_file, true)) { Log(LOG_LEVEL_INFO, "Could not symlink or copy '%s' to '%s'", filename, prev_file); rtn = false; } ThreadUnlock(cft_count); return rtn; } #ifndef TEST_CF_EXECD int ConnectToSmtpSocket(const ExecConfig *config) { struct hostent *hp = gethostbyname(config->mail_server); if (!hp) { Log(LOG_LEVEL_ERR, "Mail report: unknown host '%s' ('smtpserver' in body executor control). Make sure that fully qualified names can be looked up at your site.", config->mail_server); return -1; } struct servent *server = getservbyname("smtp", "tcp"); if (!server) { Log(LOG_LEVEL_ERR, "Mail report: unable to lookup smtp service. (getservbyname: %s)", GetErrorStr()); return -1; } struct sockaddr_in raddr; memset(&raddr, 0, sizeof(raddr)); raddr.sin_port = (unsigned int) server->s_port; raddr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr; raddr.sin_family = AF_INET; Log(LOG_LEVEL_DEBUG, "Mail report: connecting..."); int sd = socket(AF_INET, SOCK_STREAM, 0); if (sd == -1) { Log(LOG_LEVEL_ERR, "Mail report: couldn't open a socket. (socket: %s)", GetErrorStr()); return -1; } if (connect(sd, (void *) &raddr, sizeof(raddr)) == -1) { Log(LOG_LEVEL_ERR, "Mail report: couldn't connect to host '%s'. (connect: %s)", config->mail_server, GetErrorStr()); cf_closesocket(sd); return -1; } return sd; } #endif // !TEST_CF_EXECD static void MailResult(const ExecConfig *config, const char *file) { /* Must be initialised to NULL, so that free(line) works when goto mail_err. */ char *line = NULL; #if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__ time_t now = time(NULL); #endif FILE *fp = safe_fopen(file, "r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Mail report: couldn't open file '%s'. (fopen: %s)", file, GetErrorStr()); return; } Log(LOG_LEVEL_VERBOSE, "Mail report: sending result..."); { int fd = fileno(fp); struct stat statbuf; if (fstat(fd, &statbuf) == -1) { Log(LOG_LEVEL_ERR, "Mail report: failed to stat file '%s' [errno: %d]", file, errno); fclose(fp); return; } if (statbuf.st_size == 0) { unlink(file); fclose(fp); Log(LOG_LEVEL_DEBUG, "Mail report: nothing to report in file '%s'", file); return; } } { char prev_file[CF_BUFSIZE]; snprintf(prev_file, CF_BUFSIZE, "%s/outputs/previous", GetWorkDir()); MapName(prev_file); if (CompareResultEqualOrFiltered(config, file, prev_file)) { Log(LOG_LEVEL_VERBOSE, "Mail report: previous output is the same as current so do not mail it"); fclose(fp); return; } } if ((strlen(config->mail_server) == 0) || (strlen(config->mail_to_address) == 0)) { /* Syslog should have done this */ Log(LOG_LEVEL_VERBOSE, "Mail report: empty mail server or address - skipping"); fclose(fp); return; } if (config->mail_max_lines == 0) { Log(LOG_LEVEL_DEBUG, "Mail report: not mailing because EmailMaxLines was zero"); fclose(fp); return; } Log(LOG_LEVEL_DEBUG, "Mail report: mailing results of '%s' to '%s'", file, config->mail_to_address); int sd = ConnectToSmtpSocket(config); if (sd < 0) { fclose(fp); return; } /* read greeting */ if (!Dialogue(sd, NULL)) { goto mail_err; } char vbuff[CF_BUFSIZE]; snprintf(vbuff, sizeof(vbuff), "HELO %s\r\n", config->fq_name); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); if (!Dialogue(sd, vbuff)) { goto mail_err; } if (strlen(config->mail_from_address) == 0) { snprintf(vbuff, sizeof(vbuff), "MAIL FROM: \r\n", config->fq_name); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); } else { snprintf(vbuff, sizeof(vbuff), "MAIL FROM: <%s>\r\n", config->mail_from_address); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); } if (!Dialogue(sd, vbuff)) { goto mail_err; } snprintf(vbuff, sizeof(vbuff), "RCPT TO: <%s>\r\n", config->mail_to_address); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); if (!Dialogue(sd, vbuff)) { goto mail_err; } if (!Dialogue(sd, "DATA\r\n")) { goto mail_err; } if (SafeStringLength(config->mail_subject) == 0) { snprintf(vbuff, sizeof(vbuff), "Subject: [%s/%s]\r\n", config->fq_name, config->ip_address); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); } else { snprintf(vbuff, sizeof(vbuff), "Subject: %s\r\n", config->mail_subject); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); } send(sd, vbuff, strlen(vbuff), 0); /* Send X-CFEngine SMTP header */ unsigned char digest[EVP_MAX_MD_SIZE + 1]; char buffer[CF_HOSTKEY_STRING_SIZE]; char *existing_policy_server = PolicyServerReadFile(GetWorkDir()); if (!existing_policy_server) { existing_policy_server = xstrdup("(none)"); } HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST); snprintf(vbuff, sizeof(vbuff), "X-CFEngine: vfqhost=\"%s\";ip-addresses=\"%s\";policyhub=\"%s\";pkhash=\"%s\"\r\n", VFQNAME, config->ip_addresses, existing_policy_server, HashPrintSafe(buffer, sizeof(buffer), digest, CF_DEFAULT_DIGEST, true)); send(sd, vbuff, strlen(vbuff), 0); free(existing_policy_server); #if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__ { struct tm tm_value; struct tm *const tm_pointer = localtime_r(&now, &tm_value); strftime(vbuff, CF_BUFSIZE, "Date: %a, %d %b %Y %H:%M:%S %z\r\n", tm_pointer); } send(sd, vbuff, strlen(vbuff), 0); #endif if (strlen(config->mail_from_address) == 0) { snprintf(vbuff, sizeof(vbuff), "From: cfengine@%s\r\n", config->fq_name); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); } else { snprintf(vbuff, sizeof(vbuff), "From: %s\r\n", config->mail_from_address); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); } send(sd, vbuff, strlen(vbuff), 0); snprintf(vbuff, sizeof(vbuff), "To: %s\r\n\r\n", config->mail_to_address); Log(LOG_LEVEL_DEBUG, "Mail report: %s", vbuff); send(sd, vbuff, strlen(vbuff), 0); size_t line_size = CF_BUFSIZE; line = xmalloc(line_size); ssize_t n_read; int count = 0; while ((n_read = CfReadLine(&line, &line_size, fp)) > 0) { if (LineIsFiltered(config, line)) { continue; } if (send(sd, line, n_read, 0) == -1 || send(sd, "\r\n", 2, 0) == -1) { Log(LOG_LEVEL_ERR, "Error while sending mail to mailserver " "'%s'. (send: '%s')", config->mail_server, GetErrorStr()); goto mail_err; } count++; if ((config->mail_max_lines != INF_LINES) && (count >= config->mail_max_lines)) { snprintf(line, line_size, "\r\n[Mail truncated by CFEngine. File is at %s on %s]\r\n", file, config->fq_name); if (send(sd, line, strlen(line), 0) == -1) { Log(LOG_LEVEL_ERR, "Error while sending mail to mailserver " "'%s'. (send: '%s')", config->mail_server, GetErrorStr()); goto mail_err; } break; } } if (!Dialogue(sd, ".\r\n")) { Log(LOG_LEVEL_DEBUG, "Mail report: mail_err\n"); goto mail_err; } Dialogue(sd, "QUIT\r\n"); Log(LOG_LEVEL_DEBUG, "Mail report: done sending mail"); free(line); fclose(fp); cf_closesocket(sd); return; mail_err: free(line); fclose(fp); cf_closesocket(sd); Log(LOG_LEVEL_ERR, "Mail report: cannot mail to %s.", config->mail_to_address); } static bool Dialogue(int sd, const char *s) { if ((s != NULL) && (*s != '\0')) { int sent = send(sd, s, strlen(s), 0); Log(LOG_LEVEL_DEBUG, "SENT(%d) -> '%s'", sent, s); } else { Log(LOG_LEVEL_DEBUG, "Nothing to send .. waiting for opening"); } int charpos = 0; int rfclinetype = ' '; char ch, f = '\0'; while (recv(sd, &ch, 1, 0)) { charpos++; if (f == '\0') { f = ch; } if (charpos == 4) /* Multiline RFC in form 222-Message with hyphen at pos 4 */ { rfclinetype = ch; } if ((ch == '\n') || (ch == '\0')) { charpos = 0; if (rfclinetype == ' ') { break; } } } return ((f == '2') || (f == '3')); /* return code 200 or 300 from smtp */ } cfengine-3.24.2/cf-execd/exec-config.c0000644000000000000000000002423115010704253017366 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #define PCRE2_CODE_UNIT_WIDTH 8 #include #include #include #include #include #include #include #include // TODO: fix #include static char *GetIpAddresses(const EvalContext *ctx) { Writer *ipbuf = StringWriter(); for (Item *iptr = EvalContextGetIpAddresses(ctx); iptr != NULL; iptr = iptr->next) { WriterWrite(ipbuf, iptr->name); if (iptr->next != NULL) { WriterWriteChar(ipbuf, ' '); } } return StringWriterClose(ipbuf); } static void RegexFree(void *ptr) { pcre2_code_free(ptr); } static void MailFilterFill(const char *pattern, Seq **output, Seq **output_regex, const char *filter_type) { int err_code; size_t err_offset; pcre2_code *regex = pcre2_compile((PCRE2_SPTR) pattern, PCRE2_ZERO_TERMINATED, PCRE2_MULTILINE | PCRE2_DOTALL | PCRE2_ANCHORED, &err_code, &err_offset, NULL); if (regex != NULL) { SeqAppend(*output, xstrdup(pattern)); SeqAppend(*output_regex, regex); } else { char err_msg[128]; if (pcre2_get_error_message(err_code, (PCRE2_UCHAR*) err_msg, sizeof(err_msg)) != PCRE2_ERROR_BADDATA) { Log(LOG_LEVEL_ERR, "Invalid regular expression in mailfilter_%s: " "pcre2_compile() '%s' in expression '%s' (offset: %zd). " "Ignoring expression.", filter_type, err_msg, pattern, err_offset); } else { Log(LOG_LEVEL_ERR, "Invalid regular expression in mailfilter_%s: " "pcre2_compile() failed for expression '%s' (offset: %zd). " "Ignoring expression.", filter_type, pattern, err_offset); } } } static void RlistMailFilterFill(const Rlist *input, Seq **output, Seq **output_regex, const char *filter_type) { int len = RlistLen(input); *output = SeqNew(len, &free); *output_regex = SeqNew(len, &RegexFree); const Rlist *ptr = input; for (int i = 0; i < len; i++) { const char *str = ptr->val.item; MailFilterFill(str, output, output_regex, filter_type); ptr = ptr->next; } } static void SeqMailFilterFill(const Seq *input, Seq **output, Seq **output_regex, const char *filter_type) { int len = SeqLength(input); *output = SeqNew(len, &free); *output_regex = SeqNew(len, &RegexFree); for (int i = 0; i < len; i++) { MailFilterFill(SeqAt(input, i), output, output_regex, filter_type); } } ExecConfig *ExecConfigNew(bool scheduled_run, const EvalContext *ctx, const Policy *policy) { ExecConfig *exec_config = xcalloc(1, sizeof(ExecConfig)); exec_config->scheduled_run = scheduled_run; exec_config->exec_command = xstrdup(""); exec_config->agent_expireafter = 2 * 60; /* two hours */ exec_config->mail_server = xstrdup(""); exec_config->mail_from_address = xstrdup(""); exec_config->mail_to_address = xstrdup(""); exec_config->mail_subject = xstrdup(""); exec_config->mail_max_lines = 30; exec_config->mailfilter_include = SeqNew(0, &free); exec_config->mailfilter_include_regex = SeqNew(0, &RegexFree); exec_config->mailfilter_exclude = SeqNew(0, &free); exec_config->mailfilter_exclude_regex = SeqNew(0, &RegexFree); exec_config->fq_name = xstrdup(VFQNAME); exec_config->ip_address = xstrdup(VIPADDRESS); exec_config->ip_addresses = GetIpAddresses(ctx); Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_EXECUTOR); if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_executor"); DataType t; const void *value = EvalContextVariableGet(ctx, ref, &t); VarRefDestroy(ref); if (t == CF_DATA_TYPE_NONE) { ProgrammingError("Unknown attribute '%s' in control body," " should have already been stopped by the parser", cp->lval); } if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILFROM].lval) == 0) { free(exec_config->mail_from_address); exec_config->mail_from_address = xstrdup(value); Log(LOG_LEVEL_DEBUG, "mailfrom '%s'", exec_config->mail_from_address); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILTO].lval) == 0) { free(exec_config->mail_to_address); exec_config->mail_to_address = xstrdup(value); Log(LOG_LEVEL_DEBUG, "mailto '%s'", exec_config->mail_to_address); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILSUBJECT].lval) == 0) { free(exec_config->mail_subject); exec_config->mail_subject = xstrdup(value); Log(LOG_LEVEL_DEBUG, "mailsubject '%s'", exec_config->mail_subject); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_SMTPSERVER].lval) == 0) { free(exec_config->mail_server); exec_config->mail_server = xstrdup(value); Log(LOG_LEVEL_DEBUG, "smtpserver '%s'", exec_config->mail_server); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_EXECCOMMAND].lval) == 0) { free(exec_config->exec_command); exec_config->exec_command = xstrdup(value); Log(LOG_LEVEL_DEBUG, "exec_command '%s'", exec_config->exec_command); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_AGENT_EXPIREAFTER].lval) == 0) { exec_config->agent_expireafter = IntFromString(value); Log(LOG_LEVEL_DEBUG, "agent_expireafter %d", exec_config->agent_expireafter); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILMAXLINES].lval) == 0) { exec_config->mail_max_lines = IntFromString(value); Log(LOG_LEVEL_DEBUG, "maxlines %d", exec_config->mail_max_lines); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILFILTER_INCLUDE].lval) == 0) { SeqDestroy(exec_config->mailfilter_include); SeqDestroy(exec_config->mailfilter_include_regex); RlistMailFilterFill(value, &exec_config->mailfilter_include, &exec_config->mailfilter_include_regex, "include"); } else if (strcmp(cp->lval, CFEX_CONTROLBODY[EXEC_CONTROL_MAILFILTER_EXCLUDE].lval) == 0) { SeqDestroy(exec_config->mailfilter_exclude); SeqDestroy(exec_config->mailfilter_exclude_regex); RlistMailFilterFill(value, &exec_config->mailfilter_exclude, &exec_config->mailfilter_exclude_regex, "exclude"); } } } return exec_config; } ExecConfig *ExecConfigCopy(const ExecConfig *config) { ExecConfig *copy = xcalloc(1, sizeof(ExecConfig)); copy->scheduled_run = config->scheduled_run; copy->exec_command = xstrdup(config->exec_command); copy->agent_expireafter = config->agent_expireafter; copy->mail_server = xstrdup(config->mail_server); copy->mail_from_address = xstrdup(config->mail_from_address); copy->mail_to_address = xstrdup(config->mail_to_address); copy->mail_subject = xstrdup(config->mail_subject); copy->mail_max_lines = config->mail_max_lines; SeqMailFilterFill(config->mailfilter_include, ©->mailfilter_include, ©->mailfilter_include_regex, "include"); SeqMailFilterFill(config->mailfilter_exclude, ©->mailfilter_exclude, ©->mailfilter_exclude_regex, "exclude"); copy->fq_name = xstrdup(config->fq_name); copy->ip_address = xstrdup(config->ip_address); copy->ip_addresses = xstrdup(config->ip_addresses); return copy; } void ExecConfigDestroy(ExecConfig *exec_config) { if (exec_config) { free(exec_config->exec_command); free(exec_config->mail_server); free(exec_config->mail_from_address); free(exec_config->mail_to_address); free(exec_config->mail_subject); SeqDestroy(exec_config->mailfilter_include); SeqDestroy(exec_config->mailfilter_exclude); SeqDestroy(exec_config->mailfilter_include_regex); SeqDestroy(exec_config->mailfilter_exclude_regex); free(exec_config->fq_name); free(exec_config->ip_address); free(exec_config->ip_addresses); free(exec_config); } } cfengine-3.24.2/cf-execd/cf-execd-runagent.c0000644000000000000000000001214115010704253020473 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include /** * Handle request to run cf-runagent. * * @note Expected to be called from a forked child process (blocks and forks). */ void HandleRunagentRequest(int conn_fd, const char *local_run_command) { FILE *conn_file = fdopen(conn_fd, "r+"); if (conn_file == NULL) { Log(LOG_LEVEL_ERR, "Failed to create file stream from the connection file descriptor: %s", GetErrorStr()); /* SIGH: There's no dprintf() on exotics. */ char error_buf[256]; size_t length = snprintf(error_buf, sizeof(error_buf), "{\"error\": \"Failed to create file stream from the connection file descriptor: %s\"}", GetErrorStr()); assert(length < sizeof(error_buf)); NDEBUG_UNUSED size_t written = write(conn_fd, error_buf, MIN(sizeof(error_buf), (size_t) length)); assert(written == MIN(sizeof(error_buf), (size_t) length)); close(conn_fd); return; } char *request = NULL; size_t line_size = 0; ssize_t n_read = getline(&request, &line_size, conn_file); if (n_read <= 0) { Log(LOG_LEVEL_ERR, "Failed to read the runagent request: %s", (n_read < 0) ? GetErrorStr() : "no data"); fprintf(conn_file, "{\"error\": \"Failed to read the runagent request: %s\"}", (n_read < 0) ? GetErrorStr() : "no data"); free(request); fclose(conn_file); return; } /* Strip the trailing newline (if any). */ if (request[n_read - 1] == '\n') { request[n_read - 1] = '\0'; } /* TODO: '--raw' for just getting output from cf-runagent directly? */ const char *tool = NULL; char *command; if (StringEqual(request, "localhost") || StringIsLocalHostIP(request)) { tool = "cf-agent"; command = xstrdup(local_run_command); } else { tool = "cf-runagent"; xasprintf(&command, "%s%ccf-runagent -b -H %s", GetBinDir(), FILE_SEPARATOR, request); } free(request); FILE *run_agent_output = cf_popen(command, "r", true); free(command); if (run_agent_output == NULL) { Log(LOG_LEVEL_ERR, "Failed to start %s and connect to its output", tool); fprintf(conn_file, "{\"error\": \"Failed to start %s and connect to its output\"}", tool); fclose(conn_file); return; } Buffer *collected_output = BufferNewWithCapacity(1024); char output_buffer[CF_BUFSIZE]; size_t read_bytes = fread(output_buffer, 1, sizeof(output_buffer), run_agent_output); while (read_bytes > 0) { BufferAppend(collected_output, output_buffer, read_bytes); read_bytes = fread(output_buffer, 1, sizeof(output_buffer), run_agent_output); } if (!feof(run_agent_output)) { Log(LOG_LEVEL_ERR, "Failed to read output from %s", tool); fprintf(conn_file, "{\"error\": \"Failed to read output from %s\"}", tool); cf_pclose(run_agent_output); fclose(conn_file); return; } BufferAppendChar(collected_output, '\0'); int run_agent_ret = cf_pclose(run_agent_output); if (run_agent_ret == -1) { Log(LOG_LEVEL_ERR, "Failed to wait for the %s process to terminate", tool); fprintf(conn_file, "{\"error\": \"Failed to wait for the %s process to terminate\"}", tool); fclose(conn_file); return; } Writer *json_writer = FileWriter(conn_file); NDEBUG_UNUSED size_t written = WriterWrite(json_writer, "{\n\"output\" : \""); assert(written > 0); JsonEncodeStringWriter(BufferData(collected_output), json_writer); written = WriterWrite(json_writer, "\",\n"); assert(written > 0); written = WriterWriteF(json_writer, "\"exit_code\": %d\n", run_agent_ret); assert(written > 0); written = WriterWrite(json_writer, "}\n"); assert(written > 0); BufferDestroy(collected_output); fclose(conn_file); return; } cfengine-3.24.2/cf-execd/cf-execd.h0000644000000000000000000000245115010704253016662 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CF_EXECD_H #define CF_EXECD_H #include #include #include #include #include #include void StartServer(EvalContext *ctx, Policy *policy, GenericAgentConfig *config, ExecdConfig **execd_config, ExecConfig **exec_config); #endif cfengine-3.24.2/cf-execd/cf-execd-runagent.h0000644000000000000000000000217315010704253020504 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CF_EXECD_RUNAGENT_H #define CFENGINE_CF_EXECD_RUNAGENT_H void HandleRunagentRequest(int conn_fd, const char *local_run_command); #endif cfengine-3.24.2/cf-execd/Makefile.in0000644000000000000000000010755715010704300017106 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @WINDOWS_FALSE@am__append_1 = cf-execd-runagent.c cf-execd-runagent.h @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-execd$(EXEEXT) subdir = cf-execd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_execd_test_la_DEPENDENCIES = $(libcf_execd_la_LIBADD) am__libcf_execd_test_la_SOURCES_DIST = cf-execd.c cf-execd.h \ cf-execd-runner.c cf-execd-runner.h exec-config.c \ exec-config.h execd-config.c execd-config.h \ cf-execd-runagent.c cf-execd-runagent.h @WINDOWS_FALSE@am__objects_1 = \ @WINDOWS_FALSE@ libcf_execd_test_la-cf-execd-runagent.lo am__objects_2 = libcf_execd_test_la-cf-execd.lo \ libcf_execd_test_la-cf-execd-runner.lo \ libcf_execd_test_la-exec-config.lo \ libcf_execd_test_la-execd-config.lo $(am__objects_1) am_libcf_execd_test_la_OBJECTS = $(am__objects_2) libcf_execd_test_la_OBJECTS = $(am_libcf_execd_test_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libcf_execd_la_DEPENDENCIES = ../libpromises/libpromises.la am__libcf_execd_la_SOURCES_DIST = cf-execd.c cf-execd.h \ cf-execd-runner.c cf-execd-runner.h exec-config.c \ exec-config.h execd-config.c execd-config.h \ cf-execd-runagent.c cf-execd-runagent.h @WINDOWS_FALSE@am__objects_3 = cf-execd-runagent.lo am_libcf_execd_la_OBJECTS = cf-execd.lo cf-execd-runner.lo \ exec-config.lo execd-config.lo $(am__objects_3) libcf_execd_la_OBJECTS = $(am_libcf_execd_la_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) cf_execd_SOURCES = cf-execd.c cf_execd_OBJECTS = cf_execd-cf-execd.$(OBJEXT) @BUILTIN_EXTENSIONS_FALSE@cf_execd_DEPENDENCIES = libcf-execd.la cf_execd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(cf_execd_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_execd_test_la_SOURCES) $(libcf_execd_la_SOURCES) \ cf-execd.c DIST_SOURCES = $(am__libcf_execd_test_la_SOURCES_DIST) \ $(am__libcf_execd_la_SOURCES_DIST) cf-execd.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-execd.la libcf-execd-test.la AM_CPPFLAGS = \ -I$(srcdir)/../libpromises \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libenv \ -I$(srcdir)/../cf-check \ $(PCRE2_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(PCRE2_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(PTHREAD_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_execd_la_LIBADD = ../libpromises/libpromises.la libcf_execd_la_SOURCES = cf-execd.c cf-execd.h cf-execd-runner.c \ cf-execd-runner.h exec-config.c exec-config.h execd-config.c \ execd-config.h $(am__append_1) libcf_execd_test_la_SOURCES = $(libcf_execd_la_SOURCES) libcf_execd_test_la_LIBADD = $(libcf_execd_la_LIBADD) libcf_execd_test_la_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_CF_EXECD # Workaround for automake madness (try removing it if you want to know why). @BUILTIN_EXTENSIONS_FALSE@cf_execd_CFLAGS = $(AM_CFLAGS) @BUILTIN_EXTENSIONS_FALSE@cf_execd_LDADD = libcf-execd.la CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-execd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-execd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-execd-test.la: $(libcf_execd_test_la_OBJECTS) $(libcf_execd_test_la_DEPENDENCIES) $(EXTRA_libcf_execd_test_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_execd_test_la_OBJECTS) $(libcf_execd_test_la_LIBADD) $(LIBS) libcf-execd.la: $(libcf_execd_la_OBJECTS) $(libcf_execd_la_DEPENDENCIES) $(EXTRA_libcf_execd_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_execd_la_OBJECTS) $(libcf_execd_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-execd$(EXEEXT): $(cf_execd_OBJECTS) $(cf_execd_DEPENDENCIES) $(EXTRA_cf_execd_DEPENDENCIES) @rm -f cf-execd$(EXEEXT) $(AM_V_CCLD)$(cf_execd_LINK) $(cf_execd_OBJECTS) $(cf_execd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-execd-runagent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-execd-runner.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-execd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_execd-cf-execd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exec-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execd-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcf_execd_test_la-cf-execd-runagent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcf_execd_test_la-cf-execd-runner.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcf_execd_test_la-cf-execd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcf_execd_test_la-exec-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcf_execd_test_la-execd-config.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libcf_execd_test_la-cf-execd.lo: cf-execd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcf_execd_test_la-cf-execd.lo -MD -MP -MF $(DEPDIR)/libcf_execd_test_la-cf-execd.Tpo -c -o libcf_execd_test_la-cf-execd.lo `test -f 'cf-execd.c' || echo '$(srcdir)/'`cf-execd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcf_execd_test_la-cf-execd.Tpo $(DEPDIR)/libcf_execd_test_la-cf-execd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-execd.c' object='libcf_execd_test_la-cf-execd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcf_execd_test_la-cf-execd.lo `test -f 'cf-execd.c' || echo '$(srcdir)/'`cf-execd.c libcf_execd_test_la-cf-execd-runner.lo: cf-execd-runner.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcf_execd_test_la-cf-execd-runner.lo -MD -MP -MF $(DEPDIR)/libcf_execd_test_la-cf-execd-runner.Tpo -c -o libcf_execd_test_la-cf-execd-runner.lo `test -f 'cf-execd-runner.c' || echo '$(srcdir)/'`cf-execd-runner.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcf_execd_test_la-cf-execd-runner.Tpo $(DEPDIR)/libcf_execd_test_la-cf-execd-runner.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-execd-runner.c' object='libcf_execd_test_la-cf-execd-runner.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcf_execd_test_la-cf-execd-runner.lo `test -f 'cf-execd-runner.c' || echo '$(srcdir)/'`cf-execd-runner.c libcf_execd_test_la-exec-config.lo: exec-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcf_execd_test_la-exec-config.lo -MD -MP -MF $(DEPDIR)/libcf_execd_test_la-exec-config.Tpo -c -o libcf_execd_test_la-exec-config.lo `test -f 'exec-config.c' || echo '$(srcdir)/'`exec-config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcf_execd_test_la-exec-config.Tpo $(DEPDIR)/libcf_execd_test_la-exec-config.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exec-config.c' object='libcf_execd_test_la-exec-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcf_execd_test_la-exec-config.lo `test -f 'exec-config.c' || echo '$(srcdir)/'`exec-config.c libcf_execd_test_la-execd-config.lo: execd-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcf_execd_test_la-execd-config.lo -MD -MP -MF $(DEPDIR)/libcf_execd_test_la-execd-config.Tpo -c -o libcf_execd_test_la-execd-config.lo `test -f 'execd-config.c' || echo '$(srcdir)/'`execd-config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcf_execd_test_la-execd-config.Tpo $(DEPDIR)/libcf_execd_test_la-execd-config.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='execd-config.c' object='libcf_execd_test_la-execd-config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcf_execd_test_la-execd-config.lo `test -f 'execd-config.c' || echo '$(srcdir)/'`execd-config.c libcf_execd_test_la-cf-execd-runagent.lo: cf-execd-runagent.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcf_execd_test_la-cf-execd-runagent.lo -MD -MP -MF $(DEPDIR)/libcf_execd_test_la-cf-execd-runagent.Tpo -c -o libcf_execd_test_la-cf-execd-runagent.lo `test -f 'cf-execd-runagent.c' || echo '$(srcdir)/'`cf-execd-runagent.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcf_execd_test_la-cf-execd-runagent.Tpo $(DEPDIR)/libcf_execd_test_la-cf-execd-runagent.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-execd-runagent.c' object='libcf_execd_test_la-cf-execd-runagent.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcf_execd_test_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcf_execd_test_la-cf-execd-runagent.lo `test -f 'cf-execd-runagent.c' || echo '$(srcdir)/'`cf-execd-runagent.c cf_execd-cf-execd.o: cf-execd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_execd_CFLAGS) $(CFLAGS) -MT cf_execd-cf-execd.o -MD -MP -MF $(DEPDIR)/cf_execd-cf-execd.Tpo -c -o cf_execd-cf-execd.o `test -f 'cf-execd.c' || echo '$(srcdir)/'`cf-execd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_execd-cf-execd.Tpo $(DEPDIR)/cf_execd-cf-execd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-execd.c' object='cf_execd-cf-execd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_execd_CFLAGS) $(CFLAGS) -c -o cf_execd-cf-execd.o `test -f 'cf-execd.c' || echo '$(srcdir)/'`cf-execd.c cf_execd-cf-execd.obj: cf-execd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_execd_CFLAGS) $(CFLAGS) -MT cf_execd-cf-execd.obj -MD -MP -MF $(DEPDIR)/cf_execd-cf-execd.Tpo -c -o cf_execd-cf-execd.obj `if test -f 'cf-execd.c'; then $(CYGPATH_W) 'cf-execd.c'; else $(CYGPATH_W) '$(srcdir)/cf-execd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_execd-cf-execd.Tpo $(DEPDIR)/cf_execd-cf-execd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-execd.c' object='cf_execd-cf-execd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_execd_CFLAGS) $(CFLAGS) -c -o cf_execd-cf-execd.obj `if test -f 'cf-execd.c'; then $(CYGPATH_W) 'cf-execd.c'; else $(CYGPATH_W) '$(srcdir)/cf-execd.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-execd/exec-config.h0000644000000000000000000000405115010704253017371 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_EXEC_CONFIG_H #define CFENGINE_EXEC_CONFIG_H #include /* This struct is supposed to be immutable: don't update it, just destroy and create anew */ typedef struct { bool scheduled_run; char *exec_command; int agent_expireafter; /* in minutes */ char *mail_server; char *mail_from_address; char *mail_to_address; char *mail_subject; int mail_max_lines; // These two contain regular expression strings. Seq *mailfilter_include; Seq *mailfilter_exclude; // These two contain precompiled regexes (pcre*). Seq *mailfilter_include_regex; Seq *mailfilter_exclude_regex; /* * Host information. * Might change during policy reload, so copy is retained in each worker. */ char *fq_name; char *ip_address; char *ip_addresses; } ExecConfig; ExecConfig *ExecConfigNew(bool scheduled_run, const EvalContext *ctx, const Policy *policy); ExecConfig *ExecConfigCopy(const ExecConfig *exec_config); void ExecConfigDestroy(ExecConfig *exec_config); #endif cfengine-3.24.2/cf-execd/execd-config.h0000644000000000000000000000274315010704253017543 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_EXECD_CONFIG_H #define CFENGINE_EXECD_CONFIG_H #include #include /* This struct is supposed to be immutable: don't update it, just destroy and create anew */ typedef struct ExecdConfig { StringSet *schedule; int splay_time; char *log_facility; StringSet *runagent_allow_users; char *local_run_command; } ExecdConfig; ExecdConfig *ExecdConfigNew(const EvalContext *ctx, const Policy *policy); void ExecdConfigDestroy(ExecdConfig *exec_config); #endif cfengine-3.24.2/cf-execd/cf-execd.c0000644000000000000000000010237415010704253016662 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #ifndef __MINGW32__ #include #include #include #include #include #include /* ChopLastNode */ #ifndef AF_LOCAL #define AF_LOCAL AF_UNIX #endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* CheckDBRepairFlagFile() */ #include #include /* AllowAccessForUsers() */ #include #define CF_EXEC_IFELAPSED 0 #define CF_EXEC_EXPIREAFTER 1 #define CF_EXECD_RUNAGENT_SOCKET_NAME "runagent.socket" /* The listen() queue doesn't need to be long, new connections are accepted * quickly and handed over to forked child processes so a pile up means some * serious problem and it's better to just throw such connections away. */ #define CF_EXECD_RUNAGENT_SOCKET_LISTEN_QUEUE 5 static bool PERFORM_DB_CHECK = false; static int NO_FORK = false; /* GLOBAL_A */ static int ONCE = false; /* GLOBAL_A */ static int WINSERVICE = true; /* GLOBAL_A */ static char *RUNAGENT_SOCKET_DIR = NULL; static pthread_attr_t threads_attrs; /* GLOBAL_T, initialized by pthread_attr_init */ /*******************************************************************/ static GenericAgentConfig *CheckOpts(int argc, char **argv); void ThisAgentInit(void); static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecdConfig **execd_config, ExecConfig **exec_config); #ifndef __MINGW32__ static pid_t LocalExecInFork(const ExecConfig *config); static void Apoptosis(void); static inline bool GetRunagentSocketInfo(struct sockaddr_un *sock_info); static inline bool SetRunagentSocketACLs(char *sock_path, StringSet *allow_users); #else static bool LocalExecInThread(const ExecConfig *config); #endif /*******************************************************************/ /* Command line options */ /*******************************************************************/ static const char *const CF_EXECD_SHORT_DESCRIPTION = "scheduling daemon for cf-agent"; static const char *const CF_EXECD_MANPAGE_LONG_DESCRIPTION = "cf-execd is the scheduling daemon for cf-agent. It runs cf-agent locally according to a schedule specified in " "policy code (executor control body). After a cf-agent run is completed, cf-execd gathers output from cf-agent, " "and may be configured to email the output to a specified address. It may also be configured to splay (randomize) the " "execution schedule to prevent synchronized cf-agent runs across a network. " "Note: this daemon reloads it's config when the SIGHUP signal is received."; static const Component COMPONENT = { .name = "cf-execd", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"help", no_argument, 0, 'h'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"dry-run", no_argument, 0, 'n'}, {"version", no_argument, 0, 'V'}, {"file", required_argument, 0, 'f'}, {"define", required_argument, 0, 'D'}, {"negate", required_argument, 0, 'N'}, {"no-lock", no_argument, 0, 'K'}, {"inform", no_argument, 0, 'I'}, {"diagnostic", no_argument, 0, 'x'}, {"log-level", required_argument, 0, 'g'}, {"no-fork", no_argument, 0, 'F'}, {"once", no_argument, 0, 'O'}, {"no-winsrv", no_argument, 0, 'W'}, {"ld-library-path", required_argument, 0, 'L'}, {"color", optional_argument, 0, 'C'}, {"timestamp", no_argument, 0, 'l'}, /* Only long option for the rest */ {"ignore-preferred-augments", no_argument, 0, 0}, {"skip-db-check", optional_argument, 0, 0 }, {"with-runagent-socket", required_argument, 0, 0}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Enable debugging output", "Output verbose information about the behaviour of cf-execd", "All talk and no action mode - make no changes, only inform of promises not kept", "Output the version of the software", "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.", "Define a list of comma separated classes to be defined at the start of execution", "Define a list of comma separated classes to be undefined at the start of execution", "Ignore locking constraints during execution (ifelapsed/expireafter) if \"too soon\" to run", "Print basic information about changes made to the system, i.e. promises repaired", "Activate internal diagnostics (developers only)", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Run as a foreground processes (do not fork)", "Run once and then exit (implies no-fork)", "Do not run as a service on windows - use this when running from a command shell (CFEngine Nova only)", "Set the internal value of LD_LIBRARY_PATH for child processes", "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", "Log timestamps on each line of log output", "Ignore def_preferred.json file in favor of def.json", "Do not run database integrity checks and repairs at startup", "Specify the directory for the socket for runagent requests or 'no' to disable the socket", NULL }; /*****************************************************************************/ int main(int argc, char *argv[]) { GenericAgentConfig *config = CheckOpts(argc, argv); bool force_repair = CheckDBRepairFlagFile(); if (force_repair || PERFORM_DB_CHECK) { repair_lmdb_default(force_repair); } EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); const char *program_invocation_name = argv[0]; const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR); const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name); GenericAgentDiscoverContext(ctx, config, program_name); Policy *policy = SelectAndLoadPolicy(config, ctx, false, false); if (!policy) { Log(LOG_LEVEL_ERR, "Error reading CFEngine policy. Exiting..."); DoCleanupAndExit(EXIT_FAILURE); } GenericAgentPostLoadInit(ctx); ThisAgentInit(); ExecConfig *exec_config = ExecConfigNew(!ONCE, ctx, policy); ExecdConfig *execd_config = ExecdConfigNew(ctx, policy); SetFacility(execd_config->log_facility); #ifdef __MINGW32__ if (WINSERVICE) { NovaWin_StartExecService(); } else #endif /* __MINGW32__ */ { StartServer(ctx, policy, config, &execd_config, &exec_config); } GenericAgentFinalize(ctx, config); ExecConfigDestroy(exec_config); ExecdConfigDestroy(execd_config); free(RUNAGENT_SOCKET_DIR); CallCleanupFunctions(); return 0; } /*****************************************************************************/ /* Level 1 */ /*****************************************************************************/ static GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int c; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_EXECUTOR, GetTTYInteractive()); int longopt_idx; while ((c = getopt_long(argc, argv, "dvnKIf:g:D:N:VxL:hFOV1gMWC::l", OPTIONS, &longopt_idx)) != -1) { switch (c) { case 'f': GenericAgentConfigSetInputFile(config, GetInputDir(), optarg); MINUSF = true; break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case 'K': config->ignore_locks = true; break; case 'D': { StringSet *defined_classes = StringSetFromString(optarg, ','); if (! config->heap_soft) { config->heap_soft = defined_classes; } else { StringSetJoin(config->heap_soft, defined_classes, xstrdup); StringSetDestroy(defined_classes); } } break; case 'N': { StringSet *negated_classes = StringSetFromString(optarg, ','); if (! config->heap_negated) { config->heap_negated = negated_classes; } else { StringSetJoin(config->heap_negated, negated_classes, xstrdup); StringSetDestroy(negated_classes); } } break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); NO_FORK = true; // TODO: really? break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'n': EVAL_MODE = EVAL_MODE_DRY_RUN; config->ignore_locks = true; break; case 'L': { Log(LOG_LEVEL_VERBOSE, "Setting 'LD_LIBRARY_PATH=%s'", optarg); setenv_wrapper("LD_LIBRARY_PATH", optarg, 1); break; } case 'W': WINSERVICE = false; break; case 'F': NO_FORK = true; break; case 'O': ONCE = true; NO_FORK = true; break; case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'h': { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-execd", time(NULL), CF_EXECD_SHORT_DESCRIPTION, CF_EXECD_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(out); DoCleanupAndExit(EXIT_SUCCESS); } case 'x': Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired."); DoCleanupAndExit(EXIT_SUCCESS); case 'C': if (!GenericAgentConfigParseColor(config, optarg)) { DoCleanupAndExit(EXIT_FAILURE); } break; case 'l': LoggingEnableTimestamps(true); break; case 0: { const char *const option_name = OPTIONS[longopt_idx].name; if (StringEqual(option_name, "ignore-preferred-augments")) { config->ignore_preferred_augments = true; } else if (StringEqual(option_name, "skip-db-check")) { if (optarg == NULL) { PERFORM_DB_CHECK = false; // Skip (no arg), check = false } else if (StringEqual_IgnoreCase(optarg, "yes")) { PERFORM_DB_CHECK = false; // Skip = yes, check = false } else if (StringEqual_IgnoreCase(optarg, "no")) { PERFORM_DB_CHECK = true; // Skip = no, check = true } else { Log(LOG_LEVEL_ERR, "Invalid argument for --skip-db-check(yes/no): '%s'", optarg); DoCleanupAndExit(EXIT_FAILURE); } } else if (StringEqual(option_name, "with-runagent-socket")) { assert(optarg != NULL); /* required_argument */ RUNAGENT_SOCKET_DIR = xstrdup(optarg); } break; } default: { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_FAILURE); } } if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind)) { Log(LOG_LEVEL_ERR, "Too many arguments"); DoCleanupAndExit(EXIT_FAILURE); } return config; } /*****************************************************************************/ void ThisAgentInit(void) { umask(077); } // Return 2 to 62 seconds depending on how much time is left until the next // minute starts. Since cf-execd wakes up "every minute" to evaluate its // schedule, we want to do this at the start of the minute, to avoid // accidentally skipping any runs if things are slow. // // Why +2? Why not 0 to 60? Not a very good reason, but: // Sleep at least 2 seconds to avoid 2 agent runs very close together // Target waking up at :02 seconds, to reduce the chances of waking // up at :59 in the previous minute, and unintentionally having 2 // agent runs in the same minute static inline time_t GetPulseTime() { const time_t current_second = (time(NULL) % CFPULSETIME); const time_t remaining_seconds = CFPULSETIME - current_second; return remaining_seconds + 2; } /*****************************************************************************/ #ifndef __MINGW32__ static inline bool UsingRunagentSocket() { /* No runagent socket dir specified (use the default) or a directory * specified ("no" disables the functionality). */ return ((RUNAGENT_SOCKET_DIR == NULL) || (!StringEqual_IgnoreCase(RUNAGENT_SOCKET_DIR, "no"))); } /** * Sleep for the given number of seconds while handling requests from sockets. * * @return Whether to terminate (skip any further actions) or not. */ static bool HandleRequestsOrSleep(time_t seconds, const char *reason, int runagent_socket, const char *local_run_command) { if (IsPendingTermination()) { return true; } Log(LOG_LEVEL_VERBOSE, "Sleeping for %s %ju seconds", reason, (intmax_t) seconds); if (runagent_socket >= 0) { time_t sleep_started = time(NULL); struct timeval remaining = {seconds, 0}; while (remaining.tv_sec != 0) { fd_set rfds; FD_ZERO(&rfds); FD_SET(runagent_socket, &rfds); int ret = select(runagent_socket + 1, &rfds, NULL, NULL, &remaining); if ((ret == -1) && (errno != EINTR)) { /* unexpected error */ Log(LOG_LEVEL_ERR, "Failed to sleep for %s using select(): %s", reason, GetErrorStr()); } else if (ret == 0) { /* timeout -- slept for the specified time */ remaining.tv_sec = 0; } else { /* runagent_socket ready or signal received (EINTR) */ // We are sleeping above, so make sure a terminating signal did not // arrive during that time. if (IsPendingTermination()) { return true; } if (ret > 0) { assert(FD_ISSET(runagent_socket, &rfds)); int data_socket = accept(runagent_socket, NULL, NULL); pid_t pid = fork(); if (pid == 0) { /* child */ signal(SIGPIPE, SIG_DFL); HandleRunagentRequest(data_socket, local_run_command); _exit(EXIT_SUCCESS); } else if (pid == -1) { /* error */ Log(LOG_LEVEL_ERR, "Failed to fork runagent request handler: %s", GetErrorStr()); } /* parent: nothing more to do, go back to sleep */ } remaining.tv_sec = MAX(0, seconds - (time(NULL) - sleep_started)); } } } else { sleep(seconds); } // We are sleeping above, so make sure a terminating signal did not // arrive during that time. if (IsPendingTermination()) { return true; } return false; } // Non-windows version of main loop: static void CFExecdMainLoop(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecdConfig **execd_config, ExecConfig **exec_config, int runagent_socket) { bool terminate = false; while (!IsPendingTermination()) { /* reap child processes (if any) */ while (waitpid(-1, NULL, WNOHANG) > 0) { Log(LOG_LEVEL_DEBUG, "Reaped child process"); } if (ScheduleRun(ctx, policy, config, execd_config, exec_config)) { terminate = HandleRequestsOrSleep((*execd_config)->splay_time, "splay time", runagent_socket, (*execd_config)->local_run_command); if (terminate) { break; } pid_t child_pid = LocalExecInFork(*exec_config); if (child_pid < 0) { Log(LOG_LEVEL_INFO, "Unable to run agent in a fork, falling back to blocking execution"); LocalExec(*exec_config); } } /* 1 Minute resolution is enough */ terminate = HandleRequestsOrSleep(GetPulseTime(), "pulse time", runagent_socket, (*execd_config)->local_run_command); if (terminate) { break; } } /* Remove the runagent socket (if any). */ if (UsingRunagentSocket()) { struct sockaddr_un sock_info; if (GetRunagentSocketInfo(&sock_info)) { unlink(sock_info.sun_path); } } } static inline bool GetRunagentSocketInfo(struct sockaddr_un *sock_info) { assert(sock_info != NULL); memset(sock_info, 0, sizeof(*sock_info)); /* This can easily fail if GetStateDir() returns some long path, * 'sock_info.sun_path' is limited to 140 characters or even * fewer. "/var/cfengine/state" is fine, crazy long temporary state * directories used in the tests are too long. */ int ret; if (RUNAGENT_SOCKET_DIR == NULL) { ret = snprintf(sock_info->sun_path, sizeof(sock_info->sun_path) - 1, "%s/cf-execd.sockets/"CF_EXECD_RUNAGENT_SOCKET_NAME, GetStateDir()); } else { ret = snprintf(sock_info->sun_path, sizeof(sock_info->sun_path) - 1, "%s/"CF_EXECD_RUNAGENT_SOCKET_NAME, RUNAGENT_SOCKET_DIR); } return ((ret > 0) && ((size_t) ret <= (sizeof(sock_info->sun_path) - 1))); } static inline bool SetRunagentSocketACLs(char *sock_path, StringSet *allow_users) { /* Allow access to the socket (rw) */ bool success = AllowAccessForUsers(sock_path, allow_users, true, false); /* Need to ensure access to the parent folder too (rx) */ if (success) { ChopLastNode(sock_path); success = AllowAccessForUsers(sock_path, allow_users, false, true); } return success; } static int SetupRunagentSocket(const ExecdConfig *execd_config) { assert(execd_config != NULL); int runagent_socket = -1; struct sockaddr_un sock_info; if (GetRunagentSocketInfo(&sock_info)) { sock_info.sun_family = AF_LOCAL; MakeParentDirectoryPerms(sock_info.sun_path, true, NULL, (mode_t) 0700); /* Remove potential left-overs from old processes. */ unlink(sock_info.sun_path); runagent_socket = socket(AF_LOCAL, SOCK_STREAM, 0); assert(runagent_socket >= 0); } if (runagent_socket < 0) { Log(LOG_LEVEL_ERR, "Failed to create socket for runagent requests"); } else { int ret = bind(runagent_socket, (const struct sockaddr *) &sock_info, sizeof(sock_info)); assert(ret == 0); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to bind the runagent socket: %s", GetErrorStr()); close(runagent_socket); runagent_socket = -1; } else { safe_chmod(sock_info.sun_path, (mode_t) 0600); ret = listen(runagent_socket, CF_EXECD_RUNAGENT_SOCKET_LISTEN_QUEUE); assert(ret == 0); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to listen on runagent socket: %s", GetErrorStr()); close(runagent_socket); runagent_socket = -1; } } if (StringSetSize(execd_config->runagent_allow_users) > 0) { bool success = SetRunagentSocketACLs(sock_info.sun_path, execd_config->runagent_allow_users); if (!success) { Log(LOG_LEVEL_ERR, "Failed to allow runagent_socket_allow_users users access the runagent socket"); /* keep going anyway */ } } } return runagent_socket; } #else /* ! __MINGW32__ */ /** * Sleep if not pending termination and log a message. * * @note: #msg_format should include exactly one "%u". */ static inline unsigned int MaybeSleepLog(LogLevel level, const char *msg_format, unsigned int seconds) { if (IsPendingTermination()) { return seconds; } Log(level, msg_format, seconds); return sleep(seconds); } // Windows version of main loop: static void CFExecdMainLoop(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecdConfig **execd_config, ExecConfig **exec_config, ARG_UNUSED int runagent_socket) { while (!IsPendingTermination()) { if (ScheduleRun(ctx, policy, config, execd_config, exec_config)) { MaybeSleepLog(LOG_LEVEL_VERBOSE, "Sleeping for splaytime %u seconds", (*execd_config)->splay_time); // We are sleeping above, so make sure a terminating signal did not // arrive during that time. if (IsPendingTermination()) { break; } if (!LocalExecInThread(*exec_config)) { Log(LOG_LEVEL_INFO, "Unable to run agent in thread, falling back to blocking execution"); LocalExec(*exec_config); } } // This is not just a log message, it maybe sleeps and maybe logs something: MaybeSleepLog(LOG_LEVEL_VERBOSE, "Sleeping for pulse time %u seconds...", GetPulseTime()); } } #endif /* ! __MINGW32__ */ /* Might be called back from NovaWin_StartExecService */ void StartServer(EvalContext *ctx, Policy *policy, GenericAgentConfig *config, ExecdConfig **execd_config, ExecConfig **exec_config) { pthread_attr_init(&threads_attrs); pthread_attr_setdetachstate(&threads_attrs, PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&threads_attrs, (size_t)2048*1024); Banner("Starting executor"); #ifndef __MINGW32__ if (!ONCE) { /* Kill previous instances of cf-execd if those are still running */ Apoptosis(); } time_t now = time(NULL); if ((!NO_FORK) && (fork() != 0)) { Log(LOG_LEVEL_INFO, "cf-execd starting %.24s", ctime(&now)); _exit(EXIT_SUCCESS); } if (!NO_FORK) { ActAsDaemon(); } #else /* __MINGW32__ */ if (!NO_FORK) { Log(LOG_LEVEL_VERBOSE, "Windows does not support starting processes in the background - starting in foreground"); } #endif WritePID("cf-execd.pid"); signal(SIGINT, HandleSignalsForDaemon); signal(SIGTERM, HandleSignalsForDaemon); signal(SIGBUS, HandleSignalsForDaemon); signal(SIGHUP, HandleSignalsForDaemon); signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, HandleSignalsForDaemon); signal(SIGUSR2, HandleSignalsForDaemon); umask(077); int runagent_socket = -1; #ifndef __MINGW32__ if (UsingRunagentSocket()) { runagent_socket = SetupRunagentSocket(*execd_config); } #endif if (ONCE) { LocalExec(*exec_config); CloseLog(); } else { CFExecdMainLoop(ctx, &policy, config, execd_config, exec_config, runagent_socket); } PolicyDestroy(policy); } /*****************************************************************************/ #ifndef __MINGW32__ static pid_t LocalExecInFork(const ExecConfig *config) { Log(LOG_LEVEL_VERBOSE, "Forking for exec_command execution"); pid_t pid = fork(); if (pid == -1) { Log(LOG_LEVEL_ERR, "Failed to fork for exec_command execution: %s", GetErrorStr()); return -1; } else if (pid == 0) { /* child */ LocalExec(config); Log(LOG_LEVEL_VERBOSE, "Finished exec_command execution, terminating the forked process"); _exit(0); } else { /* parent */ return pid; } } #else static void *LocalExecThread(void *param) { ExecConfig *config = (ExecConfig *) param; LocalExec(config); ExecConfigDestroy(config); Log(LOG_LEVEL_VERBOSE, "Finished exec_command execution, terminating thread"); return NULL; } static bool LocalExecInThread(const ExecConfig *config) { ExecConfig *thread_config = ExecConfigCopy(config); pthread_t tid; Log(LOG_LEVEL_VERBOSE, "Spawning thread for exec_command execution"); int ret = pthread_create(&tid, &threads_attrs, LocalExecThread, thread_config); if (ret != 0) { ExecConfigDestroy(thread_config); Log(LOG_LEVEL_ERR, "Failed to create thread (pthread_create: %s)", GetErrorStr()); return false; } return true; } #endif /* ! __MINGW32__ */ #ifndef __MINGW32__ static void Apoptosis(void) { char promiser_buf[CF_SMALLBUF]; snprintf(promiser_buf, sizeof(promiser_buf), "%s%ccf-execd", GetBinDir(), FILE_SEPARATOR); if (LoadProcessTable()) { char myuid[PRINTSIZE(unsigned)]; xsnprintf(myuid, sizeof(myuid), "%u", (unsigned) getuid()); Rlist *owners = NULL; RlistPrepend(&owners, myuid, RVAL_TYPE_SCALAR); ProcessSelect process_select = PROCESS_SELECT_INIT; process_select.owner = owners; process_select.process_result = "process_owner"; Item *killlist = SelectProcesses(promiser_buf, &(process_select), true); RlistDestroy(owners); for (Item *ip = killlist; ip != NULL; ip = ip->next) { pid_t pid = ip->counter; if (pid != getpid() && kill(pid, SIGTERM) < 0) { if (errno == ESRCH) { /* That's ok, process exited voluntarily */ } else { Log(LOG_LEVEL_ERR, "Unable to kill stale cf-execd process pid=%d. (kill: %s)", (int)pid, GetErrorStr()); } } } } ClearProcessTable(); Log(LOG_LEVEL_VERBOSE, "Pruning complete"); } #endif typedef enum { RELOAD_ENVIRONMENT, RELOAD_FULL } Reload; static Reload CheckNewPromises(GenericAgentConfig *config) { Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file); time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL); bool reload_config = false; if (config->agent_specific.daemon.last_validated_at < validated_at) { Log(LOG_LEVEL_VERBOSE, "New promises detected..."); reload_config = true; } if (ReloadConfigRequested()) { Log(LOG_LEVEL_VERBOSE, "Force reload of inputs files..."); reload_config = true; } if (reload_config) { ClearRequestReloadConfig(); /* Rereading policies now, so update timestamp. */ config->agent_specific.daemon.last_validated_at = validated_at; if (GenericAgentArePromisesValid(config)) { return RELOAD_FULL; } else { Log(LOG_LEVEL_INFO, "New promises file contains syntax errors -- ignoring"); } } else { Log(LOG_LEVEL_DEBUG, "No new promises found"); } return RELOAD_ENVIRONMENT; } static bool ScheduleRun(EvalContext *ctx, Policy **policy, GenericAgentConfig *config, ExecdConfig **execd_config, ExecConfig **exec_config) { /* * FIXME: this logic duplicates the one from cf-serverd.c. Unify ASAP. */ if (CheckNewPromises(config) == RELOAD_FULL) { /* Full reload */ Log(LOG_LEVEL_INFO, "Re-reading promise file '%s'", config->input_file); EvalContextClear(ctx); strcpy(VDOMAIN, "undefined.domain"); PolicyDestroy(*policy); *policy = NULL; EvalContextSetPolicyServerFromFile(ctx, GetWorkDir()); UpdateLastPolicyUpdateTime(ctx); DetectEnvironment(ctx); GenericAgentDiscoverContext(ctx, config, NULL); EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_EXECUTOR], "cfe_internal,source=agent"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); GenericAgentConfigSetBundleSequence(config, NULL); #ifndef __MINGW32__ /* Take over the runagent_socket_allow_users set for comparison. */ StringSet *old_runagent_allow_users = NULL; if (UsingRunagentSocket()) { old_runagent_allow_users = (*execd_config)->runagent_allow_users; (*execd_config)->runagent_allow_users = NULL; } #endif *policy = LoadPolicy(ctx, config); ExecConfigDestroy(*exec_config); ExecdConfigDestroy(*execd_config); *exec_config = ExecConfigNew(!ONCE, ctx, *policy); *execd_config = ExecdConfigNew(ctx, *policy); #ifndef __MINGW32__ if (UsingRunagentSocket()) { /* Check if the old list and the new one differ. */ if (!StringSetIsEqual(old_runagent_allow_users, (*execd_config)->runagent_allow_users)) { struct sockaddr_un sock_info; if (GetRunagentSocketInfo(&sock_info)) { bool success = SetRunagentSocketACLs(sock_info.sun_path, (*execd_config)->runagent_allow_users); if (!success) { Log(LOG_LEVEL_ERR, "Failed to allow new runagent_socket_allow_users users access the runagent socket" " (on policy reload)"); /* keep going anyway */ } } else { Log(LOG_LEVEL_ERR, "Failed to get runagent.socket path"); } } StringSetDestroy(old_runagent_allow_users); } #endif SetFacility((*execd_config)->log_facility); } else { /* Environment reload */ EvalContextClear(ctx); DetectEnvironment(ctx); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); } { StringSetIterator it = StringSetIteratorInit((*execd_config)->schedule); const char *time_context = NULL; while ((time_context = StringSetIteratorNext(&it))) { if (IsDefinedClass(ctx, time_context)) { Log(LOG_LEVEL_VERBOSE, "Waking up the agent at %s ~ %s", ctime(&CFSTARTTIME), time_context); return true; } } } Log(LOG_LEVEL_VERBOSE, "Nothing to do at %s", ctime(&CFSTARTTIME)); return false; } cfengine-3.24.2/libpromises/0000755000000000000000000000000015010704322015700 5ustar00rootroot00000000000000cfengine-3.24.2/libpromises/vars.h0000644000000000000000000000263015010704253017030 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VARS_H #define CFENGINE_VARS_H #include #include size_t ExtractScalarPrefix(Buffer *out, const char *str, size_t len); bool ExtractScalarReference(Buffer *out, const char *str, size_t len, bool extract_inner); bool RlistIsUnresolved(const Rlist *args); bool IsQualifiedVariable(const char *var); bool StringContainsVar(const char *s, const char *v); bool IsCf3VarString(const char *str); #endif cfengine-3.24.2/libpromises/cf3lex.c0000644000000000000000000026110715010704322017237 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /*******************************************************************/ /* */ /* LEXER for cfengine 3 */ /* */ /*******************************************************************/ #include #include #include #include #include #include #include #line 41 "cf3lex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 1 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = NULL; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *yyin = NULL, *yyout = NULL; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #ifdef yytext_ptr #undef yytext_ptr #endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yynoreturn yy_fatal_error (yyconst char* msg ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 31 #define YY_END_OF_BUFFER 32 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[339] = { 0, 0, 0, 0, 0, 32, 30, 28, 1, 30, 30, 30, 29, 30, 30, 30, 19, 30, 30, 19, 30, 19, 19, 10, 14, 15, 15, 28, 1, 1, 0, 0, 0, 26, 0, 0, 29, 0, 0, 0, 0, 0, 22, 19, 0, 21, 0, 0, 25, 19, 0, 26, 19, 19, 19, 10, 14, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 19, 19, 19, 0, 0, 23, 0, 27, 0, 0, 0, 0, 0, 0, 17, 19, 19, 0, 0, 23, 0, 27, 0, 0, 0, 27, 23, 12, 0, 0, 0, 0, 0, 19, 19, 11, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 16, 19, 13, 27, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; static yyconst YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 9, 1, 6, 10, 11, 12, 1, 1, 13, 14, 15, 1, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 1, 1, 18, 19, 1, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 23, 24, 1, 25, 26, 27, 28, 21, 29, 30, 31, 21, 21, 32, 21, 21, 33, 34, 35, 36, 37, 21, 38, 39, 40, 41, 42, 43, 44, 45, 21, 46, 6, 47, 1, 1, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 } ; static yyconst YY_CHAR yy_meta[50] = { 0, 1, 2, 3, 1, 2, 2, 1, 1, 4, 1, 5, 6, 1, 1, 7, 8, 7, 1, 1, 1, 8, 9, 1, 10, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 11, 7, 1 } ; static yyconst flex_uint16_t yy_base[361] = { 0, 0, 0, 47, 49, 834, 835, 52, 0, 830, 815, 48, 0, 45, 49, 812, 68, 811, 54, 99, 803, 146, 22, 0, 835, 825, 797, 59, 0, 0, 809, 808, 59, 807, 68, 55, 0, 65, 66, 58, 82, 83, 835, 107, 121, 835, 61, 792, 138, 84, 796, 835, 101, 93, 105, 0, 835, 121, 804, 803, 152, 0, 148, 807, 142, 771, 157, 0, 800, 777, 786, 809, 132, 142, 145, 774, 783, 835, 178, 835, 181, 187, 174, 781, 778, 179, 176, 182, 184, 779, 776, 181, 783, 782, 220, 781, 226, 780, 198, 835, 772, 199, 772, 771, 187, 210, 213, 835, 769, 212, 229, 52, 198, 835, 759, 773, 216, 770, 752, 760, 219, 227, 835, 835, 764, 751, 756, 748, 750, 757, 756, 223, 749, 756, 747, 754, 742, 748, 747, 755, 741, 748, 747, 738, 734, 733, 731, 733, 746, 735, 739, 734, 733, 736, 733, 722, 738, 751, 736, 735, 721, 722, 727, 714, 0, 713, 712, 714, 717, 713, 720, 737, 718, 717, 714, 734, 705, 705, 835, 704, 703, 704, 721, 697, 654, 653, 613, 599, 246, 597, 595, 594, 573, 576, 835, 570, 259, 541, 525, 524, 517, 536, 264, 266, 527, 485, 465, 456, 271, 457, 273, 278, 447, 414, 437, 425, 835, 412, 280, 123, 285, 287, 291, 405, 387, 382, 293, 298, 253, 300, 835, 376, 305, 362, 307, 312, 351, 314, 319, 320, 325, 326, 331, 339, 835, 302, 333, 835, 295, 341, 346, 348, 353, 354, 288, 357, 359, 90, 160, 282, 371, 365, 367, 373, 378, 379, 384, 279, 385, 390, 392, 334, 396, 404, 408, 268, 410, 415, 261, 417, 422, 398, 403, 423, 428, 835, 254, 430, 227, 436, 442, 438, 444, 449, 450, 453, 455, 459, 460, 462, 466, 468, 474, 480, 346, 476, 482, 487, 489, 214, 490, 186, 495, 497, 503, 509, 505, 474, 511, 503, 188, 514, 516, 521, 524, 529, 523, 529, 531, 534, 543, 133, 109, 539, 542, 320, 546, 90, 835, 562, 573, 583, 591, 602, 613, 623, 630, 638, 649, 660, 665, 669, 679, 689, 692, 696, 704, 712, 720, 728, 69 } ; static yyconst flex_int16_t yy_def[361] = { 0, 338, 1, 339, 339, 338, 338, 338, 340, 338, 341, 342, 343, 338, 344, 338, 345, 338, 338, 346, 347, 346, 21, 348, 338, 338, 338, 338, 340, 340, 341, 341, 342, 338, 342, 349, 343, 350, 351, 344, 344, 352, 338, 345, 353, 338, 338, 338, 353, 21, 347, 338, 21, 21, 21, 348, 338, 338, 341, 338, 349, 349, 350, 354, 351, 355, 352, 352, 48, 338, 338, 338, 21, 21, 21, 338, 338, 338, 349, 338, 356, 357, 352, 338, 338, 338, 21, 21, 21, 338, 338, 349, 358, 358, 356, 359, 357, 359, 352, 338, 338, 338, 338, 338, 338, 21, 21, 338, 338, 338, 354, 338, 355, 338, 338, 338, 338, 338, 338, 338, 21, 21, 338, 338, 338, 338, 338, 338, 338, 338, 338, 21, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 360, 338, 338, 338, 338, 338, 338, 360, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 0, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338 } ; static yyconst flex_uint16_t yy_nxt[885] = { 0, 6, 7, 8, 9, 7, 10, 11, 12, 13, 14, 10, 10, 6, 15, 10, 16, 10, 17, 6, 18, 19, 6, 6, 6, 19, 20, 19, 21, 19, 19, 19, 19, 19, 19, 19, 19, 22, 19, 19, 19, 19, 19, 19, 19, 19, 6, 6, 16, 6, 24, 25, 24, 25, 27, 33, 37, 27, 49, 33, 54, 27, 51, 49, 27, 37, 33, 26, 33, 26, 30, 34, 40, 30, 30, 60, 111, 171, 61, 30, 30, 40, 34, 30, 46, 44, 47, 63, 65, 63, 65, 38, 66, 51, 69, 257, 70, 35, 41, 79, 38, 30, 285, 258, 30, 30, 67, 41, 35, 30, 30, 30, 30, 30, 30, 43, 48, 35, 30, 30, 49, 247, 30, 30, 44, 49, 30, 30, 73, 49, 72, 41, 30, 30, 49, 194, 30, 49, 58, 228, 30, 74, 49, 30, 30, 244, 49, 43, 30, 30, 30, 30, 30, 30, 75, 58, 76, 30, 30, 51, 79, 30, 43, 48, 81, 271, 65, 51, 49, 78, 80, 87, 63, 49, 82, 61, 272, 86, 49, 88, 67, 49, 52, 49, 51, 51, 49, 53, 51, 79, 92, 98, 92, 93, 43, 91, 95, 67, 95, 95, 230, 61, 321, 63, 61, 63, 101, 102, 51, 65, 103, 65, 49, 104, 118, 105, 106, 49, 49, 119, 49, 67, 112, 49, 79, 49, 216, 92, 92, 92, 114, 92, 93, 95, 97, 95, 109, 95, 95, 115, 120, 123, 63, 302, 110, 123, 49, 126, 65, 49, 112, 49, 121, 110, 49, 49, 127, 131, 194, 49, 49, 195, 196, 49, 49, 194, 92, 92, 49, 239, 300, 194, 95, 97, 195, 203, 194, 294, 194, 209, 210, 195, 211, 216, 291, 194, 217, 218, 209, 220, 194, 194, 216, 195, 221, 217, 227, 194, 273, 194, 209, 229, 195, 230, 268, 216, 231, 232, 236, 237, 216, 263, 194, 217, 238, 209, 240, 230, 261, 244, 231, 242, 245, 246, 247, 257, 216, 248, 249, 236, 251, 216, 194, 258, 217, 252, 253, 194, 230, 271, 209, 254, 255, 230, 257, 244, 231, 256, 245, 262, 272, 257, 258, 247, 259, 260, 248, 264, 216, 258, 216, 259, 265, 236, 266, 216, 194, 250, 217, 230, 267, 230, 254, 269, 231, 270, 257, 244, 243, 244, 275, 276, 245, 277, 258, 247, 259, 274, 278, 279, 247, 216, 241, 248, 280, 281, 216, 230, 235, 236, 282, 283, 230, 234, 230, 254, 284, 231, 285, 257, 216, 286, 287, 257, 297, 216, 233, 258, 236, 288, 289, 258, 244, 259, 290, 275, 292, 244, 226, 247, 245, 293, 278, 295, 247, 230, 225, 248, 296, 298, 230, 257, 285, 254, 299, 286, 301, 257, 224, 258, 244, 288, 303, 223, 305, 258, 244, 259, 304, 275, 306, 244, 247, 222, 245, 247, 307, 247, 278, 308, 248, 216, 230, 219, 230, 309, 310, 254, 285, 257, 285, 311, 312, 286, 313, 257, 244, 258, 244, 275, 314, 215, 316, 258, 244, 288, 315, 275, 317, 247, 214, 247, 230, 318, 278, 319, 320, 285, 257, 285, 311, 322, 286, 323, 257, 247, 258, 244, 278, 324, 213, 326, 258, 247, 288, 325, 285, 327, 285, 257, 328, 311, 329, 285, 257, 244, 286, 258, 212, 331, 330, 247, 258, 285, 288, 332, 285, 333, 257, 311, 334, 285, 208, 207, 285, 336, 258, 311, 285, 335, 206, 205, 337, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 28, 28, 204, 28, 28, 28, 28, 28, 28, 28, 28, 30, 202, 201, 30, 30, 30, 30, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 36, 36, 200, 36, 36, 36, 36, 36, 36, 36, 36, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 43, 199, 198, 43, 43, 43, 43, 49, 197, 193, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 55, 55, 192, 55, 55, 55, 55, 55, 55, 55, 55, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 62, 62, 62, 62, 64, 64, 64, 64, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 68, 191, 190, 68, 68, 68, 68, 63, 63, 63, 63, 63, 65, 65, 65, 65, 65, 94, 94, 94, 94, 94, 94, 94, 94, 96, 96, 96, 96, 96, 96, 96, 96, 92, 92, 92, 92, 92, 189, 92, 92, 95, 95, 95, 95, 95, 188, 95, 95, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 172, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 130, 129, 128, 125, 124, 122, 117, 116, 113, 111, 111, 109, 109, 108, 107, 100, 99, 90, 89, 85, 84, 83, 31, 79, 79, 77, 58, 51, 71, 59, 58, 31, 57, 56, 51, 45, 42, 31, 29, 338, 5, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338 } ; static yyconst flex_int16_t yy_chk[885] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 7, 11, 13, 7, 22, 14, 22, 27, 35, 22, 27, 18, 32, 3, 39, 4, 16, 11, 14, 16, 16, 34, 111, 360, 35, 16, 16, 39, 32, 16, 18, 16, 18, 37, 38, 37, 38, 13, 40, 41, 46, 257, 46, 11, 14, 111, 18, 19, 337, 257, 19, 19, 41, 39, 32, 43, 19, 19, 43, 43, 19, 19, 19, 34, 43, 43, 49, 332, 43, 44, 43, 49, 44, 44, 53, 53, 52, 40, 44, 44, 53, 219, 44, 52, 44, 219, 48, 54, 52, 48, 48, 331, 54, 19, 21, 48, 48, 21, 21, 48, 57, 48, 57, 21, 21, 60, 62, 21, 21, 21, 64, 258, 64, 66, 72, 60, 62, 73, 62, 72, 66, 60, 258, 72, 73, 74, 66, 74, 21, 73, 82, 78, 74, 21, 91, 64, 80, 82, 80, 80, 21, 78, 81, 82, 81, 81, 320, 78, 311, 80, 91, 80, 85, 85, 98, 81, 85, 81, 86, 85, 104, 87, 88, 86, 87, 104, 88, 98, 112, 87, 109, 88, 309, 80, 80, 94, 101, 94, 94, 81, 81, 96, 109, 96, 96, 101, 105, 110, 94, 288, 94, 112, 105, 116, 96, 106, 96, 105, 106, 110, 106, 120, 116, 121, 188, 131, 120, 188, 188, 121, 131, 228, 94, 94, 121, 228, 286, 196, 96, 96, 196, 196, 202, 278, 203, 202, 202, 203, 203, 208, 275, 210, 208, 208, 210, 210, 211, 267, 218, 211, 211, 218, 218, 220, 259, 221, 220, 220, 221, 222, 254, 226, 222, 222, 226, 226, 227, 248, 229, 227, 227, 229, 229, 232, 245, 234, 232, 232, 234, 234, 235, 335, 237, 235, 235, 237, 237, 238, 239, 335, 238, 238, 239, 240, 241, 271, 240, 241, 241, 242, 243, 246, 242, 242, 246, 246, 271, 304, 243, 249, 243, 243, 249, 249, 250, 304, 251, 304, 250, 251, 251, 252, 253, 236, 252, 255, 253, 256, 255, 255, 256, 256, 260, 261, 233, 262, 261, 261, 262, 262, 260, 263, 260, 260, 263, 263, 264, 265, 231, 264, 264, 265, 266, 268, 225, 266, 266, 268, 269, 224, 270, 269, 269, 270, 272, 273, 281, 272, 272, 274, 281, 282, 223, 273, 282, 273, 273, 274, 276, 274, 274, 276, 276, 277, 217, 279, 277, 277, 279, 279, 280, 283, 215, 280, 280, 283, 284, 289, 287, 284, 284, 287, 287, 290, 214, 289, 291, 289, 289, 213, 291, 290, 292, 290, 290, 292, 292, 293, 294, 212, 293, 295, 294, 296, 295, 295, 296, 297, 298, 209, 299, 297, 298, 299, 300, 302, 301, 300, 300, 301, 301, 303, 317, 302, 305, 317, 302, 207, 305, 303, 306, 303, 303, 306, 306, 307, 206, 308, 310, 307, 308, 308, 310, 312, 314, 313, 312, 312, 313, 313, 315, 319, 314, 316, 319, 314, 205, 316, 315, 318, 315, 315, 321, 318, 322, 324, 321, 322, 322, 323, 325, 326, 323, 324, 204, 326, 324, 327, 325, 328, 325, 327, 329, 328, 330, 329, 329, 333, 201, 200, 334, 333, 330, 334, 336, 330, 199, 198, 336, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 340, 340, 197, 340, 340, 340, 340, 340, 340, 340, 340, 341, 195, 193, 341, 341, 341, 341, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 343, 343, 192, 343, 343, 343, 343, 343, 343, 343, 343, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 345, 191, 190, 345, 345, 345, 345, 346, 189, 187, 346, 346, 346, 346, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, 348, 348, 186, 348, 348, 348, 348, 348, 348, 348, 348, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 350, 350, 350, 350, 351, 351, 351, 351, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, 353, 185, 184, 353, 353, 353, 353, 354, 354, 354, 354, 354, 355, 355, 355, 355, 355, 356, 356, 356, 356, 356, 356, 356, 356, 357, 357, 357, 357, 357, 357, 357, 357, 358, 358, 358, 358, 358, 183, 358, 358, 359, 359, 359, 359, 359, 182, 359, 359, 181, 180, 179, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 163, 162, 161, 160, 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 130, 129, 128, 127, 126, 125, 124, 119, 118, 117, 115, 114, 108, 103, 102, 100, 97, 95, 93, 92, 90, 89, 84, 83, 76, 75, 71, 70, 69, 68, 65, 63, 59, 58, 50, 47, 33, 31, 30, 26, 25, 20, 17, 15, 10, 9, 5, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, 338 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "cf3lex.l" #line 43 "cf3lex.l" /* yyinput/input are generated and unused */ #if defined(__GNUC__) # define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) # if GCC_VERSION >= 40200 # pragma GCC diagnostic ignored "-Wunused-function" # endif #endif #undef malloc #undef realloc #define malloc xmalloc #define realloc xrealloc //#define ParserDebug if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) printf #define ParserDebug(...) ((void) 0) #define P PARSER_STATE static Regex *context_expression_whitespace_rx = NULL; static int DeEscapeQuotedString(const char *from, char *to); int yywrap(void) { return 1; } static void yyuseraction() { P.offsets.current += yyleng; } #define YY_USER_ACTION yyuseraction(); // Do not use lex - flex only /* * Three types of quoted strings: * * - string in double quotes, starts with double quote, runs until another * double quote, \" masks the double quote. * - string in single quotes, starts with single quote, runs until another * single quote, \' masks the single quote. * - string in backquotes, starts with backquote, runs until another backquote. * * The same rule formatted for the better readability: * * := \" \" | \' \' | ` ` * = * * = \\ | [^"\\] * = * * = \\ | [^'\\] * = * * = [^`] * = . | \n * */ #line 856 "cf3lex.c" #define INITIAL 0 #define if_ignore_state 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * _in_str ); FILE *yyget_out (void ); void yyset_out (FILE * _out_str ); int yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif #ifndef YY_NO_UNPUT static void yyunput (int c,char *buf_ptr ); #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 147 "cf3lex.l" #line 1077 "cf3lex.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 339 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 835 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 148 "cf3lex.l" { free(P.current_line); P.current_line = xstrdup(yytext+1); ParserDebug("L:line %s\n", P.current_line); P.line_no++; P.line_pos = 1; // push back on stack and skip first char yyless(1); } YY_BREAK case 2: YY_RULE_SETUP #line 158 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* minimum = yytext+20; ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, minimum); VersionComparison result = CompareVersion(Version(), minimum); if (result == VERSION_GREATER || result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } YY_BREAK case 3: YY_RULE_SETUP #line 192 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* maximum = yytext+20; ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, maximum); VersionComparison result = CompareVersion(Version(), maximum); if (result == VERSION_SMALLER || result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_GREATER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } YY_BREAK case 4: YY_RULE_SETUP #line 226 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* target = yytext + strlen("@if before_version("); ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, target); VersionComparison result = CompareVersion(Version(), target); if (result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_GREATER || result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } YY_BREAK case 5: YY_RULE_SETUP #line 260 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* target = yytext + strlen("@if at_version("); ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, target); VersionComparison result = CompareVersion(Version(), target); if (result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_GREATER || result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } YY_BREAK case 6: YY_RULE_SETUP #line 294 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* target = yytext + strlen("@if after_version("); ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, target); VersionComparison result = CompareVersion(Version(), target); if (result == VERSION_GREATER) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_EQUAL || result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } YY_BREAK case 7: YY_RULE_SETUP #line 328 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* from = yytext + strlen("@if between_versions("); const char *to = strchr(from, ','); to += 1; while (*to == ' ') { to += 1; } ParserDebug("\tL:macro @if %d:between_versions(%s\n", P.line_pos, from); VersionComparison a = CompareVersion(Version(), from); VersionComparison b = CompareVersion(Version(), to); if ((a == VERSION_EQUAL || a == VERSION_GREATER) && (b == VERSION_EQUAL || b == VERSION_SMALLER)) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } } YY_BREAK case 8: YY_RULE_SETUP #line 367 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } char* feature_text = yytext+12; // remove trailing ')' feature_text[strlen(feature_text)-1] = 0; ParserDebug("\tL:macro @if %d:feature=%s\n", P.line_pos, feature_text); { if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; if (KnownFeature(feature_text)) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else { /* ignore to the next @endif */ ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } } } YY_BREAK case 9: YY_RULE_SETUP #line 400 "cf3lex.l" { if ( P.line_pos != 1 ) { yyerror("fatal: macro @endif must be at beginning of the line."); return 0; } ParserDebug("\tL:macro @endif %d\n", P.line_pos); BEGIN(INITIAL); if (P.if_depth <= 0) { yyerror("fatal: @endif macros without a matching @if are not allowed"); return 0; } P.if_depth--; } YY_BREAK case 10: YY_RULE_SETUP #line 418 "cf3lex.l" { ParserDebug("\tL:inside macro @if, ignoring line text:\"%s\"\n", yytext); } YY_BREAK case 11: YY_RULE_SETUP #line 422 "cf3lex.l" { ParserDebug("\tL:macro @else, will no longer ignore lines\n", P.line_pos); BEGIN(INITIAL); } YY_BREAK case 12: YY_RULE_SETUP #line 426 "cf3lex.l" { if (P.if_depth <= 0) { yyerror("fatal: @else macro without a matching @if are not allowed"); return 0; } ParserDebug("\tL:macro @else, will now ignore lines\n", P.line_pos); BEGIN(if_ignore_state); } YY_BREAK case 13: YY_RULE_SETUP #line 436 "cf3lex.l" { ParserDebug("\tL:macro @endif %d\n", P.line_pos); BEGIN(INITIAL); if (P.if_depth <= 0) { yyerror("fatal: @endif macros without a matching @if are not allowed"); return 0; } P.if_depth--; } YY_BREAK case 14: /* rule 14 can match eol */ YY_RULE_SETUP #line 447 "cf3lex.l" { } YY_BREAK case 15: YY_RULE_SETUP #line 450 "cf3lex.l" { /* eat up al unknown chars when line starts with @*/ ParserDebug("\tL:inside macro @if, ignoring char text:\"%s\"\n", yytext); } YY_BREAK case 16: YY_RULE_SETUP #line 455 "cf3lex.l" { /* Note this has to come before "id" since it is a subset of id */ if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.line_pos += yyleng; ParserDebug("\tL:bundle %d\n", P.line_pos); return BUNDLE; } YY_BREAK case 17: YY_RULE_SETUP #line 475 "cf3lex.l" { /* Note this has to come before "id" since it is a subset of id */ if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.line_pos += yyleng; ParserDebug("\tL:body %d\n", P.line_pos); return BODY; } YY_BREAK case 18: YY_RULE_SETUP #line 495 "cf3lex.l" { /* Note this has to come before "id" since it is a subset of id */ if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.line_pos += yyleng; ParserDebug("\tL:promise %d\n", P.line_pos); return PROMISE; } YY_BREAK case 19: YY_RULE_SETUP #line 515 "cf3lex.l" { P.offsets.last_id = P.offsets.current - yyleng; P.line_pos += yyleng; ParserDebug("\tL:id %s %d\n", yytext, P.line_pos); if (yyleng > CF_MAXVARSIZE-1) { yyerror("identifier too long"); } strncpy(P.currentid, yytext, CF_MAXVARSIZE - 1); return IDENTIFIER; } YY_BREAK case 20: YY_RULE_SETUP #line 528 "cf3lex.l" { P.offsets.last_id = P.offsets.current - yyleng; P.line_pos += yyleng; ParserDebug("\tL:symbol %s %d\n", yytext, P.line_pos); if (yyleng > CF_MAXVARSIZE-1) { yyerror("qualified identifier too long"); } strncpy(P.currentid, yytext, CF_MAXVARSIZE - 1); return IDENTIFIER; } YY_BREAK case 21: YY_RULE_SETUP #line 541 "cf3lex.l" { P.line_pos += yyleng; ParserDebug("\tL:assign %d\n", P.line_pos); return FAT_ARROW; } YY_BREAK case 22: YY_RULE_SETUP #line 547 "cf3lex.l" { P.line_pos += yyleng; ParserDebug("\tL:arrow %d\n", P.line_pos); return THIN_ARROW; } YY_BREAK case 23: /* rule 23 can match eol */ YY_RULE_SETUP #line 553 "cf3lex.l" { char *tmp = NULL; P.line_pos += yyleng; ParserDebug("\tL:varclass %s %d\n", yytext, P.line_pos); tmp = xstrdup(yytext+1); // remove leading quote tmp[yyleng-4] = '\0'; // remove tail quote plus :: if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.currentvarclasses = xstrdup(tmp); free(tmp); return CLASS_GUARD; } YY_BREAK case 24: YY_RULE_SETUP #line 580 "cf3lex.l" { char *tmp = NULL; P.line_pos += yyleng; ParserDebug("\tL:class %s %d\n", yytext, P.line_pos); if (context_expression_whitespace_rx == NULL) { context_expression_whitespace_rx = CompileRegex(CFENGINE_REGEX_WHITESPACE_IN_CONTEXTS); } if (context_expression_whitespace_rx == NULL) { yyerror("The context expression whitespace regular expression could not be compiled, aborting."); } if (StringMatchFullWithPrecompiledRegex(context_expression_whitespace_rx, yytext)) { yyerror("class names can't be separated by whitespace without an intervening operator"); } tmp = xstrdup(yytext); tmp[yyleng-2] = '\0'; if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.currentclasses = xstrdup(tmp); free(tmp); return CLASS_GUARD; } YY_BREAK case 25: YY_RULE_SETUP #line 621 "cf3lex.l" { char *tmp = NULL; P.line_pos += yyleng; ParserDebug("\tL:promise_guard %s %d\n", yytext, P.line_pos); P.offsets.last_promise_guard_id = P.offsets.current - yyleng; tmp = xstrdup(yytext); assert(tmp[yyleng - 1] == ':'); tmp[yyleng - 1] = '\0'; // Exclude trailing colon in promise guard assert(strlen(tmp) > 0); assert(tmp[strlen(tmp) - 1] != ':'); strncpy(P.currenttype, tmp, CF_MAXVARSIZE - 1); if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } free(tmp); return PROMISE_GUARD; } YY_BREAK case 26: /* rule 26 can match eol */ YY_RULE_SETUP #line 652 "cf3lex.l" { char *tmp = NULL; int less = 0; P.offsets.last_string = P.offsets.current - yyleng; P.line_pos += yyleng; ParserDebug("\tL:qstring %s %d\n", yytext, P.line_pos); for (char *c = yytext; *c; ++c) { if (*c == '\n') { P.line_no++; } } tmp = xmalloc(yyleng + 1); if ((less = DeEscapeQuotedString(yytext,tmp)) > 0) { yyless(less); P.offsets.current -= less; } if (P.currentstring) { free(P.currentstring); } P.currentstring = xstrdup(tmp); free(tmp); return QUOTED_STRING; } YY_BREAK case 27: YY_RULE_SETUP #line 688 "cf3lex.l" { P.line_pos += yyleng; ParserDebug("\tL: %s %d\n", yytext, P.line_pos); if (P.currentstring) { free(P.currentstring); } P.currentstring = xstrdup(yytext); return NAKEDVAR; } YY_BREAK case 28: YY_RULE_SETUP #line 699 "cf3lex.l" { P.line_pos += yyleng; } YY_BREAK case 29: YY_RULE_SETUP #line 703 "cf3lex.l" { } YY_BREAK case 30: YY_RULE_SETUP #line 707 "cf3lex.l" { P.line_pos++; return yytext[0]; } YY_BREAK case YY_STATE_EOF(if_ignore_state): #line 712 "cf3lex.l" { if (P.if_depth > 0) { yyerror("EOF seen while @if was waiting for @endif in ignore_state"); return 0; } } YY_BREAK case YY_STATE_EOF(INITIAL): #line 720 "cf3lex.l" { if (P.if_depth > 0) { yyerror("EOF seen while @if was waiting for @endif without ignore_state"); } return 0; // loops forever without this } YY_BREAK case 31: YY_RULE_SETUP #line 728 "cf3lex.l" ECHO; YY_BREAK #line 1813 "cf3lex.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { yy_state_type yy_current_state; char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 49); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 339 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { int yy_is_jam; char *yy_cp = (yy_c_buf_p); YY_CHAR yy_c = 49; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 339 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; yy_is_jam = (yy_current_state == 338); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT static void yyunput (int c, char * yy_bp ) { char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ int number_to_move = (yy_n_chars) + 2; char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = (yy_size_t)size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,(int) strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param _line_number line number * */ void yyset_lineno (int _line_number ) { yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str ) { yyin = _in_str ; } void yyset_out (FILE * _out_str ) { yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int _bdebug ) { yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = NULL; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 728 "cf3lex.l" static int DeEscapeQuotedString(const char *from, char *to) { char *cp; const char *sp; char start = *from; int len = strlen(from); if (len == 0) { return 0; } for (sp = from + 1, cp = to; (sp - from) < len; sp++, cp++) { if ((*sp == start)) { *(cp) = '\0'; if (*(sp + 1) != '\0') { return (2 + (sp - from)); } return 0; } if (*sp == '\\') { switch (*(sp + 1)) { case '\n': sp += 2; break; case ' ': break; case '\\': case '\"': case '\'': sp++; break; } } *cp = *sp; } yyerror("Runaway string"); *(cp) = '\0'; return 0; } /* EOF */ cfengine-3.24.2/libpromises/verify_classes.h0000644000000000000000000000226015010704253021075 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_CLASSES_H #define CFENGINE_VERIFY_CLASSES_H #include #include PromiseResult VerifyClassPromise(EvalContext *ctx, const Promise *pp, void *param); #endif cfengine-3.24.2/libpromises/process_unix.c0000644000000000000000000002006615010704253020574 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #define SLEEP_POLL_TIMEOUT_NS 10000000 /* * Wait until process specified by #pid is stopped due to SIGSTOP signal. * * @returns true if process has come to stop during #timeout_ns nanoseconds, * false if the process cannot be found or failed to stop during #timeout_ns * nanoseconds. * * FIXME: Only timeouts < 1s are supported */ static bool ProcessWaitUntilStopped(pid_t pid, long timeout_ns) { while (timeout_ns > 0) { switch (GetProcessState(pid)) { case PROCESS_STATE_RUNNING: break; /* retry in a while */ case PROCESS_STATE_STOPPED: return true; case PROCESS_STATE_ZOMBIE: /* There is not much we can do by waiting a zombie process. It * will never change to a stopped state. */ return false; case PROCESS_STATE_DOES_NOT_EXIST: return false; } struct timespec ts = { .tv_sec = 0, .tv_nsec = MIN(SLEEP_POLL_TIMEOUT_NS, timeout_ns), }; while (nanosleep(&ts, &ts) < 0) { if (errno != EINTR) { ProgrammingError("Invalid timeout for nanosleep"); } } timeout_ns = MAX(0, timeout_ns - SLEEP_POLL_TIMEOUT_NS); } return false; } /* * Currently only timeouts < 1s are supported */ static bool ProcessWaitUntilExited(pid_t pid, long timeout_ns) { assert(timeout_ns < 1000000000); while (timeout_ns > 0) { switch (GetProcessState(pid)) { case PROCESS_STATE_RUNNING: break; /* retry in a while */ case PROCESS_STATE_DOES_NOT_EXIST: return true; case PROCESS_STATE_ZOMBIE: /* There is not much we can do by waiting a zombie process. It's the responsibility of the caller to reap the child so we're considering it has already exited. */ return true; case PROCESS_STATE_STOPPED: /* Almost the same case with a zombie process, but it will * respond only to signals that can't be caught. */ return false; } struct timespec ts = { .tv_sec = 0, .tv_nsec = MIN(SLEEP_POLL_TIMEOUT_NS, timeout_ns), }; Log(LOG_LEVEL_DEBUG, "PID %jd still alive after signalling, waiting for %lu ms...", (intmax_t) pid, ts.tv_nsec / 1000000); while (nanosleep(&ts, &ts) < 0) { if (errno != EINTR) { ProgrammingError("Invalid timeout for nanosleep"); } } timeout_ns = MAX(0, timeout_ns - SLEEP_POLL_TIMEOUT_NS); } return false; } /* A timeout (in nanoseconds) to wait for process to stop (pause) or exit. * Note that it's important that it does not overflow 32 bits; no more than * nine 9s in a row, i.e. one second. */ #define STOP_WAIT_TIMEOUT 999999999L /* * Safely kill process by checking that the process is the right one by matching * process start time. * * The algorithm: * * 1. Check that the process has the same start time as stored in lock. If it * is not, return, as we know for sure this is a wrong process. (This step * is an optimization to avoid sending SIGSTOP/SIGCONT to wrong processes). * * 2. Send SIGSTOP to the process. * * 3. Poll process state until it is stopped. * * Now the process is stopped, so we may examine it and not be afraid that it * will exit and another one with the same PID will appear. * * 4. Check that the process has the same start time as provided. * If it is, send the signal to the process. * * 5. Send SIGCONT to the process, so it may continue. * * * Returns 0 on success, -1 on error. Error code is signalled through errno. * * ERRORS * * EINVAL An invalid signal was specified. * EPERM The process does not have permission to send the signal. * ESRCH The pid does not exist or its start time does not match expected one. */ static int SafeKill(pid_t pid, time_t expected_start_time, int signal) { /* Preliminary check: in case process start time is different already, we * are sure we don't want to STOP it or kill it. */ time_t pid_start_time = GetProcessStartTime(pid); if (pid_start_time != expected_start_time) { errno = ESRCH; return -1; } /* Now to avoid race conditions we need to stop process so it won't exit * voluntarily while we are working on it */ if (kill(pid, SIGSTOP) < 0) { return -1; } if (!ProcessWaitUntilStopped(pid, STOP_WAIT_TIMEOUT)) { /* Ensure the process is started again in case of timeout or error, so * we don't leave SIGSTOP'ed processes around on overloaded or * misconfigured machine */ kill(pid, SIGCONT); errno = ESRCH; return -1; } /* Here process has stopped, so we may interrogate it without race conditions */ pid_start_time = GetProcessStartTime(pid); if (pid_start_time != expected_start_time) { /* This is a wrong process, let it continue */ kill(pid, SIGCONT); errno = ESRCH; return -1; } /* We've got a right process, signal it and let it continue */ int ret = kill(pid, signal); int saved_errno = errno; /* * We don't check return value of SIGCONT, as the process may have been * terminated already by previous kill. Moreover, what would we do with the * return code? */ kill(pid, SIGCONT); errno = saved_errno; return ret; } static int Kill(pid_t pid, time_t process_start_time, int signal) { if (process_start_time == PROCESS_START_TIME_UNKNOWN) { /* We don't know when the process has started, do a plain kill(2) */ return kill(pid, signal); } else { return SafeKill(pid, process_start_time, signal); } } bool GracefulTerminate(pid_t pid, time_t process_start_time) { /* We can't allow to kill ourselves. First it does not make sense, and * second, once SafeKill() sends SIGSTOP, we will just freeze forever. */ if (pid == getpid()) { Log(LOG_LEVEL_WARNING, "Ignoring request to kill ourself (pid %jd)!", (intmax_t) pid); return false; } if (Kill(pid, process_start_time, SIGINT) < 0) { /* If we failed to kill the process return error. If the process * doesn't even exist (errno==ESRCH), again return error, we shouldn't * have signalled the PID in the first place. */ return false; } if (ProcessWaitUntilExited(pid, STOP_WAIT_TIMEOUT)) { return true; } if (Kill(pid, process_start_time, SIGTERM) < 0) { return errno == ESRCH; } if (ProcessWaitUntilExited(pid, STOP_WAIT_TIMEOUT)) { return true; } if (Kill(pid, process_start_time, SIGKILL) < 0) { return errno == ESRCH; } return true; } cfengine-3.24.2/libpromises/monitoring_read.h0000644000000000000000000000374115010704253021241 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MONITORING_READ_H #define CFENGINE_MONITORING_READ_H #include extern MonitoringSlot *SLOTS[CF_OBSERVABLES - ob_spare]; void Nova_FreeSlot(MonitoringSlot *slot); MonitoringSlot *Nova_MakeSlot(const char *name, const char *description, const char *units, double expected_minimum, double expected_maximum, bool consolidable); void Nova_LoadSlots(void); bool NovaHasSlot(int idx); const char *NovaGetSlotName(int idx); const char *NovaGetSlotDescription(int index); const char *NovaGetSlotUnits(int index); double NovaGetSlotExpectedMinimum(int index); double NovaGetSlotExpectedMaximum(int index); bool NovaIsSlotConsolidable(int index); bool GetRecordForTime(CF_DB *db, time_t time, Averages *result); /* - date-related functions - */ void MakeTimekey(time_t time, char *result); time_t WeekBegin(time_t time); time_t SubtractWeeks(time_t time, int weeks); time_t NextShift(time_t time); #endif cfengine-3.24.2/libpromises/enterprise_extension.c0000644000000000000000000000450715010704322022326 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* #### THIS FILE WAS AUTOGENERATED FROM extensions_template.[ch].pre #### */ #include #include /* getenv() */ #include /* strerror() */ #include #include #ifndef BUILTIN_EXTENSIONS static pthread_once_t enterprise_library_once = PTHREAD_ONCE_INIT; static void *enterprise_library_handle = NULL; static void enterprise_library_assign(); void *enterprise_library_open() { if (getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE") != NULL) { return extension_library_open(ENTERPRISE_LIBRARY_NAME); } int ret = pthread_once(&enterprise_library_once, &enterprise_library_assign); if (ret != 0) { Log(LOG_LEVEL_ERR, "Could not initialize Extension Library: %s: %s", ENTERPRISE_LIBRARY_NAME, strerror(ret)); return NULL; } return enterprise_library_handle; } static void enterprise_library_assign() { enterprise_library_handle = extension_library_open(ENTERPRISE_LIBRARY_NAME); } void enterprise_library_close(void *handle) { if (getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE") != NULL) { return extension_library_close(handle); } // Normally we don't ever close the extension library, because we may have // pointer references to it. } #endif // BUILTIN_EXTENSIONS cfengine-3.24.2/libpromises/pipes.h0000644000000000000000000000612015010704253017173 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PIPES_H #define CFENGINE_PIPES_H #include typedef struct { int write_fd; int read_fd; FILE *write_stream; FILE *read_stream; } IOData; typedef enum OutputSelect { OUTPUT_SELECT_BOTH, OUTPUT_SELECT_STDOUT, OUTPUT_SELECT_STDERR, } OutputSelect; IOData cf_popen_full_duplex(const char *command, bool capture_stderr, bool require_full_path); IOData cf_popen_full_duplex_streams(const char *command, bool capture_stderr, bool require_full_path); int cf_pclose_full_duplex(IOData *data); int cf_pclose_full_duplex_side(int fd); FILE *cf_popen(const char *command, const char *type, bool capture_stderr); FILE *cf_popen_select(const char *command, const char *type, OutputSelect output_select); FILE *cf_popensetuid(const char *command, const Seq *arglist, const char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, int background); FILE *cf_popen_sh(const char *command, const char *type); FILE *cf_popen_sh_select(const char *command, const char *type, OutputSelect output_select); FILE *cf_popen_shsetuid(const char *command, const char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, int background); int cf_pclose(FILE *pp); void cf_pclose_nowait(FILE *pp); bool PipeToPid(pid_t *pid, FILE *pp); bool PipeTypeIsOk(const char *type); int PipeIsReadWriteReady(const IOData *io, int timeout_sec); Rlist *PipeReadData(const IOData *io, int pipe_timeout_secs, int pipe_termination_check_secs); ssize_t PipeWrite(IOData *io, const char *data); int PipeWriteData(const char *base_cmd, const char *args, const char *data); int PipeReadWriteData(const char *base_command, const char *args, const char *request, Rlist **response, int pipe_timeout_secs, int pipe_termination_check_secs); #ifdef __MINGW32__ FILE *cf_popen_powershell(const char *command, const char *type); FILE *cf_popen_powershell_select(const char *command, const char *type, OutputSelect output_select); FILE *cf_popen_powershell_setuid(const char *command, const char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, int background); #endif #endif cfengine-3.24.2/libpromises/feature.h0000644000000000000000000000025215010704253017506 0ustar00rootroot00000000000000#ifndef CFENGINE_FEATURE_H #define CFENGINE_FEATURE_H int KnownFeature(const char *feature); void CreateHardClassesFromFeatures(EvalContext *ctx, char *tags); #endif cfengine-3.24.2/libpromises/mod_common.h0000644000000000000000000000411315010704253020202 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_COMMON_H #define CFENGINE_MOD_COMMON_H #include typedef enum { SERVER_CONTROL_ALLOW_ALL_CONNECTS, SERVER_CONTROL_ALLOW_CONNECTS, SERVER_CONTROL_ALLOW_USERS, SERVER_CONTROL_AUDITING, SERVER_CONTROL_BIND_TO_INTERFACE, SERVER_CONTROL_CFRUNCOMMAND, SERVER_CONTROL_CALL_COLLECT_INTERVAL, SERVER_CONTROL_CALL_COLLECT_WINDOW, SERVER_CONTROL_DENY_BAD_CLOCKS, SERVER_CONTROL_DENY_CONNECTS, SERVER_CONTROL_DYNAMIC_ADDRESSES, SERVER_CONTROL_HOSTNAME_KEYS, SERVER_CONTROL_KEY_TTL, SERVER_CONTROL_LOG_ALL_CONNECTIONS, SERVER_CONTROL_LOG_ENCRYPTED_TRANSFERS, SERVER_CONTROL_MAX_CONNECTIONS, SERVER_CONTROL_PORT_NUMBER, SERVER_CONTROL_SERVER_FACILITY, SERVER_CONTROL_SKIP_VERIFY, SERVER_CONTROL_TRUST_KEYS_FROM, SERVER_CONTROL_LISTEN, SERVER_CONTROL_ALLOWCIPHERS, SERVER_CONTROL_ALLOWLEGACYCONNECTS, SERVER_CONTROL_ALLOWTLSVERSION, SERVER_CONTROL_MAX } ServerControl; extern const ConstraintSyntax CFS_CONTROLBODY[SERVER_CONTROL_MAX + 1]; CommonControl CommonControlFromString(const char *lval); #endif cfengine-3.24.2/libpromises/mod_environ.c0000644000000000000000000000735615010704253020401 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax environment_resources_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewInt("env_cpus", CF_VALRANGE, "Number of virtual CPUs in the environment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("env_memory", CF_VALRANGE, "Amount of primary storage (RAM) in the virtual environment (KB)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("env_disk", CF_VALRANGE, "Amount of secondary storage (DISK) in the virtual environment (MB)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("env_baseline", CF_ABSPATHRANGE, "The path to an image with which to baseline the virtual environment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("env_spec", CF_ANYSTRING, "A string containing a technology specific set of promises for the virtual instance", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax environment_resources_body = BodySyntaxNew("environment_resources", environment_resources_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax environment_interface_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("env_addresses", "", "The IP addresses of the environment's network interfaces", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("env_name", "", "The hostname of the virtual environment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("env_network", "", "The hostname of the virtual network", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax environment_interface_body = BodySyntaxNew("environment_interface", environment_interface_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax CF_ENVIRON_BODIES[] = { ConstraintSyntaxNewString("environment_host", "[a-zA-Z0-9_]+", "A class indicating which physical node will execute this guest machine", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("environment_interface", &environment_interface_body, "Virtual environment outward identity and location", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("environment_resources", &environment_resources_body, "Virtual environment resource description", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("environment_state", "create,delete,running,suspended,down", "The desired dynamical state of the specified environment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("environment_type", "xen,kvm,esx,vbox,test,xen_net,kvm_net,esx_net,test_net,zone,ec2,eucalyptus", "Virtual environment type", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_ENVIRONMENT_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "guest_environments", CF_ENVIRON_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/files_names.h0000644000000000000000000000504015010704253020340 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_NAMES_H #define CFENGINE_FILES_NAMES_H #include typedef enum { FILE_PATH_TYPE_ABSOLUTE, // /foo.cf FILE_PATH_TYPE_RELATIVE, // ./../foo.cf FILE_PATH_TYPE_NON_ANCHORED, // foo.cf } FilePathType; FilePathType FilePathGetType(const char *file_path); bool IsNewerFileTree(const char *dir, time_t reftime); int CompareCSVName(const char *s1, const char *s2); bool IsDir(const char *path); char *JoinSuffix(char *path, size_t path_size, const char *leaf); char *JoinPaths(char *path, size_t path_size, const char *leaf_path); bool IsAbsPath(const char *path); void AddSlash(char *str); char *GetParentDirectoryCopy(const char *path); void DeleteSlash(char *str); void DeleteRedundantSlashes(char *str); const char *FirstFileSeparator(const char *str); const char *LastFileSeparator(const char *str); bool ChopLastNode(char *str); char *CanonifyName(const char *str); void TransformNameInPlace(char *s, char from, char to); char *CanonifyChar(const char *str, char ch); const char *ReadLastNode(const char *str); bool CompressPath(char *dest, size_t dest_size, const char *src); char *GetAbsolutePath(const char *path); char *GetRealPath(const char *path); bool IsFileOutsideDefaultRepository(const char *f); int RootDirLength(const char *f); const char *GetSoftwareCacheFilename(char *buffer); const char *GetSoftwarePatchesFilename(char *buffer); /** * Detect whether package manager starts with an env command instead of package manager, * and if so, return the real package manager. */ const char *RealPackageManager(const char *manager); #endif cfengine-3.24.2/libpromises/files_lib.h0000644000000000000000000000566415010704253020017 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_LIB_H #define CFENGINE_FILES_LIB_H #include #include void PurgeItemList(Item **list, char *name); bool FileWriteOver(char *filename, char *contents); bool LoadFileAsItemList(Item **liststart, const char *file, EditDefaults edits, bool only_checks); /** * @see MakeParentDirectoryForPromise() */ bool MakeParentDirectory(const char *parentandchild, bool force, bool *created); /** * Identical to MakeParentDirectory, but allows you to specify permissions (mode) */ bool MakeParentDirectoryPerms(const char *parentandchild, bool force, bool *created, mode_t perms_mode); /** * Create an internal directory (never in the changes chroot). */ bool MakeParentInternalDirectory(const char *parentandchild, bool force, bool *created); /** * @warning This function will not behave right on Windows if the path * contains double (back)slashes! **/ bool MakeParentDirectoryForPromise(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *parentandchild, bool force, bool *created, mode_t perms_mode); void RotateFiles(const char *name, int number); void CreateEmptyFile(char *name); /** * @brief This is a somewhat simpler version of nftw that support user_data. * Callback function must return 0 to indicate success, -1 for failure. * @param path Path to traverse * @param user_data User data carry * @return True if successful */ bool TraverseDirectoryTree(const char *path, int (*callback)(const char *path, const struct stat *sb, void *user_data), void *user_data); bool HashDirectoryTree(const char *path, const char **extensions_filter, EVP_MD_CTX *crypto_context); #include #endif cfengine-3.24.2/libpromises/cf3globals.c0000644000000000000000000001232415010704253020070 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include /*****************************************************************************/ /* flags */ /*****************************************************************************/ /*****************************************************************************/ /* operational state */ /*****************************************************************************/ bool FIPS_MODE = false; /* GLOBAL_P */ struct utsname VSYSNAME; /* GLOBAL_E, initialized later */ int CFA_MAXTHREADS = 10; /* GLOBAL_P */ int CF_PERSISTENCE = 10; /* GLOBAL_P */ AgentType THIS_AGENT_TYPE; /* GLOBAL_C, initialized later */ /*****************************************************************************/ /* Internal data structures */ /*****************************************************************************/ long LASTSEENEXPIREAFTER = SECONDS_PER_WEEK; /* GLOBAL_P */ /*****************************************************************************/ /* Compatibility infrastructure */ /*****************************************************************************/ /* The mode policy is evaluated in (normal, dry-run, audit,...) */ EvalMode EVAL_MODE = EVAL_MODE_NORMAL; /* NB! Check use before changing sizes */ // Note: These were previously all CF_MAXVARSIZE = 1024 size // However, to avoid problematic truncation, we changed the last 2 to 512, // thus they will fit into VFQNAME ("%s.%s"). // This RFC indicates that DNS only supports up to 255 bytes, anyway: // https://tools.ietf.org/html/rfc2181#section-11 char VFQNAME[CF_MAXVARSIZE] = ""; /* GLOBAL_E GLOBAL_P */ char VUQNAME[CF_MAXVARSIZE / 2] = ""; /* GLOBAL_E */ char VDOMAIN[CF_MAXVARSIZE / 2] = ""; /* GLOBAL_E GLOBAL_P */ /* Default value for copytype attribute. Loaded by cf-agent from body control */ const char *DEFAULT_COPYTYPE = NULL; /* GLOBAL_P */ /* Keys for the agent. Loaded by LoadSecretKeys. Used in network protocol and leaked to language. */ RSA *PRIVKEY = NULL, *PUBKEY = NULL; /* GLOBAL_X */ /* First IP address discovered by DetectEnvironment (hence reloaded every policy change). Used somewhere in cf-execd, superficially in old-style protocol handshake and sporadically in other situations. */ char VIPADDRESS[CF_MAX_IP_LEN] = ""; /* GLOBAL_E */ /* Edition-time constant (MD5 for community, something else for Enterprise) Used as a default hash everywhere (not only in network protocol) */ HashMethod CF_DEFAULT_DIGEST; /* GLOBAL_C, initialized later */ int CF_DEFAULT_DIGEST_LEN; /* GLOBAL_C, initialized later */ /* Holds the "now" time captured at the moment of policy (re)load. TODO: This variable should be internal to timeout.c, not exposed. It should only be set by SetStartTime() and read by GetStartTime(). Utilized everywhere "now" start time is needed */ time_t CFSTARTTIME; /* GLOBAL_E, initialized later */ /* Set in cf-agent/cf-runagent (from control body). Used as a timeout for socket operations in network code. */ time_t CONNTIMEOUT = 30; /* seconds */ /* GLOBAL_A GLOBAL_P */ /* Internal detail of timeout operations. Due to historical reasons is defined here, not in libpromises/timeout.c */ pid_t ALARM_PID = -1; /* GLOBAL_X */ /* Set in cf-agent (from control body). Used as a default value for maxfilesize attribute in policy */ int EDITFILESIZE = 100000; /* GLOBAL_P */ /* Set in cf-agent (from control body) and GenericAgentInitialize. Used as a default value for ifelapsed attribute in policy. */ int VIFELAPSED = 1; /* GLOBAL_P */ /* Set in cf-agent (from control body) and GenericAgentInitialize. Used as a default value for expireafter attribute in policy. */ int VEXPIREAFTER = 120; /* GLOBAL_P */ /* Set in cf-agent/cf-serverd (from control body). Utilized in server/client code to bind sockets. */ char BINDINTERFACE[CF_MAXVARSIZE]; /* GLOBAL_P */ /* Set in cf-*.c:CheckOpts and GenericAgentConfigParseArguments. Utilized in generic_agent.c for - cf_promises_validated filename - GenericAgentCheckPolicy - GenericAgentLoadPolicy (ReadPolicyValidatedFile) */ bool MINUSF = false; /* GLOBAL_A */ cfengine-3.24.2/libpromises/files_operators.c0000644000000000000000000003374115010704253021257 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool MoveObstruction(EvalContext *ctx, char *from, const Attributes *attr, const Promise *pp, PromiseResult *result) { assert(attr != NULL); struct stat sb; char stamp[CF_BUFSIZE], saved[CF_BUFSIZE]; time_t now_stamp = time((time_t *) NULL); const char *changes_from = from; if (ChrootChanges()) { changes_from = ToChangesChroot(from); } if (lstat(from, &sb) == 0) { if (!attr->move_obstructions) { RecordFailure(ctx, pp, attr, "Object '%s' is obstructing promise", from); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (!S_ISDIR(sb.st_mode)) { if (!MakingChanges(ctx, pp, attr, result, "move aside object '%s' obstructing promise", from)) { return false; } saved[0] = '\0'; strlcpy(saved, changes_from, sizeof(saved)); if (attr->copy.backup == BACKUP_OPTION_TIMESTAMP || attr->edits.backup == BACKUP_OPTION_TIMESTAMP) { snprintf(stamp, CF_BUFSIZE, "_%jd_%s", (intmax_t) CFSTARTTIME, CanonifyName(ctime(&now_stamp))); strlcat(saved, stamp, sizeof(saved)); } strlcat(saved, CF_SAVED, sizeof(saved)); if (rename(changes_from, saved) == -1) { RecordFailure(ctx, pp, attr, "Can't rename '%s' to '%s'. (rename: %s)", from, saved, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, attr, "Moved obstructing object '%s' to '%s'", from, saved); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); if (ArchiveToRepository(saved, attr)) { RecordChange(ctx, pp, attr, "Archived '%s'", saved); unlink(saved); } return true; } if (S_ISDIR(sb.st_mode)) { if (!MakingChanges(ctx, pp, attr, result, "move aside directory '%s' obstructing", from)) { return false; } saved[0] = '\0'; strlcpy(saved, changes_from, sizeof(saved)); snprintf(stamp, CF_BUFSIZE, "_%jd_%s", (intmax_t) CFSTARTTIME, CanonifyName(ctime(&now_stamp))); strlcat(saved, stamp, sizeof(saved)); strlcat(saved, CF_SAVED, sizeof(saved)); strlcat(saved, ".dir", sizeof(saved)); if (stat(saved, &sb) != -1) { RecordFailure(ctx, pp, attr, "Couldn't move directory '%s' aside, since '%s' exists already", from, saved); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (rename(changes_from, saved) == -1) { RecordFailure(ctx, pp, attr, "Can't rename '%s' to '%s'. (rename: %s)", from, saved, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, attr, "Moved directory '%s' to '%s%s'", from, from, CF_SAVED); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } return true; } /*********************************************************************/ bool SaveAsFile(SaveCallbackFn callback, void *param, const char *file, const Attributes *a, NewLineMode new_line_mode) { assert(a != NULL); struct stat statbuf; char new[CF_BUFSIZE], backup[CF_BUFSIZE]; char stamp[CF_BUFSIZE]; time_t stamp_now; Buffer *deref_file = BufferNewFrom(file, strlen(file)); Buffer *pretty_file = BufferNew(); bool ret = false; BufferPrintf(pretty_file, "'%s'", file); stamp_now = time((time_t *) NULL); while (1) { if (lstat(BufferData(deref_file), &statbuf) == -1) { Log(LOG_LEVEL_ERR, "Can no longer access file %s, which needed editing. (lstat: %s)", BufferData(pretty_file), GetErrorStr()); goto end; } #ifndef __MINGW32__ if (S_ISLNK(statbuf.st_mode)) { char buf[statbuf.st_size + 1]; // Careful. readlink() doesn't add '\0' byte. ssize_t linksize = readlink(BufferData(deref_file), buf, statbuf.st_size); if (linksize == 0) { Log(LOG_LEVEL_WARNING, "readlink() failed with 0 bytes. Should not happen (bug?)."); goto end; } else if (linksize < 0) { Log(LOG_LEVEL_ERR, "Could not read link %s. (readlink: %s)", BufferData(pretty_file), GetErrorStr()); goto end; } buf[linksize] = '\0'; if (!IsAbsPath(buf)) { char dir[BufferSize(deref_file) + 1]; strcpy(dir, BufferData(deref_file)); ChopLastNode(dir); BufferPrintf(deref_file, "%s/%s", dir, buf); } else { BufferSet(deref_file, buf, linksize); } BufferPrintf(pretty_file, "'%s' (from symlink '%s')", BufferData(deref_file), file); } else #endif { break; } } strcpy(backup, BufferData(deref_file)); if (a->edits.backup == BACKUP_OPTION_TIMESTAMP) { snprintf(stamp, CF_BUFSIZE, "_%jd_%s", (intmax_t) CFSTARTTIME, CanonifyName(ctime(&stamp_now))); strcat(backup, stamp); } strcat(backup, ".cf-before-edit"); strcpy(new, BufferData(deref_file)); strcat(new, ".cf-after-edit"); unlink(new); /* Just in case of races */ if ((*callback)(new, param, new_line_mode) == false) { goto end; } if (!CopyFilePermissionsDisk(BufferData(deref_file), new)) { Log(LOG_LEVEL_ERR, "Can't copy file permissions from %s to '%s' - so promised edits could not be moved into place.", BufferData(pretty_file), new); goto end; } unlink(backup); #ifndef __MINGW32__ if (link(BufferData(deref_file), backup) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't link %s to '%s' - falling back to copy. (link: %s)", BufferData(pretty_file), backup, GetErrorStr()); #else /* No hardlinks on Windows, go straight to copying */ { #endif if (!CopyRegularFileDisk(BufferData(deref_file), backup)) { Log(LOG_LEVEL_ERR, "Can't copy %s to '%s' - so promised edits could not be moved into place.", BufferData(pretty_file), backup); goto end; } if (!CopyFilePermissionsDisk(BufferData(deref_file), backup)) { Log(LOG_LEVEL_ERR, "Can't copy permissions %s to '%s' - so promised edits could not be moved into place.", BufferData(pretty_file), backup); goto end; } } if (a->edits.backup == BACKUP_OPTION_ROTATE) { RotateFiles(backup, a->edits.rotate); unlink(backup); } if (a->edits.backup != BACKUP_OPTION_NO_BACKUP) { if (ArchiveToRepository(backup, a)) { unlink(backup); } } else { unlink(backup); } if (rename(new, BufferData(deref_file)) == -1) { Log(LOG_LEVEL_ERR, "Can't rename '%s' to %s - so promised edits could not be moved into place. (rename: %s)", new, BufferData(pretty_file), GetErrorStr()); goto end; } ret = true; end: BufferDestroy(pretty_file); BufferDestroy(deref_file); return ret; } /*********************************************************************/ static bool SaveItemListCallback(const char *dest_filename, void *param, NewLineMode new_line_mode) { Item *liststart = param, *ip; //saving list to file FILE *fp = safe_fopen( dest_filename, (new_line_mode == NewLineMode_Native) ? "wt" : "w"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Unable to open destination file '%s' for writing. (fopen: %s)", dest_filename, GetErrorStr()); return false; } for (ip = liststart; ip != NULL; ip = ip->next) { if (fprintf(fp, "%s\n", ip->name) < 0) { Log(LOG_LEVEL_ERR, "Unable to write into destination file '%s'. (fprintf: %s)", dest_filename, GetErrorStr()); fclose(fp); return false; } } if (fclose(fp) == -1) { Log(LOG_LEVEL_ERR, "Unable to close file '%s' after writing. (fclose: %s)", dest_filename, GetErrorStr()); return false; } return true; } /*********************************************************************/ bool SaveItemListAsFile(Item *liststart, const char *file, const Attributes *a, NewLineMode new_line_mode) { assert(a != NULL); return SaveAsFile(&SaveItemListCallback, liststart, file, a, new_line_mode); } // Some complex logic here to enable warnings of diffs to be given static Item *NextItem(const Item *ip) { if (ip) { return ip->next; } else { return NULL; } } static bool ItemListsEqual(EvalContext *ctx, const Item *list1, const Item *list2, int warnings, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); bool retval = true; const Item *ip1 = list1; const Item *ip2 = list2; while (true) { if ((ip1 == NULL) && (ip2 == NULL)) { return retval; } if ((ip1 == NULL) || (ip2 == NULL)) { if (warnings) { if ((ip1 == list1) || (ip2 == list2)) { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "File content wants to change from from/to full/empty but only a warning promised"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); } else { if (ip1 != NULL) { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, " ! edit_line change warning promised: (remove) %s", ip1->name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); } if (ip2 != NULL) { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, " ! edit_line change warning promised: (add) %s", ip2->name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); } } } if (warnings) { if (ip1 || ip2) { retval = false; ip1 = NextItem(ip1); ip2 = NextItem(ip2); continue; } } return false; } if (strcmp(ip1->name, ip2->name) != 0) { if (!warnings) { // No need to wait return false; } else { // If we want to see warnings, we need to scan the whole file cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "edit_line warning promised: - %s", ip1->name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); retval = false; } } ip1 = NextItem(ip1); ip2 = NextItem(ip2); } return retval; } /* returns true if file on disk is identical to file in memory */ bool CompareToFile( EvalContext *ctx, const Item *liststart, const char *file, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); struct stat statbuf; Item *cmplist = NULL; if (stat(file, &statbuf) == -1) { return false; } if ((liststart == NULL) && (statbuf.st_size == 0)) { return true; } if (liststart == NULL) { return false; } if (!LoadFileAsItemList(&cmplist, file, a->edits, false)) { return false; } if (!ItemListsEqual(ctx, cmplist, liststart, (a->transaction.action == cfa_warn), a, pp, result)) { DeleteItemList(cmplist); return false; } DeleteItemList(cmplist); return (true); } cfengine-3.24.2/libpromises/Makefile.am0000644000000000000000000001707215010704253017746 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # if !BUILTIN_EXTENSIONS projlib_LTLIBRARIES = libpromises.la AM_LDFLAGS = -version-info 3:6:0 -no-undefined else noinst_LTLIBRARIES = libpromises.la AM_LDFLAGS = endif AM_LDFLAGS += $(CORE_LDFLAGS) $(LMDB_LDFLAGS) $(TOKYOCABINET_LDFLAGS) $(QDBM_LDFLAGS) \ $(PCRE2_LDFLAGS) $(OPENSSL_LDFLAGS) $(SQLITE3_LDFLAGS) $(LIBACL_LDFLAGS) $(LIBYAML_LDFLAGS) $(LIBCURL_LDFLAGS) AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libenv \ -I$(srcdir)/../cf-check \ $(CORE_CPPFLAGS) $(ENTERPRISE_CPPFLAGS) \ $(LMDB_CPPFLAGS) $(TOKYOCABINET_CPPFLAGS) $(QDBM_CPPFLAGS) \ $(PCRE2_CPPFLAGS) $(OPENSSL_CPPFLAGS) $(SQLITE3_CPPFLAGS) $(LIBACL_CPPFLAGS) $(LIBYAML_CPPFLAGS) $(LIBCURL_CPPFLAGS) AM_CFLAGS = $(CORE_CFLAGS) $(ENTERPRISE_CFLAGS) \ $(LMDB_CFLAGS) $(TOKYOCABINET_CFLAGS) $(QDBM_CFLAGS) \ $(PCRE2_CFLAGS) $(OPENSSL_CFLAGS) $(SQLITE3_CFLAGS) $(LIBACL_CFLAGS) $(LIBYAML_CFLAGS) $(LIBCURL_CFLAGS) AM_YFLAGS = -d LIBS = $(LMDB_LIBS) $(TOKYOCABINET_LIBS) $(QDBM_LIBS) \ $(PCRE2_LIBS) $(OPENSSL_LIBS) $(SQLITE3_LIBS) $(LIBACL_LIBS) $(LIBYAML_LIBS) $(LIBCURL_LIBS) # The lib providing sd_listen_fds() is not needed in libpromises, it's actually # needed in libcfnet. But adding it here is an easy way to make sure it's # available for all the binaries that might need it. Once libcfnet doesn't # require libpromises, we can do this properly. LIBS += $(SYSTEMD_SOCKET_LIBS) libpromises_la_LIBADD = ../libntech/libutils/libutils.la ../libcfecompat/libcfecompat.la \ ../libcfnet/libcfnet.la \ ../libenv/libenv.la $(ENTERPRISE_LDADD) libpromises_la_SOURCES = \ acl_tools.h acl_tools_posix.c \ actuator.c actuator.h \ assoc.c assoc.h \ attributes.c attributes.h \ audit.c audit.h \ bootstrap.c bootstrap.h bootstrap.inc failsafe.cf \ cf-windows-functions.h \ cf3.defs.h \ cf3.extern.h \ cf3globals.c \ cf3lex.l \ cf3parse.y cf3parse.h \ cf3parse_logic.h \ changes_chroot.c changes_chroot.h \ chflags.c chflags.h \ class.c class.h \ cmdb.c cmdb.h \ constants.c \ conversion.c conversion.h \ crypto.c crypto.h \ dbm_api.c dbm_api.h dbm_api_types.h dbm_priv.h \ dbm_migration.c dbm_migration.h \ dbm_migration_lastseen.c \ dbm_lmdb.c \ dbm_quick.c \ dbm_tokyocab.c \ enterprise_stubs.c enterprise_extension.c enterprise_extension.h \ eval_context.c eval_context.h \ evalfunction.c evalfunction.h \ exec_tools.c exec_tools.h \ expand.c expand.h \ extensions.c extensions.h \ extensions_template.c.pre extensions_template.h.pre \ feature.c feature.h \ files_copy.c files_copy.h \ files_interfaces.c files_interfaces.h \ files_lib.c files_lib.h \ files_links.c files_links.h \ files_names.c files_names.h \ files_operators.c files_operators.h \ files_repository.c files_repository.h \ fncall.c fncall.h \ generic_agent.c generic_agent.h \ global_mutex.c global_mutex.h \ granules.c granules.h \ instrumentation.c instrumentation.h \ item_lib.c item_lib.h \ iteration.c iteration.h \ keyring.c keyring.h \ lastseen.c lastseen.h \ loading.c loading.h \ locks.c locks.h \ logic_expressions.c logic_expressions.h \ matching.c matching.h \ match_scope.c match_scope.h \ math_eval.c math_eval.h math.pc \ mod_access.c mod_access.h \ mod_common.c mod_common.h \ mod_custom.c mod_custom.h \ mod_databases.c mod_databases.h \ mod_environ.c mod_environ.h \ mod_exec.c mod_exec.h \ mod_files.c mod_files.h \ mod_measurement.c mod_measurement.h \ mod_methods.c mod_methods.h \ mod_outputs.c mod_outputs.h \ mod_packages.c mod_packages.h \ mod_process.c mod_process.h \ mod_report.c mod_report.h \ mod_services.c mod_services.h \ mod_storage.c mod_storage.h \ mod_knowledge.c mod_knowledge.h \ mod_users.c mod_users.h \ modes.c \ monitoring_read.c monitoring_read.h \ ornaments.c ornaments.h \ policy.c policy.h \ parser.c parser.h \ parser_helpers.h \ parser_state.h \ patches.c \ pipes.h pipes.c \ processes_select.c processes_select.h \ process_lib.h process_unix_priv.h \ promises.c promises.h \ prototypes3.h \ rlist.c rlist.h \ scope.c scope.h \ shared_lib.c shared_lib.h \ signals.c signals.h \ sort.c sort.h \ storage_tools.c \ string_expressions.c string_expressions.h \ syntax.c syntax.h \ syslog_client.c syslog_client.h \ systype.c systype.h \ timeout.c timeout.h \ unix.c unix.h \ var_expressions.c var_expressions.h \ variable.c variable.h \ vars.c vars.h \ verify_classes.c verify_classes.h \ verify_reports.c \ verify_vars.c verify_vars.h \ ../cf-check/backup.c ../cf-check/backup.h \ ../cf-check/diagnose.c ../cf-check/diagnose.h \ ../cf-check/lmdump.c ../cf-check/lmdump.h \ ../cf-check/repair.c ../cf-check/repair.h \ ../cf-check/replicate_lmdb.c ../cf-check/replicate_lmdb.h \ ../cf-check/utilities.c ../cf-check/utilities.h \ ../cf-check/validate.c ../cf-check/validate.h if !NT libpromises_la_SOURCES += \ process_unix.c \ pipes_unix.c if LINUX libpromises_la_SOURCES += \ process_linux.c endif if AIX libpromises_la_SOURCES += \ process_aix.c endif if HPUX libpromises_la_SOURCES += \ process_hpux.c endif if SOLARIS libpromises_la_SOURCES += \ process_solaris.c endif if FREEBSD libpromises_la_SOURCES += \ process_freebsd.c endif if !LINUX if !AIX if !HPUX if !SOLARIS if !FREEBSD libpromises_la_SOURCES += \ process_unix_stub.c endif endif endif endif endif endif # !NT if !NDEBUG if LINUX libpromises_la_SOURCES += \ dbm_test_api.c dbm_test_api.h endif endif ########## Sources pre-generated and distributed in the tarball ########## # Make sure you include the generated file as a dependency to a target # (e.g. libpromises_la) so that it's generated during "make dist" BUILT_SOURCES = cf3lex.c cf3parse.h cf3parse.c \ enterprise_extension.c enterprise_extension.h \ bootstrap.inc EXTRA_SCRIPTS = text2cstring.pl enterprise_extension.sed EXTRA_DIST = $(EXTRA_SCRIPTS) enterprise_extension.c: extensions_template.c.pre enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/enterprise_extension.sed $< > $@ enterprise_extension.h: extensions_template.h.pre enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/enterprise_extension.sed $< > $@ bootstrap.inc: failsafe.cf text2cstring.pl $(V_PERL) $(PERL) $(srcdir)/text2cstring.pl $< > $@ # # Proper compilation progress printing # V_PERL = $(cf__v_PERL_$(V)) cf__v_PERL_ = $(cf__v_PERL_$(AM_DEFAULT_VERBOSITY)) cf__v_PERL_0 = @echo " PERL " "$@"; cf__v_PERL_1 = V_SED = $(cf__v_SED_$(V)) cf__v_SED_ = $(cf__v_SED_$(AM_DEFAULT_VERBOSITY)) cf__v_SED_0 = @echo " SED " "$@"; cf__v_SED_1 = # # Some basic clean ups # # Use "make mostlyclean" if you want to keep the BUILT_SOURCES # CLEANFILES = $(BUILT_SOURCES) MOSTLYCLEANFILES = *.gcno *.gcda *~ *.orig *.rej cfengine-3.24.2/libpromises/pipes.c0000644000000000000000000001710315010704253017171 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include bool PipeTypeIsOk(const char *type) { if (type[0] != 'r' && type[0] != 'w') { return false; } else if (type[1] != 't' && type[1] != '+') { if (type[1] == '\0') { return true; } else { return false; } } else if (type[2] == '\0' || type[2] == 't') { return true; } else { return false; } } /*******************************************************************/ /* Pipe read/write interface, originally in package modules */ /*******************************************************************/ Rlist *PipeReadData(const IOData *io, int pipe_timeout_secs, int pipe_termination_check_secs) { char buff[CF_BUFSIZE] = {0}; Buffer *data = BufferNew(); if (!data) { Log(LOG_LEVEL_VERBOSE, "Unable to allocate buffer for handling pipe responses."); return NULL; } int timeout_seconds_left = pipe_timeout_secs; while (!IsPendingTermination() && timeout_seconds_left > 0) { int fd = PipeIsReadWriteReady(io, pipe_termination_check_secs); if (fd < 0) { Log(LOG_LEVEL_DEBUG, "Error reading data from application pipe %d", fd); break; } else if (fd == io->read_fd) { ssize_t res = read(fd, buff, sizeof(buff) - 1); if (res == -1) { if (errno == EINTR) { continue; } else { Log(LOG_LEVEL_ERR, "Unable to read output from application pipe: %s", GetErrorStr()); BufferDestroy(data); return NULL; } } else if (res == 0) /* reached EOF */ { break; } Log(LOG_LEVEL_DEBUG, "Data read from application pipe: %zd [%s]", res, buff); BufferAppendString(data, buff); memset(buff, 0, sizeof(buff)); } else if (fd == 0) /* timeout */ { timeout_seconds_left -= pipe_termination_check_secs; continue; } } char *read_string = BufferClose(data); #ifdef __MINGW32__ bool detect_crlf = true; #else bool detect_crlf = false; #endif Rlist *response_lines = RlistFromStringSplitLines(read_string, detect_crlf); free(read_string); return response_lines; } ssize_t PipeWrite(IOData *io, const char *data) { /* If there is nothing to write close writing end of pipe. */ if (data == NULL || strlen(data) == 0) { if (io->write_fd >= 0) { cf_pclose_full_duplex_side(io->write_fd); io->write_fd = -1; } return 0; } ssize_t wrt = write(io->write_fd, data, strlen(data)); /* Make sure to close write_fd after sending all data. */ if (io->write_fd >= 0) { cf_pclose_full_duplex_side(io->write_fd); io->write_fd = -1; } return wrt; } int PipeWriteData(const char *base_cmd, const char *args, const char *data) { assert(base_cmd); assert(args); char *command = StringFormat("%s %s", base_cmd, args); IOData io = cf_popen_full_duplex(command, false, true); free(command); if (io.write_fd == -1 || io.read_fd == -1) { Log(LOG_LEVEL_VERBOSE, "Error occurred while opening pipes for " "communication with application '%s'.", base_cmd); return -1; } Log(LOG_LEVEL_DEBUG, "Opened fds %d and %d for command '%s'.", io.read_fd, io.write_fd, args); int res = 0; int written = PipeWrite(&io, data); if (written < 0) { Log(LOG_LEVEL_ERR, "Failed to write to pipe (fd %d): %s", io.write_fd, GetErrorStr()); res = -1; } else if ((size_t) written != strlen(data)) { Log(LOG_LEVEL_VERBOSE, "Was not able to send whole data to application '%s'.", base_cmd); res = -1; } /* If script returns non 0 status */ int close = cf_pclose_full_duplex(&io); if (close != EXIT_SUCCESS) { Log(LOG_LEVEL_VERBOSE, "Application '%s' returned with non zero return code: %d", base_cmd, close); res = -1; } return res; } /* In some cases the response is expected to be not filled out. Some requests will have response filled only in case of errors. */ int PipeReadWriteData(const char *base_cmd, const char *args, const char *request, Rlist **response, int pipe_timeout_secs, int pipe_termination_check_secs) { assert(base_cmd); assert(args); char *command = StringFormat("%s %s", base_cmd, args); IOData io = cf_popen_full_duplex(command, false, true); if (io.write_fd == -1 || io.read_fd == -1) { Log(LOG_LEVEL_INFO, "Some error occurred while communicating with %s", command); free(command); return -1; } Log(LOG_LEVEL_DEBUG, "Opened fds %d and %d for command '%s'.", io.read_fd, io.write_fd, command); int written = PipeWrite(&io, request); if (written < 0) { Log(LOG_LEVEL_ERR, "Failed to write to pipe (fd %d): %s", io.write_fd, GetErrorStr()); return -1; } else if ((size_t) written != strlen(request)) { Log(LOG_LEVEL_VERBOSE, "Couldn't send whole data to application '%s'.", base_cmd); free(command); return -1; } /* We can have some error message here. */ Rlist *res = PipeReadData(&io, pipe_timeout_secs, pipe_termination_check_secs); /* If script returns non 0 status */ int close = cf_pclose_full_duplex(&io); if (close != EXIT_SUCCESS) { Log(LOG_LEVEL_VERBOSE, "Command '%s' returned with non zero return code: %d", command, close); free(command); RlistDestroy(res); return -1; } free(command); *response = res; return 0; } IOData cf_popen_full_duplex_streams( const char *command, bool capture_stderr, bool require_full_path) { IOData ret = cf_popen_full_duplex( command, capture_stderr, require_full_path); // On windows, these streams are already set up correctly: if (ret.read_stream == NULL) { ret.read_stream = fdopen(ret.read_fd, "r"); } if (ret.write_stream == NULL) { ret.write_stream = fdopen(ret.write_fd, "w"); } return ret; } cfengine-3.24.2/libpromises/cf3lex.l0000644000000000000000000007016715010704253017257 0ustar00rootroot00000000000000%top{ /* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /*******************************************************************/ /* */ /* LEXER for cfengine 3 */ /* */ /*******************************************************************/ #include #include #include #include #include #include #include } %{ /* yyinput/input are generated and unused */ #if defined(__GNUC__) # define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) # if GCC_VERSION >= 40200 # pragma GCC diagnostic ignored "-Wunused-function" # endif #endif #undef malloc #undef realloc #define malloc xmalloc #define realloc xrealloc //#define ParserDebug if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) printf #define ParserDebug(...) ((void) 0) #define P PARSER_STATE static Regex *context_expression_whitespace_rx = NULL; static int DeEscapeQuotedString(const char *from, char *to); int yywrap(void) { return 1; } static void yyuseraction() { P.offsets.current += yyleng; } #define YY_USER_ACTION yyuseraction(); // Do not use lex - flex only %} %x if_ignore_state space [ \t]+ newline ([\n]|[\xd][\xa]) eat_line ([\n]|[\xd][\xa]).* comment #[^\n]* macro_if_minimum_version @if\ minimum_version\([0-9]{1,5}(\.[0-9]{1,5}){0,2}\) macro_if_maximum_version @if\ maximum_version\([0-9]{1,5}(\.[0-9]{1,5}){0,2}\) macro_if_before_version @if\ before_version\([0-9]{1,5}(\.[0-9]{1,5}){0,2}\) macro_if_at_version @if\ at_version\([0-9]{1,5}(\.[0-9]{1,5}){0,2}\) macro_if_after_version @if\ after_version\([0-9]{1,5}(\.[0-9]{1,5}){0,2}\) macro_if_between_versions @if\ between_versions\([0-9]{1,5}(\.[0-9]{1,5}){0,2}\ *,\ *[0-9]{1,5}(\.[0-9]{1,5}){0,2}\) macro_if_feature @if\ feature\([a-zA-Z0-9_]+\) macro_else @else macro_endif @endif macro_line [^@\n\xd\xa].* bundle bundle body body promise promise nakedvar [$@][(][a-zA-Z0-9_\[\]\200-\377.:]+[)]|[$@][{][a-zA-Z0-9_\[\]\200-\377.:]+[}]|[$@][(][a-zA-Z0-9_\200-\377.:]+[\[][a-zA-Z0-9_$(){}\200-\377.:]+[\]]+[)]|[$@][{][a-zA-Z0-9_\200-\377.:]+[\[][a-zA-Z0-9_$(){}\200-\377.:]+[\]]+[}] identifier [a-zA-Z0-9_\200-\377]+ symbol [a-zA-Z0-9_\200-\377]+[:][a-zA-Z0-9_\200-\377]+ fat_arrow => thin_arrow -> /* * Three types of quoted strings: * * - string in double quotes, starts with double quote, runs until another * double quote, \" masks the double quote. * - string in single quotes, starts with single quote, runs until another * single quote, \' masks the single quote. * - string in backquotes, starts with backquote, runs until another backquote. * * The same rule formatted for the better readability: * * := \" \" | \' \' | ` ` * = * * = \\ | [^"\\] * = * * = \\ | [^'\\] * = * * = [^`] * = . | \n * */ qstring \"((\\(.|\n))|[^"\\])*\"|\'((\\(.|\n))|[^'\\])*\'|`[^`]*` class [.|&!()a-zA-Z0-9_\200-\377:][\t .|&!()a-zA-Z0-9_\200-\377:]*:: varclass (\"[^"\0]*\"|\'[^'\0]*\'):: promise_guard [a-zA-Z_]+: %% {eat_line} { free(P.current_line); P.current_line = xstrdup(yytext+1); ParserDebug("L:line %s\n", P.current_line); P.line_no++; P.line_pos = 1; // push back on stack and skip first char yyless(1); } {macro_if_minimum_version} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* minimum = yytext+20; ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, minimum); VersionComparison result = CompareVersion(Version(), minimum); if (result == VERSION_GREATER || result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } {macro_if_maximum_version} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* maximum = yytext+20; ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, maximum); VersionComparison result = CompareVersion(Version(), maximum); if (result == VERSION_SMALLER || result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_GREATER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } {macro_if_before_version} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* target = yytext + strlen("@if before_version("); ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, target); VersionComparison result = CompareVersion(Version(), target); if (result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_GREATER || result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } {macro_if_at_version} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* target = yytext + strlen("@if at_version("); ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, target); VersionComparison result = CompareVersion(Version(), target); if (result == VERSION_EQUAL) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_GREATER || result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } {macro_if_after_version} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* target = yytext + strlen("@if after_version("); ParserDebug("\tL:macro @if %d:version=%s\n", P.line_pos, target); VersionComparison result = CompareVersion(Version(), target); if (result == VERSION_GREATER) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else if (result == VERSION_EQUAL || result == VERSION_SMALLER) { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } else { assert(result == VERSION_ERROR); yyerror("fatal: macro @if requested an unparseable version"); } } {macro_if_between_versions} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; const char* from = yytext + strlen("@if between_versions("); const char *to = strchr(from, ','); to += 1; while (*to == ' ') { to += 1; } ParserDebug("\tL:macro @if %d:between_versions(%s\n", P.line_pos, from); VersionComparison a = CompareVersion(Version(), from); VersionComparison b = CompareVersion(Version(), to); if ((a == VERSION_EQUAL || a == VERSION_GREATER) && (b == VERSION_EQUAL || b == VERSION_SMALLER)) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else { ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } } {macro_if_feature} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @if must be at beginning of the line."); return 0; } char* feature_text = yytext+12; // remove trailing ')' feature_text[strlen(feature_text)-1] = 0; ParserDebug("\tL:macro @if %d:feature=%s\n", P.line_pos, feature_text); { if (P.if_depth > 0) { yyerror("fatal: nested @if macros are not allowed"); return 0; } P.if_depth++; if (KnownFeature(feature_text)) { ParserDebug("\tL:macro @if %d:accepted to next @endif\n", P.line_pos); } else { /* ignore to the next @endif */ ParserDebug("\tL:macro @if %d:ignoring to next @endif or EOF\n", P.line_pos); BEGIN(if_ignore_state); } } } {macro_endif} { if ( P.line_pos != 1 ) { yyerror("fatal: macro @endif must be at beginning of the line."); return 0; } ParserDebug("\tL:macro @endif %d\n", P.line_pos); BEGIN(INITIAL); if (P.if_depth <= 0) { yyerror("fatal: @endif macros without a matching @if are not allowed"); return 0; } P.if_depth--; } {macro_line} { ParserDebug("\tL:inside macro @if, ignoring line text:\"%s\"\n", yytext); } {macro_else} { ParserDebug("\tL:macro @else, will no longer ignore lines\n", P.line_pos); BEGIN(INITIAL); } {macro_else} { if (P.if_depth <= 0) { yyerror("fatal: @else macro without a matching @if are not allowed"); return 0; } ParserDebug("\tL:macro @else, will now ignore lines\n", P.line_pos); BEGIN(if_ignore_state); } {macro_endif} { ParserDebug("\tL:macro @endif %d\n", P.line_pos); BEGIN(INITIAL); if (P.if_depth <= 0) { yyerror("fatal: @endif macros without a matching @if are not allowed"); return 0; } P.if_depth--; } {newline} { } . { /* eat up al unknown chars when line starts with @*/ ParserDebug("\tL:inside macro @if, ignoring char text:\"%s\"\n", yytext); } {bundle} { /* Note this has to come before "id" since it is a subset of id */ if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.line_pos += yyleng; ParserDebug("\tL:bundle %d\n", P.line_pos); return BUNDLE; } {body} { /* Note this has to come before "id" since it is a subset of id */ if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.line_pos += yyleng; ParserDebug("\tL:body %d\n", P.line_pos); return BODY; } {promise} { /* Note this has to come before "id" since it is a subset of id */ if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.line_pos += yyleng; ParserDebug("\tL:promise %d\n", P.line_pos); return PROMISE; } {identifier} { P.offsets.last_id = P.offsets.current - yyleng; P.line_pos += yyleng; ParserDebug("\tL:id %s %d\n", yytext, P.line_pos); if (yyleng > CF_MAXVARSIZE-1) { yyerror("identifier too long"); } strncpy(P.currentid, yytext, CF_MAXVARSIZE - 1); return IDENTIFIER; } {symbol} { P.offsets.last_id = P.offsets.current - yyleng; P.line_pos += yyleng; ParserDebug("\tL:symbol %s %d\n", yytext, P.line_pos); if (yyleng > CF_MAXVARSIZE-1) { yyerror("qualified identifier too long"); } strncpy(P.currentid, yytext, CF_MAXVARSIZE - 1); return IDENTIFIER; } {fat_arrow} { P.line_pos += yyleng; ParserDebug("\tL:assign %d\n", P.line_pos); return FAT_ARROW; } {thin_arrow} { P.line_pos += yyleng; ParserDebug("\tL:arrow %d\n", P.line_pos); return THIN_ARROW; } {varclass} { char *tmp = NULL; P.line_pos += yyleng; ParserDebug("\tL:varclass %s %d\n", yytext, P.line_pos); tmp = xstrdup(yytext+1); // remove leading quote tmp[yyleng-4] = '\0'; // remove tail quote plus :: if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.currentvarclasses = xstrdup(tmp); free(tmp); return CLASS_GUARD; } {class} { char *tmp = NULL; P.line_pos += yyleng; ParserDebug("\tL:class %s %d\n", yytext, P.line_pos); if (context_expression_whitespace_rx == NULL) { context_expression_whitespace_rx = CompileRegex(CFENGINE_REGEX_WHITESPACE_IN_CONTEXTS); } if (context_expression_whitespace_rx == NULL) { yyerror("The context expression whitespace regular expression could not be compiled, aborting."); } if (StringMatchFullWithPrecompiledRegex(context_expression_whitespace_rx, yytext)) { yyerror("class names can't be separated by whitespace without an intervening operator"); } tmp = xstrdup(yytext); tmp[yyleng-2] = '\0'; if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } P.currentclasses = xstrdup(tmp); free(tmp); return CLASS_GUARD; } {promise_guard} { char *tmp = NULL; P.line_pos += yyleng; ParserDebug("\tL:promise_guard %s %d\n", yytext, P.line_pos); P.offsets.last_promise_guard_id = P.offsets.current - yyleng; tmp = xstrdup(yytext); assert(tmp[yyleng - 1] == ':'); tmp[yyleng - 1] = '\0'; // Exclude trailing colon in promise guard assert(strlen(tmp) > 0); assert(tmp[strlen(tmp) - 1] != ':'); strncpy(P.currenttype, tmp, CF_MAXVARSIZE - 1); if (P.currentclasses != NULL) { free(P.currentclasses); P.currentclasses = NULL; } if (P.currentvarclasses != NULL) { free(P.currentvarclasses); P.currentvarclasses = NULL; } free(tmp); return PROMISE_GUARD; } {qstring} { char *tmp = NULL; int less = 0; P.offsets.last_string = P.offsets.current - yyleng; P.line_pos += yyleng; ParserDebug("\tL:qstring %s %d\n", yytext, P.line_pos); for (char *c = yytext; *c; ++c) { if (*c == '\n') { P.line_no++; } } tmp = xmalloc(yyleng + 1); if ((less = DeEscapeQuotedString(yytext,tmp)) > 0) { yyless(less); P.offsets.current -= less; } if (P.currentstring) { free(P.currentstring); } P.currentstring = xstrdup(tmp); free(tmp); return QUOTED_STRING; } {nakedvar} { P.line_pos += yyleng; ParserDebug("\tL: %s %d\n", yytext, P.line_pos); if (P.currentstring) { free(P.currentstring); } P.currentstring = xstrdup(yytext); return NAKEDVAR; } {space}+ { P.line_pos += yyleng; } {comment} { } . { P.line_pos++; return yytext[0]; } <> { if (P.if_depth > 0) { yyerror("EOF seen while @if was waiting for @endif in ignore_state"); return 0; } } <> { if (P.if_depth > 0) { yyerror("EOF seen while @if was waiting for @endif without ignore_state"); } return 0; // loops forever without this } %% static int DeEscapeQuotedString(const char *from, char *to) { char *cp; const char *sp; char start = *from; int len = strlen(from); if (len == 0) { return 0; } for (sp = from + 1, cp = to; (sp - from) < len; sp++, cp++) { if ((*sp == start)) { *(cp) = '\0'; if (*(sp + 1) != '\0') { return (2 + (sp - from)); } return 0; } if (*sp == '\\') { switch (*(sp + 1)) { case '\n': sp += 2; break; case ' ': break; case '\\': case '\"': case '\'': sp++; break; } } *cp = *sp; } yyerror("Runaway string"); *(cp) = '\0'; return 0; } /* EOF */ cfengine-3.24.2/libpromises/changes_chroot.c0000644000000000000000000002214615010704253021042 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* xstrdup() */ #include /* DirOpen(), DirRead(), DirClose() */ #include /* ToChangesChroot() */ #include /* FILE_SEPARATOR */ #include /* MakeParentDirectory() */ #include /* CopyRegularFileDisk(), CopyFilePermissionsDisk() */ #include /* IsAbsPath(), JoinPaths() */ #include /* ExpandLinks() */ #include /* StringEqual() */ #include /* WriteLenPrefixedString() */ #include /* FileWriter(), Writer */ #include /* CsvWriter */ #include static inline const char *GetLastFileSeparator(const char *path, const char *end) { const char *cp = end; for (; (cp > path) && (*cp != FILE_SEPARATOR); cp--); return cp; } static char *GetFirstNonExistingParentDir(const char *path, char buf[PATH_MAX]) { /* Get rid of the trailing file separator (if any). */ size_t path_len = strlen(path); if (path[path_len - 1] == FILE_SEPARATOR) { strncpy(buf, path, PATH_MAX - 1); buf[path_len] = '\0'; } else { strncpy(buf, path, PATH_MAX - 1); } char *last_sep = (char *) GetLastFileSeparator(buf, buf + path_len); while (last_sep != buf) { *last_sep = '\0'; if (access(buf, F_OK) == 0) { *last_sep = FILE_SEPARATOR; *(last_sep + 1) = '\0'; return buf; } last_sep = (char *) GetLastFileSeparator(buf, last_sep - 1); } *last_sep = '\0'; return buf; } static bool MirrorDirTreePermsToChroot(const char *path) { const char *chrooted = ToChangesChroot(path); if (!CopyFilePermissionsDisk(path, chrooted)) { return false; } size_t path_len = strlen(path); char path_copy[path_len + 1]; strcpy(path_copy, path); const char *const path_copy_end = path_copy + (path_len - 1); const char *const chrooted_end = chrooted + strlen(chrooted) - 1; char *last_sep = (char *) GetLastFileSeparator(path_copy, path_copy_end); while (last_sep != path_copy) { char *last_sep_chrooted = (char *) chrooted_end - (path_copy_end - last_sep); *last_sep = '\0'; *last_sep_chrooted = '\0'; if (!CopyFilePermissionsDisk(path_copy, chrooted)) { return false; } *last_sep = FILE_SEPARATOR; *last_sep_chrooted = FILE_SEPARATOR; last_sep = (char *) GetLastFileSeparator(path_copy, last_sep - 1); } return true; } #ifndef __MINGW32__ /** * Mirror the symlink #path to #chrooted_path together with its target, then * mirror the target if it is a symlink too,..., recursively. */ static void ChrootSymlinkDeep(const char *path, const char *chrooted_path, struct stat *sb) { assert(sb != NULL); size_t target_size = (sb->st_size != 0 ? sb->st_size + 1 : PATH_MAX); char target[target_size]; ssize_t ret = readlink(path, target, target_size); if (ret == -1) { /* Should never happen, but nothing to do here if it does. */ return; } target[ret] = '\0'; if (IsAbsPath(target)) { const char *chrooted_target = ToChangesChroot(target); if (symlink(chrooted_target, chrooted_path) != 0) { /* Should never happen, but nothing to do here if it does. */ return; } else { PrepareChangesChroot(target); } } else { if (symlink(target, chrooted_path) != 0) { /* Should never happen, but nothing to do here if it does. */ return; } else { char expanded_target[PATH_MAX]; if (!ExpandLinks(expanded_target, path, 0, 1)) { /* Should never happen, but nothing to do here if it does. */ return; } PrepareChangesChroot(expanded_target); } } } #endif /* __MINGW32__ */ void PrepareChangesChroot(const char *path) { struct stat sb; /* We need to create a copy because ToChangesChroot() returns a pointer to * its internal buffer which gets overwritten by later calls of the * function. */ char *chrooted = xstrdup(ToChangesChroot(path)); if (lstat(chrooted, &sb) != -1) { /* chrooted 'path' already exists, we are done */ free(chrooted); return; } { char first_nonexisting_parent[PATH_MAX]; GetFirstNonExistingParentDir(path, first_nonexisting_parent); MakeParentDirectory(first_nonexisting_parent, true, NULL); MirrorDirTreePermsToChroot(first_nonexisting_parent); } if (lstat(path, &sb) == -1) { /* 'path' doesn't exist, nothing to do here */ return; } #ifndef __MINGW32__ if (S_ISLNK(sb.st_mode)) { ChrootSymlinkDeep(path, chrooted, &sb); } else #endif /* __MINGW32__ */ if (S_ISDIR(sb.st_mode)) { mkdir(chrooted, sb.st_mode); Dir *dir = DirOpen(path); if (dir == NULL) { /* Should never happen, but nothing to do here if it does. */ free(chrooted); return; } for (const struct dirent *entry = DirRead(dir); entry != NULL; entry = DirRead(dir)) { if (StringEqual(entry->d_name, ".") || StringEqual(entry->d_name, "..")) { continue; } char entry_path[PATH_MAX]; strcpy(entry_path, path); JoinPaths(entry_path, PATH_MAX, entry->d_name); PrepareChangesChroot(entry_path); } DirClose(dir); } else { /* TODO: sockets, pipes, devices,... ? */ CopyRegularFileDisk(path, chrooted); } CopyFilePermissionsDisk(path, chrooted); free(chrooted); } bool RecordFileChangedInChroot(const char *path) { FILE *chroot_changes = safe_fopen(ToChangesChroot(CHROOT_CHANGES_LIST_FILE), "a"); Writer *writer = FileWriter(chroot_changes); bool ret = WriteLenPrefixedString(writer, path); WriterClose(writer); return ret; } bool RecordFileRenamedInChroot(const char *old_name, const char *new_name) { FILE *chroot_renames = safe_fopen(ToChangesChroot(CHROOT_RENAMES_LIST_FILE), "a"); Writer *writer = FileWriter(chroot_renames); bool ret = WriteLenPrefixedString(writer, old_name); ret = (ret && WriteLenPrefixedString(writer, new_name)); WriterClose(writer); return ret; } bool RecordFileEvaluatedInChroot(const char *path) { FILE *chroot_changes = safe_fopen(ToChangesChroot(CHROOT_KEPT_LIST_FILE), "a"); Writer *writer = FileWriter(chroot_changes); bool ret = WriteLenPrefixedString(writer, path); WriterClose(writer); return ret; } bool RecordPkgOperationInChroot(const char *op, const char *name, const char *arch, const char *version) { assert(op != NULL); assert(name != NULL); /* the rest is optional */ FILE *chroot_pkgs_ops = safe_fopen(ToChangesChroot(CHROOT_PKGS_OPS_FILE), "a"); if (chroot_pkgs_ops == NULL) { Log(LOG_LEVEL_ERR, "Failed to open package operations record file '%s'", CHROOT_PKGS_OPS_FILE); return false; } Writer *writer = FileWriter(chroot_pkgs_ops); if (writer == NULL) { Log(LOG_LEVEL_ERR, "Failed to create a writer for package operations record file '%s'", CHROOT_PKGS_OPS_FILE); fclose(chroot_pkgs_ops); return false; } CsvWriter *csv_writer = CsvWriterOpen(writer); if (csv_writer == NULL) { Log(LOG_LEVEL_ERR, "Failed to create a CSV writer for package operations record file '%s'", CHROOT_PKGS_OPS_FILE); WriterClose(writer); return false; } CsvWriterField(csv_writer, op); CsvWriterField(csv_writer, name); CsvWriterField(csv_writer, NULL_TO_EMPTY_STRING(arch)); CsvWriterField(csv_writer, NULL_TO_EMPTY_STRING(version)); CsvWriterNewRecord(csv_writer); CsvWriterClose(csv_writer); WriterClose(writer); return true; } cfengine-3.24.2/libpromises/shared_lib.h0000644000000000000000000000224415010704253020152 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef SHARED_LIB_H #define SHARED_LIB_H void *shlib_open(const char *lib_name); void *shlib_load(void *handle, const char *symbol_name); void shlib_close(void *handle); #endif // SHARED_LIB_H cfengine-3.24.2/libpromises/dbm_test_api.h0000644000000000000000000000436115010704253020512 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DBM_TEST_API_H #define CFENGINE_DBM_TEST_API_H #include #include void DoRandomReads(dbid db_id, int keys_refresh_s, long min_interval_ms, long max_interval_ms, bool *terminate); void DoRandomWrites(dbid db_id, int sample_size_pct, int prune_interval_s, long min_interval_ms, long max_interval_ms, bool *terminate); void DoRandomIterations(dbid db_id, long min_interval_ms, long max_interval_ms, bool *terminate); typedef struct DBLoadSimulation_ DBLoadSimulation; DBLoadSimulation *SimulateDBLoad(dbid db_id, int read_keys_refresh_s, long read_min_interval_ms, long read_max_interval_ms, int write_sample_size_pct, int write_prune_interval_s, long write_min_interval_ms, long write_max_interval_ms, long iter_min_interval_ms, long iter_max_interval_ms); void StopSimulation(DBLoadSimulation *simulation); typedef struct DBFilament_ DBFilament; DBFilament *FillUpDB(dbid db_id, int usage_pct); void RemoveFilament(DBFilament *filament); #endif /* CFENGINE_DBM_TEST_API_H */ cfengine-3.24.2/libpromises/files_links.c0000644000000000000000000006442115010704253020360 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include /* PrepareChangesChroot() */ #if !defined(__MINGW32__) static bool MakeLink(EvalContext *ctx, const char *from, const char *to, const Attributes *attr, const Promise *pp, PromiseResult *result); #endif static char *AbsLinkPath(const char *from, const char *relto); /*****************************************************************************/ #ifdef __MINGW32__ PromiseResult VerifyLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp) { RecordFailure(ctx, pp, attr, "Windows does not support symbolic links (at VerifyLink())"); return PROMISE_RESULT_FAIL; } #else PromiseResult VerifyLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp) { assert(attr != NULL); /* VerifyHardLink() is a separate function */ assert(attr->link.link_type != FILE_LINK_TYPE_HARDLINK); char to[CF_BUFSIZE], linkbuf[CF_BUFSIZE], absto[CF_BUFSIZE]; struct stat sb; memset(to, 0, CF_BUFSIZE); const bool absolute_source = IsAbsoluteFileName(source); if ((!absolute_source) && (*source != '.')) /* links without a directory reference */ { snprintf(to, CF_BUFSIZE - 1, "./%s", source); } else { strlcpy(to, source, CF_BUFSIZE); } if (!absolute_source) /* relative path, must still check if exists */ { Log(LOG_LEVEL_DEBUG, "Relative link destination detected '%s'", to); strcpy(absto, AbsLinkPath(destination, to)); Log(LOG_LEVEL_DEBUG, "Absolute path to relative link '%s', '%s'", absto, destination); } else { strcpy(absto, to); } /* If making changes in a chroot, we need to get the link target into the * chroot. */ if (ChrootChanges()) { PrepareChangesChroot(absto); } const char *changes_absto = absto; if (ChrootChanges()) { changes_absto = ToChangesChroot(absto); } bool source_file_exists = true; if (stat(changes_absto, &sb) == -1) { Log(LOG_LEVEL_DEBUG, "No source file '%s'", absto); source_file_exists = false; } if ((!source_file_exists) && (attr->link.when_no_file != cfa_force) && (attr->link.when_no_file != cfa_delete)) { Log(LOG_LEVEL_VERBOSE, "Source '%s' for linking is absent", absto); RecordFailure(ctx, pp, attr, "Unable to create link '%s' -> '%s', no source", destination, to); return PROMISE_RESULT_FAIL; } const char *changes_destination = destination; if (ChrootChanges()) { changes_destination = ToChangesChroot(destination); } PromiseResult result = PROMISE_RESULT_NOOP; if ((!source_file_exists) && (attr->link.when_no_file == cfa_delete)) { KillGhostLink(ctx, changes_destination, attr, pp, &result); return result; } memset(linkbuf, 0, CF_BUFSIZE); if (readlink(changes_destination, linkbuf, CF_BUFSIZE - 1) == -1) { if (!MakingChanges(ctx, pp, attr, &result, "create link '%s'", destination)) { return result; } bool dir_created = false; if (MakeParentDirectoryForPromise(ctx, pp, attr, &result, destination, attr->move_obstructions, &dir_created, DEFAULTMODE)) { if (dir_created) { RecordChange(ctx, pp, attr, "Created parent directory for link '%s'", destination); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } if (!MoveObstruction(ctx, destination, attr, pp, &result)) { RecordFailure(ctx, pp, attr, "Unable to create link '%s' -> '%s', failed to move obstruction", destination, to); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (!MakeLink(ctx, destination, source, attr, pp, &result)) { RecordFailure(ctx, pp, attr, "Unable to create link '%s' -> '%s'", destination, to); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } return result; } else { /* to == "./$source" */ bool link_correct = (StringEqual(linkbuf, source) || StringEqual(linkbuf, to)); /* If making changes in chroot, the existing symlink can also be * pointing to the changes chroot (if it's absolute). */ if (!link_correct && absolute_source && ChrootChanges()) { link_correct = StringEqual(linkbuf, ToChangesChroot(source)); } if (link_correct) { RecordNoChange(ctx, pp, attr, "Link '%s' points to '%s', promise kept", destination, source); return PROMISE_RESULT_NOOP; } /* else */ if (attr->move_obstructions) { if (MakingChanges(ctx, pp, attr, &result, "remove incorrect link '%s'", destination)) { if (unlink(ToChangesPath(destination)) == -1) { RecordFailure(ctx, pp, attr, "Error removing link '%s' (points to '%s' not '%s')", destination, linkbuf, to); return PROMISE_RESULT_FAIL; } RecordChange(ctx, pp, attr, "Overrode incorrect link '%s'", destination); result = PROMISE_RESULT_CHANGE; MakeLink(ctx, destination, source, attr, pp, &result); return result; } else { return result; } } else { RecordFailure(ctx, pp, attr, "Link '%s' points to '%s' not '%s', but not moving obstructions", destination, linkbuf, to); return PROMISE_RESULT_FAIL; } } } #endif /* !__MINGW32__ */ /*****************************************************************************/ #ifdef __MINGW32__ PromiseResult VerifyAbsoluteLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp) { RecordFailure(ctx, pp, attr, "Windows does not support symbolic links (at VerifyAbsoluteLink())"); return PROMISE_RESULT_FAIL; } #else PromiseResult VerifyAbsoluteLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp) { assert(attr != NULL); char absto[CF_BUFSIZE]; char expand[CF_BUFSIZE]; char linkto[CF_BUFSIZE]; if (*source == '.') { strcpy(linkto, destination); ChopLastNode(linkto); JoinPaths(linkto, sizeof(linkto), source); } else { strcpy(linkto, source); } CompressPath(absto, sizeof(absto), linkto); expand[0] = '\0'; if (attr->link.when_no_file == cfa_force) { bool expanded; struct stat sb; if (ChrootChanges() && (lstat(ToChangesChroot(absto), &sb) != -1)) { char chrooted_expand[sizeof(expand)]; chrooted_expand[0] = '\0'; expanded = ExpandLinks(chrooted_expand, ToChangesChroot(absto), 0, CF_MAXLINKLEVEL); strlcpy(expand, ToNormalRoot(chrooted_expand), sizeof(expand)); } else { expanded = ExpandLinks(expand, absto, 0, CF_MAXLINKLEVEL); } if (expanded) { Log(LOG_LEVEL_DEBUG, "ExpandLinks returned '%s'", expand); } else { RecordFailure(ctx, pp, attr, "Failed to expand absolute link to '%s'", source); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } } else { strcpy(expand, absto); } CompressPath(linkto, sizeof(linkto), expand); return VerifyLink(ctx, destination, linkto, attr, pp); } #endif /* __MINGW32__ */ /*****************************************************************************/ PromiseResult VerifyRelativeLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp) { char *sp, *commonto, *commonfrom; char buff[CF_BUFSIZE], linkto[CF_BUFSIZE]; int levels = 0; if (*source == '.') { return VerifyLink(ctx, destination, source, attr, pp); } if (!CompressPath(linkto, sizeof(linkto), source)) { RecordInterruption(ctx, pp, attr, "Failed to link '%s' to '%s'", destination, source); return PROMISE_RESULT_INTERRUPTED; } commonto = linkto; commonfrom = destination; if (strcmp(commonto, commonfrom) == 0) { RecordInterruption(ctx, pp, attr, "Failed to link '%s' to '%s', can't link file '%s' to itself", destination, source, commonto); return PROMISE_RESULT_INTERRUPTED; } while (*commonto == *commonfrom) { commonto++; commonfrom++; } while (!((IsAbsoluteFileName(commonto)) && (IsAbsoluteFileName(commonfrom)))) { commonto--; commonfrom--; } commonto++; for (sp = commonfrom; *sp != '\0'; sp++) { if (IsFileSep(*sp)) { levels++; } } memset(buff, 0, CF_BUFSIZE); strcat(buff, "."); strcat(buff, FILE_SEPARATOR_STR); while (--levels > 0) { const char add[] = ".." FILE_SEPARATOR_STR; if (!PathAppend(buff, sizeof(buff), add, FILE_SEPARATOR)) { RecordFailure(ctx, pp, attr, "Internal limit reached in VerifyRelativeLink()," " path too long: '%s' + '%s'", buff, add); return PROMISE_RESULT_FAIL; } } if (!PathAppend(buff, sizeof(buff), commonto, FILE_SEPARATOR)) { RecordFailure(ctx, pp, attr, "Internal limit reached in VerifyRelativeLink() end," " path too long: '%s' + '%s'", buff, commonto); return PROMISE_RESULT_FAIL; } return VerifyLink(ctx, destination, buff, attr, pp); } /*****************************************************************************/ PromiseResult VerifyHardLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp) { char to[CF_BUFSIZE], absto[CF_BUFSIZE]; struct stat ssb, dsb; memset(to, 0, CF_BUFSIZE); const bool absolute_source = IsAbsoluteFileName(source); if ((!absolute_source) && (*source != '.')) /* links without a directory reference */ { snprintf(to, CF_BUFSIZE - 1, ".%c%s", FILE_SEPARATOR, source); } else { strlcpy(to, source, CF_BUFSIZE); } if (!absolute_source) /* relative path, must still check if exists */ { Log(LOG_LEVEL_DEBUG, "Relative link destination detected '%s'", to); strcpy(absto, AbsLinkPath(destination, to)); Log(LOG_LEVEL_DEBUG, "Absolute path to relative link '%s', '%s'", absto, destination); } else { strcpy(absto, to); } /* If making changes in a chroot, we need to get the link target into the * chroot. */ if (ChrootChanges()) { PrepareChangesChroot(absto); } const char *changes_absto = absto; if (ChrootChanges()) { changes_absto = ToChangesChroot(absto); } if (stat(changes_absto, &ssb) == -1) { Log(LOG_LEVEL_DEBUG, "No source file '%s'", absto); } if (!S_ISREG(ssb.st_mode)) { RecordFailure(ctx, pp, attr, "Source file '%s' is not a regular file, not appropriate to hard-link", to); return PROMISE_RESULT_FAIL; } Log(LOG_LEVEL_DEBUG, "Trying to hard link '%s' -> '%s'", destination, to); if (stat(ChrootChanges()? ToChangesChroot(destination) : destination, &dsb) == -1) { PromiseResult result = PROMISE_RESULT_NOOP; MakeHardLink(ctx, destination, to, attr, pp, &result); return result; } /* both files exist, but are they the same file? POSIX says */ /* the files could be on different devices, but unix doesn't */ /* allow this behaviour so the tests below are theoretical... */ if ((dsb.st_ino != ssb.st_ino) && (dsb.st_dev != ssb.st_dev)) { Log(LOG_LEVEL_VERBOSE, "If this is POSIX, unable to determine if %s is hard link is correct" " since it points to a different filesystem", destination); if ((dsb.st_mode == ssb.st_mode) && (dsb.st_size == ssb.st_size)) { RecordNoChange(ctx, pp, attr, "Hard link '%s' -> '%s' on different device appears okay", destination, to); return PROMISE_RESULT_NOOP; } } if ((dsb.st_ino == ssb.st_ino) && (dsb.st_dev == ssb.st_dev)) { RecordNoChange(ctx, pp, attr, "Hard link '%s' -> '%s' exists and is okay", destination, to); return PROMISE_RESULT_NOOP; } const char *chroot_msg = ""; if (ChrootChanges()) { chroot_msg = " (but hardlinks are always replicated to the changes chroot)"; } Log(LOG_LEVEL_INFO, "'%s' does not appear to be a hard link to '%s'%s", destination, to, chroot_msg); PromiseResult result = PROMISE_RESULT_NOOP; if (!MakingChanges(ctx, pp, attr, &result, "hard link '%s' -> '%s'", destination, to)) { return result; } if (!MoveObstruction(ctx, destination, attr, pp, &result)) { RecordFailure(ctx, pp, attr, "Unable to create hard link '%s' -> '%s', failed to move obstruction", destination, to); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } MakeHardLink(ctx, destination, to, attr, pp, &result); return result; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ #ifdef __MINGW32__ bool KillGhostLink(EvalContext *ctx, const char *name, const Attributes *attr, const Promise *pp, PromiseResult *result) { RecordFailure(ctx, pp, attr, "Cannot remove dead link '%s' (Windows does not support symbolic links)", name); PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } #else /* !__MINGW32__ */ bool KillGhostLink(EvalContext *ctx, const char *name, const Attributes *attr, const Promise *pp, PromiseResult *result) { char linkbuf[CF_BUFSIZE], tmp[CF_BUFSIZE]; char linkpath[CF_BUFSIZE], *sp; struct stat statbuf; memset(linkbuf, 0, CF_BUFSIZE); memset(linkpath, 0, CF_BUFSIZE); const char *changes_name = name; if (ChrootChanges()) { changes_name = ToChangesChroot(name); } if (readlink(changes_name, linkbuf, CF_BUFSIZE - 1) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't read link '%s' while checking for deadlinks", name); return true; /* ignore */ } if (!IsAbsoluteFileName(linkbuf)) { strcpy(linkpath, changes_name); /* Get path to link */ for (sp = linkpath + strlen(linkpath); (*sp != FILE_SEPARATOR) && (sp >= linkpath); sp--) { *sp = '\0'; } } strcat(linkpath, linkbuf); CompressPath(tmp, sizeof(tmp), linkpath); if (stat(tmp, &statbuf) == -1) /* link points nowhere */ { if ((attr->link.when_no_file == cfa_delete) || (attr->recursion.rmdeadlinks)) { Log(LOG_LEVEL_VERBOSE, "'%s' is a link which points to '%s', but the target doesn't seem to exist", name, linkbuf); if (MakingChanges(ctx, pp, attr, result, "remove dead link '%s'", name)) { unlink(changes_name); /* May not work on a client-mounted system ! */ RecordChange(ctx, pp, attr, "Removed dead link '%s'", name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } else { return true; } } } return false; } #endif /* !__MINGW32__ */ /*****************************************************************************/ #if !defined(__MINGW32__) static bool MakeLink(EvalContext *ctx, const char *from, const char *to, const Attributes *attr, const Promise *pp, PromiseResult *result) { if (MakingChanges(ctx, pp, attr, result, "link files '%s' -> '%s'", from, to)) { const char *changes_to = to; char *chroot_to = NULL; if (ChrootChanges()) { /* Create a copy because the next call to ToChangesChroot() will * overwrite the value. */ chroot_to = xstrdup(ToChangesChroot(to)); changes_to = chroot_to; } const char *changes_from = from; if (ChrootChanges()) { changes_from = ToChangesChroot(from); } if (symlink(changes_to, changes_from) == -1) { RecordFailure(ctx, pp, attr, "Couldn't link '%s' to '%s'. (symlink: %s)", to, from, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); free(chroot_to); return false; } else { RecordChange(ctx, pp, attr, "Linked files '%s' -> '%s'", from, to); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); free(chroot_to); return true; } } else { return false; } } #endif /* !__MINGW32__ */ /*****************************************************************************/ #ifdef __MINGW32__ bool MakeHardLink(EvalContext *ctx, const char *from, const char *to, const Attributes *attr, const Promise *pp, PromiseResult *result) { // TODO: Implement ? RecordFailure(ctx, pp, attr, "Couldn't hard link '%s' to '%s' (Hard links are not yet supported on Windows)", to, from); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } #else /* !__MINGW32__ */ bool MakeHardLink(EvalContext *ctx, const char *from, const char *to, const Attributes *attr, const Promise *pp, PromiseResult *result) { if (MakingChanges(ctx, pp, attr, result, "hard link files '%s' -> '%s'", from, to)) { const char *changes_to = to; char *chroot_to = NULL; if (ChrootChanges()) { /* Create a copy because the next call to ToChangesChroot() will * overwrite the value. */ chroot_to = xstrdup(ToChangesChroot(to)); changes_to = chroot_to; } const char *changes_from = from; if (ChrootChanges()) { changes_from = ToChangesChroot(from); } if (link(changes_to, changes_from) == -1) { RecordFailure(ctx, pp, attr, "Failed to hard link '%s' to '%s'. (link: %s)", to, from, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } else { RecordChange(ctx, pp, attr, "Hard linked file '%s' -> '%s'", from, to); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } } else { return false; } } #endif /* !__MINGW32__ */ /*********************************************************************/ /* Expand a path contaning symbolic links, up to 4 levels */ /* of symbolic links and then beam out in a hurry ! */ #ifdef __MINGW32__ bool ExpandLinks(char *dest, const char *from, int level, int max_level) { Log(LOG_LEVEL_ERR, "Windows does not support symbolic links (at ExpandLinks(%s,%s))", dest, from); return false; } #else /* !__MINGW32__ */ bool ExpandLinks(char *dest, const char *from, int level, int max_level) { char buff[CF_BUFSIZE]; char node[CF_MAXLINKSIZE]; struct stat statbuf; int lastnode = false; memset(dest, 0, CF_BUFSIZE); if (level >= CF_MAXLINKLEVEL) { Log(LOG_LEVEL_ERR, "Too many levels of symbolic links to evaluate absolute path"); return false; } if (level >= max_level) { Log(LOG_LEVEL_DEBUG, "Reached maximum level of symbolic link resolution"); return true; } const char *sp = from; while (*sp != '\0') { if (*sp == FILE_SEPARATOR) { sp++; continue; } sscanf(sp, "%[^/]", node); sp += strlen(node); if (*sp == '\0') { lastnode = true; } if (strcmp(node, ".") == 0) { continue; } if (strcmp(node, "..") == 0) { strcat(dest, "/.."); continue; } else { strcat(dest, "/"); } strcat(dest, node); if (lstat(dest, &statbuf) == -1) /* File doesn't exist so we can stop here */ { Log(LOG_LEVEL_ERR, "Can't stat '%s' in ExpandLinks. (lstat: %s)", dest, GetErrorStr()); return false; } if (S_ISLNK(statbuf.st_mode)) { memset(buff, 0, CF_BUFSIZE); if (readlink(dest, buff, CF_BUFSIZE - 1) == -1) { Log(LOG_LEVEL_ERR, "Expand links can't stat '%s'. (readlink: %s)", dest, GetErrorStr()); return false; } else { if (buff[0] == '.') { ChopLastNode(dest); AddSlash(dest); /* TODO pass and use parameter dest_size. */ size_t ret = strlcat(dest, buff, CF_BUFSIZE); if (ret >= CF_BUFSIZE) { Log(LOG_LEVEL_ERR, "Internal limit reached in ExpandLinks()," " path too long: '%s' + '%s'", dest, buff); return false; } } else if (IsAbsoluteFileName(buff)) { strcpy(dest, buff); DeleteSlash(dest); if (strcmp(dest, from) == 0) { Log(LOG_LEVEL_DEBUG, "No links to be expanded"); return true; } if ((!lastnode) && (!ExpandLinks(buff, dest, level + 1, max_level))) { return false; } } else { ChopLastNode(dest); AddSlash(dest); /* TODO use param dest_size. */ size_t ret = strlcat(dest, buff, CF_BUFSIZE); if (ret >= CF_BUFSIZE) { Log(LOG_LEVEL_ERR, "Internal limit reached in ExpandLinks end," " path too long: '%s' + '%s'", dest, buff); return false; } DeleteSlash(dest); if (strcmp(dest, from) == 0) { Log(LOG_LEVEL_DEBUG, "No links to be expanded"); return true; } memset(buff, 0, CF_BUFSIZE); if ((!lastnode) && (!ExpandLinks(buff, dest, level + 1, max_level))) { return false; } } } } } return true; } #endif /* !__MINGW32__ */ /*********************************************************************/ static char *AbsLinkPath(const char *from, const char *relto) /* Take an abolute source and a relative destination object and find the absolute name of the to object */ { int pop = 1; static char destination[CF_BUFSIZE]; /* GLOBAL_R, no need to initialize */ if (IsAbsoluteFileName(relto)) { ProgrammingError("Call to AbsLInkPath with absolute pathname"); } strcpy(destination, from); /* reuse to save stack space */ const char *sp = NULL; for (sp = relto; *sp != '\0'; sp++) { if (strncmp(sp, "../", 3) == 0) { pop++; sp += 2; continue; } if (strncmp(sp, "./", 2) == 0) { sp += 1; continue; } break; /* real link */ } while (pop > 0) { ChopLastNode(destination); pop--; } if (strlen(destination) == 0) { strcpy(destination, "/"); } else { AddSlash(destination); } strcat(destination, sp); Log(LOG_LEVEL_DEBUG, "Reconstructed absolute linkname '%s'", destination); return destination; } cfengine-3.24.2/libpromises/vars.c0000644000000000000000000002534515010704253017033 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include static bool IsCf3Scalar(char *str); /*******************************************************************/ bool RlistIsUnresolved(const Rlist *list) { for (const Rlist *rp = list; rp != NULL; rp = rp->next) { // JSON data container values are never expanded, except with the // data_expand() function which see. if (rp->val.type == RVAL_TYPE_CONTAINER) { continue; } if (rp->val.type != RVAL_TYPE_SCALAR) { return true; } if (IsCf3Scalar(RlistScalarValue(rp))) { if (strstr(RlistScalarValue(rp), "$(this)") || strstr(RlistScalarValue(rp), "${this}") || strstr(RlistScalarValue(rp), "$(this.k)") || strstr(RlistScalarValue(rp), "${this.k}") || strstr(RlistScalarValue(rp), "$(this.k[1])") || strstr(RlistScalarValue(rp), "${this.k[1]}") || strstr(RlistScalarValue(rp), "$(this.v)") || strstr(RlistScalarValue(rp), "${this.v}")) { // We should allow this in function args for substitution in maplist() etc // We should allow this.k and this.k[1] and this.v in function args for substitution in maparray() etc } else { return true; } } } return false; } /******************************************************************/ bool StringContainsVar(const char *s, const char *v) { int vlen = strlen(v); if (s == NULL) { return false; } /* Look for ${v}, $(v), @{v}, $(v) */ for (;;) { /* Look for next $ or @ */ s = strpbrk(s, "$@"); if (s == NULL) { return false; } /* If next symbol */ if (*++s == '\0') { return false; } /* is { or ( */ if (*s != '(' && *s != '{') { continue; } /* Then match the variable starting from next symbol */ if (strncmp(s + 1, v, vlen) != 0) { continue; } /* And if it matched, match the closing bracket */ if ((s[0] == '(' && s[vlen + 1] == ')') || (s[0] == '{' && s[vlen + 1] == '}')) { return true; } } } /*********************************************************************/ bool IsCf3VarString(const char *str) { char left = 'x', right = 'x'; int dollar = false; int bracks = 0, vars = 0; if (str == NULL) { return false; } for (const char *sp = str; *sp != '\0'; sp++) /* check for varitems */ { switch (*sp) { case '$': case '@': if (*(sp + 1) == '{' || *(sp + 1) == '(') { dollar = true; } break; case '(': case '{': if (dollar) { left = *sp; bracks++; } break; case ')': case '}': if (dollar) { bracks--; right = *sp; } break; } /* Some chars cannot be in variable ids, e.g. $(/bin/cat file) is legal in bash */ if ((bracks > 0) && (*sp == '/')) { return false; } if (left == '(' && right == ')' && dollar && (bracks == 0)) { vars++; dollar = false; } if (left == '{' && right == '}' && dollar && (bracks == 0)) { vars++; dollar = false; } } if (dollar && (bracks != 0)) { char output[CF_BUFSIZE]; snprintf(output, CF_BUFSIZE, "Broken variable syntax or bracket mismatch in string (%s)", str); yyerror(output); return false; } return (vars != 0); } /*********************************************************************/ static bool IsCf3Scalar(char *str) { char *sp; char left = 'x', right = 'x'; int dollar = false; int bracks = 0, vars = 0; if (str == NULL) { return false; } for (sp = str; *sp != '\0'; sp++) /* check for varitems */ { switch (*sp) { case '$': if (*(sp + 1) == '{' || *(sp + 1) == '(') { dollar = true; } break; case '(': case '{': if (dollar) { left = *sp; bracks++; } break; case ')': case '}': if (dollar) { bracks--; right = *sp; } break; } /* Some chars cannot be in variable ids, e.g. $(/bin/cat file) is legal in bash */ if ((bracks > 0) && (*sp == '/')) { return false; } if (left == '(' && right == ')' && dollar && (bracks == 0)) { vars++; dollar = false; } if (left == '{' && right == '}' && dollar && (bracks == 0)) { vars++; dollar = false; } } if (dollar && (bracks != 0)) { char output[CF_BUFSIZE]; snprintf(output, CF_BUFSIZE, "Broken scalar variable syntax or bracket mismatch in '%s'", str); yyerror(output); return false; } return (vars != 0); } /* Extract everything up to the dollar sign. */ size_t ExtractScalarPrefix(Buffer *out, const char *str, size_t len) { assert(str); if (len == 0) { return 0; } const char *dollar_point = NULL; for (size_t i = 0; i < (len - 1); i++) { if (str[i] == '$') { if (str[i + 1] == '(' || str[i + 1] == '{') { dollar_point = str + i; break; } } } if (!dollar_point) { BufferAppend(out, str, len); return len; } else if (dollar_point > str) { size_t prefix_len = dollar_point - str; if (prefix_len > 0) { BufferAppend(out, str, prefix_len); } return prefix_len; } return 0; } static const char *ReferenceEnd(const char *str, size_t len) { assert(len > 1); assert(str[0] == '$'); assert(str[1] == '{' || str[1] == '('); #define MAX_VARIABLE_REFERENCE_LEVELS 10 char stack[MAX_VARIABLE_REFERENCE_LEVELS] = { 0, str[1], 0 }; int level = 1; for (size_t i = 2; i < len; i++) { switch (str[i]) { case '{': case '(': if (level < MAX_VARIABLE_REFERENCE_LEVELS - 1) { level++; stack[level] = str[i]; } else { Log(LOG_LEVEL_ERR, "Stack overflow in variable reference parsing. More than %d levels", MAX_VARIABLE_REFERENCE_LEVELS); return NULL; } break; case '}': if (stack[level] != '{') { Log(LOG_LEVEL_ERR, "Variable reference bracket mismatch '%.*s'", (int) len, str); return NULL; } level--; break; case ')': if (stack[level] != '(') { Log(LOG_LEVEL_ERR, "Variable reference bracket mismatch '%.*s'", (int) len, str); return NULL; } level--; break; } if (level == 0) { return str + i; } } return NULL; } /** * Extract variable inside dollar-paren. * @param extract_inner ignore opening dollar-paren and closing paren. */ bool ExtractScalarReference(Buffer *out, const char *str, size_t len, bool extract_inner) { if (len <= 1) { return false; } const char *dollar_point = memchr(str, '$', len); if (!dollar_point || (size_t) (dollar_point - str) == len) { return false; } else { const char *close_point = NULL; { size_t remaining = len - (dollar_point - str); if (*(dollar_point + 1) == '{' || *(dollar_point + 1) == '(') { close_point = ReferenceEnd(dollar_point, remaining); } else { return ExtractScalarReference(out, dollar_point + 1, remaining - 1, extract_inner); } } if (!close_point) { Log(LOG_LEVEL_ERR, "Variable reference close mismatch '%.*s'", (int) len, str); return false; } size_t outer_len = close_point - dollar_point + 1; if (outer_len <= 3) { Log(LOG_LEVEL_ERR, "Empty variable reference close mismatch '%.*s'", (int) len, str); return false; } if (extract_inner) { BufferAppend(out, dollar_point + 2, outer_len - 3); } else { BufferAppend(out, dollar_point, outer_len); } return true; } } /*********************************************************************/ bool IsQualifiedVariable(const char *var) { int isarraykey = false; for (const char *sp = var; *sp != '\0'; sp++) { if (*sp == '[') { isarraykey = true; } if (isarraykey) { return false; } else { if (*sp == '.') { return true; } } } return false; } cfengine-3.24.2/libpromises/process_hpux.c0000644000000000000000000000333215010704253020572 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include time_t GetProcessStartTime(pid_t pid) { struct pst_status proc; if (pstat_getproc(&proc, sizeof(proc), 0, pid) > 0) { return proc.pst_start; } else { return PROCESS_START_TIME_UNKNOWN; } } ProcessState GetProcessState(pid_t pid) { struct pst_status proc; if (pstat_getproc(&proc, sizeof(proc), 0, pid) > 0) { switch (proc.pst_stat) { case PS_STOP: return PROCESS_STATE_STOPPED; case PS_ZOMBIE: return PROCESS_STATE_ZOMBIE; default: return PROCESS_STATE_RUNNING; } } else { return PROCESS_STATE_DOES_NOT_EXIST; } } cfengine-3.24.2/libpromises/files_names.c0000644000000000000000000004704315010704253020344 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include /*********************************************************************/ bool IsNewerFileTree(const char *dir, time_t reftime) { const struct dirent *dirp; Dir *dirh; struct stat sb; // Assumes that race conditions on the file path are unlikely and unimportant if (lstat(dir, &sb) == -1) { Log(LOG_LEVEL_ERR, "Unable to stat directory '%s' in IsNewerFileTree. (stat: %s)", dir, GetErrorStr()); // return true to provoke update return true; } if (S_ISDIR(sb.st_mode)) { if (sb.st_mtime > reftime) { Log(LOG_LEVEL_VERBOSE, " >> Detected change in %s", dir); return true; } } if ((dirh = DirOpen(dir)) == NULL) { Log(LOG_LEVEL_ERR, "Unable to open directory '%s' in IsNewerFileTree. (opendir: %s)", dir, GetErrorStr()); return false; } else { for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, "..")) { continue; } char path[CF_BUFSIZE]; size_t ret = (size_t) snprintf(path, sizeof(path), "%s%c%s", dir, FILE_SEPARATOR, dirp->d_name); if (ret >= sizeof(path)) { Log(LOG_LEVEL_ERR, "Internal limit reached in IsNewerFileTree()," " path too long: '%s' + '%s'", dir, dirp->d_name); DirClose(dirh); return false; } if (lstat(path, &sb) == -1) { Log(LOG_LEVEL_ERR, "Unable to stat directory '%s' in IsNewerFileTree. (lstat: %s)", path, GetErrorStr()); DirClose(dirh); // return true to provoke update return true; } if (S_ISDIR(sb.st_mode)) { if (sb.st_mtime > reftime) { Log(LOG_LEVEL_VERBOSE, " >> Detected change in %s", path); DirClose(dirh); return true; } else { if (IsNewerFileTree(path, reftime)) { DirClose(dirh); return true; } } } } } DirClose(dirh); return false; } /*********************************************************************/ bool IsDir(const char *path) /* Checks if the object pointed to by path exists and is a directory. Returns true if so, false otherwise. */ { #ifdef __MINGW32__ return NovaWin_IsDir(path); #else struct stat sb; if (stat(path, &sb) != -1) { if (S_ISDIR(sb.st_mode)) { return true; } } return false; #endif /* !__MINGW32__ */ } /*********************************************************************/ char *JoinSuffix(char *path, size_t path_size, const char *leaf) { int len = strlen(leaf); if (Chop(path, path_size) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } DeleteSlash(path); if (strlen(path) + len + 1 > path_size) { Log(LOG_LEVEL_ERR, "JoinSuffix: Internal limit reached. Tried to add %s to %s", leaf, path); return NULL; } strlcat(path, leaf, path_size); return path; } /** * Just like the JoinSuffix() above, but makes sure there's a FILE_SEPARATOR * between @path and @leaf_path. The only exception is the case where @path is * "" and @leaf_path doesn't start with a FILE_SEPARATOR. In that case: * JoinPaths("", PATH_MAX, "some_path") -> "some_path" * * This function is similar to Python's os.path.join() except that unlike the * Python function this one actually joins @path and @leaf_path even if * @leaf_path starts with a FILE_SEPARATOR. */ char *JoinPaths(char *path, size_t path_size, const char *leaf_path) { size_t len = strlen(leaf_path); size_t path_len = strnlen(path, path_size); if (Chop(path, path_size - 1) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); return NULL; } if (path_len + len + 1 > path_size) { Log(LOG_LEVEL_ERR, "JoinPaths: Internal limit reached. Tried to add %s to %s", leaf_path, path); return NULL; } /* make sure there's a FILE_SEPARATOR between path and leaf_path */ if ((path_len > 0 && !IsFileSep(path[path_len - 1])) && !IsFileSep(leaf_path[0])) { strlcat(path, FILE_SEPARATOR_STR, path_size); } else if ((path_len > 0 && IsFileSep(path[path_len - 1])) && IsFileSep(leaf_path[0])) { leaf_path += 1; } strlcat(path, leaf_path, path_size); return path; } bool IsAbsPath(const char *path) { if (IsFileSep(*path)) { return true; } else { return false; } } /** * Append a slash, of the kind that the string already has, only if the string * doesn't end in one. */ void AddSlash(char *str) { char *sp, *sep = FILE_SEPARATOR_STR; int f = false, b = false; if (str == NULL) { return; } if (strlen(str) == 0) { strcpy(str, sep); return; } /* Try to see what convention is being used for filenames in case this is a cross-system copy from Win/Unix */ for (sp = str; *sp != '\0'; sp++) { switch (*sp) { case '/': f = true; break; case '\\': b = true; break; default: break; } } if (f && (!b)) { sep = "/"; } else if (b && (!f)) { sep = "\\"; } if (!IsFileSep(str[strlen(str) - 1])) { strcat(str, sep); } } /*********************************************************************/ char *GetParentDirectoryCopy(const char *path) /** * WARNING: Remember to free return value. **/ { assert(path); assert(strlen(path) > 0); char *path_copy = xstrdup(path); if(strcmp(path_copy, "/") == 0) { return path_copy; } char *sp = (char *)LastFileSeparator(path_copy); if(!sp) { Log(LOG_LEVEL_ERR, "Path %s does not contain file separators (GetParentDirectory())", path_copy); free(path_copy); return NULL; } if(sp == FirstFileSeparator(path_copy)) // don't chop off first path separator { *(sp + 1) = '\0'; } else { *sp = '\0'; } return path_copy; } /*********************************************************************/ // Can remove several slashes if they are redundant. void DeleteSlash(char *str) { int size = strlen(str); if ((size == 0) || (str == NULL)) { return; } int root = RootDirLength(str); while (IsFileSep(str[size - 1]) && size - 1 > root) { size--; } str[size] = '\0'; /* no-op if we didn't change size */ } /*********************************************************************/ void DeleteRedundantSlashes(char *str) { int move_from; // Invariant: newpos <= oldpos int oldpos = RootDirLength(str); int newpos = oldpos; while (str[oldpos] != '\0') { // Skip over subsequent separators. while (IsFileSep(str[oldpos])) { oldpos++; } move_from = oldpos; // And then skip over the next path component. while (str[oldpos] != '\0' && !IsFileSep(str[oldpos])) { oldpos++; } // If next character is file separator, move past it, since we want to keep one. if (IsFileSep(str[oldpos])) { oldpos++; } int move_len = oldpos - move_from; memmove(&str[newpos], &str[move_from], move_len); newpos += move_len; } str[newpos] = '\0'; } /*********************************************************************/ const char *FirstFileSeparator(const char *str) { assert(str); assert(strlen(str) > 0); if(strncmp(str, "\\\\", 2) == 0) // windows share { return str + 1; } for(const char *pos = str; *pos != '\0'; pos++) { if(IsFileSep(*pos)) { return pos; } } return NULL; } /*********************************************************************/ const char *LastFileSeparator(const char *str) /* Return pointer to last file separator in string, or NULL if string does not contains any file separtors */ { const char *sp; /* Walk through string backwards */ sp = str + strlen(str) - 1; while (sp >= str) { if (IsFileSep(*sp)) { return sp; } sp--; } return NULL; } /*********************************************************************/ bool ChopLastNode(char *str) /* Chop off trailing node name (possible blank) starting from last character and removing up to the first / encountered e.g. /a/b/c -> /a/b /a/b/ -> /a/b Will also collapse redundant/repeating path separators. */ { char *sp; bool ret; DeleteRedundantSlashes(str); /* Here cast is necessary and harmless, str is modifiable */ if ((sp = (char *) LastFileSeparator(str)) == NULL) { int pos = RootDirLength(str); if (str[pos] == '\0') { ret = false; } else { str[pos] = '.'; str[pos + 1] = '\0'; ret = true; } } else { // Don't chop the root slash in an absolute path. if (IsAbsoluteFileName(str) && FirstFileSeparator(str) == sp) { *(++sp) = '\0'; } else { *sp = '\0'; } ret = true; } return ret; } /*********************************************************************/ void TransformNameInPlace(char *s, char from, char to) { for (; *s != '\0'; s++) { if (*s == from) { *s = to; } } } /*********************************************************************/ /* TODO remove, kill, burn this function! Replace with BufferCanonify or CanonifyNameInPlace */ char *CanonifyName(const char *str) { static char buffer[CF_BUFSIZE]; /* GLOBAL_R, no initialization needed */ strlcpy(buffer, str, CF_BUFSIZE); CanonifyNameInPlace(buffer); return buffer; } /*********************************************************************/ char *CanonifyChar(const char *str, char ch) { static char buffer[CF_BUFSIZE]; /* GLOBAL_R, no initialization needed */ char *sp; strlcpy(buffer, str, CF_BUFSIZE); for (sp = buffer; *sp != '\0'; sp++) { if (*sp == ch) { *sp = '_'; } } return buffer; } /*********************************************************************/ int CompareCSVName(const char *s1, const char *s2) { const char *sp1, *sp2; char ch1, ch2; for (sp1 = s1, sp2 = s2; (*sp1 != '\0') || (*sp2 != '\0'); sp1++, sp2++) { ch1 = (*sp1 == ',') ? '_' : *sp1; ch2 = (*sp2 == ',') ? '_' : *sp2; if (ch1 > ch2) { return 1; } else if (ch1 < ch2) { return -1; } } return 0; } /*********************************************************************/ const char *ReadLastNode(const char *str) /* Return the last node of a pathname string */ { const char *sp; if ((sp = LastFileSeparator(str)) == NULL) { return str; } else { return sp + 1; } } /*********************************************************************/ bool CompressPath(char *dest, size_t dest_size, const char *src) { char node[CF_BUFSIZE]; int nodelen; int rootlen; memset(dest, 0, dest_size); rootlen = RootDirLength(src); if((size_t) rootlen >= dest_size) { Log(LOG_LEVEL_ERR, "Internal limit reached in CompressPath()," "src path too long (%d bytes): '%s'", rootlen, src); return false; } memcpy(dest, src, rootlen); for (const char *sp = src + rootlen; *sp != '\0'; sp++) { if (IsFileSep(*sp)) { continue; } for (nodelen = 0; (sp[nodelen] != '\0') && (!IsFileSep(sp[nodelen])); nodelen++) { if (nodelen > CF_MAXLINKSIZE) { Log(LOG_LEVEL_ERR, "Link in path suspiciously large"); return false; } } strncpy(node, sp, nodelen); node[nodelen] = '\0'; sp += nodelen - 1; if (strcmp(node, ".") == 0) { continue; } if (strcmp(node, "..") == 0) { if (!ChopLastNode(dest)) { Log(LOG_LEVEL_DEBUG, "used .. beyond top of filesystem!"); return false; } continue; } AddSlash(dest); size_t ret = strlcat(dest, node, dest_size); if (ret >= CF_BUFSIZE) { Log(LOG_LEVEL_ERR, "Internal limit reached in CompressPath()," " path too long: '%s' + '%s'", dest, node); return false; } } return true; } /*********************************************************************/ /** * Get absolute path of @path. If @path is already an absolute path this * function just returns a compressed (see CompressPath()) copy of it. Otherwise * this function prepends the curent working directory before @path and returns * the result compressed with CompressPath(). If anything goes wrong, an empty * string is returned. * * WARNING: Remember to free return value. **/ char *GetAbsolutePath(const char *path) { if (NULL_OR_EMPTY(path)) { return NULL; } char abs_path[PATH_MAX] = { 0 }; if (IsAbsoluteFileName(path)) { CompressPath(abs_path, PATH_MAX, path); return xstrdup(abs_path); } else { /* the full_path can potentially be long (with many '../' parts)*/ char full_path[2 * PATH_MAX] = { 0 }; if (getcwd(full_path, PATH_MAX) == NULL) { Log(LOG_LEVEL_WARNING, "Could not determine current directory (getcwd: %s)", GetErrorStr()); } JoinPaths(full_path, 2 * PATH_MAX, path); CompressPath(abs_path, PATH_MAX, full_path); return xstrdup(abs_path); } } char *GetRealPath(const char *const path) { if (NULL_OR_EMPTY(path)) { return NULL; } char *const abs_path = GetAbsolutePath(path); if (NULL_OR_EMPTY(abs_path)) { free(abs_path); return NULL; } #ifdef __linux__ // POSIX 2008 - could add newer versions of BSD / solaris char *real_path = realpath(abs_path, NULL); if (NOT_NULL_AND_EMPTY(real_path)) { free(real_path); real_path = NULL; } #else // Pre POSIX 2008 - realpath arg cannot be NULL char *const path_buf = xcalloc(1, PATH_MAX); char *real_path = realpath(abs_path, path_buf); if (NULL_OR_EMPTY(real_path)) { free(path_buf); real_path = NULL; } #endif free(abs_path); return real_path; } /*********************************************************************/ FilePathType FilePathGetType(const char *file_path) { if (IsAbsoluteFileName(file_path)) { return FILE_PATH_TYPE_ABSOLUTE; } else if (*file_path == '.') { return FILE_PATH_TYPE_RELATIVE; } else { return FILE_PATH_TYPE_NON_ANCHORED; } } bool IsFileOutsideDefaultRepository(const char *f) { return !StringStartsWith(f, GetInputDir()); } /*******************************************************************/ static int UnixRootDirLength(const char *f) { if (IsFileSep(*f)) { return 1; } return 0; } #ifdef _WIN32 static int NTRootDirLength(const char *f) { int len; if (f[0] == '\\' && f[1] == '\\') { /* UNC style path */ /* Skip over host name */ for (len = 2; f[len] != '\\'; len++) { if (f[len] == '\0') { return len; } } /* Skip over share name */ for (len++; f[len] != '\\'; len++) { if (f[len] == '\0') { return len; } } /* Skip over file separator */ len++; return len; } if (isalpha(f[0]) && f[1] == ':') { if (IsFileSep(f[2])) { return 3; } return 2; } return UnixRootDirLength(f); } #endif int RootDirLength(const char *f) /* Return length of Initial directory in path - */ { #ifdef _WIN32 return NTRootDirLength(f); #else return UnixRootDirLength(f); #endif } /* Buffer should be at least CF_MAXVARSIZE large */ const char *GetSoftwareCacheFilename(char *buffer) { snprintf(buffer, CF_MAXVARSIZE, "%s/%s", GetStateDir(), SOFTWARE_PACKAGES_CACHE); MapName(buffer); return buffer; } /* Buffer should be at least CF_MAXVARSIZE large */ const char *GetSoftwarePatchesFilename(char *buffer) { snprintf(buffer, CF_MAXVARSIZE, "%s/%s", GetStateDir(), SOFTWARE_PATCHES_CACHE); MapName(buffer); return buffer; } const char *RealPackageManager(const char *manager) { assert(manager); const char *pos = strchr(manager, ' '); if (strncmp(manager, "env ", 4) != 0 && (!pos || pos - manager < 4 || strncmp(pos - 4, "/env", 4) != 0)) { return CommandArg0(manager); } // Look for variable assignments. const char *last_pos; bool eq_sign_found = false; while (true) { if (eq_sign_found) { last_pos = pos + 1; } else { last_pos = pos + strspn(pos, " "); // Skip over consecutive spaces. } pos = strpbrk(last_pos, "= "); if (!pos) { break; } if (*pos == '=') { eq_sign_found = true; } else if (eq_sign_found) { eq_sign_found = false; } else { return CommandArg0(last_pos); } } // Reached the end? Weird. Must be env command with no real command. return CommandArg0(manager); } cfengine-3.24.2/libpromises/dbm_api.h0000644000000000000000000001050015010704253017443 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DBM_API_H #define CFENGINE_DBM_API_H #define EC_CORRUPTION_REPAIRED 120 #define EC_CORRUPTION_REPAIR_FAILED 121 #include #include #include // Only append to the end, keep in sync with DB_PATHS_STATEDIR array typedef enum { dbid_classes = 0, // Deprecated dbid_variables = 1, // Deprecated dbid_performance = 2, dbid_checksums = 3, // Deprecated dbid_filestats = 4, // Deprecated dbid_changes = 5, dbid_observations = 6, dbid_state = 7, dbid_lastseen = 8, dbid_audit = 9, dbid_locks = 10, dbid_history = 11, dbid_measure = 12, dbid_static = 13, dbid_scalars = 14, dbid_windows_registry = 15, dbid_cache = 16, dbid_license = 17, dbid_value = 18, dbid_agent_execution = 19, dbid_bundles = 20, // Deprecated dbid_packages_installed = 21, // new package promise installed packages list dbid_packages_updates = 22, // new package promise list of available updates dbid_cookies = 23, // Enterprise reporting cookies for duplicate host detection dbid_max } dbid; typedef struct DBHandle_ DBHandle; typedef struct DBCursor_ DBCursor; typedef DBHandle CF_DB; typedef DBCursor CF_DBC; void DBSetMaximumConcurrentTransactions(int max_txn); bool OpenDB(CF_DB **dbp, dbid db); bool OpenSubDB(DBHandle **dbp, dbid id, const char *sub_name); bool CleanDB(DBHandle *handle); void CloseDB(CF_DB *dbp); DBHandle *GetDBHandleFromFilename(const char *db_file_name); time_t GetDBOpenTimestamp(const DBHandle *handle); /** * @return -1 in case of unknown a number between 0 and 100 otherwise */ int GetDBUsagePercentage(const DBHandle *handle); bool HasKeyDB(CF_DB *dbp, const char *key, int key_size); int ValueSizeDB(CF_DB *dbp, const char *key, int key_size); bool ReadComplexKeyDB(CF_DB *dbp, const char *key, int key_size, void *dest, int destSz); bool WriteComplexKeyDB(CF_DB *dbp, const char *key, int keySz, const void *src, int srcSz); bool DeleteComplexKeyDB(CF_DB *dbp, const char *key, int size); bool ReadDB(CF_DB *dbp, const char *key, void *dest, int destSz); bool WriteDB(CF_DB *dbp, const char *key, const void *src, int srcSz); bool OverwriteDB(DBHandle *handle, const char *key, const void *value, size_t value_size, OverwriteCondition Condition, void *data); bool DeleteDB(CF_DB *dbp, const char *key); void FreezeDB(DBHandle *handle); /* * Creating cursor locks the whole database, so keep the amount of work here to * minimum. * * Don't use WriteDB/DeleteDB while iterating database, it will result in * deadlock. Use cursor-specific operations instead. They work on the current * key. */ bool NewDBCursor(CF_DB *dbp, CF_DBC **dbcp); bool NextDB(CF_DBC *dbcp, char **key, int *ksize, void **value, int *vsize); bool DBCursorDeleteEntry(CF_DBC *cursor); bool DBCursorWriteEntry(CF_DBC *cursor, const void *value, int value_size); bool DeleteDBCursor(CF_DBC *dbcp); char *DBIdToPath(dbid id); char *DBIdToSubPath(dbid id, const char *subdb_name); Seq *SearchExistingSubDBNames(dbid id); StringMap *LoadDatabaseToStringMap(dbid database_id); bool CheckDBRepairFlagFile(); #endif /* NOT CFENGINE_DBM_API_H */ cfengine-3.24.2/libpromises/keyring.h0000644000000000000000000000221215010704253017521 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_KEYRING_H #define CFENGINE_KEYRING_H #include bool HostKeyAddressUnknown(const char *value); int RemovePublicKey(const char *id); #endif cfengine-3.24.2/libpromises/dbm_tokyocab.c0000644000000000000000000003127415010704253020513 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * Implementation using Tokyo Cabinet hash API. */ #include #include #include #include #ifdef TCDB # include # include struct DBPriv_ { /* * This mutex prevents destructive modifications of the database (removing * records) while the cursor is active on it. */ pthread_mutex_t cursor_lock; TCHDB *hdb; }; struct DBCursorPriv_ { DBPriv *db; char *current_key; int current_key_size; char *curval; /* * Removing a key underneath the active cursor stops the database iteration, * so if key needs to be deleted while database is iterated, this fact is * remembered and once iterator advances to next key, this pending delete is * executed. * * Writes to key underneath the active cursor are safe, so only deletes are * tracked. */ bool pending_delete; }; /******************************************************************************/ static bool LockCursor(DBPriv *db) { int ret = pthread_mutex_lock(&db->cursor_lock); if (ret != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to obtain cursor lock for Tokyo Cabinet database. (pthread_mutex_lock: %s)", GetErrorStr()); return false; } return true; } static void UnlockCursor(DBPriv *db) { int ret = pthread_mutex_unlock(&db->cursor_lock); if (ret != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to release cursor lock for Tokyo Cabinet database. (pthread_mutex_unlock: %s)", GetErrorStr()); } } const char *DBPrivGetFileExtension(void) { return "tcdb"; } static const char *ErrorMessage(TCHDB *hdb) { return tchdberrmsg(tchdbecode(hdb)); } static bool OpenTokyoDatabase(const char *filename, TCHDB **hdb) { *hdb = tchdbnew(); if (!tchdbsetmutex(*hdb)) { return false; } if (!tchdbopen(*hdb, filename, HDBOWRITER | HDBOCREAT)) { return false; } static int threshold = -1; /* GLOBAL_X */ if (threshold == -1) { /** Optimize always if TCDB_OPTIMIZE_PERCENT is equal to 100 Never optimize if TCDB_OPTIMIZE_PERCENT is equal to 0 */ const char *perc = getenv("TCDB_OPTIMIZE_PERCENT"); if (perc != NULL) { /* Environment variable exists */ char *end; long result = strtol(perc, &end, 10); /* Environment variable is a number and in 0..100 range */ if (!*end && result >-1 && result < 101) { threshold = 100 - (int)result; } else { /* This corresponds to 1% */ threshold = 99; } } else { /* This corresponds to 1% */ threshold = 99; } } if ((threshold != 100) && (threshold == 0 || (int)(rand()%threshold) == 0)) { if (!tchdboptimize(*hdb, -1, -1, -1, false)) { tchdbclose(*hdb); return false; } } return true; } void DBPrivSetMaximumConcurrentTransactions(ARG_UNUSED int max_txn) { } DBPriv *DBPrivOpenDB(const char *dbpath, ARG_UNUSED dbid id) { DBPriv *db = xcalloc(1, sizeof(DBPriv)); pthread_mutex_init(&db->cursor_lock, NULL); if (!OpenTokyoDatabase(dbpath, &db->hdb)) { Log(LOG_LEVEL_ERR, "Could not open Tokyo database at path '%s'. (OpenTokyoDatabase: %s)", dbpath, ErrorMessage(db->hdb)); int errcode = tchdbecode(db->hdb); if(errcode != TCEMETA && errcode != TCEREAD) { goto err; } tchdbdel(db->hdb); return DB_PRIV_DATABASE_BROKEN; } return db; err: pthread_mutex_destroy(&db->cursor_lock); tchdbdel(db->hdb); free(db); return NULL; } void DBPrivCloseDB(DBPriv *db) { int ret; if ((ret = pthread_mutex_destroy(&db->cursor_lock)) != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to destroy mutex during Tokyo Cabinet database handle close. (pthread_mutex_destroy: %s)", GetErrorStr()); } if (!tchdbclose(db->hdb)) { Log(LOG_LEVEL_ERR, "Closing database failed. (tchdbclose: %s)", ErrorMessage(db->hdb)); } tchdbdel(db->hdb); free(db); } void DBPrivCommit(ARG_UNUSED DBPriv *db) { } bool DBPrivClean(DBPriv *db) { DBCursorPriv *cursor = DBPrivOpenCursor(db); if (!cursor) { return false; } void *key; int key_size; void *value; int value_size; while ((DBPrivAdvanceCursor(cursor, &key, &key_size, &value, &value_size))) { DBPrivDeleteCursorEntry(cursor); } DBPrivCloseCursor(cursor); return true; } int DBPrivGetDBUsagePercentage(ARG_UNUSED const char *db_path) { Log(LOG_LEVEL_WARNING, "Cannot determine usage of a TokyoCabinet database"); return -1; } bool DBPrivHasKey(DBPriv *db, const void *key, int key_size) { // FIXME: distinguish between "entry not found" and "error occurred" return tchdbvsiz(db->hdb, key, key_size) != -1; } int DBPrivGetValueSize(DBPriv *db, const void *key, int key_size) { return tchdbvsiz(db->hdb, key, key_size); } bool DBPrivRead(DBPriv *db, const void *key, int key_size, void *dest, size_t dest_size) { if (tchdbget3(db->hdb, key, key_size, dest, dest_size) == -1) { if (tchdbecode(db->hdb) != TCENOREC) { Log(LOG_LEVEL_ERR, "Could not read key '%s': (tchdbget3: %s)", (const char *)key, ErrorMessage(db->hdb)); } return false; } return true; } static bool Write(TCHDB *hdb, const void *key, int key_size, const void *value, int value_size) { if (!tchdbput(hdb, key, key_size, value, value_size)) { Log(LOG_LEVEL_ERR, "Could not write key to Tokyo path '%s'. (tchdbput: %s)", tchdbpath(hdb), ErrorMessage(hdb)); return false; } return true; } static bool Delete(TCHDB *hdb, const void *key, int key_size) { if (!tchdbout(hdb, key, key_size) && tchdbecode(hdb) != TCENOREC) { Log(LOG_LEVEL_ERR, "Could not delete Tokyo key. (tchdbout: %s)", ErrorMessage(hdb)); return false; } return true; } /* * This one has to be locked against cursor, or interaction between * write/pending delete might yield surprising results. */ bool DBPrivWrite(DBPriv *db, const void *key, int key_size, const void *value, int value_size) { /* FIXME: get a cursor and see what is the current key */ int ret = Write(db->hdb, key, key_size, value, value_size); return ret; } bool DBPrivOverwrite(DBPriv *db, const char *key, int key_size, const void *value, size_t value_size, OverwriteCondition Condition, void *data) { ssize_t cur_val_size = tchdbvsiz(db->hdb, key, key_size); void *cur_val = NULL; bool exists = (cur_val_size > 0); if (exists) { assert(cur_val_size > 0); cur_val = xmalloc(cur_val_size); if (tchdbget3(db->hdb, key, key_size, cur_val, cur_val_size) == -1) { /* If exists, we should never get the TCENOREC error. */ assert(tchdbecode(db->hdb) != TCENOREC); Log(LOG_LEVEL_ERR, "Could not read key '%s': (tchdbget3: %s)", (const char *)key, ErrorMessage(db->hdb)); free(cur_val); return false; } } if ((Condition != NULL) && !Condition(cur_val, cur_val_size, data)) { free(cur_val); return false; } free(cur_val); return Write(db->hdb, key, key_size, value, value_size); } /* * This one has to be locked against cursor -- deleting entries might interrupt * iteration. */ bool DBPrivDelete(DBPriv *db, const void *key, int key_size) { if (!LockCursor(db)) { return false; } int ret = Delete(db->hdb, key, key_size); UnlockCursor(db); return ret; } DBCursorPriv *DBPrivOpenCursor(DBPriv *db) { if (!LockCursor(db)) { return false; } DBCursorPriv *cursor = xcalloc(1, sizeof(DBCursorPriv)); cursor->db = db; /* Cursor remains locked */ return cursor; } bool DBPrivAdvanceCursor(DBCursorPriv *cursor, void **key, int *key_size, void **value, int *value_size) { *key = tchdbgetnext3(cursor->db->hdb, cursor->current_key, cursor->current_key_size, key_size, (const char **)value, value_size); /* * If there is pending delete on the key, apply it */ if (cursor->pending_delete) { Delete(cursor->db->hdb, cursor->current_key, cursor->current_key_size); } /* This will free the value as well: tchdbgetnext3 returns single allocated * chunk of memory */ free(cursor->current_key); cursor->current_key = *key; cursor->current_key_size = *key_size; cursor->pending_delete = false; return *key != NULL; } bool DBPrivDeleteCursorEntry(DBCursorPriv *cursor) { cursor->pending_delete = true; return true; } bool DBPrivWriteCursorEntry(DBCursorPriv *cursor, const void *value, int value_size) { /* * If a pending deletion of entry has been requested, cancel it */ cursor->pending_delete = false; return Write(cursor->db->hdb, cursor->current_key, cursor->current_key_size, value, value_size); } void DBPrivCloseCursor(DBCursorPriv *cursor) { DBPriv *db = cursor->db; if (cursor->pending_delete) { Delete(db->hdb, cursor->current_key, cursor->current_key_size); } free(cursor->current_key); free(cursor); /* Cursor lock was obtained in DBPrivOpenCursor */ UnlockCursor(db); } char *DBPrivDiagnose(const char *dbpath) { #define SWAB64(num) \ ( \ ((num & 0x00000000000000ffULL) << 56) | \ ((num & 0x000000000000ff00ULL) << 40) | \ ((num & 0x0000000000ff0000ULL) << 24) | \ ((num & 0x00000000ff000000ULL) << 8) | \ ((num & 0x000000ff00000000ULL) >> 8) | \ ((num & 0x0000ff0000000000ULL) >> 24) | \ ((num & 0x00ff000000000000ULL) >> 40) | \ ((num & 0xff00000000000000ULL) >> 56) \ ) static const char *const MAGIC="ToKyO CaBiNeT"; FILE *fp = fopen(dbpath, "r"); if(!fp) { return StringFormat("Error opening file '%s': %s", dbpath, strerror(errno)); } if(fseek(fp, 0, SEEK_END) != 0) { fclose(fp); return StringFormat("Error seeking to end: %s\n", strerror(errno)); } long size = ftell(fp); if(size < 256) { fclose(fp); return StringFormat("Seek-to-end size less than minimum required: %ld", size); } char hbuf[256]; memset(hbuf, 0, sizeof(hbuf)); if(fseek(fp, 0, SEEK_SET) != 0) { fclose(fp); return StringFormat("Error seeking to offset 256: %s", strerror(errno)); } if(fread(&hbuf, 256, 1, fp) != 1) { fclose(fp); return StringFormat("Error reading 256 bytes: %s\n", strerror(errno)); } fclose(fp); if(strncmp(hbuf, MAGIC, strlen(MAGIC)) != 0) { return StringFormat("Magic string mismatch"); } uint64_t declared_size = 0; /* Read file size from tchdb header. It is stored in little endian. */ memcpy(&declared_size, &hbuf[56], sizeof(uint64_t)); if (declared_size == (uint64_t) size) { return NULL; // all is well } else { declared_size = SWAB64(declared_size); if (declared_size == (uint64_t) size) { return StringFormat("Endianness mismatch, declared size SWAB64 '%ju' equals seek-to-end size '%ld'", (uintmax_t) declared_size, size); } else { return StringFormat("Size mismatch, declared size SWAB64 '%ju', seek-to-end-size '%ld'", (uintmax_t) declared_size, size); } } } #endif cfengine-3.24.2/libpromises/process_unix_stub.c0000644000000000000000000000337715010704253021637 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include time_t GetProcessStartTime(ARG_UNUSED pid_t pid) { Log(LOG_LEVEL_VERBOSE, "No platform-specific code for obtaining process start time. - " "Falling back to no PID double-checking on kill()"); return PROCESS_START_TIME_UNKNOWN; } ProcessState GetProcessState(pid_t pid) { Log(LOG_LEVEL_DEBUG, "No platform-specific code for obtaining process state. - " "Falling back to no PID double-checking on kill()"); if (kill(pid, 0) < 0 && errno == ESRCH) { return PROCESS_STATE_DOES_NOT_EXIST; } /* It might be RUNNING, STOPPED or ZOMBIE, but we can't tell the * difference without platform specific code. */ return PROCESS_STATE_RUNNING; } cfengine-3.24.2/libpromises/variable.c0000644000000000000000000002367515010704253017651 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /* DataTypeToString */ #define VARIABLE_TAG_SECRET "secret" struct Variable_ { VarRef *ref; Rval rval; DataType type; StringSet *tags; char *comment; const Promise *promise; // The promise that set the present value }; static Variable *VariableNew(VarRef *ref, Rval rval, DataType type, StringSet *tags, char *comment, const Promise *promise) { Variable *var = xmalloc(sizeof(Variable)); var->ref = ref; var->rval = rval; var->type = type; var->tags = tags; var->comment = comment; var->promise = promise; return var; } /* DO NOT EXPORT, this is for internal (hash table) use only, and it doesn't * free everything in Variable, in particular it leaves var->ref to be handled * by the Map implementation calling the key-destroy function. */ static void VariableDestroy(Variable *var) { if (var != NULL) { RvalDestroy(var->rval); StringSetDestroy(var->tags); free(var->comment); // Nothing to do for ->promise free(var); } } static void VariableDestroy_untyped(void *var) { VariableDestroy(var); } const VarRef *VariableGetRef(const Variable *var) { assert(var != NULL); return var->ref; } DataType VariableGetType(const Variable *var) { assert(var != NULL); return var->type; } RvalType VariableGetRvalType(const Variable *var) { assert(var != NULL); return var->rval.type; } StringSet *VariableGetTags(const Variable *var) { assert(var != NULL); return var->tags; } const char *VariableGetComment(const Variable *var) { assert(var != NULL); return var->comment; } const Promise *VariableGetPromise(const Variable *var) { assert(var != NULL); return var->promise; } bool VariableIsSecret(const Variable *var) { assert(var != NULL); return ((var->tags != NULL) && StringSetContains(var->tags, VARIABLE_TAG_SECRET)); } Rval VariableGetRval(const Variable *var, bool get_secret) { assert(var != NULL); if (!get_secret && VariableIsSecret(var)) { return RvalNewSecret(); } return var->rval; } void VariableSetRval(Variable *var, Rval new_rval) { assert(var != NULL); RvalDestroy(var->rval); var->rval = new_rval; } /** Define "VarMap" hash table. Key: VarRef Value: Variable */ TYPED_MAP_DECLARE(Var, VarRef *, Variable *) TYPED_MAP_DEFINE(Var, VarRef *, Variable *, VarRefHash_untyped, VarRefEqual_untyped, VarRefDestroy_untyped, VariableDestroy_untyped) struct VariableTable_ { VarMap *vars; }; struct VariableTableIterator_ { VarRef *ref; MapIterator iter; }; VariableTable *VariableTableNew(void) { VariableTable *table = xmalloc(sizeof(VariableTable)); table->vars = VarMapNew(); return table; } void VariableTableDestroy(VariableTable *table) { if (table) { VarMapDestroy(table->vars); free(table); } } /* NULL return value means variable not found. */ Variable *VariableTableGet(const VariableTable *table, const VarRef *ref) { Variable *v = VarMapGet(table->vars, ref); char *ref_s = VarRefToString(ref, true); /* TODO optimise */ if (v != NULL) { CF_ASSERT(v->rval.item != NULL || DataTypeIsIterable(v->type), "VariableTableGet(%s): " "Only iterables (Rlists) are allowed to be NULL", ref_s); } if (LogModuleEnabled(LOG_MOD_VARTABLE)) { Buffer *buf = BufferNew(); BufferPrintf(buf, "VariableTableGet(%s): %s", ref_s, v ? DataTypeToString(v->type) : "NOT FOUND"); if (v != NULL) { char *value_s; BufferAppendString(buf, " => "); if (DataTypeIsIterable(v->type) && v->rval.item == NULL) { value_s = xstrdup("EMPTY"); } else { value_s = RvalToString(v->rval); } BufferAppendString(buf, value_s); free(value_s); } LogDebug(LOG_MOD_VARTABLE, "%s", BufferGet(buf)); BufferDestroy(buf); } free(ref_s); return v; } bool VariableTableRemove(VariableTable *table, const VarRef *ref) { return VarMapRemove(table->vars, ref); } bool VariableTablePut(VariableTable *table, const VarRef *ref, const Rval *rval, DataType type, StringSet *tags, char *comment, const Promise *promise) { assert(VarRefIsQualified(ref)); /* TODO assert there are no CF_NS or '.' in the variable name? */ if (LogModuleEnabled(LOG_MOD_VARTABLE)) { char *value_s = RvalToString(*rval); LogDebug(LOG_MOD_VARTABLE, "VariableTablePut(%s): %s => %s", ref->lval, DataTypeToString(type), rval->item ? value_s : "EMPTY"); free(value_s); } CF_ASSERT(rval != NULL || DataTypeIsIterable(type), "VariableTablePut(): " "Only iterables (Rlists) are allowed to be NULL"); Variable *var = VariableNew(VarRefCopy(ref), RvalCopy(*rval), type, tags, comment, promise); return VarMapInsert(table->vars, var->ref, var); } bool VariableTableClear(VariableTable *table, const char *ns, const char *scope, const char *lval) { const size_t vars_num = VarMapSize(table->vars); if (!ns && !scope && !lval) { VarMapClear(table->vars); bool has_vars = (vars_num > 0); return has_vars; } /* We can't remove elements from the hash table while we are iterating * over it. So we first store the VarRef pointers on a list. */ VarRef **to_remove = xmalloc(vars_num * sizeof(*to_remove)); size_t remove_count = 0; { VariableTableIterator *iter = VariableTableIteratorNew(table, ns, scope, lval); for (Variable *v = VariableTableIteratorNext(iter); v != NULL; v = VariableTableIteratorNext(iter)) { to_remove[remove_count] = v->ref; remove_count++; } VariableTableIteratorDestroy(iter); } if (remove_count == 0) { free(to_remove); return false; } size_t removed = 0; for(size_t i = 0; i < remove_count; i++) { if (VariableTableRemove(table, to_remove[i])) { removed++; } } free(to_remove); assert(removed == remove_count); return true; } size_t VariableTableCount(const VariableTable *table, const char *ns, const char *scope, const char *lval) { if (!ns && !scope && !lval) { return VarMapSize(table->vars); } VariableTableIterator *iter = VariableTableIteratorNew(table, ns, scope, lval); size_t count = 0; while (VariableTableIteratorNext(iter)) { count++; } VariableTableIteratorDestroy(iter); return count; } VariableTableIterator *VariableTableIteratorNewFromVarRef(const VariableTable *table, const VarRef *ref) { VariableTableIterator *iter = xmalloc(sizeof(VariableTableIterator)); iter->ref = VarRefCopy(ref); iter->iter = MapIteratorInit(table->vars->impl); return iter; } VariableTableIterator *VariableTableIteratorNew(const VariableTable *table, const char *ns, const char *scope, const char *lval) { VarRef ref = { 0 }; ref.ns = (char *)ns; ref.scope = (char *)scope; ref.lval = (char *)lval; return VariableTableIteratorNewFromVarRef(table, &ref); } Variable *VariableTableIteratorNext(VariableTableIterator *iter) { MapKeyValue *keyvalue; while ((keyvalue = MapIteratorNext(&iter->iter)) != NULL) { Variable *var = keyvalue->value; const char *key_ns = var->ref->ns ? var->ref->ns : "default"; if (iter->ref->ns && strcmp(key_ns, iter->ref->ns) != 0) { continue; } if (iter->ref->scope && strcmp(var->ref->scope, iter->ref->scope) != 0) { continue; } if (iter->ref->lval && strcmp(var->ref->lval, iter->ref->lval) != 0) { continue; } if (iter->ref->num_indices > 0) { if (iter->ref->num_indices > var->ref->num_indices) { continue; } bool match = true; for (size_t i = 0; i < iter->ref->num_indices; i++) { if (strcmp(var->ref->indices[i], iter->ref->indices[i]) != 0) { match = false; break; } } if (!match) { continue; } } return var; } return NULL; } void VariableTableIteratorDestroy(VariableTableIterator *iter) { if (iter) { VarRefDestroy(iter->ref); free(iter); } } cfengine-3.24.2/libpromises/changes_chroot.h0000644000000000000000000000312015010704253021036 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CHANGES_CHROOT_H #define CFENGINE_CHANGES_CHROOT_H #define CHROOT_CHANGES_LIST_FILE "/changed_files" #define CHROOT_RENAMES_LIST_FILE "/renamed_files" #define CHROOT_KEPT_LIST_FILE "/kept_files" #define CHROOT_PKGS_OPS_FILE "/pkgs_ops" void PrepareChangesChroot(const char *path); bool RecordFileChangedInChroot(const char *path); bool RecordFileRenamedInChroot(const char *old_name, const char *new_name); bool RecordFileEvaluatedInChroot(const char *path); bool RecordPkgOperationInChroot(const char *op, const char *name, const char *arch, const char *version); #endif /* CFENGINE_CHANGES_CHROOT_H */ cfengine-3.24.2/libpromises/files_repository.c0000644000000000000000000001073715010704253021460 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include /* PathAppend */ /*********************************************************************/ static Item *VREPOSLIST = NULL; /* GLOBAL_X */ static char REPOSCHAR = '_'; /* GLOBAL_P */ static char *VREPOSITORY = NULL; /* GLOBAL_P */ /*********************************************************************/ void SetRepositoryLocation(const char *path) { VREPOSITORY = xstrdup(path); } /*********************************************************************/ void SetRepositoryChar(char c) { REPOSCHAR = c; } /*********************************************************************/ bool GetRepositoryPath(ARG_UNUSED const char *file, const Attributes *attr, char *destination) { if ((attr->repository == NULL) && (VREPOSITORY == NULL)) { return false; } size_t repopathlen; if (attr->repository != NULL) { repopathlen = strlcpy(destination, attr->repository, CF_BUFSIZE); } else { repopathlen = strlcpy(destination, VREPOSITORY, CF_BUFSIZE); } if (repopathlen >= CF_BUFSIZE) { Log(LOG_LEVEL_ERR, "Internal limit, buffer ran out of space for long filename"); return false; } return true; } /*********************************************************************/ bool ArchiveToRepository(const char *file, const Attributes *attr) /* Returns true if the file was backup up and false if not */ { char destination[CF_BUFSIZE]; struct stat sb, dsb; // Skip empty file name if (file[0] == '\0') { return false; } if (!GetRepositoryPath(file, attr, destination)) { return false; } if (attr->copy.backup == BACKUP_OPTION_NO_BACKUP) { return true; } if (IsItemIn(VREPOSLIST, file)) { Log(LOG_LEVEL_INFO, "The file '%s' has already been moved to the repository once. Multiple update will cause loss of backup.", file); return true; } ThreadLock(cft_getaddr); PrependItemList(&VREPOSLIST, file); ThreadUnlock(cft_getaddr); if (!PathAppend(destination, sizeof(destination), CanonifyName(file), FILE_SEPARATOR)) { Log(LOG_LEVEL_ERR, "Internal limit reached in ArchiveToRepository()," " path too long: '%s' + '%s'", destination, CanonifyName(file)); return false; } if (!MakeParentDirectory(destination, attr->move_obstructions, NULL)) { // Could not create parent directory, assume this is okay, // verbose logging in MakeParentDirectory() Log(LOG_LEVEL_DEBUG, "Could not create parent directory '%s'", destination); } if (stat(file, &sb) == -1) { Log(LOG_LEVEL_DEBUG, "File '%s' promised to archive to the repository but it disappeared!", file); return true; } stat(destination, &dsb); if (CopyRegularFileDisk(file, destination)) { Log(LOG_LEVEL_INFO, "Moved '%s' to repository location '%s'", file, destination); return true; } else { Log(LOG_LEVEL_INFO, "Failed to move '%s' to repository location '%s'", file, destination); return false; } } bool FileInRepository(const char *filename) { return IsItemIn(VREPOSLIST, filename); } cfengine-3.24.2/libpromises/mod_report.h0000644000000000000000000000225015010704253020225 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_REPORT_H #define CFENGINE_MOD_REPORT_H #include extern const PromiseTypeSyntax CF_REPORT_PROMISE_TYPES[]; extern const ConstraintSyntax CF_REPORT_BODIES[]; #endif cfengine-3.24.2/libpromises/mod_common.c0000644000000000000000000012511115010704253020177 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* This is a root node in the syntax tree */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CF_LOGRANGE "stdout|udp_syslog|(\042?[a-zA-Z]:\\\\.*)|(/.*)" #define CF_FACILITY "LOG_USER,LOG_DAEMON,LOG_LOCAL0,LOG_LOCAL1,LOG_LOCAL2,LOG_LOCAL3,LOG_LOCAL4,LOG_LOCAL5,LOG_LOCAL6,LOG_LOCAL7" static const char *const POLICY_ERROR_VARS_CONSTRAINT_DUPLICATE_TYPE = "Variable contains existing data type contstraint %s, tried to " "redefine with %s"; static const char *const POLICY_ERROR_VARS_PROMISER_NUMERICAL = "Variable promises cannot have a purely numerical name (promiser)"; static const char *const POLICY_ERROR_VARS_PROMISER_INVALID = "Variable promise is using an invalid name (promiser)"; static const char *const POLICY_ERROR_CLASSES_PROMISER_NUMERICAL = "Classes promises cannot have a purely numerical name (promiser)"; static bool ActionCheck(const Body *body, Seq *errors) { bool success = true; if (BodyHasConstraint(body, "log_kept") || BodyHasConstraint(body, "log_repaired") || BodyHasConstraint(body, "log_failed")) { if (!BodyHasConstraint(body, "log_string")) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, body, "An action body with log_kept, log_repaired or log_failed is required to have a log_string attribute")); success = false; } } return success; } static const ConstraintSyntax action_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("action_policy", "fix,warn,nop", "Whether to repair or report about non-kept promises", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("ifelapsed", CF_VALRANGE, "Number of minutes before next allowed assessment of promise. Default value: control body value", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("expireafter", CF_VALRANGE, "Number of minutes before a repair action is interrupted and retried. Default value: control body value", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("log_string", "", "A message to be written to the log when a promise verification leads to a repair", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("log_level", "inform,verbose,error,log", "The reporting level sent to syslog", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("log_kept", CF_LOGRANGE,"This should be filename of a file to which log_string will be saved, if undefined it goes to the system logger", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("log_priority", "emergency,alert,critical,error,warning,notice,info,debug","The priority level of the log message, as interpreted by a syslog server", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("log_repaired", CF_LOGRANGE,"This should be filename of a file to which log_string will be saved, if undefined it goes to the system logger", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("log_failed", CF_LOGRANGE,"This should be filename of a file to which log_string will be saved, if undefined it goes to the system logger", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewReal("value_kept", CF_REALRANGE, "A real number value attributed to keeping this promise", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewReal("value_repaired", CF_REALRANGE, "A real number value attributed to reparing this promise", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewReal("value_notkept", CF_REALRANGE, "A real number value (possibly negative) attributed to not keeping this promise", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewBool("audit", "true/false switch for detailed audit records of this promise. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("background", "true/false switch for parallelizing the promise repair. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("report_level", "inform,verbose,error,log", "The reporting level for standard output for this promise. Default value: none", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("measurement_class", "", "If set performance will be measured and recorded under this identifier", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax action_body = BodySyntaxNew("action", action_constraints, ActionCheck, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax classes_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("scope", "namespace,bundle", "Scope of the contexts set by this body", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("promise_repaired", CF_IDRANGE, "A list of classes to be defined globally", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("repair_failed", CF_IDRANGE, "A list of classes to be defined globally", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("repair_denied", CF_IDRANGE, "A list of classes to be defined globally", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("repair_timeout", CF_IDRANGE, "A list of classes to be defined globally", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("promise_kept", CF_IDRANGE, "A list of classes to be defined globally", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("cancel_kept", CF_IDRANGE, "A list of classes to be cancelled if the promise is kept", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("cancel_repaired", CF_IDRANGE, "A list of classes to be cancelled if the promise is repaired", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("cancel_notkept", CF_IDRANGE, "A list of classes to be cancelled if the promise is not kept for any reason", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("kept_returncodes", CF_INTLISTRANGE, "A list of return codes indicating a kept command-related promise", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("repaired_returncodes", CF_INTLISTRANGE,"A list of return codes indicating a repaired command-related promise", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("failed_returncodes", CF_INTLISTRANGE, "A list of return codes indicating a failed command-related promise", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("persist_time", CF_VALRANGE, "A number of minutes the specified classes should remain active", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("timer_policy", "absolute,reset", "Whether a persistent class restarts its counter when rediscovered. Default value: reset", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax classes_body = BodySyntaxNew("classes", classes_constraints, NULL, SYNTAX_STATUS_NORMAL); const ConstraintSyntax CF_VARBODY[] = { ConstraintSyntaxNewString("string", "", "A scalar string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("int", CF_INTRANGE, "A scalar integer", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewReal("real", CF_REALRANGE, "A scalar real number", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("slist", "", "A list of scalar strings", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntList("ilist", "A list of integers", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewRealList("rlist", "A list of real numbers", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContainer("data", "A data container", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("policy", "free,overridable,constant,ifdefined", "The policy for (dis)allowing (re)definition of variables", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static bool CheckIdentifierNotPurelyNumerical(const char *identifier) { if (*identifier == '\0') { return true; } for (const char *check = identifier; *check != '\0' && check - identifier < CF_BUFSIZE; check++) { if (!isdigit(*check)) { return true; } } return false; } static bool VarsParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; if (!CheckIdentifierNotPurelyNumerical(pp->promiser)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_VARS_PROMISER_NUMERICAL)); success = false; } if (!CheckParseVariableName(pp->promiser)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_VARS_PROMISER_INVALID)); success = false; } // ensure variables are declared with only one type. { char *data_type = NULL; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (DataTypeFromString(cp->lval) != CF_DATA_TYPE_NONE) { if (data_type != NULL) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp, POLICY_ERROR_VARS_CONSTRAINT_DUPLICATE_TYPE, data_type, cp->lval)); success = false; } data_type = cp->lval; } } } return success; } const ConstraintSyntax CF_METABODY[] = { ConstraintSyntaxNewString("string", "", "A scalar string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("slist", "", "A list of scalar strings", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContainer("data", "A data container", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CF_DEFAULTSBODY[] = { ConstraintSyntaxNewString("if_match_regex", "", "If this regular expression matches the current value of the variable, replace it with default", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("string", "", "A scalar string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("slist", "", "A list of scalar strings", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CF_CLASSBODY[] = { ConstraintSyntaxNewOption("scope", "namespace,bundle", "Scope of the class set by this promise", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContextList("and", "Combine class sources with AND", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewRealList("dist", "Generate a probabilistic class distribution (from strategies in cfengine 2)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContext("expression", "Evaluate string expression of classes in normal form", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContextList("or", "Combine class sources with inclusive OR", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("persistence", CF_VALRANGE, "Make the class persistent (cached) to avoid reevaluation, time in minutes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContext("not", "Evaluate the negation of string expression in normal form", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContextList("select_class", "Select one of the named list of classes to define based on host identity. Default value: random_selection", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContextList("xor", "Combine class sources with XOR", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static bool ClassesParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; if (!CheckIdentifierNotPurelyNumerical(pp->promiser)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_CLASSES_PROMISER_NUMERICAL)); success = false; } return success; } const ConstraintSyntax CFG_CONTROLBODY[COMMON_CONTROL_MAX + 1] = { ConstraintSyntaxNewStringList("bundlesequence", ".*", "List of promise bundles to verify in order", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("goal_patterns", "", "A list of regular expressions that match promisees/topics considered to be organizational goals", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("ignore_missing_bundles", "If any bundles in the bundlesequence do not exist, ignore and continue. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("ignore_missing_inputs", "If any input files do not exist, ignore and continue. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("inputs", ".*", "List of additional filenames to parse for promises", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("version", "", "Scalar version string for this configuration", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("lastseenexpireafter", CF_VALRANGE, "Number of minutes after which last-seen entries are purged. Default value: one week", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("output_prefix", "", "The string prefix for standard output", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("domain", ".*", "Specify the domain name for this host", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("require_comments", "Warn about promises that do not have comment documentation. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("host_licenses_paid", CF_VALRANGE, "This promise is deprecated since CFEngine version 3.1 and is ignored. Default value: 25", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewContextList("site_classes", "A list of classes that will represent geographical site locations for hosts. These should be defined elsewhere in the configuration in a classes promise.", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("syslog_host", CF_IPRANGE, "The name or address of a host to which syslog messages should be sent directly by UDP. Default value: localhost", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("syslog_port", CF_VALRANGE, "The port number of a UDP syslog service. Default value: 514", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("system_log_level", "(critical|error|warning|notice|info)", "Minimum system log level of messages that should be logged to system log", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("fips_mode", "Activate full FIPS mode restrictions. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewReal("bwlimit", CF_VALRANGE, "Limit outgoing protocol bandwidth in Bytes per second", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("cache_system_functions", "Cache the result of system functions. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("protocol_version", "1,classic,2,tls,3,cookie,latest", "CFEngine protocol version to use when connecting to the server. Default: \"latest\"", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("tls_ciphers", "", "List of acceptable ciphers in outgoing TLS connections, defaults to OpenSSL's default. For syntax help see man page for \"openssl ciphers\"", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("tls_min_version", "", "Minimum acceptable TLS version for outgoing connections, defaults to OpenSSL's default", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("package_inventory", ".*", "Name of the package manager used for software inventory management", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_module", ".*", "Name of the default package manager", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CFA_CONTROLBODY[] = { ConstraintSyntaxNewStringList("abortclasses", ".*", "A list of classes which if defined in an agent bundle lead to termination of cf-agent", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("abortbundleclasses", ".*", "A list of classes which if defined lead to termination of current bundle", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("addclasses", ".*", "A list of classes to be defined always in the current context", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("agentaccess", ".*", "A list of user names allowed to execute cf-agent", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("agentfacility", CF_FACILITY, "The syslog facility for cf-agent. Default value: LOG_USER", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("allclassesreport", "Generate allclasses.txt report", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("alwaysvalidate", "true/false flag to determine whether configurations will always be checked before executing, or only after updates", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("auditing", "This option is deprecated, does nothing and is kept for backward compatibility. Default value: false", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("binarypaddingchar", "", "Character used to pad unequal replacements in binary editing. Default value: space (ASC=32)", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("bindtointerface", ".*", "Use this interface for outgoing connections", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("hashupdates", "true/false whether stored hashes are updated when change is detected in source. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("childlibpath", ".*", "LD_LIBRARY_PATH for child processes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("checksum_alert_time", "0,60", "The persistence time for the checksum_alert class. Default value: 10 mins", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("defaultcopytype", "mtime,atime,ctime,digest,hash,binary", "ctime or mtime differ", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("dryrun", "All talk and no action mode. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("editbinaryfilesize", CF_VALRANGE, "Integer limit on maximum binary file size to be edited. Default value: 100000", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("editfilesize", CF_VALRANGE, "Integer limit on maximum text file size to be edited. Default value: 100000", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("environment", "[A-Za-z0-9_]+=.*", "List of environment variables to be inherited by children", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("exclamation", "true/false print exclamation marks during security warnings. Default value: true", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewInt("expireafter", CF_VALRANGE, "Global default for time before on-going promise repairs are interrupted. Default value: 1 min", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("files_single_copy", "", "List of filenames to be watched for multiple-source conflicts", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("files_auto_define", "", "List of filenames to define classes if copied", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("hostnamekeys", "true/false label ppkeys by hostname not IP address. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("ifelapsed", CF_VALRANGE, "Global default for time that must elapse before promise will be rechecked. Default value: 1", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("inform", "true/false set inform level default. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("intermittency", "This option is deprecated, does nothing and is kept for backward compatibility. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("max_children", CF_VALRANGE, "Maximum number of background tasks that should be allowed concurrently. Default value: 1 concurrent agent promise", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("maxconnections", CF_VALRANGE, "Maximum number of outgoing connections to cf-serverd. Default value: 30 remote queries", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("mountfilesystems", "true/false mount any filesystems promised. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("nonalphanumfiles", "true/false warn about filenames with no alphanumeric content. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("repchar", ".", "The character used to canonize pathnames in the file repository. Default value: _", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("refresh_processes", CF_IDRANGE, "Reload the process table before verifying the bundles named in this list (lazy evaluation)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("default_repository", CF_ABSPATHRANGE, "Path to the default file repository. Default value: in situ", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("secureinput", "true/false check whether input files are writable by unauthorized users. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("sensiblecount", CF_VALRANGE, "Minimum number of files a mounted filesystem is expected to have. Default value: 2 files", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("sensiblesize", CF_VALRANGE, "Minimum number of bytes a mounted filesystem is expected to have. Default value: 1000 bytes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("skipidentify", "Do not send IP/name during server connection because address resolution is broken. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("suspiciousnames", "", "List of names to skip and warn about if found during any file search", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("syslog", "true/false switches on output to syslog at the inform level. Default value: false", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewBool("track_value", "true/false switches on tracking of promise valuation. Default value: false", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("timezone", "", "List of allowed timezones this machine must comply with", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("default_timeout", CF_VALRANGE, "Maximum time a network connection should attempt to connect. Default value: 10 seconds", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("verbose", "true/false switches on verbose standard output. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("report_class_log", "true/false enables logging classes at the end of agent execution. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("select_end_match_eof", "Set the default behavior of select_end_match_eof in edit_line promises. Default: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("copyfrom_restrict_keys", ".*", "A list of key hashes to restrict copy_from to", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CFS_CONTROLBODY[SERVER_CONTROL_MAX + 1] = { ConstraintSyntaxNewStringList("allowallconnects", "","List of IPs or hostnames that may have more than one connection to the server port", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("allowconnects", "", "List of IPs or hostnames that may connect to the server port", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("allowusers", "", "List of usernames who may execute requests from this server", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("auditing", "true/false activate auditing of server connections. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("bindtointerface", "", "IP of the interface to which the server should bind on multi-homed hosts", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("cfruncommand", CF_PATHRANGE, "Path to the cf-agent command or cf-execd wrapper for remote execution", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("call_collect_interval", CF_VALRANGE, "The interval in minutes in between collect calls to the policy hub offering a tunnel for report collection (Enterprise)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("collect_window", CF_VALRANGE, "A time in seconds that a collect-call tunnel remains open to a hub to attempt a report transfer before it is closed (Enterprise)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("denybadclocks", "true/false accept connections from hosts with clocks that are out of sync. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("denyconnects", "", "List of IPs or hostnames that may NOT connect to the server port", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("dynamicaddresses", "", "List of IPs or hostnames for which the IP/name binding is expected to change", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("hostnamekeys", "true/false store keys using hostname lookup instead of IP addresses. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("keycacheTTL", CF_VALRANGE, "Maximum number of hours to hold public keys in the cache. Default value: 24", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewBool("logallconnections", "true/false causes the server to log all new connections to syslog. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("logencryptedtransfers", "true/false log all successful transfers required to be encrypted. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("maxconnections", CF_VALRANGE, "Maximum number of connections that will be accepted by cf-serverd. Default value: 30 remote queries", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("port", "1,65535", "Default port for cfengine server. Default value: 5308", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("serverfacility", CF_FACILITY, "Menu option for syslog facility level. Default value: LOG_USER", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("skipverify", "", "This option is deprecated, does nothing and is kept for backward compatibility.", SYNTAX_STATUS_DEPRECATED), ConstraintSyntaxNewStringList("trustkeysfrom", "", "List of IPs from whom we accept public keys on trust", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("listen", "true/false enable server daemon to listen on defined port. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("allowciphers", "", "List of ciphers the server accepts. For Syntax help see man page for \"openssl ciphers\". Default is \"AES256-GCM-SHA384:AES256-SHA\"", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("allowlegacyconnects", "", "List of IPs from whom we accept legacy protocol connections", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("allowtlsversion", "", "Minimum TLS version allowed for incoming connections", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CFM_CONTROLBODY[] = { ConstraintSyntaxNewReal("forgetrate", "0,1", "Decimal fraction [0,1] weighting of new values over old in 2d-average computation. Default value: 0.6", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("monitorfacility", CF_FACILITY, "Menu option for syslog facility. Default value: LOG_USER", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("histograms", "Ignored, kept for backward compatibility. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("tcpdump", "true/false use tcpdump if found. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("tcpdumpcommand", CF_ABSPATHRANGE, "Path to the tcpdump command on this system", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CFR_CONTROLBODY[] = { ConstraintSyntaxNewStringList("hosts", "", "List of host or IP addresses to attempt connection with", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("port", "1,65535", "Default port for cfengine server. Default value: 5308", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("force_ipv4", "true/false force use of ipv4 in connection. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("trustkey", "true/false automatically accept all keys on trust from servers. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("encrypt", "true/false encrypt connections with servers. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("background_children", "true/false parallelize connections to servers. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("max_children", CF_VALRANGE, "Maximum number of simultaneous connections to attempt. Default value: 50 runagents", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("output_to_file", "true/false whether to send collected output to file(s). Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("output_directory", CF_ABSPATHRANGE, "Directory where the output is stored", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("timeout", "1,9999", "Connection timeout, sec", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CFEX_CONTROLBODY[] = /* enum cfexcontrol */ { ConstraintSyntaxNewInt("splaytime", CF_VALRANGE, "Time in minutes to splay this host based on its name hash. Default value: 0", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("mailfrom", ".*@.*", "Email-address cfengine mail appears to come from", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("mailto", ".*@.*", "Email-address cfengine mail is sent to", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("mailsubject", "", "Define a custom mailsubject for the email message", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("smtpserver", ".*", "Name or IP of a willing smtp server for sending email", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("mailmaxlines", "0,1000", "Maximum number of lines of output to send by email. Default value: 30", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("mailfilter_include", "", "Which lines from the cf-agent output will be included in emails (regular expression)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("mailfilter_exclude", "", "Which lines from the cf-agent output will be excluded in emails (regular expression)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("schedule", "", "The class schedule used by cf-execd for activating cf-agent", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("executorfacility", CF_FACILITY, "Menu option for syslog facility level. Default value: LOG_USER", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("exec_command", CF_ABSPATHRANGE,"The full path and command to the executable run by default (overriding builtin)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("agent_expireafter", "0,10080", "Maximum agent runtime (in minutes). Default value: 120", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("runagent_socket_allow_users", "", "Users allowed to work with the runagent.socket to trigger agent runs", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; // Must be in sync with enum HubControl const ConstraintSyntax CFH_CONTROLBODY[] = { ConstraintSyntaxNewString("export_zenoss", CF_PATHRANGE, "Generate report for Zenoss integration", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("exclude_hosts", "", "A list of IP addresses of hosts to exclude from report collection", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("hub_schedule", "", "The class schedule used by cf-hub for report collation", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("query_timeout", "0,300", "Timeout (s) for connecting to host when querying. Default value: 30 (s)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("port", "1,65535", "Default port for contacting hub nodes. Default value: 5308", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("client_history_timeout", "1,65535", "Threshold in hours over which if client did not report, hub will start query for full state of the host and discard all accumulated report history on the client. Default value: 6 hours", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax file_control_constraints[] = /* enum cfh_control */ { ConstraintSyntaxNewString("namespace", "[a-zA-Z_][a-zA-Z0-9_]*", "Switch to a private namespace to protect current file from duplicate definitions", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("inputs", ".*", "List of additional filenames to parse for promises", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CFRE_CONTROLBODY[] = /* enum cfrecontrol */ { ConstraintSyntaxNewString("aggregation_point", CF_ABSPATHRANGE, "The root directory of the data cache for CMDB aggregation", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("auto_scaling", CF_BOOL, "true/false whether to auto-scale graph output to optimize use of space. Default value: true", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("build_directory", ".*", "The directory in which to generate output files", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("csv2xml", "", "A list of csv formatted files in the build directory to convert to simple xml", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("error_bars", CF_BOOL, "true/false whether to generate error bars on graph output", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("html_banner", "", "HTML code for a banner to be added to rendered in html after the header", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("html_embed", CF_BOOL, "If true, no header and footer tags will be added to html output", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("html_footer", "", "HTML code for a page footer to be added to rendered in html before the end body tag", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("query_engine", "", "Name of a dynamic web-page used to accept and drive queries in a browser", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOptionList("reports", "all,audit,performance,all_locks,active_locks,hashes,classes,last_seen,monitor_now,monitor_history,monitor_summary,compliance,setuid,file_changes,installed_software,software_patches,value,variables", "A list of reports that may be generated", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("report_output", "csv,html,text,xml", "Menu option for generated output format. Applies only to text reports, graph data remain in xydy format.", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("style_sheet", "", "Name of a style-sheet to be used in rendering html output (added to headers)", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("time_stamps", CF_BOOL, "true/false whether to generate timestamps in the output directory name", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; const ConstraintSyntax CFK_CONTROLBODY[] = { ConstraintSyntaxNewString("build_directory", ".*", "The directory in which to generate output files", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("document_root", ".*", "The directory in which the web root resides", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("generate_manual", CF_BOOL, "true/false generate texinfo manual page skeleton for this version", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("graph_directory", CF_ABSPATHRANGE, "Path to directory where rendered .png files will be created", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("graph_output", CF_BOOL, "true/false generate png visualization of topic map if possible (requires lib)", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("html_banner", "", "HTML code for a banner to be added to rendered in html after the header", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("html_footer", "", "HTML code for a page footer to be added to rendered in html before the end body tag", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("id_prefix", ".*", "The LTM identifier prefix used to label topic maps (used for disambiguation in merging)", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("manual_source_directory", CF_ABSPATHRANGE, "Path to directory where raw text about manual topics is found (defaults to build_directory)", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("query_engine", "", "Name of a dynamic web-page used to accept and drive queries in a browser", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("query_output", "html,text", "Menu option for generated output format", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("sql_type", "mysql,postgres", "Menu option for supported database type", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("sql_database", "", "Name of database used for the topic map", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("sql_owner", "", "User id of sql database user", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("sql_passwd", "", "Embedded password for accessing sql database", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("sql_server", "", "Name or IP of database server (or localhost)", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("sql_connection_db", "", "The name of an existing database to connect to in order to create/manage other databases", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("style_sheet", "", "Name of a style-sheet to be used in rendering html output (added to headers)", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("view_projections", CF_BOOL, "Perform view-projection analytics in graph generation", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; /* This list is for checking free standing body lval => rval bindings */ const BodySyntax CONTROL_BODIES[] = { BodySyntaxNew(CF_COMMONC, CFG_CONTROLBODY, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew(CF_AGENTC, CFA_CONTROLBODY, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew(CF_SERVERC, CFS_CONTROLBODY, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew(CF_MONITORC, CFM_CONTROLBODY, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew(CF_RUNC, CFR_CONTROLBODY, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew(CF_EXECC, CFEX_CONTROLBODY, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew(CF_HUBC, CFH_CONTROLBODY, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew("file", file_control_constraints, NULL, SYNTAX_STATUS_NORMAL), BodySyntaxNew("reporter", CFRE_CONTROLBODY, NULL, SYNTAX_STATUS_REMOVED), BodySyntaxNew("knowledge", CFK_CONTROLBODY, NULL, SYNTAX_STATUS_REMOVED), // get others from modules e.g. "agent","files",CF_FILES_BODIES, BodySyntaxNewNull() }; /*********************************************************/ /* */ /* Constraint values/types */ /* */ /*********************************************************/ /* This is where we place lval => rval bindings that apply to more than one promise_type, e.g. generic processing behavioural details */ const ConstraintSyntax CF_COMMON_BODIES[] = { ConstraintSyntaxNewBody("action", &action_body, "Output behaviour", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("classes", &classes_body, "Signalling behaviour", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("comment", "", "A comment about this promise's real intention that follows through the program", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("depends_on", "","A list of promise handles that this promise builds on or depends on somehow (for knowledge management)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("handle", "", "A unique id-tag string for referring to this as a promisee elsewhere", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("ifvarclass", "", "Extended classes ANDed with context (alias for 'if')", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("if", "", "Extended classes ANDed with context", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("unless", "", "Negated 'if'", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("meta", "", "User-data associated with policy, e.g. key=value strings", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("with", "", "A string that will replace every instance of $(with)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; /* This is where we place promise promise_types that apply to more than one type of bundle, e.g. agent,server.. */ const PromiseTypeSyntax CF_COMMON_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("*", "classes", CF_CLASSBODY, &ClassesParseTreeCheck, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("*", "defaults", CF_DEFAULTSBODY, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("*", "meta", CF_METABODY, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("*", "reports", CF_REPORT_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("*", "vars", CF_VARBODY, &VarsParseTreeCheck, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("*", "*", CF_COMMON_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; /*********************************************************/ /* THIS IS WHERE TO ATTACH SYNTAX MODULES */ /*********************************************************/ /* Read in all parsable Bundle definitions */ /* REMEMBER TO REGISTER THESE IN cf3.extern.h */ const PromiseTypeSyntax *const CF_ALL_PROMISE_TYPES[] = { CF_COMMON_PROMISE_TYPES, /* Add modules after this, mod_report.c is here */ CF_EXEC_PROMISE_TYPES, /* mod_exec.c */ CF_DATABASES_PROMISE_TYPES, /* mod_databases.c */ CF_ENVIRONMENT_PROMISE_TYPES, /* mod_environ.c */ CF_FILES_PROMISE_TYPES, /* mod_files.c */ CF_METHOD_PROMISE_TYPES, /* mod_methods.c */ CF_OUTPUTS_PROMISE_TYPES, /* mod_outputs.c */ CF_PACKAGES_PROMISE_TYPES, /* mod_packages.c */ CF_PROCESS_PROMISE_TYPES, /* mod_process.c */ CF_SERVICES_PROMISE_TYPES, /* mod_services.c */ CF_STORAGE_PROMISE_TYPES, /* mod_storage.c */ CF_REMACCESS_PROMISE_TYPES, /* mod_access.c */ CF_MEASUREMENT_PROMISE_TYPES, /* mod_measurement.c */ CF_KNOWLEDGE_PROMISE_TYPES, /* mod_knowledge.c */ CF_USERS_PROMISE_TYPES, /* mod_users.c */ }; const int CF3_MODULES = (sizeof(CF_ALL_PROMISE_TYPES) / sizeof(CF_ALL_PROMISE_TYPES[0])); CommonControl CommonControlFromString(const char *lval) { int i = 0; for (const ConstraintSyntax *s = CFG_CONTROLBODY; s->lval; s++, i++) { if (strcmp(lval, s->lval) == 0) { return (CommonControl)i; } } return COMMON_CONTROL_MAX; } cfengine-3.24.2/libpromises/mod_storage.h0000644000000000000000000000217115010704253020360 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_STORAGE_H #define CFENGINE_MOD_STORAGE_H #include extern const PromiseTypeSyntax CF_STORAGE_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/mod_users.c0000644000000000000000000000543215010704253020053 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax password_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("format", "plaintext,hash", "The format of the given password, either plaintext or hash", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("data", "", "Password", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax password_body = BodySyntaxNew("password", password_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax users_constraints[] = { ConstraintSyntaxNewOption("policy", "present,absent,locked", "The promised state of a given user", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("uid", CF_INTRANGE, "User id", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("password", &password_body, "User password", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("description", "", "User comment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("group_primary", "", "User primary group", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("groups_secondary", ".*", "User additional groups", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("home_dir", CF_ABSPATHRANGE, "User home directory", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBundle("home_bundle", "Specify the name of a bundle to run when creating a user", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("home_bundle_inherit", "If true this causes the home_bundle to inherit the private classes of its parent", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("shell", CF_ABSPATHRANGE, "User shell", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_USERS_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "users", users_constraints, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/audit.h0000644000000000000000000000301715010704253017163 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_AUDIT_H #define CFENGINE_AUDIT_H /* * This module keeps track of amount and value of promises kept/repaired/not-kept */ #include #include #include void BeginAudit(void); void UpdatePromiseCounters(PromiseResult status); void EndAudit(const EvalContext *ctx, int background_tasks); /* * FatalError causes EndAudit, so don't call it from the low-memory or corrupted stack situations. */ void FatalError(const EvalContext *ctx, char *s, ...) FUNC_ATTR_NORETURN FUNC_ATTR_PRINTF(2, 3); #endif cfengine-3.24.2/libpromises/mod_packages.c0000644000000000000000000002166115010704253020472 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax package_method_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString("package_add_command", CF_PATHRANGE, "Command to install a package to the system", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_arch_regex", "", "Regular expression with one backreference to extract package architecture string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("package_changes", "individual,bulk", "Menu option - whether to group packages into a single aggregate command", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_delete_command", CF_PATHRANGE, "Command to remove a package from the system", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_delete_convention", "", "This is how the package manager expects the package to be referred to in the deletion part of a package update, e.g. $(name)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("package_file_repositories", "", "A list of machine-local directories to search for packages", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_installed_regex", "", "Regular expression which matches packages that are already installed", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_default_arch_command", CF_ABSPATHRANGE, "Command to detect the default packages' architecture", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_list_arch_regex", "", "Regular expression with one backreference to extract package architecture string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_list_command", CF_PATHRANGE, "Command to obtain a list of available packages", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_list_name_regex", "", "Regular expression with one backreference to extract package name string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_list_update_command", "", "Command to update the list of available packages (if any)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("package_list_update_ifelapsed", CF_INTRANGE, "The ifelapsed locking time in between updates of the package list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_list_version_regex", "", "Regular expression with one backreference to extract package version string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_name_convention", "", "This is how the package manager expects the package to be referred to, e.g. $(name).$(arch)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_name_regex", "", "Regular expression with one backreference to extract package name string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_noverify_regex", "", "Regular expression to match verification failure output", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("package_noverify_returncode", CF_INTRANGE, "Integer return code indicating package verification failure", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_patch_arch_regex", "", "Regular expression with one backreference to extract update architecture string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_patch_command", CF_PATHRANGE, "Command to update to the latest patch release of an installed package", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_patch_installed_regex", "", "Regular expression which matches packages that are already installed", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_patch_list_command", CF_PATHRANGE, "Command to obtain a list of available patches or updates", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_patch_name_regex", "", "Regular expression with one backreference to extract update name string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_patch_version_regex", "", "Regular expression with one backreference to extract update version string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_update_command", CF_PATHRANGE, "Command to update to the latest version a currently installed package", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_verify_command", CF_PATHRANGE, "Command to verify the correctness of an installed package", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_version_regex", "", "Regular expression with one backreference to extract package version string", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_multiline_start", "", "Regular expression which matches the start of a new package in multiline output", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("package_commands_useshell", "Whether to use shell for commands in this body. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_version_less_command", CF_PATHRANGE, "Command to check whether first supplied package version is less than second one", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_version_equal_command", CF_PATHRANGE, "Command to check whether first supplied package version is equal to second one", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax package_method_body = BodySyntaxNew("package_method", package_method_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax package_module_constraints[] = { ConstraintSyntaxNewInt("query_installed_ifelapsed", CF_INTRANGE, "The ifelapsed locking time in between updates of the installed package list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("query_updates_ifelapsed", CF_INTRANGE, "The ifelapsed locking time in between updates of the available updates list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("default_options", "", "Default options passed to package manager wrapper", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("interpreter", "", "Path to the interpreter to run the package manager wrapper with", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("module_path", "", "Non-standard path to the package manager wrapper", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax package_module_body = BodySyntaxNew("package_module", package_module_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax packages_constraints[] = { ConstraintSyntaxNewStringList("package_architectures", "", "Select the architecture for package selection", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("package_method", &package_method_body, "Criteria for installation and verification", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("package_policy", "add,delete,reinstall,update,addupdate,patch,verify", "Criteria for package installation/upgrade on the current system. Default value: verify", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("package_select", ">,<,==,!=,>=,<=", "A criterion for first acceptable match relative to \"package_version\"", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("package_version", "", "Version reference point for determining promised version", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("policy", "absent,present", "Criteria for package installation/upgrade on the current system", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("package_module", &package_module_body, "Package manager used for package related operations", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("version", "", "Version reference point for determining promised version", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("architecture", "", "Architecture type of package", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("options", "", "Additional options passed to package manager", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("additional_packages", "", "Additional packages processed with given package promiser", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_PACKAGES_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "packages", packages_constraints, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/mod_access.c0000644000000000000000000002022215010704253020145 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* This file can act as a template for adding functionality to cfengine 3. All functionality can be added by extending the main array CF_MOD_PROMISE_TYPES[CF3_MODULES] and its array dimension, in mod_common, in the manner shown here. */ #include #include #include #include /* Read this module file backwards, as dependencies have to be defined first - these arrays declare pairs of constraints lval => rval in the form (lval,type,range) If the type is cf_body then the range is a pointer to another array of pairs, like in a body "sub-routine" */ static const char *const POLICY_ERROR_WRONG_RESOURCE_FOR_DATA_SELECT = "Constraint report_data_select is allowed only for 'query' resource_type"; static bool AccessParseTreeCheck(const Promise *pp, Seq *errors); static const ConstraintSyntax report_data_select_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("classes_include", CF_ANYSTRING, "List of regex filters for class names to be included into class report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("classes_exclude", CF_ANYSTRING, "List of regex filters for class names to be excluded from class report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("variables_include", CF_ANYSTRING, "List of regex filters for variable full qualified path to be included into variables report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("variables_exclude", CF_ANYSTRING, "List of regex filters for variable full qualified path to be excluded from variables report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("promise_notkept_log_include", CF_ANYSTRING, "List of regex filters for handle name to be included into promise not kept log report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("promise_notkept_log_exclude", CF_ANYSTRING, "List of regex filters for handle name to be excluded from promise not kept log report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("promise_repaired_log_include", CF_ANYSTRING, "List of regex filters for handle name to be included into promise repaired log report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("promise_repaired_log_exclude", CF_ANYSTRING, "List of regex filters for handle name to be excluded from promise repaired log report", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("monitoring_include", CF_ANYSTRING, "List of regex filters for slot name to be included from monitoring report", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("monitoring_exclude", CF_ANYSTRING, "List of regex filters for slot name to be excluded from monitoring report", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("metatags_include", CF_ANYSTRING, "List of regex filters for metatags to be included into reports", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("metatags_exclude", CF_ANYSTRING, "List of regex filters for metatags to be excluded from reports", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("promise_handle_include", CF_ANYSTRING, "List of regex filters for promise handle to be included into reports", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("promise_handle_exclude", CF_ANYSTRING, "List of regex filters for promise handle to be excluded from reports", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax report_data_select_body = BodySyntaxNew("report_data_select", report_data_select_constraints, NULL, SYNTAX_STATUS_NORMAL); const ConstraintSyntax CF_REMACCESS_BODIES[REMOTE_ACCESS_NONE + 1] = { ConstraintSyntaxNewStringList("admit", "", "List of host names or IP addresses to grant access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("deny", "", "List of host names or IP addresses to deny access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("admit_ips", "", "List of IP addresses or subnet masks to grant access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("deny_ips", "", "List of IP addresses or subnet masks to deny access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("admit_hostnames", "", "List of hostnames to grant access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("deny_hostnames", "", "List of hostnames to deny access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("admit_keys", "", "List of host keys that will be granted access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("deny_keys", "", "List of host keys that will be denied access to file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("maproot", "", "List of host names or IP addresses to grant full read-privilege on the server", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("ifencrypted", "true/false whether the current file access promise is conditional on the connection from the client being encrypted. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("resource_type", "path,literal,context,query,variable,bundle", "The type of object being granted access (the default is path and grants access to files)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("report_data_select", &report_data_select_body, "Report content filter", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("shortcut", "", "For path resource_type, the server will expand a relative path beginning with this text", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CF_REMROLE_BODIES[REMOTE_ROLE_NONE + 1] = { ConstraintSyntaxNewStringList("authorize", "", "List of public-key user names that are allowed to activate the promised class during remote agent activation", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_REMACCESS_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("server", "access", CF_REMACCESS_BODIES, &AccessParseTreeCheck, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("server", "roles", CF_REMROLE_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; static bool AccessParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; bool isResourceType = false; bool isReportDataSelect = false; Constraint *data_select_const = NULL; for (size_t i = 0; i conlist); i++) { Constraint *con = SeqAt(pp->conlist, i); if (StringSafeCompare("resource_type", con->lval) == 0) { if (con->rval.type == RVAL_TYPE_SCALAR) { if (StringSafeCompare("query", (char*)con->rval.item) == 0) { isResourceType = true; } } } else if (StringSafeCompare("report_data_select", con->lval) == 0) { data_select_const = con; isReportDataSelect = true; } } if (isReportDataSelect && !isResourceType) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, data_select_const, POLICY_ERROR_WRONG_RESOURCE_FOR_DATA_SELECT)); success = false; } return success; } cfengine-3.24.2/libpromises/granules.c0000644000000000000000000000433715010704253017676 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include char *GenTimeKey(time_t now) { struct tm tm; static char buf[18]; /* GLOBAL_R, no initialization needed */ gmtime_r(&now, &tm); xsnprintf(buf, sizeof(buf), "%3.3s:Hr%02d:Min%02d_%02d", DAY_TEXT[tm.tm_wday ? (tm.tm_wday - 1) : 6], tm.tm_hour, tm.tm_min / 5 * 5, ((tm.tm_min + 5) / 5 * 5) % 60); return buf; } int GetTimeSlot(time_t here_and_now) { return ((here_and_now - (4 * 24 * 60 * 60)) % SECONDS_PER_WEEK) / (long)CF_MEASURE_INTERVAL; } int GetShiftSlot(time_t t) { return UnsignedModulus((t - CF_MONDAY_MORNING), SECONDS_PER_WEEK) / CF_SHIFT_INTERVAL; } time_t GetShiftSlotStart(time_t t) { return (t - (t % SECONDS_PER_SHIFT)); } time_t MeasurementSlotStart(time_t t) { return (t - t % (time_t)CF_MEASURE_INTERVAL); } time_t MeasurementSlotTime(size_t slot, size_t num_slots, time_t now) { assert(slot <= num_slots); size_t start_slot = GetTimeSlot(now); size_t distance = 0; if (slot <= start_slot) { distance = start_slot - slot; } else { distance = start_slot + (num_slots - slot - 1); } time_t start_time = MeasurementSlotStart(now); return start_time - (distance * CF_MEASURE_INTERVAL); } cfengine-3.24.2/libpromises/expand.h0000644000000000000000000000473015010704253017337 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_EXPAND_H #define CFENGINE_EXPAND_H #include #include #include PromiseResult CommonEvalPromise(EvalContext *ctx, const Promise *pp, void *param); PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *ActOnPromise, void *param); Rval ExpandDanglers(EvalContext *ctx, const char *ns, const char *scope, Rval rval, const Promise *pp); bool IsExpandable(const char *str); char *ExpandScalar(const EvalContext *ctx, const char *ns, const char *scope, const char *string, Buffer *out); Rval ExpandBundleReference(EvalContext *ctx, const char *ns, const char *scope, Rval rval); Rval ExpandPrivateRval(const EvalContext *ctx, const char *ns, const char *scope, const void *rval_item, RvalType rval_type); Rlist *ExpandList(const EvalContext *ctx, const char *ns, const char *scope, const Rlist *list, int expandnaked); Rval EvaluateFinalRval(EvalContext *ctx, const Policy *policy, const char *ns, const char *scope, Rval rval, bool forcelist, const Promise *pp); void BundleResolve(EvalContext *ctx, const Bundle *bundle); void PolicyResolve(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config); void BundleResolvePromiseType(EvalContext *ctx, const Bundle *bundle, const char *type, PromiseActuator *actuator); bool IsNakedVar(const char *str, char vtype); void GetNaked(char *dst, const char *s); bool IsVarList(const char *var); #include // ProtocolVersionParse() TODO: Remove #endif cfengine-3.24.2/libpromises/mod_databases.h0000644000000000000000000000217715010704253020651 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_DATABASES_H #define CFENGINE_MOD_DATABASES_H #include extern const PromiseTypeSyntax CF_DATABASES_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/logic_expressions.c0000644000000000000000000001613215010704253021611 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include /* */ static ParseResult ParsePrimary(const char *expr, int start, int end) { if (start < end && expr[start] == '(') { ParseResult res = ParseExpression(expr, start + 1, end); if (res.result) { /* Check if there is a matching ')' at the end */ if (res.position < end && expr[res.position] == ')') { return (ParseResult) {res.result, res.position + 1}; } else { /* Haven't found a matching bracket. Give up */ FreeExpression(res.result); return (ParseResult) {NULL, res.position}; } } else { return res; } } else { StringParseResult strres = ParseStringExpression(expr, start, end); if (strres.result) { Expression *res = xcalloc(1, sizeof(Expression)); res->op = LOGICAL_OP_EVAL; res->val.eval.name = strres.result; return (ParseResult) {res, strres.position}; } else { return (ParseResult) {NULL, strres.position}; } } } /* */ static ParseResult ParseNotExpression(const char *expr, int start, int end) { if (start < end && expr[start] == '!') { ParseResult primres = ParsePrimary(expr, start + 1, end); if (primres.result) { Expression *res = xcalloc(1, sizeof(Expression)); res->op = LOGICAL_OP_NOT; res->val.not.arg = primres.result; return (ParseResult) {res, primres.position}; } else { return primres; } } else { return ParsePrimary(expr, start, end); } } /* */ static ParseResult ParseAndExpression(const char *expr, int start, int end) { ParseResult lhs, rhs; Expression *res; lhs = ParseNotExpression(expr, start, end); if (!lhs.result) { return lhs; } if (lhs.position == end || (expr[lhs.position] != '.' && expr[lhs.position] != '&')) { return lhs; } rhs = ParseAndExpression(expr, lhs.position + 1, end); if (!rhs.result) { FreeExpression(lhs.result); return rhs; } res = xcalloc(1, sizeof(Expression)); res->op = LOGICAL_OP_AND; res->val.andor.lhs = lhs.result; res->val.andor.rhs = rhs.result; return (ParseResult) {res, rhs.position}; } /* */ ParseResult ParseExpression(const char *expr, int start, int end) { ParseResult lhs, rhs; Expression *res; int position; lhs = ParseAndExpression(expr, start, end); if (!lhs.result) { return lhs; } /* End of left-hand side expression */ position = lhs.position; if (position == end || expr[position] != '|') { return lhs; } /* Skip second '|' in 'lhs||rhs' */ if (position + 1 < end && expr[position + 1] == '|') { position++; } rhs = ParseExpression(expr, position + 1, end); if (!rhs.result) { FreeExpression(lhs.result); return rhs; } res = xcalloc(1, sizeof(Expression)); res->op = LOGICAL_OP_OR; res->val.andor.lhs = lhs.result; res->val.andor.rhs = rhs.result; return (ParseResult) {res, rhs.position}; } /* Evaluation */ ExpressionValue EvalExpression(const Expression *expr, NameEvaluator nameevalfn, VarRefEvaluator varrefevalfn, void *param) { switch (expr->op) { case LOGICAL_OP_OR: case LOGICAL_OP_AND: { ExpressionValue lhs = EXPRESSION_VALUE_ERROR, rhs = EXPRESSION_VALUE_ERROR; lhs = EvalExpression(expr->val.andor.lhs, nameevalfn, varrefevalfn, param); if (lhs == EXPRESSION_VALUE_ERROR) { return EXPRESSION_VALUE_ERROR; } rhs = EvalExpression(expr->val.andor.rhs, nameevalfn, varrefevalfn, param); if (rhs == EXPRESSION_VALUE_ERROR) { return EXPRESSION_VALUE_ERROR; } if (expr->op == LOGICAL_OP_OR) { return ((ExpressionValue) (lhs || rhs)); } else { return ((ExpressionValue) (lhs && rhs)); } } case LOGICAL_OP_NOT: { ExpressionValue arg = EvalExpression(expr->val.not.arg, nameevalfn, varrefevalfn, param); if (arg == EXPRESSION_VALUE_ERROR) { return EXPRESSION_VALUE_ERROR; } else { return !arg; } } case LOGICAL_OP_EVAL: { ExpressionValue ret = EXPRESSION_VALUE_ERROR; char *name = EvalStringExpression(expr->val.eval.name, varrefevalfn, param); if (name == NULL) { return EXPRESSION_VALUE_ERROR; } else if (strcmp("true", name) == 0) { ret = EXPRESSION_VALUE_TRUE; } else if (strcmp("false", name) == 0) { ret = EXPRESSION_VALUE_FALSE; } else { ret = (*nameevalfn) (name, param); } free(name); return ret; } default: ProgrammingError("Unexpected class expression type is found: %d", expr->op); } } /* Freeing results */ void FreeExpression(Expression *e) { if (!e) { return; } switch (e->op) { case LOGICAL_OP_OR: case LOGICAL_OP_AND: FreeExpression(e->val.andor.lhs); FreeExpression(e->val.andor.rhs); break; case LOGICAL_OP_NOT: FreeExpression(e->val.not.arg); break; case LOGICAL_OP_EVAL: FreeStringExpression(e->val.eval.name); break; default: ProgrammingError("Unknown logic expression type encountered in" "FreeExpression: %d", e->op); } free(e); } cfengine-3.24.2/libpromises/mod_outputs.h0000644000000000000000000000217115010704253020437 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_OUTPUTS_H #define CFENGINE_MOD_OUTPUTS_H #include extern const PromiseTypeSyntax CF_OUTPUTS_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/verify_vars.c0000644000000000000000000006130615010704253020414 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include /* CompileRegex,StringMatchFullWithPrecompiledRegex */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct { bool should_converge; bool ok_redefine; bool drop_undefined; Constraint *cp_save; // e.g. string => "foo" } ConvergeVariableOptions; static ConvergeVariableOptions CollectConvergeVariableOptions(EvalContext *ctx, const Promise *pp); static bool Epimenides(EvalContext *ctx, const char *ns, const char *scope, const char *var, Rval rval, int level); static bool CompareRval(const void *rval1_item, RvalType rval1_type, const void *rval2_item, RvalType rval2_type); static bool IsLegalVariableName(EvalContext *ctx, const Promise *pp) { const char *var_name = pp->promiser; /* TODO: remove at some point (global, leaked), but for now * this offers an attractive speedup. */ static Regex *rx = NULL; if (!rx) { /* \200-\377 is there for multibyte unicode characters */ rx = CompileRegex("[a-zA-Z0-9_\200-\377.]+(\\[.+\\])*"); /* Known leak, see TODO. */ } if (!StringMatchFullWithPrecompiledRegex(rx, var_name)) { return false; } char *bracket = strchr(var_name, '['); char *dot = strchr(var_name, '.'); /* we only care about variable name prefix, not dots inside array keys */ if ((dot != NULL) && ((bracket == NULL) || (dot < bracket))) { /* detect and prevent remote bundle variable injection (CFE-1915) */ char *prefix = xstrndup(var_name, dot - var_name); const Bundle *cur_bundle = PromiseGetBundle(pp); if (!StringEqual(prefix, cur_bundle->name)) { Log(LOG_LEVEL_VERBOSE, "Variable '%s' may be attempted to be injected into a remote bundle", var_name); if (StringSetContains(EvalContextGetBundleNames(ctx), prefix)) { Log(LOG_LEVEL_ERR, "Remote bundle variable injection detected!"); free(prefix); return false; } /* the conflicting bundle may be defined later, we need to remember * this promise as potentially dangerous */ EvalContextPushRemoteVarPromise(ctx, prefix, pp->org_pp); } free(prefix); } return true; } // TODO why not printing that new definition is skipped? // TODO what with ifdefined? PromiseResult VerifyVarPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert(pp != NULL); ConvergeVariableOptions opts = CollectConvergeVariableOptions(ctx, pp); Log(LOG_LEVEL_DEBUG, "Evaluating vars promise: %s", pp->promiser); LogDebug(LOG_MOD_VARS, "ok_redefine=%d, drop_undefined=%d, should_converge=%d", opts.ok_redefine, opts.drop_undefined, opts.should_converge); if (!opts.should_converge) { LogDebug(LOG_MOD_VARS, "Skipping vars promise because should_converge=false"); return PROMISE_RESULT_NOOP; } // opts.drop_undefined = true; /* always remove @{unresolved_list} */ Attributes a = ZeroAttributes; // More consideration needs to be given to using these //a.transaction = GetTransactionConstraints(pp); /* Warn if promise locking was used with a promise that doesn't support it * (which applies to all of 'vars', 'meta' and 'defaults' promises handled * by this code). * 'ifelapsed => "0"' (e.g. with 'action => immediate') can however be used * to make sure cached functions are called every time. [ENT-7478] * (Only do this in the first pass in cf-promises, we don't have to repeat * the warning over and over.) */ if (EvalContextGetPass(ctx) == 0 && THIS_AGENT_TYPE == AGENT_TYPE_COMMON) { int ifelapsed = PromiseGetConstraintAsInt(ctx, "ifelapsed", pp); if ((ifelapsed != CF_NOINT) && ((ifelapsed != 0) || !StringEqual(PromiseGetPromiseType(pp), "vars"))) { Log(LOG_LEVEL_WARNING, "ifelapsed attribute specified in action body for %s promise '%s'," " but %s promises do not support promise locking", PromiseGetPromiseType(pp), pp->promiser, PromiseGetPromiseType(pp)); } int expireafter = PromiseGetConstraintAsInt(ctx, "expireafter", pp); if (expireafter != CF_NOINT) { Log(LOG_LEVEL_WARNING, "expireafter attribute specified in action body for %s promise '%s'," " but %s promises do not support promise locking", PromiseGetPromiseType(pp), pp->promiser, PromiseGetPromiseType(pp)); } } a.classes = GetClassDefinitionConstraints(ctx, pp); VarRef *ref = VarRefParseFromBundle(pp->promiser, PromiseGetBundle(pp)); if (strcmp("meta", PromiseGetPromiseType(pp)) == 0) { VarRefSetMeta(ref, true); } DataType existing_value_type = CF_DATA_TYPE_NONE; const void *existing_value; if (IsExpandable(pp->promiser)) { existing_value = NULL; } else { existing_value = EvalContextVariableGet(ctx, ref, &existing_value_type); } Rval rval = opts.cp_save->rval; PromiseResult result; if (rval.item != NULL || rval.type == RVAL_TYPE_LIST) { DataType data_type = DataTypeFromString(opts.cp_save->lval); if (opts.cp_save->rval.type == RVAL_TYPE_FNCALL) { FnCall *fp = RvalFnCallValue(rval); const FnCallType *fn = FnCallTypeGet(fp->name); if (!fn) { assert(false && "Canary: should have been caught before this point"); FatalError(ctx, "While setting variable '%s' in bundle '%s', unknown function '%s'", pp->promiser, PromiseGetBundle(pp)->name, fp->name); } if (fn->dtype != DataTypeFromString(opts.cp_save->lval)) { FatalError(ctx, "While setting variable '%s' in bundle '%s', variable declared type '%s' but function '%s' returns type '%s'", pp->promiser, PromiseGetBundle(pp)->name, opts.cp_save->lval, fp->name, DataTypeToString(fn->dtype)); } if (existing_value_type != CF_DATA_TYPE_NONE) { // Already did this VarRefDestroy(ref); return PROMISE_RESULT_NOOP; } FnCallResult res = FnCallEvaluate(ctx, PromiseGetPolicy(pp), fp, pp); if (res.status == FNCALL_FAILURE) { /* We do not assign variables to failed fn calls */ if (EvalContextGetPass(ctx) == CF_DONEPASSES-1) { // If we still fail at last pass, make a log Log(LOG_LEVEL_VERBOSE, "While setting variable '%s' in bundle '%s', function '%s' failed - skipping", pp->promiser, PromiseGetBundle(pp)->name, fp->name); } RvalDestroy(res.rval); VarRefDestroy(ref); return PROMISE_RESULT_NOOP; } else { rval = res.rval; } } else { Buffer *conv = BufferNew(); bool malformed = false, misprint = false; if (strcmp(opts.cp_save->lval, "int") == 0) { long int asint = IntFromString(opts.cp_save->rval.item); if (asint == CF_NOINT) { malformed = true; } else if (0 > BufferPrintf(conv, "%ld", asint)) { misprint = true; } else { rval = RvalNew(BufferData(conv), opts.cp_save->rval.type); } } else if (strcmp(opts.cp_save->lval, "real") == 0) { double real_value; if (!DoubleFromString(opts.cp_save->rval.item, &real_value)) { malformed = true; } else if (0 > BufferPrintf(conv, "%lf", real_value)) { misprint = true; } else { rval = RvalNew(BufferData(conv), opts.cp_save->rval.type); } } else { rval = RvalCopy(opts.cp_save->rval); } BufferDestroy(conv); if (malformed) { /* Arises when opts->cp_save->rval.item isn't yet expanded. */ /* Has already been logged by *FromString */ VarRefDestroy(ref); return PROMISE_RESULT_FAIL; } else if (misprint) { /* Even though no problems with memory allocation can * get here, there might be other problems. */ UnexpectedError("Problems writing to buffer"); VarRefDestroy(ref); return PROMISE_RESULT_FAIL; } else if (rval.type == RVAL_TYPE_LIST) { Rlist *rval_list = RvalRlistValue(rval); RlistFlatten(ctx, &rval_list); rval.item = rval_list; } } if (Epimenides(ctx, PromiseGetBundle(pp)->ns, PromiseGetBundle(pp)->name, pp->promiser, rval, 0)) { Log(LOG_LEVEL_ERR, "Variable '%s' contains itself indirectly - an unkeepable promise", pp->promiser); DoCleanupAndExit(EXIT_FAILURE); } else { /* See if the variable needs recursively expanding again */ Rval returnval = EvaluateFinalRval(ctx, PromiseGetPolicy(pp), ref->ns, ref->scope, rval, true, pp); RvalDestroy(rval); // freed before function exit rval = returnval; } /* If variable did resolve but we're not allowed to modify it. */ /* ok_redefine: only on second iteration, else we ignore broken promises. TODO wat? */ if (existing_value_type != CF_DATA_TYPE_NONE && !opts.ok_redefine) { if (!CompareRval(existing_value, DataTypeToRvalType(existing_value_type), rval.item, rval.type)) { switch (rval.type) { /* TODO redefinition shouldn't be mentioned. Maybe handle like normal variable definition/ */ case RVAL_TYPE_SCALAR: Log(LOG_LEVEL_VERBOSE, "V: Skipping redefinition of constant scalar '%s': from '%s' to '%s'", pp->promiser, (const char *)existing_value, RvalScalarValue(rval)); PromiseRef(LOG_LEVEL_VERBOSE, pp); break; case RVAL_TYPE_LIST: { Log(LOG_LEVEL_VERBOSE, "V: Skipping redefinition of constant list '%s'", pp->promiser); Writer *w = StringWriter(); RlistWrite(w, existing_value); char *oldstr = StringWriterClose(w); Log(LOG_LEVEL_DEBUG, "Old value: %s", oldstr); free(oldstr); w = StringWriter(); RlistWrite(w, rval.item); char *newstr = StringWriterClose(w); Log(LOG_LEVEL_DEBUG, "Skipped new value: %s", newstr); free(newstr); PromiseRef(LOG_LEVEL_VERBOSE, pp); } break; case RVAL_TYPE_CONTAINER: case RVAL_TYPE_FNCALL: case RVAL_TYPE_NOPROMISEE: break; } } RvalDestroy(rval); VarRefDestroy(ref); return PROMISE_RESULT_NOOP; } if (IsCf3VarString(pp->promiser)) { // Unexpanded variables, we don't do anything with RvalDestroy(rval); VarRefDestroy(ref); return PROMISE_RESULT_NOOP; } if (!IsLegalVariableName(ctx, pp)) { Log(LOG_LEVEL_ERR, "Variable identifier '%s' is not legal", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); RvalDestroy(rval); VarRefDestroy(ref); return PROMISE_RESULT_NOOP; } if (rval.type == RVAL_TYPE_LIST) { if (opts.drop_undefined) { Rlist *stripped = RvalRlistValue(rval); Rlist *entry = stripped; while (entry) { Rlist *delete_me = NULL; if (IsNakedVar(RlistScalarValue(entry), '@')) { delete_me = entry; } entry = entry->next; RlistDestroyEntry(&stripped, delete_me); } rval.item = stripped; } for (const Rlist *rp = RvalRlistValue(rval); rp; rp = rp->next) { if (rp->val.type != RVAL_TYPE_SCALAR) { // Cannot assign variable because value is a list containing a non-scalar item VarRefDestroy(ref); RvalDestroy(rval); return PROMISE_RESULT_NOOP; } } } if (ref->num_indices > 0) { if (data_type == CF_DATA_TYPE_CONTAINER) { char *lval_str = VarRefToString(ref, true); Log(LOG_LEVEL_ERR, "Cannot assign a container to an indexed variable name '%s'. Should be assigned to '%s' instead", lval_str, ref->lval); free(lval_str); VarRefDestroy(ref); RvalDestroy(rval); return PROMISE_RESULT_NOOP; } else { DataType existing_type; VarRef *base_ref = VarRefCopyIndexless(ref); if (EvalContextVariableGet(ctx, ref, &existing_type) && existing_type == CF_DATA_TYPE_CONTAINER) { char *lval_str = VarRefToString(ref, true); char *base_ref_str = VarRefToString(base_ref, true); Log(LOG_LEVEL_ERR, "Cannot assign value to indexed variable name '%s', because a container is already assigned to the base name '%s'", lval_str, base_ref_str); free(lval_str); free(base_ref_str); VarRefDestroy(base_ref); VarRefDestroy(ref); RvalDestroy(rval); return PROMISE_RESULT_NOOP; } VarRefDestroy(base_ref); } } DataType required_datatype = DataTypeFromString(opts.cp_save->lval); if (rval.type != DataTypeToRvalType(required_datatype)) { char *ref_str = VarRefToString(ref, true); char *value_str = RvalToString(rval); Log(LOG_LEVEL_ERR, "Variable '%s' expected a variable of type '%s', but was given incompatible value '%s'", ref_str, DataTypeToString(required_datatype), value_str); PromiseRef(LOG_LEVEL_ERR, pp); free(ref_str); free(value_str); VarRefDestroy(ref); RvalDestroy(rval); return PROMISE_RESULT_FAIL; } StringSet *tags = StringSetNew(); StringSetAdd(tags, xstrdup("source=promise")); Rlist *promise_meta = PromiseGetConstraintAsList(ctx, "meta", pp); if (promise_meta) { Buffer *print; for (const Rlist *rp = promise_meta; rp; rp = rp->next) { StringSetAdd(tags, xstrdup(RlistScalarValue(rp))); if (WouldLog(LOG_LEVEL_DEBUG)) { print = StringSetToBuffer(tags, ','); Log(LOG_LEVEL_DEBUG, "Added tag %s to variable %s tags (now [%s])", RlistScalarValue(rp), pp->promiser, BufferData(print)); BufferDestroy(print); } } } const char *comment = PromiseGetConstraintAsRval(pp, "comment", RVAL_TYPE_SCALAR); /* WRITE THE VARIABLE AT LAST. */ bool success = EvalContextVariablePutTagsSetWithComment(ctx, ref, rval.item, required_datatype, tags, comment); if (success && (comment != NULL)) { Log(LOG_LEVEL_VERBOSE, "Added variable '%s' with comment '%s'", pp->promiser, comment); } if (!success) { Log(LOG_LEVEL_VERBOSE, "Unable to converge %s.%s value (possibly empty or infinite regression)", ref->scope, pp->promiser); PromiseRef(LOG_LEVEL_VERBOSE, pp); VarRefDestroy(ref); RvalDestroy(rval); StringSetDestroy(tags); return PROMISE_RESULT_FAIL; } result = PROMISE_RESULT_NOOP; } else { Log(LOG_LEVEL_ERR, "Variable %s has no promised value", pp->promiser); Log(LOG_LEVEL_ERR, "Rule from %s at/before line %zu", PromiseGetBundle(pp)->source_path, opts.cp_save->offset.line); result = PROMISE_RESULT_FAIL; } /* * FIXME: Variable promise are exempt from normal evaluation logic still, so * they are not pushed to evaluation stack before being evaluated. Due to * this reason, we cannot call cfPS here to set classes, as it will error * out with ProgrammingError. * * In order to support 'classes' body for variables as well, we call * ClassAuditLog explicitly. */ ClassAuditLog(ctx, pp, &a, result); VarRefDestroy(ref); RvalDestroy(rval); return result; } static bool CompareRval(const void *rval1_item, RvalType rval1_type, const void *rval2_item, RvalType rval2_type) { if (rval1_type != rval2_type) { return false; } switch (rval1_type) { case RVAL_TYPE_SCALAR: if (IsCf3VarString(rval1_item) || IsCf3VarString(rval2_item)) { return false; // inconclusive } if (strcmp(rval1_item, rval2_item) != 0) { return false; } break; case RVAL_TYPE_LIST: return RlistEqual(rval1_item, rval2_item); case RVAL_TYPE_FNCALL: return false; default: return false; } return true; } static bool Epimenides(EvalContext *ctx, const char *ns, const char *scope, const char *var, Rval rval, int level) { switch (rval.type) { case RVAL_TYPE_SCALAR: if (StringContainsVar(RvalScalarValue(rval), var)) { Log(LOG_LEVEL_ERR, "Scalar variable '%s' contains itself (non-convergent) '%s'", var, RvalScalarValue(rval)); return true; } if (IsCf3VarString(RvalScalarValue(rval))) { Buffer *exp = BufferNew(); ExpandScalar(ctx, ns, scope, RvalScalarValue(rval), exp); if (strcmp(BufferData(exp), RvalScalarValue(rval)) == 0) { BufferDestroy(exp); return false; } if (level > 3) { BufferDestroy(exp); return false; } if (Epimenides(ctx, ns, scope, var, (Rval) { BufferGet(exp), RVAL_TYPE_SCALAR}, level + 1)) { BufferDestroy(exp); return true; } BufferDestroy(exp); } break; case RVAL_TYPE_LIST: for (const Rlist *rp = RvalRlistValue(rval); rp != NULL; rp = rp->next) { if (Epimenides(ctx, ns, scope, var, rp->val, level)) { return true; } } break; case RVAL_TYPE_CONTAINER: case RVAL_TYPE_FNCALL: case RVAL_TYPE_NOPROMISEE: return false; } return false; } /** * @brief Collects variable constraints controlling how the promise should be converged */ static ConvergeVariableOptions CollectConvergeVariableOptions(EvalContext *ctx, const Promise *pp) { ConvergeVariableOptions opts; opts.drop_undefined = false; opts.cp_save = NULL; /* main variable value */ /* By default allow variable redefinition, use "policy" constraint * to override. */ opts.ok_redefine = true; /* Main return value: becomes true at the end of the function. */ opts.should_converge = false; if (!IsDefinedClass(ctx, pp->classes)) { return opts; } int num_values = 0; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (strcmp(cp->lval, "comment") == 0) { // Comments don't affect convergence // Unclear why this is in the constraint list in the first place? continue; } else if (cp->rval.item == NULL && cp->rval.type != RVAL_TYPE_LIST) { // No right value, considered empty continue; } else if (strcmp(cp->lval, "ifvarclass") == 0 || strcmp(cp->lval, "if") == 0) { switch (cp->rval.type) { case RVAL_TYPE_SCALAR: if (!IsDefinedClass(ctx, cp->rval.item)) { return opts; } break; case RVAL_TYPE_FNCALL: { bool excluded = false; /* eval it: e.g. ifvarclass => not("a_class") */ Rval res = FnCallEvaluate(ctx, PromiseGetPolicy(pp), cp->rval.item, pp).rval; /* Don't continue unless function was evaluated properly */ if (res.type != RVAL_TYPE_SCALAR) { RvalDestroy(res); return opts; } excluded = !IsDefinedClass(ctx, res.item); RvalDestroy(res); if (excluded) { return opts; } } break; default: Log(LOG_LEVEL_ERR, "Invalid if/ifvarclass type '%c': should be string or function", cp->rval.type); } } else if (strcmp(cp->lval, "policy") == 0) { if (strcmp(cp->rval.item, "ifdefined") == 0) { opts.drop_undefined = true; } else if (strcmp(cp->rval.item, "constant") == 0) { opts.ok_redefine = false; } } else if (DataTypeFromString(cp->lval) != CF_DATA_TYPE_NONE) { num_values++; opts.cp_save = cp; } } if (opts.cp_save == NULL) { Log(LOG_LEVEL_WARNING, "Incomplete vars promise: %s", pp->promiser); PromiseRef(LOG_LEVEL_INFO, pp); return opts; } if (num_values > 2) { Log(LOG_LEVEL_ERR, "Variable '%s' breaks its own promise with multiple (%d) values", pp->promiser, num_values); PromiseRef(LOG_LEVEL_ERR, pp); return opts; } /* All constraints look OK, and classes are defined. Move forward with * this promise. */ opts.should_converge = true; return opts; } cfengine-3.24.2/libpromises/unix.h0000644000000000000000000000463415010704253017046 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_UNIX_H #define CFENGINE_UNIX_H #include #include void ProcessSignalTerminate(pid_t pid); bool GetCurrentUserName(char *userName, int userNameLen); #ifndef __MINGW32__ /** * Get user name for the user with UID #uid * * @param uid UID of the user * @param user_name_buf buffer to store the user name (if found) * (%NULL if only checking if a user with #uid exists) * @param buf_size size of the #user_name_buf buffer * @param error_log_level log level to store errors with (not found or an actual error) * @return whether the lookup was successful or not */ bool GetUserName(uid_t uid, char *user_name_buf, size_t buf_size, LogLevel error_log_level); bool GetGroupName(gid_t gid, char *group_name_buf, size_t buf_size, LogLevel error_log_level); /** * Get UID for the user with user name #user_name * * @param user_name user name of the user * @param[out] uid place to store the UID of user #user_name (if found) * (%NULL if only checking if a user with #user_name exists) * @param error_log_level log level to store errors with (not found or an actual error) * @return whether the lookup was successful or not */ bool GetUserID(const char *user_name, uid_t *uid, LogLevel error_log_level); bool GetGroupID(const char *group_name, gid_t *gid, LogLevel error_log_level); #endif #endif cfengine-3.24.2/libpromises/match_scope.h0000644000000000000000000000251315010704253020342 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MATCH_SCOPE_H #define CFENGINE_MATCH_SCOPE_H #include bool FullTextMatch(EvalContext *ctx, const char *regptr, const char *cmpptr); /* Sets variables */ bool BlockTextMatch(EvalContext *ctx, const char *regexp, const char *teststring, int *s, int *e); /* Sets variables */ bool ValidateRegEx(const char *regex); /* Pure */ #endif cfengine-3.24.2/libpromises/lastseen.h0000644000000000000000000000522515010704253017676 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LASTSEEN_H #define CFENGINE_LASTSEEN_H #include typedef struct { bool acknowledged; // True when acknowledged by cf-hub, false when updated time_t lastseen; QPoint Q; // Average time between connections (rolling weighted average) } KeyHostSeen; typedef enum { LAST_SEEN_ROLE_CONNECT, LAST_SEEN_ROLE_ACCEPT } LastSeenRole; bool Address2Hostkey(char *dst, size_t dst_size, const char *address); char *HostkeyToAddress(const char *hostkey); void LastSaw1(const char *ipaddress, const char *hashstr, LastSeenRole role); void LastSaw(const char *ipaddress, const unsigned char *digest, LastSeenRole role); bool DeleteIpFromLastSeen(const char *ip, char *digest, size_t digest_size); bool DeleteDigestFromLastSeen(const char *key, char *ip, size_t ip_size, bool a_entry_required); /* * Return false in order to stop iteration */ typedef bool (*LastSeenQualityCallback)(const char *hostkey, const char *address, bool incoming, const KeyHostSeen *quality, void *ctx); bool ScanLastSeenQuality(LastSeenQualityCallback callback, void *ctx); int LastSeenHostKeyCount(void); bool IsLastSeenCoherent(void); int RemoveKeysFromLastSeen(const char *input, bool must_be_coherent, char *equivalent, size_t equivalent_size); /** * @brief Acknowledge that lastseen host entry is observed. * @param host_key The host key of the lastseen entry. * @param incoming Whether it is an incoming or outgoing entry. * @return true if host entry was successfully acknowledged, otherwise false. */ bool LastSeenHostAcknowledge(const char *host_key, bool incoming); #endif cfengine-3.24.2/libpromises/promises.h0000644000000000000000000000271315010704253017720 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROMISES_H #define CFENGINE_PROMISES_H #include #include #include Promise *DeRefCopyPromise(EvalContext *ctx, const Promise *pp); Promise *ExpandDeRefPromise(EvalContext *ctx, const Promise *pp, bool *excluded); void PromiseRef(LogLevel level, const Promise *pp); void CopyBodyConstraintsToPromise(EvalContext *ctx, Promise *pp, const Body *bp); const char *PromiseID(const Promise *pp); #endif cfengine-3.24.2/libpromises/process_aix.c0000644000000000000000000000443015010704253020367 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /* * AIX 5.3 is missing this declaration */ #ifndef HAVE_GETPROCS64 int getprocs64(void *procsinfo, int sizproc, void *fdsinfo, int sizfd, pid_t *index, int count); #endif static bool FillProcEntry(struct procentry64* pe, pid_t pid) { pid_t nextpid = pid; int ret = getprocs64(pe, sizeof(*pe), NULL, 0, &nextpid, 1); /* * getprocs64 may * - return -1 => we can't access this process (EPERM) * - return 0 => end of process table, no such process * - return another process' info => no such process */ return ret == 1 && pe->pi_pid == pid; } time_t GetProcessStartTime(pid_t pid) { struct procentry64 pe; if (FillProcEntry(&pe, pid)) { return pe.pi_start; } else { return PROCESS_START_TIME_UNKNOWN; } } ProcessState GetProcessState(pid_t pid) { struct procentry64 pe; if (FillProcEntry(&pe, pid)) { switch (pe.pi_state) { case SSTOP: return PROCESS_STATE_STOPPED; case SZOMB: return PROCESS_STATE_ZOMBIE; default: return PROCESS_STATE_RUNNING; } } else { return PROCESS_STATE_DOES_NOT_EXIST; } } cfengine-3.24.2/libpromises/evalfunction.h0000644000000000000000000000342615010704253020556 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_EVALFUNCTION_H #define CFENGINE_EVALFUNCTION_H #include #include #include #include FnCallResult FnCallHostInNetgroup(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *finalargs); int FnNumArgs(const FnCallType *call_type); void ModuleProtocol(EvalContext *ctx, const char *command, const char *line, int print, char* context, size_t context_size, StringSet *tags, long *persistence); /* Implemented in Nova for Win32 */ FnCallResult FnCallGroupExists(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *finalargs); FnCallResult FnCallUserExists(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *finalargs); JsonElement *DefaultTemplateData(const EvalContext *ctx, const char *wantbundle); #endif cfengine-3.24.2/libpromises/shared_lib.c0000644000000000000000000000355415010704253020152 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef __MINGW32__ #include #include #include #include #include #include #include void *shlib_open(const char *lib_name) { struct stat statbuf; if (stat(lib_name, &statbuf) == -1) { Log(LOG_LEVEL_DEBUG, "Could not open shared library: %s\n", GetErrorStr()); return NULL; } void * ret = dlopen(lib_name, RTLD_NOW); if (!ret) { Log(LOG_LEVEL_ERR, "Could not open shared library: %s\n", dlerror()); } return ret; } void *shlib_load(void *handle, const char *symbol_name) { static pthread_mutex_t dlsym_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; ThreadLock(&dlsym_mutex); void *ret = dlsym(handle, symbol_name); ThreadUnlock(&dlsym_mutex); return ret; } void shlib_close(void *handle) { dlclose(handle); } #endif // !__MINGW32__ cfengine-3.24.2/libpromises/item_lib.c0000644000000000000000000007151615010704253017645 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include /* StringMatchFull,CompileRegex,StringMatchWithPrecompiledRegex */ #include #include #ifdef CYCLE_DETECTION /* While looping over entry lp in an Item list, advance slow half as * fast as lp; let n be the number of steps it has fallen behind; this * increases by one every second time round the loop. If there's a * cycle of length M, lp shall run round and round it; once slow gets * into the loop, they shall be n % M steps apart; at most 2*M more * times round the loop and n % M shall be 0 so lp == slow. If the * lead-in to the loop is of length L, this takes at most 2*(L+M) * turns round the loop to discover the cycle. The added cost is O(1) * per time round the loop, so the typical O(list length) user doesn't * change order when this is enabled, albeit the constant of * proportionality is up. * * Note, however, that none of this works if you're messing with the * structure (e.g. reversing or deleting) of the list as you go. * * To use the macros: before the loop, declare and initialize your * loop variable; pass it as lp to CYCLE_DECLARE(), followed by two * names not in use in your code. Then, in the body of the loop, * after advancing the loop variable, CYCLE_CHECK() the same three * parameters. This is apt to require a while loop where you might * otherwise have used a for loop; you also need to make sure your * loop doesn't continue past the checking. When you compile with * CYCLE_DETECTION defined, your function shall catch cycles, raising * a ProgrammingError() if it sees one. */ #define CYCLE_DECLARE(lp, slow, toggle) \ const Item *slow = lp; bool toggle = false #define CYCLE_VERIFY(lp, slow) if (!lp) { /* skip */ } \ else if (!slow) ProgrammingError("Loop-detector bug :-("); \ else if (lp == slow) ProgrammingError("Found loop in Item list") #define CYCLE_CHECK(lp, slow, toggle) \ CYCLE_VERIFY(lp, slow); \ if (toggle) { slow = slow->next; CYCLE_VERIFY(lp, slow); } \ toggle = !toggle #else #define CYCLE_DECLARE(lp, slow, toggle) /* skip */ #define CYCLE_CHECK(lp, slow, toggle) /* skip */ #endif #ifndef NDEBUG /* Only intended for use in assertions. Note that its cost is O(list * length), so you don't want to call it inside a loop over the * list. */ static bool ItemIsInList(const Item *list, const Item *item) { CYCLE_DECLARE(list, slow, toggle); while (list) { if (list == item) { return true; } list = list->next; CYCLE_CHECK(list, slow, toggle); } return false; } #endif /* NDEBUG */ /*******************************************************************/ Item *ReverseItemList(Item *list) { /* TODO: cycle-detection, which is somewhat harder here, without * turning this into a quadratic-cost function, albeit only when * assert() is enabled. */ Item *tail = NULL; while (list) { Item *here = list; list = here->next; /* assert(!ItemIsInList(here, list)); // quadratic cost */ here->next = tail; tail = here; } return tail; } /*******************************************************************/ void PrintItemList(const Item *list, Writer *w) { WriterWriteChar(w, '{'); const Item *ip = list; CYCLE_DECLARE(ip, slow, toggle); while (ip != NULL) { if (ip != list) { WriterWriteChar(w, ','); } WriterWriteChar(w, '\''); WriterWrite(w, ip->name); WriterWriteChar(w, '\''); ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } WriterWriteChar(w, '}'); } /*********************************************************************/ size_t ItemListSize(const Item *list) { size_t size = 0; const Item *ip = list; CYCLE_DECLARE(ip, slow, toggle); while (ip != NULL) { if (ip->name) { size += strlen(ip->name); } ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } return size; } /*********************************************************************/ Item *ReturnItemIn(Item *list, const char *item) { if (item == NULL || item[0] == '\0') { return NULL; } Item *ptr = list; CYCLE_DECLARE(ptr, slow, toggle); while (ptr != NULL) { if (strcmp(ptr->name, item) == 0) { return ptr; } ptr = ptr->next; CYCLE_CHECK(ptr, slow, toggle); } return NULL; } /*********************************************************************/ Item *ReturnItemInClass(Item *list, const char *item, const char *classes) { if (item == NULL || item[0] == '\0') { return NULL; } Item *ptr = list; CYCLE_DECLARE(ptr, slow, toggle); while (ptr != NULL) { if (strcmp(ptr->name, item) == 0 && strcmp(ptr->classes, classes) == 0) { return ptr; } ptr = ptr->next; CYCLE_CHECK(ptr, slow, toggle); } return NULL; } /*********************************************************************/ Item *ReturnItemAtIndex(Item *list, int index) { Item *ptr = list; for (int i = 0; ptr != NULL && i < index; i++) { ptr = ptr->next; } return ptr; } /*********************************************************************/ bool IsItemIn(const Item *list, const char *item) { if (item == NULL || item[0] == '\0') { return true; } const Item *ptr = list; CYCLE_DECLARE(ptr, slow, toggle); while (ptr != NULL) { if (strcmp(ptr->name, item) == 0) { return true; } ptr = ptr->next; CYCLE_CHECK(ptr, slow, toggle); } return false; } /*********************************************************************/ /* True precisely if the lists are of equal length and every entry of * the first appears in the second. As long as each list is known to * have no duplication of its entries, this is equivalent to testing * they have the same set of entries (ignoring order). * * This is not, in general, the same as the lists being equal ! They * may have the same entries in different orders. If the first list * has some duplicate entries, the second list can have some entries * not in the first, yet compare equal. Two lists with the same set * of entries but with different multiplicities are equal or different * precisely if of equal length. */ bool ListsCompare(const Item *list1, const Item *list2) { if (ListLen(list1) != ListLen(list2)) { return false; } const Item *ptr = list1; CYCLE_DECLARE(ptr, slow, toggle); while (ptr != NULL) { if (IsItemIn(list2, ptr->name) == false) { return false; } ptr = ptr->next; CYCLE_CHECK(ptr, slow, toggle); } return true; } /** * Checks whether list1 is a subset of list2, i.e. every entry in list1 must * be found in list2. */ bool ListSubsetOfList(const Item *list1, const Item *list2) { const Item *list1_ptr = list1; CYCLE_DECLARE(list1_ptr, slow, toggle); while (list1_ptr != NULL) { if (!IsItemIn(list2, list1_ptr->name)) { return false; } list1_ptr = list1_ptr->next; CYCLE_CHECK(list1_ptr, slow, toggle); } return true; /* all elements of list1 were found in list2 */ } /*********************************************************************/ Item *EndOfList(Item *ip) { Item *prev = CF_UNDEFINED_ITEM; CYCLE_DECLARE(ip, slow, toggle); while (ip != NULL) { prev = ip; ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } return prev; } /*********************************************************************/ Item *IdempPrependItem(Item **liststart, const char *itemstring, const char *classes) { Item *ip = ReturnItemIn(*liststart, itemstring); if (ip) { return ip; } PrependItem(liststart, itemstring, classes); return *liststart; } /*********************************************************************/ Item *IdempPrependItemClass(Item **liststart, const char *itemstring, const char *classes) { Item *ip = ReturnItemInClass(*liststart, itemstring, classes); if (ip) // already exists { return ip; } PrependItem(liststart, itemstring, classes); return *liststart; } /*********************************************************************/ void IdempItemCount(Item **liststart, const char *itemstring, const char *classes) { Item *ip = ReturnItemIn(*liststart, itemstring); if (ip) { ip->counter++; } else { PrependItem(liststart, itemstring, classes); } // counter+1 is the histogram of occurrences } /*********************************************************************/ Item *PrependItem(Item **liststart, const char *itemstring, const char *classes) { Item *ip = xcalloc(1, sizeof(Item)); ip->name = xstrdup(itemstring); if (classes != NULL) { ip->classes = xstrdup(classes); } ip->next = *liststart; *liststart = ip; return ip; } /*********************************************************************/ void PrependFullItem(Item **liststart, const char *itemstring, const char *classes, int counter, time_t t) { Item *ip = xcalloc(1, sizeof(Item)); ip->name = xstrdup(itemstring); ip->next = *liststart; ip->counter = counter; ip->time = t; if (classes != NULL) { ip->classes = xstrdup(classes); } *liststart = ip; } /*********************************************************************/ /* Warning: doing this a lot incurs quadratic costs, as we have to run * to the end of the list each time. If you're building long lists, * it is usually better to build the list with PrependItemList() and * then use ReverseItemList() to get the entries in the order you * wanted; for modest-sized n, 2*n < n*n, even after you've applied * different fixed scalings to the two sides. */ void AppendItem(Item **liststart, const char *itemstring, const char *classes) { Item *ip = xcalloc(1, sizeof(Item)); ip->name = xstrdup(itemstring); if (classes) { ip->classes = xstrdup(classes); /* unused now */ } if (*liststart == NULL) { *liststart = ip; } else { Item *lp = EndOfList(*liststart); assert(lp != CF_UNDEFINED_ITEM); lp->next = ip; } } /*********************************************************************/ void PrependItemList(Item **liststart, const char *itemstring) { Item *ip = xcalloc(1, sizeof(Item)); ip->name = xstrdup(itemstring); ip->next = *liststart; *liststart = ip; } /*********************************************************************/ size_t ListLen(const Item *list) { int count = 0; const Item *ip = list; CYCLE_DECLARE(ip, slow, toggle); while (ip != NULL) { count++; ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } return count; } /***************************************************************************/ void CopyList(Item **dest, const Item *source) /* Copy a list. */ { if (*dest != NULL) { ProgrammingError("CopyList - list not initialized"); } if (source == NULL) { return; } const Item *ip = source; CYCLE_DECLARE(ip, slow, toggle); Item *backwards = NULL; while (ip != NULL) { PrependFullItem(&backwards, ip->name, ip->classes, ip->counter, ip->time); ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } *dest = ReverseItemList(backwards); } /*********************************************************************/ Item *ConcatLists(Item *list1, Item *list2) /* Notes: * Refrain from freeing list2 after using ConcatLists * list1 must have at least one element in it */ { if (list1 == NULL) { ProgrammingError("ConcatLists: first argument must have at least one element"); } Item *tail = EndOfList(list1); assert(tail != CF_UNDEFINED_ITEM); assert(tail->next == NULL); /* If any entry in list1 is in list2, so is tail; so this is a * sufficient check that we're not creating a loop: */ assert(!ItemIsInList(list2, tail)); tail->next = list2; return list1; } void InsertAfter(Item **filestart, Item *ptr, const char *string) { if (*filestart == NULL || ptr == CF_UNDEFINED_ITEM) { AppendItem(filestart, string, NULL); return; } if (ptr == NULL) { AppendItem(filestart, string, NULL); return; } Item *ip = xcalloc(1, sizeof(Item)); ip->next = ptr->next; ptr->next = ip; ip->name = xstrdup(string); ip->classes = NULL; } /** * Splits a string containing a separator like ':' into a linked list of * separate items, * * @NOTE backslashes can be used to escape either the separator, or the * backslash itself, e.g. "\:" or "\\" (ofcourse proper C strings need * double backslash). * * @NOTE separator can't be the backslash. */ Item *SplitString(const char *string, char sep) { Item *liststart = NULL; size_t string_len = strlen(string); /* Temporary buffer for each chunk we append. This has the maximum * possible size we might possibly need. */ char *buf = xmalloc(string_len + 1); size_t buf_len = 0; /* We scan the string for separator or backslash. */ char sep2[3] = { sep, '\\', '\0' }; size_t z = 0; while ((z = strcspn(string, sep2)) < string_len) { memcpy(&buf[buf_len], string, z); buf_len += z; if (string[z] == '\\') { /* Check next character after backslash, if it's backslash or * separator then skip backslash, append character to buffer. */ if (string[z+1] == '\\' || string[z+1] == sep) { z++; } /* Append the single character to our buffer. */ buf[buf_len] = string[z]; buf_len++; /* SKIP, find next backslash or separator. */ string += z + 1; string_len -= z + 1; continue; } else /* separator was found, and it's not escaped */ { assert(string[z] == sep); assert((z == 0) || (z > 0 && string[z-1] != '\\')); } /* Terminate buffer and add to Item list. */ buf[buf_len] = '\0'; PrependItem(&liststart, buf, NULL); /* Empty the buffer. */ buf_len = 0; /* Start new search from after separator. */ string += z + 1; string_len -= z + 1; } memcpy(&buf[buf_len], string, z); buf_len += z; buf[buf_len] = '\0'; PrependItem(&liststart, buf, NULL); free(buf); return ReverseItemList(liststart); } /*********************************************************************/ Item *SplitStringAsItemList(const char *string, char sep) /* Splits a string containing a separator like : into a linked list of separate items, */ { Item *liststart = NULL; char node[256]; char format[] = "%255[^\0]"; /* Overwrite format's internal \0 with sep: */ format[strlen(format)] = sep; assert(strlen(format) + 1 == sizeof(format) || sep == '\0'); for (const char *sp = string; *sp != '\0'; sp++) { if (sscanf(sp, format, node) == 1 && node[0] != '\0') { sp += strlen(node) - 1; PrependItem(&liststart, node, NULL); } } return ReverseItemList(liststart); } /*********************************************************************/ /* NB: does not escape entries in list ! */ char *ItemList2CSV(const Item *list) { /* After each entry, we need space for either a ',' (before the * next entry) or a final '\0'. */ size_t s_size = ItemListSize(list) + ListLen(list); if (s_size == 0) { s_size = 1; } char *s = xmalloc(s_size); *s = '\0'; /* No point cycle-checking; done while computing s_size. */ for (const Item *ip = list; ip != NULL; ip = ip->next) { if (ip->name) { strcat(s, ip->name); } if (ip->next) { strcat(s, ","); } } assert(strlen(s) + 1 == s_size); return s; } /** * Write all strings in list to buffer #buf, separating them with * #separator. Watch out, no escaping happens. * * @return Final strlen(#buf), or #buf_size if string was truncated. * Always '\0'-terminates #buf (within #buf_size). */ size_t ItemList2CSV_bound(const Item *list, char *buf, size_t buf_size, char separator) { size_t space = buf_size - 1; /* Reserve one for a '\0' */ char *tail = buf; /* Point to end of what we've written. */ const Item *ip = list; CYCLE_DECLARE(ip, slow, toggle); while (ip != NULL) { size_t len = strlen(ip->name); assert(buf + buf_size == tail + space + 1); if (space < len) /* We must truncate */ { memcpy(tail, ip->name, space); tail[space] = '\0'; /* a.k.a. buf[buf_size - 1] */ return buf_size; /* This signifies truncation */ } else { memcpy(tail, ip->name, len); tail += len; space -= len; } /* Output separator if list has more entries. */ if (ip->next != NULL) { if (space > 0) { *tail = separator; tail++; space--; } else /* truncation */ { *tail = '\0'; return buf_size; } } ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } *tail = '\0'; return tail - buf; } /*********************************************************************/ /* Basic operations */ /*********************************************************************/ void IncrementItemListCounter(Item *list, const char *item) { if (item == NULL || item[0] == '\0') { return; } Item *ptr = list; CYCLE_DECLARE(ptr, slow, toggle); while (ptr != NULL) { if (strcmp(ptr->name, item) == 0) { ptr->counter++; return; } ptr = ptr->next; CYCLE_CHECK(ptr, slow, toggle); } } /*********************************************************************/ void SetItemListCounter(Item *list, const char *item, int value) { if (item == NULL || item[0] == '\0') { return; } Item *ptr = list; CYCLE_DECLARE(ptr, slow, toggle); while (ptr != NULL) { if (strcmp(ptr->name, item) == 0) { ptr->counter = value; return; } ptr = ptr->next; CYCLE_CHECK(ptr, slow, toggle); } } /*********************************************************************/ bool IsMatchItemIn(const Item *list, const char *item) /* Solve for possible regex/fuzzy models unified */ { if (item == NULL || item[0] == '\0') { return true; } const Item *ptr = list; CYCLE_DECLARE(ptr, slow, toggle); while (ptr != NULL) { if (FuzzySetMatch(ptr->name, item) == 0 || (IsRegex(ptr->name) && StringMatchFull(ptr->name, item))) { return true; } ptr = ptr->next; CYCLE_CHECK(ptr, slow, toggle); } return false; } /*********************************************************************/ /* Cycle-detection: you'll get a double free if there's a cycle. */ void DeleteItemList(Item *item) /* delete starting from item */ { while (item != NULL) { Item *here = item; item = here->next; /* before free()ing here */ free(here->name); free(here->classes); free(here); } } /*********************************************************************/ void DeleteItem(Item **liststart, Item *item) { if (item != NULL) { if (item == *liststart) { *liststart = item->next; } else { Item *ip = *liststart; CYCLE_DECLARE(ip, slow, toggle); while (ip && ip->next != item) { ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } if (ip != NULL) { assert(ip->next == item); ip->next = item->next; } } free(item->name); free(item->classes); free(item); } } /*********************************************************************/ /* DeleteItem* function notes: * -They all take an item list and an item specification ("string" argument.) * -Some of them treat the item spec as a literal string, while others * treat it as a regular expression. * -They all delete the first item meeting their criteria, as below. * function deletes item * ------------------------------------------------------------------------ * DeleteItemStarting start is literally equal to string item spec * DeleteItemLiteral literally equal to string item spec * DeleteItemMatching fully matched by regex item spec * DeleteItemContaining containing string item spec */ /*********************************************************************/ bool DeleteItemGeneral(Item **list, const char *string, ItemMatchType type) { if (list == NULL) { return false; } Regex *rx = NULL; if (type == ITEM_MATCH_TYPE_REGEX_COMPLETE_NOT || type == ITEM_MATCH_TYPE_REGEX_COMPLETE) { rx = CompileRegex(string); if (!rx) { return false; } } Item *ip = *list, *last = NULL; CYCLE_DECLARE(ip, slow, toggle); while (ip != NULL) { if (ip->name != NULL) { bool match = false, flip = false; switch (type) { case ITEM_MATCH_TYPE_LITERAL_START_NOT: flip = true; /* fall through */ case ITEM_MATCH_TYPE_LITERAL_START: match = (strncmp(ip->name, string, strlen(string)) == 0); break; case ITEM_MATCH_TYPE_LITERAL_COMPLETE_NOT: flip = true; /* fall through */ case ITEM_MATCH_TYPE_LITERAL_COMPLETE: match = (strcmp(ip->name, string) == 0); break; case ITEM_MATCH_TYPE_LITERAL_SOMEWHERE_NOT: flip = true; /* fall through */ case ITEM_MATCH_TYPE_LITERAL_SOMEWHERE: match = (strstr(ip->name, string) != NULL); break; case ITEM_MATCH_TYPE_REGEX_COMPLETE_NOT: flip = true; /* fall through */ case ITEM_MATCH_TYPE_REGEX_COMPLETE: match = StringMatchFullWithPrecompiledRegex(rx, ip->name); break; } if (flip) { match = !match; } if (match) { if (ip == *list) { *list = ip->next; } else { assert(ip != NULL); assert(last != NULL); assert(last->next == ip); last->next = ip->next; } free(ip->name); free(ip->classes); free(ip); if (rx) { RegexDestroy(rx); } return true; } } last = ip; ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } if (rx) { RegexDestroy(rx); } return false; } /*********************************************************************/ bool DeleteItemStarting(Item **list, const char *string) /* delete 1st item starting with string */ { return DeleteItemGeneral(list, string, ITEM_MATCH_TYPE_LITERAL_START); } /*********************************************************************/ bool DeleteItemNotStarting(Item **list, const char *string) /* delete 1st item starting with string */ { return DeleteItemGeneral(list, string, ITEM_MATCH_TYPE_LITERAL_START_NOT); } /*********************************************************************/ bool DeleteItemLiteral(Item **list, const char *string) /* delete 1st item which is string */ { return DeleteItemGeneral(list, string, ITEM_MATCH_TYPE_LITERAL_COMPLETE); } /*********************************************************************/ bool DeleteItemMatching(Item **list, const char *string) /* delete 1st item fully matching regex */ { return DeleteItemGeneral(list, string, ITEM_MATCH_TYPE_REGEX_COMPLETE); } /*********************************************************************/ bool DeleteItemNotMatching(Item **list, const char *string) /* delete 1st item fully matching regex */ { return DeleteItemGeneral(list, string, ITEM_MATCH_TYPE_REGEX_COMPLETE_NOT); } /*********************************************************************/ bool DeleteItemContaining(Item **list, const char *string) /* delete first item containing string */ { return DeleteItemGeneral(list, string, ITEM_MATCH_TYPE_LITERAL_SOMEWHERE); } /*********************************************************************/ bool DeleteItemNotContaining(Item **list, const char *string) /* delete first item containing string */ { return DeleteItemGeneral(list, string, ITEM_MATCH_TYPE_LITERAL_SOMEWHERE_NOT); } /*********************************************************************/ bool RawSaveItemList(const Item *liststart, const char *filename, NewLineMode new_line_mode) { char new[CF_BUFSIZE]; snprintf(new, sizeof(new), "%s%s", filename, CF_EDITED); unlink(new); /* Just in case of races */ FILE *fp = safe_fopen( new, (new_line_mode == NewLineMode_Native) ? "wt" : "w"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't write file '%s'. (fopen: %s)", new, GetErrorStr()); return false; } const Item *ip = liststart; CYCLE_DECLARE(ip, slow, toggle); while (ip != NULL) { fprintf(fp, "%s\n", ip->name); ip = ip->next; CYCLE_CHECK(ip, slow, toggle); } if (fclose(fp) == -1) { Log(LOG_LEVEL_ERR, "Unable to close file '%s' while writing. (fclose: %s)", new, GetErrorStr()); return false; } if (rename(new, filename) == -1) { Log(LOG_LEVEL_INFO, "Error while renaming file '%s' to '%s'. (rename: %s)", new, filename, GetErrorStr()); return false; } return true; } Item *RawLoadItemList(const char *filename) { FILE *fp = safe_fopen(filename, "r"); if (!fp) { return NULL; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); Item *list = NULL; while (CfReadLine(&line, &line_size, fp) != -1) { PrependItem(&list, line, NULL); } free(line); if (!feof(fp)) { Log(LOG_LEVEL_ERR, "Error while reading item list from file: %s", filename); DeleteItemList(list); list = NULL; } fclose(fp); return ReverseItemList(list); } bool IsInterfaceAddress(const Item *ip_addresses, const char *adr) /* Does this address belong to a local interface */ { for (const Item *ip = ip_addresses; ip != NULL; ip = ip->next) { if (strncasecmp(adr, ip->name, strlen(adr)) == 0) { Log(LOG_LEVEL_DEBUG, "Identifying '%s' as one of my interfaces", adr); return true; } } Log(LOG_LEVEL_DEBUG, "'%s' is not one of my interfaces", adr); return false; } cfengine-3.24.2/libpromises/mod_custom.c0000644000000000000000000012473015010704253020227 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include // StringStartsWith() #include // SeqStrginFromString() #include // Promise #include // cfPS(), EvalContextVariableGet() #include // GetClassContextAttributes(), IsClassesBodyConstraint() #include // ExpandScalar() #include // StringContainsUnresolved(), StringIsBareNonScalarRef() #include // Map* #include // AcquireLock() #include // GracefulTerminate(), GetProcessStartTime() static Map *custom_modules = NULL; static const ConstraintSyntax promise_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString( "path", "", "Path to promise module", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString( "interpreter", "", "Path to interpreter", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull()}; const BodySyntax CUSTOM_PROMISE_BLOCK_SYNTAX = BodySyntaxNew("promise", promise_constraints, NULL, SYNTAX_STATUS_NORMAL); const BodySyntax CUSTOM_BODY_BLOCK_SYNTAX = BodySyntaxNew("custom", NULL, NULL, SYNTAX_STATUS_CUSTOM); Body *FindCustomPromiseType(const Promise *promise) { assert(promise != NULL); const char *const promise_type = PromiseGetPromiseType(promise); const Policy *const policy = promise->parent_section->parent_bundle->parent_policy; Seq *custom_promise_types = policy->custom_promise_types; const size_t length = SeqLength(custom_promise_types); for (size_t i = 0; i < length; ++i) { Body *current = SeqAt(custom_promise_types, i); if (StringEqual(current->name, promise_type)) { return current; } } return NULL; } static bool GetInterpreterAndPath( EvalContext *ctx, Body *promise_block, char **interpreter_out, char **path_out) { assert(promise_block != NULL); assert(interpreter_out != NULL); assert(path_out != NULL); char *interpreter = NULL; char *path = NULL; const char *promise_type = promise_block->name; Seq *promise_block_attributes = promise_block->conlist; const size_t length = SeqLength(promise_block_attributes); for (size_t i = 0; i < length; ++i) { Constraint *attribute = SeqAt(promise_block_attributes, i); const char *name = attribute->lval; const char *value = RvalScalarValue(attribute->rval); if (StringEqual("interpreter", name)) { free(interpreter); interpreter = ExpandScalar(ctx, NULL, NULL, value, NULL); } else if (StringEqual("path", name)) { free(path); path = ExpandScalar(ctx, NULL, NULL, value, NULL); } else { debug_abort_if_reached(); } } if (path == NULL) { Log(LOG_LEVEL_ERR, "Custom promise type '%s' missing path", promise_type); free(interpreter); free(path); return false; } *interpreter_out = interpreter; *path_out = path; return true; } static inline LogLevel PromiseModule_LogJson(JsonElement *object, const Promise *pp, const char *promise_log_level) { const char *level_string = JsonObjectGetAsString(object, "level"); const char *message = JsonObjectGetAsString(object, "message"); assert(level_string != NULL && message != NULL); const LogLevel level = LogLevelFromString(level_string); assert(level != LOG_LEVEL_NOTHING); /* Check if there is a log level specified for the particular promise. */ if ((pp != NULL) && (promise_log_level != NULL)) { LogLevel specific = ActionAttributeLogLevelFromString(promise_log_level); if (specific < level) { /* Do not log messages that have a higher log level than the log * level specified for the promise (e.g. 'info' messages when * 'error' was requested for the promise). */ return level; } } Log(level, "%s", message); return level; } static inline JsonElement *PromiseModule_ParseResultClasses(char *value) { JsonElement *result_classes = JsonArrayCreate(1); char *delim = strchr(value, ','); while (delim != NULL) { *delim = '\0'; JsonArrayAppendString(result_classes, value); value = delim + 1; delim = strchr(value, ','); } JsonArrayAppendString(result_classes, value); return result_classes; } static JsonElement *PromiseModule_Receive(PromiseModule *module, const Promise *pp, uint16_t n_log_msgs[LOG_LEVEL_DEBUG + 1]) { assert(module != NULL); bool line_based = !(module->json); char *line = NULL; size_t size = 0; bool empty_line = false; JsonElement *log_array = JsonArrayCreate(10); JsonElement *response = NULL; if (line_based) { response = JsonObjectCreate(10); } const char *promise_log_level = NULL; if (pp != NULL) { promise_log_level = PromiseGetConstraintAsRval(pp, "log_level", RVAL_TYPE_SCALAR); } ssize_t bytes; while (!empty_line && ((bytes = getline(&line, &size, module->output)) > 0)) { assert(bytes > 0); assert(line != NULL); assert(line[bytes] == '\0'); assert(line[bytes - 1] == '\n'); line[bytes - 1] = '\0'; // Log only non-empty lines: if (bytes > 1) { Log(LOG_LEVEL_DEBUG, "Received line from module: '%s'", line); } if (line[0] == '\0') { empty_line = true; } else if (StringStartsWith(line, "log_")) { const char *const equal_sign = strchr(line, '='); assert(equal_sign != NULL); if (equal_sign == NULL) { Log(LOG_LEVEL_ERR, "Promise module sent invalid log line: '%s'", line); // Skip this line but keep parsing FREE_AND_NULL(line); size = 0; continue; } const char *const message = equal_sign + 1; const char *const level_start = line + strlen("log_"); const size_t level_length = equal_sign - level_start; char *const level = xstrndup(level_start, level_length); assert(strlen(level) == level_length); JsonElement *log_message = JsonObjectCreate(2); JsonObjectAppendString(log_message, "level", level); JsonObjectAppendString(log_message, "message", message); LogLevel log_level = PromiseModule_LogJson(log_message, pp, promise_log_level); if (log_level > LOG_LEVEL_NOTHING) { n_log_msgs[log_level]++; } JsonArrayAppendObject(log_array, log_message); free(level); } else if (line_based) { const char *const equal_sign = strchr(line, '='); assert(equal_sign != NULL); if (equal_sign == NULL) { Log(LOG_LEVEL_ERR, "Promise module sent invalid line: '%s'", line); } else { const char *const value = equal_sign + 1; const size_t key_length = equal_sign - line; char *const key = xstrndup(line, key_length); assert(strlen(key) == key_length); if (StringEqual(key, "result_classes")) { char *result_classes_str = xstrdup(value); JsonElement *result_classes = PromiseModule_ParseResultClasses(result_classes_str); JsonObjectAppendArray(response, key, result_classes); free(result_classes_str); } else { JsonObjectAppendString(response, key, value); } free(key); } } else // JSON protocol: { assert(strlen(line) > 0); assert(response == NULL); // Should be first and only line const char *data = line; // JsonParse() moves this while parsing JsonParseError err = JsonParse(&data, &response); if (err != JSON_PARSE_OK) { assert(response == NULL); Log(LOG_LEVEL_ERR, "Promise module '%s' sent invalid JSON", module->path); free(line); return NULL; } assert(response != NULL); } FREE_AND_NULL(line); size = 0; } if (response == NULL) { // This can happen if using the JSON protocol, and the module sends // nothing (newlines) or only log= lines. assert(!line_based); Log(LOG_LEVEL_ERR, "The '%s' promise module sent an invalid/incomplete response with JSON based protocol", module->path); return NULL; } if (line_based) { JsonObjectAppendArray(response, "log", log_array); log_array = NULL; } else { JsonElement *json_log_messages = JsonObjectGet(response, "log"); // Log messages inside JSON data haven't been printed yet, // do it now: if (json_log_messages != NULL) { size_t length = JsonLength(json_log_messages); for (size_t i = 0; i < length; ++i) { LogLevel log_level = PromiseModule_LogJson(JsonArrayGet(json_log_messages, i), pp, promise_log_level); if (log_level > LOG_LEVEL_NOTHING) { n_log_msgs[log_level]++; } } } JsonElement *merged = NULL; bool had_log_lines = (log_array != NULL && JsonLength(log_array) > 0); if (json_log_messages == NULL && !had_log_lines) { // No log messages at all, no need to add anything to JSON } else if (!had_log_lines) { // No separate log lines before JSON data, leave JSON as is } else if (had_log_lines && (json_log_messages == NULL)) { // Separate log lines, but no log messages in JSON data JsonObjectAppendArray(response, "log", log_array); log_array = NULL; } else { // both log messages as separate lines and in JSON, merge: merged = JsonMerge(log_array, json_log_messages); JsonObjectAppendArray(response, "log", merged); // json_log_messages will be destroyed since we append over it } } JsonDestroy(log_array); assert(response != NULL); return response; } static void PromiseModule_SendMessage(PromiseModule *module, Seq *message) { assert(module != NULL); const size_t length = SeqLength(message); for (size_t i = 0; i < length; ++i) { const char *line = SeqAt(message, i); NDEBUG_UNUSED const size_t line_length = strlen(line); assert(line_length > 0 && memchr(line, '\n', line_length) == NULL); fprintf(module->input, "%s\n", line); } fprintf(module->input, "\n"); fflush(module->input); } static Seq *PromiseModule_ReceiveHeader(PromiseModule *module) { assert(module != NULL); // Read header: char *line = NULL; size_t size = 0; ssize_t bytes = getline(&line, &size, module->output); if (bytes <= 0) { Log(LOG_LEVEL_ERR, "Did not receive header from promise module '%s'", module->path); free(line); return NULL; } if (line[bytes - 1] != '\n') { Log(LOG_LEVEL_ERR, "Promise module '%s %s' sent an invalid header with no newline: '%s'", module->interpreter, module->path, line); free(line); return NULL; } line[bytes - 1] = '\0'; Log(LOG_LEVEL_DEBUG, "Received header from promise module: '%s'", line); Seq *header = SeqStringFromString(line, ' '); FREE_AND_NULL(line); size = 0; // Read empty line: bytes = getline(&line, &size, module->output); if (bytes != 1 || line[0] != '\n') { Log(LOG_LEVEL_ERR, "Promise module '%s %s' failed to send empty line after header: '%s'", module->interpreter, module->path, line); SeqDestroy(header); free(line); return NULL; } free(line); return header; } // Internal function, use PromiseModule_Terminate instead static void PromiseModule_DestroyInternal(PromiseModule *module) { assert(module != NULL); free(module->path); free(module->interpreter); cf_pclose_full_duplex(&(module->fds)); free(module); } static PromiseModule *PromiseModule_Start(char *interpreter, char *path) { assert(path != NULL); if ((interpreter != NULL) && (access(interpreter, X_OK) != 0)) { Log(LOG_LEVEL_ERR, "Promise module interpreter '%s' is not an executable file", interpreter); return NULL; } if ((interpreter == NULL) && (access(path, X_OK) != 0)) { Log(LOG_LEVEL_ERR, "Promise module path '%s' is not an executable file", path); return NULL; } if (access(path, F_OK) != 0) { Log(LOG_LEVEL_ERR, "Promise module '%s' does not exist", path); return NULL; } PromiseModule *module = xcalloc(1, sizeof(PromiseModule)); module->interpreter = interpreter; module->path = path; char command[CF_BUFSIZE]; if (interpreter == NULL) { snprintf(command, CF_BUFSIZE, "%s", path); } else { snprintf(command, CF_BUFSIZE, "%s %s", interpreter, path); } Log(LOG_LEVEL_VERBOSE, "Starting custom promise module '%s' with command '%s'", path, command); module->fds = cf_popen_full_duplex_streams(command, false, true); module->output = module->fds.read_stream; module->input = module->fds.write_stream; module->message = NULL; if (!PipeToPid(&module->pid, module->fds.write_stream)) { Log(LOG_LEVEL_ERR, "Failed to get PID of custom promise module '%s'", path); PromiseModule_DestroyInternal(module); return NULL; } module->process_start_time = GetProcessStartTime(module->pid); if (module->process_start_time == PROCESS_START_TIME_UNKNOWN) { Log(LOG_LEVEL_ERR, "Failed to get process start time of custom promise module '%s'", path); PromiseModule_DestroyInternal(module); return NULL; } fprintf(module->input, "cf-agent %s v1\n\n", Version()); fflush(module->input); Seq *header = PromiseModule_ReceiveHeader(module); if (header == NULL) { // error logged in PromiseModule_ReceiveHeader() /* Make sure 'path' and 'interpreter' are not free'd twice (the calling * code frees them if it gets NULL). */ module->path = NULL; module->interpreter = NULL; PromiseModule_DestroyInternal(module); return NULL; } /* line_based is the default, but the module should specify it * explicitly. */ module->json = false; bool protocol_specified = false; const size_t header_length = SeqLength(header); const size_t flags_offset = 3; /* where flags start */ assert(header_length > flags_offset); /* at least one flag required -- json_based/line_based */ for (size_t i = flags_offset; i < header_length; ++i) { const char *const flag = SeqAt(header, i); if (StringEqual(flag, "json_based")) { module->json = true; if (protocol_specified) { Log(LOG_LEVEL_WARNING, "Ambiguous protocol specification from the custom promise module '%s'." " Please report this as a bug in the module", module->path); } protocol_specified = true; } else if (StringEqual(flag, "line_based")) { module->json = false; if (protocol_specified) { Log(LOG_LEVEL_WARNING, "Ambiguous protocol specification from the custom promise module '%s'." " Please report this as a bug in the module", module->path); } protocol_specified = true; } else if (StringEqual(flag, "action_policy")) { module->action_policy = true; } } if (!protocol_specified) { Log(LOG_LEVEL_WARNING, "Custom promise module '%s' didn't fully specify protocol." " Using 'line_based' as the default. Please report this as a bug in the module", module->path); } SeqDestroy(header); return module; } static void PromiseModule_AppendString( PromiseModule *module, const char *key, const char *value) { assert(module != NULL); if (module->message == NULL) { module->message = JsonObjectCreate(10); } JsonObjectAppendString(module->message, key, value); } static void PromiseModule_AppendInteger( PromiseModule *module, const char *key, int64_t value) { assert(module != NULL); if (module->message == NULL) { module->message = JsonObjectCreate(10); } JsonObjectAppendInteger64(module->message, key, value); } static void PromiseModule_AppendAttribute( PromiseModule *module, const char *key, JsonElement *value) { assert(module != NULL); if (module->message == NULL) { module->message = JsonObjectCreate(10); } JsonElement *attributes = JsonObjectGet(module->message, "attributes"); if (attributes == NULL) { attributes = JsonObjectCreate(10); JsonObjectAppendObject(module->message, "attributes", attributes); } JsonObjectAppendElement(attributes, key, value); } static void PromiseModule_Send(PromiseModule *module) { assert(module != NULL); if (module->json) { Writer *w = FileWriter(module->input); JsonWriteCompact(w, module->message); FileWriterDetach(w); DESTROY_AND_NULL(JsonDestroy, module->message); fprintf(module->input, "\n\n"); fflush(module->input); return; } Seq *message = SeqNew(10, free); JsonIterator iter = JsonIteratorInit(module->message); const char *key; while ((key = JsonIteratorNextKey(&iter)) != NULL) { if (StringEqual("attributes", key)) { JsonElement *attributes = JsonIteratorCurrentValue(&iter); JsonIterator attr_iter = JsonIteratorInit(attributes); const char *attr_name; while ((attr_name = JsonIteratorNextKey(&attr_iter)) != NULL) { const char *attr_val = JsonPrimitiveGetAsString( JsonIteratorCurrentValue(&attr_iter)); char *attr_line = NULL; xasprintf(&attr_line, "attribute_%s=%s", attr_name, attr_val); SeqAppend(message, attr_line); } } else { const char *value = JsonPrimitiveGetAsString(JsonIteratorCurrentValue(&iter)); char *line = NULL; xasprintf(&line, "%s=%s", key, value); SeqAppend(message, line); } } PromiseModule_SendMessage(module, message); SeqDestroy(message); DESTROY_AND_NULL(JsonDestroy, module->message); } static inline bool TryToGetContainerFromScalarRef(const EvalContext *ctx, const char *scalar, JsonElement **out) { if (StringIsBareNonScalarRef(scalar)) { /* Resolve a potential 'data' variable reference. */ const size_t scalar_len = strlen(scalar); char *var_ref_str = xstrndup(scalar + 2, scalar_len - 3); VarRef *ref = VarRefParse(var_ref_str); DataType type = CF_DATA_TYPE_NONE; const void *val = EvalContextVariableGet(ctx, ref, &type); free(var_ref_str); VarRefDestroy(ref); if ((val != NULL) && (type == CF_DATA_TYPE_CONTAINER)) { if (out != NULL) { *out = JsonCopy(val); } return true; } } return false; } static void PromiseModule_AppendAllAttributes( PromiseModule *module, const EvalContext *ctx, const Promise *pp) { assert(module != NULL); assert(pp != NULL); /* Need to make sure action_policy is "warn" in case of dry-run/simulate * modes. */ const bool dontdo = (EVAL_MODE != EVAL_MODE_NORMAL); bool seen_action_policy = false; const size_t attributes = SeqLength(pp->conlist); for (size_t i = 0; i < attributes; i++) { const Constraint *attribute = SeqAt(pp->conlist, i); const char *const name = attribute->lval; assert(!StringEqual(name, "ifvarclass")); // Not allowed by validation if (IsClassesBodyConstraint(name) || StringEqual(name, "if") || StringEqual(name, "ifvarclass") || StringEqual(name, "unless") || StringEqual(name, "depends_on") || StringEqual(name, "with") || StringEqual(name, "meta") || StringEqual(name, "expireafter")) { // Evaluated by agent and not sent to module, skip continue; } if (StringEqual(name, "action") || StringEqual(name, "action_name")) { /* We only pass "action_policy" to the module (see below). */ continue; } if (StringEqual(attribute->lval, "log_level")) { /* Passed to the module as 'log_level' request field, not as an attribute. */ continue; } JsonElement *value = NULL; if (dontdo && StringEqual(name, "action_policy")) { /* Override the value in case of dry-run/simulate modes. */ seen_action_policy = true; value = JsonStringCreate("warn"); } else if (attribute->rval.type == RVAL_TYPE_SCALAR) { /* Could be a '@(container)' reference. */ if (!TryToGetContainerFromScalarRef(ctx, RvalScalarValue(attribute->rval), &value)) { /* Didn't resolve to a container value, let's just use the * scalar value as-is. */ value = RvalToJson(attribute->rval); } } else if ((attribute->rval.type == RVAL_TYPE_LIST) || (attribute->rval.type == RVAL_TYPE_CONTAINER)) { value = RvalToJson(attribute->rval); } if (value != NULL) { PromiseModule_AppendAttribute(module, name, value); } else { Log(LOG_LEVEL_VERBOSE, "Unsupported type of the '%s' attribute (%c), cannot be sent to custom promise module", name, attribute->rval.type); } seen_action_policy = (seen_action_policy || StringEqual(name, "action_policy")); } if (dontdo && !seen_action_policy) { /* Make sure action_policy is specified in case of dry-run/simulate modes. */ PromiseModule_AppendAttribute(module, "action_policy", JsonStringCreate("warn")); } } static bool CheckPrimitiveForUnexpandedVars(JsonElement *primitive, ARG_UNUSED void *data) { assert(JsonGetElementType(primitive) == JSON_ELEMENT_TYPE_PRIMITIVE); /* Stop the iteration if a variable expression is found. */ return (!StringContainsUnresolved(JsonPrimitiveGetAsString(primitive))); } static bool CheckObjectForUnexpandedVars(JsonElement *object, ARG_UNUSED void *data) { assert(JsonGetType(object) == JSON_TYPE_OBJECT); /* Stop the iteration if a variable expression is found among children * keys. (elements inside the object are checked separately) */ JsonIterator iter = JsonIteratorInit(object); while (JsonIteratorHasMore(&iter)) { const char *key = JsonIteratorNextKey(&iter); if (StringContainsUnresolved(key)) { return false; } } return true; } static inline bool CustomPromise_IsFullyResolved(const EvalContext *ctx, const Promise *pp, bool nonscalars_allowed) { assert(pp != NULL); if (StringContainsUnresolved(pp->promiser)) { return false; } const size_t attributes = SeqLength(pp->conlist); for (size_t i = 0; i < attributes; i++) { const Constraint *attribute = SeqAt(pp->conlist, i); if (IsClassesBodyConstraint(attribute->lval) || StringEqual(attribute->lval, "meta")) { /* Not passed to the modules, handled on the agent side. */ continue; } if (StringEqual(attribute->lval, "log_level")) { /* Passed to the module as 'log_level' request field, not as an attribute. */ continue; } if (StringEqual(attribute->lval, "unless")) { /* unless can actually have unresolved variables here, it defaults to evaluate in case of unresolved variables, to be the true opposite of if. (if would skip).*/ continue; } if ((attribute->rval.type == RVAL_TYPE_FNCALL) || (!nonscalars_allowed && (attribute->rval.type != RVAL_TYPE_SCALAR))) { return false; } if (attribute->rval.type == RVAL_TYPE_SCALAR) { const char *const value = RvalScalarValue(attribute->rval); if (StringContainsUnresolved(value) && !TryToGetContainerFromScalarRef(ctx, value, NULL)) { return false; } } else if (attribute->rval.type == RVAL_TYPE_LIST) { assert(nonscalars_allowed); for (Rlist *rl = RvalRlistValue(attribute->rval); rl != NULL; rl = rl->next) { assert(rl->val.type == RVAL_TYPE_SCALAR); const char *const value = RvalScalarValue(rl->val); if (StringContainsUnresolved(value)) { return false; } } } else { assert(nonscalars_allowed); assert(attribute->rval.type == RVAL_TYPE_CONTAINER); JsonElement *attr_data = RvalContainerValue(attribute->rval); return JsonWalk(attr_data, CheckObjectForUnexpandedVars, NULL, CheckPrimitiveForUnexpandedVars, NULL); } } return true; } static inline bool HasResultAndResultIsValid(JsonElement *response) { const char *const result = JsonObjectGetAsString(response, "result"); return ((result != NULL) && StringEqual(result, "valid")); } static inline const char *LogLevelToRequestFromModule(const Promise *pp) { LogLevel log_level = LogGetGlobalLevel(); /* Check if there is a log level specified for the particular promise. */ const char *value = PromiseGetConstraintAsRval(pp, "log_level", RVAL_TYPE_SCALAR); if (value != NULL) { LogLevel specific = ActionAttributeLogLevelFromString(value); /* Promise-specific log level cannot go above the global log level * (e.g. no 'info' messages for a particular promise if the global level * is 'error'). */ log_level = MIN(log_level, specific); } // We will never request LOG_LEVEL_NOTHING or LOG_LEVEL_CRIT from the // module: if (log_level < LOG_LEVEL_ERR) { assert((log_level == LOG_LEVEL_NOTHING) || (log_level == LOG_LEVEL_CRIT)); return LogLevelToString(LOG_LEVEL_ERR); } return LogLevelToString(log_level); } static bool PromiseModule_Validate(PromiseModule *module, const EvalContext *ctx, const Promise *pp) { assert(module != NULL); assert(pp != NULL); const char *const promise_type = PromiseGetPromiseType(pp); const char *const promiser = pp->promiser; const char *action_policy = PromiseGetConstraintAsRval(pp, "action_policy", RVAL_TYPE_SCALAR); const bool dontdo = ((EVAL_MODE != EVAL_MODE_NORMAL) || StringEqual(action_policy, "warn") || StringEqual(action_policy, "nop")); if (dontdo && !module->action_policy) { Log(LOG_LEVEL_ERR, "Not making changes to the system, but the custom promise module '%s' doesn't support action_policy", module->path); return false; } PromiseModule_AppendString(module, "operation", "validate_promise"); PromiseModule_AppendString(module, "log_level", LogLevelToRequestFromModule(pp)); PromiseModule_AppendString(module, "promise_type", promise_type); PromiseModule_AppendString(module, "promiser", promiser); PromiseModule_AppendInteger(module, "line_number", pp->offset.line); PromiseModule_AppendString(module, "filename", PromiseGetBundle(pp)->source_path); PromiseModule_AppendAllAttributes(module, ctx, pp); PromiseModule_Send(module); // Prints errors / log messages from module: uint16_t n_log_msgs[LOG_LEVEL_DEBUG + 1] = {0}; JsonElement *response = PromiseModule_Receive(module, pp, n_log_msgs); if (response == NULL) { // Error already printed in PromiseModule_Receive() return false; } const bool valid = HasResultAndResultIsValid(response); JsonDestroy(response); if (!valid) { // Detailed error messages from module should already have been printed const char *const filename = pp->parent_section->parent_bundle->source_path; const size_t line = pp->offset.line; Log(LOG_LEVEL_VERBOSE, "%s promise with promiser '%s' failed validation (%s:%zu)", promise_type, promiser, filename, line); if ((n_log_msgs[LOG_LEVEL_ERR] == 0) && (n_log_msgs[LOG_LEVEL_CRIT] == 0)) { Log(LOG_LEVEL_CRIT, "Bug in promise module - No error(s) logged for invalid %s promise with promiser '%s' (%s:%zu)", promise_type, promiser, filename, line); } } return valid; } static PromiseResult PromiseModule_Evaluate( PromiseModule *module, EvalContext *ctx, const Promise *pp) { assert(module != NULL); assert(pp != NULL); const char *const promise_type = PromiseGetPromiseType(pp); const char *const promiser = pp->promiser; PromiseModule_AppendString(module, "operation", "evaluate_promise"); PromiseModule_AppendString( module, "log_level", LogLevelToRequestFromModule(pp)); PromiseModule_AppendString(module, "promise_type", promise_type); PromiseModule_AppendString(module, "promiser", promiser); PromiseModule_AppendInteger(module, "line_number", pp->offset.line); PromiseModule_AppendString(module, "filename", PromiseGetBundle(pp)->source_path); PromiseModule_AppendAllAttributes(module, ctx, pp); PromiseModule_Send(module); const char *action_policy = PromiseGetConstraintAsRval(pp, "action_policy", RVAL_TYPE_SCALAR); const bool dontdo = ((EVAL_MODE != EVAL_MODE_NORMAL) || StringEqual(action_policy, "warn") || StringEqual(action_policy, "nop")); uint16_t n_log_msgs[LOG_LEVEL_DEBUG + 1] = {0}; JsonElement *response = PromiseModule_Receive(module, pp, n_log_msgs); if (response == NULL) { // Log from PromiseModule_Receive return PROMISE_RESULT_FAIL; } JsonElement *result_classes = JsonObjectGetAsArray(response, "result_classes"); if (result_classes != NULL) { const size_t n_classes = JsonLength(result_classes); for (size_t i = 0; i < n_classes; i++) { const char *class_name = JsonArrayGetAsString(result_classes, i); assert(class_name != NULL); EvalContextClassPutSoft(ctx, class_name, CONTEXT_SCOPE_BUNDLE, "source=promise-module"); } } PromiseResult result; const char *const result_str = JsonObjectGetAsString(response, "result"); /* Attributes needed for setting outcome classes etc. */ Attributes a = GetClassContextAttributes(ctx, pp); const char *const filename = pp->parent_section->parent_bundle->source_path; const size_t line = pp->offset.line; if (dontdo && (n_log_msgs[LOG_LEVEL_INFO] > 0)) { Log(LOG_LEVEL_CRIT, "Bug in promise module - 'info:' log messages reported for %s promise with promiser '%s' (%s:%zu)" " while making changes on the system disabled", promise_type, promiser, filename, line); } if (result_str == NULL) { result = PROMISE_RESULT_FAIL; cfPS( ctx, LOG_LEVEL_ERR, result, pp, &a, "Promise module did not return a result for promise evaluation (%s promise, promiser: '%s' module: '%s')", promise_type, promiser, module->path); } else if (StringEqual(result_str, "kept")) { result = PROMISE_RESULT_NOOP; cfPS( ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "Promise with promiser '%s' was kept by promise module '%s'", promiser, module->path); } else if (StringEqual(result_str, "not_kept")) { result = PROMISE_RESULT_FAIL; cfPS( ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "Promise with promiser '%s' was not kept by promise module '%s'", promiser, module->path); if (!dontdo && (n_log_msgs[LOG_LEVEL_ERR] == 0) && (n_log_msgs[LOG_LEVEL_CRIT] == 0)) { Log(LOG_LEVEL_CRIT, "Bug in promise module - Failed to log errors for not kept %s promise with promiser '%s' (%s:%zu)", promise_type, promiser, filename, line); } else if (dontdo && ((n_log_msgs[LOG_LEVEL_WARNING] + n_log_msgs[LOG_LEVEL_ERR] + n_log_msgs[LOG_LEVEL_CRIT]) == 0)) { Log(LOG_LEVEL_CRIT, "Bug in promise module - Failed to log warnings for not kept %s promise with promiser '%s' (%s:%zu)" " while making changes on the system disabled", promise_type, promiser, filename, line); } } else if (StringEqual(result_str, "repaired")) { result = PROMISE_RESULT_CHANGE; cfPS( ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "Promise with promiser '%s' was repaired by promise module '%s'", promiser, module->path); if (dontdo) { Log(LOG_LEVEL_CRIT, "Bug in promise module - %s promise with promiser '%s' (%s:%zu)" " repaired while making changes on the system disabled", promise_type, promiser, filename, line); } if (n_log_msgs[LOG_LEVEL_INFO] == 0) { Log(LOG_LEVEL_CRIT, "Bug in promise module - Failed to log about changes made by a repaired %s promise with promiser '%s' (%s:%zu)", promise_type, promiser, filename, line); } } else if (StringEqual(result_str, "error")) { result = PROMISE_RESULT_FAIL; cfPS( ctx, LOG_LEVEL_ERR, result, pp, &a, "An unexpected error occured in promise module (%s promise, promiser: '%s' module: '%s')", promise_type, promiser, module->path); } else { result = PROMISE_RESULT_FAIL; cfPS( ctx, LOG_LEVEL_ERR, result, pp, &a, "Promise module returned unacceptable result: '%s' (%s promise, promiser: '%s' module: '%s')", result_str, promise_type, promiser, module->path); } JsonDestroy(response); return result; } static void PromiseModule_Terminate(PromiseModule *module, const Promise *pp) { if (module != NULL) { PromiseModule_AppendString(module, "operation", "terminate"); PromiseModule_Send(module); uint16_t n_log_msgs[LOG_LEVEL_DEBUG + 1] = {0}; JsonElement *response = PromiseModule_Receive(module, pp, n_log_msgs); JsonDestroy(response); PromiseModule_DestroyInternal(module); } } static void PromiseModule_Terminate_untyped(void *data) { PromiseModule *module = data; PromiseModule_Terminate(module, NULL); } void TerminateCustomPromises(void) { MapIterator iter = MapIteratorInit(custom_modules); for (const MapKeyValue *item = MapIteratorNext(&iter); item != NULL; item = MapIteratorNext(&iter)) { const char *const path = item->key; const PromiseModule *const module = item->value; if (!GracefulTerminate(module->pid, module->process_start_time)) { Log(LOG_LEVEL_ERR, "Failed to terminate custom promise module '%s'", path); } } } bool InitializeCustomPromises() { /* module_path -> PromiseModule map */ custom_modules = MapNew(StringHash_untyped, StringEqual_untyped, free, PromiseModule_Terminate_untyped); assert(custom_modules != NULL); return (custom_modules != NULL); } void FinalizeCustomPromises() { MapDestroy(custom_modules); } PromiseResult EvaluateCustomPromise(EvalContext *ctx, const Promise *pp) { assert(ctx != NULL); assert(pp != NULL); Body *promise_block = FindCustomPromiseType(pp); if (promise_block == NULL) { Log(LOG_LEVEL_ERR, "Undefined promise type '%s'", PromiseGetPromiseType(pp)); return PROMISE_RESULT_FAIL; } /* Attributes needed for setting outcome classes etc. */ Attributes a = GetClassContextAttributes(ctx, pp); char *interpreter = NULL; char *path = NULL; bool success = GetInterpreterAndPath(ctx, promise_block, &interpreter, &path); if (!success) { assert(interpreter == NULL && path == NULL); /* Details logged in GetInterpreterAndPath() */ cfPS(ctx, LOG_LEVEL_NOTHING, PROMISE_RESULT_FAIL, pp, &a, NULL); return PROMISE_RESULT_FAIL; } /* Used below, constructed here while path and interpreter are definitely * valid pointers. */ char custom_promise_id[CF_BUFSIZE]; NDEBUG_UNUSED size_t ret = snprintf(custom_promise_id, sizeof(custom_promise_id), "%s-%s-%s", pp->promiser, path, interpreter ? interpreter : "(null)"); assert((ret > 0) && (ret < sizeof(custom_promise_id))); PromiseModule *module = MapGet(custom_modules, path); if (module == NULL) { /* Takes ownership of interpreter and path. */ module = PromiseModule_Start(interpreter, path); if (module != NULL) { MapInsert(custom_modules, xstrdup(path), module); } else { free(interpreter); free(path); // Error logged in PromiseModule_Start() cfPS(ctx, LOG_LEVEL_NOTHING, PROMISE_RESULT_FAIL, pp, &a, NULL); return PROMISE_RESULT_FAIL; } } else { if (!StringEqual(interpreter, module->interpreter)) { Log(LOG_LEVEL_ERR, "Conflicting interpreter specifications for custom promise module '%s'" " (started with '%s' and '%s' requested for promise '%s' of type '%s')", path, module->interpreter, interpreter, pp->promiser, PromiseGetPromiseType(pp)); free(interpreter); free(path); cfPS(ctx, LOG_LEVEL_NOTHING, PROMISE_RESULT_FAIL, pp, &a, NULL); return PROMISE_RESULT_FAIL; } free(interpreter); free(path); } // TODO: Do validation earlier (cf-promises --full-check) bool valid = CustomPromise_IsFullyResolved(ctx, pp, module->json); if ((!valid) && (EvalContextGetPass(ctx) == CF_DONEPASSES - 1)) { Log(LOG_LEVEL_ERR, "%s promise with promiser '%s' has unresolved/unexpanded variables", PromiseGetPromiseType(pp), pp->promiser); } CfLock promise_lock = AcquireLock(ctx, custom_promise_id, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, false); if (promise_lock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } if (valid) { valid = PromiseModule_Validate(module, ctx, pp); } PromiseResult result; if (valid) { result = PromiseModule_Evaluate(module, ctx, pp); } else { // PromiseModule_Validate() already printed an error Log(LOG_LEVEL_VERBOSE, "%s promise with promiser '%s' will be skipped because it failed validation", PromiseGetPromiseType(pp), pp->promiser); cfPS(ctx, LOG_LEVEL_NOTHING, PROMISE_RESULT_FAIL, pp, &a, NULL); result = PROMISE_RESULT_FAIL; // TODO: Investigate if DENIED is more // appropriate } YieldCurrentLock(promise_lock); return result; } cfengine-3.24.2/libpromises/files_copy.c0000644000000000000000000002002715010704253020204 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include bool CopyRegularFileDiskPerms(const char *source, const char *destination, int mode) { assert(source != NULL); assert(destination != NULL); int sd = safe_open(source, O_RDONLY | O_BINARY); if (sd == -1) { Log(LOG_LEVEL_INFO, "Can't copy '%s' (open: %s)", source, GetErrorStr()); return false; } /* unlink() + safe_open(O_CREAT|O_EXCL) to avoid symlink attacks and races. */ unlink(destination); int dd = safe_open_create_perms(destination, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, mode); if (dd == -1) { Log(LOG_LEVEL_INFO, "Unable to open destination file while copying '%s' to '%s'" " (open: %s)", source, destination, GetErrorStr()); close(sd); return false; } /* We need to stat the file to get the block size of the source file */ struct stat statbuf; if (fstat(sd, &statbuf) == -1) { Log(LOG_LEVEL_INFO, "Can't copy '%s' (fstat: %s)", source, GetErrorStr()); close(sd); close(dd); return false; } size_t total_bytes_written; bool last_write_was_hole; bool ret = FileSparseCopy(sd, source, dd, destination, ST_BLKSIZE(statbuf), &total_bytes_written, &last_write_was_hole); if (!ret) { unlink(destination); close(sd); close(dd); return false; } bool do_sync = false; ret = FileSparseClose(dd, destination, do_sync, total_bytes_written, last_write_was_hole); if (!ret) { unlink(destination); } close(sd); close(dd); return ret; } bool CopyRegularFileDisk(const char *source, const char *destination) { assert(source != NULL); assert(destination != NULL); bool ok1 = false, ok2 = false; /* initialize before the goto end; */ int sd = safe_open(source, O_RDONLY | O_BINARY); if (sd == -1) { Log(LOG_LEVEL_INFO, "Can't copy '%s' (open: %s)", source, GetErrorStr()); goto end; } /* We need to stat the file to get the right source permissions. */ struct stat statbuf; if (fstat(sd, &statbuf) == -1) { Log(LOG_LEVEL_INFO, "Can't copy '%s' (fstat: %s)", source, GetErrorStr()); goto end; } /* unlink() + safe_open(O_CREAT|O_EXCL) to avoid symlink attacks and races. */ unlink(destination); int dd = safe_open_create_perms(destination, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, statbuf.st_mode); if (dd == -1) { Log(LOG_LEVEL_INFO, "Unable to open destination file while copying '%s' to '%s'" " (open: %s)", source, destination, GetErrorStr()); goto end; } size_t total_bytes_written; bool last_write_was_hole; ok1 = FileSparseCopy(sd, source, dd, destination, ST_BLKSIZE(statbuf), &total_bytes_written, &last_write_was_hole); bool do_sync = false; ok2 = FileSparseClose(dd, destination, do_sync, total_bytes_written, last_write_was_hole); if (!ok1 || !ok2) { unlink(destination); } end: if (sd != -1) { close(sd); } return ok1 && ok2; } bool CopyFilePermissionsDisk(const char *source, const char *destination) { struct stat statbuf; if (stat(source, &statbuf) == -1) { Log(LOG_LEVEL_INFO, "Can't copy permissions '%s'. (stat: %s)", source, GetErrorStr()); return false; } if (safe_chmod(destination, statbuf.st_mode) != 0) { Log(LOG_LEVEL_INFO, "Can't copy permissions '%s'. (chmod: %s)", source, GetErrorStr()); return false; } if (safe_chown(destination, statbuf.st_uid, statbuf.st_gid) != 0) { Log(LOG_LEVEL_INFO, "Can't copy permissions '%s'. (chown: %s)", source, GetErrorStr()); return false; } if (!CopyFileExtendedAttributesDisk(source, destination, NULL)) { return false; } return true; } bool CopyFileExtendedAttributesDisk(const char *source, const char *destination, bool *change) { #if defined(WITH_XATTR) // Extended attributes include both POSIX ACLs and SELinux contexts. ssize_t attr_raw_names_size; char attr_raw_names[CF_BUFSIZE]; attr_raw_names_size = llistxattr(source, attr_raw_names, sizeof(attr_raw_names)); if (attr_raw_names_size < 0) { if (errno == ENOTSUP || errno == ENODATA) { if (change != NULL) { *change = false; } return true; } else { Log(LOG_LEVEL_ERR, "Can't copy extended attributes from '%s' to '%s'. (llistxattr: %s)", source, destination, GetErrorStr()); return false; } } int pos; for (pos = 0; pos < attr_raw_names_size;) { const char *current = attr_raw_names + pos; pos += strlen(current) + 1; char src_data[CF_BUFSIZE]; int src_datasize = lgetxattr(source, current, src_data, sizeof(src_data)); if (src_datasize < 0) { if (errno == ENOTSUP) { continue; } else { Log(LOG_LEVEL_ERR, "Can't copy extended attributes from '%s' to '%s'. (lgetxattr: %s: %s)", source, destination, GetErrorStr(), current); return false; } } char dst_data[CF_BUFSIZE]; int dst_datasize = lgetxattr(destination, current, dst_data, sizeof(dst_data)); if ((dst_datasize < 0) && (errno == ENOTSUP)) { continue; } else if ((src_datasize == dst_datasize) && (memcmp(src_data, dst_data, src_datasize) == 0)) { /* The value is the same, no need to overwrite it. */ continue; } int ret = lsetxattr(destination, current, src_data, src_datasize, 0); if (ret < 0) { if (errno == ENOTSUP) { continue; } else { Log(LOG_LEVEL_ERR, "Can't copy extended attributes from '%s' to '%s'. (lsetxattr: %s: %s)", source, destination, GetErrorStr(), current); return false; } } if (change != NULL) { *change = true; } } #else // !WITH_XATTR // ACLs are included in extended attributes, but fall back to CopyACLs if xattr is not available. if (!CopyACLs(source, destination, change)) { return false; } #endif return true; } cfengine-3.24.2/libpromises/mod_services.c0000644000000000000000000000533415010704253020536 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax service_method_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString("service_args", "", "Parameters for starting the service as command", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("service_autostart_policy", "none,boot_time,on_demand", "Should the service be started automatically by the OS", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBundle("service_bundle", "A bundle reference with two arguments (service_name,args) used if the service type is generic", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("service_dependence_chain", "ignore,start_parent_services,stop_child_services,all_related", "How to handle dependencies and dependent services", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("service_type", "windows,generic", "Service abstraction type", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax service_method_body = BodySyntaxNew("service_method", service_method_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax services_constraints[] = { ConstraintSyntaxNewString("service_policy", "", "Policy for cfengine service status", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("service_dependencies", CF_IDRANGE, "A list of services on which the named service abstraction depends", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("service_method", &service_method_body, "Details of promise body for the service abtraction feature", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_SERVICES_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "services", services_constraints, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/extensions_template.h.pre0000644000000000000000000050043715010704253022744 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ BEGIN_MARKER // Do not include this file directly! Build process should replace XextensionX occurrences. /******************************************************************************* * Note: This shared library calling mechanism should only be used for private * shared libraries, such as the Enterprise plugins for CFEngine. ******************************************************************************/ /******************************************************************************* * How to use the Extension calling API: * * In the application: * * - Declare function prototypes using the xEXTENSIONx_FUNC_xARG_DECLARE macros. * Replace x with the number of arguments to the function. * * - Define a stub function using the xEXTENSIONx_FUNC_xARG_DEFINE_STUB macros. * * In the xExtensionX plugin: * * - Include the same prototype as you used in the application. * * - Define the xExtensionX function with the xEXTENSIONx_FUNC_xARG_DEFINE * macros. * * IMPORTANT: * * - For functions returning void, you need to use the VOID_FUNC version of the * macros. * * - Due to macro limitations, for each function argument, you need to put the * type and the name as separate arguments, so instead of (int par), use * (int, par). * * - You can use the function normally in your code. If the xExtensionX plugin * is available, it will call that function, if not, it will call the stub * function. * * - The lookup is more expensive than a normal function call. Don't use it in * a tight loop. * * - Be careful when changing the function signature. The plugin needs * to stay binary compatible, otherwise the it will not work, and may even * crash. Signature changes should only happen between major releases. * * Examples: * * - int xExtensionXOnlyInt(const char *str, int num) becomes * xEXTENSIONx_FUNC_2ARG_DECLARE(int, xExtensionXOnlyInt, * const char *, str, int, num) * xEXTENSIONx_FUNC_2ARG_DEFINE_STUB(int, xExtensionXOnlyInt, * const char *, str, int, num) * xEXTENSIONx_FUNC_2ARG_DEFINE(int, xExtensionXOnlyInt, * const char *, str, int, num) * * - void xExtensionXFunc(int num) becomes * xEXTENSIONx_VOID_FUNC_1ARG_DECLARE(void, xExtensionXFunc, int, num) * xEXTENSIONx_VOID_FUNC_1ARG_DEFINE_STUB(void, xExtensionXFunc, int, num) * xEXTENSIONx_VOID_FUNC_1ARG_DEFINE(void, xExtensionXFunc, int, num) ******************************************************************************/ /******************************************************************************* * It may be easier to understand the implementation below by looking at the * output it actually produces. gcc -E is your friend. ******************************************************************************/ #ifndef xEXTENSIONx_EXTENSION_H #define xEXTENSIONx_EXTENSION_H #include #include #include #ifndef BUILTIN_EXTENSIONS #define xEXTENSIONx_CANARY_VALUE 0x10203040 #define xEXTENSIONx_LIBRARY_NAME "cfengine-XextensionX.so" void *XextensionX_library_open(); void XextensionX_library_close(void *handle); #ifndef BUILDING_xEXTENSIONx_EXTENSION # define xEXTENSIONx_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ __ret __func() # define xEXTENSIONx_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func(__t1 __p1) # define xEXTENSIONx_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func(__t1 __p1, __t2 __p2) # define xEXTENSIONx_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3) # define xEXTENSIONx_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define xEXTENSIONx_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define xEXTENSIONx_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define xEXTENSIONx_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define xEXTENSIONx_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define xEXTENSIONx_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define xEXTENSIONx_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define xEXTENSIONx_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define xEXTENSIONx_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define xEXTENSIONx_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define xEXTENSIONx_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define xEXTENSIONx_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) # define xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) \ __ret __func##__stub() # define xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__stub(__t1 __p1) # define xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__stub(__t1 __p1, __t2 __p2) # define xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3) # define xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) #else // BUILDING_xEXTENSIONx_EXTENSION # define xEXTENSIONx_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, int32_t __end_canary) # define xEXTENSIONx_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, int32_t __end_canary) # define xEXTENSIONx_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, int32_t __end_canary) # define xEXTENSIONx_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, int32_t __end_canary) # define xEXTENSIONx_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, int32_t __end_canary) # define xEXTENSIONx_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, int32_t __end_canary) # define xEXTENSIONx_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, int32_t __end_canary) # define xEXTENSIONx_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, int32_t __end_canary) # define xEXTENSIONx_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, int32_t __end_canary) # define xEXTENSIONx_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, int32_t __end_canary) # define xEXTENSIONx_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, int32_t __end_canary) # define xEXTENSIONx_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, int32_t __end_canary) # define xEXTENSIONx_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, int32_t __end_canary) # define xEXTENSIONx_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, int32_t __end_canary) # define xEXTENSIONx_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, int32_t __end_canary) # define xEXTENSIONx_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15, int32_t __end_canary) # define xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) \ __ret __func##__real() # define xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__real(__t1 __p1) # define xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__real(__t1 __p1, __t2 __p2) # define xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3) # define xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) # define xEXTENSIONx_FUNC_0ARG_INLINE_SIGNATURE(__ret, __func) \ inline static __ret __func() # define xEXTENSIONx_FUNC_1ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1) \ inline static __ret __func(__t1 __p1) # define xEXTENSIONx_FUNC_2ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ inline static __ret __func(__t1 __p1, __t2 __p2) # define xEXTENSIONx_FUNC_3ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3) # define xEXTENSIONx_FUNC_4ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define xEXTENSIONx_FUNC_5ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define xEXTENSIONx_FUNC_6ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define xEXTENSIONx_FUNC_7ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define xEXTENSIONx_FUNC_8ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define xEXTENSIONx_FUNC_9ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define xEXTENSIONx_FUNC_10ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define xEXTENSIONx_FUNC_11ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define xEXTENSIONx_FUNC_12ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define xEXTENSIONx_FUNC_13ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define xEXTENSIONx_FUNC_14ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define xEXTENSIONx_FUNC_15ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) #endif // BUILDING_xEXTENSIONx_EXTENSION #ifndef BUILDING_xEXTENSIONx_EXTENSION # define xEXTENSIONx_FUNC_0ARG_DECLARE_IMPL(__ret, __func) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, int32_t __end_canary); \ xEXTENSIONx_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func); \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define xEXTENSIONx_FUNC_1ARG_DECLARE_IMPL(__ret, __func, __t1, __p1) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, int32_t __end_canary); \ xEXTENSIONx_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1); \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define xEXTENSIONx_FUNC_2ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, int32_t __end_canary); \ xEXTENSIONx_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2); \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define xEXTENSIONx_FUNC_3ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, int32_t __end_canary); \ xEXTENSIONx_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3); \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define xEXTENSIONx_FUNC_4ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, int32_t __end_canary); \ xEXTENSIONx_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4); \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define xEXTENSIONx_FUNC_5ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, int32_t __end_canary); \ xEXTENSIONx_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5); \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define xEXTENSIONx_FUNC_6ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, int32_t __end_canary); \ xEXTENSIONx_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6); \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define xEXTENSIONx_FUNC_7ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, int32_t __end_canary); \ xEXTENSIONx_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7); \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define xEXTENSIONx_FUNC_8ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, int32_t __end_canary); \ xEXTENSIONx_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8); \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define xEXTENSIONx_FUNC_9ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, int32_t __end_canary); \ xEXTENSIONx_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9); \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define xEXTENSIONx_FUNC_10ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, int32_t __end_canary); \ xEXTENSIONx_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10); \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define xEXTENSIONx_FUNC_11ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, int32_t __end_canary); \ xEXTENSIONx_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11); \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define xEXTENSIONx_FUNC_12ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, int32_t __end_canary); \ xEXTENSIONx_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12); \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define xEXTENSIONx_FUNC_13ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, int32_t __end_canary); \ xEXTENSIONx_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13); \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define xEXTENSIONx_FUNC_14ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, int32_t __end_canary); \ xEXTENSIONx_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14); \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define xEXTENSIONx_FUNC_15ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15, int32_t __end_canary); \ xEXTENSIONx_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15); \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) # define xEXTENSIONx_FUNC_0ARG_DECLARE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_DECLARE_IMPL(__ret, __func) # define xEXTENSIONx_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_DECLARE_IMPL(__ret, __func, __t1, __p1) # define xEXTENSIONx_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2) # define xEXTENSIONx_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define xEXTENSIONx_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define xEXTENSIONx_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define xEXTENSIONx_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define xEXTENSIONx_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define xEXTENSIONx_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define xEXTENSIONx_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define xEXTENSIONx_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define xEXTENSIONx_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define xEXTENSIONx_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define xEXTENSIONx_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define xEXTENSIONx_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define xEXTENSIONx_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) # define xEXTENSIONx_VOID_FUNC_0ARG_DECLARE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_DECLARE_IMPL(__ret, __func) # define xEXTENSIONx_VOID_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_DECLARE_IMPL(__ret, __func, __t1, __p1) # define xEXTENSIONx_VOID_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2) # define xEXTENSIONx_VOID_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define xEXTENSIONx_VOID_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define xEXTENSIONx_VOID_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define xEXTENSIONx_VOID_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define xEXTENSIONx_VOID_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define xEXTENSIONx_VOID_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define xEXTENSIONx_VOID_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define xEXTENSIONx_VOID_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define xEXTENSIONx_VOID_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define xEXTENSIONx_VOID_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define xEXTENSIONx_VOID_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define xEXTENSIONx_VOID_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define xEXTENSIONx_VOID_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #else // BUILDING_xEXTENSIONx_EXTENSION # define xEXTENSIONx_FUNC_0ARG_DECLARE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func); \ xEXTENSIONx_FUNC_0ARG_INLINE_SIGNATURE(__ret, __func) \ { \ return __func##__real(); \ } \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define xEXTENSIONx_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1); \ xEXTENSIONx_FUNC_1ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1) \ { \ return __func##__real(__p1); \ } \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define xEXTENSIONx_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2); \ xEXTENSIONx_FUNC_2ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ { \ return __func##__real(__p1, __p2); \ } \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define xEXTENSIONx_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3); \ xEXTENSIONx_FUNC_3ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ { \ return __func##__real(__p1, __p2, __p3); \ } \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define xEXTENSIONx_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4); \ xEXTENSIONx_FUNC_4ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ { \ return __func##__real(__p1, __p2, __p3, __p4); \ } \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define xEXTENSIONx_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5); \ xEXTENSIONx_FUNC_5ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5); \ } \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define xEXTENSIONx_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6); \ xEXTENSIONx_FUNC_6ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6); \ } \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define xEXTENSIONx_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7); \ xEXTENSIONx_FUNC_7ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7); \ } \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define xEXTENSIONx_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8); \ xEXTENSIONx_FUNC_8ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8); \ } \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define xEXTENSIONx_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9); \ xEXTENSIONx_FUNC_9ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9); \ } \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define xEXTENSIONx_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10); \ xEXTENSIONx_FUNC_10ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10); \ } \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define xEXTENSIONx_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11); \ xEXTENSIONx_FUNC_11ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11); \ } \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define xEXTENSIONx_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12); \ xEXTENSIONx_FUNC_12ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12); \ } \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define xEXTENSIONx_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13); \ xEXTENSIONx_FUNC_13ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13); \ } \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define xEXTENSIONx_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14); \ xEXTENSIONx_FUNC_14ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14); \ } \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define xEXTENSIONx_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15); \ xEXTENSIONx_FUNC_15ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15); \ } \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) # define xEXTENSIONx_VOID_FUNC_0ARG_DECLARE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func); \ xEXTENSIONx_FUNC_0ARG_INLINE_SIGNATURE(__ret, __func) \ { \ return __func##__real(); \ } \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define xEXTENSIONx_VOID_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1); \ xEXTENSIONx_FUNC_1ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1) \ { \ return __func##__real(__p1); \ } \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define xEXTENSIONx_VOID_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2); \ xEXTENSIONx_FUNC_2ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ { \ return __func##__real(__p1, __p2); \ } \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define xEXTENSIONx_VOID_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3); \ xEXTENSIONx_FUNC_3ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ { \ return __func##__real(__p1, __p2, __p3); \ } \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define xEXTENSIONx_VOID_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4); \ xEXTENSIONx_FUNC_4ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ { \ return __func##__real(__p1, __p2, __p3, __p4); \ } \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define xEXTENSIONx_VOID_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5); \ xEXTENSIONx_FUNC_5ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5); \ } \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define xEXTENSIONx_VOID_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6); \ xEXTENSIONx_FUNC_6ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6); \ } \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define xEXTENSIONx_VOID_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7); \ xEXTENSIONx_FUNC_7ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7); \ } \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define xEXTENSIONx_VOID_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8); \ xEXTENSIONx_FUNC_8ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8); \ } \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define xEXTENSIONx_VOID_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9); \ xEXTENSIONx_FUNC_9ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9); \ } \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define xEXTENSIONx_VOID_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10); \ xEXTENSIONx_FUNC_10ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10); \ } \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define xEXTENSIONx_VOID_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11); \ xEXTENSIONx_FUNC_11ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11); \ } \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define xEXTENSIONx_VOID_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12); \ xEXTENSIONx_FUNC_12ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12); \ } \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define xEXTENSIONx_VOID_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13); \ xEXTENSIONx_FUNC_13ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13); \ } \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define xEXTENSIONx_VOID_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14); \ xEXTENSIONx_FUNC_14ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14); \ } \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define xEXTENSIONx_VOID_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15); \ xEXTENSIONx_FUNC_15ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15); \ } \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #endif // BUILDING_xEXTENSIONx_EXTENSION #ifndef BUILDING_xEXTENSIONx_EXTENSION // The __ret__assign and __ret_ref parameters are to work around functions returning void. #define xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, __real__func__par, __stub__func__par) \ { \ void *__handle = XextensionX_library_open(); \ if (__handle) \ { \ static __func##__type func_ptr = NULL; \ if (!func_ptr) \ { \ func_ptr = shlib_load(__handle, #__func "__wrapper"); \ } \ if (func_ptr) \ { \ int __successful = 0; \ __ret__assign func_ptr __real__func__par; \ if (__successful) \ { \ XextensionX_library_close(__handle); \ return __ret__ref; \ } \ } \ XextensionX_library_close(__handle); \ } \ return __func##__stub __stub__func__par; \ } # define xEXTENSIONx_FUNC_0ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref) \ xEXTENSIONx_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, xEXTENSIONx_CANARY_VALUE), \ ()) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define xEXTENSIONx_FUNC_1ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, xEXTENSIONx_CANARY_VALUE), \ (__p1)) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define xEXTENSIONx_FUNC_2ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2)) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define xEXTENSIONx_FUNC_3ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3)) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define xEXTENSIONx_FUNC_4ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4)) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define xEXTENSIONx_FUNC_5ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5)) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define xEXTENSIONx_FUNC_6ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6)) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define xEXTENSIONx_FUNC_7ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7)) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define xEXTENSIONx_FUNC_8ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8)) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define xEXTENSIONx_FUNC_9ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9)) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define xEXTENSIONx_FUNC_10ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10)) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define xEXTENSIONx_FUNC_11ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11)) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define xEXTENSIONx_FUNC_12ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12)) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define xEXTENSIONx_FUNC_13ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13)) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define xEXTENSIONx_FUNC_14ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14)) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define xEXTENSIONx_FUNC_15ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (xEXTENSIONx_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15, xEXTENSIONx_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15)) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value) #define xEXTENSIONx_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1) #define xEXTENSIONx_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2) #define xEXTENSIONx_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_VOID_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_DEFINE_STUB_IMPL(__ret, __func, , ) #define xEXTENSIONx_VOID_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1) #define xEXTENSIONx_VOID_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2) #define xEXTENSIONx_VOID_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_VOID_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_VOID_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_VOID_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_VOID_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_VOID_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_VOID_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_VOID_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_VOID_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_VOID_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_VOID_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_VOID_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_VOID_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_FUNC_DEFINE_REAL_INVALID In_core_code_you_need_to_use_DEFINE_STUB func() #define xEXTENSIONx_FUNC_0ARG_DEFINE(__ret, __func) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_0ARG_DEFINE(__ret, __func) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #define xEXTENSIONx_VOID_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_DEFINE_REAL_INVALID #else // BUILDING_xEXTENSIONx_EXTENSION #define xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL_RET_VALUE(__ret, __func, __real__func__par, __ret__expr) \ { \ if (__start_canary != xEXTENSIONx_CANARY_VALUE || __end_canary != xEXTENSIONx_CANARY_VALUE) \ { \ Log(LOG_LEVEL_ERR, "Function '%s %s%s' failed stack consistency check. Most likely this means the plugin containing the " \ "function is incompatible with this version of CFEngine.", #__ret, #__func, #__real__func__par); \ __ret__expr; \ } \ *__successful = 1; \ return __func __real__func__par; \ } #define xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, __real__func__par) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL_RET_VALUE(__ret, __func, __real__func__par, \ __ret __ret_value = (__ret)0; \ (void)__ret_value; \ return __ret_value) #define xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, __real__func__par) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL_RET_VALUE(__ret, __func, __real__func__par, return) #define xEXTENSIONx_FUNC_DEFINE_INLINE_IMPL(__ret, __func, __real__func__par) \ { \ return __func##__real __real__func__par; \ } #define xEXTENSIONx_FUNC_0ARG_DEFINE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ ()) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define xEXTENSIONx_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1)) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2)) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3)) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4)) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5)) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6)) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7)) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8)) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9)) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10)) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11)) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12)) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13)) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14)) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15)) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_VOID_FUNC_0ARG_DEFINE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ ()) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define xEXTENSIONx_VOID_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1)) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_VOID_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2)) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_VOID_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3)) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_VOID_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4)) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_VOID_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5)) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_VOID_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6)) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_VOID_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7)) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_VOID_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8)) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_VOID_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9)) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_VOID_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10)) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_VOID_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11)) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_VOID_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12)) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_VOID_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13)) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_VOID_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14)) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_VOID_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15)) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_FUNC_DEFINE_STUB_INVALID In_extension_code_you_cannot_define_a_STUB func() #define xEXTENSIONx_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #define xEXTENSIONx_VOID_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_DEFINE_STUB_INVALID #endif // BUILDING_xEXTENSIONx_EXTENSION #else // BUILTIN_EXTENSIONS // In this case just map to real function calls. // BUILTIN_EXTENSIONS is for Windows binaries and debugging. # define xEXTENSIONx_FUNC_0ARG_STUB_SIGNATURE(__ret, __func) \ __ret __func##__stub() # define xEXTENSIONx_FUNC_1ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__stub(__t1 __p1) # define xEXTENSIONx_FUNC_2ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__stub(__t1 __p1, __t2 __p2) # define xEXTENSIONx_FUNC_3ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3) # define xEXTENSIONx_FUNC_4ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define xEXTENSIONx_FUNC_5ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define xEXTENSIONx_FUNC_6ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define xEXTENSIONx_FUNC_7ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define xEXTENSIONx_FUNC_8ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define xEXTENSIONx_FUNC_9ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define xEXTENSIONx_FUNC_10ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define xEXTENSIONx_FUNC_11ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define xEXTENSIONx_FUNC_12ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define xEXTENSIONx_FUNC_13ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define xEXTENSIONx_FUNC_14ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define xEXTENSIONx_FUNC_15ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) # define xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) \ __ret __func() # define xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func(__t1 __p1) # define xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func(__t1 __p1, __t2 __p2) # define xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3) # define xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) #define xEXTENSIONx_FUNC_0ARG_DECLARE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define xEXTENSIONx_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_VOID_FUNC_0ARG_DECLARE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define xEXTENSIONx_VOID_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_VOID_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_VOID_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_VOID_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_VOID_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_VOID_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_VOID_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_VOID_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_VOID_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_VOID_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_VOID_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_VOID_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_VOID_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_VOID_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_VOID_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_FUNC_0ARG_DEFINE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define xEXTENSIONx_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_VOID_FUNC_0ARG_DEFINE(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define xEXTENSIONx_VOID_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_VOID_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_VOID_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_VOID_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_VOID_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_VOID_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_VOID_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_VOID_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_VOID_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_VOID_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_VOID_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_VOID_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_VOID_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_VOID_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_VOID_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_STUB_SIGNATURE(__ret, __func) #define xEXTENSIONx_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define xEXTENSIONx_VOID_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ xEXTENSIONx_FUNC_0ARG_STUB_SIGNATURE(__ret, __func) #define xEXTENSIONx_VOID_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ xEXTENSIONx_FUNC_1ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1) #define xEXTENSIONx_VOID_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ xEXTENSIONx_FUNC_2ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define xEXTENSIONx_VOID_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ xEXTENSIONx_FUNC_3ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define xEXTENSIONx_VOID_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ xEXTENSIONx_FUNC_4ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define xEXTENSIONx_VOID_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ xEXTENSIONx_FUNC_5ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define xEXTENSIONx_VOID_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ xEXTENSIONx_FUNC_6ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define xEXTENSIONx_VOID_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ xEXTENSIONx_FUNC_7ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define xEXTENSIONx_VOID_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ xEXTENSIONx_FUNC_8ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define xEXTENSIONx_VOID_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ xEXTENSIONx_FUNC_9ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define xEXTENSIONx_VOID_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ xEXTENSIONx_FUNC_10ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define xEXTENSIONx_VOID_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ xEXTENSIONx_FUNC_11ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define xEXTENSIONx_VOID_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ xEXTENSIONx_FUNC_12ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define xEXTENSIONx_VOID_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ xEXTENSIONx_FUNC_13ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define xEXTENSIONx_VOID_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ xEXTENSIONx_FUNC_14ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define xEXTENSIONx_VOID_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ xEXTENSIONx_FUNC_15ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #endif // BUILTIN_EXTENSIONS #endif // xEXTENSIONx_EXTENSION_H cfengine-3.24.2/libpromises/locks.h0000644000000000000000000000405415010704253017172 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LOCKS_H #define CFENGINE_LOCKS_H #include CfLock AcquireLock(EvalContext *ctx, const char *operand, const char *host, time_t now, int ifelapsed, int expireafter, const Promise *pp, bool ignoreProcesses); void YieldCurrentLock(CfLock lock); void YieldCurrentLockAndRemoveFromCache(EvalContext *ctx, CfLock lock, const char *operand, const Promise *pp); void GetLockName(char *lockname, const char *locktype, const char *base, const Rlist *params); void PurgeLocks(void); void BackupLockDatabase(void); void RestoreLockDatabase(void); // Used in enterprise/nova code: CF_DB *OpenLock(); void CloseLock(CF_DB *dbp); /* These are only used in ENT! TODO fix and remove from header file. */ void WaitForCriticalSection(const char *section_id); void ReleaseCriticalSection(const char *section_id); void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type); #endif cfengine-3.24.2/libpromises/dbm_migration.c0000644000000000000000000000432115010704253020662 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include extern const DBMigrationFunction dbm_migration_plan_lastseen[]; #ifndef LMDB bool DBMigrate(ARG_UNUSED DBHandle *db, ARG_UNUSED dbid id) { return true; } #else static size_t DBVersion(DBHandle *db) { char version[64]; if (ReadDB(db, "version", version, sizeof(version)) == false) { return 0; } else { return StringToLongDefaultOnError(version, 0); } } static const DBMigrationFunction *const dbm_migration_plans[dbid_max] = { [dbid_lastseen] = dbm_migration_plan_lastseen }; bool DBMigrate(DBHandle *db, dbid id) { const DBMigrationFunction *plan = dbm_migration_plans[id]; if (plan) { size_t step_version = 0; for (const DBMigrationFunction *step = plan; *step; step++, step_version++) { if (step_version == DBVersion(db)) { Seq *seq = SeqNew(1, free); SeqAppend(seq, DBIdToPath(id)); backup_files_copy(seq); SeqDestroy(seq); if (!(*step)(db)) { return false; } } } } return true; } #endif cfengine-3.24.2/libpromises/mod_process.h0000644000000000000000000000217115010704253020372 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_PROCESS_H #define CFENGINE_MOD_PROCESS_H #include extern const PromiseTypeSyntax CF_PROCESS_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/logic_expressions.h0000644000000000000000000000636015010704253021620 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LOGIC_EXPRESSIONS_H #define CFENGINE_LOGIC_EXPRESSIONS_H #include #include /* Logic expressions grammar: ::= ::= | || ::= . & ::= ! ::= ( ) Basis of logic evaluation is values which are provided by StringExpression and suitable string->bool evaluator. */ typedef enum { LOGICAL_OP_OR, LOGICAL_OP_AND, LOGICAL_OP_NOT, LOGICAL_OP_EVAL } LogicalOp; typedef struct Expression_ Expression; struct Expression_ { LogicalOp op; union { struct { Expression *lhs; Expression *rhs; } andor; struct { Expression *arg; } not; struct { StringExpression *name; } eval; } val; }; /* Parsing and evaluation */ /* * Result of parsing. * * if succeeded, then result is the result of parsing and position is last * character consumed. * * if not succeeded, then result is NULL and position is last character consumed * before the error. */ typedef struct { Expression *result; int position; } ParseResult; ParseResult ParseExpression(const char *expr, int start, int end); typedef enum ExpressionValue { EXPRESSION_VALUE_ERROR = -1, EXPRESSION_VALUE_FALSE = false, EXPRESSION_VALUE_TRUE = true, } ExpressionValue; /* * Evaluator should return FALSE, TRUE or ERROR if unable to parse result. In * later case evaluation will be aborted and ERROR will be returned from * EvalExpression. */ typedef ExpressionValue(*NameEvaluator) (const char *name, void *param); /* * Result is heap-allocated. In case evalfn() returns ERROR whole * EvalExpression returns ERROR as well. */ ExpressionValue EvalExpression(const Expression *expr, NameEvaluator nameevalfn, VarRefEvaluator varrefevalfn, void *param); /* * Frees Expression produced by ParseExpression. NULL-safe. */ void FreeExpression(Expression *expr); #endif cfengine-3.24.2/libpromises/files_interfaces.h0000644000000000000000000000236415010704253021366 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_INTERFACES_H #define CFENGINE_FILES_INTERFACES_H #include #include /* AgentConnection */ int cf_lstat(const char *file, struct stat *buf, const FileCopy *fc, AgentConnection *conn); #endif cfengine-3.24.2/libpromises/mod_packages.h0000644000000000000000000000217515010704253020476 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_PACKAGES_H #define CFENGINE_MOD_PACKAGES_H #include extern const PromiseTypeSyntax CF_PACKAGES_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/parser.h0000644000000000000000000000361415010704253017354 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PARSER_H #define CFENGINE_PARSER_H #include #define PARSER_WARNING_DEPRECATED (1 << 0) #define PARSER_WARNING_REMOVED (1 << 1) #define PARSER_WARNING_SANITY_CHECK (1 << 2) #define PARSER_WARNING_ALL 0xfffffff /** * @return warning code, or -1 if not a valid warning */ int ParserWarningFromString(const char *warning_str); const char *ParserWarningToString(unsigned int warning); /** * @brief Parse a CFEngine file to create a Policy DOM * @param agent_type Which agent is parsing the file. The parser will ignore elements not pertitent to its type * @param path Path of file to parse * @param warnings Bitfield of which warnings should be recorded * @param warnings_error Bitfield of which warnings should be counted as errors * @return */ Policy *ParserParseFile(AgentType agent_type, const char *path, unsigned int warnings, unsigned int warnings_error); #endif cfengine-3.24.2/libpromises/class.h0000644000000000000000000000463115010704253017165 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CLASS_H #define CFENGINE_CLASS_H #include #include typedef struct { char *ns; /* NULL in case of default namespace */ char *name; /* class name */ ContextScope scope; bool is_soft; StringSet *tags; char *comment; } Class; typedef struct ClassTable_ ClassTable; typedef struct ClassTableIterator_ ClassTableIterator; ClassTable *ClassTableNew(void); void ClassTableDestroy(ClassTable *table); bool ClassTablePut(ClassTable *table, const char *ns, const char *name, bool is_soft, ContextScope scope, StringSet *tags, const char *comment); Class *ClassTableGet(const ClassTable *table, const char *ns, const char *name); Class *ClassTableMatch(const ClassTable *table, const char *regex); bool ClassTableRemove(ClassTable *table, const char *ns, const char *name); bool ClassTableClear(ClassTable *table); ClassTableIterator *ClassTableIteratorNew(const ClassTable *table, const char *ns, bool is_hard, bool is_soft); Class *ClassTableIteratorNext(ClassTableIterator *iter); void ClassTableIteratorDestroy(ClassTableIterator *iter); typedef struct { char *ns; char *name; } ClassRef; ClassRef ClassRefParse(const char *expr); char *ClassRefToString(const char *ns, const char *name); bool ClassRefIsQualified(ClassRef ref); void ClassRefQualify(ClassRef *ref, const char *ns); void ClassRefDestroy(ClassRef ref); #endif cfengine-3.24.2/libpromises/mod_methods.h0000644000000000000000000000217015010704253020356 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_METHODS_H #define CFENGINE_MOD_METHODS_H #include extern const PromiseTypeSyntax CF_METHOD_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/loading.h0000644000000000000000000000234115010704253017471 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LOADING_H #define CFENGINE_LOADING_H #include #include Policy *LoadPolicy(EvalContext *ctx, GenericAgentConfig *config); Policy *Cf3ParseFile(const GenericAgentConfig *config, const char *input_path); #endif cfengine-3.24.2/libpromises/mod_exec.c0000644000000000000000000000677015010704253017644 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax contain_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("useshell", "noshell,useshell,powershell," CF_BOOL, "noshell/useshell/powershell embed the command in the given shell environment. Default value: noshell", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("umask", "", "The umask value for the child process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("exec_owner", "", "The user name or id under which to run the process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("exec_group", "", "The group name or id under which to run the process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("exec_timeout", "1,3600", "Timeout in seconds for command completion", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("chdir", CF_ABSPATHRANGE, "Directory for setting current/base directory for the process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("chroot", CF_ABSPATHRANGE, "Directory of root sandbox for process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("preview", "true/false preview command when running in dry-run mode (with -n). Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("no_output", "true/false discard all output from the command. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax contain_body = BodySyntaxNew("contain", contain_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax commands_constraints[] = { ConstraintSyntaxNewString("args", "", "Alternative string of arguments for the command (concatenated with promiser string and 'arglist' attribute)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("arglist", CF_ANYSTRING, "Alternative string list of arguments for the command (concatenated with promiser string and 'args' attribute)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("contain", &contain_body, "Containment options for the execution process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("module", "true/false whether to expect the cfengine module protocol. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("inform", "true/false whether to print info messages for command execution. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_EXEC_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "commands", commands_constraints, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/syslog_client.h0000644000000000000000000000251615010704253020736 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SYSLOG_CLIENT_H #define CFENGINE_SYSLOG_CLIENT_H #include /* * This module provides implementation of UDP syslog protocol */ bool SetSyslogHost(const char *host); void SetSyslogPort(uint16_t port); void SetSyslogFacility(int facility); int GetSyslogFacility(); void RemoteSysLog(int log_priority, const char *log_string); #endif cfengine-3.24.2/libpromises/eval_context.h0000644000000000000000000004643415010704253020562 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_EVAL_CONTEXT_H #define CFENGINE_EVAL_CONTEXT_H #include #include #include #include #include #include #include #include #include #include #include #include #include typedef enum { STACK_FRAME_TYPE_BUNDLE, STACK_FRAME_TYPE_BODY, STACK_FRAME_TYPE_BUNDLE_SECTION, STACK_FRAME_TYPE_PROMISE, STACK_FRAME_TYPE_PROMISE_ITERATION, STACK_FRAME_TYPE_MAX } StackFrameType; typedef struct { const Bundle *owner; ClassTable *classes; VariableTable *vars; } StackFrameBundle; typedef struct { const Body *owner; VariableTable *vars; } StackFrameBody; typedef struct { const Promise *owner; VariableTable *vars; } StackFramePromise; typedef struct { const BundleSection *owner; } StackFrameBundleSection; typedef struct { Promise *owner; const PromiseIterator *iter_ctx; size_t index; RingBuffer *log_messages; } StackFramePromiseIteration; typedef struct { StackFrameType type; bool inherits_previous; // whether or not this frame inherits context from the previous frame union { StackFrameBundle bundle; StackFrameBody body; StackFrameBundleSection bundle_section; StackFramePromise promise; StackFramePromiseIteration promise_iteration; } data; char *path; } StackFrame; typedef enum { EVAL_OPTION_NONE = 0, EVAL_OPTION_EVAL_FUNCTIONS = 1 << 0, EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS = 1 << 1, EVAL_OPTION_FULL = 0xFFFFFFFF } EvalContextOption; EvalContext *EvalContextNew(void); void EvalContextDestroy(EvalContext *ctx); void EvalContextSetConfig(EvalContext *ctx, const GenericAgentConfig *config); const GenericAgentConfig *EvalContextGetConfig(EvalContext *ctx); Rlist *EvalContextGetRestrictKeys(const EvalContext *ctx); void EvalContextSetRestrictKeys(EvalContext *ctx, const Rlist *restrict_keys); void EvalContextHeapAddAbort(EvalContext *ctx, const char *context, const char *activated_on_context); void EvalContextHeapAddAbortCurrentBundle(EvalContext *ctx, const char *context, const char *activated_on_context); void EvalContextHeapPersistentSave(EvalContext *ctx, const char *name, unsigned int ttl_minutes, PersistentClassPolicy policy, const char *tags); void EvalContextHeapPersistentRemove(const char *context); void EvalContextHeapPersistentLoadAll(EvalContext *ctx); /** * Sets negated classes (persistent classes that should not be defined). * * @note Takes ownership of #negated_classes */ void EvalContextSetNegatedClasses(EvalContext *ctx, StringSet *negated_classes); bool EvalContextClassPutSoft(EvalContext *ctx, const char *name, ContextScope scope, const char *tags); bool EvalContextClassPutSoftTagsSet(EvalContext *ctx, const char *name, ContextScope scope, StringSet *tags); bool EvalContextClassPutSoftTagsSetWithComment(EvalContext *ctx, const char *name, ContextScope scope, StringSet *tags, const char *comment); bool EvalContextClassPutSoftNS(EvalContext *ctx, const char *ns, const char *name, ContextScope scope, const char *tags); bool EvalContextClassPutSoftNSTagsSet(EvalContext *ctx, const char *ns, const char *name, ContextScope scope, StringSet *tags); bool EvalContextClassPutSoftNSTagsSetWithComment(EvalContext *ctx, const char *ns, const char *name, ContextScope scope, StringSet *tags, const char *comment); bool EvalContextClassPutHard(EvalContext *ctx, const char *name, const char *tags); Class *EvalContextClassGet(const EvalContext *ctx, const char *ns, const char *name); Class *EvalContextClassMatch(const EvalContext *ctx, const char *regex); bool EvalContextClassRemove(EvalContext *ctx, const char *ns, const char *name); StringSet *EvalContextClassTags(const EvalContext *ctx, const char *ns, const char *name); ClassTableIterator *EvalContextClassTableIteratorNewGlobal(const EvalContext *ctx, const char *ns, bool is_hard, bool is_soft); ClassTableIterator *EvalContextClassTableIteratorNewLocal(const EvalContext *ctx); // Class Logging const StringSet *EvalContextAllClassesGet(const EvalContext *ctx); void EvalContextAllClassesLoggingEnable(EvalContext *ctx, bool enable); void EvalContextPushBundleName(const EvalContext *ctx, const char *bundle_name); const StringSet *EvalContextGetBundleNames(const EvalContext *ctx); void EvalContextPushRemoteVarPromise(EvalContext *ctx, const char *bundle_name, const Promise *pp); const Seq *EvalContextGetRemoteVarPromises(const EvalContext *ctx, const char *bundle_name); void EvalContextClear(EvalContext *ctx); Rlist *EvalContextGetPromiseCallerMethods(EvalContext *ctx); void EvalContextStackPushBundleFrame(EvalContext *ctx, const Bundle *owner, const Rlist *args, bool inherits_previous); void EvalContextStackPushBodyFrame(EvalContext *ctx, const Promise *caller, const Body *body, const Rlist *args); void EvalContextStackPushBundleSectionFrame(EvalContext *ctx, const BundleSection *owner); void EvalContextStackPushPromiseFrame(EvalContext *ctx, const Promise *owner); Promise *EvalContextStackPushPromiseIterationFrame(EvalContext *ctx, const PromiseIterator *iter_ctx); void EvalContextStackPopFrame(EvalContext *ctx); const char *EvalContextStackToString(EvalContext *ctx); void EvalContextSetBundleArgs(EvalContext *ctx, const Rlist *args); void EvalContextSetPass(EvalContext *ctx, int pass); Rlist *EvalContextGetBundleArgs(EvalContext *ctx); int EvalContextGetPass(EvalContext *ctx); char *EvalContextStackPath(const EvalContext *ctx); StringSet *EvalContextStackPromisees(const EvalContext *ctx); const Promise *EvalContextStackCurrentPromise(const EvalContext *ctx); const Bundle *EvalContextStackCurrentBundle(const EvalContext *ctx); const RingBuffer *EvalContextStackCurrentMessages(const EvalContext *ctx); Rlist *EvalContextGetPromiseCallerMethods(EvalContext *ctx); JsonElement *EvalContextGetPromiseCallers(EvalContext *ctx); bool EvalContextVariablePut(EvalContext *ctx, const VarRef *ref, const void *value, DataType type, const char *tags); bool EvalContextVariablePutTagsSet(EvalContext *ctx, const VarRef *ref, const void *value, DataType type, StringSet *tags); bool EvalContextVariablePutTagsSetWithComment(EvalContext *ctx, const VarRef *ref, const void *value, DataType type, StringSet *tags, const char *comment); bool EvalContextVariablePutSpecial(EvalContext *ctx, SpecialScope scope, const char *lval, const void *value, DataType type, const char *tags); bool EvalContextVariablePutSpecialTagsSet(EvalContext *ctx, SpecialScope scope, const char *lval, const void *value, DataType type, StringSet *tags); bool EvalContextVariablePutSpecialTagsSetWithComment(EvalContext *ctx, SpecialScope scope, const char *lval, const void *value, DataType type, StringSet *tags, const char *comment); const void *EvalContextVariableGetSpecial(const EvalContext *ctx, const SpecialScope scope, const char *varname, DataType *type_out); const char *EvalContextVariableGetSpecialString(const EvalContext *ctx, const SpecialScope scope, const char *varname); const void *EvalContextVariableGet(const EvalContext *ctx, const VarRef *ref, DataType *type_out); const Promise *EvalContextVariablePromiseGet(const EvalContext *ctx, const VarRef *ref); bool EvalContextVariableRemoveSpecial(const EvalContext *ctx, SpecialScope scope, const char *lval); bool EvalContextVariableRemove(const EvalContext *ctx, const VarRef *ref); StringSet *EvalContextVariableTags(const EvalContext *ctx, const VarRef *ref); bool EvalContextVariableClearMatch(EvalContext *ctx); VariableTableIterator *EvalContextVariableTableIteratorNew(const EvalContext *ctx, const char *ns, const char *scope, const char *lval); VariableTableIterator *EvalContextVariableTableFromRefIteratorNew(const EvalContext *ctx, const VarRef *ref); bool EvalContextPromiseLockCacheContains(const EvalContext *ctx, const char *key); void EvalContextPromiseLockCachePut(EvalContext *ctx, const char *key); void EvalContextPromiseLockCacheRemove(EvalContext *ctx, const char *key); bool EvalContextFunctionCacheGet(const EvalContext *ctx, const FnCall *fp, const Rlist *args, Rval *rval_out); void EvalContextFunctionCachePut(EvalContext *ctx, const FnCall *fp, const Rlist *args, const Rval *rval); const void *EvalContextVariableControlCommonGet(const EvalContext *ctx, CommonControl lval); /** * @brief Find a bundle for a bundle call, given a callee reference (in the form of ns:bundle), and a type of bundle. * This is requires EvalContext because the callee reference may be unqualified. * Hopefully this should go away in the future if we make a more generalized API to simply call a bundle, * but we have a few special rules around edit_line and so on. */ const Bundle *EvalContextResolveBundleExpression(const EvalContext *ctx, const Policy *policy, const char *callee_reference, const char *callee_type); const Body *EvalContextFindFirstMatchingBody(const Policy *policy, const char *type, const char *namespace, const char *name); /** @brief Returns a Sequence of const Body* elements, first the body and then its parents Uses `inherit_from` to figure out the parents. */ Seq *EvalContextResolveBodyExpression(const EvalContext *ctx, const Policy *policy, const char *callee_reference, const char *callee_type); /* - Parsing/evaluating expressions - */ void ValidateClassSyntax(const char *str); ExpressionValue CheckClassExpression(const EvalContext *ctx, const char *context); static inline bool IsDefinedClass(const EvalContext *ctx, const char *context) { return (CheckClassExpression(ctx, context) == EXPRESSION_VALUE_TRUE); } StringSet *ClassesMatching(const EvalContext *ctx, ClassTableIterator *iter, const char* regex, const Rlist *tags, bool first_only); StringSet *ClassesMatchingGlobal(const EvalContext *ctx, const char* regex, const Rlist *tags, bool first_only); StringSet *ClassesMatchingLocal(const EvalContext *ctx, const char* regex, const Rlist *tags, bool first_only); bool EvalProcessResult(const char *process_result, StringSet *proc_attr); bool EvalFileResult(const char *file_result, StringSet *leaf_attr); /** * @brief Evaluates a class expression based on a set of defined classes. * @param expr Class expression (E.g. "GMT_Monday|GMT_Wednesday"). * @param token_set Set of defined classes. * @return True if the class expression evaluates to true, otherwise false. */ bool EvalWithTokenFromList(const char *expr, StringSet *token_set); /* Various global options */ void SetChecksumUpdatesDefault(EvalContext *ctx, bool enabled); bool GetChecksumUpdatesDefault(const EvalContext *ctx); /* IP addresses */ Item *EvalContextGetIpAddresses(const EvalContext *ctx); void EvalContextAddIpAddress(EvalContext *ctx, const char *address, const char *iface); void EvalContextDeleteIpAddresses(EvalContext *ctx); /* - Rest - */ void EvalContextSetEvalOption(EvalContext *ctx, EvalContextOption option, bool value); bool EvalContextGetEvalOption(EvalContext *ctx, EvalContextOption option); bool EvalContextIsIgnoringLocks(const EvalContext *ctx); void EvalContextSetIgnoreLocks(EvalContext *ctx, bool ignore); void EvalContextSetLaunchDirectory(EvalContext *ctx, const char *path); void EvalContextSetEntryPoint(EvalContext* ctx, const char *entry_point); const char *EvalContextGetEntryPoint(EvalContext* ctx); bool BundleAbort(EvalContext *ctx); bool EvalAborted(const EvalContext *ctx); void NotifyDependantPromises(EvalContext *ctx, const Promise *pp, PromiseResult result); bool MissingDependencies(EvalContext *ctx, const Promise *pp); /** * Record promise status (result). * * This function should be called once for every promise to record its * status/result. It logs the given message (#fmt and varargs) with the given * #level based on the logging specifications in the 'action' body and * increments the counters of actuated promises and promises * kept/repaired/failed/... * * If #fmt is NULL or an empty string, nothing is logged. #level should be * #LOG_LEVEL_NOTHING in such cases. */ void cfPS(EvalContext *ctx, LogLevel level, PromiseResult status, const Promise *pp, const Attributes *attr, const char *fmt, ...) FUNC_ATTR_PRINTF(6, 7); /** * Log change done by the agent when evaluating policy and set the outcome * classes. * * Unlike cfPS(), this function is expected to be called multiple times for the * same promise. It's not recording a promise status, but rather one out of * multiple changes done by the given promise. */ void RecordChange(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) FUNC_ATTR_PRINTF(4, 5); void RecordNoChange(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) FUNC_ATTR_PRINTF(4, 5); void RecordFailure(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) FUNC_ATTR_PRINTF(4, 5); void RecordWarning(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) FUNC_ATTR_PRINTF(4, 5); void RecordDenial(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) FUNC_ATTR_PRINTF(4, 5); void RecordInterruption(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) FUNC_ATTR_PRINTF(4, 5); /** * Check if the given promise is allowed to make changes in the current agent * run and if not, log the fact and update #result accordingly. * * The #change_desc_fmt argument and the ones following it should format a * message that describes the action, like "rename the file '/etc/issue'", the * implementation of this function prepends and, potentially, appends text to * the message to form a complete sentence. */ bool MakingChanges(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *change_desc_fmt, ...) FUNC_ATTR_PRINTF(5, 6); /** * Similar to MakingChanges() above, but checking if changes to internal * structures are allowed. Audit modes should, for example, not make such * changes, even though they make other changes (in a changes chroot). */ bool MakingInternalChanges(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *change_desc_fmt, ...) FUNC_ATTR_PRINTF(5, 6); /** * Whether to make changes in a chroot or not. */ static inline bool ChrootChanges() { return ((EVAL_MODE == EVAL_MODE_SIMULATE_DIFF) || (EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST) || (EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST_FULL)); } /** * Set the chroot for recording changes in files (in simulate mode(s)). * * @note This function should only be called once. */ void SetChangesChroot(const char *chroot); /** * Get the path for #orig_path under the changes chroot (where changes in simulate * mode(s) are done). #orig_path is expected to be an absolute path. * * @note Returns a pointer to an internal buffer and the value is only valid * until the function is called again. * @warning not thread-safe */ const char *ToChangesChroot(const char *orig_path); /** * Possibly transform #path to the path where changes are to be made. * @see ChrootChanges() * @see ToChangesChroot() */ static inline const char *ToChangesPath(const char *path) { return (ChrootChanges() ? ToChangesChroot(path) : path); } /** * Reverse operation for ToChangesChroot(). * * @return A pointer to an offset of #orig_path where the non-chrooted path starts. * @warning Doesn't work on Windows (because on Windows the operation is not as easy as just * shifting the pointer by the offset). */ #ifndef __MINGW32__ const char *ToNormalRoot(const char *orig_path); #else const char *ToNormalRoot(const char *orig_path) __attribute__((error ("Not supported on Windows"))); #endif PackagePromiseContext *GetPackageDefaultsFromCtx(const EvalContext *ctx); bool EvalContextGetSelectEndMatchEof(const EvalContext *ctx); void EvalContextSetSelectEndMatchEof(EvalContext *ctx, bool value); void AddDefaultPackageModuleToContext(const EvalContext *ctx, char *name); void AddDefaultInventoryToContext(const EvalContext *ctx, Rlist *inventory); void AddPackageModuleToContext(const EvalContext *ctx, PackageModuleBody *pm); PackageModuleBody *GetPackageModuleFromContext(const EvalContext *ctx, const char *name); PackageModuleBody *GetDefaultPackageModuleFromContext(const EvalContext *ctx); Rlist *GetDefaultInventoryFromContext(const EvalContext *ctx); PackagePromiseContext *GetPackagePromiseContext(const EvalContext *ctx); /* This function is temporarily exported. It needs to be made an detail of * evaluator again, once variables promises are no longer specially handled */ void ClassAuditLog(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult status); /** * Set classes based on the promise outcome/result. * * @note This function should only be called in special cases, ClassAuditLog() * (which calls this function internally) should be called in most places. */ void SetPromiseOutcomeClasses(EvalContext *ctx, PromiseResult status, const DefineClasses *dc); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, TrackTotalCompliance, ARG_UNUSED PromiseResult, status, ARG_UNUSED const Promise *, pp); ENTERPRISE_VOID_FUNC_3ARG_DECLARE(void, EvalContextLogPromiseIterationOutcome, EvalContext *, ctx, const Promise *, pp, PromiseResult, result); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, EvalContextSetupMissionPortalLogHook, EvalContext *, ctx); char *MissionPortalLogHook(LoggingPrivContext *pctx, LogLevel level, const char *message); JsonElement* JsonExpandElement(EvalContext *ctx, const JsonElement *source); void EvalContextSetDumpReports(EvalContext *ctx, bool dump_reports); bool EvalContextGetDumpReports(EvalContext *ctx); void EvalContextUpdateDumpReports(EvalContext *ctx); #endif cfengine-3.24.2/libpromises/attributes.c0000644000000000000000000020241615010704253020242 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include // ParseProtocolVersionPolicy() #include /* StringEqual() */ #define CF_DEFINECLASSES "classes" #define CF_TRANSACTION "action" static FilePerms GetPermissionConstraints(const EvalContext *ctx, const Promise *pp); static TransactionContext GetTransactionConstraints(const EvalContext *ctx, const Promise *pp); void ClearFilesAttributes(Attributes *whom) { UidListDestroy(whom->perms.owners); GidListDestroy(whom->perms.groups); } Attributes GetFilesAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; // default for file copy attr.havedepthsearch = PromiseGetConstraintAsBoolean(ctx, "depth_search", pp); attr.haveselect = PromiseGetConstraintAsBoolean(ctx, "file_select", pp); attr.haverename = PromiseGetConstraintAsBoolean(ctx, "rename", pp); attr.havedelete = PromiseGetConstraintAsBoolean(ctx, "delete", pp); attr.content = PromiseGetConstraintAsRval(pp, "content", RVAL_TYPE_SCALAR); attr.haveperms = PromiseGetConstraintAsBoolean(ctx, "perms", pp); attr.havechange = PromiseGetConstraintAsBoolean(ctx, "changes", pp); attr.havecopy = PromiseGetConstraintAsBoolean(ctx, "copy_from", pp); attr.havelink = PromiseGetConstraintAsBoolean(ctx, "link_from", pp); attr.edit_template = PromiseGetConstraintAsRval(pp, "edit_template", RVAL_TYPE_SCALAR); attr.edit_template_string = PromiseGetConstraintAsRval(pp, "edit_template_string", RVAL_TYPE_SCALAR); attr.template_method = PromiseGetConstraintAsRval(pp, "template_method", RVAL_TYPE_SCALAR); attr.template_data = PromiseGetConstraintAsRval(pp, "template_data", RVAL_TYPE_CONTAINER); if (!attr.template_method ) { attr.template_method = "cfengine"; } attr.haveeditline = PromiseBundleOrBodyConstraintExists(ctx, "edit_line", pp); attr.haveeditxml = PromiseBundleOrBodyConstraintExists(ctx, "edit_xml", pp); attr.haveedit = (attr.haveeditline) || (attr.haveeditxml) || (attr.edit_template) || (attr.edit_template_string); /* Files, specialist */ attr.repository = PromiseGetConstraintAsRval(pp, "repository", RVAL_TYPE_SCALAR); attr.create = PromiseGetConstraintAsBoolean(ctx, "create", pp); attr.touch = PromiseGetConstraintAsBoolean(ctx, "touch", pp); attr.transformer = PromiseGetConstraintAsRval(pp, "transformer", RVAL_TYPE_SCALAR); attr.move_obstructions = PromiseGetConstraintAsBoolean(ctx, "move_obstructions", pp); attr.pathtype = PromiseGetConstraintAsRval(pp, "pathtype", RVAL_TYPE_SCALAR); attr.file_type = PromiseGetConstraintAsRval(pp, "file_type", RVAL_TYPE_SCALAR); attr.acl = GetAclConstraints(ctx, pp); attr.perms = GetPermissionConstraints(ctx, pp); attr.select = GetSelectConstraints(ctx, pp); attr.delete = GetDeleteConstraints(ctx, pp); attr.rename = GetRenameConstraints(ctx, pp); attr.change = GetChangeMgtConstraints(ctx, pp); attr.copy = GetCopyConstraints(ctx, pp); attr.link = GetLinkConstraints(ctx, pp); attr.edits = GetEditDefaults(ctx, pp); if (attr.edit_template || attr.edit_template_string) { attr.edits.empty_before_use = true; attr.edits.inherit = true; } /* Files, multiple use */ attr.recursion = GetRecursionConstraints(ctx, pp); /* Common ("included") */ attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetReportsAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.transaction = GetTransactionConstraints(ctx, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); attr.report = GetReportConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetEnvironmentsAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.transaction = GetTransactionConstraints(ctx, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); attr.env = GetEnvironmentsConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetServicesAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.transaction = GetTransactionConstraints(ctx, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); attr.service = GetServicesConstraints(ctx, pp); attr.havebundle = PromiseBundleOrBodyConstraintExists(ctx, "service_bundle", pp); return attr; } /*******************************************************************/ Attributes GetPackageAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.transaction = GetTransactionConstraints(ctx, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); attr.packages = GetPackageConstraints(ctx, pp); attr.new_packages = GetNewPackageConstraints(ctx, pp); return attr; } /*******************************************************************/ static User GetUserConstraints(const EvalContext *ctx, const Promise *pp) { User u; char *value; value = PromiseGetConstraintAsRval(pp, "policy", RVAL_TYPE_SCALAR); u.policy = UserStateFromString(value); u.uid = PromiseGetConstraintAsRval(pp, "uid", RVAL_TYPE_SCALAR); value = PromiseGetConstraintAsRval(pp, "format", RVAL_TYPE_SCALAR); u.password_format = PasswordFormatFromString(value); u.password = PromiseGetConstraintAsRval(pp, "data", RVAL_TYPE_SCALAR); u.description = PromiseGetConstraintAsRval(pp, "description", RVAL_TYPE_SCALAR); u.group_primary = PromiseGetConstraintAsRval(pp, "group_primary", RVAL_TYPE_SCALAR); u.home_dir = PromiseGetConstraintAsRval(pp, "home_dir", RVAL_TYPE_SCALAR); u.shell = PromiseGetConstraintAsRval(pp, "shell", RVAL_TYPE_SCALAR); u.groups_secondary = PromiseGetConstraintAsList(ctx, "groups_secondary", pp); const Constraint *cp = PromiseGetImmediateConstraint(pp, "groups_secondary"); u.groups_secondary_given = (cp != NULL); if (value && ((u.policy) == USER_STATE_NONE)) { Log(LOG_LEVEL_ERR, "Unsupported user policy '%s' in users promise", value); PromiseRef(LOG_LEVEL_ERR, pp); } return u; } Attributes GetUserAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.havebundle = PromiseBundleOrBodyConstraintExists(ctx, "home_bundle", pp); attr.inherit = PromiseGetConstraintAsBoolean(ctx, "home_bundle_inherit", pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); attr.users = GetUserConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetDatabaseAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.transaction = GetTransactionConstraints(ctx, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); attr.database = GetDatabaseConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetClassContextAttributes(const EvalContext *ctx, const Promise *pp) { Attributes a = ZeroAttributes; a.transaction = GetTransactionConstraints(ctx, pp); a.classes = GetClassDefinitionConstraints(ctx, pp); a.context = GetContextConstraints(ctx, pp); return a; } /*******************************************************************/ Attributes GetExecAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.contain = GetExecContainConstraints(ctx, pp); attr.havecontain = PromiseGetConstraintAsBoolean(ctx, "contain", pp); attr.args = PromiseGetConstraintAsRval(pp, "args", RVAL_TYPE_SCALAR); attr.arglist = PromiseGetConstraintAsList(ctx, "arglist", pp); attr.module = PromiseGetConstraintAsBoolean(ctx, "module", pp); // Possible to suppress info level messages per commands promise: if (PromiseBundleOrBodyConstraintExists(ctx, "inform", pp)) { attr.inform = PromiseGetConstraintAsBoolean(ctx, "inform", pp); } else { attr.inform = true; // Default to printing the inform messages } /* Common ("included") */ attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetProcessAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.signals = PromiseGetConstraintAsList(ctx, "signals", pp); attr.process_stop = PromiseGetConstraintAsRval(pp, "process_stop", RVAL_TYPE_SCALAR); attr.haveprocess_count = PromiseGetConstraintAsBoolean(ctx, "process_count", pp); attr.haveselect = PromiseGetConstraintAsBoolean(ctx, "process_select", pp); attr.restart_class = PromiseGetConstraintAsRval(pp, "restart_class", RVAL_TYPE_SCALAR); attr.process_count = GetMatchesConstraints(ctx, pp); attr.process_select = GetProcessFilterConstraints(ctx, pp); /* Common ("included") */ attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetStorageAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.mount = GetMountConstraints(ctx, pp); attr.volume = GetVolumeConstraints(ctx, pp); attr.havevolume = PromiseGetConstraintAsBoolean(ctx, "volume", pp); attr.havemount = PromiseGetConstraintAsBoolean(ctx, "mount", pp); /* Common ("included") */ if (attr.edits.maxfilesize <= 0) { attr.edits.maxfilesize = EDITFILESIZE; } attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetMethodAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.havebundle = PromiseBundleOrBodyConstraintExists(ctx, "usebundle", pp); attr.inherit = PromiseGetConstraintAsBoolean(ctx, "inherit", pp); /* Common ("included") */ attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } Attributes GetMeasurementAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.measure = GetMeasurementConstraint(ctx, pp); /* Common ("included") */ attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ /* Level */ /*******************************************************************/ Services GetServicesConstraints(const EvalContext *ctx, const Promise *pp) { Services s; s.service_type = PromiseGetConstraintAsRval(pp, "service_type", RVAL_TYPE_SCALAR); s.service_policy = PromiseGetConstraintAsRval(pp, "service_policy", RVAL_TYPE_SCALAR); s.service_autostart_policy = PromiseGetConstraintAsRval(pp, "service_autostart_policy", RVAL_TYPE_SCALAR); s.service_args = PromiseGetConstraintAsRval(pp, "service_args", RVAL_TYPE_SCALAR); s.service_depend = PromiseGetConstraintAsList(ctx, "service_dependencies", pp); s.service_depend_chain = PromiseGetConstraintAsRval(pp, "service_dependence_chain", RVAL_TYPE_SCALAR); return s; } /*******************************************************************/ Environments GetEnvironmentsConstraints(const EvalContext *ctx, const Promise *pp) { Environments e; e.cpus = PromiseGetConstraintAsInt(ctx, "env_cpus", pp); e.memory = PromiseGetConstraintAsInt(ctx, "env_memory", pp); e.disk = PromiseGetConstraintAsInt(ctx, "env_disk", pp); e.baseline = PromiseGetConstraintAsRval(pp, "env_baseline", RVAL_TYPE_SCALAR); e.spec = PromiseGetConstraintAsRval(pp, "env_spec", RVAL_TYPE_SCALAR); e.host = PromiseGetConstraintAsRval(pp, "environment_host", RVAL_TYPE_SCALAR); e.addresses = PromiseGetConstraintAsList(ctx, "env_addresses", pp); e.name = PromiseGetConstraintAsRval(pp, "env_name", RVAL_TYPE_SCALAR); e.type = PromiseGetConstraintAsRval(pp, "environment_type", RVAL_TYPE_SCALAR); e.state = EnvironmentStateFromString(PromiseGetConstraintAsRval(pp, "environment_state", RVAL_TYPE_SCALAR)); return e; } /*******************************************************************/ ExecContain GetExecContainConstraints(const EvalContext *ctx, const Promise *pp) { ExecContain e; e.shelltype = ShellTypeFromString(PromiseGetConstraintAsRval(pp, "useshell", RVAL_TYPE_SCALAR)); e.umask = PromiseGetConstraintAsOctal(ctx, "umask", pp); e.owner = PromiseGetConstraintAsUid(ctx, "exec_owner", pp); e.group = PromiseGetConstraintAsGid(ctx, "exec_group", pp); e.preview = PromiseGetConstraintAsBoolean(ctx, "preview", pp); if (PromiseBundleOrBodyConstraintExists(ctx, "no_output", pp)) { e.nooutput = PromiseGetConstraintAsBoolean(ctx, "no_output", pp); } else { e.nooutput = PromiseGetConstraintAsBoolean(ctx, "module", pp); } e.timeout = PromiseGetConstraintAsInt(ctx, "exec_timeout", pp); e.chroot = PromiseGetConstraintAsRval(pp, "chroot", RVAL_TYPE_SCALAR); e.chdir = PromiseGetConstraintAsRval(pp, "chdir", RVAL_TYPE_SCALAR); return e; } /*******************************************************************/ DirectoryRecursion GetRecursionConstraints(const EvalContext *ctx, const Promise *pp) { DirectoryRecursion r; r.travlinks = PromiseGetConstraintAsBoolean(ctx, "traverse_links", pp); r.rmdeadlinks = PromiseGetConstraintAsBoolean(ctx, "rmdeadlinks", pp); r.depth = PromiseGetConstraintAsInt(ctx, "depth", pp); if (r.depth == CF_NOINT) { r.depth = 0; } r.xdev = PromiseGetConstraintAsBoolean(ctx, "xdev", pp); r.include_dirs = PromiseGetConstraintAsList(ctx, "include_dirs", pp); r.exclude_dirs = PromiseGetConstraintAsList(ctx, "exclude_dirs", pp); r.include_basedir = PromiseGetConstraintAsBoolean(ctx, "include_basedir", pp); return r; } /*******************************************************************/ Acl GetAclConstraints(const EvalContext *ctx, const Promise *pp) { Acl ac; ac.acl_method = AclMethodFromString(PromiseGetConstraintAsRval(pp, "acl_method", RVAL_TYPE_SCALAR)); ac.acl_type = AclTypeFromString(PromiseGetConstraintAsRval(pp, "acl_type", RVAL_TYPE_SCALAR)); ac.acl_default = AclDefaultFromString(PromiseGetConstraintAsRval(pp, "acl_default", RVAL_TYPE_SCALAR)); if (ac.acl_default == ACL_DEFAULT_NONE) { /* Deprecated attribute. */ ac.acl_default = AclDefaultFromString(PromiseGetConstraintAsRval(pp, "acl_directory_inherit", RVAL_TYPE_SCALAR)); } ac.acl_entries = PromiseGetConstraintAsList(ctx, "aces", pp); ac.acl_default_entries = PromiseGetConstraintAsList(ctx, "specify_default_aces", pp); if (ac.acl_default_entries == NULL) { /* Deprecated attribute. */ ac.acl_default_entries = PromiseGetConstraintAsList(ctx, "specify_inherit_aces", pp); } ac.acl_inherit = AclInheritFromString(PromiseGetConstraintAsRval(pp, "acl_inherit", RVAL_TYPE_SCALAR)); return ac; } /*******************************************************************/ static FilePerms GetPermissionConstraints(const EvalContext *ctx, const Promise *pp) { FilePerms p; char *mode_value; Rlist *list; mode_value = PromiseGetConstraintAsRval(pp, "mode", RVAL_TYPE_SCALAR); p.plus = CF_SAMEMODE; p.minus = CF_SAMEMODE; if (!ParseModeString(mode_value, &p.plus, &p.minus)) { Log(LOG_LEVEL_ERR, "Problem validating a mode string"); PromiseRef(LOG_LEVEL_ERR, pp); } list = PromiseGetConstraintAsList(ctx, "bsdflags", pp); p.plus_flags = 0; p.minus_flags = 0; if (list && (!ParseFlagString(list, &p.plus_flags, &p.minus_flags))) { Log(LOG_LEVEL_ERR, "Problem validating a BSD flag string"); PromiseRef(LOG_LEVEL_ERR, pp); } p.owners = Rlist2UidList((Rlist *) PromiseGetConstraintAsRval(pp, "owners", RVAL_TYPE_LIST), pp); p.groups = Rlist2GidList((Rlist *) PromiseGetConstraintAsRval(pp, "groups", RVAL_TYPE_LIST), pp); p.findertype = PromiseGetConstraintAsRval(pp, "findertype", RVAL_TYPE_SCALAR); p.rxdirs = PromiseGetConstraintAsBooleanWithDefault(ctx, "rxdirs", pp, false, (mode_value != NULL)); return p; } /*******************************************************************/ FileSelect GetSelectConstraints(const EvalContext *ctx, const Promise *pp) { FileSelect s; char *value; Rlist *rp; mode_t plus, minus; u_long fplus, fminus; int entries = false; s.name = (Rlist *) PromiseGetConstraintAsRval(pp, "leaf_name", RVAL_TYPE_LIST); s.path = (Rlist *) PromiseGetConstraintAsRval(pp, "path_name", RVAL_TYPE_LIST); s.filetypes = (Rlist *) PromiseGetConstraintAsRval(pp, "file_types", RVAL_TYPE_LIST); s.issymlinkto = (Rlist *) PromiseGetConstraintAsRval(pp, "issymlinkto", RVAL_TYPE_LIST); s.perms = PromiseGetConstraintAsList(ctx, "search_mode", pp); for (rp = s.perms; rp != NULL; rp = rp->next) { plus = 0; minus = 0; value = RlistScalarValue(rp); if (!ParseModeString(value, &plus, &minus)) { Log(LOG_LEVEL_ERR, "Problem validating a mode string"); PromiseRef(LOG_LEVEL_ERR, pp); } } s.bsdflags = PromiseGetConstraintAsList(ctx, "search_bsdflags", pp); fplus = 0; fminus = 0; if (!ParseFlagString(s.bsdflags, &fplus, &fminus)) { Log(LOG_LEVEL_ERR, "Problem validating a BSD flag string"); PromiseRef(LOG_LEVEL_ERR, pp); } if ((s.name) || (s.path) || (s.filetypes) || (s.issymlinkto) || (s.perms) || (s.bsdflags)) { entries = true; } s.owners = (Rlist *) PromiseGetConstraintAsRval(pp, "search_owners", RVAL_TYPE_LIST); s.groups = (Rlist *) PromiseGetConstraintAsRval(pp, "search_groups", RVAL_TYPE_LIST); value = PromiseGetConstraintAsRval(pp, "search_size", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, (long *) &s.min_size, (long *) &s.max_size)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "ctime", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, (long *) &s.min_ctime, (long *) &s.max_ctime)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "atime", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, (long *) &s.min_atime, (long *) &s.max_atime)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "mtime", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, (long *) &s.min_mtime, (long *) &s.max_mtime)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } s.exec_regex = PromiseGetConstraintAsRval(pp, "exec_regex", RVAL_TYPE_SCALAR); s.exec_program = PromiseGetConstraintAsRval(pp, "exec_program", RVAL_TYPE_SCALAR); if ((s.owners) || (s.min_size) || (s.exec_regex) || (s.exec_program)) { entries = true; } if ((s.result = PromiseGetConstraintAsRval(pp, "file_result", RVAL_TYPE_SCALAR)) == NULL) { if (!entries) { Log(LOG_LEVEL_ERR, "file_select body missing its a file_result return value"); } } return s; } /*******************************************************************/ LogLevel ActionAttributeLogLevelFromString(const char *log_level) { if (!log_level) { return LOG_LEVEL_ERR; } if (StringEqual(log_level, "inform") || StringEqual(log_level, "info")) { return LOG_LEVEL_INFO; } else if (StringEqual(log_level, "verbose")) { return LOG_LEVEL_VERBOSE; } else if (StringEqual(log_level, "error") || StringEqual(log_level, "log")) { /* XXX: what is 'log' and why is it the same as 'error'? */ return LOG_LEVEL_ERR; } else { Log(LOG_LEVEL_WARNING, "Unrecognized 'log_level' attribute value: %s", log_level); return LOG_LEVEL_ERR; } } static TransactionContext GetTransactionConstraints(const EvalContext *ctx, const Promise *pp) { TransactionContext t; char *value; value = PromiseGetConstraintAsRval(pp, "action_policy", RVAL_TYPE_SCALAR); if (value && ((strcmp(value, "warn") == 0) || (strcmp(value, "nop") == 0))) { t.action = cfa_warn; } else { t.action = cfa_fix; // default } t.background = PromiseGetConstraintAsBoolean(ctx, "background", pp); t.ifelapsed = PromiseGetConstraintAsInt(ctx, "ifelapsed", pp); t.expireafter = PromiseGetConstraintAsInt(ctx, "expireafter", pp); /* Warn if promise locking was used with a promise that doesn't support it. * XXX: EvalContextGetPass() takes 'EvalContext *' instead of 'const EvalContext *'*/ if ((strcmp("access", PromiseGetPromiseType(pp)) == 0 || strcmp("classes", PromiseGetPromiseType(pp)) == 0 || strcmp("defaults", PromiseGetPromiseType(pp)) == 0 || strcmp("meta", PromiseGetPromiseType(pp)) == 0 || strcmp("roles", PromiseGetPromiseType(pp)) == 0 || strcmp("vars", PromiseGetPromiseType(pp)) == 0)) { if (t.ifelapsed != CF_NOINT) { Log(LOG_LEVEL_WARNING, "ifelapsed attribute specified in action body for %s promise '%s'," " but %s promises do not support promise locking", PromiseGetPromiseType(pp), pp->promiser, PromiseGetPromiseType(pp)); } if (t.expireafter != CF_NOINT) { Log(LOG_LEVEL_WARNING, "expireafter attribute specified in action body for %s promise '%s'," " but %s promises do not support promise locking", PromiseGetPromiseType(pp), pp->promiser, PromiseGetPromiseType(pp)); } } if (t.ifelapsed == CF_NOINT) { t.ifelapsed = VIFELAPSED; } if (t.expireafter == CF_NOINT) { t.expireafter = VEXPIREAFTER; } t.audit = PromiseGetConstraintAsBoolean(ctx, "audit", pp); t.log_string = PromiseGetConstraintAsRval(pp, "log_string", RVAL_TYPE_SCALAR); t.log_priority = SyslogPriorityFromString(PromiseGetConstraintAsRval(pp, "log_priority", RVAL_TYPE_SCALAR)); t.log_kept = PromiseGetConstraintAsRval(pp, "log_kept", RVAL_TYPE_SCALAR); t.log_repaired = PromiseGetConstraintAsRval(pp, "log_repaired", RVAL_TYPE_SCALAR); t.log_failed = PromiseGetConstraintAsRval(pp, "log_failed", RVAL_TYPE_SCALAR); value = PromiseGetConstraintAsRval(pp, "log_level", RVAL_TYPE_SCALAR); t.log_level = ActionAttributeLogLevelFromString(value); value = PromiseGetConstraintAsRval(pp, "report_level", RVAL_TYPE_SCALAR); t.report_level = ActionAttributeLogLevelFromString(value); t.measure_id = PromiseGetConstraintAsRval(pp, "measurement_class", RVAL_TYPE_SCALAR); return t; } /*******************************************************************/ bool IsClassesBodyConstraint(const char *constraint) { return ( StringEqual(constraint, "classes") || StringEqual(constraint, "classes_name") || StringEqual(constraint, "scope") || StringEqual(constraint, "promise_repaired") || StringEqual(constraint, "repair_failed") || StringEqual(constraint, "repair_denied") || StringEqual(constraint, "repair_timeout") || StringEqual(constraint, "promise_kept") || StringEqual(constraint, "cancel_repaired") || StringEqual(constraint, "cancel_kept") || StringEqual(constraint, "cancel_notkept") || StringEqual(constraint, "kept_returncodes") || StringEqual(constraint, "repaired_returncodes") || StringEqual(constraint, "failed_returncodes") || StringEqual(constraint, "persist_time") || StringEqual(constraint, "timer_policy") ); } DefineClasses GetClassDefinitionConstraints(const EvalContext *ctx, const Promise *pp) { DefineClasses c; char *pt = NULL; { const char *context_scope = PromiseGetConstraintAsRval(pp, "scope", RVAL_TYPE_SCALAR); c.scope = ContextScopeFromString(context_scope); } c.change = (Rlist *) PromiseGetConstraintAsList(ctx, "promise_repaired", pp); c.failure = (Rlist *) PromiseGetConstraintAsList(ctx, "repair_failed", pp); c.denied = (Rlist *) PromiseGetConstraintAsList(ctx, "repair_denied", pp); c.timeout = (Rlist *) PromiseGetConstraintAsList(ctx, "repair_timeout", pp); c.kept = (Rlist *) PromiseGetConstraintAsList(ctx, "promise_kept", pp); c.del_change = (Rlist *) PromiseGetConstraintAsList(ctx, "cancel_repaired", pp); c.del_kept = (Rlist *) PromiseGetConstraintAsList(ctx, "cancel_kept", pp); c.del_notkept = (Rlist *) PromiseGetConstraintAsList(ctx, "cancel_notkept", pp); c.retcode_kept = (Rlist *) PromiseGetConstraintAsList(ctx, "kept_returncodes", pp); c.retcode_repaired = (Rlist *) PromiseGetConstraintAsList(ctx, "repaired_returncodes", pp); c.retcode_failed = (Rlist *) PromiseGetConstraintAsList(ctx, "failed_returncodes", pp); c.persist = PromiseGetConstraintAsInt(ctx, "persist_time", pp); if (c.persist == CF_NOINT) { c.persist = 0; } pt = PromiseGetConstraintAsRval(pp, "timer_policy", RVAL_TYPE_SCALAR); if (pt && (strncmp(pt, "abs", 3) == 0)) { c.timer = CONTEXT_STATE_POLICY_PRESERVE; } else { c.timer = CONTEXT_STATE_POLICY_RESET; } return c; } /*******************************************************************/ FileDelete GetDeleteConstraints(const EvalContext *ctx, const Promise *pp) { FileDelete f; char *value; value = PromiseGetConstraintAsRval(pp, "dirlinks", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "keep") == 0)) { f.dirlinks = TIDY_LINK_KEEP; } else { f.dirlinks = TIDY_LINK_DELETE; } f.rmdirs = PromiseGetConstraintAsBoolean(ctx, "rmdirs", pp); return f; } /*******************************************************************/ FileRename GetRenameConstraints(const EvalContext *ctx, const Promise *pp) { FileRename r; char *value; value = PromiseGetConstraintAsRval(pp, "disable_mode", RVAL_TYPE_SCALAR); if (!ParseModeString(value, &r.plus, &r.minus)) { Log(LOG_LEVEL_ERR, "Problem validating a mode string"); PromiseRef(LOG_LEVEL_ERR, pp); } r.disable = PromiseGetConstraintAsBoolean(ctx, "disable", pp); r.disable_suffix = PromiseGetConstraintAsRval(pp, "disable_suffix", RVAL_TYPE_SCALAR); r.newname = PromiseGetConstraintAsRval(pp, "newname", RVAL_TYPE_SCALAR); r.rotate = PromiseGetConstraintAsInt(ctx, "rotate", pp); return r; } /*******************************************************************/ ENTERPRISE_FUNC_0ARG_DEFINE_STUB(HashMethod, GetBestFileChangeHashMethod) { return HASH_METHOD_BEST; } FileChange GetChangeMgtConstraints(const EvalContext *ctx, const Promise *pp) { FileChange c; char *value; value = PromiseGetConstraintAsRval(pp, "hash", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "best") == 0)) { c.hash = GetBestFileChangeHashMethod(); } else if (value && (strcmp(value, "md5") == 0)) { c.hash = HASH_METHOD_MD5; } else if (value && (strcmp(value, "sha1") == 0)) { c.hash = HASH_METHOD_SHA1; } else if (value && (strcmp(value, "sha256") == 0)) { c.hash = HASH_METHOD_SHA256; } else if (value && (strcmp(value, "sha384") == 0)) { c.hash = HASH_METHOD_SHA384; } else if (value && (strcmp(value, "sha512") == 0)) { c.hash = HASH_METHOD_SHA512; } else { c.hash = CF_DEFAULT_DIGEST; } if (FIPS_MODE && (c.hash == HASH_METHOD_MD5)) { Log(LOG_LEVEL_ERR, "FIPS mode is enabled, and md5 is not an approved algorithm"); PromiseRef(LOG_LEVEL_ERR, pp); } value = PromiseGetConstraintAsRval(pp, "report_changes", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "content") == 0)) { c.report_changes = FILE_CHANGE_REPORT_CONTENT_CHANGE; } else if (value && (strcmp(value, "stats") == 0)) { c.report_changes = FILE_CHANGE_REPORT_STATS_CHANGE; } else if (value && (strcmp(value, "all") == 0)) { c.report_changes = FILE_CHANGE_REPORT_ALL; } else { c.report_changes = FILE_CHANGE_REPORT_NONE; } if (PromiseGetConstraintAsRval(pp, "update_hashes", RVAL_TYPE_SCALAR)) { c.update = PromiseGetConstraintAsBoolean(ctx, "update_hashes", pp); } else { c.update = GetChecksumUpdatesDefault(ctx); } c.report_diffs = PromiseGetConstraintAsBoolean(ctx, "report_diffs", pp); return c; } /*******************************************************************/ FileCopy GetCopyConstraints(const EvalContext *ctx, const Promise *pp) { FileCopy f; long min, max; const char *value; f.source = PromiseGetConstraintAsRval(pp, "source", RVAL_TYPE_SCALAR); f.servers = PromiseGetConstraintAsList(ctx, "servers", pp); value = PromiseGetConstraintAsRval(pp, "compare", RVAL_TYPE_SCALAR); if (value == NULL) { value = DEFAULT_COPYTYPE; } f.compare = FileComparatorFromString(value); value = PromiseGetConstraintAsRval(pp, "link_type", RVAL_TYPE_SCALAR); f.link_type = FileLinkTypeFromString(value); char *protocol_version = PromiseGetConstraintAsRval(pp, "protocol_version", RVAL_TYPE_SCALAR); /* Default is undefined, which leaves the choice to body common. */ f.protocol_version = CF_PROTOCOL_UNDEFINED; if (protocol_version != NULL) { ProtocolVersion parsed = ParseProtocolVersionPolicy(protocol_version); if (ProtocolIsKnown(parsed)) { f.protocol_version = parsed; } } f.port = PromiseGetConstraintAsRval(pp, "portnumber", RVAL_TYPE_SCALAR); f.timeout = (short) PromiseGetConstraintAsInt(ctx, "timeout", pp); f.link_instead = PromiseGetConstraintAsList(ctx, "linkcopy_patterns", pp); f.copy_links = PromiseGetConstraintAsList(ctx, "copylink_patterns", pp); value = PromiseGetConstraintAsRval(pp, "copy_backup", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "false") == 0)) { f.backup = BACKUP_OPTION_NO_BACKUP; } else if (value && (strcmp(value, "timestamp") == 0)) { f.backup = BACKUP_OPTION_TIMESTAMP; } else { f.backup = BACKUP_OPTION_BACKUP; } f.stealth = PromiseGetConstraintAsBoolean(ctx, "stealth", pp); f.collapse = PromiseGetConstraintAsBoolean(ctx, "collapse_destination_dir", pp); f.preserve = PromiseGetConstraintAsBoolean(ctx, "preserve", pp); f.type_check = PromiseGetConstraintAsBoolean(ctx, "type_check", pp); f.force_update = PromiseGetConstraintAsBoolean(ctx, "force_update", pp); f.force_ipv4 = PromiseGetConstraintAsBoolean(ctx, "force_ipv4", pp); f.check_root = PromiseGetConstraintAsBoolean(ctx, "check_root", pp); value = PromiseGetConstraintAsRval(pp, "copy_size", RVAL_TYPE_SCALAR); if (!IntegerRangeFromString(value, &min, &max)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } f.min_size = (size_t) min; f.max_size = (size_t) max; f.trustkey = PromiseGetConstraintAsBoolean(ctx, "trustkey", pp); f.encrypt = PromiseGetConstraintAsBoolean(ctx, "encrypt", pp); f.verify = PromiseGetConstraintAsBoolean(ctx, "verify", pp); f.purge = PromiseGetConstraintAsBoolean(ctx, "purge", pp); f.missing_ok = PromiseGetConstraintAsBoolean(ctx, "missing_ok", pp); f.destination = NULL; return f; } /*******************************************************************/ FileLink GetLinkConstraints(const EvalContext *ctx, const Promise *pp) { FileLink f; char *value; f.source = PromiseGetConstraintAsRval(pp, "source", RVAL_TYPE_SCALAR); value = PromiseGetConstraintAsRval(pp, "link_type", RVAL_TYPE_SCALAR); f.link_type = FileLinkTypeFromString(value); f.copy_patterns = PromiseGetConstraintAsList(ctx, "copy_patterns", pp); value = PromiseGetConstraintAsRval(pp, "when_no_source", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "force") == 0)) { f.when_no_file = cfa_force; } else if (value && (strcmp(value, "delete") == 0)) { f.when_no_file = cfa_delete; } else { f.when_no_file = cfa_skip; } value = PromiseGetConstraintAsRval(pp, "when_linking_children", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "override_file") == 0)) { f.when_linking_children = cfa_override; } else { f.when_linking_children = cfa_onlynonexisting; } f.link_children = PromiseGetConstraintAsBoolean(ctx, "link_children", pp); return f; } /*******************************************************************/ EditDefaults GetEditDefaults(const EvalContext *ctx, const Promise *pp) { EditDefaults e = { 0 }; char *value; e.maxfilesize = PromiseGetConstraintAsInt(ctx, "max_file_size", pp); if (e.maxfilesize == CF_NOINT) { e.maxfilesize = EDITFILESIZE; } value = PromiseGetConstraintAsRval(pp, "edit_backup", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "false") == 0)) { e.backup = BACKUP_OPTION_NO_BACKUP; } else if (value && (strcmp(value, "timestamp") == 0)) { e.backup = BACKUP_OPTION_TIMESTAMP; } else if (value && (strcmp(value, "rotate") == 0)) { e.backup = BACKUP_OPTION_ROTATE; e.rotate = PromiseGetConstraintAsInt(ctx, "rotate", pp); } else { e.backup = BACKUP_OPTION_BACKUP; } e.empty_before_use = PromiseGetConstraintAsBoolean(ctx, "empty_file_before_editing", pp); e.joinlines = PromiseGetConstraintAsBoolean(ctx, "recognize_join", pp); e.inherit = PromiseGetConstraintAsBoolean(ctx, "inherit", pp); return e; } /*******************************************************************/ ContextConstraint GetContextConstraints(const EvalContext *ctx, const Promise *pp) { ContextConstraint a; a.nconstraints = 0; a.expression = NULL; a.persistent = PromiseGetConstraintAsInt(ctx, "persistence", pp); { const char *context_scope = PromiseGetConstraintAsRval(pp, "scope", RVAL_TYPE_SCALAR); a.scope = ContextScopeFromString(context_scope); } for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); for (int k = 0; CF_CLASSBODY[k].lval != NULL; k++) { if (strcmp(cp->lval, "persistence") == 0 || strcmp(cp->lval, "scope") == 0) { continue; } if (strcmp(cp->lval, CF_CLASSBODY[k].lval) == 0) { a.expression = cp; a.nconstraints++; } } } return a; } /*******************************************************************/ Packages GetPackageConstraints(const EvalContext *ctx, const Promise *pp) { Packages p = {0}; bool has_package_method = PromiseBundleOrBodyConstraintExists(ctx, "package_method", pp); bool has_generic_package_method = false; if (!has_package_method) { /* Check if we have generic package_method. */ const Policy *policy = PolicyFromPromise(pp); Seq *bodies_and_args = EvalContextResolveBodyExpression(ctx, policy, "generic", "package_method");; // at position 0 we'll have the body, then its rval, then the same for each of its inherit_from parents if (bodies_and_args != NULL && SeqLength(bodies_and_args) > 0) { Log(LOG_LEVEL_VERBOSE, "Package promise had no package_method attribute so it's being assigned a value of 'generic' as default."); const Body *bp = SeqAt(bodies_and_args, 0); // guaranteed to be non-NULL CopyBodyConstraintsToPromise((EvalContext*)ctx, (Promise*)pp, bp); has_generic_package_method = true; } else { Log(LOG_LEVEL_VERBOSE, "Package promise had no package_method attibute and policy had no 'generic' package_method body so will use v2 package modules."); } SeqDestroy(bodies_and_args); } p.package_version = PromiseGetConstraintAsRval(pp, "package_version", RVAL_TYPE_SCALAR); p.package_architectures = PromiseGetConstraintAsList(ctx, "package_architectures", pp); p.package_select = PackageVersionComparatorFromString(PromiseGetConstraintAsRval(pp, "package_select", RVAL_TYPE_SCALAR)); p.package_policy = PackageActionFromString(PromiseGetConstraintAsRval(pp, "package_policy", RVAL_TYPE_SCALAR)); if (p.package_version == NULL && p.package_architectures == NULL && p.package_select == PACKAGE_VERSION_COMPARATOR_NONE && p.package_policy == PACKAGE_ACTION_NONE) { p.is_empty = true; } else { p.is_empty = false; } if (p.package_policy == PACKAGE_ACTION_NONE) // Default action => package add { p.package_policy = PACKAGE_ACTION_ADD; } p.has_package_method = has_package_method | has_generic_package_method; /* body package_method constraints */ p.package_add_command = PromiseGetConstraintAsRval(pp, "package_add_command", RVAL_TYPE_SCALAR); p.package_arch_regex = PromiseGetConstraintAsRval(pp, "package_arch_regex", RVAL_TYPE_SCALAR); p.package_changes = PackageActionPolicyFromString(PromiseGetConstraintAsRval(pp, "package_changes", RVAL_TYPE_SCALAR)); p.package_delete_command = PromiseGetConstraintAsRval(pp, "package_delete_command", RVAL_TYPE_SCALAR); p.package_delete_convention = PromiseGetConstraintAsRval(pp, "package_delete_convention", RVAL_TYPE_SCALAR); p.package_file_repositories = PromiseGetConstraintAsList(ctx, "package_file_repositories", pp); p.package_installed_regex = PromiseGetConstraintAsRval(pp, "package_installed_regex", RVAL_TYPE_SCALAR); p.package_default_arch_command = PromiseGetConstraintAsRval(pp, "package_default_arch_command", RVAL_TYPE_SCALAR); p.package_list_arch_regex = PromiseGetConstraintAsRval(pp, "package_list_arch_regex", RVAL_TYPE_SCALAR); p.package_list_command = PromiseGetConstraintAsRval(pp, "package_list_command", RVAL_TYPE_SCALAR); p.package_name_regex = PromiseGetConstraintAsRval(pp, "package_name_regex", RVAL_TYPE_SCALAR); p.package_list_update_command = PromiseGetConstraintAsRval(pp, "package_list_update_command", RVAL_TYPE_SCALAR); p.package_list_update_ifelapsed = PromiseGetConstraintAsInt(ctx, "package_list_update_ifelapsed", pp); p.package_list_version_regex = PromiseGetConstraintAsRval(pp, "package_list_version_regex", RVAL_TYPE_SCALAR); p.package_name_convention = PromiseGetConstraintAsRval(pp, "package_name_convention", RVAL_TYPE_SCALAR); p.package_patch_name_regex = PromiseGetConstraintAsRval(pp, "package_patch_name_regex", RVAL_TYPE_SCALAR); p.package_noverify_regex = PromiseGetConstraintAsRval(pp, "package_noverify_regex", RVAL_TYPE_SCALAR); p.package_noverify_returncode = PromiseGetConstraintAsInt(ctx, "package_noverify_returncode", pp); p.package_patch_arch_regex = PromiseGetConstraintAsRval(pp, "package_patch_arch_regex", RVAL_TYPE_SCALAR); p.package_patch_command = PromiseGetConstraintAsRval(pp, "package_patch_command", RVAL_TYPE_SCALAR); p.package_patch_installed_regex = PromiseGetConstraintAsRval(pp, "package_patch_installed_regex", RVAL_TYPE_SCALAR); p.package_patch_list_command = PromiseGetConstraintAsRval(pp, "package_patch_list_command", RVAL_TYPE_SCALAR); p.package_list_name_regex = PromiseGetConstraintAsRval(pp, "package_list_name_regex", RVAL_TYPE_SCALAR); p.package_patch_version_regex = PromiseGetConstraintAsRval(pp, "package_patch_version_regex", RVAL_TYPE_SCALAR); p.package_update_command = PromiseGetConstraintAsRval(pp, "package_update_command", RVAL_TYPE_SCALAR); p.package_verify_command = PromiseGetConstraintAsRval(pp, "package_verify_command", RVAL_TYPE_SCALAR); p.package_version_regex = PromiseGetConstraintAsRval(pp, "package_version_regex", RVAL_TYPE_SCALAR); p.package_multiline_start = PromiseGetConstraintAsRval(pp, "package_multiline_start", RVAL_TYPE_SCALAR); if (PromiseGetConstraint(pp, "package_commands_useshell") == NULL) { p.package_commands_useshell = true; } else { p.package_commands_useshell = PromiseGetConstraintAsBoolean(ctx, "package_commands_useshell", pp); } p.package_version_less_command = PromiseGetConstraintAsRval(pp, "package_version_less_command", RVAL_TYPE_SCALAR); p.package_version_equal_command = PromiseGetConstraintAsRval(pp, "package_version_equal_command", RVAL_TYPE_SCALAR); return p; } /*******************************************************************/ static const char *new_packages_actions[] = { "absent", "present", NULL }; NewPackages GetNewPackageConstraints(const EvalContext *ctx, const Promise *pp) { NewPackages p = {0}; NewPackages empty = {0}; p.package_version = PromiseGetConstraintAsRval(pp, "version", RVAL_TYPE_SCALAR); p.package_architecture = PromiseGetConstraintAsRval(pp, "architecture", RVAL_TYPE_SCALAR); p.package_options = PromiseGetConstraintAsList(ctx, "options", pp); p.is_empty = (memcmp(&p, &empty, sizeof(NewPackages)) == 0); bool have_policy = PromiseBundleOrBodyConstraintExists(ctx, "policy", pp); bool have_package_policy = PromiseBundleOrBodyConstraintExists(ctx, "package_policy", pp); if (!have_policy && !have_package_policy) { Log(LOG_LEVEL_DEBUG, "Package promise has no policy or package_policy attribute. Checking if default:control_common.package_module is defined to default the policy attribute to 'present' and force use of v2 package promise (package_module)."); const void *ret = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_PACKAGE_MODULE); PackageModuleBody *package_module = GetPackageModuleFromContext(ctx, ret); if (package_module != NULL) { Log(LOG_LEVEL_DEBUG, "Package promise had no policy or package_policy attribute and default:control_common.package_module is defined so defaulting to v2 package promise (package_module) and setting 'policy' attribute to 'present' and 'package_module' to %s.", package_module->name); PromiseAppendConstraint((Promise*)pp, "policy", (Rval) {xstrdup("present"), RVAL_TYPE_SCALAR }, false); PromiseAppendConstraint((Promise*)pp, "package_module_name", (Rval) {xstrdup(package_module->name), RVAL_TYPE_SCALAR }, false); } else { Log(LOG_LEVEL_VERBOSE, "Package promise had no policy or package_policy attribute and default:control_common.package_module is undefined so will use v1 package promise (package_method)."); } } p.package_policy = GetNewPackagePolicy(PromiseGetConstraintAsRval(pp, "policy", RVAL_TYPE_SCALAR), new_packages_actions); /* We can have only policy specified in v2 package promise (package_module) definition. */ if (p.package_policy != NEW_PACKAGE_ACTION_NONE) { p.is_empty = false; } /* If we have promise package manager specified. * IMPORTANT: this must be done after is_empty flag is set as we can have * some default options for new package promise specified and still use * old promise inside policy. */ char *local_promise_manager = PromiseGetConstraintAsRval(pp, "package_module_name", RVAL_TYPE_SCALAR); if (local_promise_manager) { p.module_body = GetPackageModuleFromContext(ctx, local_promise_manager); } else { p.module_body = GetDefaultPackageModuleFromContext(ctx); } p.package_inventory = GetDefaultInventoryFromContext(ctx); /* If global options are not override by promise specific ones. */ if (!p.package_options && p.module_body) { p.package_options = p.module_body->options; } return p; } /*******************************************************************/ ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise *pp) { ProcessSelect p; char *value; int entries = 0; p.owner = PromiseGetConstraintAsList(ctx, "process_owner", pp); value = PromiseGetConstraintAsRval(pp, "pid", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, &p.min_pid, &p.max_pid)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "ppid", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, &p.min_ppid, &p.max_ppid)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "pgid", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, &p.min_pgid, &p.max_pgid)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "rsize", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, &p.min_rsize, &p.max_rsize)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "vsize", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, &p.min_vsize, &p.max_vsize)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "ttime_range", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, (long *) &p.min_ttime, (long *) &p.max_ttime)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "stime_range", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, (long *) &p.min_stime, (long *) &p.max_stime)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } p.status = PromiseGetConstraintAsRval(pp, "status", RVAL_TYPE_SCALAR); p.command = PromiseGetConstraintAsRval(pp, "command", RVAL_TYPE_SCALAR); p.tty = PromiseGetConstraintAsRval(pp, "tty", RVAL_TYPE_SCALAR); value = PromiseGetConstraintAsRval(pp, "priority", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, &p.min_pri, &p.max_pri)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } value = PromiseGetConstraintAsRval(pp, "threads", RVAL_TYPE_SCALAR); if (value) { entries++; } if (!IntegerRangeFromString(value, &p.min_thread, &p.max_thread)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } if ((p.owner) || (p.status) || (p.command) || (p.tty)) { entries = true; } if ((p.process_result = PromiseGetConstraintAsRval(pp, "process_result", RVAL_TYPE_SCALAR)) == NULL) { if (entries) { Log(LOG_LEVEL_ERR, "process_select body missing its a process_result return value"); } } return p; } /*******************************************************************/ ProcessCount GetMatchesConstraints(const EvalContext *ctx, const Promise *pp) { ProcessCount p; char *value; value = PromiseGetConstraintAsRval(pp, "match_range", RVAL_TYPE_SCALAR); if (!IntegerRangeFromString(value, &p.min_range, &p.max_range)) { PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Could not make sense of integer range [%s]", value); } p.in_range_define = PromiseGetConstraintAsList(ctx, "in_range_define", pp); p.out_of_range_define = PromiseGetConstraintAsList(ctx, "out_of_range_define", pp); return p; } Attributes GetInsertionAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.havelocation = PromiseGetConstraintAsBoolean(ctx, "location", pp); attr.location = GetLocationAttributes(pp); attr.sourcetype = PromiseGetConstraintAsRval(pp, "insert_type", RVAL_TYPE_SCALAR); attr.expandvars = PromiseGetConstraintAsBoolean(ctx, "expand_scalars", pp); attr.haveinsertselect = PromiseGetConstraintAsBoolean(ctx, "insert_select", pp); attr.line_select = GetInsertSelectConstraints(ctx, pp); attr.insert_match = PromiseGetConstraintAsList(ctx, "whitespace_policy", pp); /* Common ("included") */ attr.haveregion = PromiseGetConstraintAsBoolean(ctx, "select_region", pp); attr.region = GetRegionConstraints(ctx, pp); attr.xml = GetXmlConstraints(pp); attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ EditLocation GetLocationAttributes(const Promise *pp) { EditLocation e; char *value; e.line_matching = PromiseGetConstraintAsRval(pp, "select_line_matching", RVAL_TYPE_SCALAR); value = PromiseGetConstraintAsRval(pp, "before_after", RVAL_TYPE_SCALAR); if (value && (strcmp(value, "before") == 0)) { e.before_after = EDIT_ORDER_BEFORE; } else { e.before_after = EDIT_ORDER_AFTER; } e.first_last = PromiseGetConstraintAsRval(pp, "first_last", RVAL_TYPE_SCALAR); return e; } /*******************************************************************/ Attributes GetDeletionAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.not_matching = PromiseGetConstraintAsBoolean(ctx, "not_matching", pp); attr.havedeleteselect = PromiseGetConstraintAsBoolean(ctx, "delete_select", pp); attr.line_select = GetDeleteSelectConstraints(ctx, pp); /* common */ attr.haveregion = PromiseGetConstraintAsBoolean(ctx, "select_region", pp); attr.region = GetRegionConstraints(ctx, pp); attr.xml = GetXmlConstraints(pp); attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetColumnAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.havecolumn = PromiseGetConstraintAsBoolean(ctx, "edit_field", pp); attr.column = GetColumnConstraints(ctx, pp); /* common */ attr.haveregion = PromiseGetConstraintAsBoolean(ctx, "select_region", pp); attr.region = GetRegionConstraints(ctx, pp); attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ Attributes GetReplaceAttributes(const EvalContext *ctx, const Promise *pp) { Attributes attr = ZeroAttributes; attr.havereplace = PromiseGetConstraintAsBoolean(ctx, "replace_patterns", pp); attr.replace = GetReplaceConstraints(pp); attr.havecolumn = PromiseGetConstraintAsBoolean(ctx, "replace_with", pp); /* common */ attr.haveregion = PromiseGetConstraintAsBoolean(ctx, "select_region", pp); attr.region = GetRegionConstraints(ctx, pp); attr.xml = GetXmlConstraints(pp); attr.havetrans = PromiseGetConstraintAsBoolean(ctx, CF_TRANSACTION, pp); attr.transaction = GetTransactionConstraints(ctx, pp); attr.haveclasses = PromiseGetConstraintAsBoolean(ctx, CF_DEFINECLASSES, pp); attr.classes = GetClassDefinitionConstraints(ctx, pp); return attr; } /*******************************************************************/ EditXml GetXmlConstraints(const Promise *pp) { EditXml x; x.havebuildxpath = ((x.build_xpath = PromiseGetConstraintAsRval(pp, "build_xpath", RVAL_TYPE_SCALAR)) != NULL); x.haveselectxpath = ((x.select_xpath = PromiseGetConstraintAsRval(pp, "select_xpath", RVAL_TYPE_SCALAR)) != NULL); x.haveattributevalue = ((x.attribute_value = PromiseGetConstraintAsRval(pp, "attribute_value", RVAL_TYPE_SCALAR)) != NULL); return x; } /*******************************************************************/ EditRegion GetRegionConstraints(const EvalContext *ctx, const Promise *pp) { EditRegion e; e.select_start = PromiseGetConstraintAsRval(pp, "select_start", RVAL_TYPE_SCALAR); e.select_end = PromiseGetConstraintAsRval(pp, "select_end", RVAL_TYPE_SCALAR); e.include_start = PromiseGetConstraintAsBoolean(ctx, "include_start_delimiter", pp); e.include_end = PromiseGetConstraintAsBoolean(ctx, "include_end_delimiter", pp); // set the value based on body agent control char *local_select_end = PromiseGetConstraintAsRval(pp, "select_end_match_eof", RVAL_TYPE_SCALAR); if (local_select_end != NULL) { if (strcmp(local_select_end, "true") == 0) { e.select_end_match_eof = true; } else { e.select_end_match_eof = false; } } else { e.select_end_match_eof = EvalContextGetSelectEndMatchEof(ctx); } return e; } /*******************************************************************/ EditReplace GetReplaceConstraints(const Promise *pp) { EditReplace r; r.replace_value = PromiseGetConstraintAsRval(pp, "replace_value", RVAL_TYPE_SCALAR); r.occurrences = PromiseGetConstraintAsRval(pp, "occurrences", RVAL_TYPE_SCALAR); return r; } /*******************************************************************/ EditColumn GetColumnConstraints(const EvalContext *ctx, const Promise *pp) { EditColumn c; char *value; c.column_separator = PromiseGetConstraintAsRval(pp, "field_separator", RVAL_TYPE_SCALAR); c.select_column = PromiseGetConstraintAsInt(ctx, "select_field", pp); if (((c.select_column) != CF_NOINT) && (PromiseGetConstraintAsBoolean(ctx, "start_fields_from_zero", pp))) { c.select_column++; } value = PromiseGetConstraintAsRval(pp, "value_separator", RVAL_TYPE_SCALAR); if (value) { c.value_separator = *value; } else { c.value_separator = '\0'; } c.column_value = PromiseGetConstraintAsRval(pp, "field_value", RVAL_TYPE_SCALAR); c.column_operation = PromiseGetConstraintAsRval(pp, "field_operation", RVAL_TYPE_SCALAR); c.extend_columns = PromiseGetConstraintAsBoolean(ctx, "extend_fields", pp); c.blanks_ok = PromiseGetConstraintAsBoolean(ctx, "allow_blank_fields", pp); return c; } /*******************************************************************/ /* Storage */ /*******************************************************************/ StorageMount GetMountConstraints(const EvalContext *ctx, const Promise *pp) { StorageMount m; m.mount_type = PromiseGetConstraintAsRval(pp, "mount_type", RVAL_TYPE_SCALAR); m.mount_source = PromiseGetConstraintAsRval(pp, "mount_source", RVAL_TYPE_SCALAR); m.mount_server = PromiseGetConstraintAsRval(pp, "mount_server", RVAL_TYPE_SCALAR); m.mount_options = PromiseGetConstraintAsList(ctx, "mount_options", pp); m.editfstab = PromiseGetConstraintAsBoolean(ctx, "edit_fstab", pp); m.unmount = PromiseGetConstraintAsBoolean(ctx, "unmount", pp); return m; } /*******************************************************************/ StorageVolume GetVolumeConstraints(const EvalContext *ctx, const Promise *pp) { StorageVolume v; char *value; v.check_foreign = PromiseGetConstraintAsBoolean(ctx, "check_foreign", pp); value = PromiseGetConstraintAsRval(pp, "freespace", RVAL_TYPE_SCALAR); v.freespace = (long) IntFromString(value); value = PromiseGetConstraintAsRval(pp, "sensible_size", RVAL_TYPE_SCALAR); v.sensible_size = (int) IntFromString(value); value = PromiseGetConstraintAsRval(pp, "sensible_count", RVAL_TYPE_SCALAR); v.sensible_count = (int) IntFromString(value); v.scan_arrivals = PromiseGetConstraintAsBoolean(ctx, "scan_arrivals", pp); // defaults if (v.sensible_size == CF_NOINT) { v.sensible_size = 1000; } if (v.sensible_count == CF_NOINT) { v.sensible_count = 2; } return v; } Report GetReportConstraints(const EvalContext *ctx, const Promise *pp) { Report r = {0}; r.result = PromiseGetConstraintAsRval(pp, "bundle_return_value_index", RVAL_TYPE_SCALAR); if (PromiseGetConstraintAsRval(pp, "lastseen", RVAL_TYPE_SCALAR)) { r.havelastseen = true; r.lastseen = PromiseGetConstraintAsInt(ctx, "lastseen", pp); if (r.lastseen == CF_NOINT) { r.lastseen = 0; } } else { r.havelastseen = false; r.lastseen = 0; } if (!PromiseGetConstraintAsReal(ctx, "intermittency", pp, &r.intermittency)) { r.intermittency = 0; } r.haveprintfile = PromiseGetConstraintAsBoolean(ctx, "printfile", pp); r.filename = PromiseGetConstraintAsRval(pp, "file_to_print", RVAL_TYPE_SCALAR); r.numlines = PromiseGetConstraintAsInt(ctx, "number_of_lines", pp); if (r.numlines == CF_NOINT) { r.numlines = 5; } r.showstate = PromiseGetConstraintAsList(ctx, "showstate", pp); r.friend_pattern = PromiseGetConstraintAsRval(pp, "friend_pattern", RVAL_TYPE_SCALAR); r.to_file = PromiseGetConstraintAsRval(pp, "report_to_file", RVAL_TYPE_SCALAR); if ((r.result) && ((r.haveprintfile) || (r.filename) || (r.showstate) || (r.to_file) || (r.lastseen))) { Log(LOG_LEVEL_ERR, "bundle_return_value promise for '%s' in bundle '%s' with too many constraints (ignored)", pp->promiser, PromiseGetBundle(pp)->name); } return r; } /*******************************************************************/ LineSelect GetInsertSelectConstraints(const EvalContext *ctx, const Promise *pp) { LineSelect s; s.startwith_from_list = PromiseGetConstraintAsList(ctx, "insert_if_startwith_from_list", pp); s.not_startwith_from_list = PromiseGetConstraintAsList(ctx, "insert_if_not_startwith_from_list", pp); s.match_from_list = PromiseGetConstraintAsList(ctx, "insert_if_match_from_list", pp); s.not_match_from_list = PromiseGetConstraintAsList(ctx, "insert_if_not_match_from_list", pp); s.contains_from_list = PromiseGetConstraintAsList(ctx, "insert_if_contains_from_list", pp); s.not_contains_from_list = PromiseGetConstraintAsList(ctx, "insert_if_not_contains_from_list", pp); return s; } /*******************************************************************/ LineSelect GetDeleteSelectConstraints(const EvalContext *ctx, const Promise *pp) { LineSelect s; s.startwith_from_list = PromiseGetConstraintAsList(ctx, "delete_if_startwith_from_list", pp); s.not_startwith_from_list = PromiseGetConstraintAsList(ctx, "delete_if_not_startwith_from_list", pp); s.match_from_list = PromiseGetConstraintAsList(ctx, "delete_if_match_from_list", pp); s.not_match_from_list = PromiseGetConstraintAsList(ctx, "delete_if_not_match_from_list", pp); s.contains_from_list = PromiseGetConstraintAsList(ctx, "delete_if_contains_from_list", pp); s.not_contains_from_list = PromiseGetConstraintAsList(ctx, "delete_if_not_contains_from_list", pp); return s; } /*******************************************************************/ Measurement GetMeasurementConstraint(const EvalContext *ctx, const Promise *pp) { Measurement m; char *value; m.stream_type = PromiseGetConstraintAsRval(pp, "stream_type", RVAL_TYPE_SCALAR); value = PromiseGetConstraintAsRval(pp, "data_type", RVAL_TYPE_SCALAR); m.data_type = DataTypeFromString(value); if (m.data_type == CF_DATA_TYPE_NONE) { m.data_type = CF_DATA_TYPE_STRING; } m.history_type = PromiseGetConstraintAsRval(pp, "history_type", RVAL_TYPE_SCALAR); m.select_line_matching = PromiseGetConstraintAsRval(pp, "select_line_matching", RVAL_TYPE_SCALAR); m.select_line_number = PromiseGetConstraintAsInt(ctx, "select_line_number", pp); m.policy = MeasurePolicyFromString(PromiseGetConstraintAsRval(pp, "select_multiline_policy", RVAL_TYPE_SCALAR)); m.extraction_regex = PromiseGetConstraintAsRval(pp, "extraction_regex", RVAL_TYPE_SCALAR); m.units = PromiseGetConstraintAsRval(pp, "units", RVAL_TYPE_SCALAR); m.growing = PromiseGetConstraintAsBoolean(ctx, "track_growing_file", pp); return m; } /*******************************************************************/ Database GetDatabaseConstraints(const EvalContext *ctx, const Promise *pp) { Database d; char *value; d.db_server_owner = PromiseGetConstraintAsRval(pp, "db_server_owner", RVAL_TYPE_SCALAR); d.db_server_password = PromiseGetConstraintAsRval(pp, "db_server_password", RVAL_TYPE_SCALAR); d.db_server_host = PromiseGetConstraintAsRval(pp, "db_server_host", RVAL_TYPE_SCALAR); d.db_connect_db = PromiseGetConstraintAsRval(pp, "db_server_connection_db", RVAL_TYPE_SCALAR); d.type = PromiseGetConstraintAsRval(pp, "database_type", RVAL_TYPE_SCALAR); d.server = PromiseGetConstraintAsRval(pp, "database_server", RVAL_TYPE_SCALAR); d.columns = PromiseGetConstraintAsList(ctx, "database_columns", pp); d.rows = PromiseGetConstraintAsList(ctx, "database_rows", pp); d.operation = PromiseGetConstraintAsRval(pp, "database_operation", RVAL_TYPE_SCALAR); d.exclude = PromiseGetConstraintAsList(ctx, "registry_exclude", pp); value = PromiseGetConstraintAsRval(pp, "db_server_type", RVAL_TYPE_SCALAR); d.db_server_type = DatabaseTypeFromString(value); if (value && ((d.db_server_type) == DATABASE_TYPE_NONE)) { Log(LOG_LEVEL_ERR, "Unsupported database type '%s' in databases promise", value); PromiseRef(LOG_LEVEL_ERR, pp); } return d; } cfengine-3.24.2/libpromises/fncall.c0000644000000000000000000003361515010704253017316 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #define SIMULATE_SAFE_META_TAG "simulate_safe" /******************************************************************/ /* Argument propagation */ /******************************************************************/ /* When formal parameters are passed, they should be literal strings, i.e. values (check for this). But when the values are received the receiving body should state only variable names without literal quotes. That way we can feed in the received parameter name directly in as an lvalue e.g. access => myaccess("$(person)"), body files myaccess(user) leads to Hash Association (lval,rval) => (user,"$(person)") */ /******************************************************************/ Rlist *NewExpArgs(EvalContext *ctx, const Policy *policy, const FnCall *fp, const FnCallType *fp_type) { // Functions with delayed evaluation will call this themselves later if (fp_type && fp_type->options & FNCALL_OPTION_DELAYED_EVALUATION) { return RlistCopy(fp->args); } const FnCallType *fn = FnCallTypeGet(fp->name); if (fn == NULL) { FatalError(ctx, "Function call '%s' has unknown type", fp->name); } else { int len = RlistLen(fp->args); if (!(fn->options & FNCALL_OPTION_VARARG)) { if (len != FnNumArgs(fn)) { Log(LOG_LEVEL_ERR, "Arguments to function '%s' do not tally. Expected %d not %d", fp->name, FnNumArgs(fn), len); PromiseRef(LOG_LEVEL_ERR, fp->caller); DoCleanupAndExit(EXIT_FAILURE); } } } Rlist *expanded_args = NULL; for (const Rlist *rp = fp->args; rp != NULL; rp = rp->next) { Rval rval; if (rp->val.type == RVAL_TYPE_FNCALL) { FnCall *subfp = RlistFnCallValue(rp); rval = FnCallEvaluate(ctx, policy, subfp, fp->caller).rval; } else { rval = ExpandPrivateRval(ctx, NULL, NULL, rp->val.item, rp->val.type); assert(rval.item); } /* Collect compound values into containers only if the function supports it. Functions without FNCALL_OPTION_COLLECTING don't collect Rlist elements. So in the policy, you call and(splitstring("a b")) and it ends up as and("a", "b"). This expansion happens once per FnCall, not for all arguments. Functions with FNCALL_OPTION_COLLECTING instead collect all the results of a FnCall into a single JSON array object. It requires functions to expect it, but it's the only reasonable way to preserve backwards compatibility for functions like and() and allow nesting of calls to functions that take and return compound data types. */ RlistAppendAllTypes(&expanded_args, rval.item, rval.type, (fn->options & FNCALL_OPTION_COLLECTING)); RvalDestroy(rval); } return expanded_args; } /*******************************************************************/ bool FnCallIsBuiltIn(Rval rval) { FnCall *fp; if (rval.type != RVAL_TYPE_FNCALL) { return false; } fp = (FnCall *) rval.item; if (FnCallTypeGet(fp->name)) { return true; } else { return false; } } /*******************************************************************/ FnCall *FnCallNew(const char *name, Rlist *args) { FnCall *fp = xmalloc(sizeof(FnCall)); fp->name = xstrdup(name); fp->args = args; return fp; } /*******************************************************************/ FnCall *FnCallCopyRewriter(const FnCall *f, JsonElement *map) { return FnCallNew(f->name, RlistCopyRewriter(f->args, map)); } FnCall *FnCallCopy(const FnCall *f) { return FnCallCopyRewriter(f, NULL); } /*******************************************************************/ void FnCallDestroy(FnCall *fp) { if (fp) { free(fp->name); RlistDestroy(fp->args); } free(fp); } unsigned FnCallHash(const FnCall *fp, unsigned seed) { unsigned hash = StringHash(fp->name, seed); return RlistHash(fp->args, hash); } FnCall *ExpandFnCall(const EvalContext *ctx, const char *ns, const char *scope, const FnCall *f) { FnCall *result = NULL; if (IsCf3VarString(f->name)) { // e.g. usebundle => $(m)(arg0, arg1); Buffer *buf = BufferNewWithCapacity(CF_MAXVARSIZE); ExpandScalar(ctx, ns, scope, f->name, buf); result = FnCallNew(BufferData(buf), ExpandList(ctx, ns, scope, f->args, false)); BufferDestroy(buf); } else { result = FnCallNew(f->name, ExpandList(ctx, ns, scope, f->args, false)); } return result; } void FnCallWrite(Writer *writer, const FnCall *call) { WriterWrite(writer, call->name); WriterWriteChar(writer, '('); for (const Rlist *rp = call->args; rp != NULL; rp = rp->next) { switch (rp->val.type) { case RVAL_TYPE_SCALAR: ScalarWrite(writer, RlistScalarValue(rp), true, false); break; case RVAL_TYPE_FNCALL: FnCallWrite(writer, RlistFnCallValue(rp)); break; default: WriterWrite(writer, "(** Unknown argument **)\n"); break; } if (rp->next != NULL) { WriterWriteChar(writer, ','); } } WriterWriteChar(writer, ')'); } /*******************************************************************/ static FnCallResult CallFunction(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *expargs) { const Rlist *rp = fp->args; const FnCallType *fncall_type = FnCallTypeGet(fp->name); if (fncall_type == NULL) { FatalError(ctx, "Function call '%s' has unknown type", fp->name); } int argnum = 0; for (argnum = 0; rp != NULL && fncall_type->args[argnum].pattern != NULL; argnum++) { if (rp->val.type != RVAL_TYPE_FNCALL) { /* Nested functions will not match to lval so don't bother checking */ SyntaxTypeMatch err = CheckConstraintTypeMatch(fp->name, rp->val, fncall_type->args[argnum].dtype, fncall_type->args[argnum].pattern, 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "In function '%s', error in variable '%s', '%s'", fp->name, (const char *)rp->val.item, SyntaxTypeMatchToString(err)); } } rp = rp->next; } if (argnum != RlistLen(expargs) && !(fncall_type->options & FNCALL_OPTION_VARARG)) { char *args_str = RlistToString(expargs); Log(LOG_LEVEL_ERR, "Argument template mismatch handling function %s(%s)", fp->name, args_str); free(args_str); rp = expargs; for (int i = 0; i < argnum; i++) { if (rp != NULL) { char *rval_str = RvalToString(rp->val); Log(LOG_LEVEL_ERR, " arg[%d] range %s\t %s ", i, fncall_type->args[i].pattern, rval_str); free(rval_str); } else { Log(LOG_LEVEL_ERR, " arg[%d] range %s\t ? ", i, fncall_type->args[i].pattern); } } FatalError(ctx, "Bad arguments"); } return (*fncall_type->impl) (ctx, policy, fp, expargs); } FnCallResult FnCallEvaluate(EvalContext *ctx, const Policy *policy, FnCall *fp, const Promise *caller) { assert(ctx != NULL); assert(policy != NULL); assert(fp != NULL); fp->caller = caller; if (!EvalContextGetEvalOption(ctx, EVAL_OPTION_EVAL_FUNCTIONS)) { Log(LOG_LEVEL_VERBOSE, "Skipping function '%s', because evaluation was turned off in the evaluator", fp->name); return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } }; } const FnCallType *fp_type = FnCallTypeGet(fp->name); if (!fp_type) { if (caller) { Log(LOG_LEVEL_ERR, "No such FnCall '%s' in promise '%s' near line %zu", fp->name, PromiseGetBundle(caller)->source_path, caller->offset.line); } else { Log(LOG_LEVEL_ERR, "No such FnCall '%s', context info unavailable", fp->name); } return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } }; } const bool skip_unsafe_function_calls = ((EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST) || (EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST_FULL) || (EVAL_MODE == EVAL_MODE_SIMULATE_DIFF)); Rlist *caller_meta = PromiseGetConstraintAsList(ctx, "meta", caller); if (skip_unsafe_function_calls && ((fp_type->options & FNCALL_OPTION_UNSAFE) != 0) && !RlistContainsString(caller_meta, SIMULATE_SAFE_META_TAG)) { Log(LOG_LEVEL_WARNING, "Not calling unsafe function '%s' in simulate mode", fp->name); return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } }; } Rlist *expargs = NewExpArgs(ctx, policy, fp, fp_type); Writer *fncall_writer = NULL; const char *fncall_string = ""; if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { fncall_writer = StringWriter(); FnCallWrite(fncall_writer, fp); fncall_string = StringWriterData(fncall_writer); } // Check if arguments are resolved, except for delayed evaluation functions if ( ! (fp_type->options & FNCALL_OPTION_DELAYED_EVALUATION) && RlistIsUnresolved(expargs)) { // Special case where a three argument ifelse call must // be allowed to have undefined variables. if (strcmp(fp->name, "ifelse") == 0 && expargs->val.type != RVAL_TYPE_FNCALL && RlistLen(expargs) == 3) { Log(LOG_LEVEL_DEBUG, "Allowing ifelse() function evaluation even" " though its arguments contain unresolved variables: %s", fncall_string); } else { if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { Log(LOG_LEVEL_DEBUG, "Skipping function evaluation for now," " arguments contain unresolved variables: %s", fncall_string); WriterClose(fncall_writer); } RlistDestroy(expargs); return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } }; } } /* Call functions in promises with 'ifelapsed => "0"' (e.g. with * 'action => immediate') [ENT-7478] */ const int if_elapsed = PromiseGetConstraintAsInt(ctx, "ifelapsed", caller); if (if_elapsed != 0) { Rval cached_rval; if ((fp_type->options & FNCALL_OPTION_CACHED) && EvalContextFunctionCacheGet(ctx, fp, expargs, &cached_rval)) { if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { Log(LOG_LEVEL_DEBUG, "Using previously cached result for function: %s", fncall_string); WriterClose(fncall_writer); } Writer *w = StringWriter(); FnCallWrite(w, fp); WriterClose(w); RlistDestroy(expargs); return (FnCallResult) { FNCALL_SUCCESS, RvalCopy(cached_rval) }; } } if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { Log(LOG_LEVEL_DEBUG, "Evaluating function: %s%s", fncall_string, (if_elapsed == 0) ? " (because of ifelapsed => \"0\")" : ""); WriterClose(fncall_writer); } FnCallResult result = CallFunction(ctx, policy, fp, expargs); if (result.status == FNCALL_FAILURE) { RlistDestroy(expargs); RvalDestroy(result.rval); return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } }; } if (fp_type->options & FNCALL_OPTION_CACHED) { Writer *w = StringWriter(); FnCallWrite(w, fp); Log(LOG_LEVEL_VERBOSE, "Caching result for function '%s'", StringWriterData(w)); WriterClose(w); EvalContextFunctionCachePut(ctx, fp, expargs, &result.rval); } RlistDestroy(expargs); return result; } /*******************************************************************/ const FnCallType *FnCallTypeGet(const char *name) { int i; for (i = 0; CF_FNCALL_TYPES[i].name != NULL; i++) { if (strcmp(CF_FNCALL_TYPES[i].name, name) == 0) { return CF_FNCALL_TYPES + i; } } return NULL; } cfengine-3.24.2/libpromises/files_interfaces.c0000644000000000000000000000343315010704253021357 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* remote_stat */ int cf_lstat(const char *file, struct stat *buf, const FileCopy *fc, AgentConnection *conn) { if (conn == NULL) { int ret = lstat(file, buf); if (ret == -1) { Log(LOG_LEVEL_ERR, "lstat: %s", GetErrorStr()); } return ret; } else { assert(fc->servers && strcmp(fc->servers->val.item, "localhost")); return cf_remote_stat(conn, fc->encrypt, file, buf, "link"); } } cfengine-3.24.2/libpromises/signals.c0000644000000000000000000001622615010704253017516 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* GetStateDir() */ #include /* FILE_SEPARATOR */ #include /* TerminateCustomPromises */ static bool PENDING_TERMINATION = false; /* GLOBAL_X */ static bool RELOAD_CONFIG = false; /* GLOBAL_X */ /********************************************************************/ bool IsPendingTermination(void) { return PENDING_TERMINATION; } bool ReloadConfigRequested(void) { return RELOAD_CONFIG; } void ClearRequestReloadConfig() { RELOAD_CONFIG = false; } void RequestReloadConfig() { RELOAD_CONFIG = true; } /********************************************************************/ static int SIGNAL_PIPE[2] = { -1, -1 }; /* GLOBAL_C */ static void CloseSignalPipe(void) { int c = 2; while (c > 0) { c--; if (SIGNAL_PIPE[c] >= 0) { close(SIGNAL_PIPE[c]); SIGNAL_PIPE[c] = -1; } } } /** * Make a pipe that can be used to flag that a signal has arrived. * Using a pipe avoids race conditions, since it saves its values until emptied. * Use GetSignalPipe() to get the pipe. * Note that we use a real socket as the pipe, because Windows only supports * using select() with real sockets. This means also using send() and recv() * instead of write() and read(). */ void MakeSignalPipe(void) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, SIGNAL_PIPE) != 0) { Log(LOG_LEVEL_CRIT, "Could not create internal communication pipe. Cannot continue. (socketpair: '%s')", GetErrorStr()); DoCleanupAndExit(EXIT_FAILURE); } RegisterCleanupFunction(&CloseSignalPipe); for (int c = 0; c < 2; c++) { #ifdef __MINGW32__ u_long enable = 1; int ret = ioctlsocket(SIGNAL_PIPE[c], FIONBIO, &enable); #define CNTLNAME "ioctlsocket" #else /* Unix: */ int ret = fcntl(SIGNAL_PIPE[c], F_SETFL, O_NONBLOCK); #define CNTLNAME "fcntl" #endif /* __MINGW32__ */ if (ret != 0) { Log(LOG_LEVEL_CRIT, "Could not unblock internal communication pipe. " "Cannot continue. (" CNTLNAME ": '%s')", GetErrorStr()); DoCleanupAndExit(EXIT_FAILURE); } #undef CNTLNAME } } /** * Gets the signal pipe, which is non-blocking. * Each byte read corresponds to one arrived signal. * Note: Use recv() to read from the pipe, not read(). */ int GetSignalPipe(void) { return SIGNAL_PIPE[0]; } static void SignalNotify(int signum) { unsigned char sig = (unsigned char)signum; if (SIGNAL_PIPE[1] >= 0) { // send() is async-safe, according to POSIX. if (send(SIGNAL_PIPE[1], &sig, 1, 0) < 0) { // These signal contention. Everything else is an error. if (errno != EAGAIN #ifndef __MINGW32__ && errno != EWOULDBLOCK #endif ) { // This is not async safe, but if we get in here there's something really weird // going on. Log(LOG_LEVEL_CRIT, "Could not write to signal pipe. Unsafe to continue. (write: '%s')", GetErrorStr()); _exit(EXIT_FAILURE); } } } } void HandleSignalsForAgent(int signum) { switch (signum) { case SIGTERM: case SIGINT: /* TODO don't exit from the signal handler, just set a flag. Reason is * that all the cleanup() hooks we register are not reentrant. */ TerminateCustomPromises(); DoCleanupAndExit(0); case SIGBUS: /* SIGBUS almost certainly means a violation of mmap() area boundaries * or some mis-aligned memory access. IOW, an LMDB corruption. */ { char filename[PATH_MAX] = { 0 }; /* trying to avoid memory allocation */ xsnprintf(filename, PATH_MAX, "%s%c%s", GetStateDir(), FILE_SEPARATOR, CF_DB_REPAIR_TRIGGER); int fd = open(filename, O_CREAT|O_RDWR, CF_PERMS_DEFAULT); if (fd != -1) { close(fd); } /* avoid calling complex logging functions */ fprintf(stdout, "process killed by SIGBUS\n"); /* else: we tried, nothing more to do in the limited environment of a * signal handler */ _exit(1); } break; case SIGUSR1: LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case SIGUSR2: LogSetGlobalLevel(LOG_LEVEL_NOTICE); break; default: /* No action */ break; } SignalNotify(signum); /* Reset the signal handler */ signal(signum, HandleSignalsForAgent); } /********************************************************************/ void HandleSignalsForDaemon(int signum) { switch (signum) { case SIGTERM: case SIGINT: case SIGSEGV: case SIGKILL: PENDING_TERMINATION = true; break; case SIGBUS: /* SIGBUS almost certainly means a violation of mmap() area boundaries * or some mis-aligned memory access. IOW, an LMDB corruption. */ { char filename[PATH_MAX] = { 0 }; /* trying to avoid memory allocation */ xsnprintf(filename, PATH_MAX, "%s%c%s", GetStateDir(), FILE_SEPARATOR, CF_DB_REPAIR_TRIGGER); int fd = open(filename, O_CREAT|O_RDWR, CF_PERMS_DEFAULT); if (fd != -1) { close(fd); } /* avoid calling complex logging functions */ fprintf(stdout, "process killed by SIGBUS\n"); /* else: we tried, nothing more to do in the limited environment of a * signal handler */ _exit(1); } break; case SIGUSR1: LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case SIGUSR2: LogSetGlobalLevel(LOG_LEVEL_NOTICE); break; case SIGHUP: RELOAD_CONFIG = true; break; case SIGPIPE: default: /* No action */ break; } /* Notify processes that use the signal pipe (cf-serverd). */ SignalNotify(signum); /* Reset the signal handler. */ signal(signum, HandleSignalsForDaemon); } cfengine-3.24.2/libpromises/assoc.c0000644000000000000000000000300615010704253017156 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include CfAssoc *NewAssoc(const char *lval, Rval rval, DataType dt) { CfAssoc *ap; ap = xmalloc(sizeof(CfAssoc)); /* Make a private copy because promises are ephemeral in expansion phase */ ap->lval = xstrdup(lval); ap->rval = RvalCopy(rval); ap->dtype = dt; return ap; } /*******************************************************************/ void DeleteAssoc(CfAssoc *ap) { if (ap == NULL) { return; } free(ap->lval); RvalDestroy(ap->rval); free(ap); } cfengine-3.24.2/libpromises/process_solaris.c0000644000000000000000000001130615010704253021262 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include /* * procfs.h is not 64-bit off_t clean, but the only affected structure is * priovec, which we don't use. Hence we may work around #error in sys/procfs.h * by lying that we are not compiling with large file support (while we do). */ #define _FILE_OFFSET_BITS 32 #include static bool GetProcessPsinfo(pid_t pid, psinfo_t *psinfo) { char filename[CF_BUFSIZE]; snprintf(filename, CF_BUFSIZE, "/proc/%d/psinfo", (int)pid); int fd = open(filename, O_RDONLY); if (fd == -1) { return false; } int res = FullRead(fd, psinfo, sizeof(*psinfo)); close(fd); return res == sizeof(*psinfo); } time_t GetProcessStartTime(pid_t pid) { psinfo_t psinfo; if (GetProcessPsinfo(pid, &psinfo)) { return psinfo.pr_start.tv_sec; } else { return PROCESS_START_TIME_UNKNOWN; } } static bool GetProcessPstatus(pid_t pid, pstatus_t *pstatus) { char filename[CF_BUFSIZE]; snprintf(filename, CF_BUFSIZE, "/proc/%jd/status", (intmax_t) pid); int fd = open(filename, O_RDONLY); if (fd == -1) { return false; } int res = FullRead(fd, pstatus, sizeof(*pstatus)); close(fd); return res == sizeof(*pstatus); } ProcessState GetProcessState(pid_t pid) { /* This is the documented way to check for zombie process, on Solaris 9 * however I couldn't get it to work: Killing a child process and then reading * /proc/PID/psinfo *before* reaping the dead child, resulted in * psinfo.pr_nlwp == 1 and psinfo.pr_lwp.pr_lwpid == 1. */ #if 0 psinfo_t psinfo; if (GetProcessPsinfo(pid, &psinfo)) { if (psinfo.pr_nlwp == 0 && psinfo.pr_lwp.pr_lwpid == 0) { return PROCESS_STATE_ZOMBIE; } else { /* Then, we must read the "status" file to get * pstatus.pr_lwp.pr_flags, because the psinfo.pr_lwp.pr_flag is * deprecated. */ pstatus_t pstatus; if (GetProcessPstatus(pid &pstatus)) { if (pstatus.pr_lwp.pr_flags & PR_STOPPED) { return PROCESS_STATE_STOPPED; } else { return PROCESS_STATE_RUNNING; } } } } return PROCESS_STATE_DOES_NOT_EXIST; #endif /* HACK WARNING: By experimentation I figured out that on Solaris 9 there is no clear way to figure out if a process is zombie, but if the "status" file is not there while the "psinfo" file is, then it's most probably a zombie. */ pstatus_t pstatus; bool success = GetProcessPstatus(pid, &pstatus); if (!success && errno == ENOENT) /* file does not exist */ { psinfo_t psinfo; if (GetProcessPsinfo(pid, &psinfo)) { /* /proc/PID/psinfo exists, /proc/PID/status does not exist */ return PROCESS_STATE_ZOMBIE; } else /* Neither status nor psinfo could be opened */ { return PROCESS_STATE_DOES_NOT_EXIST; } } /* Read the flags from status, since reading it from psinfo is deprecated. */ if (success) { if (pstatus.pr_lwp.pr_flags & PR_STOPPED) { return PROCESS_STATE_STOPPED; } else { return PROCESS_STATE_RUNNING; } } /* If we reach this point it's probably because /proc/PID/status couldn't * be opened because of EPERM. We can't do anything to that process, so we * might as well pretend it does not exist. */ return PROCESS_STATE_DOES_NOT_EXIST; } cfengine-3.24.2/libpromises/math_eval.c0000644000000000000000000001130515010704253020007 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #define MATH_EVAL_STACK_SIZE 1024 const char *const math_eval_function_names[] = { "ceil", "floor", "log10", "log2", "log", "sqrt", "sin", "cos", "tan", "asin", "acos", "atan", "abs", "step" }; static double _math_eval_step(double p) { return ((p < 0) ? 0 : 1); } typedef double (*MathEvalFunctionType)(double); static const MathEvalFunctionType math_eval_functions[] = { ceil, floor, log10, log2, log, sqrt, sin, cos, tan, asin, acos, atan, fabs, _math_eval_step }; double math_eval_push(double n, double *stack, int *stackp) { if (*stackp > MATH_EVAL_STACK_SIZE) { Log(LOG_LEVEL_ERR, "Math evaluation stack size exceeded"); return 0; } return stack[++(*stackp)]= n; } double math_eval_pop(double *stack, int *stackp) { if (*stackp < 0) { Log(LOG_LEVEL_ERR, "Math evaluation stack could not be popped, internal error!"); return 0; } return stack[(*stackp)--]; } #define YYSTYPE double #define YYPARSE yymath_parse #define YYPARSEFROM yymath_parsefrom #define YY_CTX_LOCAL #define YY_PARSE(T) T #define YY_INPUT(ctx, buf, result, max_size) { \ result = 0; \ if (ctx->input != NULL) \ { \ /*Log(LOG_LEVEL_ERR, "YYINPUT: %s", ctx->input);*/ \ strncpy(buf, ctx->input, max_size); \ int n = strlen(ctx->input)+1; \ if (n > max_size) n = max_size; \ if (n > 0) buf[n - 1]= '\0'; \ result = strlen(buf); \ ctx->input = NULL; \ } \ } #undef malloc #undef realloc #define malloc xmalloc #define realloc xrealloc #define YY_CTX_MEMBERS char *failure; \ const char *input; \ const char *original_input; \ EvalContext *eval_context; \ double result; \ char fname[50]; \ double stack[MATH_EVAL_STACK_SIZE]; \ int stackp; /* Mark unused functions as such */ struct _yycontext; static int yyAccept(struct _yycontext *yy, int tp0) FUNC_UNUSED; static void yyPush(struct _yycontext *yy, char *text, int count) FUNC_UNUSED; static void yyPop(struct _yycontext *yy, char *text, int count) FUNC_UNUSED; static void yySet(struct _yycontext *yy, char *text, int count) FUNC_UNUSED; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #include // Generated from math.peg using 3rdparty/peg-0.1.15 #pragma GCC diagnostic pop double EvaluateMathInfix(EvalContext *ctx, const char *input, char *failure) { yycontext yyctx; memset(&yyctx, 0, sizeof(yycontext)); yyctx.failure = failure; yyctx.original_input = input; yyctx.input = input; yyctx.eval_context = ctx; yyctx.result = 0; yyctx.stackp = -1; yymath_parse(&yyctx); yyrelease(&yyctx); return yyctx.result; } double EvaluateMathFunction(const char *f, double p) { int count = sizeof(math_eval_functions)/sizeof(math_eval_functions[0]); for (int i=0; i < count; i++) { if (strcmp(math_eval_function_names[i], f) == 0) { return (*math_eval_functions[i])(p); } } return p; } cfengine-3.24.2/libpromises/bootstrap.c0000644000000000000000000003051215010704253020065 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include // PrintVersionBanner #include #include #include #include #include #include #include #include #include #include #include #include /* Bootstrapping is a tricky sequence of fragile events. We need to map shakey/IP and identify policy hub IP in a special order to bootstrap the license and agents. During commercial bootstrap: - InitGA (generic-agent) loads the public key - The verifylicense function sets the policy hub but fails to verify license yet as there is no key/IP binding - Policy server gets set in workdir/state/am_policy_hub - The agents gets run and start this all over again, but this time the am_policy_hub is defined and caches the key/IP binding - Now the license has a binding, resolves the policy hub's key and succeeds */ #if defined(__CYGWIN__) || defined(__ANDROID__) bool BootstrapAllowed(void) { return true; } #elif !defined(__MINGW32__) bool BootstrapAllowed(void) { return IsPrivileged(); } #endif /** * @brief Sets both internal C variables as well as policy sys variables. * * Called at bootstrap and after reading policy_server.dat. * Changes sys.policy_hub and sys.policy_hub_port. * NULL is an acceptable value for new_policy_server. Could happen when an * already bootstrapped server re-parses its policies, and the * policy_server.dat file has been removed. Then this function will be called * with NULL as new_policy_server, and cf-serverd will keep running even * without a policy server set. * * @param ctx EvalContext is used to set related variables * @param new_policy_server can be 'host:port', same as policy_server.dat */ void EvalContextSetPolicyServer(EvalContext *ctx, const char *new_policy_server) { // Remove variables if undefined policy server: if ( NULL_OR_EMPTY(new_policy_server) ) { EvalContextVariableRemoveSpecial( ctx, SPECIAL_SCOPE_SYS, "policy_hub" ); EvalContextVariableRemoveSpecial( ctx, SPECIAL_SCOPE_SYS, "policy_hub_port" ); return; } PolicyServerSet(new_policy_server); const char *ip = PolicyServerGetIP(); // Set the sys.policy_hub variable: if ( ip != NULL ) { EvalContextVariablePutSpecial( ctx, SPECIAL_SCOPE_SYS, "policy_hub", ip, CF_DATA_TYPE_STRING, "source=bootstrap" ); } else { EvalContextVariableRemoveSpecial( ctx, SPECIAL_SCOPE_SYS, "policy_hub" ); } // Set the sys.policy_hub_port variable: if (PolicyServerGetPort() != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "policy_hub_port", PolicyServerGetPort(), CF_DATA_TYPE_STRING, "source=bootstrap" ); } else // Default value (CFENGINE_PORT_STR = "5308") is set { EvalContextVariablePutSpecial( ctx, SPECIAL_SCOPE_SYS, "policy_hub_port", CFENGINE_PORT_STR, CF_DATA_TYPE_STRING, "source=bootstrap" ); } } //******************************************************************* // POLICY SERVER FILE FUNCTIONS: //******************************************************************* /** * @brief Reads the policy_server.dat and sets the internal variables. * @param[in] ctx EvalContext used by EvalContextSetPolicyServer() * @param[in] workdir the directory of policy_server.dat usually GetWorkDir() */ void EvalContextSetPolicyServerFromFile(EvalContext *ctx, const char *workdir) { char *contents = PolicyServerReadFile(workdir); EvalContextSetPolicyServer(ctx, contents); free(contents); } //******************************************************************* // POLICY HUB FUNCTIONS: //******************************************************************* /** * @brief Updates sys.last_policy_update variable from $(sys.masterdir)/cf_promises_validated * @param ctx EvalContext to put variable into */ void UpdateLastPolicyUpdateTime(EvalContext *ctx) { // Get the timestamp on policy update struct stat sb; { char cf_promises_validated_filename[CF_MAXVARSIZE]; snprintf(cf_promises_validated_filename, CF_MAXVARSIZE, "%s/cf_promises_validated", GetMasterDir()); MapName(cf_promises_validated_filename); if ((stat(cf_promises_validated_filename, &sb)) != 0) { return; } } char timebuf[26] = { 0 }; cf_strtimestamp_local(sb.st_mtime, timebuf); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "last_policy_update", timebuf, CF_DATA_TYPE_STRING, "source=agent"); } /** * @return True if the file STATEDIR/am_policy_hub exists */ bool GetAmPolicyHub(void) { char path[CF_BUFSIZE] = { 0 }; snprintf(path, sizeof(path), "%s/am_policy_hub", GetStateDir()); MapName(path); struct stat sb; return stat(path, &sb) == 0; } /** * @brief Set the STATEDIR/am_policy_hub marker file. * @param am_policy_hub If true, create marker file. If false, delete it. * @return True if successful */ static char *AmPolicyHubFilename(void) { return StringFormat("%s%cam_policy_hub", GetStateDir(), FILE_SEPARATOR); } bool WriteAmPolicyHubFile(bool am_policy_hub) { char *filename = AmPolicyHubFilename(); if (am_policy_hub) { if (!GetAmPolicyHub()) { if (creat(filename, 0600) == -1) { Log(LOG_LEVEL_ERR, "Error writing marker file '%s'", filename); free(filename); return false; } } } else { if (GetAmPolicyHub()) { if (unlink(filename) != 0) { Log(LOG_LEVEL_ERR, "Error removing marker file '%s'", filename); free(filename); return false; } } } free(filename); return true; } //******************************************************************* // FAILSAFE FUNCTIONS: //******************************************************************* /** * @brief Write the builtin failsafe policy to the default location * @return True if successful */ bool WriteBuiltinFailsafePolicy(const char *inputdir) { char failsafe_path[CF_BUFSIZE]; snprintf(failsafe_path, CF_BUFSIZE - 1, "%s/failsafe.cf", inputdir); MapName(failsafe_path); return WriteBuiltinFailsafePolicyToPath(failsafe_path); } /** * @brief Exposed for testing. Use WriteBuiltinFailsafePolicy. */ bool WriteBuiltinFailsafePolicyToPath(const char *filename) { // The bootstrap.inc file is generated by "make bootstrap-inc" const char *bootstrap_content = #include "bootstrap.inc" ; Log(LOG_LEVEL_INFO, "Writing built-in failsafe policy to '%s'", filename); FILE *fout = safe_fopen(filename, "w"); if (!fout) { Log(LOG_LEVEL_ERR, "Unable to write failsafe to '%s' (fopen: %s)", filename, GetErrorStr()); return false; } fputs(bootstrap_content, fout); fclose(fout); return true; } //******************************************************************* // POLICY FILE FUNCTIONS: //******************************************************************* /** * @brief Removes all files in $(sys.inputdir) * @param inputdir * @return True if successful */ bool RemoveAllExistingPolicyInInputs(const char *inputs_path) { Log(LOG_LEVEL_INFO, "Removing all files in '%s'", inputs_path); struct stat sb; if (stat(inputs_path, &sb) == -1) { if (errno == ENOENT) { return true; } else { Log(LOG_LEVEL_ERR, "Could not stat inputs directory at '%s'. (stat: %s)", inputs_path, GetErrorStr()); return false; } } if (!S_ISDIR(sb.st_mode)) { Log(LOG_LEVEL_ERR, "Inputs path exists at '%s', but it is not a directory", inputs_path); return false; } return DeleteDirectoryTree(inputs_path); } /** * @return True if the file $(sys.masterdir)/promises.cf exists */ bool MasterfileExists(const char *masterdir) { char filename[CF_BUFSIZE] = { 0 }; snprintf(filename, sizeof(filename), "%s/promises.cf", masterdir); MapName(filename); struct stat sb; if (stat(filename, &sb) == -1) { if (errno == ENOENT) { return false; } else { Log(LOG_LEVEL_ERR, "Could not stat file '%s'. (stat: %s)", filename, GetErrorStr()); return false; } } if (!S_ISREG(sb.st_mode)) { Log(LOG_LEVEL_ERR, "Path exists at '%s', but it is not a regular file", filename); return false; } return true; } static char *BootstrapIDFilename(const char *workdir) { assert(workdir != NULL); return StringFormat("%s%cbootstrap_id.dat", workdir, FILE_SEPARATOR); } char *CreateBootstrapIDFile(const char *workdir) { assert(workdir != NULL); char *filename = BootstrapIDFilename(workdir); FILE *file = safe_fopen_create_perms(filename, "w", CF_PERMS_DEFAULT); if (file == NULL) { Log(LOG_LEVEL_ERR, "Unable to write bootstrap id file '%s' (fopen: %s)", filename, GetErrorStr()); free(filename); return NULL; } CryptoInitialize(); #define RANDOM_BYTES 240 / 8 // 240 avoids padding (divisible by 6) #define BASE_64_LENGTH_NO_PADDING (4 * (RANDOM_BYTES / 3)) unsigned char buf[RANDOM_BYTES]; RAND_bytes(buf, RANDOM_BYTES); char *b64_id = StringEncodeBase64(buf, RANDOM_BYTES); fprintf(file, "%s\n", b64_id); fclose(file); free(filename); return b64_id; } char *ReadBootstrapIDFile(const char *workdir) { assert(workdir != NULL); char *const path = BootstrapIDFilename(workdir); Writer *writer = FileRead(path, BASE_64_LENGTH_NO_PADDING + 1, NULL); if (writer == NULL) { // Not having a bootstrap id file is considered normal Log(LOG_LEVEL_DEBUG, "Could not read bootstrap ID from file: '%s'", path); free(path); return NULL; } char *data = StringWriterClose(writer); size_t data_length = strlen(data); assert(data_length == BASE_64_LENGTH_NO_PADDING + 1); assert(data[data_length - 1] == '\n'); if (data_length != BASE_64_LENGTH_NO_PADDING + 1) { Log(LOG_LEVEL_ERR, "'%s' contains invalid data: '%s'", path, data); free(path); free(data); return NULL; } data[data_length - 1] = '\0'; Log(LOG_LEVEL_VERBOSE, "Successfully read bootstrap ID '%s' from file '%s'", data, path); free(path); return data; } void EvalContextSetBootstrapID(EvalContext *ctx, char *bootstrap_id) { EvalContextVariablePutSpecial( ctx, SPECIAL_SCOPE_SYS, "bootstrap_id", bootstrap_id, CF_DATA_TYPE_STRING, "source=bootstrap"); } cfengine-3.24.2/libpromises/parser_helpers.h0000644000000000000000000000445015010704253021075 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ // This header contains types and (inline) functions used // when parsing policy. It is used in a few files related // to parsing, for example cf3lex.l (flex generated lexer), // cf3parse.y (yacc generated parser) and syntax.c // It doesn't really contain the grammar, or syntax // description just some helper functions, to enable those. // The intention is to move a lot of logic (C code) out of // the lex and yacc files to make them easier to understand // and maintain. // It could maybe be combined with parser_state.h, but // there is a distinction, this file does not include anything // about the state of the parser #ifndef CF_PARSER_HELPERS_H #define CF_PARSER_HELPERS_H #include // debug_abort_if_reached() // Blocks are the top level elements of a policy file // (excluding macros). // Currently there are 3 types of blocks; bundle, body, promise typedef enum { PARSER_BLOCK_BUNDLE = 1, PARSER_BLOCK_BODY = 2, PARSER_BLOCK_PROMISE = 3, } ParserBlock; static inline const char *ParserBlockString(ParserBlock b) { switch (b) { case PARSER_BLOCK_BUNDLE: return "bundle"; case PARSER_BLOCK_BODY: return "body"; case PARSER_BLOCK_PROMISE: return "promise"; default: break; } debug_abort_if_reached(); return "ERROR"; } #endif // CF_PARSER_HELPERS_H cfengine-3.24.2/libpromises/ornaments.h0000644000000000000000000000261115010704253020062 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ORNAMENTS_H #define CFENGINE_ORNAMENTS_H /* * Various ornaments in output */ #include #include #include void SpecialTypeBanner(TypeSequence type, int pass); void PromiseBanner(EvalContext *ctx, const Promise *pp); void Banner(const char *s); void Legend(); void BundleBanner(const Bundle *bp, const Rlist *params); void EndBundleBanner(const Bundle *bp); #endif cfengine-3.24.2/libpromises/policy.h0000644000000000000000000001722215010704253017357 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_POLICY_H #define CFENGINE_POLICY_H #include #include #include #include #include typedef enum { POLICY_ELEMENT_TYPE_POLICY, POLICY_ELEMENT_TYPE_BUNDLE, POLICY_ELEMENT_TYPE_BODY, POLICY_ELEMENT_TYPE_BUNDLE_SECTION, POLICY_ELEMENT_TYPE_PROMISE, POLICY_ELEMENT_TYPE_CONSTRAINT } PolicyElementType; typedef struct { PolicyElementType type; const void *subject; char *message; } PolicyError; struct Policy_ { char *release_id; Seq *bundles; Seq *bodies; Seq *custom_promise_types; StringMap *policy_files_hashes; }; typedef struct { size_t start; size_t end; size_t line; size_t context; } SourceOffset; struct Bundle_ { Policy *parent_policy; char *type; char *name; char *ns; Rlist *args; Seq *sections; Seq *custom_sections; char *source_path; SourceOffset offset; }; struct Body_ { Policy *parent_policy; char *type; char *name; char *ns; Rlist *args; Seq *conlist; bool is_custom; char *source_path; SourceOffset offset; }; struct BundleSection_ { Bundle *parent_bundle; char *promise_type; Seq *promises; SourceOffset offset; }; struct Promise_ { BundleSection *parent_section; char *classes; char *comment; char *promiser; Rval promisee; Seq *conlist; const Promise *org_pp; /* A ptr to the unexpanded raw promise */ SourceOffset offset; }; struct Constraint_ { PolicyElementType type; union { Promise *promise; Body *body; } parent; char *lval; Rval rval; char *classes; bool references_body; SourceOffset offset; }; const char *NamespaceDefault(void); Policy *PolicyNew(void); int PolicyCompare(const void *a, const void *b); void PolicyDestroy(Policy *policy); unsigned PolicyHash(const Policy *policy); StringSet *PolicySourceFiles(const Policy *policy); const char *PolicyGetPolicyFileHash(const Policy *policy, const char *policy_file_path); Policy *PolicyMerge(Policy *a, Policy *b); Body *PolicyGetBody(const Policy *policy, const char *ns, const char *type, const char *name); Bundle *PolicyGetBundle(const Policy *policy, const char *ns, const char *type, const char *name); bool PolicyIsRunnable(const Policy *policy); const Policy *PolicyFromPromise(const Promise *promise); char *BundleQualifiedName(const Bundle *bundle); PolicyError *PolicyErrorNew(PolicyElementType type, const void *subject, const char *error_msg, ...); void PolicyErrorDestroy(PolicyError *error); void PolicyErrorWrite(Writer *writer, const PolicyError *error); bool PolicyCheckPartial(const Policy *policy, Seq *errors); bool PolicyCheckRunnable(const EvalContext *ctx, const Policy *policy, Seq *errors); Bundle *PolicyAppendBundle(Policy *policy, const char *ns, const char *name, const char *type, const Rlist *args, const char *source_path); Body *PolicyAppendBody(Policy *policy, const char *ns, const char *name, const char *type, Rlist *args, const char *source_path, bool is_custom); Body *PolicyAppendPromiseBlock(Policy *policy, const char *ns, const char *name, const char *type, Rlist *args, const char *source_path); JsonElement *PolicyToJson(const Policy *policy); JsonElement *BundleToJson(const Bundle *bundle); JsonElement *BodyToJson(const Body *body); Policy *PolicyFromJson(JsonElement *json_policy); void PolicyToString(const Policy *policy, Writer *writer); BundleSection *BundleAppendSection(Bundle *bundle, const char *promise_type); const BundleSection *BundleGetSection(const Bundle *bp, const char *promise_type); Constraint *BodyAppendConstraint(Body *body, const char *lval, Rval rval, const char *classes, bool references_body); Seq *BodyGetConstraint(Body *body, const char *lval); bool BodyHasConstraint(const Body *body, const char *lval); const char *ConstraintGetNamespace(const Constraint *cp); Promise *BundleSectionAppendPromise(BundleSection *section, const char *promiser, Rval promisee, const char *classes, const char *varclasses); void BundleSectionDestroy(BundleSection *section); void PromiseDestroy(Promise *pp); Constraint *PromiseAppendConstraint(Promise *promise, const char *lval, Rval rval, bool references_body); const char *PromiseGetNamespace(const Promise *pp); const Bundle *PromiseGetBundle(const Promise *pp); const Policy *PromiseGetPolicy(const Promise *pp); static inline const char *PromiseGetPromiseType(const Promise *pp) { assert(pp != NULL); return pp->parent_section->promise_type; } void PromisePath(Writer *w, const Promise *pp); const char *PromiseGetHandle(const Promise *pp); int PromiseGetConstraintAsInt(const EvalContext *ctx, const char *lval, const Promise *pp); bool PromiseGetConstraintAsReal(const EvalContext *ctx, const char *lval, const Promise *list, double *value_out); mode_t PromiseGetConstraintAsOctal(const EvalContext *ctx, const char *lval, const Promise *list); uid_t PromiseGetConstraintAsUid(const EvalContext *ctx, const char *lval, const Promise *pp); gid_t PromiseGetConstraintAsGid(const EvalContext *ctx, char *lval, const Promise *pp); Rlist *PromiseGetConstraintAsList(const EvalContext *ctx, const char *lval, const Promise *pp); int PromiseGetConstraintAsBoolean(const EvalContext *ctx, const char *lval, const Promise *list); int PromiseGetConstraintAsBooleanWithDefault(const EvalContext *ctx, const char *lval, const Promise *pp, int default_val, bool with_warning); Constraint *PromiseGetConstraintWithType(const Promise *promise, const char *lval, RvalType type); Constraint *PromiseGetImmediateConstraint(const Promise *promise, const char *lval); void *PromiseGetConstraintAsRval(const Promise *promise, const char *lval, RvalType type); Constraint *PromiseGetConstraint(const Promise *promise, const char *lval); bool PromiseBundleOrBodyConstraintExists(const EvalContext *ctx, const char *lval, const Promise *pp); void PromiseRecheckAllConstraints(const EvalContext *ctx, const Promise *pp); void ConstraintDestroy(Constraint *cp); int ConstraintsGetAsBoolean(const EvalContext *ctx, const char *lval, const Seq *constraints); const char *ConstraintContext(const Constraint *cp); Constraint *EffectiveConstraint(const EvalContext *ctx, Seq *constraints); void *PromiseGetImmediateRvalValue(const char *lval, const Promise *pp, RvalType rtype); char *QualifiedNameNamespaceComponent(const char *qualified_name); char *QualifiedNameScopeComponent(const char *qualified_name); bool BundleTypeCheck(const char *name); Rval DefaultBundleConstraint(const Promise *pp, char *promisetype); bool PolicyHasCustomPromiseType(const Policy *policy, const char *name); #endif cfengine-3.24.2/libpromises/dbm_test_api.c0000644000000000000000000005263415010704253020513 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* lrand48_r() */ #include /* usleep(), syscall()/gettid() */ #include /* xstrndup() */ #include #include #include #include #include /* StringFormat() */ #include #if !HAVE_DECL_GETTID /* Older versions of glibc don't provide a wrapper function for the gettid() * syscall. */ #include static inline pid_t gettid() { return syscall(SYS_gettid); } #endif typedef struct DBItem { char *key; size_t val_size; void *val; } DBItem; DBItem *DBItemNew(const char *key, size_t val_size, void *val) { DBItem *ret = xmalloc(sizeof(DBItem)); ret->key = xstrdup(key); ret->val_size = val_size; ret->val = xmemdup(val, val_size); return ret; } static void DBItemDestroy(DBItem *item) { if (item != NULL) { free(item->key); free(item->val); free(item); } } static __thread struct drand48_data rng_data; static void InitializeRNG(long int seed) { srand48_r(seed, &rng_data); } static long GetRandomNumber(long limit) { long rnd_val; lrand48_r(&rng_data, &rnd_val); /* generates a value in the [0, 2^31) interval */ const long random_max = ((0x80000000 - 1) / limit) * limit; while (rnd_val > random_max) { /* got a bad value past the greatest multiple of the limit interval, * retry (see "modulo bias" if this is unclear) */ lrand48_r(&rng_data, &rnd_val); } return rnd_val % limit; } static Seq *GetDBKeys(DBHandle *db) { DBCursor *cur; bool success = NewDBCursor(db, &cur); if (!success) { return NULL; } Seq *ret = SeqNew(16, free); while (success) { int key_size; char *key; int val_size; void *val; success = NextDB(cur, &key, &key_size, &val, &val_size); if (success) { SeqAppend(ret, xstrndup(key, key_size)); } } DeleteDBCursor(cur); return ret; } /* TODO: LoadDBIntoMap() */ static Seq *LoadDB(DBHandle *db, size_t limit) { DBCursor *cur; bool success = NewDBCursor(db, &cur); if (!success) { return NULL; } Seq *ret = SeqNew(16, DBItemDestroy); size_t remaining = (limit != 0) ? limit : SIZE_MAX; while (success && (remaining > 0)) { int key_size; char *key; int val_size; void *val; success = NextDB(cur, &key, &key_size, &val, &val_size); if (success) { SeqAppend(ret, DBItemNew(key, val_size, val)); remaining--; } } DeleteDBCursor(cur); return ret; } void DoRandomReads(dbid db_id, int keys_refresh_s, long min_interval_ms, long max_interval_ms, bool *terminate) { assert(terminate != NULL); InitializeRNG((long) gettid()); DBHandle *db; bool success = OpenDB(&db, db_id); assert(success); Seq *keys = GetDBKeys(db); assert(keys != NULL); CloseDB(db); size_t n_keys = SeqLength(keys); unsigned long acc_sleeps_ms = 0; while (!*terminate) { long rnd = GetRandomNumber(max_interval_ms - min_interval_ms); unsigned long sleep_for_ms = min_interval_ms + rnd; int ret = usleep(sleep_for_ms * 1000); acc_sleeps_ms += sleep_for_ms; if (ret == -1) { if (errno == EINTR) { continue; } /* else */ /* Should never happen. */ Log(LOG_LEVEL_ERR, "Failed to usleep() for %ld ms: %s", (min_interval_ms + rnd) * 1000, GetErrorStr()); SeqDestroy(keys); return; } rnd = GetRandomNumber(n_keys); unsigned char val[1024]; char *key = SeqAt(keys, rnd); bool success = OpenDB(&db, db_id); assert(success); success = ReadDB(db, key, val, sizeof(val)); assert(success || !HasKeyDB(db, key, strlen(key))); if (acc_sleeps_ms > (keys_refresh_s * 1000)) { SeqDestroy(keys); keys = GetDBKeys(db); assert(keys != NULL); n_keys = SeqLength(keys); acc_sleeps_ms = 0; } CloseDB(db); } SeqDestroy(keys); } struct ReadParams { dbid db_id; int keys_refresh_s; long min_interval_ms; long max_interval_ms; bool *terminate; }; static void *DoRandomReadsRoutine(void *data) { struct ReadParams *params = data; DoRandomReads(params->db_id, params->keys_refresh_s, params->min_interval_ms, params->max_interval_ms, params->terminate); /* Always return NULL, pthread_create() requires a function which returns (void *) */ return NULL; } static bool PruneDB(DBHandle *db, const char *prefix, StringSet *written_keys) { DBCursor *cur; bool success = NewDBCursor(db, &cur); assert(success); bool have_next = success; while (success && have_next) { int key_size; char *key; int val_size; void *val; have_next = NextDB(cur, &key, &key_size, &val, &val_size); if (have_next && StringStartsWith(key, prefix)) { success = DBCursorDeleteEntry(cur); if (success) { StringSetRemove(written_keys, key); } } } DeleteDBCursor(cur); return success; } void DoRandomWrites(dbid db_id, int sample_size_pct, int prune_interval_s, long min_interval_ms, long max_interval_ms, bool *terminate) { assert(terminate != NULL); InitializeRNG((long) gettid()); DBHandle *db; bool success = OpenDB(&db, db_id); assert(success); Seq *items = LoadDB(db, 0); assert(items != NULL); CloseDB(db); const size_t n_items = SeqLength(items); const size_t n_samples = (n_items * sample_size_pct) / 100; assert(n_samples > 0); const size_t sample_nths = n_items / n_samples; /* see below */ StringSet *written_keys = StringSetNew(); unsigned long acc_sleeps_ms = 0; while (!*terminate) { long rnd = GetRandomNumber(max_interval_ms - min_interval_ms); unsigned long sleep_for_ms = min_interval_ms + rnd; int ret = usleep(sleep_for_ms * 1000); acc_sleeps_ms += sleep_for_ms; if (ret == -1) { if (errno == EINTR) { continue; } /* else */ /* Should never happen. */ Log(LOG_LEVEL_ERR, "Failed to usleep() for %ld ms: %s", (min_interval_ms + rnd) * 1000, GetErrorStr()); SeqDestroy(items); return; } /* We only want to use a sample_size portion of all the items given by * sample_size_pct. However, instead of picking a random number in the * 0-sample_size range, we split the full range of all items into * (n_items / n_samples)-ths and then use the first item from the * respective nth. For example, if using 30% of 10 items, we would only * use the items at indices 0, 3 and 6. * * This potentially gives us better sample from the original set where * similar items are likely to be next to each other. */ rnd = GetRandomNumber(n_items); size_t idx = ((rnd * n_samples) / n_items) * sample_nths; DBItem *item = SeqAt(items, idx); success = OpenDB(&db, db_id); assert(success); /* Derive a key for our new item from the thread ID and the original * item's key so that we don't mess with the original item and we can * clean after ourselves (LMDB has a limit of 511 bytes for the key). */ char *key = StringFormat("test_%ju_%.400s", (uintmax_t) gettid(), item->key); success = WriteDB(db, key, item->val, item->val_size); assert(success); StringSetAdd(written_keys, key); /* takes ownership of key */ if (acc_sleeps_ms > (prune_interval_s * 1000)) { char *key_prefix = StringFormat("test_%ju_", (uintmax_t) gettid()); success = PruneDB(db, key_prefix, written_keys); free(key_prefix); assert(success); acc_sleeps_ms = 0; } CloseDB(db); } success = OpenDB(&db, db_id); assert(success); /* Clean after ourselves. */ SetIterator iter = StringSetIteratorInit(written_keys); char *key; while ((key = StringSetIteratorNext(&iter)) != NULL) { success = DeleteDB(db, key); assert(success); } CloseDB(db); SeqDestroy(items); } struct WriteParams { dbid db_id; int sample_size_pct; int prune_interval_s; long min_interval_ms; long max_interval_ms; bool *terminate; }; static void *DoRandomWritesRoutine(void *data) { struct WriteParams *params = data; DoRandomWrites(params->db_id, params->sample_size_pct, params->prune_interval_s, params->min_interval_ms, params->max_interval_ms, params->terminate); /* Always return NULL, pthread_create() requires a function which returns (void *) */ return NULL; } void DoRandomIterations(dbid db_id, long min_interval_ms, long max_interval_ms, bool *terminate) { assert(terminate != NULL); InitializeRNG((long)gettid()); while (!terminate) { long rnd = GetRandomNumber(max_interval_ms - min_interval_ms); unsigned long sleep_for_ms = min_interval_ms + rnd; int ret = usleep(sleep_for_ms * 1000); if (ret == -1) { if (errno == EINTR) { continue; } /* else */ /* Should never happen. */ Log(LOG_LEVEL_ERR, "Failed to usleep() for %ld ms: %s", (min_interval_ms + rnd) * 1000, GetErrorStr()); return; } DBHandle *db; bool success = OpenDB(&db, db_id); assert(success); DBCursor *cur; success = NewDBCursor(db, &cur); assert(success); while (success) { int key_size; char *key; int val_size; void *val; success = NextDB(cur, &key, &key_size, &val, &val_size); } DeleteDBCursor(cur); CloseDB(db); } } struct IterParams { dbid db_id; long min_interval_ms; long max_interval_ms; bool *terminate; }; static void *DoRandomIterationsRoutine(void *data) { struct IterParams *params = data; DoRandomIterations(params->db_id, params->min_interval_ms, params->max_interval_ms, params->terminate); return NULL; } struct DBLoadSimulation_ { struct ReadParams read_params; pthread_t read_th; bool read_th_started; bool read_th_terminate; struct WriteParams write_params; pthread_t write_th; bool write_th_started; bool write_th_terminate; struct IterParams iter_params; pthread_t iter_th; bool iter_th_started; bool iter_th_terminate; }; DBLoadSimulation *SimulateDBLoad(dbid db_id, int read_keys_refresh_s, long read_min_interval_ms, long read_max_interval_ms, int write_sample_size_pct, int write_prune_interval_s, long write_min_interval_ms, long write_max_interval_ms, long iter_min_interval_ms, long iter_max_interval_ms) { /* Try to open the DB as a safety check. */ DBHandle *db; bool success = OpenDB(&db, db_id); if (!success) { /* Not a nice log message, but this is testing/debugging code normal * users should never run and face. */ Log(LOG_LEVEL_ERR, "Failed to open DB with ID %d", db_id); return NULL; } CloseDB(db); DBLoadSimulation *simulation = xcalloc(sizeof(DBLoadSimulation), 1); simulation->read_params.db_id = db_id; simulation->read_params.terminate = &(simulation->read_th_terminate); simulation->read_params.keys_refresh_s = read_keys_refresh_s; simulation->read_params.min_interval_ms = read_min_interval_ms; simulation->read_params.max_interval_ms = read_max_interval_ms; simulation->write_params.db_id = db_id; simulation->write_params.terminate = &(simulation->write_th_terminate); simulation->write_params.sample_size_pct = write_sample_size_pct; simulation->write_params.prune_interval_s = write_prune_interval_s; simulation->write_params.min_interval_ms = write_min_interval_ms; simulation->write_params.max_interval_ms = write_max_interval_ms; simulation->iter_params.db_id = db_id; simulation->iter_params.terminate = &(simulation->iter_th_terminate); simulation->iter_params.min_interval_ms = iter_min_interval_ms; simulation->iter_params.max_interval_ms = iter_max_interval_ms; if ((simulation->read_params.keys_refresh_s != 0) || (simulation->read_params.min_interval_ms != 0) || (simulation->read_params.max_interval_ms != 0)) { int ret = pthread_create(&(simulation->read_th), NULL, DoRandomReadsRoutine, &(simulation->read_params)); simulation->read_th_started = (ret == 0); if (!simulation->read_th_started) { Log(LOG_LEVEL_ERR, "Failed to start read simulation thread: %s", GetErrorStrFromCode(ret)); } } if ((simulation->write_params.prune_interval_s != 0) || (simulation->write_params.min_interval_ms != 0) || (simulation->write_params.max_interval_ms != 0)) { int ret = pthread_create(&(simulation->write_th), NULL, DoRandomWritesRoutine, &(simulation->write_params)); simulation->write_th_started = (ret == 0); if (!simulation->write_th_started) { Log(LOG_LEVEL_ERR, "Failed to start write simulation thread: %s", GetErrorStrFromCode(ret)); } } if ((simulation->iter_params.min_interval_ms != 0) || (simulation->iter_params.max_interval_ms != 0)) { int ret = pthread_create(&(simulation->iter_th), NULL, DoRandomIterationsRoutine, &(simulation->iter_params)); simulation->iter_th_started = (ret == 0); if (!simulation->iter_th_started) { Log(LOG_LEVEL_ERR, "Failed to start iteration simulation thread: %s", GetErrorStrFromCode(ret)); } } if (!simulation->read_th_started && !simulation->write_th_started && !simulation->iter_th_started) { Log(LOG_LEVEL_ERR, "No simulation running"); free(simulation); return NULL; } return simulation; } void StopSimulation(DBLoadSimulation *simulation) { /* Signal threads to terminate. */ simulation->read_th_terminate = true; simulation->write_th_terminate = true; simulation->iter_th_terminate = true; int ret; struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { Log(LOG_LEVEL_ERR, "Failed to get real time clock: %s", GetErrorStr()); Log(LOG_LEVEL_NOTICE, "Joining simulation threads with no timeout"); if (simulation->read_th_started) { ret = pthread_join(simulation->read_th, NULL); simulation->read_th_started = (ret == 0); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join read simulation thread: %s", GetErrorStrFromCode(ret)); } } if (simulation->write_th_started) { ret = pthread_join(simulation->write_th, NULL); simulation->write_th_started = (ret == 0); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join write simulation thread: %s", GetErrorStrFromCode(ret)); } } if (simulation->iter_th_started) { ret = pthread_join(simulation->iter_th, NULL); simulation->iter_th_started = (ret == 0); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join iteration simulation thread: %s", GetErrorStrFromCode(ret)); } } } /* Give at most 5 seconds to threads to terminate. */ ts.tv_sec += 5; if (simulation->read_th_started) { ret = pthread_timedjoin_np(simulation->read_th, NULL, &ts); simulation->read_th_started = (ret != 0); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join read simulation thread: %s", GetErrorStrFromCode(ret)); } } if (simulation->write_th_started) { ret = pthread_timedjoin_np(simulation->write_th, NULL, &ts); simulation->write_th_started = (ret != 0); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join write simulation thread: %s", GetErrorStrFromCode(ret)); } } if (simulation->iter_th_started) { ret = pthread_timedjoin_np(simulation->iter_th, NULL, &ts); simulation->iter_th_started = (ret != 0); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join iteration simulation thread: %s", GetErrorStrFromCode(ret)); } } if (simulation->read_th_started || simulation->write_th_started || simulation->iter_th_started) { Log(LOG_LEVEL_ERR, "Failed to stop simulation, leaking simulation data"); } else { free(simulation); } } struct DBFilament_ { dbid db_id; StringSet *items; }; DBFilament *FillUpDB(dbid db_id, int usage_pct) { DBHandle *db; bool success = OpenDB(&db, db_id); if (!success) { Log(LOG_LEVEL_ERR, "Failed to open DB with ID %d", db_id); return NULL; } int usage = GetDBUsagePercentage(db); if (usage == -1) { Log(LOG_LEVEL_ERR, "Cannot determine usage of the DB with ID %d", db_id); CloseDB(db); return NULL; } /* We need just one item. */ Seq *items = LoadDB(db, 1); if ((items == NULL) || (SeqLength(items) == 0)) { Log(LOG_LEVEL_ERR, "No DB item to use as a template for fillament"); CloseDB(db); return NULL; } DBItem *item = SeqAt(items, 0); CloseDB(db); StringSet *added_keys = StringSetNew(); size_t iter_idx = 0; pid_t tid = gettid(); while (usage < usage_pct) { success = OpenDB(&db, db_id); assert(success); /* Derive a key for our new item from an index, the thread ID and the * original item's key so that we don't mess with the original item and * we can clean after ourselves (LMDB has a limit of 511 bytes for the * key). */ /* Add 1000 items in each iteration so that each iteration makes some * difference in the DB usage and we don't have to do so many * iterations. */ for (size_t i = 0; i < 1000; i++) { char *key = StringFormat("test_%ju_%.200s_%zd_%zd", (uintmax_t) tid, item->key, iter_idx, i); success = WriteDB(db, key, item->val, item->val_size); assert(success); StringSetAdd(added_keys, key); /* takes ownership of key */ } iter_idx++; usage = GetDBUsagePercentage(db); assert(usage != -1); /* didn't happen at first, should always work */ CloseDB(db); } SeqDestroy(items); DBFilament *ret = xmalloc(sizeof(DBFilament)); ret->db_id = db_id; ret->items = added_keys; return ret; } void RemoveFilament(DBFilament *filament) { if (filament == NULL) { /* Nothing to do. */ return; } if (StringSetSize(filament->items) == 0) { StringSetDestroy(filament->items); free(filament); } DBHandle *db; bool success = OpenDB(&db, filament->db_id); if (!success) { Log(LOG_LEVEL_ERR, "Failed to open DB with ID %d", filament->db_id); return; } SetIterator iter = StringSetIteratorInit(filament->items); char *key; while ((key = StringSetIteratorNext(&iter)) != NULL) { success = DeleteDB(db, key); assert(success); } StringSetDestroy(filament->items); free(filament); CloseDB(db); } cfengine-3.24.2/libpromises/modes.c0000644000000000000000000002024715010704253017163 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include /***************************************************************/ enum modestate { wild, who, which }; enum modesort { unknown, numeric, symbolic }; /*******************************************************************/ static bool CheckModeState(enum modestate stateA, enum modestate stateB, enum modesort modeA, enum modesort modeB, char ch); static bool SetModeMask(char action, int value, int affected, mode_t *p, mode_t *m); /***************************************************************/ bool ParseModeString(const char *modestring, mode_t *plusmask, mode_t *minusmask) { int affected = 0, value = 0, gotaction; bool no_error = true; char action = '='; enum modestate state = wild; enum modesort found_sort = unknown; /* Already found "sort" of mode */ enum modesort sort = unknown; /* Sort of started but not yet finished mode */ *plusmask = *minusmask = 0; if (modestring == NULL) { return true; } gotaction = false; for (const char *sp = modestring; true; sp++) { switch (*sp) { case 'a': no_error = CheckModeState(who, state, symbolic, sort, *sp); affected |= 07777; sort = symbolic; break; case 'u': no_error = CheckModeState(who, state, symbolic, sort, *sp); affected |= 04700; sort = symbolic; break; case 'g': no_error = CheckModeState(who, state, symbolic, sort, *sp); affected |= 02070; sort = symbolic; break; case 'o': no_error = CheckModeState(who, state, symbolic, sort, *sp); affected |= 00007; sort = symbolic; break; case '+': case '-': case '=': if (gotaction) { Log(LOG_LEVEL_ERR, "Too many +-= in mode string"); return false; } no_error = CheckModeState(who, state, symbolic, sort, *sp); action = *sp; state = which; gotaction = true; sort = unknown; break; case 'r': no_error = CheckModeState(which, state, symbolic, sort, *sp); value |= 0444 & affected; sort = symbolic; break; case 'w': no_error = CheckModeState(which, state, symbolic, sort, *sp); value |= 0222 & affected; sort = symbolic; break; case 'x': no_error = CheckModeState(which, state, symbolic, sort, *sp); value |= 0111 & affected; sort = symbolic; break; case 's': no_error = CheckModeState(which, state, symbolic, sort, *sp); value |= 06000 & affected; sort = symbolic; break; case 't': no_error = CheckModeState(which, state, symbolic, sort, *sp); value |= 01000; sort = symbolic; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': no_error = CheckModeState(which, state, numeric, sort, *sp); sort = numeric; gotaction = true; state = which; affected = 07777; /* TODO: Hard-coded; see below */ sscanf(sp, "%o", &value); if (value & S_IFMT) { Log(LOG_LEVEL_INFO, "Mode-Value is not entirely within the system's allowed permissions (octal %o) and will be filtered accordingly : %s", S_IFMT, modestring); } /* stat() returns the file types in the mode, but they * can't be set. So we clear the file-type as per POSIX * 2001 instead of erroring out, leaving just the * permissions. */ value &= ~S_IFMT; if (value > 07777) /* TODO: Hardcoded ! Is this correct for all sorts of Unix ? What about NT ? Any (POSIX)-constants ?? */ { Log(LOG_LEVEL_ERR, "Mode-Value too big : %s", modestring); return false; } while ((isdigit((int) *sp)) && (*sp != '\0')) { sp++; } sp--; break; case ',': if (!SetModeMask(action, value, affected, plusmask, minusmask)) { return false; } if ((found_sort != unknown) && (found_sort != sort)) { Log(LOG_LEVEL_INFO, "Symbolic and numeric form for modes mixed"); } found_sort = sort; sort = unknown; action = '='; affected = 0; value = 0; gotaction = false; state = who; break; case '\0': if ((state == who) || (value == 0)) { if ((strcmp(modestring, "0000") != 0) && (strcmp(modestring, "000") != 0)) { Log(LOG_LEVEL_ERR, "mode string is incomplete"); return false; } } if (!SetModeMask(action, value, affected, plusmask, minusmask)) { return false; } if ((found_sort != unknown) && (found_sort != sort)) { Log(LOG_LEVEL_INFO, "Symbolic and numeric form for modes mixed"); } Log(LOG_LEVEL_DEBUG, "Modestring [PLUS = %jo] [MINUS = %jo]", (uintmax_t) *plusmask, (uintmax_t) *minusmask); return true; default: Log(LOG_LEVEL_ERR, "Invalid mode string (%s)", modestring); return false; } } if (!no_error) { Log(LOG_LEVEL_ERR, "Error validating mode string %s", modestring); } return no_error; } /*********************************************************/ static bool CheckModeState(enum modestate stateA, enum modestate stateB, enum modesort sortA, enum modesort sortB, char ch) { if ((stateA != wild) && (stateB != wild) && (stateA != stateB)) { Log(LOG_LEVEL_ERR, "Mode string constant (%c) used out of context", ch); return false; } if ((sortA != unknown) && (sortB != unknown) && (sortA != sortB)) { Log(LOG_LEVEL_ERR, "Symbolic and numeric filemodes mixed within expression"); return false; } return true; } /*********************************************************/ static bool SetModeMask(char action, int value, int affected, mode_t *p, mode_t *m) { switch (action) { case '+': *p |= value; *m |= 0; return true; case '-': *p |= 0; *m |= value; return true; case '=': *p |= value; *m |= ((~value) & 07777 & affected); return true; default: Log(LOG_LEVEL_ERR, "Mode directive %c is unknown", action); return false; } } cfengine-3.24.2/libpromises/cf3.defs.h0000644000000000000000000012166315010704253017460 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CF3_DEFS_H #define CFENGINE_CF3_DEFS_H /* ALWAYS INCLUDE EITHER THIS FILE OR platform.h FIRST */ #include #include #include /* HashMethod */ #include #include #include /* CF_MAXVARSIZE, CF_BUFSIZE etc */ #include /* ProtocolVersion, etc */ #include /* xsnprintf, ProgrammingError etc */ /*******************************************************************/ /* Undef platform specific defines that pollute our namespace */ /*******************************************************************/ #ifdef interface #undef interface #endif /*******************************************************************/ /* Various defines */ /*******************************************************************/ #define CF_MAXFRAGMENT 19 /* abbreviate long promise names to 2*MAXFRAGMENT+3 */ #define CF_NONCELEN (CF_BUFSIZE/16) #define CF_MAXLINKSIZE 256 #define CF_PROCCOLS 16 #define CF_MACROALPHABET 61 /* a-z, A-Z plus a bit */ #define CF_ALPHABETSIZE 256 #define CF_SAMEMODE 7777 /* CF_SAME_OWNER/GROUP should be -1; chown(-1) doesn't change ownership. */ #define CF_SAME_OWNER ((uid_t)-1) #define CF_UNKNOWN_OWNER ((uid_t)-2) #define CF_SAME_GROUP ((gid_t)-1) #define CF_UNKNOWN_GROUP ((gid_t)-2) #define CF_INFINITY ((int)999999999) #define CF_MONDAY_MORNING 345600 #define MINUTES_PER_HOUR 60 #define SECONDS_PER_MINUTE 60 #define SECONDS_PER_HOUR (60 * SECONDS_PER_MINUTE) #define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR) #define SECONDS_PER_WEEK (7 * SECONDS_PER_DAY) #define SECONDS_PER_YEAR (365 * SECONDS_PER_DAY) /* Long-term monitoring constants */ #define HOURS_PER_SHIFT 6 #define SECONDS_PER_SHIFT (HOURS_PER_SHIFT * SECONDS_PER_HOUR) #define SHIFTS_PER_DAY 4 #define SHIFTS_PER_WEEK (4*7) #define MAX_MONTH_NAME 9 #define MAX_DIGEST_BYTES (512 / 8) /* SHA-512 */ #define MAX_DIGEST_HEX (MAX_DIGEST_BYTES * 2) /*******************************************************************/ #define CF_FILECHANGE "file_change.log" #define CF_FILECHANGE_NEW "file_changes.log" #define CF_PROMISE_LOG "promise_summary.log" #define CF_ENV_FILE "env_data" #define CF_DB_REPAIR_TRIGGER "db_repair_required" #define CF_SAVED ".cfsaved" #define CF_EDITED ".cfedited" #define CF_NEW ".cfnew" #define CFD_TERMINATOR "---cfXen/gine/cfXen/gine---" #define CFD_TRUE "CFD_TRUE" #define CFD_FALSE "CFD_FALSE" #define CFD_FALSE_SIZE sizeof(CFD_FALSE) // size of CFD_FALSE including terminator #define CF_ANYCLASS "any" #define CF_SMALL_OFFSET 2 #define CF_NS ':' // namespace character separator /* Mangled namespace and scope characters, in order for the iteration engine * to VariablePut() to THIS scope single elements of namespaced iterables * (slists/containers). See expand.c and iteration.c. */ #define CF_MANGLED_NS '*' #define CF_MANGLED_SCOPE '#' /*****************************************************************************/ /* Auditing key */ typedef enum { // Logging of outcomes in cf-agent.c: PROMISE_RESULT_SKIPPED = 's', // PROMISE_RESULT_NOOP = 'n', // Kept PROMISE_RESULT_CHANGE = 'c', // Repaired PROMISE_RESULT_WARN = 'w', // Not kept PROMISE_RESULT_FAIL = 'f', // Not kept PROMISE_RESULT_DENIED = 'd', // Not kept PROMISE_RESULT_TIMEOUT = 't', // Timed out PROMISE_RESULT_INTERRUPTED = 'i' // Not kept } PromiseResult; /*****************************************************************************/ #define CF_FAILEDSTR "BAD: Unspecified server refusal (see verbose server output)" #define CF_CHANGEDSTR1 "BAD: File changed " /* Split this so it cannot be recognized */ #define CF_CHANGEDSTR2 "while copying" #define CF_START_DOMAIN "undefined.domain" #define CF_GRAINS 64 #define CF_NETATTR 7 /* icmp udp dns tcpsyn tcpfin tcpack */ #define CF_MEASURE_INTERVAL (5.0*60.0) #define CF_SHIFT_INTERVAL (6*3600) #define CF_OBSERVABLES 100 /* Special exit codes */ #define EC_EVAL_ABORTED 6 /* like SIGABRT, but signal exit codes are 120+SIG */ typedef struct { char *name; char *description; char *units; double expected_minimum; double expected_maximum; bool consolidable; } MonitoringSlot; enum observables { ob_users, ob_rootprocs, ob_otherprocs, ob_diskfree, ob_loadavg, ob_netbiosns_in, ob_netbiosns_out, ob_netbiosdgm_in, ob_netbiosdgm_out, ob_netbiosssn_in, ob_netbiosssn_out, ob_imap_in, ob_imap_out, ob_cfengine_in, ob_cfengine_out, ob_nfsd_in, ob_nfsd_out, ob_smtp_in, ob_smtp_out, ob_www_in, ob_www_out, ob_ftp_in, ob_ftp_out, ob_ssh_in, ob_ssh_out, ob_wwws_in, ob_wwws_out, ob_icmp_in, ob_icmp_out, ob_udp_in, ob_udp_out, ob_dns_in, ob_dns_out, ob_tcpsyn_in, ob_tcpsyn_out, ob_tcpack_in, ob_tcpack_out, ob_tcpfin_in, ob_tcpfin_out, ob_tcpmisc_in, ob_tcpmisc_out, ob_webaccess, ob_weberrors, ob_syslog, ob_messages, ob_temp0, ob_temp1, ob_temp2, ob_temp3, ob_cpuall, ob_cpu0, ob_cpu1, ob_cpu2, ob_cpu3, ob_microsoft_ds_in, ob_microsoft_ds_out, ob_www_alt_in, ob_www_alt_out, ob_imaps_in, ob_imaps_out, ob_ldap_in, ob_ldap_out, ob_ldaps_in, ob_ldaps_out, ob_mongo_in, ob_mongo_out, ob_mysql_in, ob_mysql_out, ob_postgresql_in, ob_postgresql_out, ob_ipp_in, ob_ipp_out, ob_spare }; #include /* QPoint */ typedef struct { time_t t; QPoint Q; } Event; typedef struct { time_t last_seen; QPoint Q[CF_OBSERVABLES]; } Averages; /******************************************************************/ /** Data for an individual promise (lock), as it's stored in the lock DB * (/var/cfengine/state/cf_lock.lmdb). This is the value, the key is an MD5 * hash of various strings identifying the promise. * * Most C code doesn't use this struct directly, instead AcquireLock() is called * which uses functions in locks.c to read the LockData from LMDB and create a * new CfLock struct. * * Please ensure the padding in this struct is initialized to 0 * LockData lock = { 0 }; // Will zero padding as well as members * lock.pid = [...] */ typedef struct { pid_t pid; // 4 bytes // 4 bytes padding time_t time; // 8 bytes time_t process_start_time; // 8 bytes } LockData; /*****************************************************************************/ #ifdef __MINGW32__ # define NULLFILE "nul" # define EXEC_SUFFIX ".exe" #else # define NULLFILE "/dev/null" # define EXEC_SUFFIX "" #endif /* !__MINGW32__ */ #define CF_WORDSIZE 8 /* Number of bytes in a word */ /*******************************************************************/ typedef struct Item_ Item; /*******************************************************************/ typedef enum { CF_SIZE_ABS, CF_SIZE_PERCENT } CfSize; /*******************************************************************/ typedef enum { CONTEXT_STATE_POLICY_RESET, /* Policy when trying to add already defined persistent states */ CONTEXT_STATE_POLICY_PRESERVE } PersistentClassPolicy; /*******************************************************************/ typedef struct UidList_ UidList; // TODO: why do UIDs have their own list type? Clean up. struct UidList_ { #ifdef __MINGW32__ // TODO: remove uid for NT ? char sid[CF_MAXSIDSIZE]; /* Invalid sid indicates unset */ #endif /* __MINGW32__ */ uid_t uid; char *uidname; /* when uid is -2 */ UidList *next; }; /*******************************************************************/ typedef struct GidList_ GidList; // TODO: why do UIDs have their own list type? Clean up. struct GidList_ { gid_t gid; char *gidname; /* when gid is -2 */ GidList *next; }; /*************************************************************************/ /* Fundamental (meta) types */ /*************************************************************************/ #define CF_UNDEFINED -1 #define CF_NOINT -678L #define CF_UNDEFINED_ITEM (void *)0x1234 #define DEFAULTMODE ((mode_t)0700) #define CF_DONEPASSES 4 #define CFPULSETIME 60 /*************************************************************************/ /* Parsing and syntax tree structures */ /*************************************************************************/ extern const int CF3_MODULES; /*************************************************************************/ typedef struct Policy_ Policy; typedef struct Bundle_ Bundle; typedef struct Body_ Body; typedef struct Promise_ Promise; typedef struct BundleSection_ BundleSection; typedef struct FnCall_ FnCall; /*************************************************************************/ /* Abstract datatypes */ /*************************************************************************/ typedef enum { CF_DATA_TYPE_STRING, CF_DATA_TYPE_INT, CF_DATA_TYPE_REAL, CF_DATA_TYPE_STRING_LIST, CF_DATA_TYPE_INT_LIST, CF_DATA_TYPE_REAL_LIST, CF_DATA_TYPE_OPTION, CF_DATA_TYPE_OPTION_LIST, CF_DATA_TYPE_BODY, CF_DATA_TYPE_BUNDLE, CF_DATA_TYPE_CONTEXT, CF_DATA_TYPE_CONTEXT_LIST, CF_DATA_TYPE_INT_RANGE, CF_DATA_TYPE_REAL_RANGE, CF_DATA_TYPE_COUNTER, CF_DATA_TYPE_CONTAINER, CF_DATA_TYPE_NONE } DataType; /*************************************************************************/ #define CF_COMMONC "common" #define CF_AGENTC "agent" #define CF_SERVERC "server" #define CF_MONITORC "monitor" #define CF_EXECC "executor" #define CF_RUNC "runagent" #define CF_KEYGEN "keygenerator" #define CF_HUBC "hub" typedef enum { AGENT_TYPE_COMMON, AGENT_TYPE_AGENT, AGENT_TYPE_SERVER, AGENT_TYPE_MONITOR, AGENT_TYPE_EXECUTOR, AGENT_TYPE_RUNAGENT, AGENT_TYPE_KEYGEN, AGENT_TYPE_HUB, AGENT_TYPE_NOAGENT } AgentType; /*************************************************************************/ typedef enum { COMMON_CONTROL_BUNDLESEQUENCE, COMMON_CONTROL_GOALPATTERNS, COMMON_CONTROL_IGNORE_MISSING_BUNDLES, COMMON_CONTROL_IGNORE_MISSING_INPUTS, COMMON_CONTROL_INPUTS, COMMON_CONTROL_VERSION, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER, COMMON_CONTROL_OUTPUT_PREFIX, COMMON_CONTROL_DOMAIN, COMMON_CONTROL_REQUIRE_COMMENTS, COMMON_CONTROL_LICENSES, COMMON_CONTROL_SITE_CLASSES, COMMON_CONTROL_SYSLOG_HOST, COMMON_CONTROL_SYSLOG_PORT, COMMON_CONTROL_SYSTEM_LOG_LEVEL, COMMON_CONTROL_FIPS_MODE, COMMON_CONTROL_BWLIMIT, COMMON_CONTROL_CACHE_SYSTEM_FUNCTIONS, COMMON_CONTROL_PROTOCOL_VERSION, COMMON_CONTROL_TLS_CIPHERS, COMMON_CONTROL_TLS_MIN_VERSION, COMMON_CONTROL_PACKAGE_INVENTORY, COMMON_CONTROL_PACKAGE_MODULE, COMMON_CONTROL_MAX } CommonControl; /*************************************************************************/ typedef enum { AGENT_CONTROL_ABORTCLASSES, AGENT_CONTROL_ABORTBUNDLECLASSES, AGENT_CONTROL_ADDCLASSES, AGENT_CONTROL_AGENTACCESS, AGENT_CONTROL_AGENTFACILITY, AGENT_CONTROL_ALLCLASSESREPORT, AGENT_CONTROL_ALWAYSVALIDATE, AGENT_CONTROL_AUDITING, AGENT_CONTROL_BINARYPADDINGCHAR, AGENT_CONTROL_BINDTOINTERFACE, AGENT_CONTROL_HASHUPDATES, AGENT_CONTROL_CHILDLIBPATH, AGENT_CONTROL_CHECKSUM_ALERT_TIME, AGENT_CONTROL_DEFAULTCOPYTYPE, AGENT_CONTROL_DRYRUN, AGENT_CONTROL_EDITBINARYFILESIZE, AGENT_CONTROL_EDITFILESIZE, AGENT_CONTROL_ENVIRONMENT, AGENT_CONTROL_EXCLAMATION, AGENT_CONTROL_EXPIREAFTER, AGENT_CONTROL_FSINGLECOPY, AGENT_CONTROL_FAUTODEFINE, AGENT_CONTROL_HOSTNAMEKEYS, AGENT_CONTROL_IFELAPSED, AGENT_CONTROL_INFORM, AGENT_CONTROL_INTERMITTENCY, AGENT_CONTROL_MAX_CHILDREN, AGENT_CONTROL_MAXCONNECTIONS, AGENT_CONTROL_MOUNTFILESYSTEMS, AGENT_CONTROL_NONALPHANUMFILES, AGENT_CONTROL_REPCHAR, AGENT_CONTROL_REFRESH_PROCESSES, AGENT_CONTROL_REPOSITORY, AGENT_CONTROL_SECUREINPUT, AGENT_CONTROL_SENSIBLECOUNT, AGENT_CONTROL_SENSIBLESIZE, AGENT_CONTROL_SKIPIDENTIFY, AGENT_CONTROL_SUSPICIOUSNAMES, AGENT_CONTROL_SYSLOG, AGENT_CONTROL_TRACK_VALUE, AGENT_CONTROL_TIMEZONE, AGENT_CONTROL_TIMEOUT, AGENT_CONTROL_VERBOSE, AGENT_CONTROL_REPORTCLASSLOG, AGENT_CONTROL_SELECT_END_MATCH_EOF, AGENT_CONTROL_COPYFROM_RESTRICT_KEYS, AGENT_CONTROL_NONE } AgentControl; /*************************************************************************/ typedef enum { EXEC_CONTROL_SPLAYTIME, EXEC_CONTROL_MAILFROM, EXEC_CONTROL_MAILTO, EXEC_CONTROL_MAILSUBJECT, EXEC_CONTROL_SMTPSERVER, EXEC_CONTROL_MAILMAXLINES, EXEC_CONTROL_MAILFILTER_INCLUDE, EXEC_CONTROL_MAILFILTER_EXCLUDE, EXEC_CONTROL_SCHEDULE, EXEC_CONTROL_EXECUTORFACILITY, EXEC_CONTROL_EXECCOMMAND, EXEC_CONTROL_AGENT_EXPIREAFTER, EXEC_CONTROL_RUNAGENT_ALLOW_USERS, EXEC_CONTROL_NONE } ExecControl; typedef enum { EDIT_ORDER_BEFORE, EDIT_ORDER_AFTER } EditOrder; /*************************************************************************/ typedef enum { TYPE_SEQUENCE_META, TYPE_SEQUENCE_VARS, TYPE_SEQUENCE_DEFAULTS, TYPE_SEQUENCE_CONTEXTS, TYPE_SEQUENCE_USERS, TYPE_SEQUENCE_FILES, TYPE_SEQUENCE_PACKAGES, TYPE_SEQUENCE_ENVIRONMENTS, TYPE_SEQUENCE_METHODS, TYPE_SEQUENCE_PROCESSES, TYPE_SEQUENCE_SERVICES, TYPE_SEQUENCE_COMMANDS, TYPE_SEQUENCE_STORAGE, TYPE_SEQUENCE_DATABASES, TYPE_SEQUENCE_REPORTS, TYPE_SEQUENCE_NONE } TypeSequence; /*************************************************************************/ /* Syntax module range/pattern constants for type validation */ /*************************************************************************/ #define CF_BUNDLE (void*)1234 /* any non-null value, not used */ /* Initial values for max=low, min=high when determining a range, for * which we'll revise max upwards and in downwards if given meaningful * bounds for them. Quite why they're these values, rather than 9999 * (longest string of 9s to fit in an int16) or 999999999 (similar for * int32) remains a mystery. */ #define CF_HIGHINIT 999999L #define CF_LOWINIT -999999L #define CF_BOOL "true,false,yes,no,on,off" #define CF_LINKRANGE "symlink,hardlink,relative,absolute" #define CF_TIMERANGE "0,2147483647" /* i.e. "0,0x7fffffff" */ /* Syntax checker accepts absurdly big numbers for backwards * compatibility. WARNING: internally they are stored as longs, possibly * being truncated to LONG_MAX within IntFromString(). */ #define CF_VALRANGE "0,99999999999" #define CF_INTRANGE "-99999999999,99999999999" #define CF_INTLISTRANGE "[-0-9_$(){}\\[\\].]+" #define CF_REALRANGE "-9.99999E100,9.99999E100" #define CF_CHARRANGE "^.$" #define CF_MODERANGE "[0-7augorwxst,+-=]+" #define CF_BSDFLAGRANGE "[+-]*[(arch|archived|nodump|opaque|sappnd|sappend|schg|schange|simmutable|sunlnk|sunlink|uappnd|uappend|uchg|uchange|uimmutable|uunlnk|uunlink)]+" #define CF_CLASSRANGE "[a-zA-Z0-9_!&@@$|.()\\[\\]{}:]+" #define CF_IDRANGE "[a-zA-Z0-9_$(){}\\[\\].:]+" #define CF_USERRANGE "[a-zA-Z0-9_$.-]+" #define CF_IPRANGE "[a-zA-Z0-9_$(){}.:-]+" #define CF_FNCALLRANGE "[a-zA-Z0-9_(){}.$@]+" #define CF_NAKEDLRANGE "@[(][a-zA-Z0-9_$(){}\\[\\].:]+[)]" #define CF_ANYSTRING ".*" #define CF_KEYSTRING "^(SHA|MD5)=[0123456789abcdef]*$" #ifndef __MINGW32__ # define CF_ABSPATHRANGE "\"?(/.*)" #else // can start with e.g. c:\... or "c:\... | unix (for Cygwin-style paths) # define CF_ABSPATHRANGE "\"?(([a-zA-Z]:\\\\.*)|(/.*))" #endif /* Any non-empty string can be an absolute path under Unix */ #define CF_PATHRANGE ".+" // Put this here now for caching efficiency #define SOFTWARE_PACKAGES_CACHE "software_packages.csv" #define SOFTWARE_PATCHES_CACHE "software_patches_avail.csv" #define PACKAGES_CONTEXT "cf_pack_context" #define PACKAGES_CONTEXT_ANYVER "cf_pack_context_anyver" /*************************************************************************/ typedef struct EvalContext_ EvalContext; typedef enum { RVAL_TYPE_SCALAR = 's', RVAL_TYPE_LIST = 'l', RVAL_TYPE_FNCALL = 'f', RVAL_TYPE_CONTAINER = 'c', RVAL_TYPE_NOPROMISEE = 'X' // TODO: must be another hack } RvalType; typedef struct { void *item; RvalType type; } Rval; typedef struct Rlist_ Rlist; typedef struct ConstraintSyntax_ ConstraintSyntax; typedef struct BodySyntax_ BodySyntax; /* * Promise types or bodies may optionally provide parse-tree check function, called after * parsing to do a preliminary syntax/semantic checking of unexpanded promises. * * This check function should populate #errors sequence with errors it finds and * return false in case it has found at least one error. * * If the check function has not found any errors, it should return true. */ typedef bool (*PromiseCheckFn)(const Promise *pp, Seq *errors); typedef bool (*BodyCheckFn)(const Body *body, Seq *errors); typedef enum { SYNTAX_STATUS_NORMAL, SYNTAX_STATUS_DEPRECATED, SYNTAX_STATUS_REMOVED, SYNTAX_STATUS_CUSTOM } SyntaxStatus; typedef enum { FNCALL_CATEGORY_SYSTEM, FNCALL_CATEGORY_FILES, FNCALL_CATEGORY_IO, FNCALL_CATEGORY_COMM, FNCALL_CATEGORY_DATA, FNCALL_CATEGORY_UTILS, FNCALL_CATEGORY_INTERNAL } FnCallCategory; struct ConstraintSyntax_ { const char *lval; const DataType dtype; union { const char *validation_string; const BodySyntax *body_type_syntax; } range; const char *description; SyntaxStatus status; }; struct BodySyntax_ { const char *body_type; const ConstraintSyntax *constraints; BodyCheckFn check_body; SyntaxStatus status; }; typedef struct { const char *bundle_type; const char *promise_type; const ConstraintSyntax *constraints; const PromiseCheckFn check_promise; SyntaxStatus status; } PromiseTypeSyntax; /*************************************************************************/ typedef struct Constraint_ Constraint; typedef enum { INTERVAL_HOURLY, INTERVAL_DAILY, INTERVAL_NONE } Interval; typedef enum { FILE_COMPARATOR_ATIME, FILE_COMPARATOR_MTIME, FILE_COMPARATOR_CTIME, FILE_COMPARATOR_CHECKSUM, FILE_COMPARATOR_HASH, FILE_COMPARATOR_BINARY, FILE_COMPARATOR_EXISTS, FILE_COMPARATOR_NONE } FileComparator; typedef enum { FILE_LINK_TYPE_SYMLINK, FILE_LINK_TYPE_HARDLINK, FILE_LINK_TYPE_RELATIVE, FILE_LINK_TYPE_ABSOLUTE, FILE_LINK_TYPE_NONE } FileLinkType; enum cfopaction { cfa_fix, cfa_warn, }; typedef enum { BACKUP_OPTION_BACKUP, BACKUP_OPTION_NO_BACKUP, BACKUP_OPTION_TIMESTAMP, BACKUP_OPTION_ROTATE, BACKUP_OPTION_REPOSITORY_STORE /* for internal use only */ } BackupOption; enum cfnofile { cfa_force, cfa_delete, cfa_skip }; enum cflinkchildren { cfa_override, cfa_onlynonexisting }; typedef enum { FILE_CHANGE_REPORT_NONE, FILE_CHANGE_REPORT_CONTENT_CHANGE, FILE_CHANGE_REPORT_STATS_CHANGE, FILE_CHANGE_REPORT_ALL } FileChangeReport; typedef enum { PACKAGE_ACTION_ADD, PACKAGE_ACTION_DELETE, PACKAGE_ACTION_REINSTALL, PACKAGE_ACTION_UPDATE, PACKAGE_ACTION_ADDUPDATE, PACKAGE_ACTION_PATCH, PACKAGE_ACTION_VERIFY, PACKAGE_ACTION_NONE } PackageAction; typedef enum { NEW_PACKAGE_ACTION_ABSENT, NEW_PACKAGE_ACTION_PRESENT, NEW_PACKAGE_ACTION_NONE } NewPackageAction; typedef enum { PACKAGE_VERSION_COMPARATOR_EQ, PACKAGE_VERSION_COMPARATOR_NEQ, PACKAGE_VERSION_COMPARATOR_GT, PACKAGE_VERSION_COMPARATOR_LT, PACKAGE_VERSION_COMPARATOR_GE, PACKAGE_VERSION_COMPARATOR_LE, PACKAGE_VERSION_COMPARATOR_NONE } PackageVersionComparator; typedef enum { PACKAGE_ACTION_POLICY_INDIVIDUAL, PACKAGE_ACTION_POLICY_BULK, PACKAGE_ACTION_POLICY_NONE } PackageActionPolicy; typedef enum { PROMISE_STATE_REPAIRED = 'r', PROMISE_STATE_NOTKEPT = 'n', PROMISE_STATE_KEPT = 'c', PROMISE_STATE_ANY = 'x' } PromiseState; /************************************************************************************/ typedef enum { LAST_SEEN_DIRECTION_INCOMING = '-', LAST_SEEN_DIRECTION_OUTGOING = '+' } LastSeenDirection; /************************************************************************************/ typedef enum { ACL_METHOD_APPEND, ACL_METHOD_OVERWRITE, ACL_METHOD_NONE } AclMethod; typedef enum { ACL_TYPE_GENERIC, ACL_TYPE_POSIX, ACL_TYPE_NTFS_, ACL_TYPE_NONE } AclType; typedef enum { ACL_DEFAULT_NO_CHANGE, ACL_DEFAULT_SPECIFY, ACL_DEFAULT_ACCESS, ACL_DEFAULT_CLEAR, ACL_DEFAULT_NONE } AclDefault; typedef enum { ACL_INHERIT_FALSE, ACL_INHERIT_TRUE, ACL_INHERIT_NOCHANGE } AclInherit; typedef struct { AclMethod acl_method; AclType acl_type; AclDefault acl_default; Rlist *acl_entries; Rlist *acl_default_entries; /* Only used on Windows */ AclInherit acl_inherit; } Acl; typedef enum { INHERIT_ACCESS_ONLY, INHERIT_DEFAULT_ONLY, INHERIT_ACCESS_AND_DEFAULT } inherit_t; typedef enum { INSERT_MATCH_TYPE_IGNORE_LEADING, INSERT_MATCH_TYPE_IGNORE_TRAILING, INSERT_MATCH_TYPE_IGNORE_EMBEDDED, INSERT_MATCH_TYPE_EXACT } InsertMatchType; /*************************************************************************/ /* Runtime constraint structures */ /*************************************************************************/ #define OVECCOUNT 30 /*******************************************************************/ typedef struct { char *last; char *lock; bool is_dummy; } CfLock; /*************************************************************************/ typedef struct { char *host; char *source; char *mounton; char *options; int unmount; } Mount; /*************************************************************************/ typedef struct { int travlinks; int rmdeadlinks; int depth; int xdev; int include_basedir; Rlist *include_dirs; Rlist *exclude_dirs; } DirectoryRecursion; /*************************************************************************/ typedef struct { enum cfopaction action; int ifelapsed; int expireafter; int background; char *log_string; char *log_kept; char *log_repaired; char *log_failed; int log_priority; char *measure_id; int audit; LogLevel report_level; LogLevel log_level; } TransactionContext; /*************************************************************************/ typedef enum { CONTEXT_SCOPE_NAMESPACE, CONTEXT_SCOPE_BUNDLE, CONTEXT_SCOPE_NONE } ContextScope; typedef struct { ContextScope scope; Rlist *change; Rlist *failure; Rlist *denied; Rlist *timeout; Rlist *kept; int persist; PersistentClassPolicy timer; Rlist *del_change; Rlist *del_kept; Rlist *del_notkept; Rlist *retcode_kept; Rlist *retcode_repaired; Rlist *retcode_failed; } DefineClasses; /*************************************************************************/ /* SQL Database connectors */ /*************************************************************************/ typedef enum { DATABASE_TYPE_MYSQL, DATABASE_TYPE_POSTGRES, DATABASE_TYPE_NONE } DatabaseType; /*************************************************************************/ /* Package promises */ /*************************************************************************/ typedef struct PackageItem_ PackageItem; typedef struct PackageManager_ PackageManager; struct PackageManager_ { char *manager; PackageAction action; PackageActionPolicy policy; PackageItem *pack_list; PackageItem *patch_list; PackageItem *patch_avail; PackageManager *next; }; /*************************************************************************/ struct PackageItem_ { char *name; char *version; char *arch; Promise *pp; PackageItem *next; }; typedef struct { unsigned int expires; PersistentClassPolicy policy; char tags[]; // variable length, must be zero terminated } PersistentClassInfo; /*************************************************************************/ typedef struct { mode_t plus; mode_t minus; UidList *owners; GidList *groups; char *findertype; u_long plus_flags; /* for *BSD chflags */ u_long minus_flags; /* for *BSD chflags */ int rxdirs; } FilePerms; /*************************************************************************/ typedef struct { Rlist *name; Rlist *path; Rlist *perms; Rlist *bsdflags; Rlist *owners; Rlist *groups; long max_size; long min_size; time_t max_ctime; time_t min_ctime; time_t max_mtime; time_t min_mtime; time_t max_atime; time_t min_atime; char *exec_regex; char *exec_program; Rlist *filetypes; Rlist *issymlinkto; char *result; } FileSelect; /*************************************************************************/ typedef struct { enum { TIDY_LINK_DELETE, TIDY_LINK_KEEP } dirlinks; int rmdirs; } FileDelete; /*************************************************************************/ typedef struct { char *newname; char *disable_suffix; int disable; int rotate; mode_t plus; mode_t minus; } FileRename; /*************************************************************************/ typedef struct { HashMethod hash; FileChangeReport report_changes; int report_diffs; int update; } FileChange; /*************************************************************************/ typedef struct { char *source; FileLinkType link_type; Rlist *copy_patterns; enum cfnofile when_no_file; enum cflinkchildren when_linking_children; int link_children; } FileLink; /*************************************************************************/ typedef enum { SHELL_TYPE_NONE, SHELL_TYPE_USE, SHELL_TYPE_POWERSHELL } ShellType; typedef struct { ShellType shelltype; mode_t umask; uid_t owner; gid_t group; char *chdir; char *chroot; int preview; bool nooutput; int timeout; } ExecContain; /*************************************************************************/ typedef struct { long min_range; long max_range; Rlist *in_range_define; Rlist *out_of_range_define; } ProcessCount; /*************************************************************************/ typedef struct { Rlist *owner; long min_pid; long max_pid; long min_ppid; long max_ppid; long min_pgid; long max_pgid; long min_rsize; long max_rsize; long min_vsize; long max_vsize; time_t min_ttime; time_t max_ttime; time_t min_stime; time_t max_stime; long min_pri; long max_pri; long min_thread; long max_thread; char *status; char *command; char *tty; char *process_result; } ProcessSelect; #define PROCESS_SELECT_INIT { \ .owner = NULL, \ .min_pid = CF_NOINT, \ .max_pid = CF_NOINT, \ .min_ppid = CF_NOINT, \ .max_ppid = CF_NOINT, \ .min_pgid = CF_NOINT, \ .max_pgid = CF_NOINT, \ .min_rsize = CF_NOINT, \ .max_rsize = CF_NOINT, \ .min_vsize = CF_NOINT, \ .max_vsize = CF_NOINT, \ .min_ttime = CF_NOINT, \ .max_ttime = CF_NOINT, \ .min_stime = CF_NOINT, \ .max_stime = CF_NOINT, \ .min_pri = CF_NOINT, \ .max_pri = CF_NOINT, \ .min_thread = CF_NOINT, \ .max_thread = CF_NOINT, \ .status = NULL, \ .command = NULL, \ .tty = NULL, \ .process_result = NULL, \ } /*************************************************************************/ typedef struct { Constraint *expression; ContextScope scope; int nconstraints; int persistent; } ContextConstraint; /*************************************************************************/ typedef struct { BackupOption backup; int empty_before_use; int maxfilesize; int joinlines; int rotate; int inherit; } EditDefaults; /*************************************************************************/ typedef struct { Rlist *startwith_from_list; Rlist *not_startwith_from_list; Rlist *match_from_list; Rlist *not_match_from_list; Rlist *contains_from_list; Rlist *not_contains_from_list; } LineSelect; typedef struct { char *build_xpath; char *select_xpath; char *attribute_value; int havebuildxpath; int haveselectxpath; int haveattributevalue; } EditXml; typedef struct { char *line_matching; EditOrder before_after; char *first_last; } EditLocation; typedef struct { char *select_start; char *select_end; int include_start; int include_end; bool select_end_match_eof; } EditRegion; typedef struct { char *column_separator; int select_column; char value_separator; char *column_value; char *column_operation; int extend_columns; int blanks_ok; } EditColumn; typedef struct { char *replace_value; char *occurrences; } EditReplace; /*************************************************************************/ typedef struct { char *mount_type; char *mount_source; char *mount_server; Rlist *mount_options; int editfstab; int unmount; } StorageMount; typedef struct { int check_foreign; long freespace; int sensible_size; int sensible_count; int scan_arrivals; } StorageVolume; /*************************************************************************/ typedef struct { int haveprintfile; int havelastseen; int lastseen; char *result; double intermittency; char *friend_pattern; char *filename; char *to_file; int numlines; Rlist *showstate; } Report; /*************************************************************************/ typedef struct { PackageAction package_policy; char *package_version; Rlist *package_architectures; PackageVersionComparator package_select; PackageActionPolicy package_changes; Rlist *package_file_repositories; char *package_default_arch_command; char *package_list_command; char *package_list_version_regex; char *package_list_name_regex; char *package_list_arch_regex; char *package_patch_list_command; char *package_patch_version_regex; char *package_patch_name_regex; char *package_patch_arch_regex; char *package_patch_installed_regex; char *package_list_update_command; int package_list_update_ifelapsed; char *package_version_regex; char *package_name_regex; char *package_arch_regex; char *package_installed_regex; char *package_add_command; char *package_delete_command; char *package_update_command; char *package_patch_command; char *package_verify_command; char *package_noverify_regex; char *package_name_convention; char *package_delete_convention; bool package_commands_useshell; char *package_multiline_start; char *package_version_less_command; char *package_version_equal_command; int package_noverify_returncode; bool has_package_method; bool is_empty; } Packages; /*************************************************************************/ typedef struct { char *name; int updates_ifelapsed; int installed_ifelapsed; Rlist *options; char *interpreter; char *module_path; } PackageModuleBody; typedef struct { Rlist *control_package_inventory; /* list of all inventory used package managers * names taken from common control */ char *control_package_module; /* policy default package manager name */ Seq *package_modules_bodies; /* list of all discovered in policy PackageManagerBody * bodies taken from common control */ } PackagePromiseContext; typedef struct { NewPackageAction package_policy; PackageModuleBody *module_body; Rlist *package_inventory; char *package_version; char *package_architecture; Rlist *package_options; bool is_empty; } NewPackages; /*************************************************************************/ typedef enum { MEASURE_POLICY_AVERAGE, MEASURE_POLICY_SUM, MEASURE_POLICY_FIRST, MEASURE_POLICY_LAST, MEASURE_POLICY_NONE } MeasurePolicy; typedef struct { char *stream_type; DataType data_type; MeasurePolicy policy; char *history_type; char *select_line_matching; int select_line_number; char *extraction_regex; char *units; int growing; } Measurement; typedef struct { char *db_server_owner; char *db_server_password; char *db_server_host; char *db_connect_db; DatabaseType db_server_type; char *server; char *type; char *operation; Rlist *columns; Rlist *rows; Rlist *exclude; } Database; /*************************************************************************/ typedef enum { USER_STATE_PRESENT, USER_STATE_ABSENT, USER_STATE_LOCKED, USER_STATE_NONE } UserState; typedef enum { PASSWORD_FORMAT_PLAINTEXT, PASSWORD_FORMAT_HASH, PASSWORD_FORMAT_NONE } PasswordFormat; typedef struct { UserState policy; char *uid; PasswordFormat password_format; char *password; char *description; char *group_primary; Rlist *groups_secondary; bool groups_secondary_given; char *home_dir; char *shell; } User; /*************************************************************************/ typedef struct { Rlist *service_depend; char *service_type; char *service_args; char *service_policy; char *service_autostart_policy; char *service_depend_chain; } Services; /*************************************************************************/ typedef enum { ENVIRONMENT_STATE_CREATE, ENVIRONMENT_STATE_DELETE, ENVIRONMENT_STATE_RUNNING, ENVIRONMENT_STATE_SUSPENDED, ENVIRONMENT_STATE_DOWN, ENVIRONMENT_STATE_NONE } EnvironmentState; typedef struct { int cpus; int memory; int disk; char *baseline; char *spec; Rlist *addresses; char *name; char *host; char *type; EnvironmentState state; } Environments; /* This is huge, but the simplification of logic is huge too so we leave it to the compiler to optimize */ #include typedef struct { const char *source; const char *port; /* port or service name */ char *destination; FileComparator compare; FileLinkType link_type; Rlist *servers; Rlist *link_instead; Rlist *copy_links; BackupOption backup; int stealth; int preserve; int collapse; /* collapse_destination_dir */ int check_root; int type_check; int force_update; int force_ipv4; size_t min_size; /* Safety margin not search criterion */ size_t max_size; int trustkey; int encrypt; int verify; int purge; short timeout; ProtocolVersion protocol_version; bool missing_ok; } FileCopy; typedef struct { FileSelect select; FilePerms perms; FileCopy copy; FileDelete delete; char *content; FileRename rename; FileChange change; FileLink link; EditDefaults edits; Packages packages; NewPackages new_packages; ContextConstraint context; Measurement measure; Acl acl; Database database; Services service; User users; Environments env; char *transformer; char *pathtype; char *file_type; char *repository; char *edit_template; char *edit_template_string; char *template_method; JsonElement *template_data; int touch; int create; int move_obstructions; int inherit; DirectoryRecursion recursion; TransactionContext transaction; DefineClasses classes; ExecContain contain; char *args; Rlist *arglist; int module; bool inform; Rlist *signals; char *process_stop; char *restart_class; ProcessCount process_count; ProcessSelect process_select; Report report; StorageMount mount; StorageVolume volume; int havedepthsearch; int haveselect; int haverename; int havedelete; int haveperms; int havechange; int havecopy; int havelink; int haveeditline; int haveeditxml; int haveedit; int havecontain; int haveclasses; int havetrans; int haveprocess_count; int havemount; int havevolume; int havebundle; int havepackages; /* editline */ EditRegion region; EditLocation location; EditColumn column; EditReplace replace; EditXml xml; int haveregion; int havelocation; int havecolumn; int havereplace; int haveinsertselect; int havedeleteselect; LineSelect line_select; char *sourcetype; int expandvars; int not_matching; Rlist *insert_match; } Attributes; #define ZeroAttributes {\ .select = {0},\ .perms = {0},\ .copy = {0},\ .delete = {0},\ .content = NULL,\ .rename = {0},\ .change = {0},\ .link = {0},\ .edits = {0},\ .packages = {0},\ .new_packages = {0},\ .context = {0},\ .measure = {0},\ .acl = {0},\ .database = {0},\ .service = {0},\ .users = {0},\ .env = {0},\ .transformer = NULL,\ .pathtype = NULL,\ .file_type = NULL,\ .repository = NULL,\ .edit_template = NULL,\ .edit_template_string = NULL,\ .template_method = NULL,\ .template_data = NULL,\ .touch = 0,\ .create = 0,\ .move_obstructions = 0,\ .inherit = 0,\ .recursion = { 0 },\ .transaction = { 0 },\ .classes = { 0 },\ .contain = { 0 },\ .args = NULL,\ .arglist = NULL,\ .module = 0,\ .inform = false,\ .signals = NULL,\ .process_stop = NULL,\ .restart_class = NULL,\ .process_count = { 0 },\ .process_select = { 0 },\ .report = { 0 },\ .mount = { 0 },\ .volume = { 0 },\ .havedepthsearch = 0,\ .haveselect = 0,\ .haverename = 0,\ .havedelete = 0,\ .haveperms = 0,\ .havechange = 0,\ .havecopy = 0,\ .havelink = 0,\ .haveeditline = 0,\ .haveeditxml = 0,\ .haveedit = 0,\ .havecontain = 0,\ .haveclasses = 0,\ .havetrans = 0,\ .haveprocess_count = 0,\ .havemount = 0,\ .havevolume = 0,\ .havebundle = 0,\ .havepackages = 0,\ .region = { 0 },\ .location = { 0 },\ .column = { 0 },\ .replace = { 0 },\ .xml = { 0 },\ .haveregion = 0,\ .havelocation = 0,\ .havecolumn = 0,\ .havereplace = 0,\ .haveinsertselect = 0,\ .havedeleteselect = 0,\ .line_select = { 0 },\ .sourcetype = NULL,\ .expandvars = 0,\ .not_matching = 0,\ .insert_match = NULL\ } /*************************************************************************/ /* common macros */ /*************************************************************************/ #include #include #include #include #include #include extern const ConstraintSyntax CF_COMMON_BODIES[]; extern const ConstraintSyntax CF_VARBODY[]; extern const PromiseTypeSyntax *const CF_ALL_PROMISE_TYPES[]; extern const ConstraintSyntax CFG_CONTROLBODY[]; extern const BodySyntax CONTROL_BODIES[]; extern const ConstraintSyntax CFH_CONTROLBODY[]; extern const PromiseTypeSyntax CF_COMMON_PROMISE_TYPES[]; extern const ConstraintSyntax CF_CLASSBODY[]; extern const ConstraintSyntax CFA_CONTROLBODY[]; extern const ConstraintSyntax CFEX_CONTROLBODY[]; typedef struct ServerConnectionState_ ServerConnectionState; #endif cfengine-3.24.2/libpromises/bootstrap.inc0000644000000000000000000007065115010704322020421 0ustar00rootroot00000000000000 "#\n" "# Copyright 2021 Northern.tech AS\n" "#\n" "# This file is part of CFEngine 3 - written and maintained by Northern.tech AS.\n" "#\n" "# This program is free software; you can redistribute it and/or modify it\n" "# under the terms of the GNU General Public License as published by the\n" "# Free Software Foundation; version 3.\n" "#\n" "# This program is distributed in the hope that it will be useful,\n" "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "# GNU General Public License for more details.\n" "#\n" "# You should have received a copy of the GNU General Public License\n" "# along with this program; if not, write to the Free Software\n" "# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n" "#\n" "# To the extent this program is licensed as part of the Enterprise\n" "# versions of CFEngine, the applicable Commercial Open Source License\n" "# (COSL) may apply to this file if you as a licensee so wish it. See\n" "# included file COSL.txt.\n" "\n" "########## CFEngine Bootstrap / Failsafe Policy ##############################\n" "# This file (failsafe.cf) is re-generated inside \"inputs\" directory every time\n" "# you bootstrap. This means that custom changes will be overwritten.\n" "#\n" "# The role of this standalone policy file is to fetch the main promises from\n" "# the policy hub for the first time when bootstrapping, and to recover the\n" "# system by fetching policies in case the standard agent run fails.\n" "##############################################################################\n" "\n" "body agent control\n" "{\n" " # Bootstrapping can't continue without keys\n" " abortclasses => { \"no_ppkeys_ABORT_kept\" };\n" " # Make sure that running failsafe many times in a row does not\n" " # change functionality\n" " ifelapsed => \"0\";\n" "}\n" "\n" "################################################################################\n" "\n" "bundle agent main\n" "{\n" " meta:\n" "\n" " \"description\"\n" " string => \"Perform bootstrap or failsafe recovery operations.\";\n" "\n" " vars:\n" " # In order to preserve the log level used during bootstrap we build the\n" " # string to set log level on any direct sub-agent calls based on classes\n" " # that are defined when the options are set.\n" "\n" " # --log-level, -g value - Specify how detailed logs should be.\n" " # Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'\n" "\n" " \"log_level\"\n" " string => ifelse(\"debug_mode\", \"--log-level=debug\",\n" " \"verbose_mode\", \"--log-level=verbose\",\n" " \"info_mode\", \"--log-level=info\",\n" " # CFE-4121 - Not yet implemented\n" " # \"notice_mode\", \"--log-level=notice\",\n" " # \"warning_mode\", \"--log-level=warning\",\n" " # \"error_mode\", \"--log-level=error\",\n" " \"\");\n" "\n" " methods:\n" "\n" " \"Check Keys\"\n" " usebundle => failsafe_cfe_internal_checkkeys,\n" " comment => \"Without a valid keypair we aren't going to be able\n" " to establish trust\";\n" "\n" " \"Fetch Inputs\"\n" " usebundle => failsafe_cfe_internal_update,\n" " comment => \"We need to fetch policy from upstream if we are\n" " bootstrapping or if we are performing failsafe\n" " recovery.\";\n" "\n" " \"Actuate Update Policy\"\n" " usebundle => failsafe_cfe_internal_call_update,\n" " comment => \"In order to speed up convergence and reporting we\n" " trigger the update policy right after initial\n" " bootstrap. This allows the first scheduled run to\n" " happen with the most up to date and complete\n" " information.\";\n" "\n" " \"Trigger Policy\"\n" " usebundle => failsafe_cfe_internal_trigger_policy,\n" " comment => \"In order to speed up convergence and reporting we\n" " trigger the whole policy right after initial\n" " bootstrap. This allows the first report to provide\n" " more complete data.\";\n" "\n" " \"Report\"\n" " usebundle => failsafe_cfe_internal_report,\n" " comment => \"It's important to let the user know what happened\n" " as the result of the bootstrap or failsafe\n" " operation.\";\n" "}\n" "\n" "bundle agent failsafe_cfe_internal_checkkeys\n" "{\n" " classes:\n" " \"have_ppkeys\"\n" " expression => fileexists(\"$(sys.workdir)/ppkeys/localhost.pub\"),\n" " handle => \"failsafe_cfe_internal_bootstrap_checkkeys_classes_have_ppkeys\";\n" "\n" " reports:\n" " !have_ppkeys::\n" " \"No public/private key pair is loaded, please create one by running \\\"cf-key\\\"\"\n" " classes => failsafe_results(\"namespace\", \"no_ppkeys_ABORT\");\n" "}\n" "\n" "################################################################################\n" "\n" "bundle agent failsafe_cfe_internal_update\n" "{\n" " vars:\n" "\n" " # A policy server cannot use the shortcut feature to resolve\n" " # masterfiles since cf-serverd is potentially not yet up and\n" " # running.\n" "\n" " # The unqualified path is used for non policy servers so that\n" " # the policy server can use a shortcut to decide on behalf of\n" " # the client which policy to serve by default. This is useful\n" " # when running binaires from mixed sources (for example CFEngine\n" " # produced binaries vs packages from the debian repository).\n" "\n" " \"masterfiles_dir_remote\"\n" " string => ifelse( \"policy_server\", $(sys.masterdir),\n" " \"masterfiles\" );\n" "\n" " files:\n" "\n" " \"$(sys.inputdir)\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_shortcut\",\n" " copy_from => failsafe_scp(\"$(masterfiles_dir_remote)\"),\n" " depth_search => failsafe_u_infinite_client_policy,\n" " file_select => failsafe_exclude_vcs_files,\n" " classes => failsafe_results(\"namespace\", \"inputdir_update\");\n" "\n" " !policy_server::\n" "\n" " \"$(sys.workdir)/modules\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_modules_shortcut\",\n" " copy_from => failsafe_scp(\"modules\"),\n" " depth_search => failsafe_recurse(\"inf\"),\n" " file_select => failsafe_exclude_vcs_files,\n" " classes => failsafe_results(\"namespace\", \"modulesdir_update\");\n" "\n" " !windows.inputdir_update_error::\n" "\n" " # When running on a *nix platform with homogeneous packages\n" " # $(sys.masterdir) is a good guess. This is never the case for\n" " # windows, and might be a poor guess if mixing packages from\n" " # different sources (for example debian repositories and\n" " # CFEngine produced packages).\n" " \"$(sys.inputdir)\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_not_windows\",\n" " copy_from => failsafe_scp(\"$(sys.masterdir)\"),\n" " depth_search => failsafe_recurse(\"inf\"),\n" " file_select => failsafe_exclude_vcs_files,\n" " classes => failsafe_results(\"namespace\", \"inputdir_update\"),\n" " comment => \"If we failed to fetch policy we try again using\n" " the legacy default in case we are fetching policy\n" " from a hub that is not serving mastefiles via a\n" " shortcut.\";\n" "\n" " windows.inputdir_update_error::\n" "\n" " # Note: Windows can't use $(sys.masterdir) because no one runs a\n" " # hub on windows and the copy_from needs the remote path.\n" " \"$(sys.inputdir)\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_windows\",\n" " copy_from => failsafe_scp(\"/var/cfengine/masterfiles\"),\n" " depth_search => failsafe_recurse(\"inf\"),\n" " file_select => failsafe_exclude_vcs_files,\n" " classes => failsafe_results(\"namespace\", \"inputdir_update\"),\n" " comment => \"If we failed to fetch policy we try again using\n" " the legacy default in case we are fetching policy\n" " from a hub that is not serving mastefiles via a\n" " shortcut.\";\n" "\n" " windows::\n" "\n" " # TODO: Remove the use of bin-twin ref: Redmine #7364\n" " \"$(sys.workdir)\\\\bin-twin\\\\.\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_files_sys_workdir_bin_twin_windows\",\n" " copy_from => failsafe_cp(\"$(sys.workdir)\\\\bin\\\\.\"),\n" " depth_search => failsafe_recurse(\"1\"),\n" " file_select => failsafe_exclude_vcs_files,\n" " comment => \"Make sure we maintain a clone of the binaries and\n" " libraries for updating\";\n" "\n" "\n" " processes:\n" "\n" " # TODO: Decide if this class guard is appropriate. Should we\n" " # guard checking of cf-execd process running to when inputs are\n" " # repaired\n" " !windows.inputdir_update_repaired::\n" "\n" " # We need to know when cf-execd is not running so that we can\n" " # start it when necessary. Windows and systemd hosts uses the service\n" " # manager instead of keying on individual processes.\n" "\n" " \"cf-execd\" restart_class => \"cf_execd_not_running\",\n" " handle => \"failsafe_cfe_internal_bootstrap_update_processes_start_cf_execd\";\n" "\n" " any::\n" "\n" " # We need to know if cf-serverd isn't running so that we can\n" " # start it when necessary.\n" "\n" " \"cf-serverd\" restart_class => \"cf_serverd_not_running\",\n" " handle => \"failsafe_cfe_internal_bootstrap_update_processes_start_cf_serverd\";\n" "\n" " commands:\n" "\n" " cf_execd_not_running.!(windows|systemd|bootstrap_skip_services)::\n" "\n" " # Windows and systemd do not launch cf-execd directly and are\n" " # handeled separately.\n" "\n" " \"$(sys.cf_execd)\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_commands_check_sys_cf_execd_start\",\n" " classes => failsafe_results(\"namespace\", \"cf_execd_running\");\n" "\n" " cf_serverd_not_running.!(windows|systemd|bootstrap_skip_services)::\n" "\n" " # cf-serverd is not launched directly on Windows and systemd and is\n" " # handled separately.\n" "\n" " \"$(sys.cf_serverd)\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_commands_check_sys_cf_serverd_start\",\n" " action => failsafe_ifwin_bg,\n" " classes => failsafe_results(\"namespace\", \"cf_serverd_running\"),\n" " comment => \"cf-serverd is needed on policy hubs or remote\n" " clients will not be able to get policy. Clients do\n" " not have a strong dependency on cf-serverd and if\n" " the component is necessay it is expected to be\n" " started by a separate policy.\";\n" "\n" " cf_execd_not_running.systemd.!bootstrap_skip_services::\n" "\n" " # We explicitly use \"restart\", because it is possible that cf-serverd\n" " # is running, even if cf-execd isn't, for example. Here we want to be\n" " # sure we relaunch everything.\n" "\n" " \"/bin/systemctl restart cfengine3\" -> { \"CFE-1459\" }\n" " handle => \"failsafe_cfe_internal_bootstrap_update_commands_systemd_cfe_start\",\n" " contain => bootstrap_command_silent,\n" " classes => failsafe_results(\"namespace\", \"systemctl_restart_cfengine3\");\n" "\n" " services:\n" "\n" " # TODO: Is this restriction to only promise the service running\n" " # when inputs are repaired appropriate? Perhaps it should always\n" " # be checked.\n" " windows.inputdir_update_repaired.!bootstrap_skip_services::\n" "\n" " \"CfengineNovaExec\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_services_windows_executor\",\n" " service_policy => \"start\",\n" " service_method => failsafe_bootstart,\n" " classes => failsafe_results(\"namespace\", \"cf_execd_running\");\n" "}\n" "\n" "################################################################################\n" "\n" "bundle agent failsafe_cfe_internal_report\n" "{\n" " meta:\n" "\n" " \"description\"\n" " string => \"Report the outcome of the embedded\n" " bootstrap/failsafe operation.\";\n" "\n" " classes:\n" "\n" " # TODO: Determine if this is necessary and/or useful. Pre-eval\n" " # might resolve this before policy update occurs, and this is\n" " # probably most useful after policy update has been attempted.\n" "\n" " \"have_promises_cf\"\n" " scope => \"bundle\",\n" " expression => fileexists(\"$(sys.inputdir)/promises.cf\"),\n" " handle => \"failsafe_cfe_internal_bootstrap_update_classes_have_promises_cf\",\n" " comment => \"We expect to find promises.cf after policy has\n" " been successfully copied from the policy\n" " server. If promises.cf is missing, then the\n" " bootstrap or failsafe recovery has likely\n" " failed.\";\n" "\n" " reports:\n" "\n" " !bootstrap_mode::\n" "\n" " \"Built-in failsafe policy triggered\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_failsafe_notification\",\n" " comment => \"Be sure to inform the user that the failsafe policy has\n" " been triggered. This typically indicates that the agent has\n" " received broken policy. It may also indicate legacy\n" " configuration in body executor control.\";\n" "\n" " bootstrap_mode::\n" "\n" " \"Bootstrapping from host '$(sys.policy_hub)' via built-in policy '$(this.promise_filename)'\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_bootstrap_notification\",\n" " comment => \"Be sure to inform the user that they have triggerd a bootstrap.\";\n" "\n" " bootstrap_mode.policy_server::\n" "\n" " \"This host assumes the role of policy server\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_assume_policy_hub\";\n" "\n" " bootstrap_mode.!policy_server::\n" "\n" " \"This autonomous node assumes the role of voluntary client\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_assume_voluntary_client\";\n" "\n" " inputdir_update_repaired::\n" "\n" " \"Updated local policy from policy server\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_inputdir_update_repaired\";\n" "\n" "\n" " inputdir_update_repaired.!have_promises_cf::\n" "\n" " # We used to display this report when we have fetched new\n" " # policy, but still can not find promises.cf in\n" " # sys.inputdir. However if the hub being bootstrapped to is down\n" " # we may never repair inputs and this may not be triggered\n" " #\n" " # TODO: Come up with better conditions. These seem weak.\n" " # - Potentially use returnszero() with cf-promises?\n" "\n" " \"Failed to copy policy from policy server at $(sys.policy_hub):$(sys.masterdir)\n" " Please check\n" " * cf-serverd is running on $(sys.policy_hub)\n" " * CFEngine version on the policy hub is 3.6.0 or latest - otherwise you need to tweak the protocol_version setting\n" " * network connectivity to $(sys.policy_hub) on port $(sys.policy_hub_port)\n" " * masterfiles 'body server control' - in particular allowconnects, trustkeysfrom and skipverify\n" " * masterfiles 'bundle server' -> access: -> masterfiles -> admit/deny\n" " It is often useful to restart cf-serverd in verbose mode (cf-serverd -v) on $(sys.policy_hub) to diagnose connection issues.\n" " When updating masterfiles, wait (usually 5 minutes) for files to propagate to inputs on $(sys.policy_hub) before retrying.\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_did_not_get_policy\";\n" "\n" " trigger_policy_repaired::\n" " \"Triggered an initial run of the policy\"\n" " handle => \"failsafe_cfe_internal_bootstrap_trigger_policy_passed\";\n" "\n" " trigger_policy_failed::\n" " \"Initial run of the policy failed\"\n" " handle => \"failsafe_cfe_internal_bootstrap_trigger_policy_failed\";\n" "\n" " systemctl_restart_cfengine3_repaired::\n" "\n" " \"Restarted systemd unit cfengine3\"\n" " handle => \"failsafe_cfe_intrnal_bootstrap_update_reports_systemd_unit_restarted\";\n" "\n" " systemctl_restart_cfengine3_error::\n" "\n" " \"Error restarting systemd unit cfengine3\"\n" " handle => \"failsafe_cfe_intrnal_bootstrap_update_reports_systemd_unit_restarted\";\n" "\n" " cf_serverd_running_repaired::\n" "\n" " \"Started the server\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_started_serverd\";\n" "\n" " cf_serverd_running_failed::\n" "\n" " \"Failed to start the server\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_failed_to_start_serverd\";\n" "\n" " cf_execd_running_repaired::\n" "\n" " \"Started the scheduler\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_started_execd\";\n" "\n" " cf_execd_running_failed::\n" "\n" " \"Failed to start the scheduler\"\n" " handle => \"failsafe_cfe_internal_bootstrap_update_reports_failed_to_start_execd\";\n" "}\n" "\n" "################################################################################\n" "\n" "bundle agent failsafe_cfe_internal_call_update\n" "{\n" " vars:\n" "\n" " \"mode\" string => ifelse(\"bootstrap_mode\", \"bootstrap_mode\", \"failsafe_mode\");\n" "\n" " commands:\n" "\n" " # On Windows we need cf-execd to call update.cf, otherwise the daemons will\n" " # not run under the SYSTEM account.\n" " !windows.!skip_policy_on_bootstrap::\n" " \"$(sys.cf_agent) -f $(sys.update_policy_path) --define $(mode) $(main.log_level)\"\n" " handle => \"failsafe_cfe_internal_call_update_commands_call_update_cf\",\n" " if => fileexists( $(sys.update_policy_path) ),\n" " comment => \"We run update.cf in order to prepare system information for\n" " collection into CFEngine Enterprise more quickly.\";\n" "}\n" "\n" "################################################################################\n" "\n" "bundle agent failsafe_cfe_internal_trigger_policy\n" "{\n" " commands:\n" "\n" " bootstrap_mode.!skip_policy_on_bootstrap::\n" " \"$(sys.cf_agent) --define bootstrap_mode $(main.log_level)\"\n" " handle => \"failsafe_cfe_internal_trigger_policy_commands_call_promises_cf\",\n" " if => fileexists( $(sys.default_policy_path) ),\n" " classes => failsafe_results(\"namespace\", \"trigger_policy\"),\n" " comment => \"We run promises.cf in order to prepare system information for\n" " collection into CFEngine Enterprise more quickly.\";\n" "}\n" "\n" "############################################\n" "body copy_from failsafe_scp(from)\n" "{\n" " source => \"$(from)\";\n" " compare => \"digest\";\n" " # This class is always set when bootstrapping. You can deactivate\n" " # this class with --trust-server=no when bootstrapping\n" " trust_server::\n" " trustkey => \"true\";\n" " !policy_server::\n" " servers => { \"$(sys.policy_hub)\" };\n" " portnumber => \"$(sys.policy_hub_port)\";\n" "}\n" "############################################\n" "body depth_search failsafe_u_infinite_client_policy\n" "# @brief Search recursively for files excluding vcs related files and .no-distrib directories\n" "# @param d Maximum depth to search recursively\n" "# Duplicated in update policy\n" "{\n" " depth => \"inf\";\n" " exclude_dirs => { \"\\.svn\", \"\\.git\", \"git-core\", \"\\.no-distrib\" };\n" "}\n" "############################################\n" "body depth_search failsafe_recurse(d)\n" "{\n" " depth => \"$(d)\";\n" " exclude_dirs => { \"\\.svn\", \"\\.git\" };\n" "}\n" "############################################\n" "body file_select failsafe_exclude_vcs_files\n" "{\n" " leaf_name => { \"\\.git.*\", \"\\.mailmap\" };\n" " file_result => \"!leaf_name\";\n" "}\n" "############################################\n" "body service_method failsafe_bootstart\n" "{\n" " service_autostart_policy => \"boot_time\";\n" "}\n" "############################################\n" "body action failsafe_ifwin_bg\n" "{\n" " windows::\n" " background => \"true\";\n" "}\n" "############################################\n" "body copy_from failsafe_cp(from)\n" "{\n" " source => \"$(from)\";\n" " compare => \"digest\";\n" " copy_backup => \"false\";\n" "}\n" "\n" "############################################\n" "body classes failsafe_results(scope, class_prefix)\n" "# @brief Define classes prefixed with `class_prefix` and suffixed with\n" "# appropriate outcomes: _kept, _repaired, _not_kept, _error, _failed,\n" "# _denied, _timeout, _reached\n" "#\n" "# @param scope The scope in which the class should be defined (`bundle` or `namespace`)\n" "# @param class_prefix The prefix for the classes defined\n" "{\n" " scope => \"$(scope)\";\n" "\n" " promise_kept => { \"$(class_prefix)_reached\",\n" " \"$(class_prefix)_kept\" };\n" "\n" " promise_repaired => { \"$(class_prefix)_reached\",\n" " \"$(class_prefix)_repaired\" };\n" "\n" " repair_failed => { \"$(class_prefix)_reached\",\n" " \"$(class_prefix)_error\",\n" " \"$(class_prefix)_not_kept\",\n" " \"$(class_prefix)_failed\" };\n" "\n" " repair_denied => { \"$(class_prefix)_reached\",\n" " \"$(class_prefix)_error\",\n" " \"$(class_prefix)_not_kept\",\n" " \"$(class_prefix)_denied\" };\n" "\n" " repair_timeout => { \"$(class_prefix)_reached\",\n" " \"$(class_prefix)_error\",\n" " \"$(class_prefix)_not_kept\",\n" " \"$(class_prefix)_timeout\" };\n" "}\n" "\n" "body contain bootstrap_command_silent\n" "# @brief Suppress command output\n" "{\n" " no_output => \"true\";\n" "}\n" cfengine-3.24.2/libpromises/acl_tools.h0000644000000000000000000000332415010704253020035 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ACL_TOOLS_H #define CFENGINE_ACL_TOOLS_H bool CopyACLs(const char *src, const char *dst, bool *change); /** * Allow access to the given file ONLY for the given users using ACLs. Existing * 'user:...' ACL entries are replaced by new entries allowing access for the * given users. * * @param path file to set the ACLs on * @param users users to allow access for * @param allow_writes whether to allow write access (read access is always allowed) * @param allow_execute whether to allow execute access (read access is always allowed) * @return Whether the change of ACLs was successful or not */ bool AllowAccessForUsers(const char *path, StringSet *users, bool allow_writes, bool allow_execute); #endif // CFENGINE_ACL_TOOLS_H cfengine-3.24.2/libpromises/instrumentation.h0000644000000000000000000000251315010704253021320 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_INSTRUMENTATION_H #define CFENGINE_INSTRUMENTATION_H #include #include #include struct timespec BeginMeasure(void); void EndMeasure(char *eventname, struct timespec start); int EndMeasureValueMs(struct timespec start); void EndMeasurePromise(struct timespec start, const Promise *pp); extern bool TIMING; #endif cfengine-3.24.2/libpromises/iteration.h0000644000000000000000000000302415010704253020051 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ITERATION_H #define CFENGINE_ITERATION_H #include typedef struct PromiseIterator_ PromiseIterator; PromiseIterator *PromiseIteratorNew(const Promise *pp); void PromiseIteratorDestroy(PromiseIterator *iterctx); void PromiseIteratorPrepare(PromiseIterator *iterctx, const EvalContext *evalctx, char *s); bool PromiseIteratorNext(PromiseIterator *iterctx, EvalContext *evalctx); size_t PromiseIteratorIndex(const PromiseIterator *iter_ctx); #endif cfengine-3.24.2/libpromises/math.pc0000644000000000000000000012206015010704253017161 0ustar00rootroot00000000000000/* A recursive-descent parser generated by peg 0.1.15 */ #include #include #include #define YYRULECOUNT 23 #ifndef YY_MALLOC #define YY_MALLOC(C, N) malloc(N) #endif #ifndef YY_REALLOC #define YY_REALLOC(C, P, N) realloc(P, N) #endif #ifndef YY_FREE #define YY_FREE(C, P) free(P) #endif #ifndef YY_LOCAL #define YY_LOCAL(T) static T #endif #ifndef YY_ACTION #define YY_ACTION(T) static T #endif #ifndef YY_RULE #define YY_RULE(T) static T #endif #ifndef YY_PARSE #define YY_PARSE(T) T #endif #ifndef YYPARSE #define YYPARSE yyparse #endif #ifndef YYPARSEFROM #define YYPARSEFROM yyparsefrom #endif #ifndef YYRELEASE #define YYRELEASE yyrelease #endif #ifndef YY_BEGIN #define YY_BEGIN ( yy->__begin= yy->__pos, 1) #endif #ifndef YY_END #define YY_END ( yy->__end= yy->__pos, 1) #endif #ifdef YY_DEBUG # define yyprintf(args) fprintf args #else # define yyprintf(args) #endif #ifndef YYSTYPE #define YYSTYPE int #endif #ifndef YY_STACK_SIZE #define YY_STACK_SIZE 128 #endif #ifndef YY_BUFFER_SIZE #define YY_BUFFER_SIZE 1024 #endif #ifndef YY_PART typedef struct _yycontext yycontext; typedef void (*yyaction)(yycontext *yy, char *yytext, int yyleng); typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk; struct _yycontext { char *__buf; int __buflen; int __pos; int __limit; char *__text; int __textlen; int __begin; int __end; int __textmax; yythunk *__thunks; int __thunkslen; int __thunkpos; YYSTYPE __; YYSTYPE *__val; YYSTYPE *__vals; int __valslen; #ifdef YY_CTX_MEMBERS YY_CTX_MEMBERS #endif }; #ifdef YY_CTX_LOCAL #define YY_CTX_PARAM_ yycontext *yyctx, #define YY_CTX_PARAM yycontext *yyctx #define YY_CTX_ARG_ yyctx, #define YY_CTX_ARG yyctx #ifndef YY_INPUT #define YY_INPUT(yy, buf, result, max_size) \ { \ int yyc= getchar(); \ result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ yyprintf((stderr, "<%c>", yyc)); \ } #endif #else #define YY_CTX_PARAM_ #define YY_CTX_PARAM #define YY_CTX_ARG_ #define YY_CTX_ARG yycontext _yyctx= { 0, 0 }; yycontext *yyctx= &_yyctx; #ifndef YY_INPUT #define YY_INPUT(buf, result, max_size) \ { \ int yyc= getchar(); \ result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ yyprintf((stderr, "<%c>", yyc)); \ } #endif #endif YY_LOCAL(int) yyrefill(yycontext *yy) { int yyn; while (yy->__buflen - yy->__pos < 512) { yy->__buflen *= 2; yy->__buf= (char *)YY_REALLOC(yy, yy->__buf, yy->__buflen); } #ifdef YY_CTX_LOCAL YY_INPUT(yy, (yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos)); #else YY_INPUT((yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos)); #endif if (!yyn) return 0; yy->__limit += yyn; return 1; } YY_LOCAL(int) yymatchDot(yycontext *yy) { if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; ++yy->__pos; return 1; } YY_LOCAL(int) yymatchChar(yycontext *yy, int c) { if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; if ((unsigned char)yy->__buf[yy->__pos] == c) { ++yy->__pos; yyprintf((stderr, " ok yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos)); return 1; } yyprintf((stderr, " fail yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos)); return 0; } YY_LOCAL(int) yymatchString(yycontext *yy, const char *s) { int yysav= yy->__pos; while (*s) { if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; if (yy->__buf[yy->__pos] != *s) { yy->__pos= yysav; return 0; } ++s; ++yy->__pos; } return 1; } YY_LOCAL(int) yymatchClass(yycontext *yy, unsigned char *bits) { int c; if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; c= (unsigned char)yy->__buf[yy->__pos]; if (bits[c >> 3] & (1 << (c & 7))) { ++yy->__pos; yyprintf((stderr, " ok yymatchClass @ %s\n", yy->__buf+yy->__pos)); return 1; } yyprintf((stderr, " fail yymatchClass @ %s\n", yy->__buf+yy->__pos)); return 0; } YY_LOCAL(void) yyDo(yycontext *yy, yyaction action, int begin, int end) { while (yy->__thunkpos >= yy->__thunkslen) { yy->__thunkslen *= 2; yy->__thunks= (yythunk *)YY_REALLOC(yy, yy->__thunks, sizeof(yythunk) * yy->__thunkslen); } yy->__thunks[yy->__thunkpos].begin= begin; yy->__thunks[yy->__thunkpos].end= end; yy->__thunks[yy->__thunkpos].action= action; ++yy->__thunkpos; } YY_LOCAL(int) yyText(yycontext *yy, int begin, int end) { int yyleng= end - begin; if (yyleng <= 0) yyleng= 0; else { while (yy->__textlen < (yyleng + 1)) { yy->__textlen *= 2; yy->__text= (char *)YY_REALLOC(yy, yy->__text, yy->__textlen); } memcpy(yy->__text, yy->__buf + begin, yyleng); } yy->__text[yyleng]= '\0'; return yyleng; } YY_LOCAL(void) yyDone(yycontext *yy) { int pos; for (pos= 0; pos < yy->__thunkpos; ++pos) { yythunk *thunk= &yy->__thunks[pos]; int yyleng= thunk->end ? yyText(yy, thunk->begin, thunk->end) : thunk->begin; yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, yy->__text)); thunk->action(yy, yy->__text, yyleng); } yy->__thunkpos= 0; } YY_LOCAL(void) yyCommit(yycontext *yy) { if ((yy->__limit -= yy->__pos)) { memmove(yy->__buf, yy->__buf + yy->__pos, yy->__limit); } yy->__begin -= yy->__pos; yy->__end -= yy->__pos; yy->__pos= yy->__thunkpos= 0; } YY_LOCAL(int) yyAccept(yycontext *yy, int tp0) { if (tp0) { fprintf(stderr, "accept denied at %d\n", tp0); return 0; } else { yyDone(yy); yyCommit(yy); } return 1; } YY_LOCAL(void) yyPush(yycontext *yy, char *text, int count) { yy->__val += count; while (yy->__valslen <= yy->__val - yy->__vals) { long offset= yy->__val - yy->__vals; yy->__valslen *= 2; yy->__vals= (YYSTYPE *)YY_REALLOC(yy, yy->__vals, sizeof(YYSTYPE) * yy->__valslen); yy->__val= yy->__vals + offset; } } YY_LOCAL(void) yyPop(yycontext *yy, char *text, int count) { yy->__val -= count; } YY_LOCAL(void) yySet(yycontext *yy, char *text, int count) { yy->__val[count]= yy->__; } #endif /* YY_PART */ #define YYACCEPT yyAccept(yy, yythunkpos0) YY_RULE(int) yy_Fname(yycontext *yy); /* 23 */ YY_RULE(int) yy_CLOSE(yycontext *yy); /* 22 */ YY_RULE(int) yy_OPEN(yycontext *yy); /* 21 */ YY_RULE(int) yy_Funcall(yycontext *yy); /* 20 */ YY_RULE(int) yy_Constant(yycontext *yy); /* 19 */ YY_RULE(int) yy_SI_Unit(yycontext *yy); /* 18 */ YY_RULE(int) yy_F_NUMBER(yycontext *yy); /* 17 */ YY_RULE(int) yy_MOD(yycontext *yy); /* 16 */ YY_RULE(int) yy_DIVIDE(yycontext *yy); /* 15 */ YY_RULE(int) yy_TIMES(yycontext *yy); /* 14 */ YY_RULE(int) yy_POW(yycontext *yy); /* 13 */ YY_RULE(int) yy_Value(yycontext *yy); /* 12 */ YY_RULE(int) yy_GREATER_THAN(yycontext *yy); /* 11 */ YY_RULE(int) yy_GREATEREQ_THAN(yycontext *yy); /* 10 */ YY_RULE(int) yy_LESS_THAN(yycontext *yy); /* 9 */ YY_RULE(int) yy_LESSEQ_THAN(yycontext *yy); /* 8 */ YY_RULE(int) yy_CLOSE_ENOUGH(yycontext *yy); /* 7 */ YY_RULE(int) yy_MINUS(yycontext *yy); /* 6 */ YY_RULE(int) yy_PLUS(yycontext *yy); /* 5 */ YY_RULE(int) yy_Product(yycontext *yy); /* 4 */ YY_RULE(int) yy_Sum(yycontext *yy); /* 3 */ YY_RULE(int) yy_SPACE(yycontext *yy); /* 2 */ YY_RULE(int) yy_Expr(yycontext *yy); /* 1 */ YY_ACTION(void) yy_5_SI_Unit(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_5_SI_Unit\n")); { math_eval_push(1000000000000000, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_SI_Unit(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_SI_Unit\n")); { math_eval_push(1000000000000, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_SI_Unit(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_SI_Unit\n")); { math_eval_push(1000000000, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_SI_Unit(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_SI_Unit\n")); { math_eval_push(1000000, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_SI_Unit(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_SI_Unit\n")); { math_eval_push(1000, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_13_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_13_Constant\n")); { math_eval_push(0.70710678118654752440, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_12_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_12_Constant\n")); { math_eval_push(1.41421356237309504880, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_11_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_11_Constant\n")); { math_eval_push(1.12837916709551257390, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_10_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_10_Constant\n")); { math_eval_push(0.63661977236758134308, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_9_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_9_Constant\n")); { math_eval_push(0.31830988618379067154, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_8_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_8_Constant\n")); { math_eval_push(0.78539816339744830962, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_7_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_7_Constant\n")); { math_eval_push(1.57079632679489661923, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_6_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_6_Constant\n")); { math_eval_push(3.14159265358979323846, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_5_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_5_Constant\n")); { math_eval_push(2.30258509299404568402, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_Constant\n")); { math_eval_push(0.69314718055994530942, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_Constant\n")); { math_eval_push(0.43429448190325182765, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Constant\n")); { math_eval_push(1.4426950408889634074, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Constant(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Constant\n")); { math_eval_push(2.7182818284590452354, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Fname(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Fname\n")); { strcpy(yy->fname, yytext); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Funcall(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Funcall\n")); { math_eval_push(EvaluateMathFunction(yy->fname, math_eval_pop(yy->stack, &(yy->stackp))), yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Value(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Value\n")); { double scanned = 0; sscanf(yytext, "%lf", &scanned); math_eval_push(scanned, yy->stack, &(yy->stackp)); /*Log(LOG_LEVEL_ERR, "YY: read FP %lf", scanned);*/ ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Value(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Value\n")); { double scanned = 0; sscanf(yytext, "%lf", &scanned); math_eval_push(math_eval_pop(yy->stack, &(yy->stackp)) * scanned, yy->stack, &(yy->stackp)); /* Log(LOG_LEVEL_ERR, "YY: read FP %lf", scanned); */ ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_Product(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_Product\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push((long)l % (long)r, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_Product(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_Product\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(l / r, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Product(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Product\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(l * r, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Product(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Product\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(pow(l, r), yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_7_Sum(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_7_Sum\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(l > r, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_6_Sum(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_6_Sum\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push((l > r || fabs(l - r) < 0.00000000000000001), yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_5_Sum(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_5_Sum\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(l < r, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_Sum(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_Sum\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push((l < r || fabs(l - r) < 0.00000000000000001), yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_Sum(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_Sum\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(fabs(l - r) < 0.00000000000000001, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Sum(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Sum\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(l - r, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Sum(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Sum\n")); { double r= math_eval_pop(yy->stack, &(yy->stackp)), l= math_eval_pop(yy->stack, &(yy->stackp)); math_eval_push(l + r, yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Expr(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Expr\n")); { strcpy(yy->failure, "expression could not be parsed"); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Expr(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Expr\n")); { yy->result = math_eval_pop(yy->stack, &(yy->stackp)); ; } #undef yythunkpos #undef yypos #undef yy } YY_RULE(int) yy_Fname(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Fname")); yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l1; #undef yytext #undef yyleng } { int yypos2= yy->__pos, yythunkpos2= yy->__thunkpos; if (!yymatchString(yy, "ceil")) goto l3; goto l2; l3:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "floor")) goto l4; goto l2; l4:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "log10")) goto l5; goto l2; l5:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "log2")) goto l6; goto l2; l6:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "log")) goto l7; goto l2; l7:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "sqrt")) goto l8; goto l2; l8:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "sin")) goto l9; goto l2; l9:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "cos")) goto l10; goto l2; l10:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "tan")) goto l11; goto l2; l11:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "asin")) goto l12; goto l2; l12:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "acos")) goto l13; goto l2; l13:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "atan")) goto l14; goto l2; l14:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "abs")) goto l15; goto l2; l15:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchString(yy, "step")) goto l1; } l2:; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l1; #undef yytext #undef yyleng } yyDo(yy, yy_1_Fname, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "Fname", yy->__buf+yy->__pos)); return 1; l1:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Fname", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_CLOSE(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "CLOSE")); if (!yymatchChar(yy, ')')) goto l16; if (!yy_SPACE(yy)) goto l16; yyprintf((stderr, " ok %s @ %s\n", "CLOSE", yy->__buf+yy->__pos)); return 1; l16:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "CLOSE", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_OPEN(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "OPEN")); if (!yymatchChar(yy, '(')) goto l17; if (!yy_SPACE(yy)) goto l17; yyprintf((stderr, " ok %s @ %s\n", "OPEN", yy->__buf+yy->__pos)); return 1; l17:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "OPEN", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Funcall(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Funcall")); if (!yy_Fname(yy)) goto l18; if (!yy_OPEN(yy)) goto l18; if (!yy_Value(yy)) goto l18; if (!yy_CLOSE(yy)) goto l18; yyDo(yy, yy_1_Funcall, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "Funcall", yy->__buf+yy->__pos)); return 1; l18:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Funcall", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Constant(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Constant")); { int yypos20= yy->__pos, yythunkpos20= yy->__thunkpos; if (!yymatchChar(yy, 'e')) goto l21; yyDo(yy, yy_1_Constant, yy->__begin, yy->__end); goto l20; l21:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "log2e")) goto l22; yyDo(yy, yy_2_Constant, yy->__begin, yy->__end); goto l20; l22:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "log10e")) goto l23; yyDo(yy, yy_3_Constant, yy->__begin, yy->__end); goto l20; l23:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "ln2")) goto l24; yyDo(yy, yy_4_Constant, yy->__begin, yy->__end); goto l20; l24:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "ln10")) goto l25; yyDo(yy, yy_5_Constant, yy->__begin, yy->__end); goto l20; l25:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "pi")) goto l26; yyDo(yy, yy_6_Constant, yy->__begin, yy->__end); goto l20; l26:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "pi_2")) goto l27; yyDo(yy, yy_7_Constant, yy->__begin, yy->__end); goto l20; l27:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "pi_4")) goto l28; yyDo(yy, yy_8_Constant, yy->__begin, yy->__end); goto l20; l28:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "1_pi")) goto l29; yyDo(yy, yy_9_Constant, yy->__begin, yy->__end); goto l20; l29:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "2_pi")) goto l30; yyDo(yy, yy_10_Constant, yy->__begin, yy->__end); goto l20; l30:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "2_sqrtpi")) goto l31; yyDo(yy, yy_11_Constant, yy->__begin, yy->__end); goto l20; l31:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "sqrt2")) goto l32; yyDo(yy, yy_12_Constant, yy->__begin, yy->__end); goto l20; l32:; yy->__pos= yypos20; yy->__thunkpos= yythunkpos20; if (!yymatchString(yy, "sqrt1_2")) goto l19; yyDo(yy, yy_13_Constant, yy->__begin, yy->__end); } l20:; yyprintf((stderr, " ok %s @ %s\n", "Constant", yy->__buf+yy->__pos)); return 1; l19:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Constant", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_SI_Unit(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "SI_Unit")); { int yypos34= yy->__pos, yythunkpos34= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\000\000\000\010\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l35; if (!yy_SPACE(yy)) goto l35; yyDo(yy, yy_1_SI_Unit, yy->__begin, yy->__end); goto l34; l35:; yy->__pos= yypos34; yy->__thunkpos= yythunkpos34; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\000\000\000\040\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l36; if (!yy_SPACE(yy)) goto l36; yyDo(yy, yy_2_SI_Unit, yy->__begin, yy->__end); goto l34; l36:; yy->__pos= yypos34; yy->__thunkpos= yythunkpos34; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\000\000\200\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l37; if (!yy_SPACE(yy)) goto l37; yyDo(yy, yy_3_SI_Unit, yy->__begin, yy->__end); goto l34; l37:; yy->__pos= yypos34; yy->__thunkpos= yythunkpos34; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\000\000\000\000\020\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l38; if (!yy_SPACE(yy)) goto l38; yyDo(yy, yy_4_SI_Unit, yy->__begin, yy->__end); goto l34; l38:; yy->__pos= yypos34; yy->__thunkpos= yythunkpos34; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l33; if (!yy_SPACE(yy)) goto l33; yyDo(yy, yy_5_SI_Unit, yy->__begin, yy->__end); } l34:; yyprintf((stderr, " ok %s @ %s\n", "SI_Unit", yy->__buf+yy->__pos)); return 1; l33:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "SI_Unit", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_F_NUMBER(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "F_NUMBER")); yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l39; #undef yytext #undef yyleng } { int yypos40= yy->__pos, yythunkpos40= yy->__thunkpos; { int yypos42= yy->__pos, yythunkpos42= yy->__thunkpos; if (!yymatchChar(yy, '-')) goto l42; goto l43; l42:; yy->__pos= yypos42; yy->__thunkpos= yythunkpos42; } l43:; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l41; l44:; { int yypos45= yy->__pos, yythunkpos45= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l45; goto l44; l45:; yy->__pos= yypos45; yy->__thunkpos= yythunkpos45; } { int yypos46= yy->__pos, yythunkpos46= yy->__thunkpos; if (!yymatchChar(yy, '.')) goto l46; goto l47; l46:; yy->__pos= yypos46; yy->__thunkpos= yythunkpos46; } l47:; l48:; { int yypos49= yy->__pos, yythunkpos49= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l49; goto l48; l49:; yy->__pos= yypos49; yy->__thunkpos= yythunkpos49; } goto l40; l41:; yy->__pos= yypos40; yy->__thunkpos= yythunkpos40; { int yypos50= yy->__pos, yythunkpos50= yy->__thunkpos; if (!yymatchChar(yy, '-')) goto l50; goto l51; l50:; yy->__pos= yypos50; yy->__thunkpos= yythunkpos50; } l51:; if (!yymatchChar(yy, '.')) goto l39; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l39; l52:; { int yypos53= yy->__pos, yythunkpos53= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l53; goto l52; l53:; yy->__pos= yypos53; yy->__thunkpos= yythunkpos53; } } l40:; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l39; #undef yytext #undef yyleng } if (!yy_SPACE(yy)) goto l39; yyprintf((stderr, " ok %s @ %s\n", "F_NUMBER", yy->__buf+yy->__pos)); return 1; l39:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "F_NUMBER", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_MOD(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "MOD")); if (!yymatchChar(yy, '%')) goto l54; if (!yy_SPACE(yy)) goto l54; yyprintf((stderr, " ok %s @ %s\n", "MOD", yy->__buf+yy->__pos)); return 1; l54:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "MOD", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_DIVIDE(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "DIVIDE")); if (!yymatchChar(yy, '/')) goto l55; if (!yy_SPACE(yy)) goto l55; yyprintf((stderr, " ok %s @ %s\n", "DIVIDE", yy->__buf+yy->__pos)); return 1; l55:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "DIVIDE", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_TIMES(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "TIMES")); if (!yymatchChar(yy, '*')) goto l56; if (!yy_SPACE(yy)) goto l56; yyprintf((stderr, " ok %s @ %s\n", "TIMES", yy->__buf+yy->__pos)); return 1; l56:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "TIMES", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_POW(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "POW")); { int yypos58= yy->__pos, yythunkpos58= yy->__thunkpos; if (!yymatchChar(yy, '^')) goto l59; if (!yy_SPACE(yy)) goto l59; goto l58; l59:; yy->__pos= yypos58; yy->__thunkpos= yythunkpos58; if (!yymatchString(yy, "**")) goto l57; if (!yy_SPACE(yy)) goto l57; } l58:; yyprintf((stderr, " ok %s @ %s\n", "POW", yy->__buf+yy->__pos)); return 1; l57:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "POW", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Value(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Value")); { int yypos61= yy->__pos, yythunkpos61= yy->__thunkpos; if (!yy_F_NUMBER(yy)) goto l62; if (!yy_SI_Unit(yy)) goto l62; yyDo(yy, yy_1_Value, yy->__begin, yy->__end); goto l61; l62:; yy->__pos= yypos61; yy->__thunkpos= yythunkpos61; if (!yy_F_NUMBER(yy)) goto l63; yyDo(yy, yy_2_Value, yy->__begin, yy->__end); goto l61; l63:; yy->__pos= yypos61; yy->__thunkpos= yythunkpos61; if (!yy_Constant(yy)) goto l64; goto l61; l64:; yy->__pos= yypos61; yy->__thunkpos= yythunkpos61; if (!yy_Funcall(yy)) goto l65; goto l61; l65:; yy->__pos= yypos61; yy->__thunkpos= yythunkpos61; if (!yy_OPEN(yy)) goto l60; if (!yy_Sum(yy)) goto l60; if (!yy_CLOSE(yy)) goto l60; } l61:; yyprintf((stderr, " ok %s @ %s\n", "Value", yy->__buf+yy->__pos)); return 1; l60:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Value", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_GREATER_THAN(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "GREATER_THAN")); if (!yymatchChar(yy, '>')) goto l66; if (!yy_SPACE(yy)) goto l66; yyprintf((stderr, " ok %s @ %s\n", "GREATER_THAN", yy->__buf+yy->__pos)); return 1; l66:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "GREATER_THAN", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_GREATEREQ_THAN(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "GREATEREQ_THAN")); if (!yymatchString(yy, ">=")) goto l67; if (!yy_SPACE(yy)) goto l67; yyprintf((stderr, " ok %s @ %s\n", "GREATEREQ_THAN", yy->__buf+yy->__pos)); return 1; l67:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "GREATEREQ_THAN", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LESS_THAN(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LESS_THAN")); if (!yymatchChar(yy, '<')) goto l68; if (!yy_SPACE(yy)) goto l68; yyprintf((stderr, " ok %s @ %s\n", "LESS_THAN", yy->__buf+yy->__pos)); return 1; l68:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LESS_THAN", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LESSEQ_THAN(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LESSEQ_THAN")); if (!yymatchString(yy, "<=")) goto l69; if (!yy_SPACE(yy)) goto l69; yyprintf((stderr, " ok %s @ %s\n", "LESSEQ_THAN", yy->__buf+yy->__pos)); return 1; l69:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LESSEQ_THAN", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_CLOSE_ENOUGH(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "CLOSE_ENOUGH")); if (!yymatchString(yy, "==")) goto l70; if (!yy_SPACE(yy)) goto l70; yyprintf((stderr, " ok %s @ %s\n", "CLOSE_ENOUGH", yy->__buf+yy->__pos)); return 1; l70:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "CLOSE_ENOUGH", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_MINUS(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "MINUS")); if (!yymatchChar(yy, '-')) goto l71; if (!yy_SPACE(yy)) goto l71; yyprintf((stderr, " ok %s @ %s\n", "MINUS", yy->__buf+yy->__pos)); return 1; l71:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "MINUS", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_PLUS(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "PLUS")); if (!yymatchChar(yy, '+')) goto l72; if (!yy_SPACE(yy)) goto l72; yyprintf((stderr, " ok %s @ %s\n", "PLUS", yy->__buf+yy->__pos)); return 1; l72:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "PLUS", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Product(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Product")); if (!yy_Value(yy)) goto l73; l74:; { int yypos75= yy->__pos, yythunkpos75= yy->__thunkpos; { int yypos76= yy->__pos, yythunkpos76= yy->__thunkpos; if (!yy_POW(yy)) goto l77; if (!yy_Value(yy)) goto l77; yyDo(yy, yy_1_Product, yy->__begin, yy->__end); goto l76; l77:; yy->__pos= yypos76; yy->__thunkpos= yythunkpos76; if (!yy_TIMES(yy)) goto l78; if (!yy_Value(yy)) goto l78; yyDo(yy, yy_2_Product, yy->__begin, yy->__end); goto l76; l78:; yy->__pos= yypos76; yy->__thunkpos= yythunkpos76; if (!yy_DIVIDE(yy)) goto l79; if (!yy_Value(yy)) goto l79; yyDo(yy, yy_3_Product, yy->__begin, yy->__end); goto l76; l79:; yy->__pos= yypos76; yy->__thunkpos= yythunkpos76; if (!yy_MOD(yy)) goto l75; if (!yy_Value(yy)) goto l75; yyDo(yy, yy_4_Product, yy->__begin, yy->__end); } l76:; goto l74; l75:; yy->__pos= yypos75; yy->__thunkpos= yythunkpos75; } yyprintf((stderr, " ok %s @ %s\n", "Product", yy->__buf+yy->__pos)); return 1; l73:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Product", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Sum(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Sum")); if (!yy_Product(yy)) goto l80; l81:; { int yypos82= yy->__pos, yythunkpos82= yy->__thunkpos; { int yypos83= yy->__pos, yythunkpos83= yy->__thunkpos; if (!yy_PLUS(yy)) goto l84; if (!yy_Product(yy)) goto l84; yyDo(yy, yy_1_Sum, yy->__begin, yy->__end); goto l83; l84:; yy->__pos= yypos83; yy->__thunkpos= yythunkpos83; if (!yy_MINUS(yy)) goto l85; if (!yy_Product(yy)) goto l85; yyDo(yy, yy_2_Sum, yy->__begin, yy->__end); goto l83; l85:; yy->__pos= yypos83; yy->__thunkpos= yythunkpos83; if (!yy_CLOSE_ENOUGH(yy)) goto l86; if (!yy_Product(yy)) goto l86; yyDo(yy, yy_3_Sum, yy->__begin, yy->__end); goto l83; l86:; yy->__pos= yypos83; yy->__thunkpos= yythunkpos83; if (!yy_LESSEQ_THAN(yy)) goto l87; if (!yy_Product(yy)) goto l87; yyDo(yy, yy_4_Sum, yy->__begin, yy->__end); goto l83; l87:; yy->__pos= yypos83; yy->__thunkpos= yythunkpos83; if (!yy_LESS_THAN(yy)) goto l88; if (!yy_Product(yy)) goto l88; yyDo(yy, yy_5_Sum, yy->__begin, yy->__end); goto l83; l88:; yy->__pos= yypos83; yy->__thunkpos= yythunkpos83; if (!yy_GREATEREQ_THAN(yy)) goto l89; if (!yy_Product(yy)) goto l89; yyDo(yy, yy_6_Sum, yy->__begin, yy->__end); goto l83; l89:; yy->__pos= yypos83; yy->__thunkpos= yythunkpos83; if (!yy_GREATER_THAN(yy)) goto l82; if (!yy_Product(yy)) goto l82; yyDo(yy, yy_7_Sum, yy->__begin, yy->__end); } l83:; goto l81; l82:; yy->__pos= yypos82; yy->__thunkpos= yythunkpos82; } yyprintf((stderr, " ok %s @ %s\n", "Sum", yy->__buf+yy->__pos)); return 1; l80:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Sum", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_SPACE(yycontext *yy) { yyprintf((stderr, "%s\n", "SPACE")); l91:; { int yypos92= yy->__pos, yythunkpos92= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\002\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l92; goto l91; l92:; yy->__pos= yypos92; yy->__thunkpos= yythunkpos92; } yyprintf((stderr, " ok %s @ %s\n", "SPACE", yy->__buf+yy->__pos)); return 1; } YY_RULE(int) yy_Expr(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Expr")); { int yypos94= yy->__pos, yythunkpos94= yy->__thunkpos; if (!yy_SPACE(yy)) goto l95; if (!yy_Sum(yy)) goto l95; yyDo(yy, yy_1_Expr, yy->__begin, yy->__end); goto l94; l95:; yy->__pos= yypos94; yy->__thunkpos= yythunkpos94; if (!yymatchDot(yy)) goto l93; yyDo(yy, yy_2_Expr, yy->__begin, yy->__end); } l94:; yyprintf((stderr, " ok %s @ %s\n", "Expr", yy->__buf+yy->__pos)); return 1; l93:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Expr", yy->__buf+yy->__pos)); return 0; } #ifndef YY_PART typedef int (*yyrule)(yycontext *yy); YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart) { int yyok; if (!yyctx->__buflen) { yyctx->__buflen= YY_BUFFER_SIZE; yyctx->__buf= (char *)YY_MALLOC(yyctx, yyctx->__buflen); yyctx->__textlen= YY_BUFFER_SIZE; yyctx->__text= (char *)YY_MALLOC(yyctx, yyctx->__textlen); yyctx->__thunkslen= YY_STACK_SIZE; yyctx->__thunks= (yythunk *)YY_MALLOC(yyctx, sizeof(yythunk) * yyctx->__thunkslen); yyctx->__valslen= YY_STACK_SIZE; yyctx->__vals= (YYSTYPE *)YY_MALLOC(yyctx, sizeof(YYSTYPE) * yyctx->__valslen); yyctx->__begin= yyctx->__end= yyctx->__pos= yyctx->__limit= yyctx->__thunkpos= 0; } yyctx->__begin= yyctx->__end= yyctx->__pos; yyctx->__thunkpos= 0; yyctx->__val= yyctx->__vals; yyok= yystart(yyctx); if (yyok) yyDone(yyctx); yyCommit(yyctx); return yyok; } YY_PARSE(int) YYPARSE(YY_CTX_PARAM) { return YYPARSEFROM(YY_CTX_ARG_ yy_Expr); } YY_PARSE(yycontext *) YYRELEASE(yycontext *yyctx) { if (yyctx->__buflen) { yyctx->__buflen= 0; YY_FREE(yyctx, yyctx->__buf); YY_FREE(yyctx, yyctx->__text); YY_FREE(yyctx, yyctx->__thunks); YY_FREE(yyctx, yyctx->__vals); } return yyctx; } #endif cfengine-3.24.2/libpromises/enterprise_extension.sed0000644000000000000000000000224315010704253022655 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # s,.*BEGIN_MARKER.*,/* #### THIS FILE WAS AUTOGENERATED FROM extensions_template.[ch].pre #### */,; s/xEXTENSIONx/ENTERPRISE/g; s/XextensionX/enterprise/g; s/xExtensionX/Enterprise/g; cfengine-3.24.2/libpromises/class.c0000644000000000000000000002023515010704253017156 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include /* String*() */ #include /* CompileRegex,StringMatchFullWithPrecompiledRegex */ #include static void ClassDestroy(Class *cls); /* forward declaration */ static void ClassDestroy_untyped(void *p) { ClassDestroy(p); } /** Define ClassMap. Key: a string which is always the fully qualified class name, for example "default:127_0_0_1" */ TYPED_MAP_DECLARE(Class, char *, Class *) TYPED_MAP_DEFINE(Class, char *, Class *, StringHash_untyped, StringEqual_untyped, free, ClassDestroy_untyped) struct ClassTable_ { ClassMap *classes; }; struct ClassTableIterator_ { MapIterator iter; char *ns; bool is_hard; bool is_soft; }; static void ClassInit(Class *cls, const char *ns, const char *name, bool is_soft, ContextScope scope, StringSet *tags, const char *comment) { assert(cls != NULL); if (ns == NULL || strcmp(ns, "default") == 0) { cls->ns = NULL; } else { cls->ns = xstrdup(ns); } cls->name = xstrdup(name); CanonifyNameInPlace(cls->name); cls->is_soft = is_soft; cls->scope = scope; cls->tags = (tags ? tags : StringSetNew()); if (!is_soft && !StringSetContains(cls->tags, "hardclass")) { StringSetAdd(cls->tags, xstrdup("hardclass")); } cls->comment = SafeStringDuplicate(comment); } static void ClassDestroySoft(Class *cls) { if (cls != NULL) { free(cls->ns); free(cls->name); StringSetDestroy(cls->tags); free(cls->comment); } } static void ClassDestroy(Class *cls) { if (cls) { ClassDestroySoft(cls); free(cls); } } ClassTable *ClassTableNew(void) { ClassTable *table = xmalloc(sizeof(*table)); table->classes = ClassMapNew(); return table; } void ClassTableDestroy(ClassTable *table) { if (table) { ClassMapDestroy(table->classes); free(table); } } bool ClassTablePut(ClassTable *table, const char *ns, const char *name, bool is_soft, ContextScope scope, StringSet *tags, const char *comment) { assert(name); assert(is_soft || (!ns || strcmp("default", ns) == 0)); // hard classes should have default namespace assert(is_soft || scope == CONTEXT_SCOPE_NAMESPACE); // hard classes cannot be local if (ns == NULL) { ns = "default"; } Class *cls = xmalloc(sizeof(*cls)); ClassInit(cls, ns, name, is_soft, scope, tags, comment); /* (cls->name != name) because canonification has happened. */ char *fullname = StringConcatenate(3, ns, ":", cls->name); Log(LOG_LEVEL_DEBUG, "Setting %sclass: %s", is_soft ? "" : "hard ", fullname); return ClassMapInsert(table->classes, fullname, cls); } Class *ClassTableGet(const ClassTable *table, const char *ns, const char *name) { if (ns == NULL) { ns = "default"; } char fullname[ strlen(ns) + 1 + strlen(name) + 1 ]; xsnprintf(fullname, sizeof(fullname), "%s:%s", ns, name); return ClassMapGet(table->classes, fullname); } Class *ClassTableMatch(const ClassTable *table, const char *regex) { ClassTableIterator *it = ClassTableIteratorNew(table, NULL, true, true); Class *cls = NULL; Regex *pattern = CompileRegex(regex); if (pattern == NULL) { // TODO: perhaps pcre has can give more info on this error? Log(LOG_LEVEL_ERR, "Unable to pcre compile regex '%s'", regex); return NULL; } while ((cls = ClassTableIteratorNext(it))) { bool matched; if (cls->ns) { char *class_expr = ClassRefToString(cls->ns, cls->name); matched = StringMatchFullWithPrecompiledRegex(pattern, class_expr); free(class_expr); } else { matched = StringMatchFullWithPrecompiledRegex(pattern, cls->name); } if (matched) { break; } } RegexDestroy(pattern); ClassTableIteratorDestroy(it); return cls; } bool ClassTableRemove(ClassTable *table, const char *ns, const char *name) { if (ns == NULL) { ns = "default"; } char fullname[ strlen(ns) + 1 + strlen(name) + 1 ]; xsnprintf(fullname, sizeof(fullname), "%s:%s", ns, name); return ClassMapRemove(table->classes, fullname); } bool ClassTableClear(ClassTable *table) { bool has_classes = (ClassMapSize(table->classes) > 0); ClassMapClear(table->classes); return has_classes; } ClassTableIterator *ClassTableIteratorNew(const ClassTable *table, const char *ns, bool is_hard, bool is_soft) { ClassTableIterator *iter = xmalloc(sizeof(*iter)); iter->ns = ns ? xstrdup(ns) : NULL; iter->iter = MapIteratorInit(table->classes->impl); iter->is_soft = is_soft; iter->is_hard = is_hard; return iter; } Class *ClassTableIteratorNext(ClassTableIterator *iter) { MapKeyValue *keyvalue; while ((keyvalue = MapIteratorNext(&iter->iter)) != NULL) { Class *cls = keyvalue->value; /* Make sure we never store "default" as namespace in the ClassTable, * instead we have always ns==NULL in that case. */ CF_ASSERT_FIX(cls->ns == NULL || strcmp(cls->ns, "default") != 0, (cls->ns = NULL), "Class table contained \"default\" namespace," " should never happen!"); const char *key_ns = cls->ns ? cls->ns : "default"; if (iter->ns && strcmp(key_ns, iter->ns) != 0) { continue; } if (iter->is_soft && !iter->is_soft) { continue; } if (iter->is_hard && !iter->is_hard) { continue; } return cls; } return NULL; } void ClassTableIteratorDestroy(ClassTableIterator *iter) { if (iter) { free(iter->ns); free(iter); } } ClassRef ClassRefParse(const char *expr) { char *name_start = strchr(expr, ':'); if (!name_start) { return (ClassRef) { .ns = NULL, .name = xstrdup(expr) }; } else { char *ns = NULL; if ((name_start - expr) > 0) { ns = xstrndup(expr, name_start - expr); } else { // this would be invalid syntax ns = xstrdup(""); } char *name = xstrdup(name_start + 1); return (ClassRef) { .ns = ns, .name = name }; } } char *ClassRefToString(const char *ns, const char *name) { assert(name != NULL); if (ns == NULL || strcmp("default", ns) == 0) { return xstrdup(name); } else { return StringConcatenate(3, ns, ":", name); } } bool ClassRefIsQualified(ClassRef ref) { return ref.ns != NULL; } void ClassRefQualify(ClassRef *ref, const char *ns) { free(ref->ns); ref->ns = xstrdup(ns); } void ClassRefDestroy(ClassRef ref) { free(ref.ns); free(ref.name); } cfengine-3.24.2/libpromises/mod_knowledge.h0000644000000000000000000000217715010704253020701 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_KNOWLEDGE_H #define CFENGINE_MOD_KNOWLEDGE_H #include extern const PromiseTypeSyntax CF_KNOWLEDGE_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/generic_agent.c0000644000000000000000000027772715010704253020667 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include // FileCanOpen() #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // StringCopy() #include // CompileRegex() #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* LoadCMDBData() */ #include "cf3.defs.h" #define AUGMENTS_VARIABLES_TAGS "tags" #define AUGMENTS_VARIABLES_DATA "value" #define AUGMENTS_CLASSES_TAGS "tags" #define AUGMENTS_CLASSES_CLASS_EXPRESSIONS "class_expressions" #define AUGMENTS_CLASSES_REGULAR_EXPRESSIONS "regular_expressions" #define AUGMENTS_COMMENT_KEY "comment" static pthread_once_t pid_cleanup_once = PTHREAD_ONCE_INIT; /* GLOBAL_T */ static char PIDFILE[CF_BUFSIZE] = ""; /* GLOBAL_C */ /* Used for 'ident' argument to openlog() */ static char CF_PROGRAM_NAME[256] = ""; static void CheckWorkingDirectories(EvalContext *ctx); static void GetAutotagDir(char *dirname, size_t max_size, const char *maybe_dirname); static void GetPromisesValidatedFile(char *filename, size_t max_size, const GenericAgentConfig *config, const char *maybe_dirname); static bool WriteReleaseIdFile(const char *filename, const char *dirname); static bool GeneratePolicyReleaseIDFromGit(char *release_id_out, size_t out_size, const char *policy_dir); static bool GeneratePolicyReleaseID(char *release_id_out, size_t out_size, const char *policy_dir); static char* ReadReleaseIdFromReleaseIdFileMasterfiles(const char *maybe_dirname); static bool MissingInputFile(const char *input_file); static bool LoadAugmentsFiles(EvalContext *ctx, const char* filename); static void GetChangesChrootDir(char *buf, size_t buf_size); static void DeleteChangesChroot(); static int ParseFacility(const char *name); static inline const char *LogFacilityToString(int facility); #if !defined(__MINGW32__) static void OpenLog(int facility); #endif /*****************************************************************************/ static void SanitizeEnvironment() { /* ps(1) and other utilities invoked by CFEngine may be affected */ unsetenv("COLUMNS"); /* Make sure subprocesses output is not localized */ unsetenv("LANG"); unsetenv("LANGUAGE"); unsetenv("LC_MESSAGES"); } /*****************************************************************************/ ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, GenericAgentSetDefaultDigest, HashMethod *, digest, int *, digest_len) { *digest = HASH_METHOD_MD5; *digest_len = CF_MD5_LEN; } void SetCFEngineRoles(EvalContext *ctx) { char cf_hub_path[PATH_MAX]; snprintf(cf_hub_path, sizeof(cf_hub_path), "%s%ccf-hub", GetBinDir(), FILE_SEPARATOR); const bool is_reporting_hub = (access(cf_hub_path, F_OK) == 0); const bool is_policy_server = EvalContextClassGet(ctx, "default", "policy_server"); if (!is_policy_server && !is_reporting_hub) { EvalContextClassPutHard(ctx, "cfengine_client", "report"); Rlist *const roles = RlistFromSplitString("Client", ','); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cfengine_roles", roles, CF_DATA_TYPE_STRING_LIST, "inventory,attribute_name=CFEngine roles"); RlistDestroy(roles); return; } if (is_reporting_hub) { EvalContextClassPutHard(ctx, "cfengine_reporting_hub", "report"); } // Community policy server: if (is_policy_server && !is_reporting_hub) { Rlist *const roles = RlistFromSplitString("Policy server", ','); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cfengine_roles", roles, CF_DATA_TYPE_STRING_LIST, "inventory,attribute_name=CFEngine roles"); RlistDestroy(roles); return; } // Enterprise hub bootstrapped to another policy server: // TODO: This is a weird situation, should we print a warning? if (is_reporting_hub && !is_policy_server) { Rlist *const roles = RlistFromSplitString("Reporting hub", ','); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cfengine_roles", roles, CF_DATA_TYPE_STRING_LIST, "inventory,attribute_name=CFEngine roles"); RlistDestroy(roles); return; } // Normal Enterprise hub: assert(is_policy_server && is_reporting_hub); Rlist *const roles = RlistFromSplitString("Policy server,Reporting hub", ','); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cfengine_roles", roles, CF_DATA_TYPE_STRING_LIST, "inventory,attribute_name=CFEngine roles"); RlistDestroy(roles); return; } void MarkAsPolicyServer(EvalContext *ctx) { EvalContextClassPutHard(ctx, "am_policy_hub", "source=bootstrap,deprecated,alias=policy_server"); Log(LOG_LEVEL_VERBOSE, "Additional class defined: am_policy_hub"); EvalContextClassPutHard(ctx, "policy_server", "report"); Log(LOG_LEVEL_VERBOSE, "Additional class defined: policy_server"); } Policy *SelectAndLoadPolicy(GenericAgentConfig *config, EvalContext *ctx, bool validate_policy, bool write_validated_file) { Policy *policy = NULL; if (GenericAgentCheckPolicy(config, validate_policy, write_validated_file)) { policy = LoadPolicy(ctx, config); } else if (config->tty_interactive) { Log(LOG_LEVEL_ERR, "Failsafe condition triggered. Interactive session detected, skipping failsafe.cf execution."); } else { Log(LOG_LEVEL_ERR, "CFEngine was not able to get confirmation of promises from cf-promises, so going to failsafe"); EvalContextClassPutHard(ctx, "failsafe_fallback", "report,attribute_name=Errors,source=agent"); if (CheckAndGenerateFailsafe(GetInputDir(), "failsafe.cf")) { GenericAgentConfigSetInputFile(config, GetInputDir(), "failsafe.cf"); Log(LOG_LEVEL_ERR, "CFEngine failsafe.cf: %s %s", config->input_dir, config->input_file); policy = LoadPolicy(ctx, config); /* Doing failsafe, set the release_id to "failsafe" and also * overwrite the cfe_release_id file so that sub-agent executed as * part of failsafe can just pick it up and then rewrite it with the * actual value from masterfiles. */ free(policy->release_id); policy->release_id = xstrdup("failsafe"); char filename[PATH_MAX]; GetReleaseIdFile(GetInputDir(), filename, sizeof(filename)); FILE *release_id_stream = safe_fopen_create_perms(filename, "w", CF_PERMS_DEFAULT); if (release_id_stream == NULL) { Log(LOG_LEVEL_ERR, "Failed to open the release_id file for writing during failsafe"); } else { Writer *release_id_writer = FileWriter(release_id_stream); WriterWrite(release_id_writer, "{ releaseId: \"failsafe\" }\n"); WriterClose(release_id_writer); } } } return policy; } static bool CheckContextClassmatch(EvalContext *ctx, const char *class_str) { if (StringEndsWith(class_str, "::")) // Treat as class expression, not regex { const size_t length = strlen(class_str); if (length <= 2) { assert(length == 2); // True because StringEndsWith Log(LOG_LEVEL_ERR, "Invalid class expression in augments: '%s'", class_str); return false; } char *const tmp_class_str = xstrdup(class_str); assert(strlen(tmp_class_str) == length); tmp_class_str[length - 2] = '\0'; // 2 = strlen("::") const bool found = IsDefinedClass(ctx, tmp_class_str); free(tmp_class_str); return found; } ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); StringSet *global_matches = ClassesMatching(ctx, iter, class_str, NULL, true); // returns early const bool found = (StringSetSize(global_matches) > 0); StringSetDestroy(global_matches); ClassTableIteratorDestroy(iter); return found; } static StringSet *GetTagsFromAugmentsTags(const char *item_type, const char *key, const JsonElement *json_tags, const char *default_tag, const char *filename) { StringSet *tags = NULL; if (JSON_NOT_NULL(json_tags)) { if ((JsonGetType(json_tags) != JSON_TYPE_ARRAY) || (!JsonArrayContainsOnlyPrimitives((JsonElement*) json_tags))) { Log(LOG_LEVEL_ERR, "Invalid tags information for %s '%s' in augments file '%s':" " must be a JSON array of strings", item_type, key, filename); } else { tags = JsonArrayToStringSet(json_tags); if (tags == NULL) { Log(LOG_LEVEL_ERR, "Invalid meta information %s '%s' in augments file '%s':" " must be a JSON array of strings", item_type, key, filename); } } } if (tags == NULL) { tags = StringSetNew(); } StringSetAdd(tags, xstrdup(default_tag)); return tags; } static inline bool CanSetVariable(const EvalContext *ctx, VarRef *var_ref) { assert(var_ref != NULL); bool null_ns = false; if (var_ref->ns == NULL) { null_ns = true; var_ref->ns = "default"; } StringSet *tags = EvalContextVariableTags(ctx, var_ref); bool can_set = ((tags == NULL) || !StringSetContains(tags, CMDB_SOURCE_TAG)); if (!can_set) { Log(LOG_LEVEL_VERBOSE, "Cannot set variable %s:%s.%s from augments, already defined from host-specific data", var_ref->ns, var_ref->scope, var_ref->lval); } if (null_ns) { var_ref->ns = NULL; } return can_set; } static inline bool CanSetClass(const EvalContext *ctx, const char *class_spec) { char *ns = NULL; char *ns_delim = strchr(class_spec, ':'); if (ns_delim != NULL) { ns = xstrndup(class_spec, ns_delim - class_spec); class_spec = ns_delim + 1; } StringSet *tags = EvalContextClassTags(ctx, ns, class_spec); bool can_set = ((tags == NULL) || !StringSetContains(tags, CMDB_SOURCE_TAG)); if (!can_set) { Log(LOG_LEVEL_VERBOSE, "Cannot set class %s:%s from augments, already defined from host-specific data", ns, class_spec); } return can_set; } static inline const char *GetAugmentsComment(const char *item_type, const char *identifier, const char *file_name, const JsonElement *json_object) { assert(JsonGetType(json_object) == JSON_TYPE_OBJECT); JsonElement *json_comment = JsonObjectGet(json_object, AUGMENTS_COMMENT_KEY); if (NULL_JSON(json_comment)) { return NULL; } if (JsonGetType(json_comment) != JSON_TYPE_STRING) { Log(LOG_LEVEL_ERR, "Invalid type of the 'comment' field for the '%s' %s in augments data in '%s', must be a string", identifier, item_type, file_name); return NULL; } return JsonPrimitiveGetAsString(json_comment); } static bool LoadAugmentsData(EvalContext *ctx, const char *filename, const JsonElement* augment) { bool loaded = false; if (JsonGetElementType(augment) != JSON_ELEMENT_TYPE_CONTAINER || JsonGetContainerType(augment) != JSON_CONTAINER_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid augments file contents in '%s', must be a JSON object", filename); } else { loaded = true; Log(LOG_LEVEL_VERBOSE, "Loaded augments file '%s', installing contents", filename); JsonIterator iter = JsonIteratorInit(augment); const char *key; while ((key = JsonIteratorNextKey(&iter))) { if (!(StringEqual(key, "vars") || StringEqual(key, "classes") || StringEqual(key, "inputs") || StringEqual(key, "augments"))) { Log(LOG_LEVEL_VERBOSE, "Unknown augments key '%s' in file '%s', skipping it", key, filename); } } /* load variables (if any) */ JsonElement *element = JsonObjectGet(augment, "vars"); if (JSON_NOT_NULL(element)) { JsonElement* vars = JsonExpandElement(ctx, element); if (vars == NULL || JsonGetElementType(vars) != JSON_ELEMENT_TYPE_CONTAINER || JsonGetContainerType(vars) != JSON_CONTAINER_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid augments vars in '%s', must be a JSON object", filename); goto vars_cleanup; } JsonIterator iter = JsonIteratorInit(vars); const char *vkey; while ((vkey = JsonIteratorNextKey(&iter))) { VarRef *ref = VarRefParse(vkey); if (ref->ns != NULL) { if (ref->scope == NULL) { Log(LOG_LEVEL_ERR, "Invalid variable specification in augments data in '%s': '%s'" " (bundle name has to be specified if namespace is specified)", filename, vkey); VarRefDestroy(ref); continue; } } if (ref->scope == NULL) { ref->scope = xstrdup("def"); } JsonElement *data = JsonObjectGet(vars, vkey); if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_PRIMITIVE) { char *value = JsonPrimitiveToString(data); if ((ref->ns == NULL) && (ref->scope == NULL)) { Log(LOG_LEVEL_VERBOSE, "Installing augments variable '%s.%s=%s' from file '%s'", SpecialScopeToString(SPECIAL_SCOPE_DEF), vkey, value, filename); if (CanSetVariable(ctx, ref)) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_DEF, vkey, value, CF_DATA_TYPE_STRING, "source=augments_file"); } } else { Log(LOG_LEVEL_VERBOSE, "Installing augments variable '%s=%s' from file '%s'", vkey, value, filename); if (CanSetVariable(ctx, ref)) { EvalContextVariablePut(ctx, ref, value, CF_DATA_TYPE_STRING, "source=augments_file"); } } free(value); } else if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_CONTAINER && JsonGetContainerType(data) == JSON_CONTAINER_TYPE_ARRAY && JsonArrayContainsOnlyPrimitives(data)) { // map to slist if the data only has primitives Rlist *data_as_rlist = RlistFromContainer(data); if ((ref->ns == NULL) && (ref->scope == NULL)) { Log(LOG_LEVEL_VERBOSE, "Installing augments slist variable '%s.%s' from file '%s'", SpecialScopeToString(SPECIAL_SCOPE_DEF), vkey, filename); if (CanSetVariable(ctx, ref)) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_DEF, vkey, data_as_rlist, CF_DATA_TYPE_STRING_LIST, "source=augments_file"); } } else { Log(LOG_LEVEL_VERBOSE, "Installing augments slist variable '%s' from file '%s'", vkey, filename); if (CanSetVariable(ctx, ref)) { EvalContextVariablePut(ctx, ref, data_as_rlist, CF_DATA_TYPE_STRING_LIST, "source=augments_file"); } } RlistDestroy(data_as_rlist); } else // install as a data container { if ((ref->ns == NULL) && (ref->scope == NULL)) { Log(LOG_LEVEL_VERBOSE, "Installing augments data container variable '%s.%s' from file '%s'", SpecialScopeToString(SPECIAL_SCOPE_DEF), vkey, filename); if (CanSetVariable(ctx, ref)) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_DEF, vkey, data, CF_DATA_TYPE_CONTAINER, "source=augments_file"); } } else { Log(LOG_LEVEL_VERBOSE, "Installing augments data container variable '%s' from file '%s'", vkey, filename); if (CanSetVariable(ctx, ref)) { EvalContextVariablePut(ctx, ref, data, CF_DATA_TYPE_CONTAINER, "source=augments_file"); } } } VarRefDestroy(ref); } vars_cleanup: JsonDestroy(vars); } /* Uses the new format allowing metadata (CFE-3633) */ element = JsonObjectGet(augment, "variables"); if (JSON_NOT_NULL(element)) { JsonElement* variables = JsonExpandElement(ctx, element); if (variables == NULL || JsonGetType(variables) != JSON_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid augments variables in '%s', must be a JSON object", filename); goto variables_cleanup; } JsonIterator variables_iter = JsonIteratorInit(variables); const char *vkey; while ((vkey = JsonIteratorNextKey(&variables_iter))) { VarRef *ref = VarRefParse(vkey); if (ref->ns != NULL) { if (ref->scope == NULL) { Log(LOG_LEVEL_ERR, "Invalid variable specification in augments data in '%s': '%s'" " (bundle name has to be specified if namespace is specified)", filename, vkey); VarRefDestroy(ref); continue; } } if (ref->scope == NULL) { ref->scope = xstrdup("def"); } const JsonElement *const var_info = JsonObjectGet(variables, vkey); const JsonElement *data; StringSet *tags; const char *comment = NULL; if (JsonGetType(var_info) == JSON_TYPE_OBJECT) { data = JsonObjectGet(var_info, AUGMENTS_VARIABLES_DATA); if (NULL_JSON(data)) { Log(LOG_LEVEL_ERR, "Missing value for the augments variable '%s' in '%s' (value field is required)", vkey, filename); VarRefDestroy(ref); continue; } const JsonElement *json_tags = JsonObjectGet(var_info, AUGMENTS_VARIABLES_TAGS); tags = GetTagsFromAugmentsTags("variable", vkey, json_tags, "source=augments_file", filename); comment = GetAugmentsComment("variable", vkey, filename, var_info); } else { // Just a bare value, like in "vars", no metadata data = var_info; tags = GetTagsFromAugmentsTags("variable", vkey, NULL, "source=augments_file", filename); } assert(tags != NULL); assert(data != NULL); bool installed = false; if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_PRIMITIVE) { char *value = JsonPrimitiveToString(data); if ((ref->ns == NULL) && (ref->scope == NULL)) { Log(LOG_LEVEL_VERBOSE, "Installing augments variable '%s.%s=%s' from file '%s'", SpecialScopeToString(SPECIAL_SCOPE_DEF), vkey, value, filename); if (CanSetVariable(ctx, ref)) { installed = EvalContextVariablePutSpecialTagsSetWithComment(ctx, SPECIAL_SCOPE_DEF, vkey, value, CF_DATA_TYPE_STRING, tags, comment); } } else { Log(LOG_LEVEL_VERBOSE, "Installing augments variable '%s=%s' from file '%s'", vkey, value, filename); if (CanSetVariable(ctx, ref)) { installed = EvalContextVariablePutTagsSetWithComment(ctx, ref, value, CF_DATA_TYPE_STRING, tags, comment); } } free(value); } else if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_CONTAINER && JsonGetContainerType(data) == JSON_CONTAINER_TYPE_ARRAY && JsonArrayContainsOnlyPrimitives((JsonElement *) data)) { // map to slist if the data only has primitives Rlist *data_as_rlist = RlistFromContainer(data); if ((ref->ns == NULL) && (ref->scope == NULL)) { Log(LOG_LEVEL_VERBOSE, "Installing augments slist variable '%s.%s' from file '%s'", SpecialScopeToString(SPECIAL_SCOPE_DEF), vkey, filename); if (CanSetVariable(ctx, ref)) { installed = EvalContextVariablePutSpecialTagsSetWithComment(ctx, SPECIAL_SCOPE_DEF, vkey, data_as_rlist, CF_DATA_TYPE_STRING_LIST, tags, comment); } } else { Log(LOG_LEVEL_VERBOSE, "Installing augments slist variable '%s' from file '%s'", vkey, filename); if (CanSetVariable(ctx, ref)) { installed = EvalContextVariablePutTagsSetWithComment(ctx, ref, data_as_rlist, CF_DATA_TYPE_STRING_LIST, tags, comment); } } RlistDestroy(data_as_rlist); } else // install as a data container { if ((ref->ns == NULL) && (ref->scope == NULL)) { Log(LOG_LEVEL_VERBOSE, "Installing augments data container variable '%s.%s' from file '%s'", SpecialScopeToString(SPECIAL_SCOPE_DEF), vkey, filename); if (CanSetVariable(ctx, ref)) { installed = EvalContextVariablePutSpecialTagsSetWithComment(ctx, SPECIAL_SCOPE_DEF, vkey, data, CF_DATA_TYPE_CONTAINER, tags, comment); } } else { Log(LOG_LEVEL_VERBOSE, "Installing augments data container variable '%s' from file '%s'", vkey, filename); if (CanSetVariable(ctx, ref)) { installed = EvalContextVariablePutTagsSetWithComment(ctx, ref, data, CF_DATA_TYPE_CONTAINER, tags, comment); } } } VarRefDestroy(ref); if (!installed) { /* EvalContextVariablePutTagsSetWithComment() and * EvalContextVariablePutSpecialTagsSetWithComment() take * over tags in case of success. Otherwise we have to * destroy the set. */ StringSetDestroy(tags); } } variables_cleanup: JsonDestroy(variables); } /* load classes (if any) */ element = JsonObjectGet(augment, "classes"); if (JSON_NOT_NULL(element)) { JsonElement* classes = JsonExpandElement(ctx, element); if (JsonGetElementType(classes) != JSON_ELEMENT_TYPE_CONTAINER || JsonGetContainerType(classes) != JSON_CONTAINER_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid augments classes in '%s', must be a JSON object", filename); goto classes_cleanup; } const char default_tags[] = "source=augments_file"; JsonIterator iter = JsonIteratorInit(classes); const char *ckey; while ((ckey = JsonIteratorNextKey(&iter))) { JsonElement *data = JsonObjectGet(classes, ckey); if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_PRIMITIVE) { char *check = JsonPrimitiveToString(data); // check if class is true if (CheckContextClassmatch(ctx, check)) { Log(LOG_LEVEL_VERBOSE, "Installing augments class '%s' (checked '%s') from file '%s'", ckey, check, filename); if (CanSetClass(ctx, ckey)) { EvalContextClassPutSoft(ctx, ckey, CONTEXT_SCOPE_NAMESPACE, default_tags); } } free(check); } else if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_CONTAINER && JsonGetContainerType(data) == JSON_CONTAINER_TYPE_ARRAY && JsonArrayContainsOnlyPrimitives(data)) { // check if each class is true JsonIterator data_iter = JsonIteratorInit(data); const JsonElement *el; while ((el = JsonIteratorNextValueByType(&data_iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { char *check = JsonPrimitiveToString(el); if (CheckContextClassmatch(ctx, check)) { Log(LOG_LEVEL_VERBOSE, "Installing augments class '%s' (checked array entry '%s') from file '%s'", ckey, check, filename); if (CanSetClass(ctx, ckey)) { EvalContextClassPutSoft(ctx, ckey, CONTEXT_SCOPE_NAMESPACE, default_tags); } free(check); break; } free(check); } } else if (JsonGetType(data) == JSON_TYPE_OBJECT) { const JsonElement *class_exprs = JsonObjectGet(data, AUGMENTS_CLASSES_CLASS_EXPRESSIONS); const JsonElement *reg_exprs = JsonObjectGet(data, AUGMENTS_CLASSES_REGULAR_EXPRESSIONS); const JsonElement *json_tags = JsonObjectGet(data, AUGMENTS_CLASSES_TAGS); if ((JSON_NOT_NULL(class_exprs) && JSON_NOT_NULL(reg_exprs)) || (NULL_JSON(class_exprs) && NULL_JSON(reg_exprs))) { Log(LOG_LEVEL_ERR, "Invalid augments class data for class '%s' in '%s':" " either \"class_expressions\" or \"regular_expressions\" need to be specified", ckey, filename); continue; } StringSet *tags = GetTagsFromAugmentsTags("class", ckey, json_tags, "source=augments_file", filename); const char *comment = GetAugmentsComment("class", ckey, filename, data); bool installed = false; JsonIterator exprs_iter = JsonIteratorInit(class_exprs ? class_exprs : reg_exprs); const JsonElement *el; while ((el = JsonIteratorNextValueByType(&exprs_iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { char *check = JsonPrimitiveToString(el); if (CheckContextClassmatch(ctx, check)) { Log(LOG_LEVEL_VERBOSE, "Installing augments class '%s' (checked array entry '%s') from file '%s'", ckey, check, filename); if (CanSetClass(ctx, ckey)) { installed = EvalContextClassPutSoftTagsSetWithComment(ctx, ckey, CONTEXT_SCOPE_NAMESPACE, tags, comment); } free(check); break; } free(check); } if (!installed) { /* EvalContextClassPutSoftTagsSetWithComment() takes over tags in * case of success. Otherwise we have to destroy the set. */ StringSetDestroy(tags); } } else { Log(LOG_LEVEL_ERR, "Invalid augments class data for class '%s' in '%s'", ckey, filename); } } classes_cleanup: JsonDestroy(classes); } /* load inputs (if any) */ element = JsonObjectGet(augment, "inputs"); if (JSON_NOT_NULL(element)) { JsonElement* inputs = JsonExpandElement(ctx, element); if (JsonGetElementType(inputs) == JSON_ELEMENT_TYPE_CONTAINER && JsonGetContainerType(inputs) == JSON_CONTAINER_TYPE_ARRAY && JsonArrayContainsOnlyPrimitives(inputs)) { Log(LOG_LEVEL_VERBOSE, "Installing augments def.augments_inputs from file '%s'", filename); Rlist *rlist = RlistFromContainer(inputs); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_DEF, "augments_inputs", rlist, CF_DATA_TYPE_STRING_LIST, "source=augments_file"); RlistDestroy(rlist); } else { Log(LOG_LEVEL_ERR, "Trying to augment inputs in '%s' but the value was not a list of strings", filename); } JsonDestroy(inputs); } /* load further def.json files (if any) */ element = JsonObjectGet(augment, "augments"); if (JSON_NOT_NULL(element)) { JsonElement* further_augments = element; assert(further_augments != NULL); if (JsonGetElementType(further_augments) == JSON_ELEMENT_TYPE_CONTAINER && JsonGetContainerType(further_augments) == JSON_CONTAINER_TYPE_ARRAY && JsonArrayContainsOnlyPrimitives(further_augments)) { JsonIterator iter = JsonIteratorInit(further_augments); const JsonElement *el; while ((el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true)) != NULL) { char *nested_filename = JsonPrimitiveToString(el); bool further_loaded = LoadAugmentsFiles(ctx, nested_filename); if (further_loaded) { Log(LOG_LEVEL_VERBOSE, "Completed augmenting from file '%s'", nested_filename); } else { Log(LOG_LEVEL_ERR, "Could not load requested further augments from file '%s'", nested_filename); } free(nested_filename); } } else { Log(LOG_LEVEL_ERR, "Trying to augment inputs in '%s' but the value was not a list of strings", filename); } } } return loaded; } static bool LoadAugmentsFiles(EvalContext *ctx, const char *unexpanded_filename) { bool loaded = false; char *filename = ExpandScalar(ctx, NULL, "this", unexpanded_filename, NULL); if (strstr(filename, "/.json")) { Log(LOG_LEVEL_DEBUG, "Skipping augments file '%s' because it failed to expand the base filename, resulting in '%s'", unexpanded_filename, filename); } else { Log(LOG_LEVEL_DEBUG, "Searching for augments file '%s' (original '%s')", filename, unexpanded_filename); if (FileCanOpen(filename, "r")) { // 5 MB should be enough for most reasonable def.json data JsonElement* augment = ReadJsonFile(filename, LOG_LEVEL_ERR, 5 * 1024 * 1024); if (augment != NULL) { loaded = LoadAugmentsData(ctx, filename, augment); JsonDestroy(augment); } } else { Log(LOG_LEVEL_VERBOSE, "could not load JSON augments from '%s'", filename); } } free(filename); return loaded; } static bool IsFile(const char *const filename) { struct stat buffer; if (stat(filename, &buffer) != 0) { return false; } if (S_ISREG(buffer.st_mode) != 0) { return true; } return false; } void LoadAugments(EvalContext *ctx, GenericAgentConfig *config) { assert(config != NULL); char* def_json = NULL; // --ignore-preferred-augments command line option: if (config->ignore_preferred_augments) { EvalContextClassPutHard(ctx, "ignore_preferred_augments", "source=command_line_option"); // def_json is NULL so it will be assigned below } else { def_json = StringFormat("%s%c%s", config->input_dir, FILE_SEPARATOR, "def_preferred.json"); if (!IsFile(def_json)) { // def_preferred.json does not exist or we cannot read it FREE_AND_NULL(def_json); } } if (def_json == NULL) { // No def_preferred.json, either because the feature is disabled // or we could not read the file. // Fall back to old / default behavior, using def.json: def_json = StringFormat("%s%c%s", config->input_dir, FILE_SEPARATOR, "def.json"); } Log(LOG_LEVEL_VERBOSE, "Loading JSON augments from '%s' (input dir '%s', input file '%s'", def_json, config->input_dir, config->input_file); LoadAugmentsFiles(ctx, def_json); free(def_json); } static void AddPolicyEntryVariables (EvalContext *ctx, const GenericAgentConfig *config) { char *abs_input_path = GetAbsolutePath(config->input_file); /* both dirname() and basename() may actually modify the string they are given (see man:basename(3)) */ char *dirname_path = xstrdup(abs_input_path); char *basename_path = xstrdup(abs_input_path); EvalContextSetEntryPoint(ctx, abs_input_path); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "policy_entry_filename", abs_input_path, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "policy_entry_dirname", dirname(dirname_path), CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "policy_entry_basename", basename(basename_path), CF_DATA_TYPE_STRING, "source=agent"); free(abs_input_path); free(dirname_path); free(basename_path); } void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config, const char *program_name) { assert(config != NULL); strcpy(VPREFIX, ""); if (program_name != NULL) { strncpy(CF_PROGRAM_NAME, program_name, sizeof(CF_PROGRAM_NAME) - 1); } Log(LOG_LEVEL_VERBOSE, " %s", NameVersion()); Banner("Initialization preamble"); GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN); GenericAgentInitialize(ctx, config); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); SanitizeEnvironment(); THIS_AGENT_TYPE = config->agent_type; LoggingSetAgentType(CF_AGENTTYPES[config->agent_type]); EvalContextClassPutHard(ctx, CF_AGENTTYPES[config->agent_type], "cfe_internal,source=agent"); DetectEnvironment(ctx); AddPolicyEntryVariables(ctx, config); EvalContextHeapPersistentLoadAll(ctx); LoadSystemConstants(ctx); const char *bootstrap_arg = config->agent_specific.agent.bootstrap_argument; const char *bootstrap_ip = config->agent_specific.agent.bootstrap_ip; /* Are we bootstrapping the agent? */ if (config->agent_type == AGENT_TYPE_AGENT && bootstrap_arg != NULL) { EvalContextClassPutHard(ctx, "bootstrap_mode", "report,source=environment"); if (!config->agent_specific.agent.bootstrap_trigger_policy) { EvalContextClassPutHard(ctx, "skip_policy_on_bootstrap", "report,source=environment"); } if (!RemoveAllExistingPolicyInInputs(GetInputDir())) { Log(LOG_LEVEL_ERR, "Error removing existing input files prior to bootstrap"); DoCleanupAndExit(EXIT_FAILURE); } if (!WriteBuiltinFailsafePolicy(GetInputDir())) { Log(LOG_LEVEL_ERR, "Error writing builtin failsafe to inputs prior to bootstrap"); DoCleanupAndExit(EXIT_FAILURE); } GenericAgentConfigSetInputFile(config, GetInputDir(), "failsafe.cf"); char canonified_ipaddr[strlen(bootstrap_ip) + 1]; StringCanonify(canonified_ipaddr, bootstrap_ip); bool am_policy_server = EvalContextClassGet(ctx, NULL, canonified_ipaddr) != NULL; if (am_policy_server) { Log(LOG_LEVEL_INFO, "Assuming role as policy server," " with policy distribution point at: %s", GetMasterDir()); MarkAsPolicyServer(ctx); // Sets policy_server class SetCFEngineRoles(ctx); // Checks policy_server class if (!MasterfileExists(GetMasterDir())) { Log(LOG_LEVEL_ERR, "In order to bootstrap as a policy server," " the file '%s/promises.cf' must exist.", GetMasterDir()); DoCleanupAndExit(EXIT_FAILURE); } CheckAndSetHAState(GetWorkDir(), ctx); } else { Log(LOG_LEVEL_INFO, "Assuming role as regular client," " bootstrapping to policy server: %s", bootstrap_arg); // Once we have set, or in this case not set, // the policy_server class, we can set roles: SetCFEngineRoles(ctx); if (config->agent_specific.agent.bootstrap_trust_server) { EvalContextClassPutHard(ctx, "trust_server", "source=agent"); Log(LOG_LEVEL_NOTICE, "Bootstrap mode: implicitly trusting server, " "use --trust-server=no if server trust is already established"); } } WriteAmPolicyHubFile(am_policy_server); PolicyServerWriteFile(GetWorkDir(), bootstrap_arg); EvalContextSetPolicyServer(ctx, bootstrap_arg); char *const bootstrap_id = CreateBootstrapIDFile(GetWorkDir()); if (bootstrap_id != NULL) { EvalContextSetBootstrapID(ctx, bootstrap_id); free(bootstrap_id); } /* FIXME: Why it is called here? Can't we move both invocations to before if? */ UpdateLastPolicyUpdateTime(ctx); } else { char *existing_policy_server = PolicyServerReadFile(GetWorkDir()); if (existing_policy_server) { Log(LOG_LEVEL_VERBOSE, "This agent is bootstrapped to: %s", existing_policy_server); EvalContextSetPolicyServer(ctx, existing_policy_server); char *const bootstrap_id = ReadBootstrapIDFile(GetWorkDir()); if (bootstrap_id != NULL) { EvalContextSetBootstrapID(ctx, bootstrap_id); free(bootstrap_id); } free(existing_policy_server); UpdateLastPolicyUpdateTime(ctx); if (GetAmPolicyHub()) { // Hub: MarkAsPolicyServer(ctx); // Sets policy_server class SetCFEngineRoles(ctx); // Checks policy_server class /* Should this go in MarkAsPolicyServer() ? */ CheckAndSetHAState(GetWorkDir(), ctx); } else { // Client, set appropriate role: SetCFEngineRoles(ctx); } } else { Log(LOG_LEVEL_VERBOSE, "This agent is not bootstrapped -" " can't find policy_server.dat in: %s", GetWorkDir()); } } /* Load CMDB data *before* augments. */ if (!config->agent_specific.common.no_host_specific && !LoadCMDBData(ctx)) { Log(LOG_LEVEL_ERR, "Failed to load CMDB data"); } if (!config->agent_specific.common.no_augments) { /* load augments here so that they can make use of the classes added above * (especially 'am_policy_hub' and 'policy_server') */ LoadAugments(ctx, config); } } static bool IsPolicyPrecheckNeeded(GenericAgentConfig *config, bool force_validation) { bool check_policy = false; if (IsFileOutsideDefaultRepository(config->input_file)) { check_policy = true; Log(LOG_LEVEL_VERBOSE, "Input file is outside default repository, validating it"); } if (GenericAgentIsPolicyReloadNeeded(config)) { check_policy = true; Log(LOG_LEVEL_VERBOSE, "Input file is changed since last validation, validating it"); } if (force_validation) { check_policy = true; Log(LOG_LEVEL_VERBOSE, "always_validate is set, forcing policy validation"); } return check_policy; } bool GenericAgentCheckPolicy(GenericAgentConfig *config, bool force_validation, bool write_validated_file) { if (!MissingInputFile(config->input_file)) { { if (config->agent_type == AGENT_TYPE_SERVER || config->agent_type == AGENT_TYPE_MONITOR || config->agent_type == AGENT_TYPE_EXECUTOR) { time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL); config->agent_specific.daemon.last_validated_at = validated_at; } } if (IsPolicyPrecheckNeeded(config, force_validation)) { bool policy_check_ok = GenericAgentArePromisesValid(config); if (policy_check_ok && write_validated_file) { GenericAgentTagReleaseDirectory(config, NULL, // use GetAutotagDir write_validated_file, // true GetAmPolicyHub()); // write release ID? } if (config->agent_specific.agent.bootstrap_argument && !policy_check_ok) { Log(LOG_LEVEL_VERBOSE, "Policy is not valid, but proceeding with bootstrap"); return true; } return policy_check_ok; } else { Log(LOG_LEVEL_VERBOSE, "Policy is already validated"); return true; } } return false; } static JsonElement *ReadPolicyValidatedFile(const char *filename) { bool missing = true; struct stat sb; if (stat(filename, &sb) != -1) { missing = false; } JsonElement *validated_doc = ReadJsonFile(filename, LOG_LEVEL_DEBUG, 5 * 1024 * 1024); if (validated_doc == NULL) { Log(missing ? LOG_LEVEL_DEBUG : LOG_LEVEL_VERBOSE, "Could not parse policy_validated JSON file '%s', using dummy data", filename); validated_doc = JsonObjectCreate(2); if (missing) { JsonObjectAppendInteger(validated_doc, "timestamp", 0); } else { JsonObjectAppendInteger(validated_doc, "timestamp", sb.st_mtime); } } return validated_doc; } static JsonElement *ReadPolicyValidatedFileFromMasterfiles(const GenericAgentConfig *config, const char *maybe_dirname) { char filename[CF_MAXVARSIZE]; GetPromisesValidatedFile(filename, sizeof(filename), config, maybe_dirname); return ReadPolicyValidatedFile(filename); } /** * @brief Writes a file with a contained timestamp to mark a policy file as validated * @param filename the filename * @return True if successful. */ static bool WritePolicyValidatedFile(ARG_UNUSED const GenericAgentConfig *config, const char *filename) { if (!MakeParentDirectory(filename, true, NULL)) { Log(LOG_LEVEL_ERR, "Could not write policy validated marker file: %s", filename); return false; } int fd = creat(filename, CF_PERMS_DEFAULT); if (fd == -1) { Log(LOG_LEVEL_ERR, "While writing policy validated marker file '%s', could not create file (create: %s)", filename, GetErrorStr()); return false; } JsonElement *info = JsonObjectCreate(3); JsonObjectAppendInteger(info, "timestamp", time(NULL)); Writer *w = FileWriter(fdopen(fd, "w")); JsonWrite(w, info, 0); WriterClose(w); JsonDestroy(info); Log(LOG_LEVEL_VERBOSE, "Saved policy validated marker file '%s'", filename); return true; } /** * @brief Writes the policy validation file and release ID to a directory * @return True if successful. */ bool GenericAgentTagReleaseDirectory(const GenericAgentConfig *config, const char *dirname, bool write_validated, bool write_release) { char local_dirname[PATH_MAX + 1]; if (dirname == NULL) { GetAutotagDir(local_dirname, PATH_MAX, NULL); dirname = local_dirname; } char filename[CF_MAXVARSIZE]; char git_checksum[GENERIC_AGENT_CHECKSUM_SIZE]; bool have_git_checksum = GeneratePolicyReleaseIDFromGit(git_checksum, sizeof(git_checksum), dirname); Log(LOG_LEVEL_DEBUG, "Tagging directory %s for release (write_validated: %s, write_release: %s)", dirname, write_validated ? "yes" : "no", write_release ? "yes" : "no"); if (write_release) { // first, tag the release ID GetReleaseIdFile(dirname, filename, sizeof(filename)); char *id = ReadReleaseIdFromReleaseIdFileMasterfiles(dirname); if (id == NULL || (have_git_checksum && strcmp(id, git_checksum) != 0)) { if (id == NULL) { Log(LOG_LEVEL_DEBUG, "The release_id of %s was missing", dirname); } else { Log(LOG_LEVEL_DEBUG, "The release_id of %s needs to be updated", dirname); } bool wrote_release = WriteReleaseIdFile(filename, dirname); if (!wrote_release) { Log(LOG_LEVEL_VERBOSE, "The release_id file %s was NOT updated", filename); free(id); return false; } else { Log(LOG_LEVEL_DEBUG, "The release_id file %s was updated", filename); } } free(id); } // now, tag the promises_validated if (write_validated) { Log(LOG_LEVEL_DEBUG, "Tagging directory %s for validation", dirname); GetPromisesValidatedFile(filename, sizeof(filename), config, dirname); bool wrote_validated = WritePolicyValidatedFile(config, filename); if (!wrote_validated) { Log(LOG_LEVEL_VERBOSE, "The promises_validated file %s was NOT updated", filename); return false; } Log(LOG_LEVEL_DEBUG, "The promises_validated file %s was updated", filename); return true; } return true; } /** * @brief Writes a file with a contained release ID based on git SHA, * or file checksum if git SHA is not available. * @param filename the release_id file * @param dirname the directory to checksum or get the Git hash * @return True if successful */ static bool WriteReleaseIdFile(const char *filename, const char *dirname) { char release_id[GENERIC_AGENT_CHECKSUM_SIZE]; bool have_release_id = GeneratePolicyReleaseID(release_id, sizeof(release_id), dirname); if (!have_release_id) { return false; } int fd = creat(filename, CF_PERMS_DEFAULT); if (fd == -1) { Log(LOG_LEVEL_ERR, "While writing policy release ID file '%s', could not create file (create: %s)", filename, GetErrorStr()); return false; } JsonElement *info = JsonObjectCreate(3); JsonObjectAppendString(info, "releaseId", release_id); Writer *w = FileWriter(fdopen(fd, "w")); JsonWrite(w, info, 0); WriterClose(w); JsonDestroy(info); Log(LOG_LEVEL_VERBOSE, "Saved policy release ID file '%s'", filename); return true; } bool GenericAgentArePromisesValid(const GenericAgentConfig *config) { assert(config != NULL); char cmd[CF_BUFSIZE]; const char* const bindir = GetBinDir(); Log(LOG_LEVEL_VERBOSE, "Verifying the syntax of the inputs..."); { char cfpromises[CF_MAXVARSIZE]; snprintf(cfpromises, sizeof(cfpromises), "%s%ccf-promises%s", bindir, FILE_SEPARATOR, EXEC_SUFFIX); struct stat sb; if (stat(cfpromises, &sb) == -1) { Log(LOG_LEVEL_ERR, "cf-promises%s needs to be installed in %s for pre-validation of full configuration", EXEC_SUFFIX, bindir); return false; } if (config->bundlesequence) { snprintf(cmd, sizeof(cmd), "\"%s\" \"", cfpromises); } else { snprintf(cmd, sizeof(cmd), "\"%s\" -c \"", cfpromises); } } strlcat(cmd, config->input_file, CF_BUFSIZE); strlcat(cmd, "\"", CF_BUFSIZE); if (config->bundlesequence) { strlcat(cmd, " -b \"", CF_BUFSIZE); for (const Rlist *rp = config->bundlesequence; rp; rp = rp->next) { const char *bundle_ref = RlistScalarValue(rp); strlcat(cmd, bundle_ref, CF_BUFSIZE); if (rp->next) { strlcat(cmd, ",", CF_BUFSIZE); } } strlcat(cmd, "\"", CF_BUFSIZE); } if (config->ignore_preferred_augments) { strlcat(cmd, " --ignore-preferred-augments", CF_BUFSIZE); } Log(LOG_LEVEL_VERBOSE, "Checking policy with command '%s'", cmd); if (!ShellCommandReturnsZero(cmd, true)) { Log(LOG_LEVEL_ERR, "Policy failed validation with command '%s'", cmd); return false; } return true; } /*****************************************************************************/ #if !defined(__MINGW32__) static void OpenLog(int facility) { openlog(CF_PROGRAM_NAME, LOG_PID | LOG_NOWAIT | LOG_ODELAY, facility); } #endif /*****************************************************************************/ #if !defined(__MINGW32__) void CloseLog(void) { closelog(); } #endif ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, GenericAgentAddEditionClasses, EvalContext *, ctx) { EvalContextClassPutHard(ctx, "community_edition", "inventory,attribute_name=none,source=agent"); } static int GetDefaultLogFacility() { char log_facility_file[PATH_MAX]; NDEBUG_UNUSED int written = snprintf(log_facility_file, sizeof(log_facility_file) - 1, "%s%c%s_log_facility.dat", GetStateDir(), FILE_SEPARATOR, CF_PROGRAM_NAME); assert(written < PATH_MAX); if (access(log_facility_file, R_OK) != 0) { return LOG_USER; } FILE *f = fopen(log_facility_file, "r"); if (f == NULL) { return LOG_USER; } char facility_str[16] = {0}; /* at most "LOG_DAEMON\n" */ size_t n_read = fread(facility_str, 1, sizeof(facility_str) - 1, f); fclose(f); if (n_read == 0) { return LOG_USER; } if (facility_str[n_read - 1] == '\n') { facility_str[n_read - 1] = '\0'; } return ParseFacility(facility_str); } static bool StoreDefaultLogFacility() { char log_facility_file[PATH_MAX]; NDEBUG_UNUSED int written = snprintf(log_facility_file, sizeof(log_facility_file) - 1, "%s%c%s_log_facility.dat", GetStateDir(), FILE_SEPARATOR, CF_PROGRAM_NAME); assert(written < PATH_MAX); FILE *f = fopen(log_facility_file, "w"); if (f == NULL) { return false; } const char *facility_str = LogFacilityToString(GetSyslogFacility()); NDEBUG_UNUSED int printed = fprintf(f, "%s\n", facility_str); assert(printed > 0); fclose(f); return true; } void GenericAgentInitialize(EvalContext *ctx, GenericAgentConfig *config) { int force = false; struct stat statbuf, sb; char vbuff[CF_BUFSIZE]; char ebuff[CF_EXPANDSIZE]; #ifdef __MINGW32__ InitializeWindows(); #endif /* Set output to line-buffered to avoid truncated debug logs. */ /* Bug on HP-UX: Buffered output is discarded if you switch buffering mode without flushing the buffered output first. This will happen anyway when switching modes, so no performance is lost. */ fflush(stdout); #ifndef SUNOS_5 setlinebuf(stdout); #else /* CFE-2527: On Solaris we avoid calling setlinebuf, since fprintf() on Solaris 10 and 11 truncates output under certain conditions. We fully disable buffering to avoid truncated debug logs; performance impact should be minimal because we mostly write full lines anyway. */ setvbuf(stdout, NULL, _IONBF, 0); #endif DetermineCfenginePort(); int default_facility = GetDefaultLogFacility(); OpenLog(default_facility); SetSyslogFacility(default_facility); EvalContextClassPutHard(ctx, "any", "source=agent"); GenericAgentAddEditionClasses(ctx); /* Make sure the chroot for recording changes this process would normally * make on the system is setup if that was requested. */ if (ChrootChanges()) { char changes_chroot[PATH_MAX] = {0}; GetChangesChrootDir(changes_chroot, sizeof(changes_chroot)); SetChangesChroot(changes_chroot); RegisterCleanupFunction(DeleteChangesChroot); Log(LOG_LEVEL_WARNING, "All changes in files will be made in the '%s' chroot", changes_chroot); } /* Define trusted directories */ const char *workdir = GetWorkDir(); const char *bindir = GetBinDir(); if (!workdir) { FatalError(ctx, "Error determining working directory"); } Log(LOG_LEVEL_VERBOSE, "Work directory is %s", workdir); snprintf(vbuff, CF_BUFSIZE, "%s%cupdate.conf", GetInputDir(), FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s%ccf-agent", bindir, FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s%coutputs%cspooled_reports", workdir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s%clastseen%cintermittencies", workdir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s%creports%cvarious", workdir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s%c.", GetLogDir(), FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s%c.", GetPidDir(), FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s%c.", GetStateDir(), FILE_SEPARATOR); MakeParentInternalDirectory(vbuff, force, NULL); MakeParentInternalDirectory(GetLogDir(), force, NULL); snprintf(vbuff, CF_BUFSIZE, "%s", GetInputDir()); if (stat(vbuff, &sb) == -1) { FatalError(ctx, " No access to WORKSPACE/inputs dir"); } /* ensure WORKSPACE/inputs directory has all user bits set (u+rwx) */ if ((sb.st_mode & 0700) != 0700) { chmod(vbuff, sb.st_mode | 0700); } snprintf(vbuff, CF_BUFSIZE, "%s%coutputs", workdir, FILE_SEPARATOR); if (stat(vbuff, &sb) == -1) { FatalError(ctx, " No access to WORKSPACE/outputs dir"); } /* ensure WORKSPACE/outputs directory has all user bits set (u+rwx) */ if ((sb.st_mode & 0700) != 0700) { chmod(vbuff, sb.st_mode | 0700); } const char* const statedir = GetStateDir(); snprintf(ebuff, sizeof(ebuff), "%s%ccf_procs", statedir, FILE_SEPARATOR); MakeParentDirectory(ebuff, force, NULL); if (stat(ebuff, &statbuf) == -1) { CreateEmptyFile(ebuff); } snprintf(ebuff, sizeof(ebuff), "%s%ccf_rootprocs", statedir, FILE_SEPARATOR); if (stat(ebuff, &statbuf) == -1) { CreateEmptyFile(ebuff); } snprintf(ebuff, sizeof(ebuff), "%s%ccf_otherprocs", statedir, FILE_SEPARATOR); if (stat(ebuff, &statbuf) == -1) { CreateEmptyFile(ebuff); } snprintf(ebuff, sizeof(ebuff), "%s%cprevious_state%c", statedir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentDirectory(ebuff, force, NULL); snprintf(ebuff, sizeof(ebuff), "%s%cdiff%c", statedir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentDirectory(ebuff, force, NULL); snprintf(ebuff, sizeof(ebuff), "%s%cuntracked%c", statedir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentDirectory(ebuff, force, NULL); OpenNetwork(); CryptoInitialize(); CheckWorkingDirectories(ctx); /* Initialize keys and networking. cf-key, doesn't need keys. In fact it must function properly even without them, so that it generates them! */ if (config->agent_type != AGENT_TYPE_KEYGEN) { LoadSecretKeys(NULL, NULL, NULL, NULL); char *ipaddr = NULL, *port = NULL; PolicyServerLookUpFile(workdir, &ipaddr, &port); PolicyHubUpdateKeys(ipaddr); free(ipaddr); free(port); } size_t cwd_size = PATH_MAX; while (true) { char cwd[cwd_size]; if (!getcwd(cwd, cwd_size)) { if (errno == ERANGE) { cwd_size *= 2; continue; } else { Log(LOG_LEVEL_WARNING, "Could not determine current directory (getcwd: %s)", GetErrorStr()); break; } } EvalContextSetLaunchDirectory(ctx, cwd); break; } if (!MINUSF) { GenericAgentConfigSetInputFile(config, GetInputDir(), "promises.cf"); } } static void GetChangesChrootDir(char *buf, size_t buf_size) { snprintf(buf, buf_size, "%s/%ju.changes", GetStateDir(), (uintmax_t) getpid()); } static void DeleteChangesChroot() { char changes_chroot[PATH_MAX] = {0}; GetChangesChrootDir(changes_chroot, sizeof(changes_chroot)); Log(LOG_LEVEL_VERBOSE, "Deleting changes chroot '%s'", changes_chroot); DeleteDirectoryTree(changes_chroot); /* DeleteDirectoryTree() doesn't delete the root of the tree. */ if (rmdir(changes_chroot) != 0) { Log(LOG_LEVEL_ERR, "Failed to delete changes chroot '%s'", changes_chroot); } } void GenericAgentFinalize(EvalContext *ctx, GenericAgentConfig *config) { /* TODO, FIXME: what else from the above do we need to undo here ? */ if (config->agent_type != AGENT_TYPE_KEYGEN) { cfnet_shut(); } CryptoDeInitialize(); GenericAgentConfigDestroy(config); EvalContextDestroy(ctx); } static bool MissingInputFile(const char *input_file) { struct stat sb; if (stat(input_file, &sb) == -1) { Log(LOG_LEVEL_ERR, "There is no readable input file at '%s'. (stat: %s)", input_file, GetErrorStr()); return true; } return false; } // Git only. static bool GeneratePolicyReleaseIDFromGit(char *release_id_out, #ifdef NDEBUG /* out_size is only used in an assertion */ ARG_UNUSED #endif size_t out_size, const char *policy_dir) { char git_filename[PATH_MAX + 1]; snprintf(git_filename, PATH_MAX, "%s/.git/HEAD", policy_dir); MapName(git_filename); // Note: Probably we should not be reading all of these filenames directly, // and should instead use git plumbing commands to retrieve the data. FILE *git_file = safe_fopen(git_filename, "r"); if (git_file) { char git_head[128]; int scanned = fscanf(git_file, "ref: %127s", git_head); if (scanned == 1) // Found HEAD Reference which means we are on a checked out branch { fclose(git_file); snprintf(git_filename, PATH_MAX, "%s/.git/%s", policy_dir, git_head); git_file = safe_fopen(git_filename, "r"); Log(LOG_LEVEL_DEBUG, "Found a git HEAD ref"); } else { Log(LOG_LEVEL_DEBUG, "Unable to find HEAD ref in '%s', looking for commit instead", git_filename); assert(out_size > 40); fseek(git_file, 0, SEEK_SET); scanned = fscanf(git_file, "%40s", release_id_out); fclose(git_file); if (scanned == 1) { Log(LOG_LEVEL_DEBUG, "Found current git checkout pointing to: %s", release_id_out); return true; } else { /* We didn't find a commit sha in .git/HEAD, so we assume the * git information is invalid. */ git_file = NULL; } } if (git_file) { assert(out_size > 40); scanned = fscanf(git_file, "%40s", release_id_out); fclose(git_file); return scanned == 1; } else { Log(LOG_LEVEL_DEBUG, "While generating policy release ID, found git head ref '%s', but unable to open (errno: %s)", policy_dir, GetErrorStr()); } } else { Log(LOG_LEVEL_DEBUG, "While generating policy release ID, directory is '%s' not a git repository", policy_dir); } return false; } static bool GeneratePolicyReleaseIDFromTree(char *release_id_out, size_t out_size, const char *policy_dir) { if (access(policy_dir, R_OK) != 0) { Log(LOG_LEVEL_ERR, "Cannot access policy directory '%s' to generate release ID", policy_dir); return false; } // fallback, produce some pseudo sha1 hash const EVP_MD *const md = HashDigestFromId(GENERIC_AGENT_CHECKSUM_METHOD); if (md == NULL) { Log(LOG_LEVEL_ERR, "Could not determine function for file hashing"); return false; } EVP_MD_CTX *crypto_ctx = EVP_MD_CTX_new(); if (crypto_ctx == NULL) { Log(LOG_LEVEL_ERR, "Could not allocate openssl hash context"); return false; } EVP_DigestInit(crypto_ctx, md); bool success = HashDirectoryTree(policy_dir, (const char *[]) { ".cf", ".dat", ".txt", ".conf", ".mustache", ".json", ".yaml", NULL}, crypto_ctx); int md_len; unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 }; EVP_DigestFinal(crypto_ctx, digest, &md_len); EVP_MD_CTX_free(crypto_ctx); HashPrintSafe(release_id_out, out_size, digest, GENERIC_AGENT_CHECKSUM_METHOD, false); return success; } static bool GeneratePolicyReleaseID(char *release_id_out, size_t out_size, const char *policy_dir) { if (GeneratePolicyReleaseIDFromGit(release_id_out, out_size, policy_dir)) { return true; } return GeneratePolicyReleaseIDFromTree(release_id_out, out_size, policy_dir); } /** * @brief Gets the promises_validated file name depending on context and options */ static void GetPromisesValidatedFile(char *filename, size_t max_size, const GenericAgentConfig *config, const char *maybe_dirname) { char dirname[max_size]; /* TODO overflow error checking! */ GetAutotagDir(dirname, max_size, maybe_dirname); if (maybe_dirname == NULL && MINUSF) { snprintf(filename, max_size, "%s/validated_%s", dirname, CanonifyName(config->original_input_file)); } else { snprintf(filename, max_size, "%s/cf_promises_validated", dirname); } MapName(filename); } /** * @brief Gets the promises_validated file name depending on context and options */ static void GetAutotagDir(char *dirname, size_t max_size, const char *maybe_dirname) { if (maybe_dirname != NULL) { strlcpy(dirname, maybe_dirname, max_size); } else if (MINUSF) { strlcpy(dirname, GetStateDir(), max_size); } else { strlcpy(dirname, GetMasterDir(), max_size); } MapName(dirname); } /** * @brief Gets the release_id file name in the given base_path. */ void GetReleaseIdFile(const char *base_path, char *filename, size_t max_size) { snprintf(filename, max_size, "%s/cf_promises_release_id", base_path); MapName(filename); } static JsonElement *ReadReleaseIdFileFromMasterfiles(const char *maybe_dirname) { char filename[CF_MAXVARSIZE]; GetReleaseIdFile((maybe_dirname == NULL) ? GetMasterDir() : maybe_dirname, filename, sizeof(filename)); JsonElement *doc = ReadJsonFile(filename, LOG_LEVEL_DEBUG, 5 * 1024 * 1024); if (doc == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not parse release_id JSON file %s", filename); } return doc; } static char* ReadReleaseIdFromReleaseIdFileMasterfiles(const char *maybe_dirname) { JsonElement *doc = ReadReleaseIdFileFromMasterfiles(maybe_dirname); char *id = NULL; if (doc) { JsonElement *jid = JsonObjectGet(doc, "releaseId"); if (jid) { id = xstrdup(JsonPrimitiveGetAsString(jid)); } JsonDestroy(doc); } return id; } // TODO: refactor Read*FromPolicyValidatedMasterfiles time_t ReadTimestampFromPolicyValidatedFile(const GenericAgentConfig *config, const char *maybe_dirname) { time_t validated_at = 0; { JsonElement *validated_doc = ReadPolicyValidatedFileFromMasterfiles(config, maybe_dirname); if (validated_doc) { JsonElement *timestamp = JsonObjectGet(validated_doc, "timestamp"); if (timestamp) { validated_at = JsonPrimitiveGetAsInteger(timestamp); } JsonDestroy(validated_doc); } } return validated_at; } // TODO: refactor Read*FromPolicyValidatedMasterfiles char* ReadChecksumFromPolicyValidatedMasterfiles(const GenericAgentConfig *config, const char *maybe_dirname) { char *checksum_str = NULL; { JsonElement *validated_doc = ReadPolicyValidatedFileFromMasterfiles(config, maybe_dirname); if (validated_doc) { JsonElement *checksum = JsonObjectGet(validated_doc, "checksum"); if (checksum ) { checksum_str = xstrdup(JsonPrimitiveGetAsString(checksum)); } JsonDestroy(validated_doc); } } return checksum_str; } /** * @NOTE Updates the config->agent_specific.daemon.last_validated_at timestamp * used by serverd, execd etc daemons when checking for new policies. */ bool GenericAgentIsPolicyReloadNeeded(const GenericAgentConfig *config) { time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL); time_t now = time(NULL); if (validated_at > now) { Log(LOG_LEVEL_INFO, "Clock seems to have jumped back in time, mtime of %jd is newer than current time %jd, touching it", (intmax_t) validated_at, (intmax_t) now); GenericAgentTagReleaseDirectory(config, NULL, // use GetAutotagDir true, // write validated false); // write release ID return true; } { struct stat sb; if (stat(config->input_file, &sb) == -1) { Log(LOG_LEVEL_VERBOSE, "There is no readable input file at '%s'. (stat: %s)", config->input_file, GetErrorStr()); return true; } else if (sb.st_mtime > validated_at) { Log(LOG_LEVEL_VERBOSE, "Input file '%s' has changed since the last policy read attempt (file is newer than previous)", config->input_file); return true; } } // Check the directories first for speed and because non-input/data files should trigger an update { if (IsNewerFileTree( (char *)GetInputDir(), validated_at)) { Log(LOG_LEVEL_VERBOSE, "Quick search detected file changes"); return true; } } { char filename[MAX_FILENAME]; snprintf(filename, MAX_FILENAME, "%s/policy_server.dat", GetWorkDir()); MapName(filename); struct stat sb; if ((stat(filename, &sb) != -1) && (sb.st_mtime > validated_at)) { return true; } } return false; } /*******************************************************************/ Seq *ControlBodyConstraints(const Policy *policy, AgentType agent) { for (size_t i = 0; i < SeqLength(policy->bodies); i++) { const Body *body = SeqAt(policy->bodies, i); if (strcmp(body->type, CF_AGENTTYPES[agent]) == 0) { if (strcmp(body->name, "control") == 0) { return body->conlist; } } } return NULL; } /*******************************************************************/ static int ParseFacility(const char *name) { if (strcmp(name, "LOG_USER") == 0) { return LOG_USER; } if (strcmp(name, "LOG_DAEMON") == 0) { return LOG_DAEMON; } if (strcmp(name, "LOG_LOCAL0") == 0) { return LOG_LOCAL0; } if (strcmp(name, "LOG_LOCAL1") == 0) { return LOG_LOCAL1; } if (strcmp(name, "LOG_LOCAL2") == 0) { return LOG_LOCAL2; } if (strcmp(name, "LOG_LOCAL3") == 0) { return LOG_LOCAL3; } if (strcmp(name, "LOG_LOCAL4") == 0) { return LOG_LOCAL4; } if (strcmp(name, "LOG_LOCAL5") == 0) { return LOG_LOCAL5; } if (strcmp(name, "LOG_LOCAL6") == 0) { return LOG_LOCAL6; } if (strcmp(name, "LOG_LOCAL7") == 0) { return LOG_LOCAL7; } return -1; } static inline const char *LogFacilityToString(int facility) { switch(facility) { case LOG_LOCAL0: return "LOG_LOCAL0"; case LOG_LOCAL1: return "LOG_LOCAL1"; case LOG_LOCAL2: return "LOG_LOCAL2"; case LOG_LOCAL3: return "LOG_LOCAL3"; case LOG_LOCAL4: return "LOG_LOCAL4"; case LOG_LOCAL5: return "LOG_LOCAL5"; case LOG_LOCAL6: return "LOG_LOCAL6"; case LOG_LOCAL7: return "LOG_LOCAL7"; case LOG_USER: return "LOG_USER"; case LOG_DAEMON: return "LOG_DAEMON"; default: return "UNKNOWN"; } } void SetFacility(const char *retval) { Log(LOG_LEVEL_VERBOSE, "SET Syslog FACILITY = %s", retval); CloseLog(); OpenLog(ParseFacility(retval)); SetSyslogFacility(ParseFacility(retval)); if (!StoreDefaultLogFacility()) { Log(LOG_LEVEL_ERR, "Failed to store default log facility"); } } static void CheckWorkingDirectories(EvalContext *ctx) /* NOTE: We do not care about permissions (ACLs) in windows */ { struct stat statbuf; char vbuff[CF_BUFSIZE]; const char* const workdir = GetWorkDir(); const char* const statedir = GetStateDir(); if (uname(&VSYSNAME) == -1) { Log(LOG_LEVEL_ERR, "Couldn't get kernel name info. (uname: %s)", GetErrorStr()); memset(&VSYSNAME, 0, sizeof(VSYSNAME)); } snprintf(vbuff, CF_BUFSIZE, "%s%c.", workdir, FILE_SEPARATOR); MakeParentDirectory(vbuff, false, NULL); /* check that GetWorkDir() exists */ if (stat(GetWorkDir(), &statbuf) == -1) { FatalError(ctx,"Unable to stat working directory '%s'! (stat: %s)\n", GetWorkDir(), GetErrorStr()); } Log(LOG_LEVEL_VERBOSE, "Making sure that internal directories are private..."); Log(LOG_LEVEL_VERBOSE, "Checking integrity of the trusted workdir"); /* fix any improper uid/gid ownership on workdir */ if (statbuf.st_uid != getuid() || statbuf.st_gid != getgid()) { if (chown(workdir, getuid(), getgid()) == -1) { const char* error_reason = GetErrorStr(); Log(LOG_LEVEL_ERR, "Unable to set ownership on '%s' to '%ju.%ju'. (chown: %s)", workdir, (uintmax_t)getuid(), (uintmax_t)getgid(), error_reason); } } /* ensure workdir permissions are go-w */ if ((statbuf.st_mode & 022) != 0) { if (chmod(workdir, (mode_t) (statbuf.st_mode & ~022)) == -1) { Log(LOG_LEVEL_ERR, "Unable to set permissions on '%s' to go-w. (chmod: %s)", workdir, GetErrorStr()); } } MakeParentDirectory(GetStateDir(), false, NULL); Log(LOG_LEVEL_VERBOSE, "Checking integrity of the state database"); snprintf(vbuff, CF_BUFSIZE, "%s", statedir); if (stat(vbuff, &statbuf) == -1) { snprintf(vbuff, CF_BUFSIZE, "%s%c", statedir, FILE_SEPARATOR); MakeParentDirectory(vbuff, false, NULL); if (chown(vbuff, getuid(), getgid()) == -1) { Log(LOG_LEVEL_ERR, "Unable to set owner on '%s' to '%ju.%ju'. (chown: %s)", vbuff, (uintmax_t)getuid(), (uintmax_t)getgid(), GetErrorStr()); } chmod(vbuff, (mode_t) 0755); } else { #ifndef __MINGW32__ if (statbuf.st_mode & 022) { Log(LOG_LEVEL_ERR, "UNTRUSTED: State directory %s (mode %jo) was not private, world and/or group writeable!", statedir, (uintmax_t)(statbuf.st_mode & 0777)); } #endif /* !__MINGW32__ */ } Log(LOG_LEVEL_VERBOSE, "Checking integrity of the module directory"); snprintf(vbuff, CF_BUFSIZE, "%s%cmodules", workdir, FILE_SEPARATOR); if (stat(vbuff, &statbuf) == -1) { snprintf(vbuff, CF_BUFSIZE, "%s%cmodules%c.", workdir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentDirectory(vbuff, false, NULL); if (chown(vbuff, getuid(), getgid()) == -1) { Log(LOG_LEVEL_ERR, "Unable to set owner on '%s' to '%ju.%ju'. (chown: %s)", vbuff, (uintmax_t)getuid(), (uintmax_t)getgid(), GetErrorStr()); } chmod(vbuff, (mode_t) 0700); } else { #ifndef __MINGW32__ if (statbuf.st_mode & 022) { Log(LOG_LEVEL_ERR, "UNTRUSTED: Module directory %s (mode %jo) was not private!", vbuff, (uintmax_t)(statbuf.st_mode & 0777)); } #endif /* !__MINGW32__ */ } Log(LOG_LEVEL_VERBOSE, "Checking integrity of the PKI directory"); snprintf(vbuff, CF_BUFSIZE, "%s%cppkeys", workdir, FILE_SEPARATOR); if (stat(vbuff, &statbuf) == -1) { snprintf(vbuff, CF_BUFSIZE, "%s%cppkeys%c", workdir, FILE_SEPARATOR, FILE_SEPARATOR); MakeParentDirectory(vbuff, false, NULL); chmod(vbuff, (mode_t) 0700); /* Keys must be immutable to others */ } else { #ifndef __MINGW32__ if (statbuf.st_mode & 077) { FatalError(ctx, "UNTRUSTED: Private key directory %s%cppkeys (mode %jo) was not private!\n", workdir, FILE_SEPARATOR, (uintmax_t)(statbuf.st_mode & 0777)); } #endif /* !__MINGW32__ */ } } const char *GenericAgentResolveInputPath(const GenericAgentConfig *config, const char *input_file) { static char input_path[CF_BUFSIZE]; /* GLOBAL_R, no initialization needed */ switch (FilePathGetType(input_file)) { case FILE_PATH_TYPE_ABSOLUTE: strlcpy(input_path, input_file, CF_BUFSIZE); break; case FILE_PATH_TYPE_NON_ANCHORED: case FILE_PATH_TYPE_RELATIVE: snprintf(input_path, CF_BUFSIZE, "%s%c%s", config->input_dir, FILE_SEPARATOR, input_file); break; } return MapName(input_path); } ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, GenericAgentWriteVersion, Writer *, w) { WriterWriteF(w, "%s\n", NameVersion()); } /*******************************************************************/ const char *Version(void) { return VERSION; } /*******************************************************************/ const char *NameVersion(void) { return "CFEngine Core " VERSION; } /********************************************************************/ static void CleanPidFile(void) { if (unlink(PIDFILE) != 0) { if (errno != ENOENT) { Log(LOG_LEVEL_ERR, "Unable to remove pid file '%s'. (unlink: %s)", PIDFILE, GetErrorStr()); } } } /********************************************************************/ static void RegisterPidCleanup(void) { RegisterCleanupFunction(&CleanPidFile); } /********************************************************************/ void WritePID(char *filename) { pthread_once(&pid_cleanup_once, RegisterPidCleanup); snprintf(PIDFILE, CF_BUFSIZE - 1, "%s%c%s", GetPidDir(), FILE_SEPARATOR, filename); FILE *fp = safe_fopen_create_perms(PIDFILE, "w", CF_PERMS_DEFAULT); if (fp == NULL) { Log(LOG_LEVEL_INFO, "Could not write to PID file '%s'. (fopen: %s)", filename, GetErrorStr()); return; } fprintf(fp, "%ju\n", (uintmax_t)getpid()); fclose(fp); } pid_t ReadPID(char *filename) { char pidfile[PATH_MAX]; snprintf(pidfile, PATH_MAX - 1, "%s%c%s", GetPidDir(), FILE_SEPARATOR, filename); if (access(pidfile, F_OK) != 0) { Log(LOG_LEVEL_VERBOSE, "PID file '%s' doesn't exist", pidfile); return -1; } FILE *fp = safe_fopen(pidfile, "r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Could not read PID file '%s' (fopen: %s)", filename, GetErrorStr()); return -1; } intmax_t pid; if (fscanf(fp, "%jd", &pid) != 1) { Log(LOG_LEVEL_ERR, "Could not read PID from '%s'", pidfile); fclose(fp); return -1; } fclose(fp); return ((pid_t) pid); } bool GenericAgentConfigParseArguments(GenericAgentConfig *config, int argc, char **argv) { if (argc == 0) { return true; } if (argc > 1) { return false; } GenericAgentConfigSetInputFile(config, NULL, argv[0]); MINUSF = true; return true; } bool GenericAgentConfigParseWarningOptions(GenericAgentConfig *config, const char *warning_options) { if (strlen(warning_options) == 0) { return false; } if (strcmp("error", warning_options) == 0) { config->agent_specific.common.parser_warnings_error |= PARSER_WARNING_ALL; return true; } const char *options_start = warning_options; bool warnings_as_errors = false; if (StringStartsWith(warning_options, "error=")) { options_start = warning_options + strlen("error="); warnings_as_errors = true; } StringSet *warnings_set = StringSetFromString(options_start, ','); StringSetIterator it = StringSetIteratorInit(warnings_set); const char *warning_str = NULL; while ((warning_str = StringSetIteratorNext(&it))) { int warning = ParserWarningFromString(warning_str); if (warning == -1) { Log(LOG_LEVEL_ERR, "Unrecognized warning '%s'", warning_str); StringSetDestroy(warnings_set); return false; } if (warnings_as_errors) { config->agent_specific.common.parser_warnings_error |= warning; } else { config->agent_specific.common.parser_warnings |= warning; } } StringSetDestroy(warnings_set); return true; } bool GenericAgentConfigParseColor(GenericAgentConfig *config, const char *mode) { if (!mode || strcmp("auto", mode) == 0) { config->color = config->tty_interactive; return true; } else if (strcmp("always", mode) == 0) { config->color = true; return true; } else if (strcmp("never", mode) == 0) { config->color = false; return true; } else { Log(LOG_LEVEL_ERR, "Unrecognized color mode '%s'", mode); return false; } } bool GetTTYInteractive(void) { return isatty(0) || isatty(1) || isatty(2); } GenericAgentConfig *GenericAgentConfigNewDefault(AgentType agent_type, bool tty_interactive) { GenericAgentConfig *config = xmalloc(sizeof(GenericAgentConfig)); LoggingSetAgentType(CF_AGENTTYPES[agent_type]); config->agent_type = agent_type; config->tty_interactive = tty_interactive; const char *color_env = getenv("CFENGINE_COLOR"); config->color = (color_env && strcmp(color_env, "1") == 0); config->bundlesequence = NULL; config->original_input_file = NULL; config->input_file = NULL; config->input_dir = NULL; config->tag_release_dir = NULL; config->check_not_writable_by_others = agent_type != AGENT_TYPE_COMMON; config->check_runnable = agent_type != AGENT_TYPE_COMMON; config->ignore_missing_bundles = false; config->ignore_missing_inputs = false; config->ignore_preferred_augments = false; config->heap_soft = NULL; config->heap_negated = NULL; config->ignore_locks = false; config->protocol_version = CF_PROTOCOL_UNDEFINED; config->agent_specific.agent.bootstrap_argument = NULL; config->agent_specific.agent.bootstrap_ip = NULL; config->agent_specific.agent.bootstrap_port = NULL; config->agent_specific.agent.bootstrap_host = NULL; /* By default we trust the network when bootstrapping. */ config->agent_specific.agent.bootstrap_trust_server = true; /* By default we run promises.cf as the last step of boostrapping */ config->agent_specific.agent.bootstrap_trigger_policy = true; /* By default we start services during bootstrap */ config->agent_specific.agent.skip_bootstrap_service_start = false; /* Log classes */ config->agent_specific.agent.report_class_log = false; config->agent_specific.common.no_augments = false; config->agent_specific.common.no_host_specific = false; switch (agent_type) { case AGENT_TYPE_COMMON: config->agent_specific.common.eval_functions = true; config->agent_specific.common.show_classes = NULL; config->agent_specific.common.show_variables = NULL; config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE; /* Bitfields of warnings to be recorded, or treated as errors. */ config->agent_specific.common.parser_warnings = PARSER_WARNING_ALL; config->agent_specific.common.parser_warnings_error = 0; break; case AGENT_TYPE_AGENT: config->agent_specific.agent.show_evaluated_classes = NULL; config->agent_specific.agent.show_evaluated_variables = NULL; break; default: break; } return config; } void GenericAgentConfigDestroy(GenericAgentConfig *config) { if (config != NULL) { RlistDestroy(config->bundlesequence); StringSetDestroy(config->heap_soft); StringSetDestroy(config->heap_negated); free(config->original_input_file); free(config->input_file); free(config->input_dir); free(config->tag_release_dir); free(config->agent_specific.agent.bootstrap_argument); free(config->agent_specific.agent.bootstrap_host); free(config->agent_specific.agent.bootstrap_ip); free(config->agent_specific.agent.bootstrap_port); free(config); } } void GenericAgentConfigApply(EvalContext *ctx, const GenericAgentConfig *config) { assert(config != NULL); EvalContextSetConfig(ctx, config); if (config->heap_soft) { StringSetIterator it = StringSetIteratorInit(config->heap_soft); const char *context = NULL; while ((context = StringSetIteratorNext(&it))) { Class *cls = EvalContextClassGet(ctx, NULL, context); if (cls && !cls->is_soft) { FatalError(ctx, "You cannot use -D to define a reserved class"); } EvalContextClassPutSoft(ctx, context, CONTEXT_SCOPE_NAMESPACE, "source=environment"); } } if (config->heap_negated != NULL) { /* Takes ownership of heap_negated. */ EvalContextSetNegatedClasses(ctx, config->heap_negated); ((GenericAgentConfig *)config)->heap_negated = NULL; } switch (LogGetGlobalLevel()) { case LOG_LEVEL_DEBUG: EvalContextClassPutHard(ctx, "debug_mode", "cfe_internal,source=agent"); EvalContextClassPutHard(ctx, "opt_debug", "cfe_internal,source=agent"); // fall through case LOG_LEVEL_VERBOSE: EvalContextClassPutHard(ctx, "verbose_mode", "cfe_internal,source=agent"); // fall through case LOG_LEVEL_INFO: EvalContextClassPutHard(ctx, "inform_mode", "cfe_internal,source=agent"); break; default: break; } if (config->color) { LoggingSetColor(config->color); } if (config->agent_type == AGENT_TYPE_COMMON) { EvalContextSetEvalOption(ctx, EVAL_OPTION_FULL, false); if (config->agent_specific.common.eval_functions) { EvalContextSetEvalOption(ctx, EVAL_OPTION_EVAL_FUNCTIONS, true); } } EvalContextSetIgnoreLocks(ctx, config->ignore_locks); if (DONTDO) { EvalContextClassPutHard(ctx, "opt_dry_run", "cfe_internal,source=environment"); } } bool CheckAndGenerateFailsafe(const char *inputdir, const char *input_file) { char failsafe_path[CF_BUFSIZE]; if (strlen(inputdir) + strlen(input_file) > sizeof(failsafe_path) - 2) { Log(LOG_LEVEL_ERR, "Unable to generate path for %s/%s file. Path too long.", inputdir, input_file); /* We could create dynamically allocated buffer able to hold the whole content of the path but this should be unlikely that we will end up here. */ return false; } snprintf(failsafe_path, CF_BUFSIZE - 1, "%s/%s", inputdir, input_file); MapName(failsafe_path); if (access(failsafe_path, R_OK) != 0) { return WriteBuiltinFailsafePolicyToPath(failsafe_path); } return true; } void GenericAgentConfigSetInputFile(GenericAgentConfig *config, const char *inputdir, const char *input_file) { free(config->original_input_file); free(config->input_file); free(config->input_dir); config->original_input_file = xstrdup(input_file); if (inputdir && FilePathGetType(input_file) == FILE_PATH_TYPE_NON_ANCHORED) { config->input_file = StringFormat("%s%c%s", inputdir, FILE_SEPARATOR, input_file); } else { config->input_file = xstrdup(input_file); } config->input_dir = xstrdup(config->input_file); if (!ChopLastNode(config->input_dir)) { free(config->input_dir); config->input_dir = xstrdup("."); } } void GenericAgentConfigSetBundleSequence(GenericAgentConfig *config, const Rlist *bundlesequence) { RlistDestroy(config->bundlesequence); config->bundlesequence = RlistCopy(bundlesequence); } bool GenericAgentPostLoadInit(const EvalContext *ctx) { const char *tls_ciphers = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_TLS_CIPHERS); const char *tls_min_version = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_TLS_MIN_VERSION); const char *system_log_level_str = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_SYSTEM_LOG_LEVEL); LogLevel system_log_level = LogLevelFromString(system_log_level_str); if (system_log_level != LOG_LEVEL_NOTHING) { LogSetGlobalSystemLogLevel(system_log_level); } return cfnet_init(tls_min_version, tls_ciphers); } void SetupSignalsForAgent(void) { signal(SIGINT, HandleSignalsForAgent); signal(SIGTERM, HandleSignalsForAgent); signal(SIGBUS, HandleSignalsForAgent); signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, HandleSignalsForAgent); signal(SIGUSR2, HandleSignalsForAgent); } void GenericAgentShowContextsFormatted(EvalContext *ctx, const char *regexp) { assert(regexp != NULL); ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Seq *seq = SeqNew(1000, free); Regex *rx = CompileRegex(regexp); if (rx == NULL) { Log(LOG_LEVEL_ERR, "Sorry, we could not compile regular expression %s", regexp); return; } Class *cls = NULL; while ((cls = ClassTableIteratorNext(iter)) != NULL) { char *class_name = ClassRefToString(cls->ns, cls->name); if (!RegexPartialMatch(rx, class_name)) { free(class_name); continue; } StringSet *tagset = cls->tags; Buffer *tagbuf = StringSetToBuffer(tagset, ','); char *line; xasprintf(&line, "%-60s %-40s %-40s", class_name, BufferData(tagbuf), NULL_TO_EMPTY_STRING(cls->comment)); SeqAppend(seq, line); BufferDestroy(tagbuf); free(class_name); } RegexDestroy(rx); SeqSort(seq, StrCmpWrapper, NULL); printf("%-60s %-40s %-40s\n", "Class name", "Meta tags", "Comment"); for (size_t i = 0; i < SeqLength(seq); i++) { const char *context = SeqAt(seq, i); printf("%s\n", context); } SeqDestroy(seq); ClassTableIteratorDestroy(iter); } void GenericAgentShowVariablesFormatted(EvalContext *ctx, const char *regexp) { assert(regexp != NULL); VariableTableIterator *iter = EvalContextVariableTableIteratorNew(ctx, NULL, NULL, NULL); Variable *v = NULL; Seq *seq = SeqNew(2000, free); Regex *rx = CompileRegex(regexp); if (rx == NULL) { Log(LOG_LEVEL_ERR, "Sorry, we could not compile regular expression %s", regexp); return; } while ((v = VariableTableIteratorNext(iter))) { char *varname = VarRefToString(VariableGetRef(v), true); if (!RegexPartialMatch(rx, varname)) { free(varname); continue; } Writer *w = StringWriter(); Rval var_rval = VariableGetRval(v, false); if (var_rval.type == RVAL_TYPE_CONTAINER) { JsonWriteCompact(w, RvalContainerValue(var_rval)); } else { RvalWrite(w, var_rval); } const char *var_value; if (StringIsPrintable(StringWriterData(w))) { var_value = StringWriterData(w); } else { var_value = ""; } Buffer *tagbuf = NULL; StringSet *tagset = VariableGetTags(v); if (tagset != NULL) { tagbuf = StringSetToBuffer(tagset, ','); } const char *comment = VariableGetComment(v); char *line; xasprintf(&line, "%-40s %-60s %-40s %-40s", varname, var_value, tagbuf != NULL ? BufferData(tagbuf) : "", NULL_TO_EMPTY_STRING(comment)); SeqAppend(seq, line); BufferDestroy(tagbuf); WriterClose(w); free(varname); } RegexDestroy(rx); SeqSort(seq, StrCmpWrapper, NULL); printf("%-40s %-60s %-40s %-40s\n", "Variable name", "Variable value", "Meta tags", "Comment"); for (size_t i = 0; i < SeqLength(seq); i++) { const char *variable = SeqAt(seq, i); printf("%s\n", variable); } SeqDestroy(seq); VariableTableIteratorDestroy(iter); } cfengine-3.24.2/libpromises/dbm_migration.h0000644000000000000000000000223315010704253020667 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DB_MIGRATION_H #define CFENGINE_DB_MIGRATION_H #include typedef bool (*DBMigrationFunction)(DBHandle *db); bool DBMigrate(DBHandle *db, dbid id); #endif cfengine-3.24.2/libpromises/extensions.c0000644000000000000000000001402615010704253020251 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* sscanf() */ #include /* getenv() */ #include /* strcmp() */ #include #include #include /* * A note regarding the loading of the extension plugins: * * The extension plugin was originally statically linked into each agent, * but was then refactored into plugins. * Therefore, since it hasn't been written according to plugin guidelines, * it is not safe to assume that we can unload it once we have * loaded it, since it may allocate resources that are not freed. It is also * not safe to assume that we can load it after initialization is complete * (for example if the plugin is dropped into the directory after cf-serverd * has already been running for some time), because some data structures may * not have been initialized. * * Therefore, the load strategy is as follows: * * - If we find the plugin immediately, load it, and keep it loaded. * * - If we don't find the plugin, NEVER attempt to load it again afterwards. * * - Never unload the plugin. * * - Any installation/upgrade/removal of the plugin requires daemon restarts. * * - The exception is for testing (see getenv below). */ #ifndef BUILTIN_EXTENSIONS static bool enable_extension_libraries = true; /* GLOBAL_X */ static bool attempted_loading = false; /* GLOBAL_X */ void extension_libraries_disable() { if (attempted_loading) { ProgrammingError("extension_libraries_disable() MUST be called before any call to extension functions"); } enable_extension_libraries = false; } void *extension_library_open(const char *name) { if (!enable_extension_libraries) { return NULL; } if (getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE") == NULL) { // Only do loading checks if we are not doing tests. attempted_loading = true; } const char *dirs_to_try[3] = { NULL }; const char *dir = getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR"); char lib[] = "/lib"; if (dir) { lib[0] = '\0'; dirs_to_try[0] = dir; } else { dirs_to_try[0] = GetWorkDir(); if (strcmp(WORKDIR, dirs_to_try[0]) != 0) { // try to load from the real WORKDIR in case GetWorkDir returned the local workdir to the user // We try this because enterprise "make install" is in WORKDIR, not per user dirs_to_try[1] = WORKDIR; } } void *handle = NULL; for (int i = 0; dirs_to_try[i]; i++) { char path[strlen(dirs_to_try[i]) + strlen(lib) + strlen(name) + 2]; xsnprintf(path, sizeof(path), "%s%s/%s", dirs_to_try[i], lib, name); Log(LOG_LEVEL_DEBUG, "Trying to shlib_open extension plugin '%s' from '%s'", name, path); handle = shlib_open(path); if (handle) { Log(LOG_LEVEL_VERBOSE, "Successfully opened extension plugin '%s' from '%s'", name, path); break; } else { const char *error; if (errno == ENOENT) { error = "(not installed)"; } else { error = GetErrorStr(); } Log(LOG_LEVEL_VERBOSE, "Could not open extension plugin '%s' from '%s': %s", name, path, error); } } if (!handle) { return handle; } // Version check, to avoid binary incompatible plugins. const char * (*GetExtensionLibraryVersion)() = shlib_load(handle, "GetExtensionLibraryVersion"); if (!GetExtensionLibraryVersion) { Log(LOG_LEVEL_ERR, "Could not retrieve version from extension plugin (%s). Not loading the plugin.", name); goto close_and_fail; } const char *plugin_version = GetExtensionLibraryVersion(); unsigned int bin_major, bin_minor, bin_patch; unsigned int plug_major, plug_minor, plug_patch; if (sscanf(VERSION, "%u.%u.%u", &bin_major, &bin_minor, &bin_patch) != 3) { Log(LOG_LEVEL_ERR, "Not able to extract version number from binary (%s). Not loading extension plugin.", name); goto close_and_fail; } if (sscanf(plugin_version, "%u.%u.%u", &plug_major, &plug_minor, &plug_patch) != 3) { Log(LOG_LEVEL_ERR, "Not able to extract version number from plugin (%s). Not loading extension plugin.", name); goto close_and_fail; } if (bin_major != plug_major || bin_minor != plug_minor || bin_patch != plug_patch) { Log(LOG_LEVEL_ERR, "Extension plugin version does not match CFEngine Community version " "(CFEngine Community v%u.%u.%u, Extension (%s) v%u.%u.%u). Refusing to load it.", bin_major, bin_minor, bin_patch, name, plug_major, plug_minor, plug_patch); goto close_and_fail; } Log(LOG_LEVEL_VERBOSE, "Successfully loaded extension plugin '%s'", name); return handle; close_and_fail: shlib_close(handle); return NULL; } void extension_library_close(void *handle) { shlib_close(handle); } #endif // !BUILTIN_EXTENSIONS cfengine-3.24.2/libpromises/matching.h0000644000000000000000000000353115010704253017650 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MATCHING_H #define CFENGINE_MATCHING_H #include bool IsRegex(const char *str); /* Pure */ bool IsRegexItemIn(const EvalContext *ctx, const Item *list, const char *regex); /* Uses context */ char *ExtractFirstReference(const char *regexp, const char *teststring); /* Pure, not thread-safe */ bool IsPathRegex(const char *str); /* Pure */ bool HasRegexMetaChars(const char *string); void EscapeRegexChars(char *str, char *strEsc, int strEscSz); /* Pure */ void EscapeSpecialChars(const char *str, char *strEsc, size_t strEscSz, char *noEscseq, char *noEsclist); /* Pure */ size_t EscapeRegexCharsLen(const char *str); /* Pure */ char *EscapeChar(char *str, size_t strSz, char esc); /* Pure */ void AnchorRegex(const char *regex, char *out, int outSz); /* Pure */ /** result is malloced */ char *AnchorRegexNew(const char *regex); #endif // MATCHING_H cfengine-3.24.2/libpromises/syslog_client.c0000644000000000000000000001023315010704253020724 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* * Set by cf-agent/cf-serverd from body agent/server control. */ static char SYSLOG_HOST[MAXHOSTNAMELEN] = "localhost"; /* * Set by cf-agent/cf-serverd from body agent/server control. */ static uint16_t SYSLOG_PORT = 514; /* * Set by cf-agent/cf-serverd/cf-execd from body agent/exec/server control. */ static int SYSLOG_FACILITY = LOG_USER; void SetSyslogFacility(int facility) { SYSLOG_FACILITY = facility; } int GetSyslogFacility() { return SYSLOG_FACILITY; } bool SetSyslogHost(const char *host) { if (strlen(host) < sizeof(SYSLOG_HOST)) { strcpy(SYSLOG_HOST, host); return true; } else { return false; } } void SetSyslogPort(uint16_t port) { SYSLOG_PORT = port; } void RemoteSysLog(int log_priority, const char *log_string) { time_t now = time(NULL); struct addrinfo query = { 0 }, *response = NULL; char strport[PRINTSIZE(unsigned)]; xsnprintf(strport, sizeof(strport), "%u", (unsigned) SYSLOG_PORT); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_DGRAM; int err = getaddrinfo(SYSLOG_HOST, strport, &query, &response); if (err != 0) { Log(LOG_LEVEL_INFO, "Unable to find syslog_host or service: (%s/%s) %s", SYSLOG_HOST, strport, gai_strerror(err)); if (response != NULL) { freeaddrinfo(response); } return; } for (const struct addrinfo *ap = response; ap != NULL; ap = ap->ai_next) { /* No DNS lookup, just convert IP address to string. */ char txtaddr[CF_MAX_IP_LEN] = ""; getnameinfo(ap->ai_addr, ap->ai_addrlen, txtaddr, sizeof(txtaddr), NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_VERBOSE, "Connect to syslog '%s' = '%s' on port '%s'", SYSLOG_HOST, txtaddr, strport); int sd = socket(ap->ai_family, ap->ai_socktype, IPPROTO_UDP); if (sd == -1) { Log(LOG_LEVEL_INFO, "Couldn't open a socket. (socket: %s)", GetErrorStr()); continue; } else { const size_t rfc3164_len = 1024; char message[rfc3164_len]; char timebuffer[26]; pid_t pid = getpid(); snprintf( message, sizeof(message), "<%i>%.15s %.256s %.256s[%ld]: %s", (log_priority | SYSLOG_FACILITY), (cf_strtimestamp_local(now, timebuffer) + 4), // Skips day str VFQNAME, VPREFIX, (long) pid, log_string); err = sendto(sd, message, strlen(message), 0, ap->ai_addr, ap->ai_addrlen); if (err == -1) { Log(LOG_LEVEL_VERBOSE, "Couldn't send '%s' to syslog server '%s'. (sendto: %s)", message, SYSLOG_HOST, GetErrorStr()); } else { Log(LOG_LEVEL_VERBOSE, "Syslog message: '%s' to server '%s'", message, SYSLOG_HOST); } close(sd); } } freeaddrinfo(response); } cfengine-3.24.2/libpromises/timeout.h0000644000000000000000000000216015010704253017541 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_TIMEOUT_H #define CFENGINE_TIMEOUT_H void SetTimeOut(int timeout); void TimeOut(void); time_t SetReferenceTime(void); #endif cfengine-3.24.2/libpromises/mod_services.h0000644000000000000000000000217415010704253020542 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_SERVICES_H #define CFENGINE_MOD_SERVICES_H #include extern const PromiseTypeSyntax CF_SERVICES_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/scope.c0000644000000000000000000002527315010704253017171 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include /*******************************************************************/ const char *SpecialScopeToString(SpecialScope scope) { switch (scope) { case SPECIAL_SCOPE_CONST: return "const"; case SPECIAL_SCOPE_EDIT: return "edit"; case SPECIAL_SCOPE_MATCH: return "match"; case SPECIAL_SCOPE_MON: return "mon"; case SPECIAL_SCOPE_SYS: return "sys"; case SPECIAL_SCOPE_DEF: return "def"; case SPECIAL_SCOPE_THIS: return "this"; case SPECIAL_SCOPE_BODY: return "body"; default: ProgrammingError("Unhandled special scope"); } } SpecialScope SpecialScopeFromString(const char *scope) { if (scope == NULL) { return SPECIAL_SCOPE_NONE; } else if (strcmp("const", scope) == 0) { return SPECIAL_SCOPE_CONST; } else if (strcmp("edit", scope) == 0) { return SPECIAL_SCOPE_EDIT; } else if (strcmp("match", scope) == 0) { return SPECIAL_SCOPE_MATCH; } else if (strcmp("mon", scope) == 0) { return SPECIAL_SCOPE_MON; } else if (strcmp("sys", scope) == 0) { return SPECIAL_SCOPE_SYS; } else if (strcmp("def", scope) == 0) { return SPECIAL_SCOPE_DEF; } else if (strcmp("this", scope) == 0) { return SPECIAL_SCOPE_THIS; } else if (strcmp("body", scope) == 0) { return SPECIAL_SCOPE_BODY; } /* All other scopes fall here, for example all bundle names. It means that * scope was not special. */ return SPECIAL_SCOPE_NONE; } void ScopeAugment(EvalContext *ctx, const Bundle *bp, const Promise *pp, const Rlist *arguments) { if (RlistLen(bp->args) != RlistLen(arguments)) { Log(LOG_LEVEL_ERR, "While constructing scope '%s'", bp->name); fprintf(stderr, "Formal = "); { Writer *w = FileWriter(stderr); RlistWrite(w, bp->args); FileWriterDetach(w); } fprintf(stderr, ", Actual = "); { Writer *w = FileWriter(stderr); RlistWrite(w, arguments); FileWriterDetach(w); } fprintf(stderr, "\n"); FatalError(ctx, "Augment scope, formal and actual parameter mismatch is fatal"); } const Bundle *pbp = NULL; if (pp != NULL) { pbp = PromiseGetBundle(pp); } for (const Rlist *rpl = bp->args, *rpr = arguments; rpl != NULL; rpl = rpl->next, rpr = rpr->next) { const char *lval = RlistScalarValue(rpl); Log(LOG_LEVEL_VERBOSE, "V: + Private parameter: '%s' in scope '%s' (type: %c) in pass %d", lval, bp->name, rpr->val.type, EvalContextGetPass(ctx)); // CheckBundleParameters() already checked that there is no namespace collision // By this stage all functions should have been expanded, so we only have scalars left if (rpr->val.type == RVAL_TYPE_SCALAR && IsNakedVar(RlistScalarValue(rpr), '@')) { char naked[CF_BUFSIZE]; GetNaked(naked, RlistScalarValue(rpr)); DataType value_type; const void *value; if (pbp != NULL) { VarRef *ref = VarRefParseFromBundle(naked, pbp); value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); } else { VarRef *ref = VarRefParseFromBundle(naked, bp); value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); } switch (value_type) { case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: { VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, value, CF_DATA_TYPE_STRING_LIST, "source=promise"); VarRefDestroy(ref); } break; case CF_DATA_TYPE_CONTAINER: { VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, value, CF_DATA_TYPE_CONTAINER, "source=promise"); VarRefDestroy(ref); } break; default: { Log(LOG_LEVEL_ERR, "List or container parameter '%s' not found while constructing scope '%s' - use @(scope.variable) in calling reference", naked, bp->name); VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, RlistScalarValue(rpr), CF_DATA_TYPE_STRING, "source=promise"); VarRefDestroy(ref); } break; } } else { switch(rpr->val.type) { case RVAL_TYPE_SCALAR: { VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, RvalScalarValue(rpr->val), CF_DATA_TYPE_STRING, "source=promise"); VarRefDestroy(ref); } break; case RVAL_TYPE_FNCALL: { FnCall *subfp = RlistFnCallValue(rpr); Rval rval = FnCallEvaluate(ctx, PromiseGetPolicy(pp), subfp, pp).rval; if (rval.type == RVAL_TYPE_SCALAR) { VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariablePut(ctx, ref, RvalScalarValue(rval), CF_DATA_TYPE_STRING, "source=promise"); VarRefDestroy(ref); } else { Log(LOG_LEVEL_ERR, "Only functions returning scalars can be used as arguments"); } RvalDestroy(rval); } break; default: ProgrammingError("An argument neither a scalar nor a list seemed to appear. Impossible"); } } } /* Check that there are no danglers left to evaluate in the hash table itself */ return; } void ScopeMapBodyArgs(EvalContext *ctx, const Body *body, const Rlist *args) { const Rlist *arg = NULL; const Rlist *param = NULL; for (arg = args, param = body->args; arg != NULL && param != NULL; arg = arg->next, param = param->next) { DataType arg_type = CF_DATA_TYPE_NONE; switch (arg->val.type) { case RVAL_TYPE_SCALAR: arg_type = StringDataType(ctx, RlistScalarValue(arg)); break; case RVAL_TYPE_FNCALL: { const FnCallType *fn = FnCallTypeGet(RlistFnCallValue(arg)->name); if (!fn) { FatalError(ctx, "Argument '%s' given to body '%s' is not a valid function", RlistFnCallValue(arg)->name, body->name); } arg_type = fn->dtype; } break; default: FatalError(ctx, "Cannot derive data type from Rval type %c", arg->val.type); } switch (arg->val.type) { case RVAL_TYPE_SCALAR: { const char *lval = RlistScalarValue(param); VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.'); EvalContextVariablePut(ctx, ref, RvalScalarValue(arg->val), arg_type, "source=body"); VarRefDestroy(ref); } break; case RVAL_TYPE_LIST: { const char *lval = RlistScalarValue(param); VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.'); EvalContextVariablePut(ctx, ref, RvalRlistValue(arg->val), arg_type, "source=body"); VarRefDestroy(ref); } break; case RVAL_TYPE_FNCALL: { FnCall *fp = RlistFnCallValue(arg); arg_type = CF_DATA_TYPE_NONE; { const FnCallType *fncall_type = FnCallTypeGet(fp->name); if (fncall_type) { arg_type = fncall_type->dtype; } } FnCallResult res = FnCallEvaluate(ctx, body->parent_policy, fp, NULL); if (res.status == FNCALL_FAILURE && THIS_AGENT_TYPE != AGENT_TYPE_COMMON) { Log(LOG_LEVEL_VERBOSE, "Embedded function argument does not resolve to a name - probably too many evaluation levels for '%s'", fp->name); } else { const char *lval = RlistScalarValue(param); void *rval = res.rval.item; VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.'); EvalContextVariablePut(ctx, ref, rval, arg_type, "source=body"); VarRefDestroy(ref); } RvalDestroy(res.rval); } break; default: /* Nothing else should happen */ ProgrammingError("Software error: something not a scalar/function in argument literal"); } } } /*******************************************************************/ /* Utility functions */ /*******************************************************************/ void JoinScopeName(const char *ns, const char *bundle, char scope_out[CF_MAXVARSIZE]) { assert(bundle); if (ns) { snprintf(scope_out, CF_MAXVARSIZE, "%s%c%s", ns, CF_NS, bundle); } else { snprintf(scope_out, CF_MAXVARSIZE, "%s", bundle); } } cfengine-3.24.2/libpromises/parser.c0000644000000000000000000001142715010704253017350 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include int yyparse(void); ParserState PARSER_STATE = { 0 }; /* GLOBAL_X */ extern FILE *yyin; static void ParserStateReset(ParserState *p, bool discard) { assert(p != NULL); p->agent_type = AGENT_TYPE_COMMON; p->warnings = PARSER_WARNING_ALL; p->policy = NULL; int i = CF_MAX_NESTING; while (i-- > 0) /* Clear stacks from top down */ { if (discard) { free(p->currentfnid[i]); RlistDestroy(p->giveargs[i]); FnCallDestroy(p->currentfncall[i]); } else { assert(!p->currentfnid[i]); assert(!p->giveargs[i]); assert(!p->currentfncall[i]); } p->currentfnid[i] = NULL; p->giveargs[i] = NULL; p->currentfncall[i] = NULL; } free(p->current_line); p->current_line = NULL; p->line_no = 1; p->line_pos = 1; p->error_count = 0; p->warning_count = 0; p->list_nesting = 0; p->arg_nesting = 0; free(p->current_namespace); p->current_namespace = xstrdup("default"); p->currentid[0] = '\0'; if (p->currentstring) { free(p->currentstring); } p->currentstring = NULL; p->currenttype[0] = '\0'; if (p->currentclasses) { free(p->currentclasses); } p->currentclasses = NULL; p->currentRlist = NULL; p->currentpromise = NULL; p->currentbody = NULL; if (p->promiser) { free(p->promiser); } p->promiser = NULL; p->blockid[0] = '\0'; p->blocktype[0] = '\0'; RvalDestroy(p->rval); p->rval = RvalNew(NULL, RVAL_TYPE_NOPROMISEE); } static void ParserStateClean(ParserState *p) { free(p->current_namespace); p->current_namespace = NULL; } Policy *ParserParseFile(AgentType agent_type, const char *path, unsigned int warnings, unsigned int warnings_error) { ParserStateReset(&PARSER_STATE, false); PARSER_STATE.agent_type = agent_type; PARSER_STATE.policy = PolicyNew(); PARSER_STATE.warnings = warnings; PARSER_STATE.warnings_error = warnings_error; strlcpy(PARSER_STATE.filename, path, CF_MAXVARSIZE); yyin = safe_fopen(path, "rt"); if (yyin == NULL) { Log(LOG_LEVEL_ERR, "While opening file '%s' for parsing. (fopen: %s)", path, GetErrorStr()); DoCleanupAndExit(EXIT_FAILURE); } while (!feof(yyin)) { yyparse(); if (ferror(yyin)) { perror("cfengine"); DoCleanupAndExit(EXIT_FAILURE); } } fclose(yyin); if (PARSER_STATE.error_count > 0) { PolicyDestroy(PARSER_STATE.policy); ParserStateReset(&PARSER_STATE, true); ParserStateClean(&PARSER_STATE); return NULL; } Policy *policy = PARSER_STATE.policy; ParserStateReset(&PARSER_STATE, false); ParserStateClean(&PARSER_STATE); return policy; } int ParserWarningFromString(const char *warning_str) { if (strcmp("deprecated", warning_str) == 0) { return PARSER_WARNING_DEPRECATED; } else if (strcmp("removed", warning_str) == 0) { return PARSER_WARNING_REMOVED; } else if (strcmp("sanity-check", warning_str) == 0) { return PARSER_WARNING_SANITY_CHECK; } else if (strcmp("all", warning_str) == 0) { return PARSER_WARNING_ALL; } else { return -1; } } const char *ParserWarningToString(unsigned int warning) { switch (warning) { case PARSER_WARNING_DEPRECATED: return "deprecated"; case PARSER_WARNING_REMOVED: return "removed"; case PARSER_WARNING_SANITY_CHECK: return "sanity-check"; default: ProgrammingError("Invalid parser warning: %u", warning); } } cfengine-3.24.2/libpromises/timeout.c0000644000000000000000000000361615010704253017543 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include void SetTimeOut(int timeout) { ALARM_PID = -1; signal(SIGALRM, (void *) TimeOut); alarm(timeout); } /*************************************************************************/ void TimeOut() { alarm(0); if (ALARM_PID != -1) { Log(LOG_LEVEL_VERBOSE, "Time out of process %jd", (intmax_t)ALARM_PID); GracefulTerminate(ALARM_PID, PROCESS_START_TIME_UNKNOWN); } else { Log(LOG_LEVEL_VERBOSE, "%s> Time out", VPREFIX); } } /*************************************************************************/ time_t SetReferenceTime(void) { time_t tloc; if ((tloc = time((time_t *) NULL)) == -1) { Log(LOG_LEVEL_ERR, "Couldn't read system clock. (time: %s)", GetErrorStr()); } CFSTARTTIME = tloc; Log(LOG_LEVEL_VERBOSE, "Reference time set to '%s'", ctime(&tloc)); return tloc; } cfengine-3.24.2/libpromises/match_scope.c0000644000000000000000000000773215010704253020345 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include /* StringFromLong */ #include /* CompileRegex */ /* Sets variables */ static bool RegExMatchSubString(EvalContext *ctx, Regex *regex, const char *teststring, int *start, int *end) { pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(regex, NULL); int result = pcre2_match(regex, (PCRE2_SPTR) teststring, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); /* pcre2_match() returns the highest capture group number + 1, i.e. 1 means * a match with 0 capture groups. 0 means the vector of offsets is small, * negative numbers are errors (incl. no match). */ if (result > 0) { size_t *ovector = pcre2_get_ovector_pointer(match_data); *start = ovector[0]; *end = ovector[1]; EvalContextVariableClearMatch(ctx); for (int i = 0; i < result; i++) /* make backref vars $(1),$(2) etc */ { const char *backref_start = teststring + ovector[i * 2]; int backref_len = ovector[i * 2 + 1] - ovector[i * 2]; if (backref_len < CF_MAXVARSIZE) { char substring[CF_MAXVARSIZE]; char *index = StringFromLong(i); strlcpy(substring, backref_start, MIN(CF_MAXVARSIZE, backref_len + 1)); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_MATCH, index, substring, CF_DATA_TYPE_STRING, "source=regex"); free(index); } } } else { *start = 0; *end = 0; } pcre2_match_data_free(match_data); RegexDestroy(regex); return result > 0; } /* Sets variables */ static bool RegExMatchFullString(EvalContext *ctx, Regex *rx, const char *teststring) { int match_start; int match_len; if (RegExMatchSubString(ctx, rx, teststring, &match_start, &match_len)) { return ((size_t) match_start == 0) && ((size_t) match_len == strlen(teststring)); } else { return false; } } bool FullTextMatch(EvalContext *ctx, const char *regexp, const char *teststring) { if (strcmp(regexp, teststring) == 0) { return true; } Regex *rx = CompileRegex(regexp); if (rx == NULL) { return false; } if (RegExMatchFullString(ctx, rx, teststring)) { return true; } else { return false; } } bool ValidateRegEx(const char *regex) { Regex *rx = CompileRegex(regex); bool regex_valid = rx != NULL; RegexDestroy(rx); return regex_valid; } bool BlockTextMatch(EvalContext *ctx, const char *regexp, const char *teststring, int *start, int *end) { Regex *rx = CompileRegex(regexp); if (rx == NULL) { return false; } if (RegExMatchSubString(ctx, rx, teststring, start, end)) { return true; } else { return false; } } cfengine-3.24.2/libpromises/parser_state.h0000644000000000000000000000500715010704253020552 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PARSER_STATE_H #define CFENGINE_PARSER_STATE_H #include #include #include #include // ParserBlock #define CF_MAX_NESTING 10 typedef struct { AgentType agent_type; ParserBlock block; // enum for bundle/body char blocktype[CF_MAXVARSIZE]; char blockid[CF_MAXVARSIZE]; char filename[CF_MAXVARSIZE]; char *current_line; int line_pos; int line_no; int error_count; int warning_count; int warnings; // bitfield of warnings not considered to be an error int warnings_error; // bitfield of warnings considered to be an error int if_depth; int arg_nesting; int list_nesting; char lval[CF_MAXVARSIZE]; Rval rval; bool references_body; char *promiser; void *promisee; char *current_namespace; char currentid[CF_MAXVARSIZE]; char currenttype[CF_MAXVARSIZE]; char *currentstring; char *currentclasses; char *currentvarclasses; Policy *policy; Bundle *currentbundle; Body *currentbody; Promise *currentpromise; BundleSection *currentstype; Rlist *useargs; Rlist *currentRlist; char *currentfnid[CF_MAX_NESTING]; Rlist *giveargs[CF_MAX_NESTING]; FnCall *currentfncall[CF_MAX_NESTING]; struct OffsetState { size_t current; size_t last_id; size_t last_string; size_t last_block_id; size_t last_promise_guard_id; size_t last_class_id; } offsets; } ParserState; extern ParserState PARSER_STATE; #endif cfengine-3.24.2/libpromises/granules.h0000644000000000000000000000254515010704253017702 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_GRANULES_H #define CFENGINE_GRANULES_H #include char *GenTimeKey(time_t now); const char *ShiftSlotToString(int shift_slot); int GetTimeSlot(time_t here_and_now); int GetShiftSlot(time_t here_and_now); time_t GetShiftSlotStart(time_t t); time_t MeasurementSlotStart(time_t t); time_t MeasurementSlotTime(size_t slot, size_t num_slots, time_t now); #endif cfengine-3.24.2/libpromises/scope.h0000644000000000000000000000420215010704253017163 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SCOPE_H #define CFENGINE_SCOPE_H #include #include typedef enum { SPECIAL_SCOPE_CONST, SPECIAL_SCOPE_EDIT, SPECIAL_SCOPE_MATCH, SPECIAL_SCOPE_MON, SPECIAL_SCOPE_SYS, SPECIAL_SCOPE_THIS, SPECIAL_SCOPE_BODY, SPECIAL_SCOPE_DEF, SPECIAL_SCOPE_NONE } SpecialScope; const char *SpecialScopeToString(SpecialScope scope); SpecialScope SpecialScopeFromString(const char *scope); /** * @brief augments a scope, expecting corresponding lists of lvals and rvals (implying same length). * in addition to copying them in, also attempts to do one-pass resolution of variables, * and evaluates function calls, and attempts expansion on senior scope members. */ void ScopeAugment(EvalContext *ctx, const Bundle *bp, const Promise *pp, const Rlist *arguments); void ScopeMapBodyArgs(EvalContext *ctx, const Body *body, const Rlist *args); // TODO: namespacing utility functions. there are probably a lot of these floating around, but probably best // leave them until we get a proper symbol table void JoinScopeName(const char *ns, const char *bundle, char scope_out[CF_MAXVARSIZE]); #endif cfengine-3.24.2/libpromises/text2cstring.pl0000755000000000000000000000252615010704253020710 0ustar00rootroot00000000000000#!/usr/bin/perl # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # use warnings; use strict; use Data::Dumper; my $source = shift @ARGV; die "Syntax: $0 SOURCE" unless defined $source; open my $sf, '<', $source or die "Can't read from file '$source': $!"; my @lines = <$sf>; chomp @lines; s/\\/\\\\/g foreach @lines; s/"/\\"/g foreach @lines; @lines = map { " \"$_\\n\"\n" } @lines; print @lines; cfengine-3.24.2/libpromises/constants.c0000644000000000000000000001355215010704253020071 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include const char *const DAY_TEXT[] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", NULL }; const char *const MONTH_TEXT[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", NULL }; const char *const SHIFT_TEXT[] = { "Night", "Morning", "Afternoon", "Evening", NULL }; const char *const CF_AGENTTYPES[] = /* see enum cfagenttype */ { CF_COMMONC, CF_AGENTC, CF_SERVERC, CF_MONITORC, CF_EXECC, CF_RUNC, CF_KEYGEN, CF_HUBC, "", }; // Name and description pairs of all observed monitoring variables const char *const OBSERVABLES[CF_OBSERVABLES][2] = { {"users", "Users with active processes - including system users"}, {"rootprocs", "Sum privileged system processes"}, {"otherprocs", "Sum non-privileged process"}, {"diskfree", "Free disk on / partition"}, {"loadavg", "Kernel load average utilization (sum over cores)"}, {"netbiosns_in", "netbios name lookups (in)"}, {"netbiosns_out", "netbios name lookups (out)"}, {"netbiosdgm_in", "netbios name datagrams (in)"}, {"netbiosdgm_out", "netbios name datagrams (out)"}, {"netbiosssn_in", "Samba/netbios name sessions (in)"}, {"netbiosssn_out", "Samba/netbios name sessions (out)"}, {"imap_in", "imap mail client sessions (in)"}, {"imap_out", "imap mail client sessions (out)"}, {"cfengine_in", "cfengine connections (in)"}, {"cfengine_out", "cfengine connections (out)"}, {"nfsd_in", "nfs connections (in)"}, {"nfsd_out", "nfs connections (out)"}, {"smtp_in", "smtp connections (in)"}, {"smtp_out", "smtp connections (out)"}, {"www_in", "www connections (in)"}, {"www_out", "www connections (out)"}, {"ftp_in", "ftp connections (in)"}, {"ftp_out", "ftp connections (out)"}, {"ssh_in", "ssh connections (in)"}, {"ssh_out", "ssh connections (out)"}, {"wwws_in", "wwws connections (in)"}, {"wwws_out", "wwws connections (out)"}, {"icmp_in", "ICMP packets (in)"}, {"icmp_out", "ICMP packets (out)"}, {"udp_in", "UDP dgrams (in)"}, {"udp_out", "UDP dgrams (out)"}, {"dns_in", "DNS requests (in)"}, {"dns_out", "DNS requests (out)"}, {"tcpsyn_in", "TCP sessions (in)"}, {"tcpsyn_out", "TCP sessions (out)"}, {"tcpack_in", "TCP acks (in)"}, {"tcpack_out", "TCP acks (out)"}, {"tcpfin_in", "TCP finish (in)"}, {"tcpfin_out", "TCP finish (out)"}, {"tcpmisc_in", "TCP misc (in)"}, {"tcpmisc_out", "TCP misc (out)"}, {"webaccess", "Webserver hits"}, {"weberrors", "Webserver errors"}, {"syslog", "New log entries (Syslog)"}, {"messages", "New log entries (messages)"}, {"temp0", "CPU Temperature 0"}, {"temp1", "CPU Temperature 1"}, {"temp2", "CPU Temperature 2"}, {"temp3", "CPU Temperature 3"}, {"cpu", "%CPU utilization (all)"}, {"cpu0", "%CPU utilization 0"}, {"cpu1", "%CPU utilization 1"}, {"cpu2", "%CPU utilization 2"}, {"cpu3", "%CPU utilization 3"}, {"microsoft_ds_in", "Samba/MS_ds name sessions (in)"}, {"microsoft_ds_out", "Samba/MS_ds name sessions (out)"}, {"www_alt_in", "Alternative web service connections (in)"}, {"www_alt_out", "Alternative web client connections (out)"}, {"imaps_in", "encrypted imap mail service sessions (in)"}, {"imaps_out", "encrypted imap mail client sessions (out)"}, {"ldap_in", "LDAP directory service service sessions (in)"}, {"ldap_out", "LDAP directory service client sessions (out)"}, {"ldaps_in", "LDAP directory service service sessions (in)"}, {"ldaps_out", "LDAP directory service client sessions (out)"}, {"mongo_in", "Mongo database service sessions (in)"}, {"mongo_out", "Mongo database client sessions (out)"}, {"mysql_in", "MySQL database service sessions (in)"}, {"mysql_out", "MySQL database client sessions (out)"}, {"postgres_in", "PostgreSQL database service sessions (in)"}, {"postgres_out", "PostgreSQL database client sessions (out)"}, {"ipp_in", "Internet Printer Protocol (in)"}, {"ipp_out", "Internet Printer Protocol (out)"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, {"spare", "unused"}, }; cfengine-3.24.2/libpromises/files_links.h0000644000000000000000000000366215010704253020365 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_LINKS_H #define CFENGINE_FILES_LINKS_H #include #define CF_MAXLINKLEVEL 4 PromiseResult VerifyLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp); PromiseResult VerifyAbsoluteLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp); PromiseResult VerifyRelativeLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp); PromiseResult VerifyHardLink(EvalContext *ctx, char *destination, const char *source, const Attributes *attr, const Promise *pp); bool KillGhostLink(EvalContext *ctx, const char *name, const Attributes *attr, const Promise *pp, PromiseResult *result); bool MakeHardLink(EvalContext *ctx, const char *from, const char *to, const Attributes *attr, const Promise *pp, PromiseResult *result); bool ExpandLinks(char *dest, const char *from, int level, int max_level); #endif cfengine-3.24.2/libpromises/cf3parse_logic.h0000644000000000000000000010174015010704253020742 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* This file is an attempt to clean up cf3parse.y, moving as much C code (logic) as possible out of it, so the actual grammar is more readable. It should only be included from cf3parse.y (!). The advantages of moving the C code out of the grammar are: * Separate overall grammar from noisy details * Less crazy indentation * Better editor support for auto complete / syntax highlighting */ #ifndef CF3_PARSE_LOGIC_H #define CF3_PARSE_LOGIC_H #include "cf3.defs.h" #include "parser.h" #include "parser_helpers.h" #include "parser_state.h" #include "logging.h" #include "fncall.h" #include "rlist.h" #include "item_lib.h" #include "policy.h" #include "mod_files.h" #include "string_lib.h" #include "logic_expressions.h" #include "json-yaml.h" #include "cleanup.h" // FIX: remove #include "syntax.h" #include int yylex(void); extern char *yytext; static bool RelevantBundle(const char *agent, const char *blocktype); static bool LvalWantsBody(char *stype, char *lval); static SyntaxTypeMatch CheckSelection( ParserBlock block, const char *type, const char *name, const char *lval, Rval rval); static SyntaxTypeMatch CheckConstraint( const char *type, const char *lval, Rval rval, const PromiseTypeSyntax *ss); static void fatal_yyerror(const char *s); static void ParseErrorColumnOffset(int column_offset, const char *s, ...) FUNC_ATTR_PRINTF(2, 3); static void ParseError(const char *s, ...) FUNC_ATTR_PRINTF(1, 2); static void ParseWarning(unsigned int warning, const char *s, ...) FUNC_ATTR_PRINTF(2, 3); static void ValidateClassLiteral(const char *class_literal); static bool INSTALL_SKIP = false; static size_t CURRENT_BLOCKID_LINE = 0; static size_t CURRENT_PROMISER_LINE = 0; #define YYMALLOC xmalloc #define P PARSER_STATE #define ParserDebug(...) LogDebug(LOG_MOD_PARSER, __VA_ARGS__) /*****************************************************************/ static void ParseErrorVColumnOffset( int column_offset, const char *s, va_list ap) { char *errmsg = StringVFormat(s, ap); fprintf( stderr, "%s:%d:%d: error: %s\n", P.filename, P.line_no, P.line_pos + column_offset, errmsg); free(errmsg); P.error_count++; /* Current line is not set when syntax error in first line */ if (P.current_line) { fprintf(stderr, "%s\n", P.current_line); fprintf(stderr, "%*s\n", P.line_pos + column_offset, "^"); } if (P.error_count > 12) { fprintf(stderr, "Too many errors\n"); DoCleanupAndExit(EXIT_FAILURE); } } static void ParseErrorColumnOffset(int column_offset, const char *s, ...) { va_list ap; va_start(ap, s); ParseErrorVColumnOffset(column_offset, s, ap); va_end(ap); } static void ParseErrorV(const char *s, va_list ap) { ParseErrorVColumnOffset(0, s, ap); } static void ParseError(const char *s, ...) { va_list ap; va_start(ap, s); ParseErrorV(s, ap); va_end(ap); } static void ParseWarningV(unsigned int warning, const char *s, va_list ap) { if (((P.warnings | P.warnings_error) & warning) == 0) { return; } char *errmsg = StringVFormat(s, ap); const char *warning_str = ParserWarningToString(warning); fprintf( stderr, "%s:%d:%d: warning: %s [-W%s]\n", P.filename, P.line_no, P.line_pos, errmsg, warning_str); fprintf(stderr, "%s\n", P.current_line); fprintf(stderr, "%*s\n", P.line_pos, "^"); free(errmsg); P.warning_count++; if ((P.warnings_error & warning) != 0) { P.error_count++; } if (P.error_count > 12) { fprintf(stderr, "Too many errors\n"); DoCleanupAndExit(EXIT_FAILURE); } } static void ParseWarning(unsigned int warning, const char *s, ...) { va_list ap; va_start(ap, s); ParseWarningV(warning, s, ap); va_end(ap); } void yyerror(const char *str) { ParseError("%s", str); } static void fatal_yyerror(const char *s) { char *sp = yytext; /* Skip quotation mark */ if (sp && *sp == '\"' && sp[1]) { sp++; } fprintf( stderr, "%s: %d,%d: Fatal error during parsing: %s, near token \'%.20s\'\n", P.filename, P.line_no, P.line_pos, s, sp ? sp : "NULL"); DoCleanupAndExit(EXIT_FAILURE); } static bool RelevantBundle(const char *agent, const char *blocktype) { if ((strcmp(agent, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0) || (strcmp(CF_COMMONC, blocktype) == 0)) { return true; } /* Here are some additional bundle types handled by cfAgent */ Item *ip = SplitString("edit_line,edit_xml", ','); if (strcmp(agent, CF_AGENTTYPES[AGENT_TYPE_AGENT]) == 0) { if (IsItemIn(ip, blocktype)) { DeleteItemList(ip); return true; } } DeleteItemList(ip); return false; } static bool LvalWantsBody(char *stype, char *lval) { for (int i = 0; i < CF3_MODULES; i++) { const PromiseTypeSyntax *promise_type_syntax = CF_ALL_PROMISE_TYPES[i]; if (!promise_type_syntax) { continue; } for (int j = 0; promise_type_syntax[j].promise_type != NULL; j++) { const ConstraintSyntax *bs = promise_type_syntax[j].constraints; if (!bs) { continue; } if (strcmp(promise_type_syntax[j].promise_type, stype) != 0) { continue; } for (int l = 0; bs[l].lval != NULL; l++) { if (strcmp(bs[l].lval, lval) == 0) { if (bs[l].dtype == CF_DATA_TYPE_BODY) { return true; } else { return false; } } } } } return false; } static SyntaxTypeMatch CheckSelection( ParserBlock block, const char *type, const char *name, const char *lval, Rval rval) { if (block == PARSER_BLOCK_PROMISE) { const BodySyntax *body_syntax = BodySyntaxGet(block, type); const ConstraintSyntax *constraints = body_syntax->constraints; for (int i = 0; constraints[i].lval != NULL; i++) { if (StringEqual(lval, constraints[i].lval)) { return CheckConstraintTypeMatch( lval, rval, constraints[i].dtype, constraints[i].range.validation_string, 0); } } // Parser should ensure that lval is a valid // attribute, and so we should never get here debug_abort_if_reached(); } assert(block == PARSER_BLOCK_BODY); // Check internal control bodies etc if (strcmp("control", name) == 0) { for (int i = 0; CONTROL_BODIES[i].body_type != NULL; i++) { if (strcmp(type, CONTROL_BODIES[i].body_type) == 0) { const ConstraintSyntax *bs = CONTROL_BODIES[i].constraints; for (int l = 0; bs[l].lval != NULL; l++) { if (strcmp(lval, bs[l].lval) == 0) { if (bs[l].dtype == CF_DATA_TYPE_BODY) { return SYNTAX_TYPE_MATCH_OK; } else if (bs[l].dtype == CF_DATA_TYPE_BUNDLE) { return SYNTAX_TYPE_MATCH_OK; } else { return CheckConstraintTypeMatch( lval, rval, bs[l].dtype, bs[l].range.validation_string, 0); } } } } } } // Now check the functional modules - extra level of indirection for (int i = 0; i < CF3_MODULES; i++) { const PromiseTypeSyntax *promise_type_syntax = CF_ALL_PROMISE_TYPES[i]; if (!promise_type_syntax) { continue; } for (int j = 0; promise_type_syntax[j].promise_type != NULL; j++) { const ConstraintSyntax *bs = promise_type_syntax[j].constraints; if (!bs) { continue; } for (int l = 0; bs[l].lval != NULL; l++) { if (bs[l].dtype == CF_DATA_TYPE_BODY) { const ConstraintSyntax *bs2 = bs[l].range.body_type_syntax->constraints; if (bs2 == NULL || bs2 == (void *) CF_BUNDLE) { continue; } for (int k = 0; bs2[k].dtype != CF_DATA_TYPE_NONE; k++) { /* Either module defined or common */ if (strcmp(promise_type_syntax[j].promise_type, type) == 0 && strcmp(promise_type_syntax[j].promise_type, "*") != 0) { char output[CF_BUFSIZE]; snprintf( output, CF_BUFSIZE, "lval %s belongs to promise type '%s': but this is '%s'\n", lval, promise_type_syntax[j].promise_type, type); yyerror(output); return SYNTAX_TYPE_MATCH_OK; } if (strcmp(lval, bs2[k].lval) == 0) { /* Body definitions will be checked later. */ if (bs2[k].dtype != CF_DATA_TYPE_BODY) { return CheckConstraintTypeMatch( lval, rval, bs2[k].dtype, bs2[k].range.validation_string, 0); } else { return SYNTAX_TYPE_MATCH_OK; } } } } } } } char output[CF_BUFSIZE]; snprintf( output, CF_BUFSIZE, "Constraint lvalue \"%s\" is not allowed in \'%s\' constraint body", lval, type); yyerror(output); return SYNTAX_TYPE_MATCH_OK; // TODO: OK? } static SyntaxTypeMatch CheckConstraint( const char *type, const char *lval, Rval rval, const PromiseTypeSyntax *promise_type_syntax) { assert(promise_type_syntax); if (promise_type_syntax->promise_type != NULL) /* In a bundle */ { if (strcmp(promise_type_syntax->promise_type, type) == 0) { const ConstraintSyntax *bs = promise_type_syntax->constraints; for (int l = 0; bs[l].lval != NULL; l++) { if (strcmp(lval, bs[l].lval) == 0) { /* If we get here we have found the lval and it is valid for this promise_type */ /* For bodies and bundles definitions can be elsewhere, so they are checked in PolicyCheckRunnable(). */ if (bs[l].dtype != CF_DATA_TYPE_BODY && bs[l].dtype != CF_DATA_TYPE_BUNDLE) { return CheckConstraintTypeMatch( lval, rval, bs[l].dtype, bs[l].range.validation_string, 0); } } } } } return SYNTAX_TYPE_MATCH_OK; } static void ValidateClassLiteral(const char *class_literal) { ParseResult res = ParseExpression(class_literal, 0, strlen(class_literal)); if (!res.result) { ParseErrorColumnOffset( res.position - strlen(class_literal), "Syntax error in context string"); } FreeExpression(res.result); } static inline void ParserEndCurrentBlock() { P.offsets.last_id = -1; P.offsets.last_string = -1; P.offsets.last_class_id = -1; if (P.block != PARSER_BLOCK_BUNDLE && P.currentbody != NULL) { P.currentbody->offset.end = P.offsets.current; } if (P.block == PARSER_BLOCK_BUNDLE && P.currentbundle != NULL) { P.currentbundle->offset.end = P.offsets.current; } } // This part of the parser is interesting, to say the least. // While parsing, we try to, opportunistically, do a bunch of // transformations on the right-hand side values (rval) of // promise attributes. For example converting some patterns // to function calls: // @(x) // mergedata(x) // data => "{}" // data => parsejson("{}") // // In some cases, we even try to evaluate the function call, // like parsejson, and if it succeeds (if there are no // unresolved variables) we just insert the resulting data // container directly. static inline void MagicRvalTransformations( const PromiseTypeSyntax *promise_type_syntax) { const char *item = P.rval.item; // convert @(x) to mergedata(x) if (P.rval.type == RVAL_TYPE_SCALAR && (strcmp(P.lval, "data") == 0 || strcmp(P.lval, "template_data") == 0) && strlen(item) > 3 && item[0] == '@' && (item[1] == '(' || item[1] == '{')) { Rlist *synthetic_args = NULL; char *tmp = xstrndup(P.rval.item + 2, strlen(P.rval.item) - 3); RlistAppendScalar(&synthetic_args, tmp); free(tmp); RvalDestroy(P.rval); P.rval = (Rval){FnCallNew("mergedata", synthetic_args), RVAL_TYPE_FNCALL}; } // convert 'json or yaml' to direct container or parsejson(x) // or parseyaml(x) else if ( P.rval.type == RVAL_TYPE_SCALAR && (strcmp(P.lval, "data") == 0 || strcmp(P.lval, "template_data") == 0)) { JsonElement *json = NULL; JsonParseError res; bool json_parse_attempted = false; Buffer *copy = BufferNewFrom(P.rval.item, strlen(P.rval.item)); const char *fname = NULL; if (strlen(P.rval.item) > 3 && strncmp("---", P.rval.item, 3) == 0) { fname = "parseyaml"; // look for unexpanded variables if (strstr(P.rval.item, "$(") == NULL && strstr(P.rval.item, "${") == NULL) { const char *copy_data = BufferData(copy); res = JsonParseYamlString(©_data, &json); json_parse_attempted = true; } } else { fname = "parsejson"; // look for unexpanded variables if (strstr(P.rval.item, "$(") == NULL && strstr(P.rval.item, "${") == NULL) { const char *copy_data = BufferData(copy); res = JsonParse(©_data, &json); json_parse_attempted = true; } } BufferDestroy(copy); if (json_parse_attempted && res != JSON_PARSE_OK) { // Parsing failed, insert fncall so it can be retried // during evaluation } else if ( json != NULL && JsonGetElementType(json) == JSON_ELEMENT_TYPE_PRIMITIVE) { // Parsing failed, insert fncall so it can be retried // during evaluation JsonDestroy(json); json = NULL; } if (fname != NULL) { if (json == NULL) { Rlist *synthetic_args = NULL; RlistAppendScalar(&synthetic_args, P.rval.item); RvalDestroy(P.rval); P.rval = (Rval){FnCallNew(fname, synthetic_args), RVAL_TYPE_FNCALL}; } else { RvalDestroy(P.rval); P.rval = (Rval){json, RVAL_TYPE_CONTAINER}; } } } if (promise_type_syntax != NULL) // NULL for custom promise types { SyntaxTypeMatch err = CheckConstraint( P.currenttype, P.lval, P.rval, promise_type_syntax); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { yyerror(SyntaxTypeMatchToString(err)); } } if (P.rval.type == RVAL_TYPE_SCALAR && (strcmp(P.lval, "ifvarclass") == 0 || strcmp(P.lval, "if") == 0)) { ValidateClassLiteral(P.rval.item); } } static inline void ParserAppendCurrentConstraint() { Constraint *cp = PromiseAppendConstraint( P.currentpromise, P.lval, RvalCopy(P.rval), P.references_body); cp->offset.line = P.line_no; cp->offset.start = P.offsets.last_id; cp->offset.end = P.offsets.current; cp->offset.context = P.offsets.last_class_id; P.currentstype->offset.end = P.offsets.current; } // This function is called for every rval (right hand side value) of every // promise while parsing. The reason why it is so big is because it does a lot // of transformation, for example transforming strings into function calls like // parsejson, and then attempts to resolve those function calls. static inline void ParserHandleBundlePromiseRval() { if (INSTALL_SKIP) { RvalDestroy(P.rval); P.rval = RvalNew(NULL, RVAL_TYPE_NOPROMISEE); return; } if (PolicyHasCustomPromiseType(P.policy, P.currenttype)) { // Definitely custom promise type, just add the constraint and move on MagicRvalTransformations(NULL); ParserAppendCurrentConstraint(); goto cleanup; } const PromiseTypeSyntax *promise_type_syntax = PromiseTypeSyntaxGet(P.blocktype, P.currenttype); const ConstraintSyntax *constraint_syntax = (promise_type_syntax != NULL) ? PromiseTypeSyntaxGetConstraintSyntax(promise_type_syntax, P.lval) : NULL; if (promise_type_syntax == NULL) { // Assume custom promise type, but defined in another policy file MagicRvalTransformations(NULL); ParserAppendCurrentConstraint(); goto cleanup; } else if (constraint_syntax == NULL) { ParseError( "Unknown constraint '%s' in promise type '%s'", P.lval, promise_type_syntax->promise_type); } else { switch (constraint_syntax->status) { case SYNTAX_STATUS_DEPRECATED: ParseWarning( PARSER_WARNING_DEPRECATED, "Deprecated constraint '%s' in promise type '%s'", constraint_syntax->lval, promise_type_syntax->promise_type); // fall through case SYNTAX_STATUS_CUSTOM: // fall through case SYNTAX_STATUS_NORMAL: { MagicRvalTransformations(promise_type_syntax); ParserAppendCurrentConstraint(); } break; case SYNTAX_STATUS_REMOVED: ParseWarning( PARSER_WARNING_REMOVED, "Removed constraint '%s' in promise type '%s'", constraint_syntax->lval, promise_type_syntax->promise_type); break; } } cleanup: RvalDestroy(P.rval); P.rval = RvalNew(NULL, RVAL_TYPE_NOPROMISEE); strcpy(P.lval, "no lval"); RlistDestroy(P.currentRlist); P.currentRlist = NULL; } static inline void ParserBeginBlock(ParserBlock b) { ParserDebug("P:%s:%s\n", ParserBlockString(b), P.blocktype); P.block = b; if (b == PARSER_BLOCK_BUNDLE) { RvalDestroy(P.rval); P.rval = RvalNew(NULL, RVAL_TYPE_NOPROMISEE); } RlistDestroy(P.currentRlist); P.currentRlist = NULL; if (P.currentstring) { free(P.currentstring); } P.currentstring = NULL; strcpy(P.blockid, ""); } // The promise "guard" is a promise type followed by a single colon, // found in bundles. It is called guard because it resembles the // class guards, and all other names I could think of were confusing. // (It doesn't really "guard" anything). static inline void ParserHandlePromiseGuard() { ParserDebug( "\tP:%s:%s:%s promise_type = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currenttype); const PromiseTypeSyntax *promise_type_syntax = PromiseTypeSyntaxGet(P.blocktype, P.currenttype); if (promise_type_syntax) { switch (promise_type_syntax->status) { case SYNTAX_STATUS_DEPRECATED: ParseWarning( PARSER_WARNING_DEPRECATED, "Deprecated promise type '%s' in bundle type '%s'", promise_type_syntax->promise_type, promise_type_syntax->bundle_type); // fall through case SYNTAX_STATUS_CUSTOM: // fall through case SYNTAX_STATUS_NORMAL: if (P.block == PARSER_BLOCK_BUNDLE) { if (!INSTALL_SKIP) { P.currentstype = BundleAppendSection(P.currentbundle, P.currenttype); P.currentstype->offset.line = P.line_no; P.currentstype->offset.start = P.offsets.last_promise_guard_id; } else { P.currentstype = NULL; } } break; case SYNTAX_STATUS_REMOVED: ParseWarning( PARSER_WARNING_REMOVED, "Removed promise type '%s' in bundle type '%s'", promise_type_syntax->promise_type, promise_type_syntax->bundle_type); INSTALL_SKIP = true; break; } } else { // Unrecognized promise type, assume it is custom // no way to know while parsing, let's check later: if (!INSTALL_SKIP) { P.currentstype = BundleAppendSection(P.currentbundle, P.currenttype); P.currentstype->offset.line = P.line_no; P.currentstype->offset.start = P.offsets.last_promise_guard_id; } else { P.currentstype = NULL; } } } // Called at the beginning of the body of the block, i.e. the opening '{' static inline void ParserBeginBlockBody() { const BodySyntax *body_syntax = BodySyntaxGet(P.block, P.blocktype); if (P.block == PARSER_BLOCK_PROMISE && body_syntax != NULL) { P.currentbody = PolicyAppendPromiseBlock( P.policy, P.current_namespace, P.blockid, P.blocktype, P.useargs, P.filename); P.currentbody->offset.line = CURRENT_BLOCKID_LINE; P.currentbody->offset.start = P.offsets.last_block_id; } else if (body_syntax) { INSTALL_SKIP = false; switch (body_syntax->status) { case SYNTAX_STATUS_DEPRECATED: ParseWarning( PARSER_WARNING_DEPRECATED, "Deprecated body '%s' of type '%s'", P.blockid, body_syntax->body_type); // fall through case SYNTAX_STATUS_CUSTOM: // fall through case SYNTAX_STATUS_NORMAL: P.currentbody = PolicyAppendBody( P.policy, P.current_namespace, P.blockid, P.blocktype, P.useargs, P.filename, body_syntax->status == SYNTAX_STATUS_CUSTOM); P.currentbody->offset.line = CURRENT_BLOCKID_LINE; P.currentbody->offset.start = P.offsets.last_block_id; break; case SYNTAX_STATUS_REMOVED: ParseWarning( PARSER_WARNING_REMOVED, "Removed body '%s' of type '%s'", P.blockid, body_syntax->body_type); INSTALL_SKIP = true; break; } } else { ParseError("Invalid body type '%s'", P.blocktype); INSTALL_SKIP = true; } RlistDestroy(P.useargs); P.useargs = NULL; strcpy(P.currentid, ""); } // Called for every Rval (Right hand side value) of attributes // in body blocks static inline void ParserHandleBlockAttributeRval() { assert(P.block == PARSER_BLOCK_BODY || P.block == PARSER_BLOCK_PROMISE); if (!INSTALL_SKIP) { const BodySyntax *body_syntax = BodySyntaxGet(P.block, P.blocktype); assert(body_syntax != NULL); ConstraintSyntax *constraint_syntax; if (body_syntax->status == SYNTAX_STATUS_CUSTOM) { constraint_syntax = xmalloc(sizeof(ConstraintSyntax)); constraint_syntax->status = SYNTAX_STATUS_CUSTOM; } else { constraint_syntax = (ConstraintSyntax *) BodySyntaxGetConstraintSyntax(body_syntax->constraints, P.lval); } if (constraint_syntax) { switch (constraint_syntax->status) { case SYNTAX_STATUS_DEPRECATED: ParseWarning( PARSER_WARNING_DEPRECATED, "Deprecated constraint '%s' in body type '%s'", constraint_syntax->lval, body_syntax->body_type); // fall through case SYNTAX_STATUS_NORMAL: { SyntaxTypeMatch err = CheckSelection( P.block, P.blocktype, P.blockid, P.lval, P.rval); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { yyerror(SyntaxTypeMatchToString(err)); } if (P.rval.type == RVAL_TYPE_SCALAR && (strcmp(P.lval, "ifvarclass") == 0 || strcmp(P.lval, "if") == 0)) { ValidateClassLiteral(P.rval.item); } } // fall through case SYNTAX_STATUS_CUSTOM: { Constraint *cp = NULL; if (P.currentclasses == NULL) { cp = BodyAppendConstraint( P.currentbody, P.lval, RvalCopy(P.rval), "any", P.references_body); } else { cp = BodyAppendConstraint( P.currentbody, P.lval, RvalCopy(P.rval), P.currentclasses, P.references_body); } if (P.currentvarclasses != NULL) { ParseError( "Body attributes can't be put under a variable class '%s'", P.currentvarclasses); } cp->offset.line = P.line_no; cp->offset.start = P.offsets.last_id; cp->offset.end = P.offsets.current; cp->offset.context = P.offsets.last_class_id; break; } case SYNTAX_STATUS_REMOVED: ParseWarning( PARSER_WARNING_REMOVED, "Removed constraint '%s' in promise type '%s'", constraint_syntax->lval, body_syntax->body_type); break; } } if (body_syntax->status == SYNTAX_STATUS_CUSTOM) { free(constraint_syntax); } } else { RvalDestroy(P.rval); P.rval = RvalNew(NULL, RVAL_TYPE_NOPROMISEE); } if (strcmp(P.blockid, "control") == 0 && strcmp(P.blocktype, "file") == 0) { if (strcmp(P.lval, "namespace") == 0) { if (P.rval.type != RVAL_TYPE_SCALAR) { yyerror("namespace must be a constant scalar string"); } else { free(P.current_namespace); P.current_namespace = xstrdup(P.rval.item); } } } RvalDestroy(P.rval); P.rval = RvalNew(NULL, RVAL_TYPE_NOPROMISEE); } static inline void ParserBeginBundleBody() { assert(P.block == PARSER_BLOCK_BUNDLE); if (RelevantBundle(CF_AGENTTYPES[P.agent_type], P.blocktype)) { INSTALL_SKIP = false; } else if (strcmp(CF_AGENTTYPES[P.agent_type], P.blocktype) != 0) { INSTALL_SKIP = true; } if (!INSTALL_SKIP) { P.currentbundle = PolicyAppendBundle( P.policy, P.current_namespace, P.blockid, P.blocktype, P.useargs, P.filename); P.currentbundle->offset.line = CURRENT_BLOCKID_LINE; P.currentbundle->offset.start = P.offsets.last_block_id; } else { P.currentbundle = NULL; } RlistDestroy(P.useargs); P.useargs = NULL; } static inline void ParserHandleQuotedListItem() { RlistAppendScalar((Rlist **) &P.currentRlist, (void *) P.currentstring); FREE_AND_NULL(P.currentstring); } /** * A sanity check that prints a warning if there is a promise without any * actions (i.e., the promise is a no-op). This check is naive and assumes * promises containing any non-common attributes perform actions. It also has * exceptions for promises that perform actions without any attributes. We can * expect false negatives. However, there should not be any false positives. The * motivation for this check is to aid policy writers in detecting semantic * errors early. */ static inline void ParserCheckPromiseLine() { if (P.currentpromise == NULL) { return; } const char *const promise_type = P.currenttype; if (!IsBuiltInPromiseType(promise_type)) { // We leave sanity checking to the custom promise module. return; } // The following promise types does not require any actions static const char *const exceptions[] = { "classes", "commands", "methods", "reports", "insert_lines", "packages", "delete_lines", "build_xpath", "insert_tree" }; static const size_t num_exceptions = sizeof(exceptions) / sizeof(exceptions[0]); if (IsStringInArray(promise_type, exceptions, num_exceptions)) { // This promise type does not require any action attributes. return; } // We don't consider common attributes an actions. static const char *const common_attrs[] = { "action", "classes", "comment", "depends_on", "handle", "if", "meta", "with" }; const Seq *const constraints = P.currentpromise->conlist; const size_t num_constraints = SeqLength(constraints); for (size_t i = 0; i < num_constraints; i++) { const Constraint *const constraint = SeqAt(constraints, i); if (!IsStringInArray(constraint->lval, common_attrs, sizeof(common_attrs) / sizeof(common_attrs[0]))) { // Not in common attributes, we assume it is an action return; } } const char *const promiser = P.currentpromise->promiser; const char *const file = P.filename; const char *const bundle = P.currentbundle->name; size_t line = P.currentpromise->offset.line; ParseWarning(PARSER_WARNING_SANITY_CHECK, "No action requested for %s promise with promiser '%s' in %s:%s close to line %zu", promise_type, promiser, file, bundle, line); } #endif // CF3_PARSE_LOGIC_H cfengine-3.24.2/libpromises/dbm_quick.c0000644000000000000000000002422715010704253020014 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * Implementation using QDBM */ #include #include #include #include #ifdef QDB # include struct DBPriv_ { /* * This mutex controls the access to depot, which is not thread-aware */ pthread_mutex_t lock; /* * This mutex prevents two cursors to be active on depot at same time, as * cursors are internal for QDBM. 'cursor_lock' is always taken before * 'lock' to avoid deadlocks. */ pthread_mutex_t cursor_lock; DEPOT *depot; }; struct DBCursorPriv_ { DBPriv *db; char *curkey; int curkey_size; char *curval; }; /******************************************************************************/ static bool Lock(DBPriv *db) { int ret = pthread_mutex_lock(&db->lock); if (ret != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to lock QDBM database. (pthread_mutex_lock: %s)", GetErrorStr()); return false; } return true; } static void Unlock(DBPriv *db) { int ret = pthread_mutex_unlock(&db->lock); if (ret != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to unlock QDBM database. (pthread_mutex_unlock: %s)", GetErrorStr()); } } static bool LockCursor(DBPriv *db) { int ret = pthread_mutex_lock(&db->cursor_lock); if (ret != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to obtain cursor lock for QDBM database. (pthread_mutex_lock: %s)", GetErrorStr()); return false; } return true; } static void UnlockCursor(DBPriv *db) { int ret = pthread_mutex_unlock(&db->cursor_lock); if (ret != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to release cursor lock for QDBM database. (pthread_mutex_unlock: %s)", GetErrorStr()); } } const char *DBPrivGetFileExtension(void) { return "qdbm"; } void DBPrivSetMaximumConcurrentTransactions(ARG_UNUSED int max_txn) { } DBPriv *DBPrivOpenDB(const char *filename, ARG_UNUSED dbid id) { DBPriv *db = xcalloc(1, sizeof(DBPriv)); pthread_mutex_init(&db->lock, NULL); pthread_mutex_init(&db->cursor_lock, NULL); db->depot = dpopen(filename, DP_OWRITER | DP_OCREAT, -1); if ((db->depot == NULL) && (dpecode == DP_EBROKEN)) { Log(LOG_LEVEL_ERR, "Database '%s' is broken, trying to repair...", filename); if (dprepair(filename)) { Log(LOG_LEVEL_INFO, "Successfully repaired database '%s'", filename); } else { Log(LOG_LEVEL_ERR, "Failed to repair database '%s', recreating...", filename); return DB_PRIV_DATABASE_BROKEN; } db->depot = dpopen(filename, DP_OWRITER | DP_OCREAT, -1); } if (db->depot == NULL) { Log(LOG_LEVEL_ERR, "dpopen: Opening database '%s' failed. (dpopen: %s)", filename, dperrmsg(dpecode)); pthread_mutex_destroy(&db->cursor_lock); pthread_mutex_destroy(&db->lock); free(db); return NULL; } return db; } void DBPrivCloseDB(DBPriv *db) { int ret; if ((ret = pthread_mutex_destroy(&db->lock)) != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Lock is still active during QDBM database handle close. (pthread_mutex_destroy: %s)", GetErrorStr()); } if ((ret = pthread_mutex_destroy(&db->cursor_lock)) != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Cursor lock is still active during QDBM database handle close. (pthread_mutex_destroy: %s)", GetErrorStr()); } if (!dpclose(db->depot)) { Log(LOG_LEVEL_ERR, "Unable to close QDBM database. (dpclose: %s)", dperrmsg(dpecode)); } free(db); } void DBPrivCommit(ARG_UNUSED DBPriv *db) { } bool DBPrivClean(DBPriv *db) { if (!Lock(db)) { return false; } if (!dpiterinit(db->depot)) { Log(LOG_LEVEL_ERR, "Could not initialize QuickDB iterator. (dpiterinit: %s)", dperrmsg(dpecode)); Unlock(db); return false; } char *key = NULL; while((key = dpiternext(db->depot, NULL))) { dpout(db->depot, key, -1); } Unlock(db); return true; } int DBPrivGetDBUsagePercentage(ARG_UNUSED const char *db_path) { Log(LOG_LEVEL_WARNING, "Cannot determine usage of a QuickDB database"); return -1; } bool DBPrivRead(DBPriv *db, const void *key, int key_size, void *dest, size_t dest_size) { if (!Lock(db)) { return false; } if (dpgetwb(db->depot, key, key_size, 0, dest_size, dest) == -1) { // FIXME: distinguish between "entry not found" and "failure to read" Log(LOG_LEVEL_DEBUG, "QDBM DBPrivRead: Could not read '%s', (dpgetwb: %s)", (const char *)key, dperrmsg(dpecode)); Unlock(db); return false; } Unlock(db); return true; } bool DBPrivWrite(DBPriv *db, const void *key, int key_size, const void *value, int value_size) { if (!Lock(db)) { return false; } if (!dpput(db->depot, key, key_size, value, value_size, DP_DOVER)) { char *db_name = dpname(db->depot); Log(LOG_LEVEL_ERR, "Could not write key to DB '%s'. (dpput: %s)", db_name, dperrmsg(dpecode)); free(db_name); Unlock(db); return false; } Unlock(db); return true; } bool DBPrivOverwrite(DBPriv *db, const char *key, int key_size, const void *value, size_t value_size, OverwriteCondition Condition, void *data) { if (!Lock(db)) { return false; } ssize_t cur_val_size = dpvsiz(db->depot, key, key_size); bool exists = (cur_val_size != -1); void *cur_val = NULL; if (exists) { assert(cur_val_size > 0); cur_val = xmalloc((size_t) cur_val_size); if (dpgetwb(db->depot, key, key_size, 0, value_size, cur_val) == -1) { Log(LOG_LEVEL_DEBUG, "QDBM DBPrivRead: Could not read '%s', (dpgetwb: %s)", (const char *)key, dperrmsg(dpecode)); Unlock(db); return false; } } if ((Condition != NULL) && !Condition(cur_val, cur_val_size, data)) { free(cur_val); Unlock(db); return false; } free(cur_val); if (!dpput(db->depot, key, key_size, value, value_size, DP_DOVER)) { char *db_name = dpname(db->depot); Log(LOG_LEVEL_ERR, "Could not write key to DB '%s'. (dpput: %s)", db_name, dperrmsg(dpecode)); free(db_name); Unlock(db); return false; } Unlock(db); return true; } bool DBPrivHasKey(DBPriv *db, const void *key, int key_size) { if (!Lock(db)) { return false; } int ret = dpvsiz(db->depot, key, key_size) != -1; Unlock(db); return ret; } int DBPrivGetValueSize(DBPriv *db, const void *key, int key_size) { if (!Lock(db)) { return false; } int ret = dpvsiz(db->depot, key, key_size); Unlock(db); return ret; } bool DBPrivDelete(DBPriv *db, const void *key, int key_size) { if (!Lock(db)) { return false; } /* dpout returns false both for error and if key is not found */ if (!dpout(db->depot, key, key_size) && dpecode != DP_ENOITEM) { Unlock(db); return false; } Unlock(db); return true; } DBCursorPriv *DBPrivOpenCursor(DBPriv *db) { if (!LockCursor(db)) { return NULL; } if (!Lock(db)) { UnlockCursor(db); return NULL; } if (!dpiterinit(db->depot)) { Log(LOG_LEVEL_ERR, "Could not initialize QuickDB iterator. (dpiterinit: %s)", dperrmsg(dpecode)); Unlock(db); UnlockCursor(db); return NULL; } DBCursorPriv *cursor = xcalloc(1, sizeof(DBCursorPriv)); cursor->db = db; Unlock(db); /* Cursor remains locked */ return cursor; } bool DBPrivAdvanceCursor(DBCursorPriv *cursor, void **key, int *ksize, void **value, int *vsize) { if (!Lock(cursor->db)) { return false; } free(cursor->curkey); free(cursor->curval); cursor->curkey = NULL; cursor->curval = NULL; *key = dpiternext(cursor->db->depot, ksize); if (*key == NULL) { /* Reached the end of database */ Unlock(cursor->db); return false; } *value = dpget(cursor->db->depot, *key, *ksize, 0, -1, vsize); // keep pointers for later free cursor->curkey = *key; cursor->curkey_size = *ksize; cursor->curval = *value; Unlock(cursor->db); return true; } bool DBPrivDeleteCursorEntry(DBCursorPriv *cursor) { return DBPrivDelete(cursor->db, cursor->curkey, cursor->curkey_size); } bool DBPrivWriteCursorEntry(DBCursorPriv *cursor, const void *value, int value_size) { return DBPrivWrite(cursor->db, cursor->curkey, cursor->curkey_size, value, value_size); } void DBPrivCloseCursor(DBCursorPriv *cursor) { DBPriv *db = cursor->db; /* FIXME: communicate the deadlock if happens */ Lock(db); free(cursor->curkey); free(cursor->curval); free(cursor); Unlock(db); /* Cursor lock was obtained in DBPrivOpenCursor */ UnlockCursor(db); } char *DBPrivDiagnose(const char *dbpath) { return StringFormat("Unable to diagnose QuickDB file (not implemented) for '%s'", dbpath); } #endif cfengine-3.24.2/libpromises/sort.c0000644000000000000000000002712315010704253017043 0ustar00rootroot00000000000000/*******************************************************************/ /* The following sort functions are trivial rewrites of merge-sort * implementation by Simon Tatham * copyright 2001 Simon Tatham. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include typedef bool (*LessFn)(void *lhs, void *rhs, void *ctx); typedef void * (*GetNextElementFn)(void *element); typedef void (*PutNextElementFn)(void *element, void *next); static void *Sort(void *list, LessFn less, GetNextElementFn next, PutNextElementFn putnext, void *ctx) { void *p, *q, *e, *tail; int insize, nmerges, psize, qsize, i; if (list == NULL) { return NULL; } insize = 1; while (true) { p = list; list = NULL; tail = NULL; nmerges = 0; /* count number of merges we do in this pass */ while (p) { nmerges++; /* there exists a merge to be done */ /* step `insize' places along from p */ q = p; psize = 0; for (i = 0; i < insize; i++) { psize++; q = next(q); if (!q) { break; } } /* if q hasn't fallen off end, we have two lists to merge */ qsize = insize; /* now we have two lists; merge them */ while ((psize > 0) || ((qsize > 0) && q)) { /* decide whether next element of merge comes from p or q */ if (psize == 0) { /* p is empty; e must come from q. */ e = q; q = next(q); qsize--; } else if ((qsize == 0) || (!q)) { /* q is empty; e must come from p. */ e = p; p = next(p); psize--; } else if (less(p, q, ctx)) { /* First element of p is lower (or same); * e must come from p. */ e = p; p = next(p); psize--; } else { /* First element of q is lower; e must come from q. */ e = q; q = next(q); qsize--; } /* add the next element to the merged list */ if (tail) { putnext(tail, e); } else { list = e; } tail = e; } /* now p has stepped `insize' places along, and q has too */ p = q; } putnext(tail, NULL); /* If we have done only one merge, we're finished. */ if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ { return list; } /* Otherwise repeat, merging lists twice the size */ insize *= 2; } } /* Item* callbacks */ static bool ItemNameLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return strcmp(((Item*)lhs)->name, ((Item*)rhs)->name) < 0; } static bool ItemClassesLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return strcmp(((Item*)lhs)->classes, ((Item*)rhs)->classes) < 0; } static bool ItemCounterMore(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return ((Item*)lhs)->counter > ((Item*)rhs)->counter; } static bool ItemTimeMore(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return ((Item*)lhs)->time > ((Item*)rhs)->time; } static void *ItemGetNext(void *element) { return ((Item*)element)->next; } static void ItemPutNext(void *element, void *next) { ((Item*)element)->next = (Item *)next; } /* Item* sorting */ Item *SortItemListNames(Item *list) { return Sort(list, &ItemNameLess, &ItemGetNext, &ItemPutNext, NULL); } Item *SortItemListClasses(Item *list) { return Sort(list, &ItemClassesLess, &ItemGetNext, &ItemPutNext, NULL); } Item *SortItemListCounters(Item *list) { return Sort(list, &ItemCounterMore, &ItemGetNext, &ItemPutNext, NULL); } Item *SortItemListTimes(Item *list) { return Sort(list, &ItemTimeMore, &ItemGetNext, &ItemPutNext, NULL); } /* Rlist* and String* callbacks */ static bool RlistCustomItemLess(void *lhs_, void *rhs_, void *ctx) { Rlist *lhs = lhs_; Rlist *rhs = rhs_; bool (*cmp)(void *a, void *b) = ctx; return (*cmp)(lhs->val.item, rhs->val.item); } static bool RlistItemLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return strcmp(((Rlist*)lhs)->val.item, ((Rlist*)rhs)->val.item) < 0; } static bool StringItemLess(const char *lhs, const char *rhs, ARG_UNUSED void *ctx) { return strcmp(lhs, rhs) < 0; } static bool StringItemNumberLess(const char *lhs, const char *rhs, ARG_UNUSED void *ctx, bool int_mode) { char remainder[4096]; double left; double right; bool matched_left = sscanf(lhs, "%lf", &left) > 0; bool matched_right = sscanf(rhs, "%lf", &right) > 0; if (!matched_left) { matched_left = sscanf(lhs, "%lf%4095s", &left, remainder) > 0; } if (!matched_right) { matched_right = sscanf(rhs, "%lf%4095s", &right, remainder) > 0; } if (matched_left && matched_right) { if (int_mode) { return ((long int)left) - ((long int)right) < 0; } else { return left - right < 0; } } if (matched_left) { return false; } if (matched_right) { return true; } // neither item matched return StringItemLess(lhs, rhs, ctx); } static bool RlistItemNumberLess(void *lhs, void *rhs, ARG_UNUSED void *ctx, bool int_mode) { return StringItemNumberLess(RlistScalarValue((Rlist*)lhs), RlistScalarValue((Rlist*)rhs), ctx, int_mode); } static bool RlistItemIntLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return RlistItemNumberLess(lhs, rhs, ctx, true); } static bool RlistItemRealLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return RlistItemNumberLess(lhs, rhs, ctx, false); } static bool StringItemIPLess(const char *left_item, const char *right_item, ARG_UNUSED void *ctx) { Buffer *left_buffer = BufferNewFrom(left_item, strlen(left_item)); Buffer *right_buffer = BufferNewFrom(right_item, strlen(right_item)); IPAddress *left = IPAddressNew(left_buffer); IPAddress *right = IPAddressNew(right_buffer); bool matched_left = (left != NULL); bool matched_right = (right != NULL); BufferDestroy(left_buffer); BufferDestroy(right_buffer); if (matched_left && matched_right) { bool less = IPAddressCompareLess(left, right); IPAddressDestroy(&left); IPAddressDestroy(&right); return less; } IPAddressDestroy(&left); IPAddressDestroy(&right); if (matched_left) { return false; } if (matched_right) { return true; } // neither item matched return StringItemLess(left_item, right_item, ctx); } static bool RlistItemIPLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return StringItemIPLess(RlistScalarValue((Rlist*)lhs), RlistScalarValue((Rlist*)rhs), ctx); } static long ParseEtherAddress(const char* input, unsigned char *addr) { if (strlen(input) > 12) { return sscanf(input, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]); } return sscanf(input, "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]); } static bool StringItemMACLess(const char *lhs, const char *rhs, ARG_UNUSED void *ctx) { int bytes = 6; unsigned char left[bytes], right[bytes]; int matched_left = (ParseEtherAddress(lhs, left) == 6); int matched_right = (ParseEtherAddress(rhs, right) == 6);; if (matched_left && matched_right) { int difference = memcmp(left, right, bytes); if (difference != 0) return difference < 0; } if (matched_left) { return false; } if (matched_right) { return true; } // neither item matched return StringItemLess(lhs, rhs, ctx); } static bool RlistItemMACLess(void *lhs, void *rhs, ARG_UNUSED void *ctx) { return StringItemMACLess(RlistScalarValue((Rlist*)lhs), RlistScalarValue((Rlist*)rhs), ctx); } static void *RlistGetNext(void *element) { return ((Rlist*)element)->next; } static void RlistPutNext(void *element, void *next) { ((Rlist*)element)->next = (Rlist *)next; } /* Rlist* sorting */ Rlist *SortRlist(Rlist *list, bool (*CompareItems) ()) { return Sort(list, &RlistCustomItemLess, &RlistGetNext, &RlistPutNext, CompareItems); } Rlist *AlphaSortRListNames(Rlist *list) { return Sort(list, &RlistItemLess, &RlistGetNext, &RlistPutNext, NULL); } Rlist *IntSortRListNames(Rlist *list) { return Sort(list, &RlistItemIntLess, &RlistGetNext, &RlistPutNext, NULL); } Rlist *RealSortRListNames(Rlist *list) { return Sort(list, &RlistItemRealLess, &RlistGetNext, &RlistPutNext, NULL); } Rlist *IPSortRListNames(Rlist *list) { return Sort(list, &RlistItemIPLess, &RlistGetNext, &RlistPutNext, NULL); } Rlist *MACSortRListNames(Rlist *list) { return Sort(list, &RlistItemMACLess, &RlistGetNext, &RlistPutNext, NULL); } bool GenericItemLess(const char *sort_type, void *lhs, void *rhs) { if (strcmp(sort_type, "int") == 0) { return RlistItemNumberLess(lhs, rhs, NULL, true); } else if (strcmp(sort_type, "real") == 0) { return RlistItemNumberLess(lhs, rhs, NULL, false); } else if (strcasecmp(sort_type, "IP") == 0) { return RlistItemIPLess(lhs, rhs, NULL); } else if (strcasecmp(sort_type, "MAC") == 0) { return RlistItemMACLess(lhs, rhs, NULL); } // "lex" return RlistItemLess(lhs, rhs, NULL); } bool GenericStringItemLess(const char *sort_type, const char *lhs, const char *rhs) { if (strcmp(sort_type, "int") == 0) { return StringItemNumberLess(lhs, rhs, NULL, true); } else if (strcmp(sort_type, "real") == 0) { return StringItemNumberLess(lhs, rhs, NULL, false); } else if (strcasecmp(sort_type, "IP") == 0) { return StringItemIPLess(lhs, rhs, NULL); } else if (strcasecmp(sort_type, "MAC") == 0) { return StringItemMACLess(lhs, rhs, NULL); } // "lex" return StringItemLess(lhs, rhs, NULL); } cfengine-3.24.2/libpromises/audit.c0000644000000000000000000000547515010704253017170 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include int PR_KEPT = 0; /* GLOBAL_X */ int PR_REPAIRED = 0; /* GLOBAL_X */ int PR_NOTKEPT = 0; /* GLOBAL_X */ static bool END_AUDIT_REQUIRED = false; /* GLOBAL_X */ void BeginAudit() { END_AUDIT_REQUIRED = true; } void UpdatePromiseCounters(PromiseResult status) { switch (status) { case PROMISE_RESULT_CHANGE: PR_REPAIRED++; break; case PROMISE_RESULT_NOOP: PR_KEPT++; break; case PROMISE_RESULT_WARN: case PROMISE_RESULT_TIMEOUT: case PROMISE_RESULT_FAIL: case PROMISE_RESULT_DENIED: case PROMISE_RESULT_INTERRUPTED: PR_NOTKEPT++; break; default: ProgrammingError("Unexpected status '%c' has been passed to UpdatePromiseCounters", status); } } void EndAudit(const EvalContext *ctx, int background_tasks) { if (!END_AUDIT_REQUIRED) { return; } double total = (double) (PR_KEPT + PR_NOTKEPT + PR_REPAIRED) / 100.0; const char *version = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_VERSION); if (!version) { version = "(not specified)"; } if (total == 0) { Log(LOG_LEVEL_VERBOSE, "Outcome of version '%s', no checks were scheduled", version); return; } else { LogTotalCompliance(version, background_tasks); } } void FatalError(const EvalContext *ctx, char *s, ...) { if (s) { va_list ap; char buf[CF_BUFSIZE] = ""; va_start(ap, s); vsnprintf(buf, CF_BUFSIZE - 1, s, ap); va_end(ap); Log(LOG_LEVEL_ERR, "Fatal CFEngine error: %s", buf); } EndAudit(ctx, 0); /* calling abort would bypass cleanup handlers and trigger subtle bugs */ DoCleanupAndExit(EXIT_FAILURE); } cfengine-3.24.2/libpromises/files_lib.c0000644000000000000000000005456115010704253020012 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include /* MakingChanges(), RecordFailure() */ #include /* PromiseResultUpdate() */ static Item *ROTATED = NULL; /* GLOBAL_X */ /*********************************************************************/ void PurgeItemList(Item **list, char *name) { Item *ip, *copy = NULL; struct stat sb; CopyList(©, *list); for (ip = copy; ip != NULL; ip = ip->next) { if (stat(ip->name, &sb) == -1) { Log(LOG_LEVEL_VERBOSE, "Purging file '%s' from '%s' list as it no longer exists", ip->name, name); DeleteItemLiteral(list, ip->name); } } DeleteItemList(copy); } bool FileWriteOver(char *filename, char *contents) { FILE *fp = safe_fopen_create_perms(filename, "w", CF_PERMS_DEFAULT); if(fp == NULL) { return false; } size_t bytes_to_write = strlen(contents); size_t bytes_written = fwrite(contents, 1, bytes_to_write, fp); bool res = true; if(bytes_written != bytes_to_write) { res = false; } if(fclose(fp) != 0) { res = false; } return res; } /*********************************************************************/ static bool MakeParentDirectoryImpl(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *parentandchild, bool force, bool internal, bool *created, mode_t perms_mode); bool MakeParentDirectory(const char *parentandchild, bool force, bool *created) { /* just use the complex function with no promise info */ return MakeParentDirectoryImpl(NULL, NULL, NULL, NULL, parentandchild, force, false, created, DEFAULTMODE); } bool MakeParentDirectoryPerms(const char *parentandchild, bool force, bool *created, mode_t perms_mode) { return MakeParentDirectoryImpl(NULL, NULL, NULL, NULL, parentandchild, force, false, created, perms_mode); } bool MakeParentInternalDirectory(const char *parentandchild, bool force, bool *created) { /* just use the complex function with no promise info */ return MakeParentDirectoryImpl(NULL, NULL, NULL, NULL, parentandchild, force, true, created, DEFAULTMODE); } bool MakeParentDirectoryForPromise(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *parentandchild, bool force, bool *created, const mode_t perms_mode) { return MakeParentDirectoryImpl(ctx, pp, attr, result, parentandchild, force, false, created, perms_mode); } static bool MakeParentDirectoryImpl(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *parentandchild, bool force, bool internal, bool *created, mode_t perms_mode) { char *sp; char currentpath[CF_BUFSIZE]; char pathbuf[CF_BUFSIZE]; struct stat statbuf; mode_t mask; int rootlen; const char *changes_parentandchild = parentandchild; if (!internal && ChrootChanges()) { changes_parentandchild = ToChangesChroot(parentandchild); } const bool have_promise_info = ((ctx != NULL) && (pp != NULL) && (attr != NULL) && (result != NULL)); if (created != NULL) { *created = false; } #ifdef __APPLE__ /* Keeps track of if dealing w. resource fork */ int rsrcfork; rsrcfork = 0; char *tmpstr; #endif Log(LOG_LEVEL_DEBUG, "Trying to create a parent directory%s for: %s", force ? " (force applied)" : "", parentandchild); if (!IsAbsoluteFileName(parentandchild)) { Log(LOG_LEVEL_ERR, "Will not create directories for a relative filename: %s", parentandchild); return false; } strlcpy(pathbuf, changes_parentandchild, CF_BUFSIZE); /* local copy */ #ifdef __APPLE__ if (strstr(pathbuf, _PATH_RSRCFORKSPEC) != NULL) { rsrcfork = 1; } #endif /* skip link name */ sp = (char *) LastFileSeparator(pathbuf); /* de-constify */ if (sp == NULL) { sp = pathbuf; } *sp = '\0'; DeleteSlash(pathbuf); if (lstat(pathbuf, &statbuf) != -1) { if (S_ISLNK(statbuf.st_mode)) { Log(LOG_LEVEL_VERBOSE, "'%s' is a symbolic link, not a directory", pathbuf); } if (force) /* force in-the-way directories aside */ { struct stat dir; stat(pathbuf, &dir); /* If the target directory exists as a directory, no problem. */ /* If the target directory exists but is not a directory, then * rename it to ".cf-moved": */ if (!S_ISDIR(dir.st_mode)) { struct stat sbuf; strcpy(currentpath, pathbuf); DeleteSlash(currentpath); /* TODO overflow check! */ strlcat(currentpath, ".cf-moved", sizeof(currentpath)); Log(LOG_LEVEL_VERBOSE, "Moving obstructing file/link %s to %s to make directory", pathbuf, currentpath); if (have_promise_info && !MakingChanges(ctx, pp, attr, result, "move obstructing file/link '%s' to '%s' to make directories for '%s'", pathbuf, currentpath, parentandchild)) { return true; } /* Remove possibly pre-existing ".cf-moved" backup object. */ if (lstat(currentpath, &sbuf) != -1) { if (S_ISDIR(sbuf.st_mode)) /* directory */ { if (!DeleteDirectoryTree(currentpath)) { Log(LOG_LEVEL_WARNING, "Failed to remove directory '%s' while trying to remove a backup", currentpath); } } else /* not a directory */ { if (unlink(currentpath) == -1) { Log(LOG_LEVEL_WARNING, "Couldn't remove file/link '%s' while trying to remove a backup" " (unlink: %s)", currentpath, GetErrorStr()); } } } /* And then rename the current object to ".cf-moved". */ if (rename(pathbuf, currentpath) == -1) { if (have_promise_info) { RecordFailure(ctx, pp, attr, "Couldn't rename '%s' to .cf-moved (rename: %s)", pathbuf, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { Log(LOG_LEVEL_ERR, "Couldn't rename '%s' to .cf-moved (rename: %s)", pathbuf, GetErrorStr()); } return false; } else if (have_promise_info) { RecordChange(ctx, pp, attr, "Moved obstructing file/link '%s' to '%s' to make directories for '%s'", pathbuf, currentpath, parentandchild); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } } else { if (!S_ISLNK(statbuf.st_mode) && !S_ISDIR(statbuf.st_mode)) { if (have_promise_info) { RecordFailure(ctx, pp, attr, "The object '%s' is not a directory." " Cannot make a new directory without deleting it.", pathbuf); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { Log(LOG_LEVEL_ERR, "The object '%s' is not a directory." " Cannot make a new directory without deleting it.", pathbuf); } return false; } } } /* Now we make directories descending from the root folder down to the leaf */ currentpath[0] = '\0'; rootlen = RootDirLength(changes_parentandchild); /* currentpath is not NULL terminated on purpose! */ strncpy(currentpath, changes_parentandchild, rootlen); for (size_t z = rootlen; changes_parentandchild[z] != '\0'; z++) { const char c = changes_parentandchild[z]; /* Copy up to the next separator. */ if (!IsFileSep(c)) { currentpath[z] = c; continue; } const char path_file_separator = c; currentpath[z] = '\0'; /* currentpath is complete path for each of the parent directories. */ if (currentpath[0] == '\0') { /* We are at dir "/" of an absolute path, no need to create. */ } /* WARNING: on Windows stat() fails if path has a trailing slash! */ else if (stat(currentpath, &statbuf) == -1) { if (!have_promise_info || MakingChanges(ctx, pp, attr, result, "make directory '%s' for '%s'", currentpath, parentandchild)) { mask = umask(0); if (mkdir(currentpath, perms_mode) == -1) { if (errno != EEXIST) { if (have_promise_info) { RecordFailure(ctx, pp, attr, "Failed to make directory: %s (mkdir: %s)", currentpath, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { Log(LOG_LEVEL_ERR, "Failed to make directory: %s (mkdir: %s)", currentpath, GetErrorStr()); } umask(mask); return false; } } else { if (created != NULL) { *created = true; } } umask(mask); } } else { if (!S_ISDIR(statbuf.st_mode)) { #ifdef __APPLE__ /* Ck if rsrc fork */ if (rsrcfork) { tmpstr = xmalloc(CF_BUFSIZE); strlcpy(tmpstr, currentpath, CF_BUFSIZE); strncat(tmpstr, _PATH_FORKSPECIFIER, CF_BUFSIZE); /* CFEngine removed terminating slashes */ DeleteSlash(tmpstr); if (strncmp(tmpstr, pathbuf, CF_BUFSIZE) == 0) { free(tmpstr); return true; } free(tmpstr); } #endif if (have_promise_info) { RecordFailure(ctx, pp, attr, "Cannot make %s - %s is not a directory!", pathbuf, currentpath); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { Log(LOG_LEVEL_ERR, "Cannot make %s - %s is not a directory!", pathbuf, currentpath); } return false; } } currentpath[z] = path_file_separator; } Log(LOG_LEVEL_DEBUG, "Directory for '%s' exists. Okay", parentandchild); return true; } bool LoadFileAsItemList(Item **liststart, const char *file, EditDefaults edits, bool only_checks) { { struct stat statbuf; if (stat(file, &statbuf) == -1) { Log(LOG_LEVEL_VERBOSE, "The proposed file '%s' could not be loaded. (stat: %s)", file, GetErrorStr()); return false; } if (edits.maxfilesize != 0 && statbuf.st_size > edits.maxfilesize) { Log(LOG_LEVEL_INFO, "File '%s' is bigger than the edit limit. max_file_size = %jd > %d bytes", file, (intmax_t) statbuf.st_size, edits.maxfilesize); return false; } if (!S_ISREG(statbuf.st_mode)) { Log(LOG_LEVEL_INFO, "%s is not a plain file", file); return false; } } if (only_checks) { /* Checks done and none of them failed and returned we can just return * true here. */ return true; } FILE *fp = safe_fopen(file, "rt"); if (!fp) { Log(LOG_LEVEL_INFO, "Couldn't read file '%s' for editing. (fopen: %s)", file, GetErrorStr()); return false; } Buffer *concat = BufferNew(); size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); bool result = true; for (;;) { ssize_t num_read = CfReadLine(&line, &line_size, fp); if (num_read == -1) { if (!feof(fp)) { Log(LOG_LEVEL_ERR, "Unable to read contents of file: %s (fread: %s)", file, GetErrorStr()); result = false; } break; } if (edits.joinlines && *(line + strlen(line) - 1) == '\\') { *(line + strlen(line) - 1) = '\0'; BufferAppend(concat, line, num_read); } else { BufferAppend(concat, line, num_read); if (!feof(fp) || (BufferSize(concat) > 0)) { AppendItem(liststart, BufferData(concat), NULL); } } BufferClear(concat); } free(line); BufferDestroy(concat); fclose(fp); return result; } bool TraverseDirectoryTreeInternal(const char *base_path, const char *current_path, int (*callback)(const char *, const struct stat *, void *), void *user_data) { Dir *dirh = DirOpen(base_path); if (!dirh) { if (errno == ENOENT) { return true; } Log(LOG_LEVEL_INFO, "Unable to open directory '%s' during traversal of directory tree '%s' (opendir: %s)", current_path, base_path, GetErrorStr()); return false; } bool failed = false; for (const struct dirent *dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, "..")) { continue; } char sub_path[CF_BUFSIZE]; snprintf(sub_path, CF_BUFSIZE, "%s" FILE_SEPARATOR_STR "%s", current_path, dirp->d_name); struct stat lsb; if (lstat(sub_path, &lsb) == -1) { if (errno == ENOENT) { /* File disappeared on its own */ continue; } Log(LOG_LEVEL_VERBOSE, "Unable to stat file '%s' during traversal of directory tree '%s' (lstat: %s)", current_path, base_path, GetErrorStr()); failed = true; } else { if (S_ISDIR(lsb.st_mode)) { if (!TraverseDirectoryTreeInternal(base_path, sub_path, callback, user_data)) { failed = true; } } else { if (callback(sub_path, &lsb, user_data) == -1) { failed = true; } } } } DirClose(dirh); return !failed; } bool TraverseDirectoryTree(const char *path, int (*callback)(const char *, const struct stat *, void *), void *user_data) { return TraverseDirectoryTreeInternal(path, path, callback, user_data); } typedef struct { unsigned char buffer[1024]; const char **extensions_filter; EVP_MD_CTX *crypto_context; unsigned char **digest; } HashDirectoryTreeState; int HashDirectoryTreeCallback(const char *filename, ARG_UNUSED const struct stat *sb, void *user_data) { HashDirectoryTreeState *state = user_data; bool ignore = true; for (size_t i = 0; state->extensions_filter[i]; i++) { if (StringEndsWith(filename, state->extensions_filter[i])) { ignore = false; break; } } if (ignore) { return 0; } FILE *file = fopen(filename, "rb"); if (!file) { Log(LOG_LEVEL_ERR, "Cannot open file for hashing '%s'. (fopen: %s)", filename, GetErrorStr()); return -1; } size_t len = 0; char buffer[1024]; while ((len = fread(buffer, 1, 1024, file))) { EVP_DigestUpdate(state->crypto_context, state->buffer, len); } fclose(file); return 0; } bool HashDirectoryTree(const char *path, const char **extensions_filter, EVP_MD_CTX *crypto_context) { HashDirectoryTreeState state; memset(state.buffer, 0, 1024); state.extensions_filter = extensions_filter; state.crypto_context = crypto_context; return TraverseDirectoryTree(path, HashDirectoryTreeCallback, &state); } void RotateFiles(const char *name, int number) { int i, fd; struct stat statbuf; char from[CF_BUFSIZE], to[CF_BUFSIZE]; if (IsItemIn(ROTATED, name)) { return; } PrependItem(&ROTATED, name, NULL); if (stat(name, &statbuf) == -1) { Log(LOG_LEVEL_VERBOSE, "No access to file %s", name); return; } for (i = number - 1; i > 0; i--) { snprintf(from, CF_BUFSIZE, "%s.%d", name, i); snprintf(to, CF_BUFSIZE, "%s.%d", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.gz", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.gz", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.Z", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.Z", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.bz", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.bz", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } snprintf(from, CF_BUFSIZE, "%s.%d.bz2", name, i); snprintf(to, CF_BUFSIZE, "%s.%d.bz2", name, i + 1); if (rename(from, to) == -1) { Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from); } } snprintf(to, CF_BUFSIZE, "%s.1", name); if (CopyRegularFileDisk(name, to) == false) { Log(LOG_LEVEL_DEBUG, "Copy failed in RotateFiles '%s' -> '%s'", name, to); return; } safe_chmod(to, statbuf.st_mode); if (safe_chown(to, statbuf.st_uid, statbuf.st_gid)) { UnexpectedError("Failed to chown %s", to); } safe_chmod(name, 0600); /* File must be writable to empty .. */ if ((fd = safe_creat(name, statbuf.st_mode)) == -1) { Log(LOG_LEVEL_ERR, "Failed to create new '%s' in disable(rotate). (create: %s)", name, GetErrorStr()); } else { if (safe_chown(name, statbuf.st_uid, statbuf.st_gid)) /* NT doesn't have fchown */ { UnexpectedError("Failed to chown '%s'", name); } fchmod(fd, statbuf.st_mode); close(fd); } } #ifndef __MINGW32__ void CreateEmptyFile(char *name) { if (unlink(name) == -1) { if (errno != ENOENT) { Log(LOG_LEVEL_DEBUG, "Unable to remove existing file '%s'. (unlink: %s)", name, GetErrorStr()); } } int tempfd = safe_open(name, O_CREAT | O_EXCL | O_WRONLY); if (tempfd < 0) { Log(LOG_LEVEL_ERR, "Couldn't open a file '%s'. (open: %s)", name, GetErrorStr()); } close(tempfd); } #endif cfengine-3.24.2/libpromises/unix.c0000644000000000000000000003431715010704253017042 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #ifdef HAVE_SYS_UIO_H # include #endif #ifndef __MINGW32__ /* Max size of the 'passwd' string in the getpwuid_r() function, * man:getpwuid_r(3) says that this value "Should be more than enough". */ #define GETPW_R_SIZE_MAX 16384 #define GETGR_R_SIZE_MAX 16384 /* same for group name */ static bool IsProcessRunning(pid_t pid); void ProcessSignalTerminate(pid_t pid) { if(!IsProcessRunning(pid)) { return; } if(kill(pid, SIGINT) == -1) { Log(LOG_LEVEL_ERR, "Could not send SIGINT to pid '%jd'. (kill: %s)", (intmax_t)pid, GetErrorStr()); } sleep(1); if (kill(pid, 0) != 0) { /* can no longer send signals to the process => it's dead now */ return; } if(kill(pid, SIGTERM) == -1) { Log(LOG_LEVEL_ERR, "Could not send SIGTERM to pid '%jd'. (kill: %s)", (intmax_t)pid, GetErrorStr()); } sleep(5); if (kill(pid, 0) != 0) { /* can no longer send signals to the process => it's dead now */ return; } if(kill(pid, SIGKILL) == -1) { Log(LOG_LEVEL_ERR, "Could not send SIGKILL to pid '%jd'. (kill: %s)", (intmax_t)pid, GetErrorStr()); } sleep(1); } /*************************************************************/ static bool IsProcessRunning(pid_t pid) { int res = kill(pid, 0); if(res == 0) { return true; } if(res == -1 && errno == ESRCH) { return false; } Log(LOG_LEVEL_ERR, "Failed checking for process existence. (kill: %s)", GetErrorStr()); return false; } /*************************************************************/ bool IsExecutable(const char *file) { struct stat sb; gid_t grps[NGROUPS]; int n; if (stat(file, &sb) == -1) { Log(LOG_LEVEL_ERR, "Proposed executable file '%s' doesn't exist", file); return false; } if (sb.st_mode & 02) { Log(LOG_LEVEL_ERR, "SECURITY ALERT: promised executable '%s' is world writable! ", file); Log(LOG_LEVEL_ERR, "SECURITY ALERT: CFEngine will not execute this - requires human inspection"); return false; } if ((getuid() == sb.st_uid) || (getuid() == 0)) { if (sb.st_mode & 0100) { return true; } } else if (getgid() == sb.st_gid) { if (sb.st_mode & 0010) { return true; } } else { if (sb.st_mode & 0001) { return true; } if ((n = getgroups(NGROUPS, grps)) > 0) { int i; for (i = 0; i < n; i++) { if (grps[i] == sb.st_gid) { if (sb.st_mode & 0010) { return true; } } } } } return false; } bool ShellCommandReturnsZero(const char *command, ShellType shell) { int status; pid_t pid; if (shell == SHELL_TYPE_POWERSHELL) { Log(LOG_LEVEL_ERR, "Powershell is only supported on Windows"); return false; } if ((pid = fork()) < 0) { Log(LOG_LEVEL_ERR, "Failed to fork new process: %s", command); return false; } else if (pid == 0) /* child */ { ALARM_PID = -1; if (shell == SHELL_TYPE_USE) { if (execl(SHELL_PATH, "sh", "-c", command, NULL) == -1) { Log(LOG_LEVEL_ERR, "Command '%s' failed. (execl: %s)", command, GetErrorStr()); exit(EXIT_FAILURE); /* OK since this is a forked proc and no registered cleanup functions */ } } else { char **argv = ArgSplitCommand(command, NULL); int devnull; if (LogGetGlobalLevel() < LOG_LEVEL_INFO) { if ((devnull = open("/dev/null", O_WRONLY)) == -1) { Log(LOG_LEVEL_ERR, "Command '%s' failed. (open: %s)", command, GetErrorStr()); exit(EXIT_FAILURE); /* OK since this is a forked proc and no registered cleanup functions */ } if (dup2(devnull, STDOUT_FILENO) == -1 || dup2(devnull, STDERR_FILENO) == -1) { Log(LOG_LEVEL_ERR, "Command '%s' failed. (dup2: %s)", command, GetErrorStr()); exit(EXIT_FAILURE); /* OK since this is a forked proc and no registered cleanup functions */ } close(devnull); } if (execv(argv[0], argv) == -1) { Log(LOG_LEVEL_ERR, "Command '%s' failed. (execv: %s)", argv[0], GetErrorStr()); exit(EXIT_FAILURE); /* OK since this is a forked proc and no registered cleanup functions */ } } } else /* parent */ { ALARM_PID = pid; while (waitpid(pid, &status, 0) < 0) { if (errno != EINTR) { return false; } } return (WEXITSTATUS(status) == 0); } return false; } /*************************************************************/ static bool GetUserGroupInfoFromGetent(const char *type, const char *query, char *name, size_t name_size, uintmax_t *id, LogLevel error_log_level) { struct stat sb; char* getent_bin; if (stat("/bin/getent", &sb) == 0) { getent_bin = "/bin/getent"; } else { getent_bin = "/usr/bin/getent"; } char buf[CF_BUFSIZE]; NDEBUG_UNUSED int print_ret = snprintf(buf, sizeof(buf), "%s %s %s", getent_bin, type, query); assert(print_ret < sizeof(buf)); FILE *out = cf_popen(buf, "r", OUTPUT_SELECT_STDOUT); size_t offset = 0; size_t n_read; while ((n_read = fread(buf + offset, 1, sizeof(buf) - offset, out)) > 0) { offset += n_read; } buf[offset] = '\0'; if (!feof(out)) { Log(error_log_level, "Failed to read output from 'getent %s %s'", type, query); cf_pclose(out); return false; } int ec = cf_pclose(out); if (ec == 2) { /* not found */ return false; } else if (ec != 0) { Log(error_log_level, "Failed to get information about '%s %s' using getent", type, query); return false; } char *nl = strchr(buf, '\n'); if ((nl != NULL) && (nl < buf + offset) && (strchr(nl + 1, '\n') != NULL)) { Log(error_log_level, "Multiple results from 'getent %s %s'", type, query); return false; } /* The format is: * name:password:id:... * (just like /etc/passwd and /etc/group) */ char *next_colon = strchr(buf, ':'); if (next_colon == NULL) { Log(error_log_level, "Invalid data from 'getent %s %s': %s", type, query, buf); return false; } *next_colon = '\0'; if (name != NULL) { size_t ret = strlcpy(name, buf, name_size); assert(ret < name_size); if (ret >= name_size) { /* This should never happen, but if it does, it's always an error */ Log(LOG_LEVEL_ERR, "Failed to extract info from 'getent %s %s', buffer too small", type, query); return false; } } if (id == NULL) { /* We are done. */ return true; } /* just skip the next field (password) */ next_colon = strchr(next_colon + 1, ':'); if (next_colon == NULL) { Log(error_log_level, "Invalid data from 'getent %s %s': %s", type, query, buf); return false; } *next_colon = '\0'; char *id_start = next_colon + 1; next_colon = strchr(id_start, ':'); if (next_colon == NULL) { Log(error_log_level, "Invalid data from 'getent %s %s': %s", type, query, buf); return false; } *next_colon = '\0'; int n_scanned = sscanf(id_start, "%ju", id); if (n_scanned != 1) { Log(error_log_level, "Failed to extract info from 'getent %s %s': unexpected ID data '%s'", type, query, buf); return false; } return true; } bool GetUserName(uid_t uid, char *user_name_buf, size_t buf_size, LogLevel error_log_level) { char buf[GETPW_R_SIZE_MAX] = {0}; struct passwd pwd; struct passwd *result; int ret = getpwuid_r(uid, &pwd, buf, GETPW_R_SIZE_MAX, &result); if (result == NULL) { char uid_str[32]; /* len("%d" % (2**64 - 1)) == 20 */ NDEBUG_UNUSED int print_ret = snprintf(uid_str, sizeof(uid_str), "%ju", (uintmax_t) uid); assert(print_ret < sizeof(uid_str)); if (GetUserGroupInfoFromGetent("passwd", uid_str, user_name_buf, buf_size, NULL, error_log_level)) { /* Found by getent. */ return true; } else { Log(error_log_level, "Could not get user name for uid %ju, (getpwuid: %s)", (uintmax_t) uid, (ret == 0) ? "not found" : GetErrorStrFromCode(ret)); return false; } } if ((user_name_buf != NULL) && (buf_size > 0)) { ret = strlcpy(user_name_buf, result->pw_name, buf_size); assert(ret < buf_size); if (ret >= buf_size) { /* Should never happen, but if it does, it's definitely an error. */ Log(LOG_LEVEL_ERR, "Failed to get user name for uid %ju (buffer too small)", (uintmax_t) uid); return false; } } return true; } bool GetCurrentUserName(char *userName, int userNameLen) { memset(userName, 0, userNameLen); bool success = GetUserName(getuid(), userName, userNameLen, LOG_LEVEL_ERR); if (!success) { strlcpy(userName, "UNKNOWN", userNameLen); } return success; } bool GetGroupName(gid_t gid, char *group_name_buf, size_t buf_size, LogLevel error_log_level) { char buf[GETGR_R_SIZE_MAX] = {0}; struct group grp; struct group *result; int ret = getgrgid_r(gid, &grp, buf, GETGR_R_SIZE_MAX, &result); if (result == NULL) { char gid_str[32]; /* len("%d" % (2**64 - 1)) == 20 */ NDEBUG_UNUSED int print_ret = snprintf(gid_str, sizeof(gid_str), "%ju", (uintmax_t) gid); assert(print_ret < sizeof(gid_str)); if (GetUserGroupInfoFromGetent("group", gid_str, group_name_buf, buf_size, NULL, error_log_level)) { /* Found by getent. */ return true; } else { Log(error_log_level, "Could not get group name for gid %ju, (getgrgid: %s)", (uintmax_t) gid, (ret == 0) ? "not found" : GetErrorStrFromCode(ret)); return false; } } if ((group_name_buf != NULL) && (buf_size > 0)) { ret = strlcpy(group_name_buf, result->gr_name, buf_size); assert(ret < buf_size); if (ret >= buf_size) { /* Should never happen, but if it does, it's definitely an error. */ Log(LOG_LEVEL_ERR, "Failed to get group name for gid %ju (buffer too small)", (uintmax_t) gid); return false; } } return true; } bool GetUserID(const char *user_name, uid_t *uid, LogLevel error_log_level) { char buf[GETPW_R_SIZE_MAX] = {0}; struct passwd pwd; struct passwd *result; int ret = getpwnam_r(user_name, &pwd, buf, GETPW_R_SIZE_MAX, &result); if (result == NULL) { uintmax_t tmp; if (GetUserGroupInfoFromGetent("passwd", user_name, NULL, 0, &tmp, error_log_level)) { /* Found by getent. */ if (uid != NULL) { *uid = (uid_t) tmp; } return true; } else { Log(error_log_level, "Could not get UID for user '%s', (getpwnam: %s)", user_name, (ret == 0) ? "not found" : GetErrorStrFromCode(ret)); return false; } } if (uid != NULL) { *uid = result->pw_uid; } return true; } bool GetGroupID(const char *group_name, gid_t *gid, LogLevel error_log_level) { char buf[GETGR_R_SIZE_MAX] = {0}; struct group grp; struct group *result; int ret = getgrnam_r(group_name, &grp, buf, GETGR_R_SIZE_MAX, &result); if (result == NULL) { uintmax_t tmp; if (GetUserGroupInfoFromGetent("group", group_name, NULL, 0, &tmp, error_log_level)) { /* Found by getent. */ if (gid != NULL) { *gid = (gid_t) tmp; } return true; } else { Log(error_log_level, "Could not get GID for group '%s', (getgrnam: %s)", group_name, (ret == 0) ? "not found" : GetErrorStrFromCode(ret)); return false; } } if (gid != NULL) { *gid = result->gr_gid; } return true; } #endif /* !__MINGW32__ */ cfengine-3.24.2/libpromises/mod_users.h0000644000000000000000000000216415010704253020057 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_USERS_H #define CFENGINE_MOD_USERS_H #include extern const PromiseTypeSyntax CF_USERS_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/files_operators.h0000644000000000000000000000325215010704253021256 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_OPERATORS_H #define CFENGINE_FILES_OPERATORS_H #include #include bool MoveObstruction(EvalContext *ctx, char *from, const Attributes *attr, const Promise *pp, PromiseResult *result); typedef bool (*SaveCallbackFn)(const char *dest_filename, void *param, NewLineMode new_line_mode); bool SaveAsFile(SaveCallbackFn callback, void *param, const char *file, const Attributes *a, NewLineMode new_line_mode); bool SaveItemListAsFile(Item *liststart, const char *file, const Attributes *a, NewLineMode new_line_mode); bool CompareToFile(EvalContext *ctx, const Item *liststart, const char *file, const Attributes *a, const Promise *pp, PromiseResult *result); #endif cfengine-3.24.2/libpromises/exec_tools.h0000644000000000000000000000336315010704253020225 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_EXEC_TOOLS_H #define CFENGINE_EXEC_TOOLS_H #include #include #include // OutputSelect bool IsExecutable(const char *file); bool ShellCommandReturnsZero(const char *command, ShellType shell); bool GetExecOutput(const char *command, char **buffer, size_t *buffer_size, ShellType shell, OutputSelect output_select, int *ret_out); void ActAsDaemon(); void ArgGetExecutableAndArgs(const char *comm, char **exec, char **args); /** * Create a argument list as expected by execv(3) * @param command is split on spaces, unless quoted * @param arglist is not split (can have embedded spaces) * @return null-terminated argument list */ char **ArgSplitCommand(const char *command, const Seq *arglist); void ArgFree(char **args); #endif cfengine-3.24.2/libpromises/matching.c0000644000000000000000000002401015010704253017636 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include /* CompileRegex,StringMatchFull */ #include /* Pure, non-thread-safe */ static char *FirstBackReference(Regex *regex, const char *teststring) { static char backreference[CF_BUFSIZE]; /* GLOBAL_R, no initialization needed */ memset(backreference, 0, CF_BUFSIZE); pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(regex, NULL); int result = pcre2_match(regex, (PCRE2_SPTR) teststring, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); /* pcre2_match() returns the highest capture group number + 1, i.e. 1 means * a match with 0 capture groups. 0 means the vector of offsets is small, * negative numbers are errors (incl. no match). */ if (result > 0) { uint32_t num_pairs = pcre2_get_ovector_count(match_data); if (num_pairs <= 1) { /* There was no match */ strlcpy(backreference, "CF_NOMATCH", CF_MAXVARSIZE); pcre2_match_data_free(match_data); RegexDestroy(regex); return backreference; } size_t *ovector = pcre2_get_ovector_pointer(match_data); /* ovector[0] and ovector[1] are for the start and end of the whole * match, the capture groups follow in [2] and [3], etc. */ const char *backref_start = teststring + ovector[2]; size_t backref_len = ovector[3] - ovector[2]; if (backref_len < CF_MAXVARSIZE) { strncpy(backreference, backref_start, backref_len); } } pcre2_match_data_free(match_data); RegexDestroy(regex); return backreference; } char *ExtractFirstReference(const char *regexp, const char *teststring) { char *backreference; if ((regexp == NULL) || (teststring == NULL)) { return ""; } Regex *rx = CompileRegex(regexp); if (rx == NULL) { return ""; } backreference = FirstBackReference(rx, teststring); if (strlen(backreference) == 0) { strlcpy(backreference, "CF_NOMATCH", CF_MAXVARSIZE); } return backreference; } bool IsRegex(const char *str) { const char *sp; bool ret = false; enum { r_norm, r_norepeat, r_literal } special = r_norepeat; int bracket = 0; int paren = 0; /* Try to see when something is intended as a regular expression */ for (sp = str; *sp != '\0'; sp++) { if (special == r_literal) { special = r_norm; continue; } else if (*sp == '\\') { special = r_literal; continue; } else if (bracket && (*sp != ']')) { if (*sp == '[') { return false; } continue; } switch (*sp) { case '^': special = (sp == str) ? r_norepeat : r_norm; break; case '*': case '+': if (special == r_norepeat) { return false; } special = r_norepeat; ret = true; break; case '[': special = r_norm; bracket++; ret = true; break; case ']': if (bracket == 0) { return false; } bracket = 0; special = r_norm; break; case '(': special = r_norepeat; paren++; break; case ')': special = r_norm; paren--; if (paren < 0) { return false; } break; case '|': special = r_norepeat; if (paren > 0) { ret = true; } break; default: special = r_norm; } } if ((bracket != 0) || (paren != 0) || (special == r_literal)) { return false; } else { return ret; } } bool IsPathRegex(const char *str) { bool result = IsRegex(str); if (result) { int s = 0, r = 0; /* Count square and round brackets. */ for (const char *sp = str; *sp != '\0'; sp++) { switch (*sp) { case '[': s++; break; case ']': s--; break; case '(': r++; break; case ')': r--; break; default: if (*sp == FILE_SEPARATOR && (r || s)) { Log(LOG_LEVEL_ERR, "Path regular expression %s seems to use expressions containing the directory symbol %c", str, FILE_SEPARATOR); Log(LOG_LEVEL_ERR, "Use a work-around to avoid pathological behaviour"); return false; } break; } } } return result; } /* Checks whether item matches a list of wildcards */ bool IsRegexItemIn(const EvalContext *ctx, const Item *list, const char *regex) { for (const Item *ptr = list; ptr != NULL; ptr = ptr->next) { if (ctx != NULL && ptr->classes != NULL && !IsDefinedClass(ctx, ptr->classes)) { continue; } /* Cheap pre-test: */ if (strcmp(regex, ptr->name) == 0) { return true; } /* Make it commutative */ if (StringMatchFull(regex, ptr->name) || StringMatchFull(ptr->name, regex)) { return true; } } return false; } /* Escapes non-alphanumeric chars, except sequence given in noEscSeq */ void EscapeSpecialChars(const char *str, char *strEsc, size_t strEscSz, char *noEscSeq, char *noEscList) { size_t strEscPos = 0; if (noEscSeq == NULL) { noEscSeq = ""; } if (noEscList == NULL) { noEscList = ""; } memset(strEsc, 0, strEscSz); for (const char *sp = str; (*sp != '\0') && (strEscPos < strEscSz - 2); sp++) { if (strncmp(sp, noEscSeq, strlen(noEscSeq)) == 0) { if (strEscSz <= strEscPos + strlen(noEscSeq)) { Log(LOG_LEVEL_ERR, "EscapeSpecialChars: Output string truncated. in='%s' out='%s'", str, strEsc); break; } strlcat(strEsc, noEscSeq, strEscSz); strEscPos += strlen(noEscSeq); sp += strlen(noEscSeq); } if (strchr(noEscList,*sp) != NULL) { // Found current char (*sp) in noEscList, do nothing } else if ((*sp != '\0') && (!isalnum((int)*sp))) { strEsc[strEscPos++] = '\\'; } strEsc[strEscPos++] = *sp; } } size_t EscapeRegexCharsLen(const char *str) { size_t ret = 2; for (const char *sp = str; *sp != '\0'; sp++) { switch (*sp) { case '.': case '*': ret++; break; default: break; } ret++; } return ret; } void EscapeRegexChars(char *str, char *strEsc, int strEscSz) { char *sp; int strEscPos = 0; memset(strEsc, 0, strEscSz); for (sp = str; (*sp != '\0') && (strEscPos < strEscSz - 2); sp++) { switch (*sp) { case '.': case '*': strEsc[strEscPos++] = '\\'; break; default: break; } strEsc[strEscPos++] = *sp; } } /* Escapes characters esc in the string str of size strSz */ char *EscapeChar(char *str, size_t strSz, char esc) { char strDup[CF_BUFSIZE]; size_t strPos, strDupPos; if (sizeof(strDup) < strSz) { ProgrammingError("Too large string passed to EscapeCharInplace()"); } snprintf(strDup, sizeof(strDup), "%s", str); memset(str, 0, strSz); for (strPos = 0, strDupPos = 0; strPos < strSz - 2; strPos++, strDupPos++) { if (strDup[strDupPos] == esc) { str[strPos] = '\\'; strPos++; } str[strPos] = strDup[strDupPos]; } return str; } void AnchorRegex(const char *regex, char *out, int outSz) { if (NULL_OR_EMPTY(regex)) { memset(out, 0, outSz); } else { snprintf(out, outSz, "^(%s)$", regex); } } char *AnchorRegexNew(const char *regex) { if (NULL_OR_EMPTY(regex)) { return xstrdup("^$"); } char *ret = NULL; xasprintf(&ret, "^(%s)$", regex); return ret; } bool HasRegexMetaChars(const char *string) { if (!string) { return false; } if (string[strcspn(string, "\\^${}[]().*+?|<>-&")] == '\0') /* i.e. no metachars appear in string */ { return false; } return true; } cfengine-3.24.2/libpromises/actuator.h0000644000000000000000000000242015010704253017674 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ACTUATOR_H #define CFENGINE_ACTUATOR_H #include typedef PromiseResult PromiseActuator(EvalContext *ctx, const Promise *pp, void *param); PromiseResult PromiseResultUpdate(PromiseResult prior, PromiseResult evidence); bool PromiseResultIsOK(PromiseResult result); #endif cfengine-3.24.2/libpromises/assoc.h0000644000000000000000000000241615010704253017167 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ASSOC_H #define CFENGINE_ASSOC_H #include /* variable reference linkage , with metatype*/ typedef struct { char *lval; Rval rval; DataType dtype; } CfAssoc; CfAssoc *NewAssoc(const char *lval, Rval rval, DataType dt); void DeleteAssoc(CfAssoc *ap); #endif cfengine-3.24.2/libpromises/process_lib.h0000644000000000000000000000370515010704253020365 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROCESS_H #define CFENGINE_PROCESS_H #include /* TODO move to libutils, once windows implementation is merged. */ #define PROCESS_START_TIME_UNKNOWN ((time_t) 0) /** * Obtain start time of specified process. * * @return start time (Unix timestamp) of specified process * @return PROCESS_START_TIME_UNKNOWN if start time cannot be determined */ time_t GetProcessStartTime(pid_t pid); /** * Gracefully kill the process with pid #pid and start time #process_start_time. * * Under Unix this will send SIGINT, then SIGTERM and then SIGKILL if process * does not exit. * * #process_start_time may be PROCESS_START_TIME_UNKNOWN, which will disable * safety check for killing right process. * * @return true if process was killed successfully, false otherwise. * @return false if killing failed for any reason, or if the PID wasn't * present in the first place. */ bool GracefulTerminate(pid_t pid, time_t process_start_time); #endif cfengine-3.24.2/libpromises/mod_files.h0000644000000000000000000000233615010704253020021 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_FILES_H #define CFENGINE_MOD_FILES_H #include extern const PromiseTypeSyntax CF_FILES_PROMISE_TYPES[]; extern const ConstraintSyntax CF_COMMON_EDITBODIES[]; extern const ConstraintSyntax CF_COMMON_XMLBODIES[]; #endif cfengine-3.24.2/libpromises/process_linux.c0000644000000000000000000000754615010704253020760 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include typedef struct { time_t starttime; char state; } ProcessStat; static bool GetProcessStat(pid_t pid, ProcessStat *state) { char filename[64]; xsnprintf(filename, sizeof(filename), "/proc/%jd/stat", (intmax_t) pid); int fd; for (;;) { if ((fd = open(filename, O_RDONLY)) != -1) { break; } if (errno == EINTR) { continue; } if (errno == ENOENT || errno == ENOTDIR) { return false; } if (errno == EACCES) { return false; } assert (fd != -1 && "Unable to open /proc//stat"); } char stat[CF_BUFSIZE]; int res = FullRead(fd, stat, sizeof(stat) - 1); /* -1 for the '\0', below */ close(fd); if (res < 0) { return false; } assert(res < CF_BUFSIZE); stat[res] = '\0'; /* read() doesn't '\0'-terminate */ /* stat entry is of form: () * To avoid choking on weird task names, we search for the closing * parenthesis first: */ char *p = memrchr(stat, ')', res); if (p == NULL) { /* Wrong field format! */ return false; } p++; // Skip the parenthesis char proc_state[2]; unsigned long long starttime; if (sscanf(p, "%1s" /* state */ "%*s" /* ppid */ "%*s" /* pgrp */ "%*s" /* session */ "%*s" /* tty_nr */ "%*s" /* tpgid */ "%*s" /* flags */ "%*s" /* minflt */ "%*s" /* cminflt */ "%*s" /* majflt */ "%*s" /* cmajflt */ "%*s" /* utime */ "%*s" /* stime */ "%*s" /* cutime */ "%*s" /* cstime */ "%*s" /* priority */ "%*s" /* nice */ "%*s" /* num_threads */ "%*s" /* itrealvalue */ "%llu" /* starttime */, proc_state, &starttime) != 2) { return false; } state->state = proc_state[0]; state->starttime = (time_t)(starttime / sysconf(_SC_CLK_TCK)); return true; } time_t GetProcessStartTime(pid_t pid) { ProcessStat st; if (GetProcessStat(pid, &st)) { return st.starttime; } else { return PROCESS_START_TIME_UNKNOWN; } } ProcessState GetProcessState(pid_t pid) { ProcessStat st; if (GetProcessStat(pid, &st)) { switch (st.state) { case 'T': return PROCESS_STATE_STOPPED; case 'Z': return PROCESS_STATE_ZOMBIE; default: return PROCESS_STATE_RUNNING; } } else { return PROCESS_STATE_DOES_NOT_EXIST; } } cfengine-3.24.2/libpromises/var_expressions.h0000644000000000000000000000736215010704253021316 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VAR_EXPRESSIONS_H #define CFENGINE_VAR_EXPRESSIONS_H #include #include #include #include /* StringContains() */ /** VarRef is immutable, which means that after allocated the members never change, until all of it is freed. @TODO constify all pointers returned from VarRef initializers (VarRefCopy, VarRefParse, etc) */ typedef struct { char *ns; char *scope; char *lval; char **indices; size_t num_indices; /* TODO performance: when using VarRefCopy() we just need to allocate one * big chunk with malloc() and all pointers can point in there. This * whole struct can be a single malloc'ed chunk with array[] space in * the end, if our use allows it (no changes after creation). */ /* bool single_alloc; */ /* char space[]; */ } VarRef; VarRef *VarRefCopy(const VarRef *ref); VarRef *VarRefCopyLocalized(const VarRef *ref); VarRef *VarRefCopyIndexless(const VarRef *ref); bool is_this_not_special(const char *scope, const char *lval); VarRef *VarRefParse(const char *var_ref_string); VarRef *VarRefParseFromBundle(const char *var_ref_string, const Bundle *bundle); VarRef *VarRefParseFromScope(const char *var_ref_string, const char *scope); VarRef *VarRefParseFromNamespaceAndScope(const char *qualified_name, const char *_ns, const char *_scope, char ns_separator, char scope_separator); VarRef VarRefConst(const char *ns, const char *scope, const char *lval); void VarRefDestroy (VarRef *ref); void VarRefDestroy_untyped(void *ref); char *VarRefToString(const VarRef *ref, bool qualified); void VarRefSetMeta(VarRef *ref, bool enabled); bool VarRefIsQualified(const VarRef *ref); void VarRefQualify(VarRef *ref, const char *ns, const char *scope); void VarRefAddIndex(VarRef *ref, const char *index); int VarRefCompare(const VarRef *a, const VarRef *b); bool VarRefEqual_untyped(const void *a, const void *b); unsigned int VarRefHash_untyped(const void *ref, unsigned int seed); static inline bool StringContainsUnresolved(const char *str) { // clang-format off return (StringContains(str, "$(") || StringContains(str, "${") || StringContains(str, "@{") || StringContains(str, "@(")); // clang-format on } /** Whether #str is of form "@{something}"/"@(something)" or not. */ static inline bool StringIsBareNonScalarRef(const char *str) { assert(str != NULL); const size_t str_len = strlen(str); return ((str[0] == '@') && (((str[1] == '(') && (str[str_len - 1] == ')')) || ((str[1] == '{') && (str[str_len - 1] == '}')))); } #endif cfengine-3.24.2/libpromises/mod_methods.c0000644000000000000000000000713615010704253020360 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include static const char *const POLICY_ERROR_METHODS_BUNDLE_ARITY = "Conflicting arity in calling bundle %s, expected %d arguments, %d given"; static const ConstraintSyntax CF_METHOD_BODIES[] = { ConstraintSyntaxNewBool("inherit", "If true this causes the sub-bundle to inherit the private classes of its parent", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBundle("usebundle", "Specify the name of a bundle to run as a parameterized method", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("useresult", CF_IDRANGE, "Specify the name of a local variable to contain any result/return value from the child", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static bool MethodsParseTreeCheck(const Promise *pp, Seq *errors) { bool success = true; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { const Constraint *cp = SeqAt(pp->conlist, i); // ensure: if call and callee are resolved, then they have matching arity if (StringEqual(cp->lval, "usebundle")) { if (cp->rval.type == RVAL_TYPE_FNCALL) { // HACK: exploiting the fact that class-references and call-references are similar FnCall *call = RvalFnCallValue(cp->rval); ClassRef ref = ClassRefParse(call->name); if (!ClassRefIsQualified(ref)) { ClassRefQualify(&ref, PromiseGetNamespace(pp)); } const Bundle *callee = PolicyGetBundle(PolicyFromPromise(pp), ref.ns, "agent", ref.name); if (!callee) { callee = PolicyGetBundle(PolicyFromPromise(pp), ref.ns, "common", ref.name); } ClassRefDestroy(ref); if (callee) { if (RlistLen(call->args) != RlistLen(callee->args)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp, POLICY_ERROR_METHODS_BUNDLE_ARITY, call->name, RlistLen(callee->args), RlistLen(call->args))); success = false; } } } } } return success; } const PromiseTypeSyntax CF_METHOD_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "methods", CF_METHOD_BODIES, &MethodsParseTreeCheck, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/verify_reports.c0000644000000000000000000001436215010704253021137 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static bool PrintFile(const char *filename, ssize_t max_lines); static void ReportToFile(const char *logfile, const char *message); static void ReportToLog(const char *message); PromiseResult VerifyReportPromise(EvalContext *ctx, const Promise *pp) { assert(pp != NULL); /* This check needs to happen *before* the lock is acquired otherwise the * promise would be skipped in the next evaluation pass and a report with an * unresolved variable reference would never be shown. */ if ((EvalContextGetPass(ctx) < (CF_DONEPASSES - 1)) && IsCf3VarString(pp->promiser)) { /* Unresolved variable reference in the string to be reported and there * is still a chance it will get resolved later. */ return PROMISE_RESULT_SKIPPED; } CfLock thislock; char unique_name[CF_EXPANDSIZE]; Attributes a = GetReportsAttributes(ctx, pp); // We let AcquireLock worry about making a unique name snprintf(unique_name, CF_EXPANDSIZE - 1, "%s", pp->promiser); thislock = AcquireLock(ctx, unique_name, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, false); // Handle return values before locks, as we always do this if (a.report.result) { // User-unwritable value last-result contains the useresult if (strlen(a.report.result) > 0) { snprintf(unique_name, CF_BUFSIZE, "last-result[%s]", a.report.result); } else { snprintf(unique_name, CF_BUFSIZE, "last-result"); } VarRef *ref = VarRefParseFromBundle(unique_name, PromiseGetBundle(pp)); EvalContextVariablePut(ctx, ref, pp->promiser, CF_DATA_TYPE_STRING, "source=bundle"); VarRefDestroy(ref); if (thislock.lock) { YieldCurrentLock(thislock); } return PROMISE_RESULT_NOOP; } if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } PromiseBanner(ctx, pp); if (DONTDO || (a.transaction.action == cfa_warn)) { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, &a, "Need to repair reports promise: %s", pp->promiser); YieldCurrentLock(thislock); return PROMISE_RESULT_WARN; } if (a.report.to_file) { ReportToFile(a.report.to_file, pp->promiser); } else { ReportToLog(pp->promiser); } PromiseResult result = PROMISE_RESULT_NOOP; if (a.report.haveprintfile) { if (!PrintFile(a.report.filename, a.report.numlines)) { result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } YieldCurrentLock(thislock); ClassAuditLog(ctx, pp, &a, result); return result; } static void ReportToLog(const char *message) { char *report_message; xasprintf(&report_message, "R: %s", message); fputs(report_message, stdout); fputc('\n', stdout); LogToSystemLog(report_message, LOG_LEVEL_NOTICE); free(report_message); } static void ReportToFile(const char *logfile, const char *message) { FILE *fp = safe_fopen_create_perms(logfile, "a", CF_PERMS_DEFAULT); if (!fp) { Log(LOG_LEVEL_ERR, "Could not open log file '%s', message '%s'. (fopen: %s)", logfile, message, GetErrorStr()); } else { fprintf(fp, "%s\n", message); fclose(fp); } } static bool PrintFile(const char *filename, ssize_t max_lines) { if (!filename) { Log(LOG_LEVEL_VERBOSE, "Printfile promise was incomplete, with no filename."); return false; } FILE *fp = safe_fopen(filename, "r"); if (!fp) { Log(LOG_LEVEL_ERR, "Printing of file '%s' was not possible. (fopen: %s)", filename, GetErrorStr()); return false; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); ssize_t skip_lines = 0; if (max_lines < 0) { skip_lines = max_lines; max_lines = ABS(max_lines); while (CfReadLine(&line, &line_size, fp) != -1) { skip_lines++; } if (ferror(fp)) { Log(LOG_LEVEL_ERR, "Failed to read line from stream, (getline: %s)", GetErrorStr()); free(line); return false; } rewind(fp); } for (ssize_t i = 0; i < skip_lines + max_lines; i++) { if (CfReadLine(&line, &line_size, fp) == -1) { if (ferror(fp)) { Log(LOG_LEVEL_ERR, "Failed to read line from stream, (getline: %s)", GetErrorStr()); free(line); return false; } else { break; } } if (i >= skip_lines) { ReportToLog(line); } } fclose(fp); free(line); return true; } cfengine-3.24.2/libpromises/Makefile.in0000644000000000000000000015463015010704300017752 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @NT_FALSE@am__append_1 = \ @NT_FALSE@ process_unix.c \ @NT_FALSE@ pipes_unix.c @LINUX_TRUE@@NT_FALSE@am__append_2 = \ @LINUX_TRUE@@NT_FALSE@ process_linux.c @AIX_TRUE@@NT_FALSE@am__append_3 = \ @AIX_TRUE@@NT_FALSE@ process_aix.c @HPUX_TRUE@@NT_FALSE@am__append_4 = \ @HPUX_TRUE@@NT_FALSE@ process_hpux.c @NT_FALSE@@SOLARIS_TRUE@am__append_5 = \ @NT_FALSE@@SOLARIS_TRUE@ process_solaris.c @FREEBSD_TRUE@@NT_FALSE@am__append_6 = \ @FREEBSD_TRUE@@NT_FALSE@ process_freebsd.c @AIX_FALSE@@FREEBSD_FALSE@@HPUX_FALSE@@LINUX_FALSE@@NT_FALSE@@SOLARIS_FALSE@am__append_7 = \ @AIX_FALSE@@FREEBSD_FALSE@@HPUX_FALSE@@LINUX_FALSE@@NT_FALSE@@SOLARIS_FALSE@ process_unix_stub.c @LINUX_TRUE@@NDEBUG_FALSE@am__append_8 = \ @LINUX_TRUE@@NDEBUG_FALSE@ dbm_test_api.c dbm_test_api.h subdir = libpromises ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(projlibdir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(projlib_LTLIBRARIES) libpromises_la_DEPENDENCIES = ../libntech/libutils/libutils.la \ ../libcfecompat/libcfecompat.la ../libcfnet/libcfnet.la \ ../libenv/libenv.la am__libpromises_la_SOURCES_DIST = acl_tools.h acl_tools_posix.c \ actuator.c actuator.h assoc.c assoc.h attributes.c \ attributes.h audit.c audit.h bootstrap.c bootstrap.h \ bootstrap.inc failsafe.cf cf-windows-functions.h cf3.defs.h \ cf3.extern.h cf3globals.c cf3lex.l cf3parse.y cf3parse.h \ cf3parse_logic.h changes_chroot.c changes_chroot.h chflags.c \ chflags.h class.c class.h cmdb.c cmdb.h constants.c \ conversion.c conversion.h crypto.c crypto.h dbm_api.c \ dbm_api.h dbm_api_types.h dbm_priv.h dbm_migration.c \ dbm_migration.h dbm_migration_lastseen.c dbm_lmdb.c \ dbm_quick.c dbm_tokyocab.c enterprise_stubs.c \ enterprise_extension.c enterprise_extension.h eval_context.c \ eval_context.h evalfunction.c evalfunction.h exec_tools.c \ exec_tools.h expand.c expand.h extensions.c extensions.h \ extensions_template.c.pre extensions_template.h.pre feature.c \ feature.h files_copy.c files_copy.h files_interfaces.c \ files_interfaces.h files_lib.c files_lib.h files_links.c \ files_links.h files_names.c files_names.h files_operators.c \ files_operators.h files_repository.c files_repository.h \ fncall.c fncall.h generic_agent.c generic_agent.h \ global_mutex.c global_mutex.h granules.c granules.h \ instrumentation.c instrumentation.h item_lib.c item_lib.h \ iteration.c iteration.h keyring.c keyring.h lastseen.c \ lastseen.h loading.c loading.h locks.c locks.h \ logic_expressions.c logic_expressions.h matching.c matching.h \ match_scope.c match_scope.h math_eval.c math_eval.h math.pc \ mod_access.c mod_access.h mod_common.c mod_common.h \ mod_custom.c mod_custom.h mod_databases.c mod_databases.h \ mod_environ.c mod_environ.h mod_exec.c mod_exec.h mod_files.c \ mod_files.h mod_measurement.c mod_measurement.h mod_methods.c \ mod_methods.h mod_outputs.c mod_outputs.h mod_packages.c \ mod_packages.h mod_process.c mod_process.h mod_report.c \ mod_report.h mod_services.c mod_services.h mod_storage.c \ mod_storage.h mod_knowledge.c mod_knowledge.h mod_users.c \ mod_users.h modes.c monitoring_read.c monitoring_read.h \ ornaments.c ornaments.h policy.c policy.h parser.c parser.h \ parser_helpers.h parser_state.h patches.c pipes.h pipes.c \ processes_select.c processes_select.h process_lib.h \ process_unix_priv.h promises.c promises.h prototypes3.h \ rlist.c rlist.h scope.c scope.h shared_lib.c shared_lib.h \ signals.c signals.h sort.c sort.h storage_tools.c \ string_expressions.c string_expressions.h syntax.c syntax.h \ syslog_client.c syslog_client.h systype.c systype.h timeout.c \ timeout.h unix.c unix.h var_expressions.c var_expressions.h \ variable.c variable.h vars.c vars.h verify_classes.c \ verify_classes.h verify_reports.c verify_vars.c verify_vars.h \ ../cf-check/backup.c ../cf-check/backup.h \ ../cf-check/diagnose.c ../cf-check/diagnose.h \ ../cf-check/lmdump.c ../cf-check/lmdump.h ../cf-check/repair.c \ ../cf-check/repair.h ../cf-check/replicate_lmdb.c \ ../cf-check/replicate_lmdb.h ../cf-check/utilities.c \ ../cf-check/utilities.h ../cf-check/validate.c \ ../cf-check/validate.h process_unix.c pipes_unix.c \ process_linux.c process_aix.c process_hpux.c process_solaris.c \ process_freebsd.c process_unix_stub.c dbm_test_api.c \ dbm_test_api.h @NT_FALSE@am__objects_1 = process_unix.lo pipes_unix.lo @LINUX_TRUE@@NT_FALSE@am__objects_2 = process_linux.lo @AIX_TRUE@@NT_FALSE@am__objects_3 = process_aix.lo @HPUX_TRUE@@NT_FALSE@am__objects_4 = process_hpux.lo @NT_FALSE@@SOLARIS_TRUE@am__objects_5 = process_solaris.lo @FREEBSD_TRUE@@NT_FALSE@am__objects_6 = process_freebsd.lo @AIX_FALSE@@FREEBSD_FALSE@@HPUX_FALSE@@LINUX_FALSE@@NT_FALSE@@SOLARIS_FALSE@am__objects_7 = process_unix_stub.lo @LINUX_TRUE@@NDEBUG_FALSE@am__objects_8 = dbm_test_api.lo am_libpromises_la_OBJECTS = acl_tools_posix.lo actuator.lo assoc.lo \ attributes.lo audit.lo bootstrap.lo cf3globals.lo cf3lex.lo \ cf3parse.lo changes_chroot.lo chflags.lo class.lo cmdb.lo \ constants.lo conversion.lo crypto.lo dbm_api.lo \ dbm_migration.lo dbm_migration_lastseen.lo dbm_lmdb.lo \ dbm_quick.lo dbm_tokyocab.lo enterprise_stubs.lo \ enterprise_extension.lo eval_context.lo evalfunction.lo \ exec_tools.lo expand.lo extensions.lo feature.lo files_copy.lo \ files_interfaces.lo files_lib.lo files_links.lo files_names.lo \ files_operators.lo files_repository.lo fncall.lo \ generic_agent.lo global_mutex.lo granules.lo \ instrumentation.lo item_lib.lo iteration.lo keyring.lo \ lastseen.lo loading.lo locks.lo logic_expressions.lo \ matching.lo match_scope.lo math_eval.lo mod_access.lo \ mod_common.lo mod_custom.lo mod_databases.lo mod_environ.lo \ mod_exec.lo mod_files.lo mod_measurement.lo mod_methods.lo \ mod_outputs.lo mod_packages.lo mod_process.lo mod_report.lo \ mod_services.lo mod_storage.lo mod_knowledge.lo mod_users.lo \ modes.lo monitoring_read.lo ornaments.lo policy.lo parser.lo \ patches.lo pipes.lo processes_select.lo promises.lo rlist.lo \ scope.lo shared_lib.lo signals.lo sort.lo storage_tools.lo \ string_expressions.lo syntax.lo syslog_client.lo systype.lo \ timeout.lo unix.lo var_expressions.lo variable.lo vars.lo \ verify_classes.lo verify_reports.lo verify_vars.lo backup.lo \ diagnose.lo lmdump.lo repair.lo replicate_lmdb.lo utilities.lo \ validate.lo $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) libpromises_la_OBJECTS = $(am_libpromises_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = @BUILTIN_EXTENSIONS_FALSE@am_libpromises_la_rpath = -rpath \ @BUILTIN_EXTENSIONS_FALSE@ $(projlibdir) @BUILTIN_EXTENSIONS_TRUE@am_libpromises_la_rpath = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = @MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ || LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap @MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ -e s/c++$$/h++/ -e s/c$$/h/ YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) AM_V_YACC = $(am__v_YACC_@AM_V@) am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) am__v_YACC_0 = @echo " YACC " $@; am__v_YACC_1 = SOURCES = $(libpromises_la_SOURCES) DIST_SOURCES = $(am__libpromises_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/ylwrap cf3lex.c cf3parse.c cf3parse.h DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ # The lib providing sd_listen_fds() is not needed in libpromises, it's actually # needed in libcfnet. But adding it here is an easy way to make sure it's # available for all the binaries that might need it. Once libcfnet doesn't # require libpromises, we can do this properly. LIBS = $(LMDB_LIBS) $(TOKYOCABINET_LIBS) $(QDBM_LIBS) $(PCRE2_LIBS) \ $(OPENSSL_LIBS) $(SQLITE3_LIBS) $(LIBACL_LIBS) $(LIBYAML_LIBS) \ $(LIBCURL_LIBS) $(SYSTEMD_SOCKET_LIBS) LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # @BUILTIN_EXTENSIONS_FALSE@projlib_LTLIBRARIES = libpromises.la @BUILTIN_EXTENSIONS_FALSE@AM_LDFLAGS = -version-info 3:6:0 \ @BUILTIN_EXTENSIONS_FALSE@ -no-undefined $(CORE_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ $(LMDB_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ $(TOKYOCABINET_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ $(QDBM_LDFLAGS) $(PCRE2_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ $(OPENSSL_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ $(SQLITE3_LDFLAGS) $(LIBACL_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ $(LIBYAML_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ $(LIBCURL_LDFLAGS) @BUILTIN_EXTENSIONS_TRUE@AM_LDFLAGS = $(CORE_LDFLAGS) $(LMDB_LDFLAGS) \ @BUILTIN_EXTENSIONS_TRUE@ $(TOKYOCABINET_LDFLAGS) \ @BUILTIN_EXTENSIONS_TRUE@ $(QDBM_LDFLAGS) $(PCRE2_LDFLAGS) \ @BUILTIN_EXTENSIONS_TRUE@ $(OPENSSL_LDFLAGS) $(SQLITE3_LDFLAGS) \ @BUILTIN_EXTENSIONS_TRUE@ $(LIBACL_LDFLAGS) $(LIBYAML_LDFLAGS) \ @BUILTIN_EXTENSIONS_TRUE@ $(LIBCURL_LDFLAGS) @BUILTIN_EXTENSIONS_TRUE@noinst_LTLIBRARIES = libpromises.la AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libenv \ -I$(srcdir)/../cf-check \ $(CORE_CPPFLAGS) $(ENTERPRISE_CPPFLAGS) \ $(LMDB_CPPFLAGS) $(TOKYOCABINET_CPPFLAGS) $(QDBM_CPPFLAGS) \ $(PCRE2_CPPFLAGS) $(OPENSSL_CPPFLAGS) $(SQLITE3_CPPFLAGS) $(LIBACL_CPPFLAGS) $(LIBYAML_CPPFLAGS) $(LIBCURL_CPPFLAGS) AM_CFLAGS = $(CORE_CFLAGS) $(ENTERPRISE_CFLAGS) \ $(LMDB_CFLAGS) $(TOKYOCABINET_CFLAGS) $(QDBM_CFLAGS) \ $(PCRE2_CFLAGS) $(OPENSSL_CFLAGS) $(SQLITE3_CFLAGS) $(LIBACL_CFLAGS) $(LIBYAML_CFLAGS) $(LIBCURL_CFLAGS) AM_YFLAGS = -d libpromises_la_LIBADD = ../libntech/libutils/libutils.la ../libcfecompat/libcfecompat.la \ ../libcfnet/libcfnet.la \ ../libenv/libenv.la $(ENTERPRISE_LDADD) libpromises_la_SOURCES = acl_tools.h acl_tools_posix.c actuator.c \ actuator.h assoc.c assoc.h attributes.c attributes.h audit.c \ audit.h bootstrap.c bootstrap.h bootstrap.inc failsafe.cf \ cf-windows-functions.h cf3.defs.h cf3.extern.h cf3globals.c \ cf3lex.l cf3parse.y cf3parse.h cf3parse_logic.h \ changes_chroot.c changes_chroot.h chflags.c chflags.h class.c \ class.h cmdb.c cmdb.h constants.c conversion.c conversion.h \ crypto.c crypto.h dbm_api.c dbm_api.h dbm_api_types.h \ dbm_priv.h dbm_migration.c dbm_migration.h \ dbm_migration_lastseen.c dbm_lmdb.c dbm_quick.c dbm_tokyocab.c \ enterprise_stubs.c enterprise_extension.c \ enterprise_extension.h eval_context.c eval_context.h \ evalfunction.c evalfunction.h exec_tools.c exec_tools.h \ expand.c expand.h extensions.c extensions.h \ extensions_template.c.pre extensions_template.h.pre feature.c \ feature.h files_copy.c files_copy.h files_interfaces.c \ files_interfaces.h files_lib.c files_lib.h files_links.c \ files_links.h files_names.c files_names.h files_operators.c \ files_operators.h files_repository.c files_repository.h \ fncall.c fncall.h generic_agent.c generic_agent.h \ global_mutex.c global_mutex.h granules.c granules.h \ instrumentation.c instrumentation.h item_lib.c item_lib.h \ iteration.c iteration.h keyring.c keyring.h lastseen.c \ lastseen.h loading.c loading.h locks.c locks.h \ logic_expressions.c logic_expressions.h matching.c matching.h \ match_scope.c match_scope.h math_eval.c math_eval.h math.pc \ mod_access.c mod_access.h mod_common.c mod_common.h \ mod_custom.c mod_custom.h mod_databases.c mod_databases.h \ mod_environ.c mod_environ.h mod_exec.c mod_exec.h mod_files.c \ mod_files.h mod_measurement.c mod_measurement.h mod_methods.c \ mod_methods.h mod_outputs.c mod_outputs.h mod_packages.c \ mod_packages.h mod_process.c mod_process.h mod_report.c \ mod_report.h mod_services.c mod_services.h mod_storage.c \ mod_storage.h mod_knowledge.c mod_knowledge.h mod_users.c \ mod_users.h modes.c monitoring_read.c monitoring_read.h \ ornaments.c ornaments.h policy.c policy.h parser.c parser.h \ parser_helpers.h parser_state.h patches.c pipes.h pipes.c \ processes_select.c processes_select.h process_lib.h \ process_unix_priv.h promises.c promises.h prototypes3.h \ rlist.c rlist.h scope.c scope.h shared_lib.c shared_lib.h \ signals.c signals.h sort.c sort.h storage_tools.c \ string_expressions.c string_expressions.h syntax.c syntax.h \ syslog_client.c syslog_client.h systype.c systype.h timeout.c \ timeout.h unix.c unix.h var_expressions.c var_expressions.h \ variable.c variable.h vars.c vars.h verify_classes.c \ verify_classes.h verify_reports.c verify_vars.c verify_vars.h \ ../cf-check/backup.c ../cf-check/backup.h \ ../cf-check/diagnose.c ../cf-check/diagnose.h \ ../cf-check/lmdump.c ../cf-check/lmdump.h ../cf-check/repair.c \ ../cf-check/repair.h ../cf-check/replicate_lmdb.c \ ../cf-check/replicate_lmdb.h ../cf-check/utilities.c \ ../cf-check/utilities.h ../cf-check/validate.c \ ../cf-check/validate.h $(am__append_1) $(am__append_2) \ $(am__append_3) $(am__append_4) $(am__append_5) \ $(am__append_6) $(am__append_7) $(am__append_8) ########## Sources pre-generated and distributed in the tarball ########## # Make sure you include the generated file as a dependency to a target # (e.g. libpromises_la) so that it's generated during "make dist" BUILT_SOURCES = cf3lex.c cf3parse.h cf3parse.c \ enterprise_extension.c enterprise_extension.h \ bootstrap.inc EXTRA_SCRIPTS = text2cstring.pl enterprise_extension.sed EXTRA_DIST = $(EXTRA_SCRIPTS) # # Proper compilation progress printing # V_PERL = $(cf__v_PERL_$(V)) cf__v_PERL_ = $(cf__v_PERL_$(AM_DEFAULT_VERBOSITY)) cf__v_PERL_0 = @echo " PERL " "$@"; cf__v_PERL_1 = V_SED = $(cf__v_SED_$(V)) cf__v_SED_ = $(cf__v_SED_$(AM_DEFAULT_VERBOSITY)) cf__v_SED_0 = @echo " SED " "$@"; cf__v_SED_1 = # # Some basic clean ups # # Use "make mostlyclean" if you want to keep the BUILT_SOURCES # CLEANFILES = $(BUILT_SOURCES) MOSTLYCLEANFILES = *.gcno *.gcda *~ *.orig *.rej all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .l .lo .o .obj .y $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libpromises/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libpromises/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-projlibLTLIBRARIES: $(projlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(projlib_LTLIBRARIES)'; test -n "$(projlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(projlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(projlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(projlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(projlibdir)"; \ } uninstall-projlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(projlib_LTLIBRARIES)'; test -n "$(projlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(projlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(projlibdir)/$$f"; \ done clean-projlibLTLIBRARIES: -test -z "$(projlib_LTLIBRARIES)" || rm -f $(projlib_LTLIBRARIES) @list='$(projlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } cf3parse.h: cf3parse.c @if test ! -f $@; then rm -f cf3parse.c; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) cf3parse.c; else :; fi libpromises.la: $(libpromises_la_OBJECTS) $(libpromises_la_DEPENDENCIES) $(EXTRA_libpromises_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(am_libpromises_la_rpath) $(libpromises_la_OBJECTS) $(libpromises_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acl_tools_posix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/actuator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assoc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attributes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bootstrap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf3globals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf3lex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf3parse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changes_chroot.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chflags.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/class.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constants.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conversion.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbm_api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbm_lmdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbm_migration.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbm_migration_lastseen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbm_quick.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbm_test_api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbm_tokyocab.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diagnose.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enterprise_extension.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enterprise_stubs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_context.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evalfunction.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exec_tools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extensions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/feature.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_copy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_interfaces.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_links.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_names.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_operators.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_repository.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fncall.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generic_agent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global_mutex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/granules.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/instrumentation.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/item_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iteration.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyring.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lastseen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmdump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loading.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/locks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logic_expressions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/match_scope.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matching.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/math_eval.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_custom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_databases.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_environ.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_exec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_files.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_knowledge.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_measurement.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_methods.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_outputs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_packages.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_process.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_report.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_storage.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_users.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitoring_read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ornaments.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patches.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipes_unix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_aix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_freebsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_hpux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_solaris.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_unix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_unix_stub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processes_select.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/promises.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repair.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/replicate_lmdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rlist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scope.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shared_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sort.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/storage_tools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_expressions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syntax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syslog_client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/systype.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeout.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utilities.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/var_expressions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/variable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vars.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_classes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_reports.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_vars.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< backup.lo: ../cf-check/backup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT backup.lo -MD -MP -MF $(DEPDIR)/backup.Tpo -c -o backup.lo `test -f '../cf-check/backup.c' || echo '$(srcdir)/'`../cf-check/backup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/backup.Tpo $(DEPDIR)/backup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../cf-check/backup.c' object='backup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o backup.lo `test -f '../cf-check/backup.c' || echo '$(srcdir)/'`../cf-check/backup.c diagnose.lo: ../cf-check/diagnose.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT diagnose.lo -MD -MP -MF $(DEPDIR)/diagnose.Tpo -c -o diagnose.lo `test -f '../cf-check/diagnose.c' || echo '$(srcdir)/'`../cf-check/diagnose.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/diagnose.Tpo $(DEPDIR)/diagnose.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../cf-check/diagnose.c' object='diagnose.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o diagnose.lo `test -f '../cf-check/diagnose.c' || echo '$(srcdir)/'`../cf-check/diagnose.c lmdump.lo: ../cf-check/lmdump.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmdump.lo -MD -MP -MF $(DEPDIR)/lmdump.Tpo -c -o lmdump.lo `test -f '../cf-check/lmdump.c' || echo '$(srcdir)/'`../cf-check/lmdump.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmdump.Tpo $(DEPDIR)/lmdump.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../cf-check/lmdump.c' object='lmdump.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmdump.lo `test -f '../cf-check/lmdump.c' || echo '$(srcdir)/'`../cf-check/lmdump.c repair.lo: ../cf-check/repair.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT repair.lo -MD -MP -MF $(DEPDIR)/repair.Tpo -c -o repair.lo `test -f '../cf-check/repair.c' || echo '$(srcdir)/'`../cf-check/repair.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/repair.Tpo $(DEPDIR)/repair.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../cf-check/repair.c' object='repair.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o repair.lo `test -f '../cf-check/repair.c' || echo '$(srcdir)/'`../cf-check/repair.c replicate_lmdb.lo: ../cf-check/replicate_lmdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT replicate_lmdb.lo -MD -MP -MF $(DEPDIR)/replicate_lmdb.Tpo -c -o replicate_lmdb.lo `test -f '../cf-check/replicate_lmdb.c' || echo '$(srcdir)/'`../cf-check/replicate_lmdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/replicate_lmdb.Tpo $(DEPDIR)/replicate_lmdb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../cf-check/replicate_lmdb.c' object='replicate_lmdb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o replicate_lmdb.lo `test -f '../cf-check/replicate_lmdb.c' || echo '$(srcdir)/'`../cf-check/replicate_lmdb.c utilities.lo: ../cf-check/utilities.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utilities.lo -MD -MP -MF $(DEPDIR)/utilities.Tpo -c -o utilities.lo `test -f '../cf-check/utilities.c' || echo '$(srcdir)/'`../cf-check/utilities.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utilities.Tpo $(DEPDIR)/utilities.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../cf-check/utilities.c' object='utilities.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utilities.lo `test -f '../cf-check/utilities.c' || echo '$(srcdir)/'`../cf-check/utilities.c validate.lo: ../cf-check/validate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT validate.lo -MD -MP -MF $(DEPDIR)/validate.Tpo -c -o validate.lo `test -f '../cf-check/validate.c' || echo '$(srcdir)/'`../cf-check/validate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/validate.Tpo $(DEPDIR)/validate.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../cf-check/validate.c' object='validate.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o validate.lo `test -f '../cf-check/validate.c' || echo '$(srcdir)/'`../cf-check/validate.c .l.c: $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) .y.c: $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(projlibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -rm -f cf3lex.c -rm -f cf3parse.c -rm -f cf3parse.h -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-projlibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-projlibLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-projlibLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES clean-projlibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-projlibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-projlibLTLIBRARIES .PRECIOUS: Makefile enterprise_extension.c: extensions_template.c.pre enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/enterprise_extension.sed $< > $@ enterprise_extension.h: extensions_template.h.pre enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/enterprise_extension.sed $< > $@ bootstrap.inc: failsafe.cf text2cstring.pl $(V_PERL) $(PERL) $(srcdir)/text2cstring.pl $< > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libpromises/mod_knowledge.c0000644000000000000000000001544615010704253020677 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax association_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString("forward_relationship", "", "Name of forward association between promiser topic and associates", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewString("backward_relationship", "", "Name of backward/inverse association from associates to promiser topic", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("associates", "", "List of associated topics by this forward relationship", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; static const BodySyntax association_body = BodySyntaxNew("association", association_constraints, NULL, SYNTAX_STATUS_REMOVED); static const ConstraintSyntax topics_constraints[] = { ConstraintSyntaxNewBody("association", &association_body, "Declare associated topics", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("synonyms", "", "A list of words to be treated as equivalents in the defined context", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("generalizations", "", "A list of words to be treated as super-sets for the current topic, used when reasoning", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; static const ConstraintSyntax occurrences_constraints[] = { ConstraintSyntaxNewStringList("about_topics", "", "List of topics that the document or resource addresses", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("represents", "", "List of explanations for what relationship this document has to the topics it is about", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("representation", "literal,url,db,file,web,image,portal", "How to interpret the promiser string e.g. actual data or reference to data", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; static const ConstraintSyntax things_constraints[] = { ConstraintSyntaxNewStringList("synonyms", "", "A list of words to be treated as equivalents in the defined context", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("affects", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("belongs_to", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("causes", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("certainty", "certain,uncertain,possible", "Selects the level of certainty for the proposed knowledge, for use in inferential reasoning", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("determines", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("generalizations", "", "A list of words to be treated as super-sets for the current topic, used when reasoning", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("implements", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("involves", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_caused_by", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_connected_to", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_determined_by", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_followed_by", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_implemented_by", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_located_in", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_measured_by", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_part_of", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("is_preceded_by", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("measures", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("needs", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("provides", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("uses", "", "Special fixed relation for describing topics that are things", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; static const ConstraintSyntax inferences_constraints[] = { ConstraintSyntaxNewStringList("precedents", "", "The foundational vector for a trinary inference", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewStringList("qualifiers", "", "The second vector in a trinary inference", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_KNOWLEDGE_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("knowledge", "inferences", inferences_constraints, NULL, SYNTAX_STATUS_REMOVED), PromiseTypeSyntaxNew("knowledge", "things", things_constraints, NULL, SYNTAX_STATUS_REMOVED), PromiseTypeSyntaxNew("knowledge", "topics", topics_constraints, NULL, SYNTAX_STATUS_REMOVED), PromiseTypeSyntaxNew("knowledge", "occurrences", occurrences_constraints, NULL, SYNTAX_STATUS_REMOVED), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/locks.c0000644000000000000000000010615215010704253017167 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LMDB // Be careful if you want to change this, // it must match mdb_env_get_maxkeysize(env) #define LMDB_MAX_KEY_SIZE 511 #endif #define CFLOGSIZE 1048576 /* Size of lock-log before rotation */ #define CF_MAXLOCKNUM 8192 #define CF_CRITIAL_SECTION "CF_CRITICAL_SECTION" #define LOG_LOCK_ENTRY(__lock, __lock_sum, __lock_data) \ log_lock("Entering", __FUNCTION__, __lock, __lock_sum, __lock_data) #define LOG_LOCK_EXIT(__lock, __lock_sum, __lock_data) \ log_lock("Exiting", __FUNCTION__, __lock, __lock_sum, __lock_data) #define LOG_LOCK_OP(__lock, __lock_sum, __lock_data) \ log_lock("Performing", __FUNCTION__, __lock, __lock_sum, __lock_data) /** * Map the locks DB usage percentage to the lock horizon interval (how old locks * we want to keep). */ #define N_LOCK_HORIZON_USAGE_INTERVALS 4 /* 0-25, 26-50,... */ static const time_t LOCK_HORIZON_USAGE_INTERVALS[N_LOCK_HORIZON_USAGE_INTERVALS] = { 0, /* plenty of space, no cleanup needed (0 is a special * value) */ 4 * SECONDS_PER_WEEK, /* used to be the fixed value */ 2 * SECONDS_PER_WEEK, /* a bit more aggressive, but still reasonable */ SECONDS_PER_WEEK, /* as far as we want to go to avoid making long locks * unreliable and practically non-functional */ }; typedef struct CfLockStack_ { char lock[CF_BUFSIZE]; char last[CF_BUFSIZE]; struct CfLockStack_ *previous; } CfLockStack; static CfLockStack *LOCK_STACK = NULL; static void PushLock(char *lock, char *last) { CfLockStack *new_lock = xmalloc(sizeof(CfLockStack)); strlcpy(new_lock->lock, lock, CF_BUFSIZE); strlcpy(new_lock->last, last, CF_BUFSIZE); new_lock->previous = LOCK_STACK; LOCK_STACK = new_lock; } static CfLockStack *PopLock() { if (!LOCK_STACK) { return NULL; } CfLockStack *lock = LOCK_STACK; LOCK_STACK = lock->previous; return lock; } static void CopyLockDatabaseAtomically(const char *from, const char *to, const char *from_pretty_name, const char *to_pretty_name); CF_DB *OpenLock() { CF_DB *dbp; if (!OpenDB(&dbp, dbid_locks)) { return NULL; } return dbp; } void CloseLock(CF_DB *dbp) { if (dbp) { CloseDB(dbp); } } static pthread_once_t lock_cleanup_once = PTHREAD_ONCE_INIT; /* GLOBAL_X */ #ifdef LMDB static inline void log_lock(const char *op, const char *function, const char *lock, const char *lock_sum, const LockData *lock_data) { /* Check log level first to save cycles when not in debug mode. */ if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { if (lock_data) { LogDebug(LOG_MOD_LOCKS, "%s lock operation in '%s()': " "lock_id = '%s', lock_checksum = '%s', " "lock.pid = '%d', lock.time = '%d', " "lock.process_start_time = '%d'", op, function, lock, lock_sum, (int)lock_data->pid, (int)lock_data->time, (int)lock_data->process_start_time); } else { LogDebug(LOG_MOD_LOCKS, "%s lock operation in '%s()'. " "lock_id = '%s', lock_checksum = '%s'", op, function, lock, lock_sum); } } } static void HashLockKeyIfNecessary(const char *const istring, char *const ohash) { assert(strlen("CF_CRITICAL_SECTION") < LMDB_MAX_KEY_SIZE); assert(strlen("lock.track_license_bundle.track_license") < LMDB_MAX_KEY_SIZE); StringCopyTruncateAndHashIfNecessary(istring, ohash, LMDB_MAX_KEY_SIZE); } #endif static bool WriteLockData(CF_DB *dbp, const char *lock_id, LockData *lock_data) { bool ret; #ifdef LMDB unsigned char digest2[LMDB_MAX_KEY_SIZE]; HashLockKeyIfNecessary(lock_id, digest2); LOG_LOCK_ENTRY(lock_id, digest2, lock_data); ret = WriteDB(dbp, digest2, lock_data, sizeof(LockData)); LOG_LOCK_EXIT(lock_id, digest2, lock_data); #else ret = WriteDB(dbp, lock_id, lock_data, sizeof(LockData)); #endif return ret; } static bool WriteLockDataCurrent(CF_DB *dbp, const char *lock_id) { LockData lock_data = { 0 }; lock_data.pid = getpid(); lock_data.time = time(NULL); lock_data.process_start_time = GetProcessStartTime(getpid()); return WriteLockData(dbp, lock_id, &lock_data); } static int WriteLock(const char *name) { CF_DB *dbp = OpenLock(); if (dbp == NULL) { return -1; } ThreadLock(cft_lock); WriteLockDataCurrent(dbp, name); CloseLock(dbp); ThreadUnlock(cft_lock); return 0; } static time_t FindLockTime(const char *name) { bool ret; CF_DB *dbp = OpenLock(); if (dbp == NULL) { return -1; } LockData entry = { 0 }; entry.process_start_time = PROCESS_START_TIME_UNKNOWN; #ifdef LMDB unsigned char ohash[LMDB_MAX_KEY_SIZE]; HashLockKeyIfNecessary(name, ohash); LOG_LOCK_ENTRY(name, ohash, &entry); ret = ReadDB(dbp, ohash, &entry, sizeof(entry)); LOG_LOCK_EXIT(name, ohash, &entry); #else ret = ReadDB(dbp, name, &entry, sizeof(entry)); #endif if (ret) { CloseLock(dbp); return entry.time; } else { CloseLock(dbp); return -1; } } static void RemoveDates(char *s) { int i, a = 0, b = 0, c = 0, d = 0; char *dayp = NULL, *monthp = NULL, *sp; char *days[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; char *months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; // Canonifies or blanks our times/dates for locks where there would be an explosion of state /* Has s always been generated by something that uses two-digit hh:mm:ss? * Are there any time-zones whose abbreviations are shorter than three * letters? */ if (strlen(s) < sizeof("Fri Oct 1 15:15:23 EST 2010") - 1) { // Probably not a full date return; } for (i = 0; i < 7; i++) { if ((dayp = strstr(s, days[i]))) { *dayp = 'D'; *(dayp + 1) = 'A'; *(dayp + 2) = 'Y'; break; } } for (i = 0; i < 12; i++) { if ((monthp = strstr(s, months[i]))) { *monthp = 'M'; *(monthp + 1) = 'O'; *(monthp + 2) = 'N'; break; } } if (dayp && monthp) // looks like a full date { sscanf(monthp + 4, "%d %d:%d:%d", &a, &b, &c, &d); if (a * b * c * d == 0) { // Probably not a date return; } for (sp = monthp + 4; *sp != '\0'; sp++) { if (sp > monthp + 15) { break; } if (isdigit((int)*sp)) { *sp = 't'; } } } } static int RemoveLock(const char *name) { CF_DB *dbp = OpenLock(); if (dbp == NULL) { return -1; } ThreadLock(cft_lock); #ifdef LMDB unsigned char digest2[LMDB_MAX_KEY_SIZE]; HashLockKeyIfNecessary(name, digest2); LOG_LOCK_ENTRY(name, digest2, NULL); DeleteDB(dbp, digest2); LOG_LOCK_EXIT(name, digest2, NULL); #else DeleteDB(dbp, name); #endif ThreadUnlock(cft_lock); CloseLock(dbp); return 0; } static bool NoOrObsoleteLock(LockData *entry, ARG_UNUSED size_t entry_size, size_t *max_old) { assert((entry == NULL) || (entry_size == sizeof(LockData))); if (entry == NULL) { return true; } time_t now = time(NULL); if ((now - entry->time) <= (time_t) *max_old) { Log(LOG_LEVEL_DEBUG, "Giving time to process '%d' (holding lock for %ld s)", entry->pid, (now - entry->time)); } return ((now - entry->time) > (time_t) *max_old); } void WaitForCriticalSection(const char *section_id) { ThreadLock(cft_lock); CF_DB *dbp = OpenLock(); if (dbp == NULL) { Log(LOG_LEVEL_CRIT, "Failed to open lock database when waiting for critical section"); ThreadUnlock(cft_lock); return; } time_t started = time(NULL); LockData entry = { 0 }; entry.pid = getpid(); entry.process_start_time = PROCESS_START_TIME_UNKNOWN; #ifdef LMDB unsigned char ohash[LMDB_MAX_KEY_SIZE]; HashLockKeyIfNecessary(section_id, ohash); Log(LOG_LEVEL_DEBUG, "Hashed critical section lock '%s' to '%s'", section_id, ohash); section_id = ohash; #endif /* If another agent has been waiting more than a minute, it means there is likely crash detritus to clear up... After a minute we take our chances ... */ size_t max_old = 60; Log(LOG_LEVEL_DEBUG, "Acquiring critical section lock '%s'", section_id); bool got_lock = false; while (!got_lock && ((time(NULL) - started) <= (time_t) max_old)) { entry.time = time(NULL); got_lock = OverwriteDB(dbp, section_id, &entry, sizeof(entry), (OverwriteCondition) NoOrObsoleteLock, &max_old); if (!got_lock) { Log(LOG_LEVEL_DEBUG, "Waiting for critical section lock '%s'", section_id); sleep(1); } } /* If we still haven't gotten the lock, let's try the biggest hammer we * have. */ if (!got_lock) { Log(LOG_LEVEL_NOTICE, "Failed to wait for critical section lock '%s', force-writing new lock", section_id); if (!WriteDB(dbp, section_id, &entry, sizeof(entry))) { Log(LOG_LEVEL_CRIT, "Failed to force-write critical section lock '%s'", section_id); } } else { Log(LOG_LEVEL_DEBUG, "Acquired critical section lock '%s'", section_id); } CloseLock(dbp); ThreadUnlock(cft_lock); } void ReleaseCriticalSection(const char *section_id) { Log(LOG_LEVEL_DEBUG, "Releasing critical section lock '%s'", section_id); if (RemoveLock(section_id) == 0) { Log(LOG_LEVEL_DEBUG, "Released critical section lock '%s'", section_id); } else { Log(LOG_LEVEL_DEBUG, "Failed to release critical section lock '%s'", section_id); } } static time_t FindLock(char *last) { time_t mtime; if ((mtime = FindLockTime(last)) == -1) { /* Do this to prevent deadlock loops from surviving if IfElapsed > T_sched */ if (WriteLock(last) == -1) { Log(LOG_LEVEL_ERR, "Unable to lock %s", last); return 0; } return 0; } else { return mtime; } } static void LocksCleanup(void) { CfLockStack *lock; while ((lock = PopLock()) != NULL) { CfLock best_guess = { .lock = xstrdup(lock->lock), .last = xstrdup(lock->last), }; YieldCurrentLock(best_guess); free(lock); } } static void RegisterLockCleanup(void) { RegisterCleanupFunction(&LocksCleanup); } /** * Return a type template for the promise for lock-type * identification. WARNING: instead of truncation, it does not include any * parts (i.e. constraints or promise type) that don't fit. * * @WARNING currently it only prints up to the 5 first constraints (WHY?) */ static void PromiseTypeString(char *dst, size_t dst_size, const Promise *pp) { const char *sp = PromiseGetPromiseType(pp); size_t sp_len = strlen(sp); dst[0] = '\0'; size_t dst_len = 0; if (sp_len + 1 < dst_size) { strcpy(dst, sp); strcat(dst, "."); dst_len += sp_len + 1; } if (pp->conlist != NULL) { /* Number of constraints (attributes) of that promise. */ size_t cons_num = SeqLength(pp->conlist); for (size_t i = 0; (i < 5) && (i < cons_num); i++) { Constraint *cp = SeqAt(pp->conlist, i); const char *con = cp->lval; /* the constraint */ /* Exception for args (promise type commands), by symmetry, for locking. */ if (strcmp(con, "args") == 0) { continue; } /* Exception for arglist (promise type commands), by symmetry, for locking. */ if (strcmp(con, "arglist") == 0) { continue; } size_t con_len = strlen(con); if (dst_len + con_len + 1 < dst_size) { strcat(dst, con); strcat(dst, "."); dst_len += con_len + 1; } } } } /** * A helper best-effort function to prevent us from killing non CFEngine * processes with matching PID-start_time combinations **when/where it's easy to * check**. */ static bool IsCfengineLockHolder(pid_t pid) { char procfile[PATH_MAX]; snprintf(procfile, PATH_MAX, "/proc/%ju/comm", (uintmax_t) pid); int f = open(procfile, O_RDONLY); /* On platforms where /proc doesn't exist, we would have to do a more complicated check probably not worth it in this helper best-effort function. */ if (f == -1) { /* assume true where we cannot check */ return true; } /* more than any possible CFEngine lock holder's name */ char command[32] = {0}; ssize_t n_read = FullRead(f, command, sizeof(command)); close(f); if ((n_read <= 1) || (n_read == sizeof(command))) { Log(LOG_LEVEL_VERBOSE, "Failed to get command for process %ju", (uintmax_t) pid); /* assume true where we cannot check */ return true; } if (command[n_read - 1] == '\n') { command[n_read - 1] = '\0'; } /* potential CFEngine lock holders (others like cf-net, cf-key,... are not * supposed/expected to be lock holders) */ const char *const cfengine_procs[] = { "cf-promises", "lt-cf-agent", /* when running from a build with 'libtool --mode=execute' */ "cf-agent", "cf-execd", "cf-serverd", "cf-monitord", "cf-hub", NULL }; for (size_t i = 0; cfengine_procs[i] != NULL; i++) { if (StringEqual(cfengine_procs[i], command)) { return true; } } Log(LOG_LEVEL_DEBUG, "'%s' not considered a CFEngine process", command); return false; } static bool KillLockHolder(const char *lock) { bool ret; CF_DB *dbp = OpenLock(); if (dbp == NULL) { Log(LOG_LEVEL_ERR, "Unable to open locks database"); return false; } LockData lock_data = { 0 }; lock_data.process_start_time = PROCESS_START_TIME_UNKNOWN; #ifdef LMDB unsigned char ohash[LMDB_MAX_KEY_SIZE]; HashLockKeyIfNecessary(lock, ohash); LOG_LOCK_ENTRY(lock, ohash, &lock_data); ret = ReadDB(dbp, ohash, &lock_data, sizeof(lock_data)); LOG_LOCK_EXIT(lock, ohash, &lock_data); #else ret = ReadDB(dbp, lock, &lock_data, sizeof(lock_data)); #endif if (!ret) { /* No lock found */ CloseLock(dbp); return true; } CloseLock(dbp); if (!IsCfengineLockHolder(lock_data.pid)) { Log(LOG_LEVEL_VERBOSE, "Lock holder with PID %ju was replaced by a non CFEngine process, ignoring request to kill it", (uintmax_t) lock_data.pid); return true; } if (GracefulTerminate(lock_data.pid, lock_data.process_start_time)) { Log(LOG_LEVEL_INFO, "Process with PID %jd successfully killed", (intmax_t) lock_data.pid); return true; } else { if (errno == ESRCH) { Log(LOG_LEVEL_VERBOSE, "Process with PID %jd has already been killed", (intmax_t) lock_data.pid); return true; } else { Log(LOG_LEVEL_ERR, "Failed to kill process with PID: %jd (kill: %s)", (intmax_t) lock_data.pid, GetErrorStr()); return false; } } } static void RvalDigestUpdate(EVP_MD_CTX *context, Rlist *rp) { assert(context != NULL); assert(rp != NULL); switch (rp->val.type) { case RVAL_TYPE_SCALAR: EVP_DigestUpdate(context, RlistScalarValue(rp), strlen(RlistScalarValue(rp))); break; case RVAL_TYPE_FNCALL: // TODO: This should be recursive and not just hash the function name EVP_DigestUpdate(context, RlistFnCallValue(rp)->name, strlen(RlistFnCallValue(rp)->name)); break; default: ProgrammingError("Unhandled case in switch"); break; } } void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type) { static const char PACK_UPIFELAPSED_SALT[] = "packageuplist"; int md_len; const EVP_MD *md = NULL; Rlist *rp; FnCall *fp; char *noRvalHash[] = { "mtime", "atime", "ctime", "stime_range", "ttime_range", "log_string", "template_data", NULL }; int doHash; md = HashDigestFromId(type); if (md == NULL) { Log(LOG_LEVEL_ERR, "Could not determine function for file hashing (type=%d)", (int) type); return; } EVP_MD_CTX *context = EVP_MD_CTX_new(); if (context == NULL) { Log(LOG_LEVEL_ERR, "Could not allocate openssl hash context"); return; } EVP_DigestInit(context, md); // multiple packages (promisers) may share same package_list_update_ifelapsed lock if ( (!salt) || strcmp(salt, PACK_UPIFELAPSED_SALT) ) { EVP_DigestUpdate(context, pp->promiser, strlen(pp->promiser)); } if (pp->comment) { EVP_DigestUpdate(context, pp->comment, strlen(pp->comment)); } if (pp->parent_section && pp->parent_section->parent_bundle) { if (pp->parent_section->parent_bundle->ns) { EVP_DigestUpdate(context, pp->parent_section->parent_bundle->ns, strlen(pp->parent_section->parent_bundle->ns)); } if (pp->parent_section->parent_bundle->name) { EVP_DigestUpdate(context, pp->parent_section->parent_bundle->name, strlen(pp->parent_section->parent_bundle->name)); } } // Unused: pp start, end, and line attributes (describing source position). if (salt) { EVP_DigestUpdate(context, salt, strlen(salt)); } if (pp->conlist) { for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); EVP_DigestUpdate(context, cp->lval, strlen(cp->lval)); // don't hash rvals that change (e.g. times) doHash = true; for (int j = 0; noRvalHash[j] != NULL; j++) { if (strcmp(cp->lval, noRvalHash[j]) == 0) { doHash = false; break; } } if (!doHash) { continue; } switch (cp->rval.type) { case RVAL_TYPE_SCALAR: EVP_DigestUpdate(context, cp->rval.item, strlen(cp->rval.item)); break; case RVAL_TYPE_LIST: for (rp = cp->rval.item; rp != NULL; rp = rp->next) { RvalDigestUpdate(context, rp); } break; case RVAL_TYPE_CONTAINER: { const JsonElement *rval_json = RvalContainerValue(cp->rval); Writer *writer = StringWriter(); JsonWriteCompact(writer, rval_json); /* sorts elements and produces canonical form */ EVP_DigestUpdate(context, StringWriterData(writer), StringWriterLength(writer)); WriterClose(writer); break; } case RVAL_TYPE_FNCALL: /* Body or bundle */ fp = (FnCall *) cp->rval.item; EVP_DigestUpdate(context, fp->name, strlen(fp->name)); for (rp = fp->args; rp != NULL; rp = rp->next) { RvalDigestUpdate(context, rp); } break; default: break; } } } EVP_DigestFinal(context, digest, &md_len); EVP_MD_CTX_free(context); /* Digest length stored in md_len */ } static CfLock CfLockNew(const char *last, const char *lock, bool is_dummy) { return (CfLock) { .last = last ? xstrdup(last) : NULL, .lock = lock ? xstrdup(lock) : NULL, .is_dummy = is_dummy }; } static CfLock CfLockNull(void) { return (CfLock) { .last = NULL, .lock = NULL, .is_dummy = false }; } CfLock AcquireLock(EvalContext *ctx, const char *operand, const char *host, time_t now, int ifelapsed, int expireafter, const Promise *pp, bool ignoreProcesses) { if (now == 0) { return CfLockNull(); } char str_digest[CF_HOSTKEY_STRING_SIZE]; { unsigned char digest[EVP_MAX_MD_SIZE + 1]; PromiseRuntimeHash(pp, operand, digest, CF_DEFAULT_DIGEST); HashPrintSafe(str_digest, sizeof(str_digest), digest, CF_DEFAULT_DIGEST, true); } if (EvalContextPromiseLockCacheContains(ctx, str_digest)) { // Log(LOG_LEVEL_DEBUG, "This promise has already been verified"); return CfLockNull(); } EvalContextPromiseLockCachePut(ctx, str_digest); // Finally if we're supposed to ignore locks ... do the remaining stuff if (EvalContextIsIgnoringLocks(ctx)) { return CfLockNew(NULL, "dummy", true); } char cc_operator[CF_MAXVARSIZE]; { char promise[CF_MAXVARSIZE - CF_BUFFERMARGIN]; PromiseTypeString(promise, sizeof(promise), pp); snprintf(cc_operator, sizeof(cc_operator), "%s-%s", promise, host); } char cc_operand[CF_BUFSIZE]; strlcpy(cc_operand, operand, CF_BUFSIZE); CanonifyNameInPlace(cc_operand); RemoveDates(cc_operand); Log(LOG_LEVEL_DEBUG, "AcquireLock(%s,%s), ExpireAfter = %d, IfElapsed = %d", cc_operator, cc_operand, expireafter, ifelapsed); int sum = 0; for (int i = 0; cc_operator[i] != '\0'; i++) { sum = (CF_MACROALPHABET * sum + cc_operator[i]) % CF_MAXLOCKNUM; } for (int i = 0; cc_operand[i] != '\0'; i++) { sum = (CF_MACROALPHABET * sum + cc_operand[i]) % CF_MAXLOCKNUM; } const char *bundle_name = PromiseGetBundle(pp)->name; char cflock[CF_BUFSIZE] = ""; snprintf(cflock, CF_BUFSIZE, "lock.%.100s.%s.%.100s_%d_%s", bundle_name, cc_operator, cc_operand, sum, str_digest); char cflast[CF_BUFSIZE] = ""; snprintf(cflast, CF_BUFSIZE, "last.%.100s.%s.%.100s_%d_%s", bundle_name, cc_operator, cc_operand, sum, str_digest); Log(LOG_LEVEL_DEBUG, "Locking bundle '%s' with lock '%s'", bundle_name, cflock); // Now see if we can get exclusivity to edit the locks WaitForCriticalSection(CF_CRITIAL_SECTION); // Look for non-existent (old) processes time_t lastcompleted = FindLock(cflast); time_t elapsedtime = (time_t) (now - lastcompleted) / 60; // For promises/locks with ifelapsed == 0, skip all detection logic of // previously acquired locks, whether in this agent or a parallel one. if (ifelapsed != 0) { if (elapsedtime < 0) { Log(LOG_LEVEL_VERBOSE, "Another cf-agent seems to have done this since I started " "(elapsed=%jd)", (intmax_t) elapsedtime); ReleaseCriticalSection(CF_CRITIAL_SECTION); return CfLockNull(); } if (elapsedtime < ifelapsed) { Log(LOG_LEVEL_VERBOSE, "Nothing promised here [%.40s] (%jd/%u minutes elapsed)", cflast, (intmax_t) elapsedtime, ifelapsed); ReleaseCriticalSection(CF_CRITIAL_SECTION); return CfLockNull(); } } // Look for existing (current) processes lastcompleted = FindLock(cflock); if (!ignoreProcesses) { elapsedtime = (time_t) (now - lastcompleted) / 60; if (lastcompleted != 0) { if (elapsedtime >= expireafter) { Log(LOG_LEVEL_INFO, "Lock expired after %jd/%u minutes: %s", (intmax_t) elapsedtime, expireafter, cflock); if (KillLockHolder(cflock)) { Log(LOG_LEVEL_VERBOSE, "Lock successfully expired: %s", cflock); unlink(cflock); } else { Log(LOG_LEVEL_ERR, "Failed to expire lock: %s", cflock); } } else { ReleaseCriticalSection(CF_CRITIAL_SECTION); Log(LOG_LEVEL_VERBOSE, "Couldn't obtain lock for %s (already running!)", cflock); return CfLockNull(); } } int ret = WriteLock(cflock); if (ret != -1) { /* Register a cleanup handler *after* having opened the DB, so that * CloseAllDB() atexit() handler is registered in advance, and it * is called after removing this lock. * There is a small race condition here that we'll leave a stale * lock if we exit before the following line. */ pthread_once(&lock_cleanup_once, &RegisterLockCleanup); } } ReleaseCriticalSection(CF_CRITIAL_SECTION); // Keep this as a global for signal handling PushLock(cflock, cflast); return CfLockNew(cflast, cflock, false); } void YieldCurrentLock(CfLock lock) { if (lock.is_dummy) { free(lock.lock); /* allocated in AquireLock as a special case */ return; } if (lock.lock == (char *) CF_UNDEFINED) { return; } Log(LOG_LEVEL_DEBUG, "Yielding lock '%s'", lock.lock); if (RemoveLock(lock.lock) == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to remove lock %s", lock.lock); free(lock.last); free(lock.lock); return; } if (WriteLock(lock.last) == -1) { Log(LOG_LEVEL_ERR, "Unable to create '%s'. (create: %s)", lock.last, GetErrorStr()); free(lock.last); free(lock.lock); return; } /* This lock has ben yield'ed, don't try to yield it again in case process * is terminated abnormally. */ CfLockStack *stack = LOCK_STACK; CfLockStack *last = NULL; while (stack) { if ((strcmp(stack->lock, lock.lock) == 0) && (strcmp(stack->last, lock.last) == 0)) { CfLockStack *delete_me = stack; stack = stack->previous; if (!last) { assert(delete_me == LOCK_STACK); LOCK_STACK = stack; } else { last->previous = stack; } free(delete_me); continue; } last = stack; stack = stack->previous; } free(lock.last); free(lock.lock); } void YieldCurrentLockAndRemoveFromCache(EvalContext *ctx, CfLock lock, const char *operand, const Promise *pp) { unsigned char digest[EVP_MAX_MD_SIZE + 1]; PromiseRuntimeHash(pp, operand, digest, CF_DEFAULT_DIGEST); char str_digest[CF_HOSTKEY_STRING_SIZE]; HashPrintSafe(str_digest, sizeof(str_digest), digest, CF_DEFAULT_DIGEST, true); YieldCurrentLock(lock); EvalContextPromiseLockCacheRemove(ctx, str_digest); } void GetLockName(char *lockname, const char *locktype, const char *base, const Rlist *params) { int max_sample, count = 0; for (const Rlist *rp = params; rp != NULL; rp = rp->next) { count++; } if (count) { max_sample = CF_BUFSIZE / (2 * count); } else { max_sample = 0; } strlcpy(lockname, locktype, CF_BUFSIZE / 10); strlcat(lockname, "_", CF_BUFSIZE / 10); strlcat(lockname, base, CF_BUFSIZE / 10); strlcat(lockname, "_", CF_BUFSIZE / 10); for (const Rlist *rp = params; rp != NULL; rp = rp->next) { switch (rp->val.type) { case RVAL_TYPE_SCALAR: strncat(lockname, RlistScalarValue(rp), max_sample); break; case RVAL_TYPE_FNCALL: strncat(lockname, RlistFnCallValue(rp)->name, max_sample); break; default: ProgrammingError("Unhandled case in switch %d", rp->val.type); break; } } } void RestoreLockDatabase(void) { // We don't do any locking here (since we can't trust the database), but // worst case someone else will just copy the same file to the same // location. char *db_path = DBIdToPath(dbid_locks); char *db_path_backup; xasprintf(&db_path_backup, "%s.backup", db_path); CopyLockDatabaseAtomically(db_path_backup, db_path, "lock database backup", "lock database"); free(db_path); free(db_path_backup); } static void CopyLockDatabaseAtomically(const char *from, const char *to, const char *from_pretty_name, const char *to_pretty_name) { char *tmp_file_name; xasprintf(&tmp_file_name, "%s.tmp", to); int from_fd = open(from, O_RDONLY | O_BINARY); if (from_fd < 0) { Log(LOG_LEVEL_WARNING, "Could not open '%s' (open: %s)", from_pretty_name, GetErrorStr()); goto cleanup; } int to_fd = open(tmp_file_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600); if (to_fd < 0) { Log(LOG_LEVEL_WARNING, "Could not open '%s' temporary file (open: %s)", to_pretty_name, GetErrorStr()); goto cleanup; } size_t total_bytes_written; bool last_write_was_hole; bool ok1 = FileSparseCopy(from_fd, from_pretty_name, to_fd, to_pretty_name, DEV_BSIZE, &total_bytes_written, &last_write_was_hole); /* Make sure changes are persistent on disk, so database cannot get * corrupted at system crash. */ bool do_sync = true; bool ok2 = FileSparseClose(to_fd, to_pretty_name, do_sync, total_bytes_written, last_write_was_hole); if (!ok1 || !ok2) { Log(LOG_LEVEL_WARNING, "Error while moving database from '%s' to '%s'", from_pretty_name, to_pretty_name); } if (rename(tmp_file_name, to) != 0) { Log(LOG_LEVEL_WARNING, "Could not move '%s' into place (rename: %s)", to_pretty_name, GetErrorStr()); } cleanup: if (from_fd != -1) { close(from_fd); } unlink(tmp_file_name); free(tmp_file_name); } void BackupLockDatabase(void) { WaitForCriticalSection(CF_CRITIAL_SECTION); char *db_path = DBIdToPath(dbid_locks); char *db_path_backup; xasprintf(&db_path_backup, "%s.backup", db_path); CopyLockDatabaseAtomically(db_path, db_path_backup, "lock database", "lock database backup"); free(db_path); free(db_path_backup); ReleaseCriticalSection(CF_CRITIAL_SECTION); } void PurgeLocks(void) { DBHandle *db = OpenLock(); if (db == NULL) { return; } time_t now = time(NULL); int usage_pct = GetDBUsagePercentage(db); if (usage_pct == -1) { /* error already logged */ /* no usage info, assume 50% */ usage_pct = 50; } unsigned short interval_idx = MIN(usage_pct / (100 / N_LOCK_HORIZON_USAGE_INTERVALS), N_LOCK_HORIZON_USAGE_INTERVALS - 1); const time_t lock_horizon_interval = LOCK_HORIZON_USAGE_INTERVALS[interval_idx]; if (lock_horizon_interval == 0) { Log(LOG_LEVEL_VERBOSE, "No lock purging needed (lock DB usage: %d %%)", usage_pct); CloseLock(db); return; } const time_t purge_horizon = now - lock_horizon_interval; LockData lock_horizon; memset(&lock_horizon, 0, sizeof(lock_horizon)); if (ReadDB(db, "lock_horizon", &lock_horizon, sizeof(lock_horizon))) { if (lock_horizon.time > purge_horizon) { Log(LOG_LEVEL_VERBOSE, "No lock purging scheduled"); CloseLock(db); return; } } Log(LOG_LEVEL_VERBOSE, "Looking for stale locks (older than %jd seconds) to purge", (intmax_t) lock_horizon_interval); DBCursor *cursor; if (!NewDBCursor(db, &cursor)) { char *db_path = DBIdToPath(dbid_locks); Log(LOG_LEVEL_ERR, "Unable to get cursor for locks database '%s'", db_path); free(db_path); CloseLock(db); return; } char *key; int ksize, vsize; LockData *entry = NULL; while (NextDB(cursor, &key, &ksize, (void **)&entry, &vsize)) { #ifdef LMDB LOG_LOCK_OP("", key, entry); #endif if (StringStartsWith(key, "last.internal_bundle.track_license.handle")) { continue; } if (entry->time < purge_horizon) { Log(LOG_LEVEL_VERBOSE, "Purging lock (%jd s elapsed): %s", (intmax_t) (now - entry->time), key); DBCursorDeleteEntry(cursor); } } DeleteDBCursor(cursor); Log(LOG_LEVEL_DEBUG, "Finished purging locks"); lock_horizon.time = now; WriteDB(db, "lock_horizon", &lock_horizon, sizeof(lock_horizon)); CloseLock(db); } cfengine-3.24.2/libpromises/systype.h0000644000000000000000000000477715010704253017613 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SYSTYPE_H #define CFENGINE_SYSTYPE_H /*******************************************************************/ typedef enum { PLATFORM_CONTEXT_UNKNOWN, PLATFORM_CONTEXT_OPENVZ, /* VZ Host with vzps installed */ PLATFORM_CONTEXT_HP, PLATFORM_CONTEXT_AIX, PLATFORM_CONTEXT_LINUX, PLATFORM_CONTEXT_BUSYBOX, /* Linux-based Busybox toolset */ PLATFORM_CONTEXT_SOLARIS, /* > 5.10, BSD-compatible system tools */ PLATFORM_CONTEXT_SUN_SOLARIS, /* < 5.11, BSD tools in /usr/ucb */ PLATFORM_CONTEXT_FREEBSD, PLATFORM_CONTEXT_NETBSD, PLATFORM_CONTEXT_CRAYOS, PLATFORM_CONTEXT_WINDOWS_NT, /* MS-Win CygWin */ PLATFORM_CONTEXT_SYSTEMV, PLATFORM_CONTEXT_OPENBSD, PLATFORM_CONTEXT_CFSCO, PLATFORM_CONTEXT_DARWIN, /* MacOS X */ PLATFORM_CONTEXT_QNX, PLATFORM_CONTEXT_DRAGONFLY, PLATFORM_CONTEXT_MINGW, /* MS-Win native */ PLATFORM_CONTEXT_VMWARE, PLATFORM_CONTEXT_ANDROID, PLATFORM_CONTEXT_MAX /* Not an actual platform: must be last */ } PlatformContext; /*******************************************************************/ extern PlatformContext VSYSTEMHARDCLASS; extern PlatformContext VPSHARDCLASS; /* used to define which ps command to use*/ extern const char *const CLASSTEXT[PLATFORM_CONTEXT_MAX]; extern const char *const VPSCOMM[PLATFORM_CONTEXT_MAX]; extern const char *const VPSOPTS[PLATFORM_CONTEXT_MAX]; extern const char *const VFSTAB[PLATFORM_CONTEXT_MAX]; /*******************************************************************/ #endif /* CFENGINE_SYSTYPE_H */ cfengine-3.24.2/libpromises/mod_databases.c0000644000000000000000000000623715010704253020645 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax database_server_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString("db_server_owner", "", "User name for database connection", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("db_server_password", "", "Clear text password for database connection", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("db_server_host", "", "Hostname or address for connection to database, blank means localhost", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("db_server_type", "postgres,mysql", "The dialect of the database server. Default value: none", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("db_server_connection_db", "", "The name of an existing database to connect to in order to create/manage other databases", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax database_server_body = BodySyntaxNew("database_server", database_server_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax databases_constraints[] = { ConstraintSyntaxNewBody("database_server", &database_server_body, "Credentials for connecting to a local/remote database server", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("database_type", "sql,ms_registry", "The type of database that is to be manipulated. Default value: none", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("database_operation", "create,delete,drop,cache,verify,restore", "The nature of the promise - to be or not to be", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("database_columns", ".*", "A list of column definitions to be promised by SQL databases", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("database_rows", ".*,.*", "An ordered list of row values to be promised by SQL databases", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("registry_exclude", "", "A list of regular expressions to ignore in key/value verification", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_DATABASES_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "databases", databases_constraints, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/files_copy.h0000644000000000000000000000343115010704253020211 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_COPY_H #define CFENGINE_FILES_COPY_H #include #ifdef WITH_XATTR_EXTRA_ARGS #define llistxattr(__arg1, __arg2, __arg3) \ llistxattr((__arg1), (__arg2), (__arg3), 0) #define lgetxattr(__arg1, __arg2, __arg3, __arg4) \ lgetxattr((__arg1), (__arg2), (__arg3), (__arg4), 0, 0) #define lsetxattr(__arg1, __arg2, __arg3, __arg4, __arg5) \ lsetxattr((__arg1), (__arg2), (__arg3), (__arg4), 0, (__arg5)) #endif bool CopyRegularFileDiskPerms(const char *source, const char *destination, const int mode); bool CopyRegularFileDisk(const char *source, const char *destination); bool CopyFilePermissionsDisk(const char *source, const char *destination); bool CopyFileExtendedAttributesDisk(const char *source, const char *destination, bool *change); #endif cfengine-3.24.2/libpromises/dbm_migration_lastseen.c0000644000000000000000000001056115010704253022563 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include typedef struct { double q; double expect; double var; } QPoint0; typedef struct { time_t lastseen; QPoint Q; // Average time between connections (rolling weighted average) } KeyHostSeen1; #define QPOINT0_OFFSET 128 /* * Structure of version 0 lastseen entry: * * flag | hostkey -> address | QPoint * | | | \- 3*double * | | \- 128 chars * | \- N*chars * \- 1 byte, '+' or '-' */ static bool LastseenMigrationVersion0(DBHandle *db) { /* For some reason DB migration for LMDB was disabled in 2014 (in commit * 8611970bfa33be7b3cf0724eb684833e08582850). Unfortunately there is no * mention as to why this was done. Maybe it was not working? * * However, we're re-enabling it now (10 years later). Since this * migration function has not been active for the last 10 years, the * safest thing is to remove the migration logic, and only update the * version number. * * If you have not upgraded CFEngine in the last 10 years, this will be * the least of your problems. */ return WriteDB(db, "version", "1", sizeof("1")); } static bool LastseenMigrationVersion1(DBHandle *db) { DBCursor *cursor; if (!NewDBCursor(db, &cursor)) { Log(LOG_LEVEL_ERR, "Unable to create database cursor during lastseen migration"); return false; } char *key; void *value; int key_size, value_size; // Iterate through all key-value pairs while (NextDB(cursor, &key, &key_size, &value, &value_size)) { if (key_size == 0) { Log(LOG_LEVEL_WARNING, "Found zero-length key during lastseen migration"); continue; } // Only look for old KeyHostSeen entries if (key[0] != 'q') { // Warn about completely unexpected keys if ((key[0] != 'k') && (key[0] != 'a') && !StringEqualN(key, "version", key_size)) { Log(LOG_LEVEL_WARNING, "Found unexpected key '%s' during lastseen migration. " "Only expecting 'version' or 'k', 'a' and 'q[i|o]' prefixed keys.", key); } continue; } KeyHostSeen1 *old_value = value; KeyHostSeen new_value = { .acknowledged = true, // We don't know, assume yes .lastseen = old_value->lastseen, .Q = old_value->Q, }; // This will overwrite the entry if (!DBCursorWriteEntry(cursor, &new_value, sizeof(new_value))) { Log(LOG_LEVEL_ERR, "Unable to write version 2 of entry for key '%s' during lastseen migration.", key); return false; } } if (!DeleteDBCursor(cursor)) { Log(LOG_LEVEL_ERR, "Unable to close cursor during lastseen migration"); return false; } if (!WriteDB(db, "version", "2", sizeof("2"))) { Log(LOG_LEVEL_ERR, "Failed to update version number during lastseen migration"); return false; } Log(LOG_LEVEL_INFO, "Migrated lastseen database from version 1 to 2"); return true; } const DBMigrationFunction dbm_migration_plan_lastseen[] = { LastseenMigrationVersion0, LastseenMigrationVersion1, NULL }; cfengine-3.24.2/libpromises/cf3parse.y0000644000000000000000000011501015010704253017601 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ %{ #include %} %token IDENTIFIER QUOTED_STRING CLASS_GUARD PROMISE_GUARD BUNDLE BODY PROMISE FAT_ARROW THIN_ARROW NAKEDVAR %expect 1 %% specification: /* empty */ | blocks /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ blocks: block | blocks block; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ block: bundle | body | promise | error { ParseError("Expected 'bundle' or 'body' keyword, wrong input '%s'", yytext); YYABORT; } bundle: BUNDLE bundletype bundleid arglist bundlebody body: BODY bodytype bodyid arglist bodybody promise: PROMISE promisecomponent promiseid arglist bodybody /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bundletype: bundletype_values { ParserBeginBlock(PARSER_BLOCK_BUNDLE); } bundletype_values: typeid { /* FIXME: We keep it here, because we skip unknown * promise bundles. Ought to be moved to * after-parsing step once we know how to deal with * it */ if (!BundleTypeCheck(P.blocktype)) { ParseError("Unknown bundle type '%s'", P.blocktype); INSTALL_SKIP = true; } } | error { yyclearin; ParseError("Expected bundle type, wrong input '%s'", yytext); INSTALL_SKIP = true; } bundleid: bundleid_values { ParserDebug("\tP:bundle:%s:%s\n", P.blocktype, P.blockid); CURRENT_BLOCKID_LINE = P.line_no; } bundleid_values: symbol | error { yyclearin; ParseError("Expected bundle identifier, wrong input '%s'", yytext); INSTALL_SKIP = true; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bodytype: bodytype_values { ParserBeginBlock(PARSER_BLOCK_BODY); } bodytype_values: typeid { if (!BodySyntaxGet(PARSER_BLOCK_BODY, P.blocktype)) { ParseError("Unknown body type '%s'", P.blocktype); } } | error { yyclearin; ParseError("Expected body type, wrong input '%s'", yytext); } bodyid: bodyid_values { ParserDebug("\tP:body:%s:%s\n", P.blocktype, P.blockid); CURRENT_BLOCKID_LINE = P.line_no; } bodyid_values: symbol | error { yyclearin; ParseError("Expected body identifier, wrong input '%s'", yytext); INSTALL_SKIP = true; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promisecomponent: promisecomponent_values { ParserBeginBlock(PARSER_BLOCK_PROMISE); } promisecomponent_values: typeid { if (!StringEqual(P.blocktype, "agent")) { ParseError("Custom promises only supported for 'agent', not '%s'", P.blocktype); } } | error { yyclearin; ParseError("Expected 'agent', got '%s'", yytext); } promiseid: promiseid_values { if (IsBuiltInPromiseType(P.blockid)) { ParseError("'%s' promises are built in and cannot be custom", yytext); } ParserDebug("\tP:promise:%s:%s\n", P.blocktype, P.blockid); CURRENT_BLOCKID_LINE = P.line_no; } promiseid_values: symbol | error { yyclearin; ParseError("Expected promise type identifier, wrong input '%s'", yytext); INSTALL_SKIP = true; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ typeid: IDENTIFIER { strncpy(P.blocktype,P.currentid,CF_MAXVARSIZE); RlistDestroy(P.useargs); P.useargs = NULL; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ symbol: IDENTIFIER { strncpy(P.blockid,P.currentid,CF_MAXVARSIZE); P.offsets.last_block_id = P.offsets.last_id; }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ arglist: /* Empty */ | arglist_begin aitems arglist_end | arglist_begin arglist_end | arglist_begin error { yyclearin; ParseError("Error in bundle parameter list, expected ')', wrong input '%s'", yytext); } arglist_begin: '(' { ParserDebug("P:%s:%s:%s arglist begin:%s\n", ParserBlockString(P.block),P.blocktype,P.blockid, yytext); } arglist_end: ')' { ParserDebug("P:%s:%s:%s arglist end:%s\n", ParserBlockString(P.block),P.blocktype,P.blockid, yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ aitems: aitem | aitem ',' | aitem ',' aitems /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ aitem: IDENTIFIER /* recipient of argument is never a literal */ { ParserDebug("P:%s:%s:%s arg id: %s\n", ParserBlockString(P.block),P.blocktype,P.blockid, P.currentid); RlistAppendScalar(&(P.useargs),P.currentid); } | error { yyclearin; ParseError("Expected identifier, wrong input '%s'", yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bundlebody: body_begin { ParserBeginBundleBody(); } bundle_decl '}' { INSTALL_SKIP = false; ParserEndCurrentBlock(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ body_begin: '{' { ParserDebug("P:%s:%s:%s begin body open\n", ParserBlockString(P.block),P.blocktype,P.blockid); } | error { ParseError("Expected body open '{', wrong input '%s'", yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bundle_decl: /* empty */ | bundle_statements /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bundle_statements: bundle_statement | bundle_statements bundle_statement | error { INSTALL_SKIP = true; ParseError("Expected promise type, got '%s'", yytext); ParserDebug("P:promise_type:error yychar = %d, %c, yyempty = %d\n", yychar, yychar, YYEMPTY); yyclearin; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bundle_statement: promise_guard classpromises_decl /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promise_guard: PROMISE_GUARD /* BUNDLE ONLY */ { ParserHandlePromiseGuard(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ classpromises_decl: /* empty */ | classpromises /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ classpromises: classpromise | classpromises classpromise /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ classpromise: class | promise_decl { ParserCheckPromiseLine(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promise_decl: promise_line ';' | promiser error { /* * Based on yychar display right error message */ ParserDebug("P:promiser:error yychar = %d\n", yychar); if (yychar =='-' || yychar == '>') { ParseError("Expected '->', got '%s'", yytext); } else if (yychar == IDENTIFIER) { ParseError("Expected attribute, got '%s'", yytext); } else if (yychar == ',') { ParseError("Expected attribute, got '%s' (comma after promiser is not allowed since 3.5.0)", yytext); } else { ParseError("Expected ';', got '%s'", yytext); } yyclearin; } promise_line: promise_with_promisee | promise_without_promisee /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promise_with_promisee: promiser promisee_arrow rval { if (!INSTALL_SKIP) { if (!P.currentstype) { ParseError("Missing promise type declaration"); } P.currentpromise = BundleSectionAppendPromise(P.currentstype, P.promiser, RvalCopy(P.rval), P.currentclasses ? P.currentclasses : "any", P.currentvarclasses); P.currentpromise->offset.line = CURRENT_PROMISER_LINE; P.currentpromise->offset.start = P.offsets.last_string; P.currentpromise->offset.context = P.offsets.last_class_id; } else { P.currentpromise = NULL; } } promise_decl_constraints /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promise_without_promisee: promiser { if (!INSTALL_SKIP) { if (!P.currentstype) { ParseError("Missing promise type declaration"); } P.currentpromise = BundleSectionAppendPromise(P.currentstype, P.promiser, (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, P.currentclasses ? P.currentclasses : "any", P.currentvarclasses); P.currentpromise->offset.line = CURRENT_PROMISER_LINE; P.currentpromise->offset.start = P.offsets.last_string; P.currentpromise->offset.context = P.offsets.last_class_id; } else { P.currentpromise = NULL; } } promise_decl_constraints /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promiser: QUOTED_STRING { if (P.promiser) { free(P.promiser); } P.promiser = P.currentstring; P.currentstring = NULL; CURRENT_PROMISER_LINE = P.line_no; ParserDebug("\tP:%s:%s:%s:%s:%s promiser = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currenttype, P.currentclasses ? P.currentclasses : "any", P.promiser); } | error { INSTALL_SKIP = true; ParserDebug("P:promiser:qstring::error yychar = %d\n", yychar); if (yychar == BUNDLE || yychar == BODY) { ParseError("Expected '}', got '%s'", yytext); /* YYABORT; */ } else { ParseError("Expected promiser string, got '%s'", yytext); } yyclearin; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promise_decl_constraints: /* empty */ | constraints_decl | constraints_decl error { /* * Based on next token id display right error message */ ParserDebug("P:constraints_decl:error yychar = %d\n", yychar); if ( yychar == IDENTIFIER ) { ParseError("Check previous line, Expected ',', got '%s'", yytext); } else { ParseError("Check previous line, Expected ';', got '%s'", yytext); } yyclearin; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ constraints_decl: constraints { /* Don't free these */ strcpy(P.currentid,""); RlistDestroy(P.currentRlist); P.currentRlist = NULL; free(P.promiser); if (P.currentstring) { free(P.currentstring); } P.currentstring = NULL; P.promiser = NULL; P.promisee = NULL; /* reset argptrs etc*/ } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ constraints: constraint /* BUNDLE ONLY */ | constraints ',' constraint /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ constraint: constraint_id /* BUNDLE ONLY */ assign_arrow rval { ParserHandleBundlePromiseRval(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ constraint_id: IDENTIFIER /* BUNDLE ONLY */ { ParserDebug("\tP:%s:%s:%s:%s:%s:%s attribute = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currenttype, P.currentclasses ? P.currentclasses : "any", P.promiser, P.currentid); const PromiseTypeSyntax *promise_type_syntax = PromiseTypeSyntaxGet(P.blocktype, P.currenttype); if (promise_type_syntax == NULL) { // This promise type might be defined in another Policy object. // There is no way to distinguish a custom promise type // from a wrong (misspelled) promise type while parsing // since the Policy objects will be merged later. } else if (!PromiseTypeSyntaxGetConstraintSyntax(promise_type_syntax, P.currentid)) { // Built in promise type with bad attribute ParseError("Unknown attribute '%s' for promise type '%s' in bundle with type '%s'", P.currentid, P.currenttype, P.blocktype); INSTALL_SKIP = true; } strncpy(P.lval,P.currentid,CF_MAXVARSIZE); RlistDestroy(P.currentRlist); P.currentRlist = NULL; } | error { ParseError("Expected attribute, got '%s'\n", yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bodybody: body_begin { ParserBeginBlockBody(); } bodybody_inner '}' { ParserEndCurrentBlock(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bodybody_inner: /* empty */ | bodyattribs bodyattribs: bodyattrib /* BODY/PROMISE ONLY */ | bodyattribs bodyattrib /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bodyattrib: class | selection_line /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ selection_line: selection ';' | selection error { ParseError("Expected ';' check previous statement, got '%s'", yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ selection: selection_id /* BODY/PROMISE ONLY */ assign_arrow rval { ParserHandleBlockAttributeRval(); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ selection_id: IDENTIFIER { ParserDebug("\tP:%s:%s:%s:%s attribute = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentid); if (!INSTALL_SKIP) { const BodySyntax *body_syntax = BodySyntaxGet(P.block, P.currentbody->type); if (!body_syntax || (body_syntax->status != SYNTAX_STATUS_CUSTOM && !BodySyntaxGetConstraintSyntax(body_syntax->constraints, P.currentid))) { ParseError( "Unknown attribute '%s' for '%s %s %s'", P.currentid, // attribute name (lval) ParserBlockString(P.block), // body (block type) P.currentbody->type, // file (body type) P.blockid); // control (body name) INSTALL_SKIP = true; } strncpy(P.lval,P.currentid,CF_MAXVARSIZE); } RlistDestroy(P.currentRlist); P.currentRlist = NULL; } | error { ParserDebug("P:selection_id:idsyntax:error yychar = %d\n", yychar); if ( yychar == BUNDLE || yychar == BODY ) { ParseError("Expected '}', got '%s'", yytext); /* YYABORT; */ } else { ParseError("Expected attribute, got '%s'", yytext); } yyclearin; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ assign_arrow: FAT_ARROW { ParserDebug("\tP:=>\n"); } | error { yyclearin; ParseError("Expected '=>', got '%s'", yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ promisee_arrow: THIN_ARROW { ParserDebug("\tP:->\n"); } /* else we display the wrong error | error { yyclearin; ParseError("Expected '->', got '%s'", yytext); } */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ class: CLASS_GUARD { P.offsets.last_class_id = P.offsets.current - strlen(P.currentclasses ? P.currentclasses : P.currentvarclasses) - 2; ParserDebug("\tP:%s:%s:%s:%s %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currenttype, P.currentclasses ? "class": "varclass", yytext); if (P.currentclasses != NULL) { char *literal = xstrdup(P.currentclasses); ValidateClassLiteral(literal); free(literal); } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ rval: IDENTIFIER { ParserDebug("\tP:%s:%s:%s:%s id rval, %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval, P.currentid); RvalDestroy(P.rval); P.rval = (Rval) { xstrdup(P.currentid), RVAL_TYPE_SCALAR }; P.references_body = true; } | QUOTED_STRING { ParserDebug("\tP:%s:%s:%s:%s qstring rval, %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval, P.currentstring); RvalDestroy(P.rval); P.rval = (Rval) { P.currentstring, RVAL_TYPE_SCALAR }; P.currentstring = NULL; P.references_body = false; if (P.currentpromise) { if (LvalWantsBody(P.currentpromise->parent_section->promise_type, P.lval)) { yyerror("An rvalue is quoted, but we expect an unquoted body identifier"); } } } | NAKEDVAR { ParserDebug("\tP:%s:%s:%s:%s nakedvar rval, %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval, P.currentstring); RvalDestroy(P.rval); P.rval = (Rval) { P.currentstring, RVAL_TYPE_SCALAR }; P.currentstring = NULL; P.references_body = false; } | list { ParserDebug("\tP:%s:%s:%s:%s install list = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval); RvalDestroy(P.rval); P.rval = (Rval) { RlistCopy(P.currentRlist), RVAL_TYPE_LIST }; RlistDestroy(P.currentRlist); P.currentRlist = NULL; P.references_body = false; } | usefunction { RvalDestroy(P.rval); P.rval = (Rval) { P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL }; P.currentfncall[P.arg_nesting+1] = NULL; P.references_body = false; } | error { yyclearin; ParseError("Invalid r-value type '%s'", yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ list: '{' '}' | '{' litems '}' | '{' litems ',' '}' /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ litems: litem | litems ',' litem | litem error { ParserDebug("P:rval:list:error yychar = %d\n", yychar); if ( yychar ==';' ) { ParseError("Expected '}', wrong input '%s'", yytext); } else if ( yychar == FAT_ARROW ) { ParseError("Check list statement previous line," " Expected '}', wrong input '%s'", yytext); } else { ParseError("Expected ',', wrong input '%s'", yytext); } yyclearin; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ litem: IDENTIFIER { ParserDebug("\tP:%s:%s:%s:%s list append: " "id = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, (P.currentclasses ? P.currentclasses : "any"), P.currentid); RlistAppendScalar((Rlist **) &P.currentRlist, P.currentid); } | QUOTED_STRING { ParserDebug("\tP:%s:%s:%s:%s list append: " "qstring = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, (P.currentclasses ? P.currentclasses : "any"), P.currentstring); ParserHandleQuotedListItem(); } | NAKEDVAR { ParserDebug("\tP:%s:%s:%s:%s list append: nakedvar = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentstring); RlistAppendScalar((Rlist **)&P.currentRlist,(void *)P.currentstring); free(P.currentstring); P.currentstring = NULL; } | usefunction { RlistAppend(&P.currentRlist, P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL); FnCallDestroy(P.currentfncall[P.arg_nesting+1]); P.currentfncall[P.arg_nesting+1] = NULL; } | error { yyclearin; ParseError("Invalid input for a list item, got '%s'", yytext); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ functionid: IDENTIFIER { ParserDebug("\tP:%s:%s:%s:%s function id = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentid); } | NAKEDVAR { ParserDebug("\tP:%s:%s:%s:%s function nakedvar = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentstring); strncpy(P.currentid, P.currentstring, CF_MAXVARSIZE - 1); // Make a var look like an ID free(P.currentstring); P.currentstring = NULL; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ usefunction: functionid givearglist { ParserDebug("\tP:%s:%s:%s:%s Finished with function, now at level %d\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.arg_nesting); }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ givearglist: '(' { if (++P.arg_nesting >= CF_MAX_NESTING) { fatal_yyerror("Nesting of functions is deeper than recommended"); } P.currentfnid[P.arg_nesting] = xstrdup(P.currentid); ParserDebug("\tP:%s:%s:%s begin givearglist for function %s, level %d\n", ParserBlockString(P.block),P.blocktype,P.blockid, P.currentfnid[P.arg_nesting], P.arg_nesting ); } gaitems ')' { ParserDebug("\tP:%s:%s:%s end givearglist for function %s, level %d\n", ParserBlockString(P.block),P.blocktype,P.blockid, P.currentfnid[P.arg_nesting], P.arg_nesting ); P.currentfncall[P.arg_nesting] = FnCallNew(P.currentfnid[P.arg_nesting], P.giveargs[P.arg_nesting]); P.giveargs[P.arg_nesting] = NULL; strcpy(P.currentid,""); free(P.currentfnid[P.arg_nesting]); P.currentfnid[P.arg_nesting] = NULL; P.arg_nesting--; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ gaitems: /* empty */ | gaitem | gaitems ',' gaitem | gaitem error { ParseError("Expected ',', wrong input '%s'", yytext); yyclearin; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ gaitem: IDENTIFIER { ParserDebug("\tP:%s:%s:%s:%s function %s, id arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentid); /* currently inside a use function */ RlistAppendScalar(&P.giveargs[P.arg_nesting],P.currentid); } | QUOTED_STRING { /* currently inside a use function */ ParserDebug("\tP:%s:%s:%s:%s function %s, qstring arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentstring); RlistAppendScalar(&P.giveargs[P.arg_nesting],P.currentstring); free(P.currentstring); P.currentstring = NULL; } | NAKEDVAR { /* currently inside a use function */ ParserDebug("\tP:%s:%s:%s:%s function %s, nakedvar arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentstring); RlistAppendScalar(&P.giveargs[P.arg_nesting],P.currentstring); free(P.currentstring); P.currentstring = NULL; } | usefunction { /* Careful about recursion */ ParserDebug("\tP:%s:%s:%s:%s function %s, nakedvar arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentstring); RlistAppend(&P.giveargs[P.arg_nesting], P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL); RvalDestroy((Rval) { P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL }); P.currentfncall[P.arg_nesting+1] = NULL; } | error { ParserDebug("P:rval:function:gaitem:error yychar = %d\n", yychar); if (yychar == ';') { ParseError("Expected ')', wrong input '%s'", yytext); } else if (yychar == FAT_ARROW ) { ParseError("Check function statement previous line, Expected ')', wrong input '%s'", yytext); } else { ParseError("Invalid function argument, wrong input '%s'", yytext); } yyclearin; } %% cfengine-3.24.2/libpromises/verify_vars.h0000644000000000000000000000225315010704253020415 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_VARS_H #define CFENGINE_VERIFY_VARS_H #include #include PromiseResult VerifyVarPromise(EvalContext *ctx, const Promise *pp, void *param); #endif cfengine-3.24.2/libpromises/promises.c0000644000000000000000000010217015010704253017711 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include static void AddDefaultBodiesToPromise(EvalContext *ctx, Promise *promise, const PromiseTypeSyntax *syntax); void CopyBodyConstraintsToPromise(EvalContext *ctx, Promise *pp, const Body *bp) { for (size_t k = 0; k < SeqLength(bp->conlist); k++) { Constraint *scp = SeqAt(bp->conlist, k); if (IsDefinedClass(ctx, scp->classes)) { Rval returnval = ExpandPrivateRval(ctx, NULL, "body", scp->rval.item, scp->rval.type); PromiseAppendConstraint(pp, scp->lval, returnval, false); } } } /** * Get a map that rewrites body according to parameters. * * @NOTE make sure you free the returned map with JsonDestroy(). */ static JsonElement *GetBodyRewriter(const EvalContext *ctx, const Body *current_body, const Rval *called_rval, bool in_inheritance_chain) { size_t given_args = 0; JsonElement *arg_rewriter = JsonObjectCreate(2); if (called_rval == NULL) { // nothing needed, this is not an inherit_from rval } else if (called_rval->type == RVAL_TYPE_SCALAR) { // We leave the parameters as they were. // Unless the current body matches the // parameters of the inherited body, there // will be unexpanded variables. But the // alternative is to match up body and fncall // arguments, which is not trivial. } else if (called_rval->type == RVAL_TYPE_FNCALL) { const Rlist *call_args = RvalFnCallValue(*called_rval)->args; const Rlist *body_args = current_body->args; given_args = RlistLen(call_args); while (call_args != NULL && body_args != NULL) { JsonObjectAppendString(arg_rewriter, RlistScalarValue(body_args), RlistScalarValue(call_args)); call_args = call_args->next; body_args = body_args->next; } } size_t required_args = RlistLen(current_body->args); // only check arguments for inherited bodies if (in_inheritance_chain && required_args != given_args) { FatalError(ctx, "Argument count mismatch for body " "(gave %zu arguments) vs. inherited body '%s:%s' " "(requires %zu arguments)", given_args, current_body->ns, current_body->name, required_args); } return arg_rewriter; } /** * Appends expanded bodies to the promise #pcopy. It expands the bodies based * on arguments, inheritance, and it can optionally flatten the '@' slists and * expand the variables in the body according to the EvalContext. */ static void AppendExpandedBodies(EvalContext *ctx, Promise *pcopy, const Seq *bodies_and_args, bool flatten_slists, bool expand_body_vars) { size_t ba_len = SeqLength(bodies_and_args); /* Iterate over all parent bodies, and finally over the body of the * promise itself, expanding arguments. We have already reversed the Seq * so we start with the most distant parent in the inheritance tree. */ for (size_t i = 0; i < ba_len; i += 2) { const Rval *called_rval = SeqAt(bodies_and_args, i); const Body *current_body = SeqAt(bodies_and_args, i + 1); bool in_inheritance_chain= (ba_len - i > 2); JsonElement *arg_rewriter = GetBodyRewriter(ctx, current_body, called_rval, in_inheritance_chain); size_t constraints_num = SeqLength(current_body->conlist); for (size_t k = 0; k < constraints_num; k++) { const Constraint *scp = SeqAt(current_body->conlist, k); // we don't copy the inherit_from attribute or associated call if (strcmp("inherit_from", scp->lval) == 0) { continue; } if (IsDefinedClass(ctx, scp->classes)) { /* We copy the Rval expanding all, including inherited, * body arguments. */ Rval newrv = RvalCopyRewriter(scp->rval, arg_rewriter); /* Expand '@' slists. */ if (flatten_slists && newrv.type == RVAL_TYPE_LIST) { RlistFlatten(ctx, (Rlist **) &newrv.item); } /* Expand body vars; note it has to happen ONLY ONCE. */ if (expand_body_vars) { Rval newrv2 = ExpandPrivateRval(ctx, NULL, "body", newrv.item, newrv.type); RvalDestroy(newrv); newrv = newrv2; } /* PromiseAppendConstraint() overwrites existing constraints, thus inheritance just works, as it correctly overwrites parents' constraints. */ Constraint *scp_copy = PromiseAppendConstraint(pcopy, scp->lval, newrv, false); scp_copy->offset = scp->offset; char *rval_s = RvalToString(scp->rval); char *rval_exp_s = RvalToString(scp_copy->rval); Log(LOG_LEVEL_DEBUG, "DeRefCopyPromise(): " "expanding constraint '%s': '%s' -> '%s'", scp->lval, rval_s, rval_exp_s); free(rval_exp_s); free(rval_s); } } /* for all body constraints */ JsonDestroy(arg_rewriter); } } static Rval GetExpandedBodyAsContainer(EvalContext *ctx, const Seq *bodies_and_args, bool flatten_slists, bool expand_body_vars) { const size_t ba_len = SeqLength(bodies_and_args); JsonElement *body = JsonObjectCreate(ba_len / 2); /* Iterate over all parent bodies, and finally over the body of the * promise itself, expanding arguments. We have already reversed the Seq * so we start with the most distant parent in the inheritance tree. */ for (size_t i = 0; i < ba_len; i += 2) { const Rval *called_rval = SeqAt(bodies_and_args, i); const Body *current_body = SeqAt(bodies_and_args, i + 1); bool in_inheritance_chain = (ba_len - i > 2); JsonElement *arg_rewriter = GetBodyRewriter(ctx, current_body, called_rval, in_inheritance_chain); const size_t constraints_num = SeqLength(current_body->conlist); for (size_t k = 0; k < constraints_num; k++) { const Constraint *scp = SeqAt(current_body->conlist, k); // we don't copy the inherit_from attribute or associated call if (StringEqual("inherit_from", scp->lval)) { continue; } if (IsDefinedClass(ctx, scp->classes)) { /* We copy the Rval expanding all, including inherited, * body arguments. */ Rval newrv = RvalCopyRewriter(scp->rval, arg_rewriter); /* Expand '@' slists. */ if (flatten_slists && newrv.type == RVAL_TYPE_LIST) { RlistFlatten(ctx, (Rlist **) &newrv.item); } /* Expand body vars; note it has to happen ONLY ONCE. */ if (expand_body_vars) { Rval newrv2 = ExpandPrivateRval(ctx, NULL, "body", newrv.item, newrv.type); RvalDestroy(newrv); newrv = newrv2; } /* JsonObjectAppendElement() overwrites existing constraints, thus inheritance just works, as it correctly overwrites parents' constraints. */ JsonObjectAppendElement(body, scp->lval, RvalToJson(newrv)); if (WouldLog(LOG_LEVEL_DEBUG)) { char *rval_s = RvalToString(scp->rval); char *rval_exp_s = RvalToString(newrv); Log(LOG_LEVEL_DEBUG, "DeRefCopyPromise(): " "expanding constraint '%s': '%s' -> '%s'", scp->lval, rval_s, rval_exp_s); free(rval_exp_s); free(rval_s); } } } /* for all body constraints */ JsonDestroy(arg_rewriter); } return RvalNew((void *) body, RVAL_TYPE_CONTAINER); } /** * Copies the promise, expanding the constraints. * * 1. copy the promise itself * 2. copy constraints: copy the bodies expanding arguments passed * (arg_rewrite), copy the bundles, copy the rest of the constraints * 3. flatten '@' slists everywhere * 4. handle body inheritance */ Promise *DeRefCopyPromise(EvalContext *ctx, const Promise *pp) { Log(LOG_LEVEL_DEBUG, "DeRefCopyPromise(): promiser:'%s'", SAFENULL(pp->promiser)); Promise *pcopy = xcalloc(1, sizeof(Promise)); if (pp->promiser) { pcopy->promiser = xstrdup(pp->promiser); } /* Copy promisee (if not NULL) while expanding '@' slists. */ pcopy->promisee = RvalCopy(pp->promisee); if (pcopy->promisee.type == RVAL_TYPE_LIST) { RlistFlatten(ctx, (Rlist **) &pcopy->promisee.item); } if (pp->promisee.item != NULL) { char *promisee_string = RvalToString(pp->promisee); CF_ASSERT(pcopy->promisee.item != NULL, "DeRefCopyPromise: Failed to copy promisee: %s", promisee_string); Log(LOG_LEVEL_DEBUG, "DeRefCopyPromise(): " "expanded promisee: '%s'", promisee_string); free(promisee_string); } assert(pp->classes); pcopy->classes = xstrdup(pp->classes); pcopy->parent_section = pp->parent_section; pcopy->offset.line = pp->offset.line; pcopy->comment = pp->comment ? xstrdup(pp->comment) : NULL; pcopy->conlist = SeqNew(10, ConstraintDestroy); pcopy->org_pp = pp->org_pp; pcopy->offset = pp->offset; /* No further type checking should be necessary here, already done by CheckConstraintTypeMatch */ for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); const Policy *policy = PolicyFromPromise(pp); /* bodies_and_args: Do we have body to expand, possibly with arguments? * At position 0 we'll have the body, then its rval, then the same for * each of its inherit_from parents. */ Seq *bodies_and_args = NULL; const Rlist *args = NULL; const char *body_reference = NULL; /* A body template reference could look like a scalar or fn to the parser w/w () */ switch (cp->rval.type) { case RVAL_TYPE_SCALAR: if (cp->references_body) { body_reference = RvalScalarValue(cp->rval); bodies_and_args = EvalContextResolveBodyExpression(ctx, policy, body_reference, cp->lval); } args = NULL; break; case RVAL_TYPE_FNCALL: body_reference = RvalFnCallValue(cp->rval)->name; bodies_and_args = EvalContextResolveBodyExpression(ctx, policy, body_reference, cp->lval); args = RvalFnCallValue(cp->rval)->args; break; default: break; } /* First case is: we have a body to expand lval = body(args). */ if (bodies_and_args != NULL && SeqLength(bodies_and_args) > 0) { const Body *bp = SeqAt(bodies_and_args, 0); assert(bp != NULL); SeqReverse(bodies_and_args); // when we iterate, start with the furthest parent EvalContextStackPushBodyFrame(ctx, pcopy, bp, args); if (strcmp(bp->type, cp->lval) != 0) { Log(LOG_LEVEL_ERR, "Body type mismatch for body reference '%s' in promise " "at line %zu of file '%s', '%s' does not equal '%s'", body_reference, pp->offset.line, PromiseGetBundle(pp)->source_path, bp->type, cp->lval); } Log(LOG_LEVEL_DEBUG, "DeRefCopyPromise(): " "copying body %s: '%s'", cp->lval, body_reference); if (IsDefinedClass(ctx, cp->classes) && !bp->is_custom) { /* For new package promises we need to have name of the * package_manager body. */ char body_name[strlen(cp->lval) + 6]; xsnprintf(body_name, sizeof(body_name), "%s_name", cp->lval); PromiseAppendConstraint(pcopy, body_name, (Rval) {xstrdup(bp->name), RVAL_TYPE_SCALAR }, false); /* Keep the referent body type as a boolean for convenience * when checking later. */ PromiseAppendConstraint(pcopy, cp->lval, (Rval) {xstrdup("true"), RVAL_TYPE_SCALAR }, false); } if (bp->args) /* There are arguments to insert */ { if (!args) { Log(LOG_LEVEL_ERR, "Argument mismatch for body reference '%s' in promise " "at line %zu of file '%s'", body_reference, pp->offset.line, PromiseGetBundle(pp)->source_path); } if (bp->is_custom) { PromiseAppendConstraint(pcopy, cp->lval, GetExpandedBodyAsContainer(ctx, bodies_and_args, false, true), false); } else { AppendExpandedBodies(ctx, pcopy, bodies_and_args, false, true); } } else /* No body arguments or body undeclared */ { if (args) /* body undeclared */ { Log(LOG_LEVEL_ERR, "Apparent body '%s' was undeclared or could " "have incorrect args, but used in a promise near " "line %zu of %s (possible unquoted literal value)", RvalScalarValue(cp->rval), pp->offset.line, PromiseGetBundle(pp)->source_path); } else /* no body arguments, but maybe the inherited bodies have */ { if (bp->is_custom) { PromiseAppendConstraint(pcopy, cp->lval, GetExpandedBodyAsContainer(ctx, bodies_and_args, true, false), false); } else { AppendExpandedBodies(ctx, pcopy, bodies_and_args, true, false); } } } EvalContextStackPopFrame(ctx); SeqDestroy(bodies_and_args); } else /* constraint is not a body */ { if (cp->references_body) { // assume this is a typed bundle (e.g. edit_line) const Bundle *callee = EvalContextResolveBundleExpression(ctx, policy, body_reference, cp->lval); if (!callee) { // otherwise, assume this is a method-type call callee = EvalContextResolveBundleExpression(ctx, policy, body_reference, "agent"); if (!callee) { callee = EvalContextResolveBundleExpression(ctx, policy, body_reference, "common"); } } if (callee == NULL && cp->rval.type != RVAL_TYPE_FNCALL && strcmp("ifvarclass", cp->lval) != 0 && strcmp("if", cp->lval) != 0) { char *rval_string = RvalToString(cp->rval); Log(LOG_LEVEL_ERR, "Apparent bundle '%s' was undeclared, but " "used in a promise near line %zu of %s " "(possible unquoted literal value)", rval_string, pp->offset.line, PromiseGetBundle(pp)->source_path); free(rval_string); } Log(LOG_LEVEL_DEBUG, "DeRefCopyPromise(): copying bundle: '%s'", body_reference); } else { Log(LOG_LEVEL_DEBUG, "DeRefCopyPromise(): copying constraint: '%s'", cp->lval); } /* For all non-body constraints: copy the Rval expanding the * '@' list variables. */ if (IsDefinedClass(ctx, cp->classes)) { Rval newrv = RvalCopy(cp->rval); if (newrv.type == RVAL_TYPE_LIST) { RlistFlatten(ctx, (Rlist **) &newrv.item); } PromiseAppendConstraint(pcopy, cp->lval, newrv, false); } } } /* for all constraints */ // Add default body for promise body types that are not present char *bundle_type = pcopy->parent_section->parent_bundle->type; const char *promise_type = PromiseGetPromiseType(pcopy); const PromiseTypeSyntax *syntax = PromiseTypeSyntaxGet(bundle_type, promise_type); AddDefaultBodiesToPromise(ctx, pcopy, syntax); // Add default body for global body types that are not present const PromiseTypeSyntax *global_syntax = PromiseTypeSyntaxGet("*", "*"); AddDefaultBodiesToPromise(ctx, pcopy, global_syntax); return pcopy; } // Try to add default bodies to promise for every body type found in syntax static void AddDefaultBodiesToPromise(EvalContext *ctx, Promise *promise, const PromiseTypeSyntax *syntax) { // do nothing if syntax is not defined if (syntax == NULL) { return; } // iterate over possible constraints for (int i = 0; syntax->constraints[i].lval; i++) { // of type body if(syntax->constraints[i].dtype == CF_DATA_TYPE_BODY) { const char *constraint_type = syntax->constraints[i].lval; // if there is no matching body in this promise if(!PromiseBundleOrBodyConstraintExists(ctx, constraint_type, promise)) { const Policy *policy = PolicyFromPromise(promise); // default format is _ char* default_body_name = StringConcatenate(3, PromiseGetPromiseType(promise), "_", constraint_type); const Body *bp = EvalContextFindFirstMatchingBody(policy, constraint_type, "bodydefault", default_body_name); if(bp) { Log(LOG_LEVEL_VERBOSE, "Using the default body: %60s", default_body_name); CopyBodyConstraintsToPromise(ctx, promise, bp); } free(default_body_name); } } } } /*****************************************************************************/ static bool EvaluateConstraintIteration(EvalContext *ctx, const Constraint *cp, Rval *rval_out) { assert(cp->type == POLICY_ELEMENT_TYPE_PROMISE); const Promise *pp = cp->parent.promise; if (!IsDefinedClass(ctx, cp->classes)) { return false; } if (ExpectedDataType(cp->lval) == CF_DATA_TYPE_BUNDLE) { *rval_out = ExpandBundleReference(ctx, NULL, "this", cp->rval); } else { *rval_out = EvaluateFinalRval(ctx, PromiseGetPolicy(pp), NULL, "this", cp->rval, false, pp); } return true; } /** @brief Helper function to determine whether the Rval of ifvarclass/if/unless is defined. If the Rval is a function, call that function. */ static ExpressionValue CheckVarClassExpression(const EvalContext *ctx, const Constraint *cp, Promise *pcopy) { assert(ctx); assert(cp); assert(pcopy); /* This might fail to expand if there are unexpanded variables in function arguments (in which case the function won't be called at all), but the function still returns true. If expansion fails for other reasons, assume that we don't know this class. */ Rval final; if (!EvaluateConstraintIteration((EvalContext*)ctx, cp, &final)) { return EXPRESSION_VALUE_ERROR; } char *classes = NULL; PromiseAppendConstraint(pcopy, cp->lval, final, false); switch (final.type) { case RVAL_TYPE_SCALAR: classes = RvalScalarValue(final); break; case RVAL_TYPE_FNCALL: Log(LOG_LEVEL_DEBUG, "Function call in class expression did not succeed"); break; default: break; } if (classes == NULL) { return EXPRESSION_VALUE_ERROR; } // sanity check for unexpanded variables if (strchr(classes, '$') || strchr(classes, '@')) { Log(LOG_LEVEL_DEBUG, "Class expression did not evaluate"); return EXPRESSION_VALUE_ERROR; } return CheckClassExpression(ctx, classes); } /* Expands "$(this.promiser)" comment if present. Writes the result to pp. */ static void DereferenceAndPutComment(Promise* pp, const char *comment) { free(pp->comment); char *sp; if ((sp = strstr(comment, "$(this.promiser)")) != NULL || (sp = strstr(comment, "${this.promiser}")) != NULL) { char *s; int this_len = strlen("$(this.promiser)"); int this_offset = sp - comment; xasprintf(&s, "%.*s%s%s", this_offset, comment, pp->promiser, &comment[this_offset + this_len]); pp->comment = s; } else { pp->comment = xstrdup(comment); } } Promise *ExpandDeRefPromise(EvalContext *ctx, const Promise *pp, bool *excluded) { assert(pp != NULL); assert(pp->parent_section != NULL); assert(pp->promiser != NULL); assert(pp->classes != NULL); assert(excluded != NULL); *excluded = false; Rval returnval = ExpandPrivateRval(ctx, PromiseGetNamespace(pp), "this", pp->promiser, RVAL_TYPE_SCALAR); if (returnval.item == NULL) { assert(returnval.type == RVAL_TYPE_LIST || returnval.type == RVAL_TYPE_NOPROMISEE); /* TODO Log() empty slist, promise skipped? */ *excluded = true; return NULL; } Promise *pcopy = xcalloc(1, sizeof(Promise)); pcopy->promiser = RvalScalarValue(returnval); /* TODO remove the conditions here for fixing redmine#7880. */ if (!StringEqual("storage", PromiseGetPromiseType(pp))) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser", pcopy->promiser, CF_DATA_TYPE_STRING, "source=promise"); } if (pp->promisee.item) { pcopy->promisee = EvaluateFinalRval(ctx, PromiseGetPolicy(pp), NULL, "this", pp->promisee, true, pp); } else { pcopy->promisee = (Rval) {NULL, RVAL_TYPE_NOPROMISEE }; } pcopy->classes = xstrdup(pp->classes); pcopy->parent_section = pp->parent_section; pcopy->offset.line = pp->offset.line; pcopy->comment = pp->comment ? xstrdup(pp->comment) : NULL; pcopy->conlist = SeqNew(10, ConstraintDestroy); pcopy->org_pp = pp->org_pp; // if this is a class promise, check if it is already set, if so, skip if (strcmp("classes", PromiseGetPromiseType(pp)) == 0) { if (IsDefinedClass(ctx, CanonifyName(pcopy->promiser))) { Log(LOG_LEVEL_DEBUG, "Skipping evaluation of classes promise as class '%s' is already set", CanonifyName(pcopy->promiser)); *excluded = true; return pcopy; } } /* Look for 'if'/'ifvarclass' exclusion. */ { /* We need to make sure to check both 'if' and 'ifvarclass' constraints. */ bool checked_if = false; const Constraint *ifvarclass = PromiseGetConstraint(pp, "ifvarclass"); if (!ifvarclass) { ifvarclass = PromiseGetConstraint(pp, "if"); checked_if = true; } // if - Skip if false or error: while (ifvarclass != NULL) { if (CheckVarClassExpression(ctx, ifvarclass, pcopy) != EXPRESSION_VALUE_TRUE) { if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { char *ifvarclass_string = RvalToString(ifvarclass->rval); Log(LOG_LEVEL_VERBOSE, "Skipping promise '%s'" " because constraint '%s => %s' is not met", pp->promiser, ifvarclass->lval, ifvarclass_string); free(ifvarclass_string); } *excluded = true; return pcopy; } if (!checked_if) { ifvarclass = PromiseGetConstraint(pp, "if"); checked_if = true; } else { ifvarclass = NULL; } } } /* Look for 'unless' exclusion. */ { const Constraint *unless = PromiseGetConstraint(pp, "unless"); // unless - Skip if true or error: if (unless != NULL) { // If the rval is a function, CheckVarClassExpression will call it // It will evaluate the class expression as well: const ExpressionValue value = CheckVarClassExpression(ctx, unless, pcopy); // If it returns EXPRESSION_VALUE_ERROR, it most likely means there // are unexpanded variables in the rval (possibly in function calls) if ((EvalContextGetPass(ctx) == CF_DONEPASSES-1) && (value == EXPRESSION_VALUE_ERROR)) { char *unless_string = RvalToString(unless->rval); // The rval is most likely a string or a function call, // with unexpanded variables, for example: // unless => "$(no_such_var)" // We default to NOT skipping (since if would skip). Log(LOG_LEVEL_VERBOSE, "Not skipping %s promise '%s' with constraint '%s => %s' in last evaluation pass (since if would skip)", PromiseGetPromiseType(pp), pp->promiser, unless->lval, unless_string); free(unless_string); } else if (value != EXPRESSION_VALUE_FALSE) { if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { char *unless_string = RvalToString(unless->rval); Log(LOG_LEVEL_VERBOSE, "Skipping promise '%s' because constraint '%s => %s' is not met", pp->promiser, unless->lval, unless_string); free(unless_string); } *excluded = true; return pcopy; } } } /* Look for depends_on exclusion. */ { const Constraint *depends_on = PromiseGetConstraint(pp, "depends_on"); if (depends_on) { Rval final; if (EvaluateConstraintIteration(ctx, depends_on, &final)) { PromiseAppendConstraint(pcopy, depends_on->lval, final, false); if (MissingDependencies(ctx, pcopy)) { *excluded = true; return pcopy; } } } } /* NOTE: We have to undefine the '$(this.promiser)' variable for a 'files' * promise now because it is later defined for the individual * expansions of the promise and so it has to be left unexpanded in * the constraints/attributes. It is, however, defined above just like * for any other promise so that it can be used in the common * if/ifvarclass/unless checking. */ if (StringEqual(PromiseGetPromiseType(pp), "files")) { EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser"); } /* Evaluate all constraints. */ for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); // special constraints ifvarclass and depends_on are evaluated before the rest of the constraints if (strcmp(cp->lval, "ifvarclass") == 0 || strcmp(cp->lval, "if") == 0 || strcmp(cp->lval, "unless") == 0 || strcmp(cp->lval, "depends_on") == 0) { continue; } Rval final; if (!EvaluateConstraintIteration(ctx, cp, &final)) { continue; } PromiseAppendConstraint(pcopy, cp->lval, final, false); if (strcmp(cp->lval, "comment") == 0) { if (final.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Comments can only be scalar objects, not '%s' in '%s'", RvalTypeToString(final.type), pp->promiser); } else { assert(final.item != NULL); /* it's SCALAR type */ DereferenceAndPutComment(pcopy, final.item); } } } return pcopy; } void PromiseRef(LogLevel level, const Promise *pp) { if (pp == NULL) { return; } if (PromiseGetBundle(pp)->source_path) { Log(level, "Promise belongs to bundle '%s' in file '%s' near line %zu", PromiseGetBundle(pp)->name, PromiseGetBundle(pp)->source_path, pp->offset.line); } else { Log(level, "Promise belongs to bundle '%s' near line %zu", PromiseGetBundle(pp)->name, pp->offset.line); } if (pp->comment) { Log(level, "Comment is '%s'", pp->comment); } switch (pp->promisee.type) { case RVAL_TYPE_SCALAR: Log(level, "This was a promise to '%s'", (char *)(pp->promisee.item)); break; case RVAL_TYPE_LIST: { Writer *w = StringWriter(); RlistWrite(w, pp->promisee.item); char *p = StringWriterClose(w); Log(level, "This was a promise to '%s'", p); free(p); break; } default: break; } } /*******************************************************************/ /* Old legacy function from Enterprise, TODO remove static string. */ const char *PromiseID(const Promise *pp) { static char id[CF_MAXVARSIZE]; char vbuff[CF_MAXVARSIZE]; const char *handle = PromiseGetHandle(pp); if (handle) { snprintf(id, CF_MAXVARSIZE, "%s", CanonifyName(handle)); } else if (pp && PromiseGetBundle(pp)->source_path) { snprintf(vbuff, CF_MAXVARSIZE, "%s", ReadLastNode(PromiseGetBundle(pp)->source_path)); snprintf(id, CF_MAXVARSIZE, "promise_%s_%zu", CanonifyName(vbuff), pp->offset.line); } else { snprintf(id, CF_MAXVARSIZE, "unlabelled_promise"); } return id; } cfengine-3.24.2/libpromises/systype.c0000644000000000000000000001704615010704253017577 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #if defined __FreeBSD__ #include #endif /* Set in libenv/sysinfo.c::DetectEnvironment (called every time environment reload is performed). Utilized all over the place, usually to look up OS-specific command/option to call external utility */ PlatformContext VSYSTEMHARDCLASS; /* GLOBAL_E?, initialized_later */ PlatformContext VPSHARDCLASS; /* used to define which ps command to use*/ /* Configure system name and system-specific details. */ const char *const CLASSTEXT[] = { [PLATFORM_CONTEXT_UNKNOWN] = "", [PLATFORM_CONTEXT_OPENVZ] = "virt_host_vz_vzps", [PLATFORM_CONTEXT_HP] = "hpux", [PLATFORM_CONTEXT_AIX] = "aix", [PLATFORM_CONTEXT_LINUX] = "linux", [PLATFORM_CONTEXT_BUSYBOX] = "linux", [PLATFORM_CONTEXT_SOLARIS] = "solaris", [PLATFORM_CONTEXT_SUN_SOLARIS] = "solaris", [PLATFORM_CONTEXT_FREEBSD] = "freebsd", [PLATFORM_CONTEXT_NETBSD] = "netbsd", [PLATFORM_CONTEXT_CRAYOS] = "cray", [PLATFORM_CONTEXT_WINDOWS_NT] = "windows", [PLATFORM_CONTEXT_SYSTEMV] = "unix_sv", [PLATFORM_CONTEXT_OPENBSD] = "openbsd", [PLATFORM_CONTEXT_CFSCO] = "sco", [PLATFORM_CONTEXT_DARWIN] = "darwin", [PLATFORM_CONTEXT_QNX] = "qnx", [PLATFORM_CONTEXT_DRAGONFLY] = "dragonfly", [PLATFORM_CONTEXT_MINGW] = "windows", [PLATFORM_CONTEXT_VMWARE] = "vmware", [PLATFORM_CONTEXT_ANDROID] = "android", }; const char *const VPSCOMM[] = { [PLATFORM_CONTEXT_UNKNOWN] = "", [PLATFORM_CONTEXT_OPENVZ] = "/bin/vzps", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/bin/ps", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/bin/ps", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/bin/ps", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "/bin/ps", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/bin/ps", /* solaris >= 11 */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/bin/ps", /* solaris < 11 */ [PLATFORM_CONTEXT_FREEBSD] = "/bin/ps", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/bin/ps", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/bin/ps", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "/bin/ps", /* NT - cygnus */ [PLATFORM_CONTEXT_SYSTEMV] = "/bin/ps", /* unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/bin/ps", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/bin/ps", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "/bin/ps", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/bin/ps", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/bin/ps", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "mingw-invalid", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "/bin/ps", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "/system/xbin/busybox ps", /* android */ }; // linux after rhel 3: ps -eo user,pid,ppid,pgid,%cpu,%mem,vsize,ni,rss,stat,nlwp,stime,time,args // solaris: ps -eo user,pid,ppid,pgid,pcpu,pmem,vsz,pri,rss,nlwp,stime,time,args const char *const VPSOPTS[] = { [PLATFORM_CONTEXT_UNKNOWN] = "", [PLATFORM_CONTEXT_OPENVZ] = "-E 0 -o user,pid,ppid,pgid,pcpu,pmem,vsz,ni,rss,thcount,stime,time,args", /* virt_host_vz_vzps (with vzps, the -E 0 replace the -e) */ [PLATFORM_CONTEXT_HP] = "-ef", /* hpux */ [PLATFORM_CONTEXT_AIX] = "-N -eo user,pid,ppid,pgid,pcpu,pmem,vsz,ni,stat,st=STIME,time,args", /* aix */ /* Note: keep in sync with GetProcessOptions()'s hack for Linux 2.4 */ /* For header text "TTY" specify "tname" (not "tty" which gives header "TT") */ [PLATFORM_CONTEXT_LINUX] = "-eo user:30,pid,ppid,pgid,pcpu,pmem,vsz,ni,rss:9,tname,nlwp,stime,etime,time,args",/* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "", /* linux / busybox */ [PLATFORM_CONTEXT_SOLARIS] = "-eo user,pid,pcpu,pmem,osz,rss,tty,s,stime,time,args", /* solaris >= 11 */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "-eo user,pid,pcpu,pmem,osz,rss,tty,s,stime,time,args", /* solaris < 11 */ #if __FreeBSD_version >= 903000 [PLATFORM_CONTEXT_FREEBSD] = "auxw -J 0", /* freebsd 9.3 and newer */ #else [PLATFORM_CONTEXT_FREEBSD] = "auxw", /* freebsd 9.2 and older*/ #endif [PLATFORM_CONTEXT_NETBSD] = "-axwwo user,pid,ppid,pgid,pcpu,pmem,vsz,ni,rss,nlwp,start,time,args", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "-elyf", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "-aW", /* NT */ [PLATFORM_CONTEXT_SYSTEMV] = "-ef", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "-axwwo user,pid,ppid,pgid,pcpu,pmem,vsz,ni,rss,start,time,args", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "-ef", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "auxw", /* darwin */ [PLATFORM_CONTEXT_QNX] = "-elyf", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "auxw", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "mingw-invalid", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "?", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "", /* android */ }; const char *const VFSTAB[] = { [PLATFORM_CONTEXT_UNKNOWN] = "-", [PLATFORM_CONTEXT_OPENVZ] = "/etc/fstab", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/etc/fstab", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/etc/filesystems", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/etc/fstab", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "/etc/fstab", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/etc/vfstab", /* solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/etc/vfstab", /* solaris */ [PLATFORM_CONTEXT_FREEBSD] = "/etc/fstab", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/etc/fstab", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/etc/fstab", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "/etc/fstab", /* NT */ [PLATFORM_CONTEXT_SYSTEMV] = "/etc/vfstab", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/etc/fstab", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/etc/default/filesys",/* sco */ [PLATFORM_CONTEXT_DARWIN] = "/etc/fstab", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/etc/fstab", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/etc/fstab", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "/etc/fstab", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "", /* android */ }; cfengine-3.24.2/libpromises/cmdb.h0000644000000000000000000000237215010704253016765 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CMDB_H #define CFENGINE_CMDB_H #include #include #define CMDB_SOURCE_TAG "source=cmdb" JsonElement *ReadJsonFile(const char *filename, LogLevel log_level, size_t size_max); bool LoadCMDBData(EvalContext *ctx); #endif /* CFENGINE_CMDB_H */ cfengine-3.24.2/libpromises/eval_context.c0000644000000000000000000033703615010704253020556 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include /* ExpandPrivateRval */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* DataTypeIsIterable */ #include /* If we need to put a scoped variable into a special scope, use the string * below to replace the original scope separator. * (e.g. "config.var" -> "this.config___var" ) */ #define NESTED_SCOPE_SEP "___" static const char *STACK_FRAME_TYPE_STR[STACK_FRAME_TYPE_MAX] = { "BUNDLE", "BODY", "PROMISE_TYPE", "PROMISE", "PROMISE_ITERATION" }; /** Define FuncCacheMap. Key: an Rlist (which is linked list of Rvals) listing all the argument of the function Value: an Rval, the result of the function */ static void RvalDestroy2(void *p) { Rval *rv = p; RvalDestroy(*rv); free(rv); } TYPED_MAP_DECLARE(FuncCache, Rlist *, Rval *) TYPED_MAP_DEFINE(FuncCache, Rlist *, Rval *, RlistHash_untyped, RlistEqual_untyped, RlistDestroy_untyped, RvalDestroy2) /** Define RemoteVarsPromisesMap. Key: bundle name (char *) Value: a sequence of promises (const *Promise), only the container (sequence) should be deallocated) */ static void SeqDestroy_untyped(void *p) { Seq *s = p; SeqDestroy(s); } TYPED_MAP_DECLARE(RemoteVarPromises, char *, Seq *) TYPED_MAP_DEFINE(RemoteVarPromises, char *, Seq *, StringHash_untyped, StringEqual_untyped, free, SeqDestroy_untyped) static Regex *context_expression_whitespace_rx = NULL; #include static bool BundleAborted(const EvalContext *ctx); static void SetBundleAborted(EvalContext *ctx); static void SetEvalAborted(EvalContext *ctx); static bool EvalContextStackFrameContainsSoft(const EvalContext *ctx, const char *context); static bool EvalContextHeapContainsSoft(const EvalContext *ctx, const char *ns, const char *name); static bool EvalContextHeapContainsHard(const EvalContext *ctx, const char *name); static bool EvalContextClassPut(EvalContext *ctx, const char *ns, const char *name, bool is_soft, ContextScope scope, const char *tags, const char *comment); static const char *EvalContextCurrentNamespace(const EvalContext *ctx); static ClassRef IDRefQualify(const EvalContext *ctx, const char *id); /** * Every agent has only one EvalContext from process start to finish. */ struct EvalContext_ { const GenericAgentConfig *config; int eval_options; bool bundle_aborted; bool eval_aborted; bool checksum_updates_default; Item *ip_addresses; bool ignore_locks; int pass; Rlist *args; Rlist *restrict_keys; Item *heap_abort; Item *heap_abort_current_bundle; Seq *stack; ClassTable *global_classes; VariableTable *global_variables; VariableTable *match_variables; StringSet *promise_lock_cache; StringSet *dependency_handles; FuncCacheMap *function_cache; uid_t uid; uid_t gid; pid_t pid; pid_t ppid; // Full path to directory that the binary was launched from. char *launch_directory; char *entry_point; /* new package promise evaluation context */ PackagePromiseContext *package_promise_context; /* select_end_match_eof context*/ bool select_end_match_eof; /* List if all classes set during policy evaluation */ StringSet *all_classes; /* Negated classes (persistent classes that should not be defined). */ StringSet *negated_classes; /* These following two fields are needed for remote variable injection * detection (CFE-1915) */ /* Names of all bundles */ StringSet *bundle_names; /* Promises possibly remotely-injecting variables */ /* ONLY INITIALIZED WHEN NON-EMPTY, OTHERWISE NULL */ RemoteVarPromisesMap *remote_var_promises; bool dump_reports; }; void EvalContextSetConfig(EvalContext *ctx, const GenericAgentConfig *config) { assert(ctx != NULL); ctx->config = config; } const GenericAgentConfig *EvalContextGetConfig(EvalContext *ctx) { assert(ctx != NULL); return ctx->config; } bool EvalContextGetSelectEndMatchEof(const EvalContext *ctx) { return ctx->select_end_match_eof; } void EvalContextSetSelectEndMatchEof(EvalContext *ctx, bool value) { ctx->select_end_match_eof = value; } Rlist *EvalContextGetRestrictKeys(const EvalContext *ctx) { assert(ctx != NULL); return ctx->restrict_keys; } void EvalContextSetRestrictKeys(EvalContext *ctx, const Rlist *restrict_keys) { assert(ctx != NULL); ctx->restrict_keys = RlistCopy(restrict_keys); } void AddDefaultPackageModuleToContext(const EvalContext *ctx, char *name) { assert(ctx); assert(ctx->package_promise_context); free(ctx->package_promise_context->control_package_module); ctx->package_promise_context->control_package_module = SafeStringDuplicate(name); } void AddDefaultInventoryToContext(const EvalContext *ctx, Rlist *inventory) { assert(ctx); assert(ctx->package_promise_context); RlistDestroy(ctx->package_promise_context->control_package_inventory); ctx->package_promise_context->control_package_inventory = RlistCopy(inventory); } static int PackageManagerSeqCompare(const void *a, const void *b, ARG_UNUSED void *data) { return StringSafeCompare((char*)a, ((PackageModuleBody*)b)->name); } void AddPackageModuleToContext(const EvalContext *ctx, PackageModuleBody *pm) { assert(ctx != NULL); assert(pm != NULL); /* First check if the body is there added from previous pre-evaluation * iteration. If it is there update it as we can have new expanded variables. */ Seq *const bodies = ctx->package_promise_context->package_modules_bodies; ssize_t index = SeqIndexOf(bodies, pm->name, PackageManagerSeqCompare); if (index != -1) { SeqRemove(bodies, index); } SeqAppend(bodies, pm); } PackageModuleBody *GetPackageModuleFromContext(const EvalContext *ctx, const char *name) { if (name == NULL) { return NULL; } for (size_t i = 0; i < SeqLength(ctx->package_promise_context->package_modules_bodies); i++) { PackageModuleBody *pm = SeqAt(ctx->package_promise_context->package_modules_bodies, i); if (strcmp(name, pm->name) == 0) { return pm; } } return NULL; } PackageModuleBody *GetDefaultPackageModuleFromContext(const EvalContext *ctx) { char *def_pm_name = ctx->package_promise_context->control_package_module; return GetPackageModuleFromContext(ctx, def_pm_name); } Rlist *GetDefaultInventoryFromContext(const EvalContext *ctx) { return ctx->package_promise_context->control_package_inventory; } PackagePromiseContext *GetPackagePromiseContext(const EvalContext *ctx) { return ctx->package_promise_context; } static StackFrame *LastStackFrame(const EvalContext *ctx, size_t offset) { if (SeqLength(ctx->stack) <= offset) { return NULL; } return SeqAt(ctx->stack, SeqLength(ctx->stack) - 1 - offset); } static StackFrame *LastStackFrameByType(const EvalContext *ctx, StackFrameType type) { for (size_t i = 0; i < SeqLength(ctx->stack); i++) { StackFrame *frame = LastStackFrame(ctx, i); if (frame->type == type) { return frame; } } return NULL; } static LogLevel AdjustLogLevel(LogLevel base, LogLevel adjust) { if (adjust == -1) { return base; } else { return MAX(base, adjust); } } static LogLevel StringToLogLevel(const char *value) { if (value) { if (!strcmp(value, "verbose")) { return LOG_LEVEL_VERBOSE; } if (!strcmp(value, "inform")) { return LOG_LEVEL_INFO; } if (!strcmp(value, "error")) { return LOG_LEVEL_NOTICE; /* Error level includes warnings and notices */ } } return -1; } static LogLevel GetLevelForPromise(const Promise *pp, const char *attr_name) { return StringToLogLevel(PromiseGetConstraintAsRval(pp, attr_name, RVAL_TYPE_SCALAR)); } static LogLevel CalculateLogLevel(const Promise *pp) { LogLevel global_log_level = LogGetGlobalLevel(); LogLevel system_log_level = LogGetGlobalSystemLogLevel(); LogLevel log_level = (system_log_level != LOG_LEVEL_NOTHING ? system_log_level : global_log_level); if (pp) { log_level = AdjustLogLevel(log_level, GetLevelForPromise(pp, "log_level")); } /* Disable system log for dry-runs */ if (DONTDO) { log_level = LOG_LEVEL_NOTHING; } return log_level; } static LogLevel CalculateReportLevel(const Promise *pp) { LogLevel report_level = LogGetGlobalLevel(); if (pp) { report_level = AdjustLogLevel(report_level, GetLevelForPromise(pp, "report_level")); } return report_level; } const char *EvalContextStackToString(EvalContext *ctx) { StackFrame *last_frame = LastStackFrame(ctx, 0); if (last_frame) { return last_frame->path; } return ""; } static const char *GetAgentAbortingContext(const EvalContext *ctx) { for (const Item *ip = ctx->heap_abort; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->classes)) { const char *regex = ip->name; Class *cls = EvalContextClassMatch(ctx, regex); if (cls) { return cls->name; } } } return NULL; } static void EvalContextStackFrameAddSoft(EvalContext *ctx, const char *context, const char *tags) { assert(SeqLength(ctx->stack) > 0); StackFrameBundle frame; { StackFrame *last_frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); if (!last_frame) { ProgrammingError("Attempted to add a soft class on the stack, but stack had no bundle frame"); } frame = last_frame->data.bundle; } char copy[CF_BUFSIZE]; if (strcmp(frame.owner->ns, "default") != 0) { snprintf(copy, CF_MAXVARSIZE, "%s:%s", frame.owner->ns, context); } else { strlcpy(copy, context, CF_MAXVARSIZE); } if (Chop(copy, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } if (strlen(copy) == 0) { return; } if (EvalContextHeapContainsSoft(ctx, frame.owner->ns, context)) { Log(LOG_LEVEL_WARNING, "Private class '%s' in bundle '%s' shadows a global class - you should choose a different name to avoid conflicts", copy, frame.owner->name); } if (IsRegexItemIn(ctx, ctx->heap_abort_current_bundle, copy)) { Log(LOG_LEVEL_ERR, "Bundle '%s' aborted on defined class '%s'", frame.owner->name, copy); SetBundleAborted(ctx); } if (IsRegexItemIn(ctx, ctx->heap_abort, copy)) { Log(LOG_LEVEL_NOTICE, "cf-agent aborted on defined class '%s'", copy); SetEvalAborted(ctx); } if (EvalContextStackFrameContainsSoft(ctx, copy)) { return; } ClassTablePut(frame.classes, frame.owner->ns, context, true, CONTEXT_SCOPE_BUNDLE, NULL_OR_EMPTY(tags) ? NULL : StringSetFromString(tags, ','), NULL); if (!BundleAborted(ctx)) { for (const Item *ip = ctx->heap_abort_current_bundle; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->name)) { Log(LOG_LEVEL_ERR, "Setting abort for '%s' when setting '%s'", ip->name, context); SetBundleAborted(ctx); break; } } } } static ExpressionValue EvalTokenAsClass(const char *classname, void *param) { const EvalContext *ctx = param; ClassRef ref = ClassRefParse(classname); if (ClassRefIsQualified(ref)) { if (strcmp(ref.ns, NamespaceDefault()) == 0) { if (EvalContextHeapContainsHard(ctx, ref.name)) { ClassRefDestroy(ref); return EXPRESSION_VALUE_TRUE; } } } else { if (EvalContextHeapContainsHard(ctx, ref.name)) { ClassRefDestroy(ref); return EXPRESSION_VALUE_TRUE; } const char *ns = EvalContextCurrentNamespace(ctx); if (ns) { ClassRefQualify(&ref, ns); } else { ClassRefQualify(&ref, NamespaceDefault()); } } assert(ClassRefIsQualified(ref)); bool classy = (strcmp("any", ref.name) == 0 || EvalContextHeapContainsSoft(ctx, ref.ns, ref.name) || EvalContextStackFrameContainsSoft(ctx, ref.name)); ClassRefDestroy(ref); return (ExpressionValue) classy; // ExpressionValue extends bool } /**********************************************************************/ static char *EvalVarRef(ARG_UNUSED const char *varname, ARG_UNUSED VarRefType type, ARG_UNUSED void *param) { /* * There should be no unexpanded variables when we evaluate any kind of * logic expressions, until parsing of logic expression changes and they are * not pre-expanded before evaluation. */ return NULL; } /**********************************************************************/ bool ClassCharIsWhitespace(char ch) { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; } ExpressionValue CheckClassExpression(const EvalContext *ctx, const char *context) { assert(context != NULL); ParseResult res; if (!context) { // TODO: Remove this, seems like a hack return EXPRESSION_VALUE_TRUE; } if (context_expression_whitespace_rx == NULL) { context_expression_whitespace_rx = CompileRegex(CFENGINE_REGEX_WHITESPACE_IN_CONTEXTS); } if (context_expression_whitespace_rx == NULL) { Log(LOG_LEVEL_ERR, "The context expression whitespace regular expression could not be compiled, aborting."); return EXPRESSION_VALUE_ERROR; } if (StringMatchFullWithPrecompiledRegex(context_expression_whitespace_rx, context)) { Log(LOG_LEVEL_ERR, "class expressions can't be separated by whitespace without an intervening operator in expression '%s'", context); return EXPRESSION_VALUE_ERROR; } Buffer *condensed = BufferNewFrom(context, strlen(context)); BufferRewrite(condensed, &ClassCharIsWhitespace, true); res = ParseExpression(BufferData(condensed), 0, BufferSize(condensed)); BufferDestroy(condensed); if (!res.result) { Log(LOG_LEVEL_ERR, "Unable to parse class expression '%s'", context); return EXPRESSION_VALUE_ERROR; } else { ExpressionValue r = EvalExpression(res.result, &EvalTokenAsClass, &EvalVarRef, (void *)ctx); // controlled cast. None of these should modify EvalContext FreeExpression(res.result); return r; } } /**********************************************************************/ static ExpressionValue EvalTokenFromList(const char *token, void *param) { StringSet *set = param; return (ExpressionValue) StringSetContains(set, token); // EV extends bool } /**********************************************************************/ bool EvalWithTokenFromList(const char *expr, StringSet *token_set) { ParseResult res = ParseExpression(expr, 0, strlen(expr)); if (!res.result) { Log(LOG_LEVEL_ERR, "Syntax error in expression '%s'", expr); return false; /* FIXME: return error */ } else { ExpressionValue r = EvalExpression(res.result, &EvalTokenFromList, &EvalVarRef, token_set); FreeExpression(res.result); /* r is EvalResult which could be ERROR */ return r == EXPRESSION_VALUE_TRUE; } } /**********************************************************************/ /* Process result expression */ bool EvalProcessResult(const char *process_result, StringSet *proc_attr) { assert(process_result != NULL); if (StringEqual(process_result, "")) { /* nothing to evaluate */ return false; } return EvalWithTokenFromList(process_result, proc_attr); } /**********************************************************************/ /* File result expressions */ bool EvalFileResult(const char *file_result, StringSet *leaf_attr) { return EvalWithTokenFromList(file_result, leaf_attr); } /*****************************************************************************/ void EvalContextHeapPersistentSave(EvalContext *ctx, const char *name, unsigned int ttl_minutes, PersistentClassPolicy policy, const char *tags) { assert(tags); time_t now = time(NULL); CF_DB *dbp; if (!OpenDB(&dbp, dbid_state)) { char *db_path = DBIdToPath(dbid_state); Log(LOG_LEVEL_ERR, "While persisting class, unable to open database at '%s' (OpenDB: %s)", db_path, GetErrorStr()); free(db_path); return; } ClassRef ref = IDRefQualify(ctx, name); char *key = ClassRefToString(ref.ns, ref.name); ClassRefDestroy(ref); size_t tags_length = strlen(tags) + 1; size_t new_info_size = sizeof(PersistentClassInfo) + tags_length; PersistentClassInfo *new_info = xcalloc(1, new_info_size); new_info->expires = now + ttl_minutes * 60; new_info->policy = policy; strlcpy(new_info->tags, tags, tags_length); // first see if we have an existing record, and if we should bother to update { int existing_info_size = ValueSizeDB(dbp, key, strlen(key)); if (existing_info_size > 0) { PersistentClassInfo *existing_info = xcalloc(existing_info_size, 1); if (ReadDB(dbp, key, existing_info, existing_info_size)) { if (existing_info->policy == CONTEXT_STATE_POLICY_PRESERVE && now < existing_info->expires && strcmp(existing_info->tags, new_info->tags) == 0) { Log(LOG_LEVEL_VERBOSE, "Persistent class '%s' is already in a preserved state -- %jd minutes to go", key, (intmax_t)((existing_info->expires - now) / 60)); CloseDB(dbp); free(key); free(new_info); return; } } else { Log(LOG_LEVEL_ERR, "While persisting class '%s', error reading existing value", key); CloseDB(dbp); free(key); free(new_info); return; } } } Log(LOG_LEVEL_VERBOSE, "Updating persistent class '%s'", key); WriteDB(dbp, key, new_info, new_info_size); CloseDB(dbp); free(key); free(new_info); } /*****************************************************************************/ void EvalContextHeapPersistentRemove(const char *context) { CF_DB *dbp; if (!OpenDB(&dbp, dbid_state)) { return; } DeleteDB(dbp, context); Log(LOG_LEVEL_DEBUG, "Deleted persistent class '%s'", context); CloseDB(dbp); } /*****************************************************************************/ void EvalContextHeapPersistentLoadAll(EvalContext *ctx) { assert(ctx != NULL); time_t now = time(NULL); Log(LOG_LEVEL_VERBOSE, "Loading persistent classes"); CF_DB *dbp; if (!OpenDB(&dbp, dbid_state)) { return; } CF_DBC *dbcp; if (!NewDBCursor(dbp, &dbcp)) { Log(LOG_LEVEL_INFO, "Unable to scan persistence cache"); return; } const char *key; int key_size = 0; void *info_p; int info_size = 0; while (NextDB(dbcp, (char **)&key, &key_size, &info_p, &info_size)) { Log(LOG_LEVEL_DEBUG, "Found key persistent class key '%s'", key); /* Info points to db-owned data, which is not aligned properly and * dereferencing might be slow or even cause SIGBUS! */ PersistentClassInfo info = { 0 }; memcpy(&info, info_p, info_size < (int) sizeof(info) ? info_size : (int) sizeof(info)); const char *tags = NULL; if (info_size > (int) sizeof(PersistentClassInfo)) { /* This is char pointer, it can point to unaligned data. */ tags = ((PersistentClassInfo *) info_p)->tags; } else { tags = ""; /* no tags */ } if (now > info.expires) { Log(LOG_LEVEL_VERBOSE, "Persistent class '%s' expired", key); DBCursorDeleteEntry(dbcp); } else { Log(LOG_LEVEL_VERBOSE, "Persistent class '%s' for %jd more minutes", key, (intmax_t) ((info.expires - now) / 60)); if ((ctx->negated_classes != NULL) && StringSetContains(ctx->negated_classes, key)) { Log(LOG_LEVEL_VERBOSE, "Not adding persistent class '%s' due to match in -N/--negate", key); } else { Log(LOG_LEVEL_DEBUG, "Adding persistent class '%s'", key); ClassRef ref = ClassRefParse(key); EvalContextClassPut(ctx, ref.ns, ref.name, true, CONTEXT_SCOPE_NAMESPACE, tags, NULL); StringSet *tag_set = EvalContextClassTags(ctx, ref.ns, ref.name); assert(tag_set); StringSetAdd(tag_set, xstrdup("source=persistent")); ClassRefDestroy(ref); } } } DeleteDBCursor(dbcp); CloseDB(dbp); } void EvalContextSetNegatedClasses(EvalContext *ctx, StringSet *negated_classes) { assert(ctx != NULL); ctx->negated_classes = negated_classes; } bool BundleAbort(EvalContext *ctx) { assert(ctx != NULL); if (ctx->bundle_aborted) { ctx->bundle_aborted = false; return true; } return false; } static bool BundleAborted(const EvalContext* ctx) { assert(ctx != NULL); return ctx->bundle_aborted; } static void SetBundleAborted(EvalContext *ctx) { assert(ctx != NULL); ctx->bundle_aborted = true; } static void SetEvalAborted(EvalContext *ctx) { assert(ctx != NULL); ctx->eval_aborted = true; } bool EvalAborted(const EvalContext *ctx) { assert(ctx != NULL); return ctx->eval_aborted; } void EvalContextHeapAddAbort(EvalContext *ctx, const char *context, const char *activated_on_context) { assert(ctx != NULL); if (!IsItemIn(ctx->heap_abort, context)) { AppendItem(&ctx->heap_abort, context, activated_on_context); } const char *aborting_context = GetAgentAbortingContext(ctx); if (aborting_context) { Log(LOG_LEVEL_NOTICE, "cf-agent aborted on defined class '%s'", aborting_context); SetEvalAborted(ctx); } } void EvalContextHeapAddAbortCurrentBundle(EvalContext *ctx, const char *context, const char *activated_on_context) { assert(ctx != NULL); if (!IsItemIn(ctx->heap_abort_current_bundle, context)) { AppendItem(&ctx->heap_abort_current_bundle, context, activated_on_context); } } /*****************************************************************************/ bool MissingDependencies(EvalContext *ctx, const Promise *pp) { assert(ctx != NULL); const Rlist *dependenies = PromiseGetConstraintAsList(ctx, "depends_on", pp); if (RlistIsNullList(dependenies)) { return false; } for (const Rlist *rp = PromiseGetConstraintAsList(ctx, "depends_on", pp); rp; rp = rp->next) { if (rp->val.type != RVAL_TYPE_SCALAR) { return true; } if (!StringSetContains(ctx->dependency_handles, RlistScalarValue(rp))) { Log(LOG_LEVEL_VERBOSE, "Skipping promise '%s', as promise dependency '%s' has not yet been kept", pp->promiser, RlistScalarValue(rp)); return true; } } return false; } static void StackFrameBundleDestroy(StackFrameBundle frame) { ClassTableDestroy(frame.classes); VariableTableDestroy(frame.vars); } static void StackFrameBodyDestroy(ARG_UNUSED StackFrameBody frame) { VariableTableDestroy(frame.vars); } static void StackFramePromiseDestroy(StackFramePromise frame) { VariableTableDestroy(frame.vars); } static void StackFramePromiseIterationDestroy(StackFramePromiseIteration frame) { PromiseDestroy(frame.owner); RingBufferDestroy(frame.log_messages); } static void StackFrameDestroy(StackFrame *frame) { if (frame) { switch (frame->type) { case STACK_FRAME_TYPE_BUNDLE: StackFrameBundleDestroy(frame->data.bundle); break; case STACK_FRAME_TYPE_BODY: StackFrameBodyDestroy(frame->data.body); break; case STACK_FRAME_TYPE_BUNDLE_SECTION: break; case STACK_FRAME_TYPE_PROMISE: StackFramePromiseDestroy(frame->data.promise); break; case STACK_FRAME_TYPE_PROMISE_ITERATION: StackFramePromiseIterationDestroy(frame->data.promise_iteration); break; default: ProgrammingError("Unhandled stack frame type"); } free(frame->path); free(frame); } } static void FreePackageManager(PackageModuleBody *manager) { assert(manager != NULL); free(manager->name); free(manager->interpreter); free(manager->module_path); RlistDestroy(manager->options); free(manager); } static PackagePromiseContext *PackagePromiseConfigNew() { PackagePromiseContext *package_promise_defaults = xmalloc(sizeof(PackagePromiseContext)); package_promise_defaults->control_package_module = NULL; package_promise_defaults->control_package_inventory = NULL; package_promise_defaults->package_modules_bodies = SeqNew(5, FreePackageManager); return package_promise_defaults; } static void FreePackagePromiseContext(PackagePromiseContext *pp_ctx) { SeqDestroy(pp_ctx->package_modules_bodies); RlistDestroy(pp_ctx->control_package_inventory); free(pp_ctx->control_package_module); free(pp_ctx); } /* Keeps the last 5 messages of each promise in a ring buffer in the * EvalContext, which are written to a JSON file from the Enterprise function * EvalContextLogPromiseIterationOutcome() at the end of each promise. */ char *MissionPortalLogHook(LoggingPrivContext *pctx, LogLevel level, const char *message) { const EvalContext *ctx = pctx->param; StackFrame *last_frame = LastStackFrame(ctx, 0); if (last_frame && last_frame->type == STACK_FRAME_TYPE_PROMISE_ITERATION && level <= LOG_LEVEL_INFO) { RingBufferAppend(last_frame->data.promise_iteration.log_messages, xstrdup(message)); } return xstrdup(message); } ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, EvalContextSetupMissionPortalLogHook, ARG_UNUSED EvalContext *, ctx) { } EvalContext *EvalContextNew(void) { EvalContext *ctx = xcalloc(1, sizeof(EvalContext)); ctx->eval_options = EVAL_OPTION_FULL; ctx->stack = SeqNew(10, StackFrameDestroy); ctx->global_classes = ClassTableNew(); ctx->global_variables = VariableTableNew(); ctx->match_variables = VariableTableNew(); ctx->dependency_handles = StringSetNew(); ctx->uid = getuid(); ctx->gid = getgid(); ctx->pid = getpid(); #ifndef __MINGW32__ ctx->ppid = getppid(); #endif ctx->promise_lock_cache = StringSetNew(); ctx->function_cache = FuncCacheMapNew(); EvalContextSetupMissionPortalLogHook(ctx); ctx->package_promise_context = PackagePromiseConfigNew(); ctx->all_classes = NULL; ctx->negated_classes = NULL; ctx->bundle_names = StringSetNew(); ctx->remote_var_promises = NULL; ctx->select_end_match_eof = false; ctx->dump_reports = false; return ctx; } void EvalContextDestroy(EvalContext *ctx) { if (ctx) { free(ctx->launch_directory); free(ctx->entry_point); // Freeing logging context doesn't belong here... { LoggingPrivContext *pctx = LoggingPrivGetContext(); free(pctx); LoggingPrivSetContext(NULL); } LoggingFreeCurrentThreadContext(); EvalContextDeleteIpAddresses(ctx); DeleteItemList(ctx->heap_abort); DeleteItemList(ctx->heap_abort_current_bundle); RlistDestroy(ctx->args); SeqDestroy(ctx->stack); ClassTableDestroy(ctx->global_classes); VariableTableDestroy(ctx->global_variables); VariableTableDestroy(ctx->match_variables); StringSetDestroy(ctx->dependency_handles); StringSetDestroy(ctx->promise_lock_cache); FuncCacheMapDestroy(ctx->function_cache); FreePackagePromiseContext(ctx->package_promise_context); StringSetDestroy(ctx->all_classes); StringSetDestroy(ctx->negated_classes); StringSetDestroy(ctx->bundle_names); if (ctx->remote_var_promises != NULL) { RemoteVarPromisesMapDestroy(ctx->remote_var_promises); ctx->remote_var_promises = NULL; } free(ctx); } } static bool EvalContextHeapContainsSoft(const EvalContext *ctx, const char *ns, const char *name) { const Class *cls = ClassTableGet(ctx->global_classes, ns, name); return cls && cls->is_soft; } static bool EvalContextHeapContainsHard(const EvalContext *ctx, const char *name) { const Class *cls = ClassTableGet(ctx->global_classes, NULL, name); return cls && !cls->is_soft; } bool StackFrameContainsSoftRecursive(const EvalContext *ctx, const char *context, size_t stack_index) { StackFrame *frame = SeqAt(ctx->stack, stack_index); if (frame->type == STACK_FRAME_TYPE_BUNDLE && ClassTableGet(frame->data.bundle.classes, frame->data.bundle.owner->ns, context) != NULL) { return true; } else if (stack_index > 0 && frame->inherits_previous) { return StackFrameContainsSoftRecursive(ctx, context, stack_index - 1); } else { return false; } } static bool EvalContextStackFrameContainsSoft(const EvalContext *ctx, const char *context) { if (SeqLength(ctx->stack) == 0) { return false; } size_t stack_index = SeqLength(ctx->stack) - 1; return StackFrameContainsSoftRecursive(ctx, context, stack_index); } bool EvalContextHeapRemoveSoft(EvalContext *ctx, const char *ns, const char *name) { return ClassTableRemove(ctx->global_classes, ns, name); } bool EvalContextHeapRemoveHard(EvalContext *ctx, const char *name) { return ClassTableRemove(ctx->global_classes, NULL, name); } void EvalContextClear(EvalContext *ctx) { ClassTableClear(ctx->global_classes); EvalContextDeleteIpAddresses(ctx); VariableTableClear(ctx->global_variables, NULL, NULL, NULL); VariableTableClear(ctx->match_variables, NULL, NULL, NULL); StringSetClear(ctx->promise_lock_cache); SeqClear(ctx->stack); FuncCacheMapClear(ctx->function_cache); } Rlist *EvalContextGetPromiseCallerMethods(EvalContext *ctx) { Rlist *callers_promisers = NULL; for (size_t i = 0; i < SeqLength(ctx->stack); i++) { StackFrame *frame = SeqAt(ctx->stack, i); switch (frame->type) { case STACK_FRAME_TYPE_BODY: break; case STACK_FRAME_TYPE_BUNDLE: break; case STACK_FRAME_TYPE_PROMISE_ITERATION: break; case STACK_FRAME_TYPE_PROMISE: if (strcmp(frame->data.promise.owner->parent_section->promise_type, "methods") == 0) { RlistAppendScalar(&callers_promisers, frame->data.promise.owner->promiser); } break; case STACK_FRAME_TYPE_BUNDLE_SECTION: break; default: ProgrammingError("Unhandled stack frame type"); } } return callers_promisers; } JsonElement *EvalContextGetPromiseCallers(EvalContext *ctx) { JsonElement *callers = JsonArrayCreate(4); size_t depth = SeqLength(ctx->stack); for (size_t i = 0; i < depth; i++) { StackFrame *frame = SeqAt(ctx->stack, i); JsonElement *f = JsonObjectCreate(10); JsonObjectAppendInteger(f, "frame", depth-i); JsonObjectAppendInteger(f, "depth", i); switch (frame->type) { case STACK_FRAME_TYPE_BODY: JsonObjectAppendString(f, "type", "body"); JsonObjectAppendObject(f, "body", BodyToJson(frame->data.body.owner)); break; case STACK_FRAME_TYPE_BUNDLE: JsonObjectAppendString(f, "type", "bundle"); JsonObjectAppendObject(f, "bundle", BundleToJson(frame->data.bundle.owner)); break; case STACK_FRAME_TYPE_PROMISE_ITERATION: JsonObjectAppendString(f, "type", "iteration"); JsonObjectAppendInteger(f, "iteration_index", frame->data.promise_iteration.index); break; case STACK_FRAME_TYPE_PROMISE: JsonObjectAppendString(f, "type", "promise"); JsonObjectAppendString(f, "promise_type", frame->data.promise.owner->parent_section->promise_type); JsonObjectAppendString(f, "promiser", frame->data.promise.owner->promiser); JsonObjectAppendString(f, "promise_classes", frame->data.promise.owner->classes); JsonObjectAppendString(f, "promise_comment", (frame->data.promise.owner->comment == NULL) ? "" : frame->data.promise.owner->comment); break; case STACK_FRAME_TYPE_BUNDLE_SECTION: JsonObjectAppendString(f, "type", "promise_type"); JsonObjectAppendString(f, "promise_type", frame->data.bundle_section.owner->promise_type); break; default: ProgrammingError("Unhandled stack frame type"); } JsonArrayAppendObject(callers, f); } return callers; } void EvalContextSetBundleArgs(EvalContext *ctx, const Rlist *args) { if (ctx->args) { RlistDestroy(ctx->args); } ctx->args = RlistCopy(args); } Rlist *EvalContextGetBundleArgs(EvalContext *ctx) { return (Rlist *) ctx->args; } void EvalContextSetPass(EvalContext *ctx, int pass) { ctx->pass = pass; } int EvalContextGetPass(EvalContext *ctx) { return ctx->pass; } static StackFrame *StackFrameNew(StackFrameType type, bool inherit_previous) { StackFrame *frame = xmalloc(sizeof(StackFrame)); frame->type = type; frame->inherits_previous = inherit_previous; frame->path = NULL; return frame; } static StackFrame *StackFrameNewBundle(const Bundle *owner, bool inherit_previous) { StackFrame *frame = StackFrameNew(STACK_FRAME_TYPE_BUNDLE, inherit_previous); frame->data.bundle.owner = owner; frame->data.bundle.classes = ClassTableNew(); frame->data.bundle.vars = VariableTableNew(); return frame; } static StackFrame *StackFrameNewBody(const Body *owner) { StackFrame *frame = StackFrameNew(STACK_FRAME_TYPE_BODY, false); frame->data.body.owner = owner; frame->data.body.vars = VariableTableNew(); return frame; } static StackFrame *StackFrameNewBundleSection(const BundleSection *owner) { StackFrame *frame = StackFrameNew(STACK_FRAME_TYPE_BUNDLE_SECTION, true); frame->data.bundle_section.owner = owner; return frame; } static StackFrame *StackFrameNewPromise(const Promise *owner) { StackFrame *frame = StackFrameNew(STACK_FRAME_TYPE_PROMISE, true); frame->data.promise.owner = owner; return frame; } static StackFrame *StackFrameNewPromiseIteration(Promise *owner, const PromiseIterator *iter_ctx) { StackFrame *frame = StackFrameNew(STACK_FRAME_TYPE_PROMISE_ITERATION, true); frame->data.promise_iteration.owner = owner; frame->data.promise_iteration.iter_ctx = iter_ctx; frame->data.promise_iteration.log_messages = RingBufferNew(5, NULL, free); return frame; } void EvalContextStackFrameRemoveSoft(EvalContext *ctx, const char *context) { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); assert(frame); ClassTableRemove(frame->data.bundle.classes, frame->data.bundle.owner->ns, context); } static void EvalContextStackPushFrame(EvalContext *ctx, StackFrame *frame) { StackFrame *last_frame = LastStackFrame(ctx, 0); if (last_frame) { if (last_frame->type == STACK_FRAME_TYPE_PROMISE_ITERATION) { LogLevel global_log_level = LogGetGlobalLevel(); LogLevel system_log_level = LogGetGlobalSystemLogLevel(); LoggingPrivSetLevels(system_log_level != LOG_LEVEL_NOTHING ? system_log_level : global_log_level, global_log_level); } } SeqAppend(ctx->stack, frame); assert(!frame->path); frame->path = EvalContextStackPath(ctx); LogDebug(LOG_MOD_EVALCTX, "PUSHED FRAME (type %s)", STACK_FRAME_TYPE_STR[frame->type]); } void EvalContextStackPushBundleFrame(EvalContext *ctx, const Bundle *owner, const Rlist *args, bool inherits_previous) { assert(!LastStackFrame(ctx, 0) || LastStackFrame(ctx, 0)->type == STACK_FRAME_TYPE_PROMISE_ITERATION); EvalContextStackPushFrame(ctx, StackFrameNewBundle(owner, inherits_previous)); if (RlistLen(args) > 0) { const Promise *caller = EvalContextStackCurrentPromise(ctx); if (caller) { VariableTable *table = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE)->data.bundle.vars; VariableTableClear(table, NULL, NULL, NULL); } ScopeAugment(ctx, owner, caller, args); } { VariableTableIterator *iter = VariableTableIteratorNew(ctx->global_variables, owner->ns, owner->name, NULL); Variable *var = NULL; while ((var = VariableTableIteratorNext(iter))) { Rval var_rval = VariableGetRval(var, true); Rval retval = ExpandPrivateRval(ctx, owner->ns, owner->name, var_rval.item, var_rval.type); VariableSetRval(var, retval); } VariableTableIteratorDestroy(iter); } } void EvalContextStackPushBodyFrame(EvalContext *ctx, const Promise *caller, const Body *body, const Rlist *args) { #ifndef NDEBUG StackFrame *last_frame = LastStackFrame(ctx, 0); if (last_frame) { assert(last_frame->type == STACK_FRAME_TYPE_BUNDLE_SECTION); } else { assert(strcmp("control", body->name) == 0); } #endif EvalContextStackPushFrame(ctx, StackFrameNewBody(body)); if (RlistLen(body->args) != RlistLen(args)) { if (caller) { Log(LOG_LEVEL_ERR, "Argument arity mismatch in body '%s' at line %zu in file '%s', expected %d, got %d", body->name, caller->offset.line, PromiseGetBundle(caller)->source_path, RlistLen(body->args), RlistLen(args)); } else { assert(strcmp("control", body->name) == 0); ProgrammingError("Control body stack frame was pushed with arguments. This should have been caught before"); } return; } else { ScopeMapBodyArgs(ctx, body, args); } } void EvalContextStackPushBundleSectionFrame(EvalContext *ctx, const BundleSection *owner) { assert(LastStackFrame(ctx, 0) && LastStackFrame(ctx, 0)->type == STACK_FRAME_TYPE_BUNDLE); StackFrame *frame = StackFrameNewBundleSection(owner); EvalContextStackPushFrame(ctx, frame); } void EvalContextStackPushPromiseFrame(EvalContext *ctx, const Promise *owner) { assert(LastStackFrame(ctx, 0)); assert(LastStackFrame(ctx, 0)->type == STACK_FRAME_TYPE_BUNDLE_SECTION); EvalContextVariableClearMatch(ctx); StackFrame *frame = StackFrameNewPromise(owner); EvalContextStackPushFrame(ctx, frame); // create an empty table frame->data.promise.vars = VariableTableNew(); if (PromiseGetBundle(owner)->source_path) { char path[CF_BUFSIZE]; if (!IsAbsoluteFileName(PromiseGetBundle(owner)->source_path) && ctx->launch_directory) { snprintf(path, CF_BUFSIZE, "%s%c%s", ctx->launch_directory, FILE_SEPARATOR, PromiseGetBundle(owner)->source_path); } else { strlcpy(path, PromiseGetBundle(owner)->source_path, CF_BUFSIZE); } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promise_filename", path, CF_DATA_TYPE_STRING, "source=promise"); // We now make path just the directory name! DeleteSlash(path); ChopLastNode(path); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promise_dirname", path, CF_DATA_TYPE_STRING, "source=promise"); char number[PRINTSIZE(uintmax_t)]; xsnprintf(number, CF_SMALLBUF, "%ju", (uintmax_t) owner->offset.line); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promise_linenumber", number, CF_DATA_TYPE_STRING, "source=promise"); } char v[PRINTSIZE(int)]; xsnprintf(v, sizeof(v), "%d", (int) ctx->uid); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_uid", v, CF_DATA_TYPE_INT, "source=agent"); xsnprintf(v, sizeof(v), "%d", (int) ctx->gid); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_gid", v, CF_DATA_TYPE_INT, "source=agent"); xsnprintf(v, sizeof(v), "%d", (int) ctx->pid); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_pid", v, CF_DATA_TYPE_INT, "source=agent"); xsnprintf(v, sizeof(v), "%d", (int) ctx->ppid); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_ppid", v, CF_DATA_TYPE_INT, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "bundle", PromiseGetBundle(owner)->name, CF_DATA_TYPE_STRING, "source=promise"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "namespace", PromiseGetNamespace(owner), CF_DATA_TYPE_STRING, "source=promise"); // Recompute `with` for (size_t i = 0; i < SeqLength(owner->conlist); i++) { Constraint *cp = SeqAt(owner->conlist, i); if (StringEqual(cp->lval, "with")) { Rval final = EvaluateFinalRval(ctx, PromiseGetPolicy(owner), NULL, "this", cp->rval, false, owner); if (final.type == RVAL_TYPE_SCALAR && ((EvalContextGetPass(ctx) == CF_DONEPASSES - 1) || !IsCf3VarString(RvalScalarValue(final)))) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "with", RvalScalarValue(final), CF_DATA_TYPE_STRING, "source=promise_iteration/with"); } RvalDestroy(final); } } } Promise *EvalContextStackPushPromiseIterationFrame(EvalContext *ctx, const PromiseIterator *iter_ctx) { const StackFrame *last_frame = LastStackFrame(ctx, 0); assert(last_frame != NULL); assert(last_frame->type == STACK_FRAME_TYPE_PROMISE); /* Evaluate all constraints by calling functions etc. */ bool excluded; Promise *pexp = ExpandDeRefPromise(ctx, last_frame->data.promise.owner, &excluded); if (excluded || !pexp) { PromiseDestroy(pexp); return NULL; } EvalContextStackPushFrame(ctx, StackFrameNewPromiseIteration(pexp, iter_ctx)); LoggingPrivSetLevels(CalculateLogLevel(pexp), CalculateReportLevel(pexp)); return pexp; } void EvalContextStackPopFrame(EvalContext *ctx) { assert(SeqLength(ctx->stack) > 0); StackFrame *last_frame = LastStackFrame(ctx, 0); StackFrameType last_frame_type = last_frame->type; switch (last_frame_type) { case STACK_FRAME_TYPE_BUNDLE: { const Bundle *bp = last_frame->data.bundle.owner; if (strcmp(bp->type, "edit_line") == 0 || strcmp(bp->type, "edit_xml") == 0) { VariableTableClear(last_frame->data.bundle.vars, "default", "edit", NULL); } } break; case STACK_FRAME_TYPE_PROMISE_ITERATION: { LogLevel global_log_level = LogGetGlobalLevel(); LogLevel system_log_level = LogGetGlobalSystemLogLevel(); LoggingPrivSetLevels(system_log_level != LOG_LEVEL_NOTHING ? system_log_level : global_log_level, global_log_level); } break; default: break; } SeqRemove(ctx->stack, SeqLength(ctx->stack) - 1); last_frame = LastStackFrame(ctx, 0); if (last_frame) { if (last_frame->type == STACK_FRAME_TYPE_PROMISE_ITERATION) { const Promise *pp = EvalContextStackCurrentPromise(ctx); LoggingPrivSetLevels(CalculateLogLevel(pp), CalculateReportLevel(pp)); } } LogDebug(LOG_MOD_EVALCTX, "POPPED FRAME (type %s)", STACK_FRAME_TYPE_STR[last_frame_type]); } bool EvalContextClassRemove(EvalContext *ctx, const char *ns, const char *name) { for (size_t i = 0; i < SeqLength(ctx->stack); i++) { StackFrame *frame = SeqAt(ctx->stack, i); if (frame->type != STACK_FRAME_TYPE_BUNDLE) { continue; } ClassTableRemove(frame->data.bundle.classes, ns, name); } return ClassTableRemove(ctx->global_classes, ns, name); } Class *EvalContextClassGet(const EvalContext *ctx, const char *ns, const char *name) { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); if (frame) { Class *cls = ClassTableGet(frame->data.bundle.classes, ns, name); if (cls) { return cls; } } return ClassTableGet(ctx->global_classes, ns, name); } Class *EvalContextClassMatch(const EvalContext *ctx, const char *regex) { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); if (frame) { Class *cls = ClassTableMatch(frame->data.bundle.classes, regex); if (cls) { return cls; } } return ClassTableMatch(ctx->global_classes, regex); } static bool EvalContextClassPutTagsSet(EvalContext *ctx, const char *ns, const char *name, bool is_soft, ContextScope scope, StringSet *tags, const char *comment) { { char context_copy[2 * CF_MAXVARSIZE]; char canonified_context[CF_MAXVARSIZE]; /* Redmine #7013 * Fix for classes names longer than CF_MAXVARSIZE. */ if (strlen(name) >= sizeof(canonified_context)) { Log(LOG_LEVEL_WARNING, "Skipping adding class [%s] as its name " "is equal or longer than %zu", name, sizeof(canonified_context)); return false; } strlcpy(canonified_context, name, sizeof(canonified_context)); if (Chop(canonified_context, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } CanonifyNameInPlace(canonified_context); if (ns && strcmp(ns, "default") != 0) { snprintf(context_copy, sizeof(context_copy), "%s:%s", ns, canonified_context); } else { strlcpy(context_copy, canonified_context, sizeof(context_copy)); } if (strlen(context_copy) == 0) { return false; } if (IsRegexItemIn(ctx, ctx->heap_abort_current_bundle, context_copy)) { const Bundle *bundle = EvalContextStackCurrentBundle(ctx); if (bundle != NULL) { Log(LOG_LEVEL_ERR, "Bundle '%s' aborted on defined class '%s'", bundle->name, context_copy); } else { Log(LOG_LEVEL_ERR, "Bundle (unknown) aborted on defined class '%s'", context_copy); } SetBundleAborted(ctx); } if (IsRegexItemIn(ctx, ctx->heap_abort, context_copy)) { Log(LOG_LEVEL_NOTICE, "cf-agent aborted on defined class '%s'", context_copy); SetEvalAborted(ctx); } } Class *existing_class = EvalContextClassGet(ctx, ns, name); if (existing_class && existing_class->scope == scope) { return false; } Nova_ClassHistoryAddContextName(ctx->all_classes, name); switch (scope) { case CONTEXT_SCOPE_BUNDLE: { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); if (!frame) { ProgrammingError("Attempted to add bundle class '%s' while not evaluating a bundle", name); } ClassTablePut(frame->data.bundle.classes, ns, name, is_soft, scope, tags, comment); } break; case CONTEXT_SCOPE_NAMESPACE: ClassTablePut(ctx->global_classes, ns, name, is_soft, scope, tags, comment); break; case CONTEXT_SCOPE_NONE: ProgrammingError("Attempted to add a class without a set scope"); } if (!BundleAborted(ctx)) { for (const Item *ip = ctx->heap_abort_current_bundle; ip != NULL; ip = ip->next) { const char *class_expr = ip->name; if (IsDefinedClass(ctx, class_expr)) { Log(LOG_LEVEL_ERR, "Setting abort for '%s' when setting class '%s'", ip->name, name); SetBundleAborted(ctx); break; } } } return true; } static bool EvalContextClassPut(EvalContext *ctx, const char *ns, const char *name, bool is_soft, ContextScope scope, const char *tags, const char *comment) { StringSet *tags_set = (NULL_OR_EMPTY(tags) ? NULL : StringSetFromString(tags, ',')); bool ret = EvalContextClassPutTagsSet(ctx, ns, name, is_soft, scope, tags_set, comment); if (!ret) { StringSetDestroy(tags_set); } return ret; } static const char *EvalContextCurrentNamespace(const EvalContext *ctx) { size_t i = SeqLength(ctx->stack); while (i > 0) { i--; StackFrame *frame = SeqAt(ctx->stack, i); switch (frame->type) { case STACK_FRAME_TYPE_BUNDLE: return frame->data.bundle.owner->ns; case STACK_FRAME_TYPE_BODY: return frame->data.body.owner->ns; default: break; /* out of the switch but not the loop ! */ } } return NULL; } bool EvalContextClassPutHard(EvalContext *ctx, const char *name, const char *tags) { return EvalContextClassPut(ctx, NULL, name, false, CONTEXT_SCOPE_NAMESPACE, tags, NULL); } bool EvalContextClassPutSoft(EvalContext *ctx, const char *name, ContextScope scope, const char *tags) { StringSet *tags_set = (NULL_OR_EMPTY(tags) ? NULL : StringSetFromString(tags, ',')); bool ret = EvalContextClassPutSoftTagsSet(ctx, name, scope, tags_set); if (!ret) { StringSetDestroy(tags_set); } return ret; } bool EvalContextClassPutSoftTagsSet(EvalContext *ctx, const char *name, ContextScope scope, StringSet *tags) { return EvalContextClassPutSoftTagsSetWithComment(ctx, name, scope, tags, NULL); } bool EvalContextClassPutSoftTagsSetWithComment(EvalContext *ctx, const char *name, ContextScope scope, StringSet *tags, const char *comment) { bool ret; char *ns = NULL; char *delim = strchr(name, ':'); if (delim) { ns = xstrndup(name, delim - name); } ret = EvalContextClassPutTagsSet(ctx, ns ? ns : EvalContextCurrentNamespace(ctx), ns ? delim + 1 : name, true, scope, tags, comment); free(ns); return ret; } bool EvalContextClassPutSoftNS(EvalContext *ctx, const char *ns, const char *name, ContextScope scope, const char *tags) { return EvalContextClassPut(ctx, ns, name, true, scope, tags, NULL); } /** * Takes over #tags in case of success. */ bool EvalContextClassPutSoftNSTagsSet(EvalContext *ctx, const char *ns, const char *name, ContextScope scope, StringSet *tags) { return EvalContextClassPutSoftNSTagsSetWithComment(ctx, ns, name, scope, tags, NULL); } bool EvalContextClassPutSoftNSTagsSetWithComment(EvalContext *ctx, const char *ns, const char *name, ContextScope scope, StringSet *tags, const char *comment) { return EvalContextClassPutTagsSet(ctx, ns, name, true, scope, tags, comment); } ClassTableIterator *EvalContextClassTableIteratorNewGlobal(const EvalContext *ctx, const char *ns, bool is_hard, bool is_soft) { return ClassTableIteratorNew(ctx->global_classes, ns, is_hard, is_soft); } ClassTableIterator *EvalContextClassTableIteratorNewLocal(const EvalContext *ctx) { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); if (!frame) { return NULL; } return ClassTableIteratorNew(frame->data.bundle.classes, frame->data.bundle.owner->ns, false, true); } const Promise *EvalContextStackCurrentPromise(const EvalContext *ctx) { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_PROMISE_ITERATION); return frame ? frame->data.promise_iteration.owner : NULL; } const Bundle *EvalContextStackCurrentBundle(const EvalContext *ctx) { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); return frame ? frame->data.bundle.owner : NULL; } const RingBuffer *EvalContextStackCurrentMessages(const EvalContext *ctx) { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_PROMISE_ITERATION); return frame ? frame->data.promise_iteration.log_messages : NULL; } /** * @brief Concatenate string #str to #buf, replacing mangling * characters '*' and '#' with their visible counterparts. */ static void BufferAppendPromiseStr(Buffer *buf, const char *str) { for (const char *ch = str; *ch != '\0'; ch++) { switch (*ch) { case CF_MANGLED_NS: BufferAppendChar(buf, ':'); break; case CF_MANGLED_SCOPE: BufferAppendChar(buf, '.'); break; default: BufferAppendChar(buf, *ch); break; } } } /** * @brief Like @c BufferAppendPromiseStr, but if @c str contains newlines * and is longer than 2*N+3, then only copy an abbreviated version * consisting of the first and last N characters, separated by @c `...` * * @param buffer Buffer to be used. * @param promiser Constant string to append * @param N Max. length of initial/final segment of @c promiser to keep * @note 2*N+3 is the maximum length of the appended string (excl. terminating NULL) * */ static void BufferAppendAbbreviatedStr(Buffer *buf, const char *promiser, const int N) { /* check if `promiser` contains a new line (may happen for "insert_lines") */ const char *const nl = strchr(promiser, '\n'); if (NULL == nl) { BufferAppendPromiseStr(buf, promiser); } else { /* `promiser` contains a newline: abbreviate it by taking the first and last few characters */ static const char sep[] = "..."; char abbr[sizeof(sep) + 2 * N]; const int head = (nl > promiser + N) ? N : (nl - promiser); const char * last_line = strrchr(promiser, '\n') + 1; assert(last_line); /* not NULL, we know we have at least one '\n' */ const int tail = strlen(last_line); if (tail > N) { last_line += tail - N; } memcpy(abbr, promiser, head); strcpy(abbr + head, sep); strcat(abbr, last_line); BufferAppendPromiseStr(buf, abbr); } } char *EvalContextStackPath(const EvalContext *ctx) { Buffer *path = BufferNew(); for (size_t i = 0; i < SeqLength(ctx->stack); i++) { StackFrame *frame = SeqAt(ctx->stack, i); switch (frame->type) { case STACK_FRAME_TYPE_BODY: BufferAppendChar(path, '/'); BufferAppend(path, frame->data.body.owner->name, CF_BUFSIZE); break; case STACK_FRAME_TYPE_BUNDLE: BufferAppendChar(path, '/'); BufferAppend(path, frame->data.bundle.owner->ns, CF_BUFSIZE); BufferAppendChar(path, '/'); BufferAppend(path, frame->data.bundle.owner->name, CF_BUFSIZE); break; case STACK_FRAME_TYPE_BUNDLE_SECTION: BufferAppendChar(path, '/'); BufferAppend(path, frame->data.bundle_section.owner->promise_type, CF_BUFSIZE); case STACK_FRAME_TYPE_PROMISE: break; case STACK_FRAME_TYPE_PROMISE_ITERATION: BufferAppendChar(path, '/'); BufferAppendChar(path, '\''); BufferAppendAbbreviatedStr(path, frame->data.promise_iteration.owner->promiser, CF_MAXFRAGMENT); BufferAppendChar(path, '\''); if (i == SeqLength(ctx->stack) - 1 && /* For some reason verify_packages.c is adding NULL iteration * frames all over the place; TODO fix. */ frame->data.promise_iteration.iter_ctx != NULL) { BufferAppendF(path, "[%zu]", PromiseIteratorIndex(frame->data.promise_iteration.iter_ctx)); } break; default: ProgrammingError("Unhandled stack frame type"); } } return BufferClose(path); } StringSet *EvalContextStackPromisees(const EvalContext *ctx) { StringSet *promisees = StringSetNew(); for (size_t i = 0; i < SeqLength(ctx->stack); i++) { StackFrame *frame = SeqAt(ctx->stack, i); if (frame->type != STACK_FRAME_TYPE_PROMISE_ITERATION) { continue; } Rval promisee = frame->data.promise_iteration.owner->promisee; switch (promisee.type) { case RVAL_TYPE_SCALAR: StringSetAdd(promisees, xstrdup(RvalScalarValue(promisee))); break; case RVAL_TYPE_LIST: { for (const Rlist *rp = RvalRlistValue(promisee); rp; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR) { StringSetAdd(promisees, xstrdup(RvalScalarValue(rp->val))); } else { assert(false && "Canary: promisee list contained non-scalar value"); } } } break; case RVAL_TYPE_NOPROMISEE: break; default: assert(false && "Canary: promisee not scalar or list"); } } return promisees; } /** * We cannot have double-scoped variables (e.g. "this.config.var1"), so if we * want to put a scoped variable into a special scope, we need to mangle the * name like this: * "config.var1" -> "config___var1" */ static inline char *MangleScopedVarNameIntoSpecialScopeName(const char *scope, const char *var_name) { const size_t var_name_len = strlen(var_name); /* Replace '.' with NESTED_SCOPE_SEP */ char *new_var_name = xmalloc(var_name_len + sizeof(NESTED_SCOPE_SEP)); memcpy(new_var_name, var_name, var_name_len + 1 /* including '\0' */); /* Make sure we only replace the "scope." string, not all dots. */ char *scope_with_dot = StringConcatenate(2, scope, "."); char *scope_with_underscores = StringConcatenate(2, scope, NESTED_SCOPE_SEP); /* Only replace the first "scope." occurrence (there might be "scope." * inside square brackets). */ NDEBUG_UNUSED ssize_t ret = StringReplaceN(new_var_name, var_name_len + sizeof(NESTED_SCOPE_SEP), scope_with_dot, scope_with_underscores, 1); assert(ret == (var_name_len + sizeof(NESTED_SCOPE_SEP) - 2)); free(scope_with_dot); free(scope_with_underscores); return new_var_name; } /* * Copies value, so you need to free your own copy afterwards. */ bool EvalContextVariablePutSpecial(EvalContext *ctx, SpecialScope scope, const char *lval, const void *value, DataType type, const char *tags) { StringSet *tags_set = (NULL_OR_EMPTY(tags) ? NULL : StringSetFromString(tags, ',')); bool ret = EvalContextVariablePutSpecialTagsSet(ctx, scope, lval, value, type, tags_set); if (!ret) { StringSetDestroy(tags_set); } return ret; } /** * Copies value, so you need to free your own copy afterwards, EXCEPT FOR THE * 'tags' SET which is taken over as-is IF THE VARIABLE IS SUCCESSFULLY ADDED. */ bool EvalContextVariablePutSpecialTagsSet(EvalContext *ctx, SpecialScope scope, const char *lval, const void *value, DataType type, StringSet *tags) { return EvalContextVariablePutSpecialTagsSetWithComment(ctx, scope, lval, value, type, tags, NULL); } bool EvalContextVariablePutSpecialTagsSetWithComment(EvalContext *ctx, SpecialScope scope, const char *lval, const void *value, DataType type, StringSet *tags, const char *comment) { char *new_lval = NULL; if (strchr(lval, '.') != NULL) { VarRef *ref = VarRefParse(lval); if (ref->scope != NULL) { new_lval = MangleScopedVarNameIntoSpecialScopeName(ref->scope, lval); } VarRefDestroy(ref); } if (strchr(lval, '[')) { // dealing with (legacy) array reference in lval, must parse VarRef *ref = VarRefParseFromScope(new_lval ? new_lval : lval, SpecialScopeToString(scope)); bool ret = EvalContextVariablePutTagsSetWithComment(ctx, ref, value, type, tags, comment); free(new_lval); VarRefDestroy(ref); return ret; } else { // plain lval, skip parsing const VarRef ref = VarRefConst(NULL, SpecialScopeToString(scope), new_lval ? new_lval : lval); bool ret = EvalContextVariablePutTagsSetWithComment(ctx, &ref, value, type, tags, comment); free(new_lval); return ret; } } const void *EvalContextVariableGetSpecial( const EvalContext *const ctx, const SpecialScope scope, const char *const varname, DataType *const type_out) { VarRef *const ref = VarRefParseFromScope( varname, SpecialScopeToString(scope)); const void *const result = EvalContextVariableGet(ctx, ref, type_out); VarRefDestroy(ref); return result; } /** * @note Only use this when you know the variable is a string * @see EvalContextVariableGetSpecial() */ const char *EvalContextVariableGetSpecialString( const EvalContext *const ctx, const SpecialScope scope, const char *const varname) { DataType type_out; const void *const result = EvalContextVariableGetSpecial( ctx, scope, varname, &type_out); assert(type_out == CF_DATA_TYPE_STRING); // Programming error if not string return (type_out == CF_DATA_TYPE_STRING) ? result : NULL; } bool EvalContextVariableRemoveSpecial(const EvalContext *ctx, SpecialScope scope, const char *lval) { switch (scope) { case SPECIAL_SCOPE_SYS: case SPECIAL_SCOPE_MON: case SPECIAL_SCOPE_CONST: case SPECIAL_SCOPE_EDIT: case SPECIAL_SCOPE_BODY: case SPECIAL_SCOPE_THIS: { VarRef *ref = VarRefParseFromScope(lval, SpecialScopeToString(scope)); bool ret = EvalContextVariableRemove(ctx, ref); VarRefDestroy(ref); return ret; } case SPECIAL_SCOPE_NONE: assert(false && "Attempted to remove none-special variable"); return false; default: assert(false && "Unhandled case in switch"); return false; } } static VariableTable *GetVariableTableForScope(const EvalContext *ctx, NDEBUG_UNUSED const char *ns, /* only used in assertions ... */ const char *scope) { assert(ctx != NULL); switch (SpecialScopeFromString(scope)) { case SPECIAL_SCOPE_DEF: /* 'def.' is not as special as the other scopes below. (CFE-3668) */ return ctx->global_variables; case SPECIAL_SCOPE_SYS: case SPECIAL_SCOPE_MON: case SPECIAL_SCOPE_CONST: assert(!ns || strcmp("default", ns) == 0); return ctx->global_variables; case SPECIAL_SCOPE_MATCH: assert(!ns || strcmp("default", ns) == 0); return ctx->match_variables; case SPECIAL_SCOPE_EDIT: assert(!ns || strcmp("default", ns) == 0); { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BUNDLE); assert(frame); return frame->data.bundle.vars; } case SPECIAL_SCOPE_BODY: assert(!ns || strcmp("default", ns) == 0); { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_BODY); return frame ? frame->data.body.vars : NULL; } // "this" variables can be in local or global variable table (when this is used for non-special // varables), so return local as VariableResolve will try global table anyway. case SPECIAL_SCOPE_THIS: { StackFrame *frame = LastStackFrameByType(ctx, STACK_FRAME_TYPE_PROMISE); return frame ? frame->data.promise.vars : NULL; } case SPECIAL_SCOPE_NONE: return ctx->global_variables; default: assert(false && "Unhandled case in switch"); return NULL; } } bool EvalContextVariableRemove(const EvalContext *ctx, const VarRef *ref) { VariableTable *table = GetVariableTableForScope(ctx, ref->ns, ref->scope); return VariableTableRemove(table, ref); } static bool IsVariableSelfReferential(const VarRef *ref, const void *value, RvalType rval_type) { switch (rval_type) { case RVAL_TYPE_SCALAR: if (StringContainsVar(value, ref->lval)) { char *ref_str = VarRefToString(ref, true); Log(LOG_LEVEL_ERR, "The value of variable '%s' contains a reference to itself, '%s'", ref_str, (char *)value); free(ref_str); return true; } break; case RVAL_TYPE_LIST: for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (rp->val.type != RVAL_TYPE_SCALAR) { continue; } if (StringContainsVar(RlistScalarValue(rp), ref->lval)) { char *ref_str = VarRefToString(ref, true); Log(LOG_LEVEL_ERR, "An item in list variable '%s' contains a reference to itself", ref_str); free(ref_str); return true; } } break; case RVAL_TYPE_FNCALL: case RVAL_TYPE_CONTAINER: case RVAL_TYPE_NOPROMISEE: break; } return false; } static void VarRefStackQualify(const EvalContext *ctx, VarRef *ref) { StackFrame *last_frame = LastStackFrame(ctx, 0); assert(last_frame); switch (last_frame->type) { case STACK_FRAME_TYPE_BODY: VarRefQualify(ref, NULL, SpecialScopeToString(SPECIAL_SCOPE_BODY)); break; case STACK_FRAME_TYPE_BUNDLE_SECTION: { StackFrame *last_last_frame = LastStackFrame(ctx, 1); assert(last_last_frame); assert(last_last_frame->type == STACK_FRAME_TYPE_BUNDLE); VarRefQualify(ref, last_last_frame->data.bundle.owner->ns, last_last_frame->data.bundle.owner->name); } break; case STACK_FRAME_TYPE_BUNDLE: VarRefQualify(ref, last_frame->data.bundle.owner->ns, last_frame->data.bundle.owner->name); break; case STACK_FRAME_TYPE_PROMISE: case STACK_FRAME_TYPE_PROMISE_ITERATION: // Allow special "this" variables to work when used without "this" VarRefQualify(ref, NULL, SpecialScopeToString(SPECIAL_SCOPE_THIS)); break; default: ProgrammingError("Unhandled stack frame type"); } } /* * Copies value, so you need to free your own copy afterwards. */ bool EvalContextVariablePut(EvalContext *ctx, const VarRef *ref, const void *value, DataType type, const char *tags) { StringSet *tags_set = (NULL_OR_EMPTY(tags) ? NULL : StringSetFromString(tags, ',')); bool ret = EvalContextVariablePutTagsSet(ctx, ref, value, type, tags_set); if (!ret) { StringSetDestroy(tags_set); } return ret; } /** * Copies value, so you need to free your own copy afterwards, EXCEPT FOR THE * 'tags' SET which is taken over as-is IF THE VARIABLE IS SUCCESSFULLY ADDED. */ bool EvalContextVariablePutTagsSet(EvalContext *ctx, const VarRef *ref, const void *value, DataType type, StringSet *tags) { return EvalContextVariablePutTagsSetWithComment(ctx, ref, value, type, tags, NULL); } bool EvalContextVariablePutTagsSetWithComment(EvalContext *ctx, const VarRef *ref, const void *value, DataType type, StringSet *tags, const char *comment) { assert(type != CF_DATA_TYPE_NONE); assert(ref); assert(ref->lval); /* The only possible way to get a NULL value is if it's an empty linked * list (Rlist usually). */ assert(value != NULL || DataTypeIsIterable(type)); if (strlen(ref->lval) > CF_MAXVARSIZE) { char *lval_str = VarRefToString(ref, true); Log(LOG_LEVEL_ERR, "Variable '%s'' cannot be added because " "its length exceeds the maximum length allowed ('%d' characters)", lval_str, CF_MAXVARSIZE); free(lval_str); return false; } if (strcmp(ref->scope, "body") != 0 && IsVariableSelfReferential(ref, value, DataTypeToRvalType(type))) { return false; } Rval rval = (Rval) { (void *)value, DataTypeToRvalType(type) }; VariableTable *table = GetVariableTableForScope(ctx, ref->ns, ref->scope); const Promise *pp = EvalContextStackCurrentPromise(ctx); VariableTablePut(table, ref, &rval, type, tags, SafeStringDuplicate(comment), pp ? pp->org_pp : pp); return true; } /** * Change ref for e.g. 'config.var1' to 'this.config___var1' * * @see MangleScopedVarNameIntoSpecialScopeName() */ static inline VarRef *MangledThisScopedRef(const VarRef *ref) { VarRef *mangled_this_ref = VarRefCopy(ref); char *scope_underscores_lval = StringConcatenate(3, mangled_this_ref->scope, NESTED_SCOPE_SEP, mangled_this_ref->lval); free(mangled_this_ref->lval); mangled_this_ref->lval = scope_underscores_lval; free(mangled_this_ref->scope); mangled_this_ref->scope = xstrdup("this"); return mangled_this_ref; } static Variable *VariableResolve2(const EvalContext *ctx, const VarRef *ref) { assert(ref != NULL); // Get the variable table associated to the scope VariableTable *table = GetVariableTableForScope(ctx, ref->ns, ref->scope); Variable *var; if (table) { /* NOTE: The 'this.' scope should ignore namespaces because it contains * iteration variables that don't have the namespace in their ref * string and so VariableTableGet() would fail to find them with * the namespace. And similar logic applies to other special * scopes except for 'def.' which is actually not so special. */ if ((SpecialScopeFromString(ref->scope) != SPECIAL_SCOPE_NONE) && (SpecialScopeFromString(ref->scope) != SPECIAL_SCOPE_DEF) && (ref->ns != NULL)) { VarRef *ref2 = VarRefCopy(ref); free(ref2->ns); ref2->ns = NULL; var = VariableTableGet(table, ref2); VarRefDestroy(ref2); } else { var = VariableTableGet(table, ref); } if (var) { return var; } else if (ref->num_indices > 0) { /* Iteration over slists creates special variables in the 'this.' * scope with the slist variable replaced by the individual * values. However, if a scoped variable is part of the variable * reference, e.g. 'config.data[$(list)]', the special iteration * variables use mangled names to avoid having two scopes * (e.g. 'this.config___data[list_item1]' instead of * 'this.config.data[list_item1]'). * * If the ref we are looking for has indices and it has a scope, it * might be the case described above. Let's give it a try before * falling back to the indexless container lookup described below * (which will not have the list-iteration variables expanded). */ if (ref->scope != NULL) { VariableTable *this_table = GetVariableTableForScope(ctx, ref->ns, SpecialScopeToString(SPECIAL_SCOPE_THIS)); if (this_table != NULL) { VarRef *mangled_this_ref = MangledThisScopedRef(ref); var = VariableTableGet(this_table, mangled_this_ref); VarRefDestroy(mangled_this_ref); if (var != NULL) { return var; } } } /* If the lookup with indices (the [idx1][idx2]... part of the * variable reference) fails, there might still be a container * variable where the indices actually refer to child objects inside * the container structure. */ VarRef *base_ref = VarRefCopyIndexless(ref); var = VariableTableGet(table, base_ref); VarRefDestroy(base_ref); if (var && (VariableGetType(var) == CF_DATA_TYPE_CONTAINER)) { return var; } } } return NULL; } /* * Looks up a variable in the the context of the 'current scope'. This * basically means that an unqualified reference will be looked up in the * context of the top stack frame. * * Note that when evaluating a promise, this * will qualify a reference to 'this' scope and when evaluating a body, it * will qualify a reference to 'body' scope. */ static Variable *VariableResolve(const EvalContext *ctx, const VarRef *ref) { assert(ref->lval); /* We will make a first lookup that works in almost all cases: will look * for local or global variables, depending of the current scope. */ Variable *ret_var = VariableResolve2(ctx, ref); if (ret_var != NULL) { return ret_var; } /* Try to qualify non-scoped vars to the scope: "this" for promises, "body" for bodies, current bundle for bundles. */ VarRef *scoped_ref = NULL; if (!VarRefIsQualified(ref)) { scoped_ref = VarRefCopy(ref); VarRefStackQualify(ctx, scoped_ref); ret_var = VariableResolve2(ctx, scoped_ref); if (ret_var != NULL) { VarRefDestroy(scoped_ref); return ret_var; } ref = scoped_ref; /* continue with the scoped variable */ } const Bundle *last_bundle = EvalContextStackCurrentBundle(ctx); /* If we are in a promise or a body, the variable might be coming from the * last bundle. So try a last lookup with "this" or "body" special scopes * replaced with the last bundle. */ if ((SpecialScopeFromString(ref->scope) == SPECIAL_SCOPE_THIS || SpecialScopeFromString(ref->scope) == SPECIAL_SCOPE_BODY) && last_bundle != NULL) { VarRef *ref2 = VarRefCopy(ref); VarRefQualify(ref2, last_bundle->ns, last_bundle->name); ret_var = VariableResolve2(ctx, ref2); VarRefDestroy(scoped_ref); VarRefDestroy(ref2); return ret_var; } VarRefDestroy(scoped_ref); return NULL; } /** * * @NOTE NULL is a valid return value if #type_out is of list type and the * list is empty. To check if the variable didn't resolve, check if * #type_out was set to CF_DATA_TYPE_NONE. */ const void *EvalContextVariableGet(const EvalContext *ctx, const VarRef *ref, DataType *type_out) { Variable *var = VariableResolve(ctx, ref); if (var) { const VarRef *var_ref = VariableGetRef(var); DataType var_type = VariableGetType(var); Rval var_rval = VariableGetRval(var, true); if (var_ref->num_indices == 0 && ref->num_indices > 0 && var_type == CF_DATA_TYPE_CONTAINER) { JsonElement *child = JsonSelect(RvalContainerValue(var_rval), ref->num_indices, ref->indices); if (child) { if (type_out) { *type_out = CF_DATA_TYPE_CONTAINER; } return child; } } else { if (type_out) { *type_out = var_type; } return var_rval.item; } } if (type_out) { *type_out = CF_DATA_TYPE_NONE; } return NULL; } const Promise *EvalContextVariablePromiseGet(const EvalContext *ctx, const VarRef *ref) { Variable *var = VariableResolve(ctx, ref); return var ? VariableGetPromise(var) : NULL; } StringSet *EvalContextClassTags(const EvalContext *ctx, const char *ns, const char *name) { Class *cls = EvalContextClassGet(ctx, ns, name); if (!cls) { return NULL; } assert(cls->tags != NULL); return cls->tags; } StringSet *EvalContextVariableTags(const EvalContext *ctx, const VarRef *ref) { Variable *var = VariableResolve(ctx, ref); if (!var) { return NULL; } StringSet *var_tags = VariableGetTags(var); return var_tags; } bool EvalContextVariableClearMatch(EvalContext *ctx) { return VariableTableClear(ctx->match_variables, NULL, NULL, NULL); } VariableTableIterator *EvalContextVariableTableIteratorNew(const EvalContext *ctx, const char *ns, const char *scope, const char *lval) { VariableTable *table = scope ? GetVariableTableForScope(ctx, ns, scope) : ctx->global_variables; return table ? VariableTableIteratorNew(table, ns, scope, lval) : NULL; } VariableTableIterator *EvalContextVariableTableFromRefIteratorNew(const EvalContext *ctx, const VarRef *ref) { assert(ref); VariableTable *table = ref->scope ? GetVariableTableForScope(ctx, ref->ns, ref->scope) : ctx->global_variables; return table ? VariableTableIteratorNewFromVarRef(table, ref) : NULL; } const void *EvalContextVariableControlCommonGet(const EvalContext *ctx, CommonControl lval) { assert(lval >= 0 && lval < COMMON_CONTROL_MAX); VarRef *ref = VarRefParseFromScope(CFG_CONTROLBODY[lval].lval, "control_common"); const void *ret = EvalContextVariableGet(ctx, ref, NULL); VarRefDestroy(ref); return ret; } static ClassRef IDRefQualify(const EvalContext *ctx, const char *id) { // HACK: Because call reference names are equivalent to class names, we abuse ClassRef here ClassRef ref = ClassRefParse(id); if (!ClassRefIsQualified(ref)) { const char *ns = EvalContextCurrentNamespace(ctx); if (ns) { ClassRefQualify(&ref, ns); } else { ClassRefQualify(&ref, NamespaceDefault()); } } return ref; } const Bundle *EvalContextResolveBundleExpression(const EvalContext *ctx, const Policy *policy, const char *callee_reference, const char *callee_type) { ClassRef ref = IDRefQualify(ctx, callee_reference); const Bundle *bp = NULL; for (size_t i = 0; i < SeqLength(policy->bundles); i++) { const Bundle *curr_bp = SeqAt(policy->bundles, i); if ((strcmp(curr_bp->type, callee_type) != 0) || (strcmp(curr_bp->name, ref.name) != 0) || !StringEqual(curr_bp->ns, ref.ns)) { continue; } bp = curr_bp; break; } ClassRefDestroy(ref); return bp; } const Body *EvalContextFindFirstMatchingBody(const Policy *policy, const char *type, const char *namespace, const char *name) { for (size_t i = 0; i < SeqLength(policy->bodies); i++) { const Body *curr_bp = SeqAt(policy->bodies, i); if ((strcmp(curr_bp->type, type) == 0) && (strcmp(curr_bp->name, name) == 0) && StringEqual(curr_bp->ns, namespace)) { return curr_bp; } } return NULL; } void EvalContextAppendBodyParentsAndArgs(const EvalContext *ctx, const Policy *policy, Seq* chain, const Body *bp, const char *callee_type, int depth) { if (depth > 30) // sanity check { Log(LOG_LEVEL_ERR, "EvalContextAppendBodyParentsAndArgs: body inheritance chain depth %d in body %s is too much, aborting", depth, bp->name); DoCleanupAndExit(EXIT_FAILURE); } for (size_t k = 0; bp->conlist && k < SeqLength(bp->conlist); k++) { Constraint *scp = SeqAt(bp->conlist, k); if (strcmp("inherit_from", scp->lval) == 0) { char* call = NULL; if (RVAL_TYPE_SCALAR == scp->rval.type) { call = RvalScalarValue(scp->rval); } else if (RVAL_TYPE_FNCALL == scp->rval.type) { call = RvalFnCallValue(scp->rval)->name; } ClassRef parent_ref = IDRefQualify(ctx, call); // We don't do a more detailed check for circular // inheritance because the depth check above will catch it if (strcmp(parent_ref.name, bp->name) == 0) { Log(LOG_LEVEL_ERR, "EvalContextAppendBodyParentsAndArgs: self body inheritance in %s->%s, aborting", bp->name, parent_ref.name); DoCleanupAndExit(EXIT_FAILURE); } const Body *parent = EvalContextFindFirstMatchingBody(policy, callee_type, parent_ref.ns, parent_ref.name); if (parent) { SeqAppend(chain, (void *)parent); SeqAppend(chain, &(scp->rval)); EvalContextAppendBodyParentsAndArgs(ctx, policy, chain, parent, callee_type, depth+1); } ClassRefDestroy(parent_ref); } } } Seq *EvalContextResolveBodyExpression(const EvalContext *ctx, const Policy *policy, const char *callee_reference, const char *callee_type) { ClassRef ref = IDRefQualify(ctx, callee_reference); Seq *bodies = NULL; const Body *bp = EvalContextFindFirstMatchingBody(policy, callee_type, ref.ns, ref.name); if (bp) { bodies = SeqNew(2, NULL); SeqAppend(bodies, (void *)bp); SeqAppend(bodies, (void *)NULL); EvalContextAppendBodyParentsAndArgs(ctx, policy, bodies, bp, callee_type, 1); } ClassRefDestroy(ref); return bodies; } bool EvalContextPromiseLockCacheContains(const EvalContext *ctx, const char *key) { return StringSetContains(ctx->promise_lock_cache, key); } void EvalContextPromiseLockCachePut(EvalContext *ctx, const char *key) { StringSetAdd(ctx->promise_lock_cache, xstrdup(key)); } void EvalContextPromiseLockCacheRemove(EvalContext *ctx, const char *key) { StringSetRemove(ctx->promise_lock_cache, key); } bool EvalContextFunctionCacheGet(const EvalContext *ctx, const FnCall *fp ARG_UNUSED, const Rlist *args, Rval *rval_out) { assert(fp != NULL); assert(fp->name != NULL); assert(ctx != NULL); if (!(ctx->eval_options & EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS)) { return false; } // The cache key is made of the function name and all args values Rlist *args_copy = RlistCopy(args); Rlist *key = RlistPrepend(&args_copy, fp->name, RVAL_TYPE_SCALAR); Rval *rval = FuncCacheMapGet(ctx->function_cache, key); RlistDestroy(key); if (rval) { if (rval_out) { *rval_out = *rval; } return true; } else { return false; } } void EvalContextFunctionCachePut(EvalContext *ctx, const FnCall *fp ARG_UNUSED, const Rlist *args, const Rval *rval) { assert(fp != NULL); assert(fp->name != NULL); assert(ctx != NULL); if (!(ctx->eval_options & EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS)) { return; } Rval *rval_copy = xmalloc(sizeof(Rval)); *rval_copy = RvalCopy(*rval); Rlist *args_copy = RlistCopy(args); Rlist *key = RlistPrepend(&args_copy, fp->name, RVAL_TYPE_SCALAR); FuncCacheMapInsert(ctx->function_cache, key, rval_copy); } /* cfPS and associated machinery */ /* * Internal functions temporarily used from logging implementation */ static const char *const NO_STATUS_TYPES[] = { "vars", "classes", "insert_lines", "delete_lines", "replace_patterns", "field_edits", NULL }; static const char *const NO_LOG_TYPES[] = { "vars", "classes", "insert_lines", "delete_lines", "replace_patterns", "field_edits", NULL }; /* * Vars, classes and similar promises which do not affect the system itself (but * just support evalution) do not need to be counted as repaired/failed, as they * may change every iteration and introduce lot of churn in reports without * giving any value. */ static bool IsPromiseValuableForStatus(const Promise *pp) { return pp && (PromiseGetPromiseType(pp) != NULL) && (!IsStrIn(PromiseGetPromiseType(pp), NO_STATUS_TYPES)); } /* * Vars, classes and subordinate promises (like edit_line) do not need to be * logged, as they exist to support other promises. */ static bool IsPromiseValuableForLogging(const Promise *pp) { return pp && (PromiseGetPromiseType(pp) != NULL) && (!IsStrIn(PromiseGetPromiseType(pp), NO_LOG_TYPES)); } static void AddAllClasses(EvalContext *ctx, const Rlist *list, unsigned int persistence_ttl, PersistentClassPolicy policy, ContextScope context_scope) { for (const Rlist *rp = list; rp != NULL; rp = rp->next) { char *classname = xstrdup(RlistScalarValue(rp)); if (strcmp(classname, "a_class_global_from_command") == 0 || strcmp(classname, "xxx:a_class_global_from_command") == 0) { Log(LOG_LEVEL_ERR, "Hit '%s'", classname); } CanonifyNameInPlace(classname); if (EvalContextHeapContainsHard(ctx, classname)) { Log(LOG_LEVEL_ERR, "You cannot use reserved hard class '%s' as post-condition class", classname); // TODO: ok.. but should we take any action? continue; maybe? } if (persistence_ttl > 0) { if (context_scope != CONTEXT_SCOPE_NAMESPACE) { Log(LOG_LEVEL_INFO, "Automatically promoting context scope for '%s' to namespace visibility, due to persistence", classname); } Log(LOG_LEVEL_VERBOSE, "C: + persistent outcome class '%s'", classname); EvalContextHeapPersistentSave(ctx, classname, persistence_ttl, policy, ""); EvalContextClassPutSoft(ctx, classname, CONTEXT_SCOPE_NAMESPACE, ""); } else { Log(LOG_LEVEL_VERBOSE, "C: + promise outcome class '%s'", classname); switch (context_scope) { case CONTEXT_SCOPE_BUNDLE: EvalContextStackFrameAddSoft(ctx, classname, ""); break; case CONTEXT_SCOPE_NONE: case CONTEXT_SCOPE_NAMESPACE: EvalContextClassPutSoft(ctx, classname, CONTEXT_SCOPE_NAMESPACE, ""); break; default: ProgrammingError("AddAllClasses: Unexpected context_scope %d!", context_scope); } } free(classname); } } static void DeleteAllClasses(EvalContext *ctx, const Rlist *list) { for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (CheckParseContext(RlistScalarValue(rp), CF_IDRANGE) != SYNTAX_TYPE_MATCH_OK) { return; // TODO: interesting course of action, but why is the check there in the first place? } if (EvalContextHeapContainsHard(ctx, RlistScalarValue(rp))) { Log(LOG_LEVEL_ERR, "You cannot cancel a reserved hard class '%s' in post-condition classes", RlistScalarValue(rp)); return; } const char *string = RlistScalarValue(rp); Log(LOG_LEVEL_VERBOSE, "Cancelling class '%s'", string); EvalContextHeapPersistentRemove(string); { ClassRef ref = ClassRefParse(CanonifyName(string)); EvalContextClassRemove(ctx, ref.ns, ref.name); ClassRefDestroy(ref); } EvalContextStackFrameRemoveSoft(ctx, CanonifyName(string)); } } ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, TrackTotalCompliance, ARG_UNUSED PromiseResult, status, ARG_UNUSED const Promise *, pp) { } void SetPromiseOutcomeClasses(EvalContext *ctx, PromiseResult status, const DefineClasses *dc) { Rlist *add_classes = NULL; Rlist *del_classes = NULL; switch (status) { case PROMISE_RESULT_CHANGE: add_classes = dc->change; del_classes = dc->del_change; break; case PROMISE_RESULT_TIMEOUT: add_classes = dc->timeout; del_classes = dc->del_notkept; break; case PROMISE_RESULT_WARN: case PROMISE_RESULT_FAIL: case PROMISE_RESULT_INTERRUPTED: add_classes = dc->failure; del_classes = dc->del_notkept; break; case PROMISE_RESULT_DENIED: add_classes = dc->denied; del_classes = dc->del_notkept; break; case PROMISE_RESULT_NOOP: add_classes = dc->kept; del_classes = dc->del_kept; break; default: ProgrammingError("Unexpected status '%c' has been passed to SetPromiseOutcomeClasses", status); } AddAllClasses(ctx, add_classes, dc->persist, dc->timer, dc->scope); DeleteAllClasses(ctx, del_classes); } static void SummarizeTransaction(EvalContext *ctx, const TransactionContext *tc, const char *logname) { if (logname && (tc->log_string)) { Buffer *buffer = BufferNew(); ExpandScalar(ctx, NULL, NULL, tc->log_string, buffer); if (strcmp(logname, "udp_syslog") == 0) { RemoteSysLog(tc->log_priority, BufferData(buffer)); } else if (strcmp(logname, "stdout") == 0) { Log(LOG_LEVEL_INFO, "L: %s", BufferData(buffer)); } else { struct stat dsb; // Does the file exist already? if (lstat(logname, &dsb) == -1) { mode_t filemode = 0600; /* Mode for log file creation */ int fd = creat(logname, filemode); if (fd >= 0) { Log(LOG_LEVEL_VERBOSE, "Created log file '%s' with requested permissions %jo", logname, (intmax_t) filemode); close(fd); } } FILE *fout = safe_fopen(logname, "a"); if (fout == NULL) { Log(LOG_LEVEL_ERR, "Unable to open private log '%s'", logname); return; } Log(LOG_LEVEL_VERBOSE, "Logging string '%s' to '%s'", BufferData(buffer), logname); fprintf(fout, "%s\n", BufferData(buffer)); fclose(fout); } BufferDestroy(buffer); // FIXME: This was overwriting a local copy, with no side effects. // The intention was clearly to skip this function if called // repeatedly. Try to introduce this change: // tc.log_string = NULL; /* To avoid repetition */ } } static void DoSummarizeTransaction(EvalContext *ctx, PromiseResult status, const Promise *pp, const TransactionContext *tc) { if (!IsPromiseValuableForLogging(pp)) { return; } char *log_name = NULL; switch (status) { case PROMISE_RESULT_CHANGE: log_name = tc->log_repaired; break; case PROMISE_RESULT_WARN: /* FIXME: nothing? */ return; case PROMISE_RESULT_TIMEOUT: case PROMISE_RESULT_FAIL: case PROMISE_RESULT_DENIED: case PROMISE_RESULT_INTERRUPTED: log_name = tc->log_failed; break; case PROMISE_RESULT_NOOP: log_name = tc->log_kept; break; default: ProgrammingError("Unexpected promise result status: %d", status); } SummarizeTransaction(ctx, tc, log_name); } void NotifyDependantPromises(EvalContext *ctx, const Promise *pp, PromiseResult result) { switch (result) { case PROMISE_RESULT_CHANGE: case PROMISE_RESULT_NOOP: { const char *handle = PromiseGetHandle(pp); if (handle) { StringSetAdd(ctx->dependency_handles, xstrdup(handle)); } } break; default: /* This promise is not yet done, don't mark it is as such */ break; } } void ClassAuditLog(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult status) { assert(attr != NULL); if (IsPromiseValuableForStatus(pp)) { TrackTotalCompliance(status, pp); UpdatePromiseCounters(status); } SetPromiseOutcomeClasses(ctx, status, &(attr->classes)); DoSummarizeTransaction(ctx, status, pp, &(attr->transaction)); } static void LogPromiseContext(const EvalContext *ctx, const Promise *pp) { if (!WouldLog(LOG_LEVEL_VERBOSE)) { return; } Writer *w = StringWriter(); WriterWrite(w, "Additional promise info:"); if (PromiseGetHandle(pp)) { WriterWriteF(w, " handle '%s'", PromiseGetHandle(pp)); } { const char *version = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_VERSION); if (version) { WriterWriteF(w, " version '%s'", version); } } if (PromiseGetBundle(pp)->source_path) { WriterWriteF(w, " source path '%s' at line %zu", PromiseGetBundle(pp)->source_path, pp->offset.line); } switch (pp->promisee.type) { case RVAL_TYPE_SCALAR: WriterWriteF(w, " promisee '%s'", RvalScalarValue(pp->promisee)); break; case RVAL_TYPE_LIST: WriterWrite(w, " promisee "); RlistWrite(w, pp->promisee.item); break; default: break; } if (pp->comment) { WriterWriteF(w, " comment '%s'", pp->comment); } Log(LOG_LEVEL_VERBOSE, "%s", StringWriterData(w)); WriterClose(w); } void cfPS(EvalContext *ctx, LogLevel level, PromiseResult status, const Promise *pp, const Attributes *attr, const char *fmt, ...) { assert(pp != NULL); assert(attr != NULL); /* Either logging something (based on 'fmt') or logging nothing. */ assert(!NULL_OR_EMPTY(fmt) || (level == LOG_LEVEL_NOTHING)); if (!NULL_OR_EMPTY(fmt)) { if (level >= LOG_LEVEL_VERBOSE) { LogPromiseContext(ctx, pp); } va_list ap; va_start(ap, fmt); VLog(level, fmt, ap); va_end(ap); } /* Now complete the exits status classes and auditing */ if (status != PROMISE_RESULT_SKIPPED) { ClassAuditLog(ctx, pp, attr, status); } } void RecordChange(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) { assert(ctx != NULL); assert(pp != NULL); assert(attr != NULL); LogPromiseContext(ctx, pp); va_list ap; va_start(ap, fmt); VLog(LOG_LEVEL_INFO, fmt, ap); va_end(ap); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_CHANGE, &(attr->classes)); } void RecordNoChange(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) { assert(ctx != NULL); assert(pp != NULL); assert(attr != NULL); LogPromiseContext(ctx, pp); va_list ap; va_start(ap, fmt); VLog(LOG_LEVEL_VERBOSE, fmt, ap); va_end(ap); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_NOOP, &(attr->classes)); } void RecordFailure(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) { assert(ctx != NULL); assert(pp != NULL); assert(attr != NULL); LogPromiseContext(ctx, pp); va_list ap; va_start(ap, fmt); VLog(LOG_LEVEL_ERR, fmt, ap); va_end(ap); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_FAIL, &(attr->classes)); } void RecordWarning(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) { assert(ctx != NULL); assert(pp != NULL); assert(attr != NULL); LogPromiseContext(ctx, pp); va_list ap; va_start(ap, fmt); VLog(LOG_LEVEL_WARNING, fmt, ap); va_end(ap); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_WARN, &(attr->classes)); } void RecordDenial(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) { assert(ctx != NULL); assert(pp != NULL); assert(attr != NULL); LogPromiseContext(ctx, pp); va_list ap; va_start(ap, fmt); VLog(LOG_LEVEL_ERR, fmt, ap); va_end(ap); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_DENIED, &(attr->classes)); } void RecordInterruption(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *fmt, ...) { assert(ctx != NULL); assert(pp != NULL); assert(attr != NULL); LogPromiseContext(ctx, pp); va_list ap; va_start(ap, fmt); VLog(LOG_LEVEL_ERR, fmt, ap); va_end(ap); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_INTERRUPTED, &(attr->classes)); } bool MakingChanges(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *change_desc_fmt, ...) { assert(attr != NULL); if ((EVAL_MODE != EVAL_MODE_DRY_RUN) && (attr->transaction.action != cfa_warn)) { return true; } /* else */ char *fmt = NULL; if (attr->transaction.action == cfa_warn) { xasprintf(&fmt, "Should %s, but only warning promised", change_desc_fmt); } else { xasprintf(&fmt, "Should %s", change_desc_fmt); } LogPromiseContext(ctx, pp); va_list ap; va_start(ap, change_desc_fmt); VLog(LOG_LEVEL_WARNING, fmt, ap); va_end(ap); free(fmt); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_WARN, &(attr->classes)); if (result != NULL) { *result = PROMISE_RESULT_WARN; } return false; } bool MakingInternalChanges(EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, const char *change_desc_fmt, ...) { assert(attr != NULL); if ((EVAL_MODE == EVAL_MODE_NORMAL) && (attr->transaction.action != cfa_warn)) { return true; } /* else */ char *fmt = NULL; if (attr->transaction.action == cfa_warn) { xasprintf(&fmt, "Should %s, but only warning promised", change_desc_fmt); } else { xasprintf(&fmt, "Should %s", change_desc_fmt); } LogPromiseContext(ctx, pp); va_list ap; va_start(ap, change_desc_fmt); VLog(LOG_LEVEL_WARNING, fmt, ap); va_end(ap); free(fmt); SetPromiseOutcomeClasses(ctx, PROMISE_RESULT_WARN, &(attr->classes)); if (result != NULL) { *result = PROMISE_RESULT_WARN; } return false; } void SetChecksumUpdatesDefault(EvalContext *ctx, bool enabled) { ctx->checksum_updates_default = enabled; } bool GetChecksumUpdatesDefault(const EvalContext *ctx) { return ctx->checksum_updates_default; } void EvalContextAddIpAddress(EvalContext *ctx, const char *ip_address, const char *iface) { AppendItem(&ctx->ip_addresses, ip_address, (iface == NULL) ? "" : iface); } void EvalContextDeleteIpAddresses(EvalContext *ctx) { DeleteItemList(ctx->ip_addresses); ctx->ip_addresses = NULL; } Item *EvalContextGetIpAddresses(const EvalContext *ctx) { return ctx->ip_addresses; } void EvalContextSetEvalOption(EvalContext *ctx, EvalContextOption option, bool value) { if (value) { ctx->eval_options |= option; } else { ctx->eval_options &= ~option; } } bool EvalContextGetEvalOption(EvalContext *ctx, EvalContextOption option) { return ((ctx->eval_options & option) != 0); } void EvalContextSetLaunchDirectory(EvalContext *ctx, const char *path) { free(ctx->launch_directory); ctx->launch_directory = xstrdup(path); } void EvalContextSetEntryPoint( EvalContext *const ctx, const char *const entry_point) { assert(ctx != NULL); free(ctx->entry_point); ctx->entry_point = SafeStringDuplicate(entry_point); } const char *EvalContextGetEntryPoint(EvalContext *const ctx) { assert(ctx != NULL); return ctx->entry_point; } void EvalContextSetIgnoreLocks(EvalContext *ctx, bool ignore) { ctx->ignore_locks = ignore; } bool EvalContextIsIgnoringLocks(const EvalContext *ctx) { return ctx->ignore_locks; } StringSet *ClassesMatchingLocalRecursive( const EvalContext *ctx, const char *regex, const Rlist *tags, bool first_only, size_t stack_index) { assert(ctx != NULL); StackFrame *frame = SeqAt(ctx->stack, stack_index); StringSet *matches; if (frame->type == STACK_FRAME_TYPE_BUNDLE) { ClassTableIterator *iter = ClassTableIteratorNew( frame->data.bundle.classes, frame->data.bundle.owner->ns, false, true); // from EvalContextClassTableIteratorNewLocal() matches = ClassesMatching(ctx, iter, regex, tags, first_only); ClassTableIteratorDestroy(iter); } else { matches = StringSetNew(); // empty for passing up the recursion chain } if (stack_index > 0 && frame->inherits_previous) { StringSet *parent_matches = ClassesMatchingLocalRecursive( ctx, regex, tags, first_only, stack_index - 1); StringSetJoin(matches, parent_matches, xstrdup); StringSetDestroy(parent_matches); } return matches; } StringSet *ClassesMatchingLocal( const EvalContext *ctx, const char *regex, const Rlist *tags, bool first_only) { assert(ctx != NULL); return ClassesMatchingLocalRecursive( ctx, regex, tags, first_only, SeqLength(ctx->stack) - 1); } StringSet *ClassesMatchingGlobal( const EvalContext *ctx, const char *regex, const Rlist *tags, bool first_only) { ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); StringSet *matches = ClassesMatching(ctx, iter, regex, tags, first_only); ClassTableIteratorDestroy(iter); return matches; } StringSet *ClassesMatching(const EvalContext *ctx, ClassTableIterator *iter, const char* regex, const Rlist *tags, bool first_only) { StringSet *matching = StringSetNew(); Regex *rx = CompileRegex(regex); Class *cls; while ((cls = ClassTableIteratorNext(iter))) { char *expr = ClassRefToString(cls->ns, cls->name); /* FIXME: review this strcmp. Moved out from StringMatch */ if (!strcmp(regex, expr) || (rx && StringMatchFullWithPrecompiledRegex(rx, expr))) { bool pass = false; StringSet *tagset = EvalContextClassTags(ctx, cls->ns, cls->name); if (tags) { for (const Rlist *arg = tags; arg; arg = arg->next) { const char *tag_regex = RlistScalarValue(arg); const char *element; StringSetIterator it = StringSetIteratorInit(tagset); while ((element = StringSetIteratorNext(&it))) { /* FIXME: review this strcmp. Moved out from StringMatch */ if (strcmp(tag_regex, element) == 0 || StringMatchFull(tag_regex, element)) { pass = true; break; } } } } else // without any tags queried, accept class { pass = true; } if (pass) { StringSetAdd(matching, expr); } else { free(expr); } } else { free(expr); } if (first_only && StringSetSize(matching) > 0) { break; } } if (rx) { RegexDestroy(rx); } return matching; } JsonElement* JsonExpandElement(EvalContext *ctx, const JsonElement *source) { if (JsonGetElementType(source) == JSON_ELEMENT_TYPE_PRIMITIVE) { Buffer *expbuf; JsonElement *expanded_json; if (JsonGetPrimitiveType(source) == JSON_PRIMITIVE_TYPE_STRING) { expbuf = BufferNew(); ExpandScalar(ctx, NULL, "this", JsonPrimitiveGetAsString(source), expbuf); expanded_json = JsonStringCreate(BufferData(expbuf)); BufferDestroy(expbuf); return expanded_json; } else { return JsonCopy(source); } } else if (JsonGetElementType(source) == JSON_ELEMENT_TYPE_CONTAINER) { if (JsonGetContainerType(source) == JSON_CONTAINER_TYPE_OBJECT) { JsonElement *dest = JsonObjectCreate(JsonLength(source)); JsonIterator iter = JsonIteratorInit(source); const char *key; while ((key = JsonIteratorNextKey(&iter))) { Buffer *expbuf = BufferNew(); ExpandScalar(ctx, NULL, "this", key, expbuf); JsonObjectAppendElement(dest, BufferData(expbuf), JsonExpandElement(ctx, JsonObjectGet(source, key))); BufferDestroy(expbuf); } return dest; } else { JsonElement *dest = JsonArrayCreate(JsonLength(source)); for (size_t i = 0; i < JsonLength(source); i++) { JsonArrayAppendElement(dest, JsonExpandElement(ctx, JsonArrayGet(source, i))); } return dest; } } ProgrammingError("JsonExpandElement: unexpected container type"); return NULL; } const StringSet *EvalContextAllClassesGet(const EvalContext *ctx) { assert (ctx); return ctx->all_classes; } void EvalContextAllClassesLoggingEnable(EvalContext *ctx, bool enable) { assert (ctx); Nova_ClassHistoryEnable(&(ctx->all_classes), enable); } void EvalContextPushBundleName(const EvalContext *ctx, const char *bundle_name) { assert (ctx); StringSetAdd(ctx->bundle_names, xstrdup(bundle_name)); } const StringSet *EvalContextGetBundleNames(const EvalContext *ctx) { assert (ctx); return ctx->bundle_names; } void EvalContextPushRemoteVarPromise(EvalContext *ctx, const char *bundle_name, const Promise *pp) { assert (ctx); /* initiliaze the map if needed */ if (ctx->remote_var_promises == NULL) { ctx->remote_var_promises = RemoteVarPromisesMapNew(); } Seq *promises = RemoteVarPromisesMapGet(ctx->remote_var_promises, bundle_name); if (promises == NULL) { /* initialize the sequence if needed */ /* ItemDestroy == NULL because we need to store the exact pointers not * copies */ promises = SeqNew(10, NULL); RemoteVarPromisesMapInsert(ctx->remote_var_promises, xstrdup(bundle_name), promises); } /* intentionally not making a copy here, we need the exact pointer */ SeqAppend(promises, (void *) pp); } const Seq *EvalContextGetRemoteVarPromises(const EvalContext *ctx, const char *bundle_name) { assert (ctx); if (ctx->remote_var_promises == NULL) { return NULL; } return RemoteVarPromisesMapGet(ctx->remote_var_promises, bundle_name); } void EvalContextSetDumpReports(EvalContext *ctx, bool dump_reports) { assert(ctx != NULL); ctx->dump_reports = dump_reports; if (dump_reports) { Log(LOG_LEVEL_VERBOSE, "Report dumping is enabled"); } } bool EvalContextGetDumpReports(EvalContext *ctx) { assert(ctx != NULL); return ctx->dump_reports; } void EvalContextUpdateDumpReports(EvalContext *ctx) { assert(ctx != NULL); char enable_file_path[PATH_MAX]; snprintf( enable_file_path, PATH_MAX, "%s%cenable_report_dumps", GetWorkDir(), FILE_SEPARATOR); EvalContextSetDumpReports(ctx, (access(enable_file_path, F_OK) == 0)); } static char chrooted_path[PATH_MAX + 1] = {0}; static size_t chroot_len = 0; void SetChangesChroot(const char *chroot) { assert(chroot != NULL); /* This function should only be called once. */ assert(chroot_len == 0); chroot_len = SafeStringLength(chroot); memcpy(chrooted_path, chroot, chroot_len); /* Make sure there is a file separator at the end. */ if (!IsFileSep(chroot[chroot_len - 1])) { chroot_len++; chrooted_path[chroot_len - 1] = FILE_SEPARATOR; } } const char *ToChangesChroot(const char *orig_path) { /* SetChangesChroot() should be called first. */ assert(chroot_len != 0); assert(orig_path != NULL); assert(IsAbsPath(orig_path)); assert(strlen(orig_path) <= (PATH_MAX - chroot_len - 1)); size_t offset = 0; #ifdef __MINGW32__ /* On Windows, absolute path starts with the drive letter and colon followed * by '\'. Let's replace the ":\" with just "\" so that each drive has its * own directory tree in the chroot. */ if ((orig_path[0] > 'A') && ((orig_path[0] < 'Z')) && (orig_path[1] == ':')) { chrooted_path[chroot_len] = orig_path[0]; chrooted_path[chroot_len + 1] = FILE_SEPARATOR; orig_path += 2; offset += 2; } #endif while (orig_path[0] == FILE_SEPARATOR) { orig_path++; } /* Adds/copies the NUL-byte at the end of the string. */ strncpy(chrooted_path + chroot_len + offset, orig_path, (PATH_MAX - chroot_len - offset - 1)); return chrooted_path; } const char *ToNormalRoot(const char *orig_path) { assert(strncmp(orig_path, chrooted_path, chroot_len) == 0); return orig_path + chroot_len - 1; } cfengine-3.24.2/libpromises/mod_environ.h0000644000000000000000000000217515010704253020400 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_ENVIRON_H #define CFENGINE_MOD_ENVIRON_H #include extern const PromiseTypeSyntax CF_ENVIRONMENT_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/lastseen.c0000644000000000000000000005506615010704253017701 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #ifdef LMDB #include #endif void UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); /* * Lastseen database schema (version 1): * * Version entry * * key: "version\0" * value: "1\0" * * "Quality of connection" entries * * key: q (direction: 'i' for incoming, 'o' for outgoing) * value: struct KeyHostSeen * * "Hostkey" entries * * key: k ("MD5-ffffefefeefef..." or "SHA-abacabaca...") * value:
(IPv4 or IPv6) * * "Address", or reverse, entries (auxiliary) * * key: a
(IPv6 or IPv6) * value: * * * * Schema version 0 mapped direction + hostkey to address + quality of * connection. This approach had a number of drawbacks: * - There were two potentially conflicting addresses for given hostkey. * - There was no way to quickly lookup hostkey by address. * - Address update required traversal of the whole database. * * In order to overcome these limitations, new schema normalized (in relational * algebra sense) the data relations. */ /* TODO #ifndef NDEBUG check, report loudly, and fix consistency issues in every operation. */ /*****************************************************************************/ /** * @brief Same as LastSaw() but the digest parameter is the hash as a * "SHA=..." string, to avoid converting twice. */ void LastSaw1(const char *ipaddress, const char *hashstr, LastSeenRole role) { const char *mapip = MapAddress(ipaddress); UpdateLastSawHost(hashstr, mapip, role == LAST_SEEN_ROLE_ACCEPT, time(NULL)); } void LastSaw(const char *ipaddress, const unsigned char *digest, LastSeenRole role) { char databuf[CF_HOSTKEY_STRING_SIZE]; if (strlen(ipaddress) == 0) { Log(LOG_LEVEL_INFO, "LastSeen registry for empty IP with role %d", role); return; } HashPrintSafe(databuf, sizeof(databuf), digest, CF_DEFAULT_DIGEST, true); const char *mapip = MapAddress(ipaddress); UpdateLastSawHost(databuf, mapip, role == LAST_SEEN_ROLE_ACCEPT, time(NULL)); } /*****************************************************************************/ void UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp) { DBHandle *db = NULL; if (!OpenDB(&db, dbid_lastseen)) { Log(LOG_LEVEL_ERR, "Unable to open last seen db"); return; } /* Update quality-of-connection entry */ char quality_key[CF_BUFSIZE]; snprintf(quality_key, CF_BUFSIZE, "q%c%s", incoming ? 'i' : 'o', hostkey); KeyHostSeen newq = { .acknowledged = false, .lastseen = timestamp, }; KeyHostSeen q; if (ReadDB(db, quality_key, &q, sizeof(q))) { newq.Q = QAverage(q.Q, newq.lastseen - q.lastseen, 0.4); } else { /* FIXME: more meaningful default value? */ newq.Q = QDefinite(0); } WriteDB(db, quality_key, &newq, sizeof(newq)); /* Update forward mapping */ char hostkey_key[CF_BUFSIZE]; snprintf(hostkey_key, CF_BUFSIZE, "k%s", hostkey); WriteDB(db, hostkey_key, address, strlen(address) + 1); /* Update reverse mapping */ char address_key[CF_BUFSIZE]; snprintf(address_key, CF_BUFSIZE, "a%s", address); WriteDB(db, address_key, hostkey, strlen(hostkey) + 1); CloseDB(db); } /*****************************************************************************/ /* Lookup a reverse entry (IP->KeyHash) in lastseen database. */ static bool Address2HostkeyInDB(DBHandle *db, const char *address, char *result, size_t result_size) { char address_key[CF_BUFSIZE]; char hostkey[CF_HOSTKEY_STRING_SIZE]; /* Address key: "a" + address */ snprintf(address_key, CF_BUFSIZE, "a%s", address); if (!ReadDB(db, address_key, &hostkey, sizeof(hostkey))) { return false; } #ifndef NDEBUG /* Check for inconsistencies. Return success even if db is found * inconsistent, since the reverse entry is already found. */ char hostkey_key[1 + CF_HOSTKEY_STRING_SIZE]; char back_address[CF_BUFSIZE]; /* Hostkey key: "k" + hostkey */ snprintf(hostkey_key, sizeof(hostkey_key), "k%s", hostkey); if (!ReadDB(db, hostkey_key, &back_address, sizeof(back_address))) { Log(LOG_LEVEL_WARNING, "Lastseen db inconsistency: " "no key entry '%s' for existing host entry '%s'", hostkey_key, address_key); } #endif strlcpy(result, hostkey, result_size); return true; } /*****************************************************************************/ /* Given an address it returns a key - its own key if address is 127.0.0.1, * else it looks the "aADDRESS" entry in lastseen. */ bool Address2Hostkey(char *dst, size_t dst_size, const char *address) { bool retval = false; dst[0] = '\0'; if ((strcmp(address, "127.0.0.1") == 0) || (strcmp(address, "::1") == 0) || (strcmp(address, VIPADDRESS) == 0)) { Log(LOG_LEVEL_DEBUG, "Address2Hostkey: Returning local key for address %s", address); if (PUBKEY) { unsigned char digest[EVP_MAX_MD_SIZE + 1]; HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST); HashPrintSafe(dst, dst_size, digest, CF_DEFAULT_DIGEST, true); retval = true; } else { Log(LOG_LEVEL_VERBOSE, "Local key not found, generate one with cf-key?"); retval = false; } } else /* lastseen lookup */ { DBHandle *db; if (OpenDB(&db, dbid_lastseen)) { retval = Address2HostkeyInDB(db, address, dst, dst_size); CloseDB(db); if (!retval) { Log(LOG_LEVEL_VERBOSE, "Key digest for address '%s' was not found in lastseen db!", address); } } } return retval; } char *HostkeyToAddress(const char *hostkey) { DBHandle *db; if (OpenDB(&db, dbid_lastseen)) { char hostkey_key[CF_HOSTKEY_STRING_SIZE + 1]; char address[CF_BUFSIZE]; /* Hostkey key: "k" + hostkey */ snprintf(hostkey_key, sizeof(hostkey_key), "k%s", hostkey); if (ReadDB(db, hostkey_key, &address, sizeof(address))) { CloseDB(db); Log(LOG_LEVEL_DEBUG, "Found hostkey '%s' in lastseen LMDB", hostkey); return xstrdup(address); } else { CloseDB(db); Log(LOG_LEVEL_VERBOSE, "Could not find hostkey '%s' in lastseen LMDB", hostkey); return NULL; } } else { Log(LOG_LEVEL_ERR, "Failed to open lastseen DB"); return NULL; } } /** * @brief detects whether input is a host/ip name or a key digest * * @param[in] key digest (SHA/MD5 format) or free host name string * (character '=' is optional but recommended) * @retval true if a key digest, false otherwise */ static bool IsDigestOrHost(const char *input) { if (strncmp(input, "SHA=", 3) == 0) { return true; } else if (strncmp(input, "MD5=", 3) == 0) { return true; } else { return false; } } /** * @brief check whether the lastseen DB is coherent or not. * * It is allowed for a aIP1 -> KEY1 to not have a reverse kKEY1 -> IP. * kKEY1 *must* exist, but may point to another IP. * Same for IP values, they *must* appear as aIP entries, but we don't * care where they point to. * So for every aIP->KEY1 entry there should be a kKEY1->whatever entry. * And for every kKEY->IP1 entry there should be a aIP1->whatever entry. * * If a host changes IP, then we have a new entry aIP2 -> KEY1 together * with the aIP1 -> KEY1 entry. ALLOWED. * * If a host changes key, then its entry will become aIP1 -> KEY2. * Then still it will exist kKEY1 -> IP1 but also kKEY2 -> IP1. ALLOWED * * Can I have a IP value of some kKEY that does not have any aIP entry? * NO because at some time aIP it was written in the database. * SO EVERY kIP must be found in aIPS. * kIPS SUBSET OF aIPS * * Can I have a KEY value of some aIP that does not have any kKEY entry? * NO for the same reason. * SO EVERY akey must be found in kkeys. * aKEYS SUBSET OF kKEYS * * FIN * * @TODO P.S. redesign lastseen. Really, these whole requirements are * implemented on top of a simple key-value store, no wonder it's such a * mess. I believe that reverse mapping is not even needed since only * aIP entries are ever looked up. kKEY entries can be deprecated and * forget all the false notion of "schema consistency" in this key-value * store... * * @retval true if the lastseen DB is coherent, false otherwise. */ bool IsLastSeenCoherent(void) { DBHandle *db; DBCursor *cursor; if (!OpenDB(&db, dbid_lastseen)) { char *db_path = DBIdToPath(dbid_lastseen); Log(LOG_LEVEL_ERR, "Unable to open lastseen database '%s'", db_path); free(db_path); return false; } if (!NewDBCursor(db, &cursor)) { Log(LOG_LEVEL_ERR, "Unable to create lastseen database cursor"); CloseDB(db); return false; } char *key; void *value; int ksize, vsize; Item *qKEYS = NULL; Item *aKEYS = NULL; Item *kKEYS = NULL; Item *aIPS = NULL; Item *kIPS = NULL; bool result = true; while (NextDB(cursor, &key, &ksize, &value, &vsize)) { if (strcmp(key, "version") != 0 && strncmp(key, "qi", 2) != 0 && strncmp(key, "qo", 2) != 0 && key[0] != 'k' && key[0] != 'a') { Log(LOG_LEVEL_WARNING, "lastseen db inconsistency, unexpected key: %s", key); result = false; } if (key[0] == 'q' ) { if (strncmp(key,"qiSHA=",5)==0 || strncmp(key,"qoSHA=",5)==0 || strncmp(key,"qiMD5=",5)==0 || strncmp(key,"qoMD5=",5)==0) { if (!IsItemIn(qKEYS, key+2)) { PrependItem(&qKEYS, key+2, NULL); } } } if (key[0] == 'k' ) { if (strncmp(key, "kSHA=", 4)==0 || strncmp(key, "kMD5=", 4)==0) { if (!IsItemIn(kKEYS, key+1)) { PrependItem(&kKEYS, key+1, NULL); } if (!IsItemIn(kIPS, value)) { PrependItem(&kIPS, value, NULL); } } } if (key[0] == 'a' ) { if (!IsItemIn(aIPS, key+1)) { PrependItem(&aIPS, key+1, NULL); } if (!IsItemIn(aKEYS, value)) { PrependItem(&aKEYS, value, NULL); } } } DeleteDBCursor(cursor); CloseDB(db); /* For every kKEY->IP1 entry there should be a aIP1->whatever entry. * So basically: kIPS SUBSET OF aIPS. */ Item *kip = kIPS; while (kip != NULL) { if (!IsItemIn(aIPS, kip->name)) { Log(LOG_LEVEL_WARNING, "lastseen db inconsistency, found kKEY -> '%s' entry, " "but no 'a%s' -> any key entry exists!", kip->name, kip->name); result = false; } kip = kip->next; } /* For every aIP->KEY1 entry there should be a kKEY1->whatever entry. * So basically: aKEYS SUBSET OF kKEYS. */ Item *akey = aKEYS; while (akey != NULL) { if (!IsItemIn(kKEYS, akey->name)) { Log(LOG_LEVEL_WARNING, "lastseen db inconsistency, found aIP -> '%s' entry, " "but no 'k%s' -> any ip entry exists!", akey->name, akey->name); result = false; } akey = akey->next; } DeleteItemList(qKEYS); DeleteItemList(aKEYS); DeleteItemList(kKEYS); DeleteItemList(aIPS); DeleteItemList(kIPS); return result; } /** * @brief removes all traces of host 'ip' from lastseen DB * * @param[in] ip : either in (SHA/MD5 format) * @param[in,out] digest: return corresponding digest of input host. * If NULL, return nothing * @param[in] digest_size: size of digest parameter * @retval true if entry was deleted, false otherwise */ bool DeleteIpFromLastSeen(const char *ip, char *digest, size_t digest_size) { DBHandle *db; bool res = false; if (!OpenDB(&db, dbid_lastseen)) { char *db_path = DBIdToPath(dbid_lastseen); Log(LOG_LEVEL_ERR, "Unable to open lastseen database '%s'", db_path); free(db_path); return false; } char bufkey[CF_BUFSIZE + 1]; char bufhost[CF_BUFSIZE + 1]; strcpy(bufhost, "a"); strlcat(bufhost, ip, CF_BUFSIZE); char key[CF_BUFSIZE]; if (ReadDB(db, bufhost, &key, sizeof(key)) == true) { strcpy(bufkey, "k"); strlcat(bufkey, key, CF_BUFSIZE); if (HasKeyDB(db, bufkey, strlen(bufkey) + 1) == false) { res = false; goto clean; } else { if (digest != NULL) { strlcpy(digest, bufkey + 1, digest_size); } DeleteDB(db, bufkey); DeleteDB(db, bufhost); res = true; } } else { res = false; goto clean; } strcpy(bufkey, "qi"); strlcat(bufkey, key, CF_BUFSIZE); DeleteDB(db, bufkey); strcpy(bufkey, "qo"); strlcat(bufkey, key, CF_BUFSIZE); DeleteDB(db, bufkey); clean: CloseDB(db); return res; } /** * @brief removes all traces of key digest 'key' from lastseen DB * * @param[in] key : either in (SHA/MD5 format) * @param[in,out] ip : return the key corresponding host. * If NULL, return nothing * @param[in] ip_size : length of ip parameter * @param[in] a_entry_required : whether 'aIP_ADDR' entry is required for * the 'kHOSTKEY' entry deletion * @retval true if entry was deleted, false otherwise */ bool DeleteDigestFromLastSeen(const char *key, char *ip, size_t ip_size, bool a_entry_required) { DBHandle *db; bool res = false; if (!OpenDB(&db, dbid_lastseen)) { char *db_path = DBIdToPath(dbid_lastseen); Log(LOG_LEVEL_ERR, "Unable to open lastseen database '%s'", db_path); free(db_path); return false; } char bufkey[CF_BUFSIZE + 1]; char bufhost[CF_BUFSIZE + 1]; strcpy(bufkey, "k"); strlcat(bufkey, key, CF_BUFSIZE); char host[CF_BUFSIZE]; if (ReadDB(db, bufkey, &host, sizeof(host)) == true) { strcpy(bufhost, "a"); strlcat(bufhost, host, CF_BUFSIZE); if (a_entry_required && !HasKeyDB(db, bufhost, strlen(bufhost) + 1)) { res = false; goto clean; } else { if (ip != NULL) { strlcpy(ip, host, ip_size); } DeleteDB(db, bufhost); DeleteDB(db, bufkey); res = true; } } else { res = false; goto clean; } strcpy(bufkey, "qi"); strlcat(bufkey, key, CF_BUFSIZE); DeleteDB(db, bufkey); strcpy(bufkey, "qo"); strlcat(bufkey, key, CF_BUFSIZE); DeleteDB(db, bufkey); clean: CloseDB(db); return res; } /*****************************************************************************/ bool ScanLastSeenQuality(LastSeenQualityCallback callback, void *ctx) { StringMap *lastseen_db = LoadDatabaseToStringMap(dbid_lastseen); if (!lastseen_db) { return false; } MapIterator it = MapIteratorInit(lastseen_db->impl); MapKeyValue *item; Seq *hostkeys = SeqNew(100, free); while ((item = MapIteratorNext(&it)) != NULL) { char *key = item->key; /* Only look for "keyhost" entries */ if (key[0] != 'k') { continue; } SeqAppend(hostkeys, xstrdup(key + 1)); } for (size_t i = 0; i < SeqLength(hostkeys); ++i) { const char *hostkey = SeqAt(hostkeys, i); char keyhost_key[CF_BUFSIZE]; snprintf(keyhost_key, CF_BUFSIZE, "k%s", hostkey); char *address = NULL; address = (char*)StringMapGet(lastseen_db, keyhost_key); if (!address) { Log(LOG_LEVEL_ERR, "Failed to read address for key '%s'.", hostkey); continue; } char incoming_key[CF_BUFSIZE]; snprintf(incoming_key, CF_BUFSIZE, "qi%s", hostkey); KeyHostSeen *incoming = NULL; incoming = (KeyHostSeen*)StringMapGet(lastseen_db, incoming_key); if (incoming) { if (!(*callback)(hostkey, address, true, incoming, ctx)) { break; } } char outgoing_key[CF_BUFSIZE]; snprintf(outgoing_key, CF_BUFSIZE, "qo%s", hostkey); KeyHostSeen *outgoing = NULL; outgoing = (KeyHostSeen*)StringMapGet(lastseen_db, outgoing_key); if (outgoing) { if (!(*callback)(hostkey, address, false, outgoing, ctx)) { break; } } } StringMapDestroy(lastseen_db); SeqDestroy(hostkeys); return true; } /*****************************************************************************/ int LastSeenHostKeyCount(void) { CF_DB *dbp; CF_DBC *dbcp; QPoint entry; char *key; void *value; int ksize, vsize; int count = 0; if (OpenDB(&dbp, dbid_lastseen)) { memset(&entry, 0, sizeof(entry)); if (NewDBCursor(dbp, &dbcp)) { while (NextDB(dbcp, &key, &ksize, &value, &vsize)) { /* Only look for valid "hostkey" entries */ if ((key[0] != 'k') || (value == NULL)) { continue; } count++; } DeleteDBCursor(dbcp); } CloseDB(dbp); } return count; } /** * @brief removes all traces of entry 'input' from lastseen DB * * @param[in] key digest (SHA/MD5 format) or free host name string * @param[in] must_be_coherent. false : delete if lastseen is incoherent, * true : don't if lastseen is incoherent * @param[out] equivalent. If input is a host, return its corresponding * digest. If input is a digest, return its * corresponding host. CAN BE NULL! If equivalent * is null, it stays as NULL * @retval 0 if entry was deleted, <>0 otherwise */ int RemoveKeysFromLastSeen(const char *input, bool must_be_coherent, char *equivalent, size_t equivalent_size) { bool is_coherent = false; if (must_be_coherent == true) { is_coherent = IsLastSeenCoherent(); if (is_coherent == false) { Log(LOG_LEVEL_ERR, "Lastseen database is incoherent (there is not a 1-to-1 relationship between hosts and keys) and coherence check is enforced. Will not proceed to remove entries from it."); return 254; } } bool is_digest; is_digest = IsDigestOrHost(input); if (is_digest == true) { Log(LOG_LEVEL_VERBOSE, "Removing digest '%s' from lastseen database\n", input); if (!DeleteDigestFromLastSeen(input, equivalent, equivalent_size, must_be_coherent)) { Log(LOG_LEVEL_ERR, "Unable to remove digest from lastseen database."); return 252; } } else { Log(LOG_LEVEL_VERBOSE, "Removing host '%s' from lastseen database\n", input); if (DeleteIpFromLastSeen(input, equivalent, equivalent_size) == false) { Log(LOG_LEVEL_ERR, "Unable to remove host from lastseen database."); return 253; } } Log(LOG_LEVEL_INFO, "Removed corresponding entries from lastseen database."); return 0; } static bool OnlyRewriteIfChanged(KeyHostSeen *entry, ARG_UNUSED size_t size, KeyHostSeen *new) { assert(entry != NULL); assert(new != NULL); if (entry->acknowledged) { return false; } new->acknowledged = true; new->lastseen = entry->lastseen; new->Q = entry->Q; return true; } bool LastSeenHostAcknowledge(const char *host_key, bool incoming) { DBHandle *db = NULL; if (!OpenDB(&db, dbid_lastseen)) { Log(LOG_LEVEL_ERR, "Unable to open lastseen DB"); return false; } // Update quality-of-connection entry char key[CF_BUFSIZE]; NDEBUG_UNUSED int ret = snprintf(key, CF_BUFSIZE, "q%c%s", incoming ? 'i' : 'o', host_key); assert(ret > 0 && ret < CF_BUFSIZE); KeyHostSeen value; value.lastseen = 0; /* To distinguish between entry not found and error */ if (OverwriteDB(db, key, &value, sizeof(value), (OverwriteCondition)OnlyRewriteIfChanged, &value)) { Log(LOG_LEVEL_DEBUG, "Acknowledged observation of key '%s' to lastseen DB", key); } else if (value.lastseen != 0 /* was found */ && !value.acknowledged /* should update */) { /* In this case, the entry was found and should have been updated. * However, false was returned. Hence, this must be due to error. */ Log(LOG_LEVEL_ERR, "Unable to overwrite key '%s' to lastseen DB", key); CloseDB(db); return false; } CloseDB(db); return true; } cfengine-3.24.2/libpromises/verify_classes.c0000644000000000000000000003013015010704253021065 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include /* StringHash */ #include /* StringMatchFull */ static bool EvalClassExpression(EvalContext *ctx, Constraint *cp, const Promise *pp); static bool ValidClassName(const char *str) { ParseResult res = ParseExpression(str, 0, strlen(str)); if (res.result) { FreeExpression(res.result); } assert(res.position >= 0); return res.result && (size_t) res.position == strlen(str); } PromiseResult VerifyClassPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert(pp != NULL); assert(param == NULL); Log(LOG_LEVEL_DEBUG, "Evaluating classes promise: %s", pp->promiser); Attributes a = GetClassContextAttributes(ctx, pp); if (!StringMatchFull("[a-zA-Z0-9_]+", pp->promiser)) { Log(LOG_LEVEL_VERBOSE, "Class identifier '%s' contains illegal characters - canonifying", pp->promiser); CanonifyNameInPlace(pp->promiser); } if (a.context.nconstraints > 1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Irreconcilable constraints in classes for '%s'", pp->promiser); return PROMISE_RESULT_FAIL; } if (a.context.expression == NULL || EvalClassExpression(ctx, a.context.expression, pp)) { if (a.context.expression == NULL) { Log(LOG_LEVEL_DEBUG, "Setting class '%s' without an expression, implying 'any'", pp->promiser); } if (!ValidClassName(pp->promiser)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Attempted to name a class '%s', which is an illegal class identifier", pp->promiser); return PROMISE_RESULT_FAIL; } else { StringSet *tags = StringSetNew(); StringSetAdd(tags, xstrdup("source=promise")); for (const Rlist *rp = PromiseGetConstraintAsList(ctx, "meta", pp); rp; rp = rp->next) { StringSetAdd(tags, xstrdup(RlistScalarValue(rp))); } const char *comment = PromiseGetConstraintAsRval(pp, "comment", RVAL_TYPE_SCALAR); bool inserted = false; if (/* Persistent classes are always global: */ a.context.persistent > 0 || /* Namespace-scope is global: */ a.context.scope == CONTEXT_SCOPE_NAMESPACE || /* If there is no explicit scope, common bundles define global * classes, other bundles define local classes: */ (a.context.scope == CONTEXT_SCOPE_NONE && strcmp(PromiseGetBundle(pp)->type, "common") == 0)) { Log(LOG_LEVEL_VERBOSE, "C: + Global class: %s", pp->promiser); inserted = EvalContextClassPutSoftTagsSetWithComment(ctx, pp->promiser, CONTEXT_SCOPE_NAMESPACE, tags, comment); } else { Log(LOG_LEVEL_VERBOSE, "C: + Private class: %s", pp->promiser); inserted = EvalContextClassPutSoftTagsSetWithComment(ctx, pp->promiser, CONTEXT_SCOPE_BUNDLE, tags, comment); } if (a.context.persistent > 0) { Log(LOG_LEVEL_VERBOSE, "C: + Persistent class: '%s' (%d minutes)", pp->promiser, a.context.persistent); Buffer *buf = StringSetToBuffer(tags, ','); EvalContextHeapPersistentSave(ctx, pp->promiser, a.context.persistent, CONTEXT_STATE_POLICY_RESET, BufferData(buf)); BufferDestroy(buf); } if (inserted && (comment != NULL)) { Log(LOG_LEVEL_VERBOSE, "Added class '%s' with comment '%s'", pp->promiser, comment); } if (!inserted) { StringSetDestroy(tags); } return PROMISE_RESULT_NOOP; } } return PROMISE_RESULT_NOOP; } static bool SelectClass(EvalContext *ctx, const Rlist *list, const Promise *pp) { int count = RlistLen(list); if (count == 0) { Log(LOG_LEVEL_ERR, "No classes to select on RHS"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } else if (count == 1 && IsVarList(RlistScalarValue(list))) { Log(LOG_LEVEL_VERBOSE, "select_class: Can not expand list '%s' for setting class.", RlistScalarValue(list)); PromiseRef(LOG_LEVEL_VERBOSE, pp); return false; } assert(list); // Max: (strlen of VFQNAME) (strlen of VIPADDRESS) (strlen of max 64 bit integer ) '++\0' char splay[sizeof(VFQNAME) - 1 + sizeof(VIPADDRESS) - 1 + sizeof("18446744073709551615") - 1 + 2 + 1]; snprintf(splay, sizeof(splay), "%s+%s+%ju", VFQNAME, VIPADDRESS, (uintmax_t)getuid()); unsigned int hash = StringHash(splay, 0); int n = hash % count; while (n > 0 && list->next != NULL) { n--; list = list->next; } /* We are not having expanded variable or list at this point, * so we can not set select_class. */ if (IsExpandable(RlistScalarValue(list))) { Log(LOG_LEVEL_VERBOSE, "select_class: Can not use not expanded element '%s' for setting class.", RlistScalarValue(list)); PromiseRef(LOG_LEVEL_VERBOSE, pp); return false; } EvalContextClassPutSoft(ctx, RlistScalarValue(list), CONTEXT_SCOPE_NAMESPACE, "source=promise"); return true; } static bool DistributeClass(EvalContext *ctx, const Rlist *dist, const Promise *pp) { int total = 0; const Rlist *rp; for (rp = dist; rp != NULL; rp = rp->next) { int result = IntFromString(RlistScalarValue(rp)); if (result < 0) { Log(LOG_LEVEL_ERR, "Negative integer in class distribution"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } total += result; } if (total == 0) { Log(LOG_LEVEL_ERR, "An empty distribution was specified on RHS"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } double fluct = drand48() * total; assert(0 <= fluct && fluct < total); for (rp = dist; rp != NULL; rp = rp->next) { fluct -= IntFromString(RlistScalarValue(rp)); if (fluct < 0) { break; } } assert(rp); char buffer[CF_MAXVARSIZE]; snprintf(buffer, CF_MAXVARSIZE, "%s_%s", pp->promiser, RlistScalarValue(rp)); if (strcmp(PromiseGetBundle(pp)->type, "common") == 0) { EvalContextClassPutSoft(ctx, buffer, CONTEXT_SCOPE_NAMESPACE, "source=promise"); } else { EvalContextClassPutSoft(ctx, buffer, CONTEXT_SCOPE_BUNDLE, "source=promise"); } return true; } enum combine_t { c_or, c_and, c_xor }; // Class combinations static bool EvalBoolCombination(EvalContext *ctx, const Rlist *list, enum combine_t logic) { bool result = (logic == c_and); for (const Rlist *rp = list; rp != NULL; rp = rp->next) { // tolerate unexpanded entries here and interpret as "class not set" bool here = (rp->val.type == RVAL_TYPE_SCALAR && IsDefinedClass(ctx, RlistScalarValue(rp))); // shortcut "and" and "or" switch (logic) { case c_or: if (here) { return true; } break; case c_and: if (!here) { return false; } break; default: result ^= here; break; } } return result; } static bool EvalClassExpression(EvalContext *ctx, Constraint *cp, const Promise *pp) { assert(pp); if (cp == NULL) // ProgrammingError ? We'll crash RSN anyway ... { Log(LOG_LEVEL_ERR, "EvalClassExpression internal diagnostic discovered an ill-formed condition"); } if (!IsDefinedClass(ctx, pp->classes)) { return false; } if (IsDefinedClass(ctx, pp->promiser)) { if (PromiseGetConstraintAsInt(ctx, "persistence", pp) == 0) { Log(LOG_LEVEL_VERBOSE, " ?> Cancelling cached persistent class %s", pp->promiser); EvalContextHeapPersistentRemove(pp->promiser); } return false; } switch (cp->rval.type) { Rval rval; FnCall *fp; case RVAL_TYPE_FNCALL: fp = RvalFnCallValue(cp->rval); /* Special expansion of functions for control, best effort only: */ FnCallResult res = FnCallEvaluate(ctx, PromiseGetPolicy(pp), fp, pp); FnCallDestroy(fp); cp->rval = res.rval; break; case RVAL_TYPE_LIST: for (Rlist *rp = cp->rval.item; rp != NULL; rp = rp->next) { rval = EvaluateFinalRval(ctx, PromiseGetPolicy(pp), NULL, "this", rp->val, true, pp); RvalDestroy(rp->val); rp->val = rval; } break; default: rval = ExpandPrivateRval(ctx, NULL, "this", cp->rval.item, cp->rval.type); RvalDestroy(cp->rval); cp->rval = rval; break; } if (strcmp(cp->lval, "expression") == 0) { return (cp->rval.type == RVAL_TYPE_SCALAR && IsDefinedClass(ctx, RvalScalarValue(cp->rval))); } if (strcmp(cp->lval, "not") == 0) { return (cp->rval.type == RVAL_TYPE_SCALAR && !IsDefinedClass(ctx, RvalScalarValue(cp->rval))); } /* If we get here, anything remaining on the RHS must be a clist */ if (cp->rval.type != RVAL_TYPE_LIST) { Log(LOG_LEVEL_ERR, "RHS of promise body attribute '%s' is not a list", cp->lval); PromiseRef(LOG_LEVEL_ERR, pp); return true; } // Class selection if (strcmp(cp->lval, "select_class") == 0) { return SelectClass(ctx, cp->rval.item, pp); } // Class distributions if (strcmp(cp->lval, "dist") == 0) { return DistributeClass(ctx, cp->rval.item, pp); } /* Combine with and/or/xor: */ if (strcmp(cp->lval, "or") == 0) { return EvalBoolCombination(ctx, cp->rval.item, c_or); } else if (strcmp(cp->lval, "and") == 0) { return EvalBoolCombination(ctx, cp->rval.item, c_and); } else if (strcmp(cp->lval, "xor") == 0) { return EvalBoolCombination(ctx, cp->rval.item, c_xor); } return false; } cfengine-3.24.2/libpromises/dbm_api.c0000644000000000000000000005313515010704253017451 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* ThreadLock */ #include #include #include #include #include #include #include #include #include /* time() */ #include static bool DBPathLock(FileLock *lock, const char *filename); static void DBPathUnLock(FileLock *lock); static void DBPathMoveBroken(const char *filename); struct DBHandle_ { /* Filename of database file */ char *filename; /* Name of specific sub-db */ char *subname; /* Actual database-specific data */ DBPriv *priv; int refcount; /* This lock protects initialization of .priv element, and .refcount manipulation */ pthread_mutex_t lock; /* Record when the DB was opened (to check if possible corruptions are * already repaired) */ time_t open_tstamp; /** * @see FreezeDB() */ bool frozen; }; struct DBCursor_ { DBCursorPriv *cursor; }; typedef struct dynamic_db_handles_ { DBHandle *handle; struct dynamic_db_handles_ *next; } DynamicDBHandles; /******************************************************************************/ /* * This lock protects on-demand initialization of db_handles[i].lock and * db_handles[i].name. */ static pthread_mutex_t db_handles_lock = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; /* GLOBAL_T */ static DBHandle db_handles[dbid_max] = { { 0 } }; /* GLOBAL_X */ static DynamicDBHandles *db_dynamic_handles; static pthread_once_t db_shutdown_once = PTHREAD_ONCE_INIT; /* GLOBAL_T */ /******************************************************************************/ // Only append to the end, keep in sync with dbid enum in dbm_api.h static const char *const DB_PATHS_STATEDIR[] = { [dbid_classes] = "cf_classes", [dbid_variables] = "cf_variables", [dbid_performance] = "performance", [dbid_checksums] = "checksum_digests", [dbid_filestats] = "stats", [dbid_changes] = "cf_changes", [dbid_observations] = "cf_observations", [dbid_state] = "cf_state", [dbid_lastseen] = "cf_lastseen", [dbid_audit] = "cf_audit", [dbid_locks] = "cf_lock", [dbid_history] = "history", [dbid_measure] = "nova_measures", [dbid_static] = "nova_static", [dbid_scalars] = "nova_pscalar", [dbid_windows_registry] = "mswin", [dbid_cache] = "nova_cache", [dbid_license] = "nova_track", [dbid_value] = "nova_value", [dbid_agent_execution] = "nova_agent_execution", [dbid_bundles] = "bundles", [dbid_packages_installed] = "packages_installed", [dbid_packages_updates] = "packages_updates", [dbid_cookies] = "nova_cookies", }; /* These are the old (pre 3.7) paths in workdir, supported for installations that still have them. We will never create a database here. NULL means that the database was always in the state directory. */ static const char *const DB_PATHS_WORKDIR[sizeof(DB_PATHS_STATEDIR) / sizeof(const char * const)] = { [dbid_classes] = "cf_classes", [dbid_variables] = NULL, [dbid_performance] = "performance", [dbid_checksums] = "checksum_digests", [dbid_filestats] = "stats", [dbid_changes] = NULL, [dbid_observations] = NULL, [dbid_state] = NULL, [dbid_lastseen] = "cf_lastseen", [dbid_audit] = "cf_audit", [dbid_locks] = NULL, [dbid_history] = NULL, [dbid_measure] = NULL, [dbid_static] = NULL, [dbid_scalars] = NULL, [dbid_windows_registry] = "mswin", [dbid_cache] = "nova_cache", [dbid_license] = "nova_track", [dbid_value] = "nova_value", [dbid_agent_execution] = "nova_agent_execution", [dbid_bundles] = "bundles", }; /******************************************************************************/ char *DBIdToSubPath(dbid id, const char *subdb_name) { char *filename; if (xasprintf(&filename, "%s/%s_%s.%s", GetStateDir(), DB_PATHS_STATEDIR[id], subdb_name, DBPrivGetFileExtension()) == -1) { ProgrammingError("Unable to construct sub database filename for file" "%s_%s", DB_PATHS_STATEDIR[id], subdb_name); } char *native_filename = MapNameCopy(filename); free(filename); return native_filename; } Seq *SearchExistingSubDBNames(const dbid id) { char *const glob_pattern = DBIdToSubPath(id, "*"); StringSet *const db_paths = GlobFileList(glob_pattern); free(glob_pattern); Seq *const db_names = SeqNew(StringSetSize(db_paths), free); StringSetIterator iter = StringSetIteratorInit(db_paths); const char *db_path; // Start after the '$(sys.statedir)/packages_installed_' part of the path const size_t from = strlen(GetStateDir()) + 1 + strlen(DB_PATHS_STATEDIR[id]) + 1; // End before the '.lmdb' part of the path const size_t chop = from + 1 + strlen(DBPrivGetFileExtension()); while ((db_path = StringSetIteratorNext(&iter)) != NULL) { char *const db_name = SafeStringNDuplicate(db_path + from, strlen(db_path) - chop); SeqAppend(db_names, db_name); } StringSetDestroy(db_paths); return db_names; } char *DBIdToPath(dbid id) { assert(DB_PATHS_STATEDIR[id] != NULL); char *filename = NULL; if (DB_PATHS_WORKDIR[id]) { xasprintf(&filename, "%s/%s.%s", GetWorkDir(), DB_PATHS_WORKDIR[id], DBPrivGetFileExtension()); struct stat statbuf; if (stat(filename, &statbuf) == -1) { // Old database in workdir is not there. Use new database in statedir. free(filename); filename = NULL; } } if (!filename) { xasprintf(&filename, "%s/%s.%s", GetStateDir(), DB_PATHS_STATEDIR[id], DBPrivGetFileExtension()); } char *native_filename = MapNameCopy(filename); free(filename); return native_filename; } static bool IsSubHandle(DBHandle *handle, dbid id, const char *name) { char *sub_path = DBIdToSubPath(id, name); bool result = StringEqual(handle->filename, sub_path); free(sub_path); return result; } static DBHandle *DBHandleGetSubDB(dbid id, const char *name) { ThreadLock(&db_handles_lock); DynamicDBHandles *handles_list = db_dynamic_handles; while (handles_list) { if (IsSubHandle(handles_list->handle, id, name)) { ThreadUnlock(&db_handles_lock); return handles_list->handle; } handles_list = handles_list->next; } DBHandle *handle = xcalloc(1, sizeof(DBHandle)); handle->filename = DBIdToSubPath(id, name); handle->subname = SafeStringDuplicate(name); /* Initialize mutexes as error-checking ones. */ pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); pthread_mutex_init(&handle->lock, &attr); pthread_mutexattr_destroy(&attr); /* Prepend handle to global list. */ handles_list = xcalloc(1, sizeof(DynamicDBHandles)); handles_list->handle = handle; handles_list->next = db_dynamic_handles; db_dynamic_handles = handles_list; ThreadUnlock(&db_handles_lock); return handle; } static DBHandle *DBHandleGet(int id) { assert(id >= 0 && id < dbid_max); ThreadLock(&db_handles_lock); if (db_handles[id].filename == NULL) { db_handles[id].filename = DBIdToPath(id); /* Initialize mutexes as error-checking ones. */ pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); pthread_mutex_init(&db_handles[id].lock, &attr); pthread_mutexattr_destroy(&attr); } ThreadUnlock(&db_handles_lock); return &db_handles[id]; } static inline void CloseDBInstance(DBHandle *handle) { /* Wait until all DB users are served, or a threshold is reached */ int count = 0; ThreadLock(&handle->lock); if (handle->frozen) { /* Just clean some allocated memory, but don't touch the DB itself. */ free(handle->filename); free(handle->subname); ThreadUnlock(&handle->lock); return; } while (handle->refcount > 0 && count < 1000) { ThreadUnlock(&handle->lock); struct timespec sleeptime = { .tv_sec = 0, .tv_nsec = 10000000 /* 10 ms */ }; nanosleep(&sleeptime, NULL); count++; ThreadLock(&handle->lock); } /* Keep mutex locked. */ /* If we exited because of timeout make sure we Log() it. */ if (handle->refcount != 0) { Log(LOG_LEVEL_ERR, "Database %s refcount is still not zero (%d), forcing CloseDB()!", handle->filename, handle->refcount); DBPrivCloseDB(handle->priv); } else /* TODO: can we clean this up unconditionally ? */ { free(handle->filename); free(handle->subname); handle->filename = NULL; } } /** * @brief Wait for all users of all databases to close the DBs. Then acquire * the mutexes *AND KEEP THEM LOCKED* so that no background thread can open * any database. So make sure you exit soon... * * @warning This is usually register with atexit(), however you have to make * sure no other DB-cleaning exit hook was registered before, so that this is * called last. **/ void CloseAllDBExit() { ThreadLock(&db_handles_lock); for (int i = 0; i < dbid_max; i++) { if (db_handles[i].filename) { CloseDBInstance(&db_handles[i]); } } DynamicDBHandles *db_dynamic_handles_list = db_dynamic_handles; while (db_dynamic_handles_list) { DBHandle *handle = db_dynamic_handles_list->handle; CloseDBInstance(handle); DynamicDBHandles *next_free = db_dynamic_handles_list; db_dynamic_handles_list = db_dynamic_handles_list->next; FREE_AND_NULL(handle); FREE_AND_NULL(next_free); } } static void RegisterShutdownHandler(void) { RegisterCleanupFunction(&CloseAllDBExit); } /** * Keeps track of the maximum number of concurrent transactions, which is * expected to be set by agents as they start up. If it is not set it will use * the existing value. If it is set, but the database cannot honor it, CFEngine * will warn. * @param max_txn Maximum number of concurrent transactions for a single * database. */ void DBSetMaximumConcurrentTransactions(int max_txn) { DBPrivSetMaximumConcurrentTransactions(max_txn); } static inline bool OpenDBInstance(DBHandle **dbp, dbid id, DBHandle *handle) { assert(handle != NULL); ThreadLock(&handle->lock); if (handle->frozen) { Log(LOG_LEVEL_WARNING, "Attempt to open a frozen DB '%s'", handle->filename); ThreadUnlock(&handle->lock); return false; } if (handle->refcount == 0) { FileLock lock = EMPTY_FILE_LOCK; if (DBPathLock(&lock, handle->filename)) { handle->open_tstamp = time(NULL); handle->priv = DBPrivOpenDB(handle->filename, id); if (handle->priv == DB_PRIV_DATABASE_BROKEN) { DBPathMoveBroken(handle->filename); handle->priv = DBPrivOpenDB(handle->filename, id); if (handle->priv == DB_PRIV_DATABASE_BROKEN) { handle->priv = NULL; } } if (handle->priv != NULL) { if (!DBMigrate(handle, id)) { /* Migration failed. The best we can do is to move the * broken DB to the side and start fresh. */ DBPrivCloseDB(handle->priv); DBPathMoveBroken(handle->filename); handle->priv = DBPrivOpenDB(handle->filename, id); if (handle->priv == DB_PRIV_DATABASE_BROKEN) { handle->priv = NULL; } } } DBPathUnLock(&lock); } } if (handle->priv) { handle->refcount++; *dbp = handle; /* Only register shutdown handler if any database was opened * correctly. Otherwise this shutdown caller may be called too early, * and shutdown handler installed by the database library may end up * being called before CloseAllDB function */ pthread_once(&db_shutdown_once, RegisterShutdownHandler); } else { *dbp = NULL; } ThreadUnlock(&handle->lock); return *dbp != NULL; } bool OpenSubDB(DBHandle **dbp, dbid id, const char *sub_name) { DBHandle *handle = DBHandleGetSubDB(id, sub_name); return OpenDBInstance(dbp, id, handle); } bool OpenDB(DBHandle **dbp, dbid id) { DBHandle *handle = DBHandleGet(id); return OpenDBInstance(dbp, id, handle); } /** * @db_file_name Absolute path of the DB file */ DBHandle *GetDBHandleFromFilename(const char *db_file_name) { ThreadLock(&db_handles_lock); for(dbid id=0; id < dbid_max; id++) { if (StringEqual(db_handles[id].filename, db_file_name)) { ThreadUnlock(&db_handles_lock); return &(db_handles[id]); } } ThreadUnlock(&db_handles_lock); return NULL; } time_t GetDBOpenTimestamp(const DBHandle *handle) { assert(handle != NULL); return handle->open_tstamp; } void CloseDB(DBHandle *handle) { assert(handle != NULL); /* Skip in case of nested locking, for example signal handler. * DB behaviour becomes erratic otherwise (CFE-1996). */ ThreadLock(&handle->lock); if (handle->frozen) { /* Just clean some allocated memory, but don't touch the DB itself. */ free(handle->filename); free(handle->subname); ThreadUnlock(&handle->lock); return; } DBPrivCommit(handle->priv); if (handle->refcount < 1) { Log(LOG_LEVEL_ERR, "Trying to close database which is not open: %s", handle->filename); } else { handle->refcount--; if (handle->refcount == 0) { FileLock lock = EMPTY_FILE_LOCK; bool locked = DBPathLock(&lock, handle->filename); DBPrivCloseDB(handle->priv); handle->open_tstamp = -1; if (locked) { DBPathUnLock(&lock); } } } ThreadUnlock(&handle->lock); } bool CleanDB(DBHandle *handle) { ThreadLock(&handle->lock); if (handle->frozen) { Log(LOG_LEVEL_WARNING, "Attempt to clean a frozen DB '%s'", handle->filename); ThreadUnlock(&handle->lock); return false; } bool ret = DBPrivClean(handle->priv); ThreadUnlock(&handle->lock); return ret; } int GetDBUsagePercentage(const DBHandle *handle) { assert(handle != NULL); return DBPrivGetDBUsagePercentage(handle->filename); } /** * Freezes the DB so that it is never touched by this process again. In * particular, new OpenDB() calls are ignored and CloseAllDBExit() also ignores * the DB. */ void FreezeDB(DBHandle *handle) { /* This is intentionally NOT using the handle->lock to avoid deadlocks. * Nothing ever sets this to 'false' explicitly, that's only done in the * initialization with '{ { 0 } }', so this bit-flip is safe. */ Log(LOG_LEVEL_NOTICE, "Freezing the DB '%s'", handle->filename); handle->frozen = true; } /*****************************************************************************/ bool ReadComplexKeyDB(DBHandle *handle, const char *key, int key_size, void *dest, int dest_size) { return DBPrivRead(handle->priv, key, key_size, dest, dest_size); } bool WriteComplexKeyDB(DBHandle *handle, const char *key, int key_size, const void *value, int value_size) { return DBPrivWrite(handle->priv, key, key_size, value, value_size); } bool DeleteComplexKeyDB(DBHandle *handle, const char *key, int key_size) { return DBPrivDelete(handle->priv, key, key_size); } bool ReadDB(DBHandle *handle, const char *key, void *dest, int destSz) { return DBPrivRead(handle->priv, key, strlen(key) + 1, dest, destSz); } bool WriteDB(DBHandle *handle, const char *key, const void *src, int srcSz) { return DBPrivWrite(handle->priv, key, strlen(key) + 1, src, srcSz); } bool OverwriteDB(DBHandle *handle, const char *key, const void *value, size_t value_size, OverwriteCondition Condition, void *data) { assert(handle != NULL); return DBPrivOverwrite(handle->priv, key, strlen(key) + 1, value, value_size, Condition, data); } bool HasKeyDB(DBHandle *handle, const char *key, int key_size) { return DBPrivHasKey(handle->priv, key, key_size); } int ValueSizeDB(DBHandle *handle, const char *key, int key_size) { return DBPrivGetValueSize(handle->priv, key, key_size); } bool DeleteDB(DBHandle *handle, const char *key) { return DBPrivDelete(handle->priv, key, strlen(key) + 1); } bool NewDBCursor(DBHandle *handle, DBCursor **cursor) { DBCursorPriv *priv = DBPrivOpenCursor(handle->priv); if (!priv) { return false; } *cursor = xcalloc(1, sizeof(DBCursor)); (*cursor)->cursor = priv; return true; } bool NextDB(DBCursor *cursor, char **key, int *ksize, void **value, int *vsize) { return DBPrivAdvanceCursor(cursor->cursor, (void **)key, ksize, value, vsize); } bool DBCursorDeleteEntry(DBCursor *cursor) { return DBPrivDeleteCursorEntry(cursor->cursor); } bool DBCursorWriteEntry(DBCursor *cursor, const void *value, int value_size) { return DBPrivWriteCursorEntry(cursor->cursor, value, value_size); } bool DeleteDBCursor(DBCursor *cursor) { DBPrivCloseCursor(cursor->cursor); free(cursor); return true; } static bool DBPathLock(FileLock *lock, const char *filename) { char *filename_lock; if (xasprintf(&filename_lock, "%s.lock", filename) == -1) { ProgrammingError("Unable to construct lock database filename for file %s", filename); } if (ExclusiveFileLockPath(lock, filename_lock, true) != 0) { Log(LOG_LEVEL_ERR, "Unable to lock database lock file '%s'.", filename_lock); free(filename_lock); return false; } free(filename_lock); return true; } static void DBPathUnLock(FileLock *lock) { ExclusiveFileUnlock(lock, true); } static void DBPathMoveBroken(const char *filename) { char *filename_broken; if (xasprintf(&filename_broken, "%s.broken", filename) == -1) { ProgrammingError("Unable to construct broken database filename for file '%s'", filename); } if(rename(filename, filename_broken) != 0) { Log(LOG_LEVEL_ERR, "Failed moving broken db out of the way '%s'", filename); } free(filename_broken); } StringMap *LoadDatabaseToStringMap(dbid database_id) { CF_DB *db_conn = NULL; CF_DBC *db_cursor = NULL; char *key = NULL; void *value = NULL; int key_size = 0; int value_size = 0; if (!OpenDB(&db_conn, database_id)) { return NULL; } if (!NewDBCursor(db_conn, &db_cursor)) { Log(LOG_LEVEL_ERR, "Unable to scan db"); CloseDB(db_conn); return NULL; } StringMap *db_map = StringMapNew(); while (NextDB(db_cursor, &key, &key_size, &value, &value_size)) { if (!key) { continue; } if (!value) { Log(LOG_LEVEL_VERBOSE, "Invalid entry (key='%s') in database.", key); continue; } void *val = xcalloc(1, value_size); val = memcpy(val, value, value_size); StringMapInsert(db_map, xstrdup(key), val); } DeleteDBCursor(db_cursor); CloseDB(db_conn); return db_map; } /** * Checks if a DB repair flag file is present and if it is, removes it. * * @return Whether the DB repair flag file was present or not. */ bool CheckDBRepairFlagFile() { /* The DB repair flag file can be created by user or by some process * that hit an error condition potentially caused by local DB corruption * that it was not able to handle properly by repairing the corrupted DB * file(s). For example, if a process is killed by a signal. */ char repair_flag_file[PATH_MAX] = { 0 }; bool present = false; xsnprintf(repair_flag_file, PATH_MAX, "%s%c%s", GetStateDir(), FILE_SEPARATOR, CF_DB_REPAIR_TRIGGER); /* This is full of race-conditions, but it's just a best-effort * thing. If a force-repair is missed, it will happen next time. If it's * done twice, no big deal. */ if (access(repair_flag_file, F_OK) == 0) { present = true; unlink(repair_flag_file); } return present; } cfengine-3.24.2/libpromises/mod_report.c0000644000000000000000000000601615010704253020224 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax printfile_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString("file_to_print", CF_ABSPATHRANGE, "Path name to the file that is to be sent to standard output", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("number_of_lines", CF_INTRANGE, "Integer maximum number of lines to print from selected file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax printfile_body = BodySyntaxNew("printfile", printfile_constraints, NULL, SYNTAX_STATUS_NORMAL); const ConstraintSyntax CF_REPORT_BODIES[] = { ConstraintSyntaxNewString("friend_pattern", "", "Regular expression to keep selected hosts from the friends report list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewReal("intermittency", "0,1", "Real number threshold [0,1] of intermittency about current peers, report above. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("lastseen", CF_VALRANGE, "Integer time threshold in hours since current peers were last seen, report absence", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("printfile", &printfile_body, "Quote part of a file to standard output", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("report_to_file", CF_ABSPATHRANGE, "The path and filename to which output should be appended", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("bundle_return_value_index", CF_IDRANGE, "The promiser is to be interpreted as a literal value that the caller can accept as a result for this bundle, i.e. a return value with array index defined by this attribute.", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("showstate", "", "List of services about which status reports should be reported to standard output", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_REPORT_PROMISE_TYPES[] = { /* Body lists belonging to "reports:" type in Agent */ PromiseTypeSyntaxNew("agent", "reports", CF_REPORT_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/ornaments.c0000644000000000000000000002133515010704253020061 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include /* PromiseID */ /** * @brief Like StringAppend(), but replace characters '*' and '#' with their visible counterparts. * @param buffer Buffer to be used. * @param src Constant string to append * @param n Total size of dst buffer. The string will be truncated if this is exceeded. */ static bool StringAppendPromise(char *dst, const char *src, size_t n) { size_t i, j; if (n == 0) { return false; } n--; for (i = 0; i < n && dst[i]; i++) { } for (j = 0; i < n && src[j]; i++, j++) { const char ch = src[j]; switch (ch) { case CF_MANGLED_NS: dst[i] = ':'; break; case CF_MANGLED_SCOPE: dst[i] = '.'; break; default: dst[i] = ch; break; } } dst[i] = '\0'; return (i < n || !src[j]); } /** * @brief Like @c BufferAppendPromiseStr, but if @c str contains newlines * and is longer than 2*N+3, then only copy an abbreviated version * consisting of the first and last N characters, separated by @c `...` * @param buffer Buffer to be used. * @param str Constant string to append * @param n Total size of dst buffer. The string will be truncated if this is exceeded. * @param max_fragment Max. length of initial/final segment of @c str to keep * @note 2*max_fragment+3 is the maximum length of the appended string (excl. terminating NULL) * */ static bool StringAppendAbbreviatedPromise(char *dst, const char *src, size_t n, const size_t max_fragment) { /* check if `src` contains a new line (may happen for "insert_lines") */ const char *const nl = strchr(src, '\n'); if (nl == NULL) { return StringAppendPromise(dst, src, n); } else { /* `src` contains a newline: abbreviate it by taking the first and last few characters */ static const char sep[] = "..."; char abbr[sizeof(sep) + 2 * max_fragment]; const size_t head = (nl > src + max_fragment) ? max_fragment : (size_t) (nl - src); const char * last_line = strrchr(src, '\n') + 1; assert(last_line); /* not max_fragmentULL, we know we have at least one '\n' */ const size_t tail = strlen(last_line); if (tail > max_fragment) { last_line += tail - max_fragment; } memcpy(abbr, src, head); strcpy(abbr + head, sep); strcat(abbr, last_line); return StringAppendPromise(dst, abbr, n); } } /*********************************************************************/ void SpecialTypeBanner(TypeSequence type, int pass) { if (type == TYPE_SEQUENCE_CONTEXTS) { Log(LOG_LEVEL_VERBOSE, "C: ........................................................."); Log(LOG_LEVEL_VERBOSE, "C: BEGIN classes / conditions (pass %d)", pass); } if (type == TYPE_SEQUENCE_VARS) { Log(LOG_LEVEL_VERBOSE, "V: ........................................................."); Log(LOG_LEVEL_VERBOSE, "V: BEGIN variables (pass %d)", pass); } } void PromiseBanner(EvalContext *ctx, const Promise *pp) { char handle[CF_MAXVARSIZE]; const char *sp; if ((sp = PromiseGetHandle(pp)) || (sp = PromiseID(pp))) { strlcpy(handle, sp, CF_MAXVARSIZE); } else { strcpy(handle, ""); } Log(LOG_LEVEL_VERBOSE, "P: ........................................................."); if (strlen(handle) > 0) { Log(LOG_LEVEL_VERBOSE, "P: BEGIN promise '%s' of type \"%s\" (pass %d)", handle, PromiseGetPromiseType(pp), EvalContextGetPass(ctx)); } else { Log(LOG_LEVEL_VERBOSE, "P: BEGIN un-named promise of type \"%s\" (pass %d)", PromiseGetPromiseType(pp), EvalContextGetPass(ctx)); } const size_t n = 2*CF_MAXFRAGMENT + 3; char pretty_promise_name[n+1]; pretty_promise_name[0] = '\0'; StringAppendAbbreviatedPromise(pretty_promise_name, pp->promiser, n, CF_MAXFRAGMENT); Log(LOG_LEVEL_VERBOSE, "P: Promiser/affected object: '%s'", pretty_promise_name); Rlist *params = NULL; char *varclass; FnCall *fp; if ((params = EvalContextGetBundleArgs(ctx))) { Writer *w = StringWriter(); RlistWrite(w, params); Log(LOG_LEVEL_VERBOSE, "P: From parameterized bundle: %s(%s)", PromiseGetBundle(pp)->name, StringWriterData(w)); WriterClose(w); } else { Log(LOG_LEVEL_VERBOSE, "P: Part of bundle: %s", PromiseGetBundle(pp)->name); } Log(LOG_LEVEL_VERBOSE, "P: Base context class: %s", pp->classes); if ((varclass = PromiseGetConstraintAsRval(pp, "if", RVAL_TYPE_SCALAR)) || (varclass = PromiseGetConstraintAsRval(pp, "ifvarclass", RVAL_TYPE_SCALAR))) { Log(LOG_LEVEL_VERBOSE, "P: \"if\" class condition: %s", varclass); } else if ((fp = (FnCall *)PromiseGetConstraintAsRval(pp, "if", RVAL_TYPE_FNCALL)) || (fp = (FnCall *)PromiseGetConstraintAsRval(pp, "ifvarclass", RVAL_TYPE_FNCALL))) { Writer *w = StringWriter(); FnCallWrite(w, fp); Log(LOG_LEVEL_VERBOSE, "P: \"if\" class condition: %s", StringWriterData(w)); } else if ((varclass = PromiseGetConstraintAsRval(pp, "unless", RVAL_TYPE_SCALAR))) { Log(LOG_LEVEL_VERBOSE, "P: \"unless\" class condition: %s", varclass); } else if ((fp = (FnCall *)PromiseGetConstraintAsRval(pp, "unless", RVAL_TYPE_FNCALL))) { Writer *w = StringWriter(); FnCallWrite(w, fp); Log(LOG_LEVEL_VERBOSE, "P: \"unless\" class condition: %s", StringWriterData(w)); } Log(LOG_LEVEL_VERBOSE, "P: Stack path: %s", EvalContextStackToString(ctx)); if (pp->comment) { Log(LOG_LEVEL_VERBOSE, "P:\n"); Log(LOG_LEVEL_VERBOSE, "P: Comment: %s", pp->comment); } } void Legend() { Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); Log(LOG_LEVEL_VERBOSE, "PREFIX LEGEND:"); Log(LOG_LEVEL_VERBOSE, " V: variable or parameter new definition in scope"); Log(LOG_LEVEL_VERBOSE, " C: class/context new definition "); Log(LOG_LEVEL_VERBOSE, " B: bundle start/end execution marker"); Log(LOG_LEVEL_VERBOSE, " P: promise execution output "); Log(LOG_LEVEL_VERBOSE, " A: accounting output "); Log(LOG_LEVEL_VERBOSE, " T: time measurement for stated object (promise or bundle)"); Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); } void Banner(const char *s) { Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); Log(LOG_LEVEL_VERBOSE, " %s ", s); Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); } void BundleBanner(const Bundle *bp, const Rlist *params) { Log(LOG_LEVEL_VERBOSE, "B: *****************************************************************"); if (params) { Writer *w = StringWriter(); RlistWrite(w, params); Log(LOG_LEVEL_VERBOSE, "B: BEGIN bundle %s(%s)", bp->name, StringWriterData(w)); WriterClose(w); } else { Log(LOG_LEVEL_VERBOSE, "B: BEGIN bundle %s", bp->name); } Log(LOG_LEVEL_VERBOSE, "B: *****************************************************************"); } void EndBundleBanner(const Bundle *bp) { if (bp == NULL) { return; } Log(LOG_LEVEL_VERBOSE, "B: *****************************************************************"); Log(LOG_LEVEL_VERBOSE, "B: END bundle %s", bp->name); Log(LOG_LEVEL_VERBOSE, "B: *****************************************************************"); } cfengine-3.24.2/libpromises/mod_access.h0000644000000000000000000000342215010704253020155 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_ACCESS_H #define CFENGINE_MOD_ACCESS_H #include typedef enum { REMOTE_ACCESS_ADMIT, REMOTE_ACCESS_DENY, REMOTE_ACCESS_ADMITIPS, REMOTE_ACCESS_DENYIPS, REMOTE_ACCESS_ADMITHOSTNAMES, REMOTE_ACCESS_DENYHOSTNAMES, REMOTE_ACCESS_ADMITKEYS, REMOTE_ACCESS_DENYKEYS, REMOTE_ACCESS_MAPROOT, REMOTE_ACCESS_IFENCRYPTED, REMOTE_ACCESS_RESOURCE_TYPE, REMOTE_ACCESS_REPORT_DATA_SELECT, REMOTE_ACCESS_SHORTCUT, REMOTE_ACCESS_NONE } RemoteAccess; typedef enum { REMOTE_ROLE_AUTHORIZE, REMOTE_ROLE_NONE } RemoteRole; extern const PromiseTypeSyntax CF_REMACCESS_PROMISE_TYPES[]; extern const ConstraintSyntax CF_REMACCESS_BODIES[REMOTE_ACCESS_NONE + 1]; extern const ConstraintSyntax CF_REMROLE_BODIES[REMOTE_ROLE_NONE + 1]; #endif cfengine-3.24.2/libpromises/processes_select.c0000644000000000000000000014763715010704253021436 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include /* Chop */ #include /* CompileRegex,StringMatchWithPrecompiledRegex,StringMatchFull */ #include #include // SetUmask(), RestoreUmask() #include #include #include #include #include #include #include # ifdef HAVE_GETZONEID #include #define MAX_ZONENAME_SIZE 64 # endif #ifdef _WIN32 #define TABLE_STORAGE #else #define TABLE_STORAGE static #endif TABLE_STORAGE Item *PROCESSTABLE = NULL; typedef enum { /* * In this mode, all columns must be present by the occurrence of at least * one non-whitespace character. */ PCA_AllColumnsPresent, /* * In this mode, if a process is a zombie, and if there is nothing but * whitespace in the byte columns directly below a header, that column is * skipped. * * This means that very little text shifting will be tolerated, preferably * none, or small enough that all column entries still remain under their * own header. It also means that a zombie process must be detectable by * reading the 'Z' state directly below the 'S' or 'ST' header. */ PCA_ZombieSkipEmptyColumns, } PsColumnAlgorithm; /* Ideally this should be autoconf-tested, but it's really hard to do so. See SplitProcLine() to see the exact effects this has. */ static const PsColumnAlgorithm PS_COLUMN_ALGORITHM[] = { [PLATFORM_CONTEXT_UNKNOWN] = PCA_AllColumnsPresent, [PLATFORM_CONTEXT_OPENVZ] = PCA_AllColumnsPresent, /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = PCA_AllColumnsPresent, /* hpux */ [PLATFORM_CONTEXT_AIX] = PCA_ZombieSkipEmptyColumns, /* aix */ [PLATFORM_CONTEXT_LINUX] = PCA_AllColumnsPresent, /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = PCA_AllColumnsPresent, /* linux */ [PLATFORM_CONTEXT_SOLARIS] = PCA_AllColumnsPresent, /* solaris >= 11 */ [PLATFORM_CONTEXT_SUN_SOLARIS] = PCA_AllColumnsPresent, /* solaris < 11 */ [PLATFORM_CONTEXT_FREEBSD] = PCA_AllColumnsPresent, /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = PCA_AllColumnsPresent, /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = PCA_AllColumnsPresent, /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = PCA_AllColumnsPresent, /* NT - cygnus */ [PLATFORM_CONTEXT_SYSTEMV] = PCA_AllColumnsPresent, /* unixware */ [PLATFORM_CONTEXT_OPENBSD] = PCA_AllColumnsPresent, /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = PCA_AllColumnsPresent, /* sco */ [PLATFORM_CONTEXT_DARWIN] = PCA_AllColumnsPresent, /* darwin */ [PLATFORM_CONTEXT_QNX] = PCA_AllColumnsPresent, /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = PCA_AllColumnsPresent, /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = PCA_AllColumnsPresent, /* mingw */ [PLATFORM_CONTEXT_VMWARE] = PCA_AllColumnsPresent, /* vmware */ [PLATFORM_CONTEXT_ANDROID] = PCA_AllColumnsPresent, /* android */ }; #if defined(__sun) || defined(TEST_UNIT_TEST) static StringMap *UCB_PS_MAP = NULL; // These will be tried in order. static const char *UCB_STYLE_PS[] = { "/usr/ucb/ps", "/bin/ps", NULL }; static const char *UCB_STYLE_PS_ARGS = "axwww"; static const PsColumnAlgorithm UCB_STYLE_PS_COLUMN_ALGORITHM = PCA_ZombieSkipEmptyColumns; #endif static bool SelectProcRangeMatch(char *name1, char *name2, int min, int max, char **names, char **line); static bool SelectProcRegexMatch(const char *name1, const char *name2, const char *regex, bool anchored, char **colNames, char **line); static bool SplitProcLine(const char *proc, time_t pstime, char **names, int *start, int *end, PsColumnAlgorithm pca, char **line); static bool SelectProcTimeCounterRangeMatch(char *name1, char *name2, time_t min, time_t max, char **names, char **line); static bool SelectProcTimeAbsRangeMatch(char *name1, char *name2, time_t min, time_t max, char **names, char **line); static int GetProcColumnIndex(const char *name1, const char *name2, char **names); static void GetProcessColumnNames(const char *proc, char **names, int *start, int *end); static int ExtractPid(char *psentry, char **names, int *end); static void ApplyPlatformExtraTable(char **names, char **columns); /***************************************************************************/ static bool SelectProcess(const char *procentry, time_t pstime, char **names, int *start, int *end, const char *process_regex, const ProcessSelect *a, bool attrselect) { bool result = true; char *column[CF_PROCCOLS]; Rlist *rp; assert(process_regex); assert(a != NULL); StringSet *process_select_attributes = StringSetNew(); memset(column, 0, sizeof(column)); if (!SplitProcLine(procentry, pstime, names, start, end, PS_COLUMN_ALGORITHM[VPSHARDCLASS], column)) { result = false; goto cleanup; } ApplyPlatformExtraTable(names, column); for (int i = 0; names[i] != NULL; i++) { LogDebug(LOG_MOD_PS, "In SelectProcess, COL[%s] = '%s'", names[i], column[i]); } if (!SelectProcRegexMatch("CMD", "COMMAND", process_regex, false, names, column)) { result = false; goto cleanup; } if (!attrselect) { // If we are not considering attributes, then the matching is done. goto cleanup; } for (rp = a->owner; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_FNCALL) { Log(LOG_LEVEL_VERBOSE, "Function call '%s' in process_select body was not resolved, skipping", RlistFnCallValue(rp)->name); } else if (SelectProcRegexMatch("USER", "UID", RlistScalarValue(rp), true, names, column)) { StringSetAdd(process_select_attributes, xstrdup("process_owner")); break; } } if (SelectProcRangeMatch("PID", "PID", a->min_pid, a->max_pid, names, column)) { StringSetAdd(process_select_attributes, xstrdup("pid")); } if (SelectProcRangeMatch("PPID", "PPID", a->min_ppid, a->max_ppid, names, column)) { StringSetAdd(process_select_attributes, xstrdup("ppid")); } if (SelectProcRangeMatch("PGID", "PGID", a->min_pgid, a->max_pgid, names, column)) { StringSetAdd(process_select_attributes, xstrdup("pgid")); } if (SelectProcRangeMatch("VSZ", "SZ", a->min_vsize, a->max_vsize, names, column)) { StringSetAdd(process_select_attributes, xstrdup("vsize")); } if (SelectProcRangeMatch("RSS", "RSS", a->min_rsize, a->max_rsize, names, column)) { StringSetAdd(process_select_attributes, xstrdup("rsize")); } if (SelectProcTimeCounterRangeMatch("TIME", "TIME", a->min_ttime, a->max_ttime, names, column)) { StringSetAdd(process_select_attributes, xstrdup("ttime")); } if (SelectProcTimeAbsRangeMatch ("STIME", "START", a->min_stime, a->max_stime, names, column)) { StringSetAdd(process_select_attributes, xstrdup("stime")); } if (SelectProcRangeMatch("NI", "PRI", a->min_pri, a->max_pri, names, column)) { StringSetAdd(process_select_attributes, xstrdup("priority")); } if (SelectProcRangeMatch("NLWP", "NLWP", a->min_thread, a->max_thread, names, column)) { StringSetAdd(process_select_attributes, xstrdup("threads")); } if (SelectProcRegexMatch("S", "STAT", a->status, true, names, column)) { StringSetAdd(process_select_attributes, xstrdup("status")); } if (SelectProcRegexMatch("CMD", "COMMAND", a->command, true, names, column)) { StringSetAdd(process_select_attributes, xstrdup("command")); } if (SelectProcRegexMatch("TTY", "TTY", a->tty, true, names, column)) { StringSetAdd(process_select_attributes, xstrdup("tty")); } if (!a->process_result) { if (StringSetSize(process_select_attributes) == 0) { result = EvalProcessResult("", process_select_attributes); } else { Writer *w = StringWriter(); StringSetIterator iter = StringSetIteratorInit(process_select_attributes); char *attr = StringSetIteratorNext(&iter); WriterWrite(w, attr); while ((attr = StringSetIteratorNext(&iter))) { WriterWriteChar(w, '.'); WriterWrite(w, attr); } result = EvalProcessResult(StringWriterData(w), process_select_attributes); WriterClose(w); } } else { result = EvalProcessResult(a->process_result, process_select_attributes); } cleanup: StringSetDestroy(process_select_attributes); for (int i = 0; column[i] != NULL; i++) { free(column[i]); } return result; } Item *SelectProcesses(const char *process_name, const ProcessSelect *a, bool attrselect) { assert(a != NULL); const Item *processes = PROCESSTABLE; Item *result = NULL; if (processes == NULL) { return result; } char *names[CF_PROCCOLS]; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; GetProcessColumnNames(processes->name, names, start, end); /* TODO: use actual time of ps-run, as time(NULL) may be later. */ time_t pstime = time(NULL); for (Item *ip = processes->next; ip != NULL; ip = ip->next) { if (NULL_OR_EMPTY(ip->name)) { continue; } if (!SelectProcess(ip->name, pstime, names, start, end, process_name, a, attrselect)) { continue; } pid_t pid = ExtractPid(ip->name, names, end); if (pid == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to extract pid while looking for %s", process_name); continue; } PrependItem(&result, ip->name, ""); result->counter = (int)pid; } for (int i = 0; i < CF_PROCCOLS; i++) { free(names[i]); } return result; } static bool SelectProcRangeMatch(char *name1, char *name2, int min, int max, char **names, char **line) { int i; long value; if ((min == CF_NOINT) || (max == CF_NOINT)) { return false; } if ((i = GetProcColumnIndex(name1, name2, names)) != -1) { value = IntFromString(line[i]); if (value == CF_NOINT) { Log(LOG_LEVEL_INFO, "Failed to extract a valid integer from '%s' => '%s' in process list", names[i], line[i]); return false; } if ((min <= value) && (value <= max)) { return true; } else { return false; } } return false; } /***************************************************************************/ static long TimeCounter2Int(const char *s) { long days, hours, minutes, seconds; if (s == NULL) { return CF_NOINT; } /* If we match dd-hh:mm[:ss], believe it: */ int got = sscanf(s, "%ld-%ld:%ld:%ld", &days, &hours, &minutes, &seconds); if (got > 2) { /* All but perhaps seconds set */ } /* Failing that, try matching hh:mm[:ss] */ else if (1 < (got = sscanf(s, "%ld:%ld:%ld", &hours, &minutes, &seconds))) { /* All but days and perhaps seconds set */ days = 0; got++; } else { Log(LOG_LEVEL_ERR, "Unable to parse 'ps' time field as [dd-]hh:mm[:ss], got '%s'", s); return CF_NOINT; } assert(got > 2); /* i.e. all but maybe seconds have been set */ /* Clear seconds if unset: */ if (got < 4) { seconds = 0; } LogDebug(LOG_MOD_PS, "TimeCounter2Int:" " Parsed '%s' as elapsed time '%ld-%02ld:%02ld:%02ld'", s, days, hours, minutes, seconds); /* Convert to seconds: */ return ((days * 24 + hours) * 60 + minutes) * 60 + seconds; } static bool SelectProcTimeCounterRangeMatch(char *name1, char *name2, time_t min, time_t max, char **names, char **line) { if ((min == CF_NOINT) || (max == CF_NOINT)) { return false; } int i = GetProcColumnIndex(name1, name2, names); if (i != -1) { time_t value = (time_t) TimeCounter2Int(line[i]); if (value == CF_NOINT) { Log(LOG_LEVEL_INFO, "Failed to extract a valid integer from %s => '%s' in process list", names[i], line[i]); return false; } if ((min <= value) && (value <= max)) { Log(LOG_LEVEL_VERBOSE, "Selection filter matched counter range" " '%s/%s' = '%s' in [%jd,%jd] (= %jd secs)", name1, name2, line[i], (intmax_t)min, (intmax_t)max, (intmax_t)value); return true; } else { LogDebug(LOG_MOD_PS, "Selection filter REJECTED counter range" " '%s/%s' = '%s' in [%jd,%jd] (= %jd secs)", name1, name2, line[i], (intmax_t) min, (intmax_t) max, (intmax_t) value); return false; } } return false; } static time_t TimeAbs2Int(const char *s) { if (s == NULL) { return CF_NOINT; } struct tm tm; localtime_r(&CFSTARTTIME, &tm); tm.tm_sec = 0; tm.tm_isdst = -1; /* Try various ways to parse s: */ char word[4]; /* Abbreviated month name */ long ns[3]; /* Miscellaneous numbers, diverse readings */ int got = sscanf(s, "%2ld:%2ld:%2ld", ns, ns + 1, ns + 2); if (1 < got) /* Hr:Min[:Sec] */ { tm.tm_hour = ns[0]; tm.tm_min = ns[1]; if (got == 3) { tm.tm_sec = ns[2]; } } /* or MMM dd (the %ld shall ignore any leading space) */ else if (sscanf(s, "%3[a-zA-Z]%ld", word, ns) == 2 && /* Only match if word is a valid month text: */ 0 < (ns[1] = Month2Int(word))) { int month = ns[1] - 1; if (tm.tm_mon < month) { /* Wrapped around */ tm.tm_year--; } tm.tm_mon = month; tm.tm_mday = ns[0]; tm.tm_hour = 0; tm.tm_min = 0; } /* or just year, or seconds since 1970 */ else if (sscanf(s, "%ld", ns) == 1) { if (ns[0] > 9999) { /* Seconds since 1970. * * This is the amended value SplitProcLine() replaces * start time with if it's imprecise and a better value * can be calculated from elapsed time. */ return (time_t)ns[0]; } /* else year, at most four digits; either 4-digit CE or * already relative to 1900. */ memset(&tm, 0, sizeof(tm)); tm.tm_year = ns[0] < 999 ? ns[0] : ns[0] - 1900; tm.tm_isdst = -1; } else { return CF_NOINT; } return mktime(&tm); } static bool SelectProcTimeAbsRangeMatch(char *name1, char *name2, time_t min, time_t max, char **names, char **line) { int i; time_t value; if ((min == CF_NOINT) || (max == CF_NOINT)) { return false; } if ((i = GetProcColumnIndex(name1, name2, names)) != -1) { value = TimeAbs2Int(line[i]); if (value == CF_NOINT) { Log(LOG_LEVEL_INFO, "Failed to extract a valid integer from %c => '%s' in process list", name1[i], line[i]); return false; } if ((min <= value) && (value <= max)) { Log(LOG_LEVEL_VERBOSE, "Selection filter matched absolute '%s/%s' = '%s(%jd)' in [%jd,%jd]", name1, name2, line[i], (intmax_t)value, (intmax_t)min, (intmax_t)max); return true; } else { return false; } } return false; } /***************************************************************************/ static bool SelectProcRegexMatch(const char *name1, const char *name2, const char *regex, bool anchored, char **colNames, char **line) { int i; if (regex == NULL) { return false; } if ((i = GetProcColumnIndex(name1, name2, colNames)) != -1) { if (anchored) { return StringMatchFull(regex, line[i]); } else { size_t s, e; return StringMatch(regex, line[i], &s, &e); } } return false; } static void PrintStringIndexLine(int prefix_spaces, int len) { char arrow_str[CF_BUFSIZE]; arrow_str[0] = '^'; arrow_str[1] = '\0'; char index_str[CF_BUFSIZE]; index_str[0] = '0'; index_str[1] = '\0'; for (int lineindex = 10; lineindex <= len; lineindex += 10) { char num[PRINTSIZE(lineindex)]; xsnprintf(num, sizeof(num), "%10d", lineindex); strlcat(index_str, num, sizeof(index_str)); strlcat(arrow_str, " ^", sizeof(arrow_str)); } // Prefix the beginning of the indexes with the given number. LogDebug(LOG_MOD_PS, "%*s%s", prefix_spaces, "", arrow_str); LogDebug(LOG_MOD_PS, "%*s%s", prefix_spaces, "Index: ", index_str); } static void MaybeFixStartTime(const char *line, time_t pstime, char **names, char **fields) { /* Since start times can be very imprecise (e.g. just a past day's * date, or a past year), calculate a better value from elapsed * time, if available: */ int k = GetProcColumnIndex("ELAPSED", "ELAPSED", names); if (k != -1) { const long elapsed = TimeCounter2Int(fields[k]); if (elapsed != CF_NOINT) /* Only use if parsed successfully ! */ { int j = GetProcColumnIndex("STIME", "START", names), ns[3]; /* Trust the reported value if it matches hh:mm[:ss], though: */ if (sscanf(fields[j], "%d:%d:%d", ns, ns + 1, ns + 2) < 2) { time_t value = pstime - (time_t) elapsed; LogDebug(LOG_MOD_PS, "processes: Replacing parsed start time %s with %s", fields[j], ctime(&value)); free(fields[j]); xasprintf(fields + j, "%ld", value); } } else if (fields[k]) { Log(LOG_LEVEL_VERBOSE, "Parsing problem was in ELAPSED field of '%s'", line); } } } /*******************************************************************/ /* fields must be char *fields[CF_PROCCOLS] in fact. */ /* pstime should be the time at which ps was run. */ static bool SplitProcLine(const char *line, time_t pstime, char **names, int *start, int *end, PsColumnAlgorithm pca, char **fields) { if (line == NULL || line[0] == '\0') { return false; } const size_t checklen = strlen(line); if (checklen > INT_MAX) { Log(LOG_LEVEL_ERR, "Proc line too long (%zu > %d)", checklen, INT_MAX); return false; } int linelen = (int) checklen; if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { LogDebug(LOG_MOD_PS, "Parsing ps line: '%s'", line); // Makes the entry line up with the line above. PrintStringIndexLine(18, linelen); } /* All platforms have been verified to not produce overlapping fields with currently used ps tools, and hence we can parse based on space separation (with some caveats, see below). Dates may have spaces in them, like "May 4", or not, like "May4". Prefer to match a date without spaces as long as it contains a number, but fall back to parsing letters followed by space(s) and a date. Commands will also have extra spaces, but it is always the last field, so we just include spaces at this point in the parsing. An additional complication is that some platforms (only AIX is known at the time of writing) can have empty columns when a process is a zombie. The plan is to match for this by checking the range between start and end directly below the header (same byte position). If the whole range is whitespace we consider the entry missing. The columns are (presumably) guaranteed to line up correctly for this, since zombie processes do not have memory usage which can produce large, potentially alignment-altering numbers. However, we cannot do this whitespace check in general, because non-zombie processes may shift columns in a way that leaves some columns apparently (but not actually) empty. Zombie processes have state Z and command on AIX. Similarly processes marked with command also have missing columns and need to be skipped. (AIX only). Take these two examples: Windows: User field can contain spaces. E.g.: USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND NETWORK SERVICE 540 0.0 0.3 5092 11180 ? ? Apr28 00:00 C:\\Windows\\system32\\svchost.exe -k RPCSS -p etc. There is really no good way to do this with the current parsing logic. We know that the next field will be a PID, so we can parse until we find a number. AIX: USER PID PPID PGID %CPU %MEM VSZ NI S STIME TIME COMMAND root 1 0 0 0.0 0.0 784 20 A Nov 28 00:00:00 /etc/init root 1835344 1 1835344 0.0 0.0 944 20 A Nov 28 00:00:00 /usr/lib/errdemon root 2097594 1 1638802 0.0 0.0 596 20 A Nov 28 00:00:05 /usr/sbin/syncd 60 root 3408328 1 3408328 0.0 0.0 888 20 A Nov 28 00:00:00 /usr/sbin/srcmstr root 4325852 3408328 4325852 0.0 0.0 728 20 A Nov 28 00:00:00 /usr/sbin/syslogd root 4784534 3408328 4784534 0.0 0.0 1212 20 A Nov 28 00:00:00 sendmail: accepting connections root 5898690 1 5898690 0.0 0.0 1040 20 A Nov 28 00:00:00 /usr/sbin/cron 6095244 8913268 8913268 20 Z 00:00:00 root 6160866 3408328 6160866 0.0 0.0 1612 20 A Nov 28 00:00:00 /opt/rsct/bin/IBM.ServiceRMd 6750680 17826152 17826152 20 Z 00:00:00 root 7143692 3408328 7143692 0.0 0.0 476 20 A Nov 28 00:00:00 /var/perf/pm/bin/pmperfrec root 7340384 8651136 8651136 0.0 0.0 500 20 A Nov 28 00:00:00 [trspoolm] root 7602560 8978714 7602560 0.0 0.0 636 20 A Nov 28 00:00:00 sshd: u0013628 [priv] 7733720 - - - A - Solaris 9: USER PID %CPU %MEM SZ RSS TT S STIME TIME COMMAND jenkins 29769 0.0 0.0 810 2976 pts/1 S 07:22:43 0:00 /usr/bin/perl ../../ps.pl jenkins 29835 - - 0 0 ? Z - 0:00 jenkins 10026 0.0 0.3 30927 143632 ? S Jan_21 01:18:58 /usr/jdk/jdk1.6.0_45/bin/java -jar slave.jar Due to how the process state 'S' is shifted under the 'S' header in the second example, it is not possible to separate between this and a missing column. Counting spaces is no good, because commands can contain an arbitrary number of spaces, and there is no way to know the byte position where a command begins. Hence the only way is to base this algorithm on platform and only do the "empty column detection" when: * The platform is known to produce empty columns for zombie processes (see PCA_ZombieSkipEmptyColumns) * The platform is known to not shift columns when the process is a zombie. * It is a zombie / exiting / idle process (These states provide almost no useful info in ps output) */ bool skip = false; if (pca == PCA_ZombieSkipEmptyColumns) { // Find out if the process is a zombie. for (int field = 0; names[field] && !skip; field++) { if (strcmp(names[field], "S") == 0 || strcmp(names[field], "ST") == 0) { // Check for zombie state. for (int pos = start[field]; pos <= end[field] && pos < linelen && !skip; pos++) { // 'Z' letter with word boundary on each side. if (isspace(line[pos - 1]) && line[pos] == 'Z' && (isspace(line[pos + 1]) || line[pos + 1] == '\0')) { LogDebug(LOG_MOD_PS, "Detected zombie process, " "skipping parsing of empty ps fields."); skip = true; } } } else if (strcmp(names[field], "COMMAND") == 0) { // Check for exiting or idle state. for (int pos = start[field]; pos <= end[field] && pos < linelen && !skip; pos++) { if (!isspace(line[pos])) // Skip spaces { if (strncmp(line + pos, "", 9) == 0 || strncmp(line + pos, "", 6) == 0) { LogDebug(LOG_MOD_PS, "Detected exiting/idle process, " "skipping parsing of empty ps fields."); skip = true; } else { break; } } } } } } int field = 0; int pos = 0; while (names[field]) { // Some sanity checks. if (pos >= linelen) { if (pca == PCA_ZombieSkipEmptyColumns && skip) { LogDebug(LOG_MOD_PS, "Assuming '%s' field is empty, " "since ps line '%s' is not long enough to reach under its " "header.", names[field], line); fields[field] = xstrdup(""); field++; continue; } else { Log(LOG_LEVEL_ERR, "ps output line '%s' is shorter than its " "associated header.", line); return false; } } bool cmd = (strcmp(names[field], "CMD") == 0 || strcmp(names[field], "COMMAND") == 0); bool stime = !cmd && (strcmp(names[field], "STIME") == 0); bool is_user_field = StringEqual(names[field], "USER"); // Equal boolean results, either both must be true, or both must be // false. IOW we must either both be at the last field, and it must be // CMD, or none of those. | // v if ((names[field + 1] != NULL) == cmd) { Log(LOG_LEVEL_ERR, "Last field of ps output '%s' is not " "CMD/COMMAND.", line); return false; } // If zombie/exiting, check if field is empty. if (pca == PCA_ZombieSkipEmptyColumns && skip) { int empty_pos = start[field]; bool empty = true; while (empty_pos <= end[field]) { if (!isspace(line[empty_pos])) { empty = false; break; } empty_pos++; } if (empty) { LogDebug(LOG_MOD_PS, "Detected empty" " '%s' field between positions %d and %d", names[field], start[field], end[field]); fields[field] = xstrdup(""); pos = end[field] + 1; field++; continue; } else { LogDebug(LOG_MOD_PS, "Detected non-empty " "'%s' field between positions %d and %d", names[field], start[field], end[field]); } } // Preceding space. while (isspace(line[pos])) { pos++; } // Field. int last = pos; if (cmd) { // Last field, slurp up the rest, but discard trailing whitespace. last = linelen; while (last > pos && isspace(line[last - 1])) { last--; } } else if (stime) { while (isalpha(line[last])) { last++; } if (isspace(line[last])) { // In this case we expect spaces followed by a number. // It means what we first read was the month, now is the date. do { last++; } while (isspace(line[last])); if (!isdigit(line[last])) { char fmt[200]; xsnprintf(fmt, sizeof(fmt), "Unable to parse STIME entry in ps " "output line '%%s': Expected day number after " "'%%.%ds'", (last - 1) - pos); Log(LOG_LEVEL_ERR, fmt, line, line + pos); return false; } } while (line[last] && !isspace(line[last])) { last++; } } else if (is_user_field) { bool done = false; while (!done) { while (line[last] != '\0' && !isspace(line[last])) { last++; } /* On windows the USER field can contain spaces. We know that * the next field will be PID. Hence, we seek past the spaces * to see if the next thing is a number. If this is not the * case, we assume it is still the USER field. This is not * bulletproof. However, this parser never was. */ int seek_past = last; while (line[seek_past] != '\0' && isspace(line[seek_past])) { seek_past++; } if (line[seek_past] == '\0') { done = true; } else if (isdigit(line[seek_past])) { done = true; } else { last = seek_past; } } } else { // Generic fields while (line[last] && !isspace(line[last])) { last++; } } // Make a copy and store in fields. fields[field] = xstrndup(line + pos, last - pos); LogDebug(LOG_MOD_PS, "'%s' field '%s'" " extracted from between positions %d and %d", names[field], fields[field], pos, last - 1); pos = last; field++; } MaybeFixStartTime(line, pstime, names, fields); return true; } /*******************************************************************/ static int GetProcColumnIndex(const char *name1, const char *name2, char **names) { for (int i = 0; names[i] != NULL; i++) { if (strcmp(names[i], name1) == 0 || strcmp(names[i], name2) == 0) { return i; } } LogDebug(LOG_MOD_PS, "Process column %s/%s" " was not supported on this system", name1, name2); return -1; } /**********************************************************************************/ bool IsProcessNameRunning(char *procNameRegex) { char *colHeaders[CF_PROCCOLS]; int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; bool matched = false; int i; memset(colHeaders, 0, sizeof(colHeaders)); if (PROCESSTABLE == NULL) { Log(LOG_LEVEL_ERR, "IsProcessNameRunning: PROCESSTABLE is empty"); return false; } /* TODO: use actual time of ps-run, not time(NULL), which may be later. */ time_t pstime = time(NULL); GetProcessColumnNames(PROCESSTABLE->name, colHeaders, start, end); for (const Item *ip = PROCESSTABLE->next; !matched && ip != NULL; ip = ip->next) // iterate over ps lines { char *lineSplit[CF_PROCCOLS]; memset(lineSplit, 0, sizeof(lineSplit)); if (NULL_OR_EMPTY(ip->name)) { continue; } if (!SplitProcLine(ip->name, pstime, colHeaders, start, end, PS_COLUMN_ALGORITHM[VPSHARDCLASS], lineSplit)) { Log(LOG_LEVEL_ERR, "IsProcessNameRunning: Could not split process line '%s'", ip->name); goto loop_cleanup; } ApplyPlatformExtraTable(colHeaders, lineSplit); if (SelectProcRegexMatch("CMD", "COMMAND", procNameRegex, true, colHeaders, lineSplit)) { matched = true; } loop_cleanup: for (i = 0; lineSplit[i] != NULL; i++) { free(lineSplit[i]); } } for (i = 0; colHeaders[i] != NULL; i++) { free(colHeaders[i]); } return matched; } static void GetProcessColumnNames(const char *proc, char **names, int *start, int *end) { char title[16]; int col, offset = 0; if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { LogDebug(LOG_MOD_PS, "Parsing ps line: '%s'", proc); // Makes the entry line up with the line above. PrintStringIndexLine(18, strlen(proc)); } for (col = 0; col < CF_PROCCOLS; col++) { start[col] = end[col] = -1; names[col] = NULL; } col = 0; for (const char *sp = proc; *sp != '\0'; sp++) { offset = sp - proc; if (isspace((unsigned char) *sp)) { if (start[col] != -1) { LogDebug(LOG_MOD_PS, "End of '%s' is %d", title, offset - 1); end[col++] = offset - 1; if (col >= CF_PROCCOLS) /* No space for more columns. */ { size_t blank = strspn(sp, " \t\r\n\f\v"); if (sp[blank]) /* i.e. that wasn't everything. */ { /* If this happens, we have more columns in * our ps output than space to store them. * Update the #define CF_PROCCOLS (last seen * in libpromises/cf3.defs.h) to a bigger * number ! */ Log(LOG_LEVEL_ERR, "Process table lacks space for last columns: %s", sp + blank); } break; } } } else if (start[col] == -1) { if (col == 0) { // The first column always extends all the way to the left. start[col] = 0; } else { start[col] = offset; } if (sscanf(sp, "%15s", title) == 1) { LogDebug(LOG_MOD_PS, "Start of '%s' is at offset: %d", title, offset); LogDebug(LOG_MOD_PS, "Col[%d] = '%s'", col, title); names[col] = xstrdup(title); } } } if (end[col] == -1) { LogDebug(LOG_MOD_PS, "End of '%s' is %d", title, offset); end[col] = offset; } } #ifndef _WIN32 static const char *GetProcessOptions(void) { # ifdef __linux__ if (strncmp(VSYSNAME.release, "2.4", 3) == 0) { // No threads on 2.4 kernels, so omit nlwp return "-eo user,pid,ppid,pgid,pcpu,pmem,vsz,ni,rss:9,stime,etime,time,args"; } # endif return VPSOPTS[VPSHARDCLASS]; } #endif static int ExtractPid(char *psentry, char **names, int *end) { int offset = 0; for (int col = 0; col < CF_PROCCOLS; col++) { if (strcmp(names[col], "PID") == 0) { if (col > 0) { offset = end[col - 1]; } break; } } for (const char *sp = psentry + offset; *sp != '\0'; sp++) /* if first field contains alpha, skip */ { /* If start with alphanum then skip it till the first space */ if (isalnum((unsigned char) *sp)) { while (*sp != ' ' && *sp != '\0') { sp++; } } while (*sp == ' ' || *sp == '\t') { sp++; } int pid; if (sscanf(sp, "%d", &pid) == 1 && pid != -1) { return pid; } } return -1; } # ifndef _WIN32 # ifdef HAVE_GETZONEID /* ListLookup with the following return semantics * -1 if the first argument is smaller than the second * 0 if the arguments are equal * 1 if the first argument is bigger than the second */ int PidListCompare(const void *pid1, const void *pid2, ARG_UNUSED void *user_data) { int p1 = (intptr_t)(void *)pid1; int p2 = (intptr_t)(void *)pid2; if (p1 < p2) { return -1; } else if (p1 > p2) { return 1; } return 0; } /* Load processes using zone-aware ps * to obtain solaris list of global * process ids for root and non-root * users to lookup later */ int ZLoadProcesstable(Seq *pidlist, Seq *rootpidlist) { char *names[CF_PROCCOLS]; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; const char *pscmd = "/usr/bin/ps -Aleo zone,user,pid"; FILE *psf = cf_popen(pscmd, "r", false); if (psf == NULL) { Log(LOG_LEVEL_ERR, "ZLoadProcesstable: Couldn't open the process list with command %s.", pscmd); return false; } size_t pbuff_size = CF_BUFSIZE; char *pbuff = xmalloc(pbuff_size); bool header = true; while (true) { ssize_t res = CfReadLine(&pbuff, &pbuff_size, psf); if (res == -1) { if (!feof(psf)) { Log(LOG_LEVEL_ERR, "IsGlobalProcess(char **, int): Unable to read process list with command '%s'. (fread: %s)", pscmd, GetErrorStr()); cf_pclose(psf); free(pbuff); return false; } else { break; } } Chop(pbuff, pbuff_size); if (header) /* This line is the header. */ { GetProcessColumnNames(pbuff, &names[0], start, end); } else { int pid = ExtractPid(pbuff, &names[0], end); size_t zone_offset = strspn(pbuff, " "); size_t zone_end_offset = strcspn(pbuff + zone_offset, " ") + zone_offset; size_t user_offset = strspn(pbuff + zone_end_offset, " ") + zone_end_offset; size_t user_end_offset = strcspn(pbuff + user_offset, " ") + user_offset; bool is_global = (zone_end_offset - zone_offset == 6 && strncmp(pbuff + zone_offset, "global", 6) == 0); bool is_root = (user_end_offset - user_offset == 4 && strncmp(pbuff + user_offset, "root", 4) == 0); if (is_global && is_root) { SeqAppend(rootpidlist, (void*)(intptr_t)pid); } else if (is_global && !is_root) { SeqAppend(pidlist, (void*)(intptr_t)pid); } } header = false; } cf_pclose(psf); free(pbuff); return true; } bool PidInSeq(Seq *list, int pid) { void *res = SeqLookup(list, (void *)(intptr_t)pid, PidListCompare); int result = (intptr_t)(void*)res; if (result == pid) { return true; } return false; } /* return true if the process with * pid is in the global zone */ int IsGlobalProcess(int pid, Seq *pidlist, Seq *rootpidlist) { if (PidInSeq(pidlist, pid) || PidInSeq(rootpidlist, pid)) { return true; } else { return false; } } void ZCopyProcessList(Item **dest, const Item *source, Seq *pidlist, char **names, int *end) { int gpid = ExtractPid(source->name, names, end); if (PidInSeq(pidlist, gpid)) { PrependItem(dest, source->name, ""); } } # endif /* HAVE_GETZONEID */ static void CheckPsLineLimitations(void) { #ifdef __hpux FILE *ps_fd; int ret; char limit[21]; char *buf = NULL; size_t bufsize = 0; ps_fd = safe_fopen("/etc/default/ps", "r"); if (!ps_fd) { Log(LOG_LEVEL_VERBOSE, "Could not open '/etc/default/ps' " "to check ps line length limitations."); return; } while (true) { ret = CfReadLine(&buf, &bufsize, ps_fd); if (ret < 0) { break; } ret = sscanf(buf, "DEFAULT_CMD_LINE_WIDTH = %20[0-9]", limit); if (ret == 1) { if (atoi(limit) < 1024) { Log(LOG_LEVEL_VERBOSE, "ps line length limit is less than 1024. " "Consider adjusting the DEFAULT_CMD_LINE_WIDTH setting in /etc/default/ps " "in order to guarantee correct process matching."); } break; } } free(buf); fclose(ps_fd); #endif // __hpux } #endif // _WIN32 const char *GetProcessTableLegend(void) { if (PROCESSTABLE) { // First entry in the table is legend. return PROCESSTABLE->name; } else { return ""; } } #if defined(__sun) || defined(TEST_UNIT_TEST) static FILE *OpenUcbPsPipe(void) { for (int i = 0; UCB_STYLE_PS[i]; i++) { struct stat statbuf; if (stat(UCB_STYLE_PS[i], &statbuf) < 0) { Log(LOG_LEVEL_VERBOSE, "%s not found, cannot be used for extra process information", UCB_STYLE_PS[i]); continue; } if (!(statbuf.st_mode & 0111)) { Log(LOG_LEVEL_VERBOSE, "%s not executable, cannot be used for extra process information", UCB_STYLE_PS[i]); continue; } char *ps_cmd; xasprintf(&ps_cmd, "%s %s", UCB_STYLE_PS[i], UCB_STYLE_PS_ARGS); FILE *cmd = cf_popen(ps_cmd, "rt", false); if (!cmd) { Log(LOG_LEVEL_WARNING, "Could not execute \"%s\", extra process " "information not available. " "Process command line length may be limited to 80 characters.", ps_cmd); } free(ps_cmd); return cmd; } Log(LOG_LEVEL_VERBOSE, "No eligible tool for extra process information " "found. Skipping."); return NULL; } static void ReadFromUcbPsPipe(FILE *cmd) { char *names[CF_PROCCOLS]; memset(names, 0, sizeof(names)); int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; char *line = NULL; size_t linesize = 0; bool header = true; time_t pstime = time(NULL); int pidcol = -1; int cmdcol = -1; while (CfReadLine(&line, &linesize, cmd) > 0) { if (header) { GetProcessColumnNames(line, names, start, end); for (int i = 0; names[i]; i++) { if (strcmp(names[i], "PID") == 0) { pidcol = i; } else if (strcmp(names[i], "COMMAND") == 0 || strcmp(names[i], "CMD") == 0) { cmdcol = i; } } if (pidcol < 0 || cmdcol < 0) { Log(LOG_LEVEL_ERR, "Could not find PID and/or CMD/COMMAND column in " "ps output: \"%s\"", line); break; } header = false; continue; } char *columns[CF_PROCCOLS]; memset(columns, 0, sizeof(columns)); if (!SplitProcLine(line, pstime, names, start, end, UCB_STYLE_PS_COLUMN_ALGORITHM, columns)) { Log(LOG_LEVEL_WARNING, "Not able to parse ps output: \"%s\"", line); } StringMapInsert(UCB_PS_MAP, columns[pidcol], columns[cmdcol]); // We avoid strdup'ing these strings by claiming ownership here. columns[pidcol] = NULL; columns[cmdcol] = NULL; for (int i = 0; i < CF_PROCCOLS; i++) { // There may be some null entries here, but since we "steal" // strings in the section above, we may have set some of them to // NULL and there may be following non-NULL fields. free(columns[i]); } } if (!feof(cmd) && ferror(cmd)) { Log(LOG_LEVEL_ERR, "Error while reading output from ps: %s", GetErrorStr()); } for (int i = 0; names[i] && i < CF_PROCCOLS; i++) { free(names[i]); } free(line); } static void ClearPlatformExtraTable(void) { if (UCB_PS_MAP) { StringMapDestroy(UCB_PS_MAP); UCB_PS_MAP = NULL; } } static void LoadPlatformExtraTable(void) { if (UCB_PS_MAP) { return; } UCB_PS_MAP = StringMapNew(); FILE *cmd = OpenUcbPsPipe(); if (!cmd) { return; } ReadFromUcbPsPipe(cmd); if (cf_pclose(cmd) != 0) { Log(LOG_LEVEL_WARNING, "Command returned non-zero while gathering " "extra process information."); // Make an empty map, in this case. The information can't be trusted. StringMapClear(UCB_PS_MAP); } } static void ApplyPlatformExtraTable(char **names, char **columns) { int pidcol = -1; for (int i = 0; names[i] && columns[i]; i++) { if (strcmp(names[i], "PID") == 0) { pidcol = i; break; } } if (pidcol == -1 || !StringMapHasKey(UCB_PS_MAP, columns[pidcol])) { return; } for (int i = 0; names[i] && columns[i]; i++) { if (strcmp(names[i], "COMMAND") == 0 || strcmp(names[i], "CMD") == 0) { free(columns[i]); columns[i] = xstrdup(StringMapGet(UCB_PS_MAP, columns[pidcol])); break; } } } #else static inline void LoadPlatformExtraTable(void) { } static inline void ClearPlatformExtraTable(void) { } static inline void ApplyPlatformExtraTable(ARG_UNUSED char **names, ARG_UNUSED char **columns) { } #endif #ifndef _WIN32 bool LoadProcessTable() { FILE *prp; char pscomm[CF_MAXLINKSIZE]; Item *rootprocs = NULL; Item *otherprocs = NULL; if (PROCESSTABLE) { Log(LOG_LEVEL_VERBOSE, "Reusing cached process table"); return true; } LoadPlatformExtraTable(); CheckPsLineLimitations(); const char *psopts = GetProcessOptions(); snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VPSHARDCLASS], psopts); Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm); if ((prp = cf_popen(pscomm, "r", false)) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr()); return false; } size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); # ifdef HAVE_GETZONEID char *names[CF_PROCCOLS]; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; Seq *pidlist = SeqNew(1, NULL); Seq *rootpidlist = SeqNew(1, NULL); bool global_zone = IsGlobalZone(); if (global_zone) { int res = ZLoadProcesstable(pidlist, rootpidlist); if (res == false) { Log(LOG_LEVEL_ERR, "Unable to load solaris zone process table."); return false; } } # endif ARG_UNUSED bool header = true; /* used only if HAVE_GETZONEID */ for (;;) { ssize_t res = CfReadLine(&vbuff, &vbuff_size, prp); if (res == -1) { if (!feof(prp)) { Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr()); cf_pclose(prp); free(vbuff); return false; } else { break; } } Chop(vbuff, vbuff_size); # ifdef HAVE_GETZONEID if (global_zone) { if (header) { /* this is the banner so get the column header names for later use*/ GetProcessColumnNames(vbuff, &names[0], start, end); } else { int gpid = ExtractPid(vbuff, names, end); if (!IsGlobalProcess(gpid, pidlist, rootpidlist)) { continue; } } } # endif AppendItem(&PROCESSTABLE, vbuff, ""); header = false; } cf_pclose(prp); /* Now save the data */ const char* const statedir = GetStateDir(); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_procs", statedir, FILE_SEPARATOR); RawSaveItemList(PROCESSTABLE, vbuff, NewLineMode_Unix); # ifdef HAVE_GETZONEID if (global_zone) /* pidlist and rootpidlist are empty if we're not in the global zone */ { Item *ip = PROCESSTABLE; while (ip != NULL) { ZCopyProcessList(&rootprocs, ip, rootpidlist, names, end); ip = ip->next; } ReverseItemList(rootprocs); ip = PROCESSTABLE; while (ip != NULL) { ZCopyProcessList(&otherprocs, ip, pidlist, names, end); ip = ip->next; } ReverseItemList(otherprocs); } else # endif { CopyList(&rootprocs, PROCESSTABLE); CopyList(&otherprocs, PROCESSTABLE); while (DeleteItemNotContaining(&rootprocs, "root")) { } while (DeleteItemContaining(&otherprocs, "root")) { } } if (otherprocs) { PrependItem(&rootprocs, otherprocs->name, NULL); } // TODO: Change safe_fopen() to default to 0600, then remove this. const mode_t old_umask = SetUmask(0077); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_rootprocs", statedir, FILE_SEPARATOR); RawSaveItemList(rootprocs, vbuff, NewLineMode_Unix); DeleteItemList(rootprocs); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_otherprocs", statedir, FILE_SEPARATOR); RawSaveItemList(otherprocs, vbuff, NewLineMode_Unix); DeleteItemList(otherprocs); RestoreUmask(old_umask); free(vbuff); return true; } # endif void ClearProcessTable(void) { ClearPlatformExtraTable(); DeleteItemList(PROCESSTABLE); PROCESSTABLE = NULL; } cfengine-3.24.2/libpromises/string_expressions.c0000644000000000000000000001727415010704253022032 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include /* */ static StringParseResult ParseQname(const char *expr, int start, int end) { StringParseResult lhs, rhs; StringExpression *ret, *subret, *dot; lhs = ParseStringExpression(expr, start, end); if (!lhs.result) { return lhs; } if (lhs.position == end || expr[lhs.position] != '.') { return lhs; } rhs = ParseStringExpression(expr, lhs.position + 1, end); if (!rhs.result) { FreeStringExpression(lhs.result); return rhs; } dot = xcalloc(1, sizeof(StringExpression)); dot->op = LITERAL; dot->val.literal.literal = xstrdup("."); subret = xcalloc(1, sizeof(StringExpression)); subret->op = CONCAT; subret->val.concat.lhs = dot; subret->val.concat.rhs = rhs.result; ret = xcalloc(1, sizeof(StringExpression)); ret->op = CONCAT; ret->val.concat.lhs = lhs.result; ret->val.concat.rhs = subret; return (StringParseResult) {ret, rhs.position}; } /* */ static StringParseResult ParseVarRef(const char *expr, int start, int end) { if (start + 1 < end && (expr[start] == '$' || expr[start] == '@')) { if (expr[start + 1] == '(' || expr[start + 1] == '{') { char closing_bracket = expr[start + 1] == '(' ? ')' : '}'; StringParseResult res = ParseQname(expr, start + 2, end); if (res.result) { if (res.position < end && expr[res.position] == closing_bracket) { StringExpression *ret = xcalloc(1, sizeof(StringExpression)); ret->op = VARREF; ret->val.varref.name = res.result; if (expr[start] == '$') { ret->val.varref.type = VAR_REF_TYPE_SCALAR; } else if (expr[start] == '@') { ret->val.varref.type = VAR_REF_TYPE_LIST; } else { ProgrammingError("Unrecognized var ref type"); } return (StringParseResult) {ret, res.position + 1}; } else { FreeStringExpression(res.result); return (StringParseResult) {NULL, res.position}; } } else { return res; } } else { return (StringParseResult) {NULL, start + 1}; } } else { return (StringParseResult) {NULL, start}; } } /* */ static inline bool ValidTokenCharacter(char c, bool *inside_index) { assert(inside_index != NULL); if (c >= 'a' && c <= 'z') { return true; } if (c >= 'A' && c <= 'Z') { return true; } if (c >= '0' && c <= '9') { return true; } if (c == '_' || c == ':') { return true; } if (c == '[') { *inside_index = true; return true; } if (c == ']') { if (*inside_index) { *inside_index = false; } return true; } if ((c == ' ') && *inside_index) { return true; } return false; } static StringParseResult ParseToken(const char *expr, int start, int end) { int endlit = start; bool inside_index = false; while (endlit < end && ValidTokenCharacter(expr[endlit], &inside_index)) { endlit++; } if (endlit > start) { StringExpression *ret = xcalloc(1, sizeof(StringExpression)); ret->op = LITERAL; ret->val.literal.literal = xstrndup(expr + start, endlit - start); return (StringParseResult) {ret, endlit}; } else { return (StringParseResult) {NULL, endlit}; } } /* */ static StringParseResult ParseTerm(const char *expr, int start, int end) { StringParseResult res = ParseToken(expr, start, end); if (res.result) { return res; } else { return ParseVarRef(expr, start, end); } } /* */ StringParseResult ParseStringExpression(const char *expr, int start, int end) { StringParseResult lhs = ParseTerm(expr, start, end); if (lhs.result) { StringParseResult rhs = ParseStringExpression(expr, lhs.position, end); if (rhs.result) { StringExpression *ret = xcalloc(1, sizeof(StringExpression)); ret->op = CONCAT; ret->val.concat.lhs = lhs.result; ret->val.concat.rhs = rhs.result; return (StringParseResult) {ret, rhs.position}; } else { return lhs; } } else { return lhs; } } /* Evaluation */ static char *EvalConcat(const StringExpression *expr, VarRefEvaluator evalfn, void *param) { char *lhs, *rhs, *res; lhs = EvalStringExpression(expr->val.concat.lhs, evalfn, param); if (!lhs) { return NULL; } rhs = EvalStringExpression(expr->val.concat.rhs, evalfn, param); if (!rhs) { free(lhs); return NULL; } xasprintf(&res, "%s%s", lhs, rhs); free(lhs); free(rhs); return res; } static char *EvalVarRef(const StringExpression *expr, VarRefEvaluator evalfn, void *param) { char *name, *eval; name = EvalStringExpression(expr->val.varref.name, evalfn, param); if (!name) { return NULL; } eval = (*evalfn) (name, expr->val.varref.type, param); free(name); return eval; } char *EvalStringExpression(const StringExpression *expr, VarRefEvaluator evalfn, void *param) { switch (expr->op) { case CONCAT: return EvalConcat(expr, evalfn, param); case LITERAL: return xstrdup(expr->val.literal.literal); case VARREF: return EvalVarRef(expr, evalfn, param); default: ProgrammingError("Unknown type of string expression" "encountered during evaluation: %d", expr->op); } } /* Freeing results */ void FreeStringExpression(StringExpression *expr) { if (!expr) { return; } switch (expr->op) { case CONCAT: FreeStringExpression(expr->val.concat.lhs); FreeStringExpression(expr->val.concat.rhs); break; case LITERAL: free(expr->val.literal.literal); break; case VARREF: FreeStringExpression(expr->val.varref.name); break; default: ProgrammingError("Unknown type of string expression encountered: %d", expr->op); } free(expr); } cfengine-3.24.2/libpromises/crypto.c0000644000000000000000000006652515010704253017405 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* ERR_* */ #include /* RAND_* */ #include /* BN_* */ #if OPENSSL_VERSION_NUMBER > 0x30000000 #include /* OSSL_PROVIDER_* */ #endif #include #include #include #include #include #include #include #include #include /* UnexpectedError,ProgrammingError */ #include #ifdef DARWIN // On Mac OSX 10.7 and later, majority of functions in /usr/include/openssl/crypto.h // are deprecated. No known replacement, so shutting up compiler warnings #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif #if OPENSSL_VERSION_NUMBER < 0x10100000 void CRYPTO_set_id_callback(unsigned long (*func)(void)); #endif static void RandomSeed(void); static void SetupOpenSSLThreadLocks(void); static void CleanupOpenSSLThreadLocks(void); /* TODO move crypto.[ch] to libutils. Will need to remove all manipulation of * lastseen db. */ static bool crypto_initialized = false; /* GLOBAL_X */ #if OPENSSL_VERSION_NUMBER > 0x30000000 static OSSL_PROVIDER *legacy_provider = NULL; static OSSL_PROVIDER *default_provider = NULL; #endif const char *CryptoLastErrorString() { const char *errmsg = ERR_reason_error_string(ERR_get_error()); return (errmsg != NULL) ? errmsg : "no error message"; } void CryptoInitialize() { if (!crypto_initialized) { SetupOpenSSLThreadLocks(); OpenSSL_add_all_algorithms(); OpenSSL_add_all_digests(); ERR_load_crypto_strings(); #if OPENSSL_VERSION_NUMBER > 0x30000000 /* We need Blowfish for legacy encrypted network stuff and in OpenSSL * 3+, it's only available when the legacy provider is loaded. And we * also need the default provider. */ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy"); default_provider = OSSL_PROVIDER_load(NULL, "default"); #endif RandomSeed(); crypto_initialized = true; } } void CryptoDeInitialize() { if (crypto_initialized) { char randfile[CF_BUFSIZE]; snprintf(randfile, CF_BUFSIZE, "%s%crandseed", GetWorkDir(), FILE_SEPARATOR); /* Only write out a seed if the file doesn't exist * and we have enough entropy to do so. If RAND_write_File * returns a bad value, delete the poor seed. */ if (access(randfile, R_OK) && errno == ENOENT && RAND_write_file(randfile) != 1024) { Log(LOG_LEVEL_WARNING, "Could not write randomness to '%s'", randfile); unlink(randfile); /* do not reuse entropy */ } chmod(randfile, 0600); EVP_cleanup(); CleanupOpenSSLThreadLocks(); ERR_free_strings(); #if OPENSSL_VERSION_NUMBER > 0x30000000 if (legacy_provider != NULL) { OSSL_PROVIDER_unload(legacy_provider); legacy_provider = NULL; } if (default_provider != NULL) { OSSL_PROVIDER_unload(default_provider); default_provider = NULL; } #endif crypto_initialized = false; } } static void RandomSeed(void) { /* 1. Seed the weak C PRNGs. */ /* Mix various stuff. */ pid_t pid = getpid(); size_t fqdn_len = strlen(VFQNAME) > 0 ? strlen(VFQNAME) : 1; time_t start_time = CFSTARTTIME; time_t now = time(NULL); srand((unsigned) pid * start_time ^ (unsigned) fqdn_len * now); srand48((long) pid * start_time ^ (long) fqdn_len * now); /* 2. Seed the strong OpenSSL PRNG. */ #ifndef __MINGW32__ RAND_poll(); /* windows may hang */ #else RAND_screen(); /* noop unless openssl is very old */ #endif if (RAND_status() != 1) { /* randseed file is written on deinitialization of crypto system */ char randfile[CF_BUFSIZE]; snprintf(randfile, CF_BUFSIZE, "%s%crandseed", GetWorkDir(), FILE_SEPARATOR); Log(LOG_LEVEL_VERBOSE, "Looking for a source of entropy in '%s'", randfile); if (RAND_load_file(randfile, -1) != 1024) { Log(LOG_LEVEL_CRIT, "Could not read randomness from '%s'", randfile); unlink(randfile); /* kill randseed if error reading it */ } /* If we've used the random seed, then delete */ unlink(randfile); } } /* PEM functions need the const cast away, but hopefully the default * call-back doesn't actually modify its user-data. */ static const char priv_passphrase[] = PRIVKEY_PASSPHRASE; /** * @param[in] priv_key_path path to the private key to use (%NULL to use the default) * @param[in] pub_key_path path to the private key to use (%NULL to use the default) * @param[out] priv_key a place to store the loaded private key (or %NULL to * use the global PRIVKEY variable) * @param[out] pub_key a place to store the loaded public key (or %NULL to * use the global PUBKEY variable) * @return true the error is not so severe that we must stop */ bool LoadSecretKeys(const char *const priv_key_path, const char *const pub_key_path, RSA **priv_key, RSA **pub_key) { { char *privkeyfile = NULL; if (priv_key_path == NULL) { privkeyfile = PrivateKeyFile(GetWorkDir()); } FILE *fp = safe_fopen(privkeyfile != NULL ? privkeyfile : priv_key_path, "r"); if (!fp) { /* VERBOSE in case it's a custom, local-only installation. */ Log(LOG_LEVEL_VERBOSE, "Couldn't find a private key at '%s', use cf-key to get one. (fopen: %s)", privkeyfile != NULL ? privkeyfile : priv_key_path, GetErrorStr()); free(privkeyfile); return false; } if (priv_key == NULL) { /* if no place to store the private key was specified, use the * global variable PRIVKEY */ priv_key = &PRIVKEY; } if (*priv_key != NULL) { DESTROY_AND_NULL(RSA_free, *priv_key); } // Can read both encrypted (old) and unencrypted(new) key files: *priv_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, (void*) priv_passphrase); if (*priv_key == NULL) { Log(LOG_LEVEL_ERR, "Error reading private key. (PEM_read_RSAPrivateKey: %s)", CryptoLastErrorString()); *priv_key = NULL; fclose(fp); return false; } fclose(fp); Log(LOG_LEVEL_VERBOSE, "Loaded private key at '%s'", privkeyfile); free(privkeyfile); } { char *pubkeyfile = NULL; if (pub_key_path == NULL) { pubkeyfile = PublicKeyFile(GetWorkDir()); } FILE *fp = safe_fopen(pubkeyfile != NULL ? pubkeyfile : pub_key_path, "r"); if (!fp) { /* VERBOSE in case it's a custom, local-only installation. */ Log(LOG_LEVEL_VERBOSE, "Couldn't find a public key at '%s', use cf-key to get one (fopen: %s)", pubkeyfile != NULL ? pubkeyfile : pub_key_path, GetErrorStr()); free(pubkeyfile); return false; } if (pub_key == NULL) { /* if no place to store the public key was specified, use the * global variable PUBKEY */ pub_key = &PUBKEY; } if (*pub_key != NULL) { DESTROY_AND_NULL(RSA_free, *pub_key); } *pub_key = PEM_read_RSAPublicKey(fp, NULL, NULL, (void*) priv_passphrase); if (*pub_key == NULL) { Log(LOG_LEVEL_ERR, "Error reading public key at '%s'. (PEM_read_RSAPublicKey: %s)", pubkeyfile, CryptoLastErrorString()); fclose(fp); free(pubkeyfile); return false; } Log(LOG_LEVEL_VERBOSE, "Loaded public key '%s'", pubkeyfile); free(pubkeyfile); fclose(fp); } if (*pub_key != NULL) { const BIGNUM *n, *e; RSA_get0_key(*pub_key, &n, &e, NULL); if ((BN_num_bits(e) < 2) || (!BN_is_odd(e))) { Log(LOG_LEVEL_ERR, "The public key RSA exponent is too small or not odd"); return false; } } return true; } void PolicyHubUpdateKeys(const char *policy_server) { if (GetAmPolicyHub() && PUBKEY != NULL) { unsigned char digest[EVP_MAX_MD_SIZE + 1]; const char* const workdir = GetWorkDir(); char dst_public_key_filename[CF_BUFSIZE] = ""; { char buffer[CF_HOSTKEY_STRING_SIZE]; HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST); snprintf(dst_public_key_filename, sizeof(dst_public_key_filename), "%s/ppkeys/%s-%s.pub", workdir, "root", HashPrintSafe(buffer, sizeof(buffer), digest, CF_DEFAULT_DIGEST, true)); MapName(dst_public_key_filename); } struct stat sb; if ((stat(dst_public_key_filename, &sb) == -1)) { char src_public_key_filename[CF_BUFSIZE] = ""; snprintf(src_public_key_filename, CF_MAXVARSIZE, "%s/ppkeys/localhost.pub", workdir); MapName(src_public_key_filename); // copy localhost.pub to root-HASH.pub on policy server if (!LinkOrCopy(src_public_key_filename, dst_public_key_filename, false)) { Log(LOG_LEVEL_ERR, "Unable to copy policy server's own public key from '%s' to '%s'", src_public_key_filename, dst_public_key_filename); } if (policy_server) { LastSaw(policy_server, digest, LAST_SEEN_ROLE_CONNECT); } } } } /*********************************************************************/ /** * @brief Search for a key given an IP address, by getting the * key hash value from lastseen db. * @return NULL if the key was not found in any form. */ RSA *HavePublicKeyByIP(const char *username, const char *ipaddress) { char hash[CF_HOSTKEY_STRING_SIZE]; /* Get the key hash for that address from lastseen db. */ bool found = Address2Hostkey(hash, sizeof(hash), ipaddress); /* If not found, by passing "" as digest, we effectively look only for * the old-style key file, e.g. root-1.2.3.4.pub. */ return HavePublicKey(username, ipaddress, found ? hash : ""); } static const char *const pub_passphrase = "public"; /** * @brief Search for a key: * 1. username-hash.pub * 2. username-ip.pub * @return NULL if key not found in any form */ RSA *HavePublicKey(const char *username, const char *ipaddress, const char *digest) { char keyname[CF_MAXVARSIZE], newname[CF_BUFSIZE], oldname[CF_BUFSIZE]; struct stat statbuf; RSA *newkey = NULL; const char* const workdir = GetWorkDir(); snprintf(keyname, CF_MAXVARSIZE, "%s-%s", username, digest); snprintf(newname, CF_BUFSIZE, "%s/ppkeys/%s.pub", workdir, keyname); MapName(newname); if (stat(newname, &statbuf) == -1) { Log(LOG_LEVEL_VERBOSE, "Did not find new key format '%s'", newname); snprintf(oldname, CF_BUFSIZE, "%s/ppkeys/%s-%s.pub", workdir, username, ipaddress); MapName(oldname); Log(LOG_LEVEL_VERBOSE, "Trying old style '%s'", oldname); if (stat(oldname, &statbuf) == -1) { Log(LOG_LEVEL_DEBUG, "Did not have old-style key '%s'", oldname); return NULL; } if (strlen(digest) > 0) { Log(LOG_LEVEL_INFO, "Renaming old key from '%s' to '%s'", oldname, newname); if (rename(oldname, newname) != 0) { Log(LOG_LEVEL_ERR, "Could not rename from old key format '%s' to new '%s'. (rename: %s)", oldname, newname, GetErrorStr()); } } else { /* We don't know the digest (e.g. because we are a client and have no lastseen-map yet), so we're using old file format (root-IP.pub). */ Log(LOG_LEVEL_VERBOSE, "We have no digest yet, using old keyfile name: %s", oldname); snprintf(newname, sizeof(newname), "%s", oldname); } } FILE *fp = safe_fopen(newname, "r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open public key file '%s' (fopen: %s)", newname, GetErrorStr()); return NULL; } if ((newkey = PEM_read_RSAPublicKey(fp, NULL, NULL, (void *)pub_passphrase)) == NULL) { Log(LOG_LEVEL_ERR, "Error reading public key from '%s' (PEM_read_RSAPublicKey: %s)", newname, CryptoLastErrorString()); fclose(fp); return NULL; } fclose(fp); { const BIGNUM *n, *e; RSA_get0_key(newkey, &n, &e, NULL); if ((BN_num_bits(e) < 2) || (!BN_is_odd(e))) { Log(LOG_LEVEL_ERR, "RSA Exponent too small or not odd for key: %s", newname); RSA_free(newkey); return NULL; } } return newkey; } /*********************************************************************/ bool SavePublicKey(const char *user, const char *digest, const RSA *key) { char keyname[CF_MAXVARSIZE], filename[CF_BUFSIZE]; struct stat statbuf; int ret; ret = snprintf(keyname, sizeof(keyname), "%s-%s", user, digest); if (ret < 0) { Log(LOG_LEVEL_ERR, "snprintf failed: %s", GetErrorStr()); return false; } else if ((unsigned long) ret >= sizeof(keyname)) { Log(LOG_LEVEL_ERR, "USERNAME-KEY (%s-%s) string too long!", user, digest); return false; } ret = snprintf(filename, sizeof(filename), "%s/ppkeys/%s.pub", GetWorkDir(), keyname); if (ret < 0) { Log(LOG_LEVEL_ERR, "snprintf failed: %s", GetErrorStr()); return false; } else if ((unsigned long) ret >= sizeof(filename)) { Log(LOG_LEVEL_ERR, "Filename too long!"); return false; } MapName(filename); if (stat(filename, &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "Public key file '%s' already exists, not rewriting", filename); return true; } Log(LOG_LEVEL_VERBOSE, "Saving public key to file '%s'", filename); FILE *fp = safe_fopen_create_perms(filename, "w", CF_PERMS_DEFAULT); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Unable to write a public key '%s'. (fopen: %s)", filename, GetErrorStr()); return false; } if (!PEM_write_RSAPublicKey(fp, key)) { Log(LOG_LEVEL_ERR, "Error saving public key to '%s'. (PEM_write_RSAPublicKey: %s)", filename, CryptoLastErrorString()); fclose(fp); return false; } fclose(fp); return true; } RSA *LoadPublicKey(const char *filename) { FILE *fp; RSA *key; const BIGNUM *n, *e; fp = safe_fopen(filename, "r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Cannot open public key file '%s' (fopen: %s)", filename, GetErrorStr()); return NULL; }; if ((key = PEM_read_RSAPublicKey(fp, NULL, NULL, (void *)priv_passphrase)) == NULL) { Log(LOG_LEVEL_ERR, "Error while reading public key '%s' (PEM_read_RSAPublicKey: %s)", filename, CryptoLastErrorString()); fclose(fp); return NULL; }; fclose(fp); RSA_get0_key(key, &n, &e, NULL); if (BN_num_bits(e) < 2 || !BN_is_odd(e)) { Log(LOG_LEVEL_ERR, "Error while reading public key '%s' - RSA Exponent is too small or not odd. (BN_num_bits: %s)", filename, GetErrorStr()); return NULL; }; return key; } /** Return a string with the printed digest of the given key file, or NULL if an error occurred. */ char *LoadPubkeyDigest(const char *filename) { unsigned char digest[EVP_MAX_MD_SIZE + 1]; RSA *key = NULL; char *buffer = xmalloc(CF_HOSTKEY_STRING_SIZE); key = LoadPublicKey(filename); if (key == NULL) { return NULL; } HashPubKey(key, digest, CF_DEFAULT_DIGEST); HashPrintSafe(buffer, CF_HOSTKEY_STRING_SIZE, digest, CF_DEFAULT_DIGEST, true); RSA_free(key); return buffer; } /** Return a string with the printed digest of the given key file. */ char *GetPubkeyDigest(RSA *pubkey) { unsigned char digest[EVP_MAX_MD_SIZE + 1]; char *buffer = xmalloc(CF_HOSTKEY_STRING_SIZE); HashPubKey(pubkey, digest, CF_DEFAULT_DIGEST); HashPrintSafe(buffer, CF_HOSTKEY_STRING_SIZE, digest, CF_DEFAULT_DIGEST, true); return buffer; } /** * Trust the given key. If #ipaddress is not NULL, then also * update the "last seen" database. The IP address is required for * trusting a server key (on the client); it is -currently- optional * for trusting a client key (on the server). */ bool TrustKey(const char *filename, const char *ipaddress, const char *username) { RSA* key; char *digest; key = LoadPublicKey(filename); if (key == NULL) { return false; } digest = GetPubkeyDigest(key); if (digest == NULL) { RSA_free(key); return false; } if (ipaddress != NULL) { Log(LOG_LEVEL_VERBOSE, "Adding a CONNECT entry in lastseen db: IP '%s', key '%s'", ipaddress, digest); LastSaw1(ipaddress, digest, LAST_SEEN_ROLE_CONNECT); } bool ret = SavePublicKey(username, digest, key); RSA_free(key); free(digest); return ret; } int EncryptString(char *out, size_t out_size, const char *in, int plainlen, char type, unsigned char *key) { int cipherlen = 0, tmplen; unsigned char iv[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; if (key == NULL) ProgrammingError("EncryptString: session key == NULL"); size_t max_ciphertext_size = CipherTextSizeMax(CfengineCipher(type), plainlen); if(max_ciphertext_size > out_size) { ProgrammingError("EncryptString: output buffer too small: max_ciphertext_size (%zd) > out_size (%zd)", max_ciphertext_size, out_size); } EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, CfengineCipher(type), NULL, key, iv); if (!EVP_EncryptUpdate(ctx, out, &cipherlen, in, plainlen)) { EVP_CIPHER_CTX_free(ctx); return -1; } if (!EVP_EncryptFinal_ex(ctx, out + cipherlen, &tmplen)) { EVP_CIPHER_CTX_free(ctx); return -1; } cipherlen += tmplen; if (cipherlen < 0) { ProgrammingError("EncryptString: chipherlen (%d) < 0", cipherlen); } else if ((size_t) cipherlen > max_ciphertext_size) { ProgrammingError("EncryptString: too large ciphertext written: cipherlen (%d) > max_ciphertext_size (%zd)", cipherlen, max_ciphertext_size); } EVP_CIPHER_CTX_free(ctx); return cipherlen; } size_t CipherBlockSizeBytes(const EVP_CIPHER *cipher) { return EVP_CIPHER_block_size(cipher); } size_t CipherTextSizeMax(const EVP_CIPHER* cipher, size_t plaintext_size) { // see man EVP_DecryptUpdate() and EVP_DecryptFinal_ex() size_t padding_size = (CipherBlockSizeBytes(cipher) * 2) - 1; // check for potential integer overflow, leave some buffer if(plaintext_size > SIZE_MAX - padding_size) { ProgrammingError("CipherTextSizeMax: plaintext_size is too large (%zu)", plaintext_size); } return plaintext_size + padding_size; } size_t PlainTextSizeMax(const EVP_CIPHER* cipher, size_t ciphertext_size) { // see man EVP_DecryptUpdate() and EVP_DecryptFinal_ex() size_t padding_size = (CipherBlockSizeBytes(cipher) * 2); // check for potential integer overflow, leave some buffer if(ciphertext_size > SIZE_MAX - padding_size) { ProgrammingError("PlainTextSizeMax: ciphertext_size is too large (%zu)", ciphertext_size); } return ciphertext_size + padding_size; } /*********************************************************************/ int DecryptString(char *out, size_t out_size, const char *in, int cipherlen, char type, unsigned char *key) { int plainlen = 0, tmplen; unsigned char iv[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; if (key == NULL) ProgrammingError("DecryptString: session key == NULL"); size_t max_plaintext_size = PlainTextSizeMax(CfengineCipher(type), cipherlen); if(max_plaintext_size > out_size) { ProgrammingError("DecryptString: output buffer too small: max_plaintext_size (%zd) > out_size (%zd)", max_plaintext_size, out_size); } EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, CfengineCipher(type), NULL, key, iv); if (!EVP_DecryptUpdate(ctx, out, &plainlen, in, cipherlen)) { Log(LOG_LEVEL_ERR, "Failed to decrypt string"); EVP_CIPHER_CTX_free(ctx); return -1; } if (!EVP_DecryptFinal_ex(ctx, out + plainlen, &tmplen)) { unsigned long err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Failed to decrypt at final of cipher length %d. (EVP_DecryptFinal_ex: %s)", cipherlen, ERR_error_string(err, NULL)); EVP_CIPHER_CTX_free(ctx); return -1; } plainlen += tmplen; if (plainlen < 0) { ProgrammingError("DecryptString: plainlen (%d) < 0", plainlen); } if ((size_t) plainlen > max_plaintext_size) { ProgrammingError("DecryptString: too large plaintext written: plainlen (%d) > max_plaintext_size (%zd)", plainlen, max_plaintext_size); } EVP_CIPHER_CTX_free(ctx); return plainlen; } /*********************************************************************/ void DebugBinOut(char *buffer, int len, char *comment) { unsigned char *sp; char buf[CF_BUFSIZE]; char hexStr[3]; // one byte as hex if (len < 0) { Log(LOG_LEVEL_ERR, "Debug binary print negative len param (len = %d)", len); } else if ((unsigned long) len >= (sizeof(buf) / 2)) // hex uses two chars per byte { Log(LOG_LEVEL_DEBUG, "Debug binary print is too large (len = %d)", len); return; } memset(buf, 0, sizeof(buf)); for (sp = buffer; sp < (unsigned char *) (buffer + len); sp++) { xsnprintf(hexStr, sizeof(hexStr), "%2.2x", (int) *sp); strcat(buf, hexStr); } Log(LOG_LEVEL_VERBOSE, "BinaryBuffer, %d bytes, comment '%s', buffer '%s'", len, comment, buf); } char *PublicKeyFile(const char *workdir) { char *keyfile; xasprintf(&keyfile, "%s" FILE_SEPARATOR_STR "ppkeys" FILE_SEPARATOR_STR "localhost.pub", workdir); return keyfile; } char *PrivateKeyFile(const char *workdir) { char *keyfile; xasprintf(&keyfile, "%s" FILE_SEPARATOR_STR "ppkeys" FILE_SEPARATOR_STR "localhost.priv", workdir); return keyfile; } /********************************************************************* * Functions for threadsafe OpenSSL usage * * Only pthread support - we don't create threads with any other API * *********************************************************************/ static pthread_mutex_t *cf_openssl_locks = NULL; #ifndef __MINGW32__ #if OPENSSL_VERSION_NUMBER < 0x10100000 unsigned long ThreadId_callback(void) { return (unsigned long) pthread_self(); } #endif #endif #if OPENSSL_VERSION_NUMBER < 0x10100000 static void OpenSSLLock_callback(int mode, int index, char *file, int line) { if (mode & CRYPTO_LOCK) { int ret = pthread_mutex_lock(&(cf_openssl_locks[index])); if (ret != 0) { Log(LOG_LEVEL_ERR, "OpenSSL locking failure at %s:%d! (pthread_mutex_lock: %s)", file, line, GetErrorStrFromCode(ret)); } } else { int ret = pthread_mutex_unlock(&(cf_openssl_locks[index])); if (ret != 0) { Log(LOG_LEVEL_ERR, "OpenSSL locking failure at %s:%d! (pthread_mutex_unlock: %s)", file, line, GetErrorStrFromCode(ret)); } } } #endif // Callback only for openssl < 1.1.0 static void SetupOpenSSLThreadLocks(void) { const int num_locks = CRYPTO_num_locks(); assert(cf_openssl_locks == NULL); cf_openssl_locks = xmalloc(num_locks * sizeof(*cf_openssl_locks)); for (int i = 0; i < num_locks; i++) { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to use error-checking mutexes for openssl," " falling back to normal ones (pthread_mutexattr_settype: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); } ret = pthread_mutex_init(&cf_openssl_locks[i], &attr); if (ret != 0) { Log(LOG_LEVEL_CRIT, "Failed to use initialise mutexes for openssl" " (pthread_mutex_init: %s)!", GetErrorStrFromCode(ret)); } pthread_mutexattr_destroy(&attr); } #ifndef __MINGW32__ #if OPENSSL_VERSION_NUMBER < 0x10100000 CRYPTO_set_id_callback((unsigned long (*)())ThreadId_callback); #endif #endif #if OPENSSL_VERSION_NUMBER < 0x10100000 CRYPTO_set_locking_callback((void (*)())OpenSSLLock_callback); #endif } static void CleanupOpenSSLThreadLocks(void) { const int numLocks = CRYPTO_num_locks(); CRYPTO_set_locking_callback(NULL); #ifndef __MINGW32__ #if OPENSSL_VERSION_NUMBER < 0x10100000 CRYPTO_set_id_callback(NULL); #endif #endif for (int i = 0; i < numLocks; i++) { pthread_mutex_destroy(&(cf_openssl_locks[i])); } free(cf_openssl_locks); cf_openssl_locks = NULL; } cfengine-3.24.2/libpromises/mod_storage.c0000644000000000000000000000714015010704253020354 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax volume_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewBool("check_foreign", "true/false verify storage that is mounted from a foreign system on this host. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("freespace", "[0-9]+[MBkKgGmb%]", "Absolute or percentage minimum disk space that should be available before warning", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("sensible_size", CF_VALRANGE, "Minimum size in bytes that should be used on a sensible-looking storage device", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("sensible_count", CF_VALRANGE, "Minimum number of files that should be defined on a sensible-looking storage device", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("scan_arrivals", "true/false generate pseudo-periodic disk change arrival distribution. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax volume_body = BodySyntaxNew("volume", volume_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax mount_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewBool("edit_fstab", "true/false add or remove entries to the file system table (\"fstab\"). Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("mount_type", "nfs,nfs2,nfs3,nfs4,panfs,cifs", "Protocol type of remote file system", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("mount_source", CF_ABSPATHRANGE, "Path of remote file system to mount", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("mount_server", "", "Hostname or IP or remote file system server", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("mount_options", "", "List of option strings to add to the file system table (\"fstab\")", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("unmount", "true/false unmount a previously mounted filesystem. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax mount_body = BodySyntaxNew("mount", mount_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax storage_constraints[] = { ConstraintSyntaxNewBody("mount", &mount_body, "Criteria for mounting foreign file systems", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("volume", &volume_body, "Criteria for monitoring/probing mounted volumes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_STORAGE_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "storage", storage_constraints, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/crypto.h0000644000000000000000000000533115010704253017376 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CRYPTO_H #define CFENGINE_CRYPTO_H #include #include #include // This passphrase was used to encrypt private keys. // We no longer encrypt new keys, but the passphrase is kept // for backwards compatibility - old encrypted keys will still work. #define PRIVKEY_PASSPHRASE "Cfengine passphrase" #define PRIVKEY_PASSPHRASE_LEN 19 void CryptoInitialize(void); void CryptoDeInitialize(void); const char *CryptoLastErrorString(void); void DebugBinOut(char *buffer, int len, char *com); bool LoadSecretKeys(const char *const priv_key_path, const char *const pub_key_path, RSA **priv_key, RSA **pub_key); void PolicyHubUpdateKeys(const char *policy_server); int EncryptString(char *out, size_t out_size, const char *in, int plainlen, char type, unsigned char *key); size_t CipherBlockSizeBytes(const EVP_CIPHER *cipher); size_t CipherTextSizeMax(const EVP_CIPHER* cipher, size_t plaintext_size); size_t PlainTextSizeMax(const EVP_CIPHER* cipher, size_t ciphertext_size); int DecryptString(char *out, size_t out_size, const char *in, int cipherlen, char type, unsigned char *key); RSA *HavePublicKey(const char *username, const char *ipaddress, const char *digest); RSA *HavePublicKeyByIP(const char *username, const char *ipaddress); bool SavePublicKey(const char *username, const char *digest, const RSA *key); RSA *LoadPublicKey(const char *filename); char *LoadPubkeyDigest(const char *pubkey); char *GetPubkeyDigest(RSA *pubkey); bool TrustKey(const char *pubkey, const char *ipaddress, const char *username); char *PublicKeyFile(const char *workdir); char *PrivateKeyFile(const char *workdir); LogLevel CryptoGetMissingKeyLogLevel(void); #endif cfengine-3.24.2/libpromises/feature.c0000644000000000000000000000226415010704253017506 0ustar00rootroot00000000000000#include #include #include #include #include static const char* features[] = { #ifdef HAVE_LIBYAML "yaml", #endif #ifdef HAVE_LIBXML2 "xml", #endif #ifdef HAVE_LIBCURL "curl", #endif "tls_1_0", /* we require versions of OpenSSL that support * at least TLS 1.0 */ #ifdef HAVE_TLS_1_1 "tls_1_1", #endif #ifdef HAVE_TLS_1_2 "tls_1_2", #endif #ifdef HAVE_TLS_1_3 "tls_1_3", #endif "def_json_preparse", "host_specific_data_load", "copyfrom_restrict_keys", NULL }; int KnownFeature(const char *feature) { // dumb algorithm, but still effective for a small number of features for(int i=0 ; features[i]!=NULL ; i++) { int r = strcmp(feature, features[i]); if(r==0) { return 1; } } return 0; } void CreateHardClassesFromFeatures(EvalContext *ctx, char *tags) { Buffer *buffer = BufferNew(); for(int i=0 ; features[i]!=NULL ; i++) { BufferPrintf(buffer, "feature_%s", features[i]); CreateHardClassesFromCanonification(ctx, BufferData(buffer), tags); } BufferDestroy(buffer); } cfengine-3.24.2/libpromises/loading.c0000644000000000000000000005067715010704253017503 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // TODO: remove #include /* IsCf3VarString */ #include /* FatalError */ static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringMap *policy_files_hashes, StringSet *parsed_files_checksums, StringSet *failed_files); /* * The difference between filename and input_input file is that the latter is the file specified by -f or * equivalently the file containing body common control. This will hopefully be squashed in later refactoring. */ Policy *Cf3ParseFile(const GenericAgentConfig *config, const char *input_path) { struct stat statbuf; if (stat(input_path, &statbuf) == -1) { if (config->ignore_missing_inputs) { return PolicyNew(); } Log(LOG_LEVEL_ERR, "Can't stat file '%s' for parsing. (stat: %s)", input_path, GetErrorStr()); DoCleanupAndExit(EXIT_FAILURE); } else if (S_ISDIR(statbuf.st_mode)) { if (config->ignore_missing_inputs) { return PolicyNew(); } Log(LOG_LEVEL_ERR, "Can't parse directory '%s'.", input_path); DoCleanupAndExit(EXIT_FAILURE); } #ifndef _WIN32 if (config->check_not_writable_by_others && (statbuf.st_mode & (S_IWGRP | S_IWOTH))) { Log(LOG_LEVEL_ERR, "File %s (owner %ju) is writable by others (security exception)", input_path, (uintmax_t)statbuf.st_uid); DoCleanupAndExit(EXIT_FAILURE); } #endif Log(LOG_LEVEL_VERBOSE, "BEGIN parsing file: %s", input_path); if (!FileCanOpen(input_path, "r")) { Log(LOG_LEVEL_ERR, "Can't open file '%s' for parsing", input_path); DoCleanupAndExit(EXIT_FAILURE); } Policy *policy = NULL; if (StringEndsWith(input_path, ".json")) { Writer *contents = FileRead(input_path, SIZE_MAX, NULL); if (!contents) { Log(LOG_LEVEL_ERR, "Error reading JSON input file '%s'", input_path); return NULL; } JsonElement *json_policy = NULL; const char *data = StringWriterData(contents); if (JsonParse(&data, &json_policy) != JSON_PARSE_OK) { Log(LOG_LEVEL_ERR, "Error parsing JSON input file '%s'", input_path); WriterClose(contents); return NULL; } policy = PolicyFromJson(json_policy); if (policy == NULL) { Log(LOG_LEVEL_ERR, "Failed to deserialize a policy from the JSON input file '%s'", input_path); JsonDestroy(json_policy); WriterClose(contents); return NULL; } JsonDestroy(json_policy); WriterClose(contents); } else { if (config->agent_type == AGENT_TYPE_COMMON) { policy = ParserParseFile(config->agent_type, input_path, config->agent_specific.common.parser_warnings, config->agent_specific.common.parser_warnings_error); } else { policy = ParserParseFile(config->agent_type, input_path, 0, 0); } } Log(LOG_LEVEL_VERBOSE, "END parsing file: %s", input_path); return policy; } static Policy *LoadPolicyInputFiles(EvalContext *ctx, GenericAgentConfig *config, const Rlist *inputs, StringMap *policy_files_hashes, StringSet *parsed_files_checksums, StringSet *failed_files) { Policy *policy = PolicyNew(); for (const Rlist *rp = inputs; rp; rp = rp->next) { if (rp->val.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Non-file object in inputs list"); continue; } const char *unresolved_input = RlistScalarValue(rp); if (IsExpandable(unresolved_input)) { PolicyResolve(ctx, policy, config); } Rval resolved_input = EvaluateFinalRval(ctx, policy, NULL, "sys", rp->val, true, NULL); Policy *aux_policy = NULL; switch (resolved_input.type) { case RVAL_TYPE_SCALAR: if (IsCf3VarString(RvalScalarValue(resolved_input))) { Log(LOG_LEVEL_ERR, "Unresolved variable '%s' in input list, cannot parse", RvalScalarValue(resolved_input)); break; } aux_policy = LoadPolicyFile(ctx, config, GenericAgentResolveInputPath(config, RvalScalarValue(resolved_input)), policy_files_hashes, parsed_files_checksums, failed_files); break; case RVAL_TYPE_LIST: aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(resolved_input), policy_files_hashes, parsed_files_checksums, failed_files); break; default: ProgrammingError("Unknown type in input list for parsing: %d", resolved_input.type); break; } if (aux_policy) { policy = PolicyMerge(policy, aux_policy); } RvalDestroy(resolved_input); } return policy; } // TODO: should be replaced by something not complected with loading static void ShowContext(EvalContext *ctx) { Seq *hard_contexts = SeqNew(1000, NULL); Seq *soft_contexts = SeqNew(1000, NULL); { ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls = NULL; while ((cls = ClassTableIteratorNext(iter))) { if (cls->is_soft) { SeqAppend(soft_contexts, cls->name); } else { SeqAppend(hard_contexts, cls->name); } } ClassTableIteratorDestroy(iter); } SeqSort(soft_contexts, StrCmpWrapper, NULL); SeqSort(hard_contexts, StrCmpWrapper, NULL); Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); { Log(LOG_LEVEL_VERBOSE, "BEGIN Discovered hard classes:"); for (size_t i = 0; i < SeqLength(hard_contexts); i++) { const char *context = SeqAt(hard_contexts, i); Log(LOG_LEVEL_VERBOSE, "C: discovered hard class %s", context); } Log(LOG_LEVEL_VERBOSE, "END Discovered hard classes"); } Log(LOG_LEVEL_VERBOSE, "----------------------------------------------------------------"); if (SeqLength(soft_contexts)) { Log(LOG_LEVEL_VERBOSE, "BEGIN initial soft classes:"); for (size_t i = 0; i < SeqLength(soft_contexts); i++) { const char *context = SeqAt(soft_contexts, i); Log(LOG_LEVEL_VERBOSE, "C: added soft class %s", context); } Log(LOG_LEVEL_VERBOSE, "END initial soft classes"); } SeqDestroy(hard_contexts); SeqDestroy(soft_contexts); } static void RenameMainBundle(EvalContext *ctx, Policy *policy) { assert(policy != NULL); assert(ctx != NULL); assert(policy->bundles != NULL); char *const entry_point = GetRealPath(EvalContextGetEntryPoint(ctx)); if (NULL_OR_EMPTY(entry_point)) { free(entry_point); return; } Seq *bundles = policy->bundles; int length = SeqLength(bundles); bool removed = false; for (int i = 0; i < length; ++i) { Bundle *const bundle = SeqAt(bundles, i); if (StringEqual(bundle->name, "__main__")) { char *abspath = GetRealPath(bundle->source_path); if (StringEqual(abspath, entry_point)) { Log(LOG_LEVEL_VERBOSE, "Redefining __main__ bundle from file %s to be main", abspath); strncpy(bundle->name, "main", 4+1); // "__main__" is always big enough for "main" } else { Log(LOG_LEVEL_VERBOSE, "Dropping __main__ bundle from file %s (entry point: %s)", abspath, entry_point); removed = true; SeqSet(bundles, i, NULL); // SeqSet calls destroy function } free(abspath); } } if (removed) { SeqRemoveNulls(bundles); } free(entry_point); } static Policy *LoadPolicyFile(EvalContext *ctx, GenericAgentConfig *config, const char *policy_file, StringMap *policy_files_hashes, StringSet *parsed_files_checksums, StringSet *failed_files) { unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 }; char hashbuffer[CF_HOSTKEY_STRING_SIZE] = { 0 }; HashFile(policy_file, digest, CF_DEFAULT_DIGEST, false); HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest, CF_DEFAULT_DIGEST, true); Log(LOG_LEVEL_DEBUG, "Hashed policy file %s to %s", policy_file, hashbuffer); if (StringMapHasKey(policy_files_hashes, policy_file)) { Log(LOG_LEVEL_DEBUG, "Skipping loading of duplicate policy file %s", policy_file); return NULL; } else if (StringSetContains(parsed_files_checksums, hashbuffer)) { Log(LOG_LEVEL_DEBUG, "Skipping loading of duplicate (detected by hash) policy file %s", policy_file); return NULL; } else { Log(LOG_LEVEL_DEBUG, "Loading policy file %s", policy_file); } Policy *policy = Cf3ParseFile(config, policy_file); StringMapInsert(policy_files_hashes, xstrdup(policy_file), xstrdup(hashbuffer)); StringSetAdd(parsed_files_checksums, xstrdup(hashbuffer)); if (policy) { RenameMainBundle(ctx, policy); Seq *errors = SeqNew(10, free); if (!PolicyCheckPartial(policy, errors)) { Writer *writer = FileWriter(stderr); for (size_t i = 0; i < errors->length; i++) { PolicyErrorWrite(writer, errors->data[i]); } WriterClose(writer); SeqDestroy(errors); StringSetAdd(failed_files, xstrdup(policy_file)); PolicyDestroy(policy); return NULL; } SeqDestroy(errors); } else { StringSetAdd(failed_files, xstrdup(policy_file)); return NULL; } PolicyResolve(ctx, policy, config); Body *body_common_control = PolicyGetBody(policy, NULL, "common", "control"); Body *body_file_control = PolicyGetBody(policy, NULL, "file", "control"); if (body_common_control) { Seq *potential_inputs = BodyGetConstraint(body_common_control, "inputs"); Constraint *cp = EffectiveConstraint(ctx, potential_inputs); SeqDestroy(potential_inputs); if (cp) { Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), policy_files_hashes, parsed_files_checksums, failed_files); if (aux_policy) { policy = PolicyMerge(policy, aux_policy); } } } if (body_file_control) { Seq *potential_inputs = BodyGetConstraint(body_file_control, "inputs"); Constraint *cp = EffectiveConstraint(ctx, potential_inputs); SeqDestroy(potential_inputs); if (cp) { Policy *aux_policy = LoadPolicyInputFiles(ctx, config, RvalRlistValue(cp->rval), policy_files_hashes, parsed_files_checksums, failed_files); if (aux_policy) { policy = PolicyMerge(policy, aux_policy); } } } return policy; } static bool VerifyBundleSequence(EvalContext *ctx, const Policy *policy, const GenericAgentConfig *config) { Rlist *fallback = NULL; const Rlist *bundlesequence = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_BUNDLESEQUENCE); if (!bundlesequence) { RlistAppendScalar(&fallback, "main"); bundlesequence = fallback; } const char *name; bool ok = true; for (const Rlist *rp = bundlesequence; rp != NULL; rp = rp->next) { switch (rp->val.type) { case RVAL_TYPE_SCALAR: name = RlistScalarValue(rp); break; case RVAL_TYPE_FNCALL: name = RlistFnCallValue(rp)->name; break; default: name = NULL; ok = false; { Writer *w = StringWriter(); WriterWrite(w, "Illegal item found in bundlesequence '"); RvalWrite(w, rp->val); WriterWrite(w, "'"); Log(LOG_LEVEL_ERR, "%s", StringWriterData(w)); WriterClose(w); } continue; } if (!config->ignore_missing_bundles && !PolicyGetBundle(policy, NULL, NULL, name)) { Log(LOG_LEVEL_ERR, "Bundle '%s' listed in the bundlesequence is not a defined bundle", name); ok = false; } } RlistDestroy(fallback); return ok; } /** * @brief Reads the release_id file from inputs and return a JsonElement. */ static JsonElement *ReadReleaseIdFileFromInputs() { char filename[CF_MAXVARSIZE]; GetReleaseIdFile(GetInputDir(), filename, sizeof(filename)); struct stat sb; if (stat(filename, &sb) == -1) { return NULL; } JsonElement *validated_doc = NULL; JsonParseError err = JsonParseFile(filename, 4096, &validated_doc); if (err != JSON_PARSE_OK) { Log(LOG_LEVEL_WARNING, "Could not read release ID: '%s' did not contain valid JSON data. " "(JsonParseFile: '%s')", filename, JsonParseErrorToString(err)); } return validated_doc; } Policy *LoadPolicy(EvalContext *ctx, GenericAgentConfig *config) { StringMap *policy_files_hashes = StringMapNew(); StringSet *parsed_files_checksums = StringSetNew(); StringSet *failed_files = StringSetNew(); Banner("Loading policy"); Policy *policy = LoadPolicyFile(ctx, config, config->input_file, policy_files_hashes, parsed_files_checksums, failed_files); if (StringSetSize(failed_files) > 0) { Log(LOG_LEVEL_ERR, "There are syntax errors in policy files"); DoCleanupAndExit(EXIT_FAILURE); } StringSetDestroy(parsed_files_checksums); StringSetDestroy(failed_files); if (policy != NULL) { policy->policy_files_hashes = policy_files_hashes; } else { StringMapDestroy(policy_files_hashes); } { Seq *errors = SeqNew(100, PolicyErrorDestroy); if (PolicyCheckPartial(policy, errors)) { if (!config->bundlesequence && (PolicyIsRunnable(policy) || config->check_runnable)) { Log(LOG_LEVEL_VERBOSE, "Running full policy integrity checks"); PolicyCheckRunnable(ctx, policy, errors); } } if (SeqLength(errors) > 0) { Writer *writer = FileWriter(stderr); for (size_t i = 0; i < errors->length; i++) { PolicyErrorWrite(writer, errors->data[i]); } WriterClose(writer); SeqDestroy(errors); DoCleanupAndExit(EXIT_FAILURE); // TODO: do not exit } SeqDestroy(errors); } if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { Legend(); ShowContext(ctx); } if (config->agent_type == AGENT_TYPE_AGENT) { Banner("Preliminary variable/class-context convergence"); } if (policy) { /* store names of all bundles in the EvalContext */ for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); EvalContextPushBundleName(ctx, bp->name); } for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (size_t j = 0; j < SeqLength(bp->sections); j++) { BundleSection *sp = SeqAt(bp->sections, j); EvalContextStackPushBundleSectionFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); /* Skip constraint syntax verification through all * slist/container iterations for cf-promises! cf-agent * still checks though. */ if (config->agent_type != AGENT_TYPE_COMMON) { ExpandPromise(ctx, pp, CommonEvalPromise, NULL); } } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); } PolicyResolve(ctx, policy, config); // TODO: need to move this inside PolicyCheckRunnable eventually. if (!config->bundlesequence && config->check_runnable) { // only verify policy-defined bundlesequence for cf-agent, cf-promises if ((config->agent_type == AGENT_TYPE_AGENT) || (config->agent_type == AGENT_TYPE_COMMON)) { if (!VerifyBundleSequence(ctx, policy, config)) { FatalError(ctx, "Errors in promise bundles: could not verify bundlesequence"); } } } } if (config->agent_type == AGENT_TYPE_AGENT && config->agent_specific.agent.bootstrap_argument != NULL) { /* Doing bootstrap, set the release_id to "bootstrap" and also write it * into a file so that sub-agent executed as part of bootstrap can just * pick it up and then rewrite it with the actual value from * masterfiles. */ policy->release_id = xstrdup("bootstrap"); char filename[PATH_MAX]; GetReleaseIdFile(GetInputDir(), filename, sizeof(filename)); FILE *release_id_stream = safe_fopen_create_perms(filename, "w", CF_PERMS_DEFAULT); if (release_id_stream == NULL) { Log(LOG_LEVEL_ERR, "Failed to open the release_id file for writing during bootstrap"); } else { Writer *release_id_writer = FileWriter(release_id_stream); WriterWrite(release_id_writer, "{ releaseId: \"bootstrap\" }\n"); WriterClose(release_id_writer); } } else { JsonElement *validated_doc = ReadReleaseIdFileFromInputs(); if (validated_doc) { const char *release_id = JsonObjectGetAsString(validated_doc, "releaseId"); if (release_id) { policy->release_id = xstrdup(release_id); } JsonDestroy(validated_doc); } } return policy; } cfengine-3.24.2/libpromises/cmdb.c0000644000000000000000000004637115010704253016767 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include /* StringSet */ #include #include /* GetDataDir() */ #include /* VarRef, StringContainsUnresolved() */ #include /* EvalContext*() */ #include /* JoinPaths() */ #include #define HOST_SPECIFIC_DATA_FILE "host_specific.json" #define HOST_SPECIFIC_DATA_MAX_SIZE (5 * 1024 * 1024) /* maximum size of the host-specific.json file */ #define CMDB_NAMESPACE "data" #define CMDB_VARIABLES_TAGS "tags" #define CMDB_VARIABLES_DATA "value" #define CMDB_CLASSES_TAGS "tags" #define CMDB_CLASSES_CLASS_EXPRESSIONS "class_expressions" #define CMDB_CLASSES_REGULAR_EXPRESSIONS "regular_expressions" #define CMDB_COMMENT_KEY "comment" JsonElement *ReadJsonFile(const char *filename, LogLevel log_level, size_t size_max) { assert(filename != NULL); JsonElement *doc = NULL; JsonParseError err = JsonParseFile(filename, size_max, &doc); if (err == JSON_PARSE_ERROR_NO_SUCH_FILE) { Log(log_level, "Could not open JSON file %s", filename); return NULL; } if (err != JSON_PARSE_OK || doc == NULL) { Log(log_level, "Could not parse JSON file %s: %s", filename, JsonParseErrorToString(err)); } return doc; } static bool CheckPrimitiveForUnexpandedVars(JsonElement *primitive, ARG_UNUSED void *data) { assert(JsonGetElementType(primitive) == JSON_ELEMENT_TYPE_PRIMITIVE); /* Stop the iteration if a variable expression is found. */ return (!StringContainsUnresolved(JsonPrimitiveGetAsString(primitive))); } static bool CheckObjectForUnexpandedVars(JsonElement *object, ARG_UNUSED void *data) { assert(JsonGetType(object) == JSON_TYPE_OBJECT); /* Stop the iteration if a variable expression is found among children * keys. (elements inside the object are checked separately) */ JsonIterator iter = JsonIteratorInit(object); while (JsonIteratorHasMore(&iter)) { const char *key = JsonIteratorNextKey(&iter); if (StringContainsUnresolved(key)) { return false; } } return true; } static VarRef *GetCMDBVariableRef(const char *key) { VarRef *ref = VarRefParse(key); if (ref->ns == NULL) { ref->ns = xstrdup(CMDB_NAMESPACE); } else { if (ref->scope == NULL) { Log(LOG_LEVEL_ERR, "Invalid variable specification in CMDB data: '%s'" " (bundle name has to be specified if namespace is specified)", key); VarRefDestroy(ref); return NULL; } } if (ref->scope == NULL) { ref->scope = xstrdup("variables"); } return ref; } static bool AddCMDBVariable(EvalContext *ctx, const char *key, const VarRef *ref, JsonElement *data, StringSet *tags, const char *comment) { assert(ctx != NULL); assert(key != NULL); assert(ref != NULL); assert(data != NULL); assert(tags != NULL); bool ret; if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_PRIMITIVE) { char *value = JsonPrimitiveToString(data); Log(LOG_LEVEL_VERBOSE, "Installing CMDB variable '%s:%s.%s=%s'", ref->ns, ref->scope, key, value); ret = EvalContextVariablePutTagsSetWithComment(ctx, ref, value, CF_DATA_TYPE_STRING, tags, comment); free(value); } else if ((JsonGetType(data) == JSON_TYPE_ARRAY) && JsonArrayContainsOnlyPrimitives(data)) { // map to slist if the data only has primitives Log(LOG_LEVEL_VERBOSE, "Installing CMDB slist variable '%s:%s.%s'", ref->ns, ref->scope, key); Rlist *data_rlist = RlistFromContainer(data); ret = EvalContextVariablePutTagsSetWithComment(ctx, ref, data_rlist, CF_DATA_TYPE_STRING_LIST, tags, comment); RlistDestroy(data_rlist); } else { // install as a data container Log(LOG_LEVEL_VERBOSE, "Installing CMDB data container variable '%s:%s.%s'", ref->ns, ref->scope, key); ret = EvalContextVariablePutTagsSetWithComment(ctx, ref, data, CF_DATA_TYPE_CONTAINER, tags, comment); } if (!ret) { /* On success, EvalContextVariablePutTagsSet() consumes the tags set, * otherwise, we shall destroy it. */ StringSetDestroy(tags); } return ret; } static bool ReadCMDBVars(EvalContext *ctx, JsonElement *vars) { assert(vars != NULL); if (JsonGetType(vars) != JSON_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid 'vars' CMDB data, must be a JSON object"); return false; } if (!JsonWalk(vars, CheckObjectForUnexpandedVars, NULL, CheckPrimitiveForUnexpandedVars, NULL)) { Log(LOG_LEVEL_ERR, "Invalid 'vars' CMDB data, cannot contain variable references"); return false; } JsonIterator iter = JsonIteratorInit(vars); while (JsonIteratorHasMore(&iter)) { const char *key = JsonIteratorNextKey(&iter); JsonElement *data = JsonObjectGet(vars, key); VarRef *ref = GetCMDBVariableRef(key); if (ref == NULL) { continue; } StringSet *tags = StringSetNew(); StringSetAdd(tags, xstrdup(CMDB_SOURCE_TAG)); bool ret = AddCMDBVariable(ctx, key, ref, data, tags, NULL); VarRefDestroy(ref); if (!ret) { /* Details should have been logged already. */ Log(LOG_LEVEL_ERR, "Failed to add CMDB variable '%s'", key); } } return true; } static StringSet *GetTagsFromJsonTags(const char *item_type, const char *key, const JsonElement *json_tags, const char *default_tag) { StringSet *tags = NULL; if (JSON_NOT_NULL(json_tags)) { if ((JsonGetType(json_tags) != JSON_TYPE_ARRAY) || (!JsonArrayContainsOnlyPrimitives((JsonElement*) json_tags))) { Log(LOG_LEVEL_ERR, "Invalid json_tags information for %s '%s' in CMDB data:" " must be a JSON array of strings", item_type, key); } else { tags = JsonArrayToStringSet(json_tags); if (tags == NULL) { Log(LOG_LEVEL_ERR, "Invalid json_tags information %s '%s' in CMDB data:" " must be a JSON array of strings", item_type, key); } } } if (tags == NULL) { tags = StringSetNew(); } StringSetAdd(tags, xstrdup(default_tag)); return tags; } static inline const char *GetCMDBComment(const char *item_type, const char *identifier, const JsonElement *json_object) { assert(JsonGetType(json_object) == JSON_TYPE_OBJECT); JsonElement *json_comment = JsonObjectGet(json_object, CMDB_COMMENT_KEY); if (NULL_JSON(json_comment)) { return NULL; } if (JsonGetType(json_comment) != JSON_TYPE_STRING) { Log(LOG_LEVEL_ERR, "Invalid type of the 'comment' field for the '%s' %s in CMDB data, must be a string", identifier, item_type); return NULL; } return JsonPrimitiveGetAsString(json_comment); } /** Uses the new format allowing metadata (CFE-3633) */ static bool ReadCMDBVariables(EvalContext *ctx, JsonElement *variables) { assert(variables != NULL); if (JsonGetType(variables) != JSON_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid 'variables' CMDB data, must be a JSON object"); return false; } if (!JsonWalk(variables, CheckObjectForUnexpandedVars, NULL, CheckPrimitiveForUnexpandedVars, NULL)) { Log(LOG_LEVEL_ERR, "Invalid 'variables' CMDB data, cannot contain variable references"); return false; } JsonIterator iter = JsonIteratorInit(variables); while (JsonIteratorHasMore(&iter)) { const char *key = JsonIteratorNextKey(&iter); VarRef *ref = GetCMDBVariableRef(key); if (ref == NULL) { continue; } JsonElement *const var_info = JsonObjectGet(variables, key); JsonElement *data; StringSet *tags; const char *comment = NULL; if (JsonGetType(var_info) == JSON_TYPE_OBJECT) { data = JsonObjectGet(var_info, CMDB_VARIABLES_DATA); if (data == NULL) { Log(LOG_LEVEL_ERR, "Missing value in '%s' variable specification in CMDB data (value field is required)", key); VarRefDestroy(ref); continue; } JsonElement *json_tags = JsonObjectGet(var_info, CMDB_VARIABLES_TAGS); tags = GetTagsFromJsonTags("variable", key, json_tags, CMDB_SOURCE_TAG); comment = GetCMDBComment("variable", key, var_info); } else { // Just a bare value, like in "vars", no metadata data = var_info; tags = GetTagsFromJsonTags("variable", key, NULL, CMDB_SOURCE_TAG); } assert(tags != NULL); assert(data != NULL); bool ret = AddCMDBVariable(ctx, key, ref, data, tags, comment); VarRefDestroy(ref); if (!ret) { /* Details should have been logged already. */ Log(LOG_LEVEL_ERR, "Failed to add CMDB variable '%s'", key); } } return true; } static bool AddCMDBClass(EvalContext *ctx, const char *key, StringSet *tags, const char *comment) { assert(ctx != NULL); assert(key != NULL); assert(tags != NULL); bool ret; Log(LOG_LEVEL_VERBOSE, "Installing CMDB class '%s'", key); if (strchr(key, ':') != NULL) { char *ns_class_name = xstrdup(key); char *sep = strchr(ns_class_name, ':'); *sep = '\0'; key = sep + 1; ret = EvalContextClassPutSoftNSTagsSetWithComment(ctx, ns_class_name, key, CONTEXT_SCOPE_NAMESPACE, tags, comment); free(ns_class_name); } else { ret = EvalContextClassPutSoftNSTagsSetWithComment(ctx, CMDB_NAMESPACE, key, CONTEXT_SCOPE_NAMESPACE, tags, comment); } if (!ret) { /* On success, EvalContextClassPutSoftNSTagsSetWithComment() consumes * the tags set, otherwise, we shall destroy it. */ StringSetDestroy(tags); } return ret; } static bool ReadCMDBClasses(EvalContext *ctx, JsonElement *classes) { assert(classes != NULL); if (JsonGetType(classes) != JSON_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid 'classes' CMDB data, must be a JSON object"); return false; } if (!JsonWalk(classes, CheckObjectForUnexpandedVars, NULL, CheckPrimitiveForUnexpandedVars, NULL)) { Log(LOG_LEVEL_ERR, "Invalid 'classes' CMDB data, cannot contain variable references"); return false; } JsonIterator iter = JsonIteratorInit(classes); while (JsonIteratorHasMore(&iter)) { const char *key = JsonIteratorNextKey(&iter); JsonElement *data = JsonObjectGet(classes, key); if (JsonGetElementType(data) == JSON_ELEMENT_TYPE_PRIMITIVE) { const char *expr = JsonPrimitiveGetAsString(data); if (!StringEqual(expr, "any::")) { Log(LOG_LEVEL_ERR, "Invalid class specification '%s' in CMDB data, only \"any::\" allowed", expr); continue; } StringSet *default_tags = StringSetNew(); StringSetAdd(default_tags, xstrdup(CMDB_SOURCE_TAG)); bool ret = AddCMDBClass(ctx, key, default_tags, NULL); if (!ret) { /* It does not have to be and error, it could be a result of * the class already existing. Anyways, details about * potential errors should have been logged already. */ Log(LOG_LEVEL_DEBUG, "Did not add CMDB class '%s'", key); } } else if (JsonGetContainerType(data) == JSON_CONTAINER_TYPE_ARRAY && JsonArrayContainsOnlyPrimitives(data)) { switch (JsonLength(data)) { case 0: Log(LOG_LEVEL_ERR, "Empty class specification '[]' in CMDB data not allowed, only '[\"any::\"]'"); continue;; case 1: if (!StringEqual(JsonPrimitiveGetAsString(JsonArrayGet(data, 0)), "any::")) { Log(LOG_LEVEL_ERR, "Invalid class specification '[\"%s\"]' in CMDB data, only '[\"any::\"]' allowed", JsonPrimitiveGetAsString(JsonArrayGet(data, 0))); continue; } // All good :) break; default: { Writer *const str = StringWriter(); JsonWriteCompact(str, data); Log(LOG_LEVEL_ERR, "Too many elements in class specification '%s' in CMDB data, only '[\"any::\"]' allowed", StringWriterData(str)); WriterClose(str); } continue; } StringSet *default_tags = StringSetNew(); StringSetAdd(default_tags, xstrdup(CMDB_SOURCE_TAG)); bool ret = AddCMDBClass(ctx, key, default_tags, NULL); if (!ret) { /* It does not have to be and error, it could be a result of * the class already existing. Anyways, details about * potential errors should have been logged already. */ Log(LOG_LEVEL_DEBUG, "Did not add CMDB class '%s'", key); } } else if (JsonGetContainerType(data) == JSON_CONTAINER_TYPE_OBJECT) { const JsonElement *class_exprs = JsonObjectGet(data, CMDB_CLASSES_CLASS_EXPRESSIONS); const JsonElement *reg_exprs = JsonObjectGet(data, CMDB_CLASSES_REGULAR_EXPRESSIONS); const JsonElement *json_tags = JsonObjectGet(data, CMDB_CLASSES_TAGS); if (JSON_NOT_NULL(class_exprs) && (JsonGetType(class_exprs) != JSON_TYPE_ARRAY || JsonLength(class_exprs) > 1 || (JsonLength(class_exprs) == 1 && !StringEqual(JsonPrimitiveGetAsString(JsonArrayGet(class_exprs, 0)), "any::")))) { Log(LOG_LEVEL_ERR, "Invalid class expression rules for class '%s' in CMDB data," " only '[]' or '[\"any::\"]' allowed", key); continue; } if (JSON_NOT_NULL(reg_exprs) && (JsonGetType(reg_exprs) != JSON_TYPE_ARRAY || JsonLength(reg_exprs) > 1 || (JsonLength(reg_exprs) == 1 && !StringEqual(JsonPrimitiveGetAsString(JsonArrayGet(reg_exprs, 0)), "any")))) { Log(LOG_LEVEL_ERR, "Invalid regular expression rules for class '%s' in CMDB data," " only '[]' or '[\"any\"]' allowed", key); continue; } StringSet *tags = GetTagsFromJsonTags("class", key, json_tags, CMDB_SOURCE_TAG); const char *comment = GetCMDBComment("class", key, data); bool ret = AddCMDBClass(ctx, key, tags, comment); if (!ret) { /* It does not have to be and error, it could be a result of * the class already existing. Anyways, details about * potential errors should have been logged already. */ Log(LOG_LEVEL_DEBUG, "Did not add CMDB class '%s'", key); } } else { Log(LOG_LEVEL_ERR, "Invalid CMDB class data for class '%s'", key); } } return true; } bool LoadCMDBData(EvalContext *ctx) { char file_path[PATH_MAX] = {0}; strncpy(file_path, GetDataDir(), sizeof(file_path) - 1); JoinPaths(file_path, sizeof(file_path), HOST_SPECIFIC_DATA_FILE); if (access(file_path, F_OK) != 0) { Log(LOG_LEVEL_VERBOSE, "No host-specific JSON data available at '%s'", file_path); return true; /* not an error */ } if (access(file_path, R_OK) != 0) { Log(LOG_LEVEL_ERR, "Cannot read host-spefic JSON data from '%s'", file_path); return false; } JsonElement *data = ReadJsonFile(file_path, LOG_LEVEL_ERR, HOST_SPECIFIC_DATA_MAX_SIZE); if (data == NULL) { /* Details are logged by ReadJsonFile() */ return false; } if (JsonGetType(data) != JSON_TYPE_OBJECT) { Log(LOG_LEVEL_ERR, "Invalid CMDB contents in '%s', must be a JSON object", file_path); JsonDestroy(data); return false; } Log(LOG_LEVEL_VERBOSE, "Loaded CMDB data file '%s', installing contents", file_path); JsonIterator iter = JsonIteratorInit(data); while (JsonIteratorHasMore(&iter)) { const char *key = JsonIteratorNextKey(&iter); /* Only vars and classes allowed in CMDB data */ if (!IsStrIn(key, (const char*[4]){"vars", "classes", "variables", NULL})) { Log(LOG_LEVEL_WARNING, "Invalid key '%s' in the CMDB data file '%s', skipping it", key, file_path); } } bool success = true; JsonElement *vars = JsonObjectGet(data, "vars"); if (JSON_NOT_NULL(vars) && !ReadCMDBVars(ctx, vars)) { success = false; } /* Uses the new format allowing metadata (CFE-3633) */ JsonElement *variables = JsonObjectGet(data, "variables"); if (JSON_NOT_NULL(variables) && !ReadCMDBVariables(ctx, variables)) { success = false; } JsonElement *classes = JsonObjectGet(data, "classes"); if (JSON_NOT_NULL(classes) && !ReadCMDBClasses(ctx, classes)) { success = false; } JsonDestroy(data); return success; } cfengine-3.24.2/libpromises/global_mutex.h0000644000000000000000000000246215010704253020542 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_GLOBAL_MUTEX_H #define CFENGINE_GLOBAL_MUTEX_H #include extern pthread_mutex_t *cft_lock; extern pthread_mutex_t *cft_count; extern pthread_mutex_t *cft_getaddr; extern pthread_mutex_t *cft_server_children; extern pthread_mutex_t *cft_server_filter; extern pthread_mutex_t *cft_db_corruption_lock; #endif cfengine-3.24.2/libpromises/mod_measurement.h0000644000000000000000000000220515010704253021237 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_MEASUREMENT_H #define CFENGINE_MOD_MEASUREMENT_H #include extern const PromiseTypeSyntax CF_MEASUREMENT_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/files_repository.h0000644000000000000000000000261315010704253021457 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_REPOSITORY_H #define CFENGINE_FILES_REPOSITORY_H void SetRepositoryLocation(const char *path); void SetRepositoryChar(char c); bool ArchiveToRepository(const char *file, const Attributes *attr); bool FileInRepository(const char *filename); /* Returns false if backing up files to repository is not set up */ bool GetRepositoryPath(const char *file, const Attributes *attr, char *destination); #endif cfengine-3.24.2/libpromises/mod_measurement.c0000644000000000000000000000610015010704253021230 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax match_value_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, /* Row models */ ConstraintSyntaxNewString("select_line_matching", CF_ANYSTRING, "Regular expression for matching line location", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("select_line_number", CF_VALRANGE, "Read from the n-th line of the output (fixed format)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("extraction_regex", "", "Regular expression that should contain a single backreference for extracting a value", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("track_growing_file", "If true, cfengine remembers the position to which is last read when opening the file, and resets to the start if the file has since been truncated", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("select_multiline_policy", "average,sum,first,last", "Regular expression for matching line location", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax match_value_body = BodySyntaxNew("match_value", match_value_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax CF_MEASURE_BODIES[] = { ConstraintSyntaxNewOption("stream_type", "pipe,file", "The datatype being collected.", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("data_type", "counter,int,real,string,slist", "The datatype being collected.", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("history_type", "weekly,scalar,static,log", "Whether the data can be seen as a time-series or just an isolated value", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("units", "", "The engineering dimensions of this value or a note about its intent used in plots", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("match_value", &match_value_body, "Criteria for extracting the measurement from a datastream", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_MEASUREMENT_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("monitor", "measurements", CF_MEASURE_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/generic_agent.h0000644000000000000000000001372615010704253020657 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_GENERIC_AGENT_H #define CFENGINE_GENERIC_AGENT_H #include #include #include #define GENERIC_AGENT_CHECKSUM_SIZE ((2*CF_SHA1_LEN) + 1) #define GENERIC_AGENT_CHECKSUM_METHOD HASH_METHOD_SHA1 enum generic_agent_config_common_policy_output_format { GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE, GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF, GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON, GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF_FULL, GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON_FULL }; typedef struct { AgentType agent_type; Rlist *bundlesequence; char *original_input_file; char *input_file; char *input_dir; char *tag_release_dir; bool check_not_writable_by_others; bool check_runnable; StringSet *heap_soft; StringSet *heap_negated; bool ignore_locks; bool tty_interactive; // agent is running interactively, via tty/terminal interface bool color; ProtocolVersion protocol_version; // agent state bool ignore_missing_bundles; bool ignore_missing_inputs; bool ignore_preferred_augments; // --ignore-preferred-augments struct { struct { enum generic_agent_config_common_policy_output_format policy_output_format; unsigned int parser_warnings; unsigned int parser_warnings_error; bool eval_functions; char *show_classes; char *show_variables; bool no_augments; bool no_host_specific; } common; struct { char *bootstrap_argument; char *bootstrap_host; char *bootstrap_port; char *bootstrap_ip; bool bootstrap_trust_server; bool bootstrap_trigger_policy; bool skip_bootstrap_service_start; char *show_evaluated_classes; char *show_evaluated_variables; // BODY AGENT CONTROL bool report_class_log; } agent; struct { /* Time of the last validated_at timestamp seen. */ time_t last_validated_at; } daemon; /* execd, serverd etc */ } agent_specific; } GenericAgentConfig; ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, GenericAgentSetDefaultDigest, HashMethod *, digest, int *, digest_len); const char *GenericAgentResolveInputPath(const GenericAgentConfig *config, const char *input_file); void MarkAsPolicyServer(EvalContext *ctx); void GenericAgentDiscoverContext(EvalContext *ctx, GenericAgentConfig *config, const char *program_name); bool GenericAgentCheckPolicy(GenericAgentConfig *config, bool force_validation, bool write_validated_file); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, GenericAgentAddEditionClasses, EvalContext *, ctx); void GenericAgentInitialize(EvalContext *ctx, GenericAgentConfig *config); void GenericAgentFinalize(EvalContext *ctx, GenericAgentConfig *config); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, GenericAgentWriteVersion, Writer *, w); bool GenericAgentArePromisesValid(const GenericAgentConfig *config); time_t ReadTimestampFromPolicyValidatedFile(const GenericAgentConfig *config, const char *maybe_dirname); bool GenericAgentIsPolicyReloadNeeded(const GenericAgentConfig *config); void CloseLog(void); Seq *ControlBodyConstraints(const Policy *policy, AgentType agent); void SetFacility(const char *retval); void CheckBundleParameters(char *scope, Rlist *args); void WritePID(char *filename); pid_t ReadPID(char *filename); bool GenericAgentConfigParseArguments(GenericAgentConfig *config, int argc, char **argv); bool GenericAgentConfigParseWarningOptions(GenericAgentConfig *config, const char *warning_options); bool GenericAgentConfigParseColor(GenericAgentConfig *config, const char *mode); Policy *SelectAndLoadPolicy(GenericAgentConfig *config, EvalContext *ctx, bool validate_policy, bool write_validated_file); GenericAgentConfig *GenericAgentConfigNewDefault(AgentType agent_type, bool tty_interactive); bool GetTTYInteractive(void); void GenericAgentConfigDestroy(GenericAgentConfig *config); void GenericAgentConfigApply(EvalContext *ctx, const GenericAgentConfig *config); bool CheckAndGenerateFailsafe(const char *inputdir, const char *input_file); void GenericAgentConfigSetInputFile(GenericAgentConfig *config, const char *inputdir, const char *input_file); void GenericAgentConfigSetBundleSequence(GenericAgentConfig *config, const Rlist *bundlesequence); bool GenericAgentTagReleaseDirectory(const GenericAgentConfig *config, const char *dirname, bool write_validated, bool write_release); void GetReleaseIdFile(const char *base_path, char *filename, size_t max_size); bool GenericAgentPostLoadInit(const EvalContext *ctx); void SetupSignalsForAgent(void); void LoadAugments(EvalContext *ctx, GenericAgentConfig *config); void GenericAgentShowContextsFormatted(EvalContext *ctx, const char *regexp); void GenericAgentShowVariablesFormatted(EvalContext *ctx, const char *regexp); #endif cfengine-3.24.2/libpromises/mod_custom.h0000644000000000000000000000436415010704253020234 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_CUSTOM_H #define CFENGINE_MOD_CUSTOM_H #include #include // IOData // mod_custom is not like the other modules which define promise types // (except for mod_common). It just defines some basics needed, for // custom promise types (promise modules) to work. // Defines the syntax for the top level promise block, i.e. what // constraints are allowed when adding new promises via promise modules // Uses BodySyntax, since promise blocks are syntatctically the same // as body blocks. (bundles are different, with sections and // promise attributes). extern const BodySyntax CUSTOM_PROMISE_BLOCK_SYNTAX; // Defines custom promise block with no syntax, as syntax will be checked by // the custom promise module. extern const BodySyntax CUSTOM_BODY_BLOCK_SYNTAX; typedef struct PromiseModule { pid_t pid; time_t process_start_time; IOData fds; FILE *input; FILE *output; char *path; char *interpreter; bool json; bool action_policy; JsonElement *message; } PromiseModule; bool InitializeCustomPromises(); void FinalizeCustomPromises(); void TerminateCustomPromises(); Body *FindCustomPromiseType(const Promise *promise); PromiseResult EvaluateCustomPromise(ARG_UNUSED EvalContext *ctx, const Promise *pp); #endif cfengine-3.24.2/libpromises/signals.h0000644000000000000000000000262615010704253017522 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SIGNALS_H #define CFENGINE_SIGNALS_H #include // check whether the running daemon should terminate after having received a signal. bool IsPendingTermination(void); bool ReloadConfigRequested(void); void ClearRequestReloadConfig(); void RequestReloadConfig(void); void MakeSignalPipe(void); int GetSignalPipe(void); void HandleSignalsForDaemon(int signum); void HandleSignalsForAgent(int signum); #endif cfengine-3.24.2/libpromises/iteration.c0000644000000000000000000011776515010704253020066 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include /* ExpandScalar */ #include /* DataTypeIsIterable */ /** * WHEELS * * The iteration engine for CFEngine is set up with a number of "wheels" that * roll in all combinations in order to iterate over everything - like the * combination lock found on suitcases. One wheel is added for each iterable * variable in the promiser-promisee-constraints strings. Iterable variables * are slists and containers. But wheels are created in other cases as well, * like variables that don't resolve yet but might change later on and * possibly become iterables. * * The wheels are in struct PromiseIterator_ and are added right after * initialisation of it, using PromiseIteratorPrepare() that calls ProcessVar(). * * Wheels are added in the Seq in an order that matters: variables that depend * on others to expand are *on the right* of their dependencies. That means * that *independent variables are on the left*. * * EXAMPLE reports promise: * "Value of A is $(A[$(i)][$(j)]) for indexes $(i) and $(j)" * * One appropriate wheels Seq for that would be: i j A[$(i)][$(j)] * * So for that promise 3 wheels get generated, and always the dependent * variables are on the right of their dependencies. The wheels sequence would * be exactly the same if the reports promise was simply "$(A[$(i)][$(j)])", * because there are again the same 3 variables. */ /** * ITERATING * * We push a new iteration context for each iteration, and VariablePut() into * THIS context all selected single values of the iterable variables (slists * or containers) represented by the wheels. * * *Thus EvalContext "THIS" never contains iterables (lists or containers).* * * This presents a problem for absolute references like $(abs.var), since * these cannot be mapped into "this" without some magic (see MANGLING). * * The iteration context is popped and re-pushed for each iteration, until no * further combinations of the wheel variables are left to be selected. */ /** * SCOPE/NAMESPACE MANGLING * * One important thing to notice is that the variables that are * namespaced/scope need to be *mangled* in order to be added as wheels. This * means that the scope separator '.' and namespace separator ':' are replaced * with '#' and '*' respectively. This happens in ProcessVar(), see comments * for reasoning and further info. */ typedef struct { /* The unexpanded variable name, dependent on inner expansions. This * field never changes after Wheel initialisation. */ char *varname_unexp; /* On each iteration of the wheels, the unexpanded string is * re-expanded, so the following is refilled, again and again. */ char *varname_exp; /* * Values of varname_exp, to iterate on. WE DO NOT OWN THE RVALS, they * belong to EvalContext, so don't free(). Only if vartype is CONTAINER do * we own the strings and we must free() them. * * After the iteration engine has started (via PromiseIteratorNext()) * "values" can be NULL when a variable does not resolve, or when it's * not an iterable but it's already there in EvalContext, so no need to * Put() separately; this means that it has exactly one value. * * When the variable resolves to an empty iterable (like empty slist or * container) then it's not NULL, but SeqLength(values)==0. * * TODO values==NULL should only be unresolved variable - * non-iterable variable should be SeqLength()==1. */ Seq *values; /* This is the list-type of the iterable variable, and this sets the type * of the elements stored in Seq values. Only possibilities are INTLIST, * REALLIST, SLIST, CONTAINER, NONE (if the variable did not resolve). */ DataType vartype; size_t iter_index; /* current iteration index */ } Wheel; struct PromiseIterator_ { Seq *wheels; const Promise *pp; /* not owned by us */ size_t count; /* total iterations count */ }; /** * @NOTE #varname doesn't need to be '\0'-terminated, since the length is * provided. */ static Wheel *WheelNew(const char *varname, size_t varname_len) { Wheel new_wheel = { .varname_unexp = xstrndup(varname, varname_len), .varname_exp = NULL, .values = NULL, .vartype = -1, .iter_index = 0 }; return xmemdup(&new_wheel, sizeof(new_wheel)); } static void WheelValuesSeqDestroy(Wheel *w) { if (w->values != NULL) { /* Only if the variable resolved to type CONTAINER do we need to free * the values, since we trasformed it to a Seq of strings. */ if (w->vartype == CF_DATA_TYPE_CONTAINER) { size_t values_len = SeqLength(w->values); for (size_t i = 0; i < values_len; i++) { char *value = SeqAt(w->values, i); free(value); } } SeqDestroy(w->values); w->values = NULL; } w->vartype = -1; } static void WheelDestroy(void *wheel) { Wheel *w = wheel; free(w->varname_unexp); free(w->varname_exp); WheelValuesSeqDestroy(w); free(w); } /* Type of this function is SeqItemComparator for use in SeqLookup(). */ static int WheelCompareUnexpanded(const void *wheel1, const void *wheel2, void *user_data ARG_UNUSED) { const Wheel *w1 = wheel1; const Wheel *w2 = wheel2; return strcmp(w1->varname_unexp, w2->varname_unexp); } PromiseIterator *PromiseIteratorNew(const Promise *pp) { PromiseIterator iterctx = { .wheels = SeqNew(4, WheelDestroy), .pp = pp, .count = 0 }; return xmemdup(&iterctx, sizeof(iterctx)); } void PromiseIteratorDestroy(PromiseIterator *iterctx) { SeqDestroy(iterctx->wheels); free(iterctx); } size_t PromiseIteratorIndex(const PromiseIterator *iter_ctx) { return iter_ctx->count; } /** * Returns offset to "$(" or "${" in the string. * Reads bytes up to s[max-1], s[max] is NOT read. * If a '\0' is encountered before the pattern, return offset to `\0` byte * If no '\0' byte or pattern is found within max bytes, max is returned */ static size_t FindDollarParen(const char *s, size_t max) { size_t i = 0; while (i < max && s[i] != '\0') { if (i+1 < max && (s[i] == '$' && (s[i+1] == '(' || s[i+1] == '{'))) { return i; } i++; } assert(i == max || s[i] == '\0'); return i; } static char opposite(char c) { switch (c) { case '(': return ')'; case '{': return '}'; default : ProgrammingError("Was expecting '(' or '{' but got: '%c'", c); } return 0; } /** * Find the closing parenthesis for #c in #s. #c is considered to *not* be part * of #s (IOW, #s is considered to be a string after #c). * * @return A closing parenthesis for #c in #s or %NULL if not found */ static char *FindClosingParen(char *s, char c) { char closing = opposite(c); int counter = 0; for (char *cur=s; *cur != '\0'; cur++) { if (*cur == closing) { if (counter == 0) { return cur; } counter--; } if (*cur == c) { counter++; } } return NULL; } /** * Check if variable reference is mangled, while avoiding going into the inner * variables that are being expanded, or into array indexes. * * @NOTE variable name is naked, i.e. shouldn't start with dollar-paren. */ static bool IsMangled(const char *s) { assert(s != NULL); size_t s_length = strlen(s); size_t dollar_paren = FindDollarParen(s, s_length); size_t bracket = strchrnul(s, '[') - s; size_t upto = MIN(dollar_paren, bracket); size_t mangled_ns = strchrnul(s, CF_MANGLED_NS) - s; size_t mangled_scope = strchrnul(s, CF_MANGLED_SCOPE) - s; if (mangled_ns < upto || mangled_scope < upto) { return true; } else { return false; } } /** * Mangle namespace and scope separators, up to '$(', '${', '[', '\0', * whichever comes first. * * "this" scope is never mangled, no need to VariablePut() a mangled reference * in THIS scope, since the non-mangled one already exists. */ static void MangleVarRefString(char *ref_str, size_t len) { size_t dollar_paren = FindDollarParen(ref_str, len); size_t upto = MIN(len, dollar_paren); char *bracket = memchr(ref_str, '[', upto); if (bracket != NULL) { upto = bracket - ref_str; } char *ns = memchr(ref_str, ':', upto); char *ref_str2 = ref_str; if (ns != NULL) { *ns = CF_MANGLED_NS; ref_str2 = ns + 1; assert(upto >= (ns + 1 - ref_str)); upto -= (ns + 1 - ref_str); } bool mangled_scope = false; char *scope = memchr(ref_str2, '.', upto); if (scope != NULL && strncmp(ref_str2, "this", 4) != 0) { *scope = CF_MANGLED_SCOPE; mangled_scope = true; } if (mangled_scope || ns != NULL) { LogDebug(LOG_MOD_ITERATIONS, "Mangled namespaced/scoped variable for iterating over it: %.*s", (int) len, ref_str); } } /** * Lookup a variable within iteration context. Since the scoped or namespaced * variable names may be mangled, we have to look them up using special * separators CF_MANGLED_NS and CF_MANGLED_SCOPE. */ static const void *IterVariableGet(const PromiseIterator *iterctx, const EvalContext *evalctx, const char *varname, DataType *type) { const void *value; const Bundle *bundle = PromiseGetBundle(iterctx->pp); /* Equivalent to: VarRefParseFromBundle(varname, PromiseGetBundle(iterctx->pp)) but with custom namespace,scope separators. Even !IsMangled(varname) it should be resolved properly since the secondary separators shouldn't alter the result for an unqualified varname. */ VarRef *ref = VarRefParseFromNamespaceAndScope(varname, bundle->ns, bundle->name, CF_MANGLED_NS, CF_MANGLED_SCOPE); value = EvalContextVariableGet(evalctx, ref, type); VarRefDestroy(ref); if (*type == CF_DATA_TYPE_NONE) /* did not resolve */ { assert(value == NULL); if (!IsMangled(varname)) { /* Lookup with no mangling, it might be a scoped/namespaced * variable that is not an iterable, so it was not mangled in * ProcessVar(). */ VarRef *ref2 = VarRefParse(varname); value = EvalContextVariableGet(evalctx, ref2, type); VarRefDestroy(ref2); } } return value; } /* TODO this is ugly!!! mapdata() needs to be refactored to put a whole slist as "this.k". But how? It is executed *after* PromiseIteratorNext()! */ static bool VarIsSpecial(const char *s) { if (strcmp(s, "this") == 0 || strcmp(s, "this.k") == 0 || strcmp(s, "this.v") == 0 || strcmp(s, "this.k[1]") == 0 || strcmp(s, "this.this") == 0) { return true; } else { return false; } } /** * Decide whether to mangle varname and add wheel to the iteration engine. * * If variable contains inner expansions -> mangle and add wheel * (because you don't know if it will be an iterable or not - you will * know after inner variable is iterated and the variable is looked up) * * else if it resolves to iterable -> mangle and add wheel * * else if it resolves to empty iterable -> mangle and add wheel * (see comments in code) * * else if the variable name is special for some functions (this.k etc) * -> mangle and add wheel * * else if it resolves to non-iterable -> no mangle, no wheel * * else if it doesn't resolve -> no mangle, no wheel * * @NOTE Important special scopes (e.g. "connection.ip" for cf-serverd) must * not be mangled to work correctly. This is auto-OK because such * variables do not resolve usually. */ static bool ShouldAddVariableAsIterationWheel( const PromiseIterator *iterctx, const EvalContext *evalctx, char *varname, size_t varname_len) { bool result; /* Shorten string temporarily to the appropriate length. */ char tmp_c = varname[varname_len]; varname[varname_len] = '\0'; VarRef *ref = VarRefParseFromBundle(varname, PromiseGetBundle(iterctx->pp)); DataType t; ARG_UNUSED const void *value = EvalContextVariableGet(evalctx, ref, &t); VarRefDestroy(ref); size_t dollar_paren = FindDollarParen(varname, varname_len); if (dollar_paren < varname_len) { /* Varname contains inner expansions, so maybe the variable will * resolve to an iterable during the iteration - must add wheel. */ result = true; } else if (DataTypeIsIterable(t)) { result = true; /* NOTE: If it is an EMPTY ITERABLE i.e. value==NULL, we are still * adding an iteration wheel, but with "wheel->values" set to an empty * Seq. The reason is that the iteration engine will completely *skip* * all promise evaluations when one of the wheels is empty. * * Otherwise, if we didn't add the empty wheel, even if the promise * contained no other wheels, the promise would get evaluated exactly * once with "$(varname)" literally in there. */ } else if (VarIsSpecial(varname)) { result = true; } else { /* * Either varname resolves to a non-iterable, e.g. string. * Or it does not resolve. * * Since this variable does not contain inner expansions, this can't * change during iteration of other variables. So don't add wheel - * i.e. don't iterate over this variable's values, because we know * there will always be only one value. */ result = false; } varname[varname_len] = tmp_c; /* Restore original string */ return result; } /** * Recursive function that adds wheels to the iteration engine, according to * the variable (and possibly its inner variables) in #s. * * Another important thing it does, is *modify* the string #s, mangling all * scoped or namespaced variable names. Mangling is done in order to iterate * over foreign variables, without modifying the foreign value. For example if * "test.var" is an slist, then we mangle it as "test#var" and on each * iteration we just VariablePut(test#var) in the local scope. * Mangling is skipped for variables that do not resolve, since they are not * to be iterated over. * * @param s is the start of a variable name, right after "$(" or "${". * @param c is the character after '$', i.e. must be either '(' or '{'. * @return pointer to the closing parenthesis or brace of the variable, or * if not found, returns a pointer to terminating '\0' of #s. */ static char *ProcessVar(PromiseIterator *iterctx, const EvalContext *evalctx, char *s, char c) { assert(s != NULL); assert(c == '(' || c == '{'); char *s_end = FindClosingParen(s, c); const size_t s_max = strlen(s); if (s_end == NULL) { /* Set s_end to the point to the NUL byte if no closing parenthesis was * found. It's used for comparisons and other things below. */ s_end = s + s_max; } char *next_var = s + FindDollarParen(s, s_max); while (next_var < s_end) /* does it have nested variables? */ { /* It's a dependent variable, the wheels of the dependencies must be * added first. Example: "$(blah_$(dependency))" */ assert(next_var[0] != '\0'); assert(next_var[1] != '\0'); char *subvar_end = ProcessVar(iterctx, evalctx, &next_var[2], next_var[1]); /* Was there unbalanced paren for the inner expansion? */ if (*subvar_end == '\0') { /* Despite unclosed parenthesis for the inner expansion, * the outer variable might close with a brace, or not. */ const size_t s_end_len = strlen(s_end); next_var = s_end + FindDollarParen(s_end, s_end_len); /* s_end is already correct */ } else /* inner variable processed correctly */ { /* This variable depends on inner expansions. */ /* We are sure (subvar_end+1) is not out of bounds. */ char *s_next = subvar_end + 1; const size_t s_next_len = strlen(s_next); s_end = FindClosingParen(s_next, c); if (s_end == NULL) { /* Set s_end to the point to the NUL byte if no closing parenthesis was * found. It's used for comparisons and other things below. */ s_end = s_next + s_next_len; } next_var = s_next + FindDollarParen(s_next, s_next_len); } } assert(s_end != NULL); if (*s_end == '\0') { Log(LOG_LEVEL_ERR, "No closing '%c' found for variable: %s", opposite(c), s); return s_end; } const size_t s_len = s_end - s; if (ShouldAddVariableAsIterationWheel(iterctx, evalctx, s, s_len)) { /* Change the variable name in order to mangle namespaces and scopes. */ MangleVarRefString(s, s_len); Wheel *new_wheel = WheelNew(s, s_len); /* If identical variable is already inserted, it means that it has * been seen before and has been inserted together with all * dependencies; skip. */ /* It can happen if variables exist twice in a string, for example: "$(i) blah $(A[$(i)])" has i variable twice. */ bool same_var_found = (SeqLookup(iterctx->wheels, new_wheel, WheelCompareUnexpanded) != NULL); if (same_var_found) { LogDebug(LOG_MOD_ITERATIONS, "Skipped adding iteration wheel for already existing variable: %s", new_wheel->varname_unexp); WheelDestroy(new_wheel); } else { /* If this variable is dependent on other variables, we've already * appended the wheels of the dependencies during the recursive * calls. Or it happens and this is an independent variable. So * now APPEND the wheel for this variable. */ SeqAppend(iterctx->wheels, new_wheel); LogDebug(LOG_MOD_ITERATIONS, "Added iteration wheel %zu for variable: %s", SeqLength(iterctx->wheels) - 1, new_wheel->varname_unexp); } } assert(s_end != NULL); assert(*s_end == opposite(c)); return s_end; } /** * @brief Fills up the wheels of the iterator according to the variables * found in #s. Also mangles all namespaced/scoped variables in #s. * * @EXAMPLE Have a look in iteration_test.c:test_PromiseIteratorPrepare() * * @NOTE the wheel numbers can't change once iteration started, so make sure * you call WheelIteratorPrepare() in advance, as many times it's * needed. */ void PromiseIteratorPrepare(PromiseIterator *iterctx, const EvalContext *evalctx, char *s) { assert(s != NULL); LogDebug(LOG_MOD_ITERATIONS, "PromiseIteratorPrepare(\"%s\")", s); const size_t s_len = strlen(s); const size_t offset = FindDollarParen(s, s_len); assert(offset <= s_len); // FindDollarParen guarantees this if (offset == s_len) { return; // Don't search past NULL terminator } char *var_start = s + offset; while (*var_start != '\0') { char paren_or_brace = var_start[1]; var_start += 2; /* skip dollar-paren */ assert(paren_or_brace == '(' || paren_or_brace == '{'); char *var_end = ProcessVar(iterctx, evalctx, var_start, paren_or_brace); assert(var_end != NULL); if (*var_end == '\0') { return; // Don't search past NULL terminator } char *var_next = var_end + 1; const size_t var_next_len = s_len - (var_next - s); const size_t var_offset = FindDollarParen(var_next, var_next_len); assert(var_offset <= var_next_len); if (var_offset == var_next_len) { return; // Don't search past NULL terminator } var_start = var_next + var_offset; } } static void IterListElementVariablePut(EvalContext *evalctx, const char *varname, DataType listtype, void *value) { DataType t; switch (listtype) { case CF_DATA_TYPE_CONTAINER: t = CF_DATA_TYPE_STRING; break; case CF_DATA_TYPE_STRING_LIST: t = CF_DATA_TYPE_STRING; break; case CF_DATA_TYPE_INT_LIST: t = CF_DATA_TYPE_INT; break; case CF_DATA_TYPE_REAL_LIST: t = CF_DATA_TYPE_REAL; break; default: t = CF_DATA_TYPE_NONE; /* silence warning */ ProgrammingError("IterVariablePut() invalid type: %d", listtype); } EvalContextVariablePutSpecial(evalctx, SPECIAL_SCOPE_THIS, varname, value, t, "source=promise_iteration"); } static void SeqAppendContainerPrimitive(Seq *seq, const JsonElement *primitive) { assert(JsonGetElementType(primitive) == JSON_ELEMENT_TYPE_PRIMITIVE); switch (JsonGetPrimitiveType(primitive)) { case JSON_PRIMITIVE_TYPE_BOOL: SeqAppend(seq, (JsonPrimitiveGetAsBool(primitive) ? xstrdup("true") : xstrdup("false"))); break; case JSON_PRIMITIVE_TYPE_INTEGER: { char *str = StringFromLong(JsonPrimitiveGetAsInteger(primitive)); SeqAppend(seq, str); break; } case JSON_PRIMITIVE_TYPE_REAL: { char *str = StringFromDouble(JsonPrimitiveGetAsReal(primitive)); SeqAppend(seq, str); break; } case JSON_PRIMITIVE_TYPE_STRING: SeqAppend(seq, xstrdup(JsonPrimitiveGetAsString(primitive))); break; case JSON_PRIMITIVE_TYPE_NULL: break; } } static Seq *ContainerToSeq(const JsonElement *container) { Seq *seq = SeqNew(5, NULL); switch (JsonGetElementType(container)) { case JSON_ELEMENT_TYPE_PRIMITIVE: SeqAppendContainerPrimitive(seq, container); break; case JSON_ELEMENT_TYPE_CONTAINER: { JsonIterator iter = JsonIteratorInit(container); const JsonElement *child; while ((child = JsonIteratorNextValue(&iter)) != NULL) { if (JsonGetElementType(child) == JSON_ELEMENT_TYPE_PRIMITIVE) { SeqAppendContainerPrimitive(seq, child); } } break; } } /* TODO SeqFinalise() to save space? */ return seq; } static Seq *RlistToSeq(const Rlist *p) { Seq *seq = SeqNew(5, NULL); const Rlist *rlist = p; while(rlist != NULL) { Rval val = rlist->val; SeqAppend(seq, val.item); rlist = rlist->next; } /* TODO SeqFinalise() to save space? */ return seq; } static Seq *IterableToSeq(const void *v, DataType t) { switch (t) { case CF_DATA_TYPE_CONTAINER: return ContainerToSeq(v); break; case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: /* All lists are stored as Rlist internally. */ assert(DataTypeToRvalType(t) == RVAL_TYPE_LIST); return RlistToSeq(v); default: ProgrammingError("IterableToSeq() got non-iterable type: %d", t); } } /* During initialization of the iteration engine, lists from foreign bundles are * mangled in order to avoid overwriting the values in that bundle. However, the * iteration engine has no way of knowing that some variables like * $($(parent_bundle).lst) is a list during initialization. Hence, while * crunching the wheels, this hack makes sure foreign variables are mangled when * ever they expand into a list. * * How does it work? It looks for a '.' in both #iterctx->pp->promiser and * #varname, where the left side of #varname is a bundle name and the right side * of #iterctx->pp->promiser begins with the right side of #varname. If all of * the constraints are fulfilled it swaps the '.' with '#' in both variables. * Furthermore, if the variable also contains a namespace, it will mangle ':' * with '*'. * * See ticket ENT-9491 & ENT-11923 for more info. */ static void WheelMangleAfterExpandingToList(const PromiseIterator *iterctx, EvalContext *evalctx, char *varname) { assert(iterctx != NULL); assert(iterctx->pp != NULL); assert(iterctx->pp->promiser != NULL); const StringSet *scopes = EvalContextGetBundleNames(evalctx); // In case there is a namespace char *unexp_namespace_token = iterctx->pp->promiser; while ((unexp_namespace_token = strchr(unexp_namespace_token, CF_NS)) != NULL) { char *exp_namespace_token = varname; while ((exp_namespace_token = strchr(exp_namespace_token, CF_NS)) != NULL) { char *unexp_scope_token = iterctx->pp->promiser; while ((unexp_scope_token = strchr(unexp_scope_token, '.')) != NULL) { char *exp_scope_token = varname; while ((exp_scope_token = strchr(exp_scope_token, '.')) != NULL) { if (exp_scope_token < exp_namespace_token) { // A scope token cannot come before a namespace token continue; } *exp_scope_token = '\0'; const char *exp_scope = exp_namespace_token + 1; const char *unexp_name = unexp_scope_token + 1; const char *exp_name = exp_scope_token + 1; if (StringStartsWith(unexp_name, exp_name) && StringSetContains(scopes, exp_scope)) { *unexp_namespace_token = CF_MANGLED_NS; *exp_namespace_token = CF_MANGLED_NS; *unexp_scope_token = CF_MANGLED_SCOPE; *exp_scope_token = CF_MANGLED_SCOPE; // We are done! return; } // Put things back the way they were *exp_scope_token = '.'; exp_scope_token += 1; } unexp_scope_token += 1; } exp_namespace_token += 1; } unexp_namespace_token += 1; } // In case there is no namespace char *unexp_scope_token = iterctx->pp->promiser; while ((unexp_scope_token = strchr(unexp_scope_token, '.')) != NULL) { char *exp_scope_token = varname; while ((exp_scope_token = strchr(exp_scope_token, '.')) != NULL) { *exp_scope_token = '\0'; const char *exp_scope = varname; const char *unexp_name = unexp_scope_token + 1 ; const char *exp_name = exp_scope_token + 1; if (StringStartsWith(unexp_name, exp_name) && StringSetContains(scopes, exp_scope)) { *unexp_scope_token = CF_MANGLED_SCOPE; *exp_scope_token = CF_MANGLED_SCOPE; // We are done! return; } // Put things back the way they were *exp_scope_token = '.'; exp_scope_token += 1; } unexp_scope_token += 1; } } /** * For each of the wheels to the right of wheel_idx (including this one) * * 1. varname_exp = expand the variable name * - if it's same with previous varname_exp, skip steps 2-4 * 2. values = VariableGet(varname_exp); * 3. if the value is an iterable (slist/container), set the wheel size. * 4. reset the wheel in order to re-iterate over all combinations. * 5. Put(varname_exp:first_value) in the EvalContext */ static void ExpandAndPutWheelVariablesAfter( const PromiseIterator *iterctx, EvalContext *evalctx, size_t wheel_idx) { assert(iterctx != NULL); assert(iterctx->wheels != NULL); assert(iterctx->pp != NULL); assert(iterctx->pp->promiser != NULL); /* Buffer to store the expanded wheel variable name, for each wheel. */ Buffer *tmpbuf = BufferNew(); size_t wheels_num = SeqLength(iterctx->wheels); for (size_t i = wheel_idx; i < wheels_num; i++) { Wheel *wheel = SeqAt(iterctx->wheels, i); BufferClear(tmpbuf); /* Reset wheel in order to re-iterate over all combinations. */ wheel->iter_index = 0; /* The wheel variable may depend on previous wheels, for example * "B_$(k)_$(v)" is dependent on variables "k" and "v", which are * wheels already set (to the left, or at lower i index). */ const char *varname = ExpandScalar(evalctx, PromiseGetNamespace(iterctx->pp), /* Use NULL as scope so that we try both "this" and "bundle" scopes. */ NULL, wheel->varname_unexp, tmpbuf); /* If it expanded to something different than before. */ if (wheel->varname_exp == NULL || strcmp(varname, wheel->varname_exp) != 0) { free(wheel->varname_exp); /* could be NULL */ wheel->varname_exp = xstrdup(varname); WheelValuesSeqDestroy(wheel); /* free previous values */ /* After expanding the variable name, we have to lookup its value, and set the size of the wheel if it's an slist or container. */ DataType value_type; const void *value = IterVariableGet(iterctx, evalctx, varname, &value_type); wheel->vartype = value_type; /* Set wheel values and size according to variable type. */ if (DataTypeIsIterable(value_type)) { wheel->values = IterableToSeq(value, value_type); if (SeqLength(wheel->values) == 0) { /* * If this variable now expands to a 0-length list, then * we should skip this iteration, no matter the * other variables: "zero times whatever" multiplication * always equals zero. */ Log(LOG_LEVEL_VERBOSE, "Skipping iteration since variable '%s'" " resolves to an empty list", varname); } else { assert( wheel->values != NULL); assert(SeqLength(wheel->values) > 0); assert( SeqAt(wheel->values, 0) != NULL); if (!IsMangled(varname)) { WheelMangleAfterExpandingToList(iterctx, evalctx, (char *) varname); } /* Put the first value of the iterable. */ IterListElementVariablePut(evalctx, varname, value_type, SeqAt(wheel->values, 0)); } } /* It it's NOT AN ITERABLE BUT IT RESOLVED AND IT IS MANGLED: this * is possibly a variable that was unresolvable during the * Prepare() stage, but now resolves to a string etc. We still * need to Put() it despite not being an iterable, since the * mangled version is not in the EvalContext. * The "values" Seq is left as NULL. */ else if (value_type != CF_DATA_TYPE_NONE && IsMangled(varname)) { EvalContextVariablePutSpecial(evalctx, SPECIAL_SCOPE_THIS, varname, value, value_type, "source=promise_iteration"); } /* It's NOT AN ITERABLE AND IT'S NOT MANGLED, which means that * the variable with the correct value (the only value) is already * in the EvalContext, no need to Put() it again. */ /* OR it doesn't resolve at all! */ else { /* DO NOTHING, everything is already set. */ assert(!DataTypeIsIterable(value_type)); assert(value_type == CF_DATA_TYPE_NONE || /* var does not resolve */ !IsMangled(varname)); /* or is not mangled */ /* We don't allocate Seq for non-iterables. */ assert(wheel->values == NULL); } } else /* The variable name expanded to the same name */ { /* speedup: the variable name expanded to the same name, so the * value is the same and wheel->values is already correct. So if * it's an iterable, we VariablePut() the first element. */ if (wheel->values != NULL && SeqLength(wheel->values) > 0) { /* Put the first value of the iterable. */ IterListElementVariablePut(evalctx, wheel->varname_exp, wheel->vartype, SeqAt(wheel->values, 0)); } } } BufferDestroy(tmpbuf); } static bool IteratorHasEmptyWheel(const PromiseIterator *iterctx) { size_t wheels_num = SeqLength(iterctx->wheels); for (size_t i = 0; i < wheels_num; i++) { Wheel *wheel = SeqAt(iterctx->wheels, i); assert(wheel != NULL); if (VarIsSpecial(wheel->varname_unexp)) /* TODO this is ugly! */ { return false; } /* If variable resolves to an empty iterable or it doesn't resolve. */ if ((wheel->values != NULL && SeqLength(wheel->values) == 0) || wheel->vartype == CF_DATA_TYPE_NONE) { return true; } } return false; } /* Try incrementing the rightmost wheel first that has values left to iterate on. (rightmost i.e. the most dependent variable). */ static size_t WheelRightmostIncrement(PromiseIterator *iterctx) { size_t wheels_num = SeqLength(iterctx->wheels); size_t i = wheels_num; Wheel *wheel; assert(wheels_num > 0); do { if (i == 0) { return (size_t) -1; /* all wheels have been iterated over */ } i--; /* move one wheel to the left */ wheel = SeqAt(iterctx->wheels, i); wheel->iter_index++; /* Stop when we have found a wheel with value available at iter_index. */ } while (wheel->values == NULL || wheel->vartype == CF_DATA_TYPE_NONE || SeqLength(wheel->values) == 0 || wheel->iter_index >= SeqLength(wheel->values)); return i; /* return which wheel was incremented */ } /* Nothing to iterate on, so get out after running the promise once. * Because all promises, even if there are zero variables to be * expanded in them, must be evaluated. */ static bool RunOnlyOnce(PromiseIterator *iterctx) { assert(SeqLength(iterctx->wheels) == 0); if (iterctx->count == 0) { iterctx->count++; return true; } else { return false; } } bool PromiseIteratorNext(PromiseIterator *iterctx, EvalContext *evalctx) { size_t wheels_num = SeqLength(iterctx->wheels); if (wheels_num == 0) { return RunOnlyOnce(iterctx); } bool done = false; /* First iteration: we initialise all wheels. */ if (iterctx->count == 0) { Log(LOG_LEVEL_DEBUG, "Starting iteration engine with %zu wheels" " --- ENTERING WARP SPEED", wheels_num); ExpandAndPutWheelVariablesAfter(iterctx, evalctx, 0); done = ! IteratorHasEmptyWheel(iterctx); } while (!done) { size_t i = WheelRightmostIncrement(iterctx); if (i == (size_t) -1) /* all combinations have been tried */ { Log(LOG_LEVEL_DEBUG, "Iteration engine finished" " --- WARPING OUT"); return false; } /* * Alright, incrementing the wheel at index "i" was successful. Now * Put() the new value of the variable in the EvalContext. This is the * *basic iteration step*, just going to the next value of the * iterable. */ Wheel *wheel = SeqAt(iterctx->wheels, i); void *new_value = SeqAt(wheel->values, wheel->iter_index); IterListElementVariablePut( evalctx, wheel->varname_exp, wheel->vartype, new_value); /* All the wheels to the right of the one we changed have to be reset * and recomputed, in order to do all possible combinations. */ ExpandAndPutWheelVariablesAfter(iterctx, evalctx, i + 1); /* If any of the wheels has no values to offer, then this iteration * should be skipped completely; so the function doesn't yield any * result yet, it just loops over until it finds a meaningful one. */ done = ! IteratorHasEmptyWheel(iterctx); LogDebug(LOG_MOD_ITERATIONS, "PromiseIteratorNext():" " count=%zu wheels_num=%zu current_wheel=%zd", iterctx->count, wheels_num, (ssize_t) i); /* TODO if not done, then we are re-Put()ing variables in the EvalContext, * hopefully overwriting the previous values, but possibly not! */ } // Recompute `with` for (size_t i = 0; i < SeqLength(iterctx->pp->conlist); i++) { Constraint *cp = SeqAt(iterctx->pp->conlist, i); if (StringEqual(cp->lval, "with")) { Rval final = EvaluateFinalRval(evalctx, PromiseGetPolicy(iterctx->pp), NULL, "this", cp->rval, false, iterctx->pp); if (final.type == RVAL_TYPE_SCALAR && !IsCf3VarString(RvalScalarValue(final))) { EvalContextVariablePutSpecial(evalctx, SPECIAL_SCOPE_THIS, "with", RvalScalarValue(final), CF_DATA_TYPE_STRING, "source=promise_iteration/with"); } RvalDestroy(final); } } iterctx->count++; return true; } cfengine-3.24.2/libpromises/process_unix_priv.h0000644000000000000000000000326015010704253021636 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROCESS_PRIV_H #define CFENGINE_PROCESS_PRIV_H /* * Unix-like OS should provide implementations of the following functions. */ /* * GetProcessStartTime (see process_lib.h) */ typedef enum { PROCESS_STATE_RUNNING, PROCESS_STATE_STOPPED, PROCESS_STATE_ZOMBIE, PROCESS_STATE_DOES_NOT_EXIST } ProcessState; /* * Obtain process state. * * @return PROCESS_STATE_RUNNING if process exists and is running, * @return PROCESS_STATE_STOPPED if process exists and has been stopped by SIGSTOP signal, * @return PROCESS_STATE_ZOMBIE if process exists and is zombie, * @return PROCESS_STATE_DOES_NOT_EXIST if process cannot be found. */ ProcessState GetProcessState(pid_t pid); #endif cfengine-3.24.2/libpromises/processes_select.h0000644000000000000000000000255115010704253021424 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROCESSES_SELECT_H #define CFENGINE_PROCESSES_SELECT_H #include #ifdef _WIN32 extern Item *PROCESSTABLE; #endif bool LoadProcessTable(void); void ClearProcessTable(void); Item *SelectProcesses(const char *process_name, const ProcessSelect *a, bool attrselect); bool IsProcessNameRunning(char *procNameRegex); const char *GetProcessTableLegend(void); #endif cfengine-3.24.2/libpromises/patches.c0000644000000000000000000001243415010704253017502 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* Contains any fixes which need to be made because of lack of OS support on a given platform These are conditionally compiled, pending extensions or developments in the OS concerned. FIXME: move to the libcompat/ directory or to the appropriate source file. */ #include #include #ifdef __ANDROID__ # include /* File_Copy() */ #endif static char *cf_format_strtimestamp(struct tm *tm, char *buf); /*********************************************************/ #ifndef HAVE_SETNETGRENT #if SETNETGRENT_RETURNS_INT int #else void #endif setnetgrent(const char *netgroup) { #if SETNETGRENT_RETURNS_INT return 0; #endif } #endif /**********************************************************/ #ifndef HAVE_GETNETGRENT int getnetgrent(char **machinep, char **userp, char **domainp) { *machinep = NULL; *userp = NULL; *domainp = NULL; return 0; } #endif /***********************************************************/ #ifndef HAVE_ENDNETGRENT #if ENDNETGRENT_RETURNS_INT int #else void #endif endnetgrent(void) { #if ENDNETGRENT_RETURNS_INT return 1; #endif } #endif /***********************************************************/ #ifndef HAVE_SETEGID int setegid(gid_t gid) { # ifdef HAVE_SETREGID return setregid(-1, gid); # else Log(LOG_LEVEL_VERBOSE, "(This system does not have setregid (patches.c)"); return -1; # endif } #endif /*******************************************************************/ bool IsPrivileged() { #ifdef _WIN32 return true; #else return (getuid() == 0); #endif } /* * This function converts passed time_t value to string timestamp used * throughout the system. By sheer coincidence this timestamp has the same * format as ctime(3) output on most systems (but NT differs in definition of * ctime format, so those are not identical there). * * Buffer passed should be at least 26 bytes long (including the trailing zero). * * Please use this function instead of (non-portable and deprecated) ctime_r or * (non-threadsafe) ctime. */ /*******************************************************************/ char *cf_strtimestamp_local(const time_t time, char *buf) { struct tm tm; if (localtime_r(&time, &tm) == NULL) { Log(LOG_LEVEL_VERBOSE, "Unable to parse passed timestamp. (localtime_r: %s)", GetErrorStr()); return NULL; } return cf_format_strtimestamp(&tm, buf); } /*******************************************************************/ char *cf_strtimestamp_utc(const time_t time, char *buf) { struct tm tm; if (gmtime_r(&time, &tm) == NULL) { Log(LOG_LEVEL_VERBOSE, "Unable to parse passed timestamp. (gmtime_r: %s)", GetErrorStr()); return NULL; } return cf_format_strtimestamp(&tm, buf); } /*******************************************************************/ static char *cf_format_strtimestamp(struct tm *tm, char *buf) { /* Security checks */ if ((tm->tm_year < -2899) || (tm->tm_year > 8099)) { Log(LOG_LEVEL_ERR, "Unable to format timestamp: passed year is out of range: %d", tm->tm_year + 1900); return NULL; } /* There is no easy way to replicate ctime output by using strftime */ if (snprintf(buf, 26, "%3.3s %3.3s %2d %02d:%02d:%02d %04d", DAY_TEXT[tm->tm_wday ? (tm->tm_wday - 1) : 6], MONTH_TEXT[tm->tm_mon], tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900) >= 26) { Log(LOG_LEVEL_ERR, "Unable to format timestamp: passed values are out of range"); return NULL; } return buf; } /*******************************************************************/ bool LinkOrCopy(const char *from, const char *to, int sym) /** * Creates symlink to file on platforms supporting it, copies on * others. **/ { #ifdef __MINGW32__ // only copy on Windows for now if (!CopyFile(from, to, TRUE)) { return false; } #elif __ANDROID__ /* link() not supported on ANDROID platform */ return File_Copy(from, to); #else /* !__MINGW32__ */ if (sym) { if (symlink(from, to) == -1) { return false; } } else // hardlink { if (link(from, to) == -1) { return false; } } #endif /* !__MINGW32__ */ return true; } cfengine-3.24.2/libpromises/syntax.h0000644000000000000000000001506615010704253017412 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SYNTAX_H #define CFENGINE_SYNTAX_H #include #include #include #include #include /* * WARNING: This file is in need of serious cleanup. */ typedef enum { SYNTAX_TYPE_MATCH_OK, SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED, SYNTAX_TYPE_MATCH_ERROR_RANGE_BRACKETED, SYNTAX_TYPE_MATCH_ERROR_RANGE_MULTIPLE_ITEMS, SYNTAX_TYPE_MATCH_ERROR_GOT_SCALAR, SYNTAX_TYPE_MATCH_ERROR_GOT_LIST, SYNTAX_TYPE_MATCH_ERROR_GOT_NULL, SYNTAX_TYPE_MATCH_ERROR_SCALAR_OUT_OF_RANGE, SYNTAX_TYPE_MATCH_ERROR_EMPTY_SCALAR_OUT_OF_RANGE, SYNTAX_TYPE_MATCH_ERROR_STRING_UNIX_PERMISSION, SYNTAX_TYPE_MATCH_ERROR_INT_PARSE, SYNTAX_TYPE_MATCH_ERROR_INT_OUT_OF_RANGE, SYNTAX_TYPE_MATCH_ERROR_REAL_INF, SYNTAX_TYPE_MATCH_ERROR_REAL_OUT_OF_RANGE, SYNTAX_TYPE_MATCH_ERROR_OPTS_OUT_OF_RANGE, SYNTAX_TYPE_MATCH_ERROR_FNCALL_RETURN_TYPE, SYNTAX_TYPE_MATCH_ERROR_FNCALL_UNKNOWN, SYNTAX_TYPE_MATCH_ERROR_CONTEXT_OUT_OF_RANGE, SYNTAX_TYPE_MATCH_ERROR_ABSOLUTE_PATH, SYNTAX_TYPE_MATCH_MAX } SyntaxTypeMatch; const char *SyntaxTypeMatchToString(SyntaxTypeMatch result); bool CheckParseVariableName(const char *name); SyntaxTypeMatch CheckConstraintTypeMatch(const char *lval, Rval rval, DataType dt, const char *range, int level); SyntaxTypeMatch CheckParseContext(const char *context, const char *range); DataType StringDataType(EvalContext *ctx, const char *string); DataType ExpectedDataType(const char *lvalname); bool IsBuiltInPromiseType(const char *const promise_type); const PromiseTypeSyntax *PromiseTypeSyntaxGet(const char *bundle_type, const char *promise_type); const ConstraintSyntax *PromiseTypeSyntaxGetConstraintSyntax(const PromiseTypeSyntax *promise_type_syntax, const char *lval); const BodySyntax *BodySyntaxGet(ParserBlock block, const char *body_type); const ConstraintSyntax *BodySyntaxGetConstraintSyntax(const ConstraintSyntax *body_syntax, const char *lval); const char *SyntaxStatusToString(SyntaxStatus status); JsonElement *SyntaxToJson(void); #define ConstraintSyntaxNewNull() { NULL, CF_DATA_TYPE_NONE, .range.validation_string = NULL, .status = SYNTAX_STATUS_NORMAL } #define ConstraintSyntaxNewBool(lval, description, status) { lval, CF_DATA_TYPE_OPTION, .range.validation_string = CF_BOOL, description, status } #define ConstraintSyntaxNewOption(lval, options, description, status) { lval, CF_DATA_TYPE_OPTION, .range.validation_string = options, description, status } #define ConstraintSyntaxNewOptionList(lval, item_range, description, status) { lval, CF_DATA_TYPE_OPTION_LIST, .range.validation_string = item_range, description, status } #define ConstraintSyntaxNewString(lval, regex, description, status) { lval, CF_DATA_TYPE_STRING, .range.validation_string = regex, description, status } #define ConstraintSyntaxNewStringList(lval, item_range, description, status) { lval, CF_DATA_TYPE_STRING_LIST, .range.validation_string = item_range, description, status } #define ConstraintSyntaxNewInt(lval, int_range, description, status) { lval, CF_DATA_TYPE_INT, .range.validation_string = int_range, description, status } #define ConstraintSyntaxNewIntRange(lval, int_range, description, status ) { lval , CF_DATA_TYPE_INT_RANGE, .range.validation_string = int_range, description, status } #define ConstraintSyntaxNewIntList(lval, description, status) { lval, CF_DATA_TYPE_INT_LIST, .range.validation_string = CF_INTRANGE, description, status } #define ConstraintSyntaxNewReal(lval, real_range, description, status) { lval, CF_DATA_TYPE_REAL, .range.validation_string = real_range, description, status } #define ConstraintSyntaxNewRealList(lval, description, status) { lval, CF_DATA_TYPE_REAL_LIST, .range.validation_string = CF_REALRANGE, description, status } #define ConstraintSyntaxNewContext(lval, description, status) { lval, CF_DATA_TYPE_CONTEXT, .range.validation_string = CF_CLASSRANGE, description, status } #define ConstraintSyntaxNewContextList(lval, description, status) { lval, CF_DATA_TYPE_CONTEXT_LIST, .range.validation_string = CF_CLASSRANGE, description, status } #define ConstraintSyntaxNewContainer(lval, description, status) { lval, CF_DATA_TYPE_CONTAINER, .range.validation_string = "", description, status } #define ConstraintSyntaxNewBody(lval, body_syntax, description, status) { lval, CF_DATA_TYPE_BODY, .range.body_type_syntax = body_syntax, description, status } #define ConstraintSyntaxNewBundle(lval, description, status) { lval, CF_DATA_TYPE_BUNDLE, .range.validation_string = CF_BUNDLE, description, status } #define BodySyntaxNew(body_type, constraints, check_fn, status) { body_type, constraints, check_fn, status } #define BodySyntaxNewNull() { NULL, NULL, NULL, SYNTAX_STATUS_NORMAL } #define PromiseTypeSyntaxNew(agent_type, promise_type, constraints, check_fn, status) { agent_type, promise_type, constraints, check_fn, status } #define PromiseTypeSyntaxNewNull() PromiseTypeSyntaxNew(NULL, NULL, NULL, NULL, SYNTAX_STATUS_NORMAL) #define FnCallTypeNew(name, return_type, arguments, implementation, description, opts, category, status) { name, return_type, arguments, implementation, description, .options = opts, category, status } #define FnCallTypeNewNull() FnCallTypeNew(NULL, CF_DATA_TYPE_NONE, NULL, NULL, NULL, false, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL) #define CONSTRAINT_SYNTAX_GLOBAL { "meta", CF_DATA_TYPE_STRING_LIST, .range.validation_string = "", "Tags describing the body", SYNTAX_STATUS_NORMAL }, \ { "inherit_from", CF_DATA_TYPE_BODY, .range.validation_string = "", "Body from which attributes will be inherited", SYNTAX_STATUS_NORMAL } #endif cfengine-3.24.2/libpromises/cf3.extern.h0000644000000000000000000000506215010704253020036 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CF3_EXTERN_H #define CFENGINE_CF3_EXTERN_H #include /* CF_MAX_IP_LEN */ #include /* CF_MAXVARSIZE,CF_OBSERVABLES */ /* See variables in cf3globals.c and syntax.c */ extern pid_t ALARM_PID; extern RSA *PRIVKEY, *PUBKEY; extern char BINDINTERFACE[CF_MAXVARSIZE]; extern time_t CONNTIMEOUT; extern time_t CFSTARTTIME; extern struct utsname VSYSNAME; extern char VIPADDRESS[CF_MAX_IP_LEN]; extern char VPREFIX[1024]; extern char VFQNAME[CF_MAXVARSIZE]; extern char VDOMAIN[CF_MAXVARSIZE / 2]; extern char VUQNAME[CF_MAXVARSIZE / 2]; typedef enum EvalMode { EVAL_MODE_NORMAL = 0, /* needs to be 'false' to work for DONTDO below */ EVAL_MODE_DRY_RUN = 1, EVAL_MODE_SIMULATE_DIFF = 2, EVAL_MODE_SIMULATE_MANIFEST = 3, EVAL_MODE_SIMULATE_MANIFEST_FULL = 4, } EvalMode; extern EvalMode EVAL_MODE; /* This is only for backwards compatibility with code that uses * 'if (!DONTDO)'. */ #define DONTDO ((bool) EVAL_MODE) extern bool MINUSF; extern int EDITFILESIZE; extern int VIFELAPSED; extern int VEXPIREAFTER; extern const char *const OBSERVABLES[CF_OBSERVABLES][2]; extern bool FIPS_MODE; extern HashMethod CF_DEFAULT_DIGEST; extern int CF_DEFAULT_DIGEST_LEN; extern int CF_PERSISTENCE; extern const char *const CF_AGENTTYPES[]; extern int CFA_MAXTHREADS; extern AgentType THIS_AGENT_TYPE; extern long LASTSEENEXPIREAFTER; extern const char *DEFAULT_COPYTYPE; extern const char *const DAY_TEXT[]; extern const char *const MONTH_TEXT[]; extern const char *const SHIFT_TEXT[]; #endif cfengine-3.24.2/libpromises/pipes_unix.c0000644000000000000000000006550415010704253020244 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include static bool CfSetuid(uid_t uid, gid_t gid); static int cf_pwait(pid_t pid); static pid_t *CHILDREN = NULL; /* GLOBAL_X */ static int MAX_FD = 2048; /* GLOBAL_X */ /* Max number of simultaneous pipes */ static void ChildrenFDInit() { ThreadLock(cft_count); if (CHILDREN == NULL) /* first time */ { CHILDREN = xcalloc(MAX_FD, sizeof(pid_t)); } ThreadUnlock(cft_count); } /*****************************************************************************/ /* This leaks memory and is not thread-safe! To be used only when you are * about to exec() or _exit(), and only async-signal-safe code is allowed. */ static void ChildrenFDUnsafeClose() { /* GenericCreatePipeAndFork() must have been called to init this. */ assert(CHILDREN != NULL); for (int i = 0; i < MAX_FD; i++) { if (CHILDREN[i] > 0) { close(i); } } CHILDREN = NULL; /* leaks on purpose */ } /* This is the original safe version, but not signal-handler-safe. It's currently unused. */ #if 0 static void ChildrenFDClose() { ThreadLock(cft_count); int i; for (i = 0; i < MAX_FD; i++) { if (CHILDREN[i] > 0) { close(i); } } free(CHILDREN); CHILDREN = NULL; ThreadUnlock(cft_count); } #endif static void ChildOutputSelectDupClose(int pd[2], OutputSelect output_select) { close(pd[0]); // Don't need output from parent if (pd[1] != 1) // TODO: When is pd[1] == 1 ??? { if ((output_select == OUTPUT_SELECT_BOTH) || (output_select == OUTPUT_SELECT_STDOUT)) { // close our(child) stdout(1) and open (pd[1]) as stdout dup2(pd[1], 1); // Subsequent stdout output will go to parent (pd[1]) } else { // Close / discard stdout int nullfd = open(NULLFILE, O_WRONLY); dup2(nullfd, 1); close(nullfd); } if ((output_select == OUTPUT_SELECT_BOTH) || (output_select == OUTPUT_SELECT_STDERR)) { // close our(child) stderr(2) and open (pd[1]) as stderr dup2(pd[1], 2); // Subsequent stderr output will go to parent (pd[1]) } else { // Close / discard stderr int nullfd = open(NULLFILE, O_WRONLY); dup2(nullfd, 2); close(nullfd); } close(pd[1]); } } /*****************************************************************************/ static void ChildrenFDSet(int fd, pid_t pid) { int new_max = 0; if (fd >= MAX_FD) { Log(LOG_LEVEL_WARNING, "File descriptor %d of child %jd higher than MAX_FD, check for defunct children", fd, (intmax_t) pid); new_max = fd + 32; } ThreadLock(cft_count); if (new_max) { CHILDREN = xrealloc(CHILDREN, new_max * sizeof(pid_t)); MAX_FD = new_max; } CHILDREN[fd] = pid; ThreadUnlock(cft_count); } /*****************************************************************************/ typedef struct { const char *type; int pipe_desc[2]; } IOPipe; static pid_t GenericCreatePipeAndFork(IOPipe *pipes) { for (int i = 0; i < 2; i++) { if (pipes[i].type && !PipeTypeIsOk(pipes[i].type)) { errno = EINVAL; return -1; } } ChildrenFDInit(); /* Create pair of descriptors to this process. */ if (pipes[0].type && pipe(pipes[0].pipe_desc) < 0) { return -1; } /* Create second pair of descriptors (if exists) to this process. * This will allow full I/O operations. */ if (pipes[1].type && pipe(pipes[1].pipe_desc) < 0) { close(pipes[0].pipe_desc[0]); close(pipes[0].pipe_desc[1]); return -1; } pid_t pid = -1; if ((pid = fork()) == (pid_t) -1) { /* One pipe will be always here. */ close(pipes[0].pipe_desc[0]); close(pipes[0].pipe_desc[1]); /* Second pipe is optional so we have to check existence. */ if (pipes[1].type) { close(pipes[1].pipe_desc[0]); close(pipes[1].pipe_desc[1]); } return -1; } /* Ignore SIGCHLD, by setting the handler to SIG_DFL. NOTE: this is * different than setting to SIG_IGN. In the latter case no zombies are * generated ever and you can't wait() for the child to finish. */ struct sigaction sa = { .sa_handler = SIG_DFL, }; sigemptyset(&sa.sa_mask); sigaction(SIGCHLD, &sa, NULL); if (pid == 0) /* child */ { /* WARNING only call async-signal-safe functions in child. */ /* The fork()ed child is always single-threaded, but we are only * allowed to call async-signal-safe functions (man 3p fork). */ // Redmine #2971: reset SIGPIPE signal handler in the child to have a // sane behavior of piped commands within child signal(SIGPIPE, SIG_DFL); /* The child should always accept all signals after it has exec'd, * else the child might be unkillable! (happened in ENT-3147). */ sigset_t sigmask; sigemptyset(&sigmask); sigprocmask(SIG_SETMASK, &sigmask, NULL); } ALARM_PID = (pid != 0 ? pid : -1); return pid; } /*****************************************************************************/ static pid_t CreatePipeAndFork(const char *type, int *pd) { IOPipe pipes[2]; pipes[0].type = type; pipes[1].type = NULL; /* We don't want to create this one. */ pid_t pid = GenericCreatePipeAndFork(pipes); pd[0] = pipes[0].pipe_desc[0]; pd[1] = pipes[0].pipe_desc[1]; return pid; } /*****************************************************************************/ static pid_t CreatePipesAndFork(const char *type, int *pd, int *pdb) { IOPipe pipes[2]; /* Both pipes MUST have the same type. */ pipes[0].type = type; pipes[1].type = type; pid_t pid = GenericCreatePipeAndFork(pipes); pd[0] = pipes[0].pipe_desc[0]; pd[1] = pipes[0].pipe_desc[1]; pdb[0] = pipes[1].pipe_desc[0]; pdb[1] = pipes[1].pipe_desc[1]; return pid; } /*****************************************************************************/ IOData cf_popen_full_duplex(const char *command, bool capture_stderr, bool require_full_path) { /* For simplifying reading and writing directions */ const int READ=0, WRITE=1; int child_pipe[2]; /* From child to parent */ int parent_pipe[2]; /* From parent to child */ pid_t pid; char **argv = ArgSplitCommand(command, NULL); fflush(NULL); /* Empty file buffers */ pid = CreatePipesAndFork("r+t", child_pipe, parent_pipe); if (pid == (pid_t) -1) { Log(LOG_LEVEL_ERR, "Couldn't fork child process: %s", GetErrorStr()); ArgFree(argv); return (IOData) {-1, -1, NULL, NULL}; } else if (pid > 0) // parent { close(child_pipe[WRITE]); close(parent_pipe[READ]); IOData io_desc; io_desc.write_fd = parent_pipe[WRITE]; io_desc.read_fd = child_pipe[READ]; io_desc.read_stream = NULL; io_desc.write_stream = NULL; ChildrenFDSet(parent_pipe[WRITE], pid); ChildrenFDSet(child_pipe[READ], pid); ArgFree(argv); return io_desc; } else // child { close(child_pipe[READ]); close(parent_pipe[WRITE]); /* Open stdin from parant process and stdout from child */ if (dup2(parent_pipe[READ], 0) == -1 || dup2(child_pipe[WRITE],1) == -1) { Log(LOG_LEVEL_ERR, "Can not execute dup2: %s", GetErrorStr()); _exit(EXIT_FAILURE); } if (capture_stderr) { /* Merge stdout/stderr */ if(dup2(child_pipe[WRITE], 2) == -1) { Log(LOG_LEVEL_ERR, "Can not execute dup2 for merging stderr: %s", GetErrorStr()); _exit(EXIT_FAILURE); } } else { /* leave stderr open */ } close(child_pipe[WRITE]); close(parent_pipe[READ]); ChildrenFDUnsafeClose(); int res; if (require_full_path) { res = execv(argv[0], argv); } else { res = execvp(argv[0], argv); } if (res == -1) { /* NOTE: exec functions return only when error have occurred. */ Log(LOG_LEVEL_ERR, "Couldn't run '%s'. (%s: %s)", argv[0], require_full_path ? "execv" : "execvp", GetErrorStr()); } /* We shouldn't reach this point */ _exit(EXIT_FAILURE); } } FILE *cf_popen_select(const char *command, const char *type, OutputSelect output_select) { int pd[2]; pid_t pid; FILE *pp = NULL; char **argv = ArgSplitCommand(command, NULL); pid = CreatePipeAndFork(type, pd); if (pid == (pid_t) -1) { ArgFree(argv); return NULL; } if (pid == 0) /* child */ { /* WARNING only call async-signal-safe functions in child. */ switch (*type) { case 'r': ChildOutputSelectDupClose(pd, output_select); break; case 'w': close(pd[1]); if (pd[0] != 0) { dup2(pd[0], 0); close(pd[0]); } } ChildrenFDUnsafeClose(); if (execv(argv[0], argv) == -1) { Log(LOG_LEVEL_ERR, "Couldn't run '%s'. (execv: %s)", argv[0], GetErrorStr()); } _exit(EXIT_FAILURE); } else /* parent */ { switch (*type) { case 'r': close(pd[1]); if ((pp = fdopen(pd[0], type)) == NULL) { cf_pwait(pid); ArgFree(argv); return NULL; } break; case 'w': close(pd[0]); if ((pp = fdopen(pd[1], type)) == NULL) { cf_pwait(pid); ArgFree(argv); return NULL; } } ChildrenFDSet(fileno(pp), pid); ArgFree(argv); return pp; } ProgrammingError("Unreachable code"); return NULL; } FILE *cf_popen(const char *command, const char *type, bool capture_stderr) { return cf_popen_select( command, type, capture_stderr ? OUTPUT_SELECT_BOTH : OUTPUT_SELECT_STDOUT); } /*****************************************************************************/ /* * WARNING: this is only allowed to be called from single-threaded code, * because of the safe_chdir() call in the forked child. */ FILE *cf_popensetuid(const char *command, const Seq *arglist, const char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, ARG_UNUSED int background) { int pd[2]; pid_t pid; FILE *pp = NULL; char **argv = ArgSplitCommand(command, arglist); pid = CreatePipeAndFork(type, pd); if (pid == (pid_t) -1) { ArgFree(argv); return NULL; } if (pid == 0) /* child */ { /* WARNING only call async-signal-safe functions in child. */ switch (*type) { case 'r': close(pd[0]); /* Don't need output from parent */ if (pd[1] != 1) { dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */ dup2(pd[1], 2); /* Merge stdout/stderr */ close(pd[1]); } break; case 'w': close(pd[1]); if (pd[0] != 0) { dup2(pd[0], 0); close(pd[0]); } } ChildrenFDUnsafeClose(); if (chrootv && (strlen(chrootv) != 0)) { if (chroot(chrootv) == -1) { Log(LOG_LEVEL_ERR, "Couldn't chroot to '%s'. (chroot: %s)", chrootv, GetErrorStr()); _exit(EXIT_FAILURE); } } if (chdirv && (strlen(chdirv) != 0)) { if (safe_chdir(chdirv) == -1) { Log(LOG_LEVEL_ERR, "Couldn't chdir to '%s'. (chdir: %s)", chdirv, GetErrorStr()); _exit(EXIT_FAILURE); } } if (!CfSetuid(uid, gid)) { _exit(EXIT_FAILURE); } if (execv(argv[0], argv) == -1) { Log(LOG_LEVEL_ERR, "Couldn't run '%s'. (execv: %s)", argv[0], GetErrorStr()); } _exit(EXIT_FAILURE); } else /* parent */ { switch (*type) { case 'r': close(pd[1]); if ((pp = fdopen(pd[0], type)) == NULL) { cf_pwait(pid); ArgFree(argv); return NULL; } break; case 'w': close(pd[0]); if ((pp = fdopen(pd[1], type)) == NULL) { cf_pwait(pid); ArgFree(argv); return NULL; } } ChildrenFDSet(fileno(pp), pid); ArgFree(argv); return pp; } ProgrammingError("Unreachable code"); return NULL; } /*****************************************************************************/ /* Shell versions of commands - not recommended for security reasons */ /*****************************************************************************/ FILE *cf_popen_sh_select(const char *command, const char *type, OutputSelect output_select) { int pd[2]; pid_t pid; FILE *pp = NULL; pid = CreatePipeAndFork(type, pd); if (pid == (pid_t) -1) { return NULL; } if (pid == 0) /* child */ { /* WARNING only call async-signal-safe functions in child. */ switch (*type) { case 'r': ChildOutputSelectDupClose(pd, output_select); break; case 'w': close(pd[1]); if (pd[0] != 0) { dup2(pd[0], 0); close(pd[0]); } } ChildrenFDUnsafeClose(); execl(SHELL_PATH, "sh", "-c", command, NULL); Log(LOG_LEVEL_ERR, "Couldn't run: '%s' (execl: %s)", command, GetErrorStr()); _exit(EXIT_FAILURE); } else /* parent */ { switch (*type) { case 'r': close(pd[1]); if ((pp = fdopen(pd[0], type)) == NULL) { cf_pwait(pid); return NULL; } break; case 'w': close(pd[0]); if ((pp = fdopen(pd[1], type)) == NULL) { cf_pwait(pid); return NULL; } } ChildrenFDSet(fileno(pp), pid); return pp; } ProgrammingError("Unreachable code"); return NULL; } FILE *cf_popen_sh(const char *command, const char *type) { return cf_popen_sh_select(command, type, OUTPUT_SELECT_BOTH); } /******************************************************************************/ /* * WARNING: this is only allowed to be called from single-threaded code, * because of the safe_chdir() call in the forked child. */ FILE *cf_popen_shsetuid(const char *command, const char *type, uid_t uid, gid_t gid, char *chdirv, char *chrootv, ARG_UNUSED int background) { int pd[2]; pid_t pid; FILE *pp = NULL; pid = CreatePipeAndFork(type, pd); if (pid == (pid_t) -1) { return NULL; } if (pid == 0) /* child */ { /* WARNING only call async-signal-safe functions in child. */ switch (*type) { case 'r': close(pd[0]); /* Don't need output from parent */ if (pd[1] != 1) { dup2(pd[1], 1); /* Attach pp=pd[1] to our stdout */ dup2(pd[1], 2); /* Merge stdout/stderr */ close(pd[1]); } break; case 'w': close(pd[1]); if (pd[0] != 0) { dup2(pd[0], 0); close(pd[0]); } } ChildrenFDUnsafeClose(); if (chrootv && (strlen(chrootv) != 0)) { if (chroot(chrootv) == -1) { Log(LOG_LEVEL_ERR, "Couldn't chroot to '%s'. (chroot: %s)", chrootv, GetErrorStr()); _exit(EXIT_FAILURE); } } if (chdirv && (strlen(chdirv) != 0)) { if (safe_chdir(chdirv) == -1) { Log(LOG_LEVEL_ERR, "Couldn't chdir to '%s'. (chdir: %s)", chdirv, GetErrorStr()); _exit(EXIT_FAILURE); } } if (!CfSetuid(uid, gid)) { _exit(EXIT_FAILURE); } execl(SHELL_PATH, "sh", "-c", command, NULL); Log(LOG_LEVEL_ERR, "Couldn't run: '%s' (execl: %s)", command, GetErrorStr()); _exit(EXIT_FAILURE); } else /* parent */ { switch (*type) { case 'r': close(pd[1]); if ((pp = fdopen(pd[0], type)) == NULL) { cf_pwait(pid); return NULL; } break; case 'w': close(pd[0]); if ((pp = fdopen(pd[1], type)) == NULL) { cf_pwait(pid); return NULL; } } ChildrenFDSet(fileno(pp), pid); return pp; } ProgrammingError("Unreachable code"); return NULL; } static int cf_pwait(pid_t pid) { Log(LOG_LEVEL_DEBUG, "cf_pwait - waiting for process %jd", (intmax_t) pid); int status; while (waitpid(pid, &status, 0) < 0) { if (errno != EINTR) { Log(LOG_LEVEL_ERR, "Waiting for child PID %jd failed (waitpid: %s)", (intmax_t) pid, GetErrorStr()); return -1; } } if (!WIFEXITED(status)) { Log(LOG_LEVEL_VERBOSE, "Child PID %jd exited abnormally (%s)", (intmax_t) pid, WIFSIGNALED(status) ? "signalled" : ( WIFSTOPPED(status) ? "stopped" : ( WIFCONTINUED(status) ? "continued" : "unknown" ))); return -1; } int retcode = WEXITSTATUS(status); Log(LOG_LEVEL_DEBUG, "cf_pwait - process %jd exited with code: %d", (intmax_t) pid, retcode); return retcode; } /*******************************************************************/ /** * Closes the pipe without waiting the child. * * @param pp pipe to the child process */ void cf_pclose_nowait(FILE *pp) { if (fclose(pp) == EOF) { Log(LOG_LEVEL_ERR, "Could not close the pipe to the executed subcommand (fclose: %s)", GetErrorStr()); } } /** * Closes the pipe and wait()s for PID of the child, * in order to reap the zombies. */ int cf_pclose(FILE *pp) { int fd = fileno(pp); pid_t pid; ThreadLock(cft_count); if (CHILDREN == NULL) /* popen hasn't been called */ { ThreadUnlock(cft_count); fclose(pp); return -1; } ALARM_PID = -1; if (fd >= MAX_FD) { ThreadUnlock(cft_count); Log(LOG_LEVEL_ERR, "File descriptor %d of child higher than MAX_FD in cf_pclose!", fd); fclose(pp); return -1; } pid = CHILDREN[fd]; CHILDREN[fd] = 0; ThreadUnlock(cft_count); if (fclose(pp) == EOF) { Log(LOG_LEVEL_ERR, "Could not close the pipe to the executed subcommand (fclose: %s)", GetErrorStr()); } return cf_pwait(pid); } int cf_pclose_full_duplex_side(int fd) { ThreadLock(cft_count); if (CHILDREN == NULL) /* popen hasn't been called */ { ThreadUnlock(cft_count); close(fd); return -1; } if (fd >= MAX_FD) { ThreadUnlock(cft_count); Log(LOG_LEVEL_ERR, "File descriptor %d of child higher than MAX_FD in cf_pclose_full_duplex_side!", fd); } else { CHILDREN[fd] = 0; ThreadUnlock(cft_count); } return close(fd); } /* We are assuming that read_fd part will be always open at this point. */ int cf_pclose_full_duplex(IOData *data) { assert(data != NULL); ThreadLock(cft_count); if (CHILDREN == NULL) { ThreadUnlock(cft_count); if (data->read_stream != NULL) { // fclose closes the underlying fd / socket, // but we need the fd for handling of processes below. assert(data->read_fd >= 0); fclose(data->read_stream); } else if (data->read_fd >= 0) { close(data->read_fd); } if (data->write_stream != NULL) { // fclose closes the underlying fd / socket, // but we need the fd for handling of processes below. assert(data->write_fd >= 0); fclose(data->write_stream); } else if (data->write_fd >= 0) { close(data->write_fd); } return -1; } ALARM_PID = -1; pid_t pid = 0; /* Safe as pipes[1] is -1 if not initialized */ if (data->read_fd >= MAX_FD || data->write_fd >= MAX_FD) { ThreadUnlock(cft_count); Log(LOG_LEVEL_ERR, "File descriptor %d of child higher than MAX_FD in cf_pclose!", data->read_fd > data->write_fd ? data->read_fd : data->write_fd); } else { pid = CHILDREN[data->read_fd]; if (data->write_fd >= 0) { assert(pid == CHILDREN[data->write_fd]); CHILDREN[data->write_fd] = 0; } CHILDREN[data->read_fd] = 0; ThreadUnlock(cft_count); } if (data->read_stream != NULL) { // Stream is open, fclose it if (fclose(data->read_stream) != 0) { return -1; } } else { // No stream, just close fd if (close(data->read_fd) != 0) { return -1; } } if (data->write_fd >= 0) { // write fd needs to be closed if (data->write_stream != NULL) { // Stream is open, fclose it if (fclose(data->write_stream) != 0) { return -1; } } else { // No stream, close fd directly if (close(data->write_fd) != 0) { return -1; } } } if (pid == 0) { return -1; } return cf_pwait(pid); } bool PipeToPid(pid_t *pid, FILE *pp) { int fd = fileno(pp); ThreadLock(cft_count); if (CHILDREN == NULL) /* popen hasn't been called */ { ThreadUnlock(cft_count); return false; } *pid = CHILDREN[fd]; ThreadUnlock(cft_count); return true; } /*******************************************************************/ static bool CfSetuid(uid_t uid, gid_t gid) { struct passwd *pw; if (gid != (gid_t) - 1) { Log(LOG_LEVEL_VERBOSE, "Changing gid to %ju", (uintmax_t)gid); if (setgid(gid) == -1) { Log(LOG_LEVEL_ERR, "Couldn't set gid to '%ju'. (setgid: %s)", (uintmax_t)gid, GetErrorStr()); return false; } /* Now eliminate any residual privileged groups */ if ((pw = getpwuid(uid)) == NULL) { Log(LOG_LEVEL_ERR, "Unable to get login groups when dropping privilege to '%ju'. (getpwuid: %s)", (uintmax_t)uid, GetErrorStr()); return false; } if (initgroups(pw->pw_name, pw->pw_gid) == -1) { Log(LOG_LEVEL_ERR, "Unable to set login groups when dropping privilege to '%s=%ju'. (initgroups: %s)", pw->pw_name, (uintmax_t)uid, GetErrorStr()); return false; } } if (uid != (uid_t) - 1) { Log(LOG_LEVEL_VERBOSE, "Changing uid to '%ju'", (uintmax_t)uid); if (setuid(uid) == -1) { Log(LOG_LEVEL_ERR, "Couldn't set uid to '%ju'. (setuid: %s)", (uintmax_t)uid, GetErrorStr()); return false; } } return true; } /* For Windows we need a different method because select() does not */ /* work with non-socket file descriptors. */ int PipeIsReadWriteReady(const IOData *io, int timeout_sec) { fd_set rset; FD_ZERO(&rset); FD_SET(io->read_fd, &rset); struct timeval tv = { .tv_sec = timeout_sec, .tv_usec = 0, }; Log(LOG_LEVEL_DEBUG, "PipeIsReadWriteReady: wait max %ds for data on fd %d", timeout_sec, io->read_fd); int ret = select(io->read_fd + 1, &rset, NULL, NULL, &tv); if (ret < 0) { Log(LOG_LEVEL_VERBOSE, "Failed checking for data (select: %s)", GetErrorStr()); return -1; } else if (FD_ISSET(io->read_fd, &rset)) { return io->read_fd; } else if (ret == 0) { /* timeout_sec has elapsed but no data was available. */ return 0; } else { UnexpectedError("select() returned > 0 but our only fd is not set!"); return -1; } } cfengine-3.24.2/libpromises/mod_outputs.c0000644000000000000000000000323115010704253020430 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax CF_OUTPUTS_BODIES[] = { ConstraintSyntaxNewOption("output_level", "verbose,debug,inform", "Output level to observe for the named promise or bundle (meta-promise). Default value: verbose", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewOption("promiser_type", "promise,bundle", "Output level to observe for the named promise or bundle (meta-promise). Default value: promise", SYNTAX_STATUS_REMOVED), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_OUTPUTS_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "outputs", CF_OUTPUTS_BODIES, NULL, SYNTAX_STATUS_REMOVED), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/mod_process.c0000644000000000000000000001271115010704253020366 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static const ConstraintSyntax process_count_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("in_range_define", "", "List of classes to define if the matches are in range", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("match_range", CF_VALRANGE, "Integer range for acceptable number of matches for this process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("out_of_range_define", "", "List of classes to define if the matches are out of range", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax process_count_body = BodySyntaxNew("process_count", process_count_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax process_select_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString("command", "", "Regular expression matching the command/cmd field of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("pid", CF_VALRANGE, "Range of integers matching the process id of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("pgid", CF_VALRANGE, "Range of integers matching the parent group id of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("ppid", CF_VALRANGE, "Range of integers matching the parent process id of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("priority", "-20,+20", "Range of integers matching the priority field (PRI/NI) of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("process_owner", "", "List of regexes matching the user of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("process_result", "[(process_owner|pid|ppid||pgid|rsize|vsize|status|command|ttime|stime|tty|priority|threads)[|&!.]*]*", "Boolean class expression returning the logical combination of classes set by a process selection test", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("rsize", CF_VALRANGE, "Range of integers matching the resident memory size of a process, in kilobytes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("status", "", "Regular expression matching the status field of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("stime_range", CF_TIMERANGE, "Range of integers matching the start time of a process", SYNTAX_STATUS_NORMAL), /* CF_VALRANGE insted of CF_TIMERANGE since ttime_range counts cumulative * time, not absolute time since the epoch. See cumulative() that has * maximum number of years 1000, that can easily surpass CF_TIMERANGE in * seconds. */ ConstraintSyntaxNewIntRange("ttime_range", CF_VALRANGE, "Range of integers matching the total elapsed time of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("tty", "", "Regular expression matching the tty field of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("threads", CF_VALRANGE, "Range of integers matching the threads (NLWP) field of a process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("vsize", CF_VALRANGE, "Range of integers matching the virtual memory size of a process, in kilobytes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax process_select_body = BodySyntaxNew("process_select", process_select_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax processes_constraints[] = { ConstraintSyntaxNewBody("process_count", &process_count_body, "Criteria for constraining the number of processes matching other criteria", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("process_select", &process_select_body, "Criteria for matching processes in the system process table", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("process_stop", CF_ABSPATHRANGE, "A command used to stop a running process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("restart_class", CF_IDRANGE, "A class to be defined globally if the process is not running, so that a command: rule can be referred to restart the process", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("signals", "(hup|int|trap|kill|pipe|cont|abrt|stop|quit|term|child|usr1|usr2|bus|segv|[0-9]+s?)", "A list of strings representing signals to be sent to a process or sleep periods", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const PromiseTypeSyntax CF_PROCESS_PROMISE_TYPES[] = { PromiseTypeSyntaxNew("agent", "processes", processes_constraints, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/rlist.c0000644000000000000000000012770115010704253017214 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include /* StringHash */ #include /* StringMatchWithPrecompiledRegex,CompileRegex */ #include #include #include #include #include /* IsCf3VarString */ static Rlist *RlistPrependRval(Rlist **start, Rval rval); static char SECRET_RVAL[] = "************"; RvalType DataTypeToRvalType(DataType datatype) { switch (datatype) { case CF_DATA_TYPE_BODY: case CF_DATA_TYPE_BUNDLE: case CF_DATA_TYPE_CONTEXT: case CF_DATA_TYPE_COUNTER: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_INT_RANGE: case CF_DATA_TYPE_OPTION: case CF_DATA_TYPE_REAL: case CF_DATA_TYPE_REAL_RANGE: case CF_DATA_TYPE_STRING: return RVAL_TYPE_SCALAR; case CF_DATA_TYPE_CONTEXT_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_OPTION_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_STRING_LIST: return RVAL_TYPE_LIST; case CF_DATA_TYPE_CONTAINER: return RVAL_TYPE_CONTAINER; case CF_DATA_TYPE_NONE: return RVAL_TYPE_NOPROMISEE; } ProgrammingError("DataTypeToRvalType, unhandled"); } bool RlistValueIsType(const Rlist *rlist, RvalType type) { return (rlist != NULL && rlist->val.type == type); } char *RlistScalarValue(const Rlist *rlist) { if (rlist->val.type != RVAL_TYPE_SCALAR) { ProgrammingError("Rlist value contains type %c instead of expected scalar", rlist->val.type); } return rlist->val.item; } char *RlistScalarValueSafe(const Rlist *rlist) { if (rlist->val.type != RVAL_TYPE_SCALAR) { return "[not printable]"; } return RlistScalarValue(rlist); } /*******************************************************************/ FnCall *RlistFnCallValue(const Rlist *rlist) { if (rlist->val.type != RVAL_TYPE_FNCALL) { ProgrammingError("Rlist value contains type %c instead of expected FnCall", rlist->val.type); } return rlist->val.item; } /*******************************************************************/ Rlist *RlistRlistValue(const Rlist *rlist) { if (rlist->val.type != RVAL_TYPE_LIST) { ProgrammingError("Rlist value contains type %c instead of expected List", rlist->val.type); } return rlist->val.item; } /*******************************************************************/ char *RvalScalarValue(Rval rval) { if (rval.type != RVAL_TYPE_SCALAR) { ProgrammingError("Internal error: Rval contains type %c instead of expected scalar", rval.type); } return rval.item; } /*******************************************************************/ FnCall *RvalFnCallValue(Rval rval) { if (rval.type != RVAL_TYPE_FNCALL) { ProgrammingError("Rval contains type %c instead of expected FnCall", rval.type); } return rval.item; } /*******************************************************************/ Rlist *RvalRlistValue(Rval rval) { if (rval.type != RVAL_TYPE_LIST) { ProgrammingError("Rval contain type %c instead of expected List", rval.type); } return rval.item; } /*******************************************************************/ JsonElement *RvalContainerValue(Rval rval) { if (rval.type != RVAL_TYPE_CONTAINER) { ProgrammingError("Rval contain type %c instead of expected container", rval.type); } return rval.item; } const char *RvalTypeToString(RvalType type) { switch (type) { case RVAL_TYPE_CONTAINER: return "data"; case RVAL_TYPE_FNCALL: return "call"; case RVAL_TYPE_LIST: return "list"; case RVAL_TYPE_NOPROMISEE: return "null"; case RVAL_TYPE_SCALAR: return "scalar"; } assert(false && "never reach"); return NULL; } Rlist *RlistKeyIn(Rlist *list, const char *key) { for (Rlist *rp = list; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR && strcmp(RlistScalarValue(rp), key) == 0) { return rp; } } return NULL; } /*******************************************************************/ bool RlistMatchesRegexRlist(const Rlist *list, const Rlist *search) /* Returns true if "list" contains all the regular expressions in "search". Non-scalars in "list" and "search" are skipped. */ { for (const Rlist *rp = search; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR && // check for the current element in the search list !RlistMatchesRegex(list, RlistScalarValue(search))) { return false; } } return true; } bool RlistMatchesRegex(const Rlist *list, const char *regex) /* Returns true if any of the "list" of strings matches "regex". Non-scalars in "list" are skipped. */ { if (regex == NULL || list == NULL) { return false; } Regex *rx = CompileRegex(regex); if (!rx) { return false; } for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR && StringMatchFullWithPrecompiledRegex(rx, RlistScalarValue(rp))) { RegexDestroy(rx); return true; } } RegexDestroy(rx); return false; } bool RlistIsNullList(const Rlist *list) { return (list == NULL); } bool RlistIsInListOfRegex(const Rlist *list, const char *str) /* Returns true if any of the "list" of regular expressions matches "str". Non-scalars in "list" are skipped. */ { if (str == NULL || list == NULL) { return false; } for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR && StringMatchFull(RlistScalarValue(rp), str)) { return true; } } return false; } bool RlistContainsString(const Rlist *list, const char *string) { assert(string != NULL); if (list == NULL) { // Empty Rlist is represented as a NULL pointer return false; } for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR && StringEqual(RlistScalarValue(rp), string)) { return true; } } return false; } /*******************************************************************/ static Rval RvalCopyScalar(Rval rval) { assert(rval.type == RVAL_TYPE_SCALAR); const char * src = rval.item ? rval.item : ""; return (Rval) {xstrdup(src), RVAL_TYPE_SCALAR}; } Rlist *RlistAppendRval(Rlist **start, Rval rval) { Rlist *rp = xmalloc(sizeof(Rlist)); rp->val = rval; rp->next = NULL; if (*start == NULL) { *start = rp; } else { Rlist *lp = *start; while (lp->next != NULL) { lp = lp->next; } lp->next = rp; } return rp; } /* Inserts an Rlist node with value #rval, right after the rlist node #node. */ void RlistInsertAfter(Rlist *node, Rval rval) { assert(node != NULL); Rlist new_node = { .val = rval, .next = node->next }; node->next = xmemdup(&new_node, sizeof(new_node)); } Rval RvalNewRewriter(const void *item, RvalType type, JsonElement *map) { switch (type) { case RVAL_TYPE_SCALAR: if (map != NULL && JsonLength(map) > 0 && // do we have a rewrite map? (strstr(item, "$(") || strstr(item, "${"))) // are there unresolved variable references? { // TODO: replace with BufferSearchAndReplace when the // string_replace code is merged. // Sorry about the CF_BUFSIZE ugliness. int max_size = 10*CF_BUFSIZE+1; char *buffer_from = xmalloc(max_size); char *buffer_to = xmalloc(max_size); Buffer *format = BufferNew(); StringCopy(item, buffer_from, max_size); buffer_to[0] = '\0'; for (int iteration = 0; iteration < 10; iteration++) { bool replacement_made = false; int var_start = -1; char closing_brace = 0; for (int c = 0; buffer_from[c] != '\0'; c++) { if (buffer_from[c] == '$') { if (buffer_from[c+1] == '(') { closing_brace = ')'; } else if (buffer_from[c+1] == '{') { closing_brace = '}'; } if (closing_brace) { c++; var_start = c-1; } } else if (var_start >= 0 && buffer_from[c] == closing_brace) { char saved = buffer_from[c]; buffer_from[c] = '\0'; const char *repl = JsonObjectGetAsString(map, buffer_from + var_start + 2); buffer_from[c] = saved; if (repl) { // Before the replacement. memcpy(buffer_to, buffer_from, var_start); // The actual replacement. int repl_len = strlen(repl); memcpy(buffer_to + var_start, repl, repl_len); // The text after. strlcpy(buffer_to + var_start + repl_len, buffer_from + c + 1, max_size - var_start - repl_len); // Reset location to immediately after the replacement. c = var_start + repl_len - 1; var_start = -1; StringCopy(buffer_to, buffer_from, max_size); closing_brace = 0; replacement_made = true; } } } if (!replacement_made) { break; } } char* ret; if (buffer_to[0] == '\0') { // If nothing has been written to buffer_to, we pass the input verbatim. // This function only evaluates body parameters, but the body can also reference the global // context. ret = xstrdup(buffer_from); } else { ret = xstrdup(buffer_to); } BufferDestroy(format); free(buffer_to); free(buffer_from); return (Rval) { ret, RVAL_TYPE_SCALAR }; } else { return (Rval) { xstrdup(item), RVAL_TYPE_SCALAR }; } case RVAL_TYPE_FNCALL: return (Rval) { FnCallCopyRewriter(item, map), RVAL_TYPE_FNCALL }; case RVAL_TYPE_LIST: return (Rval) { RlistCopyRewriter(item, map), RVAL_TYPE_LIST }; case RVAL_TYPE_CONTAINER: return (Rval) { JsonCopy(item), RVAL_TYPE_CONTAINER }; case RVAL_TYPE_NOPROMISEE: return ((Rval) {NULL, type}); } assert(false); return ((Rval) { NULL, RVAL_TYPE_NOPROMISEE }); } Rval RvalNew(const void *item, RvalType type) { return RvalNewRewriter(item, type, NULL); } Rval RvalNewSecret() { return ((Rval) {SECRET_RVAL, RVAL_TYPE_SCALAR}); } Rval RvalCopyRewriter(Rval rval, JsonElement *map) { return RvalNewRewriter(rval.item, rval.type, map); } Rval RvalCopy(Rval rval) { return RvalNew(rval.item, rval.type); } /*******************************************************************/ Rlist *RlistCopyRewriter(const Rlist *rp, JsonElement *map) { Rlist *start = NULL; while (rp != NULL) { RlistAppendRval(&start, RvalCopyRewriter(rp->val, map)); rp = rp->next; } return start; } Rlist *RlistCopy(const Rlist *rp) { return RlistCopyRewriter(rp, NULL); } /*******************************************************************/ void RlistDestroy(Rlist *rl) /* Delete an rlist and all its references */ { while (rl != NULL) { Rlist *next = rl->next; if (rl->val.item) { RvalDestroy(rl->val); } free(rl); rl = next; } } void RlistDestroy_untyped(void *rl) { RlistDestroy(rl); } /*******************************************************************/ Rlist *RlistAppendScalarIdemp(Rlist **start, const char *scalar) { if (RlistKeyIn(*start, scalar)) { return NULL; } return RlistAppendScalar(start, scalar); } Rlist *RlistPrependScalarIdemp(Rlist **start, const char *scalar) { if (RlistKeyIn(*start, scalar)) { return NULL; } return RlistPrepend(start, scalar, RVAL_TYPE_SCALAR); } Rlist *RlistAppendScalar(Rlist **start, const char *scalar) { return RlistAppendRval(start, RvalCopyScalar((Rval) { (char *)scalar, RVAL_TYPE_SCALAR })); } Rlist *RlistAppendString(Rlist **start, const char *string) { Rlist *l = RlistAppendScalar(start, string); assert(RlistContainsString(l, string)); return l; } // NOTE: Copies item, does NOT take ownership Rlist *RlistAppend(Rlist **start, const void *item, RvalType type) { return RlistAppendAllTypes(start, item, type, false); } // See fncall.c for the usage of allow_all_types. Rlist *RlistAppendAllTypes(Rlist **start, const void *item, RvalType type, bool allow_all_types) { Rlist *lp = *start; switch (type) { case RVAL_TYPE_SCALAR: return RlistAppendScalar(start, item); case RVAL_TYPE_FNCALL: break; case RVAL_TYPE_LIST: if (allow_all_types) { JsonElement* store = JsonArrayCreate(RlistLen(item)); for (const Rlist *rp = item; rp; rp = rp->next) { JsonArrayAppendElement(store, RvalToJson(rp->val)); } return RlistAppendRval(start, (Rval) { store, RVAL_TYPE_CONTAINER }); } for (const Rlist *rp = item; rp; rp = rp->next) { lp = RlistAppendRval(start, RvalCopy(rp->val)); } return lp; case RVAL_TYPE_CONTAINER: if (allow_all_types) { return RlistAppendRval(start, (Rval) { JsonCopy((JsonElement*) item), RVAL_TYPE_CONTAINER }); } // fall through default: Log(LOG_LEVEL_DEBUG, "Cannot append %c to rval-list '%s'", type, (char *) item); return NULL; } Rlist *rp = xmalloc(sizeof(Rlist)); rp->val = RvalNew(item, type); rp->next = NULL; if (*start == NULL) { *start = rp; } else { for (lp = *start; lp->next != NULL; lp = lp->next) { } lp->next = rp; } return rp; } /*******************************************************************/ static Rlist *RlistPrependRval(Rlist **start, Rval rval) { Rlist *rp = xmalloc(sizeof(Rlist)); rp->next = *start; rp->val = rval; *start = rp; return rp; } Rlist *RlistPrepend(Rlist **start, const void *item, RvalType type) { switch (type) { case RVAL_TYPE_LIST: { Rlist *lp = NULL; for (const Rlist *rp = item; rp; rp = rp->next) { lp = RlistPrependRval(start, RvalCopy(rp->val)); } return lp; } case RVAL_TYPE_SCALAR: case RVAL_TYPE_FNCALL: case RVAL_TYPE_CONTAINER: case RVAL_TYPE_NOPROMISEE: return RlistPrependRval(start, RvalNew(item, type)); } assert(false); return NULL; } /*******************************************************************/ int RlistLen(const Rlist *start) { int count = 0; for (const Rlist *rp = start; rp != NULL; rp = rp->next) { count++; } return count; } /*******************************************************************/ Rlist *RlistParseShown(const char *string) { Rlist *newlist = NULL, *splitlist, *rp; /* Parse a string representation generated by ShowList and turn back into Rlist */ splitlist = RlistFromSplitString(string, ','); for (rp = splitlist; rp != NULL; rp = rp->next) { char value[CF_MAXVARSIZE] = { 0 }; sscanf(RlistScalarValue(rp), "%*[{ '\"]%255[^'\"}]", value); RlistAppendScalar(&newlist, value); } RlistDestroy(splitlist); return newlist; } /*******************************************************************/ typedef enum { ST_OPENED, ST_PRECLOSED, ST_CLOSED, ST_IO, ST_ELM1, ST_ELM2, ST_END1, ST_END2, ST_SEP, ST_ERROR } state; #define CLASS_BLANK(x) (((x)==' ')||((x)=='\t')) #define CLASS_START1(x) (((x)=='\'')) #define CLASS_START2(x) (((x)=='"')) #define CLASS_END1(x) ((CLASS_START1(x))) #define CLASS_END2(x) ((CLASS_START2(x))) #define CLASS_BRA1(x) (((x)=='{')) #define CLASS_BRA2(x) (((x)=='}')) #define CLASS_SEP(x) (((x)==',')) #define CLASS_EOL(x) (((x)=='\0')) #define CLASS_ANY0(x) ((!CLASS_BLANK(x))&&(!CLASS_BRA1(x))) #define CLASS_ANY1(x) ((!CLASS_BLANK(x))&&(!CLASS_START1(x))&&(!CLASS_START2(x))) #define CLASS_ANY2(x) ((!CLASS_END1(x))) #define CLASS_ANY3(x) ((!CLASS_END2(x))) #define CLASS_ANY4(x) ((!CLASS_BLANK(x))&&(!CLASS_SEP(x))&&(!CLASS_BRA2(x))) #define CLASS_ANY5(x) ((!CLASS_BLANK(x))&&(!CLASS_SEP(x))&&(!CLASS_BRA2(x))) #define CLASS_ANY6(x) ((!CLASS_BLANK(x))&&(!CLASS_START2(x))&&(!CLASS_START2(x))) #define CLASS_ANY7(x) ((!CLASS_BLANK(x))&&(!CLASS_EOL(x))) /** @brief parse elements in a list passed through use_module @param[in] str: is the string to parse @param[out] newlist: rlist of elements found @retval 0: successful > 0: failed */ static int LaunchParsingMachine(const char *str, Rlist **newlist) { const char *s = str; state current_state = ST_OPENED; int ret; Buffer *buf = BufferNewWithCapacity(CF_MAXVARSIZE); assert(newlist); while (current_state != ST_CLOSED && *s) { switch(current_state) { case ST_ERROR: Log(LOG_LEVEL_ERR, "Parsing error : Malformed string"); ret = 1; goto clean; case ST_OPENED: if (CLASS_BLANK(*s)) { current_state = ST_OPENED; } else if (CLASS_BRA1(*s)) { current_state = ST_IO; } else if (CLASS_ANY0(*s)) { current_state = ST_ERROR; } s++; break; case ST_IO: if (CLASS_BLANK(*s)) { current_state = ST_IO; } else if (CLASS_START1(*s)) { BufferClear(buf); current_state = ST_ELM1; } else if (CLASS_START2(*s)) { BufferClear(buf); current_state = ST_ELM2; } else if (CLASS_ANY1(*s)) { current_state = ST_ERROR; } s++; break; case ST_ELM1: if (CLASS_END1(*s)) { RlistAppendScalar(newlist, BufferData(buf)); BufferClear(buf); current_state = ST_END1; } else if (CLASS_ANY2(*s)) { BufferAppendChar(buf, *s); current_state = ST_ELM1; } s++; break; case ST_ELM2: if (CLASS_END2(*s)) { RlistAppendScalar(newlist, BufferData(buf)); BufferClear(buf); current_state = ST_END2; } else if (CLASS_ANY3(*s)) { BufferAppendChar(buf, *s); current_state = ST_ELM2; } s++; break; case ST_END1: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END1; } else if (CLASS_ANY4(*s)) { current_state = ST_ERROR; } s++; break; case ST_END2: if (CLASS_SEP(*s)) { current_state = ST_SEP; } else if (CLASS_BRA2(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_BLANK(*s)) { current_state = ST_END2; } else if (CLASS_ANY5(*s)) { current_state = ST_ERROR; } s++; break; case ST_SEP: if (CLASS_BLANK(*s)) { current_state = ST_SEP; } else if (CLASS_START1(*s)) { current_state = ST_ELM1; } else if (CLASS_START2(*s)) { current_state = ST_ELM2; } else if (CLASS_ANY6(*s)) { current_state = ST_ERROR; } s++; break; case ST_PRECLOSED: if (CLASS_BLANK(*s)) { current_state = ST_PRECLOSED; } else if (CLASS_EOL(*s)) { current_state = ST_CLOSED; } else if (CLASS_ANY7(*s)) { current_state = ST_ERROR; } s++; break; default: Log(LOG_LEVEL_ERR, "Parsing logic error: unknown state"); ret = 2; goto clean; break; } } if (current_state != ST_CLOSED && current_state != ST_PRECLOSED ) { Log(LOG_LEVEL_ERR, "Parsing error : Malformed string (unexpected end of input)"); ret = 3; goto clean; } BufferDestroy(buf); return 0; clean: BufferDestroy(buf); RlistDestroy(*newlist); assert(ret != 0); return ret; } Rlist *RlistParseString(const char *string) { Rlist *newlist = NULL; if (LaunchParsingMachine(string, &newlist)) { return NULL; } return newlist; } /*******************************************************************/ void RvalDestroy(Rval rval) { if (rval.item == NULL || rval.item == SECRET_RVAL) { return; } switch (rval.type) { case RVAL_TYPE_SCALAR: free(RvalScalarValue(rval)); return; case RVAL_TYPE_LIST: RlistDestroy(RvalRlistValue(rval)); return; case RVAL_TYPE_FNCALL: FnCallDestroy(RvalFnCallValue(rval)); break; case RVAL_TYPE_CONTAINER: JsonDestroy(RvalContainerValue(rval)); break; case RVAL_TYPE_NOPROMISEE: return; } } /*********************************************************************/ void RlistDestroyEntry(Rlist **liststart, Rlist *entry) { if (entry != NULL) { if (entry->val.item) { free(entry->val.item); } Rlist *sp = entry->next; if (entry == *liststart) { *liststart = sp; } else { Rlist *rp = *liststart; while (rp->next != entry) { rp = rp->next; } assert(rp && rp->next == entry); rp->next = sp; } free(entry); } } /*******************************************************************/ /* Copies a -delimited unit from into a new entry in . * * \ is not counted as the separator, but copied to the new entry * as . No other escape sequences are supported. * * Returns the number of bytes read out of ; this may be more * than the length of the new entry in . The new entry is * prepended; the caller can reverse once built. */ static size_t SubStrnCopyChr(Rlist **to, const char *from, char sep, char lstrip) { assert(from && from[0]); size_t offset = 0; while (lstrip != '\0' && from[0] == lstrip && from[0] != '\0') { /* Skip over all instances of the 'lstrip' character (e.g. ' ') if * specified */ from++; offset++; } if (from[0] == '\0') { /* Reached the end already so there's nothing to add to the result list, just tell the caller how far they can move. */ return offset; } const char *end = from; size_t escapes = 0; while (end && end[0] && end[0] != sep) { end = strchr(end, sep); assert(end == NULL || end[0] == sep); if (end && end > from && end[-1] == '\\') { escapes++; end++; } } size_t consume = (end == NULL) ? strlen(from) : (size_t)(end - from); assert(consume >= escapes); char copy[1 + consume - escapes], *dst = copy; for (const char *src = from; src[0] != '\0' && src[0] != sep; src++) { if (src[0] == '\\' && src[1] == sep) { src++; /* Skip over the backslash so we copy the sep */ } dst++[0] = src[0]; } assert(dst + 1 == copy + sizeof(copy)); *dst = '\0'; /* Prepend to the list and reverse when done, costing O(len), * instead of appending, which costs O(len**2). */ RlistPrependRval(to, RvalCopyScalar((Rval) { copy, RVAL_TYPE_SCALAR })); return offset + consume; } Rlist *RlistFromSplitString(const char *string, char sep) /* Splits a string on a separator - e.g. "," - into a linked list of * separate items. Supports escaping separators - e.g. "\," isn't a * separator, it contributes a simple "," in a list entry. */ { if (string == NULL || string[0] == '\0') { return NULL; } Rlist *liststart = NULL; for (const char *sp = string; *sp != '\0';) { sp += SubStrnCopyChr(&liststart, sp, sep, '\0'); assert((size_t) (sp - string) <= strlen(string)); if (*sp) { assert(*sp == sep && (sp == string || sp[-1] != '\\')); sp++; } } RlistReverse(&liststart); return liststart; } /** * Splits the given string into lines. On Windows, both \n and \r\n newlines are * detected. Escaped newlines are respected/ignored too. * * @param detect_crlf whether to try to detect and respect "\r\n" line endings * @return: an #Rlist where items are the individual lines **without** the * trailing newline character(s) * @note: Free the result with RlistDestroy() * @warning: This function doesn't work properly if @string uses "\r\n" newlines * and contains '\r' characters that are not part of any "\r\n" * sequence because it first splits @string on '\r'. */ Rlist *RlistFromStringSplitLines(const char *string, bool detect_crlf) { if (string == NULL || string[0] == '\0') { return NULL; } if (!detect_crlf || (strstr(string, "\r\n") == NULL)) { return RlistFromSplitString(string, '\n'); } /* else we split on '\r' just like RlistFromSplitString() above, but * strip leading '\n' in every chunk, thus effectively split on \r\n. See * the warning in the function's documentation.*/ Rlist *liststart = NULL; for (const char *sp = string; *sp != '\0';) { sp += SubStrnCopyChr(&liststart, sp, '\r', '\n'); assert((size_t) (sp - string) <= strlen(string)); if (*sp) { assert(*sp == '\r' && (sp == string || sp[-1] != '\\')); sp++; } } RlistReverse(&liststart); return liststart; } /*******************************************************************/ Rlist *RlistFromSplitRegex(const char *string, const char *regex, size_t max_entries, bool allow_blanks) { assert(string); if (!string) { return NULL; } const char *sp = string; size_t entry_count = 0; size_t start = 0; size_t end = 0; Rlist *result = NULL; Buffer *buffer = BufferNewWithCapacity(CF_MAXVARSIZE); Regex *rx = CompileRegex(regex); if (rx) { while ((entry_count < max_entries) && StringMatchWithPrecompiledRegex(rx, sp, &start, &end)) { if (end == 0) { break; } BufferClear(buffer); BufferAppend(buffer, sp, start); if (allow_blanks || BufferSize(buffer) > 0) { RlistAppendScalar(&result, BufferData(buffer)); entry_count++; } sp += end; } RegexDestroy(rx); } if (entry_count < max_entries) { BufferClear(buffer); size_t remaining = strlen(sp); BufferAppend(buffer, sp, remaining); if ((allow_blanks && sp != string) || BufferSize(buffer) > 0) { RlistAppendScalar(&result, BufferData(buffer)); } } BufferDestroy(buffer); return result; } /*******************************************************************/ /* * Splits string on regex, returns a list of (at most max) fragments. * * NOTE: in contrast with RlistFromSplitRegex() this one will produce at most max number of elements; * last element will contain everything that lefts from original string (we use everything after * the (max-1)-th separator as the final list element, including any separators that may be embedded in it) */ Rlist *RlistFromRegexSplitNoOverflow(const char *string, const char *regex, int max) { Rlist *liststart = NULL; char node[CF_MAXVARSIZE]; size_t start, end; int count = 0; assert(max > 0); // ensured by FnCallStringSplit() before calling us assert(string != NULL); // ensured by FnCallStringSplit() before calling us const char *sp = string; // We will avoid compiling regex multiple times. Regex *pattern = CompileRegex(regex); if (pattern == NULL) { Log(LOG_LEVEL_DEBUG, "Error compiling regex from '%s'", regex); return NULL; } while (count < max - 1 && StringMatchWithPrecompiledRegex(pattern, sp, &start, &end)) { size_t len = start; if (len >= CF_MAXVARSIZE) { len = CF_MAXVARSIZE - 1; Log(LOG_LEVEL_WARNING, "Segment in string_split() is %zu bytes and will be truncated to %zu bytes", start, len); } memcpy(node, sp, len); node[len] = '\0'; RlistAppendScalar(&liststart, node); count++; sp += end; } assert(count < max); RlistAppendScalar(&liststart, sp); RegexDestroy(pattern); return liststart; } Rlist *RlistLast(Rlist *start) { if (start == NULL) { return NULL; } Rlist *rp = start; while (rp->next != NULL) { rp = rp->next; } return rp; } void RlistFilter(Rlist **list, bool (*KeepPredicate)(void *, void *), void *predicate_user_data, void (*DestroyItem)(void *)) { assert(KeepPredicate); Rlist *start = *list, *prev = NULL, *next; for (Rlist *rp = start; rp; rp = next) { next = rp->next; if (KeepPredicate(RlistScalarValue(rp), predicate_user_data)) { prev = rp; } else { if (prev) { prev->next = next; } else { assert(rp == *list); *list = next; } if (DestroyItem) { DestroyItem(rp->val.item); rp->val.item = NULL; } rp->next = NULL; RlistDestroy(rp); } } } void RlistReverse(Rlist **list) { Rlist *prev = NULL; while (*list) { Rlist *tmp = *list; *list = (*list)->next; tmp->next = prev; prev = tmp; } *list = prev; } void RlistWrite(Writer *writer, const Rlist *list) { WriterWrite(writer, " {"); for (const Rlist *rp = list; rp != NULL; rp = rp->next) { RvalWriteQuoted(writer, rp->val); if (rp->next != NULL) { WriterWriteChar(writer, ','); } } WriterWriteChar(writer, '}'); } void ScalarWrite(Writer *writer, const char *s, bool quote, bool raw) { if (quote) { WriterWriteChar(writer, '"'); } for (; *s; s++) { if (*s == '"' && !raw) { WriterWriteChar(writer, '\\'); } WriterWriteChar(writer, *s); } if (quote) { WriterWriteChar(writer, '"'); } } static void RvalWriteParts(Writer *writer, const void* item, RvalType type, bool quote, bool raw) { if (item == NULL) { return; } switch (type) { case RVAL_TYPE_SCALAR: ScalarWrite(writer, item, quote, raw); break; case RVAL_TYPE_LIST: RlistWrite(writer, item); break; case RVAL_TYPE_FNCALL: FnCallWrite(writer, item); break; case RVAL_TYPE_NOPROMISEE: WriterWrite(writer, "(no-one)"); break; case RVAL_TYPE_CONTAINER: JsonWrite(writer, item, 0); break; } } void RvalWrite(Writer *writer, Rval rval) { RvalWriteParts(writer, rval.item, rval.type, false, false); } void RvalWriteQuoted(Writer *writer, Rval rval) { RvalWriteParts(writer, rval.item, rval.type, true, false); } void RvalWriteRaw(Writer *writer, Rval rval) { RvalWriteParts(writer, rval.item, rval.type, false, true); } char *RvalToString(Rval rval) { Writer *w = StringWriter(); RvalWrite(w, rval); return StringWriterClose(w); } char *RlistToString(const Rlist *rlist) { Writer *w = StringWriter(); RlistWrite(w, rlist); return StringWriterClose(w); } unsigned RvalHash(Rval rval, unsigned seed) { switch (rval.type) { case RVAL_TYPE_SCALAR: return StringHash(RvalScalarValue(rval), seed); case RVAL_TYPE_FNCALL: return FnCallHash(RvalFnCallValue(rval), seed); case RVAL_TYPE_LIST: return RlistHash(RvalRlistValue(rval), seed); case RVAL_TYPE_NOPROMISEE: /* TODO modulus operation is biasing results. */ return (seed + 1); default: ProgrammingError("Unhandled case in switch: %d", rval.type); } } unsigned int RlistHash(const Rlist *list, unsigned seed) { unsigned hash = seed; for (const Rlist *rp = list; rp; rp = rp->next) { hash = RvalHash(rp->val, hash); } return hash; } unsigned int RlistHash_untyped(const void *list, unsigned seed) { return RlistHash(list, seed); } static JsonElement *FnCallToJson(const FnCall *fp) { assert(fp); JsonElement *object = JsonObjectCreate(3); JsonObjectAppendString(object, "name", fp->name); JsonObjectAppendString(object, "type", "function-call"); JsonElement *argsArray = JsonArrayCreate(5); for (Rlist *rp = fp->args; rp != NULL; rp = rp->next) { switch (rp->val.type) { case RVAL_TYPE_SCALAR: JsonArrayAppendString(argsArray, RlistScalarValue(rp)); break; case RVAL_TYPE_FNCALL: JsonArrayAppendObject(argsArray, FnCallToJson(RlistFnCallValue(rp))); break; default: assert(false && "Unknown argument type"); break; } } JsonObjectAppendArray(object, "arguments", argsArray); return object; } static JsonElement *RlistToJson(Rlist *list) { JsonElement *array = JsonArrayCreate(RlistLen(list)); for (Rlist *rp = list; rp; rp = rp->next) { switch (rp->val.type) { case RVAL_TYPE_SCALAR: JsonArrayAppendString(array, RlistScalarValue(rp)); break; case RVAL_TYPE_LIST: JsonArrayAppendArray(array, RlistToJson(RlistRlistValue(rp))); break; case RVAL_TYPE_FNCALL: JsonArrayAppendObject(array, FnCallToJson(RlistFnCallValue(rp))); break; default: ProgrammingError("Unsupported item type in rlist"); break; } } return array; } JsonElement *RvalToJson(Rval rval) { /* Only empty Rlist can be NULL. */ assert(rval.item || rval.type == RVAL_TYPE_LIST); switch (rval.type) { case RVAL_TYPE_SCALAR: return JsonStringCreate(RvalScalarValue(rval)); case RVAL_TYPE_LIST: return RlistToJson(RvalRlistValue(rval)); case RVAL_TYPE_FNCALL: return FnCallToJson(RvalFnCallValue(rval)); case RVAL_TYPE_CONTAINER: return JsonCopy(RvalContainerValue(rval)); case RVAL_TYPE_NOPROMISEE: assert(false); return JsonObjectCreate(1); } assert(false); return NULL; } /** * @brief Flattens an Rlist by expanding naked scalar list-variable * members. Flattening is only one-level deep. */ void RlistFlatten(EvalContext *ctx, Rlist **list) { Rlist *next; for (Rlist *rp = *list; rp != NULL; rp = next) { next = rp->next; if (rp->val.type == RVAL_TYPE_SCALAR && IsNakedVar(RlistScalarValue(rp), '@')) { char naked[CF_MAXVARSIZE]; GetNaked(naked, RlistScalarValue(rp)); /* Make sure there are no inner expansions to take place, like if * rp was "@{blah_$(blue)}". */ if (!IsExpandable(naked)) { Log(LOG_LEVEL_DEBUG, "Flattening slist: %s", RlistScalarValue(rp)); VarRef *ref = VarRefParse(naked); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); if (value_type == CF_DATA_TYPE_NONE) { assert(value == NULL); continue; /* undefined variable */ } if (DataTypeToRvalType(value_type) != RVAL_TYPE_LIST) { Log(LOG_LEVEL_WARNING, "'%s' failed - variable is not list but %s", RlistScalarValue(rp), DataTypeToString(value_type)); continue; } /* NOTE: Remember that value can be NULL as an empty Rlist. */ /* at_node: just a mnemonic name for the list node with @{blah}. */ Rlist *at_node = rp; Rlist *insert_after = at_node; for (const Rlist *rp2 = value; rp2 != NULL; rp2 = rp2->next) { assert(insert_after != NULL); RlistInsertAfter(insert_after, RvalCopy(rp2->val)); insert_after = insert_after->next; } /* Make sure we won't miss any element. */ assert(insert_after->next == next); RlistDestroyEntry(list, at_node); /* Delete @{blah} entry */ char *list_s = RlistToString(*list); Log(LOG_LEVEL_DEBUG, "Flattened slist: %s", list_s); free(list_s); } } } } bool RlistEqual(const Rlist *list1, const Rlist *list2) { const Rlist *rp1, *rp2; for (rp1 = list1, rp2 = list2; rp1 != NULL && rp2 != NULL; rp1 = rp1->next, rp2 = rp2->next) { if (rp1->val.item != NULL && rp2->val.item != NULL) { if (rp1->val.type == RVAL_TYPE_FNCALL || rp2->val.type == RVAL_TYPE_FNCALL) { return false; // inconclusive } const Rlist *rc1 = rp1; const Rlist *rc2 = rp2; // Check for list nesting with { fncall(), "x" ... } if (rp1->val.type == RVAL_TYPE_LIST) { rc1 = rp1->val.item; } if (rp2->val.type == RVAL_TYPE_LIST) { rc2 = rp2->val.item; } if (IsCf3VarString(rc1->val.item) || IsCf3VarString(rp2->val.item)) { return false; // inconclusive } if (strcmp(rc1->val.item, rc2->val.item) != 0) { return false; } } else if ((rp1->val.item != NULL && rp2->val.item == NULL) || (rp1->val.item == NULL && rp2->val.item != NULL)) { return false; } else { assert(rp1->val.item == NULL && rp2->val.item == NULL); } } // return false if lengths are different return (rp1 == NULL && rp2 == NULL); } bool RlistEqual_untyped(const void *list1, const void *list2) { return RlistEqual(list1, list2); } /*******************************************************************/ static void RlistAppendContainerPrimitive(Rlist **list, const JsonElement *primitive) { assert(JsonGetElementType(primitive) == JSON_ELEMENT_TYPE_PRIMITIVE); switch (JsonGetPrimitiveType(primitive)) { case JSON_PRIMITIVE_TYPE_BOOL: RlistAppendScalar(list, JsonPrimitiveGetAsBool(primitive) ? "true" : "false"); break; case JSON_PRIMITIVE_TYPE_INTEGER: { char *str = StringFromLong(JsonPrimitiveGetAsInteger(primitive)); RlistAppendScalar(list, str); free(str); } break; case JSON_PRIMITIVE_TYPE_REAL: { char *str = StringFromDouble(JsonPrimitiveGetAsReal(primitive)); RlistAppendScalar(list, str); free(str); } break; case JSON_PRIMITIVE_TYPE_STRING: RlistAppendScalar(list, JsonPrimitiveGetAsString(primitive)); break; case JSON_PRIMITIVE_TYPE_NULL: break; } } Rlist *RlistFromContainer(const JsonElement *container) { Rlist *list = NULL; switch (JsonGetElementType(container)) { case JSON_ELEMENT_TYPE_PRIMITIVE: RlistAppendContainerPrimitive(&list, container); break; case JSON_ELEMENT_TYPE_CONTAINER: { JsonIterator iter = JsonIteratorInit(container); const JsonElement *child; while (NULL != (child = JsonIteratorNextValue(&iter))) { if (JsonGetElementType(child) == JSON_ELEMENT_TYPE_PRIMITIVE) { RlistAppendContainerPrimitive(&list, child); } } } break; } return list; } cfengine-3.24.2/libpromises/expand.c0000644000000000000000000012324415010704253017334 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** * VARIABLES AND PROMISE EXPANSION * * Expanding variables is easy -- expanding lists automagically requires * some thought. Remember that * * promiser <=> RVAL_TYPE_SCALAR * promisee <=> RVAL_TYPE_LIST * * For bodies we have * * lval <=> RVAL_TYPE_LIST | RVAL_TYPE_SCALAR * * Any list or container variable occurring within a scalar or in place of a * scalar is assumed to be iterated i.e. $(name). See comments in iteration.c. * * Any list variable @(name) is *not iterated*, but dropped into place (see * DeRefCopyPromise()). * * Please note that bodies cannot contain iterators. * * The full process of promise and variable expansion is mostly outlined in * ExpandPromise() and ExpandPromiseAndDo() and the basic steps are: * * + Skip everything if the class guard is not defined. * * + DeRefCopyPromise(): *Copy the promise* while expanding '@' slists and body * arguments and handling body inheritance. This requires one round of * expansion with scopeid "body". * * + Push promise frame * * + MapIteratorsFromRval(): Parse all strings (promiser-promisee-constraints), * find all unexpanded variables, mangle them if needed (if they are * namespaced/scoped), and *initialise the wheels* in the iteration engine * (iterctx) to iterate over iterable variables (slists and containers). See * comments in iteration.c for further details. * * + For every iteration: * * - Push iteration frame * * - EvalContextStackPushPromiseIterationFrame()->ExpandDeRefPromise(): Make * another copy of the promise with all constraints evaluated and variables * expanded. * * -- NOTE: As a result all *functions are also evaluated*, even if they are * not to be used immediately (for example promises that the actuator skips * because of ifvarclass, see promises.c:ExpandDeRefPromise() ). * * -- (TODO IS IT CORRECT?) In a sub-bundle, create a new context and make * hashes of the the transferred variables in the temporary context * * - Run the actuator (=act_on_promise= i.e. =VerifyWhateverPromise()=) * * - Pop iteration frame * * + Pop promise frame * */ static inline char opposite(char c); static void PutHandleVariable(EvalContext *ctx, const Promise *pp) { char *handle_s; const char *existing_handle = PromiseGetHandle(pp); if (existing_handle != NULL) { // This ordering is necessary to get automated canonification handle_s = ExpandScalar(ctx, NULL, "this", existing_handle, NULL); CanonifyNameInPlace(handle_s); } else { handle_s = xstrdup(PromiseID(pp)); /* default handle */ } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", handle_s, CF_DATA_TYPE_STRING, "source=promise"); free(handle_s); } /** * Recursively go down the #rval and run PromiseIteratorPrepare() to take note * of all iterables and mangle all rvals than need to be mangled before * iterating. */ static void MapIteratorsFromRval(EvalContext *ctx, PromiseIterator *iterctx, Rval rval) { switch (rval.type) { case RVAL_TYPE_SCALAR: PromiseIteratorPrepare(iterctx, ctx, RvalScalarValue(rval)); break; case RVAL_TYPE_LIST: for (const Rlist *rp = RvalRlistValue(rval); rp != NULL; rp = rp->next) { MapIteratorsFromRval(ctx, iterctx, rp->val); } break; case RVAL_TYPE_FNCALL: { char *fn_name = RvalFnCallValue(rval)->name; /* Check function name. */ PromiseIteratorPrepare(iterctx, ctx, fn_name); /* Check each of the function arguments. */ /* EXCEPT on functions that use special variables: the mangled * variables would never be resolved if they contain inner special * variables (for example "$(bundle.A[$(this.k)])" and the returned * slist would contained mangled vars like "bundle#A[1]" which would * never resolve in future iterations. By skipping the iteration * engine for now, the function returns an slist with unmangled * entries, and the iteration engine works correctly on the next * pass! */ if (strcmp(fn_name, "maplist") != 0 && strcmp(fn_name, "mapdata") != 0 && strcmp(fn_name, "maparray")!= 0) { for (Rlist *rp = RvalFnCallValue(rval)->args; rp != NULL; rp = rp->next) { MapIteratorsFromRval(ctx, iterctx, rp->val); } } break; } case RVAL_TYPE_CONTAINER: case RVAL_TYPE_NOPROMISEE: break; } } static PromiseResult ExpandPromiseAndDo(EvalContext *ctx, PromiseIterator *iterctx, PromiseActuator *act_on_promise, void *param, bool actuate_ifelse) { PromiseResult result = PROMISE_RESULT_SKIPPED; /* In the case of ifelse() we must always include an extra round of "actuation" * in the while loop below. PromiseIteratorNext() will return false in the case * that there are doubly-unresolved Rvals like $($(missing)). * We can't add an empty wheel because that is skipped as well as noted in * libpromises/iteration.c ShouldAddVariableAsIterationWheel(). */ bool ifelse_actuated = !actuate_ifelse; /* TODO this loop could be completely skipped for for non vars/classes if * act_on_promise is CommonEvalPromise(). */ while (PromiseIteratorNext(iterctx, ctx) || !ifelse_actuated) { /* * ACTUAL WORK PART 1: Get a (another) copy of the promise. * * Basically this evaluates all constraints. As a result it evaluates * all functions, even if they are not to be used immediately (for * example promises that the actuator skips because of ifvarclass). */ const Promise *pexp = /* expanded promise */ EvalContextStackPushPromiseIterationFrame(ctx, iterctx); if (pexp == NULL) /* is the promise excluded? */ { result = PromiseResultUpdate(result, PROMISE_RESULT_SKIPPED); ifelse_actuated = true; continue; } /* ACTUAL WORK PART 2: run the actuator */ PromiseResult iteration_result = act_on_promise(ctx, pexp, param); /* iteration_result is always NOOP for PRE-EVAL. */ result = PromiseResultUpdate(result, iteration_result); /* Redmine#6484: Do not store promise handles during PRE-EVAL, to * avoid package promise always running. */ if (act_on_promise != &CommonEvalPromise) { NotifyDependantPromises(ctx, pexp, iteration_result); } /* EVALUATE VARS PROMISES again, allowing redefinition of * variables. The theory behind this is that the "sampling rate" of * vars promise needs to be double than the rest. */ if (strcmp(PromiseGetPromiseType(pexp), "vars") == 0 || strcmp(PromiseGetPromiseType(pexp), "meta") == 0) { if (act_on_promise != &VerifyVarPromise) { VerifyVarPromise(ctx, pexp, NULL); } } /* Why do we push/pop an iteration frame, if all iterated variables * are Put() on the previous scope? */ EvalContextStackPopFrame(ctx); ifelse_actuated = true; } return result; } PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp, PromiseActuator *act_on_promise, void *param) { assert(pp != NULL); if (!IsDefinedClass(ctx, pp->classes)) { Log(LOG_LEVEL_DEBUG, "Skipping %s promise expansion with promiser '%s' due to class guard '%s::' (pass %d)", PromiseGetPromiseType(pp), pp->promiser, pp->classes, EvalContextGetPass(ctx)); return PROMISE_RESULT_SKIPPED; } /* 1. Copy the promise while expanding '@' slists and body arguments * (including body inheritance). */ Promise *pcopy = DeRefCopyPromise(ctx, pp); EvalContextStackPushPromiseFrame(ctx, pcopy); PromiseIterator *iterctx = PromiseIteratorNew(pcopy); /* 2. Parse all strings (promiser-promisee-constraints), find all unexpanded variables, mangle them if needed (if they are namespaced/scoped), and start the iteration engine (iterctx) to iterate over slists and containers. */ MapIteratorsFromRval(ctx, iterctx, (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR }); if (pcopy->promisee.item != NULL) { MapIteratorsFromRval(ctx, iterctx, pcopy->promisee); } bool actuate_ifelse = false; for (size_t i = 0; i < SeqLength(pcopy->conlist); i++) { Constraint *cp = SeqAt(pcopy->conlist, i); if (cp->rval.type == RVAL_TYPE_FNCALL && strcmp(RvalFnCallValue(cp->rval)->name, "ifelse") == 0) { actuate_ifelse = true; } MapIteratorsFromRval(ctx, iterctx, cp->rval); } /* 3. GO! */ PutHandleVariable(ctx, pcopy); PromiseResult result = ExpandPromiseAndDo(ctx, iterctx, act_on_promise, param, actuate_ifelse); EvalContextStackPopFrame(ctx); PromiseIteratorDestroy(iterctx); PromiseDestroy(pcopy); return result; } /*********************************************************************/ /*********************************************************************/ Rval ExpandPrivateRval(const EvalContext *ctx, const char *ns, const char *scope, const void *rval_item, RvalType rval_type) { Rval returnval; returnval.item = NULL; returnval.type = RVAL_TYPE_NOPROMISEE; switch (rval_type) { case RVAL_TYPE_SCALAR: returnval.item = ExpandScalar(ctx, ns, scope, rval_item, NULL); returnval.type = RVAL_TYPE_SCALAR; break; case RVAL_TYPE_LIST: returnval.item = ExpandList(ctx, ns, scope, rval_item, true); returnval.type = RVAL_TYPE_LIST; break; case RVAL_TYPE_FNCALL: returnval.item = ExpandFnCall(ctx, ns, scope, rval_item); returnval.type = RVAL_TYPE_FNCALL; break; case RVAL_TYPE_CONTAINER: returnval = RvalNew(rval_item, RVAL_TYPE_CONTAINER); break; case RVAL_TYPE_NOPROMISEE: break; } return returnval; } /** * Detects a variable expansion inside of a data/list reference, for example * "@(${container_name})" or "@(prefix${container_name})" or * "@(nspace:${container_name})" or "@(container_name[${field}])". * * @note This function doesn't have to be bullet-proof, it only needs to * properly detect valid cases. The rest is left to the parser and code * expanding variables. */ static inline bool VariableDataOrListReference(const char *str) { assert(str != NULL); size_t len = strlen(str); /* at least '@($(X))' is needed */ if (len < 7) { return false; } if (!((str[0] == '@') && ((str[1] == '{') || (str[1] == '(')))) { return false; } /* Check if, after '@(', there are only * - characters allowed in data/list names or * - ':' to separate namespace from the name or * - '.' to separate bundle and variable name or, * - '[' for data/list field/index specification, * followed by "$(" or "${" with a matching close bracket somewhere. */ for (size_t i = 2; i < len; i++) { if (!(isalnum((int) str[i]) || (str[i] == '_') || (str[i] == ':') || (str[i] == '$') || (str[i] == '.') || (str[i] == '['))) { return false; } if (str[i] == '$') { if (((i + 1) < len) && ((str[i + 1] == '{') || (str[i + 1] == '('))) { int close_bracket = (int) opposite(str[i+1]); return (strchr(str + i + 2, close_bracket) != NULL); } else { return false; } } } return false; } static Rval ExpandListEntry(const EvalContext *ctx, const char *ns, const char *scope, int expandnaked, Rval entry) { Rval expanded_data_list = {0}; /* If rval is something like '@($(container_name).field)', we need to expand * the nested variable first. */ if (entry.type == RVAL_TYPE_SCALAR && VariableDataOrListReference(entry.item)) { entry = ExpandPrivateRval(ctx, ns, scope, entry.item, entry.type); expanded_data_list = entry; } if (entry.type == RVAL_TYPE_SCALAR && IsNakedVar(entry.item, '@')) { if (expandnaked) { char naked[CF_MAXVARSIZE]; GetNaked(naked, entry.item); if (IsExpandable(naked)) { char *exp = ExpandScalar(ctx, ns, scope, naked, NULL); strlcpy(naked, exp, sizeof(naked)); /* TODO err */ free(exp); } /* Check again, it might have changed. */ if (!IsExpandable(naked)) { VarRef *ref = VarRefParseFromScope(naked, scope); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); if (value_type != CF_DATA_TYPE_NONE) /* variable found? */ { Rval ret = ExpandPrivateRval(ctx, ns, scope, value, DataTypeToRvalType(value_type)); RvalDestroy(expanded_data_list); return ret; } } } else { Rval ret = RvalNew(entry.item, RVAL_TYPE_SCALAR); RvalDestroy(expanded_data_list); return ret; } } Rval ret = ExpandPrivateRval(ctx, ns, scope, entry.item, entry.type); RvalDestroy(expanded_data_list); return ret; } Rlist *ExpandList(const EvalContext *ctx, const char *ns, const char *scope, const Rlist *list, int expandnaked) { Rlist *start = NULL; for (const Rlist *rp = list; rp != NULL; rp = rp->next) { Rval returnval = ExpandListEntry(ctx, ns, scope, expandnaked, rp->val); RlistAppend(&start, returnval.item, returnval.type); RvalDestroy(returnval); } return start; } /*********************************************************************/ Rval ExpandBundleReference(EvalContext *ctx, const char *ns, const char *scope, Rval rval) { // Allocates new memory for the copy switch (rval.type) { case RVAL_TYPE_SCALAR: return (Rval) { ExpandScalar(ctx, ns, scope, RvalScalarValue(rval), NULL), RVAL_TYPE_SCALAR }; case RVAL_TYPE_FNCALL: return (Rval) { ExpandFnCall(ctx, ns, scope, RvalFnCallValue(rval)), RVAL_TYPE_FNCALL}; case RVAL_TYPE_CONTAINER: case RVAL_TYPE_LIST: case RVAL_TYPE_NOPROMISEE: return RvalNew(NULL, RVAL_TYPE_NOPROMISEE); } assert(false); return RvalNew(NULL, RVAL_TYPE_NOPROMISEE); } /** * Expand a #string into Buffer #out, returning the pointer to the string * itself, inside the Buffer #out. If #out is NULL then the buffer will be * created and destroyed internally. * * @retval NULL something went wrong */ char *ExpandScalar(const EvalContext *ctx, const char *ns, const char *scope, const char *string, Buffer *out) { bool out_belongs_to_us = false; if (out == NULL) { out = BufferNew(); out_belongs_to_us = true; } assert(string != NULL); assert(out != NULL); Buffer *current_item = BufferNew(); for (const char *sp = string; *sp != '\0'; sp++) { BufferClear(current_item); ExtractScalarPrefix(current_item, sp, strlen(sp)); BufferAppend(out, BufferData(current_item), BufferSize(current_item)); sp += BufferSize(current_item); if (*sp == '\0') { break; } BufferClear(current_item); char varstring = sp[1]; ExtractScalarReference(current_item, sp, strlen(sp), true); sp += BufferSize(current_item) + 2; if (IsCf3VarString(BufferData(current_item))) { Buffer *temp = BufferCopy(current_item); BufferClear(current_item); ExpandScalar(ctx, ns, scope, BufferData(temp), current_item); BufferDestroy(temp); } if (!IsExpandable(BufferData(current_item))) { VarRef *ref = VarRefParseFromNamespaceAndScope( BufferData(current_item), ns, scope, CF_NS, '.'); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); switch (DataTypeToRvalType(value_type)) { case RVAL_TYPE_SCALAR: assert(value != NULL); BufferAppendString(out, value); continue; break; case RVAL_TYPE_CONTAINER: { assert(value != NULL); const JsonElement *jvalue = value; /* instead of casts */ if (JsonGetElementType(jvalue) == JSON_ELEMENT_TYPE_PRIMITIVE) { BufferAppendString(out, JsonPrimitiveGetAsString(jvalue)); continue; } break; } default: /* TODO Log() */ break; } } if (varstring == '{') { BufferAppendF(out, "${%s}", BufferData(current_item)); } else { BufferAppendF(out, "$(%s)", BufferData(current_item)); } } BufferDestroy(current_item); LogDebug(LOG_MOD_EXPAND, "Expanded scalar '%s' to '%s' using %s namespace and %s scope.", string, BufferData(out), (ns == NULL) ? "current" : ns, (scope == NULL) ? "current" : scope); return out_belongs_to_us ? BufferClose(out) : BufferGet(out); } /*********************************************************************/ Rval EvaluateFinalRval(EvalContext *ctx, const Policy *policy, const char *ns, const char *scope, Rval rval, bool forcelist, const Promise *pp) { assert(ctx); assert(policy); Rval returnval; /* Treat lists specially. */ if (rval.type == RVAL_TYPE_SCALAR && IsNakedVar(rval.item, '@')) { char naked[CF_MAXVARSIZE]; GetNaked(naked, rval.item); if (IsExpandable(naked)) /* example: @(blah_$(blue)) */ { returnval = ExpandPrivateRval(ctx, NULL, "this", rval.item, rval.type); } else { VarRef *ref = VarRefParseFromScope(naked, scope); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); if (DataTypeToRvalType(value_type) == RVAL_TYPE_LIST) { returnval.item = ExpandList(ctx, ns, scope, value, true); returnval.type = RVAL_TYPE_LIST; } else { returnval = ExpandPrivateRval(ctx, NULL, "this", rval.item, rval.type); } } } else if (forcelist) /* We are replacing scalar @(name) with list */ { returnval = ExpandPrivateRval(ctx, ns, scope, rval.item, rval.type); } else if (FnCallIsBuiltIn(rval)) { returnval = RvalCopy(rval); } else { returnval = ExpandPrivateRval(ctx, NULL, "this", rval.item, rval.type); } switch (returnval.type) { case RVAL_TYPE_SCALAR: case RVAL_TYPE_CONTAINER: break; case RVAL_TYPE_LIST: for (Rlist *rp = RvalRlistValue(returnval); rp; rp = rp->next) { switch (rp->val.type) { case RVAL_TYPE_FNCALL: { FnCall *fp = RlistFnCallValue(rp); rp->val = FnCallEvaluate(ctx, policy, fp, pp).rval; FnCallDestroy(fp); break; } case RVAL_TYPE_SCALAR: if (EvalContextStackCurrentPromise(ctx) && IsCf3VarString(RlistScalarValue(rp))) { void *prior = rp->val.item; rp->val = ExpandPrivateRval(ctx, NULL, "this", prior, RVAL_TYPE_SCALAR); free(prior); } /* else: returnval unchanged. */ break; default: assert(!"Bad type for entry in Rlist"); } } break; case RVAL_TYPE_FNCALL: if (FnCallIsBuiltIn(returnval)) { FnCall *fp = RvalFnCallValue(returnval); returnval = FnCallEvaluate(ctx, policy, fp, pp).rval; FnCallDestroy(fp); } break; default: assert(returnval.item == NULL); /* else we're leaking it */ returnval.item = NULL; returnval.type = RVAL_TYPE_NOPROMISEE; break; } return returnval; } /*********************************************************************/ void BundleResolvePromiseType(EvalContext *ctx, const Bundle *bundle, const char *type, PromiseActuator *actuator) { for (size_t j = 0; j < SeqLength(bundle->sections); j++) { BundleSection *section = SeqAt(bundle->sections, j); if (strcmp(section->promise_type, type) == 0) { EvalContextStackPushBundleSectionFrame(ctx, section); for (size_t i = 0; i < SeqLength(section->promises); i++) { Promise *pp = SeqAt(section->promises, i); ExpandPromise(ctx, pp, actuator, NULL); } EvalContextStackPopFrame(ctx); } } } static int PointerCmp(const void *a, const void *b, ARG_UNUSED void *user_data) { if (a < b) { return -1; } else if (a == b) { return 0; } else { return 1; } } static void RemoveRemotelyInjectedVars(const EvalContext *ctx, const Bundle *bundle) { const Seq *remote_var_promises = EvalContextGetRemoteVarPromises(ctx, bundle->name); if ((remote_var_promises == NULL) || SeqLength(remote_var_promises) == 0) { /* nothing to do here */ return; } size_t promises_length = SeqLength(remote_var_promises); Seq *remove_vars = SeqNew(promises_length, NULL); /* remove variables that have been attempted to be inserted into this * bundle */ /* TODO: this is expensive and should be removed! */ for (size_t i = 0; i < promises_length; i++) { const Promise *pp = (Promise *) SeqAt(remote_var_promises, i); VariableTableIterator *iter = EvalContextVariableTableIteratorNew(ctx, NULL, bundle->name, NULL); const Variable *var = VariableTableIteratorNext(iter); while (var != NULL) { /* variables are stored together with their original promises (org_pp) */ const Promise *var_promise = VariableGetPromise(var); const VarRef *var_ref = VariableGetRef(var); if (var_promise && var_promise->org_pp == pp) { Log(LOG_LEVEL_ERR, "Ignoring remotely-injected variable '%s'", var_ref->lval); /* avoid modifications of the variable table being iterated * over and avoid trying to remove the same variable twice */ SeqAppendOnce(remove_vars, (void *) var, PointerCmp); } var = VariableTableIteratorNext(iter); } VariableTableIteratorDestroy(iter); } /* iteration over the variable table done, time to remove the variables */ size_t remove_vars_length = SeqLength(remove_vars); for (size_t i = 0; i < remove_vars_length; i++) { Variable *var = (Variable *) SeqAt(remove_vars, i); const VarRef *var_ref = VariableGetRef(var); if (var_ref != NULL) { EvalContextVariableRemove(ctx, var_ref); } } SeqDestroy(remove_vars); } void BundleResolve(EvalContext *ctx, const Bundle *bundle) { Log(LOG_LEVEL_DEBUG, "Resolving classes and variables in 'bundle %s %s'", bundle->type, bundle->name); /* first check if some variables were injected remotely into this bundle and * remove them (CFE-1915) */ RemoveRemotelyInjectedVars(ctx, bundle); /* PRE-EVAL: evaluate classes of common bundles. */ if (strcmp(bundle->type, "common") == 0) { /* Necessary to parse vars *before* classes for cases like this: * 00_basics/04_bundles/dynamic_bundlesequence/dynamic_inputs_based_on_class_set_using_variable_file_control_extends_inputs.cf.sub * -- see bundle "classify". */ BundleResolvePromiseType(ctx, bundle, "vars", VerifyVarPromise); BundleResolvePromiseType(ctx, bundle, "classes", VerifyClassPromise); } /* Necessary to also parse vars *after* classes, * because "inputs" might be affected in cases like: * 00_basics/04_bundles/dynamic_bundlesequence/dynamic_inputs_based_on_list_variable_dependent_on_class.cf */ BundleResolvePromiseType(ctx, bundle, "vars", VerifyVarPromise); } /** * Evaluate the relevant control body, and set the * relevant fields in #ctx and #config. */ static void ResolveControlBody(EvalContext *ctx, GenericAgentConfig *config, const Body *control_body) { const char *filename = control_body->source_path; assert(CFG_CONTROLBODY[COMMON_CONTROL_MAX].lval == NULL); const ConstraintSyntax *body_syntax = NULL; for (int i = 0; CONTROL_BODIES[i].constraints != NULL; i++) { body_syntax = CONTROL_BODIES[i].constraints; if (strcmp(control_body->type, CONTROL_BODIES[i].body_type) == 0) { break; } } if (body_syntax == NULL) { FatalError(ctx, "Unknown control body: %s", control_body->type); } char *scope; assert(strcmp(control_body->name, "control") == 0); xasprintf(&scope, "control_%s", control_body->type); Log(LOG_LEVEL_DEBUG, "Initiate control variable convergence for scope '%s'", scope); EvalContextStackPushBodyFrame(ctx, NULL, control_body, NULL); for (size_t i = 0; i < SeqLength(control_body->conlist); i++) { const char *lval; Rval evaluated_rval; size_t lineno; /* Use nested scope to constrain cp. */ { Constraint *cp = SeqAt(control_body->conlist, i); lval = cp->lval; lineno = cp->offset.line; if (!IsDefinedClass(ctx, cp->classes)) { continue; } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_BUNDLESEQUENCE].lval) == 0) { evaluated_rval = ExpandPrivateRval(ctx, NULL, scope, cp->rval.item, cp->rval.type); } else { evaluated_rval = EvaluateFinalRval(ctx, control_body->parent_policy, NULL, scope, cp->rval, true, NULL); } } /* Close scope: assert we only use evaluated_rval, not cp->rval. */ VarRef *ref = VarRefParseFromScope(lval, scope); EvalContextVariableRemove(ctx, ref); DataType rval_proper_datatype = ConstraintSyntaxGetDataType(body_syntax, lval); if (evaluated_rval.type != DataTypeToRvalType(rval_proper_datatype)) { Log(LOG_LEVEL_ERR, "Attribute '%s' in %s:%zu is of wrong type, skipping", lval, filename, lineno); VarRefDestroy(ref); RvalDestroy(evaluated_rval); continue; } bool success = EvalContextVariablePut( ctx, ref, evaluated_rval.item, rval_proper_datatype, "source=promise"); if (!success) { Log(LOG_LEVEL_ERR, "Attribute '%s' in %s:%zu can't be added, skipping", lval, filename, lineno); VarRefDestroy(ref); RvalDestroy(evaluated_rval); continue; } VarRefDestroy(ref); if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_OUTPUT_PREFIX].lval) == 0) { strlcpy(VPREFIX, RvalScalarValue(evaluated_rval), sizeof(VPREFIX)); } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_DOMAIN].lval) == 0) { strlcpy(VDOMAIN, RvalScalarValue(evaluated_rval), sizeof(VDOMAIN)); Log(LOG_LEVEL_VERBOSE, "SET domain = %s", VDOMAIN); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_SYS, "domain"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "domain", VDOMAIN, CF_DATA_TYPE_STRING, "source=agent"); EvalContextClassPutHard(ctx, VDOMAIN, "source=agent"); int ret = snprintf(VFQNAME, CF_MAXVARSIZE, "%s.%s", VUQNAME, VDOMAIN); assert(ret >= 0 && ret < CF_MAXVARSIZE); if (ret < 0 || ret >= CF_MAXVARSIZE) { Log(LOG_LEVEL_ERR, "Failed to update variable default:sys.fqhost to include domain name: " "Maximum variable size was exceeded (%d >= %d)", ret, CF_MAXVARSIZE); } else { EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_SYS, "fqhost"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "fqhost", VFQNAME, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=Host name"); } } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_IGNORE_MISSING_INPUTS].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "SET ignore_missing_inputs %s", RvalScalarValue(evaluated_rval)); if (StringIsBoolean(RvalScalarValue(evaluated_rval))) { config->ignore_missing_inputs = BooleanFromString( RvalScalarValue(evaluated_rval)); } } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_IGNORE_MISSING_BUNDLES].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "SET ignore_missing_bundles %s", RvalScalarValue(evaluated_rval)); if (StringIsBoolean(RvalScalarValue(evaluated_rval))) { config->ignore_missing_bundles = BooleanFromString( RvalScalarValue(evaluated_rval)); } } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_CACHE_SYSTEM_FUNCTIONS].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "SET cache_system_functions %s", RvalScalarValue(evaluated_rval)); bool cache_system_functions = BooleanFromString( RvalScalarValue(evaluated_rval)); EvalContextSetEvalOption(ctx, EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS, cache_system_functions); } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_PROTOCOL_VERSION].lval) == 0) { config->protocol_version = ProtocolVersionParse( RvalScalarValue(evaluated_rval)); Log(LOG_LEVEL_VERBOSE, "SET common protocol_version: %s", ProtocolVersionString(config->protocol_version)); } /* Those are package_inventory and package_module common control body options */ if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_PACKAGE_INVENTORY].lval) == 0) { AddDefaultInventoryToContext(ctx, RvalRlistValue(evaluated_rval)); Log(LOG_LEVEL_VERBOSE, "SET common package_inventory list"); } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_PACKAGE_MODULE].lval) == 0) { AddDefaultPackageModuleToContext(ctx, RvalScalarValue(evaluated_rval)); Log(LOG_LEVEL_VERBOSE, "SET common package_module: %s", RvalScalarValue(evaluated_rval)); } if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_GOALPATTERNS].lval) == 0) { /* Ignored */ } RvalDestroy(evaluated_rval); } EvalContextStackPopFrame(ctx); free(scope); } static void ResolvePackageManagerBody(EvalContext *ctx, const Body *pm_body) { PackageModuleBody *new_manager = xcalloc(1, sizeof(PackageModuleBody)); new_manager->name = SafeStringDuplicate(pm_body->name); for (size_t i = 0; i < SeqLength(pm_body->conlist); i++) { Constraint *cp = SeqAt(pm_body->conlist, i); Rval returnval = {0}; if (IsDefinedClass(ctx, cp->classes)) { returnval = ExpandPrivateRval(ctx, NULL, "body", cp->rval.item, cp->rval.type); } if (returnval.item == NULL || returnval.type == RVAL_TYPE_NOPROMISEE) { Log(LOG_LEVEL_VERBOSE, "have invalid constraint while resolving" "package promise body: %s", cp->lval); RvalDestroy(returnval); continue; } if (strcmp(cp->lval, "query_installed_ifelapsed") == 0) { new_manager->installed_ifelapsed = (int)IntFromString(RvalScalarValue(returnval)); } else if (strcmp(cp->lval, "query_updates_ifelapsed") == 0) { new_manager->updates_ifelapsed = (int)IntFromString(RvalScalarValue(returnval)); } else if (strcmp(cp->lval, "default_options") == 0) { new_manager->options = RlistCopy(RvalRlistValue(returnval)); } else if (strcmp(cp->lval, "interpreter") == 0) { assert(new_manager->interpreter == NULL); new_manager->interpreter = SafeStringDuplicate(RvalScalarValue(returnval)); } else if (strcmp(cp->lval, "module_path") == 0) { assert(new_manager->module_path == NULL); new_manager->module_path = SafeStringDuplicate(RvalScalarValue(returnval)); } else { /* This should be handled by the parser. */ assert(0); } RvalDestroy(returnval); } AddPackageModuleToContext(ctx, new_manager); } void PolicyResolve(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config) { /* PRE-EVAL: common bundles: classes,vars. */ for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bundle = SeqAt(policy->bundles, i); if (strcmp("common", bundle->type) == 0) { EvalContextStackPushBundleFrame(ctx, bundle, NULL, false); BundleResolve(ctx, bundle); /* PRE-EVAL classes,vars */ EvalContextStackPopFrame(ctx); } } /* * HACK: yet another pre-eval pass here, WHY? TODO remove, but test fails: * 00_basics/03_bodies/dynamic_inputs_findfiles.cf */ #if 1 /* PRE-EVAL: non-common bundles: only vars. */ for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bundle = SeqAt(policy->bundles, i); if (strcmp("common", bundle->type) != 0) { EvalContextStackPushBundleFrame(ctx, bundle, NULL, false); BundleResolve(ctx, bundle); /* PRE-EVAL vars */ EvalContextStackPopFrame(ctx); } } #endif for (size_t i = 0; i < SeqLength(policy->bodies); i++) { Body *bdp = SeqAt(policy->bodies, i); if (strcmp(bdp->name, "control") == 0) { ResolveControlBody(ctx, config, bdp); } /* Collect all package managers data from policy as we don't know yet * which ones we will use. */ else if (strcmp(bdp->type, "package_module") == 0) { ResolvePackageManagerBody(ctx, bdp); } } } bool IsExpandable(const char *str) { char left = 'x', right = 'x'; int dollar = false; int bracks = 0, vars = 0; for (const char *sp = str; *sp != '\0'; sp++) /* check for varitems */ { switch (*sp) { case '$': if (*(sp + 1) == '{' || *(sp + 1) == '(') { dollar = true; } break; case '(': case '{': if (dollar) { left = *sp; bracks++; } break; case ')': case '}': if (dollar) { bracks--; right = *sp; } break; } if (left == '(' && right == ')' && dollar && (bracks == 0)) { vars++; dollar = false; } if (left == '{' && right == '}' && dollar && (bracks == 0)) { vars++; dollar = false; } } if (bracks != 0) { Log(LOG_LEVEL_DEBUG, "If this is an expandable variable string then it contained syntax errors"); return false; } if (vars > 0) { Log(LOG_LEVEL_DEBUG, "Expanding variable '%s': found %d variables", str, vars); } return (vars > 0); } /*********************************************************************/ static inline char opposite(char c) { switch (c) { case '(': return ')'; case '{': return '}'; default : ProgrammingError("Was expecting '(' or '{' but got: '%c'", c); } return 0; } /** * Check if #str contains one and only one variable expansion of #vtype kind * (it's usually either '$' or '@'). It can contain nested expansions which * are not checked properly. Examples: * true: "$(whatever)", "${whatever}", "$(blah$(blue))" * false: "$(blah)blue", "blah$(blue)", "$(blah)$(blue)", "$(blah}" */ bool IsNakedVar(const char *str, char vtype) { size_t len = strlen(str); char last = len > 0 ? str[len-1] : '\0'; if (len < 3 || str[0] != vtype || (str[1] != '(' && str[1] != '{') || last != opposite(str[1])) { return false; } /* TODO check if nesting happens correctly? Is it needed? */ size_t count = 0; for (const char *sp = str; *sp != '\0'; sp++) { switch (*sp) { case '(': case '{': count++; break; case ')': case '}': count--; /* Make sure the end of the variable is the last character. */ if (count == 0 && sp[1] != '\0') { return false; } break; } } if (count != 0) { return false; } return true; } /*********************************************************************/ /** * Copy @(listname) -> listname. * * This function performs no validations, it is necessary to call the * validation functions before calling this function. * * @NOTE make sure sizeof(dst) >= sizeof(s) */ void GetNaked(char *dst, const char *s) { size_t s_len = strlen(s); if (s_len < 4 || s_len + 3 >= CF_MAXVARSIZE) { Log(LOG_LEVEL_ERR, "@(variable) expected, but got malformed: %s", s); strlcpy(dst, s, CF_MAXVARSIZE); return; } memcpy(dst, &s[2], s_len - 3); dst[s_len - 3] = '\0'; } /*********************************************************************/ /** * Checks if a variable is an @-list and returns true or false. */ bool IsVarList(const char *var) { if ('@' != var[0]) { return false; } /* * Minimum size for a list is 4: * '@' + '(' + name + ')' */ if (strlen(var) < 4) { return false; } return true; } PromiseResult CommonEvalPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert(param == NULL); PromiseRecheckAllConstraints(ctx, pp); return PROMISE_RESULT_NOOP; } cfengine-3.24.2/libpromises/variable.h0000644000000000000000000000630015010704253017640 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VARIABLE_H #define CFENGINE_VARIABLE_H #include #include typedef struct Variable_ Variable; typedef struct VariableTable_ VariableTable; typedef struct VariableTableIterator_ VariableTableIterator; const VarRef *VariableGetRef(const Variable *var); DataType VariableGetType(const Variable *var); RvalType VariableGetRvalType(const Variable *var); StringSet *VariableGetTags(const Variable *var); const char *VariableGetComment(const Variable *var); const Promise *VariableGetPromise(const Variable *var); /** * Get the variable's value. * * @param get_secret Whether to get the secret value in case the variable is tagged as secret * * @note #get_secret should only be %true if the potentially secret value is * really required, i.e. being actually used not logged, reported,... */ Rval VariableGetRval(const Variable *var, bool get_secret); /** * Set new value of variable. * * @note Destroys the old variable's value. */ void VariableSetRval(Variable *var, Rval new_rval); /** * Whether the variable is marked as secret or not. */ bool VariableIsSecret(const Variable *var); VariableTable *VariableTableNew(void); void VariableTableDestroy(VariableTable *table); bool VariableTablePut(VariableTable *table, const VarRef *ref, const Rval *rval, DataType type, StringSet *tags, char *comment, const Promise *promise); Variable *VariableTableGet(const VariableTable *table, const VarRef *ref); bool VariableTableRemove(VariableTable *table, const VarRef *ref); size_t VariableTableCount(const VariableTable *table, const char *ns, const char *scope, const char *lval); bool VariableTableClear(VariableTable *table, const char *ns, const char *scope, const char *lval); VariableTableIterator *VariableTableIteratorNew(const VariableTable *table, const char *ns, const char *scope, const char *lval); VariableTableIterator *VariableTableIteratorNewFromVarRef(const VariableTable *table, const VarRef *ref); Variable *VariableTableIteratorNext(VariableTableIterator *iter); void VariableTableIteratorDestroy(VariableTableIterator *iter); VariableTable *VariableTableCopyLocalized(const VariableTable *table, const char *ns, const char *scope); #endif cfengine-3.24.2/libpromises/item_lib.h0000644000000000000000000001032615010704253017642 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ITEM_LIB_H #define CFENGINE_ITEM_LIB_H #include #include #include struct Item_ { char *name; char *classes; int counter; time_t time; Item *next; }; typedef enum { ITEM_MATCH_TYPE_LITERAL_START, ITEM_MATCH_TYPE_LITERAL_COMPLETE, ITEM_MATCH_TYPE_LITERAL_SOMEWHERE, ITEM_MATCH_TYPE_REGEX_COMPLETE, ITEM_MATCH_TYPE_LITERAL_START_NOT, ITEM_MATCH_TYPE_LITERAL_COMPLETE_NOT, ITEM_MATCH_TYPE_LITERAL_SOMEWHERE_NOT, ITEM_MATCH_TYPE_REGEX_COMPLETE_NOT } ItemMatchType; void PrintItemList(const Item *list, Writer *w); void PrependFullItem(Item **liststart, const char *itemstring, const char *classes, int counter, time_t t); Item *ReturnItemIn(Item *list, const char *item); Item *ReturnItemInClass(Item *list, const char *item, const char *classes); Item *ReturnItemAtIndex(Item *list, int index); Item *EndOfList(Item *start); void PrependItemList(Item **liststart, const char *itemstring); void InsertAfter(Item **filestart, Item *ptr, const char *string); bool RawSaveItemList(const Item *liststart, const char *filename, NewLineMode new_line_mode); Item *RawLoadItemList(const char *filename); Item *SplitStringAsItemList(const char *string, char sep); Item *SplitString(const char *string, char sep); bool DeleteItemGeneral(Item **filestart, const char *string, ItemMatchType type); bool DeleteItemLiteral(Item **filestart, const char *string); bool DeleteItemStarting(Item **list, const char *string); bool DeleteItemNotStarting(Item **list, const char *string); bool DeleteItemMatching(Item **list, const char *string); bool DeleteItemNotMatching(Item **list, const char *string); bool DeleteItemContaining(Item **list, const char *string); bool DeleteItemNotContaining(Item **list, const char *string); size_t ListLen(const Item *list); bool IsItemIn(const Item *list, const char *item); bool ListsCompare(const Item *list1, const Item *list2); bool ListSubsetOfList(const Item *list1, const Item *list2); bool IsMatchItemIn(const Item *list, const char *item); Item *ConcatLists(Item *list1, Item *list2); void CopyList(Item **dest, const Item *source); void IdempItemCount(Item **liststart, const char *itemstring, const char *classes); Item *IdempPrependItem(Item **liststart, const char *itemstring, const char *classes); Item *IdempPrependItemClass(Item **liststart, const char *itemstring, const char *classes); Item *ReverseItemList(Item *list); /* Eats list, spits it out reversed. */ Item *PrependItem(Item **liststart, const char *itemstring, const char *classes); /* Warning: AppendItem()'s cost is proportional to list length; it is * usually cheaper to build a list using PrependItem, then reverse it; * building it with AppendItem() is quadratic in length. */ void AppendItem(Item **liststart, const char *itemstring, const char *classes); void DeleteItemList(Item *item); void DeleteItem(Item **liststart, Item *item); void IncrementItemListCounter(Item *ptr, const char *string); void SetItemListCounter(Item *ptr, const char *string, int value); char *ItemList2CSV(const Item *list); size_t ItemList2CSV_bound(const Item *list, char *buf, size_t buf_size, char separator); size_t ItemListSize(const Item *list); bool IsInterfaceAddress(const Item *ip_addresses, const char *adr); #endif cfengine-3.24.2/libpromises/sort.h0000644000000000000000000000334615010704253017051 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SORT_H #define CFENGINE_SORT_H /* * Sorting is destructive, use the returned pointer to refer to sorted list. */ Item *SortItemListNames(Item *list); /* Alphabetical */ Item *SortItemListClasses(Item *list); /* Alphabetical */ Item *SortItemListCounters(Item *list); /* Reverse sort */ Item *SortItemListTimes(Item *list); /* Reverse sort */ Rlist *SortRlist(Rlist *list, bool (*CompareItems) ()); Rlist *AlphaSortRListNames(Rlist *list); Rlist *IntSortRListNames(Rlist *list); Rlist *RealSortRListNames(Rlist *list); Rlist *IPSortRListNames(Rlist *list); Rlist *MACSortRListNames(Rlist *list); bool GenericItemLess(const char *mode, void *lhs, void *rhs); bool GenericStringItemLess(const char *sort_type, const char *lhs, const char *rhs); #endif cfengine-3.24.2/libpromises/keyring.c0000644000000000000000000000632715010704253017527 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /***************************************************************/ bool HostKeyAddressUnknown(const char *value) { if (strcmp(value, "location unknown") == 0) { return true; } // Is there some other non-ip string left over? if (!((strchr(value, '.')) || (strchr(value, ':')))) { return false; } return false; } /***************************************************************/ int RemovePublicKey(const char *id) { Dir *dirh = NULL; int removed = 0; char keysdir[CF_BUFSIZE]; const struct dirent *dirp; char suffix[CF_BUFSIZE]; snprintf(keysdir, CF_BUFSIZE, "%s/ppkeys", GetWorkDir()); MapName(keysdir); if ((dirh = DirOpen(keysdir)) == NULL) { if (errno == ENOENT) { return 0; } else { Log(LOG_LEVEL_ERR, "Unable to open keys directory at '%s'. (opendir: %s)", keysdir, GetErrorStr()); return -1; } } snprintf(suffix, CF_BUFSIZE, "-%s.pub", id); while ((dirp = DirRead(dirh)) != NULL) { char *c = strstr(dirp->d_name, suffix); if (c && c[strlen(suffix)] == '\0') /* dirp->d_name ends with suffix */ { char keyfilename[sizeof(keysdir) + sizeof(dirp->d_name)]; // both sizeof's include NUL, so one of those is for the '/' snprintf(keyfilename, sizeof(keyfilename), "%s/%s", keysdir, dirp->d_name); MapName(keyfilename); if (unlink(keyfilename) < 0) { if (errno != ENOENT) { Log(LOG_LEVEL_ERR, "Unable to remove key file '%s'. (unlink: %s)", dirp->d_name, GetErrorStr()); DirClose(dirh); return -1; } } else { removed++; } } } if (errno) { Log(LOG_LEVEL_ERR, "Unable to enumerate files in keys directory. (ReadDir: %s)", GetErrorStr()); DirClose(dirh); return -1; } DirClose(dirh); return removed; } /***************************************************************/ cfengine-3.24.2/libpromises/math_eval.h0000644000000000000000000000227615010704253020023 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MATH_EVAL_H #define CFENGINE_MATH_EVAL_H #include double EvaluateMathInfix(EvalContext *ctx, const char *input, char *failure); double EvaluateMathFunction(const char *f, double p); #endif cfengine-3.24.2/libpromises/evalfunction.c0000644000000000000000000133511515010704253020555 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* GetUserName(), GetGroupName() */ #include #include /* CompileRegex,StringMatchWithPrecompiledRegex */ #include /* SocketConnect */ #include #include /* SendSocketStream */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* ThreadWait */ #include #include #include #include #ifdef HAVE_LIBCURL #include #endif #ifdef HAVE_LIBCURL static bool CURL_INITIALIZED = false; /* GLOBAL */ static JsonElement *CURL_CACHE = NULL; #endif #define SPLAY_PSEUDO_RANDOM_CONSTANT 8192 static FnCallResult FilterInternal(EvalContext *ctx, const FnCall *fp, const char *regex, const Rlist* rp, bool do_regex, bool invert, long max); static char *StripPatterns(char *file_buffer, const char *pattern, const char *filename); static int BuildLineArray(EvalContext *ctx, const Bundle *bundle, const char *array_lval, const char *file_buffer, const char *split, int maxent, DataType type, bool int_index); static JsonElement* BuildData(EvalContext *ctx, const char *file_buffer, const char *split, int maxent, bool make_array); static bool ExecModule(EvalContext *ctx, char *command); static bool CheckIDChar(const char ch); static bool CheckID(const char *id); static const Rlist *GetListReferenceArgument(const EvalContext *ctx, const FnCall *fp, const char *lval_str, DataType *datatype_out); static char *CfReadFile(const char *filename, size_t maxsize); /*******************************************************************/ int FnNumArgs(const FnCallType *call_type) { for (int i = 0;; i++) { if (call_type->args[i].pattern == NULL) { return i; } } } /*******************************************************************/ /* assume args are all scalar literals by the time we get here and each handler allocates the memory it returns. There is a protocol to be followed here: Set args, Eval Content, Set rtype, ErrorFlags returnval = FnCallXXXResult(fp) */ /* * Return successful FnCallResult with copy of str retained. */ static FnCallResult FnReturn(const char *str) { return (FnCallResult) { FNCALL_SUCCESS, { xstrdup(str), RVAL_TYPE_SCALAR } }; } /* * Return successful FnCallResult with str as is. */ static FnCallResult FnReturnNoCopy(char *str) { return (FnCallResult) { FNCALL_SUCCESS, { str, RVAL_TYPE_SCALAR } }; } static FnCallResult FnReturnBuffer(Buffer *buf) { return (FnCallResult) { FNCALL_SUCCESS, { BufferClose(buf), RVAL_TYPE_SCALAR } }; } static FnCallResult FnReturnContainerNoCopy(JsonElement *container) { return (FnCallResult) { FNCALL_SUCCESS, (Rval) { container, RVAL_TYPE_CONTAINER }}; } // Currently only used for LIBCURL function, macro can be removed later #ifdef HAVE_LIBCURL static FnCallResult FnReturnContainer(JsonElement *container) { return FnReturnContainerNoCopy(JsonCopy(container)); } #endif // HAVE_LIBCURL static FnCallResult FnReturnF(const char *fmt, ...) FUNC_ATTR_PRINTF(1, 2); static FnCallResult FnReturnF(const char *fmt, ...) { va_list ap; va_start(ap, fmt); char *buffer; xvasprintf(&buffer, fmt, ap); va_end(ap); return FnReturnNoCopy(buffer); } static FnCallResult FnReturnContext(bool result) { return FnReturn(result ? "any" : "!any"); } static FnCallResult FnFailure(void) { return (FnCallResult) { FNCALL_FAILURE, { 0 } }; } static VarRef* ResolveAndQualifyVarName(const FnCall *fp, const char *varname) { VarRef *ref = NULL; if (varname != NULL && IsVarList(varname) && strlen(varname) < CF_MAXVARSIZE) { char naked[CF_MAXVARSIZE] = ""; GetNaked(naked, varname); ref = VarRefParse(naked); } else { ref = VarRefParse(varname); } if (!VarRefIsQualified(ref)) { if (fp->caller) { const Bundle *caller_bundle = PromiseGetBundle(fp->caller); VarRefQualify(ref, caller_bundle->ns, caller_bundle->name); } else { Log(LOG_LEVEL_WARNING, "Function '%s' was not called from a promise; " "the unqualified variable reference %s cannot be qualified automatically.", fp->name, varname); VarRefDestroy(ref); return NULL; } } return ref; } static JsonElement* VarRefValueToJson(const EvalContext *ctx, const FnCall *fp, const VarRef *ref, const DataType disallowed_datatypes[], size_t disallowed_count, bool allow_scalars, bool *allocated) { assert(ref); DataType value_type = CF_DATA_TYPE_NONE; const void *value = EvalContextVariableGet(ctx, ref, &value_type); bool want_type = true; // Convenience storage for the name of the function, since fp can be NULL const char* fp_name = (fp ? fp->name : "VarRefValueToJson"); for (size_t di = 0; di < disallowed_count; di++) { if (disallowed_datatypes[di] == value_type) { want_type = false; break; } } JsonElement *convert = NULL; if (want_type) { switch (DataTypeToRvalType(value_type)) { case RVAL_TYPE_LIST: convert = JsonArrayCreate(RlistLen(value)); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR) /* TODO what if it's an ilist */ { JsonArrayAppendString(convert, RlistScalarValue(rp)); } else { ProgrammingError("Ignored Rval of list type: %s", RvalTypeToString(rp->val.type)); } } *allocated = true; break; case RVAL_TYPE_CONTAINER: // TODO: look into optimizing this if necessary convert = JsonCopy(value); *allocated = true; break; case RVAL_TYPE_SCALAR: { const char* data = value; if (allow_scalars) { convert = JsonStringCreate(value); *allocated = true; break; } else { /* regarray,mergedata,maparray,mapdata only care for arrays * and ignore strings, so they go through this path. */ Log(LOG_LEVEL_DEBUG, "Skipping scalar '%s' because 'allow_scalars' is false", data); } } // fallthrough default: *allocated = true; { VariableTableIterator *iter = EvalContextVariableTableFromRefIteratorNew(ctx, ref); convert = JsonObjectCreate(10); const size_t ref_num_indices = ref->num_indices; char *last_key = NULL; Variable *var; while ((var = VariableTableIteratorNext(iter)) != NULL) { JsonElement *holder = convert; JsonElement *holder_parent = NULL; const VarRef *var_ref = VariableGetRef(var); if (var_ref->num_indices - ref_num_indices == 1) { last_key = var_ref->indices[ref_num_indices]; } else if (var_ref->num_indices - ref_num_indices > 1) { Log(LOG_LEVEL_DEBUG, "%s: got ref with starting depth %zu and index count %zu", fp_name, ref_num_indices, var_ref->num_indices); for (size_t index = ref_num_indices; index < var_ref->num_indices-1; index++) { JsonElement *local = JsonObjectGet(holder, var_ref->indices[index]); if (local == NULL) { local = JsonObjectCreate(1); JsonObjectAppendObject(holder, var_ref->indices[index], local); } last_key = var_ref->indices[index+1]; holder_parent = holder; holder = local; } } if (last_key != NULL && holder != NULL) { Rval var_rval = VariableGetRval(var, true); switch (var_rval.type) { case RVAL_TYPE_SCALAR: if (JsonGetElementType(holder) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_WARNING, "Replacing a non-container JSON element '%s' with a new empty container" " (for the '%s' subkey)", JsonGetPropertyAsString(holder), last_key); assert(holder_parent != NULL); JsonElement *empty_container = JsonObjectCreate(10); /* we have to duplicate 'holder->propertyName' * instead of just using a pointer to it here * because 'holder' is destroyed as part of the * JsonObjectAppendElement() call below */ char *element_name = xstrdup(JsonGetPropertyAsString(holder)); JsonObjectAppendElement(holder_parent, element_name, empty_container); free (element_name); holder = empty_container; JsonObjectAppendString(holder, last_key, var_rval.item); } else { JsonElement *child = JsonObjectGet(holder, last_key); if (child != NULL && JsonGetElementType(child) == JSON_ELEMENT_TYPE_CONTAINER) { Rval var_rval_secret = VariableGetRval(var, false); Log(LOG_LEVEL_WARNING, "Not replacing the container '%s' with a non-container value '%s'", JsonGetPropertyAsString(child), (char*) var_rval_secret.item); } else { /* everything ok, just append the string */ JsonObjectAppendString(holder, last_key, var_rval.item); } } break; case RVAL_TYPE_LIST: { JsonElement *array = JsonArrayCreate(10); for (const Rlist *rp = RvalRlistValue(var_rval); rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR) { JsonArrayAppendString(array, RlistScalarValue(rp)); } } JsonObjectAppendArray(holder, last_key, array); } break; default: break; } } } VariableTableIteratorDestroy(iter); if (JsonLength(convert) < 1) { char *varname = VarRefToString(ref, true); Log(LOG_LEVEL_VERBOSE, "%s: argument '%s' does not resolve to a container or a list or a CFEngine array", fp_name, varname); free(varname); JsonDestroy(convert); return NULL; } break; } // end of default case } // end of data type switch } else // !wanted_type { char *varname = VarRefToString(ref, true); Log(LOG_LEVEL_DEBUG, "%s: argument '%s' resolved to an undesired data type", fp_name, varname); free(varname); } return convert; } static JsonElement *LookupVarRefToJson(void *ctx, const char **data) { Buffer* varname = NULL; Seq *s = StringMatchCaptures("^(([a-zA-Z0-9_]+\\.)?[a-zA-Z0-9._]+)(\\[[^\\[\\]]+\\])?", *data, false); if (s && SeqLength(s) > 0) // got a variable name { varname = BufferCopy((const Buffer*) SeqAt(s, 0)); } if (s) { SeqDestroy(s); } VarRef *ref = NULL; if (varname) { ref = VarRefParse(BufferData(varname)); // advance to the last character of the matched variable name *data += strlen(BufferData(varname))-1; BufferDestroy(varname); } if (!ref) { return NULL; } bool allocated = false; JsonElement *vardata = VarRefValueToJson(ctx, NULL, ref, NULL, 0, true, &allocated); VarRefDestroy(ref); // This should always return a copy if (!allocated) { vardata = JsonCopy(vardata); } return vardata; } static JsonElement* VarNameOrInlineToJson(EvalContext *ctx, const FnCall *fp, const Rlist* rp, bool allow_scalars, bool *allocated) { JsonElement *inline_data = NULL; assert(rp); if (rp->val.type == RVAL_TYPE_CONTAINER) { return (JsonElement*) rp->val.item; } const char* data = RlistScalarValue(rp); JsonParseError res = JsonParseWithLookup(ctx, &LookupVarRefToJson, &data, &inline_data); if (res == JSON_PARSE_OK) { if (JsonGetElementType(inline_data) == JSON_ELEMENT_TYPE_PRIMITIVE) { JsonDestroy(inline_data); inline_data = NULL; } else { *allocated = true; return inline_data; } } VarRef *ref = ResolveAndQualifyVarName(fp, data); if (!ref) { return NULL; } JsonElement *vardata = VarRefValueToJson(ctx, fp, ref, NULL, 0, allow_scalars, allocated); VarRefDestroy(ref); return vardata; } typedef struct { char *address; char *hostkey; time_t lastseen; } HostData; static HostData *HostDataNew(const char *address, const char *hostkey, time_t lastseen) { HostData *data = xmalloc(sizeof(HostData)); data->address = SafeStringDuplicate(address); data->hostkey = SafeStringDuplicate(hostkey); data->lastseen = lastseen; return data; } static void HostDataFree(HostData *hd) { if (hd != NULL) { free(hd->address); free(hd->hostkey); free(hd); } } typedef enum { NAME, ADDRESS, HOSTKEY, NONE } HostsSeenFieldOption; static HostsSeenFieldOption ParseHostsSeenFieldOption(const char *field) { if (StringEqual(field, "name")) { return NAME; } else if (StringEqual(field, "address")) { return ADDRESS; } else if (StringEqual(field, "hostkey")) { return HOSTKEY; } else { return NONE; } } static Rlist *GetHostsFromLastseenDB(Seq *host_data, time_t horizon, HostsSeenFieldOption return_what, bool return_recent) { Rlist *recent = NULL, *aged = NULL; time_t now = time(NULL); time_t entrytime; char ret_host_data[CF_MAXVARSIZE]; // TODO: Could this be 1025 / NI_MAXHOST ? const size_t length = SeqLength(host_data); for (size_t i = 0; i < length; ++i) { HostData *hd = SeqAt(host_data, i); entrytime = hd->lastseen; if ((return_what == NAME || return_what == ADDRESS) && HostKeyAddressUnknown(hd->hostkey)) { continue; } switch (return_what) { case NAME: { char hostname[NI_MAXHOST]; if (IPString2Hostname(hostname, hd->address, sizeof(hostname)) != -1) { StringCopy(hostname, ret_host_data, sizeof(ret_host_data)); } else { /* Not numeric address was requested, but IP was unresolvable. */ StringCopy(hd->address, ret_host_data, sizeof(ret_host_data)); } break; } case ADDRESS: StringCopy(hd->address, ret_host_data, sizeof(ret_host_data)); break; case HOSTKEY: StringCopy(hd->hostkey, ret_host_data, sizeof(ret_host_data)); break; default: ProgrammingError("Parser allowed invalid hostsseen() field argument"); } if (entrytime < now - horizon) { Log(LOG_LEVEL_DEBUG, "Old entry"); if (RlistKeyIn(recent, ret_host_data)) { Log(LOG_LEVEL_DEBUG, "There is recent entry for this ret_host_data. Do nothing."); } else { Log(LOG_LEVEL_DEBUG, "Adding to list of aged hosts."); RlistPrependScalarIdemp(&aged, ret_host_data); } } else { Log(LOG_LEVEL_DEBUG, "Recent entry"); Rlist *r = RlistKeyIn(aged, ret_host_data); if (r) { Log(LOG_LEVEL_DEBUG, "Purging from list of aged hosts."); RlistDestroyEntry(&aged, r); } Log(LOG_LEVEL_DEBUG, "Adding to list of recent hosts."); RlistPrependScalarIdemp(&recent, ret_host_data); } } if (return_recent) { RlistDestroy(aged); return recent; } else { RlistDestroy(recent); return aged; } } /*********************************************************************/ static FnCallResult FnCallAnd(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(fp->name, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "Function '%s', %s", fp->name, SyntaxTypeMatchToString(err)); } } for (const Rlist *arg = finalargs; arg; arg = arg->next) { if (!IsDefinedClass(ctx, RlistScalarValue(arg))) { return FnReturnContext(false); } } return FnReturnContext(true); } /*******************************************************************/ static bool CallHostsSeenCallback(const char *hostkey, const char *address, ARG_UNUSED bool incoming, const KeyHostSeen *quality, void *ctx) { SeqAppend(ctx, HostDataNew(address, hostkey, quality->lastseen)); return true; } /*******************************************************************/ static FnCallResult FnCallHostsSeen(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { Seq *host_data = SeqNew(1, HostDataFree); int horizon = IntFromString(RlistScalarValue(finalargs)) * 3600; char *hostseen_policy = RlistScalarValue(finalargs->next); char *field_str = RlistScalarValue(finalargs->next->next); HostsSeenFieldOption field = ParseHostsSeenFieldOption(field_str); Log(LOG_LEVEL_DEBUG, "Calling hostsseen(%d,%s,%s)", horizon, hostseen_policy, field_str); if (!ScanLastSeenQuality(&CallHostsSeenCallback, host_data)) { SeqDestroy(host_data); return FnFailure(); } Rlist *returnlist = GetHostsFromLastseenDB(host_data, horizon, field, StringEqual(hostseen_policy, "lastseen")); SeqDestroy(host_data); { Writer *w = StringWriter(); WriterWrite(w, "hostsseen return values:"); for (Rlist *rp = returnlist; rp; rp = rp->next) { WriterWriteF(w, " '%s'", RlistScalarValue(rp)); } Log(LOG_LEVEL_DEBUG, "%s", StringWriterData(w)); WriterClose(w); } if (returnlist == NULL) { return FnFailure(); } return (FnCallResult) { FNCALL_SUCCESS, { returnlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallHostsWithClass(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { Rlist *returnlist = NULL; char *class_name = RlistScalarValue(finalargs); char *return_format = RlistScalarValue(finalargs->next); if (!ListHostsWithClass(ctx, &returnlist, class_name, return_format)) { return FnFailure(); } return (FnCallResult) { FNCALL_SUCCESS, { returnlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ /** @brief Convert function call from/to variables to range * * Swap the two integers in place if the first is bigger * Check for CF_NOINT, indicating invalid arguments * * @return Absolute (positive) difference, -1 for error (0 for equal) */ static int int_range_convert(int *from, int *to) { int old_from = *from; int old_to = *to; if (old_from == CF_NOINT || old_to == CF_NOINT) { return -1; } if (old_from == old_to) { return 0; } if (old_from > old_to) { *from = old_to; *to = old_from; } assert(*to > *from); return (*to) - (*from); } static FnCallResult FnCallRandomInt(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { if (finalargs->next == NULL) { return FnFailure(); } int from = IntFromString(RlistScalarValue(finalargs)); int to = IntFromString(RlistScalarValue(finalargs->next)); int range = int_range_convert(&from, &to); if (range == -1) { return FnFailure(); } if (range == 0) { return FnReturnF("%d", from); } assert(range > 0); int result = from + (int) (drand48() * (double) range); return FnReturnF("%d", result); } // Read an array of bytes as unsigned integers // Convert to 64 bit unsigned integer // Cross platform/arch, bytes[0] is always LSB of result static uint64_t BytesToUInt64(uint8_t *bytes) { uint64_t result = 0; size_t n = 8; for (size_t i = 0; inext == NULL || finalargs->next->next == NULL) { return FnFailure(); } signed int from = IntFromString(RlistScalarValue(finalargs)); signed int to = IntFromString(RlistScalarValue(finalargs->next)); signed int range = int_range_convert(&from, &to); if (range == -1) { return FnFailure(); } if (range == 0) { return FnReturnF("%d", from); } assert(range > 0); const unsigned char * const inp = RlistScalarValue(finalargs->next->next); // Use beginning of SHA checksum as basis: unsigned char digest[EVP_MAX_MD_SIZE + 1]; memset(digest, 0, sizeof(digest)); HashString(inp, strlen(inp), digest, HASH_METHOD_SHA256); uint64_t converted_sha = BytesToUInt64((uint8_t*)digest); // Limit using modulo: signed int result = from + (converted_sha % range); return FnReturnF("%d", result); } /*********************************************************************/ static FnCallResult FnCallGetEnv(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char buffer[CF_BUFSIZE] = "", ctrlstr[CF_SMALLBUF]; char *name = RlistScalarValue(finalargs); int limit = IntFromString(RlistScalarValue(finalargs->next)); snprintf(ctrlstr, CF_SMALLBUF, "%%.%ds", limit); // -> %45s if (getenv(name)) { snprintf(buffer, CF_BUFSIZE - 1, ctrlstr, getenv(name)); } return FnReturn(buffer); } /*********************************************************************/ #if defined(HAVE_GETPWENT) && !defined(__ANDROID__) static FnCallResult FnCallGetUsers(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { const char *except_name = RlistScalarValue(finalargs); const char *except_uid = RlistScalarValue(finalargs->next); Rlist *except_names = RlistFromSplitString(except_name, ','); Rlist *except_uids = RlistFromSplitString(except_uid, ','); setpwent(); Rlist *newlist = NULL; struct passwd *pw; while ((pw = getpwent())) { char *pw_uid_str = StringFromLong((int)pw->pw_uid); if (!RlistKeyIn(except_names, pw->pw_name) && !RlistKeyIn(except_uids, pw_uid_str)) { RlistAppendScalarIdemp(&newlist, pw->pw_name); } free(pw_uid_str); } endpwent(); RlistDestroy(except_names); RlistDestroy(except_uids); return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } #else static FnCallResult FnCallGetUsers(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, ARG_UNUSED const Rlist *finalargs) { Log(LOG_LEVEL_ERR, "getusers is not implemented"); return FnFailure(); } #endif /*********************************************************************/ static FnCallResult FnCallEscape(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char buffer[CF_BUFSIZE]; buffer[0] = '\0'; char *name = RlistScalarValue(finalargs); EscapeSpecialChars(name, buffer, CF_BUFSIZE - 1, "", ""); return FnReturn(buffer); } /*********************************************************************/ static FnCallResult FnCallHost2IP(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *name = RlistScalarValue(finalargs); char ipaddr[CF_MAX_IP_LEN]; if (Hostname2IPString(ipaddr, name, sizeof(ipaddr)) != -1) { return FnReturn(ipaddr); } else { /* Retain legacy behaviour, return hostname in case resolution fails. */ return FnReturn(name); } } /*********************************************************************/ static FnCallResult FnCallIP2Host(ARG_UNUSED EvalContext *ctx, ARG_UNUSED ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char hostname[NI_MAXHOST]; char *ip = RlistScalarValue(finalargs); if (IPString2Hostname(hostname, ip, sizeof(hostname)) != -1) { return FnReturn(hostname); } else { /* Retain legacy behaviour, return ip address in case resolution fails. */ return FnReturn(ip); } } /*********************************************************************/ static FnCallResult FnCallSysctlValue(ARG_UNUSED EvalContext *ctx, ARG_UNUSED ARG_UNUSED const Policy *policy, ARG_LINUX_ONLY const FnCall *fp, ARG_LINUX_ONLY const Rlist *finalargs) { #ifdef __linux__ const bool sysctlvalue_mode = (strcmp(fp->name, "sysctlvalue") == 0); size_t max_sysctl_data = 16 * 1024; Buffer *procrootbuf = BufferNew(); // Assumes that FILE_SEPARATOR is / BufferAppendString(procrootbuf, GetRelocatedProcdirRoot()); BufferAppendString(procrootbuf, "/proc/sys"); if (sysctlvalue_mode) { Buffer *key = BufferNewFrom(RlistScalarValue(finalargs), strlen(RlistScalarValue(finalargs))); // Note that in the single-key mode, we just reuse procrootbuf. Buffer *filenamebuf = procrootbuf; // Assumes that FILE_SEPARATOR is / BufferAppendChar(filenamebuf, '/'); BufferSearchAndReplace(key, "\\.", "/", "gT"); BufferAppendString(filenamebuf, BufferData(key)); BufferDestroy(key); if (IsDir(BufferData(filenamebuf))) { Log(LOG_LEVEL_INFO, "Error while reading file '%s' because it's a directory (%s)", BufferData(filenamebuf), GetErrorStr()); BufferDestroy(filenamebuf); return FnFailure(); } Writer *w = NULL; bool truncated = false; int fd = safe_open(BufferData(filenamebuf), O_RDONLY | O_TEXT); if (fd >= 0) { w = FileReadFromFd(fd, max_sysctl_data, &truncated); close(fd); } if (w == NULL) { Log(LOG_LEVEL_VERBOSE, "Error while reading file '%s' (%s)", BufferData(filenamebuf), GetErrorStr()); BufferDestroy(filenamebuf); return FnFailure(); } BufferDestroy(filenamebuf); char *result = StringWriterClose(w); StripTrailingNewline(result, max_sysctl_data); return FnReturnNoCopy(result); } JsonElement *sysctl_data = JsonObjectCreate(10); // For the remaining operations, we want the trailing slash on this. BufferAppendChar(procrootbuf, '/'); Buffer *filematchbuf = BufferCopy(procrootbuf); BufferAppendString(filematchbuf, "**/*"); StringSet *sysctls = GlobFileList(BufferData(filematchbuf)); BufferDestroy(filematchbuf); StringSetIterator it = StringSetIteratorInit(sysctls); const char *filename = NULL; while ((filename = StringSetIteratorNext(&it))) { Writer *w = NULL; bool truncated = false; if (IsDir(filename)) { // No warning: this is normal as we match wildcards. continue; } int fd = safe_open(filename, O_RDONLY | O_TEXT); if (fd >= 0) { w = FileReadFromFd(fd, max_sysctl_data, &truncated); close(fd); } if (!w) { Log(LOG_LEVEL_INFO, "Error while reading file '%s' (%s)", filename, GetErrorStr()); continue; } char *result = StringWriterClose(w); StripTrailingNewline(result, max_sysctl_data); Buffer *var = BufferNewFrom(filename, strlen(filename)); BufferSearchAndReplace(var, BufferData(procrootbuf), "", "T"); BufferSearchAndReplace(var, "/", ".", "gT"); JsonObjectAppendString(sysctl_data, BufferData(var), result); free(result); BufferDestroy(var); } StringSetDestroy(sysctls); BufferDestroy(procrootbuf); return FnReturnContainerNoCopy(sysctl_data); #else return FnFailure(); #endif } /*********************************************************************/ /* TODO move platform-specific code to libenv. */ static FnCallResult FnCallGetUserInfo(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { #ifdef __MINGW32__ // TODO NetUserGetInfo(NULL, username, 1, &buf), see: // https://msdn.microsoft.com/en-us/library/windows/desktop/aa370654(v=vs.85).aspx return FnFailure(); #else /* !__MINGW32__ */ /* TODO: implement and use new GetUserInfo(uid_or_username) */ struct passwd *pw = NULL; if (finalargs == NULL) { pw = getpwuid(getuid()); } else { char *arg = RlistScalarValue(finalargs); if (StringIsNumeric(arg)) { uid_t uid = Str2Uid(arg, NULL, NULL); if (uid == CF_SAME_OWNER) // user "*" { uid = getuid(); } else if (uid == CF_UNKNOWN_OWNER) { return FnFailure(); } pw = getpwuid(uid); } else { pw = getpwnam(arg); } } JsonElement *result = GetUserInfo(pw); if (result == NULL) { return FnFailure(); } return FnReturnContainerNoCopy(result); #endif } /*********************************************************************/ static FnCallResult FnCallGetUid(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { #ifdef __MINGW32__ return FnFailure(); /* TODO */ #else /* !__MINGW32__ */ uid_t uid; if (!GetUserID(RlistScalarValue(finalargs), &uid, LOG_LEVEL_ERR)) { return FnFailure(); } return FnReturnF("%ju", (uintmax_t)uid); #endif } /*********************************************************************/ static FnCallResult FnCallGetGid(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { #ifdef __MINGW32__ return FnFailure(); /* TODO */ #else /* !__MINGW32__ */ gid_t gid; if (!GetGroupID(RlistScalarValue(finalargs), &gid, LOG_LEVEL_ERR)) { return FnFailure(); } return FnReturnF("%ju", (uintmax_t)gid); #endif } /*********************************************************************/ static FnCallResult FnCallHandlerHash(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) /* Hash(string,md5|sha1|crypt) */ { unsigned char digest[EVP_MAX_MD_SIZE + 1]; HashMethod type; char *string_or_filename = RlistScalarValue(finalargs); char *typestring = RlistScalarValue(finalargs->next); const bool filehash_mode = strcmp(fp->name, "file_hash") == 0; type = HashIdFromName(typestring); if (FIPS_MODE && type == HASH_METHOD_MD5) { Log(LOG_LEVEL_ERR, "FIPS mode is enabled, and md5 is not an approved algorithm in call to %s()", fp->name); } if (filehash_mode) { HashFile(string_or_filename, digest, type, false); } else { HashString(string_or_filename, strlen(string_or_filename), digest, type); } char hashbuffer[CF_HOSTKEY_STRING_SIZE]; HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest, type, true); return FnReturn(SkipHashType(hashbuffer)); } /*********************************************************************/ static FnCallResult FnCallHashMatch(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) /* HashMatch(string,md5|sha1|crypt,"abdxy98edj") */ { unsigned char digest[EVP_MAX_MD_SIZE + 1]; HashMethod type; char *string = RlistScalarValue(finalargs); char *typestring = RlistScalarValue(finalargs->next); char *compare = RlistScalarValue(finalargs->next->next); type = HashIdFromName(typestring); HashFile(string, digest, type, false); char hashbuffer[CF_HOSTKEY_STRING_SIZE]; HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest, type, true); Log(LOG_LEVEL_VERBOSE, "File '%s' hashes to '%s', compare to '%s'", string, hashbuffer, compare); return FnReturnContext(strcmp(hashbuffer + 4, compare) == 0); } /*********************************************************************/ static FnCallResult FnCallConcat(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char id[CF_BUFSIZE]; char result[CF_BUFSIZE] = ""; snprintf(id, CF_BUFSIZE, "built-in FnCall concat-arg"); /* We need to check all the arguments, ArgTemplate does not check varadic functions */ for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(id, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "in %s: %s", id, SyntaxTypeMatchToString(err)); } } for (const Rlist *arg = finalargs; arg; arg = arg->next) { if (strlcat(result, RlistScalarValue(arg), CF_BUFSIZE) >= CF_BUFSIZE) { /* Complain */ Log(LOG_LEVEL_ERR, "Unable to evaluate concat() function, arguments are too long"); return FnFailure(); } } return FnReturn(result); } /*********************************************************************/ static FnCallResult FnCallIfElse(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { unsigned int argcount = 0; char id[CF_BUFSIZE]; snprintf(id, CF_BUFSIZE, "built-in FnCall ifelse-arg"); /* We need to check all the arguments, ArgTemplate does not check varadic functions */ for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(id, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "in %s: %s", id, SyntaxTypeMatchToString(err)); } argcount++; } /* Require an odd number of arguments. We will always return something. */ if ((argcount % 2) == 0) { FatalError(ctx, "in built-in FnCall ifelse: even number of arguments"); } const Rlist *arg; for (arg = finalargs; /* Start with arg set to finalargs. */ arg && arg->next; /* We must have arg and arg->next to proceed. */ arg = arg->next->next) /* arg steps forward *twice* every time. */ { /* Similar to classmatch(), we evaluate the first of the two * arguments as a class. */ if (IsDefinedClass(ctx, RlistScalarValue(arg))) { /* If the evaluation returned true in the current context, * return the second of the two arguments. */ return FnReturn(RlistScalarValue(arg->next)); } } /* If we get here, we've reached the last argument (arg->next is NULL). */ return FnReturn(RlistScalarValue(arg)); } /*********************************************************************/ static FnCallResult FnCallClassesMatching(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { assert(finalargs != NULL); bool count_only = false; bool check_only = false; unsigned count = 0; if (StringEqual(fp->name, "classesmatching")) { // Expected / default case } else if (StringEqual(fp->name, "classmatch")) { check_only = true; } else if (StringEqual(fp->name, "countclassesmatching")) { count_only = true; } else { FatalError(ctx, "FnCallClassesMatching: got unknown function name '%s', aborting", fp->name); } if (!finalargs) { FatalError(ctx, "Function '%s' requires at least one argument", fp->name); } for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(fp->name, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "in function '%s', '%s'", fp->name, SyntaxTypeMatchToString(err)); } } Rlist *matches = NULL; { StringSet *global_matches = ClassesMatchingGlobal(ctx, RlistScalarValue(finalargs), finalargs->next, check_only); StringSetIterator it = StringSetIteratorInit(global_matches); const char *element = NULL; while ((element = StringSetIteratorNext(&it))) { if (count_only || check_only) { count++; } else { RlistPrepend(&matches, element, RVAL_TYPE_SCALAR); } } StringSetDestroy(global_matches); } if (check_only && count >= 1) { return FnReturnContext(true); } { StringSet *local_matches = ClassesMatchingLocal(ctx, RlistScalarValue(finalargs), finalargs->next, check_only); StringSetIterator it = StringSetIteratorInit(local_matches); const char *element = NULL; while ((element = StringSetIteratorNext(&it))) { if (count_only || check_only) { count++; } else { RlistPrepend(&matches, element, RVAL_TYPE_SCALAR); } } StringSetDestroy(local_matches); } if (check_only) { return FnReturnContext(count >= 1); } else if (count_only) { return FnReturnF("%u", count); } // else, this is classesmatching() return (FnCallResult) { FNCALL_SUCCESS, { matches, RVAL_TYPE_LIST } }; } static JsonElement *VariablesMatching(const EvalContext *ctx, const FnCall *fp, VariableTableIterator *iter, const Rlist *args, bool collect_full_data) { JsonElement *matching = JsonObjectCreate(10); const char *regex = RlistScalarValue(args); Regex *rx = CompileRegex(regex); Variable *v = NULL; while ((v = VariableTableIteratorNext(iter))) { const VarRef *var_ref = VariableGetRef(v); char *expr = VarRefToString(var_ref, true); if (rx != NULL && StringMatchFullWithPrecompiledRegex(rx, expr)) { StringSet *tagset = EvalContextVariableTags(ctx, var_ref); bool pass = false; if ((tagset != NULL) && (args->next != NULL)) { for (const Rlist *arg = args->next; arg; arg = arg->next) { const char* tag_regex = RlistScalarValue(arg); const char *element = NULL; StringSetIterator it = StringSetIteratorInit(tagset); while ((element = SetIteratorNext(&it))) { if (StringMatchFull(tag_regex, element)) { pass = true; break; } } } } else // without any tags queried, accept variable { pass = true; } if (pass) { JsonElement *data = NULL; bool allocated = false; if (collect_full_data) { data = VarRefValueToJson(ctx, fp, var_ref, NULL, 0, true, &allocated); } /* * When we don't collect the full variable data * (collect_full_data is false), we still create a JsonObject * with empty strings as the values. It will be destroyed soon * afterwards, but the code is cleaner if we do it this way than * if we make a JsonArray in one branch and a JsonObject in the * other branch. The empty strings provide assurance that * serializing this JsonObject (e.g. for logging) will not * create problems. The extra memory usage from the empty * strings is negligible. */ if (data == NULL) { JsonObjectAppendString(matching, expr, ""); } else { if (!allocated) { data = JsonCopy(data); } JsonObjectAppendElement(matching, expr, data); } } } free(expr); } if (rx) { RegexDestroy(rx); } return matching; } static FnCallResult FnCallVariablesMatching(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { bool fulldata = (strcmp(fp->name, "variablesmatching_as_data") == 0); if (!finalargs) { FatalError(ctx, "Function '%s' requires at least one argument", fp->name); } for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(fp->name, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "In function '%s', %s", fp->name, SyntaxTypeMatchToString(err)); } } Rlist *matches = NULL; { VariableTableIterator *iter = EvalContextVariableTableIteratorNew(ctx, NULL, NULL, NULL); JsonElement *global_matches = VariablesMatching(ctx, fp, iter, finalargs, fulldata); VariableTableIteratorDestroy(iter); assert (JsonGetContainerType(global_matches) == JSON_CONTAINER_TYPE_OBJECT); if (fulldata) { return FnReturnContainerNoCopy(global_matches); } JsonIterator jiter = JsonIteratorInit(global_matches); const char *key; while ((key = JsonIteratorNextKey(&jiter)) != NULL) { assert (key != NULL); RlistPrepend(&matches, key, RVAL_TYPE_SCALAR); } JsonDestroy(global_matches); } return (FnCallResult) { FNCALL_SUCCESS, { matches, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallGetMetaTags(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { if (!finalargs) { FatalError(ctx, "Function '%s' requires at least one argument", fp->name); } Rlist *tags = NULL; StringSet *tagset = NULL; if (strcmp(fp->name, "getvariablemetatags") == 0) { VarRef *ref = VarRefParse(RlistScalarValue(finalargs)); tagset = EvalContextVariableTags(ctx, ref); VarRefDestroy(ref); } else if (strcmp(fp->name, "getclassmetatags") == 0) { ClassRef ref = ClassRefParse(RlistScalarValue(finalargs)); tagset = EvalContextClassTags(ctx, ref.ns, ref.name); ClassRefDestroy(ref); } else { FatalError(ctx, "FnCallGetMetaTags: got unknown function name '%s', aborting", fp->name); } if (tagset == NULL) { Log(LOG_LEVEL_VERBOSE, "%s found variable or class %s without a tagset", fp->name, RlistScalarValue(finalargs)); return (FnCallResult) { FNCALL_FAILURE, { 0 } }; } char *key = NULL; if (finalargs->next != NULL) { Buffer *keybuf = BufferNew(); BufferPrintf(keybuf, "%s=", RlistScalarValue(finalargs->next)); key = BufferClose(keybuf); } char *element; StringSetIterator it = StringSetIteratorInit(tagset); while ((element = SetIteratorNext(&it))) { if (key != NULL) { if (StringStartsWith(element, key)) { RlistAppendScalar(&tags, element+strlen(key)); } } else { RlistAppendScalar(&tags, element); } } free(key); return (FnCallResult) { FNCALL_SUCCESS, { tags, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallBasename(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { assert(fp != NULL); assert(fp->name != NULL); if (args == NULL) { Log(LOG_LEVEL_ERR, "Function %s requires a filename as first arg!", fp->name); return FnFailure(); } char dir[PATH_MAX]; strlcpy(dir, RlistScalarValue(args), PATH_MAX); if (dir[0] == '\0') { return FnReturn(dir); } char *base = basename(dir); if (args->next != NULL) { char *suffix = RlistScalarValue(args->next); if (StringEndsWith(base, suffix)) { size_t base_len = strlen(base); size_t suffix_len = strlen(suffix); // Remove only if actually a suffix, not the same string if (suffix_len < base_len) { // On Solaris, trying to edit the buffer returned by basename // causes segfault(!) base = xstrndup(base, base_len - suffix_len); return FnReturnNoCopy(base); } } } return FnReturn(base); } /*********************************************************************/ static FnCallResult FnCallBundlesMatching(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *finalargs) { if (!finalargs) { return FnFailure(); } const char *regex = RlistScalarValue(finalargs); Regex *rx = CompileRegex(regex); if (!rx) { return FnFailure(); } const Rlist *tag_args = finalargs->next; Rlist *matches = NULL; for (size_t i = 0; i < SeqLength(policy->bundles); i++) { const Bundle *bp = SeqAt(policy->bundles, i); char *bundle_name = BundleQualifiedName(bp); if (StringMatchFullWithPrecompiledRegex(rx, bundle_name)) { VarRef *ref = VarRefParseFromBundle("tags", bp); VarRefSetMeta(ref, true); DataType type; const void *bundle_tags = EvalContextVariableGet(ctx, ref, &type); VarRefDestroy(ref); bool found = false; // case where tag_args are given and the bundle has no tags if (tag_args == NULL) { // we declare it found if no tags were requested found = true; } /* was the variable "tags" found? */ else if (type != CF_DATA_TYPE_NONE) { switch (DataTypeToRvalType(type)) { case RVAL_TYPE_SCALAR: { Rlist *searched = RlistFromSplitString(bundle_tags, ','); found = RlistMatchesRegexRlist(searched, tag_args); RlistDestroy(searched); } break; case RVAL_TYPE_LIST: found = RlistMatchesRegexRlist(bundle_tags, tag_args); break; default: Log(LOG_LEVEL_WARNING, "Function '%s' only matches tags defined as a scalar or a list. " "Bundle '%s' had meta defined as '%s'", fp->name, bundle_name, DataTypeToString(type)); found = false; break; } } if (found) { RlistPrepend(&matches, bundle_name, RVAL_TYPE_SCALAR); } } free(bundle_name); } RegexDestroy(rx); return (FnCallResult) { FNCALL_SUCCESS, { matches, RVAL_TYPE_LIST } }; } /*********************************************************************/ static bool AddPackagesMatchingJsonLine(Regex *matcher, JsonElement *json, char *line) { const size_t line_length = strlen(line); if (line_length > CF_BUFSIZE - 80) { Log(LOG_LEVEL_ERR, "Line from package inventory is too long (%zu) to be sensible", line_length); return false; } if (StringMatchFullWithPrecompiledRegex(matcher, line)) { Seq *list = SeqParseCsvString(line); if (SeqLength(list) != 4) { Log(LOG_LEVEL_ERR, "Line from package inventory '%s' did not yield correct number of elements.", line); SeqDestroy(list); return true; } JsonElement *line_obj = JsonObjectCreate(4); JsonObjectAppendString(line_obj, "name", SeqAt(list, 0)); JsonObjectAppendString(line_obj, "version", SeqAt(list, 1)); JsonObjectAppendString(line_obj, "arch", SeqAt(list, 2)); JsonObjectAppendString(line_obj, "method", SeqAt(list, 3)); SeqDestroy(list); JsonArrayAppendObject(json, line_obj); } return true; } static bool GetLegacyPackagesMatching(Regex *matcher, JsonElement *json, const bool installed_mode) { char filename[CF_MAXVARSIZE]; if (installed_mode) { GetSoftwareCacheFilename(filename); } else { GetSoftwarePatchesFilename(filename); } Log(LOG_LEVEL_DEBUG, "Reading inventory from '%s'", filename); FILE *const fin = fopen(filename, "r"); if (fin == NULL) { Log(LOG_LEVEL_VERBOSE, "Cannot open the %s packages inventory '%s' - " "This is not necessarily an error. " "Either the inventory policy has not been included, " "or it has not had time to have an effect yet or you are using" "new package promise and check for legacy promise is made." "A future call may still succeed. (fopen: %s)", installed_mode ? "installed" : "available", filename, GetErrorStr()); return true; } char *line; while ((line = GetCsvLineNext(fin)) != NULL) { if (!AddPackagesMatchingJsonLine(matcher, json, line)) { free(line); break; } free(line); } bool ret = (feof(fin) != 0); fclose(fin); return ret; } static bool GetPackagesMatching(Regex *matcher, JsonElement *json, const bool installed_mode, Rlist *default_inventory) { dbid database = (installed_mode == true ? dbid_packages_installed : dbid_packages_updates); bool read_some_db = false; for (const Rlist *rp = default_inventory; rp != NULL; rp = rp->next) { const char *pm_name = RlistScalarValue(rp); size_t pm_name_size = strlen(pm_name); if (StringContainsUnresolved(pm_name)) { Log(LOG_LEVEL_DEBUG, "Package module '%s' contains unresolved variables", pm_name); continue; } Log(LOG_LEVEL_DEBUG, "Reading packages (%d) for package module [%s]", database, pm_name); CF_DB *db_cached; if (!OpenSubDB(&db_cached, database, pm_name)) { Log(LOG_LEVEL_ERR, "Can not open database %d to get packages data.", database); return false; } else { read_some_db = true; } char *key = ""; int data_size = ValueSizeDB(db_cached, key, strlen(key) + 1); Log(LOG_LEVEL_DEBUG, "Reading inventory from database: %d", data_size); /* For empty list we are storing one byte value in database. */ if (data_size > 1) { char *buff = xmalloc(data_size + 1); buff[data_size] = '\0'; if (!ReadDB(db_cached, key, buff, data_size)) { Log(LOG_LEVEL_WARNING, "Can not read installed packages database " "for '%s' package module.", pm_name); continue; } Seq *packages_from_module = SeqStringFromString(buff, '\n'); free(buff); if (packages_from_module) { // Iterate over and see where match is. for (size_t i = 0; i < SeqLength(packages_from_module); i++) { // With the new package promise we are storing inventory // information it the database. This set of lines ('\n' separated) // containing packages information. Each line is comma // separated set of data containing name, version and architecture. // // Legacy package promise is using 4 values, where the last one // is package method. In our case, method is simply package // module name. To make sure regex matching is working as // expected (we are comparing whole lines, containing package // method) we need to extend the line to contain package // module before regex match is taking place. char *line = SeqAt(packages_from_module, i); size_t new_line_size = strlen(line) + pm_name_size + 2; // we need coma and terminator char new_line[new_line_size]; strcpy(new_line, line); strcat(new_line, ","); strcat(new_line, pm_name); if (!AddPackagesMatchingJsonLine(matcher, json, new_line)) { break; } } SeqDestroy(packages_from_module); } else { Log(LOG_LEVEL_WARNING, "Can not parse packages database for '%s' " "package module.", pm_name); } } CloseDB(db_cached); } return read_some_db; } static FnCallResult FnCallPackagesMatching(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const bool installed_mode = (strcmp(fp->name, "packagesmatching") == 0); Regex *matcher; { const char *regex_package = RlistScalarValue(finalargs); const char *regex_version = RlistScalarValue(finalargs->next); const char *regex_arch = RlistScalarValue(finalargs->next->next); const char *regex_method = RlistScalarValue(finalargs->next->next->next); char regex[CF_BUFSIZE]; // Here we will truncate the regex if the parameters add up to over CF_BUFSIZE snprintf(regex, sizeof(regex), "^%s,%s,%s,%s$", regex_package, regex_version, regex_arch, regex_method); matcher = CompileRegex(regex); if (matcher == NULL) { return FnFailure(); } } JsonElement *json = JsonArrayCreate(50); bool ret = false; Rlist *default_inventory = GetDefaultInventoryFromContext(ctx); bool inventory_allocated = false; if (default_inventory == NULL) { // Did not find default inventory from context, try looking for // existing LMDB databases in the state directory dbid database = (installed_mode ? dbid_packages_installed : dbid_packages_updates); Seq *const seq = SearchExistingSubDBNames(database); const size_t length = SeqLength(seq); for (size_t i = 0; i < length; i++) { const char *const db_name = SeqAt(seq, i); RlistAppendString(&default_inventory, db_name); inventory_allocated = true; } SeqDestroy(seq); } if (!default_inventory) { // Legacy package promise ret = GetLegacyPackagesMatching(matcher, json, installed_mode); } else { // We are using package modules. bool some_valid_inventory = false; for (const Rlist *rp = default_inventory; !some_valid_inventory && (rp != NULL); rp = rp->next) { const char *pm_name = RlistScalarValue(rp); if (!StringContainsUnresolved(pm_name)) { some_valid_inventory = true; } } if (some_valid_inventory) { ret = GetPackagesMatching(matcher, json, installed_mode, default_inventory); } else { Log(LOG_LEVEL_DEBUG, "No valid package module inventory found"); RegexDestroy(matcher); JsonDestroy(json); if (inventory_allocated) { RlistDestroy(default_inventory); } return FnFailure(); } } if (inventory_allocated) { RlistDestroy(default_inventory); } RegexDestroy(matcher); if (ret == false) { Log(LOG_LEVEL_ERR, "%s: Unable to read package inventory.", fp->name); JsonDestroy(json); return FnFailure(); } return FnReturnContainerNoCopy(json); } /*********************************************************************/ static FnCallResult FnCallCanonify(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { char buf[CF_BUFSIZE]; char *string = RlistScalarValue(finalargs); buf[0] = '\0'; if (!strcmp(fp->name, "canonifyuniquely")) { char hashbuffer[CF_HOSTKEY_STRING_SIZE]; unsigned char digest[EVP_MAX_MD_SIZE + 1]; HashMethod type; type = HashIdFromName("sha1"); HashString(string, strlen(string), digest, type); snprintf(buf, CF_BUFSIZE, "%s_%s", string, SkipHashType(HashPrintSafe(hashbuffer, sizeof(hashbuffer), digest, type, true))); } else { snprintf(buf, CF_BUFSIZE, "%s", string); } return FnReturn(CanonifyName(buf)); } /*********************************************************************/ static FnCallResult FnCallTextXform(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { char *string = RlistScalarValue(finalargs); const size_t len = strlen(string); /* In case of string_length(), buf needs enough space to hold a number. */ const size_t bufsiz = MAX(len + 1, PRINTSIZE(len)); char *buf = xcalloc(bufsiz, sizeof(char)); memcpy(buf, string, len + 1); if (StringEqual(fp->name, "string_downcase")) { for (size_t pos = 0; pos < len; pos++) { buf[pos] = tolower(buf[pos]); } } else if (StringEqual(fp->name, "string_upcase")) { for (size_t pos = 0; pos < len; pos++) { buf[pos] = toupper(buf[pos]); } } else if (StringEqual(fp->name, "string_reverse")) { if (len > 1) { size_t c, i, j; for (i = 0, j = len - 1; i < j; i++, j--) { c = buf[i]; buf[i] = buf[j]; buf[j] = c; } } } else if (StringEqual(fp->name, "string_length")) { xsnprintf(buf, bufsiz, "%zu", len); } else if (StringEqual(fp->name, "string_head")) { long max = IntFromString(RlistScalarValue(finalargs->next)); // A negative offset -N on string_head() means the user wants up to the Nth from the end if (max < 0) { max = len - labs(max); } // If the negative offset was too big, return an empty string if (max < 0) { max = 0; } if ((size_t) max < bufsiz) { buf[max] = '\0'; } } else if (StringEqual(fp->name, "string_tail")) { const long max = IntFromString(RlistScalarValue(finalargs->next)); // A negative offset -N on string_tail() means the user wants up to the Nth from the start if (max < 0) { size_t offset = MIN(labs(max), len); memcpy(buf, string + offset , len - offset + 1); } else if ((size_t) max < len) { memcpy(buf, string + len - max, max + 1); } } else { Log(LOG_LEVEL_ERR, "text xform with unknown call function %s, aborting", fp->name); free(buf); return FnFailure(); } return FnReturnNoCopy(buf); } /*********************************************************************/ static FnCallResult FnCallLastNode(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *name = RlistScalarValue(finalargs); char *split = RlistScalarValue(finalargs->next); Rlist *newlist = RlistFromSplitRegex(name, split, 100, true); if (newlist != NULL) { char *res = NULL; const Rlist *rp = newlist; while (rp->next != NULL) { rp = rp->next; } assert(rp && !rp->next); if (rp->val.item) { res = xstrdup(RlistScalarValue(rp)); } RlistDestroy(newlist); if (res) { return FnReturnNoCopy(res); } } return FnFailure(); } /*******************************************************************/ static FnCallResult FnCallDirname(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char dir[PATH_MAX]; strlcpy(dir, RlistScalarValue(finalargs), PATH_MAX); DeleteSlash(dir); ChopLastNode(dir); return FnReturn(dir); } /*********************************************************************/ static FnCallResult FnCallClassify(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { bool is_defined = IsDefinedClass(ctx, CanonifyName(RlistScalarValue(finalargs))); return FnReturnContext(is_defined); } /*********************************************************************/ static VersionComparison GenericVersionCheck( const FnCall *fp, const Rlist *args) { assert(fp != NULL); assert(fp->name != NULL); if (args == NULL) { Log(LOG_LEVEL_ERR, "Policy fuction %s requires version to compare against", fp->name); return VERSION_ERROR; } const char *ver_string = RlistScalarValue(args); VersionComparison comparison = CompareVersion(Version(), ver_string); if (comparison == VERSION_ERROR) { Log(LOG_LEVEL_ERR, "%s: Format of version comparison string '%s' is incorrect", fp->name, ver_string); return VERSION_ERROR; } return comparison; } static FnCallResult FnCallVersionCompare( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { assert(fp != NULL); assert(fp->name != NULL); if (args == NULL || args->next == NULL || args->next->next == NULL) { Log(LOG_LEVEL_ERR, "Policy function %s requires 3 arguments:" " %s(version, operator, version)", fp->name, fp->name); return FnFailure(); } const char *const version_a = RlistScalarValue(args); const char *const operator = RlistScalarValue(args->next); const char *const version_b = RlistScalarValue(args->next->next); const BooleanOrError result = CompareVersionExpression(version_a, operator, version_b); if (result == BOOLEAN_ERROR) { Log(LOG_LEVEL_ERR, "Cannot compare versions: %s(\"%s\", \"%s\", \"%s\")", fp->name, version_a, operator, version_b); return FnFailure(); } return FnReturnContext(result == BOOLEAN_TRUE); } static FnCallResult FnCallVersionMinimum( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { const VersionComparison comparison = GenericVersionCheck(fp, args); if (comparison == VERSION_ERROR) { return FnFailure(); } return FnReturnContext(comparison == VERSION_GREATER || comparison == VERSION_EQUAL); } static FnCallResult FnCallVersionAfter( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { const VersionComparison comparison = GenericVersionCheck(fp, args); if (comparison == VERSION_ERROR) { return FnFailure(); } return FnReturnContext(comparison == VERSION_GREATER); } static FnCallResult FnCallVersionMaximum( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { const VersionComparison comparison = GenericVersionCheck(fp, args); if (comparison == VERSION_ERROR) { return FnFailure(); } return FnReturnContext(comparison == VERSION_SMALLER || comparison == VERSION_EQUAL); } static FnCallResult FnCallVersionBefore( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { const VersionComparison comparison = GenericVersionCheck(fp, args); if (comparison == VERSION_ERROR) { return FnFailure(); } return FnReturnContext(comparison == VERSION_SMALLER); } static FnCallResult FnCallVersionAt( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { const VersionComparison comparison = GenericVersionCheck(fp, args); if (comparison == VERSION_ERROR) { return FnFailure(); } return FnReturnContext(comparison == VERSION_EQUAL); } static FnCallResult FnCallVersionBetween( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { assert(fp != NULL); assert(fp->name != NULL); if (args == NULL || args->next == NULL) { Log(LOG_LEVEL_ERR, "Policy fuction %s requires lower " "and upper versions to compare against", fp->name); return FnFailure(); } const char *ver_string_lower = RlistScalarValue(args); const VersionComparison lower_comparison = CompareVersion(Version(), ver_string_lower); if (lower_comparison == VERSION_ERROR) { Log(LOG_LEVEL_ERR, "%s: Format of lower version comparison string '%s' is incorrect", fp->name, ver_string_lower); return FnFailure(); } const char *ver_string_upper = RlistScalarValue(args->next); const VersionComparison upper_comparison = CompareVersion(Version(), ver_string_upper); if (upper_comparison == VERSION_ERROR) { Log(LOG_LEVEL_ERR, "%s: Format of upper version comparison string '%s' is incorrect", fp->name, ver_string_upper); return FnFailure(); } return FnReturnContext((lower_comparison == VERSION_GREATER || lower_comparison == VERSION_EQUAL) && (upper_comparison == VERSION_SMALLER || upper_comparison == VERSION_EQUAL)); } /*********************************************************************/ /* Executions */ /*********************************************************************/ static FnCallResult FnCallReturnsZero(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { char comm[CF_BUFSIZE]; const char *shell_option = RlistScalarValue(finalargs->next); ShellType shelltype = SHELL_TYPE_NONE; bool need_executable_check = false; if (strcmp(shell_option, "useshell") == 0) { shelltype = SHELL_TYPE_USE; } else if (strcmp(shell_option, "powershell") == 0) { shelltype = SHELL_TYPE_POWERSHELL; } if (IsAbsoluteFileName(RlistScalarValue(finalargs))) { need_executable_check = true; } else if (shelltype == SHELL_TYPE_NONE) { Log(LOG_LEVEL_ERR, "returnszero '%s' does not have an absolute path", RlistScalarValue(finalargs)); return FnReturnContext(false); } if (need_executable_check && !IsExecutable(CommandArg0(RlistScalarValue(finalargs)))) { Log(LOG_LEVEL_ERR, "returnszero '%s' is assumed to be executable but isn't", RlistScalarValue(finalargs)); return FnReturnContext(false); } snprintf(comm, CF_BUFSIZE, "%s", RlistScalarValue(finalargs)); if (ShellCommandReturnsZero(comm, shelltype)) { Log(LOG_LEVEL_VERBOSE, "%s ran '%s' successfully and it returned zero", fp->name, RlistScalarValue(finalargs)); return FnReturnContext(true); } else { Log(LOG_LEVEL_VERBOSE, "%s ran '%s' successfully and it did not return zero", fp->name, RlistScalarValue(finalargs)); return FnReturnContext(false); } } /*********************************************************************/ static FnCallResult FnCallExecResult(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { assert(fp != NULL); const char *const function = fp->name; size_t args = RlistLen(finalargs); if (args == 0) { FatalError(ctx, "Missing argument to %s() - Must specify command", function); } else if (args == 1) { FatalError(ctx, "Missing argument to %s() - Must specify 'noshell', 'useshell', or 'powershell'", function); } else if (args > 3) { FatalError(ctx, "Too many arguments to %s() - Maximum 3 allowed", function); } const char *shell_option = RlistScalarValue(finalargs->next); ShellType shelltype = SHELL_TYPE_NONE; bool need_executable_check = false; if (strcmp(shell_option, "useshell") == 0) { shelltype = SHELL_TYPE_USE; } else if (strcmp(shell_option, "powershell") == 0) { shelltype = SHELL_TYPE_POWERSHELL; } const char *const command = RlistScalarValue(finalargs); if (IsAbsoluteFileName(command)) { need_executable_check = true; } else if (shelltype == SHELL_TYPE_NONE) { Log(LOG_LEVEL_ERR, "%s '%s' does not have an absolute path", fp->name, command); return FnFailure(); } if (need_executable_check && !IsExecutable(CommandArg0(command))) { Log(LOG_LEVEL_ERR, "%s '%s' is assumed to be executable but isn't", fp->name, command); return FnFailure(); } size_t buffer_size = CF_EXPANDSIZE; char *buffer = xcalloc(1, buffer_size); OutputSelect output_select = OUTPUT_SELECT_BOTH; if (args >= 3) { const char *output = RlistScalarValue(finalargs->next->next); if (StringEqual(output, "stderr")) { output_select = OUTPUT_SELECT_STDERR; } else if (StringEqual(output, "stdout")) { output_select = OUTPUT_SELECT_STDOUT; } else { assert(StringEqual(output, "both")); assert(output_select == OUTPUT_SELECT_BOTH); } } int exit_code; if (GetExecOutput(command, &buffer, &buffer_size, shelltype, output_select, &exit_code)) { Log(LOG_LEVEL_VERBOSE, "%s ran '%s' successfully", fp->name, command); if (StringEqual(function, "execresult")) { FnCallResult res = FnReturn(buffer); free(buffer); return res; } else { assert(StringEqual(function, "execresult_as_data")); JsonElement *result = JsonObjectCreate(2); JsonObjectAppendInteger(result, "exit_code", exit_code); JsonObjectAppendString(result, "output", buffer); free(buffer); return FnReturnContainerNoCopy(result); } } else { Log(LOG_LEVEL_VERBOSE, "%s could not run '%s' successfully", fp->name, command); free(buffer); return FnFailure(); } } /*********************************************************************/ static FnCallResult FnCallUseModule(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) /* usemodule("/programpath",varargs) */ { char modulecmd[CF_BUFSIZE]; struct stat statbuf; char *command = RlistScalarValue(finalargs); char *args = RlistScalarValue(finalargs->next); const char* const workdir = GetWorkDir(); snprintf(modulecmd, CF_BUFSIZE, "\"%s%cmodules%c%s\"", workdir, FILE_SEPARATOR, FILE_SEPARATOR, command); if (stat(CommandArg0(modulecmd), &statbuf) == -1) { Log(LOG_LEVEL_ERR, "Plug-in module '%s' not found", modulecmd); return FnFailure(); } if ((statbuf.st_uid != 0) && (statbuf.st_uid != getuid())) { Log(LOG_LEVEL_ERR, "Module '%s' was not owned by uid %ju who is executing agent", modulecmd, (uintmax_t)getuid()); return FnFailure(); } snprintf(modulecmd, CF_BUFSIZE, "\"%s%cmodules%c%s\" %s", workdir, FILE_SEPARATOR, FILE_SEPARATOR, command, args); Log(LOG_LEVEL_VERBOSE, "Executing and using module [%s]", modulecmd); if (!ExecModule(ctx, modulecmd)) { return FnFailure(); } return FnReturnContext(true); } /*********************************************************************/ /* Misc */ /*********************************************************************/ static FnCallResult FnCallSplayClass(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char class_name[CF_MAXVARSIZE]; Interval splay_policy = IntervalFromString(RlistScalarValue(finalargs->next)); if (splay_policy == INTERVAL_HOURLY) { /* 12 5-minute slots in hour */ int slot = StringHash(RlistScalarValue(finalargs), 0); slot &= (SPLAY_PSEUDO_RANDOM_CONSTANT - 1); slot = slot * 12 / SPLAY_PSEUDO_RANDOM_CONSTANT; snprintf(class_name, CF_MAXVARSIZE, "Min%02d_%02d", slot * 5, ((slot + 1) * 5) % 60); } else { /* 12*24 5-minute slots in day */ int dayslot = StringHash(RlistScalarValue(finalargs), 0); dayslot &= (SPLAY_PSEUDO_RANDOM_CONSTANT - 1); dayslot = dayslot * 12 * 24 / SPLAY_PSEUDO_RANDOM_CONSTANT; int hour = dayslot / 12; int slot = dayslot % 12; snprintf(class_name, CF_MAXVARSIZE, "Min%02d_%02d.Hr%02d", slot * 5, ((slot + 1) * 5) % 60, hour); } Log(LOG_LEVEL_VERBOSE, "Computed context for '%s' splayclass: '%s'", RlistScalarValue(finalargs), class_name); return FnReturnContext(IsDefinedClass(ctx, class_name)); } /*********************************************************************/ #ifdef HAVE_LIBCURL struct _curl_userdata { const FnCall *fp; const char *desc; size_t max_size; Buffer* content; }; static size_t cfengine_curl_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) { struct _curl_userdata *options = (struct _curl_userdata*) userdata; unsigned int old = BufferSize(options->content); size_t requested = size*nmemb; size_t granted = requested; if (old + requested > options->max_size) { granted = options->max_size - old; Log(LOG_LEVEL_VERBOSE, "%s: while receiving %s, current %u + requested %zu bytes would be over the maximum %zu; only accepting %zu bytes", options->fp->name, options->desc, old, requested, options->max_size, granted); } BufferAppend(options->content, ptr, granted); // `written` is actually (BufferSize(options->content) - old) but // libcurl doesn't like that size_t written = requested; // extra caution BufferTrimToMaxLength(options->content, options->max_size); return written; } static void CurlCleanup() { if (CURL_CACHE == NULL) { JsonElement *temp = CURL_CACHE; CURL_CACHE = NULL; JsonDestroy(temp); } if (CURL_INITIALIZED) { curl_global_cleanup(); CURL_INITIALIZED = false; } } #endif static FnCallResult FnCallUrlGet(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { #ifdef HAVE_LIBCURL char *url = RlistScalarValue(finalargs); bool allocated = false; JsonElement *options = VarNameOrInlineToJson(ctx, fp, finalargs->next, false, &allocated); if (options == NULL) { return FnFailure(); } if (JsonGetElementType(options) != JSON_ELEMENT_TYPE_CONTAINER || JsonGetContainerType(options) != JSON_CONTAINER_TYPE_OBJECT) { JsonDestroyMaybe(options, allocated); return FnFailure(); } Writer *cache_w = StringWriter(); WriterWriteF(cache_w, "url = %s; options = ", url); JsonWriteCompact(cache_w, options); if (CURL_CACHE == NULL) { CURL_CACHE = JsonObjectCreate(10); atexit(&CurlCleanup); } JsonElement *old_result = JsonObjectGetAsObject(CURL_CACHE, StringWriterData(cache_w)); if (old_result != NULL) { Log(LOG_LEVEL_VERBOSE, "%s: found cached request for %s", fp->name, url); WriterClose(cache_w); JsonDestroyMaybe(options, allocated); return FnReturnContainer(old_result); } if (!CURL_INITIALIZED && curl_global_init(CURL_GLOBAL_DEFAULT) != 0) { Log(LOG_LEVEL_ERR, "%s: libcurl initialization failed, sorry", fp->name); WriterClose(cache_w); JsonDestroyMaybe(options, allocated); return FnFailure(); } CURL_INITIALIZED = true; CURL *curl = curl_easy_init(); if (!curl) { Log(LOG_LEVEL_ERR, "%s: libcurl easy_init failed, sorry", fp->name); WriterClose(cache_w); JsonDestroyMaybe(options, allocated); return FnFailure(); } Buffer *content = BufferNew(); Buffer *headers = BufferNew(); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // do not use signals curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3L); // set default timeout curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, // Allowed protocols "file,ftp,ftps,http,https"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cfengine_curl_write_callback); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, cfengine_curl_write_callback); size_t max_content = 4096; size_t max_headers = 4096; JsonIterator iter = JsonIteratorInit(options); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { const char *key = JsonIteratorCurrentKey(&iter); const char *value = JsonPrimitiveGetAsString(e); if (strcmp(key, "url.timeout") == 0) { Log(LOG_LEVEL_VERBOSE, "%s: setting timeout to %ld seconds", fp->name, IntFromString(value)); curl_easy_setopt(curl, CURLOPT_TIMEOUT, IntFromString(value)); } else if (strcmp(key, "url.verbose") == 0) { Log(LOG_LEVEL_VERBOSE, "%s: setting verbosity to %ld", fp->name, IntFromString(value)); curl_easy_setopt(curl, CURLOPT_VERBOSE, IntFromString(value)); } else if (strcmp(key, "url.header") == 0) { Log(LOG_LEVEL_VERBOSE, "%s: setting inline headers to %ld", fp->name, IntFromString(value)); curl_easy_setopt(curl, CURLOPT_HEADER, IntFromString(value)); } else if (strcmp(key, "url.referer") == 0) { Log(LOG_LEVEL_VERBOSE, "%s: setting referer to %s", fp->name, value); curl_easy_setopt(curl, CURLOPT_REFERER, value); } else if (strcmp(key, "url.user-agent") == 0) { Log(LOG_LEVEL_VERBOSE, "%s: setting user agent string to %s", fp->name, value); curl_easy_setopt(curl, CURLOPT_USERAGENT, value); } else if (strcmp(key, "url.max_content") == 0) { Log(LOG_LEVEL_VERBOSE, "%s: setting max contents to %ld", fp->name, IntFromString(value)); max_content = IntFromString(value); } else if (strcmp(key, "url.max_headers") == 0) { Log(LOG_LEVEL_VERBOSE, "%s: setting max headers to %ld", fp->name, IntFromString(value)); max_headers = IntFromString(value); } else { Log(LOG_LEVEL_INFO, "%s: unknown option %s", fp->name, key); } } struct _curl_userdata data = { fp, "content", max_content, content }; curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); struct _curl_userdata header_data = { fp, "headers", max_headers, headers }; curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header_data); JsonElement *options_headers = JsonObjectGetAsArray(options, "url.headers"); struct curl_slist *header_list = NULL; if (options_headers != NULL) { iter = JsonIteratorInit(options_headers); while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { header_list = curl_slist_append(header_list, JsonPrimitiveGetAsString(e)); } } if (header_list != NULL) { curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list); } JsonElement *result = JsonObjectCreate(10); CURLcode res = curl_easy_perform(curl); if (header_list != NULL) { curl_slist_free_all(header_list); header_list = NULL; } long returncode = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &returncode); JsonObjectAppendInteger(result, "returncode", returncode); curl_easy_cleanup(curl); JsonObjectAppendInteger(result, "rc", 0+res); bool success = (CURLE_OK == res); JsonObjectAppendBool(result, "success", success); if (!success) { JsonObjectAppendString(result, "error_message", curl_easy_strerror(res)); } BufferTrimToMaxLength(content, max_content); JsonObjectAppendString(result, "content", BufferData(content)); BufferDestroy(content); BufferTrimToMaxLength(headers, max_headers); JsonObjectAppendString(result, "headers", BufferData(headers)); BufferDestroy(headers); JsonObjectAppendObject(CURL_CACHE, StringWriterData(cache_w), JsonCopy(result)); WriterClose(cache_w); JsonDestroyMaybe(options, allocated); return FnReturnContainerNoCopy(result); #else UNUSED(finalargs); /* suppress unused parameter warning */ Log(LOG_LEVEL_ERR, "%s: libcurl integration is not compiled into CFEngine, sorry", fp->name); return FnFailure(); #endif } /*********************************************************************/ /* ReadTCP(localhost,80,'GET index.html',1000) */ static FnCallResult FnCallReadTcp(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *hostnameip = RlistScalarValue(finalargs); char *port = RlistScalarValue(finalargs->next); char *sendstring = RlistScalarValue(finalargs->next->next); ssize_t maxbytes = IntFromString(RlistScalarValue(finalargs->next->next->next)); if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON) { return FnFailure(); } if (maxbytes < 0 || maxbytes > CF_BUFSIZE - 1) { Log(LOG_LEVEL_VERBOSE, "readtcp: invalid number of bytes %zd to read, defaulting to %d", maxbytes, CF_BUFSIZE - 1); maxbytes = CF_BUFSIZE - 1; } char txtaddr[CF_MAX_IP_LEN] = ""; int sd = SocketConnect(hostnameip, port, CONNTIMEOUT, false, txtaddr, sizeof(txtaddr)); if (sd == -1) { Log(LOG_LEVEL_INFO, "readtcp: Couldn't connect. (socket: %s)", GetErrorStr()); return FnFailure(); } if (strlen(sendstring) > 0) { int sent = 0; int result = 0; size_t length = strlen(sendstring); do { result = send(sd, sendstring, length, 0); if (result < 0) { cf_closesocket(sd); return FnFailure(); } else { sent += result; } } while ((size_t) sent < length); } char recvbuf[CF_BUFSIZE]; ssize_t n_read = recv(sd, recvbuf, maxbytes, 0); cf_closesocket(sd); if (n_read < 0) { Log(LOG_LEVEL_INFO, "readtcp: Error while receiving (%s)", GetErrorStr()); return FnFailure(); } assert((size_t) n_read < sizeof(recvbuf)); recvbuf[n_read] = '\0'; Log(LOG_LEVEL_VERBOSE, "readtcp: requested %zd maxbytes, got %zd bytes from %s", maxbytes, n_read, txtaddr); return FnReturn(recvbuf); } /*********************************************************************/ /** * Look for the indices of a variable in #finalargs if it is an array. * * @return *Always* return an slist of the indices; if the variable is not an * array or does not resolve at all, return an empty slist. * * @NOTE * This is needed for literally one acceptance test: * 01_vars/02_functions/getindices_returns_expected_list_from_array.cf * * The case is that we have a[x] = "1" AND a[x][y] = "2" which is * ambiguous, but classic CFEngine arrays allow it. So we want the * classic getindices("a[x]") to return "y" in this case. */ static FnCallResult FnCallGetIndicesClassic(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { VarRef *ref = VarRefParse(RlistScalarValue(finalargs)); if (!VarRefIsQualified(ref)) { if (fp->caller) { const Bundle *caller_bundle = PromiseGetBundle(fp->caller); VarRefQualify(ref, caller_bundle->ns, caller_bundle->name); } else { Log(LOG_LEVEL_WARNING, "Function '%s' was given an unqualified variable reference, " "and it was not called from a promise. " "No way to automatically qualify the reference '%s'", fp->name, RlistScalarValue(finalargs)); VarRefDestroy(ref); return FnFailure(); } } Rlist *keys = NULL; VariableTableIterator *iter = EvalContextVariableTableFromRefIteratorNew(ctx, ref); const Variable *itervar; while ((itervar = VariableTableIteratorNext(iter)) != NULL) { const VarRef *itervar_ref = VariableGetRef(itervar); /* Log(LOG_LEVEL_DEBUG, "%s(%s): got itervar->ref->num_indices %zu while ref->num_indices is %zu", fp->name, RlistScalarValue(finalargs), itervar->ref->num_indices, ref->num_indices); */ /* Does the variable we found have more indices than the one we * requested? For example, if we requested the variable "blah", it has * 0 indices, so a found variable blah[i] will be acceptable. */ if (itervar_ref->num_indices > ref->num_indices) { RlistAppendScalarIdemp(&keys, itervar_ref->indices[ref->num_indices]); } } VariableTableIteratorDestroy(iter); VarRefDestroy(ref); return (FnCallResult) { FNCALL_SUCCESS, { keys, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallGetIndices(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *name_str = RlistScalarValueSafe(finalargs); bool allocated = false; JsonElement *json = NULL; // Protect against collected args (their rval type will be data // container). This is a special case to preserve legacy behavior // for array lookups that requires a scalar in finalargs. if (RlistValueIsType(finalargs, RVAL_TYPE_SCALAR)) { VarRef *ref = ResolveAndQualifyVarName(fp, name_str); DataType type; EvalContextVariableGet(ctx, ref, &type); /* A variable holding a data container. */ if (type == CF_DATA_TYPE_CONTAINER) { json = VarRefValueToJson(ctx, fp, ref, NULL, 0, true, &allocated); } /* Resolves to a different type or does not resolve at all. It's * normal not to resolve, for example "blah" will not resolve if the * variable table only contains "blah[1]"; we have to go through * FnCallGetIndicesClassic() to extract these indices. */ else { JsonParseError res = JsonParseWithLookup(ctx, &LookupVarRefToJson, &name_str, &json); if (res == JSON_PARSE_OK) { if (JsonGetElementType(json) == JSON_ELEMENT_TYPE_PRIMITIVE) { // VarNameOrInlineToJson() would now look up this primitive // in the variable table, returning a JSON container for // whatever type it is, but since we already know that it's // not a native container type (thanks to the // CF_DATA_TYPE_CONTAINER check above) we skip that, and // stick to the legacy data types. JsonDestroy(json); VarRefDestroy(ref); return FnCallGetIndicesClassic(ctx, policy, fp, finalargs); } else { // Inline JSON of some sort. allocated = true; } } else { /* Invalid inline JSON. */ VarRefDestroy(ref); return FnCallGetIndicesClassic(ctx, policy, fp, finalargs); } } VarRefDestroy(ref); } else { json = VarNameOrInlineToJson(ctx, fp, finalargs, true, &allocated); } // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } Rlist *keys = NULL; if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { JsonDestroyMaybe(json, allocated); return (FnCallResult) { FNCALL_SUCCESS, { keys, RVAL_TYPE_LIST } }; } if (JsonGetContainerType(json) == JSON_CONTAINER_TYPE_OBJECT) { JsonIterator iter = JsonIteratorInit(json); const char *key; while ((key = JsonIteratorNextKey(&iter))) { RlistAppendScalar(&keys, key); } } else { for (size_t i = 0; i < JsonLength(json); i++) { Rval key = (Rval) { StringFromLong(i), RVAL_TYPE_SCALAR }; RlistAppendRval(&keys, key); } } JsonDestroyMaybe(json, allocated); return (FnCallResult) { FNCALL_SUCCESS, { keys, RVAL_TYPE_LIST } }; } /*********************************************************************/ void CollectContainerValues(EvalContext *ctx, Rlist **values, const JsonElement *container) { if (JsonGetElementType(container) == JSON_ELEMENT_TYPE_CONTAINER) { JsonIterator iter = JsonIteratorInit(container); const JsonElement *el; while ((el = JsonIteratorNextValue(&iter))) { if (JsonGetElementType(el) == JSON_ELEMENT_TYPE_CONTAINER) { CollectContainerValues(ctx, values, el); } else { char *value = JsonPrimitiveToString(el); if (value != NULL) { RlistAppendScalar(values, value); free(value); } } } } else if (JsonGetElementType(container) == JSON_ELEMENT_TYPE_PRIMITIVE) { char *value = JsonPrimitiveToString(container); if (value != NULL) { RlistAppendScalar(values, value); free(value); } } } /*********************************************************************/ static FnCallResult FnCallGetValues(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, true, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { /* CFE-2479: Inexistent variable, return an empty slist. */ Log(LOG_LEVEL_DEBUG, "getvalues('%s'):" " unresolvable variable, returning an empty list", RlistScalarValueSafe(finalargs)); return (FnCallResult) { FNCALL_SUCCESS, { NULL, RVAL_TYPE_LIST } }; } Rlist *values = NULL; /* start with an empty Rlist */ CollectContainerValues(ctx, &values, json); JsonDestroyMaybe(json, allocated); return (FnCallResult) { FNCALL_SUCCESS, { values, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallGrep(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { return FilterInternal(ctx, fp, RlistScalarValue(finalargs), // regex finalargs->next, // list identifier 1, // regex match = TRUE 0, // invert matches = FALSE LONG_MAX); // max results = max int } /*********************************************************************/ static FnCallResult FnCallRegList(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { return FilterInternal(ctx, fp, RlistScalarValue(finalargs->next), // regex or string finalargs, // list identifier 1, 0, LONG_MAX); } /*********************************************************************/ static FnCallResult JoinContainer(const JsonElement *container, const char *delimiter) { JsonIterator iter = JsonIteratorInit(container); const JsonElement *e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true); if (!e) { return FnReturn(""); } Buffer *result = BufferNew(); BufferAppendString(result, JsonPrimitiveGetAsString(e)); while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { BufferAppendString(result, delimiter); BufferAppendString(result, JsonPrimitiveGetAsString(e)); } return FnReturnBuffer(result); } static FnCallResult FnCallJoin(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { const char *delimiter = RlistScalarValue(finalargs); const char *name_str = RlistScalarValueSafe(finalargs->next); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs->next, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } FnCallResult result = JoinContainer(json, delimiter); JsonDestroyMaybe(json, allocated); return result; } /*********************************************************************/ static FnCallResult FnCallGetFields(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { Regex *rx = CompileRegex(RlistScalarValue(finalargs)); if (!rx) { return FnFailure(); } const char *filename = RlistScalarValue(finalargs->next); const char *split = RlistScalarValue(finalargs->next->next); const char *array_lval = RlistScalarValue(finalargs->next->next->next); FILE *fin = safe_fopen(filename, "rt"); if (!fin) { Log(LOG_LEVEL_ERR, "File '%s' could not be read in getfields(). (fopen: %s)", filename, GetErrorStr()); RegexDestroy(rx); return FnFailure(); } size_t line_size = CF_BUFSIZE; char *line = xmalloc(CF_BUFSIZE); int line_count = 0; while (CfReadLine(&line, &line_size, fin) != -1) { if (!StringMatchFullWithPrecompiledRegex(rx, line)) { continue; } if (line_count == 0) { Rlist *newlist = RlistFromSplitRegex(line, split, 31, true); int vcount = 1; for (const Rlist *rp = newlist; rp != NULL; rp = rp->next) { char name[CF_MAXVARSIZE]; snprintf(name, CF_MAXVARSIZE - 1, "%s[%d]", array_lval, vcount); VarRef *ref = VarRefParse(name); if (!VarRefIsQualified(ref)) { if (fp->caller) { const Bundle *caller_bundle = PromiseGetBundle(fp->caller); VarRefQualify(ref, caller_bundle->ns, caller_bundle->name); } else { Log(LOG_LEVEL_WARNING, "Function '%s' was given an unqualified variable reference, " "and it was not called from a promise. No way to automatically qualify the reference '%s'.", fp->name, RlistScalarValue(finalargs)); VarRefDestroy(ref); free(line); RlistDestroy(newlist); RegexDestroy(rx); return FnFailure(); } } EvalContextVariablePut(ctx, ref, RlistScalarValue(rp), CF_DATA_TYPE_STRING, "source=function,function=getfields"); VarRefDestroy(ref); Log(LOG_LEVEL_VERBOSE, "getfields: defining '%s' => '%s'", name, RlistScalarValue(rp)); vcount++; } RlistDestroy(newlist); } line_count++; } RegexDestroy(rx); free(line); if (!feof(fin)) { Log(LOG_LEVEL_ERR, "Unable to read data from file '%s'. (fgets: %s)", filename, GetErrorStr()); fclose(fin); return FnFailure(); } fclose(fin); return FnReturnF("%d", line_count); } /*********************************************************************/ static FnCallResult FnCallCountLinesMatching(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { Regex *rx = CompileRegex(RlistScalarValue(finalargs)); if (!rx) { return FnFailure(); } char *filename = RlistScalarValue(finalargs->next); FILE *fin = safe_fopen(filename, "rt"); if (!fin) { Log(LOG_LEVEL_ERR, "File '%s' could not be read in countlinesmatching(). (fopen: %s)", filename, GetErrorStr()); RegexDestroy(rx); return FnReturn("0"); } int lcount = 0; { size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); while (CfReadLine(&line, &line_size, fin) != -1) { if (StringMatchFullWithPrecompiledRegex(rx, line)) { lcount++; Log(LOG_LEVEL_VERBOSE, "countlinesmatching: matched '%s'", line); continue; } } free(line); } RegexDestroy(rx); if (!feof(fin)) { Log(LOG_LEVEL_ERR, "Unable to read data from file '%s'. (fgets: %s)", filename, GetErrorStr()); fclose(fin); return FnFailure(); } fclose(fin); return FnReturnF("%d", lcount); } /*********************************************************************/ static FnCallResult FnCallLsDir(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { Rlist *newlist = NULL; char *dirname = RlistScalarValue(finalargs); char *regex = RlistScalarValue(finalargs->next); int includepath = BooleanFromString(RlistScalarValue(finalargs->next->next)); Dir *dirh = DirOpen(dirname); if (dirh == NULL) { Log(LOG_LEVEL_ERR, "Directory '%s' could not be accessed in lsdir(), (opendir: %s)", dirname, GetErrorStr()); return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } const struct dirent *dirp; for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (strlen(regex) == 0 || StringMatchFull(regex, dirp->d_name)) { if (includepath) { char line[CF_BUFSIZE]; snprintf(line, CF_BUFSIZE, "%s/%s", dirname, dirp->d_name); MapName(line); RlistPrepend(&newlist, line, RVAL_TYPE_SCALAR); } else { RlistPrepend(&newlist, dirp->d_name, RVAL_TYPE_SCALAR); } } } DirClose(dirh); return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ bool EvalContextVariablePutSpecialEscaped(EvalContext *ctx, SpecialScope scope, const char *lval, const void *value, DataType type, const char *tags, bool escape) { if (escape) { char *escaped = EscapeCharCopy(value, '"', '\\'); bool ret = EvalContextVariablePutSpecial(ctx, scope, lval, escaped, type, tags); free(escaped); return ret; } return EvalContextVariablePutSpecial(ctx, scope, lval, value, type, tags); } /*********************************************************************/ static JsonElement* ExecJSON_Pipe(const char *cmd, JsonElement *container) { IOData io = cf_popen_full_duplex(cmd, false, false); if (io.write_fd == -1 || io.read_fd == -1) { Log(LOG_LEVEL_INFO, "An error occurred while communicating with '%s'", cmd); return NULL; } Log(LOG_LEVEL_DEBUG, "Opened fds %d and %d for command '%s'.", io.read_fd, io.write_fd, cmd); // write the container to a string Writer *w = StringWriter(); JsonWrite(w, container, 0); char *container_str = StringWriterClose(w); ssize_t written = PipeWrite(&io, container_str); if (written < 0) { Log(LOG_LEVEL_ERR, "Failed to write to pipe (fd = %d): %s", io.write_fd, GetErrorStr()); free(container_str); container_str = NULL; } else if ((size_t) written != strlen(container_str)) { Log(LOG_LEVEL_VERBOSE, "Couldn't send whole container data to '%s'.", cmd); free(container_str); container_str = NULL; } Rlist *returnlist = NULL; if (container_str) { free(container_str); /* We can have some error message here. */ returnlist = PipeReadData(&io, 5, 5); } /* If script returns non 0 status */ int close = cf_pclose_full_duplex(&io); if (close != EXIT_SUCCESS) { Log(LOG_LEVEL_VERBOSE, "%s returned with non zero return code: %d", cmd, close); } // Exit if no data was obtained from the pipe if (returnlist == NULL) { return NULL; } JsonElement *returnjq = JsonArrayCreate(5); Buffer *buf = BufferNew(); for (const Rlist *rp = returnlist; rp != NULL; rp = rp->next) { const char *data = RlistScalarValue(rp); if (BufferSize(buf) != 0) { // simulate the newline BufferAppendString(buf, "\n"); } BufferAppendString(buf, data); const char *bufdata = BufferData(buf); JsonElement *parsed = NULL; if (JsonParse(&bufdata, &parsed) == JSON_PARSE_OK) { JsonArrayAppendElement(returnjq, parsed); BufferClear(buf); } else { Log(LOG_LEVEL_DEBUG, "'%s' generated invalid JSON '%s', appending next line", cmd, data); } } BufferDestroy(buf); RlistDestroy(returnlist); return returnjq; } /*********************************************************************/ static FnCallResult FnCallMapData(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, ARG_UNUSED const Rlist *finalargs) { if (!fp->caller) { Log(LOG_LEVEL_ERR, "Function '%s' must be called from a promise", fp->name); return FnFailure(); } bool mapdatamode = (strcmp(fp->name, "mapdata") == 0); Rlist *returnlist = NULL; // This is a delayed evaluation function, so we have to resolve arguments ourselves // We resolve them once now, to get the second or third argument with the iteration data Rlist *expargs = NewExpArgs(ctx, policy, fp, NULL); Rlist *varpointer = NULL; const char* conversion = NULL; if (mapdatamode) { if (expargs == NULL || RlistIsUnresolved(expargs->next->next)) { RlistDestroy(expargs); return FnFailure(); } conversion = RlistScalarValue(expargs); varpointer = expargs->next->next; } else { if (expargs == NULL || RlistIsUnresolved(expargs->next)) { RlistDestroy(expargs); return FnFailure(); } conversion = "none"; varpointer = expargs->next; } const char* varname = RlistScalarValueSafe(varpointer); bool jsonmode = (strcmp(conversion, "json") == 0); bool canonifymode = (strcmp(conversion, "canonify") == 0); bool json_pipemode = (strcmp(conversion, "json_pipe") == 0); bool allocated = false; JsonElement *container = VarNameOrInlineToJson(ctx, fp, varpointer, false, &allocated); if (container == NULL) { RlistDestroy(expargs); return FnFailure(); } if (JsonGetElementType(container) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_ERR, "Function '%s' got an unexpected non-container from argument '%s'", fp->name, varname); JsonDestroyMaybe(container, allocated); RlistDestroy(expargs); return FnFailure(); } if (mapdatamode && json_pipemode) { JsonElement *returnjson_pipe = ExecJSON_Pipe(RlistScalarValue(expargs->next), container); RlistDestroy(expargs); if (returnjson_pipe == NULL) { Log(LOG_LEVEL_ERR, "Function %s failed to get output from 'json_pipe' execution", fp->name); return FnFailure(); } JsonDestroyMaybe(container, allocated); return FnReturnContainerNoCopy(returnjson_pipe); } Buffer *expbuf = BufferNew(); if (JsonGetContainerType(container) != JSON_CONTAINER_TYPE_OBJECT) { JsonElement *temp = JsonObjectCreate(0); JsonElement *temp2 = JsonMerge(temp, container); JsonDestroy(temp); JsonDestroyMaybe(container, allocated); container = temp2; allocated = true; } JsonIterator iter = JsonIteratorInit(container); const JsonElement *e; while ((e = JsonIteratorNextValue(&iter)) != NULL) { EvalContextVariablePutSpecialEscaped(ctx, SPECIAL_SCOPE_THIS, "k", JsonGetPropertyAsString(e), CF_DATA_TYPE_STRING, "source=function,function=maparray", jsonmode); switch (JsonGetElementType(e)) { case JSON_ELEMENT_TYPE_PRIMITIVE: BufferClear(expbuf); EvalContextVariablePutSpecialEscaped(ctx, SPECIAL_SCOPE_THIS, "v", JsonPrimitiveGetAsString(e), CF_DATA_TYPE_STRING, "source=function,function=maparray", jsonmode); // This is a delayed evaluation function, so we have to resolve arguments ourselves // We resolve them every time now, to get the arg_map argument Rlist *local_expargs = NewExpArgs(ctx, policy, fp, NULL); const char *arg_map = RlistScalarValueSafe(mapdatamode ? local_expargs->next : local_expargs); ExpandScalar(ctx, PromiseGetBundle(fp->caller)->ns, PromiseGetBundle(fp->caller)->name, arg_map, expbuf); RlistDestroy(local_expargs); if (strstr(BufferData(expbuf), "$(this.k)") || strstr(BufferData(expbuf), "${this.k}") || strstr(BufferData(expbuf), "$(this.v)") || strstr(BufferData(expbuf), "${this.v}")) { RlistDestroy(returnlist); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "k"); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "v"); BufferDestroy(expbuf); JsonDestroyMaybe(container, allocated); RlistDestroy(expargs); return FnFailure(); } if (canonifymode) { BufferCanonify(expbuf); } RlistAppendScalar(&returnlist, BufferData(expbuf)); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "v"); break; case JSON_ELEMENT_TYPE_CONTAINER: { const JsonElement *e2; JsonIterator iter2 = JsonIteratorInit(e); while ((e2 = JsonIteratorNextValueByType(&iter2, JSON_ELEMENT_TYPE_PRIMITIVE, true)) != NULL) { char *key = (char*) JsonGetPropertyAsString(e2); bool havekey = (key != NULL); if (havekey) { EvalContextVariablePutSpecialEscaped(ctx, SPECIAL_SCOPE_THIS, "k[1]", key, CF_DATA_TYPE_STRING, "source=function,function=maparray", jsonmode); } BufferClear(expbuf); EvalContextVariablePutSpecialEscaped(ctx, SPECIAL_SCOPE_THIS, "v", JsonPrimitiveGetAsString(e2), CF_DATA_TYPE_STRING, "source=function,function=maparray", jsonmode); // This is a delayed evaluation function, so we have to resolve arguments ourselves // We resolve them every time now, to get the arg_map argument Rlist *local_expargs = NewExpArgs(ctx, policy, fp, NULL); const char *arg_map = RlistScalarValueSafe(mapdatamode ? local_expargs->next : local_expargs); ExpandScalar(ctx, PromiseGetBundle(fp->caller)->ns, PromiseGetBundle(fp->caller)->name, arg_map, expbuf); RlistDestroy(local_expargs); if (strstr(BufferData(expbuf), "$(this.k)") || strstr(BufferData(expbuf), "${this.k}") || (havekey && (strstr(BufferData(expbuf), "$(this.k[1])") || strstr(BufferData(expbuf), "${this.k[1]}"))) || strstr(BufferData(expbuf), "$(this.v)") || strstr(BufferData(expbuf), "${this.v}")) { RlistDestroy(returnlist); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "k"); if (havekey) { EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "k[1]"); } EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "v"); BufferDestroy(expbuf); JsonDestroyMaybe(container, allocated); RlistDestroy(expargs); return FnFailure(); } if (canonifymode) { BufferCanonify(expbuf); } RlistAppendScalarIdemp(&returnlist, BufferData(expbuf)); if (havekey) { EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "k[1]"); } EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "v"); } } break; default: break; } EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "k"); } BufferDestroy(expbuf); JsonDestroyMaybe(container, allocated); RlistDestroy(expargs); JsonElement *returnjson = NULL; // this is mapdata() if (mapdatamode) { returnjson = JsonArrayCreate(RlistLen(returnlist)); for (const Rlist *rp = returnlist; rp != NULL; rp = rp->next) { const char *data = RlistScalarValue(rp); if (jsonmode) { JsonElement *parsed = NULL; if (JsonParseWithLookup(ctx, &LookupVarRefToJson, &data, &parsed) == JSON_PARSE_OK) { JsonArrayAppendElement(returnjson, parsed); } else { Log(LOG_LEVEL_VERBOSE, "Function '%s' could not parse dynamic JSON '%s', skipping it", fp->name, data); } } else { JsonArrayAppendString(returnjson, data); } } RlistDestroy(returnlist); return FnReturnContainerNoCopy(returnjson); } // this is maparray() return (FnCallResult) { FNCALL_SUCCESS, { returnlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallMapList(EvalContext *ctx, const Policy *policy, const FnCall *fp, ARG_UNUSED const Rlist *finalargs) { // This is a delayed evaluation function, so we have to resolve arguments ourselves // We resolve them once now, to get the second argument Rlist *expargs = NewExpArgs(ctx, policy, fp, NULL); if (expargs == NULL || RlistIsUnresolved(expargs->next)) { RlistDestroy(expargs); return FnFailure(); } const char *name_str = RlistScalarValueSafe(expargs->next); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, expargs->next, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { RlistDestroy(expargs); return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); RlistDestroy(expargs); return FnFailure(); } Rlist *newlist = NULL; Buffer *expbuf = BufferNew(); JsonIterator iter = JsonIteratorInit(json); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { const char* value = JsonPrimitiveGetAsString(e); BufferClear(expbuf); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "this", value, CF_DATA_TYPE_STRING, "source=function,function=maplist"); // This is a delayed evaluation function, so we have to resolve arguments ourselves // We resolve them every time now, to get the first argument Rlist *local_expargs = NewExpArgs(ctx, policy, fp, NULL); const char *arg_map = RlistScalarValueSafe(local_expargs); ExpandScalar(ctx, NULL, "this", arg_map, expbuf); RlistDestroy(local_expargs); if (strstr(BufferData(expbuf), "$(this)") || strstr(BufferData(expbuf), "${this}")) { RlistDestroy(newlist); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "this"); BufferDestroy(expbuf); JsonDestroyMaybe(json, allocated); RlistDestroy(expargs); return FnFailure(); } RlistAppendScalar(&newlist, BufferData(expbuf)); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "this"); } BufferDestroy(expbuf); JsonDestroyMaybe(json, allocated); RlistDestroy(expargs); return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } /******************************************************************************/ static FnCallResult FnCallExpandRange(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { Rlist *newlist = NULL; const char *template = RlistScalarValue(finalargs); char *step = RlistScalarValue(finalargs->next); size_t template_size = strlen(template) + 1; char *before = xstrdup(template); char *after = xcalloc(template_size, 1); char *work = xstrdup(template); int from = CF_NOINT, to = CF_NOINT, step_size = atoi(step); if (*template == '[') { *before = '\0'; sscanf(template, "[%d-%d]%[^\n]", &from, &to, after); } else { sscanf(template, "%[^[\[][%d-%d]%[^\n]", before, &from, &to, after); } if (step_size < 1 || abs(from-to) < step_size) { FatalError(ctx, "EXPANDRANGE Step size cannot be less than 1 or greater than the interval"); } if (from == CF_NOINT || to == CF_NOINT) { FatalError(ctx, "EXPANDRANGE malformed range expression"); } if (from > to) { for (int i = from; i >= to; i -= step_size) { xsnprintf(work, template_size, "%s%d%s",before,i,after);; RlistAppendScalar(&newlist, work); } } else { for (int i = from; i <= to; i += step_size) { xsnprintf(work, template_size, "%s%d%s",before,i,after);; RlistAppendScalar(&newlist, work); } } free(before); free(after); free(work); return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } /*****************************************************************************/ static FnCallResult FnCallMergeData(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { if (RlistLen(args) == 0) { Log(LOG_LEVEL_ERR, "%s needs at least one argument, a reference to a container variable", fp->name); return FnFailure(); } for (const Rlist *arg = args; arg; arg = arg->next) { if (args->val.type != RVAL_TYPE_SCALAR && args->val.type != RVAL_TYPE_CONTAINER) { Log(LOG_LEVEL_ERR, "%s: argument is not a variable reference", fp->name); return FnFailure(); } } Seq *containers = SeqNew(10, &JsonDestroy); for (const Rlist *arg = args; arg; arg = arg->next) { // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, arg, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { SeqDestroy(containers); return FnFailure(); } // Fail on json primitives, only merge containers if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { if (allocated) { JsonDestroy(json); } char *const as_string = RvalToString(arg->val); Log(LOG_LEVEL_ERR, "%s is not mergeable as it it not a container", as_string); free(as_string); SeqDestroy(containers); return FnFailure(); } // This can be optimized better if (allocated) { SeqAppend(containers, json); } else { SeqAppend(containers, JsonCopy(json)); } } // end of args loop if (SeqLength(containers) == 1) { JsonElement *first = JsonCopy(SeqAt(containers, 0)); SeqDestroy(containers); return FnReturnContainerNoCopy(first); } else { JsonElement *first = SeqAt(containers, 0); JsonElement *second = SeqAt(containers, 1); JsonElement *result = JsonMerge(first, second); for (size_t i = 2; i < SeqLength(containers); i++) { JsonElement *cur = SeqAt(containers, i); JsonElement *tmp = JsonMerge(result, cur); JsonDestroy(result); result = tmp; } SeqDestroy(containers); return FnReturnContainerNoCopy(result); } assert(false); } JsonElement *DefaultTemplateData(const EvalContext *ctx, const char *wantbundle) { JsonElement *hash = JsonObjectCreate(30); JsonElement *classes = NULL; JsonElement *bundles = NULL; bool want_all_bundles = (wantbundle == NULL); if (want_all_bundles) // no specific bundle { classes = JsonObjectCreate(50); bundles = JsonObjectCreate(50); JsonObjectAppendObject(hash, "classes", classes); JsonObjectAppendObject(hash, "vars", bundles); ClassTableIterator *it = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls; while ((cls = ClassTableIteratorNext(it))) { char *key = ClassRefToString(cls->ns, cls->name); JsonObjectAppendBool(classes, key, true); free(key); } ClassTableIteratorDestroy(it); it = EvalContextClassTableIteratorNewLocal(ctx); while ((cls = ClassTableIteratorNext(it))) { char *key = ClassRefToString(cls->ns, cls->name); JsonObjectAppendBool(classes, key, true); free(key); } ClassTableIteratorDestroy(it); } { VariableTableIterator *it = EvalContextVariableTableIteratorNew(ctx, NULL, NULL, NULL); Variable *var; while ((var = VariableTableIteratorNext(it))) { const VarRef *var_ref = VariableGetRef(var); // TODO: need to get a CallRef, this is bad char *scope_key = ClassRefToString(var_ref->ns, var_ref->scope); JsonElement *scope_obj = NULL; if (want_all_bundles) { scope_obj = JsonObjectGetAsObject(bundles, scope_key); if (!scope_obj) { scope_obj = JsonObjectCreate(50); JsonObjectAppendObject(bundles, scope_key, scope_obj); } } else if (StringEqual(scope_key, wantbundle)) { scope_obj = hash; } free(scope_key); if (scope_obj != NULL) { char *lval_key = VarRefToString(var_ref, false); Rval var_rval = VariableGetRval(var, true); // don't collect mangled refs if (strchr(lval_key, CF_MANGLED_SCOPE) == NULL) { JsonObjectAppendElement(scope_obj, lval_key, RvalToJson(var_rval)); } free(lval_key); } } VariableTableIteratorDestroy(it); } Writer *w = StringWriter(); JsonWrite(w, hash, 0); Log(LOG_LEVEL_DEBUG, "Generated DefaultTemplateData '%s'", StringWriterData(w)); WriterClose(w); return hash; } static FnCallResult FnCallDatastate(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, ARG_UNUSED const Rlist *args) { JsonElement *state = DefaultTemplateData(ctx, NULL); return FnReturnContainerNoCopy(state); } static FnCallResult FnCallBundlestate(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, ARG_UNUSED const Rlist *args) { JsonElement *state = DefaultTemplateData(ctx, RlistScalarValue(args)); if (state == NULL || JsonGetElementType(state) != JSON_ELEMENT_TYPE_CONTAINER || JsonLength(state) < 1) { if (state != NULL) { JsonDestroy(state); } return FnFailure(); } else { return FnReturnContainerNoCopy(state); } } static FnCallResult FnCallSelectServers(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *listvar = RlistScalarValue(finalargs); const char *port = RlistScalarValue(finalargs->next); const char *sendstring = RlistScalarValue(finalargs->next->next); const char *regex = RlistScalarValue(finalargs->next->next->next); ssize_t maxbytes = IntFromString(RlistScalarValue(finalargs->next->next->next->next)); char *array_lval = xstrdup(RlistScalarValue(finalargs->next->next->next->next->next)); if (!IsQualifiedVariable(array_lval)) { if (fp->caller) { VarRef *ref = VarRefParseFromBundle(array_lval, PromiseGetBundle(fp->caller)); free(array_lval); array_lval = VarRefToString(ref, true); VarRefDestroy(ref); } else { Log(LOG_LEVEL_ERR, "Function '%s' called with an unqualifed array reference '%s', " "and the reference could not be automatically qualified as the function was not called from a promise.", fp->name, array_lval); free(array_lval); return FnFailure(); } } char naked[CF_MAXVARSIZE] = ""; if (IsVarList(listvar)) { GetNaked(naked, listvar); } else { Log(LOG_LEVEL_VERBOSE, "Function selectservers was promised a list called '%s' but this was not found", listvar); return FnFailure(); } VarRef *ref = VarRefParse(naked); DataType value_type; const Rlist *hostnameip = EvalContextVariableGet(ctx, ref, &value_type); if (value_type == CF_DATA_TYPE_NONE) { Log(LOG_LEVEL_VERBOSE, "Function selectservers was promised a list called '%s' but this was not found from context '%s.%s'", listvar, ref->scope, naked); VarRefDestroy(ref); free(array_lval); return FnFailure(); } VarRefDestroy(ref); if (DataTypeToRvalType(value_type) != RVAL_TYPE_LIST) { Log(LOG_LEVEL_VERBOSE, "Function selectservers was promised a list called '%s' but this variable is not a list", listvar); free(array_lval); return FnFailure(); } if (maxbytes < 0 || maxbytes > CF_BUFSIZE - 1) { Log(LOG_LEVEL_VERBOSE, "selectservers: invalid number of bytes %zd to read, defaulting to %d", maxbytes, CF_BUFSIZE - 1); maxbytes = CF_BUFSIZE - 1; } if (THIS_AGENT_TYPE != AGENT_TYPE_AGENT) { free(array_lval); return FnReturnF("%d", 0); } Policy *select_server_policy = PolicyNew(); { Bundle *bp = PolicyAppendBundle(select_server_policy, NamespaceDefault(), "select_server_bundle", "agent", NULL, NULL); BundleSection *sp = BundleAppendSection(bp, "select_server"); BundleSectionAppendPromise(sp, "function", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL, NULL); } size_t count = 0; for (const Rlist *rp = hostnameip; rp != NULL; rp = rp->next) { const char *host = RlistScalarValue(rp); Log(LOG_LEVEL_DEBUG, "Want to read %zd bytes from %s port %s", maxbytes, host, port); char txtaddr[CF_MAX_IP_LEN] = ""; int sd = SocketConnect(host, port, CONNTIMEOUT, false, txtaddr, sizeof(txtaddr)); if (sd == -1) { continue; } if (strlen(sendstring) > 0) { if (SendSocketStream(sd, sendstring, strlen(sendstring)) != -1) { char recvbuf[CF_BUFSIZE]; ssize_t n_read = recv(sd, recvbuf, maxbytes, 0); if (n_read >= 0) { /* maxbytes was checked earlier, but just make sure... */ assert((size_t) n_read < sizeof(recvbuf)); recvbuf[n_read] = '\0'; if (strlen(regex) == 0 || StringMatchFull(regex, recvbuf)) { Log(LOG_LEVEL_VERBOSE, "selectservers: Got matching reply from host %s address %s", host, txtaddr); char buffer[CF_MAXVARSIZE] = ""; snprintf(buffer, sizeof(buffer), "%s[%zu]", array_lval, count); VarRef *ref = VarRefParse(buffer); EvalContextVariablePut(ctx, ref, host, CF_DATA_TYPE_STRING, "source=function,function=selectservers"); VarRefDestroy(ref); count++; } } } } else /* If query is empty, all hosts are added */ { Log(LOG_LEVEL_VERBOSE, "selectservers: Got reply from host %s address %s", host, txtaddr); char buffer[CF_MAXVARSIZE] = ""; snprintf(buffer, sizeof(buffer), "%s[%zu]", array_lval, count); VarRef *ref = VarRefParse(buffer); EvalContextVariablePut(ctx, ref, host, CF_DATA_TYPE_STRING, "source=function,function=selectservers"); VarRefDestroy(ref); count++; } cf_closesocket(sd); } PolicyDestroy(select_server_policy); free(array_lval); Log(LOG_LEVEL_VERBOSE, "selectservers: found %zu servers", count); return FnReturnF("%zu", count); } static FnCallResult FnCallShuffle(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *seed_str = RlistScalarValue(finalargs->next); const char *name_str = RlistScalarValueSafe(finalargs); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } Seq *seq = SeqNew(100, NULL); JsonIterator iter = JsonIteratorInit(json); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { SeqAppend(seq, (void*)JsonPrimitiveGetAsString(e)); } SeqShuffle(seq, StringHash(seed_str, 0)); Rlist *shuffled = NULL; for (size_t i = 0; i < SeqLength(seq); i++) { RlistPrepend(&shuffled, SeqAt(seq, i), RVAL_TYPE_SCALAR); } SeqDestroy(seq); JsonDestroyMaybe(json, allocated); return (FnCallResult) { FNCALL_SUCCESS, (Rval) { shuffled, RVAL_TYPE_LIST } }; } static FnCallResult FnCallInt(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { assert(finalargs != NULL); char *str = RlistScalarValueSafe(finalargs); double val; bool ok = DoubleFromString(str, &val); if (!ok) { // Log from DoubleFromString return FnFailure(); } return FnReturnF("%jd", (intmax_t) val); // Discard decimals } static FnCallResult FnCallIsNewerThan(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { struct stat frombuf, tobuf; if (stat(RlistScalarValue(finalargs), &frombuf) == -1 || stat(RlistScalarValue(finalargs->next), &tobuf) == -1) { return FnFailure(); } return FnReturnContext(frombuf.st_mtime > tobuf.st_mtime); } /*********************************************************************/ static FnCallResult FnCallIsAccessedBefore(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { struct stat frombuf, tobuf; if (stat(RlistScalarValue(finalargs), &frombuf) == -1 || stat(RlistScalarValue(finalargs->next), &tobuf) == -1) { return FnFailure(); } return FnReturnContext(frombuf.st_atime < tobuf.st_atime); } /*********************************************************************/ static FnCallResult FnCallIsChangedBefore(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { struct stat frombuf, tobuf; if (stat(RlistScalarValue(finalargs), &frombuf) == -1 || stat(RlistScalarValue(finalargs->next), &tobuf) == -1) { return FnFailure(); } return FnReturnContext(frombuf.st_ctime > tobuf.st_ctime); } /*********************************************************************/ static FnCallResult FnCallFileStat(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { char *path = RlistScalarValue(finalargs); struct stat statbuf; if (lstat(path, &statbuf) == -1) { if (StringEqual(fp->name, "filesize")) { return FnFailure(); } return FnReturnContext(false); } if (!strcmp(fp->name, "isexecutable")) { if (S_ISLNK(statbuf.st_mode) && stat(path, &statbuf) == -1) { // stat on link target failed - probably broken link return FnReturnContext(false); } return FnReturnContext(IsExecutable(path)); } if (!strcmp(fp->name, "isdir")) { return FnReturnContext(S_ISDIR(statbuf.st_mode)); } if (!strcmp(fp->name, "islink")) { return FnReturnContext(S_ISLNK(statbuf.st_mode)); } if (!strcmp(fp->name, "isplain")) { return FnReturnContext(S_ISREG(statbuf.st_mode)); } if (!strcmp(fp->name, "fileexists")) { return FnReturnContext(true); } if (!strcmp(fp->name, "filesize")) { return FnReturnF("%ju", (uintmax_t) statbuf.st_size); } ProgrammingError("Unexpected function name in FnCallFileStat: %s", fp->name); } /*********************************************************************/ static FnCallResult FnCallFileStatDetails(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { char buffer[CF_BUFSIZE]; const char *path = RlistScalarValue(finalargs); char *detail = RlistScalarValue(finalargs->next); struct stat statbuf; buffer[0] = '\0'; if (lstat(path, &statbuf) == -1) { return FnFailure(); } else if (!strcmp(detail, "xattr")) { #if defined(WITH_XATTR) // Extended attributes include both POSIX ACLs and SELinux contexts. char attr_raw_names[CF_BUFSIZE]; ssize_t attr_raw_names_size = llistxattr(path, attr_raw_names, sizeof(attr_raw_names)); if (attr_raw_names_size < 0) { if (errno != ENOTSUP && errno != ENODATA) { Log(LOG_LEVEL_ERR, "Can't read extended attributes of '%s'. (llistxattr: %s)", path, GetErrorStr()); } } else { Buffer *printattr = BufferNew(); for (int pos = 0; pos < attr_raw_names_size;) { const char *current = attr_raw_names + pos; pos += strlen(current) + 1; if (!StringIsPrintable(current)) { Log(LOG_LEVEL_INFO, "Skipping extended attribute of '%s', it has a non-printable name: '%s'", path, current); continue; } char data[CF_BUFSIZE]; int datasize = lgetxattr(path, current, data, sizeof(data)); if (datasize < 0) { if (errno == ENOTSUP) { continue; } else { Log(LOG_LEVEL_ERR, "Can't read extended attribute '%s' of '%s'. (lgetxattr: %s)", path, current, GetErrorStr()); } } else { if (!StringIsPrintable(data)) { Log(LOG_LEVEL_INFO, "Skipping extended attribute of '%s', it has non-printable data: '%s=%s'", path, current, data); continue; } BufferPrintf(printattr, "%s=%s", current, data); // Append a newline for multiple attributes. if (attr_raw_names_size > 0) { BufferAppendChar(printattr, '\n'); } } } snprintf(buffer, CF_MAXVARSIZE, "%s", BufferData(printattr)); BufferDestroy(printattr); } #else // !WITH_XATTR // do nothing, leave the buffer empty #endif } else if (!strcmp(detail, "size")) { snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) statbuf.st_size); } else if (!strcmp(detail, "gid")) { snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) statbuf.st_gid); } else if (!strcmp(detail, "uid")) { snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) statbuf.st_uid); } else if (!strcmp(detail, "ino")) { snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) statbuf.st_ino); } else if (!strcmp(detail, "nlink")) { snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) statbuf.st_nlink); } else if (!strcmp(detail, "ctime")) { snprintf(buffer, CF_MAXVARSIZE, "%jd", (intmax_t) statbuf.st_ctime); } else if (!strcmp(detail, "mtime")) { snprintf(buffer, CF_MAXVARSIZE, "%jd", (intmax_t) statbuf.st_mtime); } else if (!strcmp(detail, "atime")) { snprintf(buffer, CF_MAXVARSIZE, "%jd", (intmax_t) statbuf.st_atime); } else if (!strcmp(detail, "permstr")) { snprintf(buffer, CF_MAXVARSIZE, "%c%c%c%c%c%c%c%c%c%c", S_ISDIR(statbuf.st_mode) ? 'd' : '-', (statbuf.st_mode & S_IRUSR) ? 'r' : '-', (statbuf.st_mode & S_IWUSR) ? 'w' : '-', (statbuf.st_mode & S_IXUSR) ? 'x' : '-', (statbuf.st_mode & S_IRGRP) ? 'r' : '-', (statbuf.st_mode & S_IWGRP) ? 'w' : '-', (statbuf.st_mode & S_IXGRP) ? 'x' : '-', (statbuf.st_mode & S_IROTH) ? 'r' : '-', (statbuf.st_mode & S_IWOTH) ? 'w' : '-', (statbuf.st_mode & S_IXOTH) ? 'x' : '-'); } else if (!strcmp(detail, "permoct")) { snprintf(buffer, CF_MAXVARSIZE, "%jo", (uintmax_t) (statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))); } else if (!strcmp(detail, "modeoct")) { snprintf(buffer, CF_MAXVARSIZE, "%jo", (uintmax_t) statbuf.st_mode); } else if (!strcmp(detail, "mode")) { snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) statbuf.st_mode); } else if (!strcmp(detail, "type")) { switch (statbuf.st_mode & S_IFMT) { case S_IFBLK: snprintf(buffer, CF_MAXVARSIZE, "%s", "block device"); break; case S_IFCHR: snprintf(buffer, CF_MAXVARSIZE, "%s", "character device"); break; case S_IFDIR: snprintf(buffer, CF_MAXVARSIZE, "%s", "directory"); break; case S_IFIFO: snprintf(buffer, CF_MAXVARSIZE, "%s", "FIFO/pipe"); break; case S_IFLNK: snprintf(buffer, CF_MAXVARSIZE, "%s", "symlink"); break; case S_IFREG: snprintf(buffer, CF_MAXVARSIZE, "%s", "regular file"); break; case S_IFSOCK: snprintf(buffer, CF_MAXVARSIZE, "%s", "socket"); break; default: snprintf(buffer, CF_MAXVARSIZE, "%s", "unknown"); break; } } else if (!strcmp(detail, "dev_minor")) { #if !defined(__MINGW32__) snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) minor(statbuf.st_dev) ); #else snprintf(buffer, CF_MAXVARSIZE, "Not available on Windows"); #endif } else if (!strcmp(detail, "dev_major")) { #if !defined(__MINGW32__) snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) major(statbuf.st_dev) ); #else snprintf(buffer, CF_MAXVARSIZE, "Not available on Windows"); #endif } else if (!strcmp(detail, "devno")) { #if !defined(__MINGW32__) snprintf(buffer, CF_MAXVARSIZE, "%ju", (uintmax_t) statbuf.st_dev ); #else snprintf(buffer, CF_MAXVARSIZE, "%c:", statbuf.st_dev + 'A'); #endif } else if (!strcmp(detail, "dirname")) { snprintf(buffer, CF_MAXVARSIZE, "%s", path); ChopLastNode(buffer); MapName(buffer); } else if (!strcmp(detail, "basename")) { snprintf(buffer, CF_MAXVARSIZE, "%s", ReadLastNode(path)); } else if (!strcmp(detail, "linktarget") || !strcmp(detail, "linktarget_shallow")) { #if !defined(__MINGW32__) char path_buffer[CF_BUFSIZE]; bool recurse = !strcmp(detail, "linktarget"); int cycles = 0; int max_cycles = 30; // This allows for up to 31 levels of indirection. strlcpy(path_buffer, path, CF_MAXVARSIZE); // Iterate while we're looking at a link. while (S_ISLNK(statbuf.st_mode)) { if (cycles > max_cycles) { Log(LOG_LEVEL_INFO, "%s bailing on link '%s' (original '%s') because %d cycles were chased", fp->name, path_buffer, path, cycles + 1); break; } Log(LOG_LEVEL_VERBOSE, "%s cycle %d, resolving link: %s", fp->name, cycles+1, path_buffer); /* Note we subtract 1 since we may need an extra char for '\0'. */ ssize_t got = readlink(path_buffer, buffer, CF_BUFSIZE - 1); if (got < 0) { // An error happened. Empty the buffer (don't keep the last target). Log(LOG_LEVEL_ERR, "%s could not readlink '%s'", fp->name, path_buffer); path_buffer[0] = '\0'; break; } buffer[got] = '\0'; /* readlink() doesn't terminate */ /* If it is a relative path, then in order to follow it further we * need to prepend the directory. */ if (!IsAbsoluteFileName(buffer) && strcmp(detail, "linktarget") == 0) { DeleteSlash(path_buffer); ChopLastNode(path_buffer); AddSlash(path_buffer); strlcat(path_buffer, buffer, sizeof(path_buffer)); /* Use buffer again as a tmp buffer. */ CompressPath(buffer, sizeof(buffer), path_buffer); } // We got a good link target into buffer. Copy it to path_buffer. strlcpy(path_buffer, buffer, CF_MAXVARSIZE); Log(LOG_LEVEL_VERBOSE, "Link resolved to: %s", path_buffer); if (!recurse) { Log(LOG_LEVEL_VERBOSE, "%s bailing on link '%s' (original '%s') because linktarget_shallow was requested", fp->name, path_buffer, path); break; } else if (lstat(path_buffer, &statbuf) == -1) { Log(LOG_LEVEL_INFO, "%s bailing on link '%s' (original '%s') because it could not be read", fp->name, path_buffer, path); break; } // At this point we haven't bailed, path_buffer has the link target cycles++; } // Get the path_buffer back into buffer. strlcpy(buffer, path_buffer, CF_MAXVARSIZE); #else // Always return the original path on W32. strlcpy(buffer, path, CF_MAXVARSIZE); #endif } return FnReturn(buffer); } /*********************************************************************/ static FnCallResult FnCallFindfiles(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { Rlist *returnlist = NULL; char id[CF_BUFSIZE]; snprintf(id, CF_BUFSIZE, "built-in FnCall %s-arg", fp->name); /* We need to check all the arguments, ArgTemplate does not check varadic functions */ for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(id, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "in %s: %s", id, SyntaxTypeMatchToString(err)); } } for (const Rlist *arg = finalargs; /* Start with arg set to finalargs. */ arg; /* We must have arg to proceed. */ arg = arg->next) /* arg steps forward every time. */ { const char *pattern = RlistScalarValue(arg); if (!IsAbsoluteFileName(pattern)) { Log(LOG_LEVEL_WARNING, "Non-absolute path in findfiles(), skipping: %s", pattern); continue; } StringSet *found = GlobFileList(pattern); char fname[CF_BUFSIZE]; StringSetIterator it = StringSetIteratorInit(found); const char *element = NULL; while ((element = StringSetIteratorNext(&it))) { // TODO: this truncates the filename and may be removed // if Rlist and the core are OK with that possibility strlcpy(fname, element, CF_BUFSIZE); Log(LOG_LEVEL_VERBOSE, "%s pattern '%s' found match '%s'", fp->name, pattern, fname); RlistAppendScalarIdemp(&returnlist, fname); } StringSetDestroy(found); } return (FnCallResult) { FNCALL_SUCCESS, { returnlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallFilter(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { return FilterInternal(ctx, fp, RlistScalarValue(finalargs), // regex or string finalargs->next, // list identifier BooleanFromString(RlistScalarValue(finalargs->next->next)), // match as regex or exactly BooleanFromString(RlistScalarValue(finalargs->next->next->next)), // invert matches IntFromString(RlistScalarValue(finalargs->next->next->next->next))); // max results } /*********************************************************************/ static const Rlist *GetListReferenceArgument(const EvalContext *ctx, const FnCall *fp, const char *lval_str, DataType *datatype_out) { VarRef *ref = VarRefParse(lval_str); DataType value_type; const Rlist *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); /* Error 1: variable not found. */ if (value_type == CF_DATA_TYPE_NONE) { Log(LOG_LEVEL_VERBOSE, "Could not resolve expected list variable '%s' in function '%s'", lval_str, fp->name); assert(value == NULL); } /* Error 2: variable is not a list. */ else if (DataTypeToRvalType(value_type) != RVAL_TYPE_LIST) { Log(LOG_LEVEL_ERR, "Function '%s' expected a list variable," " got variable of type '%s'", fp->name, DataTypeToString(value_type)); value = NULL; value_type = CF_DATA_TYPE_NONE; } if (datatype_out) { *datatype_out = value_type; } return value; } /*********************************************************************/ static FnCallResult FilterInternal(EvalContext *ctx, const FnCall *fp, const char *regex, const Rlist* rp, bool do_regex, bool invert, long max) { Regex *rx = NULL; if (do_regex) { rx = CompileRegex(regex); if (!rx) { return FnFailure(); } } bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, rp, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { RegexDestroy(rx); return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, RlistScalarValueSafe(rp)); JsonDestroyMaybe(json, allocated); RegexDestroy(rx); return FnFailure(); } Rlist *returnlist = NULL; long match_count = 0; long total = 0; JsonIterator iter = JsonIteratorInit(json); const JsonElement *el = NULL; while ((el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true)) && match_count < max) { char *val = JsonPrimitiveToString(el); if (val != NULL) { bool found; if (do_regex) { found = StringMatchFullWithPrecompiledRegex(rx, val); } else { found = (0==strcmp(regex, val)); } if (invert ? !found : found) { RlistAppendScalar(&returnlist, val); match_count++; if (strcmp(fp->name, "some") == 0 || strcmp(fp->name, "regarray") == 0) { free(val); break; } } else if (strcmp(fp->name, "every") == 0) { total++; free(val); break; } total++; free(val); } } JsonDestroyMaybe(json, allocated); if (rx) { RegexDestroy(rx); } bool contextmode = false; bool ret = false; if (strcmp(fp->name, "every") == 0) { contextmode = true; ret = (match_count == total && total > 0); } else if (strcmp(fp->name, "none") == 0) { contextmode = true; ret = (match_count == 0); } else if (strcmp(fp->name, "some") == 0 || strcmp(fp->name, "regarray") == 0 || strcmp(fp->name, "reglist") == 0) { contextmode = true; ret = (match_count > 0); } else if (strcmp(fp->name, "grep") != 0 && strcmp(fp->name, "filter") != 0) { ProgrammingError("built-in FnCall %s: unhandled FilterInternal() contextmode", fp->name); } if (contextmode) { RlistDestroy(returnlist); return FnReturnContext(ret); } // else, return the list itself return (FnCallResult) { FNCALL_SUCCESS, { returnlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallSublist(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *name_str = RlistScalarValueSafe(finalargs); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } bool head = (strcmp(RlistScalarValue(finalargs->next), "head") == 0); // heads or tails long max = IntFromString(RlistScalarValue(finalargs->next->next)); // max results Rlist *input_list = NULL; Rlist *returnlist = NULL; JsonIterator iter = JsonIteratorInit(json); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { RlistAppendScalar(&input_list, JsonPrimitiveGetAsString(e)); } JsonDestroyMaybe(json, allocated); if (head) { long count = 0; for (const Rlist *rp = input_list; rp != NULL && count < max; rp = rp->next) { RlistAppendScalar(&returnlist, RlistScalarValue(rp)); count++; } } else if (max > 0) // tail mode { const Rlist *rp = input_list; int length = RlistLen((const Rlist *) rp); int offset = max >= length ? 0 : length-max; for (; rp != NULL && offset--; rp = rp->next) { /* skip to offset */ } for (; rp != NULL; rp = rp->next) { RlistAppendScalar(&returnlist, RlistScalarValue(rp)); } } RlistDestroy(input_list); return (FnCallResult) { FNCALL_SUCCESS, { returnlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ // TODO: This monstrosity needs refactoring static FnCallResult FnCallSetop(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { bool difference_mode = (strcmp(fp->name, "difference") == 0); bool unique_mode = (strcmp(fp->name, "unique") == 0); const char *name_str = RlistScalarValueSafe(finalargs); bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } JsonElement *json_b = NULL; bool allocated_b = false; if (!unique_mode) { const char *name_str_b = RlistScalarValueSafe(finalargs->next); json_b = VarNameOrInlineToJson(ctx, fp, finalargs->next, false, &allocated_b); // we failed to produce a valid JsonElement, so give up if (json_b == NULL) { JsonDestroyMaybe(json, allocated); return FnFailure(); } else if (JsonGetElementType(json_b) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str_b); JsonDestroyMaybe(json, allocated); JsonDestroyMaybe(json_b, allocated_b); return FnFailure(); } } StringSet *set_b = StringSetNew(); if (!unique_mode) { JsonIterator iter = JsonIteratorInit(json_b); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { StringSetAdd(set_b, xstrdup(JsonPrimitiveGetAsString(e))); } } Rlist *returnlist = NULL; JsonIterator iter = JsonIteratorInit(json); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { const char *value = JsonPrimitiveGetAsString(e); // Yes, this is an XOR. But it's more legible this way. if (!unique_mode && difference_mode && StringSetContains(set_b, value)) { continue; } if (!unique_mode && !difference_mode && !StringSetContains(set_b, value)) { continue; } RlistAppendScalarIdemp(&returnlist, value); } JsonDestroyMaybe(json, allocated); if (json_b != NULL) { JsonDestroyMaybe(json_b, allocated_b); } StringSetDestroy(set_b); return (FnCallResult) { FNCALL_SUCCESS, (Rval) { returnlist, RVAL_TYPE_LIST } }; } static FnCallResult FnCallLength(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *name_str = RlistScalarValueSafe(finalargs); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } size_t len = JsonLength(json); JsonDestroyMaybe(json, allocated); return FnReturnF("%zu", len); } static FnCallResult FnCallFold(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *sort_type = finalargs->next ? RlistScalarValue(finalargs->next) : NULL; size_t count = 0; double product = 1.0; // this could overflow double sum = 0; // this could overflow double mean = 0; double M2 = 0; char* min = NULL; char* max = NULL; bool variance_mode = strcmp(fp->name, "variance") == 0; bool mean_mode = strcmp(fp->name, "mean") == 0; bool max_mode = strcmp(fp->name, "max") == 0; bool min_mode = strcmp(fp->name, "min") == 0; bool sum_mode = strcmp(fp->name, "sum") == 0; bool product_mode = strcmp(fp->name, "product") == 0; bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); if (!json) { return FnFailure(); } JsonIterator iter = JsonIteratorInit(json); const JsonElement *el; while ((el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { char *value = JsonPrimitiveToString(el); if (value != NULL) { if (sort_type) { if (min_mode && (min == NULL || !GenericStringItemLess(sort_type, min, value))) { free(min); min = xstrdup(value); } if (max_mode && (max == NULL || GenericStringItemLess(sort_type, max, value))) { free(max); max = xstrdup(value); } } count++; if (mean_mode || variance_mode || sum_mode || product_mode) { double x; if (sscanf(value, "%lf", &x) != 1) { x = 0; /* treat non-numeric entries as zero */ } // Welford's algorithm double delta = x - mean; mean += delta/count; M2 += delta * (x - mean); sum += x; product *= x; } free(value); } } JsonDestroyMaybe(json, allocated); if (mean_mode) { return count == 0 ? FnFailure() : FnReturnF("%lf", mean); } else if (sum_mode) { return FnReturnF("%lf", sum); } else if (product_mode) { return FnReturnF("%lf", product); } else if (variance_mode) { double variance = 0; if (count == 0) { return FnFailure(); } // if count is 1, variance is 0 if (count > 1) { variance = M2/(count - 1); } return FnReturnF("%lf", variance); } else if (max_mode) { return max == NULL ? FnFailure() : FnReturnNoCopy(max); } else if (min_mode) { return min == NULL ? FnFailure() : FnReturnNoCopy(min); } // else, we don't know this fp->name ProgrammingError("Unknown function call %s to FnCallFold", fp->name); return FnFailure(); } /*********************************************************************/ static FnCallResult FnCallDatatype(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { assert(fp != NULL); assert(fp->name != NULL); if (finalargs == NULL) { Log(LOG_LEVEL_ERR, "Function %s requires variable identifier as first argument", fp->name); return FnFailure(); } const char* const var_name = RlistScalarValue(finalargs); VarRef* const var_ref = VarRefParse(var_name); DataType type; const void *value = EvalContextVariableGet(ctx, var_ref, &type); VarRefDestroy(var_ref); /* detail argument defaults to false */ bool detail = false; if (finalargs->next != NULL) { detail = BooleanFromString(RlistScalarValue(finalargs->next)); } const char *const type_str = (type == CF_DATA_TYPE_NONE) ? "none" : DataTypeToString(type); if (!detail) { return FnReturn(type_str); } if (type == CF_DATA_TYPE_CONTAINER) { const char *subtype_str; const JsonElement *const element = value; switch (JsonGetType(element)) { case JSON_CONTAINER_TYPE_OBJECT: subtype_str = "object"; break; case JSON_CONTAINER_TYPE_ARRAY: subtype_str = "array"; break; case JSON_PRIMITIVE_TYPE_STRING: subtype_str = "string"; break; case JSON_PRIMITIVE_TYPE_INTEGER: subtype_str = "int"; break; case JSON_PRIMITIVE_TYPE_REAL: subtype_str = "real"; break; case JSON_PRIMITIVE_TYPE_BOOL: subtype_str = "boolean"; break; case JSON_PRIMITIVE_TYPE_NULL: subtype_str = "null"; break; default: Log(LOG_LEVEL_ERR, "Function %s failed to get subtype of type data", fp->name); return FnFailure(); } return FnReturnF("%s %s", type_str, subtype_str); } return FnReturnF("policy %s", type_str); } /*********************************************************************/ static FnCallResult FnCallNth(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char* const key = RlistScalarValue(finalargs->next); const char *name_str = RlistScalarValueSafe(finalargs); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } const char *jstring = NULL; FnCallResult result; if (JsonGetElementType(json) == JSON_ELEMENT_TYPE_CONTAINER) { JsonContainerType ct = JsonGetContainerType(json); JsonElement* jelement = NULL; if (JSON_CONTAINER_TYPE_OBJECT == ct) { jelement = JsonObjectGet(json, key); } else if (JSON_CONTAINER_TYPE_ARRAY == ct) { long index = IntFromString(key); if (index < 0) { index += JsonLength(json); } if (index >= 0 && index < (long) JsonLength(json)) { jelement = JsonAt(json, index); } } else { ProgrammingError("JSON Container is neither array nor object but type %d", (int) ct); } if (jelement != NULL && JsonGetElementType(jelement) == JSON_ELEMENT_TYPE_PRIMITIVE) { jstring = JsonPrimitiveGetAsString(jelement); if (jstring != NULL) { result = FnReturn(jstring); } } } JsonDestroyMaybe(json, allocated); if (jstring == NULL) { return FnFailure(); } return result; } /*********************************************************************/ static FnCallResult FnCallEverySomeNone(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { return FilterInternal(ctx, fp, RlistScalarValue(finalargs), // regex or string finalargs->next, // list identifier 1, 0, LONG_MAX); } static FnCallResult FnCallSort(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { if (finalargs == NULL) { FatalError(ctx, "in built-in FnCall %s: missing first argument, a list name", fp->name); } const char *sort_type = NULL; if (finalargs->next) { sort_type = RlistScalarValue(finalargs->next); // sort mode } else { sort_type = "lex"; } const char *name_str = RlistScalarValueSafe(finalargs); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } Rlist *sorted = NULL; JsonIterator iter = JsonIteratorInit(json); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { RlistAppendScalar(&sorted, JsonPrimitiveGetAsString(e)); } JsonDestroyMaybe(json, allocated); if (strcmp(sort_type, "int") == 0) { sorted = IntSortRListNames(sorted); } else if (strcmp(sort_type, "real") == 0) { sorted = RealSortRListNames(sorted); } else if (strcmp(sort_type, "IP") == 0 || strcmp(sort_type, "ip") == 0) { sorted = IPSortRListNames(sorted); } else if (strcmp(sort_type, "MAC") == 0 || strcmp(sort_type, "mac") == 0) { sorted = MACSortRListNames(sorted); } else // "lex" { sorted = AlphaSortRListNames(sorted); } return (FnCallResult) { FNCALL_SUCCESS, (Rval) { sorted, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *const id = "built-in FnCall format-arg"; /* We need to check all the arguments, ArgTemplate does not check varadic functions */ for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(id, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "in %s: %s", id, SyntaxTypeMatchToString(err)); } } if (finalargs == NULL) { return FnFailure(); } char *format = RlistScalarValue(finalargs); if (format == NULL) { return FnFailure(); } const Rlist *rp = finalargs->next; char *check = strchr(format, '%'); char check_buffer[CF_BUFSIZE]; Buffer *buf = BufferNew(); if (check != NULL) { BufferAppend(buf, format, check - format); Seq *s; while (check != NULL && (s = StringMatchCaptures("^(%%|%[^diouxXeEfFgGaAcsCSpnm%]*?[diouxXeEfFgGaAcsCSpnm])([^%]*)(.*)$", check, false))) { { if (SeqLength(s) >= 2) { const char *format_piece = BufferData(SeqAt(s, 1)); bool percent = StringEqualN(format_piece, "%%", 2); char *data = NULL; if (percent) { // "%%" in format string } else if (rp != NULL) { data = RlistScalarValue(rp); rp = rp->next; } else // not %% and no data { Log(LOG_LEVEL_ERR, "format() didn't have enough parameters"); BufferDestroy(buf); SeqDestroy(s); return FnFailure(); } char piece[CF_BUFSIZE]; memset(piece, 0, CF_BUFSIZE); const char bad_modifiers[] = "hLqjzt"; const size_t length = strlen(bad_modifiers); for (size_t b = 0; b < length; b++) { if (strchr(format_piece, bad_modifiers[b]) != NULL) { Log(LOG_LEVEL_ERR, "format() does not allow modifier character '%c' in format specifier '%s'.", bad_modifiers[b], format_piece); BufferDestroy(buf); SeqDestroy(s); return FnFailure(); } } if (strrchr(format_piece, 'd') != NULL || strrchr(format_piece, 'o') != NULL || strrchr(format_piece, 'x') != NULL) { long x = 0; sscanf(data, "%ld", &x); snprintf(piece, CF_BUFSIZE, format_piece, x); BufferAppend(buf, piece, strlen(piece)); } else if (percent) { // "%%" -> "%" BufferAppend(buf, "%", 1); } else if (strrchr(format_piece, 'f') != NULL) { double x = 0; sscanf(data, "%lf", &x); snprintf(piece, CF_BUFSIZE, format_piece, x); BufferAppend(buf, piece, strlen(piece)); } else if (strrchr(format_piece, 's') != NULL) { BufferAppendF(buf, format_piece, data); } else if (strrchr(format_piece, 'S') != NULL) { char *found_format_spec = NULL; char format_rewrite[CF_BUFSIZE]; strlcpy(format_rewrite, format_piece, CF_BUFSIZE); found_format_spec = strrchr(format_rewrite, 'S'); if (found_format_spec != NULL) { *found_format_spec = 's'; } else { ProgrammingError("Couldn't find the expected S format spec in %s", format_piece); } const char* const varname = data; VarRef *ref = VarRefParse(varname); DataType type; const void *value = EvalContextVariableGet(ctx, ref, &type); VarRefDestroy(ref); if (type == CF_DATA_TYPE_CONTAINER) { Writer *w = StringWriter(); JsonWriteCompact(w, value); BufferAppendF(buf, format_rewrite, StringWriterData(w)); WriterClose(w); } else // it might be a list reference { DataType data_type; const Rlist *list = GetListReferenceArgument(ctx, fp, varname, &data_type); if (data_type == CF_DATA_TYPE_STRING_LIST) { Writer *w = StringWriter(); WriterWrite(w, "{ "); for (const Rlist *rp = list; rp; rp = rp->next) { char *escaped = EscapeCharCopy(RlistScalarValue(rp), '"', '\\'); WriterWriteF(w, "\"%s\"", escaped); free(escaped); if (rp != NULL && rp->next != NULL) { WriterWrite(w, ", "); } } WriterWrite(w, " }"); BufferAppendF(buf, format_rewrite, StringWriterData(w)); WriterClose(w); } else // whatever this is, it's not a list reference or a data container { Log(LOG_LEVEL_VERBOSE, "format() with %%S specifier needs a data container or a list instead of '%s'.", varname); BufferDestroy(buf); SeqDestroy(s); return FnFailure(); } } } else { char error[] = "(unhandled format)"; BufferAppend(buf, error, strlen(error)); } } else { check = NULL; } } { if (SeqLength(s) >= 3) { BufferAppend(buf, BufferData(SeqAt(s, 2)), BufferSize(SeqAt(s, 2))); } else { check = NULL; } } { if (SeqLength(s) >= 4) { strlcpy(check_buffer, BufferData(SeqAt(s, 3)), CF_BUFSIZE); check = check_buffer; } else { check = NULL; } } SeqDestroy(s); } } else { BufferAppend(buf, format, strlen(format)); } return FnReturnBuffer(buf); } /*********************************************************************/ static FnCallResult FnCallIPRange(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { assert(fp != NULL); if (finalargs == NULL) { Log(LOG_LEVEL_ERR, "Function '%s' requires at least one argument", fp->name); return FnFailure(); } const char *range = RlistScalarValue(finalargs); const Rlist *ifaces = finalargs->next; if (!FuzzyMatchParse(range)) { Log(LOG_LEVEL_VERBOSE, "%s(%s): argument is not a valid address range", fp->name, range); return FnFailure(); } for (const Item *ip = EvalContextGetIpAddresses(ctx); ip != NULL; ip = ip->next) { if (FuzzySetMatch(range, ip->name) == 0) { /* * MODE1: iprange(range) * Match range on the address of any interface. */ if (ifaces == NULL) { Log(LOG_LEVEL_DEBUG, "%s(%s): Match on IP '%s'", fp->name, range, ip->name); return FnReturnContext(true); } /* * MODE2: iprange(range, args...) * Match range only on the addresses of args interfaces. */ else { for (const Rlist *i = ifaces; i != NULL; i = i->next) { char *iface = xstrdup(RlistScalarValue(i)); CanonifyNameInPlace(iface); const char *ip_iface = ip->classes; if (ip_iface != NULL && strcmp(iface, ip_iface) == 0) { Log(LOG_LEVEL_DEBUG, "%s(%s): Match on IP '%s' interface '%s'", fp->name, range, ip->name, ip->classes); free(iface); return FnReturnContext(true); } free(iface); } } } } Log(LOG_LEVEL_DEBUG, "%s(%s): no match", fp->name, range); return FnReturnContext(false); } static FnCallResult FnCallIsIpInSubnet(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { assert(fp != NULL); if (finalargs == NULL) { Log(LOG_LEVEL_ERR, "Function '%s' requires at least one argument", fp->name); return FnFailure(); } const char *range = RlistScalarValue(finalargs); const Rlist *ips = finalargs->next; if (!FuzzyMatchParse(range)) { Log(LOG_LEVEL_VERBOSE, "%s(%s): argument is not a valid address range", fp->name, range); return FnFailure(); } for (const Rlist *ip = ips; ip != NULL; ip = ip->next) { const char *ip_s = RlistScalarValue(ip); if (FuzzySetMatch(range, ip_s) == 0) { Log(LOG_LEVEL_DEBUG, "%s(%s): Match on IP '%s'", fp->name, range, ip_s); return FnReturnContext(true); } } Log(LOG_LEVEL_DEBUG, "%s(%s): no match", fp->name, range); return FnReturnContext(false); } /*********************************************************************/ static FnCallResult FnCallHostRange(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *prefix = RlistScalarValue(finalargs); char *range = RlistScalarValue(finalargs->next); if (!FuzzyHostParse(range)) { return FnFailure(); } return FnReturnContext(FuzzyHostMatch(prefix, range, VUQNAME) == 0); } /*********************************************************************/ FnCallResult FnCallHostInNetgroup(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { setnetgrent(RlistScalarValue(finalargs)); bool found = false; char *host, *user, *domain; while (getnetgrent(&host, &user, &domain)) { if (host == NULL) { Log(LOG_LEVEL_VERBOSE, "Matched '%s' in netgroup '%s'", VFQNAME, RlistScalarValue(finalargs)); found = true; break; } if (strcmp(host, VFQNAME) == 0 || strcmp(host, VUQNAME) == 0) { Log(LOG_LEVEL_VERBOSE, "Matched '%s' in netgroup '%s'", host, RlistScalarValue(finalargs)); found = true; break; } } endnetgrent(); return FnReturnContext(found); } /*********************************************************************/ static FnCallResult FnCallIsVariable(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { const char *lval = RlistScalarValue(finalargs); bool found = false; if (lval) { VarRef *ref = VarRefParse(lval); DataType value_type; EvalContextVariableGet(ctx, ref, &value_type); if (value_type != CF_DATA_TYPE_NONE) { found = true; } VarRefDestroy(ref); } return FnReturnContext(found); } /*********************************************************************/ static FnCallResult FnCallStrCmp(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { return FnReturnContext(strcmp(RlistScalarValue(finalargs), RlistScalarValue(finalargs->next)) == 0); } /*********************************************************************/ static FnCallResult FnCallTranslatePath(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char buffer[MAX_FILENAME]; strlcpy(buffer, RlistScalarValue(finalargs), sizeof(buffer)); MapName(buffer); return FnReturn(buffer); } /*********************************************************************/ #if defined(__MINGW32__) static FnCallResult FnCallRegistryValue(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char buffer[CF_BUFSIZE] = ""; const char *const key = RlistScalarValue(finalargs); const char *const value = RlistScalarValue(finalargs->next); if (GetRegistryValue(key, value, buffer, sizeof(buffer))) { return FnReturn(buffer); } Log(LOG_LEVEL_ERR, "Could not read existing registry data for key '%s' and value '%s'.", key, value); return FnFailure(); } #else /* !__MINGW32__ */ static FnCallResult FnCallRegistryValue(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, ARG_UNUSED const Rlist *finalargs) { return FnFailure(); } #endif /* !__MINGW32__ */ /*********************************************************************/ static FnCallResult FnCallRemoteScalar(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *handle = RlistScalarValue(finalargs); char *server = RlistScalarValue(finalargs->next); int encrypted = BooleanFromString(RlistScalarValue(finalargs->next->next)); if (strcmp(server, "localhost") == 0) { /* The only reason for this is testing... */ server = "127.0.0.1"; } if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON) { return FnReturn(""); } else { char buffer[CF_BUFSIZE]; buffer[0] = '\0'; char *ret = GetRemoteScalar(ctx, "VAR", handle, server, encrypted, buffer); if (ret == NULL) { return FnFailure(); } if (strncmp(buffer, "BAD:", 4) == 0) { if (RetrieveUnreliableValue("remotescalar", handle, buffer) == 0) { // This function should never fail buffer[0] = '\0'; } } else { CacheUnreliableValue("remotescalar", handle, buffer); } return FnReturn(buffer); } } /*********************************************************************/ static FnCallResult FnCallHubKnowledge(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *handle = RlistScalarValue(finalargs); if (THIS_AGENT_TYPE != AGENT_TYPE_AGENT) { return FnReturn(""); } else { char buffer[CF_BUFSIZE]; buffer[0] = '\0'; Log(LOG_LEVEL_VERBOSE, "Accessing hub knowledge base for '%s'", handle); char *ret = GetRemoteScalar(ctx, "VAR", handle, PolicyServerGetIP(), true, buffer); if (ret == NULL) { return FnFailure(); } // This should always be successful - and this one doesn't cache if (strncmp(buffer, "BAD:", 4) == 0) { return FnReturn("0"); } return FnReturn(buffer); } } /*********************************************************************/ static FnCallResult FnCallRemoteClassesMatching(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *regex = RlistScalarValue(finalargs); char *server = RlistScalarValue(finalargs->next); int encrypted = BooleanFromString(RlistScalarValue(finalargs->next->next)); char *prefix = RlistScalarValue(finalargs->next->next->next); if (strcmp(server, "localhost") == 0) { /* The only reason for this is testing... */ server = "127.0.0.1"; } if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON) { return FnReturn("remote_classes"); } else { char buffer[CF_BUFSIZE]; buffer[0] = '\0'; char *ret = GetRemoteScalar(ctx, "CONTEXT", regex, server, encrypted, buffer); if (ret == NULL) { return FnFailure(); } if (strncmp(buffer, "BAD:", 4) == 0) { return FnFailure(); } Rlist *classlist = RlistFromSplitString(buffer, ','); if (classlist) { for (const Rlist *rp = classlist; rp != NULL; rp = rp->next) { char class_name[CF_MAXVARSIZE]; snprintf(class_name, sizeof(class_name), "%s_%s", prefix, RlistScalarValue(rp)); EvalContextClassPutSoft(ctx, class_name, CONTEXT_SCOPE_BUNDLE, "source=function,function=remoteclassesmatching"); } RlistDestroy(classlist); } return FnReturnContext(true); } } /*********************************************************************/ static FnCallResult FnCallPeers(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { int maxent = 100000, maxsize = 100000; char *filename = RlistScalarValue(finalargs); char *comment = RlistScalarValue(finalargs->next); int groupsize = IntFromString(RlistScalarValue(finalargs->next->next)); if (2 > groupsize) { Log(LOG_LEVEL_WARNING, "Function %s: called with a nonsensical group size of %d, failing", fp->name, groupsize); return FnFailure(); } char *file_buffer = CfReadFile(filename, maxsize); if (file_buffer == NULL) { return FnFailure(); } file_buffer = StripPatterns(file_buffer, comment, filename); Rlist *const newlist = file_buffer ? RlistFromSplitRegex(file_buffer, "\n", maxent, true) : NULL; /* Slice up the list and discard everything except our slice */ int i = 0; bool found = false; Rlist *pruned = NULL; for (const Rlist *rp = newlist; rp != NULL; rp = rp->next) { const char *s = RlistScalarValue(rp); if (EmptyString(s)) { continue; } if (strcmp(s, VFQNAME) == 0 || strcmp(s, VUQNAME) == 0) { found = true; } else { RlistPrepend(&pruned, s, RVAL_TYPE_SCALAR); } if (i++ % groupsize == groupsize - 1) { if (found) { break; } else { RlistDestroy(pruned); pruned = NULL; } } } RlistDestroy(newlist); free(file_buffer); // OK if it's NULL if (pruned && found) { RlistReverse(&pruned); } else { RlistDestroy(pruned); pruned = NULL; } return (FnCallResult) { FNCALL_SUCCESS, { pruned, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallPeerLeader(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { int maxent = 100000, maxsize = 100000; char *filename = RlistScalarValue(finalargs); char *comment = RlistScalarValue(finalargs->next); int groupsize = IntFromString(RlistScalarValue(finalargs->next->next)); if (2 > groupsize) { Log(LOG_LEVEL_WARNING, "Function %s: called with a nonsensical group size of %d, failing", fp->name, groupsize); return FnFailure(); } char *file_buffer = CfReadFile(filename, maxsize); if (file_buffer == NULL) { return FnFailure(); } file_buffer = StripPatterns(file_buffer, comment, filename); Rlist *const newlist = file_buffer ? RlistFromSplitRegex(file_buffer, "\n", maxent, true) : NULL; /* Slice up the list and discard everything except our slice */ int i = 0; bool found = false; char buffer[CF_MAXVARSIZE]; buffer[0] = '\0'; for (const Rlist *rp = newlist; !found && rp != NULL; rp = rp->next) { const char *s = RlistScalarValue(rp); if (EmptyString(s)) { continue; } found = (strcmp(s, VFQNAME) == 0 || strcmp(s, VUQNAME) == 0); if (i % groupsize == 0) { strlcpy(buffer, found ? "localhost" : s, CF_MAXVARSIZE); } i++; } RlistDestroy(newlist); free(file_buffer); if (found) { return FnReturn(buffer); } return FnFailure(); } /*********************************************************************/ static FnCallResult FnCallPeerLeaders(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { int maxent = 100000, maxsize = 100000; char *filename = RlistScalarValue(finalargs); char *comment = RlistScalarValue(finalargs->next); int groupsize = IntFromString(RlistScalarValue(finalargs->next->next)); if (2 > groupsize) { Log(LOG_LEVEL_WARNING, "Function %s: called with a nonsensical group size of %d, failing", fp->name, groupsize); return FnFailure(); } char *file_buffer = CfReadFile(filename, maxsize); if (file_buffer == NULL) { return FnFailure(); } file_buffer = StripPatterns(file_buffer, comment, filename); Rlist *const newlist = file_buffer ? RlistFromSplitRegex(file_buffer, "\n", maxent, true) : NULL; /* Slice up the list and discard everything except our slice */ int i = 0; Rlist *pruned = NULL; for (const Rlist *rp = newlist; rp != NULL; rp = rp->next) { const char *s = RlistScalarValue(rp); if (EmptyString(s)) { continue; } if (i % groupsize == 0) { if (strcmp(s, VFQNAME) == 0 || strcmp(s, VUQNAME) == 0) { RlistPrepend(&pruned, "localhost", RVAL_TYPE_SCALAR); } else { RlistPrepend(&pruned, s, RVAL_TYPE_SCALAR); } } i++; } RlistDestroy(newlist); free(file_buffer); RlistReverse(&pruned); return (FnCallResult) { FNCALL_SUCCESS, { pruned, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallRegCmp(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *argv0 = RlistScalarValue(finalargs); char *argv1 = RlistScalarValue(finalargs->next); return FnReturnContext(StringMatchFull(argv0, argv1)); } /*********************************************************************/ static FnCallResult FnCallRegReplace(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { const char *data = RlistScalarValue(finalargs); const char *regex = RlistScalarValue(finalargs->next); const char *replacement = RlistScalarValue(finalargs->next->next); const char *options = RlistScalarValue(finalargs->next->next->next); Buffer *rewrite = BufferNewFrom(data, strlen(data)); const char* error = BufferSearchAndReplace(rewrite, regex, replacement, options); if (error) { BufferDestroy(rewrite); Log(LOG_LEVEL_ERR, "%s: couldn't use regex '%s', replacement '%s', and options '%s': error=%s", fp->name, regex, replacement, options, error); return FnFailure(); } return FnReturnBuffer(rewrite); } /*********************************************************************/ static FnCallResult FnCallRegExtract(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { const bool container_mode = strcmp(fp->name, "data_regextract") == 0; const char *regex = RlistScalarValue(finalargs); const char *data = RlistScalarValue(finalargs->next); char *arrayname = NULL; if (!container_mode) { arrayname = xstrdup(RlistScalarValue(finalargs->next->next)); if (!IsQualifiedVariable(arrayname)) { if (fp->caller) { VarRef *ref = VarRefParseFromBundle(arrayname, PromiseGetBundle(fp->caller)); free(arrayname); arrayname = VarRefToString(ref, true); VarRefDestroy(ref); } else { Log(LOG_LEVEL_ERR, "Function '%s' called with an unqualifed array reference '%s', " "and the reference could not be automatically qualified as the function was not called from a promise.", fp->name, arrayname); free(arrayname); return FnFailure(); } } } Seq *s = StringMatchCaptures(regex, data, true); if (!s || SeqLength(s) == 0) { SeqDestroy(s); free(arrayname); return container_mode ? FnFailure() : FnReturnContext(false); } JsonElement *json = NULL; if (container_mode) { json = JsonObjectCreate(SeqLength(s)/2); } for (size_t i = 0; i < SeqLength(s); i+=2) { Buffer *key = SeqAt(s, i); Buffer *value = SeqAt(s, i+1); if (container_mode) { JsonObjectAppendString(json, BufferData(key), BufferData(value)); } else { char var[CF_MAXVARSIZE] = ""; snprintf(var, CF_MAXVARSIZE - 1, "%s[%s]", arrayname, BufferData(key)); VarRef *new_ref = VarRefParse(var); EvalContextVariablePut(ctx, new_ref, BufferData(value), CF_DATA_TYPE_STRING, "source=function,function=regextract"); VarRefDestroy(new_ref); } } free(arrayname); SeqDestroy(s); if (container_mode) { return FnReturnContainerNoCopy(json); } else { return FnReturnContext(true); } } /*********************************************************************/ static FnCallResult FnCallRegLine(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { Regex *rx = CompileRegex(RlistScalarValue(finalargs)); if (!rx) { return FnFailure(); } const char *arg_filename = RlistScalarValue(finalargs->next); FILE *fin = safe_fopen(arg_filename, "rt"); if (!fin) { RegexDestroy(rx); return FnReturnContext(false); } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); while (CfReadLine(&line, &line_size, fin) != -1) { if (StringMatchFullWithPrecompiledRegex(rx, line)) { free(line); fclose(fin); RegexDestroy(rx); return FnReturnContext(true); } } RegexDestroy(rx); free(line); if (!feof(fin)) { Log(LOG_LEVEL_ERR, "In function '%s', error reading from file. (getline: %s)", fp->name, GetErrorStr()); } fclose(fin); return FnReturnContext(false); } /*********************************************************************/ static FnCallResult FnCallIsLessGreaterThan(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { char *argv0 = RlistScalarValue(finalargs); char *argv1 = RlistScalarValue(finalargs->next); bool rising = (strcmp(fp->name, "isgreaterthan") == 0); if (IsRealNumber(argv0) && IsRealNumber(argv1)) { double a = 0, b = 0; if (!DoubleFromString(argv0, &a) || !DoubleFromString(argv1, &b)) { return FnFailure(); } if (rising) { return FnReturnContext(a > b); } else { return FnReturnContext(a < b); } } if (rising) { return FnReturnContext(strcmp(argv0, argv1) > 0); } else { return FnReturnContext(strcmp(argv0, argv1) < 0); } } /*********************************************************************/ static FnCallResult FnCallIRange(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { long from = IntFromString(RlistScalarValue(finalargs)); long to = IntFromString(RlistScalarValue(finalargs->next)); if (from == CF_NOINT || to == CF_NOINT) { return FnFailure(); } if (from > to) { long tmp = to; to = from; from = tmp; } return FnReturnF("%ld,%ld", from, to); } /*********************************************************************/ static FnCallResult FnCallRRange(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { double from = 0; if (!DoubleFromString(RlistScalarValue(finalargs), &from)) { Log(LOG_LEVEL_ERR, "Function rrange, error reading assumed real value '%s'", RlistScalarValue(finalargs)); return FnFailure(); } double to = 0; if (!DoubleFromString(RlistScalarValue(finalargs), &to)) { Log(LOG_LEVEL_ERR, "Function rrange, error reading assumed real value '%s'", RlistScalarValue(finalargs->next)); return FnFailure(); } if (from > to) { int tmp = to; to = from; from = tmp; } return FnReturnF("%lf,%lf", from, to); } static FnCallResult FnCallReverse(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *name_str = RlistScalarValueSafe(finalargs); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } Rlist *returnlist = NULL; JsonIterator iter = JsonIteratorInit(json); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { RlistPrepend(&returnlist, JsonPrimitiveGetAsString(e), RVAL_TYPE_SCALAR); } JsonDestroyMaybe(json, allocated); return (FnCallResult) { FNCALL_SUCCESS, (Rval) { returnlist, RVAL_TYPE_LIST } }; } /* Convert y/m/d/h/m/s 6-tuple */ static struct tm FnArgsToTm(const Rlist *rp) { struct tm ret = { .tm_isdst = -1 }; /* .tm_year stores year - 1900 */ ret.tm_year = IntFromString(RlistScalarValue(rp)) - 1900; rp = rp->next; /* .tm_mon counts from Jan = 0 to Dec = 11 */ ret.tm_mon = IntFromString(RlistScalarValue(rp)); rp = rp->next; /* .tm_mday is day of month, 1 to 31, but we use 0 through 30 (for now) */ ret.tm_mday = IntFromString(RlistScalarValue(rp)) + 1; rp = rp->next; ret.tm_hour = IntFromString(RlistScalarValue(rp)); rp = rp->next; ret.tm_min = IntFromString(RlistScalarValue(rp)); rp = rp->next; ret.tm_sec = IntFromString(RlistScalarValue(rp)); return ret; } static FnCallResult FnCallOn(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { struct tm tmv = FnArgsToTm(finalargs); time_t cftime = mktime(&tmv); if (cftime == -1) { Log(LOG_LEVEL_INFO, "Illegal time value"); } return FnReturnF("%jd", (intmax_t) cftime); } /*********************************************************************/ static FnCallResult FnCallOr(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char id[CF_BUFSIZE]; snprintf(id, CF_BUFSIZE, "built-in FnCall or-arg"); /* We need to check all the arguments, ArgTemplate does not check varadic functions */ for (const Rlist *arg = finalargs; arg; arg = arg->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(id, arg->val, CF_DATA_TYPE_STRING, "", 1); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { FatalError(ctx, "in %s: %s", id, SyntaxTypeMatchToString(err)); } } for (const Rlist *arg = finalargs; arg; arg = arg->next) { if (IsDefinedClass(ctx, RlistScalarValue(arg))) { return FnReturnContext(true); } } return FnReturnContext(false); } /*********************************************************************/ static FnCallResult FnCallLaterThan(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { time_t now = time(NULL); struct tm tmv = FnArgsToTm(finalargs); /* Adjust to 1-based counting (input) for month and day of month * (0-based in mktime): */ tmv.tm_mon--; tmv.tm_mday--; time_t cftime = mktime(&tmv); if (cftime == -1) { Log(LOG_LEVEL_INFO, "Illegal time value"); } return FnReturnContext(now > cftime); } static FnCallResult FnCallAgoDate(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { struct tm ago = FnArgsToTm(finalargs); time_t now = time(NULL); struct tm t; localtime_r(&now, &t); t.tm_year -= ago.tm_year + 1900; /* tm.tm_year stores year - 1900 */ t.tm_mon -= ago.tm_mon; t.tm_mday -= ago.tm_mday - 1; t.tm_hour -= ago.tm_hour; t.tm_min -= ago.tm_min; t.tm_sec -= ago.tm_sec; time_t cftime = mktime(&t); if (cftime < 0) { return FnReturn("0"); } return FnReturnF("%jd", (intmax_t) cftime); } /*********************************************************************/ static FnCallResult FnCallAccumulatedDate(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { struct tm tmv = FnArgsToTm(finalargs); intmax_t cftime = 0; cftime = 0; cftime += tmv.tm_sec; cftime += (intmax_t) tmv.tm_min * 60; cftime += (intmax_t) tmv.tm_hour * 3600; cftime += (intmax_t) (tmv.tm_mday - 1) * 24 * 3600; cftime += (intmax_t) tmv.tm_mon * 30 * 24 * 3600; cftime += (intmax_t) (tmv.tm_year + 1900) * 365 * 24 * 3600; return FnReturnF("%jd", (intmax_t) cftime); } /*********************************************************************/ static FnCallResult FnCallNot(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { return FnReturnContext(!IsDefinedClass(ctx, RlistScalarValue(finalargs))); } /*********************************************************************/ static FnCallResult FnCallNow(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, ARG_UNUSED const Rlist *finalargs) { return FnReturnF("%jd", (intmax_t)CFSTARTTIME); } /*********************************************************************/ #ifdef __sun /* Lacks %P and */ #define STRFTIME_F_HACK #define STRFTIME_s_HACK #define STRFTIME_R_HACK #endif /* http://www.unix.com/man-page/opensolaris/3c/strftime/ */ #ifdef __hpux /* Unknown gaps, aside from: */ #define STRFTIME_F_HACK #endif #ifdef _WIN32 /* Has non-standard %z, lacks %[CDeGghklnPrRtTuV] and: */ #define STRFTIME_F_HACK #define STRFTIME_R_HACK #define STRFTIME_s_HACK #endif /* http://msdn.microsoft.com/en-us/library/fe06s4ak.aspx */ bool PortablyFormatTime(char *buffer, size_t bufsiz, const char *format, #ifndef STRFTIME_s_HACK ARG_UNUSED #endif time_t when, const struct tm *tm) { /* TODO: might be better done in a libcompat wrapper. * * The following GNU extensions may be worth adding at some point; * see individual platforms for lists of which they lack. * * %C (century) * %D => %m/%d/%y * %e: as %d but s/^0/ / * %G: like %Y but frobbed for ISO week numbers * %g: last two digits of %G * %h => %b * %k: as %H but s/^0/ / * %l: as %I but s/^0/ / * %n => \n * %P: as %p but lower-cased * %r => %I:%M:%S %p * %s: seconds since epoch * %t => \t * %T => %H:%M:%S * %u: dow, {1: Mon, ..., Sun: 7} * %V: ISO week number within year %G * * The "=>" ones can all be done by extending expansion[], below; * the rest would require actually implementing GNU strftime() * properly. */ #ifdef STRFTIME_s_HACK /* %s: seconds since epoch */ char epoch[PRINTSIZE(when)]; xsnprintf(epoch, sizeof(epoch), "%jd", (intmax_t) when); #endif /* STRFTIME_s_HACK */ typedef char * SearchReplacePair[2]; SearchReplacePair expansion[] = { /* Each pair is { search, replace }. */ #ifdef STRFTIME_F_HACK { "%F", "%Y-%m-%d" }, #endif #ifdef STRFTIME_R_HACK /* %R => %H:%M:%S */ { "%R", "%H:%M:%S" }, #endif #ifdef STRFTIME_s_HACK { "%s", epoch }, #endif /* Order as in GNU strftime's man page. */ { NULL, NULL } }; char *delenda = NULL; /* in need of destruction */ /* No-op when no STRFTIME_*_HACK were defined. */ for (size_t i = 0; expansion[i][0]; i++) { char *tmp = SearchAndReplace(format, expansion[i][0], expansion[i][1]); free(delenda); format = delenda = tmp; } size_t ans = strftime(buffer, bufsiz, format, tm); free(delenda); return ans > 0; } #undef STRFTIME_F_HACK #undef STRFTIME_R_HACK #undef STRFTIME_s_HACK /*********************************************************************/ static FnCallResult FnCallStrftime(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { /* begin fn-specific content */ char *mode = RlistScalarValue(finalargs); char *format_string = RlistScalarValue(finalargs->next); // this will be a problem on 32-bit systems... const time_t when = IntFromString(RlistScalarValue(finalargs->next->next)); struct tm tm_value; struct tm *tm_pointer; if (strcmp("gmtime", mode) == 0) { tm_pointer = gmtime_r(&when, &tm_value); } else { tm_pointer = localtime_r(&when, &tm_value); } char buffer[CF_BUFSIZE]; if (tm_pointer == NULL) { Log(LOG_LEVEL_WARNING, "Function %s, the given time stamp '%ld' was invalid. (strftime: %s)", fp->name, when, GetErrorStr()); } else if (PortablyFormatTime(buffer, sizeof(buffer), format_string, when, tm_pointer)) { return FnReturn(buffer); } return FnFailure(); } /*********************************************************************/ static FnCallResult FnCallEval(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { if (finalargs == NULL) { FatalError(ctx, "in built-in FnCall %s: missing first argument, an evaluation input", fp->name); } const char *input = RlistScalarValue(finalargs); const char *type = NULL; if (finalargs->next) { type = RlistScalarValue(finalargs->next); } else { type = "math"; } /* Third argument can currently only be "infix". */ // So we completely ignore finalargs->next->next const bool context_mode = (strcmp(type, "class") == 0); char failure[CF_BUFSIZE]; memset(failure, 0, sizeof(failure)); double result = EvaluateMathInfix(ctx, input, failure); if (context_mode) { // see CLOSE_ENOUGH in math.peg return FnReturnContext(strlen(failure) == 0 && !(result < 0.00000000000000001 && result > -0.00000000000000001)); } if (strlen(failure) > 0) { Log(LOG_LEVEL_INFO, "%s error: %s (input '%s')", fp->name, failure, input); return FnReturn(""); /* TODO: why not FnFailure() ? */ } return FnReturnF("%lf", result); } /*********************************************************************/ /* Read functions */ /*********************************************************************/ static FnCallResult FnCallReadFile(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { if (finalargs == NULL) { Log(LOG_LEVEL_ERR, "Function 'readfile' requires at least one argument"); return FnFailure(); } char *filename = RlistScalarValue(finalargs); const Rlist *next = finalargs->next; // max_size argument, default to inf: long maxsize = next ? IntFromString(RlistScalarValue(next)) : IntFromString("inf"); if (maxsize == CF_INFINITY) /* "inf" in the policy */ { maxsize = 0; } if (maxsize < 0) { Log(LOG_LEVEL_ERR, "%s: requested max size %li is less than 0", fp->name, maxsize); return FnFailure(); } // Read once to validate structure of file in itemlist char *contents = CfReadFile(filename, maxsize); if (contents) { return FnReturnNoCopy(contents); } Log(LOG_LEVEL_VERBOSE, "Function '%s' failed to read file: %s", fp->name, filename); return FnFailure(); } /*********************************************************************/ static FnCallResult ReadList(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const FnCall *fp, const Rlist *finalargs, DataType type) { const char *filename = RlistScalarValue(finalargs); const char *comment = RlistScalarValue(finalargs->next); const char *split = RlistScalarValue(finalargs->next->next); const int maxent = IntFromString(RlistScalarValue(finalargs->next->next->next)); const int maxsize = IntFromString(RlistScalarValue(finalargs->next->next->next->next)); char *file_buffer = CfReadFile(filename, maxsize); if (!file_buffer) { Log(LOG_LEVEL_VERBOSE, "Function '%s' failed to read file: %s", fp->name, filename); return FnFailure(); } bool blanks = false; Rlist *newlist = NULL; file_buffer = StripPatterns(file_buffer, comment, filename); if (!file_buffer) { return (FnCallResult) { FNCALL_SUCCESS, { NULL, RVAL_TYPE_LIST } }; } else { newlist = RlistFromSplitRegex(file_buffer, split, maxent, blanks); } bool noerrors = true; switch (type) { case CF_DATA_TYPE_STRING: break; case CF_DATA_TYPE_INT: for (Rlist *rp = newlist; rp != NULL; rp = rp->next) { if (IntFromString(RlistScalarValue(rp)) == CF_NOINT) { Log(LOG_LEVEL_ERR, "Presumed int value '%s' read from file '%s' has no recognizable value", RlistScalarValue(rp), filename); noerrors = false; } } break; case CF_DATA_TYPE_REAL: for (Rlist *rp = newlist; rp != NULL; rp = rp->next) { double real_value = 0; if (!DoubleFromString(RlistScalarValue(rp), &real_value)) { Log(LOG_LEVEL_ERR, "Presumed real value '%s' read from file '%s' has no recognizable value", RlistScalarValue(rp), filename); noerrors = false; } } break; default: ProgrammingError("Unhandled type in switch: %d", type); } free(file_buffer); if (noerrors) { return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } RlistDestroy(newlist); return FnFailure(); } static FnCallResult FnCallReadStringList(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadList(ctx, fp, args, CF_DATA_TYPE_STRING); } static FnCallResult FnCallReadIntList(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadList(ctx, fp, args, CF_DATA_TYPE_INT); } static FnCallResult FnCallReadRealList(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadList(ctx, fp, args, CF_DATA_TYPE_REAL); } static FnCallResult ReadDataGeneric(const char *const fname, const char *const input_path, const size_t size_max, const DataFileType requested_mode) { assert(fname != NULL); assert(input_path != NULL); JsonElement *json = JsonReadDataFile(fname, input_path, requested_mode, size_max); if (json == NULL) { return FnFailure(); } return FnReturnContainerNoCopy(json); } static FnCallResult FnCallReadData(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { assert(fp != NULL); if (args == NULL) { Log(LOG_LEVEL_ERR, "Function '%s' requires at least one argument", fp->name); return FnFailure(); } const char *input_path = RlistScalarValue(args); const char *const mode_string = RlistScalarValue(args->next); DataFileType requested_mode = DATAFILETYPE_UNKNOWN; if (StringEqual("auto", mode_string)) { requested_mode = GetDataFileTypeFromSuffix(input_path); Log(LOG_LEVEL_VERBOSE, "%s: automatically selected data type %s from filename %s", fp->name, DataFileTypeToString(requested_mode), input_path); } else { requested_mode = GetDataFileTypeFromString(mode_string); } return ReadDataGeneric(fp->name, input_path, CF_INFINITY, requested_mode); } static FnCallResult ReadGenericDataType(const FnCall *fp, const Rlist *args, const DataFileType requested_mode) { assert(fp != NULL); if (args == NULL) { Log(LOG_LEVEL_ERR, "Function '%s' requires at least one argument", fp->name); return FnFailure(); } const char *const input_path = RlistScalarValue(args); size_t size_max = args->next ? IntFromString(RlistScalarValue(args->next)) : CF_INFINITY; return ReadDataGeneric(fp->name, input_path, size_max, requested_mode); } static FnCallResult FnCallReadCsv(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadGenericDataType(fp, args, DATAFILETYPE_CSV); } static FnCallResult FnCallReadEnvFile(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadGenericDataType(fp, args, DATAFILETYPE_ENV); } static FnCallResult FnCallReadYaml(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadGenericDataType(fp, args, DATAFILETYPE_YAML); } static FnCallResult FnCallReadJson(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadGenericDataType(fp, args, DATAFILETYPE_JSON); } static FnCallResult ValidateDataGeneric(const char *const fname, const char *data, const DataFileType requested_mode) { assert(data != NULL); if (requested_mode != DATAFILETYPE_JSON) { Log(LOG_LEVEL_ERR, "%s: Data type %s is not supported by this function", fname, DataFileTypeToString(requested_mode)); return FnFailure(); } JsonElement *json = NULL; JsonParseError err = JsonParseAll(&data, &json); if (err != JSON_PARSE_OK) { Log(LOG_LEVEL_VERBOSE, "%s: %s", fname, JsonParseErrorToString(err)); } FnCallResult ret = FnReturnContext(json != NULL); JsonDestroy(json); return ret; } static FnCallResult FnCallValidData(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { assert(fp != NULL); if (args == NULL || args->next == NULL) { Log(LOG_LEVEL_ERR, "Function '%s' requires two arguments", fp->name); return FnFailure(); } const char *data = RlistScalarValue(args); const char *const mode_string = RlistScalarValue(args->next); DataFileType requested_mode = GetDataFileTypeFromString(mode_string); return ValidateDataGeneric(fp->name, data, requested_mode); } static FnCallResult FnCallValidJson(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { assert(fp != NULL); if (args == NULL) { Log(LOG_LEVEL_ERR, "Function '%s' requires one argument", fp->name); return FnFailure(); } const char *data = RlistScalarValue(args); return ValidateDataGeneric(fp->name, data, DATAFILETYPE_JSON); } static FnCallResult FnCallReadModuleProtocol( ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { assert(fp != NULL); if (args == NULL) { Log(LOG_LEVEL_ERR, "Function '%s' requires at least one argument", fp->name); return FnFailure(); } const char *input_path = RlistScalarValue(args); char module_context[CF_BUFSIZE] = {0}; FILE *file = safe_fopen(input_path, "rt"); if (file == NULL) { return FnReturnContext(false); } StringSet *module_tags = StringSetNew(); long persistence = 0; size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); bool success = true; for (;;) { const ssize_t res = CfReadLine(&line, &line_size, file); if (res == -1) { if (!feof(file)) { Log(LOG_LEVEL_ERR, "Unable to read from file '%s'. (fread: %s)", input_path, GetErrorStr()); success = false; } break; } ModuleProtocol(ctx, input_path, line, false, module_context, sizeof(module_context), module_tags, &persistence); } StringSetDestroy(module_tags); free(line); fclose(file); return FnReturnContext(success); } static int JsonPrimitiveComparator(JsonElement const *left_obj, JsonElement const *right_obj, void *user_data) { size_t const index = *(size_t *)user_data; char const *left = JsonPrimitiveGetAsString(JsonAt(left_obj, index)); char const *right = JsonPrimitiveGetAsString(JsonAt(right_obj, index)); return StringSafeCompare(left, right); } static FnCallResult FnCallClassFilterCsv(EvalContext *ctx, ARG_UNUSED Policy const *policy, FnCall const *fp, Rlist const *args) { if (args == NULL || args->next == NULL || args->next->next == NULL) { FatalError(ctx, "Function %s requires at least 3 arguments", fp->name); } char const *path = RlistScalarValue(args); bool const has_heading = BooleanFromString(RlistScalarValue(args->next)); size_t const class_index = IntFromString(RlistScalarValue(args->next->next)); Rlist const *sort_arg = args->next->next->next; FILE *csv_file = safe_fopen(path, "r"); if (csv_file == NULL) { Log(LOG_LEVEL_ERR, "%s: Failed to read file %s: %s", fp->name, path, GetErrorStrFromCode(errno)); return FnFailure(); } Seq *heading = NULL; JsonElement *json = JsonArrayCreate(50); char *line; size_t num_columns = 0; // Current line number, for debugging size_t line_number = 0; while ((line = GetCsvLineNext(csv_file)) != NULL) { ++line_number; if (line[0] == '#') { Log(LOG_LEVEL_DEBUG, "%s: Ignoring comment at line %zu", fp->name, line_number); free(line); continue; } Seq *list = SeqParseCsvString(line); free(line); if (list == NULL) { Log(LOG_LEVEL_WARNING, "%s: Failed to parse line %zu, line ignored.", fp->name, line_number); continue; } if (SeqLength(list) == 1 && strlen(SeqAt(list, 0)) == 0) { Log(LOG_LEVEL_DEBUG, "%s: Found empty line at line %zu, line ignored", fp->name, line_number); SeqDestroy(list); continue; } if (num_columns == 0) { num_columns = SeqLength(list); assert(num_columns != 0); if (class_index >= num_columns) { Log(LOG_LEVEL_ERR, "%s: Class expression index is out of bounds. " "Row length %zu, index %zu", fp->name, num_columns, class_index); SeqDestroy(list); JsonDestroy(json); return FnFailure(); } } else if (num_columns != SeqLength(list)) { Log(LOG_LEVEL_WARNING, "%s: Line %zu has incorrect amount of elements, " "%zu instead of %zu. Line ignored.", fp->name, line_number, SeqLength(list), num_columns); SeqDestroy(list); continue; } // First parsed line is set to be heading if has_heading is true if (has_heading && heading == NULL) { Log(LOG_LEVEL_DEBUG, "%s: Found header at line %zu", fp->name, line_number); heading = list; SeqRemove(heading, class_index); } else { if (!IsDefinedClass(ctx, SeqAt(list, class_index))) { SeqDestroy(list); continue; } SeqRemove(list, class_index); JsonElement *class_container = JsonObjectCreate(num_columns); size_t const num_fields = SeqLength(list); for (size_t i = 0; i < num_fields; i++) { if (has_heading) { JsonObjectAppendString(class_container, SeqAt(heading, i), SeqAt(list, i)); } else { size_t const key_len = PRINTSIZE(size_t); char key[key_len]; xsnprintf(key, key_len, "%zu", i); JsonObjectAppendString(class_container, key, SeqAt(list, i)); } } JsonArrayAppendObject(json, class_container); SeqDestroy(list); } } if (sort_arg != NULL) { size_t sort_index = IntFromString(RlistScalarValue(sort_arg)); if (sort_index == class_index) { Log(LOG_LEVEL_WARNING, "%s: sorting column (%zu) is the same as class " "expression column (%zu). Not sorting data container.", fp->name, sort_index, class_index); } else if (sort_index >= num_columns) { Log(LOG_LEVEL_WARNING, "%s: sorting index %zu out of bounds. " "Not sorting data container.", fp->name, sort_index); } else { /* The sorting index needs to be decremented if it is higher than * the class expression index, since the class column is removed * in the data containers. */ if (sort_index > class_index) { sort_index--; } JsonSort(json, JsonPrimitiveComparator, &sort_index); } } fclose(csv_file); if (heading != NULL) { SeqDestroy(heading); } return FnReturnContainerNoCopy(json); } static FnCallResult FnCallParseJson(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *args) { const char *data = RlistScalarValue(args); JsonElement *json = NULL; bool yaml_mode = (strcmp(fp->name, "parseyaml") == 0); const char* data_type = yaml_mode ? "YAML" : "JSON"; JsonParseError res; if (yaml_mode) { res = JsonParseYamlString(&data, &json); } else { res = JsonParseWithLookup(ctx, &LookupVarRefToJson, &data, &json); } if (res != JSON_PARSE_OK) { Log(LOG_LEVEL_ERR, "Error parsing %s expression '%s': %s", data_type, data, JsonParseErrorToString(res)); } else if (JsonGetElementType(json) == JSON_ELEMENT_TYPE_PRIMITIVE) { Log(LOG_LEVEL_ERR, "Non-container from parsing %s expression '%s'", data_type, data); JsonDestroy(json); } else { return FnReturnContainerNoCopy(json); } return FnFailure(); } /*********************************************************************/ static FnCallResult FnCallStoreJson(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { const char *name_str = RlistScalarValueSafe(finalargs); // try to load directly bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } Writer *w = StringWriter(); JsonWrite(w, json, 0); JsonDestroyMaybe(json, allocated); Log(LOG_LEVEL_DEBUG, "%s: from data container %s, got JSON data '%s'", fp->name, name_str, StringWriterData(w)); return FnReturnNoCopy(StringWriterClose(w)); } /*********************************************************************/ // this function is separate so other data container readers can use it static FnCallResult DataRead(EvalContext *ctx, const FnCall *fp, const Rlist *finalargs) { /* 5 args: filename,comment_regex,split_regex,max number of entries,maxfilesize */ const char *filename = RlistScalarValue(finalargs); const char *comment = RlistScalarValue(finalargs->next); const char *split = RlistScalarValue(finalargs->next->next); int maxent = IntFromString(RlistScalarValue(finalargs->next->next->next)); int maxsize = IntFromString(RlistScalarValue(finalargs->next->next->next->next)); bool make_array = (strcmp(fp->name, "data_readstringarrayidx") == 0); JsonElement *json = NULL; // Read once to validate structure of file in itemlist char *file_buffer = CfReadFile(filename, maxsize); if (file_buffer) { file_buffer = StripPatterns(file_buffer, comment, filename); if (file_buffer != NULL) { json = BuildData(ctx, file_buffer, split, maxent, make_array); } } free(file_buffer); if (json == NULL) { Log(LOG_LEVEL_ERR, "%s: error reading from file '%s'", fp->name, filename); return FnFailure(); } return FnReturnContainerNoCopy(json); } /*********************************************************************/ static FnCallResult FnCallDataExpand(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *args) { bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, args, false, &allocated); if (json == NULL) { return FnFailure(); } JsonElement *expanded = JsonExpandElement(ctx, json); JsonDestroyMaybe(json, allocated); return FnReturnContainerNoCopy(expanded); } /*********************************************************************/ static FnCallResult FnCallDataRead(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return DataRead(ctx, fp, args); } /*********************************************************************/ static FnCallResult ReadArray(EvalContext *ctx, const FnCall *fp, const Rlist *finalargs, DataType type, bool int_index) /* lval,filename,separator,comment,Max number of bytes */ { if (!fp->caller) { Log(LOG_LEVEL_ERR, "Function '%s' can only be called from a promise", fp->name); return FnFailure(); } /* 6 args: array_lval,filename,comment_regex,split_regex,max number of entries,maxfilesize */ const char *array_lval = RlistScalarValue(finalargs); const char *filename = RlistScalarValue(finalargs->next); const char *comment = RlistScalarValue(finalargs->next->next); const char *split = RlistScalarValue(finalargs->next->next->next); int maxent = IntFromString(RlistScalarValue(finalargs->next->next->next->next)); int maxsize = IntFromString(RlistScalarValue(finalargs->next->next->next->next->next)); // Read once to validate structure of file in itemlist char *file_buffer = CfReadFile(filename, maxsize); int entries = 0; if (file_buffer) { file_buffer = StripPatterns(file_buffer, comment, filename); if (file_buffer) { entries = BuildLineArray(ctx, PromiseGetBundle(fp->caller), array_lval, file_buffer, split, maxent, type, int_index); } } switch (type) { case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: break; default: ProgrammingError("Unhandled type in switch: %d", type); } free(file_buffer); return FnReturnF("%d", entries); } /*********************************************************************/ static FnCallResult FnCallReadStringArray(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadArray(ctx, fp, args, CF_DATA_TYPE_STRING, false); } /*********************************************************************/ static FnCallResult FnCallReadStringArrayIndex(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadArray(ctx, fp, args, CF_DATA_TYPE_STRING, true); } /*********************************************************************/ static FnCallResult FnCallReadIntArray(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadArray(ctx, fp, args, CF_DATA_TYPE_INT, false); } /*********************************************************************/ static FnCallResult FnCallReadRealArray(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ReadArray(ctx, fp, args, CF_DATA_TYPE_REAL, false); } /*********************************************************************/ static FnCallResult ParseArray(EvalContext *ctx, const FnCall *fp, const Rlist *finalargs, DataType type, int intIndex) /* lval,filename,separator,comment,Max number of bytes */ { if (!fp->caller) { Log(LOG_LEVEL_ERR, "Function '%s' can only be called from a promise", fp->name); return FnFailure(); } /* 6 args: array_lval,instring,comment_regex,split_regex,max number of entries,maxtextsize */ const char *array_lval = RlistScalarValue(finalargs); int maxsize = IntFromString(RlistScalarValue(finalargs->next->next->next->next->next)); char *instring = xstrndup(RlistScalarValue(finalargs->next), maxsize); const char *comment = RlistScalarValue(finalargs->next->next); const char *split = RlistScalarValue(finalargs->next->next->next); int maxent = IntFromString(RlistScalarValue(finalargs->next->next->next->next)); // Read once to validate structure of file in itemlist Log(LOG_LEVEL_DEBUG, "Parse string data from string '%s' - , maxent %d, maxsize %d", instring, maxent, maxsize); int entries = 0; if (instring) { instring = StripPatterns(instring, comment, "string argument 2"); if (instring) { entries = BuildLineArray(ctx, PromiseGetBundle(fp->caller), array_lval, instring, split, maxent, type, intIndex); } } switch (type) { case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: break; default: ProgrammingError("Unhandled type in switch: %d", type); } free(instring); return FnReturnF("%d", entries); } /*********************************************************************/ static FnCallResult FnCallParseStringArray(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ParseArray(ctx, fp, args, CF_DATA_TYPE_STRING, false); } /*********************************************************************/ static FnCallResult FnCallParseStringArrayIndex(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ParseArray(ctx, fp, args, CF_DATA_TYPE_STRING, true); } /*********************************************************************/ static FnCallResult FnCallParseIntArray(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ParseArray(ctx, fp, args, CF_DATA_TYPE_INT, false); } /*********************************************************************/ static FnCallResult FnCallParseRealArray(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *args) { return ParseArray(ctx, fp, args, CF_DATA_TYPE_REAL, false); } /*********************************************************************/ static FnCallResult FnCallStringMustache(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { if (!finalargs) { return FnFailure(); } const char* const mustache_template = RlistScalarValue(finalargs); JsonElement *json = NULL; bool allocated = false; if (finalargs->next) // we have a variable name... { // try to load directly json = VarNameOrInlineToJson(ctx, fp, finalargs->next, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } } else { allocated = true; json = DefaultTemplateData(ctx, NULL); } Buffer *result = BufferNew(); bool success = MustacheRender(result, mustache_template, json); JsonDestroyMaybe(json, allocated); if (success) { return FnReturnBuffer(result); } else { BufferDestroy(result); return FnFailure(); } } /*********************************************************************/ static FnCallResult FnCallSplitString(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { /* 2args: string,split_regex,max */ char *string = RlistScalarValue(finalargs); char *split = RlistScalarValue(finalargs->next); int max = IntFromString(RlistScalarValue(finalargs->next->next)); // Read once to validate structure of file in itemlist Rlist *newlist = RlistFromSplitRegex(string, split, max, true); return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallStringSplit(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { /* 3 args: string, split_regex, max */ char *string = RlistScalarValue(finalargs); char *split = RlistScalarValue(finalargs->next); int max = IntFromString(RlistScalarValue(finalargs->next->next)); if (max < 1) { Log(LOG_LEVEL_VERBOSE, "Function '%s' called with invalid maxent argument: '%d' (should be > 0).", fp->name, max); return FnFailure(); } Rlist *newlist = RlistFromRegexSplitNoOverflow(string, split, max); if (newlist == NULL) { /* We are logging error in RlistFromRegexSplitNoOverflow() so no need to do it here as well. */ return FnFailure(); } return (FnCallResult) { FNCALL_SUCCESS, { newlist, RVAL_TYPE_LIST } }; } /*********************************************************************/ static FnCallResult FnCallStringReplace(ARG_UNUSED EvalContext *ctx, ARG_UNUSED Policy const *policy, ARG_UNUSED FnCall const *fp, Rlist const *finalargs) { if (finalargs->next == NULL || finalargs->next->next == NULL) { Log(LOG_LEVEL_WARNING, "Incorrect number of arguments for function '%s'", fp->name); return FnFailure(); } char *string = RlistScalarValue(finalargs); char *match = RlistScalarValue(finalargs->next); char *substitute = RlistScalarValue(finalargs->next->next); char *ret = SearchAndReplace(string, match, substitute); if (ret == NULL) { Log(LOG_LEVEL_WARNING, "Failed to replace with function '%s', string: '%s', match: '%s', " "substitute: '%s'", fp->name, string, match, substitute); return FnFailure(); } return FnReturnNoCopy(ret); } /*********************************************************************/ static FnCallResult FnCallStringTrim(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *string = RlistScalarValue(finalargs); return FnReturn(TrimWhitespace(string)); } /*********************************************************************/ static FnCallResult FnCallFileSexist(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { Log(LOG_LEVEL_VERBOSE, "Cannot produce valid JSON from the argument '%s' of the function '%s'", fp->name, RlistScalarValueSafe(finalargs)); return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, RlistScalarValueSafe(finalargs)); JsonDestroyMaybe(json, allocated); return FnFailure(); } JsonIterator iter = JsonIteratorInit(json); const JsonElement *el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true); /* no elements mean 'false' should be returned, otherwise let's see if the files exist */ bool file_found = el != NULL; while (file_found && (el != NULL)) { char *val = JsonPrimitiveToString(el); struct stat sb; if (stat(val, &sb) == -1) { file_found = false; } free(val); el = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true); } JsonDestroyMaybe(json, allocated); return FnReturnContext(file_found); } /*********************************************************************/ /* LDAP Nova features */ /*********************************************************************/ static FnCallResult FnCallLDAPValue(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char buffer[CF_BUFSIZE], handle[CF_BUFSIZE]; char *uri = RlistScalarValue(finalargs); char *dn = RlistScalarValue(finalargs->next); char *filter = RlistScalarValue(finalargs->next->next); char *name = RlistScalarValue(finalargs->next->next->next); char *scope = RlistScalarValue(finalargs->next->next->next->next); char *sec = RlistScalarValue(finalargs->next->next->next->next->next); snprintf(handle, CF_BUFSIZE, "%s_%s_%s_%s", dn, filter, name, scope); void *newval = CfLDAPValue(uri, dn, filter, name, scope, sec); if (newval) { CacheUnreliableValue("ldapvalue", handle, newval); } else if (RetrieveUnreliableValue("ldapvalue", handle, buffer) > 0) { newval = xstrdup(buffer); } if (newval) { return FnReturnNoCopy(newval); } return FnFailure(); } /*********************************************************************/ static FnCallResult FnCallLDAPArray(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { if (!fp->caller) { Log(LOG_LEVEL_ERR, "Function '%s' can only be called from a promise", fp->name); return FnFailure(); } char *array = RlistScalarValue(finalargs); char *uri = RlistScalarValue(finalargs->next); char *dn = RlistScalarValue(finalargs->next->next); char *filter = RlistScalarValue(finalargs->next->next->next); char *scope = RlistScalarValue(finalargs->next->next->next->next); char *sec = RlistScalarValue(finalargs->next->next->next->next->next); void *newval = CfLDAPArray(ctx, PromiseGetBundle(fp->caller), array, uri, dn, filter, scope, sec); if (newval) { return FnReturnNoCopy(newval); } return FnFailure(); } /*********************************************************************/ static FnCallResult FnCallLDAPList(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *uri = RlistScalarValue(finalargs); char *dn = RlistScalarValue(finalargs->next); char *filter = RlistScalarValue(finalargs->next->next); char *name = RlistScalarValue(finalargs->next->next->next); char *scope = RlistScalarValue(finalargs->next->next->next->next); char *sec = RlistScalarValue(finalargs->next->next->next->next->next); void *newval = CfLDAPList(uri, dn, filter, name, scope, sec); if (newval) { return (FnCallResult) { FNCALL_SUCCESS, { newval, RVAL_TYPE_LIST } }; } return FnFailure(); } /*********************************************************************/ static FnCallResult FnCallRegLDAP(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *uri = RlistScalarValue(finalargs); char *dn = RlistScalarValue(finalargs->next); char *filter = RlistScalarValue(finalargs->next->next); char *name = RlistScalarValue(finalargs->next->next->next); char *scope = RlistScalarValue(finalargs->next->next->next->next); char *regex = RlistScalarValue(finalargs->next->next->next->next->next); char *sec = RlistScalarValue(finalargs->next->next->next->next->next->next); void *newval = CfRegLDAP(ctx, uri, dn, filter, name, scope, regex, sec); if (newval) { return FnReturnNoCopy(newval); } return FnFailure(); } /*********************************************************************/ #define KILOBYTE 1024 static FnCallResult FnCallDiskFree(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { off_t df = GetDiskUsage(RlistScalarValue(finalargs), CF_SIZE_ABS); if (df == CF_INFINITY) { df = 0; } return FnReturnF("%jd", (intmax_t) (df / KILOBYTE)); } static FnCallResult FnCallMakerule(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { const char *target = RlistScalarValue(finalargs); const char *name_str = RlistScalarValueSafe(finalargs->next); time_t target_time = 0; bool stale = false; struct stat statbuf; if (lstat(target, &statbuf) == -1) { stale = true; } else { if (!S_ISREG(statbuf.st_mode)) { Log(LOG_LEVEL_WARNING, "Function '%s' target-file '%s' exists and is not a plain file", fp->name, target); // Not a probe's responsibility to fix - but have this for debugging } target_time = statbuf.st_mtime; } // Check if the file name (which should be a scalar if given directly) is explicit if (RlistValueIsType(finalargs->next, RVAL_TYPE_SCALAR) && lstat(name_str, &statbuf) != -1) { if (statbuf.st_mtime > target_time) { stale = true; } } else { // try to load directly from a container of collected values bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs->next, false, &allocated); // we failed to produce a valid JsonElement, so give up if (json == NULL) { return FnFailure(); } else if (JsonGetElementType(json) != JSON_ELEMENT_TYPE_CONTAINER) { Log(LOG_LEVEL_VERBOSE, "Function '%s', argument '%s' was not a data container or list", fp->name, name_str); JsonDestroyMaybe(json, allocated); return FnFailure(); } JsonIterator iter = JsonIteratorInit(json); const JsonElement *e; while ((e = JsonIteratorNextValueByType(&iter, JSON_ELEMENT_TYPE_PRIMITIVE, true))) { const char *value = JsonPrimitiveGetAsString(e); if (lstat(value, &statbuf) == -1) { Log(LOG_LEVEL_VERBOSE, "Function '%s', source dependency %s was not (yet) readable", fp->name, value); JsonDestroyMaybe(json, allocated); return FnReturnContext(false); } else { if (statbuf.st_mtime > target_time) { stale = true; } } } JsonDestroyMaybe(json, allocated); } return stale ? FnReturnContext(true) : FnReturnContext(false); } #if !defined(__MINGW32__) FnCallResult FnCallUserExists(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *arg = RlistScalarValue(finalargs); if (StringIsNumeric(arg)) { uid_t uid = Str2Uid(arg, NULL, NULL); if (uid == CF_SAME_OWNER || uid == CF_UNKNOWN_OWNER) { return FnFailure(); } if (!GetUserName(uid, NULL, 0, LOG_LEVEL_VERBOSE)) { return FnReturnContext(false); } } else if (!GetUserID(arg, NULL, LOG_LEVEL_VERBOSE)) { return FnReturnContext(false); } return FnReturnContext(true); } /*********************************************************************/ FnCallResult FnCallGroupExists(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, const Rlist *finalargs) { char *arg = RlistScalarValue(finalargs); if (StringIsNumeric(arg)) { gid_t gid = Str2Gid(arg, NULL, NULL); if (gid == CF_SAME_GROUP || gid == CF_UNKNOWN_GROUP) { return FnFailure(); } if (!GetGroupName(gid, NULL, 0, LOG_LEVEL_VERBOSE)) { return FnReturnContext(false); } } else if (!GetGroupID(arg, NULL, LOG_LEVEL_VERBOSE)) { return FnReturnContext(false); } return FnReturnContext(true); } #endif /* !defined(__MINGW32__) */ static bool SingleLine(const char *s) { size_t length = strcspn(s, "\n\r"); #ifdef __MINGW32__ /* Treat a CRLF as a single line-ending: */ if (s[length] == '\r' && s[length + 1] == '\n') { length++; } #endif /* [\n\r] followed by EOF */ return s[length] && !s[length+1]; } static char *CfReadFile(const char *filename, size_t maxsize) { /* TODO remove this stat() call, it's a remnant from old code that examined sb.st_size. */ struct stat sb; if (stat(filename, &sb) == -1) { if (THIS_AGENT_TYPE == AGENT_TYPE_COMMON) { Log(LOG_LEVEL_ERR, "Could not examine file '%s'", filename); } else { if (IsCf3VarString(filename)) { Log(LOG_LEVEL_VERBOSE, "Cannot converge/reduce variable '%s' yet .. assuming it will resolve later", filename); } else { Log(LOG_LEVEL_ERR, "CfReadFile: Could not examine file '%s' (stat: %s)", filename, GetErrorStr()); } } return NULL; } /* 0 means 'read until the end of file' */ size_t limit = maxsize > 0 ? maxsize : SIZE_MAX; bool truncated = false; Writer *w = NULL; int fd = safe_open(filename, O_RDONLY | O_TEXT); if (fd >= 0) { w = FileReadFromFd(fd, limit, &truncated); close(fd); } if (!w) { Log(LOG_LEVEL_ERR, "CfReadFile: Error while reading file '%s' (%s)", filename, GetErrorStr()); return NULL; } if (truncated) { Log(LOG_LEVEL_VERBOSE, "CfReadFile: Truncating file '%s' to %zu bytes as " "requested by maxsize parameter", filename, maxsize); } size_t size = StringWriterLength(w); char *result = StringWriterClose(w); /* FIXME: Is it necessary here? Move to caller(s) */ if (SingleLine(result)) { StripTrailingNewline(result, size); } return result; } /*********************************************************************/ static char *StripPatterns(char *file_buffer, const char *pattern, const char *filename) { if (NULL_OR_EMPTY(pattern)) { return file_buffer; } Regex *rx = CompileRegex(pattern); if (!rx) { return file_buffer; } size_t start, end, count = 0; const size_t original_length = strlen(file_buffer); while (StringMatchWithPrecompiledRegex(rx, file_buffer, &start, &end)) { StringCloseHole(file_buffer, start, end); if (start == end) { Log(LOG_LEVEL_WARNING, "Comment regex '%s' matched empty string in '%s'", pattern, filename); break; } assert(start < end); if (count++ > original_length) { debug_abort_if_reached(); Log(LOG_LEVEL_ERR, "Comment regex '%s' was irreconcilable reading input '%s' probably because it legally matches nothing", pattern, filename); break; } } RegexDestroy(rx); return file_buffer; } /*********************************************************************/ static JsonElement* BuildData(ARG_UNUSED EvalContext *ctx, const char *file_buffer, const char *split, int maxent, bool make_array) { JsonElement *ret = make_array ? JsonArrayCreate(10) : JsonObjectCreate(10); Seq *lines = SeqStringFromString(file_buffer, '\n'); char *line; int hcount = 0; for (size_t i = 0; i < SeqLength(lines) && hcount < maxent; i++) { line = (char*) SeqAt(lines, i); size_t line_len = strlen(line); if (line_len == 0 || (line_len == 1 && line[0] == '\r')) { continue; } if (line[line_len - 1] == '\r') { line[line_len - 1] = '\0'; } Rlist *tokens = RlistFromSplitRegex(line, split, 99999, true); JsonElement *linearray = JsonArrayCreate(10); for (const Rlist *rp = tokens; rp; rp = rp->next) { const char *token = RlistScalarValue(rp); JsonArrayAppendString(linearray, token); } RlistDestroy(tokens); if (JsonLength(linearray) > 0) { if (make_array) { JsonArrayAppendArray(ret, linearray); } else { char *key = xstrdup(JsonArrayGetAsString(linearray, 0)); JsonArrayRemoveRange(linearray, 0, 0); JsonObjectAppendArray(ret, key, linearray); free(key); } // only increase hcount if we actually got something hcount++; } } SeqDestroy(lines); return ret; } /*********************************************************************/ static int BuildLineArray(EvalContext *ctx, const Bundle *bundle, const char *array_lval, const char *file_buffer, const char *split, int maxent, DataType type, bool int_index) { Rlist *lines = RlistFromSplitString(file_buffer, '\n'); int hcount = 0; for (Rlist *it = lines; it && hcount < maxent; it = it->next) { char *line = RlistScalarValue(it); size_t line_len = strlen(line); if (line_len == 0 || (line_len == 1 && line[0] == '\r')) { continue; } if (line[line_len - 1] == '\r') { line[line_len - 1] = '\0'; } char* first_index = NULL; int vcount = 0; Rlist *tokens = RlistFromSplitRegex(line, split, 99999, true); for (const Rlist *rp = tokens; rp; rp = rp->next) { const char *token = RlistScalarValue(rp); char *converted = NULL; switch (type) { case CF_DATA_TYPE_STRING: converted = xstrdup(token); break; case CF_DATA_TYPE_INT: { long value = IntFromString(token); if (value == CF_NOINT) { FatalError(ctx, "Could not convert token to int"); } converted = StringFormat("%ld", value); } break; case CF_DATA_TYPE_REAL: { double real_value = 0; if (!DoubleFromString(token, &real_value)) { FatalError(ctx, "Could not convert token to double"); } converted = xstrdup(token); } break; default: ProgrammingError("Unhandled type in switch: %d", type); } if (first_index == NULL) { first_index = xstrdup(converted); } char *name; if (int_index) { xasprintf(&name, "%s[%d][%d]", array_lval, hcount, vcount); } else { xasprintf(&name, "%s[%s][%d]", array_lval, first_index, vcount); } VarRef *ref = VarRefParseFromBundle(name, bundle); EvalContextVariablePut(ctx, ref, converted, type, "source=function,function=buildlinearray"); VarRefDestroy(ref); free(name); free(converted); vcount++; } free(first_index); RlistDestroy(tokens); hcount++; line++; } RlistDestroy(lines); return hcount; } /*********************************************************************/ static FnCallResult FnCallProcessExists(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { char *regex = RlistScalarValue(finalargs); const bool is_context_processexists = strcmp(fp->name, "processexists") == 0; if (!LoadProcessTable()) { Log(LOG_LEVEL_ERR, "%s: could not load the process table?!?!", fp->name); return FnFailure(); } ProcessSelect ps = PROCESS_SELECT_INIT; ps.owner = NULL; ps.process_result = ""; // ps is unused because attrselect = false below Item *matched = SelectProcesses(regex, &ps, false); ClearProcessTable(); if (is_context_processexists) { const bool ret = (matched != NULL); DeleteItemList(matched); return FnReturnContext(ret); } JsonElement *json = JsonArrayCreate(50); // we're in process gathering mode for (Item *ip = matched; ip != NULL; ip = ip->next) { // we only have the ps line and PID // TODO: this properly, by including more properties of the // processes, when the underlying code stops using a plain // ItemList JsonElement *pobj = JsonObjectCreate(2); JsonObjectAppendString(pobj, "line", ip->name); JsonObjectAppendInteger(pobj, "pid", ip->counter); JsonArrayAppendObject(json, pobj); } DeleteItemList(matched); return FnReturnContainerNoCopy(json); } /*********************************************************************/ static FnCallResult FnCallNetworkConnections(EvalContext *ctx, ARG_UNUSED const Policy *policy, ARG_UNUSED const FnCall *fp, ARG_UNUSED const Rlist *finalargs) { JsonElement *json = GetNetworkingConnections(ctx); if (json == NULL) { // nothing was collected, this is a failure return FnFailure(); } return FnReturnContainerNoCopy(json); } /*********************************************************************/ struct IsReadableThreadData { pthread_t thread; pthread_cond_t cond; pthread_mutex_t mutex; const char *path; FnCallResult result; }; static void *IsReadableThreadRoutine(void *data) { assert(data != NULL); struct IsReadableThreadData *const thread_data = data; // Give main thread time to call pthread_cond_timedwait(3) int ret = pthread_mutex_lock(&thread_data->mutex); if (ret != 0) { ProgrammingError("Failed to lock mutex: %s", GetErrorStrFromCode(ret)); } thread_data->result = FnReturnContext(false); // Allow main thread to require lock on pthread_cond_timedwait(3) ret = pthread_mutex_unlock(&thread_data->mutex); if (ret != 0) { ProgrammingError("Failed to unlock mutex: %s", GetErrorStrFromCode(ret)); } char buf[1]; const int fd = open(thread_data->path, O_RDONLY); if (fd < 0) { Log(LOG_LEVEL_DEBUG, "Failed to open file '%s': %s", thread_data->path, GetErrorStr()); } else if (read(fd, buf, sizeof(buf)) < 0) { Log(LOG_LEVEL_DEBUG, "Failed to read from file '%s': %s", thread_data->path, GetErrorStr()); close(fd); } else { close(fd); thread_data->result = FnReturnContext(true); } ret = pthread_cond_signal(&(thread_data->cond)); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to signal waiting thread: %s", GetErrorStrFromCode(ret)); } return NULL; } static FnCallResult FnCallIsReadable(ARG_UNUSED EvalContext *const ctx, ARG_UNUSED const Policy *const policy, const FnCall *const fp, const Rlist *finalargs) { assert(fp != NULL); assert(fp->name != NULL); if (finalargs == NULL) { Log(LOG_LEVEL_ERR, "Function %s requires path as first argument", fp->name); return FnFailure(); } const char *const path = RlistScalarValue(finalargs); long timeout = (finalargs->next == NULL) ? 3L /* default timeout */ : IntFromString(RlistScalarValue(finalargs->next)); assert(timeout >= 0); if (timeout == 0) // Try read in main thread, possibly blocking forever { Log(LOG_LEVEL_DEBUG, "Checking if file '%s' is readable in main thread, " "possibly blocking forever.", path); char buf[1]; const int fd = open(path, O_RDONLY); if (fd < 0) { Log(LOG_LEVEL_DEBUG, "Failed to open file '%s': %s", path, GetErrorStr()); return FnReturnContext(false); } else if (read(fd, buf, sizeof(buf)) < 0) { Log(LOG_LEVEL_DEBUG, "Failed to read from file '%s': %s", path, GetErrorStr()); close(fd); return FnReturnContext(false); } close(fd); return FnReturnContext(true); } // Else try read in separate thread, possibly blocking for N seconds Log(LOG_LEVEL_DEBUG, "Checking if file '%s' is readable in separate thread, " "possibly blocking for %ld seconds.", path, timeout); struct IsReadableThreadData thread_data = {0}; thread_data.path = path; int ret = pthread_mutex_init(&thread_data.mutex, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize mutex: %s", GetErrorStrFromCode(ret)); return FnFailure(); } ret = pthread_cond_init(&thread_data.cond, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize condition: %s", GetErrorStrFromCode(ret)); return FnFailure(); } // Keep thread from doing its thing until we call // pthread_cond_timedwait(3) ret = pthread_mutex_lock(&thread_data.mutex); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to lock mutex: %s", GetErrorStrFromCode(ret)); return FnFailure(); } ret = pthread_create(&thread_data.thread, NULL, &IsReadableThreadRoutine, &thread_data); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to create thread: %s", GetErrorStrFromCode(ret)); return FnFailure(); } FnCallResult result; // Wait on thread to finish or timeout ret = ThreadWait(&thread_data.cond, &thread_data.mutex, timeout); switch (ret) { case 0: // Thread finished in time result = thread_data.result; break; case ETIMEDOUT: // Thread timed out Log(LOG_LEVEL_DEBUG, "File '%s' is not readable: " "Read operation timed out, exceeded %ld seconds.", path, timeout); ret = pthread_cancel(thread_data.thread); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to cancel thread"); return FnFailure(); } result = FnReturnContext(false); break; default: Log(LOG_LEVEL_ERR, "Failed to wait for condition: %s", GetErrorStrFromCode(ret)); return FnFailure(); } ret = pthread_mutex_unlock(&thread_data.mutex); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to unlock mutex"); return FnFailure(); } void *status; ret = pthread_join(thread_data.thread, &status); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join thread"); return FnFailure(); } if (status == PTHREAD_CANCELED) { Log(LOG_LEVEL_DEBUG, "Thread was canceled"); } return result; } /*********************************************************************/ static FnCallResult FnCallFindfilesUp(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { assert(fp != NULL); assert(fp->name != NULL); const Rlist *const path_arg = finalargs; if (path_arg == NULL) { Log(LOG_LEVEL_ERR, "Function %s requires path as first argument", fp->name); return FnFailure(); } const Rlist *const glob_arg = finalargs->next; if (glob_arg == NULL) { Log(LOG_LEVEL_ERR, "Function %s requires glob as second argument", fp->name); return FnFailure(); } const Rlist *const level_arg = finalargs->next->next; char path[PATH_MAX]; size_t copied = strlcpy(path, RlistScalarValue(path_arg), sizeof(path)); if (copied >= sizeof(path)) { Log(LOG_LEVEL_ERR, "Function %s, path is too long (%zu > %zu)", fp->name, copied, sizeof(path)); return FnFailure(); } if (!IsAbsoluteFileName(path)) { Log(LOG_LEVEL_ERR, "Function %s, not an absolute path '%s'", fp->name, path); return FnFailure(); } if (!IsDir(path)) { Log(LOG_LEVEL_ERR, "Function %s, path '%s' is not a directory", fp->name, path); return FnFailure(); } MapName(path); // Makes sure we get host native path separators DeleteRedundantSlashes(path); size_t len = strlen(path); if (path[len - 1] == FILE_SEPARATOR) { path[len - 1] = '\0'; } char glob[PATH_MAX]; copied = strlcpy(glob, RlistScalarValue(glob_arg), sizeof(glob)); if (copied >= sizeof(glob)) { Log(LOG_LEVEL_ERR, "Function %s, glob is too long (%zu > %zu)", fp->name, copied, sizeof(glob)); return FnFailure(); } if (IsAbsoluteFileName(glob)) { Log(LOG_LEVEL_ERR, "Function %s, glob '%s' cannot be an absolute path", fp->name, glob); return FnFailure(); } DeleteRedundantSlashes(glob); /* level defaults to inf */ long level = IntFromString("inf"); if (level_arg != NULL) { level = IntFromString(RlistScalarValue(level_arg)); } JsonElement *json = JsonArrayCreate(1); while (level-- >= 0) { char filepath[PATH_MAX]; copied = strlcpy(filepath, path, sizeof(filepath)); assert(copied < sizeof(path)); if (JoinPaths(filepath, sizeof(filepath), glob) == NULL) { Log(LOG_LEVEL_ERR, "Function %s, failed to join path '%s' and glob '%s'", fp->name, path, glob); } StringSet *matches = GlobFileList(filepath); JsonElement *matches_json = StringSetToJson(matches); JsonArrayExtend(json, matches_json); StringSetDestroy(matches); char *sep = strrchr(path, FILE_SEPARATOR); if (sep == NULL) { /* don't search beyond root directory */ break; } *sep = '\0'; } return FnReturnContainerNoCopy(json); } /*********************************************************************/ static bool ExecModule(EvalContext *ctx, char *command) { FILE *pp = cf_popen(command, "rt", true); if (!pp) { Log(LOG_LEVEL_ERR, "Couldn't open pipe from '%s'. (cf_popen: %s)", command, GetErrorStr()); return false; } char context[CF_BUFSIZE] = ""; StringSet *tags = StringSetNew(); long persistence = 0; size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); while (CfReadLine(&line, &line_size, pp) != -1) { bool print = false; for (const char *sp = line; *sp != '\0'; sp++) { if (!isspace((unsigned char) *sp)) { print = true; break; } } ModuleProtocol(ctx, command, line, print, context, sizeof(context), tags, &persistence); } bool atend = feof(pp); cf_pclose(pp); free(line); StringSetDestroy(tags); if (!atend) { Log(LOG_LEVEL_ERR, "Unable to read output from '%s'. (fread: %s)", command, GetErrorStr()); return false; } return true; } void ModuleProtocol(EvalContext *ctx, const char *command, const char *line, int print, char* context, size_t context_size, StringSet *tags, long *persistence) { assert(tags); StringSetAdd(tags, xstrdup("source=module")); StringSetAddF(tags, "derived_from=%s", command); // see the sscanf() limit below if(context_size < 51) { ProgrammingError("ModuleProtocol: context_size too small (%zu)", context_size); } if (*context == '\0') { /* Infer namespace from script name */ char arg0[CF_BUFSIZE]; strlcpy(arg0, CommandArg0(command), CF_BUFSIZE); char *filename = basename(arg0); /* Canonicalize filename into acceptable namespace name */ CanonifyNameInPlace(filename); strlcpy(context, filename, context_size); Log(LOG_LEVEL_VERBOSE, "Module context '%s'", context); } char name[CF_BUFSIZE], content[CF_BUFSIZE]; name[0] = content[0] = '\0'; size_t length = strlen(line); switch (*line) { case '^': // Allow modules to set their variable context (up to 50 characters) if (sscanf(line + 1, "context=%50[^\n]", content) == 1 && content[0] != '\0') { /* Symbol ID without \200 to \377: */ Regex *context_name_rx = CompileRegex("[a-zA-Z0-9_]+"); if (!context_name_rx) { Log(LOG_LEVEL_ERR, "Internal error compiling module protocol context regex, aborting!!!"); } else if (StringMatchFullWithPrecompiledRegex(context_name_rx, content)) { Log(LOG_LEVEL_VERBOSE, "Module changed variable context from '%s' to '%s'", context, content); strlcpy(context, content, context_size); } else { Log(LOG_LEVEL_ERR, "Module protocol was given an unacceptable ^context directive '%s', skipping", content); } if (context_name_rx) { RegexDestroy(context_name_rx); } } else if (sscanf(line + 1, "meta=%1024[^\n]", content) == 1 && content[0] != '\0') { Log(LOG_LEVEL_VERBOSE, "Module set meta tags to '%s'", content); StringSetClear(tags); StringSetAddSplit(tags, content, ','); StringSetAdd(tags, xstrdup("source=module")); StringSetAddF(tags, "derived_from=%s", command); } else if (sscanf(line + 1, "persistence=%ld", persistence) == 1) { Log(LOG_LEVEL_VERBOSE, "Module set persistence to %ld minutes", *persistence); } else { Log(LOG_LEVEL_INFO, "Unknown extended module command '%s'", line); } break; case '+': if (length > CF_MAXVARSIZE) { Log(LOG_LEVEL_ERR, "Module protocol was given an overlong +class line (%zu bytes), skipping", length); break; } // the class name will fit safely inside CF_MAXVARSIZE - 1 bytes sscanf(line + 1, "%1023[^\n]", content); Log(LOG_LEVEL_VERBOSE, "Activating classes from module protocol: '%s'", content); if (CheckID(content)) { Buffer *tagbuf = StringSetToBuffer(tags, ','); EvalContextClassPutSoft(ctx, content, CONTEXT_SCOPE_NAMESPACE, BufferData(tagbuf)); if (*persistence > 0) { Log(LOG_LEVEL_VERBOSE, "Module set persistent class '%s' for %ld minutes", content, *persistence); EvalContextHeapPersistentSave(ctx, content, *persistence, CONTEXT_STATE_POLICY_PRESERVE, BufferData(tagbuf)); } BufferDestroy(tagbuf); } else { Log(LOG_LEVEL_VERBOSE, "Automatically canonifying '%s'", content); CanonifyNameInPlace(content); Log(LOG_LEVEL_VERBOSE, "Automatically canonified to '%s'", content); Buffer *tagbuf = StringSetToBuffer(tags, ','); EvalContextClassPutSoft(ctx, content, CONTEXT_SCOPE_NAMESPACE, BufferData(tagbuf)); BufferDestroy(tagbuf); } break; case '-': if (length > CF_MAXVARSIZE) { Log(LOG_LEVEL_ERR, "Module protocol was given an overlong -class line (%zu bytes), skipping", length); break; } // the class name(s) will fit safely inside CF_MAXVARSIZE - 1 bytes sscanf(line + 1, "%1023[^\n]", content); Log(LOG_LEVEL_VERBOSE, "Deactivating classes from module protocol: '%s'", content); if (CheckID(content)) { if (content[0] != '\0') { StringSet *negated = StringSetFromString(content, ','); StringSetIterator it = StringSetIteratorInit(negated); const char *negated_context = NULL; while ((negated_context = StringSetIteratorNext(&it))) { Class *cls = EvalContextClassGet(ctx, NULL, negated_context); if (cls && !cls->is_soft) { FatalError(ctx, "Cannot negate the reserved class '%s'", negated_context); } ClassRef ref = ClassRefParse(negated_context); EvalContextClassRemove(ctx, ref.ns, ref.name); ClassRefDestroy(ref); } StringSetDestroy(negated); } } break; case '=': if (length > CF_BUFSIZE + 256) { Log(LOG_LEVEL_ERR, "Module protocol was given an overlong variable =line (%zu bytes), skipping", length); break; } // TODO: the variable name is limited to 256 to accommodate the // context name once it's in the vartable. Maybe this can be relaxed. sscanf(line + 1, "%256[^=]=%4095[^\n]", name, content); if (CheckID(name)) { Log(LOG_LEVEL_VERBOSE, "Defined variable '%s' in context '%s' with value '%s'", name, context, content); VarRef *ref = VarRefParseFromScope(name, context); Buffer *tagbuf = StringSetToBuffer(tags, ','); EvalContextVariablePut(ctx, ref, content, CF_DATA_TYPE_STRING, BufferData(tagbuf)); BufferDestroy(tagbuf); VarRefDestroy(ref); } break; case '&': // TODO: the variable name is limited to 256 to accommodate the // context name once it's in the vartable. Maybe this can be relaxed. // &policy_varname=/path/to/file can be json/env/yaml/csv type, default: json sscanf(line + 1, "%256[^=]=%4095[^\n]", name, content); if (CheckID(name)) { if (FileCanOpen(content, "r")) { const int size_max = IntFromString("inf"); const DataFileType requested_mode = GetDataFileTypeFromSuffix(content); Log(LOG_LEVEL_DEBUG, "Module protocol parsing %s file '%s'", DataFileTypeToString(requested_mode), content); JsonElement *json = JsonReadDataFile("module file protocol", content, requested_mode, size_max); if (json != NULL) { Buffer *tagbuf = StringSetToBuffer(tags, ','); VarRef *ref = VarRefParseFromScope(name, context); EvalContextVariablePut(ctx, ref, json, CF_DATA_TYPE_CONTAINER, BufferData(tagbuf)); VarRefDestroy(ref); BufferDestroy(tagbuf); JsonDestroy(json); } else { // reading / parsing failed, error message printed by JsonReadDataFile, // variable will not be created } } else { Log(LOG_LEVEL_ERR, "could not load module file '%s'", content); } } break; case '%': // TODO: the variable name is limited to 256 to accommodate the // context name once it's in the vartable. Maybe this can be relaxed. sscanf(line + 1, "%256[^=]=", name); if (CheckID(name)) { JsonElement *json = NULL; Buffer *holder = BufferNewFrom(line+strlen(name)+1+1, length - strlen(name) - 1 - 1); const char *hold = BufferData(holder); Log(LOG_LEVEL_DEBUG, "Module protocol parsing JSON %s", content); JsonParseError res = JsonParse(&hold, &json); if (res != JSON_PARSE_OK) { Log(LOG_LEVEL_INFO, "Failed to parse JSON '%s' for module protocol: %s", content, JsonParseErrorToString(res)); } else { if (JsonGetElementType(json) == JSON_ELEMENT_TYPE_PRIMITIVE) { Log(LOG_LEVEL_INFO, "Module protocol JSON '%s' should be object or array; wasn't", content); } else { Log(LOG_LEVEL_VERBOSE, "Defined data container variable '%s' in context '%s' with value '%s'", name, context, BufferData(holder)); Buffer *tagbuf = StringSetToBuffer(tags, ','); VarRef *ref = VarRefParseFromScope(name, context); EvalContextVariablePut(ctx, ref, json, CF_DATA_TYPE_CONTAINER, BufferData(tagbuf)); VarRefDestroy(ref); BufferDestroy(tagbuf); } JsonDestroy(json); } BufferDestroy(holder); } break; case '@': // TODO: should not need to exist. entry size matters, not line size. bufferize module protocol if (length > CF_BUFSIZE + 256 - 1) { Log(LOG_LEVEL_ERR, "Module protocol was given an overlong variable @line (%zu bytes), skipping", length); break; } sscanf(line + 1, "%256[^=]=%4095[^\n]", name, content); if (CheckID(name)) { Rlist *list = RlistParseString(content); if (!list) { Log(LOG_LEVEL_ERR, "Module protocol could not parse variable %s's data content %s", name, content); } else { bool has_oversize_entry = false; for (const Rlist *rp = list; rp; rp = rp->next) { size_t entry_size = strlen(RlistScalarValue(rp)); if (entry_size > CF_MAXVARSIZE) { has_oversize_entry = true; break; } } if (has_oversize_entry) { Log(LOG_LEVEL_ERR, "Module protocol was given a variable @ line with an oversize entry, skipping"); RlistDestroy(list); break; } Log(LOG_LEVEL_VERBOSE, "Defined variable '%s' in context '%s' with value '%s'", name, context, content); VarRef *ref = VarRefParseFromScope(name, context); Buffer *tagbuf = StringSetToBuffer(tags, ','); EvalContextVariablePut(ctx, ref, list, CF_DATA_TYPE_STRING_LIST, BufferData(tagbuf)); BufferDestroy(tagbuf); VarRefDestroy(ref); RlistDestroy(list); } } break; case '\0': break; default: if (print) { Log(LOG_LEVEL_INFO, "M '%s': %s", command, line); } break; } } /*********************************************************************/ static FnCallResult FnCallCFEngineCallers(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, ARG_UNUSED const Rlist *finalargs) { bool promisersmode = (strcmp(fp->name, "callstack_promisers") == 0); if (promisersmode) { Rlist *returnlist = EvalContextGetPromiseCallerMethods(ctx); return (FnCallResult) { FNCALL_SUCCESS, { returnlist, RVAL_TYPE_LIST } }; } JsonElement *callers = EvalContextGetPromiseCallers(ctx); return FnReturnContainerNoCopy(callers); } static FnCallResult FnCallString(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs) { assert(finalargs != NULL); char *ret = RvalToString(finalargs->val); if (StringStartsWith(ret, "@(") || StringStartsWith(ret, "@{")) { bool allocated = false; JsonElement *json = VarNameOrInlineToJson(ctx, fp, finalargs, false, &allocated); if (json != NULL) { Writer *w = StringWriter(); JsonWriteCompact(w, json); ret = StringWriterClose(w); if (allocated) { JsonDestroy(json); } } } return FnReturnNoCopy(ret); } /*********************************************************************/ /* Level */ /*********************************************************************/ static bool CheckIDChar(const char ch) { return isalnum((int) ch) || (ch == '.') || (ch == '-') || (ch == '_') || (ch == '[') || (ch == ']') || (ch == '/') || (ch == '@'); } static bool CheckID(const char *id) { for (const char *sp = id; *sp != '\0'; sp++) { if (!CheckIDChar(*sp)) { Log(LOG_LEVEL_VERBOSE, "Module protocol contained an illegal character '%c' in class/variable identifier '%s'.", *sp, id); } } return true; } /*********************************************************/ /* Function prototypes */ /*********************************************************/ static const FnCallArg ACCESSEDBEFORE_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Newer filename"}, {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Older filename"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg ACCUM_ARGS[] = { {"0,1000", CF_DATA_TYPE_INT, "Years"}, {"0,1000", CF_DATA_TYPE_INT, "Months"}, {"0,1000", CF_DATA_TYPE_INT, "Days"}, {"0,1000", CF_DATA_TYPE_INT, "Hours"}, {"0,1000", CF_DATA_TYPE_INT, "Minutes"}, {"0,40000", CF_DATA_TYPE_INT, "Seconds"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg AND_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg AGO_ARGS[] = { {"0,1000", CF_DATA_TYPE_INT, "Years"}, {"0,1000", CF_DATA_TYPE_INT, "Months"}, {"0,1000", CF_DATA_TYPE_INT, "Days"}, {"0,1000", CF_DATA_TYPE_INT, "Hours"}, {"0,1000", CF_DATA_TYPE_INT, "Minutes"}, {"0,40000", CF_DATA_TYPE_INT, "Seconds"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg LATERTHAN_ARGS[] = { {"0,10000", CF_DATA_TYPE_INT, "Years"}, {"0,1000", CF_DATA_TYPE_INT, "Months"}, {"0,1000", CF_DATA_TYPE_INT, "Days"}, {"0,1000", CF_DATA_TYPE_INT, "Hours"}, {"0,1000", CF_DATA_TYPE_INT, "Minutes"}, {"0,40000", CF_DATA_TYPE_INT, "Seconds"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg BASENAME_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "File path"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Optional suffix"}, {NULL, CF_DATA_TYPE_NONE, NULL}, }; static const FnCallArg DATE_ARGS[] = /* for on() */ { {"1970,3000", CF_DATA_TYPE_INT, "Year"}, {"0,1000", CF_DATA_TYPE_INT, "Month (January = 0)"}, {"0,1000", CF_DATA_TYPE_INT, "Day (First day of month = 0)"}, {"0,1000", CF_DATA_TYPE_INT, "Hour"}, {"0,1000", CF_DATA_TYPE_INT, "Minute"}, {"0,1000", CF_DATA_TYPE_INT, "Second"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CANONIFY_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "String containing non-identifier characters"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CHANGEDBEFORE_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Newer filename"}, {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Older filename"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CFVERSION_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine version number to compare against"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CFVERSIONBETWEEN_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Lower CFEngine version number to compare against"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Upper CFEngine version number to compare against"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg VERSION_COMPARE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "First version to compare"}, {"=,==,!=,>,<,>=,<=", CF_DATA_TYPE_OPTION, "Operator to use in comparison"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Second version to compare"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CLASSIFY_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CLASSMATCH_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CONCAT_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg COUNTLINESMATCHING_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Filename"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg DIRNAME_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "File path"}, {NULL, CF_DATA_TYPE_NONE, NULL}, }; static const FnCallArg DISKFREE_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File system directory"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg ESCAPE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "IP address or string to escape"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg EXECRESULT_ARGS[] = { {CF_PATHRANGE, CF_DATA_TYPE_STRING, "Fully qualified command path"}, {"noshell,useshell,powershell", CF_DATA_TYPE_OPTION, "Shell encapsulation option"}, {"both,stdout,stderr", CF_DATA_TYPE_OPTION, "Which output to return; stdout or stderr"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; // fileexists, isdir,isplain,islink static const FnCallArg FILESTAT_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File object name"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg FILESTAT_DETAIL_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File object name"}, {"size,gid,uid,ino,nlink,ctime,atime,mtime,xattr,mode,modeoct,permstr,permoct,type,devno,dev_minor,dev_major,basename,dirname,linktarget,linktarget_shallow", CF_DATA_TYPE_OPTION, "stat() field to get"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg FILESEXIST_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg FINDFILES_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg FILTER_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression or string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {CF_BOOL, CF_DATA_TYPE_OPTION, "Match as regular expression if true, as exact string otherwise"}, {CF_BOOL, CF_DATA_TYPE_OPTION, "Invert matches"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of matches to return"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETFIELDS_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression to match line"}, {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Filename to read"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression to split fields"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Return array name"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETINDICES_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETUSERS_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Comma separated list of User names"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Comma separated list of UserID numbers"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETENV_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Name of environment variable"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of characters to read "}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETGID_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Group name in text"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETUID_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "User name in text"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETUSERINFO_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "User name in text"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GREP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GROUPEXISTS_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Group name or identifier"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HASH_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input text"}, {"md5,sha1,sha256,sha384,sha512", CF_DATA_TYPE_OPTION, "Hash or digest algorithm"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg FILE_HASH_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File object name"}, {"md5,sha1,sha256,sha384,sha512", CF_DATA_TYPE_OPTION, "Hash or digest algorithm"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HASHMATCH_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Filename to hash"}, {"md5,sha1,sha256,sha384,sha512", CF_DATA_TYPE_OPTION, "Hash or digest algorithm"}, {CF_IDRANGE, CF_DATA_TYPE_STRING, "ASCII representation of hash for comparison"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HOST2IP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Host name in ascii"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg IP2HOST_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "IP address (IPv4 or IPv6)"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HOSTINNETGROUP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Netgroup name"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HOSTRANGE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Hostname prefix"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Enumerated range"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HOSTSSEEN_ARGS[] = { {CF_VALRANGE, CF_DATA_TYPE_INT, "Horizon since last seen in hours"}, {"lastseen,notseen", CF_DATA_TYPE_OPTION, "Complements for selection policy"}, {"name,address,hostkey", CF_DATA_TYPE_OPTION, "Type of return value desired"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HOSTSWITHCLASS_ARGS[] = { {"[a-zA-Z0-9_]+", CF_DATA_TYPE_STRING, "Class name to look for"}, {"name,address", CF_DATA_TYPE_OPTION, "Type of return value desired"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg IFELSE_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg INT_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Numeric string to convert to integer"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg IPRANGE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "IP address range syntax"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg IRANGE_ARGS[] = { {CF_INTRANGE, CF_DATA_TYPE_INT, "Integer start of range"}, {CF_INTRANGE, CF_DATA_TYPE_INT, "Integer end of range"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg ISGREATERTHAN_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Larger string or value"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Smaller string or value"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg ISLESSTHAN_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Smaller string or value"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Larger string or value"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg ISNEWERTHAN_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Newer file name"}, {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Older file name"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg ISVARIABLE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Variable identifier"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg JOIN_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Join glue-string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg LASTNODE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Link separator, e.g. /,:"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg LDAPARRAY_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Array name"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "URI"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Distinguished name"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Filter"}, {"subtree,onelevel,base", CF_DATA_TYPE_OPTION, "Search scope policy"}, {"none,ssl,sasl", CF_DATA_TYPE_OPTION, "Security level"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg LDAPLIST_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "URI"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Distinguished name"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Filter"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Record name"}, {"subtree,onelevel,base", CF_DATA_TYPE_OPTION, "Search scope policy"}, {"none,ssl,sasl", CF_DATA_TYPE_OPTION, "Security level"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg LDAPVALUE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "URI"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Distinguished name"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Filter"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Record name"}, {"subtree,onelevel,base", CF_DATA_TYPE_OPTION, "Search scope policy"}, {"none,ssl,sasl", CF_DATA_TYPE_OPTION, "Security level"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg LSDIRLIST_ARGS[] = { {CF_PATHRANGE, CF_DATA_TYPE_STRING, "Path to base directory"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression to match files or blank"}, {CF_BOOL, CF_DATA_TYPE_OPTION, "Include the base path in the list"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg MAPLIST_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Pattern based on $(this) as original text"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg EXPANDRANGE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "String containing numerical range e.g. string[13-47]"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Step size of numerical increments"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg MAPARRAY_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Pattern based on $(this.k) and $(this.v) as original text"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON, the array variable to map"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg MAPDATA_ARGS[] = { {"none,canonify,json,json_pipe", CF_DATA_TYPE_OPTION, "Conversion to apply to the mapped string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Pattern based on $(this.k) and $(this.v) as original text"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg MERGEDATA_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg NOT_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Class value"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg NOW_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg OR_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SUM_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PRODUCT_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PACKAGESMATCHING_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression (unanchored) to match package name"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression (unanchored) to match package version"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression (unanchored) to match package architecture"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression (unanchored) to match package method"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PEERS_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name of host list"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Comment regex pattern"}, {"2,64", CF_DATA_TYPE_INT, "Peer group size"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PEERLEADER_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name of host list"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Comment regex pattern"}, {"2,64", CF_DATA_TYPE_INT, "Peer group size"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PEERLEADERS_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name of host list"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Comment regex pattern"}, {"2,64", CF_DATA_TYPE_INT, "Peer group size"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg RANDOMINT_ARGS[] = { {CF_INTRANGE, CF_DATA_TYPE_INT, "Lower inclusive bound"}, {CF_INTRANGE, CF_DATA_TYPE_INT, "Upper exclusive bound"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HASH_TO_INT_ARGS[] = { {CF_INTRANGE, CF_DATA_TYPE_INT, "Lower inclusive bound"}, {CF_INTRANGE, CF_DATA_TYPE_INT, "Upper exclusive bound"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string to hash"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STRING_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Convert argument to string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg READFILE_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of bytes to read"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg VALIDDATATYPE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "String to validate as JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CLASSFILTERCSV_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name"}, {CF_BOOL, CF_DATA_TYPE_OPTION, "CSV file has heading"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Column index to filter by, " "contains classes"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Column index to sort by"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg READSTRINGARRAY_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Array identifier to populate"}, {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name to read"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex matching comments"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex to split data"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of entries to read"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum bytes to read"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PARSESTRINGARRAY_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Array identifier to populate"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "A string to parse for input data"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex matching comments"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex to split data"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of entries to read"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum bytes to read"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg READSTRINGLIST_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name to read"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex matching comments"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex to split data"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of entries to read"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum bytes to read"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg READDATA_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name to read"}, {"CSV,YAML,JSON,ENV,auto", CF_DATA_TYPE_OPTION, "Type of data to read"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg VALIDDATA_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "String to validate as JSON"}, {"JSON", CF_DATA_TYPE_OPTION, "Type of data to validate"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg READMODULE_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name to read and parse from"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PARSEJSON_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "JSON string to parse"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STOREJSON_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg READTCP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Host name or IP address of server socket"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Port number or service name"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Protocol query string"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of bytes to read"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGARRAY_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGCMP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Match string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGEXTRACT_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Match string"}, {CF_IDRANGE, CF_DATA_TYPE_STRING, "Identifier for back-references"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg DATA_REGEXTRACT_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Match string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGEX_REPLACE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Source string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression pattern"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Replacement string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "sed/Perl-style options: gmsixUT"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGISTRYVALUE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Windows registry key"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Windows registry value-id"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGLINE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Filename to search"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGLIST_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg MAKERULE_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Target filename"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Source filename or CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REGLDAP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "URI"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Distinguished name"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Filter"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Record name"}, {"subtree,onelevel,base", CF_DATA_TYPE_OPTION, "Search scope policy"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex to match results"}, {"none,ssl,sasl", CF_DATA_TYPE_OPTION, "Security level"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REMOTESCALAR_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Variable identifier"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Hostname or IP address of server"}, {CF_BOOL, CF_DATA_TYPE_OPTION, "Use enryption"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg HUB_KNOWLEDGE_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Variable identifier"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REMOTECLASSESMATCHING_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Server name or address"}, {CF_BOOL, CF_DATA_TYPE_OPTION, "Use encryption"}, {CF_IDRANGE, CF_DATA_TYPE_STRING, "Return class prefix"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg RETURNSZERO_ARGS[] = { {CF_PATHRANGE, CF_DATA_TYPE_STRING, "Command path"}, {"noshell,useshell,powershell", CF_DATA_TYPE_OPTION, "Shell encapsulation option"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg RRANGE_ARGS[] = { {CF_REALRANGE, CF_DATA_TYPE_REAL, "Real number, start of range"}, {CF_REALRANGE, CF_DATA_TYPE_REAL, "Real number, end of range"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SELECTSERVERS_ARGS[] = { {CF_NAKEDLRANGE, CF_DATA_TYPE_STRING, "CFEngine list identifier, the list of hosts or addresses to contact"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Port number or service name."}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "A query string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "A regular expression to match success"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of bytes to read from server"}, {CF_IDRANGE, CF_DATA_TYPE_STRING, "Name for array of results"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SPLAYCLASS_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string for classification"}, {"daily,hourly", CF_DATA_TYPE_OPTION, "Splay time policy"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SPLITSTRING_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "A data string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex to split on"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of pieces"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STRCMP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "String"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "String"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STRFTIME_ARGS[] = { {"gmtime,localtime", CF_DATA_TYPE_OPTION, "Use GMT or local time"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "A format string"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "The time as a Unix epoch offset"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STRING_REPLACE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Source string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "String to replace"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Replacement string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STRING_TRIM_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SUBLIST_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {"head,tail", CF_DATA_TYPE_OPTION, "Whether to return elements from the head or from the tail of the list"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of elements to return"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg TRANSLATEPATH_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Unix style path"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg USEMODULE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Name of module command"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Argument string for the module"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg UNIQUE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg NTH_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Offset or key of element to return"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg EVERY_SOME_NONE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression or string"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg USEREXISTS_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "User name or identifier"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SORT_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {"lex,int,real,IP,ip,MAC,mac", CF_DATA_TYPE_OPTION, "Sorting method: lex or int or real (floating point) or IPv4/IPv6 or MAC address"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg REVERSE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SHUFFLE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Any seed string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STAT_FOLD_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SETOP_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine base variable identifier or inline JSON"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine filter variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg FORMAT_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine format string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg EVAL_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string"}, {"math,class", CF_DATA_TYPE_OPTION, "Evaluation type"}, {"infix", CF_DATA_TYPE_OPTION, "Evaluation options"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg BUNDLESMATCHING_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg XFORM_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg XFORM_SUBSTR_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Input string"}, {CF_INTRANGE, CF_DATA_TYPE_INT, "Maximum number of characters to return"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg DATASTATE_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg BUNDLESTATE_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Bundle name"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETCLASSMETATAGS_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Class identifier"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg GETVARIABLEMETATAGS_ARGS[] = { {CF_IDRANGE, CF_DATA_TYPE_STRING, "Variable identifier"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg DATA_READSTRINGARRAY_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "File name to read"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex matching comments"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regex to split data"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum number of entries to read"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Maximum bytes to read"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg DATA_EXPAND_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg STRING_MUSTACHE_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CURL_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "URL to retrieve"}, {CF_ANYSTRING, CF_DATA_TYPE_STRING, "CFEngine variable identifier or inline JSON, can be blank"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg PROCESSEXISTS_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Regular expression to match process name"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg NETWORK_CONNECTIONS_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CFENGINE_PROMISERS_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg CFENGINE_CALLERS_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg SYSCTLVALUE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "sysctl key"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg DATA_SYSCTLVALUES_ARGS[] = { {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg FINDFILES_UP_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Path to search from"}, {CF_PATHRANGE, CF_DATA_TYPE_STRING, "Glob pattern to match files"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Number of levels to search"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg ISREADABLE_ARGS[] = { {CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Path to file"}, {CF_VALRANGE, CF_DATA_TYPE_INT, "Timeout interval"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; static const FnCallArg DATATYPE_ARGS[] = { {CF_ANYSTRING, CF_DATA_TYPE_STRING, "Variable identifier"}, {CF_BOOL, CF_DATA_TYPE_OPTION, "Enable detailed type decription"}, {NULL, CF_DATA_TYPE_NONE, NULL} }; /*********************************************************/ /* FnCalls are rvalues in certain promise constraints */ /*********************************************************/ /* see fncall.h enum FnCallType */ /* In evalfunction_test.c we both include this file and link with libpromises. * This guard makes sure we don't get a duplicate definition of this symbol */ #ifndef CFENGINE_EVALFUNCTION_TEST_C const FnCallType CF_FNCALL_TYPES[] = { FnCallTypeNew("accessedbefore", CF_DATA_TYPE_CONTEXT, ACCESSEDBEFORE_ARGS, &FnCallIsAccessedBefore, "True if arg1 was accessed before arg2 (atime)", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("accumulated", CF_DATA_TYPE_INT, ACCUM_ARGS, &FnCallAccumulatedDate, "Convert an accumulated amount of time into a system representation", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("ago", CF_DATA_TYPE_INT, AGO_ARGS, &FnCallAgoDate, "Convert a time relative to now to an integer system representation", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("and", CF_DATA_TYPE_CONTEXT, AND_ARGS, &FnCallAnd, "Calculate whether all arguments evaluate to true", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("basename", CF_DATA_TYPE_STRING, BASENAME_ARGS, &FnCallBasename, "Retrieves the basename of a filename.", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("bundlesmatching", CF_DATA_TYPE_STRING_LIST, BUNDLESMATCHING_ARGS, &FnCallBundlesMatching, "Find all the bundles that match a regular expression and tags.", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("bundlestate", CF_DATA_TYPE_CONTAINER, BUNDLESTATE_ARGS, &FnCallBundlestate, "Construct a container of the variables in a bundle and the global class state", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("canonify", CF_DATA_TYPE_STRING, CANONIFY_ARGS, &FnCallCanonify, "Convert an abitrary string into a legal class name", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("canonifyuniquely", CF_DATA_TYPE_STRING, CANONIFY_ARGS, &FnCallCanonify, "Convert an abitrary string into a unique legal class name", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("concat", CF_DATA_TYPE_STRING, CONCAT_ARGS, &FnCallConcat, "Concatenate all arguments into string", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("cf_version_minimum", CF_DATA_TYPE_CONTEXT, CFVERSION_ARGS, &FnCallVersionMinimum, "True if local CFEngine version is newer than or equal to input", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("cf_version_after", CF_DATA_TYPE_CONTEXT, CFVERSION_ARGS, &FnCallVersionAfter, "True if local CFEngine version is newer than input", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("cf_version_maximum", CF_DATA_TYPE_CONTEXT, CFVERSION_ARGS, &FnCallVersionMaximum, "True if local CFEngine version is older than or equal to input", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("cf_version_before", CF_DATA_TYPE_CONTEXT, CFVERSION_ARGS, &FnCallVersionBefore, "True if local CFEngine version is older than input", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("cf_version_at", CF_DATA_TYPE_CONTEXT, CFVERSION_ARGS, &FnCallVersionAt, "True if local CFEngine version is the same as input", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("cf_version_between", CF_DATA_TYPE_CONTEXT, CFVERSIONBETWEEN_ARGS, &FnCallVersionBetween, "True if local CFEngine version is between two input versions (inclusive)", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("changedbefore", CF_DATA_TYPE_CONTEXT, CHANGEDBEFORE_ARGS, &FnCallIsChangedBefore, "True if arg1 was changed before arg2 (ctime)", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("classify", CF_DATA_TYPE_CONTEXT, CLASSIFY_ARGS, &FnCallClassify, "True if the canonicalization of the argument is a currently defined class", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("classmatch", CF_DATA_TYPE_CONTEXT, CLASSMATCH_ARGS, &FnCallClassesMatching, "True if the regular expression matches any currently defined class", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("classesmatching", CF_DATA_TYPE_STRING_LIST, CLASSMATCH_ARGS, &FnCallClassesMatching, "List the defined classes matching regex arg1 and tag regexes arg2,arg3,...", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("classfiltercsv", CF_DATA_TYPE_CONTAINER, CLASSFILTERCSV_ARGS, &FnCallClassFilterCsv, "Parse a CSV file and create data container filtered by defined classes", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("countclassesmatching", CF_DATA_TYPE_INT, CLASSMATCH_ARGS, &FnCallClassesMatching, "Count the number of defined classes matching regex arg1", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("countlinesmatching", CF_DATA_TYPE_INT, COUNTLINESMATCHING_ARGS, &FnCallCountLinesMatching, "Count the number of lines matching regex arg1 in file arg2", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("url_get", CF_DATA_TYPE_CONTAINER, CURL_ARGS, &FnCallUrlGet, "Retrieve the contents at a URL with libcurl", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("datastate", CF_DATA_TYPE_CONTAINER, DATASTATE_ARGS, &FnCallDatastate, "Construct a container of the variable and class state", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("difference", CF_DATA_TYPE_STRING_LIST, SETOP_ARGS, &FnCallSetop, "Returns all the unique elements of list or array or data container arg1 that are not in list or array or data container arg2", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("dirname", CF_DATA_TYPE_STRING, DIRNAME_ARGS, &FnCallDirname, "Return the parent directory name for given path", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("diskfree", CF_DATA_TYPE_INT, DISKFREE_ARGS, &FnCallDiskFree, "Return the free space (in KB) available on the directory's current partition (0 if not found)", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("escape", CF_DATA_TYPE_STRING, ESCAPE_ARGS, &FnCallEscape, "Escape regular expression characters in a string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("eval", CF_DATA_TYPE_STRING, EVAL_ARGS, &FnCallEval, "Evaluate a mathematical expression", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("every", CF_DATA_TYPE_CONTEXT, EVERY_SOME_NONE_ARGS, &FnCallEverySomeNone, "True if every element in the list or array or data container matches the given regular expression", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("execresult", CF_DATA_TYPE_STRING, EXECRESULT_ARGS, &FnCallExecResult, "Execute named command and assign output to variable", FNCALL_OPTION_CACHED | FNCALL_OPTION_VARARG | FNCALL_OPTION_UNSAFE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("execresult_as_data", CF_DATA_TYPE_CONTAINER, EXECRESULT_ARGS, &FnCallExecResult, "Execute command and return exit code and output in data container", FNCALL_OPTION_CACHED | FNCALL_OPTION_VARARG | FNCALL_OPTION_UNSAFE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("file_hash", CF_DATA_TYPE_STRING, FILE_HASH_ARGS, &FnCallHandlerHash, "Return the hash of file arg1, type arg2 and assign to a variable", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("expandrange", CF_DATA_TYPE_STRING_LIST, EXPANDRANGE_ARGS, &FnCallExpandRange, "Expand a name as a list of names numered according to a range", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("fileexists", CF_DATA_TYPE_CONTEXT, FILESTAT_ARGS, &FnCallFileStat, "True if the named file can be accessed", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("filesexist", CF_DATA_TYPE_CONTEXT, FILESEXIST_ARGS, &FnCallFileSexist, "True if the named list of files can ALL be accessed", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("filesize", CF_DATA_TYPE_INT, FILESTAT_ARGS, &FnCallFileStat, "Returns the size in bytes of the file", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("filestat", CF_DATA_TYPE_STRING, FILESTAT_DETAIL_ARGS, &FnCallFileStatDetails, "Returns stat() details of the file", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("filter", CF_DATA_TYPE_STRING_LIST, FILTER_ARGS, &FnCallFilter, "Similarly to grep(), filter the list or array or data container arg2 for matches to arg2. The matching can be as a regular expression or exactly depending on arg3. The matching can be inverted with arg4. A maximum on the number of matches returned can be set with arg5.", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("findfiles", CF_DATA_TYPE_STRING_LIST, FINDFILES_ARGS, &FnCallFindfiles, "Find files matching a shell glob pattern", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("findprocesses", CF_DATA_TYPE_CONTAINER, PROCESSEXISTS_ARGS, &FnCallProcessExists, "Returns data container of processes matching the regular expression", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("format", CF_DATA_TYPE_STRING, FORMAT_ARGS, &FnCallFormat, "Applies a list of string values in arg2,arg3... to a string format in arg1 with sprintf() rules", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getclassmetatags", CF_DATA_TYPE_STRING_LIST, GETCLASSMETATAGS_ARGS, &FnCallGetMetaTags, "Collect the class arg1's meta tags into an slist, optionally collecting only tag key arg2", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getenv", CF_DATA_TYPE_STRING, GETENV_ARGS, &FnCallGetEnv, "Return the environment variable named arg1, truncated at arg2 characters", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getfields", CF_DATA_TYPE_INT, GETFIELDS_ARGS, &FnCallGetFields, "Get an array of fields in the lines matching regex arg1 in file arg2, split on regex arg3 as array name arg4", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getgid", CF_DATA_TYPE_INT, GETGID_ARGS, &FnCallGetGid, "Return the integer group id of the named group on this host", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getindices", CF_DATA_TYPE_STRING_LIST, GETINDICES_ARGS, &FnCallGetIndices, "Get a list of keys to the list or array or data container whose id is the argument and assign to variable", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getuid", CF_DATA_TYPE_INT, GETUID_ARGS, &FnCallGetUid, "Return the integer user id of the named user on this host", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getusers", CF_DATA_TYPE_STRING_LIST, GETUSERS_ARGS, &FnCallGetUsers, "Get a list of all system users defined, minus those names defined in arg1 and uids in arg2", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getuserinfo", CF_DATA_TYPE_CONTAINER, GETUSERINFO_ARGS, &FnCallGetUserInfo, "Get a data container describing user arg1, defaulting to current user", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getvalues", CF_DATA_TYPE_STRING_LIST, GETINDICES_ARGS, &FnCallGetValues, "Get a list of values in the list or array or data container arg1", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("getvariablemetatags", CF_DATA_TYPE_STRING_LIST, GETVARIABLEMETATAGS_ARGS, &FnCallGetMetaTags, "Collect the variable arg1's meta tags into an slist, optionally collecting only tag key arg2", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("grep", CF_DATA_TYPE_STRING_LIST, GREP_ARGS, &FnCallGrep, "Extract the sub-list if items matching the regular expression in arg1 of the list or array or data container arg2", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("groupexists", CF_DATA_TYPE_CONTEXT, GROUPEXISTS_ARGS, &FnCallGroupExists, "True if group or numerical id exists on this host", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hash", CF_DATA_TYPE_STRING, HASH_ARGS, &FnCallHandlerHash, "Return the hash of arg1, type arg2 and assign to a variable", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hashmatch", CF_DATA_TYPE_CONTEXT, HASHMATCH_ARGS, &FnCallHashMatch, "Compute the hash of arg1, of type arg2 and test if it matches the value in arg3", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("host2ip", CF_DATA_TYPE_STRING, HOST2IP_ARGS, &FnCallHost2IP, "Returns the primary name-service IP address for the named host", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("ip2host", CF_DATA_TYPE_STRING, IP2HOST_ARGS, &FnCallIP2Host, "Returns the primary name-service host name for the IP address", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hostinnetgroup", CF_DATA_TYPE_CONTEXT, HOSTINNETGROUP_ARGS, &FnCallHostInNetgroup, "True if the current host is in the named netgroup", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hostrange", CF_DATA_TYPE_CONTEXT, HOSTRANGE_ARGS, &FnCallHostRange, "True if the current host lies in the range of enumerated hostnames specified", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hostsseen", CF_DATA_TYPE_STRING_LIST, HOSTSSEEN_ARGS, &FnCallHostsSeen, "Extract the list of hosts last seen/not seen within the last arg1 hours", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hostswithclass", CF_DATA_TYPE_STRING_LIST, HOSTSWITHCLASS_ARGS, &FnCallHostsWithClass, "Extract the list of hosts with the given class set from the hub database (enterprise extension)", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hubknowledge", CF_DATA_TYPE_STRING, HUB_KNOWLEDGE_ARGS, &FnCallHubKnowledge, "Read global knowledge from the hub host by id (enterprise extension)", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("ifelse", CF_DATA_TYPE_STRING, IFELSE_ARGS, &FnCallIfElse, "Do If-ElseIf-ElseIf-...-Else evaluation of arguments", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("int", CF_DATA_TYPE_INT, INT_ARGS, &FnCallInt, "Convert numeric string to int", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("intersection", CF_DATA_TYPE_STRING_LIST, SETOP_ARGS, &FnCallSetop, "Returns all the unique elements of list or array or data container arg1 that are also in list or array or data container arg2", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("iprange", CF_DATA_TYPE_CONTEXT, IPRANGE_ARGS, &FnCallIPRange, "True if the current host lies in the range of IP addresses specified in arg1 (can be narrowed to specific interfaces with arg2).", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isipinsubnet", CF_DATA_TYPE_CONTEXT, IPRANGE_ARGS, &FnCallIsIpInSubnet, "True if an IP address specified in arg2, arg3, ... lies in the range of IP addresses specified in arg1", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("irange", CF_DATA_TYPE_INT_RANGE, IRANGE_ARGS, &FnCallIRange, "Define a range of integer values for cfengine internal use", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isdir", CF_DATA_TYPE_CONTEXT, FILESTAT_ARGS, &FnCallFileStat, "True if the named object is a directory", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isexecutable", CF_DATA_TYPE_CONTEXT, FILESTAT_ARGS, &FnCallFileStat, "True if the named object has execution rights for the current user", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isgreaterthan", CF_DATA_TYPE_CONTEXT, ISGREATERTHAN_ARGS, &FnCallIsLessGreaterThan, "True if arg1 is numerically greater than arg2, else compare strings like strcmp", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("islessthan", CF_DATA_TYPE_CONTEXT, ISLESSTHAN_ARGS, &FnCallIsLessGreaterThan, "True if arg1 is numerically less than arg2, else compare strings like NOT strcmp", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("islink", CF_DATA_TYPE_CONTEXT, FILESTAT_ARGS, &FnCallFileStat, "True if the named object is a symbolic link", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isnewerthan", CF_DATA_TYPE_CONTEXT, ISNEWERTHAN_ARGS, &FnCallIsNewerThan, "True if arg1 is newer (modified later) than arg2 (mtime)", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isplain", CF_DATA_TYPE_CONTEXT, FILESTAT_ARGS, &FnCallFileStat, "True if the named object is a plain/regular file", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isvariable", CF_DATA_TYPE_CONTEXT, ISVARIABLE_ARGS, &FnCallIsVariable, "True if the named variable is defined", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("join", CF_DATA_TYPE_STRING, JOIN_ARGS, &FnCallJoin, "Join the items of list or array or data container arg2 into a string, using the conjunction in arg1", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("lastnode", CF_DATA_TYPE_STRING, LASTNODE_ARGS, &FnCallLastNode, "Extract the last of a separated string, e.g. filename from a path", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("laterthan", CF_DATA_TYPE_CONTEXT, LATERTHAN_ARGS, &FnCallLaterThan, "True if the current time is later than the given date", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("ldaparray", CF_DATA_TYPE_CONTEXT, LDAPARRAY_ARGS, &FnCallLDAPArray, "Extract all values from an ldap record", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("ldaplist", CF_DATA_TYPE_STRING_LIST, LDAPLIST_ARGS, &FnCallLDAPList, "Extract all named values from multiple ldap records", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("ldapvalue", CF_DATA_TYPE_STRING, LDAPVALUE_ARGS, &FnCallLDAPValue, "Extract the first matching named value from ldap", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("lsdir", CF_DATA_TYPE_STRING_LIST, LSDIRLIST_ARGS, &FnCallLsDir, "Return a list of files in a directory matching a regular expression", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("makerule", CF_DATA_TYPE_STRING, MAKERULE_ARGS, &FnCallMakerule, "True if the target file arg1 does not exist or a source file arg2 or the list or array or data container arg2 is newer", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("maparray", CF_DATA_TYPE_STRING_LIST, MAPARRAY_ARGS, &FnCallMapData, "Return a list with each element mapped from a list or array or data container by a pattern based on $(this.k) and $(this.v)", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("mapdata", CF_DATA_TYPE_CONTAINER, MAPDATA_ARGS, &FnCallMapData, "Return a data container with each element parsed from a JSON string applied to every key-value pair of the list or array or data container, given as $(this.k) and $(this.v)", FNCALL_OPTION_COLLECTING|FNCALL_OPTION_DELAYED_EVALUATION, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("maplist", CF_DATA_TYPE_STRING_LIST, MAPLIST_ARGS, &FnCallMapList, "Return a mapping of the list or array or data container with each element modified by a pattern based $(this)", FNCALL_OPTION_COLLECTING|FNCALL_OPTION_DELAYED_EVALUATION, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("mergedata", CF_DATA_TYPE_CONTAINER, MERGEDATA_ARGS, &FnCallMergeData, "Merge two or more items, each a list or array or data container", FNCALL_OPTION_COLLECTING|FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("none", CF_DATA_TYPE_CONTEXT, EVERY_SOME_NONE_ARGS, &FnCallEverySomeNone, "True if no element in the list or array or data container matches the given regular expression", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("not", CF_DATA_TYPE_CONTEXT, NOT_ARGS, &FnCallNot, "Calculate whether argument is false", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("now", CF_DATA_TYPE_INT, NOW_ARGS, &FnCallNow, "Convert the current time into system representation", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("nth", CF_DATA_TYPE_STRING, NTH_ARGS, &FnCallNth, "Get the element at arg2 in list or array or data container arg1", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("on", CF_DATA_TYPE_INT, DATE_ARGS, &FnCallOn, "Convert an exact date/time to an integer system representation", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("or", CF_DATA_TYPE_CONTEXT, OR_ARGS, &FnCallOr, "Calculate whether any argument evaluates to true", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("packagesmatching", CF_DATA_TYPE_CONTAINER, PACKAGESMATCHING_ARGS, &FnCallPackagesMatching, "List the installed packages (\"name,version,arch,manager\") matching regex arg1=name,arg2=version,arg3=arch,arg4=method", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("packageupdatesmatching", CF_DATA_TYPE_CONTAINER, PACKAGESMATCHING_ARGS, &FnCallPackagesMatching, "List the available patches (\"name,version,arch,manager\") matching regex arg1=name,arg2=version,arg3=arch,arg4=method. Enterprise only.", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("parseintarray", CF_DATA_TYPE_INT, PARSESTRINGARRAY_ARGS, &FnCallParseIntArray, "Read an array of integers from a string, indexing by first entry on line and sequentially within each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("parsejson", CF_DATA_TYPE_CONTAINER, PARSEJSON_ARGS, &FnCallParseJson, "Parse a JSON data container from a string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("parserealarray", CF_DATA_TYPE_INT, PARSESTRINGARRAY_ARGS, &FnCallParseRealArray, "Read an array of real numbers from a string, indexing by first entry on line and sequentially within each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("parsestringarray", CF_DATA_TYPE_INT, PARSESTRINGARRAY_ARGS, &FnCallParseStringArray, "Read an array of strings from a string, indexing by first word on line and sequentially within each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("parsestringarrayidx", CF_DATA_TYPE_INT, PARSESTRINGARRAY_ARGS, &FnCallParseStringArrayIndex, "Read an array of strings from a string, indexing by line number and sequentially within each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("parseyaml", CF_DATA_TYPE_CONTAINER, PARSEJSON_ARGS, &FnCallParseJson, "Parse a data container from a YAML string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("peers", CF_DATA_TYPE_STRING_LIST, PEERS_ARGS, &FnCallPeers, "Get a list of peers (not including ourself) from the partition to which we belong", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("peerleader", CF_DATA_TYPE_STRING, PEERLEADER_ARGS, &FnCallPeerLeader, "Get the assigned peer-leader of the partition to which we belong", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("peerleaders", CF_DATA_TYPE_STRING_LIST, PEERLEADERS_ARGS, &FnCallPeerLeaders, "Get a list of peer leaders from the named partitioning", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("processexists", CF_DATA_TYPE_CONTEXT, PROCESSEXISTS_ARGS, &FnCallProcessExists, "True if the regular expression matches a process", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("randomint", CF_DATA_TYPE_INT, RANDOMINT_ARGS, &FnCallRandomInt, "Generate a random integer between the given limits, excluding the upper", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("hash_to_int", CF_DATA_TYPE_INT, HASH_TO_INT_ARGS, &FnCallHashToInt, "Generate an integer in given range based on string hash", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string", CF_DATA_TYPE_STRING, STRING_ARGS, &FnCallString, "Convert argument to string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), // read functions for reading from file FnCallTypeNew("readdata", CF_DATA_TYPE_CONTAINER, READDATA_ARGS, &FnCallReadData, "Parse a YAML, JSON, CSV, etc. file and return a JSON data container with the contents", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readfile", CF_DATA_TYPE_STRING, READFILE_ARGS, &FnCallReadFile, "Read max number of bytes from named file and assign to variable", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readcsv", CF_DATA_TYPE_CONTAINER, READFILE_ARGS, &FnCallReadCsv, "Parse a CSV file and return a JSON data container with the contents", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readenvfile", CF_DATA_TYPE_CONTAINER, READFILE_ARGS, &FnCallReadEnvFile, "Parse a ENV-style file and return a JSON data container with the contents", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readjson", CF_DATA_TYPE_CONTAINER, READFILE_ARGS, &FnCallReadJson, "Read a JSON data container from a file", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readyaml", CF_DATA_TYPE_CONTAINER, READFILE_ARGS, &FnCallReadYaml, "Read a data container from a YAML file", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("read_module_protocol", CF_DATA_TYPE_CONTEXT, READMODULE_ARGS, &FnCallReadModuleProtocol, "Parse a file containing module protocol output (for cached modules)", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readintarray", CF_DATA_TYPE_INT, READSTRINGARRAY_ARGS, &FnCallReadIntArray, "Read an array of integers from a file, indexed by first entry on line and sequentially on each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readintlist", CF_DATA_TYPE_INT_LIST, READSTRINGLIST_ARGS, &FnCallReadIntList, "Read and assign a list variable from a file of separated ints", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readrealarray", CF_DATA_TYPE_INT, READSTRINGARRAY_ARGS, &FnCallReadRealArray, "Read an array of real numbers from a file, indexed by first entry on line and sequentially on each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readreallist", CF_DATA_TYPE_REAL_LIST, READSTRINGLIST_ARGS, &FnCallReadRealList, "Read and assign a list variable from a file of separated real numbers", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readstringarray", CF_DATA_TYPE_INT, READSTRINGARRAY_ARGS, &FnCallReadStringArray, "Read an array of strings from a file, indexed by first entry on line and sequentially on each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readstringarrayidx", CF_DATA_TYPE_INT, READSTRINGARRAY_ARGS, &FnCallReadStringArrayIndex, "Read an array of strings from a file, indexed by line number and sequentially on each line; return line count", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readstringlist", CF_DATA_TYPE_STRING_LIST, READSTRINGLIST_ARGS, &FnCallReadStringList, "Read and assign a list variable from a file of separated strings", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("readtcp", CF_DATA_TYPE_STRING, READTCP_ARGS, &FnCallReadTcp, "Connect to tcp port, send string and assign result to variable", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), // reg functions for regex FnCallTypeNew("regarray", CF_DATA_TYPE_CONTEXT, REGARRAY_ARGS, &FnCallRegList, "True if the regular expression in arg1 matches any item in the list or array or data container arg2", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("regcmp", CF_DATA_TYPE_CONTEXT, REGCMP_ARGS, &FnCallRegCmp, "True if arg1 is a regular expression matching that matches string arg2", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("regextract", CF_DATA_TYPE_CONTEXT, REGEXTRACT_ARGS, &FnCallRegExtract, "True if the regular expression in arg 1 matches the string in arg2 and sets a non-empty array of backreferences named arg3", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("registryvalue", CF_DATA_TYPE_STRING, REGISTRYVALUE_ARGS, &FnCallRegistryValue, "Returns a value for an MS-Win registry key,value pair", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("regline", CF_DATA_TYPE_CONTEXT, REGLINE_ARGS, &FnCallRegLine, "True if the regular expression in arg1 matches a line in file arg2", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("reglist", CF_DATA_TYPE_CONTEXT, REGLIST_ARGS, &FnCallRegList, "True if the regular expression in arg2 matches any item in the list or array or data container whose id is arg1", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("regldap", CF_DATA_TYPE_CONTEXT, REGLDAP_ARGS, &FnCallRegLDAP, "True if the regular expression in arg6 matches a value item in an ldap search", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("remotescalar", CF_DATA_TYPE_STRING, REMOTESCALAR_ARGS, &FnCallRemoteScalar, "Read a scalar value from a remote cfengine server", FNCALL_OPTION_CACHED, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("remoteclassesmatching", CF_DATA_TYPE_CONTEXT, REMOTECLASSESMATCHING_ARGS, &FnCallRemoteClassesMatching, "Read persistent classes matching a regular expression from a remote cfengine server and add them into local context with prefix", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("returnszero", CF_DATA_TYPE_CONTEXT, RETURNSZERO_ARGS, &FnCallReturnsZero, "True if named shell command has exit status zero", FNCALL_OPTION_CACHED | FNCALL_OPTION_UNSAFE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("rrange", CF_DATA_TYPE_REAL_RANGE, RRANGE_ARGS, &FnCallRRange, "Define a range of real numbers for cfengine internal use", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("reverse", CF_DATA_TYPE_STRING_LIST, REVERSE_ARGS, &FnCallReverse, "Reverse a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("selectservers", CF_DATA_TYPE_INT, SELECTSERVERS_ARGS, &FnCallSelectServers, "Select tcp servers which respond correctly to a query and return their number, set array of names", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("shuffle", CF_DATA_TYPE_STRING_LIST, SHUFFLE_ARGS, &FnCallShuffle, "Shuffle the items in a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("some", CF_DATA_TYPE_CONTEXT, EVERY_SOME_NONE_ARGS, &FnCallEverySomeNone, "True if an element in the list or array or data container matches the given regular expression", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("sort", CF_DATA_TYPE_STRING_LIST, SORT_ARGS, &FnCallSort, "Sort a list or array or data container", FNCALL_OPTION_COLLECTING | FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("splayclass", CF_DATA_TYPE_CONTEXT, SPLAYCLASS_ARGS, &FnCallSplayClass, "True if the first argument's time-slot has arrived, according to a policy in arg2", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("splitstring", CF_DATA_TYPE_STRING_LIST, SPLITSTRING_ARGS, &FnCallSplitString, "Convert a string in arg1 into a list of max arg3 strings by splitting on a regular expression in arg2", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_DEPRECATED), FnCallTypeNew("storejson", CF_DATA_TYPE_STRING, STOREJSON_ARGS, &FnCallStoreJson, "Convert a list or array or data container to a JSON string", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("strcmp", CF_DATA_TYPE_CONTEXT, STRCMP_ARGS, &FnCallStrCmp, "True if the two strings match exactly", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("strftime", CF_DATA_TYPE_STRING, STRFTIME_ARGS, &FnCallStrftime, "Format a date and time string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("sublist", CF_DATA_TYPE_STRING_LIST, SUBLIST_ARGS, &FnCallSublist, "Returns arg3 element from either the head or the tail (according to arg2) of list or array or data container arg1.", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("sysctlvalue", CF_DATA_TYPE_STRING, SYSCTLVALUE_ARGS, &FnCallSysctlValue, "Returns a value for sysctl key arg1 pair", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("data_sysctlvalues", CF_DATA_TYPE_CONTAINER, DATA_SYSCTLVALUES_ARGS, &FnCallSysctlValue, "Returns a data container map of all the sysctl key,value pairs", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("translatepath", CF_DATA_TYPE_STRING, TRANSLATEPATH_ARGS, &FnCallTranslatePath, "Translate path separators from Unix style to the host's native", FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("unique", CF_DATA_TYPE_STRING_LIST, UNIQUE_ARGS, &FnCallSetop, "Returns all the unique elements of list or array or data container arg1", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("usemodule", CF_DATA_TYPE_CONTEXT, USEMODULE_ARGS, &FnCallUseModule, "Execute cfengine module script and set class if successful", FNCALL_OPTION_NONE | FNCALL_OPTION_UNSAFE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), FnCallTypeNew("userexists", CF_DATA_TYPE_CONTEXT, USEREXISTS_ARGS, &FnCallUserExists, "True if user name or numerical id exists on this host", FNCALL_OPTION_NONE, FNCALL_CATEGORY_SYSTEM, SYNTAX_STATUS_NORMAL), FnCallTypeNew("validdata", CF_DATA_TYPE_CONTEXT, VALIDDATA_ARGS, &FnCallValidData, "Check for errors in JSON or YAML data", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("validjson", CF_DATA_TYPE_CONTEXT, VALIDDATATYPE_ARGS, &FnCallValidJson, "Check for errors in JSON data", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("variablesmatching", CF_DATA_TYPE_STRING_LIST, CLASSMATCH_ARGS, &FnCallVariablesMatching, "List the variables matching regex arg1 and tag regexes arg2,arg3,...", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("version_compare", CF_DATA_TYPE_CONTEXT, VERSION_COMPARE_ARGS, &FnCallVersionCompare, "Compare two version numbers with a specified operator", FNCALL_OPTION_NONE, FNCALL_CATEGORY_UTILS, SYNTAX_STATUS_NORMAL), // Functions section following new naming convention FnCallTypeNew("string_mustache", CF_DATA_TYPE_STRING, STRING_MUSTACHE_ARGS, &FnCallStringMustache, "Expand a Mustache template from arg1 into a string using the optional data container in arg2 or datastate()", FNCALL_OPTION_COLLECTING|FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_split", CF_DATA_TYPE_STRING_LIST, SPLITSTRING_ARGS, &FnCallStringSplit, "Convert a string in arg1 into a list of at most arg3 strings by splitting on a regular expression in arg2", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_replace", CF_DATA_TYPE_STRING, STRING_REPLACE_ARGS, &FnCallStringReplace, "Search through arg1, replacing occurences of arg2 with arg3.", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_trim", CF_DATA_TYPE_STRING, STRING_TRIM_ARGS, &FnCallStringTrim, "Trim whitespace from beginning and end of string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("regex_replace", CF_DATA_TYPE_STRING, REGEX_REPLACE_ARGS, &FnCallRegReplace, "Replace occurrences of arg1 in arg2 with arg3, allowing backreferences. Perl-style options accepted in arg4.", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), // Text xform functions FnCallTypeNew("string_downcase", CF_DATA_TYPE_STRING, XFORM_ARGS, &FnCallTextXform, "Convert a string to lowercase", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_head", CF_DATA_TYPE_STRING, XFORM_SUBSTR_ARGS, &FnCallTextXform, "Extract characters from the head of the string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_reverse", CF_DATA_TYPE_STRING, XFORM_ARGS, &FnCallTextXform, "Reverse a string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_length", CF_DATA_TYPE_INT, XFORM_ARGS, &FnCallTextXform, "Return the length of a string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_tail", CF_DATA_TYPE_STRING, XFORM_SUBSTR_ARGS, &FnCallTextXform, "Extract characters from the tail of the string", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("string_upcase", CF_DATA_TYPE_STRING, XFORM_ARGS, &FnCallTextXform, "Convert a string to UPPERCASE", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), // List folding functions FnCallTypeNew("length", CF_DATA_TYPE_INT, STAT_FOLD_ARGS, &FnCallLength, "Return the length of a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("max", CF_DATA_TYPE_STRING, SORT_ARGS, &FnCallFold, "Return the maximum value in a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("mean", CF_DATA_TYPE_REAL, STAT_FOLD_ARGS, &FnCallFold, "Return the mean (average) in a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("min", CF_DATA_TYPE_STRING, SORT_ARGS, &FnCallFold, "Return the minimum in a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("product", CF_DATA_TYPE_REAL, PRODUCT_ARGS, &FnCallFold, "Return the product of a list or array or data container of reals", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("sum", CF_DATA_TYPE_REAL, SUM_ARGS, &FnCallFold, "Return the sum of a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("variance", CF_DATA_TYPE_REAL, STAT_FOLD_ARGS, &FnCallFold, "Return the variance of a list or array or data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), // CFEngine internal functions FnCallTypeNew("callstack_promisers", CF_DATA_TYPE_STRING_LIST, CFENGINE_PROMISERS_ARGS, &FnCallCFEngineCallers, "Get the list of promisers to the current promise execution path", FNCALL_OPTION_NONE, FNCALL_CATEGORY_INTERNAL, SYNTAX_STATUS_NORMAL), FnCallTypeNew("callstack_callers", CF_DATA_TYPE_CONTAINER, CFENGINE_CALLERS_ARGS, &FnCallCFEngineCallers, "Get the current promise execution stack in detail", FNCALL_OPTION_NONE, FNCALL_CATEGORY_INTERNAL, SYNTAX_STATUS_NORMAL), // Data container functions FnCallTypeNew("data_regextract", CF_DATA_TYPE_CONTAINER, DATA_REGEXTRACT_ARGS, &FnCallRegExtract, "Matches the regular expression in arg 1 against the string in arg2 and returns a data container holding the backreferences by name", FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("data_expand", CF_DATA_TYPE_CONTAINER, DATA_EXPAND_ARGS, &FnCallDataExpand, "Expands any CFEngine variables in a list or array or data container, converting to a data container", FNCALL_OPTION_COLLECTING, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNew("variablesmatching_as_data", CF_DATA_TYPE_CONTAINER, CLASSMATCH_ARGS, &FnCallVariablesMatching, "Capture the variables matching regex arg1 and tag regexes arg2,arg3,... with their data", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), // File parsing functions that output a data container FnCallTypeNew("data_readstringarray", CF_DATA_TYPE_CONTAINER, DATA_READSTRINGARRAY_ARGS, &FnCallDataRead, "Read an array of strings from a file into a data container map, using the first element as a key", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), FnCallTypeNew("data_readstringarrayidx", CF_DATA_TYPE_CONTAINER, DATA_READSTRINGARRAY_ARGS, &FnCallDataRead, "Read an array of strings from a file into a data container array", FNCALL_OPTION_NONE, FNCALL_CATEGORY_IO, SYNTAX_STATUS_NORMAL), // Network probe functions FnCallTypeNew("network_connections", CF_DATA_TYPE_CONTAINER, NETWORK_CONNECTIONS_ARGS, &FnCallNetworkConnections, "Get the full list of TCP, TCP6, UDP, and UDP6 connections from /proc/net", FNCALL_OPTION_NONE, FNCALL_CATEGORY_COMM, SYNTAX_STATUS_NORMAL), // Files functions FnCallTypeNew("findfiles_up", CF_DATA_TYPE_CONTAINER, FINDFILES_UP_ARGS, &FnCallFindfilesUp, "Find files matching a glob pattern by searching up the directory three from a given point in the tree structure", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("search_up", CF_DATA_TYPE_CONTAINER, FINDFILES_UP_ARGS, &FnCallFindfilesUp, "Hush... This is a super secret alias name for function 'findfiles_up'", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), FnCallTypeNew("isreadable", CF_DATA_TYPE_CONTEXT, ISREADABLE_ARGS, &FnCallIsReadable, "Check if file is readable. Timeout immediately or after optional timeout interval", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL), // Datatype functions FnCallTypeNew("type", CF_DATA_TYPE_STRING, DATATYPE_ARGS, &FnCallDatatype, "Get type description as string", FNCALL_OPTION_VARARG, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL), FnCallTypeNewNull() }; #endif // CFENGINE_EVALFUNCTION_TEST_C cfengine-3.24.2/libpromises/dbm_priv.h0000644000000000000000000000615515010704253017665 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DBM_PRIV_H #define CFENGINE_DBM_PRIV_H #include /* DBM implementation is supposed to define the following structures and * implement the following functions */ typedef struct DBPriv_ DBPriv; typedef struct DBCursorPriv_ DBCursorPriv; const char *DBPrivGetFileExtension(void); #define DB_PRIV_DATABASE_BROKEN ((DBPriv *)-1) void DBPrivSetMaximumConcurrentTransactions(int max_txn); /* * These two functions will always be called with a per-database lock held. */ /* * Should return either * - NULL in case of generic error * - DB_PRIV_DATABASE_BROKEN in case database file is broken, need to be moved away and attempt to open database again should be performed. * - valid pointer to DBPriv * in case database was opened successfully. */ DBPriv *DBPrivOpenDB(const char *dbpath, dbid id); void DBPrivCloseDB(DBPriv *hdbp); void DBPrivCommit(DBPriv *hdbp); bool DBPrivClean(DBPriv *hdbp); int DBPrivGetDBUsagePercentage(const char *db_path); bool DBPrivHasKey(DBPriv *db, const void *key, int key_size); int DBPrivGetValueSize(DBPriv *db, const void *key, int key_size); bool DBPrivRead(DBPriv *db, const void *key, int key_size, void *dest, size_t dest_size); bool DBPrivWrite(DBPriv *db, const void *key, int key_size, const void *value, int value_size); bool DBPrivOverwrite(DBPriv *handle, const char *key, int key_size, const void *value, size_t value_size, OverwriteCondition Condition, void *data); bool DBPrivDelete(DBPriv *db, const void *key, int key_size); DBCursorPriv *DBPrivOpenCursor(DBPriv *db); bool DBPrivAdvanceCursor(DBCursorPriv *cursor, void **key, int *key_size, void **value, int *value_size); bool DBPrivDeleteCursorEntry(DBCursorPriv *cursor); bool DBPrivWriteCursorEntry(DBCursorPriv *cursor, const void *value, int value_size); void DBPrivCloseCursor(DBCursorPriv *cursor); /** * @brief Check a database file for consistency * @param dbpath Path to database file * @return NULL if successful, else an error string that must be freed */ char *DBPrivDiagnose(const char *dbpath); #endif cfengine-3.24.2/libpromises/enterprise_stubs.c0000644000000000000000000001623715010704253021460 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include // StringCopy() #include /* * This module contains numeruous functions which don't use all their parameters * * Temporarily, in order to avoid cluttering output with thousands of warnings, * this module is excempted from producing warnings about unused function * parameters. * * Please remove this #pragma ASAP and provide ARG_UNUSED declarations for * unused parameters. */ #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-parameter" #endif extern int PR_KEPT; extern int PR_REPAIRED; extern int PR_NOTKEPT; ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, Nova_Initialize, EvalContext *, ctx) { } /* all agents: generic_agent.c */ ENTERPRISE_FUNC_0ARG_DEFINE_STUB(const char *, GetConsolePrefix) { return "cf3"; } /* all agents: sysinfo.c */ ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, EnterpriseContext, ARG_UNUSED EvalContext *, ctx) { } /* all agents: logging.c */ ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, LogTotalCompliance, const char *, version, int, background_tasks) { double total = (double) (PR_KEPT + PR_NOTKEPT + PR_REPAIRED) / 100.0; char string[CF_BUFSIZE] = { 0 }; snprintf(string, CF_BUFSIZE, "Outcome of version %s (" CF_AGENTC "-%d): Promises observed to be kept %.2f%%, Promises repaired %.2f%%, Promises not repaired %.2f%%", version, background_tasks, (double) PR_KEPT / total, (double) PR_REPAIRED / total, (double) PR_NOTKEPT / total); Log(LOG_LEVEL_VERBOSE, "Logging total compliance, total '%s'", string); char filename[CF_BUFSIZE]; snprintf(filename, CF_BUFSIZE, "%s/%s", GetLogDir(), CF_PROMISE_LOG); MapName(filename); FILE *fout = safe_fopen(filename, "a"); if (fout == NULL) { Log(LOG_LEVEL_ERR, "In total compliance logging, could not open file '%s'. (fopen: %s)", filename, GetErrorStr()); } else { fprintf(fout, "%jd,%jd: %s\n", (intmax_t)CFSTARTTIME, (intmax_t)time(NULL), string); fclose(fout); } } /* network communication: cf-serverd.c, client_protocol.c, client_code.c, crypto.c */ ENTERPRISE_FUNC_1ARG_DEFINE_STUB(int, CfSessionKeySize, char, type) { return CF_BLOWFISHSIZE; } ENTERPRISE_FUNC_0ARG_DEFINE_STUB(char, CfEnterpriseOptions) { return 'c'; } ENTERPRISE_FUNC_1ARG_DEFINE_STUB(const EVP_CIPHER *, CfengineCipher, char, type) { return EVP_bf_cbc(); } /* cf-agent: evalfunction.c */ ENTERPRISE_FUNC_6ARG_DEFINE_STUB(char *, GetRemoteScalar, EvalContext *, ctx, char *, proto, char *, handle, const char *, server, int, encrypted, char *, rcv) { Log(LOG_LEVEL_VERBOSE, "Access to server literals is only available in CFEngine Enterprise"); return ""; } ENTERPRISE_VOID_FUNC_3ARG_DEFINE_STUB(void, CacheUnreliableValue, char *, caller, char *, handle, char *, buffer) { Log(LOG_LEVEL_VERBOSE, "Value fault-tolerance only available in CFEngine Enterprise"); } ENTERPRISE_FUNC_3ARG_DEFINE_STUB(int, RetrieveUnreliableValue, char *, caller, char *, handle, char *, buffer) { Log(LOG_LEVEL_VERBOSE, "Value fault-tolerance only available in CFEngine Enterprise"); return 0; // enterprise version returns strlen(buffer) or 0 for error } #if defined(__MINGW32__) ENTERPRISE_FUNC_4ARG_DEFINE_STUB(bool, GetRegistryValue, char *, key, char *, name, char *, buf, int, bufSz) { return 0; } #endif ENTERPRISE_FUNC_6ARG_DEFINE_STUB(void *, CfLDAPValue, char *, uri, char *, dn, char *, filter, char *, name, char *, scope, char *, sec) { Log(LOG_LEVEL_ERR, "LDAP support only available in CFEngine Enterprise"); return NULL; } ENTERPRISE_FUNC_6ARG_DEFINE_STUB(void *, CfLDAPList, char *, uri, char *, dn, char *, filter, char *, name, char *, scope, char *, sec) { Log(LOG_LEVEL_ERR, "LDAP support only available in CFEngine Enterprise"); return NULL; } ENTERPRISE_FUNC_8ARG_DEFINE_STUB(void *, CfLDAPArray, EvalContext *, ctx, const Bundle *, caller, char *, array, char *, uri, char *, dn, char *, filter, char *, scope, char *, sec) { Log(LOG_LEVEL_ERR, "LDAP support only available in CFEngine Enterprise"); return NULL; } ENTERPRISE_FUNC_8ARG_DEFINE_STUB(void *, CfRegLDAP, EvalContext *, ctx, char *, uri, char *, dn, char *, filter, char *, name, char *, scope, char *, regex, char *, sec) { Log(LOG_LEVEL_ERR, "LDAP support only available in CFEngine Enterprise"); return NULL; } ENTERPRISE_FUNC_4ARG_DEFINE_STUB(bool, ListHostsWithClass, EvalContext *, ctx, Rlist **, return_list, char *, class_name, char *, return_format) { Log(LOG_LEVEL_ERR, "Host class counting is only available in CFEngine Enterprise"); return false; } /* cf-serverd: server_transform.c, cf-serverd.c */ ENTERPRISE_FUNC_3ARG_DEFINE_STUB(bool, TranslatePath, const char *, from, char *, to, size_t, to_size) { const size_t length = StringCopy(from, to, to_size); if (length >= to_size) { Log(LOG_LEVEL_ERR, "File name was too long and got truncated: '%s'", to); return false; } return true; } ENTERPRISE_VOID_FUNC_3ARG_DEFINE_STUB(void, EvalContextLogPromiseIterationOutcome, ARG_UNUSED EvalContext *, ctx, ARG_UNUSED const Promise *, pp, ARG_UNUSED PromiseResult, result) { } ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, CheckAndSetHAState, ARG_UNUSED const char *, workdir, ARG_UNUSED EvalContext *, ctx) { } ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(void, ReloadHAConfig) { } ENTERPRISE_FUNC_0ARG_DEFINE_STUB(size_t, EnterpriseGetMaxCfHubProcesses) { return 0; } ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, Nova_ClassHistoryAddContextName, ARG_UNUSED const StringSet *, list, ARG_UNUSED const char *, context_name) { } ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, Nova_ClassHistoryEnable, ARG_UNUSED StringSet **, list, ARG_UNUSED bool, enable) { } cfengine-3.24.2/libpromises/extensions.h0000644000000000000000000000246115010704253020256 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #ifdef BUILTIN_EXTENSIONS // No effect if using builtin extensions. static inline void extension_libraries_disable() { } #else // !BUILTIN_EXTENSIONS void extension_libraries_disable(); void *extension_library_open(const char *name); void extension_library_close(void *handle); #endif // !BUILTIN_EXTENSIONS cfengine-3.24.2/libpromises/conversion.h0000644000000000000000000000736115010704253020250 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CONVERSION_H #define CFENGINE_CONVERSION_H #include // Type-String conversion MeasurePolicy MeasurePolicyFromString(const char *s); EnvironmentState EnvironmentStateFromString(const char *s); InsertMatchType InsertMatchTypeFromString(const char *s); Interval IntervalFromString(const char *s); DatabaseType DatabaseTypeFromString(const char *s); UserState UserStateFromString(const char *s); PasswordFormat PasswordFormatFromString(const char *s); ContextScope ContextScopeFromString(const char *scope_str); FileComparator FileComparatorFromString(const char *s); FileLinkType FileLinkTypeFromString(const char *s); DataType DataTypeFromString(const char *name); const char *DataTypeToString(DataType dtype); PackageActionPolicy PackageActionPolicyFromString(const char *s); PackageVersionComparator PackageVersionComparatorFromString(const char *s); PackageAction PackageActionFromString(const char *s); NewPackageAction GetNewPackagePolicy(const char *s, const char **action_types); AclMethod AclMethodFromString(const char *string); AclType AclTypeFromString(const char *string); AclDefault AclDefaultFromString(const char *string); AclInherit AclInheritFromString(const char *string); int SignalFromString(const char *s); int SyslogPriorityFromString(const char *s); ShellType ShellTypeFromString(const char *s); // Date/Time conversion void TimeToDateStr(time_t t, char *outStr, int outStrSz); int Month2Int(const char *string); // Evalaution conversion bool BooleanFromString(const char *val); bool StringIsBoolean(const char *val); long IntFromString(const char *s); bool DoubleFromString(const char *s, double *value_out); bool IntegerRangeFromString(const char *intrange, long *min_out, long *max_out); bool IsRealNumber(const char *s); // Misc. char *Rlist2String(Rlist *list, char *sep); // TODO: Yet another Rlist serialization scheme.. Found 5 so far. DataType ConstraintSyntaxGetDataType(const ConstraintSyntax *body_syntax, const char *lval); const char *MapAddress(const char *addr); const char *CommandArg0(const char *execstr); size_t CommandArg0_bound(char *dst, const char *src, size_t dst_size); void CommandPrefix(char *execstr, char *comm); const char *DataTypeShortToType(char *short_type); bool DataTypeIsIterable(DataType t); bool CoarseLaterThan(const char *key, const char *from); int FindTypeInArray(const char *const haystack[], const char *needle, int default_value, int null_value); void UidListDestroy(UidList *uids); void GidListDestroy(GidList *gids); UidList *Rlist2UidList(Rlist *uidnames, const Promise *pp); GidList *Rlist2GidList(Rlist *gidnames, const Promise *pp); #ifndef __MINGW32__ uid_t Str2Uid(const char *uidbuff, char *copy, const Promise *pp); gid_t Str2Gid(const char *gidbuff, char *copy, const Promise *pp); #endif /* !__MINGW32__ */ #endif cfengine-3.24.2/libpromises/process_freebsd.c0000644000000000000000000000520115010704253021215 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include typedef struct { time_t starttime; char state; } ProcessStat; static bool GetProcessStat(pid_t pid, ProcessStat *state) { int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; struct kinfo_proc psinfo; size_t len = sizeof(psinfo); if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &psinfo, &len, NULL, 0) == 0) { state->starttime = psinfo.ki_start.tv_sec; switch(psinfo.ki_stat) { case SRUN: case SIDL: state->state = 'R'; break; case SSTOP: state->state = 'T'; break; case SSLEEP: state->state = 'S'; break; case SZOMB: state->state = 'Z'; break; default: state->state = 'X'; } } else { return false; } return true; } time_t GetProcessStartTime(pid_t pid) { ProcessStat st; if (GetProcessStat(pid, &st)) { return st.starttime; } else { return PROCESS_START_TIME_UNKNOWN; } } ProcessState GetProcessState(pid_t pid) { ProcessStat st; if (GetProcessStat(pid, &st)) { switch (st.state) { case 'T': return PROCESS_STATE_STOPPED; case 'Z': return PROCESS_STATE_ZOMBIE; default: return PROCESS_STATE_RUNNING; } } else { return PROCESS_STATE_DOES_NOT_EXIST; } } cfengine-3.24.2/libpromises/storage_tools.c0000644000000000000000000000714015010704253020735 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #ifdef HAVE_SYS_STATFS_H # include #endif #ifdef HAVE_SYS_VFS_H # include #endif #ifdef HAVE_SYS_STATVFS_H # include #endif /************************************************************************/ #ifndef __MINGW32__ off_t GetDiskUsage(char *file, CfSize type) { # if defined __sun || defined sco || defined __OpenBSD__ || (defined(__NetBSD__) && __NetBSD_Version__ >= 200040000) struct statvfs buf; # else struct statfs buf; # endif int64_t used = 0, avail = 0; int capacity = 0; memset(&buf, 0, sizeof(buf)); # if defined __sun || defined sco || defined __OpenBSD__ || (defined(__NetBSD__) && __NetBSD_Version__ >= 200040000) if (statvfs(file, &buf) != 0) { Log(LOG_LEVEL_ERR, "Couldn't get filesystem info for %s (statvfs)", file); return CF_INFINITY; } # elif defined __SCO_DS || defined _CRAY || (defined(__NetBSD__) && __NetBSD_Version__ >= 200040000) if (statfs(file, &buf, sizeof(struct statfs), 0) != 0) { Log(LOG_LEVEL_ERR, "Couldn't get filesystem info for %s (statfs)", file); return CF_INFINITY; } # else if (statfs(file, &buf) != 0) { Log(LOG_LEVEL_ERR, "Couldn't get filesystem info for '%s'. (statfs: %s)", file, GetErrorStr()); return CF_INFINITY; } # endif # if defined __sun used = (buf.f_blocks - buf.f_bfree) * (int64_t)buf.f_frsize; avail = buf.f_bavail * (int64_t)buf.f_frsize; # endif # if defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __hpux || defined __APPLE__ used = (buf.f_blocks - buf.f_bfree) * (int64_t)buf.f_bsize; avail = buf.f_bavail * (int64_t)buf.f_bsize; # endif # if defined _AIX || defined __SCO_DS || defined _CRAY used = (buf.f_blocks - buf.f_bfree) * (int64_t)buf.f_bsize; avail = buf.f_bfree * (int64_t)buf.f_bsize; # endif # if defined __linux__ used = (buf.f_blocks - buf.f_bfree) * (int64_t)buf.f_bsize; avail = buf.f_bavail * (int64_t)buf.f_bsize; # endif capacity = (double) (avail) / (double) (avail + used) * 100; Log(LOG_LEVEL_DEBUG, "GetDiskUsage(%s) = %jd/%jd", file, (intmax_t) avail, (intmax_t) capacity); if (type == CF_SIZE_ABS) { // TODO: This should be handled better by actually returning a bigger // data type, but for now just protect against overflow by hitting the // ceiling. if (sizeof(off_t) < sizeof(int64_t) && avail > 0x7fffffffLL) { return 0x7fffffff; } else { return avail; } } else { return capacity; } } #endif /* __MINGW32__ */ cfengine-3.24.2/libpromises/attributes.h0000644000000000000000000001205415010704253020244 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ATTRIBUTES_H #define CFENGINE_ATTRIBUTES_H #include LogLevel ActionAttributeLogLevelFromString(const char *log_level); bool IsClassesBodyConstraint(const char *constraint); Attributes GetClassContextAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetColumnAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetDatabaseAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetDeletionAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetEnvironmentsAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetExecAttributes(const EvalContext *ctx, const Promise *pp); void ClearFilesAttributes(Attributes *whom); /* Every return from GetFilesAttributes() must be passed to * ClearFilesAttributes() when you're done with it. */ Attributes GetFilesAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetInferencesAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetInsertionAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetMeasurementAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetMethodAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetOccurrenceAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetPackageAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetUserAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetProcessAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetReplaceAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetReportsAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetServicesAttributes(const EvalContext *ctx, const Promise *pp); Attributes GetStorageAttributes(const EvalContext *ctx, const Promise *pp); Acl GetAclConstraints(const EvalContext *ctx, const Promise *pp); ContextConstraint GetContextConstraints(const EvalContext *ctx, const Promise *pp); Database GetDatabaseConstraints(const EvalContext *ctx, const Promise *pp); DefineClasses GetClassDefinitionConstraints(const EvalContext *ctx, const Promise *pp); EditColumn GetColumnConstraints(const EvalContext *ctx, const Promise *pp); EditDefaults GetEditDefaults(const EvalContext *ctx, const Promise *pp); EditLocation GetLocationAttributes(const Promise *pp); EditXml GetXmlConstraints(const Promise *pp); EditRegion GetRegionConstraints(const EvalContext *ctx, const Promise *pp); EditReplace GetReplaceConstraints(const Promise *pp); Environments GetEnvironmentsConstraints(const EvalContext *ctx, const Promise *pp); ExecContain GetExecContainConstraints(const EvalContext *ctx, const Promise *pp); ENTERPRISE_FUNC_0ARG_DECLARE(HashMethod, GetBestFileChangeHashMethod); FileChange GetChangeMgtConstraints(const EvalContext *ctx, const Promise *pp); FileCopy GetCopyConstraints(const EvalContext *ctx, const Promise *pp); FileDelete GetDeleteConstraints(const EvalContext *ctx, const Promise *pp); FileLink GetLinkConstraints(const EvalContext *ctx, const Promise *pp); FileRename GetRenameConstraints(const EvalContext *ctx, const Promise *pp); FileSelect GetSelectConstraints(const EvalContext *ctx, const Promise *pp); LineSelect GetDeleteSelectConstraints(const EvalContext *ctx, const Promise *pp); LineSelect GetInsertSelectConstraints(const EvalContext *ctx, const Promise *pp); Measurement GetMeasurementConstraint(const EvalContext *ctx, const Promise *pp); Packages GetPackageConstraints(const EvalContext *ctx, const Promise *pp); NewPackages GetNewPackageConstraints(const EvalContext *ctx, const Promise *pp); ProcessCount GetMatchesConstraints(const EvalContext *ctx, const Promise *pp); ProcessSelect GetProcessFilterConstraints(const EvalContext *ctx, const Promise *pp); DirectoryRecursion GetRecursionConstraints(const EvalContext *ctx, const Promise *pp); Report GetReportConstraints(const EvalContext *ctx, const Promise *pp); Services GetServicesConstraints(const EvalContext *ctx, const Promise *pp); StorageMount GetMountConstraints(const EvalContext *ctx, const Promise *pp); StorageVolume GetVolumeConstraints(const EvalContext *ctx, const Promise *pp); #endif cfengine-3.24.2/libpromises/var_expressions.c0000644000000000000000000003432315010704253021306 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include // This is not allowed to be the part of VarRef.indices so looks safe // to be used as multi array indices separator while hashing. #define ARRAY_SEPARATOR_HASH ']' static unsigned VarRefHash(const VarRef *ref) { unsigned int h = 0; if (VarRefIsQualified(ref)) { if (ref->ns) { for (int i = 0; ref->ns[i] != '\0'; i++) { h += ref->ns[i]; h += (h << 10); h ^= (h >> 6); } } else { h = 1195645448; // hash of "default" } int len = strlen(ref->scope); for (int i = 0; i < len; i++) { h += ref->scope[i]; h += (h << 10); h ^= (h >> 6); } } for (int i = 0; ref->lval[i] != '\0'; i++) { h += ref->lval[i]; h += (h << 10); h ^= (h >> 6); } for (size_t k = 0; k < ref->num_indices; k++) { // Fixing multi index arrays hashing collisions - Redmine 6674 // Multi index arrays with indexes expanded to the same string // (e.g. v[te][st], v[t][e][s][t]) will not be hashed to the same value. h += ARRAY_SEPARATOR_HASH; h += (h << 10); h ^= (h >> 6); for (int i = 0; ref->indices[k][i] != '\0'; i++) { h += ref->indices[k][i]; h += (h << 10); h ^= (h >> 6); } } h += (h << 3); h ^= (h >> 11); h += (h << 15); return h; } unsigned int VarRefHash_untyped(const void *ref, unsigned int seed ARG_UNUSED) { return VarRefHash(ref); } VarRef VarRefConst(const char *ns, const char *scope, const char *lval) { VarRef ref; ref.ns = (char *)ns; ref.scope = (char *)scope; ref.lval = (char *)lval; ref.num_indices = 0; ref.indices = NULL; return ref; } VarRef *VarRefCopy(const VarRef *ref) { VarRef *copy = xmalloc(sizeof(VarRef)); copy->ns = ref->ns ? xstrdup(ref->ns) : NULL; copy->scope = ref->scope ? xstrdup(ref->scope) : NULL; copy->lval = ref->lval ? xstrdup(ref->lval) : NULL; copy->num_indices = ref->num_indices; if (ref->num_indices > 0) { copy->indices = xmalloc(ref->num_indices * sizeof(char*)); for (size_t i = 0; i < ref->num_indices; i++) { copy->indices[i] = xstrdup(ref->indices[i]); } } else { copy->indices = NULL; } return copy; } VarRef *VarRefCopyLocalized(const VarRef *ref) { VarRef *copy = xmalloc(sizeof(VarRef)); copy->ns = NULL; copy->scope = xstrdup("this"); copy->lval = ref->lval ? xstrdup(ref->lval) : NULL; copy->num_indices = ref->num_indices; if (ref->num_indices > 0) { copy->indices = xmalloc(ref->num_indices * sizeof(char*)); for (size_t i = 0; i < ref->num_indices; i++) { copy->indices[i] = xstrdup(ref->indices[i]); } } else { copy->indices = NULL; } return copy; } VarRef *VarRefCopyIndexless(const VarRef *ref) { VarRef *copy = xmalloc(sizeof(VarRef)); copy->ns = ref->ns ? xstrdup(ref->ns) : NULL; copy->scope = ref->scope ? xstrdup(ref->scope) : NULL; copy->lval = ref->lval ? xstrdup(ref->lval) : NULL; copy->num_indices = 0; copy->indices = NULL; return copy; } static bool IndexBracketsBalance(const char *var_string) { int count = 0; for (const char *c = var_string; *c != '\0'; c++) { if (*c == '[') { count++; } if (*c == ']') { count--; } } return count == 0; } static size_t IndexCount(const char *var_string) { size_t count = 0; size_t level = 0; for (const char *c = var_string; *c != '\0'; c++) { if (*c == '[') { if (level == 0) { count++; } level++; } if (*c == ']') { level--; } } return count; } VarRef *VarRefParseFromNamespaceAndScope(const char *qualified_name, const char *_ns, const char *_scope, char ns_separator, char scope_separator) { assert(qualified_name); char *ns = NULL; const char *indices_start = strchr(qualified_name, '['); const char *scope_start = strchr(qualified_name, ns_separator); if (scope_start && (!indices_start || scope_start < indices_start)) { ns = xstrndup(qualified_name, scope_start - qualified_name); scope_start++; } else { scope_start = qualified_name; } char *scope = NULL; const char *lval_start = strchr(scope_start, scope_separator); if (lval_start && (!indices_start || lval_start < indices_start)) { lval_start++; scope = xstrndup(scope_start, lval_start - scope_start - 1); } else { lval_start = scope_start; } char *lval = NULL; char **indices = NULL; size_t num_indices = 0; if (indices_start) { indices_start++; lval = xstrndup(lval_start, indices_start - lval_start - 1); if (!IndexBracketsBalance(indices_start - 1)) { Log(LOG_LEVEL_ERR, "Broken variable expression, index brackets do not balance, in '%s'", qualified_name); } else { num_indices = IndexCount(indices_start - 1); indices = xmalloc(num_indices * sizeof(char *)); Buffer *buf = BufferNew(); size_t cur_index = 0; size_t open_count = 1; for (const char *c = indices_start; *c != '\0'; c++) { if (*c == '[') { if (open_count++ == 0) { cur_index++; continue; } } else if (*c == ']') { if (open_count-- == 1) { indices[cur_index] = xstrdup(BufferData(buf)); BufferClear(buf); continue; } } BufferAppend(buf, c, sizeof(char)); } BufferDestroy(buf); } } else { lval = xstrdup(lval_start); } assert(lval); if (scope) { if (SpecialScopeFromString(scope) != SPECIAL_SCOPE_NONE) { _ns = NULL; } /* * Force considering non-special "this." variables as unqualified. * This allows qualifying bundle parameters passed as reference with a "this" scope * in the calling bundle. */ if (is_this_not_special(scope, lval)) { free(scope); scope = NULL; } } VarRef *ref = xmalloc(sizeof(VarRef)); ref->ns = ns ? ns : (_ns ? xstrdup(_ns) : NULL); ref->scope = scope ? scope : (_scope ? xstrdup(_scope) : NULL); ref->lval = lval; ref->indices = indices; ref->num_indices = num_indices; return ref; } /* * This function will return true if the given variable is * a this.something variable that is an alias to a non-special local variable. */ bool is_this_not_special(const char *scope, const char *lval) { // TODO: better way to get this list? const char *special_this_variables[] = {"v","k","this","service_policy","promiser","promiser_uid","promiser_gid","promiser_pid","promiser_ppid","bundle","handle","namespace","promise_filename","promise_dirname","promise_linenumber", NULL}; if (!scope) { return false; } if (SpecialScopeFromString(scope) != SPECIAL_SCOPE_THIS) { return false; } if (IsStrIn(lval, special_this_variables)) { return false; } return true; } VarRef *VarRefParse(const char *var_ref_string) { return VarRefParseFromNamespaceAndScope(var_ref_string, NULL, NULL, CF_NS, '.'); } VarRef *VarRefParseFromScope(const char *var_ref_string, const char *scope) { if (!scope) { return VarRefParseFromNamespaceAndScope(var_ref_string, NULL, NULL, CF_NS, '.'); } const char *scope_start = strchr(scope, CF_NS); if (scope_start) { char *ns = xstrndup(scope, scope_start - scope); VarRef *ref = VarRefParseFromNamespaceAndScope(var_ref_string, ns, scope_start + 1, CF_NS, '.'); free(ns); return ref; } else { return VarRefParseFromNamespaceAndScope(var_ref_string, NULL, scope, CF_NS, '.'); } } /** * @brief Parse the variable reference in the context of a bundle. This means * that the VarRef will inherit scope and namespace of the bundle if * these are not specified explicitly in the string. */ VarRef *VarRefParseFromBundle(const char *var_ref_string, const Bundle *bundle) { if (bundle) { return VarRefParseFromNamespaceAndScope(var_ref_string, bundle->ns, bundle->name, CF_NS, '.'); } else { return VarRefParse(var_ref_string); } } void VarRefDestroy(VarRef *ref) { if (ref) { free(ref->ns); free(ref->scope); free(ref->lval); if (ref->num_indices > 0) { for (size_t i = 0; i < ref->num_indices; ++i) { free(ref->indices[i]); } free(ref->indices); } free(ref); } } void VarRefDestroy_untyped(void *ref) { VarRefDestroy(ref); } char *VarRefToString(const VarRef *ref, bool qualified) { assert(ref->lval); Buffer *buf = BufferNew(); if (qualified && VarRefIsQualified(ref)) { const char *ns = ref->ns ? ref->ns : "default"; BufferAppend(buf, ns, strlen(ns)); BufferAppend(buf, ":", sizeof(char)); BufferAppend(buf, ref->scope, strlen(ref->scope)); BufferAppend(buf, ".", sizeof(char)); } BufferAppend(buf, ref->lval, strlen(ref->lval)); for (size_t i = 0; i < ref->num_indices; i++) { BufferAppend(buf, "[", sizeof(char)); BufferAppend(buf, ref->indices[i], strlen(ref->indices[i])); BufferAppend(buf, "]", sizeof(char)); } return BufferClose(buf); } char *VarRefMangle(const VarRef *ref) { char *suffix = VarRefToString(ref, false); if (!ref->scope) { return suffix; } else { if (ref->ns) { char *mangled = StringFormat("%s*%s#%s", ref->ns, ref->scope, suffix); free(suffix); return mangled; } else { char *mangled = StringFormat("%s#%s", ref->scope, suffix); free(suffix); return mangled; } } } VarRef *VarRefDeMangle(const char *mangled_var_ref) { return VarRefParseFromNamespaceAndScope(mangled_var_ref, NULL, NULL, CF_MANGLED_NS, CF_MANGLED_SCOPE); } static bool VarRefIsMeta(VarRef *ref) { return StringEndsWith(ref->scope, "_meta"); } void VarRefSetMeta(VarRef *ref, bool enabled) { if (enabled) { if (!VarRefIsMeta(ref)) { char *tmp = StringConcatenate(2, ref->scope, "_meta"); free(ref->scope); ref->scope = tmp; } } else { if (VarRefIsMeta(ref)) { char *tmp = ref->scope; size_t len = strlen(ref->scope); memcpy(ref->scope, StringSubstring(ref->scope, len, 0, len - strlen("_meta")), len - strlen("_meta")); free(tmp); } } } bool VarRefIsQualified(const VarRef *ref) { return ref->scope != NULL; } void VarRefQualify(VarRef *ref, const char *ns, const char *scope) { assert(scope); free(ref->ns); ref->ns = NULL; free(ref->scope); ref->scope = NULL; ref->ns = ns ? xstrdup(ns) : NULL; ref->scope = xstrdup(scope); } void VarRefAddIndex(VarRef *ref, const char *index) { if (ref->indices) { assert(ref->num_indices > 0); ref->indices = xrealloc(ref->indices, sizeof(char *) * (ref->num_indices + 1)); } else { assert(ref->num_indices == 0); ref->indices = xmalloc(sizeof(char *)); } ref->indices[ref->num_indices] = xstrdup(index); ref->num_indices++; } int VarRefCompare(const VarRef *a, const VarRef *b) { int ret = strcmp(a->lval, b->lval); if (ret != 0) { return ret; } ret = strcmp(NULLStringToEmpty(a->scope), NULLStringToEmpty(b->scope)); if (ret != 0) { return ret; } const char *a_ns = a->ns ? a->ns : "default"; const char *b_ns = b->ns ? b->ns : "default"; ret = strcmp(a_ns, b_ns); if (ret != 0) { return ret; } ret = a->num_indices - b->num_indices; if (ret != 0) { return ret; } for (size_t i = 0; i < a->num_indices; i++) { ret = strcmp(a->indices[i], b->indices[i]); if (ret != 0) { return ret; } } return 0; } bool VarRefEqual_untyped(const void *a, const void *b) { return (VarRefCompare(a, b) == 0); } cfengine-3.24.2/libpromises/dbm_api_types.h0000644000000000000000000000223315010704253020673 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DBM_API_TYPES_H #define CFENGINE_DBM_API_TYPES_H typedef bool (*OverwriteCondition) (void *value, size_t value_size, void *data); #endif /* CFENGINE_DBM_API_TYPES_H */ cfengine-3.24.2/libpromises/bootstrap.h0000644000000000000000000000354515010704253020100 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_BOOTSTRAP_H #define CFENGINE_BOOTSTRAP_H #include // EVALCONTEXT POLICY SERVER: void EvalContextSetPolicyServer(EvalContext *ctx, const char *new_policy_server); void EvalContextSetPolicyServerFromFile(EvalContext *ctx, const char *workdir); // POLICY HUB FUNCTIONS: void UpdateLastPolicyUpdateTime(EvalContext *ctx); bool GetAmPolicyHub(void); bool WriteAmPolicyHubFile(bool am_policy_hub); // FAILSAFE FUNCTIONS: bool WriteBuiltinFailsafePolicy(const char *workdir); bool WriteBuiltinFailsafePolicyToPath(const char *filename); // POLICY FILE FUNCTIONS: bool RemoveAllExistingPolicyInInputs(const char *inputdir); bool MasterfileExists(const char *masterdir); // BOOTSTRAP ID FUNCTIONS: char *CreateBootstrapIDFile(const char *workdir); char *ReadBootstrapIDFile(const char *workdir); void EvalContextSetBootstrapID(EvalContext *ctx, char *bootstrap_id); #endif cfengine-3.24.2/libpromises/mod_files.c0000644000000000000000000007412715010704253020023 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include static const ConstraintSyntax location_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("before_after", "before,after", "Menu option, point cursor before of after matched line. Default value: after", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("first_last", "first,last", "Menu option, choose first or last occurrence of match in file. Default value: last", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("select_line_matching", CF_ANYSTRING, "Regular expression for matching file line location", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax location_body = BodySyntaxNew("location", location_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax edit_field_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewBool("allow_blank_fields", "true/false allow blank fields in a line (do not purge). Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("extend_fields", "true/false add new fields at end of line if necessary to complete edit. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("field_operation", "prepend,append,alphanum,delete,set", "Menu option policy for editing subfields. Default value: none", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("field_separator", CF_ANYSTRING, "The regular expression used to separate fields in a line. Default value: none", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("field_value", CF_ANYSTRING, "Set field value to a fixed value", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("select_field", "0,99999999", "Integer index of the field required 0..n (default starts from 1)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("start_fields_from_zero", "If set, the default field numbering starts from 0", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("value_separator", CF_CHARRANGE, "Character separator for subfields inside the selected field. Default value: none", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax edit_field_body = BodySyntaxNew("edit_field", edit_field_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax replace_with_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("occurrences", "all,first", "Menu option to replace all occurrences or just first (NB the latter is non-convergent). Default value: all", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("replace_value", CF_ANYSTRING, "Value used to replace regular expression matches in search", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax replace_with_body = BodySyntaxNew("replace_with", replace_with_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax select_region_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewBool("include_start_delimiter", "Whether to include the section delimiter. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("include_end_delimiter", "Whether to include the section delimiter. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("select_start", CF_ANYSTRING, "Regular expression matching start of edit region", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("select_end", CF_ANYSTRING, "Regular expression matches end of edit region from start", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("select_end_match_eof", "Whether to include EOF as end of the region. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax select_region_body = BodySyntaxNew("select_region", select_region_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax delete_select_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("delete_if_startwith_from_list", CF_ANYSTRING, "Delete line if it starts with a string in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("delete_if_not_startwith_from_list", CF_ANYSTRING, "Delete line if it DOES NOT start with a string in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("delete_if_match_from_list", CF_ANYSTRING, "Delete line if it fully matches a regex in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("delete_if_not_match_from_list", CF_ANYSTRING,"Delete line if it DOES NOT fully match a regex in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("delete_if_contains_from_list", CF_ANYSTRING, "Delete line if a regex in the list match a line fragment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("delete_if_not_contains_from_list", CF_ANYSTRING,"Delete line if a regex in the list DOES NOT match a line fragment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax delete_select_body = BodySyntaxNew("delete_select", delete_select_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax insert_select_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("insert_if_startwith_from_list", CF_ANYSTRING, "Insert line if it starts with a string in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("insert_if_not_startwith_from_list", CF_ANYSTRING,"Insert line if it DOES NOT start with a string in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("insert_if_match_from_list", CF_ANYSTRING, "Insert line if it fully matches a regex in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("insert_if_not_match_from_list", CF_ANYSTRING,"Insert line if it DOES NOT fully match a regex in the list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("insert_if_contains_from_list", CF_ANYSTRING,"Insert line if a regex in the list match a line fragment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("insert_if_not_contains_from_list", CF_ANYSTRING, "Insert line if a regex in the list DOES NOT match a line fragment", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax insert_select_body = BodySyntaxNew("insert_select", insert_select_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax CF_INSERTLINES_BODIES[] = { ConstraintSyntaxNewBool("expand_scalars", "Expand any unexpanded variables. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("insert_type", "literal,string,file,file_preserve_block,preserve_block,preserve_all_lines", "Type of object the promiser string refers to. Default value: literal", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("insert_select", &insert_select_body, "Insert only if lines pass filter criteria", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("location", &location_body, "Specify where in a file an insertion will be made", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOptionList("whitespace_policy", "ignore_leading,ignore_trailing,ignore_embedded,exact_match", "Criteria for matching and recognizing existing lines", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const ConstraintSyntax CF_DELETELINES_BODIES[] = { ConstraintSyntaxNewBody("delete_select", &delete_select_body, "Delete only if lines pass filter criteria", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("not_matching", "true/false negate match criterion. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const ConstraintSyntax CF_COLUMN_BODIES[] = { ConstraintSyntaxNewBody("edit_field", &edit_field_body, "Edit line-based file as matrix of fields", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const ConstraintSyntax CF_REPLACE_BODIES[] = { ConstraintSyntaxNewBody("replace_with", &replace_with_body, "Search-replace pattern", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; const ConstraintSyntax CF_COMMON_EDITBODIES[] = { ConstraintSyntaxNewBody("select_region", &select_region_body, "Limit edits to a demarked region of the file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static bool AclCheck(const Body *body, Seq *errors) { bool success = true; if (BodyHasConstraint(body, "acl_directory_inherit") && BodyHasConstraint(body, "acl_default")) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, body, "An acl body cannot have both acl_directory_inherit and acl_default. Please use acl_default only")); success = false; } if (BodyHasConstraint(body, "specify_inherit_aces") && BodyHasConstraint(body, "specify_default_aces")) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, body, "An acl body cannot have both specify_inherit_aces and specify_default_aces. Please use specify_default_aces only")); success = false; } return success; } static const ConstraintSyntax acl_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("aces", "((user|group):[^:]+:[-=+,rwx()dtTabBpcoD]*(:(allow|deny))?)|((all|mask):[-=+,rwx()]*(:(allow|deny))?)", "Native settings for access control entry", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("acl_directory_inherit", "nochange,parent,specify,clear", "Access control list type for the affected file system", SYNTAX_STATUS_DEPRECATED), ConstraintSyntaxNewOption("acl_default", "nochange,access,specify,clear", "How to apply default (inheritable) access control list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("acl_method", "append,overwrite", "Editing method for access control list", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("acl_type", "generic,posix,ntfs", "Access control list type for the affected file system", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("specify_inherit_aces", "((user|group):[^:]+:[-=+,rwx()dtTabBpcoD]*(:(allow|deny))?)|((all|mask):[-=+,rwx()]*(:(allow|deny))?)", "Native settings for access control entry", SYNTAX_STATUS_DEPRECATED), ConstraintSyntaxNewStringList("specify_default_aces", "((user|group):[^:]+:[-=+,rwx()dtTabBpcoD]*(:(allow|deny))?)|((all|mask):[-=+,rwx()]*(:(allow|deny))?)", "Native settings for access control entry", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("acl_inherit", CF_BOOL ",nochange", "Whether the object inherits its ACL from the parent (Windows only)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax acl_body = BodySyntaxNew("acl", acl_constraints, &AclCheck, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax changes_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("hash", "md5,sha1,sha224,sha256,sha384,sha512,best", "Hash files for change detection", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("report_changes", "all,stats,content,none", "Specify criteria for change warnings", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("update_hashes", "Update hash values immediately after change warning", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("report_diffs","Generate reports summarizing the major differences between individual text files", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax changes_body = BodySyntaxNew("changes", changes_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax depth_search_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewInt("depth", CF_VALRANGE, "Maximum depth level for search", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("exclude_dirs", ".*", "List of regexes of directory names NOT to include in depth search", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("include_basedir", "true/false include the start/root dir of the search results", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("include_dirs", ".*", "List of regexes of directory names to include in depth search", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("rmdeadlinks", "true/false remove links that point to nowhere. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("traverse_links", "true/false traverse symbolic links to directories. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("xdev", "When true files and directories on different devices from the promiser will be excluded from depth_search results. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax depth_search_body = BodySyntaxNew("depth_search", depth_search_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax edit_defaults_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("edit_backup", "true,false,timestamp,rotate", "Menu option for backup policy on edit changes. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("empty_file_before_editing", "Baseline memory model of file to zero/empty before commencing promised edits. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("inherit", "If true this causes the sub-bundle to inherit the private classes of its parent", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("max_file_size", CF_VALRANGE, "Do not edit files bigger than this number of bytes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("recognize_join", "Join together lines that end with a backslash, up to 4kB limit. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("rotate", "0,99", "How many backups to store if 'rotate' edit_backup strategy is selected. Default value: 1", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax edit_defaults_body = BodySyntaxNew("edit_defaults", edit_defaults_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax delete_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewOption("dirlinks", "delete,tidy,keep", "Menu option policy for dealing with symbolic links to directories during deletion", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("rmdirs", "true/false whether to delete empty directories during recursive deletion", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax delete_body = BodySyntaxNew("delete", delete_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax rename_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewBool("disable", "true/false automatically rename and remove permissions. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("disable_mode", CF_MODERANGE, "The permissions to set when a file is disabled", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("disable_suffix", "", "The suffix to add to files when disabling (.cfdisabled)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("newname", "", "The desired name for the current file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("rotate", "0,99", "Maximum number of file rotations to keep", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax rename_body = BodySyntaxNew("rename", rename_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax perms_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("bsdflags", CF_BSDFLAGRANGE, "List of menu options for bsd file system flags to set", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("groups", CF_USERRANGE, "List of acceptable groups of group ids, first is change target", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("mode", CF_MODERANGE, "File permissions (like posix chmod)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("owners", CF_USERRANGE, "List of acceptable owners or user ids, first is change target", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("rxdirs", "true/false add execute flag for directories if read flag is set", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax perms_body = BodySyntaxNew("perms", perms_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax file_select_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("leaf_name", "", "List of regexes that match an acceptable name", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("path_name", CF_ABSPATHRANGE, "List of pathnames to match acceptable target", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("search_mode", CF_MODERANGE, "A list of mode masks for acceptable file permissions", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("search_size", "0,inf", "Integer range of file sizes", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("search_owners", "", "List of acceptable user names or ids for the file, or regexes to match", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("search_groups", "", "List of acceptable group names or ids for the file, or regexes to match", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("search_bsdflags", CF_BSDFLAGRANGE, "String of flags for bsd file system flags expected set", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("ctime", CF_TIMERANGE, "Range of change times (ctime) for acceptable files", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("mtime", CF_TIMERANGE, "Range of modification times (mtime) for acceptable files", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("atime", CF_TIMERANGE, "Range of access times (atime) for acceptable files", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("exec_regex", CF_ANYSTRING, "Matches file if this regular expression matches any full line returned by the command", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("exec_program", CF_ABSPATHRANGE, "Execute this command on each file and match if the exit status is zero", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOptionList("file_types", "plain,reg,symlink,dir,socket,fifo,door,char,block", "List of acceptable file types from menu choices", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("issymlinkto", "", "List of regular expressions to match file objects", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("file_result", "[!*(leaf_name|path_name|file_types|mode|size|owner|group|atime|ctime|mtime|issymlinkto|exec_regex|exec_program|bsdflags)[|&.]*]*", "Logical expression combining classes defined by file search criteria", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax file_select_body = BodySyntaxNew("file_select", file_select_constraints, NULL, SYNTAX_STATUS_NORMAL); /* Copy and link are really the same body and should have non-overlapping patterns so that they are XOR but it's okay that some names overlap (like source) as there is no ambiguity in XOR */ static const ConstraintSyntax link_from_constraints[] = { CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewStringList("copy_patterns", "", "A set of patterns that should be copied and synchronized instead of linked", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("link_children", "true/false whether to link all directory's children to source originals. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("link_type", CF_LINKRANGE, "The type of link used to alias the file. Default value: symlink", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("source", CF_PATHRANGE, "The source file to which the link should point", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("when_linking_children", "override_file,if_no_such_file", "Policy for overriding existing files when linking directories of children", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("when_no_source", "force,delete,nop", "Behaviour when the source file to link to does not exist. Default value: nop", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax link_from_body = BodySyntaxNew("link_from", link_from_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax copy_from_constraints[] = { /* We use CF_PATHRANGE due to collision with LINKTO_BODY and a bug lurking in * a verification stage -- this attribute gets picked instead of another * 'source' */ CONSTRAINT_SYNTAX_GLOBAL, ConstraintSyntaxNewString("source", CF_PATHRANGE, "Reference source file from which to copy", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("servers", "[A-Za-z0-9_.:\\-\\[\\]]+", "List of servers in order of preference from which to copy", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("collapse_destination_dir", "Copy files from subdirectories to the root destination directory. Default: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("compare", "atime,mtime,ctime,digest,hash,exists,binary", "Menu option policy for comparing source and image file attributes. Default: mtime or ctime differs", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("copy_backup", "true,false,timestamp", "Menu option policy for file backup/version control. Default value: true", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("encrypt", "true/false use encrypted data stream to connect to remote host. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("check_root", "true/false check permissions on the root directory when depth_search", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("copylink_patterns", "", "List of patterns matching files that should be copied instead of linked", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewIntRange("copy_size", "0,inf", "Integer range of file sizes that may be copied", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("findertype", "MacOSX", "Menu option for default finder type on MacOSX", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewStringList("linkcopy_patterns", "", "List of patterns matching files that should be replaced with symbolic links", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("link_type", CF_LINKRANGE, "Menu option for type of links to use when copying. Default value: symlink", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("force_update", "true/false force copy update always. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("force_ipv4", "true/false force use of ipv4 on ipv6 enabled network. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("portnumber", "", "Port number or service name to connect to on server host", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("preserve", "true/false whether to preserve file permissions on copied file. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("purge", "true/false purge files on client that do not match files on server when a depth_search is used. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("stealth", "true/false whether to preserve time stamps on copied file. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewInt("timeout", "1,3600", "Connection timeout, seconds", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("trustkey", "true/false trust public keys from remote server if previously unknown. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("type_check", "true/false compare file types before copying and require match", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("verify", "true/false verify transferred file by hashing after copy (resource penalty). Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("protocol_version", "1,classic,2,tls,3,cookie,latest", "CFEngine protocol version to use when connecting to the server. Default: undefined", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("missing_ok", "true/false Do not treat missing file as an error. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const BodySyntax copy_from_body = BodySyntaxNew("copy_from", copy_from_constraints, NULL, SYNTAX_STATUS_NORMAL); static const ConstraintSyntax CF_FILES_BODIES[] = { ConstraintSyntaxNewBody("acl", &acl_body, "Criteria for access control lists on file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("changes", &changes_body, "Criteria for change management", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("copy_from", ©_from_body, "Criteria for copying file from a source", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("create", "true/false whether to create non-existing file. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("delete", &delete_body, "Criteria for deleting files", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("content", CF_ANYSTRING, "Complete content the promised file should contain", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("depth_search", &depth_search_body, "Criteria for file depth searches", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("edit_defaults", &edit_defaults_body, "Default promise details for file edits", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBundle("edit_line", "Line editing model for file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("edit_template", CF_ABSPATHRANGE, "The name of a special CFEngine template file to expand", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("edit_template_string", CF_ANYSTRING, "Template string to expand", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBundle("edit_xml", "XML editing model for file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("file_select", &file_select_body, "Choose which files select in a search", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("file_type", "regular,fifo", "Type of file to create. Default value: regular", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("link_from", &link_from_body, "Criteria for linking file from a source", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("move_obstructions", "true/false whether to move obstructions to file-object creation. Default value: false", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("pathtype", "literal,regex,guess", "Menu option for interpreting promiser file object", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("perms", &perms_body, "Criteria for setting permissions on a file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBody("rename", &rename_body, "Criteria for renaming files", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("repository", CF_ABSPATHRANGE, "Name of a repository for versioning", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewBool("touch", "true/false whether to touch time stamps on file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("transformer", CF_ABSPATHRANGE, "Command (with full path) used to transform current file (no shell wrapper used)", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewOption("template_method", "cfengine,inline_mustache,mustache", "", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewContainer("template_data", "", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; // edit_xml body syntax const ConstraintSyntax CF_COMMON_XMLBODIES[] = { ConstraintSyntaxNewString("build_xpath", "", "Build an XPath within the XML file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewString("select_xpath", "", "Select the XPath node in the XML file to edit", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const ConstraintSyntax CF_INSERTTAGS_BODIES[] = { ConstraintSyntaxNewNull() }; static const ConstraintSyntax CF_DELETETAGS_BODIES[] = { ConstraintSyntaxNewNull() }; static const ConstraintSyntax CF_INSERTATTRIBUTES_BODIES[] = { ConstraintSyntaxNewString("attribute_value", "", "Value of the attribute to be inserted into the XPath node of the XML file", SYNTAX_STATUS_NORMAL), ConstraintSyntaxNewNull() }; static const ConstraintSyntax CF_DELETEATTRIBUTES_BODIES[] = { ConstraintSyntaxNewNull() }; // Master Syntax for Files const PromiseTypeSyntax CF_FILES_PROMISE_TYPES[] = { /* Body lists belonging to "files:" type in Agent */ PromiseTypeSyntaxNew("agent", "files", CF_FILES_BODIES, NULL, SYNTAX_STATUS_NORMAL), /* Body lists belonging to th edit_line sub-bundle of files: */ PromiseTypeSyntaxNew("edit_line", "*", CF_COMMON_EDITBODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_line", "delete_lines", CF_DELETELINES_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_line", "insert_lines", CF_INSERTLINES_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_line", "field_edits", CF_COLUMN_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_line", "replace_patterns", CF_REPLACE_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "*", CF_COMMON_XMLBODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "build_xpath", CF_INSERTTAGS_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "delete_tree", CF_DELETETAGS_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "insert_tree", CF_INSERTTAGS_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "delete_attribute", CF_DELETEATTRIBUTES_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "set_attribute", CF_INSERTATTRIBUTES_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "delete_text", CF_DELETETAGS_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "set_text", CF_INSERTTAGS_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNew("edit_xml", "insert_text", CF_INSERTTAGS_BODIES, NULL, SYNTAX_STATUS_NORMAL), PromiseTypeSyntaxNewNull() }; cfengine-3.24.2/libpromises/conversion.c0000644000000000000000000007055415010704253020247 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include /* GetUserID(), GetGroupID() */ const char *MapAddress(const char *unspec_address) { /* Is the address a mapped ipv4 over ipv6 address */ if (strncmp(unspec_address, "::ffff:", 7) == 0) { return unspec_address + 7; } else { return unspec_address; } } int FindTypeInArray(const char *const haystack[], const char *needle, int default_value, int null_value) { if (needle == NULL) { return null_value; } for (int i = 0; haystack[i] != NULL; ++i) { if (strcmp(needle, haystack[i]) == 0) { return i; } } return default_value; } MeasurePolicy MeasurePolicyFromString(const char *s) { static const char *const MEASURE_POLICY_TYPES[] = { "average", "sum", "first", "last", NULL }; return FindTypeInArray(MEASURE_POLICY_TYPES, s, MEASURE_POLICY_AVERAGE, MEASURE_POLICY_NONE); } EnvironmentState EnvironmentStateFromString(const char *s) { static const char *const ENV_STATE_TYPES[] = { "create", "delete", "running", "suspended", "down", NULL }; return FindTypeInArray(ENV_STATE_TYPES, s, ENVIRONMENT_STATE_NONE, ENVIRONMENT_STATE_CREATE); } InsertMatchType InsertMatchTypeFromString(const char *s) { static const char *const INSERT_MATCH_TYPES[] = { "ignore_leading", "ignore_trailing", "ignore_embedded", "exact_match", NULL }; return FindTypeInArray(INSERT_MATCH_TYPES, s, INSERT_MATCH_TYPE_EXACT, INSERT_MATCH_TYPE_EXACT); } int SyslogPriorityFromString(const char *s) { static const char *const SYSLOG_PRIORITY_TYPES[] = { "emergency", "alert", "critical", "error", "warning", "notice", "info", "debug", NULL }; return FindTypeInArray(SYSLOG_PRIORITY_TYPES, s, 3, 3); } ShellType ShellTypeFromString(const char *string) { // For historical reasons, supports all CF_BOOL values (true/false/yes/no...), // as well as "noshell,useshell,powershell". char *start, *end; char *options = "noshell,useshell,powershell," CF_BOOL; int i; int size; if (string == NULL) { return SHELL_TYPE_NONE; } start = options; size = strlen(string); for (i = 0;; i++) { end = strchr(start, ','); if (end == NULL) { break; } if (size == end - start && strncmp(string, start, end - start) == 0) { int cfBoolIndex; switch (i) { case 0: return SHELL_TYPE_NONE; case 1: return SHELL_TYPE_USE; case 2: return SHELL_TYPE_POWERSHELL; default: // Even cfBoolIndex is true, odd cfBoolIndex is false (from CF_BOOL). cfBoolIndex = i-3; return (cfBoolIndex & 1) ? SHELL_TYPE_NONE : SHELL_TYPE_USE; } } start = end + 1; } return SHELL_TYPE_NONE; } DatabaseType DatabaseTypeFromString(const char *s) { static const char *const DB_TYPES[] = { "mysql", "postgres", NULL }; return FindTypeInArray(DB_TYPES, s, DATABASE_TYPE_NONE, DATABASE_TYPE_NONE); } UserState UserStateFromString(const char *s) { static const char *const U_TYPES[] = { "present", "absent", "locked", NULL }; return FindTypeInArray(U_TYPES, s, USER_STATE_NONE, USER_STATE_NONE); } PasswordFormat PasswordFormatFromString(const char *s) { static const char *const U_TYPES[] = { "plaintext", "hash", NULL }; return FindTypeInArray(U_TYPES, s, PASSWORD_FORMAT_NONE, PASSWORD_FORMAT_NONE); } PackageAction PackageActionFromString(const char *s) { static const char *const PACKAGE_ACTION_TYPES[] = { "add", "delete", "reinstall", "update", "addupdate", "patch", "verify", NULL }; return FindTypeInArray(PACKAGE_ACTION_TYPES, s, PACKAGE_ACTION_NONE, PACKAGE_ACTION_NONE); } NewPackageAction GetNewPackagePolicy(const char *s, const char **action_types) { return FindTypeInArray(action_types, s, NEW_PACKAGE_ACTION_NONE, NEW_PACKAGE_ACTION_NONE); } PackageVersionComparator PackageVersionComparatorFromString(const char *s) { static const char *const PACKAGE_SELECT_TYPES[] = { "==", "!=", ">", "<", ">=", "<=", NULL }; return FindTypeInArray(PACKAGE_SELECT_TYPES, s, PACKAGE_VERSION_COMPARATOR_NONE, PACKAGE_VERSION_COMPARATOR_NONE); } PackageActionPolicy PackageActionPolicyFromString(const char *s) { static const char *const ACTION_POLICY_TYPES[] = { "individual", "bulk", NULL }; return FindTypeInArray(ACTION_POLICY_TYPES, s, PACKAGE_ACTION_POLICY_NONE, PACKAGE_ACTION_POLICY_NONE); } /***************************************************************************/ char *Rlist2String(Rlist *list, char *sep) { Writer *writer = StringWriter(); for (const Rlist *rp = list; rp != NULL; rp = rp->next) { RvalWrite(writer, rp->val); if (rp->next != NULL) { WriterWrite(writer, sep); } } return StringWriterClose(writer); } /***************************************************************************/ int SignalFromString(const char *s) { char *signal_names[15] = { "hup", "int", "trap", "kill", "pipe", "cont", "abrt", "stop", "quit", "term", "child", "usr1", "usr2", "bus", "segv" }; int signals[15] = { SIGHUP, SIGINT, SIGTRAP, SIGKILL, SIGPIPE, SIGCONT, SIGABRT, SIGSTOP, SIGQUIT, SIGTERM, SIGCHLD, SIGUSR1, SIGUSR2, SIGBUS, SIGSEGV }; for (size_t i = 0; i < 15; i++) { if (StringEqual(s, signal_names[i])) { return signals[i]; } } return -1; } ContextScope ContextScopeFromString(const char *scope_str) { static const char *const CONTEXT_SCOPES[] = { "namespace", "bundle" }; return FindTypeInArray(CONTEXT_SCOPES, scope_str, CONTEXT_SCOPE_NAMESPACE, CONTEXT_SCOPE_NONE); } FileLinkType FileLinkTypeFromString(const char *s) { static const char *const LINK_TYPES[] = { "symlink", "hardlink", "relative", "absolute", NULL }; return FindTypeInArray(LINK_TYPES, s, FILE_LINK_TYPE_SYMLINK, FILE_LINK_TYPE_SYMLINK); } FileComparator FileComparatorFromString(const char *s) { static const char *const FILE_COMPARISON_TYPES[] = { "atime", "mtime", "ctime", "digest", "hash", "binary", "exists", NULL }; return FindTypeInArray(FILE_COMPARISON_TYPES, s, FILE_COMPARATOR_NONE, FILE_COMPARATOR_NONE); } static const char *const datatype_strings[] = { [CF_DATA_TYPE_STRING] = "string", [CF_DATA_TYPE_INT] = "int", [CF_DATA_TYPE_REAL] = "real", [CF_DATA_TYPE_STRING_LIST] = "slist", [CF_DATA_TYPE_INT_LIST] = "ilist", [CF_DATA_TYPE_REAL_LIST] = "rlist", [CF_DATA_TYPE_OPTION] = "option", [CF_DATA_TYPE_OPTION_LIST] = "olist", [CF_DATA_TYPE_BODY] = "body", [CF_DATA_TYPE_BUNDLE] = "bundle", [CF_DATA_TYPE_CONTEXT] = "context", [CF_DATA_TYPE_CONTEXT_LIST] = "clist", [CF_DATA_TYPE_INT_RANGE] = "irange", [CF_DATA_TYPE_REAL_RANGE] = "rrange", [CF_DATA_TYPE_COUNTER] = "counter", [CF_DATA_TYPE_CONTAINER] = "data", [CF_DATA_TYPE_NONE] = "none" }; DataType DataTypeFromString(const char *name) { for (int i = 0; i < CF_DATA_TYPE_NONE; i++) { if (strcmp(datatype_strings[i], name) == 0) { return i; } } return CF_DATA_TYPE_NONE; } const char *DataTypeToString(DataType type) { assert(type < CF_DATA_TYPE_NONE); return datatype_strings[type]; } DataType ConstraintSyntaxGetDataType(const ConstraintSyntax *body_syntax, const char *lval) { int i = 0; for (i = 0; body_syntax[i].lval != NULL; i++) { if (lval && (strcmp(body_syntax[i].lval, lval) == 0)) { return body_syntax[i].dtype; } } return CF_DATA_TYPE_NONE; } /****************************************************************************/ // Warning: Defaults to true on unexpected (non-bool) input bool BooleanFromString(const char *s) { assert(StringEqual(CF_BOOL, "true,false,yes,no,on,off")); assert(s != NULL); if (StringEqual(s, "false") || StringEqual(s, "no") || StringEqual(s, "off")) { return false; } // Unnecessary to check here because the default is true anyway: // if (StringEqual(s, "true") // || StringEqual(s, "yes") // || StringEqual(s, "on")) // { // return true; // } // Default to true to preserve old behavior: return true; } bool StringIsBoolean(const char *s) { assert(StringEqual(CF_BOOL, "true,false,yes,no,on,off")); assert(s != NULL); return (StringEqual(s, "true") || StringEqual(s, "false") || StringEqual(s, "yes") || StringEqual(s, "no") || StringEqual(s, "on") || StringEqual(s, "off")); } /****************************************************************************/ /** * @NOTE parameter #s might be NULL. It's already used by design like that, * for example parsing inexistent attributes in GetVolumeConstraints(). * * @TODO see DoubleFromString(): return bool, have a value_out parameter, and * kill CF_NOINT (goes deep!) */ long IntFromString(const char *s) { long long ll = CF_NOINT; char quantifier, remainder; if (s == NULL) { return CF_NOINT; } if (strcmp(s, "inf") == 0) { return (long) CF_INFINITY; } if (strcmp(s, "now") == 0) { return (long) CFSTARTTIME; } int ret = sscanf(s, "%lld%c %c", &ll, &quantifier, &remainder); if (ret < 1 || ll == CF_NOINT) { if (strchr(s, '$') != NULL) /* don't log error, might converge */ { Log(LOG_LEVEL_VERBOSE, "Ignoring failed to parse integer '%s'" " because of possibly unexpanded variable", s); } else { Log(LOG_LEVEL_ERR, "Failed to parse integer number: %s", s); } } else if (ret == 3) { ll = CF_NOINT; if (quantifier == '$') /* don't log error, might converge */ { Log(LOG_LEVEL_VERBOSE, "Ignoring failed to parse integer '%s'" " because of possibly unexpanded variable", s); } else { Log(LOG_LEVEL_ERR, "Anomalous ending '%c%c' while parsing integer number: %s", quantifier, remainder, s); } } else if (ret == 1) /* no quantifier */ { /* nop */ } else { assert(ret == 2); switch (quantifier) { case 'k': ll *= 1000; break; case 'K': ll *= 1024; break; case 'm': ll *= 1000 * 1000; break; case 'M': ll *= 1024 * 1024; break; case 'g': ll *= 1000 * 1000 * 1000; break; case 'G': ll *= 1024 * 1024 * 1024; break; case '%': if ((ll < 0) || (ll > 100)) { Log(LOG_LEVEL_ERR, "Percentage out of range: %lld", ll); return CF_NOINT; } else { /* Represent percentages internally as negative numbers */ /* TODO fix? */ ll *= -1; } break; case ' ': break; default: Log(LOG_LEVEL_VERBOSE, "Ignoring bad quantifier '%c' in integer: %s", quantifier, s); break; } } /* TODO Use strtol() instead of scanf(), it properly checks for overflow * but it is prone to coding errors, so even better bring OpenBSD's * strtonum() for proper conversions. */ if (ll < LONG_MIN) { Log(LOG_LEVEL_VERBOSE, "Number '%s' underflows a long int, truncating to %ld", s, LONG_MIN); return LONG_MIN; } else if (ll > LONG_MAX) { Log(LOG_LEVEL_VERBOSE, "Number '%s' overflows a long int, truncating to %ld", s, LONG_MAX); return LONG_MAX; } return (long) ll; } Interval IntervalFromString(const char *string) { static const char *const INTERVAL_TYPES[] = { "hourly", "daily", NULL }; return FindTypeInArray(INTERVAL_TYPES, string, INTERVAL_NONE, INTERVAL_NONE); } bool DoubleFromString(const char *s, double *value_out) { double d; char quantifier, remainder; assert(s != NULL); assert(value_out != NULL); int ret = sscanf(s, "%lf%c %c", &d, &quantifier, &remainder); if (ret < 1) { Log(LOG_LEVEL_ERR, "Failed to parse real number: %s", s); return false; } else if (ret == 3) /* non-space remainder */ { Log(LOG_LEVEL_ERR, "Anomalous ending '%c%c' while parsing real number: %s", quantifier, remainder, s); return false; } else if (ret == 1) /* no quantifier char */ { /* nop */ } else /* got quantifier */ { assert(ret == 2); switch (quantifier) { case 'k': d *= 1000; break; case 'K': d *= 1024; break; case 'm': d *= 1000 * 1000; break; case 'M': d *= 1024 * 1024; break; case 'g': d *= 1000 * 1000 * 1000; break; case 'G': d *= 1024 * 1024 * 1024; break; case '%': if ((d < 0) || (d > 100)) { Log(LOG_LEVEL_ERR, "Percentage out of range: %.2lf", d); return false; } else { /* Represent percentages internally as negative numbers */ /* TODO fix? */ d *= -1; } break; case ' ': break; default: Log(LOG_LEVEL_VERBOSE, "Ignoring bad quantifier '%c' in real number: %s", quantifier, s); break; } } assert(ret == 1 || ret == 2); *value_out = d; return true; } /****************************************************************************/ /** * @return true if successful */ bool IntegerRangeFromString(const char *intrange, long *min_out, long *max_out) { Item *split; long lmax = CF_LOWINIT, lmin = CF_HIGHINIT; /* Numeric types are registered by range separated by comma str "min,max" */ if (intrange == NULL) { *min_out = CF_NOINT; *max_out = CF_NOINT; return true; } split = SplitString(intrange, ','); sscanf(split->name, "%ld", &lmin); if (strcmp(split->next->name, "inf") == 0) { lmax = (long) CF_INFINITY; } else { sscanf(split->next->name, "%ld", &lmax); } DeleteItemList(split); if ((lmin == CF_HIGHINIT) || (lmax == CF_LOWINIT)) { return false; } *min_out = lmin; *max_out = lmax; return true; } AclMethod AclMethodFromString(const char *string) { static const char *const ACL_METHOD_TYPES[] = { "append", "overwrite", NULL }; return FindTypeInArray(ACL_METHOD_TYPES, string, ACL_METHOD_NONE, ACL_METHOD_NONE); } AclType AclTypeFromString(const char *string) { static const char *const ACL_TYPES[]= { "generic", "posix", "ntfs", NULL }; return FindTypeInArray(ACL_TYPES, string, ACL_TYPE_NONE, ACL_TYPE_NONE); } /* For the deprecated attribute acl_directory_inherit. */ AclDefault AclInheritanceFromString(const char *string) { static const char *const ACL_INHERIT_TYPES[5] = { "nochange", "specify", "parent", "clear", NULL }; return FindTypeInArray(ACL_INHERIT_TYPES, string, ACL_DEFAULT_NONE, ACL_DEFAULT_NONE); } AclDefault AclDefaultFromString(const char *string) { static const char *const ACL_DEFAULT_TYPES[5] = { "nochange", "specify", "access", "clear", NULL }; return FindTypeInArray(ACL_DEFAULT_TYPES, string, ACL_DEFAULT_NONE, ACL_DEFAULT_NONE); } AclInherit AclInheritFromString(const char *string) { char *start, *end; char *options = CF_BOOL ",nochange"; int i; int size; if (string == NULL) { return ACL_INHERIT_NOCHANGE; } start = options; size = strlen(string); for (i = 0;; i++) { end = strchr(start, ','); if (end == NULL) { break; } if (size == end - start && strncmp(string, start, end - start) == 0) { // Even i is true, odd i is false (from CF_BOOL). return (i & 1) ? ACL_INHERIT_FALSE : ACL_INHERIT_TRUE; } start = end + 1; } return ACL_INHERIT_NOCHANGE; } const char *DataTypeShortToType(char *short_type) { assert(short_type); if(strcmp(short_type, "s") == 0) { return "string"; } if(strcmp(short_type, "i") == 0) { return "int"; } if(strcmp(short_type, "r") == 0) { return "real"; } if(strcmp(short_type, "m") == 0) { return "menu"; } if(strcmp(short_type, "sl") == 0) { return "string list"; } if(strcmp(short_type, "il") == 0) { return "int list"; } if(strcmp(short_type, "rl") == 0) { return "real list"; } if(strcmp(short_type, "ml") == 0) { return "menu list"; } return "unknown type"; } bool DataTypeIsIterable(DataType t) { if (t == CF_DATA_TYPE_STRING_LIST || t == CF_DATA_TYPE_INT_LIST || t == CF_DATA_TYPE_REAL_LIST || t == CF_DATA_TYPE_CONTAINER) { return true; } else { return false; } } bool CoarseLaterThan(const char *bigger, const char *smaller) { char month_small[CF_SMALLBUF]; char month_big[CF_SMALLBUF]; int m_small, day_small, year_small, m_big, year_big, day_big; sscanf(smaller, "%d %s %d", &day_small, month_small, &year_small); sscanf(bigger, "%d %s %d", &day_big, month_big, &year_big); if (year_big < year_small) { return false; } m_small = Month2Int(month_small); m_big = Month2Int(month_big); if (m_big < m_small) { return false; } if (day_big < day_small && m_big == m_small && year_big == year_small) { return false; } return true; } int Month2Int(const char *string) { int i; if (string == NULL) { return -1; } for (i = 0; i < 12; i++) { if (strncmp(MONTH_TEXT[i], string, strlen(string)) == 0) { return i + 1; break; } } return -1; } /*********************************************************************/ void TimeToDateStr(time_t t, char *outStr, int outStrSz) /** * Formats a time as "30 Sep 2010". */ { char month[CF_SMALLBUF], day[CF_SMALLBUF], year[CF_SMALLBUF]; char tmp[CF_SMALLBUF]; snprintf(tmp, sizeof(tmp), "%s", ctime(&t)); sscanf(tmp, "%*s %5s %3s %*s %5s", month, day, year); snprintf(outStr, outStrSz, "%s %s %s", day, month, year); } /*********************************************************************/ /** * Copy first argument of #src to #dst. Argument is delimited either by double * quotes if first character is double quotes, or by space. * * @note Thread-safe version of CommandArg0(). * * @return The length of #dst, or (size_t) -1 in case of overflow. */ size_t CommandArg0_bound(char *dst, const char *src, size_t dst_size) { const char *start; char end_delimiter; if(src[0] == '\"') { start = &src[1]; end_delimiter = '\"'; } else { start = src; end_delimiter = ' '; } char *end = strchrnul(start, end_delimiter); size_t len = end - start; if (len < dst_size) { memcpy(dst, start, len); dst[len] = '\0'; return len; } else { /* Check return value of CommandArg0_bound! If -1, the user should * never use dst, but just in case we are writing a bogus string. */ const char trap[] = "BUG: COMMANDARG0_TOO_LONG"; strlcpy(dst, trap, dst_size); return (size_t) -1; } } const char *CommandArg0(const char *execstr) /** * WARNING: Not thread-safe. **/ { static char arg[CF_BUFSIZE]; /* GLOBAL_R, no initialization needed */ const char *start; char end_delimiter; if(execstr[0] == '\"') { start = execstr + 1; end_delimiter = '\"'; } else { start = execstr; end_delimiter = ' '; } strlcpy(arg, start, sizeof(arg)); char *cut = strchr(arg, end_delimiter); if(cut) { *cut = '\0'; } return arg; } /*************************************************************/ void CommandPrefix(char *execstr, char *comm) { char *sp; for (sp = execstr; (*sp != ' ') && (*sp != '\0'); sp++) { } if (sp - 10 >= execstr) { sp -= 10; /* copy 15 most relevant characters of command */ } else { sp = execstr; } memset(comm, 0, 20); strncpy(comm, sp, 15); } /*******************************************************************/ bool IsRealNumber(const char *s) { double d; int ret = sscanf(s, "%lf", &d); if (ret != 1) { return false; } return true; } #ifndef __MINGW32__ /*******************************************************************/ /* Unix-only functions */ /*******************************************************************/ /****************************************************************************/ /* Rlist to Uid/Gid lists */ /****************************************************************************/ void UidListDestroy(UidList *uids) { while (uids) { UidList *ulp = uids; uids = uids->next; free(ulp->uidname); free(ulp); } } static void AddSimpleUidItem(UidList ** uidlist, uid_t uid, char *uidname) { UidList *ulp = xcalloc(1, sizeof(UidList)); ulp->uid = uid; if (uid == CF_UNKNOWN_OWNER) /* unknown user */ { ulp->uidname = xstrdup(uidname); } if (*uidlist == NULL) { *uidlist = ulp; } else /* Hang new element off end of list: */ { UidList *u = *uidlist; while (u->next != NULL) { u = u->next; } u->next = ulp; } } UidList *Rlist2UidList(Rlist *uidnames, const Promise *pp) { UidList *uidlist = NULL; Rlist *rp; char username[CF_MAXVARSIZE]; uid_t uid; for (rp = uidnames; rp != NULL; rp = rp->next) { username[0] = '\0'; uid = Str2Uid(RlistScalarValue(rp), username, pp); AddSimpleUidItem(&uidlist, uid, username); } if (uidlist == NULL) { AddSimpleUidItem(&uidlist, CF_SAME_OWNER, NULL); } return uidlist; } /*********************************************************************/ void GidListDestroy(GidList *gids) { while (gids) { GidList *glp = gids; gids = gids->next; free(glp->gidname); free(glp); } } static void AddSimpleGidItem(GidList ** gidlist, gid_t gid, char *gidname) { GidList *glp = xcalloc(1, sizeof(GidList)); glp->gid = gid; if (gid == CF_UNKNOWN_GROUP) /* unknown group */ { glp->gidname = xstrdup(gidname); } if (*gidlist == NULL) { *gidlist = glp; } else /* Hang new element off end of list: */ { GidList *g = *gidlist; while (g->next != NULL) { g = g->next; } g->next = glp; } } GidList *Rlist2GidList(Rlist *gidnames, const Promise *pp) { GidList *gidlist = NULL; Rlist *rp; char groupname[CF_MAXVARSIZE]; gid_t gid; for (rp = gidnames; rp != NULL; rp = rp->next) { groupname[0] = '\0'; gid = Str2Gid(RlistScalarValue(rp), groupname, pp); AddSimpleGidItem(&gidlist, gid, groupname); } if (gidlist == NULL) { AddSimpleGidItem(&gidlist, CF_SAME_GROUP, NULL); } return gidlist; } /*********************************************************************/ uid_t Str2Uid(const char *uidbuff, char *usercopy, const Promise *pp) { if (StringEqual(uidbuff, "*")) { return CF_SAME_OWNER; /* signals wildcard */ } if (StringIsNumeric(uidbuff)) { #ifdef __hpux /* sscanf("0", "%ju", &tmp) with 'uintmax_t' fails, 'int' and '%d' work */ int tmp; NDEBUG_UNUSED int ret = sscanf(uidbuff, "%d", &tmp); assert(ret == 1); #else uintmax_t tmp; NDEBUG_UNUSED int ret = sscanf(uidbuff, "%ju", &tmp); assert(ret == 1); #endif return (uid_t) tmp; } uid_t uid = CF_UNKNOWN_OWNER; if (uidbuff[0] == '+') { if (uidbuff[1] == '@') { uidbuff++; } char *machine = NULL; char *user = NULL; char *domain = NULL; setnetgrent(uidbuff); while ((uid == CF_UNKNOWN_OWNER) && (getnetgrent(&machine, &user, &domain) == 1)) { if (user != NULL) { if (GetUserID(user, &uid, LOG_LEVEL_INFO)) { if (usercopy != NULL) { strcpy(usercopy, user); } } else { if (pp != NULL) { PromiseRef(LOG_LEVEL_INFO, pp); } } } } endnetgrent(); return uid; } if (GetUserID(uidbuff, &uid, LOG_LEVEL_INFO)) { if (usercopy != NULL) { strcpy(usercopy, uidbuff); } } else { if (pp) { PromiseRef(LOG_LEVEL_INFO, pp); } } return uid; } /*********************************************************************/ gid_t Str2Gid(const char *gidbuff, char *groupcopy, const Promise *pp) { if (StringEqual(gidbuff, "*")) { return CF_SAME_GROUP; /* signals wildcard */ } if (StringIsNumeric(gidbuff)) { #ifdef __hpux /* sscanf("0", "%ju", &tmp) with 'uintmax_t' fails, 'int' and '%d' work */ int tmp; NDEBUG_UNUSED int ret = sscanf(gidbuff, "%d", &tmp); assert(ret == 1); #else uintmax_t tmp; NDEBUG_UNUSED int ret = sscanf(gidbuff, "%ju", &tmp); assert(ret == 1); #endif return (gid_t) tmp; } gid_t gid = CF_UNKNOWN_GROUP; if (GetGroupID(gidbuff, &gid, LOG_LEVEL_INFO)) { if (groupcopy != NULL) { strcpy(groupcopy, gidbuff); } } else { if (pp) { PromiseRef(LOG_LEVEL_INFO, pp); } } return gid; } #else /* !__MINGW32__ */ /* Release everything NovaWin_Rlist2SidList() allocates: */ void UidListDestroy(UidList *uids) { while (uids) { UidList *ulp = uids; uids = uids->next; free(ulp); } } void GidListDestroy(ARG_UNUSED GidList *gids) { assert(gids == NULL); } #endif cfengine-3.24.2/libpromises/exec_tools.c0000644000000000000000000002156515010704253020224 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include // CloseLog /********************************************************************/ bool GetExecOutput(const char *command, char **buffer, size_t *buffer_size, ShellType shell, OutputSelect output_select, int *ret_out) /* Buffer initially contains whole exec string */ { FILE *pp; if (shell == SHELL_TYPE_USE) { pp = cf_popen_sh_select(command, "rt", output_select); } else if (shell == SHELL_TYPE_POWERSHELL) { #ifdef __MINGW32__ pp = cf_popen_powershell_select(command, "rt", output_select); #else // !__MINGW32__ Log(LOG_LEVEL_ERR, "Powershell is only supported on Windows"); return false; #endif // __MINGW32__ } else { pp = cf_popen_select(command, "rt", output_select); } if (pp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", command, GetErrorStr()); return false; } size_t offset = 0; size_t line_size = CF_EXPANDSIZE; size_t attempted_size = 0; char *line = xcalloc(1, line_size); while (*buffer_size < CF_MAXSIZE) { ssize_t res = CfReadLine(&line, &line_size, pp); if (res == -1) { if (!feof(pp)) { Log(LOG_LEVEL_ERR, "Unable to read output of command '%s'. (fread: %s)", command, GetErrorStr()); cf_pclose(pp); free(line); return false; } else { break; } } if ((attempted_size = snprintf(*buffer + offset, *buffer_size - offset, "%s\n", line)) >= *buffer_size - offset) { *buffer_size += (attempted_size > CF_EXPANDSIZE ? attempted_size : CF_EXPANDSIZE); *buffer = xrealloc(*buffer, *buffer_size); snprintf(*buffer + offset, *buffer_size - offset, "%s\n", line); } offset += strlen(line) + 1; } if (offset > 0) { if (Chop(*buffer, *buffer_size) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } } Log(LOG_LEVEL_DEBUG, "GetExecOutput got '%s'", *buffer); if (ret_out != NULL) { *ret_out = cf_pclose(pp); } else { cf_pclose(pp); } free(line); return true; } /**********************************************************************/ void ActAsDaemon() { int fd; #ifdef HAVE_SETSID if (setsid() == (pid_t) -1) { Log(LOG_LEVEL_WARNING, "Failed to become a session leader while daemonising (setsid: %s)", GetErrorStr()); } #endif CloseNetwork(); CloseLog(); fflush(NULL); /* Close descriptors 0,1,2 and reopen them with /dev/null. */ fd = open(NULLFILE, O_RDWR, 0); if (fd == -1) { Log(LOG_LEVEL_WARNING, "Could not open '%s', " "stdin/stdout/stderr are still open (open: %s)", NULLFILE, GetErrorStr()); } else { if (dup2(fd, STDIN_FILENO) == -1) { Log(LOG_LEVEL_WARNING, "Could not close stdin while daemonising (dup2: %s)", GetErrorStr()); } if (dup2(fd, STDOUT_FILENO) == -1) { Log(LOG_LEVEL_WARNING, "Could not close stdout while daemonising (dup2: %s)", GetErrorStr()); } if (dup2(fd, STDERR_FILENO) == -1) { Log(LOG_LEVEL_WARNING, "Could not close stderr while daemonising (dup2: %s)", GetErrorStr()); } if (fd > STDERR_FILENO) { close(fd); } } if (chdir("/")) { Log(LOG_LEVEL_WARNING, "Failed to chdir into '/' directory while daemonising (chdir: %s)", GetErrorStr()); } } /**********************************************************************/ /** * Split the command string like "/bin/echo -n Hi!" in two parts -- the * executable ("/bin/echo") and the arguments for the executable ("-n Hi!"). * * @param[in] comm the whole command to split * @param[out] exec pointer to **a newly allocated** string with the executable * @param[out] args pointer to **a newly allocated** string with the args * * @note Whitespace between the executable and the arguments is skipped. */ void ArgGetExecutableAndArgs(const char *comm, char **exec, char **args) { const char *s = comm; while (*s != '\0') { const char *end = NULL; if (isspace((int)*s)) /* Skip whitespace */ { s++; continue; } switch (*s) { case '"': /* Look for matching quote */ case '\'': case '`': { char delim = *(s++); /* Skip first delimeter */ end = strchr(s, delim); break; } default: /* Look for whitespace */ end = strpbrk(s, " \f\n\r\t\v"); break; } if (end == NULL) /* Delimeter was not found, remaining string is the executable */ { *exec = xstrdup(s); *args = NULL; return; } else { assert(end > s); const size_t length = end - s; *exec = xstrndup(s, length); const char *args_start = end; if (*(args_start + 1) != '\0') { args_start++; /* Skip second delimeter */ args_start += strspn(args_start, " \f\n\r\t\v"); /* Skip whitespace */ *args = xstrdup(args_start); } else { *args = NULL; } return; } } /* was not able to parse/split the command */ *exec = NULL; *args = NULL; return; } #define INITIAL_ARGS 8 char **ArgSplitCommand(const char *comm, const Seq *arglist) { const char *s = comm; int argc = 0; int argslen = INITIAL_ARGS; char **args = xmalloc(argslen * sizeof(char *)); while (*s != '\0') { const char *end; char *arg; if (isspace((int)*s)) /* Skip whitespace */ { s++; continue; } switch (*s) { case '"': /* Look for matching quote */ case '\'': case '`': { char delim = *s++; /* Skip first delimeter */ end = strchr(s, delim); break; } default: /* Look for whitespace */ end = strpbrk(s, " \f\n\r\t\v"); break; } if (end == NULL) /* Delimeter was not found, remaining string is the argument */ { arg = xstrdup(s); s += strlen(arg); } else { arg = xstrndup(s, end - s); s = end; if ((*s == '"') || (*s == '\'') || (*s == '`')) /* Skip second delimeter */ s++; } /* Argument */ if (argc == argslen) { argslen *= 2; args = xrealloc(args, argslen * sizeof(char *)); } args[argc++] = arg; } size_t extra = (arglist == NULL) ? 0 : SeqLength(arglist); if (argc + extra + 1 /* NULL */ > argslen) { args = xrealloc(args, (argc + extra + 1) * sizeof(char *)); } for (size_t i = 0; i < extra; i++) { args[argc++] = xstrdup(SeqAt(arglist, i)); } args[argc] = NULL; return args; } /**********************************************************************/ void ArgFree(char **args) { if (args != NULL) { for (char **arg = args; *arg; ++arg) { free(*arg); } free(args); } } cfengine-3.24.2/libpromises/dbm_lmdb.c0000644000000000000000000012122015010704253017605 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * Implementation using LMDB API. */ #include #include #include #include #include #include #include #include #ifdef LMDB #include #include #include /* cf_db_corruption_lock */ #include #include /* time() */ // Shared between threads. struct DBPriv_ { MDB_env *env; MDB_dbi dbi; // Used to keep track of transactions. // We set this to the transaction address when a thread creates a // transaction, and back to 0x0 when it is destroyed. pthread_key_t txn_key; }; // Not shared between threads. typedef struct DBTxn_ { MDB_txn *txn; // Whether txn is a read/write (true) or read-only (false) transaction. bool rw_txn; bool cursor_open; } DBTxn; struct DBCursorPriv_ { DBPriv *db; MDB_cursor *mc; MDB_val delkey; void *curkv; size_t curks; bool pending_delete; }; static int DB_MAX_READERS = -1; #define N_LMDB_EINVAL_RETRIES 5 /******************************************************************************/ static void HandleLMDBCorruption(MDB_env *env, const char *msg); static void HandleFullLMDB(MDB_env *env); static inline void CheckLMDBUsable(int rc, MDB_env *env) { if (rc == MDB_CORRUPTED) { HandleLMDBCorruption(env, ""); } else if (rc == MDB_MAP_FULL) { HandleFullLMDB(env); } } static int GetReadTransaction(DBPriv *const db, DBTxn **const txn) { assert(db != NULL); assert(txn != NULL); DBTxn *db_txn = pthread_getspecific(db->txn_key); int rc = MDB_SUCCESS; if (db_txn == NULL) { db_txn = xcalloc(1, sizeof(DBTxn)); pthread_setspecific(db->txn_key, db_txn); } if (db_txn->txn == NULL) { rc = mdb_txn_begin(db->env, NULL, MDB_RDONLY, &db_txn->txn); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Unable to open read transaction in '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); } } *txn = db_txn; return rc; } static int GetWriteTransaction(DBPriv *const db, DBTxn **const txn) { assert(db != NULL); assert(txn != NULL); DBTxn *db_txn = pthread_getspecific(db->txn_key); int rc = MDB_SUCCESS; if (db_txn == NULL) { db_txn = xcalloc(1, sizeof(DBTxn)); pthread_setspecific(db->txn_key, db_txn); } if (db_txn->txn != NULL && !db_txn->rw_txn) { rc = mdb_txn_commit(db_txn->txn); CheckLMDBUsable(rc, db->env); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Unable to close read-only transaction in '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); } db_txn->txn = NULL; } if (db_txn->txn == NULL) { rc = mdb_txn_begin(db->env, NULL, 0, &db_txn->txn); CheckLMDBUsable(rc, db->env); if (rc == MDB_SUCCESS) { db_txn->rw_txn = true; } else { Log(LOG_LEVEL_ERR, "Unable to open write transaction in '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); } } *txn = db_txn; return rc; } static void AbortTransaction(DBPriv *const db) { assert(db != NULL); DBTxn *db_txn = pthread_getspecific(db->txn_key); if (db_txn != NULL) { if (db_txn->txn != NULL) { mdb_txn_abort(db_txn->txn); } pthread_setspecific(db->txn_key, NULL); free(db_txn); } } static void DestroyTransaction(void *const ptr) { DBTxn *const db_txn = (DBTxn *)ptr; UnexpectedError("Transaction object still exists when terminating thread"); if (db_txn->txn) { UnexpectedError("Transaction still open when terminating thread!"); mdb_txn_abort(db_txn->txn); } free(db_txn); } const char *DBPrivGetFileExtension(void) { return "lmdb"; } /* NOTE: Must be in sync with LMDB_MAXSIZE in cf-check/diagnose.c. */ #ifndef LMDB_MAXSIZE #define LMDB_MAXSIZE 104857600 #endif void DBPrivSetMaximumConcurrentTransactions(const int max_txn) { DB_MAX_READERS = max_txn; } static int LmdbEnvOpen( MDB_env *const env, const char *const path, const unsigned int flags, const mdb_mode_t mode) { assert(env != NULL); // dereferenced in lmdb (mdb_env_open) assert(path != NULL); // dereferenced (strlen) in lmdb (mdb_env_open) assert(mdb_env_get_maxkeysize(env) == 511); // Search for 511 in locks.c /* There is a race condition in LMDB that will fail to open the database * environment if another process is opening it at the exact same time. This * condition is signaled by returning ENOENT, which we should never get * otherwise. This can lead to error messages on a heavily loaded machine, * so try to open it again after allowing other threads to finish their * opening process. */ int attempts = 5; while (attempts-- > 0) { int rc = mdb_env_open(env, path, flags, mode); if (rc != ENOENT) { return rc; } #if HAVE_DECL_SCHED_YIELD && defined(HAVE_SCHED_YIELD) // Not required for this to work, but makes it less likely that the race // condition will persist. sched_yield(); #endif } // Return EBUSY for an error message slightly more related to reality. return EBUSY; } /** * @warning Expects @fd_stamp to be locked. */ static bool RepairedAfterOpen(const char *lmdb_file, int fd_tstamp) { time_t repaired_tstamp = -1; ssize_t n_read = read(fd_tstamp, &repaired_tstamp, sizeof(time_t)); lseek(fd_tstamp, 0, SEEK_SET); if (n_read < 0) { Log(LOG_LEVEL_ERR, "Failed to read %s: %s", lmdb_file, GetErrorStr()); } else if (n_read == 0) { /* EOF (empty file) => never repaired */ Log(LOG_LEVEL_VERBOSE, "DB '%s' never repaired before", lmdb_file); } else if ((size_t) n_read < sizeof(time_t)) { /* error */ Log(LOG_LEVEL_ERR, "Failed to read the timestamp of repair of the '%s' DB", lmdb_file); } else { /* read the timestamp => Check if the LMDB file was repaired after * we opened it last time. Or, IOW, if this is a new corruption or * an already-handled one. */ DBHandle *handle = GetDBHandleFromFilename(lmdb_file); if (repaired_tstamp > GetDBOpenTimestamp(handle)) { return true; } } return false; } /** * @warning Expects @fd_stamp to be locked. */ static bool RotatedAfterOpen(const char *lmdb_file, int fd_tstamp) { time_t rotated_tstamp = -1; ssize_t n_read = read(fd_tstamp, &rotated_tstamp, sizeof(time_t)); lseek(fd_tstamp, 0, SEEK_SET); if (n_read < 0) { Log(LOG_LEVEL_ERR, "Failed to read %s: %s", lmdb_file, GetErrorStr()); } else if (n_read == 0) { /* EOF (empty file) => never rotated */ Log(LOG_LEVEL_VERBOSE, "DB '%s' never rotated before", lmdb_file); } else if ((size_t) n_read < sizeof(time_t)) { /* error */ Log(LOG_LEVEL_ERR, "Failed to read the timestamp of rotation of the '%s' DB", lmdb_file); } else { /* read the timestamp => Check if the LMDB file was rotated after * we opened it last time. */ DBHandle *handle = GetDBHandleFromFilename(lmdb_file); if (rotated_tstamp > GetDBOpenTimestamp(handle)) { return true; } } return false; } static void HandleLMDBCorruption(MDB_env *env, const char *msg) { const char *lmdb_file = mdb_env_get_userctx(env); Log(LOG_LEVEL_CRIT, "Corruption in the '%s' DB detected! %s", lmdb_file, msg); /* Freeze the DB ASAP. This also makes the call to exit() safe regarding * this particular DB because exit handlers will ignore it. */ DBHandle *handle = GetDBHandleFromFilename(lmdb_file); FreezeDB(handle); #ifdef __MINGW32__ /* Not much we can do on Windows because there is no fork() and file locking * is also not so nice. */ Log(LOG_LEVEL_WARNING, "Removing the corrupted DB file '%s'", lmdb_file); if (unlink(lmdb_file) != 0) { Log(LOG_LEVEL_CRIT, "Failed to remove the corrupted DB file '%s'", lmdb_file); exit(EC_CORRUPTION_REPAIR_FAILED); } exit(EC_CORRUPTION_REPAIRED); #else /* Try to handle the corruption gracefully by repairing the LMDB file * (replacing it with a new LMDB file with all the data we managed to read * from the corrupted one). */ /* To avoid two processes acting on the same corrupted file at once, file * locks are involved. Looking at OpenDBInstance() and DBPathLock() * in libpromises/db_api.c might also be useful.*/ /* Only allow one thread at a time to handle DB corruption. File locks are * *process* specific so threads could step on each others toes. */ ThreadLock(cft_db_corruption_lock); char *tstamp_file = StringFormat("%s.repaired", lmdb_file); char *db_lock_file = StringFormat("%s.lock", lmdb_file); int fd_tstamp = safe_open(tstamp_file, O_CREAT|O_RDWR); if (fd_tstamp == -1) { Log(LOG_LEVEL_CRIT, "Failed to open the '%s' DB repair timestamp file", lmdb_file); ThreadUnlock(cft_db_corruption_lock); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIR_FAILED); } FileLock tstamp_lock = { .fd = fd_tstamp }; int fd_db_lock = safe_open(db_lock_file, O_CREAT|O_RDWR); if (fd_db_lock == -1) { Log(LOG_LEVEL_CRIT, "Failed to open the '%s' DB lock file", lmdb_file); ThreadUnlock(cft_db_corruption_lock); close(fd_tstamp); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIR_FAILED); } FileLock db_lock = { .fd = fd_db_lock }; int ret; bool handle_corruption = true; /* Make sure we are not holding the DB's lock (potentially needed by some * other process for the repair) to avoid deadlocks. */ Log(LOG_LEVEL_DEBUG, "Releasing lock on the '%s' DB", lmdb_file); ExclusiveFileUnlock(&db_lock, false); /* close=false */ ret = SharedFileLock(&tstamp_lock, true); if (ret == 0) { if (RepairedAfterOpen(lmdb_file, fd_tstamp)) { /* The corruption has already been handled. This process should * just die because we have no way to return to the point where * it would just open the new (repaired) LMDB file. */ handle_corruption = false; } SharedFileUnlock(&tstamp_lock, false); } else { /* should never happen (we tried to wait), but if it does, just log an * error and keep going */ Log(LOG_LEVEL_ERR, "Failed to get shared lock for the repair timestamp of the '%s' DB", lmdb_file); } if (!handle_corruption) { /* Just clean after ourselves and terminate the process. */ ThreadUnlock(cft_db_corruption_lock); close(fd_db_lock); close(fd_tstamp); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIRED); } /* HERE is a window for some other process to do the repair between when we * checked the timestamp using the shared lock above and the attempt to get * the exclusive lock right below. However, this is detected by checking the * contents of the timestamp file again below, while holding the EXCLUSIVE * lock. */ ret = ExclusiveFileLock(&tstamp_lock, true); if (ret != 0) { /* should never happen (we tried to wait), but if it does, just * terminate because doing the repair without the lock could be * disasterous */ Log(LOG_LEVEL_ERR, "Failed to get shared lock for the repair timestamp of the '%s' DB", lmdb_file); ThreadUnlock(cft_db_corruption_lock); close(fd_db_lock); close(fd_tstamp); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIR_FAILED); } /* Cleared to resolve the corruption. */ /* 1. Acquire the lock for the DB to prevent more processes trying to use * it while it is corrupted (wait till the lock is available). */ while (ExclusiveFileLock(&db_lock, false) == -1) { /* busy wait to do the logging */ Log(LOG_LEVEL_INFO, "Waiting for the lock on the '%s' DB", lmdb_file); sleep(1); } /* 2. Check the last repair timestamp again (see the big "HERE..." comment * above) */ if (RepairedAfterOpen(lmdb_file, fd_tstamp)) { /* Some other process repaired the DB since we checked last time, * nothing more to do here. */ ThreadUnlock(cft_db_corruption_lock); close(fd_db_lock); /* releases locks */ close(fd_tstamp); /* releases locks */ free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIRED); } /* 3. Repair the DB or at least move it out of the way. */ /* repair_lmdb_file() forks so it is safe (file locks are not * inherited). */ ret = repair_lmdb_file(lmdb_file, fd_tstamp); /* repair_lmdb_file returns -1 in case of error, 0 in case of successfull * repair, >0 in case of failed repair, but successful remove */ bool repair_successful = (ret != -1); if (repair_successful) { Log(LOG_LEVEL_NOTICE, "DB '%s' successfully repaired", lmdb_file); } else { Log(LOG_LEVEL_CRIT, "Failed to repair DB '%s'", lmdb_file); } /* 4. Make the repaired DB available for others. Also release the locks * in the opposite order in which they were acquired to avoid * deadlocks. */ if (ExclusiveFileUnlock(&db_lock, true) != 0) { Log(LOG_LEVEL_ERR, "Failed to release the acquired lock for '%s'", db_lock_file); } /* 5. Signal that the repair is done (also closes fd_tstamp). */ if (ExclusiveFileUnlock(&tstamp_lock, true) != 0) { Log(LOG_LEVEL_ERR, "Failed to release the acquired lock for '%s'", tstamp_file); } ThreadUnlock(cft_db_corruption_lock); free(db_lock_file); free(tstamp_file); /* fd_db_lock and fd_tstamp are already closed by the calls to * ExclusiveFileUnlock above. */ if (repair_successful) { exit(EC_CORRUPTION_REPAIRED); } else { exit(EC_CORRUPTION_REPAIR_FAILED); } #endif /* __MINGW32__ */ } /** * A modified clone of HandleLMDBCorruption() for handling full LMDBs. It's not * easy and nice to share much code between the two functions, unfortunately. */ static void HandleFullLMDB(MDB_env *env) { const char *lmdb_file = mdb_env_get_userctx(env); Log(LOG_LEVEL_CRIT, "'%s' DB full!", lmdb_file); /* Freeze the DB ASAP. This also makes the call to exit() safe regarding * this particular DB because exit handlers will ignore it. */ DBHandle *handle = GetDBHandleFromFilename(lmdb_file); FreezeDB(handle); #ifdef _WIN32 /* Not much we can do on Windows because there is no fork() and file locking * is also not so nice. */ Log(LOG_LEVEL_WARNING, "Moving the full DB file '%s' aside", lmdb_file); time_t now = time(NULL); char *rotated_file = StringFormat("%s.rotated.%jd", lmdb_file, (intmax_t) now); if (rename(lmdb_file, rotated_file) != 0) { free(rotated_file); Log(LOG_LEVEL_CRIT, "Failed to move the full DB file '%s' aside (%s), will be removed instead", lmdb_file, GetErrorStr()); if (unlink(lmdb_file) != 0) { Log(LOG_LEVEL_CRIT, "Failed to remove the full DB file '%s': %s", lmdb_file, GetErrorStr()); } exit(EC_CORRUPTION_REPAIR_FAILED); } free(rotated_file); exit(EC_CORRUPTION_REPAIRED); #else /* To avoid two processes acting on the same corrupted file at once, file * locks are involved. Looking at OpenDBInstance() and DBPathLock() * in libpromises/db_api.c might also be useful.*/ /* Only allow one thread at a time to handle a full or corrupted DB. File * locks are *process* specific so threads could step on each others * toes. */ ThreadLock(cft_db_corruption_lock); char *tstamp_file = StringFormat("%s.rotated", lmdb_file); char *db_lock_file = StringFormat("%s.lock", lmdb_file); int fd_tstamp = safe_open(tstamp_file, O_CREAT|O_RDWR); if (fd_tstamp == -1) { Log(LOG_LEVEL_CRIT, "Failed to open the '%s' DB rotation timestamp file", lmdb_file); ThreadUnlock(cft_db_corruption_lock); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIR_FAILED); } FileLock tstamp_lock = { .fd = fd_tstamp }; int fd_db_lock = safe_open(db_lock_file, O_CREAT|O_RDWR); if (fd_db_lock == -1) { Log(LOG_LEVEL_CRIT, "Failed to open the '%s' DB lock file", lmdb_file); ThreadUnlock(cft_db_corruption_lock); close(fd_tstamp); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIR_FAILED); } FileLock db_lock = { .fd = fd_db_lock }; int ret; bool handle_rotation = true; /* Make sure we are not holding the DB's lock (potentially needed by some * other process for the repair or rotation) to avoid deadlocks. */ Log(LOG_LEVEL_DEBUG, "Releasing lock on the '%s' DB", lmdb_file); ExclusiveFileUnlock(&db_lock, false); /* close=false */ ret = SharedFileLock(&tstamp_lock, true); if (ret == 0) { if (RotatedAfterOpen(lmdb_file, fd_tstamp)) { /* The corruption has already been handled. This process should just * die because we have no way to return to the point where it would * just open the new (repaired or rotated) LMDB file. */ handle_rotation = false; } SharedFileUnlock(&tstamp_lock, false); } else { /* should never happen (we tried to wait), but if it does, just log an * error and keep going */ Log(LOG_LEVEL_ERR, "Failed to get shared lock for the rotation timestamp of the '%s' DB", lmdb_file); } if (!handle_rotation) { /* Just clean after ourselves and terminate the process. */ ThreadUnlock(cft_db_corruption_lock); close(fd_db_lock); close(fd_tstamp); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIRED); } /* HERE is a window for some other process to do the rotation between when we * checked the timestamp using the shared lock above and the attempt to get * the exclusive lock right below. However, this is detected by checking the * contents of the timestamp file again below, while holding the EXCLUSIVE * lock. */ ret = ExclusiveFileLock(&tstamp_lock, true); if (ret != 0) { /* should never happen (we tried to wait), but if it does, just * terminate because doing the rotation without the lock could be * disasterous */ Log(LOG_LEVEL_ERR, "Failed to get shared lock for the rotation timestamp of the '%s' DB", lmdb_file); ThreadUnlock(cft_db_corruption_lock); close(fd_db_lock); close(fd_tstamp); free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIR_FAILED); } /* Cleared to resolve the corruption. */ /* 1. Acquire the lock for the DB to prevent more processes trying to use * it while it is corrupted (wait till the lock is available). */ while (ExclusiveFileLock(&db_lock, false) == -1) { /* busy wait to do the logging */ Log(LOG_LEVEL_INFO, "Waiting for the lock on the '%s' DB", lmdb_file); sleep(1); } /* 2. Check the last rotation timestamp again (see the big "HERE..." comment * above) */ if (RotatedAfterOpen(lmdb_file, fd_tstamp)) { /* Some other process rotated the DB since we checked last time, * nothing more to do here. */ ThreadUnlock(cft_db_corruption_lock); close(fd_db_lock); /* releases locks */ close(fd_tstamp); /* releases locks */ free(db_lock_file); free(tstamp_file); exit(EC_CORRUPTION_REPAIRED); } /* 3. Rotate the DB or at least move it out of the way. */ ret = rotate_lmdb_file(lmdb_file, fd_tstamp); bool rotation_successful = (ret == 0); if (rotation_successful) { Log(LOG_LEVEL_NOTICE, "DB '%s' successfully rotated", lmdb_file); } else { Log(LOG_LEVEL_CRIT, "Failed to rotate '%s' DB", lmdb_file); } /* 4. Make the rotated DB available for others. Also release the locks * in the opposite order in which they were acquired to avoid * deadlocks. */ if (ExclusiveFileUnlock(&db_lock, true) != 0) { Log(LOG_LEVEL_ERR, "Failed to release the acquired lock for '%s'", db_lock_file); } /* 5. Signal that the rotation is done (also closes fd_tstamp). */ if (ExclusiveFileUnlock(&tstamp_lock, true) != 0) { Log(LOG_LEVEL_ERR, "Failed to release the acquired lock for '%s'", tstamp_file); } ThreadUnlock(cft_db_corruption_lock); free(db_lock_file); free(tstamp_file); /* fd_db_lock and fd_tstamp are already closed by the calls to * ExclusiveFileUnlock above. */ if (rotation_successful) { exit(EC_CORRUPTION_REPAIRED); } else { exit(EC_CORRUPTION_REPAIR_FAILED); } #endif /* _WIN32 */ } DBPriv *DBPrivOpenDB(const char *const dbpath, const dbid id) { DBPriv *const db = xcalloc(1, sizeof(DBPriv)); MDB_txn *txn = NULL; int rc = pthread_key_create(&db->txn_key, &DestroyTransaction); if (rc) { Log(LOG_LEVEL_ERR, "Could not create transaction key. (pthread_key_create: '%s')", GetErrorStrFromCode(rc)); free(db); return NULL; } rc = mdb_env_create(&db->env); if (rc) { Log(LOG_LEVEL_ERR, "Could not create handle for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } rc = mdb_env_set_userctx(db->env, xstrdup(dbpath)); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_WARNING, "Could not store DB file path (%s) in the DB context", dbpath); } rc = mdb_env_set_assert(db->env, (MDB_assert_func*) HandleLMDBCorruption); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_WARNING, "Could not set the corruption handler for '%s'", dbpath); } rc = mdb_env_set_mapsize(db->env, LMDB_MAXSIZE); if (rc) { Log(LOG_LEVEL_ERR, "Could not set mapsize for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } if (DB_MAX_READERS > 0) { rc = mdb_env_set_maxreaders(db->env, DB_MAX_READERS); if (rc) { Log(LOG_LEVEL_ERR, "Could not set maxreaders for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } } unsigned int open_flags = MDB_NOSUBDIR; #if !defined(_AIX) && !defined(__sun) /* The locks and lastseen (on hubs) DBs are heavily used and using * MDB_NOSYNC increases performance. However, AIX and Solaris often suffer * from some serious issues with consistency (ENT-4002) so it's better to * sacrifice some performance there in favor of stability. */ if (id == dbid_locks || (GetAmPolicyHub() && id == dbid_lastseen)) { open_flags |= MDB_NOSYNC; } #endif #ifdef __hpux /* * On HP-UX, a unified file cache was not introduced until version 11.31. * This means that on 11.23 there are separate file caches for mmap()'ed * files and open()'ed files. When these two are mixed, changes made using * one mode won't be immediately seen by the other mode, which is an * assumption LMDB is relying on. The MDB_WRITEMAP flag causes LMDB to use * mmap() only, so that we stay within one file cache. */ open_flags |= MDB_WRITEMAP; #endif rc = LmdbEnvOpen(db->env, dbpath, open_flags, CF_PERMS_DEFAULT); if (rc) { Log(LOG_LEVEL_ERR, "Could not open database %s: %s", dbpath, mdb_strerror(rc)); if (rc == MDB_CORRUPTED || rc == MDB_INVALID) { HandleLMDBCorruption(db->env, mdb_strerror(rc)); } goto err; } if (DB_MAX_READERS > 0) { int max_readers; rc = mdb_env_get_maxreaders(db->env, &max_readers); if (rc) { Log(LOG_LEVEL_ERR, "Could not get maxreaders for database %s: %s", dbpath, mdb_strerror(rc)); goto err; } if (max_readers < DB_MAX_READERS) { // LMDB will only reinitialize maxreaders if no database handles are // open, including in other processes, which is how we might end up // here. Log(LOG_LEVEL_VERBOSE, "Failed to set LMDB max reader limit on database '%s', " "consider restarting CFEngine", dbpath); } } /* There seems to be a race condition causing mdb_txn_begin() return * EINVAL. We do a couple retries before giving up. */ rc = mdb_txn_begin(db->env, NULL, MDB_RDONLY, &txn); int attempts = N_LMDB_EINVAL_RETRIES; while ((rc != 0) && (attempts-- > 0)) { CheckLMDBUsable(rc, db->env); if (rc != EINVAL) { Log(LOG_LEVEL_ERR, "Could not open database txn %s: %s", dbpath, mdb_strerror(rc)); goto err; } #if HAVE_DECL_SCHED_YIELD && defined(HAVE_SCHED_YIELD) // Not required for this to work, but makes it less likely that the race // condition will persist. sched_yield(); #endif rc = mdb_txn_begin(db->env, NULL, MDB_RDONLY, &txn); } if (rc != 0) { Log(LOG_LEVEL_ERR, "Could not open database txn %s: %s", dbpath, mdb_strerror(rc)); goto err; } rc = mdb_open(txn, NULL, 0, &db->dbi); CheckLMDBUsable(rc, db->env); if (rc) { Log(LOG_LEVEL_ERR, "Could not open database dbi %s: %s", dbpath, mdb_strerror(rc)); mdb_txn_abort(txn); goto err; } rc = mdb_txn_commit(txn); CheckLMDBUsable(rc, db->env); if (rc) { Log(LOG_LEVEL_ERR, "Could not commit database dbi %s: %s", dbpath, mdb_strerror(rc)); goto err; } return db; err: if (db->env) { mdb_env_close(db->env); } pthread_key_delete(db->txn_key); free(db); if (rc == MDB_INVALID) { return DB_PRIV_DATABASE_BROKEN; } return NULL; } void DBPrivCloseDB(DBPriv *db) { assert(db != NULL); /* Abort LMDB transaction of the current thread. There should only be some * transaction open when the signal handler or atexit() hook is called. */ AbortTransaction(db); char *db_path = mdb_env_get_userctx(db->env); if (db_path) { free(db_path); } if (db->env) { mdb_env_close(db->env); } pthread_key_delete(db->txn_key); free(db); } #define EMPTY_DB 0 bool DBPrivClean(DBPriv *db) { assert(db != NULL); DBTxn *txn; const int rc = GetWriteTransaction(db, &txn); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Unable to get write transaction for '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); return false; } assert(txn != NULL); assert(!txn->cursor_open); return (mdb_drop(txn->txn, db->dbi, EMPTY_DB) != 0); } int DBPrivGetDBUsagePercentage(const char *db_path) { struct stat sb; int ret = stat(db_path, &sb); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to get size of '%s': %s", db_path, GetErrorStr()); return -1; } return (int) ((((float) sb.st_size) / LMDB_MAXSIZE) * 100); } void DBPrivCommit(DBPriv *db) { assert(db != NULL); DBTxn *db_txn = pthread_getspecific(db->txn_key); if (db_txn != NULL && db_txn->txn != NULL) { assert(!db_txn->cursor_open); const int rc = mdb_txn_commit(db_txn->txn); CheckLMDBUsable(rc, db->env); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not commit database transaction to '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); } } pthread_setspecific(db->txn_key, NULL); free(db_txn); } bool DBPrivHasKey(DBPriv *db, const void *key, int key_size) { assert(db != NULL); MDB_val mkey, data; DBTxn *txn; // FIXME: distinguish between "entry not found" and "error occurred" int rc = GetReadTransaction(db, &txn); if (rc == MDB_SUCCESS) { assert(!txn->cursor_open); mkey.mv_data = (void *) key; mkey.mv_size = key_size; rc = mdb_get(txn->txn, db->dbi, &mkey, &data); CheckLMDBUsable(rc, db->env); if (rc != 0 && rc != MDB_NOTFOUND) { Log(LOG_LEVEL_ERR, "Could not read database entry from '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); } } return (rc == MDB_SUCCESS); } int DBPrivGetValueSize(DBPriv *const db, const void *const key, const int key_size) { assert(db != NULL); assert(key_size >= 0); MDB_val mkey, data; DBTxn *txn; data.mv_size = 0; int rc = GetReadTransaction(db, &txn); if (rc == MDB_SUCCESS) { assert(!txn->cursor_open); mkey.mv_data = (void *) key; mkey.mv_size = key_size; rc = mdb_get(txn->txn, db->dbi, &mkey, &data); CheckLMDBUsable(rc, db->env); if (rc && rc != MDB_NOTFOUND) { Log(LOG_LEVEL_ERR, "Could not read database entry from '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); } } size_t ret = data.mv_size; assert(ret <= INT_MAX); return ret; } bool DBPrivRead( DBPriv *const db, const void *const key, const int key_size, void *const dest, size_t dest_size) { assert(db != NULL); assert(key_size >= 0); DBTxn *txn; bool ret = false; int rc = GetReadTransaction(db, &txn); if (rc == MDB_SUCCESS) { MDB_val mkey, data; assert(txn != NULL); assert(!txn->cursor_open); mkey.mv_data = (void *) key; mkey.mv_size = key_size; rc = mdb_get(txn->txn, db->dbi, &mkey, &data); CheckLMDBUsable(rc, db->env); if (rc == MDB_SUCCESS) { if (dest_size > data.mv_size) { dest_size = data.mv_size; } memcpy(dest, data.mv_data, dest_size); ret = true; } else if (rc != MDB_NOTFOUND) { Log(LOG_LEVEL_ERR, "Could not read database entry from '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); } } return ret; } bool DBPrivWrite( DBPriv *const db, const void *const key, const int key_size, const void *const value, const int value_size) { assert(db != NULL); assert(key_size >= 0); DBTxn *txn; int rc = GetWriteTransaction(db, &txn); if (rc == MDB_SUCCESS) { MDB_val mkey, data; assert(txn != NULL); assert(!txn->cursor_open); mkey.mv_data = (void *) key; mkey.mv_size = key_size; data.mv_data = (void *)value; data.mv_size = value_size; rc = mdb_put(txn->txn, db->dbi, &mkey, &data, 0); CheckLMDBUsable(rc, db->env); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not write database entry to '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); } } return (rc == MDB_SUCCESS); } bool DBPrivOverwrite(DBPriv *db, const char *key, int key_size, const void *value, size_t value_size, OverwriteCondition Condition, void *data) { assert(db != NULL); assert(key_size >= 0); DBTxn *txn; int rc = GetWriteTransaction(db, &txn); if (rc != MDB_SUCCESS) { return false; } assert(txn != NULL); assert(!txn->cursor_open); MDB_val mkey, orig_data; mkey.mv_data = (void *) key; mkey.mv_size = key_size; rc = mdb_get(txn->txn, db->dbi, &mkey, &orig_data); CheckLMDBUsable(rc, db->env); if ((rc != MDB_SUCCESS) && (rc != MDB_NOTFOUND)) { Log(LOG_LEVEL_ERR, "Could not read database entry from '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); return false; } if (Condition != NULL) { if (rc == MDB_SUCCESS) { assert(orig_data.mv_size > 0); /* We have to copy the data because orig_data.mv_data is a pointer to * the mmap()-ed area which can potentially have bad alignment causing * a SIGBUS on some architectures. */ unsigned char cur_val[orig_data.mv_size]; memcpy(cur_val, orig_data.mv_data, orig_data.mv_size); if (!Condition(cur_val, orig_data.mv_size, data)) { AbortTransaction(db); return false; } } else { assert(rc == MDB_NOTFOUND); if (!Condition(NULL, 0, data)) { AbortTransaction(db); return false; } } } MDB_val new_data; new_data.mv_data = (void *)value; new_data.mv_size = value_size; rc = mdb_put(txn->txn, db->dbi, &mkey, &new_data, 0); CheckLMDBUsable(rc, db->env); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not write database entry to '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); return false; } DBPrivCommit(db); return true; } bool DBPrivDelete(DBPriv *const db, const void *const key, const int key_size) { assert(key_size >= 0); assert(db != NULL); MDB_val mkey; DBTxn *txn; int rc = GetWriteTransaction(db, &txn); if (rc == MDB_SUCCESS) { assert(!txn->cursor_open); mkey.mv_data = (void *) key; mkey.mv_size = key_size; rc = mdb_del(txn->txn, db->dbi, &mkey, NULL); CheckLMDBUsable(rc, db->env); if (rc == MDB_NOTFOUND) { Log(LOG_LEVEL_DEBUG, "Entry not found in '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); } else if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not delete from '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); } } return (rc == MDB_SUCCESS); } DBCursorPriv *DBPrivOpenCursor(DBPriv *const db) { assert(db != NULL); DBCursorPriv *cursor = NULL; DBTxn *txn; MDB_cursor *mc; int rc = GetWriteTransaction(db, &txn); if (rc == MDB_SUCCESS) { assert(!txn->cursor_open); rc = mdb_cursor_open(txn->txn, db->dbi, &mc); CheckLMDBUsable(rc, db->env); if (rc == MDB_SUCCESS) { cursor = xcalloc(1, sizeof(DBCursorPriv)); cursor->db = db; cursor->mc = mc; txn->cursor_open = true; } else { Log(LOG_LEVEL_ERR, "Could not open cursor in '%s': %s", (char *) mdb_env_get_userctx(db->env), mdb_strerror(rc)); AbortTransaction(db); } /* txn remains with cursor */ } return cursor; } bool DBPrivAdvanceCursor( DBCursorPriv *const cursor, void **const key, int *const key_size, void **const value, int *const value_size) { assert(cursor != NULL); assert(cursor->db != NULL); MDB_val mkey, data; bool retval = false; if (cursor->curkv != NULL) { free(cursor->curkv); cursor->curkv = NULL; } int rc = mdb_cursor_get(cursor->mc, &mkey, &data, MDB_NEXT); CheckLMDBUsable(rc, cursor->db->env); if (rc == MDB_SUCCESS) { // Align second buffer to 64-bit boundary, to avoid alignment errors on // certain platforms. size_t keybuf_size = mkey.mv_size; if (keybuf_size & 0x7) { keybuf_size += 8 - (keybuf_size % 8); } cursor->curkv = xmalloc(keybuf_size + data.mv_size); memcpy(cursor->curkv, mkey.mv_data, mkey.mv_size); cursor->curks = mkey.mv_size; *key = cursor->curkv; *key_size = mkey.mv_size; *value_size = data.mv_size; memcpy((char *) cursor->curkv + keybuf_size, data.mv_data, data.mv_size); *value = ((char *) cursor->curkv + keybuf_size); retval = true; } else if (rc != MDB_NOTFOUND) { Log(LOG_LEVEL_ERR, "Could not advance cursor in '%s': %s", (char *) mdb_env_get_userctx(cursor->db->env), mdb_strerror(rc)); } if (cursor->pending_delete) { int r2; /* Position on key to delete */ r2 = mdb_cursor_get(cursor->mc, &cursor->delkey, NULL, MDB_SET); if (r2 == MDB_SUCCESS) { r2 = mdb_cursor_del(cursor->mc, 0); // TODO: Should the return value be checked? } /* Reposition the cursor if it was valid before */ if (rc == MDB_SUCCESS) { mkey.mv_data = *key; rc = mdb_cursor_get(cursor->mc, &mkey, NULL, MDB_SET); CheckLMDBUsable(rc, cursor->db->env); // TODO: Should the return value be checked? } cursor->pending_delete = false; } return retval; } bool DBPrivDeleteCursorEntry(DBCursorPriv *const cursor) { assert(cursor != NULL); int rc = mdb_cursor_get(cursor->mc, &cursor->delkey, NULL, MDB_GET_CURRENT); CheckLMDBUsable(rc, cursor->db->env); if (rc == MDB_SUCCESS) { cursor->pending_delete = true; } return (rc == MDB_SUCCESS); } bool DBPrivWriteCursorEntry( DBCursorPriv *const cursor, const void *const value, const int value_size) { assert(cursor != NULL); assert(cursor->db != NULL); MDB_val data; int rc; cursor->pending_delete = false; data.mv_data = (void *) value; data.mv_size = value_size; if (cursor->curkv) { MDB_val curkey; curkey.mv_data = cursor->curkv; curkey.mv_size = cursor->curks; rc = mdb_cursor_put(cursor->mc, &curkey, &data, MDB_CURRENT); CheckLMDBUsable(rc, cursor->db->env); if (rc != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not write cursor entry to '%s': %s", (char *) mdb_env_get_userctx(cursor->db->env), mdb_strerror(rc)); } } else { Log(LOG_LEVEL_ERR, "Could not write cursor entry to '%s': cannot find current key", (char *) mdb_env_get_userctx(cursor->db->env)); rc = MDB_INVALID; } return (rc == MDB_SUCCESS); } void DBPrivCloseCursor(DBCursorPriv *const cursor) { assert(cursor != NULL); assert(cursor->db != NULL); DBTxn *txn; const int rc = GetWriteTransaction(cursor->db, &txn); CF_ASSERT(rc == MDB_SUCCESS, "Could not get write transaction"); CF_ASSERT(txn->cursor_open, "Transaction not open"); txn->cursor_open = false; if (cursor->curkv) { free(cursor->curkv); } if (cursor->pending_delete) { mdb_cursor_del(cursor->mc, 0); } mdb_cursor_close(cursor->mc); free(cursor); } char *DBPrivDiagnose(const char *const dbpath) { return StringFormat("Unable to diagnose LMDB file (not implemented) for '%s'", dbpath); } #endif cfengine-3.24.2/libpromises/string_expressions.h0000644000000000000000000000573515010704253022036 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_STRING_EXPRESSIONS_H #define CFENGINE_STRING_EXPRESSIONS_H /* String expressions grammar: ::= ::= ::= [a-zA-Z0-9_:]+ ::= $( ) ${ } ::= . Subsequent s are concatenated during evaluation. */ typedef enum { CONCAT, LITERAL, VARREF } StringOp; typedef enum { VAR_REF_TYPE_SCALAR, VAR_REF_TYPE_LIST } VarRefType; typedef struct StringExpression_ StringExpression; struct StringExpression_ { StringOp op; union StringExpressionValue { struct { StringExpression *lhs; StringExpression *rhs; } concat; struct { char *literal; } literal; struct { StringExpression *name; VarRefType type; } varref; } val; }; /* Parsing and evaluation */ /* * Result of parsing. * * if succeeded, then result is the result of parsing and position is last * character consumed. * * if not succeeded, then result is NULL and position is last character consumed * before the error. */ typedef struct { StringExpression *result; int position; } StringParseResult; StringParseResult ParseStringExpression(const char *expr, int start, int end); /* * Evaluator should return either heap-allocated string or NULL. In later case * evaluation will be aborted and NULL will be returned from * EvalStringExpression. */ typedef char *(*VarRefEvaluator) (const char *varname, VarRefType type, void *param); /* * Result is heap-allocated. In case evalfn() returns NULL whole * EvalStringExpression returns NULL as well. */ char *EvalStringExpression(const StringExpression *expr, VarRefEvaluator evalfn, void *param); /* * Frees StringExpression produced by ParseStringExpression. NULL-safe. */ void FreeStringExpression(StringExpression *expr); #endif cfengine-3.24.2/libpromises/enterprise_extension.h0000644000000000000000000047642115010704322022343 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* #### THIS FILE WAS AUTOGENERATED FROM extensions_template.[ch].pre #### */ /******************************************************************************* * Note: This shared library calling mechanism should only be used for private * shared libraries, such as the Enterprise plugins for CFEngine. ******************************************************************************/ /******************************************************************************* * How to use the Extension calling API: * * In the application: * * - Declare function prototypes using the ENTERPRISE_FUNC_xARG_DECLARE macros. * Replace x with the number of arguments to the function. * * - Define a stub function using the ENTERPRISE_FUNC_xARG_DEFINE_STUB macros. * * In the Enterprise plugin: * * - Include the same prototype as you used in the application. * * - Define the Enterprise function with the ENTERPRISE_FUNC_xARG_DEFINE * macros. * * IMPORTANT: * * - For functions returning void, you need to use the VOID_FUNC version of the * macros. * * - Due to macro limitations, for each function argument, you need to put the * type and the name as separate arguments, so instead of (int par), use * (int, par). * * - You can use the function normally in your code. If the Enterprise plugin * is available, it will call that function, if not, it will call the stub * function. * * - The lookup is more expensive than a normal function call. Don't use it in * a tight loop. * * - Be careful when changing the function signature. The plugin needs * to stay binary compatible, otherwise the it will not work, and may even * crash. Signature changes should only happen between major releases. * * Examples: * * - int EnterpriseOnlyInt(const char *str, int num) becomes * ENTERPRISE_FUNC_2ARG_DECLARE(int, EnterpriseOnlyInt, * const char *, str, int, num) * ENTERPRISE_FUNC_2ARG_DEFINE_STUB(int, EnterpriseOnlyInt, * const char *, str, int, num) * ENTERPRISE_FUNC_2ARG_DEFINE(int, EnterpriseOnlyInt, * const char *, str, int, num) * * - void EnterpriseFunc(int num) becomes * ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, EnterpriseFunc, int, num) * ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, EnterpriseFunc, int, num) * ENTERPRISE_VOID_FUNC_1ARG_DEFINE(void, EnterpriseFunc, int, num) ******************************************************************************/ /******************************************************************************* * It may be easier to understand the implementation below by looking at the * output it actually produces. gcc -E is your friend. ******************************************************************************/ #ifndef ENTERPRISE_EXTENSION_H #define ENTERPRISE_EXTENSION_H #include #include #include #ifndef BUILTIN_EXTENSIONS #define ENTERPRISE_CANARY_VALUE 0x10203040 #define ENTERPRISE_LIBRARY_NAME "cfengine-enterprise.so" void *enterprise_library_open(); void enterprise_library_close(void *handle); #ifndef BUILDING_ENTERPRISE_EXTENSION # define ENTERPRISE_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ __ret __func() # define ENTERPRISE_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func(__t1 __p1) # define ENTERPRISE_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func(__t1 __p1, __t2 __p2) # define ENTERPRISE_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3) # define ENTERPRISE_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define ENTERPRISE_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define ENTERPRISE_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define ENTERPRISE_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define ENTERPRISE_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define ENTERPRISE_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define ENTERPRISE_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define ENTERPRISE_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define ENTERPRISE_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define ENTERPRISE_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define ENTERPRISE_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define ENTERPRISE_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) # define ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) \ __ret __func##__stub() # define ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__stub(__t1 __p1) # define ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__stub(__t1 __p1, __t2 __p2) # define ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3) # define ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) #else // BUILDING_ENTERPRISE_EXTENSION # define ENTERPRISE_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, int32_t __end_canary) # define ENTERPRISE_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, int32_t __end_canary) # define ENTERPRISE_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, int32_t __end_canary) # define ENTERPRISE_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, int32_t __end_canary) # define ENTERPRISE_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, int32_t __end_canary) # define ENTERPRISE_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, int32_t __end_canary) # define ENTERPRISE_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, int32_t __end_canary) # define ENTERPRISE_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, int32_t __end_canary) # define ENTERPRISE_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, int32_t __end_canary) # define ENTERPRISE_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, int32_t __end_canary) # define ENTERPRISE_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, int32_t __end_canary) # define ENTERPRISE_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, int32_t __end_canary) # define ENTERPRISE_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, int32_t __end_canary) # define ENTERPRISE_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, int32_t __end_canary) # define ENTERPRISE_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, int32_t __end_canary) # define ENTERPRISE_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__wrapper(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15, int32_t __end_canary) # define ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) \ __ret __func##__real() # define ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__real(__t1 __p1) # define ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__real(__t1 __p1, __t2 __p2) # define ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3) # define ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__real(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) # define ENTERPRISE_FUNC_0ARG_INLINE_SIGNATURE(__ret, __func) \ inline static __ret __func() # define ENTERPRISE_FUNC_1ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1) \ inline static __ret __func(__t1 __p1) # define ENTERPRISE_FUNC_2ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ inline static __ret __func(__t1 __p1, __t2 __p2) # define ENTERPRISE_FUNC_3ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3) # define ENTERPRISE_FUNC_4ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define ENTERPRISE_FUNC_5ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define ENTERPRISE_FUNC_6ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define ENTERPRISE_FUNC_7ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define ENTERPRISE_FUNC_8ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define ENTERPRISE_FUNC_9ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define ENTERPRISE_FUNC_10ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define ENTERPRISE_FUNC_11ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define ENTERPRISE_FUNC_12ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define ENTERPRISE_FUNC_13ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define ENTERPRISE_FUNC_14ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define ENTERPRISE_FUNC_15ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ inline static __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) #endif // BUILDING_ENTERPRISE_EXTENSION #ifndef BUILDING_ENTERPRISE_EXTENSION # define ENTERPRISE_FUNC_0ARG_DECLARE_IMPL(__ret, __func) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, int32_t __end_canary); \ ENTERPRISE_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func); \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define ENTERPRISE_FUNC_1ARG_DECLARE_IMPL(__ret, __func, __t1, __p1) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, int32_t __end_canary); \ ENTERPRISE_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1); \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define ENTERPRISE_FUNC_2ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, int32_t __end_canary); \ ENTERPRISE_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2); \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define ENTERPRISE_FUNC_3ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, int32_t __end_canary); \ ENTERPRISE_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3); \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define ENTERPRISE_FUNC_4ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, int32_t __end_canary); \ ENTERPRISE_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4); \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define ENTERPRISE_FUNC_5ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, int32_t __end_canary); \ ENTERPRISE_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5); \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define ENTERPRISE_FUNC_6ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, int32_t __end_canary); \ ENTERPRISE_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6); \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define ENTERPRISE_FUNC_7ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, int32_t __end_canary); \ ENTERPRISE_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7); \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define ENTERPRISE_FUNC_8ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, int32_t __end_canary); \ ENTERPRISE_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8); \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define ENTERPRISE_FUNC_9ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, int32_t __end_canary); \ ENTERPRISE_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9); \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define ENTERPRISE_FUNC_10ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, int32_t __end_canary); \ ENTERPRISE_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10); \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define ENTERPRISE_FUNC_11ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, int32_t __end_canary); \ ENTERPRISE_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11); \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define ENTERPRISE_FUNC_12ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, int32_t __end_canary); \ ENTERPRISE_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12); \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define ENTERPRISE_FUNC_13ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, int32_t __end_canary); \ ENTERPRISE_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13); \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define ENTERPRISE_FUNC_14ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, int32_t __end_canary); \ ENTERPRISE_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14); \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define ENTERPRISE_FUNC_15ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ typedef __ret (*__func##__type)(int32_t __start_canary, int *__successful, __t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15, int32_t __end_canary); \ ENTERPRISE_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15); \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) # define ENTERPRISE_FUNC_0ARG_DECLARE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_DECLARE_IMPL(__ret, __func) # define ENTERPRISE_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_DECLARE_IMPL(__ret, __func, __t1, __p1) # define ENTERPRISE_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2) # define ENTERPRISE_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define ENTERPRISE_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define ENTERPRISE_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define ENTERPRISE_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define ENTERPRISE_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define ENTERPRISE_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define ENTERPRISE_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define ENTERPRISE_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define ENTERPRISE_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define ENTERPRISE_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define ENTERPRISE_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define ENTERPRISE_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define ENTERPRISE_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) # define ENTERPRISE_VOID_FUNC_0ARG_DECLARE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_DECLARE_IMPL(__ret, __func) # define ENTERPRISE_VOID_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_DECLARE_IMPL(__ret, __func, __t1, __p1) # define ENTERPRISE_VOID_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2) # define ENTERPRISE_VOID_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define ENTERPRISE_VOID_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define ENTERPRISE_VOID_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define ENTERPRISE_VOID_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define ENTERPRISE_VOID_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define ENTERPRISE_VOID_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define ENTERPRISE_VOID_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define ENTERPRISE_VOID_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define ENTERPRISE_VOID_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define ENTERPRISE_VOID_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define ENTERPRISE_VOID_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define ENTERPRISE_VOID_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define ENTERPRISE_VOID_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_DECLARE_IMPL(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #else // BUILDING_ENTERPRISE_EXTENSION # define ENTERPRISE_FUNC_0ARG_DECLARE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func); \ ENTERPRISE_FUNC_0ARG_INLINE_SIGNATURE(__ret, __func) \ { \ return __func##__real(); \ } \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define ENTERPRISE_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1); \ ENTERPRISE_FUNC_1ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1) \ { \ return __func##__real(__p1); \ } \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define ENTERPRISE_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2); \ ENTERPRISE_FUNC_2ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ { \ return __func##__real(__p1, __p2); \ } \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define ENTERPRISE_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3); \ ENTERPRISE_FUNC_3ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ { \ return __func##__real(__p1, __p2, __p3); \ } \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define ENTERPRISE_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4); \ ENTERPRISE_FUNC_4ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ { \ return __func##__real(__p1, __p2, __p3, __p4); \ } \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define ENTERPRISE_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5); \ ENTERPRISE_FUNC_5ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5); \ } \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define ENTERPRISE_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6); \ ENTERPRISE_FUNC_6ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6); \ } \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define ENTERPRISE_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7); \ ENTERPRISE_FUNC_7ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7); \ } \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define ENTERPRISE_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8); \ ENTERPRISE_FUNC_8ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8); \ } \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define ENTERPRISE_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9); \ ENTERPRISE_FUNC_9ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9); \ } \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define ENTERPRISE_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10); \ ENTERPRISE_FUNC_10ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10); \ } \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define ENTERPRISE_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11); \ ENTERPRISE_FUNC_11ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11); \ } \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define ENTERPRISE_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12); \ ENTERPRISE_FUNC_12ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12); \ } \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define ENTERPRISE_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13); \ ENTERPRISE_FUNC_13ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13); \ } \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define ENTERPRISE_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14); \ ENTERPRISE_FUNC_14ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14); \ } \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define ENTERPRISE_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15); \ ENTERPRISE_FUNC_15ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15); \ } \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) # define ENTERPRISE_VOID_FUNC_0ARG_DECLARE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func); \ ENTERPRISE_FUNC_0ARG_INLINE_SIGNATURE(__ret, __func) \ { \ return __func##__real(); \ } \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define ENTERPRISE_VOID_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1); \ ENTERPRISE_FUNC_1ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1) \ { \ return __func##__real(__p1); \ } \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define ENTERPRISE_VOID_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2); \ ENTERPRISE_FUNC_2ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ { \ return __func##__real(__p1, __p2); \ } \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define ENTERPRISE_VOID_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3); \ ENTERPRISE_FUNC_3ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ { \ return __func##__real(__p1, __p2, __p3); \ } \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define ENTERPRISE_VOID_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4); \ ENTERPRISE_FUNC_4ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ { \ return __func##__real(__p1, __p2, __p3, __p4); \ } \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define ENTERPRISE_VOID_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5); \ ENTERPRISE_FUNC_5ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5); \ } \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define ENTERPRISE_VOID_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6); \ ENTERPRISE_FUNC_6ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6); \ } \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define ENTERPRISE_VOID_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7); \ ENTERPRISE_FUNC_7ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7); \ } \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define ENTERPRISE_VOID_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8); \ ENTERPRISE_FUNC_8ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8); \ } \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define ENTERPRISE_VOID_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9); \ ENTERPRISE_FUNC_9ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9); \ } \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define ENTERPRISE_VOID_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10); \ ENTERPRISE_FUNC_10ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10); \ } \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define ENTERPRISE_VOID_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11); \ ENTERPRISE_FUNC_11ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11); \ } \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define ENTERPRISE_VOID_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12); \ ENTERPRISE_FUNC_12ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12); \ } \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define ENTERPRISE_VOID_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13); \ ENTERPRISE_FUNC_13ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13); \ } \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define ENTERPRISE_VOID_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14); \ ENTERPRISE_FUNC_14ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14); \ } \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define ENTERPRISE_VOID_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15); \ ENTERPRISE_FUNC_15ARG_INLINE_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ { \ return __func##__real(__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15); \ } \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #endif // BUILDING_ENTERPRISE_EXTENSION #ifndef BUILDING_ENTERPRISE_EXTENSION // The __ret__assign and __ret_ref parameters are to work around functions returning void. #define ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, __real__func__par, __stub__func__par) \ { \ void *__handle = enterprise_library_open(); \ if (__handle) \ { \ static __func##__type func_ptr = NULL; \ if (!func_ptr) \ { \ func_ptr = shlib_load(__handle, #__func "__wrapper"); \ } \ if (func_ptr) \ { \ int __successful = 0; \ __ret__assign func_ptr __real__func__par; \ if (__successful) \ { \ enterprise_library_close(__handle); \ return __ret__ref; \ } \ } \ enterprise_library_close(__handle); \ } \ return __func##__stub __stub__func__par; \ } # define ENTERPRISE_FUNC_0ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref) \ ENTERPRISE_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, ENTERPRISE_CANARY_VALUE), \ ()) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) # define ENTERPRISE_FUNC_1ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, ENTERPRISE_CANARY_VALUE), \ (__p1)) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) # define ENTERPRISE_FUNC_2ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2)) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) # define ENTERPRISE_FUNC_3ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3)) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) # define ENTERPRISE_FUNC_4ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4)) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) # define ENTERPRISE_FUNC_5ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5)) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) # define ENTERPRISE_FUNC_6ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6)) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) # define ENTERPRISE_FUNC_7ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7)) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) # define ENTERPRISE_FUNC_8ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8)) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) # define ENTERPRISE_FUNC_9ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9)) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) # define ENTERPRISE_FUNC_10ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10)) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) # define ENTERPRISE_FUNC_11ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11)) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) # define ENTERPRISE_FUNC_12ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12)) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) # define ENTERPRISE_FUNC_13ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13)) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) # define ENTERPRISE_FUNC_14ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14)) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) # define ENTERPRISE_FUNC_15ARG_DEFINE_STUB_IMPL(__ret, __func, __ret__assign, __ret__ref, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_IMPL_LOADER(__ret, __func, __ret__assign, __ret__ref, \ (ENTERPRISE_CANARY_VALUE, &__successful, __p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15, ENTERPRISE_CANARY_VALUE), \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15)) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ ENTERPRISE_FUNC_0ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value) #define ENTERPRISE_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1) #define ENTERPRISE_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2) #define ENTERPRISE_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_DEFINE_STUB_IMPL(__ret, __func, __ret __ret_value =, __ret_value, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ ENTERPRISE_FUNC_0ARG_DEFINE_STUB_IMPL(__ret, __func, , ) #define ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1) #define ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2) #define ENTERPRISE_VOID_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_VOID_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_VOID_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_VOID_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_VOID_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_VOID_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_VOID_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_VOID_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_VOID_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_VOID_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_VOID_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_VOID_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_VOID_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_DEFINE_STUB_IMPL(__ret, __func, , , __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_FUNC_DEFINE_REAL_INVALID In_core_code_you_need_to_use_DEFINE_STUB func() #define ENTERPRISE_FUNC_0ARG_DEFINE(__ret, __func) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_0ARG_DEFINE(__ret, __func) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #define ENTERPRISE_VOID_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_DEFINE_REAL_INVALID #else // BUILDING_ENTERPRISE_EXTENSION #define ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL_RET_VALUE(__ret, __func, __real__func__par, __ret__expr) \ { \ if (__start_canary != ENTERPRISE_CANARY_VALUE || __end_canary != ENTERPRISE_CANARY_VALUE) \ { \ Log(LOG_LEVEL_ERR, "Function '%s %s%s' failed stack consistency check. Most likely this means the plugin containing the " \ "function is incompatible with this version of CFEngine.", #__ret, #__func, #__real__func__par); \ __ret__expr; \ } \ *__successful = 1; \ return __func __real__func__par; \ } #define ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, __real__func__par) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL_RET_VALUE(__ret, __func, __real__func__par, \ __ret __ret_value = (__ret)0; \ (void)__ret_value; \ return __ret_value) #define ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, __real__func__par) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL_RET_VALUE(__ret, __func, __real__func__par, return) #define ENTERPRISE_FUNC_DEFINE_INLINE_IMPL(__ret, __func, __real__func__par) \ { \ return __func##__real __real__func__par; \ } #define ENTERPRISE_FUNC_0ARG_DEFINE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ ()) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define ENTERPRISE_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1)) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2)) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3)) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4)) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5)) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6)) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7)) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8)) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9)) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10)) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11)) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12)) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13)) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14)) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15)) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_VOID_FUNC_0ARG_DEFINE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_WRAPPER_SIGNATURE(__ret, __func) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ ()) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define ENTERPRISE_VOID_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1)) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_VOID_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2)) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_VOID_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3)) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_VOID_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4)) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_VOID_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5)) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_VOID_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6)) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_VOID_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7)) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_VOID_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8)) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_VOID_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9)) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_VOID_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10)) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_VOID_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11)) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_VOID_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12)) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_VOID_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13)) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_VOID_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14)) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_VOID_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_WRAPPER_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_VOID_FUNC_DEFINE_WRAPPER_IMPL(__ret, __func, \ (__p1, __p2, __p3, __p4, __p5, __p6, __p7, __p8, __p9, __p10, __p11, __p12, __p13, __p14, __p15)) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_FUNC_DEFINE_STUB_INVALID In_extension_code_you_cannot_define_a_STUB func() #define ENTERPRISE_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #define ENTERPRISE_VOID_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_DEFINE_STUB_INVALID #endif // BUILDING_ENTERPRISE_EXTENSION #else // BUILTIN_EXTENSIONS // In this case just map to real function calls. // BUILTIN_EXTENSIONS is for Windows binaries and debugging. # define ENTERPRISE_FUNC_0ARG_STUB_SIGNATURE(__ret, __func) \ __ret __func##__stub() # define ENTERPRISE_FUNC_1ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func##__stub(__t1 __p1) # define ENTERPRISE_FUNC_2ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func##__stub(__t1 __p1, __t2 __p2) # define ENTERPRISE_FUNC_3ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3) # define ENTERPRISE_FUNC_4ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define ENTERPRISE_FUNC_5ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define ENTERPRISE_FUNC_6ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define ENTERPRISE_FUNC_7ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define ENTERPRISE_FUNC_8ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define ENTERPRISE_FUNC_9ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define ENTERPRISE_FUNC_10ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define ENTERPRISE_FUNC_11ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define ENTERPRISE_FUNC_12ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define ENTERPRISE_FUNC_13ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define ENTERPRISE_FUNC_14ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define ENTERPRISE_FUNC_15ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func##__stub(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) # define ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) \ __ret __func() # define ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) \ __ret __func(__t1 __p1) # define ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) \ __ret __func(__t1 __p1, __t2 __p2) # define ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3) # define ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4) # define ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5) # define ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6) # define ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7) # define ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8) # define ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9) # define ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10) # define ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11) # define ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12) # define ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13) # define ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14) # define ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ __ret __func(__t1 __p1, __t2 __p2, __t3 __p3, __t4 __p4, __t5 __p5, __t6 __p6, __t7 __p7, __t8 __p8, __t9 __p9, __t10 __p10, __t11 __p11, __t12 __p12, __t13 __p13, __t14 __p14, __t15 __p15) #define ENTERPRISE_FUNC_0ARG_DECLARE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define ENTERPRISE_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_VOID_FUNC_0ARG_DECLARE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define ENTERPRISE_VOID_FUNC_1ARG_DECLARE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_VOID_FUNC_2ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_VOID_FUNC_3ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_VOID_FUNC_4ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_VOID_FUNC_5ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_VOID_FUNC_6ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_VOID_FUNC_7ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_VOID_FUNC_8ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_VOID_FUNC_9ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_VOID_FUNC_10ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_VOID_FUNC_11ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_VOID_FUNC_12ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_VOID_FUNC_13ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_VOID_FUNC_14ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_VOID_FUNC_15ARG_DECLARE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_FUNC_0ARG_DEFINE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define ENTERPRISE_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_VOID_FUNC_0ARG_DEFINE(__ret, __func) \ ENTERPRISE_FUNC_0ARG_REAL_SIGNATURE(__ret, __func) #define ENTERPRISE_VOID_FUNC_1ARG_DEFINE(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_VOID_FUNC_2ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_VOID_FUNC_3ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_VOID_FUNC_4ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_VOID_FUNC_5ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_VOID_FUNC_6ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_VOID_FUNC_7ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_VOID_FUNC_8ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_VOID_FUNC_9ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_VOID_FUNC_10ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_VOID_FUNC_11ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_VOID_FUNC_12ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_VOID_FUNC_13ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_VOID_FUNC_14ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_VOID_FUNC_15ARG_DEFINE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_REAL_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ ENTERPRISE_FUNC_0ARG_STUB_SIGNATURE(__ret, __func) #define ENTERPRISE_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #define ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(__ret, __func) \ ENTERPRISE_FUNC_0ARG_STUB_SIGNATURE(__ret, __func) #define ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(__ret, __func, __t1, __p1) \ ENTERPRISE_FUNC_1ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1) #define ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2) \ ENTERPRISE_FUNC_2ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2) #define ENTERPRISE_VOID_FUNC_3ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) \ ENTERPRISE_FUNC_3ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3) #define ENTERPRISE_VOID_FUNC_4ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) \ ENTERPRISE_FUNC_4ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4) #define ENTERPRISE_VOID_FUNC_5ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) \ ENTERPRISE_FUNC_5ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5) #define ENTERPRISE_VOID_FUNC_6ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) \ ENTERPRISE_FUNC_6ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6) #define ENTERPRISE_VOID_FUNC_7ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) \ ENTERPRISE_FUNC_7ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7) #define ENTERPRISE_VOID_FUNC_8ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) \ ENTERPRISE_FUNC_8ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8) #define ENTERPRISE_VOID_FUNC_9ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) \ ENTERPRISE_FUNC_9ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9) #define ENTERPRISE_VOID_FUNC_10ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) \ ENTERPRISE_FUNC_10ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10) #define ENTERPRISE_VOID_FUNC_11ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) \ ENTERPRISE_FUNC_11ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11) #define ENTERPRISE_VOID_FUNC_12ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) \ ENTERPRISE_FUNC_12ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12) #define ENTERPRISE_VOID_FUNC_13ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) \ ENTERPRISE_FUNC_13ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13) #define ENTERPRISE_VOID_FUNC_14ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) \ ENTERPRISE_FUNC_14ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14) #define ENTERPRISE_VOID_FUNC_15ARG_DEFINE_STUB(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) \ ENTERPRISE_FUNC_15ARG_STUB_SIGNATURE(__ret, __func, __t1, __p1, __t2, __p2, __t3, __p3, __t4, __p4, __t5, __p5, __t6, __p6, __t7, __p7, __t8, __p8, __t9, __p9, __t10, __p10, __t11, __p11, __t12, __p12, __t13, __p13, __t14, __p14, __t15, __p15) #endif // BUILTIN_EXTENSIONS #endif // ENTERPRISE_EXTENSION_H cfengine-3.24.2/libpromises/fncall.h0000644000000000000000000000662015010704253017317 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FNCALL_H #define CFENGINE_FNCALL_H #include struct FnCall_ { char *name; Rlist *args; const Promise *caller; }; typedef enum FnCallStatus { FNCALL_SUCCESS, FNCALL_FAILURE } FnCallStatus; typedef struct { FnCallStatus status; Rval rval; } FnCallResult; typedef struct { const char *pattern; DataType dtype; const char *description; } FnCallArg; typedef enum { FNCALL_OPTION_NONE = 0, // Functions with variable arguments don't require a fixed number // of arguments. FNCALL_OPTION_VARARG = 1 << 0, // Cached functions are evaluated once per run (memoized). The // hash key is the function name and all the arguments. FNCALL_OPTION_CACHED = 1 << 1, // Collecting functions take a variable reference OR can accept a // nested function call. Either way, those parameters are // collected into a data container. FNCALL_OPTION_COLLECTING = 1 << 2, // Delayed-evaluation functions will evaluate their arguments directly, // so they can do things like maplist(canonify($(this)), mylist) FNCALL_OPTION_DELAYED_EVALUATION = 1 << 3, // Unsafe functions (with side effects) that should not be evaluated in // simulate mode(s). FNCALL_OPTION_UNSAFE = 1 << 4, } FnCallOption; typedef struct { const char *name; DataType dtype; const FnCallArg *args; FnCallResult (*impl)(EvalContext *, const Policy *, const FnCall *, const Rlist *); const char *description; FnCallOption options; FnCallCategory category; SyntaxStatus status; } FnCallType; extern const FnCallType CF_FNCALL_TYPES[]; bool FnCallIsBuiltIn(Rval rval); FnCall *FnCallNew(const char *name, Rlist *args); FnCall *FnCallCopy(const FnCall *f); FnCall *FnCallCopyRewriter(const FnCall *f, JsonElement *map); void FnCallDestroy(FnCall *fp); unsigned FnCallHash(const FnCall *fp, unsigned seed); void FnCallWrite(Writer *writer, const FnCall *call); FnCallResult FnCallEvaluate(EvalContext *ctx, const Policy *policy, FnCall *fp, const Promise *caller); const FnCallType *FnCallTypeGet(const char *name); FnCall *ExpandFnCall(const EvalContext *ctx, const char *ns, const char *scope, const FnCall *f); Rlist *NewExpArgs(EvalContext *ctx, const Policy *policy, const FnCall *fp, const FnCallType *fp_type); // TODO: should probably demolish this eventually void FnCallShow(FILE *fout, const char *prefix, const FnCall *fp, const Rlist *args); #endif cfengine-3.24.2/libpromises/mod_exec.h0000644000000000000000000000216015010704253017636 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MOD_EXEC_H #define CFENGINE_MOD_EXEC_H #include extern const PromiseTypeSyntax CF_EXEC_PROMISE_TYPES[]; #endif cfengine-3.24.2/libpromises/chflags.c0000644000000000000000000001272215010704253017462 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* BSD flags */ #include typedef struct { char *name; u_long bits; } BSDFlag; static const BSDFlag CF_BSDFLAGS[] = { {"arch", (u_long) SF_ARCHIVED}, {"archived", (u_long) SF_ARCHIVED}, {"nodump", (u_long) UF_NODUMP}, {"opaque", (u_long) UF_OPAQUE}, {"sappnd", (u_long) SF_APPEND}, {"sappend", (u_long) SF_APPEND}, {"schg", (u_long) SF_IMMUTABLE}, {"schange", (u_long) SF_IMMUTABLE}, {"simmutable", (u_long) SF_IMMUTABLE}, {"sunlnk", (u_long) SF_NOUNLINK}, {"sunlink", (u_long) SF_NOUNLINK}, {"uappnd", (u_long) UF_APPEND}, {"uappend", (u_long) UF_APPEND}, {"uchg", (u_long) UF_IMMUTABLE}, {"uchange", (u_long) UF_IMMUTABLE}, {"uimmutable", (u_long) UF_IMMUTABLE}, {"uunlnk", (u_long) UF_NOUNLINK}, {"uunlink", (u_long) UF_NOUNLINK}, {NULL, (u_long) 0} }; /***************************************************************/ static u_long ConvertBSDBits(const char *s); /***************************************************************/ bool ParseFlagString(Rlist *bitlist, u_long *plusmask, u_long *minusmask) { // FIXME: ALWAYS returns true if (bitlist == NULL) { return true; } *plusmask = 0; *minusmask = 0; for (const Rlist *rp = bitlist; rp != NULL; rp = rp->next) { const char *flag = RlistScalarValue(rp); char op = *RlistScalarValue(rp); switch (op) { case '-': *minusmask |= ConvertBSDBits(flag + 1); break; case '+': *plusmask |= ConvertBSDBits(flag + 1); break; default: *plusmask |= ConvertBSDBits(flag); break; } } Log(LOG_LEVEL_DEBUG, "ParseFlagString: [PLUS = %lo] [MINUS = %lo]", *plusmask, *minusmask); return true; } /***************************************************************/ static u_long ConvertBSDBits(const char *s) { int i; for (i = 0; CF_BSDFLAGS[i].name != NULL; i++) { if (strcmp(s, CF_BSDFLAGS[i].name) == 0) { return CF_BSDFLAGS[i].bits; } } return 0; } /* CHFLAGS(1) FreeBSD General Commands Manual CHFLAGS(1) NAME chflags - change file flags SYNOPSIS chflags [-R [-H | -L | -P]] flags file ... DESCRIPTION The chflags utility modifies the file flags of the listed files as speci- fied by the flags operand. The options are as follows: -H If the -R option is specified, symbolic links on the command line are followed. (Symbolic links encountered in the tree traversal are not followed.) -L If the -R option is specified, all symbolic links are followed. -P If the -R option is specified, no symbolic links are followed. -R Change the file flags for the file hierarchies rooted in the files instead of just the files themselves. Flags are a comma separated list of keywords. The following keywords are currently defined: arch set the archived flag (super-user only) dump set the dump flag sappnd set the system append-only flag (super-user only) schg set the system immutable flag (super-user only) sunlnk set the system undeletable flag (super-user only) uappnd set the user append-only flag (owner or super-user only) uchg set the user immutable flag (owner or super-user only) uunlnk set the user undeletable flag (owner or super-user only) archived, sappend, schange, simmutable, uappend, uchange, uimmutable, sunlink, uunlink aliases for the above Putting the letters ``no'' before an option causes the flag to be turned off. For example: nodump the file should never be dumped Symbolic links do not have flags, so unless the -H or -L option is set, chflags on a symbolic link always succeeds and has no effect. The -H, -L and -P options are ignored unless the -R option is specified. In addi- tion, these options override each other and the command's actions are de- termined by the last one specified. You can use "ls -lo" to see the flags of existing files. The chflags utility exits 0 on success, and >0 if an error occurs. SEE ALSO ls(1), chflags(2), stat(2), fts(3), symlink(7) HISTORY The chflags command first appeared in 4.4BSD. BSD March 31, 1994 1 */ cfengine-3.24.2/libpromises/actuator.c0000644000000000000000000000512115010704253017670 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include PromiseResult PromiseResultUpdate(PromiseResult prior, PromiseResult evidence) { switch (prior) { case PROMISE_RESULT_DENIED: case PROMISE_RESULT_FAIL: case PROMISE_RESULT_INTERRUPTED: case PROMISE_RESULT_TIMEOUT: return prior; case PROMISE_RESULT_WARN: switch (evidence) { case PROMISE_RESULT_DENIED: case PROMISE_RESULT_FAIL: case PROMISE_RESULT_INTERRUPTED: case PROMISE_RESULT_TIMEOUT: case PROMISE_RESULT_WARN: return evidence; case PROMISE_RESULT_CHANGE: case PROMISE_RESULT_NOOP: case PROMISE_RESULT_SKIPPED: return prior; default: ProgrammingError("Unexpected promise result"); } case PROMISE_RESULT_SKIPPED: return evidence; case PROMISE_RESULT_NOOP: if (evidence == PROMISE_RESULT_SKIPPED) { return prior; } else { return evidence; } case PROMISE_RESULT_CHANGE: switch (evidence) { case PROMISE_RESULT_DENIED: case PROMISE_RESULT_FAIL: case PROMISE_RESULT_INTERRUPTED: case PROMISE_RESULT_TIMEOUT: case PROMISE_RESULT_WARN: return evidence; case PROMISE_RESULT_CHANGE: case PROMISE_RESULT_NOOP: case PROMISE_RESULT_SKIPPED: return prior; } } ProgrammingError("Never reach"); } bool PromiseResultIsOK(PromiseResult result) { return (result == PROMISE_RESULT_CHANGE) || (result == PROMISE_RESULT_NOOP); } cfengine-3.24.2/libpromises/prototypes3.h0000644000000000000000000001131515010704253020370 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROTOTYPES3_H #define CFENGINE_PROTOTYPES3_H #include #include #include #include bool BootstrapAllowed(void); /* Versions */ const char *Version(void); const char *NameVersion(void); /* cfparse.y */ void yyerror(const char *s); /* agent.c */ PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp); /* Only for agent.c */ void ConnectionsInit(void); void ConnectionsCleanup(void); /* client_protocol.c */ void SetSkipIdentify(bool enabled); /* enterprise_stubs.c */ ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, Nova_Initialize, EvalContext *, ctx); ENTERPRISE_FUNC_1ARG_DECLARE(int, CfSessionKeySize, char, c); ENTERPRISE_FUNC_0ARG_DECLARE(char, CfEnterpriseOptions); ENTERPRISE_FUNC_1ARG_DECLARE(const EVP_CIPHER *, CfengineCipher, char, type); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, EnterpriseContext, EvalContext *, ctx); ENTERPRISE_FUNC_0ARG_DECLARE(const char *, GetConsolePrefix); ENTERPRISE_FUNC_6ARG_DECLARE(char *, GetRemoteScalar, EvalContext *, ctx, char *, proto, char *, handle, const char *, server, int, encrypted, char *, rcv); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, LogTotalCompliance, const char *, version, int, background_tasks); #if defined(__MINGW32__) ENTERPRISE_FUNC_4ARG_DECLARE(bool, GetRegistryValue, const char *, key, char *, name, char *, buf, int, bufSz); #endif ENTERPRISE_FUNC_6ARG_DECLARE(void *, CfLDAPValue, char *, uri, char *, dn, char *, filter, char *, name, char *, scope, char *, sec); ENTERPRISE_FUNC_6ARG_DECLARE(void *, CfLDAPList, char *, uri, char *, dn, char *, filter, char *, name, char *, scope, char *, sec); ENTERPRISE_FUNC_8ARG_DECLARE(void *, CfLDAPArray, EvalContext *, ctx, const Bundle *, caller, char *, array, char *, uri, char *, dn, char *, filter, char *, scope, char *, sec); ENTERPRISE_FUNC_8ARG_DECLARE(void *, CfRegLDAP, EvalContext *, ctx, char *, uri, char *, dn, char *, filter, char *, name, char *, scope, char *, regex, char *, sec); ENTERPRISE_VOID_FUNC_3ARG_DECLARE(void, CacheUnreliableValue, char *, caller, char *, handle, char *, buffer); ENTERPRISE_FUNC_3ARG_DECLARE(int, RetrieveUnreliableValue, char *, caller, char *, handle, char *, buffer); ENTERPRISE_FUNC_3ARG_DECLARE(bool, TranslatePath, const char *, from, char *, to, size_t, to_size); ENTERPRISE_FUNC_4ARG_DECLARE(bool, ListHostsWithClass, EvalContext *, ctx, Rlist **, return_list, char *, class_name, char *, return_format); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, CheckAndSetHAState, const char *, workdir, EvalContext *, ctx); ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, ReloadHAConfig); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, Nova_ClassHistoryAddContextName, const StringSet *, list, const char *, context_name); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, Nova_ClassHistoryEnable, StringSet **, list, bool, enable); /* manual.c */ void TexinfoManual(EvalContext *ctx, const char *source_dir, const char *output_file); /* modes.c */ bool ParseModeString(const char *modestring, mode_t *plusmask, mode_t *minusmask); /* patches.c */ bool IsPrivileged(void); char *cf_strtimestamp_local(const time_t time, char *buf); char *cf_strtimestamp_utc(const time_t time, char *buf); int cf_closesocket(int sd); #if !defined(__MINGW32__) #define OpenNetwork() /* noop */ #define CloseNetwork() /* noop */ #else void OpenNetwork(void); void CloseNetwork(void); #endif bool LinkOrCopy(const char *from, const char *to, int sym); /* storage_tools.c */ off_t GetDiskUsage(char *file, CfSize type); /* verify_reports.c */ PromiseResult VerifyReportPromise(EvalContext *ctx, const Promise *pp); /* cf-key */ ENTERPRISE_FUNC_1ARG_DECLARE(bool, LicenseInstall, char *, path_source); /* cf-serverd */ ENTERPRISE_FUNC_0ARG_DECLARE(size_t, EnterpriseGetMaxCfHubProcesses); #endif cfengine-3.24.2/libpromises/extensions_template.c.pre0000644000000000000000000000456015010704253022733 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ BEGIN_MARKER // Do not include this file directly! Build process should replace XextensionX occurrences. #include #include /* getenv() */ #include /* strerror() */ #include #include #ifndef BUILTIN_EXTENSIONS static pthread_once_t XextensionX_library_once = PTHREAD_ONCE_INIT; static void *XextensionX_library_handle = NULL; static void XextensionX_library_assign(); void *XextensionX_library_open() { if (getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE") != NULL) { return extension_library_open(xEXTENSIONx_LIBRARY_NAME); } int ret = pthread_once(&XextensionX_library_once, &XextensionX_library_assign); if (ret != 0) { Log(LOG_LEVEL_ERR, "Could not initialize Extension Library: %s: %s", xEXTENSIONx_LIBRARY_NAME, strerror(ret)); return NULL; } return XextensionX_library_handle; } static void XextensionX_library_assign() { XextensionX_library_handle = extension_library_open(xEXTENSIONx_LIBRARY_NAME); } void XextensionX_library_close(void *handle) { if (getenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE") != NULL) { return extension_library_close(handle); } // Normally we don't ever close the extension library, because we may have // pointer references to it. } #endif // BUILTIN_EXTENSIONS cfengine-3.24.2/libpromises/failsafe.cf0000644000000000000000000004773215010704253020004 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########## CFEngine Bootstrap / Failsafe Policy ############################## # This file (failsafe.cf) is re-generated inside "inputs" directory every time # you bootstrap. This means that custom changes will be overwritten. # # The role of this standalone policy file is to fetch the main promises from # the policy hub for the first time when bootstrapping, and to recover the # system by fetching policies in case the standard agent run fails. ############################################################################## body agent control { # Bootstrapping can't continue without keys abortclasses => { "no_ppkeys_ABORT_kept" }; # Make sure that running failsafe many times in a row does not # change functionality ifelapsed => "0"; } ################################################################################ bundle agent main { meta: "description" string => "Perform bootstrap or failsafe recovery operations."; vars: # In order to preserve the log level used during bootstrap we build the # string to set log level on any direct sub-agent calls based on classes # that are defined when the options are set. # --log-level, -g value - Specify how detailed logs should be. # Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug' "log_level" string => ifelse("debug_mode", "--log-level=debug", "verbose_mode", "--log-level=verbose", "info_mode", "--log-level=info", # CFE-4121 - Not yet implemented # "notice_mode", "--log-level=notice", # "warning_mode", "--log-level=warning", # "error_mode", "--log-level=error", ""); methods: "Check Keys" usebundle => failsafe_cfe_internal_checkkeys, comment => "Without a valid keypair we aren't going to be able to establish trust"; "Fetch Inputs" usebundle => failsafe_cfe_internal_update, comment => "We need to fetch policy from upstream if we are bootstrapping or if we are performing failsafe recovery."; "Actuate Update Policy" usebundle => failsafe_cfe_internal_call_update, comment => "In order to speed up convergence and reporting we trigger the update policy right after initial bootstrap. This allows the first scheduled run to happen with the most up to date and complete information."; "Trigger Policy" usebundle => failsafe_cfe_internal_trigger_policy, comment => "In order to speed up convergence and reporting we trigger the whole policy right after initial bootstrap. This allows the first report to provide more complete data."; "Report" usebundle => failsafe_cfe_internal_report, comment => "It's important to let the user know what happened as the result of the bootstrap or failsafe operation."; } bundle agent failsafe_cfe_internal_checkkeys { classes: "have_ppkeys" expression => fileexists("$(sys.workdir)/ppkeys/localhost.pub"), handle => "failsafe_cfe_internal_bootstrap_checkkeys_classes_have_ppkeys"; reports: !have_ppkeys:: "No public/private key pair is loaded, please create one by running \"cf-key\"" classes => failsafe_results("namespace", "no_ppkeys_ABORT"); } ################################################################################ bundle agent failsafe_cfe_internal_update { vars: # A policy server cannot use the shortcut feature to resolve # masterfiles since cf-serverd is potentially not yet up and # running. # The unqualified path is used for non policy servers so that # the policy server can use a shortcut to decide on behalf of # the client which policy to serve by default. This is useful # when running binaires from mixed sources (for example CFEngine # produced binaries vs packages from the debian repository). "masterfiles_dir_remote" string => ifelse( "policy_server", $(sys.masterdir), "masterfiles" ); files: "$(sys.inputdir)" handle => "failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_shortcut", copy_from => failsafe_scp("$(masterfiles_dir_remote)"), depth_search => failsafe_u_infinite_client_policy, file_select => failsafe_exclude_vcs_files, classes => failsafe_results("namespace", "inputdir_update"); !policy_server:: "$(sys.workdir)/modules" handle => "failsafe_cfe_internal_bootstrap_update_files_sys_workdir_modules_shortcut", copy_from => failsafe_scp("modules"), depth_search => failsafe_recurse("inf"), file_select => failsafe_exclude_vcs_files, classes => failsafe_results("namespace", "modulesdir_update"); !windows.inputdir_update_error:: # When running on a *nix platform with homogeneous packages # $(sys.masterdir) is a good guess. This is never the case for # windows, and might be a poor guess if mixing packages from # different sources (for example debian repositories and # CFEngine produced packages). "$(sys.inputdir)" handle => "failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_not_windows", copy_from => failsafe_scp("$(sys.masterdir)"), depth_search => failsafe_recurse("inf"), file_select => failsafe_exclude_vcs_files, classes => failsafe_results("namespace", "inputdir_update"), comment => "If we failed to fetch policy we try again using the legacy default in case we are fetching policy from a hub that is not serving mastefiles via a shortcut."; windows.inputdir_update_error:: # Note: Windows can't use $(sys.masterdir) because no one runs a # hub on windows and the copy_from needs the remote path. "$(sys.inputdir)" handle => "failsafe_cfe_internal_bootstrap_update_files_sys_workdir_inputs_windows", copy_from => failsafe_scp("/var/cfengine/masterfiles"), depth_search => failsafe_recurse("inf"), file_select => failsafe_exclude_vcs_files, classes => failsafe_results("namespace", "inputdir_update"), comment => "If we failed to fetch policy we try again using the legacy default in case we are fetching policy from a hub that is not serving mastefiles via a shortcut."; windows:: # TODO: Remove the use of bin-twin ref: Redmine #7364 "$(sys.workdir)\\bin-twin\\." handle => "failsafe_cfe_internal_bootstrap_update_files_sys_workdir_bin_twin_windows", copy_from => failsafe_cp("$(sys.workdir)\\bin\\."), depth_search => failsafe_recurse("1"), file_select => failsafe_exclude_vcs_files, comment => "Make sure we maintain a clone of the binaries and libraries for updating"; processes: # TODO: Decide if this class guard is appropriate. Should we # guard checking of cf-execd process running to when inputs are # repaired !windows.inputdir_update_repaired:: # We need to know when cf-execd is not running so that we can # start it when necessary. Windows and systemd hosts uses the service # manager instead of keying on individual processes. "cf-execd" restart_class => "cf_execd_not_running", handle => "failsafe_cfe_internal_bootstrap_update_processes_start_cf_execd"; any:: # We need to know if cf-serverd isn't running so that we can # start it when necessary. "cf-serverd" restart_class => "cf_serverd_not_running", handle => "failsafe_cfe_internal_bootstrap_update_processes_start_cf_serverd"; commands: cf_execd_not_running.!(windows|systemd|bootstrap_skip_services):: # Windows and systemd do not launch cf-execd directly and are # handeled separately. "$(sys.cf_execd)" handle => "failsafe_cfe_internal_bootstrap_update_commands_check_sys_cf_execd_start", classes => failsafe_results("namespace", "cf_execd_running"); cf_serverd_not_running.!(windows|systemd|bootstrap_skip_services):: # cf-serverd is not launched directly on Windows and systemd and is # handled separately. "$(sys.cf_serverd)" handle => "failsafe_cfe_internal_bootstrap_update_commands_check_sys_cf_serverd_start", action => failsafe_ifwin_bg, classes => failsafe_results("namespace", "cf_serverd_running"), comment => "cf-serverd is needed on policy hubs or remote clients will not be able to get policy. Clients do not have a strong dependency on cf-serverd and if the component is necessay it is expected to be started by a separate policy."; cf_execd_not_running.systemd.!bootstrap_skip_services:: # We explicitly use "restart", because it is possible that cf-serverd # is running, even if cf-execd isn't, for example. Here we want to be # sure we relaunch everything. "/bin/systemctl restart cfengine3" -> { "CFE-1459" } handle => "failsafe_cfe_internal_bootstrap_update_commands_systemd_cfe_start", contain => bootstrap_command_silent, classes => failsafe_results("namespace", "systemctl_restart_cfengine3"); services: # TODO: Is this restriction to only promise the service running # when inputs are repaired appropriate? Perhaps it should always # be checked. windows.inputdir_update_repaired.!bootstrap_skip_services:: "CfengineNovaExec" handle => "failsafe_cfe_internal_bootstrap_update_services_windows_executor", service_policy => "start", service_method => failsafe_bootstart, classes => failsafe_results("namespace", "cf_execd_running"); } ################################################################################ bundle agent failsafe_cfe_internal_report { meta: "description" string => "Report the outcome of the embedded bootstrap/failsafe operation."; classes: # TODO: Determine if this is necessary and/or useful. Pre-eval # might resolve this before policy update occurs, and this is # probably most useful after policy update has been attempted. "have_promises_cf" scope => "bundle", expression => fileexists("$(sys.inputdir)/promises.cf"), handle => "failsafe_cfe_internal_bootstrap_update_classes_have_promises_cf", comment => "We expect to find promises.cf after policy has been successfully copied from the policy server. If promises.cf is missing, then the bootstrap or failsafe recovery has likely failed."; reports: !bootstrap_mode:: "Built-in failsafe policy triggered" handle => "failsafe_cfe_internal_bootstrap_update_reports_failsafe_notification", comment => "Be sure to inform the user that the failsafe policy has been triggered. This typically indicates that the agent has received broken policy. It may also indicate legacy configuration in body executor control."; bootstrap_mode:: "Bootstrapping from host '$(sys.policy_hub)' via built-in policy '$(this.promise_filename)'" handle => "failsafe_cfe_internal_bootstrap_update_reports_bootstrap_notification", comment => "Be sure to inform the user that they have triggerd a bootstrap."; bootstrap_mode.policy_server:: "This host assumes the role of policy server" handle => "failsafe_cfe_internal_bootstrap_update_reports_assume_policy_hub"; bootstrap_mode.!policy_server:: "This autonomous node assumes the role of voluntary client" handle => "failsafe_cfe_internal_bootstrap_update_reports_assume_voluntary_client"; inputdir_update_repaired:: "Updated local policy from policy server" handle => "failsafe_cfe_internal_bootstrap_update_reports_inputdir_update_repaired"; inputdir_update_repaired.!have_promises_cf:: # We used to display this report when we have fetched new # policy, but still can not find promises.cf in # sys.inputdir. However if the hub being bootstrapped to is down # we may never repair inputs and this may not be triggered # # TODO: Come up with better conditions. These seem weak. # - Potentially use returnszero() with cf-promises? "Failed to copy policy from policy server at $(sys.policy_hub):$(sys.masterdir) Please check * cf-serverd is running on $(sys.policy_hub) * CFEngine version on the policy hub is 3.6.0 or latest - otherwise you need to tweak the protocol_version setting * network connectivity to $(sys.policy_hub) on port $(sys.policy_hub_port) * masterfiles 'body server control' - in particular allowconnects, trustkeysfrom and skipverify * masterfiles 'bundle server' -> access: -> masterfiles -> admit/deny It is often useful to restart cf-serverd in verbose mode (cf-serverd -v) on $(sys.policy_hub) to diagnose connection issues. When updating masterfiles, wait (usually 5 minutes) for files to propagate to inputs on $(sys.policy_hub) before retrying." handle => "failsafe_cfe_internal_bootstrap_update_reports_did_not_get_policy"; trigger_policy_repaired:: "Triggered an initial run of the policy" handle => "failsafe_cfe_internal_bootstrap_trigger_policy_passed"; trigger_policy_failed:: "Initial run of the policy failed" handle => "failsafe_cfe_internal_bootstrap_trigger_policy_failed"; systemctl_restart_cfengine3_repaired:: "Restarted systemd unit cfengine3" handle => "failsafe_cfe_intrnal_bootstrap_update_reports_systemd_unit_restarted"; systemctl_restart_cfengine3_error:: "Error restarting systemd unit cfengine3" handle => "failsafe_cfe_intrnal_bootstrap_update_reports_systemd_unit_restarted"; cf_serverd_running_repaired:: "Started the server" handle => "failsafe_cfe_internal_bootstrap_update_reports_started_serverd"; cf_serverd_running_failed:: "Failed to start the server" handle => "failsafe_cfe_internal_bootstrap_update_reports_failed_to_start_serverd"; cf_execd_running_repaired:: "Started the scheduler" handle => "failsafe_cfe_internal_bootstrap_update_reports_started_execd"; cf_execd_running_failed:: "Failed to start the scheduler" handle => "failsafe_cfe_internal_bootstrap_update_reports_failed_to_start_execd"; } ################################################################################ bundle agent failsafe_cfe_internal_call_update { vars: "mode" string => ifelse("bootstrap_mode", "bootstrap_mode", "failsafe_mode"); commands: # On Windows we need cf-execd to call update.cf, otherwise the daemons will # not run under the SYSTEM account. !windows.!skip_policy_on_bootstrap:: "$(sys.cf_agent) -f $(sys.update_policy_path) --define $(mode) $(main.log_level)" handle => "failsafe_cfe_internal_call_update_commands_call_update_cf", if => fileexists( $(sys.update_policy_path) ), comment => "We run update.cf in order to prepare system information for collection into CFEngine Enterprise more quickly."; } ################################################################################ bundle agent failsafe_cfe_internal_trigger_policy { commands: bootstrap_mode.!skip_policy_on_bootstrap:: "$(sys.cf_agent) --define bootstrap_mode $(main.log_level)" handle => "failsafe_cfe_internal_trigger_policy_commands_call_promises_cf", if => fileexists( $(sys.default_policy_path) ), classes => failsafe_results("namespace", "trigger_policy"), comment => "We run promises.cf in order to prepare system information for collection into CFEngine Enterprise more quickly."; } ############################################ body copy_from failsafe_scp(from) { source => "$(from)"; compare => "digest"; # This class is always set when bootstrapping. You can deactivate # this class with --trust-server=no when bootstrapping trust_server:: trustkey => "true"; !policy_server:: servers => { "$(sys.policy_hub)" }; portnumber => "$(sys.policy_hub_port)"; } ############################################ body depth_search failsafe_u_infinite_client_policy # @brief Search recursively for files excluding vcs related files and .no-distrib directories # @param d Maximum depth to search recursively # Duplicated in update policy { depth => "inf"; exclude_dirs => { "\.svn", "\.git", "git-core", "\.no-distrib" }; } ############################################ body depth_search failsafe_recurse(d) { depth => "$(d)"; exclude_dirs => { "\.svn", "\.git" }; } ############################################ body file_select failsafe_exclude_vcs_files { leaf_name => { "\.git.*", "\.mailmap" }; file_result => "!leaf_name"; } ############################################ body service_method failsafe_bootstart { service_autostart_policy => "boot_time"; } ############################################ body action failsafe_ifwin_bg { windows:: background => "true"; } ############################################ body copy_from failsafe_cp(from) { source => "$(from)"; compare => "digest"; copy_backup => "false"; } ############################################ body classes failsafe_results(scope, class_prefix) # @brief Define classes prefixed with `class_prefix` and suffixed with # appropriate outcomes: _kept, _repaired, _not_kept, _error, _failed, # _denied, _timeout, _reached # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined { scope => "$(scope)"; promise_kept => { "$(class_prefix)_reached", "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_reached", "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_failed" }; repair_denied => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_denied" }; repair_timeout => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_timeout" }; } body contain bootstrap_command_silent # @brief Suppress command output { no_output => "true"; } cfengine-3.24.2/libpromises/policy.c0000644000000000000000000030244215010704253017353 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const char *const POLICY_ERROR_BUNDLE_NAME_RESERVED = "Use of a reserved container name as a bundle name \"%s\""; static const char *const POLICY_ERROR_BUNDLE_REDEFINITION = "Duplicate definition of bundle %s with type %s"; static const char *const POLICY_ERROR_BODY_REDEFINITION = "Duplicate definition of body %s with type %s"; static const char *const POLICY_ERROR_BODY_UNDEFINED = "Undefined body %s with type %s"; static const char *const POLICY_ERROR_BODY_CONTROL_ARGS = "Control bodies cannot take arguments, body %s control"; static const char *const POLICY_ERROR_PROMISE_UNCOMMENTED = "Promise is missing a comment attribute, and comments are required " "by policy"; static const char *const POLICY_ERROR_PROMISE_DUPLICATE_HANDLE = "Duplicate promise handle %s found"; static const char *const POLICY_ERROR_LVAL_INVALID = "Promise type %s has unknown attribute %s"; static const char *const POLICY_ERROR_PROMISE_ATTRIBUTE_NOT_SUPPORTED = "Common attribute '%s' not supported for custom promises, use '%s' instead (%s promises)"; static const char *const POLICY_ERROR_PROMISE_TYPE_UNSUPPORTED = "Promise type '%s' not supported by '%s' bundle type"; static const char *const POLICY_ERROR_CONSTRAINT_TYPE_MISMATCH = "Type mismatch in constraint: %s"; static const char *const POLICY_ERROR_EMPTY_VARREF = "Empty variable reference"; //************************************************************************ static void BundleDestroy(Bundle *bundle); static void BodyDestroy(Body *body); static SyntaxTypeMatch ConstraintCheckType(const Constraint *cp); static bool PromiseCheck(const Promise *pp, Seq *errors); /*************************************************************************/ /** * @brief Return a default bundle name for this method/service */ Rval DefaultBundleConstraint(const Promise *pp, char *promisetype) { static char name[CF_BUFSIZE]; snprintf(name, CF_BUFSIZE, "%s_%s", promisetype, CanonifyName(pp->promiser)); return (Rval) { name, RVAL_TYPE_SCALAR }; } /*************************************************************************/ const char *NamespaceDefault(void) { return "default"; } /*************************************************************************/ Policy *PolicyNew(void) { Policy *policy = xcalloc(1, sizeof(Policy)); policy->release_id = NULL; policy->bundles = SeqNew(100, BundleDestroy); policy->bodies = SeqNew(100, BodyDestroy); policy->custom_promise_types = SeqNew(20, BodyDestroy); policy->policy_files_hashes = NULL; return policy; } /*************************************************************************/ int PolicyCompare(const void *a, const void *b) { return a - b; } /*************************************************************************/ void PolicyDestroy(Policy *policy) { if (policy != NULL) { SeqDestroy(policy->bundles); SeqDestroy(policy->bodies); SeqDestroy(policy->custom_promise_types); free(policy->release_id); if (policy->policy_files_hashes != NULL) { StringMapDestroy(policy->policy_files_hashes); } free(policy); } } /*************************************************************************/ static unsigned ConstraintHash(const Constraint *cp, unsigned seed) { unsigned hash = seed; hash = StringHash(cp->lval, hash); hash = StringHash(cp->classes, hash); hash = RvalHash(cp->rval, hash); return hash; } /*************************************************************************/ static unsigned BodyHash(const Body *body, unsigned seed) { unsigned hash = seed; for (size_t i = 0; i < SeqLength(body->conlist); i++) { const Constraint *cp = SeqAt(body->conlist, i); hash = ConstraintHash(cp, hash); } return hash; } /*************************************************************************/ static unsigned PromiseHash(const Promise *pp, unsigned seed) { unsigned hash = seed; hash = StringHash(pp->promiser, seed); hash = RvalHash(pp->promisee, hash); for (size_t i = 0; i < SeqLength(pp->conlist); i++) { const Constraint *cp = SeqAt(pp->conlist, i); hash = ConstraintHash(cp, hash); } return hash; } /*************************************************************************/ static unsigned BundleSectionHash(const BundleSection *section, unsigned seed) { unsigned hash = seed; hash = StringHash(section->promise_type, hash); for (size_t i = 0; i < SeqLength(section->promises); i++) { const Promise *pp = SeqAt(section->promises, i); hash = PromiseHash(pp, hash); } return hash; } /*************************************************************************/ static unsigned BundleHash(const Bundle *bundle, unsigned seed) { unsigned hash = seed; hash = StringHash(bundle->type, hash); hash = StringHash(bundle->ns, hash); hash = StringHash(bundle->name, hash); hash = RlistHash(bundle->args, hash); for (size_t i = 0; i < SeqLength(bundle->sections); i++) { const BundleSection *section = SeqAt(bundle->sections, i); hash = BundleSectionHash(section, hash); } return hash; } /*************************************************************************/ unsigned PolicyHash(const Policy *policy) { unsigned hash = 0; for (size_t i = 0; i < SeqLength(policy->bodies); i++) { const Body *body = SeqAt(policy->bodies, i); hash = BodyHash(body, hash); } for (size_t i = 0; i < SeqLength(policy->bundles); i++) { const Bundle *bundle = SeqAt(policy->bundles, i); hash = BundleHash(bundle, hash); } return hash; } /*************************************************************************/ StringSet *PolicySourceFiles(const Policy *policy) { StringSet *files = StringSetNew(); for (size_t i = 0; i < SeqLength(policy->bundles); i++) { const Bundle *bp = SeqAt(policy->bundles, i); if (bp->source_path) { StringSetAdd(files, xstrdup(bp->source_path)); } } for (size_t i = 0; i < SeqLength(policy->bodies); i++) { const Bundle *bp = SeqAt(policy->bodies, i); if (bp->source_path) { StringSetAdd(files, xstrdup(bp->source_path)); } } return files; } /*************************************************************************/ /** * Get hash digest of the given policy file. * * @param policy Policy that is supposed to contain (have loaded) the file * @param policy_file_path Absolute path of the policy file to get the digest for * @return Hash digest of the given policy file or %NULL if unknown * @note The returned hash digest is owned by the policy, **do not free it**. */ const char *PolicyGetPolicyFileHash(const Policy *policy, const char *policy_file_path) { return StringMapGet(policy->policy_files_hashes, policy_file_path); } /*************************************************************************/ static const char *StripNamespace(const char *full_symbol) { char *sep = strchr(full_symbol, CF_NS); if (sep == NULL) { return full_symbol; } else { return sep + 1; } } /*************************************************************************/ /** * @brief Query a policy for a body * @param policy The policy to query * @param ns Namespace filter (optionally NULL) * @param type Body type filter * @param name Body name filter * @return Body child object if found, otherwise NULL */ Body *PolicyGetBody(const Policy *policy, const char *ns, const char *type, const char *name) { for (size_t i = 0; i < SeqLength(policy->bodies); i++) { Body *bp = SeqAt(policy->bodies, i); const char *body_symbol = StripNamespace(bp->name); if (strcmp(bp->type, type) == 0 && strcmp(body_symbol, name) == 0) { // allow namespace to be optionally matched if (ns && strcmp(bp->ns, ns) != 0) { continue; } return bp; } } return NULL; } /*************************************************************************/ /** * @brief Query a policy for a bundle * @param policy The policy to query * @param ns Namespace filter (optionally NULL) * @param type Bundle type filter * @param name Bundle name filter * @return Bundle child object if found, otherwise NULL */ Bundle *PolicyGetBundle(const Policy *policy, const char *ns, const char *type, const char *name) { const char *bundle_symbol = StripNamespace(name); for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); if ((type == NULL || strcmp(bp->type, type) == 0) && ((strcmp(bp->name, bundle_symbol) == 0) || (strcmp(bp->name, name) == 0))) { // allow namespace to be optionally matched if (ns && strcmp(bp->ns, ns) != 0) { continue; } return bp; } } return NULL; } /*************************************************************************/ /** * @brief Check to see if a policy is runnable (contains body common control) * @param policy Policy to check * @return True if policy is runnable */ bool PolicyIsRunnable(const Policy *policy) { return PolicyGetBody(policy, NULL, "common", "control") != NULL; } /*************************************************************************/ /** * @brief Merge two partial policy objects. The memory for the child objects of the original policies are transferred to the new parent. * @param a * @param b * @return Merged policy */ Policy *PolicyMerge(Policy *a, Policy *b) { assert(a != NULL); assert(b != NULL); Policy *result = PolicyNew(); SeqAppendSeq(result->bundles, a->bundles); SeqSoftDestroy(a->bundles); SeqAppendSeq(result->bundles, b->bundles); SeqSoftDestroy(b->bundles); for (size_t i = 0; i < SeqLength(result->bundles); i++) { Bundle *bp = SeqAt(result->bundles, i); bp->parent_policy = result; } SeqAppendSeq(result->bodies, a->bodies); SeqSoftDestroy(a->bodies); SeqAppendSeq(result->bodies, b->bodies); SeqSoftDestroy(b->bodies); for (size_t i = 0; i < SeqLength(result->bodies); i++) { Body *bdp = SeqAt(result->bodies, i); bdp->parent_policy = result; } SeqAppendSeq(result->custom_promise_types, a->custom_promise_types); SeqSoftDestroy(a->custom_promise_types); SeqAppendSeq(result->custom_promise_types, b->custom_promise_types); SeqSoftDestroy(b->custom_promise_types); for (size_t i = 0; i < SeqLength(result->custom_promise_types); i++) { Body *bdp = SeqAt(result->custom_promise_types, i); bdp->parent_policy = result; } StringMap *extra_hashes = NULL; if (a->policy_files_hashes != NULL) { result->policy_files_hashes = a->policy_files_hashes; a->policy_files_hashes = NULL; extra_hashes = b->policy_files_hashes; b->policy_files_hashes = NULL; } else if (b->policy_files_hashes != NULL) { result->policy_files_hashes = b->policy_files_hashes; b->policy_files_hashes = NULL; } else { result->policy_files_hashes = NULL; } if (extra_hashes != NULL) { MapIterator it = MapIteratorInit(extra_hashes->impl); MapKeyValue *item; while ((item = MapIteratorNext(&it)) != NULL) { /* Move data and duplicate just the keys (which are always owned by the map). */ StringMapInsert(result->policy_files_hashes, xstrdup((char*) item->key), (char*) item->value); } /* Destroy only the map and the keys, data was moved. */ StringMapSoftDestroy(extra_hashes); } /* Should result take over a release_id ? */ free(a->release_id); free(b->release_id); free(a); free(b); return result; } /*************************************************************************/ const char *ConstraintGetNamespace(const Constraint *cp) { switch (cp->type) { case POLICY_ELEMENT_TYPE_BODY: return cp->parent.body->ns; case POLICY_ELEMENT_TYPE_PROMISE: return cp->parent.promise->parent_section->parent_bundle->ns; default: ProgrammingError("Constraint has parent type: %d", cp->type); } } /*************************************************************************/ /** * @brief Convenience function to get the policy object associated with a promise * @param promise * @return Policy object */ const Policy *PolicyFromPromise(const Promise *promise) { assert(promise); BundleSection *section = promise->parent_section; assert(section != NULL); Bundle *bundle = section->parent_bundle; assert(bundle); return bundle->parent_policy; } char *BundleQualifiedName(const Bundle *bundle) { assert(bundle); if (!bundle) { return NULL; } if (bundle->name) { const char *ns = bundle->ns ? bundle->ns : NamespaceDefault(); return StringConcatenate(3, ns, ":", bundle->name); // CF_NS == ':' } return NULL; } static bool RvalTypeCheckDataType(RvalType rval_type, DataType expected_datatype) { if (rval_type == RVAL_TYPE_FNCALL) { return true; } switch (expected_datatype) { case CF_DATA_TYPE_BODY: case CF_DATA_TYPE_BUNDLE: return rval_type == RVAL_TYPE_SCALAR; case CF_DATA_TYPE_CONTEXT: case CF_DATA_TYPE_COUNTER: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_INT_RANGE: case CF_DATA_TYPE_OPTION: case CF_DATA_TYPE_REAL: case CF_DATA_TYPE_REAL_RANGE: case CF_DATA_TYPE_STRING: return rval_type == RVAL_TYPE_SCALAR; case CF_DATA_TYPE_CONTEXT_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_OPTION_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_STRING_LIST: return (rval_type == RVAL_TYPE_SCALAR) || (rval_type == RVAL_TYPE_LIST); case CF_DATA_TYPE_CONTAINER: return (rval_type == RVAL_TYPE_CONTAINER); default: ProgrammingError("Unhandled expected datatype in switch: %d", expected_datatype); } } /*************************************************************************/ /* Check if a constraint's syntax is correct according to its promise_type and lvalue. */ static bool ConstraintCheckSyntax(const Constraint *constraint, Seq *errors) { assert(constraint != NULL); if (constraint->type != POLICY_ELEMENT_TYPE_PROMISE) { ProgrammingError("Attempted to check the syntax for a constraint" " not belonging to a promise"); } const BundleSection *section = constraint->parent.promise->parent_section; const Bundle *bundle = section->parent_bundle; /* Check if lvalue is valid for the bundle's specific section. */ const PromiseTypeSyntax *promise_type_syntax = PromiseTypeSyntaxGet(bundle->type, section->promise_type); for (size_t i = 0; promise_type_syntax->constraints[i].lval != NULL; i++) { const ConstraintSyntax *body_syntax = &promise_type_syntax->constraints[i]; if (strcmp(body_syntax->lval, constraint->lval) == 0) { if (!RvalTypeCheckDataType(constraint->rval.type, body_syntax->dtype)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, constraint, POLICY_ERROR_CONSTRAINT_TYPE_MISMATCH, constraint->lval)); return false; } return true; } } /* FIX: Call a VerifyConstraint() hook for the specific promise_type, defined in verify_TYPE.c, that checks for promise_type-specific constraint syntax. */ /* Check if lvalue is valid for all bodies. */ for (size_t i = 0; CF_COMMON_BODIES[i].lval != NULL; i++) { if (strcmp(constraint->lval, CF_COMMON_BODIES[i].lval) == 0) { if (!RvalTypeCheckDataType(constraint->rval.type, CF_COMMON_BODIES[i].dtype)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, constraint, POLICY_ERROR_CONSTRAINT_TYPE_MISMATCH, constraint->lval)); return false; } return true; } } for (size_t i = 0; CF_COMMON_EDITBODIES[i].lval != NULL; i++) { if (strcmp(constraint->lval, CF_COMMON_EDITBODIES[i].lval) == 0) { if (!RvalTypeCheckDataType(constraint->rval.type, CF_COMMON_EDITBODIES[i].dtype)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, constraint, POLICY_ERROR_CONSTRAINT_TYPE_MISMATCH, constraint->lval)); return false; } return true; } } for (size_t i = 0; CF_COMMON_XMLBODIES[i].lval != NULL; i++) { if (strcmp(constraint->lval, CF_COMMON_XMLBODIES[i].lval) == 0) { if (!RvalTypeCheckDataType(constraint->rval.type, CF_COMMON_XMLBODIES[i].dtype)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, constraint, POLICY_ERROR_CONSTRAINT_TYPE_MISMATCH, constraint->lval)); return false; } return true; } } /* lval is unknown for this promise type */ SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, constraint, POLICY_ERROR_LVAL_INVALID, constraint->parent.promise->parent_section->promise_type, constraint->lval)); return false; } /*************************************************************************/ static bool PolicyCheckPromiseType(const BundleSection *section, Seq *errors) { assert(section != NULL); assert(section->parent_bundle); bool success = true; for (size_t i = 0; i < SeqLength(section->promises); i++) { const Promise *pp = SeqAt(section->promises, i); success &= PromiseCheck(pp, errors); } return success; } /*************************************************************************/ static inline bool PolicyCheckBundleSections(Seq * sections, Seq *errors) { bool success = true; const size_t length = SeqLength(sections); for (size_t i = 0; i < length; i++) { const BundleSection *section = SeqAt(sections, i); success &= PolicyCheckPromiseType(section, errors); } return success; } static bool PolicyCheckBundle(const Bundle *bundle, Seq *errors) { assert(bundle); bool success = true; // ensure no reserved bundle names are used { static const char *const reserved_names[] = { "sys", "const", "mon", "edit", "match", "mon", "this", NULL }; if (IsStrIn(bundle->name, reserved_names)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BUNDLE, bundle, POLICY_ERROR_BUNDLE_NAME_RESERVED, bundle->name)); success = false; } } success &= PolicyCheckBundleSections(bundle->sections, errors); success &= PolicyCheckBundleSections(bundle->custom_sections, errors); return success; } static bool PolicyCheckBody(const Body *body, Seq *errors) { bool success = true; if (strcmp("control", body->name) == 0) { if (RlistLen(body->args) > 0) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, body, POLICY_ERROR_BODY_CONTROL_ARGS, body->type)); success = false; } } for (size_t i = 0; i < SeqLength(body->conlist); i++) { Constraint *cp = SeqAt(body->conlist, i); SyntaxTypeMatch err = ConstraintCheckType(cp); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp, POLICY_ERROR_CONSTRAINT_TYPE_MISMATCH, cp->lval)); success = false; } } const BodySyntax *body_syntax = BodySyntaxGet(PARSER_BLOCK_BODY, body->type); assert(body_syntax && "Should have been checked at parse time"); if (body_syntax->check_body) { success &= body_syntax->check_body(body, errors); } return success; } /*************************************************************************/ /* Get the syntax of a constraint according to its promise_type and lvalue. Make sure you've already checked the constraint's validity. */ static const ConstraintSyntax *ConstraintGetSyntax(const Constraint *constraint) { if (constraint->type != POLICY_ELEMENT_TYPE_PROMISE) { ProgrammingError("Attempted to get the syntax for a constraint not belonging to a promise"); } const Promise *promise = constraint->parent.promise; const BundleSection *section = promise->parent_section; const Bundle *bundle = section->parent_bundle; const PromiseTypeSyntax *promise_type_syntax = PromiseTypeSyntaxGet(bundle->type, section->promise_type); /* Check if lvalue is valid for the bundle's specific section. */ for (size_t i = 0; promise_type_syntax->constraints[i].lval != NULL; i++) { const ConstraintSyntax *body_syntax = &promise_type_syntax->constraints[i]; if (strcmp(body_syntax->lval, constraint->lval) == 0) { return body_syntax; } } /* Check if lvalue is valid for all bodies. */ for (size_t i = 0; CF_COMMON_BODIES[i].lval != NULL; i++) { if (strcmp(constraint->lval, CF_COMMON_BODIES[i].lval) == 0) { return &CF_COMMON_BODIES[i]; } } for (size_t i = 0; CF_COMMON_EDITBODIES[i].lval != NULL; i++) { if (strcmp(constraint->lval, CF_COMMON_EDITBODIES[i].lval) == 0) { return &CF_COMMON_EDITBODIES[i]; } } for (size_t i = 0; CF_COMMON_XMLBODIES[i].lval != NULL; i++) { if (strcmp(constraint->lval, CF_COMMON_XMLBODIES[i].lval) == 0) { return &CF_COMMON_XMLBODIES[i]; } } /* Syntax must have been checked first during PolicyCheckPartial(). */ ProgrammingError("ConstraintGetSyntax() was called for constraint with " "invalid lvalue: %s", constraint->lval); return NULL; } /*************************************************************************/ /** * @return A reference to the full symbol value of the Rval regardless of type, e.g. "foo:bar""foo:bar" */ static const char *RvalFullSymbol(const Rval *rval) { switch (rval->type) { case RVAL_TYPE_SCALAR: return rval->item; break; case RVAL_TYPE_FNCALL: return ((FnCall *)rval->item)->name; default: ProgrammingError("Cannot get full symbol value from Rval of type %c", rval->type); return NULL; } } /** * @return A copy of the namespace component of a qualified name, or NULL. e.g. "foo:bar" -> "foo" */ char *QualifiedNameNamespaceComponent(const char *qualified_name) { if (strchr(qualified_name, CF_NS)) { char ns[256] = { 0 }; sscanf(qualified_name, "%255[^:]", ns); return xstrdup(ns); } else { return NULL; } } /** * @return A copy of the symbol compoent of a qualified name, or NULL. e.g. "foo:bar" -> "bar" */ char *QualifiedNameScopeComponent(const char *qualified_name) { char *sep = strchr(qualified_name, CF_NS); if (sep) { return xstrdup(sep + 1); } else { return xstrdup(qualified_name); } } static bool PolicyCheckUndefinedBodies(const Policy *policy, Seq *errors) { bool success = true; for (size_t bpi = 0; bpi < SeqLength(policy->bundles); bpi++) { Bundle *bundle = SeqAt(policy->bundles, bpi); for (size_t sti = 0; sti < SeqLength(bundle->sections); sti++) { BundleSection *section = SeqAt(bundle->sections, sti); for (size_t ppi = 0; ppi < SeqLength(section->promises); ppi++) { Promise *promise = SeqAt(section->promises, ppi); for (size_t cpi = 0; cpi < SeqLength(promise->conlist); cpi++) { Constraint *constraint = SeqAt(promise->conlist, cpi); const ConstraintSyntax *syntax = ConstraintGetSyntax(constraint); if (syntax->dtype == CF_DATA_TYPE_BODY) { char *ns = QualifiedNameNamespaceComponent(RvalFullSymbol(&constraint->rval)); char *symbol = QualifiedNameScopeComponent(RvalFullSymbol(&constraint->rval)); Body *referenced_body = PolicyGetBody(policy, ns, constraint->lval, symbol); if (!referenced_body) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, constraint, POLICY_ERROR_BODY_UNDEFINED, symbol, constraint->lval)); success = false; } free(ns); free(symbol); } } // constraints } // promises } // promise_types } // bundles return success; } static bool PolicyCheckRequiredComments(const EvalContext *ctx, const Policy *policy, Seq *errors) { const Body *common_control = PolicyGetBody(policy, NULL, "common", "control"); if (common_control) { bool require_comments = ConstraintsGetAsBoolean(ctx, "require_comments", common_control->conlist); if (!require_comments) { return true; } bool success = true; for (size_t bpi = 0; bpi < SeqLength(policy->bundles); bpi++) { Bundle *bundle = SeqAt(policy->bundles, bpi); for (size_t sti = 0; sti < SeqLength(bundle->sections); sti++) { BundleSection *section = SeqAt(bundle->sections, sti); for (size_t ppi = 0; ppi < SeqLength(section->promises); ppi++) { Promise *promise = SeqAt(section->promises, ppi); bool promise_has_comment = false; for (size_t cpi = 0; cpi < SeqLength(promise->conlist); cpi++) { Constraint *constraint = SeqAt(promise->conlist, cpi); if (strcmp(constraint->lval, "comment") == 0) { promise_has_comment = true; break; } } // constraints if (!promise_has_comment) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, promise, POLICY_ERROR_PROMISE_UNCOMMENTED)); success = false; } } // promises } // promise_types } // bundles return success; } else { return true; } } bool PolicyCheckDuplicateHandles(const Policy *policy, Seq *errors) { bool success = true; Map *recorded = MapNew(StringHash_untyped, StringEqual_untyped, NULL, NULL); for (size_t bpi = 0; bpi < SeqLength(policy->bundles); bpi++) { Bundle *bundle = SeqAt(policy->bundles, bpi); for (size_t sti = 0; sti < SeqLength(bundle->sections); sti++) { BundleSection *section = SeqAt(bundle->sections, sti); for (size_t ppi = 0; ppi < SeqLength(section->promises); ppi++) { Promise *promise = SeqAt(section->promises, ppi); const char *handle = PromiseGetHandle(promise); if (handle) { if (IsCf3VarString(handle)) { // can't check dynamic handles continue; } const Promise *other_promise = MapGet(recorded, handle); if (other_promise) { // Need to make this smarter by comparing parsed expressions for equivalency. if (strcmp(promise->classes, other_promise->classes) == 0) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, promise, POLICY_ERROR_PROMISE_DUPLICATE_HANDLE, handle)); success = false; } } else { MapInsert(recorded, (void *)handle, (void *)promise); } } } } } MapDestroy(recorded); return success; } /** * @brief Check a runnable policy DOM for errors * @param policy Policy to check * @param errors Sequence of PolicyError to append errors to * @param ignore_missing_bundles Whether to ignore missing bundle references * @return True if no new errors are found */ bool PolicyCheckRunnable(const EvalContext *ctx, const Policy *policy, Seq *errors) { bool success = true; success &= PolicyCheckRequiredComments(ctx, policy, errors); success &= PolicyCheckUndefinedBodies(policy, errors); success &= PolicyCheckDuplicateHandles(policy, errors); return success; } /** * @brief Check a partial policy DOM for errors * @param policy Policy to check * @param errors Sequence of PolicyError to append errors to * @return True if no new errors are found */ bool PolicyCheckPartial(const Policy *policy, Seq *errors) { bool success = true; // ensure bundle names are not duplicated for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); for (size_t j = 0; j < SeqLength(policy->bundles); j++) { Bundle *bp2 = SeqAt(policy->bundles, j); if (bp != bp2 && strcmp(bp->type, bp2->type) == 0 && strcmp(bp->ns, bp2->ns) == 0 && strcmp(bp->name, bp2->name) == 0) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BUNDLE, bp, POLICY_ERROR_BUNDLE_REDEFINITION, bp->name, bp->type)); success = false; } } } for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); success &= PolicyCheckBundle(bp, errors); } // ensure body names are not duplicated for (size_t i = 0; i < SeqLength(policy->bodies); i++) { const Body *bp = SeqAt(policy->bodies, i); for (size_t j = 0; j < SeqLength(policy->bodies); j++) { const Body *bp2 = SeqAt(policy->bodies, j); if (bp != bp2 && strcmp(bp->type, bp2->type) == 0 && strcmp(bp->ns, bp2->ns) == 0 && strcmp(bp->name, bp2->name) == 0) { if (strcmp(bp->type,"file") != 0) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BODY, bp, POLICY_ERROR_BODY_REDEFINITION, bp->name, bp->type)); success = false; } } } } for (size_t i = 0; i < SeqLength(policy->bodies); i++) { const Body *body = SeqAt(policy->bodies, i); success &= PolicyCheckBody(body, errors); } success &= PolicyCheckDuplicateHandles(policy, errors); return success; } /*************************************************************************/ PolicyError *PolicyErrorNew(PolicyElementType type, const void *subject, const char *error_msg, ...) { PolicyError *error = xmalloc(sizeof(PolicyError)); error->type = type; error->subject = subject; va_list args; va_start(args, error_msg); xvasprintf(&error->message, error_msg, args); va_end(args); return error; } /*************************************************************************/ void PolicyErrorDestroy(PolicyError *error) { free(error->message); free(error); } /*************************************************************************/ static SourceOffset PolicyElementSourceOffset(PolicyElementType type, const void *element) { assert(element); switch (type) { case POLICY_ELEMENT_TYPE_POLICY: { return (SourceOffset) { 0 }; } case POLICY_ELEMENT_TYPE_BUNDLE: { const Bundle *bundle = (const Bundle *)element; return bundle->offset; } case POLICY_ELEMENT_TYPE_BODY: { const Body *body = (const Body *)element; return body->offset; } case POLICY_ELEMENT_TYPE_BUNDLE_SECTION: { const BundleSection *section = (const BundleSection *) element; return section->offset; } case POLICY_ELEMENT_TYPE_PROMISE: { const Promise *promise = (const Promise *)element; return promise->offset; } case POLICY_ELEMENT_TYPE_CONSTRAINT: { const Constraint *constraint = (const Constraint *)element; return constraint->offset; } default: assert(false && "Invalid policy element"); return (SourceOffset) { 0 }; } } /*************************************************************************/ static const char *PolicyElementSourceFile(PolicyElementType type, const void *element) { assert(element); switch (type) { case POLICY_ELEMENT_TYPE_POLICY: return ""; case POLICY_ELEMENT_TYPE_BUNDLE: { const Bundle *bundle = (const Bundle *)element; return bundle->source_path; } case POLICY_ELEMENT_TYPE_BODY: { const Body *body = (const Body *)element; return body->source_path; } case POLICY_ELEMENT_TYPE_BUNDLE_SECTION: { const BundleSection *section = (const BundleSection *) element; return PolicyElementSourceFile(POLICY_ELEMENT_TYPE_BUNDLE, section->parent_bundle); } case POLICY_ELEMENT_TYPE_PROMISE: { const Promise *promise = (const Promise *)element; return PolicyElementSourceFile(POLICY_ELEMENT_TYPE_BUNDLE_SECTION, promise->parent_section); } case POLICY_ELEMENT_TYPE_CONSTRAINT: { const Constraint *constraint = (const Constraint *)element; switch (constraint->type) { case POLICY_ELEMENT_TYPE_BODY: return PolicyElementSourceFile(POLICY_ELEMENT_TYPE_BODY, constraint->parent.body); case POLICY_ELEMENT_TYPE_PROMISE: return PolicyElementSourceFile(POLICY_ELEMENT_TYPE_PROMISE, constraint->parent.promise); default: assert(false && "Constraint has invalid parent element type"); return NULL; } } default: assert(false && "Invalid policy element"); return NULL; } } /*************************************************************************/ void PolicyErrorWrite(Writer *writer, const PolicyError *error) { SourceOffset offset = PolicyElementSourceOffset(error->type, error->subject); const char *path = PolicyElementSourceFile(error->type, error->subject); // FIX: need to track columns in SourceOffset WriterWriteF(writer, "%s:%zu:%zu: error: %s\n", path, offset.line, (size_t)0, error->message); } static char *PolicyErrorToString(const PolicyError *error) { SourceOffset offset = PolicyElementSourceOffset(error->type, error->subject); const char *path = PolicyElementSourceFile(error->type, error->subject); Writer *msg = StringWriter(); WriterWriteF(msg, "%s:%zu:%zu: %s.", path, offset.line, (size_t)0, error->message); if (error->type == POLICY_ELEMENT_TYPE_CONSTRAINT) { const Constraint *cp = error->subject; WriterWrite(msg, " Given attribute value '"); RvalWrite(msg, cp->rval); WriterWriteChar(msg, '\''); } return StringWriterClose(msg); } /*************************************************************************/ void BundleSectionDestroy(BundleSection *section) { if (section != NULL) { SeqDestroy(section->promises); free(section->promise_type); free(section); } } Bundle *PolicyAppendBundle(Policy *policy, const char *ns, const char *name, const char *type, const Rlist *args, const char *source_path) { Bundle *bundle = xcalloc(1, sizeof(Bundle)); bundle->parent_policy = policy; SeqAppend(policy->bundles, bundle); bundle->name = xstrdup(name); bundle->type = xstrdup(type); bundle->ns = xstrdup(ns); bundle->args = RlistCopy(args); bundle->source_path = SafeStringDuplicate(source_path); bundle->sections = SeqNew(10, BundleSectionDestroy); bundle->custom_sections = SeqNew(10, BundleSectionDestroy); return bundle; } /*******************************************************************/ Body *PolicyAppendBody(Policy *policy, const char *ns, const char *name, const char *type, Rlist *args, const char *source_path, bool is_custom) { Body *body = xcalloc(1, sizeof(Body)); body->parent_policy = policy; SeqAppend(policy->bodies, body); body->name = xstrdup(name); body->type = xstrdup(type); body->ns = xstrdup(ns); body->args = RlistCopy(args); body->source_path = SafeStringDuplicate(source_path); body->conlist = SeqNew(10, ConstraintDestroy); body->is_custom = is_custom; // TODO: move to standard callback if (strcmp("service_method", body->name) == 0) { Rlist *bundle_args = NULL; RlistAppendRval(&bundle_args, RvalNew("$(this.promiser)", RVAL_TYPE_SCALAR)); RlistAppendRval(&bundle_args, RvalNew("$(this.service_policy)", RVAL_TYPE_SCALAR)); FnCall *service_bundle = FnCallNew("standard_services", bundle_args); BodyAppendConstraint(body, "service_bundle", (Rval) { service_bundle, RVAL_TYPE_FNCALL }, "any", false); } return body; } /*******************************************************************/ Body *PolicyAppendPromiseBlock( Policy *policy, const char *ns, const char *name, const char *type, Rlist *args, const char *source_path) { assert(policy != NULL); Body *body = xcalloc(1, sizeof(Body)); body->parent_policy = policy; SeqAppend(policy->custom_promise_types, body); body->name = xstrdup(name); body->type = xstrdup(type); body->ns = xstrdup(ns); body->args = RlistCopy(args); body->source_path = SafeStringDuplicate(source_path); body->conlist = SeqNew(10, ConstraintDestroy); return body; } /*******************************************************************/ BundleSection *BundleAppendSection(Bundle *bundle, const char *promise_type) { if (bundle == NULL) { ProgrammingError("Attempt to add a type without a bundle"); } // TODO: review SeqLookup for (size_t i = 0; i < SeqLength(bundle->sections); i++) { BundleSection *existing = SeqAt(bundle->sections, i); if (strcmp(existing->promise_type, promise_type) == 0) { return existing; } } for (size_t i = 0; i < SeqLength(bundle->custom_sections); i++) { BundleSection *existing = SeqAt(bundle->custom_sections, i); if (strcmp(existing->promise_type, promise_type) == 0) { return existing; } } BundleSection *section = xcalloc(1, sizeof(BundleSection)); section->parent_bundle = bundle; section->promise_type = xstrdup(promise_type); section->promises = SeqNew(10, PromiseDestroy); if (IsBuiltInPromiseType(promise_type)) { SeqAppend(bundle->sections, section); } else { SeqAppend(bundle->custom_sections, section); } return section; } /*******************************************************************/ Promise *BundleSectionAppendPromise(BundleSection *section, const char *promiser, Rval promisee, const char *classes, const char *varclasses) { assert(promiser && "Missing promiser"); assert(section != NULL && "Missing promise type"); Promise *pp = xcalloc(1, sizeof(Promise)); pp->promiser = xstrdup(promiser); if (classes && strlen(classes) > 0) { pp->classes = xstrdup(classes); } else { pp->classes = xstrdup("any"); } SeqAppend(section->promises, pp); pp->parent_section = section; pp->promisee = promisee; pp->conlist = SeqNew(10, ConstraintDestroy); pp->org_pp = pp; if (varclasses != NULL) { PromiseAppendConstraint(pp, "ifvarclass", RvalNew(varclasses, RVAL_TYPE_SCALAR), true); } return pp; } static void BundleDestroy(Bundle *bundle) { if (bundle != NULL) { free(bundle->name); free(bundle->type); free(bundle->ns); free(bundle->source_path); RlistDestroy(bundle->args); SeqDestroy(bundle->sections); SeqDestroy(bundle->custom_sections); free(bundle); } } static void BodyDestroy(Body *body) { if (body) { free(body->name); free(body->type); free(body->ns); free(body->source_path); RlistDestroy(body->args); SeqDestroy(body->conlist); free(body); } } void PromiseDestroy(Promise *pp) { if (pp) { free(pp->promiser); if (pp->promisee.item) { RvalDestroy(pp->promisee); } free(pp->classes); free(pp->comment); SeqDestroy(pp->conlist); free(pp); } } /*******************************************************************/ static Constraint *ConstraintNew(const char *lval, Rval rval, const char *classes, bool references_body) { Constraint *cp = xcalloc(1, sizeof(Constraint)); cp->lval = SafeStringDuplicate(lval); cp->rval = rval; cp->classes = SafeStringDuplicate(classes); cp->references_body = references_body; return cp; } Constraint *PromiseAppendConstraint(Promise *pp, const char *lval, Rval rval, bool references_body) { Constraint *cp = ConstraintNew(lval, rval, "any", references_body); cp->type = POLICY_ELEMENT_TYPE_PROMISE; cp->parent.promise = pp; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *old_cp = SeqAt(pp->conlist, i); if (strcmp(old_cp->lval, lval) == 0) { if (strcmp(old_cp->lval, "ifvarclass") == 0 || strcmp(old_cp->lval, "if") == 0) { // merge two if/ifvarclass promise attributes this // only happens in a variable context when we have a // scalar already in the attribute (old_cp) switch (rval.type) { case RVAL_TYPE_FNCALL: // case 1: merge FnCall with scalar { char * rval_string = RvalToString(old_cp->rval); Log(LOG_LEVEL_DEBUG, "PromiseAppendConstraint: merging PREVIOUS %s string context rval %s", old_cp->lval, rval_string); Log(LOG_LEVEL_DEBUG, "PromiseAppendConstraint: merging NEW %s rval %s", old_cp->lval, rval_string); free(rval_string); Rlist *synthetic_args = NULL; RlistAppendScalar(&synthetic_args, RvalScalarValue(old_cp->rval)); // append the old Rval (a function call) under the arguments of the new one RlistAppend(&synthetic_args, rval.item, RVAL_TYPE_FNCALL); Rval replacement = (Rval) { FnCallNew("and", synthetic_args), RVAL_TYPE_FNCALL }; rval_string = RvalToString(replacement); Log(LOG_LEVEL_DEBUG, "PromiseAppendConstraint: MERGED %s rval %s", old_cp->lval, rval_string); free(rval_string); // overwrite the old Constraint rval with its replacement RvalDestroy(cp->rval); cp->rval = replacement; } break; case RVAL_TYPE_SCALAR: // case 2: merge scalar with scalar { Buffer *grow = BufferNew(); BufferAppendF(grow, "(%s).(%s)", RvalScalarValue(old_cp->rval), RvalScalarValue(rval)); RvalDestroy(cp->rval); rval = RvalNew(BufferData(grow), RVAL_TYPE_SCALAR); BufferDestroy(grow); cp->rval = rval; } break; default: ProgrammingError("PromiseAppendConstraint: unexpected rval type: %c", rval.type); break; } } SeqSet(pp->conlist, i, cp); return cp; } } SeqAppend(pp->conlist, cp); return cp; } Constraint *BodyAppendConstraint(Body *body, const char *lval, Rval rval, const char *classes, bool references_body) { Constraint *cp = ConstraintNew(lval, rval, classes, references_body); cp->type = POLICY_ELEMENT_TYPE_BODY; cp->parent.body = body; for (size_t i = 0; i < SeqLength(body->conlist); i++) { Constraint *old_cp = SeqAt(body->conlist, i); if (strcmp(old_cp->lval, lval) == 0 && strcmp(old_cp->classes, classes) == 0) { SeqSet(body->conlist, i, cp); return cp; } } SeqAppend(body->conlist, cp); return cp; } /*******************************************************************/ const BundleSection *BundleGetSection(const Bundle *bp, const char *promise_type) { // TODO: hiding error, remove and see what will crash if (bp == NULL) { return NULL; } for (size_t i = 0; i < SeqLength(bp->sections); i++) { BundleSection *sp = SeqAt(bp->sections, i); if (strcmp(promise_type, sp->promise_type) == 0) { return sp; } } return NULL; } /****************************************************************************/ static Buffer *EscapeQuotes(const char *raw, Buffer *out) { const char *spf; for (spf = raw; *spf != '\0'; spf++) { switch (*spf) { case '\'': case '\"': BufferAppendChar(out, '\\'); break; default: break; } BufferAppendChar(out, *spf); } return out; } /** * Converts the given attribute rval to a JSON object. * * @return A JsonElement of type JSON_ELEMENT_TYPE_CONTAINER */ static JsonElement *AttributeValueToJson(Rval rval, bool symbolic_reference) { switch (rval.type) { case RVAL_TYPE_CONTAINER: { return JsonCopy(RvalContainerValue(rval)); } case RVAL_TYPE_SCALAR: { Buffer *buffer = BufferNewWithCapacity(strlen(rval.item)); EscapeQuotes((const char *) rval.item, buffer); JsonElement *json_attribute = JsonObjectCreate(10); if (symbolic_reference) { JsonObjectAppendString(json_attribute, "type", "symbol"); } else { JsonObjectAppendString(json_attribute, "type", "string"); } JsonObjectAppendString(json_attribute, "value", BufferData(buffer)); BufferDestroy(buffer); return json_attribute; } case RVAL_TYPE_LIST: { Rlist *rp = NULL; JsonElement *list = JsonArrayCreate(10); JsonElement *json_attribute = JsonObjectCreate(10); JsonObjectAppendString(json_attribute, "type", "list"); for (rp = (Rlist *) rval.item; rp != NULL; rp = rp->next) { JsonArrayAppendObject(list, AttributeValueToJson(rp->val, false)); } JsonObjectAppendArray(json_attribute, "value", list); return json_attribute; } case RVAL_TYPE_FNCALL: { Rlist *argp = NULL; FnCall *call = (FnCall *) rval.item; JsonElement *json_attribute = JsonObjectCreate(10); JsonObjectAppendString(json_attribute, "type", "functionCall"); JsonObjectAppendString(json_attribute, "name", call->name); { JsonElement *arguments = JsonArrayCreate(10); for (argp = call->args; argp != NULL; argp = argp->next) { JsonArrayAppendObject(arguments, AttributeValueToJson(argp->val, false)); } JsonObjectAppendArray(json_attribute, "arguments", arguments); } return json_attribute; } case RVAL_TYPE_NOPROMISEE: ProgrammingError("Attempted to export attribute of type: %c", rval.type); return NULL; } assert(false); return NULL; } static JsonElement *CreateContextAsJson(const char *name, const char *children_name, JsonElement *children) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "name", name); JsonObjectAppendArray(json, children_name, children); return json; } static JsonElement *BodyContextsToJson(const Seq *constraints) { JsonElement *json_contexts = JsonArrayCreate(10); JsonElement *json_attributes = JsonArrayCreate(10); char *current_context = "any"; for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); JsonElement *json_attribute = JsonObjectCreate(10); if (strcmp(current_context, cp->classes) != 0) { JsonArrayAppendObject(json_contexts, CreateContextAsJson(current_context, "attributes", json_attributes)); json_attributes = JsonArrayCreate(10); current_context = cp->classes; } JsonObjectAppendInteger(json_attribute, "line", cp->offset.line); JsonObjectAppendString(json_attribute, "lval", cp->lval); JsonObjectAppendObject(json_attribute, "rval", AttributeValueToJson(cp->rval, false)); JsonArrayAppendObject(json_attributes, json_attribute); } JsonArrayAppendObject(json_contexts, CreateContextAsJson(current_context, "attributes", json_attributes)); return json_contexts; } static JsonElement *BundleContextsToJson(const Seq *promises) { JsonElement *json_contexts = JsonArrayCreate(10); JsonElement *json_promises = JsonArrayCreate(10); char *current_context = NULL; for (size_t ppi = 0; ppi < SeqLength(promises); ppi++) { Promise *pp = SeqAt(promises, ppi); if (!current_context) { current_context = pp->classes; } JsonElement *json_promise = JsonObjectCreate(10); if (strcmp(current_context, pp->classes) != 0) { JsonArrayAppendObject(json_contexts, CreateContextAsJson(current_context, "promises", json_promises)); json_promises = JsonArrayCreate(10); current_context = pp->classes; } JsonObjectAppendInteger(json_promise, "line", pp->offset.line); { JsonElement *json_promise_attributes = JsonArrayCreate(10); for (size_t k = 0; k < SeqLength(pp->conlist); k++) { Constraint *cp = SeqAt(pp->conlist, k); JsonElement *json_attribute = JsonObjectCreate(10); JsonObjectAppendInteger(json_attribute, "line", cp->offset.line); JsonObjectAppendString(json_attribute, "lval", cp->lval); JsonElement *json_rval = AttributeValueToJson(cp->rval, cp->references_body); if (JsonGetContainerType(json_rval) == JSON_CONTAINER_TYPE_ARRAY) { JsonObjectAppendArray(json_attribute, "rval", json_rval); } else { JsonObjectAppendObject(json_attribute, "rval", json_rval); } JsonArrayAppendObject(json_promise_attributes, json_attribute); } JsonObjectAppendString(json_promise, "promiser", pp->promiser); switch (pp->promisee.type) { case RVAL_TYPE_SCALAR: JsonObjectAppendString(json_promise, "promisee", pp->promisee.item); break; case RVAL_TYPE_LIST: { JsonElement *promisee_list = JsonArrayCreate(10); for (const Rlist *rp = pp->promisee.item; rp; rp = rp->next) { JsonArrayAppendString(promisee_list, RlistScalarValue(rp)); } JsonObjectAppendArray(json_promise, "promisee", promisee_list); } break; default: break; } JsonObjectAppendArray(json_promise, "attributes", json_promise_attributes); } JsonArrayAppendObject(json_promises, json_promise); } if (JsonLength(json_promises) > 0) { JsonArrayAppendObject(json_contexts, CreateContextAsJson(current_context, "promises", json_promises)); } return json_contexts; } /** * @brief Serialize a bundle as JSON * @param bundle The bundle to serialize * @return A JsonElement representing the input bundle */ JsonElement *BundleToJson(const Bundle *bundle) { JsonElement *json_bundle = JsonObjectCreate(10); if (bundle->source_path) { JsonObjectAppendString(json_bundle, "sourcePath", bundle->source_path); } JsonObjectAppendInteger(json_bundle, "line", bundle->offset.line); JsonObjectAppendString(json_bundle, "namespace", bundle->ns); JsonObjectAppendString(json_bundle, "name", bundle->name); JsonObjectAppendString(json_bundle, "bundleType", bundle->type); { JsonElement *json_args = JsonArrayCreate(10); Rlist *argp = NULL; for (argp = bundle->args; argp != NULL; argp = argp->next) { JsonArrayAppendString(json_args, RlistScalarValue(argp)); } JsonObjectAppendArray(json_bundle, "arguments", json_args); } { JsonElement *json_promise_types = JsonArrayCreate(10); for (size_t i = 0; i < SeqLength(bundle->sections); i++) { const BundleSection *sp = SeqAt(bundle->sections, i); JsonElement *json_promise_type = JsonObjectCreate(10); JsonObjectAppendInteger(json_promise_type, "line", sp->offset.line); JsonObjectAppendString(json_promise_type, "name", sp->promise_type); JsonObjectAppendArray(json_promise_type, "contexts", BundleContextsToJson(sp->promises)); JsonArrayAppendObject(json_promise_types, json_promise_type); } JsonObjectAppendArray(json_bundle, "promiseTypes", json_promise_types); } return json_bundle; } /** * @brief Serialize a body as JSON * @param body The body to serialize * @return A JsonElement representing the input body */ JsonElement *BodyToJson(const Body *body) { JsonElement *json_body = JsonObjectCreate(10); if (body->source_path) { JsonObjectAppendString(json_body, "sourcePath", body->source_path); } JsonObjectAppendInteger(json_body, "line", body->offset.line); JsonObjectAppendString(json_body, "namespace", body->ns); JsonObjectAppendString(json_body, "name", body->name); JsonObjectAppendString(json_body, "bodyType", body->type); { JsonElement *json_args = JsonArrayCreate(10); Rlist *argp = NULL; for (argp = body->args; argp != NULL; argp = argp->next) { JsonArrayAppendString(json_args, RlistScalarValue(argp)); } JsonObjectAppendArray(json_body, "arguments", json_args); } JsonObjectAppendArray(json_body, "contexts", BodyContextsToJson(body->conlist)); return json_body; } /** * @brief Serialize a policy as JSON * @param policy The policy to serialize * @return A JsonElement representing the input policy */ JsonElement *PolicyToJson(const Policy *policy) { JsonElement *json_policy = JsonObjectCreate(10); { JsonElement *json_bundles = JsonArrayCreate(10); for (size_t i = 0; i < SeqLength(policy->bundles); i++) { const Bundle *bp = SeqAt(policy->bundles, i); JsonArrayAppendObject(json_bundles, BundleToJson(bp)); } JsonObjectAppendArray(json_policy, "bundles", json_bundles); } { JsonElement *json_bodies = JsonArrayCreate(10); for (size_t i = 0; i < SeqLength(policy->bodies); i++) { const Body *bdp = SeqAt(policy->bodies, i); JsonArrayAppendObject(json_bodies, BodyToJson(bdp)); } JsonObjectAppendArray(json_policy, "bodies", json_bodies); } return json_policy; } /****************************************************************************/ static void IndentPrint(Writer *writer, int indent_level) { static const int PRETTY_PRINT_SPACES_PER_INDENT = 2; int i = 0; for (i = 0; i < PRETTY_PRINT_SPACES_PER_INDENT * indent_level; i++) { WriterWriteChar(writer, ' '); } } static void AttributeToString(Writer *writer, Constraint *attribute, bool symbolic_reference) { WriterWriteF(writer, "%s => ", attribute->lval); if (symbolic_reference) { RvalWrite(writer, attribute->rval); } else { RvalWriteQuoted(writer, attribute->rval); } } static void ArgumentsToString(Writer *writer, Rlist *args) { Rlist *argp = NULL; WriterWriteChar(writer, '('); for (argp = args; argp != NULL; argp = argp->next) { WriterWriteF(writer, "%s", RlistScalarValue(argp)); if (argp->next != NULL) { WriterWrite(writer, ", "); } } WriterWriteChar(writer, ')'); } void BodyToString(Writer *writer, Body *body) { char *current_class = NULL; WriterWriteF(writer, "body %s %s", body->type, body->name); ArgumentsToString(writer, body->args); WriterWrite(writer, "\n{"); for (size_t i = 0; i < SeqLength(body->conlist); i++) { Constraint *cp = SeqAt(body->conlist, i); if (current_class == NULL || strcmp(cp->classes, current_class) != 0) { current_class = cp->classes; if (strcmp(current_class, "any") == 0) { WriterWrite(writer, "\n"); } else { WriterWriteF(writer, "\n\n%s::", current_class); } } IndentPrint(writer, 1); AttributeToString(writer, cp, false); WriterWriteChar(writer, ';'); WriterWriteChar(writer, '\n'); } WriterWrite(writer, "\n}\n"); } void BundleToString(Writer *writer, Bundle *bundle) { WriterWriteF(writer, "bundle %s %s", bundle->type, bundle->name); ArgumentsToString(writer, bundle->args); WriterWrite(writer, "\n{"); for (size_t i = 0; i < SeqLength(bundle->sections); i++) { BundleSection *section = SeqAt(bundle->sections, i); WriterWriteF(writer, "\n%s:\n", section->promise_type); char *current_class = NULL; for (size_t ppi = 0; ppi < SeqLength(section->promises); ppi++) { Promise *pp = SeqAt(section->promises, ppi); if (current_class == NULL || strcmp(pp->classes, current_class) != 0) { current_class = pp->classes; IndentPrint(writer, 1); WriterWriteF(writer, "%s::\n", current_class); } IndentPrint(writer, 2); ScalarWrite(writer, pp->promiser, true, false); /* FIX: add support * if (pp->promisee != NULL) { fprintf(out, "%s", pp->promisee); } */ for (size_t k = 0; k < SeqLength(pp->conlist); k++) { Constraint *cp = SeqAt(pp->conlist, k); IndentPrint(writer, 4); AttributeToString(writer, cp, cp->references_body); if (k < SeqLength(pp->conlist)-1) { WriterWriteChar(writer, ','); WriterWriteChar(writer, '\n'); } } WriterWriteChar(writer, ';'); WriterWriteChar(writer, '\n'); } if (i == (SeqLength(bundle->sections) - 1)) { WriterWriteChar(writer, '\n'); } } WriterWrite(writer, "\n}\n"); } /** * @brief Pretty-print a policy * @param policy The policy to print * @param writer Writer to write into */ void PolicyToString(const Policy *policy, Writer *writer) { for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bundle = SeqAt(policy->bundles, i); BundleToString(writer, bundle); WriterWriteChar(writer, '\n'); } for (size_t i = 0; i < SeqLength(policy->bodies); i++) { Body *body = SeqAt(policy->bodies, i); BodyToString(writer, body); WriterWriteChar(writer, '\n'); } } //***************************************************************************** static Rval RvalFromJson(JsonElement *json_rval) { const char *type = JsonObjectGetAsString(json_rval, "type"); if (strcmp("string", type) == 0 || strcmp("symbol", type) == 0) { const char *value = JsonObjectGetAsString(json_rval, "value"); return ((Rval) { xstrdup(value), RVAL_TYPE_SCALAR }); } else if (strcmp("list", type) == 0) { JsonElement *json_list = JsonObjectGetAsArray(json_rval, "value"); Rlist *rlist = NULL; for (size_t i = 0; i < JsonLength(json_list); i++) { Rval list_value = RvalFromJson(JsonArrayGetAsObject(json_list, i)); RlistAppend(&rlist, list_value.item, list_value.type); RvalDestroy(list_value); } return ((Rval) { rlist, RVAL_TYPE_LIST }); } else if (strcmp("functionCall", type) == 0) { const char *name = JsonObjectGetAsString(json_rval, "name"); JsonElement *json_args = JsonObjectGetAsArray(json_rval, "arguments"); Rlist *args = NULL; for (size_t i = 0; i < JsonLength(json_args); i++) { JsonElement *json_arg = JsonArrayGetAsObject(json_args, i); Rval arg = RvalFromJson(json_arg); RlistAppend(&args, arg.item, arg.type); RvalDestroy(arg); } FnCall *fn = FnCallNew(name, args); return ((Rval) { fn, RVAL_TYPE_FNCALL }); } else { ProgrammingError("Unexpected rval type: %s", type); } } static Constraint *PromiseAppendConstraintJson(Promise *promise, JsonElement *json_constraint) { const char *lval = JsonObjectGetAsString(json_constraint, "lval"); JsonElement *json_rval = JsonObjectGetAsObject(json_constraint, "rval"); const char *type = JsonObjectGetAsString(json_rval, "type"); Rval rval = RvalFromJson(json_rval); Constraint *cp = PromiseAppendConstraint(promise, lval, rval, (strcmp("symbol", type) == 0)); return cp; } static Promise *BundleSectionAppendPromiseJson(BundleSection *section, JsonElement *json_promise, const char *context) { const char *promiser = JsonObjectGetAsString(json_promise, "promiser"); Promise *promise = BundleSectionAppendPromise(section, promiser, (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, context, NULL); JsonElement *json_attributes = JsonObjectGetAsArray(json_promise, "attributes"); for (size_t i = 0; i < JsonLength(json_attributes); i++) { JsonElement *json_attribute = JsonArrayGetAsObject(json_attributes, i); PromiseAppendConstraintJson(promise, json_attribute); } return promise; } static BundleSection *BundleAppendSectionJson(Bundle *bundle, JsonElement *json_promise_type) { const char *name = JsonObjectGetAsString(json_promise_type, "name"); BundleSection *section = BundleAppendSection(bundle, name); JsonElement *json_contexts = JsonObjectGetAsArray(json_promise_type, "contexts"); for (size_t i = 0; i < JsonLength(json_contexts); i++) { JsonElement *json_context = JsonArrayGetAsObject(json_contexts, i); const char *context = JsonObjectGetAsString(json_context, "name"); JsonElement *json_context_promises = JsonObjectGetAsArray(json_context, "promises"); for (size_t j = 0; j < JsonLength(json_context_promises); j++) { JsonElement *json_promise = JsonArrayGetAsObject(json_context_promises, j); BundleSectionAppendPromiseJson(section, json_promise, context); } } return section; } static Bundle *PolicyAppendBundleJson(Policy *policy, JsonElement *json_bundle) { const char *ns = JsonObjectGetAsString(json_bundle, "namespace"); const char *name = JsonObjectGetAsString(json_bundle, "name"); const char *type = JsonObjectGetAsString(json_bundle, "bundleType"); const char *source_path = JsonObjectGetAsString(json_bundle, "sourcePath"); Rlist *args = NULL; { JsonElement *json_args = JsonObjectGetAsArray(json_bundle, "arguments"); for (size_t i = 0; i < JsonLength(json_args); i++) { RlistAppendScalar(&args, JsonArrayGetAsString(json_args, i)); } } Bundle *bundle = PolicyAppendBundle(policy, ns, name, type, args, source_path); { JsonElement *json_promise_types = JsonObjectGetAsArray(json_bundle, "promiseTypes"); for (size_t i = 0; i < JsonLength(json_promise_types); i++) { JsonElement *json_promise_type = JsonArrayGetAsObject(json_promise_types, i); BundleAppendSectionJson(bundle, json_promise_type); } } return bundle; } static Constraint *BodyAppendConstraintJson(Body *body, JsonElement *json_constraint, const char *context) { const char *lval = JsonObjectGetAsString(json_constraint, "lval"); JsonElement *json_rval = JsonObjectGetAsObject(json_constraint, "rval"); const char *type = JsonObjectGetAsString(json_rval, "type"); Rval rval = RvalFromJson(json_rval); Constraint *cp = BodyAppendConstraint(body, lval, rval, context, (strcmp("symbol", type) == 0)); return cp; } static Body *PolicyAppendBodyJson(Policy *policy, JsonElement *json_body) { const char *ns = JsonObjectGetAsString(json_body, "namespace"); const char *name = JsonObjectGetAsString(json_body, "name"); const char *type = JsonObjectGetAsString(json_body, "bodyType"); const char *source_path = JsonObjectGetAsString(json_body, "sourcePath"); Rlist *args = NULL; { JsonElement *json_args = JsonObjectGetAsArray(json_body, "arguments"); for (size_t i = 0; i < JsonLength(json_args); i++) { RlistAppendScalar(&args, JsonArrayGetAsString(json_args, i)); } } Body *body = PolicyAppendBody(policy, ns, name, type, args, source_path, false); RlistDestroy(args); // It's copied by PolicyAppendBody() { JsonElement *json_contexts = JsonObjectGetAsArray(json_body, "contexts"); for (size_t i = 0; i < JsonLength(json_contexts); i++) { JsonElement *json_context = JsonArrayGetAsObject(json_contexts, i); const char *context = JsonObjectGetAsString(json_context, "name"); { JsonElement *json_attributes = JsonObjectGetAsArray(json_context, "attributes"); for (size_t j = 0; j < JsonLength(json_attributes); j++) { JsonElement *json_attribute = JsonArrayGetAsObject(json_attributes, j); BodyAppendConstraintJson(body, json_attribute, context); } } } } return body; } /** * @brief Deserialize a policy from JSON * @param json_policy JSON to deserialize * @return A policy DOM */ Policy *PolicyFromJson(JsonElement *json_policy) { Policy *policy = PolicyNew(); JsonElement *json_bundles = JsonObjectGetAsArray(json_policy, "bundles"); JsonElement *json_bodies = JsonObjectGetAsArray(json_policy, "bodies"); if ((json_bundles == NULL) && (json_bodies == NULL)) { return NULL; } if (json_bundles != NULL) { for (size_t i = 0; i < JsonLength(json_bundles); i++) { JsonElement *json_bundle = JsonArrayGetAsObject(json_bundles, i); PolicyAppendBundleJson(policy, json_bundle); } } if (json_bodies != NULL) { for (size_t i = 0; i < JsonLength(json_bodies); i++) { JsonElement *json_body = JsonArrayGetAsObject(json_bodies, i); PolicyAppendBodyJson(policy, json_body); } } return policy; } /** * @brief A sequence of constraints matching the l-value. * @param body Body to query * @param lval l-value to match * @return Sequence of pointers to the constraints. Destroying it does not alter the DOM. */ Seq *BodyGetConstraint(Body *body, const char *lval) { Seq *matches = SeqNew(5, NULL); for (size_t i = 0; i < SeqLength(body->conlist); i++) { Constraint *cp = SeqAt(body->conlist, i); if (strcmp(cp->lval, lval) == 0) { SeqAppend(matches, cp); } } return matches; } bool BodyHasConstraint(const Body *body, const char *lval) { for (size_t i = 0; i < SeqLength(body->conlist); i++) { Constraint *cp = SeqAt(body->conlist, i); if (StringEqual(lval, cp->lval)) { return true; } } return false; } /** * @brief Get the context of the given constraint * @param cp * @return context. never returns NULL. */ const char *ConstraintContext(const Constraint *cp) { switch (cp->type) { case POLICY_ELEMENT_TYPE_BODY: return cp->classes; case POLICY_ELEMENT_TYPE_BUNDLE: return cp->parent.promise->classes; default: ProgrammingError("Constraint had parent element type: %d", cp->type); return NULL; } } /** * @brief Returns the first effective constraint from a list of candidates, depending on evaluation state. * @param constraints The list of potential candidates * @return The effective constraint, or NULL if none are found. */ Constraint *EffectiveConstraint(const EvalContext *ctx, Seq *constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); const char *context = ConstraintContext(cp); if (IsDefinedClass(ctx, context)) { return cp; } } return NULL; } void ConstraintDestroy(Constraint *cp) { if (cp) { RvalDestroy(cp->rval); free(cp->lval); free(cp->classes); free(cp); } } /*****************************************************************************/ /** * @brief Get the boolean value of the first effective constraint found matching, from a promise * @return true/false * @note Returns #false if no matching constraint is found */ int PromiseGetConstraintAsBoolean(const EvalContext *ctx, const char *lval, const Promise *pp) { return PromiseGetConstraintAsBooleanWithDefault(ctx, lval, pp, false, false); } /** * @brief Get the boolean value of the first effective constraint found matching, from a promise * @return true/false */ int PromiseGetConstraintAsBooleanWithDefault(const EvalContext *ctx, const char *lval, const Promise *pp, int default_val, bool with_warning) { assert(pp != NULL); int retval = CF_UNDEFINED; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (strcmp(cp->lval, lval) == 0) { if (IsDefinedClass(ctx, cp->classes)) { if (retval != CF_UNDEFINED) { Log(LOG_LEVEL_ERR, "Multiple '%s' (boolean) constraints break this promise", lval); PromiseRef(LOG_LEVEL_ERR, pp); } } else { continue; } if (cp->rval.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Type mismatch on rhs - expected type %c for boolean constraint '%s'", cp->rval.type, lval); PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Aborted"); } if (strcmp(cp->rval.item, "true") == 0 || strcmp(cp->rval.item, "yes") == 0) { retval = true; continue; } if (strcmp(cp->rval.item, "false") == 0 || strcmp(cp->rval.item, "no") == 0) { retval = false; } } } if (retval == CF_UNDEFINED) { if (with_warning) { Log(LOG_LEVEL_WARNING, "Using the default value '%s' for attribute %s (promiser: %s, file: %s:%zd), please set it explicitly", default_val ? "true" : "false", lval, pp->promiser, PromiseGetBundle(pp)->source_path, pp->offset.line); } retval = default_val; } return retval; } /*****************************************************************************/ /** * @brief Get the trinary boolean value of the first effective constraint found matching * @param lval * @param constraints * @return True/false, or CF_UNDEFINED if not found */ int ConstraintsGetAsBoolean(const EvalContext *ctx, const char *lval, const Seq *constraints) { int retval = CF_UNDEFINED; for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (strcmp(cp->lval, lval) == 0) { if (IsDefinedClass(ctx, cp->classes)) { if (retval != CF_UNDEFINED) { Log(LOG_LEVEL_ERR, "Multiple '%s' (boolean) body constraints break this promise", lval); } } else { continue; } if (cp->rval.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Type mismatch - expected type %c for boolean constraint '%s'", cp->rval.type, lval); FatalError(ctx, "Aborted"); } if (strcmp(cp->rval.item, "true") == 0 || strcmp(cp->rval.item, "yes") == 0) { retval = true; continue; } if (strcmp(cp->rval.item, "false") == 0 || strcmp(cp->rval.item, "no") == 0) { retval = false; } } } if (retval == CF_UNDEFINED) { retval = false; } return retval; } /*****************************************************************************/ bool PromiseBundleOrBodyConstraintExists(const EvalContext *ctx, const char *lval, const Promise *pp) { int retval = CF_UNDEFINED; for (size_t i = 0; i < SeqLength(pp->conlist); i++) { const Constraint *cp = SeqAt(pp->conlist, i); if (strcmp(cp->lval, lval) == 0) { if (IsDefinedClass(ctx, cp->classes)) { if (retval != CF_UNDEFINED) { Log(LOG_LEVEL_ERR, "Multiple '%s' constraints break this promise", lval); PromiseRef(LOG_LEVEL_ERR, pp); } } else { continue; } if (!(cp->rval.type == RVAL_TYPE_FNCALL || cp->rval.type == RVAL_TYPE_SCALAR)) { Log(LOG_LEVEL_ERR, "Anomalous type mismatch - type %c for bundle constraint '%s' did not match internals", cp->rval.type, lval); PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Aborted"); } return true; } } return false; } static inline bool CheckScalarNotEmptyVarRef(const char *scalar) { return (!StringEqual("$()", scalar) && !StringEqual("${}", scalar)); } static bool ValidateCustomPromise(const Promise *pp, Seq *errors) { assert(pp != NULL); assert(pp->parent_section != NULL); assert(errors != NULL); const char *const promise_type = PromiseGetPromiseType(pp); bool valid = true; Seq *attributes = pp->conlist; const size_t length = SeqLength(attributes); for (size_t i = 0; i < length; ++i) { Constraint *attribute = SeqAt(attributes, i); const char *name = attribute->lval; if (StringEqual(name, "ifvarclass")) { SeqAppend( errors, PolicyErrorNew( POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_PROMISE_ATTRIBUTE_NOT_SUPPORTED, name, "if", promise_type)); valid = false; } } // TODO: If we are running --full-check, spawn promise module and perform // validate operation. https://northerntech.atlassian.net/browse/CFE-3430 return valid; } static bool PromiseCheck(const Promise *pp, Seq *errors) { assert(pp != NULL); bool success = true; if (!CheckScalarNotEmptyVarRef(pp->promiser)) { SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_PROMISE, pp, POLICY_ERROR_EMPTY_VARREF)); success = false; } const bool is_builtin = IsBuiltInPromiseType(PromiseGetPromiseType(pp)); const PromiseTypeSyntax *pts = PromiseTypeSyntaxGet(pp->parent_section->parent_bundle->type, PromiseGetPromiseType(pp)); if (is_builtin) { if(pts == NULL) { // No promise type syntax to check for a built in promise // This should be an error, for example if trying to use // methods promises outside agent bundles SeqAppend(errors, PolicyErrorNew(POLICY_ELEMENT_TYPE_BUNDLE_SECTION, pp->parent_section, POLICY_ERROR_PROMISE_TYPE_UNSUPPORTED, pp->parent_section->promise_type, pp->parent_section->parent_bundle->type)); return false; } // check if promise's constraints are valid for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *constraint = SeqAt(pp->conlist, i); success &= ConstraintCheckSyntax(constraint, errors); } } if (pts == NULL) { assert(!is_builtin); success &= ValidateCustomPromise(pp, errors); } else if (pts->check_promise) { assert(is_builtin); success &= pts->check_promise(pp, errors); } return success; } const char *PromiseGetNamespace(const Promise *pp) { return pp->parent_section->parent_bundle->ns; } const Bundle *PromiseGetBundle(const Promise *pp) { return pp->parent_section->parent_bundle; } const Policy *PromiseGetPolicy(const Promise *pp) { return PromiseGetBundle(pp)->parent_policy; } static void BundlePath(Writer *w, const Bundle *bp) { WriterWriteChar(w, '/'); WriterWrite(w, bp->ns); WriterWriteChar(w, '/'); WriterWrite(w, bp->name); } static void PromiseTypePath(Writer *w, const BundleSection *section) { BundlePath(w, section->parent_bundle); WriterWriteChar(w, '/'); WriterWrite(w, section->promise_type); } /** * @brief Write a string describing the promise location in policy, e.g. /default/foo/packages/'emacs' */ void PromisePath(Writer *w, const Promise *pp) { PromiseTypePath(w, pp->parent_section); WriterWriteChar(w, '/'); WriterWriteChar(w, '\''); WriterWrite(w, pp->promiser); WriterWriteChar(w, '\''); } /** * @brief Return handle of the promise. * @param pp * @return Promise handle or NULL if no handle is provided */ const char *PromiseGetHandle(const Promise *pp) { return (const char *)PromiseGetImmediateRvalValue("handle", pp, RVAL_TYPE_SCALAR); } /** * @brief Get the int value of the first effective constraint found matching, from a promise * @param lval * @param pp * @return Int value, or CF_NOINT */ int PromiseGetConstraintAsInt(const EvalContext *ctx, const char *lval, const Promise *pp) { int retval = CF_NOINT; const Constraint *cp = PromiseGetConstraint(pp, lval); if (cp) { if (cp->rval.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Anomalous type mismatch - expected type for int constraint %s did not match internals", lval); PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Aborted"); } retval = (int) IntFromString((char *) cp->rval.item); } return retval; } /*****************************************************************************/ /** * @brief Get the real value of the first effective constraint found matching, from a promise * @return true if value could be extracted */ bool PromiseGetConstraintAsReal(const EvalContext *ctx, const char *lval, const Promise *pp, double *value_out) { const Constraint *cp = PromiseGetConstraint(pp, lval); if (cp) { if (cp->rval.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Anomalous type mismatch - expected type for int constraint '%s' did not match internals", lval); FatalError(ctx, "Aborted"); } *value_out = DoubleFromString((char *) cp->rval.item, value_out); return true; } return false; } /*****************************************************************************/ /** * @return true if successful */ static bool Str2Mode(const char *s, mode_t *mode_out) { int a = CF_UNDEFINED; if (s == NULL) { *mode_out = (mode_t)0; return true; } sscanf(s, "%o", &a); if (a == CF_UNDEFINED) { return false; } *mode_out = (mode_t)a; return true; } /** * @brief Get the octal value of the first effective constraint found matching, from a promise * @param lval * @param list * @return Double value, or 077 if not found */ mode_t PromiseGetConstraintAsOctal(const EvalContext *ctx, const char *lval, const Promise *pp) { mode_t retval = 077; // We could handle units here, like kb,b,mb const Constraint *cp = PromiseGetConstraint(pp, lval); if (cp) { if (cp->rval.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Anomalous type mismatch - expected type for int constraint %s did not match internals", lval); PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Aborted"); } if (!Str2Mode(cp->rval.item, &retval)) { Log(LOG_LEVEL_ERR, "Error reading assumed octal value '%s'", (const char *)cp->rval.item); PromiseRef(LOG_LEVEL_ERR, pp); } } return retval; } /*****************************************************************************/ #ifdef __MINGW32__ uid_t PromiseGetConstraintAsUid(const EvalContext *ctx, const char *lval, const Promise *pp) { // we use sids on windows instead return CF_SAME_OWNER; } #else /* !__MINGW32__ */ /** * @brief Get the uid value of the first effective constraint found matching, from a promise * @param lval * @param pp * @return Uid value, or CF_SAME_OWNER if not found */ uid_t PromiseGetConstraintAsUid(const EvalContext *ctx, const char *lval, const Promise *pp) { int retval = CF_SAME_OWNER; char buffer[CF_MAXVARSIZE]; const Constraint *cp = PromiseGetConstraint(pp, lval); if (cp) { if (cp->rval.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Anomalous type mismatch - expected type for owner constraint %s did not match internals", lval); PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Aborted"); } retval = Str2Uid((char *) cp->rval.item, buffer, pp); } return retval; } #endif /* !__MINGW32__ */ /*****************************************************************************/ #ifdef __MINGW32__ gid_t PromiseGetConstraintAsGid(const EvalContext *ctx, char *lval, const Promise *pp) { // not applicable on windows: processes have no group return CF_SAME_GROUP; } #else /* !__MINGW32__ */ /** * @brief Get the uid value of the first effective constraint found matching, from a promise * @param lval * @param pp * @return Gid value, or CF_SAME_GROUP if not found */ gid_t PromiseGetConstraintAsGid(const EvalContext *ctx, char *lval, const Promise *pp) { int retval = CF_SAME_GROUP; char buffer[CF_MAXVARSIZE]; const Constraint *cp = PromiseGetConstraint(pp, lval); if (cp) { if (cp->rval.type != RVAL_TYPE_SCALAR) { Log(LOG_LEVEL_ERR, "Anomalous type mismatch - expected type for group constraint '%s' did not match internals", lval); PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Aborted"); } retval = Str2Gid((char *) cp->rval.item, buffer, pp); } return retval; } #endif /* !__MINGW32__ */ /*****************************************************************************/ /** * @brief Get the Rlist value of the first effective constraint found matching, from a promise * @param lval * @param list * @return Rlist or NULL if not found (note: same as empty list) */ // FIX: promise constrained classed? Rlist *PromiseGetConstraintAsList(const EvalContext *ctx, const char *lval, const Promise *pp) { const Constraint *cp = PromiseGetConstraint(pp, lval); if (cp) { if (cp->rval.type != RVAL_TYPE_LIST) { Log(LOG_LEVEL_ERR, "Type mismatch on rhs - expected type for list constraint '%s'", lval); PromiseRef(LOG_LEVEL_ERR, pp); FatalError(ctx, "Aborted"); } return RvalRlistValue(cp->rval); } return NULL; } /** * @brief Get the first effective constraint from the promise, also does some checking * @param promise * @param lval * @return Effective constraint if found, otherwise NULL */ Constraint *PromiseGetConstraint(const Promise *pp, const char *lval) { if (!pp) { return NULL; } for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (strcmp(cp->lval, lval) == 0) { return cp; } } return NULL; } Constraint *PromiseGetConstraintWithType(const Promise *pp, const char *lval, RvalType type) { assert(pp); for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); if (cp->rval.type != type) { continue; } if (strcmp(cp->lval, lval) == 0) { return cp; } } return NULL; } /** * @brief Get the first constraint from the promise * * Kill this function with fire once we have separated promise constraints and body constraints. * * @param promise * @param lval * @return Constraint if found, otherwise NULL */ Constraint *PromiseGetImmediateConstraint(const Promise *pp, const char *lval) { if (pp == NULL) { return NULL; } for (size_t i = 0; i < SeqLength(pp->conlist); ++i) { Constraint *cp = SeqAt(pp->conlist, i); if (strcmp(cp->lval, lval) == 0) { /* It would be nice to check whether the constraint we have asked for is defined in promise (not in referenced body), but there seem to be no way to do it easily. Checking for absence of classes does not work, as constrains obtain classes defined on promise itself. */ return cp; } } return NULL; } /** * @brief Get the Rval value of the first constraint that matches the given * type. Checks that this constraint does not have any contexts attached. * * Kill this function with fire once we have separated body constraints and bundle constraints. * * @param lval * @param promise * @param type * @return Rval value if found, NULL otherwise */ void *PromiseGetImmediateRvalValue(const char *lval, const Promise *pp, RvalType rtype) { const Constraint *constraint = PromiseGetImmediateConstraint(pp, lval); if (constraint && constraint->rval.type == rtype) { return constraint->rval.item; } else { return NULL; } } /*****************************************************************************/ /** * @brief Get the Rval value of the first effective constraint that matches the given type * @param lval * @param promise * @param type * @return Rval value if found, NULL otherwise */ void *PromiseGetConstraintAsRval(const Promise *pp, const char *lval, RvalType rtype) { const Constraint *constraint = PromiseGetConstraint(pp, lval); if (constraint && constraint->rval.type == rtype) { return constraint->rval.item; } else { return NULL; } } /*****************************************************************************/ /* * Check promise constraints while iterating through all slist/containers * combinations, called from ExpandPromiseAndDo() during PRE-EVAL. This is * currently running also in cf-promises, but it's enough if such errors are * detected in the agent run. * * TODO remove CommonEvalPromise() actuator, that all it does is call this * function, and call this one at the beginning of the main actuators, like * KeepAgentPromise(). */ void PromiseRecheckAllConstraints(const EvalContext *ctx, const Promise *pp) { for (size_t i = 0; i < SeqLength(pp->conlist); i++) { Constraint *cp = SeqAt(pp->conlist, i); SyntaxTypeMatch err = ConstraintCheckType(cp); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { PolicyError *error = PolicyErrorNew(POLICY_ELEMENT_TYPE_CONSTRAINT, cp, "In attribute '%s', %s", cp->lval, SyntaxTypeMatchToString(err)); char *error_str = PolicyErrorToString(error); Log(LOG_LEVEL_ERR, "%s", error_str); PolicyErrorDestroy(error); free(error_str); FatalError(ctx, "Cannot continue"); } } /* Check and warn for non-convergence, see commits 4f8c19b84327b8f3c2e269173196282ccedfdad9 and 30c109d22e170a781a647b04b4b0a4a2f7244871. */ if (strcmp(PromiseGetPromiseType(pp), "insert_lines") == 0) { /* TODO without static var, actually remove this check from here * completely, do it at the end of PRE-EVAL promise iterations * (ExpandPromiseAndDo() after the main loop). */ static Item *EDIT_ANCHORS = NULL; /* GLOBAL_X */ const char *sp = PromiseGetConstraintAsRval(pp, "select_line_matching", RVAL_TYPE_SCALAR); if (sp != NULL && !IsExpandable(sp)) { /* Avoid adding twice the same select_line_matching anchor. */ const char *bun = PromiseGetBundle(pp)->name; const Item *ptr = ReturnItemInClass(EDIT_ANCHORS, sp, bun); if (ptr != NULL) { Log(LOG_LEVEL_INFO, "insert_lines promise uses the same select_line_matching anchor '%s' as another promise." " This will lead to non-convergent behaviour unless 'empty_file_before_editing' is set", sp); PromiseRef(LOG_LEVEL_INFO, pp); return; } PrependItem(&EDIT_ANCHORS, sp, bun); } } } /*****************************************************************************/ static SyntaxTypeMatch ConstraintCheckType(const Constraint *cp) { // Check class for (size_t i = 0; CF_CLASSBODY[i].lval != NULL; i++) { if (strcmp(cp->lval, CF_CLASSBODY[i].lval) == 0) { SyntaxTypeMatch err = CheckConstraintTypeMatch(cp->lval, cp->rval, CF_CLASSBODY[i].dtype, CF_CLASSBODY[i].range.validation_string, 0); if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED) { return err; } } } if (cp->type == POLICY_ELEMENT_TYPE_PROMISE) { BundleSection *section = cp->parent.promise->parent_section; for (size_t i = 0; i < (size_t) CF3_MODULES; i++) { const PromiseTypeSyntax *ssp = CF_ALL_PROMISE_TYPES[i]; if (!ssp) { continue; } for (size_t j = 0; ssp[j].bundle_type != NULL; j++) { PromiseTypeSyntax ss = ssp[j]; if (ss.promise_type != NULL) { if (strcmp(ss.promise_type, section->promise_type) == 0) { const ConstraintSyntax *bs = ss.constraints; for (size_t l = 0; bs[l].lval != NULL; l++) { // No validation for CF_DATA_TYPE_BUNDLE here // see: PolicyCheckUndefinedBundles() etc. if (bs[l].dtype == CF_DATA_TYPE_BODY) { const ConstraintSyntax *bs2 = bs[l].range.body_type_syntax->constraints; for (size_t m = 0; bs2[m].lval != NULL; m++) { if (strcmp(cp->lval, bs2[m].lval) == 0) { return CheckConstraintTypeMatch(cp->lval, cp->rval, bs2[m].dtype, bs2[m].range.validation_string, 0); } } } if (strcmp(cp->lval, bs[l].lval) == 0) { return CheckConstraintTypeMatch(cp->lval, cp->rval, bs[l].dtype, bs[l].range.validation_string, 0); } } } } } } } /* Now check the functional modules - extra level of indirection */ for (size_t i = 0; CF_COMMON_BODIES[i].lval != NULL; i++) { if (CF_COMMON_BODIES[i].dtype == CF_DATA_TYPE_BODY) { continue; } if (strcmp(cp->lval, CF_COMMON_BODIES[i].lval) == 0) { return CheckConstraintTypeMatch(cp->lval, cp->rval, CF_COMMON_BODIES[i].dtype, CF_COMMON_BODIES[i].range.validation_string, 0); } } return SYNTAX_TYPE_MATCH_OK; } /** * @brief Check whether the promise type is allowed one */ /* FIXME: need to be done automatically */ bool BundleTypeCheck(const char *name) { /* FIXME: export size of CF_AGENTTYPES somewhere */ for (int i = 0; strcmp(CF_AGENTTYPES[i], "") != 0; ++i) { if (!strcmp(CF_AGENTTYPES[i], name)) { return true; } } if (!strcmp("knowledge", name)) { return true; } if (!strcmp("edit_line", name)) { return true; } if (!strcmp("edit_xml", name)) { return true; } return false; } bool PolicyHasCustomPromiseType(const Policy *policy, const char *name) { assert(policy != NULL); Seq *types = policy->custom_promise_types; const size_t length = SeqLength(types); for (size_t i = 0; i < length; ++i) { Body *type = SeqAt(types, i); if (StringEqual(name, type->name)) { return true; } } return false; } cfengine-3.24.2/libpromises/monitoring_read.c0000644000000000000000000001731415010704253021235 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* FILE_SEPARATOR */ #include /* GLOBALS */ static const char *UNITS[CF_OBSERVABLES] = /* constant */ { "average users per 2.5 mins", "processes", "processes", "percent", "jobs", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "packets", "entries", "entries", "entries", "entries", "Celcius", "Celcius", "Celcius", "Celcius", "percent", "percent", "percent", "percent", "percent", "packets", "packets", "connections", "connections", "connections", "connections", "connections", "connections", "connections", "connections", }; time_t slots_load_time = 0; MonitoringSlot *SLOTS[CF_OBSERVABLES - ob_spare]; /*****************************************************************************/ void Nova_FreeSlot(MonitoringSlot *slot) { if (slot) { free(slot->name); free(slot->description); free(slot->units); free(slot); } } MonitoringSlot *Nova_MakeSlot(const char *name, const char *description, const char *units, double expected_minimum, double expected_maximum, bool consolidable) { MonitoringSlot *slot = xmalloc(sizeof(MonitoringSlot)); slot->name = xstrdup(name); slot->description = xstrdup(description); slot->units = xstrdup(units); slot->expected_minimum = expected_minimum; slot->expected_maximum = expected_maximum; slot->consolidable = consolidable; return slot; } // This function is similar to cf-check/observables.c function GetObservableNames // If we refactor for dynamic observables instead of hard coded and limited to 100 // then we likely should change here and there or refactor to have // this ts_key read/parse code in one shared place. void Nova_LoadSlots(void) { char filename[CF_BUFSIZE]; int i; snprintf(filename, CF_BUFSIZE - 1, "%s%cts_key", GetStateDir(), FILE_SEPARATOR); FILE *f = safe_fopen(filename, "r"); if (f == NULL) { return; } int fd = fileno(f); struct stat sb; if ((fstat(fd, &sb) != 0) || (sb.st_mtime <= slots_load_time)) { fclose(f); return; } slots_load_time = sb.st_mtime; for (i = 0; i < CF_OBSERVABLES; ++i) { if (i < ob_spare) { int r; do { r = fgetc(f); } while (r != (int)'\n' && r != EOF); if (r == EOF) { break; } } else { char line[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE], desc[CF_MAXVARSIZE]; char units[CF_MAXVARSIZE] = "unknown"; double expected_min = 0.0; double expected_max = 100.0; int consolidable = true; if (fgets(line, CF_MAXVARSIZE, f) == NULL) { Log(LOG_LEVEL_ERR, "Error trying to read ts_key from file '%s'. (fgets: %s)", filename, GetErrorStr()); break; } int fields = sscanf(line, "%*d,%1023[^,],%1023[^,],%1023[^,],%lf,%lf,%d", name, desc, units, &expected_min, &expected_max, &consolidable); if (fields == 2) { /* Old-style ts_key with name and description */ } else if (fields == 6) { /* New-style ts_key with additional parameters */ } else { Log(LOG_LEVEL_ERR, "Wrong line format in ts_key: %s", line); } if (strcmp(name, "spare") != 0) { Nova_FreeSlot(SLOTS[i - ob_spare]); SLOTS[i - ob_spare] = Nova_MakeSlot(name, desc, units, expected_min, expected_max, consolidable); } } } fclose(f); } bool NovaHasSlot(int idx) { Nova_LoadSlots(); return idx < ob_spare || SLOTS[idx - ob_spare]; } const char *NovaGetSlotName(int idx) { Nova_LoadSlots(); return idx < ob_spare ? OBSERVABLES[idx][0] : SLOTS[idx - ob_spare]->name; } const char *NovaGetSlotDescription(int idx) { Nova_LoadSlots(); return idx < ob_spare ? OBSERVABLES[idx][1] : SLOTS[idx - ob_spare]->description; } const char *NovaGetSlotUnits(int idx) { Nova_LoadSlots(); return idx < ob_spare ? UNITS[idx] : SLOTS[idx - ob_spare]->units; } // TODO: real expected minimum/maximum/consolidable for core slots double NovaGetSlotExpectedMinimum(int idx) { Nova_LoadSlots(); return idx < ob_spare ? 0.0f : SLOTS[idx - ob_spare]->expected_minimum; } double NovaGetSlotExpectedMaximum(int idx) { Nova_LoadSlots(); return idx < ob_spare ? 100.0f : SLOTS[idx - ob_spare]->expected_maximum; } bool NovaIsSlotConsolidable(int idx) { Nova_LoadSlots(); return idx < ob_spare ? true : SLOTS[idx - ob_spare]->consolidable; } /* * This function returns beginning of last Monday relative to 'time'. If 'time' * is Monday, beginning of the same day is returned. */ time_t WeekBegin(time_t time) { struct tm tm; gmtime_r(&time, &tm); /* Move back in time to reach Monday. */ time -= ((tm.tm_wday == 0 ? 6 : tm.tm_wday - 1) * SECONDS_PER_DAY); /* Move to the beginning of day */ time -= tm.tm_hour * SECONDS_PER_HOUR; time -= tm.tm_min * SECONDS_PER_MINUTE; time -= tm.tm_sec; return time; } time_t SubtractWeeks(time_t time, int weeks) { return time - weeks * SECONDS_PER_WEEK; } time_t NextShift(time_t time) { return time + SECONDS_PER_SHIFT; } void MakeTimekey(time_t time, char *result) { /* Generate timekey for database */ struct tm tm; gmtime_r(&time, &tm); snprintf(result, 64, "%d_%.3s_Lcycle_%d_%s", tm.tm_mday, MONTH_TEXT[tm.tm_mon], (tm.tm_year + 1900) % 3, SHIFT_TEXT[tm.tm_hour / 6]); } /* Returns true if entry was found, false otherwise */ bool GetRecordForTime(CF_DB *db, time_t time, Averages *result) { char timekey[CF_MAXVARSIZE]; MakeTimekey(time, timekey); return ReadDB(db, timekey, result, sizeof(Averages)); } cfengine-3.24.2/libpromises/cf3parse.c0000644000000000000000000025501215010704322017557 0ustar00rootroot00000000000000/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Copy the first part of user declarations. */ #line 25 "cf3parse.y" /* yacc.c:339 */ #include #line 70 "cf3parse.c" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* In a future release of Bison, this section will be replaced by #include "y.tab.h". */ #ifndef YY_YY_CF_PARSE_H_INCLUDED # define YY_YY_CF_PARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { IDENTIFIER = 258, QUOTED_STRING = 259, CLASS_GUARD = 260, PROMISE_GUARD = 261, BUNDLE = 262, BODY = 263, PROMISE = 264, FAT_ARROW = 265, THIN_ARROW = 266, NAKEDVAR = 267 }; #endif /* Tokens. */ #define IDENTIFIER 258 #define QUOTED_STRING 259 #define CLASS_GUARD 260 #define PROMISE_GUARD 261 #define BUNDLE 262 #define BODY 263 #define PROMISE 264 #define FAT_ARROW 265 #define THIN_ARROW 266 #define NAKEDVAR 267 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_CF_PARSE_H_INCLUDED */ /* Copy the second part of user declarations. */ #line 145 "cf3parse.c" /* yacc.c:358 */ #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE # if (defined __GNUC__ \ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C # define YY_ATTRIBUTE(Spec) __attribute__(Spec) # else # define YY_ATTRIBUTE(Spec) /* empty */ # endif #endif #ifndef YY_ATTRIBUTE_PURE # define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) #endif #ifndef YY_ATTRIBUTE_UNUSED # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) #endif #if !defined _Noreturn \ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) # if defined _MSC_VER && 1200 <= _MSC_VER # define _Noreturn __declspec (noreturn) # else # define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) #else # define YYUSE(E) /* empty */ #endif #if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 24 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 142 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 19 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 69 /* YYNRULES -- Number of rules. */ #define YYNRULES 127 /* YYNSTATES -- Number of states. */ #define YYNSTATES 156 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 267 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 14, 2, 2, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 18, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 34, 34, 35, 39, 40, 44, 45, 46, 47, 53, 55, 57, 61, 66, 79, 86, 92, 93, 102, 107, 114, 120, 126, 127, 136, 141, 148, 154, 164, 165, 174, 184, 192, 193, 194, 195, 201, 206, 213, 214, 215, 219, 224, 233, 232, 247, 251, 259, 260, 264, 265, 266, 277, 281, 288, 289, 293, 294, 298, 299, 307, 308, 333, 334, 344, 339, 371, 370, 398, 409, 431, 432, 433, 454, 473, 474, 479, 488, 511, 519, 518, 532, 533, 535, 536, 540, 541, 545, 546, 553, 562, 587, 608, 612, 620, 634, 654, 661, 678, 687, 696, 704, 712, 713, 714, 719, 720, 721, 743, 755, 767, 775, 782, 790, 794, 807, 815, 814, 840, 841, 842, 843, 851, 858, 867, 876, 885 }; #endif #if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "IDENTIFIER", "QUOTED_STRING", "CLASS_GUARD", "PROMISE_GUARD", "BUNDLE", "BODY", "PROMISE", "FAT_ARROW", "THIN_ARROW", "NAKEDVAR", "'('", "')'", "','", "'}'", "'{'", "';'", "$accept", "specification", "blocks", "block", "bundle", "body", "promise", "bundletype", "bundletype_values", "bundleid", "bundleid_values", "bodytype", "bodytype_values", "bodyid", "bodyid_values", "promisecomponent", "promisecomponent_values", "promiseid", "promiseid_values", "typeid", "symbol", "arglist", "arglist_begin", "arglist_end", "aitems", "aitem", "bundlebody", "$@1", "body_begin", "bundle_decl", "bundle_statements", "bundle_statement", "promise_guard", "classpromises_decl", "classpromises", "classpromise", "promise_decl", "promise_line", "promise_with_promisee", "$@2", "promise_without_promisee", "$@3", "promiser", "promise_decl_constraints", "constraints_decl", "constraints", "constraint", "constraint_id", "bodybody", "$@4", "bodybody_inner", "bodyattribs", "bodyattrib", "selection_line", "selection", "selection_id", "assign_arrow", "promisee_arrow", "class", "rval", "list", "litems", "litem", "functionid", "usefunction", "givearglist", "$@5", "gaitems", "gaitem", YY_NULLPTR }; #endif # ifdef YYPRINT /* YYTOKNUM[NUM] -- (External) token number corresponding to the (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 40, 41, 44, 125, 123, 59 }; # endif #define YYPACT_NINF -110 #define yypact_value_is_default(Yystate) \ (!!((Yystate) == (-110))) #define YYTABLE_NINF -121 #define yytable_value_is_error(Yytable_value) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { 98, -110, 9, 112, 113, 11, 103, -110, -110, -110, -110, -110, -110, 116, -110, -110, -110, 117, -110, -110, -110, 120, -110, -110, -110, -110, -110, -110, 15, -110, -110, -110, 15, -110, -110, -110, 15, -110, -110, -110, 2, 69, 2, 2, -110, -110, -110, -110, 25, -110, -110, -110, 20, 30, -110, -110, -110, 17, -110, 83, 55, -110, -110, 1, 74, -110, 31, -110, -110, -110, -110, -110, 59, 61, -110, -110, 7, 91, -110, -110, -110, -110, -110, -110, 37, -110, -110, 70, -110, -110, 3, -110, -110, -110, -110, -110, -110, -110, 12, -110, -110, -110, -110, 4, 12, -110, 72, -110, 82, 45, -110, -110, 114, -110, -110, -110, -110, 8, 115, -110, 91, -110, -110, 72, -110, 82, -110, 35, 58, -110, -110, -110, -110, 121, 12, 4, 51, -110, -110, 75, -110, -110, -110, -110, -110, -110, 72, -110, 82, -110, 94, 67, -110, 90, -110, -110 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 0, 9, 0, 0, 0, 0, 0, 4, 6, 7, 8, 15, 31, 0, 13, 14, 21, 0, 19, 20, 27, 0, 25, 26, 1, 5, 18, 32, 33, 16, 17, 24, 33, 22, 23, 30, 33, 28, 29, 37, 0, 0, 0, 0, 47, 46, 10, 44, 36, 42, 38, 35, 0, 39, 80, 11, 12, 0, 34, 0, 0, 52, 54, 0, 49, 50, 0, 43, 41, 92, 91, 96, 0, 0, 84, 87, 0, 0, 86, 45, 51, 70, 69, 53, 0, 57, 60, 0, 63, 64, 0, 59, 81, 85, 89, 88, 94, 93, 0, 58, 61, 62, 95, 0, 0, 102, 97, 98, 99, 0, 90, 100, 0, 101, 79, 78, 68, 0, 74, 75, 0, 65, 113, 109, 110, 111, 103, 0, 0, 112, 117, 116, 73, 0, 0, 0, 0, 104, 108, 0, 76, 77, 66, 105, 107, 127, 123, 124, 125, 126, 0, 0, 118, 0, 122, 121 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -110, -110, -110, 123, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, -110, 122, 48, 64, -110, 76, 73, -110, -110, -110, 93, -110, -110, 71, -110, -110, -110, 47, -110, -110, -110, -110, -110, -110, -110, -1, -110, -110, 5, -110, 96, -110, -110, -110, 63, -110, -110, -110, 21, -110, -64, -103, -110, -110, 6, -110, -109, -110, -110, -110, -16 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 5, 6, 7, 8, 9, 10, 13, 14, 28, 29, 17, 18, 32, 33, 21, 22, 36, 37, 15, 30, 40, 41, 51, 52, 53, 46, 57, 54, 63, 64, 65, 66, 83, 84, 85, 86, 87, 88, 135, 89, 103, 90, 116, 117, 118, 119, 120, 55, 60, 72, 73, 74, 75, 76, 77, 98, 104, 78, 110, 111, 127, 128, 112, 113, 131, 139, 150, 151 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { 129, 121, 91, 44, 101, 114, -67, 115, 94, 132, 11, 24, 12, 105, 102, 106, 107, 79, 61, 45, 91, -67, -71, 62, 108, 95, -72, 129, 39, 109, 149, 141, 81, -48, 50, 82, 71, -55, 81, -43, -43, 82, 71, -56, 149, 59, 122, -55, 123, 124, 136, 137, 122, -56, 123, 124, 69, 125, 70, 138, 71, 126, 69, 125, 70, 34, 71, 143, 154, 38, 48, -82, 49, -106, -106, 92, 145, -83, 146, 147, 62, -120, -120, 50, 67, -114, 49, 148, 100, -119, -119, 145, 96, 146, 147, -115, 42, -40, -2, 1, 43, 97, 148, -3, 1, 2, 3, 4, 152, 153, 2, 3, 4, 16, 20, 12, 12, 26, 31, 27, 27, 35, 114, 27, 115, 19, 23, 130, 58, 25, 133, 99, 68, 47, 142, 80, 93, 155, 140, 56, 0, 134, 144 }; static const yytype_int16 yycheck[] = { 109, 104, 66, 1, 1, 1, 3, 3, 1, 1, 1, 0, 3, 1, 11, 3, 4, 16, 1, 17, 84, 18, 18, 6, 12, 18, 18, 136, 13, 17, 139, 134, 1, 16, 14, 4, 5, 6, 1, 14, 15, 4, 5, 6, 153, 15, 1, 16, 3, 4, 15, 16, 1, 16, 3, 4, 1, 12, 3, 1, 5, 16, 1, 12, 3, 17, 5, 16, 1, 21, 1, 16, 3, 15, 16, 16, 1, 16, 3, 4, 6, 14, 15, 14, 1, 13, 3, 12, 18, 14, 15, 1, 1, 3, 4, 13, 32, 14, 0, 1, 36, 10, 12, 0, 1, 7, 8, 9, 14, 15, 7, 8, 9, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 3, 3, 3, 4, 13, 52, 6, 15, 84, 59, 40, 135, 64, 73, 153, 133, 43, -1, 120, 136 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 1, 7, 8, 9, 20, 21, 22, 23, 24, 25, 1, 3, 26, 27, 38, 1, 30, 31, 38, 1, 34, 35, 38, 0, 22, 1, 3, 28, 29, 39, 1, 32, 33, 39, 1, 36, 37, 39, 13, 40, 41, 40, 40, 1, 17, 45, 47, 1, 3, 14, 42, 43, 44, 47, 67, 67, 46, 42, 15, 68, 1, 6, 48, 49, 50, 51, 1, 43, 1, 3, 5, 69, 70, 71, 72, 73, 74, 77, 16, 50, 1, 4, 52, 53, 54, 55, 56, 57, 59, 61, 77, 16, 71, 1, 18, 1, 10, 75, 54, 18, 1, 11, 60, 76, 1, 3, 4, 12, 17, 78, 79, 82, 83, 1, 3, 62, 63, 64, 65, 66, 78, 1, 3, 4, 12, 16, 80, 81, 83, 13, 84, 1, 15, 75, 58, 15, 16, 1, 85, 65, 78, 62, 16, 81, 1, 3, 4, 12, 83, 86, 87, 14, 15, 1, 87 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 24, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 40, 40, 40, 41, 42, 43, 43, 43, 44, 44, 46, 45, 47, 47, 48, 48, 49, 49, 49, 50, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 58, 57, 60, 59, 61, 61, 62, 62, 62, 63, 64, 64, 65, 66, 66, 68, 67, 69, 69, 70, 70, 71, 71, 72, 72, 73, 74, 74, 75, 75, 76, 77, 78, 78, 78, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 81, 81, 82, 82, 83, 85, 84, 86, 86, 86, 86, 87, 87, 87, 87, 87 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 1, 1, 2, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, 2, 2, 1, 1, 1, 2, 3, 1, 1, 0, 4, 1, 1, 0, 1, 1, 2, 1, 2, 1, 0, 1, 1, 2, 1, 1, 2, 2, 1, 1, 0, 5, 0, 3, 1, 1, 0, 1, 2, 1, 1, 3, 3, 1, 1, 0, 4, 0, 1, 1, 2, 1, 1, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 4, 0, 1, 3, 2, 1, 1, 1, 1, 1 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*----------------------------------------. | Print this symbol's value on YYOUTPUT. | `----------------------------------------*/ static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { FILE *yyo = yyoutput; YYUSE (yyo); if (!yyvaluep) return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif YYUSE (yytype); } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) { YYFPRINTF (yyoutput, "%s %s (", yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yystos[yyssp[yyi + 1 - yynrhs]], &(yyvsp[(yyi + 1) - (yynrhs)]) ); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T yystrlen (const char *yystr) { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; { YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } { YYSIZE_T yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) { YYUSE (yyvaluep); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YYUSE (yytype); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (void) { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: 'yyss': related to states. 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yyssp = yyss = yyssa; yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 9: #line 48 "cf3parse.y" /* yacc.c:1646 */ { ParseError("Expected 'bundle' or 'body' keyword, wrong input '%s'", yytext); YYABORT; } #line 1353 "cf3parse.c" /* yacc.c:1646 */ break; case 13: #line 62 "cf3parse.y" /* yacc.c:1646 */ { ParserBeginBlock(PARSER_BLOCK_BUNDLE); } #line 1361 "cf3parse.c" /* yacc.c:1646 */ break; case 14: #line 67 "cf3parse.y" /* yacc.c:1646 */ { /* FIXME: We keep it here, because we skip unknown * promise bundles. Ought to be moved to * after-parsing step once we know how to deal with * it */ if (!BundleTypeCheck(P.blocktype)) { ParseError("Unknown bundle type '%s'", P.blocktype); INSTALL_SKIP = true; } } #line 1378 "cf3parse.c" /* yacc.c:1646 */ break; case 15: #line 80 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected bundle type, wrong input '%s'", yytext); INSTALL_SKIP = true; } #line 1388 "cf3parse.c" /* yacc.c:1646 */ break; case 16: #line 87 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:bundle:%s:%s\n", P.blocktype, P.blockid); CURRENT_BLOCKID_LINE = P.line_no; } #line 1397 "cf3parse.c" /* yacc.c:1646 */ break; case 18: #line 94 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected bundle identifier, wrong input '%s'", yytext); INSTALL_SKIP = true; } #line 1407 "cf3parse.c" /* yacc.c:1646 */ break; case 19: #line 103 "cf3parse.y" /* yacc.c:1646 */ { ParserBeginBlock(PARSER_BLOCK_BODY); } #line 1415 "cf3parse.c" /* yacc.c:1646 */ break; case 20: #line 108 "cf3parse.y" /* yacc.c:1646 */ { if (!BodySyntaxGet(PARSER_BLOCK_BODY, P.blocktype)) { ParseError("Unknown body type '%s'", P.blocktype); } } #line 1426 "cf3parse.c" /* yacc.c:1646 */ break; case 21: #line 115 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected body type, wrong input '%s'", yytext); } #line 1435 "cf3parse.c" /* yacc.c:1646 */ break; case 22: #line 121 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:body:%s:%s\n", P.blocktype, P.blockid); CURRENT_BLOCKID_LINE = P.line_no; } #line 1444 "cf3parse.c" /* yacc.c:1646 */ break; case 24: #line 128 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected body identifier, wrong input '%s'", yytext); INSTALL_SKIP = true; } #line 1454 "cf3parse.c" /* yacc.c:1646 */ break; case 25: #line 137 "cf3parse.y" /* yacc.c:1646 */ { ParserBeginBlock(PARSER_BLOCK_PROMISE); } #line 1462 "cf3parse.c" /* yacc.c:1646 */ break; case 26: #line 142 "cf3parse.y" /* yacc.c:1646 */ { if (!StringEqual(P.blocktype, "agent")) { ParseError("Custom promises only supported for 'agent', not '%s'", P.blocktype); } } #line 1473 "cf3parse.c" /* yacc.c:1646 */ break; case 27: #line 149 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected 'agent', got '%s'", yytext); } #line 1482 "cf3parse.c" /* yacc.c:1646 */ break; case 28: #line 155 "cf3parse.y" /* yacc.c:1646 */ { if (IsBuiltInPromiseType(P.blockid)) { ParseError("'%s' promises are built in and cannot be custom", yytext); } ParserDebug("\tP:promise:%s:%s\n", P.blocktype, P.blockid); CURRENT_BLOCKID_LINE = P.line_no; } #line 1495 "cf3parse.c" /* yacc.c:1646 */ break; case 30: #line 166 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected promise type identifier, wrong input '%s'", yytext); INSTALL_SKIP = true; } #line 1505 "cf3parse.c" /* yacc.c:1646 */ break; case 31: #line 175 "cf3parse.y" /* yacc.c:1646 */ { strncpy(P.blocktype,P.currentid,CF_MAXVARSIZE); RlistDestroy(P.useargs); P.useargs = NULL; } #line 1516 "cf3parse.c" /* yacc.c:1646 */ break; case 32: #line 185 "cf3parse.y" /* yacc.c:1646 */ { strncpy(P.blockid,P.currentid,CF_MAXVARSIZE); P.offsets.last_block_id = P.offsets.last_id; } #line 1525 "cf3parse.c" /* yacc.c:1646 */ break; case 36: #line 196 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Error in bundle parameter list, expected ')', wrong input '%s'", yytext); } #line 1534 "cf3parse.c" /* yacc.c:1646 */ break; case 37: #line 202 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("P:%s:%s:%s arglist begin:%s\n", ParserBlockString(P.block),P.blocktype,P.blockid, yytext); } #line 1542 "cf3parse.c" /* yacc.c:1646 */ break; case 38: #line 207 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("P:%s:%s:%s arglist end:%s\n", ParserBlockString(P.block),P.blocktype,P.blockid, yytext); } #line 1550 "cf3parse.c" /* yacc.c:1646 */ break; case 42: #line 220 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("P:%s:%s:%s arg id: %s\n", ParserBlockString(P.block),P.blocktype,P.blockid, P.currentid); RlistAppendScalar(&(P.useargs),P.currentid); } #line 1559 "cf3parse.c" /* yacc.c:1646 */ break; case 43: #line 225 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected identifier, wrong input '%s'", yytext); } #line 1568 "cf3parse.c" /* yacc.c:1646 */ break; case 44: #line 233 "cf3parse.y" /* yacc.c:1646 */ { ParserBeginBundleBody(); } #line 1576 "cf3parse.c" /* yacc.c:1646 */ break; case 45: #line 240 "cf3parse.y" /* yacc.c:1646 */ { INSTALL_SKIP = false; ParserEndCurrentBlock(); } #line 1585 "cf3parse.c" /* yacc.c:1646 */ break; case 46: #line 248 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("P:%s:%s:%s begin body open\n", ParserBlockString(P.block),P.blocktype,P.blockid); } #line 1593 "cf3parse.c" /* yacc.c:1646 */ break; case 47: #line 252 "cf3parse.y" /* yacc.c:1646 */ { ParseError("Expected body open '{', wrong input '%s'", yytext); } #line 1601 "cf3parse.c" /* yacc.c:1646 */ break; case 52: #line 267 "cf3parse.y" /* yacc.c:1646 */ { INSTALL_SKIP = true; ParseError("Expected promise type, got '%s'", yytext); ParserDebug("P:promise_type:error yychar = %d, %c, yyempty = %d\n", yychar, yychar, YYEMPTY); yyclearin; } #line 1612 "cf3parse.c" /* yacc.c:1646 */ break; case 54: #line 282 "cf3parse.y" /* yacc.c:1646 */ { ParserHandlePromiseGuard(); } #line 1620 "cf3parse.c" /* yacc.c:1646 */ break; case 60: #line 300 "cf3parse.y" /* yacc.c:1646 */ { ParserCheckPromiseLine(); } #line 1628 "cf3parse.c" /* yacc.c:1646 */ break; case 62: #line 309 "cf3parse.y" /* yacc.c:1646 */ { /* * Based on yychar display right error message */ ParserDebug("P:promiser:error yychar = %d\n", yychar); if (yychar =='-' || yychar == '>') { ParseError("Expected '->', got '%s'", yytext); } else if (yychar == IDENTIFIER) { ParseError("Expected attribute, got '%s'", yytext); } else if (yychar == ',') { ParseError("Expected attribute, got '%s' (comma after promiser is not allowed since 3.5.0)", yytext); } else { ParseError("Expected ';', got '%s'", yytext); } yyclearin; } #line 1656 "cf3parse.c" /* yacc.c:1646 */ break; case 65: #line 344 "cf3parse.y" /* yacc.c:1646 */ { if (!INSTALL_SKIP) { if (!P.currentstype) { ParseError("Missing promise type declaration"); } P.currentpromise = BundleSectionAppendPromise(P.currentstype, P.promiser, RvalCopy(P.rval), P.currentclasses ? P.currentclasses : "any", P.currentvarclasses); P.currentpromise->offset.line = CURRENT_PROMISER_LINE; P.currentpromise->offset.start = P.offsets.last_string; P.currentpromise->offset.context = P.offsets.last_class_id; } else { P.currentpromise = NULL; } } #line 1682 "cf3parse.c" /* yacc.c:1646 */ break; case 67: #line 371 "cf3parse.y" /* yacc.c:1646 */ { if (!INSTALL_SKIP) { if (!P.currentstype) { ParseError("Missing promise type declaration"); } P.currentpromise = BundleSectionAppendPromise(P.currentstype, P.promiser, (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, P.currentclasses ? P.currentclasses : "any", P.currentvarclasses); P.currentpromise->offset.line = CURRENT_PROMISER_LINE; P.currentpromise->offset.start = P.offsets.last_string; P.currentpromise->offset.context = P.offsets.last_class_id; } else { P.currentpromise = NULL; } } #line 1709 "cf3parse.c" /* yacc.c:1646 */ break; case 69: #line 399 "cf3parse.y" /* yacc.c:1646 */ { if (P.promiser) { free(P.promiser); } P.promiser = P.currentstring; P.currentstring = NULL; CURRENT_PROMISER_LINE = P.line_no; ParserDebug("\tP:%s:%s:%s:%s:%s promiser = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currenttype, P.currentclasses ? P.currentclasses : "any", P.promiser); } #line 1724 "cf3parse.c" /* yacc.c:1646 */ break; case 70: #line 410 "cf3parse.y" /* yacc.c:1646 */ { INSTALL_SKIP = true; ParserDebug("P:promiser:qstring::error yychar = %d\n", yychar); if (yychar == BUNDLE || yychar == BODY) { ParseError("Expected '}', got '%s'", yytext); /* YYABORT; */ } else { ParseError("Expected promiser string, got '%s'", yytext); } yyclearin; } #line 1747 "cf3parse.c" /* yacc.c:1646 */ break; case 73: #line 434 "cf3parse.y" /* yacc.c:1646 */ { /* * Based on next token id display right error message */ ParserDebug("P:constraints_decl:error yychar = %d\n", yychar); if ( yychar == IDENTIFIER ) { ParseError("Check previous line, Expected ',', got '%s'", yytext); } else { ParseError("Check previous line, Expected ';', got '%s'", yytext); } yyclearin; } #line 1768 "cf3parse.c" /* yacc.c:1646 */ break; case 74: #line 455 "cf3parse.y" /* yacc.c:1646 */ { /* Don't free these */ strcpy(P.currentid,""); RlistDestroy(P.currentRlist); P.currentRlist = NULL; free(P.promiser); if (P.currentstring) { free(P.currentstring); } P.currentstring = NULL; P.promiser = NULL; P.promisee = NULL; /* reset argptrs etc*/ } #line 1788 "cf3parse.c" /* yacc.c:1646 */ break; case 77: #line 482 "cf3parse.y" /* yacc.c:1646 */ { ParserHandleBundlePromiseRval(); } #line 1796 "cf3parse.c" /* yacc.c:1646 */ break; case 78: #line 489 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s:%s:%s attribute = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currenttype, P.currentclasses ? P.currentclasses : "any", P.promiser, P.currentid); const PromiseTypeSyntax *promise_type_syntax = PromiseTypeSyntaxGet(P.blocktype, P.currenttype); if (promise_type_syntax == NULL) { // This promise type might be defined in another Policy object. // There is no way to distinguish a custom promise type // from a wrong (misspelled) promise type while parsing // since the Policy objects will be merged later. } else if (!PromiseTypeSyntaxGetConstraintSyntax(promise_type_syntax, P.currentid)) { // Built in promise type with bad attribute ParseError("Unknown attribute '%s' for promise type '%s' in bundle with type '%s'", P.currentid, P.currenttype, P.blocktype); INSTALL_SKIP = true; } strncpy(P.lval,P.currentid,CF_MAXVARSIZE); RlistDestroy(P.currentRlist); P.currentRlist = NULL; } #line 1823 "cf3parse.c" /* yacc.c:1646 */ break; case 79: #line 512 "cf3parse.y" /* yacc.c:1646 */ { ParseError("Expected attribute, got '%s'\n", yytext); } #line 1831 "cf3parse.c" /* yacc.c:1646 */ break; case 80: #line 519 "cf3parse.y" /* yacc.c:1646 */ { ParserBeginBlockBody(); } #line 1839 "cf3parse.c" /* yacc.c:1646 */ break; case 81: #line 526 "cf3parse.y" /* yacc.c:1646 */ { ParserEndCurrentBlock(); } #line 1847 "cf3parse.c" /* yacc.c:1646 */ break; case 89: #line 547 "cf3parse.y" /* yacc.c:1646 */ { ParseError("Expected ';' check previous statement, got '%s'", yytext); } #line 1855 "cf3parse.c" /* yacc.c:1646 */ break; case 90: #line 556 "cf3parse.y" /* yacc.c:1646 */ { ParserHandleBlockAttributeRval(); } #line 1863 "cf3parse.c" /* yacc.c:1646 */ break; case 91: #line 563 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s attribute = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentid); if (!INSTALL_SKIP) { const BodySyntax *body_syntax = BodySyntaxGet(P.block, P.currentbody->type); if (!body_syntax || (body_syntax->status != SYNTAX_STATUS_CUSTOM && !BodySyntaxGetConstraintSyntax(body_syntax->constraints, P.currentid))) { ParseError( "Unknown attribute '%s' for '%s %s %s'", P.currentid, // attribute name (lval) ParserBlockString(P.block), // body (block type) P.currentbody->type, // file (body type) P.blockid); // control (body name) INSTALL_SKIP = true; } strncpy(P.lval,P.currentid,CF_MAXVARSIZE); } RlistDestroy(P.currentRlist); P.currentRlist = NULL; } #line 1892 "cf3parse.c" /* yacc.c:1646 */ break; case 92: #line 588 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("P:selection_id:idsyntax:error yychar = %d\n", yychar); if ( yychar == BUNDLE || yychar == BODY ) { ParseError("Expected '}', got '%s'", yytext); /* YYABORT; */ } else { ParseError("Expected attribute, got '%s'", yytext); } yyclearin; } #line 1914 "cf3parse.c" /* yacc.c:1646 */ break; case 93: #line 609 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:=>\n"); } #line 1922 "cf3parse.c" /* yacc.c:1646 */ break; case 94: #line 613 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Expected '=>', got '%s'", yytext); } #line 1931 "cf3parse.c" /* yacc.c:1646 */ break; case 95: #line 621 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:->\n"); } #line 1939 "cf3parse.c" /* yacc.c:1646 */ break; case 96: #line 635 "cf3parse.y" /* yacc.c:1646 */ { P.offsets.last_class_id = P.offsets.current - strlen(P.currentclasses ? P.currentclasses : P.currentvarclasses) - 2; ParserDebug("\tP:%s:%s:%s:%s %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currenttype, P.currentclasses ? "class": "varclass", yytext); if (P.currentclasses != NULL) { char *literal = xstrdup(P.currentclasses); ValidateClassLiteral(literal); free(literal); } } #line 1957 "cf3parse.c" /* yacc.c:1646 */ break; case 97: #line 655 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s id rval, %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval, P.currentid); RvalDestroy(P.rval); P.rval = (Rval) { xstrdup(P.currentid), RVAL_TYPE_SCALAR }; P.references_body = true; } #line 1968 "cf3parse.c" /* yacc.c:1646 */ break; case 98: #line 662 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s qstring rval, %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval, P.currentstring); RvalDestroy(P.rval); P.rval = (Rval) { P.currentstring, RVAL_TYPE_SCALAR }; P.currentstring = NULL; P.references_body = false; if (P.currentpromise) { if (LvalWantsBody(P.currentpromise->parent_section->promise_type, P.lval)) { yyerror("An rvalue is quoted, but we expect an unquoted body identifier"); } } } #line 1989 "cf3parse.c" /* yacc.c:1646 */ break; case 99: #line 679 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s nakedvar rval, %s = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval, P.currentstring); RvalDestroy(P.rval); P.rval = (Rval) { P.currentstring, RVAL_TYPE_SCALAR }; P.currentstring = NULL; P.references_body = false; } #line 2002 "cf3parse.c" /* yacc.c:1646 */ break; case 100: #line 688 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s install list = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.lval); RvalDestroy(P.rval); P.rval = (Rval) { RlistCopy(P.currentRlist), RVAL_TYPE_LIST }; RlistDestroy(P.currentRlist); P.currentRlist = NULL; P.references_body = false; } #line 2015 "cf3parse.c" /* yacc.c:1646 */ break; case 101: #line 697 "cf3parse.y" /* yacc.c:1646 */ { RvalDestroy(P.rval); P.rval = (Rval) { P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL }; P.currentfncall[P.arg_nesting+1] = NULL; P.references_body = false; } #line 2026 "cf3parse.c" /* yacc.c:1646 */ break; case 102: #line 705 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Invalid r-value type '%s'", yytext); } #line 2035 "cf3parse.c" /* yacc.c:1646 */ break; case 108: #line 722 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("P:rval:list:error yychar = %d\n", yychar); if ( yychar ==';' ) { ParseError("Expected '}', wrong input '%s'", yytext); } else if ( yychar == FAT_ARROW ) { ParseError("Check list statement previous line," " Expected '}', wrong input '%s'", yytext); } else { ParseError("Expected ',', wrong input '%s'", yytext); } yyclearin; } #line 2058 "cf3parse.c" /* yacc.c:1646 */ break; case 109: #line 744 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s list append: " "id = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, (P.currentclasses ? P.currentclasses : "any"), P.currentid); RlistAppendScalar((Rlist **) &P.currentRlist, P.currentid); } #line 2073 "cf3parse.c" /* yacc.c:1646 */ break; case 110: #line 756 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s list append: " "qstring = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, (P.currentclasses ? P.currentclasses : "any"), P.currentstring); ParserHandleQuotedListItem(); } #line 2088 "cf3parse.c" /* yacc.c:1646 */ break; case 111: #line 768 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s list append: nakedvar = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentstring); RlistAppendScalar((Rlist **)&P.currentRlist,(void *)P.currentstring); free(P.currentstring); P.currentstring = NULL; } #line 2099 "cf3parse.c" /* yacc.c:1646 */ break; case 112: #line 776 "cf3parse.y" /* yacc.c:1646 */ { RlistAppend(&P.currentRlist, P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL); FnCallDestroy(P.currentfncall[P.arg_nesting+1]); P.currentfncall[P.arg_nesting+1] = NULL; } #line 2109 "cf3parse.c" /* yacc.c:1646 */ break; case 113: #line 783 "cf3parse.y" /* yacc.c:1646 */ { yyclearin; ParseError("Invalid input for a list item, got '%s'", yytext); } #line 2118 "cf3parse.c" /* yacc.c:1646 */ break; case 114: #line 791 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s function id = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentid); } #line 2126 "cf3parse.c" /* yacc.c:1646 */ break; case 115: #line 795 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s function nakedvar = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentstring); strncpy(P.currentid, P.currentstring, CF_MAXVARSIZE - 1); // Make a var look like an ID free(P.currentstring); P.currentstring = NULL; } #line 2137 "cf3parse.c" /* yacc.c:1646 */ break; case 116: #line 808 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s Finished with function, now at level %d\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.arg_nesting); } #line 2145 "cf3parse.c" /* yacc.c:1646 */ break; case 117: #line 815 "cf3parse.y" /* yacc.c:1646 */ { if (++P.arg_nesting >= CF_MAX_NESTING) { fatal_yyerror("Nesting of functions is deeper than recommended"); } P.currentfnid[P.arg_nesting] = xstrdup(P.currentid); ParserDebug("\tP:%s:%s:%s begin givearglist for function %s, level %d\n", ParserBlockString(P.block),P.blocktype,P.blockid, P.currentfnid[P.arg_nesting], P.arg_nesting ); } #line 2158 "cf3parse.c" /* yacc.c:1646 */ break; case 118: #line 827 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s end givearglist for function %s, level %d\n", ParserBlockString(P.block),P.blocktype,P.blockid, P.currentfnid[P.arg_nesting], P.arg_nesting ); P.currentfncall[P.arg_nesting] = FnCallNew(P.currentfnid[P.arg_nesting], P.giveargs[P.arg_nesting]); P.giveargs[P.arg_nesting] = NULL; strcpy(P.currentid,""); free(P.currentfnid[P.arg_nesting]); P.currentfnid[P.arg_nesting] = NULL; P.arg_nesting--; } #line 2172 "cf3parse.c" /* yacc.c:1646 */ break; case 122: #line 844 "cf3parse.y" /* yacc.c:1646 */ { ParseError("Expected ',', wrong input '%s'", yytext); yyclearin; } #line 2181 "cf3parse.c" /* yacc.c:1646 */ break; case 123: #line 852 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("\tP:%s:%s:%s:%s function %s, id arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentid); /* currently inside a use function */ RlistAppendScalar(&P.giveargs[P.arg_nesting],P.currentid); } #line 2191 "cf3parse.c" /* yacc.c:1646 */ break; case 124: #line 859 "cf3parse.y" /* yacc.c:1646 */ { /* currently inside a use function */ ParserDebug("\tP:%s:%s:%s:%s function %s, qstring arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentstring); RlistAppendScalar(&P.giveargs[P.arg_nesting],P.currentstring); free(P.currentstring); P.currentstring = NULL; } #line 2203 "cf3parse.c" /* yacc.c:1646 */ break; case 125: #line 868 "cf3parse.y" /* yacc.c:1646 */ { /* currently inside a use function */ ParserDebug("\tP:%s:%s:%s:%s function %s, nakedvar arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentstring); RlistAppendScalar(&P.giveargs[P.arg_nesting],P.currentstring); free(P.currentstring); P.currentstring = NULL; } #line 2215 "cf3parse.c" /* yacc.c:1646 */ break; case 126: #line 877 "cf3parse.y" /* yacc.c:1646 */ { /* Careful about recursion */ ParserDebug("\tP:%s:%s:%s:%s function %s, nakedvar arg = %s\n", ParserBlockString(P.block), P.blocktype, P.blockid, P.currentclasses ? P.currentclasses : "any", P.currentfnid[P.arg_nesting], P.currentstring); RlistAppend(&P.giveargs[P.arg_nesting], P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL); RvalDestroy((Rval) { P.currentfncall[P.arg_nesting+1], RVAL_TYPE_FNCALL }); P.currentfncall[P.arg_nesting+1] = NULL; } #line 2227 "cf3parse.c" /* yacc.c:1646 */ break; case 127: #line 886 "cf3parse.y" /* yacc.c:1646 */ { ParserDebug("P:rval:function:gaitem:error yychar = %d\n", yychar); if (yychar == ';') { ParseError("Expected ')', wrong input '%s'", yytext); } else if (yychar == FAT_ARROW ) { ParseError("Check function statement previous line, Expected ')', wrong input '%s'", yytext); } else { ParseError("Invalid function argument, wrong input '%s'", yytext); } yyclearin; } #line 2248 "cf3parse.c" /* yacc.c:1646 */ break; #line 2252 "cf3parse.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif return yyresult; } #line 903 "cf3parse.y" /* yacc.c:1906 */ cfengine-3.24.2/libpromises/syntax.c0000644000000000000000000011772615010704253017413 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include /* IsStrIn */ #include /* StringMatchFull */ #include #include #include #include static SyntaxTypeMatch CheckParseString(const char *lv, const char *s, const char *range); static SyntaxTypeMatch CheckParseInt(const char *lv, const char *s, const char *range); static SyntaxTypeMatch CheckParseReal(const char *lv, const char *s, const char *range); static SyntaxTypeMatch CheckParseRealRange(const char *lval, const char *s, const char *range); static SyntaxTypeMatch CheckParseIntRange(const char *lval, const char *s, const char *range); static SyntaxTypeMatch CheckParseOpts(const char *s, const char *range); static SyntaxTypeMatch CheckFnCallType(const char *s, DataType dtype); /*********************************************************/ static const PromiseTypeSyntax *PromiseTypeSyntaxGetStrict(const char *bundle_type, const char *promise_type) { assert(bundle_type != NULL); assert(promise_type != NULL); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; if (strcmp(bundle_type, promise_type_syntax->bundle_type) == 0 && strcmp(promise_type, promise_type_syntax->promise_type) == 0) { return promise_type_syntax; } } } return NULL; } bool IsBuiltInPromiseType(const char *const promise_type) { // Any built in promise type, regardless of bundle (agent) type assert(promise_type != NULL); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { const PromiseTypeSyntax *const module = CF_ALL_PROMISE_TYPES[module_index]; for (int promise_type_index = 0; module[promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &(module[promise_type_index]); if (StringEqual(promise_type, promise_type_syntax->promise_type)) { return true; } } } return false; } const PromiseTypeSyntax *PromiseTypeSyntaxGet(const char *bundle_type, const char *promise_type) { const PromiseTypeSyntax *pts = PromiseTypeSyntaxGetStrict(bundle_type, promise_type); if (!pts) { pts = PromiseTypeSyntaxGetStrict("*", promise_type); } return pts; } static const ConstraintSyntax *GetCommonConstraint(const char *lval) { for (int i = 0; CF_COMMON_PROMISE_TYPES[i].promise_type; i++) { const ConstraintSyntax *constraints = CF_COMMON_PROMISE_TYPES[i].constraints; for (int j = 0; constraints[j].lval != NULL; j++) { if (StringEqual(constraints[j].lval, lval)) { return &(constraints[j]); } } } return NULL; } const ConstraintSyntax *BodySyntaxGetConstraintSyntax(const ConstraintSyntax *body_syntax, const char *lval) { if (body_syntax == NULL) { return NULL; } for (int j = 0; body_syntax[j].lval; j++) { if (strcmp(body_syntax[j].lval, lval) == 0) { return &body_syntax[j]; } } return NULL; } const ConstraintSyntax *PromiseTypeSyntaxGetConstraintSyntax(const PromiseTypeSyntax *promise_type_syntax, const char *lval) { assert(promise_type_syntax != NULL); assert(lval != NULL); for (int i = 0; promise_type_syntax->constraints[i].lval; i++) { if (strcmp(promise_type_syntax->constraints[i].lval, lval) == 0) { return &promise_type_syntax->constraints[i]; } } const ConstraintSyntax *constraint_syntax = NULL; if (strcmp("edit_line", promise_type_syntax->bundle_type) == 0) { constraint_syntax = BodySyntaxGetConstraintSyntax(CF_COMMON_EDITBODIES, lval); if (constraint_syntax) { return constraint_syntax; } } else if (strcmp("edit_xml", promise_type_syntax->bundle_type) == 0) { constraint_syntax = BodySyntaxGetConstraintSyntax(CF_COMMON_XMLBODIES, lval); if (constraint_syntax) { return constraint_syntax; } } return GetCommonConstraint(lval); } const BodySyntax *BodySyntaxGet(ARG_UNUSED ParserBlock block, const char *body_type) { if (block == PARSER_BLOCK_PROMISE) { // Required: promise agent if (!StringEqual(body_type, "agent")) { return NULL; } return &CUSTOM_PROMISE_BLOCK_SYNTAX; } assert(block == PARSER_BLOCK_BODY); for (int i = 0; i < CF3_MODULES; i++) { const PromiseTypeSyntax *promise_type_syntax = CF_ALL_PROMISE_TYPES[i]; for (int k = 0; promise_type_syntax[k].bundle_type != NULL; k++) { for (int z = 0; promise_type_syntax[k].constraints[z].lval != NULL; z++) { const ConstraintSyntax constraint_syntax = promise_type_syntax[k].constraints[z]; if (constraint_syntax.dtype == CF_DATA_TYPE_BODY && strcmp(body_type, constraint_syntax.lval) == 0) { return constraint_syntax.range.body_type_syntax; } } } } for (int i = 0; CONTROL_BODIES[i].body_type != NULL; i++) { const BodySyntax body_syntax = CONTROL_BODIES[i]; if (strcmp(body_type, body_syntax.body_type) == 0) { return &CONTROL_BODIES[i]; } } // Not a built in body type, assume it's a custom body type return &CUSTOM_BODY_BLOCK_SYNTAX; } const char *SyntaxStatusToString(SyntaxStatus status) { assert( status == SYNTAX_STATUS_DEPRECATED || status == SYNTAX_STATUS_NORMAL || status == SYNTAX_STATUS_REMOVED ); switch (status) { case SYNTAX_STATUS_DEPRECATED: return "deprecated"; case SYNTAX_STATUS_NORMAL: return "normal"; case SYNTAX_STATUS_REMOVED: return "removed"; case SYNTAX_STATUS_CUSTOM: return "custom"; default: break; } return NULL; } /****************************************************************************/ DataType ExpectedDataType(const char *lvalname) { int i, j, k, l; const ConstraintSyntax *bs, *bs2; const PromiseTypeSyntax *ss; for (i = 0; i < CF3_MODULES; i++) { if ((ss = CF_ALL_PROMISE_TYPES[i]) == NULL) { continue; } for (j = 0; ss[j].promise_type != NULL; j++) { if ((bs = ss[j].constraints) == NULL) { continue; } for (k = 0; bs[k].lval != NULL; k++) { if (strcmp(lvalname, bs[k].lval) == 0) { return bs[k].dtype; } } for (k = 0; bs[k].lval != NULL; k++) { if (bs[k].dtype == CF_DATA_TYPE_BODY) { bs2 = bs[k].range.body_type_syntax->constraints; if (bs2 == NULL || bs2 == (void *) CF_BUNDLE) { continue; } for (l = 0; bs2[l].dtype != CF_DATA_TYPE_NONE; l++) { if (strcmp(lvalname, bs2[l].lval) == 0) { return bs2[l].dtype; } } } } } } return CF_DATA_TYPE_NONE; } /****************************************************************************/ /* Level 1 */ /****************************************************************************/ const char *SyntaxTypeMatchToString(SyntaxTypeMatch result) { assert(result < SYNTAX_TYPE_MATCH_MAX); static const char *const msgs[SYNTAX_TYPE_MATCH_MAX] = { [SYNTAX_TYPE_MATCH_OK] = "OK", [SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED] = "Cannot check unexpanded value", [SYNTAX_TYPE_MATCH_ERROR_RANGE_BRACKETED] = "Real range specification should not be enclosed in brackets - just 'a,b'", [SYNTAX_TYPE_MATCH_ERROR_RANGE_MULTIPLE_ITEMS] = "Range format specifier should be of form 'a,b'' but got multiple items", [SYNTAX_TYPE_MATCH_ERROR_GOT_SCALAR] = "Attempted to give a scalar to a non-scalar type", [SYNTAX_TYPE_MATCH_ERROR_GOT_LIST] = "Attempted to give a list to a non-list type", [SYNTAX_TYPE_MATCH_ERROR_GOT_NULL] = "Attempted to give a value of type null", [SYNTAX_TYPE_MATCH_ERROR_STRING_UNIX_PERMISSION] = "Error parsing Unix permission string", [SYNTAX_TYPE_MATCH_ERROR_SCALAR_OUT_OF_RANGE] = "Scalar value is out of range", [SYNTAX_TYPE_MATCH_ERROR_EMPTY_SCALAR_OUT_OF_RANGE] = "Empty scalar value is out of range", [SYNTAX_TYPE_MATCH_ERROR_INT_PARSE] = "Cannot parse value as integer", [SYNTAX_TYPE_MATCH_ERROR_INT_OUT_OF_RANGE] = "Integer is out of range", [SYNTAX_TYPE_MATCH_ERROR_REAL_INF] = "Keyword 'inf' has an integer value, cannot be used as real", [SYNTAX_TYPE_MATCH_ERROR_REAL_OUT_OF_RANGE] = "Real value is out of range", [SYNTAX_TYPE_MATCH_ERROR_OPTS_OUT_OF_RANGE] = "Selection is out of bounds", [SYNTAX_TYPE_MATCH_ERROR_FNCALL_RETURN_TYPE] = "Function does not return the required type", [SYNTAX_TYPE_MATCH_ERROR_FNCALL_UNKNOWN] = "Unknown function", [SYNTAX_TYPE_MATCH_ERROR_CONTEXT_OUT_OF_RANGE] = "Context string is invalid/out of range", [SYNTAX_TYPE_MATCH_ERROR_ABSOLUTE_PATH] = "Filename is not an absolute path", }; return msgs[result]; } SyntaxTypeMatch CheckConstraintTypeMatch(const char *lval, Rval rval, DataType dt, const char *range, int level) { Rlist *rp; Item *checklist; /* Get type of lval */ switch (rval.type) { case RVAL_TYPE_SCALAR: switch (dt) { case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_CONTEXT_LIST: case CF_DATA_TYPE_OPTION_LIST: if (level == 0) { return SYNTAX_TYPE_MATCH_ERROR_GOT_SCALAR; } break; default: /* Only lists are incompatible with scalars */ break; } break; case RVAL_TYPE_LIST: switch (dt) { case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_CONTEXT_LIST: case CF_DATA_TYPE_OPTION_LIST: break; default: return SYNTAX_TYPE_MATCH_ERROR_GOT_LIST; } for (rp = (Rlist *) rval.item; rp != NULL; rp = rp->next) { SyntaxTypeMatch err = CheckConstraintTypeMatch(lval, rp->val, dt, range, 1); switch (err) { case SYNTAX_TYPE_MATCH_OK: case SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED: break; default: return err; } } return SYNTAX_TYPE_MATCH_OK; case RVAL_TYPE_FNCALL: /* Fn-like objects are assumed to be parameterized bundles in these... */ checklist = SplitString("bundlesequence,edit_line,edit_xml,usebundle,service_bundle,home_bundle", ','); if (!IsItemIn(checklist, lval)) { SyntaxTypeMatch err = CheckFnCallType(RvalFnCallValue(rval)->name, dt); DeleteItemList(checklist); return err; } DeleteItemList(checklist); return SYNTAX_TYPE_MATCH_OK; case RVAL_TYPE_CONTAINER: break; case RVAL_TYPE_NOPROMISEE: return SYNTAX_TYPE_MATCH_ERROR_GOT_NULL; } /* If we get here, we have a literal scalar type */ switch (dt) { case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_STRING_LIST: return CheckParseString(lval, (const char *) rval.item, range); case CF_DATA_TYPE_INT: case CF_DATA_TYPE_INT_LIST: return CheckParseInt(lval, (const char *) rval.item, range); case CF_DATA_TYPE_REAL: case CF_DATA_TYPE_REAL_LIST: return CheckParseReal(lval, (const char *) rval.item, range); case CF_DATA_TYPE_BODY: case CF_DATA_TYPE_BUNDLE: case CF_DATA_TYPE_CONTAINER: break; case CF_DATA_TYPE_OPTION: case CF_DATA_TYPE_OPTION_LIST: return CheckParseOpts(RvalScalarValue(rval), range); case CF_DATA_TYPE_CONTEXT: case CF_DATA_TYPE_CONTEXT_LIST: return CheckParseContext((const char *) rval.item, range); case CF_DATA_TYPE_INT_RANGE: return CheckParseIntRange(lval, (const char *) rval.item, range); case CF_DATA_TYPE_REAL_RANGE: return CheckParseRealRange(lval, (char *) rval.item, range); default: ProgrammingError("Unknown (unhandled) datatype for lval = %s (CheckConstraintTypeMatch)", lval); break; } return SYNTAX_TYPE_MATCH_OK; } /****************************************************************************/ DataType StringDataType(EvalContext *ctx, const char *string) { int islist = false; /* TODO something is wrong here */ /*------------------------------------------------------- What happens if we embed vars in a literal string "$(list)withending" - a list? "$(list1)$(list2)" - not a simple list Disallow these manual concatenations as ambiguous. Demand this syntax to work around vars: "listvar" slist => EmbellishList("prefix$(list)suffix"); ---------------------------------------------------------*/ size_t len = strlen(string); if (*string == '$') { Buffer *inner_value = BufferNew(); if (ExtractScalarReference(inner_value, string, len, true)) { DataType dtype; if (!IsExpandable(BufferData(inner_value))) { VarRef *ref = VarRefParse(BufferData(inner_value)); EvalContextVariableGet(ctx, ref, &dtype); VarRefDestroy(ref); if (DataTypeToRvalType(dtype) == RVAL_TYPE_LIST) { if (!islist) { islist = true; } else { islist = false; } } } if (BufferSize(inner_value) == strlen(string)) { BufferDestroy(inner_value); return dtype; } else { BufferDestroy(inner_value); return CF_DATA_TYPE_STRING; } } BufferDestroy(inner_value); } return CF_DATA_TYPE_STRING; } /****************************************************************************/ /* Level 1 */ /****************************************************************************/ static SyntaxTypeMatch CheckParseString(const char *lval, const char *s, const char *range) { if (s == NULL) { return SYNTAX_TYPE_MATCH_OK; } if (strlen(range) == 0) { return SYNTAX_TYPE_MATCH_OK; } if (IsNakedVar(s, '@') || IsNakedVar(s, '$')) { return SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED; } /* Deal with complex strings as special cases */ if (strcmp(lval, "mode") == 0 || strcmp(lval, "search_mode") == 0) { mode_t plus, minus; if (!ParseModeString(s, &plus, &minus)) { return SYNTAX_TYPE_MATCH_ERROR_STRING_UNIX_PERMISSION; } } /* FIXME: review this strcmp. Moved out from StringMatch */ if (!strcmp(range, s) || StringMatchFull(range, s)) { return SYNTAX_TYPE_MATCH_OK; } if (IsCf3VarString(s)) { return SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED; } else if ('\0' == s[0]) { return SYNTAX_TYPE_MATCH_ERROR_EMPTY_SCALAR_OUT_OF_RANGE; } else if (!strcmp(range, CF_ABSPATHRANGE)) { return SYNTAX_TYPE_MATCH_ERROR_ABSOLUTE_PATH; } else { return SYNTAX_TYPE_MATCH_ERROR_SCALAR_OUT_OF_RANGE; } return SYNTAX_TYPE_MATCH_OK; } /****************************************************************************/ SyntaxTypeMatch CheckParseContext(const char *context, const char *range) { if (strlen(range) == 0) { return SYNTAX_TYPE_MATCH_OK; } /* FIXME: review this strcmp. Moved out from StringMatch */ if (!strcmp(range, context) || StringMatchFull(range, context)) { return SYNTAX_TYPE_MATCH_OK; } return SYNTAX_TYPE_MATCH_ERROR_CONTEXT_OUT_OF_RANGE; } /****************************************************************************/ static SyntaxTypeMatch CheckParseInt(const char *lval, const char *s, const char *range) { Item *split; int n; long long max = CF_LOWINIT, min = CF_HIGHINIT; // Numeric types are registered by range separated by comma str "min,max" split = SplitString(range, ','); if ((n = ListLen(split)) != 2) { ProgrammingError("INTERN: format specifier for int rvalues is not ok for lval %s - got %d items", lval, n); } sscanf(split->name, "%lld", &min); if (strcmp(split->next->name, "inf") == 0) { max = CF_INFINITY; } else { sscanf(split->next->name, "%lld", &max); } DeleteItemList(split); if (min == CF_HIGHINIT || max == CF_LOWINIT) { ProgrammingError("INTERN: could not parse format specifier for int rvalues for lval %s", lval); } if (IsCf3VarString(s)) { return SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED; } long val = IntFromString(s); if (val == CF_NOINT) { return SYNTAX_TYPE_MATCH_ERROR_INT_PARSE; } if (val > max || val < min) { return SYNTAX_TYPE_MATCH_ERROR_INT_OUT_OF_RANGE; } return SYNTAX_TYPE_MATCH_OK; } /****************************************************************************/ static SyntaxTypeMatch CheckParseIntRange(const char *lval, const char *s, const char *range) { Item *split, *ip, *rangep; int n; long long max = CF_LOWINIT, min = CF_HIGHINIT; // Numeric types are registered by range separated by comma str "min,max" if (*s == '[' || *s == '(') { return SYNTAX_TYPE_MATCH_ERROR_RANGE_BRACKETED; } split = SplitString(range, ','); if ((n = ListLen(split)) != 2) { ProgrammingError("Format specifier %s for irange rvalues is not ok for lval %s - got %d items", range, lval, n); } sscanf(split->name, "%lld", &min); if (strcmp(split->next->name, "inf") == 0) { max = CF_INFINITY; } else { sscanf(split->next->name, "%lld", &max); } DeleteItemList(split); if (min == CF_HIGHINIT || max == CF_LOWINIT) { ProgrammingError("Could not parse irange format specifier for int rvalues for lval %s", lval); } if (IsCf3VarString(s)) { return SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED; } rangep = SplitString(s, ','); if ((n = ListLen(rangep)) != 2) { return SYNTAX_TYPE_MATCH_ERROR_RANGE_MULTIPLE_ITEMS; } for (ip = rangep; ip != NULL; ip = ip->next) { long val = IntFromString(ip->name); if (val > max || val < min) { return SYNTAX_TYPE_MATCH_ERROR_INT_OUT_OF_RANGE; } } DeleteItemList(rangep); return SYNTAX_TYPE_MATCH_OK; } /****************************************************************************/ static SyntaxTypeMatch CheckParseReal(const char *lval, const char *s, const char *range) { Item *split; double max = (double) CF_LOWINIT, min = (double) CF_HIGHINIT, val; int n; if (strcmp(s, "inf") == 0) { return SYNTAX_TYPE_MATCH_ERROR_REAL_INF; } if (IsCf3VarString(s)) { return SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED; } /* Numeric types are registered by range separated by comma str "min,max" */ split = SplitString(range, ','); if ((n = ListLen(split)) != 2) { ProgrammingError("Format specifier for real rvalues is not ok for lval %s - %d items", lval, n); } sscanf(split->name, "%lf", &min); sscanf(split->next->name, "%lf", &max); DeleteItemList(split); if (min == CF_HIGHINIT || max == CF_LOWINIT) { ProgrammingError("Could not parse format specifier for int rvalues for lval %s", lval); } if (!DoubleFromString(s, &val)) { return SYNTAX_TYPE_MATCH_ERROR_REAL_OUT_OF_RANGE; } if (val > max || val < min) { return SYNTAX_TYPE_MATCH_ERROR_REAL_OUT_OF_RANGE; } return SYNTAX_TYPE_MATCH_OK; } /****************************************************************************/ static SyntaxTypeMatch CheckParseRealRange(const char *lval, const char *s, const char *range) { Item *split, *rangep, *ip; double max = (double) CF_LOWINIT, min = (double) CF_HIGHINIT, val; int n; if (*s == '[' || *s == '(') { return SYNTAX_TYPE_MATCH_ERROR_RANGE_BRACKETED; } if (strcmp(s, "inf") == 0) { return SYNTAX_TYPE_MATCH_ERROR_REAL_INF; } if (IsCf3VarString(s)) { return SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED; } /* Numeric types are registered by range separated by comma str "min,max" */ split = SplitString(range, ','); if ((n = ListLen(split)) != 2) { ProgrammingError("Format specifier for real rvalues is not ok for lval %s - %d items", lval, n); } sscanf(split->name, "%lf", &min); sscanf(split->next->name, "%lf", &max); DeleteItemList(split); if (min == CF_HIGHINIT || max == CF_LOWINIT) { ProgrammingError("Could not parse format specifier for int rvalues for lval %s", lval); } rangep = SplitString(s, ','); if ((n = ListLen(rangep)) != 2) { return SYNTAX_TYPE_MATCH_ERROR_RANGE_MULTIPLE_ITEMS; } for (ip = rangep; ip != NULL; ip = ip->next) { if (!DoubleFromString(ip->name, &val)) { return SYNTAX_TYPE_MATCH_ERROR_REAL_OUT_OF_RANGE; } if (val > max || val < min) { return SYNTAX_TYPE_MATCH_ERROR_REAL_OUT_OF_RANGE; } } DeleteItemList(rangep); return SYNTAX_TYPE_MATCH_OK; } /****************************************************************************/ static SyntaxTypeMatch CheckParseOpts(const char *s, const char *range) { Item *split; /* List/menu types are separated by comma str "a,b,c,..." */ if (IsNakedVar(s, '@') || IsNakedVar(s, '$')) { return SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED; } split = SplitString(range, ','); if (!IsItemIn(split, s)) { DeleteItemList(split); return SYNTAX_TYPE_MATCH_ERROR_OPTS_OUT_OF_RANGE; } DeleteItemList(split); return SYNTAX_TYPE_MATCH_OK; } /****************************************************************************/ bool CheckParseVariableName(const char *const name) { assert(name != NULL); const char *const reserved[] = { "promiser", "handle", "promise_filename", "promise_dirname", "promise_linenumber", "this", NULL }; if (IsStrIn(name, reserved)) { return false; } int count = 0, level = 0; const char *const first_dot = strchr(name, '.'); if (first_dot != NULL) { for (const char *sp = name; *sp != '\0'; sp++) { switch (*sp) { case '.': count++; if (count > 1 && level != 1) { // Adding a second dot is not allowed, // except inside 1 level of square brackets return false; } break; case '[': level++; break; case ']': level--; break; default: break; } if (level > 1) { yyerror("Too many levels of [] reserved for array use"); return false; } } if (count == 1) { // Check that there is something before and after first dot: if (name[0] == '.' || first_dot[1] == '\0') { return false; } } } return true; } /****************************************************************************/ static SyntaxTypeMatch CheckFnCallType(const char *s, DataType desired_type) { const FnCallType *fn = FnCallTypeGet(s); if (fn != NULL) { DataType fn_ret_type = fn->dtype; if (desired_type != fn_ret_type) { /* All scalar values can be used where string is expected (they are, * in fact, strings internally, see RvalType). */ if ((desired_type == CF_DATA_TYPE_STRING) && ((fn_ret_type == CF_DATA_TYPE_INT) || (fn_ret_type == CF_DATA_TYPE_REAL) || (fn_ret_type == CF_DATA_TYPE_OPTION) || (fn_ret_type == CF_DATA_TYPE_CONTEXT))) { return SYNTAX_TYPE_MATCH_OK; } /* Ok to allow fn calls of correct element-type in lists */ if (fn_ret_type == CF_DATA_TYPE_STRING && desired_type == CF_DATA_TYPE_STRING_LIST) { return SYNTAX_TYPE_MATCH_OK; } if (fn_ret_type == CF_DATA_TYPE_STRING && desired_type == CF_DATA_TYPE_CONTEXT) { return SYNTAX_TYPE_MATCH_OK; } if (fn_ret_type == CF_DATA_TYPE_INT && desired_type == CF_DATA_TYPE_INT_LIST) { return SYNTAX_TYPE_MATCH_OK; } if (fn_ret_type == CF_DATA_TYPE_REAL && desired_type == CF_DATA_TYPE_REAL_LIST) { return SYNTAX_TYPE_MATCH_OK; } if (fn_ret_type == CF_DATA_TYPE_OPTION && desired_type == CF_DATA_TYPE_OPTION_LIST) { return SYNTAX_TYPE_MATCH_OK; } if (fn_ret_type == CF_DATA_TYPE_CONTEXT && desired_type == CF_DATA_TYPE_CONTEXT_LIST) { return SYNTAX_TYPE_MATCH_OK; } return SYNTAX_TYPE_MATCH_ERROR_FNCALL_RETURN_TYPE; } else { return SYNTAX_TYPE_MATCH_OK; } } else { return SYNTAX_TYPE_MATCH_ERROR_FNCALL_UNKNOWN; } } /****************************************************************************/ static JsonElement *ConstraintSyntaxToJson(const ConstraintSyntax *constraint_syntax) { JsonElement *json_constraint = JsonObjectCreate(5); JsonObjectAppendString(json_constraint, "attribute", constraint_syntax->lval); JsonObjectAppendString(json_constraint, "status", SyntaxStatusToString(constraint_syntax->status)); JsonObjectAppendString(json_constraint, "type", DataTypeToString(constraint_syntax->dtype)); if (constraint_syntax->dtype != CF_DATA_TYPE_BODY && constraint_syntax->dtype != CF_DATA_TYPE_BUNDLE) { JsonObjectAppendString(json_constraint, "range", constraint_syntax->range.validation_string); } return json_constraint; } static JsonElement *BodySyntaxToJson(const BodySyntax *body_syntax) { JsonElement *json_body = JsonObjectCreate(2); JsonObjectAppendString(json_body, "status", SyntaxStatusToString(body_syntax->status)); { JsonElement *attributes = JsonObjectCreate(50); for (int i = 0; body_syntax->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &body_syntax->constraints[i]; if (constraint_syntax->status != SYNTAX_STATUS_REMOVED) { JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "body"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } } JsonObjectAppendObject(json_body, "attributes", attributes); } return json_body; } static JsonElement *JsonBundleTypeNew(void) { JsonElement *json_bundle_type = JsonObjectCreate(2); JsonObjectAppendString(json_bundle_type, "status", SyntaxStatusToString(SYNTAX_STATUS_NORMAL)); JsonObjectAppendArray(json_bundle_type, "promiseTypes", JsonArrayCreate(50)); return json_bundle_type; } static JsonElement *BundleTypesToJson(void) { JsonElement *bundle_types = JsonObjectCreate(50); Seq *common_promise_types = SeqNew(50, free); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; // skip global constraints if (strcmp("*", promise_type_syntax->promise_type) == 0) { continue; } // collect common promise types to be appended at the end if (strcmp("*", promise_type_syntax->bundle_type) == 0) { SeqAppend(common_promise_types, xstrdup(promise_type_syntax->promise_type)); continue; } if (promise_type_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonElement *bundle_type = JsonObjectGet(bundle_types, promise_type_syntax->bundle_type); if (!bundle_type) { bundle_type = JsonBundleTypeNew(); JsonObjectAppendObject(bundle_types, promise_type_syntax->bundle_type, bundle_type); } assert(bundle_type); JsonElement *promise_types = JsonObjectGet(bundle_type, "promiseTypes"); assert(promise_types); JsonArrayAppendString(promise_types, promise_type_syntax->promise_type); } } // Append the common bundle, which has only common promise types, but is not declared in syntax { JsonElement *bundle_type = JsonBundleTypeNew(); JsonObjectAppendObject(bundle_types, "common", bundle_type); } JsonIterator it = JsonIteratorInit(bundle_types); const char *bundle_type = NULL; while ((bundle_type = JsonIteratorNextKey(&it))) { JsonElement *promise_types = JsonObjectGetAsArray(JsonObjectGetAsObject(bundle_types, bundle_type), "promiseTypes"); for (size_t i = 0; i < SeqLength(common_promise_types); i++) { const char *common_promise_type = SeqAt(common_promise_types, i); JsonArrayAppendString(promise_types, common_promise_type); } } SeqDestroy(common_promise_types); return bundle_types; } static JsonElement *JsonPromiseTypeNew(SyntaxStatus status) { JsonElement *promise_type = JsonObjectCreate(2); JsonObjectAppendString(promise_type, "status", SyntaxStatusToString(status)); JsonObjectAppendObject(promise_type, "attributes", JsonObjectCreate(50)); return promise_type; } static JsonElement *PromiseTypesToJson(void) { JsonElement *promise_types = JsonObjectCreate(50); const PromiseTypeSyntax *global_promise_type = PromiseTypeSyntaxGet("*", "*"); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; // skip global and bundle-local common constraints if (strcmp("*", promise_type_syntax->promise_type) == 0) { continue; } if (promise_type_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonElement *promise_type = JsonObjectGet(promise_types, promise_type_syntax->promise_type); if (!promise_type) { promise_type = JsonPromiseTypeNew(promise_type_syntax->status); JsonObjectAppendObject(promise_types, promise_type_syntax->promise_type, promise_type); } assert(promise_type); JsonElement *attributes = JsonObjectGet(promise_type, "attributes"); assert(attributes); for (int i = 0; promise_type_syntax->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &promise_type_syntax->constraints[i]; JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "promiseType"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } // append bundle common constraints const PromiseTypeSyntax *bundle_promise_type = PromiseTypeSyntaxGet(promise_type_syntax->bundle_type, "*"); if (strcmp("*", bundle_promise_type->bundle_type) != 0) { for (int i = 0; bundle_promise_type->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &bundle_promise_type->constraints[i]; JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "bundle"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } } // append global common constraints for (int i = 0; global_promise_type->constraints[i].lval; i++) { const ConstraintSyntax *constraint_syntax = &global_promise_type->constraints[i]; JsonElement *json_constraint = ConstraintSyntaxToJson(constraint_syntax); JsonObjectAppendString(json_constraint, "visibility", "global"); JsonObjectAppendObject(attributes, constraint_syntax->lval, json_constraint); } } } return promise_types; } static JsonElement *BodyTypesToJson(void) { JsonElement *body_types = JsonObjectCreate(50); for (int module_index = 0; module_index < CF3_MODULES; module_index++) { for (int promise_type_index = 0; CF_ALL_PROMISE_TYPES[module_index][promise_type_index].promise_type; promise_type_index++) { const PromiseTypeSyntax *promise_type_syntax = &CF_ALL_PROMISE_TYPES[module_index][promise_type_index]; for (int constraint_index = 0; promise_type_syntax->constraints[constraint_index].lval; constraint_index++) { const ConstraintSyntax *constraint_syntax = &promise_type_syntax->constraints[constraint_index]; if (constraint_syntax->dtype != CF_DATA_TYPE_BODY) { continue; } if (constraint_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } const BodySyntax *body_syntax = constraint_syntax->range.body_type_syntax; JsonElement *body_type = JsonObjectGet(body_types, body_syntax->body_type); if (!body_type) { JsonElement *body_type = BodySyntaxToJson(body_syntax); JsonObjectAppendObject(body_types, body_syntax->body_type, body_type); } } } } for (int i = 0; CONTROL_BODIES[i].body_type; i++) { const BodySyntax *body_syntax = &CONTROL_BODIES[i]; if (body_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonElement *body_type = JsonObjectGet(body_types, body_syntax->body_type); if (!body_type) { JsonElement *body_type = BodySyntaxToJson(body_syntax); JsonObjectAppendObject(body_types, body_syntax->body_type, body_type); } } return body_types; } static const char *FnCallCategoryToString(FnCallCategory category) { static const char *const category_str[] = { [FNCALL_CATEGORY_COMM] = "communication", [FNCALL_CATEGORY_DATA] = "data", [FNCALL_CATEGORY_FILES] = "files", [FNCALL_CATEGORY_IO] = "io", [FNCALL_CATEGORY_SYSTEM] = "system", [FNCALL_CATEGORY_UTILS] = "utils", [FNCALL_CATEGORY_INTERNAL] = "internal" }; return category_str[category]; } static JsonElement *FnCallTypeToJson(const FnCallType *fn_syntax) { JsonElement *json_fn = JsonObjectCreate(10); JsonObjectAppendString(json_fn, "status", SyntaxStatusToString(fn_syntax->status)); JsonObjectAppendString(json_fn, "returnType", DataTypeToString(fn_syntax->dtype)); { JsonElement *params = JsonArrayCreate(10); for (int i = 0; fn_syntax->args[i].pattern; i++) { const FnCallArg *param = &fn_syntax->args[i]; JsonElement *json_param = JsonObjectCreate(2); JsonObjectAppendString(json_param, "type", DataTypeToString(param->dtype)); JsonObjectAppendString(json_param, "range", param->pattern); JsonObjectAppendString(json_param, "description", param->description); JsonArrayAppendObject(params, json_param); } JsonObjectAppendArray(json_fn, "parameters", params); } JsonObjectAppendBool(json_fn, "variadic", fn_syntax->options & FNCALL_OPTION_VARARG); JsonObjectAppendBool(json_fn, "cached", fn_syntax->options & FNCALL_OPTION_CACHED); JsonObjectAppendBool(json_fn, "collecting", fn_syntax->options & FNCALL_OPTION_COLLECTING); JsonObjectAppendString(json_fn, "category", FnCallCategoryToString(fn_syntax->category)); return json_fn; } static JsonElement *FunctionsToJson(void) { JsonElement *functions = JsonObjectCreate(500); for (int i = 0; CF_FNCALL_TYPES[i].name; i++) { const FnCallType *fn_syntax = &CF_FNCALL_TYPES[i]; if (fn_syntax->status == SYNTAX_STATUS_REMOVED) { continue; } JsonObjectAppendObject(functions, fn_syntax->name, FnCallTypeToJson(fn_syntax)); } return functions; } JsonElement *SyntaxToJson(void) { JsonElement *syntax_tree = JsonObjectCreate(3); JsonObjectAppendObject(syntax_tree, "bundleTypes", BundleTypesToJson()); JsonObjectAppendObject(syntax_tree, "promiseTypes", PromiseTypesToJson()); JsonObjectAppendObject(syntax_tree, "bodyTypes", BodyTypesToJson()); JsonObjectAppendObject(syntax_tree, "functions", FunctionsToJson()); return syntax_tree; } cfengine-3.24.2/libpromises/acl_tools_posix.c0000644000000000000000000001662515010704253021262 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #ifdef HAVE_ACL_H # include #endif #ifdef HAVE_SYS_ACL_H # include #endif #ifdef HAVE_ACL_LIBACL_H # include #endif #ifdef HAVE_LIBACL #include /* GetUserID() */ bool CopyACLs(const char *src, const char *dst, bool *change) { acl_t acls; struct stat statbuf; int ret; acls = acl_get_file(src, ACL_TYPE_ACCESS); if (!acls) { if (errno == ENOTSUP) { if (change != NULL) { *change = false; } return true; } else { Log(LOG_LEVEL_ERR, "Can't copy ACLs from '%s'. (acl_get_file: %s)", src, GetErrorStr()); return false; } } ret = acl_set_file(dst, ACL_TYPE_ACCESS, acls); acl_free(acls); if (ret != 0) { if (errno == ENOTSUP) { if (change != NULL) { *change = false; } return true; } else { Log(LOG_LEVEL_ERR, "Can't copy ACLs to '%s'. (acl_set_file: %s)", dst, GetErrorStr()); return false; } } if (stat(src, &statbuf) != 0) { Log(LOG_LEVEL_ERR, "Can't copy ACLs from '%s'. (stat: %s)", src, GetErrorStr()); return false; } if (!S_ISDIR(statbuf.st_mode)) { if (change != NULL) { *change = false; } return true; } // For directory, copy default ACL too. acls = acl_get_file(src, ACL_TYPE_DEFAULT); if (!acls) { Log(LOG_LEVEL_ERR, "Can't copy ACLs from '%s'. (acl_get_file: %s)", src, GetErrorStr()); return false; } ret = acl_set_file(dst, ACL_TYPE_DEFAULT, acls); acl_free(acls); if (ret != 0) { Log(LOG_LEVEL_ERR, "Can't copy ACLs to '%s'. (acl_set_file: %s)", dst, GetErrorStr()); return false; } if (change != NULL) { *change = true; } return true; } bool AllowAccessForUsers(const char *path, StringSet *users, bool allow_writes, bool allow_execute) { assert(path != NULL); assert(users != NULL); acl_t acl = acl_get_file(path, ACL_TYPE_ACCESS); if (acl == NULL) { Log(LOG_LEVEL_ERR, "Failed to get ACLs for '%s': %s", path, GetErrorStr()); return false; } acl_entry_t entry; int ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); while (ret > 0) { acl_tag_t entry_tag; if (acl_get_tag_type(entry, &entry_tag) == -1) { Log(LOG_LEVEL_ERR, "Failed to get ACL entry type: %s", GetErrorStr()); acl_free(acl); return false; } if (entry_tag == ACL_USER) { if (acl_delete_entry(acl, entry) == -1) { Log(LOG_LEVEL_ERR, "Failed to remove user ACL entry: %s", GetErrorStr()); acl_free(acl); return false; } } ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry); } if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to get ACL entries: %s", GetErrorStr()); acl_free(acl); return false; } StringSetIterator iter = StringSetIteratorInit(users); const char *user = NULL; while ((user = StringSetIteratorNext(&iter)) != NULL) { uid_t uid; if (!GetUserID(user, &uid, LOG_LEVEL_ERR)) { /* errors already logged */ acl_free(acl); return false; } if (acl_create_entry(&acl, &entry) == -1) { Log(LOG_LEVEL_ERR, "Failed to create a new ACL entry: %s", GetErrorStr()); acl_free(acl); return false; } if (acl_set_tag_type(entry, ACL_USER) == -1) { Log(LOG_LEVEL_ERR, "Failed to set ACL entry type: %s", GetErrorStr()); acl_free(acl); return false; } if (acl_set_qualifier(entry, &uid) == -1) { Log(LOG_LEVEL_ERR, "Failed to set ACL entry qualifier: %s", GetErrorStr()); acl_free(acl); return false; } acl_permset_t permset; if (acl_get_permset(entry, &permset) == -1) { Log(LOG_LEVEL_ERR, "Failed to get permset: %s", GetErrorStr()); acl_free(acl); return false; } if (acl_clear_perms(permset) == -1) { Log(LOG_LEVEL_ERR, "Failed to clear permset: %s", GetErrorStr()); acl_free(acl); return false; } if (acl_add_perm(permset, ACL_READ) == -1) { Log(LOG_LEVEL_ERR, "Failed to add read permission to set: %s", GetErrorStr()); acl_free(acl); return false; } if (allow_writes && (acl_add_perm(permset, ACL_WRITE) == -1)) { Log(LOG_LEVEL_ERR, "Failed to add write permission to set: %s", GetErrorStr()); acl_free(acl); return false; } if (allow_execute && (acl_add_perm(permset, ACL_EXECUTE) == -1)) { Log(LOG_LEVEL_ERR, "Failed to add execute permission to set: %s", GetErrorStr()); acl_free(acl); return false; } if (acl_set_permset(entry, permset) == -1) { Log(LOG_LEVEL_ERR, "Failed to set permset: %s", GetErrorStr()); acl_free(acl); return false; } } if (acl_calc_mask(&acl) == -1) { Log(LOG_LEVEL_ERR, "Failed to recalculate mask: %s", GetErrorStr()); acl_free(acl); return false; } if (acl_valid(acl) != 0) { Log(LOG_LEVEL_ERR, "Ended up with an invalid ACL"); acl_free(acl); return false; } if (acl_set_file(path, ACL_TYPE_ACCESS, acl) == -1) { Log(LOG_LEVEL_ERR, "Failed to set ACL: %s", GetErrorStr()); acl_free(acl); return false; } acl_free(acl); return true; } #elif !defined(__MINGW32__) /* !HAVE_LIBACL */ bool CopyACLs(ARG_UNUSED const char *src, ARG_UNUSED const char *dst, bool *change) { if (change != NULL) { *change = false; } return true; } bool AllowAccessForUsers(ARG_UNUSED const char *path, ARG_UNUSED StringSet *users, ARG_UNUSED bool allow_writes, ARG_UNUSED bool allow_execute) { Log(LOG_LEVEL_ERR, "ACL manipulation not supported"); return false; } #endif cfengine-3.24.2/libpromises/chflags.h0000644000000000000000000000224315010704253017464 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CHFLAGS_H #define CFENGINE_CHFLAGS_H /* BSD flags */ #include #include bool ParseFlagString(Rlist *flags, u_long *plusmask, u_long *minusmask); #endif cfengine-3.24.2/libpromises/instrumentation.c0000644000000000000000000001260415010704253021315 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include static void NotePerformance(char *eventname, time_t t, double value); /* Alter this code at your peril. Berkeley DB is very sensitive to errors. */ bool TIMING = false; /***************************************************************/ struct timespec BeginMeasure() { struct timespec start = { 0 }; if (clock_gettime(CLOCK_REALTIME, &start) == -1) { Log(LOG_LEVEL_VERBOSE, "Clock gettime failure. (clock_gettime: %s)", GetErrorStr()); } else if (TIMING) { Log(LOG_LEVEL_VERBOSE, "T: Starting measuring time"); } return start; } /***************************************************************/ void EndMeasurePromise(struct timespec start, const Promise *pp) { char id[CF_BUFSIZE], *mid = NULL; if (TIMING) { Log(LOG_LEVEL_VERBOSE, "\n"); Log(LOG_LEVEL_VERBOSE, "T: ........................................................."); Log(LOG_LEVEL_VERBOSE, "T: Promise timing summary for %s", pp->promiser); } mid = PromiseGetConstraintAsRval(pp, "measurement_class", RVAL_TYPE_SCALAR); if (mid) { snprintf(id, CF_BUFSIZE, "%s:%s:%.100s", mid, PromiseGetPromiseType(pp), pp->promiser); Chop(id, CF_EXPANDSIZE); EndMeasure(id, start); } else { if (TIMING) { Log(LOG_LEVEL_VERBOSE, "T: No measurement_class attribute set in action body"); } EndMeasure(NULL, start); } if (TIMING) { Log(LOG_LEVEL_VERBOSE, "T: ........................................................."); } } /***************************************************************/ void EndMeasure(char *eventname, struct timespec start) { struct timespec stop; if (clock_gettime(CLOCK_REALTIME, &stop) == -1) { Log(LOG_LEVEL_VERBOSE, "Clock gettime failure. (clock_gettime: %s)", GetErrorStr()); } else { double dt = (stop.tv_sec - start.tv_sec) + (stop.tv_nsec - start.tv_nsec) / (double) CF_BILLION; if (eventname) { NotePerformance(eventname, start.tv_sec, dt); } else if (TIMING) { Log(LOG_LEVEL_VERBOSE, "T: This execution measured %lf seconds (use measurement_class to track)", dt); } } } /***************************************************************/ int EndMeasureValueMs(struct timespec start) { struct timespec stop; if (clock_gettime(CLOCK_REALTIME, &stop) == -1) { Log(LOG_LEVEL_VERBOSE, "Clock gettime failure. (clock_gettime: %s)", GetErrorStr()); } else { double dt = ((stop.tv_sec - start.tv_sec) * 1e3 + /* 1 s = 1e3 ms */ (stop.tv_nsec - start.tv_nsec) / 1e6); /* 1e6 ns = 1 ms */ return (int)dt; } return -1; } /***************************************************************/ static void NotePerformance(char *eventname, time_t t, double value) { CF_DB *dbp; Event e, newe; double lastseen; int lsea = SECONDS_PER_WEEK; time_t now = time(NULL); if (!OpenDB(&dbp, dbid_performance)) { return; } if (ReadDB(dbp, eventname, &e, sizeof(e))) { lastseen = now - e.t; newe.t = t; newe.Q = QAverage(e.Q, value, 0.3); /* Have to kickstart variance computation, assume 1% to start */ if (newe.Q.var <= 0.0009) { newe.Q.var = newe.Q.expect / 100.0; } } else { lastseen = 0.0; newe.t = t; newe.Q.q = value; newe.Q.dq = 0; newe.Q.expect = value; newe.Q.var = 0.001; } if (lastseen > (double) lsea) { Log(LOG_LEVEL_DEBUG, "Performance record '%s' expired", eventname); DeleteDB(dbp, eventname); } else { WriteDB(dbp, eventname, &newe, sizeof(newe)); if (TIMING) { Log(LOG_LEVEL_VERBOSE, "T: This measurement event, alias '%s', measured at time %s\n", eventname, ctime(&newe.t)); Log(LOG_LEVEL_VERBOSE, "T: Last measured %lf seconds ago\n", lastseen); Log(LOG_LEVEL_VERBOSE, "T: This execution measured %lf seconds\n", newe.Q.q); Log(LOG_LEVEL_VERBOSE, "T: Average execution time %lf +/- %lf seconds\n", newe.Q.expect, sqrt(newe.Q.var)); } } CloseDB(dbp); } cfengine-3.24.2/libpromises/cf-windows-functions.h0000644000000000000000000000617615010704253022154 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_WINDOWS_FUNCTIONS_H #define CFENGINE_WINDOWS_FUNCTIONS_H #include #ifdef __MINGW32__ /* win_api.c */ int NovaWin_chmod(const char *path, mode_t mode); /* win_file.c */ int NovaWin_rename(const char *oldpath, const char *newpath); bool NovaWin_FileExists(const char *fileName); bool NovaWin_IsDir(char *fileName); int NovaWin_TakeFileOwnership(char *path); int NovaWin_SetFileOwnership(char *path, SID *sid); off_t NovaWin_GetDiskUsage(char *file, CfSize type); /* win_log.c */ void OpenLog(int facility); void CloseLog(void); void LogToSystemLog(const char *msg, LogLevel level); /* win_proc.c */ int NovaWin_IsProcessRunning(pid_t pid); int NovaWin_GetCurrentProcessOwner(SID *sid, int sidSz); int NovaWin_SetTokenPrivilege(HANDLE token, char *privilegeName, int enablePriv); /* win_ps.c */ int NovaWin_GetProcessSnapshot(Item **procdata); int GatherProcessUsers(Item **userList, int *userListSz, int *numRootProcs, int *numOtherProcs); /* win_service_exec.c */ void NovaWin_StartExecService(void); /* win_sysinfo.c */ int NovaWin_GetWinDir(char *winDir, int winDirSz); int NovaWin_GetSysDir(char *sysDir, int sysDirSz); int NovaWin_GetProgDir(char *progDir, int progDirSz); int NovaWin_GetEnv(char *varName, char *varContents, int varContentsSz); /* win_user.c */ int NovaWin_UserNameToSid(char *userName, SID *sid, DWORD sidSz, int shouldExist); int NovaWin_GroupNameToSid(char *groupName, SID *sid, DWORD sidSz, int shouldExist); int NovaWin_NameToSid(char *name, SID *sid, DWORD sidSz); int NovaWin_SidToName(SID *sid, char *name, int nameSz); int NovaWin_StringToSid(char *stringSid, SID *sid, int sidSz); FnCallResult FnCallUserExists(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *finalargs); FnCallResult FnCallGroupExists(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *finalargs); /* win_wmi.c */ int NovaWin_PackageListInstalledFromAPI(EvalContext *ctx, PackageItem ** pkgList, const Attributes *a, Promise *pp); /* win_execd_pipe.c */ bool IsReadReady(int fd, int timeout_sec); /* win_common.c */ void InitializeWindows(void); #endif /* __MINGW32__ */ #endif // CFENGINE_WINDOWS_FUNCTIONS_H cfengine-3.24.2/libpromises/global_mutex.c0000644000000000000000000000326315010704253020535 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include static pthread_mutex_t MUTEXES[] = /* GLOBAL_T */ { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, }; pthread_mutex_t *cft_lock = &MUTEXES[0]; /* GLOBAL_T */ pthread_mutex_t *cft_count = &MUTEXES[1]; /* GLOBAL_T */ pthread_mutex_t *cft_getaddr = &MUTEXES[2]; /* GLOBAL_T */ pthread_mutex_t *cft_server_children = &MUTEXES[3]; /* GLOBAL_T */ pthread_mutex_t *cft_server_filter = &MUTEXES[4]; /* GLOBAL_T */ pthread_mutex_t *cft_db_corruption_lock = &MUTEXES[5]; /* GLOBAL_T */ cfengine-3.24.2/libpromises/rlist.h0000644000000000000000000001102215010704253017205 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_RLIST_H #define CFENGINE_RLIST_H #include #include #include #include /* NOTE: an empty Rlist is simply NULL. */ struct Rlist_ { Rval val; Rlist *next; }; RvalType DataTypeToRvalType(DataType datatype); bool RlistValueIsType(const Rlist *rlist, RvalType type); char *RvalScalarValue(Rval rval); FnCall *RvalFnCallValue(Rval rval); Rlist *RvalRlistValue(Rval rval); JsonElement *RvalContainerValue(Rval rval); const char *RvalTypeToString(RvalType type); Rval RvalNew(const void *item, RvalType type); /** * Get new secret Rval. * * @note RvalDestroy() not required to be called on the returned value. */ Rval RvalNewSecret(); Rval RvalNewRewriter(const void *item, RvalType type, JsonElement *map); Rval RvalCopy(Rval rval); Rval RvalCopyRewriter(Rval rval, JsonElement *map); void RvalDestroy(Rval rval); JsonElement *RvalToJson(Rval rval); char *RvalToString(Rval rval); char *RlistToString(const Rlist *rlist); void RvalWrite(Writer *writer, Rval rval); void RvalWriteQuoted(Writer *writer, Rval rval); void RvalWriteRaw(Writer *writer, Rval rval); unsigned RvalHash(Rval rval, unsigned seed); Rlist *RlistCopy(const Rlist *list); Rlist *RlistCopyRewriter(const Rlist *list, JsonElement *map); unsigned int RlistHash (const Rlist *list, unsigned seed); unsigned int RlistHash_untyped(const void *list, unsigned seed); void RlistDestroy (Rlist *list); void RlistDestroy_untyped(void *rl); void RlistDestroyEntry(Rlist **liststart, Rlist *entry); char *RlistScalarValue(const Rlist *rlist); char *RlistScalarValueSafe(const Rlist *rlist); FnCall *RlistFnCallValue(const Rlist *rlist); Rlist *RlistRlistValue(const Rlist *rlist); Rlist *RlistParseShown(const char *string); Rlist *RlistParseString(const char *string); Rlist *RlistKeyIn(Rlist *list, const char *key); int RlistLen(const Rlist *start); bool RlistMatchesRegexRlist(const Rlist *list, const Rlist *search); bool RlistMatchesRegex(const Rlist *list, const char *str); bool RlistIsInListOfRegex(const Rlist *list, const char *str); bool RlistIsNullList(const Rlist *list); bool RlistContainsString(const Rlist *list, const char *string); Rlist *RlistAppendRval(Rlist **start, Rval rval); Rlist *RlistPrependScalarIdemp(Rlist **start, const char *scalar); Rlist *RlistAppendScalarIdemp(Rlist **start, const char *scalar); Rlist *RlistAppendScalar(Rlist **start, const char *scalar); Rlist *RlistPrepend(Rlist **start, const void *item, RvalType type); Rlist *RlistAppend(Rlist **start, const void *item, RvalType type); Rlist *RlistAppendAllTypes(Rlist **start, const void *item, RvalType type, bool all_types); Rlist *RlistAppendString(Rlist **start, const char *string); Rlist *RlistFromSplitString(const char *string, char sep); Rlist *RlistFromStringSplitLines(const char *string, bool detect_crlf); Rlist *RlistFromSplitRegex(const char *string, const char *regex, size_t max_entries, bool allow_blanks); Rlist *RlistFromRegexSplitNoOverflow(const char *string, const char *regex, int max); Rlist *RlistFromContainer(const JsonElement *container); void RlistWrite(Writer *writer, const Rlist *list); Rlist *RlistLast(Rlist *start); void RlistFilter(Rlist **list, bool (*KeepPredicate)(void *item, void *predicate_data), void *predicate_user_data, void (*DestroyItem)(void *item)); void RlistReverse(Rlist **list); void ScalarWrite(Writer *w, const char *s, bool quote, bool raw); void RlistFlatten(EvalContext *ctx, Rlist **list); bool RlistEqual (const Rlist *list1, const Rlist *list2); bool RlistEqual_untyped(const void *list1, const void *list2); #endif cfengine-3.24.2/libpromises/cf3parse.h0000644000000000000000000000465715010704322017573 0ustar00rootroot00000000000000/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ #ifndef YY_YY_CF_PARSE_H_INCLUDED # define YY_YY_CF_PARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif /* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { IDENTIFIER = 258, QUOTED_STRING = 259, CLASS_GUARD = 260, PROMISE_GUARD = 261, BUNDLE = 262, BODY = 263, PROMISE = 264, FAT_ARROW = 265, THIN_ARROW = 266, NAKEDVAR = 267 }; #endif /* Tokens. */ #define IDENTIFIER 258 #define QUOTED_STRING 259 #define CLASS_GUARD 260 #define PROMISE_GUARD 261 #define BUNDLE 262 #define BODY 263 #define PROMISE 264 #define FAT_ARROW 265 #define THIN_ARROW 266 #define NAKEDVAR 267 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE yylval; int yyparse (void); #endif /* !YY_YY_CF_PARSE_H_INCLUDED */ cfengine-3.24.2/Makefile.am0000644000000000000000000001315615010704253015415 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # AUTOMAKE_OPTIONS = foreign MAKEFLAGS = $(if $(filter-out 0,$(V)),,--no-print-directory --quiet) LCOV_FLAGS = $(if $(filter-out 0,$(V)),,-q) SUBDIRS = \ libntech \ libcfecompat \ libcfnet \ libenv \ cf-check \ libpromises \ cf-agent \ cf-execd \ cf-key \ cf-monitord \ cf-promises \ cf-runagent \ cf-serverd \ cf-testd \ cf-upgrade \ cf-net \ cf-secret \ misc \ python \ ext \ examples \ tests \ contrib/vagrant-ci/centos-9s-x64 # Hide the buildsystem's username, at least with GNU tar. TAR_OPTIONS = --owner=0 --group=0 export TAR_OPTIONS EXTRA_DIST = ChangeLog INSTALL README.md LICENSE CFVERSION doc_DATA = README.md ChangeLog # # Some basic clean ups # MOSTLYCLEANFILES = *~ # # Get everything removed down to where rebuilding requires: # "configure; make; make install" # DISTCLEANFILES = # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.sub \ configure install-sh missing mkinstalldirs depcomp ylwrap \ ltmain.sh mdate-sh # # Pass proper flags to aclocal to pick up Libtool macros # ACLOCAL_AMFLAGS = -I m4 list: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' install-data-local: $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/inputs $(MKDIR_P) -m 755 $(DESTDIR)$(workdir)/modules $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/outputs $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/ppkeys $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/plugins $(MKDIR_P) -m 750 $(DESTDIR)$(workdir)/state tar-package: pkgdir=`mktemp -d` && export pkgdir && \ origdir=`pwd` && export origdir && \ $(MAKE) DESTDIR=$$pkgdir install && \ ( cd $$pkgdir && \ find . -name '*.cf*' | xargs -n1 chmod go-w && \ tardir=. && \ $(am__tar) | GZIP=$(GZIP_ENV) gzip -c \ > "$$origdir"/$(PACKAGE)-$(VERSION).pkg.tar.gz \ ) ; \ [ x$$pkgdir != x ] && rm -rf $$pkgdir # # Code coverage # clean-coverage: find -L $(srcdir) -name '*.gcda' -delete run-coverage: -$(MAKE) check -k collect-coverage: mkdir -p coverage $(LCOV) $(LCOV_FLAGS) --capture --initial --directory . --output-file coverage/cfengine-lcov-base.info $(LCOV) $(LCOV_FLAGS) --capture --directory . --output-file coverage/lcov.info --test-name CFENGINE --no-checksum --compat-libtool $(LCOV) $(LCOV_FLAGS) -a coverage/cfengine-lcov-base.info -a coverage/lcov.info --output-file coverage/cfengine-lcov.info $(LCOV) $(LCOV_FLAGS) --remove coverage/lcov.info '/usr/include/*' --output-file coverage/lcov.info LANG=C $(LCOV_GENHTML) $(LCOV_FLAGS) --prefix . --output-directory coverage-html --title "CFEngine Code Coverage" --legend --show-details coverage/lcov.info @echo @echo " Code coverage information: file://"`pwd`"/coverage-html/index.html" @echo " Code coverage summary for IDEs: file://"`pwd`"/coverage/lcov.info" @echo coverage: clean-coverage run-coverage collect-coverage ################################################################################ # Identical to what is in libpromises/Makefile.am. # This is because there is a circular dependency libcfnet <-> libpromises # so we need to generate it before everything else. ################################################################################ BUILT_SOURCES = \ $(srcdir)/libpromises/enterprise_extension.c \ $(srcdir)/libpromises/enterprise_extension.h $(srcdir)/libpromises/enterprise_extension.c: libpromises/extensions_template.c.pre libpromises/enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/libpromises/enterprise_extension.sed $< > $@ $(srcdir)/libpromises/enterprise_extension.h: libpromises/extensions_template.h.pre libpromises/enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/libpromises/enterprise_extension.sed $< > $@ V_PERL = $(cf__v_PERL_$(V)) cf__v_PERL_ = $(cf__v_PERL_$(AM_DEFAULT_VERBOSITY)) cf__v_PERL_0 = @echo " PERL " "$@"; cf__v_PERL_1 = V_SED = $(cf__v_SED_$(V)) cf__v_SED_ = $(cf__v_SED_$(AM_DEFAULT_VERBOSITY)) cf__v_SED_0 = @echo " SED " "$@"; cf__v_SED_1 = vm-check: $(MAKE) -C contrib/vagrant-ci/centos-9s-x64/ vm-check vm-check-full: $(MAKE) -C contrib/vagrant-ci/centos-9s-x64/ vm-check-full destroy-vms: $(MAKE) -C contrib/vagrant-ci/centos-9s-x64/ destroy-vms static-check: tests/static-check/run.sh static-check-f%: STATIC_CHECKS_FEDORA_VERSION=$* tests/static-check/run.sh # # Get everything removed down to where rebuilding requires: # "make; make install" # CLEANFILES = cfengine-lcov-base.info cfengine-lcov.info \ $(BUILT_SOURCES) cfengine-3.24.2/cf-promises/0000755000000000000000000000000015010704322015577 5ustar00rootroot00000000000000cfengine-3.24.2/cf-promises/Makefile.am0000644000000000000000000000320415010704253017635 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-promises.la AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libpromises \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ @CPPFLAGS@ \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) AM_LDFLAGS = \ @LDFLAGS@ libcf_promises_la_LIBADD = ../libpromises/libpromises.la libcf_promises_la_SOURCES = cf-promises.c if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-promises cf_promises_LDADD = libcf-promises.la cf_promises_SOURCES = endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-promises/cf-promises.c0000644000000000000000000004436215010704253020206 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* FILE_SEPARATOR */ #include #include /* CompileRegex */ #include #include #include static GenericAgentConfig *CheckOpts(int argc, char **argv); /*******************************************************************/ /* Command line options */ /*******************************************************************/ static const char *const CF_PROMISES_SHORT_DESCRIPTION = "validate and analyze CFEngine policy code"; static const char *const CF_PROMISES_MANPAGE_LONG_DESCRIPTION = "cf-promises is a tool for checking CFEngine policy code. " "It operates by first parsing policy code checing for syntax errors. Second, it validates the integrity of " "policy consisting of multiple files. Third, it checks for semantic errors, e.g. specific attribute set rules. " "Finally, cf-promises attempts to expose errors by partially evaluating the policy, resolving as many variable and " "classes promise statements as possible. At no point does cf-promises make any changes to the system."; static const Component COMPONENT = { .name = "cf-promises", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; /* Long-style only options, values must start above max ASCII value. */ enum { OPT_EVAL_FUNCTIONS = 256, OPT_SHOW_CLASSES, OPT_SHOW_VARS }; static const struct option OPTIONS[] = { {"workdir", required_argument, 0, 'w'}, {"eval-functions", optional_argument, 0, OPT_EVAL_FUNCTIONS }, {"show-classes", optional_argument, 0, OPT_SHOW_CLASSES }, {"show-vars", optional_argument, 0, OPT_SHOW_VARS }, {"help", no_argument, 0, 'h'}, {"bundlesequence", required_argument, 0, 'b'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"log-level", required_argument, 0, 'g'}, {"dry-run", no_argument, 0, 'n'}, {"version", no_argument, 0, 'V'}, {"file", required_argument, 0, 'f'}, {"define", required_argument, 0, 'D'}, {"negate", required_argument, 0, 'N'}, {"inform", no_argument, 0, 'I'}, {"diagnostic", no_argument, 0, 'x'}, {"policy-output-format", required_argument, 0, 'p'}, {"syntax-description", required_argument, 0, 's'}, {"full-check", no_argument, 0, 'c'}, {"warn", required_argument, 0, 'W'}, {"color", optional_argument, 0, 'C'}, {"tag-release", required_argument, 0, 'T'}, {"timestamp", no_argument, 0, 'l'}, /* Only long option for the rest */ {"ignore-preferred-augments", no_argument, 0, 0}, {"log-modules", required_argument, 0, 0}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Override the work directory for testing (same as setting CFENGINE_TEST_OVERRIDE_WORKDIR)", "Evaluate functions during syntax checking (may catch more run-time errors). Possible values: 'yes', 'no'. Default is 'yes'", "Show discovered classes, including those defined in common bundles in policy. Optionally can take a regular expression.", "Show discovered variables, including those defined without dependency to user-defined classes in policy. Optionally can take a regular expression.", "Print the help message", "Use the specified bundlesequence for verification", "Enable debugging output", "Output verbose information about the behaviour of cf-promises", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "All talk and no action mode - make no changes, only inform of promises not kept", "Output the version of the software", "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.", "Define a list of comma separated classes to be defined at the start of execution", "Define a list of comma separated classes to be undefined at the start of execution", "Print basic information about changes made to the system, i.e. promises repaired", "Activate internal diagnostics (developers only)", "Output the parsed policy. Possible values: 'none', 'cf', 'json' (this file only), 'cf-full', 'json-full' (all parsed promises). Default is 'none'. (experimental)", "Output a document describing the available syntax elements of CFEngine. Possible values: 'none', 'json'. Default is 'none'.", "Ensure full policy integrity checks", "Pass comma-separated |all to enable non-default warnings, or error=|all", "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", "Tag a directory with promises.cf with cf_promises_validated and cf_promises_release_id", "Log timestamps on each line of log output", "Ignore def_preferred.json file in favor of def.json", "Enable even more detailed debug logging for specific areas of the implementation. Use together with '-d'. Use --log-modules=help for a list of available modules", NULL }; /*******************************************************************/ /* Level 0 : Main */ /*******************************************************************/ int main(int argc, char *argv[]) { SetupSignalsForAgent(); GenericAgentConfig *config = CheckOpts(argc, argv); EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); const char *program_invocation_name = argv[0]; const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR); const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name); GenericAgentDiscoverContext(ctx, config, program_name); Policy *policy = LoadPolicy(ctx, config); if (!policy) { Log(LOG_LEVEL_ERR, "Input files contain errors."); DoCleanupAndExit(EXIT_FAILURE); } GenericAgentPostLoadInit(ctx); if (config->tag_release_dir != NULL) { // write the validated file and the release ID bool tagged = GenericAgentTagReleaseDirectory(config, config->tag_release_dir, true, true); if (tagged) { Log(LOG_LEVEL_VERBOSE, "Release tagging done!"); } else { Log(LOG_LEVEL_ERR, "The given directory could not be tagged, sorry."); DoCleanupAndExit(EXIT_FAILURE); } } const enum generic_agent_config_common_policy_output_format output_format = config->agent_specific.common.policy_output_format; switch (output_format) { case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF_FULL: { Writer *writer = FileWriter(stdout); PolicyToString(policy, writer); WriterClose(writer); break; } case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON_FULL: { Writer *writer = FileWriter(stdout); JsonElement *json_policy = PolicyToJson(policy); JsonWrite(writer, json_policy, 2); JsonDestroy(json_policy); WriterClose(writer); break; } case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF: case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON: { // If no file was provided, use 'promises.cf' by default if (config->input_file == NULL) { GenericAgentConfigSetInputFile(config, GetInputDir(), "promises.cf"); } Policy *output_policy = Cf3ParseFile(config, config->input_file); CF_ASSERT_FIX(output_policy != NULL, DoCleanupAndExit(EXIT_FAILURE), "File has already been parsed OK, but fails now!"); Writer *writer = FileWriter(stdout); if (output_format == GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF) { PolicyToString(output_policy, writer); } else { JsonElement *json_policy = PolicyToJson(output_policy); JsonWrite(writer, json_policy, 2); JsonDestroy(json_policy); } WriterClose(writer); PolicyDestroy(output_policy); break; } /* Avoids warnings. */ case GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE: break; } if (config->agent_specific.common.show_classes != NULL) { GenericAgentShowContextsFormatted(ctx, config->agent_specific.common.show_classes); free(config->agent_specific.common.show_classes); } if (config->agent_specific.common.show_variables != NULL) { GenericAgentShowVariablesFormatted(ctx, config->agent_specific.common.show_variables); free(config->agent_specific.common.show_variables); } PolicyDestroy(policy); GenericAgentFinalize(ctx, config); } /*******************************************************************/ /* Level 1 */ /*******************************************************************/ GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int c; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON, GetTTYInteractive()); int longopt_idx; while ((c = getopt_long(argc, argv, "dvnIw:f:g:D:N:VSrxMb:i:p:s:cg:hW:C::T:l", OPTIONS, &longopt_idx)) != -1) { switch (c) { case OPT_EVAL_FUNCTIONS: if (optarg == NULL) { optarg = "yes"; } config->agent_specific.common.eval_functions = strcmp("yes", optarg) == 0; break; case OPT_SHOW_CLASSES: if (optarg == NULL) { optarg = ".*"; } config->agent_specific.common.show_classes = xstrdup(optarg); break; case OPT_SHOW_VARS: if (optarg == NULL) { optarg = ".*"; } config->agent_specific.common.show_variables = xstrdup(optarg); break; case 'w': { Log(LOG_LEVEL_INFO, "Setting workdir to '%s'", optarg); char *str = StringConcatenate(2, "CFENGINE_TEST_OVERRIDE_WORKDIR=", optarg); putenv_wrapper(str); free(str); break; } case 'c': config->check_runnable = true; break; case 'f': GenericAgentConfigSetInputFile(config, GetInputDir(), optarg); MINUSF = true; break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'b': if (optarg) { Rlist *bundlesequence = RlistFromSplitString(optarg, ','); GenericAgentConfigSetBundleSequence(config, bundlesequence); RlistDestroy(bundlesequence); } break; case 'p': if (strcmp("none", optarg) == 0) { config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_NONE; } else if (strcmp("cf", optarg) == 0) { config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF; } else if (strcmp("json", optarg) == 0) { config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON; } else if (strcmp("cf-full", optarg) == 0) { config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_CF_FULL; } else if (strcmp("json-full", optarg) == 0) { config->agent_specific.common.policy_output_format = GENERIC_AGENT_CONFIG_COMMON_POLICY_OUTPUT_FORMAT_JSON_FULL; } else { Log(LOG_LEVEL_ERR, "Invalid policy output format: '%s'. Possible values are 'none', 'cf', 'json', 'cf-full', 'json-full'", optarg); DoCleanupAndExit(EXIT_FAILURE); } break; case 's': if (strcmp("none", optarg) == 0) { break; } else if (strcmp("json", optarg) == 0) { JsonElement *json_syntax = SyntaxToJson(); Writer *out = FileWriter(stdout); JsonWrite(out, json_syntax, 0); FileWriterDetach(out); JsonDestroy(json_syntax); DoCleanupAndExit(EXIT_SUCCESS); } else { Log(LOG_LEVEL_ERR, "Invalid syntax description output format: '%s'. Possible values are 'none', 'json'", optarg); DoCleanupAndExit(EXIT_FAILURE); } break; case 'K': config->ignore_locks = true; break; case 'D': { StringSet *defined_classes = StringSetFromString(optarg, ','); if (! config->heap_soft) { config->heap_soft = defined_classes; } else { StringSetJoin(config->heap_soft, defined_classes, xstrdup); StringSetDestroy(defined_classes); } } break; case 'N': { StringSet *negated_classes = StringSetFromString(optarg, ','); if (! config->heap_negated) { config->heap_negated = negated_classes; } else { StringSetJoin(config->heap_negated, negated_classes, xstrdup); StringSetDestroy(negated_classes); } } break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); break; case 'n': EVAL_MODE = EVAL_MODE_DRY_RUN; config->ignore_locks = true; break; case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'h': { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-promises", time(NULL), CF_PROMISES_SHORT_DESCRIPTION, CF_PROMISES_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(out); DoCleanupAndExit(EXIT_SUCCESS); } case 'r': Log(LOG_LEVEL_ERR, "Option '-r' has been deprecated"); DoCleanupAndExit(EXIT_FAILURE); break; case 'W': if (!GenericAgentConfigParseWarningOptions(config, optarg)) { Log(LOG_LEVEL_ERR, "Error parsing warning option"); DoCleanupAndExit(EXIT_FAILURE); } break; case 'x': Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired."); DoCleanupAndExit(EXIT_SUCCESS); case 'C': if (!GenericAgentConfigParseColor(config, optarg)) { DoCleanupAndExit(EXIT_FAILURE); } break; case 'T': GenericAgentConfigSetInputFile(config, optarg, "promises.cf"); MINUSF = true; config->tag_release_dir = xstrdup(optarg); break; case 'l': LoggingEnableTimestamps(true); break; /* long options only */ case 0: { const char *const option_name = OPTIONS[longopt_idx].name; if (StringEqual(option_name, "ignore-preferred-augments")) { config->ignore_preferred_augments = true; } else if (StringEqual(option_name, "log-modules")) { bool ret = LogEnableModulesFromString(optarg); if (!ret) { DoCleanupAndExit(EXIT_FAILURE); } } break; } default: { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_FAILURE); } } if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind)) { Log(LOG_LEVEL_ERR, "Too many arguments"); DoCleanupAndExit(EXIT_FAILURE); } CallCleanupFunctions(); return config; } cfengine-3.24.2/cf-promises/Makefile.in0000644000000000000000000006311515010704300017646 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-promises$(EXEEXT) subdir = cf-promises ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_promises_la_DEPENDENCIES = ../libpromises/libpromises.la am_libcf_promises_la_OBJECTS = cf-promises.lo libcf_promises_la_OBJECTS = $(am_libcf_promises_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_cf_promises_OBJECTS = cf_promises_OBJECTS = $(am_cf_promises_OBJECTS) @BUILTIN_EXTENSIONS_FALSE@cf_promises_DEPENDENCIES = \ @BUILTIN_EXTENSIONS_FALSE@ libcf-promises.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_promises_la_SOURCES) $(cf_promises_SOURCES) DIST_SOURCES = $(libcf_promises_la_SOURCES) $(cf_promises_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-promises.la AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libpromises \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ @CPPFLAGS@ \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) AM_LDFLAGS = \ @LDFLAGS@ libcf_promises_la_LIBADD = ../libpromises/libpromises.la libcf_promises_la_SOURCES = cf-promises.c @BUILTIN_EXTENSIONS_FALSE@cf_promises_LDADD = libcf-promises.la @BUILTIN_EXTENSIONS_FALSE@cf_promises_SOURCES = CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-promises/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-promises/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-promises.la: $(libcf_promises_la_OBJECTS) $(libcf_promises_la_DEPENDENCIES) $(EXTRA_libcf_promises_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_promises_la_OBJECTS) $(libcf_promises_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-promises$(EXEEXT): $(cf_promises_OBJECTS) $(cf_promises_DEPENDENCIES) $(EXTRA_cf_promises_DEPENDENCIES) @rm -f cf-promises$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_promises_OBJECTS) $(cf_promises_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-promises.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/contrib/0000755000000000000000000000000015010704323015011 5ustar00rootroot00000000000000cfengine-3.24.2/contrib/vagrant-ci/0000755000000000000000000000000015010704323017044 5ustar00rootroot00000000000000cfengine-3.24.2/contrib/vagrant-ci/centos-9s-x64/0000755000000000000000000000000015010704323021307 5ustar00rootroot00000000000000cfengine-3.24.2/contrib/vagrant-ci/centos-9s-x64/Makefile.am0000644000000000000000000000067315010704253023353 0ustar00rootroot00000000000000vm-check: vagrant up --no-provision no-deps-build && vagrant provision no-deps-build; \ echo "Destroy the VM by running 'make destroy-vms'" vm-check-full: vagrant up --no-provision full-build && vagrant provision full-build; \ echo "Destroy the VM by running 'make destroy-vms'" destroy-vms: -vagrant destroy no-deps-build -vagrant destroy full-build EXTRA_DIST = Vagrantfile Makefile.in MAINTAINERCLEANFILES = Makefile.in cfengine-3.24.2/contrib/vagrant-ci/centos-9s-x64/Makefile.in0000644000000000000000000004051515010704300023354 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = contrib/vagrant-ci/centos-9s-x64 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ EXTRA_DIST = Vagrantfile Makefile.in MAINTAINERCLEANFILES = Makefile.in all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/vagrant-ci/centos-9s-x64/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/vagrant-ci/centos-9s-x64/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile vm-check: vagrant up --no-provision no-deps-build && vagrant provision no-deps-build; \ echo "Destroy the VM by running 'make destroy-vms'" vm-check-full: vagrant up --no-provision full-build && vagrant provision full-build; \ echo "Destroy the VM by running 'make destroy-vms'" destroy-vms: -vagrant destroy no-deps-build -vagrant destroy full-build # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/contrib/vagrant-ci/centos-9s-x64/Vagrantfile0000644000000000000000000000666615010704253023514 0ustar00rootroot00000000000000# -*- mode: ruby -*- # vi: set ft=ruby : def os_cpu_cores case RbConfig::CONFIG['host_os'] when /darwin/ Integer(`sysctl -n hw.ncpu`) when /linux/ Integer(`cat /proc/cpuinfo | grep processor | wc -l`) else raise StandardError, "Unsupported platform" end end # All Vagrant configuration is done below. The "2" in Vagrant.configure # configures the configuration version (we support older styles for # backwards compatibility). Please don't change it unless you know what # you're doing. Vagrant.configure("2") do |config| config.vm.synced_folder "../../../", "/cfe/core", type: "rsync", rsync__args: ["--archive", "--links", "--delete"] config.vm.box = "generic/centos9s" config.vm.provider :libvirt do |lv| lv.cpus = os_cpu_cores lv.memory = 1024 lv.disk_driver :cache => 'unsafe' end # common provisioning config.vm.provision "shell", inline: <<-SHELL sed -ri '/-build/d' /etc/hosts dnf -q -y install epel-release dnf config-manager --set-enabled crb dnf -q -y install '@Development tools' pkgconfig pam-devel libtool libtool-ltdl dnf -q -y install 'perl(Sys::Hostname)' # needed for remake_outputs.pl dnf -q -y update SHELL no_deps_vm_name = "no-deps-build" full_vm_name = "full-build" # using system-provided dependencies config.vm.define no_deps_vm_name.to_sym, primary: true do |nd| nd.vm.hostname = no_deps_vm_name.to_sym nd.vm.provision "shell", inline: <<-SHELL set -e dnf -q -y install lmdb-devel pcre2-devel openssl-devel libyaml-devel libxml2-devel SHELL nd.vm.provision "shell", inline: <<-SHELL set -e shopt -s expand_aliases alias make='make -j -l#{os_cpu_cores}' cd /cfe/core make clean && make maintainer-clean ./autogen.sh -C --enable-debug make export UNSAFE_TESTS=1 export GAINROOT=sudo chmod -R go-w tests/acceptance make check SHELL end # doing a full build will the dependencies config.vm.define full_vm_name.to_sym, primary: false, autostart: false do |fd| fd.vm.hostname = full_vm_name.to_sym fd.vm.synced_folder "../../../../buildscripts", "/cfe/buildscripts", type: "rsync", rsync__args: ["--archive", "--links", "--delete"] fd.vm.synced_folder "../../../../masterfiles", "/cfe/masterfiles", type: "rsync", rsync__args: ["--archive", "--links", "--delete"] fd.vm.provision "shell", inline: <<-SHELL set -e dnf -q -y install 'perl(ExtUtils::MakeMaker)' 'perl(Digest::MD5)' 'perl(Module::Load::Conditional)' 'perl(IO::Uncompress::Gunzip)' 'perl(JSON::PP)' 'perl(IPC::Cmd)' \ ncurses-devel rpm-build dnf -q -y install psmisc # for fuser command dnf -q -y install wget SHELL fd.vm.provision "shell", inline: <<-SHELL shopt -s expand_aliases export MAKEFLAGS="-j -l#{os_cpu_cores}" alias make='make -j -l#{os_cpu_cores}' export BUILD_TYPE=DEBUG export NO_CONFIGURE=1 export PROJECT=community cd /cfe ./buildscripts/build-scripts/autogen yum -q -y remove libtool libtool-ltdl ./buildscripts/build-scripts/clean-buildmachine ./buildscripts/build-scripts/build-environment-check ./buildscripts/build-scripts/install-dependencies ./buildscripts/build-scripts/configure ./buildscripts/build-scripts/compile ./buildscripts/build-scripts/package rm -rf /var/cfengine export TEST_MACHINE=chroot ./buildscripts/build-scripts/clean-buildmachine ./buildscripts/build-scripts/build-environment-check ./buildscripts/build-scripts/install-dependencies ./buildscripts/build-scripts/test SHELL end end cfengine-3.24.2/configure0000755000000000000000000253744115010704277015310 0ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for cfengine 3.24.2. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='cfengine' PACKAGE_TARNAME='cfengine' PACKAGE_VERSION='3.24.2' PACKAGE_STRING='cfengine 3.24.2' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="libpromises/generic_agent.c" : "${AR_FLAGS=cr}" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_config_libobj_dir=libcfecompat ac_header_list= enable_option_checking=no ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS subdirs post_macros ENABLE_COVERAGE_FALSE ENABLE_COVERAGE_TRUE LCOV_GENHTML LCOV HOSTNAME PLATFORM_SELINUX_POLICIES WITH_SELINUX_FALSE WITH_SELINUX_TRUE SYSTEMD_SOCKET_LIBS SYSTEMD_SOCKET_LDFLAGS SYSTEMD_SOCKET_CFLAGS SYSTEMD_SOCKET_CPPFLAGS SYSTEMD_SOCKET_PATH OS_ENVIRONMENT_PATH WITH_SYSTEMD_SERVICE_FALSE WITH_SYSTEMD_SERVICE_TRUE SYSTEMD_SERVICE_PATH systemctl WITH_INIT_D_SCRIPT_FALSE WITH_INIT_D_SCRIPT_TRUE INIT_D_PATH statedir piddir logdir inputdir masterdir workdir XNU_FALSE XNU_TRUE NETBSD_FALSE NETBSD_TRUE HPUX_FALSE HPUX_TRUE AIX_FALSE AIX_TRUE CYGWIN_FALSE CYGWIN_TRUE NT_FALSE NT_TRUE SOLARIS_FALSE SOLARIS_TRUE MACOSX_FALSE MACOSX_TRUE LINUX_FALSE LINUX_TRUE FREEBSD_FALSE FREEBSD_TRUE CORE_LIBS CORE_LDFLAGS CORE_CFLAGS CORE_CPPFLAGS hw_cv_func_rename_proper hw_cv_func_stat_proper hw_cv_func_mkdir_proper hw_cv_func_ctime_proper HAVE_USERS_PROMISE_DEPS_FALSE HAVE_USERS_PROMISE_DEPS_TRUE PAM_LIBS PAM_LDFLAGS PAM_CFLAGS PAM_CPPFLAGS PAM_PATH GETLOADAVG_LIBS KMEM_GROUP NEED_SETGID LIBOBJS NO_SYSTEM_GETOPT_H_FALSE NO_SYSTEM_GETOPT_H_TRUE HAVE_AVAHI_COMMON_FALSE HAVE_AVAHI_COMMON_TRUE HAVE_AVAHI_CLIENT_FALSE HAVE_AVAHI_CLIENT_TRUE HAVE_LIBXML2_FALSE HAVE_LIBXML2_TRUE LIBXML2_LIBS LIBXML2_LDFLAGS LIBXML2_CFLAGS LIBXML2_CPPFLAGS LIBXML2_PATH XML2_CONFIG LIBYAML_LIBS LIBYAML_LDFLAGS LIBYAML_CFLAGS LIBYAML_CPPFLAGS LIBYAML_PATH HAVE_LIBCURL_FALSE HAVE_LIBCURL_TRUE LIBCURL_LIBS LIBCURL_LDFLAGS LIBCURL_CFLAGS LIBCURL_CPPFLAGS LIBCURL_PATH LIBACL_LIBS LIBACL_LDFLAGS LIBACL_CFLAGS LIBACL_CPPFLAGS LIBACL_PATH LIBVIRT_LIBS LIBVIRT_LDFLAGS LIBVIRT_CFLAGS LIBVIRT_CPPFLAGS LIBVIRT_PATH PCRE2_LIBS PCRE2_LDFLAGS PCRE2_CFLAGS PCRE2_CPPFLAGS PCRE2_PATH OPENSSL_LIBS OPENSSL_LDFLAGS OPENSSL_CFLAGS OPENSSL_CPPFLAGS OPENSSL_PATH LMDB_LIBS LMDB_LDFLAGS LMDB_CFLAGS LMDB_CPPFLAGS LMDB_PATH TOKYOCABINET_LIBS TOKYOCABINET_LDFLAGS TOKYOCABINET_CFLAGS TOKYOCABINET_CPPFLAGS TOKYOCABINET_PATH QDBM_LIBS QDBM_LDFLAGS QDBM_CFLAGS QDBM_CPPFLAGS QDBM_PATH MYSQL_LIBS MYSQL_LDFLAGS MYSQL_CFLAGS MYSQL_CPPFLAGS MYSQL_PATH POSTGRESQL_LIBS POSTGRESQL_LDFLAGS POSTGRESQL_CFLAGS POSTGRESQL_CPPFLAGS POSTGRESQL_PATH NDEBUG_FALSE NDEBUG_TRUE WINDOWS_FALSE WINDOWS_TRUE projlibdir enable_builtin_extensions BUILTIN_EXTENSIONS_FALSE BUILTIN_EXTENSIONS_TRUE PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC acx_pthread_config PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG CROSS_COMPILING_FALSE CROSS_COMPILING_TRUE GETCONF PERL YFLAGS YACC LEXLIB LEX_OUTPUT_ROOT LEX LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED LIBTOOL CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM MAKEINFO target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking enable_static enable_shared with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock with_pthreads enable_builtin_extensions enable_fhs enable_debug with_sql with_postgresql with_mysql with_qdbm with_tokyocabinet with_lmdb with_openssl with_pcre2 with_libvirt with_libacl with_libcurl with_libyaml with_libxml2 with_avahi enable_largefile with_pam enable_selinux with_workdir with_masterdir with_inputdir with_datadir with_logdir with_piddir with_statedir with_shell with_init_script with_systemd_service with_environment_path with_systemd_socket with_selinux_policy enable_coverage ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP LT_SYS_LIBRARY_PATH YACC YFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR' ac_subdirs_all='libntech' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures cfengine 3.24.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/cfengine] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of cfengine 3.24.2:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --disable-maintainer-mode disable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) Build binaries with builtin extensions --enable-fhs Enable FHS compliance. Defaults to custom CFEngine files layout --enable-debug Enable debugging --disable-largefile omit support for large files --enable-selinux Deprecated. SELinux support is always enabled --enable-coverage Enable code coverage Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-pthreads[=PATH] Specify path to pthreads, if not the part of operating system --with-sql[=PATH] Enable SQL database connectors (deprecated, use --with[[out]]-postgresql and --with[[out]]-mysql instead) --with-postgresql[=PATH] Enable PostgreSQL connector --with-mysql[=PATH] Enable MySQL connector --with-qdbm[=PATH] use QDBM to store runtime data --with-tokyocabinet[=PATH] use Tokyo Cabinet to store runtime data --with-lmdb[=PATH] use Lightning MDB to store runtime data --with-openssl[=PATH] Specify OpenSSL path --with-pcre2[=PATH] Specify PCRE2 path --with-libvirt[=PATH] support virtual machine management --with-libacl[=PATH] Specify libacl path --with-libcurl[=PATH] Specify libcurl path --with-libyaml[=PATH] Specify libyaml path --with-libxml2[=PATH] Specify libxml2 path --with-avahi[=yes/no/check] Compile with Avahi support [default=no] --with-pam Compile with PAM support --with-workdir=WORKDIR default for internal (trusted) working directory --with-masterdir=MASTERDIR default for internal masterfiles directory --with-inputdir=INPUTDIR default for internal inputs directory --with-datadir=DATADIR default for internal data directory --with-logdir=LOGDIR default for internal log directory --with-piddir=LOGDIR default for internal pid directory --with-statedir=STATEDIR default for internal state directory --with-shell=PATH Specify path to POSIX-compatible shell (if not /bin/sh) --with-init-script=PATH Install init.d script in given path. The default is no, but if specified, the default path is platform specific. --with-systemd-service=PATH Install systemd service file in given path. The default is no, but if specified, the default path is /usr/lib/systemd/system. --with-environment-path=PATH Specifies the location of the environment files for the platform. Currently used only by systemd. --with-systemd-socket[=PATH] support systemd socket activation --with-selinux-policy Whether to build and install SELinux policy (default: no) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor LT_SYS_LIBRARY_PATH User-defined run-time library search path. YACC The `Yet Another Compiler Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. PKG_CONFIG path to pkg-config PKG_CONFIG_PATH directories to add to the pkg-config search path PKG_CONFIG_LIBDIR path overriding pkg-config's search path Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF cfengine configure 3.24.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by cfengine $as_me 3.24.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi as_fn_append ac_header_list " sys/sysmacros.h" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- # Extract the first word of "makeinfo", so it can be a program name with args. set dummy makeinfo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MAKEINFO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MAKEINFO"; then ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MAKEINFO="makeinfo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MAKEINFO=$ac_cv_prog_MAKEINFO if test -n "$MAKEINFO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINFO" >&5 $as_echo "$MAKEINFO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking automake version" >&5 $as_echo_n "checking automake version... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: 1.15" >&5 $as_echo "1.15" >&6; } am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='cfengine' VERSION='3.24.2' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar plaintar pax cpio none' # The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether UID '$am_uid' is supported by ustar format" >&5 $as_echo_n "checking whether UID '$am_uid' is supported by ustar format... " >&6; } if test $am_uid -le $am_max_uid; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } _am_tools=none fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GID '$am_gid' is supported by ustar format" >&5 $as_echo_n "checking whether GID '$am_gid' is supported by ustar format... " >&6; } if test $am_gid -le $am_max_gid; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } _am_tools=none fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5 $as_echo_n "checking how to create a ustar tar archive... " >&6; } # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_ustar-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do { echo "$as_me:$LINENO: $_am_tar --version" >&5 ($_am_tar --version) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && break done # Work around CFEngine redmine #6925 by using --hard-dereference. { echo "$as_me:$LINENO: $_am_tar --hard-dereference 2>&1 | grep 'unrecognized option'" >&5 ($_am_tar --hard-dereference 2>&1 | grep 'unrecognized option') >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } # Check if --hard-dereference is supported by this version of GNU Tar if test "$ac_status" -eq 0; then _am_gnutar_hard_dereference=false am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"' am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"' else _am_gnutar_hard_dereference=true am__tar="$_am_tar --format=ustar --hard-dereference -chf - "'"$$tardir"' am__tar_="$_am_tar --format=ustar --hard-dereference -chf - "'"$tardir"' fi am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x ustar -w "$$tardir"' am__tar_='pax -L -x ustar -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H ustar -L' am__tar_='find "$tardir" -print | cpio -o -H ustar -L' am__untar='cpio -i -H ustar -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_ustar}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -rf conftest.dir if test -s conftest.tar; then { echo "$as_me:$LINENO: $am__untar &5 ($am__untar &5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: cat conftest.dir/file" >&5 (cat conftest.dir/file) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir if ${am_cv_prog_tar_ustar+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_prog_tar_ustar=$_am_tool fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5 $as_echo "$am_cv_prog_tar_ustar" >&6; } if test $_am_tool = gnutar; then # We've checked already, so we're just printing here { $as_echo "$as_me:${as_lineno-$LINENO}: checking if GNU tar supports --hard-dereference" >&5 $as_echo_n "checking if GNU tar supports --hard-dereference... " >&6; } if test x$_am_gnutar_hard_dereference = xtrue; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE cfengine_version=3.24.2 if test -n "$RELEASE"; then : cat >>confdefs.h <<_ACEOF #define RELEASE "$RELEASE" _ACEOF else $as_echo "#define RELEASE \"1\"" >>confdefs.h fi $as_echo "#define BUILD_YEAR 2025" >>confdefs.h $as_echo "#define CF_WEBSITE \"https://cfengine.com\"" >>confdefs.h $as_echo "#define CF_COPYRIGHT \"2023 Northern.tech AS\"" >>confdefs.h cat >>confdefs.h <<_ACEOF #define ABS_TOP_SRCDIR "`cd -- "$srcdir"; pwd`" _ACEOF # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' ac_config_headers="$ac_config_headers config.h" ENV_CFLAGS="$CFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined __HP_cc #This is HP-UX ANSI C #endif _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : HP_UX_AC="no" else CFLAGS="$CFLAGS -Agcc" CPPFLAGS="$CPPFLAGS -Agcc" HP_UX_AC="yes" fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HP-UX aC" >&5 $as_echo_n "checking for HP-UX aC... " >&6; } if test "x$HP_UX_AC" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC specific compile flags" >&5 $as_echo_n "checking for GCC specific compile flags... " >&6; } if test x"$GCC" = "xyes" && test x"$HP_UX_AC" != x"yes"; then CFLAGS="$CFLAGS -g -Wall" CPPFLAGS="$CPPFLAGS -std=gnu99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-pointer-sign" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wno-pointer-sign" >&5 $as_echo_n "checking for -Wno-pointer-sign... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror=implicit-function-declaration" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Werror=implicit-function-declaration" >&5 $as_echo_n "checking for -Werror=implicit-function-declaration... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wunused-parameter" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wunused-parameter" >&5 $as_echo_n "checking for -Wunused-parameter... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wno-duplicate-decl-specifier" >&5 $as_echo_n "checking for -Wno-duplicate-decl-specifier... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __clang__ # error Not a clang #endif int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$save_CFLAGS -Wno-duplicate-decl-specifier" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Use either new LT_INIT or old AC_DISABLE_STATIC/AC_PROG_LIBTOOL macros case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=no fi enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ yyless ((input () != 0)); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi if test "$LEX" = :; then LEX=${am_missing_run}flex fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi CFECOMPAT_CPPFLAGS="-I$srcdir/libcfecompat" # Extract the first word of "getconf", so it can be a program name with args. set dummy getconf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GETCONF+:} false; then : $as_echo_n "(cached) " >&6 else case $GETCONF in [\\/]* | ?:[\\/]*) ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$PATH:$prefix/bin:/usr/bin:/usr/local/bin:/sw/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GETCONF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GETCONF" && ac_cv_path_GETCONF="false" ;; esac fi GETCONF=$ac_cv_path_GETCONF if test -n "$GETCONF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GETCONF" >&5 $as_echo "$GETCONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$cross_compiling" = "xyes"; then CROSS_COMPILING_TRUE= CROSS_COMPILING_FALSE='#' else CROSS_COMPILING_TRUE='#' CROSS_COMPILING_FALSE= fi # Check whether `pkg-config' is available if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi # Check whether --with-pthreads was given. if test "${with_pthreads+set}" = set; then : withval=$with_pthreads; fi if test "x$with_pthreads" != x && test "x$with_pthreads" != "xyes" && test "x$with_pthreads" != "xno"; then LIBS="$LIBS -L$with_pthreads/lib" CPPFLAGS="-I$with_pthreads/include $CPPFLAGS" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 $as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_join (); int main () { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : acx_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 $as_echo "$acx_pthread_ok" >&6; } if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt -mthreads pthread --thread-safe pthread-config pthreadGC2" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 $as_echo_n "checking whether pthreads work without any flags... " >&6; } ;; -*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 $as_echo_n "checking whether pthreads work with $flag... " >&6; } PTHREAD_CFLAGS="$flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_acx_pthread_config+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$acx_pthread_config"; then ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_acx_pthread_config="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no" fi fi acx_pthread_config=$ac_cv_prog_acx_pthread_config if test -n "$acx_pthread_config"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5 $as_echo "$acx_pthread_config" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 $as_echo_n "checking for the pthreads library -l$flag... " >&6; } PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : acx_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 $as_echo "$acx_pthread_ok" >&6; } if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 $as_echo_n "checking for joinable pthread attribute... " >&6; } attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int attr=$attr; return attr; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : attr_name=$attr; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 $as_echo "$attr_name" >&6; } if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then cat >>confdefs.h <<_ACEOF #define PTHREAD_CREATE_JOINABLE $attr_name _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 $as_echo_n "checking if more special flags are required for pthreads... " >&6; } flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 $as_echo "${flag}" >&6; } if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then for ac_prog in xlc_r cc_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PTHREAD_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 $as_echo "$PTHREAD_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h : else acx_pthread_ok=no as_fn_error $? "pthread-compatible library is required to build CFEngine" "$LINENO" 5 fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$PTHREAD_CC" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check whether --enable-builtin-extensions was given. if test "${enable_builtin_extensions+set}" = set; then : enableval=$enable_builtin_extensions; else case ${target_os} in #( mingw*) : enable_builtin_extensions=yes ;; #( *) : enable_builtin_extensions=no ;; esac fi if test "x$enable_builtin_extensions" = "xyes"; then BUILTIN_EXTENSIONS_TRUE= BUILTIN_EXTENSIONS_FALSE='#' else BUILTIN_EXTENSIONS_TRUE='#' BUILTIN_EXTENSIONS_FALSE= fi if test "x$enable_builtin_extensions" = "xyes"; then : $as_echo "#define BUILTIN_EXTENSIONS 1" >>confdefs.h fi # Check whether --enable-fhs was given. if test "${enable_fhs+set}" = set; then : enableval=$enable_fhs; fi # # pkglibdir/pkgdatadir are not overridable, so use our own invention instead. # if test x"$enable_fhs" = xyes; then : projlibdir='${pkglibdir}' WORKDIR='${localstatedir}/lib/${PACKAGE}' MASTERDIR='default' INPUTDIR='default' DATADIR='default' LOGDIR='${localstatedir}/log/${PACKAGE}' PIDDIR='${runstatedir:-${localstatedir}/run}/${PACKAGE}' STATEDIR='default' else if test x"$prefix" = xNONE || test x"$prefix" = x/var/cfengine; then prefix=/var/cfengine case "$target_os" in mingw*) WORKDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') PIDDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') STATEDIR=default ;; *) WORKDIR=/var/cfengine MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=/var/cfengine PIDDIR=/var/cfengine STATEDIR=default ;; esac else WORKDIR="${localstatedir}/${PACKAGE}" MASTERDIR="default" INPUTDIR="default" DATADIR="default" LOGDIR="${localstatedir}/${PACKAGE}" PIDDIR="${localstatedir}/${PACKAGE}" STATEDIR="default" fi bindir="${bindir:-${exec_prefix}/bin}" projlibdir='${libdir}' fi case ${target_os} in #( mingw*) : # Disable printf format warnings, because our wrapper supports more # flags than vanilla Windows version, so they are false positives. CFLAGS="$CFLAGS -Wno-format" ;; #( *) : ;; esac case ${target_os} in #( mingw*) : if true; then WINDOWS_TRUE= WINDOWS_FALSE='#' else WINDOWS_TRUE='#' WINDOWS_FALSE= fi ;; #( *) : if false; then WINDOWS_TRUE= WINDOWS_FALSE='#' else WINDOWS_TRUE='#' WINDOWS_FALSE= fi ;; esac # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; debug=$enableval else debug=no fi if test x"$debug" = x"no"; then NDEBUG_TRUE= NDEBUG_FALSE='#' else NDEBUG_TRUE='#' NDEBUG_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for debug option" >&5 $as_echo_n "checking for debug option... " >&6; } if test x"$debug" = x"yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$CFLAGS -g3 -O0 $ENV_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$CFLAGS -O2 -DNDEBUG $ENV_CFLAGS" fi # TODO remove # Check whether --with-sql was given. if test "${with_sql+set}" = set; then : withval=$with_sql; with_postgresql=$with_sql; with_mysql=$with_sql fi # Check whether --with-postgresql was given. if test "${with_postgresql+set}" = set; then : withval=$with_postgresql; else with_postgresql=check fi if test "x$with_postgresql" != "xno" then if test "x$with_postgresql" != xyes && test "x$with_postgresql" != xcheck then PG_CONFIG=$with_postgresql/bin/pg_config else PG_CONFIG=pg_config fi # pg_config is only for native builds if test "x$cross_compiling" = "xno" then if test x`which $PG_CONFIG` != x then pg_include_dir=`$PG_CONFIG --includedir` if test -n "$pg_include_dir" then POSTGRESQL_CPPFLAGS="-I$pg_include_dir" fi fi fi # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_postgresql" != xyes && test "x$with_postgresql" != xcheck && test "x$with_postgresql" != x then test -z "$POSTGRESQL_PATH" && POSTGRESQL_PATH="$with_postgresql" if test "x$with_postgresql" != x/usr && test "x$with_postgresql" != x/ then test -z "$POSTGRESQL_CFLAGS" && POSTGRESQL_CFLAGS="" test -z "$POSTGRESQL_CPPFLAGS" && POSTGRESQL_CPPFLAGS="-I$with_postgresql/include" test -z "$POSTGRESQL_LDFLAGS" && POSTGRESQL_LDFLAGS="-L$with_postgresql/lib" fi else POSTGRESQL_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $POSTGRESQL_CFLAGS" CPPFLAGS="$CPPFLAGS $POSTGRESQL_CPPFLAGS" LDFLAGS="$LDFLAGS $POSTGRESQL_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQconnectdb in -lpq" >&5 $as_echo_n "checking for PQconnectdb in -lpq... " >&6; } if ${ac_cv_lib_pq_PQconnectdb+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpq $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char PQconnectdb (); int main () { return PQconnectdb (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pq_PQconnectdb=yes else ac_cv_lib_pq_PQconnectdb=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQconnectdb" >&5 $as_echo "$ac_cv_lib_pq_PQconnectdb" >&6; } if test "x$ac_cv_lib_pq_PQconnectdb" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPQ 1 _ACEOF LIBS="-lpq $LIBS" else if test "x$with_postgresql" != xcheck; then as_fn_error $? "Cannot find PostgreSQL client library" "$LINENO" 5; fi fi for ac_header in libpq-fe.h do : ac_fn_c_check_header_mongrel "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default" if test "x$ac_cv_header_libpq_fe_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPQ_FE_H 1 _ACEOF else if test "x$with_postgresql" != xcheck; then as_fn_error $? "Cannot find PostgreSQL client library" "$LINENO" 5; fi fi done # # Pick up any libraries added by tests # test -z "$POSTGRESQL_LIBS" && POSTGRESQL_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_postgresql" != xyes && test "x$with_postgresql" != xcheck && test "x$with_postgresql" != x/usr && test "x$with_postgresql" != x/ then POSTGRESQL_LDFLAGS="$POSTGRESQL_LDFLAGS -R$with_postgresql/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-mysql was given. if test "${with_mysql+set}" = set; then : withval=$with_mysql; else with_mysql=check fi if test "x$with_mysql" != "xno" then if test "x$with_mysql" != xyes && test "x$with_mysql" != xcheck then MYSQL_CONFIG=$with_mysql/bin/mysql_config else MYSQL_CONFIG=mysql_config fi # mysql_config is only for native builds if test "x$cross_compiling" = "xno" then if test x`which $MYSQL_CONFIG` != x then mysql_include_dir=`$MYSQL_CONFIG --include` if test -n "$mysql_include_dir" then MYSQL_CPPFLAGS="$mysql_include_dir" fi fi fi # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_mysql" != xyes && test "x$with_mysql" != xcheck && test "x$with_mysql" != x then test -z "$MYSQL_PATH" && MYSQL_PATH="$with_mysql" if test "x$with_mysql" != x/usr && test "x$with_mysql" != x/ then test -z "$MYSQL_CFLAGS" && MYSQL_CFLAGS="" test -z "$MYSQL_CPPFLAGS" && MYSQL_CPPFLAGS="-I$with_mysql/include" test -z "$MYSQL_LDFLAGS" && MYSQL_LDFLAGS="-L$with_mysql/lib" fi else MYSQL_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $MYSQL_CFLAGS" CPPFLAGS="$CPPFLAGS $MYSQL_CPPFLAGS" LDFLAGS="$LDFLAGS $MYSQL_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mysql_real_connect in -lmysqlclient" >&5 $as_echo_n "checking for mysql_real_connect in -lmysqlclient... " >&6; } if ${ac_cv_lib_mysqlclient_mysql_real_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mysql_real_connect (); int main () { return mysql_real_connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_mysqlclient_mysql_real_connect=yes else ac_cv_lib_mysqlclient_mysql_real_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_mysql_real_connect" >&5 $as_echo "$ac_cv_lib_mysqlclient_mysql_real_connect" >&6; } if test "x$ac_cv_lib_mysqlclient_mysql_real_connect" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBMYSQLCLIENT 1 _ACEOF LIBS="-lmysqlclient $LIBS" else if test "x$with_mysql" != xcheck; then as_fn_error $? "Cannot find MySQL client library" "$LINENO" 5; fi fi for ac_header in mysql.h do : ac_fn_c_check_header_mongrel "$LINENO" "mysql.h" "ac_cv_header_mysql_h" "$ac_includes_default" if test "x$ac_cv_header_mysql_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MYSQL_H 1 _ACEOF else if test "x$with_mysql" != xcheck; then as_fn_error $? "Cannot find MySQL clientlibrary" "$LINENO" 5; fi fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_init in -lmysqlclient" >&5 $as_echo_n "checking for EVP_CIPHER_CTX_init in -lmysqlclient... " >&6; } if ${ac_cv_lib_mysqlclient_EVP_CIPHER_CTX_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmysqlclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char EVP_CIPHER_CTX_init (); int main () { return EVP_CIPHER_CTX_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_mysqlclient_EVP_CIPHER_CTX_init=yes else ac_cv_lib_mysqlclient_EVP_CIPHER_CTX_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mysqlclient_EVP_CIPHER_CTX_init" >&5 $as_echo "$ac_cv_lib_mysqlclient_EVP_CIPHER_CTX_init" >&6; } if test "x$ac_cv_lib_mysqlclient_EVP_CIPHER_CTX_init" = xyes; then : as_fn_error $? "MySQL client library exports symbols clashing \ with OpenSSL. Get the update from distribution provider, \ recompile MySQL library or disable MySQL connector. See \ http://bugs.mysql.com/bug.php?id=65055 for details." "$LINENO" 5 fi # # Pick up any libraries added by tests # test -z "$MYSQL_LIBS" && MYSQL_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_mysql" != xyes && test "x$with_mysql" != xcheck && test "x$with_mysql" != x/usr && test "x$with_mysql" != x/ then MYSQL_LDFLAGS="$MYSQL_LDFLAGS -R$with_mysql/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-qdbm was given. if test "${with_qdbm+set}" = set; then : withval=$with_qdbm; fi if test -n "$with_qdbm" && test "x$with_qdbm" != "xno"; then : WITH_QDBM=1 else WITH_QDBM=0 fi if test $WITH_QDBM = 1; then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_qdbm" != xyes && test "x$with_qdbm" != xcheck && test "x$with_qdbm" != x then test -z "$QDBM_PATH" && QDBM_PATH="$with_qdbm" if test "x$with_qdbm" != x/usr && test "x$with_qdbm" != x/ then test -z "$QDBM_CFLAGS" && QDBM_CFLAGS="" test -z "$QDBM_CPPFLAGS" && QDBM_CPPFLAGS="-I$with_qdbm/include" test -z "$QDBM_LDFLAGS" && QDBM_LDFLAGS="-L$with_qdbm/lib" fi else QDBM_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $QDBM_CFLAGS" CPPFLAGS="$CPPFLAGS $QDBM_CPPFLAGS" LDFLAGS="$LDFLAGS $QDBM_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dpopen in -lqdbm" >&5 $as_echo_n "checking for dpopen in -lqdbm... " >&6; } if ${ac_cv_lib_qdbm_dpopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lqdbm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dpopen (); int main () { return dpopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_qdbm_dpopen=yes else ac_cv_lib_qdbm_dpopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_qdbm_dpopen" >&5 $as_echo "$ac_cv_lib_qdbm_dpopen" >&6; } if test "x$ac_cv_lib_qdbm_dpopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBQDBM 1 _ACEOF LIBS="-lqdbm $LIBS" else as_fn_error $? "Cannot find QDBM" "$LINENO" 5 fi for ac_header in qdbm/depot.h do : ac_fn_c_check_header_mongrel "$LINENO" "qdbm/depot.h" "ac_cv_header_qdbm_depot_h" "$ac_includes_default" if test "x$ac_cv_header_qdbm_depot_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_QDBM_DEPOT_H 1 _ACEOF else as_fn_error $? "Cannot find QDBM" "$LINENO" 5 fi done $as_echo "#define QDB 1" >>confdefs.h # # Pick up any libraries added by tests # test -z "$QDBM_LIBS" && QDBM_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_qdbm" != xyes && test "x$with_qdbm" != xcheck && test "x$with_qdbm" != x/usr && test "x$with_qdbm" != x/ then QDBM_LDFLAGS="$QDBM_LDFLAGS -R$with_qdbm/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-tokyocabinet was given. if test "${with_tokyocabinet+set}" = set; then : withval=$with_tokyocabinet; fi if test $WITH_QDBM -eq 0 && test -n "$with_tokyocabinet" && test "x$with_tokyocabinet" != "xno"; then : WITH_TOKYO=1 else WITH_TOKYO=0 fi if test $WITH_TOKYO = 1; then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_tokyocabinet" != xyes && test "x$with_tokyocabinet" != xcheck && test "x$with_tokyocabinet" != x then test -z "$TOKYOCABINET_PATH" && TOKYOCABINET_PATH="$with_tokyocabinet" if test "x$with_tokyocabinet" != x/usr && test "x$with_tokyocabinet" != x/ then test -z "$TOKYOCABINET_CFLAGS" && TOKYOCABINET_CFLAGS="" test -z "$TOKYOCABINET_CPPFLAGS" && TOKYOCABINET_CPPFLAGS="-I$with_tokyocabinet/include" test -z "$TOKYOCABINET_LDFLAGS" && TOKYOCABINET_LDFLAGS="-L$with_tokyocabinet/lib" fi else TOKYOCABINET_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $TOKYOCABINET_CFLAGS" CPPFLAGS="$CPPFLAGS $TOKYOCABINET_CPPFLAGS" LDFLAGS="$LDFLAGS $TOKYOCABINET_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tchdbnew in -ltokyocabinet" >&5 $as_echo_n "checking for tchdbnew in -ltokyocabinet... " >&6; } if ${ac_cv_lib_tokyocabinet_tchdbnew+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltokyocabinet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tchdbnew (); int main () { return tchdbnew (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_tokyocabinet_tchdbnew=yes else ac_cv_lib_tokyocabinet_tchdbnew=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tokyocabinet_tchdbnew" >&5 $as_echo "$ac_cv_lib_tokyocabinet_tchdbnew" >&6; } if test "x$ac_cv_lib_tokyocabinet_tchdbnew" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBTOKYOCABINET 1 _ACEOF LIBS="-ltokyocabinet $LIBS" else as_fn_error $? "Cannot find Tokyo Cabinet" "$LINENO" 5 fi for ac_header in tcutil.h do : ac_fn_c_check_header_mongrel "$LINENO" "tcutil.h" "ac_cv_header_tcutil_h" "$ac_includes_default" if test "x$ac_cv_header_tcutil_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TCUTIL_H 1 _ACEOF else as_fn_error $? "Cannot find Tokyo Cabinet" "$LINENO" 5 fi done for ac_header in tchdb.h do : ac_fn_c_check_header_mongrel "$LINENO" "tchdb.h" "ac_cv_header_tchdb_h" "$ac_includes_default" if test "x$ac_cv_header_tchdb_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TCHDB_H 1 _ACEOF else as_fn_error $? "Cannot find Tokyo Cabinet" "$LINENO" 5 fi done $as_echo "#define TCDB 1" >>confdefs.h # # Pick up any libraries added by tests # test -z "$TOKYOCABINET_LIBS" && TOKYOCABINET_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_tokyocabinet" != xyes && test "x$with_tokyocabinet" != xcheck && test "x$with_tokyocabinet" != x/usr && test "x$with_tokyocabinet" != x/ then TOKYOCABINET_LDFLAGS="$TOKYOCABINET_LDFLAGS -R$with_tokyocabinet/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-lmdb was given. if test "${with_lmdb+set}" = set; then : withval=$with_lmdb; fi if test $WITH_TOKYO -eq 0 && test $WITH_QDBM -eq 0 && (! test -n "$with_lmdb" || test "x$with_lmdb" != "xno"); then : WITH_LMDB=1 else WITH_LMDB=0 fi if test $WITH_LMDB = 1; then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_lmdb" != xyes && test "x$with_lmdb" != xcheck && test "x$with_lmdb" != x then test -z "$LMDB_PATH" && LMDB_PATH="$with_lmdb" if test "x$with_lmdb" != x/usr && test "x$with_lmdb" != x/ then test -z "$LMDB_CFLAGS" && LMDB_CFLAGS="" test -z "$LMDB_CPPFLAGS" && LMDB_CPPFLAGS="-I$with_lmdb/include" test -z "$LMDB_LDFLAGS" && LMDB_LDFLAGS="-L$with_lmdb/lib" fi else LMDB_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $LMDB_CFLAGS" CPPFLAGS="$CPPFLAGS $LMDB_CPPFLAGS" LDFLAGS="$LDFLAGS $LMDB_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mdb_dbi_open in -llmdb" >&5 $as_echo_n "checking for mdb_dbi_open in -llmdb... " >&6; } if ${ac_cv_lib_lmdb_mdb_dbi_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llmdb $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mdb_dbi_open (); int main () { return mdb_dbi_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lmdb_mdb_dbi_open=yes else ac_cv_lib_lmdb_mdb_dbi_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lmdb_mdb_dbi_open" >&5 $as_echo "$ac_cv_lib_lmdb_mdb_dbi_open" >&6; } if test "x$ac_cv_lib_lmdb_mdb_dbi_open" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBLMDB 1 _ACEOF LIBS="-llmdb $LIBS" else as_fn_error $? "Cannot find Lightning MDB" "$LINENO" 5 fi for ac_header in lmdb.h do : ac_fn_c_check_header_mongrel "$LINENO" "lmdb.h" "ac_cv_header_lmdb_h" "$ac_includes_default" if test "x$ac_cv_header_lmdb_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LMDB_H 1 _ACEOF else as_fn_error $? "Cannot find Lightning MDB" "$LINENO" 5 fi done $as_echo "#define LMDB 1" >>confdefs.h # # Pick up any libraries added by tests # test -z "$LMDB_LIBS" && LMDB_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_lmdb" != xyes && test "x$with_lmdb" != xcheck && test "x$with_lmdb" != x/usr && test "x$with_lmdb" != x/ then LMDB_LDFLAGS="$LMDB_LDFLAGS -R$with_lmdb/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test $WITH_QDBM -eq 0 && test $WITH_TOKYO -eq 0 && test $WITH_LMDB -eq 0; then as_fn_error LMDB "Either Tokyo Cabinet" "$LINENO" 5 fi # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then : withval=$with_openssl; else with_openssl=yes fi if test x"$with_openssl" = xno ; then as_fn_error $? "This release of CFEngine requires OpenSSL >= 0.9.7" "$LINENO" 5 fi if test -d /usr/local/Cellar/ && \ test -d /usr/local/opt/openssl/ && \ test "x$with_openssl" = "xyes" ; then with_openssl=$(brew --prefix openssl) echo "OS X Homebrew detected" echo "Defaulting to: --with-openssl=$with_openssl" fi # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_openssl" != xyes && test "x$with_openssl" != xcheck && test "x$with_openssl" != x then test -z "$OPENSSL_PATH" && OPENSSL_PATH="$with_openssl" if test "x$with_openssl" != x/usr && test "x$with_openssl" != x/ then test -z "$OPENSSL_CFLAGS" && OPENSSL_CFLAGS="" test -z "$OPENSSL_CPPFLAGS" && OPENSSL_CPPFLAGS="-I$with_openssl/include" test -z "$OPENSSL_LDFLAGS" && OPENSSL_LDFLAGS="-L$with_openssl/lib" fi else OPENSSL_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $OPENSSL_CFLAGS" CPPFLAGS="$CPPFLAGS $OPENSSL_CPPFLAGS" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RSA_generate_key_ex in -lcrypto" >&5 $as_echo_n "checking for RSA_generate_key_ex in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_RSA_generate_key_ex+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char RSA_generate_key_ex (); int main () { return RSA_generate_key_ex (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_RSA_generate_key_ex=yes else ac_cv_lib_crypto_RSA_generate_key_ex=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RSA_generate_key_ex" >&5 $as_echo "$ac_cv_lib_crypto_RSA_generate_key_ex" >&6; } if test "x$ac_cv_lib_crypto_RSA_generate_key_ex" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPTO 1 _ACEOF LIBS="-lcrypto $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_free in -lssl" >&5 $as_echo_n "checking for SSL_free in -lssl... " >&6; } if ${ac_cv_lib_ssl_SSL_free+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSL_free (); int main () { return SSL_free (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ssl_SSL_free=yes else ac_cv_lib_ssl_SSL_free=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_free" >&5 $as_echo "$ac_cv_lib_ssl_SSL_free" >&6; } if test "x$ac_cv_lib_ssl_SSL_free" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" fi ac_fn_c_check_decl "$LINENO" "SSL_CTX_clear_options" "ac_cv_have_decl_SSL_CTX_clear_options" "#include " if test "x$ac_cv_have_decl_SSL_CTX_clear_options" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SSL_CTX_CLEAR_OPTIONS $ac_have_decl _ACEOF for ac_header in openssl/opensslv.h do : ac_fn_c_check_header_mongrel "$LINENO" "openssl/opensslv.h" "ac_cv_header_openssl_opensslv_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_opensslv_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_OPENSSLV_H 1 _ACEOF else as_fn_error $? "Cannot find OpenSSL" "$LINENO" 5 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL version" >&5 $as_echo_n "checking for OpenSSL version... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if OPENSSL_VERSION_NUMBER < 0x1000000fL #This OpenSSL is too old #endif _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: OK" >&5 $as_echo "OK" >&6; } else as_fn_error $? "This release of CFEngine requires OpenSSL >= 1.0.0" "$LINENO" 5 fi rm -f conftest.err conftest.i conftest.$ac_ext if test "x$ac_cv_lib_crypto_RSA_generate_key_ex" = "xno" ; then as_fn_error $? "Cannot find OpenSSL" "$LINENO" 5 fi $as_echo "#define OPENSSL_SUPPRESS_DEPRECATED 1" >>confdefs.h ac_fn_c_check_decl "$LINENO" "SSL_OP_NO_TLSv1_1" "ac_cv_have_decl_SSL_OP_NO_TLSv1_1" "#include " if test "x$ac_cv_have_decl_SSL_OP_NO_TLSv1_1" = xyes; then : $as_echo "#define HAVE_TLS_1_1 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "SSL_OP_NO_TLSv1_2" "ac_cv_have_decl_SSL_OP_NO_TLSv1_2" "#include " if test "x$ac_cv_have_decl_SSL_OP_NO_TLSv1_2" = xyes; then : $as_echo "#define HAVE_TLS_1_2 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "SSL_OP_NO_TLSv1_3" "ac_cv_have_decl_SSL_OP_NO_TLSv1_3" "#include " if test "x$ac_cv_have_decl_SSL_OP_NO_TLSv1_3" = xyes; then : $as_echo "#define HAVE_TLS_1_3 1" >>confdefs.h fi # # Pick up any libraries added by tests # test -z "$OPENSSL_LIBS" && OPENSSL_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_openssl" != xyes && test "x$with_openssl" != xcheck && test "x$with_openssl" != x/usr && test "x$with_openssl" != x/ then OPENSSL_LDFLAGS="$OPENSSL_LDFLAGS -R$with_openssl/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" # Check whether --with-pcre2 was given. if test "${with_pcre2+set}" = set; then : withval=$with_pcre2; else with_pcre2=yes fi if test "x$with_pcre2" = "xno"; then as_fn_error $? "PCRE2 is required" "$LINENO" 5 fi # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_pcre2" != xyes && test "x$with_pcre2" != xcheck && test "x$with_pcre2" != x then test -z "$PCRE2_PATH" && PCRE2_PATH="$with_pcre2" if test "x$with_pcre2" != x/usr && test "x$with_pcre2" != x/ then test -z "$PCRE2_CFLAGS" && PCRE2_CFLAGS="" test -z "$PCRE2_CPPFLAGS" && PCRE2_CPPFLAGS="-I$with_pcre2/include" test -z "$PCRE2_LDFLAGS" && PCRE2_LDFLAGS="-L$with_pcre2/lib" fi else PCRE2_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $PCRE2_CFLAGS" CPPFLAGS="$CPPFLAGS $PCRE2_CPPFLAGS" LDFLAGS="$LDFLAGS $PCRE2_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre2_compile_8 in -lpcre2-8" >&5 $as_echo_n "checking for pcre2_compile_8 in -lpcre2-8... " >&6; } if ${ac_cv_lib_pcre2_8_pcre2_compile_8+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcre2-8 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pcre2_compile_8 (); int main () { return pcre2_compile_8 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pcre2_8_pcre2_compile_8=yes else ac_cv_lib_pcre2_8_pcre2_compile_8=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre2_8_pcre2_compile_8" >&5 $as_echo "$ac_cv_lib_pcre2_8_pcre2_compile_8" >&6; } if test "x$ac_cv_lib_pcre2_8_pcre2_compile_8" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPCRE2_8 1 _ACEOF LIBS="-lpcre2-8 $LIBS" else as_fn_error $? "Cannot find PCRE2" "$LINENO" 5 fi for ac_header in pcre2.h do : ac_fn_c_check_header_compile "$LINENO" "pcre2.h" "ac_cv_header_pcre2_h" "#define PCRE2_CODE_UNIT_WIDTH 8 " if test "x$ac_cv_header_pcre2_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PCRE2_H 1 _ACEOF else as_fn_error $? "Cannot find PCRE2" "$LINENO" 5 fi done # # Pick up any libraries added by tests # test -z "$PCRE2_LIBS" && PCRE2_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_pcre2" != xyes && test "x$with_pcre2" != xcheck && test "x$with_pcre2" != x/usr && test "x$with_pcre2" != x/ then PCRE2_LDFLAGS="$PCRE2_LDFLAGS -R$with_pcre2/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" $as_echo "#define WITH_PCRE2 1" >>confdefs.h # Check whether --with-libvirt was given. if test "${with_libvirt+set}" = set; then : withval=$with_libvirt; else with_libvirt=check fi if test "x$with_libvirt" != xno then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_libvirt" != xyes && test "x$with_libvirt" != xcheck && test "x$with_libvirt" != x then test -z "$LIBVIRT_PATH" && LIBVIRT_PATH="$with_libvirt" if test "x$with_libvirt" != x/usr && test "x$with_libvirt" != x/ then test -z "$LIBVIRT_CFLAGS" && LIBVIRT_CFLAGS="" test -z "$LIBVIRT_CPPFLAGS" && LIBVIRT_CPPFLAGS="-I$with_libvirt/include" test -z "$LIBVIRT_LDFLAGS" && LIBVIRT_LDFLAGS="-L$with_libvirt/lib" fi else LIBVIRT_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $LIBVIRT_CFLAGS" CPPFLAGS="$CPPFLAGS $LIBVIRT_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBVIRT_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for virConnectOpen in -lvirt" >&5 $as_echo_n "checking for virConnectOpen in -lvirt... " >&6; } if ${ac_cv_lib_virt_virConnectOpen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lvirt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char virConnectOpen (); int main () { return virConnectOpen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_virt_virConnectOpen=yes else ac_cv_lib_virt_virConnectOpen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_virt_virConnectOpen" >&5 $as_echo "$ac_cv_lib_virt_virConnectOpen" >&6; } if test "x$ac_cv_lib_virt_virConnectOpen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBVIRT 1 _ACEOF LIBS="-lvirt $LIBS" else if test "x$with_libvirt" != xcheck; then as_fn_error $? "Cannot find libvirt library" "$LINENO" 5; fi fi for ac_header in libvirt/libvirt.h do : ac_fn_c_check_header_mongrel "$LINENO" "libvirt/libvirt.h" "ac_cv_header_libvirt_libvirt_h" "$ac_includes_default" if test "x$ac_cv_header_libvirt_libvirt_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBVIRT_LIBVIRT_H 1 _ACEOF else if test "x$with_libvirt" != xcheck; then as_fn_error $? "Cannot find libvirt library headers" "$LINENO" 5; fi fi done # # Pick up any libraries added by tests # test -z "$LIBVIRT_LIBS" && LIBVIRT_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_libvirt" != xyes && test "x$with_libvirt" != xcheck && test "x$with_libvirt" != x/usr && test "x$with_libvirt" != x/ then LIBVIRT_LDFLAGS="$LIBVIRT_LDFLAGS -R$with_libvirt/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-libacl was given. if test "${with_libacl+set}" = set; then : withval=$with_libacl; else with_libacl=check fi if test "x$with_libacl" != xno then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_libacl" != xyes && test "x$with_libacl" != xcheck && test "x$with_libacl" != x then test -z "$LIBACL_PATH" && LIBACL_PATH="$with_libacl" if test "x$with_libacl" != x/usr && test "x$with_libacl" != x/ then test -z "$LIBACL_CFLAGS" && LIBACL_CFLAGS="" test -z "$LIBACL_CPPFLAGS" && LIBACL_CPPFLAGS="-I$with_libacl/include" test -z "$LIBACL_LDFLAGS" && LIBACL_LDFLAGS="-L$with_libacl/lib" fi else LIBACL_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $LIBACL_CFLAGS" CPPFLAGS="$CPPFLAGS $LIBACL_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBACL_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_init in -lacl" >&5 $as_echo_n "checking for acl_init in -lacl... " >&6; } if ${ac_cv_lib_acl_acl_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lacl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char acl_init (); int main () { return acl_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_acl_acl_init=yes else ac_cv_lib_acl_acl_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_init" >&5 $as_echo "$ac_cv_lib_acl_acl_init" >&6; } if test "x$ac_cv_lib_acl_acl_init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBACL 1 _ACEOF LIBS="-lacl $LIBS" else if test "x$with_libacl" != xcheck; then as_fn_error $? "Cannot find libacl library" "$LINENO" 5; fi fi for ac_header in acl.h sys/acl.h acl/libacl.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF libacl_header_found=yes fi done if test "x$libacl_header_found" != "xyes" && test "x$with_libacl" != xcheck; then as_fn_error $? "Cannot find libacl library headers" "$LINENO" 5; fi # # Pick up any libraries added by tests # test -z "$LIBACL_LIBS" && LIBACL_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_libacl" != xyes && test "x$with_libacl" != xcheck && test "x$with_libacl" != x/usr && test "x$with_libacl" != x/ then LIBACL_LDFLAGS="$LIBACL_LDFLAGS -R$with_libacl/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-libcurl was given. if test "${with_libcurl+set}" = set; then : withval=$with_libcurl; else with_libcurl=check fi if test "x$with_libcurl" != xno then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_libcurl" != xyes && test "x$with_libcurl" != xcheck && test "x$with_libcurl" != x then test -z "$LIBCURL_PATH" && LIBCURL_PATH="$with_libcurl" if test "x$with_libcurl" != x/usr && test "x$with_libcurl" != x/ then test -z "$LIBCURL_CFLAGS" && LIBCURL_CFLAGS="" test -z "$LIBCURL_CPPFLAGS" && LIBCURL_CPPFLAGS="-I$with_libcurl/include" test -z "$LIBCURL_LDFLAGS" && LIBCURL_LDFLAGS="-L$with_libcurl/lib" fi else LIBCURL_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $LIBCURL_CFLAGS" CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBCURL_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curl_global_init in -lcurl" >&5 $as_echo_n "checking for curl_global_init in -lcurl... " >&6; } if ${ac_cv_lib_curl_curl_global_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcurl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char curl_global_init (); int main () { return curl_global_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_curl_curl_global_init=yes else ac_cv_lib_curl_curl_global_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curl_curl_global_init" >&5 $as_echo "$ac_cv_lib_curl_curl_global_init" >&6; } if test "x$ac_cv_lib_curl_curl_global_init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCURL 1 _ACEOF LIBS="-lcurl $LIBS" else libcurl_lib_found=no; if test "x$with_libcurl" != xcheck; then as_fn_error $? "Cannot find libcurl library" "$LINENO" 5; fi fi for ac_header in curl/curl.h do : ac_fn_c_check_header_mongrel "$LINENO" "curl/curl.h" "ac_cv_header_curl_curl_h" "$ac_includes_default" if test "x$ac_cv_header_curl_curl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CURL_CURL_H 1 _ACEOF libcurl_header_found=yes else if test "x$with_libcurl" != xcheck; then as_fn_error $? "Cannot find libcurl header files" "$LINENO" 5; fi fi done # # Pick up any libraries added by tests # test -z "$LIBCURL_LIBS" && LIBCURL_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_libcurl" != xyes && test "x$with_libcurl" != xcheck && test "x$with_libcurl" != x/usr && test "x$with_libcurl" != x/ then LIBCURL_LDFLAGS="$LIBCURL_LDFLAGS -R$with_libcurl/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test "x$libcurl_lib_found" != xno && test "x$libcurl_header_found" = xyes; then HAVE_LIBCURL_TRUE= HAVE_LIBCURL_FALSE='#' else HAVE_LIBCURL_TRUE='#' HAVE_LIBCURL_FALSE= fi # Check whether --with-libyaml was given. if test "${with_libyaml+set}" = set; then : withval=$with_libyaml; else with_libyaml=check fi if test "x$with_libyaml" != xno then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_libyaml" != xyes && test "x$with_libyaml" != xcheck && test "x$with_libyaml" != x then test -z "$LIBYAML_PATH" && LIBYAML_PATH="$with_libyaml" if test "x$with_libyaml" != x/usr && test "x$with_libyaml" != x/ then test -z "$LIBYAML_CFLAGS" && LIBYAML_CFLAGS="" test -z "$LIBYAML_CPPFLAGS" && LIBYAML_CPPFLAGS="-I$with_libyaml/include" test -z "$LIBYAML_LDFLAGS" && LIBYAML_LDFLAGS="-L$with_libyaml/lib" fi else LIBYAML_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $LIBYAML_CFLAGS" CPPFLAGS="$CPPFLAGS $LIBYAML_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBYAML_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yaml_parser_initialize in -lyaml" >&5 $as_echo_n "checking for yaml_parser_initialize in -lyaml... " >&6; } if ${ac_cv_lib_yaml_yaml_parser_initialize+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lyaml $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char yaml_parser_initialize (); int main () { return yaml_parser_initialize (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_yaml_yaml_parser_initialize=yes else ac_cv_lib_yaml_yaml_parser_initialize=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_yaml_yaml_parser_initialize" >&5 $as_echo "$ac_cv_lib_yaml_yaml_parser_initialize" >&6; } if test "x$ac_cv_lib_yaml_yaml_parser_initialize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBYAML 1 _ACEOF LIBS="-lyaml $LIBS" else if test "x$with_libyaml" != xcheck; then as_fn_error $? "Cannot find libyaml library" "$LINENO" 5; fi fi for ac_header in yaml.h do : ac_fn_c_check_header_mongrel "$LINENO" "yaml.h" "ac_cv_header_yaml_h" "$ac_includes_default" if test "x$ac_cv_header_yaml_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_YAML_H 1 _ACEOF libyaml_header_found=yes else if test "x$with_libyaml" != xcheck; then as_fn_error $? "Cannot find libyaml header files" "$LINENO" 5; fi fi done # # Pick up any libraries added by tests # test -z "$LIBYAML_LIBS" && LIBYAML_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_libyaml" != xyes && test "x$with_libyaml" != xcheck && test "x$with_libyaml" != x/usr && test "x$with_libyaml" != x/ then LIBYAML_LDFLAGS="$LIBYAML_LDFLAGS -R$with_libyaml/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-libxml2 was given. if test "${with_libxml2+set}" = set; then : withval=$with_libxml2; else with_libxml2=check fi have_libxml2="no" if test "x$with_libxml2" != "xno"; then if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxml2 via pkg-config" >&5 $as_echo_n "checking for libxml2 via pkg-config... " >&6; } if `$PKG_CONFIG --exists libxml-2.0`; then LIBXML2_CFLAGS=`$PKG_CONFIG --cflags libxml-2.0` LIBXML2_CPPFLAGS="$LIBXML2_CFLAGS" LIBXML2_LIBS=`$PKG_CONFIG --libs libxml-2.0` LIBXML2_VERSION=`$PKG_CONFIG --modversion libxml-2.0` { $as_echo "$as_me:${as_lineno-$LINENO}: result: found version $LIBXML2_VERSION" >&5 $as_echo "found version $LIBXML2_VERSION" >&6; } have_libxml2="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } fi fi if test "x$have_libxml2" = "xno"; then if test "x$with_libxml2" != "xyes" && test "x$with_libxml2" != "xcheck" && test -x "$with_libxml2/bin/xml2-config" then XML2_CONFIG=$with_libxml2/bin/xml2-config else # Extract the first word of "xml2-config", so it can be a program name with args. set dummy xml2-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XML2_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $XML2_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_XML2_CONFIG="$XML2_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XML2_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XML2_CONFIG=$ac_cv_path_XML2_CONFIG if test -n "$XML2_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XML2_CONFIG" >&5 $as_echo "$XML2_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # xml2-config is only for native builds if test "x$cross_compiling" = "xno" && test -n "$XML2_CONFIG"; then xml2_include_dir=`$XML2_CONFIG --cflags` if test -n "$xml2_include_dir"; then LIBXML2_CPPFLAGS="$xml2_include_dir" fi else # xml2-config not found # if a path, e.g. /var/cfengine was given, then we # must take into account that libxml2 includes are in # /var/cfengine/include/libxml2 LIBXML2_CPPFLAGS=-I$with_libxml2/include/libxml2 fi fi # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_libxml2" != xyes && test "x$with_libxml2" != xcheck && test "x$with_libxml2" != x then test -z "$LIBXML2_PATH" && LIBXML2_PATH="$with_libxml2" if test "x$with_libxml2" != x/usr && test "x$with_libxml2" != x/ then test -z "$LIBXML2_CFLAGS" && LIBXML2_CFLAGS="" test -z "$LIBXML2_CPPFLAGS" && LIBXML2_CPPFLAGS="-I$with_libxml2/include" test -z "$LIBXML2_LDFLAGS" && LIBXML2_LDFLAGS="-L$with_libxml2/lib" fi else LIBXML2_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $LIBXML2_CFLAGS" CPPFLAGS="$CPPFLAGS $LIBXML2_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBXML2_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xmlFirstElementChild in -lxml2" >&5 $as_echo_n "checking for xmlFirstElementChild in -lxml2... " >&6; } if ${ac_cv_lib_xml2_xmlFirstElementChild+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lxml2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char xmlFirstElementChild (); int main () { return xmlFirstElementChild (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_xml2_xmlFirstElementChild=yes else ac_cv_lib_xml2_xmlFirstElementChild=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml2_xmlFirstElementChild" >&5 $as_echo "$ac_cv_lib_xml2_xmlFirstElementChild" >&6; } if test "x$ac_cv_lib_xml2_xmlFirstElementChild" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXML2 1 _ACEOF LIBS="-lxml2 $LIBS" else if test "x$with_libxml2" != xcheck; then as_fn_error $? "Cannot find libxml2" "$LINENO" 5; fi fi for ac_header in libxml/xmlwriter.h do : ac_fn_c_check_header_mongrel "$LINENO" "libxml/xmlwriter.h" "ac_cv_header_libxml_xmlwriter_h" "$ac_includes_default" if test "x$ac_cv_header_libxml_xmlwriter_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXML_XMLWRITER_H 1 _ACEOF break else if test "x$with_libxml2" != xcheck; then as_fn_error $? "Cannot find libxml2" "$LINENO" 5; fi fi done # # Pick up any libraries added by tests # test -z "$LIBXML2_LIBS" && LIBXML2_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_libxml2" != xyes && test "x$with_libxml2" != xcheck && test "x$with_libxml2" != x/usr && test "x$with_libxml2" != x/ then LIBXML2_LDFLAGS="$LIBXML2_LDFLAGS -R$with_libxml2/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi if test "x$with_libxml2" != xno && test "x$ac_cv_lib_xml2_xmlFirstElementChild" = xyes; then HAVE_LIBXML2_TRUE= HAVE_LIBXML2_FALSE='#' else HAVE_LIBXML2_TRUE='#' HAVE_LIBXML2_FALSE= fi # Check whether --with-avahi was given. if test "${with_avahi+set}" = set; then : withval=$with_avahi; else with_avahi=no fi if test "x$with_avahi" != xno then for ac_header in avahi-client/client.h do : ac_fn_c_check_header_mongrel "$LINENO" "avahi-client/client.h" "ac_cv_header_avahi_client_client_h" "$ac_includes_default" if test "x$ac_cv_header_avahi_client_client_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_AVAHI_CLIENT_CLIENT_H 1 _ACEOF if true; then HAVE_AVAHI_CLIENT_TRUE= HAVE_AVAHI_CLIENT_FALSE='#' else HAVE_AVAHI_CLIENT_TRUE='#' HAVE_AVAHI_CLIENT_FALSE= fi else if false; then HAVE_AVAHI_CLIENT_TRUE= HAVE_AVAHI_CLIENT_FALSE='#' else HAVE_AVAHI_CLIENT_TRUE='#' HAVE_AVAHI_CLIENT_FALSE= fi test "x$with_avahi" != "xcheck" && as_fn_error $? "Cannot find avahi-client/client.h" "$LINENO" 5 fi done for ac_header in avahi-common/address.h do : ac_fn_c_check_header_mongrel "$LINENO" "avahi-common/address.h" "ac_cv_header_avahi_common_address_h" "$ac_includes_default" if test "x$ac_cv_header_avahi_common_address_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_AVAHI_COMMON_ADDRESS_H 1 _ACEOF if true; then HAVE_AVAHI_COMMON_TRUE= HAVE_AVAHI_COMMON_FALSE='#' else HAVE_AVAHI_COMMON_TRUE='#' HAVE_AVAHI_COMMON_FALSE= fi else if false; then HAVE_AVAHI_COMMON_TRUE= HAVE_AVAHI_COMMON_FALSE='#' else HAVE_AVAHI_COMMON_TRUE='#' HAVE_AVAHI_COMMON_FALSE= fi test "x$with_avahi" != "xcheck" && as_fn_error $? "Cannot find avahi-common/address.h" "$LINENO" 5 fi done else if false; then HAVE_AVAHI_CLIENT_TRUE= HAVE_AVAHI_CLIENT_FALSE='#' else HAVE_AVAHI_CLIENT_TRUE='#' HAVE_AVAHI_CLIENT_FALSE= fi if false; then HAVE_AVAHI_COMMON_TRUE= HAVE_AVAHI_COMMON_FALSE='#' else HAVE_AVAHI_COMMON_TRUE='#' HAVE_AVAHI_COMMON_FALSE= fi fi for ac_header in unistd.h stdlib.h sys/loadavg.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/param.h sys/resource.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # sys/param.h is required for sys/mount.h on OpenBSD for ac_header in sys/mount.h do : ac_fn_c_check_header_compile "$LINENO" "sys/mount.h" "ac_cv_header_sys_mount_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_mount_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_MOUNT_H 1 _ACEOF fi done # Required on BSD to get struct sockaddr_dl (for retrieving MAC addresses from getifaddrs()) for ac_header in net/if_dl.h do : ac_fn_c_check_header_mongrel "$LINENO" "net/if_dl.h" "ac_cv_header_net_if_dl_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_dl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NET_IF_DL_H 1 _ACEOF fi done # Required on Solaris to get struct arpreq (for retrieving MAC addresses) for ac_header in net/if_arp.h do : ac_fn_c_check_header_compile "$LINENO" "net/if_arp.h" "ac_cv_header_net_if_arp_h" "$ac_includes_default #include " if test "x$ac_cv_header_net_if_arp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NET_IF_ARP_H 1 _ACEOF fi done for ac_header in getopt.h do : ac_fn_c_check_header_mongrel "$LINENO" "getopt.h" "ac_cv_header_getopt_h" "$ac_includes_default" if test "x$ac_cv_header_getopt_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETOPT_H 1 _ACEOF system_getopt_h=1 else system_getopt_h=0 fi done if test x$system_getopt_h = x0; then NO_SYSTEM_GETOPT_H_TRUE= NO_SYSTEM_GETOPT_H_FALSE='#' else NO_SYSTEM_GETOPT_H_TRUE='#' NO_SYSTEM_GETOPT_H_FALSE= fi for ac_header in utime.h do : ac_fn_c_check_header_mongrel "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default" if test "x$ac_cv_header_utime_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTIME_H 1 _ACEOF fi done for ac_header in time.h do : ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" if test "x$ac_cv_header_time_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TIME_H 1 _ACEOF fi done for ac_header in sys/time.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" if test "x$ac_cv_header_sys_time_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TIME_H 1 _ACEOF fi done for ac_header in malloc.h sys/malloc.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in vfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "vfs.h" "ac_cv_header_vfs_h" "$ac_includes_default" if test "x$ac_cv_header_vfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VFS_H 1 _ACEOF fi done for ac_header in sys/vfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/vfs.h" "ac_cv_header_sys_vfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_vfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_VFS_H 1 _ACEOF fi done for ac_header in sys/sockio.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/sockio.h" "ac_cv_header_sys_sockio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sockio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SOCKIO_H 1 _ACEOF fi done for ac_header in sys/statvfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_statvfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_STATVFS_H 1 _ACEOF fi done for ac_header in sys/statfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/statfs.h" "ac_cv_header_sys_statfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_statfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_STATFS_H 1 _ACEOF fi done for ac_header in fcntl.h do : ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" if test "x$ac_cv_header_fcntl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FCNTL_H 1 _ACEOF fi done for ac_header in sys/filesys.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/filesys.h" "ac_cv_header_sys_filesys_h" "$ac_includes_default" if test "x$ac_cv_header_sys_filesys_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_FILESYS_H 1 _ACEOF fi done for ac_header in dustat.h do : ac_fn_c_check_header_mongrel "$LINENO" "dustat.h" "ac_cv_header_dustat_h" "$ac_includes_default" if test "x$ac_cv_header_dustat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DUSTAT_H 1 _ACEOF fi done for ac_header in sys/systeminfo.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/systeminfo.h" "ac_cv_header_sys_systeminfo_h" "$ac_includes_default" if test "x$ac_cv_header_sys_systeminfo_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SYSTEMINFO_H 1 _ACEOF fi done for ac_header in ieeefp.h do : ac_fn_c_check_header_mongrel "$LINENO" "ieeefp.h" "ac_cv_header_ieeefp_h" "$ac_includes_default" if test "x$ac_cv_header_ieeefp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IEEEFP_H 1 _ACEOF fi done for ac_header in winsock2.h do : ac_fn_c_check_header_mongrel "$LINENO" "winsock2.h" "ac_cv_header_winsock2_h" "$ac_includes_default" if test "x$ac_cv_header_winsock2_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WINSOCK2_H 1 _ACEOF fi done for ac_header in ws2tcpip.h do : ac_fn_c_check_header_mongrel "$LINENO" "ws2tcpip.h" "ac_cv_header_ws2tcpip_h" "$ac_includes_default" if test "x$ac_cv_header_ws2tcpip_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WS2TCPIP_H 1 _ACEOF fi done for ac_header in zone.h do : ac_fn_c_check_header_mongrel "$LINENO" "zone.h" "ac_cv_header_zone_h" "$ac_includes_default" if test "x$ac_cv_header_zone_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZONE_H 1 _ACEOF fi done for ac_header in sys/uio.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_uio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_UIO_H 1 _ACEOF fi done for ac_header in $ac_header_list do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TYPES_H 1 _ACEOF fi done for ac_header in sys/mpctl.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/mpctl.h" "ac_cv_header_sys_mpctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mpctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_MPCTL_H 1 _ACEOF fi done for ac_header in shadow.h do : ac_fn_c_check_header_mongrel "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default" if test "x$ac_cv_header_shadow_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SHADOW_H 1 _ACEOF fi done for ac_header in sys/jail.h do : ac_fn_c_check_header_compile "$LINENO" "sys/jail.h" "ac_cv_header_sys_jail_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_jail_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_JAIL_H 1 _ACEOF fi done for ac_header in net/route.h netinet/in.h netinet/ip.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if ${ac_cv_header_sys_wait_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$as_ac_Header=yes" else eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" if test "x$ac_cv_type_mode_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define mode_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 $as_echo_n "checking for uid_t in sys/types.h... " >&6; } if ${ac_cv_type_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then : ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 $as_echo "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then $as_echo "#define uid_t int" >>confdefs.h $as_echo "#define gid_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "clockid_t" "ac_cv_type_clockid_t" " #ifdef HAVE_TIME_H # include #endif " if test "x$ac_cv_type_clockid_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CLOCKID_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " #ifdef HAVE_SYS_TYPES_H # include #endif #include " if test "x$ac_cv_type_socklen_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi # # AC_SYS_LARGEFILE correctly figures out necessary macros for large files, but # on AIX there is a gotcha: # # Code generated by flex #includes at the beginning of the file, which # picks up 32-bit wide off_t. Then it #includes which provides LFS # macros, and finally it includes another system header, now with 64-bit wide # off_t, which causes a conflict. # if test "x$ac_cv_sys_large_files" = x1; then CPPFLAGS="-D_LARGE_FILES=1 $CPPFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 $as_echo_n "checking for sqrt in -lm... " >&6; } if ${ac_cv_lib_m_sqrt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sqrt (); int main () { return sqrt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_sqrt=yes else ac_cv_lib_m_sqrt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 $as_echo "$ac_cv_lib_m_sqrt" >&6; } if test "x$ac_cv_lib_m_sqrt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if ${ac_cv_lib_rt_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi ac_fn_c_check_decl "$LINENO" "clock_gettime" "ac_cv_have_decl_clock_gettime" "#include " if test "x$ac_cv_have_decl_clock_gettime" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CLOCK_GETTIME $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "unsetenv" "ac_cv_have_decl_unsetenv" "$ac_includes_default" if test "x$ac_cv_have_decl_unsetenv" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_UNSETENV $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "$ac_includes_default" if test "x$ac_cv_have_decl_strnlen" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNLEN $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "seteuid" "ac_cv_have_decl_seteuid" "$ac_includes_default" if test "x$ac_cv_have_decl_seteuid" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETEUID $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "setlinebuf" "ac_cv_have_decl_setlinebuf" "$ac_includes_default" if test "x$ac_cv_have_decl_setlinebuf" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETLINEBUF $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strlcat" "ac_cv_have_decl_strlcat" "$ac_includes_default" if test "x$ac_cv_have_decl_strlcat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRLCAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strlcpy" "ac_cv_have_decl_strlcpy" "$ac_includes_default" if test "x$ac_cv_have_decl_strlcpy" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRLCPY $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "realpath" "ac_cv_have_decl_realpath" "$ac_includes_default" if test "x$ac_cv_have_decl_realpath" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_REALPATH $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strdup" "ac_cv_have_decl_strdup" "$ac_includes_default" if test "x$ac_cv_have_decl_strdup" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRDUP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "memrchr" "ac_cv_have_decl_memrchr" "$ac_includes_default" if test "x$ac_cv_have_decl_memrchr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MEMRCHR $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "round" "ac_cv_have_decl_round" "#include " if test "x$ac_cv_have_decl_round" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ROUND $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "nanosleep" "ac_cv_have_decl_nanosleep" "$ac_includes_default" if test "x$ac_cv_have_decl_nanosleep" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_NANOSLEEP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "memdup" "ac_cv_have_decl_memdup" "$ac_includes_default" if test "x$ac_cv_have_decl_memdup" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MEMDUP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "memmem" "ac_cv_have_decl_memmem" "$ac_includes_default" if test "x$ac_cv_have_decl_memmem" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MEMMEM $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "srand48" "ac_cv_have_decl_srand48" "$ac_includes_default" if test "x$ac_cv_have_decl_srand48" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SRAND48 $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "drand48" "ac_cv_have_decl_drand48" "$ac_includes_default" if test "x$ac_cv_have_decl_drand48" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_DRAND48 $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strerror" "ac_cv_have_decl_strerror" "$ac_includes_default" if test "x$ac_cv_have_decl_strerror" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strstr" "ac_cv_have_decl_strstr" "$ac_includes_default" if test "x$ac_cv_have_decl_strstr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRSTR $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strcasestr" "ac_cv_have_decl_strcasestr" "$ac_includes_default" if test "x$ac_cv_have_decl_strcasestr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCASESTR $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strcasecmp" "ac_cv_have_decl_strcasecmp" "$ac_includes_default" if test "x$ac_cv_have_decl_strcasecmp" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCASECMP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strncasecmp" "ac_cv_have_decl_strncasecmp" "$ac_includes_default" if test "x$ac_cv_have_decl_strncasecmp" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNCASECMP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strsep" "ac_cv_have_decl_strsep" "$ac_includes_default" if test "x$ac_cv_have_decl_strsep" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRSEP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strsignal" "ac_cv_have_decl_strsignal" "$ac_includes_default" if test "x$ac_cv_have_decl_strsignal" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRSIGNAL $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "gmtime_r" "ac_cv_have_decl_gmtime_r" "#include " if test "x$ac_cv_have_decl_gmtime_r" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GMTIME_R $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "getline" "ac_cv_have_decl_getline" "#define _GNU_SOURCE 1 $ac_includes_default " if test "x$ac_cv_have_decl_getline" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETLINE $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strchrnul" "ac_cv_have_decl_strchrnul" "#define _GNU_SOURCE 1 $ac_includes_default " if test "x$ac_cv_have_decl_strchrnul" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCHRNUL $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "localtime_r" "ac_cv_have_decl_localtime_r" "#include " if test "x$ac_cv_have_decl_localtime_r" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOCALTIME_R $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fgetgrent" "ac_cv_have_decl_fgetgrent" "#include " if test "x$ac_cv_have_decl_fgetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FGETGRENT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "isfinite" "ac_cv_have_decl_isfinite" "#include " if test "x$ac_cv_have_decl_isfinite" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ISFINITE $ac_have_decl _ACEOF for ac_func in getpwent setpwent endpwent do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in fgetspent lckpwdf ulckpwdf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgetspent in -lsec" >&5 $as_echo_n "checking for fgetspent in -lsec... " >&6; } if ${ac_cv_lib_sec_fgetspent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsec $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fgetspent (); int main () { return fgetspent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sec_fgetspent=yes else ac_cv_lib_sec_fgetspent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sec_fgetspent" >&5 $as_echo "$ac_cv_lib_sec_fgetspent" >&6; } if test "x$ac_cv_lib_sec_fgetspent" = xyes; then : $as_echo "#define HAVE_LIBSEC 1" >>confdefs.h $as_echo "#define HAVE_FGETSPENT 1" >>confdefs.h LIBS="-lsec $LIBS" fi ac_fn_c_check_decl "$LINENO" "getloadavg" "ac_cv_have_decl_getloadavg" "$ac_includes_default" if test "x$ac_cv_have_decl_getloadavg" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETLOADAVG $ac_have_decl _ACEOF ac_have_func=no # yes means we've found a way to get the load average. # Make sure getloadavg.c is where it belongs, at configure-time. test -f "$srcdir/$ac_config_libobj_dir/getloadavg.c" || as_fn_error $? "$srcdir/$ac_config_libobj_dir/getloadavg.c is missing" "$LINENO" 5 ac_save_LIBS=$LIBS # Check for getloadavg, but be sure not to touch the cache variable. (ac_fn_c_check_func "$LINENO" "getloadavg" "ac_cv_func_getloadavg" if test "x$ac_cv_func_getloadavg" = xyes; then : exit 0 else exit 1 fi ) && ac_have_func=yes # On HPUX9, an unprivileged user can get load averages through this function. for ac_func in pstat_getdynamic do : ac_fn_c_check_func "$LINENO" "pstat_getdynamic" "ac_cv_func_pstat_getdynamic" if test "x$ac_cv_func_pstat_getdynamic" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PSTAT_GETDYNAMIC 1 _ACEOF fi done # Solaris has libkstat which does not require root. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for kstat_open in -lkstat" >&5 $as_echo_n "checking for kstat_open in -lkstat... " >&6; } if ${ac_cv_lib_kstat_kstat_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkstat $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char kstat_open (); int main () { return kstat_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_kstat_kstat_open=yes else ac_cv_lib_kstat_kstat_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_kstat_kstat_open" >&5 $as_echo "$ac_cv_lib_kstat_kstat_open" >&6; } if test "x$ac_cv_lib_kstat_kstat_open" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBKSTAT 1 _ACEOF LIBS="-lkstat $LIBS" fi test $ac_cv_lib_kstat_kstat_open = yes && ac_have_func=yes # Some systems with -lutil have (and need) -lkvm as well, some do not. # On Solaris, -lkvm requires nlist from -lelf, so check that first # to get the right answer into the cache. # For kstat on solaris, we need libelf to force the definition of SVR4 below. if test $ac_have_func = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for elf_begin in -lelf" >&5 $as_echo_n "checking for elf_begin in -lelf... " >&6; } if ${ac_cv_lib_elf_elf_begin+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lelf $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char elf_begin (); int main () { return elf_begin (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_elf_elf_begin=yes else ac_cv_lib_elf_elf_begin=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_elf_elf_begin" >&5 $as_echo "$ac_cv_lib_elf_elf_begin" >&6; } if test "x$ac_cv_lib_elf_elf_begin" = xyes; then : LIBS="-lelf $LIBS" fi fi if test $ac_have_func = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for kvm_open in -lkvm" >&5 $as_echo_n "checking for kvm_open in -lkvm... " >&6; } if ${ac_cv_lib_kvm_kvm_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkvm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char kvm_open (); int main () { return kvm_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_kvm_kvm_open=yes else ac_cv_lib_kvm_kvm_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_kvm_kvm_open" >&5 $as_echo "$ac_cv_lib_kvm_kvm_open" >&6; } if test "x$ac_cv_lib_kvm_kvm_open" = xyes; then : LIBS="-lkvm $LIBS" fi # Check for the 4.4BSD definition of getloadavg. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getloadavg in -lutil" >&5 $as_echo_n "checking for getloadavg in -lutil... " >&6; } if ${ac_cv_lib_util_getloadavg+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getloadavg (); int main () { return getloadavg (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_util_getloadavg=yes else ac_cv_lib_util_getloadavg=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_getloadavg" >&5 $as_echo "$ac_cv_lib_util_getloadavg" >&6; } if test "x$ac_cv_lib_util_getloadavg" = xyes; then : LIBS="-lutil $LIBS" ac_have_func=yes ac_cv_func_getloadavg_setgid=yes fi fi if test $ac_have_func = no; then # There is a commonly available library for RS/6000 AIX. # Since it is not a standard part of AIX, it might be installed locally. ac_getloadavg_LIBS=$LIBS LIBS="-L/usr/local/lib $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getloadavg in -lgetloadavg" >&5 $as_echo_n "checking for getloadavg in -lgetloadavg... " >&6; } if ${ac_cv_lib_getloadavg_getloadavg+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgetloadavg $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getloadavg (); int main () { return getloadavg (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_getloadavg_getloadavg=yes else ac_cv_lib_getloadavg_getloadavg=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_getloadavg_getloadavg" >&5 $as_echo "$ac_cv_lib_getloadavg_getloadavg" >&6; } if test "x$ac_cv_lib_getloadavg_getloadavg" = xyes; then : LIBS="-lgetloadavg $LIBS" else LIBS=$ac_getloadavg_LIBS fi fi # Make sure it is really in the library, if we think we found it, # otherwise set up the replacement function. for ac_func in getloadavg do : ac_fn_c_check_func "$LINENO" "getloadavg" "ac_cv_func_getloadavg" if test "x$ac_cv_func_getloadavg" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETLOADAVG 1 _ACEOF else case " $LIBOBJS " in *" getloadavg.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getloadavg.$ac_objext" ;; esac $as_echo "#define C_GETLOADAVG 1" >>confdefs.h # Figure out what our getloadavg.c needs. ac_have_func=no ac_fn_c_check_header_mongrel "$LINENO" "sys/dg_sys_info.h" "ac_cv_header_sys_dg_sys_info_h" "$ac_includes_default" if test "x$ac_cv_header_sys_dg_sys_info_h" = xyes; then : ac_have_func=yes $as_echo "#define DGUX 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dg_sys_info in -ldgc" >&5 $as_echo_n "checking for dg_sys_info in -ldgc... " >&6; } if ${ac_cv_lib_dgc_dg_sys_info+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldgc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dg_sys_info (); int main () { return dg_sys_info (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dgc_dg_sys_info=yes else ac_cv_lib_dgc_dg_sys_info=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dgc_dg_sys_info" >&5 $as_echo "$ac_cv_lib_dgc_dg_sys_info" >&6; } if test "x$ac_cv_lib_dgc_dg_sys_info" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDGC 1 _ACEOF LIBS="-ldgc $LIBS" fi fi ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" if test "x$ac_cv_header_locale_h" = xyes; then : fi for ac_func in setlocale do : ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" if test "x$ac_cv_func_setlocale" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETLOCALE 1 _ACEOF fi done # We cannot check for , because Solaris 2 does not use dwarf (it # uses stabs), but it is still SVR4. We cannot check for because # Irix 4.0.5F has the header but not the library. if test $ac_have_func = no && test "$ac_cv_lib_elf_elf_begin" = yes \ && test "$ac_cv_lib_kvm_kvm_open" = yes; then ac_have_func=yes $as_echo "#define SVR4 1" >>confdefs.h fi if test $ac_have_func = no; then ac_fn_c_check_header_mongrel "$LINENO" "inq_stats/cpustats.h" "ac_cv_header_inq_stats_cpustats_h" "$ac_includes_default" if test "x$ac_cv_header_inq_stats_cpustats_h" = xyes; then : ac_have_func=yes $as_echo "#define UMAX 1" >>confdefs.h $as_echo "#define UMAX4_3 1" >>confdefs.h fi fi if test $ac_have_func = no; then ac_fn_c_check_header_mongrel "$LINENO" "sys/cpustats.h" "ac_cv_header_sys_cpustats_h" "$ac_includes_default" if test "x$ac_cv_header_sys_cpustats_h" = xyes; then : ac_have_func=yes; $as_echo "#define UMAX 1" >>confdefs.h fi fi if test $ac_have_func = no; then for ac_header in mach/mach.h do : ac_fn_c_check_header_mongrel "$LINENO" "mach/mach.h" "ac_cv_header_mach_mach_h" "$ac_includes_default" if test "x$ac_cv_header_mach_mach_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MACH_MACH_H 1 _ACEOF fi done fi for ac_header in nlist.h do : ac_fn_c_check_header_mongrel "$LINENO" "nlist.h" "ac_cv_header_nlist_h" "$ac_includes_default" if test "x$ac_cv_header_nlist_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NLIST_H 1 _ACEOF ac_fn_c_check_member "$LINENO" "struct nlist" "n_un.n_name" "ac_cv_member_struct_nlist_n_un_n_name" "#include " if test "x$ac_cv_member_struct_nlist_n_un_n_name" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_NLIST_N_UN_N_NAME 1 _ACEOF $as_echo "#define NLIST_NAME_UNION 1" >>confdefs.h fi fi done fi done # Some definitions of getloadavg require that the program be installed setgid. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getloadavg requires setgid" >&5 $as_echo_n "checking whether getloadavg requires setgid... " >&6; } if ${ac_cv_func_getloadavg_setgid+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "$srcdir/$ac_config_libobj_dir/getloadavg.c" #ifdef LDAV_PRIVILEGED Yowza Am I SETGID yet #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "Yowza Am I SETGID yet" >/dev/null 2>&1; then : ac_cv_func_getloadavg_setgid=yes else ac_cv_func_getloadavg_setgid=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getloadavg_setgid" >&5 $as_echo "$ac_cv_func_getloadavg_setgid" >&6; } if test $ac_cv_func_getloadavg_setgid = yes; then NEED_SETGID=true $as_echo "#define GETLOADAVG_PRIVILEGED 1" >>confdefs.h else NEED_SETGID=false fi if test $ac_cv_func_getloadavg_setgid = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking group of /dev/kmem" >&5 $as_echo_n "checking group of /dev/kmem... " >&6; } if ${ac_cv_group_kmem+:} false; then : $as_echo_n "(cached) " >&6 else # On Solaris, /dev/kmem is a symlink. Get info on the real file. ac_ls_output=`ls -lgL /dev/kmem 2>/dev/null` # If we got an error (system does not support symlinks), try without -L. test -z "$ac_ls_output" && ac_ls_output=`ls -lg /dev/kmem` ac_cv_group_kmem=`$as_echo "$ac_ls_output" \ | sed -ne 's/[ ][ ]*/ /g; s/^.[sSrwx-]* *[0-9]* *\([^0-9]*\) *.*/\1/; / /s/.* //;p;'` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_group_kmem" >&5 $as_echo "$ac_cv_group_kmem" >&6; } KMEM_GROUP=$ac_cv_group_kmem fi if test "x$ac_save_LIBS" = x; then GETLOADAVG_LIBS=$LIBS else GETLOADAVG_LIBS=`$as_echo "$LIBS" | sed "s|$ac_save_LIBS||"` fi LIBS=$ac_save_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac for ac_header in endian.h do : ac_fn_c_check_header_mongrel "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default" if test "x$ac_cv_header_endian_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ENDIAN_H 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "le32toh" "ac_cv_have_decl_le32toh" "#include " if test "x$ac_cv_have_decl_le32toh" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LE32TOH $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "closefrom" "ac_cv_have_decl_closefrom" "#include #include " if test "x$ac_cv_have_decl_closefrom" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CLOSEFROM $ac_have_decl _ACEOF for ac_header in sys/pstat.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/pstat.h" "ac_cv_header_sys_pstat_h" "$ac_includes_default" if test "x$ac_cv_header_sys_pstat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_PSTAT_H 1 _ACEOF fi done for ac_func in pstat_getfile2 do : ac_fn_c_check_func "$LINENO" "pstat_getfile2" "ac_cv_func_pstat_getfile2" if test "x$ac_cv_func_pstat_getfile2" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PSTAT_GETFILE2 1 _ACEOF fi done found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for chpasswd... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/chpasswd && ls -ld $i/chpasswd | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : CHPASSWD=$i/chpasswd found=1 break fi done if test "$found" = "1"; then : $as_echo "$CHPASSWD" else $as_echo no CHPASSWD= fi if test "x$CHPASSWD" != "x"; then : $as_echo "#define HAVE_CHPASSWD 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define CHPASSWD "$CHPASSWD" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for pwdadm... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/pwdadm && ls -ld $i/pwdadm | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : PWDADM=$i/pwdadm found=1 break fi done if test "$found" = "1"; then : $as_echo "$PWDADM" else $as_echo no PWDADM= fi if test "x$PWDADM" != "x"; then : $as_echo "#define HAVE_PWDADM 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PWDADM "$PWDADM" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for useradd... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/useradd && ls -ld $i/useradd | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : USERADD=$i/useradd found=1 break fi done if test "$found" = "1"; then : $as_echo "$USERADD" else $as_echo no USERADD= fi if test "x$USERADD" != "x"; then : $as_echo "#define HAVE_USERADD 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define USERADD "$USERADD" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for usermod... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/usermod && ls -ld $i/usermod | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : USERMOD=$i/usermod found=1 break fi done if test "$found" = "1"; then : $as_echo "$USERMOD" else $as_echo no USERMOD= fi if test "x$USERMOD" != "x"; then : $as_echo "#define HAVE_USERMOD 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define USERMOD "$USERMOD" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for userdel... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/userdel && ls -ld $i/userdel | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : USERDEL=$i/userdel found=1 break fi done if test "$found" = "1"; then : $as_echo "$USERDEL" else $as_echo no USERDEL= fi if test "x$USERDEL" != "x"; then : $as_echo "#define HAVE_USERDEL 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define USERDEL "$USERDEL" _ACEOF fi if test "x$USERADD" != x && \ test "x$USERMOD" != x && test "x$USERDEL" != x; then : have_userprogs=yes else have_userprogs=no fi found=0 if test "x/usr/bin:$PATH" = "x"; then : path=$PATH else path=/usr/bin:$PATH fi $as_echo_n "checking for chpass... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/chpass && ls -ld $i/chpass | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : CHPASS=$i/chpass found=1 break fi done if test "$found" = "1"; then : $as_echo "$CHPASS" else $as_echo no CHPASS= fi if test "x$CHPASS" != "x"; then : $as_echo "#define HAVE_CHPASS 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define CHPASS "$CHPASS" _ACEOF fi found=0 if test "x/usr/sbin:$PATH" = "x"; then : path=$PATH else path=/usr/sbin:$PATH fi $as_echo_n "checking for pw... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/pw && ls -ld $i/pw | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : PW=$i/pw found=1 break fi done if test "$found" = "1"; then : $as_echo "$PW" else $as_echo no PW= fi if test "x$PW" != "x"; then : $as_echo "#define HAVE_PW 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PW "$PW" _ACEOF fi if test "x$CHPASS" != x && \ test "x$PW" != x; then : have_userprogs=yes else have_userprogs=no fi # Check whether --with-pam was given. if test "${with_pam+set}" = set; then : withval=$with_pam; fi if test x$with_pam != xno; then : # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_pam" != xyes && test "x$with_pam" != xcheck && test "x$with_pam" != x then test -z "$PAM_PATH" && PAM_PATH="$with_pam" if test "x$with_pam" != x/usr && test "x$with_pam" != x/ then test -z "$PAM_CFLAGS" && PAM_CFLAGS="" test -z "$PAM_CPPFLAGS" && PAM_CPPFLAGS="-I$with_pam/include" test -z "$PAM_LDFLAGS" && PAM_LDFLAGS="-L$with_pam/lib" fi else PAM_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $PAM_CFLAGS" CPPFLAGS="$CPPFLAGS $PAM_CPPFLAGS" LDFLAGS="$LDFLAGS $PAM_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5 $as_echo_n "checking for pam_start in -lpam... " >&6; } if ${ac_cv_lib_pam_pam_start+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pam_start (); int main () { return pam_start (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pam_pam_start=yes else ac_cv_lib_pam_pam_start=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5 $as_echo "$ac_cv_lib_pam_pam_start" >&6; } if test "x$ac_cv_lib_pam_pam_start" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPAM 1 _ACEOF LIBS="-lpam $LIBS" fi for ac_header in security/pam_appl.h do : ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SECURITY_PAM_APPL_H 1 _ACEOF fi done # # Pick up any libraries added by tests # test -z "$PAM_LIBS" && PAM_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_pam" != xyes && test "x$with_pam" != xcheck && test "x$with_pam" != x/usr && test "x$with_pam" != x/ then PAM_LDFLAGS="$PAM_LDFLAGS -R$with_pam/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" case $target_os in #( *gnu*|*solaris*|*aix*|*hpux*|*hp-ux*) : if test "x$ac_cv_lib_pam_pam_start" != "xyes"; then : as_fn_error $? "Cannot find PAM library" "$LINENO" 5 fi if test "x$ac_cv_header_security_pam_appl_h" != "xyes"; then : as_fn_error $? "Cannot find PAM headers" "$LINENO" 5 fi ;; #( *) : ;; esac if test "x$ac_cv_lib_pam_pam_start" = "xyes" && \ test "x$ac_cv_header_security_pam_appl_h" = "xyes"; then : have_pam=yes else have_pam=no fi for ac_func in fgetpwent fgetgrent do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_fgetpwent" = "xyes" && \ test "x$ac_cv_func_fgetgrent" = "xyes"; then : have_fgetpwent_fgetgrent=yes $as_echo "#define HAVE_FGETPWENT_FGETGRENT 1" >>confdefs.h else have_fgetpwent_fgetgrent=no fi case "$target_os" in #( freebsd*) : if test "x$have_pam" = "xyes" && \ test "x$have_userprogs" = "xyes"; then : users_promises_ok=yes else users_promises_ok=no fi ;; #( *) : if test "x$have_pam" = "xyes" && \ test "x$have_userprogs" = "xyes" test "x$ac_cv_func_fgetpwent" = "xyes" && \ test "x$ac_cv_func_fgetgrent" = "xyes"; then : users_promises_ok=yes else users_promises_ok=no fi ;; esac else users_promises_ok=no fi if test "x$users_promises_ok" = "xyes"; then HAVE_USERS_PROMISE_DEPS_TRUE= HAVE_USERS_PROMISE_DEPS_FALSE='#' else HAVE_USERS_PROMISE_DEPS_TRUE='#' HAVE_USERS_PROMISE_DEPS_FALSE= fi ac_fn_c_check_decl "$LINENO" "getnetgrent" "ac_cv_have_decl_getnetgrent" "#include " if test "x$ac_cv_have_decl_getnetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETNETGRENT $ac_have_decl _ACEOF for ac_func in getnetgrent do : ac_fn_c_check_func "$LINENO" "getnetgrent" "ac_cv_func_getnetgrent" if test "x$ac_cv_func_getnetgrent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETNETGRENT 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "setnetgrent" "ac_cv_have_decl_setnetgrent" "#include " if test "x$ac_cv_have_decl_setnetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETNETGRENT $ac_have_decl _ACEOF for ac_func in setnetgrent do : ac_fn_c_check_func "$LINENO" "setnetgrent" "ac_cv_func_setnetgrent" if test "x$ac_cv_func_setnetgrent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETNETGRENT 1 _ACEOF fi done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { extern int setnetgrent(const char *) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define SETNETGRENT_RETURNS_INT 1" >>confdefs.h else $as_echo "#define SETNETGRENT_RETURNS_INT 0" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_decl "$LINENO" "endnetgrent" "ac_cv_have_decl_endnetgrent" "#include " if test "x$ac_cv_have_decl_endnetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ENDNETGRENT $ac_have_decl _ACEOF for ac_func in endnetgrent do : ac_fn_c_check_func "$LINENO" "endnetgrent" "ac_cv_func_endnetgrent" if test "x$ac_cv_func_endnetgrent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ENDNETGRENT 1 _ACEOF fi done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { extern int endnetgrent(const char *) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define ENDNETGRENT_RETURNS_INT 1" >>confdefs.h else $as_echo "#define ENDNETGRENT_RETURNS_INT 0" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext for ac_func in sendto do : ac_fn_c_check_func "$LINENO" "sendto" "ac_cv_func_sendto" if test "x$ac_cv_func_sendto" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SENDTO 1 _ACEOF fi done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { extern ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define SENDTO_RETURNS_SSIZE_T 1" >>confdefs.h else $as_echo "#define SENDTO_RETURNS_SSIZE_T 0" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_func "$LINENO" "ctime" "ac_cv_func_ctime" if test "x$ac_cv_func_ctime" = xyes; then : else as_fn_error $? "Unable to find function ctime" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ctime is properly declared" >&5 $as_echo_n "checking whether ctime is properly declared... " >&6; } if ${hw_cv_func_ctime_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #error ctime(3) may produce different results on different OSes. Let's have our POSIX-compliant implementation all the time ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_ctime_proper=yes else hw_cv_func_ctime_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_ctime_proper" >&5 $as_echo "$hw_cv_func_ctime_proper" >&6; } if test "$hw_cv_func_ctime_proper" = yes; then : $as_echo "#define HAVE_ctime_PROPER 1" >>confdefs.h else post_macros="$post_macros #define ctime rpl_ctime" fi ac_fn_c_check_func "$LINENO" "mkdir" "ac_cv_func_mkdir" if test "x$ac_cv_func_mkdir" = xyes; then : else as_fn_error $? "Unable to find function mkdir" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mkdir is properly declared" >&5 $as_echo_n "checking whether mkdir is properly declared... " >&6; } if ${hw_cv_func_mkdir_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { int mkdir(const char *pathname, mode_t mode); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_mkdir_proper=yes else hw_cv_func_mkdir_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_mkdir_proper" >&5 $as_echo "$hw_cv_func_mkdir_proper" >&6; } if test "$hw_cv_func_mkdir_proper" = yes; then : $as_echo "#define HAVE_mkdir_PROPER 1" >>confdefs.h else post_macros="$post_macros #define mkdir rpl_mkdir" fi ac_fn_c_check_func "$LINENO" "stat" "ac_cv_func_stat" if test "x$ac_cv_func_stat" = xyes; then : else as_fn_error $? "Unable to find function stat" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat is properly declared" >&5 $as_echo_n "checking whether stat is properly declared... " >&6; } if ${hw_cv_func_stat_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if defined(__MINGW32__) #error stat in Windows CRT ill-behaves #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_stat_proper=yes else hw_cv_func_stat_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_stat_proper" >&5 $as_echo "$hw_cv_func_stat_proper" >&6; } if test "$hw_cv_func_stat_proper" = yes; then : $as_echo "#define HAVE_stat_PROPER 1" >>confdefs.h else post_macros="$post_macros " fi ac_fn_c_check_func "$LINENO" "rename" "ac_cv_func_rename" if test "x$ac_cv_func_rename" = xyes; then : else as_fn_error $? "Unable to find function rename" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether rename is properly declared" >&5 $as_echo_n "checking whether rename is properly declared... " >&6; } if ${hw_cv_func_rename_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #if defined(__MINGW32__) #error rename in Windows CRT ill-behaves #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_rename_proper=yes else hw_cv_func_rename_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_rename_proper" >&5 $as_echo "$hw_cv_func_rename_proper" >&6; } if test "$hw_cv_func_rename_proper" = yes; then : $as_echo "#define HAVE_rename_PROPER 1" >>confdefs.h else post_macros="$post_macros #define rename rpl_rename" fi ac_fn_c_check_decl "$LINENO" "mkdtemp" "ac_cv_have_decl_mkdtemp" "$ac_includes_default" if test "x$ac_cv_have_decl_mkdtemp" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MKDTEMP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strrstr" "ac_cv_have_decl_strrstr" "$ac_includes_default" if test "x$ac_cv_have_decl_strrstr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRRSTR $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "stpncpy" "ac_cv_have_decl_stpncpy" "$ac_includes_default" if test "x$ac_cv_have_decl_stpncpy" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STPNCPY $ac_have_decl _ACEOF for ac_func in seteuid setegid setreuid setregid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in uname gethostname chflags do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in mkfifo statfs statvfs door do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in sysinfo setsid sysconf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getzoneid getzonenamebyid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in fpathconf do : ac_fn_c_check_func "$LINENO" "fpathconf" "ac_cv_func_fpathconf" if test "x$ac_cv_func_fpathconf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FPATHCONF 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_MTIM 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec" "ac_cv_member_struct_stat_st_mtimespec" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_mtimespec" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_MTIMESPEC 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLOCKS 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PRIuMAX/PRIdMAX macros" >&5 $as_echo_n "checking for PRIuMAX/PRIdMAX macros... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #include #if defined(PRIuMAX) && defined(PRIdMAX) primacros_found #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "primacros_found" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Unable to find out how to scan intmax_t/uintmax_t types" >&5 $as_echo "Unable to find out how to scan intmax_t/uintmax_t types" >&6; } fi rm -f conftest* for ac_header in stdarg.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" if test "x$ac_cv_header_stdarg_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDARG_H 1 _ACEOF fi done for ac_header in inttypes.h locale.h stddef.h stdint.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct lconv" "decimal_point" "ac_cv_member_struct_lconv_decimal_point" "#include " if test "x$ac_cv_member_struct_lconv_decimal_point" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_LCONV_DECIMAL_POINT 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct lconv" "thousands_sep" "ac_cv_member_struct_lconv_thousands_sep" "#include " if test "x$ac_cv_member_struct_lconv_thousands_sep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_LCONV_THOUSANDS_SEP 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 $as_echo_n "checking for long double... " >&6; } if ${ac_cv_type_long_double+:} false; then : $as_echo_n "(cached) " >&6 else if test "$GCC" = yes; then ac_cv_type_long_double=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* The Stardent Vistra knows sizeof (long double), but does not support it. */ long double foo = 0.0L; int main () { static int test_array [1 - 2 * !(/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ sizeof (double) <= sizeof (long double))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_long_double=yes else ac_cv_type_long_double=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double" >&5 $as_echo "$ac_cv_type_long_double" >&6; } if test $ac_cv_type_long_double = yes; then $as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 $as_echo_n "checking for long long int... " >&6; } if ${ac_cv_type_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* For now, do not test the preprocessor; as of 2007 there are too many implementations with broken preprocessors. Perhaps this can be revisited in 2012. In the meantime, code should not expect #if to work with literals wider than 32 bits. */ /* Test literals. */ long long int ll = 9223372036854775807ll; long long int nll = -9223372036854775807LL; unsigned long long int ull = 18446744073709551615ULL; /* Test constant expressions. */ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 ? 1 : -1)]; int i = 63; int main () { /* Test availability of runtime routines for shift and division. */ long long int llmax = 9223372036854775807ll; unsigned long long int ullmax = 18446744073709551615ull; return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) | (llmax / ll) | (llmax % ll) | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) | (ullmax / ull) | (ullmax % ull)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if test "$cross_compiling" = yes; then : ac_cv_type_long_long_int=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef LLONG_MAX # define HALF \ (1LL << (sizeof (long long int) * CHAR_BIT - 2)) # define LLONG_MAX (HALF - 1 + HALF) #endif int main () { long long int n = 1; int i; for (i = 0; ; i++) { long long int m = n << i; if (m >> i != n) return 1; if (LLONG_MAX / 2 < m) break; } return 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_type_long_long_int=yes else ac_cv_type_long_long_int=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else ac_cv_type_long_long_int=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 $as_echo "$ac_cv_type_long_long_int" >&6; } if test $ac_cv_type_long_long_int = yes; then $as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 $as_echo_n "checking for unsigned long long int... " >&6; } if ${ac_cv_type_unsigned_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* For now, do not test the preprocessor; as of 2007 there are too many implementations with broken preprocessors. Perhaps this can be revisited in 2012. In the meantime, code should not expect #if to work with literals wider than 32 bits. */ /* Test literals. */ long long int ll = 9223372036854775807ll; long long int nll = -9223372036854775807LL; unsigned long long int ull = 18446744073709551615ULL; /* Test constant expressions. */ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 ? 1 : -1)]; int i = 63; int main () { /* Test availability of runtime routines for shift and division. */ long long int llmax = 9223372036854775807ll; unsigned long long int ullmax = 18446744073709551615ull; return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) | (llmax / ll) | (llmax % ll) | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) | (ullmax / ull) | (ullmax % ull)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_type_unsigned_long_long_int=yes else ac_cv_type_unsigned_long_long_int=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 $as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } if test $ac_cv_type_unsigned_long_long_int = yes; then $as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default" if test "x$ac_cv_type_intmax_t" = xyes; then : $as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h else test $ac_cv_type_long_long_int = yes \ && ac_type='long long int' \ || ac_type='long int' cat >>confdefs.h <<_ACEOF #define intmax_t $ac_type _ACEOF fi ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" if test "x$ac_cv_type_uintmax_t" = xyes; then : $as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h else test $ac_cv_type_unsigned_long_long_int = yes \ && ac_type='unsigned long long int' \ || ac_type='unsigned long int' cat >>confdefs.h <<_ACEOF #define uintmax_t $ac_type _ACEOF fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : $as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h else for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define uintptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTRDIFF_T 1 _ACEOF fi for ac_func in localeconv do : ac_fn_c_check_func "$LINENO" "localeconv" "ac_cv_func_localeconv" if test "x$ac_cv_func_localeconv" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LOCALECONV 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" if test "x$ac_cv_func_vsnprintf" = xyes; then : hw_cv_func_vsnprintf=yes else hw_cv_func_vsnprintf=no fi if test "$hw_cv_func_vsnprintf" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vsnprintf is C99 compliant" >&5 $as_echo_n "checking whether vsnprintf is C99 compliant... " >&6; } if ${hw_cv_func_vsnprintf_c99+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func_vsnprintf_c99=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_STDARG_H #include #endif #include static int testprintf(char *buf, size_t size, const char *format, ...) { int result; va_list ap; va_start(ap, format); result = vsnprintf(buf, size, format, ap); va_end(ap); return result; } int main () { char buf[43]; if (testprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || testprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || testprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ testprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func_vsnprintf_c99=yes else hw_cv_func_vsnprintf_c99=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_vsnprintf_c99" >&5 $as_echo "$hw_cv_func_vsnprintf_c99" >&6; } else hw_cv_func_snprintf_c99=no fi if test "$hw_cv_func_vsnprintf_c99" = yes; then : $as_echo "#define HAVE_VSNPRINTF 1" >>confdefs.h else $as_echo "#define vsnprintf rpl_vsnprintf" >>confdefs.h $as_echo "#define vprintf rpl_vprintf" >>confdefs.h $as_echo "#define vfprintf rpl_vfprintf" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test "x$ac_cv_func_snprintf" = xyes; then : hw_cv_func_snprintf=yes else hw_cv_func_snprintf=no fi if test "$hw_cv_func_snprintf" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf is C99 compliant" >&5 $as_echo_n "checking whether snprintf is C99 compliant... " >&6; } if ${hw_cv_func_snprintf_c99+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func_snprintf_c99=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char buf[43]; if (snprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || snprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || snprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ snprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func_snprintf_c99=yes else hw_cv_func_snprintf_c99=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_snprintf_c99" >&5 $as_echo "$hw_cv_func_snprintf_c99" >&6; } else hw_cv_func_snprintf_c99=no fi if test "$hw_cv_func_snprintf_c99" = yes; then : $as_echo "#define HAVE_SNPRINTF 1" >>confdefs.h else $as_echo "#define snprintf rpl_snprintf" >>confdefs.h $as_echo "#define printf rpl_printf" >>confdefs.h $as_echo "#define fprintf rpl_fprintf" >>confdefs.h fi for ac_header in varargs.h do : ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default" if test "x$ac_cv_header_varargs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VARARGS_H 1 _ACEOF fi done # Don't even bother checking for vasprintf if snprintf was standards # incompliant, this one is going to be too. if test "$hw_cv_func_snprintf_c99" = yes; then : for ac_func in vasprintf do : ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf" if test "x$ac_cv_func_vasprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VASPRINTF 1 _ACEOF hw_cv_func_vasprintf=yes else hw_cv_func_vasprintf=no fi done else hw_cv_func_vasprintf=no fi if test "$hw_cv_func_vasprintf" = no; then : $as_echo "#define vasprintf rpl_vasprintf" >>confdefs.h for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for va_copy" >&5 $as_echo_n "checking for va_copy... " >&6; } if ${hw_cv_func_va_copy+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func_va_copy=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif int main () { va_list ap, aq; va_copy(aq, ap); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func_va_copy=yes else hw_cv_func_va_copy=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_va_copy" >&5 $as_echo "$hw_cv_func_va_copy" >&6; } if test "$hw_cv_func_va_copy" = yes; then : $as_echo "#define HAVE_VA_COPY 1" >>confdefs.h fi if test "$hw_cv_func_va_copy" = no; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __va_copy" >&5 $as_echo_n "checking for __va_copy... " >&6; } if ${hw_cv_func___va_copy+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func___va_copy=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif int main () { va_list ap, aq; __va_copy(aq, ap); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func___va_copy=yes else hw_cv_func___va_copy=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func___va_copy" >&5 $as_echo "$hw_cv_func___va_copy" >&6; } if test "$hw_cv_func___va_copy" = yes; then : $as_echo "#define HAVE___VA_COPY 1" >>confdefs.h fi fi fi # Don't even bother checking for asprintf if snprintf was standards # incompliant, this one is going to be too. if test "$hw_cv_func_snprintf_c99" = yes; then : for ac_func in asprintf do : ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" if test "x$ac_cv_func_asprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ASPRINTF 1 _ACEOF hw_cv_func_asprintf=yes else hw_cv_func_asprintf=no fi done else hw_cv_func_asprintf=no fi if test "$hw_cv_func_asprintf" = no; then : $as_echo "#define asprintf rpl_asprintf" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "$ac_includes_default #ifdef HAVE_DIRENT_H # include #endif " if test "x$ac_cv_have_decl_dirfd" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_DIRFD $ac_have_decl _ACEOF for ac_func in dirfd do : ac_fn_c_check_func "$LINENO" "dirfd" "ac_cv_func_dirfd" if test "x$ac_cv_func_dirfd" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DIRFD 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dirfd macro" >&5 $as_echo_n "checking for dirfd macro... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #ifdef HAVE_DIRENT_H # include #endif #ifdef dirfd dirfd_found #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "dirfd_found" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DIRFD_MACRO_FOUND=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f conftest* fi done for ac_func in jail_get do : ac_fn_c_check_func "$LINENO" "jail_get" "ac_cv_func_jail_get" if test "x$ac_cv_func_jail_get" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_JAIL_GET 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5 $as_echo_n "checking for library containing setsockopt... " >&6; } if ${ac_cv_search_setsockopt+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); int main () { return setsockopt (); ; return 0; } _ACEOF for ac_lib in '' socket; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_setsockopt=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_setsockopt+:} false; then : break fi done if ${ac_cv_search_setsockopt+:} false; then : else ac_cv_search_setsockopt=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5 $as_echo "$ac_cv_search_setsockopt" >&6; } ac_res=$ac_cv_search_setsockopt if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostent" >&5 $as_echo_n "checking for library containing gethostent... " >&6; } if ${ac_cv_search_gethostent+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostent (); int main () { return gethostent (); ; return 0; } _ACEOF for ac_lib in '' nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_gethostent=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_gethostent+:} false; then : break fi done if ${ac_cv_search_gethostent+:} false; then : else ac_cv_search_gethostent=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostent" >&5 $as_echo "$ac_cv_search_gethostent" >&6; } ac_res=$ac_cv_search_gethostent if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi for ac_func in socket do : ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" if test "x$ac_cv_func_socket" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SOCKET 1 _ACEOF fi done for ac_func in setsockopt do : ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" if test "x$ac_cv_func_setsockopt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETSOCKOPT 1 _ACEOF fi done for ac_func in gethostent do : ac_fn_c_check_func "$LINENO" "gethostent" "ac_cv_func_gethostent" if test "x$ac_cv_func_gethostent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETHOSTENT 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" " #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif " if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE 1 _ACEOF fi ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" " #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif " if test "x$ac_cv_have_decl_getaddrinfo" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETADDRINFO $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "inet_ntop" "ac_cv_have_decl_inet_ntop" "#include " if test "x$ac_cv_have_decl_inet_ntop" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_INET_NTOP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" "#include " if test "x$ac_cv_have_decl_inet_pton" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_INET_PTON $ac_have_decl _ACEOF for ac_func in getifaddrs do : ac_fn_c_check_func "$LINENO" "getifaddrs" "ac_cv_func_getifaddrs" if test "x$ac_cv_func_getifaddrs" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETIFADDRS 1 _ACEOF fi done for ac_func in getprocs64 do : ac_fn_c_check_func "$LINENO" "getprocs64" "ac_cv_func_getprocs64" if test "x$ac_cv_func_getprocs64" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPROCS64 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "lchown" "ac_cv_func_lchown" if test "x$ac_cv_func_lchown" = xyes; then : $as_echo "#define HAVE_LCHOWN 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "pthread_attr_setstacksize" "ac_cv_have_decl_pthread_attr_setstacksize" "#include " if test "x$ac_cv_have_decl_pthread_attr_setstacksize" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PTHREAD_ATTR_SETSTACKSIZE $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "pthread_sigmask" "ac_cv_have_decl_pthread_sigmask" "#include " if test "x$ac_cv_have_decl_pthread_sigmask" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PTHREAD_SIGMASK $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "sched_yield" "ac_cv_have_decl_sched_yield" "#include " if test "x$ac_cv_have_decl_sched_yield" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SCHED_YIELD $ac_have_decl _ACEOF for ac_func in sched_yield do : ac_fn_c_check_func "$LINENO" "sched_yield" "ac_cv_func_sched_yield" if test "x$ac_cv_func_sched_yield" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SCHED_YIELD 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "openat" "ac_cv_have_decl_openat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_openat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_OPENAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fstatat" "ac_cv_have_decl_fstatat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_fstatat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FSTATAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fchownat" "ac_cv_have_decl_fchownat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_fchownat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FCHOWNAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fchmodat" "ac_cv_have_decl_fchmodat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_fchmodat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FCHMODAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "readlinkat" "ac_cv_have_decl_readlinkat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_readlinkat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_READLINKAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "log2" "ac_cv_have_decl_log2" "#include " if test "x$ac_cv_have_decl_log2" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOG2 $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "fexecve" "ac_cv_func_fexecve" if test "x$ac_cv_func_fexecve" = xyes; then : $as_echo "#define HAVE_FEXECVE 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "alarm" "ac_cv_have_decl_alarm" "$ac_includes_default" if test "x$ac_cv_have_decl_alarm" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ALARM $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "chmod" "ac_cv_have_decl_chmod" "$ac_includes_default" if test "x$ac_cv_have_decl_chmod" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CHMOD $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "chown" "ac_cv_have_decl_chown" "$ac_includes_default" if test "x$ac_cv_have_decl_chown" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CHOWN $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fchmod" "ac_cv_have_decl_fchmod" "$ac_includes_default" if test "x$ac_cv_have_decl_fchmod" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FCHMOD $ac_have_decl _ACEOF for ac_func in fchmod do : ac_fn_c_check_func "$LINENO" "fchmod" "ac_cv_func_fchmod" if test "x$ac_cv_func_fchmod" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FCHMOD 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "uname" "ac_cv_have_decl_uname" "$ac_includes_default" if test "x$ac_cv_have_decl_uname" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_UNAME $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "getuid" "ac_cv_have_decl_getuid" "$ac_includes_default" if test "x$ac_cv_have_decl_getuid" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETUID $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "getgid" "ac_cv_have_decl_getgid" "$ac_includes_default" if test "x$ac_cv_have_decl_getgid" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETGID $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "lstat" "ac_cv_have_decl_lstat" "$ac_includes_default" if test "x$ac_cv_have_decl_lstat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LSTAT $ac_have_decl _ACEOF for ac_func in sleep do : ac_fn_c_check_func "$LINENO" "sleep" "ac_cv_func_sleep" if test "x$ac_cv_func_sleep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SLEEP 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "socketpair" "ac_cv_have_decl_socketpair" "#include " if test "x$ac_cv_have_decl_socketpair" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SOCKETPAIR $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fsync" "ac_cv_have_decl_fsync" "$ac_includes_default" if test "x$ac_cv_have_decl_fsync" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FSYNC $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "glob" "ac_cv_have_decl_glob" "#include " if test "x$ac_cv_have_decl_glob" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GLOB $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "gettid" "ac_cv_have_decl_gettid" " #define _GNU_SOURCE #include " if test "x$ac_cv_have_decl_gettid" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETTID $ac_have_decl _ACEOF ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" " #include #include " if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_SA_LEN 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct ifreq" "ifr_hwaddr" "ac_cv_member_struct_ifreq_ifr_hwaddr" " #include #include " if test "x$ac_cv_member_struct_ifreq_ifr_hwaddr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_IFREQ_IFR_HWADDR 1 _ACEOF fi for ac_header in sys/sysctl.h do : ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_sysctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SYSCTL_H 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct sysinfo" "uptime" "ac_cv_member_struct_sysinfo_uptime" "#include " if test "x$ac_cv_member_struct_sysinfo_uptime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SYSINFO_UPTIME 1 _ACEOF fi for ac_header in sys/sysctl.h do : ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_sysctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SYSCTL_H 1 _ACEOF fi done for ac_header in kstat.h do : ac_fn_c_check_header_mongrel "$LINENO" "kstat.h" "ac_cv_header_kstat_h" "$ac_includes_default" if test "x$ac_cv_header_kstat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_KSTAT_H 1 _ACEOF fi done for ac_header in utmp.h do : ac_fn_c_check_header_mongrel "$LINENO" "utmp.h" "ac_cv_header_utmp_h" "$ac_includes_default" if test "x$ac_cv_header_utmp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTMP_H 1 _ACEOF fi done for ac_header in utmpx.h do : ac_fn_c_check_header_mongrel "$LINENO" "utmpx.h" "ac_cv_header_utmpx_h" "$ac_includes_default" if test "x$ac_cv_header_utmpx_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTMPX_H 1 _ACEOF fi done for ac_header in linux/fs.h do : ac_fn_c_check_header_mongrel "$LINENO" "linux/fs.h" "ac_cv_header_linux_fs_h" "$ac_includes_default" if test "x$ac_cv_header_linux_fs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LINUX_FS_H 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "FICLONE" "ac_cv_have_decl_FICLONE" "#include " if test "x$ac_cv_have_decl_FICLONE" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FICLONE $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "SEEK_DATA" "ac_cv_have_decl_SEEK_DATA" " #define _GNU_SOURCE #include " if test "x$ac_cv_have_decl_SEEK_DATA" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SEEK_DATA $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "FALLOC_FL_PUNCH_HOLE" "ac_cv_have_decl_FALLOC_FL_PUNCH_HOLE" " #define _GNU_SOURCE #include " if test "x$ac_cv_have_decl_FALLOC_FL_PUNCH_HOLE" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FALLOC_FL_PUNCH_HOLE $ac_have_decl _ACEOF for ac_header in sys/sendfile.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/sendfile.h" "ac_cv_header_sys_sendfile_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sendfile_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SENDFILE_H 1 _ACEOF fi done for ac_func in sendfile do : ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile" if test "x$ac_cv_func_sendfile" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SENDFILE 1 _ACEOF fi done for ac_func in copy_file_range do : ac_fn_c_check_func "$LINENO" "copy_file_range" "ac_cv_func_copy_file_range" if test "x$ac_cv_func_copy_file_range" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_COPY_FILE_RANGE 1 _ACEOF fi done rtry=none { $as_echo "$as_me:${as_lineno-$LINENO}: checking for either struct rtentry or struct ortentry" >&5 $as_echo_n "checking for either struct rtentry or struct ortentry... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "rtentry" >/dev/null 2>&1; then : rtry=rtentry fi rm -f conftest* if test "$rtry" = rtentry; then $as_echo "#define HAVE_RTENTRY 1" >>confdefs.h fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ortentry" >/dev/null 2>&1; then : rtry=ortentry fi rm -f conftest* if test "$rtry" = ortentry; then $as_echo "#define HAVE_ORTENTRY 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rtry" >&5 $as_echo "$rtry" >&6; } for ac_func in llistxattr do : ac_fn_c_check_func "$LINENO" "llistxattr" "ac_cv_func_llistxattr" if test "x$ac_cv_func_llistxattr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LLISTXATTR 1 _ACEOF $as_echo "#define WITH_XATTR 1" >>confdefs.h fi done for ac_header in attr/xattr.h sys/xattr.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr functions have extra arguments" >&5 $as_echo_n "checking whether xattr functions have extra arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { (void)llistxattr("", 0, 0, 0); (void)lgetxattr("", "", 0, 0, 0, 0); (void)lsetxattr("", "", "", 0, 0, 0); (void)lremovexattr("", "", 0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define WITH_XATTR_EXTRA_ARGS 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Check whether --enable-selinux was given. if test "${enable_selinux+set}" = set; then : enableval=$enable_selinux; fi CORE_CPPFLAGS="$LMDB_CPPFLAGS $TOKYOCABINET_CPPFLAGS $QDBM_CPPFLAGS $PCRE2_CPPFLAGS $OPENSSL_CPPFLAGS $SQLITE3_CPPFLAGS $LIBACL_CPPFLAGS $LIBCURL_CPPFLAGS $LIBYAML_CPPFLAGS $POSTGRESQL_CPPFLAGS $MYSQL_CPPFLAGS $LIBXML2_CPPFLAGS $CPPFLAGS $CFECOMPAT_CPPFLAGS" CORE_CFLAGS="$LMDB_CFLAGS $TOKYOCABINET_CFLAGS $QDBM_CFLAGS $PCRE2_CFLAGS $OPENSSL_CFLAGS $SQLITE3_CFLAGS $LIBACL_CFLAGS $LIBCURL_CFLAGS $LIBYAML_CFLAGS $POSTGRESQL_CFLAGS $MYSQL_CFLAGS $LIBXML2_CFLAGS $CFLAGS" CORE_LDFLAGS="$LMDB_LDFLAGS $TOKYOCABINET_LDFLAGS $QDBM_LDFLAGS $PCRE2_LDFLAGS $OPENSSL_LDFLAGS $SQLITE3_LDFLAGS $LIBACL_LDFLAGS $LIBCURL_LDFLAGS $LIBYAML_LDFLAGS $POSTGRESQL_LDFLAGS $MYSQL_LDFLAGS $LIBXML2_LDFLAGS $LDFLAGS" CORE_LIBS="$LMDB_LIBS $TOKYOCABINET_LIBS $QDBM_LIBS $PCRE2_LIBS $OPENSSL_LIBS $SQLITE3_LIBS $LIBACL_LIBS $LIBCURL_LIBS $LIBYAML_LIBS $POSTGRESQL_LIBS $MYSQL_LIBS $LIBXML2_LIBS $LIBS" ac_config_files="$ac_config_files configure_flags.env" case "$target_os" in solaris2.8|solaris2.9) $as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h ;; solaris2.10|solaris2.11) $as_echo "#define _XOPEN_SOURCE 600" >>confdefs.h $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h ;; hpux*|hp-ux*) $as_echo "#define _PSTAT64 1" >>confdefs.h ;; aix*) CPPFLAGS="$CPPFLAGS -w" ;; linux*|*bsd*|*gnu*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yp_get_default_domain in -lnss_nis" >&5 $as_echo_n "checking for yp_get_default_domain in -lnss_nis... " >&6; } if ${ac_cv_lib_nss_nis_yp_get_default_domain+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnss_nis $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char yp_get_default_domain (); int main () { return yp_get_default_domain (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nss_nis_yp_get_default_domain=yes else ac_cv_lib_nss_nis_yp_get_default_domain=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nss_nis_yp_get_default_domain" >&5 $as_echo "$ac_cv_lib_nss_nis_yp_get_default_domain" >&6; } if test "x$ac_cv_lib_nss_nis_yp_get_default_domain" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSS_NIS 1 _ACEOF LIBS="-lnss_nis $LIBS" fi ;; freebsd*|dragonfly*) if true; then FREEBSD_TRUE= FREEBSD_FALSE='#' else FREEBSD_TRUE='#' FREEBSD_FALSE= fi ;; netbsd*) ;; unicos*) ;; cray*) ;; qnx*) ;; openbsd*|obsd*) ;; sysv4.2MP|unix_sv*) ;; cygwin*) ;; mingw*) ;; sco*) ;; darwin*) ;; *) as_fn_error $? "Unknown system type $target_os" "$LINENO" 5 ;; esac # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # # OS kernels conditionals. Don't use those unless it is really needed (if code # depends on the *kernel* feature, and even then -- some kernel features are # shared by different kernels). # # Good example: use LINUX to select code which uses inotify and netlink sockets. # Bad example: use LINUX to select code which parses output of coreutils' ps(1). # if test -n "`echo ${target_os} | grep linux`"; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test -n "`echo ${target_os} | grep darwin`"; then MACOSX_TRUE= MACOSX_FALSE='#' else MACOSX_TRUE='#' MACOSX_FALSE= fi if test -n "`(echo ${target_os} | egrep 'solaris|sunos')`"; then SOLARIS_TRUE= SOLARIS_FALSE='#' else SOLARIS_TRUE='#' SOLARIS_FALSE= fi if test -n "`(echo ${target_os} | egrep 'mingw|cygwin')`"; then NT_TRUE= NT_FALSE='#' else NT_TRUE='#' NT_FALSE= fi if test -n "`(echo ${target_os} | egrep 'cygwin')`"; then CYGWIN_TRUE= CYGWIN_FALSE='#' else CYGWIN_TRUE='#' CYGWIN_FALSE= fi if test -n "`(echo ${target_os} | grep aix)`"; then AIX_TRUE= AIX_FALSE='#' else AIX_TRUE='#' AIX_FALSE= fi if test -n "`(echo ${target_os} | egrep 'hpux|hp-ux')`"; then HPUX_TRUE= HPUX_FALSE='#' else HPUX_TRUE='#' HPUX_FALSE= fi if test -n "`(echo ${target_os} | grep freebsd)`"; then FREEBSD_TRUE= FREEBSD_FALSE='#' else FREEBSD_TRUE='#' FREEBSD_FALSE= fi if test -n "`(echo ${target_os} | grep netbsd)`"; then NETBSD_TRUE= NETBSD_FALSE='#' else NETBSD_TRUE='#' NETBSD_FALSE= fi if test -n "`(echo ${target_os} | grep darwin)`"; then XNU_TRUE= XNU_FALSE='#' else XNU_TRUE='#' XNU_FALSE= fi # Check whether --with-workdir was given. if test "${with_workdir+set}" = set; then : withval=$with_workdir; if test "x$withval" != x ; then WORKDIR="$withval" LOGDIR="$withval" PIDDIR="$withval" fi fi _lcl_receval=""${WORKDIR}"" WORKDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define WORKDIR "${WORKDIR}" _ACEOF workdir="${WORKDIR}" # Check whether --with-masterdir was given. if test "${with_masterdir+set}" = set; then : withval=$with_masterdir; if test "x$withval" != x ; then MASTERDIR="$withval" fi fi _lcl_receval=""${MASTERDIR}"" MASTERDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define MASTERDIR "${MASTERDIR}" _ACEOF masterdir="${MASTERDIR}" # Check whether --with-inputdir was given. if test "${with_inputdir+set}" = set; then : withval=$with_inputdir; if test "x$withval" != x ; then INPUTDIR="$withval" fi fi _lcl_receval=""${INPUTDIR}"" INPUTDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define INPUTDIR "${INPUTDIR}" _ACEOF inputdir="${INPUTDIR}" # Check whether --with-datadir was given. if test "${with_datadir+set}" = set; then : withval=$with_datadir; if test "x$withval" != x ; then DATADIR="$withval" fi fi _lcl_receval=""${DATADIR}"" DATADIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define CF_DATADIR "${DATADIR}" _ACEOF datadir="${DATADIR}" # Check whether --with-logdir was given. if test "${with_logdir+set}" = set; then : withval=$with_logdir; if test "x$withval" != x ; then LOGDIR="$withval" fi fi _lcl_receval=""${LOGDIR}"" LOGDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define LOGDIR "${LOGDIR}" _ACEOF logdir="${LOGDIR}" # Check whether --with-piddir was given. if test "${with_piddir+set}" = set; then : withval=$with_piddir; if test "x$withval" != x ; then PIDDIR="$withval" fi fi _lcl_receval=""${PIDDIR}"" PIDDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define PIDDIR "${PIDDIR}" _ACEOF piddir="${PIDDIR}" # Check whether --with-statedir was given. if test "${with_statedir+set}" = set; then : withval=$with_statedir; if test "x$withval" != x ; then STATEDIR="$withval" fi fi _lcl_receval=""${STATEDIR}"" STATEDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define STATEDIR "${STATEDIR}" _ACEOF statedir="${STATEDIR}" # Check whether --with-shell was given. if test "${with_shell+set}" = set; then : withval=$with_shell; else with_shell=/bin/sh fi _lcl_receval=""${bindir}"" bindir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define BINDIR "${bindir}" _ACEOF bindir="${bindir}" if test "x$with_shell" = "xno"; then as_fn_error $? "Please specify full path to POSIX-compatible shell" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define SHELL_PATH "$with_shell" _ACEOF # Check whether --with-init-script was given. if test "${with_init_script+set}" = set; then : withval=$with_init_script; if test -n "$withval" && test "x$withval" != "xno"; then if test "x$withval" = "xyes"; then case "$target_os" in #( aix*) : INIT_D_PATH=/etc/rc.d/init.d ;; #( hpux*) : INIT_D_PATH=/sbin/init.d ;; #( *) : INIT_D_PATH=/etc/init.d ;; esac else INIT_D_PATH="$withval" fi ac_config_files="$ac_config_files misc/init.d/cfengine3" fi fi if test -n "$INIT_D_PATH"; then WITH_INIT_D_SCRIPT_TRUE= WITH_INIT_D_SCRIPT_FALSE='#' else WITH_INIT_D_SCRIPT_TRUE='#' WITH_INIT_D_SCRIPT_FALSE= fi SYSTEMD_SERVICE_PATH="" # Check whether --with-systemd-service was given. if test "${with_systemd_service+set}" = set; then : withval=$with_systemd_service; if test -n "$withval" && test "x$withval" != "xno"; then if test "x$withval" = "xyes"; then SYSTEMD_SERVICE_PATH=/usr/lib/systemd/system else SYSTEMD_SERVICE_PATH="$withval" fi fi else # Extract the first word of "systemctl", so it can be a program name with args. set dummy systemctl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_systemctl+:} false; then : $as_echo_n "(cached) " >&6 else case $systemctl in [\\/]* | ?:[\\/]*) ac_cv_path_systemctl="$systemctl" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_systemctl="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_systemctl" && ac_cv_path_systemctl="no" ;; esac fi systemctl=$ac_cv_path_systemctl if test -n "$systemctl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $systemctl" >&5 $as_echo "$systemctl" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$systemctl" == "xno"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking Not a systemd system" >&5 $as_echo_n "checking Not a systemd system... " >&6; } else SYSTEMD_SERVICE_PATH=/usr/lib/systemd/system fi fi if test "x$SYSTEMD_SERVICE_PATH" = "x"; then : else ac_config_files="$ac_config_files misc/systemd/cfengine3.service" ac_config_files="$ac_config_files misc/systemd/cf-apache.service" ac_config_files="$ac_config_files misc/systemd/cf-execd.service" ac_config_files="$ac_config_files misc/systemd/cf-hub.service" ac_config_files="$ac_config_files misc/systemd/cf-reactor.service" ac_config_files="$ac_config_files misc/systemd/cf-monitord.service" ac_config_files="$ac_config_files misc/systemd/cf-postgres.service" ac_config_files="$ac_config_files misc/systemd/cf-serverd.service" fi if test -n "$SYSTEMD_SERVICE_PATH"; then WITH_SYSTEMD_SERVICE_TRUE= WITH_SYSTEMD_SERVICE_FALSE='#' else WITH_SYSTEMD_SERVICE_TRUE='#' WITH_SYSTEMD_SERVICE_FALSE= fi # Check whether --with-environment-path was given. if test "${with_environment_path+set}" = set; then : withval=$with_environment_path; fi OS_ENVIRONMENT_PATH= if test -z "$with_environment_path" || test "$with_environment_path" = "yes"; then if test -n "$SYSTEMD_SERVICE_PATH"; then for i in /etc/sysconfig /etc/default; do if test -d $i; then OS_ENVIRONMENT_PATH=$i break fi done if test -z "$OS_ENVIRONMENT_PATH"; then as_fn_error $? "Unable to detect location of environment files on the platform (e.g. '/etc/sysconfig'). Please specify it using --with-environment-path, or turn off systemd support." "$LINENO" 5 fi fi else if test "$with_environment_path" = "no"; then if test -n "$SYSTEMD_SERVICE_PATH"; then as_fn_error $? "It is not possible to both specify systemd support and not provide an environment path with --without-environment-path." "$LINENO" 5 fi else OS_ENVIRONMENT_PATH="$with_environment_path" fi fi # Check whether --with-systemd-socket was given. if test "${with_systemd_socket+set}" = set; then : withval=$with_systemd_socket; else with_systemd_socket=check fi if test "x$with_systemd_service" != xno && test "x$with_systemd_socket" != xno then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_systemd_socket" != xyes && test "x$with_systemd_socket" != xcheck && test "x$with_systemd_socket" != x then test -z "$SYSTEMD_SOCKET_PATH" && SYSTEMD_SOCKET_PATH="$with_systemd_socket" if test "x$with_systemd_socket" != x/usr && test "x$with_systemd_socket" != x/ then test -z "$SYSTEMD_SOCKET_CFLAGS" && SYSTEMD_SOCKET_CFLAGS="" test -z "$SYSTEMD_SOCKET_CPPFLAGS" && SYSTEMD_SOCKET_CPPFLAGS="-I$with_systemd_socket/include" test -z "$SYSTEMD_SOCKET_LDFLAGS" && SYSTEMD_SOCKET_LDFLAGS="-L$with_systemd_socket/lib" fi else SYSTEMD_SOCKET_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $SYSTEMD_SOCKET_CFLAGS" CPPFLAGS="$CPPFLAGS $SYSTEMD_SOCKET_CPPFLAGS" LDFLAGS="$LDFLAGS $SYSTEMD_SOCKET_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sd_listen_fds in -lsystemd" >&5 $as_echo_n "checking for sd_listen_fds in -lsystemd... " >&6; } if ${ac_cv_lib_systemd_sd_listen_fds+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsystemd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sd_listen_fds (); int main () { return sd_listen_fds (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_systemd_sd_listen_fds=yes else ac_cv_lib_systemd_sd_listen_fds=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_sd_listen_fds" >&5 $as_echo "$ac_cv_lib_systemd_sd_listen_fds" >&6; } if test "x$ac_cv_lib_systemd_sd_listen_fds" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSYSTEMD 1 _ACEOF LIBS="-lsystemd $LIBS" else if test "x$with_systemd_socket" != xcheck; then as_fn_error $? "Cannot find systemd library" "$LINENO" 5; fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sd_notify_barrier in -lsystemd" >&5 $as_echo_n "checking for sd_notify_barrier in -lsystemd... " >&6; } if ${ac_cv_lib_systemd_sd_notify_barrier+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsystemd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sd_notify_barrier (); int main () { return sd_notify_barrier (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_systemd_sd_notify_barrier=yes else ac_cv_lib_systemd_sd_notify_barrier=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_sd_notify_barrier" >&5 $as_echo "$ac_cv_lib_systemd_sd_notify_barrier" >&6; } if test "x$ac_cv_lib_systemd_sd_notify_barrier" = xyes; then : $as_echo "#define HAVE_SD_NOTIFY_BARRIER 1" >>confdefs.h fi for ac_header in systemd/sd-daemon.h do : ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default" if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYSTEMD_SD_DAEMON_H 1 _ACEOF else if test "x$with_systemd_socket" != xcheck; then as_fn_error $? "Cannot find systemd headers" "$LINENO" 5; fi fi done # # Pick up any libraries added by tests # test -z "$SYSTEMD_SOCKET_LIBS" && SYSTEMD_SOCKET_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_systemd_socket" != xyes && test "x$with_systemd_socket" != xcheck && test "x$with_systemd_socket" != x/usr && test "x$with_systemd_socket" != x/ then SYSTEMD_SOCKET_LDFLAGS="$SYSTEMD_SOCKET_LDFLAGS -R$with_systemd_socket/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-selinux-policy was given. if test "${with_selinux_policy+set}" = set; then : withval=$with_selinux_policy; else with_selinux_policy=no fi if test "x$with_selinux_policy" != "xno"; then WITH_SELINUX_TRUE= WITH_SELINUX_FALSE='#' else WITH_SELINUX_TRUE='#' WITH_SELINUX_FALSE= fi if test "x$with_selinux_policy" != "xno"; then platform_id=$(sed -r -e '/PLATFORM_ID/!d;s/PLATFORM_ID="platform:([^"]+)"/\1/' < /etc/os-release) if test -f ${srcdir}/misc/selinux/cfengine-enterprise.te.$platform_id; then PLATFORM_SELINUX_POLICIES=cfengine-enterprise.te.$platform_id fi fi # Extract the first word of "hostname", so it can be a program name with args. set dummy hostname; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_HOSTNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $HOSTNAME in [\\/]* | ?:[\\/]*) ac_cv_path_HOSTNAME="$HOSTNAME" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_HOSTNAME="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_HOSTNAME" && ac_cv_path_HOSTNAME="""" ;; esac fi HOSTNAME=$ac_cv_path_HOSTNAME if test -n "$HOSTNAME"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HOSTNAME" >&5 $as_echo "$HOSTNAME" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi cat >>confdefs.h <<_ACEOF #define AUTOCONF_HOSTNAME "`$HOSTNAME`" _ACEOF cat >>confdefs.h <<_ACEOF #define AUTOCONF_SYSNAME "$target_os" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Xen cpuid-based HVM detection" >&5 $as_echo_n "checking for Xen cpuid-based HVM detection... " >&6; } if test x"$GCC" = "xyes"; then case $host_cpu in i[3456]86*|x86_64*|amd64) $as_echo "#define XEN_CPUID_SUPPORT 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Check whether --enable-coverage was given. if test "${enable_coverage+set}" = set; then : enableval=$enable_coverage; use_coverage=$enableval else use_coverage=no fi if test "x$use_coverage" = "xyes"; then if test "$GCC" != "yes"; then as_fn_error $? "GCC is required for --enable-coverage" "$LINENO" 5 fi if test "$debug" != "yes"; then as_fn_error $? "--enable-debug is required for --enable-coverage" "$LINENO" 5 fi # Extract the first word of "lcov", so it can be a program name with args. set dummy lcov; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LCOV+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LCOV"; then ac_cv_prog_LCOV="$LCOV" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LCOV="lcov" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LCOV=$ac_cv_prog_LCOV if test -n "$LCOV"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 $as_echo "$LCOV" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "genhtml", so it can be a program name with args. set dummy genhtml; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LCOV_GENHTML+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LCOV_GENHTML"; then ac_cv_prog_LCOV_GENHTML="$LCOV_GENHTML" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LCOV_GENHTML="genhtml" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LCOV_GENHTML=$ac_cv_prog_LCOV_GENHTML if test -n "$LCOV_GENHTML"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV_GENHTML" >&5 $as_echo "$LCOV_GENHTML" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$LCOV"; then as_fn_error $? "Cannot find lcov from the LTP package" "$LINENO" 5 fi if test -z "$LCOV_GENHTML"; then as_fn_error $? "Could not find genhtml from the LTP package" "$LINENO" 5 fi CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov" # Need to set ENABLE_COVERAGE so that tests/unit/Makefile.am can adapt for one # test which needs gcov stubs if core not built with coverage. if true; then ENABLE_COVERAGE_TRUE= ENABLE_COVERAGE_FALSE='#' else ENABLE_COVERAGE_TRUE='#' ENABLE_COVERAGE_FALSE= fi else if false; then ENABLE_COVERAGE_TRUE= ENABLE_COVERAGE_FALSE='#' else ENABLE_COVERAGE_TRUE='#' ENABLE_COVERAGE_FALSE= fi fi # # Populate contents of config.post.h # ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_control" "ac_cv_member_struct_msghdr_msg_control" "#include #include " if test "x$ac_cv_member_struct_msghdr_msg_control" = xyes; then : $as_echo "#define HAVE_MSGHDR_MSG_CONTROL 1" >>confdefs.h else $as_echo "#define HAVE_NO_MSGHDR_MSG_CONTROL 1" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_accrights" "ac_cv_member_struct_msghdr_msg_accrights" "#include #include " if test "x$ac_cv_member_struct_msghdr_msg_accrights" = xyes; then : $as_echo "#define HAVE_MSGHDR_ACCRIGHTS 1" >>confdefs.h else $as_echo "#define HAVE_NO_MSGHDR_ACCRIGHTS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Summary:" >&5 $as_echo "Summary:" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: > Version: $cfengine_version" >&5 $as_echo "> Version: $cfengine_version" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: > Required libraries" >&5 $as_echo "> Required libraries" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> OpenSSL: $OPENSSL_PATH" >&5 $as_echo "-> OpenSSL: $OPENSSL_PATH" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> PCRE2: $PCRE2_PATH" >&5 $as_echo "-> PCRE2: $PCRE2_PATH" >&6; } if test $WITH_TOKYO = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> DB: Tokyo Cabinet: $TOKYOCABINET_PATH" >&5 $as_echo "-> DB: Tokyo Cabinet: $TOKYOCABINET_PATH" >&6; } elif test $WITH_QDBM = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> DB: QDBM: $QDBM_PATH" >&5 $as_echo "-> DB: QDBM: $QDBM_PATH" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: > Optional libraries" >&5 $as_echo "> Optional libraries" >&6; } if test "x$ac_cv_lib_mysqlclient_mysql_real_connect" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> MySQL connector: $MYSQL_PATH" >&5 $as_echo "-> MySQL connector: $MYSQL_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> MySQL connector: disabled" >&5 $as_echo "-> MySQL connector: disabled" >&6; } fi if test "x$ac_cv_lib_pq_PQconnectdb" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> PostgreSQL connector: $POSTGRESQL_PATH" >&5 $as_echo "-> PostgreSQL connector: $POSTGRESQL_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> PostgreSQL connector: disabled" >&5 $as_echo "-> PostgreSQL connector: disabled" >&6; } fi if test $WITH_LMDB = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> DB: Lightning MDB: $LMDB_PATH" >&5 $as_echo "-> DB: Lightning MDB: $LMDB_PATH" >&6; } elif test $WITH_TOKYO = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> DB: Tokyo Cabinet: $TOKYOCABINET_PATH" >&5 $as_echo "-> DB: Tokyo Cabinet: $TOKYOCABINET_PATH" >&6; } elif test $WITH_QDBM = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> DB: QDBM: $QDBM_PATH" >&5 $as_echo "-> DB: QDBM: $QDBM_PATH" >&6; } fi if test "x$ac_cv_lib_virt_virConnectOpen" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libvirt: $LIBVIRT_PATH" >&5 $as_echo "-> libvirt: $LIBVIRT_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libvirt: disabled" >&5 $as_echo "-> libvirt: disabled" >&6; } fi if test "x$ac_cv_lib_acl_acl_init" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libacl: $LIBACL_PATH" >&5 $as_echo "-> libacl: $LIBACL_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libacl: disabled" >&5 $as_echo "-> libacl: disabled" >&6; } fi if test "x$ac_cv_lib_curl_curl_global_init" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libcurl: $LIBCURL_PATH" >&5 $as_echo "-> libcurl: $LIBCURL_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libcurl: disabled" >&5 $as_echo "-> libcurl: disabled" >&6; } fi if test "x$ac_cv_lib_yaml_yaml_parser_initialize" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libyaml: $LIBYAML_PATH" >&5 $as_echo "-> libyaml: $LIBYAML_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libyaml: disabled" >&5 $as_echo "-> libyaml: disabled" >&6; } fi if test "x$ac_cv_lib_xml2_xmlFirstElementChild" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libxml2: $LIBXML2_PATH" >&5 $as_echo "-> libxml2: $LIBXML2_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libxml2: disabled" >&5 $as_echo "-> libxml2: disabled" >&6; } fi if test "x$users_promises_ok" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> User promises: PAM/user* tools" >&5 $as_echo "-> User promises: PAM/user* tools" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> User promises: disabled" >&5 $as_echo "-> User promises: disabled" >&6; } fi if test "x$enable_builtin_extensions" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Enterprise extensions: Built in" >&5 $as_echo "-> Enterprise extensions: Built in" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Enterprise extensions: Plugin or not included" >&5 $as_echo "-> Enterprise extensions: Plugin or not included" >&6; } fi if test -n "$INIT_D_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> init.d script: $INIT_D_PATH" >&5 $as_echo "-> init.d script: $INIT_D_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> init.d script: disabled" >&5 $as_echo "-> init.d script: disabled" >&6; } fi if test -n "$SYSTEMD_SERVICE_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Systemd service: $SYSTEMD_SERVICE_PATH" >&5 $as_echo "-> Systemd service: $SYSTEMD_SERVICE_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Systemd service: disabled" >&5 $as_echo "-> Systemd service: disabled" >&6; } fi if test -n "$OS_ENVIRONMENT_PATH"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Path of platform environment files: $OS_ENVIRONMENT_PATH" >&5 $as_echo "-> Path of platform environment files: $OS_ENVIRONMENT_PATH" >&6; } fi if test "x$with_selinux_policy" != "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> SELinux policy: enabled" >&5 $as_echo "-> SELinux policy: enabled" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> SELinux platform policies: $PLATFORM_SELINUX_POLICIES" >&5 $as_echo "-> SELinux platform policies: $PLATFORM_SELINUX_POLICIES" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> SELinux policy: disabled" >&5 $as_echo "-> SELinux policy: disabled" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Workdir: $WORKDIR" >&5 $as_echo "-> Workdir: $WORKDIR" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Masterdir: $MASTERDIR" >&5 $as_echo "-> Masterdir: $MASTERDIR" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Inputdir: $INPUTDIR" >&5 $as_echo "-> Inputdir: $INPUTDIR" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Datadir: $DATADIR" >&5 $as_echo "-> Datadir: $DATADIR" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Logdir: $LOGDIR" >&5 $as_echo "-> Logdir: $LOGDIR" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Piddir: $PIDDIR" >&5 $as_echo "-> Piddir: $PIDDIR" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> Statedir: $STATEDIR" >&5 $as_echo "-> Statedir: $STATEDIR" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> bindir: $bindir" >&5 $as_echo "-> bindir: $bindir" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } ac_config_files="$ac_config_files Makefile libcfnet/Makefile libenv/Makefile libpromises/Makefile libcfecompat/Makefile cf-agent/Makefile cf-check/Makefile cf-promises/Makefile cf-execd/Makefile cf-key/Makefile cf-monitord/Makefile cf-upgrade/Makefile cf-runagent/Makefile cf-serverd/Makefile cf-testd/Makefile cf-net/Makefile cf-secret/Makefile config.post.h contrib/vagrant-ci/centos-9s-x64/Makefile misc/Makefile misc/selinux/Makefile python/Makefile ext/Makefile examples/Makefile tests/Makefile tests/acceptance/Makefile tests/acceptance/25_cf-execd/Makefile tests/unit/Makefile tests/load/Makefile tests/static-check/Makefile tests/valgrind-check/Makefile" # Run autoconf/configure in libutils, generating necessary makefiles: subdirs="$subdirs libntech" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILTIN_EXTENSIONS_TRUE}" && test -z "${BUILTIN_EXTENSIONS_FALSE}"; then as_fn_error $? "conditional \"BUILTIN_EXTENSIONS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WINDOWS_TRUE}" && test -z "${WINDOWS_FALSE}"; then as_fn_error $? "conditional \"WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WINDOWS_TRUE}" && test -z "${WINDOWS_FALSE}"; then as_fn_error $? "conditional \"WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NDEBUG_TRUE}" && test -z "${NDEBUG_FALSE}"; then as_fn_error $? "conditional \"NDEBUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_LIBCURL_TRUE}" && test -z "${HAVE_LIBCURL_FALSE}"; then as_fn_error $? "conditional \"HAVE_LIBCURL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_LIBXML2_TRUE}" && test -z "${HAVE_LIBXML2_FALSE}"; then as_fn_error $? "conditional \"HAVE_LIBXML2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVAHI_CLIENT_TRUE}" && test -z "${HAVE_AVAHI_CLIENT_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVAHI_CLIENT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVAHI_CLIENT_TRUE}" && test -z "${HAVE_AVAHI_CLIENT_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVAHI_CLIENT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVAHI_COMMON_TRUE}" && test -z "${HAVE_AVAHI_COMMON_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVAHI_COMMON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVAHI_COMMON_TRUE}" && test -z "${HAVE_AVAHI_COMMON_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVAHI_COMMON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVAHI_CLIENT_TRUE}" && test -z "${HAVE_AVAHI_CLIENT_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVAHI_CLIENT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_AVAHI_COMMON_TRUE}" && test -z "${HAVE_AVAHI_COMMON_FALSE}"; then as_fn_error $? "conditional \"HAVE_AVAHI_COMMON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NO_SYSTEM_GETOPT_H_TRUE}" && test -z "${NO_SYSTEM_GETOPT_H_FALSE}"; then as_fn_error $? "conditional \"NO_SYSTEM_GETOPT_H\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_USERS_PROMISE_DEPS_TRUE}" && test -z "${HAVE_USERS_PROMISE_DEPS_FALSE}"; then as_fn_error $? "conditional \"HAVE_USERS_PROMISE_DEPS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_TRUE}" && test -z "${FREEBSD_FALSE}"; then as_fn_error $? "conditional \"FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MACOSX_TRUE}" && test -z "${MACOSX_FALSE}"; then as_fn_error $? "conditional \"MACOSX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then as_fn_error $? "conditional \"SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NT_TRUE}" && test -z "${NT_FALSE}"; then as_fn_error $? "conditional \"NT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CYGWIN_TRUE}" && test -z "${CYGWIN_FALSE}"; then as_fn_error $? "conditional \"CYGWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AIX_TRUE}" && test -z "${AIX_FALSE}"; then as_fn_error $? "conditional \"AIX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HPUX_TRUE}" && test -z "${HPUX_FALSE}"; then as_fn_error $? "conditional \"HPUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_TRUE}" && test -z "${FREEBSD_FALSE}"; then as_fn_error $? "conditional \"FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NETBSD_TRUE}" && test -z "${NETBSD_FALSE}"; then as_fn_error $? "conditional \"NETBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${XNU_TRUE}" && test -z "${XNU_FALSE}"; then as_fn_error $? "conditional \"XNU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_INIT_D_SCRIPT_TRUE}" && test -z "${WITH_INIT_D_SCRIPT_FALSE}"; then as_fn_error $? "conditional \"WITH_INIT_D_SCRIPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_SYSTEMD_SERVICE_TRUE}" && test -z "${WITH_SYSTEMD_SERVICE_FALSE}"; then as_fn_error $? "conditional \"WITH_SYSTEMD_SERVICE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_SELINUX_TRUE}" && test -z "${WITH_SELINUX_FALSE}"; then as_fn_error $? "conditional \"WITH_SELINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_COVERAGE_TRUE}" && test -z "${ENABLE_COVERAGE_FALSE}"; then as_fn_error $? "conditional \"ENABLE_COVERAGE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_COVERAGE_TRUE}" && test -z "${ENABLE_COVERAGE_FALSE}"; then as_fn_error $? "conditional \"ENABLE_COVERAGE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by cfengine $as_me 3.24.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ cfengine config.status 3.24.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "configure_flags.env") CONFIG_FILES="$CONFIG_FILES configure_flags.env" ;; "misc/init.d/cfengine3") CONFIG_FILES="$CONFIG_FILES misc/init.d/cfengine3" ;; "misc/systemd/cfengine3.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cfengine3.service" ;; "misc/systemd/cf-apache.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cf-apache.service" ;; "misc/systemd/cf-execd.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cf-execd.service" ;; "misc/systemd/cf-hub.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cf-hub.service" ;; "misc/systemd/cf-reactor.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cf-reactor.service" ;; "misc/systemd/cf-monitord.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cf-monitord.service" ;; "misc/systemd/cf-postgres.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cf-postgres.service" ;; "misc/systemd/cf-serverd.service") CONFIG_FILES="$CONFIG_FILES misc/systemd/cf-serverd.service" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libcfnet/Makefile") CONFIG_FILES="$CONFIG_FILES libcfnet/Makefile" ;; "libenv/Makefile") CONFIG_FILES="$CONFIG_FILES libenv/Makefile" ;; "libpromises/Makefile") CONFIG_FILES="$CONFIG_FILES libpromises/Makefile" ;; "libcfecompat/Makefile") CONFIG_FILES="$CONFIG_FILES libcfecompat/Makefile" ;; "cf-agent/Makefile") CONFIG_FILES="$CONFIG_FILES cf-agent/Makefile" ;; "cf-check/Makefile") CONFIG_FILES="$CONFIG_FILES cf-check/Makefile" ;; "cf-promises/Makefile") CONFIG_FILES="$CONFIG_FILES cf-promises/Makefile" ;; "cf-execd/Makefile") CONFIG_FILES="$CONFIG_FILES cf-execd/Makefile" ;; "cf-key/Makefile") CONFIG_FILES="$CONFIG_FILES cf-key/Makefile" ;; "cf-monitord/Makefile") CONFIG_FILES="$CONFIG_FILES cf-monitord/Makefile" ;; "cf-upgrade/Makefile") CONFIG_FILES="$CONFIG_FILES cf-upgrade/Makefile" ;; "cf-runagent/Makefile") CONFIG_FILES="$CONFIG_FILES cf-runagent/Makefile" ;; "cf-serverd/Makefile") CONFIG_FILES="$CONFIG_FILES cf-serverd/Makefile" ;; "cf-testd/Makefile") CONFIG_FILES="$CONFIG_FILES cf-testd/Makefile" ;; "cf-net/Makefile") CONFIG_FILES="$CONFIG_FILES cf-net/Makefile" ;; "cf-secret/Makefile") CONFIG_FILES="$CONFIG_FILES cf-secret/Makefile" ;; "config.post.h") CONFIG_FILES="$CONFIG_FILES config.post.h" ;; "contrib/vagrant-ci/centos-9s-x64/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/vagrant-ci/centos-9s-x64/Makefile" ;; "misc/Makefile") CONFIG_FILES="$CONFIG_FILES misc/Makefile" ;; "misc/selinux/Makefile") CONFIG_FILES="$CONFIG_FILES misc/selinux/Makefile" ;; "python/Makefile") CONFIG_FILES="$CONFIG_FILES python/Makefile" ;; "ext/Makefile") CONFIG_FILES="$CONFIG_FILES ext/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/acceptance/Makefile") CONFIG_FILES="$CONFIG_FILES tests/acceptance/Makefile" ;; "tests/acceptance/25_cf-execd/Makefile") CONFIG_FILES="$CONFIG_FILES tests/acceptance/25_cf-execd/Makefile" ;; "tests/unit/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit/Makefile" ;; "tests/load/Makefile") CONFIG_FILES="$CONFIG_FILES tests/load/Makefile" ;; "tests/static-check/Makefile") CONFIG_FILES="$CONFIG_FILES tests/static-check/Makefile" ;; "tests/valgrind-check/Makefile") CONFIG_FILES="$CONFIG_FILES tests/valgrind-check/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; "misc/init.d/cfengine3":F) chmod +x misc/init.d/cfengine3 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi # # CONFIG_SUBDIRS section. # if test "$no_recursion" != yes; then # Remove --cache-file, --srcdir, and --disable-option-checking arguments # so they do not pile up. ac_sub_configure_args= ac_prev= eval "set x $ac_configure_args" shift for ac_arg do if test -n "$ac_prev"; then ac_prev= continue fi case $ac_arg in -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ | --c=*) ;; --config-cache | -C) ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) ;; --disable-option-checking) ;; *) case $ac_arg in *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_sub_configure_args " '$ac_arg'" ;; esac done # Always prepend --prefix to ensure using the same prefix # in subdir configurations. ac_arg="--prefix=$prefix" case $ac_arg in *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" # Pass --silent if test "$silent" = yes; then ac_sub_configure_args="--silent $ac_sub_configure_args" fi # Always prepend --disable-option-checking to silence warnings, since # different subdirs can have different --enable and --with options. ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue # Do not complain, so a configure script can configure whichever # parts of a large source tree are present. test -d "$srcdir/$ac_dir" || continue ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 $as_echo "$ac_msg" >&6 as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" # Check for guested configure; otherwise get Cygnus style configure. if test -f "$ac_srcdir/configure.gnu"; then ac_sub_configure=$ac_srcdir/configure.gnu elif test -f "$ac_srcdir/configure"; then ac_sub_configure=$ac_srcdir/configure elif test -f "$ac_srcdir/configure.in"; then # This should be Cygnus configure. ac_sub_configure=$ac_aux_dir/configure else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} ac_sub_configure= fi # The recursion is here. if test -n "$ac_sub_configure"; then # Make the cache file name correct relative to the subdirectory. case $cache_file in [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; *) # Relative name. ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 $as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} # The eval makes quoting arguments work. eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 fi cd "$ac_popdir" done fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: DONE: Configuration done. Run make/gmake to build CFEngine Community." >&5 $as_echo "DONE: Configuration done. Run make/gmake to build CFEngine Community." >&6; } cfengine-3.24.2/missing0000755000000000000000000001533015010704300014745 0ustar00rootroot00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/cf-check/0000755000000000000000000000000015010704322015013 5ustar00rootroot00000000000000cfengine-3.24.2/cf-check/observables.h0000644000000000000000000000033715010704253017501 0ustar00rootroot00000000000000#ifndef CF_CHECK_TS_KEY_READ_H #define CF_CHECK_TS_KEY_READ_H #include // copy of libpromises/cf3.defs.h, TODO refactor #define CF_OBSERVABLES 100 char **GetObservableNames(const char *ts_key_path); #endif cfengine-3.24.2/cf-check/repair.c0000644000000000000000000002703515010704253016453 0ustar00rootroot00000000000000#include #include #include #if defined(__MINGW32__) || !defined(LMDB) int repair_main(ARG_UNUSED int argc, ARG_UNUSED const char *const *const argv) { Log(LOG_LEVEL_ERR, "cf-check repair not available on this platform/build"); return 1; } int repair_lmdb_default(ARG_UNUSED bool force) { Log(LOG_LEVEL_INFO, "database repair not available on this platform/build"); return 0; } #else #include #include #include #include #include #include #include #include #include #include #include #include #include static void print_usage(void) { printf("Usage: cf-check repair [-f] [FILE ...]\n"); printf("Example: cf-check repair /var/cfengine/state/cf_lastseen.lmdb\n"); printf("Options:\n" "-f|--force repair LMDB files that look OK\n" "-w|--test-write test writing when checking files\n"); } int remove_files(Seq *files) { assert(files != NULL); size_t corruptions = SeqLength(files); int failures = 0; for (size_t i = 0; i < corruptions; ++i) { const char *filename = SeqAt(files, i); assert(filename != NULL); Log(LOG_LEVEL_INFO, "Removing: '%s'", filename); if (unlink(filename) != 0) { Log(LOG_LEVEL_ERR, "Failed to remove '%s' (%d - %s)", filename, errno, strerror(errno)); ++failures; continue; } char *lock_file = StringConcatenate(2, filename, ".lock"); unlink(lock_file); free(lock_file); lock_file = StringConcatenate(2, filename, "-lock"); unlink(lock_file); free(lock_file); } if (failures != 0) { Log(LOG_LEVEL_ERR, "Failed to remove %d files", failures); } return failures; } static bool record_timestamp(int fd_tstamp) { time_t this_timestamp = time(NULL); lseek(fd_tstamp, 0, SEEK_SET); ssize_t n_written = write(fd_tstamp, &this_timestamp, sizeof(time_t)); if (n_written != sizeof(time_t)) { /* should never happen */ return false; } return true; } /** * @param file LMDB file to repair * @param fd_tstamp An open FD to the repair timestamp file or -1 * * @note If #fd_tstamp != -1 then it is expected to be open and with file locks * taken care of. If #fd_tstamp == -1, this function opens the repair * timestamp file on its own and takes care of the file locks. */ int repair_lmdb_file(const char *file, int fd_tstamp) { int ret; char *dest_file = StringFormat("%s"REPAIR_FILE_EXTENSION, file); FileLock lock = EMPTY_FILE_LOCK; if (fd_tstamp == -1) { char *tstamp_file = StringFormat("%s.repaired", file); int lock_ret = ExclusiveFileLockPath(&lock, tstamp_file, true); /* wait=true */ free(tstamp_file); if (lock_ret < 0) { /* Should never happen because we tried to wait for the lock. */ Log(LOG_LEVEL_ERR, "Failed to acquire lock for the '%s' DB repair timestamp file", file); ret = -1; goto cleanup; } fd_tstamp = lock.fd; } pid_t child_pid = fork(); if (child_pid == 0) { /* child */ /* The process can receive a SIGBUS signal while trying to read a * corrupted LMDB file. This has a special handling in cf-agent and * other processes, but this child process should just die in case of * SIGBUS (which is then detected by the parent and handled * accordingly). */ signal(SIGBUS, SIG_DFL); exit(replicate_lmdb(file, dest_file)); } else { /* parent */ int status; pid_t pid = waitpid(child_pid, &status, 0); if (pid != child_pid) { /* real error that should never happen */ ret = -1; goto cleanup; } if (WIFEXITED(status) && WEXITSTATUS(status) != CF_CHECK_OK && WEXITSTATUS(status) != CF_CHECK_LMDB_CORRUPT_PAGE) { Log(LOG_LEVEL_ERR, "Failed to repair file '%s', removing", file); if (unlink(file) != 0) { Log(LOG_LEVEL_ERR, "Failed to remove file '%s'", file); ret = -1; } else { if (!record_timestamp(fd_tstamp)) { Log(LOG_LEVEL_ERR, "Failed to write the timestamp of repair of the '%s' file", file); } ret = WEXITSTATUS(status); } goto cleanup; } else if (WIFSIGNALED(status)) { Log(LOG_LEVEL_ERR, "Failed to repair file '%s', child process signaled (%d), removing", file, WTERMSIG(status)); if (unlink(file) != 0) { Log(LOG_LEVEL_ERR, "Failed to remove file '%s'", file); ret = -1; } else { if (!record_timestamp(fd_tstamp)) { Log(LOG_LEVEL_ERR, "Failed to write the timestamp of repair of the '%s' file", file); } ret = signal_to_cf_check_code(WTERMSIG(status)); } goto cleanup; } else { /* replication successfull */ Log(LOG_LEVEL_INFO, "Replacing '%s' with the new copy", file); if (rename(dest_file, file) != 0) { Log(LOG_LEVEL_ERR, "Failed to replace file '%s' with the repaired copy: %s", file, strerror(errno)); unlink(dest_file); ret = -1; goto cleanup; } if (!record_timestamp(fd_tstamp)) { Log(LOG_LEVEL_ERR, "Failed to write the timestamp of repair of the '%s' file", file); } ret = 0; } } cleanup: free(dest_file); if (lock.fd != -1) { ExclusiveFileUnlock(&lock, true); /* close=true */ } return ret; } /** * @param file LMDB file to rotate * @param fd_tstamp An open FD to the repair timestamp file or -1 * * @note If #fd_tstamp != -1 then it is expected to be open and with file locks * taken care of. If #fd_tstamp == -1, this function opens the rotation * timestamp file on its own and takes care of the file locks. */ int rotate_lmdb_file(const char *file, int fd_tstamp) { int ret; FileLock lock = EMPTY_FILE_LOCK; if (fd_tstamp == -1) { char *tstamp_file = StringFormat("%s.rotated", file); int lock_ret = ExclusiveFileLockPath(&lock, tstamp_file, true); /* wait=true */ free(tstamp_file); if (lock_ret < 0) { /* Should never happen because we tried to wait for the lock. */ Log(LOG_LEVEL_ERR, "Failed to acquire lock for the '%s' DB repair timestamp file", file); ret = -1; goto cleanup; } fd_tstamp = lock.fd; } time_t now = time(NULL); { char *rotated_file = StringFormat("%s.rotated_%jd", file, (intmax_t) now); ret = rename(file, rotated_file); free(rotated_file); } if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to rotate the '%s' DB file (%s), will be removed instead", file, GetErrorStr()); ret = unlink(file); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to remove the '%s' DB file: %s", file, GetErrorStr()); } } if (ret == 0) { if (!record_timestamp(fd_tstamp)) { Log(LOG_LEVEL_ERR, "Failed to write the timestamp of rotation of the '%s' DB file", file); } } cleanup: if (lock.fd != -1) { ExclusiveFileUnlock(&lock, true); /* close=true */ } return ret; } static int repair_lmdb_files(Seq *files, bool force, bool test_write) { assert(files != NULL); assert(SeqLength(files) > 0); Seq *corrupt; if (force) { corrupt = files; } else { const int corruptions = diagnose_files(files, &corrupt, false, false, test_write); if (corruptions != 0) { assert(corrupt != NULL); Log(LOG_LEVEL_NOTICE, "%d corrupt database%s to fix", corruptions, corruptions != 1 ? "s" : ""); } else { Log(LOG_LEVEL_INFO, "No corrupted LMDB files - nothing to do"); return 0; } } int ret = 0; const size_t length = SeqLength(corrupt); assert(length > 0); backup_files_copy(corrupt); for (size_t i = 0; i < length; ++i) { const char *file = SeqAt(corrupt, i); if (repair_lmdb_file(file, -1) == -1) { ret++; } int usage; if (lmdb_file_needs_rotation(file, &usage)) { if (rotate_lmdb_file(file, -1) != -1) { Log(LOG_LEVEL_INFO, "Rotated '%s' DB with %d%% usage", file, usage); } } } if (!force) { /* see 'if (force)' above */ SeqDestroy(corrupt); } if (ret == 0) { Log(LOG_LEVEL_NOTICE, "Database repair successful"); } else { Log(LOG_LEVEL_ERR, "Database repair failed"); } return ret; } int repair_main(int argc, const char *const *const argv) { bool force = false; bool test_write = false; int i = 1; for (; (i < argc) && (argv[i] != NULL) && (argv[i][0] == '-'); i++) { if (StringMatchesOption(argv[i], "--force", "-f")) { force = true; } else if (StringMatchesOption(argv[i], "--test-write", "-w")) { test_write = true; } else { print_usage(); printf("Unrecognized option: '%s'\n", argv[1]); return 1; } } if (force && test_write) { Log(LOG_LEVEL_WARNING, "Ignoring --test-write due to --force skipping DB checks"); } size_t offset = i; Seq *files = argv_to_lmdb_files(argc, argv, offset); if (files == NULL || SeqLength(files) == 0) { Log(LOG_LEVEL_ERR, "No database files to repair"); return 1; } const int ret = repair_lmdb_files(files, force, test_write); SeqDestroy(files); return ret; } int repair_lmdb_default(bool force) { // This function is used by cf-execd and cf-agent, not cf-check // Consistency checks are not enabled by default (--skip-db-check=yes) // This log message can be changed to verbose if it happens by default: Log(LOG_LEVEL_INFO, "Running internal DB (LMDB) consistency checks"); Seq *files = default_lmdb_files(); if (files == NULL) { // Error message printed default_lmdb_files() return 1; } if (SeqLength(files) == 0) { // First agent run - no LMDB files Log(LOG_LEVEL_INFO, "Skipping local database repair, no lmdb files"); return 0; } const int ret = repair_lmdb_files(files, force, false); SeqDestroy(files); if (ret != 0) { Log(LOG_LEVEL_ERR, "Something went wrong during database repair"); Log(LOG_LEVEL_ERR, "Try running `cf-check repair` manually"); } return ret; } #endif cfengine-3.24.2/cf-check/dump.c0000644000000000000000000004207515010704253016137 0ustar00rootroot00000000000000#include #include #ifdef LMDB #include #include #include #include #include #include // GetStateDir() for usage printout #include // FILE_SEPARATOR #include typedef enum { DUMP_NICE, // Print strings in a nice way, and file specific structs DUMP_PORTABLE, // Portable and unambiguous, structs and raw strings DUMP_SIMPLE, // Fallback mode for arbitrary / unrecognized data DUMP_KEYS, DUMP_VALUES, } dump_mode; static void print_usage(void) { printf("Usage: cf-check dump [-k|-v|-n|-s|-p|-t FILE] [FILE ...]\n"); printf("\n"); printf("\t-k|--keys print only keys\n"); printf("\t-v|--values print only values\n"); printf("\t-n|--nice print strings in a nice way and with database specific awareness\n"); printf("\t-s|--simple print as simple escaped binary data\n"); printf("\t-p|--portable print unambiguously with structs and raw strings\n"); printf("\t-t|--tskey FILE use FILE as list of observables\n"); printf("\tWill use '%s%cts_key' if not specified, or built-in list if no ts_key file is found.\n", GetStateDir(), FILE_SEPARATOR); printf("\n"); printf("Example: cf-check dump /var/cfengine/state/cf_lastseen.lmdb\n"); } static int dump_report_error(const int rc) { printf("err(%d): %s\n", rc, mdb_strerror(rc)); return rc; } static void print_json_string( const char *const data, size_t size, const bool strip_strings) { assert(data != NULL); printf("\""); if (size == 0) { // size 0 is printed unambiguously as empty string "" // An empty C string (size 1) will be printed as "\0" // in all modes (including nice) printf("\""); return; } if (strip_strings) { const size_t len = strnlen(data, size); // We expect the data to either be single byte ("0" or "1"), // or a C-string bool known_data = ((size == 1) || (len == (size - 1)) || (data[size - 1] == '\n')); if (!known_data) { printf("\nError: This database contains unknown binary data - use --simple to print anyway or try on the same OS/architecture the lmdb file was generated on\n"); exit(1); } // Most of what we store are C strings except 1 byte '0' or '1', // and some structs. So in nice mode, we try to default to printing // C strings in a nice way. This means it can be ambiguous (we chop // off the NUL byte sometimes). Use --simple for correct, unambiguous, // uglier output. if (size > 1 && len == (size - 1)) { // Looks like a normal string, let's remove NUL byte (nice mode) size = len; } } Slice unescaped_data = {.data = (void *) data, .size = size}; char *escaped_data = Json5EscapeData(unescaped_data); printf("%s", escaped_data); free(escaped_data); printf("\""); } static void print_struct_lastseen_quality( const MDB_val value, const bool strip_strings) { assert(sizeof(KeyHostSeen) == value.mv_size); if (sizeof(KeyHostSeen) != value.mv_size) { // Fall back to simple printing in release builds: print_json_string(value.mv_data, value.mv_size, strip_strings); } else { // TODO: improve names of struct members in QPoint and KeyHostSeen KeyHostSeen quality; memcpy(&quality, value.mv_data, sizeof(quality)); const time_t lastseen = quality.lastseen; const QPoint Q = quality.Q; bool acknowledged = quality.acknowledged; JsonElement *q_json = JsonObjectCreate(4); JsonObjectAppendReal(q_json, "q", Q.q); JsonObjectAppendReal(q_json, "expect", Q.expect); JsonObjectAppendReal(q_json, "var", Q.var); JsonObjectAppendReal(q_json, "dq", Q.dq); JsonElement *top_json = JsonObjectCreate(2); JsonObjectAppendBool(top_json, "acknowledged", acknowledged); JsonObjectAppendInteger(top_json, "lastseen", lastseen); JsonObjectAppendObject(top_json, "Q", q_json); Writer *w = FileWriter(stdout); JsonWriteCompact(w, top_json); FileWriterDetach(w); JsonDestroy(top_json); } } static void print_struct_lock_data( const MDB_val value, const bool strip_strings) { assert(sizeof(LockData) == value.mv_size); if (sizeof(LockData) != value.mv_size) { // Fall back to simple printing in release builds: print_json_string(value.mv_data, value.mv_size, strip_strings); } else { // TODO: improve names of struct members in LockData LockData lock; memcpy(&lock, value.mv_data, sizeof(lock)); const pid_t pid = lock.pid; const time_t time = lock.time; const time_t process_start_time = lock.process_start_time; JsonElement *json = JsonObjectCreate(3); JsonObjectAppendInteger(json, "pid", pid); JsonObjectAppendInteger(json, "time", time); JsonObjectAppendInteger( json, "process_start_time", process_start_time); Writer *w = FileWriter(stdout); JsonWriteCompact(w, json); FileWriterDetach(w); JsonDestroy(json); } } // Used to print values in /var/cfengine/state/cf_observations.lmdb: static void print_struct_averages( const MDB_val value, const bool strip_strings, const char *tskey_filename) { assert(sizeof(Averages) == value.mv_size); if (sizeof(Averages) != value.mv_size) { // Fall back to simple printing in release builds: print_json_string(value.mv_data, value.mv_size, strip_strings); } else { // TODO: clean up Averages char **obnames = NULL; Averages averages; memcpy(&averages, value.mv_data, sizeof(averages)); const time_t last_seen = averages.last_seen; obnames = GetObservableNames(tskey_filename); JsonElement *all_observables = JsonObjectCreate(CF_OBSERVABLES); for (Observable i = 0; i < CF_OBSERVABLES; ++i) { char *name = obnames[i]; JsonElement *observable = JsonObjectCreate(4); QPoint Q = averages.Q[i]; JsonObjectAppendReal(observable, "q", Q.q); JsonObjectAppendReal(observable, "expect", Q.expect); JsonObjectAppendReal(observable, "var", Q.var); JsonObjectAppendReal(observable, "dq", Q.dq); JsonObjectAppendObject(all_observables, name, observable); free(obnames[i]); } free(obnames); JsonElement *top_json = JsonObjectCreate(2); JsonObjectAppendInteger(top_json, "last_seen", last_seen); JsonObjectAppendObject(top_json, "Q", all_observables); Writer *w = FileWriter(stdout); JsonWriteCompact(w, top_json); FileWriterDetach(w); JsonDestroy(top_json); } } static void print_struct_persistent_class( const MDB_val value, const bool strip_strings) { // Value from db should always be bigger than sizeof struct // Since tags is not counted in sizeof. `tags` is variable size, // and should be at least size 1 (NUL byte) for data to make sense. assert(value.mv_size > sizeof(PersistentClassInfo)); if (value.mv_size <= sizeof(PersistentClassInfo)) { // Fall back to simple printing in release builds: print_json_string(value.mv_data, value.mv_size, strip_strings); } else { /* Make a copy to ensure proper alignment. We cannot just copy data to a * local PersistentClassInfo variable because it contains a * variable-length string at the end (see the struct definition). */ PersistentClassInfo *class_info = xmalloc(value.mv_size); memcpy(class_info, value.mv_data, value.mv_size); const unsigned int expires = class_info->expires; const PersistentClassPolicy policy = class_info->policy; const char *policy_str; switch (policy) { case CONTEXT_STATE_POLICY_RESET: policy_str = "RESET"; break; case CONTEXT_STATE_POLICY_PRESERVE: policy_str = "PRESERVE"; break; default: debug_abort_if_reached(); policy_str = "INTERNAL ERROR"; break; } const char *const tags = class_info->tags; assert(tags > (char *) class_info); const size_t offset = (tags - (char *) class_info); /* (sizeof(unsigned int) + sizeof(PersistentClassPolicy)) is offset without the padding */ assert(offset >= (sizeof(unsigned int) + sizeof(PersistentClassPolicy))); assert(value.mv_size > offset); const size_t str_size = value.mv_size - offset; assert(str_size > 0); if (memchr(tags, '\0', str_size) == NULL) { // String is not terminated, abort or fall back to default: debug_abort_if_reached(); print_json_string(value.mv_data, value.mv_size, strip_strings); free(class_info); return; } // At this point, it should be safe to strdup(tags) JsonElement *top_json = JsonObjectCreate(2); JsonObjectAppendInteger(top_json, "expires", expires); JsonObjectAppendString(top_json, "policy", policy_str); JsonObjectAppendString(top_json, "tags", tags); Writer *w = FileWriter(stdout); JsonWriteCompact(w, top_json); FileWriterDetach(w); JsonDestroy(top_json); free(class_info); } } static void print_struct_or_string( const MDB_val key, const MDB_val value, const char *const file, const bool strip_strings, const bool structs, const char *tskey_filename) { if (structs) { if (StringContains(file, "cf_lastseen.lmdb") && StringStartsWith(key.mv_data, "q")) { print_struct_lastseen_quality(value, strip_strings); } else if (StringContains(file, "cf_lock.lmdb")) { print_struct_lock_data(value, strip_strings); } else if (StringContains(file, "cf_observations.lmdb")) { if (StringEqual(key.mv_data, "DATABASE_AGE")) { assert(sizeof(double) == value.mv_size); double age; memcpy(&age, value.mv_data, sizeof(age)); printf("%f", age); } else { print_struct_averages(value, strip_strings, tskey_filename); } } else if (StringEqual(file, "history.lmdb") || StringEndsWith(file, FILE_SEPARATOR_STR"history.lmdb") || StringEqual(file, "history.lmdb.backup") || StringEndsWith(file, FILE_SEPARATOR_STR"history.lmdb.backup")) { print_struct_averages(value, strip_strings, tskey_filename); } else if (StringContains(file, "cf_state.lmdb")) { print_struct_persistent_class(value, strip_strings); } else if (StringContains(file, "nova_agent_execution.lmdb")) { if (StringEqual(key.mv_data, "delta_gavr")) { assert(sizeof(double) == value.mv_size); double average; memcpy(&average, value.mv_data, sizeof(average)); printf("%f", average); } else if (StringEqual(key.mv_data, "last_exec")) { assert(sizeof(time_t) == value.mv_size); time_t last_exec; memcpy(&last_exec, value.mv_data, sizeof(last_exec)); printf("%ju", (uintmax_t) (last_exec)); } else { debug_abort_if_reached(); } } else { print_json_string(value.mv_data, value.mv_size, strip_strings); } } else { print_json_string(value.mv_data, value.mv_size, strip_strings); } } static void print_line_key_value( const MDB_val key, const MDB_val value, const char *const file, const bool strip_strings, const bool structs, const char *tskey_filename) { printf("\t"); print_json_string(key.mv_data, key.mv_size, strip_strings); printf(": "); print_struct_or_string(key, value, file, strip_strings, structs, tskey_filename); printf(",\n"); } static void print_line_array_element( const MDB_val value, const bool strip_strings) { printf("\t"); print_json_string(value.mv_data, value.mv_size, strip_strings); printf(",\n"); } static void print_opening_bracket(const dump_mode mode) { if (mode == DUMP_VALUES || mode == DUMP_KEYS) { printf("[\n"); } else { printf("{\n"); } } static void print_closing_bracket(const dump_mode mode) { if (mode == DUMP_KEYS || mode == DUMP_VALUES) { printf("]\n"); } else { printf("}\n"); } } static int dump_db(const char *file, const dump_mode mode, const char *tskey_filename) { assert(file != NULL); const bool strip_strings = (mode == DUMP_NICE); const bool structs = (mode == DUMP_NICE || mode == DUMP_PORTABLE); int r; MDB_env *env = NULL; MDB_txn *txn = NULL; MDB_dbi dbi; MDB_cursor *cursor = NULL; if (0 != (r = mdb_env_create(&env)) || 0 != (r = mdb_env_open(env, file, MDB_NOSUBDIR | MDB_RDONLY, 0644)) || 0 != (r = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) || 0 != (r = mdb_open(txn, NULL, 0, &dbi)) || 0 != (r = mdb_cursor_open(txn, dbi, &cursor))) { if (env != NULL) { if (txn != NULL) { if (cursor != NULL) { mdb_cursor_close(cursor); } mdb_txn_abort(txn); } mdb_env_close(env); } return dump_report_error(r); } MDB_val key, value; print_opening_bracket(mode); while ((r = mdb_cursor_get(cursor, &key, &value, MDB_NEXT)) == MDB_SUCCESS) { switch (mode) { case DUMP_NICE: case DUMP_PORTABLE: case DUMP_SIMPLE: print_line_key_value(key, value, file, strip_strings, structs, tskey_filename); break; case DUMP_KEYS: print_line_array_element(key, strip_strings); break; case DUMP_VALUES: print_line_array_element(value, strip_strings); break; default: debug_abort_if_reached(); break; } } print_closing_bracket(mode); if (r != MDB_NOTFOUND) { // At this point, not found is expected, anything else is an error return dump_report_error(r); } mdb_cursor_close(cursor); mdb_close(env, dbi); mdb_txn_abort(txn); mdb_env_close(env); return 0; } static int dump_dbs(Seq *const files, const dump_mode mode, const char *tskey_filename) { assert(files != NULL); const size_t length = SeqLength(files); assert(length > 0); if (length == 1) { return dump_db(SeqAt(files, 0), mode, tskey_filename); } int ret = 0; for (size_t i = 0; i < length; ++i) { const char *const filename = SeqAt(files, i); printf("%s:\n", filename); const int r = dump_db(filename, mode, tskey_filename); if (r != 0) { ret = r; } } return ret; } int dump_main(int argc, const char *const *const argv) { assert(argv != NULL); assert(argc >= 1); dump_mode mode = DUMP_NICE; size_t offset = 1; const char *tskey_filename = NULL; if ((size_t) argc > offset && argv[offset] != NULL && argv[offset][0] == '-') { const char *const option = argv[offset]; offset += 1; if (StringMatchesOption(option, "--keys", "-k")) { mode = DUMP_KEYS; } else if (StringMatchesOption(option, "--values", "-v")) { mode = DUMP_VALUES; } else if (StringMatchesOption(option, "--nice", "-n")) { mode = DUMP_NICE; } else if (StringMatchesOption(option, "--simple", "-s")) { mode = DUMP_SIMPLE; } else if (StringMatchesOption(option, "--portable", "-p")) { mode = DUMP_PORTABLE; } else if (StringMatchesOption(option, "--tskey", "-t")) { tskey_filename = argv[offset]; offset += 1; } else { print_usage(); printf("Unrecognized option: '%s'\n", option); return 1; } } if ((size_t) argc > offset && argv[offset] != NULL && argv[offset][0] == '-') { print_usage(); printf("Only one option supported!\n"); return 1; } Seq *files = argv_to_lmdb_files(argc, argv, offset); const int ret = dump_dbs(files, mode, tskey_filename); SeqDestroy(files); return ret; } #else int dump_main(ARG_UNUSED int argc, ARG_UNUSED const char *const *const argv) { printf("dump only implemented for LMDB.\n"); return 1; } #endif cfengine-3.24.2/cf-check/Makefile.am0000644000000000000000000000433015010704253017052 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-check.la AM_CPPFLAGS = -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libntech/libcompat \ -I$(srcdir)/../libcfecompat \ @CPPFLAGS@ \ $(PCRE2_CPPFLAGS) \ $(LIBYAML_CPPFLAGS) \ $(LMDB_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) AM_CFLAGS = \ @CFLAGS@ \ $(LMDB_CFLAGS) \ $(PCRE2_CFLAGS) \ $(LIBYAML_CFLAGS) \ $(PTHREAD_CFLAGS) AM_LDFLAGS = \ @LDFLAGS@ \ $(PCRE2_LDFLAGS) \ $(LIBYAML_LDFLAGS) \ $(LMDB_LDFLAGS) libcf_check_la_LIBADD = ../libntech/libutils/libutils.la \ ../libcfecompat/libcfecompat.la \ $(LMDB_LIBS) \ $(PCRE2_LIBS) \ $(LIBYAML_LIBS) \ $(PTHREAD_LIBS) \ $(OPENSSL_LIBS) libcf_check_la_SOURCES = \ backup.c backup.h \ cf-check.c \ diagnose.c diagnose.h \ lmdump.c lmdump.h \ db_structs.h \ dump.c dump.h \ utilities.c utilities.h \ repair.c repair.h \ replicate_lmdb.c replicate_lmdb.h \ validate.c validate.h \ observables.c observables.h if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-check # Workaround for automake madness (try removing it if you want to know why). cf_check_CFLAGS = $(AM_CFLAGS) # Build both a libcf-check.la library, and a cf-check executable cf_check_LDADD = libcf-check.la endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-check/cf-check.c0000644000000000000000000001707715010704253016641 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include /* CallCleanupFunctions() */ static void print_version() { printf("cf-check BETA version %s\n", VERSION); } static const char *const CF_CHECK_SHORT_DESCRIPTION = "Utility for diagnosis and repair of local CFEngine databases."; static const char *const CF_CHECK_MANPAGE_LONG_DESCRIPTION = "cf-check does not evaluate policy or rely on the integrity of the\n" "databases. It is intended to be able to detect and repair a corrupt\n" "database."; static const Component COMPONENT = { .name = "cf-check", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const Description COMMANDS[] = { {"help", "Prints general help or per topic", "cf-check help [command]"}, {"diagnose", "Assess the health of one or more database files", "cf-check diagnose"}, {"backup", "Backup database files to a timestamped folder", "cf-check backup"}, {"repair", "Diagnose, then backup and delete any corrupt databases", "cf-check repair"}, {"dump", "Print the contents of a database file", "cf-check dump " WORKDIR "/state/cf_lastseen.lmdb"}, {"lmdump", "LMDB database dumper (deprecated)", "cf-check lmdump -a " WORKDIR "/state/cf_lastseen.lmdb"}, {NULL, NULL, NULL} }; static const struct option OPTIONS[] = { {"help", optional_argument, 0, 'h'}, {"manpage", no_argument, 0, 'M'}, {"version", no_argument, 0, 'V'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"log-level", required_argument, 0, 'g'}, {"inform", no_argument, 0, 'I'}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Print the man page", "Output the version of the software", "Enable debugging output", "Enable verbose output", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Enable basic information output", NULL }; static int CFCheckHelpTopic(const char *topic) { assert(topic != NULL); bool found = false; for (int i = 0; COMMANDS[i].name != NULL; ++i) { if (strcmp(COMMANDS[i].name, topic) == 0) { printf("Command: %s\n", COMMANDS[i].name); printf("Usage: %s\n", COMMANDS[i].usage); printf("Description: %s\n", COMMANDS[i].description); found = true; break; } } // Add more detailed explanation here if necessary: if (strcmp("help", topic) == 0) { printf("\nYou did it, you used the help command!\n"); } else { if (!found) { printf("Unknown help topic: '%s'\n", topic); return EXIT_FAILURE; } } return EXIT_SUCCESS; } int main(int argc, const char *const *argv) { if (StringEndsWith(argv[0], "lmdump")) { // Compatibility mode; act like lmdump if symlinked or renamed: int ret = lmdump_main(argc, argv); CallCleanupFunctions(); return ret; } // When run separately it makes sense for cf-check to have INFO messages LogSetGlobalLevel(LOG_LEVEL_INFO); // In agent, NOTICE log level is default, and cf-check functions // will print less information if (argc < 2) { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, COMMANDS, false, true); FileWriterDetach(w); Log(LOG_LEVEL_ERR, "No command given"); CallCleanupFunctions(); return EXIT_FAILURE; } int c = 0; int start_index = 1; const char *optstr = "+hMg:dvI"; // + means stop for non opt arg. :) while ((c = getopt_long(argc, (char *const *) argv, optstr, OPTIONS, &start_index)) != -1) { switch (c) { case 'd': { LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; } case 'v': { LogSetGlobalLevel(LOG_LEVEL_VERBOSE); break; } case 'I': { LogSetGlobalLevel(LOG_LEVEL_INFO); break; } case 'g': { LogSetGlobalLevelArgOrExit(optarg); break; } case 'V': { print_version(); CallCleanupFunctions(); return EXIT_SUCCESS; break; } case 'h': { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, COMMANDS, false, true); FileWriterDetach(w); CallCleanupFunctions(); return EXIT_SUCCESS; break; } case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-check", time(NULL), CF_CHECK_SHORT_DESCRIPTION, CF_CHECK_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(out); CallCleanupFunctions(); return EXIT_SUCCESS; break; } default: { CallCleanupFunctions(); return EXIT_FAILURE; break; } } } const char *const *const cmd_argv = argv + optind; int cmd_argc = argc - optind; const char *command = cmd_argv[0]; if (StringEqual_IgnoreCase(command, "lmdump")) { int ret = lmdump_main(cmd_argc, cmd_argv); CallCleanupFunctions(); return ret; } if (StringEqual_IgnoreCase(command, "dump")) { int ret = dump_main(cmd_argc, cmd_argv); CallCleanupFunctions(); return ret; } if (StringEqual_IgnoreCase(command, "diagnose")) { int ret = diagnose_main(cmd_argc, cmd_argv); CallCleanupFunctions(); return ret; } if (StringEqual_IgnoreCase(command, "backup")) { int ret = backup_main(cmd_argc, cmd_argv); CallCleanupFunctions(); return ret; } if (StringEqual_IgnoreCase(command, "repair") || StringEqual_IgnoreCase(command, "remediate")) { int ret = repair_main(cmd_argc, cmd_argv); CallCleanupFunctions(); return ret; } if (StringEqual_IgnoreCase(command, "help")) { if (cmd_argc > 2) { Log(LOG_LEVEL_ERR, "help takes exactly 0 or 1 arguments"); CallCleanupFunctions(); return EXIT_FAILURE; } else if (cmd_argc <= 1) { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } else { assert(cmd_argc == 2); CFCheckHelpTopic(cmd_argv[1]); } CallCleanupFunctions(); return EXIT_SUCCESS; } if (StringEqual_IgnoreCase(command, "version")) { print_version(); CallCleanupFunctions(); return EXIT_SUCCESS; } Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); Log(LOG_LEVEL_ERR, "Unrecognized command: '%s'", command); CallCleanupFunctions(); return EXIT_FAILURE; } cfengine-3.24.2/cf-check/utilities.c0000644000000000000000000000144415010704253017200 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include Seq *default_lmdb_files() { const char *state = GetStateDir(); Seq *files = ListDir(state, ".lmdb"); if (files == NULL) { Log(LOG_LEVEL_ERR, "Could not open %s", state); } return files; } Seq *argv_to_lmdb_files( const int argc, const char *const *const argv, const size_t offset) { assert(argc >= 0); if (offset >= (size_t) argc) { Log(LOG_LEVEL_INFO, "No filenames specified, defaulting to .lmdb files in %s", GetStateDir()); return default_lmdb_files(); } return SeqFromArgv(argc - offset, argv + offset); } cfengine-3.24.2/cf-check/db_structs.h0000644000000000000000000001216315010704253017346 0ustar00rootroot00000000000000#ifndef CFENGINE_DB_STRUCTS_H #define CFENGINE_DB_STRUCTS_H // All structs needed for cf-check pretty printing // Structs from libutils are included normally via headers // Structs from libpromises are duplicated; cf-check doesn't use libpromises #include // typedef struct // { // double q; // double expect; // double var; // double dq; // } QPoint; // Struct used for quality entries in /var/cfengine/state/cf_lastseen.lmdb: typedef struct { bool acknowledged; time_t lastseen; QPoint Q; } KeyHostSeen; // Keep in sync with lastseen.h // Struct used for lock entries in /var/cfengine/state/cf_lock.lmdb: typedef struct { pid_t pid; time_t time; time_t process_start_time; } LockData; // Keep in sync with cf3.defs.h #define OBSERVABLES_APPLY(apply_macro) \ apply_macro(users) \ apply_macro(rootprocs) \ apply_macro(otherprocs) \ apply_macro(diskfree) \ apply_macro(loadavg) \ apply_macro(netbiosns_in) \ apply_macro(netbiosns_out) \ apply_macro(netbiosdgm_in) \ apply_macro(netbiosdgm_out) \ apply_macro(netbiosssn_in) \ apply_macro(netbiosssn_out) \ apply_macro(imap_in) \ apply_macro(imap_out) \ apply_macro(cfengine_in) \ apply_macro(cfengine_out) \ apply_macro(nfsd_in) \ apply_macro(nfsd_out) \ apply_macro(smtp_in) \ apply_macro(smtp_out) \ apply_macro(www_in) \ apply_macro(www_out) \ apply_macro(ftp_in) \ apply_macro(ftp_out) \ apply_macro(ssh_in) \ apply_macro(ssh_out) \ apply_macro(wwws_in) \ apply_macro(wwws_out) \ apply_macro(icmp_in) \ apply_macro(icmp_out) \ apply_macro(udp_in) \ apply_macro(udp_out) \ apply_macro(dns_in) \ apply_macro(dns_out) \ apply_macro(tcpsyn_in) \ apply_macro(tcpsyn_out) \ apply_macro(tcpack_in) \ apply_macro(tcpack_out) \ apply_macro(tcpfin_in) \ apply_macro(tcpfin_out) \ apply_macro(tcpmisc_in) \ apply_macro(tcpmisc_out) \ apply_macro(webaccess) \ apply_macro(weberrors) \ apply_macro(syslog) \ apply_macro(messages) \ apply_macro(temp0) \ apply_macro(temp1) \ apply_macro(temp2) \ apply_macro(temp3) \ apply_macro(cpuall) \ apply_macro(cpu0) \ apply_macro(cpu1) \ apply_macro(cpu2) \ apply_macro(cpu3) \ apply_macro(microsoft_ds_in) \ apply_macro(microsoft_ds_out) \ apply_macro(www_alt_in) \ apply_macro(www_alt_out) \ apply_macro(imaps_in) \ apply_macro(imaps_out) \ apply_macro(ldap_in) \ apply_macro(ldap_out) \ apply_macro(ldaps_in) \ apply_macro(ldaps_out) \ apply_macro(mongo_in) \ apply_macro(mongo_out) \ apply_macro(mysql_in) \ apply_macro(mysql_out) \ apply_macro(postgresql_in) \ apply_macro(postgresql_out) \ apply_macro(ipp_in) \ apply_macro(ipp_out) \ apply_macro(spare) // Macros to apply to each element: // Double # useful for creating an identifier, expands to ob_postgresql_in, #define GENERATE_OB_ENUM(OB_NAME) ob_##OB_NAME, // Single # useful for creating string literals, expands to: "postgresql_in", #define GENERATE_OB_STRING(OB_NAME) #OB_NAME, // Use apply macro to generate enum and string array typedef enum Observable { OBSERVABLES_APPLY(GENERATE_OB_ENUM) observables_max } Observable; static const char *const observable_strings[] = { OBSERVABLES_APPLY(GENERATE_OB_STRING) NULL }; // Not the actual count, just the room we set aside in struct (and LMDB): #define CF_OBSERVABLES 100 typedef struct Averages { time_t last_seen; QPoint Q[CF_OBSERVABLES]; } Averages; // Keep in sync with cf3.defs.h typedef enum { CONTEXT_STATE_POLICY_RESET, /* Policy when trying to add already defined persistent states */ CONTEXT_STATE_POLICY_PRESERVE } PersistentClassPolicy; // Keep in sync with cf3.defs.h typedef struct { unsigned int expires; PersistentClassPolicy policy; char tags[]; // variable length, must be zero terminated } PersistentClassInfo; // Keep in sync with cf3.defs.h // Note that tags array does not increase the sizeof() this struct // It allows us to index bytes after the policy variable (plus padding) // As far as C is concerned, tags can be zero length, // we do however require that it is at least 1 (NUL) byte #endif cfengine-3.24.2/cf-check/replicate_lmdb.c0000644000000000000000000001507415010704253020137 0ustar00rootroot00000000000000#include #include #include #include #ifndef LMDB int replicate_lmdb(ARG_UNUSED const char *s_file, ARG_UNUSED const char *d_file) { Log(LOG_LEVEL_ERR, "Database replication only available for LMDB"); return 1; } #else #include typedef struct { const char *s_file; const char *d_file; MDB_txn *s_txn; MDB_txn *d_txn; } LMDBReplicationInfo; static void HandleSrcLMDBCorruption(MDB_env *env, const char *msg) { LMDBReplicationInfo *info = mdb_env_get_userctx(env); Log(LOG_LEVEL_ERR, "Corruption in the source DB '%s' detected! %s", info->s_file, msg); mdb_env_set_assert(env, (MDB_assert_func*) NULL); /* Corruption in the source DB means we cannot read more data from it. But we may have managed to read some data so let's make sure it is properly written to the destination file by committing the writing transaction. */ if (info->d_txn != NULL) { mdb_txn_commit(info->d_txn); } /* The reading transaction should just be aborted. */ if (info->s_txn != NULL) { mdb_txn_abort(info->s_txn); } /* remove files that LMDB creates behind our back */ char *garbage_file = StringFormat("%s-lock", info->d_file); unlink(garbage_file); free(garbage_file); exit(CF_CHECK_LMDB_CORRUPT_PAGE); } static void HandleDstLMDBCorruption(MDB_env *env, const char *msg) { LMDBReplicationInfo *info = mdb_env_get_userctx(env); Log(LOG_LEVEL_ERR, "Corruption in the new DB '%s' detected! %s", info->d_file, msg); mdb_env_set_assert(env, (MDB_assert_func*) NULL); if (info->d_txn != NULL) { mdb_txn_abort(info->d_txn); } if (info->s_txn != NULL) { mdb_txn_abort(info->s_txn); } /* remove files that LMDB creates behind our back */ char *garbage_file = StringFormat("%s-lock", info->d_file); unlink(garbage_file); free(garbage_file); /* This should actually never happen -- how can there be a corruption in a * freshly created LMDB where we are just inserting data? Hence, * UNKNOWN error. */ exit(CF_CHECK_UNKNOWN); } /** * Replicate an LMDB file by reading it's entries and writing them into a new LMDB file. * * @return CFCheckCode code * @WARNING This function can exit the calling process in case of an LMDB * operation failure. */ int replicate_lmdb(const char *s_file, const char *d_file) { MDB_env *s_env = NULL; MDB_txn *s_txn = NULL; MDB_dbi s_dbi; bool close_s_dbi = false; MDB_cursor *s_cursor = NULL; MDB_env *d_env = NULL; MDB_txn *d_txn = NULL; MDB_dbi d_dbi; bool close_d_dbi = false; MDB_cursor *d_cursor = NULL; LMDBReplicationInfo info = { s_file, d_file, NULL, NULL }; int ret = 0; int rc; Log(LOG_LEVEL_INFO, "Replicating '%s' into '%s'", s_file, d_file); rc = mdb_env_create(&s_env); if (rc != 0) { ret = rc; report_mdb_error(s_file, "mdb_env_create", rc); goto cleanup; } mdb_env_set_userctx(s_env, &info); mdb_env_set_assert(s_env, (MDB_assert_func*) HandleSrcLMDBCorruption); /* MDB_NOTLS -- Don't use Thread-Local Storage * Should allow us to use multiple transactions from the same thread (only * one read-write). */ rc = mdb_env_open(s_env, s_file, MDB_NOSUBDIR | MDB_RDONLY | MDB_NOTLS, 0600); if (rc != 0) { ret = rc; report_mdb_error(s_file, "mdb_env_open", rc); goto cleanup; } rc = mdb_txn_begin(s_env, NULL, MDB_RDONLY, &s_txn); if (rc != 0) { ret = rc; report_mdb_error(s_file, "mdb_txn_begin", rc); goto cleanup; } info.s_txn = s_txn; rc = mdb_dbi_open(s_txn, NULL, 0, &s_dbi); if (rc != 0) { ret = rc; report_mdb_error(s_file, "mdb_dbi_open", rc); goto cleanup; } else { close_s_dbi = true; } rc = mdb_cursor_open(s_txn, s_dbi, &s_cursor); if (rc != 0) { ret = rc; report_mdb_error(s_file, "mdb_cursor_open", rc); goto cleanup; } rc = mdb_env_create(&d_env); if (rc != 0) { ret = rc; report_mdb_error(d_file, "mdb_env_create", rc); goto cleanup; } mdb_env_set_userctx(d_env, &info); mdb_env_set_assert(d_env, (MDB_assert_func*) HandleDstLMDBCorruption); rc = mdb_env_open(d_env, d_file, MDB_NOSUBDIR | MDB_NOTLS, 0600); if (rc != 0) { ret = rc; report_mdb_error(d_file, "mdb_env_open", rc); goto cleanup; } rc = mdb_txn_begin(d_env, NULL, 0, &d_txn); if (rc != 0) { ret = rc; report_mdb_error(d_file, "mdb_txn_begin", rc); goto cleanup; } info.d_txn = d_txn; rc = mdb_dbi_open(d_txn, NULL, MDB_CREATE, &d_dbi); if (rc != 0) { ret = rc; report_mdb_error(d_file, "mdb_dbi_open", rc); goto cleanup; } else { close_d_dbi = true; } rc = mdb_cursor_open(d_txn, d_dbi, &d_cursor); if (rc != 0) { ret = rc; report_mdb_error(d_file, "mdb_cursor_open", rc); goto cleanup; } rc = MDB_SUCCESS; while (rc == MDB_SUCCESS) { MDB_val key, data; rc = mdb_cursor_get(s_cursor, &key, &data, MDB_NEXT); /* MDB_NOTFOUND => no more data */ if ((rc != MDB_SUCCESS) && (rc != MDB_NOTFOUND)) { report_mdb_error(s_file, "mdb_cursor_get", rc); ret = rc; } if (rc == MDB_SUCCESS) { rc = mdb_put(d_txn, d_dbi, &key, &data, 0); if (rc != MDB_SUCCESS) { report_mdb_error(d_file, "mdb_put", rc); ret = rc; } } } mdb_txn_commit(d_txn); d_txn = NULL; info.d_txn = NULL; cleanup: if (s_cursor != NULL) { mdb_cursor_close(s_cursor); } if (close_s_dbi) { mdb_close(s_env, s_dbi); } if (s_txn != NULL) { mdb_txn_abort(s_txn); } if (s_env != NULL) { mdb_env_close(s_env); } if (d_cursor != NULL) { mdb_cursor_close(d_cursor); } if (close_d_dbi) { mdb_close(d_env, d_dbi); } if (d_txn != NULL) { mdb_txn_abort(d_txn); } if (d_env != NULL) { mdb_env_close(d_env); } /* remove files that LMDB creates behind our back */ char *garbage_file = StringFormat("%s-lock", d_file); unlink(garbage_file); free(garbage_file); ret = lmdb_errno_to_cf_check_code(ret); return ret; } #endif /* LMDB */ cfengine-3.24.2/cf-check/lmdump.h0000644000000000000000000000054515010704253016471 0ustar00rootroot00000000000000#ifndef __LMDUMP_H__ #define __LMDUMP_H__ #include typedef enum { LMDUMP_KEYS_ASCII, LMDUMP_VALUES_ASCII, LMDUMP_VALUES_HEX, LMDUMP_SIZES, LMDUMP_UNKNOWN } lmdump_mode; lmdump_mode lmdump_char_to_mode(char mode); int lmdump(lmdump_mode mode, const char *file); int lmdump_main(int argc, const char *const *argv); #endif cfengine-3.24.2/cf-check/dump.h0000644000000000000000000000015315010704253016133 0ustar00rootroot00000000000000#ifndef CF_CHECK_DUMP_H #define CF_CHECK_DUMP_H int dump_main(int argc, const char *const *argv); #endif cfengine-3.24.2/cf-check/observables.c0000644000000000000000000000605415010704253017476 0ustar00rootroot00000000000000#include #include #include // CF_BUFSIZE #include // GetStateDir() #include // FILE_SEPARATOR #include // xstrdup() #include // observable_strings #include // StringEqual #include /** * GetObservableNames guarantees to return an array of CF_OBSERVABLES size with * non-NULL strings if using built-in, will generate "observable[n]" name, if * reading ts_key file and the item is "spare" then generating "spare[n]" where * 'n' is the id number which could be helpful in debugging raw observables * data. * * This function is similar to Nova_LoadSlots() in * libpromises/monitoring_read.c If we refactor for dynamic observables instead * of hard coded and limited to 100 then we likely should change here and there * or refactor to have this ts_key read/parse code in one shared place. */ char **GetObservableNames(const char *ts_key_path) { char buf[CF_BUFSIZE]; const char *filename; char **temp = xmalloc(CF_OBSERVABLES * sizeof(char *)); if (ts_key_path == NULL) { snprintf( buf, CF_BUFSIZE - 1, "%s%cts_key", GetStateDir(), FILE_SEPARATOR); filename = buf; } else { filename = ts_key_path; } FILE *f = safe_fopen(filename, "r"); if (f == NULL) { for (int i = 0; i < CF_OBSERVABLES; ++i) { if (i < observables_max) { temp[i] = xstrdup(observable_strings[i]); } else { snprintf(buf, CF_MAXVARSIZE, "observable[%d]", i); temp[i] = xstrdup(buf); } } } else { for (int i = 0; i < CF_OBSERVABLES; ++i) { char line[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE], desc[CF_MAXVARSIZE]; char units[CF_MAXVARSIZE] = "unknown"; double expected_min = 0.0; double expected_max = 100.0; int consolidable = true; if (fgets(line, CF_MAXVARSIZE, f) == NULL) { Log(LOG_LEVEL_ERR, "Error trying to read ts_key from file '%s'. (fgets: %s)", filename, GetErrorStr()); break; } const int fields = sscanf( line, "%*d,%1023[^,],%1023[^,],%1023[^,],%lf,%lf,%d", name, desc, units, &expected_min, &expected_max, &consolidable); if ((fields != 2) && (fields != 6)) { Log(LOG_LEVEL_ERR, "Wrong line format in ts_key: %s", line); } if (StringEqual(name, "spare")) { temp[i] = xstrdup(name); } else { snprintf(buf, CF_MAXVARSIZE, "spare[%d]", i); temp[i] = xstrdup(buf); } } fclose(f); } return temp; } cfengine-3.24.2/cf-check/validate.h0000644000000000000000000000030715010704253016760 0ustar00rootroot00000000000000#ifndef CF_CHECK_VALIDATE_H #define CF_CHECK_VALIDATE_H // Performs validation on single database file // Returns 0 for success, errno code otherwise int CFCheck_Validate(const char *path); #endif cfengine-3.24.2/cf-check/diagnose.h0000644000000000000000000001052415010704253016762 0ustar00rootroot00000000000000#ifndef __DIAGNOSE_H__ #define __DIAGNOSE_H__ #include // Extensions of the errno range, for mixing with lmdb // and operating system error codes #define CF_CHECK_ERRNO_VALIDATE_FAILED -1 // cf-check has one canonical list of error codes // which combines signals, system errno, lmdb errnos and // cf-check specific errors: // clang-format off #define CF_CHECK_RUN_CODES(macro) \ macro(OK) \ macro(OK_DOES_NOT_EXIST) \ macro(SIGNAL_HANGUP) \ macro(SIGNAL_INTERRUPT) \ macro(SIGNAL_QUIT) \ macro(SIGNAL_ILLEGAL_INSTRUCTION) \ macro(SIGNAL_TRACE_TRAP) \ macro(SIGNAL_ABORT) \ macro(SIGNAL_EMULATE_INSTRUCTION) \ macro(SIGNAL_FLOATING_POINT_EXCEPTION) \ macro(SIGNAL_KILL) \ macro(SIGNAL_BUS_ERROR) \ macro(SIGNAL_SEGFAULT) \ macro(SIGNAL_NON_EXISTENT_SYSCALL) \ macro(SIGNAL_INVALID_PIPE) \ macro(SIGNAL_TIMER_EXPIRED) \ macro(SIGNAL_TERMINATE) \ macro(SIGNAL_URGENT_SOCKET_CONDITION) \ macro(SIGNAL_STOP) \ macro(SIGNAL_KEYBOARD_STOP) \ macro(SIGNAL_CONTINUE) \ macro(SIGNAL_CHILD_STATUS_CHANGE) \ macro(SIGNAL_BACKGROUND_READ_ATTEMPT) \ macro(SIGNAL_BACKGROUND_WRITE_ATTEMPT) \ macro(SIGNAL_IO_POSSIBLE_ON_DESCRIPTOR) \ macro(SIGNAL_CPU_TIME_EXCEEDED) \ macro(SIGNAL_FILE_SIZE_EXCEEDED) \ macro(SIGNAL_VIRTUAL_TIME_ALARM) \ macro(SIGNAL_PROFILING_TIMER_ALARM) \ macro(SIGNAL_WINDOW_SIZE_CHANGE) \ macro(SIGNAL_STATUS_REQUEST) \ macro(SIGNAL_OTHER) \ macro(LMDB_KEY_EXISTS) \ macro(LMDB_KEY_NOT_FOUND) \ macro(LMDB_PAGE_NOT_FOUND) \ macro(LMDB_CORRUPT_PAGE) \ macro(LMDB_PANIC_FATAL_ERROR) \ macro(LMDB_VERSION_MISMATCH) \ macro(LMDB_INVALID_DATABASE) \ macro(LMDB_MAP_FULL) \ macro(LMDB_DBS_FULL) \ macro(LMDB_READERS_FULL) \ macro(LMDB_TLS_KEYS_FULL) \ macro(LMDB_TRANSACTION_FULL) \ macro(LMDB_CURSOR_STACK_TOO_DEEP) \ macro(LMDB_PAGE_FULL) \ macro(LMDB_MAP_RESIZE_BEYOND_SIZE) \ macro(LMDB_INCOMPATIBLE_OPERATION) \ macro(LMDB_INVALID_REUSE_OF_READER_LOCKTABLE_SLOT) \ macro(LMDB_BAD_OR_INVALID_TRANSACTION) \ macro(LMDB_WRONG_KEY_OR_VALUE_SIZE) \ macro(LMDB_BAD_DBI) \ macro(LMDUMP_UNKNOWN_ERROR) \ macro(PID_ERROR) \ macro(PERMISSION_ERROR) \ macro(DOES_NOT_EXIST) \ macro(VALIDATE_FAILED) \ macro(UNKNOWN) #define CF_CHECK_MAX CF_CHECK_UNKNOWN #define CF_CHECK_CREATE_ENUM(name) \ CF_CHECK_##name, typedef enum { CF_CHECK_RUN_CODES(CF_CHECK_CREATE_ENUM) } CFCheckCode; // clang-format on int lmdb_errno_to_cf_check_code(int r); int signal_to_cf_check_code(int sig); void report_mdb_error(const char *db_file, const char *op, int rc); bool lmdb_file_needs_rotation(const char *file, int *usage); size_t diagnose_files( const Seq *filenames, Seq **corrupt, bool foreground, bool validate, bool test_write); int diagnose_main(int argc, const char *const *argv); #endif cfengine-3.24.2/cf-check/replicate_lmdb.h0000644000000000000000000000016415010704253020136 0ustar00rootroot00000000000000#ifndef __REPLICATE_H__ #define __REPLICATE_H__ int replicate_lmdb(const char *s_file, const char *d_file); #endif cfengine-3.24.2/cf-check/Makefile.in0000644000000000000000000007176415010704300017073 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-check$(EXEEXT) subdir = cf-check ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libcf_check_la_DEPENDENCIES = ../libntech/libutils/libutils.la \ ../libcfecompat/libcfecompat.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libcf_check_la_OBJECTS = backup.lo cf-check.lo diagnose.lo \ lmdump.lo dump.lo utilities.lo repair.lo replicate_lmdb.lo \ validate.lo observables.lo libcf_check_la_OBJECTS = $(am_libcf_check_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) cf_check_SOURCES = cf-check.c cf_check_OBJECTS = cf_check-cf-check.$(OBJEXT) @BUILTIN_EXTENSIONS_FALSE@cf_check_DEPENDENCIES = libcf-check.la cf_check_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(cf_check_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_check_la_SOURCES) cf-check.c DIST_SOURCES = $(libcf_check_la_SOURCES) cf-check.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-check.la AM_CPPFLAGS = -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libntech/libcompat \ -I$(srcdir)/../libcfecompat \ @CPPFLAGS@ \ $(PCRE2_CPPFLAGS) \ $(LIBYAML_CPPFLAGS) \ $(LMDB_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) AM_CFLAGS = \ @CFLAGS@ \ $(LMDB_CFLAGS) \ $(PCRE2_CFLAGS) \ $(LIBYAML_CFLAGS) \ $(PTHREAD_CFLAGS) AM_LDFLAGS = \ @LDFLAGS@ \ $(PCRE2_LDFLAGS) \ $(LIBYAML_LDFLAGS) \ $(LMDB_LDFLAGS) libcf_check_la_LIBADD = ../libntech/libutils/libutils.la \ ../libcfecompat/libcfecompat.la \ $(LMDB_LIBS) \ $(PCRE2_LIBS) \ $(LIBYAML_LIBS) \ $(PTHREAD_LIBS) \ $(OPENSSL_LIBS) libcf_check_la_SOURCES = \ backup.c backup.h \ cf-check.c \ diagnose.c diagnose.h \ lmdump.c lmdump.h \ db_structs.h \ dump.c dump.h \ utilities.c utilities.h \ repair.c repair.h \ replicate_lmdb.c replicate_lmdb.h \ validate.c validate.h \ observables.c observables.h # Workaround for automake madness (try removing it if you want to know why). @BUILTIN_EXTENSIONS_FALSE@cf_check_CFLAGS = $(AM_CFLAGS) # Build both a libcf-check.la library, and a cf-check executable @BUILTIN_EXTENSIONS_FALSE@cf_check_LDADD = libcf-check.la CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-check/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-check/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-check.la: $(libcf_check_la_OBJECTS) $(libcf_check_la_DEPENDENCIES) $(EXTRA_libcf_check_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_check_la_OBJECTS) $(libcf_check_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-check$(EXEEXT): $(cf_check_OBJECTS) $(cf_check_DEPENDENCIES) $(EXTRA_cf_check_DEPENDENCIES) @rm -f cf-check$(EXEEXT) $(AM_V_CCLD)$(cf_check_LINK) $(cf_check_OBJECTS) $(cf_check_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-check.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_check-cf-check.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diagnose.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmdump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/observables.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repair.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/replicate_lmdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utilities.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validate.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cf_check-cf-check.o: cf-check.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_check_CFLAGS) $(CFLAGS) -MT cf_check-cf-check.o -MD -MP -MF $(DEPDIR)/cf_check-cf-check.Tpo -c -o cf_check-cf-check.o `test -f 'cf-check.c' || echo '$(srcdir)/'`cf-check.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_check-cf-check.Tpo $(DEPDIR)/cf_check-cf-check.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-check.c' object='cf_check-cf-check.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_check_CFLAGS) $(CFLAGS) -c -o cf_check-cf-check.o `test -f 'cf-check.c' || echo '$(srcdir)/'`cf-check.c cf_check-cf-check.obj: cf-check.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_check_CFLAGS) $(CFLAGS) -MT cf_check-cf-check.obj -MD -MP -MF $(DEPDIR)/cf_check-cf-check.Tpo -c -o cf_check-cf-check.obj `if test -f 'cf-check.c'; then $(CYGPATH_W) 'cf-check.c'; else $(CYGPATH_W) '$(srcdir)/cf-check.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_check-cf-check.Tpo $(DEPDIR)/cf_check-cf-check.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-check.c' object='cf_check-cf-check.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_check_CFLAGS) $(CFLAGS) -c -o cf_check-cf-check.obj `if test -f 'cf-check.c'; then $(CYGPATH_W) 'cf-check.c'; else $(CYGPATH_W) '$(srcdir)/cf-check.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-check/validate.c0000644000000000000000000004222515010704253016760 0ustar00rootroot00000000000000#include #include #include #if defined(__MINGW32__) || !defined(LMDB) int CFCheck_Validate(const char *path) { Log(LOG_LEVEL_ERR, "cf-check diagnose --validate not available on this platform/build"); // Cannot include utilities.h on Windows: return -1; // CF_CHECK_ERRNO_VALIDATE_FAILED } #else #include // mdb_open(), mdb_close(), mdb_strerror() #include // xcalloc(), xmemdup(), xstrdup() #include // StringEndsWith() #include // StringMap #include // StringSet #include // CF_CHECK_ERRNO_VALIDATE_FAILED #include // KeyHostSeen #define CF_BIRTH 725846400 // Assume timestamps before 1993-01-01 are corrupt typedef enum ValidatorMode { CF_CHECK_VALIDATE_UNKNOWN, CF_CHECK_VALIDATE_MINIMAL, CF_CHECK_VALIDATE_LOCK, CF_CHECK_VALIDATE_LASTSEEN, } ValidatorMode; typedef struct LastSeenState { StringMap *hostkey_to_address; StringMap *address_to_hostkey; StringSet *quality_outgoing_hostkeys; StringSet *quality_incoming_hostkeys; } LastSeenState; typedef struct ValidatorState { const char *path; ValidatorMode mode; size_t errors; StringSet *keys; Seq *values; union { LastSeenState lastseen; }; } ValidatorState; static Slice *NewLMDBSlice(void *data, size_t size) { assert(data != NULL); Slice *r = xcalloc(1, sizeof(Slice)); r->size = size; if (size == 0) { // don't call xmemdup(malloc inside) which is indeterminate whether // it returns NULL or a valid pointer given size is 0. r->data = NULL; } else { r->data = xmemdup(data, size); } return r; } static void DestroyLMDBSlice(Slice *value) { if (value != NULL) { free(value->data); free(value); } } static void NewValidator(const char *path, ValidatorState *state) { assert(state != NULL); state->path = path; state->errors = 0; state->keys = StringSetNew(); state->values = SeqNew(0, &DestroyLMDBSlice); if (StringEndsWith(path, "cf_lastseen.lmdb")) { state->mode = CF_CHECK_VALIDATE_LASTSEEN; state->lastseen.hostkey_to_address = StringMapNew(); state->lastseen.address_to_hostkey = StringMapNew(); state->lastseen.quality_outgoing_hostkeys = StringSetNew(); state->lastseen.quality_incoming_hostkeys = StringSetNew(); } else if (StringEndsWith(path, "cf_changes.lmdb")) { state->mode = CF_CHECK_VALIDATE_MINIMAL; } else if (StringEndsWith(path, "cf_lock.lmdb")) { state->mode = CF_CHECK_VALIDATE_LOCK; } else { state->mode = CF_CHECK_VALIDATE_UNKNOWN; } } static void DestroyValidator(ValidatorState *state) { // Since state is expected to be stack allocated, we don't allow NULL // pointer. (We normally do for heap allocated data structures). assert(state != NULL); state->path = NULL; StringSetDestroy(state->keys); SeqDestroy(state->values); switch (state->mode) { case CF_CHECK_VALIDATE_LASTSEEN: StringMapDestroy(state->lastseen.hostkey_to_address); StringMapDestroy(state->lastseen.address_to_hostkey); StringSetDestroy(state->lastseen.quality_outgoing_hostkeys); StringSetDestroy(state->lastseen.quality_incoming_hostkeys); break; case CF_CHECK_VALIDATE_MINIMAL: case CF_CHECK_VALIDATE_LOCK: case CF_CHECK_VALIDATE_UNKNOWN: break; default: debug_abort_if_reached(); break; } } static void va_ValidationError( ValidatorState *state, const char *fmt, va_list ap) { assert(state != NULL && state->path != NULL); assert(fmt != NULL); printf("Error in %s: ", state->path); vprintf(fmt, ap); printf("\n"); state->errors += 1; } static void ValidationError(ValidatorState *state, const char *fmt, ...) FUNC_ATTR_PRINTF(2, 3); static void ValidationError(ValidatorState *state, const char *fmt, ...) { va_list ap; va_start(ap, fmt); va_ValidationError(state, fmt, ap); va_end(ap); } static bool ValidateString(ValidatorState *state, MDB_val string) { assert(state != NULL); const char *const str = string.mv_data; if (strnlen(str, string.mv_size) != string.mv_size - 1) { ValidationError(state, "Invalid string - '%s'", str); return false; } if (string.mv_size == 1) { ValidationError(state, "Invalid string - empty"); return false; } return true; } // Should be used after validating that hostkey is a NUL-terminated string static bool ValidateHostkey(ValidatorState *state, const char *hostkey) { if (EmptyString(hostkey)) { // For example a key of "k", missing the "kSHA=..." parts ValidationError(state, "Empty hostkey - '%s'", hostkey); return false; } // Example hostkeys: // MD5=14f11b956431e401ba60861402be3b9c // SHA=e7f1fd5ea18f9d593641f4168d6140ab362f6c02cb1275e41faa17716db457ea if (StringStartsWith(hostkey, "SHA=")) { if (strlen(hostkey + 4) != 64) { ValidationError(state, "Bad length for hostkey - '%s'", hostkey); return false; } } else if (StringStartsWith(hostkey, "MD5=")) { if (strlen(hostkey + 4) != 32) { ValidationError(state, "Bad length for hostkey - '%s'", hostkey); return false; } } else { ValidationError(state, "Unknown format of hostkey - '%s'", hostkey); return false; } return true; } static bool ValidateAddress(ValidatorState *state, const char *address) { if (EmptyString(address)) { // For example a key of "a", missing the "a1.2.3.4" parts ValidationError(state, "Empty IP address - '%s'", address); return false; } return true; } static void UpdateValidatorLastseen( ValidatorState *state, MDB_val key, MDB_val value) { assert(state != NULL); assert(key.mv_size > 0 && key.mv_data != NULL); assert(value.mv_size > 0 && value.mv_data != NULL); const LastSeenState ls = state->lastseen; StringMap *const hostkey_to_address = ls.hostkey_to_address; StringMap *const address_to_hostkey = ls.address_to_hostkey; StringSet *const quality_outgoing_hostkeys = ls.quality_outgoing_hostkeys; StringSet *const quality_incoming_hostkeys = ls.quality_incoming_hostkeys; const char *key_string = key.mv_data; if (StringStartsWith(key_string, "k")) { if (!ValidateString(state, value)) { return; } char *hostkey = xstrdup(key_string + 1); char *address = xstrdup(value.mv_data); // This is an assert, because: // * Only this branch adds to this data structure // * UpdateValidator() has already checked for duplicate keys // (Same applies to the other branches below.) assert(StringMapGet(hostkey_to_address, hostkey) == NULL); StringMapInsert(hostkey_to_address, hostkey, address); } else if (StringStartsWith(key_string, "a")) { if (!ValidateString(state, value)) { return; } char *address = xstrdup(key_string + 1); char *hostkey = xstrdup(value.mv_data); assert(StringMapGet(address_to_hostkey, address) == NULL); StringMapInsert(address_to_hostkey, address, hostkey); } else if (StringStartsWith(key_string, "qo")) { const char *hostkey = key_string + 2; assert(!StringSetContains(quality_outgoing_hostkeys, hostkey)); StringSetAdd(quality_outgoing_hostkeys, xstrdup(hostkey)); } else if (StringStartsWith(key_string, "qi")) { const char *hostkey = key_string + 2; assert(!StringSetContains(quality_incoming_hostkeys, hostkey)); StringSetAdd(quality_incoming_hostkeys, xstrdup(hostkey)); } if (key_string[0] == 'q') { const char direction = key_string[1]; if (direction == 'i' || direction == 'o') { KeyHostSeen data; memcpy(&data, value.mv_data, sizeof(data)); const time_t lastseen = data.lastseen; const time_t current = time(NULL); Log(LOG_LEVEL_DEBUG, "LMDB validation: Quality-entry lastseen time is %ju, current time is %ju", (uintmax_t) lastseen, (uintmax_t) current); if (current < CF_BIRTH) { ValidationError( state, "Current time (%ju) is before 1993-01-01", (uintmax_t) current); } else if (lastseen < CF_BIRTH) { ValidationError( state, "Last seen time (%ju) is before 1993-01-01 (%s)", (uintmax_t) lastseen, key_string); } else if (lastseen > current) { ValidationError( state, "Future timestamp in last seen database: %ju > %ju (%s)", (uintmax_t) lastseen, (uintmax_t) current, key_string); } } else { ValidationError( state, "Unexpected quality-entry key: %s", key_string); } } } static void UpdateValidatorLock( ValidatorState *state, MDB_val key, MDB_val value) { assert(state != NULL); assert(key.mv_size > 0 && key.mv_data != NULL); assert(value.mv_size > 0 && value.mv_data != NULL); const char *key_string = key.mv_data; LockData lock; memcpy(&lock, value.mv_data, sizeof(lock)); const time_t lock_time = lock.time; const time_t current = time(NULL); Log(LOG_LEVEL_DEBUG, "LMDB validation: Lock time is %ju, current time is %ju", (uintmax_t) lock_time, (uintmax_t) current); if (current < CF_BIRTH) { ValidationError( state, "Current time (%ju) is before 1993-01-01", (uintmax_t) current); } else if (lock_time < CF_BIRTH) { ValidationError( state, "Lock time (%ju) is before 1993-01-01 (%s)", (uintmax_t) lock_time, key_string); } else if (lock_time > current) { ValidationError( state, "Future timestamp in lock database: %ju > %ju (%s)", (uintmax_t) lock_time, (uintmax_t) current, key_string); } } static bool ValidateMDBValue( ValidatorState *state, MDB_val value, const char *name) { if (value.mv_data == NULL) { ValidationError(state, "NULL %s", name); return false; } return true; } static void UpdateValidator(ValidatorState *state, MDB_val key, MDB_val value) { assert(state != NULL); if (state->mode == CF_CHECK_VALIDATE_MINIMAL) { // Databases with "weird" schemas, i.e. non-string keys, // just check that we can read out the data: void *key_copy = xmemdup(key.mv_data, key.mv_size); void *value_copy = xmemdup(value.mv_data, value.mv_size); free(key_copy); free(value_copy); return; } if (!ValidateMDBValue(state, key, "key") || !ValidateString(state, key) || !ValidateMDBValue(state, value, "value")) { return; } const char *const key_string = key.mv_data; if (StringSetContains(state->keys, key_string)) { ValidationError(state, "Duplicate key - '%s'", key_string); return; } Log(LOG_LEVEL_DEBUG, "LMDB validation: Adding key '%s'", (const char *) key.mv_data); StringSetAdd(state->keys, xstrdup(key.mv_data)); SeqAppend(state->values, NewLMDBSlice(value.mv_data, value.mv_size)); switch (state->mode) { case CF_CHECK_VALIDATE_LASTSEEN: UpdateValidatorLastseen(state, key, value); break; case CF_CHECK_VALIDATE_LOCK: UpdateValidatorLock(state, key, value); break; case CF_CHECK_VALIDATE_UNKNOWN: break; default: debug_abort_if_reached(); break; } return; } static void ValidateStateLastseen(ValidatorState *state) { const LastSeenState ls = state->lastseen; StringMap *const hostkey_to_address = ls.hostkey_to_address; StringMap *const address_to_hostkey = ls.address_to_hostkey; StringSet *const quality_outgoing_hostkeys = ls.quality_outgoing_hostkeys; StringSet *const quality_incoming_hostkeys = ls.quality_incoming_hostkeys; assert(state != NULL); { MapIterator iter = MapIteratorInit(hostkey_to_address->impl); MapKeyValue *current_item; while ((current_item = MapIteratorNext(&iter)) != NULL) { const char *hostkey = current_item->key; if (!ValidateHostkey(state, hostkey)) { continue; } const char *address = current_item->value; if (!ValidateAddress(state, address)) { continue; } const char *lookup = StringMapGet(address_to_hostkey, address); if (lookup == NULL) { ValidationError( state, "Missing address entry for '%s'", address); } else if (!StringEqual(hostkey, lookup)) { ValidationError( state, "Bad hostkey->address->hostkey reverse lookup '%s' != '%s'", hostkey, lookup); } } } { MapIterator iter = MapIteratorInit(address_to_hostkey->impl); MapKeyValue *current_item; while ((current_item = MapIteratorNext(&iter)) != NULL) { const char *address = current_item->key; if (!ValidateAddress(state, address)) { continue; } const char *hostkey = current_item->value; if (!ValidateHostkey(state, hostkey)) { continue; } const char *lookup = StringMapGet(hostkey_to_address, hostkey); if (lookup == NULL) { ValidationError( state, "Missing hostkey entry for '%s'", hostkey); } else if (!StringEqual(address, lookup)) { ValidationError( state, "Bad address->hostkey->address reverse lookup '%s' != '%s'", address, lookup); } } } { StringSetIterator iter = StringSetIteratorInit(quality_incoming_hostkeys); const char *hostkey; while ((hostkey = StringSetIteratorNext(&iter)) != NULL) { if (StringMapGet(hostkey_to_address, hostkey) == NULL) { ValidationError( state, "Missing hostkey from quality-in entry '%s'", hostkey); } } } { StringSetIterator iter = StringSetIteratorInit(quality_outgoing_hostkeys); const char *hostkey; while ((hostkey = StringSetIteratorNext(&iter)) != NULL) { if (StringMapGet(hostkey_to_address, hostkey) == NULL) { ValidationError( state, "Missing hostkey from quality-out entry '%s'", hostkey); } } } } static void ValidateState(ValidatorState *state) { assert(state != NULL); switch (state->mode) { case CF_CHECK_VALIDATE_LASTSEEN: ValidateStateLastseen(state); case CF_CHECK_VALIDATE_UNKNOWN: case CF_CHECK_VALIDATE_LOCK: case CF_CHECK_VALIDATE_MINIMAL: break; default: debug_abort_if_reached(); break; } } int CFCheck_Validate(const char *path) { assert(path != NULL); MDB_env *env; int rc = mdb_env_create(&env); if (rc != 0) { return rc; } rc = mdb_env_open(env, path, MDB_NOSUBDIR | MDB_RDONLY, 0644); if (rc != 0) { return rc; } MDB_txn *txn; rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (rc != 0) { return rc; } MDB_dbi dbi; rc = mdb_open(txn, NULL, 0, &dbi); if (rc != 0) { return rc; } MDB_cursor *cursor; rc = mdb_cursor_open(txn, dbi, &cursor); if (rc != 0) { return rc; } ValidatorState state; NewValidator(path, &state); MDB_val key, data; while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == MDB_SUCCESS) { UpdateValidator(&state, key, data); } if (rc != MDB_NOTFOUND) { // At this point, not found is expected, anything else is an error DestroyValidator(&state); return rc; } mdb_cursor_close(cursor); mdb_close(env, dbi); mdb_txn_abort(txn); mdb_env_close(env); ValidateState(&state); const size_t errors = state.errors; DestroyValidator(&state); return (errors == 0) ? 0 : CF_CHECK_ERRNO_VALIDATE_FAILED; } #endif cfengine-3.24.2/cf-check/repair.h0000644000000000000000000000044115010704253016450 0ustar00rootroot00000000000000#ifndef __REPAIR_H__ #define __REPAIR_H__ #define REPAIR_FILE_EXTENSION ".copy" int repair_main(int argc, const char *const *argv); int repair_lmdb_default(bool force); int repair_lmdb_file(const char *file, int fd_tstamp); int rotate_lmdb_file(const char *file, int fd_tstamp); #endif cfengine-3.24.2/cf-check/backup.h0000644000000000000000000000024515010704253016435 0ustar00rootroot00000000000000#ifndef __BACKUP_H__ #define __BACKUP_H__ #include int backup_files_copy(Seq *filenames); int backup_main(int argc, const char *const *argv); #endif cfengine-3.24.2/cf-check/utilities.h0000644000000000000000000000051615010704253017204 0ustar00rootroot00000000000000#ifndef __UTILITIES_H__ #define __UTILITIES_H__ #include // These functions should be moved to libutils once cf-check is // implemented and backported. Seq *argv_to_seq(int argc, const char *const *argv); Seq *default_lmdb_files(); Seq *argv_to_lmdb_files(int count, const char *const *files, size_t offset); #endif cfengine-3.24.2/cf-check/backup.c0000644000000000000000000001342315010704253016432 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include /* basename() (on some platforms) */ #include #if defined(__MINGW32__) || !defined(LMDB) int backup_main(ARG_UNUSED int argc, ARG_UNUSED const char *const *const argv) { Log(LOG_LEVEL_ERR, "cf-check backup not available on this platform/build"); return 1; } int backup_files_copy(ARG_UNUSED Seq *filenames) { Log(LOG_LEVEL_INFO, "database backup not available on this platform/build"); return 0; } #else #include static void print_usage(void) { printf("Usage: cf-check backup [-d] [FILE ...]\n"); printf("Example: cf-check backup /var/cfengine/state/cf_lastseen.lmdb\n"); printf("Options: -d|--dump use dump strategy instead of plain copy"); } const char *create_backup_dir() { static char backup_dir[PATH_MAX]; static char backup_root[PATH_MAX]; snprintf( backup_root, PATH_MAX, "%s%c%s%c", GetWorkDir(), FILE_SEPARATOR, "backups", FILE_SEPARATOR); if (mkdir(backup_root, 0700) != 0) { if (errno != EEXIST) { Log(LOG_LEVEL_ERR, "Could not create directory '%s' (%s)", backup_root, strerror(errno)); return NULL; } } time_t ts = time(NULL); if (ts == (time_t)-1) { Log(LOG_LEVEL_ERR, "Could not get current time"); return NULL; } int n = snprintf(backup_dir, PATH_MAX - 1, // trailing slash for later "%s%jd-XXXXXX", backup_root, (intmax_t)ts); if (n >= PATH_MAX) { Log(LOG_LEVEL_ERR, "Backup path too long: %jd/%jd", (intmax_t)n, (intmax_t)PATH_MAX); return NULL; } if (mkdtemp(backup_dir) == NULL) { Log(LOG_LEVEL_ERR, "Could not create directory '%s' (%s)", backup_dir, strerror(errno)); return NULL; } // Add trailing forward slash backup_dir[n++] = FILE_SEPARATOR; backup_dir[n] = '\0'; return backup_dir; } int backup_files_copy(Seq *filenames) { assert(filenames != NULL); const size_t length = SeqLength(filenames); // Attempting to back up 0 files is considered a failure: assert_or_return(length > 0, 1); const char *backup_dir = create_backup_dir(); if (backup_dir == NULL) { // Error already logged return -1; } Log(LOG_LEVEL_INFO, "Backing up to '%s'", backup_dir); int ret = 0; for (size_t i = 0; i < length; ++i) { const char *file = SeqAt(filenames, i); if (!File_CopyToDir(file, backup_dir)) { Log(LOG_LEVEL_ERR, "Copying '%s' failed", file); ret++; } } return ret; } /** * Replicate LMDB files by reading their entries and writing them into new LMDB files. * * @return the number of files that failed to be replicated or -1 in case of * some internal failure */ static int backup_files_replicate(const Seq *files) { assert(files != NULL); const size_t length = SeqLength(files); // Attempting to back up 0 files is considered a failure: assert_or_return(length > 0, 1); const char *backup_dir = create_backup_dir(); Log(LOG_LEVEL_INFO, "Backing up to '%s' using data replication", backup_dir); size_t corrupted = 0; for (size_t i = 0; i < length; ++i) { const char *file = SeqAt(files, i); assert(StringEndsWith(backup_dir, "/")); char *file_copy = xstrdup(file); /* basename() can modify the string */ char *dest_file = StringFormat("%s%s", backup_dir, basename(file_copy)); free(file_copy); pid_t child_pid = fork(); if (child_pid == 0) { /* child */ exit(replicate_lmdb(file, dest_file)); } else { /* parent */ int status; pid_t pid = waitpid(child_pid, &status, 0); if (pid != child_pid) { /* real error that should never happen */ return -1; } if (WIFEXITED(status) && WEXITSTATUS(status) != CF_CHECK_OK && WEXITSTATUS(status) != CF_CHECK_LMDB_CORRUPT_PAGE) { Log(LOG_LEVEL_ERR, "Failed to backup file '%s'", file); corrupted++; } if (WIFSIGNALED(status)) { Log(LOG_LEVEL_ERR, "Failed to backup file '%s', child process signaled (%d)", file, WTERMSIG(status)); corrupted++; } } free(dest_file); } return corrupted; } /** * @return the number of files that failed to be replicated or -1 in case of * some internal failure */ int backup_main(int argc, const char *const *const argv) { size_t offset = 1; bool do_dump = false; if (argc > 1 && argv[1] != NULL && argv[1][0] == '-') { if (StringMatchesOption(argv[1], "--dump", "-d")) { offset++; do_dump = true; } else { print_usage(); printf("Unrecognized option: '%s'\n", argv[1]); return 1; } } Seq *files = argv_to_lmdb_files(argc, argv, offset); if (files == NULL || SeqLength(files) == 0) { Log(LOG_LEVEL_ERR, "No database files to back up"); return 1; } int ret; if (do_dump) { ret = backup_files_replicate(files); } else { ret = backup_files_copy(files); } SeqDestroy(files); return ret; } #endif cfengine-3.24.2/cf-check/lmdump.c0000644000000000000000000000774615010704253016476 0ustar00rootroot00000000000000#include #include #include #ifdef LMDB #include #include #include #include static void lmdump_print_hex(const char *s, size_t len) { for (size_t i = 0; i < len; i++) { printf("%02x", s[i]); } } static void lmdump_print_usage(void) { printf("Lmdb database dumper\n"); printf("Usage: lmdump -d|-x|-a|-A filename\n\n"); printf("Has three modes :\n"); printf(" -A : print keys in ascii form\n"); printf(" -a : print keys and values in ascii form\n"); printf(" -x : print keys and values in hexadecimal form\n"); printf(" -d : print only the size of keys and values\n"); } lmdump_mode lmdump_char_to_mode(char mode) { switch (mode) { case 'A': return LMDUMP_KEYS_ASCII; case 'a': return LMDUMP_VALUES_ASCII; case 'x': return LMDUMP_VALUES_HEX; case 'd': return LMDUMP_SIZES; default: break; } return LMDUMP_UNKNOWN; } static int lmdump_report_error(int rc) { printf("err(%d): %s\n", rc, mdb_strerror(rc)); return rc; } void lmdump_print_line(lmdump_mode mode, MDB_val key, MDB_val data) { assert(mode >= 0 && mode < LMDUMP_UNKNOWN); switch (mode) { case LMDUMP_KEYS_ASCII: printf("key: %p[%d] %.*s\n", key.mv_data, (int) key.mv_size, (int) key.mv_size, (char *) key.mv_data); break; case LMDUMP_VALUES_ASCII: printf("key: %p[%d] %.*s, data: %p[%d] %.*s\n", key.mv_data, (int) key.mv_size, (int) key.mv_size, (char *) key.mv_data, data.mv_data, (int) data.mv_size, (int) data.mv_size, (char *) data.mv_data); break; case LMDUMP_VALUES_HEX: printf("key: %p[%d] ", key.mv_data, (int) key.mv_size); lmdump_print_hex(key.mv_data, (int) key.mv_size); printf(" ,data: %p[%d] ", data.mv_data, (int) data.mv_size); lmdump_print_hex(data.mv_data, (int) data.mv_size); printf("\n"); break; case LMDUMP_SIZES: printf("key: %p[%d] ,data: %p[%d]\n", key.mv_data, (int) key.mv_size, data.mv_data, (int) data.mv_size); break; default: break; } } int lmdump(lmdump_mode mode, const char *file) { assert(mode >= 0 && mode < LMDUMP_UNKNOWN); assert(file != NULL); int rc; MDB_env *env; rc = mdb_env_create(&env); if (rc) return lmdump_report_error(rc); rc = mdb_env_open(env, file, MDB_NOSUBDIR | MDB_RDONLY, 0644); if (rc) return lmdump_report_error(rc); MDB_txn *txn; rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (rc) return lmdump_report_error(rc); MDB_dbi dbi; rc = mdb_open(txn, NULL, 0, &dbi); if (rc) return lmdump_report_error(rc); MDB_cursor *cursor; rc = mdb_cursor_open(txn, dbi, &cursor); if (rc) return lmdump_report_error(rc); MDB_val key, data; while ( (rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == MDB_SUCCESS ) { lmdump_print_line(mode, key, data); } if (rc != MDB_NOTFOUND) { // At this point, not found is expected, anything else is an error return lmdump_report_error(rc); } mdb_cursor_close(cursor); mdb_close(env, dbi); mdb_txn_abort(txn); mdb_env_close(env); return 0; } int lmdump_main(int argc, const char *const *const argv) { assert(argv != NULL); if (argc != 3 || argv[1][0] != '-') { lmdump_print_usage(); return 1; } const char *filename = argv[2]; const lmdump_mode mode = lmdump_char_to_mode(argv[1][1]); if (mode == LMDUMP_UNKNOWN) { lmdump_print_usage(); return 1; } return lmdump(mode, filename); } #else int lmdump_main(ARG_UNUSED int argc, ARG_UNUSED const char *const *const argv) { printf("lmdump only implemented for LMDB.\n"); return 1; } #endif cfengine-3.24.2/cf-check/diagnose.c0000644000000000000000000004460315010704253016762 0ustar00rootroot00000000000000#include #include #include #if defined(__MINGW32__) || !defined(LMDB) int diagnose_main( ARG_UNUSED int argc, ARG_UNUSED const char *const *const argv) { Log(LOG_LEVEL_ERR, "cf-check diagnose not available on this platform/build"); return 1; } size_t diagnose_files( ARG_UNUSED const Seq *filenames, ARG_UNUSED Seq **corrupt, ARG_UNUSED bool foreground, ARG_UNUSED bool validate, ARG_UNUSED bool test_write) { Log(LOG_LEVEL_INFO, "database diagnosis not available on this platform/build"); return 0; } #else #include #include #include #include #include #include #include #include #include #include #include #include /* NOTE: Must be in sync with LMDB_MAXSIZE in libpromises/dbm_lmdb.c. */ #ifndef LMDB_MAXSIZE #define LMDB_MAXSIZE 104857600 #endif #define CF_CHECK_CREATE_STRING(name) \ #name, static const char *CF_CHECK_STR[] = { CF_CHECK_RUN_CODES(CF_CHECK_CREATE_STRING) }; static bool code_is_errno(int r) { return (r > CF_CHECK_MAX); } // Better strerror, returns NULL if it doesn't know. static const char *strerror_or_null(int r) { const char *strerror_string = strerror(r); if (strerror_string == NULL) { return NULL; } const char *unknown = "Unknown error"; if (strncmp(strerror_string, unknown, strlen(unknown)) == 0) { return NULL; } return strerror_string; } static int errno_to_code(int r) { assert(r != 0); return r + CF_CHECK_MAX; } static int code_to_errno(int r) { assert(code_is_errno(r)); return r - CF_CHECK_MAX; } static const char *CF_CHECK_STRING(int code) { static char unknown[1024]; if (code <= 0 || code < CF_CHECK_MAX) { return CF_CHECK_STR[code]; } else if (code_is_errno(code)) // code > CF_CHECK_MAX { code = code_to_errno(code); const char *str = strerror_or_null(code); if (str == NULL) { str = "Unknown"; } snprintf(unknown, sizeof(unknown), "SYSTEM_ERROR %d - %s", code, str); return unknown; } return CF_CHECK_STR[CF_CHECK_UNKNOWN]; } int signal_to_cf_check_code(int sig) { switch (sig) { case SIGHUP: return CF_CHECK_SIGNAL_HANGUP; case SIGINT: return CF_CHECK_SIGNAL_INTERRUPT; case SIGQUIT: return CF_CHECK_SIGNAL_QUIT; case SIGILL: return CF_CHECK_SIGNAL_ILLEGAL_INSTRUCTION; case SIGTRAP: return CF_CHECK_SIGNAL_TRACE_TRAP; case SIGABRT: return CF_CHECK_SIGNAL_ABORT; case SIGFPE: return CF_CHECK_SIGNAL_FLOATING_POINT_EXCEPTION; case SIGKILL: return CF_CHECK_SIGNAL_KILL; case SIGBUS: return CF_CHECK_SIGNAL_BUS_ERROR; case SIGSEGV: return CF_CHECK_SIGNAL_SEGFAULT; case SIGSYS: return CF_CHECK_SIGNAL_NON_EXISTENT_SYSCALL; case SIGPIPE: return CF_CHECK_SIGNAL_INVALID_PIPE; case SIGALRM: return CF_CHECK_SIGNAL_TIMER_EXPIRED; case SIGTERM: return CF_CHECK_SIGNAL_TERMINATE; case SIGURG: return CF_CHECK_SIGNAL_URGENT_SOCKET_CONDITION; case SIGSTOP: return CF_CHECK_SIGNAL_STOP; case SIGTSTP: return CF_CHECK_SIGNAL_KEYBOARD_STOP; case SIGCONT: return CF_CHECK_SIGNAL_CONTINUE; case SIGCHLD: return CF_CHECK_SIGNAL_CHILD_STATUS_CHANGE; case SIGTTIN: return CF_CHECK_SIGNAL_BACKGROUND_READ_ATTEMPT; case SIGTTOU: return CF_CHECK_SIGNAL_BACKGROUND_WRITE_ATTEMPT; case SIGIO: return CF_CHECK_SIGNAL_IO_POSSIBLE_ON_DESCRIPTOR; case SIGXCPU: return CF_CHECK_SIGNAL_CPU_TIME_EXCEEDED; case SIGXFSZ: return CF_CHECK_SIGNAL_FILE_SIZE_EXCEEDED; case SIGVTALRM: return CF_CHECK_SIGNAL_VIRTUAL_TIME_ALARM; case SIGPROF: return CF_CHECK_SIGNAL_PROFILING_TIMER_ALARM; case SIGWINCH: return CF_CHECK_SIGNAL_WINDOW_SIZE_CHANGE; // Some signals are present on OS X / BSD but not Ubuntu 14, omitting: // case SIGEMT: // return CF_CHECK_SIGNAL_EMULATE_INSTRUCTION; // case SIGINFO: // return CF_CHECK_SIGNAL_STATUS_REQUEST; default: break; } return CF_CHECK_SIGNAL_OTHER; } int lmdb_errno_to_cf_check_code(int r) { switch (r) { case 0: return CF_CHECK_OK; // LMDB-specific error codes: case MDB_KEYEXIST: return CF_CHECK_LMDB_KEY_EXISTS; case MDB_NOTFOUND: return CF_CHECK_LMDB_KEY_NOT_FOUND; case MDB_PAGE_NOTFOUND: return CF_CHECK_LMDB_PAGE_NOT_FOUND; case MDB_CORRUPTED: return CF_CHECK_LMDB_CORRUPT_PAGE; case MDB_PANIC: return CF_CHECK_LMDB_PANIC_FATAL_ERROR; case MDB_VERSION_MISMATCH: return CF_CHECK_LMDB_VERSION_MISMATCH; case MDB_INVALID: return CF_CHECK_LMDB_INVALID_DATABASE; case MDB_MAP_FULL: return CF_CHECK_LMDB_MAP_FULL; case MDB_DBS_FULL: return CF_CHECK_LMDB_DBS_FULL; case MDB_READERS_FULL: return CF_CHECK_LMDB_READERS_FULL; case MDB_TLS_FULL: return CF_CHECK_LMDB_TLS_KEYS_FULL; case MDB_TXN_FULL: return CF_CHECK_LMDB_TRANSACTION_FULL; case MDB_CURSOR_FULL: return CF_CHECK_LMDB_CURSOR_STACK_TOO_DEEP; case MDB_PAGE_FULL: return CF_CHECK_LMDB_PAGE_FULL; case MDB_MAP_RESIZED: return CF_CHECK_LMDB_MAP_RESIZE_BEYOND_SIZE; case MDB_INCOMPATIBLE: return CF_CHECK_LMDB_INCOMPATIBLE_OPERATION; case MDB_BAD_RSLOT: return CF_CHECK_LMDB_INVALID_REUSE_OF_READER_LOCKTABLE_SLOT; case MDB_BAD_TXN: return CF_CHECK_LMDB_BAD_OR_INVALID_TRANSACTION; case MDB_BAD_VALSIZE: return CF_CHECK_LMDB_WRONG_KEY_OR_VALUE_SIZE; // cf-check specific error codes: case CF_CHECK_ERRNO_VALIDATE_FAILED: return CF_CHECK_VALIDATE_FAILED; // Doesn't exist in earlier versions of LMDB: // case MDB_BAD_DBI: // return CF_CHECK_LMDB_BAD_DBI; default: break; } const int s = errno_to_code(r); if (s == CF_CHECK_UNKNOWN) { return CF_CHECK_LMDUMP_UNKNOWN_ERROR; } return s; } void report_mdb_error(const char *db_file, const char *op, int rc) { Log(LOG_LEVEL_ERR, "%s: %s error(%d): %s\n", db_file, op, rc, mdb_strerror(rc)); } static int diagnose(const char *path, bool temporary_redirect, bool validate) { // At this point we are already forked, we just need to decide 2 things: // * Should output be redirected (to prevent spam)? // * Which inner diagnose / validation function should be called? int ret; if (validate) { // --validate has meaningful output, so we don't want to redirect // regardless of whether it's foreground or forked. ret = CFCheck_Validate(path); } else if (temporary_redirect) { // --no-fork mode: temporarily redirect output to /dev/null & restore // Only done when necessary as it might not be so portable (/dev/fd) int saved_stdout = dup(STDOUT_FILENO); FILE *const f_result = freopen("/dev/null", "w", stdout); if (f_result == NULL) { return errno; } assert(f_result == stdout); ret = lmdump(LMDUMP_VALUES_ASCII, path); fflush(stdout); dup2(saved_stdout, STDOUT_FILENO); } else { // Normal mode: redirect to /dev/null permanently (forked process) FILE *const f_result = freopen("/dev/null", "w", stdout); if (f_result == NULL) { return errno; } assert(f_result == stdout); fclose(f_result); ret = lmdump(LMDUMP_VALUES_ASCII, path); } return lmdb_errno_to_cf_check_code(ret); } static int diagnose_write(const char *path) { MDB_env *env = NULL; MDB_txn *txn = NULL; MDB_dbi dbi; bool close_dbi = false; MDB_cursor *cursor = NULL; /* We need to initialize these to NULL here so that we can safely call * free() on them in cleanup. */ MDB_val new_key, new_data; new_key.mv_data = NULL; new_data.mv_data = NULL; int ret = 0; int rc; Log(LOG_LEVEL_INFO, "Trying to write data into '%s'", path); rc = mdb_env_create(&env); if (rc != MDB_SUCCESS) { ret = rc; report_mdb_error(path, "mdb_env_create", rc); goto cleanup; } rc = mdb_env_open(env, path, MDB_NOSUBDIR, 0600); if (rc != MDB_SUCCESS) { ret = rc; report_mdb_error(path, "mdb_env_open", rc); goto cleanup; } rc = mdb_txn_begin(env, NULL, 0, &txn); if (rc != MDB_SUCCESS) { ret = rc; report_mdb_error(path, "mdb_txn_begin", rc); goto cleanup; } rc = mdb_dbi_open(txn, NULL, 0, &dbi); if (rc != MDB_SUCCESS) { ret = rc; report_mdb_error(path, "mdb_dbi_open", rc); goto cleanup; } else { close_dbi = true; } rc = mdb_cursor_open(txn, dbi, &cursor); if (rc != MDB_SUCCESS) { ret = rc; report_mdb_error(path, "mdb_cursor_open", rc); goto cleanup; } MDB_val key, data; rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT); /* MDB_NOTFOUND => no more data */ if (rc == MDB_NOTFOUND) { Log(LOG_LEVEL_INFO, "'%s' is empty, no data to use as a template, cannot test writing", path); ret = 0; goto cleanup; } else if (rc != MDB_SUCCESS) { report_mdb_error(path, "mdb_cursor_get", rc); ret = rc; goto cleanup; } /* else */ new_key.mv_size = key.mv_size; new_data.mv_size = data.mv_size; new_key.mv_data = xmalloc(new_key.mv_size); new_data.mv_data = xmalloc(new_data.mv_size); rc = RAND_bytes((char *) new_key.mv_data, new_key.mv_size); if (rc != 1) { Log(LOG_LEVEL_ERR, "Failed to generate random key data"); ret = -1; goto cleanup; } rc = RAND_bytes((char *) new_data.mv_data, new_data.mv_size); if (rc != 1) { Log(LOG_LEVEL_ERR, "Failed to generate random value data"); ret = -1; goto cleanup; } rc = mdb_put(txn, dbi, &new_key, &new_data, 0); if (rc != MDB_SUCCESS) { report_mdb_error(path, "mdb_put", rc); Log(LOG_LEVEL_ERR, "Failed to write new data into '%s'", path); ret = rc; goto cleanup; } rc = mdb_txn_commit(txn); if (rc != MDB_SUCCESS) { report_mdb_error(path, "mdb_txn_commit", rc); Log(LOG_LEVEL_ERR, "Failed to commit new data into '%s'", path); ret = rc; goto cleanup; } txn = NULL; mdb_close(env, dbi); close_dbi = false; rc = mdb_txn_begin(env, NULL, 0, &txn); if (rc != MDB_SUCCESS) { ret = rc; report_mdb_error(path, "mdb_txn_begin", rc); goto cleanup; } rc = mdb_dbi_open(txn, NULL, 0, &dbi); if (rc != MDB_SUCCESS) { ret = rc; report_mdb_error(path, "mdb_dbi_open", rc); goto cleanup; } else { close_dbi = true; } rc = mdb_del(txn, dbi, &new_key, NULL); if (rc != MDB_SUCCESS) { report_mdb_error(path, "mdb_del", rc); Log(LOG_LEVEL_ERR, "Failed to delete new data from '%s'", path); ret = rc; goto cleanup; } rc = mdb_txn_commit(txn); if (rc != MDB_SUCCESS) { report_mdb_error(path, "mdb_txn_commit", rc); Log(LOG_LEVEL_ERR, "Failed to commit removal of new data from '%s'", path); ret = rc; goto cleanup; } txn = NULL; mdb_close(env, dbi); close_dbi = false; cleanup: free(new_key.mv_data); free(new_data.mv_data); if (cursor != NULL) { mdb_cursor_close(cursor); } if (close_dbi) { mdb_close(env, dbi); } if (txn != NULL) { mdb_txn_abort(txn); } if (env != NULL) { mdb_env_close(env); } ret = lmdb_errno_to_cf_check_code(ret); return ret; } static int fork_and_diagnose(const char *path, bool validate, bool test_write) { const pid_t child_pid = fork(); if (child_pid == 0) { // Child /* The second argument is 'temporary_redirect' and we require a * temporary redirect if we want to test writability because that * produces output. */ int r = diagnose(path, test_write, validate); if ((r == CF_CHECK_OK) && test_write) { r = diagnose_write(path); } exit(r); } else { // Parent int status; pid_t pid = waitpid(child_pid, &status, 0); if (pid != child_pid) { return CF_CHECK_PID_ERROR; } if (WIFEXITED(status) && WEXITSTATUS(status) != CF_CHECK_OK) { return WEXITSTATUS(status); } if (WIFSIGNALED(status)) { return signal_to_cf_check_code(WTERMSIG(status)); } } return CF_CHECK_OK; } static char *follow_symlink(const char *path) { char target_buf[4096] = { 0 }; const ssize_t r = readlink(path, target_buf, sizeof(target_buf)); if (r < 0) { return NULL; } if ((size_t) r >= sizeof(target_buf)) { Log(LOG_LEVEL_ERR, "Symlink target path too long: %s", path); return NULL; } target_buf[r] = '\0'; return xstrdup(target_buf); } bool lmdb_file_needs_rotation(const char *file, int *usage) { struct stat sb; if (stat(file, &sb) == 0) { int usage_pct = (((float) sb.st_size) / LMDB_MAXSIZE) * 100; if (usage != NULL) { *usage = usage_pct; } return (usage_pct >= 95); } else { Log(LOG_LEVEL_ERR, "Failed to stat() '%s' when checking usage: %s", file, GetErrorStr()); return false; } } /** * @param[in] filenames DB files to diagnose/check * @param[out] corrupt place to store the resulting sequence of corrupted * files or %NULL (to only get the number of corrupted * files) * @param[in] foreground whether to run in foreground or fork (safer) * @param[in] test_write whether to test writing into the DB * @return the number of the corrupted files */ size_t diagnose_files( const Seq *filenames, Seq **corrupt, bool foreground, bool validate, bool test_write) { size_t corruptions = 0; const size_t length = SeqLength(filenames); if (corrupt != NULL) { *corrupt = SeqNew(length, free); } for (size_t i = 0; i < length; ++i) { const char *filename = SeqAt(filenames, i); const char *symlink = NULL; // Only initialized because of gcc warning int r = 0; // Only initialized because of LGTM alert char *symlink_target = follow_symlink(filename); bool broken_symlink_handled = false; if (symlink_target != NULL) { symlink = filename; // If the LMDB file path is a symlink filename = symlink_target; if (access(symlink_target, F_OK) != 0) { // Symlink target file does not exist r = CF_CHECK_OK_DOES_NOT_EXIST; broken_symlink_handled = true; } // If this is not the case, continue repair as normal, // using the symlink target instead of the symlink in diagnose // and repair functions } if (broken_symlink_handled) { // The LMDB database was a broken symlink, // we don't need to do anything, agent will recreate it. } else if (foreground) { r = diagnose(filename, true, validate); if ((r == CF_CHECK_OK) && test_write) { r = diagnose_write(filename); } } else { r = fork_and_diagnose(filename, validate, test_write); } if (symlink_target != NULL) { int usage; bool needs_rotation = lmdb_file_needs_rotation(symlink_target, &usage); Log(LOG_LEVEL_INFO, "Status of '%s' -> '%s': %s [%d%% usage%s]\n", symlink, symlink_target, CF_CHECK_STRING(r), usage, needs_rotation ? ", needs rotation" : ""); } else { int usage; bool needs_rotation = lmdb_file_needs_rotation(filename, &usage); Log(LOG_LEVEL_INFO, "Status of '%s': %s [%d%% usage%s]\n", filename, CF_CHECK_STRING(r), usage, needs_rotation ? ", needs rotation" : ""); } if (r != CF_CHECK_OK && r != CF_CHECK_OK_DOES_NOT_EXIST) { ++corruptions; if (corrupt != NULL) { SeqAppend(*corrupt, xstrdup(filename)); } } free(symlink_target); } if (corruptions == 0) { Log(LOG_LEVEL_INFO, "All %zu databases healthy", length); } else { Log(LOG_LEVEL_ERR, "Problems detected in %zu/%zu databases", corruptions, length); } return corruptions; } int diagnose_main(int argc, const char *const *const argv) { size_t offset = 1; bool foreground = false; bool validate = false; bool test_write = false; for (int i = offset; i < argc && argv[i][0] == '-'; ++i) { if (StringMatchesOption(argv[i], "--no-fork", "-F")) { foreground = true; offset += 1; } else if (StringMatchesOption(argv[i], "--validate", "-v")) { validate = true; offset += 1; } else if (StringMatchesOption(argv[i], "--test-write", "-w")) { test_write = true; offset += 1; } else { assert(argv[i][0] == '-'); // For-loop condition Log(LOG_LEVEL_ERR, "Unrecognized option: '%s'", argv[i]); return 2; } } Seq *files = argv_to_lmdb_files(argc, argv, offset); if (files == NULL || SeqLength(files) == 0) { Log(LOG_LEVEL_ERR, "No database files to diagnose"); return 1; } const int ret = diagnose_files(files, NULL, foreground, validate, test_write); SeqDestroy(files); return ret; } #endif cfengine-3.24.2/libntech/0000755000000000000000000000000015010704322015140 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/Makefile.am0000644000000000000000000001025515010704254017203 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # AUTOMAKE_OPTIONS = foreign MAKEFLAGS = $(if $(filter-out 0,$(V)),,--no-print-directory --quiet) LCOV_FLAGS = $(if $(filter-out 0,$(V)),,-q) SUBDIRS = libcompat \ libutils \ tests # Hide the buildsystem's username, at least with GNU tar. TAR_OPTIONS = --owner=0 --group=0 export TAR_OPTIONS EXTRA_DIST = README.md LICENSE doc_DATA = README.md # # Some basic clean ups # MOSTLYCLEANFILES = *~ # # Get everything removed down to where rebuilding requires: # "configure; make; make install" # DISTCLEANFILES = # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.sub \ configure install-sh missing mkinstalldirs depcomp ylwrap \ ltmain.sh mdate-sh # # Pass proper flags to aclocal to pick up Libtool macros # ACLOCAL_AMFLAGS = -I m4 list: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' install-data-local: $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/inputs $(MKDIR_P) -m 755 $(DESTDIR)$(workdir)/modules $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/outputs $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/ppkeys $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/plugins $(MKDIR_P) -m 750 $(DESTDIR)$(workdir)/state tar-package: pkgdir=`mktemp -d` && export pkgdir && \ origdir=`pwd` && export origdir && \ $(MAKE) DESTDIR=$$pkgdir install && \ ( \ cd $$pkgdir && \ find . -name '*.cf*' | xargs -n1 chmod go-w && \ tardir=. && \ $(am__tar) | GZIP=$(GZIP_ENV) gzip -c \ > "$$origdir"/$(PACKAGE)-$(VERSION).pkg.tar.gz \ ) ; \ [ x$$pkgdir != x ] && rm -rf $$pkgdir # # Code coverage # clean-coverage: find -L $(srcdir) -name '*.gcda' -delete run-coverage: -$(MAKE) check -k collect-coverage: mkdir -p coverage $(LCOV) $(LCOV_FLAGS) --capture --initial --directory . --output-file coverage/cfengine-lcov-base.info $(LCOV) $(LCOV_FLAGS) --capture --directory . --output-file coverage/lcov.info --test-name CFENGINE --no-checksum --compat-libtool $(LCOV) $(LCOV_FLAGS) -a coverage/cfengine-lcov-base.info -a coverage/lcov.info --output-file coverage/cfengine-lcov.info $(LCOV) $(LCOV_FLAGS) --remove coverage/lcov.info '/usr/include/*' --output-file coverage/lcov.info LANG=C $(LCOV_GENHTML) $(LCOV_FLAGS) --prefix . --output-directory coverage-html --title "CFEngine Code Coverage" --legend --show-details coverage/lcov.info @echo @echo " Code coverage information: file://"`pwd`"/coverage-html/index.html" @echo " Code coverage summary for IDEs: file://"`pwd`"/coverage/lcov.info" @echo coverage: clean-coverage run-coverage collect-coverage V_PERL = $(cf__v_PERL_$(V)) cf__v_PERL_ = $(cf__v_PERL_$(AM_DEFAULT_VERBOSITY)) cf__v_PERL_0 = @echo " PERL " "$@"; cf__v_PERL_1 = V_SED = $(cf__v_SED_$(V)) cf__v_SED_ = $(cf__v_SED_$(AM_DEFAULT_VERBOSITY)) cf__v_SED_0 = @echo " SED " "$@"; cf__v_SED_1 = static-check: tests/static-check/run.sh static-check-f%: STATIC_CHECKS_FEDORA_VERSION=$* tests/static-check/run.sh # # Get everything removed down to where rebuilding requires: # "make; make install" # CLEANFILES = cfengine-lcov-base.info cfengine-lcov.info \ $(BUILT_SOURCES) cfengine-3.24.2/libntech/configure0000755000000000000000000235303515010704271017065 0ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for libntech 1.0.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libntech' PACKAGE_TARNAME='libntech' PACKAGE_VERSION='1.0.0' PACKAGE_STRING='libntech 1.0.0' PACKAGE_BUGREPORT='' PACKAGE_URL='https://github.com/NorthernTechHQ/libntech' : "${AR_FLAGS=cr}" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_config_libobj_dir=libcompat ac_header_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS post_macros CORE_LIBS CORE_LDFLAGS CORE_CFLAGS CORE_CPPFLAGS ENABLE_COVERAGE_FALSE ENABLE_COVERAGE_TRUE LCOV_GENHTML LCOV HOSTNAME statedir piddir logdir inputdir masterdir workdir XNU_FALSE XNU_TRUE NETBSD_FALSE NETBSD_TRUE FREEBSD_FALSE FREEBSD_TRUE HPUX_FALSE HPUX_TRUE AIX_FALSE AIX_TRUE CYGWIN_FALSE CYGWIN_TRUE NT_FALSE NT_TRUE SOLARIS_FALSE SOLARIS_TRUE MACOSX_FALSE MACOSX_TRUE LINUX_FALSE LINUX_TRUE NO_TAUTOLOGICAL_CC_OPTION hw_cv_func_rename_proper hw_cv_func_stat_proper hw_cv_func_mkdir_proper hw_cv_func_ctime_proper LIBOBJS HAVE_CLOCKID_T_DEFINE HAVE_GETOPT_H_DEFINE HAVE_LIBYAML_DEFINE LIBYAML_LIBS LIBYAML_LDFLAGS LIBYAML_CFLAGS LIBYAML_CPPFLAGS LIBYAML_PATH SYSTEMD_LOGGING_LIBS SYSTEMD_LOGGING_LDFLAGS SYSTEMD_LOGGING_CFLAGS SYSTEMD_LOGGING_CPPFLAGS SYSTEMD_LOGGING_PATH WITH_PCRE2_DEFINE WITH_PCRE2_FALSE WITH_PCRE2_TRUE PCRE2_LIBS PCRE2_LDFLAGS PCRE2_CFLAGS PCRE2_CPPFLAGS PCRE2_PATH WITH_OPENSSL_FALSE WITH_OPENSSL_TRUE OPENSSL_LIBS OPENSSL_LDFLAGS OPENSSL_CFLAGS OPENSSL_CPPFLAGS OPENSSL_PATH NDEBUG_FALSE NDEBUG_TRUE projlibdir PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC acx_pthread_config PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG CROSS_COMPILING_FALSE CROSS_COMPILING_TRUE GETCONF PERL YFLAGS YACC LEXLIB LEX_OUTPUT_ROOT LEX LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED LIBTOOL CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM MAKEINFO target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking enable_static enable_shared with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock with_pthreads enable_fhs enable_debug with_openssl with_pcre with_pcre2 with_systemd_logging with_libyaml enable_largefile enable_selinux with_workdir with_masterdir with_inputdir with_datadir with_logdir with_piddir with_statedir with_shell enable_coverage ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP LT_SYS_LIBRARY_PATH YACC YFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libntech 1.0.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libntech] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libntech 1.0.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --disable-maintainer-mode disable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-fhs Enable FHS compliance. Defaults to custom CFEngine files layout --enable-debug Enable debugging --disable-largefile omit support for large files --enable-selinux Deprecated. SELinux support is always enabled --enable-coverage Enable code coverage Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-pthreads[=PATH] Specify path to pthreads, if not the part of operating system --with-openssl[=PATH] Specify OpenSSL path --with-pcre=no Disable PCRE (only for backwards compatibility) --with-pcre2[=PATH] Specify PCRE2 path --with-systemd-logging[=PATH] support systemd structured logging --with-libyaml[=PATH] Specify libyaml path --with-workdir=WORKDIR default for internal (trusted) working directory --with-masterdir=MASTERDIR default for internal masterfiles directory --with-inputdir=INPUTDIR default for internal inputs directory --with-datadir=DATADIR default for internal data directory --with-logdir=LOGDIR default for internal log directory --with-piddir=PIDDIR default for internal pid directory --with-statedir=STATEDIR default for internal state directory --with-shell=PATH Specify path to POSIX-compatible shell (if not /bin/sh) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor LT_SYS_LIBRARY_PATH User-defined run-time library search path. YACC The `Yet Another Compiler Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. YFLAGS The list of arguments that will be passed by default to $YACC. This script will default YFLAGS to the empty string to avoid a default value of `-d' given by some make applications. PKG_CONFIG path to pkg-config PKG_CONFIG_PATH directories to add to the pkg-config search path PKG_CONFIG_LIBDIR path overriding pkg-config's search path Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. libntech home page: . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libntech configure 1.0.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libntech $as_me 1.0.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi as_fn_append ac_header_list " sys/sysmacros.h" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- # Extract the first word of "makeinfo", so it can be a program name with args. set dummy makeinfo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MAKEINFO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MAKEINFO"; then ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MAKEINFO="makeinfo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MAKEINFO=$ac_cv_prog_MAKEINFO if test -n "$MAKEINFO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINFO" >&5 $as_echo "$MAKEINFO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking automake version" >&5 $as_echo_n "checking automake version... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: 1.15" >&5 $as_echo "1.15" >&6; } am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libntech' VERSION='1.0.0' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar plaintar pax cpio none' # The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether UID '$am_uid' is supported by ustar format" >&5 $as_echo_n "checking whether UID '$am_uid' is supported by ustar format... " >&6; } if test $am_uid -le $am_max_uid; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } _am_tools=none fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GID '$am_gid' is supported by ustar format" >&5 $as_echo_n "checking whether GID '$am_gid' is supported by ustar format... " >&6; } if test $am_gid -le $am_max_gid; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } _am_tools=none fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5 $as_echo_n "checking how to create a ustar tar archive... " >&6; } # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_ustar-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do { echo "$as_me:$LINENO: $_am_tar --version" >&5 ($_am_tar --version) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && break done # Work around CFEngine redmine #6925 by using --hard-dereference. { echo "$as_me:$LINENO: $_am_tar --hard-dereference 2>&1 | grep 'unrecognized option'" >&5 ($_am_tar --hard-dereference 2>&1 | grep 'unrecognized option') >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } # Check if --hard-dereference is supported by this version of GNU Tar if test "$ac_status" -eq 0; then _am_gnutar_hard_dereference=false am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"' am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"' else _am_gnutar_hard_dereference=true am__tar="$_am_tar --format=ustar --hard-dereference -chf - "'"$$tardir"' am__tar_="$_am_tar --format=ustar --hard-dereference -chf - "'"$tardir"' fi am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x ustar -w "$$tardir"' am__tar_='pax -L -x ustar -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H ustar -L' am__tar_='find "$tardir" -print | cpio -o -H ustar -L' am__untar='cpio -i -H ustar -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_ustar}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -rf conftest.dir if test -s conftest.tar; then { echo "$as_me:$LINENO: $am__untar &5 ($am__untar &5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: cat conftest.dir/file" >&5 (cat conftest.dir/file) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir if ${am_cv_prog_tar_ustar+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_prog_tar_ustar=$_am_tool fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5 $as_echo "$am_cv_prog_tar_ustar" >&6; } if test $_am_tool = gnutar; then # We've checked already, so we're just printing here { $as_echo "$as_me:${as_lineno-$LINENO}: checking if GNU tar supports --hard-dereference" >&5 $as_echo_n "checking if GNU tar supports --hard-dereference... " >&6; } if test x$_am_gnutar_hard_dereference = xtrue; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE $as_echo "#define BUILD_YEAR 2025" >>confdefs.h cat >>confdefs.h <<_ACEOF #define ABS_TOP_SRCDIR "`cd -- "$srcdir"; pwd`" _ACEOF # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' ac_config_headers="$ac_config_headers config.h" ENV_CFLAGS="$CFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined __HP_cc #This is HP-UX ANSI C #endif _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : HP_UX_AC="no" else CFLAGS="$CFLAGS -Agcc" CPPFLAGS="$CPPFLAGS -Agcc" HP_UX_AC="yes" fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HP-UX aC" >&5 $as_echo_n "checking for HP-UX aC... " >&6; } if test "x$HP_UX_AC" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC specific compile flags" >&5 $as_echo_n "checking for GCC specific compile flags... " >&6; } if test x"$GCC" = "xyes" && test x"$HP_UX_AC" != x"yes"; then CFLAGS="$CFLAGS -g -Wall" CPPFLAGS="$CPPFLAGS -std=gnu99" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-pointer-sign" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wno-pointer-sign" >&5 $as_echo_n "checking for -Wno-pointer-sign... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror=implicit-function-declaration" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Werror=implicit-function-declaration" >&5 $as_echo_n "checking for -Werror=implicit-function-declaration... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wunused-parameter" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wunused-parameter" >&5 $as_echo_n "checking for -Wunused-parameter... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wno-duplicate-decl-specifier" >&5 $as_echo_n "checking for -Wno-duplicate-decl-specifier... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __clang__ # error Not a clang #endif int main() {} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$save_CFLAGS -Wno-duplicate-decl-specifier" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Use either new LT_INIT or old AC_DISABLE_STATIC/AC_PROG_LIBTOOL macros case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=no fi enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ yyless ((input () != 0)); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi if test "$LEX" = :; then LEX=${am_missing_run}flex fi for ac_prog in 'bison -y' byacc do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_YACC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_YACC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi YACC=$ac_cv_prog_YACC if test -n "$YACC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 $as_echo "$YACC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$YACC" && break done test -n "$YACC" || YACC="yacc" # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "getconf", so it can be a program name with args. set dummy getconf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GETCONF+:} false; then : $as_echo_n "(cached) " >&6 else case $GETCONF in [\\/]* | ?:[\\/]*) ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$PATH:$prefix/bin:/usr/bin:/usr/local/bin:/sw/bin" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GETCONF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GETCONF" && ac_cv_path_GETCONF="false" ;; esac fi GETCONF=$ac_cv_path_GETCONF if test -n "$GETCONF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GETCONF" >&5 $as_echo "$GETCONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$cross_compiling" = "xyes"; then CROSS_COMPILING_TRUE= CROSS_COMPILING_FALSE='#' else CROSS_COMPILING_TRUE='#' CROSS_COMPILING_FALSE= fi # Check whether `pkg-config' is available if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi # Check whether --with-pthreads was given. if test "${with_pthreads+set}" = set; then : withval=$with_pthreads; fi if test "x$with_pthreads" != x && test "x$with_pthreads" != "xyes" && test "x$with_pthreads" != "xno"; then LIBS="$LIBS -L$with_pthreads/lib" CPPFLAGS="-I$with_pthreads/include $CPPFLAGS" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5 $as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_join (); int main () { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : acx_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 $as_echo "$acx_pthread_ok" >&6; } if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt -mthreads pthread --thread-safe pthread-config pthreadGC2" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 $as_echo_n "checking whether pthreads work without any flags... " >&6; } ;; -*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 $as_echo_n "checking whether pthreads work with $flag... " >&6; } PTHREAD_CFLAGS="$flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_acx_pthread_config+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$acx_pthread_config"; then ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_acx_pthread_config="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no" fi fi acx_pthread_config=$ac_cv_prog_acx_pthread_config if test -n "$acx_pthread_config"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5 $as_echo "$acx_pthread_config" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 $as_echo_n "checking for the pthreads library -l$flag... " >&6; } PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : acx_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5 $as_echo "$acx_pthread_ok" >&6; } if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 $as_echo_n "checking for joinable pthread attribute... " >&6; } attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int attr=$attr; return attr; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : attr_name=$attr; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5 $as_echo "$attr_name" >&6; } if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then cat >>confdefs.h <<_ACEOF #define PTHREAD_CREATE_JOINABLE $attr_name _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 $as_echo_n "checking if more special flags are required for pthreads... " >&6; } flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5 $as_echo "${flag}" >&6; } if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then for ac_prog in xlc_r cc_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PTHREAD_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 $as_echo "$PTHREAD_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}" else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h : else acx_pthread_ok=no as_fn_error $? "pthread-compatible library is required to build CFEngine" "$LINENO" 5 fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$PTHREAD_CC" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check whether --enable-fhs was given. if test "${enable_fhs+set}" = set; then : enableval=$enable_fhs; fi # # pkglibdir/pkgdatadir are not overridable, so use our own invention instead. # if test x"$enable_fhs" = xyes; then : projlibdir='${pkglibdir}' WORKDIR='${localstatedir}/lib/cfengine' MASTERDIR='default' INPUTDIR='default' DATADIR='default' LOGDIR='${localstatedir}/log/cfengine' PIDDIR='${runstatedir:-${localstatedir}/run}/cfengine' STATEDIR='default' else if test x"$prefix" = xNONE || test x"$prefix" = x/var/cfengine; then prefix=/var/cfengine case "$target_os" in mingw*) WORKDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') PIDDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') STATEDIR=default ;; *) WORKDIR=/var/cfengine MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=/var/cfengine PIDDIR=/var/cfengine STATEDIR=default ;; esac else WORKDIR="${localstatedir}/${PACKAGE}" MASTERDIR="default" INPUTDIR="default" DATADIR="default" LOGDIR="${localstatedir}/${PACKAGE}" PIDDIR="${localstatedir}/${PACKAGE}" STATEDIR="default" fi bindir="${bindir:-${exec_prefix}/bin}" projlibdir='${libdir}' fi case ${target_os} in #( mingw*) : # Disable printf format warnings, because our wrapper supports more # flags than vanilla Windows version, so they are false positives. CFLAGS="$CFLAGS -Wno-format" ;; #( *) : ;; esac # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; debug=$enableval else debug=no fi if test x"$debug" = x"no"; then NDEBUG_TRUE= NDEBUG_FALSE='#' else NDEBUG_TRUE='#' NDEBUG_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for debug option" >&5 $as_echo_n "checking for debug option... " >&6; } if test x"$debug" = x"yes" then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$CFLAGS -g3 -O0 $ENV_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$CFLAGS -O2 -DNDEBUG $ENV_CFLAGS" fi # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then : withval=$with_openssl; else with_openssl=yes fi if test -d /usr/local/Cellar/ && \ test -d /usr/local/opt/openssl/ && \ test "x$with_openssl" = "xyes" ; then with_openssl=$(brew --prefix openssl) echo "OS X Homebrew detected" echo "Defaulting to: --with-openssl=$with_openssl" fi if test "x$with_openssl" != "xno"; then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_openssl" != xyes && test "x$with_openssl" != xcheck && test "x$with_openssl" != x then test -z "$OPENSSL_PATH" && OPENSSL_PATH="$with_openssl" if test "x$with_openssl" != x/usr && test "x$with_openssl" != x/ then test -z "$OPENSSL_CFLAGS" && OPENSSL_CFLAGS="" test -z "$OPENSSL_CPPFLAGS" && OPENSSL_CPPFLAGS="-I$with_openssl/include" test -z "$OPENSSL_LDFLAGS" && OPENSSL_LDFLAGS="-L$with_openssl/lib" fi else OPENSSL_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $OPENSSL_CFLAGS" CPPFLAGS="$CPPFLAGS $OPENSSL_CPPFLAGS" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RSA_generate_key_ex in -lcrypto" >&5 $as_echo_n "checking for RSA_generate_key_ex in -lcrypto... " >&6; } if ${ac_cv_lib_crypto_RSA_generate_key_ex+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char RSA_generate_key_ex (); int main () { return RSA_generate_key_ex (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypto_RSA_generate_key_ex=yes else ac_cv_lib_crypto_RSA_generate_key_ex=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RSA_generate_key_ex" >&5 $as_echo "$ac_cv_lib_crypto_RSA_generate_key_ex" >&6; } if test "x$ac_cv_lib_crypto_RSA_generate_key_ex" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPTO 1 _ACEOF LIBS="-lcrypto $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_free in -lssl" >&5 $as_echo_n "checking for SSL_free in -lssl... " >&6; } if ${ac_cv_lib_ssl_SSL_free+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSL_free (); int main () { return SSL_free (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ssl_SSL_free=yes else ac_cv_lib_ssl_SSL_free=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_free" >&5 $as_echo "$ac_cv_lib_ssl_SSL_free" >&6; } if test "x$ac_cv_lib_ssl_SSL_free" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" fi ac_fn_c_check_decl "$LINENO" "SSL_CTX_clear_options" "ac_cv_have_decl_SSL_CTX_clear_options" "#include " if test "x$ac_cv_have_decl_SSL_CTX_clear_options" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SSL_CTX_CLEAR_OPTIONS $ac_have_decl _ACEOF for ac_header in openssl/opensslv.h do : ac_fn_c_check_header_mongrel "$LINENO" "openssl/opensslv.h" "ac_cv_header_openssl_opensslv_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_opensslv_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_OPENSSLV_H 1 _ACEOF else as_fn_error $? "Cannot find OpenSSL" "$LINENO" 5 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL version" >&5 $as_echo_n "checking for OpenSSL version... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #if OPENSSL_VERSION_NUMBER < 0x1000000fL #This OpenSSL is too old #endif _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: OK" >&5 $as_echo "OK" >&6; } else as_fn_error $? "This release of CFEngine requires OpenSSL >= 1.0.0" "$LINENO" 5 fi rm -f conftest.err conftest.i conftest.$ac_ext if test "x$ac_cv_lib_crypto_RSA_generate_key_ex" = "xno"; then as_fn_error $? "Cannot find OpenSSL" "$LINENO" 5 fi $as_echo "#define OPENSSL_SUPPRESS_DEPRECATED 1" >>confdefs.h ac_fn_c_check_decl "$LINENO" "SSL_OP_NO_TLSv1_1" "ac_cv_have_decl_SSL_OP_NO_TLSv1_1" "#include " if test "x$ac_cv_have_decl_SSL_OP_NO_TLSv1_1" = xyes; then : $as_echo "#define HAVE_TLS_1_1 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "SSL_OP_NO_TLSv1_2" "ac_cv_have_decl_SSL_OP_NO_TLSv1_2" "#include " if test "x$ac_cv_have_decl_SSL_OP_NO_TLSv1_2" = xyes; then : $as_echo "#define HAVE_TLS_1_2 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "SSL_OP_NO_TLSv1_3" "ac_cv_have_decl_SSL_OP_NO_TLSv1_3" "#include " if test "x$ac_cv_have_decl_SSL_OP_NO_TLSv1_3" = xyes; then : $as_echo "#define HAVE_TLS_1_3 1" >>confdefs.h fi # # Pick up any libraries added by tests # test -z "$OPENSSL_LIBS" && OPENSSL_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_openssl" != xyes && test "x$with_openssl" != xcheck && test "x$with_openssl" != x/usr && test "x$with_openssl" != x/ then OPENSSL_LDFLAGS="$OPENSSL_LDFLAGS -R$with_openssl/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" $as_echo "#define WITH_OPENSSL 1" >>confdefs.h if true; then WITH_OPENSSL_TRUE= WITH_OPENSSL_FALSE='#' else WITH_OPENSSL_TRUE='#' WITH_OPENSSL_FALSE= fi else if false; then WITH_OPENSSL_TRUE= WITH_OPENSSL_FALSE='#' else WITH_OPENSSL_TRUE='#' WITH_OPENSSL_FALSE= fi fi # Check whether --with-pcre was given. if test "${with_pcre+set}" = set; then : withval=$with_pcre; else with_pcre=default fi if test "x$with_pcre" != "xdefault" && test "x$with_pcre" != "xno"; then as_fn_error $? "PCRE no longer supported, use PCRE2" "$LINENO" 5; fi # Check whether --with-pcre2 was given. if test "${with_pcre2+set}" = set; then : withval=$with_pcre2; else with_pcre2=yes fi if test "x$with_pcre" != "xno" && test "x$with_pcre2" != "xno"; then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_pcre2" != xyes && test "x$with_pcre2" != xcheck && test "x$with_pcre2" != x then test -z "$PCRE2_PATH" && PCRE2_PATH="$with_pcre2" if test "x$with_pcre2" != x/usr && test "x$with_pcre2" != x/ then test -z "$PCRE2_CFLAGS" && PCRE2_CFLAGS="" test -z "$PCRE2_CPPFLAGS" && PCRE2_CPPFLAGS="-I$with_pcre2/include" test -z "$PCRE2_LDFLAGS" && PCRE2_LDFLAGS="-L$with_pcre2/lib" fi else PCRE2_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $PCRE2_CFLAGS" CPPFLAGS="$CPPFLAGS $PCRE2_CPPFLAGS" LDFLAGS="$LDFLAGS $PCRE2_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre2_compile_8 in -lpcre2-8" >&5 $as_echo_n "checking for pcre2_compile_8 in -lpcre2-8... " >&6; } if ${ac_cv_lib_pcre2_8_pcre2_compile_8+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcre2-8 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pcre2_compile_8 (); int main () { return pcre2_compile_8 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pcre2_8_pcre2_compile_8=yes else ac_cv_lib_pcre2_8_pcre2_compile_8=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre2_8_pcre2_compile_8" >&5 $as_echo "$ac_cv_lib_pcre2_8_pcre2_compile_8" >&6; } if test "x$ac_cv_lib_pcre2_8_pcre2_compile_8" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPCRE2_8 1 _ACEOF LIBS="-lpcre2-8 $LIBS" else as_fn_error $? "Cannot find PCRE2" "$LINENO" 5 fi for ac_header in pcre2.h do : ac_fn_c_check_header_compile "$LINENO" "pcre2.h" "ac_cv_header_pcre2_h" "#define PCRE2_CODE_UNIT_WIDTH 8 " if test "x$ac_cv_header_pcre2_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PCRE2_H 1 _ACEOF else as_fn_error $? "Cannot find PCRE2" "$LINENO" 5 fi done # # Pick up any libraries added by tests # test -z "$PCRE2_LIBS" && PCRE2_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_pcre2" != xyes && test "x$with_pcre2" != xcheck && test "x$with_pcre2" != x/usr && test "x$with_pcre2" != x/ then PCRE2_LDFLAGS="$PCRE2_LDFLAGS -R$with_pcre2/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" $as_echo "#define WITH_PCRE2 1" >>confdefs.h if true; then WITH_PCRE2_TRUE= WITH_PCRE2_FALSE='#' else WITH_PCRE2_TRUE='#' WITH_PCRE2_FALSE= fi WITH_PCRE2_DEFINE="#define WITH_PCRE2 1" else if false; then WITH_PCRE2_TRUE= WITH_PCRE2_FALSE='#' else WITH_PCRE2_TRUE='#' WITH_PCRE2_FALSE= fi WITH_PCRE2_DEFINE="// #undef WITH_PCRE2" fi # Check whether --with-systemd-logging was given. if test "${with_systemd_logging+set}" = set; then : withval=$with_systemd_logging; else with_systemd_logging=check fi if test "x$with_systemd_logging" != xno then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_systemd_logging" != xyes && test "x$with_systemd_logging" != xcheck && test "x$with_systemd_logging" != x then test -z "$SYSTEMD_LOGGING_PATH" && SYSTEMD_LOGGING_PATH="$with_systemd_logging" if test "x$with_systemd_logging" != x/usr && test "x$with_systemd_logging" != x/ then test -z "$SYSTEMD_LOGGING_CFLAGS" && SYSTEMD_LOGGING_CFLAGS="" test -z "$SYSTEMD_LOGGING_CPPFLAGS" && SYSTEMD_LOGGING_CPPFLAGS="-I$with_systemd_logging/include" test -z "$SYSTEMD_LOGGING_LDFLAGS" && SYSTEMD_LOGGING_LDFLAGS="-L$with_systemd_logging/lib" fi else SYSTEMD_LOGGING_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $SYSTEMD_LOGGING_CFLAGS" CPPFLAGS="$CPPFLAGS $SYSTEMD_LOGGING_CPPFLAGS" LDFLAGS="$LDFLAGS $SYSTEMD_LOGGING_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sd_journal_sendv in -lsystemd" >&5 $as_echo_n "checking for sd_journal_sendv in -lsystemd... " >&6; } if ${ac_cv_lib_systemd_sd_journal_sendv+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsystemd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sd_journal_sendv (); int main () { return sd_journal_sendv (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_systemd_sd_journal_sendv=yes else ac_cv_lib_systemd_sd_journal_sendv=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_systemd_sd_journal_sendv" >&5 $as_echo "$ac_cv_lib_systemd_sd_journal_sendv" >&6; } if test "x$ac_cv_lib_systemd_sd_journal_sendv" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSYSTEMD 1 _ACEOF LIBS="-lsystemd $LIBS" else if test "x$with_systemd_logging" != xcheck; then as_fn_error $? "Cannot find systemd library" "$LINENO" 5; fi fi for ac_header in systemd/sd-journal.h do : ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-journal.h" "ac_cv_header_systemd_sd_journal_h" "$ac_includes_default" if test "x$ac_cv_header_systemd_sd_journal_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYSTEMD_SD_JOURNAL_H 1 _ACEOF else if test "x$with_systemd_logging" != xcheck; then as_fn_error $? "Cannot find systemd headers" "$LINENO" 5; fi fi done # # Pick up any libraries added by tests # test -z "$SYSTEMD_LOGGING_LIBS" && SYSTEMD_LOGGING_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_systemd_logging" != xyes && test "x$with_systemd_logging" != xcheck && test "x$with_systemd_logging" != x/usr && test "x$with_systemd_logging" != x/ then SYSTEMD_LOGGING_LDFLAGS="$SYSTEMD_LOGGING_LDFLAGS -R$with_systemd_logging/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" fi # Check whether --with-libyaml was given. if test "${with_libyaml+set}" = set; then : withval=$with_libyaml; else with_libyaml=check fi if test "x$with_libyaml" != xno then # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_libyaml" != xyes && test "x$with_libyaml" != xcheck && test "x$with_libyaml" != x then test -z "$LIBYAML_PATH" && LIBYAML_PATH="$with_libyaml" if test "x$with_libyaml" != x/usr && test "x$with_libyaml" != x/ then test -z "$LIBYAML_CFLAGS" && LIBYAML_CFLAGS="" test -z "$LIBYAML_CPPFLAGS" && LIBYAML_CPPFLAGS="-I$with_libyaml/include" test -z "$LIBYAML_LDFLAGS" && LIBYAML_LDFLAGS="-L$with_libyaml/lib" fi else LIBYAML_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $LIBYAML_CFLAGS" CPPFLAGS="$CPPFLAGS $LIBYAML_CPPFLAGS" LDFLAGS="$LDFLAGS $LIBYAML_LDFLAGS" # # Run checks passed as argument # { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yaml_parser_initialize in -lyaml" >&5 $as_echo_n "checking for yaml_parser_initialize in -lyaml... " >&6; } if ${ac_cv_lib_yaml_yaml_parser_initialize+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lyaml $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char yaml_parser_initialize (); int main () { return yaml_parser_initialize (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_yaml_yaml_parser_initialize=yes else ac_cv_lib_yaml_yaml_parser_initialize=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_yaml_yaml_parser_initialize" >&5 $as_echo "$ac_cv_lib_yaml_yaml_parser_initialize" >&6; } if test "x$ac_cv_lib_yaml_yaml_parser_initialize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBYAML 1 _ACEOF LIBS="-lyaml $LIBS" else if test "x$with_libyaml" != xcheck; then as_fn_error $? "Cannot find libyaml library" "$LINENO" 5; fi fi for ac_header in yaml.h do : ac_fn_c_check_header_mongrel "$LINENO" "yaml.h" "ac_cv_header_yaml_h" "$ac_includes_default" if test "x$ac_cv_header_yaml_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_YAML_H 1 _ACEOF libyaml_header_found=yes HAVE_LIBYAML_DEFINE="#define HAVE_LIBYAML 1" else if test "x$with_libyaml" != xcheck; then as_fn_error $? "Cannot find libyaml header files" "$LINENO" 5; fi HAVE_LIBYAML_DEFINE="// #undef HAVE_LIBYAML" fi done # # Pick up any libraries added by tests # test -z "$LIBYAML_LIBS" && LIBYAML_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_libyaml" != xyes && test "x$with_libyaml" != xcheck && test "x$with_libyaml" != x/usr && test "x$with_libyaml" != x/ then LIBYAML_LDFLAGS="$LIBYAML_LDFLAGS -R$with_libyaml/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" else HAVE_LIBYAML_DEFINE="// #undef HAVE_LIBYAML" fi for ac_header in unistd.h stdlib.h sys/loadavg.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/param.h sys/resource.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # sys/param.h is required for sys/mount.h on OpenBSD for ac_header in sys/mount.h do : ac_fn_c_check_header_compile "$LINENO" "sys/mount.h" "ac_cv_header_sys_mount_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_mount_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_MOUNT_H 1 _ACEOF fi done # Required on BSD to get struct sockaddr_dl (for retrieving MAC addresses from getifaddrs()) for ac_header in net/if_dl.h do : ac_fn_c_check_header_mongrel "$LINENO" "net/if_dl.h" "ac_cv_header_net_if_dl_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_dl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NET_IF_DL_H 1 _ACEOF fi done # Required on Solaris to get struct arpreq (for retrieving MAC addresses) for ac_header in net/if_arp.h do : ac_fn_c_check_header_compile "$LINENO" "net/if_arp.h" "ac_cv_header_net_if_arp_h" "$ac_includes_default #include " if test "x$ac_cv_header_net_if_arp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NET_IF_ARP_H 1 _ACEOF fi done for ac_header in getopt.h do : ac_fn_c_check_header_mongrel "$LINENO" "getopt.h" "ac_cv_header_getopt_h" "$ac_includes_default" if test "x$ac_cv_header_getopt_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETOPT_H 1 _ACEOF HAVE_GETOPT_H_DEFINE="#define HAVE_GETOPT_H 1" else HAVE_GETOPT_H_DEFINE="// #undef HAVE_GETOPT_H" fi done for ac_header in utime.h do : ac_fn_c_check_header_mongrel "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default" if test "x$ac_cv_header_utime_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTIME_H 1 _ACEOF fi done for ac_header in time.h do : ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" if test "x$ac_cv_header_time_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TIME_H 1 _ACEOF fi done for ac_header in sys/time.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" if test "x$ac_cv_header_sys_time_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TIME_H 1 _ACEOF fi done for ac_header in malloc.h sys/malloc.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in vfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "vfs.h" "ac_cv_header_vfs_h" "$ac_includes_default" if test "x$ac_cv_header_vfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VFS_H 1 _ACEOF fi done for ac_header in sys/vfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/vfs.h" "ac_cv_header_sys_vfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_vfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_VFS_H 1 _ACEOF fi done for ac_header in sys/sockio.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/sockio.h" "ac_cv_header_sys_sockio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sockio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SOCKIO_H 1 _ACEOF fi done for ac_header in sys/statvfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_statvfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_STATVFS_H 1 _ACEOF fi done for ac_header in sys/statfs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/statfs.h" "ac_cv_header_sys_statfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_statfs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_STATFS_H 1 _ACEOF fi done for ac_header in fcntl.h do : ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" if test "x$ac_cv_header_fcntl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FCNTL_H 1 _ACEOF fi done for ac_header in sys/filesys.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/filesys.h" "ac_cv_header_sys_filesys_h" "$ac_includes_default" if test "x$ac_cv_header_sys_filesys_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_FILESYS_H 1 _ACEOF fi done for ac_header in dustat.h do : ac_fn_c_check_header_mongrel "$LINENO" "dustat.h" "ac_cv_header_dustat_h" "$ac_includes_default" if test "x$ac_cv_header_dustat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DUSTAT_H 1 _ACEOF fi done for ac_header in sys/systeminfo.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/systeminfo.h" "ac_cv_header_sys_systeminfo_h" "$ac_includes_default" if test "x$ac_cv_header_sys_systeminfo_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SYSTEMINFO_H 1 _ACEOF fi done for ac_header in ieeefp.h do : ac_fn_c_check_header_mongrel "$LINENO" "ieeefp.h" "ac_cv_header_ieeefp_h" "$ac_includes_default" if test "x$ac_cv_header_ieeefp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IEEEFP_H 1 _ACEOF fi done for ac_header in winsock2.h do : ac_fn_c_check_header_mongrel "$LINENO" "winsock2.h" "ac_cv_header_winsock2_h" "$ac_includes_default" if test "x$ac_cv_header_winsock2_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WINSOCK2_H 1 _ACEOF fi done for ac_header in ws2tcpip.h do : ac_fn_c_check_header_mongrel "$LINENO" "ws2tcpip.h" "ac_cv_header_ws2tcpip_h" "$ac_includes_default" if test "x$ac_cv_header_ws2tcpip_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WS2TCPIP_H 1 _ACEOF fi done for ac_header in zone.h do : ac_fn_c_check_header_mongrel "$LINENO" "zone.h" "ac_cv_header_zone_h" "$ac_includes_default" if test "x$ac_cv_header_zone_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZONE_H 1 _ACEOF fi done for ac_header in sys/uio.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_uio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_UIO_H 1 _ACEOF fi done for ac_header in $ac_header_list do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/types.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" if test "x$ac_cv_header_sys_types_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_TYPES_H 1 _ACEOF fi done for ac_header in sys/mpctl.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/mpctl.h" "ac_cv_header_sys_mpctl_h" "$ac_includes_default" if test "x$ac_cv_header_sys_mpctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_MPCTL_H 1 _ACEOF fi done for ac_header in shadow.h do : ac_fn_c_check_header_mongrel "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default" if test "x$ac_cv_header_shadow_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SHADOW_H 1 _ACEOF fi done for ac_header in sys/jail.h do : ac_fn_c_check_header_compile "$LINENO" "sys/jail.h" "ac_cv_header_sys_jail_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_jail_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_JAIL_H 1 _ACEOF fi done for ac_header in net/route.h netinet/in.h netinet/ip.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if ${ac_cv_header_sys_wait_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$as_ac_Header=yes" else eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" if test "x$ac_cv_type_mode_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define mode_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 $as_echo_n "checking for uid_t in sys/types.h... " >&6; } if ${ac_cv_type_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then : ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 $as_echo "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then $as_echo "#define uid_t int" >>confdefs.h $as_echo "#define gid_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "clockid_t" "ac_cv_type_clockid_t" " #ifdef HAVE_TIME_H # include #endif " if test "x$ac_cv_type_clockid_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CLOCKID_T 1 _ACEOF HAVE_CLOCKID_T_DEFINE="#define HAVE_CLOCKID_T 1" else HAVE_CLOCKID_T_DEFINE="// #undef HAVE_CLOCKID_T" fi ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " #ifdef HAVE_SYS_TYPES_H # include #endif #include " if test "x$ac_cv_type_socklen_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=no; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=1; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_cv_sys_largefile_source=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } case $ac_cv_sys_largefile_source in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF ;; esac rm -rf conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. if test $ac_cv_sys_largefile_source != unknown; then $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi # # AC_SYS_LARGEFILE correctly figures out necessary macros for large files, but # on AIX there is a gotcha: # # Code generated by flex #includes at the beginning of the file, which # picks up 32-bit wide off_t. Then it #includes which provides LFS # macros, and finally it includes another system header, now with 64-bit wide # off_t, which causes a conflict. # if test "x$ac_cv_sys_large_files" = x1; then CPPFLAGS="-D_LARGE_FILES=1 $CPPFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 $as_echo_n "checking for sqrt in -lm... " >&6; } if ${ac_cv_lib_m_sqrt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sqrt (); int main () { return sqrt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_sqrt=yes else ac_cv_lib_m_sqrt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 $as_echo "$ac_cv_lib_m_sqrt" >&6; } if test "x$ac_cv_lib_m_sqrt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if ${ac_cv_lib_rt_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi ac_fn_c_check_decl "$LINENO" "clock_gettime" "ac_cv_have_decl_clock_gettime" "#include " if test "x$ac_cv_have_decl_clock_gettime" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CLOCK_GETTIME $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = xyes; then : $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h else case " $LIBOBJS " in *" clock_gettime.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS clock_gettime.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "unsetenv" "ac_cv_have_decl_unsetenv" "$ac_includes_default" if test "x$ac_cv_have_decl_unsetenv" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_UNSETENV $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" if test "x$ac_cv_func_unsetenv" = xyes; then : $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h else case " $LIBOBJS " in *" unsetenv.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS unsetenv.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "$ac_includes_default" if test "x$ac_cv_have_decl_strnlen" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNLEN $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen" if test "x$ac_cv_func_strnlen" = xyes; then : $as_echo "#define HAVE_STRNLEN 1" >>confdefs.h else case " $LIBOBJS " in *" strnlen.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strnlen.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strndup" "ac_cv_have_decl_strndup" "$ac_includes_default" if test "x$ac_cv_have_decl_strndup" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNDUP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strndup" "ac_cv_func_strndup" if test "x$ac_cv_func_strndup" = xyes; then : $as_echo "#define HAVE_STRNDUP 1" >>confdefs.h else case " $LIBOBJS " in *" strndup.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strndup.$ac_objext" ;; esac fi if test $ac_cv_have_decl_strndup = no; then HAVE_DECL_STRNDUP=0 fi if test $ac_cv_func_strndup = yes; then HAVE_STRNDUP=1 # AIX 5.3 has a function that tries to copy the entire range specified # by n, instead of just the length of src. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strndup" >&5 $as_echo_n "checking for working strndup... " >&6; } if ${cf3_cv_func_strndup_works+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : case $host_os in aix | aix[3-6]*) cf3_cv_func_strndup_works="guessing no";; *) cf3_cv_func_strndup_works="guessing yes";; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if !HAVE_DECL_STRNDUP extern #ifdef __cplusplus "C" #endif char *strndup (const char *, size_t); #endif char *s; // Will crash if strndup tries to traverse all 2GB. s = strndup ("string", 2000000000); return 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : cf3_cv_func_strndup_works=yes else cf3_cv_func_strndup_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cf3_cv_func_strndup_works" >&5 $as_echo "$cf3_cv_func_strndup_works" >&6; } case $cf3_cv_func_strndup_works in *no) case " $LIBOBJS " in *" strndup.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strndup.$ac_objext" ;; esac ;; esac else HAVE_STRNDUP=0 fi ac_fn_c_check_decl "$LINENO" "seteuid" "ac_cv_have_decl_seteuid" "$ac_includes_default" if test "x$ac_cv_have_decl_seteuid" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETEUID $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "seteuid" "ac_cv_func_seteuid" if test "x$ac_cv_func_seteuid" = xyes; then : $as_echo "#define HAVE_SETEUID 1" >>confdefs.h else case " $LIBOBJS " in *" seteuid.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS seteuid.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "setlinebuf" "ac_cv_have_decl_setlinebuf" "$ac_includes_default" if test "x$ac_cv_have_decl_setlinebuf" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETLINEBUF $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "setlinebuf" "ac_cv_func_setlinebuf" if test "x$ac_cv_func_setlinebuf" = xyes; then : $as_echo "#define HAVE_SETLINEBUF 1" >>confdefs.h else case " $LIBOBJS " in *" setlinebuf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS setlinebuf.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strlcat" "ac_cv_have_decl_strlcat" "$ac_includes_default" if test "x$ac_cv_have_decl_strlcat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRLCAT $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" if test "x$ac_cv_func_strlcat" = xyes; then : $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h else case " $LIBOBJS " in *" strlcat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strlcat.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strlcpy" "ac_cv_have_decl_strlcpy" "$ac_includes_default" if test "x$ac_cv_have_decl_strlcpy" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRLCPY $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" if test "x$ac_cv_func_strlcpy" = xyes; then : $as_echo "#define HAVE_STRLCPY 1" >>confdefs.h else case " $LIBOBJS " in *" strlcpy.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strlcpy.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "realpath" "ac_cv_have_decl_realpath" "$ac_includes_default" if test "x$ac_cv_have_decl_realpath" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_REALPATH $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "strdup" "ac_cv_have_decl_strdup" "$ac_includes_default" if test "x$ac_cv_have_decl_strdup" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRDUP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" if test "x$ac_cv_func_strdup" = xyes; then : $as_echo "#define HAVE_STRDUP 1" >>confdefs.h else case " $LIBOBJS " in *" strdup.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strdup.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "memrchr" "ac_cv_have_decl_memrchr" "$ac_includes_default" if test "x$ac_cv_have_decl_memrchr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MEMRCHR $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "memrchr" "ac_cv_func_memrchr" if test "x$ac_cv_func_memrchr" = xyes; then : $as_echo "#define HAVE_MEMRCHR 1" >>confdefs.h else case " $LIBOBJS " in *" memrchr.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memrchr.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "round" "ac_cv_have_decl_round" "#include " if test "x$ac_cv_have_decl_round" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ROUND $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "round" "ac_cv_func_round" if test "x$ac_cv_func_round" = xyes; then : $as_echo "#define HAVE_ROUND 1" >>confdefs.h else case " $LIBOBJS " in *" round.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS round.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "nanosleep" "ac_cv_have_decl_nanosleep" "$ac_includes_default" if test "x$ac_cv_have_decl_nanosleep" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_NANOSLEEP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" if test "x$ac_cv_func_nanosleep" = xyes; then : $as_echo "#define HAVE_NANOSLEEP 1" >>confdefs.h else case " $LIBOBJS " in *" nanosleep.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS nanosleep.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "memdup" "ac_cv_have_decl_memdup" "$ac_includes_default" if test "x$ac_cv_have_decl_memdup" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MEMDUP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "memdup" "ac_cv_func_memdup" if test "x$ac_cv_func_memdup" = xyes; then : $as_echo "#define HAVE_MEMDUP 1" >>confdefs.h else case " $LIBOBJS " in *" memdup.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memdup.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "memmem" "ac_cv_have_decl_memmem" "$ac_includes_default" if test "x$ac_cv_have_decl_memmem" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MEMMEM $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "memmem" "ac_cv_func_memmem" if test "x$ac_cv_func_memmem" = xyes; then : $as_echo "#define HAVE_MEMMEM 1" >>confdefs.h else case " $LIBOBJS " in *" memmem.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memmem.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "srand48" "ac_cv_have_decl_srand48" "$ac_includes_default" if test "x$ac_cv_have_decl_srand48" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SRAND48 $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "srand48" "ac_cv_func_srand48" if test "x$ac_cv_func_srand48" = xyes; then : $as_echo "#define HAVE_SRAND48 1" >>confdefs.h else case " $LIBOBJS " in *" srand48.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS srand48.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "drand48" "ac_cv_have_decl_drand48" "$ac_includes_default" if test "x$ac_cv_have_decl_drand48" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_DRAND48 $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "drand48" "ac_cv_func_drand48" if test "x$ac_cv_func_drand48" = xyes; then : $as_echo "#define HAVE_DRAND48 1" >>confdefs.h else case " $LIBOBJS " in *" drand48.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS drand48.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strerror" "ac_cv_have_decl_strerror" "$ac_includes_default" if test "x$ac_cv_have_decl_strerror" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRERROR $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" if test "x$ac_cv_func_strerror" = xyes; then : $as_echo "#define HAVE_STRERROR 1" >>confdefs.h else case " $LIBOBJS " in *" strerror.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strerror.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strstr" "ac_cv_have_decl_strstr" "$ac_includes_default" if test "x$ac_cv_have_decl_strstr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRSTR $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr" if test "x$ac_cv_func_strstr" = xyes; then : $as_echo "#define HAVE_STRSTR 1" >>confdefs.h else case " $LIBOBJS " in *" strstr.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strstr.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strcasestr" "ac_cv_have_decl_strcasestr" "$ac_includes_default" if test "x$ac_cv_have_decl_strcasestr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCASESTR $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" if test "x$ac_cv_func_strcasestr" = xyes; then : $as_echo "#define HAVE_STRCASESTR 1" >>confdefs.h else case " $LIBOBJS " in *" strcasestr.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strcasestr.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strcasecmp" "ac_cv_have_decl_strcasecmp" "$ac_includes_default" if test "x$ac_cv_have_decl_strcasecmp" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCASECMP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" if test "x$ac_cv_func_strcasecmp" = xyes; then : $as_echo "#define HAVE_STRCASECMP 1" >>confdefs.h else case " $LIBOBJS " in *" strcasecmp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strcasecmp.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strncasecmp" "ac_cv_have_decl_strncasecmp" "$ac_includes_default" if test "x$ac_cv_have_decl_strncasecmp" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRNCASECMP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" if test "x$ac_cv_func_strncasecmp" = xyes; then : $as_echo "#define HAVE_STRNCASECMP 1" >>confdefs.h else case " $LIBOBJS " in *" strncasecmp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strsep" "ac_cv_have_decl_strsep" "$ac_includes_default" if test "x$ac_cv_have_decl_strsep" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRSEP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strsep" "ac_cv_func_strsep" if test "x$ac_cv_func_strsep" = xyes; then : $as_echo "#define HAVE_STRSEP 1" >>confdefs.h else case " $LIBOBJS " in *" strsep.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strsep.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strsignal" "ac_cv_have_decl_strsignal" "$ac_includes_default" if test "x$ac_cv_have_decl_strsignal" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRSIGNAL $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strsignal" "ac_cv_func_strsignal" if test "x$ac_cv_func_strsignal" = xyes; then : $as_echo "#define HAVE_STRSIGNAL 1" >>confdefs.h else case " $LIBOBJS " in *" strsignal.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strsignal.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "gmtime_r" "ac_cv_have_decl_gmtime_r" "#include " if test "x$ac_cv_have_decl_gmtime_r" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GMTIME_R $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "gmtime_r" "ac_cv_func_gmtime_r" if test "x$ac_cv_func_gmtime_r" = xyes; then : $as_echo "#define HAVE_GMTIME_R 1" >>confdefs.h else case " $LIBOBJS " in *" gmtime_r.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS gmtime_r.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "getline" "ac_cv_have_decl_getline" "#define _GNU_SOURCE 1 $ac_includes_default " if test "x$ac_cv_have_decl_getline" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETLINE $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline" if test "x$ac_cv_func_getline" = xyes; then : $as_echo "#define HAVE_GETLINE 1" >>confdefs.h else case " $LIBOBJS " in *" getline.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getline.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strchrnul" "ac_cv_have_decl_strchrnul" "#define _GNU_SOURCE 1 $ac_includes_default " if test "x$ac_cv_have_decl_strchrnul" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRCHRNUL $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strchrnul" "ac_cv_func_strchrnul" if test "x$ac_cv_func_strchrnul" = xyes; then : $as_echo "#define HAVE_STRCHRNUL 1" >>confdefs.h else case " $LIBOBJS " in *" strchrnul.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strchrnul.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "localtime_r" "ac_cv_have_decl_localtime_r" "#include " if test "x$ac_cv_have_decl_localtime_r" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOCALTIME_R $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r" if test "x$ac_cv_func_localtime_r" = xyes; then : $as_echo "#define HAVE_LOCALTIME_R 1" >>confdefs.h else case " $LIBOBJS " in *" localtime_r.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS localtime_r.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "fgetgrent" "ac_cv_have_decl_fgetgrent" "#include " if test "x$ac_cv_have_decl_fgetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FGETGRENT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "isfinite" "ac_cv_have_decl_isfinite" "#include " if test "x$ac_cv_have_decl_isfinite" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ISFINITE $ac_have_decl _ACEOF for ac_func in getpwent setpwent endpwent do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in fgetspent lckpwdf ulckpwdf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgetspent in -lsec" >&5 $as_echo_n "checking for fgetspent in -lsec... " >&6; } if ${ac_cv_lib_sec_fgetspent+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsec $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fgetspent (); int main () { return fgetspent (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sec_fgetspent=yes else ac_cv_lib_sec_fgetspent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sec_fgetspent" >&5 $as_echo "$ac_cv_lib_sec_fgetspent" >&6; } if test "x$ac_cv_lib_sec_fgetspent" = xyes; then : $as_echo "#define HAVE_LIBSEC 1" >>confdefs.h $as_echo "#define HAVE_FGETSPENT 1" >>confdefs.h LIBS="-lsec $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac for ac_header in endian.h do : ac_fn_c_check_header_mongrel "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default" if test "x$ac_cv_header_endian_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ENDIAN_H 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "le32toh" "ac_cv_have_decl_le32toh" "#include " if test "x$ac_cv_have_decl_le32toh" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LE32TOH $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "closefrom" "ac_cv_have_decl_closefrom" "#include #include " if test "x$ac_cv_have_decl_closefrom" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CLOSEFROM $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "closefrom" "ac_cv_func_closefrom" if test "x$ac_cv_func_closefrom" = xyes; then : $as_echo "#define HAVE_CLOSEFROM 1" >>confdefs.h else case " $LIBOBJS " in *" closefrom.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS closefrom.$ac_objext" ;; esac fi for ac_header in sys/pstat.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/pstat.h" "ac_cv_header_sys_pstat_h" "$ac_includes_default" if test "x$ac_cv_header_sys_pstat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_PSTAT_H 1 _ACEOF fi done for ac_func in pstat_getfile2 do : ac_fn_c_check_func "$LINENO" "pstat_getfile2" "ac_cv_func_pstat_getfile2" if test "x$ac_cv_func_pstat_getfile2" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PSTAT_GETFILE2 1 _ACEOF fi done found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for chpasswd... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/chpasswd && ls -ld $i/chpasswd | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : CHPASSWD=$i/chpasswd found=1 break fi done if test "$found" = "1"; then : $as_echo "$CHPASSWD" else $as_echo no CHPASSWD= fi if test "x$CHPASSWD" != "x"; then : $as_echo "#define HAVE_CHPASSWD 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define CHPASSWD "$CHPASSWD" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for pwdadm... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/pwdadm && ls -ld $i/pwdadm | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : PWDADM=$i/pwdadm found=1 break fi done if test "$found" = "1"; then : $as_echo "$PWDADM" else $as_echo no PWDADM= fi if test "x$PWDADM" != "x"; then : $as_echo "#define HAVE_PWDADM 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define PWDADM "$PWDADM" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for useradd... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/useradd && ls -ld $i/useradd | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : USERADD=$i/useradd found=1 break fi done if test "$found" = "1"; then : $as_echo "$USERADD" else $as_echo no USERADD= fi if test "x$USERADD" != "x"; then : $as_echo "#define HAVE_USERADD 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define USERADD "$USERADD" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for usermod... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/usermod && ls -ld $i/usermod | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : USERMOD=$i/usermod found=1 break fi done if test "$found" = "1"; then : $as_echo "$USERMOD" else $as_echo no USERMOD= fi if test "x$USERMOD" != "x"; then : $as_echo "#define HAVE_USERMOD 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define USERMOD "$USERMOD" _ACEOF fi found=0 if test "x/sbin:/usr/sbin:/bin:/usr/bin:$PATH" = "x"; then : path=$PATH else path=/sbin:/usr/sbin:/bin:/usr/bin:$PATH fi $as_echo_n "checking for userdel... " for i in $(echo $path | sed -e 's/:/ /g'); do if test -e $i/userdel && ls -ld $i/userdel | grep '^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]' > /dev/null; then : USERDEL=$i/userdel found=1 break fi done if test "$found" = "1"; then : $as_echo "$USERDEL" else $as_echo no USERDEL= fi if test "x$USERDEL" != "x"; then : $as_echo "#define HAVE_USERDEL 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define USERDEL "$USERDEL" _ACEOF fi if test "x$USERADD" != x && \ test "x$USERMOD" != x && test "x$USERDEL" != x; then : have_userprogs=yes else have_userprogs=no fi ac_fn_c_check_decl "$LINENO" "getnetgrent" "ac_cv_have_decl_getnetgrent" "#include " if test "x$ac_cv_have_decl_getnetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETNETGRENT $ac_have_decl _ACEOF for ac_func in getnetgrent do : ac_fn_c_check_func "$LINENO" "getnetgrent" "ac_cv_func_getnetgrent" if test "x$ac_cv_func_getnetgrent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETNETGRENT 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "setnetgrent" "ac_cv_have_decl_setnetgrent" "#include " if test "x$ac_cv_have_decl_setnetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETNETGRENT $ac_have_decl _ACEOF for ac_func in setnetgrent do : ac_fn_c_check_func "$LINENO" "setnetgrent" "ac_cv_func_setnetgrent" if test "x$ac_cv_func_setnetgrent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETNETGRENT 1 _ACEOF fi done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { extern int setnetgrent(const char *) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define SETNETGRENT_RETURNS_INT 1" >>confdefs.h else $as_echo "#define SETNETGRENT_RETURNS_INT 0" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_decl "$LINENO" "endnetgrent" "ac_cv_have_decl_endnetgrent" "#include " if test "x$ac_cv_have_decl_endnetgrent" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ENDNETGRENT $ac_have_decl _ACEOF for ac_func in endnetgrent do : ac_fn_c_check_func "$LINENO" "endnetgrent" "ac_cv_func_endnetgrent" if test "x$ac_cv_func_endnetgrent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ENDNETGRENT 1 _ACEOF fi done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { extern int endnetgrent(const char *) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define ENDNETGRENT_RETURNS_INT 1" >>confdefs.h else $as_echo "#define ENDNETGRENT_RETURNS_INT 0" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext for ac_func in sendto do : ac_fn_c_check_func "$LINENO" "sendto" "ac_cv_func_sendto" if test "x$ac_cv_func_sendto" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SENDTO 1 _ACEOF fi done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { extern ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define SENDTO_RETURNS_SSIZE_T 1" >>confdefs.h else $as_echo "#define SENDTO_RETURNS_SSIZE_T 0" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_func "$LINENO" "ctime" "ac_cv_func_ctime" if test "x$ac_cv_func_ctime" = xyes; then : else as_fn_error $? "Unable to find function ctime" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ctime is properly declared" >&5 $as_echo_n "checking whether ctime is properly declared... " >&6; } if ${hw_cv_func_ctime_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #error ctime(3) may produce different results on different OSes. Let's have our POSIX-compliant implementation all the time ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_ctime_proper=yes else hw_cv_func_ctime_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_ctime_proper" >&5 $as_echo "$hw_cv_func_ctime_proper" >&6; } if test "$hw_cv_func_ctime_proper" = yes; then : $as_echo "#define HAVE_ctime_PROPER 1" >>confdefs.h else post_macros="$post_macros #define ctime rpl_ctime" fi if test "$hw_cv_func_ctime_proper" = "no"; then : case " $LIBOBJS " in *" rpl_ctime.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS rpl_ctime.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "mkdir" "ac_cv_func_mkdir" if test "x$ac_cv_func_mkdir" = xyes; then : else as_fn_error $? "Unable to find function mkdir" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mkdir is properly declared" >&5 $as_echo_n "checking whether mkdir is properly declared... " >&6; } if ${hw_cv_func_mkdir_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { int mkdir(const char *pathname, mode_t mode); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_mkdir_proper=yes else hw_cv_func_mkdir_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_mkdir_proper" >&5 $as_echo "$hw_cv_func_mkdir_proper" >&6; } if test "$hw_cv_func_mkdir_proper" = yes; then : $as_echo "#define HAVE_mkdir_PROPER 1" >>confdefs.h else post_macros="$post_macros #define mkdir rpl_mkdir" fi ac_fn_c_check_func "$LINENO" "stat" "ac_cv_func_stat" if test "x$ac_cv_func_stat" = xyes; then : else as_fn_error $? "Unable to find function stat" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat is properly declared" >&5 $as_echo_n "checking whether stat is properly declared... " >&6; } if ${hw_cv_func_stat_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if defined(__MINGW32__) #error stat in Windows CRT ill-behaves #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_stat_proper=yes else hw_cv_func_stat_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_stat_proper" >&5 $as_echo "$hw_cv_func_stat_proper" >&6; } if test "$hw_cv_func_stat_proper" = yes; then : $as_echo "#define HAVE_stat_PROPER 1" >>confdefs.h else post_macros="$post_macros " fi ac_fn_c_check_func "$LINENO" "rename" "ac_cv_func_rename" if test "x$ac_cv_func_rename" = xyes; then : else as_fn_error $? "Unable to find function rename" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether rename is properly declared" >&5 $as_echo_n "checking whether rename is properly declared... " >&6; } if ${hw_cv_func_rename_proper+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #if defined(__MINGW32__) #error rename in Windows CRT ill-behaves #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : hw_cv_func_rename_proper=yes else hw_cv_func_rename_proper=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_rename_proper" >&5 $as_echo "$hw_cv_func_rename_proper" >&6; } if test "$hw_cv_func_rename_proper" = yes; then : $as_echo "#define HAVE_rename_PROPER 1" >>confdefs.h else post_macros="$post_macros #define rename rpl_rename" fi ac_fn_c_check_decl "$LINENO" "mkdtemp" "ac_cv_have_decl_mkdtemp" "$ac_includes_default" if test "x$ac_cv_have_decl_mkdtemp" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MKDTEMP $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp" if test "x$ac_cv_func_mkdtemp" = xyes; then : $as_echo "#define HAVE_MKDTEMP 1" >>confdefs.h else case " $LIBOBJS " in *" mkdtemp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS mkdtemp.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "strrstr" "ac_cv_have_decl_strrstr" "$ac_includes_default" if test "x$ac_cv_have_decl_strrstr" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRRSTR $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "strrstr" "ac_cv_func_strrstr" if test "x$ac_cv_func_strrstr" = xyes; then : $as_echo "#define HAVE_STRRSTR 1" >>confdefs.h else case " $LIBOBJS " in *" strrstr.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strrstr.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "stpncpy" "ac_cv_have_decl_stpncpy" "$ac_includes_default" if test "x$ac_cv_have_decl_stpncpy" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STPNCPY $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "stpncpy" "ac_cv_func_stpncpy" if test "x$ac_cv_func_stpncpy" = xyes; then : $as_echo "#define HAVE_STPNCPY 1" >>confdefs.h else case " $LIBOBJS " in *" stpncpy.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS stpncpy.$ac_objext" ;; esac fi for ac_func in seteuid setegid setreuid setregid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in uname gethostname chflags do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in mkfifo statfs statvfs door do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in sysinfo setsid sysconf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getzoneid getzonenamebyid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in fpathconf do : ac_fn_c_check_func "$LINENO" "fpathconf" "ac_cv_func_fpathconf" if test "x$ac_cv_func_fpathconf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FPATHCONF 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_MTIM 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec" "ac_cv_member_struct_stat_st_mtimespec" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_mtimespec" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_MTIMESPEC 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLOCKS 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PRIuMAX/PRIdMAX macros" >&5 $as_echo_n "checking for PRIuMAX/PRIdMAX macros... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #include #if defined(PRIuMAX) && defined(PRIdMAX) primacros_found #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "primacros_found" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Unable to find out how to scan intmax_t/uintmax_t types" >&5 $as_echo "Unable to find out how to scan intmax_t/uintmax_t types" >&6; } fi rm -f conftest* for ac_header in stdarg.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" if test "x$ac_cv_header_stdarg_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDARG_H 1 _ACEOF fi done for ac_header in inttypes.h locale.h stddef.h stdint.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct lconv" "decimal_point" "ac_cv_member_struct_lconv_decimal_point" "#include " if test "x$ac_cv_member_struct_lconv_decimal_point" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_LCONV_DECIMAL_POINT 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct lconv" "thousands_sep" "ac_cv_member_struct_lconv_thousands_sep" "#include " if test "x$ac_cv_member_struct_lconv_thousands_sep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_LCONV_THOUSANDS_SEP 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 $as_echo_n "checking for long double... " >&6; } if ${ac_cv_type_long_double+:} false; then : $as_echo_n "(cached) " >&6 else if test "$GCC" = yes; then ac_cv_type_long_double=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* The Stardent Vistra knows sizeof (long double), but does not support it. */ long double foo = 0.0L; int main () { static int test_array [1 - 2 * !(/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ sizeof (double) <= sizeof (long double))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_long_double=yes else ac_cv_type_long_double=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double" >&5 $as_echo "$ac_cv_type_long_double" >&6; } if test $ac_cv_type_long_double = yes; then $as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 $as_echo_n "checking for long long int... " >&6; } if ${ac_cv_type_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* For now, do not test the preprocessor; as of 2007 there are too many implementations with broken preprocessors. Perhaps this can be revisited in 2012. In the meantime, code should not expect #if to work with literals wider than 32 bits. */ /* Test literals. */ long long int ll = 9223372036854775807ll; long long int nll = -9223372036854775807LL; unsigned long long int ull = 18446744073709551615ULL; /* Test constant expressions. */ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 ? 1 : -1)]; int i = 63; int main () { /* Test availability of runtime routines for shift and division. */ long long int llmax = 9223372036854775807ll; unsigned long long int ullmax = 18446744073709551615ull; return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) | (llmax / ll) | (llmax % ll) | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) | (ullmax / ull) | (ullmax % ull)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if test "$cross_compiling" = yes; then : ac_cv_type_long_long_int=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef LLONG_MAX # define HALF \ (1LL << (sizeof (long long int) * CHAR_BIT - 2)) # define LLONG_MAX (HALF - 1 + HALF) #endif int main () { long long int n = 1; int i; for (i = 0; ; i++) { long long int m = n << i; if (m >> i != n) return 1; if (LLONG_MAX / 2 < m) break; } return 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_type_long_long_int=yes else ac_cv_type_long_long_int=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else ac_cv_type_long_long_int=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 $as_echo "$ac_cv_type_long_long_int" >&6; } if test $ac_cv_type_long_long_int = yes; then $as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 $as_echo_n "checking for unsigned long long int... " >&6; } if ${ac_cv_type_unsigned_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* For now, do not test the preprocessor; as of 2007 there are too many implementations with broken preprocessors. Perhaps this can be revisited in 2012. In the meantime, code should not expect #if to work with literals wider than 32 bits. */ /* Test literals. */ long long int ll = 9223372036854775807ll; long long int nll = -9223372036854775807LL; unsigned long long int ull = 18446744073709551615ULL; /* Test constant expressions. */ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 ? 1 : -1)]; int i = 63; int main () { /* Test availability of runtime routines for shift and division. */ long long int llmax = 9223372036854775807ll; unsigned long long int ullmax = 18446744073709551615ull; return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) | (llmax / ll) | (llmax % ll) | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) | (ullmax / ull) | (ullmax % ull)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_type_unsigned_long_long_int=yes else ac_cv_type_unsigned_long_long_int=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 $as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } if test $ac_cv_type_unsigned_long_long_int = yes; then $as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default" if test "x$ac_cv_type_intmax_t" = xyes; then : $as_echo "#define HAVE_INTMAX_T 1" >>confdefs.h else test $ac_cv_type_long_long_int = yes \ && ac_type='long long int' \ || ac_type='long int' cat >>confdefs.h <<_ACEOF #define intmax_t $ac_type _ACEOF fi ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" if test "x$ac_cv_type_uintmax_t" = xyes; then : $as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h else test $ac_cv_type_unsigned_long_long_int = yes \ && ac_type='unsigned long long int' \ || ac_type='unsigned long int' cat >>confdefs.h <<_ACEOF #define uintmax_t $ac_type _ACEOF fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : $as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h else for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define uintptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTRDIFF_T 1 _ACEOF fi for ac_func in localeconv do : ac_fn_c_check_func "$LINENO" "localeconv" "ac_cv_func_localeconv" if test "x$ac_cv_func_localeconv" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LOCALECONV 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" if test "x$ac_cv_func_vsnprintf" = xyes; then : hw_cv_func_vsnprintf=yes else hw_cv_func_vsnprintf=no fi if test "$hw_cv_func_vsnprintf" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vsnprintf is C99 compliant" >&5 $as_echo_n "checking whether vsnprintf is C99 compliant... " >&6; } if ${hw_cv_func_vsnprintf_c99+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func_vsnprintf_c99=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_STDARG_H #include #endif #include static int testprintf(char *buf, size_t size, const char *format, ...) { int result; va_list ap; va_start(ap, format); result = vsnprintf(buf, size, format, ap); va_end(ap); return result; } int main () { char buf[43]; if (testprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || testprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || testprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ testprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func_vsnprintf_c99=yes else hw_cv_func_vsnprintf_c99=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_vsnprintf_c99" >&5 $as_echo "$hw_cv_func_vsnprintf_c99" >&6; } else hw_cv_func_snprintf_c99=no fi if test "$hw_cv_func_vsnprintf_c99" = yes; then : $as_echo "#define HAVE_VSNPRINTF 1" >>confdefs.h else $as_echo "#define vsnprintf rpl_vsnprintf" >>confdefs.h $as_echo "#define vprintf rpl_vprintf" >>confdefs.h $as_echo "#define vfprintf rpl_vfprintf" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi for ac_header in stdarg.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" if test "x$ac_cv_header_stdarg_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDARG_H 1 _ACEOF fi done case " $LIBOBJS " in *" snprintf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test "x$ac_cv_func_snprintf" = xyes; then : hw_cv_func_snprintf=yes else hw_cv_func_snprintf=no fi if test "$hw_cv_func_snprintf" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf is C99 compliant" >&5 $as_echo_n "checking whether snprintf is C99 compliant... " >&6; } if ${hw_cv_func_snprintf_c99+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func_snprintf_c99=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char buf[43]; if (snprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || snprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || snprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ snprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func_snprintf_c99=yes else hw_cv_func_snprintf_c99=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_snprintf_c99" >&5 $as_echo "$hw_cv_func_snprintf_c99" >&6; } else hw_cv_func_snprintf_c99=no fi if test "$hw_cv_func_snprintf_c99" = yes; then : $as_echo "#define HAVE_SNPRINTF 1" >>confdefs.h else $as_echo "#define snprintf rpl_snprintf" >>confdefs.h $as_echo "#define printf rpl_printf" >>confdefs.h $as_echo "#define fprintf rpl_fprintf" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi for ac_header in stdarg.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" if test "x$ac_cv_header_stdarg_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDARG_H 1 _ACEOF fi done case " $LIBOBJS " in *" snprintf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;; esac fi for ac_header in varargs.h do : ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default" if test "x$ac_cv_header_varargs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VARARGS_H 1 _ACEOF fi done # Don't even bother checking for vasprintf if snprintf was standards # incompliant, this one is going to be too. if test "$hw_cv_func_snprintf_c99" = yes; then : for ac_func in vasprintf do : ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf" if test "x$ac_cv_func_vasprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VASPRINTF 1 _ACEOF hw_cv_func_vasprintf=yes else hw_cv_func_vasprintf=no fi done else hw_cv_func_vasprintf=no fi if test "$hw_cv_func_vasprintf" = no; then : $as_echo "#define vasprintf rpl_vasprintf" >>confdefs.h for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for va_copy" >&5 $as_echo_n "checking for va_copy... " >&6; } if ${hw_cv_func_va_copy+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func_va_copy=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif int main () { va_list ap, aq; va_copy(aq, ap); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func_va_copy=yes else hw_cv_func_va_copy=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func_va_copy" >&5 $as_echo "$hw_cv_func_va_copy" >&6; } if test "$hw_cv_func_va_copy" = yes; then : $as_echo "#define HAVE_VA_COPY 1" >>confdefs.h fi if test "$hw_cv_func_va_copy" = no; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __va_copy" >&5 $as_echo_n "checking for __va_copy... " >&6; } if ${hw_cv_func___va_copy+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : hw_cv_func___va_copy=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif int main () { va_list ap, aq; __va_copy(aq, ap); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : hw_cv_func___va_copy=yes else hw_cv_func___va_copy=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hw_cv_func___va_copy" >&5 $as_echo "$hw_cv_func___va_copy" >&6; } if test "$hw_cv_func___va_copy" = yes; then : $as_echo "#define HAVE___VA_COPY 1" >>confdefs.h fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi for ac_header in stdarg.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" if test "x$ac_cv_header_stdarg_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDARG_H 1 _ACEOF fi done case " $LIBOBJS " in *" snprintf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;; esac fi # Don't even bother checking for asprintf if snprintf was standards # incompliant, this one is going to be too. if test "$hw_cv_func_snprintf_c99" = yes; then : for ac_func in asprintf do : ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" if test "x$ac_cv_func_asprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ASPRINTF 1 _ACEOF hw_cv_func_asprintf=yes else hw_cv_func_asprintf=no fi done else hw_cv_func_asprintf=no fi if test "$hw_cv_func_asprintf" = no; then : $as_echo "#define asprintf rpl_asprintf" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi for ac_header in stdarg.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" if test "x$ac_cv_header_stdarg_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDARG_H 1 _ACEOF fi done case " $LIBOBJS " in *" snprintf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "$ac_includes_default #ifdef HAVE_DIRENT_H # include #endif " if test "x$ac_cv_have_decl_dirfd" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_DIRFD $ac_have_decl _ACEOF for ac_func in dirfd do : ac_fn_c_check_func "$LINENO" "dirfd" "ac_cv_func_dirfd" if test "x$ac_cv_func_dirfd" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DIRFD 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dirfd macro" >&5 $as_echo_n "checking for dirfd macro... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #ifdef HAVE_DIRENT_H # include #endif #ifdef dirfd dirfd_found #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "dirfd_found" >/dev/null 2>&1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } DIRFD_MACRO_FOUND=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f conftest* if test x$DIRFD_MACRO_FOUND = x; then case " $LIBOBJS " in *" dirfd.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS dirfd.$ac_objext" ;; esac fi fi done for ac_func in jail_get do : ac_fn_c_check_func "$LINENO" "jail_get" "ac_cv_func_jail_get" if test "x$ac_cv_func_jail_get" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_JAIL_GET 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5 $as_echo_n "checking for library containing setsockopt... " >&6; } if ${ac_cv_search_setsockopt+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); int main () { return setsockopt (); ; return 0; } _ACEOF for ac_lib in '' socket; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_setsockopt=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_setsockopt+:} false; then : break fi done if ${ac_cv_search_setsockopt+:} false; then : else ac_cv_search_setsockopt=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5 $as_echo "$ac_cv_search_setsockopt" >&6; } ac_res=$ac_cv_search_setsockopt if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostent" >&5 $as_echo_n "checking for library containing gethostent... " >&6; } if ${ac_cv_search_gethostent+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostent (); int main () { return gethostent (); ; return 0; } _ACEOF for ac_lib in '' nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_gethostent=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_gethostent+:} false; then : break fi done if ${ac_cv_search_gethostent+:} false; then : else ac_cv_search_gethostent=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostent" >&5 $as_echo "$ac_cv_search_gethostent" >&6; } ac_res=$ac_cv_search_gethostent if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi for ac_func in socket do : ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" if test "x$ac_cv_func_socket" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SOCKET 1 _ACEOF fi done for ac_func in setsockopt do : ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" if test "x$ac_cv_func_setsockopt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETSOCKOPT 1 _ACEOF fi done for ac_func in gethostent do : ac_fn_c_check_func "$LINENO" "gethostent" "ac_cv_func_gethostent" if test "x$ac_cv_func_gethostent" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETHOSTENT 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" " #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif " if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_STORAGE 1 _ACEOF fi ac_fn_c_check_decl "$LINENO" "getaddrinfo" "ac_cv_have_decl_getaddrinfo" " #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif " if test "x$ac_cv_have_decl_getaddrinfo" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETADDRINFO $ac_have_decl _ACEOF if test $ac_have_decl = 1; then : else case " $LIBOBJS " in *" getaddrinfo.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "inet_ntop" "ac_cv_have_decl_inet_ntop" "#include " if test "x$ac_cv_have_decl_inet_ntop" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_INET_NTOP $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" "#include " if test "x$ac_cv_have_decl_inet_pton" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_INET_PTON $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop" if test "x$ac_cv_func_inet_ntop" = xyes; then : $as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h else case " $LIBOBJS " in *" inet_ntop.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS inet_ntop.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "inet_pton" "ac_cv_func_inet_pton" if test "x$ac_cv_func_inet_pton" = xyes; then : $as_echo "#define HAVE_INET_PTON 1" >>confdefs.h else case " $LIBOBJS " in *" inet_pton.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS inet_pton.$ac_objext" ;; esac fi for ac_func in getifaddrs do : ac_fn_c_check_func "$LINENO" "getifaddrs" "ac_cv_func_getifaddrs" if test "x$ac_cv_func_getifaddrs" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETIFADDRS 1 _ACEOF fi done for ac_func in getprocs64 do : ac_fn_c_check_func "$LINENO" "getprocs64" "ac_cv_func_getprocs64" if test "x$ac_cv_func_getprocs64" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPROCS64 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "lchown" "ac_cv_func_lchown" if test "x$ac_cv_func_lchown" = xyes; then : $as_echo "#define HAVE_LCHOWN 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "pthread_attr_setstacksize" "ac_cv_have_decl_pthread_attr_setstacksize" "#include " if test "x$ac_cv_have_decl_pthread_attr_setstacksize" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PTHREAD_ATTR_SETSTACKSIZE $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "pthread_attr_setstacksize" "ac_cv_func_pthread_attr_setstacksize" if test "x$ac_cv_func_pthread_attr_setstacksize" = xyes; then : $as_echo "#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1" >>confdefs.h else case " $LIBOBJS " in *" pthread_attr_setstacksize.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS pthread_attr_setstacksize.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "pthread_sigmask" "ac_cv_have_decl_pthread_sigmask" "#include " if test "x$ac_cv_have_decl_pthread_sigmask" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PTHREAD_SIGMASK $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "pthread_sigmask" "ac_cv_func_pthread_sigmask" if test "x$ac_cv_func_pthread_sigmask" = xyes; then : $as_echo "#define HAVE_PTHREAD_SIGMASK 1" >>confdefs.h else case " $LIBOBJS " in *" pthread_sigmask.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS pthread_sigmask.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "sched_yield" "ac_cv_have_decl_sched_yield" "#include " if test "x$ac_cv_have_decl_sched_yield" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SCHED_YIELD $ac_have_decl _ACEOF for ac_func in sched_yield do : ac_fn_c_check_func "$LINENO" "sched_yield" "ac_cv_func_sched_yield" if test "x$ac_cv_func_sched_yield" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SCHED_YIELD 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "openat" "ac_cv_have_decl_openat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_openat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_OPENAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fstatat" "ac_cv_have_decl_fstatat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_fstatat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FSTATAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fchownat" "ac_cv_have_decl_fchownat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_fchownat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FCHOWNAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fchmodat" "ac_cv_have_decl_fchmodat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_fchmodat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FCHMODAT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "readlinkat" "ac_cv_have_decl_readlinkat" "#define _GNU_SOURCE 1 #include " if test "x$ac_cv_have_decl_readlinkat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_READLINKAT $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "openat" "ac_cv_func_openat" if test "x$ac_cv_func_openat" = xyes; then : $as_echo "#define HAVE_OPENAT 1" >>confdefs.h else case " $LIBOBJS " in *" openat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS openat.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "fstatat" "ac_cv_func_fstatat" if test "x$ac_cv_func_fstatat" = xyes; then : $as_echo "#define HAVE_FSTATAT 1" >>confdefs.h else case " $LIBOBJS " in *" fstatat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS fstatat.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "fchownat" "ac_cv_func_fchownat" if test "x$ac_cv_func_fchownat" = xyes; then : $as_echo "#define HAVE_FCHOWNAT 1" >>confdefs.h else case " $LIBOBJS " in *" fchownat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS fchownat.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "fchmodat" "ac_cv_func_fchmodat" if test "x$ac_cv_func_fchmodat" = xyes; then : $as_echo "#define HAVE_FCHMODAT 1" >>confdefs.h else case " $LIBOBJS " in *" fchmodat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS fchmodat.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "readlinkat" "ac_cv_func_readlinkat" if test "x$ac_cv_func_readlinkat" = xyes; then : $as_echo "#define HAVE_READLINKAT 1" >>confdefs.h else case " $LIBOBJS " in *" readlinkat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS readlinkat.$ac_objext" ;; esac fi ac_fn_c_check_decl "$LINENO" "log2" "ac_cv_have_decl_log2" "#include " if test "x$ac_cv_have_decl_log2" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOG2 $ac_have_decl _ACEOF ac_fn_c_check_func "$LINENO" "log2" "ac_cv_func_log2" if test "x$ac_cv_func_log2" = xyes; then : $as_echo "#define HAVE_LOG2 1" >>confdefs.h else case " $LIBOBJS " in *" log2.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS log2.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "fexecve" "ac_cv_func_fexecve" if test "x$ac_cv_func_fexecve" = xyes; then : $as_echo "#define HAVE_FEXECVE 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "alarm" "ac_cv_have_decl_alarm" "$ac_includes_default" if test "x$ac_cv_have_decl_alarm" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_ALARM $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "chmod" "ac_cv_have_decl_chmod" "$ac_includes_default" if test "x$ac_cv_have_decl_chmod" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CHMOD $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "chown" "ac_cv_have_decl_chown" "$ac_includes_default" if test "x$ac_cv_have_decl_chown" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CHOWN $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fchmod" "ac_cv_have_decl_fchmod" "$ac_includes_default" if test "x$ac_cv_have_decl_fchmod" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FCHMOD $ac_have_decl _ACEOF for ac_func in fchmod do : ac_fn_c_check_func "$LINENO" "fchmod" "ac_cv_func_fchmod" if test "x$ac_cv_func_fchmod" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FCHMOD 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "uname" "ac_cv_have_decl_uname" "$ac_includes_default" if test "x$ac_cv_have_decl_uname" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_UNAME $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "getuid" "ac_cv_have_decl_getuid" "$ac_includes_default" if test "x$ac_cv_have_decl_getuid" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETUID $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "getgid" "ac_cv_have_decl_getgid" "$ac_includes_default" if test "x$ac_cv_have_decl_getgid" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GETGID $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "lstat" "ac_cv_have_decl_lstat" "$ac_includes_default" if test "x$ac_cv_have_decl_lstat" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LSTAT $ac_have_decl _ACEOF for ac_func in sleep do : ac_fn_c_check_func "$LINENO" "sleep" "ac_cv_func_sleep" if test "x$ac_cv_func_sleep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SLEEP 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "socketpair" "ac_cv_have_decl_socketpair" "#include " if test "x$ac_cv_have_decl_socketpair" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SOCKETPAIR $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "fsync" "ac_cv_have_decl_fsync" "$ac_includes_default" if test "x$ac_cv_have_decl_fsync" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FSYNC $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "glob" "ac_cv_have_decl_glob" "#include " if test "x$ac_cv_have_decl_glob" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GLOB $ac_have_decl _ACEOF ac_fn_c_check_member "$LINENO" "struct sockaddr" "sa_len" "ac_cv_member_struct_sockaddr_sa_len" " #include #include " if test "x$ac_cv_member_struct_sockaddr_sa_len" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_SA_LEN 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct ifreq" "ifr_hwaddr" "ac_cv_member_struct_ifreq_ifr_hwaddr" " #include #include " if test "x$ac_cv_member_struct_ifreq_ifr_hwaddr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_IFREQ_IFR_HWADDR 1 _ACEOF fi for ac_header in sys/sysctl.h do : ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_sysctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SYSCTL_H 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct sysinfo" "uptime" "ac_cv_member_struct_sysinfo_uptime" "#include " if test "x$ac_cv_member_struct_sysinfo_uptime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SYSINFO_UPTIME 1 _ACEOF fi for ac_header in sys/sysctl.h do : ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include #endif " if test "x$ac_cv_header_sys_sysctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SYSCTL_H 1 _ACEOF fi done for ac_header in kstat.h do : ac_fn_c_check_header_mongrel "$LINENO" "kstat.h" "ac_cv_header_kstat_h" "$ac_includes_default" if test "x$ac_cv_header_kstat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_KSTAT_H 1 _ACEOF fi done for ac_header in utmp.h do : ac_fn_c_check_header_mongrel "$LINENO" "utmp.h" "ac_cv_header_utmp_h" "$ac_includes_default" if test "x$ac_cv_header_utmp_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTMP_H 1 _ACEOF fi done for ac_header in utmpx.h do : ac_fn_c_check_header_mongrel "$LINENO" "utmpx.h" "ac_cv_header_utmpx_h" "$ac_includes_default" if test "x$ac_cv_header_utmpx_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTMPX_H 1 _ACEOF fi done for ac_header in linux/fs.h do : ac_fn_c_check_header_mongrel "$LINENO" "linux/fs.h" "ac_cv_header_linux_fs_h" "$ac_includes_default" if test "x$ac_cv_header_linux_fs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LINUX_FS_H 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "FICLONE" "ac_cv_have_decl_FICLONE" "#include " if test "x$ac_cv_have_decl_FICLONE" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FICLONE $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "SEEK_DATA" "ac_cv_have_decl_SEEK_DATA" " #define _GNU_SOURCE #include " if test "x$ac_cv_have_decl_SEEK_DATA" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SEEK_DATA $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "FALLOC_FL_PUNCH_HOLE" "ac_cv_have_decl_FALLOC_FL_PUNCH_HOLE" " #define _GNU_SOURCE #include " if test "x$ac_cv_have_decl_FALLOC_FL_PUNCH_HOLE" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_FALLOC_FL_PUNCH_HOLE $ac_have_decl _ACEOF for ac_header in sys/sendfile.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/sendfile.h" "ac_cv_header_sys_sendfile_h" "$ac_includes_default" if test "x$ac_cv_header_sys_sendfile_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_SENDFILE_H 1 _ACEOF fi done for ac_func in sendfile do : ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile" if test "x$ac_cv_func_sendfile" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SENDFILE 1 _ACEOF fi done for ac_func in copy_file_range do : ac_fn_c_check_func "$LINENO" "copy_file_range" "ac_cv_func_copy_file_range" if test "x$ac_cv_func_copy_file_range" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_COPY_FILE_RANGE 1 _ACEOF fi done rtry=none { $as_echo "$as_me:${as_lineno-$LINENO}: checking for either struct rtentry or struct ortentry" >&5 $as_echo_n "checking for either struct rtentry or struct ortentry... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "rtentry" >/dev/null 2>&1; then : rtry=rtentry fi rm -f conftest* if test "$rtry" = rtentry; then $as_echo "#define HAVE_RTENTRY 1" >>confdefs.h fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "ortentry" >/dev/null 2>&1; then : rtry=ortentry fi rm -f conftest* if test "$rtry" = ortentry; then $as_echo "#define HAVE_ORTENTRY 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rtry" >&5 $as_echo "$rtry" >&6; } for ac_func in llistxattr do : ac_fn_c_check_func "$LINENO" "llistxattr" "ac_cv_func_llistxattr" if test "x$ac_cv_func_llistxattr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LLISTXATTR 1 _ACEOF $as_echo "#define WITH_XATTR 1" >>confdefs.h fi done for ac_header in attr/xattr.h sys/xattr.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether xattr functions have extra arguments" >&5 $as_echo_n "checking whether xattr functions have extra arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { (void)llistxattr("", 0, 0, 0); (void)lgetxattr("", "", 0, 0, 0, 0); (void)lsetxattr("", "", "", 0, 0, 0); (void)lremovexattr("", "", 0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define WITH_XATTR_EXTRA_ARGS 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext saved_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wno-tautological-constant-out-of-range-compare" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wno-tautological-constant-out-of-range-compare" >&5 $as_echo_n "checking whether compiler supports -Wno-tautological-constant-out-of-range-compare... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } NO_TAUTOLOGICAL_CC_OPTION="-Wno-tautological-constant-out-of-range-compare" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } NO_TAUTOLOGICAL_CC_OPTION="" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$saved_CFLAGS" # Check whether --enable-selinux was given. if test "${enable_selinux+set}" = set; then : enableval=$enable_selinux; fi case "$target_os" in solaris2.8|solaris2.9) $as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h ;; solaris2.10|solaris2.11) $as_echo "#define _XOPEN_SOURCE 600" >>confdefs.h $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h ;; hpux*|hp-ux*) $as_echo "#define _PSTAT64 1" >>confdefs.h ;; aix*) CPPFLAGS="$CPPFLAGS -w" ;; linux*|*bsd*|*gnu*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yp_get_default_domain in -lnss_nis" >&5 $as_echo_n "checking for yp_get_default_domain in -lnss_nis... " >&6; } if ${ac_cv_lib_nss_nis_yp_get_default_domain+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnss_nis $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char yp_get_default_domain (); int main () { return yp_get_default_domain (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nss_nis_yp_get_default_domain=yes else ac_cv_lib_nss_nis_yp_get_default_domain=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nss_nis_yp_get_default_domain" >&5 $as_echo "$ac_cv_lib_nss_nis_yp_get_default_domain" >&6; } if test "x$ac_cv_lib_nss_nis_yp_get_default_domain" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSS_NIS 1 _ACEOF LIBS="-lnss_nis $LIBS" fi ;; freebsd*|dragonfly*) ;; netbsd*) ;; unicos*) ;; cray*) ;; qnx*) ;; openbsd*|obsd*) ;; sysv4.2MP|unix_sv*) ;; cygwin*) ;; mingw*) ;; sco*) ;; darwin*) ;; *) as_fn_error $? "Unknown system type $target_os" "$LINENO" 5 ;; esac # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # # OS kernels conditionals. Don't use those unless it is really needed (if code # depends on the *kernel* feature, and even then -- some kernel features are # shared by different kernels). # # Good example: use LINUX to select code which uses inotify and netlink sockets. # Bad example: use LINUX to select code which parses output of coreutils' ps(1). # if test -n "`echo ${target_os} | grep linux`"; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test -n "`echo ${target_os} | grep darwin`"; then MACOSX_TRUE= MACOSX_FALSE='#' else MACOSX_TRUE='#' MACOSX_FALSE= fi if test -n "`(echo ${target_os} | egrep 'solaris|sunos')`"; then SOLARIS_TRUE= SOLARIS_FALSE='#' else SOLARIS_TRUE='#' SOLARIS_FALSE= fi if test -n "`(echo ${target_os} | egrep 'mingw|cygwin')`"; then NT_TRUE= NT_FALSE='#' else NT_TRUE='#' NT_FALSE= fi if test -n "`(echo ${target_os} | egrep 'cygwin')`"; then CYGWIN_TRUE= CYGWIN_FALSE='#' else CYGWIN_TRUE='#' CYGWIN_FALSE= fi if test -n "`(echo ${target_os} | grep aix)`"; then AIX_TRUE= AIX_FALSE='#' else AIX_TRUE='#' AIX_FALSE= fi if test -n "`(echo ${target_os} | egrep 'hpux|hp-ux')`"; then HPUX_TRUE= HPUX_FALSE='#' else HPUX_TRUE='#' HPUX_FALSE= fi if test -n "`(echo ${target_os} | grep freebsd)`"; then FREEBSD_TRUE= FREEBSD_FALSE='#' else FREEBSD_TRUE='#' FREEBSD_FALSE= fi if test -n "`(echo ${target_os} | grep netbsd)`"; then NETBSD_TRUE= NETBSD_FALSE='#' else NETBSD_TRUE='#' NETBSD_FALSE= fi if test -n "`(echo ${target_os} | grep darwin)`"; then XNU_TRUE= XNU_FALSE='#' else XNU_TRUE='#' XNU_FALSE= fi # Check whether --with-workdir was given. if test "${with_workdir+set}" = set; then : withval=$with_workdir; if test "x$withval" != x ; then WORKDIR="$withval" LOGDIR="$withval" PIDDIR="$withval" fi fi _lcl_receval=""${WORKDIR}"" WORKDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define WORKDIR "${WORKDIR}" _ACEOF workdir="${WORKDIR}" # Check whether --with-masterdir was given. if test "${with_masterdir+set}" = set; then : withval=$with_masterdir; if test "x$withval" != x ; then MASTERDIR="$withval" fi fi _lcl_receval=""${MASTERDIR}"" MASTERDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define MASTERDIR "${MASTERDIR}" _ACEOF masterdir="${MASTERDIR}" # Check whether --with-inputdir was given. if test "${with_inputdir+set}" = set; then : withval=$with_inputdir; if test "x$withval" != x ; then INPUTDIR="$withval" fi fi _lcl_receval=""${INPUTDIR}"" INPUTDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define INPUTDIR "${INPUTDIR}" _ACEOF inputdir="${INPUTDIR}" # Check whether --with-datadir was given. if test "${with_datadir+set}" = set; then : withval=$with_datadir; if test "x$withval" != x ; then DATADIR="$withval" fi fi _lcl_receval=""${DATADIR}"" DATADIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define CF_DATADIR "${DATADIR}" _ACEOF datadir="${DATADIR}" # Check whether --with-logdir was given. if test "${with_logdir+set}" = set; then : withval=$with_logdir; if test "x$withval" != x ; then LOGDIR="$withval" fi fi _lcl_receval=""${LOGDIR}"" LOGDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define LOGDIR "${LOGDIR}" _ACEOF logdir="${LOGDIR}" # Check whether --with-piddir was given. if test "${with_piddir+set}" = set; then : withval=$with_piddir; if test "x$withval" != x ; then PIDDIR="$withval" fi fi _lcl_receval=""${PIDDIR}"" PIDDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define PIDDIR "${PIDDIR}" _ACEOF piddir="${PIDDIR}" # Check whether --with-statedir was given. if test "${with_statedir+set}" = set; then : withval=$with_statedir; if test "x$withval" != x ; then STATEDIR="$withval" fi fi _lcl_receval=""${STATEDIR}"" STATEDIR=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define STATEDIR "${STATEDIR}" _ACEOF statedir="${STATEDIR}" # Check whether --with-shell was given. if test "${with_shell+set}" = set; then : withval=$with_shell; else with_shell=/bin/sh fi _lcl_receval=""${bindir}"" bindir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` cat >>confdefs.h <<_ACEOF #define BINDIR "${bindir}" _ACEOF bindir="${bindir}" if test "x$with_shell" = "xno"; then as_fn_error $? "Please specify full path to POSIX-compatible shell" "$LINENO" 5 fi cat >>confdefs.h <<_ACEOF #define SHELL_PATH "$with_shell" _ACEOF # Extract the first word of "hostname", so it can be a program name with args. set dummy hostname; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_HOSTNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $HOSTNAME in [\\/]* | ?:[\\/]*) ac_cv_path_HOSTNAME="$HOSTNAME" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_HOSTNAME="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_HOSTNAME" && ac_cv_path_HOSTNAME="""" ;; esac fi HOSTNAME=$ac_cv_path_HOSTNAME if test -n "$HOSTNAME"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HOSTNAME" >&5 $as_echo "$HOSTNAME" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi cat >>confdefs.h <<_ACEOF #define AUTOCONF_HOSTNAME "`$HOSTNAME`" _ACEOF cat >>confdefs.h <<_ACEOF #define AUTOCONF_SYSNAME "$target_os" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Xen cpuid-based HVM detection" >&5 $as_echo_n "checking for Xen cpuid-based HVM detection... " >&6; } if test x"$GCC" = "xyes"; then case $host_cpu in i[3456]86*|x86_64*|amd64) $as_echo "#define XEN_CPUID_SUPPORT 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Check whether --enable-coverage was given. if test "${enable_coverage+set}" = set; then : enableval=$enable_coverage; use_coverage=$enableval else use_coverage=no fi if test "x$use_coverage" = "xyes"; then if test "$GCC" != "yes"; then as_fn_error $? "GCC is required for --enable-coverage" "$LINENO" 5 fi # Extract the first word of "lcov", so it can be a program name with args. set dummy lcov; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LCOV+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LCOV"; then ac_cv_prog_LCOV="$LCOV" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LCOV="lcov" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LCOV=$ac_cv_prog_LCOV if test -n "$LCOV"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 $as_echo "$LCOV" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "genhtml", so it can be a program name with args. set dummy genhtml; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LCOV_GENHTML+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LCOV_GENHTML"; then ac_cv_prog_LCOV_GENHTML="$LCOV_GENHTML" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LCOV_GENHTML="genhtml" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LCOV_GENHTML=$ac_cv_prog_LCOV_GENHTML if test -n "$LCOV_GENHTML"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV_GENHTML" >&5 $as_echo "$LCOV_GENHTML" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$LCOV"; then as_fn_error $? "Cannot find lcov from the LTP package" "$LINENO" 5 fi if test -z "$LCOV_GENHTML"; then as_fn_error $? "Could not find genhtml from the LTP package" "$LINENO" 5 fi CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov" # Need to set ENABLE_COVERAGE so that tests/unit/Makefile.am can adapt for one # test which needs gcov stubs if core not built with coverage. if true; then ENABLE_COVERAGE_TRUE= ENABLE_COVERAGE_FALSE='#' else ENABLE_COVERAGE_TRUE='#' ENABLE_COVERAGE_FALSE= fi else if false; then ENABLE_COVERAGE_TRUE= ENABLE_COVERAGE_FALSE='#' else ENABLE_COVERAGE_TRUE='#' ENABLE_COVERAGE_FALSE= fi fi CORE_CPPFLAGS="$PCRE2_CPPFLAGS $OPENSSL_CPPFLAGS $LIBYAML_CPPFLAGS $CPPFLAGS" CORE_CFLAGS="$PCRE2_CFLAGS $OPENSSL_CFLAGS $LIBYAML_CFLAGS $CFLAGS" CORE_LDFLAGS="$PCRE2_LDFLAGS $OPENSSL_LDFLAGS $LIBYAML_LDFLAGS $LDFLAGS" CORE_LIBS="$PCRE2_LIBS $OPENSSL_LIBS $LIBYAML_LIBS $LIBS" # # Populate contents of config.post.h # ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_control" "ac_cv_member_struct_msghdr_msg_control" "#include #include " if test "x$ac_cv_member_struct_msghdr_msg_control" = xyes; then : $as_echo "#define HAVE_MSGHDR_MSG_CONTROL 1" >>confdefs.h else $as_echo "#define HAVE_NO_MSGHDR_MSG_CONTROL 1" >>confdefs.h fi ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_accrights" "ac_cv_member_struct_msghdr_msg_accrights" "#include #include " if test "x$ac_cv_member_struct_msghdr_msg_accrights" = xyes; then : $as_echo "#define HAVE_MSGHDR_ACCRIGHTS 1" >>confdefs.h else $as_echo "#define HAVE_NO_MSGHDR_ACCRIGHTS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Summary:" >&5 $as_echo "Summary:" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: > Version: 1.0.0" >&5 $as_echo "> Version: 1.0.0" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: > Optional libraries" >&5 $as_echo "> Optional libraries" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> OpenSSL: $OPENSSL_PATH" >&5 $as_echo "-> OpenSSL: $OPENSSL_PATH" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> PCRE2: $PCRE2_PATH" >&5 $as_echo "-> PCRE2: $PCRE2_PATH" >&6; } if test "x$ac_cv_lib_yaml_yaml_parser_initialize" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libyaml: $LIBYAML_PATH" >&5 $as_echo "-> libyaml: $LIBYAML_PATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: -> libyaml: disabled" >&5 $as_echo "-> libyaml: disabled" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } ac_config_files="$ac_config_files Makefile libcompat/Makefile libutils/Makefile libutils/writer.h libutils/clockid_t.h libutils/regex.h libutils/glob_lib.h libutils/json-yaml.h config.post.h tests/Makefile tests/static-check/Makefile tests/unit/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NDEBUG_TRUE}" && test -z "${NDEBUG_FALSE}"; then as_fn_error $? "conditional \"NDEBUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_OPENSSL_TRUE}" && test -z "${WITH_OPENSSL_FALSE}"; then as_fn_error $? "conditional \"WITH_OPENSSL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_OPENSSL_TRUE}" && test -z "${WITH_OPENSSL_FALSE}"; then as_fn_error $? "conditional \"WITH_OPENSSL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_PCRE2_TRUE}" && test -z "${WITH_PCRE2_FALSE}"; then as_fn_error $? "conditional \"WITH_PCRE2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_PCRE2_TRUE}" && test -z "${WITH_PCRE2_FALSE}"; then as_fn_error $? "conditional \"WITH_PCRE2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MACOSX_TRUE}" && test -z "${MACOSX_FALSE}"; then as_fn_error $? "conditional \"MACOSX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then as_fn_error $? "conditional \"SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NT_TRUE}" && test -z "${NT_FALSE}"; then as_fn_error $? "conditional \"NT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CYGWIN_TRUE}" && test -z "${CYGWIN_FALSE}"; then as_fn_error $? "conditional \"CYGWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AIX_TRUE}" && test -z "${AIX_FALSE}"; then as_fn_error $? "conditional \"AIX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HPUX_TRUE}" && test -z "${HPUX_FALSE}"; then as_fn_error $? "conditional \"HPUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_TRUE}" && test -z "${FREEBSD_FALSE}"; then as_fn_error $? "conditional \"FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NETBSD_TRUE}" && test -z "${NETBSD_FALSE}"; then as_fn_error $? "conditional \"NETBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${XNU_TRUE}" && test -z "${XNU_FALSE}"; then as_fn_error $? "conditional \"XNU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_COVERAGE_TRUE}" && test -z "${ENABLE_COVERAGE_FALSE}"; then as_fn_error $? "conditional \"ENABLE_COVERAGE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_COVERAGE_TRUE}" && test -z "${ENABLE_COVERAGE_FALSE}"; then as_fn_error $? "conditional \"ENABLE_COVERAGE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libntech $as_me 1.0.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider. libntech home page: ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libntech config.status 1.0.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libcompat/Makefile") CONFIG_FILES="$CONFIG_FILES libcompat/Makefile" ;; "libutils/Makefile") CONFIG_FILES="$CONFIG_FILES libutils/Makefile" ;; "libutils/writer.h") CONFIG_FILES="$CONFIG_FILES libutils/writer.h" ;; "libutils/clockid_t.h") CONFIG_FILES="$CONFIG_FILES libutils/clockid_t.h" ;; "libutils/regex.h") CONFIG_FILES="$CONFIG_FILES libutils/regex.h" ;; "libutils/glob_lib.h") CONFIG_FILES="$CONFIG_FILES libutils/glob_lib.h" ;; "libutils/json-yaml.h") CONFIG_FILES="$CONFIG_FILES libutils/json-yaml.h" ;; "config.post.h") CONFIG_FILES="$CONFIG_FILES config.post.h" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/static-check/Makefile") CONFIG_FILES="$CONFIG_FILES tests/static-check/Makefile" ;; "tests/unit/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build static libraries. build_old_libs=$enable_static # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: DONE: Configuration done. Run make/gmake to build libntech." >&5 $as_echo "DONE: Configuration done. Run make/gmake to build libntech." >&6; } cfengine-3.24.2/libntech/missing0000755000000000000000000001533015010704272016545 0ustar00rootroot00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/libntech/m4/0000755000000000000000000000000015010704322015460 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/m4/adl_recursive_eval.m40000644000000000000000000000116715010704254021571 0ustar00rootroot00000000000000dnl adl_RECURSIVE_EVAL(VALUE, RESULT) dnl ================================= dnl Interpolate the VALUE in loop until it doesn't change, dnl and set the result to $RESULT. dnl WARNING: It's easy to get an infinite loop with some unsane input. AC_DEFUN([adl_RECURSIVE_EVAL], [_lcl_receval="$1" $2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do _lcl_receval_old="[$]_lcl_receval" eval _lcl_receval="\"[$]_lcl_receval\"" done echo "[$]_lcl_receval")`]) cfengine-3.24.2/libntech/m4/lt~obsolete.m40000644000000000000000000001377415010704266020317 0ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) cfengine-3.24.2/libntech/m4/old-autoconf.m40000644000000000000000000001260715010704254020326 0ustar00rootroot00000000000000AC_DEFUN([AC_TYPE_LONG_DOUBLE], [ AC_CACHE_CHECK([for long double], [ac_cv_type_long_double], [if test "$GCC" = yes; then ac_cv_type_long_double=yes else AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [[/* The Stardent Vistra knows sizeof (long double), but does not support it. */ long double foo = 0.0L;]], [[/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ sizeof (double) <= sizeof (long double)]])], [ac_cv_type_long_double=yes], [ac_cv_type_long_double=no]) fi]) if test $ac_cv_type_long_double = yes; then AC_DEFINE([HAVE_LONG_DOUBLE], 1, [Define to 1 if the system has the type `long double'.]) fi ]) AC_DEFUN([AC_TYPE_LONG_LONG_INT], [ AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], [AC_LINK_IFELSE( [_AC_TYPE_LONG_LONG_SNIPPET], [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. dnl If cross compiling, assume the bug isn't important, since dnl nobody cross compiles for this platform as far as we know. AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[@%:@include @%:@ifndef LLONG_MAX @%:@ define HALF \ (1LL << (sizeof (long long int) * CHAR_BIT - 2)) @%:@ define LLONG_MAX (HALF - 1 + HALF) @%:@endif]], [[long long int n = 1; int i; for (i = 0; ; i++) { long long int m = n << i; if (m >> i != n) return 1; if (LLONG_MAX / 2 < m) break; } return 0;]])], [ac_cv_type_long_long_int=yes], [ac_cv_type_long_long_int=no], [ac_cv_type_long_long_int=yes])], [ac_cv_type_long_long_int=no])]) if test $ac_cv_type_long_long_int = yes; then AC_DEFINE([HAVE_LONG_LONG_INT], 1, [Define to 1 if the system has the type `long long int'.]) fi ]) AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], [ AC_CACHE_CHECK([for unsigned long long int], [ac_cv_type_unsigned_long_long_int], [AC_LINK_IFELSE( [_AC_TYPE_LONG_LONG_SNIPPET], [ac_cv_type_unsigned_long_long_int=yes], [ac_cv_type_unsigned_long_long_int=no])]) if test $ac_cv_type_unsigned_long_long_int = yes; then AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1, [Define to 1 if the system has the type `unsigned long long int'.]) fi ]) AC_DEFUN([AC_TYPE_INTMAX_T], [ AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) AC_CHECK_TYPE([intmax_t], [AC_DEFINE([HAVE_INTMAX_T], 1, [Define to 1 if the system has the type `intmax_t'.])], [test $ac_cv_type_long_long_int = yes \ && ac_type='long long int' \ || ac_type='long int' AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], [Define to the widest signed integer type if and do not define.])]) ]) AC_DEFUN([AC_TYPE_UINTMAX_T], [ AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) AC_CHECK_TYPE([uintmax_t], [AC_DEFINE([HAVE_UINTMAX_T], 1, [Define to 1 if the system has the type `uintmax_t'.])], [test $ac_cv_type_unsigned_long_long_int = yes \ && ac_type='unsigned long long int' \ || ac_type='unsigned long int' AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type], [Define to the widest unsigned integer type if and do not define.])]) ]) AC_DEFUN([AC_TYPE_UINTPTR_T], [ AC_CHECK_TYPE([uintptr_t], [AC_DEFINE([HAVE_UINTPTR_T], 1, [Define to 1 if the system has the type `uintptr_t'.])], [for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [AC_INCLUDES_DEFAULT], [[sizeof (void *) <= sizeof ($ac_type)]])], [AC_DEFINE_UNQUOTED([uintptr_t], [$ac_type], [Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it.]) ac_type=]) test -z "$ac_type" && break done]) ]) AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], [ AC_LANG_PROGRAM( [[/* For now, do not test the preprocessor; as of 2007 there are too many implementations with broken preprocessors. Perhaps this can be revisited in 2012. In the meantime, code should not expect #if to work with literals wider than 32 bits. */ /* Test literals. */ long long int ll = 9223372036854775807ll; long long int nll = -9223372036854775807LL; unsigned long long int ull = 18446744073709551615ULL; /* Test constant expressions. */ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 ? 1 : -1)]; int i = 63;]], [[/* Test availability of runtime routines for shift and division. */ long long int llmax = 9223372036854775807ll; unsigned long long int ullmax = 18446744073709551615ull; return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) | (llmax / ll) | (llmax % ll) | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) | (ullmax / ull) | (ullmax % ull));]]) ]) cfengine-3.24.2/libntech/m4/ltsugar.m40000644000000000000000000001044015010704266017411 0ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) cfengine-3.24.2/libntech/m4/ltversion.m40000644000000000000000000000127315010704266017761 0ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) cfengine-3.24.2/libntech/m4/ltoptions.m40000644000000000000000000003426215010704266017773 0ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) cfengine-3.24.2/libntech/m4/cf3_platforms.m40000644000000000000000000000374015010704254020474 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # # OS kernels conditionals. Don't use those unless it is really needed (if code # depends on the *kernel* feature, and even then -- some kernel features are # shared by different kernels). # # Good example: use LINUX to select code which uses inotify and netlink sockets. # Bad example: use LINUX to select code which parses output of coreutils' ps(1). # AM_CONDITIONAL([LINUX], [test -n "`echo ${target_os} | grep linux`"]) AM_CONDITIONAL([MACOSX], [test -n "`echo ${target_os} | grep darwin`"]) AM_CONDITIONAL([SOLARIS], [test -n "`(echo ${target_os} | egrep 'solaris|sunos')`"]) AM_CONDITIONAL([NT], [test -n "`(echo ${target_os} | egrep 'mingw|cygwin')`"]) AM_CONDITIONAL([CYGWIN], [test -n "`(echo ${target_os} | egrep 'cygwin')`"]) AM_CONDITIONAL([AIX], [test -n "`(echo ${target_os} | grep aix)`"]) AM_CONDITIONAL([HPUX], [test -n "`(echo ${target_os} | egrep 'hpux|hp-ux')`"]) AM_CONDITIONAL([FREEBSD], [test -n "`(echo ${target_os} | grep freebsd)`"]) AM_CONDITIONAL([NETBSD], [test -n "`(echo ${target_os} | grep netbsd)`"]) AM_CONDITIONAL([XNU], [test -n "`(echo ${target_os} | grep darwin)`"]) cfengine-3.24.2/libntech/m4/snprintf.m40000644000000000000000000002324315010704254017575 0ustar00rootroot00000000000000# $Id: snprintf.m4,v 1.1.1.1 2008/01/06 03:24:00 holger Exp $ # Copyright (c) 2008 Holger Weiss . # # This code may freely be used, modified and/or redistributed for any purpose. # It would be nice if additions and fixes to this file (including trivial code # cleanups) would be sent back in order to let me include them in the version # available at . However, this is # not a requirement for using or redistributing (possibly modified) versions of # this file, nor is leaving this notice intact mandatory. # HW_HEADER_STDARG_H # ------------------ # Define HAVE_STDARG_H to 1 if is available. AC_DEFUN([HW_HEADER_STDARG_H], [ AC_CHECK_HEADERS([stdarg.h]) ])# HW_HEADER_STDARG_H # HW_HEADER_VARARGS_H # ------------------- # Define HAVE_VARARGS_H to 1 if is available. AC_DEFUN([HW_HEADER_VARARGS_H], [ AC_CHECK_HEADERS([varargs.h]) ])# HW_HEADER_VARARGS_H # HW_FUNC_VA_COPY # --------------- # Set $hw_cv_func_va_copy to "yes" or "no". Define HAVE_VA_COPY to 1 if # $hw_cv_func_va_copy is set to "yes". Note that it's "unspecified whether # va_copy and va_end are macros or identifiers declared with external linkage." # (C99: 7.15.1, 1) Therefore, the presence of va_copy(3) cannot simply "be # tested with #ifdef", as suggested by the Autoconf manual (5.5.1). AC_DEFUN([HW_FUNC_VA_COPY], [ AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H. AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H. AC_CACHE_CHECK([for va_copy], [hw_cv_func_va_copy], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif]], [[va_list ap, aq; va_copy(aq, ap);]])], [hw_cv_func_va_copy=yes], [hw_cv_func_va_copy=no], [hw_cv_func_va_copy=no])]) AS_IF([test "$hw_cv_func_va_copy" = yes], [AC_DEFINE([HAVE_VA_COPY], [1], [Define to 1 if you have the `va_copy' function or macro.])]) ])# HW_FUNC_VA_COPY # HW_FUNC___VA_COPY # ----------------- # Set $hw_cv_func___va_copy to "yes" or "no". Define HAVE___VA_COPY to 1 if # $hw_cv_func___va_copy is set to "yes". AC_DEFUN([HW_FUNC___VA_COPY], [ AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H. AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H. AC_CACHE_CHECK([for __va_copy], [hw_cv_func___va_copy], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif]], [[va_list ap, aq; __va_copy(aq, ap);]])], [hw_cv_func___va_copy=yes], [hw_cv_func___va_copy=no], [hw_cv_func___va_copy=no])]) AS_IF([test "$hw_cv_func___va_copy" = yes], [AC_DEFINE([HAVE___VA_COPY], [1], [Define to 1 if you have the `__va_copy' function or macro.])]) ])# HW_FUNC___VA_COPY # HW_FUNC_VSNPRINTF # ----------------- # Set $hw_cv_func_vsnprintf and $hw_cv_func_vsnprintf_c99 to "yes" or "no", # respectively. Define HAVE_VSNPRINTF to 1 only if $hw_cv_func_vsnprintf_c99 # is set to "yes". Otherwise, define vsnprintf to rpl_vsnprintf and make sure # the replacement function will be built. AC_DEFUN([HW_FUNC_VSNPRINTF], [ AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H. dnl The following checks are not *required* to HAVE_VSNPRINTF, but they dnl should be checked (and pass!) for the test in snprintf.c to pass. AC_CHECK_HEADERS([inttypes.h locale.h stddef.h stdint.h]) AC_CHECK_MEMBERS([struct lconv.decimal_point, struct lconv.thousands_sep], [], [], [#include ]) AC_TYPE_LONG_DOUBLE AC_TYPE_LONG_LONG_INT AC_TYPE_UNSIGNED_LONG_LONG_INT AC_TYPE_SIZE_T AC_TYPE_INTMAX_T AC_TYPE_UINTMAX_T AC_TYPE_UINTPTR_T AC_CHECK_TYPES([ptrdiff_t]) AC_CHECK_FUNCS([localeconv]) AC_CHECK_FUNC([vsnprintf], [hw_cv_func_vsnprintf=yes], [hw_cv_func_vsnprintf=no]) AS_IF([test "$hw_cv_func_vsnprintf" = yes], [AC_CACHE_CHECK([whether vsnprintf is C99 compliant], [hw_cv_func_vsnprintf_c99], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_STDARG_H #include #endif #include static int testprintf(char *buf, size_t size, const char *format, ...) { int result; va_list ap; va_start(ap, format); result = vsnprintf(buf, size, format, ap); va_end(ap); return result; }]], [[char buf[43]; if (testprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || testprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || testprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ testprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1;]])], [hw_cv_func_vsnprintf_c99=yes], [hw_cv_func_vsnprintf_c99=no], [hw_cv_func_vsnprintf_c99=no])])], [hw_cv_func_snprintf_c99=no]) AS_IF( [test "$hw_cv_func_vsnprintf_c99" = yes], [AC_DEFINE([HAVE_VSNPRINTF], [1], [Define to 1 if you have a C99 compliant `vsnprintf' function.])], [ AC_DEFINE([vsnprintf], [rpl_vsnprintf], [Define to rpl_vsnprintf if the replacement function should be used.]) AC_DEFINE([vprintf], [rpl_vprintf], [Define to rpl_vprintf if the replacement function should be used.]) AC_DEFINE([vfprintf], [rpl_vfprintf], [Define to rpl_vfprintf if the replacement function should be used.]) _HW_FUNC_XPRINTF_REPLACE ]) ])# HW_FUNC_VSNPRINTF # HW_FUNC_SNPRINTF # ---------------- # Set $hw_cv_func_snprintf and $hw_cv_func_snprintf_c99 to "yes" or "no", # respectively. Define HAVE_SNPRINTF to 1 only if $hw_cv_func_snprintf_c99 # is set to "yes". Otherwise, define snprintf to rpl_snprintf and make sure # the replacement function will be built. AC_DEFUN([HW_FUNC_SNPRINTF], [ AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our snprintf(3) calls vsnprintf(3). AC_CHECK_FUNC([snprintf], [hw_cv_func_snprintf=yes], [hw_cv_func_snprintf=no]) AS_IF([test "$hw_cv_func_snprintf" = yes], [AC_CACHE_CHECK([whether snprintf is C99 compliant], [hw_cv_func_snprintf_c99], [AC_RUN_IFELSE( [AC_LANG_PROGRAM([[#include ]], [[char buf[43]; if (snprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || snprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || snprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ snprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1;]])], [hw_cv_func_snprintf_c99=yes], [hw_cv_func_snprintf_c99=no], [hw_cv_func_snprintf_c99=no])])], [hw_cv_func_snprintf_c99=no]) AS_IF( [test "$hw_cv_func_snprintf_c99" = yes], [AC_DEFINE([HAVE_SNPRINTF], [1], [Define to 1 if you have a C99 compliant `snprintf' function.])], [ AC_DEFINE([snprintf], [rpl_snprintf], [Define to rpl_snprintf if the replacement function should be used.]) AC_DEFINE([printf], [rpl_printf], [Define to rpl_printf if the replacement function should be used.]) AC_DEFINE([fprintf], [rpl_fprintf], [Define to rpl_fprintf if the replacement function should be used.]) _HW_FUNC_XPRINTF_REPLACE ]) ])# HW_FUNC_SNPRINTF # HW_FUNC_VASPRINTF # ----------------- # Set $hw_cv_func_vasprintf to "yes" or "no". Define HAVE_VASPRINTF to 1 if # $hw_cv_func_vasprintf is set to "yes". Otherwise, define vasprintf to # rpl_vasprintf and make sure the replacement function will be built. AC_DEFUN([HW_FUNC_VASPRINTF], [ AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our vasprintf(3) calls vsnprintf(3). # Don't even bother checking for vasprintf if snprintf was standards # incompliant, this one is going to be too. AS_IF([test "$hw_cv_func_snprintf_c99" = yes], [AC_CHECK_FUNCS([vasprintf], [hw_cv_func_vasprintf=yes], [hw_cv_func_vasprintf=no]) ], [hw_cv_func_vasprintf=no]) AS_IF([test "$hw_cv_func_vasprintf" = no], [AC_DEFINE([vasprintf], [rpl_vasprintf], [Define to rpl_vasprintf if the replacement function should be used.]) AC_CHECK_HEADERS([stdlib.h]) HW_FUNC_VA_COPY AS_IF([test "$hw_cv_func_va_copy" = no], [HW_FUNC___VA_COPY]) _HW_FUNC_XPRINTF_REPLACE]) ])# HW_FUNC_VASPRINTF # HW_FUNC_ASPRINTF # ---------------- # Set $hw_cv_func_asprintf to "yes" or "no". Define HAVE_ASPRINTF to 1 if # $hw_cv_func_asprintf is set to "yes". Otherwise, define asprintf to # rpl_asprintf and make sure the replacement function will be built. AC_DEFUN([HW_FUNC_ASPRINTF], [ AC_REQUIRE([HW_FUNC_VASPRINTF])dnl Our asprintf(3) calls vasprintf(3). # Don't even bother checking for asprintf if snprintf was standards # incompliant, this one is going to be too. AS_IF([test "$hw_cv_func_snprintf_c99" = yes], [AC_CHECK_FUNCS([asprintf], [hw_cv_func_asprintf=yes], [hw_cv_func_asprintf=no]) ], [hw_cv_func_asprintf=no]) AS_IF([test "$hw_cv_func_asprintf" = no], [AC_DEFINE([asprintf], [rpl_asprintf], [Define to rpl_asprintf if the replacement function should be used.]) _HW_FUNC_XPRINTF_REPLACE]) ])# HW_FUNC_ASPRINTF # _HW_FUNC_XPRINTF_REPLACE # ------------------------ # Arrange for building snprintf.c. Must be called if one or more of the # functions provided by snprintf.c are needed. AC_DEFUN([_HW_FUNC_XPRINTF_REPLACE], [ AC_C_CONST HW_HEADER_STDARG_H AC_LIBOBJ([snprintf]) ])# _HW_FUNC_XPRINTF_REPLACE dnl vim: set joinspaces textwidth=80: cfengine-3.24.2/libntech/m4/acinclude.m40000644000000000000000000001705615010704254017666 0ustar00rootroot00000000000000dnl From http://ac-archive.sourceforge.net/ac-archive/acx_pthread.html AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE AC_LANG_C acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) AC_MSG_RESULT($acx_pthread_ok) if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt -mthreads pthread --thread-safe pthread-config pthreadGC2" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [acx_pthread_ok=yes]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($acx_pthread_ok) if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_TRY_LINK([#include ], [int attr=$attr; return attr;], [attr_name=$attr; break]) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else acx_pthread_ok=no $2 fi AC_LANG_RESTORE ])dnl ACX_PTHREAD m4_ifdef([AC_PROG_MKDIR_P], [ dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed. m4_define([AC_PROG_MKDIR_P], m4_defn([AC_PROG_MKDIR_P])[ AC_SUBST([MKDIR_P])])], [ dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P. AC_DEFUN([AC_PROG_MKDIR_P], [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake MKDIR_P='$(mkdir_p)' AC_SUBST([MKDIR_P])])]) cfengine-3.24.2/libntech/m4/cf3_path_root_prog.m40000644000000000000000000000335415010704254021514 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # CF3_PATH_ROOT_PROG(variable, program, value-if-not-found, path = $PATH) # -------------------------------------- # # This function has almost the same semantics as the AC_PATH_PROG # function. The difference is that this will detect tools that are # runnable by root, but not by the current user. These tools are # typically used not by the build, but by CFEngine itself, after # it is installed. # AC_DEFUN([CF3_PATH_ROOT_PROG], [ found=0 AS_IF([test "x$4" = "x"], [ path=$PATH ], [ path=$4 ]) AS_ECHO_N(["checking for $2... "]) for i in $(echo $path | sed -e 's/:/ /g'); do AS_IF([test -e $i/$2 && ls -ld $i/$2 | grep ['^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]'] > /dev/null], [ $1=$i/$2 found=1 break ]) done AS_IF([test "$found" = "1"], [ AS_ECHO(["$][$1"]) ], [ AS_ECHO([no]) $1=$3 ]) ]) cfengine-3.24.2/libntech/m4/libtool.m40000644000000000000000000112617115010704266017406 0ustar00rootroot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS cfengine-3.24.2/libntech/m4/tar.m40000644000000000000000000001235115010704254016516 0ustar00rootroot00000000000000# Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2015 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done # Work around CFEngine redmine #6925 by using --hard-dereference. AM_RUN_LOG([$_am_tar --hard-dereference 2>&1 | grep 'unrecognized option']) # Check if --hard-dereference is supported by this version of GNU Tar if test "$ac_status" -eq 0; then _am_gnutar_hard_dereference=false am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' else _am_gnutar_hard_dereference=true am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) --hard-dereference -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) --hard-dereference -chf - "'"$tardir"' fi am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) if test $_am_tool = gnutar; then # We've checked already, so we're just printing here AC_MSG_CHECKING([if GNU tar supports --hard-dereference]) if test x$_am_gnutar_hard_dereference = xtrue; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR cfengine-3.24.2/libntech/m4/strndup.m40000644000000000000000000000304215010704254017424 0ustar00rootroot00000000000000# strndup.m4 serial 21 dnl Copyright (C) 2002-2003, 2005-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([cf3_FUNC_STRNDUP], [ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles AC_CHECK_DECLS([strndup]) AC_REPLACE_FUNCS([strndup]) if test $ac_cv_have_decl_strndup = no; then HAVE_DECL_STRNDUP=0 fi if test $ac_cv_func_strndup = yes; then HAVE_STRNDUP=1 # AIX 5.3 has a function that tries to copy the entire range specified # by n, instead of just the length of src. AC_CACHE_CHECK([for working strndup], [cf3_cv_func_strndup_works], [AC_RUN_IFELSE([ AC_LANG_PROGRAM([[#include #include ]], [[ #if !HAVE_DECL_STRNDUP extern #ifdef __cplusplus "C" #endif char *strndup (const char *, size_t); #endif char *s; // Will crash if strndup tries to traverse all 2GB. s = strndup ("string", 2000000000); return 0;]])], [cf3_cv_func_strndup_works=yes], [cf3_cv_func_strndup_works=no], [ changequote(,)dnl case $host_os in aix | aix[3-6]*) cf3_cv_func_strndup_works="guessing no";; *) cf3_cv_func_strndup_works="guessing yes";; esac changequote([,])dnl ])]) case $cf3_cv_func_strndup_works in *no) AC_LIBOBJ([strndup]) ;; esac else HAVE_STRNDUP=0 fi ]) cfengine-3.24.2/libntech/m4/cf3_with_library.m40000644000000000000000000000564215010704254021167 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # CF3_WITH_LIBRARY(library-name, checks) # -------------------------------------- # # This function popluates CFLAGS, CPPFLAGS and LDFLAGS from the # --with-$library=PATH and runs a second argument with those options. # # After execution flags are returned to previous state, but available in # ${LIBRARY}_{CFLAGS,LDFLAGS}. Path is available in ${LIBRARY}_PATH. # # Libraries added to LIBS are available as ${LIBRARY}_LIBS afterwards. # AC_DEFUN([CF3_WITH_LIBRARY], [ m4_define([ULN],m4_toupper($1)) # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_[$1]" != xyes && test "x$with_[$1]" != xcheck && test "x$with_[$1]" != x then test -z "$ULN[]_PATH" && ULN[]_PATH="$with_[$1]" if test "x$with_[$1]" != x/usr && test "x$with_[$1]" != x/ then test -z "$ULN[]_CFLAGS" && ULN[]_CFLAGS="" test -z "$ULN[]_CPPFLAGS" && ULN[]_CPPFLAGS="-I$with_[$1]/include" test -z "$ULN[]_LDFLAGS" && ULN[]_LDFLAGS="-L$with_[$1]/lib" fi else ULN[]_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $ULN[]_CFLAGS" CPPFLAGS="$CPPFLAGS $ULN[]_CPPFLAGS" LDFLAGS="$LDFLAGS $ULN[]_LDFLAGS" # # Run checks passed as argument # $2 # # Pick up any libraries added by tests # test -z "$ULN[]_LIBS" && ULN[]_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_[$1]" != xyes && test "x$with_[$1]" != xcheck && test "x$with_[$1]" != x/usr && test "x$with_[$1]" != x/ then ULN[]_LDFLAGS="$ULN[]_LDFLAGS -R$with_[$1]/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST(ULN[]_PATH) AC_SUBST(ULN[]_CPPFLAGS) AC_SUBST(ULN[]_CFLAGS) AC_SUBST(ULN[]_LDFLAGS) AC_SUBST(ULN[]_LIBS) ]) cfengine-3.24.2/libntech/m4/cf3_check_proper_func.m40000644000000000000000000000477615010704254022156 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # dnl dnl Arguments: dnl $1 - function name dnl $2 - headers (to compile $3) dnl $3 - body for compilation dnl $4 - function invocation dnl dnl This macro checks that the function (argument 1) is defined, dnl and that the code piece (arguments 2, 3, like in AC_LANG_PROGRAM) can be dnl compiled. dnl dnl If the code compiles successfully, it defines HAVE_$1_PROPER macro. dnl dnl If the code fails, it adds '$4' to $post_macros variable. dnl If you want rpl_$1.c to be compiled as a replacement, call dnl CF3_REPLACE_PROPER_FUNC with the same function name. dnl dnl ** How to use ** dnl dnl CF3_CHECK_PROPER_FUNC(function, [#include ], [void function(FILE *);], [#define function rpl_function]) dnl CF3_REPLACE_PROPER_FUNC(function) dnl dnl Then in libutils/platform.h: dnl dnl #if !HAVE_FUNCTION_PROPER dnl void rpl_function(FILE *); dnl #endif dnl dnl And libcompat/rpl_function.c: dnl dnl #include "platform.h" dnl dnl void rpl_function(FILE *) { ... } dnl AC_DEFUN([CF3_CHECK_PROPER_FUNC], [ AC_CHECK_FUNC([$1], [], [AC_MSG_ERROR([Unable to find function $1])]) AC_CACHE_CHECK([whether $1 is properly declared], [hw_cv_func_$1_proper], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([$2],[$3])], [hw_cv_func_$1_proper=yes], [hw_cv_func_$1_proper=no])]) AC_SUBST([hw_cv_func_$1_proper]) AS_IF([test "$hw_cv_func_$1_proper" = yes], [AC_DEFINE([HAVE_$1_PROPER], [1], [Define to 1 if you have properly defined `$1' function])], [post_macros="$post_macros $4"]) ]) AC_DEFUN([CF3_REPLACE_PROPER_FUNC], [ AS_IF([test "$hw_cv_func_$1_proper" = "no"], [AC_LIBOBJ(rpl_$1)] ) ]) cfengine-3.24.2/libntech/m4/cf3_gcc_flags.m40000644000000000000000000000567415010704254020405 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # dnl #################################################################### dnl Set GCC CFLAGS only if using GCC. dnl #################################################################### AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ #if defined __HP_cc #This is HP-UX ANSI C #endif ]])], [ HP_UX_AC="no"], [ CFLAGS="$CFLAGS -Agcc" CPPFLAGS="$CPPFLAGS -Agcc" HP_UX_AC="yes"]) AC_MSG_CHECKING(for HP-UX aC) if test "x$HP_UX_AC" = "xyes"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi AC_MSG_CHECKING(for GCC specific compile flags) if test x"$GCC" = "xyes" && test x"$HP_UX_AC" != x"yes"; then CFLAGS="$CFLAGS -g -Wall" CPPFLAGS="$CPPFLAGS -std=gnu99" AC_MSG_RESULT(yes) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-pointer-sign" AC_MSG_CHECKING(for -Wno-pointer-sign) AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main() {}])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) CFLAGS="$save_CFLAGS"]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror=implicit-function-declaration" AC_MSG_CHECKING(for -Werror=implicit-function-declaration) AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main() {}])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) CFLAGS="$save_CFLAGS"]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wunused-parameter" AC_MSG_CHECKING(for -Wunused-parameter) AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main() {}])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) CFLAGS="$save_CFLAGS"]) dnl Clang does not like 'const const' construct arising from dnl expansion of TYPED_SET_DECLARE macro dnl dnl This check is relying on explicit compilator detection due to dnl GCC irregularities checking for -Wno-* command-line options dnl (command line is not fully checked until actual warning occurs) AC_MSG_CHECKING(for -Wno-duplicate-decl-specifier) AC_COMPILE_IFELSE([AC_LANG_SOURCE([#ifndef __clang__ # error Not a clang #endif int main() {}])], [AC_MSG_RESULT(yes) CFLAGS="$save_CFLAGS -Wno-duplicate-decl-specifier"], [AC_MSG_RESULT(no)]) else AC_MSG_RESULT(no) fi cfengine-3.24.2/libntech/README.md0000644000000000000000000000220015010704254016415 0ustar00rootroot00000000000000# libntech libntech is a lightweight C library used in CFEngine. It consists primarily of data structures, string parsing, logging, and other convenience functions which are generally reusable. See the [core repo](https://github.com/cfengine/core/) for more information about CFEngine. ## Example An example project is provided, showing how to use libntech in a new project: https://github.com/cfengine/libntech_example ## License As per the [LICENSE](https://github.com/cfengine/libntech/blob/master/LICENSE) file, libntech is licensed under the Apache License Version 2.0. All the files in this repository are licensed under Apache License Version 2.0, unless stated otherwise in the copyright notice inside the particular file. ## Contributing Please see the [CONTRIBUTING.md](https://github.com/cfengine/core/blob/master/CONTRIBUTING.md) file in the core repository. # Authors CFEngine was originally created by Mark Burgess with many contributions from around the world. Thanks [everyone](https://github.com/cfengine/core/blob/master/AUTHORS)! [CFEngine](https://cfengine.com) is sponsored by [Northern.tech AS](https://northern.tech) cfengine-3.24.2/libntech/config.guess0000755000000000000000000012564415010704272017500 0ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-10-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || \ echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; mips64el:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac cat >&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: cfengine-3.24.2/libntech/config.sub0000755000000000000000000010676315010704272017144 0ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-11-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: cfengine-3.24.2/libntech/depcomp0000755000000000000000000005601615010704273016532 0ustar00rootroot00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/libntech/Makefile.in0000644000000000000000000010343315010704272017215 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/tar.m4 \ $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = config.post.h CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(docdir)" DATA = $(doc_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/config.post.h.in compile config.guess config.sub \ install-sh ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GREP = @GREP@ HAVE_CLOCKID_T_DEFINE = @HAVE_CLOCKID_T_DEFINE@ HAVE_GETOPT_H_DEFINE = @HAVE_GETOPT_H_DEFINE@ HAVE_LIBYAML_DEFINE = @HAVE_LIBYAML_DEFINE@ HOSTNAME = @HOSTNAME@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NO_TAUTOLOGICAL_CC_OPTION = @NO_TAUTOLOGICAL_CC_OPTION@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_LOGGING_CFLAGS = @SYSTEMD_LOGGING_CFLAGS@ SYSTEMD_LOGGING_CPPFLAGS = @SYSTEMD_LOGGING_CPPFLAGS@ SYSTEMD_LOGGING_LDFLAGS = @SYSTEMD_LOGGING_LDFLAGS@ SYSTEMD_LOGGING_LIBS = @SYSTEMD_LOGGING_LIBS@ SYSTEMD_LOGGING_PATH = @SYSTEMD_LOGGING_PATH@ VERSION = @VERSION@ WITH_PCRE2_DEFINE = @WITH_PCRE2_DEFINE@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # AUTOMAKE_OPTIONS = foreign MAKEFLAGS = $(if $(filter-out 0,$(V)),,--no-print-directory --quiet) LCOV_FLAGS = $(if $(filter-out 0,$(V)),,-q) SUBDIRS = libcompat \ libutils \ tests # Hide the buildsystem's username, at least with GNU tar. TAR_OPTIONS = --owner=0 --group=0 EXTRA_DIST = README.md LICENSE doc_DATA = README.md # # Some basic clean ups # MOSTLYCLEANFILES = *~ # # Get everything removed down to where rebuilding requires: # "configure; make; make install" # DISTCLEANFILES = # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.sub \ configure install-sh missing mkinstalldirs depcomp ylwrap \ ltmain.sh mdate-sh # # Pass proper flags to aclocal to pick up Libtool macros # ACLOCAL_AMFLAGS = -I m4 V_PERL = $(cf__v_PERL_$(V)) cf__v_PERL_ = $(cf__v_PERL_$(AM_DEFAULT_VERBOSITY)) cf__v_PERL_0 = @echo " PERL " "$@"; cf__v_PERL_1 = V_SED = $(cf__v_SED_$(V)) cf__v_SED_ = $(cf__v_SED_$(AM_DEFAULT_VERBOSITY)) cf__v_SED_0 = @echo " SED " "$@"; cf__v_SED_1 = # # Get everything removed down to where rebuilding requires: # "make; make install" # CLEANFILES = cfengine-lcov-base.info cfengine-lcov.info \ $(BUILT_SOURCES) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 config.post.h: $(top_builddir)/config.status $(srcdir)/config.post.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-docDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-docDATA .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-data-local install-docDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-docDATA .PRECIOUS: Makefile export TAR_OPTIONS list: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' install-data-local: $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/inputs $(MKDIR_P) -m 755 $(DESTDIR)$(workdir)/modules $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/outputs $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/ppkeys $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/plugins $(MKDIR_P) -m 750 $(DESTDIR)$(workdir)/state tar-package: pkgdir=`mktemp -d` && export pkgdir && \ origdir=`pwd` && export origdir && \ $(MAKE) DESTDIR=$$pkgdir install && \ ( \ cd $$pkgdir && \ find . -name '*.cf*' | xargs -n1 chmod go-w && \ tardir=. && \ $(am__tar) | GZIP=$(GZIP_ENV) gzip -c \ > "$$origdir"/$(PACKAGE)-$(VERSION).pkg.tar.gz \ ) ; \ [ x$$pkgdir != x ] && rm -rf $$pkgdir # # Code coverage # clean-coverage: find -L $(srcdir) -name '*.gcda' -delete run-coverage: -$(MAKE) check -k collect-coverage: mkdir -p coverage $(LCOV) $(LCOV_FLAGS) --capture --initial --directory . --output-file coverage/cfengine-lcov-base.info $(LCOV) $(LCOV_FLAGS) --capture --directory . --output-file coverage/lcov.info --test-name CFENGINE --no-checksum --compat-libtool $(LCOV) $(LCOV_FLAGS) -a coverage/cfengine-lcov-base.info -a coverage/lcov.info --output-file coverage/cfengine-lcov.info $(LCOV) $(LCOV_FLAGS) --remove coverage/lcov.info '/usr/include/*' --output-file coverage/lcov.info LANG=C $(LCOV_GENHTML) $(LCOV_FLAGS) --prefix . --output-directory coverage-html --title "CFEngine Code Coverage" --legend --show-details coverage/lcov.info @echo @echo " Code coverage information: file://"`pwd`"/coverage-html/index.html" @echo " Code coverage summary for IDEs: file://"`pwd`"/coverage/lcov.info" @echo coverage: clean-coverage run-coverage collect-coverage static-check: tests/static-check/run.sh static-check-f%: STATIC_CHECKS_FEDORA_VERSION=$* tests/static-check/run.sh # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libntech/install-sh0000755000000000000000000003546315010704272017163 0ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # $RANDOM is not portable (e.g. dash); use it when possible to # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # As "mkdir -p" follows symlinks and we work in /tmp possibly; so # create the $tmpdir first (and fail if unsuccessful) to make sure # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/libntech/compile0000755000000000000000000001624515010704272016532 0ustar00rootroot00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/libntech/tests/0000755000000000000000000000000015010704322016302 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/tests/Makefile.am0000644000000000000000000000165115010704254020345 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # SUBDIRS = unit static-check cfengine-3.24.2/libntech/tests/static-check/0000755000000000000000000000000015010704322020644 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/tests/static-check/Makefile.am0000644000000000000000000000207715010704254022712 0ustar00rootroot00000000000000# # Copyright 2025 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # DISTFILES = cppcheck_suppressions.txt run_checks.sh run.sh Makefile.in Makefile.am cfengine-3.24.2/libntech/tests/static-check/run_checks.sh0000755000000000000000000000277215010704254023343 0ustar00rootroot00000000000000#!/bin/bash set -x n_procs="$(getconf _NPROCESSORS_ONLN)" function check_with_gcc() { make clean ./autogen.sh --enable-debug CC=gcc local gcc_exceptions="-Wno-sign-compare -Wno-enum-int-mismatch" make -j -l${n_procs} --keep-going CFLAGS="-Werror -Wall -Wextra $gcc_exceptions" } function check_with_clang() { make clean ./autogen.sh --enable-debug CC=clang make -j -l${n_procs} --keep-going CFLAGS="-Werror -Wall -Wextra -Wno-sign-compare" } function check_with_cppcheck() { make clean ./autogen.sh --enable-debug # print out cppcheck version for comparisons over time in case of regressions due to newer versions cppcheck --version # cppcheck options: # -I -- include paths # -i -- ignored files/folders # --include= -- force including a file, e.g. config.h # Identified issues are printed to stderr cppcheck --quiet -j${n_procs} --error-exitcode=1 ./ \ --suppressions-list=tests/static-check/cppcheck_suppressions.txt \ --check-level=exhaustive \ --include=config.h \ -I libutils/ \ -i tests \ -i libcompat/ \ 2>&1 1>/dev/null } cd "$(dirname $0)"/../../ failure=0 failures="" check_with_gcc || { failures="${failures}FAIL: GCC check failed\n"; failure=1; } check_with_clang || { failures="${failures}FAIL: Clang check failed\n"; failure=1; } check_with_cppcheck || { failures="${failures}FAIL: cppcheck failed\n"; failure=1; } echo -en "$failures" exit $failure cfengine-3.24.2/libntech/tests/static-check/Makefile.in0000644000000000000000000003611415010704273022723 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2025 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tests/static-check ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/tar.m4 \ $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GREP = @GREP@ HAVE_CLOCKID_T_DEFINE = @HAVE_CLOCKID_T_DEFINE@ HAVE_GETOPT_H_DEFINE = @HAVE_GETOPT_H_DEFINE@ HAVE_LIBYAML_DEFINE = @HAVE_LIBYAML_DEFINE@ HOSTNAME = @HOSTNAME@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NO_TAUTOLOGICAL_CC_OPTION = @NO_TAUTOLOGICAL_CC_OPTION@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_LOGGING_CFLAGS = @SYSTEMD_LOGGING_CFLAGS@ SYSTEMD_LOGGING_CPPFLAGS = @SYSTEMD_LOGGING_CPPFLAGS@ SYSTEMD_LOGGING_LDFLAGS = @SYSTEMD_LOGGING_LDFLAGS@ SYSTEMD_LOGGING_LIBS = @SYSTEMD_LOGGING_LIBS@ SYSTEMD_LOGGING_PATH = @SYSTEMD_LOGGING_PATH@ VERSION = @VERSION@ WITH_PCRE2_DEFINE = @WITH_PCRE2_DEFINE@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ DISTFILES = cppcheck_suppressions.txt run_checks.sh run.sh Makefile.in Makefile.am all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/static-check/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/static-check/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libntech/tests/static-check/cppcheck_suppressions.txt0000644000000000000000000000147215010704254026032 0ustar00rootroot00000000000000// suppress warnings for access to individual bytes of a uint32 in platform.h objectIndex:libutils/platform.h // cppcheck is not clever enough to see that if (i >= PLATFORM_CONTEXT_MAX) then 'found' is false arrayIndexOutOfBounds:libenv/sysinfo.c:587 // 'psin' is assigned to 'ai->ai_addr' and 'ai' is returned to the caller memleak:libcompat/getaddrinfo.c:153 // cppcheck doesn't understand va_copy() properly va_list_usedBeforeStarted:libcompat/snprintf.c:1505 va_list_usedBeforeStarted:libcompat/snprintf.c:1506 // too cryptic code for cppcheck to see that the 'tmp' variable is initialized // through a pointer to the same address space (and the same applies to 'dst') uninitvar:libcompat/inet_pton.c:115 uninitvar:libcompat/snprintf.c:1494 // cppcheck doesn't like VA_COPY, it seems Uninit:libcompat/snprintf.c:1505 cfengine-3.24.2/libntech/tests/static-check/run.sh0000755000000000000000000000526015010704254022016 0ustar00rootroot00000000000000#!/bin/bash # Note that this container build requires about 700MB minimum RAM for dnf to operate # use debian-12+ or rhel-8+, debian-11 buildah seems to fail setting up networking/dns for the container so dnf doesn't work (CFE-4295) set -eE # include E so that create_image() failures bubble up to the surface trap "echo FAILURE" ERR SUM_FILE="`basename $0`.sum" PROJECT=libntech if [ -z "$STATIC_CHECKS_FEDORA_VERSION" ]; then default_f_ver="40" echo "No Fedora version for static checks specified, using the default (Fedora $default_f_ver)" BASE_IMG="fedora:$default_f_ver" STATIC_CHECKS_FEDORA_VERSION="$default_f_ver" else BASE_IMG="fedora:$STATIC_CHECKS_FEDORA_VERSION" fi function create_image() { local c=$(buildah from -q $BASE_IMG) buildah run $c -- dnf -q -y install "@C Development Tools and Libraries" clang cppcheck which diffutils file >/dev/null 2>&1 buildah run $c -- dnf -q -y install pcre-devel pcre2-devel openssl-devel libxml2-devel pam-devel lmdb-devel libacl-devel libyaml-devel curl-devel libvirt-devel librsync-devel >/dev/null 2>&1 buildah run $c -- dnf clean all >/dev/null 2>&1 # Copy checksum of this file into container. We use the checksum to detect # whether or not this file has changed and we should recreate the image sha256sum $0 > $SUM_FILE buildah copy $c $SUM_FILE >/dev/null rm $SUM_FILE buildah commit $c $PROJECT-static-checker-f$STATIC_CHECKS_FEDORA_VERSION >/dev/null 2>&1 echo $c } set -x if buildah inspect $PROJECT-static-checker-f$STATIC_CHECKS_FEDORA_VERSION >/dev/null 2>&1; then c=$(buildah from $PROJECT-static-checker-f$STATIC_CHECKS_FEDORA_VERSION) # Recreate the image if the checksum of this file has changed or if the # checksum file is missing from the container if [[ `buildah run $c ls $SUM_FILE` == $SUM_FILE ]]; then SUM_A=$(sha256sum $0) SUM_B=$(buildah run $c cat $SUM_FILE) if [[ $SUM_A != $SUM_B ]]; then echo "Recreating image due to mismatching checksum..." IMAGE_ID=$(buildah inspect $c | jq -r '.FromImageID') # The --force option will cause Buildah to remove all containers that # are using the image before removing the image from the system. Hence, # there is no need to manually remove these containers buildah rmi --force $IMAGE_ID >/dev/null c=$(create_image) fi else echo "Recreating image due to missing checksum..." IMAGE_ID=$(buildah inspect $c | jq -r '.FromImageID') buildah rmi --force $IMAGE_ID >/dev/null c=$(create_image) fi else c=$(create_image) fi trap "buildah rm $c >/dev/null" EXIT buildah copy $c "$(dirname $0)/../../" /tmp/$PROJECT/ >/dev/null 2>&1 buildah run $c /tmp/$PROJECT/tests/static-check/run_checks.sh cfengine-3.24.2/libntech/tests/unit/0000755000000000000000000000000015010704322017261 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/tests/unit/threaded_stack_test.c0000644000000000000000000001053415010704254023440 0ustar00rootroot00000000000000#include "test.h" #include #include static void test_push_pop(void) { ThreadedStack *stack = ThreadedStackNew(0, free); ThreadedStackPush(stack, xstrdup("1")); ThreadedStackPush(stack, xstrdup("2")); ThreadedStackPush(stack, xstrdup("3")); char *str1 = ThreadedStackPop(stack); char *str2 = ThreadedStackPop(stack); char *str3 = ThreadedStackPop(stack); assert_int_equal(strcmp(str1, "3"), 0); assert_int_equal(strcmp(str2, "2"), 0); assert_int_equal(strcmp(str3, "1"), 0); free(str1); free(str2); free(str3); ThreadedStackDestroy(stack); } static void test_pop_empty_and_push_null(void) { ThreadedStack *stack = ThreadedStackNew(1, NULL); assert(ThreadedStackIsEmpty(stack)); void *i_am_null = ThreadedStackPop(stack); assert(i_am_null == NULL); ThreadedStackPush(stack, i_am_null); assert(ThreadedStackPop(stack) == NULL); ThreadedStackDestroy(stack); } static void test_copy(void) { ThreadedStack *stack = ThreadedStackNew(4, free); ThreadedStackPush(stack, xstrdup("1")); ThreadedStackPush(stack, xstrdup("2")); ThreadedStackPush(stack, xstrdup("3")); ThreadedStack *new_stack = ThreadedStackCopy(stack); assert(new_stack != NULL); assert_int_equal(ThreadedStackCount(stack), ThreadedStackCount(new_stack)); assert_int_equal(ThreadedStackCapacity(stack), ThreadedStackCapacity(new_stack)); char *old_str1 = ThreadedStackPop(stack); char *new_str1 = ThreadedStackPop(new_stack); char *old_str2 = ThreadedStackPop(stack); char *new_str2 = ThreadedStackPop(new_stack); char *old_str3 = ThreadedStackPop(stack); char *new_str3 = ThreadedStackPop(new_stack); assert(old_str1 == new_str1); assert(old_str2 == new_str2); assert(old_str3 == new_str3); free(old_str1); free(old_str2); free(old_str3); ThreadedStackSoftDestroy(stack); // Tests expanding the copied stack ThreadedStackPush(new_stack, xstrdup("1")); ThreadedStackPush(new_stack, xstrdup("2")); ThreadedStackPush(new_stack, xstrdup("3")); ThreadedStackPush(new_stack, xstrdup("4")); ThreadedStackPush(new_stack, xstrdup("5")); assert_int_equal(ThreadedStackCount(new_stack), 5); assert_int_equal(ThreadedStackCapacity(new_stack), 8); new_str1 = ThreadedStackPop(new_stack); new_str2 = ThreadedStackPop(new_stack); new_str3 = ThreadedStackPop(new_stack); char *new_str4 = ThreadedStackPop(new_stack); char *new_str5 = ThreadedStackPop(new_stack); assert_int_equal(strcmp(new_str1, "5"), 0); assert_int_equal(strcmp(new_str2, "4"), 0); assert_int_equal(strcmp(new_str3, "3"), 0); assert_int_equal(strcmp(new_str4, "2"), 0); assert_int_equal(strcmp(new_str5, "1"), 0); free(new_str1); free(new_str2); free(new_str3); free(new_str4); free(new_str5); ThreadedStackDestroy(new_stack); } static void test_push_report_count(void) { ThreadedStack *stack = ThreadedStackNew(0, free); size_t size1 = ThreadedStackPushReportCount(stack, xstrdup("1")); size_t size2 = ThreadedStackPushReportCount(stack, xstrdup("2")); size_t size3 = ThreadedStackPushReportCount(stack, xstrdup("3")); size_t size4 = ThreadedStackPushReportCount(stack, xstrdup("4")); assert_int_equal(size1, 1); assert_int_equal(size2, 2); assert_int_equal(size3, 3); assert_int_equal(size4, 4); ThreadedStackDestroy(stack); } static void test_expand(void) { ThreadedStack *stack = ThreadedStackNew(1, free); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); ThreadedStackPush(stack, xstrdup("spam")); assert_int_equal(ThreadedStackCount(stack), 9); assert_int_equal(ThreadedStackCapacity(stack), 16); ThreadedStackDestroy(stack); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_push_pop), unit_test(test_pop_empty_and_push_null), unit_test(test_copy), unit_test(test_push_report_count), unit_test(test_expand), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/condition_macros_test.c0000644000000000000000000000661315010704254024030 0ustar00rootroot00000000000000#include #include // No easy way to test that compiler macros fail, // since we expect these unit tests to compile successfully. // Thus, we only test that they work for the positive case // (it compiles). You can manually change one of these // cases and see it fail. #define ABC "ABC" static void test_nt_static_assert() { // Basic: nt_static_assert(1); // Const boolean logic works at compile time: nt_static_assert(true); nt_static_assert(!false); nt_static_assert(false == false); // So does arithmetic: nt_static_assert(0 + 1); nt_static_assert(-1 + 1 + 1 + 0); // And comparisons: nt_static_assert(1 > 0); nt_static_assert(-1 < 0); nt_static_assert(10 * 10 > 99); nt_static_assert(10 * 10 == 100); // sizeof works at compile-time, except for variable length arrays: nt_static_assert(sizeof(char) == 1); nt_static_assert(sizeof(char) <= sizeof(short)); nt_static_assert(sizeof(short) <= sizeof(int)); nt_static_assert(sizeof(int) <= sizeof(long)); // String literal indices? Doesn't work! // nt_static_assert(ABC[0] == 'A'); // You can use sizeof on arrays: char ten[10]; nt_static_assert(sizeof(ten) == 10); // Sizeof does not return the number of elements in array: int many[42]; nt_static_assert((sizeof(many[0]) * 42) == sizeof(many)); // strlen() can be used statically: nt_static_assert(strlen("CFEngine") == strlen("libntech")); nt_static_assert(strlen(ABC) == strlen("ABC")); nt_static_assert(strlen(ABC) == (sizeof(ABC) - 1)); nt_static_assert(sizeof(ABC) == (strlen(ABC) + 1)); // Various stdlib macros and functions work at // compile-time when you give them constant inputs: // nt_static_assert(strcmp("libntech", "libntech") == 0); // nt_static_assert(strcmp("CFEngine", "Mender") != 0); // Commented out since strcmp is only optimized out on some compilers :( // Add more cases here if you want to see if a given // macro or function can be done at compile time, // and used in static asserts. } static void test_nt_static_assert_string_equal() { // These are commented out because the macro // doesn't work everywhere yet. Highly dependent on // how smart the compiler is (How much it optimizes out). // nt_static_assert_string_equal("", ""); // nt_static_assert_string_equal("a", "a"); // nt_static_assert_string_equal("abc", "abc"); // nt_static_assert_string_equal(ABC, ABC); // nt_static_assert_string_equal("ABC", ABC); // nt_static_assert_string_equal(ABC, "ABC"); // nt_static_assert_string_equal(ABC, "ABC"); // Concatenate string literals: // nt_static_assert_string_equal(ABC ABC, "ABCABC"); // nt_static_assert_string_equal(ABC ABC, ABC ABC); // nt_static_assert_string_equal("" ABC, "" ABC); // nt_static_assert_string_equal(ABC "", ABC ""); // nt_static_assert_string_equal("ABC" "ABC", "ABCABC"); // nt_static_assert_string_equal("ABC" "ABC", "ABC" "ABC"); // nt_static_assert_string_equal("ABC" "ABC", ABC ABC); // nt_static_assert_string_equal(ABC ABC, "ABC" "ABC"); // nt_static_assert_string_equal(ABC ABC, ABC ABC); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_nt_static_assert), unit_test(test_nt_static_assert_string_equal), }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/libntech/tests/unit/csv_writer_test.c0000644000000000000000000001067315010704254022666 0ustar00rootroot00000000000000#include #include void test_empty(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpen(w); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, ""); free(result_string); } void test_single_field(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpen(w); CsvWriterField(c, "test"); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "test\r\n"); free(result_string); } void test_several_fields(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpen(w); CsvWriterField(c, "test1"); CsvWriterField(c, "test2"); CsvWriterField(c, "test3"); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "test1,test2,test3\r\n"); free(result_string); } void test_two_records(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpen(w); CsvWriterField(c, "test1"); CsvWriterNewRecord(c); CsvWriterField(c, "test2"); CsvWriterNewRecord(c); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "test1\r\ntest2\r\n"); free(result_string); } void test_empty_record(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpen(w); CsvWriterNewRecord(c); CsvWriterField(c, "test2"); CsvWriterNewRecord(c); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "\r\ntest2\r\n"); free(result_string); } void test_empty_last_record(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpen(w); CsvWriterField(c, "test1"); CsvWriterNewRecord(c); CsvWriterNewRecord(c); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "test1\r\n\r\n"); free(result_string); } void test_escape(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpen(w); CsvWriterField(c, ",\"\r\n"); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "\",\"\"\r\n\"\r\n"); free(result_string); } void test_terminate(void) { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpenSpecifyTerminate(w, true); CsvWriterField(c, "test"); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "test\r\n"); free(result_string); } void test_no_terminate(void) { { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpenSpecifyTerminate(w, false); CsvWriterField(c, "test"); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "test"); free(result_string); } { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpenSpecifyTerminate(w, false); CsvWriterField(c, "a"); CsvWriterField(c, "b"); CsvWriterField(c, "c"); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "a,b,c"); free(result_string); } { Writer *w = StringWriter(); CsvWriter *c = CsvWriterOpenSpecifyTerminate(w, false); CsvWriterField(c, "a"); CsvWriterField(c, "b"); CsvWriterField(c, "c"); CsvWriterNewRecord(c); CsvWriterField(c, "d"); CsvWriterField(c, "e"); CsvWriterField(c, "f"); CsvWriterClose(c); char *result_string = StringWriterClose(w); assert_string_equal(result_string, "a,b,c\r\nd,e,f"); free(result_string); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_empty), unit_test(test_single_field), unit_test(test_several_fields), unit_test(test_two_records), unit_test(test_empty_record), unit_test(test_empty_last_record), unit_test(test_escape), unit_test(test_terminate), unit_test(test_no_terminate), }; return run_tests(tests); } /* STUB OUT */ void __ProgrammingError(ARG_UNUSED const char *file, ARG_UNUSED int lineno, ARG_UNUSED const char *format, ...) { fail(); exit(42); } void FatalError(ARG_UNUSED char *s, ...) { fail(); exit(42); } cfengine-3.24.2/libntech/tests/unit/buffer_test.c0000644000000000000000000005312215010704254021744 0ustar00rootroot00000000000000#include #include #include #include #include #include static void test_createBuffer(void) { Buffer *buffer = BufferNew(); assert_true(buffer != NULL); assert_true(buffer->buffer != NULL); assert_int_equal(buffer->mode, BUFFER_BEHAVIOR_CSTRING); assert_int_equal(buffer->capacity, DEFAULT_BUFFER_CAPACITY); assert_int_equal(buffer->used, 0); BufferDestroy(buffer); } static void test_createBufferFrom(void) { char *data = xstrdup("this is some data"); unsigned int dataLength = strlen(data); Buffer *buffer = BufferNewFrom(data, dataLength); assert_true(buffer != NULL); assert_true(buffer->buffer != NULL); assert_string_equal(data, buffer->buffer); assert_int_equal(buffer->mode, BUFFER_BEHAVIOR_CSTRING); assert_int_equal(buffer->used, dataLength); BufferDestroy(buffer); free (data); } static void test_destroyBuffer(void) { Buffer *buffer = BufferNew(); BufferDestroy(buffer); buffer = NULL; BufferDestroy(buffer); } static void test_setBuffer(void) { char *element0 = xstrdup("element0"); unsigned int element0size = strlen(element0); char *element1 = (char *)xmalloc(2 * DEFAULT_BUFFER_CAPACITY + 2); unsigned int element1size = 2 * DEFAULT_BUFFER_CAPACITY + 1; Buffer *buffer = BufferNew(); assert_true(buffer != NULL); // Smaller than the allocated buffer BufferSet(buffer, element0, element0size); assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); assert_string_equal(element0, buffer->buffer); assert_string_equal(element0, BufferData(buffer)); // Larger than the allocated buffer for (int i = 0; i < element1size; ++i) { element1[i] = 'a'; } element1[element1size] = '\0'; BufferSet(buffer, element1, element1size); assert_int_equal(element1size, buffer->used); assert_string_equal(element1, buffer->buffer); assert_string_equal(element1, BufferData(buffer)); /* * Boundary checks, BUFFER_SIZE-1, BUFFER_SIZE and BUFFER_SIZE+1 */ Buffer *bm1 = BufferNew(); Buffer *be = BufferNew(); Buffer *bp1 = BufferNew(); char buffer_m1[DEFAULT_BUFFER_CAPACITY - 1]; char buffer_0[DEFAULT_BUFFER_CAPACITY]; char buffer_p1[DEFAULT_BUFFER_CAPACITY + 1]; unsigned int bm1_size = DEFAULT_BUFFER_CAPACITY - 1; unsigned int be_size = DEFAULT_BUFFER_CAPACITY; unsigned int bp1_size = DEFAULT_BUFFER_CAPACITY + 1; for (int i = 0; i < DEFAULT_BUFFER_CAPACITY - 1; ++i) { buffer_m1[i] = 'c'; buffer_0[i] = 'd'; buffer_p1[i] = 'e'; } /* * One shorter, that means the buffer remains the same size as before. */ buffer_m1[DEFAULT_BUFFER_CAPACITY - 2] = '\0'; BufferSet(bm1, buffer_m1, bm1_size); assert_int_equal(bm1->capacity, DEFAULT_BUFFER_CAPACITY); /* * Same size, it should allocate one more block */ buffer_0[DEFAULT_BUFFER_CAPACITY - 1] = '\0'; BufferSet(be, buffer_0, be_size); assert_int_equal(be->capacity, 2 * DEFAULT_BUFFER_CAPACITY); /* * 1 more, it should allocate one more block */ buffer_p1[DEFAULT_BUFFER_CAPACITY] = '\0'; BufferSet(bp1, buffer_p1, bp1_size); assert_int_equal(bp1->capacity, 2 * DEFAULT_BUFFER_CAPACITY); BufferSet(buffer, element0, 0); /* * Destroy the buffer and good night. */ BufferDestroy(buffer); BufferDestroy(bm1); BufferDestroy(be); BufferDestroy(bp1); free(element0); free(element1); } static void test_zeroBuffer(void) { char *element0 = xstrdup("element0"); unsigned int element0size = strlen(element0); const char *element0pointer = NULL; Buffer *buffer = BufferNew(); BufferSet(buffer, element0, element0size); element0pointer = buffer->buffer; assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); BufferClear(buffer); assert_int_equal(DEFAULT_BUFFER_CAPACITY, buffer->capacity); assert_int_equal(0, buffer->used); assert_int_equal(0, BufferSize(buffer)); const char *data = BufferData(buffer); assert_string_equal(data, ""); assert_true(element0pointer == buffer->buffer); BufferDestroy(buffer); free(element0); } static void test_copyCompareBuffer(void) { char *element0 = xstrdup("element0"); unsigned int element0size = strlen(element0); char *element1 = xstrdup("element1"); unsigned int element1size = strlen(element1); Buffer *buffer0 = NULL; Buffer *buffer1 = NULL; Buffer *buffer2 = NULL; buffer0 = BufferNew(); buffer1 = BufferNew(); assert_int_equal(0, BufferCompare(buffer0, buffer0)); assert_int_equal(0, BufferCompare(buffer0, buffer1)); buffer2 = BufferCopy(buffer0); assert_true(buffer2); assert_int_equal(0, BufferCompare(buffer0, buffer2)); // Add some flavour BufferDestroy(buffer2); BufferSet(buffer0, element0, element0size); BufferSet(buffer1, element1, element1size); assert_int_equal(0, BufferCompare(buffer0, buffer0)); assert_int_equal(-1, BufferCompare(buffer0, buffer1)); assert_int_equal(1, BufferCompare(buffer1, buffer0)); buffer2 = BufferCopy(buffer0); assert_int_equal(0, BufferCompare(buffer0, buffer2)); // Destroy the buffers BufferDestroy(buffer0); BufferDestroy(buffer1); BufferDestroy(buffer2); free (element0); free (element1); } static void test_appendBuffer(void) { char *element0 = xstrdup("element0"); unsigned int element0size = strlen(element0); const char *element0pointer = NULL; char *element1 = xstrdup("element1"); unsigned int element1size = strlen(element1); const char *element1pointer = NULL; char *element2 = (char *)xmalloc(2 * DEFAULT_BUFFER_CAPACITY + 2); unsigned int element2size = 2 * DEFAULT_BUFFER_CAPACITY + 1; Buffer *buffer = BufferNew(); assert_true(buffer != NULL); // Initialize the buffer with a small string BufferAppend(buffer, element0, element0size); element0pointer = buffer->buffer; assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); assert_string_equal(element0, buffer->buffer); assert_string_equal(element0, BufferData(buffer)); assert_int_equal(DEFAULT_BUFFER_CAPACITY, buffer->capacity); // Attach a small string to it BufferAppend(buffer, element1, element1size); assert_int_equal(element0size + element1size, BufferSize(buffer)); element1pointer = buffer->buffer; assert_true(element0pointer == element1pointer); assert_int_equal(buffer->used, element0size + element1size); assert_int_equal(BufferSize(buffer), element0size + element1size); char *shortAppend = NULL; shortAppend = (char *)xmalloc(element0size + element1size + 1); strcpy(shortAppend, element0); strcat(shortAppend, element1); assert_string_equal(shortAppend, buffer->buffer); assert_string_equal(shortAppend, BufferData(buffer)); /* * Zero the string and start again. */ BufferClear(buffer); BufferAppend(buffer, element0, element0size); assert_int_equal(element0size, BufferSize(buffer)); element0pointer = buffer->buffer; assert_int_equal(element0size, buffer->used); assert_int_equal(element0size, BufferSize(buffer)); assert_string_equal(element0, buffer->buffer); assert_string_equal(element0, BufferData(buffer)); /* * Larger than the allocated buffer, this means we will allocate more memory * copy stuff into the new buffer and all that. */ int i = 0; for (i = 0; i < element2size; ++i) element2[i] = 'a'; element2[element2size] = '\0'; BufferAppend(buffer, element2, element2size); assert_int_equal(element0size + element2size, BufferSize(buffer)); assert_int_equal(buffer->used, element0size + element2size); assert_int_equal(BufferSize(buffer), element0size + element2size); char *longAppend = NULL; longAppend = (char *)xmalloc(element0size + element2size + 1); strcpy(longAppend, element0); strcat(longAppend, element2); assert_string_equal(longAppend, buffer->buffer); assert_string_equal(longAppend, BufferData(buffer)); BufferClear(buffer); /* * Destroy the buffer and good night. */ free(shortAppend); free(longAppend); BufferDestroy(buffer); free(element0); free(element1); free(element2); } static void test_append_boundaries(void) { /* * Boundary checks, BUFFER_SIZE-1, BUFFER_SIZE and BUFFER_SIZE+1 */ char buffer_m1[DEFAULT_BUFFER_CAPACITY - 1]; char buffer_0[DEFAULT_BUFFER_CAPACITY]; char buffer_p1[DEFAULT_BUFFER_CAPACITY + 1]; for (size_t i = 0; i < DEFAULT_BUFFER_CAPACITY - 1; ++i) { buffer_m1[i] = 'c'; buffer_0[i] = 'd'; buffer_p1[i] = 'e'; } { const unsigned int bm1_size = DEFAULT_BUFFER_CAPACITY - 1; Buffer *bm1 = BufferNew(); buffer_m1[DEFAULT_BUFFER_CAPACITY - 2] = '\0'; BufferAppend(bm1, buffer_m1, bm1_size); assert_int_equal(strlen(buffer_m1), BufferSize(bm1)); assert_int_equal(bm1->capacity, DEFAULT_BUFFER_CAPACITY); BufferDestroy(bm1); } { const unsigned int be_size = DEFAULT_BUFFER_CAPACITY; Buffer *be = BufferNew(); buffer_0[DEFAULT_BUFFER_CAPACITY - 1] = '\0'; BufferAppend(be, buffer_0, be_size); assert_int_equal(strlen(buffer_0), BufferSize(be)); assert_int_equal(be->capacity, 2 * DEFAULT_BUFFER_CAPACITY); BufferDestroy(be); } { const unsigned int bp1_size = DEFAULT_BUFFER_CAPACITY + 1; Buffer *bp1 = BufferNew(); buffer_p1[DEFAULT_BUFFER_CAPACITY] = '\0'; BufferAppend(bp1, buffer_p1, bp1_size); assert_int_equal(strlen(buffer_p1), BufferSize(bp1)); assert_int_equal(bp1->capacity, 2 * DEFAULT_BUFFER_CAPACITY); BufferDestroy(bp1); } } static void test_printf(void) { char *char0 = xstrdup("char0"); unsigned int char0size = strlen(char0); const char *char0pointer = NULL; char *char1 = xstrdup("char1"); unsigned int char1size = strlen(char1); const char *char1pointer = NULL; char *char2 = (char *)xmalloc(2 * DEFAULT_BUFFER_CAPACITY + 2); unsigned int char2size = 2 * DEFAULT_BUFFER_CAPACITY + 1; int int0 = 123456789; char *int0char = xstrdup("123456789"); unsigned int int0charsize = strlen(int0char); double double0 = 3.1415; char *double0char = xstrdup("3.1415"); unsigned int double0charsize = strlen(double0char); char *char0int0char1double0 = xstrdup("char0 123456789 char1 3.1415"); unsigned int char0int0char1double0size = strlen(char0int0char1double0); Buffer *buffer = BufferNew(); assert_true(buffer != NULL); /* * Print the first char and compare the result */ assert_int_equal(char0size, BufferPrintf(buffer, "%s", char0)); char0pointer = buffer->buffer; assert_string_equal(char0, buffer->buffer); assert_string_equal(char0, BufferData(buffer)); assert_int_equal(char0size, buffer->used); assert_int_equal(char0size, BufferSize(buffer)); /* * Overwrite the first char with the second one */ assert_int_equal(char1size, BufferPrintf(buffer, "%s", char1)); char1pointer = buffer->buffer; assert_string_equal(char1, buffer->buffer); assert_string_equal(char1, BufferData(buffer)); assert_int_equal(char1size, buffer->used); assert_int_equal(char1size, BufferSize(buffer)); assert_true(char0pointer == char1pointer); /* * Try the int now */ assert_int_equal(int0charsize, BufferPrintf(buffer, "%d", int0)); assert_string_equal(int0char, buffer->buffer); assert_string_equal(int0char, BufferData(buffer)); assert_int_equal(int0charsize, buffer->used); assert_int_equal(int0charsize, BufferSize(buffer)); /* * Try the double now */ assert_int_equal(double0charsize, BufferPrintf(buffer, "%.4f", double0)); assert_string_equal(double0char, buffer->buffer); assert_string_equal(double0char, BufferData(buffer)); assert_int_equal(double0charsize, buffer->used); assert_int_equal(double0charsize, BufferSize(buffer)); /* * Try the combination now */ assert_int_equal(char0int0char1double0size, BufferPrintf(buffer, "%s %d %s %.4f", char0, int0, char1, double0)); assert_string_equal(char0int0char1double0, buffer->buffer); assert_string_equal(char0int0char1double0, BufferData(buffer)); assert_int_equal(char0int0char1double0size, buffer->used); assert_int_equal(char0int0char1double0size, BufferSize(buffer)); /* * Finally, try something larger than the default buffer and see if we get the right return value. */ unsigned int i = 0; for (i = 0; i < char2size; ++i) char2[i] = 'a'; char2[char2size] = '\0'; // The buffer should grow assert_int_equal(char2size, BufferPrintf(buffer, "%s", char2)); assert_string_equal(char2, buffer->buffer); assert_string_equal(char2, BufferData(buffer)); assert_int_equal(char2size, buffer->used); assert_int_equal(char2size, BufferSize(buffer)); /* * Boundary checks, BUFFER_SIZE-1, BUFFER_SIZE and BUFFER_SIZE+1 */ Buffer *bm1 = BufferNew(); Buffer *be = BufferNew(); Buffer *bp1 = BufferNew(); /* * The sizes are different for printf. If we have a size of X, then the string * is of length X-1, and so forth. */ char buffer_m1[DEFAULT_BUFFER_CAPACITY]; char buffer_0[DEFAULT_BUFFER_CAPACITY + 1]; char buffer_p1[DEFAULT_BUFFER_CAPACITY + 2]; unsigned int bm1_size = DEFAULT_BUFFER_CAPACITY - 1; unsigned int be_size = DEFAULT_BUFFER_CAPACITY; unsigned int bp1_size = DEFAULT_BUFFER_CAPACITY + 1; /* * Make sure the buffers are filled with 0. */ memset(buffer_m1, '\0', DEFAULT_BUFFER_CAPACITY); memset(buffer_0, '\0', DEFAULT_BUFFER_CAPACITY + 1); memset(buffer_p1, '\0', DEFAULT_BUFFER_CAPACITY + 2); /* * Write something to the buffers */ memset(buffer_m1, 'c', DEFAULT_BUFFER_CAPACITY); memset(buffer_0, 'd', DEFAULT_BUFFER_CAPACITY + 1); memset(buffer_p1, 'e', DEFAULT_BUFFER_CAPACITY + 2); /* * One shorter, that means the buffer remains the same size as before. */ buffer_m1[DEFAULT_BUFFER_CAPACITY - 1] = '\0'; assert_int_equal(bm1_size, BufferPrintf(bm1, "%s", buffer_m1)); assert_string_equal(buffer_m1, bm1->buffer); assert_int_equal(bm1->capacity, DEFAULT_BUFFER_CAPACITY); /* * Same size, it should allocate one more block. * This means retrying the operation. */ buffer_0[DEFAULT_BUFFER_CAPACITY] = '\0'; assert_int_equal(be_size, BufferPrintf(be, "%s", buffer_0)); assert_string_equal(buffer_0, be->buffer); assert_int_equal(be->capacity, 2 * DEFAULT_BUFFER_CAPACITY); /* * 1 more, it should allocate one more block * This means retrying the operation. */ buffer_p1[DEFAULT_BUFFER_CAPACITY + 1] = '\0'; assert_int_equal(bp1_size, BufferPrintf(bp1, "%s", buffer_p1)); assert_string_equal(buffer_p1, bp1->buffer); assert_int_equal(bp1->capacity, 2 * DEFAULT_BUFFER_CAPACITY); /* * Release the resources */ BufferDestroy(buffer); BufferDestroy(bm1); BufferDestroy(be); BufferDestroy(bp1); free(char0); free(char1); free(char2); free(int0char); free(double0char); free(char0int0char1double0); } static int test_vprintf_helper(Buffer *buffer, char *fmt, ...) { va_list ap; va_start(ap, fmt); int result = 0; result = BufferVPrintf(buffer, fmt, ap); va_end(ap); return result; } static void test_vprintf(void) { char *char0 = xstrdup("char0"); unsigned int char0size = strlen(char0); const char *char0pointer = NULL; char *char1 = xstrdup("char1"); unsigned int char1size = strlen(char1); const char *char1pointer = NULL; char *char2 = (char *)xmalloc(2 * DEFAULT_BUFFER_CAPACITY + 2); unsigned int char2size = 2 * DEFAULT_BUFFER_CAPACITY + 1; int int0 = 123456789; char *int0char = xstrdup("123456789"); unsigned int int0charsize = strlen(int0char); double double0 = 3.1415; char *double0char = xstrdup("3.1415"); unsigned int double0charsize = strlen(double0char); char *char0int0char1double0 = xstrdup("char0 123456789 char1 3.1415"); unsigned int char0int0char1double0size = strlen(char0int0char1double0); Buffer *buffer = BufferNew(); assert_true(buffer != NULL); /* * Print the first char and compare the result */ assert_int_equal(char0size, test_vprintf_helper(buffer, "%s", char0)); char0pointer = buffer->buffer; assert_string_equal(char0, buffer->buffer); assert_string_equal(char0, BufferData(buffer)); assert_int_equal(char0size, buffer->used); assert_int_equal(char0size, BufferSize(buffer)); /* * Overwrite the first char with the second one */ assert_int_equal(char1size, test_vprintf_helper(buffer, "%s", char1)); char1pointer = buffer->buffer; assert_string_equal(char1, buffer->buffer); assert_string_equal(char1, BufferData(buffer)); assert_int_equal(char1size, buffer->used); assert_int_equal(char1size, BufferSize(buffer)); assert_true(char0pointer == char1pointer); /* * Try the int now */ assert_int_equal(int0charsize, test_vprintf_helper(buffer, "%d", int0)); assert_string_equal(int0char, buffer->buffer); assert_string_equal(int0char, BufferData(buffer)); assert_int_equal(int0charsize, buffer->used); assert_int_equal(int0charsize, BufferSize(buffer)); /* * Try the double now */ assert_int_equal(double0charsize, test_vprintf_helper(buffer, "%.4f", double0)); assert_string_equal(double0char, buffer->buffer); assert_string_equal(double0char, BufferData(buffer)); assert_int_equal(double0charsize, buffer->used); assert_int_equal(double0charsize, BufferSize(buffer)); /* * Try the combination now */ assert_int_equal(char0int0char1double0size, test_vprintf_helper(buffer, "%s %d %s %.4f", char0, int0, char1, double0)); assert_string_equal(char0int0char1double0, buffer->buffer); assert_string_equal(char0int0char1double0, BufferData(buffer)); assert_int_equal(char0int0char1double0size, buffer->used); assert_int_equal(char0int0char1double0size, BufferSize(buffer)); /* * Finally, try something larger than the default buffer and see if we get the right return value. */ unsigned int i = 0; for (i = 0; i < char2size; ++i) char2[i] = 'a'; char2[char2size] = '\0'; // The buffer should resize itself assert_int_equal(char2size, test_vprintf_helper(buffer, "%s", char2)); assert_string_equal(char2, buffer->buffer); assert_string_equal(char2, BufferData(buffer)); assert_int_equal(char2size, buffer->used); assert_int_equal(char2size, BufferSize(buffer)); /* * Boundary checks, BUFFER_SIZE-1, BUFFER_SIZE and BUFFER_SIZE+1 */ Buffer *bm1 = BufferNew(); Buffer *be = BufferNew(); Buffer *bp1 = BufferNew(); /* * The sizes are different for printf. If we have a size of X, then the string * is of length X-1, and so forth. */ char buffer_m1[DEFAULT_BUFFER_CAPACITY]; char buffer_0[DEFAULT_BUFFER_CAPACITY + 1]; char buffer_p1[DEFAULT_BUFFER_CAPACITY + 2]; unsigned int bm1_size = DEFAULT_BUFFER_CAPACITY - 1; unsigned int be_size = DEFAULT_BUFFER_CAPACITY; unsigned int bp1_size = DEFAULT_BUFFER_CAPACITY + 1; /* * Make sure the buffers are filled with 0. */ memset(buffer_m1, '\0', DEFAULT_BUFFER_CAPACITY); memset(buffer_0, '\0', DEFAULT_BUFFER_CAPACITY + 1); memset(buffer_p1, '\0', DEFAULT_BUFFER_CAPACITY + 2); /* * Write something to the buffers */ memset(buffer_m1, 'c', DEFAULT_BUFFER_CAPACITY); memset(buffer_0, 'd', DEFAULT_BUFFER_CAPACITY + 1); memset(buffer_p1, 'e', DEFAULT_BUFFER_CAPACITY + 2); /* * One shorter, that means the buffer remains the same size as before. */ buffer_m1[DEFAULT_BUFFER_CAPACITY - 1] = '\0'; assert_int_equal(bm1_size, test_vprintf_helper(bm1, "%s", buffer_m1)); assert_string_equal(buffer_m1, bm1->buffer); assert_int_equal(bm1->capacity, DEFAULT_BUFFER_CAPACITY); /* * Same size, it should allocate one more block. * This means retrying the operation. */ buffer_0[DEFAULT_BUFFER_CAPACITY] = '\0'; assert_int_equal(be_size, test_vprintf_helper(be, "%s", buffer_0)); assert_string_equal(buffer_0, be->buffer); assert_int_equal(be->capacity, 2 * DEFAULT_BUFFER_CAPACITY); /* * 1 more, it should allocate one more block * This means retrying the operation. */ buffer_p1[DEFAULT_BUFFER_CAPACITY + 1] = '\0'; assert_int_equal(bp1_size, test_vprintf_helper(bp1, "%s", buffer_p1)); assert_string_equal(buffer_p1, bp1->buffer); assert_int_equal(bp1->capacity, 2 * DEFAULT_BUFFER_CAPACITY); /* * Release the resources */ BufferDestroy(buffer); BufferDestroy(bm1); BufferDestroy(be); BufferDestroy(bp1); free(char0); free(char1); free(char2); free(int0char); free(double0char); free(char0int0char1double0); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_createBuffer), unit_test(test_createBufferFrom), unit_test(test_destroyBuffer), unit_test(test_zeroBuffer), unit_test(test_copyCompareBuffer), unit_test(test_setBuffer), unit_test(test_appendBuffer), unit_test(test_append_boundaries), unit_test(test_printf), unit_test(test_vprintf) }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/string_lib_test.c0000644000000000000000000015205215010704254022631 0ustar00rootroot00000000000000#include #include #include #include #include #include static const char *lo_alphabet = "abcdefghijklmnopqrstuvwxyz"; static const char *hi_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static void test_get_token(void) { { const char *str = " abc def ,efg "; size_t len = strlen(str); assert_int_equal(3, StringCountTokens(str, len, ", ")); { StringRef ref = StringGetToken(str, len, 0, ", "); assert_int_equal(3, ref.len); assert_memory_equal("abc", ref.data, 3); } { StringRef ref = StringGetToken(str, len, 1, ", "); assert_int_equal(3, ref.len); assert_memory_equal("def", ref.data, 3); } { StringRef ref = StringGetToken(str, len, 2, ", "); assert_int_equal(3, ref.len); assert_memory_equal("efg", ref.data, 3); } } { const char *str = "abc"; size_t len = strlen(str); assert_int_equal(1, StringCountTokens(str, len, ", ")); { StringRef ref = StringGetToken(str, len, 0, ", "); assert_int_equal(3, ref.len); assert_memory_equal("abc", ref.data, 3); } } { const char *str = "abc "; size_t len = strlen(str); assert_int_equal(1, StringCountTokens(str, len, ", ")); { StringRef ref = StringGetToken(str, len, 0, ", "); assert_int_equal(3, ref.len); assert_memory_equal("abc", ref.data, 3); } } } static void test_mix_case_tolower(void) { char str[] = "aBcD"; ToLowerStrInplace(str); assert_string_equal(str, "abcd"); } static void test_empty_tolower(void) { char str[] = ""; ToLowerStrInplace(str); assert_string_equal(str, ""); } static void test_weird_chars_tolower(void) { static const char *weirdstuff = "1345\0xff%$#@!"; char weirdstuff_copy_lowercased[CF_MAXVARSIZE]; strlcpy(weirdstuff_copy_lowercased, weirdstuff, CF_MAXVARSIZE); ToLowerStrInplace(weirdstuff_copy_lowercased); assert_string_equal(weirdstuff_copy_lowercased, weirdstuff); } static void test_alphabet_tolower(void) { char lo_alphabet_lowercased[CF_MAXVARSIZE]; strlcpy(lo_alphabet_lowercased, lo_alphabet, CF_MAXVARSIZE); ToLowerStrInplace(lo_alphabet_lowercased); assert_string_equal(lo_alphabet_lowercased, lo_alphabet); } static void test_hi_alphabet_tolower(void) { char hi_alphabet_lowercased[CF_MAXVARSIZE]; strlcpy(hi_alphabet_lowercased, hi_alphabet, CF_MAXVARSIZE); ToLowerStrInplace(hi_alphabet_lowercased); assert_string_equal(hi_alphabet_lowercased, lo_alphabet); } static void test_inplace_tolower(void) { char abc[] = "abc"; char def[] = "def"; ToLowerStrInplace(abc); ToLowerStrInplace(def); assert_string_equal(abc, "abc"); assert_string_equal(def, "def"); } static void test_mix_case_toupper(void) { char str[] = "aBcD"; ToUpperStrInplace(str); assert_string_equal(str, "ABCD"); } static void test_empty_toupper(void) { char str[] = ""; ToUpperStrInplace(str); assert_string_equal(str, ""); } static void test_weird_chars_toupper(void) { static const char *weirdstuff = "1345\0xff%$#@!"; char weirdstuff_copy_uppercased[CF_MAXVARSIZE]; strlcpy(weirdstuff_copy_uppercased, weirdstuff, CF_MAXVARSIZE); ToUpperStrInplace(weirdstuff_copy_uppercased); assert_string_equal(weirdstuff_copy_uppercased, weirdstuff); } static void test_alphabet_toupper(void) { char lo_alphabet_uppercased[CF_MAXVARSIZE]; strlcpy(lo_alphabet_uppercased, lo_alphabet, CF_MAXVARSIZE); ToUpperStrInplace(lo_alphabet_uppercased); assert_string_equal(lo_alphabet_uppercased, hi_alphabet); } static void test_hi_alphabet_toupper(void) { char hi_alphabet_uppercased[CF_MAXVARSIZE]; strlcpy(hi_alphabet_uppercased, hi_alphabet, CF_MAXVARSIZE); ToUpperStrInplace(hi_alphabet_uppercased); assert_string_equal(hi_alphabet_uppercased, hi_alphabet); } static void test_inplace_toupper(void) { char abc[] = "abc"; char def[] = "def"; ToUpperStrInplace(abc); ToUpperStrInplace(def); assert_string_equal(abc, "ABC"); assert_string_equal(def, "DEF"); } static void test_long_search(void) { char *ns = SearchAndReplace("abc", "abcabc", "test"); assert_string_equal(ns, "abc"); free(ns); } static void test_replace_empty_pattern(void) { char *ns = SearchAndReplace("foobarbaz", "", "abc"); assert_string_equal(ns, "foobarbaz"); free(ns); } static void test_replace_empty_replacement(void) { char *ns = SearchAndReplace("foobarbaz", "a", ""); assert_string_equal(ns, "foobrbz"); free(ns); } static void test_replace_eq_size(void) { char *new_string = SearchAndReplace("sasza szedl sucha szosa", "sz", "xx"); assert_string_equal(new_string, "saxxa xxedl sucha xxosa"); free(new_string); } static void test_replace_more_size(void) { char *new_string = SearchAndReplace("sasza szedl sucha szosa", "sz", "xxx"); assert_string_equal(new_string, "saxxxa xxxedl sucha xxxosa"); free(new_string); } static void test_replace_less_size(void) { char *new_string = SearchAndReplace("sasza szedl sucha szosa", "sz", "x"); assert_string_equal(new_string, "saxa xedl sucha xosa"); free(new_string); } static void test_no_replace(void) { char *new_string = SearchAndReplace("sasza szedl sucha szosa", "no_such_pattern", "x"); assert_string_equal(new_string, "sasza szedl sucha szosa"); free(new_string); } /**************************************************************************** * Tests for StringReplace() * * StringReplace and SearchAndReplace differ in that StringReplace errors * * if the buffer is too small, and SearchAndReplace allocates sufficient * * space. * ****************************************************************************/ static void test_string_replace_empty_replacement(void) { char string[] = "foobarbaz"; size_t actual_size = strlen(string); ssize_t ret_size = StringReplace(string, actual_size + 1, "a", ""); // StringReplace returns the length without counting '\0' assert_int_not_equal(ret_size, actual_size); assert_string_equal(string, "foobrbz"); } static void test_string_replace_eq_size(void) { char string[] = "sasza szedl sucha szosa"; size_t actual_size = strlen(string); ssize_t ret_size = StringReplace(string, actual_size + 1, "sz", "xx"); assert_int_equal(ret_size, actual_size); assert_string_equal(string, "saxxa xxedl sucha xxosa"); } static void test_string_replace_buf_too_small(void) { char string[] = "sasza szedl sucha szosa"; size_t actual_size = sizeof(string); ssize_t ret_size = StringReplace(string, actual_size, "sz", "xxx"); // Errors, `string` is retained assert_int_equal(ret_size, (ssize_t) -1); assert_string_equal(string, "sasza szedl sucha szosa"); } static void test_string_replace_smaller(void) { char string[] = "sasza szedl sucha szosa"; size_t actual_size = strlen(string); ssize_t ret_size = StringReplace(string, actual_size + 1, "sz", "x"); assert_int_not_equal(ret_size, actual_size); assert_string_equal(string, "saxa xedl sucha xosa"); } static void test_string_replace_none(void) { char string[] = "sasza szedl sucha szosa"; size_t actual_size = strlen(string); ssize_t ret_size = StringReplace(string, actual_size + 1, "no_such_pattern", "x"); assert_int_equal(ret_size, 0); assert_string_equal(string, "sasza szedl sucha szosa"); } static void test_string_replace_many_percentages(void) { char string[29] = "%%%%%%%%%%%%%%"; size_t actual_size = sizeof(string); ssize_t ret_size = StringReplace(string, actual_size, "%", "%%"); assert_int_equal(ret_size, actual_size - 1); assert_string_equal(string, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); } static void test_string_replace_n(void) { char buf[11] = "1,2,3,4\0\0\0"; /* strlen(buf) == 7 */ ssize_t ret = StringReplaceN(buf, sizeof(buf), ",", "__", 2); assert_int_equal(ret, 7 + 2); assert_string_equal(buf, "1__2__3,4"); /* nothing should happen (n == 0) */ ret = StringReplaceN(buf, sizeof(buf), ",", "__", 0); assert_int_equal(ret, 0); assert_string_equal(buf, "1__2__3,4"); /* one replacement possible */ ret = StringReplaceN(buf, sizeof(buf), ",", "__", 2); assert_int_equal(ret, 7 + 3); assert_string_equal(buf, "1__2__3__4"); /* nothing should happen (n == 0) */ ret = StringReplaceN(buf, sizeof(buf), ",", "__", 0); assert_int_equal(ret, 0); assert_string_equal(buf, "1__2__3__4"); /* nothing should happen (nothing to replace) */ ret = StringReplaceN(buf, sizeof(buf), ",", "__", 5); assert_int_equal(ret, 0); assert_string_equal(buf, "1__2__3__4"); } /****************************************************************************/ static void test_concatenate(void) { char *new_string = StringConcatenate(2, "snookie", "sitch"); assert_string_equal(new_string, "snookiesitch"); free(new_string); new_string = StringConcatenate(4, "a", NULL, "c", "d"); assert_string_equal(new_string, "acd"); free(new_string); new_string = StringConcatenate(3, "a", "b", "c", "d"); assert_string_equal(new_string, "abc"); free(new_string); new_string = StringConcatenate(1, "stuff"); assert_string_equal(new_string, "stuff"); free(new_string); new_string = StringConcatenate(0, NULL); assert_false(new_string); } static void test_substring_overshoot(void) { char *new_string = StringSubstring("abcdef", 6, 0, 10); assert_string_equal(new_string, "abcdef"); free(new_string); } static void test_substring_positive(void) { char *new_string = StringSubstring("abcdef", 6, 2, 3); assert_string_equal(new_string, "cde"); free(new_string); } static void test_substring_negative_length(void) { char *new_string = StringSubstring("abcdef", 6, 2, -1); assert_string_equal(new_string, "cde"); free(new_string); } static void test_substring_negative(void) { char *new_string = StringSubstring("abcdef", 6, -3, -1); assert_string_equal(new_string, "de"); free(new_string); } static void test_substring_evil(void) { char *new_string = StringSubstring("abcdef", 6, 4, -4); assert_int_equal(new_string, NULL); } static void test_string_to_long(void) { // Basic usage: assert_int_equal(StringToLongExitOnError("0"), 0); assert_int_equal(StringToLongExitOnError("-0"), 0); assert_int_equal(StringToLongExitOnError("+0"), 0); assert_int_equal(StringToLongExitOnError("123"), 123); assert_int_equal(StringToLongExitOnError("+123"), 123); // WARNING: Some platforms have 32-bit long, 2,147,483,647 is LONG_MAX assert_int_equal(StringToLongExitOnError("2147483647"), 2147483647); assert_int_equal(StringToLongExitOnError("1987654320"), 1987654320); // Negative numbers: assert_int_equal((int)StringToLongExitOnError("-1"), -1); assert_int_equal( StringToLongExitOnError("-1"), (long)-1); assert_int_equal((int)StringToLongExitOnError("-1"), -1); assert_int_equal( StringToLongExitOnError("-1"), (long)-1); // Leading spaces: assert_int_equal(StringToLongExitOnError(" 0") , 0); assert_int_equal(StringToLongExitOnError(" 123"), 123); assert_int_equal(StringToLongExitOnError(" -123"), (long)-123); assert_int_equal(StringToLongExitOnError(" 0"), 0); assert_int_equal(StringToLongExitOnError(" 123"), 123); assert_int_equal(StringToLongExitOnError(" -123"), (long)-123); // Trailing spaces: assert_int_equal(StringToLongExitOnError("0 "), 0); assert_int_equal(StringToLongExitOnError("789 "), 789); assert_int_equal(StringToLongExitOnError("-789 "), (long)-789); assert_int_equal(StringToLongExitOnError("0 "), 0); assert_int_equal(StringToLongExitOnError("789 "), 789); assert_int_equal(StringToLongExitOnError("-789 "), (long)-789); // More spaces: assert_int_equal(StringToLongExitOnError(" 0 "), 0); assert_int_equal(StringToLongExitOnError(" -0 "), 0); assert_int_equal(StringToLongExitOnError(" 456 "), 456); // Space separated numbers: assert_int_equal(StringToLongExitOnError(" 456 9 "), 456); assert_int_equal(StringToLongExitOnError("1 0"), 1); } static void test_string_to_long_default(void) { assert_int_equal(StringToLongDefaultOnError("0",10), 0); assert_int_equal(StringToLongDefaultOnError(" ",10), 10); assert_int_equal(StringToLongDefaultOnError("error",123), 123); assert_int_equal(StringToLongDefaultOnError("-error",-123), (long)-123); } static void test_string_to_long_errors(void) { // A succesful call to StringToLong should return 0: long target = 0; assert_int_equal(StringToLong("1234", &target), 0); assert_int_equal(target, 1234); // Test that invalid inputs give error return code: assert_int_not_equal(StringToLong("", &target), 0); assert_int_not_equal(StringToLong(" ", &target), 0); assert_int_not_equal(StringToLong("error", &target), 0); assert_int_not_equal(StringToLong("-error", &target), 0); assert_int_not_equal(StringToLong("ffff", &target), 0); assert_int_not_equal(StringToLong("1d", &target), 0); assert_int_not_equal(StringToLong("56789d", &target), 0); assert_int_equal(StringToLong("9999999999999999999999999999999", &target), ERANGE); assert_int_equal(StringToLong(" 999999999999999999999999999999", &target), ERANGE); assert_int_equal(StringToLong("-999999999999999999999999999999", &target), ERANGE); // Test that error logging function can be called: LogStringToLongError("-999999999999999999999999999999", "string_lib_test", ERANGE); // Check that target is unmodified after errors: assert_int_equal(target, 1234); } static void test_string_to_long_unsafe(void) { assert_int_equal(StringToLongUnsafe("0"), 0); assert_int_equal(StringToLongUnsafe("1"), 1); assert_int_equal(StringToLongUnsafe(" 0"), 0); assert_int_equal(StringToLongUnsafe(" 1"), 1); assert_int_equal(StringToLongUnsafe("-1"), (long)-1); assert_int_equal(StringToLongUnsafe(" -1"), (long)-1); assert_int_equal(StringToLongUnsafe(" -987"), (long)-987); assert_int_equal(StringToLongUnsafe("1987654320"), 1987654320); assert_int_equal(StringToLongUnsafe(" 1987654320"), 1987654320); assert_int_equal(StringToLongUnsafe(" -1987654320"), (long)-1987654320); // Weird edge case: assert_int_equal(StringToLongUnsafe(""), 0); } // StringToLongExitOnError should replace StringToLongUnsafe: #define assert_string_to_long_unsafe(x)\ {\ assert_int_equal(StringToLongExitOnError(x), StringToLongUnsafe(x));\ } static void test_string_to_long_compatibility(void) { // All these inputs should give same result for new and old function: assert_string_to_long_unsafe("0"); assert_string_to_long_unsafe("-1"); assert_string_to_long_unsafe("-0"); assert_string_to_long_unsafe(" -0"); assert_string_to_long_unsafe("1"); assert_string_to_long_unsafe("123"); assert_string_to_long_unsafe("1987654320"); assert_string_to_long_unsafe(" 1987654320"); // Old function (StringToLongUnsafe) does not allow trailing whitespace } #define ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(str, value_out, expected) \ assert_int_equal(StringDecimalToLong(str, &value_out), 0); \ assert_int_equal(value_out, expected) static void test_string_decimal_to_long(void) { long value_out; // Basic usage: ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("0.0", value_out, 0); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("-0.0", value_out, 0); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("+0.0", value_out, 0); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("123.0", value_out, 123); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("+123.0", value_out, 123); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("-123.0", value_out, (long) -123); // Leading spaces: ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" 0.0", value_out, 0); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" 123.0", value_out, 123); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" -123.0", value_out, (long) -123); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" 0.0", value_out, 0); // 12 is max accepted int length ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" 123.0", value_out, 123); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" -123.0", value_out, (long) -123); // Trailing spaces: ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("9.0 ", value_out, 9); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("789.0 ", value_out, 789); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("-789.0 ", value_out, (long) -789); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("9.0 ", value_out, 9); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("789.0 ", value_out, 789); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("-789.0 ", value_out, (long) -789); // More spaces: ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" 0.0 ", value_out, 0); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" -0.0 ", value_out, 0); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" 123.0 ", value_out, 123); // Space separated numbers: ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG(" 123.456 78 9 ", value_out, 123); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("123.0 45", value_out, 123); // Edge case: it doesnt matter what is after the decimal point ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("789.0b", value_out, 789); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("123.blah", value_out, 123); ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("456.", value_out, 456); } static void test_string_decimal_to_long_errors(void) { // Successful call returns 0 long value_out; ASSERT_INT_EQUAL_STRING_DECIMAL_TO_LONG("1234.5678", value_out, 1234); assert_int_not_equal(StringDecimalToLong("", &value_out), 0); assert_int_not_equal(StringDecimalToLong(" ", &value_out), 0); assert_int_not_equal(StringDecimalToLong("error", &value_out), 0); assert_int_not_equal(StringDecimalToLong("-error", &value_out), 0); assert_int_not_equal(StringDecimalToLong("ffff", &value_out), 0); assert_int_equal(StringDecimalToLong("999999999999999999999999999999.9", &value_out), -84); assert_int_equal(StringDecimalToLong(" 999999999999999999999999999999.9", &value_out), -84); assert_int_equal(StringDecimalToLong("-999999999999999999999999999999.9", &value_out), -84); // value_out should be unmodified after errors assert_int_equal(value_out, 1234); } static void test_string_to_ulong(void) { // Basic usage: assert_int_equal(StringToUlongExitOnError("0"), 0); assert_int_equal(StringToUlongExitOnError("-0"), 0); assert_int_equal(StringToUlongExitOnError("+0"), 0); assert_int_equal(StringToUlongExitOnError("123"), 123); assert_int_equal(StringToUlongExitOnError("+123"), 123); // WARNING: Some platforms have 32-bit unsigned long, 4 294 967 295 is ULONG_MAX assert_int_equal(StringToUlongExitOnError("2147483647"), 2147483647); assert_int_equal(StringToUlongExitOnError("1987654320"), 1987654320); // Leading spaces: assert_int_equal(StringToUlongExitOnError(" 0") , 0); assert_int_equal(StringToUlongExitOnError(" 123"), 123); assert_int_equal(StringToUlongExitOnError(" -0"), 0); assert_int_equal(StringToUlongExitOnError(" 0"), 0); assert_int_equal(StringToUlongExitOnError(" 123"), 123); assert_int_equal(StringToUlongExitOnError(" -0"), 0); // Trailing spaces: assert_int_equal(StringToUlongExitOnError("0 "), 0); assert_int_equal(StringToUlongExitOnError("789 "), 789); assert_int_equal(StringToUlongExitOnError("-0 "), 0); assert_int_equal(StringToUlongExitOnError("0 "), 0); assert_int_equal(StringToUlongExitOnError("789 "), 789); assert_int_equal(StringToUlongExitOnError("+789 "), 789); // More spaces: assert_int_equal(StringToUlongExitOnError(" 0 "), 0); assert_int_equal(StringToUlongExitOnError(" -0 "), 0); assert_int_equal(StringToUlongExitOnError(" 456 "), 456); // Space separated numbers: assert_int_equal(StringToUlongExitOnError(" 456 9 "), 456); assert_int_equal(StringToUlongExitOnError("1 0"), 1); } static void test_string_to_ulong_default(void) { assert_int_equal(StringToUlongDefaultOnError("0",10), 0); assert_int_equal(StringToUlongDefaultOnError(" ",10), 10); assert_int_equal(StringToUlongDefaultOnError("error",123), 123); assert_int_equal(StringToUlongDefaultOnError("-123",0), 0); } static void test_string_to_ulong_errors(void) { // A succesful call to StringToLong should return 0: long target = 0; assert_int_equal(StringToUlong("1234", &target), 0); assert_int_equal(target, 1234); // Test that invalid inputs give error return code: assert_int_not_equal(StringToUlong("", &target), 0); assert_int_not_equal(StringToUlong(" ", &target), 0); assert_int_not_equal(StringToUlong("error", &target), 0); assert_int_not_equal(StringToUlong("-error", &target), 0); assert_int_not_equal(StringToUlong("ffff", &target), 0); assert_int_not_equal(StringToUlong("1d", &target), 0); assert_int_not_equal(StringToUlong("56789d", &target), 0); assert_int_equal(StringToUlong("9999999999999999999999999999999", &target), ERANGE); assert_int_equal(StringToUlong(" 999999999999999999999999999999", &target), ERANGE); assert_int_equal(StringToUlong("-1", &target), ERANGE); // Test that error logging function can be called: LogStringToLongError("-999999999999999999999999999999", "string_lib_test", ERANGE); // Check that target is unmodified after errors: assert_int_equal(target, 1234); } static void test_string_to_int64(void) { assert_int_equal(StringToInt64ExitOnError("0"), 0); assert_int_equal(StringToInt64ExitOnError("-0"), 0); assert_int_equal(StringToInt64ExitOnError("+0"), 0); assert_int_equal(StringToInt64ExitOnError("123"), 123); assert_int_equal(StringToInt64ExitOnError("+123"), 123); assert_int_equal(StringToInt64ExitOnError("9999999999"), 9999999999); assert_int_equal(StringToInt64ExitOnError("-9999999999"), -9999999999); assert_int_equal(StringToInt64ExitOnError("1234 "), 1234); assert_int_equal(StringToInt64ExitOnError("1234\n"), 1234); assert_int_equal(StringToInt64DefaultOnError("123", -1), 123); assert_int_equal(StringToInt64DefaultOnError("9999999999", 0), 9999999999); assert_int_equal(StringToInt64DefaultOnError("-9999999999", 0), -9999999999); assert_int_equal(StringToInt64DefaultOnError("", 456), 456); assert_int_equal(StringToInt64DefaultOnError(" ", 456), 456); assert_int_equal(StringToInt64DefaultOnError("\n", 456), 456); assert_int_equal(StringToInt64DefaultOnError("a", 456), 456); assert_int_equal(StringToInt64DefaultOnError("abc", 456), 456); assert_int_equal(StringToInt64DefaultOnError("k", 456), 456); { // Paranoid test, ensure value is not cast to smaller type: int error_code; int64_t out; error_code = StringToInt64("9223372036854775807", &out); assert_int_equal(error_code, 0); assert_true(out == 9223372036854775807); error_code = StringToInt64("-9223372036854775808", &out); assert_int_equal(error_code, 0); // https://stackoverflow.com/a/60323339 : assert_true(out == -9223372036854775807 - 1); } { // Error cases: // Give bad address - function should not read/write to it int error_code; error_code = StringToInt64("", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64(" ", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64("-", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64("\n", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64("[]", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64("{}", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64("\"\"", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64("e", NULL + 1); assert_true(error_code != 0); error_code = StringToInt64("1234abc", NULL + 1); assert_true(error_code != 0); } } static void test_string_from_long(void) { char *result = StringFromLong(123456789); assert_string_equal("123456789", result); free(result); result = StringFromLong(-123456789); assert_string_equal("-123456789", result); free(result); } static void test_string_to_double(void) { assert_true(1234.1234 == StringToDouble("1234.1234")); } static void test_string_from_double(void) { char *result = StringFromDouble(1234.1234); assert_string_equal("1234.12", result); free(result); } static void test_safe_compare(void) { // Strings which are equal: assert_true(StringSafeCompare(NULL, NULL) == 0); assert_true(StringSafeCompare("", "") == 0); assert_true(StringSafeCompare("a", "a") == 0); assert_true(StringSafeCompare("abc", "abc") == 0); assert_true(StringSafeCompare("Hello, world!", "Hello, world!") == 0); // Strings which are not equal: assert_true(StringSafeCompare("abc", "abC") != 0); assert_true(StringSafeCompare("a", "b") != 0); // Test ordering of strings (correct sign): assert_true(StringSafeCompare(NULL, "a") <= -1); assert_true(StringSafeCompare("", "a") <= -1); assert_true(StringSafeCompare("a", NULL) >= 1); assert_true(StringSafeCompare("a", "") >= 1); assert_true(StringSafeCompare("albatross", "bear") <= -1); assert_true(StringSafeCompare("lynx", "chicken") >= 1); } static void test_safe_equal(void) { assert_true(StringEqual(NULL, NULL)); assert_true(StringEqual("a", "a")); assert_true(StringEqual("abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz")); assert_true(StringEqual("0123456789", "0123456789")); assert_true(StringEqual("CamelCase", "CamelCase")); assert_true(StringEqual("(){}[]<>", "(){}[]<>")); assert_true(StringEqual("+-*/%%^", "+-*/%%^")); assert_false(StringEqual("", NULL)); assert_false(StringEqual(NULL, "")); assert_false(StringEqual("a", "b")); assert_false(StringEqual("a", "A")); assert_false(StringEqual("abc def", "abc deF")); } static void test_safe_compare_ignore_case(void) { // Strings which are equal: assert_true(StringSafeCompare_IgnoreCase(NULL, NULL) == 0); assert_true(StringSafeCompare_IgnoreCase("", "") == 0); assert_true(StringSafeCompare_IgnoreCase("a", "a") == 0); assert_true(StringSafeCompare_IgnoreCase("abc", "abc") == 0); assert_true(StringSafeCompare_IgnoreCase("Hello, world!", "Hello, world!") == 0); // Strings with only case differences: assert_true(StringSafeCompare_IgnoreCase("abc", "abC") == 0); assert_true(StringSafeCompare_IgnoreCase("a", "A") == 0); assert_true(StringSafeCompare_IgnoreCase("HELLO, WORLD!", "Hello, world!") == 0); assert_true(StringSafeCompare_IgnoreCase("HELLO, WORLD!", "hello, world!") == 0); // Test ordering of strings (correct sign): assert_true(StringSafeCompare_IgnoreCase(NULL, "a") <= -1); assert_true(StringSafeCompare_IgnoreCase("", "a") <= -1); assert_true(StringSafeCompare_IgnoreCase("a", NULL) >= 1); assert_true(StringSafeCompare_IgnoreCase("a", "") >= 1); assert_true(StringSafeCompare_IgnoreCase("albatross", "bear") <= -1); assert_true(StringSafeCompare_IgnoreCase("lynx", "chicken") >= 1); // Cases where StringSafeCompare and StringSafeCompare_IgnoreCase should be the same: assert_int_equal(StringSafeCompare("a", "b"), StringSafeCompare_IgnoreCase("a", "b")); assert_int_equal(StringSafeCompare("a", "b"), StringSafeCompare_IgnoreCase("A", "B")); assert_int_equal(StringSafeCompare("A", "B"), StringSafeCompare_IgnoreCase("a", "b")); assert_int_equal(StringSafeCompare("bbc", "bbd"), StringSafeCompare_IgnoreCase("BBC", "bbd")); assert_int_equal(StringSafeCompare("bbc", "bbd"), StringSafeCompare_IgnoreCase("BBC", "BBd")); } static void test_safe_equal_ignore_case(void) { assert_true(StringEqual_IgnoreCase(NULL, NULL)); assert_true(StringEqual_IgnoreCase("a", "a")); assert_true(StringEqual_IgnoreCase("a", "A")); assert_true(StringEqual_IgnoreCase(hi_alphabet, lo_alphabet)); assert_true(StringEqual_IgnoreCase("0123456789", "0123456789")); assert_true(StringEqual_IgnoreCase("CamelCase", "camelcase")); assert_true(StringEqual_IgnoreCase("(){}[]<>", "(){}[]<>")); assert_true(StringEqual_IgnoreCase("+-*/%%^", "+-*/%%^")); assert_true(StringEqual_IgnoreCase("abc def", "abc deF")); assert_false(StringEqual_IgnoreCase("", NULL)); assert_false(StringEqual_IgnoreCase(NULL, "")); assert_false(StringEqual_IgnoreCase("a", "b")); } static void test_safe_equal_n(void) { assert_true(StringEqualN("abcd", "abcX", 3)); assert_true(StringEqualN_IgnoreCase("abcd", "ABCX", 3)); assert_false(StringEqualN("abcd", "abXX", 3)); assert_false(StringEqualN_IgnoreCase("abcd", "ABXX", 3)); assert_true(StringEqualN("123abc", "123abc", 1000)); assert_true(StringEqualN_IgnoreCase("123abc", "123ABC", 1000)); } static void test_is_string_in_array(void) { const char *array[5] = {"one", "two", "three", "four", "five"}; assert_true(IsStringInArray("one", array, 5)); assert_true(IsStringInArray("two", array, 5)); assert_true(IsStringInArray("three", array, 5)); assert_true(IsStringInArray("four", array, 5)); assert_true(IsStringInArray("five", array, 5)); assert_false(IsStringInArray("fire", array, 5)); assert_false(IsStringInArray("five", array, 3)); const char **new_array = calloc(3, sizeof(char*)); new_array[0] = "one"; new_array[1] = "two"; new_array[2] = "three"; assert_true(IsStringInArray("one", new_array, 3)); assert_true(IsStringInArray("two", new_array, 3)); assert_true(IsStringInArray("three", new_array, 3)); assert_false(IsStringInArray("fire", array, 3)); assert_false(IsStringInArray("three", array, 2)); free(new_array); } static void test_encode_base64(void) { #ifdef WITH_OPENSSL { char *res = StringEncodeBase64("", 0); assert_string_equal("", res); free(res); } { char *res = StringEncodeBase64("a", 1); assert_string_equal("YQ==", res); free(res); } { char *res = StringEncodeBase64("aa", 2); assert_string_equal("YWE=", res); free(res); } { char *res = StringEncodeBase64("aaa", 3); assert_string_equal("YWFh", res); free(res); } { char *res = StringEncodeBase64("aaaa", 4); assert_string_equal("YWFhYQ==", res); free(res); } { char *res = StringEncodeBase64("snookie", 7); assert_string_equal("c25vb2tpZQ==", res); free(res); } { char *res = StringEncodeBase64("test", 4); assert_string_equal("dGVzdA==", res); free(res); } // valgrind leaks should be due to crypto one-time allocations #endif // WITH_OPENSSL } static void test_escape_char_copy(void) { char *in1 = "my test with no escape"; char *out1 = EscapeCharCopy(in1, '7', '\\'); assert_string_equal(out1, in1); free(out1); char *in2 = "my test with 'some' escape"; char *out2 = EscapeCharCopy(in2, '\'', '\\'); assert_string_equal(out2, "my test with \\'some\\' escape"); free(out2); char *in3 = "my test with 7some7"; char *out3 = EscapeCharCopy(in3, '7', '\\'); assert_string_equal(out3, "my test with \\7some\\7"); free(out3); char *in4 = "\"my\" test with 7some7"; char *out4 = EscapeCharCopy(in4, '\"', '\\'); assert_string_equal(out4, "\\\"my\\\" test with 7some7"); free(out4); char *in5 = "\"my test with 7some7\""; char *out5 = EscapeCharCopy(in5, '\"', '\\'); assert_string_equal(out5, "\\\"my test with 7some7\\\""); free(out5); } static void test_chop_no_spaces(void) { char s[] = "abc"; Chop(s, CF_EXPANDSIZE); assert_string_equal("abc", s); } static void test_chop_single_space(void) { char s[] = "abc "; Chop(s, CF_EXPANDSIZE); assert_string_equal("abc", s); } static void test_chop_two_spaces(void) { char s[] = "abc "; Chop(s, CF_EXPANDSIZE); assert_string_equal("abc", s); } static void test_chop_empty(void) { char s[] = ""; Chop(s, CF_EXPANDSIZE); assert_string_equal("", s); } static void test_chop_empty_single_space(void) { char s[] = " "; Chop(s, CF_EXPANDSIZE); assert_string_equal("", s); } static void test_chop_empty_two_spaces(void) { char s[] = " "; Chop(s, CF_EXPANDSIZE); assert_string_equal("", s); } static void test_trim_crlf(void) { { char *const data = xstrdup("\r\n"); const size_t new_length = TrimCSVLineCRLF(data); assert_string_equal(data, ""); assert_int_equal(new_length, 0); free(data); } { char *const data = xstrdup("\r\n\r\n"); const size_t new_length = TrimCSVLineCRLF(data); assert_string_equal(data, "\r\n"); assert_int_equal(new_length, 2); free(data); } { char *const data = xstrdup(","); const size_t new_length = TrimCSVLineCRLF(data); assert_string_equal(data, ","); assert_int_equal(new_length, 1); free(data); } { char *const data = xstrdup(",\r\n"); const size_t new_length = TrimCSVLineCRLF(data); assert_string_equal(data, ","); assert_int_equal(new_length, 1); free(data); } { char *const data = xstrdup("a,b,c,d,\" \"\r\n"); const size_t new_length = TrimCSVLineCRLF(data); assert_string_equal(data, "a,b,c,d,\" \""); assert_int_equal(new_length, strlen(data)); free(data); } { char *const data = xstrdup(" ,\r\n"); const size_t new_length = TrimCSVLineCRLF(data); assert_string_equal(data, " ,"); assert_int_equal(new_length, strlen(data)); free(data); } { const char *const original = ",\r\n"; char *const a = xstrdup(original); char *const b = xstrdup(original); const size_t a_len = TrimCSVLineCRLF(a); const size_t b_len = TrimCSVLineCRLF(b); assert_string_equal(a, ","); assert_string_equal(b, ","); assert_int_equal(a_len, b_len); const size_t bb_len = TrimCSVLineCRLF(b); assert_int_equal(b_len, bb_len); assert_string_equal(b, ","); free(a); free(b); } // Test strict version, which has assertions for empty strings and spaces: { char *const data = xstrdup(",\r\n"); const size_t new_length = TrimCSVLineCRLFStrict(data); assert_string_equal(data, ","); assert_int_equal(new_length, 1); free(data); } { char *const data = xstrdup(","); const size_t new_length = TrimCSVLineCRLFStrict(data); assert_string_equal(data, ","); assert_int_equal(new_length, 1); free(data); } { char *const data = xstrdup("'\r\n',\r\n"); const size_t new_length = TrimCSVLineCRLFStrict(data); assert_string_equal(data, "'\r\n',"); assert_int_equal(new_length, strlen(data)); free(data); } { char *const data = xstrdup("a,b,c,d,\" \"\r\n"); const size_t new_length = TrimCSVLineCRLFStrict(data); assert_string_equal(data, "a,b,c,d,\" \""); assert_int_equal(new_length, strlen(data)); free(data); } { char *const data = xstrdup("'\r\n',\r\n"); const size_t new_length = TrimCSVLineCRLFStrict(data); assert_string_equal(data, "'\r\n',"); assert_int_equal(new_length, strlen(data)); free(data); } } static void test_close_hole(void) { char *test_string = xstrdup("test"); StringCloseHole(test_string, 0, 0); assert_string_equal(test_string, "test"); StringCloseHole(test_string, 4, 4); assert_string_equal(test_string, "test"); size_t length = strlen(test_string); StringCloseHole(test_string, length - 1, length); assert_string_equal(test_string, "tes"); StringCloseHole(test_string, 0, 1); assert_string_equal(test_string, "es"); StringCloseHole(test_string, 1, 2); assert_string_equal(test_string, "e"); StringCloseHole(test_string, 0, 1); assert_string_equal(test_string, ""); free(test_string); } static void test_ends_with(void) { assert_true(StringEndsWith("file.json", ".json")); assert_true(StringEndsWith("file.json", "file.json")); assert_false(StringEndsWith(".json", "file")); assert_false(StringEndsWith("a", "aa")); } char *test_stringvformat_sup(const char *s, ...) { va_list ap; va_start(ap, s); char *fmted = StringVFormat(s, ap); va_end(ap); return fmted; } static void test_stringvformat(void) { char *s = test_stringvformat_sup("%s%d", "abc", 42); assert_string_equal(s, "abc42"); free(s); } static void test_stringformat(void) { char *s = StringFormat("%d%s%d", 1, "a", 2); assert_string_equal(s, "1a2"); free(s); } static void test_string_copy(void) { char a[0 + 1]; char b[1 + 1]; char c[2 + 1]; char non_terminated[3]; const size_t str_len = 3; const size_t buf_size = str_len + 1; char d[buf_size]; char e[buf_size]; char f[buf_size]; char g[buf_size]; char h[buf_size]; // Non terminated string source: non_terminated[0] = '3'; non_terminated[1] = '4'; non_terminated[2] = '5'; // Returns 3 since it was truncated to a string of length 2: // (The original was at least 3 bytes long and did not fit). assert_int_equal(3, StringCopy(non_terminated, d, 3)); assert_string_equal(d, "34"); // Too long string source (returns buf_size, NUL terminates and truncates): assert_int_equal(buf_size, StringCopy("longstring", d, buf_size)); assert_string_equal(d, "lon"); assert_int_equal(0, StringCopy("", a, 1)); assert_int_equal(1, StringCopy("A", b, 2)); assert_int_equal(2, StringCopy("BC", c, 3)); assert_int_equal(3, StringCopy("DEF", d, buf_size)); assert_int_equal(4, StringCopy("GHIJ", e, buf_size)); assert_int_equal(4, StringCopy("KLMNO", f, buf_size)); assert_int_equal(4, StringCopy("PQRSTU", g, buf_size)); assert_int_equal(4, StringCopy("VWXYZ 1", h, buf_size)); assert_string_equal(a, ""); assert_string_equal(b, "A"); assert_string_equal(c, "BC"); assert_string_equal(d, "DEF"); assert_string_equal(e, "GHI"); assert_string_equal(f, "KLM"); assert_string_equal(g, "PQR"); assert_string_equal(h, "VWX"); assert_int_equal(1, StringCopy(d, a, 1)); // Truncated, 1 NUL byte written assert_int_equal(2, StringCopy(d, b, 2)); // Truncated, 2 bytes written assert_int_equal(3, StringCopy(d, c, 3)); // Truncated, 3 bytes written // src == dst isn't allowed, have to skip d assert_int_equal(3, StringCopy(d, e, buf_size)); assert_int_equal(3, StringCopy(d, f, buf_size)); assert_int_equal(3, StringCopy(d, g, buf_size)); assert_int_equal(3, StringCopy(d, h, buf_size)); assert_string_equal(a, ""); assert_string_equal(b, "D"); assert_string_equal(c, "DE"); assert_string_equal(d, "DEF"); assert_string_equal(e, "DEF"); assert_string_equal(f, "DEF"); assert_string_equal(g, "DEF"); assert_string_equal(h, "DEF"); // Let's also try a longer string: int length = strlen(lo_alphabet); char buf[1024]; assert_int_equal(length, StringCopy(lo_alphabet, buf, 1024)); assert_string_equal(buf, lo_alphabet); // Let's check that we haven't corrupted the stack somehow: assert_true(non_terminated[0] == '3'); assert_true(non_terminated[1] == '4'); assert_true(non_terminated[2] == '5'); assert_string_equal(d, "DEF"); assert_int_equal(3, StringCopy(non_terminated, d, 3)); assert_string_equal(d, "34"); // Let's check that we don't write out of specified maximum char ones[2] = {'1', '1'}; assert_int_equal(0, StringCopy("", ones, 1)); assert_true(ones[0] == '\0'); assert_true(ones[1] == '1'); } static void test_stringscanfcapped(void) { char buf[20]; char sp[30]; strcpy(sp,""); StringNotMatchingSetCapped(sp,20,"\n",buf); assert_string_equal(buf, ""); strcpy(sp,"\n"); StringNotMatchingSetCapped(sp,20,"\n",buf); assert_string_equal(buf, ""); strcpy(sp,"\n2345678901234567890abcdefghi"); StringNotMatchingSetCapped(sp,20,"\n",buf); assert_string_equal(buf, ""); strcpy(sp,"12345678901234567890abcdefghi"); StringNotMatchingSetCapped(sp,20,"\n",buf); assert_string_equal(buf, "1234567890123456789"); strcpy(sp,"12345678901234567890abcde\nghi"); StringNotMatchingSetCapped(sp,20,"\n",buf); assert_string_equal(buf, "1234567890123456789"); strcpy(sp,"123456789012345\n7890abcdefghi"); StringNotMatchingSetCapped(sp,20,"\n",buf); assert_string_equal(buf, "123456789012345"); } static void test_PathAppend(void) { char dst[10]; bool ret; { /* fits */ dst[0] = '\0'; ret = PathAppend(dst, sizeof(dst), "blah", '/'); assert_string_equal(dst, "/blah"); assert_true(ret); } { /* SAME, but string already has separator */ strcpy(dst, "/"); ret = PathAppend(dst, sizeof(dst), "blah", '/'); assert_string_equal(dst, "/blah"); assert_true(ret); } { /* trailing separator */ dst[0] = '\0'; ret = PathAppend(dst, sizeof(dst), "blah/", '/'); assert_string_equal(dst, "/blah/"); assert_true(ret); } { /* SAME, but string already has separator ahead */ strcpy(dst, "/"); ret = PathAppend(dst, sizeof(dst), "blah/", '/'); assert_string_equal(dst, "/blah/"); assert_true(ret); } { /* barely fits */ dst[0] = '\0'; ret = PathAppend(dst, 6, "blah", '/'); assert_string_equal(dst, "/blah"); assert_true(ret); } { /* SAME, but string already has separator */ strcpy(dst, "/"); ret = PathAppend(dst, 6, "blah", '/'); assert_string_equal(dst, "/blah"); assert_true(ret); } { /* barely not fits (off by one), do nothing */ dst[0] = '\0'; ret = PathAppend(dst, 5, "blah", '/'); assert_string_equal(dst, ""); assert_false(ret); } { /* SAME, but string already has separator */ strcpy(dst, "/"); ret = PathAppend(dst, 5, "blah", '/'); assert_string_equal(dst, "/"); assert_false(ret); } { /* overflow, do nothing */ dst[0] = '\0'; ret = PathAppend(dst, 2, "blah", '/'); assert_string_equal(dst, ""); assert_false(ret); } { /* SAME, but string already has separator */ strcpy(dst, "/"); ret = PathAppend(dst, 2, "blah", '/'); assert_string_equal(dst, "/"); assert_false(ret); } } static void test_StrCat(void) { char dst[10]; size_t dst_len; { dst[0] = '\0'; dst_len = 0; StrCat(dst, sizeof(dst), &dst_len, "blah", 0); assert_string_equal(dst, "blah"); assert_int_equal(dst_len, 4); StrCat(dst, sizeof(dst), &dst_len, "", 0); assert_string_equal(dst, "blah"); assert_int_equal(dst_len, 4); StrCat(dst, sizeof(dst), &dst_len, " ", 0); assert_string_equal(dst, "blah "); assert_int_equal(dst_len, 5); StrCat(dst, sizeof(dst), &dst_len, "blue", 0); assert_string_equal(dst, "blah blue"); assert_int_equal(dst_len, 9); /* Append one OVERFLOWing character. */ StrCat(dst, sizeof(dst), &dst_len, "1", 0); /* It should protect against overflow. */ assert_string_equal(dst, "blah blue"); /* But the length indicates the needed length. */ assert_int_equal(dst_len, 10); } { /* The string to append is not '\0'-terminated */ const char *src = "blah blue"; dst[0] = '\0'; dst_len = 0; StrCat(dst, sizeof(dst), &dst_len, src, 4); assert_string_equal(dst, "blah"); assert_int_equal(dst_len, 4); StrCat(dst, sizeof(dst), &dst_len, src, 4); assert_string_equal(dst, "blahblah"); assert_int_equal(dst_len, 8); StrCat(dst, sizeof(dst), &dst_len, src, 2); assert_string_equal(dst, "blahblahb"); /* overflow */ assert_int_equal(dst_len, 10); } { dst[0] = '\0'; dst_len = 0; StrCat(dst, 4, &dst_len, "blah", 0); assert_string_equal(dst, "bla"); /* Overflow so dst_len indicates the needed length. */ assert_int_equal(dst_len, 4); StrCat(dst, 4, &dst_len, "", 0); assert_string_equal(dst, "bla"); assert_int_equal(dst_len, 4); StrCat(dst, 4, &dst_len, "blue", 0); assert_string_equal(dst, "bla"); assert_int_equal(dst_len, 8); } { /* SAME but pass NULL as dst_len */ dst[0] = '\0'; StrCat(dst, 4, NULL, "blah", 0); assert_string_equal(dst, "bla"); StrCat(dst, 4, NULL, "", 0); assert_string_equal(dst, "bla"); StrCat(dst, 4, NULL, "blue", 0); assert_string_equal(dst, "bla"); } { /* Do not reset dst but reset only dst_len. */ dst_len = 0; StrCat(dst, sizeof(dst), &dst_len, "1", 0); assert_string_equal(dst, "1"); assert_int_equal(dst_len, 1); } } static void test_StrCatDelim(void) { char dst[10]; size_t dst_len; { /* Simple appends, we don't care about truncation. */ dst[0] = '\0'; StrCatDelim(dst, sizeof(dst), NULL, "blah", ','); StrCatDelim(dst, sizeof(dst), NULL, "blah", ','); assert_string_equal(dst, "blah,blah"); StrCatDelim(dst, sizeof(dst), NULL, "blah", ','); assert_string_equal(dst, "blah,blah"); StrCatDelim(dst, sizeof(dst), NULL, "1", ','); assert_string_equal(dst, "blah,blah"); } { /* SAME, but check truncation. */ dst[0] = '\0'; dst_len = 0; StrCatDelim(dst, sizeof(dst), &dst_len, "blah", ','); assert_int_equal(dst_len, 4); StrCatDelim(dst, sizeof(dst), &dst_len, "blah", ','); assert_string_equal(dst, "blah,blah"); assert_int_equal(dst_len, 9); StrCatDelim(dst, sizeof(dst), &dst_len, "blah", ','); assert_string_equal(dst, "blah,blah"); assert_int_equal(dst_len, 14); /* needed length */ StrCatDelim(dst, sizeof(dst), &dst_len, "1", ','); assert_string_equal(dst, "blah,blah"); assert_int_equal(dst_len, 16); } { /* Only the comma fits. */ strcpy(dst, "12345678"); StrCatDelim(dst, sizeof(dst), NULL, "1", ','); assert_string_equal(dst, "12345678"); } { /* SAME, but check truncation. */ strcpy(dst, "12345678"); dst_len = 8; StrCatDelim(dst, sizeof(dst), &dst_len, "1", ','); assert_string_equal(dst, "12345678"); assert_int_equal(dst_len, 10); /* 10 is the needed length */ } } static void test_StringMatchesOption(void) { assert_true(StringMatchesOption("-i", "--info", "-i")); assert_false(StringMatchesOption("-i", "--info", "-I")); assert_true(StringMatchesOption("--info", "--inform", "-I")); assert_false(StringMatchesOption("--inform-me", "--info", "-I")); assert_true(StringMatchesOption("--client", "--clients", "-C")); assert_true(StringMatchesOption("--hub", "--hubs", "-H")); assert_true(StringMatchesOption("--host", "--hosts", "-H")); } static void test_StringFind(void) { static const char *const str = "Hello CFEngine"; const size_t len = strlen(str); assert_int_equal(StringFind(str, "C", 0, len), 6l); assert_int_equal(StringFind(str, "C", 7, len), -1l); assert_int_equal(StringFind(str, "C", 6, len), 6l); assert_int_equal(StringFind(str, "C", 6, 6), -1l); assert_int_equal(StringFind(str, "C", 6, 7), 6l); assert_int_equal(StringFind(str, "FC", 0, len), -1l); assert_int_equal(StringFind(str, "CF", 0, len), 6l); assert_int_equal(StringFind(str, "H", 0, 0), -1l); assert_int_equal(StringFind(str, "H", 0, 1), 0l); assert_int_equal(StringFind(str, "e", len - 1, len), len - 1l); assert_int_equal(StringFind(str, "e", len - 1, len - 1), -1l); assert_int_equal(StringFind(str, "Hello CFEngine in the house", 0, 1), -1l); assert_int_equal(StringFind(str, "CF", 0, 9999), 6l); assert_int_equal(StringFind(str, "CF", 8888, 9999), -1l); assert_int_equal(StringFind(str, "CF", 8888, 0), -1l); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_get_token), unit_test(test_mix_case_tolower), unit_test(test_empty_tolower), unit_test(test_weird_chars_tolower), unit_test(test_alphabet_tolower), unit_test(test_hi_alphabet_tolower), unit_test(test_inplace_tolower), unit_test(test_mix_case_toupper), unit_test(test_empty_toupper), unit_test(test_weird_chars_toupper), unit_test(test_alphabet_toupper), unit_test(test_hi_alphabet_toupper), unit_test(test_inplace_toupper), unit_test(test_replace_empty_pattern), unit_test(test_replace_empty_replacement), unit_test(test_long_search), unit_test(test_replace_eq_size), unit_test(test_replace_more_size), unit_test(test_replace_less_size), unit_test(test_no_replace), unit_test(test_string_replace_empty_replacement), unit_test(test_string_replace_eq_size), unit_test(test_string_replace_buf_too_small), unit_test(test_string_replace_smaller), unit_test(test_string_replace_none), unit_test(test_string_replace_many_percentages), unit_test(test_string_replace_n), unit_test(test_concatenate), unit_test(test_substring_overshoot), unit_test(test_substring_positive), unit_test(test_substring_negative_length), unit_test(test_substring_negative), unit_test(test_substring_evil), unit_test(test_string_to_long), unit_test(test_string_to_long_default), unit_test(test_string_to_long_errors), unit_test(test_string_to_long_unsafe), unit_test(test_string_to_long_compatibility), unit_test(test_string_to_ulong), unit_test(test_string_to_ulong_default), unit_test(test_string_to_ulong_errors), unit_test(test_string_to_int64), unit_test(test_string_from_long), unit_test(test_string_to_double), unit_test(test_string_from_double), unit_test(test_string_decimal_to_long), unit_test(test_string_decimal_to_long_errors), unit_test(test_safe_compare), unit_test(test_safe_equal), unit_test(test_safe_compare_ignore_case), unit_test(test_safe_equal_ignore_case), unit_test(test_safe_equal_n), unit_test(test_is_string_in_array), unit_test(test_encode_base64), unit_test(test_escape_char_copy), unit_test(test_chop_no_spaces), unit_test(test_chop_single_space), unit_test(test_chop_two_spaces), unit_test(test_chop_empty), unit_test(test_chop_empty_single_space), unit_test(test_chop_empty_two_spaces), unit_test(test_trim_crlf), unit_test(test_close_hole), unit_test(test_ends_with), unit_test(test_stringformat), unit_test(test_stringvformat), unit_test(test_string_copy), unit_test(test_stringscanfcapped), unit_test(test_PathAppend), unit_test(test_StrCat), unit_test(test_StrCatDelim), unit_test(test_StringMatchesOption), unit_test(test_StringFind), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/string_sequence_test.c0000644000000000000000000000762715010704254023702 0ustar00rootroot00000000000000#include #include #include #include static void test_StringJoin(void) { const char *argv[] = { "one", "two", "three" }; const int argc = sizeof(argv) / sizeof(argv[0]); Seq *seq = SeqFromArgv(argc, argv); char *actual = StringJoin(seq, NULL); assert_string_equal(actual, "onetwothree"); free(actual); actual = StringJoin(seq, ""); assert_string_equal(actual, "onetwothree"); free(actual); actual = StringJoin(seq, ", "); assert_string_equal(actual, "one, two, three"); free(actual); SeqDestroy(seq); seq = SeqNew(0, NULL); actual = StringJoin(seq, NULL); assert_string_equal(actual, ""); free(actual); actual = StringJoin(seq, ""); assert_string_equal(actual, ""); free(actual); actual = StringJoin(seq, ", "); assert_string_equal(actual, ""); free(actual); SeqDestroy(seq); } static void test_StringSplit(void) { { Seq *const seq = StringSplit("foo", ","); assert_int_equal(SeqLength(seq), 1); assert_string_equal(SeqAt(seq, 0), "foo"); SeqDestroy(seq); } { Seq *const seq = StringSplit("foo,bar", ","); assert_int_equal(SeqLength(seq), 2); assert_string_equal(SeqAt(seq, 0), "foo"); assert_string_equal(SeqAt(seq, 1), "bar"); SeqDestroy(seq); } { Seq *const seq = StringSplit("foo,bar,baz", ","); assert_int_equal(SeqLength(seq), 3); assert_string_equal(SeqAt(seq, 0), "foo"); assert_string_equal(SeqAt(seq, 1), "bar"); assert_string_equal(SeqAt(seq, 2), "baz"); SeqDestroy(seq); } { Seq *const seq = StringSplit("foo,bar,baz,", ","); assert_int_equal(SeqLength(seq), 4); assert_string_equal(SeqAt(seq, 0), "foo"); assert_string_equal(SeqAt(seq, 1), "bar"); assert_string_equal(SeqAt(seq, 2), "baz"); assert_string_equal(SeqAt(seq, 3), ""); SeqDestroy(seq); } { Seq *const seq = StringSplit("", ","); assert_int_equal(SeqLength(seq), 1); assert_string_equal(SeqAt(seq, 0), ""); SeqDestroy(seq); } { Seq *const seq = StringSplit("/etc/os-release", "/"); assert_int_equal(SeqLength(seq), 3); assert_string_equal(SeqAt(seq, 0), ""); assert_string_equal(SeqAt(seq, 1), "etc"); assert_string_equal(SeqAt(seq, 2), "os-release"); SeqDestroy(seq); } { Seq *const seq = StringSplit(".ssh/authorized_keys", "/"); assert_int_equal(SeqLength(seq), 2); assert_string_equal(SeqAt(seq, 0), ".ssh"); assert_string_equal(SeqAt(seq, 1), "authorized_keys"); SeqDestroy(seq); } { Seq *const seq = StringSplit("C:\\Program Files\\Cfengine/bin/cf-agent.exe", "\\/"); assert_int_equal(SeqLength(seq), 5); assert_string_equal(SeqAt(seq, 0), "C:"); assert_string_equal(SeqAt(seq, 2), "Cfengine"); assert_string_equal(SeqAt(seq, 4), "cf-agent.exe"); SeqDestroy(seq); } { Seq *const seq = StringSplit("/foo//bar\\/baz\\", "\\/"); assert_int_equal(SeqLength(seq), 7); assert_string_equal(SeqAt(seq, 0), ""); assert_string_equal(SeqAt(seq, 1), "foo"); assert_string_equal(SeqAt(seq, 2), ""); assert_string_equal(SeqAt(seq, 3), "bar"); assert_string_equal(SeqAt(seq, 4), ""); assert_string_equal(SeqAt(seq, 5), "baz"); assert_string_equal(SeqAt(seq, 6), ""); SeqDestroy(seq); } { Seq *const seq = StringSplit("foo", ""); assert_int_equal(SeqLength(seq), 1); assert_string_equal(SeqAt(seq, 0), "foo"); SeqDestroy(seq); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_StringJoin), unit_test(test_StringSplit), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/Makefile.am0000644000000000000000000001501615010704254021324 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Just recursively include in dist tarball all data we need for unit tests EXTRA_DIST = data AM_CPPFLAGS = $(CORE_CPPFLAGS) \ $(ENTERPRISE_CFLAGS) \ -I$(srcdir)/../../libutils \ -DTESTDATADIR='"$(srcdir)/data"' LDADD = ../../libutils/libutils.la libtest.la # automake does not support "maude_LIBS" variables. We can only alter # the generic LIBS one. In case the functions are mocked in the test # implementation, then we are pretty sure that they will be overriden by # our local implementation. So we include *everything*... LIBS = $(CORE_LIBS) AM_LDFLAGS = $(CORE_LDFLAGS) AM_CFLAGS = $(CORE_CFLAGS) $(PTHREAD_CFLAGS) check_LTLIBRARIES = libtest.la libtest_la_SOURCES = cmockery.c cmockery.h schema.h test.c test.h \ ../../libutils/alloc.c \ ../../libutils/known_dirs.c \ ../../libutils/map.c \ ../../libutils/array_map.c \ ../../libutils/hash_map.c if WITH_OPENSSL libtest_la_SOURCES += \ ../../libutils/hash.c endif libtest_la_LIBADD = ../../libcompat/libcompat.la $(PCRE_LIBS) $(OPENSSL_LIBS) $(SYSTEMD_LOGGING_LIBS) $(LIBYAML_LIBS) check_LTLIBRARIES += libstr.la libstr_la_SOURCES = \ ../../libutils/buffer.c \ ../../libutils/logging.c \ ../../libutils/misc_lib.c \ ../../libutils/sequence.c \ ../../libutils/string_lib.c \ ../../libutils/writer.c libstr_la_LIBADD = libtest.la if WITH_OPENSSL libstr_la_SOURCES += \ ../../libutils/encode.c endif if WITH_PCRE2 libstr_la_SOURCES += \ ../../libutils/regex.c endif check_PROGRAMS = \ cleanup_test \ condition_macros_test \ csv_writer_test \ set_test \ csv_parser_test \ env_file_test \ alloc_test \ string_writer_test \ file_writer_test \ xml_writer_test \ sequence_test \ json_test \ misc_lib_test \ string_lib_test \ thread_test \ file_lib_test \ file_lock_test \ map_test \ path_test \ logging_timestamp_test \ refcount_test \ list_test \ buffer_test \ ipaddress_test \ rb-tree-test \ queue_test \ stack_test \ threaded_queue_test \ threaded_deque_test \ threaded_stack_test \ version_comparison_test \ ring_buffer_test \ libcompat_test \ definitions_test \ glob_lib_test \ string_sequence_test if WITH_PCRE2 check_PROGRAMS += \ regex_test endif if WITH_OPENSSL check_PROGRAMS += \ hash_test endif TESTS = $(check_PROGRAMS) # # OS X uses real system calls instead of our stubs unless this option is used # TESTS_ENVIRONMENT = DYLD_FORCE_FLAT_NAMESPACE=yes cleanup_test_SOURCES = cleanup_test.c csv_writer_test_SOURCES = csv_writer_test.c ../../libutils/csv_writer.c \ ../../libutils/cleanup.c csv_writer_test_LDADD = libtest.la libstr.la xml_writer_test_SOURCES = xml_writer_test.c \ ../../libutils/xml_writer.c \ ../../libutils/cleanup.c xml_writer_test_LDADD = libtest.la libstr.la list_test_SOURCES = list_test.c refcount_test_SOURCES = refcount_test.c ../../libutils/refcount.c buffer_test_SOURCES = buffer_test.c ../../libutils/buffer.c # Workaround for object file basename conflicts, search the web for # "automake created with both libtool and without" buffer_test_CPPFLAGS = $(AM_CPPFLAGS) csv_parser_test_SOURCES = csv_parser_test.c ../../libutils/csv_parser.c csv_parser_test_LDADD = libtest.la ../../libutils/libutils.la #file_writer_test_CPPFLAGS = -I$(top_srcdir)/libutils file_writer_test_SOURCES = file_writer_test.c # ENABLE_COVERAGE is set in top-level configure.ac if !ENABLE_COVERAGE file_writer_test_SOURCES += gcov-stub.c endif CLEANFILES = *.gcno *.gcda cfengine-enterprise.so clean-local: rm -rf test_glob_file_list_?????? file_lib_test_SOURCES = file_lib_test.c \ ../../libutils/file_lib.c \ ../../libutils/logging.c \ ../../libutils/misc_lib.c \ ../../libutils/path.c \ ../../libutils/string_lib.c \ ../../libutils/sequence.c \ ../../libutils/set.c \ ../../libutils/buffer.c \ ../../libutils/json.c \ ../../libutils/json-yaml.c \ ../../libutils/unix_dir.c \ ../../libutils/cleanup.c \ ../../libutils/writer.c if WITH_PCRE2 file_lib_test_SOURCES += \ ../../libutils/regex.c endif file_lib_test_LDADD = libtest.la file_lib_test_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_SYMLINK_ATOMICITY ipaddress_test_SOURCES = ipaddress_test.c \ ../../libutils/file_lib.c \ ../../libutils/logging.c \ ../../libutils/misc_lib.c \ ../../libutils/path.c \ ../../libutils/string_lib.c \ ../../libutils/sequence.c \ ../../libutils/set.c \ ../../libutils/buffer.c \ ../../libutils/json.c \ ../../libutils/json-yaml.c \ ../../libutils/unix_dir.c \ ../../libutils/cleanup.c \ ../../libutils/writer.c if WITH_PCRE2 ipaddress_test_SOURCES += \ ../../libutils/regex.c endif ipaddress_test_LDADD = libtest.la ipaddress_test_CPPFLAGS = $(AM_CPPFLAGS) logging_timestamp_test_SOURCES = logging_timestamp_test.c \ ../../libutils/logging.h logging_timestamp_test_LDADD = libtest.la ../../libutils/libutils.la hash_test_SOURCES = hash_test.c hash_test_LDADD = ../../libutils/libutils.la libtest.la libcompat_test_CPPFLAGS = -I$(top_srcdir)/libcompat -I$(top_srcdir)/libutils libcompat_test_SOURCES = libcompat_test.c # Silence some warnings about generated comparisions always being false: # (The test generates some comparisons which compare an int to something # bigger than INT_MAX) misc_lib_test_CFLAGS = $(AM_CFLAGS) $(NO_TAUTOLOGICAL_CC_OPTION) queue_test_SOURCES = queue_test.c stack_test_SOURCES = stack_test.c threaded_queue_test_SOURCES = threaded_queue_test.c threaded_deque_test_SOURCES = threaded_deque_test.c threaded_stack_test_SOURCES = threaded_stack_test.c file_lock_test_SOURCES = file_lock_test.c file_lock_test_LDADD = ../../libutils/libutils.la glob_lib_test_SOURCES = glob_lib_test.c glob_lib_test_LDADD = ../../libutils/libutils.la libtest.la string_sequence_test_SOURCES = string_sequence_test.c string_sequence_test_LDADD = ../../libutils/libutils.la libtest.la cfengine-3.24.2/libntech/tests/unit/csv_parser_test.c0000644000000000000000000002240015010704254022635 0ustar00rootroot00000000000000#include #include #include #include #include static void test_new_csv_reader_empty_string() { char line[]=",Null is not empty string,,\"\",\"\""; Seq *list = SeqParseCsvString(line); assert_true(list != NULL); assert_int_equal(list->length, 5); assert_true(list->data[0] != NULL); assert_true(list->data[1] != NULL); assert_true(list->data[2] != NULL); assert_true(list->data[3] != NULL); assert_true(list->data[4] != NULL); assert_string_equal(list->data[0], ""); assert_string_equal(list->data[1], "Null is not empty string"); assert_string_equal(list->data[2], ""); assert_string_equal(list->data[3], ""); assert_string_equal(list->data[4], ""); assert_string_equal(list->data[2], list->data[3]); SeqDestroy(list); } static void test_new_csv_reader_basic() { Seq *list = NULL; char *lines[5] = { "aaaa,bbb,ccccc", "\"aaaa\",\"bbb\",\"ccccc\"", "\"aaaa\",bbb,\"ccccc\"", "aaaa,\"bbb\",ccccc", ",\"bbb\",ccccc", }; for (int i=0; i<5; i++) { list = SeqParseCsvString(lines[i]); assert_int_equal(list->length, 3); assert_string_equal(list->data[2], "ccccc"); if (list != NULL) { SeqDestroy(list); } else { assert_true(false); } } } static void test_new_csv_reader() { Seq *list = NULL; char line[]=" Type ,\"walo1\", \"walo2\" , \"wal,o \"\" 3\", \" ab,cd \", walo solo ,, \"walo\""; list = SeqParseCsvString(line); assert_int_equal(list->length, 8); assert_string_equal(list->data[3], "wal,o \" 3"); assert_string_equal(list->data[6], ""); assert_string_equal(list->data[7], "walo"); if (list != NULL) { SeqDestroy(list); } else { assert_true(false); } } static void test_new_csv_reader_lfln() { Seq *list = NULL; char line[]=" Type ,\"walo1\", \"walo2\" , \"wa\r\nl,o\n \"\"\r 3\", \" ab,cd \", walo solo ,, \"walo\" "; list = SeqParseCsvString(line); assert_int_equal(list->length, 8); assert_string_equal(list->data[3], "wa\r\nl,o\n \"\r 3"); if (list != NULL) { SeqDestroy(list); } else { assert_true(false); } } static void test_new_csv_reader_lfln_at_end() { Seq *list = NULL; char line[]=" Type ,\"walo1\", \"walo2\" , \"wal\r\n,o \"\" 3\", \" ab,cd \", walo solo , , \"walo\" \r\n "; list = SeqParseCsvString(line); assert_int_equal(list->length, 8); assert_string_equal(list->data[3], "wal\r\n,o \" 3"); assert_string_equal(list->data[6], " "); assert_string_equal(list->data[7], "walo"); if (list != NULL) { SeqDestroy(list); } else { assert_true(false); } } static void test_new_csv_reader_lfln_at_end2() { Seq *list = NULL; char line[]=" Type ,\"walo1\", \"walo2\" , \"wal\r\n,o \"\" 3\", \" ab,cd \", walo solo , ,walo\r\n"; list = SeqParseCsvString(line); assert_int_equal(list->length, 8); assert_string_equal(list->data[7], "walo"); if (list != NULL) { SeqDestroy(list); } else { assert_true(false); } } static void test_new_csv_reader_lfln_at_end3() { Seq *list = NULL; char line[]=" Type ,\"walo1\", \"walo2\" , \"wal\r\n,o \"\" 3\", \" ab,cd \", walo solo , , \r\n"; list = SeqParseCsvString(line); assert_int_equal(list->length, 8); assert_string_equal(list->data[7], " "); if (list != NULL) { SeqDestroy(list); } else { assert_true(false); } } static void test_get_next_line() { FILE *fp = fopen("./data/csv_file.csv", "r"); assert_true(fp); { char *line = GetCsvLineNext(fp); assert_true(line); assert_string_equal(line, "field_1, field_2\r\n"); Seq *list = SeqParseCsvString(line); assert_true(list); assert_int_equal(SeqLength(list), 2); assert_string_equal(SeqAt(list, 0), "field_1"); assert_string_equal(SeqAt(list, 1), " field_2"); SeqDestroy(list); free(line); } { char *line = GetCsvLineNext(fp); assert_true(line); assert_string_equal(line, "field_1, \"value1 \nvalue2 \nvalue3\"\r\n"); Seq *list = SeqParseCsvString(line); assert_true(list); assert_int_equal(SeqLength(list), 2); assert_string_equal(SeqAt(list, 0), "field_1"); assert_string_equal(SeqAt(list, 1), "value1 \nvalue2 \nvalue3"); SeqDestroy(list); free(line); } { char *line = GetCsvLineNext(fp); assert_true(line); assert_string_equal(line, "field_1, \"field,2\"\r\n"); Seq *list = SeqParseCsvString(line); assert_true(list); assert_int_equal(SeqLength(list), 2); assert_string_equal(SeqAt(list, 0), "field_1"); assert_string_equal(SeqAt(list, 1), "field,2"); SeqDestroy(list); free(line); } fclose(fp); } static void test_get_next_line_edge_cases() { // Generated file in python: // with open("tests/unit/data/csv_file_edge_cases.csv", "w") as f: // f.write("Empty,Empty,One double quote,Two double quotes,LF,CRLF,CRLFCRLF,Empty\r\n") // f.write('"",,"""","""""","\n","\r\n","\r\n\r\n",\r\n') FILE *fp = fopen("./data/csv_file_edge_cases.csv", "r"); assert_true(fp); { char *header_string = GetCsvLineNext(fp); char *data_string = GetCsvLineNext(fp); assert_true(header_string != NULL); assert_true(data_string != NULL); assert_string_equal(header_string, "Empty,Empty,One double quote,Two double quotes,LF,CRLF,CRLFCRLF,Empty\r\n"); assert_string_equal(data_string, "\"\",,\"\"\"\",\"\"\"\"\"\",\"\n\",\"\r\n\",\"\r\n\r\n\",\r\n"); Seq *header_list = SeqParseCsvString(header_string); Seq *data_list = SeqParseCsvString(data_string); assert_true(header_list != NULL); assert_true(data_list != NULL); assert_int_equal(SeqLength(header_list), 8); assert_int_equal(SeqLength(data_list), 8); assert_string_equal(SeqAt(header_list, 0), "Empty"); assert_string_equal(SeqAt(data_list, 0), ""); assert_string_equal(SeqAt(header_list, 1), "Empty"); assert_string_equal(SeqAt(data_list, 1), ""); assert_string_equal(SeqAt(header_list, 2), "One double quote"); assert_string_equal(SeqAt(data_list, 2), "\""); assert_string_equal(SeqAt(header_list, 3), "Two double quotes"); assert_string_equal(SeqAt(data_list, 3), "\"\""); assert_string_equal(SeqAt(header_list, 4), "LF"); assert_string_equal(SeqAt(data_list, 4), "\n"); assert_string_equal(SeqAt(header_list, 5), "CRLF"); assert_string_equal(SeqAt(data_list, 5), "\r\n"); assert_string_equal(SeqAt(header_list, 6), "CRLFCRLF"); assert_string_equal(SeqAt(data_list, 6), "\r\n\r\n"); assert_string_equal(SeqAt(header_list, 7), "Empty"); assert_string_equal(SeqAt(data_list, 7), ""); SeqDestroy(header_list); SeqDestroy(data_list); free(header_string); free(data_string); } fclose(fp); } /* A memory corruption (off-by-one write) used to occur with this string, * detectable by valgrind and crashing some non-linux platforms. */ static void test_new_csv_reader_zd3151_ENT3023() { const char *input = "default.cfe_autorun_inventory_proc.cpuinfo_array[337][0"; Seq *list = SeqParseCsvString(input); assert_int_equal(SeqLength(list), 1); assert_string_equal(input, SeqAt(list, 0)); SeqDestroy(list); } static void test_new_csv_reader_carriage_return() { const char *inputs[] = { "field_1,stuff,values are here\r\n", "field_2,empty,\r\n", "field_3,more stuff,more values are here\r\n", "field_4,,\r\n", }; // First entry Seq *list = SeqParseCsvString(inputs[0]); assert_int_equal(SeqLength(list), 3); assert_string_equal(SeqAt(list, 2), "values are here"); SeqDestroy(list); // Second entry list = SeqParseCsvString(inputs[1]); assert_int_equal(SeqLength(list), 3); assert_string_equal(SeqAt(list, 2), ""); SeqDestroy(list); // Third entry list = SeqParseCsvString(inputs[2]); assert_int_equal(SeqLength(list), 3); assert_string_equal(SeqAt(list, 2), "more values are here"); SeqDestroy(list); // Fourth entry list = SeqParseCsvString(inputs[3]); assert_int_equal(SeqLength(list), 3); assert_string_equal(SeqAt(list, 2), ""); SeqDestroy(list); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_new_csv_reader_empty_string), unit_test(test_new_csv_reader_basic), unit_test(test_new_csv_reader), unit_test(test_new_csv_reader_lfln), unit_test(test_new_csv_reader_lfln_at_end), unit_test(test_new_csv_reader_lfln_at_end2), unit_test(test_new_csv_reader_lfln_at_end3), unit_test(test_get_next_line), unit_test(test_get_next_line_edge_cases), unit_test(test_new_csv_reader_zd3151_ENT3023), unit_test(test_new_csv_reader_carriage_return), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/definitions_test.c0000644000000000000000000000235615010704254023011 0ustar00rootroot00000000000000#include #include #include static void test_metric_prefixes(void) { uint32_t size32; size32 = KIBIBYTE(0); assert_int_equal(size32, 0UL); size32 = KIBIBYTE(1); assert_int_equal(size32, 1024UL); size32 = KIBIBYTE(2); assert_int_equal(size32, 2048UL); size32 = MEBIBYTE(0); assert_int_equal(size32, 0UL); size32 = MEBIBYTE(1); assert_int_equal(size32, 1048576UL); size32 = MEBIBYTE(2); assert_int_equal(size32, 2097152UL); uint64_t size64; size64 = GIBIBYTE(0); assert_int_equal(size64, 0ULL); size64 = GIBIBYTE(1); assert_int_equal(size64, 1073741824ULL); size64 = GIBIBYTE(2); assert_int_equal(size64, 2147483648ULL); size64 = TEBIBYTE(0); assert_int_equal(size64, 0ULL); size64 = TEBIBYTE(1); assert_int_equal(size64, 1099511627776ULL); size64 = TEBIBYTE(2); assert_int_equal(size64, 2199023255552ULL); assert_int_equal(KIBIBYTE(1024), MEBIBYTE(1)); assert_int_equal(MEBIBYTE(1024), GIBIBYTE(1)); assert_int_equal(GIBIBYTE(1024), TEBIBYTE(1)); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_metric_prefixes) }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/stack_test.c0000644000000000000000000001013015010704254021570 0ustar00rootroot00000000000000#include "test.h" #include #include static void test_push_pop_top(void) { Stack *stack = StackNew(0, free); StackPush(stack, xstrdup("1")); assert_string_equal("1", StackTop(stack)); StackPush(stack, xstrdup("2")); assert_string_equal("2", StackTop(stack)); StackPush(stack, xstrdup("3")); assert_string_equal("3", StackTop(stack)); char *str1 = StackPop(stack); assert_string_equal("2", StackTop(stack)); char *str2 = StackPop(stack); assert_string_equal("1", StackTop(stack)); char *str3 = StackPop(stack); assert_int_equal(NULL, StackTop(stack)); assert_int_equal(strcmp(str1, "3"), 0); assert_int_equal(strcmp(str2, "2"), 0); assert_int_equal(strcmp(str3, "1"), 0); free(str1); free(str2); free(str3); StackDestroy(stack); } static void test_pop_empty_and_push_null(void) { Stack *stack = StackNew(1, NULL); assert(StackIsEmpty(stack)); void *i_am_null = StackPop(stack); assert(i_am_null == NULL); StackPush(stack, i_am_null); assert(StackPop(stack) == NULL); StackDestroy(stack); } static void test_copy(void) { Stack *stack = StackNew(4, free); StackPush(stack, xstrdup("1")); StackPush(stack, xstrdup("2")); StackPush(stack, xstrdup("3")); Stack *new_stack = StackCopy(stack); assert(new_stack != NULL); assert_int_equal(StackCount(stack), StackCount(new_stack)); assert_int_equal(StackCapacity(stack), StackCapacity(new_stack)); char *old_str1 = StackPop(stack); char *new_str1 = StackPop(new_stack); char *old_str2 = StackPop(stack); char *new_str2 = StackPop(new_stack); char *old_str3 = StackPop(stack); char *new_str3 = StackPop(new_stack); assert(old_str1 == new_str1); assert(old_str2 == new_str2); assert(old_str3 == new_str3); free(old_str1); free(old_str2); free(old_str3); StackSoftDestroy(stack); // Tests expanding the copied stack StackPush(new_stack, xstrdup("1")); StackPush(new_stack, xstrdup("2")); StackPush(new_stack, xstrdup("3")); StackPush(new_stack, xstrdup("4")); StackPush(new_stack, xstrdup("5")); assert_int_equal(StackCount(new_stack), 5); assert_int_equal(StackCapacity(new_stack), 8); new_str1 = StackPop(new_stack); new_str2 = StackPop(new_stack); new_str3 = StackPop(new_stack); char *new_str4 = StackPop(new_stack); char *new_str5 = StackPop(new_stack); assert_int_equal(strcmp(new_str1, "5"), 0); assert_int_equal(strcmp(new_str2, "4"), 0); assert_int_equal(strcmp(new_str3, "3"), 0); assert_int_equal(strcmp(new_str4, "2"), 0); assert_int_equal(strcmp(new_str5, "1"), 0); free(new_str1); free(new_str2); free(new_str3); free(new_str4); free(new_str5); StackDestroy(new_stack); } static void test_push_report_count(void) { Stack *stack = StackNew(0, free); size_t size1 = StackPushReportCount(stack, xstrdup("1")); size_t size2 = StackPushReportCount(stack, xstrdup("2")); size_t size3 = StackPushReportCount(stack, xstrdup("3")); size_t size4 = StackPushReportCount(stack, xstrdup("4")); assert_int_equal(size1, 1); assert_int_equal(size2, 2); assert_int_equal(size3, 3); assert_int_equal(size4, 4); StackDestroy(stack); } static void test_expand(void) { Stack *stack = StackNew(1, free); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); StackPush(stack, xstrdup("spam")); assert_int_equal(StackCount(stack), 9); assert_int_equal(StackCapacity(stack), 16); StackDestroy(stack); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_push_pop_top), unit_test(test_pop_empty_and_push_null), unit_test(test_copy), unit_test(test_push_report_count), unit_test(test_expand), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/set_test.c0000644000000000000000000001162215010704254021265 0ustar00rootroot00000000000000#include #include #include #include void test_stringset_from_string(void) { StringSet *s = StringSetFromString("one,two, three four,,", ','); assert_true(StringSetContains(s, "one")); assert_true(StringSetContains(s, "two")); assert_true(StringSetContains(s, " three four")); assert_true(StringSetContains(s, "")); assert_int_equal(4, StringSetSize(s)); StringSetDestroy(s); } void test_stringset_clear(void) { StringSet *s = StringSetNew(); StringSetAdd(s, xstrdup("a")); StringSetAdd(s, xstrdup("b")); assert_int_equal(2, StringSetSize(s)); StringSetClear(s); assert_int_equal(0, StringSetSize(s)); StringSetDestroy(s); } void test_stringset_serialization(void) { { StringSet *set = StringSetNew(); StringSetAdd(set, xstrdup("tag_1")); StringSetAdd(set, xstrdup("tag_2")); StringSetAdd(set, xstrdup("tag_3")); Buffer *buff = StringSetToBuffer(set, ','); assert_true(buff); assert_string_equal(BufferData(buff), "tag_1,tag_2,tag_3"); BufferDestroy(buff); StringSetDestroy(set); } { StringSet *set = StringSetNew(); Buffer *buff = StringSetToBuffer(set, ','); assert_true(buff); assert_string_equal(BufferData(buff), ""); BufferDestroy(buff); StringSetDestroy(set); } } void test_stringset_join(void) { { StringSet *set1 = StringSetNew(); StringSet *set2 = StringSetNew(); StringSetJoin(set1, set2, xstrdup); StringSetDestroy(set2); assert_int_equal(0, StringSetSize(set1)); Buffer *buff = StringSetToBuffer(set1, ','); assert_true(buff); assert_string_equal(BufferData(buff), ""); BufferDestroy(buff); StringSetDestroy(set1); } { StringSet *set = StringSetNew(); StringSetAdd(set, xstrdup("foo")); StringSetJoin(set, set, xstrdup); assert_int_equal(1, StringSetSize(set)); Buffer *buff = StringSetToBuffer(set, ','); assert_true(buff); assert_string_equal(BufferData(buff), "foo"); StringSetDestroy(set); BufferDestroy(buff); } { StringSet *set1 = StringSetNew(); StringSet *set2 = StringSetNew(); StringSetAdd(set1, xstrdup("foo")); StringSetAdd(set2, xstrdup("bar")); StringSetJoin(set1, set2, xstrdup); StringSetDestroy(set2); assert_int_equal(2, StringSetSize(set1)); Buffer *buff = StringSetToBuffer(set1, ','); StringSetDestroy(set1); assert_true(buff); assert_string_equal(BufferData(buff), "foo,bar"); BufferDestroy(buff); } } void test_json_array_to_stringset(void) { StringSet *expected = StringSetNew(); StringSetAdd(expected, xstrdup("item1")); StringSetAdd(expected, xstrdup("2")); StringSetAdd(expected, xstrdup("item2")); JsonElement *json; const char *str = "[\"item1\", \"2\", \"item2\"]"; assert_int_equal(JSON_PARSE_OK, JsonParse(&str, &json)); StringSet *converted = JsonArrayToStringSet(json); assert_true(converted != NULL); assert_true(StringSetIsEqual(expected, converted)); StringSetDestroy(converted); JsonDestroy(json); /* integer primitive should just be converted to string */ str = "[\"item1\", 2, \"item2\"]"; assert_int_equal(JSON_PARSE_OK, JsonParse(&str, &json)); converted = JsonArrayToStringSet(json); assert_true(converted != NULL); assert_true(StringSetIsEqual(expected, converted)); StringSetDestroy(converted); JsonDestroy(json); /* non-primitive child elements not supported */ str = "[\"item1\", {\"key\": \"value\"}, \"item2\"]"; assert_int_equal(JSON_PARSE_OK, JsonParse(&str, &json)); converted = JsonArrayToStringSet(json); assert_true(converted == NULL); JsonDestroy(json); /* non-array JSONs not supported */ str = "{\"key\": \"value\"}"; assert_int_equal(JSON_PARSE_OK, JsonParse(&str, &json)); converted = JsonArrayToStringSet(json); assert_true(converted == NULL); JsonDestroy(json); StringSetDestroy(expected); } void test_stringset_add_f(void) { StringSet *set = StringSetNew(); StringSetAddF(set, "Hello %s!", "CFEngine"); StringSetAddF(set, "Bye CFEngine!"); StringSetAdd(set, xstrdup("")); assert_true(StringSetContains(set, "Hello CFEngine!")); assert_true(StringSetContains(set, "Bye CFEngine!")); assert_true(StringSetContains(set, "")); StringSetDestroy(set); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_stringset_from_string), unit_test(test_stringset_serialization), unit_test(test_stringset_clear), unit_test(test_stringset_join), unit_test(test_json_array_to_stringset), unit_test(test_stringset_add_f), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/libcompat_test.c0000644000000000000000000000756615010704254022460 0ustar00rootroot00000000000000#include #include #include /* Include the tested functions directly from libcompat! */ #include #define TEST_SNPRINTF 1 #include /* TODO TEST MORE OF OUR libcompat REPLACEMENTS! */ static void test_memmem() { char *result, *needle, *haystack; /* Can't find anything in nothing. */ needle = "whatever"; result = memmem("EMPTY", 0, needle, strlen(needle)); assert_int_equal(result, NULL); /* Even nothing is not in nothing. */ result = memmem("EMPTY", 0, "EMPTY", 0); assert_int_equal(result, NULL); /* Nothing can be found in anything. */ haystack = "blah"; result = memmem(haystack, strlen(haystack), "EMPTY", 0); assert_int_equal(result, &haystack[0]); /* Find something when exact match. */ haystack = "blah"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, &haystack[0]); /* Find something when at the beginning. */ haystack = "blah123"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, &haystack[0]); /* Find something when in the middle. */ haystack = "123blah123"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, &haystack[3]); /* Find something when in the end. */ haystack = "12345blah"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, &haystack[5]); /* Partial match is not a match, part 1. */ haystack = "12345bla"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, NULL); /* Partial match is not a match, part 2. */ haystack = "bla"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, NULL); /* Partial match is not a match, part 3. */ haystack = "bla123"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, NULL); /* All the right letters, in the right order, not contiguous. */ haystack = "bleach"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, NULL); /* Should not be affected by case. */ haystack = "BLAH"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, NULL); /* Don't jump forward too much on incomplete match. */ haystack = "bblblablah"; needle = "blah"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, &haystack[6]); /* Don't jump forward too much, part 2. */ haystack = "abcabcabcd"; needle = "abcabcd"; result = memmem(haystack, strlen(haystack), needle, strlen(needle)); assert_int_equal(result, &haystack[3]); } static void test_snprintf() { int failures = snprintf_rigorous_test(); if (failures > 0) { puts("\n" "=== WARNING your system's printf() generates different results ===\n" "=== than our printf() in libcompat! ===\n" "=== This is not a necessarily a bug, since this test has lots ===\n" "=== of requirements to run properly, so testsuite result is not affected. ===\n" "=== However it might indicate that printf() in your system's libc is buggy. ===\n" ); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_memmem), unit_test(test_snprintf) /* TODO test rpl_fprintf() outputs short and long strings correctly to a file. */ }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/libntech/tests/unit/ring_buffer_test.c0000644000000000000000000000432615010704254022765 0ustar00rootroot00000000000000#include #include #include #include static void test_excess(void) { static const size_t CAPACITY = 5; static const size_t FILL = 8; RingBuffer *buf = RingBufferNew(CAPACITY, NULL, free); assert_int_equal(0, RingBufferLength(buf)); assert_false(RingBufferHead(buf)); for (size_t i = 0; i < FILL; i++) { char *s = StringFromLong(i); RingBufferAppend(buf, s); if (i >= CAPACITY) { assert_true(RingBufferIsFull(buf)); assert_int_equal(CAPACITY, RingBufferLength(buf)); } else { assert_int_equal(i + 1, RingBufferLength(buf)); } assert_string_equal(s, RingBufferHead(buf)); } RingBufferIterator *iter = RingBufferIteratorNew(buf); const char *s = NULL; int i = FILL - CAPACITY; while ((s = RingBufferIteratorNext(iter))) { assert_int_equal(i, StringToLongExitOnError(s)); i++; } assert_false(RingBufferIteratorNext(iter)); RingBufferIteratorDestroy(iter); RingBufferClear(buf); assert_int_equal(0, RingBufferLength(buf)); assert_false(RingBufferHead(buf)); RingBufferDestroy(buf); } static void test_shortage(void) { static const size_t CAPACITY = 5; RingBuffer *buf = RingBufferNew(CAPACITY, NULL, free); assert_false(RingBufferHead(buf)); RingBufferAppend(buf, xstrdup("hello")); assert_string_equal("hello", RingBufferHead(buf)); RingBufferAppend(buf, xstrdup("world")); assert_string_equal("world", RingBufferHead(buf)); assert_int_equal(2, RingBufferLength(buf)); RingBufferIterator *iter = RingBufferIteratorNew(buf); assert_string_equal("hello", RingBufferIteratorNext(iter)); assert_string_equal("world", RingBufferIteratorNext(iter)); assert_false(RingBufferIteratorNext(iter)); RingBufferIteratorDestroy(iter); RingBufferClear(buf); assert_int_equal(0, RingBufferLength(buf)); assert_false(RingBufferHead(buf)); RingBufferDestroy(buf); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_excess), unit_test(test_shortage) }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/file_writer_test.c0000644000000000000000000000513415010704254023006 0ustar00rootroot00000000000000#include #include #include static Writer *global_w; static bool global_w_closed; /* Override libc's fwrite(). */ static size_t CFENGINE_TEST_fwrite(const void *ptr, size_t size, size_t nmemb, ARG_UNUSED FILE *stream) { for (int i = 0; i < nmemb; ++i) { char *b = xstrndup(ptr + i * size, size); WriterWrite(global_w, b); free(b); } return nmemb * size; } /* Override libc's fclose(). */ static int CFENGINE_TEST_fclose(ARG_UNUSED FILE *stream) { global_w_closed = true; return 0; } #include /* MUST be included after the overrides. */ void test_empty_file_buffer(void) { global_w = StringWriter(); global_w_closed = false; Writer *w = FileWriter(NULL); assert_int_equal(StringWriterLength(global_w), 0); assert_string_equal(StringWriterData(global_w), ""); WriterClose(w); WriterClose(global_w); assert_int_equal(global_w_closed, true); } void test_write_empty_file_buffer(void) { global_w = StringWriter(); Writer *w = FileWriter(NULL); WriterWrite(w, ""); assert_int_equal(StringWriterLength(global_w), 0); assert_string_equal(StringWriterData(global_w), ""); WriterClose(w); WriterClose(global_w); assert_int_equal(global_w_closed, true); } void test_write_file_buffer(void) { global_w = StringWriter(); Writer *w = FileWriter(NULL); WriterWrite(w, "123"); assert_int_equal(StringWriterLength(global_w), 3); assert_string_equal(StringWriterData(global_w), "123"); WriterClose(w); WriterClose(global_w); assert_int_equal(global_w_closed, true); } void test_multiwrite_file_buffer(void) { global_w = StringWriter(); Writer *w = FileWriter(NULL); WriterWrite(w, "123"); WriterWrite(w, "456"); assert_int_equal(StringWriterLength(global_w), 6); assert_string_equal(StringWriterData(global_w), "123456"); WriterClose(w); WriterClose(global_w); assert_int_equal(global_w_closed, true); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_empty_file_buffer), unit_test(test_write_empty_file_buffer), unit_test(test_write_file_buffer), unit_test(test_multiwrite_file_buffer), }; return run_tests(tests); } /* STUB */ void __ProgrammingError(ARG_UNUSED const char *file, ARG_UNUSED int lineno, ARG_UNUSED const char *format, ...) { fail(); exit(42); } void FatalError(ARG_UNUSED char *s, ...) { fail(); exit(42); } cfengine-3.24.2/libntech/tests/unit/path_test.c0000644000000000000000000000166615010704254021435 0ustar00rootroot00000000000000#include #include static void test_path_getquoted(void) { char *result = Path_GetQuoted(NULL); assert_true(result == NULL); result = Path_GetQuoted("no_need_to_quote/this"); assert_string_equal(result, "no_need_to_quote/this"); free(result); result = Path_GetQuoted("\"already/quoted\""); assert_string_equal(result, "\"already/quoted\""); free(result); result = Path_GetQuoted("needs some/quoting"); assert_string_equal(result, "\"needs some/quoting\""); free(result); result = Path_GetQuoted("also&needs/quoting"); assert_string_equal(result, "\"also&needs/quoting\""); free(result); result = Path_GetQuoted("also;needs/quoting"); assert_string_equal(result, "\"also;needs/quoting\""); free(result); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_path_getquoted), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/cleanup_test.c0000644000000000000000000000231615010704254022121 0ustar00rootroot00000000000000#include #include #include bool FN1; bool FN2; bool FN3; void fn1(void) { if (FN1) { fprintf(stderr, "fn1 is called twice"); _exit(255); } if (!FN2) { fprintf(stderr, "fn2 is not called fn1"); _exit(255); } if (!FN3) { fprintf(stderr, "fn3 is not called before fn1"); _exit(255); } FN1 = true; } void fn2(void) { if (FN1) { fprintf(stderr, "fn1 is called before fn2"); _exit(255); } if (FN2) { fprintf(stderr, "fn2 is called twice"); _exit(255); } if (!FN3) { fprintf(stderr, "fn3 is not called before fn2"); _exit(255); } FN2 = true; } void fn3(void) { if (FN1) { fprintf(stderr, "fn1 is called before fn3"); _exit(255); } if (FN2) { fprintf(stderr, "fn2 is called before fn3"); _exit(255); } if (FN3) { fprintf(stderr, "fn3 is called twice"); _exit(255); } FN3 = true; } int main() { PRINT_TEST_BANNER(); RegisterCleanupFunction(&fn1); RegisterCleanupFunction(&fn2); atexit(&fn3); return 0; } cfengine-3.24.2/libntech/tests/unit/hash_test.c0000644000000000000000000002232715010704254021421 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include /* * To test the hash implementation we need three things: * - A string * - A file * - A RSA key * We run one test for each, using two algorithms, MD5 and SHA256. */ static int initialized = 0; static char message[] = "This is a message"; static int message_length = 0; static char file[] = "/tmp/hashXXXXXX"; static int fd = -1; static RSA *rsa = NULL; void tests_setup() { int result = 0; fd = mkstemp(file); if (fd < 0) { initialized = 0; return; } message_length = strlen(message); result = write(fd, message, message_length); if (result < 0) { close (fd); unlink (file); initialized = 0; return; } OPENSSL_init_crypto(0, NULL); initialized = 1; rsa = RSA_new(); if (rsa) { BIGNUM *bn = NULL; bn = BN_new(); if (!bn) { close (fd); unlink (file); RSA_free(rsa); initialized = 0; return; } BN_set_word(bn, RSA_F4); RSA_generate_key_ex(rsa, 1024, bn, NULL); BN_free(bn); } } void tests_teardown() { if (fd >= 0) { close (fd); unlink (file); } if (rsa) { RSA_free(rsa); } initialized = 0; } #define ASSERT_IF_NOT_INITIALIZED \ assert_int_equal(1, initialized) /* * Tests * Each test does the same but from different sources, this is: * 1. Create a new hash structure using MD5 * 2. Check the length of the generated hash. * 3. Check the printable version (check that is not NULL). * 4. Destroy the hash structure. * 5. Create a new hash structure using SHA256. * 6. Check the length of the generated hash. * 7. Check the printable version (check that is not NULL). * 8. Destroy the hash structure. */ static void test_HashString(void) { ASSERT_IF_NOT_INITIALIZED; Hash *hash = NULL; unsigned int length = 0; assert_true(hash == NULL); hash = HashNew(message, message_length, HASH_METHOD_MD5); assert_true(hash != NULL); assert_int_equal(HASH_METHOD_MD5, HashType(hash)); assert_int_equal(CF_MD5_LEN, HashLength(hash)); assert_true(HashData(hash, &length) != NULL); assert_int_equal(length, CF_MD5_LEN); assert_true(HashPrintable(hash) != NULL); const char *md5_hash = HashPrintable(hash); assert_true((md5_hash[0] == 'M') && (md5_hash[1] == 'D') && (md5_hash[2] == '5') && (md5_hash[3] == '=')); HashDestroy(&hash); assert_true(hash == NULL); hash = HashNew(message, message_length, HASH_METHOD_SHA256); assert_true(hash != NULL); assert_int_equal(HASH_METHOD_SHA256, HashType(hash)); assert_int_equal(CF_SHA256_LEN, HashLength(hash)); assert_true(HashData(hash, &length) != NULL); assert_int_equal(length, CF_SHA256_LEN); assert_true(HashPrintable(hash) != NULL); const char *sha256_hash = HashPrintable(hash); assert_true((sha256_hash[0] == 'S') && (sha256_hash[1] == 'H') && (sha256_hash[2] == 'A') && (sha256_hash[3] == '=')); HashDestroy(&hash); /* Negative cases */ assert_true(HashNew(NULL, message_length, HASH_METHOD_MD5) == NULL); assert_true(HashNew(message, 0, HASH_METHOD_MD5) == NULL); assert_true(HashNew(message, message_length, HASH_METHOD_NONE) == NULL); assert_true(HashNew(message, 0, HASH_METHOD_NONE) == NULL); assert_true(HashNew(NULL, message_length, HASH_METHOD_NONE) == NULL); } static void test_HashDescriptor(void) { ASSERT_IF_NOT_INITIALIZED; Hash *hash = NULL; unsigned int length = 0; assert_true(hash == NULL); hash = HashNewFromDescriptor(fd, HASH_METHOD_MD5); assert_true(hash != NULL); assert_int_equal(HASH_METHOD_MD5, HashType(hash)); assert_int_equal(CF_MD5_LEN, HashLength(hash)); assert_true(HashData(hash, &length) != NULL); assert_int_equal(length, CF_MD5_LEN); assert_true(HashPrintable(hash) != NULL); HashDestroy(&hash); assert_true(hash == NULL); hash = HashNewFromDescriptor(fd, HASH_METHOD_SHA256); assert_true(hash != NULL); assert_int_equal(HASH_METHOD_SHA256, HashType(hash)); assert_int_equal(CF_SHA256_LEN, HashLength(hash)); assert_true(HashData(hash, &length) != NULL); assert_int_equal(length, CF_SHA256_LEN); assert_true(HashPrintable(hash) != NULL); HashDestroy(&hash); /* Negative cases */ assert_true(HashNewFromDescriptor(-1, HASH_METHOD_MD5) == NULL); assert_true(HashNewFromDescriptor(fd, HASH_METHOD_NONE) == NULL); assert_true(HashNewFromDescriptor(-1, HASH_METHOD_NONE) == NULL); } static void test_HashKey(void) { ASSERT_IF_NOT_INITIALIZED; Hash *hash = NULL; unsigned int length = 0; assert_true(hash == NULL); hash = HashNewFromKey(rsa, HASH_METHOD_MD5); assert_true(hash != NULL); assert_int_equal(HASH_METHOD_MD5, HashType(hash)); assert_int_equal(CF_MD5_LEN, HashLength(hash)); assert_true(HashData(hash, &length) != NULL); assert_int_equal(length, CF_MD5_LEN); assert_true(HashPrintable(hash) != NULL); HashDestroy(&hash); assert_true(hash == NULL); hash = HashNewFromKey(rsa, HASH_METHOD_SHA256); assert_true(hash != NULL); assert_int_equal(HASH_METHOD_SHA256, HashType(hash)); assert_int_equal(CF_SHA256_LEN, HashLength(hash)); assert_true(HashData(hash, &length) != NULL); assert_int_equal(length, CF_SHA256_LEN); assert_true(HashPrintable(hash) != NULL); HashDestroy(&hash); /* Negative cases */ assert_true(HashNewFromKey(NULL, HASH_METHOD_MD5) == NULL); assert_true(HashNewFromKey(rsa, HASH_METHOD_NONE) == NULL); assert_true(HashNewFromKey(NULL, HASH_METHOD_NONE) == NULL); } static void test_HashCopy(void) { ASSERT_IF_NOT_INITIALIZED; Hash *hash = NULL; Hash *copy = NULL; unsigned int length = 0; assert_true(hash == NULL); hash = HashNew(message, message_length, HASH_METHOD_MD5); assert_true(hash != NULL); assert_int_equal(HASH_METHOD_MD5, HashType(hash)); assert_int_equal(CF_MD5_LEN, HashLength(hash)); assert_true(HashData(hash, &length) != NULL); assert_int_equal(length, CF_MD5_LEN); assert_true(HashPrintable(hash) != NULL); assert_int_equal(0, HashCopy(hash, ©)); assert_int_equal(HASH_METHOD_MD5, HashType(copy)); assert_int_equal(CF_MD5_LEN, HashLength(copy)); assert_true(HashData(copy, &length) != NULL); assert_int_equal(length, CF_MD5_LEN); assert_true(HashPrintable(copy) != NULL); assert_string_equal(HashPrintable(hash), HashPrintable(copy)); HashDestroy(©); assert_true(copy == NULL); /* Negative cases */ assert_int_equal(-1, HashCopy(NULL, ©)); assert_int_equal(-1, HashCopy(hash, NULL)); assert_int_equal(-1, HashCopy(NULL, NULL)); /* Finish */ HashDestroy(&hash); assert_true(hash == NULL); } static void test_HashesMatch(void) { unsigned char digest_a[EVP_MAX_MD_SIZE + 1] = { 0 }; unsigned char digest_b[EVP_MAX_MD_SIZE + 1] = { 0 }; unsigned char digest_c[EVP_MAX_MD_SIZE + 1] = { 0 }; unsigned char digest_d[EVP_MAX_MD_SIZE + 1] = { 0 }; HashString("abc", 4, digest_a, HASH_METHOD_MD5); HashString("abc", 4, digest_b, HASH_METHOD_MD5); HashString("abc", 3, digest_c, HASH_METHOD_MD5); HashString("abd", 4, digest_d, HASH_METHOD_MD5); assert_true(HashesMatch(digest_a, digest_b, HASH_METHOD_MD5)); assert_false(HashesMatch(digest_b, digest_c, HASH_METHOD_MD5)); assert_false(HashesMatch(digest_c, digest_d, HASH_METHOD_MD5)); assert_false(HashesMatch(digest_a, digest_d, HASH_METHOD_MD5)); } static void test_StringCopyTruncateAndHashIfNecessary(void) { char buf[40]; int ret; const char *thirty_nine = "123456789_123456789_123456789_123456789"; ret = StringCopyTruncateAndHashIfNecessary(thirty_nine, buf, 40); assert_string_equal(thirty_nine, buf); assert_int_equal(ret, 39); StringCopyTruncateAndHashIfNecessary("abc", buf, 40); assert_string_equal("abc", buf); const char *too_long = "The quick brown fox jumps over the lazy dog"; ret = StringCopyTruncateAndHashIfNecessary(too_long, buf, 40); assert_int_equal(ret, 40); assert_false(StringEqual(too_long, buf)); assert_true(strlen(too_long) != strlen(buf)); assert_int_equal(strlen(buf), 39); assert_true(StringEqual(buf, "Th#MD5=9e107d9d372bb6826bd81d3542a419d6")); ret = StringCopyTruncateAndHashIfNecessary(too_long, buf, 39); assert_int_equal(ret, 39); assert_true(StringEqual(buf, "T#MD5=9e107d9d372bb6826bd81d3542a419d6")); ret = StringCopyTruncateAndHashIfNecessary(too_long, buf, 38); assert_int_equal(ret, 38); assert_true(StringEqual(buf, "#MD5=9e107d9d372bb6826bd81d3542a419d6")); } /* * Main routine * Notice the calls to both setup and teardown. */ int main() { PRINT_TEST_BANNER(); tests_setup(); const UnitTest tests[] = { unit_test(test_HashString), unit_test(test_HashDescriptor), unit_test(test_HashKey), unit_test(test_HashCopy), unit_test(test_HashesMatch), unit_test(test_StringCopyTruncateAndHashIfNecessary), }; int result = run_tests(tests); tests_teardown(); return result; } cfengine-3.24.2/libntech/tests/unit/xml_writer_test.c0000644000000000000000000000426415010704254022672 0ustar00rootroot00000000000000#include #include #include /* * FIXME: Those unit tests need to be ajusted (or completely changed) if * XmlWriter internals are changed, as the tests expect particular layout and * escaping of generated XML. */ void test_comment(void) { Writer *w = StringWriter(); XmlComment(w, "foobar"); char *result = StringWriterClose(w); assert_string_equal(result, "\n"); free(result); } void test_no_attr(void) { Writer *w = StringWriter(); XmlTag(w, "foobar", NULL, 0); char *result = StringWriterClose(w); assert_string_equal(result, "\n"); free(result); } void test_tag(void) { Writer *w = StringWriter(); XmlTag(w, "foobar", "some value", 1, (XmlAttribute) { "a", "b"}); char *result = StringWriterClose(w); assert_string_equal(result, "some value\n"); free(result); } void test_complex_tag(void) { Writer *w = StringWriter(); XmlStartTag(w, "complex-tag", 2, (XmlAttribute) { "attr1", "value1"}, (XmlAttribute) { "attr2", "value2"}); XmlContent(w, "Some content"); XmlEndTag(w, "complex-tag"); char *result = StringWriterClose(w); assert_string_equal(result, "\nSome content\n"); free(result); } void test_escape(void) { Writer *w = StringWriter(); XmlContent(w, "&>\"'<"); char *result = StringWriterClose(w); assert_string_equal(result, "&>"'<"); free(result); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_comment), unit_test(test_no_attr), unit_test(test_tag), unit_test(test_complex_tag), unit_test(test_escape), }; return run_tests(tests); } /* STUB OUT */ void __ProgrammingError(ARG_UNUSED const char *file, ARG_UNUSED int lineno, ARG_UNUSED const char *format, ...) { fail(); exit(42); } void FatalError(ARG_UNUSED char *s, ...) { fail(); exit(42); } cfengine-3.24.2/libntech/tests/unit/alloc_test.c0000644000000000000000000000204115010704254021557 0ustar00rootroot00000000000000#include #include #include #include #include void test_xasprintf(void) { char *s; int res = xasprintf(&s, "Foo%d%s", 123, "17"); assert_int_equal(res, 8); assert_string_equal(s, "Foo12317"); free(s); } void test_xvasprintf_sub(const char *fmt, ...) { char *s; va_list ap; va_start(ap, fmt); int res = xvasprintf(&s, fmt, ap); va_end(ap); assert_int_equal(res, 8); assert_string_equal(s, "Foo12317"); free(s); } void test_xvasprintf(void) { test_xvasprintf_sub("Foo%d%s", 123, "17"); } void test_free_array_items(void) { char **arr = xcalloc(10, sizeof(char*)); for (size_t i = 0; i < 10; i++) { arr[i] = xstrdup("some string"); } free_array_items((void**)arr, 10); free(arr); /* There should be no memleaks now. */ } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_xasprintf), unit_test(test_xvasprintf), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/test.c0000644000000000000000000000234315010704254020412 0ustar00rootroot00000000000000#include #include #include #include #include char *file_read_string(FILE *in) { fpos_t pos; long size; char *buffer; assert_int_equal(fgetpos(in, &pos), 0); assert_int_equal(fseek(in, 0, SEEK_END), 0); size = ftell(in); assert_true(size >= 0); assert_int_equal(fseek(in, 0, SEEK_SET), 0); buffer = xcalloc(size + 1L, sizeof(char)); assert_int_equal(fread(buffer, 1, size, in), size); assert_int_equal(fsetpos(in, &pos), 0); return buffer; } void assert_file_equal(FILE *a, FILE *b) { char *a_buffer = file_read_string(a); char *b_buffer = file_read_string(b); if (strcmp(a_buffer, b_buffer) != 0) { printf("\n=====\n%s != \n=====\n%s\n", a_buffer, b_buffer); fail(); } free(a_buffer); free(b_buffer); } #define SMALL_DIFF 1e-14 void _assert_double_close(double left, double right, const char *const file, const int line) { if (fabs(left - right) > SMALL_DIFF) { print_error("%f != %f (+- 1e-14)\n", left, right); _fail(file, line); } } void test_progress() { putchar('.'); fflush(stdout); } void test_progress_end() { putchar('\n'); fflush(stdout); } cfengine-3.24.2/libntech/tests/unit/glob_lib_test.c0000644000000000000000000006173015010704254022250 0ustar00rootroot00000000000000#include #include static void test_expand_braces(void) { { StringSet *const set = StringSetNew(); ExpandBraces("foo", set); assert_true(StringSetContains(set, "foo")); assert_int_equal(StringSetSize(set), 1); StringSetDestroy(set); } { StringSet *const set = StringSetNew(); ExpandBraces("foo{bar,baz}qux", set); assert_true(StringSetContains(set, "foobarqux")); assert_true(StringSetContains(set, "foobazqux")); assert_int_equal(StringSetSize(set), 2); StringSetDestroy(set); } { StringSet *const set = StringSetNew(); ExpandBraces("foo{bar}baz", set); assert_true(StringSetContains(set, "foobarbaz")); assert_int_equal(StringSetSize(set), 1); StringSetDestroy(set); } { StringSet *const set = StringSetNew(); ExpandBraces("foo{}bar", set); assert_true(StringSetContains(set, "foobar")); assert_int_equal(StringSetSize(set), 1); StringSetDestroy(set); } { StringSet *const set = StringSetNew(); ExpandBraces("foo{,}bar", set); assert_true(StringSetContains(set, "foobar")); assert_int_equal(StringSetSize(set), 1); StringSetDestroy(set); } { StringSet *const set = StringSetNew(); ExpandBraces("foo{{bar,baz}qux,}", set); assert_true(StringSetContains(set, "foo")); assert_true(StringSetContains(set, "foobarqux")); assert_true(StringSetContains(set, "foobazqux")); assert_int_equal(StringSetSize(set), 3); StringSetDestroy(set); } { StringSet *const set = StringSetNew(); ExpandBraces("", set); assert_true(StringSetContains(set, "")); assert_int_equal(StringSetSize(set), 1); StringSetDestroy(set); } } static void test_normalize_path(void) { char *const actual = NormalizePath("C:\\Program Files\\Cfengine\\bin\\"); #ifdef _WIN32 assert_string_equal(actual, "c:\\program files\\cfengine\\bin\\"); #else // _WIN32 assert_string_equal(actual, "C:\\Program Files\\Cfengine\\bin\\"); #endif // _WIN32 free(actual); } #ifdef WITH_PCRE2 static void test_translate_bracket(void) { { const char *const pattern = "[a-z]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[a-z]"); free(data); } { const char *const pattern = "[abc]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[abc]"); free(data); } { const char *const pattern = "[!a-z]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[^a-z]"); free(data); } { const char *const pattern = "[!abc]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[^abc]"); free(data); } { const char *const pattern = "[a--c-f]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[a-\\-c-f]"); free(data); } { const char *const pattern = "[[]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[\\[]"); free(data); } { const char *const pattern = "[a-z+--A-Z]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[a-z+-\\-A-Z]"); free(data); } { const char *const pattern = "[a-z--/A-Z]"; Buffer *const buffer = BufferNew(); TranslateBracket(pattern, strlen(pattern), 1, buffer); char *const data = BufferClose(buffer); assert_string_equal(data, "[a-z\\--/A-Z]"); free(data); } } static void test_translate_glob(void) { { char *const regex = TranslateGlob("*"); assert_string_equal(regex, "(?s:.*)\\Z"); free(regex); } { char *const regex = TranslateGlob("?"); assert_string_equal(regex, "(?s:.)\\Z"); free(regex); } { char *const regex = TranslateGlob("a?b*"); assert_string_equal(regex, "(?s:a.b.*)\\Z"); free(regex); } { char *const regex = TranslateGlob("[abc]"); assert_string_equal(regex, "(?s:[abc])\\Z"); free(regex); } { char *const regex = TranslateGlob("[]]"); assert_string_equal(regex, "(?s:[]])\\Z"); free(regex); } { char *const regex = TranslateGlob("[!x]"); assert_string_equal(regex, "(?s:[^x])\\Z"); free(regex); } { char *const regex = TranslateGlob("[x"); assert_string_equal(regex, "(?s:\\[x)\\Z"); free(regex); } { char *const regex = TranslateGlob("ba[rz]"); assert_string_equal(regex, "(?s:ba[rz])\\Z"); free(regex); } } static void test_glob_match(void) { assert_true(GlobMatch("foo", "foo")); assert_false(GlobMatch("foo", "bar")); assert_true(GlobMatch("{foo,bar,}", "foo")); assert_true(GlobMatch("{foo,bar,}", "bar")); assert_false(GlobMatch("{foo,bar,}", "baz")); assert_true(GlobMatch("{foo,bar,}", "")); assert_true(GlobMatch("", "")); assert_false(GlobMatch("", "foo")); assert_false(GlobMatch("foo", "")); assert_true(GlobMatch("*", "foo")); assert_true(GlobMatch("*", "")); assert_true(GlobMatch("*", "*")); assert_false(GlobMatch("ba?", "foo")); assert_true(GlobMatch("ba?", "bar")); assert_true(GlobMatch("ba?", "baz")); assert_false(GlobMatch("ba[rz]", "foo")); assert_true(GlobMatch("ba[rz]", "bar")); assert_true(GlobMatch("ba[rz]", "baz")); assert_false(GlobMatch("ba[rz]", "bat")); assert_true(GlobMatch("ba[r-z]", "bat")); assert_true(GlobMatch("[a-z][a-z][a-z]", "foo")); assert_true(GlobMatch("[a-z][a-z][a-z]", "bar")); assert_true(GlobMatch("[a-z][a-z][a-z]", "baz")); assert_false(GlobMatch("[a-z][a-z][a-y]", "baz")); assert_true(GlobMatch("foo{{bar,baz}qux,}", "foo")); assert_true(GlobMatch("foo{{bar,baz}qux,}", "foobarqux")); assert_true(GlobMatch("foo{{bar,baz}qux,}", "foobazqux")); assert_false(GlobMatch("foo{{bar,baz}qux,}", "foobar")); assert_false(GlobMatch("foo{{bar,baz}qux,}", "foobaz")); assert_true(GlobMatch("[aaa]", "a")); assert_true(GlobMatch("[abc-f]", "a")); assert_true(GlobMatch("[abc-f]", "c")); assert_true(GlobMatch("[abc-f]", "d")); assert_true(GlobMatch("[ab-ef]", "d")); assert_true(GlobMatch("[ab-ef]", "f")); assert_true(GlobMatch("[!a-c][d-f]", "de")); assert_false(GlobMatch("[!a-c][d-f]", "cd")); assert_false(GlobMatch("[!a-c][d-f]", "dc")); assert_true(GlobMatch("[!abc]", "d")); assert_false(GlobMatch("[!abc]", "b")); #ifdef _WIN32 // Pattern and filename is case-normalized on Windows assert_true(GlobMatch( "C:\\Program Files\\Cfengine\\bin\\cf-agent.exe", "c:\\program files\\cfengine\\bin\\cf-agent.exe")); assert_true(GlobMatch( "c:\\program files\\cfengine\\bin\\cf-agent.exe", "C:\\Program Files\\Cfengine\\bin\\cf-agent.exe")); #else // _WIN32 // Pattern and filename is not case-normalized on Unix assert_false(GlobMatch( "C:/Program Files/Cfengine/bin/cf-agent.exe", "c:/program files/cfengine/bin/cf-agent.exe")); assert_false(GlobMatch( "c:/program files/cfengine/bin/cf-agent.exe", "C:/Program Files/Cfengine/bin/cf-agent.exe")); #endif // _WIN32 assert_true(GlobMatch("[[]", "[")); assert_true(GlobMatch("[a-z+--A-Z]", ",")); assert_true(GlobMatch("[a-z--/A-Z]", ".")); } static void test_glob_find(void) { /* This test is not very thorough. However, test_glob_file_list() * indirectly tests this one. */ { Seq *const matches = GlobFind("test.{h,c}"); assert_int_equal(SeqLength(matches), 2); assert_string_equal(SeqAt(matches, 0), "test.c"); assert_string_equal(SeqAt(matches, 1), "test.h"); SeqDestroy(matches); } { Seq *const matches = GlobFind("."); assert_int_equal(SeqLength(matches), 1); assert_string_equal(SeqAt(matches, 0), "."); SeqDestroy(matches); } } #endif // WITH_PCRE2 static void test_glob_file_list(void) { // Create temporary directory. char template[] = "test_glob_file_list_XXXXXX"; const char *const test_dir = mkdtemp(template); assert_true(test_dir != NULL); // Create test subdirectories. static const char *const test_subdirs[] = { "foo", "foo" FILE_SEPARATOR_STR "bar", "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz", "qux", }; const size_t num_test_subdirs = sizeof(test_subdirs) / sizeof(const char *); char path[PATH_MAX]; for (size_t i = 0; i < num_test_subdirs; i++) { int ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "%s", test_dir, test_subdirs[i]); assert_false(ret >= PATH_MAX || ret < 0); ret = mkdir(path, (mode_t) 0700); assert_int_equal(ret, 0); } // Create test files. static const char *const test_files[] = { #ifdef WITH_PCRE2 /* POSIX glob(3) does not support GLOB_PERIOD, meaning it will not find * this file, thus cause tests below to fail. */ ".gitignore", #endif // WITH_PCRE2 "README.md", "foo" FILE_SEPARATOR_STR "README.md", "foo" FILE_SEPARATOR_STR "bank_statements.txt", "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "README.md", "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "passwords.txt", "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "secret.gpg", "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz" FILE_SEPARATOR_STR "README.md", "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz" FILE_SEPARATOR_STR "const is love", "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz" FILE_SEPARATOR_STR "const is life", "qux" FILE_SEPARATOR_STR "README.md", "qux" FILE_SEPARATOR_STR "source.c", "qux" FILE_SEPARATOR_STR "source.h", "qux" FILE_SEPARATOR_STR "source.o", "qux" FILE_SEPARATOR_STR "source.cpp", "qux" FILE_SEPARATOR_STR "source.hpp", }; const size_t num_test_files = sizeof(test_files) / sizeof(const char *); for (size_t i = 0; i < num_test_files; i++) { const int ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "%s", test_dir, test_files[i]); assert_true(ret < PATH_MAX && ret >= 0); const int fd = open(path, O_CREAT, (mode_t) 0600); assert_int_not_equal(fd, -1); close(fd); } /* Let's do some rigorous testing! The file system should look something * like this: * * test_glob_file_list_XXXXXX/ * +-- .gitignore * +-- README.md * +-- foo/ * | +-- README.md * | +-- bank_statements.txt * | +-- bar/ * | +-- README.md * | +-- passwords.txt * | +-- secret.gpg * | +-- baz/ * | +-- README.md * | +-- "const is love" * | +-- "const is life" * +-- qux/ * +-- README.md * +-- source.c * +-- source.h * +-- source.o * +-- source.cpp * +-- source.hpp */ ////////////////////////////////////////////////////////////////////////// // Check that we can find all files with a relative path glob pattern. ////////////////////////////////////////////////////////////////////////// char pattern[PATH_MAX]; int ret = snprintf(pattern, PATH_MAX, "%s/**/*", test_dir); assert_true(ret < PATH_MAX && ret >= 0); StringSet *matches = GlobFileList(pattern); assert_int_equal( StringSetSize(matches), num_test_files + num_test_subdirs); for (size_t i = 0; i < num_test_files; i++) { const int ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "%s", test_dir, test_files[i]); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); } for (size_t i = 0; i < num_test_subdirs; i++) { const int ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "%s", test_dir, test_subdirs[i]); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); } StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Check that we can find all files with an absolute path glob pattern. ////////////////////////////////////////////////////////////////////////// char cwd[PATH_MAX]; assert_true(getcwd(cwd, PATH_MAX) != NULL); ret = snprintf(pattern, PATH_MAX, "%s/%s/**/*", cwd, test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal( StringSetSize(matches), num_test_files + num_test_subdirs); for (size_t i = 0; i < num_test_files; i++) { const int ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "%s" FILE_SEPARATOR_STR "%s", cwd, test_dir, test_files[i]); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); } for (size_t i = 0; i < num_test_subdirs; i++) { const int ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "%s" FILE_SEPARATOR_STR "%s", cwd, test_dir, test_subdirs[i]); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); } StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Let's find 'foo', 'bar', 'baz', 'qux' using brace expansion ////////////////////////////////////////////////////////////////////////// #ifdef WITH_PCRE2 // POSIX glob(3) does not support glob expansion. ret = snprintf(pattern, PATH_MAX, "%s/**/{foo,bar,baz,qux}", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 4); ret = snprintf(path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf(path, PATH_MAX, "%s" FILE_SEPARATOR_STR "qux", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); #endif // WITH_PCRE2 ////////////////////////////////////////////////////////////////////////// // Let's find all markdown files ////////////////////////////////////////////////////////////////////////// ret = snprintf(pattern, PATH_MAX, "%s/**/*.md", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 5); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "README.md", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "README.md", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "README.md", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz" FILE_SEPARATOR_STR "README.md", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR "README.md", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Let's find all one letter extension files ////////////////////////////////////////////////////////////////////////// ret = snprintf(pattern, PATH_MAX, "%s/**/*.?", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 3); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR "source.c", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR "source.h", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR "source.o", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Let's find all C++ files ////////////////////////////////////////////////////////////////////////// ret = snprintf(pattern, PATH_MAX, "%s/qux/source.[ch]pp", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 2); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR "source.cpp", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR "source.hpp", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Let's find const is {love,life} files ////////////////////////////////////////////////////////////////////////// ret = snprintf( pattern, PATH_MAX, "%s/foo/bar/baz/const is l[oi][vf]e", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 2); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz" FILE_SEPARATOR_STR "const is love", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "baz" FILE_SEPARATOR_STR "const is life", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Let's find dot files ////////////////////////////////////////////////////////////////////////// #ifdef WITH_PCRE2 /* POSIX glob(3) does not support GLOB_PERIOD, meaning it will not find * this file, thus cause tests below to fail. */ ret = snprintf(pattern, PATH_MAX, "%s/**/.*", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 1); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR ".gitignore", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); #endif // WITH_PCRE2 ////////////////////////////////////////////////////////////////////////// // Let's use ranges ////////////////////////////////////////////////////////////////////////// ret = snprintf(pattern, PATH_MAX, "%s/**/[b-f][a-o][o-y]", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 2); ret = snprintf(path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Let's find exact match ////////////////////////////////////////////////////////////////////////// ret = snprintf(pattern, PATH_MAX, "%s/foo/bank_statements.txt", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 1); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bank_statements.txt", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); ////////////////////////////////////////////////////////////////////////// // Let's combine a whole bunch of different wildcards ////////////////////////////////////////////////////////////////////////// #ifdef WITH_PCRE2 // POSIX glob(3) does not support brace expansion. ret = snprintf( pattern, PATH_MAX, "%s/{foo,bar,baz}/[bf][!b-z]{r,z}/**/*c[r]e?.?p?", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 1); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR "bar" FILE_SEPARATOR_STR "secret.gpg", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); #endif // WITH_PCRE2 ////////////////////////////////////////////////////////////////////////// // Let's use the '.' and '..' directory entries in the pattern. ////////////////////////////////////////////////////////////////////////// ret = snprintf( pattern, PATH_MAX, "%s/foo/../qux/../qux/./source.o", test_dir); assert_true(ret < PATH_MAX && ret >= 0); matches = GlobFileList(pattern); assert_int_equal(StringSetSize(matches), 1); ret = snprintf( path, PATH_MAX, "%s" FILE_SEPARATOR_STR "foo" FILE_SEPARATOR_STR ".." FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR ".." FILE_SEPARATOR_STR "qux" FILE_SEPARATOR_STR "." FILE_SEPARATOR_STR "source.o", test_dir); assert_true(ret < PATH_MAX && ret >= 0); assert_true(StringSetContains(matches, path)); StringSetDestroy(matches); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_expand_braces), unit_test(test_normalize_path), #ifdef WITH_PCRE2 unit_test(test_translate_bracket), unit_test(test_translate_glob), unit_test(test_glob_match), unit_test(test_glob_find), #endif // WITH_PCRE2 unit_test(test_glob_file_list), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/test.h0000644000000000000000000000264615010704254020425 0ustar00rootroot00000000000000/* ALWAYS INCLUDE FIRST, so that platform.h is included first as well! */ #ifndef CFENGINE_TEST_H #define CFENGINE_TEST_H #include #include #include #include #include #include /* Use this define for specific overrides inside all our source tree. */ #define CFENGINE_TEST #define PRINT_TEST_BANNER() \ printf("==================================================\n"); \ printf("Starting test: %s\n", __FILE__); \ printf("==================================================\n") char *file_read_string(FILE *in); void assert_file_equal(FILE *a, FILE *b); #define assert_double_close(a, b) _assert_double_close(a, b, __FILE__, __LINE__) void _assert_double_close(double left, double right, const char *const file, const int line); void test_progress(void); void test_progress_end(void); // like assert_string_equal, but better with respect to pointers: // if a and b are NULL, returns true // if a or b is NULL print error using assert_int // if a and b are not NULL, use assert_string #define assert_string_int_equal(a, b)\ {\ const char* x = a;\ const char* y = b;\ if (x!=y)\ {\ if (x==NULL||y==NULL)\ {\ assert_int_equal(x, y);\ }\ else\ {\ assert_string_equal(x, y);\ }\ }\ }\ #endif cfengine-3.24.2/libntech/tests/unit/rb-tree-test.c0000644000000000000000000001114415010704254021747 0ustar00rootroot00000000000000#include #include #include #include #include static void *_IntCopy(const void *_a) { return xmemdup(_a, sizeof(int)); } static int _IntCompare(const void *_a, const void *_b) { const int *a = _a, *b = _b; return *a - *b; } static RBTree *IntTreeNew_(void) { return RBTreeNew(_IntCopy, _IntCompare, free, _IntCopy, _IntCompare, free); } static void test_new_destroy(void) { RBTree *t = IntTreeNew_(); RBTreeDestroy(t); } static void test_put_overwrite(void) { RBTree *t = IntTreeNew_(); int a = 42; assert_false(RBTreePut(t, &a, &a)); int *r = RBTreeGet(t, &a); assert_int_equal(a, *r); assert_true(RBTreePut(t, &a, &a)); r = RBTreeGet(t, &a); assert_int_equal(a, *r); RBTreeDestroy(t); } static void test_put_remove(void) { RBTree *t = IntTreeNew_(); int a = 42; assert_false(RBTreePut(t, &a, &a)); int *r = RBTreeGet(t, &a); assert_int_equal(a, *r); assert_true(RBTreeRemove(t, &a)); r = RBTreeGet(t, &a); assert_true(r == NULL); assert_false(RBTreeRemove(t, &a)); r = RBTreeGet(t, &a); assert_true(r == NULL); RBTreeDestroy(t); } static void test_put_remove_inorder(void) { RBTree *t = IntTreeNew_(); for (int i = 0; i < 20000; i++) { RBTreePut(t, &i, &i); } for (int i = 0; i < 20000; i++) { int *r = RBTreeGet(t, &i); assert_int_equal(i, *r); } for (int i = 0; i < 20000; i++) { RBTreeRemove(t, &i); } RBTreeDestroy(t); } static void test_iterate_empty(void) { RBTree *t = IntTreeNew_(); RBTreeIterator *it = RBTreeIteratorNew(t); void *r = NULL; while (RBTreeIteratorNext(it, &r, NULL)) { fail(); } assert_true(r == NULL); RBTreeIteratorDestroy(it); RBTreeDestroy(t); } static void test_iterate(void) { RBTree *t = IntTreeNew_(); for (int i = 0; i < 20; i++) { RBTreePut(t, &i, &i); } assert_int_equal(20, RBTreeSize(t)); RBTreeIterator *it = RBTreeIteratorNew(t); for (int i = 0; i < 20; i++) { int *k = NULL; int *v = NULL; assert_true(RBTreeIteratorNext(it, (void **)&k, (void **)&v)); assert_int_equal(i, *k); assert_int_equal(i, *v); } assert_false(RBTreeIteratorNext(it, NULL, NULL)); RBTreeIteratorDestroy(it); RBTreeDestroy(t); } static void test_put_remove_random(void) { Seq *nums = SeqNew(20000, free); srand(0); for (int i = 0; i < 20000; i++) { int k = rand() % 1000; SeqAppend(nums, xmemdup(&k, sizeof(int))); } RBTree *t = IntTreeNew_(); for (size_t i = 0; i < SeqLength(nums); i++) { RBTreePut(t, SeqAt(nums, i), SeqAt(nums, i)); } for (size_t i = 0; i < SeqLength(nums); i++) { int *k = SeqAt(nums, i); int *r = RBTreeGet(t, k); assert_int_equal(*k, *r); } for (size_t i = 0; i < SeqLength(nums); i++) { RBTreeRemove(t, SeqAt(nums, i)); } SeqDestroy(nums); RBTreeDestroy(t); } static void test_clear(void) { RBTree *t = IntTreeNew_(); for (int i = 0; i < 20000; i++) { RBTreePut(t, &i, &i); } int k = 5; assert_true(RBTreeGet(t, &k) != NULL); assert_int_equal(20000, RBTreeSize(t)); RBTreeClear(t); assert_true(RBTreeGet(t, &k) == NULL); assert_int_equal(0, RBTreeSize(t)); for (int i = 0; i < 20000; i++) { RBTreePut(t, &i, &i); } assert_true(RBTreeGet(t, &k) != NULL); assert_int_equal(20000, RBTreeSize(t)); RBTreeDestroy(t); } static void test_equal(void) { RBTree *a = IntTreeNew_(); RBTree *b = IntTreeNew_(); for (int i = 0; i < 20000; i++) { RBTreePut(a, &i, &i); RBTreePut(b, &i, &i); } assert_true(RBTreeEqual(a, b)); RBTreeDestroy(a); RBTreeDestroy(b); } static void test_copy(void) { RBTree *a = IntTreeNew_(); for (int i = 0; i < 20000; i++) { RBTreePut(a, &i, &i); } RBTree *b = RBTreeCopy(a, NULL, NULL); assert_true(RBTreeEqual(a, b)); RBTreeDestroy(a); RBTreeDestroy(b); } int main() { const UnitTest tests[] = { unit_test(test_new_destroy), unit_test(test_put_overwrite), unit_test(test_put_remove), unit_test(test_put_remove_inorder), unit_test(test_iterate_empty), unit_test(test_iterate), unit_test(test_put_remove_random), unit_test(test_clear), unit_test(test_equal), unit_test(test_copy), }; PRINT_TEST_BANNER(); return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/list_test.c0000644000000000000000000007465415010704254021463 0ustar00rootroot00000000000000#include #include #include #include // Simple initialization test static void test_initList(void) { List *list = NULL; list = ListNew(NULL, NULL, NULL); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); // We shouldn't use this function yet, but otherwise we leak memory assert_int_equal(ListDestroy(&list), 0); } // This function is just an example function for the destroyer #include void testDestroyer(void *element) { // We know the elements are just char * char *s = (char *)element; printf("element: %s \n", s); free (s); } static void test_destroyer(void) { List *list = NULL; list = ListNew(NULL, NULL, testDestroyer); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); assert_int_equal(list->compare, NULL); assert_int_equal(list->copy, NULL); assert_int_not_equal(list->destroy, NULL); char *element0 = xstrdup("this is a test string"); char *element1 = xstrdup("another test string"); char *element2 = xstrdup("yet another test string"); char *element3 = xstrdup("and one more test string"); // We add element0 to the list. assert_int_equal(ListPrepend(list, element0), 0); // We add element1 to the list. assert_int_equal(ListPrepend(list, element1), 0); // We add element2 to the list. assert_int_equal(ListPrepend(list, element2), 0); // We add element3 to the list. assert_int_equal(ListPrepend(list, element3), 0); // Now we try to destroy the list. assert_int_equal(ListDestroy(&list), 0); } static void test_prependToList(void) { List *list = NULL; list = ListNew(NULL, NULL, testDestroyer); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); assert_int_equal(list->compare, NULL); assert_int_equal(list->copy, NULL); assert_int_not_equal(list->destroy, NULL); char *element0 = xstrdup("this is a test string"); char *element1 = xstrdup("another test string"); void *listPointer = NULL; void *firstPointer = NULL; void *lastPointer = NULL; // We add element0 to the list. assert_int_equal(ListPrepend(list, element0), 0); // Now we check the list assert_int_not_equal(list->first, NULL); firstPointer = list->first; assert_int_not_equal(list->list, NULL); listPointer = list->list; assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); lastPointer = list->last; assert_int_equal(list->node_count, 1); // Adding elements does not change the state of the list assert_int_equal(list->state, 0); // We add element1 to the list. assert_int_equal(ListPrepend(list, element1), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == firstPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_int_not_equal(list->last, NULL); assert_true(list->last == lastPointer); assert_int_equal(list->node_count, 2); assert_int_equal(list->state, 0); // Now we try to destroy the list. This should fail because the list is not empty assert_int_equal(ListDestroy(&list), 0); } static void test_appendToList(void) { List *list = NULL; list = ListNew(NULL, NULL, testDestroyer); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); char *element0 = xstrdup("this is a test string"); char *element1 = xstrdup("another test string"); void *element0tPointer = NULL; // We add element0 to the list. assert_int_equal(ListAppend(list, element0), 0); // Now we check the list assert_int_not_equal(list->first, NULL); element0tPointer = list->first; assert_int_not_equal(list->list, NULL); assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); assert_true(list->last == list->first); assert_int_equal(list->node_count, 1); // Adding elements does not change the list state assert_int_equal(list->state, 0); // We add element1 to the list. assert_int_equal(ListAppend(list, element1), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_int_not_equal(list->list, NULL); assert_int_not_equal(list->last, NULL); assert_true(element0tPointer == list->list); assert_true(element0tPointer == list->first); assert_false(list->first == list->last); assert_int_equal(list->node_count, 2); assert_int_equal(list->state, 0); // Now we try to destroy the list. This should fail because the list is not empty assert_int_equal(ListDestroy(&list), 0); } static int compareFunction(const void *a, const void *b) { return strcmp(a, b); } static void copyFunction(const void *s, void **d) { if (!s || !d) return; const char *source = s; char **destination = (char **)d; *destination = xstrdup(source); } static void test_removeFromList(void) { List *list = NULL; list = ListNew(compareFunction, NULL, testDestroyer); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); assert_int_not_equal(list->destroy, NULL); assert_int_not_equal(list->compare, NULL); assert_int_equal(list->copy, NULL); char *element0 = xstrdup("this is a test string"); char *element1 = xstrdup("another test string"); char *element2 = xstrdup("yet another test string"); char *element3 = xstrdup("and one more test string"); char *element4 = xstrdup("non existing element"); void *listPointer = NULL; void *firstPointer = NULL; void *secondPointer = NULL; void *thirdPointer = NULL; void *lastPointer = NULL; // We add element0 to the list. assert_int_equal(ListPrepend(list, element0), 0); // Now we check the list assert_int_not_equal(list->first, NULL); firstPointer = list->first; assert_int_not_equal(list->list, NULL); listPointer = list->list; assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); lastPointer = list->last; assert_int_equal(list->node_count, 1); // Adding elements does not change the list state assert_int_equal(list->state, 0); // We add element1 to the list. assert_int_equal(ListPrepend(list, element1), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == firstPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_true(list->list == list->first); secondPointer = list->list; assert_int_not_equal(list->last, NULL); assert_true(list->last == lastPointer); assert_int_equal(list->node_count, 2); assert_int_equal(list->state, 0); // We add element2 to the list. assert_int_equal(ListPrepend(list, element2), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == firstPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_true(list->list == list->first); thirdPointer = list->list; assert_int_not_equal(list->last, NULL); assert_true(list->last == lastPointer); assert_int_equal(list->node_count, 3); assert_int_equal(list->state, 0); // We add element3 to the list. assert_int_equal(ListPrepend(list, element3), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == firstPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); assert_true(list->last == lastPointer); assert_int_equal(list->node_count, 4); assert_int_equal(list->state, 0); // We remove the non existing element assert_int_equal(ListRemove(list, element4), -1); assert_int_not_equal(list->first, NULL); assert_false(list->first == firstPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); assert_true(list->last == lastPointer); assert_int_equal(list->node_count, 4); assert_int_equal(list->state, 0); // Remove element1 which is in the middle of the list assert_int_equal(ListRemove(list, element1), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == firstPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); assert_true(list->last == lastPointer); assert_int_equal(list->node_count, 3); assert_int_equal(list->state, 1); // Remove element3 which is at the beginning of the list assert_int_equal(ListRemove(list, element3), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == secondPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); assert_true(list->last == lastPointer); assert_int_equal(list->node_count, 2); assert_int_equal(list->state, 2); // Remove element0 which is at the end of the list assert_int_equal(ListRemove(list, element0), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == secondPointer); assert_int_not_equal(list->list, NULL); assert_false(list->list == listPointer); assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); assert_true(list->last == thirdPointer); assert_int_equal(list->node_count, 1); assert_int_equal(list->state, 3); // Remove element2 which is the only element on the list assert_int_equal(ListRemove(list, element2), 0); // Now we check the list assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 4); // Now we destroy the list. assert_int_equal(ListDestroy(&list), 0); free (element4); } static void test_destroyList(void) { List *list = NULL; list = ListNew(NULL, NULL, testDestroyer); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); // Now we destroy the list assert_int_equal(ListDestroy(&list), 0); assert_int_equal(list, NULL); } static void test_copyList(void) { /* * First try the normal path, i.e. with a copy function. Then try it without a copy function. */ List *list1 = NULL; List *list2 = NULL; List *list3 = NULL; List *list4 = NULL; char *element0 = xstrdup("this is a test string"); char *element1 = xstrdup("another test string"); char *element2 = xstrdup("yet another test string"); list1 = ListNew(compareFunction, copyFunction, testDestroyer); assert_true(list1 != NULL); assert_int_not_equal(list1, NULL); assert_int_equal(list1->first, NULL); assert_int_equal(list1->list, NULL); assert_int_equal(list1->last, NULL); assert_int_equal(list1->node_count, 0); assert_int_equal(list1->state, 0); assert_int_equal(0, ListPrepend(list1, (void *)element0)); assert_int_equal(1, ListCount(list1)); /* * Copy the list1 to list2 and prepend one more element */ assert_int_equal(0, ListCopy(list1, &list2)); assert_int_equal(1, ListCount(list2)); assert_true(list1->ref_count == list2->ref_count); assert_int_equal(0, ListPrepend(list2, (void *)element1)); /* * The two lists have detached now. */ assert_int_equal(1, ListCount(list1)); assert_int_equal(2, ListCount(list2)); assert_false(list1->ref_count == list2->ref_count); /* * Add one more element to list1 and then attach list3 and list4. * Finally detach list4 by removing one element. */ assert_int_equal(0, ListPrepend(list1, (void *)element2)); assert_int_equal(0, ListCopy(list1, &list3)); assert_int_equal(0, ListCopy(list1, &list4)); assert_int_equal(2, ListCount(list1)); assert_int_equal(2, ListCount(list3)); assert_int_equal(2, ListCount(list4)); assert_true(list1->ref_count == list3->ref_count); assert_true(list1->ref_count == list4->ref_count); assert_true(list4->ref_count == list3->ref_count); assert_int_equal(0, ListRemove(list4, (void *)element0)); assert_int_equal(2, ListCount(list1)); assert_int_equal(2, ListCount(list3)); assert_int_equal(1, ListCount(list4)); assert_true(list1->ref_count == list3->ref_count); assert_false(list1->ref_count == list4->ref_count); assert_false(list4->ref_count == list3->ref_count); assert_int_equal(ListDestroy(&list1), 0); assert_int_equal(ListDestroy(&list2), 0); assert_int_equal(ListDestroy(&list3), 0); assert_int_equal(ListDestroy(&list4), 0); /* * No copy function now, boys don't cry */ List *list5 = NULL; List *list6 = NULL; element0 = xstrdup("this is a test string"); list5 = ListNew(compareFunction, NULL, testDestroyer); assert_true(list5 != NULL); assert_int_not_equal(list5, NULL); assert_int_equal(list5->first, NULL); assert_int_equal(list5->list, NULL); assert_int_equal(list5->last, NULL); assert_int_equal(list5->node_count, 0); assert_int_equal(list5->state, 0); assert_int_equal(0, ListPrepend(list5, (void *)element0)); assert_int_equal(1, ListCount(list5)); /* * Copy the list5 to list6 and prepend one more element */ assert_int_equal(-1, ListCopy(list5, &list6)); assert_true(list6 == NULL); assert_int_equal(ListDestroy(&list5), 0); } static void test_iterator(void) { List *list = NULL; list = ListNew(compareFunction, NULL, testDestroyer); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); ListIterator *emptyListIterator = NULL; emptyListIterator = ListIteratorGet(list); assert_true(emptyListIterator == NULL); char *element0 = xstrdup("this is a test string"); char *element1 = xstrdup("another test string"); char *element2 = xstrdup("yet another test string"); char *element3 = xstrdup("and one more test string"); void *element0Pointer = NULL; void *element1Pointer = NULL; void *element2Pointer = NULL; void *element3Pointer = NULL; // We add element0 to the list. assert_int_equal(ListPrepend(list, element0), 0); // Now we check the list assert_int_not_equal(list->first, NULL); element0Pointer = list->first; assert_true(list->first == element0Pointer); assert_int_not_equal(list->list, NULL); assert_true(list->list == list->first); assert_int_not_equal(list->last, NULL); assert_int_equal(list->node_count, 1); assert_int_equal(list->state, 0); // We add element1 to the list. assert_int_equal(ListPrepend(list, element1), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == element0Pointer); assert_int_not_equal(list->list, NULL); element1Pointer = list->list; assert_true(list->first == element1Pointer); assert_int_not_equal(list->last, NULL); assert_true(list->last == element0Pointer); assert_int_equal(list->node_count, 2); assert_int_equal(list->state, 0); // We add element2 to the list. assert_int_equal(ListPrepend(list, element2), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == element1Pointer); assert_int_not_equal(list->list, NULL); element2Pointer = list->list; assert_true(list->first == element2Pointer); assert_int_not_equal(list->last, NULL); assert_true(list->last == element0Pointer); assert_int_equal(list->node_count, 3); assert_int_equal(list->state, 0); // We add element3 to the list. assert_int_equal(ListPrepend(list, element3), 0); // Now we check the list assert_int_not_equal(list->first, NULL); assert_false(list->first == element2Pointer); assert_int_not_equal(list->list, NULL); element3Pointer = list->list; assert_true(list->first == element3Pointer); assert_int_not_equal(list->last, NULL); assert_true(list->last == element0Pointer); assert_int_equal(list->node_count, 4); assert_int_equal(list->state, 0); ListIterator *iterator0 = NULL; iterator0 = ListIteratorGet(list); // Check the iterator assert_true(iterator0 != NULL); assert_int_equal(iterator0->state, 0); assert_true(iterator0->origin == list); assert_true(iterator0->current == list->first); // Remove element1 which is in the middle of the list, this will invalidate the iterator assert_int_equal(ListRemove(list, element1), 0); // Check that the iterator is not valid by trying to advance it assert_int_equal(ListIteratorNext(iterator0), -1); // Destroy the iterator assert_int_equal(ListIteratorDestroy(&iterator0), 0); assert_int_equal(iterator0, NULL); // Create a new iterator and move it ListIterator *iterator1 = NULL; iterator1 = ListIteratorGet(list); // Check the iterator assert_int_not_equal(iterator1, NULL); assert_int_equal(iterator1->state, 1); assert_true(iterator1->origin == list); assert_true(iterator1->current == list->first); void *value = NULL; value = ListIteratorData(iterator1); assert_true(value == element3); // Advance it assert_int_equal(ListIteratorNext(iterator1), 0); // Check the value, it should be equal to element2 value = ListIteratorData(iterator1); assert_true(value == element2); // Advance it, now we are at the last element assert_int_equal(ListIteratorNext(iterator1), 0); // Check the value, it should be equal to element0 value = ListIteratorData(iterator1); assert_true(value == element0); // Advance it, should fail and the iterator should stay where it was assert_int_equal(ListIteratorNext(iterator1), -1); // Check the value, it should be equal to element0 value = ListIteratorData(iterator1); assert_true(value == element0); // Go back assert_int_equal(ListIteratorPrevious(iterator1), 0); // Check the value, it should be equal to element2 value = ListIteratorData(iterator1); assert_true(value == element2); // Go back, now we are at the beginning of the list assert_int_equal(ListIteratorPrevious(iterator1), 0); // Check the value, it should be equal to element3 value = ListIteratorData(iterator1); assert_true(value == element3); // Go back, should fail and the iterator should stay where it was assert_int_equal(ListIteratorPrevious(iterator1), -1); // Check the value, it should be equal to element3 value = ListIteratorData(iterator1); assert_true(value == element3); // Jump to the last element assert_int_equal(ListIteratorLast(iterator1), 0); // Check the value, it should be equal to element0 value = ListIteratorData(iterator1); assert_true(value == element0); // Go back assert_true(ListIteratorHasPrevious(iterator1)); assert_int_equal(ListIteratorPrevious(iterator1), 0); // Check the value, it should be equal to element2 value = ListIteratorData(iterator1); assert_true(value == element2); // Jump to the first element assert_int_equal(ListIteratorFirst(iterator1), 0); // Check the value, it should be equal to element3 value = ListIteratorData(iterator1); assert_true(value == element3); // Advance it assert_true(ListIteratorHasNext(iterator1)); assert_int_equal(ListIteratorNext(iterator1), 0); // Check the value, it should be equal to element2 value = ListIteratorData(iterator1); assert_true(value == element2); // Remove the elements assert_int_equal(ListRemove(list, element3), 0); assert_int_equal(ListRemove(list, element0), 0); assert_int_equal(ListRemove(list, element2), 0); // Destroy the iterator assert_int_equal(ListIteratorDestroy(&iterator1), 0); // Now we destroy the list. assert_int_equal(ListDestroy(&list), 0); } static void test_mutableIterator(void) { List *list = NULL; list = ListNew(compareFunction, NULL, testDestroyer); assert_true(list != NULL); assert_int_not_equal(list, NULL); assert_int_equal(list->first, NULL); assert_int_equal(list->list, NULL); assert_int_equal(list->last, NULL); assert_int_equal(list->node_count, 0); assert_int_equal(list->state, 0); ListMutableIterator *emptyListIterator = NULL; emptyListIterator = ListMutableIteratorGet(list); assert_true(emptyListIterator == NULL); char *element0 = xstrdup("this is a test string"); char *element1 = xstrdup("another test string"); char *element2 = xstrdup("yet another test string"); char *element3 = xstrdup("and one more test string"); char *element4 = xstrdup("prepended by iterator"); char *element5 = xstrdup("appended by iterator"); char *element6 = xstrdup("appended by iterator, second time"); char *element7 = xstrdup("prepended by iterator, second time"); // We add element0 to the list. assert_int_equal(ListAppend(list, element0), 0); // We add element1 to the list. assert_int_equal(ListAppend(list, element1), 0); // We add element2 to the list. assert_int_equal(ListAppend(list, element2), 0); // We add element3 to the list. assert_int_equal(ListAppend(list, element3), 0); // We use a light iterator to check that is valid ListIterator *lightIterator = NULL; lightIterator = ListIteratorGet(list); ListMutableIterator *iterator = NULL; ListMutableIterator *secondIterator = NULL; iterator = ListMutableIteratorGet(list); assert_true(iterator != NULL); // The iterator should be pointing to the first element assert_true(iterator->current == list->first); // Trying to create a second iterator must fail secondIterator = ListMutableIteratorGet(list); assert_true(secondIterator == NULL); // Loop through the list until we get to the last element and then back while (ListMutableIteratorHasNext(iterator)) { assert_int_equal(0, ListMutableIteratorNext(iterator)); } assert_int_equal(-1, ListMutableIteratorNext(iterator)); // and back while (ListMutableIteratorHasPrevious(iterator)) { assert_int_equal(0, ListMutableIteratorPrevious(iterator)); } assert_int_equal(-1, ListMutableIteratorPrevious(iterator)); // Jump to the last element assert_int_equal(0, ListMutableIteratorLast(iterator)); // and back to the first element assert_int_equal(0, ListMutableIteratorFirst(iterator)); // Prepend one element at the beginning of the list assert_int_equal(0, ListMutableIteratorPrepend(iterator, (void *)element4)); assert_int_equal(5, list->node_count); // The light iterator is still valid assert_int_equal(list->state, lightIterator->state); // It should be possible to go back one element now. assert_int_equal(0, ListMutableIteratorPrevious(iterator)); // Check that the list and the iterator agree who is the first one. assert_true(list->first == iterator->current); // Append one element after the first element assert_int_equal(0, ListMutableIteratorAppend(iterator, (void *)element5)); assert_int_equal(6, list->node_count); // The light iterator is still valid assert_int_equal(list->state, lightIterator->state); // Loop through the list until we get to the last element and then back while (ListMutableIteratorHasNext(iterator)) { assert_int_equal(0, ListMutableIteratorNext(iterator)); } assert_int_equal(-1, ListMutableIteratorNext(iterator)); // and back while (ListMutableIteratorHasPrevious(iterator)) { assert_int_equal(0, ListMutableIteratorPrevious(iterator)); } assert_int_equal(-1, ListMutableIteratorPrevious(iterator)); // Jump to the last element assert_int_equal(0, ListMutableIteratorLast(iterator)); // and back to the first element assert_int_equal(0, ListMutableIteratorFirst(iterator)); // And back to the last element assert_int_equal(0, ListMutableIteratorLast(iterator)); // Append one element after the last element assert_int_equal(0, ListMutableIteratorAppend(iterator, (void *)element6)); assert_int_equal(7, list->node_count); // The light iterator is still valid assert_int_equal(list->state, lightIterator->state); // It should be possible to advance one position assert_int_equal(0, ListMutableIteratorNext(iterator)); // Check that both the list and the iterator point to the same last element assert_true(iterator->current == list->last); // Prepend one element before the last element assert_int_equal(0, ListMutableIteratorPrepend(iterator, (void *)element7)); assert_int_equal(8, list->node_count); // The light iterator is still valid assert_int_equal(list->state, lightIterator->state); // Go back one element and remove the element assert_int_equal(0, ListMutableIteratorPrevious(iterator)); // We should be located at element4 assert_string_equal(element7, (char *)iterator->current->payload); // Remove the current element assert_int_equal(0, ListMutableIteratorRemove(iterator)); // Check that the list agrees assert_int_equal(7, list->node_count); // We should be at element5 now, the last element of the list assert_string_equal(element6, (char *)iterator->current->payload); assert_true(iterator->current == list->last); // The light iterator is not valid anymore assert_false(list->state == lightIterator->state); // Remove the last element, we should go back to element3 assert_int_equal(0, ListMutableIteratorRemove(iterator)); // Check that the list agrees assert_int_equal(6, list->node_count); // We should be at element3 now, the last element of the list assert_string_equal(element3, (char *)iterator->current->payload); assert_true(iterator->current == list->last); // Jump to the first element of the list assert_int_equal(0, ListMutableIteratorFirst(iterator)); // Remove the first element, we should end up in element5 assert_int_equal(0, ListMutableIteratorRemove(iterator)); // Check that the list agrees assert_int_equal(5, list->node_count); // We should be at element5 now, the first element of the list assert_string_equal(element5, (char *)iterator->current->payload); assert_true(iterator->current == list->first); // Now remove element3, the last element of the list using the Remove function assert_int_equal(0, ListRemove(list, (void *)element3)); assert_int_equal(4, list->node_count); // We should be at element5 now, the first element of the list assert_string_equal(element5, (char *)iterator->current->payload); assert_true(iterator->current == list->first); // Jump to the last element of the list assert_int_equal(0, ListMutableIteratorLast(iterator)); // This should be element2 assert_string_equal(element2, (char *)iterator->current->payload); // Move the iterator to the previous element, element1, and delete it. The iterator should move to element2. assert_int_equal(0, ListMutableIteratorPrevious(iterator)); assert_int_equal(0, ListRemove(list, (void *)element1)); assert_int_equal(3, list->node_count); assert_string_equal(element2, (char *)iterator->current->payload); assert_true(iterator->current == list->last); // Remove the last element of the list, the iterator should move to element0 assert_int_equal(0, ListRemove(list, (void *)element2)); assert_int_equal(2, list->node_count); assert_string_equal(element0, (char *)iterator->current->payload); assert_true(iterator->current == list->last); // Jump to the first element assert_int_equal(0, ListMutableIteratorFirst(iterator)); // Remove the first element, that should move the iterator to element0 assert_int_equal(0, ListRemove(list, (void *)element5)); assert_int_equal(1, list->node_count); assert_string_equal(element0, (char *)iterator->current->payload); assert_true(iterator->current == list->last); assert_true(iterator->current == list->first); // Finally try to remove the only element using the iterator, it should fail. assert_int_equal(-1, ListMutableIteratorRemove(iterator)); // Remove the final element using the list and check that the iterator is invalid assert_int_equal(0, ListRemove(list, (void *)element0)); assert_false(iterator->valid); // Destroy the iterators and the list assert_int_equal(0, ListMutableIteratorRelease(&iterator)); assert_int_equal(0, ListIteratorDestroy(&lightIterator)); assert_int_equal(0, ListDestroy(&list)); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_initList) , unit_test(test_destroyList) , unit_test(test_destroyer) , unit_test(test_prependToList) , unit_test(test_appendToList) , unit_test(test_removeFromList) , unit_test(test_copyList) , unit_test(test_iterator) , unit_test(test_mutableIterator) }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/cmockery.h0000644000000000000000000005315215010704254021260 0ustar00rootroot00000000000000/* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CMOCKERY_H_ # define CMOCKERY_H_ /* * These headers or their equivalents should be included prior to including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. */ # if defined(__GNUC__) && (__GNUC__ * 100 >= 3) # define FUNC_ATTR_NORETURN __attribute__((noreturn)) # else/* not gcc >= 3.0 */ # define FUNC_ATTR_NORETURN # endif // For those who are used to __func__ from gcc. # ifndef __func__ # define __func__ __FUNCTION__ # endif /* Largest integral type. This type should be large enough to hold any * pointer or integer supported by the compiler. */ # ifndef LargestIntegralType # define LargestIntegralType unsigned long long # endif// LargestIntegralType // Printf format used to display LargestIntegralType. # ifndef LargestIntegralTypePrintfFormat # ifdef _WIN32 # define LargestIntegralTypePrintfFormat "%I64x" # define LargestIntegralTypePrintfDecimal "%I64d" # else # define LargestIntegralTypePrintfFormat "%llx" # define LargestIntegralTypePrintfDecimal "%lld" # endif // _WIN32 # endif// LargestIntegralTypePrintfFormat // Perform an unsigned cast to LargestIntegralType. # define cast_to_largest_integral_type(value) \ _cast_to_largest_integral_type(sizeof(value), value) // Retrieves a return value for the current function. # define mock() _mock(__func__, __FILE__, __LINE__) /* Stores a value to be returned by the specified function later. * The count parameter returns the number of times the value should be returned * by mock(). If count is set to -1 the value will always be returned. */ # define will_return(function, value) \ _will_return(#function, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), 1) # define will_return_count(function, value, count) \ _will_return(#function, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) /* Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event * parameter is provided it must be allocated on the heap and doesn't need to * be deallocated by the caller. */ # define expect_check(function, parameter, check_function, check_data) \ _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ cast_to_largest_integral_type(check_data), NULL, 0) /* Add an event to check a parameter, using check_expected(), against a set of * values. See will_return() for a description of the count parameter. */ # define expect_in_set(function, parameter, value_array) \ expect_in_set_count(function, parameter, value_array, 1) # define expect_in_set_count(function, parameter, value_array, count) \ _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ sizeof(value_array) / sizeof((value_array)[0]), count) # define expect_not_in_set(function, parameter, value_array) \ expect_not_in_set_count(function, parameter, value_array, 1) # define expect_not_in_set_count(function, parameter, value_array, count) \ _expect_not_in_set( \ #function, #parameter, __FILE__, __LINE__, value_array, \ sizeof(value_array) / sizeof((value_array)[0]), count) /* Add an event to check a parameter, using check_expected(), against a * signed range. Where range is minimum <= value <= maximum. * See will_return() for a description of the count parameter. */ # define expect_in_range(function, parameter, minimum, maximum) \ expect_in_range_count(function, parameter, minimum, maximum, 1) # define expect_in_range_count(function, parameter, minimum, maximum, count) \ _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ maximum, count) /* Add an event to check a parameter, using check_expected(), against a * signed range. Where range is value < minimum or value > maximum. * See will_return() for a description of the count parameter. */ # define expect_not_in_range(function, parameter, minimum, maximum) \ expect_not_in_range_count(function, parameter, minimum, maximum, 1) # define expect_not_in_range_count(function, parameter, minimum, maximum, \ count) \ _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ minimum, maximum, count) /* Add an event to check whether a parameter, using check_expected(), is or * isn't a value. See will_return() for a description of the count parameter. */ # define expect_value(function, parameter, value) \ expect_value_count(function, parameter, value, 1) # define expect_value_count(function, parameter, value, count) \ _expect_value(#function, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) # define expect_not_value(function, parameter, value) \ expect_not_value_count(function, parameter, value, 1) # define expect_not_value_count(function, parameter, value, count) \ _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) /* Add an event to check whether a parameter, using check_expected(), * is or isn't a string. See will_return() for a description of the count * parameter. */ # define expect_string(function, parameter, string) \ expect_string_count(function, parameter, string, 1) # define expect_string_count(function, parameter, string, count) \ _expect_string(#function, #parameter, __FILE__, __LINE__, \ (const char*)(string), count) # define expect_not_string(function, parameter, string) \ expect_not_string_count(function, parameter, string, 1) # define expect_not_string_count(function, parameter, string, count) \ _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ (const char*)(string), count) /* Add an event to check whether a parameter, using check_expected() does or * doesn't match an area of memory. See will_return() for a description of * the count parameter. */ # define expect_memory(function, parameter, memory, size) \ expect_memory_count(function, parameter, memory, size, 1) # define expect_memory_count(function, parameter, memory, size, count) \ _expect_memory(#function, #parameter, __FILE__, __LINE__, \ (const void*)(memory), size, count) # define expect_not_memory(function, parameter, memory, size) \ expect_not_memory_count(function, parameter, memory, size, 1) # define expect_not_memory_count(function, parameter, memory, size, count) \ _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ (const void*)(memory), size, count) /* Add an event to allow any value for a parameter checked using * check_expected(). See will_return() for a description of the count * parameter. */ # define expect_any(function, parameter) \ expect_any_count(function, parameter, 1) # define expect_any_count(function, parameter, count) \ _expect_any(#function, #parameter, __FILE__, __LINE__, count) /* Determine whether a function parameter is correct. This ensures the next * value queued by one of the expect_*() macros matches the specified variable. */ # define check_expected(parameter) \ _check_expected(__func__, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(parameter)) // Assert that the given expression is true. # define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ __FILE__, __LINE__) // Assert that the given expression is false. # define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ __FILE__, __LINE__) // Assert that the two given integers are equal, otherwise fail. # define assert_int_equal(a, b) \ _assert_int_equal(cast_to_largest_integral_type(a), \ cast_to_largest_integral_type(b), \ __FILE__, __LINE__) // Assert that the two given integers are not equal, otherwise fail. # define assert_int_not_equal(a, b) \ _assert_int_not_equal(cast_to_largest_integral_type(a), \ cast_to_largest_integral_type(b), \ __FILE__, __LINE__) // Assert that the two given strings are equal, otherwise fail. # define assert_string_equal(a, b) \ _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ __LINE__) // Assert that the two given strings are not equal, otherwise fail. # define assert_string_not_equal(a, b) \ _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ __LINE__) // Assert that the two given areas of memory are equal, otherwise fail. # define assert_memory_equal(a, b, size) \ _assert_memory_equal((const char*)(a), (const char*)(b), size, __FILE__, \ __LINE__) // Assert that the two given areas of memory are not equal, otherwise fail. # define assert_memory_not_equal(a, b, size) \ _assert_memory_not_equal((const char*)(a), (const char*)(b), size, \ __FILE__, __LINE__) // Assert that the specified value is >= minimum and <= maximum. # define assert_in_range(value, minimum, maximum) \ _assert_in_range( \ cast_to_largest_integral_type(value), \ cast_to_largest_integral_type(minimum), \ cast_to_largest_integral_type(maximum), __FILE__, __LINE__) // Assert that the specified value is < minimum or > maximum # define assert_not_in_range(value, minimum, maximum) \ _assert_not_in_range( \ cast_to_largest_integral_type(value), \ cast_to_largest_integral_type(minimum), \ cast_to_largest_integral_type(maximum), __FILE__, __LINE__) // Assert that the specified value is within a set. # define assert_in_set(value, values, number_of_values) \ _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) // Assert that the specified value is not within a set. # define assert_not_in_set(value, values, number_of_values) \ _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) // Forces the test to fail immediately and quit. # define fail() _fail(__FILE__, __LINE__) // Generic method to kick off testing # define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL) // Initializes a UnitTest structure. # define unit_test(func) { .name = #func, .f = { .function = func }, .function_type = UNIT_TEST_FUNCTION_TYPE_TEST } # define unit_test_with_state(func) { .name = #func, .f = { .function_with_state = func }, .function_type = UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE } # define unit_test_setup(test, setup) \ { .name = #test "_" #setup, .f = { .function_with_state = setup }, .function_type = UNIT_TEST_FUNCTION_TYPE_SETUP } # define unit_test_teardown(test, teardown) \ { .name = #test "_" #teardown, .f = { .function_with_state = teardown }, .function_type = UNIT_TEST_FUNCTION_TYPE_TEARDOWN } /* Initialize an array of UnitTest structures with a setup function for a test * and a teardown function. Either setup or teardown can be NULL. */ # define unit_test_setup_teardown(test, setup, teardown) \ unit_test_setup(test, setup), \ unit_test_with_state(test), \ unit_test_teardown(test, teardown) /* * Run tests specified by an array of UnitTest structures. The following * example illustrates this macro's use with the unit_test macro. * * void Test0(); * void Test1(); * * int main(int argc, char* argv[]) { * const UnitTest tests[] = { * unit_test(Test0); * unit_test(Test1); * }; * return run_tests(tests); * } */ # define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof(tests)[0], __FILE__) // Dynamic allocators # define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) # define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) # define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) // Redirect malloc, calloc and free to the unit test allocators. # if UNIT_TESTING # define malloc test_malloc # define calloc test_calloc # define free test_free # endif// UNIT_TESTING /* * Ensure mock_assert() is called. If mock_assert() is called the assert * expression string is returned. * For example: * * #define assert mock_assert * * void showmessage(const char *message) { * assert(message); * } * * int main(int argc, const char* argv[]) { * expect_assert_failure(show_message(NULL)); * printf("succeeded\n"); * return 0; * } */ # define expect_assert_failure(function_call) \ { \ const int has_expression = setjmp(global_expect_assert_env); \ global_expecting_assert = 1; \ if (has_expression) { \ print_message("Expected assertion %s occurred\n", \ global_expect_assert_expression); \ global_expecting_assert = 0; \ } else { \ function_call ; \ global_expecting_assert = 0; \ print_error("Expected assert in %s\n", #function_call); \ _fail(__FILE__, __LINE__); \ } \ } // Function prototype for setup, test and teardown functions. typedef void (*UnitTestFunction) (void); typedef void (*UnitTestFunctionWithState) (void **state); // Function that determines whether a function parameter value is correct. typedef int (*CheckParameterValue) (const LargestIntegralType value, const LargestIntegralType check_value_data); // Type of the unit test function. typedef enum UnitTestFunctionType { UNIT_TEST_FUNCTION_TYPE_TEST = 0, UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE, UNIT_TEST_FUNCTION_TYPE_SETUP, UNIT_TEST_FUNCTION_TYPE_TEARDOWN, } UnitTestFunctionType; /* Stores a unit test function with its name and type. * NOTE: Every setup function must be paired with a teardown function. It's * possible to specify NULL function pointers. */ typedef struct UnitTest { const char *name; union { UnitTestFunction function; UnitTestFunctionWithState function_with_state; } f; UnitTestFunctionType function_type; } UnitTest; // Location within some source code. typedef struct SourceLocation { const char *file; int line; } SourceLocation; // Event that's called to check a parameter value. typedef struct CheckParameterEvent { SourceLocation location; const char *parameter_name; CheckParameterValue check_value; LargestIntegralType check_value_data; } CheckParameterEvent; // Used by expect_assert_failure() and mock_assert(). extern int global_expecting_assert; extern const char *global_expect_assert_expression; extern jmp_buf global_expect_assert_env; LargestIntegralType _cast_to_largest_integral_type(size_t size, ...); // Retrieves a value for the given function, as set by "will_return". LargestIntegralType _mock(const char *const function, const char *const file, const int line); void _expect_check(const char *const function, const char *const parameter, const char *const file, const int line, const CheckParameterValue check_function, const LargestIntegralType check_data, CheckParameterEvent *const event, const int count); void _expect_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_not_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count); void _expect_not_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count); void _expect_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count); void _expect_not_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count); void _expect_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count); void _expect_not_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count); void _expect_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count); void _expect_not_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count); void _expect_any(const char *const function, const char *const parameter, const char *const file, const int line, const int count); void _check_expected(const char *const function_name, const char *const parameter_name, const char *file, const int line, const LargestIntegralType value); // Can be used to replace assert in tested code so that in conjunction with // check_assert() it's possible to determine whether an assert condition has // failed without stopping a test. void mock_assert(const int result, const char *const expression, const char *const file, const int line); void _will_return(const char *const function_name, const char *const file, const int line, const LargestIntegralType value, const int count); void _assert_true(const LargestIntegralType result, const char *const expression, const char *const file, const int line); void _assert_int_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line); void _assert_int_not_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line); void _assert_string_equal(const char *const a, const char *const b, const char *const file, const int line); void _assert_string_not_equal(const char *const a, const char *const b, const char *file, const int line); void _assert_memory_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line); void _assert_memory_not_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line); void _assert_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line); void _assert_not_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line); void _assert_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line); void _assert_not_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line); void *_test_malloc(const size_t size, const char *file, const int line); void *_test_calloc(const size_t number_of_elements, const size_t size, const char *file, const int line); void _test_free(void *const ptr, const char *file, const int line); void _fail(const char *const file, const int line) FUNC_ATTR_NORETURN; int _run_test(const char *const function_name, const UnitTestFunction Function, void **const state, const UnitTestFunctionType function_type, const void *const heap_check_point); int _run_tests(const UnitTest *const tests, const size_t number_of_tests, const char *const file); // XML init and output void vinit_xml (const char *const format, va_list args); void vprint_xml(const char *const format, va_list args); void init_xml (const char *const format, ...); void print_xml(const char *const format, ...); void vinit_cunit_run_files (const char *const file, const char *const format, va_list args); void init_cunit_run_files (const char *const file, const char *const format, ...); void append_xml_tmp(const char *ofile, const char *ifile); // Standard output and error print methods. void print_message(const char *const format, ...); void print_error(const char *const format, ...); void vprint_message(const char *const format, va_list args); void vprint_error(const char *const format, va_list args); #endif cfengine-3.24.2/libntech/tests/unit/version_comparison_test.c0000644000000000000000000001043615010704254024413 0ustar00rootroot00000000000000#include #include static void test_CompareVersion(void) { assert_true(VERSION_EQUAL == CompareVersion("3.15.0", "3.15.0")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0", "3.15.0a")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0", "3.15.0a1")); assert_true(VERSION_EQUAL == CompareVersion("3.15", "3.15.0")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0", "3.15")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0", "3")); assert_true(VERSION_EQUAL == CompareVersion("3", "3.15.0")); assert_true(VERSION_EQUAL == CompareVersion("3.", "3")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0", "3.15.0-2")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0-1", "3.15.0-2")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0.123", "3.15.0-2")); assert_true(VERSION_EQUAL == CompareVersion("3.15.0.123", "3.15.0.321")); assert_true(VERSION_GREATER == CompareVersion("4", "3")); assert_true(VERSION_GREATER == CompareVersion("3", "1")); assert_true(VERSION_GREATER == CompareVersion("4", "3.15")); assert_true(VERSION_GREATER == CompareVersion("4", "3.999")); assert_true(VERSION_GREATER == CompareVersion("4", "3.999.999")); assert_true(VERSION_GREATER == CompareVersion("4", "3.999.999-999")); assert_true(VERSION_GREATER == CompareVersion("3.16", "3.15")); assert_true(VERSION_GREATER == CompareVersion("3.16.0", "3.15.999")); assert_true(VERSION_GREATER == CompareVersion("3.16.0", "3.15")); assert_true(VERSION_GREATER == CompareVersion("3.15.1", "3.15.0")); assert_true(VERSION_GREATER == CompareVersion("3.15.10", "3.15.9")); assert_true(VERSION_GREATER == CompareVersion("3.10", "3.1")); assert_true(VERSION_GREATER == CompareVersion("3.100", "3.1")); assert_true(VERSION_SMALLER == CompareVersion("3", "4")); assert_true(VERSION_SMALLER == CompareVersion("1", "3")); assert_true(VERSION_SMALLER == CompareVersion("3.15", "4")); assert_true(VERSION_SMALLER == CompareVersion("3.999", "4")); assert_true(VERSION_SMALLER == CompareVersion("3.999.999", "4")); assert_true(VERSION_SMALLER == CompareVersion("3.999.999-999", "4")); assert_true(VERSION_SMALLER == CompareVersion("3.15", "3.16")); assert_true(VERSION_SMALLER == CompareVersion("3.15.999", "3.16.0")); assert_true(VERSION_SMALLER == CompareVersion("3.15", "3.16.0")); assert_true(VERSION_SMALLER == CompareVersion("3.15.0", "3.15.1")); assert_true(VERSION_SMALLER == CompareVersion("3.15.9", "3.15.10")); assert_true(VERSION_SMALLER == CompareVersion("3.1", "3.10")); assert_true(VERSION_SMALLER == CompareVersion("3.1", "3.100")); assert_true(VERSION_ERROR == CompareVersion("", "")); assert_true(VERSION_ERROR == CompareVersion("1", "")); assert_true(VERSION_ERROR == CompareVersion("", "1")); assert_true(VERSION_ERROR == CompareVersion("", "3.16.0")); } static void test_CompareVersionExpression(void) { assert_true(BOOLEAN_TRUE == CompareVersionExpression("1.2.3", "=", "1.2.3")); assert_true(BOOLEAN_TRUE == CompareVersionExpression("1.2.3", "==", "1.2.3")); assert_true(BOOLEAN_TRUE == CompareVersionExpression("1.2.3", "!=", "1.2.4")); assert_true(BOOLEAN_TRUE == CompareVersionExpression("100.0.0", ">", "99.0.0")); assert_true(BOOLEAN_TRUE == CompareVersionExpression("100.0.0", ">=", "99.0.0")); assert_true(BOOLEAN_TRUE == CompareVersionExpression("99.88.77", "<", "999.0.0")); assert_true(BOOLEAN_FALSE == CompareVersionExpression("1.2.3", "!=", "1.2.3")); assert_true(BOOLEAN_FALSE == CompareVersionExpression("1.2.3", "=", "1.2.4")); assert_true(BOOLEAN_FALSE == CompareVersionExpression("1.2.3", "==", "1.2.4")); assert_true(BOOLEAN_FALSE == CompareVersionExpression("100.0.0", "<=", "99.0.0")); assert_true(BOOLEAN_FALSE == CompareVersionExpression("100.0.0", "<", "99.0.0")); assert_true(BOOLEAN_FALSE == CompareVersionExpression("99.88.77", ">=", "999.0.0")); assert_true(BOOLEAN_ERROR == CompareVersionExpression("", "", "")); assert_true(BOOLEAN_ERROR == CompareVersionExpression("1", "2", "3")); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_CompareVersion), unit_test(test_CompareVersionExpression), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/gcov-stub.c0000644000000000000000000000154415010704254021346 0ustar00rootroot00000000000000#include #include /* * Stubs which allow CFEngine compiled with gcov support to link against unit * test code which has gcov disabled. */ void __gcov_init(ARG_UNUSED void *p) { } void __gcov_merge_add(ARG_UNUSED void *p, ARG_UNUSED unsigned n_counters) { } int __gcov_execv(const char *path, char *const argv[]) { return execv(path, argv); } int __gcov_execl(const char *path, char *arg, ...) { va_list ap, aq; unsigned i, length; char **args; va_start(ap, arg); va_copy(aq, ap); length = 2; while (va_arg(ap, char *)) length++; va_end(ap); args = (char **) xmalloc(length * sizeof(void *)); args[0] = arg; for (i = 1; i < length; i++) args[i] = va_arg(aq, char *); va_end(aq); return execv(path, args); } pid_t __gcov_fork(void) { return fork(); } cfengine-3.24.2/libntech/tests/unit/Makefile.in0000644000000000000000000045502415010704273021345 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @WITH_OPENSSL_TRUE@am__append_1 = \ @WITH_OPENSSL_TRUE@ ../../libutils/hash.c @WITH_OPENSSL_TRUE@am__append_2 = \ @WITH_OPENSSL_TRUE@ ../../libutils/encode.c @WITH_PCRE2_TRUE@am__append_3 = \ @WITH_PCRE2_TRUE@ ../../libutils/regex.c check_PROGRAMS = cleanup_test$(EXEEXT) condition_macros_test$(EXEEXT) \ csv_writer_test$(EXEEXT) set_test$(EXEEXT) \ csv_parser_test$(EXEEXT) env_file_test$(EXEEXT) \ alloc_test$(EXEEXT) string_writer_test$(EXEEXT) \ file_writer_test$(EXEEXT) xml_writer_test$(EXEEXT) \ sequence_test$(EXEEXT) json_test$(EXEEXT) \ misc_lib_test$(EXEEXT) string_lib_test$(EXEEXT) \ thread_test$(EXEEXT) file_lib_test$(EXEEXT) \ file_lock_test$(EXEEXT) map_test$(EXEEXT) path_test$(EXEEXT) \ logging_timestamp_test$(EXEEXT) refcount_test$(EXEEXT) \ list_test$(EXEEXT) buffer_test$(EXEEXT) \ ipaddress_test$(EXEEXT) rb-tree-test$(EXEEXT) \ queue_test$(EXEEXT) stack_test$(EXEEXT) \ threaded_queue_test$(EXEEXT) threaded_deque_test$(EXEEXT) \ threaded_stack_test$(EXEEXT) version_comparison_test$(EXEEXT) \ ring_buffer_test$(EXEEXT) libcompat_test$(EXEEXT) \ definitions_test$(EXEEXT) glob_lib_test$(EXEEXT) \ string_sequence_test$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) @WITH_PCRE2_TRUE@am__append_4 = \ @WITH_PCRE2_TRUE@ regex_test @WITH_OPENSSL_TRUE@am__append_5 = \ @WITH_OPENSSL_TRUE@ hash_test # ENABLE_COVERAGE is set in top-level configure.ac @ENABLE_COVERAGE_FALSE@am__append_6 = gcov-stub.c @WITH_PCRE2_TRUE@am__append_7 = \ @WITH_PCRE2_TRUE@ ../../libutils/regex.c @WITH_PCRE2_TRUE@am__append_8 = \ @WITH_PCRE2_TRUE@ ../../libutils/regex.c subdir = tests/unit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/tar.m4 \ $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = libstr_la_DEPENDENCIES = libtest.la am__libstr_la_SOURCES_DIST = ../../libutils/buffer.c \ ../../libutils/logging.c ../../libutils/misc_lib.c \ ../../libutils/sequence.c ../../libutils/string_lib.c \ ../../libutils/writer.c ../../libutils/encode.c \ ../../libutils/regex.c @WITH_OPENSSL_TRUE@am__objects_1 = encode.lo @WITH_PCRE2_TRUE@am__objects_2 = regex.lo am_libstr_la_OBJECTS = buffer.lo logging.lo misc_lib.lo sequence.lo \ string_lib.lo writer.lo $(am__objects_1) $(am__objects_2) libstr_la_OBJECTS = $(am_libstr_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__DEPENDENCIES_1 = libtest_la_DEPENDENCIES = ../../libcompat/libcompat.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__libtest_la_SOURCES_DIST = cmockery.c cmockery.h schema.h test.c \ test.h ../../libutils/alloc.c ../../libutils/known_dirs.c \ ../../libutils/map.c ../../libutils/array_map.c \ ../../libutils/hash_map.c ../../libutils/hash.c @WITH_OPENSSL_TRUE@am__objects_3 = hash.lo am_libtest_la_OBJECTS = cmockery.lo test.lo alloc.lo known_dirs.lo \ map.lo array_map.lo hash_map.lo $(am__objects_3) libtest_la_OBJECTS = $(am_libtest_la_OBJECTS) @WITH_PCRE2_TRUE@am__EXEEXT_1 = regex_test$(EXEEXT) @WITH_OPENSSL_TRUE@am__EXEEXT_2 = hash_test$(EXEEXT) alloc_test_SOURCES = alloc_test.c alloc_test_OBJECTS = alloc_test.$(OBJEXT) alloc_test_LDADD = $(LDADD) alloc_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_buffer_test_OBJECTS = buffer_test-buffer_test.$(OBJEXT) \ buffer_test-buffer.$(OBJEXT) buffer_test_OBJECTS = $(am_buffer_test_OBJECTS) buffer_test_LDADD = $(LDADD) buffer_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_cleanup_test_OBJECTS = cleanup_test.$(OBJEXT) cleanup_test_OBJECTS = $(am_cleanup_test_OBJECTS) cleanup_test_LDADD = $(LDADD) cleanup_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la condition_macros_test_SOURCES = condition_macros_test.c condition_macros_test_OBJECTS = condition_macros_test.$(OBJEXT) condition_macros_test_LDADD = $(LDADD) condition_macros_test_DEPENDENCIES = ../../libutils/libutils.la \ libtest.la am_csv_parser_test_OBJECTS = csv_parser_test.$(OBJEXT) \ csv_parser.$(OBJEXT) csv_parser_test_OBJECTS = $(am_csv_parser_test_OBJECTS) csv_parser_test_DEPENDENCIES = libtest.la ../../libutils/libutils.la am_csv_writer_test_OBJECTS = csv_writer_test.$(OBJEXT) \ csv_writer.$(OBJEXT) cleanup.$(OBJEXT) csv_writer_test_OBJECTS = $(am_csv_writer_test_OBJECTS) csv_writer_test_DEPENDENCIES = libtest.la libstr.la definitions_test_SOURCES = definitions_test.c definitions_test_OBJECTS = definitions_test.$(OBJEXT) definitions_test_LDADD = $(LDADD) definitions_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la env_file_test_SOURCES = env_file_test.c env_file_test_OBJECTS = env_file_test.$(OBJEXT) env_file_test_LDADD = $(LDADD) env_file_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am__file_lib_test_SOURCES_DIST = file_lib_test.c \ ../../libutils/file_lib.c ../../libutils/logging.c \ ../../libutils/misc_lib.c ../../libutils/path.c \ ../../libutils/string_lib.c ../../libutils/sequence.c \ ../../libutils/set.c ../../libutils/buffer.c \ ../../libutils/json.c ../../libutils/json-yaml.c \ ../../libutils/unix_dir.c ../../libutils/cleanup.c \ ../../libutils/writer.c ../../libutils/regex.c @WITH_PCRE2_TRUE@am__objects_4 = file_lib_test-regex.$(OBJEXT) am_file_lib_test_OBJECTS = file_lib_test-file_lib_test.$(OBJEXT) \ file_lib_test-file_lib.$(OBJEXT) \ file_lib_test-logging.$(OBJEXT) \ file_lib_test-misc_lib.$(OBJEXT) file_lib_test-path.$(OBJEXT) \ file_lib_test-string_lib.$(OBJEXT) \ file_lib_test-sequence.$(OBJEXT) file_lib_test-set.$(OBJEXT) \ file_lib_test-buffer.$(OBJEXT) file_lib_test-json.$(OBJEXT) \ file_lib_test-json-yaml.$(OBJEXT) \ file_lib_test-unix_dir.$(OBJEXT) \ file_lib_test-cleanup.$(OBJEXT) file_lib_test-writer.$(OBJEXT) \ $(am__objects_4) file_lib_test_OBJECTS = $(am_file_lib_test_OBJECTS) file_lib_test_DEPENDENCIES = libtest.la am_file_lock_test_OBJECTS = file_lock_test.$(OBJEXT) file_lock_test_OBJECTS = $(am_file_lock_test_OBJECTS) file_lock_test_DEPENDENCIES = ../../libutils/libutils.la am__file_writer_test_SOURCES_DIST = file_writer_test.c gcov-stub.c @ENABLE_COVERAGE_FALSE@am__objects_5 = gcov-stub.$(OBJEXT) am_file_writer_test_OBJECTS = file_writer_test.$(OBJEXT) \ $(am__objects_5) file_writer_test_OBJECTS = $(am_file_writer_test_OBJECTS) file_writer_test_LDADD = $(LDADD) file_writer_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_glob_lib_test_OBJECTS = glob_lib_test.$(OBJEXT) glob_lib_test_OBJECTS = $(am_glob_lib_test_OBJECTS) glob_lib_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_hash_test_OBJECTS = hash_test.$(OBJEXT) hash_test_OBJECTS = $(am_hash_test_OBJECTS) hash_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am__ipaddress_test_SOURCES_DIST = ipaddress_test.c \ ../../libutils/file_lib.c ../../libutils/logging.c \ ../../libutils/misc_lib.c ../../libutils/path.c \ ../../libutils/string_lib.c ../../libutils/sequence.c \ ../../libutils/set.c ../../libutils/buffer.c \ ../../libutils/json.c ../../libutils/json-yaml.c \ ../../libutils/unix_dir.c ../../libutils/cleanup.c \ ../../libutils/writer.c ../../libutils/regex.c @WITH_PCRE2_TRUE@am__objects_6 = ipaddress_test-regex.$(OBJEXT) am_ipaddress_test_OBJECTS = ipaddress_test-ipaddress_test.$(OBJEXT) \ ipaddress_test-file_lib.$(OBJEXT) \ ipaddress_test-logging.$(OBJEXT) \ ipaddress_test-misc_lib.$(OBJEXT) \ ipaddress_test-path.$(OBJEXT) \ ipaddress_test-string_lib.$(OBJEXT) \ ipaddress_test-sequence.$(OBJEXT) ipaddress_test-set.$(OBJEXT) \ ipaddress_test-buffer.$(OBJEXT) ipaddress_test-json.$(OBJEXT) \ ipaddress_test-json-yaml.$(OBJEXT) \ ipaddress_test-unix_dir.$(OBJEXT) \ ipaddress_test-cleanup.$(OBJEXT) \ ipaddress_test-writer.$(OBJEXT) $(am__objects_6) ipaddress_test_OBJECTS = $(am_ipaddress_test_OBJECTS) ipaddress_test_DEPENDENCIES = libtest.la json_test_SOURCES = json_test.c json_test_OBJECTS = json_test.$(OBJEXT) json_test_LDADD = $(LDADD) json_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_libcompat_test_OBJECTS = libcompat_test-libcompat_test.$(OBJEXT) libcompat_test_OBJECTS = $(am_libcompat_test_OBJECTS) libcompat_test_LDADD = $(LDADD) libcompat_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_list_test_OBJECTS = list_test.$(OBJEXT) list_test_OBJECTS = $(am_list_test_OBJECTS) list_test_LDADD = $(LDADD) list_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_logging_timestamp_test_OBJECTS = logging_timestamp_test.$(OBJEXT) logging_timestamp_test_OBJECTS = $(am_logging_timestamp_test_OBJECTS) logging_timestamp_test_DEPENDENCIES = libtest.la \ ../../libutils/libutils.la map_test_SOURCES = map_test.c map_test_OBJECTS = map_test.$(OBJEXT) map_test_LDADD = $(LDADD) map_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la misc_lib_test_SOURCES = misc_lib_test.c misc_lib_test_OBJECTS = misc_lib_test-misc_lib_test.$(OBJEXT) misc_lib_test_LDADD = $(LDADD) misc_lib_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la misc_lib_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(misc_lib_test_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ path_test_SOURCES = path_test.c path_test_OBJECTS = path_test.$(OBJEXT) path_test_LDADD = $(LDADD) path_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_queue_test_OBJECTS = queue_test.$(OBJEXT) queue_test_OBJECTS = $(am_queue_test_OBJECTS) queue_test_LDADD = $(LDADD) queue_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la rb_tree_test_SOURCES = rb-tree-test.c rb_tree_test_OBJECTS = rb-tree-test.$(OBJEXT) rb_tree_test_LDADD = $(LDADD) rb_tree_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_refcount_test_OBJECTS = refcount_test.$(OBJEXT) refcount.$(OBJEXT) refcount_test_OBJECTS = $(am_refcount_test_OBJECTS) refcount_test_LDADD = $(LDADD) refcount_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la regex_test_SOURCES = regex_test.c regex_test_OBJECTS = regex_test.$(OBJEXT) regex_test_LDADD = $(LDADD) regex_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la ring_buffer_test_SOURCES = ring_buffer_test.c ring_buffer_test_OBJECTS = ring_buffer_test.$(OBJEXT) ring_buffer_test_LDADD = $(LDADD) ring_buffer_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la sequence_test_SOURCES = sequence_test.c sequence_test_OBJECTS = sequence_test.$(OBJEXT) sequence_test_LDADD = $(LDADD) sequence_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la set_test_SOURCES = set_test.c set_test_OBJECTS = set_test.$(OBJEXT) set_test_LDADD = $(LDADD) set_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_stack_test_OBJECTS = stack_test.$(OBJEXT) stack_test_OBJECTS = $(am_stack_test_OBJECTS) stack_test_LDADD = $(LDADD) stack_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la string_lib_test_SOURCES = string_lib_test.c string_lib_test_OBJECTS = string_lib_test.$(OBJEXT) string_lib_test_LDADD = $(LDADD) string_lib_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_string_sequence_test_OBJECTS = string_sequence_test.$(OBJEXT) string_sequence_test_OBJECTS = $(am_string_sequence_test_OBJECTS) string_sequence_test_DEPENDENCIES = ../../libutils/libutils.la \ libtest.la string_writer_test_SOURCES = string_writer_test.c string_writer_test_OBJECTS = string_writer_test.$(OBJEXT) string_writer_test_LDADD = $(LDADD) string_writer_test_DEPENDENCIES = ../../libutils/libutils.la \ libtest.la thread_test_SOURCES = thread_test.c thread_test_OBJECTS = thread_test.$(OBJEXT) thread_test_LDADD = $(LDADD) thread_test_DEPENDENCIES = ../../libutils/libutils.la libtest.la am_threaded_deque_test_OBJECTS = threaded_deque_test.$(OBJEXT) threaded_deque_test_OBJECTS = $(am_threaded_deque_test_OBJECTS) threaded_deque_test_LDADD = $(LDADD) threaded_deque_test_DEPENDENCIES = ../../libutils/libutils.la \ libtest.la am_threaded_queue_test_OBJECTS = threaded_queue_test.$(OBJEXT) threaded_queue_test_OBJECTS = $(am_threaded_queue_test_OBJECTS) threaded_queue_test_LDADD = $(LDADD) threaded_queue_test_DEPENDENCIES = ../../libutils/libutils.la \ libtest.la am_threaded_stack_test_OBJECTS = threaded_stack_test.$(OBJEXT) threaded_stack_test_OBJECTS = $(am_threaded_stack_test_OBJECTS) threaded_stack_test_LDADD = $(LDADD) threaded_stack_test_DEPENDENCIES = ../../libutils/libutils.la \ libtest.la version_comparison_test_SOURCES = version_comparison_test.c version_comparison_test_OBJECTS = version_comparison_test.$(OBJEXT) version_comparison_test_LDADD = $(LDADD) version_comparison_test_DEPENDENCIES = ../../libutils/libutils.la \ libtest.la am_xml_writer_test_OBJECTS = xml_writer_test.$(OBJEXT) \ xml_writer.$(OBJEXT) cleanup.$(OBJEXT) xml_writer_test_OBJECTS = $(am_xml_writer_test_OBJECTS) xml_writer_test_DEPENDENCIES = libtest.la libstr.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libstr_la_SOURCES) $(libtest_la_SOURCES) alloc_test.c \ $(buffer_test_SOURCES) $(cleanup_test_SOURCES) \ condition_macros_test.c $(csv_parser_test_SOURCES) \ $(csv_writer_test_SOURCES) definitions_test.c env_file_test.c \ $(file_lib_test_SOURCES) $(file_lock_test_SOURCES) \ $(file_writer_test_SOURCES) $(glob_lib_test_SOURCES) \ $(hash_test_SOURCES) $(ipaddress_test_SOURCES) json_test.c \ $(libcompat_test_SOURCES) $(list_test_SOURCES) \ $(logging_timestamp_test_SOURCES) map_test.c misc_lib_test.c \ path_test.c $(queue_test_SOURCES) rb-tree-test.c \ $(refcount_test_SOURCES) regex_test.c ring_buffer_test.c \ sequence_test.c set_test.c $(stack_test_SOURCES) \ string_lib_test.c $(string_sequence_test_SOURCES) \ string_writer_test.c thread_test.c \ $(threaded_deque_test_SOURCES) $(threaded_queue_test_SOURCES) \ $(threaded_stack_test_SOURCES) version_comparison_test.c \ $(xml_writer_test_SOURCES) DIST_SOURCES = $(am__libstr_la_SOURCES_DIST) \ $(am__libtest_la_SOURCES_DIST) alloc_test.c \ $(buffer_test_SOURCES) $(cleanup_test_SOURCES) \ condition_macros_test.c $(csv_parser_test_SOURCES) \ $(csv_writer_test_SOURCES) definitions_test.c env_file_test.c \ $(am__file_lib_test_SOURCES_DIST) $(file_lock_test_SOURCES) \ $(am__file_writer_test_SOURCES_DIST) $(glob_lib_test_SOURCES) \ $(hash_test_SOURCES) $(am__ipaddress_test_SOURCES_DIST) \ json_test.c $(libcompat_test_SOURCES) $(list_test_SOURCES) \ $(logging_timestamp_test_SOURCES) map_test.c misc_lib_test.c \ path_test.c $(queue_test_SOURCES) rb-tree-test.c \ $(refcount_test_SOURCES) regex_test.c ring_buffer_test.c \ sequence_test.c set_test.c $(stack_test_SOURCES) \ string_lib_test.c $(string_sequence_test_SOURCES) \ string_writer_test.c thread_test.c \ $(threaded_deque_test_SOURCES) $(threaded_queue_test_SOURCES) \ $(threaded_stack_test_SOURCES) version_comparison_test.c \ $(xml_writer_test_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GREP = @GREP@ HAVE_CLOCKID_T_DEFINE = @HAVE_CLOCKID_T_DEFINE@ HAVE_GETOPT_H_DEFINE = @HAVE_GETOPT_H_DEFINE@ HAVE_LIBYAML_DEFINE = @HAVE_LIBYAML_DEFINE@ HOSTNAME = @HOSTNAME@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ # automake does not support "maude_LIBS" variables. We can only alter # the generic LIBS one. In case the functions are mocked in the test # implementation, then we are pretty sure that they will be overriden by # our local implementation. So we include *everything*... LIBS = $(CORE_LIBS) LIBTOOL = @LIBTOOL@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NO_TAUTOLOGICAL_CC_OPTION = @NO_TAUTOLOGICAL_CC_OPTION@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_LOGGING_CFLAGS = @SYSTEMD_LOGGING_CFLAGS@ SYSTEMD_LOGGING_CPPFLAGS = @SYSTEMD_LOGGING_CPPFLAGS@ SYSTEMD_LOGGING_LDFLAGS = @SYSTEMD_LOGGING_LDFLAGS@ SYSTEMD_LOGGING_LIBS = @SYSTEMD_LOGGING_LIBS@ SYSTEMD_LOGGING_PATH = @SYSTEMD_LOGGING_PATH@ VERSION = @VERSION@ WITH_PCRE2_DEFINE = @WITH_PCRE2_DEFINE@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Just recursively include in dist tarball all data we need for unit tests EXTRA_DIST = data AM_CPPFLAGS = $(CORE_CPPFLAGS) \ $(ENTERPRISE_CFLAGS) \ -I$(srcdir)/../../libutils \ -DTESTDATADIR='"$(srcdir)/data"' LDADD = ../../libutils/libutils.la libtest.la AM_LDFLAGS = $(CORE_LDFLAGS) AM_CFLAGS = $(CORE_CFLAGS) $(PTHREAD_CFLAGS) check_LTLIBRARIES = libtest.la libstr.la libtest_la_SOURCES = cmockery.c cmockery.h schema.h test.c test.h \ ../../libutils/alloc.c ../../libutils/known_dirs.c \ ../../libutils/map.c ../../libutils/array_map.c \ ../../libutils/hash_map.c $(am__append_1) libtest_la_LIBADD = ../../libcompat/libcompat.la $(PCRE_LIBS) $(OPENSSL_LIBS) $(SYSTEMD_LOGGING_LIBS) $(LIBYAML_LIBS) libstr_la_SOURCES = ../../libutils/buffer.c ../../libutils/logging.c \ ../../libutils/misc_lib.c ../../libutils/sequence.c \ ../../libutils/string_lib.c ../../libutils/writer.c \ $(am__append_2) $(am__append_3) libstr_la_LIBADD = libtest.la TESTS = $(check_PROGRAMS) # # OS X uses real system calls instead of our stubs unless this option is used # TESTS_ENVIRONMENT = DYLD_FORCE_FLAT_NAMESPACE=yes cleanup_test_SOURCES = cleanup_test.c csv_writer_test_SOURCES = csv_writer_test.c ../../libutils/csv_writer.c \ ../../libutils/cleanup.c csv_writer_test_LDADD = libtest.la libstr.la xml_writer_test_SOURCES = xml_writer_test.c \ ../../libutils/xml_writer.c \ ../../libutils/cleanup.c xml_writer_test_LDADD = libtest.la libstr.la list_test_SOURCES = list_test.c refcount_test_SOURCES = refcount_test.c ../../libutils/refcount.c buffer_test_SOURCES = buffer_test.c ../../libutils/buffer.c # Workaround for object file basename conflicts, search the web for # "automake created with both libtool and without" buffer_test_CPPFLAGS = $(AM_CPPFLAGS) csv_parser_test_SOURCES = csv_parser_test.c ../../libutils/csv_parser.c csv_parser_test_LDADD = libtest.la ../../libutils/libutils.la #file_writer_test_CPPFLAGS = -I$(top_srcdir)/libutils file_writer_test_SOURCES = file_writer_test.c $(am__append_6) CLEANFILES = *.gcno *.gcda cfengine-enterprise.so file_lib_test_SOURCES = file_lib_test.c ../../libutils/file_lib.c \ ../../libutils/logging.c ../../libutils/misc_lib.c \ ../../libutils/path.c ../../libutils/string_lib.c \ ../../libutils/sequence.c ../../libutils/set.c \ ../../libutils/buffer.c ../../libutils/json.c \ ../../libutils/json-yaml.c ../../libutils/unix_dir.c \ ../../libutils/cleanup.c ../../libutils/writer.c \ $(am__append_7) file_lib_test_LDADD = libtest.la file_lib_test_CPPFLAGS = $(AM_CPPFLAGS) -DTEST_SYMLINK_ATOMICITY ipaddress_test_SOURCES = ipaddress_test.c ../../libutils/file_lib.c \ ../../libutils/logging.c ../../libutils/misc_lib.c \ ../../libutils/path.c ../../libutils/string_lib.c \ ../../libutils/sequence.c ../../libutils/set.c \ ../../libutils/buffer.c ../../libutils/json.c \ ../../libutils/json-yaml.c ../../libutils/unix_dir.c \ ../../libutils/cleanup.c ../../libutils/writer.c \ $(am__append_8) ipaddress_test_LDADD = libtest.la ipaddress_test_CPPFLAGS = $(AM_CPPFLAGS) logging_timestamp_test_SOURCES = logging_timestamp_test.c \ ../../libutils/logging.h logging_timestamp_test_LDADD = libtest.la ../../libutils/libutils.la hash_test_SOURCES = hash_test.c hash_test_LDADD = ../../libutils/libutils.la libtest.la libcompat_test_CPPFLAGS = -I$(top_srcdir)/libcompat -I$(top_srcdir)/libutils libcompat_test_SOURCES = libcompat_test.c # Silence some warnings about generated comparisions always being false: # (The test generates some comparisons which compare an int to something # bigger than INT_MAX) misc_lib_test_CFLAGS = $(AM_CFLAGS) $(NO_TAUTOLOGICAL_CC_OPTION) queue_test_SOURCES = queue_test.c stack_test_SOURCES = stack_test.c threaded_queue_test_SOURCES = threaded_queue_test.c threaded_deque_test_SOURCES = threaded_deque_test.c threaded_stack_test_SOURCES = threaded_stack_test.c file_lock_test_SOURCES = file_lock_test.c file_lock_test_LDADD = ../../libutils/libutils.la glob_lib_test_SOURCES = glob_lib_test.c glob_lib_test_LDADD = ../../libutils/libutils.la libtest.la string_sequence_test_SOURCES = string_sequence_test.c string_sequence_test_LDADD = ../../libutils/libutils.la libtest.la all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/unit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/unit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libstr.la: $(libstr_la_OBJECTS) $(libstr_la_DEPENDENCIES) $(EXTRA_libstr_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libstr_la_OBJECTS) $(libstr_la_LIBADD) $(LIBS) libtest.la: $(libtest_la_OBJECTS) $(libtest_la_DEPENDENCIES) $(EXTRA_libtest_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libtest_la_OBJECTS) $(libtest_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list alloc_test$(EXEEXT): $(alloc_test_OBJECTS) $(alloc_test_DEPENDENCIES) $(EXTRA_alloc_test_DEPENDENCIES) @rm -f alloc_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(alloc_test_OBJECTS) $(alloc_test_LDADD) $(LIBS) buffer_test$(EXEEXT): $(buffer_test_OBJECTS) $(buffer_test_DEPENDENCIES) $(EXTRA_buffer_test_DEPENDENCIES) @rm -f buffer_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(buffer_test_OBJECTS) $(buffer_test_LDADD) $(LIBS) cleanup_test$(EXEEXT): $(cleanup_test_OBJECTS) $(cleanup_test_DEPENDENCIES) $(EXTRA_cleanup_test_DEPENDENCIES) @rm -f cleanup_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cleanup_test_OBJECTS) $(cleanup_test_LDADD) $(LIBS) condition_macros_test$(EXEEXT): $(condition_macros_test_OBJECTS) $(condition_macros_test_DEPENDENCIES) $(EXTRA_condition_macros_test_DEPENDENCIES) @rm -f condition_macros_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(condition_macros_test_OBJECTS) $(condition_macros_test_LDADD) $(LIBS) csv_parser_test$(EXEEXT): $(csv_parser_test_OBJECTS) $(csv_parser_test_DEPENDENCIES) $(EXTRA_csv_parser_test_DEPENDENCIES) @rm -f csv_parser_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(csv_parser_test_OBJECTS) $(csv_parser_test_LDADD) $(LIBS) csv_writer_test$(EXEEXT): $(csv_writer_test_OBJECTS) $(csv_writer_test_DEPENDENCIES) $(EXTRA_csv_writer_test_DEPENDENCIES) @rm -f csv_writer_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(csv_writer_test_OBJECTS) $(csv_writer_test_LDADD) $(LIBS) definitions_test$(EXEEXT): $(definitions_test_OBJECTS) $(definitions_test_DEPENDENCIES) $(EXTRA_definitions_test_DEPENDENCIES) @rm -f definitions_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(definitions_test_OBJECTS) $(definitions_test_LDADD) $(LIBS) env_file_test$(EXEEXT): $(env_file_test_OBJECTS) $(env_file_test_DEPENDENCIES) $(EXTRA_env_file_test_DEPENDENCIES) @rm -f env_file_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(env_file_test_OBJECTS) $(env_file_test_LDADD) $(LIBS) file_lib_test$(EXEEXT): $(file_lib_test_OBJECTS) $(file_lib_test_DEPENDENCIES) $(EXTRA_file_lib_test_DEPENDENCIES) @rm -f file_lib_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(file_lib_test_OBJECTS) $(file_lib_test_LDADD) $(LIBS) file_lock_test$(EXEEXT): $(file_lock_test_OBJECTS) $(file_lock_test_DEPENDENCIES) $(EXTRA_file_lock_test_DEPENDENCIES) @rm -f file_lock_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(file_lock_test_OBJECTS) $(file_lock_test_LDADD) $(LIBS) file_writer_test$(EXEEXT): $(file_writer_test_OBJECTS) $(file_writer_test_DEPENDENCIES) $(EXTRA_file_writer_test_DEPENDENCIES) @rm -f file_writer_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(file_writer_test_OBJECTS) $(file_writer_test_LDADD) $(LIBS) glob_lib_test$(EXEEXT): $(glob_lib_test_OBJECTS) $(glob_lib_test_DEPENDENCIES) $(EXTRA_glob_lib_test_DEPENDENCIES) @rm -f glob_lib_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(glob_lib_test_OBJECTS) $(glob_lib_test_LDADD) $(LIBS) hash_test$(EXEEXT): $(hash_test_OBJECTS) $(hash_test_DEPENDENCIES) $(EXTRA_hash_test_DEPENDENCIES) @rm -f hash_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(hash_test_OBJECTS) $(hash_test_LDADD) $(LIBS) ipaddress_test$(EXEEXT): $(ipaddress_test_OBJECTS) $(ipaddress_test_DEPENDENCIES) $(EXTRA_ipaddress_test_DEPENDENCIES) @rm -f ipaddress_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(ipaddress_test_OBJECTS) $(ipaddress_test_LDADD) $(LIBS) json_test$(EXEEXT): $(json_test_OBJECTS) $(json_test_DEPENDENCIES) $(EXTRA_json_test_DEPENDENCIES) @rm -f json_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(json_test_OBJECTS) $(json_test_LDADD) $(LIBS) libcompat_test$(EXEEXT): $(libcompat_test_OBJECTS) $(libcompat_test_DEPENDENCIES) $(EXTRA_libcompat_test_DEPENDENCIES) @rm -f libcompat_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(libcompat_test_OBJECTS) $(libcompat_test_LDADD) $(LIBS) list_test$(EXEEXT): $(list_test_OBJECTS) $(list_test_DEPENDENCIES) $(EXTRA_list_test_DEPENDENCIES) @rm -f list_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(list_test_OBJECTS) $(list_test_LDADD) $(LIBS) logging_timestamp_test$(EXEEXT): $(logging_timestamp_test_OBJECTS) $(logging_timestamp_test_DEPENDENCIES) $(EXTRA_logging_timestamp_test_DEPENDENCIES) @rm -f logging_timestamp_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(logging_timestamp_test_OBJECTS) $(logging_timestamp_test_LDADD) $(LIBS) map_test$(EXEEXT): $(map_test_OBJECTS) $(map_test_DEPENDENCIES) $(EXTRA_map_test_DEPENDENCIES) @rm -f map_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(map_test_OBJECTS) $(map_test_LDADD) $(LIBS) misc_lib_test$(EXEEXT): $(misc_lib_test_OBJECTS) $(misc_lib_test_DEPENDENCIES) $(EXTRA_misc_lib_test_DEPENDENCIES) @rm -f misc_lib_test$(EXEEXT) $(AM_V_CCLD)$(misc_lib_test_LINK) $(misc_lib_test_OBJECTS) $(misc_lib_test_LDADD) $(LIBS) path_test$(EXEEXT): $(path_test_OBJECTS) $(path_test_DEPENDENCIES) $(EXTRA_path_test_DEPENDENCIES) @rm -f path_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(path_test_OBJECTS) $(path_test_LDADD) $(LIBS) queue_test$(EXEEXT): $(queue_test_OBJECTS) $(queue_test_DEPENDENCIES) $(EXTRA_queue_test_DEPENDENCIES) @rm -f queue_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(queue_test_OBJECTS) $(queue_test_LDADD) $(LIBS) rb-tree-test$(EXEEXT): $(rb_tree_test_OBJECTS) $(rb_tree_test_DEPENDENCIES) $(EXTRA_rb_tree_test_DEPENDENCIES) @rm -f rb-tree-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rb_tree_test_OBJECTS) $(rb_tree_test_LDADD) $(LIBS) refcount_test$(EXEEXT): $(refcount_test_OBJECTS) $(refcount_test_DEPENDENCIES) $(EXTRA_refcount_test_DEPENDENCIES) @rm -f refcount_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(refcount_test_OBJECTS) $(refcount_test_LDADD) $(LIBS) regex_test$(EXEEXT): $(regex_test_OBJECTS) $(regex_test_DEPENDENCIES) $(EXTRA_regex_test_DEPENDENCIES) @rm -f regex_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(regex_test_OBJECTS) $(regex_test_LDADD) $(LIBS) ring_buffer_test$(EXEEXT): $(ring_buffer_test_OBJECTS) $(ring_buffer_test_DEPENDENCIES) $(EXTRA_ring_buffer_test_DEPENDENCIES) @rm -f ring_buffer_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(ring_buffer_test_OBJECTS) $(ring_buffer_test_LDADD) $(LIBS) sequence_test$(EXEEXT): $(sequence_test_OBJECTS) $(sequence_test_DEPENDENCIES) $(EXTRA_sequence_test_DEPENDENCIES) @rm -f sequence_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sequence_test_OBJECTS) $(sequence_test_LDADD) $(LIBS) set_test$(EXEEXT): $(set_test_OBJECTS) $(set_test_DEPENDENCIES) $(EXTRA_set_test_DEPENDENCIES) @rm -f set_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(set_test_OBJECTS) $(set_test_LDADD) $(LIBS) stack_test$(EXEEXT): $(stack_test_OBJECTS) $(stack_test_DEPENDENCIES) $(EXTRA_stack_test_DEPENDENCIES) @rm -f stack_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(stack_test_OBJECTS) $(stack_test_LDADD) $(LIBS) string_lib_test$(EXEEXT): $(string_lib_test_OBJECTS) $(string_lib_test_DEPENDENCIES) $(EXTRA_string_lib_test_DEPENDENCIES) @rm -f string_lib_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(string_lib_test_OBJECTS) $(string_lib_test_LDADD) $(LIBS) string_sequence_test$(EXEEXT): $(string_sequence_test_OBJECTS) $(string_sequence_test_DEPENDENCIES) $(EXTRA_string_sequence_test_DEPENDENCIES) @rm -f string_sequence_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(string_sequence_test_OBJECTS) $(string_sequence_test_LDADD) $(LIBS) string_writer_test$(EXEEXT): $(string_writer_test_OBJECTS) $(string_writer_test_DEPENDENCIES) $(EXTRA_string_writer_test_DEPENDENCIES) @rm -f string_writer_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(string_writer_test_OBJECTS) $(string_writer_test_LDADD) $(LIBS) thread_test$(EXEEXT): $(thread_test_OBJECTS) $(thread_test_DEPENDENCIES) $(EXTRA_thread_test_DEPENDENCIES) @rm -f thread_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(thread_test_OBJECTS) $(thread_test_LDADD) $(LIBS) threaded_deque_test$(EXEEXT): $(threaded_deque_test_OBJECTS) $(threaded_deque_test_DEPENDENCIES) $(EXTRA_threaded_deque_test_DEPENDENCIES) @rm -f threaded_deque_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(threaded_deque_test_OBJECTS) $(threaded_deque_test_LDADD) $(LIBS) threaded_queue_test$(EXEEXT): $(threaded_queue_test_OBJECTS) $(threaded_queue_test_DEPENDENCIES) $(EXTRA_threaded_queue_test_DEPENDENCIES) @rm -f threaded_queue_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(threaded_queue_test_OBJECTS) $(threaded_queue_test_LDADD) $(LIBS) threaded_stack_test$(EXEEXT): $(threaded_stack_test_OBJECTS) $(threaded_stack_test_DEPENDENCIES) $(EXTRA_threaded_stack_test_DEPENDENCIES) @rm -f threaded_stack_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(threaded_stack_test_OBJECTS) $(threaded_stack_test_LDADD) $(LIBS) version_comparison_test$(EXEEXT): $(version_comparison_test_OBJECTS) $(version_comparison_test_DEPENDENCIES) $(EXTRA_version_comparison_test_DEPENDENCIES) @rm -f version_comparison_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(version_comparison_test_OBJECTS) $(version_comparison_test_LDADD) $(LIBS) xml_writer_test$(EXEEXT): $(xml_writer_test_OBJECTS) $(xml_writer_test_DEPENDENCIES) $(EXTRA_xml_writer_test_DEPENDENCIES) @rm -f xml_writer_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(xml_writer_test_OBJECTS) $(xml_writer_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer_test-buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer_test-buffer_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cleanup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cleanup_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmockery.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/condition_macros_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv_parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv_parser_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv_writer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv_writer_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/definitions_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env_file_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-cleanup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-file_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-file_lib_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-json-yaml.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-json.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-logging.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-misc_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-path.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-regex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-sequence.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-set.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-string_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-unix_dir.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib_test-writer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lock_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_writer_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcov-stub.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glob_lib_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-buffer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-cleanup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-file_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-ipaddress_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-json-yaml.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-json.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-logging.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-misc_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-path.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-regex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-sequence.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-set.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-string_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-unix_dir.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipaddress_test-writer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/known_dirs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcompat_test-libcompat_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging_timestamp_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc_lib_test-misc_lib_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/queue_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-tree-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refcount.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refcount_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ring_buffer_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sequence.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sequence_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_lib_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_sequence_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_writer_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threaded_deque_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threaded_queue_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threaded_stack_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version_comparison_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_writer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_writer_test.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< buffer.lo: ../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT buffer.lo -MD -MP -MF $(DEPDIR)/buffer.Tpo -c -o buffer.lo `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/buffer.Tpo $(DEPDIR)/buffer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/buffer.c' object='buffer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o buffer.lo `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c logging.lo: ../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT logging.lo -MD -MP -MF $(DEPDIR)/logging.Tpo -c -o logging.lo `test -f '../../libutils/logging.c' || echo '$(srcdir)/'`../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/logging.Tpo $(DEPDIR)/logging.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/logging.c' object='logging.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o logging.lo `test -f '../../libutils/logging.c' || echo '$(srcdir)/'`../../libutils/logging.c misc_lib.lo: ../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT misc_lib.lo -MD -MP -MF $(DEPDIR)/misc_lib.Tpo -c -o misc_lib.lo `test -f '../../libutils/misc_lib.c' || echo '$(srcdir)/'`../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/misc_lib.Tpo $(DEPDIR)/misc_lib.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/misc_lib.c' object='misc_lib.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o misc_lib.lo `test -f '../../libutils/misc_lib.c' || echo '$(srcdir)/'`../../libutils/misc_lib.c sequence.lo: ../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sequence.lo -MD -MP -MF $(DEPDIR)/sequence.Tpo -c -o sequence.lo `test -f '../../libutils/sequence.c' || echo '$(srcdir)/'`../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sequence.Tpo $(DEPDIR)/sequence.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/sequence.c' object='sequence.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sequence.lo `test -f '../../libutils/sequence.c' || echo '$(srcdir)/'`../../libutils/sequence.c string_lib.lo: ../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string_lib.lo -MD -MP -MF $(DEPDIR)/string_lib.Tpo -c -o string_lib.lo `test -f '../../libutils/string_lib.c' || echo '$(srcdir)/'`../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/string_lib.Tpo $(DEPDIR)/string_lib.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/string_lib.c' object='string_lib.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string_lib.lo `test -f '../../libutils/string_lib.c' || echo '$(srcdir)/'`../../libutils/string_lib.c writer.lo: ../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT writer.lo -MD -MP -MF $(DEPDIR)/writer.Tpo -c -o writer.lo `test -f '../../libutils/writer.c' || echo '$(srcdir)/'`../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/writer.Tpo $(DEPDIR)/writer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/writer.c' object='writer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o writer.lo `test -f '../../libutils/writer.c' || echo '$(srcdir)/'`../../libutils/writer.c encode.lo: ../../libutils/encode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT encode.lo -MD -MP -MF $(DEPDIR)/encode.Tpo -c -o encode.lo `test -f '../../libutils/encode.c' || echo '$(srcdir)/'`../../libutils/encode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/encode.Tpo $(DEPDIR)/encode.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/encode.c' object='encode.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o encode.lo `test -f '../../libutils/encode.c' || echo '$(srcdir)/'`../../libutils/encode.c regex.lo: ../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT regex.lo -MD -MP -MF $(DEPDIR)/regex.Tpo -c -o regex.lo `test -f '../../libutils/regex.c' || echo '$(srcdir)/'`../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/regex.Tpo $(DEPDIR)/regex.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/regex.c' object='regex.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o regex.lo `test -f '../../libutils/regex.c' || echo '$(srcdir)/'`../../libutils/regex.c alloc.lo: ../../libutils/alloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT alloc.lo -MD -MP -MF $(DEPDIR)/alloc.Tpo -c -o alloc.lo `test -f '../../libutils/alloc.c' || echo '$(srcdir)/'`../../libutils/alloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/alloc.Tpo $(DEPDIR)/alloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/alloc.c' object='alloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o alloc.lo `test -f '../../libutils/alloc.c' || echo '$(srcdir)/'`../../libutils/alloc.c known_dirs.lo: ../../libutils/known_dirs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT known_dirs.lo -MD -MP -MF $(DEPDIR)/known_dirs.Tpo -c -o known_dirs.lo `test -f '../../libutils/known_dirs.c' || echo '$(srcdir)/'`../../libutils/known_dirs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/known_dirs.Tpo $(DEPDIR)/known_dirs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/known_dirs.c' object='known_dirs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o known_dirs.lo `test -f '../../libutils/known_dirs.c' || echo '$(srcdir)/'`../../libutils/known_dirs.c map.lo: ../../libutils/map.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT map.lo -MD -MP -MF $(DEPDIR)/map.Tpo -c -o map.lo `test -f '../../libutils/map.c' || echo '$(srcdir)/'`../../libutils/map.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/map.Tpo $(DEPDIR)/map.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/map.c' object='map.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o map.lo `test -f '../../libutils/map.c' || echo '$(srcdir)/'`../../libutils/map.c array_map.lo: ../../libutils/array_map.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT array_map.lo -MD -MP -MF $(DEPDIR)/array_map.Tpo -c -o array_map.lo `test -f '../../libutils/array_map.c' || echo '$(srcdir)/'`../../libutils/array_map.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/array_map.Tpo $(DEPDIR)/array_map.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/array_map.c' object='array_map.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o array_map.lo `test -f '../../libutils/array_map.c' || echo '$(srcdir)/'`../../libutils/array_map.c hash_map.lo: ../../libutils/hash_map.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hash_map.lo -MD -MP -MF $(DEPDIR)/hash_map.Tpo -c -o hash_map.lo `test -f '../../libutils/hash_map.c' || echo '$(srcdir)/'`../../libutils/hash_map.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hash_map.Tpo $(DEPDIR)/hash_map.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/hash_map.c' object='hash_map.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hash_map.lo `test -f '../../libutils/hash_map.c' || echo '$(srcdir)/'`../../libutils/hash_map.c hash.lo: ../../libutils/hash.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hash.lo -MD -MP -MF $(DEPDIR)/hash.Tpo -c -o hash.lo `test -f '../../libutils/hash.c' || echo '$(srcdir)/'`../../libutils/hash.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hash.Tpo $(DEPDIR)/hash.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/hash.c' object='hash.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hash.lo `test -f '../../libutils/hash.c' || echo '$(srcdir)/'`../../libutils/hash.c buffer_test-buffer_test.o: buffer_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT buffer_test-buffer_test.o -MD -MP -MF $(DEPDIR)/buffer_test-buffer_test.Tpo -c -o buffer_test-buffer_test.o `test -f 'buffer_test.c' || echo '$(srcdir)/'`buffer_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/buffer_test-buffer_test.Tpo $(DEPDIR)/buffer_test-buffer_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buffer_test.c' object='buffer_test-buffer_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o buffer_test-buffer_test.o `test -f 'buffer_test.c' || echo '$(srcdir)/'`buffer_test.c buffer_test-buffer_test.obj: buffer_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT buffer_test-buffer_test.obj -MD -MP -MF $(DEPDIR)/buffer_test-buffer_test.Tpo -c -o buffer_test-buffer_test.obj `if test -f 'buffer_test.c'; then $(CYGPATH_W) 'buffer_test.c'; else $(CYGPATH_W) '$(srcdir)/buffer_test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/buffer_test-buffer_test.Tpo $(DEPDIR)/buffer_test-buffer_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='buffer_test.c' object='buffer_test-buffer_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o buffer_test-buffer_test.obj `if test -f 'buffer_test.c'; then $(CYGPATH_W) 'buffer_test.c'; else $(CYGPATH_W) '$(srcdir)/buffer_test.c'; fi` buffer_test-buffer.o: ../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT buffer_test-buffer.o -MD -MP -MF $(DEPDIR)/buffer_test-buffer.Tpo -c -o buffer_test-buffer.o `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/buffer_test-buffer.Tpo $(DEPDIR)/buffer_test-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/buffer.c' object='buffer_test-buffer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o buffer_test-buffer.o `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c buffer_test-buffer.obj: ../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT buffer_test-buffer.obj -MD -MP -MF $(DEPDIR)/buffer_test-buffer.Tpo -c -o buffer_test-buffer.obj `if test -f '../../libutils/buffer.c'; then $(CYGPATH_W) '../../libutils/buffer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/buffer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/buffer_test-buffer.Tpo $(DEPDIR)/buffer_test-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/buffer.c' object='buffer_test-buffer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(buffer_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o buffer_test-buffer.obj `if test -f '../../libutils/buffer.c'; then $(CYGPATH_W) '../../libutils/buffer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/buffer.c'; fi` csv_parser.o: ../../libutils/csv_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT csv_parser.o -MD -MP -MF $(DEPDIR)/csv_parser.Tpo -c -o csv_parser.o `test -f '../../libutils/csv_parser.c' || echo '$(srcdir)/'`../../libutils/csv_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/csv_parser.Tpo $(DEPDIR)/csv_parser.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/csv_parser.c' object='csv_parser.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o csv_parser.o `test -f '../../libutils/csv_parser.c' || echo '$(srcdir)/'`../../libutils/csv_parser.c csv_parser.obj: ../../libutils/csv_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT csv_parser.obj -MD -MP -MF $(DEPDIR)/csv_parser.Tpo -c -o csv_parser.obj `if test -f '../../libutils/csv_parser.c'; then $(CYGPATH_W) '../../libutils/csv_parser.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/csv_parser.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/csv_parser.Tpo $(DEPDIR)/csv_parser.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/csv_parser.c' object='csv_parser.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o csv_parser.obj `if test -f '../../libutils/csv_parser.c'; then $(CYGPATH_W) '../../libutils/csv_parser.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/csv_parser.c'; fi` csv_writer.o: ../../libutils/csv_writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT csv_writer.o -MD -MP -MF $(DEPDIR)/csv_writer.Tpo -c -o csv_writer.o `test -f '../../libutils/csv_writer.c' || echo '$(srcdir)/'`../../libutils/csv_writer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/csv_writer.Tpo $(DEPDIR)/csv_writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/csv_writer.c' object='csv_writer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o csv_writer.o `test -f '../../libutils/csv_writer.c' || echo '$(srcdir)/'`../../libutils/csv_writer.c csv_writer.obj: ../../libutils/csv_writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT csv_writer.obj -MD -MP -MF $(DEPDIR)/csv_writer.Tpo -c -o csv_writer.obj `if test -f '../../libutils/csv_writer.c'; then $(CYGPATH_W) '../../libutils/csv_writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/csv_writer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/csv_writer.Tpo $(DEPDIR)/csv_writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/csv_writer.c' object='csv_writer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o csv_writer.obj `if test -f '../../libutils/csv_writer.c'; then $(CYGPATH_W) '../../libutils/csv_writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/csv_writer.c'; fi` cleanup.o: ../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cleanup.o -MD -MP -MF $(DEPDIR)/cleanup.Tpo -c -o cleanup.o `test -f '../../libutils/cleanup.c' || echo '$(srcdir)/'`../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cleanup.Tpo $(DEPDIR)/cleanup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/cleanup.c' object='cleanup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cleanup.o `test -f '../../libutils/cleanup.c' || echo '$(srcdir)/'`../../libutils/cleanup.c cleanup.obj: ../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cleanup.obj -MD -MP -MF $(DEPDIR)/cleanup.Tpo -c -o cleanup.obj `if test -f '../../libutils/cleanup.c'; then $(CYGPATH_W) '../../libutils/cleanup.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/cleanup.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cleanup.Tpo $(DEPDIR)/cleanup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/cleanup.c' object='cleanup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cleanup.obj `if test -f '../../libutils/cleanup.c'; then $(CYGPATH_W) '../../libutils/cleanup.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/cleanup.c'; fi` file_lib_test-file_lib_test.o: file_lib_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-file_lib_test.o -MD -MP -MF $(DEPDIR)/file_lib_test-file_lib_test.Tpo -c -o file_lib_test-file_lib_test.o `test -f 'file_lib_test.c' || echo '$(srcdir)/'`file_lib_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-file_lib_test.Tpo $(DEPDIR)/file_lib_test-file_lib_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file_lib_test.c' object='file_lib_test-file_lib_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-file_lib_test.o `test -f 'file_lib_test.c' || echo '$(srcdir)/'`file_lib_test.c file_lib_test-file_lib_test.obj: file_lib_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-file_lib_test.obj -MD -MP -MF $(DEPDIR)/file_lib_test-file_lib_test.Tpo -c -o file_lib_test-file_lib_test.obj `if test -f 'file_lib_test.c'; then $(CYGPATH_W) 'file_lib_test.c'; else $(CYGPATH_W) '$(srcdir)/file_lib_test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-file_lib_test.Tpo $(DEPDIR)/file_lib_test-file_lib_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='file_lib_test.c' object='file_lib_test-file_lib_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-file_lib_test.obj `if test -f 'file_lib_test.c'; then $(CYGPATH_W) 'file_lib_test.c'; else $(CYGPATH_W) '$(srcdir)/file_lib_test.c'; fi` file_lib_test-file_lib.o: ../../libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-file_lib.o -MD -MP -MF $(DEPDIR)/file_lib_test-file_lib.Tpo -c -o file_lib_test-file_lib.o `test -f '../../libutils/file_lib.c' || echo '$(srcdir)/'`../../libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-file_lib.Tpo $(DEPDIR)/file_lib_test-file_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/file_lib.c' object='file_lib_test-file_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-file_lib.o `test -f '../../libutils/file_lib.c' || echo '$(srcdir)/'`../../libutils/file_lib.c file_lib_test-file_lib.obj: ../../libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-file_lib.obj -MD -MP -MF $(DEPDIR)/file_lib_test-file_lib.Tpo -c -o file_lib_test-file_lib.obj `if test -f '../../libutils/file_lib.c'; then $(CYGPATH_W) '../../libutils/file_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/file_lib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-file_lib.Tpo $(DEPDIR)/file_lib_test-file_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/file_lib.c' object='file_lib_test-file_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-file_lib.obj `if test -f '../../libutils/file_lib.c'; then $(CYGPATH_W) '../../libutils/file_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/file_lib.c'; fi` file_lib_test-logging.o: ../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-logging.o -MD -MP -MF $(DEPDIR)/file_lib_test-logging.Tpo -c -o file_lib_test-logging.o `test -f '../../libutils/logging.c' || echo '$(srcdir)/'`../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-logging.Tpo $(DEPDIR)/file_lib_test-logging.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/logging.c' object='file_lib_test-logging.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-logging.o `test -f '../../libutils/logging.c' || echo '$(srcdir)/'`../../libutils/logging.c file_lib_test-logging.obj: ../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-logging.obj -MD -MP -MF $(DEPDIR)/file_lib_test-logging.Tpo -c -o file_lib_test-logging.obj `if test -f '../../libutils/logging.c'; then $(CYGPATH_W) '../../libutils/logging.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/logging.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-logging.Tpo $(DEPDIR)/file_lib_test-logging.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/logging.c' object='file_lib_test-logging.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-logging.obj `if test -f '../../libutils/logging.c'; then $(CYGPATH_W) '../../libutils/logging.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/logging.c'; fi` file_lib_test-misc_lib.o: ../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-misc_lib.o -MD -MP -MF $(DEPDIR)/file_lib_test-misc_lib.Tpo -c -o file_lib_test-misc_lib.o `test -f '../../libutils/misc_lib.c' || echo '$(srcdir)/'`../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-misc_lib.Tpo $(DEPDIR)/file_lib_test-misc_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/misc_lib.c' object='file_lib_test-misc_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-misc_lib.o `test -f '../../libutils/misc_lib.c' || echo '$(srcdir)/'`../../libutils/misc_lib.c file_lib_test-misc_lib.obj: ../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-misc_lib.obj -MD -MP -MF $(DEPDIR)/file_lib_test-misc_lib.Tpo -c -o file_lib_test-misc_lib.obj `if test -f '../../libutils/misc_lib.c'; then $(CYGPATH_W) '../../libutils/misc_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/misc_lib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-misc_lib.Tpo $(DEPDIR)/file_lib_test-misc_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/misc_lib.c' object='file_lib_test-misc_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-misc_lib.obj `if test -f '../../libutils/misc_lib.c'; then $(CYGPATH_W) '../../libutils/misc_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/misc_lib.c'; fi` file_lib_test-path.o: ../../libutils/path.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-path.o -MD -MP -MF $(DEPDIR)/file_lib_test-path.Tpo -c -o file_lib_test-path.o `test -f '../../libutils/path.c' || echo '$(srcdir)/'`../../libutils/path.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-path.Tpo $(DEPDIR)/file_lib_test-path.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/path.c' object='file_lib_test-path.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-path.o `test -f '../../libutils/path.c' || echo '$(srcdir)/'`../../libutils/path.c file_lib_test-path.obj: ../../libutils/path.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-path.obj -MD -MP -MF $(DEPDIR)/file_lib_test-path.Tpo -c -o file_lib_test-path.obj `if test -f '../../libutils/path.c'; then $(CYGPATH_W) '../../libutils/path.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/path.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-path.Tpo $(DEPDIR)/file_lib_test-path.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/path.c' object='file_lib_test-path.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-path.obj `if test -f '../../libutils/path.c'; then $(CYGPATH_W) '../../libutils/path.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/path.c'; fi` file_lib_test-string_lib.o: ../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-string_lib.o -MD -MP -MF $(DEPDIR)/file_lib_test-string_lib.Tpo -c -o file_lib_test-string_lib.o `test -f '../../libutils/string_lib.c' || echo '$(srcdir)/'`../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-string_lib.Tpo $(DEPDIR)/file_lib_test-string_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/string_lib.c' object='file_lib_test-string_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-string_lib.o `test -f '../../libutils/string_lib.c' || echo '$(srcdir)/'`../../libutils/string_lib.c file_lib_test-string_lib.obj: ../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-string_lib.obj -MD -MP -MF $(DEPDIR)/file_lib_test-string_lib.Tpo -c -o file_lib_test-string_lib.obj `if test -f '../../libutils/string_lib.c'; then $(CYGPATH_W) '../../libutils/string_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/string_lib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-string_lib.Tpo $(DEPDIR)/file_lib_test-string_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/string_lib.c' object='file_lib_test-string_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-string_lib.obj `if test -f '../../libutils/string_lib.c'; then $(CYGPATH_W) '../../libutils/string_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/string_lib.c'; fi` file_lib_test-sequence.o: ../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-sequence.o -MD -MP -MF $(DEPDIR)/file_lib_test-sequence.Tpo -c -o file_lib_test-sequence.o `test -f '../../libutils/sequence.c' || echo '$(srcdir)/'`../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-sequence.Tpo $(DEPDIR)/file_lib_test-sequence.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/sequence.c' object='file_lib_test-sequence.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-sequence.o `test -f '../../libutils/sequence.c' || echo '$(srcdir)/'`../../libutils/sequence.c file_lib_test-sequence.obj: ../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-sequence.obj -MD -MP -MF $(DEPDIR)/file_lib_test-sequence.Tpo -c -o file_lib_test-sequence.obj `if test -f '../../libutils/sequence.c'; then $(CYGPATH_W) '../../libutils/sequence.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/sequence.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-sequence.Tpo $(DEPDIR)/file_lib_test-sequence.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/sequence.c' object='file_lib_test-sequence.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-sequence.obj `if test -f '../../libutils/sequence.c'; then $(CYGPATH_W) '../../libutils/sequence.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/sequence.c'; fi` file_lib_test-set.o: ../../libutils/set.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-set.o -MD -MP -MF $(DEPDIR)/file_lib_test-set.Tpo -c -o file_lib_test-set.o `test -f '../../libutils/set.c' || echo '$(srcdir)/'`../../libutils/set.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-set.Tpo $(DEPDIR)/file_lib_test-set.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/set.c' object='file_lib_test-set.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-set.o `test -f '../../libutils/set.c' || echo '$(srcdir)/'`../../libutils/set.c file_lib_test-set.obj: ../../libutils/set.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-set.obj -MD -MP -MF $(DEPDIR)/file_lib_test-set.Tpo -c -o file_lib_test-set.obj `if test -f '../../libutils/set.c'; then $(CYGPATH_W) '../../libutils/set.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/set.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-set.Tpo $(DEPDIR)/file_lib_test-set.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/set.c' object='file_lib_test-set.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-set.obj `if test -f '../../libutils/set.c'; then $(CYGPATH_W) '../../libutils/set.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/set.c'; fi` file_lib_test-buffer.o: ../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-buffer.o -MD -MP -MF $(DEPDIR)/file_lib_test-buffer.Tpo -c -o file_lib_test-buffer.o `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-buffer.Tpo $(DEPDIR)/file_lib_test-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/buffer.c' object='file_lib_test-buffer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-buffer.o `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c file_lib_test-buffer.obj: ../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-buffer.obj -MD -MP -MF $(DEPDIR)/file_lib_test-buffer.Tpo -c -o file_lib_test-buffer.obj `if test -f '../../libutils/buffer.c'; then $(CYGPATH_W) '../../libutils/buffer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/buffer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-buffer.Tpo $(DEPDIR)/file_lib_test-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/buffer.c' object='file_lib_test-buffer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-buffer.obj `if test -f '../../libutils/buffer.c'; then $(CYGPATH_W) '../../libutils/buffer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/buffer.c'; fi` file_lib_test-json.o: ../../libutils/json.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-json.o -MD -MP -MF $(DEPDIR)/file_lib_test-json.Tpo -c -o file_lib_test-json.o `test -f '../../libutils/json.c' || echo '$(srcdir)/'`../../libutils/json.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-json.Tpo $(DEPDIR)/file_lib_test-json.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json.c' object='file_lib_test-json.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-json.o `test -f '../../libutils/json.c' || echo '$(srcdir)/'`../../libutils/json.c file_lib_test-json.obj: ../../libutils/json.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-json.obj -MD -MP -MF $(DEPDIR)/file_lib_test-json.Tpo -c -o file_lib_test-json.obj `if test -f '../../libutils/json.c'; then $(CYGPATH_W) '../../libutils/json.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-json.Tpo $(DEPDIR)/file_lib_test-json.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json.c' object='file_lib_test-json.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-json.obj `if test -f '../../libutils/json.c'; then $(CYGPATH_W) '../../libutils/json.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json.c'; fi` file_lib_test-json-yaml.o: ../../libutils/json-yaml.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-json-yaml.o -MD -MP -MF $(DEPDIR)/file_lib_test-json-yaml.Tpo -c -o file_lib_test-json-yaml.o `test -f '../../libutils/json-yaml.c' || echo '$(srcdir)/'`../../libutils/json-yaml.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-json-yaml.Tpo $(DEPDIR)/file_lib_test-json-yaml.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json-yaml.c' object='file_lib_test-json-yaml.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-json-yaml.o `test -f '../../libutils/json-yaml.c' || echo '$(srcdir)/'`../../libutils/json-yaml.c file_lib_test-json-yaml.obj: ../../libutils/json-yaml.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-json-yaml.obj -MD -MP -MF $(DEPDIR)/file_lib_test-json-yaml.Tpo -c -o file_lib_test-json-yaml.obj `if test -f '../../libutils/json-yaml.c'; then $(CYGPATH_W) '../../libutils/json-yaml.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json-yaml.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-json-yaml.Tpo $(DEPDIR)/file_lib_test-json-yaml.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json-yaml.c' object='file_lib_test-json-yaml.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-json-yaml.obj `if test -f '../../libutils/json-yaml.c'; then $(CYGPATH_W) '../../libutils/json-yaml.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json-yaml.c'; fi` file_lib_test-unix_dir.o: ../../libutils/unix_dir.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-unix_dir.o -MD -MP -MF $(DEPDIR)/file_lib_test-unix_dir.Tpo -c -o file_lib_test-unix_dir.o `test -f '../../libutils/unix_dir.c' || echo '$(srcdir)/'`../../libutils/unix_dir.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-unix_dir.Tpo $(DEPDIR)/file_lib_test-unix_dir.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/unix_dir.c' object='file_lib_test-unix_dir.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-unix_dir.o `test -f '../../libutils/unix_dir.c' || echo '$(srcdir)/'`../../libutils/unix_dir.c file_lib_test-unix_dir.obj: ../../libutils/unix_dir.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-unix_dir.obj -MD -MP -MF $(DEPDIR)/file_lib_test-unix_dir.Tpo -c -o file_lib_test-unix_dir.obj `if test -f '../../libutils/unix_dir.c'; then $(CYGPATH_W) '../../libutils/unix_dir.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/unix_dir.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-unix_dir.Tpo $(DEPDIR)/file_lib_test-unix_dir.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/unix_dir.c' object='file_lib_test-unix_dir.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-unix_dir.obj `if test -f '../../libutils/unix_dir.c'; then $(CYGPATH_W) '../../libutils/unix_dir.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/unix_dir.c'; fi` file_lib_test-cleanup.o: ../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-cleanup.o -MD -MP -MF $(DEPDIR)/file_lib_test-cleanup.Tpo -c -o file_lib_test-cleanup.o `test -f '../../libutils/cleanup.c' || echo '$(srcdir)/'`../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-cleanup.Tpo $(DEPDIR)/file_lib_test-cleanup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/cleanup.c' object='file_lib_test-cleanup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-cleanup.o `test -f '../../libutils/cleanup.c' || echo '$(srcdir)/'`../../libutils/cleanup.c file_lib_test-cleanup.obj: ../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-cleanup.obj -MD -MP -MF $(DEPDIR)/file_lib_test-cleanup.Tpo -c -o file_lib_test-cleanup.obj `if test -f '../../libutils/cleanup.c'; then $(CYGPATH_W) '../../libutils/cleanup.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/cleanup.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-cleanup.Tpo $(DEPDIR)/file_lib_test-cleanup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/cleanup.c' object='file_lib_test-cleanup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-cleanup.obj `if test -f '../../libutils/cleanup.c'; then $(CYGPATH_W) '../../libutils/cleanup.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/cleanup.c'; fi` file_lib_test-writer.o: ../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-writer.o -MD -MP -MF $(DEPDIR)/file_lib_test-writer.Tpo -c -o file_lib_test-writer.o `test -f '../../libutils/writer.c' || echo '$(srcdir)/'`../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-writer.Tpo $(DEPDIR)/file_lib_test-writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/writer.c' object='file_lib_test-writer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-writer.o `test -f '../../libutils/writer.c' || echo '$(srcdir)/'`../../libutils/writer.c file_lib_test-writer.obj: ../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-writer.obj -MD -MP -MF $(DEPDIR)/file_lib_test-writer.Tpo -c -o file_lib_test-writer.obj `if test -f '../../libutils/writer.c'; then $(CYGPATH_W) '../../libutils/writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/writer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-writer.Tpo $(DEPDIR)/file_lib_test-writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/writer.c' object='file_lib_test-writer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-writer.obj `if test -f '../../libutils/writer.c'; then $(CYGPATH_W) '../../libutils/writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/writer.c'; fi` file_lib_test-regex.o: ../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-regex.o -MD -MP -MF $(DEPDIR)/file_lib_test-regex.Tpo -c -o file_lib_test-regex.o `test -f '../../libutils/regex.c' || echo '$(srcdir)/'`../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-regex.Tpo $(DEPDIR)/file_lib_test-regex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/regex.c' object='file_lib_test-regex.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-regex.o `test -f '../../libutils/regex.c' || echo '$(srcdir)/'`../../libutils/regex.c file_lib_test-regex.obj: ../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib_test-regex.obj -MD -MP -MF $(DEPDIR)/file_lib_test-regex.Tpo -c -o file_lib_test-regex.obj `if test -f '../../libutils/regex.c'; then $(CYGPATH_W) '../../libutils/regex.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/regex.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib_test-regex.Tpo $(DEPDIR)/file_lib_test-regex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/regex.c' object='file_lib_test-regex.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(file_lib_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib_test-regex.obj `if test -f '../../libutils/regex.c'; then $(CYGPATH_W) '../../libutils/regex.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/regex.c'; fi` ipaddress_test-ipaddress_test.o: ipaddress_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-ipaddress_test.o -MD -MP -MF $(DEPDIR)/ipaddress_test-ipaddress_test.Tpo -c -o ipaddress_test-ipaddress_test.o `test -f 'ipaddress_test.c' || echo '$(srcdir)/'`ipaddress_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-ipaddress_test.Tpo $(DEPDIR)/ipaddress_test-ipaddress_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipaddress_test.c' object='ipaddress_test-ipaddress_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-ipaddress_test.o `test -f 'ipaddress_test.c' || echo '$(srcdir)/'`ipaddress_test.c ipaddress_test-ipaddress_test.obj: ipaddress_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-ipaddress_test.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-ipaddress_test.Tpo -c -o ipaddress_test-ipaddress_test.obj `if test -f 'ipaddress_test.c'; then $(CYGPATH_W) 'ipaddress_test.c'; else $(CYGPATH_W) '$(srcdir)/ipaddress_test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-ipaddress_test.Tpo $(DEPDIR)/ipaddress_test-ipaddress_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipaddress_test.c' object='ipaddress_test-ipaddress_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-ipaddress_test.obj `if test -f 'ipaddress_test.c'; then $(CYGPATH_W) 'ipaddress_test.c'; else $(CYGPATH_W) '$(srcdir)/ipaddress_test.c'; fi` ipaddress_test-file_lib.o: ../../libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-file_lib.o -MD -MP -MF $(DEPDIR)/ipaddress_test-file_lib.Tpo -c -o ipaddress_test-file_lib.o `test -f '../../libutils/file_lib.c' || echo '$(srcdir)/'`../../libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-file_lib.Tpo $(DEPDIR)/ipaddress_test-file_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/file_lib.c' object='ipaddress_test-file_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-file_lib.o `test -f '../../libutils/file_lib.c' || echo '$(srcdir)/'`../../libutils/file_lib.c ipaddress_test-file_lib.obj: ../../libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-file_lib.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-file_lib.Tpo -c -o ipaddress_test-file_lib.obj `if test -f '../../libutils/file_lib.c'; then $(CYGPATH_W) '../../libutils/file_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/file_lib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-file_lib.Tpo $(DEPDIR)/ipaddress_test-file_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/file_lib.c' object='ipaddress_test-file_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-file_lib.obj `if test -f '../../libutils/file_lib.c'; then $(CYGPATH_W) '../../libutils/file_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/file_lib.c'; fi` ipaddress_test-logging.o: ../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-logging.o -MD -MP -MF $(DEPDIR)/ipaddress_test-logging.Tpo -c -o ipaddress_test-logging.o `test -f '../../libutils/logging.c' || echo '$(srcdir)/'`../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-logging.Tpo $(DEPDIR)/ipaddress_test-logging.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/logging.c' object='ipaddress_test-logging.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-logging.o `test -f '../../libutils/logging.c' || echo '$(srcdir)/'`../../libutils/logging.c ipaddress_test-logging.obj: ../../libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-logging.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-logging.Tpo -c -o ipaddress_test-logging.obj `if test -f '../../libutils/logging.c'; then $(CYGPATH_W) '../../libutils/logging.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/logging.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-logging.Tpo $(DEPDIR)/ipaddress_test-logging.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/logging.c' object='ipaddress_test-logging.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-logging.obj `if test -f '../../libutils/logging.c'; then $(CYGPATH_W) '../../libutils/logging.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/logging.c'; fi` ipaddress_test-misc_lib.o: ../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-misc_lib.o -MD -MP -MF $(DEPDIR)/ipaddress_test-misc_lib.Tpo -c -o ipaddress_test-misc_lib.o `test -f '../../libutils/misc_lib.c' || echo '$(srcdir)/'`../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-misc_lib.Tpo $(DEPDIR)/ipaddress_test-misc_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/misc_lib.c' object='ipaddress_test-misc_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-misc_lib.o `test -f '../../libutils/misc_lib.c' || echo '$(srcdir)/'`../../libutils/misc_lib.c ipaddress_test-misc_lib.obj: ../../libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-misc_lib.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-misc_lib.Tpo -c -o ipaddress_test-misc_lib.obj `if test -f '../../libutils/misc_lib.c'; then $(CYGPATH_W) '../../libutils/misc_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/misc_lib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-misc_lib.Tpo $(DEPDIR)/ipaddress_test-misc_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/misc_lib.c' object='ipaddress_test-misc_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-misc_lib.obj `if test -f '../../libutils/misc_lib.c'; then $(CYGPATH_W) '../../libutils/misc_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/misc_lib.c'; fi` ipaddress_test-path.o: ../../libutils/path.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-path.o -MD -MP -MF $(DEPDIR)/ipaddress_test-path.Tpo -c -o ipaddress_test-path.o `test -f '../../libutils/path.c' || echo '$(srcdir)/'`../../libutils/path.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-path.Tpo $(DEPDIR)/ipaddress_test-path.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/path.c' object='ipaddress_test-path.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-path.o `test -f '../../libutils/path.c' || echo '$(srcdir)/'`../../libutils/path.c ipaddress_test-path.obj: ../../libutils/path.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-path.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-path.Tpo -c -o ipaddress_test-path.obj `if test -f '../../libutils/path.c'; then $(CYGPATH_W) '../../libutils/path.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/path.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-path.Tpo $(DEPDIR)/ipaddress_test-path.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/path.c' object='ipaddress_test-path.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-path.obj `if test -f '../../libutils/path.c'; then $(CYGPATH_W) '../../libutils/path.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/path.c'; fi` ipaddress_test-string_lib.o: ../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-string_lib.o -MD -MP -MF $(DEPDIR)/ipaddress_test-string_lib.Tpo -c -o ipaddress_test-string_lib.o `test -f '../../libutils/string_lib.c' || echo '$(srcdir)/'`../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-string_lib.Tpo $(DEPDIR)/ipaddress_test-string_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/string_lib.c' object='ipaddress_test-string_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-string_lib.o `test -f '../../libutils/string_lib.c' || echo '$(srcdir)/'`../../libutils/string_lib.c ipaddress_test-string_lib.obj: ../../libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-string_lib.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-string_lib.Tpo -c -o ipaddress_test-string_lib.obj `if test -f '../../libutils/string_lib.c'; then $(CYGPATH_W) '../../libutils/string_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/string_lib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-string_lib.Tpo $(DEPDIR)/ipaddress_test-string_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/string_lib.c' object='ipaddress_test-string_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-string_lib.obj `if test -f '../../libutils/string_lib.c'; then $(CYGPATH_W) '../../libutils/string_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/string_lib.c'; fi` ipaddress_test-sequence.o: ../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-sequence.o -MD -MP -MF $(DEPDIR)/ipaddress_test-sequence.Tpo -c -o ipaddress_test-sequence.o `test -f '../../libutils/sequence.c' || echo '$(srcdir)/'`../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-sequence.Tpo $(DEPDIR)/ipaddress_test-sequence.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/sequence.c' object='ipaddress_test-sequence.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-sequence.o `test -f '../../libutils/sequence.c' || echo '$(srcdir)/'`../../libutils/sequence.c ipaddress_test-sequence.obj: ../../libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-sequence.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-sequence.Tpo -c -o ipaddress_test-sequence.obj `if test -f '../../libutils/sequence.c'; then $(CYGPATH_W) '../../libutils/sequence.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/sequence.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-sequence.Tpo $(DEPDIR)/ipaddress_test-sequence.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/sequence.c' object='ipaddress_test-sequence.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-sequence.obj `if test -f '../../libutils/sequence.c'; then $(CYGPATH_W) '../../libutils/sequence.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/sequence.c'; fi` ipaddress_test-set.o: ../../libutils/set.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-set.o -MD -MP -MF $(DEPDIR)/ipaddress_test-set.Tpo -c -o ipaddress_test-set.o `test -f '../../libutils/set.c' || echo '$(srcdir)/'`../../libutils/set.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-set.Tpo $(DEPDIR)/ipaddress_test-set.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/set.c' object='ipaddress_test-set.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-set.o `test -f '../../libutils/set.c' || echo '$(srcdir)/'`../../libutils/set.c ipaddress_test-set.obj: ../../libutils/set.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-set.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-set.Tpo -c -o ipaddress_test-set.obj `if test -f '../../libutils/set.c'; then $(CYGPATH_W) '../../libutils/set.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/set.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-set.Tpo $(DEPDIR)/ipaddress_test-set.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/set.c' object='ipaddress_test-set.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-set.obj `if test -f '../../libutils/set.c'; then $(CYGPATH_W) '../../libutils/set.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/set.c'; fi` ipaddress_test-buffer.o: ../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-buffer.o -MD -MP -MF $(DEPDIR)/ipaddress_test-buffer.Tpo -c -o ipaddress_test-buffer.o `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-buffer.Tpo $(DEPDIR)/ipaddress_test-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/buffer.c' object='ipaddress_test-buffer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-buffer.o `test -f '../../libutils/buffer.c' || echo '$(srcdir)/'`../../libutils/buffer.c ipaddress_test-buffer.obj: ../../libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-buffer.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-buffer.Tpo -c -o ipaddress_test-buffer.obj `if test -f '../../libutils/buffer.c'; then $(CYGPATH_W) '../../libutils/buffer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/buffer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-buffer.Tpo $(DEPDIR)/ipaddress_test-buffer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/buffer.c' object='ipaddress_test-buffer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-buffer.obj `if test -f '../../libutils/buffer.c'; then $(CYGPATH_W) '../../libutils/buffer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/buffer.c'; fi` ipaddress_test-json.o: ../../libutils/json.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-json.o -MD -MP -MF $(DEPDIR)/ipaddress_test-json.Tpo -c -o ipaddress_test-json.o `test -f '../../libutils/json.c' || echo '$(srcdir)/'`../../libutils/json.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-json.Tpo $(DEPDIR)/ipaddress_test-json.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json.c' object='ipaddress_test-json.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-json.o `test -f '../../libutils/json.c' || echo '$(srcdir)/'`../../libutils/json.c ipaddress_test-json.obj: ../../libutils/json.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-json.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-json.Tpo -c -o ipaddress_test-json.obj `if test -f '../../libutils/json.c'; then $(CYGPATH_W) '../../libutils/json.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-json.Tpo $(DEPDIR)/ipaddress_test-json.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json.c' object='ipaddress_test-json.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-json.obj `if test -f '../../libutils/json.c'; then $(CYGPATH_W) '../../libutils/json.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json.c'; fi` ipaddress_test-json-yaml.o: ../../libutils/json-yaml.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-json-yaml.o -MD -MP -MF $(DEPDIR)/ipaddress_test-json-yaml.Tpo -c -o ipaddress_test-json-yaml.o `test -f '../../libutils/json-yaml.c' || echo '$(srcdir)/'`../../libutils/json-yaml.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-json-yaml.Tpo $(DEPDIR)/ipaddress_test-json-yaml.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json-yaml.c' object='ipaddress_test-json-yaml.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-json-yaml.o `test -f '../../libutils/json-yaml.c' || echo '$(srcdir)/'`../../libutils/json-yaml.c ipaddress_test-json-yaml.obj: ../../libutils/json-yaml.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-json-yaml.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-json-yaml.Tpo -c -o ipaddress_test-json-yaml.obj `if test -f '../../libutils/json-yaml.c'; then $(CYGPATH_W) '../../libutils/json-yaml.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json-yaml.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-json-yaml.Tpo $(DEPDIR)/ipaddress_test-json-yaml.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/json-yaml.c' object='ipaddress_test-json-yaml.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-json-yaml.obj `if test -f '../../libutils/json-yaml.c'; then $(CYGPATH_W) '../../libutils/json-yaml.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/json-yaml.c'; fi` ipaddress_test-unix_dir.o: ../../libutils/unix_dir.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-unix_dir.o -MD -MP -MF $(DEPDIR)/ipaddress_test-unix_dir.Tpo -c -o ipaddress_test-unix_dir.o `test -f '../../libutils/unix_dir.c' || echo '$(srcdir)/'`../../libutils/unix_dir.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-unix_dir.Tpo $(DEPDIR)/ipaddress_test-unix_dir.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/unix_dir.c' object='ipaddress_test-unix_dir.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-unix_dir.o `test -f '../../libutils/unix_dir.c' || echo '$(srcdir)/'`../../libutils/unix_dir.c ipaddress_test-unix_dir.obj: ../../libutils/unix_dir.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-unix_dir.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-unix_dir.Tpo -c -o ipaddress_test-unix_dir.obj `if test -f '../../libutils/unix_dir.c'; then $(CYGPATH_W) '../../libutils/unix_dir.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/unix_dir.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-unix_dir.Tpo $(DEPDIR)/ipaddress_test-unix_dir.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/unix_dir.c' object='ipaddress_test-unix_dir.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-unix_dir.obj `if test -f '../../libutils/unix_dir.c'; then $(CYGPATH_W) '../../libutils/unix_dir.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/unix_dir.c'; fi` ipaddress_test-cleanup.o: ../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-cleanup.o -MD -MP -MF $(DEPDIR)/ipaddress_test-cleanup.Tpo -c -o ipaddress_test-cleanup.o `test -f '../../libutils/cleanup.c' || echo '$(srcdir)/'`../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-cleanup.Tpo $(DEPDIR)/ipaddress_test-cleanup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/cleanup.c' object='ipaddress_test-cleanup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-cleanup.o `test -f '../../libutils/cleanup.c' || echo '$(srcdir)/'`../../libutils/cleanup.c ipaddress_test-cleanup.obj: ../../libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-cleanup.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-cleanup.Tpo -c -o ipaddress_test-cleanup.obj `if test -f '../../libutils/cleanup.c'; then $(CYGPATH_W) '../../libutils/cleanup.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/cleanup.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-cleanup.Tpo $(DEPDIR)/ipaddress_test-cleanup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/cleanup.c' object='ipaddress_test-cleanup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-cleanup.obj `if test -f '../../libutils/cleanup.c'; then $(CYGPATH_W) '../../libutils/cleanup.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/cleanup.c'; fi` ipaddress_test-writer.o: ../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-writer.o -MD -MP -MF $(DEPDIR)/ipaddress_test-writer.Tpo -c -o ipaddress_test-writer.o `test -f '../../libutils/writer.c' || echo '$(srcdir)/'`../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-writer.Tpo $(DEPDIR)/ipaddress_test-writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/writer.c' object='ipaddress_test-writer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-writer.o `test -f '../../libutils/writer.c' || echo '$(srcdir)/'`../../libutils/writer.c ipaddress_test-writer.obj: ../../libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-writer.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-writer.Tpo -c -o ipaddress_test-writer.obj `if test -f '../../libutils/writer.c'; then $(CYGPATH_W) '../../libutils/writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/writer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-writer.Tpo $(DEPDIR)/ipaddress_test-writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/writer.c' object='ipaddress_test-writer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-writer.obj `if test -f '../../libutils/writer.c'; then $(CYGPATH_W) '../../libutils/writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/writer.c'; fi` ipaddress_test-regex.o: ../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-regex.o -MD -MP -MF $(DEPDIR)/ipaddress_test-regex.Tpo -c -o ipaddress_test-regex.o `test -f '../../libutils/regex.c' || echo '$(srcdir)/'`../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-regex.Tpo $(DEPDIR)/ipaddress_test-regex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/regex.c' object='ipaddress_test-regex.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-regex.o `test -f '../../libutils/regex.c' || echo '$(srcdir)/'`../../libutils/regex.c ipaddress_test-regex.obj: ../../libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ipaddress_test-regex.obj -MD -MP -MF $(DEPDIR)/ipaddress_test-regex.Tpo -c -o ipaddress_test-regex.obj `if test -f '../../libutils/regex.c'; then $(CYGPATH_W) '../../libutils/regex.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/regex.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ipaddress_test-regex.Tpo $(DEPDIR)/ipaddress_test-regex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/regex.c' object='ipaddress_test-regex.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ipaddress_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ipaddress_test-regex.obj `if test -f '../../libutils/regex.c'; then $(CYGPATH_W) '../../libutils/regex.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/regex.c'; fi` libcompat_test-libcompat_test.o: libcompat_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcompat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcompat_test-libcompat_test.o -MD -MP -MF $(DEPDIR)/libcompat_test-libcompat_test.Tpo -c -o libcompat_test-libcompat_test.o `test -f 'libcompat_test.c' || echo '$(srcdir)/'`libcompat_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcompat_test-libcompat_test.Tpo $(DEPDIR)/libcompat_test-libcompat_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcompat_test.c' object='libcompat_test-libcompat_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcompat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcompat_test-libcompat_test.o `test -f 'libcompat_test.c' || echo '$(srcdir)/'`libcompat_test.c libcompat_test-libcompat_test.obj: libcompat_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcompat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcompat_test-libcompat_test.obj -MD -MP -MF $(DEPDIR)/libcompat_test-libcompat_test.Tpo -c -o libcompat_test-libcompat_test.obj `if test -f 'libcompat_test.c'; then $(CYGPATH_W) 'libcompat_test.c'; else $(CYGPATH_W) '$(srcdir)/libcompat_test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcompat_test-libcompat_test.Tpo $(DEPDIR)/libcompat_test-libcompat_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcompat_test.c' object='libcompat_test-libcompat_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcompat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcompat_test-libcompat_test.obj `if test -f 'libcompat_test.c'; then $(CYGPATH_W) 'libcompat_test.c'; else $(CYGPATH_W) '$(srcdir)/libcompat_test.c'; fi` misc_lib_test-misc_lib_test.o: misc_lib_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(misc_lib_test_CFLAGS) $(CFLAGS) -MT misc_lib_test-misc_lib_test.o -MD -MP -MF $(DEPDIR)/misc_lib_test-misc_lib_test.Tpo -c -o misc_lib_test-misc_lib_test.o `test -f 'misc_lib_test.c' || echo '$(srcdir)/'`misc_lib_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/misc_lib_test-misc_lib_test.Tpo $(DEPDIR)/misc_lib_test-misc_lib_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='misc_lib_test.c' object='misc_lib_test-misc_lib_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(misc_lib_test_CFLAGS) $(CFLAGS) -c -o misc_lib_test-misc_lib_test.o `test -f 'misc_lib_test.c' || echo '$(srcdir)/'`misc_lib_test.c misc_lib_test-misc_lib_test.obj: misc_lib_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(misc_lib_test_CFLAGS) $(CFLAGS) -MT misc_lib_test-misc_lib_test.obj -MD -MP -MF $(DEPDIR)/misc_lib_test-misc_lib_test.Tpo -c -o misc_lib_test-misc_lib_test.obj `if test -f 'misc_lib_test.c'; then $(CYGPATH_W) 'misc_lib_test.c'; else $(CYGPATH_W) '$(srcdir)/misc_lib_test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/misc_lib_test-misc_lib_test.Tpo $(DEPDIR)/misc_lib_test-misc_lib_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='misc_lib_test.c' object='misc_lib_test-misc_lib_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(misc_lib_test_CFLAGS) $(CFLAGS) -c -o misc_lib_test-misc_lib_test.obj `if test -f 'misc_lib_test.c'; then $(CYGPATH_W) 'misc_lib_test.c'; else $(CYGPATH_W) '$(srcdir)/misc_lib_test.c'; fi` refcount.o: ../../libutils/refcount.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT refcount.o -MD -MP -MF $(DEPDIR)/refcount.Tpo -c -o refcount.o `test -f '../../libutils/refcount.c' || echo '$(srcdir)/'`../../libutils/refcount.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/refcount.Tpo $(DEPDIR)/refcount.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/refcount.c' object='refcount.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o refcount.o `test -f '../../libutils/refcount.c' || echo '$(srcdir)/'`../../libutils/refcount.c refcount.obj: ../../libutils/refcount.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT refcount.obj -MD -MP -MF $(DEPDIR)/refcount.Tpo -c -o refcount.obj `if test -f '../../libutils/refcount.c'; then $(CYGPATH_W) '../../libutils/refcount.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/refcount.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/refcount.Tpo $(DEPDIR)/refcount.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/refcount.c' object='refcount.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o refcount.obj `if test -f '../../libutils/refcount.c'; then $(CYGPATH_W) '../../libutils/refcount.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/refcount.c'; fi` xml_writer.o: ../../libutils/xml_writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xml_writer.o -MD -MP -MF $(DEPDIR)/xml_writer.Tpo -c -o xml_writer.o `test -f '../../libutils/xml_writer.c' || echo '$(srcdir)/'`../../libutils/xml_writer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_writer.Tpo $(DEPDIR)/xml_writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/xml_writer.c' object='xml_writer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xml_writer.o `test -f '../../libutils/xml_writer.c' || echo '$(srcdir)/'`../../libutils/xml_writer.c xml_writer.obj: ../../libutils/xml_writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xml_writer.obj -MD -MP -MF $(DEPDIR)/xml_writer.Tpo -c -o xml_writer.obj `if test -f '../../libutils/xml_writer.c'; then $(CYGPATH_W) '../../libutils/xml_writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/xml_writer.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_writer.Tpo $(DEPDIR)/xml_writer.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libutils/xml_writer.c' object='xml_writer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xml_writer.obj `if test -f '../../libutils/xml_writer.c'; then $(CYGPATH_W) '../../libutils/xml_writer.c'; else $(CYGPATH_W) '$(srcdir)/../../libutils/xml_writer.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool clean-local cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile clean-local: rm -rf test_glob_file_list_?????? # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libntech/tests/unit/queue_test.c0000644000000000000000000000222515010704254021615 0ustar00rootroot00000000000000#include #include #include #include static void test_basics(void) { Queue *q = QueueNew(free); assert_int_equal(0, QueueCount(q)); assert_true(QueueIsEmpty(q)); QueueEnqueue(q, xstrdup("hello")); assert_int_equal(1, QueueCount(q)); assert_false(QueueIsEmpty(q)); assert_string_equal("hello", QueueHead(q)); QueueEnqueue(q, xstrdup("world")); assert_int_equal(2, QueueCount(q)); assert_string_equal("hello", QueueHead(q)); char *head = QueueDequeue(q); assert_string_equal("hello", head); free(head); assert_string_equal("world", QueueHead(q)); head = QueueDequeue(q); assert_string_equal("world", head); free(head); QueueDestroy(q); } static void test_destroy(void) { Queue *q = QueueNew(free); QueueEnqueue(q, xstrdup("1")); QueueEnqueue(q, xstrdup("2")); QueueEnqueue(q, xstrdup("3")); assert_int_equal(3, QueueCount(q)); QueueDestroy(q); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_basics), unit_test(test_destroy) }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/file_lock_test.c0000644000000000000000000001046015010704254022420 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include /** * This file contains file-locking tests that need to fork() a child process * which totally confuses the unit test framework used by the other tests. */ #if defined(__ANDROID__) # define TEMP_DIR "/data/data/com.termux/files/usr/tmp" #else # define TEMP_DIR "/tmp/file_lib_test" #endif #define TEST_FILE "file_lib_test.txt" static bool failure = false; #define assert_int_equal(expr1, expr2) \ if ((expr1) != (expr2)) \ { \ fprintf(stderr, "FAIL: "#expr1" != "#expr2" [%d != %d] (%s:%d)\n", (expr1), (expr2), __FILE__, __LINE__); \ failure = true; \ } #define assert_true(expr) \ if (!(expr)) \ { \ fprintf(stderr, "FAIL: "#expr" is FALSE (%s:%d)\n", __FILE__, __LINE__); \ failure = true; \ } #define assert_false(expr) \ if ((expr)) \ { \ fprintf(stderr, "FAIL: "#expr" is TRUE (%s:%d)\n", __FILE__, __LINE__); \ failure = true; \ } static void clear_tempfiles() { unlink(TEMP_DIR "/" TEST_FILE); rmdir(TEMP_DIR); } int main() { atexit(&clear_tempfiles); mkdir(TEMP_DIR, 0755); /* TEST CASE 1 -- excl. lock in parent, try excl. lock in child */ FileLock lock = EMPTY_FILE_LOCK; int fd = open(TEMP_DIR "/" TEST_FILE, O_CREAT | O_RDWR, 0644); lock.fd = fd; /* lock trying to wait */ assert_int_equal(ExclusiveFileLock(&lock, true), 0); /* FD should not be changed */ assert_int_equal(lock.fd, fd); /* we would be able to acquire the lock (we already have it) */ assert_true(ExclusiveFileLockCheck(&lock)); pid_t pid = fork(); if (pid == 0) { /* child */ failure = false; /* FDs are inherited, fcntl() locks are not */ /* the lock is held by the parent process */ assert_false(ExclusiveFileLockCheck(&lock)); /* try to lock without waiting */ assert_int_equal(ExclusiveFileLock(&lock, false), -1); /* should not affect parent's FD */ close(fd); _exit(failure ? 1 : 0); } else { /* parent */ int status; int ret = waitpid(pid, &status, 0); assert_int_equal(ret, pid); failure = (WEXITSTATUS(status) != 0); } /* unlock, but keep the FD open */ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* should be able to close */ assert_int_equal(close(lock.fd), 0); /* TEST CASE 2 -- shared lock in parent, try excl. lock in child, get shared * lock in child, get excl. lock in parent */ fd = open(TEMP_DIR "/" TEST_FILE, O_CREAT | O_RDWR, 0644); lock.fd = fd; /* SHARED lock trying to wait */ assert_int_equal(SharedFileLock(&lock, true), 0); /* FD should not be changed */ assert_int_equal(lock.fd, fd); pid = fork(); if (pid == 0) { /* child */ failure = false; /* FDs are inherited, fcntl() locks are not */ /* a shared lock is held by the parent process */ assert_false(ExclusiveFileLockCheck(&lock)); /* try to lock without waiting */ assert_int_equal(ExclusiveFileLock(&lock, false), -1); /* try to get a shared lock without waiting */ assert_int_equal(SharedFileLock(&lock, false), 0); /* should not affect parent's lock or FD */ assert_int_equal(SharedFileUnlock(&lock, true), 0); _exit(failure ? 1 : 0); } else { /* parent */ int status; int ret = waitpid(pid, &status, 0); assert_int_equal(ret, pid); failure = (WEXITSTATUS(status) != 0); } /* we are holding a shared lock so WE should be able to get an exclusive * lock */ assert_true(ExclusiveFileLockCheck(&lock)); /* upgrade the lock to an exclusive one */ assert_int_equal(ExclusiveFileLock(&lock, true), 0); /* unlock, but keep the FD open */ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* should be able to close both FDs */ assert_int_equal(close(lock.fd), 0); if (failure) { fprintf(stderr, "FAILED\n"); return 1; } else { fprintf(stderr, "SUCCESS\n"); return 0; } } cfengine-3.24.2/libntech/tests/unit/map_test.c0000644000000000000000000006025215010704254021252 0ustar00rootroot00000000000000#include #include #include #include #include #include #define HASH_MAP_INIT_SIZE 128 #define HASH_MAP_MAX_LOAD_FACTOR 0.75 #define HASH_MAP_MIN_LOAD_FACTOR 0.35 #define MIN_HASHMAP_BUCKETS 1 << 5 static unsigned int ConstHash(ARG_UNUSED const void *key, ARG_UNUSED unsigned int seed) { return 0; } static void test_new_destroy(void) { Map *map = MapNew(NULL, NULL, NULL, NULL); assert_int_equal(MapSize(map), 0); MapDestroy(map); } static void test_new_hashmap_bad_size(void) { /* too small */ HashMap *hashmap = HashMapNew(StringHash_untyped, StringEqual_untyped, free, free, MIN_HASHMAP_BUCKETS >> 1); assert_int_equal(hashmap->size, MIN_HASHMAP_BUCKETS); HashMapDestroy(hashmap); /* not a pow2 */ hashmap = HashMapNew(StringHash_untyped, StringEqual_untyped, free, free, 123); assert_int_equal(hashmap->size, 128); HashMapDestroy(hashmap); /* TODO: test size too big? Would require a lot of memory to be available. */ } static void test_insert(void) { StringMap *map = StringMapNew(); assert_false(StringMapHasKey(map, "one")); assert_false(StringMapInsert(map, xstrdup("one"), xstrdup("first"))); assert_true(StringMapHasKey(map, "one")); assert_int_equal(StringMapSize(map), 1); assert_true(StringMapInsert(map, xstrdup("one"), xstrdup("duplicate"))); assert_int_equal(StringMapSize(map), 1); assert_false(StringMapHasKey(map, "two")); assert_false(StringMapInsert(map, xstrdup("two"), xstrdup("second"))); assert_true(StringMapHasKey(map, "two")); assert_int_equal(StringMapSize(map), 2); assert_false(StringMapHasKey(map, "third")); assert_false(StringMapInsert(map, xstrdup("third"), xstrdup("first"))); assert_true(StringMapHasKey(map, "third")); assert_true(StringMapInsert(map, xstrdup("third"), xstrdup("stuff"))); assert_true(StringMapHasKey(map, "third")); assert_int_equal(StringMapSize(map), 3); StringMapDestroy(map); } static char *CharTimes(char c, size_t times) { char *res = xmalloc(times + 1); memset(res, c, times); res[times] = '\0'; return res; } static StringMap *jumbo_map; static void test_insert_jumbo(void) { jumbo_map = StringMapNew(); for (int i = 0; i < 10000; i++) { /* char *s = CharTimes('a', i); */ char s[i+1]; memset(s, 'a', i); s[i] = '\0'; assert_false(StringMapHasKey(jumbo_map, s)); assert_false(StringMapInsert(jumbo_map, xstrdup(s), xstrdup(s))); assert_true(StringMapHasKey(jumbo_map, s)); /* free(s); */ } StringMapPrintStats(jumbo_map, stdout); } static void test_remove(void) { HashMap *hashmap = HashMapNew(ConstHash, StringEqual_untyped, free, free, HASH_MAP_INIT_SIZE); HashMapInsert(hashmap, xstrdup("a"), xstrdup("b")); MapKeyValue *item = HashMapGet(hashmap, "a"); assert_string_equal(item->key, "a"); assert_string_equal(item->value, "b"); assert_true(HashMapRemove(hashmap, "a")); assert_int_equal(HashMapGet(hashmap, "a"), NULL); HashMapDestroy(hashmap); } static void test_add_n_as_to_map(HashMap *hashmap, unsigned int i) { char s[i+1]; memset(s, 'a', i); s[i] = '\0'; assert_true(HashMapGet(hashmap, s) == NULL); assert_false(HashMapInsert(hashmap, xstrdup(s), xstrdup(s))); assert_true(HashMapGet(hashmap, s) != NULL); } static void test_remove_n_as_from_map(HashMap *hashmap, unsigned int i) { char s[i+1]; memset(s, 'a', i); s[i] = '\0'; assert_true(HashMapGet(hashmap, s) != NULL); char * dup = xstrdup(s); assert_true(HashMapRemove(hashmap, dup)); free(dup); assert_true(HashMapGet(hashmap, s) == NULL); } static void assert_n_as_in_map(HashMap *hashmap, unsigned int i, bool in) { char s[i+1]; memset(s, 'a', i); s[i] = '\0'; if (in) { assert_true(HashMapGet(hashmap, s) != NULL); } else { assert_true(HashMapGet(hashmap, s) == NULL); } } static void test_grow(void) { unsigned int i = 0; HashMap *hashmap = HashMapNew(StringHash_untyped, StringEqual_untyped, free, free, HASH_MAP_INIT_SIZE); size_t orig_size = hashmap->size; size_t orig_threshold = hashmap->max_threshold; for (i = 1; i <= orig_threshold; i++) { test_add_n_as_to_map(hashmap, i); assert_int_equal(hashmap->load, i); } // HashMapPrintStats(hashmap, stdout); assert_int_equal(hashmap->size, orig_size); assert_int_equal(hashmap->max_threshold, orig_threshold); /* i == (orig_threshold + 1) now * let's go over the threshold */ test_add_n_as_to_map(hashmap, i); assert_int_equal(hashmap->load, i); assert_int_equal(hashmap->size, orig_size << 1); assert_int_equal(hashmap->max_threshold, (size_t) (hashmap->size * HASH_MAP_MAX_LOAD_FACTOR)); /* all the items so far should be in the map */ for (int j = 1; j <= i; j++) { assert_n_as_in_map(hashmap, j, true); } /* here we go again */ orig_size = hashmap->size; orig_threshold = hashmap->max_threshold; /* i * 'a' is in the map already, we need to bump it first */ for (++i; i <= orig_threshold; i++) { test_add_n_as_to_map(hashmap, i); assert_int_equal(hashmap->load, i); } // HashMapPrintStats(hashmap, stdout); assert_int_equal(hashmap->size, orig_size); assert_int_equal(hashmap->max_threshold, orig_threshold); /* i == (orig_threshold + 1) now * let's go over the threshold */ test_add_n_as_to_map(hashmap, i); assert_int_equal(hashmap->load, i); assert_int_equal(hashmap->size, orig_size << 1); assert_int_equal(hashmap->max_threshold, (size_t) (hashmap->size * HASH_MAP_MAX_LOAD_FACTOR)); /* all the items so far should be in the map */ for (int j = 1; j <= i; j++) { assert_n_as_in_map(hashmap, j, true); } /* and once more */ orig_size = hashmap->size; orig_threshold = hashmap->max_threshold; /* i * 'a' is in the map already, we need to bump it first */ for (++i; i <= orig_threshold; i++) { test_add_n_as_to_map(hashmap, i); assert_int_equal(hashmap->load, i); } // HashMapPrintStats(hashmap, stdout); assert_int_equal(hashmap->size, orig_size); assert_int_equal(hashmap->max_threshold, orig_threshold); /* i == (orig_threshold + 1) now * let's go over the threshold */ test_add_n_as_to_map(hashmap, i); assert_int_equal(hashmap->load, i); assert_int_equal(hashmap->size, orig_size << 1); assert_int_equal(hashmap->max_threshold, (size_t) (hashmap->size * HASH_MAP_MAX_LOAD_FACTOR)); /* all the items so far should be in the map */ for (int j = 1; j <= i; j++) { assert_n_as_in_map(hashmap, j, true); } HashMapDestroy(hashmap); } static void test_shrink(void) { unsigned int i = 0; HashMap *hashmap = HashMapNew(StringHash_untyped, StringEqual_untyped, free, free, HASH_MAP_INIT_SIZE); size_t orig_size = hashmap->size; size_t orig_threshold = hashmap->max_threshold; /* let the map grow first (see test_grow above for some details */ for (i = 1; i <= orig_threshold; i++) { test_add_n_as_to_map(hashmap, i); } assert_int_equal(hashmap->size, orig_size); assert_int_equal(hashmap->max_threshold, orig_threshold); test_add_n_as_to_map(hashmap, i); assert_int_equal(hashmap->load, i); assert_int_equal(hashmap->size, orig_size << 1); assert_int_equal(hashmap->max_threshold, (size_t) (hashmap->size * HASH_MAP_MAX_LOAD_FACTOR)); /* all the items so far should be in the map */ for (int j = 1; j <= i; j++) { assert_n_as_in_map(hashmap, j, true); } /* now start removing things from the map */ size_t min_threshold = hashmap->min_threshold; orig_size = hashmap->size; /* 'i' is the length of the longest one already inserted */ for (; i > min_threshold; i--) { test_remove_n_as_from_map(hashmap, i); assert_int_equal(hashmap->load, i - 1); } assert_int_equal(hashmap->load, hashmap->min_threshold); assert_int_equal(hashmap->size, orig_size); assert_int_equal(hashmap->min_threshold, min_threshold); /* let's move over the threshold */ test_remove_n_as_from_map(hashmap, i); assert_int_equal(hashmap->load, i - 1); assert_int_equal(hashmap->size, orig_size >> 1); assert_int_equal(hashmap->min_threshold, (size_t) (hashmap->size * HASH_MAP_MIN_LOAD_FACTOR)); /* all the non-removed items should still be in the map */ for (int j = 1; j < i; j++) { assert_n_as_in_map(hashmap, j, true); } HashMapDestroy(hashmap); } static void test_no_shrink_below_init_size(void) { HashMap *hashmap = HashMapNew(StringHash_untyped, StringEqual_untyped, free, free, HASH_MAP_INIT_SIZE); assert_int_equal(hashmap->size, HASH_MAP_INIT_SIZE); assert_int_equal(hashmap->init_size, HASH_MAP_INIT_SIZE); /* add and remove 'aaaaa' to/from the HashMap * * The remove could trigger the shrink mechanism because there are obviously * less than HASH_MAP_MIN_LOAD_FACTOR * HASH_MAP_INIT_SIZE items in the * map. But the 'init_size' should block that from happening. */ test_add_n_as_to_map(hashmap, 5); test_remove_n_as_from_map(hashmap, 5); assert_int_equal(hashmap->size, HASH_MAP_INIT_SIZE); HashMapDestroy(hashmap); } static void test_get(void) { StringMap *map = StringMapNew(); assert_false(StringMapInsert(map, xstrdup("one"), xstrdup("first"))); assert_string_equal(StringMapGet(map, "one"), "first"); assert_int_equal(StringMapGet(map, "two"), NULL); StringMapDestroy(map); } static void test_has_key(void) { StringMap *map = StringMapNew(); assert_false(StringMapInsert(map, xstrdup("one"), xstrdup("first"))); assert_true(StringMapHasKey(map, "one")); StringMapDestroy(map); } static void test_clear(void) { StringMap *map = StringMapNew(); assert_false(StringMapInsert(map, xstrdup("one"), xstrdup("first"))); assert_true(StringMapHasKey(map, "one")); StringMapClear(map); assert_false(StringMapHasKey(map, "one")); StringMapDestroy(map); } static void test_clear_hashmap(void) { HashMap *map = HashMapNew(StringHash_untyped, StringEqual_untyped, free, free, HASH_MAP_INIT_SIZE); assert_false(HashMapInsert(map, xstrdup("one"), xstrdup("first"))); assert_false(HashMapInsert(map, xstrdup("two"), xstrdup("second"))); assert_true(HashMapGet(map, "one") != NULL); assert_true(HashMapGet(map, "two") != NULL); assert_int_equal(map->load, 2); HashMapClear(map); assert_true(HashMapGet(map, "one") == NULL); assert_true(HashMapGet(map, "two") == NULL); assert_int_equal(map->load, 0); /* make sure that inserting items after clear doesn't trigger growth */ unsigned int i = 0; /* first populate the hashmap just below the threshold */ size_t orig_size = map->size; size_t orig_threshold = map->max_threshold; for (i = 1; i <= orig_threshold; i++) { test_add_n_as_to_map(map, i); assert_int_equal(map->load, i); } assert_int_equal(map->size, orig_size); assert_int_equal(map->max_threshold, orig_threshold); /* clear and repopulate again */ HashMapClear(map); for (i = 1; i <= orig_threshold; i++) { test_add_n_as_to_map(map, i); assert_int_equal(map->load, i); } /* the map was cleared before re-population, there's no reason for it to * grow */ assert_int_equal(map->size, orig_size); assert_int_equal(map->max_threshold, orig_threshold); HashMapDestroy(map); } static void test_soft_destroy(void) { StringMap *map = StringMapNew(); char *key = xstrdup("one"); char *value = xstrdup("first"); assert_false(StringMapInsert(map, key, value)); assert_true(StringMapHasKey(map, "one")); assert_string_equal(StringMapGet(map, "one"),"first"); StringMapSoftDestroy(map); assert_string_equal("first", value); free(value); } static void test_iterate_jumbo(void) { size_t size = StringMapSize(jumbo_map); MapIterator it = MapIteratorInit(jumbo_map->impl); MapKeyValue *item = NULL; int count = 0; int sum_len = 0; while ((item = MapIteratorNext(&it))) { int key_len = strlen(item->key); int value_len = strlen(item->value); assert_int_equal(key_len, value_len); sum_len += key_len; count++; } assert_int_equal(count, 10000); assert_int_equal(count, size); assert_int_equal(sum_len, 10000*9999/2); } #ifndef _AIX static void test_insert_jumbo_more(void) { for (int i = 1; i < 10000; i++) { /* char *s = CharTimes('x', i); */ char s[i+1]; memset(s, 'x', i); s[i] = '\0'; assert_false(StringMapHasKey(jumbo_map, s)); assert_false(StringMapInsert(jumbo_map, xstrdup(s), xstrdup(s))); assert_true(StringMapHasKey(jumbo_map, s)); /* free(s); */ } for (int i = 1; i < 7500; i++) { /* char *s = CharTimes('y', i); */ char s[i+1]; memset(s, 'y', i); s[i] = '\0'; assert_false(StringMapHasKey(jumbo_map, s)); assert_false(StringMapInsert(jumbo_map, xstrdup(s), xstrdup(s))); assert_true(StringMapHasKey(jumbo_map, s)); /* free(s); */ } StringMapPrintStats(jumbo_map, stdout); /* TODO: maybe we need a GetStats() function so that we can actually verify the stats here automatically? */ StringMapDestroy(jumbo_map); }; #endif static void test_hashmap_new_destroy(void) { HashMap *hashmap = HashMapNew(NULL, NULL, NULL, NULL, HASH_MAP_INIT_SIZE); HashMapDestroy(hashmap); } static void test_hashmap_degenerate_hash_fn(void) { HashMap *hashmap = HashMapNew(ConstHash, StringEqual_untyped, free, free, HASH_MAP_INIT_SIZE); for (int i = 0; i < 100; i++) { assert_false(HashMapInsert(hashmap, CharTimes('a', i), CharTimes('a', i))); } MapKeyValue *item = HashMapGet(hashmap, "aaaa"); assert_string_equal(item->key, "aaaa"); assert_string_equal(item->value, "aaaa"); HashMapRemove(hashmap, "aaaa"); assert_int_equal(HashMapGet(hashmap, "aaaa"), NULL); HashMapDestroy(hashmap); } #define ARRAY_STRING_KEY(last_char) {'k', 'e', 'y', last_char, '\0'} #define ARRAY_STRING_VALUE(last_char) {'v', 'a', 'l', 'u', 'e', last_char, '\0'} /** * @brief Return pointer to heap allocated string constructed as * "keyX" where X is last_char. */ static char *MallocStringKey(char last_char) { return xstrdup((char[]) ARRAY_STRING_KEY(last_char)); } /** * @brief Return pointer to heap allocated string constructed as * "valueX" where X is last_char. */ static char *MallocStringValue(char last_char) { return xstrdup((char[]) ARRAY_STRING_VALUE(last_char)); } static void test_array_map_insert(void) { ArrayMap *m = ArrayMapNew(StringEqual_untyped, free, free); // Test simple insertion for (int i = 0; i < 3; ++i) { char* k = MallocStringKey('A' + i); char* v = MallocStringValue('A' + i); assert_int_equal(ArrayMapInsert(m, k, v), 2); } assert_int_equal(m->size, 3); // Test replacing for (int i = 0; i < 3; ++i) { char* k = MallocStringKey('A' + i); char* v = MallocStringKey('0' + i); assert_int_equal(ArrayMapInsert(m, k, v), 1); } assert_int_equal(m->size, 3); // Fill array up to size 14 for (int i = 0; i < 14 - 3; ++i) { ArrayMapInsert(m, MallocStringKey('a' + i), MallocStringValue('a' + i)); } assert_int_equal(m->size, 14); // Test (no) insertion for size > 14 for (int i = 0; i < 3; ++i) { char* k = MallocStringKey('\0'); char* v = MallocStringValue('\0'); assert_int_equal(ArrayMapInsert(m, k, v), 0); free(k); free(v); } ArrayMapDestroy(m); } void test_array_map_get(void) { ArrayMap *m = ArrayMapNew(StringEqual_untyped, free, free); // Fill with some test strings for (int i = 0; i < 5; ++i) { char *k = MallocStringKey('A' + i); char *v = MallocStringValue('A' + i); assert_int_equal(ArrayMapInsert(m, k, v), 2); } // Get all the test strings for (int i = 0; i < 5; ++i) { char k[] = ARRAY_STRING_KEY('A' + i); MapKeyValue *pair = ArrayMapGet(m, k); assert_true(pair != NULL); assert_string_equal(pair->key, (char[]) ARRAY_STRING_KEY('A' + i)); assert_string_equal(pair->value, (char[]) ARRAY_STRING_VALUE('A' + i)); } // Get non existent keys for (int i = 0; i < 5; ++i) { char k[] = ARRAY_STRING_KEY('a' + i); MapKeyValue *pair = ArrayMapGet(m, k); assert_true(pair == NULL); } ArrayMapDestroy(m); } static void test_array_map_remove(void) { ArrayMap *m = ArrayMapNew(StringEqual_untyped, free, free); // Fill with some test strings for (int i = 0; i < 5; ++i) { char *k = MallocStringKey('A' + i); char *v = MallocStringValue('A' + i); assert_int_equal(ArrayMapInsert(m, k, v), 2); } // Remove all keys one by one in reverse order for (int i = 4; i >= 0; --i) { char k[] = ARRAY_STRING_KEY('A' + 4 - i); assert_true(ArrayMapRemove(m, k)); assert_true(ArrayMapGet(m, k) == NULL); } // Try to remove non existent keys for (int i = 0; i < 5; ++i) { char k[] = ARRAY_STRING_KEY('A' + i); assert_false(ArrayMapRemove(m, k)); } ArrayMapDestroy(m); } static void test_array_map_soft_destroy(void) { ArrayMap *m = ArrayMapNew(StringEqual_untyped, free, free); // Generate some pairs and keep track of values char *values[5]; for (int i = 0; i < 5; ++i) { char *k = MallocStringKey('A' + i); char *v = MallocStringValue('A' + i); values[i] = v; assert_int_equal(ArrayMapInsert(m, k, v), 2); } // Soft destroy and free them manually (should not double free) // DEV: perhaps too... much? ArrayMapSoftDestroy(m); for (int i = 0; i < 5; ++i) { free(values[i]); } } /* A special struct for *Value* in the Map, that references the Key. */ typedef struct { char *keyref; /* pointer to the key */ int val; /* arbitrary value */ } TestValue; /* This tests that in case we insert a pre-existing key, so that the value * gets replaced, the key also gets replaced despite being the same so that * any references in the new value are not invalid. */ static void test_array_map_key_referenced_in_value(void) { ArrayMap *m = ArrayMapNew(StringEqual_untyped, free, free); char *key1 = xstrdup("blah"); TestValue *val1 = xmalloc(sizeof(*val1)); val1->keyref = key1; val1->val = 1; /* Return value of 2 means: new value was inserted. */ assert_int_equal(ArrayMapInsert(m, key1, val1), 2); /* Now we insert the same key, so that it replaces the value. */ char *key2 = xstrdup("blah"); /* same key string */ TestValue *val2 = xmalloc(sizeof(*val2)); val2->keyref = key2; val2->val = 2; /* Return value of 1 means: key preexisted, old data is replaced. */ assert_int_equal(ArrayMapInsert(m, key2, val2), 1); /* And now the important bit: make sure that both "key" and "val->key" are * the same pointer. */ /* WARNING: key1 and val1 must have been freed, but there is no way to * test that. */ { MapKeyValue *keyval = ArrayMapGet(m, key2); assert_true(keyval != NULL); char *key = keyval->key; TestValue *val = keyval->value; assert_true(val->keyref == key); assert_int_equal(val->val, 2); /* Valgrind will barf on the next line if the key has freed by * mistake. */ assert_true(strcmp(val->keyref, "blah") == 0); /* A bit irrelevant: make sure that using "blah" in the lookup yields * the same results, as the string is the same as in key2. */ MapKeyValue *keyval2 = ArrayMapGet(m, "blah"); assert_true(keyval2 == keyval); } ArrayMapDestroy(m); } static void test_array_map_iterator(void) { ArrayMap *m = ArrayMapNew(StringEqual_untyped, free, free); // Fill with some test strings for (int i = 0; i < 5; ++i) { char *k = MallocStringKey('A' + i); char *v = MallocStringValue('A' + i); assert_int_equal(ArrayMapInsert(m, k, v), 2); } // Consume iterator ArrayMapIterator iter = ArrayMapIteratorInit(m); assert_true(iter.map == m); for (int i = 0; i < 5; ++i) { char k[] = ARRAY_STRING_KEY('A' + i); char v[] = ARRAY_STRING_VALUE('A' + i); MapKeyValue *pair = ArrayMapIteratorNext(&iter); assert_true(pair != NULL); assert_string_equal(pair->key, k); assert_string_equal(pair->value, v); } // Consumed iterator should return NULL for (int i = 0; i < 5; ++i) { assert_true(ArrayMapIteratorNext(&iter) == NULL); } ArrayMapDestroy(m); } /* Same purpose as the above test. */ static void test_hash_map_key_referenced_in_value(void) { HashMap *m = HashMapNew(StringHash_untyped, StringEqual_untyped, free, free, HASH_MAP_INIT_SIZE); char *key1 = xstrdup("blah"); TestValue *val1 = xmalloc(sizeof(*val1)); val1->keyref = key1; val1->val = 1; /* Return value false means: new value was inserted. */ assert_false(HashMapInsert(m, key1, val1)); /* Now we insert the same key, so that it replaces the value. */ char *key2 = xstrdup("blah"); /* same key string */ TestValue *val2 = xmalloc(sizeof(*val2)); val2->keyref = key2; val2->val = 2; /* Return value true means: key preexisted, old data is replaced. */ assert_true(HashMapInsert(m, key2, val2)); /* And now the important bit: make sure that both "key" and "val->key" are * the same pointer. */ /* WARNING: key1 and val1 must have been freed, but there is no way to * test that. */ { MapKeyValue *keyval = HashMapGet(m, key2); assert_true(keyval != NULL); char *key = keyval->key; TestValue *val = keyval->value; assert_true(val->keyref == key); /* THIS IS WHAT IT'S ALL ABOUT! */ assert_int_equal(val->val, 2); /* Valgrind will barf on the next line if the key has freed by * mistake. */ assert_true(strcmp(val->keyref, "blah") == 0); /* A bit irrelevant: make sure that using "blah" in the lookup yields * the same results, as the string is the same as in key2. */ MapKeyValue *keyval2 = HashMapGet(m, "blah"); assert_true(keyval2 == keyval); } HashMapDestroy(m); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_new_destroy), unit_test(test_new_hashmap_bad_size), unit_test(test_insert), unit_test(test_insert_jumbo), unit_test(test_remove), unit_test(test_grow), unit_test(test_shrink), unit_test(test_no_shrink_below_init_size), unit_test(test_get), unit_test(test_has_key), unit_test(test_clear), unit_test(test_clear_hashmap), unit_test(test_soft_destroy), unit_test(test_hashmap_new_destroy), unit_test(test_hashmap_degenerate_hash_fn), unit_test(test_array_map_insert), unit_test(test_array_map_get), unit_test(test_array_map_remove), unit_test(test_array_map_soft_destroy), unit_test(test_array_map_key_referenced_in_value), unit_test(test_array_map_iterator), unit_test(test_hash_map_key_referenced_in_value), unit_test(test_iterate_jumbo), #ifndef _AIX unit_test(test_insert_jumbo_more), #endif }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/README0000644000000000000000000000640415010704254020151 0ustar00rootroot00000000000000How to add unit tests ===================== 1. Make sure what you are trying to write is actually a unit test. A unit test should execute in milliseconds. If you are testing functionality that e.g. requires a generic agent to be set up, consider writing an acceptance test. A unit test should test a small piece of code (a function) in isolation. 2. You typically want to test some function of a datastructure, e.g. CfAssoc. Check to see if a test suite (e.g. assoc_test.c), exists already. If not, create one. 2.1 (Optional) Creating a new test suite Create a new file, e.g. mystruct_test.c, preferably by copying some existing file so you get the boilerplate. In Makefile.am, append mystruct_test to check_PROGRAMS, and add an automake entry such as mystruct_test_SOURCES = $(MOCKERY_SOURCES) mystruct_test.c mystruct_test_LDADD = ../../libpromises/libpromises.la 3. We are using cmockery as our testing framework. Google for it and read/skim their basic intro page. 4. Suppose you want to test your new ToString function for CfAssoc. In assoc_test.c, you could do the following. 4.1 Write the test static test_to_string(void **state) { /* assert some condition here */ } 4.2 In the main function of assoc_test.c, add the test to the suite int main() { const UnitTest tests[] = { unit_test(test_create_destroy), unit_test(test_copy), unit_test(test_to_string) }; return run_tests(tests); } 5. Mocking. Suppose you want to test some function that calls a database, but you don't want to deal with setting up and managing the state of the database. Furthermore, you don't actually want to test the database in this test. What you need to do is to stub out the function. For example, suppose your tested function calls some DB_Insert("host123", 42); A mock function is a dummy replacement function with NOOP functionality, so in this case, in your test suite, you could add a static int written_measure = -1; static void DB_Insert(const char* key, int measure) { written_measure = measure; } Then, if later your function tries to retrieve it back, you could do static int DB_Query(const char*key) { return written_measure; } Now, the key is to not have the test link towards the actual definition of the function, so in Makefile.am, rather than linking against all of libpromises, you probably want to be more specific, for example str_test_SOURCES = $(MOCKERY_SOURCES) str_test.c ../../libpromises/string_lib.c str_test_LDADD = ../../libcompat/libcompat.la Finally, if you made some mocking functions and you think it will be useful to other tests later, consider extracting them in a separate file, e.g. db_mock.c. 6. Memory checking. We don't really care about the quality of code in the unit tests, but we do care that the code tested is not leaking memory. So it's important to free everything you allocate in the test code. Then, to check to see if your code leaks, you can run valgrind --leak-check=yes .libs/lt-mystruct_test Valgrind can do stuff beyond simple leak checking, so learning about it could be a worthwhile investment. cfengine-3.24.2/libntech/tests/unit/threaded_queue_test.c0000644000000000000000000003624415010704254023465 0ustar00rootroot00000000000000#include #include #include #include /* Memory illustration legend: * * | : memory bounds * * > : head * * < : tail * * ^ : head + tail (empty) * * v : head + tail (at capacity) * * x : used memory * * - : unused memory */ static void test_push_pop(void) { // Initialised with DEFAULT_CAPACITY = 16 ThreadedQueue *queue = ThreadedQueueNew(0, free); // |^---------------| ThreadedQueuePush(queue, xstrdup("1")); // |><--------------| ThreadedQueuePush(queue, xstrdup("2")); // |>x<-------------| ThreadedQueuePush(queue, xstrdup("3")); // |>xx<------------| char *str1; ThreadedQueuePop(queue, (void **)&str1, 0); // |->x<------------| char *str2; ThreadedQueuePop(queue, (void **)&str2, 0); // |--><------------| char *str3; ThreadedQueuePop(queue, (void **)&str3, 0); // |---v------------| assert_string_equal(str1, "1"); assert_string_equal(str2, "2"); assert_string_equal(str3, "3"); free(str1); free(str2); free(str3); ThreadedQueueDestroy(queue); } static void test_pop_empty_and_push_null(void) { ThreadedQueue *queue = ThreadedQueueNew(1, NULL); // |^| assert(ThreadedQueueIsEmpty(queue)); void *i_am_null = NULL; bool ret = ThreadedQueuePop(queue, &i_am_null, 0); // |^| assert(i_am_null == NULL); assert_false(ret); ThreadedQueuePush(queue, i_am_null); // |v| ret = ThreadedQueuePop(queue, &i_am_null, 0); assert(i_am_null == NULL); assert_true(ret); // |^| ThreadedQueueDestroy(queue); } static void test_copy(void) { ThreadedQueue *queue = ThreadedQueueNew(4, free); // queue: |^---| ThreadedQueuePush(queue, xstrdup("1")); // queue: |><--| ThreadedQueuePush(queue, xstrdup("2")); // queue: |>x<-| ThreadedQueuePush(queue, xstrdup("3")); // queue: |>xx<| ThreadedQueue *new_queue = ThreadedQueueCopy(queue); // new_queue: |>xx<| assert(new_queue != NULL); assert_int_equal(ThreadedQueueCount(queue), ThreadedQueueCount(new_queue)); assert_int_equal(ThreadedQueueCapacity(queue), ThreadedQueueCapacity(new_queue)); char *old_str1; ThreadedQueuePop(queue, (void **)&old_str1, 0); // queue: |->x<| char *old_str2; ThreadedQueuePop(queue, (void **)&old_str2, 0); // queue: |--><| char *old_str3; ThreadedQueuePop(queue, (void **)&old_str3, 0); // queue: |---^| char *new_str1; ThreadedQueuePop(new_queue, (void **)&new_str1, 0); // new_queue: |->x<| char *new_str2; ThreadedQueuePop(new_queue, (void **)&new_str2, 0); // new_queue: |--><| char *new_str3; ThreadedQueuePop(new_queue, (void **)&new_str3, 0); // new_queue: |---^| // Check if pointers are equal (since this is a shallow copy) assert(old_str1 == new_str1); assert(old_str2 == new_str2); assert(old_str3 == new_str3); free(old_str1); free(old_str2); free(old_str3); ThreadedQueueSoftDestroy(queue); // Tests expanding the copied queue ThreadedQueuePush(new_queue, xstrdup("1")); // Internal array wraps: // new_queue: |<-->| ThreadedQueuePush(new_queue, xstrdup("2")); // new_queue: |x<->| ThreadedQueuePush(new_queue, xstrdup("3")); // new_queue: |xx<>| ThreadedQueuePush(new_queue, xstrdup("4")); // new_queue: |xxxv| ThreadedQueuePush(new_queue, xstrdup("5")); // Internal array restructured, array moved to end: // new_queue: |<-->xxxx| assert_int_equal(ThreadedQueueCount(new_queue), 5); assert_int_equal(ThreadedQueueCapacity(new_queue), 8); ThreadedQueuePop(new_queue, (void **)&new_str1, 0); // new_queue: |<--->xxx| ThreadedQueuePop(new_queue, (void **)&new_str2, 0); // new_queue: |<---->xx| ThreadedQueuePop(new_queue, (void **)&new_str3, 0); // new_queue: |<----->x| char *new_str4; ThreadedQueuePop(new_queue, (void **)&new_str4, 0); // new_queue: |<------>| char *new_str5; ThreadedQueuePop(new_queue, (void **)&new_str5, 0); // new_queue: |^-------| assert_string_equal(new_str1, "1"); assert_string_equal(new_str2, "2"); assert_string_equal(new_str3, "3"); assert_string_equal(new_str4, "4"); assert_string_equal(new_str5, "5"); free(new_str1); free(new_str2); free(new_str3); free(new_str4); free(new_str5); ThreadedQueueDestroy(new_queue); } static void test_push_report_count(void) { ThreadedQueue *queue = ThreadedQueueNew(0, free); size_t size1 = ThreadedQueuePush(queue, xstrdup("1")); size_t size2 = ThreadedQueuePush(queue, xstrdup("2")); size_t size3 = ThreadedQueuePush(queue, xstrdup("3")); size_t size4 = ThreadedQueuePush(queue, xstrdup("4")); assert_int_equal(size1, 1); assert_int_equal(size2, 2); assert_int_equal(size3, 3); assert_int_equal(size4, 4); ThreadedQueueDestroy(queue); } static void test_expand(void) { ThreadedQueue *queue = ThreadedQueueNew(1, free); // |^| ThreadedQueuePush(queue, xstrdup("spam")); // |v| ThreadedQueuePush(queue, xstrdup("spam")); // |vx| char *tmp; ThreadedQueuePop(queue, (void **)&tmp, 0); // |<>| free(tmp); ThreadedQueuePush(queue, xstrdup("spam")); // |xv| ThreadedQueuePush(queue, xstrdup("spam")); // Internal array restructured: // |<>xx| ThreadedQueuePush(queue, xstrdup("spam")); // |xvxx| ThreadedQueuePush(queue, xstrdup("spam")); // Internal array restructured: // |->xxxx<-| ThreadedQueuePush(queue, xstrdup("spam")); // |->xxxxx<| ThreadedQueuePop(queue, (void **)&tmp, 0); // |-->xxxx<| free(tmp); ThreadedQueuePop(queue, (void **)&tmp, 0); // |--->xxx<| free(tmp); ThreadedQueuePush(queue, xstrdup("spam")); // |<-->xxxx| ThreadedQueuePush(queue, xstrdup("spam")); // |x<->xxxx| ThreadedQueuePush(queue, xstrdup("spam")); // |xx<>xxxx| ThreadedQueuePush(queue, xstrdup("spam")); // |xxxvxxxx| ThreadedQueuePush(queue, xstrdup("spam")); // Internal array restructured // |--->xxxxxxxx<---| ThreadedQueuePush(queue, xstrdup("spam")); // |--->xxxxxxxxx<--| ThreadedQueuePush(queue, xstrdup("spam")); // |--->xxxxxxxxxx<-| assert_int_equal(ThreadedQueueCount(queue), 11); assert_int_equal(ThreadedQueueCapacity(queue), 16); ThreadedQueueDestroy(queue); } static void test_pushn(void) { ThreadedQueue *queue = ThreadedQueueNew(0, NULL); char *strs[] = {"spam1", "spam2", "spam3", "spam4", "spam5"}; size_t count = ThreadedQueuePushN(queue, (void**) strs, 5); assert_int_equal(count, 5); count = ThreadedQueueCount(queue); assert_int_equal(count, 5); for (int i = 0; i < 5; i++) { char *item; ThreadedQueuePop(queue, (void **)&item, 0); assert_string_equal(item, strs[i]); } count = ThreadedQueueCount(queue); assert_int_equal(count, 0); ThreadedQueueDestroy(queue); } static void test_popn(void) { ThreadedQueue *queue = ThreadedQueueNew(0, free); // Initialised with default size 16 // |^---------------| char *strs[] = {"spam1", "spam2", "spam3", "spam4", "spam5"}; for (int i = 0; i < 5; i++) { ThreadedQueuePush(queue, xstrdup(strs[i])); } // |>xxxx<----------| void **data = NULL; size_t count = ThreadedQueuePopN(queue, &data, 5, 0); // |-----^----------| for (size_t i = 0; i < count; i++) { assert_string_equal(data[i], strs[i]); free(data[i]); } free(data); ThreadedQueueDestroy(queue); } static void test_popn_into_array(void) { ThreadedQueue *queue = ThreadedQueueNew(0, free); // Initialised with default size 16 // |^---------------| char *strs[] = {"spam1", "spam2", "spam3", "spam4", "spam5"}; for (int i = 0; i < 5; i++) { ThreadedQueuePush(queue, xstrdup(strs[i])); } // |>xxxx<----------| void *data[7] = {NULL, NULL, NULL, NULL, NULL, "test1", "test2"}; size_t count = ThreadedQueuePopNIntoArray(queue, data, 5, 0); // |-----^----------| assert_int_equal(count, 5); for (size_t i = 0; i < count; i++) { assert_string_equal(data[i], strs[i]); free(data[i]); } assert_string_equal(data[5], "test1"); assert_string_equal(data[6], "test2"); ThreadedQueueDestroy(queue); } static void test_clear(void) { ThreadedQueue *queue = ThreadedQueueNew(0, free); char *strs[] = {"spam1", "spam2", "spam3", "spam4", "spam5"}; for (int i = 0; i < 5; i++) { ThreadedQueuePush(queue, xstrdup(strs[i])); } size_t count = ThreadedQueueCount(queue); assert_int_equal(count, 5); ThreadedQueueClear(queue); count = ThreadedQueueCount(queue); assert_int_equal(count, 0); ThreadedQueuePush(queue, xstrdup(strs[4])); char *item; ThreadedQueuePop(queue, (void **) &item, THREAD_BLOCK_INDEFINITELY); assert_string_equal(item, strs[4]); free(item); ThreadedQueueDestroy(queue); } static void test_clear_and_push(void) { ThreadedQueue *queue = ThreadedQueueNew(0, NULL); char *strs[] = {"spam1", "spam2", "spam3", "spam4", "spam5"}; for (int i = 0; i < 4; i++) { ThreadedQueuePush(queue, strs[i]); } size_t count = ThreadedQueueCount(queue); assert_int_equal(count, 4); count = ThreadedQueueClearAndPush(queue, strs[4]); assert_int_equal(count, 1); count = ThreadedQueueCount(queue); assert_int_equal(count, 1); char *item; ThreadedQueuePop(queue, (void **)&item, 0); assert_string_equal(item, strs[4]); ThreadedQueueDestroy(queue); } // Thread tests static ThreadedQueue *thread_queue; static void *thread_pop() { char *tmp; ThreadedQueuePop(thread_queue, (void **)&tmp, THREAD_BLOCK_INDEFINITELY); assert_string_equal(tmp, "bla"); free(tmp); return NULL; } /** * Used in test_threads_pushn(). Tries to pop 5 items while there should only be * 3 which are all pushed at once. So the attempt should always pop 3 items. */ static void *thread_pop_5_3() { char **items; size_t n_popped = ThreadedQueuePopN(thread_queue, (void***)&items, 5, THREAD_BLOCK_INDEFINITELY); assert_int_equal(n_popped, 3); free(items); return NULL; } static void *thread_push() { char *str = "bla"; ThreadedQueuePush(thread_queue, xstrdup(str)); return NULL; } static void *thread_wait_empty() { ThreadedQueueWaitEmpty(thread_queue, THREAD_BLOCK_INDEFINITELY); ThreadedQueuePush(thread_queue, xstrdup("a_test")); return NULL; } /* Used in the test_threads_clear_empty */ static void *thread_just_wait_empty() { ThreadedQueueWaitEmpty(thread_queue, THREAD_BLOCK_INDEFINITELY); return NULL; } static void test_threads_wait_pop(void) { #define POP_ITERATIONS 100 thread_queue = ThreadedQueueNew(0, free); pthread_t pops[POP_ITERATIONS] = {0}; for (int i = 0; i < POP_ITERATIONS; i++) { int res_create = pthread_create(&(pops[i]), NULL, thread_pop, NULL); assert_int_equal(res_create, 0); } pthread_t pushs[POP_ITERATIONS] = {0}; for (int i = 0; i < POP_ITERATIONS; i++) { int res_create = pthread_create(&(pushs[i]), NULL, thread_push, NULL); assert_int_equal(res_create, 0); } void *retval = NULL; int res; for (int i = 0; i < POP_ITERATIONS; i++) { res = pthread_join(pops[i], retval); assert_int_equal(res, 0); assert(retval == NULL); res = pthread_join(pushs[i], retval); assert_int_equal(res, 0); assert(retval == NULL); } ThreadedQueueDestroy(thread_queue); } static void test_threads_wait_empty(void) { #define WAIT_ITERATIONS 100 thread_queue = ThreadedQueueNew(0, free); pthread_t pushs[WAIT_ITERATIONS] = {0}; for (int i = 0; i < WAIT_ITERATIONS; i++) { int res_create = pthread_create(&(pushs[i]), NULL, thread_push, NULL); assert_int_equal(res_create, 0); } sleep(1); pthread_t wait_thread = 0; int res_create = pthread_create(&wait_thread, NULL, thread_wait_empty, NULL); assert_int_equal(res_create, 0); do { sleep(1); } while (ThreadedQueueCount(thread_queue) != WAIT_ITERATIONS); char **data_array = NULL; size_t arr_size = ThreadedQueuePopN(thread_queue, (void ***)&data_array, WAIT_ITERATIONS, 0); for (size_t i = 0; i < arr_size; i++) { free(data_array[i]); } free(data_array); char *waited_str; ThreadedQueuePop(thread_queue, (void **)&waited_str, 1); assert_string_equal(waited_str, "a_test"); free(waited_str); void *retval = NULL; int res; for (int i = 0; i < WAIT_ITERATIONS; i++) { res = pthread_join(pushs[i], retval); assert_int_equal(res, 0); assert(retval == NULL); } res = pthread_join(wait_thread, retval); assert_int_equal(res, 0); assert(retval == NULL); ThreadedQueueDestroy(thread_queue); } static void test_threads_pushn() { thread_queue = ThreadedQueueNew(0, NULL); pthread_t pop_thread; int res = pthread_create(&pop_thread, NULL, thread_pop_5_3, NULL); assert_int_equal(res, 0); /* give the other thread time to start waiting */ sleep(1); char *strs[] = {"spam1", "spam2", "spam3"}; size_t count = ThreadedQueuePushN(thread_queue, (void **)strs, 3); assert_int_equal(count, 3); res = pthread_join(pop_thread, NULL); assert_int_equal(res, 0); count = ThreadedQueueCount(thread_queue); assert_int_equal(count, 0); ThreadedQueueDestroy(thread_queue); } static void test_threads_clear_empty() { thread_queue = ThreadedQueueNew(0, NULL); char *strs[] = {"spam1", "spam2", "spam3", "spam4", "spam5"}; for (int i = 0; i < 5; i++) { ThreadedQueuePush(thread_queue, strs[i]); } size_t count = ThreadedQueueCount(thread_queue); assert_int_equal(count, 5); pthread_t wait_thread; int res = pthread_create(&wait_thread, NULL, thread_just_wait_empty, NULL); assert_int_equal(res, 0); ThreadedQueueClear(thread_queue); count = ThreadedQueueCount(thread_queue); assert_int_equal(count, 0); res = pthread_join(wait_thread, NULL); assert_int_equal(res, 0); ThreadedQueueDestroy(thread_queue); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_push_pop), unit_test(test_pop_empty_and_push_null), unit_test(test_copy), unit_test(test_push_report_count), unit_test(test_expand), unit_test(test_popn), unit_test(test_popn_into_array), unit_test(test_pushn), unit_test(test_clear), unit_test(test_clear_and_push), unit_test(test_threads_wait_pop), unit_test(test_threads_wait_empty), unit_test(test_threads_pushn), unit_test(test_threads_clear_empty), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/misc_lib_test.c0000644000000000000000000002306015010704254022252 0ustar00rootroot00000000000000#include #include #include #include static void test_unsigned_modulus(void) { assert_int_equal(UnsignedModulus(0, 3), 0); assert_int_equal(UnsignedModulus(1, 3), 1); assert_int_equal(UnsignedModulus(2, 3), 2); assert_int_equal(UnsignedModulus(3, 3), 0); assert_int_equal(UnsignedModulus(4, 3), 1); assert_int_equal(UnsignedModulus(-1, 3), 2); assert_int_equal(UnsignedModulus(-2, 3), 1); assert_int_equal(UnsignedModulus(-3, 3), 0); assert_int_equal(UnsignedModulus(-4, 3), 2); } static void test_upper_power_of_two(void) { assert_int_equal(0, UpperPowerOfTwo(0)); assert_int_equal(1, UpperPowerOfTwo(1)); assert_int_equal(2, UpperPowerOfTwo(2)); assert_int_equal(4, UpperPowerOfTwo(3)); assert_int_equal(16, UpperPowerOfTwo(13)); } /* Generated in python3: >>> for i in range(64): print("{:26} || \\".format("(x == 0x{:x})".format(2**i))) */ #define ISPOW2_FORSURE(x) \ ((x > 0) && \ ( \ (x == 0x1) || \ (x == 0x2) || \ (x == 0x4) || \ (x == 0x8) || \ (x == 0x10) || \ (x == 0x20) || \ (x == 0x40) || \ (x == 0x80) || \ (x == 0x100) || \ (x == 0x200) || \ (x == 0x400) || \ (x == 0x800) || \ (x == 0x1000) || \ (x == 0x2000) || \ (x == 0x4000) || \ (x == 0x8000) || \ (x == 0x10000) || \ (x == 0x20000) || \ (x == 0x40000) || \ (x == 0x80000) || \ (x == 0x100000) || \ (x == 0x200000) || \ (x == 0x400000) || \ (x == 0x800000) || \ (x == 0x1000000) || \ (x == 0x2000000) || \ (x == 0x4000000) || \ (x == 0x8000000) || \ (x == 0x10000000) || \ (x == 0x20000000) || \ (x == 0x40000000) || \ (x == 0x80000000) || \ (x == 0x100000000) || \ (x == 0x200000000) || \ (x == 0x400000000) || \ (x == 0x800000000) || \ (x == 0x1000000000) || \ (x == 0x2000000000) || \ (x == 0x4000000000) || \ (x == 0x8000000000) || \ (x == 0x10000000000) || \ (x == 0x20000000000) || \ (x == 0x40000000000) || \ (x == 0x80000000000) || \ (x == 0x100000000000) || \ (x == 0x200000000000) || \ (x == 0x400000000000) || \ (x == 0x800000000000) || \ (x == 0x1000000000000) || \ (x == 0x2000000000000) || \ (x == 0x4000000000000) || \ (x == 0x8000000000000) || \ (x == 0x10000000000000) || \ (x == 0x20000000000000) || \ (x == 0x40000000000000) || \ (x == 0x80000000000000) || \ (x == 0x100000000000000) || \ (x == 0x200000000000000) || \ (x == 0x400000000000000) || \ (x == 0x800000000000000) || \ (x == 0x1000000000000000) || \ (x == 0x2000000000000000) || \ (x == 0x4000000000000000) || \ (x == 0x8000000000000000) \ )) long count_pow2; #define TYPED_TEST_ISPOW2(orig, T) \ do { \ typeof(T) t = (typeof(T)) orig; \ \ bool ispow = ISPOW2(t); \ bool ispow_forsure = ISPOW2_FORSURE(t); \ \ if (ispow_forsure && !ispow) \ { \ printf("ISPOW2 FAIL for %jd (original value %jd), should be true but is false!\n", \ (intmax_t) t, (intmax_t) orig); \ assert_true(false); \ } \ else if (!ispow_forsure && ispow) \ { \ printf("ISPOW2 FAIL for %jd (original value %jd), should be false but is true!\n", \ (intmax_t) t, (intmax_t) orig); \ assert_true(false); \ } \ if (ispow) \ { \ count_pow2++; \ } \ } while(false); #if 0 else \ { \ printf("PASS: ISPOW2(%jd) == %s\n", \ (intmax_t) t, \ ispow ? "true" : "false"); \ } #endif #define TEST_COUNT 100000 static void test_rand_ISPOW2(void) { for (int i = 0; i < TEST_COUNT; i++) { /* drand48() doesn't give you 64 bits of randomness. */ /* Get two numbers between [0,1) */ double d1 = drand48(); double d2 = drand48(); /* Spread them over the maximum range for 32 bits. */ uint64_t u1 = d1 * UINT32_MAX; uint64_t u2 = d2 * UINT32_MAX; /* Compose them to one fully random 64 bit integer. */ uint64_t x = u1 | (u2 << 32); // printf("====> testing %20ju, signed %20jd, hex 0x%016jx\n", // (uintmax_t) x, (uintmax_t) x, (uintmax_t) x); TYPED_TEST_ISPOW2(x, uint8_t); TYPED_TEST_ISPOW2(x, uint16_t); TYPED_TEST_ISPOW2(x, uint32_t); TYPED_TEST_ISPOW2(x, uint64_t); TYPED_TEST_ISPOW2(x, int8_t); TYPED_TEST_ISPOW2(x, int16_t); TYPED_TEST_ISPOW2(x, int32_t); TYPED_TEST_ISPOW2(x, int64_t); TYPED_TEST_ISPOW2(x, intmax_t); TYPED_TEST_ISPOW2(x, uintmax_t); TYPED_TEST_ISPOW2(x, char); TYPED_TEST_ISPOW2(x, unsigned char); TYPED_TEST_ISPOW2(x, short int); TYPED_TEST_ISPOW2(x, unsigned short int); TYPED_TEST_ISPOW2(x, int); TYPED_TEST_ISPOW2(x, unsigned int); TYPED_TEST_ISPOW2(x, long int); TYPED_TEST_ISPOW2(x, unsigned long int); TYPED_TEST_ISPOW2(x, long long int); TYPED_TEST_ISPOW2(x, unsigned long long int); } printf(" Tested ISPOW2() with %8d numbers in various type combinations" " out of which %8ld where power of 2.\n", TEST_COUNT, count_pow2); } static void test_ISPOW2(void) { assert_true(ISPOW2(1)); assert_true(ISPOW2(0x80000000)); assert_false(ISPOW2(0)); assert_false(ISPOW2(0xFFFFFFFF)); } static void test_ABS(void) { assert_int_equal(ABS(-2), 2); assert_int_equal(ABS(-1), 1); assert_int_equal(ABS( 0), 0); assert_int_equal(ABS( 1), 1); assert_int_equal(ABS( 2), 2); } static void test_putenv_wrapper(void) { assert_true(getenv("UNIT_TEST_VAR") == NULL); putenv_wrapper("UNIT_TEST_VAR=VALUE"); assert_true(getenv("UNIT_TEST_VAR") != NULL); assert_string_equal(getenv("UNIT_TEST_VAR"), "VALUE"); putenv_wrapper("UNIT_TEST_VAR=NEW_VALUE"); assert_true(getenv("UNIT_TEST_VAR") != NULL); assert_string_equal(getenv("UNIT_TEST_VAR"), "NEW_VALUE"); unsetenv("UNIT_TEST_VAR"); assert_true(getenv("UNIT_TEST_VAR") == NULL); } static void test_setenv_wrapper(void) { assert_true(getenv("UNIT_TEST_VAR") == NULL); setenv_wrapper("UNIT_TEST_VAR", "VALUE", 0); assert_true(getenv("UNIT_TEST_VAR") != NULL); assert_string_equal(getenv("UNIT_TEST_VAR"), "VALUE"); setenv_wrapper("UNIT_TEST_VAR", "NEW_VALUE", 1); assert_true(getenv("UNIT_TEST_VAR") != NULL); assert_string_equal(getenv("UNIT_TEST_VAR"), "NEW_VALUE"); setenv_wrapper("UNIT_TEST_VAR", "NO_OVERWRITE", 0); assert_true(getenv("UNIT_TEST_VAR") != NULL); assert_string_equal(getenv("UNIT_TEST_VAR"), "NEW_VALUE"); unsetenv("UNIT_TEST_VAR"); assert_true(getenv("UNIT_TEST_VAR") == NULL); } int main() { srand48(time(NULL)); PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_unsigned_modulus), unit_test(test_upper_power_of_two), unit_test(test_rand_ISPOW2), unit_test(test_ISPOW2), unit_test(test_ABS), unit_test(test_putenv_wrapper), unit_test(test_setenv_wrapper), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/schema.h0000644000000000000000000001451015010704254020677 0ustar00rootroot00000000000000#ifndef SCHEMA_H_ # define SCHEMA_H_ // Printf formatting for xml CUNIT Schema #define CUNIT_INIT \ "<\?xml version=\"1.0\" \?>\n" \ "<\?xml-stylesheet type=\"text/xsl\" href=\"CUnit-Run.xsl\" \?>\n" \ "\n" \ "\n" \ " \n" \ " \n" \ " \n" \ " \n" \ " %s suite \n" #define CUNIT_RUN_TEST_SUCCESS \ " \n" \ " \n" \ " %s \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_START \ " \n" \ " \n" \ " %s \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(%lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(%lld, %lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(%s %s) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_RANGE_LLD \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(value=%lld, min=%lld, max=%lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_SET_LLD \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(value=%lld, number_of_values=%lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_ERROR \ " \n" \ " \n" \ " %s \n" \ " %d \n" #define CUNIT_RUN_SUMMARY \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " %s \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " \n" \ " \n" \ " %s \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " \n" \ " \n" \ " %s \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " \n" \ " \n" \ " File Generated By CUnit v2.1-2 - %s\n" \ " \n" \ "\n" // Printf formatting for xml XS Schema #define XS_INIT_TESTSUITE \ "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>\n" \ "\n" #define XS_TESTCASE \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_RANGE_LLD \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_SET_LLD \ " \n" \ " \n" #define XS_RUN_TEST_ERROR \ " \n" #define XS_TESTCASE_END \ " \n" #define XS_TESTSUITE_END \ "\n" #endif cfengine-3.24.2/libntech/tests/unit/regex_test.c0000644000000000000000000001302115010704254021577 0ustar00rootroot00000000000000#include #ifdef WITH_PCRE2 #include #else #error "PCRE2 required for regex tests" #endif #include #include static void test_match(void) { assert_true(StringMatch("^a.*$", "abc", NULL, NULL)); assert_true(StringMatch("a", "a", NULL, NULL)); assert_true(StringMatch("a", "ab", NULL, NULL)); assert_false(StringMatch("^a.*$", "bac", NULL, NULL)); size_t start, end; bool ret = StringMatch("[a-z]{3}", "abc", &start, &end); assert_true(ret); assert_int_equal(start, 0); assert_int_equal(end, 3); ret = StringMatch("^[a-z]{3}$", "abc", &start, &end); assert_true(ret); assert_int_equal(start, 0); assert_int_equal(end, 3); ret = StringMatch("^[a-z]{3}.*$", "abcdef", &start, &end); assert_true(ret); assert_int_equal(start, 0); assert_int_equal(end, 6); ret = StringMatch("[a-z]{3}.*", "0abcdef", &start, &end); assert_true(ret); assert_int_equal(start, 1); assert_int_equal(end, 7); } static void test_match_full(void) { assert_true(StringMatchFull("^a.*$", "abc")); assert_true(StringMatchFull("a", "a")); assert_false(StringMatchFull("a", "ab")); assert_false(StringMatchFull("^a.*$", "bac")); } static void test_match_with_captures(void) { Seq *ret = StringMatchCaptures("^a(.).*$", "abc", false); assert_true(ret); assert_int_equal(SeqLength(ret), 2); assert_string_equal(BufferData(SeqAt(ret, 0)), "abc"); assert_string_equal(BufferData(SeqAt(ret, 1)), "b"); SeqDestroy(ret); ret = StringMatchCaptures("^a(.).*$", "abc", true); assert_true(ret); assert_int_equal(SeqLength(ret), 4); assert_string_equal(BufferData(SeqAt(ret, 0)), "0"); assert_string_equal(BufferData(SeqAt(ret, 1)), "abc"); assert_string_equal(BufferData(SeqAt(ret, 2)), "1"); assert_string_equal(BufferData(SeqAt(ret, 3)), "b"); SeqDestroy(ret); ret = StringMatchCaptures("^a(?..)d*$", "abcd", false); assert_true(ret); assert_int_equal(SeqLength(ret), 2); assert_string_equal(BufferData(SeqAt(ret, 0)), "abcd"); assert_string_equal(BufferData(SeqAt(ret, 1)), "bc"); SeqDestroy(ret); ret = StringMatchCaptures("^a(?..)d*$", "abcd", true); assert_true(ret); assert_int_equal(SeqLength(ret), 4); assert_string_equal(BufferData(SeqAt(ret, 0)), "0"); assert_string_equal(BufferData(SeqAt(ret, 1)), "abcd"); assert_string_equal(BufferData(SeqAt(ret, 2)), "mid"); assert_string_equal(BufferData(SeqAt(ret, 3)), "bc"); SeqDestroy(ret); } void test_search_and_replace(void) { Buffer *buf = BufferNewFrom("abcd", 4); const char *err = BufferSearchAndReplace(buf, "b", "B", ""); assert_false(err); assert_string_equal(BufferData(buf), "aBcd"); err = BufferSearchAndReplace(buf, "cd$", "CDef", ""); assert_false(err); assert_string_equal(BufferData(buf), "aBCDef"); err = BufferSearchAndReplace(buf, "([A-Z]{2})([a-z]{2})", "$2$1", ""); assert_false(err); assert_string_equal(BufferData(buf), "aBefCD"); err = BufferSearchAndReplace(buf, "([a-z]{2})([A-Z]{2})", "\\2\\1", ""); assert_false(err); assert_string_equal(BufferData(buf), "aBCDef"); err = BufferSearchAndReplace(buf, "abcdef", "abcd", "i"); assert_false(err); assert_string_equal(BufferData(buf), "abcd"); err = BufferSearchAndReplace(buf, "bc", "$`$'", ""); assert_false(err); assert_string_equal(BufferData(buf), "aadd"); err = BufferSearchAndReplace(buf, "aadd", "$`$'abcd", ""); assert_false(err); assert_string_equal(BufferData(buf), "abcd"); err = BufferSearchAndReplace(buf, "a([a-z])([a-z])d", "a$2$1d [$+]", ""); assert_false(err); assert_string_equal(BufferData(buf), "acbd [2]"); err = BufferSearchAndReplace(buf, "a([a-z])([a-z])d", "a$2$1d [$&]", ""); assert_false(err); assert_string_equal(BufferData(buf), "abcd [acbd] [2]"); err = BufferSearchAndReplace(buf, "a", "A", "g"); assert_false(err); assert_string_equal(BufferData(buf), "Abcd [Acbd] [2]"); err = BufferSearchAndReplace(buf, "(\\w+).*", "$1", ""); assert_false(err); assert_string_equal(BufferData(buf), "Abcd"); BufferDestroy(buf); } void test_search_and_replace_bad_backrefs(void) { /* According to 01_vars/02_functions/regex_replace.cf test in CFEngine core * repo, backrefs that don't have their respective capture groups should not * cause errors but should be replaced with empty strings */ Buffer *buf = BufferNewFrom("abcdefghij", 10); const char *err = BufferSearchAndReplace(buf, "...", "[cap=\\1\\2\\3\\4\\5\\6\\7\\8\\9]", "g"); assert_false(err); assert_string_equal(BufferData(buf), "[cap=][cap=][cap=]j"); BufferDestroy(buf); buf = BufferNewFrom("abcdefghij", 10); err = BufferSearchAndReplace(buf, "(.)(.)(.)", "[cap=\\1\\2\\3\\4\\5\\6\\7\\8\\9]", "g"); assert_false(err); assert_string_equal(BufferData(buf), "[cap=abc][cap=def][cap=ghi]j"); BufferDestroy(buf); buf = BufferNewFrom("abcdefghij", 10); err = BufferSearchAndReplace(buf, "(.)(.)(.)", "[cap=$1$2$3$4$5$6$7$8$9$10$11$888]", "g"); assert_false(err); assert_string_equal(BufferData(buf), "[cap=abc][cap=def][cap=ghi]j"); BufferDestroy(buf); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_match), unit_test(test_match_full), unit_test(test_match_with_captures), unit_test(test_search_and_replace), unit_test(test_search_and_replace_bad_backrefs), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/cmockery.c0000644000000000000000000021553115010704254021254 0ustar00rootroot00000000000000/* LCOV_EXCL_STOP */ /* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* LCOV_EXCL_START */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_MALLOC_H # include #endif #include #ifndef _WIN32 # include #endif // !_WIN32 #include #include #include #include #include #include #include #include #ifdef _WIN32 # include #endif // _WIN32 #include #include #include /* Backwards compatibility with headers shipped with Visual Studio 2005 and * earlier. */ #ifdef _WIN32 WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); #endif // _WIN32 // Size of guard bytes around dynamically allocated blocks. #define MALLOC_GUARD_SIZE 16 // Pattern used to initialize guard blocks. #define MALLOC_GUARD_PATTERN 0xEF // Pattern used to initialize memory allocated with test_malloc(). #define MALLOC_ALLOC_PATTERN 0xBA #define MALLOC_FREE_PATTERN 0xCD // Alignment of allocated blocks. NOTE: This must be base2. #define MALLOC_ALIGNMENT sizeof(size_t) // Printf formatting for source code locations. #define SOURCE_LOCATION_FORMAT "%s:%d" // Calculates the number of elements in an array. #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) // Declare and initialize the pointer member of ValuePointer variable name // with ptr. #define declare_initialize_value_pointer_pointer(name, ptr) \ ValuePointer name ; \ name.value = 0; \ name.pointer = (void*)(ptr) // Declare and initialize the value member of ValuePointer variable name // with val. #define declare_initialize_value_pointer_value(name, val) \ ValuePointer name ; \ name.value = val // Cast a LargestIntegralType to pointer_type via a ValuePointer. #define cast_largest_integral_type_to_pointer( \ pointer_type, largest_integral_type) \ ((pointer_type)((ValuePointer*)&(largest_integral_type))->pointer) // Used to cast LargestIntegralType to void* and vice versa. typedef union ValuePointer { LargestIntegralType value; void *pointer; } ValuePointer; // Doubly linked list node. typedef struct ListNode { const void *value; int refcount; struct ListNode *next; struct ListNode *prev; } ListNode; // Debug information for malloc(). typedef struct MallocBlockInfo { void *block; // Address of the block returned by malloc(). size_t allocated_size; // Total size of the allocated block. size_t size; // Request block size. SourceLocation location; // Where the block was allocated. ListNode node; // Node within list of all allocated blocks. } MallocBlockInfo; // State of each test. typedef struct TestState { const ListNode *check_point; // Check point of the test if there's a // setup function. void *state; // State associated with the test. } TestState; // Determines whether two values are the same. typedef int (*EqualityFunction) (const void *left, const void *right); // Value of a symbol and the place it was declared. typedef struct SymbolValue { SourceLocation location; LargestIntegralType value; } SymbolValue; /* Contains a list of values for a symbol. * NOTE: Each structure referenced by symbol_values_list_head must have a * SourceLocation as its' first member. */ typedef struct SymbolMapValue { const char *symbol_name; ListNode symbol_values_list_head; } SymbolMapValue; // Used by list_free() to deallocate values referenced by list nodes. typedef void (*CleanupListValue) (const void *value, void *cleanup_value_data); // Structure used to check the range of integer types. typedef struct CheckIntegerRange { CheckParameterEvent event; LargestIntegralType minimum; LargestIntegralType maximum; } CheckIntegerRange; // Structure used to check whether an integer value is in a set. typedef struct CheckIntegerSet { CheckParameterEvent event; const LargestIntegralType *set; size_t size_of_set; } CheckIntegerSet; /* Used to check whether a parameter matches the area of memory referenced by * this structure. */ typedef struct CheckMemoryData { CheckParameterEvent event; const void *memory; size_t size; } CheckMemoryData; static ListNode *list_initialize(ListNode *const node); static ListNode *list_add(ListNode *const head, ListNode *new_node); static ListNode *list_add_value(ListNode *const head, const void *value, const int count); static ListNode *list_remove(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data); static void list_remove_free(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data); static int list_empty(const ListNode *const head); static int list_find(ListNode *const head, const void *value, const EqualityFunction equal_func, ListNode **output); static int list_first(ListNode *const head, ListNode **output); static ListNode *list_free(ListNode *const head, const CleanupListValue cleanup_value, void *const cleanup_value_data); static void add_symbol_value(ListNode *const symbol_map_head, const char *const symbol_names[], const size_t number_of_symbol_names, const void *value, const int count); static int get_symbol_value(ListNode *const symbol_map_head, const char *const symbol_names[], const size_t number_of_symbol_names, void **output); static void free_value(const void *value, void *cleanup_value_data); static void free_symbol_map_value(const void *value, void *cleanup_value_data); static void remove_always_return_values(ListNode *const map_head, const size_t number_of_symbol_names); static int check_for_leftover_values(const ListNode *const map_head, const char *const error_message, const size_t number_of_symbol_names); // This must be called at the beginning of a test to initialize some data // structures. static void initialize_testing(void); // This must be called at the end of a test to free() allocated structures. static void teardown_testing(void); // Keeps track of the calling context returned by setenv() so that the fail() // method can jump out of a test. static jmp_buf global_run_test_env; static int global_running_test = 0; // Keeps track of the calling context returned by setenv() so that // mock_assert() can optionally jump back to expect_assert_failure(). jmp_buf global_expect_assert_env; const char *global_expect_assert_expression; int global_expecting_assert = 0; // Keeps a map of the values that functions will have to return to provide // mocked interfaces. static ListNode global_function_result_map_head; // Location of the last mock value returned was declared. static SourceLocation global_last_mock_value_location; /* Keeps a map of the values that functions expect as parameters to their * mocked interfaces. */ static ListNode global_function_parameter_map_head; // Location of last parameter value checked was declared. static SourceLocation global_last_parameter_location; // List of all currently allocated blocks. static ListNode global_allocated_blocks; // Data of running tests for XML output. static int global_errors; static const char *global_filename; static const char *global_xmlfile; static int global_is_file_writer_test; /* bool, but type not defined here */ #ifndef _WIN32 // Signals caught by exception_handler(). static const int exception_signals[] = { SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, }; // Default signal functions that should be restored after a test is complete. typedef void (*SignalFunction) (int signal); static SignalFunction default_signal_functions[ARRAY_LENGTH(exception_signals)]; #else // _WIN32 // The default exception filter. static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; // Fatal exceptions. typedef struct ExceptionCodeInfo { DWORD code; const char *description; } ExceptionCodeInfo; # define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} static const ExceptionCodeInfo exception_codes[] = { EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), }; #endif // !_WIN32 static void exit_test(void) FUNC_ATTR_NORETURN; // Exit the currently executing test. static void exit_test(void) { if (global_running_test) { longjmp(global_run_test_env, 1); } else { exit(-1); } } #ifdef _WIN32 // Exit the currently executing test. static void exit_test_no_app(void) { if (global_running_test) { longjmp(global_run_test_env, 1); } } #endif // Initialize a SourceLocation structure. static void initialize_source_location(SourceLocation *const location) { assert_true(location); location->file = NULL; location->line = 0; } // Determine whether a source location is currently set. static int source_location_is_set(const SourceLocation *const location) { assert_true(location); return location->file && location->line; } // Set a source location. static void set_source_location(SourceLocation *const location, const char *const file, const int line) { assert_true(location); location->file = file; location->line = line; } // Create function results and expected parameter lists. void initialize_testing(void) { list_initialize(&global_function_result_map_head); initialize_source_location(&global_last_mock_value_location); list_initialize(&global_function_parameter_map_head); initialize_source_location(&global_last_parameter_location); } static void fail_if_leftover_values(const char *test_name) { int error_occurred = 0; remove_always_return_values(&global_function_result_map_head, 1); if (check_for_leftover_values(&global_function_result_map_head, "%s() has remaining non-returned values.\n", 1)) { print_xml(XS_RUN_TEST_ERROR "\"%s() has remaining non-returned values.\">\n" XS_RUN_TEST_ERROR_END, "fail_if_leftover_values", test_name); error_occurred = 1; } remove_always_return_values(&global_function_parameter_map_head, 2); if (check_for_leftover_values(&global_function_parameter_map_head, "%s parameter still has values that haven't been checked.\n", 2)) { print_xml(XS_RUN_TEST_ERROR "\"%s parameter still has values that haven't been checked.\">\n" XS_RUN_TEST_ERROR_END, "fail_if_leftover_values", test_name); error_occurred = 1; } if (error_occurred) { global_errors++; exit_test(); } } void teardown_testing(void) { list_free(&global_function_result_map_head, free_symbol_map_value, (void *) 0); initialize_source_location(&global_last_mock_value_location); list_free(&global_function_parameter_map_head, free_symbol_map_value, (void *) 1); initialize_source_location(&global_last_parameter_location); } // Initialize a list node. static ListNode *list_initialize(ListNode *const node) { node->value = NULL; node->next = node; node->prev = node; node->refcount = 1; return node; } /* Adds a value at the tail of a given list. * The node referencing the value is allocated from the heap. */ static ListNode *list_add_value(ListNode *const head, const void *value, const int refcount) { ListNode *const new_node = (ListNode *) malloc(sizeof(ListNode)); assert_true(head); assert_true(value); new_node->value = value; new_node->refcount = refcount; return list_add(head, new_node); } // Add new_node to the end of the list. static ListNode *list_add(ListNode *const head, ListNode *new_node) { assert_true(head); assert_true(new_node); new_node->next = head; new_node->prev = head->prev; head->prev->next = new_node; head->prev = new_node; return new_node; } // Remove a node from a list. static ListNode *list_remove(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data) { assert_true(node); node->prev->next = node->next; node->next->prev = node->prev; if (cleanup_value) { cleanup_value(node->value, cleanup_value_data); } return node; } /* Remove a list node from a list and free the node. */ static void list_remove_free(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data) { assert_true(node); free(list_remove(node, cleanup_value, cleanup_value_data)); } /* Frees memory kept by a linked list * The cleanup_value function is called for every "value" field of nodes in the * list, except for the head. In addition to each list value, * cleanup_value_data is passed to each call to cleanup_value. The head * of the list is not deallocated. */ static ListNode *list_free(ListNode *const head, const CleanupListValue cleanup_value, void *const cleanup_value_data) { assert_true(head); while (!list_empty(head)) { list_remove_free(head->next, cleanup_value, cleanup_value_data); } return head; } // Determine whether a list is empty. static int list_empty(const ListNode *const head) { assert_true(head); return head->next == head; } /* Find a value in the list using the equal_func to compare each node with the * value. */ static int list_find(ListNode *const head, const void *value, const EqualityFunction equal_func, ListNode **output) { ListNode *current; assert_true(head); for (current = head->next; current != head; current = current->next) { if (equal_func(current->value, value)) { *output = current; return 1; } } return 0; } // Returns the first node of a list static int list_first(ListNode *const head, ListNode **output) { ListNode *target_node; assert_true(head); if (list_empty(head)) { return 0; } target_node = head->next; *output = target_node; return 1; } #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__ * 10) >= 240) # define ARG_UNUSED __attribute__((unused)) #else # define ARG_UNUSED #endif // Deallocate a value referenced by a list. static void free_value(const void *value, ARG_UNUSED void *cleanup_value_data) { assert_true(value); free((void *) value); } // Releases memory associated to a symbol_map_value. static void free_symbol_map_value(const void *value, void *cleanup_value_data) { SymbolMapValue *const map_value = (SymbolMapValue *) value; const uintptr_t children = (uintptr_t) cleanup_value_data; assert_true(value); list_free(&map_value->symbol_values_list_head, children ? free_symbol_map_value : free_value, (void *) (children - 1)); free(map_value); } /* Determine whether a symbol name referenced by a symbol_map_value * matches the specified function name. */ static int symbol_names_match(const void *map_value, const void *symbol) { return !strcmp(((SymbolMapValue *) map_value)->symbol_name, (const char *) symbol); } /* Adds a value to the queue of values associated with the given * hierarchy of symbols. It's assumed value is allocated from the heap. */ static void add_symbol_value(ListNode *const symbol_map_head, const char *const symbol_names[], const size_t number_of_symbol_names, const void *value, const int refcount) { const char *symbol_name; ListNode *target_node; SymbolMapValue *target_map_value; assert_true(symbol_map_head); assert_true((const char *const *)symbol_names); assert_true(number_of_symbol_names); symbol_name = symbol_names[0]; if (!list_find(symbol_map_head, symbol_name, symbol_names_match, &target_node)) { SymbolMapValue *const new_symbol_map_value = malloc(sizeof(*new_symbol_map_value)); new_symbol_map_value->symbol_name = symbol_name; list_initialize(&new_symbol_map_value->symbol_values_list_head); target_node = list_add_value(symbol_map_head, new_symbol_map_value, 1); } target_map_value = (SymbolMapValue *) target_node->value; if (number_of_symbol_names == 1) { list_add_value(&target_map_value->symbol_values_list_head, value, refcount); } else { add_symbol_value(&target_map_value->symbol_values_list_head, &symbol_names[1], number_of_symbol_names - 1, value, refcount); } } /* Gets the next value associated with the given hierarchy of symbols. * The value is returned as an output parameter with the function returning the * node's old refcount value if a value is found, 0 otherwise. * This means that a return value of 1 indicates the node was just removed from * the list. */ static int get_symbol_value(ListNode *const head, const char *const symbol_names[], const size_t number_of_symbol_names, void **output) { const char *symbol_name; ListNode *target_node; assert_true(head); assert_true((const char *const *)symbol_names); assert_true(number_of_symbol_names); assert_true(output); symbol_name = symbol_names[0]; if (list_find(head, symbol_name, symbol_names_match, &target_node)) { SymbolMapValue *map_value; ListNode *child_list; int return_value = 0; assert_true(target_node); assert_true(target_node->value); map_value = (SymbolMapValue *) target_node->value; child_list = &map_value->symbol_values_list_head; if (number_of_symbol_names == 1) { ListNode *value_node = NULL; return_value = list_first(child_list, &value_node); assert_true(return_value); *output = (void *) value_node->value; return_value = value_node->refcount; if (--value_node->refcount == 0) { list_remove_free(value_node, NULL, NULL); } } else { return_value = get_symbol_value(child_list, &symbol_names[1], number_of_symbol_names - 1, output); } if (list_empty(child_list)) { list_remove_free(target_node, free_symbol_map_value, (void *) 0); } return return_value; } else { print_error("No entries for symbol %s.\n", symbol_name); } return 0; } /* Traverse down a tree of symbol values and remove the first symbol value * in each branch that has a refcount < -1 (i.e should always be returned * and has been returned at least once). */ static void remove_always_return_values(ListNode *const map_head, const size_t number_of_symbol_names) { ListNode *current; assert_true(map_head); assert_true(number_of_symbol_names); current = map_head->next; while (current != map_head) { SymbolMapValue *const value = (SymbolMapValue *) current->value; ListNode *const next = current->next; ListNode *child_list; assert_true(value); child_list = &value->symbol_values_list_head; if (!list_empty(child_list)) { if (number_of_symbol_names == 1) { ListNode *const child_node = child_list->next; // If this item has been returned more than once, free it. if (child_node->refcount < -1) { list_remove_free(child_node, free_value, NULL); } } else { remove_always_return_values(child_list, number_of_symbol_names - 1); } } if (list_empty(child_list)) { list_remove_free(current, free_value, NULL); } current = next; } } /* Checks if there are any leftover values set up by the test that were never * retrieved through execution, and fail the test if that is the case. */ static int check_for_leftover_values(const ListNode *const map_head, const char *const error_message, const size_t number_of_symbol_names) { const ListNode *current; int symbols_with_leftover_values = 0; assert_true(map_head); assert_true(number_of_symbol_names); for (current = map_head->next; current != map_head; current = current->next) { const SymbolMapValue *const value = (SymbolMapValue *) current->value; const ListNode *child_list; assert_true(value); child_list = &value->symbol_values_list_head; if (!list_empty(child_list)) { if (number_of_symbol_names == 1) { const ListNode *child_node; print_error(error_message, value->symbol_name); print_error(" Remaining item(s) declared at...\n"); for (child_node = child_list->next; child_node != child_list; child_node = child_node->next) { const SourceLocation *const location = child_node->value; print_error(" " SOURCE_LOCATION_FORMAT "\n", location->file, location->line); } } else { print_error("%s.", value->symbol_name); check_for_leftover_values(child_list, error_message, number_of_symbol_names - 1); } symbols_with_leftover_values++; } } return symbols_with_leftover_values; } LargestIntegralType _cast_to_largest_integral_type(size_t size, ...) { LargestIntegralType ret; va_list args; va_start(args, size); if (size <= sizeof(unsigned int)) { ret = va_arg(args, unsigned int); } else if (size <= sizeof(unsigned long)) { ret = va_arg(args, unsigned long); } else if (size <= sizeof(LargestIntegralType)) { ret = va_arg(args, LargestIntegralType); } else { assert(size <= sizeof(LargestIntegralType)); exit(255); } return ret; } // Get the next return value for the specified mock function. LargestIntegralType _mock(const char *const function, const char *const file, const int line) { void *result; const int rc = get_symbol_value(&global_function_result_map_head, &function, 1, &result); if (rc) { SymbolValue *const symbol = (SymbolValue *) result; const LargestIntegralType value = symbol->value; global_last_mock_value_location = symbol->location; if (rc == 1) { free(symbol); } return value; } else { print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to mock function %s\n", file, line, function); print_xml(XS_RUN_TEST_ERROR "\"ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to mock function %s\"\n", "_mock", file, line, function); if (source_location_is_set(&global_last_mock_value_location)) { print_error("Previously returned mock value was declared at " SOURCE_LOCATION_FORMAT "\n", global_last_mock_value_location.file, global_last_mock_value_location.line); print_xml(" \"Previously returned mock value was declared at " SOURCE_LOCATION_FORMAT "\">\n" XS_RUN_TEST_ERROR_END, global_last_mock_value_location.file, global_last_mock_value_location.line); } else { print_error("There were no previously returned mock values for " "this test.\n"); print_xml(" \"There were no previously returned mock values for this test.\">\n" XS_RUN_TEST_ERROR_END); } global_errors++; exit_test(); } return 0; } // Add a return value for the specified mock function name. void _will_return(const char *const function_name, const char *const file, const int line, const LargestIntegralType value, const int count) { SymbolValue *const return_value = malloc(sizeof(*return_value)); assert_true(count > 0 || count == -1); return_value->value = value; set_source_location(&return_value->location, file, line); add_symbol_value(&global_function_result_map_head, &function_name, 1, return_value, count); } /* Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event * parameter is provided it must be allocated on the heap and doesn't need to * be deallocated by the caller. */ void _expect_check(const char *const function, const char *const parameter, const char *const file, const int line, const CheckParameterValue check_function, const LargestIntegralType check_data, CheckParameterEvent *const event, const int count) { CheckParameterEvent *const check = event ? event : malloc(sizeof(*check)); const char *symbols[] = { function, parameter }; check->parameter_name = parameter; check->check_value = check_function; check->check_value_data = check_data; set_source_location(&check->location, file, line); add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, count); } /* Returns 1 if the specified values are equal. If the values are not equal * an error is displayed and 0 is returned. */ static int values_equal_display_error(const LargestIntegralType left, const LargestIntegralType right) { const int equal = left == right; if (!equal) { print_error(LargestIntegralTypePrintfFormat " != " LargestIntegralTypePrintfFormat "\n", left, right); } return equal; } /* Returns 1 if the specified values are not equal. If the values are equal * an error is displayed and 0 is returned. */ static int values_not_equal_display_error(const LargestIntegralType left, const LargestIntegralType right) { const int not_equal = left != right; if (!not_equal) { print_error(LargestIntegralTypePrintfFormat " == " LargestIntegralTypePrintfFormat "\n", left, right); } return not_equal; } /* Determine whether value is contained within check_integer_set. * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is * returned and an error is displayed. If invert is 1 and the value is not * in the set 1 is returned, otherwise 0 is returned and an error is * displayed. */ static int value_in_set_display_error(const LargestIntegralType value, const CheckIntegerSet *const check_integer_set, const int invert) { int succeeded = invert; assert_true(check_integer_set); { const LargestIntegralType *const set = check_integer_set->set; const size_t size_of_set = check_integer_set->size_of_set; size_t i; for (i = 0; i < size_of_set; i++) { if (set[i] == value) { // If invert = 0 and item is found, succeeded = 1. // If invert = 1 and item is found, succeeded = 0. succeeded = !succeeded; break; } } if (succeeded) { return 1; } print_error(LargestIntegralTypePrintfDecimal " is %sin the set (", value, invert ? "" : "not "); for (i = 0; i < size_of_set; i++) { print_error(LargestIntegralTypePrintfDecimal ", ", set[i]); } print_error(")\n"); } return 0; } /* Determine whether a value is within the specified range. If the value is * within the specified range 1 is returned. If the value isn't within the * specified range an error is displayed and 0 is returned. */ static int integer_in_range_display_error(const LargestIntegralType value, const LargestIntegralType range_min, const LargestIntegralType range_max) { if (value >= range_min && value <= range_max) { return 1; } print_error(LargestIntegralTypePrintfDecimal " is not within the range " LargestIntegralTypePrintfDecimal "-" LargestIntegralTypePrintfDecimal "\n", value, range_min, range_max); return 0; } /* Determine whether a value is within the specified range. If the value * is not within the range 1 is returned. If the value is within the * specified range an error is displayed and zero is returned. */ static int integer_not_in_range_display_error(const LargestIntegralType value, const LargestIntegralType range_min, const LargestIntegralType range_max) { if (value < range_min || value > range_max) { return 1; } print_error(LargestIntegralTypePrintfDecimal " is within the range " LargestIntegralTypePrintfDecimal "-" LargestIntegralTypePrintfDecimal "\n", value, range_min, range_max); return 0; } /* Determine whether the specified strings are equal. If the strings are equal * 1 is returned. If they're not equal an error is displayed and 0 is * returned. */ static int string_equal_display_error(const char *const left, const char *const right) { if (strcmp(left, right) == 0) { return 1; } print_error("\"%s\" != \"%s\"\n", left, right); return 0; } /* Determine whether the specified strings are equal. If the strings are not * equal 1 is returned. If they're not equal an error is displayed and 0 is * returned */ static int string_not_equal_display_error(const char *const left, const char *const right) { if (strcmp(left, right) != 0) { return 1; } print_error("\"%s\" == \"%s\"\n", left, right); return 0; } /* Determine whether the specified areas of memory are equal. If they're equal * 1 is returned otherwise an error is displayed and 0 is returned. */ static int memory_equal_display_error(const char *const a, const char *const b, const size_t size) { int differences = 0; size_t i; for (i = 0; i < size; i++) { const char l = a[i]; const char r = b[i]; if (l != r) { print_error("difference at offset %d 0x%02x 0x%02x\n", i, l, r); differences++; } } if (differences) { print_error("%d bytes of 0x%08x and 0x%08x differ\n", differences, a, b); return 0; } return 1; } /* Determine whether the specified areas of memory are not equal. If they're * not equal 1 is returned otherwise an error is displayed and 0 is * returned. */ static int memory_not_equal_display_error(const char *const a, const char *const b, const size_t size) { int same = 0; size_t i; for (i = 0; i < size; i++) { const char l = a[i]; const char r = b[i]; if (l == r) { same++; } } if (same == size) { print_error("%d bytes of 0x%08x and 0x%08x the same\n", same, a, b); return 0; } return 1; } // CheckParameterValue callback to check whether a value is within a set. static int check_in_set(const LargestIntegralType value, const LargestIntegralType check_value_data) { return value_in_set_display_error(value, cast_largest_integral_type_to_pointer(CheckIntegerSet *, check_value_data), 0); } // CheckParameterValue callback to check whether a value isn't within a set. static int check_not_in_set(const LargestIntegralType value, const LargestIntegralType check_value_data) { return value_in_set_display_error(value, cast_largest_integral_type_to_pointer(CheckIntegerSet *, check_value_data), 1); } /* Create the callback data for check_in_set() or check_not_in_set() and * register a check event. */ static void expect_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const CheckParameterValue check_function, const int count) { CheckIntegerSet *const check_integer_set = malloc(sizeof(*check_integer_set) + (sizeof(values[0]) * number_of_values)); LargestIntegralType *const set = (LargestIntegralType *) (check_integer_set + 1); declare_initialize_value_pointer_pointer(check_data, check_integer_set); assert_true((const unsigned long long *)values); assert_true(number_of_values); memcpy(set, values, number_of_values * sizeof(values[0])); check_integer_set->set = set; _expect_check(function, parameter, file, line, check_function, check_data.value, &check_integer_set->event, count); } // Add an event to check whether a value is in a set. void _expect_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count) { expect_set(function, parameter, file, line, values, number_of_values, check_in_set, count); } // Add an event to check whether a value isn't in a set. void _expect_not_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count) { expect_set(function, parameter, file, line, values, number_of_values, check_not_in_set, count); } // CheckParameterValue callback to check whether a value is within a range. static int check_in_range(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckIntegerRange *const check_integer_range = cast_largest_integral_type_to_pointer(CheckIntegerRange *, check_value_data); assert_true(check_integer_range); return integer_in_range_display_error(value, check_integer_range->minimum, check_integer_range->maximum); } // CheckParameterValue callback to check whether a value is not within a range. static int check_not_in_range(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckIntegerRange *const check_integer_range = cast_largest_integral_type_to_pointer(CheckIntegerRange *, check_value_data); assert_true(check_integer_range); return integer_not_in_range_display_error(value, check_integer_range->minimum, check_integer_range->maximum); } /* Create the callback data for check_in_range() or check_not_in_range() and * register a check event. */ static void expect_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const CheckParameterValue check_function, const int count) { CheckIntegerRange *const check_integer_range = malloc(sizeof(*check_integer_range)); declare_initialize_value_pointer_pointer(check_data, check_integer_range); check_integer_range->minimum = minimum; check_integer_range->maximum = maximum; _expect_check(function, parameter, file, line, check_function, check_data.value, &check_integer_range->event, count); } // Add an event to determine whether a parameter is within a range. void _expect_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count) { expect_range(function, parameter, file, line, minimum, maximum, check_in_range, count); } // Add an event to determine whether a parameter is not within a range. void _expect_not_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count) { expect_range(function, parameter, file, line, minimum, maximum, check_not_in_range, count); } /* CheckParameterValue callback to check whether a value is equal to an * expected value. */ static int check_value(const LargestIntegralType value, const LargestIntegralType check_value_data) { return values_equal_display_error(value, check_value_data); } // Add an event to check a parameter equals an expected value. void _expect_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count) { _expect_check(function, parameter, file, line, check_value, value, NULL, count); } /* CheckParameterValue callback to check whether a value is not equal to an * expected value. */ static int check_not_value(const LargestIntegralType value, const LargestIntegralType check_value_data) { return values_not_equal_display_error(value, check_value_data); } // Add an event to check a parameter is not equal to an expected value. void _expect_not_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count) { _expect_check(function, parameter, file, line, check_not_value, value, NULL, count); } // CheckParameterValue callback to check whether a parameter equals a string. static int check_string(const LargestIntegralType value, const LargestIntegralType check_value_data) { return string_equal_display_error(cast_largest_integral_type_to_pointer(char *, value), cast_largest_integral_type_to_pointer(char *, check_value_data)); } // Add an event to check whether a parameter is equal to a string. void _expect_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count) { declare_initialize_value_pointer_pointer(string_pointer, (char *) string); _expect_check(function, parameter, file, line, check_string, string_pointer.value, NULL, count); } /* CheckParameterValue callback to check whether a parameter is not equals to * a string. */ static int check_not_string(const LargestIntegralType value, const LargestIntegralType check_value_data) { return string_not_equal_display_error(cast_largest_integral_type_to_pointer(char *, value), cast_largest_integral_type_to_pointer(char *, check_value_data)); } // Add an event to check whether a parameter is not equal to a string. void _expect_not_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count) { declare_initialize_value_pointer_pointer(string_pointer, (char *) string); _expect_check(function, parameter, file, line, check_not_string, string_pointer.value, NULL, count); } /* CheckParameterValue callback to check whether a parameter equals an area of * memory. */ static int check_memory(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckMemoryData *const check = cast_largest_integral_type_to_pointer(CheckMemoryData *, check_value_data); assert_true(check); return memory_equal_display_error(cast_largest_integral_type_to_pointer(void *, value), check->memory, check->size); } /* Create the callback data for check_memory() or check_not_memory() and * register a check event. */ static void expect_memory_setup(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const CheckParameterValue check_function, const int count) { CheckMemoryData *const check_data = malloc(sizeof(*check_data) + size); void *const mem = (void *) (check_data + 1); declare_initialize_value_pointer_pointer(check_data_pointer, check_data); assert_true(memory); assert_true(size); memcpy(mem, memory, size); check_data->memory = mem; check_data->size = size; _expect_check(function, parameter, file, line, check_function, check_data_pointer.value, &check_data->event, count); } // Add an event to check whether a parameter matches an area of memory. void _expect_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count) { expect_memory_setup(function, parameter, file, line, memory, size, check_memory, count); } /* CheckParameterValue callback to check whether a parameter is not equal to * an area of memory. */ static int check_not_memory(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckMemoryData *const check = cast_largest_integral_type_to_pointer(CheckMemoryData *, check_value_data); assert_true(check); return memory_not_equal_display_error(cast_largest_integral_type_to_pointer(void *, value), check->memory, check->size); } // Add an event to check whether a parameter doesn't match an area of memory. void _expect_not_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count) { expect_memory_setup(function, parameter, file, line, memory, size, check_not_memory, count); } // CheckParameterValue callback that always returns 1. static int check_any(ARG_UNUSED const LargestIntegralType value, ARG_UNUSED const LargestIntegralType check_value_data) { return 1; } // Add an event to allow any value for a parameter. void _expect_any(const char *const function, const char *const parameter, const char *const file, const int line, const int count) { _expect_check(function, parameter, file, line, check_any, 0, NULL, count); } void _check_expected(const char *const function_name, const char *const parameter_name, const char *file, const int line, const LargestIntegralType value) { void *result; const char *symbols[] = { function_name, parameter_name }; const int rc = get_symbol_value(&global_function_parameter_map_head, symbols, 2, &result); if (rc) { CheckParameterEvent *const check = (CheckParameterEvent *) result; int check_succeeded; global_last_parameter_location = check->location; check_succeeded = check->check_value(value, check->check_value_data); if (rc == 1) { free(check); } if (!check_succeeded) { print_error("ERROR: Check of parameter %s, function %s failed\n" "Expected parameter declared at " SOURCE_LOCATION_FORMAT "\n", parameter_name, function_name, global_last_parameter_location.file, global_last_parameter_location.line); print_xml(XS_RUN_TEST_ERROR "\"ERROR: Check of parameter %s, function %s failed\"\n" " \"Expected parameter declared at " SOURCE_LOCATION_FORMAT "\">\n" XS_RUN_TEST_ERROR_END, "check_expected", parameter_name, function_name, global_last_parameter_location.file, global_last_parameter_location.line); global_errors++; _fail(file, line); } } else { print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to check parameter %s of function %s\n", file, line, parameter_name, function_name); print_xml(XS_RUN_TEST_ERROR "\"ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to check parameter %s of function %s\"\n", "check_expected", file, line, parameter_name, function_name); if (source_location_is_set(&global_last_parameter_location)) { print_error("Previously declared parameter value was declared at " SOURCE_LOCATION_FORMAT "\n", global_last_parameter_location.file, global_last_parameter_location.line); print_xml(" \"Previously declared parameter value was declared at " SOURCE_LOCATION_FORMAT "\">\n" XS_RUN_TEST_ERROR_END, global_last_parameter_location.file, global_last_parameter_location.line); } else { print_error("There were no previously declared parameter values " "for this test.\n"); print_xml(" \"There were no previously declared parameter values " "for this test.\">\n" XS_RUN_TEST_ERROR_END); } global_errors++; exit_test (); } } // Replacement for assert. void mock_assert(const int result, const char *const expression, const char *const file, const int line) { if (!result) { if (global_expecting_assert) { global_expect_assert_expression = expression; longjmp(global_expect_assert_env, 1); } else { const char *assertname = "mock_assert"; print_error("ASSERT: %s\n", expression); print_xml (XS_RUN_TEST_FAILURE_ASSERT, assertname, result, global_filename, line, assertname, result); _fail(file, line); } } } void _assert_true(const LargestIntegralType result, const char *const expression, const char *const file, const int line) { if (!result) { const char *assertname = "assert_true"; print_error("%s\n", expression); print_xml (XS_RUN_TEST_FAILURE_ASSERT, assertname, result, global_filename, line, assertname, result); _fail(file, line); } } void _assert_int_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line) { if (!values_equal_display_error(a, b)) { const char *assertname = "assert_int_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_int_not_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line) { if (!values_not_equal_display_error(a, b)) { const char *assertname = "assert_int_not_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_string_equal(const char *const a, const char *const b, const char *const file, const int line) { if (!string_equal_display_error(a, b)) { const char *assertname = "assert_string_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_string_not_equal(const char *const a, const char *const b, const char *file, const int line) { if (!string_not_equal_display_error(a, b)) { const char *assertname = "assert_string_not_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_memory_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line) { if (!memory_equal_display_error((const char *) a, (const char *) b, size)) { const char *assertname = "assert_memory_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_memory_not_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line) { if (!memory_not_equal_display_error((const char *) a, (const char *) b, size)) { const char *assertname = "assert_memory_not_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line) { if (!integer_in_range_display_error(value, minimum, maximum)) { const char *assertname = "assert_in_range"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_RANGE_LLD, assertname, value, minimum, maximum, global_filename, line, assertname, value, minimum, maximum); _fail(file, line); } } void _assert_not_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line) { if (!integer_not_in_range_display_error(value, minimum, maximum)) { const char *assertname = "assert_not_in_range"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_RANGE_LLD, assertname, value, minimum, maximum, global_filename, line, assertname, value, minimum, maximum); _fail(file, line); } } void _assert_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line) { CheckIntegerSet check_integer_set; check_integer_set.set = values; check_integer_set.size_of_set = number_of_values; if (!value_in_set_display_error(value, &check_integer_set, 0)) { const char *assertname = "assert_in_set"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_SET_LLD, assertname, value, number_of_values, global_filename, line, assertname, value, number_of_values); _fail(file, line); } } void _assert_not_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line) { CheckIntegerSet check_integer_set; check_integer_set.set = values; check_integer_set.size_of_set = number_of_values; if (!value_in_set_display_error(value, &check_integer_set, 1)) { const char *assertname = "assert_not_in_set"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_SET_LLD, assertname, value, number_of_values, global_filename, line, assertname, value, number_of_values); _fail(file, line); } } // Get the list of allocated blocks. static ListNode *get_allocated_blocks_list() { // If it initialized, initialize the list of allocated blocks. if (!global_allocated_blocks.value) { list_initialize(&global_allocated_blocks); global_allocated_blocks.value = (void *) 1; } return &global_allocated_blocks; } // Use the real malloc in this function. #undef malloc void *_test_malloc(const size_t size, const char *file, const int line) { char *ptr; MallocBlockInfo *block_info; ListNode *const block_list = get_allocated_blocks_list(); const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) + sizeof(*block_info) + MALLOC_ALIGNMENT; char *const block = (char *) malloc(allocate_size); assert_true(block); // Calculate the returned address. ptr = (char *) (((size_t) block + MALLOC_GUARD_SIZE + sizeof(*block_info) + MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); // Initialize the guard blocks. memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); memset(ptr, MALLOC_ALLOC_PATTERN, size); block_info = (MallocBlockInfo *) (ptr - (MALLOC_GUARD_SIZE + sizeof(*block_info))); set_source_location(&block_info->location, file, line); block_info->allocated_size = allocate_size; block_info->size = size; block_info->block = block; block_info->node.value = block_info; list_add(block_list, &block_info->node); return ptr; } #define malloc test_malloc void *_test_calloc(const size_t number_of_elements, const size_t size, const char *file, const int line) { void *const ptr = _test_malloc(number_of_elements * size, file, line); if (ptr) { memset(ptr, 0, number_of_elements * size); } return ptr; } // Use the real free in this function. #undef free void _test_free(void *const ptr, const char *file, const int line) { unsigned int i; char *block = (char *) ptr; MallocBlockInfo *block_info; _assert_true(ptr != NULL, "ptr", file, line); block_info = (MallocBlockInfo *) (block - (MALLOC_GUARD_SIZE + sizeof(*block_info))); // Check the guard blocks. { char *guards[2] = { block - MALLOC_GUARD_SIZE, block + block_info->size }; for (i = 0; i < ARRAY_LENGTH(guards); i++) { unsigned int j; char *const guard = guards[i]; for (j = 0; j < MALLOC_GUARD_SIZE; j++) { const char diff = guard[j] - MALLOC_GUARD_PATTERN; if (diff) { print_error("Guard block of 0x%08x size=%d allocated by " SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\n", (size_t) ptr, block_info->size, block_info->location.file, block_info->location.line, (size_t) &guard[j]); print_xml(XS_RUN_TEST_ERROR "\"Guard block of 0x%08x size=%d allocated by " SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\">\n" XS_RUN_TEST_ERROR_END, "test_free", (size_t) ptr, block_info->size, block_info->location.file, block_info->location.line, (size_t) &guard[j]); global_errors++; _fail(file, line); } } } } list_remove(&block_info->node, NULL, NULL); block = block_info->block; memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size); free(block); } #define free test_free // Crudely checkpoint the current heap state. static const ListNode *check_point_allocated_blocks() { return get_allocated_blocks_list()->prev; } /* Display the blocks allocated after the specified check point. This * function returns the number of blocks displayed. */ static int display_allocated_blocks(const ListNode *const check_point) { const ListNode *const head = get_allocated_blocks_list(); const ListNode *node; int allocated_blocks = 0; assert_true(check_point); assert_true(check_point->next); for (node = check_point->next; node != head; node = node->next) { const MallocBlockInfo *const block_info = node->value; assert_true(block_info); if (!allocated_blocks) { print_error("Blocks allocated...\n"); } print_error(" 0x%08x : " SOURCE_LOCATION_FORMAT "\n", block_info->block, block_info->location.file, block_info->location.line); allocated_blocks++; } return allocated_blocks; } // Free all blocks allocated after the specified check point. static void free_allocated_blocks(const ListNode *const check_point) { const ListNode *const head = get_allocated_blocks_list(); const ListNode *node; assert_true(check_point); node = check_point->next; assert_true(node); while (node != head) { MallocBlockInfo *const block_info = (MallocBlockInfo *) node->value; node = node->next; free((char *) block_info + sizeof(*block_info) + MALLOC_GUARD_SIZE); } } // Fail if any any blocks are allocated after the specified check point. static void fail_if_blocks_allocated(const ListNode *const check_point, const char *const test_name) { const int allocated_blocks = display_allocated_blocks(check_point); if (allocated_blocks) { free_allocated_blocks(check_point); print_error("ERROR: %s leaked %d block(s)\n", test_name, allocated_blocks); print_xml(XS_RUN_TEST_ERROR "\"ERROR: %s leaked %d block(s)\">\n" XS_RUN_TEST_ERROR_END, "fail_if_blocks_allocated", test_name, allocated_blocks); global_errors++; exit_test(); } } void _fail(const char *const file, const int line) { print_error("ERROR: " SOURCE_LOCATION_FORMAT " Failure!\n", file, line); exit_test(); } #ifndef _WIN32 static void exception_handler(int sig) { print_error("%s\n", strsignal(sig)); print_xml(XS_RUN_TEST_ERROR "\"%s\">\n" XS_RUN_TEST_ERROR_END, "exception_handler", strsignal(sig)); global_errors++; exit_test(); } #else // _WIN32 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { EXCEPTION_RECORD *const exception_record = exception_pointers->ExceptionRecord; const DWORD code = exception_record->ExceptionCode; unsigned int i; for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) { const ExceptionCodeInfo *const code_info = &exception_codes[i]; if (code == code_info->code) { static int shown_debug_message = 0; fflush(stdout); print_error("%s occurred at 0x%08x.\n", code_info->description, exception_record->ExceptionAddress); print_xml(XS_RUN_TEST_ERROR "\"%s occurred at 0x%08x.\">\n" XS_RUN_TEST_ERROR_END, "exception_filter", code_info->description, exception_record->ExceptionAddress); if (!shown_debug_message) { print_error("\n" "To debug in Visual Studio...\n" "1. Select menu item File->Open Project\n" "2. Change 'Files of type' to 'Executable Files'\n" "3. Open this executable.\n" "4. Select menu item Debug->Start\n" "\n" "Alternatively, set the environment variable \n" "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" "then click 'Debug' in the popup dialog box.\n" "\n"); shown_debug_message = 1; } global_errors++; exit_test_no_app(); return EXCEPTION_EXECUTE_HANDLER; } } return EXCEPTION_CONTINUE_SEARCH; } #endif // !_WIN32 void vinit_xml (const char *const format, va_list args) { FILE* xmlfile = fopen(global_xmlfile, "w"); vfprintf(xmlfile, format, args); fclose(xmlfile); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void init_xml (const char *const format, ...) { if (!global_is_file_writer_test) { va_list args; va_start(args, format); vinit_xml(format, args); va_end(args); } } void vprint_xml(const char *const format, va_list args) { FILE* xmlfile = fopen(global_xmlfile, "a"); vfprintf(xmlfile, format, args); fclose(xmlfile); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void print_xml(const char *const format, ...) { if (!global_is_file_writer_test) { va_list args; va_start(args, format); vprint_xml(format, args); va_end(args); } } void append_xml(const char *ofile, const char *ifile) { if (!global_is_file_writer_test) { char ch; FILE* xmlfile = fopen(ofile, "ab"); FILE* xml_tmp = fopen(ifile, "rb"); while(!feof(xml_tmp)) { ch = getc(xml_tmp); if(!feof(xml_tmp)) { putc(ch, xmlfile); } } fclose(xmlfile); fclose(xml_tmp); } } // Standard output and error print methods. void vprint_message(const char *const format, va_list args) { vprintf(format, args); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void vprint_error(const char *const format, va_list args) { vfprintf(stderr, format, args); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void print_message(const char *const format, ...) { va_list args; va_start(args, format); vprint_message(format, args); va_end(args); } void print_error(const char *const format, ...) { va_list args; va_start(args, format); vprint_error(format, args); va_end(args); } int _run_test(const char *const function_name, const UnitTestFunction Function, void **const state, const UnitTestFunctionType function_type, const void *const heap_check_point) { const ListNode *const check_point = heap_check_point ? heap_check_point : check_point_allocated_blocks(); void *current_state = NULL; int rc = 1; int handle_exceptions = 1; #ifdef _WIN32 handle_exceptions = !IsDebuggerPresent(); #endif // _WIN32 #if UNIT_TESTING_DEBUG handle_exceptions = 0; #endif // UNIT_TESTING_DEBUG if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { default_signal_functions[i] = signal(exception_signals[i], exception_handler); } #else // _WIN32 previous_exception_filter = SetUnhandledExceptionFilter(exception_filter); #endif // !_WIN32 } if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST || function_type == UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE) { print_message("%s: Starting test\n", function_name); } initialize_testing(); global_running_test = 1; if (setjmp(global_run_test_env) == 0) { if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { Function(); } else { ((UnitTestFunctionWithState)Function)(state ? state : ¤t_state); } fail_if_leftover_values(function_name); /* If this is a setup function then ignore any allocated blocks * only ensure they're deallocated on tear down. */ if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { fail_if_blocks_allocated(check_point, function_name); } global_running_test = 0; if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST || function_type == UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE) { print_message("%s: Test completed successfully.\n", function_name); } rc = 0; } else { global_running_test = 0; print_message("%s: Test failed.\n", function_name); } teardown_testing(); if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { signal(exception_signals[i], default_signal_functions[i]); } #else // _WIN32 if (previous_exception_filter) { SetUnhandledExceptionFilter(previous_exception_filter); previous_exception_filter = NULL; } #endif // !_WIN32 } return rc; } int _run_tests(const UnitTest *const tests, const size_t number_of_tests, const char *const file) { // Whether to execute the next test. int run_next_test = 1; // Whether the previous test failed. int previous_test_failed = 0; // Check point of the heap state. const ListNode *const check_point = check_point_allocated_blocks(); // Time of testsuite execution time_t time_suite, time_case, time_now; time_t ttime; time(&ttime); char timestamp[1024]; strcpy(timestamp, ctime(&ttime)); timestamp[strlen(timestamp)-1] = '\0'; // Current test being executed. size_t current_test = 0; // Number of tests executed. size_t tests_executed = 0; // Number of failed tests. size_t total_failed = 0; // Number of setup functions. size_t setups = 0; // Number of teardown functions. size_t teardowns = 0; /* A stack of test states. A state is pushed on the stack * when a test setup occurs and popped on tear down. */ TestState *test_states = malloc(number_of_tests * sizeof(*test_states)); size_t number_of_test_states = 0; // Names of the tests that failed. const char **failed_names = malloc(number_of_tests * sizeof(*failed_names)); void **current_state = NULL; // Make sure LargestIntegralType is at least the size of a pointer. assert_true(sizeof(LargestIntegralType) >= sizeof(void *)); //Initialize an xml file and parameters char path[1024] = {0}; char filename[1024] = {0}; char suitename[1024] = {0}; char casename[1024] = {0}; char xmlfile[sizeof(suitename) + sizeof(".xml")] = {0}; int len; strcpy(path, file); strcpy(filename, basename(path)); len = strrchr(filename, '.')-filename; strcpy(suitename, ""); strncat(suitename, filename, len); strcpy(xmlfile, "xml_tmp_suite"); global_filename = filename; global_is_file_writer_test = (0 == strcmp(suitename, "file_writer_test")); global_xmlfile = xmlfile; global_errors = 0; init_xml(""); time(&time_suite); while (current_test < number_of_tests) { const ListNode *test_check_point = NULL; TestState *current_TestState; const UnitTest *const test = &tests[current_test++]; if (!test->f.function) { continue; } switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: case UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE: run_next_test = 1; break; case UNIT_TEST_FUNCTION_TYPE_SETUP: { // Checkpoint the heap before the setup. current_TestState = &test_states[number_of_test_states++]; current_TestState->check_point = check_point_allocated_blocks(); test_check_point = current_TestState->check_point; current_state = ¤t_TestState->state; *current_state = NULL; run_next_test = 1; setups++; break; } case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: // Check the heap based on the last setup checkpoint. assert_true(number_of_test_states); current_TestState = &test_states[--number_of_test_states]; test_check_point = current_TestState->check_point; current_state = ¤t_TestState->state; teardowns++; break; default: print_error("Invalid unit test function type %d\n", test->function_type); print_xml(XS_RUN_TEST_ERROR "\"Invalid unit test function type %d\">\n" XS_RUN_TEST_ERROR_END, "", test->function_type); global_errors++; exit_test(); break; } if (run_next_test) { strcpy(casename, test->name); strcpy(xmlfile, "xml_tmp_case"); init_xml(""); time(&time_case); int failed = _run_test(test->name, test->f.function, current_state, test->function_type, test_check_point); strcpy(xmlfile, "xml_tmp_suite"); time(&time_now); print_xml(XS_TESTCASE, casename, path, difftime(time_now, time_case)); if (failed) { failed_names[total_failed] = test->name; append_xml("xml_tmp_suite", "xml_tmp_case"); } print_xml(XS_TESTCASE_END); switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: case UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE: previous_test_failed = failed; total_failed += failed; tests_executed++; break; case UNIT_TEST_FUNCTION_TYPE_SETUP: if (failed) { total_failed++; tests_executed++; // Skip forward until the next test or setup function. run_next_test = 0; } previous_test_failed = 0; break; case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: // If this test failed. if (failed && !previous_test_failed) { total_failed++; } break; default: assert_false("BUG: shouldn't be here!"); break; } } } snprintf(xmlfile, sizeof(xmlfile), "%s.xml", suitename); time(&time_now); init_xml(XS_INIT_TESTSUITE, suitename, timestamp, "localhost", number_of_tests, total_failed, global_errors, difftime(time_now, time_suite)); append_xml(xmlfile, "xml_tmp_suite"); print_xml(XS_TESTSUITE_END); if (total_failed) { size_t i; print_error("%d out of %d tests failed!\n", total_failed, tests_executed); for (i = 0; i < total_failed; i++) { print_error(" %s\n", failed_names[i]); } } else { print_message("All %d tests passed\n", tests_executed); } if (number_of_test_states) { print_error("Mismatched number of setup %d and teardown %d " "functions\n", setups, teardowns); total_failed = -1; } free(test_states); free((void *) failed_names); fail_if_blocks_allocated(check_point, "run_tests"); return (int) total_failed; } /* LCOV_EXCL_STOP */ cfengine-3.24.2/libntech/tests/unit/sequence_test.c0000644000000000000000000006056515010704254022314 0ustar00rootroot00000000000000#include #include #include #include static Seq *SequenceCreateRange(size_t initialCapacity, size_t start, size_t end) { Seq *seq = SeqNew(initialCapacity, free); for (size_t i = start; i <= end; i++) { size_t *item = xmalloc(sizeof(size_t)); *item = i; SeqAppend(seq, item); } return seq; } static void test_create_destroy(void) { Seq *seq = SeqNew(5, NULL); SeqDestroy(seq); } static void test_append(void) { Seq *seq = SeqNew(2, free); for (size_t i = 0; i < 1000; i++) { SeqAppend(seq, xstrdup("snookie")); } assert_int_equal(seq->length, 1000); for (size_t i = 0; i < 1000; i++) { assert_string_equal(seq->data[i], "snookie"); } SeqDestroy(seq); } static void test_set(void) { Seq *seq = SeqNew(10, free); for (size_t i = 0; i < 10; i++) { SeqAppend(seq, xstrdup("snookie")); } assert_int_equal(seq->length, 10); SeqSet(seq, 0, xstrdup("blah")); assert_int_equal(seq->length, 10); assert_string_equal(SeqAt(seq, 0), "blah"); char *item = SeqAt(seq, 5); assert_string_equal(item, "snookie"); SeqSoftSet(seq, 5, xstrdup("blah")); assert_int_equal(seq->length, 10); assert_string_equal(SeqAt(seq, 5), "blah"); /* SeqSoftSet() shouldn't have destroyed the item so we should (be able to) * free it and SeqDestroy() should destroy the replacement. */ free(item); SeqDestroy(seq); } static int CompareNumbers(const void *a, const void *b, ARG_UNUSED void *_user_data) { return *(size_t *) a - *(size_t *) b; } static void test_append_once(void) { Seq *seq = SequenceCreateRange(10, 0, 9); for (size_t i = 0; i <= 9; i++) { size_t *item = xmalloc(sizeof(size_t)); *item = i; SeqAppendOnce(seq, item, CompareNumbers); } /* none of the numbers above should have been inserted second time */ assert_int_equal(seq->length, 10); size_t *item = xmalloc(sizeof(size_t)); *item = 10; SeqAppendOnce(seq, item, CompareNumbers); /* 10 should have been inserted (as the first instance) */ assert_int_equal(seq->length, 11); SeqDestroy(seq); } static void test_lookup(void) { Seq *seq = SequenceCreateRange(10, 0, 9); size_t *key = xmalloc(sizeof(size_t)); *key = 5; size_t *result = SeqLookup(seq, key, CompareNumbers); assert_int_equal(*result, *key); *key = 17; result = SeqLookup(seq, key, CompareNumbers); assert_int_equal(result, NULL); SeqDestroy(seq); free(key); } static void test_binary_lookup(void) { size_t *key = xmalloc(sizeof(size_t)); size_t *result; // Even numbered length. Seq *seq = SequenceCreateRange(10, 0, 9); for (size_t i = 0; i <= 9; i++) { *key = i; result = SeqBinaryLookup(seq, key, CompareNumbers); assert_int_equal(*result, *key); } *key = 17; result = SeqBinaryLookup(seq, key, CompareNumbers); assert_int_equal(result, NULL); // Odd numbered length. SeqDestroy(seq); seq = SequenceCreateRange(10, 0, 10); for (size_t i = 0; i <= 10; i++) { *key = i; result = SeqBinaryLookup(seq, key, CompareNumbers); assert_int_equal(*result, *key); } *key = 17; result = SeqBinaryLookup(seq, key, CompareNumbers); assert_int_equal(result, NULL); // Zero-length. SeqDestroy(seq); seq = SeqNew(0, free); *key = 0; result = SeqBinaryLookup(seq, key, CompareNumbers); assert_int_equal(result, NULL); SeqDestroy(seq); free(key); } static void test_index_of(void) { Seq *seq = SequenceCreateRange(10, 0, 9); size_t *key = xmalloc(sizeof(size_t)); *key = 5; ssize_t index = SeqIndexOf(seq, key, CompareNumbers); assert_int_equal(index, 5); *key = 17; index = SeqIndexOf(seq, key, CompareNumbers); assert_true(index == -1); SeqDestroy(seq); free(key); } static void test_binary_index_of(void) { size_t *key = xmalloc(sizeof(size_t)); ssize_t result; // Even numbered length. Seq *seq = SequenceCreateRange(10, 0, 9); for (size_t i = 0; i <= 9; i++) { *key = i; result = SeqBinaryIndexOf(seq, key, CompareNumbers); assert_int_equal(result, i); } *key = 17; result = SeqBinaryIndexOf(seq, key, CompareNumbers); assert_true(result == -1); // Odd numbered length. SeqDestroy(seq); seq = SequenceCreateRange(10, 0, 10); for (size_t i = 0; i <= 10; i++) { *key = i; result = SeqBinaryIndexOf(seq, key, CompareNumbers); assert_int_equal(result, i); } *key = 17; result = SeqBinaryIndexOf(seq, key, CompareNumbers); assert_true(result == -1); // Zero-length. SeqDestroy(seq); seq = SeqNew(0, free); *key = 0; result = SeqBinaryIndexOf(seq, key, CompareNumbers); assert_true(result == -1); SeqDestroy(seq); seq = SeqNew(5, free); SeqAppend(seq, xmalloc(sizeof(size_t))); *(size_t *)SeqAt(seq, 0) = 3; SeqAppend(seq, xmalloc(sizeof(size_t))); *(size_t *)SeqAt(seq, 1) = 3; SeqAppend(seq, xmalloc(sizeof(size_t))); *(size_t *)SeqAt(seq, 2) = 3; SeqAppend(seq, xmalloc(sizeof(size_t))); *(size_t *)SeqAt(seq, 3) = 3; SeqAppend(seq, xmalloc(sizeof(size_t))); *(size_t *)SeqAt(seq, 4) = 3; *key = 3; result = SeqBinaryIndexOf(seq, key, CompareNumbers); // Any number within the range is ok. assert_true(result >= 0 && result < 5); SeqDestroy(seq); free(key); } static void test_sort(void) { Seq *seq = SeqNew(5, NULL); size_t one = 1; size_t two = 2; size_t three = 3; size_t four = 4; size_t five = 5; SeqAppend(seq, &three); SeqAppend(seq, &two); SeqAppend(seq, &five); SeqAppend(seq, &one); SeqAppend(seq, &four); SeqSort(seq, CompareNumbers, NULL); assert_int_equal(seq->data[0], &one); assert_int_equal(seq->data[1], &two); assert_int_equal(seq->data[2], &three); assert_int_equal(seq->data[3], &four); assert_int_equal(seq->data[4], &five); SeqDestroy(seq); } static void test_soft_sort(void) { Seq *seq = SeqNew(5, NULL); size_t one = 1; size_t two = 2; size_t three = 3; size_t four = 4; size_t five = 5; SeqAppend(seq, &three); SeqAppend(seq, &two); SeqAppend(seq, &five); SeqAppend(seq, &one); SeqAppend(seq, &four); Seq *new_seq = SeqSoftSort(seq, CompareNumbers, NULL); assert_int_equal(seq->data[0], &three); assert_int_equal(seq->data[1], &two); assert_int_equal(seq->data[2], &five); assert_int_equal(seq->data[3], &one); assert_int_equal(seq->data[4], &four); assert_int_equal(new_seq->data[0], &one); assert_int_equal(new_seq->data[1], &two); assert_int_equal(new_seq->data[2], &three); assert_int_equal(new_seq->data[3], &four); assert_int_equal(new_seq->data[4], &five); // This is a soft destroy, but normal destroy should also work. SeqDestroy(new_seq); SeqDestroy(seq); } static void test_remove_range(void) { Seq *seq = SequenceCreateRange(10, 0, 9); SeqRemoveRange(seq, 3, 9); assert_int_equal(seq->length, 3); assert_int_equal(*(size_t *) seq->data[0], 0); assert_int_equal(*(size_t *) seq->data[1], 1); assert_int_equal(*(size_t *) seq->data[2], 2); SeqDestroy(seq); seq = SequenceCreateRange(10, 0, 9); SeqRemoveRange(seq, 0, 2); assert_int_equal(seq->length, 7); assert_int_equal(*(size_t *) seq->data[0], 3); SeqDestroy(seq); seq = SequenceCreateRange(10, 0, 9); SeqRemoveRange(seq, 5, 5); assert_int_equal(seq->length, 9); assert_int_equal(*(size_t *) seq->data[5], 6); SeqDestroy(seq); } static void test_remove(void) { Seq *seq = SequenceCreateRange(10, 0, 9); SeqRemove(seq, 5); assert_int_equal(seq->length, 9); assert_int_equal(*(size_t *) seq->data[5], 6); SeqDestroy(seq); seq = SequenceCreateRange(10, 0, 9); SeqRemove(seq, 0); assert_int_equal(seq->length, 9); assert_int_equal(*(size_t *) seq->data[0], 1); SeqDestroy(seq); seq = SequenceCreateRange(10, 0, 9); SeqRemove(seq, 9); assert_int_equal(seq->length, 9); assert_int_equal(*(size_t *) seq->data[8], 8); SeqDestroy(seq); } static void test_reverse(void) { { Seq *seq = SequenceCreateRange(2, 0, 1); assert_int_equal(0, *(size_t *)seq->data[0]); assert_int_equal(1, *(size_t *)seq->data[1]); SeqReverse(seq); assert_int_equal(1, *(size_t *)seq->data[0]); assert_int_equal(0, *(size_t *)seq->data[1]); SeqDestroy(seq); } { Seq *seq = SequenceCreateRange(3, 0, 2); SeqReverse(seq); assert_int_equal(2, *(size_t *)seq->data[0]); assert_int_equal(1, *(size_t *)seq->data[1]); assert_int_equal(0, *(size_t *)seq->data[2]); SeqDestroy(seq); } } static void test_split(void) { { Seq *seq = SeqNew(0, free); SeqAppend(seq, xstrdup("abc")); SeqAppend(seq, xstrdup("def")); assert_int_equal(SeqLength(seq), 2); Seq *end = SeqSplit(seq, 1); assert_int_equal(SeqLength(seq), 1); assert_int_equal(SeqLength(end), 1); assert_string_equal(SeqAt(seq, 0), "abc"); assert_string_equal(SeqAt(end, 0), "def"); SeqDestroy(seq); SeqDestroy(end); } { Seq *seq = SeqNew(0, free); SeqAppend(seq, xstrdup("abc")); SeqAppend(seq, xstrdup("def")); SeqAppend(seq, xstrdup("ghi")); SeqAppend(seq, xstrdup("jkl")); assert_int_equal(SeqLength(seq), 4); Seq *end = SeqSplit(seq, 2); assert_int_equal(SeqLength(seq), 2); assert_int_equal(SeqLength(end), 2); assert_string_equal(SeqAt(seq, 0), "abc"); assert_string_equal(SeqAt(seq, 1), "def"); assert_string_equal(SeqAt(end, 0), "ghi"); assert_string_equal(SeqAt(end, 1), "jkl"); SeqDestroy(seq); SeqDestroy(end); } { Seq *empty_a = SeqNew(0, free); assert_int_equal(SeqLength(empty_a), 0); Seq *empty_b = SeqSplit(empty_a, 0); assert_int_equal(SeqLength(empty_a), 0); assert_int_equal(SeqLength(empty_b), 0); SeqDestroy(empty_a); SeqDestroy(empty_b); } { Seq *seq = SeqNew(0, free); SeqAppend(seq, xstrdup("abc")); assert_int_equal(SeqLength(seq), 1); Seq *empty = SeqSplit(seq, 1); assert_int_equal(SeqLength(seq), 1); assert_int_equal(SeqLength(empty), 0); assert_string_equal(SeqAt(seq, 0), "abc"); SeqDestroy(seq); SeqDestroy(empty); } { Seq *seq = SeqNew(0, free); SeqAppend(seq, xstrdup("abc")); assert_int_equal(SeqLength(seq), 1); Seq *all = SeqSplit(seq, 0); assert_int_equal(SeqLength(seq), 0); assert_int_equal(SeqLength(all), 1); assert_string_equal(SeqAt(all, 0), "abc"); SeqDestroy(seq); SeqDestroy(all); } } static void test_len(void) { Seq *seq = SeqNew(5, NULL); size_t one = 1; size_t two = 2; size_t three = 3; size_t four = 4; size_t five = 5; SeqAppend(seq, &three); SeqAppend(seq, &two); SeqAppend(seq, &five); SeqAppend(seq, &one); SeqAppend(seq, &four); assert_int_equal(SeqLength(seq),5); SeqDestroy(seq); } static void test_get_range(void) { Seq *seq = SeqNew(5, NULL); size_t one = 1; size_t two = 2; size_t three = 3; size_t four = 4; size_t five = 5; SeqAppend(seq, &three); SeqAppend(seq, &two); SeqAppend(seq, &five); SeqAppend(seq, &one); SeqAppend(seq, &four); assert_int_equal(SeqLength(seq),5); { Seq *sub_1 = SeqGetRange(seq, 0, 4); assert_true (sub_1 != NULL); assert_int_equal (sub_1->length, seq->length); assert_int_equal (SeqAt(sub_1, 0), SeqAt(seq, 0)); assert_int_equal (SeqAt(sub_1, 1), SeqAt(seq, 1)); assert_int_equal (SeqAt(sub_1, 2), SeqAt(seq, 2)); assert_int_equal (SeqAt(sub_1, 3), SeqAt(seq, 3)); assert_int_equal (SeqAt(sub_1, 4), SeqAt(seq, 4)); SeqSoftDestroy(sub_1); } { Seq *sub_1 = SeqGetRange(seq, 2, 4); assert_true (sub_1 != NULL); assert_int_equal (sub_1->length, 4 - 2 + 1); assert_int_equal (SeqAt(sub_1, 0), SeqAt(seq, 2)); assert_int_equal (SeqAt(sub_1, 1), SeqAt(seq, 3)); assert_int_equal (SeqAt(sub_1, 2), SeqAt(seq, 4)); SeqSoftDestroy(sub_1); } assert_true (!SeqGetRange(seq, 3, 6)); assert_true (!SeqGetRange(seq, 3, 2)); SeqDestroy(seq); } static void test_get_data(void) { Seq *seq = SeqNew(16, NULL); SeqAppend(seq, "one"); SeqAppend(seq, "two"); SeqAppend(seq, "three"); SeqAppend(seq, NULL); void *const *data = SeqGetData(seq); assert_string_equal(data[0], "one"); assert_string_equal(data[1], "two"); assert_string_equal(data[2], "three"); assert_true(data[3] == NULL); /* Check that accessing the remaining pointers is OK */ for (size_t i = 4; i < 16; i++) { void *item = data[i]; UNUSED(item); } /* no leak here, 'data' is not a copy */ SeqDestroy(seq); } static void test_seq_string_contains(void) { Seq *strings = SeqNew(10, NULL); assert_false(SeqStringContains(strings, "")); assert_false(SeqStringContains(strings, "a")); assert_false(SeqStringContains(strings, " ")); assert_false(SeqStringContains(strings, "nosuch")); SeqAppend(strings, "a"); assert_false(SeqStringContains(strings, "")); assert_true(SeqStringContains(strings, "a")); assert_false(SeqStringContains(strings, " ")); assert_false(SeqStringContains(strings, "nosuch")); SeqAppend(strings, " "); assert_false(SeqStringContains(strings, "")); assert_true(SeqStringContains(strings, "a")); assert_true(SeqStringContains(strings, " ")); assert_false(SeqStringContains(strings, "nosuch")); SeqAppend(strings, ""); assert_true(SeqStringContains(strings, "")); assert_true(SeqStringContains(strings, "a")); assert_true(SeqStringContains(strings, " ")); assert_false(SeqStringContains(strings, "nosuch")); SeqAppend(strings, "abcdefghijklmnopqrstuvwxyz"); assert_true(SeqStringContains(strings, "abcdefghijklmnopqrstuvwxyz")); assert_false(SeqStringContains(strings, "abcdefghijklmnopqrstuvwxyz ")); assert_false(SeqStringContains(strings, "abcdefghijklmnopqrstuvwxy")); assert_false(SeqStringContains(strings, "abcdefghijklmnopqrstuvwxyy")); SeqDestroy(strings); } static void test_seq_string_length(void) { Seq *strings = SeqNew(10, NULL); assert_int_equal(SeqStringLength(strings), 0); SeqAppend(strings, "1"); assert_int_equal(SeqStringLength(strings), 1); SeqAppend(strings, "2345678"); assert_int_equal(SeqStringLength(strings), 8); SeqAppend(strings, ""); SeqAppend(strings, "9"); SeqAppend(strings, ""); assert_int_equal(SeqStringLength(strings), 9); SeqDestroy(strings); } static void test_string_deserialize(void) { { char *two_newlines = xstrdup("1 \n\n1 \n\n"); Seq *seq = SeqStringDeserialize(two_newlines); assert_true(seq != NULL); free(two_newlines); // Copies should be allocated const char *a = SeqAt(seq, 0); const char *b = SeqAt(seq, 1); assert_string_equal(a, "\n"); assert_string_equal(b, "\n"); assert_int_equal(SeqLength(seq), 2); SeqDestroy(seq); } { // Any invalid string should return NULL: assert_true(SeqStringDeserialize(" ") == NULL); assert_true(SeqStringDeserialize("1") == NULL); // Missing newline: assert_true(SeqStringDeserialize("1 A") == NULL); assert_true(SeqStringDeserialize("2 A\n") == NULL); assert_true(SeqStringDeserialize("1 A ") == NULL); // NUL byte wrong (length wrong): assert_true(SeqStringDeserialize("10000 AAAAAAAAAA\n") == NULL); assert_true(SeqStringDeserialize("0 A\n") == NULL); } { // Empty String -> Empty Seq: Seq *seq = SeqStringDeserialize(""); assert(seq != NULL); assert(SeqLength(seq) == 0); SeqDestroy(seq); } } static void test_string_serialize(void) { { Seq *seq = SeqNew(100, free); char *str = SeqStringSerialize(seq); assert(str != NULL && str[0] == '\0'); free(str); SeqDestroy(seq); } const char *three = "3 ABC\n3 DEF\n3 GHI\n"; { Seq *seq = SeqNew(100, free); SeqAppend(seq, xstrdup("ABC")); SeqAppend(seq, xstrdup("DEF")); SeqAppend(seq, xstrdup("GHI")); char *serialized = SeqStringSerialize(seq); assert_string_equal(serialized, three); Seq *seq2 = SeqStringDeserialize(serialized); free(serialized); assert_true(seq2 != NULL); const char *abc = SeqAt(seq2, 0); const char *def = SeqAt(seq2, 1); const char *ghi = SeqAt(seq2, 2); assert_string_equal(abc, "ABC"); assert_string_equal(def, "DEF"); assert_string_equal(ghi, "GHI"); SeqDestroy(seq); SeqDestroy(seq2); } } static void test_seq_string_file(void) { const char *const path = "test_file_string_sequence"; Seq *const sequence = SeqNew(5, free); SeqAppend(sequence, xstrdup("ABC")); SeqAppend(sequence, xstrdup("DEF")); SeqAppend(sequence, xstrdup("123")); const size_t length = SeqLength(sequence); assert_int_equal(length, 3); const bool write_success = SeqStringWriteFile(sequence, path); assert_true(write_success); Seq *const read_sequence = SeqStringReadFile(path); assert_true(read_sequence != NULL); assert_int_equal(length, SeqLength(sequence)); assert_int_equal(length, SeqLength(read_sequence)); for(int i = 0; i < length; ++i) { assert_string_equal(SeqAt(sequence, i), SeqAt(read_sequence, i)); } SeqDestroy(sequence); SeqDestroy(read_sequence); unlink(path); assert_true(SeqStringReadFile(path) == NULL); } static void test_seq_string_empty_file(void) { const char *const path = "test_file_string_sequence"; Seq *const sequence = SeqNew(5, free); const bool write_success = SeqStringWriteFile(sequence, path); assert_true(write_success); struct stat statbuf; stat(path, &statbuf); assert_int_equal(0, statbuf.st_size); Seq *const read_sequence = SeqStringReadFile(path); assert_true(read_sequence != NULL); assert_int_equal(0, SeqLength(sequence)); assert_int_equal(0, SeqLength(read_sequence)); SeqDestroy(sequence); SeqDestroy(read_sequence); unlink(path); assert_true(SeqStringReadFile(path) == NULL); } void test_sscanf(void) { // NOTE: sscanf() on HPUX does not match %z %j %zu %ju etc. // use %ld and %lu (signed and unsigned long) instead const char *three = "3 ABC\n3 DEF\n3 GHI\n"; const char *eleven = "11 ABC\n"; unsigned long length; long long_num; int ret; ret = sscanf(three, "%lu", &length); assert_int_equal(ret, 1); assert_int_equal(length, 3); ret = sscanf(three, "%5lu'", &length); assert_int_equal(ret, 1); assert_int_equal(length, 3); ret = sscanf(three, "%10lu'", &length); assert_int_equal(ret, 1); assert_int_equal(length, 3); ret = sscanf(eleven, "%10lu'", &length); assert_int_equal(ret, 1); assert_int_equal(length, 11); ret = sscanf(eleven, "%10ld", &long_num); assert_int_equal(ret, 1); assert_int_equal(long_num, 11); // Test max field width for %s: const char *const one_to_nine = "123456789"; char a[4]; char b[4]; char c[3]; char d[2]; ret = sscanf(one_to_nine, "%3s%3s%2s%1s", a, b, c, d); assert_int_equal(ret, 4); assert_string_equal(a, "123"); assert_string_equal(b, "456"); assert_string_equal(c, "78"); assert_string_equal(d, "9"); // Test scanning shorter strings than max: const char *const with_spaces = "abc de f"; ret = sscanf(with_spaces, "%3s %3s %2s", a, b, c); assert_int_equal(ret, 3); assert_string_equal(a, "abc"); assert_string_equal(b, "de"); assert_string_equal(c, "f"); const char *const enforce_spaces = "tu wxyz A"; #define FMT_SPACE "%*[ ]" // Matches exactly 1 space and discards it ret = sscanf(enforce_spaces, "%3s"FMT_SPACE"%3s"FMT_SPACE"%2s", a, b, c); #undef FMT_SPACE assert_int_equal(ret, 2); assert_string_equal(a, "tu"); assert_string_equal(b, "wxy"); assert_string_equal(c, "f"); // Untouched // Note that in this example, %s could match commas: const char *const partial_match = "tuv,wxyz,A"; ret = sscanf(partial_match, "%3s,%3s,%2s", a, b, c); assert_int_equal(ret, 2); assert_string_equal(a, "tuv"); assert_string_equal(b, "wxy"); assert_string_equal(c, "f"); // Untouched // Don't allow commas in strings: const char *const strict_commas = "tu,wxyz,A"; ret = sscanf(strict_commas, "%3[^ ,],%3[^ ,],%2[^ ,]", a, b, c); // Stopped because second column was too long strlen("wxyz") > 3 assert_int_equal(ret, 2); assert_string_equal(a, "tu"); assert_string_equal(b, "wxy"); assert_string_equal(c, "f"); // Untouched // Spaces paces allowed in strings const char *const spaces_allowed = "a b, , a, "; ret = sscanf(spaces_allowed, "%3[^,],%3[^,],%2[^,],%1[^,]", a, b, c, d); // Stopped because second column was too long strlen("wxyz") > 3 assert_int_equal(ret, 4); assert_string_equal(a, "a b"); assert_string_equal(b, " "); assert_string_equal(c, " a"); assert_string_equal(d, " "); // Don't use sscanf to parse CSV rows: // 1. %[] cannot match empty string // 2. No way to handle quoting } void test_string_prefix(void) { const char *three = "3 ABC\n3 DEF\n3 GHI\n"; const char *eleven = "11 ABC\n"; assert_int_equal(3, GetLengthPrefix(three)); assert_int_equal(11, GetLengthPrefix(eleven)); assert_int_equal(1234, GetLengthPrefix("1234 H\n")); assert_true(three[STR_LENGTH_PREFIX_LEN] == 'A'); } void dupl_checker(const char *str) { const size_t len = strlen(str); char *res = ValidDuplicate(str, len); assert_true(res != NULL); assert_true(res != str); assert_string_equal(res, str); free(res); for (long l = len + 1; l <= 2*len; ++l) { // String shorter than specified (expected) length: res = ValidDuplicate(str, l); assert_true(res == NULL); } } void test_valid_duplicate(void) { dupl_checker(""); dupl_checker("A"); dupl_checker("AB"); dupl_checker("ABC"); dupl_checker("ABCD"); dupl_checker("ABCDE"); dupl_checker("ABCDEF"); dupl_checker("ABCDEFG"); dupl_checker(" "); dupl_checker(" "); dupl_checker(" "); dupl_checker(" "); dupl_checker(" "); dupl_checker(" "); dupl_checker(" "); dupl_checker(" "); dupl_checker(" "); dupl_checker("\n"); dupl_checker(" \n"); dupl_checker("\n "); dupl_checker("\r\n"); dupl_checker("\n\r"); dupl_checker(" \n "); dupl_checker(" \r\n "); dupl_checker(" \n\r "); dupl_checker("Lorem ipsum dolor sit amet.\nHello, world!\n\n"); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_create_destroy), unit_test(test_append), unit_test(test_set), unit_test(test_append_once), unit_test(test_lookup), unit_test(test_binary_lookup), unit_test(test_index_of), unit_test(test_binary_index_of), unit_test(test_sort), unit_test(test_soft_sort), unit_test(test_remove_range), unit_test(test_remove), unit_test(test_reverse), unit_test(test_split), unit_test(test_len), unit_test(test_get_range), unit_test(test_get_data), unit_test(test_sscanf), unit_test(test_seq_string_contains), unit_test(test_seq_string_length), unit_test(test_string_prefix), unit_test(test_valid_duplicate), unit_test(test_string_deserialize), unit_test(test_string_serialize), unit_test(test_seq_string_file), unit_test(test_seq_string_empty_file), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/env_file_test.c0000644000000000000000000001757115010704254022272 0ustar00rootroot00000000000000#include #include // xsnprintf() #include // Check the output of a single ParseEnvLine call: #define single_line_check(inp, expected_key, expected_value) \ { \ char *buf = malloc(strlen(inp)+1); \ strcpy(buf, inp); \ char *key; \ char *value; \ ParseEnvLine(buf, &key, &value, NULL, 0); \ assert_string_int_equal(key, expected_key); \ assert_string_int_equal(value, expected_value); \ free(buf); \ } static void test_ParseEnvLine(void) { // VALID INPUTS: single_line_check("KEY=VALUE", "KEY", "VALUE"); single_line_check("NAME=\"Test Linux by CFEngine\"", "NAME","Test Linux by CFEngine"); single_line_check("ID=cfengineos", "ID", "cfengineos"); single_line_check("VERSION=1234.5.0", "VERSION", "1234.5.0"); single_line_check("BUILD_ID=2017-02-14-2245", "BUILD_ID", "2017-02-14-2245"); single_line_check("PRETTY_NAME=\"Test Linux by CFEngine 1234.5.0 (Leafant)\"", "PRETTY_NAME","Test Linux by CFEngine 1234.5.0 (Leafant)"); single_line_check("ANSI_COLOR=\"37;4;65\"", "ANSI_COLOR", "37;4;65"); single_line_check("HOME_URL=\"https://cfengine.com/\"", "HOME_URL", "https://cfengine.com/"); single_line_check("BUG_REPORT_URL=\"https://northerntech.atlassian.net/projects/CFE/issues\"", "BUG_REPORT_URL","https://northerntech.atlassian.net/projects/CFE/issues"); // COMMENTS: single_line_check("#COMMENTED_OUT=TRUE", NULL, NULL); single_line_check("#COMMENTED_OUT=\"TRUE\"", NULL, NULL); single_line_check("# COMMENTED_OUT=TRUE", NULL, NULL); single_line_check(" # COMMENTED_OUT=TRUE", NULL, NULL); single_line_check(" # COMMENTED_OUT=TRUE ", NULL, NULL); // Not a comment if line doesn't start with #: single_line_check("COLOR=\"#00FFFF\"","COLOR","#00FFFF"); // QUOTE CLOSING: single_line_check("KEY=\"VALUE\" This is not parsed", "KEY", "VALUE"); single_line_check("KEY='VALUE' This is not parsed", "KEY", "VALUE"); // ESCAPE CHARACTERS: single_line_check("KEY=\\'", "KEY", "'"); single_line_check("KEY=\\\"", "KEY", "\""); single_line_check("KEY=\" \\\" \"", "KEY", " \" "); single_line_check("KEY=\"\\\"\"", "KEY", "\""); // SINGLE QUOTES: single_line_check("KEY='VALUE'", "KEY", "VALUE") single_line_check("KEY='\"'", "KEY", "\"") single_line_check("KEY='\"\"'", "KEY", "\"\"") // SLIGHTLY WEIRD BUT ACCEPTED: single_line_check("KEY=VALUE\n", "KEY", "VALUE"); single_line_check("KEY=VALUE \n", "KEY", "VALUE"); single_line_check("KEY= \"VALUE\" ", "KEY", "VALUE"); single_line_check("KEY=\"\"", "KEY", ""); single_line_check("KEY=\\\\", "KEY", "\\"); single_line_check("KEY=", "KEY", ""); single_line_check("KEY=\"\" <- String terminated", "KEY", ""); // UNCLOSED QUOTES: single_line_check("KEY=\"Oops", "KEY", "Oops"); single_line_check("KEY='Woops", "KEY", "Woops"); // NEWLINES: single_line_check("KEY=\\n", "KEY", "\n"); single_line_check("KEY=\"\\n", "KEY", "\n"); single_line_check("KEY=\"\\n\"", "KEY", "\n"); single_line_check("KEY='\\n'", "KEY", "\n"); single_line_check("KEY='AB\\nCD'", "KEY", "AB\nCD"); // INVALID INPUTS: single_line_check("=VALUE", NULL, NULL); single_line_check(" =\"VALUE\"", NULL, NULL); single_line_check(" =\"VALUE\"", NULL, NULL); single_line_check(" =\"VALUE\"", NULL, NULL); // CORNER CASES: single_line_check("", NULL, NULL); single_line_check(" ", NULL, NULL); single_line_check(" = ", NULL, NULL); single_line_check("= ", NULL, NULL); single_line_check(" =", NULL, NULL); single_line_check("\n", NULL, NULL); single_line_check(" \n", NULL, NULL); } // Tests filtered_copy from src to different dst // Keeps a 'backup' of original contents of src to check // that it's not modified. #define single_filter_check_moved(src, expected) \ { \ char* backup = malloc(strlen(src)+1); \ strcpy(backup, src); \ char* buf = malloc(strlen(src)+1); \ char* start = filtered_copy(src, buf); \ assert_string_int_equal(start, expected); \ assert_string_int_equal(backup, src) \ free(backup); \ free(buf); \ } \ // Tests filtered_copy for src=dst (in place) #define single_filter_check_in_place(src, expected) \ { \ char* buf = malloc(strlen(src)+1); \ strcpy(buf, src); \ char *value = buf; \ value = filtered_copy(value, value); \ assert_string_int_equal(value, expected); \ free(buf); \ } \ #define double_filter_check(src, expected) \ { \ single_filter_check_in_place(src, expected) \ single_filter_check_moved(src, expected) \ } \ #define filter_expect_null(invalid_input) \ { \ char *buf = malloc(1024); \ strcpy(buf, "AB\"CD"); \ char *ret = filtered_copy(buf,buf); \ assert(ret == NULL); \ UNUSED(ret); \ free(buf); \ } \ static void test_filtered_copy(void) { // STRING COPY: double_filter_check("ABC123abc123", "ABC123abc123"); double_filter_check("", ""); double_filter_check(" ", " "); double_filter_check(" ", " "); double_filter_check("\t", "\t"); // ESCAPE CHARACTERS: double_filter_check("\\\\", "\\"); double_filter_check("\\\\\\\\", "\\\\"); double_filter_check("\\\"", "\""); double_filter_check("\\'", "'"); // QUOTES: double_filter_check("\"\"", ""); double_filter_check("''", ""); double_filter_check("\"Hello world!\"", "Hello world!"); double_filter_check("'Hello world!'", "Hello world!"); double_filter_check("'\"'", "\""); double_filter_check("\"'\"", "'"); // QUOTES AND ESCAPE CHARACTERS: double_filter_check("\"\\\"\"", "\"") // "\"" -> " double_filter_check("'\\''", "'") // '\'' -> ' // AUTO CLOSE QUOTES: double_filter_check("\"Hello ", "Hello "); double_filter_check("'Hello ", "Hello "); // CLOSE QUOTES: double_filter_check("\"This\" Not this", "This"); double_filter_check("'This' Not this", "This"); // EXPECTED TO RETURN NULL (INVALID): filter_expect_null("AB\"CD"); filter_expect_null("AB'CD"); filter_expect_null(" ' "); filter_expect_null(" \" "); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_filtered_copy), unit_test(test_ParseEnvLine), }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/libntech/tests/unit/threaded_deque_test.c0000644000000000000000000002666415010704254023451 0ustar00rootroot00000000000000#include #include #include #include /* Memory illustration legend: * * | : memory bounds * * > : left (first non-empty index of data) * * < : right (first empty index after data) * * ^ : left + right (empty) * * v : left + right (at capacity) * * x : used memory * * - : unused memory */ static void test_push_pop(void) { // Initialised with DEFAULT_CAPACITY = 16 ThreadedDeque *deque = ThreadedDequeNew(0, free); // |^---------------| ThreadedDequePushLeft(deque, xstrdup("1")); // |<-------------->| ThreadedDequePushRight(deque, xstrdup("2")); // |x<------------->| ThreadedDequePushLeft(deque, xstrdup("3")); // |x<------------>x| char *str1; ThreadedDequePopRight(deque, (void **)&str1, 0); // |<------------->x| char *str2; ThreadedDequePopLeft(deque, (void **)&str2, 0); // |<-------------->| char *str3; ThreadedDequePopRight(deque, (void **)&str3, 0); // |---------------^| assert_string_equal(str1, "2"); assert_string_equal(str2, "3"); assert_string_equal(str3, "1"); free(str1); free(str2); free(str3); ThreadedDequeDestroy(deque); } static void test_pop_empty_and_push_null(void) { ThreadedDeque *deque = ThreadedDequeNew(1, NULL); // |^| assert(ThreadedDequeIsEmpty(deque)); void *i_am_null = NULL; bool ret = ThreadedDequePopLeft(deque, &i_am_null, 0); // |^| assert(i_am_null == NULL); assert_false(ret); ThreadedDequePushLeft(deque, i_am_null); // |v| ret = ThreadedDequePopLeft(deque, &i_am_null, 0); assert(i_am_null == NULL); assert_true(ret); // |^| ret = ThreadedDequePopRight(deque, &i_am_null, 0); // |^| assert(i_am_null == NULL); assert_false(ret); ThreadedDequePushRight(deque, i_am_null); // |v| ret = ThreadedDequePopRight(deque, &i_am_null, 0); assert(i_am_null == NULL); assert_true(ret); // |^| ThreadedDequeDestroy(deque); } static void test_copy(void) { ThreadedDeque *deque = ThreadedDequeNew(4, free); // deque: |^---| ThreadedDequePushRight(deque, xstrdup("1")); // deque: |><--| ThreadedDequePushRight(deque, xstrdup("2")); // deque: |>x<-| ThreadedDequePushRight(deque, xstrdup("3")); // deque: |>xx<| ThreadedDeque *new_deque = ThreadedDequeCopy(deque); // new_deque: |>xx<| assert(new_deque != NULL); assert_int_equal(ThreadedDequeCount(deque), ThreadedDequeCount(new_deque)); assert_int_equal(ThreadedDequeCapacity(deque), ThreadedDequeCapacity(new_deque)); char *old_str1; ThreadedDequePopLeft(deque, (void **)&old_str1, 0); // deque: |->x<| char *old_str2; ThreadedDequePopLeft(deque, (void **)&old_str2, 0); // deque: |--><| char *old_str3; ThreadedDequePopLeft(deque, (void **)&old_str3, 0); // deque: |---^| char *new_str1; ThreadedDequePopLeft(new_deque, (void **)&new_str1, 0); // new_deque: |->x<| char *new_str2; ThreadedDequePopLeft(new_deque, (void **)&new_str2, 0); // new_deque: |--><| char *new_str3; ThreadedDequePopLeft(new_deque, (void **)&new_str3, 0); // new_deque: |---^| // Check if pointers are equal (since this is a shallow copy) assert(old_str1 == new_str1); assert(old_str2 == new_str2); assert(old_str3 == new_str3); free(old_str1); free(old_str2); free(old_str3); ThreadedDequeSoftDestroy(deque); // Tests expanding the copied deque ThreadedDequePushLeft(new_deque, xstrdup("1")); // new_deque: |--><| ThreadedDequePushRight(new_deque, xstrdup("2")); // new_deque: |<->x| ThreadedDequePushLeft(new_deque, xstrdup("3")); // new_deque: |<>xx| ThreadedDequePushRight(new_deque, xstrdup("4")); // new_deque: |xvxx| ThreadedDequePushLeft(new_deque, xstrdup("5")); // Internal array restructured, array moved to end: // new_deque: |>xxxx<--| assert_int_equal(ThreadedDequeCount(new_deque), 5); assert_int_equal(ThreadedDequeCapacity(new_deque), 8); ThreadedDequePopRight(new_deque, (void **)&new_str1, 0); // new_deque: |>xxx<---| ThreadedDequePopLeft(new_deque, (void **)&new_str2, 0); // new_deque: |->xx<---| ThreadedDequePopRight(new_deque, (void **)&new_str3, 0); // new_deque: |->x<----| char *new_str4; ThreadedDequePopLeft(new_deque, (void **)&new_str4, 0); // new_deque: |--><----| char *new_str5; ThreadedDequePopRight(new_deque, (void **)&new_str5, 0); // new_deque: |--^-----| assert_string_equal(new_str1, "4"); assert_string_equal(new_str2, "5"); assert_string_equal(new_str3, "2"); assert_string_equal(new_str4, "3"); assert_string_equal(new_str5, "1"); free(new_str1); free(new_str2); free(new_str3); free(new_str4); free(new_str5); ThreadedDequeDestroy(new_deque); } static void test_push_report_count(void) { ThreadedDeque *deque = ThreadedDequeNew(0, free); size_t size1 = ThreadedDequePushLeft(deque, xstrdup("1")); size_t size2 = ThreadedDequePushLeft(deque, xstrdup("2")); size_t size3 = ThreadedDequePushLeft(deque, xstrdup("3")); size_t size4 = ThreadedDequePushLeft(deque, xstrdup("4")); assert_int_equal(size1, 1); assert_int_equal(size2, 2); assert_int_equal(size3, 3); assert_int_equal(size4, 4); ThreadedDequeDestroy(deque); } static void test_expand(void) { ThreadedDeque *deque = ThreadedDequeNew(1, free); // |^| ThreadedDequePushRight(deque, xstrdup("spam")); // |v| ThreadedDequePushRight(deque, xstrdup("spam")); // |vx| char *tmp; ThreadedDequePopLeft(deque, (void **)&tmp, 0); // |<>| free(tmp); ThreadedDequePushLeft(deque, xstrdup("spam")); // |vx| ThreadedDequePushLeft(deque, xstrdup("spam")); // Internal array restructured: // |xx<>| ThreadedDequePushLeft(deque, xstrdup("spam")); // |xxvx| ThreadedDequePushLeft(deque, xstrdup("spam")); // Internal array restructured: // |->xxxx<-| ThreadedDequePushRight(deque, xstrdup("spam")); // |->xxxxx<| ThreadedDequePopLeft(deque, (void **)&tmp, 0); // |-->xxxx<| free(tmp); ThreadedDequePopLeft(deque, (void **)&tmp, 0); // |--->xxx<| free(tmp); ThreadedDequePushRight(deque, xstrdup("spam")); // |<-->xxxx| ThreadedDequePushLeft(deque, xstrdup("spam")); // |<->xxxxx| ThreadedDequePushRight(deque, xstrdup("spam")); // |x<>xxxxx| ThreadedDequePushLeft(deque, xstrdup("spam")); // |xxvxxxxx| ThreadedDequePushLeft(deque, xstrdup("spam")); // Internal array restructured // |->xxxxxxxx<-----| ThreadedDequePushRight(deque, xstrdup("spam")); // |->xxxxxxxxx<----| ThreadedDequePushLeft(deque, xstrdup("spam")); // |>xxxxxxxxxx<----| assert_int_equal(ThreadedDequeCount(deque), 11); assert_int_equal(ThreadedDequeCapacity(deque), 16); ThreadedDequeDestroy(deque); } static void test_popn(void) { ThreadedDeque *deque = ThreadedDequeNew(0, free); // Initialised with default size 16 // |^---------------| char *strs[] = {"spam1", "spam2", "spam3", "spam4", "spam5"}; for (int i = 0; i < 5; i++) { ThreadedDequePushLeft(deque, xstrdup(strs[i])); } // |<---------->xxxx| void **data = NULL; size_t count = ThreadedDequePopRightN(deque, &data, 5, 0); // |-----------^----| for (size_t i = 0; i < count; i++) { assert_string_equal(data[i], strs[i]); free(data[i]); } free(data); data = NULL; for (int i = 0; i < 5; i++) { ThreadedDequePushRight(deque, xstrdup(strs[i])); } // |<---------->xxxx| count = ThreadedDequePopLeftN(deque, &data, 5, 0); // |^---------------| for (size_t i = 0; i < count; i++) { assert_string_equal(data[i], strs[i]); free(data[i]); } free(data); ThreadedDequeDestroy(deque); } // Thread tests static ThreadedDeque *thread_deque; static void *thread_pop() { char *tmp; ThreadedDequePopLeft(thread_deque, (void **)&tmp, THREAD_BLOCK_INDEFINITELY); assert_string_equal(tmp, "bla"); free(tmp); return NULL; } static void *thread_push() { char *str = "bla"; ThreadedDequePushLeft(thread_deque, xstrdup(str)); return NULL; } static void *thread_wait_empty() { ThreadedDequeWaitEmpty(thread_deque, THREAD_BLOCK_INDEFINITELY); ThreadedDequePushLeft(thread_deque, xstrdup("a_test")); return NULL; } static void test_threads_wait_pop(void) { #define POP_ITERATIONS 100 thread_deque = ThreadedDequeNew(0, free); pthread_t pops[POP_ITERATIONS] = {0}; for (int i = 0; i < POP_ITERATIONS; i++) { int res_create = pthread_create(&(pops[i]), NULL, thread_pop, NULL); assert_int_equal(res_create, 0); } pthread_t pushs[POP_ITERATIONS] = {0}; for (int i = 0; i < POP_ITERATIONS; i++) { int res_create = pthread_create(&(pushs[i]), NULL, thread_push, NULL); assert_int_equal(res_create, 0); } void *retval = NULL; int res; for (int i = 0; i < POP_ITERATIONS; i++) { res = pthread_join(pops[i], retval); assert_int_equal(res, 0); assert(retval == NULL); res = pthread_join(pushs[i], retval); assert_int_equal(res, 0); assert(retval == NULL); } ThreadedDequeDestroy(thread_deque); } static void test_threads_wait_empty(void) { #define WAIT_ITERATIONS 100 thread_deque = ThreadedDequeNew(0, free); pthread_t pushs[WAIT_ITERATIONS] = {0}; for (int i = 0; i < WAIT_ITERATIONS; i++) { int res_create = pthread_create(&(pushs[i]), NULL, thread_push, NULL); assert_int_equal(res_create, 0); } sleep(1); pthread_t wait_thread = 0; int res_create = pthread_create(&wait_thread, NULL, thread_wait_empty, NULL); assert_int_equal(res_create, 0); do { sleep(1); } while (ThreadedDequeCount(thread_deque) != WAIT_ITERATIONS); char **data_array = NULL; size_t arr_size = ThreadedDequePopLeftN(thread_deque, (void ***)&data_array, WAIT_ITERATIONS, 0); for (size_t i = 0; i < arr_size; i++) { free(data_array[i]); } free(data_array); char *waited_str; ThreadedDequePopLeft(thread_deque, (void **)&waited_str, 1); assert_string_equal(waited_str, "a_test"); free(waited_str); void *retval = NULL; int res; for (int i = 0; i < WAIT_ITERATIONS; i++) { res = pthread_join(pushs[i], retval); assert_int_equal(res, 0); assert(retval == NULL); } res = pthread_join(wait_thread, retval); assert_int_equal(res, 0); assert(retval == NULL); ThreadedDequeDestroy(thread_deque); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_push_pop), unit_test(test_pop_empty_and_push_null), unit_test(test_copy), unit_test(test_push_report_count), unit_test(test_expand), unit_test(test_popn), unit_test(test_threads_wait_pop), unit_test(test_threads_wait_empty), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/json_test.c0000644000000000000000000020340115010704254021441 0ustar00rootroot00000000000000#include #include #include #include #include #include /* xsnprintf */ #include // xasprintf() #include static const char *OBJECT_ARRAY = "{\n" " \"first\": [\n" " \"one\",\n" " \"two\"\n" " ]\n" "}"; static const char *OBJECT_COMPOUND = "{\n" " \"first\": \"one\",\n" " \"fourth\": {\n" " \"fifth\": \"five\"\n" " },\n" " \"second\": {\n" " \"third\": \"three\"\n" " }\n" "}"; static const char *OBJECT_SIMPLE = "{\n" " \"first\": \"one\",\n" " \"second\": \"two\"\n" "}"; static const char *OBJECT_NUMERIC = "{\n" " \"int\": -1234567890,\n" " \"real\": 1234.5678\n" "}"; static const char *OBJECT_BOOLEAN = "{\n" " \"bool_value\": true\n" "}"; static const char *OBJECT_ESCAPED = "{\n" " \"escaped\": \"quote\\\"stuff \\t \\n\\n\"\n" "}"; static const char *ARRAY_SIMPLE = "[\n" " \"one\",\n" " \"two\"\n" "]"; static const char *ARRAY_NUMERIC = "[\n" " 123,\n" " 123.1234\n" "]"; static const char *ARRAY_OBJECT = "[\n" " {\n" " \"first\": \"one\"\n" " }\n" "]"; static JsonElement *LoadTestFile(const char *filename) { char path[PATH_MAX]; xsnprintf(path, sizeof(path), "%s/%s", TESTDATADIR, filename); Writer *w = FileRead(path, SIZE_MAX, NULL); if (!w) { return NULL; } JsonElement *json = NULL; const char *data = StringWriterData(w); if (JsonParse(&data, &json) != JSON_PARSE_OK) { WriterClose(w); return NULL; } WriterClose(w); return json; } static void test_new_delete(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "first", "one"); JsonDestroy(json); } static void test_object_duplicate_key(void) { JsonElement *a = JsonObjectCreate(1); JsonObjectAppendString(a, "a", "a"); JsonObjectAppendString(a, "a", "a"); assert_int_equal(1, JsonLength(a)); JsonDestroy(a); } static void test_show_string(void) { JsonElement *str = JsonStringCreate("snookie"); Writer *writer = StringWriter(); JsonWrite(writer, str, 0); char *output = StringWriterClose(writer); assert_string_equal("\"snookie\"", output); JsonDestroy(str); free(output); } static void test_show_object_simple(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "first", "one"); JsonObjectAppendString(json, "second", "two"); Writer *writer = StringWriter(); JsonWrite(writer, json, 0); char *output = StringWriterClose(writer); assert_string_equal(OBJECT_SIMPLE, output); JsonDestroy(json); free(output); } static void test_show_object_escaped(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "escaped", "quote\"stuff \t \n\n"); Writer *writer = StringWriter(); JsonWrite(writer, json, 0); char *output = StringWriterClose(writer); assert_string_equal(OBJECT_ESCAPED, output); JsonDestroy(json); free(output); } static void test_show_object_numeric(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendReal(json, "real", 1234.5678); JsonObjectAppendInteger(json, "int", -1234567890); Writer *writer = StringWriter(); JsonWrite(writer, json, 0); char *output = StringWriterClose(writer); assert_string_equal(OBJECT_NUMERIC, output); JsonDestroy(json); free(output); } static void test_show_object_boolean(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendBool(json, "bool_value", true); Writer *writer = StringWriter(); JsonWrite(writer, json, 0); char *output = StringWriterClose(writer); assert_string_equal(OBJECT_BOOLEAN, output); JsonDestroy(json); free(output); } static void test_show_object_compound(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "first", "one"); { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "third", "three"); JsonObjectAppendObject(json, "second", inner); } { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "fifth", "five"); JsonObjectAppendObject(json, "fourth", inner); } Writer *writer = StringWriter(); JsonWrite(writer, json, 0); char *output = StringWriterClose(writer); assert_string_equal(OBJECT_COMPOUND, output); JsonDestroy(json); free(output); } static void test_show_object_compound_compact(void) { JsonElement *json = JsonObjectCreate(10); JsonObjectAppendString(json, "first", "one"); { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "third", "three"); JsonObjectAppendObject(json, "second", inner); } { JsonElement *inner = JsonObjectCreate(10); JsonObjectAppendString(inner, "fifth", "five"); JsonObjectAppendObject(json, "fourth", inner); } Writer *writer = StringWriter(); JsonWriteCompact(writer, json); char *output = StringWriterClose(writer); assert_string_equal( "{\"first\":\"one\",\"fourth\":{\"fifth\":\"five\"},\"second\":{\"third\":\"three\"}}", output); JsonDestroy(json); free(output); } static void test_show_object_array(void) { JsonElement *json = JsonObjectCreate(10); JsonElement *array = JsonArrayCreate(10); JsonArrayAppendString(array, "one"); JsonArrayAppendString(array, "two"); JsonObjectAppendArray(json, "first", array); Writer *writer = StringWriter(); JsonWrite(writer, json, 0); char *output = StringWriterClose(writer); assert_string_equal(OBJECT_ARRAY, output); JsonDestroy(json); free(output); } static void test_show_array(void) { JsonElement *array = JsonArrayCreate(10); JsonArrayAppendString(array, "one"); JsonArrayAppendString(array, "two"); Writer *writer = StringWriter(); JsonWrite(writer, array, 0); char *output = StringWriterClose(writer); assert_string_equal(ARRAY_SIMPLE, output); JsonDestroy(array); free(output); } static void test_show_array_compact(void) { JsonElement *array = JsonArrayCreate(10); JsonArrayAppendString(array, "one"); JsonArrayAppendString(array, "two"); Writer *writer = StringWriter(); JsonWriteCompact(writer, array); char *output = StringWriterClose(writer); assert_string_equal("[\"one\",\"two\"]", output); JsonDestroy(array); free(output); } static void test_show_array_boolean(void) { JsonElement *array = JsonArrayCreate(10); JsonArrayAppendBool(array, true); JsonArrayAppendBool(array, false); Writer *writer = StringWriter(); JsonWrite(writer, array, 0); char *output = StringWriterClose(writer); assert_string_equal( "[\n" " true,\n" " false\n" "]", output); JsonDestroy(array); free(output); } static void test_show_array_numeric(void) { JsonElement *array = JsonArrayCreate(10); JsonArrayAppendInteger(array, 123); JsonArrayAppendReal(array, 123.1234); Writer *writer = StringWriter(); JsonWrite(writer, array, 0); char *output = StringWriterClose(writer); assert_string_equal(ARRAY_NUMERIC, output); JsonDestroy(array); free(output); } static void test_show_array_object(void) { JsonElement *array = JsonArrayCreate(10); JsonElement *object = JsonObjectCreate(10); JsonObjectAppendString(object, "first", "one"); JsonArrayAppendObject(array, object); Writer *writer = StringWriter(); JsonWrite(writer, array, 0); char *output = StringWriterClose(writer); assert_string_equal(ARRAY_OBJECT, output); JsonDestroy(array); free(output); } static void test_show_array_empty(void) { JsonElement *array = JsonArrayCreate(10); Writer *writer = StringWriter(); JsonWrite(writer, array, 0); char *output = StringWriterClose(writer); assert_string_equal("[]", output); JsonDestroy(array); free(output); } static void test_show_array_nan(void) { JsonElement *array = JsonArrayCreate(10); JsonArrayAppendReal(array, sqrt(-1)); Writer *writer = StringWriter(); JsonWrite(writer, array, 0); char *output = StringWriterClose(writer); assert_string_equal("[\n 0.0000\n]", output); JsonDestroy(array); free(output); } #ifndef INFINITY #define INFINITY (1.0 / 0.0) #endif static void test_show_array_infinity(void) { JsonElement *array = JsonArrayCreate(10); JsonArrayAppendReal(array, INFINITY); Writer *writer = StringWriter(); JsonWrite(writer, array, 0); char *output = StringWriterClose(writer); assert_string_equal("[\n 0.0000\n]", output); JsonDestroy(array); free(output); } static void test_object_get_string(void) { JsonElement *obj = JsonObjectCreate(10); JsonObjectAppendString(obj, "first", "one"); JsonObjectAppendString(obj, "second", "two"); assert_string_equal(JsonObjectGetAsString(obj, "second"), "two"); assert_string_equal(JsonObjectGetAsString(obj, "first"), "one"); JsonDestroy(obj); } static void test_object_get_bool(void) { JsonElement *obj = JsonObjectCreate(10); JsonObjectAppendBool(obj, "true", true); JsonObjectAppendBool(obj, "false", false); assert_int_equal(JsonObjectGetAsBool(obj, "true"), true); assert_int_equal(JsonObjectGetAsBool(obj, "false"), false); JsonDestroy(obj); } static void test_object_get_array(void) { JsonElement *arr = JsonArrayCreate(10); JsonArrayAppendString(arr, "one"); JsonArrayAppendString(arr, "two"); JsonElement *obj = JsonObjectCreate(10); JsonObjectAppendArray(obj, "array", arr); JsonElement *arr2 = JsonObjectGetAsArray(obj, "array"); assert_string_equal(JsonArrayGetAsString(arr2, 1), "two"); JsonDestroy(obj); } static void test_object_iterator(void) { JsonElement *obj = JsonObjectCreate(10); JsonObjectAppendString(obj, "first", "one"); JsonObjectAppendString(obj, "second", "two"); JsonObjectAppendInteger(obj, "third", 3); JsonObjectAppendBool(obj, "fourth", true); JsonObjectAppendBool(obj, "fifth", false); { JsonIterator it = JsonIteratorInit(obj); assert_true(JsonIteratorHasMore(&it)); assert_string_equal("first", JsonIteratorNextKey(&it)); assert_string_equal("second", JsonIteratorNextKey(&it)); assert_string_equal("third", JsonIteratorNextKey(&it)); assert_string_equal("fourth", JsonIteratorNextKey(&it)); assert_true(JsonIteratorHasMore(&it)); assert_string_equal("fifth", JsonIteratorNextKey(&it)); assert_false(JsonIteratorHasMore(&it)); assert_false(JsonIteratorNextKey(&it)); } { JsonIterator it = JsonIteratorInit(obj); assert_true(JsonIteratorHasMore(&it)); assert_string_equal( "one", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_string_equal( "two", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_int_equal( 3, JsonPrimitiveGetAsInteger(JsonIteratorNextValue(&it))); assert_true(JsonPrimitiveGetAsBool(JsonIteratorNextValue(&it))); assert_true(JsonIteratorHasMore(&it)); assert_false(JsonPrimitiveGetAsBool(JsonIteratorNextValue(&it))); assert_false(JsonIteratorHasMore(&it)); assert_false(JsonIteratorNextValue(&it)); } JsonDestroy(obj); } static void test_array_get_string(void) { JsonElement *arr = JsonArrayCreate(10); JsonArrayAppendString(arr, "first"); JsonArrayAppendString(arr, "second"); assert_string_equal(JsonArrayGetAsString(arr, 1), "second"); assert_string_equal(JsonArrayGetAsString(arr, 0), "first"); JsonDestroy(arr); } static void test_array_iterator(void) { JsonElement *arr = JsonArrayCreate(10); JsonArrayAppendString(arr, "first"); JsonArrayAppendString(arr, "second"); { JsonIterator it = JsonIteratorInit(arr); assert_true(JsonIteratorHasMore(&it)); assert_string_equal( "first", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_true(JsonIteratorHasMore(&it)); assert_string_equal( "second", JsonPrimitiveGetAsString(JsonIteratorNextValue(&it))); assert_false(JsonIteratorHasMore(&it)); assert_false(JsonIteratorNextValue(&it)); } JsonDestroy(arr); } static void test_copy_compare(void) { JsonElement *bench = LoadTestFile("benchmark.json"); assert_true(bench != NULL); JsonElement *copy = JsonCopy(bench); assert_true(copy != NULL); assert_int_equal(0, JsonCompare(copy, bench)); JsonDestroy(bench); JsonDestroy(copy); } static void test_compare_container_type_mismatch(void) { JsonElement *object_a = JsonObjectCreate(1); JsonElement *object_b = JsonObjectCreate(1); JsonElement *child = JsonObjectCreate(1); JsonObjectAppendObject(object_a, "key", child); JsonElement *array = JsonArrayCreate(1); JsonArrayAppendString(array, "first"); JsonArrayAppendString(array, "second"); JsonObjectAppendArray(object_b, "key", array); assert_true(JsonCompare(object_a, object_b) != 0); JsonDestroy(object_a); JsonDestroy(object_b); } static void test_select(void) { const char *data = OBJECT_ARRAY; JsonElement *obj = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &obj)); assert_true(obj == JsonSelect(obj, 0, NULL)); { char *indices[] = {"first"}; assert_int_equal( JSON_CONTAINER_TYPE_ARRAY, JsonGetContainerType(JsonSelect(obj, 1, indices))); } { char *indices[] = {"first", "0"}; assert_string_equal( "one", JsonPrimitiveGetAsString(JsonSelect(obj, 2, indices))); } { char *indices[] = {"first", "1"}; assert_string_equal( "two", JsonPrimitiveGetAsString(JsonSelect(obj, 2, indices))); } { char *indices[] = {"first", "2"}; assert_true(JsonSelect(obj, 2, indices) == NULL); } { char *indices[] = {"first", "x"}; assert_true(JsonSelect(obj, 2, indices) == NULL); } { char *indices[] = {"first", "0", "x"}; assert_true(JsonSelect(obj, 3, indices) == NULL); } { char *indices[] = {"second"}; assert_true(JsonSelect(obj, 1, indices) == NULL); } JsonDestroy(obj); } static void test_merge_array(void) { JsonElement *a = JsonArrayCreate(2); JsonArrayAppendString(a, "a"); JsonArrayAppendString(a, "b"); JsonElement *b = JsonArrayCreate(2); JsonArrayAppendString(b, "c"); JsonArrayAppendString(b, "d"); JsonElement *c = JsonMerge(a, b); assert_int_equal(2, JsonLength(a)); assert_int_equal(2, JsonLength(b)); assert_int_equal(4, JsonLength(c)); assert_string_equal("a", JsonArrayGetAsString(c, 0)); assert_string_equal("b", JsonArrayGetAsString(c, 1)); assert_string_equal("c", JsonArrayGetAsString(c, 2)); assert_string_equal("d", JsonArrayGetAsString(c, 3)); JsonDestroy(a); JsonDestroy(b); JsonDestroy(c); } static void test_merge_object(void) { JsonElement *a = JsonObjectCreate(2); JsonObjectAppendString(a, "a", "a"); JsonObjectAppendString(a, "b", "b"); JsonElement *b = JsonObjectCreate(2); JsonObjectAppendString(b, "b", "b"); JsonObjectAppendString(b, "c", "c"); JsonElement *c = JsonMerge(a, b); assert_int_equal(2, JsonLength(a)); assert_int_equal(2, JsonLength(b)); assert_int_equal(3, JsonLength(c)); assert_string_equal("a", JsonObjectGetAsString(c, "a")); assert_string_equal("b", JsonObjectGetAsString(c, "b")); assert_string_equal("c", JsonObjectGetAsString(c, "c")); JsonDestroy(a); JsonDestroy(b); JsonDestroy(c); } static void test_parse_empty_containers(void) { { const char *data = "{}"; JsonElement *obj = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &obj)); assert_true(obj != NULL); assert_int_equal(JSON_TYPE_OBJECT, JsonGetType(obj)); assert_int_equal(0, JsonLength(obj)); JsonDestroy(obj); } { const char *data = "[]"; JsonElement *arr = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &arr)); assert_true(arr != NULL); assert_int_equal(JSON_ELEMENT_TYPE_CONTAINER, JsonGetElementType(arr)); assert_int_equal(JSON_CONTAINER_TYPE_ARRAY, JsonGetContainerType(arr)); assert_int_equal(JSON_TYPE_ARRAY, JsonGetType(arr)); assert_int_equal(JsonGetContainerType(arr), JsonGetType(arr)); assert_int_equal(0, JsonLength(arr)); JsonDestroy(arr); } } static void test_parse_object_simple(void) { const char *data = OBJECT_SIMPLE; JsonElement *obj = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &obj)); assert_string_equal(JsonObjectGetAsString(obj, "second"), "two"); assert_string_equal(JsonObjectGetAsString(obj, "first"), "one"); assert_int_equal(JsonObjectGetAsString(obj, "third"), NULL); JsonDestroy(obj); } static void test_parse_object_escaped(void) { const char *decoded = "\"/var/cfenigne/bin/cf-know\" "; const char *json_string = "{\n \"key\": \"\\\"/var/cfenigne/bin/cf-know\\\" \"\n}"; JsonElement *obj = NULL; const char *data = json_string; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &obj)); assert_int_not_equal(obj, NULL); assert_string_equal(JsonObjectGetAsString(obj, "key"), decoded); { Writer *w = StringWriter(); JsonWrite(w, obj, 0); assert_string_equal(json_string, StringWriterData(w)); WriterClose(w); } JsonDestroy(obj); } static void test_parse_tzz_evil_key(void) { const char *data = "{ \"third key! can? be$ anything&\": [ \"a\", \"b\", \"c\" ]}"; JsonElement *obj = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &obj)); assert_string_equal( "b", JsonArrayGetAsString( JsonObjectGetAsArray(obj, "third key! can? be$ anything&"), 1)); JsonDestroy(obj); } static void test_parse_primitives(void) { JsonElement *pri = NULL; const char *data = "\"foo\""; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &pri)); assert_string_equal("foo", JsonPrimitiveGetAsString(pri)); JsonDestroy(pri); data = "-123"; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &pri)); assert_true(-123 == JsonPrimitiveGetAsInteger(pri)); JsonDestroy(pri); data = "1.23"; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &pri)); assert_double_close(1.23, JsonPrimitiveGetAsReal(pri)); JsonDestroy(pri); data = "true"; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &pri)); assert_true(JsonPrimitiveGetAsBool(pri)); JsonDestroy(pri); } static void test_parse_array_simple(void) { const char *data = ARRAY_SIMPLE; JsonElement *arr = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &arr)); assert_string_equal(JsonArrayGetAsString(arr, 1), "two"); assert_string_equal(JsonArrayGetAsString(arr, 0), "one"); JsonDestroy(arr); } static void test_parse_object_compound(void) { const char *data = OBJECT_COMPOUND; JsonElement *obj = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &obj)); assert_string_equal(JsonObjectGetAsString(obj, "first"), "one"); JsonElement *second = JsonObjectGetAsObject(obj, "second"); assert_string_equal(JsonObjectGetAsString(second, "third"), "three"); JsonElement *fourth = JsonObjectGetAsObject(obj, "fourth"); assert_string_equal(JsonObjectGetAsString(fourth, "fifth"), "five"); JsonDestroy(obj); } static void test_parse_object_diverse(void) { { const char *data = "{ \"a\": 1, \"b\": \"snookie\", \"c\": 1.0, \"d\": {}, \"e\": [], \"f\": true, \"g\": false, \"h\": null }"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "{\"a\":1,\"b\":\"snookie\",\"c\":1.0,\"d\":{},\"e\":[],\"f\":true,\"g\":false,\"h\":null}"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } } static void test_parse_array_object(void) { const char *data = ARRAY_OBJECT; JsonElement *arr = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &arr)); JsonElement *first = JsonArrayGetAsObject(arr, 0); assert_string_equal(JsonObjectGetAsString(first, "first"), "one"); JsonDestroy(arr); } static void test_iterator_current(void) { const char *data = ARRAY_SIMPLE; JsonElement *arr = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &arr)); JsonElement *json = JsonObjectCreate(1); JsonObjectAppendArray(json, "array", arr); JsonIterator it = JsonIteratorInit(json); while (JsonIteratorNextValue(&it) != NULL) { assert_int_equal( (int) JsonIteratorCurrentElementType(&it), (int) JSON_ELEMENT_TYPE_CONTAINER); assert_int_equal( (int) JsonIteratorCurrentContainerType(&it), (int) JSON_CONTAINER_TYPE_ARRAY); assert_string_equal(JsonIteratorCurrentKey(&it), "array"); } JsonDestroy(json); } static bool VisitPrimitive(JsonElement *primitive, void *data) { assert_int_equal(JsonGetElementType(primitive), JSON_ELEMENT_TYPE_PRIMITIVE); Writer *writer = data; WriterWrite(writer, JsonPrimitiveGetAsString(primitive)); WriterWriteChar(writer, ','); return true; } static bool VisitArray(JsonElement *array, void *data) { assert_int_equal(JsonGetElementType(array), JSON_ELEMENT_TYPE_CONTAINER); assert_int_equal(JsonGetContainerType(array), JSON_CONTAINER_TYPE_ARRAY); Writer *writer = data; WriterWriteF(writer, "[%zd]", JsonLength(array)); return true; } static bool VisitObject(JsonElement *object, void *data) { assert_int_equal(JsonGetElementType(object), JSON_ELEMENT_TYPE_CONTAINER); assert_int_equal(JsonGetContainerType(object), JSON_CONTAINER_TYPE_OBJECT); Writer *writer = data; WriterWriteChar(writer, '{'); JsonIterator iter = JsonIteratorInit(object); while (JsonIteratorHasMore(&iter)) { WriterWrite(writer, JsonIteratorNextKey(&iter)); WriterWriteChar(writer, ','); } WriterWriteChar(writer, '}'); return true; } static bool VisitArrayAbortOnEmpty(JsonElement *array, void *data) { assert_int_equal(JsonGetElementType(array), JSON_ELEMENT_TYPE_CONTAINER); assert_int_equal(JsonGetContainerType(array), JSON_CONTAINER_TYPE_ARRAY); Writer *writer = data; WriterWriteF(writer, "[%zd]", JsonLength(array)); return (JsonLength(array) != 0); } static void test_json_walk(void) { JsonElement *data = LoadTestFile("sample.json"); assert_true(data != NULL); Writer *trace_writer = StringWriter(); bool ret = JsonWalk(data, VisitObject, VisitArray, VisitPrimitive, (void *) trace_writer); assert_true(ret); const char *expected_trace = "{primitive1,array0,array1,obj0,obj1,}value1,[0][2]value2,value3," "{}{primitive2,array2,obj2,}value4,[1]value5,{array3,primitive3,}[0]value6,"; assert_string_equal(StringWriterData(trace_writer), expected_trace); WriterClose(trace_writer); trace_writer = StringWriter(); ret = JsonWalk(data, VisitObject, VisitArrayAbortOnEmpty, VisitPrimitive, (void *) trace_writer); assert_false(ret); expected_trace = "{primitive1,array0,array1,obj0,obj1,}value1,[0]"; assert_string_equal(StringWriterData(trace_writer), expected_trace); WriterClose(trace_writer); JsonDestroy(data); } static void test_parse_empty_string(void) { const char *data = ""; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); data = "\"\""; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_string_equal("", JsonPrimitiveGetAsString(json)); JsonDestroy(json); } static char *JsonToString(const JsonElement *json) { Writer *w = StringWriter(); JsonWriteCompact(w, json); return StringWriterClose(w); } static void test_parse_escaped_string(void) { { const char *data = "\"\\\\\""; const char *original = data; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_string_equal("\\", JsonPrimitiveGetAsString(json)); char *out = JsonToString(json); assert_string_equal(original, out); free(out); JsonDestroy(json); } { // included by paranoia from Redmine #5773 const char *data = "\"/\\\\//\\\\/\\\\\""; const char *original = data; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_string_equal("/\\//\\/\\", JsonPrimitiveGetAsString(json)); char *out = JsonToString(json); assert_string_equal(original, out); free(out); JsonDestroy(json); } { const char *data = "\"x\\tx\""; const char *original = data; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_string_equal("x\tx", JsonPrimitiveGetAsString(json)); char *out = JsonToString(json); assert_string_equal(original, out); free(out); JsonDestroy(json); } } static void test_parse_big_numbers(void) { #define JSON_TEST_BIG_NUMBER "9999999999" #define JSON_TEST_BIG_NUMBER_INT64 9999999999LL // JsonPrimitiveGetAsInt64(): { const char *data = "[" JSON_TEST_BIG_NUMBER "]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json != NULL); const JsonElement *const primitive = JsonArrayGet(json, 0); int64_t number; const int error_code = JsonPrimitiveGetAsInt64(primitive, &number); assert_int_equal(error_code, 0); char *result; xasprintf(&result, "%jd", (intmax_t) number); assert_string_equal(result, JSON_TEST_BIG_NUMBER); free(result); JsonDestroy(json); } { const char *data = "[-" JSON_TEST_BIG_NUMBER "]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json != NULL); const JsonElement *const primitive = JsonArrayGet(json, 0); int64_t number; const int error_code = JsonPrimitiveGetAsInt64(primitive, &number); assert_int_equal(error_code, 0); char *result; xasprintf(&result, "%jd", (intmax_t) number); assert_string_equal(result, "-" JSON_TEST_BIG_NUMBER); free(result); JsonDestroy(json); } // JsonPrimitiveGetAsInt64DefaultOnError(): { const char *data = "[" JSON_TEST_BIG_NUMBER "]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json != NULL); const JsonElement *const primitive = JsonArrayGet(json, 0); const int64_t number = JsonPrimitiveGetAsInt64DefaultOnError(primitive, -1); char *result; xasprintf(&result, "%jd", (intmax_t) number); assert_string_equal(result, JSON_TEST_BIG_NUMBER); free(result); JsonDestroy(json); } { const char *data = "[-" JSON_TEST_BIG_NUMBER "]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json != NULL); const JsonElement *const primitive = JsonArrayGet(json, 0); const int64_t number = JsonPrimitiveGetAsInt64DefaultOnError(primitive, -1); char *result; xasprintf(&result, "%jd", (intmax_t) number); assert_string_equal(result, "-" JSON_TEST_BIG_NUMBER); free(result); JsonDestroy(json); } // JsonPrimitiveGetAsInt64ExitOnError(): { const char *data = "[" JSON_TEST_BIG_NUMBER "]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json != NULL); const JsonElement *const primitive = JsonArrayGet(json, 0); const int64_t number = JsonPrimitiveGetAsInt64ExitOnError(primitive); char *result; xasprintf(&result, "%jd", (intmax_t) number); assert_string_equal(result, JSON_TEST_BIG_NUMBER); free(result); JsonDestroy(json); } { const char *data = "[-" JSON_TEST_BIG_NUMBER "]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json != NULL); const JsonElement *const primitive = JsonArrayGet(json, 0); const int64_t number = JsonPrimitiveGetAsInt64ExitOnError(primitive); char *result; xasprintf(&result, "%jd", (intmax_t) number); assert_string_equal(result, "-" JSON_TEST_BIG_NUMBER); free(result); JsonDestroy(json); } // JsonIntegerCreate64 { JsonElement *object = JsonObjectCreate(1); JsonElement *size = JsonIntegerCreate64(JSON_TEST_BIG_NUMBER_INT64); JsonObjectAppendElement(object, "64bitvalue", size); assert_int_equal(1, JsonLength(object)); JsonElement *const primitive = JsonObjectGet(object, "64bitvalue"); assert_string_equal( JSON_TEST_BIG_NUMBER, JsonPrimitiveGetAsString(primitive)); JsonDestroy(object); } // JsonObjectAppendInteger64 { JsonElement *object = JsonObjectCreate(1); JsonObjectAppendInteger64(object, "64bitvalue", JSON_TEST_BIG_NUMBER_INT64); assert_int_equal(1, JsonLength(object)); const JsonElement *const primitive = JsonObjectGet(object, "64bitvalue"); int64_t number; const int error_code = JsonPrimitiveGetAsInt64(primitive, &number); assert_int_equal(error_code, 0); char *result; xasprintf(&result, "%" PRIi64, number); assert_string_equal(result, JSON_TEST_BIG_NUMBER); free(result); JsonDestroy(object); } #undef JSON_TEST_BIG_NUMBER #undef JSON_TEST_BIG_NUMBER_INT64 } static void test_parse_good_numbers(void) { { const char *data = "[0.1]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[0.1234567890123456789]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[0.1234e10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[0.1234e+10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[0.1234e-10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[1203e10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[1203e+10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[123e-10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[0e-10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[0.0e-10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[-0.0e-10]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } } static void test_parse_bad_numbers(void) { { const char *data = "[01]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } { const char *data = "[01.1]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } { const char *data = "[1.]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } { const char *data = "[e10]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } { const char *data = "[-e10]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } { const char *data = "[+2]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } { const char *data = "[1e]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } { const char *data = "[e10]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); } } static void test_parse_trim(void) { const char *data = " [] "; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } static void test_parse_array_extra_closing(void) { const char *data = " []]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } static void test_parse_all(void) { const char *data = "\"\"a"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "\"\""; // Good json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParseAll(&data, &json)); assert_true(json != NULL); JsonDestroy(json); data = "{}b"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "{}"; // Good json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParseAll(&data, &json)); assert_true(json != NULL); JsonDestroy(json); data = "[]c"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "{}}"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "{\"d\": \"e\"}}"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "[]]"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "[[]]]"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "[[[]]]]"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = " []]"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "\"some\": [ \"json\" ] }"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "{ \"some\": [ \"json\" ] } ["; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "[\"some\", \"json\"]!"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = " [\"some\", \"json\"]a"; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); data = "[\"some\", \"json\"] {\"foo\": \"var\"} "; json = NULL; assert_int_equal(JSON_PARSE_ERROR_INVALID_END, JsonParseAll(&data, &json)); assert_true(json == NULL); } static void test_parse_array_diverse(void) { { const char *data = "[1, \"snookie\", 1.0, {}, [], true, false, null ]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } { const char *data = "[1,\"snookie\",1.0,{},[],true,false,null]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_true(json); JsonDestroy(json); } } static void test_parse_bad_apple2(void) { const char *data = "]["; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } static void test_parse_object_garbage(void) { { const char *data = "{ \"first\": 1, garbage \"second\": 2 }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{ \"first\": 1 garbage \"second\": 2 }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{ \"first\": garbage, \"second\": 2 }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{ \"first\": garbage \"second\": 2 }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } } static void test_parse_object_nested_garbage(void) { { const char *data = "{ \"first\": { garbage } }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{ \"first\": [ garbage ] }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } } static void test_parse_array_garbage(void) { { const char *data = "[1, garbage]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[1 garbage]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[garbage]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[garbage, 1]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } } static void test_parse_array_nested_garbage(void) { { const char *data = "[1, [garbage]]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[1, { garbage }]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } } static void test_array_extend(void) { { JsonElement *a = JsonArrayCreate(6); JsonArrayAppendString(a, "one"); JsonArrayAppendString(a, "two"); JsonArrayAppendString(a, "three"); JsonElement *b = JsonArrayCreate(3); JsonArrayAppendString(b, "four"); JsonArrayAppendString(b, "five"); JsonArrayAppendString(b, "six"); JsonArrayExtend(a, b); assert_int_equal(JsonLength(a), 6); assert_string_equal(JsonArrayGetAsString(a, 0), "one"); assert_string_equal(JsonArrayGetAsString(a, 1), "two"); assert_string_equal(JsonArrayGetAsString(a, 2), "three"); assert_string_equal(JsonArrayGetAsString(a, 3), "four"); assert_string_equal(JsonArrayGetAsString(a, 4), "five"); assert_string_equal(JsonArrayGetAsString(a, 5), "six"); JsonDestroy(a); } { JsonElement *a = JsonArrayCreate(3); JsonArrayAppendString(a, "one"); JsonArrayAppendString(a, "two"); JsonArrayAppendString(a, "three"); JsonElement *b = JsonArrayCreate(0); JsonArrayExtend(a, b); assert_int_equal(JsonLength(a), 3); assert_string_equal(JsonArrayGetAsString(a, 0), "one"); assert_string_equal(JsonArrayGetAsString(a, 1), "two"); assert_string_equal(JsonArrayGetAsString(a, 2), "three"); JsonDestroy(a); } { JsonElement *a = JsonArrayCreate(3); JsonElement *b = JsonArrayCreate(3); JsonArrayAppendString(b, "four"); JsonArrayAppendString(b, "five"); JsonArrayAppendString(b, "six"); JsonArrayExtend(a, b); assert_int_equal(JsonLength(a), 3); assert_string_equal(JsonArrayGetAsString(a, 0), "four"); assert_string_equal(JsonArrayGetAsString(a, 1), "five"); assert_string_equal(JsonArrayGetAsString(a, 2), "six"); JsonDestroy(a); } } static void test_array_remove_range(void) { { // remove whole JsonElement *arr = JsonArrayCreate(5); JsonArrayAppendString(arr, "one"); JsonArrayAppendString(arr, "two"); JsonArrayAppendString(arr, "three"); JsonArrayRemoveRange(arr, 0, 2); assert_int_equal(JsonLength(arr), 0); JsonDestroy(arr); } { // remove middle JsonElement *arr = JsonArrayCreate(5); JsonArrayAppendString(arr, "one"); JsonArrayAppendString(arr, "two"); JsonArrayAppendString(arr, "three"); JsonArrayRemoveRange(arr, 1, 1); assert_int_equal(JsonLength(arr), 2); assert_string_equal(JsonArrayGetAsString(arr, 0), "one"); assert_string_equal(JsonArrayGetAsString(arr, 1), "three"); JsonDestroy(arr); } { // remove rest JsonElement *arr = JsonArrayCreate(5); JsonArrayAppendString(arr, "one"); JsonArrayAppendString(arr, "two"); JsonArrayAppendString(arr, "three"); JsonArrayRemoveRange(arr, 1, 2); assert_int_equal(JsonLength(arr), 1); assert_string_equal(JsonArrayGetAsString(arr, 0), "one"); JsonDestroy(arr); } { // remove but last JsonElement *arr = JsonArrayCreate(5); JsonArrayAppendString(arr, "one"); JsonArrayAppendString(arr, "two"); JsonArrayAppendString(arr, "three"); JsonArrayRemoveRange(arr, 0, 1); assert_int_equal(JsonLength(arr), 1); assert_string_equal(JsonArrayGetAsString(arr, 0), "three"); JsonDestroy(arr); } } static void test_remove_key_from_object(void) { JsonElement *object = JsonObjectCreate(3); JsonObjectAppendInteger(object, "one", 1); JsonObjectAppendInteger(object, "two", 2); JsonObjectAppendInteger(object, "three", 3); JsonObjectRemoveKey(object, "two"); assert_int_equal(2, JsonLength(object)); JsonDestroy(object); } static void test_detach_key_from_object(void) { JsonElement *object = JsonObjectCreate(3); JsonObjectAppendInteger(object, "one", 1); JsonObjectAppendInteger(object, "two", 2); JsonObjectAppendInteger(object, "three", 3); JsonElement *detached = JsonObjectDetachKey(object, "two"); assert_int_equal(2, JsonLength(object)); JsonDestroy(object); assert_int_equal(1, JsonLength(detached)); JsonDestroy(detached); } static void test_parse_array_double_and_trailing_commas(void) { { const char *data = "[ \"foo\",, \"bar\" ]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[\"foo\", , \"bar\" ]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[ \"foo\", \"bar\",, ]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[ \"foo\", \"bar\", , ]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { // We accept one, and only one, trailing comma. const char *data = "[ \"foo\", \"bar\", ]"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); JsonDestroy(json); } } static void test_parse_array_comma_after_brace(void) { { const char *data = "[ , \"foo\", \"bar\" ]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[,\"foo\",\"bar\"]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } } static void test_parse_array_bad_nested_elems(void) { { const char *data = "[ \"foo\" [\"baz\"], \"bar\" ]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[\"foo\"[\"baz\"],\"bar\"]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[ \"foo\" {\"boing\": \"baz\"}, \"bar\" ]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "[\"foo\"{\"boing\":\"baz\"},\"bar\"]"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } } static void test_parse_object_double_colon(void) { { const char *data = "{ \"foo\":: \"bar\" }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{\"foo\"::\"bar\"}"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } } static void test_parse_object_double_and_trailing_comma(void) { { const char *data = "{ ,, }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{,,}"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{\"foo\":\"bar\",,}"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { const char *data = "{\"foo\": \"bar\", , }"; JsonElement *json = NULL; assert_int_not_equal(JSON_PARSE_OK, JsonParse(&data, &json)); assert_false(json); } { // We accept one, and only one, trailing comma. const char *data = "{\"foo\": \"bar\", }"; JsonElement *json = NULL; assert_int_equal(JSON_PARSE_OK, JsonParse(&data, &json)); JsonDestroy(json); } } #define assert_json_strings_eq(unescaped, escaped) \ { \ char *const esc = JsonEncodeString(unescaped); \ char *const unesc = JsonDecodeString(escaped); \ assert_string_equal(esc, escaped); \ assert_string_equal(unesc, unescaped); \ free(esc); \ free(unesc); \ } static void test_string_escape(void) { assert_json_strings_eq("", ""); assert_json_strings_eq(" ", " "); assert_json_strings_eq("\t", "\\t"); assert_json_strings_eq("\n", "\\n"); assert_json_strings_eq("\b", "\\b"); assert_json_strings_eq("\f", "\\f"); assert_json_strings_eq("\r", "\\r"); assert_json_strings_eq("abc", "abc"); assert_json_strings_eq("\"", "\\\""); assert_json_strings_eq( "Hello, world!\n'Blah', \"blah\".", "Hello, world!\\n'Blah', \\\"blah\\\"."); } #define assert_json5_data_eq(_size, unescaped, escaped) \ { \ Slice data = {.data = (void *) unescaped, .size = _size}; \ \ char *const esc = Json5EscapeData(data); \ \ assert_string_equal(esc, escaped); \ free(esc); \ } #define assert_json5_strings(unescaped, escaped) \ { \ assert_json5_data_eq(strlen(unescaped), unescaped, escaped); \ } static void test_string_escape_json5(void) { // NUL-terminated strings, check backwards compatibility: assert_json5_strings("", ""); assert_json5_strings(" ", " "); assert_json5_strings("\t", "\\t"); assert_json5_strings("\n", "\\n"); assert_json5_strings("\b", "\\b"); assert_json5_strings("\f", "\\f"); assert_json5_strings("\r", "\\r"); assert_json5_strings("abc", "abc"); assert_json5_strings("\"", "\\\""); assert_json5_strings( "Hello, world!\n'Blah', \"blah\".", "Hello, world!\\n'Blah', \\\"blah\\\"."); // Encoding NUL bytes and strings without NUL-bytes: const char *const hello = "Hello"; assert_json5_data_eq(strlen(hello) + 1, hello, "Hello\\0"); char tab = '\t'; char nul = '\0'; assert_json5_data_eq(1, "", "\\0"); assert_json5_data_eq(1, &tab, "\\t"); assert_json5_data_eq(1, &nul, "\\0"); assert_json5_data_eq(2, " ", " \\0"); assert_json5_data_eq(4, "\0\0\0", "\\0\\0\\0\\0"); // Non-printable byte encoding: const char arr[] = {1, 2, 3, 4, 0x10, 0xF0, 0xFF}; assert_false(CharIsPrintableAscii(1)); assert_false(CharIsPrintableAscii(2)); assert_false(CharIsPrintableAscii(3)); assert_false(CharIsPrintableAscii(4)); assert_false(CharIsPrintableAscii(0x10)); assert_false(CharIsPrintableAscii(0xF0)); assert_false(CharIsPrintableAscii(0xFF)); assert_json5_data_eq(7, arr, "\\x01\\x02\\x03\\x04\\x10\\xF0\\xFF"); } static void test_json_null_not_null(void) { JsonElement *json = NULL; assert_true(NULL_JSON(json)); assert_false(JSON_NOT_NULL(json)); json = JsonObjectCreate(3); assert_true(JSON_NOT_NULL(json)); assert_false(NULL_JSON(json)); JsonObjectAppendInteger(json, "one", 1); JsonElement *child = JsonObjectGet(json, "one"); assert_true(JSON_NOT_NULL(child)); assert_false(NULL_JSON(child)); JsonObjectAppendNull(json, "two"); child = JsonObjectGet(json, "two"); assert_true(NULL_JSON(child)); assert_false(JSON_NOT_NULL(child)); JsonDestroy(json); } static bool check_json_object_merge_deep(const char *base_raw, const char *extra_raw, const char *expected_raw) { LogSetGlobalLevel(LOG_LEVEL_DEBUG); bool pass = true; JsonElement *actual = NULL; JsonElement *base = NULL; JsonElement *extra = NULL; JsonElement *expected = NULL; char *expected_string = NULL; char *actual_string = NULL; if (JsonParse(&base_raw, &base) != JSON_PARSE_OK) { printf("error: could not parse base: %s\n", base_raw); pass = false; goto finish; } if (JsonParse(&extra_raw, &extra) != JSON_PARSE_OK) { printf("error: could not parse extra: %s\n", extra_raw); pass = false; goto finish; } if (JsonParse(&expected_raw, &expected) != JSON_PARSE_OK) { printf("error: could not parse expected: %s\n", expected_raw); pass = false; goto finish; } expected_string = JsonToString(expected); actual = JsonObjectMergeDeep(base, extra); if (actual == NULL || actual == base) { pass = false; goto finish; } actual_string = JsonToString(actual); if (JsonCompare(actual, expected) != 0) { pass = false; goto finish; } DESTROY_AND_NULL(JsonDestroy,actual); actual = JsonObjectMergeDeepInplace(base, extra); // JsonObjectMergeDeepInplace() returns the first parameter (base) so actual should point to base if (actual != base) { pass = false; goto finish; } if (JsonCompare(actual, expected)) { pass = false; goto finish; } finish: if (actual_string) { if (pass == false) { printf("merged json : %s\n", actual_string); } free(actual_string); } if (expected_string) { if (pass == false) { printf("expected json: %s\n", expected_string); } free(expected_string); } // in second step of JsonObjectMergeDeepInplace() actual should point to base if (actual != base) { JsonDestroy(actual); } JsonDestroy(base); JsonDestroy(extra); JsonDestroy(expected); return pass; } static void test_json_object_merge_deep() { /* This unit test tests both JsonMergeObjectDeep and * JsonMergeObjectDeepInplace */ assert_true(check_json_object_merge_deep( // base "{}", // extra "{}", // expected "{}" )); assert_true(check_json_object_merge_deep( // base "{}", // extra "{" " \"variables\": {}" "}", // expected "{" " \"variables\": {}" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {}" "}", // extra "{}", // expected "{" " \"variables\": {}" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {}" "}", // extra "{" " \"variables\": {}" "}", // expected "{" " \"variables\": {}" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {}" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_one\": {}" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_one\": {}" " }" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {" " \"cfbs:delete_files.filenames_two\": {" " \"value\": [ \"/tmp/virus\" ]," " \"tags\": [ \"foo\", \"bar\", \"bas\" ]" " }" " }" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_two\": {" " \"value\": [ \"/tmp/malicious\" ]," " \"comment\": [ \"Delete dangerous files!\" ]" " }" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_two\": {" " \"comment\": [ \"Delete dangerous files!\" ]," " \"tags\": [ \"foo\", \"bar\", \"bas\" ]," " \"value\": [ \"/tmp/virus\", \"/tmp/malicious\" ]" " }" " }" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"classes\": {" " \"cfbs_delete_files_enable\": {" " \"class_expressions\": [" " \"linux.redhat::\"," " \"cfengine|linux::\"" " ]," " \"tags\": [ \"bogus\", \"doofus\", \"bonkers\" ]" " }" " }" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_three\": {" " \"value\": [ \"/tmp/malicious\" ]," " \"comment\": [ \"Delete dangerous files!\" ]" " }" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_three\": {" " \"comment\": [ \"Delete dangerous files!\" ]," " \"value\": [ \"/tmp/malicious\" ]" " }" " }," " \"classes\": {" " \"cfbs_delete_files_enable\": {" " \"class_expressions\": [" " \"linux.redhat::\"," " \"cfengine|linux::\"" " ]," " \"tags\": [ \"bogus\", \"doofus\", \"bonkers\" ]" " }" " }" "}" )); // NOTE: this assert_false() test is the same as the next one with the exception of value:/tmp/foobad to check deep compare assert_false(check_json_object_merge_deep( // base "{" " \"variables\": {" " \"cfbs:delete_files.filenames_bad\": {" " \"value\": [ \"/tmp/foo\", \"/tmp/bar\" ]," " }" " }" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_bad\": {" " \"value\": [ \"/tmp/bar\", \"/tmp/baz\" ]," " }" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_bad\": {" " \"value\": [ \"/tmp/foobad\", \"/tmp/bar\", \"/tmp/bar\", \"/tmp/baz\" ]," " }" " }" "}" )); // this second negative test checks that a mismatch of a second child of an object is found // note the "badchild" in the expectation // there was a bug as I was working here where only the number of children mattered if the first matched, any more than that were not compared assert_false(check_json_object_merge_deep( // base "{" " \"variables_bad_two\": {" " \"cfbs:delete_files.filenames_bad_two\": {" " \"value\": [ \"/tmp/foo\", \"/tmp/bar\" ]," " \"badchild\": { \"one\": \"uno\", \"two\": \"due\" }," " }" " }" "}", // extra "{" " \"variables_bad_two\": {" " \"cfbs:delete_files.filenames_bad_two\": {" " \"value\": [ \"/tmp/bar\", \"/tmp/baz\" ]," " }" " }" "}", // expected "{" " \"variables_bad_two\": {" " \"cfbs:delete_files.filenames_bad_two\": {" " \"value\": [ \"/tmp/foo\", \"/tmp/bar\", \"/tmp/bar\", \"/tmp/baz\" ]," " \"badchild\": { \"one\": \"uno\", \"two\": \"dva\" }," " }" " }" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables_four\": {" " \"cfbs:delete_files.filenames_four\": {" " \"value\": [ \"/tmp/foo\", \"/tmp/bar\" ]," " }" " }" "}", // extra "{" " \"variables_four\": {" " \"cfbs:delete_files.filenames_four\": {" " \"value\": [ \"/tmp/bar\", \"/tmp/baz\" ]," " }" " }" "}", // expected "{" " \"variables_four\": {" " \"cfbs:delete_files.filenames_four\": {" " \"value\": [ \"/tmp/foo\", \"/tmp/bar\", \"/tmp/bar\", \"/tmp/baz\" ]," " }" " }" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {" " \"cfbs:delete_files.filenames_five\": {" " \"value\": []," " }" " }" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_five\": {" " \"value\": {}," " }" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_five\": {" " \"value\": {}," " }" " }" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {" " \"cfbs:delete_files.filenames_six\": {" " \"value\": {}," " }" " }" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_six\": {" " \"value\": []," " }" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_six\": {" " \"value\": []," " }" " }" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {" " \"cfbs:delete_files.filenames_seven\": {" " \"value\": []," " }" " }" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_seven\": {" " \"value\": 123," " }" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_seven\": {" " \"value\": 123," " }" " }" "}" )); assert_true(check_json_object_merge_deep( // base "{" " \"variables\": {" " \"cfbs:delete_files.filenames_eight\": {" " \"value\": 123," " }" " }" "}", // extra "{" " \"variables\": {" " \"cfbs:delete_files.filenames_eight\": {" " \"value\": {}," " }" " }" "}", // expected "{" " \"variables\": {" " \"cfbs:delete_files.filenames_eight\": {" " \"value\": {}," " }" " }" "}" )); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_array_get_string), unit_test(test_array_iterator), unit_test(test_array_remove_range), unit_test(test_array_extend), unit_test(test_copy_compare), unit_test(test_detach_key_from_object), unit_test(test_iterator_current), unit_test(test_merge_array), unit_test(test_merge_object), unit_test(test_new_delete), unit_test(test_object_duplicate_key), unit_test(test_object_get_array), unit_test(test_object_get_string), unit_test(test_object_get_bool), unit_test(test_object_iterator), unit_test(test_json_walk), unit_test(test_parse_array_bad_nested_elems), unit_test(test_parse_array_comma_after_brace), unit_test(test_parse_array_diverse), unit_test(test_parse_array_double_and_trailing_commas), unit_test(test_parse_array_extra_closing), unit_test(test_parse_all), unit_test(test_parse_array_garbage), unit_test(test_parse_array_nested_garbage), unit_test(test_parse_array_object), unit_test(test_parse_array_simple), unit_test(test_parse_bad_apple2), unit_test(test_parse_bad_numbers), unit_test(test_parse_empty_containers), unit_test(test_parse_empty_string), unit_test(test_parse_escaped_string), unit_test(test_parse_big_numbers), unit_test(test_parse_good_numbers), unit_test(test_parse_object_compound), unit_test(test_parse_object_diverse), unit_test(test_parse_object_double_and_trailing_comma), unit_test(test_parse_object_double_colon), unit_test(test_parse_object_escaped), unit_test(test_parse_object_garbage), unit_test(test_parse_object_nested_garbage), unit_test(test_parse_object_simple), unit_test(test_parse_primitives), unit_test(test_parse_trim), unit_test(test_parse_tzz_evil_key), unit_test(test_remove_key_from_object), unit_test(test_select), unit_test(test_show_array), unit_test(test_show_array_boolean), unit_test(test_show_array_compact), unit_test(test_show_array_empty), unit_test(test_show_array_infinity), unit_test(test_show_array_nan), unit_test(test_show_array_numeric), unit_test(test_show_array_object), unit_test(test_show_object_array), unit_test(test_show_object_boolean), unit_test(test_show_object_compound), unit_test(test_show_object_compound_compact), unit_test(test_show_object_escaped), unit_test(test_show_object_numeric), unit_test(test_show_object_simple), unit_test(test_show_string), unit_test(test_string_escape), unit_test(test_string_escape_json5), unit_test(test_json_null_not_null), unit_test(test_json_object_merge_deep), unit_test(test_compare_container_type_mismatch), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/refcount_test.c0000644000000000000000000001500115010704254022312 0ustar00rootroot00000000000000#include #include // Simple initialization test static void test_init_destroy_RefCount(void) { RefCount *refCount = NULL; RefCountNew(&refCount); assert_int_equal(0, refCount->user_count); assert_true(refCount->last == NULL); assert_true(refCount->users == NULL); // Now we destroy the refcount. RefCountDestroy(&refCount); assert_true(refCount == NULL); // Try to destroy a NULL refCount RefCountDestroy(&refCount); } static void test_attach_detach_RefCount(void) { /* * This test does not check for NULL pointers, otherwise asserts will * be triggered. Neither does it check for non-existent owners. */ int data1 = 0xdeadbeef; int data2 = 0xbad00bad; int data3 = 0x55aaaa55; RefCount *refCount = NULL; // initialize the refcount RefCountNew(&refCount); assert_int_equal(0, refCount->user_count); assert_true(refCount->last == NULL); assert_true(refCount->users == NULL); // attach it to the first data RefCountAttach(refCount, &data1); // Check the result assert_int_equal(1, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous == NULL); assert_true(refCount->last->user == (void *)&data1); // Attach the second data RefCountAttach(refCount, &data2); // Check the result assert_int_equal(2, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous != NULL); assert_true(refCount->last->user == (void *)&data2); // Detach the first data RefCountDetach(refCount, &data1); // Check the result assert_int_equal(1, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous == NULL); assert_true(refCount->last->user == (void *)&data2); // Attach the third data RefCountAttach(refCount, &data3); // Check the result assert_int_equal(2, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous != NULL); assert_true(refCount->last->user == (void *)&data3); // Attach the first data RefCountAttach(refCount, &data1); // Check the result assert_int_equal(3, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous != NULL); assert_true(refCount->last->user == (void *)&data1); // Detach the third data RefCountDetach(refCount, &data3); // Check the result assert_int_equal(2, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous != NULL); assert_true(refCount->last->user == (void *)&data1); // Detach the first data RefCountDetach(refCount, &data1); // Check the result assert_int_equal(1, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous == NULL); assert_true(refCount->last->user == (void *)&data2); /* * We cannot detach the last element because that will assert. * Whenever there is only one element the only thing is to destroy * the refcount. */ // Destroy the refcount RefCountDestroy(&refCount); } static void test_isSharedRefCount(void) { int data1 = 0xdeadbeef; int data2 = 0xbad00bad; RefCount *refCount = NULL; // initialize the refcount RefCountNew(&refCount); assert_int_equal(0, refCount->user_count); assert_true(refCount->last == NULL); assert_true(refCount->users == NULL); // isShared should return false assert_false(RefCountIsShared(refCount)); // attach it to the first data RefCountAttach(refCount, &data1); // Check the result assert_int_equal(1, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous == NULL); assert_true(refCount->last->user == (void *)&data1); // isShared should return false assert_false(RefCountIsShared(refCount)); // Attach the second data RefCountAttach(refCount, &data2); // Check the result assert_int_equal(2, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous != NULL); assert_true(refCount->last->user == (void *)&data2); // isShared should return true assert_true(RefCountIsShared(refCount)); // Detach and try again RefCountDetach(refCount, &data1); // Check the result assert_int_equal(1, refCount->user_count); assert_true(refCount->last->next == NULL); assert_true(refCount->last->previous == NULL); assert_true(refCount->last->user == (void *)&data2); // isShared should return false assert_false(RefCountIsShared(refCount)); // Try isShared with a NULL refCount assert_false(RefCountIsShared(NULL)); // Destroy the refcount RefCountDestroy(&refCount); } static void test_isEqualRefCount(void) { int data2 = 0xbad00bad; RefCount *refCount1 = NULL; RefCount *refCount2 = NULL; // initialize refcount1 RefCountNew(&refCount1); assert_int_equal(0, refCount1->user_count); assert_true(refCount1->last == NULL); assert_true(refCount1->users == NULL); // initialize refcount2 as a copy of refcount1 refCount2 = refCount1; // isEqual should return true assert_true(RefCountIsEqual(refCount1, refCount2)); /* Initialize refcount2 on its own */ RefCountNew(&refCount2); assert_int_equal(0, refCount2->user_count); assert_true(refCount2->last == NULL); assert_true(refCount2->users == NULL); // isEqual should return false assert_false(RefCountIsEqual(refCount1, refCount2)); // Add one to refcount1 RefCountAttach(refCount1, &data2); // isEqual should return false assert_false(RefCountIsEqual(refCount1, refCount2)); // Add the same to refcount2 RefCountAttach(refCount2, &data2); // isEqual should return false assert_false(RefCountIsEqual(refCount1, refCount2)); // Try one NULL assert_false(RefCountIsEqual(refCount1, NULL)); assert_false(RefCountIsEqual(NULL, refCount2)); // Both NULL assert_false(RefCountIsEqual(NULL, NULL)); // Destroy both refcounts RefCountDestroy(&refCount1); RefCountDestroy(&refCount2); } int main() { const UnitTest tests[] = { unit_test(test_init_destroy_RefCount) , unit_test(test_attach_detach_RefCount) , unit_test(test_isSharedRefCount) , unit_test(test_isEqualRefCount) }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/thread_test.c0000644000000000000000000000663315010704254021747 0ustar00rootroot00000000000000#include #include #define NUM_THREADS 100 static void create_children(pthread_t tids[NUM_THREADS]); static void join_children(pthread_t tids[NUM_THREADS]); static void increment_shared_var(void); int SHARED_VAR; pthread_mutex_t shared_var_mutex = PTHREAD_MUTEX_INITIALIZER; void test_init_destroy(void) { pthread_mutex_t mutex_dynamic; int res_init = pthread_mutex_init(&mutex_dynamic, NULL); assert_int_equal(res_init, 0); int res_destroy = pthread_mutex_destroy(&mutex_dynamic); assert_int_equal(res_destroy, 0); } void test_trylock_impl(pthread_mutex_t *mutex) { int res_trylock_unlocked = pthread_mutex_trylock(mutex); assert_int_equal(res_trylock_unlocked, 0); int res_trylock_locked = pthread_mutex_trylock(mutex); if (res_trylock_locked != EBUSY && res_trylock_locked != EDEADLK) { /* Some pthread implementations return EDEADLK despite SUS saying otherwise */ fail(); } int res_unlock = pthread_mutex_unlock(mutex); assert_int_equal(res_unlock, 0); } void test_trylock_dynamic(void) { pthread_mutex_t mutex_dynamic; int res_init = pthread_mutex_init(&mutex_dynamic, NULL); assert_int_equal(res_init, 0); test_trylock_impl(&mutex_dynamic); int res_destroy = pthread_mutex_destroy(&mutex_dynamic); assert_int_equal(res_destroy, 0); } void test_trylock_static(void) { pthread_mutex_t mutex_static = PTHREAD_MUTEX_INITIALIZER; test_trylock_impl(&mutex_static); } void test_trylock_static_errorcheck(void) { pthread_mutex_t mutex_static_errorcheck = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; test_trylock_impl(&mutex_static_errorcheck); } void test_create(void) { SHARED_VAR = 0; pthread_t tid; int res_create = pthread_create(&tid, NULL, (void *) increment_shared_var, NULL); assert_int_equal(res_create, 0); int res_join = pthread_join(tid, NULL); assert_int_equal(res_join, 0); assert_int_equal(SHARED_VAR, 1); } static void increment_shared_var(void) { #define THREAD_ITERATIONS 1000 int res_lock = pthread_mutex_lock(&shared_var_mutex); assert_int_equal(res_lock, 0); for(int i = 0; i < THREAD_ITERATIONS; i++) { SHARED_VAR++; SHARED_VAR--; } SHARED_VAR++; int res_unlock = pthread_mutex_unlock(&shared_var_mutex); assert_int_equal(res_unlock, 0); } void test_lock(void) { SHARED_VAR = 0; pthread_t tids[NUM_THREADS]; create_children(tids); join_children(tids); assert_int_equal(SHARED_VAR, NUM_THREADS); } static void create_children(pthread_t tids[NUM_THREADS]) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 65536); for(int i = 0; i < NUM_THREADS; i++) { int res_create = pthread_create(&(tids[i]), &attr, (void *) increment_shared_var, NULL); assert_int_equal(res_create, 0); } } static void join_children(pthread_t tids[NUM_THREADS]) { for(int i = 0; i < NUM_THREADS; i++) { int res_join = pthread_join(tids[i], NULL); assert_int_equal(res_join, 0); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_init_destroy), unit_test(test_trylock_dynamic), unit_test(test_trylock_static), unit_test(test_trylock_static_errorcheck), unit_test(test_create), unit_test(test_lock), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/string_writer_test.c0000644000000000000000000000373715010704254023404 0ustar00rootroot00000000000000#include #include #include void test_empty_string_buffer(void) { Writer *w = StringWriter(); assert_int_equal(StringWriterLength(w), 0); assert_string_equal(StringWriterData(w), ""); WriterClose(w); } void test_write_empty_string_buffer(void) { Writer *w = StringWriter(); WriterWrite(w, ""); assert_int_equal(StringWriterLength(w), 0); assert_string_equal(StringWriterData(w), ""); WriterClose(w); } void test_write_string_buffer(void) { Writer *w = StringWriter(); WriterWrite(w, "123"); assert_int_equal(StringWriterLength(w), 3); assert_string_equal(StringWriterData(w), "123"); WriterClose(w); } void test_multiwrite_string_buffer(void) { Writer *w = StringWriter(); WriterWrite(w, "123"); WriterWrite(w, "456"); assert_int_equal(StringWriterLength(w), 6); assert_string_equal(StringWriterData(w), "123456"); WriterClose(w); } void test_write_char_string_buffer(void) { Writer *w = StringWriter(); WriterWriteChar(w, '1'); WriterWriteChar(w, '2'); WriterWriteChar(w, '3'); assert_string_equal(StringWriterData(w), "123"); WriterClose(w); } void test_release_string(void) { Writer *w = StringWriter(); WriterWrite(w, "123"); WriterWrite(w, "456"); char *ret = StringWriterClose(w); assert_string_equal(ret, "123456"); free(ret); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_empty_string_buffer), unit_test(test_write_empty_string_buffer), unit_test(test_write_string_buffer), unit_test(test_multiwrite_string_buffer), unit_test(test_write_char_string_buffer), unit_test(test_release_string), }; return run_tests(tests); } // STUBS void __ProgrammingError(ARG_UNUSED const char *file, ARG_UNUSED int lineno, ARG_UNUSED const char *format, ...) { fail(); exit(42); } cfengine-3.24.2/libntech/tests/unit/data/0000755000000000000000000000000015010704254020176 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/tests/unit/data/mustache_delimiters.json0000644000000000000000000000545015010704254025127 0ustar00rootroot00000000000000{ "tests": [ { "name": "Pair Behavior", "data": { "text": "Hey!" }, "expected": "(Hey!)", "template": "{{=<% %>=}}(<%text%>)", "desc": "The equals sign (used on both sides) should permit delimiter changes." }, { "name": "Special Characters", "data": { "text": "It worked!" }, "expected": "(It worked!)", "template": "({{=[ ]=}}[text])", "desc": "Characters with special meaning regexen should be valid delimiters." }, { "name": "Sections", "data": { "section": true, "data": "I got interpolated." }, "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", "template": "[\n{{#section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|#section|\n {{data}}\n |data|\n|/section|\n]\n", "desc": "Delimiters set outside sections should persist." }, { "name": "Inverted Sections", "data": { "section": false, "data": "I got interpolated." }, "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", "template": "[\n{{^section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|^section|\n {{data}}\n |data|\n|/section|\n]\n", "desc": "Delimiters set outside inverted sections should persist." }, { "name": "Surrounding Whitespace", "data": {}, "expected": "| |", "template": "| {{=@ @=}} |", "desc": "Surrounding whitespace should be left untouched." }, { "name": "Outlying Whitespace (Inline)", "data": {}, "expected": " | \n", "template": " | {{=@ @=}}\n", "desc": "Whitespace should be left untouched." }, { "name": "Standalone Tag", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n{{=@ @=}}\nEnd.\n", "desc": "Standalone lines should be removed from the template." }, { "name": "Indented Standalone Tag", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n {{=@ @=}}\nEnd.\n", "desc": "Indented standalone lines should be removed from the template." }, { "name": "Pair with Padding", "data": {}, "expected": "||", "template": "|{{= @ @ =}}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/libntech/tests/unit/data/mustache_comments.json0000644000000000000000000000636715010704254024623 0ustar00rootroot00000000000000{ "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", "overview": "Comment tags represent content that should never appear in the resulting\noutput.\n\nThe tag's content may contain any substring (including newlines) EXCEPT the\nclosing delimiter.\n\nComment tags SHOULD be treated as standalone when appropriate.\n", "tests": [ { "name": "Inline", "data": {}, "expected": "1234567890", "template": "12345{{! Comment Block! }}67890", "desc": "Comment blocks should be removed from the template." }, { "name": "Multiline", "data": {}, "expected": "1234567890\n", "template": "12345{{!\n This is a\n multi-line comment...\n}}67890\n", "desc": "Multiline comments should be permitted." }, { "name": "Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n{{! Comment Block! }}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Indented Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n {{! Indented Comment Block! }}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Standalone Line Endings", "data": {}, "expected": "|\r\n|", "template": "|\r\n{{! Standalone Comment }}\r\n|", "desc": "\"\\r\\n\" should be considered a newline for standalone tags." }, { "name": "Standalone Without Previous Line", "data": {}, "expected": "!", "template": " {{! I'm Still Standalone }}\n!", "desc": "Standalone tags should not require a newline to precede them." }, { "name": "Standalone Without Newline", "data": {}, "expected": "!\n", "template": "!\n {{! I'm Still Standalone }}", "desc": "Standalone tags should not require a newline to follow them." }, { "name": "Multiline Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n{{!\nSomething's going on here...\n}}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Indented Multiline Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n {{!\n Something's going on here...\n }}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Indented Inline", "data": {}, "expected": " 12 \n", "template": " 12 {{! 34 }}\n", "desc": "Inline comments should not strip whitespace" }, { "name": "Surrounding Whitespace", "data": {}, "expected": "12345 67890", "template": "12345 {{! Comment Block! }} 67890", "desc": "Comment removal should preserve surrounding whitespace." } ] } cfengine-3.24.2/libntech/tests/unit/data/csv_file.csv0000644000000000000000000000011115010704254022476 0ustar00rootroot00000000000000field_1, field_2 field_1, "value1 value2 value3" field_1, "field,2" cfengine-3.24.2/libntech/tests/unit/data/mustache_sections.json0000644000000000000000000002655515010704254024626 0ustar00rootroot00000000000000{ "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", "overview": "Section tags and End Section tags are used in combination to wrap a section\nof the template for iteration\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Section tag MUST be followed\nby an End Section tag with the same content within the same section.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nFor each element in the data list, the element MUST be pushed onto the\ncontext stack, the section MUST be rendered, and the element MUST be popped\noff the context stack.\n\nSection and End Section tags SHOULD be treated as standalone when\nappropriate.\n", "tests": [ { "name": "Truthy", "data": { "boolean": true }, "expected": "\"This should be rendered.\"", "template": "\"{{#boolean}}This should be rendered.{{/boolean}}\"", "desc": "Truthy sections should have their contents rendered." }, { "name": "Falsey", "data": { "boolean": false }, "expected": "\"\"", "template": "\"{{#boolean}}This should not be rendered.{{/boolean}}\"", "desc": "Falsey sections should have their contents omitted." }, { "name": "Context", "data": { "context": { "name": "Joe" } }, "expected": "\"Hi Joe.\"", "template": "\"{{#context}}Hi {{name}}.{{/context}}\"", "desc": "Objects and hashes should be pushed onto the context stack." }, { "name": "Deeply Nested Contexts", "data": { "a": { "one": 1 }, "b": { "two": 2 }, "c": { "three": 3 }, "d": { "four": 4 }, "e": { "five": 5 } }, "expected": "1\n121\n12321\n1234321\n123454321\n1234321\n12321\n121\n1\n", "template": "{{#a}}\n{{one}}\n{{#b}}\n{{one}}{{two}}{{one}}\n{{#c}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{#d}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{#e}}\n{{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}\n{{/e}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{/d}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{/c}}\n{{one}}{{two}}{{one}}\n{{/b}}\n{{one}}\n{{/a}}\n", "desc": "All elements on the context stack should be accessible." }, { "name": "List", "data": { "list": [ { "item": 1 }, { "item": 2 }, { "item": 3 } ] }, "expected": "\"123\"", "template": "\"{{#list}}{{item}}{{/list}}\"", "desc": "Lists should be iterated; list items should visit the context stack." }, { "name": "Empty List", "data": { "list": [] }, "expected": "\"\"", "template": "\"{{#list}}Yay lists!{{/list}}\"", "desc": "Empty lists should behave like falsey values." }, { "name": "Doubled", "data": { "two": "second", "bool": true }, "expected": "* first\n* second\n* third\n", "template": "{{#bool}}\n* first\n{{/bool}}\n* {{two}}\n{{#bool}}\n* third\n{{/bool}}\n", "desc": "Multiple sections per template should be permitted." }, { "name": "Nested (Truthy)", "data": { "bool": true }, "expected": "| A B C D E |", "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested truthy sections should have their contents rendered." }, { "name": "Nested (Falsey)", "data": { "bool": false }, "expected": "| A E |", "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested falsey sections should be omitted." }, { "name": "Context Misses", "data": {}, "expected": "[]", "template": "[{{#missing}}Found key 'missing'!{{/missing}}]", "desc": "Failed context lookups should be considered falsey." }, { "name": "Implicit Iterator - String", "data": { "list": [ "a", "b", "c", "d", "e" ] }, "expected": "\"(a)(b)(c)(d)(e)\"", "template": "\"{{#list}}({{.}}){{/list}}\"", "desc": "Implicit iterators should directly interpolate strings." }, { "name": "Implicit Iterator - Integer", "data": { "list": [ 1, 2, 3, 4, 5 ] }, "expected": "\"(1)(2)(3)(4)(5)\"", "template": "\"{{#list}}({{.}}){{/list}}\"", "desc": "Implicit iterators should cast integers to strings and interpolate." }, { "name": "Implicit Iterator - Decimal", "data": { "list": [ 1.1, 2.2, 3.3, 4.4, 5.5 ] }, "expected": "\"(1.10)(2.20)(3.30)(4.40)(5.50)\"", "template": "\"{{#list}}({{.}}){{/list}}\"", "desc": "Implicit iterators should cast decimals to strings and interpolate." }, { "name": "Dotted Names - Truthy", "data": { "a": { "b": { "c": true } } }, "expected": "\"Here\" == \"Here\"", "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"Here\"", "desc": "Dotted names should be valid for Section tags." }, { "name": "Dotted Names - Falsey", "data": { "a": { "b": { "c": false } } }, "expected": "\"\" == \"\"", "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", "desc": "Dotted names should be valid for Section tags." }, { "name": "Dotted Names - Broken Chains", "data": { "a": {} }, "expected": "\"\" == \"\"", "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", "desc": "Dotted names that cannot be resolved should be considered falsey." }, { "name": "Surrounding Whitespace", "data": { "boolean": true }, "expected": " | \t|\t | \n", "template": " | {{#boolean}}\t|\t{{/boolean}} | \n", "desc": "Sections should not alter surrounding whitespace." }, { "name": "Internal Whitespace", "data": { "boolean": true }, "expected": " | \n | \n", "template": " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", "desc": "Sections should not alter internal whitespace." }, { "name": "Indented Inline Sections", "data": { "boolean": true }, "expected": " YES\n GOOD\n", "template": " {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n", "desc": "Single-line sections should not alter surrounding whitespace." }, { "name": "Standalone Lines", "data": { "boolean": true }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n{{#boolean}}\n|\n{{/boolean}}\n| A Line\n", "desc": "Standalone lines should be removed from the template." }, { "name": "Indented Standalone Lines", "data": { "boolean": true }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n {{#boolean}}\n|\n {{/boolean}}\n| A Line\n", "desc": "Indented standalone lines should be removed from the template." }, { "name": "Standalone Line Endings", "data": { "boolean": true }, "expected": "|\r\n|", "template": "|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|", "desc": "\"\\r\\n\" should be considered a newline for standalone tags." }, { "name": "Standalone Without Previous Line", "data": { "boolean": true }, "expected": "#\n/", "template": " {{#boolean}}\n#{{/boolean}}\n/", "desc": "Standalone tags should not require a newline to precede them." }, { "name": "Standalone Without Newline", "data": { "boolean": true }, "expected": "#\n/\n", "template": "#{{#boolean}}\n/\n {{/boolean}}", "desc": "Standalone tags should not require a newline to follow them." }, { "name": "Padding", "data": { "boolean": true }, "expected": "|=|", "template": "|{{# boolean }}={{/ boolean }}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/libntech/tests/unit/data/mustache_inverted.json0000644000000000000000000002167115010704254024611 0ustar00rootroot00000000000000{ "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", "overview": "Inverted Section tags and End Section tags are used in combination to wrap a\nsection of the template.\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Inverted Section tag MUST be\nfollowed by an End Section tag with the same content within the same\nsection.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nThis section MUST NOT be rendered unless the data list is empty.\n\nInverted Section and End Section tags SHOULD be treated as standalone when\nappropriate.\n", "tests": [ { "name": "Falsey", "data": { "boolean": false }, "expected": "\"This should be rendered.\"", "template": "\"{{^boolean}}This should be rendered.{{/boolean}}\"", "desc": "Falsey sections should have their contents rendered." }, { "name": "Truthy", "data": { "boolean": true }, "expected": "\"\"", "template": "\"{{^boolean}}This should not be rendered.{{/boolean}}\"", "desc": "Truthy sections should have their contents omitted." }, { "name": "Context", "data": { "context": { "name": "Joe" } }, "expected": "\"\"", "template": "\"{{^context}}Hi {{name}}.{{/context}}\"", "desc": "Objects and hashes should behave like truthy values." }, { "name": "List", "data": { "list": [ { "n": 1 }, { "n": 2 }, { "n": 3 } ] }, "expected": "\"\"", "template": "\"{{^list}}{{n}}{{/list}}\"", "desc": "Lists should behave like truthy values." }, { "name": "Empty List", "data": { "list": [] }, "expected": "\"Yay lists!\"", "template": "\"{{^list}}Yay lists!{{/list}}\"", "desc": "Empty lists should behave like falsey values." }, { "name": "Doubled", "data": { "two": "second", "bool": false }, "expected": "* first\n* second\n* third\n", "template": "{{^bool}}\n* first\n{{/bool}}\n* {{two}}\n{{^bool}}\n* third\n{{/bool}}\n", "desc": "Multiple inverted sections per template should be permitted." }, { "name": "Nested (Falsey)", "data": { "bool": false }, "expected": "| A B C D E |", "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested falsey sections should have their contents rendered." }, { "name": "Nested (Truthy)", "data": { "bool": true }, "expected": "| A E |", "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested truthy sections should be omitted." }, { "name": "Context Misses", "data": {}, "expected": "[Cannot find key 'missing'!]", "template": "[{{^missing}}Cannot find key 'missing'!{{/missing}}]", "desc": "Failed context lookups should be considered falsey." }, { "name": "Dotted Names - Truthy", "data": { "a": { "b": { "c": true } } }, "expected": "\"\" == \"\"", "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"\"", "desc": "Dotted names should be valid for Inverted Section tags." }, { "name": "Dotted Names - Falsey", "data": { "a": { "b": { "c": false } } }, "expected": "\"Not Here\" == \"Not Here\"", "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", "desc": "Dotted names should be valid for Inverted Section tags." }, { "name": "Dotted Names - Broken Chains", "data": { "a": {} }, "expected": "\"Not Here\" == \"Not Here\"", "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", "desc": "Dotted names that cannot be resolved should be considered falsey." }, { "name": "Surrounding Whitespace", "data": { "boolean": false }, "expected": " | \t|\t | \n", "template": " | {{^boolean}}\t|\t{{/boolean}} | \n", "desc": "Inverted sections should not alter surrounding whitespace." }, { "name": "Internal Whitespace", "data": { "boolean": false }, "expected": " | \n | \n", "template": " | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", "desc": "Inverted should not alter internal whitespace." }, { "name": "Indented Inline Sections", "data": { "boolean": false }, "expected": " NO\n WAY\n", "template": " {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n", "desc": "Single-line sections should not alter surrounding whitespace." }, { "name": "Standalone Lines", "data": { "boolean": false }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n{{^boolean}}\n|\n{{/boolean}}\n| A Line\n", "desc": "Standalone lines should be removed from the template." }, { "name": "Standalone Indented Lines", "data": { "boolean": false }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n {{^boolean}}\n|\n {{/boolean}}\n| A Line\n", "desc": "Standalone indented lines should be removed from the template." }, { "name": "Standalone Line Endings", "data": { "boolean": false }, "expected": "|\r\n|", "template": "|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|", "desc": "\"\\r\\n\" should be considered a newline for standalone tags." }, { "name": "Standalone Without Previous Line", "data": { "boolean": false }, "expected": "^\n/", "template": " {{^boolean}}\n^{{/boolean}}\n/", "desc": "Standalone tags should not require a newline to precede them." }, { "name": "Standalone Without Newline", "data": { "boolean": false }, "expected": "^\n/\n", "template": "^{{^boolean}}\n/\n {{/boolean}}", "desc": "Standalone tags should not require a newline to follow them." }, { "name": "Padding", "data": { "boolean": false }, "expected": "|=|", "template": "|{{^ boolean }}={{/ boolean }}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/libntech/tests/unit/data/csv_file_edge_cases.csv0000644000000000000000000000015115010704254024644 0ustar00rootroot00000000000000Empty,Empty,One double quote,Two double quotes,LF,CRLF,CRLFCRLF,Empty "",,"""",""""""," "," "," ", cfengine-3.24.2/libntech/tests/unit/data/mustache_extra.json0000644000000000000000000000446115010704254024112 0ustar00rootroot00000000000000{ "tests": [ { "name": "Demo", "data": { "header": "Colors", "items": [ {"name": "red", "first": true, "url": "#Red"}, {"name": "green", "link": true, "url": "#Green"}, {"name": "blue", "link": true, "url": "#Blue"} ], "empty": false }, "expected": "

Colors

\n\n
  • red
  • \n
  • green
  • \n
  • blue
  • \n\n", "template": "

    {{header}}

    \n{{#bug}}\n{{/bug}}\n\n{{#items}}\n {{#first}}\n
  • {{name}}
  • \n {{/first}}\n {{#link}}\n
  • {{name}}
  • \n {{/link}}\n{{/items}}\n\n{{#empty}}\n

    The list is empty.

    \n{{/empty}}\n" }, { "name": "Ted's Abusive Test 1", "data": { "x": 123 }, "template": "{{x}}", "expected": "123" }, { "name": "Ted's Abusive Test 2", "data": { "x": 123, "y": 456 }, "template": "{{x}} {{y}}", "expected": "123 456" }, { "name": "Ted's Abusive Test 3", "data": [ null ], "template": "{{null}}", "expected": "" }, { "name": "Ted's Abusive Test 4", "data": { "x": 123, "y": 456 }, "template": "{{}}", "expected": "{{}}" }, { "name": "Ted's Abusive Test 5", "data": { "boolean": true}, "template": "{{#boolean}}IT IS TRUE{{/boolean}}", "expected": "IT IS TRUE" }, { "name": "Ted's Abusive Test 6", "data": { "boolean": false}, "template": "{{^boolean}}IT IS FALSE{{/boolean}}", "expected": "IT IS FALSE" }, { "name": "Ted's Abusive Test 7", "data": { "list": [ { "k": 789, "v": 0 }, { "k": null, "v": true }, { "k": -1, "v": -2 } ] }, "template": "{{#list}}{{k}}={{v}}, {{/list}}", "expected": "789=0, =true, -1=-2, " }, ] } cfengine-3.24.2/libntech/tests/unit/data/sample.json0000644000000000000000000000041515010704254022352 0ustar00rootroot00000000000000{ "primitive1": "value1", "array0": [], "array1": [ "value2", "value3" ], "obj0": {}, "obj1": { "primitive2": "value4", "array2": [ "value5" ], "obj2": { "array3": [], "primitive3": "value6" } } } cfengine-3.24.2/libntech/tests/unit/data/mustache_interpolation.json0000644000000000000000000001431215010704254025652 0ustar00rootroot00000000000000{ "tests": [ { "name": "No Interpolation", "data": {}, "expected": "Hello from {Mustache}!\n", "template": "Hello from {Mustache}!\n", "desc": "Mustache-free templates should render as-is." }, { "name": "Basic Interpolation", "data": { "subject": "world" }, "expected": "Hello, world!\n", "template": "Hello, {{subject}}!\n", "desc": "Unadorned tags should interpolate content into the template." }, { "name": "HTML Escaping", "data": { "forbidden": "& \" < >" }, "expected": "These characters should be HTML escaped: & " < >\n", "template": "These characters should be HTML escaped: {{forbidden}}\n", "desc": "Basic interpolation should be HTML escaped." }, { "name": "Triple Mustache", "data": { "forbidden": "& \" < >" }, "expected": "These characters should not be HTML escaped: & \" < >\n", "template": "These characters should not be HTML escaped: {{{forbidden}}}\n", "desc": "Triple mustaches should interpolate without HTML escaping." }, { "name": "Ampersand", "data": { "forbidden": "& \" < >" }, "expected": "These characters should not be HTML escaped: & \" < >\n", "template": "These characters should not be HTML escaped: {{&forbidden}}\n", "desc": "Ampersand should interpolate without HTML escaping." }, { "name": "Basic Integer Interpolation", "data": { "mph": 85 }, "expected": "\"85 miles an hour!\"", "template": "\"{{mph}} miles an hour!\"", "desc": "Integers should interpolate seamlessly." }, { "name": "Triple Mustache Integer Interpolation", "data": { "mph": 85 }, "expected": "\"85 miles an hour!\"", "template": "\"{{{mph}}} miles an hour!\"", "desc": "Integers should interpolate seamlessly." }, { "name": "Ampersand Integer Interpolation", "data": { "mph": 85 }, "expected": "\"85 miles an hour!\"", "template": "\"{{&mph}} miles an hour!\"", "desc": "Integers should interpolate seamlessly." }, { "name": "Basic Decimal Interpolation", "data": { "power": 1.21 }, "expected": "\"1.21 jiggawatts!\"", "template": "\"{{power}} jiggawatts!\"", "desc": "Decimals should interpolate seamlessly with proper significance." }, { "name": "Triple Mustache Decimal Interpolation", "data": { "power": 1.21 }, "expected": "\"1.21 jiggawatts!\"", "template": "\"{{{power}}} jiggawatts!\"", "desc": "Decimals should interpolate seamlessly with proper significance." }, { "name": "Ampersand Decimal Interpolation", "data": { "power": 1.21 }, "expected": "\"1.21 jiggawatts!\"", "template": "\"{{&power}} jiggawatts!\"", "desc": "Decimals should interpolate seamlessly with proper significance." }, { "name": "Interpolation - Surrounding Whitespace", "data": { "string": "---" }, "expected": "| --- |", "template": "| {{string}} |", "desc": "Interpolation should not alter surrounding whitespace." }, { "name": "Triple Mustache - Surrounding Whitespace", "data": { "string": "---" }, "expected": "| --- |", "template": "| {{{string}}} |", "desc": "Interpolation should not alter surrounding whitespace." }, { "name": "Ampersand - Surrounding Whitespace", "data": { "string": "---" }, "expected": "| --- |", "template": "| {{&string}} |", "desc": "Interpolation should not alter surrounding whitespace." }, { "name": "Interpolation - Standalone", "data": { "string": "---" }, "expected": " ---\n", "template": " {{string}}\n", "desc": "Standalone interpolation should not alter surrounding whitespace." }, { "name": "Triple Mustache - Standalone", "data": { "string": "---" }, "expected": " ---\n", "template": " {{{string}}}\n", "desc": "Standalone interpolation should not alter surrounding whitespace." }, { "name": "Ampersand - Standalone", "data": { "string": "---" }, "expected": " ---\n", "template": " {{&string}}\n", "desc": "Standalone interpolation should not alter surrounding whitespace." }, { "name": "Interpolation With Padding", "data": { "string": "---" }, "expected": "|---|", "template": "|{{ string }}|", "desc": "Superfluous in-tag whitespace should be ignored." }, { "name": "Triple Mustache With Padding", "data": { "string": "---" }, "expected": "|---|", "template": "|{{{ string }}}|", "desc": "Superfluous in-tag whitespace should be ignored." }, { "name": "Ampersand With Padding", "data": { "string": "---" }, "expected": "|---|", "template": "|{{& string }}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/libntech/tests/unit/data/benchmark.json0000644000000000000000000001350615010704254023030 0ustar00rootroot00000000000000[ { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "Hello-World", "full_name": "octocat/Hello-World", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/octocat/Hello-World", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/octocat/Hello-World", "archive_url": "https://api.github.com/repos/octocat/Hello-World/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/octocat/Hello-World/assignees{/user}", "blobs_url": "https://api.github.com/repos/octocat/Hello-World/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/octocat/Hello-World/branches{/branch}", "collaborators_url": "https://api.github.com/repos/octocat/Hello-World/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/octocat/Hello-World/comments{/number}", "commits_url": "https://api.github.com/repos/octocat/Hello-World/commits{/sha}", "compare_url": "https://api.github.com/repos/octocat/Hello-World/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/{+path}", "contributors_url": "https://api.github.com/repos/octocat/Hello-World/contributors", "deployments_url": "https://api.github.com/repos/octocat/Hello-World/deployments", "downloads_url": "https://api.github.com/repos/octocat/Hello-World/downloads", "events_url": "https://api.github.com/repos/octocat/Hello-World/events", "forks_url": "https://api.github.com/repos/octocat/Hello-World/forks", "git_commits_url": "https://api.github.com/repos/octocat/Hello-World/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/octocat/Hello-World/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/octocat/Hello-World/git/tags{/sha}", "git_url": "git:github.com/octocat/Hello-World.git", "issue_comment_url": "https://api.github.com/repos/octocat/Hello-World/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/octocat/Hello-World/issues/events{/number}", "issues_url": "https://api.github.com/repos/octocat/Hello-World/issues{/number}", "keys_url": "https://api.github.com/repos/octocat/Hello-World/keys{/key_id}", "labels_url": "https://api.github.com/repos/octocat/Hello-World/labels{/name}", "languages_url": "https://api.github.com/repos/octocat/Hello-World/languages", "merges_url": "https://api.github.com/repos/octocat/Hello-World/merges", "milestones_url": "https://api.github.com/repos/octocat/Hello-World/milestones{/number}", "notifications_url": "https://api.github.com/repos/octocat/Hello-World/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/octocat/Hello-World/pulls{/number}", "releases_url": "https://api.github.com/repos/octocat/Hello-World/releases{/id}", "ssh_url": "git@github.com:octocat/Hello-World.git", "stargazers_url": "https://api.github.com/repos/octocat/Hello-World/stargazers", "statuses_url": "https://api.github.com/repos/octocat/Hello-World/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/octocat/Hello-World/subscribers", "subscription_url": "https://api.github.com/repos/octocat/Hello-World/subscription", "tags_url": "https://api.github.com/repos/octocat/Hello-World/tags", "teams_url": "https://api.github.com/repos/octocat/Hello-World/teams", "trees_url": "https://api.github.com/repos/octocat/Hello-World/git/trees{/sha}", "clone_url": "https://github.com/octocat/Hello-World.git", "mirror_url": "git:git.example.com/octocat/Hello-World", "hooks_url": "https://api.github.com/repos/octocat/Hello-World/hooks", "svn_url": "https://svn.github.com/octocat/Hello-World", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "master", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "template_repository": "octocat/template", "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "delete_branch_on_merge": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" } } ] cfengine-3.24.2/libntech/tests/unit/file_lib_test.c0000644000000000000000000016026115010704254022243 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #define TEMP_DIR "/tmp/file_lib_test" #define TEST_FILE "file_lib_test.txt" #define TEST_LINK "file_lib_test.link" #define TEST_DIR "file_lib_test.dir" #define TEST_SUBDIR "file_lib_test.sub" #define TEST_SUBSUBDIR "file_lib_test.sub/sub" #define TEST_STRING "BLUE balloon" #define TEST_SUBSTRING "YELLOW balloon" #define TEST_SUBSUBSTRING "RED balloon" // These are just a way to pass parameters into switch_symlink_hook(). // Since it can be called from CFEngine code, we need to do it like this. // The way COUNTDOWN works is that it counts down towards zero for each // component in the path passed to safe_open(). When it reaches zero, // the symlink will be inserted at that moment. int TEST_SYMLINK_COUNTDOWN = 0; const char *TEST_SYMLINK_NAME = ""; const char *TEST_SYMLINK_TARGET = ""; // If this is true, when the countdown has been reached, we alternate // between deleting and creating the link. This is to test the race condition // when creating files. Defaults to false. bool TEST_SYMLINK_ALTERNATE = false; static int ORIG_DIR = -1; void switch_symlink_hook(void) { if (--TEST_SYMLINK_COUNTDOWN <= 0) { if (TEST_SYMLINK_COUNTDOWN == 0 || (TEST_SYMLINK_ALTERNATE && (TEST_SYMLINK_COUNTDOWN & 1))) { rmdir(TEST_SYMLINK_NAME); unlink(TEST_SYMLINK_NAME); } if (TEST_SYMLINK_COUNTDOWN == 0 || (TEST_SYMLINK_ALTERNATE && !(TEST_SYMLINK_COUNTDOWN & 1))) { assert_int_equal(symlink(TEST_SYMLINK_TARGET, TEST_SYMLINK_NAME), 0); // If we already are root, we must force the link to be non-root, // otherwise the test may have no purpose. if (getuid() == 0) { // 100 exists in most installations, but it doesn't really matter. assert_int_equal(lchown(TEST_SYMLINK_NAME, 100, 100), 0); } } } } static void complain_missing_sudo(const char *function) { printf("WARNING!!! %s will not run without root privileges.\n" "Tried using sudo with no luck.\n", function); } static void chdir_or_exit(const char *path) { if (chdir(path) < 0) { // Don't risk writing into folders we shouldn't. Just bail. exit(EXIT_FAILURE); } } static void save_test_dir(void) { ORIG_DIR = open(".", O_RDONLY); assert_true(ORIG_DIR >= 0); } static void close_test_dir(void) { close(ORIG_DIR); } static void clear_tempfiles(void) { unlink(TEMP_DIR "/" TEST_FILE); unlink(TEMP_DIR "/" TEST_LINK); unlink(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE); unlink(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE); rmdir(TEMP_DIR "/" TEST_SUBSUBDIR); rmdir(TEMP_DIR "/" TEST_SUBDIR); rmdir(TEMP_DIR); } static void setup_tempfiles(void) { clear_tempfiles(); mkdir(TEMP_DIR, 0755); chdir_or_exit(TEMP_DIR); mkdir(TEST_SUBDIR, 0755); mkdir(TEST_SUBSUBDIR, 0755); int fd = open(TEMP_DIR "/" TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644); int result = write(fd, TEST_STRING, strlen(TEST_STRING)); close(fd); fd = open(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644); result = write(fd, TEST_SUBSTRING, strlen(TEST_SUBSTRING)); close(fd); fd = open(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0644); result = write(fd, TEST_SUBSUBSTRING, strlen(TEST_SUBSUBSTRING)); close(fd); if (getuid() == 0) { // 100 exists in most installations, but it doesn't really matter. result = chown(TEMP_DIR "/" TEST_FILE, 100, 100); result = chown(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE, 100, 100); result = chown(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, 100, 100); result = chown(TEMP_DIR "/" TEST_SUBDIR, 100, 100); result = chown(TEMP_DIR "/" TEST_SUBSUBDIR, 100, 100); } (void)result; TEST_SYMLINK_ALTERNATE = false; } static void return_to_test_dir(void) { if (fchdir(ORIG_DIR) < 0) { // Don't risk writing into folders we shouldn't. Just bail. exit(EXIT_FAILURE); } } static void check_contents(int fd, const char *str) { char buf[strlen(str) + 1]; assert_int_equal(read(fd, buf, strlen(str)), strlen(str)); buf[strlen(str)] = '\0'; assert_string_equal(buf, str); } static void test_safe_open_currentdir(void) { setup_tempfiles(); int fd; assert_true((fd = safe_open(TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_STRING); close(fd); return_to_test_dir(); } static void test_safe_open_subdir(void) { setup_tempfiles(); int fd; assert_true((fd = safe_open(TEST_SUBDIR "/" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_subsubdir(void) { setup_tempfiles(); int fd; assert_true((fd = safe_open(TEST_SUBSUBDIR "/" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_updir(void) { setup_tempfiles(); chdir_or_exit(TEST_SUBDIR); int fd; assert_true((fd = safe_open("../" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_STRING); close(fd); return_to_test_dir(); } static void test_safe_open_upupdir(void) { setup_tempfiles(); chdir_or_exit(TEST_SUBSUBDIR); int fd; assert_true((fd = safe_open("../../" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_STRING); close(fd); return_to_test_dir(); } static void test_safe_open_generic_relative_dir(void) { setup_tempfiles(); int fd; assert_true((fd = safe_open(TEST_SUBSUBDIR "/../" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_generic_absolute_dir(void) { setup_tempfiles(); int fd; assert_true((fd = safe_open(TEMP_DIR "/" TEST_SUBDIR "/../" TEST_SUBSUBDIR "/../" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_extra_slashes_relative(void) { setup_tempfiles(); int fd; assert_true((fd = safe_open(TEST_SUBSUBDIR "//..////" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_extra_slashes_absolute(void) { setup_tempfiles(); chdir_or_exit(TEST_SUBSUBDIR); int fd; assert_true((fd = safe_open("/" TEMP_DIR "/" TEST_SUBDIR "//..//" TEST_SUBSUBDIR "/..//" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_unsafe_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = "/etc/passwd"; switch_symlink_hook(); assert_true(safe_open(TEMP_DIR "/" TEST_LINK, O_RDONLY) < 0); assert_int_equal(errno, ENOLINK); return_to_test_dir(); } static void test_safe_open_safe_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_FILE; switch_symlink_hook(); int fd; assert_true((fd = safe_open(TEMP_DIR "/" TEST_LINK, O_RDONLY)) >= 0); check_contents(fd, TEST_STRING); close(fd); return_to_test_dir(); } static void test_safe_open_unsafe_inserted_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = "/etc/passwd"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open(TEST_LINK, O_RDONLY) < 0); assert_int_equal(errno, ENOENT); return_to_test_dir(); } static void test_safe_open_safe_inserted_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open(TEST_LINK, O_RDONLY) < 0); assert_int_equal(errno, ENOENT); return_to_test_dir(); } static void test_safe_open_unsafe_switched_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = "/etc/passwd"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open(TEST_FILE, O_RDONLY) < 0); assert_int_equal(errno, ENOLINK); return_to_test_dir(); } static void test_safe_open_safe_switched_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 3; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); int fd; assert_true((fd = safe_open(TEMP_DIR "/" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_unsafe_dir_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = "/etc"; switch_symlink_hook(); assert_true(safe_open(TEMP_DIR "/" TEST_LINK "/passwd", O_RDONLY) < 0); assert_int_equal(errno, ENOLINK); return_to_test_dir(); } static void test_safe_open_safe_dir_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEST_SUBDIR; switch_symlink_hook(); int fd; assert_true((fd = safe_open(TEST_LINK "/" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_unsafe_inserted_dir_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = "/etc"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open(TEST_LINK "/passwd", O_RDONLY) < 0); assert_int_equal(errno, ENOENT); return_to_test_dir(); } static void test_safe_open_safe_inserted_dir_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEST_SUBDIR; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open(TEST_LINK "/" TEST_FILE, O_RDONLY) < 0); assert_int_equal(errno, ENOENT); return_to_test_dir(); } static void test_safe_open_unsafe_switched_dir_symlink(void) { setup_tempfiles(); assert_int_equal(mkdir(TEMP_DIR "/" TEST_LINK, 0755), 0); if (getuid() == 0) { assert_int_equal(chown(TEMP_DIR "/" TEST_LINK, 100, 100), 0); } TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = "/etc"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open(TEST_LINK "/passwd", O_RDONLY) < 0); assert_int_equal(errno, ENOLINK); return_to_test_dir(); } static void test_safe_open_safe_switched_dir_symlink(void) { setup_tempfiles(); assert_int_equal(mkdir(TEMP_DIR "/" TEST_LINK, 0755), 0); if (getuid() == 0) { assert_int_equal(chown(TEMP_DIR "/" TEST_LINK, 100, 100), 0); } TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEST_SUBDIR; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); int fd; assert_true((fd = safe_open(TEST_LINK "/" TEST_FILE, O_RDONLY)) >= 0); check_contents(fd, TEST_SUBSTRING); close(fd); return_to_test_dir(); } static void test_safe_open_create_safe_inserted_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); int fd = safe_open_create_perms( TEST_LINK, (O_RDONLY | O_CREAT), CF_PERMS_SHARED); assert_true(fd >= 0); check_contents(fd, TEST_STRING); close(fd); return_to_test_dir(); } static void test_safe_open_create_alternating_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_ALTERNATE = true; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open_create_perms(TEST_LINK, O_RDONLY | O_CREAT, CF_PERMS_SHARED) < 0); assert_int_equal(errno, EACCES); return_to_test_dir(); } static void test_safe_open_create_unsafe_switched_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = "/etc/passwd"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open_create_perms(TEST_FILE, O_RDONLY | O_CREAT, CF_PERMS_SHARED) < 0); assert_int_equal(errno, ENOLINK); return_to_test_dir(); } static void test_safe_open_create_switched_dangling_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = "/etc/file-that-for-sure-does-not-exist"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open_create_perms(TEST_FILE, O_RDONLY | O_CREAT, CF_PERMS_SHARED) < 0); assert_int_equal(errno, EACCES); return_to_test_dir(); } static void test_safe_open_create_switched_dangling_symlink_exclusively(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = "/etc/file-that-for-sure-does-not-exist"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open_create_perms(TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, CF_PERMS_SHARED) < 0); assert_int_equal(errno, EEXIST); return_to_test_dir(); } static void test_safe_open_create_dangling_symlink_exclusively(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = "/etc/file-that-for-sure-does-not-exist"; switch_symlink_hook(); assert_true(safe_open_create_perms(TEST_FILE, O_WRONLY | O_CREAT | O_EXCL, CF_PERMS_SHARED) < 0); assert_int_equal(errno, EEXIST); return_to_test_dir(); } static void test_safe_open_switched_dangling_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = "/etc/file-that-for-sure-does-not-exist"; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_true(safe_open(TEST_FILE, O_RDONLY) < 0); assert_int_equal(errno, ENOENT); return_to_test_dir(); } static void test_safe_open_root(void) { int fd; struct stat statbuf; assert_true((fd = safe_open("/", O_RDONLY)) >= 0); assert_int_equal(fchdir(fd), 0); assert_int_equal(stat("etc", &statbuf), 0); close(fd); return_to_test_dir(); } static void test_safe_open_ending_slashes(void) { setup_tempfiles(); int fd; // Whether a regular file with ending slash fails to open is platform dependent, // so should be the same as open(). fd = open(TEMP_DIR "/" TEST_FILE "///", O_RDONLY); bool ending_file_slash_ok; if (fd >= 0) { close(fd); ending_file_slash_ok = true; } else { ending_file_slash_ok = false; } fd = safe_open(TEMP_DIR "/" TEST_FILE "///", O_RDONLY); assert_true(ending_file_slash_ok ? (fd >= 0) : (fd < 0)); if (fd >= 0) { close(fd); } else { assert_int_equal(errno, ENOTDIR); } assert_true((fd = safe_open(TEMP_DIR "/", O_RDONLY)) >= 0); close(fd); return_to_test_dir(); } static void test_safe_open_null(void) { setup_tempfiles(); int fd; assert_false((fd = safe_open(NULL, O_RDONLY)) >= 0); assert_int_equal(errno, EINVAL); return_to_test_dir(); } static void test_safe_open_empty(void) { setup_tempfiles(); int fd; assert_false((fd = safe_open("", O_RDONLY)) >= 0); assert_int_equal(errno, ENOENT); return_to_test_dir(); } /* *********** HELPERS ********************************************* */ static size_t GetFileSize(const char *filename) { struct stat statbuf; int st_ret = lstat(filename, &statbuf); assert_int_not_equal(st_ret, -1); return (size_t) statbuf.st_size; } static void assert_file_not_exists(const char *filename) { int acc_ret = access(filename, F_OK); assert_int_equal(acc_ret, -1); assert_int_equal(errno, ENOENT); } static void create_test_file(bool empty) { unlink(TEST_FILE); int fd = open(TEST_FILE, O_WRONLY|O_CREAT, 0644); assert_int_not_equal(fd, -1); if (!empty) { ssize_t w_ret = write(fd, TEST_STRING, strlen(TEST_STRING)); assert_int_equal(w_ret, strlen(TEST_STRING)); } int cl_ret = close(fd); assert_int_not_equal(cl_ret, -1); assert_int_equal(GetFileSize(TEST_FILE), empty ? 0 : strlen(TEST_STRING)); } /* ****************************************************************** */ /* Make sure that opening a file with O_TRUNC always truncates it, even if * opening is tried several times (there is a loop in the code that resets the * "trunc" flag on retry, and this test simulates retrying by changing the * file in the middle of the operation). */ static void test_safe_open_TRUNC_safe_switched_symlink(void) { setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 3; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); int fd = safe_open(TEMP_DIR "/" TEST_FILE, O_WRONLY | O_TRUNC); assert_int_not_equal(fd, -1); int cl_ret = close(fd); assert_int_not_equal(cl_ret, -1); size_t link_target_size = GetFileSize(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE); /* TRUNCATION SHOULD HAVE HAPPENED. */ assert_int_equal(link_target_size, 0); return_to_test_dir(); } static void test_safe_open_TRUNC_unsafe_switched_symlink(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 2; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); /* Since this test runs as root, we simulate an attack where the user * overwrites the root-owned file with a symlink. The symlink target must * *not* be truncated. */ /* 1. target is owned by root */ assert_int_equal(chown(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE, 0, 0), 0); /* 2. TEST, but with a user-owned symlink being injected * in place of the file. */ int fd = safe_open(TEMP_DIR "/" TEST_FILE, O_WRONLY | O_TRUNC); assert_int_equal(fd, -1); size_t link_target_size = GetFileSize(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE); /* TRUNCATION MUST NOT HAPPEN. */ assert_int_not_equal(link_target_size, 0); return_to_test_dir(); } static void test_safe_open_TRUNC_existing_nonempty(void) { setup_tempfiles(); create_test_file(false); /* TEST: O_TRUNC */ int fd = safe_open(TEST_FILE, O_WRONLY | O_TRUNC); assert_int_not_equal(fd, -1); int cl_ret = close(fd); assert_int_not_equal(cl_ret, -1); assert_int_equal(GetFileSize(TEST_FILE), 0); return_to_test_dir(); } static void test_safe_open_TRUNC_existing_empty(void) { setup_tempfiles(); create_test_file(true); /* TEST: O_TRUNC */ int fd = safe_open(TEST_FILE, O_WRONLY | O_TRUNC); assert_int_not_equal(fd, -1); int cl_ret = close(fd); assert_int_not_equal(cl_ret, -1); assert_int_equal(GetFileSize(TEST_FILE), 0); return_to_test_dir(); } static void test_safe_open_TRUNC_nonexisting(void) { setup_tempfiles(); unlink(TEST_FILE); /* TEST: O_TRUNC */ int fd = safe_open(TEST_FILE, O_WRONLY | O_TRUNC); assert_int_equal(fd, -1); assert_int_equal(errno, ENOENT); assert_file_not_exists(TEST_FILE); return_to_test_dir(); } static void test_safe_open_CREAT_TRUNC_existing_nonempty(void) { setup_tempfiles(); create_test_file(false); /* TEST: O_CREAT | O_TRUNC */ int fd = safe_open(TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC); assert_int_not_equal(fd, -1); int cl_ret = close(fd); assert_int_not_equal(cl_ret, -1); assert_int_equal(GetFileSize(TEST_FILE), 0); return_to_test_dir(); } static void test_safe_open_CREAT_TRUNC_existing_empty(void) { setup_tempfiles(); create_test_file(true); /* TEST: O_CREAT | O_TRUNC */ int fd = safe_open(TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC); assert_int_not_equal(fd, -1); int cl_ret = close(fd); assert_int_not_equal(cl_ret, -1); assert_int_equal(GetFileSize(TEST_FILE), 0); return_to_test_dir(); } static void test_safe_open_CREAT_TRUNC_nonexisting(void) { setup_tempfiles(); unlink(TEST_FILE); /* TEST: O_TRUNC */ int fd = safe_open(TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC); assert_int_not_equal(fd, -1); int cl_ret = close(fd); assert_int_not_equal(cl_ret, -1); assert_int_equal(GetFileSize(TEST_FILE), 0); return_to_test_dir(); } static void test_safe_fopen(void) { setup_tempfiles(); FILE *fptr; char buf = 'a'; assert_true(fptr = safe_fopen(TEST_FILE, "r")); assert_int_equal(fread(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); assert_int_not_equal(fwrite(&buf, 1, 1, fptr), 1); assert_true(ferror(fptr)); clearerr(fptr); fclose(fptr); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "a", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_true(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); assert_true(fptr = safe_fopen(TEST_FILE, "r+")); assert_int_equal(fread(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "a+", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "w", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_true(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "w+", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); unlink(TEST_FILE); assert_false(fptr = safe_fopen(TEST_FILE, "r")); unlink(TEST_FILE); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "a", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_true(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); unlink(TEST_FILE); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "w", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_true(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); unlink(TEST_FILE); assert_false(fptr = safe_fopen(TEST_FILE, "r+")); unlink(TEST_FILE); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "a+", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); unlink(TEST_FILE); assert_true(fptr = safe_fopen_create_perms(TEST_FILE, "w+", CF_PERMS_DEFAULT)); assert_int_not_equal(fread(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); assert_int_equal(fwrite(&buf, 1, 1, fptr), 1); assert_false(ferror(fptr)); clearerr(fptr); fclose(fptr); return_to_test_dir(); } static void test_safe_chown_plain_file(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(chown(TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_chown(TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_chown_relative_file(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(chown(TEST_SUBSUBDIR "/" TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_chown(TEST_SUBSUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_chown_absolute_file(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(chown(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_chown(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_chown_file_extra_slashes(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(chown("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, 100, 100), 0); assert_int_equal(stat("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_chown("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, 0, 0), 0); assert_int_equal(stat("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_chown_plain_directory(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(chown(TEST_SUBDIR, 100, 100), 0); assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_chown(TEST_SUBDIR, 0, 0), 0); assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_chown_unsafe_link(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_int_equal(chown(TEST_SUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); assert_int_equal(safe_chown(TEST_FILE, 100, 100), -1); assert_int_equal(errno, ENOLINK); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_lchown_plain_file(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(lchown(TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_lchown(TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_lchown_relative_file(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(lchown(TEST_SUBSUBDIR "/" TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_lchown(TEST_SUBSUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_lchown_absolute_file(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(lchown(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_lchown(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEMP_DIR "/" TEST_SUBSUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_lchown_file_extra_slashes(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(lchown("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, 100, 100), 0); assert_int_equal(stat("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_lchown("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, 0, 0), 0); assert_int_equal(stat("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_lchown_plain_directory(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; assert_int_equal(lchown(TEST_SUBDIR, 100, 100), 0); assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_lchown(TEST_SUBDIR, 0, 0), 0); assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_lchown_unsafe_link(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_int_equal(lchown(TEST_SUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); // Unsafe links should succeed, because we are operating on the *link*, not the target. assert_int_equal(safe_lchown(TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); return_to_test_dir(); } static void test_safe_lchown_unsafe_link_to_directory(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR; switch_symlink_hook(); assert_int_equal(lchown(TEST_SUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); assert_int_equal(lchown(TEST_SUBDIR, 0, 0), 0); assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0); assert_int_equal(statbuf.st_uid, 0); assert_int_equal(statbuf.st_gid, 0); assert_int_equal(safe_lchown(TEST_LINK "/" TEST_FILE, 100, 100), -1); assert_int_equal(errno, ENOLINK); assert_int_equal(lchown(TEST_SUBDIR "/" TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(lchown(TEST_SUBDIR, 100, 100), 0); assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); assert_int_equal(safe_lchown(TEST_LINK "/" TEST_FILE, 100, 100), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_uid, 100); assert_int_equal(statbuf.st_gid, 100); return_to_test_dir(); } static void test_safe_chmod_plain_file(void) { setup_tempfiles(); struct stat statbuf; assert_int_equal(chmod(TEST_FILE, 0777), 0); assert_int_equal(stat(TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod(TEST_FILE, 0644), 0); assert_int_equal(stat(TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0644); return_to_test_dir(); } static void test_safe_chmod_relative_file(void) { setup_tempfiles(); struct stat statbuf; assert_int_equal(chmod(TEST_SUBDIR "/" TEST_FILE, 0777), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod(TEST_SUBDIR "/" TEST_FILE, 0644), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0644); return_to_test_dir(); } static void test_safe_chmod_absolute_file(void) { setup_tempfiles(); struct stat statbuf; assert_int_equal(chmod(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE, 0777), 0); assert_int_equal(stat(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE, 0644), 0); assert_int_equal(stat(TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0644); return_to_test_dir(); } static void test_safe_chmod_extra_slashes(void) { setup_tempfiles(); struct stat statbuf; assert_int_equal(chmod("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, 0777), 0); assert_int_equal(stat("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, 0644), 0); assert_int_equal(stat("/" TEMP_DIR "///" TEST_SUBDIR "//" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0644); return_to_test_dir(); } static void test_safe_chmod_unsafe_link(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); struct stat statbuf; TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE; // Not calling this function will call it right in the middle of the // safe_open() instead. //switch_symlink_hook(); assert_int_equal(chown(TEST_SUBDIR "/" TEST_FILE, 0, 0), 0); assert_int_equal(chmod(TEST_SUBDIR "/" TEST_FILE, 0777), 0); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); assert_int_equal(safe_chmod(TEST_FILE, 0644), -1); assert_int_equal(errno, ENOLINK); assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0); assert_int_equal(statbuf.st_mode & 0777, 0777); return_to_test_dir(); } static void test_safe_creat_exists(void) { setup_tempfiles(); int fd; struct stat buf; assert_true((fd = safe_creat(TEST_FILE, 0644)) >= 0); assert_int_equal(fstat(fd, &buf), 0); assert_int_equal(buf.st_size, 0); close(fd); return_to_test_dir(); } static void test_safe_creat_doesnt_exist(void) { setup_tempfiles(); int fd; struct stat buf; unlink(TEST_FILE); assert_true((fd = safe_creat(TEST_FILE, 0644)) >= 0); assert_int_equal(fstat(fd, &buf), 0); assert_int_equal(buf.st_size, 0); close(fd); return_to_test_dir(); } static void test_symlink_loop(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_FILE; switch_symlink_hook(); assert_int_equal(safe_open(TEST_FILE, O_RDONLY), -1); assert_int_equal(errno, ELOOP); assert_int_equal(safe_chown(TEST_FILE, 100, 100), -1); assert_int_equal(errno, ELOOP); assert_int_equal(safe_chmod(TEST_FILE, 0644), -1); assert_int_equal(errno, ELOOP); assert_int_equal(safe_lchown(TEST_FILE, 100, 100), 0); return_to_test_dir(); } static void test_safe_chmod_chown_fifos(void) { if (getuid() != 0) { complain_missing_sudo(__FUNCTION__); return; } setup_tempfiles(); TEST_SYMLINK_COUNTDOWN = 1; TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE; TEST_SYMLINK_TARGET = TEST_SUBDIR "/" TEST_FILE; switch_symlink_hook(); unlink(TEST_SUBDIR "/" TEST_FILE); assert_int_equal(mkfifo(TEST_SUBDIR "/" TEST_FILE, 0644), 0); // Link owner != target owner assert_int_equal(safe_chown(TEST_FILE, 100, 100), -1); assert_int_equal(errno, ENOLINK); assert_int_equal(safe_chmod(TEST_FILE, 0755), -1); assert_int_equal(errno, ENOLINK); assert_int_equal(safe_chown(TEST_SUBDIR "/" TEST_FILE, 100, 100), 0); // Now the owner is correct assert_int_equal(safe_chmod(TEST_FILE, 0755), 0); assert_int_equal(safe_chown(TEST_FILE, 0, 0), 0); assert_int_equal(safe_chmod(TEST_SUBDIR "/" TEST_FILE, 0644), 0); return_to_test_dir(); } static void test_file_can_open(void) { setup_tempfiles(); assert_true(FileCanOpen(TEST_FILE, "r")); assert_false(FileCanOpen("no_such_file", "r")); return_to_test_dir(); } static void test_file_copy(void) { setup_tempfiles(); assert_true(File_Copy(TEST_FILE, "new_file")); int fd = safe_open("new_file", O_RDONLY); assert_true(fd >= 0); check_contents(fd, TEST_STRING); close(fd); assert_int_equal(unlink("new_file"), 0); return_to_test_dir(); } static void test_file_copy_to_dir(void) { setup_tempfiles(); assert_false(File_CopyToDir(TEST_FILE, "no/such/dir/")); assert_true(File_CopyToDir(TEST_FILE, TEST_SUBDIR "/")); const char * new_path = TEST_SUBDIR "/" TEST_FILE; int fd = safe_open(new_path, O_RDONLY); assert_true(fd >= 0); check_contents(fd, TEST_STRING); close(fd); assert_int_equal(unlink(new_path), 0); return_to_test_dir(); } static void test_file_read(void) { setup_tempfiles(); { bool truncated = true; Writer *w = FileRead(TEST_FILE, 1024, &truncated); assert_false(truncated); char *data = StringWriterClose(w); assert_string_equal(TEST_STRING, data); free(data); } { bool truncated = false; Writer *w = FileRead(TEST_FILE, 4, &truncated); assert_true(truncated); char *data = StringWriterClose(w); assert_string_equal("BLUE", data); free(data); } return_to_test_dir(); } static void test_read_file_stream_to_buffer(void) { setup_tempfiles(); { const size_t length = strlen(TEST_STRING); char buf[1024] = {0}; FILE *const file = safe_fopen(TEST_FILE, "r"); assert_true(file != NULL); const ssize_t bytes_read = ReadFileStreamToBuffer(file, length, buf); fclose(file); assert_int_equal(bytes_read, length); assert_string_equal(TEST_STRING, buf); } return_to_test_dir(); } static void test_full_read_write(void) { setup_tempfiles(); // Write test string to new_file, don't include NUL-byte int fd = safe_open_create_perms("new_file", O_WRONLY | O_CREAT, 0777); const size_t length = strlen(TEST_STRING); assert_int_equal(FullWrite(fd, TEST_STRING, length), length); assert_int_equal(close(fd), 0); { // Read the same length back from file: fd = safe_open("new_file", O_RDONLY); char buf[length]; assert_int_equal(FullRead(fd, buf, length), length); assert_true(memcmp(buf, TEST_STRING, length) == 0); assert_int_equal(close(fd), 0); } { // Try to read twice as much: const size_t twice = length * 2; fd = safe_open("new_file", O_RDONLY); char buf[length]; // ASAN should panic if we overflow assert_int_equal(FullRead(fd, buf, twice), length); assert_true(memcmp(buf, TEST_STRING, length) == 0); assert_int_equal(close(fd), 0); } { // Read about half of the file: const size_t half = length / 2; fd = safe_open("new_file", O_RDONLY); char buf[half]; assert_int_equal(FullRead(fd, buf, half), half); assert_true(memcmp(buf, TEST_STRING, half) == 0); assert_int_equal(close(fd), 0); } assert_int_equal(unlink("new_file"), 0); return_to_test_dir(); } static void test_is_dir_real(void) { setup_tempfiles(); assert_true(IsDirReal("/")); assert_true(IsDirReal("..")); assert_false(IsDirReal(TEST_FILE)); assert_false(IsDirReal("no/such/dir/")); // TODO: Test that IsDirReal() returns false for symlinks return_to_test_dir(); } static void test_file_locking(void) { /* see file_lock_test.c for some more test cases */ setup_tempfiles(); /** TEST CASE 1 -- open, nowait excl. lock, unlock, close **/ int fd = open(TEMP_DIR "/" TEST_FILE, O_CREAT | O_RDWR, 0644); FileLock lock = EMPTY_FILE_LOCK; lock.fd = fd; /* lock without waiting */ assert_int_equal(ExclusiveFileLock(&lock, false), 0); /* FD should not be changed */ assert_int_equal(lock.fd, fd); /* unlock, but keep the FD open */ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* should be able to close */ assert_int_equal(close(lock.fd), 0); /** TEST CASE 2 -- open, wait excl. lock, unlock+close **/ fd = open(TEMP_DIR "/" TEST_FILE, O_CREAT | O_RDWR, 0644); lock.fd = fd; /* lock trying to wait */ assert_int_equal(ExclusiveFileLock(&lock, true), 0); /* FD should not be changed */ assert_int_equal(lock.fd, fd); /* try to lock again without waiting (we already have the lock so it's a * no-op)*/ assert_int_equal(ExclusiveFileLock(&lock, false), 0); /* unlock and close the FD */ assert_int_equal(ExclusiveFileUnlock(&lock, true), 0); /* should be already closed */ assert_int_equal(close(lock.fd), -1); /* FD should be reset to -1 */ assert_int_equal(lock.fd, -1); /** TEST CASE 3 -- open, wait shared lock, wait excl. lock, unlock, close **/ fd = open(TEMP_DIR "/" TEST_FILE, O_CREAT | O_RDWR, 0644); lock.fd = fd; /* SHARED lock trying to wait */ assert_int_equal(SharedFileLock(&lock, true), 0); /* FD should not be changed */ assert_int_equal(lock.fd, fd); /* we are holding a shared lock so WE should be able to get an exclusive * lock */ assert_true(ExclusiveFileLockCheck(&lock)); /* upgrade the lock to an exclusive one */ assert_int_equal(ExclusiveFileLock(&lock, true), 0); /* unlock, but keep the FD open */ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* should be able to close the FD */ assert_int_equal(close(lock.fd), 0); /** TEST CASE 4 -- open, unlock, wait excl. lock, unlock, excl. lock again, * unlock+close **/ fd = open(TEMP_DIR "/" TEST_FILE, O_CREAT | O_RDWR, 0644); lock.fd = fd; /* unlock, but keep the FD open (we are NOT holding the lock so this should * be no-op)*/ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* FD should not be changed */ assert_int_equal(lock.fd, fd); /* we should be able to get an exclusive lock */ assert_true(ExclusiveFileLockCheck(&lock)); /* get an exclusive lock */ assert_int_equal(ExclusiveFileLock(&lock, true), 0); /* unlock, but keep the FD open */ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* get an exclusive lock again */ assert_int_equal(ExclusiveFileLock(&lock, true), 0); /* unlock and close the FD */ assert_int_equal(ExclusiveFileUnlock(&lock, true), 0); return_to_test_dir(); } static void test_file_locking_with_path(void) { /* see file_lock_test.c for some more test cases */ setup_tempfiles(); FileLock lock = EMPTY_FILE_LOCK; /** TEST CASE 1 -- nowait excl. lock, unlock, close **/ /* lock without waiting */ assert_int_equal(ExclusiveFileLockPath(&lock, TEMP_DIR "/" TEST_FILE, false), 0); /* FD should be changed */ assert_int_not_equal(lock.fd, -1); /* unlock, but keep the FD open */ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* should be able to close */ assert_int_equal(close(lock.fd), 0); lock.fd = -1; /** TEST CASE 2 -- open, wait excl. lock, unlock+close **/ /* lock trying to wait */ assert_int_equal(ExclusiveFileLockPath(&lock, TEMP_DIR "/" TEST_FILE, true), 0); /* FD should be changed */ assert_int_not_equal(lock.fd, -1); /* try to lock again without waiting (we already have the lock so it's a * no-op)*/ assert_int_equal(ExclusiveFileLock(&lock, false), 0); /* unlock and close the FD */ assert_int_equal(ExclusiveFileUnlock(&lock, true), 0); /* should be already closed */ assert_int_equal(close(lock.fd), -1); /* FD should be reset to -1 */ assert_int_equal(lock.fd, -1); /** TEST CASE 3 -- open, wait shared lock, wait excl. lock, unlock, close **/ /* SHARED lock trying to wait */ assert_int_equal(SharedFileLockPath(&lock, TEMP_DIR "/" TEST_FILE, true), 0); /* FD should be changed */ assert_int_not_equal(lock.fd, -1); /* we are holding a shared lock so WE should be able to get an exclusive * lock */ assert_true(ExclusiveFileLockCheck(&lock)); /* SharedFileLockPath opens the file as RDONLY. For an exclusive lock, we * need RDWR. */ assert_int_equal(ExclusiveFileLock(&lock, true), -1); /* upgrade the lock to an exclusive one */ FileLock lock2 = EMPTY_FILE_LOCK; assert_int_equal(ExclusiveFileLockPath(&lock2, TEMP_DIR "/" TEST_FILE, true), 0); /* unlock, but keep the FD open */ assert_int_equal(ExclusiveFileUnlock(&lock, false), 0); /* should be able to close both FDs */ assert_int_equal(close(lock.fd), 0); lock.fd = -1; assert_int_equal(close(lock2.fd), 0); lock2.fd = -1; /* TEST CASE 4 -- try to use lock file in non-existing directory */ assert_int_equal(ExclusiveFileLockPath(&lock, "non-existing-dir/" TEST_FILE, true), -2); return_to_test_dir(); } static void try_gaining_root_privileges(ARG_UNUSED int argc, char **argv) { if (system("sudo -n /bin/true") == 0) { execlp("sudo", "sudo", "-n", argv[0], NULL); // Should never get here. } } int main(int argc, char **argv) { if (getuid() != 0) { try_gaining_root_privileges(argc, argv); } PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(save_test_dir), unit_test(test_safe_open_currentdir), unit_test(test_safe_open_subdir), unit_test(test_safe_open_subsubdir), unit_test(test_safe_open_updir), unit_test(test_safe_open_upupdir), unit_test(test_safe_open_generic_relative_dir), unit_test(test_safe_open_generic_absolute_dir), unit_test(test_safe_open_extra_slashes_relative), unit_test(test_safe_open_extra_slashes_absolute), unit_test(test_safe_open_unsafe_symlink), unit_test(test_safe_open_safe_symlink), unit_test(test_safe_open_unsafe_inserted_symlink), unit_test(test_safe_open_safe_inserted_symlink), unit_test(test_safe_open_unsafe_switched_symlink), unit_test(test_safe_open_safe_switched_symlink), unit_test(test_safe_open_unsafe_dir_symlink), unit_test(test_safe_open_safe_dir_symlink), unit_test(test_safe_open_unsafe_inserted_dir_symlink), unit_test(test_safe_open_safe_inserted_dir_symlink), unit_test(test_safe_open_unsafe_switched_dir_symlink), unit_test(test_safe_open_safe_switched_dir_symlink), unit_test(test_safe_open_create_safe_inserted_symlink), unit_test(test_safe_open_create_alternating_symlink), unit_test(test_safe_open_create_unsafe_switched_symlink), unit_test(test_safe_open_create_switched_dangling_symlink), unit_test(test_safe_open_create_switched_dangling_symlink_exclusively), unit_test(test_safe_open_create_dangling_symlink_exclusively), unit_test(test_safe_open_switched_dangling_symlink), unit_test(test_safe_open_root), unit_test(test_safe_open_ending_slashes), unit_test(test_safe_open_null), unit_test(test_safe_open_empty), unit_test(test_safe_open_TRUNC_safe_switched_symlink), unit_test(test_safe_open_TRUNC_unsafe_switched_symlink), unit_test(test_safe_open_TRUNC_existing_nonempty), unit_test(test_safe_open_TRUNC_existing_empty), unit_test(test_safe_open_TRUNC_nonexisting), unit_test(test_safe_open_CREAT_TRUNC_existing_nonempty), unit_test(test_safe_open_CREAT_TRUNC_existing_empty), unit_test(test_safe_open_CREAT_TRUNC_nonexisting), unit_test(test_safe_fopen), unit_test(test_safe_chown_plain_file), unit_test(test_safe_chown_relative_file), unit_test(test_safe_chown_absolute_file), unit_test(test_safe_chown_file_extra_slashes), unit_test(test_safe_chown_plain_directory), unit_test(test_safe_chown_unsafe_link), unit_test(test_safe_lchown_plain_file), unit_test(test_safe_lchown_relative_file), unit_test(test_safe_lchown_absolute_file), unit_test(test_safe_lchown_file_extra_slashes), unit_test(test_safe_lchown_plain_directory), unit_test(test_safe_lchown_unsafe_link), unit_test(test_safe_lchown_unsafe_link_to_directory), unit_test(test_safe_chmod_plain_file), unit_test(test_safe_chmod_relative_file), unit_test(test_safe_chmod_absolute_file), unit_test(test_safe_chmod_extra_slashes), unit_test(test_safe_chmod_unsafe_link), unit_test(test_safe_creat_exists), unit_test(test_safe_creat_doesnt_exist), unit_test(test_symlink_loop), unit_test(test_safe_chmod_chown_fifos), unit_test(test_file_can_open), unit_test(test_file_copy), unit_test(test_file_copy_to_dir), unit_test(test_file_read), unit_test(test_read_file_stream_to_buffer), unit_test(test_full_read_write), unit_test(test_is_dir_real), unit_test(test_file_locking), unit_test(test_file_locking_with_path), unit_test(close_test_dir), unit_test(clear_tempfiles), }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/libntech/tests/unit/logging_timestamp_test.c0000644000000000000000000000332415010704254024203 0ustar00rootroot00000000000000#include #include #include #include #ifdef WITH_PCRE2 #define PCRE2_CODE_UNIT_WIDTH 8 #include #endif static void test_timestamp_regex(void) { LoggingSetAgentType("test"); LoggingEnableTimestamps(true); LoggingSetColor(false); fflush(stderr); fflush(stdout); int pipe_fd[2]; assert_int_equal(pipe(pipe_fd), 0); // Duplicate stdout. int duplicate_stdout = dup(1); assert_true(duplicate_stdout >= 0); // Make stderr point to the pipe. assert_int_equal(dup2(pipe_fd[1], 1), 1); Log(LOG_LEVEL_ERR, "Test string"); fputc('\n', stdout); /* Make sure fgets() doesn't hang. */ fflush(stderr); fflush(stdout); // Restore stdout. assert_int_equal(dup2(duplicate_stdout, 1), 1); char buf[CF_BUFSIZE]; FILE *pipe_read_end = fdopen(pipe_fd[0], "r"); assert_true(pipe_read_end != NULL); assert_true(fgets(buf, sizeof(buf), pipe_read_end) != NULL); #ifdef WITH_PCRE2 int err_code; size_t err_offset; pcre2_code *regex = pcre2_compile(LOGGING_TIMESTAMP_REGEX, PCRE2_ZERO_TERMINATED, PCRE2_MULTILINE, &err_code, &err_offset, NULL); assert_true(regex != NULL); pcre2_match_data *md = pcre2_match_data_create(0, NULL); assert_true(pcre2_match(regex, (PCRE2_SPTR) buf, PCRE2_ZERO_TERMINATED, 0, 0, md, NULL) >= 1); pcre2_match_data_free(md); pcre2_code_free(regex); #endif // WITH_PCRE2 fclose(pipe_read_end); close(pipe_fd[0]); close(pipe_fd[1]); close(duplicate_stdout); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_timestamp_regex), }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/unit/ipaddress_test.c0000644000000000000000000007041715010704254022457 0ustar00rootroot00000000000000#include #include #include #include #include #include static void test_ipv4(void) { /* * This test will check the ipv4 parser. We will directly call to it, we will not check * the generic frontend. * Cases to test: * 0.0.0.0 Ok * 255.255.255.255 Ok * 1.1.1.1 Ok * 1.1.1.1:1 Ok * 1.2.3.4 Ok * 5.6.7.8:9 Ok * 10.0.0.9:0 Ok * 10.0.0.10:5308 Ok * 192.168.56.10:65535 Ok * 0 Fail * 0.1 Fail * 0.1.2 Fail * 0:0 Fail * 1.1.1.260 Fail * 1.1.260.1 Fail * 1.260.1.1 Fail * 260.1.1.1 Fail * 260.260.260.260 Fail * 1.1.1.1: Fail * 2.3.4.5:65536 Fail * a.b.c.d Fail */ struct IPV4Address ipv4; memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("0.0.0.0", &ipv4)); assert_int_equal(ipv4.octets[0], 0); assert_int_equal(ipv4.octets[1], 0); assert_int_equal(ipv4.octets[2], 0); assert_int_equal(ipv4.octets[3], 0); assert_int_equal(ipv4.port, 0); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("255.255.255.255", &ipv4)); assert_int_equal(ipv4.octets[0], 255); assert_int_equal(ipv4.octets[1], 255); assert_int_equal(ipv4.octets[2], 255); assert_int_equal(ipv4.octets[3], 255); assert_int_equal(ipv4.port, 0); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("1.1.1.1", &ipv4)); assert_int_equal(ipv4.octets[0], 1); assert_int_equal(ipv4.octets[1], 1); assert_int_equal(ipv4.octets[2], 1); assert_int_equal(ipv4.octets[3], 1); assert_int_equal(ipv4.port, 0); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("1.1.1.1:1", &ipv4)); assert_int_equal(ipv4.octets[0], 1); assert_int_equal(ipv4.octets[1], 1); assert_int_equal(ipv4.octets[2], 1); assert_int_equal(ipv4.octets[3], 1); assert_int_equal(ipv4.port, 1); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("1.2.3.4", &ipv4)); assert_int_equal(ipv4.octets[0], 1); assert_int_equal(ipv4.octets[1], 2); assert_int_equal(ipv4.octets[2], 3); assert_int_equal(ipv4.octets[3], 4); assert_int_equal(ipv4.port, 0); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("5.6.7.8:9", &ipv4)); assert_int_equal(ipv4.octets[0], 5); assert_int_equal(ipv4.octets[1], 6); assert_int_equal(ipv4.octets[2], 7); assert_int_equal(ipv4.octets[3], 8); assert_int_equal(ipv4.port, 9); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("10.0.0.9:0", &ipv4)); assert_int_equal(ipv4.octets[0], 10); assert_int_equal(ipv4.octets[1], 0); assert_int_equal(ipv4.octets[2], 0); assert_int_equal(ipv4.octets[3], 9); assert_int_equal(ipv4.port, 0); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("10.0.0.10:5308", &ipv4)); assert_int_equal(ipv4.octets[0], 10); assert_int_equal(ipv4.octets[1], 0); assert_int_equal(ipv4.octets[2], 0); assert_int_equal(ipv4.octets[3], 10); assert_int_equal(ipv4.port, 5308); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(0, IPV4_parser("192.168.56.10:65535", &ipv4)); assert_int_equal(ipv4.octets[0], 192); assert_int_equal(ipv4.octets[1], 168); assert_int_equal(ipv4.octets[2], 56); assert_int_equal(ipv4.octets[3], 10); assert_int_equal(ipv4.port, 65535); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("0", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("0.1", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("0.1.2", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("0:0", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("1.1.1.260", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("1.1.260.1", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("1.260.1.1", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("260.1.1.1", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("260.260.260.260", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("1.1.1.1:", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("2.3.4.5:65536", &ipv4)); memset(&ipv4, 0, sizeof(struct IPV4Address)); assert_int_equal(-1, IPV4_parser("a.b.c.d", &ipv4)); } static void test_char2hex(void) { /* * Even if this routine is pretty simple, this is a sanity * check. This routine does not detect errors so we only * try valid conversions. * This routine does not expect the '0x' in front of numbers, * so our tests will be: * 0 .. 9 * a .. f * A .. F */ char i = '0'; for (i = '0'; i <= '9'; ++i) assert_int_equal(i - '0', Char2Hex(0, i)); for (i = 'a'; i <= 'f'; ++i) assert_int_equal(i - 'a' + 0x0A, Char2Hex(0, i)); } static void test_ipv6(void) { /* * This test will check the ipv6 parser. We will directly call to it, we will not check * the generic frontend. * Cases to test: * 0000:0000:0000:0000:0000:0000:0000:0000 Ok * 0:0:0:0:0:0:0:0 Ok * a:b:c:d::1 Ok * a:b:c:d:0:1:2:3 Ok * [a::b] Ok * [a:b:c:d:e:f:0:1]:8080 Ok * 0:1:2::4 Ok * 0::2:3:4 Ok * ::3:4 Ok * ::::::: Fail * A:B:C:D:E:F:0:1 Fail */ struct IPV6Address ipv6; memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("0000:0000:0000:0000:0000:0000:0000:0000", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0); assert_int_equal(ipv6.sixteen[1], 0); assert_int_equal(ipv6.sixteen[2], 0); assert_int_equal(ipv6.sixteen[3], 0); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 0); assert_int_equal(ipv6.sixteen[6], 0); assert_int_equal(ipv6.sixteen[7], 0); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("0:0:0:0:0:0:0:0", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0); assert_int_equal(ipv6.sixteen[1], 0); assert_int_equal(ipv6.sixteen[2], 0); assert_int_equal(ipv6.sixteen[3], 0); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 0); assert_int_equal(ipv6.sixteen[6], 0); assert_int_equal(ipv6.sixteen[7], 0); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("a:b:c:d::1", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0x0a); assert_int_equal(ipv6.sixteen[1], 0x0b); assert_int_equal(ipv6.sixteen[2], 0x0c); assert_int_equal(ipv6.sixteen[3], 0x0d); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 0); assert_int_equal(ipv6.sixteen[6], 0); assert_int_equal(ipv6.sixteen[7], 1); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("a:b:c:d:0:1:2:3", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0x0a); assert_int_equal(ipv6.sixteen[1], 0x0b); assert_int_equal(ipv6.sixteen[2], 0x0c); assert_int_equal(ipv6.sixteen[3], 0x0d); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 1); assert_int_equal(ipv6.sixteen[6], 2); assert_int_equal(ipv6.sixteen[7], 3); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("[a::b]", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0x0a); assert_int_equal(ipv6.sixteen[1], 0); assert_int_equal(ipv6.sixteen[2], 0); assert_int_equal(ipv6.sixteen[3], 0); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 0); assert_int_equal(ipv6.sixteen[6], 0); assert_int_equal(ipv6.sixteen[7], 0x0b); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("[a:b:c:d:e:f:0:1]:8080", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0x0a); assert_int_equal(ipv6.sixteen[1], 0x0b); assert_int_equal(ipv6.sixteen[2], 0x0c); assert_int_equal(ipv6.sixteen[3], 0x0d); assert_int_equal(ipv6.sixteen[4], 0x0e); assert_int_equal(ipv6.sixteen[5], 0x0f); assert_int_equal(ipv6.sixteen[6], 0); assert_int_equal(ipv6.sixteen[7], 1); assert_int_equal(ipv6.port, 8080); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("0:1:2::4", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0); assert_int_equal(ipv6.sixteen[1], 1); assert_int_equal(ipv6.sixteen[2], 2); assert_int_equal(ipv6.sixteen[3], 0); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 0); assert_int_equal(ipv6.sixteen[6], 0); assert_int_equal(ipv6.sixteen[7], 4); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("0::2:3:4", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0); assert_int_equal(ipv6.sixteen[1], 0); assert_int_equal(ipv6.sixteen[2], 0); assert_int_equal(ipv6.sixteen[3], 0); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 2); assert_int_equal(ipv6.sixteen[6], 3); assert_int_equal(ipv6.sixteen[7], 4); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(0, IPV6_parser("::3:4", &ipv6)); assert_int_equal(ipv6.sixteen[0], 0); assert_int_equal(ipv6.sixteen[1], 0); assert_int_equal(ipv6.sixteen[2], 0); assert_int_equal(ipv6.sixteen[3], 0); assert_int_equal(ipv6.sixteen[4], 0); assert_int_equal(ipv6.sixteen[5], 0); assert_int_equal(ipv6.sixteen[6], 3); assert_int_equal(ipv6.sixteen[7], 4); assert_int_equal(ipv6.port, 0); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(-1, IPV6_parser(":::::::", &ipv6)); memset(&ipv6, 0, sizeof(struct IPV6Address)); assert_int_equal(-1, IPV6_parser("A:B:C:D:E:F:0:1", &ipv6)); } static void test_generic_interface(void) { /* * This test might seem short, but it is intentional. * All the parsing tests should be implemented directly * on the corresponding parser test. Keep this test as * lean as possible. */ IPAddress *address = NULL; Buffer *buffer = NULL; Buffer *tmp_buffer = NULL; buffer = BufferNew(); assert_true(buffer != NULL); BufferSet(buffer, "127.0.0.1", strlen("127.0.0.1")); address = IPAddressNew(buffer); assert_true(address != NULL); assert_int_equal(IP_ADDRESS_TYPE_IPV4, IPAddressType(address)); tmp_buffer = IPAddressGetAddress(address); assert_string_equal("127.0.0.1", BufferData(tmp_buffer)); DESTROY_AND_NULL(BufferDestroy, tmp_buffer); assert_int_equal(0, IPAddressGetPort(address)); assert_int_equal(0, IPAddressDestroy(&address)); BufferSet(buffer, "127.0.0.1:8080", strlen("127.0.0.1:8080")); address = IPAddressNew(buffer); assert_true(address != NULL); assert_int_equal(IP_ADDRESS_TYPE_IPV4, IPAddressType(address)); tmp_buffer = IPAddressGetAddress(address); assert_string_equal("127.0.0.1", BufferData(tmp_buffer)); DESTROY_AND_NULL(BufferDestroy, tmp_buffer); assert_int_equal(8080, IPAddressGetPort(address)); assert_int_equal(0, IPAddressDestroy(&address)); BufferSet(buffer, "0:1:2:3:4:5:6:7", strlen("0:1:2:3:4:5:6:7")); address = IPAddressNew(buffer); assert_true(address != NULL); assert_int_equal(IP_ADDRESS_TYPE_IPV6, IPAddressType(address)); tmp_buffer = IPAddressGetAddress(address); assert_string_equal("0:1:2:3:4:5:6:7", BufferData(tmp_buffer)); DESTROY_AND_NULL(BufferDestroy, tmp_buffer); assert_int_equal(0, IPAddressGetPort(address)); assert_int_equal(0, IPAddressDestroy(&address)); BufferSet(buffer, "[0:1:2:3:4:5:6:7]:9090", strlen("[0:1:2:3:4:5:6:7]:9090")); address = IPAddressNew(buffer); assert_true(address != NULL); assert_int_equal(IP_ADDRESS_TYPE_IPV6, IPAddressType(address)); tmp_buffer = IPAddressGetAddress(address); assert_string_equal("0:1:2:3:4:5:6:7", BufferData(tmp_buffer)); DESTROY_AND_NULL(BufferDestroy, tmp_buffer); assert_int_equal(9090, IPAddressGetPort(address)); assert_int_equal(0, IPAddressDestroy(&address)); BufferDestroy(buffer); } static void test_ipv4_address_comparison(void) { /* * We test different IPV4 combinations: * 1.1.1.1 vs 1.1.1.1 -> equal * 1.2.3.4 vs 1.1.1.1 -> not equal * 1.2.3.4 vs 1.2.1.1 -> not equal * 1.2.3.4 vs 1.2.3.1 -> not equal * 2.2.3.4 vs 1.2.3.4 -> not equal * 1.2.3.4 vs 1.2.3.4 -> equal * 1.2.3.4 vs NULL -> error * 1.2.3.4 vs 1:2:3:4:5:6:7:8 -> error */ IPAddress *a = NULL; IPAddress *b = NULL; Buffer *bufferA = NULL; Buffer *bufferB = NULL; bufferA = BufferNew(); assert_true(bufferA != NULL); BufferSet(bufferA, "1.1.1.1", strlen("1.1.1.1")); a = IPAddressNew(bufferA); assert_true(a != NULL); bufferB = BufferNew(); assert_true(bufferB != NULL); BufferSet(bufferB, "1.1.1.1", strlen("1.1.1.1")); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_true(IPAddressIsEqual(a, b)); BufferSet(bufferA, "1.2.3.4", strlen("1.2.3.4")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); assert_false(IPAddressIsEqual(a, b)); BufferSet(bufferB, "1.2.1.1", strlen("1.2.1.1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); BufferSet(bufferB, "1.2.3.1", strlen("1.2.3.1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); BufferSet(bufferA, "2.2.3.4", strlen("2.2.3.4")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); BufferSet(bufferB, "1.2.3.4", strlen("1.2.3.4")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); BufferSet(bufferA, "1.2.3.4", strlen("1.2.3.4")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); assert_true(IPAddressIsEqual(a, b)); assert_int_equal(IPAddressIsEqual(a, NULL), -1); assert_int_equal(IPAddressIsEqual(NULL, a), -1); BufferSet(bufferA, "1:2:3:4:5:6:7:8", strlen("1:2:3:4:5:6:7:8")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); assert_int_equal(IPAddressIsEqual(a, b), -1); assert_int_equal(IPAddressIsEqual(b, a), -1); assert_int_equal(IPAddressDestroy(&a), 0); assert_int_equal(IPAddressDestroy(&b), 0); BufferDestroy(bufferA); BufferDestroy(bufferB); } static void test_ipv6_address_comparison(void) { /* * We test different IPV6 combinations: * 1:1:1:1:1:1:1:1 vs 1:1:1:1:1:1:1:1 -> equal * 1:2:3:4:5:6:7:8 vs 1:1:1:1:1:1:1:1 -> not equal * 1:2:3:4:5:6:7:8 vs 1:2:1:1:1:1:1:1 -> not equal * 1:2:3:4:5:6:7:8 vs 1:2:3:1:1:1:1:1 -> not equal * 1:2:3:4:5:6:7:8 vs 1:2:3:4:1:1:1:1 -> not equal * 1:2:3:4:5:6:7:8 vs 1:2:3:4:5:1:1:1 -> not equal * 1:2:3:4:5:6:7:8 vs 1:2:3:4:5:6:1:1 -> not equal * 1:2:3:4:5:6:7:8 vs 1:2:3:4:5:6:7:1 -> not equal * 2:2:3:4:5:6:7:8 vs 1:2:3:4:5:6:7:8 -> not equal * 1:2:3:4:5:6:7:8 vs 1:2:3:4:5:6:7:8 -> equal * Exotic variants * 1:0:0:0:0:0:0:1 vs 1::1 -> equal * 1:1:0:0:0:0:0:1 vs 1::1 -> not equal * 1:1:0:0:0:0:0:1 vs 1:1::1 -> equal * 1:0:0:0:0:0:1:1 vs 1::1:1 -> equal * Error conditions * 1::1:1 vs NULL -> error * 1::1:1 vs 1.2.3.4 -> error */ IPAddress *a = NULL; IPAddress *b = NULL; Buffer *bufferA = NULL; Buffer *bufferB = NULL; bufferA = BufferNew(); assert_true(bufferA != NULL); BufferSet(bufferA, "1:1:1:1:1:1:1:1", strlen("1:1:1:1:1:1:1:1")); a = IPAddressNew(bufferA); assert_true(a != NULL); bufferB = BufferNew(); assert_true(bufferB != NULL); BufferSet(bufferB, "1:1:1:1:1:1:1:1", strlen("1:1:1:1:1:1:1:1")); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_true(IPAddressIsEqual(a, b)); assert_true(bufferA != NULL); BufferSet(bufferA, "1:2:3:4:5:6:7:8", strlen("1:1:1:1:1:1:1:1")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "1:2:1:1:1:1:1:1", strlen("1:2:1:1:1:1:1:1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "1:2:3:1:1:1:1:1", strlen("1:2:3:1:1:1:1:1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "1:2:3:4:1:1:1:1", strlen("1:2:3:4:1:1:1:1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "1:2:3:4:5:1:1:1", strlen("1:2:3:4:5:1:1:1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "1:2:3:4:5:6:1:1", strlen("1:2:3:4:5:6:1:1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "1:2:3:4:5:6:7:1", strlen("1:2:3:4:5:6:7:1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "2:2:3:4:5:6:7:8", strlen("2:2:3:4:5:6:7:8")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferA != NULL); BufferSet(bufferA, "1:0:0:0:0:0:0:1", strlen("1:0:0:0:0:0:0:1")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); assert_true(bufferB != NULL); BufferSet(bufferB, "1::1", strlen("1::1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_true(IPAddressIsEqual(a, b)); assert_true(bufferA != NULL); BufferSet(bufferA, "1:1:0:0:0:0:0:1", strlen("1:1:0:0:0:0:0:1")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); assert_false(IPAddressIsEqual(a, b)); assert_true(bufferB != NULL); BufferSet(bufferB, "1:1::1", strlen("1:1::1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_true(IPAddressIsEqual(a, b)); assert_true(bufferA != NULL); BufferSet(bufferA, "1::1:1", strlen("1::1:1")); assert_int_equal(IPAddressDestroy(&a), 0); a = IPAddressNew(bufferA); assert_true(a != NULL); assert_true(bufferB != NULL); BufferSet(bufferB, "1:0:0:0:0:0:1:1", strlen("1:0:0:0:0:0:1:1")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_true(IPAddressIsEqual(a, b)); assert_int_equal(IPAddressIsEqual(a, NULL), -1); assert_true(bufferB != NULL); BufferSet(bufferB, "1.2.3.4", strlen("1.2.3.4")); assert_int_equal(IPAddressDestroy(&b), 0); b = IPAddressNew(bufferB); assert_true(b != NULL); assert_int_equal(IPAddressIsEqual(a, b), -1); BufferDestroy(bufferA); BufferDestroy(bufferB); assert_int_equal(IPAddressDestroy(&a), 0); assert_int_equal(IPAddressDestroy(&b), 0); } static void test_isipaddress(void) { /* * This test is just a summary of the other tests. * We just check that this interface works accordingly, most of the * functionality has already been tested. * 1.2.3.4 -> ok * 1.2..3 -> not * 1.a.2.3 -> not * 256.255.255.255 -> not * 255.255.255.255 -> ok * 1:0:0:0:0:0:0:1 -> ok * 1:1:1:1:0:1:1:1 -> ok * a:b:c:d:e:f:0:1 -> ok * a:b:c:d:e:f:g:h -> not * ffff:ffff:fffff:0:0:0:0:1 -> not */ IPAddress *address = NULL; Buffer *bufferAddress = NULL; bufferAddress = BufferNew(); assert_true (bufferAddress != NULL); BufferSet(bufferAddress, "1.2.3.4", strlen("1.2.3.4")); assert_true(IPAddressIsIPAddress(bufferAddress, NULL)); assert_true(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address != NULL); assert_int_equal(IPAddressType(address), IP_ADDRESS_TYPE_IPV4); BufferClear(bufferAddress); assert_int_equal(IPAddressDestroy(&address), 0); BufferSet(bufferAddress, "1.2..3", strlen("1.2..3")); assert_false(IPAddressIsIPAddress(bufferAddress, NULL)); assert_false(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address == NULL); BufferClear(bufferAddress); BufferSet(bufferAddress, "1.a.2.3", strlen("1.a.2.3")); assert_false(IPAddressIsIPAddress(bufferAddress, NULL)); assert_false(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address == NULL); BufferClear(bufferAddress); BufferSet(bufferAddress, "256.255.255.255", strlen("256.255.255.255")); assert_false(IPAddressIsIPAddress(bufferAddress, NULL)); assert_false(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address == NULL); BufferClear(bufferAddress); BufferSet(bufferAddress, "255.255.255.255", strlen("255.255.255.255")); assert_true(IPAddressIsIPAddress(bufferAddress, NULL)); assert_true(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address != NULL); assert_int_equal(IPAddressType(address), IP_ADDRESS_TYPE_IPV4); BufferClear(bufferAddress); assert_int_equal(IPAddressDestroy(&address), 0); BufferSet(bufferAddress, "1:0:0:0:0:0:0:1", strlen("1:0:0:0:0:0:0:1")); assert_true(IPAddressIsIPAddress(bufferAddress, NULL)); assert_true(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address != NULL); assert_int_equal(IPAddressType(address), IP_ADDRESS_TYPE_IPV6); BufferClear(bufferAddress); assert_int_equal(IPAddressDestroy(&address), 0); BufferSet(bufferAddress, "1:1:1:1:0:1:1:1", strlen("1:1:1:1:0:1:1:1")); assert_true(IPAddressIsIPAddress(bufferAddress, NULL)); assert_true(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address != NULL); assert_int_equal(IPAddressType(address), IP_ADDRESS_TYPE_IPV6); BufferClear(bufferAddress); assert_int_equal(IPAddressDestroy(&address), 0); BufferSet(bufferAddress, "a:b:c:d:e:f:0:1", strlen("a:b:c:d:e:f:0:1")); assert_true(IPAddressIsIPAddress(bufferAddress, NULL)); assert_true(IPAddressIsIPAddress(bufferAddress, &address)); assert_true(address != NULL); assert_int_equal(IPAddressType(address), IP_ADDRESS_TYPE_IPV6); BufferClear(bufferAddress); assert_int_equal(IPAddressDestroy(&address), 0); BufferSet(bufferAddress, "a:b:c:d:e:f:g:h", strlen("a:b:c:d:e:f:g:h")); assert_false(IPAddressIsIPAddress(bufferAddress, NULL)); assert_false(IPAddressIsIPAddress(bufferAddress, &address)); BufferClear(bufferAddress); BufferSet(bufferAddress, "ffff:ffff:fffff:0:0:0:0:1", strlen("ffff:ffff:fffff:0:0:0:0:1")); assert_false(IPAddressIsIPAddress(bufferAddress, NULL)); assert_false(IPAddressIsIPAddress(bufferAddress, &address)); BufferClear(bufferAddress); BufferDestroy(bufferAddress); } static void test_string_is_local_host_ip(void) { #ifdef WITH_PCRE2 // Test IPv6 assert_true(StringIsLocalHostIP("0:0:0:0:0:0:0:1")); assert_true(StringIsLocalHostIP("0:0:0:0:0:0::1")); assert_true(StringIsLocalHostIP("0:0:0:0:0::1")); assert_true(StringIsLocalHostIP("0:0:0:0::1")); assert_true(StringIsLocalHostIP("0:0:0::1")); assert_true(StringIsLocalHostIP("0:0::1")); assert_true(StringIsLocalHostIP("0::1")); assert_true(StringIsLocalHostIP("::1")); assert_true(StringIsLocalHostIP("0:0:0:0:0::0:1")); assert_true(StringIsLocalHostIP("0:0:0:0::0:1")); assert_true(StringIsLocalHostIP("0:0:0::0:1")); assert_true(StringIsLocalHostIP("0:0::0:1")); assert_true(StringIsLocalHostIP("0::0:1")); assert_true(StringIsLocalHostIP("::0:1")); assert_true(StringIsLocalHostIP("0:0:0:0::0:0:1")); assert_true(StringIsLocalHostIP("0:0:0::0:0:1")); assert_true(StringIsLocalHostIP("0:0::0:0:1")); assert_true(StringIsLocalHostIP("0::0:0:1")); assert_true(StringIsLocalHostIP("::0:0:1")); assert_true(StringIsLocalHostIP("0:0:0::0:0:0:1")); assert_true(StringIsLocalHostIP("0:0::0:0:0:1")); assert_true(StringIsLocalHostIP("0::0:0:0:1")); assert_true(StringIsLocalHostIP("::0:0:0:1")); assert_true(StringIsLocalHostIP("0:0::0:0:0:0:1")); assert_true(StringIsLocalHostIP("0::0:0:0:0:1")); assert_true(StringIsLocalHostIP("::0:0:0:0:1")); assert_true(StringIsLocalHostIP("0::0:0:0:0:0:1")); assert_true(StringIsLocalHostIP("::0:0:0:0:0:1")); assert_true(StringIsLocalHostIP("00:000:000000:000000:00000:0000:000:01")); assert_true(StringIsLocalHostIP("000:0000::00:1")); assert_true(StringIsLocalHostIP("00000:00::000:00:00001")); assert_true(StringIsLocalHostIP("0:00:0::0000:00:00:0001")); assert_true(StringIsLocalHostIP("::0:00:00:00:1")); assert_true(StringIsLocalHostIP("::0000000001")); assert_false(StringIsLocalHostIP("0:0:1:0:0:0:0:1")); assert_false(StringIsLocalHostIP("ff:0:0:0:0::0:1")); assert_false(StringIsLocalHostIP("0:0:0::0:0:0:2")); assert_false(StringIsLocalHostIP("0::3:2:1")); assert_false(StringIsLocalHostIP("0::0:0")); assert_false(StringIsLocalHostIP("::ff")); assert_false(StringIsLocalHostIP(" 0:0:0:0:0:0:0:1")); assert_false(StringIsLocalHostIP("0:0:0::0:1 ")); assert_false(StringIsLocalHostIP(" 0::0:0:1 ")); assert_false(StringIsLocalHostIP("\t::0:0:0:0:0:1")); assert_false(StringIsLocalHostIP("0;0;0;;1")); assert_false(StringIsLocalHostIP("0: :0:0:0:0:1")); assert_false(StringIsLocalHostIP("0:0:0:0:0:1")); // Test IPv4 assert_true(StringIsLocalHostIP("127.0.0.0")); assert_true(StringIsLocalHostIP("127.1.2.3")); assert_true(StringIsLocalHostIP("127.199.199.199")); assert_true(StringIsLocalHostIP("127.255.255.255")); assert_true(StringIsLocalHostIP("0000127.0003.002.01")); assert_false(StringIsLocalHostIP("127.0.1")); assert_false(StringIsLocalHostIP("128.0.0.1")); assert_false(StringIsLocalHostIP("127.0.0.256")); assert_false(StringIsLocalHostIP("127.0.300.0")); assert_false(StringIsLocalHostIP("127.o.0.0")); assert_false(StringIsLocalHostIP(" 127.0.0.1")); assert_false(StringIsLocalHostIP("127.0.0.1 ")); assert_false(StringIsLocalHostIP(" 127.0.0.1 ")); assert_false(StringIsLocalHostIP("\t127.0.0.1")); assert_false(StringIsLocalHostIP("127,0,0,1")); // misc assert_false(StringIsLocalHostIP("localhost")); assert_false(StringIsLocalHostIP("")); assert_false(StringIsLocalHostIP(" ")); #endif } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_ipv4) , unit_test(test_char2hex) , unit_test(test_ipv6) , unit_test(test_generic_interface) , unit_test(test_ipv4_address_comparison) , unit_test(test_ipv6_address_comparison) , unit_test(test_isipaddress) , unit_test(test_string_is_local_host_ip) }; return run_tests(tests); } cfengine-3.24.2/libntech/tests/Makefile.in0000644000000000000000000005231115010704273020356 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/tar.m4 \ $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GREP = @GREP@ HAVE_CLOCKID_T_DEFINE = @HAVE_CLOCKID_T_DEFINE@ HAVE_GETOPT_H_DEFINE = @HAVE_GETOPT_H_DEFINE@ HAVE_LIBYAML_DEFINE = @HAVE_LIBYAML_DEFINE@ HOSTNAME = @HOSTNAME@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NO_TAUTOLOGICAL_CC_OPTION = @NO_TAUTOLOGICAL_CC_OPTION@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_LOGGING_CFLAGS = @SYSTEMD_LOGGING_CFLAGS@ SYSTEMD_LOGGING_CPPFLAGS = @SYSTEMD_LOGGING_CPPFLAGS@ SYSTEMD_LOGGING_LDFLAGS = @SYSTEMD_LOGGING_LDFLAGS@ SYSTEMD_LOGGING_LIBS = @SYSTEMD_LOGGING_LIBS@ SYSTEMD_LOGGING_PATH = @SYSTEMD_LOGGING_PATH@ VERSION = @VERSION@ WITH_PCRE2_DEFINE = @WITH_PCRE2_DEFINE@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # SUBDIRS = unit static-check all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libntech/tests/README0000644000000000000000000000052015010704254017163 0ustar00rootroot00000000000000============================================================================== CFEngine testsuite ============================================================================== `make check' For information on how to add acceptance tests, see tests/acceptance/README. For information on how to add unit tests, see tests/unit/README. cfengine-3.24.2/libntech/ltmain.sh0000644000000000000000000117147415010704266017006 0ustar00rootroot00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.6 Debian-2.4.6-2" package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.6-2 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: cfengine-3.24.2/libntech/config.h.in0000644000000000000000000007164015010704272017177 0ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Absolute path of source tree */ #undef ABS_TOP_SRCDIR /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Special CFEngine symbol */ #undef AUTOCONF_HOSTNAME /* Speial CFEngine symbol */ #undef AUTOCONF_SYSNAME /* binaries location */ #undef BINDIR /* "Software build year" */ #undef BUILD_YEAR /* Datadir location */ #undef CF_DATADIR /* Path to chpasswd tool */ #undef CHPASSWD /* Whether endnetgrent returns int */ #undef ENDNETGRENT_RETURNS_INT /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_ATTR_XATTR_H /* Define to 1 if you have the `chflags' function. */ #undef HAVE_CHFLAGS /* Define if chpasswd tool is present */ #undef HAVE_CHPASSWD /* Define to 1 if the system has the type `clockid_t'. */ #undef HAVE_CLOCKID_T /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define to 1 if you have the `closefrom' function. */ #undef HAVE_CLOSEFROM /* Define to 1 if you have the `copy_file_range' function. */ #undef HAVE_COPY_FILE_RANGE /* Define to 1 if you have the declaration of `alarm', and to 0 if you don't. */ #undef HAVE_DECL_ALARM /* Define to 1 if you have the declaration of `chmod', and to 0 if you don't. */ #undef HAVE_DECL_CHMOD /* Define to 1 if you have the declaration of `chown', and to 0 if you don't. */ #undef HAVE_DECL_CHOWN /* Define to 1 if you have the declaration of `clock_gettime', and to 0 if you don't. */ #undef HAVE_DECL_CLOCK_GETTIME /* Define to 1 if you have the declaration of `closefrom', and to 0 if you don't. */ #undef HAVE_DECL_CLOSEFROM /* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't. */ #undef HAVE_DECL_DIRFD /* Define to 1 if you have the declaration of `drand48', and to 0 if you don't. */ #undef HAVE_DECL_DRAND48 /* Define to 1 if you have the declaration of `endnetgrent', and to 0 if you don't. */ #undef HAVE_DECL_ENDNETGRENT /* Define to 1 if you have the declaration of `FALLOC_FL_PUNCH_HOLE', and to 0 if you don't. */ #undef HAVE_DECL_FALLOC_FL_PUNCH_HOLE /* Define to 1 if you have the declaration of `fchmod', and to 0 if you don't. */ #undef HAVE_DECL_FCHMOD /* Define to 1 if you have the declaration of `fchmodat', and to 0 if you don't. */ #undef HAVE_DECL_FCHMODAT /* Define to 1 if you have the declaration of `fchownat', and to 0 if you don't. */ #undef HAVE_DECL_FCHOWNAT /* Define to 1 if you have the declaration of `fgetgrent', and to 0 if you don't. */ #undef HAVE_DECL_FGETGRENT /* Define to 1 if you have the declaration of `FICLONE', and to 0 if you don't. */ #undef HAVE_DECL_FICLONE /* Define to 1 if you have the declaration of `fstatat', and to 0 if you don't. */ #undef HAVE_DECL_FSTATAT /* Define to 1 if you have the declaration of `fsync', and to 0 if you don't. */ #undef HAVE_DECL_FSYNC /* Define to 1 if you have the declaration of `getaddrinfo', and to 0 if you don't. */ #undef HAVE_DECL_GETADDRINFO /* Define to 1 if you have the declaration of `getgid', and to 0 if you don't. */ #undef HAVE_DECL_GETGID /* Define to 1 if you have the declaration of `getline', and to 0 if you don't. */ #undef HAVE_DECL_GETLINE /* Define to 1 if you have the declaration of `getnetgrent', and to 0 if you don't. */ #undef HAVE_DECL_GETNETGRENT /* Define to 1 if you have the declaration of `getuid', and to 0 if you don't. */ #undef HAVE_DECL_GETUID /* Define to 1 if you have the declaration of `glob', and to 0 if you don't. */ #undef HAVE_DECL_GLOB /* Define to 1 if you have the declaration of `gmtime_r', and to 0 if you don't. */ #undef HAVE_DECL_GMTIME_R /* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you don't. */ #undef HAVE_DECL_INET_NTOP /* Define to 1 if you have the declaration of `inet_pton', and to 0 if you don't. */ #undef HAVE_DECL_INET_PTON /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ #undef HAVE_DECL_ISFINITE /* Define to 1 if you have the declaration of `le32toh', and to 0 if you don't. */ #undef HAVE_DECL_LE32TOH /* Define to 1 if you have the declaration of `localtime_r', and to 0 if you don't. */ #undef HAVE_DECL_LOCALTIME_R /* Define to 1 if you have the declaration of `log2', and to 0 if you don't. */ #undef HAVE_DECL_LOG2 /* Define to 1 if you have the declaration of `lstat', and to 0 if you don't. */ #undef HAVE_DECL_LSTAT /* Define to 1 if you have the declaration of `memdup', and to 0 if you don't. */ #undef HAVE_DECL_MEMDUP /* Define to 1 if you have the declaration of `memmem', and to 0 if you don't. */ #undef HAVE_DECL_MEMMEM /* Define to 1 if you have the declaration of `memrchr', and to 0 if you don't. */ #undef HAVE_DECL_MEMRCHR /* Define to 1 if you have the declaration of `mkdtemp', and to 0 if you don't. */ #undef HAVE_DECL_MKDTEMP /* Define to 1 if you have the declaration of `nanosleep', and to 0 if you don't. */ #undef HAVE_DECL_NANOSLEEP /* Define to 1 if you have the declaration of `openat', and to 0 if you don't. */ #undef HAVE_DECL_OPENAT /* Define to 1 if you have the declaration of `pthread_attr_setstacksize', and to 0 if you don't. */ #undef HAVE_DECL_PTHREAD_ATTR_SETSTACKSIZE /* Define to 1 if you have the declaration of `pthread_sigmask', and to 0 if you don't. */ #undef HAVE_DECL_PTHREAD_SIGMASK /* Define to 1 if you have the declaration of `readlinkat', and to 0 if you don't. */ #undef HAVE_DECL_READLINKAT /* Define to 1 if you have the declaration of `realpath', and to 0 if you don't. */ #undef HAVE_DECL_REALPATH /* Define to 1 if you have the declaration of `round', and to 0 if you don't. */ #undef HAVE_DECL_ROUND /* Define to 1 if you have the declaration of `sched_yield', and to 0 if you don't. */ #undef HAVE_DECL_SCHED_YIELD /* Define to 1 if you have the declaration of `SEEK_DATA', and to 0 if you don't. */ #undef HAVE_DECL_SEEK_DATA /* Define to 1 if you have the declaration of `seteuid', and to 0 if you don't. */ #undef HAVE_DECL_SETEUID /* Define to 1 if you have the declaration of `setlinebuf', and to 0 if you don't. */ #undef HAVE_DECL_SETLINEBUF /* Define to 1 if you have the declaration of `setnetgrent', and to 0 if you don't. */ #undef HAVE_DECL_SETNETGRENT /* Define to 1 if you have the declaration of `socketpair', and to 0 if you don't. */ #undef HAVE_DECL_SOCKETPAIR /* Define to 1 if you have the declaration of `srand48', and to 0 if you don't. */ #undef HAVE_DECL_SRAND48 /* Define to 1 if you have the declaration of `SSL_CTX_clear_options', and to 0 if you don't. */ #undef HAVE_DECL_SSL_CTX_CLEAR_OPTIONS /* Define to 1 if you have the declaration of `stpncpy', and to 0 if you don't. */ #undef HAVE_DECL_STPNCPY /* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you don't. */ #undef HAVE_DECL_STRCASECMP /* Define to 1 if you have the declaration of `strcasestr', and to 0 if you don't. */ #undef HAVE_DECL_STRCASESTR /* Define to 1 if you have the declaration of `strchrnul', and to 0 if you don't. */ #undef HAVE_DECL_STRCHRNUL /* Define to 1 if you have the declaration of `strdup', and to 0 if you don't. */ #undef HAVE_DECL_STRDUP /* Define to 1 if you have the declaration of `strerror', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR /* Define to 1 if you have the declaration of `strlcat', and to 0 if you don't. */ #undef HAVE_DECL_STRLCAT /* Define to 1 if you have the declaration of `strlcpy', and to 0 if you don't. */ #undef HAVE_DECL_STRLCPY /* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you don't. */ #undef HAVE_DECL_STRNCASECMP /* Define to 1 if you have the declaration of `strndup', and to 0 if you don't. */ #undef HAVE_DECL_STRNDUP /* Define to 1 if you have the declaration of `strnlen', and to 0 if you don't. */ #undef HAVE_DECL_STRNLEN /* Define to 1 if you have the declaration of `strrstr', and to 0 if you don't. */ #undef HAVE_DECL_STRRSTR /* Define to 1 if you have the declaration of `strsep', and to 0 if you don't. */ #undef HAVE_DECL_STRSEP /* Define to 1 if you have the declaration of `strsignal', and to 0 if you don't. */ #undef HAVE_DECL_STRSIGNAL /* Define to 1 if you have the declaration of `strstr', and to 0 if you don't. */ #undef HAVE_DECL_STRSTR /* Define to 1 if you have the declaration of `uname', and to 0 if you don't. */ #undef HAVE_DECL_UNAME /* Define to 1 if you have the declaration of `unsetenv', and to 0 if you don't. */ #undef HAVE_DECL_UNSETENV /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the `dirfd' function. */ #undef HAVE_DIRFD /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `door' function. */ #undef HAVE_DOOR /* Define to 1 if you have the `drand48' function. */ #undef HAVE_DRAND48 /* Define to 1 if you have the header file. */ #undef HAVE_DUSTAT_H /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H /* Define to 1 if you have the `endnetgrent' function. */ #undef HAVE_ENDNETGRENT /* Define to 1 if you have the `endpwent' function. */ #undef HAVE_ENDPWENT /* Define to 1 if you have the `fchmod' function. */ #undef HAVE_FCHMOD /* Define to 1 if you have the `fchmodat' function. */ #undef HAVE_FCHMODAT /* Define to 1 if you have the `fchownat' function. */ #undef HAVE_FCHOWNAT /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Whether to use fexecve(3) to execute a new process */ #undef HAVE_FEXECVE /* Define if fgetspent is available */ #undef HAVE_FGETSPENT /* Define to 1 if you have the `fpathconf' function. */ #undef HAVE_FPATHCONF /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ #undef HAVE_FSEEKO /* Define to 1 if you have the `fstatat' function. */ #undef HAVE_FSTATAT /* Define to 1 if you have the `gethostent' function. */ #undef HAVE_GETHOSTENT /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `getifaddrs' function. */ #undef HAVE_GETIFADDRS /* Define to 1 if you have the `getline' function. */ #undef HAVE_GETLINE /* Define to 1 if you have the `getnetgrent' function. */ #undef HAVE_GETNETGRENT /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `getprocs64' function. */ #undef HAVE_GETPROCS64 /* Define to 1 if you have the `getpwent' function. */ #undef HAVE_GETPWENT /* Define to 1 if you have the `getzoneid' function. */ #undef HAVE_GETZONEID /* Define to 1 if you have the `getzonenamebyid' function. */ #undef HAVE_GETZONENAMEBYID /* Define to 1 if you have the `gmtime_r' function. */ #undef HAVE_GMTIME_R /* Define to 1 if you have the header file. */ #undef HAVE_IEEEFP_H /* Define to 1 if you have the `inet_ntop' function. */ #undef HAVE_INET_NTOP /* Define to 1 if you have the `inet_pton' function. */ #undef HAVE_INET_PTON /* Define to 1 if the system has the type `intmax_t'. */ #undef HAVE_INTMAX_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `jail_get' function. */ #undef HAVE_JAIL_GET /* Define to 1 if you have the header file. */ #undef HAVE_KSTAT_H /* Whether to use lchown(3) to change ownerships */ #undef HAVE_LCHOWN /* Define to 1 if you have the `lckpwdf' function. */ #undef HAVE_LCKPWDF /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `nss_nis' library (-lnss_nis). */ #undef HAVE_LIBNSS_NIS /* Define to 1 if you have the `pcre2-8' library (-lpcre2-8). */ #undef HAVE_LIBPCRE2_8 /* Define to 1 if you have the `rt' library (-lrt). */ #undef HAVE_LIBRT /* Define if -lsec is available */ #undef HAVE_LIBSEC /* Define to 1 if you have the `ssl' library (-lssl). */ #undef HAVE_LIBSSL /* Define to 1 if you have the `systemd' library (-lsystemd). */ #undef HAVE_LIBSYSTEMD /* Define to 1 if you have the `yaml' library (-lyaml). */ #undef HAVE_LIBYAML /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_FS_H /* Define to 1 if you have the `llistxattr' function. */ #undef HAVE_LLISTXATTR /* Define to 1 if you have the `localeconv' function. */ #undef HAVE_LOCALECONV /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R /* Define to 1 if you have the `log2' function. */ #undef HAVE_LOG2 /* Define to 1 if the system has the type `long double'. */ #undef HAVE_LONG_DOUBLE /* Define to 1 if the system has the type `long long int'. */ #undef HAVE_LONG_LONG_INT /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `memdup' function. */ #undef HAVE_MEMDUP /* Define to 1 if you have the `memmem' function. */ #undef HAVE_MEMMEM /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR /* Define to 1 if you have the `mkdtemp' function. */ #undef HAVE_MKDTEMP /* Define to 1 if you have the `mkfifo' function. */ #undef HAVE_MKFIFO /* Define to 1 if BSD .msg_accrights supported */ #undef HAVE_MSGHDR_ACCRIGHTS /* Define to 1 if SCM_RIGHTS supported */ #undef HAVE_MSGHDR_MSG_CONTROL /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_ARP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_DL_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_ROUTE_H /* Define to 1 if no BSD .msg_accrights support */ #undef HAVE_NO_MSGHDR_ACCRIGHTS /* Define to 1 if SCM_RIGHTS support */ #undef HAVE_NO_MSGHDR_MSG_CONTROL /* Define to 1 if you have the `openat' function. */ #undef HAVE_OPENAT /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_OPENSSLV_H /* The old route entry structure in newer BSDs */ #undef HAVE_ORTENTRY /* Define to 1 if you have the header file. */ #undef HAVE_PCRE2_H /* Define to 1 if you have the `pstat_getfile2' function. */ #undef HAVE_PSTAT_GETFILE2 /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Define to 1 if you have the `pthread_attr_setstacksize' function. */ #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE /* Define to 1 if you have the `pthread_sigmask' function. */ #undef HAVE_PTHREAD_SIGMASK /* Define to 1 if the system has the type `ptrdiff_t'. */ #undef HAVE_PTRDIFF_T /* Define if pwdadm tool is present */ #undef HAVE_PWDADM /* Define to 1 if you have the `readlinkat' function. */ #undef HAVE_READLINKAT /* Define to 1 if you have the `round' function. */ #undef HAVE_ROUND /* Do we have any route entry structure? */ #undef HAVE_RTENTRY /* Define to 1 if you have the `sched_yield' function. */ #undef HAVE_SCHED_YIELD /* Define to 1 if you have the `sendfile' function. */ #undef HAVE_SENDFILE /* Define to 1 if you have the `sendto' function. */ #undef HAVE_SENDTO /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID /* Define to 1 if you have the `seteuid' function. */ #undef HAVE_SETEUID /* Define to 1 if you have the `setlinebuf' function. */ #undef HAVE_SETLINEBUF /* Define to 1 if you have the `setnetgrent' function. */ #undef HAVE_SETNETGRENT /* Define to 1 if you have the `setpwent' function. */ #undef HAVE_SETPWENT /* Define to 1 if you have the `setregid' function. */ #undef HAVE_SETREGID /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `setsockopt' function. */ #undef HAVE_SETSOCKOPT /* Define to 1 if you have the header file. */ #undef HAVE_SHADOW_H /* Define to 1 if you have the `sleep' function. */ #undef HAVE_SLEEP /* Define to 1 if you have a C99 compliant `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if the system has the type `socklen_t'. */ #undef HAVE_SOCKLEN_T /* Define to 1 if you have the `srand48' function. */ #undef HAVE_SRAND48 /* Define to 1 if you have the `statfs' function. */ #undef HAVE_STATFS /* Define to 1 if you have the `statvfs' function. */ #undef HAVE_STATVFS /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `stpncpy' function. */ #undef HAVE_STPNCPY /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strcasestr' function. */ #undef HAVE_STRCASESTR /* Define to 1 if you have the `strchrnul' function. */ #undef HAVE_STRCHRNUL /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcat' function. */ #undef HAVE_STRLCAT /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the `strndup' function. */ #undef HAVE_STRNDUP /* Define to 1 if you have the `strnlen' function. */ #undef HAVE_STRNLEN /* Define to 1 if you have the `strrstr' function. */ #undef HAVE_STRRSTR /* Define to 1 if you have the `strsep' function. */ #undef HAVE_STRSEP /* Define to 1 if you have the `strsignal' function. */ #undef HAVE_STRSIGNAL /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if `ifr_hwaddr' is a member of `struct ifreq'. */ #undef HAVE_STRUCT_IFREQ_IFR_HWADDR /* Define to 1 if `decimal_point' is a member of `struct lconv'. */ #undef HAVE_STRUCT_LCONV_DECIMAL_POINT /* Define to 1 if `thousands_sep' is a member of `struct lconv'. */ #undef HAVE_STRUCT_LCONV_THOUSANDS_SEP /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ #undef HAVE_STRUCT_SOCKADDR_SA_LEN /* Define to 1 if the system has the type `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE /* Define to 1 if `st_blocks' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLOCKS /* Define to 1 if `st_mtim' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_MTIM /* Define to 1 if `st_mtimespec' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_MTIMESPEC /* Define to 1 if `uptime' is a member of `struct sysinfo'. */ #undef HAVE_STRUCT_SYSINFO_UPTIME /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define to 1 if you have the `sysinfo' function. */ #undef HAVE_SYSINFO /* Define to 1 if you have the header file. */ #undef HAVE_SYSTEMD_SD_JOURNAL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILESYS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_JAIL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LOADAVG_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MOUNT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MPCTL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PSTAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SENDFILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATVFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSMACROS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSTEMINFO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_VFS_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_XATTR_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define if TLS 1.1 is supported by OpenSSL */ #undef HAVE_TLS_1_1 /* Define if TLS 1.2 is supported by OpenSSL */ #undef HAVE_TLS_1_2 /* Define if TLS 1.3 is supported by OpenSSL */ #undef HAVE_TLS_1_3 /* Define to 1 if the system has the type `uintmax_t'. */ #undef HAVE_UINTMAX_T /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T /* Define to 1 if you have the `ulckpwdf' function. */ #undef HAVE_ULCKPWDF /* Define to 1 if you have the `uname' function. */ #undef HAVE_UNAME /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Define to 1 if the system has the type `unsigned long long int'. */ #undef HAVE_UNSIGNED_LONG_LONG_INT /* Define if useradd tool is present */ #undef HAVE_USERADD /* Define if userdel tool is present */ #undef HAVE_USERDEL /* Define if usermod tool is present */ #undef HAVE_USERMOD /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMPX_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMP_H /* Define to 1 if you have the header file. */ #undef HAVE_VARARGS_H /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF /* Define to 1 if you have the `va_copy' function or macro. */ #undef HAVE_VA_COPY /* Define to 1 if you have the header file. */ #undef HAVE_VFS_H /* Define to 1 if you have a C99 compliant `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_WINSOCK2_H /* Define to 1 if you have the header file. */ #undef HAVE_WS2TCPIP_H /* Define to 1 if you have the header file. */ #undef HAVE_YAML_H /* Define to 1 if you have the header file. */ #undef HAVE_ZONE_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to 1 if you have the `__va_copy' function or macro. */ #undef HAVE___VA_COPY /* Define to 1 if you have properly defined `ctime' function */ #undef HAVE_ctime_PROPER /* Define to 1 if you have properly defined `mkdir' function */ #undef HAVE_mkdir_PROPER /* Define to 1 if you have properly defined `rename' function */ #undef HAVE_rename_PROPER /* Define to 1 if you have properly defined `stat' function */ #undef HAVE_stat_PROPER /* Inputs directory location */ #undef INPUTDIR /* Logdir location */ #undef LOGDIR /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Masterfiles directory location */ #undef MASTERDIR /* Suppress deprecation warnings from OpenSSL 3 */ #undef OPENSSL_SUPPRESS_DEPRECATED /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* piddir location */ #undef PIDDIR /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* Path to pwdadm tool */ #undef PWDADM /* Whether sendto does not returns ssize_t */ #undef SENDTO_RETURNS_SSIZE_T /* Whether setnetgrent returns int */ #undef SETNETGRENT_RETURNS_INT /* Path to the POSIX-compatible shell */ #undef SHELL_PATH /* State directory location */ #undef STATEDIR /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Path to useradd tool */ #undef USERADD /* Path to userdel tool */ #undef USERDEL /* Path to usermod tool */ #undef USERMOD /* Version number of package */ #undef VERSION /* Define if OpenSSL is being used */ #undef WITH_OPENSSL /* Define if PCRE2 is being used */ #undef WITH_PCRE2 /* Define if you have a libc that supports extended attributes */ #undef WITH_XATTR /* Define if your xattr implementation has extra arguments */ #undef WITH_XATTR_EXTRA_ARGS /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Workdir location */ #undef WORKDIR /* Define if XEN cpuid-based HVM detection is available. */ #undef XEN_CPUID_SUPPORT /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE # define _DARWIN_USE_64_BIT_INODE 1 #endif /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ #undef _LARGEFILE_SOURCE /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Enable wide data structures everywhere */ #undef _PSTAT64 /* SUSv3 */ #undef _XOPEN_SOURCE /* Extended UNIX 98 interfaces */ #undef __EXTENSIONS__ /* Define to rpl_asprintf if the replacement function should be used. */ #undef asprintf /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to rpl_fprintf if the replacement function should be used. */ #undef fprintf /* Define to `int' if doesn't define. */ #undef gid_t /* Define to the widest signed integer type if and do not define. */ #undef intmax_t /* Define to `int' if does not define. */ #undef mode_t /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define to rpl_printf if the replacement function should be used. */ #undef printf /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to rpl_snprintf if the replacement function should be used. */ #undef snprintf /* Define to `int' if doesn't define. */ #undef uid_t /* Define to the widest unsigned integer type if and do not define. */ #undef uintmax_t /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t /* Define to rpl_vasprintf if the replacement function should be used. */ #undef vasprintf /* Define to rpl_vfprintf if the replacement function should be used. */ #undef vfprintf /* Define to rpl_vprintf if the replacement function should be used. */ #undef vprintf /* Define to rpl_vsnprintf if the replacement function should be used. */ #undef vsnprintf cfengine-3.24.2/libntech/aclocal.m40000644000000000000000000011662715010704271017020 0ustar00rootroot00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Copyright (C) 1998-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_LEX # ----------- # Autoconf leaves LEX=: if lex or flex can't be found. Change that to a # "missing" invocation, for better error output. AC_DEFUN([AM_PROG_LEX], [AC_PREREQ([2.50])dnl AC_REQUIRE([AM_MISSING_HAS_RUN])dnl AC_REQUIRE([AC_PROG_LEX])dnl if test "$LEX" = :; then LEX=${am_missing_run}flex fi]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) m4_include([m4/acinclude.m4]) m4_include([m4/adl_recursive_eval.m4]) m4_include([m4/cf3_check_proper_func.m4]) m4_include([m4/cf3_path_root_prog.m4]) m4_include([m4/cf3_with_library.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/old-autoconf.m4]) m4_include([m4/snprintf.m4]) m4_include([m4/strndup.m4]) m4_include([m4/tar.m4]) cfengine-3.24.2/libntech/configure.ac0000644000000000000000000011702215010704254017435 0ustar00rootroot00000000000000dnl dnl Copyright 2024 Northern.tech AS dnl dnl This file is part of CFEngine 3 - written and maintained by Northern.tech AS. dnl dnl Licensed under the Apache License, Version 2.0 (the "License"); dnl you may not use this file except in compliance with the License. dnl You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl To the extent this program is licensed as part of the Enterprise dnl versions of CFEngine, the applicable Commercial Open Source License dnl (COSL) may apply to this file if you as a licensee so wish it. See dnl included file COSL.txt. dnl dnl ########################################################################## dnl # dnl # Build libntech dnl # dnl # Run ./autogen.sh to build configure script dnl # dnl ########################################################################## AC_PREREQ(2.63) AC_INIT(libntech, 1.0.0, [], [], [https://github.com/NorthernTechHQ/libntech]) AC_CANONICAL_TARGET dnl dnl This program needs to be checked early, as MAKEINFO variable is expanded in dnl AM_INIT_AUTOMAKE. dnl AC_CHECK_PROG(MAKEINFO, makeinfo, makeinfo) dnl Parallel unit tests are causing spurious failures across several systems, dnl particularly those doing process testing. dnl Unfortunately the option to disable parallel tests (serial-tests) doesn't dnl exist in automake 1.11 and earlier, so we need to do this complicated logic dnl to determine whether we can disable it or not. If it doesn't exist as an dnl option, then serial tests are already the default. AC_MSG_CHECKING([automake version]) m4_define(AUTOMAKE_VERSION, m4_normalize(m4_esyscmd([automake --version 2>&1 | sed -ne '/^automake/{s/^automake.* \([^ ][^ ]*\)$/\1/; p;}']))) m4_define(SERIAL_TESTS, m4_bmatch(AUTOMAKE_VERSION, [^1\.\([0-9]\|1[0-1]\)\(\.\|$\)], [], [serial-tests])) AC_MSG_RESULT(AUTOMAKE_VERSION) AM_INIT_AUTOMAKE([tar-ustar] SERIAL_TESTS) AM_MAINTAINER_MODE([enable]) m4_divert_text([DEFAULTS], [: "${AR_FLAGS=cr}"]) AC_DEFINE(BUILD_YEAR, esyscmd([date +%Y | tr -d '\n']), "Software build year") AC_DEFINE_UNQUOTED(ABS_TOP_SRCDIR, "`cd -- "$srcdir"; pwd`", [Absolute path of source tree]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS([config.h]) dnl Libtool madness AC_CONFIG_MACRO_DIR([m4]) dnl dnl hide [s]include macros, so old aclocal (automake < 1.10) won't find them and dnl won't complain about something/something.m4 not found dnl m4_define(incstart,sinc) m4_define(incend,lude) dnl dnl Save environment CFLAGS before autoconf starts messing with it. dnl It is restored later. dnl ENV_CFLAGS="$CFLAGS" dnl ###################################################################### dnl Checks for programs. dnl ###################################################################### AC_PROG_CC AC_PROG_MKDIR_P AC_EXEEXT dnl GCC specific flags m4_include([m4/cf3_gcc_flags.m4]) # Use either new LT_INIT or old AC_DISABLE_STATIC/AC_PROG_LIBTOOL macros m4_ifdef([LT_INIT], [LT_INIT([disable-static])], [AC_DISABLE_STATIC AC_PROG_LIBTOOL]) AM_PROG_LEX AC_PROG_YACC AC_PROG_INSTALL AC_PATH_PROG([PERL], [perl]) AC_CONFIG_LIBOBJ_DIR(libcompat) AC_PATH_PROG(GETCONF, getconf, false, $PATH:$prefix/bin:/usr/bin:/usr/local/bin:/sw/bin) AM_CONDITIONAL(CROSS_COMPILING, test "x$cross_compiling" = "xyes") # Check whether `pkg-config' is available AC_ARG_VAR([PKG_CONFIG], [path to pkg-config]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to the pkg-config search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi dnl ###################################################################### dnl Use pthreads if available dnl ###################################################################### AC_ARG_WITH([pthreads], [AS_HELP_STRING([--with-pthreads[[=PATH]]], [Specify path to pthreads, if not the part of operating system])]) if test "x$with_pthreads" != x && test "x$with_pthreads" != "xyes" && test "x$with_pthreads" != "xno"; then LIBS="$LIBS -L$with_pthreads/lib" CPPFLAGS="-I$with_pthreads/include $CPPFLAGS" fi ACX_PTHREAD([], [AC_MSG_ERROR(pthread-compatible library is required to build CFEngine)]) CC="$PTHREAD_CC" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" dnl ###################################################################### dnl Configure files layout dnl ###################################################################### AC_ARG_ENABLE([fhs], [AS_HELP_STRING([--enable-fhs], [Enable FHS compliance. Defaults to custom CFEngine files layout])]) # # pkglibdir/pkgdatadir are not overridable, so use our own invention instead. # AS_IF([test x"$enable_fhs" = xyes], [ projlibdir='${pkglibdir}' WORKDIR='${localstatedir}/lib/cfengine' MASTERDIR='default' INPUTDIR='default' DATADIR='default' LOGDIR='${localstatedir}/log/cfengine' PIDDIR='${runstatedir:-${localstatedir}/run}/cfengine' STATEDIR='default' ], [ if test x"$prefix" = xNONE || test x"$prefix" = x/var/cfengine; then prefix=/var/cfengine case "$target_os" in mingw*) WORKDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') PIDDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') STATEDIR=default ;; *) WORKDIR=/var/cfengine MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=/var/cfengine PIDDIR=/var/cfengine STATEDIR=default ;; esac else WORKDIR="${localstatedir}/${PACKAGE}" MASTERDIR="default" INPUTDIR="default" DATADIR="default" LOGDIR="${localstatedir}/${PACKAGE}" PIDDIR="${localstatedir}/${PACKAGE}" STATEDIR="default" fi bindir="${bindir:-${exec_prefix}/bin}" projlibdir='${libdir}' ]) AC_SUBST(projlibdir) dnl ###################################################################### dnl Platform specific compiler flags. dnl ###################################################################### AS_CASE([${target_os}], [mingw*], # Disable printf format warnings, because our wrapper supports more # flags than vanilla Windows version, so they are false positives. [CFLAGS="$CFLAGS -Wno-format"]) dnl ###################################################################### dnl Enable debugging dnl ###################################################################### AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enable debugging]), [debug=$enableval], [debug=no]) AM_CONDITIONAL([NDEBUG], [test x"$debug" = x"no"]) dnl Even though CFLAGS should contain the command-line CFLAGS dnl as last, some macro seem to messes the order up and insert dnl its own optimisation flags as well. So we append ENV_CFLAGS dnl at the end manually, causing a bit of flag duplication. AC_MSG_CHECKING([for debug option]) if test x"$debug" = x"yes" then AC_MSG_RESULT(yes) CFLAGS="$CFLAGS -g3 -O0 $ENV_CFLAGS" else AC_MSG_RESULT(no) CFLAGS="$CFLAGS -O2 -DNDEBUG $ENV_CFLAGS" fi dnl ###################################################################### dnl Checks for libraries. dnl ###################################################################### dnl Now check for database connectors dnl dnl OpenSSL dnl AC_ARG_WITH(openssl, [AS_HELP_STRING([--with-openssl[[=PATH]]], [Specify OpenSSL path])], [], [with_openssl=yes]) if test -d /usr/local/Cellar/ && \ test -d /usr/local/opt/openssl/ && \ test "x$with_openssl" = "xyes" ; then with_openssl=$(brew --prefix openssl) echo "OS X Homebrew detected" echo "Defaulting to: --with-openssl=$with_openssl" fi if test "x$with_openssl" != "xno"; then CF3_WITH_LIBRARY(openssl, [ AC_CHECK_LIB(crypto, RSA_generate_key_ex, [], []) AC_CHECK_LIB(ssl, SSL_free, [], []) AC_CHECK_DECLS([SSL_CTX_clear_options], [], [], [[#include ]]) AC_CHECK_HEADERS([openssl/opensslv.h], [], [AC_MSG_ERROR(Cannot find OpenSSL)]) AC_MSG_CHECKING(for OpenSSL version) AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ #include #if OPENSSL_VERSION_NUMBER < 0x1000000fL #This OpenSSL is too old #endif ]])],[AC_MSG_RESULT(OK)],[AC_MSG_ERROR(This release of CFEngine requires OpenSSL >= 1.0.0)]) if test "x$ac_cv_lib_crypto_RSA_generate_key_ex" = "xno"; then AC_MSG_ERROR(Cannot find OpenSSL) fi AC_DEFINE([OPENSSL_SUPPRESS_DEPRECATED], [1], [Suppress deprecation warnings from OpenSSL 3]) AC_CHECK_DECL([SSL_OP_NO_TLSv1_1], [AC_DEFINE([HAVE_TLS_1_1], [1], [Define if TLS 1.1 is supported by OpenSSL])], [], [[#include ]] ) AC_CHECK_DECL([SSL_OP_NO_TLSv1_2], [AC_DEFINE([HAVE_TLS_1_2], [1], [Define if TLS 1.2 is supported by OpenSSL])], [], [[#include ]] ) AC_CHECK_DECL([SSL_OP_NO_TLSv1_3], [AC_DEFINE([HAVE_TLS_1_3], [1], [Define if TLS 1.3 is supported by OpenSSL])], [], [[#include ]] ) ]) AC_DEFINE(WITH_OPENSSL, 1, [Define if OpenSSL is being used]) AM_CONDITIONAL(WITH_OPENSSL, true) else AM_CONDITIONAL(WITH_OPENSSL, false) fi dnl PCRE2 AC_ARG_WITH([pcre], [AS_HELP_STRING([--with-pcre=no], [Disable PCRE (only for backwards compatibility)])], [], [with_pcre=default]) if test "x$with_pcre" != "xdefault" && test "x$with_pcre" != "xno"; then AC_MSG_ERROR([PCRE no longer supported, use PCRE2]); fi AC_ARG_WITH([pcre2], [AS_HELP_STRING([--with-pcre2[[=PATH]]], [Specify PCRE2 path])], [], [with_pcre2=yes]) if test "x$with_pcre" != "xno" && test "x$with_pcre2" != "xno"; then CF3_WITH_LIBRARY(pcre2, [ AC_CHECK_LIB(pcre2-8, pcre2_compile_8, [], [AC_MSG_ERROR(Cannot find PCRE2)]) AC_CHECK_HEADERS( [pcre2.h], [], AC_MSG_ERROR(Cannot find PCRE2), [#define PCRE2_CODE_UNIT_WIDTH 8] )] ) AC_DEFINE(WITH_PCRE2, 1, [Define if PCRE2 is being used]) AM_CONDITIONAL(WITH_PCRE2, true) WITH_PCRE2_DEFINE="#define WITH_PCRE2 1" else AM_CONDITIONAL(WITH_PCRE2, false) WITH_PCRE2_DEFINE="// #undef WITH_PCRE2" fi AC_SUBST(WITH_PCRE2_DEFINE) dnl systemd structured logging AC_ARG_WITH([systemd-logging], [AS_HELP_STRING([--with-systemd-logging[[=PATH]]], [support systemd structured logging])], [], [with_systemd_logging=check]) if test "x$with_systemd_logging" != xno then CF3_WITH_LIBRARY(systemd_logging, [ AC_CHECK_LIB(systemd, sd_journal_sendv, [], [if test "x$with_systemd_logging" != xcheck; then AC_MSG_ERROR(Cannot find systemd library); fi]) AC_CHECK_HEADERS(systemd/sd-journal.h, [], [if test "x$with_systemd_logging" != xcheck; then AC_MSG_ERROR(Cannot find systemd headers); fi]) ]) fi dnl libyaml AC_ARG_WITH([libyaml], [AS_HELP_STRING([--with-libyaml[[=PATH]]], [Specify libyaml path])], [], [with_libyaml=check]) if test "x$with_libyaml" != xno then CF3_WITH_LIBRARY(libyaml, [ AC_CHECK_LIB(yaml, yaml_parser_initialize, [], [if test "x$with_libyaml" != xcheck; then AC_MSG_ERROR(Cannot find libyaml library); fi]) AC_CHECK_HEADERS(yaml.h, [libyaml_header_found=yes HAVE_LIBYAML_DEFINE="#define HAVE_LIBYAML 1"], [if test "x$with_libyaml" != xcheck; then AC_MSG_ERROR(Cannot find libyaml header files); fi HAVE_LIBYAML_DEFINE="// #undef HAVE_LIBYAML"]) ]) else HAVE_LIBYAML_DEFINE="// #undef HAVE_LIBYAML" fi AC_SUBST(HAVE_LIBYAML_DEFINE) dnl ###################################################################### dnl Checks for header files. dnl ###################################################################### AC_CHECK_HEADERS(unistd.h stdlib.h sys/loadavg.h) AC_CHECK_HEADERS(sys/param.h sys/resource.h) # sys/param.h is required for sys/mount.h on OpenBSD AC_CHECK_HEADERS(sys/mount.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) # Required on BSD to get struct sockaddr_dl (for retrieving MAC addresses from getifaddrs()) AC_CHECK_HEADERS(net/if_dl.h) # Required on Solaris to get struct arpreq (for retrieving MAC addresses) AC_CHECK_HEADERS(net/if_arp.h, , , [AC_INCLUDES_DEFAULT #include ]) AC_CHECK_HEADERS(getopt.h, [HAVE_GETOPT_H_DEFINE="#define HAVE_GETOPT_H 1"], [HAVE_GETOPT_H_DEFINE="// #undef HAVE_GETOPT_H"] ) AC_SUBST(HAVE_GETOPT_H_DEFINE) AC_CHECK_HEADERS(utime.h) AC_CHECK_HEADERS(time.h) AC_CHECK_HEADERS(sys/time.h) AC_CHECK_HEADERS(malloc.h sys/malloc.h) AC_CHECK_HEADERS(vfs.h) AC_CHECK_HEADERS(sys/vfs.h) AC_CHECK_HEADERS(sys/sockio.h) AC_CHECK_HEADERS(sys/statvfs.h) AC_CHECK_HEADERS(sys/statfs.h) AC_CHECK_HEADERS(fcntl.h) AC_CHECK_HEADERS(sys/filesys.h) AC_CHECK_HEADERS(dustat.h) AC_CHECK_HEADERS(sys/systeminfo.h) AC_CHECK_HEADERS(ieeefp.h) AC_CHECK_HEADERS(winsock2.h) AC_CHECK_HEADERS(ws2tcpip.h) AC_CHECK_HEADERS(zone.h) AC_CHECK_HEADERS(sys/uio.h) AC_CHECK_HEADERS_ONCE([sys/sysmacros.h]) dnl glibc deprecated inclusion in sys/type.h AC_CHECK_HEADERS(sys/types.h) AC_CHECK_HEADERS(sys/mpctl.h) dnl For HP-UX $(sys.cpus) - Mantis #1069 AC_CHECK_HEADERS(shadow.h) AC_CHECK_HEADERS(sys/jail.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) AC_CHECK_HEADERS(net/route.h netinet/in.h netinet/ip.h) AC_HEADER_STDC AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_HEADER_DIRENT AC_HEADER_STDBOOL dnl ###################################################################### dnl Checks for data types dnl ###################################################################### AC_TYPE_MODE_T AC_TYPE_SIZE_T AC_TYPE_UID_T AC_TYPE_PID_T AC_CHECK_TYPES(clockid_t, [HAVE_CLOCKID_T_DEFINE="#define HAVE_CLOCKID_T 1"], [HAVE_CLOCKID_T_DEFINE="// #undef HAVE_CLOCKID_T"] , [[ #ifdef HAVE_TIME_H # include #endif ]]) AC_SUBST(HAVE_CLOCKID_T_DEFINE) AC_CHECK_TYPES(socklen_t, [], [], [[ #ifdef HAVE_SYS_TYPES_H # include #endif #include ]]) dnl ###################################################################### dnl Checks for typedefs, structures, and compiler characteristics. dnl ###################################################################### AC_C_CONST AC_FUNC_FSEEKO AC_SYS_LARGEFILE AC_TYPE_OFF_T # # AC_SYS_LARGEFILE correctly figures out necessary macros for large files, but # on AIX there is a gotcha: # # Code generated by flex #includes at the beginning of the file, which # picks up 32-bit wide off_t. Then it #includes which provides LFS # macros, and finally it includes another system header, now with 64-bit wide # off_t, which causes a conflict. # if test "x$ac_cv_sys_large_files" = x1; then CPPFLAGS="-D_LARGE_FILES=1 $CPPFLAGS" fi dnl ###################################################################### dnl Check for libraries dnl ###################################################################### AC_CHECK_LIB(m, sqrt) AC_CHECK_LIB(rt, clock_gettime) AC_CHECK_LIB(dl, dlopen) dnl ###################################################################### dnl Check for special functions dnl ###################################################################### AC_CHECK_DECLS(clock_gettime, [], [], [[#include ]]) AC_REPLACE_FUNCS(clock_gettime) AC_CHECK_DECLS(unsetenv) AC_REPLACE_FUNCS(unsetenv) AC_CHECK_DECLS(strnlen) AC_REPLACE_FUNCS(strnlen) cf3_FUNC_STRNDUP AC_CHECK_DECLS(seteuid) AC_REPLACE_FUNCS(seteuid) AC_CHECK_DECLS(setlinebuf) AC_REPLACE_FUNCS(setlinebuf) AC_CHECK_DECLS(strlcat) AC_REPLACE_FUNCS(strlcat) AC_CHECK_DECLS(strlcpy) AC_REPLACE_FUNCS(strlcpy) AC_CHECK_DECLS(realpath) AC_CHECK_DECLS(strdup) AC_REPLACE_FUNCS(strdup) AC_CHECK_DECLS(memrchr) AC_REPLACE_FUNCS(memrchr) AC_CHECK_DECLS(round, [], [], [[#include ]]) AC_REPLACE_FUNCS(round) AC_CHECK_DECLS(nanosleep) AC_REPLACE_FUNCS(nanosleep) AC_CHECK_DECLS(memdup) AC_REPLACE_FUNCS(memdup) AC_CHECK_DECLS(memmem) AC_REPLACE_FUNCS(memmem) AC_CHECK_DECLS(srand48) AC_REPLACE_FUNCS(srand48) AC_CHECK_DECLS(drand48) AC_REPLACE_FUNCS(drand48) AC_CHECK_DECLS(strerror) AC_REPLACE_FUNCS(strerror) AC_CHECK_DECLS(strstr) AC_REPLACE_FUNCS(strstr) AC_CHECK_DECLS(strcasestr) AC_REPLACE_FUNCS(strcasestr) AC_CHECK_DECLS(strcasecmp) AC_REPLACE_FUNCS(strcasecmp) AC_CHECK_DECLS(strncasecmp) AC_REPLACE_FUNCS(strncasecmp) AC_CHECK_DECLS(strsep) AC_REPLACE_FUNCS(strsep) AC_CHECK_DECLS(strsignal) AC_REPLACE_FUNCS(strsignal) AC_CHECK_DECLS(gmtime_r, [], [], [[#include ]]) AC_REPLACE_FUNCS(gmtime_r) AC_CHECK_DECLS(getline, [], [], [#define _GNU_SOURCE 1 AC_INCLUDES_DEFAULT]) AC_REPLACE_FUNCS(getline) AC_CHECK_DECLS(strchrnul, [], [], [#define _GNU_SOURCE 1 AC_INCLUDES_DEFAULT]) AC_REPLACE_FUNCS(strchrnul) AC_CHECK_DECLS(localtime_r, [], [], [[#include ]]) AC_REPLACE_FUNCS(localtime_r) AC_CHECK_DECLS(fgetgrent, [], [], [[#include ]]) AC_CHECK_DECLS(isfinite, [], [], [[#include ]]) AC_CHECK_FUNCS(getpwent setpwent endpwent) AC_CHECK_FUNCS(fgetspent lckpwdf ulckpwdf) AC_CHECK_LIB([sec], [fgetspent], [ AC_DEFINE([HAVE_LIBSEC], 1, [Define if -lsec is available]) AC_DEFINE([HAVE_FGETSPENT], 1, [Define if fgetspent is available]) LIBS="-lsec $LIBS" ]) AC_C_BIGENDIAN AC_CHECK_HEADERS([endian.h]) AC_CHECK_DECLS(le32toh, [], [], [[#include ]]) AC_CHECK_DECLS(closefrom, [], [], [[#include #include ]]) AC_REPLACE_FUNCS(closefrom) AC_CHECK_HEADERS([sys/pstat.h]) AC_CHECK_FUNCS(pstat_getfile2) CF3_PATH_ROOT_PROG([CHPASSWD], [chpasswd], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$CHPASSWD" != "x"], [AC_DEFINE(HAVE_CHPASSWD, 1, [Define if chpasswd tool is present])] [AC_DEFINE_UNQUOTED(CHPASSWD, ["$CHPASSWD"], [Path to chpasswd tool])] ) dnl AIX has this. CF3_PATH_ROOT_PROG([PWDADM], [pwdadm], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$PWDADM" != "x"], [AC_DEFINE(HAVE_PWDADM, 1, [Define if pwdadm tool is present])] [AC_DEFINE_UNQUOTED(PWDADM, ["$PWDADM"], [Path to pwdadm tool])] ) CF3_PATH_ROOT_PROG([USERADD], [useradd], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$USERADD" != "x"], [AC_DEFINE(HAVE_USERADD, 1, [Define if useradd tool is present])] [AC_DEFINE_UNQUOTED(USERADD, ["$USERADD"], [Path to useradd tool])] ) CF3_PATH_ROOT_PROG([USERMOD], [usermod], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$USERMOD" != "x"], [AC_DEFINE(HAVE_USERMOD, 1, [Define if usermod tool is present])] [AC_DEFINE_UNQUOTED(USERMOD, ["$USERMOD"], [Path to usermod tool])] ) CF3_PATH_ROOT_PROG([USERDEL], [userdel], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$USERDEL" != "x"], [AC_DEFINE(HAVE_USERDEL, 1, [Define if userdel tool is present])] [AC_DEFINE_UNQUOTED(USERDEL, ["$USERDEL"], [Path to userdel tool])] ) AS_IF([test "x$USERADD" != x && \ test "x$USERMOD" != x && test "x$USERDEL" != x], [have_userprogs=yes], [have_userprogs=no] ) AC_CHECK_DECLS(getnetgrent, [], [], [[#include ]]) AC_CHECK_FUNCS(getnetgrent) AC_CHECK_DECLS(setnetgrent, [], [], [[#include ]]) AC_CHECK_FUNCS(setnetgrent) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[extern int setnetgrent(const char *)]])], [AC_DEFINE([SETNETGRENT_RETURNS_INT], 1, [Whether setnetgrent returns int])], [AC_DEFINE([SETNETGRENT_RETURNS_INT], 0, [Whether setnetgrent returns int])]) AC_CHECK_DECLS(endnetgrent, [], [], [[#include ]]) AC_CHECK_FUNCS(endnetgrent) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[extern int endnetgrent(const char *)]])], [AC_DEFINE([ENDNETGRENT_RETURNS_INT], 1, [Whether endnetgrent returns int])], [AC_DEFINE([ENDNETGRENT_RETURNS_INT], 0, [Whether endnetgrent returns int])]) AC_CHECK_FUNCS(sendto) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)]])], [AC_DEFINE([SENDTO_RETURNS_SSIZE_T], 1, [Whether sendto returns ssize_t])], [AC_DEFINE([SENDTO_RETURNS_SSIZE_T], 0, [Whether sendto does not returns ssize_t])]) CF3_CHECK_PROPER_FUNC([ctime], [], [[#error ctime(3) may produce different results on different OSes. Let's have our POSIX-compliant implementation all the time]], [#define ctime rpl_ctime]) CF3_REPLACE_PROPER_FUNC([ctime]) dnl Check whether mkdir accepts two parameters CF3_CHECK_PROPER_FUNC([mkdir], [[#include #include ]], [[int mkdir(const char *pathname, mode_t mode);]], [#define mkdir rpl_mkdir]) dnl Check for Win32 stat. We don't know to detect improper stat during dnl compilation, so we resort to OS type detection. CF3_CHECK_PROPER_FUNC([stat], [[#include #include ]], [[#if defined(__MINGW32__) #error stat in Windows CRT ill-behaves #endif]], []) dnl Check for Win32 rename. We don't know how to detect improper rename (not dnl removing target file if it exists) during cross-compilation, so we resort to dnl OS type detection. CF3_CHECK_PROPER_FUNC([rename], [], [[#if defined(__MINGW32__) #error rename in Windows CRT ill-behaves #endif]], [#define rename rpl_rename]) AC_CHECK_DECLS(mkdtemp) AC_REPLACE_FUNCS(mkdtemp) AC_CHECK_DECLS(strrstr) AC_REPLACE_FUNCS(strrstr) AC_CHECK_DECLS(stpncpy) AC_REPLACE_FUNCS(stpncpy) AC_CHECK_FUNCS(seteuid setegid setreuid setregid) AC_CHECK_FUNCS(uname gethostname chflags) AC_CHECK_FUNCS(mkfifo statfs statvfs door) AC_CHECK_FUNCS(sysinfo setsid sysconf) AC_CHECK_FUNCS(getzoneid getzonenamebyid) AC_CHECK_FUNCS(fpathconf) AC_CHECK_MEMBERS([struct stat.st_mtim, struct stat.st_mtimespec]) AC_CHECK_MEMBERS([struct stat.st_blocks]) AC_MSG_CHECKING([for PRIuMAX/PRIdMAX macros]) AC_EGREP_CPP([primacros_found], AC_INCLUDES_DEFAULT [#include #if defined(PRIuMAX) && defined(PRIdMAX) primacros_found #endif ], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) AC_MSG_RESULT(Unable to find out how to scan intmax_t/uintmax_t types)]) HW_FUNC_VSNPRINTF HW_FUNC_SNPRINTF HW_FUNC_VASPRINTF HW_FUNC_ASPRINTF dnl dirfd might be a function or a macro AC_CHECK_DECLS(dirfd, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_DIRENT_H # include #endif ]) AC_CHECK_FUNCS(dirfd, [], [ AC_MSG_CHECKING([for dirfd macro]) AC_EGREP_CPP([dirfd_found], AC_INCLUDES_DEFAULT [#ifdef HAVE_DIRENT_H # include #endif #ifdef dirfd dirfd_found #endif ], [AC_MSG_RESULT(yes) DIRFD_MACRO_FOUND=1], [AC_MSG_RESULT(no)]) if test x$DIRFD_MACRO_FOUND = x; then AC_LIBOBJ([dirfd]) fi]) AC_CHECK_FUNCS(jail_get) dnl dnl Various functions dnl AC_SEARCH_LIBS(setsockopt, socket) AC_SEARCH_LIBS(gethostent, nsl) AC_CHECK_FUNCS(socket) AC_CHECK_FUNCS(setsockopt) AC_CHECK_FUNCS(gethostent) AC_CHECK_TYPES(struct sockaddr_storage, [], [], [[ #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif]]) AC_CHECK_DECLS(getaddrinfo, [], [AC_LIBOBJ(getaddrinfo)], [[ #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif ]]) AC_CHECK_DECLS([[inet_ntop], [inet_pton]], [], [], [[#include ]]) AC_REPLACE_FUNCS(inet_ntop inet_pton) AC_CHECK_FUNCS(getifaddrs) AC_CHECK_FUNCS(getprocs64) AC_CHECK_FUNC(lchown, AC_DEFINE(HAVE_LCHOWN, 1, [Whether to use lchown(3) to change ownerships])) AC_CHECK_DECLS(pthread_attr_setstacksize, [], [], [[#include ]]) AC_REPLACE_FUNCS(pthread_attr_setstacksize) AC_CHECK_DECLS(pthread_sigmask, [], [], [[#include ]]) AC_REPLACE_FUNCS(pthread_sigmask) AC_CHECK_DECLS(sched_yield, [], [], [[#include ]]) AC_CHECK_FUNCS(sched_yield) AC_CHECK_DECLS([openat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([fstatat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([fchownat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([fchmodat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([readlinkat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_REPLACE_FUNCS(openat fstatat fchownat fchmodat readlinkat) AC_CHECK_DECLS([log2], [], [], [[#include ]]) AC_REPLACE_FUNCS(log2) dnl ###################################################################### dnl Required by cf-upgrade. It cannot be implemented in libcompat because dnl cf-upgrade does not link to any libraries except libutils and only dnl statically. dnl ###################################################################### AC_CHECK_FUNC(fexecve, AC_DEFINE(HAVE_FEXECVE, 1, [Whether to use fexecve(3) to execute a new process])) dnl ###################################################################### dnl These need declarations here, but will be defined in the dnl Enterprise Windows code. dnl ###################################################################### AC_CHECK_DECLS(alarm) AC_CHECK_DECLS(chmod) AC_CHECK_DECLS(chown) AC_CHECK_DECLS(fchmod) AC_CHECK_FUNCS(fchmod) AC_CHECK_DECLS(uname) AC_CHECK_DECLS(getuid) AC_CHECK_DECLS(getgid) AC_CHECK_DECLS(lstat) AC_CHECK_FUNCS(sleep) AC_CHECK_DECLS(socketpair, [], [], [[#include ]]) AC_CHECK_DECLS(fsync) AC_CHECK_DECLS(glob, [], [], [[#include ]]) dnl ###################################################################### dnl Check for sa_len in struct sockaddr dnl ###################################################################### AC_CHECK_MEMBERS([struct sockaddr.sa_len], , , [ #include #include ]) AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr],,, [ #include #include ]) dnl BSD uses sys/sysctl.h for CPU counting AC_CHECK_HEADERS(sys/sysctl.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) dnl ###################################################################### dnl Requirements for GetUptimeMinutes() to set $(sys.uptime) dnl ###################################################################### dnl Linux sysinfo() call AC_CHECK_MEMBERS([struct sysinfo.uptime], , , [#include ]) dnl BSD uses sys/sysctl.h to get time-of-boot AC_CHECK_HEADERS(sys/sysctl.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) dnl Solaris uses kstat.h to get time-of-boot AC_CHECK_HEADERS(kstat.h) dnl SystemV way to get uptime, highly portable AC_CHECK_HEADERS(utmp.h) dnl POSIX way to get uptime AC_CHECK_HEADERS(utmpx.h) dnl ###################################################################### dnl Fancy new Linux syscalls for file/data copying dnl ###################################################################### AC_CHECK_HEADERS([linux/fs.h]) AC_CHECK_DECLS([FICLONE], [], [], [#include ]) AC_CHECK_DECLS([SEEK_DATA], [], [], [ #define _GNU_SOURCE #include ]) AC_CHECK_DECLS([FALLOC_FL_PUNCH_HOLE], [], [], [ #define _GNU_SOURCE #include ]) AC_CHECK_HEADERS([sys/sendfile.h]) AC_CHECK_FUNCS([sendfile]) AC_CHECK_FUNCS([copy_file_range]) dnl ####################################################################### dnl Newer BSD systems don't have a compatible rtentry - use ortentry dnl ####################################################################### rtry=none AC_MSG_CHECKING(for either struct rtentry or struct ortentry) AC_EGREP_HEADER(rtentry, net/route.h, rtry=rtentry) if test "$rtry" = rtentry; then AC_DEFINE(HAVE_RTENTRY, 1, [Do we have any route entry structure?]) fi AC_EGREP_HEADER(ortentry, net/route.h, rtry=ortentry) if test "$rtry" = ortentry; then AC_DEFINE(HAVE_ORTENTRY, 1, [The old route entry structure in newer BSDs]) fi AC_MSG_RESULT([$rtry]) dnl ####################################################################### dnl Enable extended attributes. Used for SELinux and ACLs dnl ####################################################################### AC_CHECK_FUNCS(llistxattr, [AC_DEFINE(WITH_XATTR, 1, [Define if you have a libc that supports extended attributes])]) AC_CHECK_HEADERS([attr/xattr.h sys/xattr.h]) AC_MSG_CHECKING([whether xattr functions have extra arguments]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include #include ], [(void)llistxattr("", 0, 0, 0); (void)lgetxattr("", "", 0, 0, 0, 0); (void)lsetxattr("", "", "", 0, 0, 0); (void)lremovexattr("", "", 0);])], [AC_DEFINE(WITH_XATTR_EXTRA_ARGS, 1, [Define if your xattr implementation has extra arguments])] [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) dnl ####################################################################### dnl Check for "fancy"(new) C compiler options dnl ####################################################################### saved_CFLAGS="$CFLAGS" CFLAGS="-Werror -Wno-tautological-constant-out-of-range-compare" AC_MSG_CHECKING([whether compiler supports -Wno-tautological-constant-out-of-range-compare]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], [AC_MSG_RESULT([yes])] [NO_TAUTOLOGICAL_CC_OPTION="-Wno-tautological-constant-out-of-range-compare"], [AC_MSG_RESULT([no])] [NO_TAUTOLOGICAL_CC_OPTION=""] ) CFLAGS="$saved_CFLAGS" AC_SUBST([NO_TAUTOLOGICAL_CC_OPTION]) dnl ###################################################################### dnl Give the chance to enable SELINUX dnl ###################################################################### AC_ARG_ENABLE([selinux], [AS_HELP_STRING([--enable-selinux], [Deprecated. SELinux support is always enabled])]) dnl ###################################################################### dnl OS specific stuff dnl ###################################################################### case "$target_os" in solaris2.8|solaris2.9) AC_DEFINE(_XOPEN_SOURCE, 500, [UNIX 98]) AC_DEFINE(__EXTENSIONS__, 1, [Extended UNIX 98 interfaces]) ;; solaris2.10|solaris2.11) AC_DEFINE(_XOPEN_SOURCE, 600, [SUSv3]) AC_DEFINE(__EXTENSIONS__, 1, [Extended UNIX 98 interfaces]) ;; hpux*|hp-ux*) dnl pstat* functions may fail with EOVERFLOW without this. AC_DEFINE(_PSTAT64, 1, [Enable wide data structures everywhere]) ;; aix*) CPPFLAGS="$CPPFLAGS -w" ;; linux*|*bsd*|*gnu*) AC_CHECK_LIB(nss_nis, yp_get_default_domain) ;; freebsd*|dragonfly*) ;; netbsd*) ;; unicos*) ;; cray*) ;; qnx*) ;; openbsd*|obsd*) ;; sysv4.2MP|unix_sv*) ;; cygwin*) ;; mingw*) ;; sco*) ;; darwin*) ;; *) AC_MSG_ERROR(Unknown system type $target_os) ;; esac m4_include([m4/cf3_platforms.m4]) dnl ##################################################################### dnl Configure directories dnl ##################################################################### AC_ARG_WITH(workdir, [ --with-workdir=WORKDIR default for internal (trusted) working directory ], [ if test "x$withval" != x ; then WORKDIR="$withval" LOGDIR="$withval" PIDDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in WORKDIR adl_RECURSIVE_EVAL("${WORKDIR}", WORKDIR) AC_DEFINE_UNQUOTED(WORKDIR, "${WORKDIR}", [Workdir location]) AC_SUBST(workdir, "${WORKDIR}") AC_ARG_WITH(masterdir, [ --with-masterdir=MASTERDIR default for internal masterfiles directory ], [ if test "x$withval" != x ; then MASTERDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in MASTERDIR adl_RECURSIVE_EVAL("${MASTERDIR}", MASTERDIR) AC_DEFINE_UNQUOTED(MASTERDIR, "${MASTERDIR}", [Masterfiles directory location]) AC_SUBST(masterdir, "${MASTERDIR}") AC_ARG_WITH(inputdir, [ --with-inputdir=INPUTDIR default for internal inputs directory ], [ if test "x$withval" != x ; then INPUTDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in INPUTDIR adl_RECURSIVE_EVAL("${INPUTDIR}", INPUTDIR) AC_DEFINE_UNQUOTED(INPUTDIR, "${INPUTDIR}", [Inputs directory location]) AC_SUBST(inputdir, "${INPUTDIR}") AC_ARG_WITH(datadir, [ --with-datadir=DATADIR default for internal data directory ], [ if test "x$withval" != x ; then DATADIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in DATADIR adl_RECURSIVE_EVAL("${DATADIR}", DATADIR) dnl There's a conflict on mingw where they have a type called DATADIR! AC_DEFINE_UNQUOTED(CF_DATADIR, "${DATADIR}", [Datadir location]) AC_SUBST(datadir, "${DATADIR}") AC_ARG_WITH(logdir, [ --with-logdir=LOGDIR default for internal log directory ], [ if test "x$withval" != x ; then LOGDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in LOGDIR adl_RECURSIVE_EVAL("${LOGDIR}", LOGDIR) AC_DEFINE_UNQUOTED(LOGDIR, "${LOGDIR}", [Logdir location]) AC_SUBST(logdir, "${LOGDIR}") AC_ARG_WITH(piddir, [ --with-piddir=PIDDIR default for internal pid directory ], [ if test "x$withval" != x ; then PIDDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in PIDDIR adl_RECURSIVE_EVAL("${PIDDIR}", PIDDIR) AC_DEFINE_UNQUOTED(PIDDIR, "${PIDDIR}", [piddir location]) AC_SUBST(piddir, "${PIDDIR}") AC_ARG_WITH(statedir, [ --with-statedir=STATEDIR default for internal state directory ], [ if test "x$withval" != x ; then STATEDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in STATEDIR adl_RECURSIVE_EVAL("${STATEDIR}", STATEDIR) AC_DEFINE_UNQUOTED(STATEDIR, "${STATEDIR}", [State directory location]) AC_SUBST(statedir, "${STATEDIR}") AC_ARG_WITH(shell, [AS_HELP_STRING([--with-shell=PATH], [Specify path to POSIX-compatible shell (if not /bin/sh)])], [], [with_shell=/bin/sh]) dnl Expand ${prefix} and whatnot in bindir adl_RECURSIVE_EVAL("${bindir}", bindir) AC_DEFINE_UNQUOTED(BINDIR, "${bindir}", [binaries location]) AC_SUBST(bindir, "${bindir}") if test "x$with_shell" = "xno"; then AC_MSG_ERROR([Please specify full path to POSIX-compatible shell]) fi AC_DEFINE_UNQUOTED(SHELL_PATH, "$with_shell", [Path to the POSIX-compatible shell]) dnl ##################################################################### dnl Hostname and Version stuff dnl ##################################################################### AC_PATH_PROG(HOSTNAME, hostname, "", $PATH) AC_DEFINE_UNQUOTED(AUTOCONF_HOSTNAME, "`$HOSTNAME`", [Special CFEngine symbol]) AC_DEFINE_UNQUOTED(AUTOCONF_SYSNAME, "$target_os", [Speial CFEngine symbol]) dnl ##################################################################### dnl xen cpuid-based hvm detection dnl ##################################################################### AC_MSG_CHECKING(for Xen cpuid-based HVM detection) if test x"$GCC" = "xyes"; then case $host_cpu in i[[3456]]86*|x86_64*|amd64) AC_DEFINE(XEN_CPUID_SUPPORT, 1, [Define if XEN cpuid-based HVM detection is available.]) AC_MSG_RESULT(yes) ;; *) AC_MSG_RESULT(no) ;; esac else AC_MSG_RESULT(no) fi dnl dnl Code coverage dnl AC_ARG_ENABLE(coverage, AS_HELP_STRING([--enable-coverage], [Enable code coverage]), [use_coverage=$enableval], [use_coverage=no]) if test "x$use_coverage" = "xyes"; then if test "$GCC" != "yes"; then AC_MSG_ERROR([GCC is required for --enable-coverage]) fi AC_CHECK_PROG(LCOV, lcov, lcov) AC_CHECK_PROG(LCOV_GENHTML, genhtml, genhtml) if test -z "$LCOV"; then AC_MSG_ERROR([Cannot find lcov from the LTP package]) fi if test -z "$LCOV_GENHTML"; then AC_MSG_ERROR([Could not find genhtml from the LTP package]) fi dnl Remove all optimization flags from CFLAGS changequote({,}) CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` changequote([,]) dnl Add the special gcc flags CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov" # Need to set ENABLE_COVERAGE so that tests/unit/Makefile.am can adapt for one # test which needs gcov stubs if core not built with coverage. AM_CONDITIONAL([ENABLE_COVERAGE], true) else AM_CONDITIONAL([ENABLE_COVERAGE], false) fi dnl ###################################################################### dnl Collect all the options dnl ###################################################################### CORE_CPPFLAGS="$PCRE2_CPPFLAGS $OPENSSL_CPPFLAGS $LIBYAML_CPPFLAGS $CPPFLAGS" CORE_CFLAGS="$PCRE2_CFLAGS $OPENSSL_CFLAGS $LIBYAML_CFLAGS $CFLAGS" CORE_LDFLAGS="$PCRE2_LDFLAGS $OPENSSL_LDFLAGS $LIBYAML_LDFLAGS $LDFLAGS" CORE_LIBS="$PCRE2_LIBS $OPENSSL_LIBS $LIBYAML_LIBS $LIBS" dnl ###################################################################### dnl Make them available to subprojects. dnl ###################################################################### AC_SUBST([CORE_CPPFLAGS]) AC_SUBST([CORE_CFLAGS]) AC_SUBST([CORE_LDFLAGS]) AC_SUBST([CORE_LIBS]) # # Populate contents of config.post.h # AC_SUBST(post_macros) AM_SUBST_NOTMAKE(post_macros) dnl ###################################################################### dnl Check how file descriptor transfers are supported between proceses. dnl ###################################################################### AC_CHECK_MEMBER([struct msghdr.msg_control], [AC_DEFINE([HAVE_MSGHDR_MSG_CONTROL], [1], [Define to 1 if SCM_RIGHTS supported])], [AC_DEFINE([HAVE_NO_MSGHDR_MSG_CONTROL], [1], [Define to 1 if SCM_RIGHTS support])], [[#include #include ]]) AC_CHECK_MEMBER([struct msghdr.msg_accrights], [AC_DEFINE([HAVE_MSGHDR_ACCRIGHTS], [1], [Define to 1 if BSD .msg_accrights supported])], [AC_DEFINE([HAVE_NO_MSGHDR_ACCRIGHTS], [1], [Define to 1 if no BSD .msg_accrights support])], [[#include #include ]]) dnl ###################################################################### dnl Summarize dnl ###################################################################### AC_MSG_RESULT( ) AC_MSG_RESULT(Summary:) AC_MSG_RESULT(> Version: AC_PACKAGE_VERSION) AC_MSG_RESULT([> Optional libraries]) AC_MSG_RESULT([-> OpenSSL: $OPENSSL_PATH]) AC_MSG_RESULT([-> PCRE2: $PCRE2_PATH]) if test "x$ac_cv_lib_yaml_yaml_parser_initialize" = xyes; then AC_MSG_RESULT([-> libyaml: $LIBYAML_PATH]) else AC_MSG_RESULT([-> libyaml: disabled]) fi AC_MSG_RESULT( ) dnl ###################################################################### dnl Now make the Makefiles dnl ###################################################################### AC_CONFIG_FILES([Makefile libcompat/Makefile libutils/Makefile libutils/writer.h libutils/clockid_t.h libutils/regex.h libutils/glob_lib.h libutils/json-yaml.h config.post.h tests/Makefile tests/static-check/Makefile tests/unit/Makefile]) AC_OUTPUT AC_MSG_RESULT(DONE: Configuration done. Run make/gmake to build libntech.) cfengine-3.24.2/libntech/config.post.h.in0000644000000000000000000000210515010704254020151 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * Macros which cannot be declared before inclusion of system headers from * config.h (say, #define mkdir rpl_mkdir) due to conflicts arising from it, * are declared here. */ @post_macros@ cfengine-3.24.2/libntech/libutils/0000755000000000000000000000000015010704322016767 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/libutils/threaded_stack.c0000644000000000000000000001333515010704254022111 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include /** @struct ThreadedStack_ @brief A simple thread-safe stack data structure. Can push, pop, and copy. Also has functions for showing current stack size and capacity, and if a stack is empty. If the amount of pushed elements exceed the capacity, it will be multiplied by EXPAND_FACTOR and reallocated with the new capacity. When destroying the stack, destroys each element with the ItemDestroy function specified -- unless it is NULL -- and then proceeds to destroy the lock, before freeing the data array and the stack itself. */ struct ThreadedStack_ { Stack base; pthread_mutex_t *lock; /**< Thread lock for accessing data. */ }; ThreadedStack *ThreadedStackNew(size_t initial_capacity, void (ItemDestroy) (void *item)) { ThreadedStack *stack = xmalloc(sizeof(ThreadedStack)); pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to use error-checking mutexes for stack, " "falling back to normal ones (pthread_mutexattr_settype: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); } stack->lock = xmalloc(sizeof(pthread_mutex_t)); ret = pthread_mutex_init(stack->lock, &attr); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize mutex (pthread_mutex_init: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_destroy(&attr); free(stack); return NULL; } pthread_mutexattr_destroy(&attr); StackInit(&(stack->base), initial_capacity, ItemDestroy); return stack; } void ThreadedStackDestroy(ThreadedStack *stack) { if (stack != NULL) { ThreadLock(stack->lock); DestroyRange(&(stack->base), 0, stack->base.size); ThreadUnlock(stack->lock); ThreadedStackSoftDestroy(stack); } } void ThreadedStackSoftDestroy(ThreadedStack *stack) { if (stack != NULL) { if (stack->lock != NULL) { pthread_mutex_destroy(stack->lock); free(stack->lock); } free(stack->base.data); free(stack); } } void *ThreadedStackPop(ThreadedStack *stack) { assert(stack != NULL); ThreadLock(stack->lock); void *item = StackPop(&(stack->base)); ThreadUnlock(stack->lock); return item; } void ThreadedStackPush(ThreadedStack *stack, void *item) { assert(stack != NULL); ThreadLock(stack->lock); StackPush(&(stack->base), item); ThreadUnlock(stack->lock); } size_t ThreadedStackPushReportCount(ThreadedStack *stack, void *item) { assert(stack != NULL); ThreadLock(stack->lock); const size_t size = StackPushReportCount(&(stack->base), item); ThreadUnlock(stack->lock); return size; } size_t ThreadedStackCount(ThreadedStack const *stack) { assert(stack != NULL); ThreadLock(stack->lock); size_t count = StackCount(&(stack->base)); ThreadUnlock(stack->lock); return count; } size_t ThreadedStackCapacity(ThreadedStack const *stack) { assert(stack != NULL); ThreadLock(stack->lock); size_t capacity = StackCapacity(&(stack->base)); ThreadUnlock(stack->lock); return capacity; } bool ThreadedStackIsEmpty(ThreadedStack const *stack) { assert(stack != NULL); ThreadLock(stack->lock); bool const empty = StackIsEmpty(&(stack->base)); ThreadUnlock(stack->lock); return empty; } ThreadedStack *ThreadedStackCopy(ThreadedStack const *stack) { assert(stack != NULL); ThreadLock(stack->lock); ThreadedStack *new_stack = xmemdup(stack, sizeof(ThreadedStack)); new_stack->base.data = xmalloc(sizeof(void *) * stack->base.capacity); memcpy(new_stack->base.data, stack->base.data, sizeof(void *) * stack->base.size); pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to use error-checking mutexes for stack, " "falling back to normal ones (pthread_mutexattr_settype: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); } new_stack->lock = xmalloc(sizeof(pthread_mutex_t)); ret = pthread_mutex_init(new_stack->lock, &attr); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize mutex (pthread_mutex_init: %s)", GetErrorStrFromCode(ret)); free(new_stack->lock); free(new_stack); new_stack = NULL; } pthread_mutexattr_destroy(&attr); ThreadUnlock(stack->lock); return new_stack; } cfengine-3.24.2/libntech/libutils/json-yaml.h.in0000644000000000000000000000336415010704254021470 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_JSON_YAML_H #define CFENGINE_JSON_YAML_H #include /* Set by ./configure allowing us to avoid #include here. */ @HAVE_LIBYAML_DEFINE@ #ifdef HAVE_LIBYAML #include #endif /** @brief Parse a YAML string to create a JsonElement @param data [in Pointer to the string to parse @param json_out Resulting JSON object @returns See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParseYamlString(const char **data, JsonElement **json_out); /** * @brief Convenience function to parse JSON from a YAML file * @param path Path to the file * @param size_max Maximum size to read in memory * @param json_out Resulting JSON object * @return See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParseYamlFile(const char *path, size_t size_max, JsonElement **json_out); #endif // CFENGINE_JSON_YAML_H cfengine-3.24.2/libntech/libutils/cleanup.h0000644000000000000000000000214315010704254020573 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CLEANUP_H #define CFENGINE_CLEANUP_H typedef void (*CleanupFn)(void); void CallCleanupFunctions(void); void DoCleanupAndExit(int ret) FUNC_ATTR_NORETURN; void RegisterCleanupFunction(CleanupFn fn); #endif cfengine-3.24.2/libntech/libutils/ring_buffer.c0000644000000000000000000000672515010704254021441 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include struct RingBuffer_ { void *(*copy)(const void *data); void (*destroy)(void *data); void **data; size_t capacity; size_t end; size_t len; }; struct RingBufferIterator_ { const RingBuffer *buf; size_t num_read; }; RingBuffer *RingBufferNew(size_t capacity, void *(*copy)(const void *), void (*destroy)(void *)) { assert(capacity > 0); RingBuffer *buf = xmalloc(sizeof(RingBuffer)); buf->copy = copy; buf->destroy = destroy; buf->data = xcalloc(capacity, sizeof(void *)); buf->capacity = MAX(capacity, 1); buf->len = 0; buf->end = 0; return buf; } void RingBufferAppend(RingBuffer *buf, void *item) { if (buf->data[buf->end] && buf->destroy) { buf->destroy(buf->data[buf->end]); } buf->data[buf->end] = buf->copy ? buf->copy(item) : item; buf->end = (buf->end + 1) % buf->capacity; if (buf->len < buf->capacity) { buf->len++; } } void RingBufferClear(RingBuffer *buf) { if (buf->destroy) { for (size_t i = 0; i < buf->capacity; i++) { if (buf->data[i]) { buf->destroy(buf->data[i]); buf->data[i] = NULL; } } } buf->end = 0; buf->len = 0; } size_t RingBufferLength(const RingBuffer *buf) { return buf->len; } bool RingBufferIsFull(const RingBuffer *buf) { return buf->len == buf->capacity; } const void *RingBufferHead(const RingBuffer *buf) { if (RingBufferLength(buf) == 0) { return NULL; } if (buf->end == 0) { return buf->data[buf->capacity - 1]; } else { return buf->data[buf->end - 1]; } } RingBufferIterator *RingBufferIteratorNew(const RingBuffer *buf) { RingBufferIterator *iter = xmalloc(sizeof(RingBufferIterator)); iter->buf = buf; iter->num_read = 0; return iter; } void RingBufferDestroy(RingBuffer *buf) { if (buf) { RingBufferClear(buf); free(buf->data); free(buf); } } void RingBufferIteratorDestroy(RingBufferIterator *iter) { if (iter) { free(iter); } } const void *RingBufferIteratorNext(RingBufferIterator *iter) { if ((iter->buf->len - iter->num_read) == 0) { return NULL; } size_t offset = iter->num_read; if (RingBufferIsFull(iter->buf)) { offset = (iter->buf->end + iter->num_read) % iter->buf->capacity; } const void *data = iter->buf->data[offset]; iter->num_read++; return data; } cfengine-3.24.2/libntech/libutils/list.c0000644000000000000000000005203415010704254020116 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include struct ListNode { void *payload; struct ListNode *next; struct ListNode *previous; }; typedef struct ListNode ListNode; struct ListMutableIterator { int valid; ListNode *current; List *origin; }; struct List { // Number of nodes int node_count; // Incremental number that keeps track of the state of the list, only used for light iterators unsigned int state; // Nodes ListNode *list; // Link to the first element ListNode *first; // Link to the last element ListNode *last; // This function is used to compare two elements int (*compare)(const void *a, const void *b); // This function is used whenever there is need to perform a deep copy void (*copy)(const void *source, void **destination); // This function can be used to destroy the elements at destruction time void (*destroy)(void *element); // Reference counting RefCount *ref_count; // Mutable iterator. ListMutableIterator *iterator; }; struct ListIterator { ListNode *current; List *origin; unsigned int state; }; #define IsIteratorValid(iterator) \ iterator->state != iterator->origin->state #define IsMutableIteratorValid(iterator) \ iterator->valid == 0 #define ChangeListState(list) \ list->state++ /* * Helper method to detach lists. */ static void ListDetach(List *list) { assert(list != NULL); int shared = RefCountIsShared(list->ref_count); if (shared) { /* * 1. Perform a deep copy (expensive!) * 2. Detach */ ListNode *p = NULL, *q = NULL, *newList = NULL, *first = NULL, *last = NULL; for (p = list->list; p; p = p->next) { if (newList) { q->next = (ListNode *)xmalloc(sizeof(ListNode)); q->next->previous = q; q->next->next = NULL; q = q->next; last = q; if (p->payload) { if (list->copy) { list->copy(p->payload, &q->payload); } else { q->payload = p->payload; } } } else { // First element newList = (ListNode *)xmalloc(sizeof(ListNode)); newList->next = NULL; newList->previous = NULL; first = newList; last = newList; if (p->payload) { if (list->copy) { list->copy(p->payload, &newList->payload); } else { newList->payload = p->payload; } } q = newList; } } list->list = newList; list->first = first; list->last = last; // Ok, we have our own copy of the list. Now we detach. RefCountDetach(list->ref_count, list); list->ref_count = NULL; RefCountNew(&list->ref_count); RefCountAttach(list->ref_count, list); } } List *ListNew(int (*compare)(const void *, const void *), void (*copy)(const void *, void **), void (*destroy)(void *)) { List *list = NULL; list = (List *)xmalloc(sizeof(List)); list->list = NULL; list->first = NULL; list->last = NULL; list->node_count = 0; list->iterator = NULL; list->state = 0; list->compare = compare; list->destroy = destroy; list->copy = copy; RefCountNew(&list->ref_count); RefCountAttach(list->ref_count, list); return list; } int ListDestroy(List **list) { if (!list || !(*list)) { return 0; } int shared = RefCountIsShared((*list)->ref_count); if (shared) { /* * We just detach from the list. */ RefCountDetach((*list)->ref_count, (*list)); } else { // We are the only ones using the list, we can delete it. ListNode *node = NULL; ListNode *p = NULL; for (node = (*list)->first; node; node = p) { if ((*list)->destroy) { (*list)->destroy(node->payload); } p = node->next; free(node); } RefCountDestroy(&(*list)->ref_count); } free((*list)); *list = NULL; return 0; } int ListCopy(List *origin, List **destination) { if (origin == NULL || destination == NULL) { return -1; } /* * The first thing we check is the presence of a copy function. * Without that function we need to abort the operation. */ if (!origin->copy) { return -1; } *destination = (List *)xmalloc(sizeof(List)); (*destination)->list = origin->list; (*destination)->first = origin->first; (*destination)->last = origin->last; (*destination)->node_count = origin->node_count; (*destination)->state = origin->state; (*destination)->destroy = origin->destroy; (*destination)->copy = origin->copy; (*destination)->compare = origin->compare; /* * We do not copy iterators. */ (*destination)->iterator = NULL; /* We have a copy function, we can perform a shallow copy. */ RefCountAttach(origin->ref_count, (*destination)); (*destination)->ref_count = origin->ref_count; return 0; } int ListPrepend(List *list, void *payload) { ListNode *node = NULL; if (list == NULL) { return -1; } ListDetach(list); node = (ListNode *)xmalloc(sizeof(ListNode)); node->payload = payload; node->previous = NULL; if (list->list) { // We have elements node->next = list->list; list->list->previous = node; } else { // First element node->next = NULL; list->last = node; } list->list = node; list->first = node; list->node_count++; return 0; } int ListAppend(List *list, void *payload) { ListNode *node = NULL; if (list == NULL) { return -1; } ListDetach(list); node = (ListNode *)xmalloc(sizeof(ListNode)); node->next = NULL; node->payload = payload; if (list->last) { // We have elements node->previous = list->last; list->last->next = node; } else { // First element node->previous = NULL; list->list = node; list->first = node; } list->last = node; list->node_count++; return 0; } /* * We split the code into several helper functions. * These functions are not exported to the outside world * since it does not make sense for them to be used in other * places. */ static int ListFindNode(List *list, void *payload) { if (list == NULL) { return -1; } ListNode *node = NULL; int found = 0; for (node = list->list; node; node = node->next) { if (!node->payload) { continue; } if (list->compare) { if (!list->compare(node->payload, payload)) { found = 1; break; } } else { if (node->payload == payload) { found = 1; break; } } } return found; } static void ListUpdateListState(List *list) { assert(list != NULL); list->node_count--; ChangeListState(list); } int ListRemove(List *list, void *payload) { if (list == NULL || payload == NULL) { return -1; } ListNode *node = NULL; /* * This is a complicated matter. We could detach the list before * we know that we have a new node, but that will mean that we * might have copied the whole list without real reasons. On the * other hand, it saves us a whole traversal of the list if we * just do it. */ int found = ListFindNode(list, payload); if (!found) { return -1; } found = 0; ListDetach(list); node = NULL; /* * We need to find the node again since we have a new list. * In theory we don't have to worry about the existence of the node, * since the list has not changed, it might have been copied but * it is still the same as before. */ for (node = list->list; node; node = node->next) { if (list->compare) { if (!list->compare(node->payload, payload)) { found = 1; break; } } else { if (node->payload == payload) { found = 1; break; } } } /* * This is nearly impossible, so we will only assert it. */ assert(node); assert(found == 1); /* * Before deleting the node we have to update the mutable iterator. * We might need to advance it! */ if (list->iterator) { if (list->iterator->current == node) { /* * So lucky, it is the same node! * Move the iterator so it is not dangling. * Rules for moving: * 1. Move forward. * 2. if not possible, move backward. * 3. If not possible, then invalidate the iterator. */ if (list->iterator->current->next) { list->iterator->current = list->iterator->current->next; } else if (list->iterator->current->previous) { list->iterator->current = list->iterator->current->previous; } else { list->iterator->valid = 0; } } } /* * Now, remove the node from the list and delete it. */ if (node->next && node->previous) { // Middle of the list node->next->previous = node->previous; node->previous->next = node->next; } else if (node->next) { // First element of the list list->list = node->next; list->first = node->next; node->next->previous = NULL; } else if (node->previous) { // Last element node->previous->next = NULL; list->last = node->previous; } else { // Single element list->list = NULL; list->first = NULL; list->last = NULL; } if (list->destroy && node->payload) { list->destroy(node->payload); } else { free (node->payload); } free(node); ListUpdateListState(list); return 0; } // Number of elements on the list int ListCount(const List *list) { return list != NULL ? list->node_count : -1; } /* * Functions for iterators */ ListIterator *ListIteratorGet(const List *list) { if (list == NULL) { return NULL; } // You cannot get an iterator for an empty list. if (!list->first) { return NULL; } ListIterator *iterator = NULL; iterator = (ListIterator *)xmalloc(sizeof(ListIterator)); iterator->current = list->list; // Remaining only works in one direction, we need two variables for this. iterator->origin = (List *)list; iterator->state = list->state; return iterator; } int ListIteratorDestroy(ListIterator **iterator) { if (!iterator || !(*iterator)) { return 0; } (*iterator)->current = NULL; free((*iterator)); *iterator = NULL; return 0; } int ListIteratorFirst(ListIterator *iterator) { if (iterator == NULL) { return -1; } if (IsIteratorValid(iterator)) { // The list has moved forward, the iterator is invalid now return -1; } iterator->current = iterator->origin->first; return 0; } int ListIteratorLast(ListIterator *iterator) { if (iterator == NULL) { return -1; } if (IsIteratorValid(iterator)) { // The list has moved forward, the iterator is invalid now return -1; } iterator->current = iterator->origin->last; return 0; } int ListIteratorNext(ListIterator *iterator) { if (iterator == NULL) { return -1; } if (IsIteratorValid(iterator)) { // The list has moved forward, the iterator is invalid now return -1; } // Ok, check if we are at the end if (iterator->current && iterator->current->next) { iterator->current = iterator->current->next; } else { return -1; } return 0; } int ListIteratorPrevious(ListIterator *iterator) { if (iterator == NULL) { return -1; } if (IsIteratorValid(iterator)) { // The list has moved forward, the iterator is invalid now return -1; } // Ok, check if we are at the end if (iterator->current && iterator->current->previous) { iterator->current = iterator->current->previous; } else { return -1; } return 0; } void *ListIteratorData(const ListIterator *iterator) { if (iterator == NULL) { return NULL; } if (IsIteratorValid(iterator)) { // The list has moved forward, the iterator is invalid now return NULL; } return iterator->current->payload; } bool ListIteratorHasNext(const ListIterator *iterator) { if (iterator == NULL) { return false; } if (IsIteratorValid(iterator)) { // The list has moved forward, the iterator is invalid now return false; } if (iterator->current->next) { return true; } return false; } bool ListIteratorHasPrevious(const ListIterator *iterator) { if (iterator == NULL) { return false; } if (IsIteratorValid(iterator)) { // The list has moved forward, the iterator is invalid now return false; } if (iterator->current->previous) { return true; } return false; } /* * Mutable iterator operations */ ListMutableIterator *ListMutableIteratorGet(List *list) { if (list == NULL) { return NULL; } if (list->iterator) { // Only one iterator at a time return NULL; } // You cannot get an iterator for an empty list. if (!list->first) { return NULL; } ListMutableIterator *iterator = NULL; iterator = (ListMutableIterator *)xmalloc(sizeof(ListMutableIterator)); iterator->current = list->first; iterator->origin = list; iterator->valid = 1; list->iterator = iterator; return iterator; } int ListMutableIteratorRelease(ListMutableIterator **iterator) { if (iterator && *iterator) { (*iterator)->origin->iterator = NULL; free (*iterator); *iterator = NULL; } return 0; } int ListMutableIteratorFirst(ListMutableIterator *iterator) { if (iterator == NULL) { return -1; } if (IsMutableIteratorValid(iterator)) { return -1; } iterator->current = iterator->origin->first; return 0; } int ListMutableIteratorLast(ListMutableIterator *iterator) { if (iterator == NULL) { return -1; } if (IsMutableIteratorValid(iterator)) { return -1; } iterator->current = iterator->origin->last; return 0; } int ListMutableIteratorNext(ListMutableIterator *iterator) { if (iterator == NULL) { return -1; } if (IsMutableIteratorValid(iterator)) { return -1; } if (!iterator->current->next) { return -1; } iterator->current = iterator->current->next; return 0; } int ListMutableIteratorPrevious(ListMutableIterator *iterator) { if (iterator == NULL) { return -1; } if (IsMutableIteratorValid(iterator)) { return -1; } if (!iterator->current->previous) { return -1; } iterator->current = iterator->current->previous; return 0; } void *ListMutableIteratorData(const ListMutableIterator *iterator) { if (iterator == NULL) { return NULL; } if (IsMutableIteratorValid(iterator)) { return NULL; } return (void *)iterator->current->payload; } int ListMutableIteratorRemove(ListMutableIterator *iterator) { if (iterator == NULL) { return -1; } if (IsMutableIteratorValid(iterator)) { return -1; } ListDetach(iterator->origin); /* * Removing an element is not as simple as it sounds. We need to inform the list * and make sure we move out of the way. */ ListNode *node = NULL; if (iterator->current->next) { /* * We are not the last element, therefore we proceed as normal. */ node = iterator->current->next; } else { /* * We might be the last element or the only element on the list. * If we are the only element we do not destroy the element otherwise the iterator * would become invalid. */ if (iterator->current->previous) { /* * last element */ node = iterator->current->previous; } else { return -1; } } /* * Now, remove the node from the list and delete it. */ if (iterator->current->next && iterator->current->previous) { // Middle of the list iterator->current->next->previous = iterator->current->previous; iterator->current->previous->next = iterator->current->next; } else if (iterator->current->next) { // First element of the list iterator->origin->list = iterator->current->next; iterator->origin->first = iterator->current->next; iterator->current->next->previous = NULL; } else if (iterator->current->previous) { // Last element iterator->current->previous->next = NULL; iterator->origin->last = iterator->current->previous; } if (iterator->origin->destroy && iterator->current->payload) { iterator->origin->destroy(iterator->current->payload); } else { free (iterator->current->payload); } free(iterator->current); iterator->current = node; ListUpdateListState(iterator->origin); return 0; } int ListMutableIteratorPrepend(ListMutableIterator *iterator, void *payload) { if (iterator == NULL) { return -1; } if (IsMutableIteratorValid(iterator)) { return -1; } ListNode *node = NULL; node = (ListNode *)xmalloc(sizeof(ListNode)); ListDetach(iterator->origin); node->payload = payload; if (iterator->current->previous) { node->previous = iterator->current->previous; node->next = iterator->current; iterator->current->previous->next = node; iterator->current->previous = node; } else { // First element node->previous = NULL; node->next = iterator->current; iterator->current->previous = node; iterator->origin->first = node; iterator->origin->list = node; } iterator->origin->node_count++; return 0; } int ListMutableIteratorAppend(ListMutableIterator *iterator, void *payload) { if (iterator == NULL) { return -1; } if (IsMutableIteratorValid(iterator)) { return -1; } ListNode *node = NULL; node = (ListNode *)xmalloc(sizeof(ListNode)); ListDetach(iterator->origin); node->next = NULL; node->payload = payload; if (iterator->current->next) { node->next = iterator->current->next; node->previous = iterator->current; iterator->current->next->previous = node; iterator->current->next = node; } else { // Last element node->next = NULL; node->previous = iterator->current; iterator->current->next = node; iterator->origin->last = node; } iterator->origin->node_count++; return 0; } bool ListMutableIteratorHasNext(const ListMutableIterator *iterator) { return iterator != NULL && iterator->current->next; } bool ListMutableIteratorHasPrevious(const ListMutableIterator *iterator) { return iterator != NULL && iterator->current->previous; } cfengine-3.24.2/libntech/libutils/map.h0000644000000000000000000002314215010704254017723 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MAP_H #define CFENGINE_MAP_H #include #include /* * Map structure. Details are encapsulated. */ typedef struct Map_ Map; Map *MapNew(MapHashFn hash_fn, MapKeyEqualFn equal_fn, MapDestroyDataFn destroy_key_fn, MapDestroyDataFn destroy_value_fn); /** * Insert a key-value pair in the map. * If the key is in the map, value get replaced. Old value is destroyed. * * @retval true if key exists already. */ bool MapInsert(Map *map, void *key, void *value); /* * Returns whether the key is in the map. */ bool MapHasKey(const Map *map, const void *key); /* * Returns the value if the key is in map, NULL otherwise. To distinguish * between NULL as a value and NULL as a lack of entry, use MapHasKey. */ void *MapGet(Map *map, const void *key); /* * Remove key/value pair from the map. Returns 'true' if key was present in the * map. */ bool MapRemove(Map *map, const void *key); size_t MapSize(const Map *map); /* * MapIterator i = MapIteratorInit(map); * MapKeyValue *item; * while ((item = MapIteratorNext(&i))) * { * // do something with item->key, item->value * } */ typedef struct { bool is_array; union { ArrayMapIterator arraymap_iter; HashMapIterator hashmap_iter; }; } MapIterator; MapIterator MapIteratorInit(Map *map); MapKeyValue *MapIteratorNext(MapIterator *i); /* * Clear the whole map */ void MapClear(Map *map); /* * Destroy the map object. */ void MapDestroy(Map *map); /* * Destroy the map object without removing values. */ void MapSoftDestroy(Map *map); /** * Returns whether the two maps contain the same keys. * The values DO NOT have to be equal, just the keys. */ bool MapContainsSameKeys(const Map *map1, const Map *map2); void MapPrintStats(const Map *map, FILE *f); #define TYPED_MAP_DECLARE(Prefix, KeyType, ValueType) \ typedef struct \ { \ Map *impl; \ } Prefix##Map; \ \ Prefix##Map *Prefix##MapNew(void); \ bool Prefix##MapInsert(const Prefix##Map *map, KeyType key, ValueType value); \ bool Prefix##MapHasKey(const Prefix##Map *map, const KeyType key); \ ValueType Prefix##MapGet(const Prefix##Map *map, const KeyType key); \ bool Prefix##MapRemove(const Prefix##Map *map, const KeyType key); \ void Prefix##MapClear(Prefix##Map *map); \ size_t Prefix##MapSize(const Prefix##Map *map); \ void Prefix##MapDestroy(Prefix##Map *map); \ void Prefix##MapSoftDestroy(Prefix##Map *map); \ bool Prefix##MapContainsSameKeys(const Prefix##Map *map1, const Prefix##Map *map2); \ void Prefix##MapPrintStats(const Prefix##Map *map, FILE *f); \ #define TYPED_MAP_DEFINE(Prefix, KeyType, ValueType, hash_fn, equal_fn, \ destroy_key_fn, destroy_value_fn) \ \ Prefix##Map *Prefix##MapNew(void) \ { \ Prefix##Map *map = xcalloc(1, sizeof(Prefix##Map)); \ map->impl = MapNew(hash_fn, equal_fn, \ destroy_key_fn, destroy_value_fn); \ return map; \ } \ \ bool Prefix##MapInsert(const Prefix##Map *map, KeyType key, ValueType value) \ { \ assert(map); \ return MapInsert(map->impl, key, value); \ } \ \ bool Prefix##MapHasKey(const Prefix##Map *map, const KeyType key) \ { \ assert(map); \ return MapHasKey(map->impl, key); \ } \ \ ValueType Prefix##MapGet(const Prefix##Map *map, const KeyType key) \ { \ assert(map); \ return MapGet(map->impl, key); \ } \ \ bool Prefix##MapRemove(const Prefix##Map *map, const KeyType key) \ { \ assert(map); \ return MapRemove(map->impl, key); \ } \ \ void Prefix##MapClear(Prefix##Map *map) \ { \ assert(map); \ MapClear(map->impl); \ } \ \ size_t Prefix##MapSize(const Prefix##Map *map) \ { \ assert(map); \ return MapSize(map->impl); \ } \ \ void Prefix##MapDestroy(Prefix##Map *map) \ { \ if (map != NULL) \ { \ MapDestroy(map->impl); \ free(map); \ } \ } \ \ void Prefix##MapSoftDestroy(Prefix##Map *map) \ { \ if (map != NULL) \ { \ MapSoftDestroy(map->impl); \ free(map); \ } \ } \ \ bool Prefix##MapContainsSameKeys(const Prefix##Map *map1, const Prefix##Map *map2) \ { \ assert(map1); \ assert(map2); \ return MapContainsSameKeys(map1->impl, map2->impl); \ } \ \ void Prefix##MapPrintStats(const Prefix##Map *map, FILE *f) \ { \ assert(map); \ return MapPrintStats(map->impl, f); \ } \ TYPED_MAP_DECLARE(String, char *, char *) #endif cfengine-3.24.2/libntech/libutils/Makefile.am0000644000000000000000000000616715010704254021041 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libutils.la # TODO remove the openssl dependency! It's only there for base64 encoding. AM_CFLAGS = $(CORE_CFLAGS) $(PCRE2_CFLAGS) $(OPENSSL_CFLAGS) AM_CPPFLAGS = $(CORE_CPPFLAGS) $(PCRE2_CPPFLAGS) $(OPENSSL_CPPFLAGS) AM_LDFLAGS = $(CORE_LDFLAGS) $(PCRE2_LDFLAGS) $(OPENSSL_LDFLAGS) libutils_la_LIBADD = ../libcompat/libcompat.la $(PCRE2_LIBS) $(OPENSSL_LIBS) $(SYSTEMD_LOGGING_LIBS) $(LIBYAML_LIBS) libutils_la_SOURCES = \ alloc.c alloc.h \ array_map.c array_map_priv.h \ buffer.c buffer.h \ cleanup.c cleanup.h \ clockid_t.h \ compiler.h \ csv_writer.c csv_writer.h \ csv_parser.c csv_parser.h \ definitions.h \ deprecated.h \ dir.h dir_priv.h \ file_lib.c file_lib.h \ hash_map.c hash_map_priv.h \ hash_method.h \ ip_address.c ip_address.h \ json.c json.h json-priv.h \ json-pcre.h \ json-utils.c json-utils.h \ json-yaml.c json-yaml.h \ known_dirs.c known_dirs.h \ list.c list.h \ logging.c logging.h logging_priv.h \ man.c man.h \ map.c map.h map_common.h \ misc_lib.c misc_lib.h \ mustache.c mustache.h \ mutex.c mutex.h \ passopenfile.c passopenfile.h \ path.c path.h \ platform.h condition_macros.h \ printsize.h \ proc_keyvalue.c proc_keyvalue.h \ queue.c queue.h \ rb-tree.c rb-tree.h \ refcount.c refcount.h \ ring_buffer.c ring_buffer.h \ sequence.c sequence.h \ string_sequence.c string_sequence.h \ set.c set.h \ stack.c stack.h \ threaded_stack.c threaded_stack.h \ statistics.c statistics.h \ string_lib.c string_lib.h \ threaded_deque.c threaded_deque.h \ threaded_queue.c threaded_queue.h \ unicode.c unicode.h \ version_comparison.c version_comparison.h \ writer.c writer.h \ xml_writer.c xml_writer.h \ glob_lib.c glob_lib.h EXTRA_DIST = stack_base.c if WITH_OPENSSL libutils_la_SOURCES += \ encode.c encode.h \ hash.c hash.h endif if WITH_PCRE2 libutils_la_SOURCES += \ regex.c regex.h endif if !NT libutils_la_SOURCES += unix_dir.c endif if CYGWIN libutils_la_SOURCES += unix_dir.c endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = config.h.in cfengine-3.24.2/libntech/libutils/set.h0000644000000000000000000002117115010704254017741 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SET_H #define CFENGINE_SET_H #include #include #include #include // xvasprintf typedef Map Set; typedef MapIterator SetIterator; typedef void *(*SetElementCopyFn)(const void *); Set *SetNew(MapHashFn element_hash_fn, MapKeyEqualFn element_equal_fn, MapDestroyDataFn element_destroy_fn); void SetDestroy(Set *set); void SetAdd(Set *set, void *element); void SetJoin(Set *set, Set *otherset, SetElementCopyFn copy_function); bool SetContains(const Set *set, const void *element); bool SetRemove(Set *set, const void *element); void SetClear(Set *set); size_t SetSize(const Set *set); bool SetIsEqual(const Set *set1, const Set *set2); SetIterator SetIteratorInit(Set *set); void *SetIteratorNext(SetIterator *i); #define TYPED_SET_DECLARE(Prefix, ElementType) \ typedef struct \ { \ Set *impl; \ } Prefix##Set; \ typedef ElementType(*Prefix##CopyFn)(const ElementType); \ \ typedef SetIterator Prefix##SetIterator; \ \ Prefix##Set *Prefix##SetNew(void); \ void Prefix##SetAdd(const Prefix##Set *set, ElementType element); \ void Prefix##SetJoin(const Prefix##Set *set, const Prefix##Set *otherset, Prefix##CopyFn copy_function); \ bool Prefix##SetContains(const Prefix##Set *Set, const ElementType element); \ bool Prefix##SetRemove(const Prefix##Set *Set, const ElementType element); \ void Prefix##SetClear(Prefix##Set *set); \ size_t Prefix##SetSize(const Prefix##Set *set); \ bool Prefix##SetIsEqual(const Prefix##Set *set1, const Prefix##Set *set2); \ void Prefix##SetDestroy(Prefix##Set *set); \ Prefix##SetIterator Prefix##SetIteratorInit(Prefix##Set *set); \ ElementType Prefix##SetIteratorNext(Prefix##SetIterator *iter); \ #define TYPED_SET_DEFINE(Prefix, ElementType, hash_fn, equal_fn, destroy_fn) \ \ Prefix##Set *Prefix##SetNew(void) \ { \ Prefix##Set *set = xcalloc(1, sizeof(Prefix##Set)); \ set->impl = SetNew(hash_fn, equal_fn, destroy_fn); \ return set; \ } \ \ void Prefix##SetAdd(const Prefix##Set *set, ElementType element) \ { \ SetAdd(set->impl, (void *)element); \ } \ \ void Prefix##SetJoin(const Prefix##Set *set, const Prefix##Set *otherset, Prefix##CopyFn copy_function) \ { \ SetJoin(set->impl, otherset->impl, (SetElementCopyFn) copy_function); \ } \ \ bool Prefix##SetContains(const Prefix##Set *set, const ElementType element) \ { \ return SetContains(set->impl, element); \ } \ \ bool Prefix##SetRemove(const Prefix##Set *set, const ElementType element) \ { \ return SetRemove(set->impl, element); \ } \ \ void Prefix##SetClear(Prefix##Set *set) \ { \ SetClear(set->impl); \ } \ \ size_t Prefix##SetSize(const Prefix##Set *set) \ { \ return SetSize(set->impl); \ } \ \ bool Prefix##SetIsEqual(const Prefix##Set *set1, const Prefix##Set *set2) \ { \ return SetIsEqual(set1->impl, set2->impl); \ } \ \ void Prefix##SetDestroy(Prefix##Set *set) \ { \ if (set) \ { \ SetDestroy(set->impl); \ free(set); \ } \ } \ \ Prefix##SetIterator Prefix##SetIteratorInit(Prefix##Set *set) \ { \ return SetIteratorInit(set->impl); \ } \ \ ElementType Prefix##SetIteratorNext(Prefix##SetIterator *iter) \ { \ return SetIteratorNext(iter); \ } \ TYPED_SET_DECLARE(String, char *) void StringSetAddSplit(StringSet *set, const char *str, char delimiter); StringSet *StringSetFromString(const char *str, char delimiter); Buffer *StringSetToBuffer(StringSet *set, const char delimiter); JsonElement *StringSetToJson(const StringSet *set); /** * Convert a flat JSON array into a #StringSet. */ StringSet *JsonArrayToStringSet(const JsonElement *array); /** * Format and add string to set. * @param[in] set string set. * @param[in] fmt format string. * @param[in] va variable-length argument list. */ FUNC_ATTR_PRINTF(2, 3) static inline void StringSetAddF(StringSet *const set, const char *const fmt, ...) { assert(set != NULL); assert(fmt != NULL); va_list args; va_start(args, fmt); char *str; NDEBUG_UNUSED int ret = xvasprintf(&str, fmt, args); assert(ret >= 0); va_end(args); StringSetAdd(set, str); } #endif cfengine-3.24.2/libntech/libutils/mutex.c0000644000000000000000000000670015010704254020304 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* Log */ #include void __ThreadLock(pthread_mutex_t *mutex, const char *funcname, const char *filename, int lineno) { int result = pthread_mutex_lock(mutex); if (result != 0) { /* Since Log blocks on mutexes, using it would be unsafe. Therefore, we use fprintf instead */ fprintf(stderr, "Locking failure at %s:%d function %s! " "(pthread_mutex_lock: %s)", filename, lineno, funcname, GetErrorStrFromCode(result)); fflush(stdout); fflush(stderr); DoCleanupAndExit(101); } } void __ThreadUnlock(pthread_mutex_t *mutex, const char *funcname, const char *filename, int lineno) { int result = pthread_mutex_unlock(mutex); if (result != 0) { /* Since Log blocks on mutexes, using it would be unsafe. Therefore, we use fprintf instead */ fprintf(stderr, "Locking failure at %s:%d function %s! " "(pthread_mutex_unlock: %s)", filename, lineno, funcname, GetErrorStrFromCode(result)); fflush(stdout); fflush(stderr); DoCleanupAndExit(101); } } int __ThreadWait(pthread_cond_t *pcond, pthread_mutex_t *mutex, int timeout, const char *funcname, const char *filename, int lineno) { int result = 0; if (timeout == THREAD_BLOCK_INDEFINITELY) { result = pthread_cond_wait(pcond, mutex); } else { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += timeout; result = pthread_cond_timedwait(pcond, mutex, &ts); } if (result != 0) { if (result == ETIMEDOUT) { Log(LOG_LEVEL_DEBUG, "Thread condition timed out at %s:%d function %s! " "(pthread_cond_timewait): %s)", filename, lineno, funcname, GetErrorStrFromCode(result)); } else { /* Since Log blocks on mutexes, using it would be unsafe. Therefore, we use fprintf instead */ fprintf(stderr, "Failed to wait for thread condition at %s:%d function " "%s! (pthread_cond_(wait|timewait)): %s)", filename, lineno, funcname, GetErrorStrFromCode(result)); fflush(stdout); fflush(stderr); DoCleanupAndExit(101); } } return result; } cfengine-3.24.2/libntech/libutils/set.c0000644000000000000000000001345215010704254017737 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include // strlen() #include #include #include TYPED_SET_DEFINE(String, char *, StringHash_untyped, StringEqual_untyped, free) Set *SetNew(MapHashFn element_hash_fn, MapKeyEqualFn element_equal_fn, MapDestroyDataFn element_destroy_fn) { return MapNew(element_hash_fn, element_equal_fn, element_destroy_fn, NULL); } void SetDestroy(Set *set) { MapDestroy(set); } void SetAdd(Set *set, void *element) { assert(set != NULL); MapInsert(set, element, element); } bool SetContains(const Set *set, const void *element) { assert(set != NULL); return MapHasKey(set, element); } bool SetRemove(Set *set, const void *element) { assert(set != NULL); return MapRemove(set, element); } void SetClear(Set *set) { assert(set != NULL); MapClear(set); } size_t SetSize(const Set *set) { assert(set != NULL); return MapSize(set); } bool SetIsEqual(const Set *set1, const Set *set2) { assert(set1 != NULL); assert(set2 != NULL); return MapContainsSameKeys(set1, set2); } SetIterator SetIteratorInit(Set *set) { assert(set != NULL); return MapIteratorInit(set); } void *SetIteratorNext(SetIterator *i) { MapKeyValue *kv = MapIteratorNext(i); return kv ? kv->key : NULL; } void SetJoin(Set *set, Set *otherset, SetElementCopyFn copy_function) { assert(set != NULL); assert(otherset != NULL); if (set == otherset) return; SetIterator si = SetIteratorInit(otherset); void *ptr = NULL; for (ptr = SetIteratorNext(&si); ptr != NULL; ptr = SetIteratorNext(&si)) { if (copy_function != NULL) { ptr = copy_function(ptr); } SetAdd(set, ptr); } } Buffer *StringSetToBuffer(StringSet *set, const char delimiter) { assert(set != NULL); Buffer *buf = BufferNew(); StringSetIterator it = StringSetIteratorInit(set); const char *element = NULL; int pos = 0; int size = StringSetSize(set); char minibuf[2]; minibuf[0] = delimiter; minibuf[1] = '\0'; while ((element = StringSetIteratorNext(&it))) { BufferAppend(buf, element, strlen(element)); if (pos < size-1) { BufferAppend(buf, minibuf, sizeof(char)); } pos++; } return buf; } void StringSetAddSplit(StringSet *set, const char *str, char delimiter) { assert(set != NULL); if (str) // TODO: remove this inconsistency, add assert(str) { const char *prev = str; const char *cur = str; while (*cur != '\0') { if (*cur == delimiter) { size_t len = cur - prev; if (len > 0) { StringSetAdd(set, xstrndup(prev, len)); } else { StringSetAdd(set, xstrdup("")); } prev = cur + 1; } cur++; } if (cur > prev) { StringSetAdd(set, xstrndup(prev, cur - prev)); } } } StringSet *StringSetFromString(const char *str, char delimiter) { StringSet *set = StringSetNew(); StringSetAddSplit(set, str, delimiter); return set; } JsonElement *StringSetToJson(const StringSet *set) { assert(set != NULL); JsonElement *arr = JsonArrayCreate(StringSetSize(set)); StringSetIterator it = StringSetIteratorInit((StringSet *)set); const char *el = NULL; while ((el = StringSetIteratorNext(&it))) { JsonArrayAppendString(arr, el); } return arr; } static bool VisitJsonArrayFirst(ARG_UNUSED JsonElement *element, void *data) { /* We only want one array with items, so just make sure there are no items * in the string set yet. This doesn't fail if there is a nested array as * the first item in the top-level array, but let's just live with that for * the sake of simplicity. */ StringSet *set = data; return (StringSetSize(set) == 0); } static bool AddArrayItemToStringSet(JsonElement *element, void *data) { char *element_str = JsonPrimitiveToString(element); StringSet *set = data; if ((element_str != NULL) && (set != NULL)) { StringSetAdd(set, element_str); return true; } return false; } StringSet *JsonArrayToStringSet(const JsonElement *array) { assert(array != NULL); if (JsonGetType(array) != JSON_TYPE_ARRAY) { return NULL; } StringSet *ret = StringSetNew(); /* We know our visitor functions don't modify the given array so we can * safely type-cast the array to JsonElement* without 'const'. */ bool success = JsonWalk((JsonElement *) array, JsonErrorVisitor, VisitJsonArrayFirst, AddArrayItemToStringSet, ret); if (!success) { StringSetDestroy(ret); return NULL; } return ret; } cfengine-3.24.2/libntech/libutils/platform.h0000644000000000000000000005653415010704254021005 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PLATFORM_H #define CFENGINE_PLATFORM_H /* * Platform-specific definitions and declarations. * * INCLUDE THIS HEADER ALWAYS FIRST in order to define appropriate macros for * including system headers (such as _FILE_OFFSET_BITS). */ #ifdef HAVE_CONFIG_H # include #endif #define _GNU_SOURCE 1 #ifdef _WIN32 # define MAX_FILENAME 227 # define WINVER 0x501 # if defined(__CYGWIN__) # undef FD_SETSIZE # endif /* Increase select(2) FD limit from 64. It's documented and valid to do it * like that provided that we define it *before* including winsock2.h. */ # define FD_SETSIZE 4096 #else # define MAX_FILENAME 254 #endif #ifdef __MINGW32__ # include # include # include # include # include # include # include # include # include # include # include // for disphelper # ifndef SHUT_RDWR // for shutdown() # define SHUT_RDWR SD_BOTH # endif #endif /* Standard C. */ #include #include #include #include #include #include /* offsetof, size_t */ /* POSIX but available in all platforms. */ #include #include #ifdef HAVE_SYS_SYSMACROS_H # include #endif #include #include /* We now require a pthreads implementation. */ #include #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_UNAME # include #else # define _SYS_NMLN 257 struct utsname { char sysname[_SYS_NMLN]; char nodename[_SYS_NMLN]; char release[_SYS_NMLN]; char version[_SYS_NMLN]; char machine[_SYS_NMLN]; }; #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_SYS_SYSTEMINFO_H # include #endif #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HAVE_SYS_MOUNT_H # include #endif #ifdef HAVE_SYS_WAIT_H # include #endif #ifndef WEXITSTATUS # define WEXITSTATUS(s) ((unsigned)(s) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(s) (((s) & 255) == 0) #endif #ifndef WIFSIGNALED # define WIFSIGNALED(s) ((s) & 0) /* Can't use for BSD */ #endif #ifndef WTERMSIG # define WTERMSIG(s) ((s) & 0) #endif #include #include #ifdef HAVE_DIRENT_H # include #else # define dirent direct # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif #ifndef PATH_MAX # ifdef _MAX_PATH # define PATH_MAX _MAX_PATH # else # define PATH_MAX 4096 # endif #endif #include #ifdef __MINGW32__ # define LOG_LOCAL0 (16<<3) # define LOG_LOCAL1 (17<<3) # define LOG_LOCAL2 (18<<3) # define LOG_LOCAL3 (19<<3) # define LOG_LOCAL4 (20<<3) # define LOG_LOCAL5 (21<<3) # define LOG_LOCAL6 (22<<3) # define LOG_LOCAL7 (23<<3) # define LOG_USER (1<<3) # define LOG_DAEMON (3<<3) /* MinGW added this flag only in latest version. */ # ifndef IPV6_V6ONLY # define IPV6_V6ONLY 27 # endif // Not available in MinGW headers unless you raise WINVER and _WIN32_WINNT, but // that is very badly supported in MinGW ATM. ULONGLONG WINAPI GetTickCount64(void); #else /* !__MINGW32__ */ # include #endif #ifdef _AIX # ifndef ps2 # include # endif # include #endif #ifdef __sun # include # undef nfstype #include #ifndef timersub # define timersub(a, b, result) \ do \ { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) \ { \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ } while (0) #endif #endif #if !HAVE_DECL_DIRFD int dirfd(DIR *dirp); #endif /* strndup is defined as a macro on many systems */ #if !HAVE_DECL_STRNDUP # ifndef strndup char *strndup(const char *s, size_t n); # endif #endif #if !HAVE_DECL_STRNLEN size_t strnlen(const char *str, size_t maxlen); #endif #ifdef HAVE_UNISTD_H # include #endif #if !HAVE_DECL_STRLCPY size_t strlcpy(char *destination, const char *source, size_t size); #endif #if !HAVE_DECL_STRLCAT size_t strlcat(char *destination, const char *source, size_t size); #endif #if !HAVE_DECL_STRSEP char *strsep(char **stringp, const char *delim); #endif #if !HAVE_DECL_SOCKETPAIR int socketpair(int domain, int type, int protocol, int sv[2]); #endif #if !HAVE_DECL_FSYNC int fsync(int fd); #endif #if !HAVE_DECL_GLOB #define GLOB_NOSPACE 1 #define GLOB_ABORTED 2 #define GLOB_NOMATCH 3 typedef struct { size_t gl_pathc; /* Count of paths matched so far */ char **gl_pathv; /* List of matched pathnames. */ size_t gl_offs; } glob_t; int glob(const char *pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob); void globfree(glob_t *pglob); #endif #ifdef __APPLE__ # include # include #endif #ifdef HAVE_SYS_MALLOC_H # ifdef __APPLE__ # include # include # endif #else # ifdef HAVE_MALLOC_H # ifndef __OpenBSD__ # ifdef __FreeBSD__ # include # else # include # endif # endif # endif #endif #include #ifdef HAVE_VFS_H # include #endif #ifdef __hpux # include #endif #ifdef HAVE_UTIME_H # include /* use utime not utimes for portability */ #elif TIME_WITH_SYS_TIME # include # include #elif HAVE_SYS_TIME_H # include #elif ! defined(AOS) # include #endif #ifdef HAVE_TIME_H # include #endif #ifdef HAVE_SYS_TIME_H # include #endif #ifdef HAVE_SYS_RESOURCE_H # include #endif #ifndef __MINGW32__ # include # include #endif #ifdef HAVE_SYS_SOCKIO_H # include #endif /* Work around bug in HPUX system headers: "/usr/include/machine/sys/getppdp.h:65: error: array type has incomplete element type" */ #ifdef __hpux union mpinfou { int dummy; }; #endif #ifndef __MINGW32__ # include # include # include # include # include # include # include # include # include # if !defined __linux__ && !defined _WIN32 # include # undef sgi # include # endif #endif #ifdef __linux__ # ifdef HAVE_NET_ROUTE_H # include # else # include # endif # ifdef HAVE_NETINET_IN_H # include # else # include # endif # ifdef HAVE_NETINET_IP_H # include # else # include # endif #endif #ifdef __linux__ #define ARG_LINUX_ONLY #else #define ARG_LINUX_ONLY ARG_UNUSED #endif #ifndef CLOCK_REALTIME # define CLOCK_REALTIME 1 #endif #include #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif # ifndef _SC_THREAD_STACK_MIN # define _SC_THREAD_STACK_MIN PTHREAD_STACK_MIN #endif #ifndef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_MUTEX_INITIALIZER #endif #ifdef HAVE_ENDIAN_H # include #endif #if !HAVE_DECL_LE32TOH static inline uint32_t ByteSwap32(uint32_t le32uint) { uint32_t be32uint; unsigned char *le_ptr = (unsigned char *)&le32uint; unsigned char *be_ptr = (unsigned char *)&be32uint; be_ptr[0] = le_ptr[3]; be_ptr[1] = le_ptr[2]; be_ptr[2] = le_ptr[1]; be_ptr[3] = le_ptr[0]; return be32uint; } # ifdef WORDS_BIGENDIAN # ifndef le32toh # define le32toh(x) ByteSwap32(x) # endif # ifndef htole32 # define htole32(x) ByteSwap32(x) # endif # else # ifndef le32toh # define le32toh(x) (x) # endif # ifndef htole32 # define htole32(x) (x) # endif # endif #endif // !HAVE_DECL_LE32TOH #if !HAVE_DECL_CLOSEFROM int closefrom(int fd); #endif #if !HAVE_DECL_PTHREAD_ATTR_SETSTACKSIZE int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); #endif #ifdef HAVE_SCHED_H # include #endif #if defined(HAVE_SYS_XATTR_H) # include #elif defined(HAVE_ATTR_XATTR_H) # include #endif #ifndef MIN # define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX # define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef INADDR_NONE # define INADDR_NONE ((unsigned long int) 0xffffffff) #endif #ifndef HAVE_SETEGID int setegid(gid_t gid); #endif #if !HAVE_DECL_UNAME int uname(struct utsname *buf); #endif #if !HAVE_DECL_GETUID uid_t getuid(void); #endif #if !HAVE_DECL_GETGID gid_t getgid(void); #endif #if !HAVE_DECL_FGETGRENT struct group *fgetgrent(FILE *stream); #endif #if !HAVE_DECL_DRAND48 double drand48(void); #endif #if !HAVE_DECL_SRAND48 void srand48(long seed); #endif #if !HAVE_DECL_CLOCK_GETTIME int clock_gettime(clockid_t clock_id, struct timespec *tp); #endif #if !HAVE_DECL_REALPATH /** * WARNING realpath() has varying behaviour among platforms. * - Do not use it to convert relative paths to absolute * (Solaris under certain conditions will return relative path). * - Do not use it to check existence of file * (on *BSD the last component of the path may not exist). * Use it only to resolve all symlinks and canonicalise filename, * i.e. remove double '/' and "/./" and "/../". * * @TODO what we need is a resolvepath(2) cross-platform implementation. */ # if defined (__MINGW32__) # define realpath(N,R) _fullpath((R), (N), PATH_MAX) # endif #endif #if !HAVE_DECL_LSTAT int lstat(const char *file_name, struct stat *buf); #endif #if !HAVE_DECL_SLEEP unsigned int sleep(unsigned int seconds); #endif #if !HAVE_DECL_ROUND double round(double x); #endif #if !HAVE_DECL_NANOSLEEP int nanosleep(const struct timespec *req, struct timespec *rem); #endif #if !HAVE_DECL_CHOWN int chown(const char *path, uid_t owner, gid_t group); #endif #if !HAVE_DECL_FCHMOD int fchmod(int fd, mode_t mode); #endif #if !HAVE_DECL_GETNETGRENT int getnetgrent(char **host, char **user, char **domain); #endif #if !HAVE_DECL_SETNETGRENT #if SETNETGRENT_RETURNS_INT int setnetgrent(const char *netgroup); #else void setnetgrent(const char *netgroup); #endif #endif #if !HAVE_DECL_ENDNETGRENT #if ENDNETGRENT_RETURNS_INT int endnetgrent(void); #else void endnetgrent(void); #endif #endif #if !HAVE_DECL_STRSTR char *strstr(const char *haystack, const char *needle); #endif #if !HAVE_DECL_STRCASESTR char *strcasestr(const char *haystack, const char *needle); #endif #if !HAVE_DECL_STRCASECMP int strcasecmp(const char *s1, const char *s2); #endif #if !HAVE_DECL_STRNCASECMP int strncasecmp(const char *s1, const char *s2, size_t n); #endif #if !HAVE_DECL_STRSIGNAL char *strsignal(int sig); #endif #if !HAVE_DECL_STRDUP char *strdup(const char *str); #endif #if !HAVE_DECL_MEMRCHR void *memrchr(const void *s, int c, size_t n); #endif #if !HAVE_DECL_MEMDUP void *memdup(const void *mem, size_t size); #endif #if !HAVE_DECL_MEMMEM void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); #endif #if !HAVE_DECL_STRERROR char *strerror(int err); #endif #if !HAVE_DECL_UNSETENV int unsetenv(const char *name); #endif #ifndef HAVE_SETEUID int seteuid(uid_t euid); #endif #ifndef HAVE_SETEUID int setegid(gid_t egid); #endif #if !HAVE_DECL_SETLINEBUF void setlinebuf(FILE *stream); #endif #if HAVE_STDARG_H # include # if !HAVE_VSNPRINTF int rpl_vsnprintf(char *, size_t, const char *, va_list); /* If [v]snprintf() does not exist or is not C99 compatible, then we assume * that [v]printf() and [v]fprintf() need to be provided as well. */ int rpl_vprintf(const char *format, va_list ap); int rpl_vfprintf(FILE *stream, const char *format, va_list ap); # endif # if !HAVE_SNPRINTF int rpl_snprintf(char *, size_t, const char *, ...); int rpl_printf(const char *format, ...); int rpl_fprintf(FILE *stream, const char *format, ...); # endif # if !HAVE_VASPRINTF int rpl_vasprintf(char **, const char *, va_list); # endif # if !HAVE_ASPRINTF int rpl_asprintf(char **, const char *, ...); # endif #endif /* HAVE_STDARG_H */ /* For example Solaris, does not have isfinite() in . */ #if !HAVE_DECL_ISFINITE && defined(HAVE_IEEEFP_H) # include # define isfinite(x) finite(x) #endif #if !HAVE_DECL_GETLINE ssize_t getline(char **lineptr, size_t *n, FILE *stream); #endif #if !HAVE_DECL_STRCHRNUL char *strchrnul(const char *s, int c); #endif #if !HAVE_DECL_GMTIME_R struct tm *gmtime_r(const time_t *timep, struct tm *result); #endif #if !HAVE_DECL_LOCALTIME_R struct tm *localtime_r(const time_t *timep, struct tm *result); #endif #if !HAVE_DECL_CHMOD int chmod(const char *path, mode_t mode); #endif #if !HAVE_DECL_ALARM unsigned int alarm(unsigned int seconds); #endif #if !HAVE_DECL_MKDTEMP char *mkdtemp(char *template); #endif #if !HAVE_DECL_STRRSTR char *strrstr(const char *haystack, const char *needle); #endif #if !HAVE_DECL_STPNCPY char *stpncpy(char *dst, const char *src, size_t len); #endif #if !HAVE_DECL_INET_NTOP const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif #if !HAVE_DECL_INET_PTON int inet_pton(int af, const char *src, void *dst); #endif #if !HAVE_DECL_GETADDRINFO int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); void freeaddrinfo(struct addrinfo *res); int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags); const char *gai_strerror(int errcode); #endif #if !HAVE_STRUCT_SOCKADDR_STORAGE #ifdef AF_INET6 #define sockaddr_storage sockaddr_in6 #else #define sockaddr_storage sockaddr #endif #endif #ifndef AF_INET6 /* if the platform doesn't have it, it's useless, but define it as -1 * since we need it in our code... */ #define AF_INET6 -1 #endif #ifndef AI_NUMERICSERV /* Not portable to MinGW so don't use it. */ #define AI_NUMERICSERV -1 #endif #if !defined(HAVE_MKDIR_PROPER) int rpl_mkdir(const char *pathname, mode_t mode); #endif #if !defined(HAVE_STAT_PROPER) int rpl_stat(const char *path, struct stat *buf); #define _stat64(name, st) rpl_stat(name, st) #endif #if !defined(HAVE_RENAME_PROPER) int rpl_rename(const char *oldpath, const char *newpath); #endif #if !defined(HAVE_CTIME_PROPER) char *rpl_ctime(const time_t *t); #endif #ifndef NGROUPS # define NGROUPS 20 #endif #if !HAVE_DECL_OPENAT int openat(int dirfd, const char *pathname, int flags, ...); #endif #if !HAVE_DECL_FSTATAT int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags); #endif #if !HAVE_DECL_FCHOWNAT int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags); #endif #if !HAVE_DECL_FCHMODAT int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags); #endif #if !HAVE_DECL_READLINKAT int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz); #endif #ifndef AT_SYMLINK_NOFOLLOW #define AT_SYMLINK_NOFOLLOW 0x1000 #endif #ifndef AT_FDCWD #define AT_FDCWD (-2) #endif #if !HAVE_DECL_LOG2 double log2(double x); #endif /*******************************************************************/ /* Windows */ /*******************************************************************/ #ifdef __MINGW32__ # define MAXHOSTNAMELEN 256 // always adequate: http://msdn.microsoft.com/en-us/library/ms738527(VS.85).aspx // as seen in in_addr struct in winsock.h typedef u_long in_addr_t; // shold be in winnt.h, but is not in current MinGW version # ifndef VER_SUITE_WH_SERVER # define VER_SUITE_WH_SERVER 0x00008000 # endif /* Dummy signals, can be set to anything below 23 but * 2, 4, 8, 11, 15, 21, 22 which are taken. * Calling signal() with anything from below causes SIG_ERR * to be returned. */ # define SIGALRM 1 # define SIGHUP 3 # define SIGTRAP 5 # define SIGKILL 6 # define SIGPIPE 7 # define SIGCONT 9 # define SIGSTOP 10 # define SIGQUIT 12 # define SIGCHLD 13 # define SIGUSR1 14 # define SIGUSR2 16 # define SIGBUS 17 # if !defined( _TIMESPEC_DEFINED) && !defined(HAVE_STRUCT_TIMESPEC) # define HAVE_STRUCT_TIMESPEC 1 struct timespec { long tv_sec; long tv_nsec; }; # endif/* NOT _TIMESPEC_DEFINED */ #endif /* __MINGW32__ */ #ifndef ERESTARTSYS # define ERESTARTSYS EINTR #endif #ifndef EOPNOTSUPP # define EOPNOTSUPP EINVAL #endif #ifndef ENOTSUPP # define ENOTSUPP EINVAL #endif #ifndef ENOLINK // Should be well outside the range of any errno value. // Will never actually be returned by any function on a platform that doesn't support it. # define ENOLINK 123456 #endif /*******************************************************************/ /* Copy file defines */ /*******************************************************************/ /** * DEV_BSIZE is 512 for most common platforms * (Linux, AIX on Power, Solaris etc). * * Exceptions: * HP-UX: 1024 * AIX on PS/2: 4096 * Windows: undefined */ #ifndef DEV_BSIZE /* usually defined in */ # ifdef BSIZE # define DEV_BSIZE BSIZE # else # define DEV_BSIZE 512 # endif #endif /** Extract or fake data from a `struct stat'. ST_BLKSIZE: Optimal I/O blocksize for the file, in bytes. This is tightly coupled to ST_NBLOCKS, i.e it must stand that (s.st_size <= ST_NBLOCKS(s) * ST_BLKSIZE(s)) ST_NBLOCKS: Number of blocks in the file, **in ST_BLKSIZE units** WARNING this is different than "stat.st_nblocks" on most systems ST_NBYTES : "disk usage" of the file on the disk, **in bytes**. TODO on Windows here is how to get the "cluster size" i.e. the block size: - send IOCTL_DISK_GET_DRIVE_GEOMETRY_EX and use Geometry.BytesPerSector from DISK_GEOMETRY_EX structure - To check if a file is sparse: File.GetAttributes().SparseFile */ /* * Known platforms that don't have stat.st_blocks: * Windows (MinGW) */ #ifndef HAVE_STRUCT_STAT_ST_BLOCKS # define ST_BLKSIZE(statbuf) DEV_BSIZE # define ST_NBLOCKS(statbuf) (((statbuf).st_size + DEV_BSIZE - 1) / DEV_BSIZE) # define ST_NBYTES(statbuf) (ST_NBLOCKS(statbuf) * DEV_BSIZE) #else /* HAVE_STRUCT_STAT_ST_BLOCKS */ /* Some systems, like Sequents, return st_blksize of 0 on pipes. */ # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \ ? (statbuf).st_blksize : DEV_BSIZE) # define ST_NBLOCKS(statbuf) ((ST_NBYTES(statbuf) + ST_BLKSIZE(statbuf) - 1) \ / ST_BLKSIZE(statbuf)) # if defined(_CRAY) # define ST_NBYTES(statbuf) ((statbuf).st_blocks * ST_BLKSIZE(statbuf)) # else /* ======= DEFAULT ============================== */ /* Most OS give stat.st_blocks in DEV_BSIZE units */ # define ST_NBYTES(statbuf) ((statbuf).st_blocks * DEV_BSIZE) /* ============================================== */ # endif /* CRAY */ #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */ #ifndef SEEK_CUR # define SEEK_CUR 1 #endif /*******************************************************************/ /* Ultrix/BSD don't have all these from sys/stat.h */ /*******************************************************************/ #ifndef S_IFBLK # define S_IFBLK 0060000 #endif #ifndef S_IFCHR # define S_IFCHR 0020000 #endif #ifndef S_IFDIR # define S_IFDIR 0040000 #endif #ifndef S_IFIFO # define S_IFIFO 0010000 #endif #ifndef S_IFREG # define S_IFREG 0100000 #endif #ifndef S_IFLNK # define S_IFLNK 0120000 #endif #ifndef S_IFSOCK # define S_IFSOCK 0140000 #endif #ifndef S_IFMT # define S_IFMT 00170000 #endif #ifndef S_ISREG # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif #ifndef S_ISDIR # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif #ifndef S_ISLNK # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) #endif #ifndef S_ISFIFO # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) #endif #ifndef S_ISCHR # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) #endif #ifndef S_ISBLK # define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) #endif #ifndef S_ISSOCK # define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) #endif #ifndef S_IRUSR # define S_IRWXU 00700 # define S_IRUSR 00400 # define S_IWUSR 00200 # define S_IXUSR 00100 #endif #ifndef S_IRGRP # define S_IRWXG 00070 # define S_IRGRP 00040 # define S_IWGRP 00020 # define S_IXGRP 00010 #endif #ifndef S_IROTH # define S_IRWXO 00007 # define S_IROTH 00004 # define S_IWOTH 00002 # define S_IXOTH 00001 #endif /* kill(2) on OS X returns ETIMEDOUT instead of ESRCH */ #ifndef ETIMEDOUT # define ETIMEDOUT ESRCH #endif /* For getnameinfo(). */ #ifndef NI_MAXHOST # define NI_MAXHOST 1025 #endif /********************************************************************/ /* *BSD chflags stuff - */ /********************************************************************/ #if !defined UF_NODUMP # define UF_NODUMP 0 #endif #if !defined UF_IMMUTABLE # define UF_IMMUTABLE 0 #endif #if !defined UF_APPEND # define UF_APPEND 0 #endif #if !defined UF_OPAQUE # define UF_OPAQUE 0 #endif #if !defined UF_NOUNLINK # define UF_NOUNLINK 0 #endif #if !defined SF_ARCHIVED # define SF_ARCHIVED 0 #endif #if !defined SF_IMMUTABLE # define SF_IMMUTABLE 0 #endif #if !defined SF_APPEND # define SF_APPEND 0 #endif #if !defined SF_NOUNLINK # define SF_NOUNLINK 0 #endif #define CHFLAGS_MASK ( UF_NODUMP | UF_IMMUTABLE | UF_APPEND | UF_OPAQUE | UF_NOUNLINK | SF_ARCHIVED | SF_IMMUTABLE | SF_APPEND | SF_NOUNLINK ) /* For cygwin32 */ #if !defined O_BINARY # define O_BINARY 0 #endif #if !defined O_TEXT # define O_TEXT 0 #endif #if defined(__MINGW32__) /* _mkdir(3) */ # include #endif /* Some shorthands. */ # if defined(__sun) && !defined(sun) # define sun # endif # if defined(__SVR4) && !defined(SVR4) # define SVR4 # endif # if (defined(sun) && defined(SVR4)) || defined (SOLARIS2) # define SUNOS_5 # endif #include /* Must be always the last one! */ #include #include #endif /* CFENGINE_PLATFORM_H */ cfengine-3.24.2/libntech/libutils/clockid_t.h0000644000000000000000000000216415010704321021075 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CLOCKID_T_H #define CLOCKID_T_H /* Set by ./configure allowing us to avoid #include here. */ #define HAVE_CLOCKID_T 1 #ifndef HAVE_CLOCKID_T typedef int clockid_t; #else #include #endif #endif /* CLOCKID_T_H */ cfengine-3.24.2/libntech/libutils/csv_parser.c0000644000000000000000000002433315010704254021313 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include typedef enum { CSV_ST_NEW_LINE, CSV_ST_PRE_START_SPACE, CSV_ST_NO_QUOTE_MODE, CSV_ST_SEPARATOR, CSV_ST_LEADING_QUOTE, CSV_ST_INTERNAL_QUOTE, CSV_ST_WITH_QUOTE_MODE, CSV_ST_SPACE_AFTER_QUOTE, CSV_ST_ERROR, CSV_ST_CLOSED } csv_state; #define CSVCL_BLANK(x) (((x)==' ')||((x)=='\t')||((x)=='\n')||((x)=='\r')) #define CSVCL_QUOTE(x) (((x)=='"')) #define CSVCL_SEP(x) (((x)==',')) #define CSVCL_EOL(x) (((x)=='\0')) #define CSVCL_ANY1(x) ((!CSVCL_BLANK(x))&&(!CSVCL_QUOTE(x))&&(!CSVCL_SEP(x))) #define CSVCL_ANY2(x) ((!CSVCL_BLANK(x))&&(!CSVCL_QUOTE(x))&&(!CSVCL_SEP(x))) #define CSVCL_ANY3(x) ((!CSVCL_QUOTE(x))&&(!CSVCL_SEP(x))) #define CSVCL_ANY4(x) ((!CSVCL_BLANK(x))&&(!CSVCL_QUOTE(x))&&(!CSVCL_SEP(x))) #define CSVCL_ANY5(x) ((!CSVCL_QUOTE(x))) #define CSVCL_ANY6(x) ((!CSVCL_BLANK(x))&&(!CSVCL_QUOTE(x))&&(!CSVCL_SEP(x))) #define CSVCL_ANY7(x) ((!CSVCL_QUOTE(x))) #define CSVCL_ANY8(x) ((!CSVCL_BLANK(x))&&(!CSVCL_SEP(x))) typedef enum { CSV_ERR_OK, CVS_ERR_MALFORMED, CSV_ERR_UNKNOWN_STATE, CSV_ERR_UNEXPECTED_END, CSV_ERR_INVALID_INPUT } csv_parser_error; /** @brief parse CSV-formatted line and put its content in a list @param[in] str: is the CSV string to parse @param[out] newlist: list of elements found @retval 0: successful, <>0: failed */ static csv_parser_error LaunchCsvAutomata(const char *str, Seq **newlist) { assert(str); if (str == NULL) { return CSV_ERR_INVALID_INPUT; } char *snatched = xmalloc(strlen(str) + 1); snatched[0] = '\0'; char *sn = snatched; csv_parser_error ret; csv_state current_state = CSV_ST_NEW_LINE; /* initial state */ const char *s; for (s = str; *s != '\0'; s++) { switch(current_state) { case CSV_ST_ERROR: ret = CVS_ERR_MALFORMED; goto clean; case CSV_ST_NEW_LINE: if (CSVCL_SEP(*s)) { *sn = '\0'; sn = NULL; SeqAppend(*newlist, xstrdup("")); current_state = CSV_ST_SEPARATOR; } else if (CSVCL_BLANK(*s)) { *sn = *s; sn++; current_state = CSV_ST_PRE_START_SPACE; } else if (CSVCL_QUOTE(*s)) { snatched[0] = '\0'; sn = NULL; current_state = CSV_ST_LEADING_QUOTE; } else if (CSVCL_ANY1(*s)) { *sn = *s; sn++; current_state = CSV_ST_NO_QUOTE_MODE; } break; case CSV_ST_PRE_START_SPACE: if (CSVCL_SEP(*s)) { *sn = '\0'; sn = NULL; SeqAppend(*newlist, xstrdup(snatched)); snatched[0] = '\0'; current_state = CSV_ST_SEPARATOR; } else if (CSVCL_BLANK(*s)) { *sn = *s; sn++; current_state = CSV_ST_PRE_START_SPACE; } else if (CSVCL_QUOTE(*s)) { snatched[0] = '\0'; sn = NULL; current_state = CSV_ST_LEADING_QUOTE; } else if (CSVCL_ANY2(*s)) { *sn = *s; sn++; current_state = CSV_ST_NO_QUOTE_MODE; } break; case CSV_ST_NO_QUOTE_MODE: if (CSVCL_SEP(*s)) { *sn = '\0'; sn = NULL; SeqAppend(*newlist, xstrdup(snatched)); snatched[0] = '\0'; current_state = CSV_ST_SEPARATOR; } else if (CSVCL_QUOTE(*s)) { snatched[0] = '\0'; sn = NULL; current_state = CSV_ST_ERROR; } else if (CSVCL_ANY3(*s)) { *sn = *s; sn++; current_state = CSV_ST_NO_QUOTE_MODE; } break; case CSV_ST_SEPARATOR: if (CSVCL_SEP(*s)) { snatched[0] = '\0'; sn = NULL; SeqAppend(*newlist, xstrdup(snatched)); current_state = CSV_ST_SEPARATOR; } else if (CSVCL_BLANK(*s)) { sn = snatched; *sn = *s; sn++; current_state = CSV_ST_PRE_START_SPACE; } else if (CSVCL_QUOTE(*s)) { snatched[0] = '\0'; sn = NULL; current_state = CSV_ST_LEADING_QUOTE; } else if (CSVCL_ANY4(*s)) { sn = snatched; *sn = *s; sn++; current_state = CSV_ST_NO_QUOTE_MODE; } break; case CSV_ST_LEADING_QUOTE: if (CSVCL_QUOTE(*s)) { sn = snatched; current_state = CSV_ST_INTERNAL_QUOTE; } else if (CSVCL_ANY5(*s)) { sn = snatched; *sn = *s; sn++; current_state = CSV_ST_WITH_QUOTE_MODE; } break; case CSV_ST_INTERNAL_QUOTE: if (CSVCL_SEP(*s)) { *sn = '\0'; sn = NULL; SeqAppend(*newlist, xstrdup(snatched)); current_state = CSV_ST_SEPARATOR; } else if (CSVCL_BLANK(*s)) { current_state = CSV_ST_SPACE_AFTER_QUOTE; } else if (CSVCL_QUOTE(*s)) { *sn = *s; sn++; current_state = CSV_ST_WITH_QUOTE_MODE; } else if (CSVCL_ANY6(*s)) { snatched[0] = '\0'; sn++; current_state = CSV_ST_ERROR; } break; case CSV_ST_WITH_QUOTE_MODE: if (CSVCL_QUOTE(*s)) { current_state = CSV_ST_INTERNAL_QUOTE; } else if (CSVCL_ANY7(*s)) { *sn = *s; sn++; current_state = CSV_ST_WITH_QUOTE_MODE; } break; case CSV_ST_SPACE_AFTER_QUOTE: if (CSVCL_SEP(*s)) { sn = NULL; SeqAppend(*newlist, xstrdup(snatched)); current_state = CSV_ST_SEPARATOR; } else if (CSVCL_BLANK(*s)) { if (sn != NULL) { *sn = '\0'; } sn = NULL; current_state = CSV_ST_SPACE_AFTER_QUOTE; } else if (CSVCL_ANY8(*s)) { snatched[0] = '\0'; sn = NULL; current_state = CSV_ST_ERROR; } break; default: ret = CSV_ERR_UNKNOWN_STATE; goto clean; } } assert(*s == '\0'); if (current_state != CSV_ST_LEADING_QUOTE && current_state != CSV_ST_WITH_QUOTE_MODE ) { if (sn != NULL) { *sn = *s; /* write the trailing '\0' */ sn = NULL; } /* Trim trailing CRLF. */ if(current_state == CSV_ST_NO_QUOTE_MODE || current_state == CSV_ST_PRE_START_SPACE) { int len = strlen(snatched); if (len > 1 && snatched[len - 2] == '\r' && snatched[len - 1] == '\n') { snatched[len - 2] = '\0'; } } SeqAppend(*newlist, xstrdup(snatched)); snatched[0] = '\0'; } else /* LEADING_QUOTE or WITH_QUOTE */ { ret = CSV_ERR_UNEXPECTED_END; goto clean; } free(snatched); return CSV_ERR_OK; clean: if (newlist) { SeqDestroy(*newlist); } free(snatched); return ret; } Seq *SeqParseCsvString(const char *string) { Seq *newlist = SeqNew(16, free); if (LaunchCsvAutomata(string, &newlist) != CSV_ERR_OK) { return NULL; } return newlist; } char *GetCsvLineNext(FILE *fp) { if (!fp) { return NULL; } Writer *buffer = StringWriter(); char prev = 0; bool in_quotes = false; for (;;) { int current = fgetc(fp); if (current == EOF || feof(fp)) { break; } WriterWriteChar(buffer, current); if (current == '"') { in_quotes = !in_quotes; } else if (!in_quotes && (current == '\n') && (prev == '\r')) { break; } prev = current; } if (StringWriterLength(buffer) <= 0) { WriterClose(buffer); return NULL; } return StringWriterClose(buffer); } cfengine-3.24.2/libntech/libutils/glob_lib.h0000644000000000000000000000623615010704321020717 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef GLOB_LIB_H #define GLOB_LIB_H #include #include /* Set by ./configure allowing us to avoid #include here. */ #define WITH_PCRE2 1 #ifdef WITH_PCRE2 /** * @brief Find files/directories matching shell pattern (glob). * * Patterns are UNIX shell style: * * '*' matches everything, * '?' matches any single character, * '[seq]' matches any character in seq, * '[!seq]' matches any character not in seq, * '{foo,bar}' matches foo or bar. * * Pattern is normalized if the operating system requires it. The double * asterisk symbol does not match any subdirectories. The result is sorted in * lexical order. * * @param pattern Glob pattern. * @return Sorted sequence of matches. */ Seq *GlobFind(const char *pattern); /** * @brief Test whether string (filename) matches shell pattern (glob). * * Patterns are UNIX shell style: * * '*' matches everything, * '?' matches any single character, * '[seq]' matches any character in seq, * '[!seq]' matches any character not in seq, * '{foo,bar}' matches foo or bar. * * Pattern is normalized if the operating system requires it. * * We don't check if filename is valid, or if it is a file or if it exists. * It's treated as just a string. * * Modeled after the python fnmatch module (see * https://github.com/python/cpython/blob/3.8/Lib/fnmatch.py) * * @param pattern Glob pattern. * @return True if filename matches shell pattern. */ bool GlobMatch(const char *pattern, const char *filename); #endif // WITH_PCRE2 /** * @brief Find files/directories matching shell pattern (glob). * * Patterns are UNIX shell style: * * '*' matches everything, * '?' matches any single character, * '[seq]' matches any character in seq, * '[!seq]' matches any character not in seq, * '{foo,bar}' matches foo or bar, * '**' matches any subdirectory from zero up to six levels deep. A * limit set by previous CFEngineers. TODO: remove limit in * ticket CFE-4317. * * Pattern is normalized if the operating system requires it. * * @param pattern Glob pattern. * @return Set of matches. */ StringSet *GlobFileList(const char *pattern); #endif // GLOB_LIB_H cfengine-3.24.2/libntech/libutils/hash_map.c0000644000000000000000000002066215010704254020725 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #define MAX_HASHMAP_BUCKETS (1 << 30) #define MIN_HASHMAP_BUCKETS (1 << 5) #define MAX_LOAD_FACTOR 0.75 #define MIN_LOAD_FACTOR 0.35 HashMap *HashMapNew(MapHashFn hash_fn, MapKeyEqualFn equal_fn, MapDestroyDataFn destroy_key_fn, MapDestroyDataFn destroy_value_fn, size_t init_size) { HashMap *map = xcalloc(1, sizeof(HashMap)); map->hash_fn = hash_fn; map->equal_fn = equal_fn; map->destroy_key_fn = destroy_key_fn; map->destroy_value_fn = destroy_value_fn; /* make sure size is in the bounds */ init_size = MIN(MAX(init_size, MIN_HASHMAP_BUCKETS), MAX_HASHMAP_BUCKETS); if (ISPOW2(init_size)) { map->size = init_size; } else { map->size = UpperPowerOfTwo(init_size); } map->init_size = map->size; map->buckets = xcalloc(map->size, sizeof(BucketListItem *)); map->load = 0; map->max_threshold = (size_t) map->size * MAX_LOAD_FACTOR; map->min_threshold = (size_t) map->size * MIN_LOAD_FACTOR; return map; } static unsigned int HashMapGetBucket(const HashMap *map, const void *key) { assert(map != NULL); unsigned int hash = map->hash_fn(key, 0); assert (ISPOW2 (map->size)); return (hash & (map->size - 1)); } static void HashMapResize(HashMap *map, size_t new_size) { size_t old_size; BucketListItem **old_buckets; old_size = map->size; old_buckets = map->buckets; map->size = new_size; /* map->load stays the same */ map->max_threshold = (size_t) map->size * MAX_LOAD_FACTOR; map->min_threshold = (size_t) map->size * MIN_LOAD_FACTOR; map->buckets = xcalloc(map->size, sizeof(BucketListItem *)); for (size_t i = 0; i < old_size; ++i) { BucketListItem *item; item = old_buckets[i]; old_buckets[i] = NULL; while (item != NULL) { BucketListItem *next = item->next; unsigned bucket = HashMapGetBucket(map, item->value.key); item->next = map->buckets[bucket]; map->buckets[bucket] = item; item = next; } } free (old_buckets); } /** * @retval true if value was preexisting in the map and got replaced. */ bool HashMapInsert(HashMap *map, void *key, void *value) { unsigned bucket = HashMapGetBucket(map, key); for (BucketListItem *i = map->buckets[bucket]; i != NULL; i = i->next) { if (map->equal_fn(i->value.key, key)) { /* Replace the key with the new one despite those two being the * same, since the new key might be referenced somewhere inside * the new value. */ map->destroy_key_fn(i->value.key); map->destroy_value_fn(i->value.value); i->value.key = key; i->value.value = value; return true; } } BucketListItem *i = xcalloc(1, sizeof(BucketListItem)); i->value.key = key; i->value.value = value; i->next = map->buckets[bucket]; map->buckets[bucket] = i; map->load++; if ((map->load > map->max_threshold) && (map->size < MAX_HASHMAP_BUCKETS)) { HashMapResize(map, map->size << 1); } return false; } bool HashMapRemove(HashMap *map, const void *key) { unsigned bucket = HashMapGetBucket(map, key); /* * prev points to a previous "next" pointer to rewrite it in case value need * to be deleted */ for (BucketListItem **prev = &map->buckets[bucket]; *prev != NULL; prev = &((*prev)->next)) { BucketListItem *cur = *prev; if (map->equal_fn(cur->value.key, key)) { map->destroy_key_fn(cur->value.key); map->destroy_value_fn(cur->value.value); *prev = cur->next; free(cur); map->load--; if ((map->load < map->min_threshold) && (map->size > map->init_size)) { HashMapResize(map, map->size >> 1); } return true; } } return false; } MapKeyValue *HashMapGet(const HashMap *map, const void *key) { unsigned bucket = HashMapGetBucket(map, key); for (BucketListItem *cur = map->buckets[bucket]; cur != NULL; cur = cur->next) { if (map->equal_fn(cur->value.key, key)) { return &cur->value; } } return NULL; } static void FreeBucketListItem(HashMap *map, BucketListItem *item) { if (item->next) { FreeBucketListItem(map, item->next); } map->destroy_key_fn(item->value.key); map->destroy_value_fn(item->value.value); free(item); map->load--; } /* Do not destroy value item */ static void FreeBucketListItemSoft(HashMap *map, BucketListItem *item) { if (item->next) { FreeBucketListItemSoft(map, item->next); } map->destroy_key_fn(item->value.key); free(item); map->load--; } void HashMapClear(HashMap *map) { for (size_t i = 0; i < map->size; ++i) { if (map->buckets[i]) { FreeBucketListItem(map, map->buckets[i]); } map->buckets[i] = NULL; } assert(map->load == 0); } void HashMapSoftDestroy(HashMap *map) { if (map) { for (size_t i = 0; i < map->size; ++i) { if (map->buckets[i]) { FreeBucketListItemSoft(map, map->buckets[i]); } map->buckets[i] = NULL; } free(map->buckets); free(map); } } void HashMapDestroy(HashMap *map) { if (map) { HashMapClear(map); free(map->buckets); free(map); } } void HashMapPrintStats(const HashMap *hmap, FILE *f) { size_t *bucket_lengths; size_t num_el = 0; size_t num_buckets = 0; bucket_lengths = xcalloc(hmap->size, sizeof(size_t)); for (size_t i = 0; i < hmap->size; i++) { BucketListItem *b = hmap->buckets[i]; if (b != NULL) { num_buckets++; } while (b != NULL) { num_el++; bucket_lengths[i]++; b = b->next; } } fprintf(f, "\tTotal number of buckets: %5zu\n", hmap->size); fprintf(f, "\tNumber of non-empty buckets: %5zu\n", num_buckets); fprintf(f, "\tTotal number of elements: %5zu\n", num_el); fprintf(f, "\tAverage elements per non-empty bucket (load factor): %5.2f\n", (float) num_el / num_buckets); fprintf(f, "\tThe 10 longest buckets are: \n"); for (int j = 0; j < 10; j++) { /* Find the maximum 10 times, zeroing it after printing it. */ int longest_bucket_id = 0; for (size_t i = 0; i < hmap->size; i++) { if (bucket_lengths[i] > bucket_lengths[longest_bucket_id]) { longest_bucket_id = i; } } fprintf(f, "\t\tbucket %5d with %zu elements\n", longest_bucket_id, bucket_lengths[longest_bucket_id]); bucket_lengths[longest_bucket_id] = 0; } free(bucket_lengths); } /******************************************************************************/ HashMapIterator HashMapIteratorInit(HashMap *map) { return (HashMapIterator) { map, map->buckets[0], 0 }; } MapKeyValue *HashMapIteratorNext(HashMapIterator *i) { while (i->cur == NULL) { if (++i->bucket >= i->map->size) { return NULL; } i->cur = i->map->buckets[i->bucket]; } MapKeyValue *ret = &i->cur->value; i->cur = i->cur->next; return ret; } cfengine-3.24.2/libntech/libutils/glob_lib.c0000644000000000000000000004747215010704254020726 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include /** * If not compiled with PCRE2, we fallback to glob(3) implementation. Why not * use glob(3) and fallback on our implementation? Because commonly used * features like brace expansion is not defined by POSIX, and would require * custom implementation anyways. We don't want subtle differences in features * for different platforms. */ #ifdef WITH_PCRE2 #include #else // WITH_PCRE2 #include #endif // WITH_PCRE2 /** * On Windows we accept both forward- & backslash, otherwise only forward slash * is accepted. */ #ifdef _WIN32 #define PATH_DELIMITERS "\\/" #else // _WIN32 #define PATH_DELIMITERS "/" #endif // _WIN32 /** * Returns a set of brace-expanded patterns. */ static void ExpandBraces(const char *pattern, StringSet *expanded) FUNC_UNUSED; // Unused if compiled without PCRE2, but tested in unit tests static void ExpandBraces(const char *const pattern, StringSet *const expanded) { assert(pattern != NULL); assert(expanded != NULL); char *const start = SafeStringDuplicate(pattern); /* First we will split the pattern into three parts based on the curly * brace delimiters. We look for the shortest possible match. E.g., the * string "foo{{bar,baz}qux,}" becomes "foo{", "bar,baz", "qux,}". */ char *left = NULL, *right = NULL; for (char *ch = start; *ch != '\0'; ch++) { if (*ch == '{') { left = ch; } else if (left != NULL && *ch == '}') { right = ch; break; } } /* Next we check if base case is reached. I.e., if there is no curly brace * pair to expand, then add the pattern itself to the result. */ if (right == NULL) { StringSetAdd(expanded, start); return; } *left = '\0'; *right = '\0'; /* Next we split the middle part (between the braces) on the comma * delimiter. E.g., the string "bar,baz" becomes "bar", "baz". If there is * no comma in the middle part, then a sequence of length 1 is returned, * containing the entire middle part, and we still continue the recursion, * because the result is added as a part of the base case in the next * recursive layer. */ char *middle = left + 1, *end = right + 1; Seq *const split = StringSplit(middle, ","); /* Lastly we combine the three parts for each split element, and * recursively expand subsequent curly braces. */ const size_t len = SeqLength(split); for (size_t i = 0; i < len; i++) { middle = SeqAt(split, i); char *const next = StringConcatenate(3, start, middle, end); ExpandBraces(next, expanded); free(next); } free(start); SeqDestroy(split); } /** * Case normalized the path on Windows, so that we can use normal string * comparison in order to compare files. E.g., 'C:/Program Files' becomes * 'c:\program files'. */ static char *NormalizePath(const char *path) FUNC_UNUSED; // Unused if compiled without PCRE2, but tested in unit tests static char *NormalizePath(const char *path) { assert(path != NULL); char *const current = xstrdup(path); #ifdef _WIN32 ToLowerStrInplace(current); #endif // _WIN32 return current; } #ifdef WITH_PCRE2 /** * Translate the square bracket part of a shell expression (glob) into a * regular expression. */ static size_t TranslateBracket( const char *const pattern, const size_t n, size_t left, Buffer *const buf) { size_t right = left; if (right < n && pattern[right] == '!') { right += 1; } if (right < n && pattern[right] == ']') { right += 1; } while (right < n && pattern[right] != ']') { right += 1; } if (right >= n) { /* There was an opening bracket, but no closing one. Treat it as part * of the filename by escaping it. */ BufferAppendString(buf, "\\["); return left; } char *stuff = SafeStringNDuplicate(pattern + left, right - left); if (StringContains(stuff, "--")) { // Escape backslashes and hyphens for set difference (--). // Hyphens that create ranges shouldn't be escaped. Seq *const chunks = SeqNew(1, free); ssize_t middle = (pattern[left] == '!') ? left + 2 : left + 1; while (true) { middle = StringFind(pattern, "-", middle, right); if (middle < 0) { break; } char *chunk = SafeStringNDuplicate(pattern + left, middle - left); char *tmp = SearchAndReplace(chunk, "\\", "\\\\"); FREE_AND_NULL(chunk); chunk = SearchAndReplace(tmp, "-", "\\-"); free(tmp); SeqAppend(chunks, chunk); left = middle + 1; middle = middle + 3; } char *chunk = SafeStringNDuplicate(pattern + left, right - left); char *tmp = SearchAndReplace(chunk, "\\", "\\\\"); FREE_AND_NULL(chunk); chunk = SearchAndReplace(tmp, "-", "\\-"); FREE_AND_NULL(tmp); SeqAppend(chunks, chunk); tmp = StringJoin(chunks, "-"); FREE_AND_NULL(stuff); stuff = tmp; SeqDestroy(chunks); } else { char *const tmp = SearchAndReplace(stuff, "\\", "\\\\"); FREE_AND_NULL(stuff); stuff = tmp; } left = right + 1; if (stuff[0] == '!') { char *const tmp = StringConcatenate(2, "^", stuff + 1); FREE_AND_NULL(stuff); stuff = tmp; } else if (stuff[0] == '^' || stuff[0] == '[') { char *const tmp = StringConcatenate(2, "\\", stuff); FREE_AND_NULL(stuff); stuff = tmp; } BufferAppendF(buf, "[%s]", stuff); FREE_AND_NULL(stuff); return left; } /** * Translate a shell pattern to a regular expression. * * This is a C implementation of the translate function in the fnmatch module * from Python's standard library. See * https://github.com/python/cpython/blob/3.8/Lib/fnmatch.py */ static char *TranslateGlob(const char *const pattern) { assert(pattern != NULL); static const char *const special_chars = "()[]{}?*+-|^$\\.&~# \t\n\r\v\f"; size_t i = 0; const size_t n = strlen(pattern); Buffer *const buf = BufferNew(); while (i < n) { char ch = pattern[i++]; switch (ch) { #ifndef _WIN32 /* We don't allow escaping wildcards in Windows for two reasons. First, * we cannot escape with backslash when it is also a path separator. * Secondly, '*' is an illegal filename on Windows. */ case '\\': BufferAppendChar(buf, ch); BufferAppendChar(buf, pattern[i++]); break; #endif // _WIN32 case '*': BufferAppendString(buf, ".*"); break; case '?': BufferAppendString(buf, "."); break; case '[': i = TranslateBracket(pattern, n, i, buf); break; default: if (strchr(special_chars, ch) != NULL) { BufferAppendF(buf, "\\%c", ch); } else { BufferAppendChar(buf, ch); } break; } } char *const res = StringFormat("(?s:%s)\\Z", BufferData(buf)); BufferDestroy(buf); return res; } bool GlobMatch(const char *const _pattern, const char *const _filename) { assert(_pattern != NULL); assert(_filename != NULL); char *pattern = NormalizePath(_pattern); char *const filename = NormalizePath(_filename); StringSet *const expanded = StringSetNew(); ExpandBraces(pattern, expanded); FREE_AND_NULL(pattern); bool any_matches = false; StringSetIterator iter = StringSetIteratorInit(expanded); while ((pattern = StringSetIteratorNext(&iter)) != NULL) { char *const regex = TranslateGlob(pattern); any_matches |= StringMatchFull(regex, filename); free(regex); } StringSetDestroy(expanded); free(filename); return any_matches; } /** * Structure used in conjunction with PathWalk() in order to pass arbitrary * data to callback function. */ typedef struct { Seq *components; Seq *matches; } GlobFindData; /** * Used before each recursive branch in PathWalk() to duplicate arbitrary data. */ static void *GlobFindDataCopy(void *const data) { assert(data != NULL); GlobFindData *const old = data; GlobFindData *const new = xmalloc(sizeof(GlobFindData)); const size_t length = SeqLength(old->components); new->components = SeqNew(length, free); for (size_t i = 0; i < length; i++) { const char *const item = SeqAt(old->components, i); char *const copy = xstrdup(item); SeqAppend(new->components, copy); } // Note that we shallow copy matches. new->matches = old->matches; return new; } /** * Used after each recursive branch in PathWalk() to free duplicated arbitrary * data. */ static void GlobFindDataDestroy(void *const _data) { assert(_data != NULL); GlobFindData *const data = _data; SeqDestroy(data->components); free(data); } /** * Convert long name to short name (8.3 alias). Returns NULL on failure or when * the short name is equal to the long name. */ static char *ConvertLongNameToShortName( const char *const dirpath, const char *const filename) { /* When you create a long filename, Windows may also create a short form of * the filename. This is often referred to as the 8.3 alias or short name. * This dates back to the good old MS-DOS area where there was a limit of * eight characters for the filename plus three characters for the file * extension. */ #ifdef _WIN32 char *const long_path = Path_JoinAlloc(dirpath, filename); char short_path[PATH_MAX]; unsigned long length = GetShortPathNameA(long_path, short_path, PATH_MAX); if (length == 0) { Log(LOG_LEVEL_DEBUG, "Failed to retrieve short path from path '%s': %s", long_path, GetLastError()); free(long_path); return NULL; } if (length >= PATH_MAX) { Log(LOG_LEVEL_DEBUG, "Failed to retrieve short path of path '%s': " "Path name too long (%lu >= %d)", long_path, length, PATH_MAX); free(long_path); return NULL; } char *b_name = basename(short_path); if (!StringEqual(b_name, filename)) { Log(LOG_LEVEL_DEBUG, "Retrieved short path '%s' from path '%s'", b_name, filename); free(long_path); return SafeStringDuplicate(b_name); } free(long_path); #else // _WIN32 UNUSED(dirpath); UNUSED(filename); #endif // _WIN32 return NULL; } /** * Callback function used in conjunction with PathWalk() in order to find glob * matches. */ static void PathWalkCallback( const char *const dirpath, Seq *const dirnames, const Seq *const filenames, void *const _data) { assert(dirpath != NULL); assert(dirnames != NULL); assert(filenames != NULL); assert(_data != NULL); GlobFindData *const data = (GlobFindData *) _data; assert(data->components != NULL); assert(data->matches != NULL); const size_t n_components = SeqLength(data->components); if (n_components == 0) { /* We have matched each and every part of the glob pattern, thus we * have a full match. */ char *const match = xstrdup(dirpath); SeqAppend(data->matches, match); Log(LOG_LEVEL_DEBUG, "Full match! Directory '%s' has matched all previous sub patterns", match); // Base case is reached and recursion ends here. SeqClear(dirnames); return; } // Pop the glob component at the head of sequence. char *const sub_pattern = SeqAt(data->components, 0); SeqSoftRemove(data->components, 0); /* Normally we would not iterate the '.' and '..' directory entries in * order to avoid infinite recursion. However, an exception is made when * they appear as a part of the glob pattern we are currently crunching. */ if (StringEqual(sub_pattern, ".") || StringEqual(sub_pattern, "..")) { char *const entry = xstrdup(sub_pattern); SeqAppend(dirnames, entry); } const size_t n_dirnames = SeqLength(dirnames); for (size_t i = 0; i < n_dirnames; i++) { const char *const dir_name = SeqAt(dirnames, i); char *const short_name = ConvertLongNameToShortName(dirpath, dir_name); if (GlobMatch(sub_pattern, dir_name)) { Log(LOG_LEVEL_DEBUG, "Partial match! Sub pattern '%s' matches directory '%s'", sub_pattern, dir_name); free(short_name); } else if (short_name != NULL && GlobMatch(sub_pattern, short_name)) { /* We matched with the short name (i.e., 8.3 alias on Windows). We * substitute the long name with the short name in dirnames, such * that it will end up as the short name in the results. */ Log(LOG_LEVEL_DEBUG, "Partial match! Sub pattern '%s' matches directory short name" " '%s' (i.e., 8.3 alias).", sub_pattern, short_name); SeqSet(dirnames, i, short_name); } else { /* Not a match! Make sure not to follow down this path. Setting the * directory name to NULL should do the trick. And it's more * efficient than removing it from the sequence. */ SeqSet(dirnames, i, NULL); free(short_name); } } if (n_components != 1) { /* Unless number of remaining glob components to match is ONE, we will * not look for non-directory matches. */ free(sub_pattern); return; } const size_t n_filenames = SeqLength(filenames); for (size_t i = 0; i < n_filenames; i++) { const char *const filename = SeqAt(filenames, i); char *const short_name = ConvertLongNameToShortName(dirpath, filename); if (GlobMatch(sub_pattern, filename)) { char *const match = (StringEqual(dirpath, ".")) ? xstrdup(filename) : Path_JoinAlloc(dirpath, filename); Log(LOG_LEVEL_DEBUG, "Full match! Found non-directory file '%s' where '%s' " "matches sub pattern '%s'", match, filename, sub_pattern); SeqAppend(data->matches, match); } else if (short_name != NULL && GlobMatch(sub_pattern, short_name)) { char *match = Path_JoinAlloc(dirpath, short_name); Log(LOG_LEVEL_DEBUG, "Full match! Found non-directory file '%s' where the short " "name '%s' (8.3 alias) matches sub pattern '%s'", match, short_name, sub_pattern); SeqAppend(data->matches, match); } free(short_name); } free(sub_pattern); } /** * Filter used in conjunction with SeqFilter() to remove empty strings from * sequence. */ static bool EmptyStringFilter(void *item) { assert(item != NULL); const char *const str = (const char *) item; return StringEqual(str, ""); } Seq *GlobFind(const char *pattern) { assert(pattern != NULL); if (StringEqual(pattern, "")) { // Glob pattern is empty. Nothing to do. return SeqNew(0, free); } Seq *const matches = SeqNew(8 /* seems reasonable */, free); StringSet *expanded = StringSetNew(); ExpandBraces(pattern, expanded); StringSetIterator iter = StringSetIteratorInit(expanded); while ((pattern = StringSetIteratorNext(&iter)) != NULL) { GlobFindData data = { .matches = matches, .components = StringSplit(pattern, PATH_DELIMITERS), }; SeqFilter(data.components, EmptyStringFilter); if (IsAbsoluteFileName(pattern)) { if (IsWindowsNetworkPath(pattern)) { // Pop component at the head of sequence. const char *const hostname = SeqAt(data.components, 0); // Path like '\\hostname\...'. char *const path = StringFormat("\\\\%s", hostname); SeqRemoveRange(data.components, 0, 0); PathWalk( path, PathWalkCallback, &data, GlobFindDataCopy, GlobFindDataDestroy); free(path); } else if (IsWindowsDiskPath(pattern)) { // Path like 'C:\...'. // Pop component at the head of sequence. char *const path = SeqAt(data.components, 0); SeqSoftRemoveRange(data.components, 0, 0); PathWalk( path, PathWalkCallback, &data, GlobFindDataCopy, GlobFindDataDestroy); free(path); } else { // Path like '/...'. PathWalk( FILE_SEPARATOR_STR, PathWalkCallback, &data, GlobFindDataCopy, GlobFindDataDestroy); } } else { PathWalk( ".", PathWalkCallback, &data, GlobFindDataCopy, GlobFindDataDestroy); } SeqDestroy(data.components); } StringSetDestroy(expanded); SeqSort(matches, StrCmpWrapper, NULL); return matches; } #endif // WITH_PCRE2 StringSet *GlobFileList(const char *pattern) { StringSet *set = StringSetNew(); const char *replace[] = { "", "*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"}; const bool double_asterisk = (strstr(pattern, "**") != NULL); const size_t replace_count = double_asterisk ? sizeof(replace) / sizeof(replace[0]) : 1; for (size_t i = 0; i < replace_count; i++) { char *expanded = double_asterisk ? SearchAndReplace(pattern, "**", replace[i]) : SafeStringDuplicate(pattern); #ifdef WITH_PCRE2 Seq *const matches = GlobFind(expanded); const size_t num_matches = SeqLength(matches); for (size_t j = 0; j < num_matches; j++) { char *const match = SafeStringDuplicate(SeqAt(matches, j)); StringSetAdd(set, match); } SeqDestroy(matches); #else // WITH_PCRE2 glob_t globbuf; // If we don't have PCRE2, we fallback to the old way of doing things Log(LOG_LEVEL_WARNING, "Globs perform limited/buggy without PCRE2" " - consider recompiling libntech with PCRE2."); /* The glob(3) function keeps double slashes (e.g., "/etc//os-release") * in the result, if part of pattern. However, we want the result to be * similar to our PCRE2 solution. */ char *const tmp = SearchAndReplace(expanded, "//", "/"); free(expanded); expanded = tmp; if (glob(expanded, 0, NULL, &globbuf) == 0) { for (size_t j = 0; j < globbuf.gl_pathc; j++) { StringSetAdd(set, SafeStringDuplicate(globbuf.gl_pathv[j])); } globfree(&globbuf); } #endif // WITH_PCRE2 free(expanded); } return set; } cfengine-3.24.2/libntech/libutils/buffer.h0000644000000000000000000002453115010704254020422 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_BUFFER_H #define CFENGINE_BUFFER_H #include #include // va_list /** @brief Buffer implementation The buffer structure acts as a byte container. It can contains any bytes and it is not restricted to C strings (by default it acts as a C String). If an error arises while doing something, we do everything we can to restore things to its previous state. Unfortunately not all errors are recoverable. Since we do not have a proper errno system, we just return -1. */ typedef enum { BUFFER_BEHAVIOR_CSTRING // buffer2 */ int BufferCompare(const Buffer *buffer1, const Buffer *buffer2); /** @brief Replaces the current content of the buffer with the given string. In CString mode the content of bytes is copied until length bytes have been copied or a '\0' is found, whatever happens first. In ByteArray mode length bytes are copied regardless of if there are '\0' or not. @note The content of the buffer are overwritten with the new content, it is not possible to access them afterwards. @note For complex data it is preferable to use Printf since that will make sure that all data is represented properly. @note The data will be preserved if this operation fails, although it might be in a detached state. @param buffer Buffer to be used. @param bytes Collection of bytes to be copied into the buffer. @param length Length of the collection of bytes. */ void BufferSet(Buffer *buffer, const char *bytes, size_t length); /** @brief This functions allows direct access to the storage inside Buffer. @return Returns the pointer used to store data inside the buffer. The content can be freely modified up to the capacity of the buffer. @remarks This function invalidates the size of the buffer. Mixing calls to this function with other Buffer functions is generally a bad idea. */ char *BufferGet(Buffer *buffer); void BufferAppend(Buffer *buffer, const char *bytes, size_t length); /** @brief Appends a char to an existing buffer. @param buffer Structure to operate on. @param byte Char to be added to the buffer. */ void BufferAppendChar(Buffer *buffer, char byte); void BufferAppendF(Buffer *buffer, const char *format, ...); void BufferAppendString(Buffer *buffer, const char *str); /** @brief Stores complex data on the buffer. This function uses the same semantic and flags as printf. Internally it might or not call sprintf, so do not depend on obscure sprintf/printf behaviors. @note This function can be used both in CString mode and in ByteArray mode. The only difference is the presence of the final '\0' character. @note The data will be preserved if this operation fails, although it might be in a detached state. @param buffer @param format @return The number of bytes written to the buffer or 0 if the operation needs to be retried. In case of error -1 is returned. */ int BufferPrintf(Buffer *buffer, const char *format, ...) FUNC_ATTR_PRINTF(2, 3); /** @brief Stores complex data on the buffer. This function uses the same semantic and flags as printf. Internally it might or not call sprintf, so do not depend on obscure sprintf/printf behaviors. This function uses a va_list instead of variable arguments. @note This function can be used both in CString mode and in ByteArray mode. The only difference is the presence of the final '\0' character. @note The data will be preserved if this operation fails, although it might be in a detached state. @param buffer @param format NB! Make sure to sanitize if taken from user input. @return The number of bytes written to the buffer or 0 if the operation needs to be retried. In case of error -1 is returned. */ int BufferVPrintf(Buffer *buffer, const char *format, va_list ap); /** @brief Does a PCRE search and replace on the buffer data. @param buffer @param pattern @param substitute (backreferences allowed) @param options Perl-style gms... @return NULL if successful, an error string otherwise. */ const char* BufferSearchAndReplace(Buffer *buffer, const char *pattern, const char *substitute, const char *options); /** @brief Clears the buffer. Clearing the buffer does not mean destroying the data. The data might be still present after this function is called, although it might not be accessible. This function never fails. If a NULL pointer is given it will politely ignore the call. @note This function might trigger a deep copy and a memory allocation if the buffer is shared. @param buffer Buffer to clear. */ void BufferClear(Buffer *buffer); /** @brief Returns the size of the buffer. @param buffer @return The size of the buffer, that is the number of bytes contained on it. @note */ size_t BufferSize(const Buffer *buffer); /** @param buffer Structure to operate on. @return Returns the capacity of the buffer. */ size_t BufferCapacity(const Buffer *buffer); /** @brief Returns the current mode of operation of the buffer. @param buffer The buffer to operate on. @return The current mode of operation. */ BufferBehavior BufferMode(const Buffer *buffer); /** @brief Sets the operational mode of the buffer. Although there are no problems changing the operational mode once the buffer is in use, there might be some obscure side effects. The data will not be changed but the interpretation of it will, therefore it might be possible that some data is lost when switching from ByteArray mode to CString mode, since '\0' are allowed in ByteArray mode but not in CString mode. @param buffer The buffer to operate on. @param mode The new mode of operation. */ void BufferSetMode(Buffer *buffer, BufferBehavior mode); /** @brief Returns a filtered copy of a Buffer @param buffer The buffer to operate on. @param filter a function to test for inclusion @param invert Whether the test should be inverted */ Buffer* BufferFilter(Buffer *buffer, BufferFilterFn filter, const bool invert); /** @brief Filters a Buffer in place @param buffer The buffer to operate on. @param filter a function to test for inclusion @param invert Whether the test should be inverted */ void BufferRewrite(Buffer *buffer, BufferFilterFn filter, const bool invert); /** @brief Trim a buffer to be at most max bytes. If the buffer is below the max bytes, nothing happens. Otherwise, it's trimmed to that many bytes. This is not persistent, the buffer could grow beyond the max bytes in the future. @param buffer @param max the maximum number of bytes to trim to */ void BufferTrimToMaxLength(Buffer *buffer, size_t max); /** @brief Canonify a buffer in place: replace [^0-9a-zA-Z] with '_' @see CanonifyNameInPlace @param buffer */ void BufferCanonify(Buffer *buffer); /** @brief Provides a pointer to the internal data. This is a const pointer and it is not supposed to be used to write data to the buffer, doing so will lead to undefined behavior and most likely segmentation faults. Use the proper functions to write data to the buffer. @param buffer @return A const char pointer to the data contained on the buffer. */ const char *BufferData(const Buffer *buffer); #endif cfengine-3.24.2/libntech/libutils/proc_keyvalue.c0000644000000000000000000000410715010704254022011 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include typedef struct { void *orig_param; KeyNumericValueCallback orig_callback; } KeyNumericParserInfo; bool KeyNumericParserCallback(const char *field, const char *value, void *param) { KeyNumericParserInfo *info = param; long long numeric_value; if (sscanf(value, #if defined(__MINGW32__) "%I64d", #else "%lli", #endif &numeric_value) != 1) { /* Malformed file */ return false; } return (*info->orig_callback) (field, numeric_value, info->orig_param); } bool ParseKeyNumericValue(FILE *fd, KeyNumericValueCallback callback, void *param) { KeyNumericParserInfo info = { param, callback }; return ParseKeyValue(fd, KeyNumericParserCallback, &info); } bool ParseKeyValue(FILE *fd, KeyValueCallback callback, void *param) { char buf[1024]; while (fgets(buf, sizeof(buf), fd)) { char *s = strchr(buf, ':'); if (!s) { /* Malformed file */ return false; } *s = 0; if (!(*callback) (buf, s + 1, param)) { return false; } } return (ferror(fd) == 0); } cfengine-3.24.2/libntech/libutils/ip_address.c0000644000000000000000000011103115010704254021251 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #ifdef WITH_PCRE2 #include #endif struct IPV4Address { uint8_t octets[4]; uint16_t port; }; struct IPV6Address { uint16_t sixteen[8]; uint16_t port; }; struct IPAddress { void *address; int type; }; #define Char2Dec(o, c) \ (o * 10) + c - '0' /* * Hexadecimal conversion is not as simple as decimal conversion, * so we implement it here. * We do not check for errors, we assume the caller has checked that * the characters are hexadecimal. */ static int Char2Hex(int beginning, char increment) { int number = beginning; number *= 16; if (('a' <= increment) && (increment <= 'f')) { number += (increment - 'a' + 0x0A); } else if (('A' <= increment) && (increment <= 'F')) { number += (increment - 'A' + 0x0A); } else { number += (increment - '0'); } return number; } /* * This function parses the source pointer and checks if it conforms to the * 0a0b0c0d or 0a0b0c0d:0e0f formats (commonly used in procfs) * * If address is not NULL and the address is IPV4, then the result is copied there. * * Returns 0 on success. */ static int IPV4_hex_parser(const char *source, struct IPV4Address *address) { { // shortcut for the 0a0b0c0d format unsigned int a, b, c, d, pport = 0; if (strlen(source) == 8 && sscanf(source, "%2x%2x%2x%2x", &a, &b, &c, &d) == 4) { address->octets[3] = a; address->octets[2] = b; address->octets[1] = c; address->octets[0] = d; address->port = pport; return 0; } // shortcut for the 0a0b0c0d:0e0f format if (strlen(source) == 8+1+4 && sscanf(source, "%2x%2x%2x%2x:%4x", &a, &b, &c, &d, &pport) == 5) { address->octets[3] = a; address->octets[2] = b; address->octets[1] = c; address->octets[0] = d; address->port = pport; return 0; } } return -1; } /* * This function parses the source pointer and checks if it conforms to the * RFC 791. * * xxx.xxx.xxx.xxx[:ppppp] * * If address is not NULL and the address is IPV4, then the result is copied there. * * Returns 0 on success. */ static int IPV4_parser(const char *source, struct IPV4Address *address) { char *p = NULL; int octet = 0; int port = 0; int period_counter = 0; int port_counter = 0; int char_counter = 0; bool is_period = false; bool is_digit = false; bool is_port = false; bool has_digit = false; /* * For simplicity sake we initialize address (if not NULL). */ if (address) { int i = 0; for (i = 0; i < 4; ++i) { address->octets[i] = 0; } address->port = 0; } /* * IPV4 parsing has 6 states, of which: * 2 are end states * 4 are parsing states * * States 0 to 3 are purely address parsing. State 5 * might never be reached if there is no port. * State 4 is the final state if everything went ok. * State 6 is reached in case of error. * * 0 1 2 3 * |d |d |d |d * | p | p | p | done * 0 -> 1 -> 2 -> 3 -> 4 * | | | | | * 7 <--+----+----+ | * error | ':' | * _5-----+ * d \| done */ int state = 0; bool state_change = false; for (p = (char *)source; *p != '\0'; ++p) { /* * Do some character recognition */ is_digit = isdigit(*p); is_period = (*p == '.') ? 1 : 0; is_port = (*p == ':') ? 1 : 0; /* * Update the corresponding flags. */ if (is_period) { period_counter++; } if (is_port) { port_counter++; } /* * Do the right operation depending on the state */ switch (state) { case 0: case 1: case 2: /* * The three first states are the same. * XXX.XXX.XXX.xxx[:nnnnn] */ if (is_digit) { octet = Char2Dec(octet, *p); has_digit = true; } else if (is_period) { if (address) { address->octets[state] = octet; } state++; state_change = true; } else { state = 7; state_change = true; } break; case 3: /* * This case is different from the previous ones. A period here means error. * xxx.xxx.xxx.XXX[:nnnnn] */ if (is_digit) { octet = Char2Dec(octet, *p); has_digit = true; } else if (is_port) { if (address) { address->octets[state] = octet; } state = 5; state_change = true; } else { state = 7; state_change = true; } break; case 4: break; case 5: if (is_digit) { port = Char2Dec(port, *p); } else { state = 7; state_change = true; } break; case 6: default: return -1; break; } /* * It is important to the filtering before counting the characters. * Otherwise the counter will need to start from -1. */ char_counter++; /* * Do some sanity checks, this should hold no matter * in which state of the state machine we are. */ if (octet > 255) { return -1; } if (port > 65535) { return -1; } if (period_counter > 1) { return -1; } if (port_counter > 1) { return -1; } if (state_change) { /* * Check that we have digits, otherwise the transition is wrong. */ if (!has_digit) { return -1; } /* * Reset all the variables. */ char_counter = 0; octet = 0; port = 0; period_counter = 0; port_counter = 0; is_period = false; is_digit = false; is_port = false; has_digit = false; state_change = false; } } /* * These states are not end state, which mean we exited the loop because of an error */ if ((state == 0) || (state == 1) || (state == 2)) { return -1; } /* * If state is 3 then we exited the loop without copying the last octet. * This is because we didn't get to state 4. * Notice that we need to check if we had characters, it might be possible that we * have the following situation 'xxx.xxx.xxx.' which will fit the state change but not * produce a valid IP. */ if (state == 3) { if (char_counter == 0) { return -1; } if (address) { address->octets[3] = octet; } } /* * If state is 5 then we exited the loop without copying the port. * This is because we hit a '\0'. * Notice that we need to check if we had characters, it might be possible that we * have the following situation 'xxx.xxx.xxx.xxx:' which will fit the state change but not * produce a valid IP. */ if (state == 5) { if (char_counter == 0) { return -1; } if (address) { address->port = port; } } /* * If state is 6 then there was an error. */ if (state == 6) { return -1; } return 0; } /* * This function parses the address and checks if it conforms to the * 0a0b0c0d0e0f0g0h or 0a0b0c0d0e0f0g0h:0i0j format (commonly used in procfs) * * Returns 0 on success. */ static int IPV6_hex_parser(const char *source, struct IPV6Address *address) { { // shortcut for the 0a0b0c0d0e0f0g0h format unsigned int a, b, c, d, e, f, g, h, pport = 0; if (strlen(source) == 32 && sscanf(source, "%4x%4x%4x%4x%4x%4x%4x%4x", &a, &b, &c, &d, &e, &f, &g, &h) == 8) { address->sixteen[0] = a; address->sixteen[1] = b; address->sixteen[2] = c; address->sixteen[3] = d; address->sixteen[4] = e; address->sixteen[5] = f; address->sixteen[6] = g; address->sixteen[7] = h; return 0; } if (strlen(source) == 32+1+4 && sscanf(source, "%4x%4x%4x%4x%4x%4x%4x%4x:%4x", &a, &b, &c, &d, &e, &f, &g, &h, &pport) == 9) { address->sixteen[0] = a; address->sixteen[1] = b; address->sixteen[2] = c; address->sixteen[3] = d; address->sixteen[4] = e; address->sixteen[5] = f; address->sixteen[6] = g; address->sixteen[7] = h; address->port = pport; return 0; } } return -1; } /* * This function parses the address and checks if it conforms to the * RFCs 2373, 2460 and 5952. * We do not support Microsoft UNC encoding, i.e. * hhhh-hhhh-hhhh-hhhh-hhhh-hhhh-hhhh-hhhh.ipv6-literal.net * Despite following RFC 5292 we do not signal errors derived from bad * zero compression although this might change on time, so please do not * trust that we will honor address with wrong zero compression. * * Returns 0 on success. */ static int IPV6_parser(const char *source, struct IPV6Address *address) { /* * IPV6 parsing is more complex than IPV4 parsing. There are a few ground rules: * - Leading zeros can be omitted. * - Fields that are just zeros can be abbreviated to one zero or completely omitted. * In the later case the following notation is used: '::'. * - Port number is specified in a special way: * [hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh]:ppppp * Notice that it is possible to have the '[' and ']' without specifying a port. * * Simplified state machine: * * _h _h _h _h _h _h _h _h _d * |/ ':' |/ ':' |/ ':' |/ ':' |/ ':' |/ ':' |/ ':' |/ ']' ':' |/ done * 0------>1------>2------>3------>4------>5------>6------>7------>8------>9------>11 * |\ | done | * -'[' 9<------+ * * This is a simplified state machine since I assume that we keep the square brackets inside * the same state as hexadecimal digits, which in practice is not true. */ char *p = NULL; int sixteen = 0; int unsorted_sixteen[6]; int unsorted_pointer = 0; int bracket_expected = 0; int port = 0; int char_counter = 0; bool is_start_bracket = 0; bool is_end_bracket = 0; bool is_colon = 0; bool is_hexdigit = 0; bool is_upper_hexdigit = 0; bool is_digit = 0; int zero_compression = 0; int already_compressed = 0; int state = 0; bool state_change = false; /* * Initialize our container for unknown numbers. */ for (unsorted_pointer = 0; unsorted_pointer < 6; ++unsorted_pointer) { unsorted_sixteen[unsorted_pointer] = 0; } unsorted_pointer = 0; /* * For simplicity sake we initialize address (if not NULL). */ if (address) { int i = 0; for (i = 0; i < 8; ++i) { address->sixteen[i] = 0; } address->port = 0; } for (p = (char *)source; *p != '\0'; ++p) { /* * Take a closer look at the character */ is_start_bracket = (*p == '[') ? 1 : 0; is_end_bracket = (*p == ']') ? 1 : 0; is_hexdigit = isxdigit(*p); is_digit = isdigit(*p); is_colon = (*p == ':') ? 1 : 0; if (is_hexdigit) { if (isalpha(*p)) { is_upper_hexdigit = isupper(*p); } } switch (state) { case 0: /* * This case is slightly different because of the possible presence of '['. * Notice that '[' is only valid as the first character, anything else is * an error! */ if (is_start_bracket) { if (char_counter == 0) { bracket_expected = 1; } else { state = 11; state_change = true; } } else if (is_hexdigit) { /* * RFC 5952 forbids upper case hex digits */ if (is_upper_hexdigit) { state = 11; state_change = true; } else { sixteen = Char2Hex(sixteen, *p); } } else if (is_colon) { if (address) { address->sixteen[0] = sixteen; } state = 1; state_change = true; } else { state = 11; state_change = true; } break; case 1: /* * This state is special since it cannot have a ']' as in the next * states. */ if (is_hexdigit) { /* * RFC 5952 forbids upper case hex digits */ if (is_upper_hexdigit) { state = 11; state_change = true; } else { sixteen = Char2Hex(sixteen, *p); } } else if (is_colon) { if (char_counter == 0) { /* * This means 'X::Y...' which means zero compression. * Flag it! */ zero_compression = 1; already_compressed = 1; } else { if (address) { address->sixteen[state] = sixteen; } } ++state; state_change = true; } else { state = 11; state_change = true; } break; case 2: case 3: case 4: case 5: case 6: if (is_hexdigit) { /* * RFC 5952 forbids upper case hex digits */ if (is_upper_hexdigit) { state = 11; state_change = true; } else { sixteen = Char2Hex(sixteen, *p); } } else if (is_colon) { if (char_counter == 0) { if (already_compressed) { /* * The '::' symbol can only occur once in a given address. */ state = 11; state_change = true; } else { /* * This means '...:X::Y...' which means zero compression. * Flag it! */ zero_compression = 1; already_compressed = 1; } } else { if (zero_compression) { /* * If zero compression is enabled, then we cannot trust the position * since we might compressed several fields. We store the value and * look at them afterwards. */ unsorted_sixteen[unsorted_pointer] = sixteen; ++unsorted_pointer; } else { /* * No zero compression, just assign the address and keep moving. */ if (address) { address->sixteen[state] = sixteen; } } ++state; state_change = true; } } else if (is_end_bracket) { if (bracket_expected && zero_compression) { bracket_expected = 0; /* * RFC 5952 says that we can end an address at any point after * the second position (consequence of the zero compression). * Therefore if we find a ']' we just jump to state 8. */ unsorted_sixteen[unsorted_pointer] = sixteen; ++unsorted_pointer; state = 8; state_change = true; } else { /* * Funny stuff, we got a ']' that we were not expecting. * Politely walk back and signal the error. */ state = 11; state_change = true; } } else { state = 11; state_change = true; } break; case 7: /* * This case is special. */ if (is_hexdigit) { /* * RFC 5952 forbids uppercase hex digits */ if (is_upper_hexdigit) { state = 11; state_change = true; } else { sixteen = Char2Hex(sixteen, *p); } } else if (is_end_bracket) { if (bracket_expected) { bracket_expected = 0; if (address) { address->sixteen[state] = sixteen; } /* * The last possible position for a sixteen is number 8. */ ++state; state_change = true; } else { /* * Funny stuff, we got a ']' that we were not expecting. * Politely walk back and signal the error. */ state = 11; state_change = true; } } else { state = 11; state_change = true; } break; case 8: if (is_colon) { ++state; state_change = true; } else { state = 11; state_change = true; } break; case 9: if (is_digit) { port = Char2Dec(port, *p); } else { state = 11; state_change = true; } break; case 10: break; case 11: default: return -1; break; } char_counter++; if (sixteen > 0xFFFF) { return -1; } if (port > 65535) { return -1; } if (state_change) { sixteen = 0; port = 0; char_counter = 0; is_start_bracket = false; is_end_bracket = false; is_colon = false; is_hexdigit = false; is_upper_hexdigit = false; is_digit = 0; state_change = false; } } /* * Look at the end state and return accordingly. */ if ((state == 0) || (state == 1)) { /* * These states are not final states, so if we exited is because something went wrong. */ return -1; } /* * Thanks to RFC5952 the final states can be intermediate states. This because of zero compression, * which means that the following address 1:0:0:0:0:0:0:1 can be written as * 1::1. Not to mention more exotic varieties such as 1:0:0:0:0:0:0:0 1:: or * 0:0:0:0:0:0:0:0 :: * The first intermediate state that can exit is 2, since even the smallest of all address('::') * will have at least two ':'. * Another exotic case is 'X:0:0:Y:0:0:0:Z' which becomes 'X::Y:0:0:0:Z' or X:0:0:Y::Z because the symbol '::' * can appear only once in a given address. */ if ((state == 2) || (state == 3) || (state == 4) || (state == 5) || (state == 6)) { /* * We check first for non-closed brackets. * Then we check if there is a number that has not been added to our array. * Finally we move to zero compression. */ if (bracket_expected) { return -1; } unsorted_sixteen[unsorted_pointer] = sixteen; ++unsorted_pointer; if (zero_compression) { /* * If there is no address, then we can just return :-) */ if (address) { /* * We need to find the rightful positions for those numbers. * We use a simple trick: * We know how many unsorted addresses we have from unsorted pointer, * and we know that once zero_compression is activated we do not fill * any more numbers to the address structure. Therefore the right way * to do this is to take the array of unsorted_sixteen and start assigning * numbers backwards. */ int i = 0; for (i = 0; i < unsorted_pointer; ++i) { address->sixteen[7 - i] = unsorted_sixteen[unsorted_pointer - i - 1]; } } } else { /* * We cannot end up here without zero compression, or an error. */ return -1; } } if (state == 7) { /* * This state corresponds to the final state of a simple ipv6 address, i.e. * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx * We exited because we ran out of characters. Let's check that we have something * before assigning things. */ if (char_counter == 0) { /* * The last field was empty, signal the error. */ return -1; } if (bracket_expected) { /* * We were expecting a bracket but it never came, so this is an error. */ return -1; } if (address) { address->sixteen[7] = sixteen; } } if (state == 8) { /* * This state corresponds to the final state if brackets were present. * We still need to check if zero compression was activated and copy * the values if so. */ if (zero_compression) { /* * If there is no address, then we can just return :-) */ if (address) { /* * We need to find the rightful positions for those numbers. * We use a simple trick: * We know how many unsorted addresses we have from unsorted pointer, * and we know that once zero_compression is activated we do not fill * any more numbers to the address structure. Therefore the right way * to do this is to take the array of unsorted_sixteen and start assigning * numbers backwards. */ int i = 0; for (i = 0; i < unsorted_pointer; ++i) { address->sixteen[7 - i] = unsorted_sixteen[i]; } } } } if (state == 9) { /* * This state corresponds to the final state if we had brackets around us. * This is usually used to append a port number to the address, so we check * if we have a port and then assign it. */ if (char_counter == 0) { /* * The last field was empty, signal the error. */ return -1; } if (address) { address->port = port; } } if (state == 11) { /* * Error state */ return -1; } return 0; } IPAddress *IPAddressNew(Buffer *source) { if (!source || !BufferData(source)) { return NULL; } IPAddress *address = NULL; const char *pad = BufferData(source); struct IPV4Address *ipv4 = NULL; struct IPV6Address *ipv6 = NULL; ipv4 = (struct IPV4Address *)xmalloc(sizeof(struct IPV4Address)); ipv6 = (struct IPV6Address *)xmalloc(sizeof(struct IPV6Address)); if (IPV4_parser(pad, ipv4) == 0) { free (ipv6); address = (IPAddress *)xmalloc(sizeof(IPAddress)); address->type = IP_ADDRESS_TYPE_IPV4; address->address = (void *)ipv4; } else if (IPV6_parser(pad, ipv6) == 0) { free (ipv4); address = (IPAddress *)xmalloc(sizeof(IPAddress)); address->type = IP_ADDRESS_TYPE_IPV6; address->address = (void *)ipv6; } else { /* * It was not a valid IP address. */ free (ipv4); free (ipv6); return NULL; } return address; } IPAddress *IPAddressNewHex(Buffer *source) { if (!source || !BufferData(source)) { return NULL; } IPAddress *address = NULL; const char *pad = BufferData(source); struct IPV4Address *ipv4 = NULL; struct IPV6Address *ipv6 = NULL; ipv4 = (struct IPV4Address *)xmalloc(sizeof(struct IPV4Address)); ipv6 = (struct IPV6Address *)xmalloc(sizeof(struct IPV6Address)); if (IPV4_hex_parser(pad, ipv4) == 0) { free (ipv6); address = (IPAddress *)xmalloc(sizeof(IPAddress)); address->type = IP_ADDRESS_TYPE_IPV4; address->address = (void *)ipv4; } else if (IPV6_hex_parser(pad, ipv6) == 0) { free (ipv4); address = (IPAddress *)xmalloc(sizeof(IPAddress)); address->type = IP_ADDRESS_TYPE_IPV6; address->address = (void *)ipv6; } else { /* * It was not a valid IP address. */ free (ipv4); free (ipv6); return NULL; } return address; } int IPAddressDestroy(IPAddress **address) { if (!address || !(*address)) { return 0; } if ((*address)->address) { free ((*address)->address); } free (*address); *address = NULL; return 0; } int IPAddressType(IPAddress *address) { if (!address) { return -1; } return address->type; } Buffer *IPAddressGetAddress(IPAddress *address) { if (!address) { return NULL; } Buffer *buffer = NULL; int result = 0; if (address->type == IP_ADDRESS_TYPE_IPV4) { struct IPV4Address *ipv4 = (struct IPV4Address *)address->address; buffer = BufferNew(); #if BIG_ENDIAN result = BufferPrintf(buffer, "%u.%u.%u.%u", ipv4->octets[0], ipv4->octets[1], ipv4->octets[2], ipv4->octets[3]); #elif LITTLE_ENDIAN result = BufferPrintf(buffer, "%u.%u.%u.%u", ipv4->octets[3], ipv4->octets[2], ipv4->octets[1], ipv4->octets[0]); #else #warning "Unrecognized endianness, assuming big endian" result = BufferPrintf(buffer, "%u.%u.%u.%u", ipv4->octets[0], ipv4->octets[1], ipv4->octets[2], ipv4->octets[3]); #endif } else if (address->type == IP_ADDRESS_TYPE_IPV6) { struct IPV6Address *ipv6 = (struct IPV6Address *)address->address; buffer = BufferNew(); #if BIG_ENDIAN result = BufferPrintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", ipv6->sixteen[0], ipv6->sixteen[1], ipv6->sixteen[2], ipv6->sixteen[3], ipv6->sixteen[4], ipv6->sixteen[5], ipv6->sixteen[6], ipv6->sixteen[7]); #elif LITTLE_ENDIAN result = BufferPrintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", ipv6->sixteen[7], ipv6->sixteen[6], ipv6->sixteen[5], ipv6->sixteen[4], ipv6->sixteen[3], ipv6->sixteen[2], ipv6->sixteen[1], ipv6->sixteen[0]); #else #warning "Unrecognized endianness, assuming big endian" result = BufferPrintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", ipv6->sixteen[0], ipv6->sixteen[1], ipv6->sixteen[2], ipv6->sixteen[3], ipv6->sixteen[4], ipv6->sixteen[5], ipv6->sixteen[6], ipv6->sixteen[7]); #endif } else { buffer = NULL; } if (result < 0) { BufferDestroy(buffer); return NULL; } return buffer; } int IPAddressGetPort(IPAddress *address) { if (!address) { return -1; } int port = -1; if (address->type == IP_ADDRESS_TYPE_IPV4) { struct IPV4Address *ipv4 = (struct IPV4Address *)address->address; port = ipv4->port; } else if (address->type == IP_ADDRESS_TYPE_IPV6) { struct IPV6Address *ipv6 = (struct IPV6Address *)address->address; port = ipv6->port; } else { return -1; } return port; } /* * Comparison for IPV4 addresses */ static int IPV4Compare(struct IPV4Address *a, struct IPV4Address *b) { int i = 0; for (i = 0; i < 4; ++i) { if (a->octets[i] != b->octets[i]) { return 0; } } return 1; } /* * Comparison for IPV6 addresses */ static int IPV6Compare(struct IPV6Address *a, struct IPV6Address *b) { int i = 0; for (i = 0; i < 8; ++i) { if (a->sixteen[i] != b->sixteen[i]) { return 0; } } return 1; } int IPAddressIsEqual(IPAddress *a, IPAddress *b) { /* * We do not support IPV4 versus IPV6 comparisons. * This is trickier than what it seems, since even the IPV6 representation of an IPV6 address is not * clear yet. */ if (!a || !b) { return -1; } if (a->type != b->type) { return -1; } if (a->type == IP_ADDRESS_TYPE_IPV4) { return IPV4Compare((struct IPV4Address *)a->address, (struct IPV4Address *)b->address); } else if (a->type == IP_ADDRESS_TYPE_IPV6) { return IPV6Compare((struct IPV6Address *)a->address, (struct IPV6Address *)b->address); } return -1; } /* * Sorting comparison for IPV4 addresses */ static bool IPV4CompareLess(struct IPV4Address *a, struct IPV4Address *b) { int i = 0; for (i = 0; i < 4; ++i) { if (a->octets[i] > b->octets[i]) { return false; } else if (a->octets[i] < b->octets[i]) { return true; } } return false; } /* * Sorting comparison for IPV6 addresses */ static bool IPV6CompareLess(struct IPV6Address *a, struct IPV6Address *b) { int i = 0; for (i = 0; i < 8; ++i) { if (a->sixteen[i] > b->sixteen[i]) { return false; } else if (a->sixteen[i] < b->sixteen[i]) { return true; } } return false; } bool IPAddressCompareLess(IPAddress *a, IPAddress *b) { /* * We do not support IPV4 versus IPV6 comparisons. * This is trickier than what it seems, since even the IPV6 representation of an IPV6 address is not * clear yet. */ if (a == NULL || b == NULL) { return true; } assert(a->type == IP_ADDRESS_TYPE_IPV4 || a->type == IP_ADDRESS_TYPE_IPV6); assert(b->type == IP_ADDRESS_TYPE_IPV4 || b->type == IP_ADDRESS_TYPE_IPV6); // If not same type - Sort IPv4 BEFORE any other types: if (a->type != b->type) { if (a->type == IP_ADDRESS_TYPE_IPV4) { return true; } else { assert(b->type == IP_ADDRESS_TYPE_IPV4); return false; } } assert(a->type == b->type); IPAddressVersion type = a->type; if (type == IP_ADDRESS_TYPE_IPV4) { return IPV4CompareLess((struct IPV4Address *)a->address, (struct IPV4Address *)b->address); } assert(type == IP_ADDRESS_TYPE_IPV6); return IPV6CompareLess((struct IPV6Address *)a->address, (struct IPV6Address *)b->address); } bool IPAddressIsIPAddress(Buffer *source, IPAddress **address) { if (!source || !BufferData(source)) { return false; } bool create_object = false; if (address) { create_object = true; } const char *pad = BufferData(source); struct IPV4Address *ipv4 = NULL; struct IPV6Address *ipv6 = NULL; ipv4 = (struct IPV4Address *)xmalloc(sizeof(struct IPV4Address)); ipv6 = (struct IPV6Address *)xmalloc(sizeof(struct IPV6Address)); if (IPV4_parser(pad, ipv4) == 0) { free (ipv6); if (create_object) { *address = (IPAddress *)xmalloc(sizeof(IPAddress)); (*address)->type = IP_ADDRESS_TYPE_IPV4; (*address)->address = (void *)ipv4; } else { /* * We know it is a valid IPV4 address and we know we don't need the * IPV4 structure. */ free (ipv4); } } else if (IPV6_parser(pad, ipv6) == 0) { free (ipv4); if (create_object) { *address = (IPAddress *)xmalloc(sizeof(IPAddress)); (*address)->type = IP_ADDRESS_TYPE_IPV6; (*address)->address = (void *)ipv6; } else { /* * We know it is a valid IPV6 address and we know we don't need the * IPV6 structure. */ free (ipv6); } } else { /* * It was not a valid IP address. */ free (ipv4); free (ipv6); return false; } return true; } #ifdef WITH_PCRE2 bool StringIsLocalHostIP(const char *str) { const char *regex = "(" // IPv4 "(0*127(\\.0*((2[0-5][0-5])|(1?[0-9]?[0-9]))){3}" "|" // Ipv6 "0*(((:0+){6})|((:0+){0,5}:)|((:0+){0,4}:(:0+))|((:0+){0,3}:(:0+){2})|((:0+){0,2}:(:0+){3})|((:0+)?:(:0+){4})|(:(:0+){5})):0*1)" ")"; return StringMatchFull(regex, str); } #endif cfengine-3.24.2/libntech/libutils/array_map_priv.h0000644000000000000000000000412415010704254022160 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ARRAY_MAP_PRIV_H #define CFENGINE_ARRAY_MAP_PRIV_H #include typedef struct { MapKeyEqualFn equal_fn; MapDestroyDataFn destroy_key_fn; MapDestroyDataFn destroy_value_fn; MapKeyValue *values; short size; } ArrayMap; typedef struct { ArrayMap *map; int pos; } ArrayMapIterator; ArrayMap *ArrayMapNew(MapKeyEqualFn equal_fn, MapDestroyDataFn destroy_key_fn, MapDestroyDataFn destroy_value_fn); /** * @retval 0 if the limit of the array size has been reached, * and no insertion took place. * @retval 1 if the key was found and the value was replaced. * @retval 2 if the key-value pair was not found and inserted as new. */ int ArrayMapInsert(ArrayMap *map, void *key, void *value); bool ArrayMapRemove(ArrayMap *map, const void *key); MapKeyValue *ArrayMapGet(const ArrayMap *map, const void *key); void ArrayMapClear(ArrayMap *map); void ArrayMapSoftDestroy(ArrayMap *map); void ArrayMapDestroy(ArrayMap *map); /******************************************************************************/ ArrayMapIterator ArrayMapIteratorInit(ArrayMap *map); MapKeyValue *ArrayMapIteratorNext(ArrayMapIterator *i); #endif cfengine-3.24.2/libntech/libutils/man.h0000644000000000000000000000252015010704254017716 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MAN_H #define CFENGINE_MAN_H #include /* time_t */ #include void ManPageWrite(Writer *out, const char *program, time_t last_modified, const char *short_description, const char *long_description, const struct option options[], const char *const option_hints[], const Description *commands, bool command_first, bool accepts_file_argument); #endif cfengine-3.24.2/libntech/libutils/clockid_t.h.in0000644000000000000000000000216315010704254021506 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CLOCKID_T_H #define CLOCKID_T_H /* Set by ./configure allowing us to avoid #include here. */ @HAVE_CLOCKID_T_DEFINE@ #ifndef HAVE_CLOCKID_T typedef int clockid_t; #else #include #endif #endif /* CLOCKID_T_H */ cfengine-3.24.2/libntech/libutils/json-pcre.h0000644000000000000000000000045415010704254021047 0ustar00rootroot00000000000000#ifndef CFENGINE_JSON_PCRE_H #define CFENGINE_JSON_PCRE_H // Parts of json.h which require PCRE2 // Should only be included inside a WITH_PCRE2 ifdef guard #include #include JsonElement *StringCaptureData( const Regex *regex, const char *pattern, const char *data); #endif cfengine-3.24.2/libntech/libutils/alloc.h0000644000000000000000000000557715010704254020254 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ALLOC_H #define CFENGINE_ALLOC_H #include // size_t #include // va_list #include // assert() #include void *xcalloc(size_t nmemb, size_t size); void *xmalloc(size_t size); void *xrealloc(void *ptr, size_t size); char *xstrdup(const char *str); char *xstrndup(const char *str, size_t n); void *xmemdup(const void *mem, size_t size); int xasprintf(char **strp, const char *fmt, ...) FUNC_ATTR_PRINTF(2, 3); int xvasprintf(char **strp, const char *fmt, va_list ap) FUNC_ATTR_PRINTF(2, 0); static inline void free_array_items(void **array, size_t n_items) { assert(array != NULL); for (size_t i = 0; i < n_items; i++) { free(array[i]); } } #define DESTROY_AND_NULL(destroy, ptr) { destroy(ptr); ptr = NULL; } #define FREE_AND_NULL(ptr) { DESTROY_AND_NULL(free, ptr); } /* * Prevent any code from using un-wrapped allocators. * * Use x* equivalents instead. */ /** * Currently regular malloc() calls are allowed for mission-critical code that * can somehow recover, like cf-serverd dropping connections or cf-execd * postponing its scheduled actions. * * @note for 99% of the cases (libpromises, cf-agent etc) use xmalloc() and * friends. **/ #if 0 # undef malloc # undef calloc # undef realloc # undef strdup # undef strndup # undef memdup # undef asprintf # undef vasprintf # define malloc __error_unchecked_malloc # define calloc __error_unchecked_calloc # define realloc __error_unchecked_realloc # define strdup __error_unchecked_strdup # define strndup __error_unchecked_strndup # define memdup __error_unchecked_memdup # define asprintf __error_unchecked_asprintf # define vasprintf __error_unchecked_vasprintf void __error_unchecked_malloc(void); void __error_unchecked_calloc(void); void __error_unchecked_realloc(void); void __error_unchecked_strdup(void); void __error_unchecked_strndup(void); void __error_unchecked_memdup(void); void __error_unchecked_asprintf(void); void __error_unchecked_vasprintf(void); #endif #endif cfengine-3.24.2/libntech/libutils/ring_buffer.h0000644000000000000000000000331315010704254021434 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_RING_BUFFER_H #define CFENGINE_RING_BUFFER_H #include #include /* size_t */ typedef struct RingBuffer_ RingBuffer; typedef struct RingBufferIterator_ RingBufferIterator; RingBuffer *RingBufferNew(size_t capacity, void *(*copy)(const void *), void (*destroy)(void *)); void RingBufferDestroy(RingBuffer *buf); void RingBufferAppend(RingBuffer *buf, void *item); void RingBufferClear(RingBuffer *buf); size_t RingBufferLength(const RingBuffer *buf); bool RingBufferIsFull(const RingBuffer *buf); const void *RingBufferHead(const RingBuffer *buf); const void *RingBufferTail(const RingBuffer *buf); RingBufferIterator *RingBufferIteratorNew(const RingBuffer *buf); void RingBufferIteratorDestroy(RingBufferIterator *iter); const void *RingBufferIteratorNext(RingBufferIterator *iter); #endif cfengine-3.24.2/libntech/libutils/version_comparison.c0000644000000000000000000000453515010704254023065 0ustar00rootroot00000000000000#include // assert() #include // sscanf #include // StringEqual() #include VersionComparison CompareVersion(const char *a, const char *b) { int a_major = 0; int a_minor = 0; int a_patch = 0; const int a_num = sscanf(a, "%d.%d.%d", &a_major, &a_minor, &a_patch); if (a_num < 1 || a_num > 3) { return VERSION_ERROR; } int b_major = 0; int b_minor = 0; int b_patch = 0; const int b_num = sscanf(b, "%d.%d.%d", &b_major, &b_minor, &b_patch); if (b_num < 1 || b_num > 3) { return VERSION_ERROR; } if (a_major > b_major) { return VERSION_GREATER; } if (a_major < b_major) { return VERSION_SMALLER; } assert(a_major == b_major); if (a_num == 1 || b_num == 1) { return VERSION_EQUAL; } assert(a_num >= 2 && b_num >= 2); if (a_minor < b_minor) { return VERSION_SMALLER; } if (a_minor > b_minor) { return VERSION_GREATER; } assert(a_minor == b_minor); if (a_num == 2 || b_num == 2) { return VERSION_EQUAL; } assert(a_num == 3 && b_num == 3); if (a_patch < b_patch) { return VERSION_SMALLER; } if (a_patch > b_patch) { return VERSION_GREATER; } assert(a_patch == b_patch); return VERSION_EQUAL; } BooleanOrError CompareVersionExpression( const char *const a, const char *const operator, const char * const b) { const VersionComparison r = CompareVersion(a, b); if (r == VERSION_ERROR) { return BOOLEAN_ERROR; } if (StringEqual(operator, "=") || StringEqual(operator, "==")) { return (BooleanOrError) (r == VERSION_EQUAL); } if (StringEqual(operator, ">")) { return (BooleanOrError) (r == VERSION_GREATER); } if (StringEqual(operator, "<")) { return (BooleanOrError) (r == VERSION_SMALLER); } if (StringEqual(operator, ">=")) { return (BooleanOrError) (r == VERSION_GREATER || r == VERSION_EQUAL); } if (StringEqual(operator, "<=")) { return (BooleanOrError) (r == VERSION_SMALLER || r == VERSION_EQUAL); } if (StringEqual(operator, "!=")) { return (BooleanOrError) (r != VERSION_EQUAL); } return BOOLEAN_ERROR; } cfengine-3.24.2/libntech/libutils/logging.c0000644000000000000000000005606515010704254020601 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #if defined(HAVE_SYSTEMD_SD_JOURNAL_H) && defined(HAVE_LIBSYSTEMD) #include /* sd_journal_sendv() */ #endif // defined(HAVE_SYSTEMD_SD_JOURNAL_H) && defined(HAVE_LIBSYSTEMD) #include /* CF_BUFSIZE */ char VPREFIX[1024] = ""; /* GLOBAL_C */ static char AgentType[80] = "generic"; static bool TIMESTAMPS = false; static LogLevel global_level = LOG_LEVEL_NOTICE; /* GLOBAL_X */ static LogLevel global_system_log_level = LOG_LEVEL_NOTHING; /* default value that means not set */ static pthread_once_t log_context_init_once = PTHREAD_ONCE_INIT; /* GLOBAL_T */ static pthread_key_t log_context_key; /* GLOBAL_T, initialized by pthread_key_create */ static Seq *log_buffer = NULL; static bool logging_into_buffer = false; static LogLevel min_log_into_buffer_level = LOG_LEVEL_NOTHING; static LogLevel max_log_into_buffer_level = LOG_LEVEL_NOTHING; typedef struct LogEntry_ { LogLevel level; char *msg; } LogEntry; static void LoggingInitializeOnce(void) { if (pthread_key_create(&log_context_key, &free) != 0) { /* There is no way to signal error out of pthread_once callback. * However if pthread_key_create fails we are pretty much guaranteed * that nothing else will work. */ fprintf(stderr, "Unable to initialize logging subsystem\n"); DoCleanupAndExit(255); } } LoggingContext *GetCurrentThreadContext(void) { pthread_once(&log_context_init_once, &LoggingInitializeOnce); LoggingContext *lctx = pthread_getspecific(log_context_key); if (lctx == NULL) { lctx = xcalloc(1, sizeof(LoggingContext)); lctx->log_level = (global_system_log_level != LOG_LEVEL_NOTHING ? global_system_log_level : global_level); lctx->report_level = global_level; pthread_setspecific(log_context_key, lctx); } return lctx; } void LoggingFreeCurrentThreadContext(void) { pthread_once(&log_context_init_once, &LoggingInitializeOnce); LoggingContext *lctx = pthread_getspecific(log_context_key); if (lctx == NULL) { return; } // lctx->pctx is usually stack allocated and shouldn't be freed FREE_AND_NULL(lctx); pthread_setspecific(log_context_key, NULL); } void LoggingSetAgentType(const char *type) { strlcpy(AgentType, type, sizeof(AgentType)); } void LoggingEnableTimestamps(bool enable) { TIMESTAMPS = enable; } void LoggingPrivSetContext(LoggingPrivContext *pctx) { LoggingContext *lctx = GetCurrentThreadContext(); lctx->pctx = pctx; } LoggingPrivContext *LoggingPrivGetContext(void) { LoggingContext *lctx = GetCurrentThreadContext(); return lctx->pctx; } void LoggingPrivSetLevels(LogLevel log_level, LogLevel report_level) { LoggingContext *lctx = GetCurrentThreadContext(); lctx->log_level = log_level; lctx->report_level = report_level; } const char *LogLevelToString(LogLevel level) { switch (level) { case LOG_LEVEL_CRIT: return "CRITICAL"; case LOG_LEVEL_ERR: return "error"; case LOG_LEVEL_WARNING: return "warning"; case LOG_LEVEL_NOTICE: return "notice"; case LOG_LEVEL_INFO: return "info"; case LOG_LEVEL_VERBOSE: return "verbose"; case LOG_LEVEL_DEBUG: return "debug"; default: ProgrammingError("LogLevelToString: Unexpected log level %d", level); } } LogLevel LogLevelFromString(const char *const level) { // Only compare the part the user typed // i/info/inform/information will all result in LOG_LEVEL_INFO size_t len = SafeStringLength(level); if (len == 0) { return LOG_LEVEL_NOTHING; } if (StringEqualN_IgnoreCase(level, "CRITICAL", len)) { return LOG_LEVEL_CRIT; } if (StringEqualN_IgnoreCase(level, "errors", len)) { return LOG_LEVEL_ERR; } if (StringEqualN_IgnoreCase(level, "warnings", len)) { return LOG_LEVEL_WARNING; } if (StringEqualN_IgnoreCase(level, "notices", len)) { return LOG_LEVEL_NOTICE; } if (StringEqualN_IgnoreCase(level, "information", len)) { return LOG_LEVEL_INFO; } if (StringEqualN_IgnoreCase(level, "verbose", len)) { return LOG_LEVEL_VERBOSE; } if (StringEqualN_IgnoreCase(level, "debug", len)) { return LOG_LEVEL_DEBUG; } return LOG_LEVEL_NOTHING; } static const char *LogLevelToColor(LogLevel level) { switch (level) { case LOG_LEVEL_CRIT: case LOG_LEVEL_ERR: return "\x1b[31m"; // red case LOG_LEVEL_WARNING: return "\x1b[33m"; // yellow case LOG_LEVEL_NOTICE: case LOG_LEVEL_INFO: return "\x1b[32m"; // green case LOG_LEVEL_VERBOSE: case LOG_LEVEL_DEBUG: return "\x1b[34m"; // blue default: ProgrammingError("LogLevelToColor: Unexpected log level %d", level); } } bool LoggingFormatTimestamp(char dest[64], size_t n, struct tm *timestamp) { if (strftime(dest, n, "%Y-%m-%dT%H:%M:%S%z", timestamp) == 0) { strlcpy(dest, "", n); return false; } return true; } static void LogToConsole(const char *msg, LogLevel level, bool color) { struct tm now; time_t now_seconds = time(NULL); localtime_r(&now_seconds, &now); if (color) { fprintf(stdout, "%s", LogLevelToColor(level)); } if (level >= LOG_LEVEL_INFO && VPREFIX[0]) { fprintf(stdout, "%s ", VPREFIX); } if (TIMESTAMPS) { char formatted_timestamp[64]; LoggingFormatTimestamp(formatted_timestamp, 64, &now); fprintf(stdout, "%s ", formatted_timestamp); } fprintf(stdout, "%8s: %s\n", LogLevelToString(level), msg); if (color) { // Turn off the color again. fprintf(stdout, "\x1b[0m"); } fflush(stdout); } #if !defined(__MINGW32__) static int LogLevelToSyslogPriority(LogLevel level) { switch (level) { case LOG_LEVEL_CRIT: return LOG_CRIT; case LOG_LEVEL_ERR: return LOG_ERR; case LOG_LEVEL_WARNING: return LOG_WARNING; case LOG_LEVEL_NOTICE: return LOG_NOTICE; case LOG_LEVEL_INFO: return LOG_INFO; case LOG_LEVEL_VERBOSE: return LOG_DEBUG; /* FIXME: Do we really want to conflate those levels? */ case LOG_LEVEL_DEBUG: return LOG_DEBUG; default: ProgrammingError("LogLevelToSyslogPriority: Unexpected log level %d", level); } } void LogToSystemLog(const char *msg, LogLevel level) { char logmsg[4096]; snprintf(logmsg, sizeof(logmsg), "CFEngine(%s) %s %s\n", AgentType, VPREFIX, msg); syslog(LogLevelToSyslogPriority(level), "%s", logmsg); } #endif /* !__MINGW32__ */ #if defined(HAVE_SYSTEMD_SD_JOURNAL_H) && defined(HAVE_LIBSYSTEMD) void LogToSystemLogStructured(const int level, ...) { va_list args; va_start(args, level); // Additional pairs Seq *const seq = SeqNew(2, free); for (const char *key = va_arg(args, char *); !StringEqual(key, "MESSAGE"); key = va_arg(args, char *)) { const char *const value = va_arg(args, char *); char *const pair = StringFormat("%s=%s", key, value); SeqAppend(seq, pair); } // Message pair const char *const format_str = va_arg(args, char *); char *const message = StringVFormat(format_str, args); char *pair = StringFormat("MESSAGE=%s", message); free(message); SeqAppend(seq, pair); // Priority pair const int priority = LogLevelToSyslogPriority(level); pair = StringFormat("PRIORITY=%i", priority); SeqAppend(seq, pair); const int num_pairs = SeqLength(seq); struct iovec iov[num_pairs]; for (int i = 0; i < num_pairs; i++) { iov[i].iov_base = SeqAt(seq, i); iov[i].iov_len = strlen(iov[i].iov_base); } NDEBUG_UNUSED int ret = sd_journal_sendv(iov, num_pairs); assert(ret == 0); SeqDestroy(seq); va_end(args); } #else // defined(HAVE_SYSTEMD_SD_JOURNAL_H) && defined(HAVE_LIBSYSTEMD) void LogToSystemLogStructured(const int level, ...) { va_list args; va_start(args, level); for (const char *key = va_arg(args, char *); !StringEqual(key, "MESSAGE"); key = va_arg(args, char *)) { va_arg(args, char *); } const char *const format_str = va_arg(args, char *); char *const message = StringVFormat(format_str, args); LogToSystemLog(message, level); free(message); va_end(args); } #endif // defined(HAVE_SYSTEMD_SD_JOURNAL_H) && defined(HAVE_LIBSYSTEMD) void __ImproperUseOfLogToSystemLogStructured(void) { // TODO: CFE-4190 // - Make sure CodeQL finds at least the reqired function calls below, // then remove this code assert(false); // Do not use this function! // Required: Missing required "MESSAGE" key. LogToSystemLogStructured(LOG_LEVEL_DEBUG, "FOO", "bogus", "BAR", "doofus"); // Required: String-literal "MESSAGE" is not the same as "message". LogToSystemLogStructured(LOG_LEVEL_INFO, "FOO", "bogus", "BAR", "doofus", "message", "Hello CFEngine!"); // Required: Number of format-string arguments is less than number of format specifiers. LogToSystemLogStructured(LOG_LEVEL_ERR, "MESSAGE", "%s %d", "CFEngine"); // Optional: Number of format-string arguments is greated than number of format specifiers. LogToSystemLogStructured(LOG_LEVEL_ERR, "MESSAGE", "%s %d", "CFEngine", 123, "ROCKS!"); // Optional: All keys must be uppercase or else they are ignored. LogToSystemLogStructured(LOG_LEVEL_CRIT, "FOO", "bogus", "bar", "DOOFUS", "MESSAGE", "Hello CFEngine!"); // Optional: Pairs trailing the "MESSAGE" key are ignored. LogToSystemLogStructured(LOG_LEVEL_NOTICE, "FOO", "bogus", "MESSAGE", "Hello CFEngine!", "BAR", "doofus"); } #ifndef __MINGW32__ const char *GetErrorStrFromCode(int error_code) { return strerror(error_code); } const char *GetErrorStr(void) { return strerror(errno); } #else const char *GetErrorStrFromCode(int error_code) { static char errbuf[CF_BUFSIZE]; int len; memset(errbuf, 0, sizeof(errbuf)); if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), errbuf, CF_BUFSIZE, NULL)) { // remove CRLF from end len = strlen(errbuf); errbuf[len - 2] = errbuf[len - 1] = '\0'; } else { strcpy(errbuf, "Unknown error"); } return errbuf; } const char *GetErrorStr(void) { return GetErrorStrFromCode(GetLastError()); } #endif /* !__MINGW32__ */ bool WouldLog(LogLevel level) { LoggingContext *lctx = GetCurrentThreadContext(); bool log_to_console = (level <= lctx->report_level); bool log_to_syslog = (level <= lctx->log_level && level < LOG_LEVEL_VERBOSE); bool force_hook = (lctx->pctx && lctx->pctx->log_hook && lctx->pctx->force_hook_level >= level); return (log_to_console || log_to_syslog || force_hook); } /** * #no_format determines whether #fmt_msg is interpreted as a format string and * combined with #ap to create the real log message (%false) or as a log message * dirrectly (%true) in which case #ap is ignored. * * @see LogNoFormat() */ static void VLogNoFormat(LogLevel level, const char *fmt_msg, va_list ap, bool no_format) { LoggingContext *lctx = GetCurrentThreadContext(); bool log_to_console = ( level <= lctx->report_level ); bool log_to_syslog = ( level <= lctx->log_level && level < LOG_LEVEL_VERBOSE ); bool force_hook = ( lctx->pctx && lctx->pctx->log_hook && lctx->pctx->force_hook_level >= level ); /* NEEDS TO BE IN SYNC WITH THE CONDITION IN WouldLog() ABOVE! */ if (!log_to_console && !log_to_syslog && !force_hook) { return; /* early return - save resources */ } char *msg; if (no_format) { msg = xstrdup(fmt_msg); } else { msg = StringVFormat(fmt_msg, ap); } char *hooked_msg = NULL; if (logging_into_buffer && (level >= min_log_into_buffer_level) && (level <= max_log_into_buffer_level)) { assert(log_buffer != NULL); if (log_buffer == NULL) { /* Should never happen. */ Log(LOG_LEVEL_ERR, "Attempt to log a message to an unitialized log buffer, discarding the message"); } LogEntry *entry = xmalloc(sizeof(LogEntry)); entry->level = level; entry->msg = msg; SeqAppend(log_buffer, entry); return; } /* Remove ending EOLN. */ for (char *sp = msg; *sp != '\0'; sp++) { if (*sp == '\n' && *(sp+1) == '\0') { *sp = '\0'; break; } } if (lctx->pctx && lctx->pctx->log_hook) { hooked_msg = lctx->pctx->log_hook(lctx->pctx, level, msg); } else { hooked_msg = msg; } if (log_to_console) { LogToConsole(hooked_msg, level, lctx->color); } if (log_to_syslog) { LogToSystemLogStructured(level, "MESSAGE", "%s", hooked_msg); } if (hooked_msg != msg) { free(hooked_msg); } free(msg); } void VLog(LogLevel level, const char *fmt, va_list ap) { VLogNoFormat(level, fmt, ap, false); } /** * @brief Logs binary data in #buf, with unprintable bytes translated to '.'. * Message is prefixed with #prefix. * @param #buflen must be no more than CF_BUFSIZE */ void LogRaw(LogLevel level, const char *prefix, const void *buf, size_t buflen) { if (buflen > CF_BUFSIZE) { debug_abort_if_reached(); buflen = CF_BUFSIZE; } LoggingContext *lctx = GetCurrentThreadContext(); if (level <= lctx->report_level || level <= lctx->log_level) { const unsigned char *src = buf; unsigned char dst[CF_BUFSIZE+1]; assert(buflen < sizeof(dst)); size_t i; for (i = 0; i < buflen; i++) { dst[i] = isprint(src[i]) ? src[i] : '.'; } assert(i < sizeof(dst)); dst[i] = '\0'; /* And Log the translated buffer, which is now a valid string. */ Log(level, "%s%s", prefix, dst); } } void Log(LogLevel level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); VLog(level, fmt, ap); va_end(ap); } /** * The same as above, but for logging messages without formatting sequences * ("%s", "%d",...). Or more precisely, for *safe* logging of messages that may * contain such sequences (for example Log(LOG_LEVEL_ERR, "%s") can potentially * log some secrets). * * It doesn't have the FUNC_ATTR_PRINTF restriction that causes a compilation * warning/error if #msg is not a constant string. * * @note This is for special cases where #msg was already printf-like formatted, * the variadic arguments are ignored, they are here just so that * 'va_list ap' can be constructed and passed to VLogNoFormat(). * * @see CommitLogBuffer() */ static void LogNoFormat(LogLevel level, const char *msg, ...) { va_list ap; va_start(ap, msg); VLogNoFormat(level, msg, ap, true); va_end(ap); } static bool module_is_enabled[LOG_MOD_MAX]; static const char *log_modules[LOG_MOD_MAX] = { "", "evalctx", "expand", "iterations", "parser", "vartable", "vars", "locks", "ps", }; static enum LogModule LogModuleFromString(const char *s) { for (enum LogModule i = 0; i < LOG_MOD_MAX; i++) { if (strcmp(log_modules[i], s) == 0) { return i; } } return LOG_MOD_NONE; } void LogEnableModule(enum LogModule mod) { assert(mod < LOG_MOD_MAX); module_is_enabled[mod] = true; } void LogModuleHelp(void) { printf("\n--log-modules accepts a comma separated list of one or more of the following:\n\n"); printf(" help\n"); printf(" all\n"); for (enum LogModule i = LOG_MOD_NONE + 1; i < LOG_MOD_MAX; i++) { printf(" %s\n", log_modules[i]); } printf("\n"); } /** * Parse a string of modules, and enable the relevant DEBUG logging modules. * Example strings: * * all : enables all debug modules * help : enables nothing, but prints a help message * iterctx : enables the "iterctx" debug logging module * iterctx,vars: enables the 2 debug modules, "iterctx" and "vars" * * @NOTE modifies string #s but restores it before returning. */ bool LogEnableModulesFromString(char *s) { bool retval = true; const char *token = s; char saved_sep = ','; /* any non-NULL value will do */ while (saved_sep != '\0' && retval != false) { char *next_token = strchrnul(token, ','); saved_sep = *next_token; *next_token = '\0'; /* modify parameter s */ size_t token_len = next_token - token; if (strcmp(token, "help") == 0) { LogModuleHelp(); retval = false; /* early exit */ } else if (strcmp(token, "all") == 0) { for (enum LogModule j = LOG_MOD_NONE + 1; j < LOG_MOD_MAX; j++) { LogEnableModule(j); } } else { enum LogModule mod = LogModuleFromString(token); assert(mod < LOG_MOD_MAX); if (mod == LOG_MOD_NONE) { Log(LOG_LEVEL_WARNING, "Unknown debug logging module '%*s'", (int) token_len, token); } else { LogEnableModule(mod); } } *next_token = saved_sep; /* restore modified parameter s */ next_token++; /* bypass comma */ token = next_token; } return retval; } bool LogModuleEnabled(enum LogModule mod) { assert(mod > LOG_MOD_NONE); assert(mod < LOG_MOD_MAX); if (module_is_enabled[mod]) { return true; } else { return false; } } void LogDebug(enum LogModule mod, const char *fmt, ...) { assert(mod < LOG_MOD_MAX); /* Did we forget any entry in log_modules? */ nt_static_assert(sizeof(log_modules) / sizeof(log_modules[0]) == LOG_MOD_MAX); if (LogModuleEnabled(mod)) { va_list ap; va_start(ap, fmt); VLog(LOG_LEVEL_DEBUG, fmt, ap); va_end(ap); /* VLog(LOG_LEVEL_DEBUG, "%s: ...", */ /* debug_modules_description[mod_order], ...); */ } } void LogSetGlobalLevel(LogLevel level) { global_level = level; if (global_system_log_level == LOG_LEVEL_NOTHING) { LoggingPrivSetLevels(level, level); } else { LoggingPrivSetLevels(global_system_log_level, level); } } void LogSetGlobalLevelArgOrExit(const char *const arg) { LogLevel level = LogLevelFromString(arg); if (level == LOG_LEVEL_NOTHING) { // This function is used as part of initializing the logging // system. Using Log() can be considered incorrect, even though // it may "work". Let's just print an error to stderr: fprintf(stderr, "Invalid log level: '%s'\n", arg); DoCleanupAndExit(1); } LogSetGlobalLevel(level); } LogLevel LogGetGlobalLevel(void) { return global_level; } void LogSetGlobalSystemLogLevel(LogLevel level) { /* LOG_LEVEL_NOTHING means "unset" (see LogUnsetGlobalSystemLogLevel()) */ assert(level != LOG_LEVEL_NOTHING); global_system_log_level = level; LoggingPrivSetLevels(level, global_level); } void LogUnsetGlobalSystemLogLevel(void) { global_system_log_level = LOG_LEVEL_NOTHING; LoggingPrivSetLevels(global_level, global_level); } LogLevel LogGetGlobalSystemLogLevel(void) { return global_system_log_level; } void LoggingSetColor(bool enabled) { LoggingContext *lctx = GetCurrentThreadContext(); lctx->color = enabled; } // byte_magnitude and byte_unit are used to print human readable byte counts long byte_magnitude(long bytes) { const long Ki = 1024; const long Mi = Ki * 1024; const long Gi = Mi * 1024; if (bytes > 8 * Gi) { return bytes / Gi; } else if (bytes > 8 * Mi) { return bytes / Mi; } else if (bytes > 8 * Ki) { return bytes / Ki; } return bytes; } // Use this with byte_magnitude // Note that the cutoff is at 8x unit, because 3192 bytes is arguably more // useful than 3KiB const char *byte_unit(long bytes) { const long Ki = 1024; const long Mi = Ki * 1024; const long Gi = Mi * 1024; if (bytes > 8 * Gi) { return "GiB"; } else if (bytes > 8 * Mi) { return "MiB"; } else if (bytes > 8 * Ki) { return "KiB"; } return "bytes"; } void LogEntryDestroy(LogEntry *entry) { if (entry != NULL) { free(entry->msg); free(entry); } } void StartLoggingIntoBuffer(LogLevel min_level, LogLevel max_level) { assert((log_buffer == NULL) && (!logging_into_buffer)); if (log_buffer != NULL) { /* Should never happen. */ Log(LOG_LEVEL_ERR, "Re-initializing log buffer without prior commit, discarding messages"); DiscardLogBuffer(); } log_buffer = SeqNew(16, LogEntryDestroy); logging_into_buffer = true; min_log_into_buffer_level = min_level; max_log_into_buffer_level = max_level; } void DiscardLogBuffer() { SeqDestroy(log_buffer); log_buffer = NULL; logging_into_buffer = false; } void CommitLogBuffer() { assert(logging_into_buffer); assert(log_buffer != NULL); if (log_buffer == NULL) { /* Should never happen. */ Log(LOG_LEVEL_ERR, "Attempt to commit an unitialized log buffer"); } /* Disable now so that LogNonConstant() below doesn't append the message * into the buffer instaed of logging it. */ logging_into_buffer = false; const size_t n_entries = SeqLength(log_buffer); for (size_t i = 0; i < n_entries; i++) { LogEntry *entry = SeqAt(log_buffer, i); LogNoFormat(entry->level, entry->msg); } DiscardLogBuffer(); } cfengine-3.24.2/libntech/libutils/unicode.h0000644000000000000000000000376415010704254020604 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef UNICODE_H #define UNICODE_H #include // bool #include // size_t #include /** * Dumb conversion from 8-bit strings to 16-bit. * * Does not take locales or any special characters into account. * @param dst The destination string. * @param src The source string. * @param size The size of dst, in wchars. */ void ConvertFromCharToWChar(int16_t *dst, const char *src, size_t size); /** * Dumb conversion from 16-bit strings to 8-bit. * * Does not take locales or any special characters into account. Since * it's possible to lose information this way, this function returns a * value indicating whether the conversion was "clean" or whether information * was lost. * @param dst The destination string. * @param src The source string. * @param size The size of dst, in bytes. * @return Returns true if conversion was successful. Returns false if the * 16-bit string could not be converted cleanly to 8-bit. Note that dst * will always contain a valid string. */ bool ConvertFromWCharToChar(char *dst, const int16_t *src, size_t size); #endif // !UNICODE_H cfengine-3.24.2/libntech/libutils/unix_dir.c0000644000000000000000000001277515010704254020774 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include struct Dir_ { DIR *dirh; struct dirent *entrybuf; }; static size_t GetNameMax(DIR *dirp); static size_t GetDirentBufferSize(size_t path_len); Dir *DirOpen(const char *dirname) { Dir *ret = xcalloc(1, sizeof(Dir)); int safe_fd; safe_fd = safe_open(dirname, O_RDONLY); if (safe_fd < 0) { free(ret); return NULL; } ret->dirh = opendir(dirname); if (ret->dirh == NULL) { close(safe_fd); free(ret); return NULL; } struct stat safe_stat, dir_stat; bool stat_failed = fstat(safe_fd, &safe_stat) < 0 || fstat(dirfd(ret->dirh), &dir_stat) < 0; close(safe_fd); if (stat_failed) { closedir(ret->dirh); free(ret); return NULL; } // Make sure we opened the same file descriptor as safe_open did. if (safe_stat.st_dev != dir_stat.st_dev || safe_stat.st_ino != dir_stat.st_ino) { closedir(ret->dirh); free(ret); errno = EACCES; return NULL; } size_t dirent_buf_size = GetDirentBufferSize(GetNameMax(ret->dirh)); ret->entrybuf = xcalloc(1, dirent_buf_size); return ret; } /* * Returns NULL on EOF or error. * * Sets errno to 0 for EOF and non-0 for error. */ const struct dirent *DirRead(Dir *dir) { assert(dir != NULL); errno = 0; #ifdef __linux__ return readdir((DIR *) dir->dirh); // Sets errno for error #else // "exotics" use readdir_r struct dirent *ret; int err = readdir_r((DIR *) dir->dirh, dir->entrybuf, &ret); if (err != 0) { errno = err; return NULL; } if (ret == NULL) { return NULL; } return ret; #endif } void DirClose(Dir *dir) { closedir((DIR *) dir->dirh); free(dir->entrybuf); free(dir); } /* * Taken from http://womble.decadent.org.uk/readdir_r-advisory.html * * Issued by Ben Hutchings , 2005-11-02. * * Licence * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following condition: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* * Calculate the required buffer size (in bytes) for directory entries read from * the given directory handle. Return -1 if this this cannot be done. * * This code does not trust values of NAME_MAX that are less than 255, since * some systems (including at least HP-UX) incorrectly define it to be a smaller * value. * * If you use autoconf, include fpathconf and dirfd in your AC_CHECK_FUNCS list. * Otherwise use some other method to detect and use them where available. */ #if defined(HAVE_FPATHCONF) && defined(_PC_NAME_MAX) static size_t GetNameMax(DIR *dirp) { long name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); if (name_max != -1) { return name_max; } # if defined(NAME_MAX) return (NAME_MAX > 255) ? NAME_MAX : 255; # else return (size_t) (-1); # endif } #else /* FPATHCONF && _PC_NAME_MAX */ # if defined(NAME_MAX) static size_t GetNameMax(DIR *dirp) { return (NAME_MAX > 255) ? NAME_MAX : 255; } # else # error "buffer size for readdir_r cannot be determined" # endif #endif /* FPATHCONF && _PC_NAME_MAX */ /* * Returns size of memory enough to hold path name_len bytes long. */ static size_t GetDirentBufferSize(size_t name_len) { size_t name_end = (size_t) offsetof(struct dirent, d_name) + name_len + 1; return MAX(name_end, sizeof(struct dirent)); } struct dirent *AllocateDirentForFilename(const char *filename) { int length = strlen(filename); struct dirent *entry = xcalloc(1, GetDirentBufferSize(length)); // d_name is fixed length, but we have allocated extra space using xcalloc // cast is to silence the compiler warning which checks length of d_name: memcpy((char *)entry->d_name, filename, length + 1); return entry; } cfengine-3.24.2/libntech/libutils/dir_priv.h0000644000000000000000000000200315010704254020755 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DIR_IMPL_H #define CFENGINE_DIR_IMPL_H struct dirent *AllocateDirentForFilename(const char *filename); #endif cfengine-3.24.2/libntech/libutils/encode.c0000644000000000000000000000351015010704254020373 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* BUF_MEM */ #include /* BIO_* */ #include /* BIO_f_base64 */ #include char *StringEncodeBase64(const char *str, size_t len) { assert(str); if (!str) { return NULL; } if (len == 0) { return xcalloc(1, sizeof(char)); } BIO *b64 = BIO_new(BIO_f_base64()); BIO *bio = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bio); BIO_write(b64, str, len); if (!BIO_flush(b64)) { assert(false && "Unable to encode string to base64" && str); return NULL; } BUF_MEM *buffer = NULL; BIO_get_mem_ptr(b64, &buffer); char *out = xcalloc(1, buffer->length); memcpy(out, buffer->data, buffer->length - 1); out[buffer->length - 1] = '\0'; BIO_free_all(b64); return out; } cfengine-3.24.2/libntech/libutils/csv_writer.c0000644000000000000000000000740615010704254021335 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include struct CsvWriter_ { Writer *w; bool beginning_of_line; bool terminate_last_line; }; /*****************************************************************************/ static void WriteCsvEscapedString(Writer *w, const char *str); static void CsvWriterFieldVF(CsvWriter * csvw, const char *fmt, va_list ap) FUNC_ATTR_PRINTF(2, 0); /*****************************************************************************/ CsvWriter *CsvWriterOpenSpecifyTerminate(Writer *w, bool terminate_last_line) { CsvWriter *csvw = xmalloc(sizeof(CsvWriter)); csvw->w = w; csvw->beginning_of_line = true; csvw->terminate_last_line = terminate_last_line; return csvw; } CsvWriter *CsvWriterOpen(Writer *w) { return CsvWriterOpenSpecifyTerminate(w, true); } /*****************************************************************************/ void CsvWriterField(CsvWriter * csvw, const char *str) { assert(csvw != NULL); if (csvw->beginning_of_line) { csvw->beginning_of_line = false; } else { WriterWriteChar(csvw->w, ','); } if (strpbrk(str, "\",\r\n")) { WriteCsvEscapedString(csvw->w, str); } else { WriterWrite(csvw->w, str); } } /*****************************************************************************/ void CsvWriterFieldF(CsvWriter * csvw, const char *fmt, ...) { va_list ap; va_start(ap, fmt); CsvWriterFieldVF(csvw, fmt, ap); va_end(ap); } /*****************************************************************************/ void CsvWriterNewRecord(CsvWriter * csvw) { assert(csvw != NULL); WriterWrite(csvw->w, "\r\n"); csvw->beginning_of_line = true; } /*****************************************************************************/ void CsvWriterClose(CsvWriter * csvw) { assert(csvw != NULL); if (!csvw->beginning_of_line && csvw->terminate_last_line) { WriterWrite(csvw->w, "\r\n"); } free(csvw); } /*****************************************************************************/ static void CsvWriterFieldVF(CsvWriter * csvw, const char *fmt, va_list ap) { /* * We are unable to avoid allocating memory here, as we need full string * contents before deciding whether there is a " in string, and hence whether * the field needs to be escaped in CSV */ char *str; xvasprintf(&str, fmt, ap); CsvWriterField(csvw, str); free(str); } /*****************************************************************************/ static void WriteCsvEscapedString(Writer *w, const char *s) { WriterWriteChar(w, '"'); while (*s) { if (*s == '"') { WriterWriteChar(w, '"'); } WriterWriteChar(w, *s); s++; } WriterWriteChar(w, '"'); } Writer *CsvWriterGetWriter(CsvWriter *csvw) { assert(csvw != NULL); return csvw->w; } cfengine-3.24.2/libntech/libutils/hash_map_priv.h0000644000000000000000000000436515010704254021774 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_HASH_MAP_PRIV_H #define CFENGINE_HASH_MAP_PRIV_H #include // size_t #include // FILE #include typedef struct BucketListItem_ { MapKeyValue value; struct BucketListItem_ *next; } BucketListItem; typedef struct { MapHashFn hash_fn; MapKeyEqualFn equal_fn; MapDestroyDataFn destroy_key_fn; MapDestroyDataFn destroy_value_fn; BucketListItem **buckets; size_t size; size_t init_size; size_t load; size_t max_threshold; size_t min_threshold; } HashMap; typedef struct { HashMap *map; BucketListItem *cur; size_t bucket; } HashMapIterator; HashMap *HashMapNew(MapHashFn hash_fn, MapKeyEqualFn equal_fn, MapDestroyDataFn destroy_key_fn, MapDestroyDataFn destroy_value_fn, size_t init_size); bool HashMapInsert(HashMap *map, void *key, void *value); bool HashMapRemove(HashMap *map, const void *key); MapKeyValue *HashMapGet(const HashMap *map, const void *key); void HashMapClear(HashMap *map); void HashMapSoftDestroy(HashMap *map); void HashMapDestroy(HashMap *map); void HashMapPrintStats(const HashMap *hmap, FILE *f); /******************************************************************************/ HashMapIterator HashMapIteratorInit(HashMap *m); MapKeyValue *HashMapIteratorNext(HashMapIterator *i); #endif cfengine-3.24.2/libntech/libutils/dir.h0000644000000000000000000000206715010704254017727 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DIR_H #define CFENGINE_DIR_H typedef struct Dir_ Dir; Dir *DirOpen(const char *dirname); const struct dirent *DirRead(Dir *dir); void DirClose(Dir *dir); #endif cfengine-3.24.2/libntech/libutils/alloc.c0000644000000000000000000000430215010704254020230 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #define ALLOC_IMPL #include #include #include static void *CheckResult(void *ptr, const char *fn, bool check_result) { if ((ptr == NULL) && (check_result)) { fputs(fn, stderr); fputs("CRITICAL: Unable to allocate memory\n", stderr); DoCleanupAndExit(255); } return ptr; } void *xmalloc(size_t size) { return CheckResult(malloc(size), "xmalloc", size != 0); } void *xcalloc(size_t nmemb, size_t size) { return CheckResult(calloc(nmemb, size), "xcalloc", (nmemb != 0) && (size != 0)); } void *xrealloc(void *ptr, size_t size) { return CheckResult(realloc(ptr, size), "xrealloc", size != 0); } char *xstrdup(const char *str) { return CheckResult(strdup(str), "xstrdup", true); } char *xstrndup(const char *str, size_t n) { return CheckResult(strndup(str, n), "xstrndup", true); } void *xmemdup(const void *data, size_t size) { return CheckResult(memdup(data, size), "xmemdup", size != 0); } int xasprintf(char **strp, const char *fmt, ...) { va_list ap; va_start(ap, fmt); int res = xvasprintf(strp, fmt, ap); va_end(ap); return res; } int xvasprintf(char **strp, const char *fmt, va_list ap) { int res = vasprintf(strp, fmt, ap); CheckResult(res == -1 ? NULL : *strp, "xvasprintf", true); return res; } cfengine-3.24.2/libntech/libutils/misc_lib.c0000644000000000000000000001125315010704254020722 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include unsigned long UnsignedModulus(long dividend, long divisor) { return ((dividend % divisor) + divisor) % divisor; } size_t UpperPowerOfTwo(size_t v) { // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } void __ProgrammingError(const char *file, int lineno, const char *format, ...) { va_list ap; char *fmt = NULL; va_start(ap, format); xasprintf(&fmt, "%s:%d: Programming Error: %s\n", file, lineno, format); vfprintf(stdout, fmt, ap); va_end(ap); free(fmt); #ifdef NDEBUG DoCleanupAndExit(255); #else abort(); #endif } /** @brief Log unexpected runtime error to stderr, do not exit program. */ void __UnexpectedError(const char *file, int lineno, const char *format, ...) { va_list ap; char *fmt = NULL; va_start(ap, format); xasprintf(&fmt, "%s:%d: Unexpected Error - this is a BUG, please report it: %s\n", file, lineno, format); vfprintf(stderr, fmt, ap); va_end(ap); free(fmt); } void xclock_gettime(clockid_t clk_id, struct timespec *ts) { int ret = clock_gettime(clk_id, ts); if (ret != 0) { Log(LOG_LEVEL_VERBOSE, "clock_gettime() failed (%s), falling back to time()", GetErrorStr()); *ts = (struct timespec) { .tv_sec = time(NULL) }; } } /** * Unchecked version of snprintf(). For when you're *sure* the result fits in * the buffer, and you don't want to check it. In other words, NO PART OF THE * OUTPUT SHOULD BE DEPENDENT ON USER DATA! * * Only exception is usage in the unit tests, where we use it all over the * place in order to flag stupid programming mistakes. */ void xsnprintf(char *str, size_t str_size, const char *format, ...) { va_list ap; va_start(ap, format); int ret = vsnprintf(str, str_size, format, ap); va_end(ap); if (ret < 0) /* error */ { *str = '\0'; Log(LOG_LEVEL_WARNING, "Unexpected failure from snprint(\"%s\"): %s", format, GetErrorStr()); } else if ((size_t) ret >= str_size) /* output truncated */ { #ifdef NDEBUG UnexpectedError("Result of snprintf(\"%s\") truncated at %zu chars", format, str_size); #else ProgrammingError("Result of snprintf(\"%s\") truncated at %zu chars", format, str_size); #endif } } int setenv_wrapper(const char *name, const char *value, int overwrite) { #if defined(__linux__) || defined(__APPLE__) return setenv(name, value, overwrite); #else if (NULL_OR_EMPTY(name) || strchr(name, '=') != NULL) { errno = EINVAL; return -1; } if (overwrite == 0 && getenv(name) != NULL) { return 0; // Don't overwrite } const size_t buffer_size = 1024; const char buf[buffer_size]; int string_length = snprintf(buf, buffer_size, "%s=%s", name, value); if (string_length >= buffer_size) { errno = EINVAL; return -1; // Combined string is too long } // Fixing this leak on platforms which don't have setenv is difficult(!) return putenv(xstrdup(buf)); #endif } int putenv_wrapper(const char* str) { char *const name = xstrdup(str); char *const equal_sign = strchr(name, '='); if (equal_sign == NULL) { free(name); errno = EINVAL; return -1; } *equal_sign = '\0'; char *value = equal_sign + 1; const int ret = setenv_wrapper(name, value, 1); free(name); return ret; } cfengine-3.24.2/libntech/libutils/array_map.c0000644000000000000000000000745315010704254021123 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* FIXME: make configurable and move to map.c */ #define TINY_LIMIT 14 ArrayMap *ArrayMapNew(MapKeyEqualFn equal_fn, MapDestroyDataFn destroy_key_fn, MapDestroyDataFn destroy_value_fn) { ArrayMap *map = xcalloc(1, sizeof(ArrayMap)); map->equal_fn = equal_fn; map->destroy_key_fn = destroy_key_fn; map->destroy_value_fn = destroy_value_fn; map->values = xcalloc(1, sizeof(MapKeyValue) * TINY_LIMIT); return map; } int ArrayMapInsert(ArrayMap *map, void *key, void *value) { if (map->size == TINY_LIMIT) { return 0; } for (int i = 0; i < map->size; ++i) { if (map->equal_fn(map->values[i].key, key)) { /* Replace the key with the new one despite those two being the * same, since the new key might be referenced somewhere inside * the new value. */ map->destroy_key_fn(map->values[i].key); map->destroy_value_fn(map->values[i].value); map->values[i].key = key; map->values[i].value = value; return 1; } } map->values[map->size++] = (MapKeyValue) { key, value }; return 2; } bool ArrayMapRemove(ArrayMap *map, const void *key) { for (int i = 0; i < map->size; ++i) { if (map->equal_fn(map->values[i].key, key)) { map->destroy_key_fn(map->values[i].key); map->destroy_value_fn(map->values[i].value); memmove(map->values + i, map->values + i + 1, sizeof(MapKeyValue) * (map->size - i - 1)); map->size--; return true; } } return false; } MapKeyValue *ArrayMapGet(const ArrayMap *map, const void *key) { for (int i = 0; i < map->size; ++i) { if (map->equal_fn(map->values[i].key, key)) { return map->values + i; } } return NULL; } void ArrayMapClear(ArrayMap *map) { for (int i = 0; i < map->size; ++i) { map->destroy_key_fn(map->values[i].key); map->destroy_value_fn(map->values[i].value); } map->size = 0; } void ArrayMapSoftDestroy(ArrayMap *map) { if (map) { for (int i = 0; i < map->size; ++i) { map->destroy_key_fn(map->values[i].key); } map->size = 0; free(map->values); free(map); } } void ArrayMapDestroy(ArrayMap *map) { if (map) { ArrayMapClear(map); free(map->values); free(map); } } /******************************************************************************/ ArrayMapIterator ArrayMapIteratorInit(ArrayMap *map) { return (ArrayMapIterator) { map, 0 }; } MapKeyValue *ArrayMapIteratorNext(ArrayMapIterator *i) { if (i->pos >= i->map->size) { return NULL; } else { return &i->map->values[i->pos++]; } } cfengine-3.24.2/libntech/libutils/json-utils.c0000644000000000000000000003122415010704254021250 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include // Log() #include // safe_fopen() #include // TrimWhitespace() #include #include // JsonParseYamlFile() #include #define ENV_BYTE_LIMIT 4096 /** * @brief Filters a string, according to env file format * * This is used to parse the part after the equal sign in an env file * Leading and trailing whitespace should already be removed * Nonescaped single or double quotes must either be at src[0] to start a * quoted string or inside a quoted string of the other type. * Will terminate string after closing quote, even when there's more * Closing quote is optional (implied at null terminator) * * Supported escape characters: \\ \" \' \n * Anything else will just add the character directly, ex: \x -> x * * @param src Copy from pointer, can be same as dst * @param dst Copy to pointer, can be same as src * @return beginning of processed string, either dst or dst + 1 */ static char *filtered_copy(const char *src, char *dst) { assert(src); assert(dst); char *beginning = dst; char opening_quote = '\0'; // Check for opening quote, must be at src[0] if (*src == '\"' || *src == '\'') { opening_quote = *src; ++src; } // Loop until null terminator or quote matching opening_quote: while (*src != '\0' && (*src != opening_quote)) { if (opening_quote == '\0' && (*src == '\"' || *src == '\'')) { // Return NULL when encountering an unmatched, unescaped quote // Invalid input: AB"CD // Correct ways: AB\"CD or 'AB"CD' return NULL; } if (*src == '\\') { // Backslash escape char ++src; // Special case for \n newline: if (*src == 'n') { *dst = '\n'; ++src; ++dst; continue; } // Otherwise: copy next char directly } *dst = *src; ++src; ++dst; } *dst = '\0'; return beginning; } /** * @brief Splits a line of en env file into key and value string * * See filtered_copy for details on how value in (key-value pair) is parsed * Empty lines are skipped * Lines with first nonspace symbol '#' are skipped (comments) * To preserve whitespace use quotes: WHITESPACE=" " * * @param raw_line input from CfReadLine. Will be edited! * @param key_out Where to store pointer to key in raw_line * @param value_out Where to store pointer to value in raw_line * @param filename_for_log Optional name for logging purposes */ void ParseEnvLine(char *raw_line, char **key_out, char **value_out, const char *filename_for_log, int linenumber) { assert(raw_line); assert(key_out); assert(value_out); char *key = NULL; char *value = NULL; *key_out = NULL; *value_out = NULL; char *line = TrimWhitespace(raw_line); if (NULL_OR_EMPTY(line)) { return; } const char *myname = "ParseEnvLine"; size_t line_length = strlen(line); if (line[0] == '#' || line_length == 0) { return; } char *next_equal = strchr(line, '='); if (next_equal == NULL) { Log(LOG_LEVEL_DEBUG, "%s: Line %d in ENV file '%s' isn't empty, but was skipped because it's missing an equal sign", myname, linenumber, filename_for_log); return; } long equal_index = next_equal - line; if (equal_index == 0) { Log(LOG_LEVEL_DEBUG, "%s: Line %d in ENV file '%s' was skipped because it's missing a key", myname, linenumber, filename_for_log); return; } *next_equal = '\0'; key = TrimWhitespace(line); value = TrimWhitespace(next_equal + 1); // Copy from value to value (dest=src) and return new starting pointer // new_start = filtered_copy(src,dst) // Modifies the string in place, removing enclosing quotes and // obeys backslash escape characters value = filtered_copy(value, value); if (value != NULL && key != NULL) { // Succeeded in finding both key and value, copy to output *key_out = key; *value_out = value; } else if (value != NULL || key != NULL) { // Parsing failed for either key or value, print log message and skip Log(LOG_LEVEL_DEBUG, "%s: Line %d in ENV file '%s' was skipped because it has invalid syntax", myname, linenumber, filename_for_log); } } /** * @brief Parses an env file and creates a key-value pair json element * * Creates JSON element where all keys and values are strings * * @param input_path file to read from ex: "/etc/os-release" * @param size_max Maximum size of env file (in bytes) * @param json_out Where to save pointer to new JsonElement, must destroy * @return true for success, false for failure */ bool JsonParseEnvFile(const char *input_path, size_t size_max, JsonElement **json_out) { assert(json_out != NULL); assert(input_path != NULL); const char *myname = "JsonParseEnvFile"; size_t line_size = ENV_BYTE_LIMIT; char *key, *value; int linenumber = 0; size_t byte_count = 0; FILE *fin = safe_fopen(input_path, "r"); if (fin == NULL) { Log(LOG_LEVEL_VERBOSE, "%s cannot open the ENV file '%s' (fopen: %s)", myname, input_path, GetErrorStr()); return false; } JsonElement *json = JsonObjectCreate(10); char *raw_line = xmalloc(line_size); while (CfReadLine(&raw_line, &line_size, fin) != -1) { ++linenumber; byte_count += strlen(raw_line); if (byte_count > size_max) { Log(LOG_LEVEL_VERBOSE, "%s: ENV file '%s' exceeded byte limit %zu at line %d", myname, input_path, size_max, linenumber); Log(LOG_LEVEL_VERBOSE, "Done with ENV file, the rest will not be parsed"); break; } ParseEnvLine(raw_line, &key, &value, input_path, linenumber); if (key != NULL && value != NULL) { JsonObjectAppendString(json, key, value); } } bool reached_eof = feof(fin); fclose(fin); free(raw_line); if (!reached_eof && byte_count <= size_max) { Log(LOG_LEVEL_ERR, "%s: failed to read ENV file '%s'. (fread: %s)", myname, input_path, GetErrorStr()); JsonDestroy(json); return false; } *json_out = json; return true; } bool JsonParseCsvFile(const char *input_path, size_t size_max, JsonElement **json_out) { assert(json_out != NULL); const char *myname = "JsonParseCsvFile"; char *line; size_t byte_count = 0; int linenumber = 0; FILE *fin = safe_fopen(input_path, "r"); if (fin == NULL) { Log(LOG_LEVEL_VERBOSE, "%s cannot open the csv file '%s' (fopen: %s)", myname, input_path, GetErrorStr()); return false; } JsonElement *const json = JsonArrayCreate(50); if (feof(fin)) { *json_out = json; Log(LOG_LEVEL_VERBOSE, "%s: CSV file '%s' was empty, so nothing was parsed", myname, input_path); return true; } while ((line = GetCsvLineNext(fin)) != NULL) { ++linenumber; byte_count += strlen(line); if (byte_count > size_max) { Log(LOG_LEVEL_VERBOSE, "%s: CSV file '%s' exceeded byte limit %zu at line %d", myname, input_path, size_max, linenumber); Log(LOG_LEVEL_VERBOSE, "Done with CSV file, the rest will not be parsed"); free(line); break; } Seq *list = SeqParseCsvString(line); free(line); if (list != NULL) { JsonElement *line_arr = JsonArrayCreate(SeqLength(list)); for (size_t i = 0; i < SeqLength(list); i++) { JsonArrayAppendString(line_arr, SeqAt(list, i)); } SeqDestroy(list); JsonArrayAppendArray(json, line_arr); } } bool reached_eof = feof(fin); if (!reached_eof && byte_count <= size_max) { Log(LOG_LEVEL_ERR, "%s: unable to read line from CSV file '%s'. (fread: %s)", myname, input_path, GetErrorStr()); JsonDestroy(json); fclose(fin); return false; } if (JsonLength(json) == 0) { Log(LOG_LEVEL_WARNING, "%s: CSV file '%s' is not empty, but nothing was parsed", myname, input_path); Log(LOG_LEVEL_WARNING, "Make sure the file contains DOS (CRLF) line endings"); } fclose(fin); *json_out = json; return true; } JsonElement *JsonReadDataFile(const char *log_identifier, const char *input_path, const DataFileType requested_mode, size_t size_max) { const char *myname = log_identifier ? log_identifier : "JsonReadDataFile"; bool env_mode = (requested_mode == DATAFILETYPE_ENV); bool csv_mode = (requested_mode == DATAFILETYPE_CSV); bool yaml_mode = (requested_mode == DATAFILETYPE_YAML); if (env_mode || csv_mode) { JsonElement *json = NULL; bool success; if (env_mode) { success = JsonParseEnvFile(input_path, size_max, &json); } else { success = JsonParseCsvFile(input_path, size_max, &json); } if (success == false) { return NULL; } return json; } JsonElement *json = NULL; JsonParseError res = JsonParseAnyFile(input_path, size_max, &json, yaml_mode); if ((res == JSON_PARSE_ERROR_NO_DATA) || (res == JSON_PARSE_ERROR_NO_SUCH_FILE)) { Log(LOG_LEVEL_ERR, "%s: data error parsing %s file '%s': %s", myname, DataFileTypeToString(requested_mode), input_path, JsonParseErrorToString(res)); } else if (res != JSON_PARSE_OK) { Log(LOG_LEVEL_ERR, "%s: error parsing %s file '%s': %s", myname, DataFileTypeToString(requested_mode), input_path, JsonParseErrorToString(res)); } else if (JsonGetElementType(json) == JSON_ELEMENT_TYPE_PRIMITIVE) { Log(LOG_LEVEL_ERR, "%s: non-container from parsing %s file '%s'", myname, DataFileTypeToString(requested_mode), input_path); JsonDestroy(json); } else { return json; } return NULL; } DataFileType GetDataFileTypeFromString(const char *const requested_mode) { DataFileType type = DATAFILETYPE_UNKNOWN; if (StringEqual_IgnoreCase(requested_mode, "yaml")) { type = DATAFILETYPE_YAML; } else if (StringEqual_IgnoreCase(requested_mode, "csv")) { type = DATAFILETYPE_CSV; } else if (StringEqual_IgnoreCase(requested_mode, "env")) { type = DATAFILETYPE_ENV; } else if (StringEqual_IgnoreCase(requested_mode, "json")) { type = DATAFILETYPE_JSON; } return type; } DataFileType GetDataFileTypeFromSuffix(const char *filename) { if (StringEndsWithCase(filename, ".csv", true)) { return DATAFILETYPE_CSV; } else if (StringEndsWithCase(filename, ".yaml", true) || StringEndsWithCase(filename, ".yml", true)) { return DATAFILETYPE_YAML; } else if (StringEndsWithCase(filename, ".env", true)) { return DATAFILETYPE_ENV; } else // always default to JSON { return DATAFILETYPE_JSON; } } const char *DataFileTypeToString(const DataFileType type) { switch (type) { case DATAFILETYPE_CSV: return "CSV"; case DATAFILETYPE_YAML: return "YAML"; case DATAFILETYPE_ENV: return "ENV"; case DATAFILETYPE_JSON: return "JSON"; default: return "unknown"; } } cfengine-3.24.2/libntech/libutils/passopenfile.c0000644000000000000000000004074315010704254021637 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include /* Local tuning parameter: should anything else know about it ? */ #define MAX_MESSAGE_SIZE 1024 /* strlen()+1 limit on text transmitted */ #ifdef __MINGW32__ #include static const char PID_FMT[] = "PID: %lu\n"; #define PID_MSG_SIZE (PRINTSIZE(unsigned long) + 8) static const char ACK_MSG[] = "ACK\n"; typedef uint32_t MSG_LEN_T; /* TODO: replace explicit waiting with use of blocking UDS. */ /* Package a call to select(), to avoid duplicating boilerplate code. */ static bool wait_for(const int uds, bool write, bool *ready) { struct timeval tv; fd_set fds; FD_ZERO(&fds); FD_SET(uds, &fds); tv.tv_sec = 1; /* Wait for up to a second */ tv.tv_usec = 0; int ret; if (write) { ret = select(uds + 1, NULL, &fds, NULL, &tv); } else { ret = select(uds + 1, &fds, NULL, NULL, &tv); } if (ret < 0) { return false; } *ready = FD_ISSET(uds, &fds); return true; } bool PassOpenFile_Put(int uds, int descriptor, const char *text) { /* From the WSADuplicateSocket() doc [0]: "A process can call * closesocket on a duplicated socket and the descriptor will * become deallocated. The underlying socket, however, will remain * open until closesocket is called by the last remaining * descriptor." So our caller can cf_closesocket(descriptor), as * long as they do it after the recipient calls WSASocket(); we * include an ACK at the end of this protocol to ensure that. * * [0] https://msdn.microsoft.com/en-us/library/windows/desktop/ms741565(v=vs.85).aspx */ WSAPROTOCOL_INFO blob; /* Receive pid from peer */ char buffer[PID_MSG_SIZE + 1]; ssize_t got = recv(uds, buffer, PID_MSG_SIZE, 0); if (got < 0) { Log(LOG_LEVEL_ERR, "Failed to read PID to which to pass descriptor"); return false; } buffer[got] = '\0'; unsigned long pid; if (sscanf(buffer, PID_FMT, &pid) != 1) { Log(LOG_LEVEL_ERR, "Failed to parse peer PID from: %s", buffer); return false; } else if (WSADuplicateSocket(descriptor, pid, &blob) != 0) { Log(LOG_LEVEL_ERR, "Failed to generate socket transmission data blob"); return false; } bool ready; if (!wait_for(uds, true, &ready)) { Log(LOG_LEVEL_ERR, "Can't pass socket to peer (select: %s)", GetErrorStr()); return false; } else if (!ready) { Log(LOG_LEVEL_ERR, "Can't pass socket (peer not ready)"); return false; } else { /* Transmit blob and text over UDS: */ ssize_t had = send(uds, (const void*)&blob, sizeof(blob), 0); /* Casts needed because MinGW thinks send(,const char*,,) :-( */ if (had == sizeof(blob)) { MSG_LEN_T size = text ? strlen(text) + 1 : 0; had = send(uds, (const void*)&size, sizeof(size), 0); if (had == sizeof(size)) { if (text) { had = send(uds, text, size, 0); } } else { had = -1; } } else { had = -1; } if (had < 0) { Log(LOG_LEVEL_ERR, "Failed to send socket-blob and accompanying text to peer"); return false; } } /* Wait for ACK so we don't closesocket() before recipient has opened it */ if (!wait_for(uds, false, &ready)) { Log(LOG_LEVEL_ERR, "Can't get ACK from descriptor recipient (select: %s)", GetErrorStr()); } else if (!ready) { Log(LOG_LEVEL_ERR, "Can't get ACK from descriptor recipient (peer not ready)"); } else { char answer[sizeof(ACK_MSG) + 1]; /* +1 for the '\0' below */ ssize_t got = recv(uds, answer, sizeof(ACK_MSG), 0); if (got > 0) { answer[got] = '\0'; /* In case unexpected message isn't terminated */ if (strcmp(answer, ACK_MSG) != 0) { Log(LOG_LEVEL_WARNING, "ACK message wasn't as expected: '%s' != '%s' (ignoring)", ACK_MSG, answer); } return true; } } return false; } int PassOpenFile_Get(int uds, char **text) { SOCKET descriptor = SOCKET_ERROR; /* Deliver pid to peer over uds */ char msg[PID_MSG_SIZE]; nt_static_assert(sizeof(PID_FMT) - 3 + PRINTSIZE(unsigned long) <= PID_MSG_SIZE); unsigned long pid = GetCurrentProcessId(); int len = snprintf(msg, sizeof(msg), PID_FMT, pid); assert(len > 0 && len < PID_MSG_SIZE); send(uds, msg, len + 1, 0); bool ready; if (!wait_for(uds, false, &ready)) { Log(LOG_LEVEL_ERR, "Can't receive descriptor (select: %s)", GetErrorStr()); return -1; } else if (!ready) { Log(LOG_LEVEL_VERBOSE, "No descriptor received."); return -1; } else { WSAPROTOCOL_INFO blob; /* Receive blob and text over UDS: */ ssize_t got = recv(uds, (const void*)&blob, sizeof(blob), 0); /* Casts needed because MinGW thinks recv(,const char*,,) :-( */ if (got == sizeof(blob)) { descriptor = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, /* Args after the blob are ignored. */ &blob, 0, WSA_FLAG_OVERLAPPED); if (descriptor == SOCKET_ERROR) { return -1; } /* else we *must* either use or closesocket() this descriptor. */ if (text) { *text = NULL; } MSG_LEN_T size; /* Including space for final '\0' byte: */ got = recv(uds, (const void*)&size, sizeof(size), 0); if (got == sizeof(size)) { if (size) { char *buffer = malloc(size); if (*text) { got = recv(uds, buffer, size, 0); if (got != size) { Log(LOG_LEVEL_ERR, "Failed to receive whole text accompanying descriptor"); } } else { got = 0; /* != size */ Log(LOG_LEVEL_ERR, "Failed to allocate buffer for text accompanying descriptor"); } if (text && got == size) { *text = buffer; } else { free(buffer); } } } else { Log(LOG_LEVEL_ERR, "Failed to read size of text accompanying descriptor"); size = 0; } if (text && size && !*text) { closesocket(descriptor); return -1; } } else { Log(LOG_LEVEL_ERR, "Failed to receive whole descriptor blob"); return -1; } } /* Send ACK now that we've opened our end of the socket. */ if (!wait_for(uds, true, &ready)) { Log(LOG_LEVEL_ERR, "Can't ACK received descriptor (select: %s)", GetErrorStr()); } else if (!ready) { Log(LOG_LEVEL_VERBOSE, "No descriptor supplier to ACK to, aborting receipt."); } else { send(uds, ACK_MSG, sizeof(ACK_MSG), 0); return descriptor; } closesocket(descriptor); return -1; } #else /* Unix: */ #ifdef HAVE_MSGHDR_MSG_CONTROL /* This is the modern interface. It should be present in most modern * Unix systems (conforming to the Single UNIX Specification). * * Transferred file descriptors "behave as though they have been * created with dup(2)" according to Linux's unix(7); which means the * sender can close() its end without prejudice to the recipient's use * of its copy. */ #define INTERFACE_STYLE "SUS" # ifndef CMSG_SPACE /* Solaris 9 contains support for .msg_control but lacks these macros * (here copied from Linux's - thankfully they're platform * agnostic) that we use to manipulate its header: */ #define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \ & (size_t) ~(sizeof (size_t) - 1)) #define CMSG_SPACE(len) (CMSG_ALIGN (len) \ + CMSG_ALIGN (sizeof (struct cmsghdr))) #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) # endif #elif defined(HAVE_MSGHDR_ACCRIGHTS) /* This is the old (BSD) interface. No Linux should use this, it's * only known to be present in older BSD-based Unixes. */ #define INTERFACE_STYLE "BSD" #else #error "No support for connection sharing on this platform :-(" #endif #ifndef MSG_WAITALL /* Linux >= 2.2 */ #define MSG_WAITALL 0 #endif static const char NULL_MSG[] = "\0NULL"; bool PassOpenFile_Put(int uds, int descriptor, const char *text) { struct msghdr message; struct iovec vector; size_t msglen = text ? strlen(text) + 1 : sizeof(NULL_MSG); assert(MAX_MESSAGE_SIZE >= msglen); Log(LOG_LEVEL_VERBOSE, "Connected to peer, passing descriptor %d with %s %s", descriptor, text ? "text:" : "no", text ? text : "text"); /* Prepare the message * * We need to send at least one byte of content, in an iovec, so * that a message actually gets received at the other end. This * means that we want to send *at least something* even when our * text is NULL. Fortunately, what we send isn't constrained by * C-string '\0'-termination, so we can send a message that * follows a '\0' byte with non-'\0' content (the NULL_MSG above) * which is definitely distinct from what we send for any non-NULL * text - non-empty has non-'\0' first byte; empty has size 1; * NULL also has '\0' as first byte but has size 6. The recipient * isn't actually told the size sent, though; so has to pre-fill * the receiving buffer with something that can't be mistaken for * our NULL_MSG, so as to safely compare. * * We are confident that the .iov_base on the sending end is only * ever read, so casting away its constness here is not a problem. * * The manual page of sendmsg(2) says .msg_name is used to specify * the target address of a datagram; its documentation of failure * modes says you can get EISCONN if: * "The connection-mode socket was connected already but a * recipient was specified. (Now either this error is returned, * or the recipient specification is ignored.)" * So, in order to keep world peace we need to set the name to NULL. * While we're at it, we clear all fields (using memset, so we don't * trip over variation between platforms in what fields exist). */ memset(&message, 0, sizeof(message)); memset(&vector, 0, sizeof(vector)); vector.iov_base = (void*) (text ? text : NULL_MSG); /* const_cast */ vector.iov_len = msglen; message.msg_iov = &vector; message.msg_iovlen = 1; #ifdef HAVE_MSGHDR_MSG_CONTROL char control_message_data[CMSG_SPACE(sizeof(descriptor))]; struct cmsghdr *control_message = NULL; message.msg_control = control_message_data; message.msg_controllen = sizeof(control_message_data); /* Conjecture: setting .msg_controllen influences CMSG_FIRSTHDR in * ways we need; but notice that we over-write it below. */ control_message = CMSG_FIRSTHDR(&message); control_message->cmsg_level = SOL_SOCKET; control_message->cmsg_type = SCM_RIGHTS; control_message->cmsg_len = CMSG_LEN(sizeof(descriptor)); memcpy(CMSG_DATA(control_message), &descriptor, sizeof(int)); message.msg_controllen = control_message->cmsg_len; #elif HAVE_MSGHDR_ACCRIGHTS message.msg_accrights = (char *)&descriptor; message.msg_accrightslen = sizeof(descriptor); #endif /* Send message: */ if (sendmsg(uds, &message, 0) < 0) { Log(LOG_LEVEL_ERR, "Can't pass descriptor to peer (sendmsg: %s)", GetErrorStr()); } else { Log(LOG_LEVEL_VERBOSE, "Descriptor %d sent", descriptor); return true; } return false; } int PassOpenFile_Get(int uds, char **text) { struct msghdr message; struct iovec vector; char buffer[MAX_MESSAGE_SIZE] = "PassOpenFile: failed to transmit any message"; assert(strcmp(buffer + 1, NULL_MSG + 1) != 0); int received_descriptor = -1; Log(LOG_LEVEL_DEBUG, "Receiving descriptor via " INTERFACE_STYLE " interface (UDS descriptor %d)", uds); memset(&message, 0, sizeof(message)); memset(&vector, 0, sizeof(vector)); memset(buffer, 0, sizeof(buffer)); vector.iov_base = buffer; vector.iov_len = sizeof(buffer); /* This is *not* updated by recvmsg ! */ /* Prepare the message. See Put()'s comment on the topic. */ message.msg_iov = &vector; message.msg_iovlen = 1; #ifdef HAVE_MSGHDR_MSG_CONTROL char control_message_data[CMSG_SPACE(sizeof(received_descriptor))]; message.msg_control = control_message_data; message.msg_controllen = sizeof(control_message_data); #elif HAVE_MSGHDR_ACCRIGHTS message.msg_accrights = (char *)&received_descriptor; message.msg_accrightslen = sizeof(received_descriptor); #endif /* Receive message: */ if (recvmsg(uds, &message, MSG_WAITALL) < 0) { Log(LOG_LEVEL_ERR, "Can't receive descriptor (recvmsg: %s)", GetErrorStr()); return -1; } /* Recover the file descriptor */ #ifdef HAVE_MSGHDR_MSG_CONTROL struct cmsghdr *control_message = CMSG_FIRSTHDR(&message); if (control_message == NULL) { Log(LOG_LEVEL_ERR, "Received no message."); return -1; } else if (control_message->cmsg_type != SCM_RIGHTS) { Log(LOG_LEVEL_ERR, "Received message does not deliver a descriptor."); return -1; } assert((char *)control_message + control_message->cmsg_len == /* i.e. we only have *one* descriptor here; otherwise, we * need to close() all but the first. */ (char *)CMSG_DATA(control_message) + sizeof(int)); memcpy(&received_descriptor, CMSG_DATA(control_message), sizeof(int)); #elif HAVE_MSGHDR_ACCRIGHTS if (message.msg_accrightslen <= 0) { Log(LOG_LEVEL_ERR, "Received no data for descriptor."); return -1; } #endif if (received_descriptor < 0) { Log(LOG_LEVEL_ERR, "Received invalid descriptor."); return -1; } /* Else, have a duty to close received_descriptor, one way or another. */ /* Recover the message and report success: */ if (buffer[0] || strcmp(buffer + 1, NULL_MSG + 1)) { if (text) { *text = xstrndup(buffer, sizeof(buffer)); } Log(LOG_LEVEL_VERBOSE, "Received descriptor %d with text '%s'", received_descriptor, buffer); } else { if (text) { *text = NULL; } Log(LOG_LEVEL_VERBOSE, "Received descriptor %d with no text", received_descriptor); } return received_descriptor; } #endif /* __MINGW32__ */ cfengine-3.24.2/libntech/libutils/logging_priv.h0000644000000000000000000000420615010704254021634 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LOGGING_PRIV_H #define CFENGINE_LOGGING_PRIV_H /* * This interface is private and intended only for use by logging extensions (such as one defined in libpromises). */ typedef struct LoggingPrivContext LoggingPrivContext; typedef char *(*LoggingPrivLogHook)(LoggingPrivContext *context, LogLevel level, const char *message); struct LoggingPrivContext { LoggingPrivLogHook log_hook; void *param; /** * Generally the log_hook runs whenever the message is printed either to * console or to syslog. You can set this to *additionally* run the hook * when the message level is <= force_hook_level. * * @NOTE the default setting of 0 equals to CRIT level, which is good as * default since the CRIT messages are always printed anyway, so * the log_hook runs anyway. */ LogLevel force_hook_level; }; /** * @brief Attaches context to logging for current thread */ void LoggingPrivSetContext(LoggingPrivContext *context); /** * @brief Retrieves logging context for current thread */ LoggingPrivContext *LoggingPrivGetContext(void); /** * @brief Set logging (syslog) and reporting (stdout) level for current thread */ void LoggingPrivSetLevels(LogLevel log_level, LogLevel report_level); #endif cfengine-3.24.2/libntech/libutils/stack.c0000644000000000000000000000642715010704254020255 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include Stack *StackNew(size_t initial_capacity, void (ItemDestroy) (void *item)) { Stack *stack = xmalloc(sizeof(Stack)); StackInit(stack, initial_capacity, ItemDestroy); return stack; } void StackDestroy(Stack *stack) { if (stack != NULL) { DestroyRange(stack, 0, stack->size); StackSoftDestroy(stack); } } void StackSoftDestroy(Stack *stack) { if (stack != NULL) { free(stack->data); free(stack); } } void *StackPop(Stack *stack) { assert(stack != NULL); size_t size = stack->size; void *item = NULL; if (size > 0) { size--; item = stack->data[size]; stack->data[size] = NULL; stack->size = size; } return item; } void *StackTop(Stack *stack) { assert(stack != NULL); size_t size = stack->size; if (size > 0) { return stack->data[size-1]; } return NULL; } /** @brief Expands capacity of stack. @note Assumes that locks are acquired. @param [in] stack Pointer to struct. */ static void ExpandIfNecessary(Stack *stack) { assert(stack != NULL); assert(stack->size <= stack->capacity); if (stack->size == stack->capacity) { stack->capacity *= EXPAND_FACTOR; stack->data = xrealloc(stack->data, sizeof(void *) * stack->capacity); } } void StackPush(Stack *stack, void *item) { assert(stack != NULL); ExpandIfNecessary(stack); stack->data[stack->size++] = item; } size_t StackPushReportCount(Stack *stack, void *item) { assert(stack != NULL); ExpandIfNecessary(stack); stack->data[stack->size++] = item; size_t size = stack->size; return size; } size_t StackCount(Stack const *stack) { assert(stack != NULL); size_t count = stack->size; return count; } size_t StackCapacity(Stack const *stack) { assert(stack != NULL); size_t capacity = stack->capacity; return capacity; } bool StackIsEmpty(Stack const *stack) { assert(stack != NULL); bool const empty = (stack->size == 0); return empty; } Stack *StackCopy(Stack const *stack) { assert(stack != NULL); Stack *new_stack = xmemdup(stack, sizeof(Stack)); new_stack->data = xmalloc(sizeof(void *) * stack->capacity); memcpy(new_stack->data, stack->data, sizeof(void *) * stack->size); return new_stack; } cfengine-3.24.2/libntech/libutils/statistics.c0000644000000000000000000000351515010704254021335 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /**********************************************************************/ double GAverage(double anew, double aold, double p) /* return convex mixture - p is the trust/confidence in the new value */ { return (p * anew + (1.0 - p) * aold); } /* * expected(Q) = p*Q_new + (1-p)*expected(Q) * variance(Q) = p*(Q_new - expected(Q))^2 + (1-p)*variance(Q) */ /**********************************************************************/ QPoint QAverage(QPoint old, double new_q, double p) { QPoint new = { .q = new_q, }; double devsquare = (new.q - old.expect) * (new.q - old.expect); new.dq = new.q - old.q; new.expect = GAverage(new.q, old.expect, p); new.var = GAverage(devsquare, old.var, p); return new; } /**********************************************************************/ QPoint QDefinite(double q) { return (QPoint) { .q = q, .dq = 0.0, .expect = q, .var = 0.0 }; } cfengine-3.24.2/libntech/libutils/sequence.c0000644000000000000000000002346315010704254020757 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include static const size_t EXPAND_FACTOR = 2; Seq *SeqNew(size_t initialCapacity, void (ItemDestroy) (void *item)) { Seq *seq = xmalloc(sizeof(Seq)); if (initialCapacity <= 0) { initialCapacity = 1; } seq->capacity = initialCapacity; seq->length = 0; seq->data = xcalloc(sizeof(void *), initialCapacity); seq->ItemDestroy = ItemDestroy; return seq; } static void DestroyRange(Seq *seq, size_t start, size_t end) { assert(seq != NULL); if (seq->ItemDestroy) { for (size_t i = start; i <= end; i++) { seq->ItemDestroy(seq->data[i]); } } } void SeqDestroy(Seq *seq) { if (seq != NULL) { if (seq->length > 0) { DestroyRange(seq, 0, seq->length - 1); } SeqSoftDestroy(seq); } } void SeqSoftDestroy(Seq *seq) { if (seq != NULL) { free(seq->data); free(seq); } } static void ExpandIfNeccessary(Seq *seq) { assert(seq != NULL); assert(seq->length <= seq->capacity); if (seq->length == seq->capacity) { seq->capacity *= EXPAND_FACTOR; seq->data = xrealloc(seq->data, sizeof(void *) * seq->capacity); } } int StrCmpWrapper(const void *s1, const void *s2, void *user_data) { UNUSED(user_data); return strcmp(s1, s2); } void SeqSet(Seq *seq, size_t index, void *item) { assert(seq != NULL); assert(index < SeqLength(seq)); if (seq->ItemDestroy) { seq->ItemDestroy(seq->data[index]); } seq->data[index] = item; } void SeqSoftSet(Seq *seq, size_t index, void *item) { assert(seq != NULL); assert(index < SeqLength(seq)); seq->data[index] = item; } void SeqAppend(Seq *seq, void *item) { assert(seq != NULL); ExpandIfNeccessary(seq); seq->data[seq->length] = item; ++(seq->length); } void SeqAppendOnce(Seq *seq, void *item, SeqItemComparator Compare) { assert(seq != NULL); if (SeqLookup(seq, item, Compare) == NULL) { SeqAppend(seq, item); } else { /* swallow the item anyway */ if (seq->ItemDestroy != NULL) { seq->ItemDestroy(item); } } } void SeqAppendSeq(Seq *seq, const Seq *items) { for (size_t i = 0; i < SeqLength(items); i++) { SeqAppend(seq, SeqAt(items, i)); } } void SeqRemoveRange(Seq *seq, size_t start, size_t end) { assert(seq != NULL); assert(end < seq->length); assert(start <= end); DestroyRange(seq, start, end); size_t rest_len = seq->length - end - 1; if (rest_len > 0) { memmove(seq->data + start, seq->data + end + 1, sizeof(void *) * rest_len); } seq->length -= end - start + 1; } void SeqRemove(Seq *seq, size_t index) { SeqRemoveRange(seq, index, index); } void *SeqLookup(Seq *seq, const void *key, SeqItemComparator Compare) { assert(seq != NULL); for (size_t i = 0; i < seq->length; i++) { if (Compare(key, seq->data[i], NULL) == 0) { return seq->data[i]; } } return NULL; } void *SeqBinaryLookup(Seq *seq, const void *key, SeqItemComparator Compare) { assert(seq != NULL); ssize_t index = SeqBinaryIndexOf(seq, key, Compare); if (index == -1) { return NULL; } else { return seq->data[index]; } } ssize_t SeqIndexOf(Seq *seq, const void *key, SeqItemComparator Compare) { assert(seq != NULL); for (size_t i = 0; i < seq->length; i++) { if (Compare(key, seq->data[i], NULL) == 0) { return i; } } return -1; } ssize_t SeqBinaryIndexOf(Seq *seq, const void *key, SeqItemComparator Compare) { assert(seq != NULL); if (seq->length == 0) { return -1; } size_t low = 0; size_t high = seq->length; while (low < high) { // Invariant: low <= middle < high size_t middle = low + ((high - low) >> 1); // ">> 1" is division by 2. int result = Compare(key, seq->data[middle], NULL); if (result == 0) { return middle; } if (result > 0) { low = middle + 1; } else { high = middle; } } // Not found. return -1; } static void Swap(void **l, void **r) { void *t = *l; *l = *r; *r = t; } // adopted from http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#C static void QuickSortRecursive(void **data, int n, SeqItemComparator Compare, void *user_data, size_t maxterm) { if (n < 2) { return; } void *pivot = data[n / 2]; void **l = data; void **r = data + n - 1; while (l <= r) { while (Compare(*l, pivot, user_data) < 0) { ++l; } while (Compare(*r, pivot, user_data) > 0) { --r; } if (l <= r) { Swap(l, r); ++l; --r; } } QuickSortRecursive(data, r - data + 1, Compare, user_data, maxterm + 1); QuickSortRecursive(l, data + n - l, Compare, user_data, maxterm + 1); } void SeqSort(Seq *seq, SeqItemComparator Compare, void *user_data) { assert(seq != NULL); QuickSortRecursive(seq->data, seq->length, Compare, user_data, 0); } Seq *SeqSoftSort(const Seq *seq, SeqItemComparator compare, void *user_data) { size_t length = SeqLength(seq); if (length == 0) { return SeqNew(0, NULL); } Seq *sorted_seq = SeqGetRange(seq, 0, length - 1); SeqSort(sorted_seq, compare, user_data); return sorted_seq; } void SeqSoftRemoveRange(Seq *seq, size_t start, size_t end) { assert(seq != NULL); assert(end < seq->length); assert(start <= end); size_t rest_len = seq->length - end - 1; if (rest_len > 0) { memmove(seq->data + start, seq->data + end + 1, sizeof(void *) * rest_len); } seq->length -= end - start + 1; } void SeqClear(Seq *seq) { if (SeqLength(seq) > 0) { SeqRemoveRange(seq, 0, SeqLength(seq) - 1); } } void SeqSoftRemove(Seq *seq, size_t index) { SeqSoftRemoveRange(seq, index, index); } void SeqReverse(Seq *seq) { assert(seq != NULL); for (size_t i = 0; i < (seq->length / 2); i++) { Swap(&seq->data[i], &seq->data[seq->length - 1 - i]); } } Seq *SeqSplit(Seq *seq, size_t index) { assert(seq != NULL); size_t length = SeqLength(seq); assert(index <= length); // index > length is invalid if (index >= length) { // index == length is valid, return empty sequence // anything higher is error, but we will handle it anyway return SeqNew(1, seq->ItemDestroy); } Seq *ret = SeqGetRange(seq, index, length - 1); assert(ret != NULL); // Our indices should be valid SeqSoftRemoveRange(seq, index, length - 1); return ret; } size_t SeqLength(const Seq *seq) { assert(seq != NULL); return seq->length; } void SeqShuffle(Seq *seq, unsigned int seed) { assert(seq != NULL); if (SeqLength(seq) == 0) { return; } /* Store current random number state for being reset at the end of function */ int rand_state = rand(); srand(seed); for (size_t i = SeqLength(seq) - 1; i > 0; i--) { size_t j = rand() % (i + 1); Swap(seq->data + i, seq->data + j); } /* Restore previous random number state */ srand(rand_state); } Seq *SeqGetRange(const Seq *seq, size_t start, size_t end) { assert(seq != NULL); if ((start > end) || (start >= seq->length) || (end >= seq->length)) { return NULL; } Seq *sub = SeqNew(end - start + 1, seq->ItemDestroy); for (size_t i = start; i <= end; i++) { assert(i < SeqLength(seq)); SeqAppend(sub, SeqAt(seq, i)); } return sub; } void *const *SeqGetData(const Seq *seq) { assert(seq != NULL); return seq->data; } Seq *SeqFilter(Seq *const seq, SeqFilterFn filter) { assert(seq != NULL); assert(filter != NULL); int length = SeqLength(seq); int from = 0; int to = 0; while (from < length) { if (filter(seq->data[from])) { seq->ItemDestroy(seq->data[from]); ++from; // Skip NULL elements } else { // Copy elements in place, DON'T use SeqSet, which will free() seq->data[to] = seq->data[from]; ++from; ++to; } } seq->length = to; return seq; } static inline bool FilterNullCallback(void *const item) { return item == NULL; } void SeqRemoveNulls(Seq *const seq) { assert(seq != NULL); SeqFilter(seq, FilterNullCallback); } Seq *SeqFromArgv(int argc, const char *const *const argv) { assert(argc > 0); assert(argv != NULL); assert(argv[0] != NULL); Seq *args = SeqNew(argc, NULL); for (int i = 0; i < argc; ++i) { SeqAppend(args, (void *)argv[i]); // Discards const } return args; } cfengine-3.24.2/libntech/libutils/known_dirs.h0000644000000000000000000000227015010704254021322 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_KNOWN_DIRS_H #define CFENGINE_KNOWN_DIRS_H const char *GetWorkDir(void); const char *GetBinDir(void); const char *GetDataDir(void); const char *GetLogDir(void); const char *GetPidDir(void); const char *GetMasterDir(void); const char *GetInputDir(void); const char *GetStateDir(void); #endif cfengine-3.24.2/libntech/libutils/mustache.h0000644000000000000000000000206715010704254020762 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MUSTACHE_H #define CFENGINE_MUSTACHE_H #include #include bool MustacheRender(Buffer *out, const char *input, const JsonElement *hash); #endif cfengine-3.24.2/libntech/libutils/condition_macros.h0000644000000000000000000000573315010704254022506 0ustar00rootroot00000000000000#ifndef __CONDITION_MACROS_H__ #define __CONDITION_MACROS_H__ #include #include // This file contains macros to use for error checking, assertions, // abort, return, etc. Each macro should have a comment about when to use it. // The normal assert() macro should only be used to catch programmer mistakes, // things which should never happen, even for weird file/network inputs. // For example, a function which doesn't accept NULL pointer arguments, // should assert that the parameter is not NULL. // Used when you want to assert a precondtion (catch programmer mistake) // but also want to handle the error if it ever happens in a release build. // Useful if you are unsure if you need to handle the error, for example // if you are adding assertions to older code. Also useful in cases where // you know you want both, for example when network or file input can trigger // the condition #ifndef assert_or_return #define assert_or_return(expr, val) { \ assert(expr); \ if (!(expr)) \ { \ return val; \ } \ } #endif // Similar to assert_or_return, except you put it inside the if // body which handles the error in release builds #ifndef debug_abort_if_reached #define debug_abort_if_reached() { \ assert(false); \ } #endif // libntech static assert (compile time check): // has nt_ prefix to not be confused with static_assert // Why not just static_assert? // - It is already defined on some platforms (recent RHEL and Ubuntu), // but in incompatible ways. On RHEL second arg (message) is required, // on Ubuntu it is not. // Why not redefine static_assert (undef + define)? // - Hard to know which static_assert you are using. Include ordering becomes // very important. Error messages are confusing if you end up using the wrong // static_assert. Error message would only appear on some platforms, not others. #ifdef _Static_assert // Note: The message here is not really necessary, // most compilers will include this information anyway. #define nt_static_assert(x) _Static_assert(x, __FILE__ ":" TO_STRING(__LINE__) ": (" #x ") -> false") #else #define nt_static_assert(x) { \ switch (0) { \ case 0: /* Cause duplicate case if next is 0 as well */ \ break; \ case x: /* Error if 0 or if non-const expression */ \ break; \ } \ } #endif // Useful to assert that 2 string literals are the same, at compile time: // #define nt_static_assert_string_equal(a,b) nt_static_assert(strcmp(a,b) == 0) // This macro doesn't work everywhere, yet, because not all the compilers we // use will optimize out the strcmp() call for string literals. // TODO: Enable later :) #endif cfengine-3.24.2/libntech/libutils/xml_writer.c0000644000000000000000000000771015010704254021340 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static void WriteEscaped(Writer *writer, const char *source); /*****************************************************************************/ void XmlComment(Writer *writer, const char *comment) { if (writer == NULL) { ProgrammingError("NULL writer passed to XmlWriter"); } WriterWrite(writer, "\n"); } /*****************************************************************************/ static void XmlEmitStartTag(Writer *writer, const char *tag_name, int attr_cnt, va_list args) { WriterWriteF(writer, "<%s", tag_name); if (attr_cnt > 0) { WriterWrite(writer, " "); } for (int i = 0; i < attr_cnt; ++i) { XmlAttribute attr = va_arg(args, XmlAttribute); WriterWriteF(writer, "%s=\"%s\" ", attr.name, attr.value); } WriterWrite(writer, ">"); } /*****************************************************************************/ void XmlStartTag(Writer *writer, const char *tag_name, int attr_cnt, ...) { va_list args; if ((writer == NULL) || (tag_name == NULL) || (attr_cnt < 0)) { ProgrammingError("writer, tag_name or attr_cnt in XmlStartTag are wrong"); } va_start(args, attr_cnt); XmlEmitStartTag(writer, tag_name, attr_cnt, args); va_end(args); WriterWrite(writer, "\n"); } /*****************************************************************************/ void XmlEndTag(Writer *writer, const char *tag_name) { if ((writer == NULL) || (tag_name == NULL)) { ProgrammingError("writer or tag_name are missing"); } WriterWriteF(writer, "\n", tag_name); } /*****************************************************************************/ void XmlTag(Writer *writer, const char *tag_name, const char *value, int attr_cnt, ...) { va_list args; if ((writer == NULL) || (tag_name == NULL) || (attr_cnt < 0)) { return; } va_start(args, attr_cnt); XmlEmitStartTag(writer, tag_name, attr_cnt, args); va_end(args); if (value != NULL) { WriteEscaped(writer, value); } XmlEndTag(writer, tag_name); } /*****************************************************************************/ void XmlContent(Writer *writer, const char *value) { if (writer == NULL) { ProgrammingError("writer is NULL"); } WriteEscaped(writer, value); } /*****************************************************************************/ static void WriteEscaped(Writer *w, const char *source) { for (const char *s = source; *s; s++) { switch (*s) { case '&': WriterWrite(w, "&"); break; case '>': WriterWrite(w, ">"); break; case '"': WriterWrite(w, """); break; case '\'': WriterWrite(w, "'"); break; case '<': WriterWrite(w, "<"); break; default: WriterWriteChar(w, *s); } } } cfengine-3.24.2/libntech/libutils/cleanup.c0000644000000000000000000000357315010704254020576 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include typedef struct CleanupList { CleanupFn fn; struct CleanupList *next; } CleanupList; static pthread_mutex_t cleanup_functions_mutex = PTHREAD_MUTEX_INITIALIZER; static CleanupList *cleanup_functions; /* To be called externally only by Windows binaries */ void CallCleanupFunctions(void) { pthread_mutex_lock(&cleanup_functions_mutex); CleanupList *p = cleanup_functions; while (p) { CleanupList *cur = p; (cur->fn)(); p = cur->next; free(cur); } cleanup_functions = NULL; pthread_mutex_unlock(&cleanup_functions_mutex); } void DoCleanupAndExit(int ret) { CallCleanupFunctions(); exit(ret); } void RegisterCleanupFunction(CleanupFn fn) { pthread_mutex_lock(&cleanup_functions_mutex); CleanupList *p = xmalloc(sizeof(CleanupList)); p->fn = fn; p->next = cleanup_functions; cleanup_functions = p; pthread_mutex_unlock(&cleanup_functions_mutex); } cfengine-3.24.2/libntech/libutils/logging.h0000644000000000000000000001554315010704254020602 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LOGGING_H #define CFENGINE_LOGGING_H #include #include #include /* va_list */ #include /* size_t */ #include /* struct tm */ // Does not include timezone, since it is hard to match on Windows. #define LOGGING_TIMESTAMP_REGEX "^20[0-9][0-9]-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]" typedef enum { LOG_LEVEL_NOTHING = -1, LOG_LEVEL_CRIT, LOG_LEVEL_ERR, LOG_LEVEL_WARNING, LOG_LEVEL_NOTICE, LOG_LEVEL_INFO, LOG_LEVEL_VERBOSE, LOG_LEVEL_DEBUG } LogLevel; /** * Enum used as a parameter in LogDebug(), used to print even more detailed * info than Log(LOG_LEVEL_DEBUG). */ enum LogModule { LOG_MOD_NONE = 0, /* DEFAULT DEBUG LOGGING */ LOG_MOD_EVALCTX, /* evaluator */ LOG_MOD_EXPAND, /* variables expansion */ LOG_MOD_ITERATIONS, /* evaluator iteration engine */ LOG_MOD_PARSER, /* yacc */ LOG_MOD_VARTABLE, /* variables tables */ LOG_MOD_VARS, /* variables promise */ LOG_MOD_LOCKS, /* locks.c */ LOG_MOD_PS, /* ps parsing */ LOG_MOD_MAX }; #include typedef struct { LogLevel log_level; LogLevel report_level; bool color; LoggingPrivContext *pctx; } LoggingContext; const char *LogLevelToString(LogLevel level); LogLevel LogLevelFromString(const char *level); /** * @brief Return the standard timestamp format used in logging. * @param dest Output buffer * @param n size of output buffer * @param timestamp Timespec to format * @return True if successful, otherwise "" will be printed to buffer */ bool LoggingFormatTimestamp(char dest[64], size_t n, struct tm *timestamp); LoggingContext *GetCurrentThreadContext(void); void LoggingFreeCurrentThreadContext(void); /** * Whether a message with level #level would be logged by Log() or not. */ bool WouldLog(LogLevel level); void Log(LogLevel level, const char *fmt, ...) FUNC_ATTR_PRINTF(2, 3); void LogDebug(enum LogModule mod, const char *fmt, ...) FUNC_ATTR_PRINTF(2, 3); void LogRaw(LogLevel level, const char *prefix, const void *buf, size_t buflen); void VLog(LogLevel level, const char *fmt, va_list ap); void LoggingSetAgentType(const char *type); void LoggingEnableTimestamps(bool enable); /** * The functions below work with two internal variables -- global_level and * global_system_log_level. If the latter one is not set, global_level is used * for both system log logging and report (console) logging. If it is set, it is * used for system log logging in all new threads unless/until * LoggingPrivSetLevels() is called in those threads. */ void LogSetGlobalLevel(LogLevel level); void LogSetGlobalLevelArgOrExit(const char *const arg); LogLevel LogGetGlobalLevel(void); void LogSetGlobalSystemLogLevel(LogLevel level); LogLevel LogGetGlobalSystemLogLevel(void); void LogUnsetGlobalSystemLogLevel(void); void LoggingSetColor(bool enabled); /* * Portable syslog() */ void LogToSystemLog(const char *msg, LogLevel level); /** * @brief Log a message with structured data to system log. * @details This function takes a variable-length argument list and expects * structured data passed as key-value pairs, where both keys and * values are C-strings. Furthermore, the last pair must contain the * "MESSAGE" key, and the corresponding value accepts a format-string * followed by its arguments. Format-strings are not accepted in the * value of any other pair. The log priority (i.e., the pair * containing the "PRIORITY" key) is automatically deduced from the * log level argument and added to the structured log message. * @note Only the formatted string from the pair with the "MESSAGE" key is * logged on platforms that does not support structured logging. * * The function takes an int as the log level, although the desired type * would be the enum "LogLevel". For some C compilers, the last required * argument must be self-promoting: that is, the default promotions must * not change its type (this is actually an ISO C requirement). However, * enums promote to an int. Thus, we cannot use them and must use int * instead. * * @param[in] level Log level. * @param[in] vararg Variable-length argument containing key-value pairs. */ void LogToSystemLogStructured(int level, ...); /** * This function is here, in order to help implement a CodeQL query for * identifying improper use of LogToSystemLogStructured CFE-4185. Once a query * is created, this function should be removed. * * @warning Do not use! * @see CFE-4185 */ void __ImproperUseOfLogToSystemLogStructured(void); /* * Portable strerror(errno) */ const char *GetErrorStr(void); const char *GetErrorStrFromCode(int error_code); void LogModuleHelp(void); bool LogModuleEnabled(enum LogModule mod); void LogEnableModule(enum LogModule mod); bool LogEnableModulesFromString(char *s); // byte_magnitude and byte_unit are used to print readable byte counts long byte_magnitude(long bytes); const char *byte_unit(long bytes); /** * API for logging messages into a buffer which is later either committed * (messages are actually logged) or discarded. * * @note StartLoggingIntoBuffer() needs to be called first and then every time * after DiscardLogBuffer() or CommitLogBuffer(). * @note There's only one global buffer, this API is *not* thread-safe. */ /** * Enable logging into a buffer for all messages with the log level greater or * equal to #min_level and less or equal than #max_level (keep in mind that the * log levels are sorted from %LOG_LEVEL_CRIT, smallest, to %LOG_LEVEL_DEBUG, * greatest). */ void StartLoggingIntoBuffer(LogLevel min_level, LogLevel max_level); void DiscardLogBuffer(); void CommitLogBuffer(); #endif cfengine-3.24.2/libntech/libutils/proc_keyvalue.h0000644000000000000000000000274715010704254022026 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROC_KEYVALUE_H #define CFENGINE_PROC_KEYVALUE_H #include #include /* * Parser for line-oriented key-value formats found in Linux /proc filesystem. */ typedef bool (*KeyNumericValueCallback) (const char *field, off_t value, void *param); /* * Returns false on syntax error */ bool ParseKeyNumericValue(FILE *fd, KeyNumericValueCallback callback, void *param); typedef bool (*KeyValueCallback) (const char *field, const char *value, void *param); /* * Returns false on syntax error */ bool ParseKeyValue(FILE *fd, KeyValueCallback callback, void *param); #endif cfengine-3.24.2/libntech/libutils/json-yaml.c0000644000000000000000000003044315010704254021054 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include JsonParseError JsonParseYamlFile(const char *path, size_t size_max, JsonElement **json_out) { return JsonParseAnyFile(path, size_max, json_out, true); } #ifdef HAVE_LIBYAML // macros and some of the parse guesses follow https://php-yaml.googlecode.com/svn-history/trunk/parse.c #define JSON_YAML_SCALAR_TAG_IS(tag, name) \ !strcmp((const char *)tag, name) #define JSON_YAML_IS_NOT_IMPLICIT_AND_TAG_IS(event, tag, name) \ (!event->data.scalar.quoted_implicit && !event->data.scalar.plain_implicit && JSON_YAML_SCALAR_TAG_IS(tag, name)) #define JSON_YAML_IS_NOT_QUOTED_OR_TAG_IS(event, tag, name) \ (!event->data.scalar.quoted_implicit && (event->data.scalar.plain_implicit || JSON_YAML_SCALAR_TAG_IS(tag, name))) static JsonElement* JsonParseYamlScalarValue(yaml_event_t *event) { assert(event != NULL); assert(event->type == YAML_SCALAR_EVENT); const char *tag = (const char *) event->data.scalar.tag; const char *value = (const char *) event->data.scalar.value; size_t length = event->data.scalar.length; if (tag == NULL) { tag = YAML_DEFAULT_SCALAR_TAG; } if (JSON_YAML_SCALAR_TAG_IS(tag, YAML_NULL_TAG) || event->data.scalar.plain_implicit) { if ((length == 1 && *value == '~') || length == 0 || !strcmp("NULL", value) || !strcmp("Null", value) || !strcmp("null", value)) { return JsonNullCreate(); } } if (JSON_YAML_IS_NOT_QUOTED_OR_TAG_IS(event, tag, YAML_BOOL_TAG)) { // see http://yaml.org/type/bool.html if ((length == 1 && (*value == 'Y' || *value == 'y')) || !strcmp("YES", value) || !strcmp("Yes", value) || !strcmp("yes", value) || !strcmp("TRUE", value) || !strcmp("True", value) || !strcmp("true", value) || !strcmp("ON", value) || !strcmp("On", value) || !strcmp("on", value)) { return JsonBoolCreate(true); } if ((length == 1 && (*value == 'N' || *value == 'n')) || !strcmp("NO", value) || !strcmp("No", value) || !strcmp("no", value) || !strcmp("FALSE", value) || !strcmp("False", value) || !strcmp("false", value) || !strcmp("OFF", value) || !strcmp("Off", value) || !strcmp("off", value)) { return JsonBoolCreate(false); } } else if (JSON_YAML_IS_NOT_IMPLICIT_AND_TAG_IS(event, tag, YAML_BOOL_TAG)) { if (length == 0 || (length == 1 && *value == '0')) { return JsonBoolCreate(false); } else { return JsonBoolCreate(true); } } /* check for numeric (int or float) */ if (!event->data.scalar.quoted_implicit && (event->data.scalar.plain_implicit || JSON_YAML_SCALAR_TAG_IS(tag, YAML_INT_TAG) || JSON_YAML_SCALAR_TAG_IS(tag, YAML_FLOAT_TAG))) { JsonElement *tobuild; const char *end_of_num_part = value; if (JSON_PARSE_OK == JsonParseAsNumber(&end_of_num_part, &tobuild)) { return tobuild; } } if (strcmp(tag, YAML_TIMESTAMP_TAG) == 0) { // what else could we do, return a epoch time? Log(LOG_LEVEL_VERBOSE, "YAML parse: treating timestamp value '%s' as a string", value); return JsonStringCreate(value); } if (JSON_YAML_SCALAR_TAG_IS(tag, YAML_STR_TAG)) { return JsonStringCreate(value); } Log(LOG_LEVEL_VERBOSE, "YAML parse: unhandled scalar tag %s, returning as string", tag); return JsonStringCreate(value); } static void JsonParseYamlData(yaml_parser_t *parser, JsonElement *element, const int depth) { yaml_event_t event; char* key = NULL; Log(LOG_LEVEL_DEBUG, "YAML parse: entering JsonParseYamlStore"); while (1) { yaml_parser_parse(parser, &event); Log(LOG_LEVEL_DEBUG, "YAML parse: event of type %d arrived with depth %d, key %s", event.type, depth, key == NULL ? "[NULL]" : key); // Parse value either as a new leaf in the mapping // or as a leaf value (one of them, in case it's a sequence) if (event.type == YAML_SCALAR_EVENT) { Log(LOG_LEVEL_DEBUG, "YAML parse: scalar event, value '%s'", event.data.scalar.value); if (JsonGetElementType(element) == JSON_ELEMENT_TYPE_CONTAINER) { if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_OBJECT) { if (key == NULL) { // save key key = xstrdup(event.data.scalar.value); } else { JsonObjectAppendElement(element, key, JsonParseYamlScalarValue(&event)); // clear key free(key); key = NULL; } } else if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_ARRAY) { JsonArrayAppendElement(element, JsonParseYamlScalarValue(&event)); // clear key free(key); key = NULL; } else { ProgrammingError("YAML Parse: scalar event received inside an unknown JSON container type"); } } else { ProgrammingError("YAML Parse: scalar event received inside a non-container JSON element"); } } else if (event.type == YAML_SEQUENCE_START_EVENT) { Log(LOG_LEVEL_DEBUG, "YAML parse: starting sequence"); JsonElement *arr = JsonArrayCreate(DEFAULT_CONTAINER_CAPACITY); if (JsonGetElementType(element) == JSON_ELEMENT_TYPE_CONTAINER) { if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_OBJECT) { if (key) { JsonObjectAppendElement(element, key, arr); JsonParseYamlData(parser, arr, depth+1); // clear key free(key); key = NULL; } else { ProgrammingError("YAML Parse: Unexpected sequence start event inside a container without a key"); } } else if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_ARRAY) { JsonArrayAppendArray(element, arr); JsonParseYamlData(parser, arr, depth+1); // clear key free(key); key = NULL; } else { ProgrammingError("YAML Parse: Unexpected sequence start event inside a non-container"); } } } else if (event.type == YAML_SEQUENCE_END_EVENT) { Log(LOG_LEVEL_DEBUG, "YAML parse: ending sequence"); if (JsonGetElementType(element) == JSON_ELEMENT_TYPE_CONTAINER) { if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_ARRAY) { // finished with this array, return up break; } else { ProgrammingError("YAML Parse: Unexpected sequence end event inside a non-array container"); } } else { ProgrammingError("YAML Parse: Unexpected sequence end event inside a non-container"); } } else if (event.type == YAML_MAPPING_START_EVENT) { Log(LOG_LEVEL_DEBUG, "YAML parse: starting mapping"); JsonElement *obj = JsonObjectCreate(DEFAULT_CONTAINER_CAPACITY); if (JsonGetElementType(element) == JSON_ELEMENT_TYPE_CONTAINER) { if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_OBJECT) { if (key) { JsonObjectAppendElement(element, key, obj); JsonParseYamlData(parser, obj, depth+1); // clear key free(key); key = NULL; } else { ProgrammingError("YAML Parse: Unexpected mapping start event inside a container without a key"); } } else if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_ARRAY) { JsonArrayAppendObject(element, obj); JsonParseYamlData(parser, obj, depth+1); // clear key free(key); key = NULL; } else { ProgrammingError("YAML Parse: Unexpected mapping start event inside a non-container"); } } } else if (event.type == YAML_MAPPING_END_EVENT) { Log(LOG_LEVEL_DEBUG, "YAML parse: ending mapping"); if (JsonGetElementType(element) == JSON_ELEMENT_TYPE_CONTAINER) { if (JsonGetContainerType(element) == JSON_CONTAINER_TYPE_OBJECT) { // finished with this object, return up break; } else { ProgrammingError("YAML Parse: Unexpected mapping end event inside a non-object container"); } } else { ProgrammingError("YAML Parse: Unexpected mapping end event inside a non-container"); } } else if (event.type == YAML_STREAM_END_EVENT) { Log(LOG_LEVEL_DEBUG, "YAML parse: ending stream"); break; } else if (event.type == YAML_NO_EVENT) { Log(LOG_LEVEL_DEBUG, "YAML parse: NO_EVENT"); break; // NO_EVENT doesn't need to be deleted } else { // ignore other events } yaml_event_delete(&event); Log(LOG_LEVEL_DEBUG, "YAML parse: running inner loop"); } if (key) { free(key); } Log(LOG_LEVEL_DEBUG, "YAML parse: exiting JsonParseYamlData"); } JsonParseError JsonParseYamlString(const char **data, JsonElement **json_out) { assert(data && *data); if (data == NULL || *data == NULL) { return JSON_PARSE_ERROR_NO_DATA; } yaml_parser_t parser; if(!yaml_parser_initialize(&parser)) { return JSON_PARSE_ERROR_LIBYAML_FAILURE; } yaml_parser_set_input_string(&parser, *data, strlen(*data)); JsonElement *holder = JsonArrayCreate(1); JsonParseYamlData(&parser, holder, 0); *json_out = JsonCopy(JsonAt(holder, 0)); JsonDestroy(holder); yaml_parser_delete(&parser); return JSON_PARSE_OK; } #else // !HAVE_LIBYAML JsonParseError JsonParseYamlString(ARG_UNUSED const char **data, ARG_UNUSED JsonElement **json_out) { return JSON_PARSE_ERROR_NO_LIBYAML; } #endif cfengine-3.24.2/libntech/libutils/string_sequence.h0000644000000000000000000000670115010704254022346 0ustar00rootroot00000000000000#ifndef __STRING_SEQUENCE_H__ #define __STRING_SEQUENCE_H__ #include // Seq #include // bool #include // Writer #define STR_LENGTH_PREFIX_LEN 10 /** @brief Create a new Sequence from splitting a string on a fixed delimiter @param [in] str String to split. @param [in] delimiter The delimiter, a fixed string. @return A pointer to the always created Sequence */ Seq *SeqStringFromString(const char *str, char delimiter); /** * @brief Join elements in sequence into a string * @param[in] seq Sequence of strings to join * @param[in] sep Separator between elements (can be NULL) * @return The concatenation of the elements in sequence * @note Sequence must contain only NUL-terminated strings, otherwise behavior * is undefined. */ char *StringJoin(const Seq *seq, const char *sep); /** * @brief Split string into a sequence based on a set of characters. * @param[in] str String to split. * @param[in] charset Characters to split on. * @return Sequence of substrings split on characters. * @note If the empty string is passed as character set, then a sequence of one * element containing the entire string is returned. This function is * similar to SeqStringFromString(). However, it splits on multiple * delimiters as opposed to one. */ Seq *StringSplit(const char *str, const char *charset); /** @brief Determine if string sequence contains a string */ bool SeqStringContains(const Seq *seq, const char *str); /** * @brief Return the total string length of a sequence of strings */ int SeqStringLength(Seq *seq); /** * Serialize the string into a length-prefixed format that consists of: * 1. 10 bytes of length prefix, where index 9 must be a space * 2. The data, with no escaping / modifications * 3. A single newline (\n) for readability * It is assumed that the string only contains ascii printable * characters and is NUL-terminated. */ bool WriteLenPrefixedString(Writer *w, const char *string); /** * @brief Read (deserialize) a length-prefixed string * * Expects the format described in WriteLenPrefixedString() above. * * @return -1 in case of error, 0 in case of EOF, 1 in case of successfull read */ int ReadLenPrefixedString(int fd, char **string); /** * @brief Serializes a sequence of strings to a length prefixed format * * (De)Serialize uses a length prefixed format. */ char *SeqStringSerialize(Seq *seq); /** * @brief Serializes a sequence of strings writing them to a Writer object * * Similar to SeqStringSerialize, but can be used with FileWriter to write * line by line to file. */ bool SeqStringWrite(Seq *seq, Writer *w); /** * @brief Serializes a sequence of strings writing them to a file * * Similar to SeqStringWrite, but opens and closes the file(name) for you. */ bool SeqStringWriteFile(Seq *seq, const char *file); /** * @brief Serializes a sequence of strings writing them to a file stream * * Similar to SeqStringWriteFile, but accepts an open file stream */ bool SeqStringWriteFileStream(Seq *seq, FILE *file); /** * @brief Reads a file deserializing it into a Seq * * @return NULL on any error, empty sequence for empty file */ Seq *SeqStringReadFile(const char *file); /** * @brief Create a sequence of strings from the serialized format * * @param[in] serialized The input string, contents are copied * @return A sequence of new allocated strings */ Seq *SeqStringDeserialize(const char *const serialized); #endif // __STRING_SEQUENCE_H__ cfengine-3.24.2/libntech/libutils/known_dirs.c0000644000000000000000000001565415010704254021327 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include static char OVERRIDE_BINDIR[PATH_MAX] = {0}; static const char *GetDefaultDir_helper(char dir[PATH_MAX], const char *root_dir, const char *append_dir); #ifdef __MINGW32__ const char *GetDefaultWorkDir(void); const char *GetDefaultLogDir(void); const char *GetDefaultDataDir(void); const char *GetDefaultPidDir(void); const char *GetDefaultMasterDir(void); const char *GetDefaultInputDir(void); #endif #if defined(__CYGWIN__) || defined(__ANDROID__) #define GET_DEFAULT_DIRECTORY_DEFINE(FUNC, GLOBAL) \ static const char *GetDefault##FUNC##Dir(void) \ { \ return GLOBAL; \ } /* getpwuid() on Android returns /data, * so use compile-time default instead */ GET_DEFAULT_DIRECTORY_DEFINE(Work, WORKDIR) GET_DEFAULT_DIRECTORY_DEFINE(Bin, BINDIR) GET_DEFAULT_DIRECTORY_DEFINE(Data, CF_DATADIR) GET_DEFAULT_DIRECTORY_DEFINE(Log, LOGDIR) GET_DEFAULT_DIRECTORY_DEFINE(Pid, PIDDIR) GET_DEFAULT_DIRECTORY_DEFINE(Input, INPUTDIR) GET_DEFAULT_DIRECTORY_DEFINE(Master, MASTERDIR) GET_DEFAULT_DIRECTORY_DEFINE(State, STATEDIR) #elif !defined(__MINGW32__) static const char *GetDefaultDir_helper(char dir[PATH_MAX], const char *root_dir, const char *append_dir) { assert(dir != NULL); if (getuid() > 0) { if (dir[0] == '\0') { struct passwd *mpw = getpwuid(getuid()); if (mpw == NULL) { return NULL; } if ( append_dir == NULL ) { if (snprintf(dir, PATH_MAX, "%s/.cfagent", mpw->pw_dir) >= PATH_MAX) { return NULL; } } else { if (snprintf(dir, PATH_MAX, "%s/.cfagent/%s", mpw->pw_dir, append_dir) >= PATH_MAX) { return NULL; } } } return dir; } else { return root_dir; } } #endif #define GET_DEFAULT_DIRECTORY_DEFINE(FUNC, STATIC, GLOBAL, FOLDER) \ const char *GetDefault##FUNC##Dir(void) \ { \ static char STATIC##dir[PATH_MAX]; /* GLOBAL_C */ \ return GetDefaultDir_helper(STATIC##dir, GLOBAL, FOLDER); \ } #if !defined(__CYGWIN__) && !defined(__ANDROID__) GET_DEFAULT_DIRECTORY_DEFINE(Work, work, WORKDIR, NULL) GET_DEFAULT_DIRECTORY_DEFINE(Bin, bin, BINDIR, "bin") GET_DEFAULT_DIRECTORY_DEFINE(Data, data, CF_DATADIR, "data") GET_DEFAULT_DIRECTORY_DEFINE(Log, log, LOGDIR, "log") GET_DEFAULT_DIRECTORY_DEFINE(Pid, pid, PIDDIR, NULL) GET_DEFAULT_DIRECTORY_DEFINE(Master, master, MASTERDIR, "masterfiles") GET_DEFAULT_DIRECTORY_DEFINE(Input, input, INPUTDIR, "inputs") GET_DEFAULT_DIRECTORY_DEFINE(State, state, STATEDIR, "state") #endif /*******************************************************************/ const char *GetWorkDir(void) { const char *workdir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR"); return workdir == NULL ? GetDefaultWorkDir() : workdir; } const char *GetBinDir(void) { const char *workdir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR"); if (workdir == NULL) { #ifdef __MINGW32__ /* Compile-time default bindir doesn't work on windows because during * the build /var/cfengine/bin is used and only when the package is * created, things are shuffled around */ snprintf(OVERRIDE_BINDIR, PATH_MAX, "%s%cbin", GetDefaultWorkDir(), FILE_SEPARATOR); return OVERRIDE_BINDIR; #else return GetDefaultBinDir(); #endif } else { snprintf(OVERRIDE_BINDIR, PATH_MAX, "%s%cbin", workdir, FILE_SEPARATOR); return OVERRIDE_BINDIR; } } const char *GetLogDir(void) { const char *logdir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR"); return logdir == NULL ? GetDefaultLogDir() : logdir; } const char *GetPidDir(void) { const char *piddir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR"); return piddir == NULL ? GetDefaultPidDir() : piddir; } #define GET_DIRECTORY_DEFINE_FUNC_BODY(FUNC, VAR, GLOBAL, FOLDER) \ { \ const char *VAR##dir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR"); \ \ static char workbuf[CF_BUFSIZE]; \ \ if (VAR##dir != NULL) \ { \ snprintf(workbuf, CF_BUFSIZE, "%s/" #FOLDER, VAR##dir); \ } \ else if (strcmp(GLOBAL##DIR, "default") == 0 ) \ { \ snprintf(workbuf, CF_BUFSIZE, "%s/" #FOLDER, GetWorkDir()); \ } \ else /* VAR##dir defined at compile-time */ \ { \ return GetDefault##FUNC##Dir(); \ } \ \ return MapName(workbuf); \ } const char *GetInputDir(void) GET_DIRECTORY_DEFINE_FUNC_BODY(Input, input, INPUT, inputs) const char *GetMasterDir(void) GET_DIRECTORY_DEFINE_FUNC_BODY(Master, master, MASTER, masterfiles) const char *GetStateDir(void) GET_DIRECTORY_DEFINE_FUNC_BODY(State, state, STATE, state) const char *GetDataDir(void) GET_DIRECTORY_DEFINE_FUNC_BODY(Data, data, CF_DATA, data) cfengine-3.24.2/libntech/libutils/json-priv.h0000644000000000000000000000237715010704254021104 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_JSON_PRIV_H #define CFENGINE_JSON_PRIV_H #include extern const int DEFAULT_CONTAINER_CAPACITY; JsonParseError JsonParseAnyFile(const char *path, size_t size_max, JsonElement **json_out, const bool yaml_format); JsonParseError JsonParseAsNumber(const char **data, JsonElement **json_out); #endif // CFENGINE_JSON_PRIV_H cfengine-3.24.2/libntech/libutils/refcount.c0000644000000000000000000000713615010704254020773 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include void RefCountNew(RefCount **ref) { if (!ref) { return; } *ref = (RefCount *)xmalloc(sizeof(RefCount)); (*ref)->user_count = 0; (*ref)->users = NULL; (*ref)->last = NULL; } void RefCountDestroy(RefCount **ref) { if (ref && *ref) { // Destroying a refcount which has more than one user is a bug, but we let it // pass in production code (memory leak). assert((*ref)->user_count <= 1); if ((*ref)->user_count > 1) return; if ((*ref)->users) free((*ref)->users); free(*ref); *ref = NULL; } } void RefCountAttach(RefCount *ref, void *owner) { if (!ref || !owner) { ProgrammingError("Either refcount or owner is NULL (or both)"); } ref->user_count++; RefCountNode *node = (RefCountNode *)xmalloc(sizeof(RefCountNode)); node->next = NULL; node->user = owner; if (ref->last) { ref->last->next = node; node->previous = ref->last; } else { ref->users = node; node->previous = NULL; } ref->last = node; } void RefCountDetach(RefCount *ref, void *owner) { if (!ref || !owner) { ProgrammingError("Either refcount or owner is NULL (or both)"); } if (ref->user_count <= 1) { /* * Semantics: If 1 that means that we are the only users, if 0 nobody is using it. * In either case it is safe to destroy the refcount. */ return; } RefCountNode *p = NULL; int found = 0; for (p = ref->users; p; p = p->next) { if (p->user == owner) { found = 1; if (p->previous && p->next) { p->previous->next = p->next; p->next->previous = p->previous; } else if (p->previous && !p->next) { // Last node p->previous->next = NULL; ref->last = p->previous; } else if (!p->previous && p->next) { // First node ref->users = p->next; p->next->previous = NULL; } else { // Only one node, we cannot detach from ourselves. return; } free(p); break; } } if (!found) { ProgrammingError("The object is not attached to the RefCount object"); } ref->user_count--; } bool RefCountIsShared(RefCount *ref) { return ref && (ref->user_count > 1); } bool RefCountIsEqual(RefCount *a, RefCount *b) { return (a && b) && (a == b); } cfengine-3.24.2/libntech/libutils/version_comparison.h0000644000000000000000000000166215010704254023070 0ustar00rootroot00000000000000#ifndef CF_VERSION_COMPARISON_H #define CF_VERSION_COMPARISON_H #include // bool typedef enum VersionComparison { VERSION_SMALLER, VERSION_EQUAL, VERSION_GREATER, VERSION_ERROR, } VersionComparison; typedef enum BooleanOrError { BOOLEAN_ERROR = -1, BOOLEAN_FALSE = false, BOOLEAN_TRUE = true, } BooleanOrError; VersionComparison CompareVersion(const char *a, const char *b); /** @brief Compare 2 version numbers using an operator. @note This function is just a wrapper around CompareVersion(). @see CompareVersion() @param [in] a The first version number of the expression. @param [in] operator One of: [">", "<", "=", "==", "!=", ">=", "<="]. @param [in] b The second version number of the expression. @return true or false or -1 (invalid operator or version numbers). */ BooleanOrError CompareVersionExpression( const char *a, const char *operator, const char *b); #endif cfengine-3.24.2/libntech/libutils/map_common.h0000644000000000000000000000236515010704254021277 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MAP_COMMON_H #define CFENGINE_MAP_COMMON_H #include /* * Key/Value pair. */ typedef struct { void* key; void *value; } MapKeyValue; typedef unsigned int (*MapHashFn) (const void *p, unsigned int seed); typedef bool (*MapKeyEqualFn) (const void *key1, const void *key2); typedef void (*MapDestroyDataFn) (void *key); #endif cfengine-3.24.2/libntech/libutils/string_sequence.c0000644000000000000000000001722215010704254022341 0ustar00rootroot00000000000000#include #include #include // SafeStringLength() #include // xstrdup() #include // strlen() #include // StringWriter() #include // safe_fopen() ////////////////////////////////////////////////////////////////////////////// // SeqString - Sequence of strings (char *) ////////////////////////////////////////////////////////////////////////////// static void SeqStringAddSplit(Seq *seq, const char *str, char delimiter) { if (str) // TODO: remove this inconsistency, add assert(str) { const char *prev = str; const char *cur = str; while (*cur != '\0') { if (*cur == delimiter) { size_t len = cur - prev; if (len > 0) { SeqAppend(seq, xstrndup(prev, len)); } else { SeqAppend(seq, xstrdup("")); } prev = cur + 1; } cur++; } if (cur > prev) { SeqAppend(seq, xstrndup(prev, cur - prev)); } } } Seq *SeqStringFromString(const char *str, char delimiter) { Seq *seq = SeqNew(10, &free); SeqStringAddSplit(seq, str, delimiter); return seq; } char *StringJoin(const Seq *const seq, const char *sep) { assert(seq != NULL); Writer *const writer = StringWriter(); const size_t len = SeqLength(seq); for (size_t i = 0; i < len; i++) { if (i != 0 && sep != NULL) { WriterWrite(writer, sep); } const char *const str = SeqAt(seq, i); WriterWrite(writer, str); } char *const data = StringWriterClose(writer); return data; } Seq *StringSplit(const char *const str, const char *const charset) { assert(str != NULL); assert(charset != NULL); Seq *seq = SeqNew(1, free); const char *start = str; const char *end = strpbrk(str, charset); while (end != NULL) { char *tmp = xstrndup(start, end - start); SeqAppend(seq, tmp); start = end + 1; end = strpbrk(start, charset); } char *tmp = xstrdup(start); SeqAppend(seq, tmp); return seq; } bool SeqStringContains(const Seq *const seq, const char *const str) { assert(seq != NULL); assert(str != NULL); size_t length = SeqLength(seq); for (size_t i = 0; i < length; ++i) { if (StringEqual(str, SeqAt(seq, i))) { return true; } } return false; } int SeqStringLength(Seq *seq) { assert(seq); int total_length = 0; size_t seq_length = SeqLength(seq); for (size_t i = 0; i < seq_length; i++) { total_length += SafeStringLength(SeqAt(seq, i)); } return total_length; } // TODO: These static helper functions could be (re)moved static bool HasNulByte(const char *str, size_t n) { for (size_t i = 0; i < n; ++i) { if (str[i] == '\0') { return true; } } return false; } static long GetLengthPrefix(const char *data) { if (HasNulByte(data, 10)) { return -1; } if (!isdigit(data[0])) { return -1; } if (data[STR_LENGTH_PREFIX_LEN - 1] != ' ') { return -1; } // NOTE: This uses long because HPUX sscanf doesn't support %zu long length; int ret = sscanf(data, "%ld", &length); if (ret != 1 || length < 0) { // Incorrect number of items matched, or // negative length prefix(invalid) return -1; } return length; } static char *ValidDuplicate(const char *src, size_t n) { assert(src != NULL); char *dst = xcalloc(n + 1, sizeof(char)); size_t len = StringCopy(src, dst, n + 1); // If string was too long, len >= n+1, this is OKAY, there's more data. if (len < n) // string was too short { free(dst); return NULL; } return dst; } bool WriteLenPrefixedString(Writer *w, const char *string) { const size_t str_length = strlen(string); const size_t bytes_written = WriterWriteF( w, "%-" TO_STRING(STR_LENGTH_PREFIX_LEN) "zu%s\n", str_length, string); // TODO: Make WriterWriteF actually be able to propagate errors // (return negative number on short writes). if (bytes_written == 0) { return false; } return true; } bool SeqStringWrite(Seq *seq, Writer *w) { const size_t length = SeqLength(seq); for (size_t i = 0; i < length; ++i) { const char *const s = SeqAt(seq, i); bool success = WriteLenPrefixedString(w, s); if (!success) { return false; } } return true; } char *SeqStringSerialize(Seq *seq) { Writer *w = StringWriter(); SeqStringWrite(seq, w); return StringWriterClose(w); } bool SeqStringWriteFileStream(Seq *seq, FILE *file) { Writer *w = FileWriter(file); assert(w != NULL); bool success = SeqStringWrite(seq, w); FileWriterDetach(w); return success; } bool SeqStringWriteFile(Seq *seq, const char *file) { FILE *f = safe_fopen(file, "w"); if (f == NULL) { return false; } const bool write_success = SeqStringWriteFileStream(seq, f); const bool close_success = (fclose(f) == 0); return (write_success && close_success); } Seq *SeqStringDeserialize(const char *const serialized) { assert(serialized != NULL); assert(STR_LENGTH_PREFIX_LEN > 0); Seq *seq = SeqNew(128, free); const char *src = serialized; while (src[0] != '\0') { // Read length prefix first long length = GetLengthPrefix(src); // Advance the src pointer src += STR_LENGTH_PREFIX_LEN; char *new_str = NULL; // Do validation and duplication in one pass // ValidDuplicate checks for terminating byte up to src[length-1] if (length < 0 || src[-1] != ' ' || NULL == (new_str = ValidDuplicate(src, length)) || src[length] != '\n') { free(new_str); SeqDestroy(seq); return NULL; } SeqAppend(seq, new_str); // Advance src pointer src += length + 1; // +1 for the added newline } return seq; } int ReadLenPrefixedString(int fd, char **string) { char prefix[STR_LENGTH_PREFIX_LEN]; ssize_t bytes_read = FullRead(fd, prefix, STR_LENGTH_PREFIX_LEN); if (bytes_read == 0) { // EOF return 0; } if (bytes_read < 0) { // Error return -1; } assert(prefix[STR_LENGTH_PREFIX_LEN - 1] == ' '); // NOTE: Not NUL-terminated const long length = GetLengthPrefix(prefix); // Read data, followed by a '\n' which we replace with '\0': const long size = length + 1; char *const data = xmalloc(size); bytes_read = FullRead(fd, data, size); if (bytes_read != size || data[length] != '\n') { // Short read, or error, or missing newline free(data); return -1; } data[length] = '\0'; // Replace newline with NUL-terminator *string = data; return 1; } Seq *SeqStringReadFile(const char *file) { const int fd = safe_open(file, O_RDONLY); if (fd < 0) { return NULL; } Seq *seq = SeqNew(500, &free); while (true) { char *data; int ret = ReadLenPrefixedString(fd, &data); if (ret < 0) { /* error */ SeqDestroy(seq); return NULL; } else if (ret == 0) { /* done (EOF) */ return seq; } else { SeqAppend(seq, data); } } } cfengine-3.24.2/libntech/libutils/compiler.h0000644000000000000000000000473615010704254020770 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_COMPILER_H #define CFENGINE_COMPILER_H /* Compiler-specific options/defines */ #if defined(__GNUC__) && (__GNUC__ >= 3) # define FUNC_ATTR_NORETURN __attribute__((noreturn)) # define FUNC_ATTR_PRINTF(string_index, first_to_check) \ __attribute__((format(__printf__, string_index, first_to_check))) # define FUNC_UNUSED __attribute__((unused)) # define ARG_UNUSED __attribute__((unused)) # define FUNC_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) # if (__GNUC__ >= 4) && (__GNUC_MINOR__ >=5) # define FUNC_DEPRECATED(msg) __attribute__((deprecated(msg))) # else # define FUNC_DEPRECATED(msg) __attribute__((deprecated)) # endif #else /* not gcc >= 3.0 */ # define FUNC_ATTR_NORETURN # define FUNC_ATTR_PRINTF(string_index, first_to_check) # define FUNC_UNUSED # define ARG_UNUSED # define FUNC_WARN_UNUSED_RESULT # define FUNC_DEPRECATED(msg) #endif /* gcc >= 3.0 */ /** * If you have a variable or function parameter unused under specific * conditions (like ifdefs), you can suppress the "unused variable" warning * by just doing UNUSED(x). */ #define UNUSED(x) (void)(x) /** * For variables only used in debug builds, in particular only in assert() * calls, use NDEBUG_UNUSED. */ #ifdef NDEBUG #define NDEBUG_UNUSED __attribute__((unused)) #else #define NDEBUG_UNUSED #endif /** * If you want a string literal version of a macro, useful in scanf formats: * * #define BUFSIZE 1024 * TO_STRING(BUFSIZE) -> "1024" */ #define STRINGIFY__INTERNAL_MACRO(x) #x #define TO_STRING(x) STRINGIFY__INTERNAL_MACRO(x) #endif /* CFENGINE_COMPILER_H */ cfengine-3.24.2/libntech/libutils/Makefile.in0000644000000000000000000007131615010704273021051 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @WITH_OPENSSL_TRUE@am__append_1 = \ @WITH_OPENSSL_TRUE@ encode.c encode.h \ @WITH_OPENSSL_TRUE@ hash.c hash.h @WITH_PCRE2_TRUE@am__append_2 = \ @WITH_PCRE2_TRUE@ regex.c regex.h @NT_FALSE@am__append_3 = unix_dir.c @CYGWIN_TRUE@am__append_4 = unix_dir.c subdir = libutils ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/tar.m4 \ $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = writer.h clockid_t.h regex.h glob_lib.h \ json-yaml.h CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libutils_la_DEPENDENCIES = ../libcompat/libcompat.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__libutils_la_SOURCES_DIST = alloc.c alloc.h array_map.c \ array_map_priv.h buffer.c buffer.h cleanup.c cleanup.h \ clockid_t.h compiler.h csv_writer.c csv_writer.h csv_parser.c \ csv_parser.h definitions.h deprecated.h dir.h dir_priv.h \ file_lib.c file_lib.h hash_map.c hash_map_priv.h hash_method.h \ ip_address.c ip_address.h json.c json.h json-priv.h \ json-pcre.h json-utils.c json-utils.h json-yaml.c json-yaml.h \ known_dirs.c known_dirs.h list.c list.h logging.c logging.h \ logging_priv.h man.c man.h map.c map.h map_common.h misc_lib.c \ misc_lib.h mustache.c mustache.h mutex.c mutex.h \ passopenfile.c passopenfile.h path.c path.h platform.h \ condition_macros.h printsize.h proc_keyvalue.c proc_keyvalue.h \ queue.c queue.h rb-tree.c rb-tree.h refcount.c refcount.h \ ring_buffer.c ring_buffer.h sequence.c sequence.h \ string_sequence.c string_sequence.h set.c set.h stack.c \ stack.h threaded_stack.c threaded_stack.h statistics.c \ statistics.h string_lib.c string_lib.h threaded_deque.c \ threaded_deque.h threaded_queue.c threaded_queue.h unicode.c \ unicode.h version_comparison.c version_comparison.h writer.c \ writer.h xml_writer.c xml_writer.h glob_lib.c glob_lib.h \ encode.c encode.h hash.c hash.h regex.c regex.h unix_dir.c @WITH_OPENSSL_TRUE@am__objects_1 = encode.lo hash.lo @WITH_PCRE2_TRUE@am__objects_2 = regex.lo @NT_FALSE@am__objects_3 = unix_dir.lo @CYGWIN_TRUE@am__objects_4 = unix_dir.lo am_libutils_la_OBJECTS = alloc.lo array_map.lo buffer.lo cleanup.lo \ csv_writer.lo csv_parser.lo file_lib.lo hash_map.lo \ ip_address.lo json.lo json-utils.lo json-yaml.lo known_dirs.lo \ list.lo logging.lo man.lo map.lo misc_lib.lo mustache.lo \ mutex.lo passopenfile.lo path.lo proc_keyvalue.lo queue.lo \ rb-tree.lo refcount.lo ring_buffer.lo sequence.lo \ string_sequence.lo set.lo stack.lo threaded_stack.lo \ statistics.lo string_lib.lo threaded_deque.lo \ threaded_queue.lo unicode.lo version_comparison.lo writer.lo \ xml_writer.lo glob_lib.lo $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) libutils_la_OBJECTS = $(am_libutils_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libutils_la_SOURCES) DIST_SOURCES = $(am__libutils_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/clockid_t.h.in \ $(srcdir)/glob_lib.h.in $(srcdir)/json-yaml.h.in \ $(srcdir)/regex.h.in $(srcdir)/writer.h.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GREP = @GREP@ HAVE_CLOCKID_T_DEFINE = @HAVE_CLOCKID_T_DEFINE@ HAVE_GETOPT_H_DEFINE = @HAVE_GETOPT_H_DEFINE@ HAVE_LIBYAML_DEFINE = @HAVE_LIBYAML_DEFINE@ HOSTNAME = @HOSTNAME@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NO_TAUTOLOGICAL_CC_OPTION = @NO_TAUTOLOGICAL_CC_OPTION@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_LOGGING_CFLAGS = @SYSTEMD_LOGGING_CFLAGS@ SYSTEMD_LOGGING_CPPFLAGS = @SYSTEMD_LOGGING_CPPFLAGS@ SYSTEMD_LOGGING_LDFLAGS = @SYSTEMD_LOGGING_LDFLAGS@ SYSTEMD_LOGGING_LIBS = @SYSTEMD_LOGGING_LIBS@ SYSTEMD_LOGGING_PATH = @SYSTEMD_LOGGING_PATH@ VERSION = @VERSION@ WITH_PCRE2_DEFINE = @WITH_PCRE2_DEFINE@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libutils.la # TODO remove the openssl dependency! It's only there for base64 encoding. AM_CFLAGS = $(CORE_CFLAGS) $(PCRE2_CFLAGS) $(OPENSSL_CFLAGS) AM_CPPFLAGS = $(CORE_CPPFLAGS) $(PCRE2_CPPFLAGS) $(OPENSSL_CPPFLAGS) AM_LDFLAGS = $(CORE_LDFLAGS) $(PCRE2_LDFLAGS) $(OPENSSL_LDFLAGS) libutils_la_LIBADD = ../libcompat/libcompat.la $(PCRE2_LIBS) $(OPENSSL_LIBS) $(SYSTEMD_LOGGING_LIBS) $(LIBYAML_LIBS) libutils_la_SOURCES = alloc.c alloc.h array_map.c array_map_priv.h \ buffer.c buffer.h cleanup.c cleanup.h clockid_t.h compiler.h \ csv_writer.c csv_writer.h csv_parser.c csv_parser.h \ definitions.h deprecated.h dir.h dir_priv.h file_lib.c \ file_lib.h hash_map.c hash_map_priv.h hash_method.h \ ip_address.c ip_address.h json.c json.h json-priv.h \ json-pcre.h json-utils.c json-utils.h json-yaml.c json-yaml.h \ known_dirs.c known_dirs.h list.c list.h logging.c logging.h \ logging_priv.h man.c man.h map.c map.h map_common.h misc_lib.c \ misc_lib.h mustache.c mustache.h mutex.c mutex.h \ passopenfile.c passopenfile.h path.c path.h platform.h \ condition_macros.h printsize.h proc_keyvalue.c proc_keyvalue.h \ queue.c queue.h rb-tree.c rb-tree.h refcount.c refcount.h \ ring_buffer.c ring_buffer.h sequence.c sequence.h \ string_sequence.c string_sequence.h set.c set.h stack.c \ stack.h threaded_stack.c threaded_stack.h statistics.c \ statistics.h string_lib.c string_lib.h threaded_deque.c \ threaded_deque.h threaded_queue.c threaded_queue.h unicode.c \ unicode.h version_comparison.c version_comparison.h writer.c \ writer.h xml_writer.c xml_writer.h glob_lib.c glob_lib.h \ $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) EXTRA_DIST = stack_base.c CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = config.h.in all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libutils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libutils/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): writer.h: $(top_builddir)/config.status $(srcdir)/writer.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ clockid_t.h: $(top_builddir)/config.status $(srcdir)/clockid_t.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ regex.h: $(top_builddir)/config.status $(srcdir)/regex.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ glob_lib.h: $(top_builddir)/config.status $(srcdir)/glob_lib.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ json-yaml.h: $(top_builddir)/config.status $(srcdir)/json-yaml.h.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libutils.la: $(libutils_la_OBJECTS) $(libutils_la_DEPENDENCIES) $(EXTRA_libutils_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libutils_la_OBJECTS) $(libutils_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cleanup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv_parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csv_writer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glob_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash_map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_address.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json-yaml.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/known_dirs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/man.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mustache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mutex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passopenfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_keyvalue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/queue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-tree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refcount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ring_buffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sequence.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statistics.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_sequence.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threaded_deque.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threaded_queue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/threaded_stack.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unicode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version_comparison.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_writer.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libntech/libutils/stack_base.c0000644000000000000000000000543015010704254021240 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /** @file stack_base.c * @brief Shared code between threaded_stack.c and stack.c * * This file should be included, not compiled separately. */ #include #define EXPAND_FACTOR 2 #define DEFAULT_CAPACITY 16 /** @struct Stack_ @brief A simple stack data structure. Can push, pop, and copy. Also has functions for showing current stack size and capacity, and if a stack is empty. If the amount of pushed elements exceed the capacity, it will be multiplied by EXPAND_FACTOR and reallocated with the new capacity. When destroying the stack, destroys each element with the ItemDestroy function specified before freeing the data array and the stack itself. */ struct Stack_ { void (*ItemDestroy) (void *item); /**< Data-specific destroy function. */ void **data; /**< Internal array of elements. */ size_t size; /**< Amount of elements in stack. */ size_t capacity; /**< Current memory allocated. */ }; static void StackInit(Stack *stack, size_t initial_capacity, void (ItemDestroy) (void *item)) { assert(stack != NULL); if (initial_capacity == 0) { initial_capacity = DEFAULT_CAPACITY; } stack->capacity = initial_capacity; stack->size = 0; stack->data = xcalloc(initial_capacity, sizeof(void *)); stack->ItemDestroy = ItemDestroy; } /** @brief Destroys data in range. @note Assumes that locks are acquired. @param [in] stack Pointer to struct. @param [in] start Start position to destroy from. @param [in] end Where to stop. */ static void DestroyRange(Stack *stack, size_t start, size_t end) { assert(stack != NULL); if (start > stack->capacity || end > stack->capacity) { return; } if (stack->ItemDestroy) { for (size_t i = start; i < end; i++) { stack->ItemDestroy(stack->data[i]); } } } cfengine-3.24.2/libntech/libutils/path.h0000644000000000000000000000337715010704254020112 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PATH_H #define CFENGINE_PATH_H // TODO: Move more functions from files_names.c here /** * @brief Returns the filename part of a string/path, similar to basename * * Differs from basename() by not modifying the input arg and * just returning a pointer within the arg (not an internal static buffer). * Locates the string after the last `/`. If none are present, assumes it's * a relative path, and that the whole string is a filename. * * @return Pointer to filename within path, NULL if path ends in / (directory) */ const char *Path_Basename(const char *path); char *Path_JoinAlloc(const char *dir, const char *leaf); /** * Get a quoted path if not already quoted and if needs to be quoted (contains * spaces and/or other special characters). * * @return A newly-allocated string (or %NULL if given %NULL) */ char *Path_GetQuoted(const char *path); #endif cfengine-3.24.2/libntech/libutils/sequence.h0000644000000000000000000002513015010704254020755 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SEQUENCE_H #define CFENGINE_SEQUENCE_H #include // size_t #include // ssize_t #include // assert() #include // FILE #include /** @brief Sequence data-structure. This is an array-list loosely modeled on GSequence. It is a managed array of void pointers and can be used to store arbitrary data. The array list will auto-expand by a factor of EXPAND_FACTOR (e.g. 2) when necessary, but not contract. Because sequence is content agnostic, it does not support the usual copy semantics found in other CFEngine structures, such as RList. Thus, appending an item to a Sequence may imply a transfer of ownership. Clients that require copy semantics should therefore make sure that elements are copied before they are appended. Some Sequence operations may remove some or all of the elements held. In order to do so safely, it's incumbent upon the client to supply the necessary item destructor to the Sequence constructor. If the item destructor argument is NULL, Sequence will not attempt to free the item memory held. */ typedef struct { void **data; size_t length; size_t capacity; void (*ItemDestroy) (void *item); } Seq; static inline void *SeqAt(const Seq *seq, size_t i) { assert(seq != NULL); assert(i < seq->length); return seq->data[i]; } /** @brief Length of the sequence. @note On NULL sequence return size 0. @param seq [in] sequence. @return Sequence length. */ size_t SeqLength(const Seq *seq); /** @brief Create a new Sequence @param [in] initial_capacity Size of initial buffer to allocate for item pointers. @param [in] ItemDestroy Optional item destructor to clean up memory when needed. @return A pointer to the created Sequence */ Seq *SeqNew(size_t initial_capacity, void (*ItemDestroy) ()); /** @brief Destroy an existing Sequence @param [in] seq The Sequence to destroy. */ void SeqDestroy(Seq *seq); /** @brief Destroy an existing Sequence without destroying its items. @param [in] seq The Sequence to destroy. */ void SeqSoftDestroy(Seq *seq); /** @brief Function to compare two items in a Sequence. @retval -1 if the first argument is smaller than the second @retval 0 if the arguments are equal @retval 1 if the first argument is bigger than the second */ typedef int (*SeqItemComparator) (const void *, const void *, void *user_data); /** @brief Wrapper of the standard library function strcmp. Used to avoid cast-function-type compiler warnings when casting strcmp to (SeqItemComparator) in sequence functions. @param [in] s1 The string being compared to the s2 string @param [in] s2 The string that s1 is compared to @param [in] user_data This parameter is the ignored user_data that the SeqItemComparator expects @return 0 if s1 and s2 strings are equal @return negative if s1 is less than s2 @return positive if s1 is greater than s2 */ int StrCmpWrapper(const void *s1, const void *s2, void *user_data); /** * Replace value at #index. * * @warning Destroys the original item at #index! See SeqSoftSet(). */ void SeqSet(Seq *set, size_t index, void *item); /** * Set value at #index. * * @note Make sure the original item at #index is destroyed. */ void SeqSoftSet(Seq *set, size_t index, void *item); /** @brief Append a new item to the Sequence @param seq [in] The Sequence to append to. @param item [in] The item to append. Note that this item may be passed to the item destructor specified in the constructor. */ void SeqAppend(Seq *seq, void *item); /** @brief Append a new item to the Sequence if it's not already present in the Sequence. @note This calls SeqLookup() and thus linearly searches through the sequence. @param seq [in] The Sequence to append to. @param item [in] The item to append. Note that this item will be passed to the item destructor specified in the constructor. Either immediately if the same item (according to Compare()) is found in the Sequence or once the Sequence is destroyed with SeqDestroy(). */ void SeqAppendOnce(Seq *seq, void *item, SeqItemComparator Compare); /** * @brief Append a sequence to this sequence. Only copies pointers. * @param seq Sequence to append to * @param items Sequence to copy pointers from. */ void SeqAppendSeq(Seq *seq, const Seq *items); /** @brief Linearly searches through the sequence and return the first item considered equal to the specified key. @param seq [in] The Sequence to search. @param key [in] The item to compare against. @param compare [in] Comparator function to use. An item matches if the function returns 0. @returns A pointer to the found item, or NULL if not found. */ void *SeqLookup(Seq *seq, const void *key, SeqItemComparator Compare); /** * @brief Performs a binary search looking for the item matching the given key. * It is the programmer's responsibility to make sure that the sequence is already sorted. * @param seq [in] The Sequence to search. * @param key [in] The item to compare against. * @param compare [in] Comparator function to use (return value has strcmp semantics). * @returns A pointer to the found item, or NULL if not found. */ void *SeqBinaryLookup(Seq *seq, const void *key, SeqItemComparator Compare); /** @brief Linearly searches through the sequence and returns the index of the first matching object, or -1 if it doesn't exist. */ ssize_t SeqIndexOf(Seq *seq, const void *key, SeqItemComparator Compare); /** * @brief Performs a binary search looking for the item matching the given key. * It is the programmer's responsibility to make sure that the sequence is already sorted. * @param seq [in] The Sequence to search. * @param key [in] The item to compare against. * @param compare [in] Comparator function to use (return value has strcmp semantics). * @returns The index of the item, or -1 if it is not found. */ ssize_t SeqBinaryIndexOf(Seq *seq, const void *key, SeqItemComparator Compare); /** @brief Remove an inclusive range of items in the Sequence. A single item may be removed by specifying start = end. @param seq [in] The Sequence to remove from. @param start [in] Index of the first element to remove @param end [in] Index of the last element to remove. */ void SeqRemoveRange(Seq *seq, size_t start, size_t end); /** @brief Remove a single item in the sequence */ void SeqRemove(Seq *seq, size_t index); /** @brief Sort a Sequence according to the given item comparator function @param compare [in] The comparator function used for sorting. @param user_data [in] Pointer passed to the comparator function */ void SeqSort(Seq *seq, SeqItemComparator compare, void *user_data); /** @brief Returns a soft copy of the sequence sorted according to the given item comparator function. @param compare [in] The comparator function used for sorting. @param user_data [in] Pointer passed to the comparator function */ Seq *SeqSoftSort(const Seq *seq, SeqItemComparator compare, void *user_data); /** @brief Remove an inclusive range of item handles in the Sequence. A single item may be removed by specifying start = end. @param seq [in] The Sequence to remove from. @param start [in] Index of the first element to remove @param end [in] Index of the last element to remove. */ void SeqSoftRemoveRange(Seq *seq, size_t start, size_t end); /** @brief Remove a single item handle from the sequence */ void SeqSoftRemove(Seq *seq, size_t index); /** @brief Reverses the order of the sequence */ void SeqReverse(Seq *seq); /** @brief Split a sequence in two at a given index. Elements before the split are kept in original sequence, elements after the split are moved to a new sequence, which is returned. The original, the new, and the modified sequence may all be empty. Items in sequence are not reallocated, they are moved and the new sequnce has the same destroy function as the original. @param original [in] The Sequence to split in two (will be modified) @param index [in] Index of split, or how many elements to keep in original @return New sequence containing the elements removed from original */ Seq *SeqSplit(Seq *original, size_t index); /** * @brief Shuffle the sequence by randomly switching positions of the pointers * @param seq * @param seed Seed value for the PRNG */ void SeqShuffle(Seq *seq, unsigned int seed); /** * @brief Remove all elements in sequence * @param seq */ void SeqClear(Seq *seq); /** @brief Get soft copy of sequence according to specified range @param [in] seq Sequence select from @param [in] start Start index of sub sequence. @param [in] end End index which will be included into. @return A pointer to sub sequence, NULL on error. */ Seq *SeqGetRange(const Seq *seq, size_t start, size_t end); /** * @brief Get the data segment of the sequence * @param [in] seq Sequence to get the data segment of * @return An array of pointers to data stored in the sequence * @warning The returned array is not guaranteed to be %NULL-terminated unless %NULL was appended to * the sequence. */ void *const *SeqGetData(const Seq *seq); /** * @brief Custom filter callback function used with SeqFilter. * @param element Element in sequence to filter. * @return True if element should be filtered, otherwise false. */ typedef bool SeqFilterFn(void *element); /** * @brief Filter elements on sequence. * @param seq Sequence to filter elements from. * @param filter Callback filter function. * @return A pointer to the sequence itself (for convenience). */ Seq *SeqFilter(Seq *seq, SeqFilterFn filter); /** * @brief Filter NULL pointers from Sequence. * @param seq Sequence to filter NULL pointers from. */ void SeqRemoveNulls(Seq *seq); Seq *SeqFromArgv(int argc, const char *const *argv); #endif cfengine-3.24.2/libntech/libutils/file_lib.h0000644000000000000000000003023215010704254020711 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILE_LIB_H #define CFENGINE_FILE_LIB_H #include // bool #include // uid_t #include // lstat #include #include #include typedef enum { NewLineMode_Unix, // LF everywhere NewLineMode_Native // CRLF on Windows, LF elsewhere } NewLineMode; #define FILE_ERROR_READ -1 /** * Reads up to size_max bytes from filename and returns a Writer. */ Writer *FileRead(const char *filename, size_t size_max, bool *truncated); /** * Reads up to max_bytes bytes from file and writes into buf. * Returns negative numbers in case of errors, bytes read/written otherwise. */ ssize_t ReadFileStreamToBuffer(FILE *file, size_t max_bytes, char *buf); /** * Copies a files content, without preserving metadata, times or permissions */ bool File_Copy(const char *src, const char *dst); /** * Same as CopyFile, except destination is a directory, * and filename will match source */ bool File_CopyToDir(const char *src, const char *dst_dir); /** * Reads up to size_max bytes from fd and returns a Writer. */ Writer *FileReadFromFd(int fd, size_t size_max, bool *truncated); bool FileCanOpen(const char *path, const char *modes); /** * Returns true if a path (such as a file or a folder) exists * Don't follow symlinks, don't check permissions, don't check if it's a file. * This function is similar to access (man 2 access), consider using that * instead (for example if you want to follow symlinks). */ static inline bool PathExists(const char *path) { struct stat statbuf; return (lstat(path, &statbuf) == 0); } /* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted. Return LEN upon success, write's (negative) error code otherwise. */ ssize_t FullWrite(int desc, const char *ptr, size_t len); /* Read up to LEN bytes (or EOF) to PTR from descriptor DESC, retrying if interrupted. Return amount of bytes read upon success, -1 otherwise */ ssize_t FullRead(int desc, char *ptr, size_t len); bool IsDirReal(const char *path); /** * Returns what type of line endings the file is using. * * @param file File to check. * @return Always returns NewLineMode_Unix on Unix. On Windows it may return * NewLineMode_Native if the file has CRLF line endings. * If the file cannot be opened, or the line endings are mixed it will * return NewLineMode_Native. Note that only the first CF_BUFSIZE bytes * are checked. */ NewLineMode FileNewLineMode(const char *file); /* File node separator (cygwin can use \ or / but prefer \ for communicating * with native windows commands). */ #ifdef _WIN32 # define IsFileSep(c) ((c) == '\\' || (c) == '/') # define FILE_SEPARATOR '\\' # define FILE_SEPARATOR_STR "\\" #else # define IsFileSep(c) ((c) == '/') # define FILE_SEPARATOR '/' # define FILE_SEPARATOR_STR "/" #endif bool IsAbsoluteFileName(const char *f); /** * @brief Check whether or not path is a Windows network path (i.e., paths that * starts with double slash followed by hostname or IP). * @param path Path to check. * @return True if path is network path, otherwise false. * @note This function cannot return true on non-Windows platforms. */ bool IsWindowsNetworkPath(const char *path); /** * @brief Check whether or not path is a Windows disk path. * @param path Path to check. * @return True if path is disk path, otherwise false. * @note This function cannot return true on non-Windows platforms. */ bool IsWindowsDiskPath(const char *path); char *MapName(char *s); char *MapNameCopy(const char *s); char *MapNameForward(char *s); Seq *ListDir(const char *dir, const char *extension); mode_t SetUmask(mode_t new_mask); void RestoreUmask(mode_t old_mask); int safe_open(const char *const pathname, int flags); int safe_open_create_perms( const char *pathname, int flags, mode_t create_perms); FILE *safe_fopen(const char *path, const char *mode); FILE *safe_fopen_create_perms( const char *path, const char *mode, mode_t create_perms); int safe_chdir(const char *path); int safe_chown(const char *path, uid_t owner, gid_t group); int safe_chmod(const char *path, mode_t mode); #ifndef __MINGW32__ int safe_lchown(const char *path, uid_t owner, gid_t group); #endif int safe_creat(const char *pathname, mode_t mode); /** * @brief Sets whether a file descriptor should be closed on * exec()/CreateProcess(). * @param fd File descriptor. * @param inherit Whether to enable close-on-exec or not. * @return true on success, false otherwise. */ bool SetCloseOnExec(int fd, bool enable); /** * @brief Deletes directory path recursively. Symlinks are not followed. * Note that this function only deletes the contents of the directory, not the directory itself. * @param path * @return true if directory was deleted successfully, false if one or more files were not deleted. */ bool DeleteDirectoryTree(const char *path); bool FileSparseWrite(int fd, const void *buf, size_t count, bool *wrote_hole); bool FileSparseCopy(int sd, const char *src_name, int dd, const char *dst_name, size_t blk_size, size_t *total_bytes_written, bool *last_write_was_a_hole); bool FileSparseClose(int fd, const char *filename, bool do_sync, size_t total_bytes_written, bool last_write_was_hole); /** * @brief Works exactly like posix 'getline', EXCEPT it does not include carriage return at the end. * @return -1 on error OR EOF, so check. Or bytes in buff without excluding terminator. */ ssize_t CfReadLine(char **buff, size_t *size, FILE *fp); /** * @brief Read lines from a file and return them as a sequence. * * @param buff If not %NULL, a buffer used for the internal CfReadLine() calls * @param size Size of the buffer %buff (or 0) * @param fp File to read the data from * @param lines Sequence to append the read lines to * * @return Number of items/lines appended to #lines or -1 in case of error * @note #buff can be reallocated by an internal CfReadLine() call in which case, * #size is also adapted accordingly (just like getline() does) * @warning The information about lengths of individual lines is lost, * use CfReadLine() for files with NUL bytes. */ ssize_t CfReadLines(char **buff, size_t *size, FILE *fp, Seq *lines); /** * @brief For testing things against /proc, uses env var CFENGINE_TEST_OVERRIDE_PROCDIR * @return the extra directory to add BEFORE /proc in the path */ const char* GetRelocatedProcdirRoot(); /*********** File locking ***********/ typedef struct _FileLock { /* may be extended with some other fields in the future */ /** * File descriptor to the file associated with the lock (if any) * @note %fd == -1 is used to indicate that the lock is not associated with * any file */ int fd; } FileLock; #define EMPTY_FILE_LOCK { .fd = -1 } /** * Try to acquire an exclusive lock. * * @param lock The lock to try to acquire. lock.fd needs to be an open FD. * @param wait Whether to wait for the lock (blocks) or give up immediately. * @return 0 in case of success, -1 in case of failure. */ int ExclusiveFileLock(FileLock *lock, bool wait); /** * Try to acquire an exclusive lock on the file given by path. * * @param lock The lock to try to acquire. lock.fd has to be -1. * @param fpath Path to the file to lock. * @param wait Whether to wait for the lock (blocks) or give up immediately. * @return 0 in case of success, * -1 in case of failure to lock, * -2 in case of failure to open */ int ExclusiveFileLockPath(FileLock *lock, const char *fpath, bool wait); /** * Yield the previously acquired lock. * * @param lock Lock to yield. * @param close_fd Whether to close the FD when yielding the lock. * @return 0 in case of success, -1 in case of failure. */ int ExclusiveFileUnlock(FileLock *lock, bool close_fd); /** * @see ExclusiveFileLock() */ int SharedFileLock(FileLock *lock, bool wait); /** * @see ExclusiveFileLockPath() * @note The resulting lock.fd is opened RDONLY (shared lock is semantically * a reader lock). */ int SharedFileLockPath(FileLock *lock, const char *fpath, bool wait); /** * @see ExclusiveFileUnock() */ int SharedFileUnlock(FileLock *lock, bool close_fd); #ifdef __MINGW32__ bool ExclusiveFileLockCheck(FileLock *lock) __attribute__ ((error("ExclusiveLockFileCheck() is not supported on Windows"))); #else /** * Check if an exclusive lock could be acquired. * * @param lock Lock to check. * @return Whether it would be possible to acquire an exclusive lock or not. * @warning There is of course a race condition when this is used to check if * a blocking call to ExclusiveFileLock() would block! * @note If the current process is already holding a lock on the file, * this function returns %true because a call to ExclusiveFileLock() * would just succeed (no-op or change the lock type). */ bool ExclusiveFileLockCheck(FileLock *lock); #endif /* __MINGW32__ */ /** * @brief Callback function prototype for PathWalk() #callback argument. * @param dirpath Path to the current directory. * @param dirnames List of subdirectories in dirpath (excluding '.' and '..'). * @param filenames List of non-directories in dirpath. * @param data Arbitrary data passed to PathWalk(). * @note If you don't want to continue down a path, you can simply remove the * respective subdirectory from the #dirnames sequence, or set it to * %NULL. Also, if you need to walk the directory entries '.' or '..', you * can append them to dirnames sequence. However, be careful so that you * don't end up with an infinite recursion. Futhermore you are free to * reorder the #dirnames sequence, which otherwise ensures a depth-first * walk. */ typedef void PathWalkFn(const char *dirpath, Seq *dirnames, const Seq *filenames, void *data); /** * @brief Callback function prototype for PathWalk() #copy argument. * @param data Arbitrary data passed to PathWalk(). * @return Should return data fully or partially duplicated. * @note Used to duplicate data before each recursive branching. Can be %NULL. */ typedef void *PathWalkCopyFn(void *data); /** * @brief Callback function prototype for PathWalk() #destroy argument. * @param data Arbitrary data passed to PathWalk(). * @note Used in conjunction with PathWalkCopyFn() in order to free duplicated * data after each recursive branching. Can be %NULL. */ typedef void PathWalkDestroyFn(void *data); /** * @brief Recursively walks the directory tree. * @param path Path to walk. * @param callback Function to call for each visited directory. * @param data Arbitrary data to pass to callback function. * @param copy You might need to duplicate the arbitrary data for each recursive * branching. In that case you can add a copy callback function. If * you don't need this, you can set this parameter to NULL. * @param destroy Callback function to be used in conjunction with the copy * callback in order to destroy copy. Can be set to NULL. * @note This function follows symbolic links. */ void PathWalk( const char *path, PathWalkFn callback, void *data, PathWalkCopyFn copy, PathWalkDestroyFn destroy); #endif cfengine-3.24.2/libntech/libutils/hash.h0000644000000000000000000001377015010704254020077 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_HASH_H #define CFENGINE_HASH_H /** @brief Hash implementations */ #include #include #include #include /* HashMethod, HashSize */ typedef struct Hash Hash; /** @brief Creates a new structure of type Hash. @param data String to hash. @param length Length of the string to hash. @param method Hash method. @return A structure of type Hash or NULL in case of error. */ Hash *HashNew(const char *data, const unsigned int length, HashMethod method); /** @brief Creates a new structure of type Hash. @param descriptor Either file descriptor or socket descriptor. @param method Hash method. @return A structure of type Hash or NULL in case of error. */ Hash *HashNewFromDescriptor(const int descriptor, HashMethod method); /** @brief Creates a new structure of type Hash. @param rsa RSA key to be hashed. @param method Hash method. @return A structure of type Hash or NULL in case of error. */ Hash *HashNewFromKey(const RSA *rsa, HashMethod method); /** @brief Destroys a structure of type Hash. @param hash The structure to be destroyed. */ void HashDestroy(Hash **hash); /** @brief Copy a hash @param origin Hash to be copied. @param destination Hash to be copied to. @return 0 if successful, -1 in any other case. */ int HashCopy(Hash *origin, Hash **destination); /** @brief Checks if two hashes are equal. @param a 1st hash to be compared. @param b 2nd hash to be compared. @return True if both hashes are equal and false in any other case. */ bool HashEqual(const Hash *a, const Hash *b); /** @brief Pointer to the raw digest data. @note Notice that this is a binary representation and not '\0' terminated. @param hash Hash structure. @param length Pointer to an unsigned int to hold the length of the data. @return A pointer to the raw digest data. */ const unsigned char *HashData(const Hash *hash, unsigned int *length); /** @brief Printable hash representation. @param hash Hash structure. @return A pointer to the printable digest representation. */ const char *HashPrintable(const Hash *hash); /** @brief Hash type. @param hash Hash structure @return The hash method used by this hash structure. */ HashMethod HashType(const Hash *hash); /** @brief Hash length in bytes. @param hash Hash structure @return The hash length in bytes. */ HashSize HashLength(const Hash *hash); /** @brief Returns the ID of the hash based on the name @param hash_name Name of the hash. @return Returns the ID of the hash from the name. */ HashMethod HashIdFromName(const char *hash_name); /** @brief Returns the name of the hash based on the ID. @param hash_id Id of the hash. @return Returns the name of the hash. */ const char *HashNameFromId(HashMethod hash_id); /** @brief Returns pointer to an openssl digest struct Equivalent to EVP_get_digestbyname(HashNameFromId(type)), but with added error checking. Returns NULL in case of error. */ const EVP_MD *HashDigestFromId(HashMethod type); /** @brief Size of the hash @param method Hash method @return Returns the size of the hash or 0 in case of error. */ HashSize HashSizeFromId(HashMethod hash_id); /* Enough room for "SHA=asdfasdfasdf". */ #define CF_HOSTKEY_STRING_SIZE (4 + 2 * EVP_MAX_MD_SIZE + 1) void HashFile(const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, bool text_mode); void HashString(const char *buffer, int len, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type); bool HashesMatch( const unsigned char digest1[EVP_MAX_MD_SIZE + 1], const unsigned char digest2[EVP_MAX_MD_SIZE + 1], HashMethod type); char *HashPrintSafe(char *dst, size_t dst_size, const unsigned char *digest, HashMethod type, bool use_prefix); char *SkipHashType(char *hash); void HashPubKey(const RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type); /** * @brief Copy a string from src to dst, if src is too big, truncate and hash. * * If the src string (including NUL terminator) does not fit in dst * (according to dst_size), the last part of dst is a hash of the full src * string, before truncation. * * This function is primarily intended to limit the length of keys in a * key-value store, like LMDB, while still keeping the strings readable AND * unique. * * Examples: * "short_string" -> "short_string" * "string_which_is_too_long_for_size" -> "string_which_is#MD5=" * * If this function returns dst_size, the string was truncated and hashed, * the destination string is exactly dst_size - 1 bytes long in this case. * * @param src[in] String to copy from, must be '\0'-terminated * @param dst[out] Destination to copy to, will always be '\0'-terminated * @param dst_size[in] Size of destination buffer (including '\0'-terminator) * @return dst_size if string was truncated, string length (src/dst) otherwise * @note dst must always be of size dst_size or bigger, regardless of src * @see StringCopy() */ size_t StringCopyTruncateAndHashIfNecessary( const char *src, char *dst, size_t dst_size); #endif // CFENGINE_HASH_H cfengine-3.24.2/libntech/libutils/csv_parser.h0000644000000000000000000000205115010704254021311 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CSV_PARSER_H #define CFENGINE_CSV_PARSER_H #include Seq *SeqParseCsvString(const char *string); char *GetCsvLineNext(FILE *fp); #endif cfengine-3.24.2/libntech/libutils/json.h0000644000000000000000000005561115010704254020125 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_JSON_H #define CFENGINE_JSON_H #include #include // int64_t #include /** @brief JSON data-structure. This is a JSON Document Object Model (DOM). Clients deal only with the opaque JsonElement, which may be either a container or a primitive (client should probably not deal much with primitive elements). A JSON container may be either an object or an array. The JSON DOM currently supports copy semantics for primitive values, but not for container types. In practice, this means that clients always just free the parent element, but an element should just have a single parent, or none. JSON primitives as JsonElement are currently not well supported. JSON DOM is currently built upon Sequence. The JSON specification may be found at @link http://www.json.org @endlink. @see Sequence */ typedef enum { JSON_ELEMENT_TYPE_CONTAINER = 1, JSON_ELEMENT_TYPE_PRIMITIVE = 2, } JsonElementType; typedef enum { JSON_CONTAINER_TYPE_OBJECT = 3, JSON_CONTAINER_TYPE_ARRAY = 4, } JsonContainerType; typedef enum { JSON_PRIMITIVE_TYPE_STRING = 5, JSON_PRIMITIVE_TYPE_INTEGER = 6, JSON_PRIMITIVE_TYPE_REAL = 7, JSON_PRIMITIVE_TYPE_BOOL = 8, JSON_PRIMITIVE_TYPE_NULL = 9, } JsonPrimitiveType; typedef enum { JSON_TYPE_OBJECT = JSON_CONTAINER_TYPE_OBJECT, JSON_TYPE_ARRAY = JSON_CONTAINER_TYPE_ARRAY, JSON_TYPE_STRING = JSON_PRIMITIVE_TYPE_STRING, JSON_TYPE_INTEGER = JSON_PRIMITIVE_TYPE_INTEGER, JSON_TYPE_REAL = JSON_PRIMITIVE_TYPE_REAL, JSON_TYPE_BOOL = JSON_PRIMITIVE_TYPE_BOOL, JSON_TYPE_NULL = JSON_PRIMITIVE_TYPE_NULL, } JsonType; typedef enum { JSON_PARSE_OK = 0, JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_START, JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_END, JSON_PARSE_ERROR_NUMBER_EXPONENT_NEGATIVE, JSON_PARSE_ERROR_NUMBER_EXPONENT_POSITIVE, JSON_PARSE_ERROR_NUMBER_DUPLICATE_ZERO, JSON_PARSE_ERROR_NUMBER_NO_DIGIT, JSON_PARSE_ERROR_NUMBER_MULTIPLE_DOTS, JSON_PARSE_ERROR_NUMBER_EXPONENT_DUPLICATE, JSON_PARSE_ERROR_NUMBER_EXPONENT_DIGIT, JSON_PARSE_ERROR_NUMBER_EXPONENT_FOLLOW_LEADING_ZERO, JSON_PARSE_ERROR_NUMBER_BAD_SYMBOL, JSON_PARSE_ERROR_NUMBER_DIGIT_END, JSON_PARSE_ERROR_ARRAY_START, JSON_PARSE_ERROR_ARRAY_END, JSON_PARSE_ERROR_ARRAY_COMMA, JSON_PARSE_ERROR_OBJECT_BAD_SYMBOL, JSON_PARSE_ERROR_OBJECT_START, JSON_PARSE_ERROR_OBJECT_END, JSON_PARSE_ERROR_OBJECT_COLON, JSON_PARSE_ERROR_OBJECT_COMMA, JSON_PARSE_ERROR_OBJECT_ARRAY_LVAL, JSON_PARSE_ERROR_OBJECT_OBJECT_LVAL, JSON_PARSE_ERROR_OBJECT_OPEN_LVAL, JSON_PARSE_ERROR_INVALID_START, JSON_PARSE_ERROR_INVALID_END, JSON_PARSE_ERROR_NO_LIBYAML, JSON_PARSE_ERROR_LIBYAML_FAILURE, JSON_PARSE_ERROR_NO_SUCH_FILE, JSON_PARSE_ERROR_NO_DATA, JSON_PARSE_ERROR_TRUNCATED, JSON_PARSE_ERROR_MAX } JsonParseError; typedef struct JsonElement_ JsonElement; typedef struct { const JsonElement *container; size_t index; } JsonIterator; ////////////////////////////////////////////////////////////////////////////// // String encoding (escaping) ////////////////////////////////////////////////////////////////////////////// char *JsonDecodeString(const char *escaped_string); char *JsonEncodeString(const char *const unescaped_string); typedef struct _Slice { // Slice is used to represent a section of memory which may or may not // contain NUL bytes. This is useful for storing the unescaped versions of // JSON(5) strings (which may have NUL bytes). void *data; // Binary data here, not just ascii plain text size_t size; // Allocated size in bytes (or shorter if you shrink later) } Slice; char *Json5EscapeData(Slice unescaped_data); // Not implemented yet: // Slice Json5UnescapeString(const char *escaped_string); ////////////////////////////////////////////////////////////////////////////// // Generic JSONElement functions ////////////////////////////////////////////////////////////////////////////// JsonElement *JsonCopy(const JsonElement *json); /** * @brief compare two JsonElement instances * * @param a JsonElement * @param b JsonElement * @return int like strcmp(), 0 is equal, non-zero is not equal */ int JsonCompare(const JsonElement *a, const JsonElement *b); JsonElement *JsonMerge(const JsonElement *a, const JsonElement *b); /** * @brief Recursively merge one object into another * * @param base Object to merge data into * @param extra Object to merge data from * @return Pointer to base object (convenient for nested function calls) * * @note The function should not return NULL * @warning Side effects: The base object is modified in place. If this is not * the intention, consider using JsonObjectMergeDeep */ JsonElement *JsonObjectMergeDeepInplace(JsonElement *base, const JsonElement *extra); /** * @brief Recursively merge two objects into a new object * * @param base Object to copy and merge data into * @param extra Object to merge data from * @return Pointer to merged object * * @note The function should not return NULL * @warning Performance penalty: A new object is created. If this is not the * intension, consider using JsonObjectMergeDeepInplace */ static inline JsonElement *JsonObjectMergeDeep(const JsonElement *const base, const JsonElement *const extra) { assert(base != NULL); /* This could do a little better job by constructing the JsonElement while * merging base and extra. Not sure if it's worth the extra complexity, * though. */ JsonElement *const copy = JsonCopy(base); return JsonObjectMergeDeepInplace(copy, extra); } /** @brief Destroy a JSON element @param element [in] The JSON element to destroy. */ void JsonDestroy(JsonElement *element); /** @brief Destroy a JSON element if needed @param element [in] The JSON element to destroy. @param allocated [in] Whether the element was allocated and needs to be destroyed. */ void JsonDestroyMaybe(JsonElement *element, bool allocated); /** @brief Get the length of a JsonElement. This is the number of elements or fields in an array or object respectively. @param element [in] The JSON element. */ size_t JsonLength(const JsonElement *element); JsonElementType JsonGetElementType(const JsonElement *element); JsonType JsonGetType(const JsonElement *element); const char *JsonElementGetPropertyName(const JsonElement *element); const char *JsonGetPropertyAsString(const JsonElement *element); #define NULL_JSON(json) ((json == NULL) || (JsonGetType(json) == JSON_TYPE_NULL)) #define JSON_NOT_NULL(json) ((json != NULL) && (JsonGetType(json) != JSON_TYPE_NULL)) ////////////////////////////////////////////////////////////////////////////// // JSON Primitives ////////////////////////////////////////////////////////////////////////////// const char *JsonContainerTypeToString(JsonContainerType type); const char *JsonPrimitiveTypeToString(JsonPrimitiveType type); JsonPrimitiveType JsonGetPrimitiveType(const JsonElement *primitive); const char *JsonPrimitiveGetAsString(const JsonElement *primitive); char *JsonPrimitiveToString(const JsonElement *primitive); bool JsonPrimitiveGetAsBool(const JsonElement *primitive); long JsonPrimitiveGetAsInteger(const JsonElement *primitive); int JsonPrimitiveGetAsInt64(const JsonElement *primitive, int64_t *value_out); int64_t JsonPrimitiveGetAsInt64DefaultOnError(const JsonElement *primitive, int64_t default_return); int64_t JsonPrimitiveGetAsInt64ExitOnError(const JsonElement *primitive); double JsonPrimitiveGetAsReal(const JsonElement *primitive); JsonElement *JsonStringCreate(const char *value); JsonElement *JsonIntegerCreate(int value); JsonElement *JsonIntegerCreate64(int64_t value); JsonElement *JsonRealCreate(double value); JsonElement *JsonBoolCreate(bool value); JsonElement *JsonNullCreate(); ////////////////////////////////////////////////////////////////////////////// // JSON Containers (array or object) ////////////////////////////////////////////////////////////////////////////// void JsonContainerReverse(JsonElement *array); typedef int JsonComparator( const JsonElement *, const JsonElement *, void *user_data); void JsonSort( const JsonElement *container, JsonComparator *Compare, void *user_data); JsonElement *JsonAt(const JsonElement *container, size_t index); JsonElement *JsonSelect( JsonElement *element, size_t num_indices, char **indices); JsonContainerType JsonGetContainerType(const JsonElement *container); ////////////////////////////////////////////////////////////////////////////// // JSON Object (dictionary) ////////////////////////////////////////////////////////////////////////////// /** @brief Create a new JSON object @param initial_capacity [in] The number of fields to preallocate space for. @returns A pointer to the created object. */ JsonElement *JsonObjectCreate(size_t initial_capacity); /** @brief Append a string field to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @param value [in] The value of the field. */ void JsonObjectAppendString( JsonElement *object, const char *key, const char *value); /** @brief Append an integer field to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @param value [in] The value of the field. */ void JsonObjectAppendInteger(JsonElement *object, const char *key, int value); /** @brief Append a 64-bit integer field to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @param value [in] The value of the field. */ void JsonObjectAppendInteger64(JsonElement *object, const char *key, int64_t value); /** @brief Append an real number field to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @param value [in] The value of the field. */ void JsonObjectAppendReal(JsonElement *object, const char *key, double value); /** @param object [in] The JSON object parent. @param key [in] the key of the field. @param value [in] The value of the field. */ void JsonObjectAppendBool(JsonElement *object, const char *key, _Bool value); /** @brief Append null field to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. */ void JsonObjectAppendNull(JsonElement *object, const char *key); /** @brief Append an array field to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @param value [in] The value of the field. */ void JsonObjectAppendArray( JsonElement *object, const char *key, JsonElement *array); /** @brief Append an object field to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @param value [in] The value of the field. */ void JsonObjectAppendObject( JsonElement *object, const char *key, JsonElement *childObject); /** @brief Append any JSON element to an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @param element [in] The element to append */ void JsonObjectAppendElement( JsonElement *object, const char *key, JsonElement *element); /** @brief Get the value of a field in an object, as a string. @param object [in] The JSON object parent. @param key [in] the key of the field. @returns A pointer to the string value, or NULL if non-existent. */ const char *JsonObjectGetAsString(const JsonElement *object, const char *key); /** @brief Get the value of a field in an object, as a boolean. @param object [in] The JSON object parent. @param key [in] the key of the field. @returns The boolean value for the key or false if key is not available */ bool JsonObjectGetAsBool(const JsonElement *const object, const char *key); /** @brief Get the value of a field in an object, as an object. @param object [in] The JSON object parent. @param key [in] the key of the field. @returns A pointer to the object value, or NULL if non-existent. */ JsonElement *JsonObjectGetAsObject(JsonElement *object, const char *key); /** @brief Get the value of a field in an object, as an array. @param object [in] The JSON object parent. @param key [in] the key of the field. @returns A pointer to the array value, or NULL if non-existent. */ JsonElement *JsonObjectGetAsArray(JsonElement *object, const char *key); JsonElement *JsonObjectGet(const JsonElement *object, const char *key); /** @brief Remove key from the object @param object containing the key property @param property name to be removed @return True if key was removed */ bool JsonObjectRemoveKey(JsonElement *object, const char *key); /** @brief Detach json element ownership from parent object; @param object containing the key property @param property name to be detached */ JsonElement *JsonObjectDetachKey(JsonElement *object, const char *key); ////////////////////////////////////////////////////////////////////////////// // JSON Array (list) ////////////////////////////////////////////////////////////////////////////// /** @brief Create a new JSON array @param initial_capacity [in] The number of fields to preallocate space for. @returns The pointer to the created array. */ JsonElement *JsonArrayCreate(size_t initialCapacity); /** @brief Append a string to an array. @param array [in] The JSON array parent. @param value [in] The string value to append. */ void JsonArrayAppendString(JsonElement *array, const char *value); void JsonArrayAppendBool(JsonElement *array, bool value); /** @brief Append an integer to an array. @param array [in] The JSON array parent. @param value [in] The integer value to append. */ void JsonArrayAppendInteger(JsonElement *array, int value); /** @brief Append an real to an array. @param array [in] The JSON array parent. @param value [in] The real value to append. */ void JsonArrayAppendReal(JsonElement *array, double value); /** @brief Append null to an array. @param array [in] The JSON array parent. */ void JsonArrayAppendNull(JsonElement *array); /** @brief Append an array to an array. @param array [in] The JSON array parent. @param child_array [in] The array value to append. */ void JsonArrayAppendArray(JsonElement *array, JsonElement *child_array); /** @brief Append an object to an array. @param array [in] The JSON array parent. @param object [in] The object value to append. */ void JsonArrayAppendObject(JsonElement *array, JsonElement *object); /** @brief Append any JSON element to an array. @param array [in] The JSON array parent. @param element [in] The object to append. */ void JsonArrayAppendElement(JsonElement *array, JsonElement *element); /** * @brief Move elements from JSON array `b` to JSON array `a`. * @param a [in] The JSON array to move elements to. * @param b [in] The JSON array to move elements from. * @note JSON array `a` takes ownership of elements in JSON array `b`. * JSON array `b` is freed from memory. */ void JsonArrayExtend(JsonElement *a, JsonElement *b); /** @brief Remove an inclusive range from a JSON array. @see SequenceRemoveRange @param array [in] The JSON array parent. @param start [in] Index of the first element to remove. @param end [in] Index of the last element to remove. */ void JsonArrayRemoveRange(JsonElement *array, size_t start, size_t end); /** @brief Get a string value from an array @param array [in] The JSON array parent @param index [in] Position of the value to get @returns A pointer to the string value, or NULL if non-existent. */ const char *JsonArrayGetAsString(JsonElement *array, size_t index); /** @brief Get an object value from an array @param array [in] The JSON array parent @param index [in] Position of the value to get @returns A pointer to the object value, or NULL if non-existent. */ JsonElement *JsonArrayGetAsObject(JsonElement *array, size_t index); JsonElement *JsonArrayGet(const JsonElement *array, size_t index); /** @brief Check if an array contains only primitives @param array [in] The JSON array parent @returns true if the array contains only primitives, false otherwise */ bool JsonArrayContainsOnlyPrimitives(JsonElement *array); ////////////////////////////////////////////////////////////////////////////// // JSON Iterator ////////////////////////////////////////////////////////////////////////////// JsonIterator JsonIteratorInit(const JsonElement *container); const char *JsonIteratorNextKey(JsonIterator *iter); JsonElement *JsonIteratorNextValue(JsonIterator *iter); JsonElement *JsonIteratorNextValueByType( JsonIterator *iter, JsonElementType type, bool skip_null); const char *JsonIteratorCurrentKey(const JsonIterator *iter); JsonElement *JsonIteratorCurrentValue(const JsonIterator *iter); JsonElementType JsonIteratorCurrentElementType(const JsonIterator *iter); JsonContainerType JsonIteratorCurrentContainerType(const JsonIterator *iter); JsonPrimitiveType JsonIteratorCurrentPrimitiveType(const JsonIterator *iter); bool JsonIteratorHasMore(const JsonIterator *iter); /** * @param element current element being visited * @param data arbitrary data passed to JsonWalk() * @return whether the recursive walk should continue or not */ typedef bool JsonElementVisitor(JsonElement *element, void *data); /** * Recursively walk over the JSON element. * * @param element JSON element to start with * @param object_visitor function to call on child objects * @param array_visitor function to call on child arrays * @param primitive_visitor function to call on child primitives * @param data arbitrary data passed to visitor functions * @return whether the recursive walk finished or was stopped (see #JsonElementVisitor) * * The function starts with the given JSON element #element and recursively * visits its child elements (if any), calling respective visitor functions on * each of the child elements. * * @note Each parent element is visited before its child elements. * @note Every element in the given JSON is visited unless one of the visitor functions returns * #false. * @note Every element is visited at most once. * @warning Modifications of the visited elements must be done with extreme caution and good * understanding of the implementation of the #JsonElement and #JsonIterator internals. */ bool JsonWalk(JsonElement *element, JsonElementVisitor object_visitor, JsonElementVisitor array_visitor, JsonElementVisitor primitive_visitor, void *data); /** * Visitor that just stops the walk on any element. * * Can be used as one of the visitor functions for JsonWalk() to detect * undesired child elements. */ bool JsonErrorVisitor(JsonElement *element, void *data); ////////////////////////////////////////////////////////////////////////////// // JSON Parsing ////////////////////////////////////////////////////////////////////////////// typedef JsonElement *JsonLookup(void *ctx, const char **data); /** @brief Parse a string to create a JsonElement @param data [in] Pointer to the string to parse @param json_out Resulting JSON object @returns See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParse(const char **data, JsonElement **json_out); /** @brief Parse the whole string to create a JsonElement @param data [in] Pointer to the string to parse @param json_out Resulting JSON object @note In contrast to JsonParse(), this function will return JSON_PARSE_ERROR_INVALID_END if there are trailing non-whitespace characters after termination of the JsonElement in the remainder of the string. @returns See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParseAll(const char **data, JsonElement **json_out); /** @brief Parse a string to create a JsonElement @param lookup_data [in] Evaluation context for variable lookups @param lookup_function [in] Callback function for variable lookups @param data [in] Pointer to the string to parse @param json_out Resulting JSON object @returns See JsonParseError and JsonParseErrorToString The lookup_context type is void so we don't have to include eval_context.h from libpromises into libutil */ JsonParseError JsonParseWithLookup( void *lookup_data, JsonLookup *lookup_function, const char **data, JsonElement **json_out); /** * @brief Convenience function to parse JSON or YAML from a file * @param path Path to the file * @param size_max Maximum size to read in memory * @param json_out Resulting JSON object * @param yaml_format Whether or not the file is in yaml format * @return See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParseAnyFile( const char *path, size_t size_max, JsonElement **json_out, bool yaml_format); /** * @brief Convenience function to parse JSON from a file. * @param path Path to the file * @param size_max Maximum size to read in memory * @param json_out Resulting JSON object * @return See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParseFile( const char *path, size_t size_max, JsonElement **json_out); const char *JsonParseErrorToString(JsonParseError error); ////////////////////////////////////////////////////////////////////////////// // JSON Serialization (Write) ////////////////////////////////////////////////////////////////////////////// /** @brief Pretty-print a JsonElement recursively into a Writer. If it's a JsonObject, its children will be sorted to produce canonical JSON output, but the object's contents are not modified so it's still a const. @see Writer @param writer [in] The Writer object to use as a buffer. @param element [in] The JSON element to print. @param indent_level [in] The nesting level with which the printing should be done. This is mainly to allow the function to be called recursively. Clients will normally want to set this to 0. */ void JsonWrite( Writer *writer, const JsonElement *element, size_t indent_level); void JsonWriteCompact(Writer *w, const JsonElement *element); void JsonEncodeStringWriter(const char *const unescaped_string, Writer *const writer); #endif cfengine-3.24.2/libntech/libutils/threaded_queue.c0000644000000000000000000004103615010704254022127 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #define EXPAND_FACTOR 2 #define DEFAULT_CAPACITY 16 /** @struct ThreadedQueue_ @brief An implementation of a thread safe queue based on a circular array Can enqueue, dequeue and give various statistics about its contents, like amount of elements, capacity and if it is empty. Has the ability to block if queue is empty, waiting for new elements to be queued. */ struct ThreadedQueue_ { pthread_mutex_t *lock; /**< Thread lock for accessing data. */ pthread_cond_t *cond_non_empty; /**< Blocking condition if empty */ pthread_cond_t *cond_empty; /**< Blocking condition if not empty */ void (*ItemDestroy) (void *item); /**< Data-specific destroy function. */ void **data; /**< Internal array of elements. */ size_t head; /**< Current position in queue. */ size_t tail; /**< Current end of queue. */ size_t size; /**< Current size of queue. */ size_t capacity; /**< Current memory allocated. */ }; static void DestroyRange(ThreadedQueue *queue, size_t start, size_t end); static void ExpandIfNecessary(ThreadedQueue *queue); ThreadedQueue *ThreadedQueueNew(size_t initial_capacity, void (ItemDestroy) (void *item)) { ThreadedQueue *queue = xcalloc(1, sizeof(ThreadedQueue)); if (initial_capacity == 0) { initial_capacity = DEFAULT_CAPACITY; } pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); // enables errorchecking for deadlocks int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to use error-checking mutexes for queue, " "falling back to normal ones (pthread_mutexattr_settype: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); } queue->lock = xmalloc(sizeof(pthread_mutex_t)); ret = pthread_mutex_init(queue->lock, &attr); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize mutex (pthread_mutex_init: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_destroy(&attr); free(queue->lock); free(queue); return NULL; } pthread_mutexattr_destroy(&attr); queue->cond_non_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(queue->cond_non_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition (pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(queue->lock); free(queue->cond_non_empty); free(queue); return NULL; } queue->cond_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(queue->cond_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition " "(pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(queue->lock); free(queue->cond_empty); free(queue->cond_non_empty); free(queue); return NULL; } queue->capacity = initial_capacity; queue->head = 0; queue->tail = 0; queue->size = 0; queue->data = xmalloc(sizeof(void *) * initial_capacity); queue->ItemDestroy = ItemDestroy; return queue; } void ThreadedQueueDestroy(ThreadedQueue *queue) { if (queue != NULL) { ThreadLock(queue->lock); DestroyRange(queue, queue->head, queue->tail); ThreadUnlock(queue->lock); ThreadedQueueSoftDestroy(queue); } } void ThreadedQueueSoftDestroy(ThreadedQueue *queue) { if (queue != NULL) { if (queue->lock != NULL) { pthread_mutex_destroy(queue->lock); free(queue->lock); } if (queue->cond_non_empty != NULL) { pthread_cond_destroy(queue->cond_non_empty); free(queue->cond_non_empty); } if (queue->cond_empty != NULL) { pthread_cond_destroy(queue->cond_empty); free(queue->cond_empty); } free(queue->data); free(queue); } } bool ThreadedQueuePop(ThreadedQueue *queue, void **item, int timeout) { assert(queue != NULL); ThreadLock(queue->lock); if (queue->size == 0 && timeout != 0) { int res = 0; do { res = ThreadWait(queue->cond_non_empty, queue->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(queue->lock); return false; } } while (queue->size == 0); // Reevaluate predicate to protect against spurious wakeups } bool ret = true; if (queue->size > 0) { size_t head = queue->head; *item = queue->data[head]; queue->data[head++] = NULL; head %= queue->capacity; queue->head = head; queue->size--; } else { ret = false; *item = NULL; } if (queue->size == 0) { // Signals that the queue is empty for ThreadedQueueWaitEmpty pthread_cond_broadcast(queue->cond_empty); } ThreadUnlock(queue->lock); return ret; } size_t ThreadedQueuePopN(ThreadedQueue *queue, void ***data_array, size_t num, int timeout) { assert(queue != NULL); ThreadLock(queue->lock); if (queue->size == 0 && timeout != 0) { int res = 0; do { res = ThreadWait(queue->cond_non_empty, queue->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(queue->lock); *data_array = NULL; return 0; } } while (queue->size == 0); // Reevaluate predicate to protect against spurious wakeups } size_t size = num < queue->size ? num : queue->size; void **data = NULL; if (size > 0) { data = xcalloc(size, sizeof(void *)); size_t head = queue->head; for (size_t i = 0; i < size; i++) { data[i] = queue->data[head]; queue->data[head++] = NULL; head %= queue->capacity; } queue->head = head; queue->size -= size; } if (queue->size == 0) { // Signals that the queue is empty for ThreadedQueueWaitEmpty pthread_cond_broadcast(queue->cond_empty); } *data_array = data; ThreadUnlock(queue->lock); return size; } size_t ThreadedQueuePopNIntoArray(ThreadedQueue *queue, void **data_array, size_t num, int timeout) { assert(queue != NULL); ThreadLock(queue->lock); if (queue->size == 0 && timeout != 0) { int res = 0; do { res = ThreadWait(queue->cond_non_empty, queue->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(queue->lock); return 0; } } while (queue->size == 0); // Reevaluate predicate to protect against spurious wakeups } size_t size = num < queue->size ? num : queue->size; if (size > 0) { size_t head = queue->head; for (size_t i = 0; i < size; i++) { data_array[i] = queue->data[head]; queue->data[head++] = NULL; head %= queue->capacity; } queue->head = head; queue->size -= size; } if (queue->size == 0) { // Signals that the queue is empty for ThreadedQueueWaitEmpty pthread_cond_broadcast(queue->cond_empty); } ThreadUnlock(queue->lock); return size; } size_t ThreadedQueuePush(ThreadedQueue *queue, void *item) { assert(queue != NULL); ThreadLock(queue->lock); ExpandIfNecessary(queue); queue->data[queue->tail++] = item; queue->size++; size_t const size = queue->size; pthread_cond_signal(queue->cond_non_empty); ThreadUnlock(queue->lock); return size; } size_t ThreadedQueuePushN(ThreadedQueue *queue, void **items, size_t n_items) { assert(queue != NULL); ThreadLock(queue->lock); for (size_t i = 0; i < n_items; i++) { /* This should be a no-op in most iterations of the loop. */ ExpandIfNecessary(queue); queue->data[queue->tail++] = items[i]; queue->size++; } size_t const size = queue->size; pthread_cond_signal(queue->cond_non_empty); ThreadUnlock(queue->lock); return size; } size_t ThreadedQueueCount(ThreadedQueue const *queue) { assert(queue != NULL); ThreadLock(queue->lock); size_t const count = queue->size; ThreadUnlock(queue->lock); return count; } size_t ThreadedQueueCapacity(ThreadedQueue const *queue) { assert(queue != NULL); ThreadLock(queue->lock); size_t const capacity = queue->capacity; ThreadUnlock(queue->lock); return capacity; } bool ThreadedQueueIsEmpty(ThreadedQueue const *queue) { assert(queue != NULL); ThreadLock(queue->lock); bool const empty = (queue->size == 0); ThreadUnlock(queue->lock); return empty; } bool ThreadedQueueWaitEmpty(ThreadedQueue const *queue, int timeout) { assert(queue != NULL); bool ret = true; ThreadLock(queue->lock); if (queue->size != 0) { if (timeout != 0) { int res = 0; do { res = ThreadWait(queue->cond_empty, queue->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(queue->lock); return false; } } while (queue->size != 0); // Reevaluate predicate to protect against spurious wakeups } else { ret = false; } } ThreadUnlock(queue->lock); return ret; } ThreadedQueue *ThreadedQueueCopy(ThreadedQueue *queue) { assert(queue != NULL); ThreadLock(queue->lock); ThreadedQueue *new_queue = xmemdup(queue, sizeof(ThreadedQueue)); new_queue->data = xmalloc(sizeof(void *) * queue->capacity); memcpy(new_queue->data, queue->data, sizeof(void *) * new_queue->capacity); ThreadUnlock(queue->lock); pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); // enables error checking for deadlocks int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to use error-checking mutexes for queue, " "falling back to normal ones (pthread_mutexattr_settype: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); } new_queue->lock = xmalloc(sizeof(pthread_mutex_t)); ret = pthread_mutex_init(new_queue->lock, &attr); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize mutex (pthread_mutex_init: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_destroy(&attr); free(new_queue->lock); free(new_queue); return NULL; } new_queue->cond_non_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(new_queue->cond_non_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition " "(pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(new_queue->lock); free(new_queue->cond_non_empty); free(new_queue); return NULL; } new_queue->cond_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(new_queue->cond_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition " "(pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(new_queue->lock); free(new_queue->cond_empty); free(new_queue->cond_non_empty); free(new_queue); return NULL; } return new_queue; } void ThreadedQueueClear(ThreadedQueue *queue) { assert(queue != NULL); ThreadLock(queue->lock); DestroyRange(queue, queue->head, queue->tail); assert(queue->size == 0); queue->head = 0; queue->tail = queue->head; pthread_cond_broadcast(queue->cond_empty); ThreadUnlock(queue->lock); } size_t ThreadedQueueClearAndPush(ThreadedQueue *queue, void *item) { assert(queue != NULL); ThreadLock(queue->lock); DestroyRange(queue, queue->head, queue->tail); queue->head = 0; queue->tail = queue->head; ExpandIfNecessary(queue); queue->data[queue->tail++] = item; queue->size++; size_t const size = queue->size; assert(queue->size == 1); pthread_cond_signal(queue->cond_non_empty); ThreadUnlock(queue->lock); return size; } /** @brief Destroys data in range. @warning Assumes that locks are acquired. @note If start == end, this means that all elements in queue will be destroyed. Since the internal array is circular, it will wrap around when reaching the array bounds. @param [in] queue Pointer to struct. @param [in] start Position to start destroying from. @param [in] end First position to not destroy. Can be same as start. */ static void DestroyRange(ThreadedQueue *queue, size_t start, size_t end) { assert(queue != NULL); if (start > queue->capacity || end > queue->capacity) { Log(LOG_LEVEL_DEBUG, "Failed to destroy ThreadedQueue, index greater than capacity: " "start = %zu, end = %zu, capacity = %zu", start, end, queue->capacity); return; } if (queue->size > 0) { if (queue->ItemDestroy != NULL) { queue->ItemDestroy(queue->data[start]); } queue->size--; // In case start == end, start at second element in range for (size_t i = start + 1; i != end; i++) { i %= queue->capacity; if (queue->ItemDestroy != NULL) { queue->ItemDestroy(queue->data[i]); } queue->size--; } } } /** @brief Either expands capacity of queue, or shifts tail to beginning. @warning Assumes that locks are acquired. @param [in] queue Pointer to struct. */ static void ExpandIfNecessary(ThreadedQueue *queue) { assert(queue != NULL); assert(queue->size <= queue->capacity); if (queue->size == queue->capacity) { if (queue->tail <= queue->head) { size_t old_capacity = queue->capacity; queue->capacity *= EXPAND_FACTOR; queue->data = xrealloc(queue->data, sizeof(void *) * queue->capacity); memmove(queue->data + old_capacity, queue->data, sizeof(void *) * queue->tail); queue->tail += old_capacity; } else { queue->capacity *= EXPAND_FACTOR; queue->data = xrealloc(queue->data, sizeof(void *) * queue->capacity); } } queue->tail %= queue->capacity; } cfengine-3.24.2/libntech/libutils/path.c0000644000000000000000000000475615010704254020107 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include const char *Path_Basename(const char *path) { assert(path != NULL); const char *filename = strrchr(path, '/'); if (filename != NULL) { filename += 1; } else { filename = path; } if (filename[0] == '\0') { return NULL; } return filename; } char *Path_JoinAlloc(const char *dir, const char *leaf) { if (StringEndsWith(dir, "/") #ifdef _WIN32 || StringEndsWith(dir, "\\") #endif // _WIN32 ) { return StringConcatenate(2, dir, leaf); } return StringConcatenate(3, dir, FILE_SEPARATOR_STR, leaf); } char *Path_GetQuoted(const char *path) { if (path == NULL) { return NULL; } size_t path_len = strlen(path); if ((path[0] == '"') && (path[path_len - 1] == '"')) { /* already quoted, just duplicate */ return SafeStringDuplicate(path); } bool needs_quoting = false; for (const char *cp = path; !needs_quoting && (*cp != '\0'); cp++) { /* let's quote everything that's not just alphanumerics, underscores and * dashes */ needs_quoting = !(((*cp >= 'a') && (*cp <= 'z')) || ((*cp >= 'A') && (*cp <= 'Z')) || ((*cp >= '0') && (*cp <= '9')) || (*cp == '_') || (*cp == '-') || IsFileSep(*cp)); } if (needs_quoting) { return StringConcatenate(3, "\"", path, "\""); } else { return SafeStringDuplicate(path); } } cfengine-3.24.2/libntech/libutils/mutex.h0000644000000000000000000000377515010704254020322 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MUTEX_H #define CFENGINE_MUTEX_H #include #define THREAD_BLOCK_INDEFINITELY -1 #define ThreadLock(m) __ThreadLock(m, __func__, __FILE__, __LINE__) #define ThreadUnlock(m) __ThreadUnlock(m, __func__, __FILE__, __LINE__) #define ThreadWait(m, n, t) __ThreadWait(m, n, t, __func__, __FILE__, __LINE__) void __ThreadLock(pthread_mutex_t *mutex, const char *funcname, const char *filename, int lineno); void __ThreadUnlock(pthread_mutex_t *mutex, const char *funcname, const char *filename, int lineno); /** @brief Function to wait for `timeout` seconds or until signalled. @note Can use THREAD_BLOCK_INDEFINITELY to block until a signal is received. @param [in] cond Thread condition to wait for. @param [in] mutex Mutex lock to acquire once condition is met. @param [in] timeout Seconds to wait for, can be THREAD_BLOCK_INDEFINITELY @return 0 on success, -1 if timed out, exits if locking fails */ int __ThreadWait(pthread_cond_t *cond, pthread_mutex_t *mutex, int timeout, const char *funcname, const char *filename, int lineno); #endif cfengine-3.24.2/libntech/libutils/refcount.h0000644000000000000000000000665315010704254021003 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_REFCOUNT_H #define CFENGINE_REFCOUNT_H #include /** @brief Simple reference count implementation. Reference counting helps to keep track of elements and avoid unnecessary duplication. In C we need to manually keep track of the users, while in C++ this is implicitly done by the "this" pointer. If we don't do that and we just count how many users we have, we risk multiples attach or detach. We need one way to find out who is connected to the refcount so we can act properly. */ struct RefCountNode { struct RefCountNode *next; struct RefCountNode *previous; void *user; }; typedef struct RefCountNode RefCountNode; struct RefCount { // Normally one unless we are shared. unsigned int user_count; RefCountNode *users; RefCountNode *last; }; typedef struct RefCount RefCount; /** @brief Initializes a refcount structure. @param ref RefCount structure to be initialized. */ void RefCountNew(RefCount **ref); /** @brief Destroys a refcount structure. @param ref RefCount structure to be destroyed. */ void RefCountDestroy(RefCount **ref); /** @brief Attaches a data structure to a given RefCount structure. Attaching refers to the fact that the container is using a data structure that might be shared by others. This should be called before using the data structure so everybody is aware of the new holder. @param ref RefCountr structure @param owner Data structure to be attached. */ void RefCountAttach(RefCount *ref, void *owner); /** @brief Detaches a data structure from a given RefCount structure. Detaching should be called after the container has copied the data structure. As long as the container is still using the data structure it should not detach from the reference counting. Otherwise this might lead to undesired side effects. @param ref RefCountr structure @param owner Data structure to be detached. */ void RefCountDetach(RefCount *ref, void *owner); /** @brief Simple check to see if a given data structure is shared. @param ref RefCount structure. @return True if shared, false otherwise. */ bool RefCountIsShared(RefCount *ref); /** @brief Compares two RefCount structures. @param a @param b @return True if a and b point to the same object, false otherwise. @remarks This function is needed in order to speed up comparisons of complex data structures. If the RefCount objects of the two structures are the same, then most likely the structures are the same. */ bool RefCountIsEqual(RefCount *a, RefCount *b); #endif // CFENGINE_REFCOUNT_H cfengine-3.24.2/libntech/libutils/queue.h0000644000000000000000000000242115010704254020267 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_QUEUE_H #define CFENGINE_QUEUE_H #include typedef struct Queue_ Queue; typedef void QueueItemDestroy(void *); Queue *QueueNew(QueueItemDestroy *item_destroy); void QueueDestroy(Queue *q); void QueueEnqueue(Queue *q, void *element); void *QueueDequeue(Queue *q); void *QueueHead(Queue *q); int QueueCount(const Queue *q); bool QueueIsEmpty(const Queue *q); #endif cfengine-3.24.2/libntech/libutils/threaded_deque.c0000644000000000000000000004177615010704254022121 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #define EXPAND_FACTOR 2 #define DEFAULT_CAPACITY 16 /** @struct ThreadedDeque_ @brief An implementation of a thread safe deque based on a circular array Can push left, push right and give various statistics about its contents, like amount of elements, capacity and if it is empty. Has the ability to block if deque is empty, waiting for new elements to be pushed. */ struct ThreadedDeque_ { pthread_mutex_t *lock; /**< Thread lock for accessing data. */ pthread_cond_t *cond_non_empty; /**< Blocking condition if empty */ pthread_cond_t *cond_empty; /**< Blocking condition if not empty */ void (*ItemDestroy) (void *item); /**< Data-specific destroy function. */ void **data; /**< Internal array of elements. */ size_t left; /**< Current position in deque. */ size_t right; /**< Current end of deque. */ size_t size; /**< Current size of deque. */ size_t capacity; /**< Current memory allocated. */ }; static void DestroyRange(ThreadedDeque *deque, size_t start, size_t end); static void ExpandIfNecessary(ThreadedDeque *deque); ThreadedDeque *ThreadedDequeNew(size_t initial_capacity, void (ItemDestroy) (void *item)) { ThreadedDeque *deque = xcalloc(1, sizeof(ThreadedDeque)); if (initial_capacity == 0) { initial_capacity = DEFAULT_CAPACITY; } pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); // enables errorchecking for deadlocks int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to use error-checking mutexes for deque, " "falling back to normal ones (pthread_mutexattr_settype: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); } deque->lock = xmalloc(sizeof(pthread_mutex_t)); ret = pthread_mutex_init(deque->lock, &attr); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize mutex (pthread_mutex_init: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_destroy(&attr); free(deque->lock); free(deque); return NULL; } pthread_mutexattr_destroy(&attr); deque->cond_non_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(deque->cond_non_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition (pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(deque->lock); free(deque->cond_non_empty); free(deque); return NULL; } deque->cond_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(deque->cond_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition " "(pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(deque->lock); free(deque->cond_empty); free(deque->cond_non_empty); free(deque); return NULL; } deque->capacity = initial_capacity; deque->left = 0; deque->right = 0; deque->size = 0; deque->data = xmalloc(sizeof(void *) * initial_capacity); deque->ItemDestroy = ItemDestroy; return deque; } void ThreadedDequeDestroy(ThreadedDeque *deque) { if (deque != NULL) { DestroyRange(deque, deque->left, deque->right); ThreadedDequeSoftDestroy(deque); } } void ThreadedDequeSoftDestroy(ThreadedDeque *deque) { if (deque != NULL) { if (deque->lock != NULL) { pthread_mutex_destroy(deque->lock); free(deque->lock); } if (deque->cond_non_empty != NULL) { pthread_cond_destroy(deque->cond_non_empty); free(deque->cond_non_empty); } if (deque->cond_empty != NULL) { pthread_cond_destroy(deque->cond_empty); free(deque->cond_empty); } free(deque->data); free(deque); } } bool ThreadedDequePopLeft(ThreadedDeque *deque, void **item, int timeout) { assert(deque != NULL); ThreadLock(deque->lock); if (deque->size == 0 && timeout != 0) { int res = 0; do { res = ThreadWait(deque->cond_non_empty, deque->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(deque->lock); return false; } } while (deque->size == 0); // Reevaluate predicate to protect against spurious wakeups } bool ret = true; if (deque->size > 0) { size_t left = deque->left; *item = deque->data[left]; deque->data[left++] = NULL; left %= deque->capacity; deque->left = left; deque->size--; } else { ret = false; *item = NULL; } if (deque->size == 0) { // Signals that the deque is empty for ThreadedDequeWaitEmpty pthread_cond_broadcast(deque->cond_empty); } ThreadUnlock(deque->lock); return ret; } bool ThreadedDequePopRight(ThreadedDeque *deque, void **item, int timeout) { assert(deque != NULL); ThreadLock(deque->lock); if (deque->size == 0 && timeout != 0) { int res = 0; do { res = ThreadWait(deque->cond_non_empty, deque->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(deque->lock); return false; } } while (deque->size == 0); // Reevaluate predicate to protect against spurious wakeups } bool ret = true; if (deque->size > 0) { size_t right = deque->right; right = right == 0 ? deque->capacity - 1 : right - 1; *item = deque->data[right]; deque->data[right] = NULL; deque->right = right; deque->size--; } else { ret = false; *item = NULL; } if (deque->size == 0) { // Signals that the deque is empty for ThreadedDequeWaitEmpty pthread_cond_broadcast(deque->cond_empty); } ThreadUnlock(deque->lock); return ret; } size_t ThreadedDequePopLeftN(ThreadedDeque *deque, void ***data_array, size_t num, int timeout) { assert(deque != NULL); ThreadLock(deque->lock); if (deque->size == 0 && timeout != 0) { int res = 0; do { res = ThreadWait(deque->cond_non_empty, deque->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(deque->lock); *data_array = NULL; return 0; } } while (deque->size == 0); // Reevaluate predicate to protect against spurious wakeups } size_t size = num < deque->size ? num : deque->size; void **data = NULL; if (size > 0) { data = xcalloc(size, sizeof(void *)); size_t left = deque->left; for (size_t i = 0; i < size; i++) { data[i] = deque->data[left]; deque->data[left++] = NULL; left %= deque->capacity; } deque->left = left; deque->size -= size; } if (deque->size == 0) { // Signals that the deque is empty for ThreadedDequeWaitEmpty pthread_cond_broadcast(deque->cond_empty); } *data_array = data; ThreadUnlock(deque->lock); return size; } size_t ThreadedDequePopRightN(ThreadedDeque *deque, void ***data_array, size_t num, int timeout) { assert(deque != NULL); ThreadLock(deque->lock); if (deque->size == 0 && timeout != 0) { int res = 0; do { res = ThreadWait(deque->cond_non_empty, deque->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(deque->lock); *data_array = NULL; return 0; } } while (deque->size == 0); // Reevaluate predicate to protect against spurious wakeups } size_t size = num < deque->size ? num : deque->size; void **data = NULL; if (size > 0) { data = xcalloc(size, sizeof(void *)); size_t right = deque->right; for (size_t i = 0; i < size; i++) { right = right == 0 ? deque->capacity - 1 : right - 1; data[i] = deque->data[right]; deque->data[right] = NULL; } deque->right = right; deque->size -= size; } if (deque->size == 0) { // Signals that the deque is empty for ThreadedDequeWaitEmpty pthread_cond_broadcast(deque->cond_empty); } *data_array = data; ThreadUnlock(deque->lock); return size; } size_t ThreadedDequePushLeft(ThreadedDeque *deque, void *item) { assert(deque != NULL); ThreadLock(deque->lock); ExpandIfNecessary(deque); deque->left = deque->left == 0 ? deque->capacity - 1 : deque->left - 1; deque->data[deque->left] = item; deque->size++; size_t const size = deque->size; pthread_cond_signal(deque->cond_non_empty); ThreadUnlock(deque->lock); return size; } size_t ThreadedDequePushRight(ThreadedDeque *deque, void *item) { assert(deque != NULL); ThreadLock(deque->lock); ExpandIfNecessary(deque); deque->data[deque->right++] = item; deque->right %= deque->capacity; deque->size++; size_t const size = deque->size; pthread_cond_signal(deque->cond_non_empty); ThreadUnlock(deque->lock); return size; } size_t ThreadedDequeCount(ThreadedDeque const *deque) { assert(deque != NULL); ThreadLock(deque->lock); size_t const count = deque->size; ThreadUnlock(deque->lock); return count; } size_t ThreadedDequeCapacity(ThreadedDeque const *deque) { assert(deque != NULL); ThreadLock(deque->lock); size_t const capacity = deque->capacity; ThreadUnlock(deque->lock); return capacity; } bool ThreadedDequeIsEmpty(ThreadedDeque const *deque) { assert(deque != NULL); ThreadLock(deque->lock); bool const empty = (deque->size == 0); ThreadUnlock(deque->lock); return empty; } bool ThreadedDequeWaitEmpty(ThreadedDeque const *deque, int timeout) { assert(deque != NULL); ThreadLock(deque->lock); if (deque->size == 0) { ThreadUnlock(deque->lock); return true; } if (timeout == 0) { ThreadUnlock(deque->lock); return false; } do { int res = ThreadWait(deque->cond_empty, deque->lock, timeout); if (res != 0) { /* Lock is reacquired even when timed out, so it needs to be released again. */ ThreadUnlock(deque->lock); return false; } // Reevaluate predicate to protect against spurious wakeups } while (deque->size != 0); ThreadUnlock(deque->lock); return true; } ThreadedDeque *ThreadedDequeCopy(ThreadedDeque *deque) { assert(deque != NULL); ThreadLock(deque->lock); ThreadedDeque *new_deque = xmemdup(deque, sizeof(ThreadedDeque)); new_deque->data = xmalloc(sizeof(void *) * deque->capacity); memcpy(new_deque->data, deque->data, sizeof(void *) * new_deque->capacity); ThreadUnlock(deque->lock); pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); // enables error checking for deadlocks int ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to use error-checking mutexes for deque, " "falling back to normal ones (pthread_mutexattr_settype: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); } new_deque->lock = xmalloc(sizeof(pthread_mutex_t)); ret = pthread_mutex_init(new_deque->lock, &attr); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize mutex (pthread_mutex_init: %s)", GetErrorStrFromCode(ret)); pthread_mutexattr_destroy(&attr); free(new_deque->lock); free(new_deque); return NULL; } new_deque->cond_non_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(new_deque->cond_non_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition " "(pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(new_deque->lock); free(new_deque->cond_non_empty); free(new_deque); return NULL; } new_deque->cond_empty = xmalloc(sizeof(pthread_cond_t)); ret = pthread_cond_init(new_deque->cond_empty, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to initialize thread condition " "(pthread_cond_init: %s)", GetErrorStrFromCode(ret)); free(new_deque->lock); free(new_deque->cond_empty); free(new_deque->cond_non_empty); free(new_deque); return NULL; } return new_deque; } /** @brief Destroys data in range. @warning Assumes that locks are acquired. @note If start == end, this means that all elements in deque will be destroyed. Since the internal array is circular, it will wrap around when reaching the array bounds. @param [in] deque Pointer to struct. @param [in] start Position to start destroying from. @param [in] end First position to not destroy. Can be same as start to destroy the entire allocated area. */ static void DestroyRange(ThreadedDeque *deque, size_t start, size_t end) { assert(deque != NULL); if (start > deque->capacity || end > deque->capacity) { Log(LOG_LEVEL_DEBUG, "Failed to destroy ThreadedDeque, index greater than capacity: " "start = %zu, end = %zu, capacity = %zu", start, end, deque->capacity); return; } if ((deque->ItemDestroy != NULL) && deque->size > 0) { do { deque->ItemDestroy(deque->data[start]); start++; start %= deque->capacity; } while (start != end); } } /** @brief Either expands capacity of deque, or shifts tail to beginning. @warning Assumes that locks are acquired. @param [in] deque Pointer to struct. */ static void ExpandIfNecessary(ThreadedDeque *deque) { assert(deque != NULL); assert(deque->size <= deque->capacity); if (deque->size == deque->capacity) { if (deque->right <= deque->left) { size_t old_capacity = deque->capacity; deque->capacity *= EXPAND_FACTOR; deque->data = xrealloc(deque->data, sizeof(void *) * deque->capacity); /* Move the data that has wrapped around to the newly allocated * part of the deque, since we need a continuous block of memory. * Offset of new placement is `old_capacity`. */ memmove(deque->data + old_capacity, deque->data, sizeof(void *) * deque->right); deque->right += old_capacity; } else { deque->capacity *= EXPAND_FACTOR; deque->data = xrealloc(deque->data, sizeof(void *) * deque->capacity); } } } cfengine-3.24.2/libntech/libutils/mustache.c0000644000000000000000000006726715010704254020772 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include typedef enum { TAG_TYPE_VAR, TAG_TYPE_VAR_UNESCAPED, TAG_TYPE_VAR_SERIALIZED, TAG_TYPE_VAR_SERIALIZED_COMPACT, TAG_TYPE_SECTION, TAG_TYPE_SECTION_END, TAG_TYPE_INVERTED, TAG_TYPE_COMMENT, TAG_TYPE_DELIM, TAG_TYPE_ERR, TAG_TYPE_NONE } TagType; typedef struct { TagType type; const char *begin; const char *end; const char *content; size_t content_len; } Mustache; #define MUSTACHE_MAX_DELIM_SIZE 10 static bool IsSpace(char c) { return c == '\t' || c == ' '; } static bool IsTagStandalone(const char *start, const char *tag_start, const char *tag_end, const char **line_begin, const char **line_end) { assert(start != NULL); assert(tag_start != NULL); assert(tag_end != NULL); assert(line_begin != NULL); assert(line_end != NULL); assert(start <= tag_start); *line_begin = start; for (const char *cur = tag_start - 1; cur >= start; cur--) { if (IsSpace(*cur)) { *line_begin = cur; if (cur == start) { break; } continue; } else if (*cur == '\n') { *line_begin = cur + 1; break; } else { return false; } } *line_end = NULL; for (const char *cur = tag_end; true; cur++) { if (IsSpace(*cur)) { continue; } else if (*cur == '\n') { *line_end = cur + 1; break; } else if (*cur == '\r') { if (*(cur + 1) == '\n') { *line_end = cur + 2; break; } continue; } else if (*cur == '\0') { *line_end = cur; break; } else { return false; } } assert(*line_end); return true; } static bool IsTagTypeRenderable(TagType type) { switch (type) { case TAG_TYPE_COMMENT: case TAG_TYPE_DELIM: case TAG_TYPE_ERR: case TAG_TYPE_INVERTED: case TAG_TYPE_SECTION: case TAG_TYPE_SECTION_END: return false; default: return true; } } static JsonElement *LookupVariable(Seq *hash_stack, const char *name, size_t name_len) { assert(SeqLength(hash_stack) > 0); size_t num_comps = StringCountTokens(name, name_len, "."); JsonElement *base_var = NULL; { StringRef base_comp = StringGetToken(name, name_len, 0, "."); char *base_comp_str = xstrndup(base_comp.data, base_comp.len); if (strcmp("-top-", base_comp_str) == 0) { base_var = SeqAt(hash_stack, 0); } for (ssize_t i = SeqLength(hash_stack) - 1; i >= 0; i--) { JsonElement *hash = SeqAt(hash_stack, i); if (!hash) { continue; } if (JsonGetType(hash) == JSON_TYPE_OBJECT) { JsonElement *var = JsonObjectGet(hash, base_comp_str); if (var) { base_var = var; break; } } } free(base_comp_str); } if (!base_var) { return NULL; } for (size_t i = 1; i < num_comps; i++) { if (JsonGetType(base_var) != JSON_TYPE_OBJECT) { return NULL; } StringRef comp = StringGetToken(name, name_len, i, "."); char *comp_str = xstrndup(comp.data, comp.len); base_var = JsonObjectGet(base_var, comp_str); free(comp_str); if (!base_var) { return NULL; } } assert(base_var); return base_var; } static Mustache NextTag(const char *input, const char *delim_start, size_t delim_start_len, const char *delim_end, size_t delim_end_len) { Mustache ret = {0}; ret.type = TAG_TYPE_NONE; ret.begin = strstr(input, delim_start); if (!ret.begin) { return ret; } ret.content = ret.begin + delim_start_len; char *extra_end = NULL; switch (ret.content[0]) { case '#': ret.type = TAG_TYPE_SECTION; ret.content++; break; case '^': ret.type = TAG_TYPE_INVERTED; ret.content++; break; case '/': ret.type = TAG_TYPE_SECTION_END; ret.content++; break; case '!': ret.type = TAG_TYPE_COMMENT; ret.content++; break; case '=': extra_end = "="; ret.type = TAG_TYPE_DELIM; ret.content++; break; case '{': extra_end = "}"; // fall through case '&': ret.type = TAG_TYPE_VAR_UNESCAPED; ret.content++; break; case '%': ret.type = TAG_TYPE_VAR_SERIALIZED; ret.content++; break; case '$': ret.type = TAG_TYPE_VAR_SERIALIZED_COMPACT; ret.content++; break; default: ret.type = TAG_TYPE_VAR; break; } if (extra_end) { const char *escape_end = strstr(ret.content, extra_end); if (!escape_end || strncmp(escape_end + 1, delim_end, delim_end_len) != 0) { Log(LOG_LEVEL_ERR, "Broken mustache template, couldn't find end tag for quoted begin tag at '%20s'...", input); ret.type = TAG_TYPE_ERR; return ret; } ret.content_len = escape_end - ret.content; ret.end = escape_end + 1 + delim_end_len; } else { ret.end = strstr(ret.content, delim_end); if (!ret.end) { Log(LOG_LEVEL_ERR, "Broken Mustache template, could not find end delimiter after reading start delimiter at '%20s'...", input); ret.type = TAG_TYPE_ERR; return ret; } ret.content_len = ret.end - ret.content; ret.end += delim_end_len; } while (*ret.content == ' ' || *ret.content == '\t') { ret.content++; ret.content_len--; } while (ret.content_len > 0 && (ret.content[ret.content_len - 1] == ' ' || ret.content[ret.content_len - 1] == '\t')) { ret.content_len--; } return ret; } static void RenderHTMLContent(Buffer *out, const char *input, size_t len) { for (size_t i = 0; i < len; i++) { switch (input[i]) { case '&': BufferAppendString(out, "&"); break; case '"': BufferAppendString(out, """); break; case '<': BufferAppendString(out, "<"); break; case '>': BufferAppendString(out, ">"); break; default: BufferAppendChar(out, input[i]); break; } } } static void RenderContent(Buffer *out, const char *content, size_t len, bool html, bool skip_content) { if (skip_content) { return; } if (html) { RenderHTMLContent(out, content, len); } else { BufferAppend(out, content, len); } } static bool RenderVariablePrimitive(Buffer *out, const JsonElement *primitive, const bool escaped, const char* json_key) { if (json_key != NULL) { if (escaped) { RenderHTMLContent(out, json_key, strlen(json_key)); } else { BufferAppendString(out, json_key); } return true; } switch (JsonGetPrimitiveType(primitive)) { case JSON_PRIMITIVE_TYPE_STRING: if (escaped) { RenderHTMLContent(out, JsonPrimitiveGetAsString(primitive), strlen(JsonPrimitiveGetAsString(primitive))); } else { BufferAppendString(out, JsonPrimitiveGetAsString(primitive)); } return true; case JSON_PRIMITIVE_TYPE_INTEGER: { char *str = StringFromLong(JsonPrimitiveGetAsInteger(primitive)); BufferAppendString(out, str); free(str); } return true; case JSON_PRIMITIVE_TYPE_REAL: { char *str = StringFromDouble(JsonPrimitiveGetAsReal(primitive)); BufferAppendString(out, str); free(str); } return true; case JSON_PRIMITIVE_TYPE_BOOL: BufferAppendString(out, JsonPrimitiveGetAsBool(primitive) ? "true" : "false"); return true; case JSON_PRIMITIVE_TYPE_NULL: return true; default: assert(!"Unrecognised JSON primitive type"); } return false; } static bool RenderVariableContainer(Buffer *out, const JsonElement *container, bool compact) { Writer *w = StringWriter(); if (compact) { JsonWriteCompact(w, container); } else { JsonWrite(w, container, 0); } BufferAppendString(out, StringWriterData(w)); WriterClose(w); return true; } static bool RenderVariable(Buffer *out, const char *content, size_t content_len, TagType conversion, Seq *hash_stack, const char *json_key) { JsonElement *var = NULL; bool escape = conversion == TAG_TYPE_VAR; bool serialize = conversion == TAG_TYPE_VAR_SERIALIZED; bool serialize_compact = conversion == TAG_TYPE_VAR_SERIALIZED_COMPACT; const bool item_mode = strncmp(content, ".", content_len) == 0; const bool key_mode = strncmp(content, "@", content_len) == 0; if (item_mode || key_mode) { var = SeqAt(hash_stack, SeqLength(hash_stack) - 1); // Leave this in, it's really useful when debugging here but useless otherwise // for (int i=1; i < SeqLength(hash_stack); i++) // { // JsonElement *dump = SeqAt(hash_stack, i); // Writer *w = StringWriter(); // JsonWrite(w, dump, 0); // Log(LOG_LEVEL_ERR, "RenderVariable: at hash_stack position %d, we found var '%s'", i, StringWriterClose(w)); // } } else { var = LookupVariable(hash_stack, content, content_len); } if (key_mode && json_key == NULL) { Log(LOG_LEVEL_WARNING, "RenderVariable: {{@}} Mustache tag must be used in a context where there's a valid key or iteration position"); return false; } if (!var) { return true; } switch (JsonGetElementType(var)) { case JSON_ELEMENT_TYPE_PRIMITIVE: // note that this also covers 'serialize' on primitives return RenderVariablePrimitive(out, var, escape, key_mode ? json_key : NULL); case JSON_ELEMENT_TYPE_CONTAINER: if (serialize || serialize_compact) { return RenderVariableContainer(out, var, serialize_compact); } else if (key_mode) { // this will only use the JSON key property, which we know is good // because we return false earlier otherwise return RenderVariablePrimitive(out, var, escape, json_key); } else if (item_mode) { // This can happen in 2 cases: // if you try to use {{.}} on the top element (without iterating) // if you try to use {{.}} while iterating and the current element is a container // In both cases we want to give an error(warning) since this is not clear in the // mustache spec Log(LOG_LEVEL_WARNING, "{{.}} mustache tag cannot expand a container without specifying conversion" " - consider {{$.}} or {{%%.}}"); return false; } } assert(false); return false; } static bool SetDelimiters(const char *content, size_t content_len, char *delim_start, size_t *delim_start_len, char *delim_end, size_t *delim_end_len) { size_t num_tokens = StringCountTokens(content, content_len, " \t"); if (num_tokens != 2) { Log(LOG_LEVEL_WARNING, "Could not parse delimiter mustache, number of tokens is %zu, expected 2 in '%s'", num_tokens, content); return false; } StringRef first = StringGetToken(content, content_len, 0, " \t"); if (first.len > MUSTACHE_MAX_DELIM_SIZE) { Log(LOG_LEVEL_WARNING, "New mustache start delimiter exceeds the allowed size of %d in '%s'", MUSTACHE_MAX_DELIM_SIZE, content); return false; } strncpy(delim_start, first.data, first.len); delim_start[first.len] = '\0'; *delim_start_len = first.len; StringRef second = StringGetToken(content, content_len, 1, " \t"); if (second.len > MUSTACHE_MAX_DELIM_SIZE) { Log(LOG_LEVEL_WARNING, "New mustache start delimiter exceeds the allowed size of %d in '%s'", MUSTACHE_MAX_DELIM_SIZE, content); return false; } strncpy(delim_end, second.data, second.len); delim_end[second.len] = '\0'; *delim_end_len = second.len; return true; } static bool IsKeyExtensionVar(TagType tag_type, const char *tag_start, char *delim_start, size_t delim_start_len, char *delim_end, size_t delim_end_len) { /* This whole function is ugly, but tries to avoid memory allocation and copying. */ /* the easiest case first: {{@}} */ if (tag_type == TAG_TYPE_VAR) { if (StringStartsWith(tag_start, delim_start) && *(tag_start + delim_start_len) == '@' && StringStartsWith(tag_start + delim_start_len + 1, delim_end)) { return true; } else { /* no other way a VAR could be {{@}} */ return false; } } if (tag_type == TAG_TYPE_VAR_UNESCAPED) { /* the case with unescaped form using &: {{&@}} */ if (StringStartsWith(tag_start, delim_start) && StringStartsWith(tag_start + delim_start_len, "&@") && StringStartsWith(tag_start + delim_start_len + 2, delim_end)) { return true; } /* the special case of unescaped form using {{{@}}} iff "{{" and "}}" are * used as delimiters */ if ((delim_start_len == 2) && (delim_end_len == 2) && StringEqual(delim_start, "{{") && StringEqual(delim_end, "}}") && StringStartsWith(tag_start, "{{{@}}}")) { return true; } } /* nothing else is our special '@' variable inside delimiters */ return false; } /** * Checks if a Json object in the current context (specified by #input) should * be iterated over or not. * * We need to iterate over a Json object if the current section directly * contains (not in a subsection) our {{@}} mustache extension. */ static bool ShouldIterateObject(const char *input, char *delim_start, size_t delim_start_len, char *delim_end, size_t delim_end_len) { assert (input != NULL); size_t loc_delim_start_len = delim_start_len; char loc_delim_start[MUSTACHE_MAX_DELIM_SIZE] = {0}; strncpy(loc_delim_start, delim_start, delim_start_len); size_t loc_delim_end_len = delim_end_len; char loc_delim_end[MUSTACHE_MAX_DELIM_SIZE] = {0}; strncpy(loc_delim_end, delim_end, delim_end_len); /* This loop should only terminate when the answer is clear and thus the * whole function returns. It's iterating over the template which has to end * somewhere (if it's not NUL-terminated, we have a much bigger issue than * this loop). */ while (true) { Mustache tag = NextTag(input, loc_delim_start, loc_delim_start_len, loc_delim_end, loc_delim_end_len); switch (tag.type) { case TAG_TYPE_ERR: case TAG_TYPE_NONE: case TAG_TYPE_SECTION: case TAG_TYPE_SECTION_END: /* these clearly mean there cannot be {{@}} directly in the current section */ return false; case TAG_TYPE_VAR: case TAG_TYPE_VAR_UNESCAPED: /* check if the variable is {{@}} respecting possibly changed delimiters */ if (IsKeyExtensionVar(tag.type, tag.begin, loc_delim_start, loc_delim_start_len, loc_delim_end, loc_delim_end_len)) { return true; } else { /* just continue to the next tag */ break; } case TAG_TYPE_DELIM: if (!SetDelimiters(tag.content, tag.content_len, loc_delim_start, &loc_delim_start_len, loc_delim_end, &loc_delim_end_len)) { return false; } break; default: /* just continue to the next tag */ break; } /* move on in the template */ input = tag.end; } return false; } static bool Render(Buffer *out, const char *start, const char *input, Seq *hash_stack, const char *json_key, char *delim_start, size_t *delim_start_len, char *delim_end, size_t *delim_end_len, bool skip_content, const char *section, const char **section_end) { while (true) { if (!input) { Log(LOG_LEVEL_ERR, "Unexpected end to Mustache template"); return false; } Mustache tag = NextTag(input, delim_start, *delim_start_len, delim_end, *delim_end_len); { const char *line_begin = NULL; const char *line_end = NULL; if (!IsTagTypeRenderable(tag.type) && tag.end != NULL && IsTagStandalone(start, tag.begin, tag.end, &line_begin, &line_end)) { RenderContent(out, input, line_begin - input, false, skip_content); input = line_end; } else { RenderContent(out, input, tag.begin - input, false, skip_content); input = tag.end; } } switch (tag.type) { case TAG_TYPE_ERR: return false; case TAG_TYPE_DELIM: if (!SetDelimiters(tag.content, tag.content_len, delim_start, delim_start_len, delim_end, delim_end_len)) { return false; } continue; case TAG_TYPE_COMMENT: continue; case TAG_TYPE_NONE: return true; case TAG_TYPE_VAR_SERIALIZED: case TAG_TYPE_VAR_SERIALIZED_COMPACT: case TAG_TYPE_VAR_UNESCAPED: case TAG_TYPE_VAR: if (!skip_content) { if (tag.content_len > 0) { if (!RenderVariable(out, tag.content, tag.content_len, tag.type, hash_stack, json_key)) { return false; } } else { RenderContent(out, delim_start, *delim_start_len, false, false); RenderContent(out, delim_end, *delim_end_len, false, false); } } continue; case TAG_TYPE_INVERTED: case TAG_TYPE_SECTION: { char *cur_section = xstrndup(tag.content, tag.content_len); JsonElement *var = LookupVariable(hash_stack, tag.content, tag.content_len); SeqAppend(hash_stack, var); if (!var) { /* XXX: no variable with the name of the section, why are we renderning anything? */ const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, NULL, delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type != TAG_TYPE_INVERTED, cur_section, &cur_section_end)) { free(cur_section); return false; } free(cur_section); input = cur_section_end; continue; } switch (JsonGetElementType(var)) { case JSON_ELEMENT_TYPE_PRIMITIVE: if (JsonGetPrimitiveType(var) == JSON_PRIMITIVE_TYPE_BOOL) { bool skip = skip_content || (!JsonPrimitiveGetAsBool(var) ^ (tag.type == TAG_TYPE_INVERTED)); const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, NULL, delim_start, delim_start_len, delim_end, delim_end_len, skip, cur_section, &cur_section_end)) { free(cur_section); return false; } free(cur_section); input = cur_section_end; continue; } else { Log(LOG_LEVEL_WARNING, "Mustache sections can only take a boolean or a container (array or map) value, but section '%s' isn't getting one of those.", cur_section); free(cur_section); return false; } break; case JSON_ELEMENT_TYPE_CONTAINER: switch (JsonGetContainerType(var)) { case JSON_CONTAINER_TYPE_OBJECT: { if (!ShouldIterateObject(input, delim_start, *delim_start_len, delim_end, *delim_end_len)) { const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, NULL, delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type == TAG_TYPE_INVERTED, cur_section, &cur_section_end)) { free(cur_section); return false; } input = cur_section_end; free(cur_section); break; } } /* fall through */ /* Because iterated objects and arrays are processed in the * same way */ case JSON_CONTAINER_TYPE_ARRAY: if (JsonLength(var) > 0) { const char *cur_section_end = NULL; for (size_t i = 0; i < JsonLength(var); i++) { JsonElement *child_hash = JsonAt(var, i); SeqAppend(hash_stack, child_hash); Buffer *kstring = BufferNew(); if (JSON_CONTAINER_TYPE_OBJECT == JsonGetContainerType(var)) { BufferAppendString(kstring, JsonElementGetPropertyName(child_hash)); } else { BufferAppendF(kstring, "%zu", i); } if (!Render(out, start, input, hash_stack, BufferData(kstring), delim_start, delim_start_len, delim_end, delim_end_len, skip_content || tag.type == TAG_TYPE_INVERTED, cur_section, &cur_section_end)) { free(cur_section); BufferDestroy(kstring); return false; } BufferDestroy(kstring); } input = cur_section_end; free(cur_section); } else { /* XXX: empty array -- why are we rendering anything? */ const char *cur_section_end = NULL; if (!Render(out, start, input, hash_stack, NULL, delim_start, delim_start_len, delim_end, delim_end_len, tag.type != TAG_TYPE_INVERTED, cur_section, &cur_section_end)) { free(cur_section); return false; } free(cur_section); input = cur_section_end; } break; } break; } } continue; case TAG_TYPE_SECTION_END: if (!section) { char *varname = xstrndup(tag.content, tag.content_len); Log(LOG_LEVEL_WARNING, "Unknown section close in mustache template '%s'", varname); free(varname); return false; } else { SeqRemove(hash_stack, SeqLength(hash_stack) - 1); *section_end = input; return true; } break; default: assert(false); return false; } } assert(false); } bool MustacheRender(Buffer *out, const char *input, const JsonElement *hash) { char delim_start[MUSTACHE_MAX_DELIM_SIZE] = "{{"; size_t delim_start_len = strlen(delim_start); char delim_end[MUSTACHE_MAX_DELIM_SIZE] = "}}"; size_t delim_end_len = strlen(delim_end); Seq *hash_stack = SeqNew(10, NULL); SeqAppend(hash_stack, (JsonElement*)hash); bool success = Render(out, input, input, hash_stack, NULL, delim_start, &delim_start_len, delim_end, &delim_end_len, false, NULL, NULL); SeqDestroy(hash_stack); return success; } cfengine-3.24.2/libntech/libutils/json-utils.h0000644000000000000000000000340015010704254021250 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_JSON_UTILS_H #define CFENGINE_JSON_UTILS_H #include typedef enum { DATAFILETYPE_UNKNOWN = 0, DATAFILETYPE_JSON, DATAFILETYPE_YAML, DATAFILETYPE_ENV, DATAFILETYPE_CSV } DataFileType; void ParseEnvLine(char *raw_line, char **key_out, char **value_out, const char *filename_for_log, int linenumber); bool JsonParseEnvFile(const char *input_path, size_t size_max, JsonElement **json_out); bool JsonParseCsvFile(const char *path, size_t size_max, JsonElement **json_out); JsonElement *JsonReadDataFile( const char *log_identifier, const char *input_path, DataFileType requested_mode, size_t size_max); DataFileType GetDataFileTypeFromString(const char *requested_mode); DataFileType GetDataFileTypeFromSuffix(const char *filename); const char *DataFileTypeToString(DataFileType type); #endif // CFENGINE_JSON_UTILS_H cfengine-3.24.2/libntech/libutils/writer.h0000644000000000000000000000572515010704321020464 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_WRITER_H #define CFENGINE_WRITER_H /* * Abstract "writer". * * Writes passed data either to * passed FILE*, or * memory buffer */ typedef struct Writer_ Writer; #include // FILE #include // bool #include // va_list #include /* Set by ./configure allowing us to avoid #include here. */ #define HAVE_GETOPT_H 1 #ifdef HAVE_GETOPT_H #include #else #ifndef _GETOPT_H /* in case something included it from somewhere anyway */ /* We actually only need the 'struct option' type from the header here so just * defined it ourselves if we cannot get it from the header. */ struct option { const char *name; int has_arg; int *flag; int val; }; #endif /* _GETOPT_H */ #endif /* HAVE_GETOPT_H */ Writer *FileWriter(FILE *); Writer *StringWriter(void); size_t WriterWriteF(Writer *writer, const char *fmt, ...) FUNC_ATTR_PRINTF(2, 3); size_t WriterWriteVF(Writer *writer, const char *fmt, va_list ap) FUNC_ATTR_PRINTF(2, 0); size_t WriterWrite(Writer *writer, const char *str); size_t WriterWriteLen(Writer *writer, const char *str, size_t len); size_t WriterWriteChar(Writer *writer, char c); size_t StringWriterLength(const Writer *writer); const char *StringWriterData(const Writer *writer); void WriterClose(Writer *writer); /* Returns modifiable string and destroys itself */ char *StringWriterClose(Writer *writer) FUNC_WARN_UNUSED_RESULT; /* Returns the open file and destroys itself */ FILE *FileWriterDetach(Writer *writer); /* Commonly used on a FileWriter(stdout), ignoring return; so don't * try to warn on unused result ! */ typedef struct { const char *name; const char *description; const char *usage; } Description; typedef struct { const char *name; const char *website; const char *copyright; } Component; void WriterWriteHelp(Writer *w, const Component *component, const struct option options[], const char *const hints[], const Description *commands, bool command_first, bool accepts_file_argument); #endif cfengine-3.24.2/libntech/libutils/deprecated.h0000644000000000000000000000275615010704254021256 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DEPRECATED_H #define CFENGINE_DEPRECATED_H #include #include /* Mark specific functions as deprecated so that we don't use them. Since the * signature of the functions has to be exactly the same as in libc, we only * do that for Linux, where main development happens. */ #if defined(__linux__) && defined(__GLIBC__) && (!defined(_FORTIFY_SOURCE) || (_FORTIFY_SOURCE < 1)) int sprintf(char *str, const char *format, ...) \ FUNC_DEPRECATED("Try snprintf() or xsnprintf() or xasprintf()"); #endif /* __linux__ && __GLIBC__ */ #endif /* CFENGINE_DEPRECATED_H */ cfengine-3.24.2/libntech/libutils/queue.c0000644000000000000000000000606415010704254020271 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include typedef struct QueueNode_ { void *data; /*!< Pointer to the stored element */ struct QueueNode_ *next; /*!< Next element in the queue or NULL */ struct QueueNode_ *previous; /*!< Pointer to the previous element or NULL */ } QueueNode; struct Queue_ { size_t node_count; /*!< Number of elements in the queue */ QueueItemDestroy *destroy; QueueNode *head; /*!< Pointer to the start of the queue */ QueueNode *tail; /*!< Pointer to the end of the queue */ }; Queue *QueueNew(QueueItemDestroy *item_destroy) { Queue *queue = xcalloc(1, sizeof(Queue)); queue->destroy = item_destroy; return queue; } void QueueDestroy(Queue *q) { if (q) { QueueNode *current = q->head; while (current) { QueueNode *next = current->next; if (q->destroy) { q->destroy(current->data); } free(current); current = next; } free(q); } } static QueueNode *QueueNodeNew(void *element) { QueueNode *node = xmalloc(sizeof(QueueNode)); node->data = element; node->previous = NULL; node->next = NULL; return node; } void QueueEnqueue(Queue *q, void *element) { assert(q); QueueNode *node = QueueNodeNew(element); if (q->tail) { q->tail->next = node; node->previous = q->tail; q->tail = node; } else { q->tail = node; q->head = node; } ++q->node_count; } void *QueueDequeue(Queue *q) { assert(q); QueueNode *node = q->head; void *data = node->data; q->head = node->next; if (q->head) { q->head->previous = NULL; } else { /* Empty queue */ q->head = NULL; q->tail = NULL; } --q->node_count; /* Free the node */ free(node); /* Return the data */ return data; } void *QueueHead(Queue *q) { assert(q); return q->head->data; } int QueueCount(const Queue *q) { assert(q); return q->node_count; } bool QueueIsEmpty(const Queue *q) { assert(q); return q->node_count == 0; } cfengine-3.24.2/libntech/libutils/glob_lib.h.in0000644000000000000000000000623515010704254021330 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef GLOB_LIB_H #define GLOB_LIB_H #include #include /* Set by ./configure allowing us to avoid #include here. */ @WITH_PCRE2_DEFINE@ #ifdef WITH_PCRE2 /** * @brief Find files/directories matching shell pattern (glob). * * Patterns are UNIX shell style: * * '*' matches everything, * '?' matches any single character, * '[seq]' matches any character in seq, * '[!seq]' matches any character not in seq, * '{foo,bar}' matches foo or bar. * * Pattern is normalized if the operating system requires it. The double * asterisk symbol does not match any subdirectories. The result is sorted in * lexical order. * * @param pattern Glob pattern. * @return Sorted sequence of matches. */ Seq *GlobFind(const char *pattern); /** * @brief Test whether string (filename) matches shell pattern (glob). * * Patterns are UNIX shell style: * * '*' matches everything, * '?' matches any single character, * '[seq]' matches any character in seq, * '[!seq]' matches any character not in seq, * '{foo,bar}' matches foo or bar. * * Pattern is normalized if the operating system requires it. * * We don't check if filename is valid, or if it is a file or if it exists. * It's treated as just a string. * * Modeled after the python fnmatch module (see * https://github.com/python/cpython/blob/3.8/Lib/fnmatch.py) * * @param pattern Glob pattern. * @return True if filename matches shell pattern. */ bool GlobMatch(const char *pattern, const char *filename); #endif // WITH_PCRE2 /** * @brief Find files/directories matching shell pattern (glob). * * Patterns are UNIX shell style: * * '*' matches everything, * '?' matches any single character, * '[seq]' matches any character in seq, * '[!seq]' matches any character not in seq, * '{foo,bar}' matches foo or bar, * '**' matches any subdirectory from zero up to six levels deep. A * limit set by previous CFEngineers. TODO: remove limit in * ticket CFE-4317. * * Pattern is normalized if the operating system requires it. * * @param pattern Glob pattern. * @return Set of matches. */ StringSet *GlobFileList(const char *pattern); #endif // GLOB_LIB_H cfengine-3.24.2/libntech/libutils/unicode.c0000644000000000000000000000311115010704254020561 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include void ConvertFromCharToWChar(int16_t *dst, const char *src, size_t size) { size_t c; size--; // Room for '\0'. for (c = 0; c < size && src[c]; c++) { dst[c] = (int16_t)src[c]; } dst[c] = '\0'; } bool ConvertFromWCharToChar(char *dst, const int16_t *src, size_t size) { bool clean = true; size_t c; size--; // Room for '\0'. for (c = 0; c < size && src[c]; c++) { // We only consider unsigned values. if (src[c] < 0 || src[c] >= 0x100) { clean = false; dst[c] = '_'; } else { dst[c] = (char)src[c]; } } dst[c] = '\0'; return clean; } cfengine-3.24.2/libntech/libutils/regex.c0000644000000000000000000002211315010704254020250 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include Regex *CompileRegex(const char *pattern) { int err_code; size_t err_offset; pcre2_code *regex = pcre2_compile((PCRE2_SPTR) pattern, PCRE2_ZERO_TERMINATED, PCRE2_MULTILINE | PCRE2_DOTALL, &err_code, &err_offset, NULL); if (regex != NULL) { return regex; } char err_msg[128]; if (pcre2_get_error_message(err_code, (PCRE2_UCHAR*) err_msg, sizeof(err_msg)) != PCRE2_ERROR_BADDATA) { Log(LOG_LEVEL_ERR, "Regular expression error: '%s' in expression '%s' (offset: %zd)", err_msg, pattern, err_offset); } else { Log(LOG_LEVEL_ERR, "Unknown regular expression error expression '%s' (offset: %zd)", pattern, err_offset); } return NULL; } void RegexDestroy(Regex *regex) { pcre2_code_free(regex); } bool StringMatchWithPrecompiledRegex(const Regex *regex, const char *str, size_t *start, size_t *end) { assert(regex != NULL); assert(str != NULL); pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(regex, NULL); int result = pcre2_match(regex, (PCRE2_SPTR) str, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); if (result > 0) { size_t *ovec = pcre2_get_ovector_pointer(match_data); if (start != NULL) { *start = ovec[0]; } if (end != NULL) { *end = ovec[1];; } } else { if (start != NULL) { *start = 0; } if (end != NULL) { *end = 0; } } pcre2_match_data_free(match_data); return result > 0; } bool StringMatch(const char *pattern, const char *str, size_t *start, size_t *end) { Regex *regex = CompileRegex(pattern); if (regex == NULL) { return false; } bool ret = StringMatchWithPrecompiledRegex(regex, str, start, end); RegexDestroy(regex); return ret; } bool StringMatchFull(const char *pattern, const char *str) { Regex *regex = CompileRegex(pattern); if (regex == NULL) { return false; } bool ret = StringMatchFullWithPrecompiledRegex(regex, str); RegexDestroy(regex); return ret; } bool StringMatchFullWithPrecompiledRegex(const Regex *regex, const char *str) { size_t start; size_t end; if (StringMatchWithPrecompiledRegex(regex, str, &start, &end)) { return (start == (size_t) 0) && (end == strlen(str)); } else { return false; } } // Returns a Sequence with Buffer elements. // If return_names is set, the even positions will be the name or // number of the capturing group, followed by the captured data in the // odd positions (so for N captures you can expect 2N elements in the // Sequence). // If return_names is not set, only the captured data is returned (so // for N captures you can expect N elements in the Sequence). Seq *StringMatchCapturesWithPrecompiledRegex(const Regex *regex, const char *str, const bool return_names) { pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(regex, NULL); int result = pcre2_match(regex, (PCRE2_SPTR) str, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); /* pcre2_match() returns the highest capture group number + 1, i.e. 1 means * a match with 0 capture groups. 0 means the vector of offsets is small, * negative numbers are errors (incl. no match). */ if (result < 1) { pcre2_match_data_free(match_data); return NULL; } uint32_t captures; int res = pcre2_pattern_info(regex, PCRE2_INFO_CAPTURECOUNT, &captures); if (res != 0) { pcre2_match_data_free(match_data); return NULL; } uint32_t namecount = 0; res = pcre2_pattern_info(regex, PCRE2_INFO_NAMECOUNT, &namecount); assert(res == 0); const bool do_named_captures = (namecount > 0 && return_names); // Get the table of named captures (see explanation below). uint32_t name_entry_size = 0; unsigned char *name_table = NULL; if (do_named_captures) { res = pcre2_pattern_info(regex, PCRE2_INFO_NAMEENTRYSIZE, &name_entry_size); assert(res == 0); res = pcre2_pattern_info(regex, PCRE2_INFO_NAMETABLE, &name_table); assert(res == 0); } size_t *ovector = pcre2_get_ovector_pointer(match_data); Seq *ret = SeqNew(captures + 1, BufferDestroy); for (uint32_t i = 0; i <= captures; ++i) { Buffer *capture = NULL; if (do_named_captures) { /* The map contains $namecount entries each with: * - 2 bytes representing the position of the capture group in the offset vector * - followed by the name of the named group, NUL-terminated. * Each entry is padded to be $name_entry_size bytes big. */ unsigned char *tabptr = name_table; for (uint32_t namepos = 0; namepos < namecount; namepos++) { uint16_t n = (tabptr[0] << 8) | tabptr[1]; if (n == i) // We found the position { capture = BufferNewFrom((char *)(tabptr + 2), name_entry_size - 3); break; } tabptr += name_entry_size; } } if (return_names) { if (capture == NULL) { capture = BufferNew(); BufferAppendF(capture, "%"PRIu32, i); } SeqAppend(ret, capture); } Buffer *data = BufferNewFrom(str + ovector[2*i], ovector[2*i + 1] - ovector[2 * i]); Log(LOG_LEVEL_DEBUG, "StringMatchCaptures: return_names = %d, do_named_captures = %s, offset %d, name '%s', data '%s'", return_names, do_named_captures ? "true" : "false", i, capture == NULL ? "no_name" : BufferData(capture), BufferData(data)); SeqAppend(ret, data); } pcre2_match_data_free(match_data); return ret; } // Returns a Sequence with Buffer elements. // If return_names is set, the even positions will be the name or // number of the capturing group, followed by the captured data in the // odd positions (so for N captures you can expect 2N elements in the // Sequence). // If return_names is not set, only the captured data is returned (so // for N captures you can expect N elements in the Sequence). Seq *StringMatchCaptures(const char *pattern, const char *str, const bool return_names) { assert(pattern); assert(str); int err_code; size_t err_offset; pcre2_code *regex = pcre2_compile((PCRE2_SPTR) pattern, PCRE2_ZERO_TERMINATED, PCRE2_MULTILINE | PCRE2_DOTALL, &err_code, &err_offset, NULL); if (regex == NULL) { return NULL; } Seq *ret = StringMatchCapturesWithPrecompiledRegex(regex, str, return_names); pcre2_code_free(regex); return ret; } bool CompareStringOrRegex(const char *value, const char *compareTo, bool regex) { if (regex) { if (!NULL_OR_EMPTY(compareTo) && !StringMatchFull(compareTo, value)) { return false; } } else { if (!NULL_OR_EMPTY(compareTo) && strcmp(compareTo, value) != 0) { return false; } } return true; } /* * This is a fast partial match function. It checks that the compiled rx matches * anywhere inside teststring. It does not allocate or free rx! */ bool RegexPartialMatch(const Regex *regex, const char *teststring) { pcre2_match_data *md = pcre2_match_data_create_from_pattern(regex, NULL); int rc = pcre2_match(regex, (PCRE2_SPTR) teststring, PCRE2_ZERO_TERMINATED, 0, 0, md, NULL); pcre2_match_data_free(md); /* pcre2_match() returns the highest capture group number + 1, i.e. 1 means * a match with 0 capture groups. 0 means the vector of offsets is small, * negative numbers are errors (incl. no match). */ return rc >= 1; } cfengine-3.24.2/libntech/libutils/json.c0000644000000000000000000024436715010704254020130 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WITH_PCRE2 #include #endif #include static const int SPACES_PER_INDENT = 2; const int DEFAULT_CONTAINER_CAPACITY = 64; static const char *const JSON_TRUE = "true"; static const char *const JSON_FALSE = "false"; static const char *const JSON_NULL = "null"; struct JsonElement_ { JsonElementType type; // We don't have a separate struct for the key-value pairs in a JSON // Object. Instead, a JSON Object has a JsonElement Seq, where each element // has a propertyName (the key). A JSON Object key-value pair is sometimes // called a JSON Object property. char *propertyName; union { struct JsonContainer { JsonContainerType type; Seq *children; } container; struct JsonPrimitive { JsonPrimitiveType type; const char *value; } primitive; }; }; // ******************************************************************************************* // JsonElement Functions // ******************************************************************************************* const char *JsonContainerTypeToString(const JsonContainerType type) { switch (type) { case JSON_CONTAINER_TYPE_ARRAY: return "array"; case JSON_CONTAINER_TYPE_OBJECT: return "object"; default: UnexpectedError("Unknown JSON container type: %d", type); return "(null)"; } } const char *JsonPrimitiveTypeToString(const JsonPrimitiveType type) { switch (type) { case JSON_PRIMITIVE_TYPE_STRING: return "string"; case JSON_PRIMITIVE_TYPE_REAL: case JSON_PRIMITIVE_TYPE_INTEGER: return "number"; case JSON_PRIMITIVE_TYPE_BOOL: return "boolean"; default: UnexpectedError("Unknown JSON primitive type: %d", type); return "(null)"; } } static void JsonElementSetPropertyName( JsonElement *const element, const char *const propertyName) { assert(element != NULL); if (element->propertyName != NULL) { free(element->propertyName); element->propertyName = NULL; } if (propertyName != NULL) { element->propertyName = xstrdup(propertyName); } } const char *JsonElementGetPropertyName(const JsonElement *const element) { assert(element != NULL); return element->propertyName; } static JsonElement *JsonElementCreateContainer( const JsonContainerType containerType, const char *const propertyName, const size_t initialCapacity) { JsonElement *element = xcalloc(1, sizeof(JsonElement)); element->type = JSON_ELEMENT_TYPE_CONTAINER; JsonElementSetPropertyName(element, propertyName); element->container.type = containerType; element->container.children = SeqNew(initialCapacity, JsonDestroy); return element; } static JsonElement *JsonElementCreatePrimitive( JsonPrimitiveType primitiveType, const char *value) { JsonElement *element = xcalloc(1, sizeof(JsonElement)); element->type = JSON_ELEMENT_TYPE_PRIMITIVE; element->primitive.type = primitiveType; element->primitive.value = value; return element; } static JsonElement *JsonArrayCopy(const JsonElement *array) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); JsonElement *copy = JsonArrayCreate(JsonLength(array)); JsonIterator iter = JsonIteratorInit(array); const JsonElement *child; while ((child = JsonIteratorNextValue(&iter)) != NULL) { JsonArrayAppendElement(copy, JsonCopy(child)); } return copy; } static JsonElement *JsonObjectCopy(const JsonElement *const object) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); JsonElement *copy = JsonObjectCreate(JsonLength(object)); JsonIterator iter = JsonIteratorInit(object); const JsonElement *child; while ((child = JsonIteratorNextValue(&iter)) != NULL) { JsonObjectAppendElement( copy, JsonIteratorCurrentKey(&iter), JsonCopy(child)); } return copy; } static JsonElement *JsonContainerCopy(const JsonElement *const container) { assert(container != NULL); assert(container->type == JSON_ELEMENT_TYPE_CONTAINER); const JsonContainerType type = container->container.type; switch (type) { case JSON_CONTAINER_TYPE_ARRAY: return JsonArrayCopy(container); case JSON_CONTAINER_TYPE_OBJECT: return JsonObjectCopy(container); default: UnexpectedError("Unknown JSON container type: %d", type); return NULL; } } static JsonElement *JsonPrimitiveCopy(const JsonElement *const primitive) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); const JsonPrimitiveType type = primitive->primitive.type; switch (type) { case JSON_PRIMITIVE_TYPE_BOOL: return JsonBoolCreate(JsonPrimitiveGetAsBool(primitive)); case JSON_PRIMITIVE_TYPE_INTEGER: return JsonIntegerCreate(JsonPrimitiveGetAsInteger(primitive)); case JSON_PRIMITIVE_TYPE_NULL: return JsonNullCreate(); case JSON_PRIMITIVE_TYPE_REAL: return JsonRealCreate(JsonPrimitiveGetAsReal(primitive)); case JSON_PRIMITIVE_TYPE_STRING: return JsonStringCreate(JsonPrimitiveGetAsString(primitive)); } UnexpectedError("Unknown JSON primitive type: %d", type); return NULL; } JsonElement *JsonCopy(const JsonElement *const element) { assert(element != NULL); switch (element->type) { case JSON_ELEMENT_TYPE_CONTAINER: return JsonContainerCopy(element); case JSON_ELEMENT_TYPE_PRIMITIVE: return JsonPrimitiveCopy(element); } UnexpectedError("Unknown JSON element type: %d", element->type); return NULL; } static int JsonArrayCompare( const JsonElement *const a, const JsonElement *const b) { assert(a != NULL); assert(b != NULL); assert(a->type == JSON_ELEMENT_TYPE_CONTAINER); assert(b->type == JSON_ELEMENT_TYPE_CONTAINER); assert(a->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(b->container.type == JSON_CONTAINER_TYPE_ARRAY); int ret = JsonLength(a) - JsonLength(b); if (ret != 0) { Log(LOG_LEVEL_DEBUG, "JsonArrayCompare() fails, length differs by %d", ret); return ret; } JsonIterator iter_a = JsonIteratorInit(a); JsonIterator iter_b = JsonIteratorInit(b); for (size_t i = 0; i < JsonLength(a); i++) { const JsonElement *child_a = JsonIteratorNextValue(&iter_a); const JsonElement *child_b = JsonIteratorNextValue(&iter_b); ret = JsonCompare(child_a, child_b); if (ret != 0) { Log(LOG_LEVEL_DEBUG, "JsonArrayCompare() fails for index %zu, children not equal", i); return ret; } } return ret; } static int JsonObjectCompare( const JsonElement *const a, const JsonElement *const b) { assert(a != NULL); assert(b != NULL); assert(a->type == JSON_ELEMENT_TYPE_CONTAINER); assert(b->type == JSON_ELEMENT_TYPE_CONTAINER); assert(a->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(b->container.type == JSON_CONTAINER_TYPE_OBJECT); int ret = JsonLength(a) - JsonLength(b); if (ret != 0) { Log(LOG_LEVEL_DEBUG, "JsonObjectCompare() fails, length differs by %d", ret); return ret; } JsonIterator iter = JsonIteratorInit(a); while (JsonIteratorHasMore(&iter)) { const char *const key = JsonIteratorNextKey(&iter); const JsonElement *const child_a = JsonIteratorCurrentValue(&iter); const JsonElement *const child_b = JsonObjectGet(b, key); if (child_b == NULL) { Log(LOG_LEVEL_DEBUG, "JsonObjectCompare() fails for key '%s', not present in object b", key); return 1; } ret = JsonCompare(child_a, child_b); if (ret != 0) { Log(LOG_LEVEL_DEBUG, "JsonObjectCompare() fails for key '%s', children are not equal", key); return ret; } } return ret; // here ret will be 0 in the case that both objects are empty or all children are equal } static int JsonContainerCompare( const JsonElement *const a, const JsonElement *const b) { assert(a != NULL); assert(b != NULL); assert(a->type == JSON_ELEMENT_TYPE_CONTAINER); assert(b->type == JSON_ELEMENT_TYPE_CONTAINER); const JsonContainerType type_a = a->container.type; const JsonContainerType type_b = b->container.type; if (type_a != type_b) { Log(LOG_LEVEL_DEBUG, "JsonContainerCompare() fails, container type '%s' not equal to container type '%s'", JsonContainerTypeToString(type_a), JsonContainerTypeToString(type_b)); return type_a - type_b; } switch (type_a) { case JSON_CONTAINER_TYPE_ARRAY: return JsonArrayCompare(a, b); case JSON_CONTAINER_TYPE_OBJECT: return JsonObjectCompare(a, b); default: UnexpectedError("Unknown JSON container type: %d", type_a); return -1; } } int JsonCompare(const JsonElement *const a, const JsonElement *const b) { assert(a != NULL); assert(b != NULL); const JsonElementType type_a = a->type; const JsonElementType type_b = b->type; if (type_a != type_b) { Log(LOG_LEVEL_DEBUG, "JsonCompare() fails, type %d not equal to type %d", type_a, type_b); return type_a - type_b; } switch (type_a) { case JSON_ELEMENT_TYPE_CONTAINER: return JsonContainerCompare(a, b); case JSON_ELEMENT_TYPE_PRIMITIVE: { if (!StringEqual(a->primitive.value, b->primitive.value)) { Log(LOG_LEVEL_DEBUG, "JsonCompare() fails, primitive '%s' not equal to '%s'", a->primitive.value, b->primitive.value); return 1; } return 0; } default: UnexpectedError("Unknown JSON element type: %d", type_a); return -1; } } void JsonDestroy(JsonElement *const element) { if (element != NULL) { switch (element->type) { case JSON_ELEMENT_TYPE_CONTAINER: assert(element->container.children); SeqDestroy(element->container.children); element->container.children = NULL; break; case JSON_ELEMENT_TYPE_PRIMITIVE: assert(element->primitive.value); if (element->primitive.type != JSON_PRIMITIVE_TYPE_NULL && element->primitive.type != JSON_PRIMITIVE_TYPE_BOOL) { free((void *) element->primitive.value); } element->primitive.value = NULL; break; default: UnexpectedError("Unknown JSON element type: %d", element->type); } if (element->propertyName != NULL) { free(element->propertyName); } free(element); } } void JsonDestroyMaybe(JsonElement *const element, const bool allocated) { if (allocated) { JsonDestroy(element); } } JsonElement *JsonArrayMergeArray( const JsonElement *const a, const JsonElement *const b) { assert(JsonGetElementType(a) == JsonGetElementType(b)); assert(JsonGetElementType(a) == JSON_ELEMENT_TYPE_CONTAINER); assert(JsonGetContainerType(a) == JsonGetContainerType(b)); assert(JsonGetContainerType(a) == JSON_CONTAINER_TYPE_ARRAY); JsonElement *result = JsonArrayCreate(JsonLength(a) + JsonLength(b)); for (size_t i = 0; i < JsonLength(a); i++) { JsonArrayAppendElement(result, JsonCopy(JsonAt(a, i))); } for (size_t i = 0; i < JsonLength(b); i++) { JsonArrayAppendElement(result, JsonCopy(JsonAt(b, i))); } return result; } JsonElement *JsonObjectMergeArray( const JsonElement *const a, const JsonElement *const b) { assert(JsonGetElementType(a) == JsonGetElementType(b)); assert(JsonGetElementType(a) == JSON_ELEMENT_TYPE_CONTAINER); assert(JsonGetContainerType(a) == JSON_CONTAINER_TYPE_OBJECT); assert(JsonGetContainerType(b) == JSON_CONTAINER_TYPE_ARRAY); JsonElement *result = JsonObjectCopy(a); for (size_t i = 0; i < JsonLength(b); i++) { char *key = StringFromLong(i); JsonObjectAppendElement(result, key, JsonCopy(JsonAt(b, i))); free(key); } return result; } JsonElement *JsonObjectMergeObject( const JsonElement *const a, const JsonElement *const b) { assert(JsonGetElementType(a) == JsonGetElementType(b)); assert(JsonGetElementType(a) == JSON_ELEMENT_TYPE_CONTAINER); assert(JsonGetContainerType(a) == JSON_CONTAINER_TYPE_OBJECT); assert(JsonGetContainerType(b) == JSON_CONTAINER_TYPE_OBJECT); JsonElement *result = JsonObjectCopy(a); JsonIterator iter = JsonIteratorInit(b); const char *key; while ((key = JsonIteratorNextKey(&iter))) { JsonObjectAppendElement( result, key, JsonCopy(JsonIteratorCurrentValue(&iter))); } return result; } JsonElement *JsonMerge(const JsonElement *const a, const JsonElement *const b) { assert(JsonGetElementType(a) == JsonGetElementType(b)); assert(JsonGetElementType(a) == JSON_ELEMENT_TYPE_CONTAINER); switch (JsonGetContainerType(a)) { case JSON_CONTAINER_TYPE_ARRAY: switch (JsonGetContainerType(b)) { case JSON_CONTAINER_TYPE_OBJECT: return JsonObjectMergeArray(b, a); case JSON_CONTAINER_TYPE_ARRAY: return JsonArrayMergeArray(a, b); } UnexpectedError( "Unknown JSON container type: %d", JsonGetContainerType(b)); break; case JSON_CONTAINER_TYPE_OBJECT: switch (JsonGetContainerType(b)) { case JSON_CONTAINER_TYPE_OBJECT: return JsonObjectMergeObject(a, b); case JSON_CONTAINER_TYPE_ARRAY: return JsonObjectMergeArray(a, b); } UnexpectedError( "Unknown JSON container type: %d", JsonGetContainerType(b)); break; default: UnexpectedError( "Unknown JSON container type: %d", JsonGetContainerType(a)); } return NULL; } JsonElement *JsonObjectMergeDeepInplace(JsonElement *const base, const JsonElement *const extra) { assert(base != NULL); assert(extra != NULL); assert(JsonGetType(base) == JSON_TYPE_OBJECT); assert(JsonGetType(extra) == JSON_TYPE_OBJECT); JsonIterator iter = JsonIteratorInit(extra); while (JsonIteratorHasMore(&iter)) { const char *const key = JsonIteratorNextKey(&iter); assert(key != NULL); const JsonElement *const extra_value = JsonIteratorCurrentValue(&iter); assert(key != NULL); JsonElement *const base_value = JsonObjectGet(base, key); if (base_value == NULL) { /* Key is unique, copy element into base */ JsonElement *const element = JsonCopy(extra_value); assert(element != NULL); JsonObjectAppendElement(base, key, element); continue; } const JsonType base_type = JsonGetType(base_value); const JsonType extra_type = JsonGetType(extra_value); if (base_type == JSON_TYPE_OBJECT && extra_type == JSON_TYPE_OBJECT) { /* Both are objects, recursively merge them */ JsonObjectMergeDeepInplace(base_value, extra_value); } else if (base_type == JSON_TYPE_ARRAY && extra_type == JSON_TYPE_ARRAY) { /* Both are arrays, concatenate them into base */ JsonElement *const element = JsonCopy(extra_value); assert(element != NULL); JsonArrayExtend(base_value, element); } else { /* Otherwise, overwrite value in base */ JsonElement *const element = JsonCopy(extra_value); assert(element != NULL); JsonObjectAppendElement(base, key, element); } } return base; } size_t JsonLength(const JsonElement *const element) { assert(element != NULL); switch (element->type) { case JSON_ELEMENT_TYPE_CONTAINER: return SeqLength(element->container.children); case JSON_ELEMENT_TYPE_PRIMITIVE: return strlen(element->primitive.value); default: UnexpectedError("Unknown JSON element type: %d", element->type); return (size_t) -1; // appease gcc } } JsonIterator JsonIteratorInit(const JsonElement *const container) { assert(container != NULL); assert(container->type == JSON_ELEMENT_TYPE_CONTAINER); return (JsonIterator){container, 0}; } const char *JsonIteratorNextKey(JsonIterator *const iter) { assert(iter != NULL); assert(iter->container != NULL); assert(iter->container->type == JSON_ELEMENT_TYPE_CONTAINER); assert(iter->container->container.type == JSON_CONTAINER_TYPE_OBJECT); const JsonElement *child = JsonIteratorNextValue(iter); return child ? child->propertyName : NULL; } JsonElement *JsonIteratorNextValue(JsonIterator *const iter) { assert(iter != NULL); assert(iter->container != NULL); assert(iter->container->type == JSON_ELEMENT_TYPE_CONTAINER); if (iter->index >= JsonLength(iter->container)) { return NULL; } Seq *const children = iter->container->container.children; return SeqAt(children, iter->index++); } JsonElement *JsonIteratorNextValueByType( JsonIterator *const iter, const JsonElementType type, const bool skip_null) { JsonElement *e = NULL; while ((e = JsonIteratorNextValue(iter))) { if (skip_null && JsonGetType(e) == JSON_TYPE_NULL) { continue; } if (e->type == type) { return e; } } return NULL; } JsonElement *JsonIteratorCurrentValue(const JsonIterator *const iter) { assert(iter != NULL); assert(iter->container != NULL); assert(iter->container->type == JSON_ELEMENT_TYPE_CONTAINER); if (iter->index == 0 || iter->index > JsonLength(iter->container)) { return NULL; } Seq *const children = iter->container->container.children; return SeqAt(children, iter->index - 1); } const char *JsonIteratorCurrentKey(const JsonIterator *const iter) { assert(iter != NULL); assert(iter->container != NULL); assert(iter->container->type == JSON_ELEMENT_TYPE_CONTAINER); assert(iter->container->container.type == JSON_CONTAINER_TYPE_OBJECT); const JsonElement *child = JsonIteratorCurrentValue(iter); return child ? child->propertyName : NULL; } JsonElementType JsonIteratorCurrentElementType(const JsonIterator *const iter) { assert(iter != NULL); const JsonElement *child = JsonIteratorCurrentValue(iter); return child->type; } JsonContainerType JsonIteratorCurrentContainerType( const JsonIterator *const iter) { assert(iter != NULL); const JsonElement *child = JsonIteratorCurrentValue(iter); assert(child->type == JSON_ELEMENT_TYPE_CONTAINER); return child->container.type; } JsonPrimitiveType JsonIteratorCurrentPrimitiveType( const JsonIterator *const iter) { assert(iter != NULL); const JsonElement *child = JsonIteratorCurrentValue(iter); assert(child->type == JSON_ELEMENT_TYPE_PRIMITIVE); return child->primitive.type; } bool JsonIteratorHasMore(const JsonIterator *const iter) { assert(iter != NULL); return iter->index < JsonLength(iter->container); } JsonElementType JsonGetElementType(const JsonElement *const element) { assert(element != NULL); return element->type; } JsonType JsonGetType(const JsonElement *element) { if (JsonGetElementType(element) == JSON_ELEMENT_TYPE_CONTAINER) { return (JsonType) JsonGetContainerType(element); } assert(JsonGetElementType(element) == JSON_ELEMENT_TYPE_PRIMITIVE); return (JsonType) JsonGetPrimitiveType(element); } JsonContainerType JsonGetContainerType(const JsonElement *const container) { assert(container != NULL); assert(container->type == JSON_ELEMENT_TYPE_CONTAINER); return container->container.type; } JsonPrimitiveType JsonGetPrimitiveType(const JsonElement *const primitive) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); return primitive->primitive.type; } const char *JsonPrimitiveGetAsString(const JsonElement *const primitive) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); return primitive->primitive.value; } char *JsonPrimitiveToString(const JsonElement *const primitive) { if (JsonGetElementType(primitive) != JSON_ELEMENT_TYPE_PRIMITIVE) { return NULL; } switch (JsonGetPrimitiveType(primitive)) { case JSON_PRIMITIVE_TYPE_BOOL: return xstrdup(JsonPrimitiveGetAsBool(primitive) ? "true" : "false"); break; case JSON_PRIMITIVE_TYPE_INTEGER: return StringFromLong(JsonPrimitiveGetAsInteger(primitive)); break; case JSON_PRIMITIVE_TYPE_REAL: return StringFromDouble(JsonPrimitiveGetAsReal(primitive)); break; case JSON_PRIMITIVE_TYPE_STRING: return xstrdup(JsonPrimitiveGetAsString(primitive)); break; case JSON_PRIMITIVE_TYPE_NULL: // redundant break; } return NULL; } bool JsonPrimitiveGetAsBool(const JsonElement *const primitive) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); assert(primitive->primitive.type == JSON_PRIMITIVE_TYPE_BOOL); return StringEqual(JSON_TRUE, primitive->primitive.value); } long JsonPrimitiveGetAsInteger(const JsonElement *const primitive) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); assert(primitive->primitive.type == JSON_PRIMITIVE_TYPE_INTEGER); return StringToLongExitOnError(primitive->primitive.value); } int JsonPrimitiveGetAsInt64(const JsonElement *primitive, int64_t *value_out) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); assert(primitive->primitive.type == JSON_PRIMITIVE_TYPE_INTEGER); return StringToInt64(primitive->primitive.value, value_out); } int64_t JsonPrimitiveGetAsInt64DefaultOnError(const JsonElement *primitive, int64_t default_return) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); assert(primitive->primitive.type == JSON_PRIMITIVE_TYPE_INTEGER); return StringToInt64DefaultOnError(primitive->primitive.value, default_return); } int64_t JsonPrimitiveGetAsInt64ExitOnError(const JsonElement *primitive) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); assert(primitive->primitive.type == JSON_PRIMITIVE_TYPE_INTEGER); return StringToInt64ExitOnError(primitive->primitive.value); } double JsonPrimitiveGetAsReal(const JsonElement *const primitive) { assert(primitive != NULL); assert(primitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); assert(primitive->primitive.type == JSON_PRIMITIVE_TYPE_REAL); return StringToDouble(primitive->primitive.value); } const char *JsonGetPropertyAsString(const JsonElement *const element) { assert(element != NULL); return element->propertyName; } void JsonSort( const JsonElement *const container, JsonComparator *const Compare, void *const user_data) { assert(container != NULL); assert(container->type == JSON_ELEMENT_TYPE_CONTAINER); Seq *const children = container->container.children; SeqSort(children, (SeqItemComparator) Compare, user_data); } JsonElement *JsonAt(const JsonElement *container, const size_t index) { assert(container != NULL); assert(container->type == JSON_ELEMENT_TYPE_CONTAINER); assert(index < JsonLength(container)); return SeqAt(container->container.children, index); } JsonElement *JsonSelect( JsonElement *const element, const size_t num_indices, char **const indices) { if (num_indices == 0) { return element; } else { if (JsonGetElementType(element) != JSON_ELEMENT_TYPE_CONTAINER) { return NULL; } const char *index = indices[0]; switch (JsonGetContainerType(element)) { case JSON_CONTAINER_TYPE_OBJECT: { JsonElement *child = JsonObjectGet(element, index); if (child != NULL) { return JsonSelect(child, num_indices - 1, indices + 1); } } return NULL; case JSON_CONTAINER_TYPE_ARRAY: if (StringIsNumeric(index)) { size_t i = StringToLongExitOnError(index); if (i < JsonLength(element)) { JsonElement *child = JsonArrayGet(element, i); if (child != NULL) { return JsonSelect(child, num_indices - 1, indices + 1); } } } break; default: UnexpectedError( "Unknown JSON container type: %d", JsonGetContainerType(element)); } return NULL; } } // ******************************************************************************************* // JsonObject Functions // ******************************************************************************************* JsonElement *JsonObjectCreate(const size_t initialCapacity) { return JsonElementCreateContainer( JSON_CONTAINER_TYPE_OBJECT, NULL, initialCapacity); } void JsonEncodeStringWriter( const char *const unescaped_string, Writer *const writer) { assert(unescaped_string != NULL); for (const char *c = unescaped_string; *c != '\0'; c++) { switch (*c) { case '\"': case '\\': WriterWriteChar(writer, '\\'); WriterWriteChar(writer, *c); break; case '\b': WriterWriteChar(writer, '\\'); WriterWriteChar(writer, 'b'); break; case '\f': WriterWriteChar(writer, '\\'); WriterWriteChar(writer, 'f'); break; case '\n': WriterWriteChar(writer, '\\'); WriterWriteChar(writer, 'n'); break; case '\r': WriterWriteChar(writer, '\\'); WriterWriteChar(writer, 'r'); break; case '\t': WriterWriteChar(writer, '\\'); WriterWriteChar(writer, 't'); break; default: WriterWriteChar(writer, *c); } } } char *JsonEncodeString(const char *const unescaped_string) { Writer *writer = StringWriter(); JsonEncodeStringWriter(unescaped_string, writer); return StringWriterClose(writer); } static void JsonDecodeStringWriter( const char *const escaped_string, Writer *const w) { assert(escaped_string != NULL); for (const char *c = escaped_string; *c != '\0'; c++) { if (*c == '\\') { switch (c[1]) { case '\"': case '\\': WriterWriteChar(w, c[1]); c++; break; case 'b': WriterWriteChar(w, '\b'); c++; break; case 'f': WriterWriteChar(w, '\f'); c++; break; case 'n': WriterWriteChar(w, '\n'); c++; break; case 'r': WriterWriteChar(w, '\r'); c++; break; case 't': WriterWriteChar(w, '\t'); c++; break; default: WriterWriteChar(w, *c); break; } } else { WriterWriteChar(w, *c); } } } char *JsonDecodeString(const char *const escaped_string) { Writer *writer = StringWriter(); JsonDecodeStringWriter(escaped_string, writer); return StringWriterClose(writer); } void Json5EscapeDataWriter(const Slice unescaped_data, Writer *const writer) { // See: https://spec.json5.org/#strings const char *const data = unescaped_data.data; assert(data != NULL); const size_t size = unescaped_data.size; for (size_t index = 0; index < size; index++) { const char byte = data[index]; switch (byte) { case '\0': WriterWrite(writer, "\\0"); break; case '\"': case '\\': WriterWriteChar(writer, '\\'); WriterWriteChar(writer, byte); break; case '\b': WriterWrite(writer, "\\b"); break; case '\f': WriterWrite(writer, "\\f"); break; case '\n': WriterWrite(writer, "\\n"); break; case '\r': WriterWrite(writer, "\\r"); break; case '\t': WriterWrite(writer, "\\t"); break; default: { if (CharIsPrintableAscii(byte)) { WriterWriteChar(writer, byte); } else { // unsigned char behaves better when implicitly cast to int: WriterWriteF(writer, "\\x%2.2X", (unsigned char) byte); } break; } } } } char *Json5EscapeData(Slice unescaped_data) { Writer *writer = StringWriter(); Json5EscapeDataWriter(unescaped_data, writer); return StringWriterClose(writer); } void JsonObjectAppendString( JsonElement *const object, const char *const key, const char *const value) { JsonElement *child = JsonStringCreate(value); JsonObjectAppendElement(object, key, child); } void JsonObjectAppendInteger( JsonElement *const object, const char *const key, const int value) { JsonElement *child = JsonIntegerCreate(value); JsonObjectAppendElement(object, key, child); } void JsonObjectAppendInteger64( JsonElement *const object, const char *const key, const int64_t value) { JsonElement *child = JsonIntegerCreate64(value); JsonObjectAppendElement(object, key, child); } void JsonObjectAppendBool( JsonElement *const object, const char *const key, const _Bool value) { JsonElement *child = JsonBoolCreate(value); JsonObjectAppendElement(object, key, child); } void JsonObjectAppendReal( JsonElement *const object, const char *const key, const double value) { JsonElement *child = JsonRealCreate(value); JsonObjectAppendElement(object, key, child); } void JsonObjectAppendNull(JsonElement *const object, const char *const key) { JsonElement *child = JsonNullCreate(); JsonObjectAppendElement(object, key, child); } void JsonObjectAppendArray( JsonElement *const object, const char *const key, JsonElement *const array) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); JsonObjectAppendElement(object, key, array); } void JsonObjectAppendObject( JsonElement *const object, const char *const key, JsonElement *const childObject) { assert(childObject != NULL); assert(childObject->type == JSON_ELEMENT_TYPE_CONTAINER); assert(childObject->container.type == JSON_CONTAINER_TYPE_OBJECT); JsonObjectAppendElement(object, key, childObject); } void JsonObjectAppendElement( JsonElement *const object, const char *const key, JsonElement *const element) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); assert(element != NULL); JsonObjectRemoveKey(object, key); JsonElementSetPropertyName(element, key); SeqAppend(object->container.children, element); } static int JsonElementHasProperty( const void *const propertyName, const void *const jsonElement, ARG_UNUSED void *const user_data) { assert(propertyName != NULL); const JsonElement *element = jsonElement; assert(element->propertyName != NULL); if (StringEqual(propertyName, element->propertyName)) { return 0; } return -1; } static int CompareKeyToPropertyName( const void *const a, const void *const b, ARG_UNUSED void *const user_data) { assert(b != NULL); const char *const key_a = a; const JsonElement *const json_b = b; return StringSafeCompare(key_a, json_b->propertyName); } static ssize_t JsonElementIndexInParentObject( JsonElement *const parent, const char *const key) { assert(parent != NULL); assert(parent->type == JSON_ELEMENT_TYPE_CONTAINER); assert(parent->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); Seq *const children = parent->container.children; return SeqIndexOf(children, key, CompareKeyToPropertyName); } bool JsonObjectRemoveKey(JsonElement *const object, const char *const key) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); const ssize_t index = JsonElementIndexInParentObject(object, key); if (index != -1) { SeqRemove(object->container.children, index); return true; } return false; } JsonElement *JsonObjectDetachKey( JsonElement *const object, const char *const key) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); JsonElement *detached = NULL; ssize_t index = JsonElementIndexInParentObject(object, key); if (index != -1) { Seq *const children = object->container.children; detached = SeqLookup(children, key, JsonElementHasProperty); SeqSoftRemove(children, index); } return detached; } const char *JsonObjectGetAsString( const JsonElement *const object, const char *const key) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); JsonElement *childPrimitive = SeqLookup(object->container.children, key, JsonElementHasProperty); if (childPrimitive != NULL) { assert(childPrimitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); return childPrimitive->primitive.value; } return NULL; } bool JsonObjectGetAsBool( const JsonElement *const object, const char *key) { assert(object != NULL); assert(JsonGetType(object) == JSON_TYPE_OBJECT); assert(key != NULL); JsonElement *childPrimitive = JsonObjectGet(object, key); if (childPrimitive != NULL) { assert(JsonGetType(childPrimitive) == JSON_TYPE_BOOL); return StringEqual(childPrimitive->primitive.value, "true"); } return false; } JsonElement *JsonObjectGetAsObject( JsonElement *const object, const char *const key) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); JsonElement *childPrimitive = SeqLookup(object->container.children, key, JsonElementHasProperty); if (childPrimitive != NULL) { assert(childPrimitive->type == JSON_ELEMENT_TYPE_CONTAINER); assert(childPrimitive->container.type == JSON_CONTAINER_TYPE_OBJECT); return childPrimitive; } return NULL; } JsonElement *JsonObjectGetAsArray( JsonElement *const object, const char *const key) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); JsonElement *childPrimitive = SeqLookup(object->container.children, key, JsonElementHasProperty); if (childPrimitive != NULL) { assert(childPrimitive->type == JSON_ELEMENT_TYPE_CONTAINER); assert(childPrimitive->container.type == JSON_CONTAINER_TYPE_ARRAY); return childPrimitive; } return NULL; } JsonElement *JsonObjectGet( const JsonElement *const object, const char *const key) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(key != NULL); return SeqLookup(object->container.children, key, JsonElementHasProperty); } // ******************************************************************************************* // JsonArray Functions // ******************************************************************************************* JsonElement *JsonArrayCreate(const size_t initialCapacity) { return JsonElementCreateContainer( JSON_CONTAINER_TYPE_ARRAY, NULL, initialCapacity); } void JsonArrayAppendString(JsonElement *const array, const char *const value) { JsonElement *child = JsonStringCreate(value); JsonArrayAppendElement(array, child); } void JsonArrayAppendBool(JsonElement *const array, const bool value) { JsonElement *child = JsonBoolCreate(value); JsonArrayAppendElement(array, child); } void JsonArrayAppendInteger(JsonElement *const array, const int value) { JsonElement *child = JsonIntegerCreate(value); JsonArrayAppendElement(array, child); } void JsonArrayAppendReal(JsonElement *const array, const double value) { JsonElement *child = JsonRealCreate(value); JsonArrayAppendElement(array, child); } void JsonArrayAppendNull(JsonElement *const array) { JsonElement *child = JsonNullCreate(); JsonArrayAppendElement(array, child); } void JsonArrayAppendArray( JsonElement *const array, JsonElement *const childArray) { assert(childArray != NULL); assert(childArray->type == JSON_ELEMENT_TYPE_CONTAINER); assert(childArray->container.type == JSON_CONTAINER_TYPE_ARRAY); JsonArrayAppendElement(array, childArray); } void JsonArrayAppendObject(JsonElement *const array, JsonElement *const object) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); JsonArrayAppendElement(array, object); } void JsonArrayAppendElement( JsonElement *const array, JsonElement *const element) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(element != NULL); SeqAppend(array->container.children, element); } void JsonArrayExtend(JsonElement *a, JsonElement *b) { assert(a != NULL); assert(a->type == JSON_ELEMENT_TYPE_CONTAINER); assert(a->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(b != NULL); assert(b->type == JSON_ELEMENT_TYPE_CONTAINER); assert(b->container.type == JSON_CONTAINER_TYPE_ARRAY); SeqAppendSeq(a->container.children, b->container.children); SeqSoftDestroy(b->container.children); if (b->propertyName != NULL) { free(b->propertyName); } free(b); } void JsonArrayRemoveRange( JsonElement *const array, const size_t start, const size_t end) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(end < SeqLength(array->container.children)); assert(start <= end); SeqRemoveRange(array->container.children, start, end); } const char *JsonArrayGetAsString(JsonElement *const array, const size_t index) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(index < SeqLength(array->container.children)); JsonElement *childPrimitive = SeqAt(array->container.children, index); if (childPrimitive != NULL) { assert(childPrimitive->type == JSON_ELEMENT_TYPE_PRIMITIVE); assert(childPrimitive->primitive.type == JSON_PRIMITIVE_TYPE_STRING); return childPrimitive->primitive.value; } return NULL; } JsonElement *JsonArrayGetAsObject(JsonElement *const array, const size_t index) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(index < SeqLength(array->container.children)); JsonElement *child = SeqAt(array->container.children, index); if (child != NULL) { assert(child->type == JSON_ELEMENT_TYPE_CONTAINER); assert(child->container.type == JSON_CONTAINER_TYPE_OBJECT); return child; } return NULL; } JsonElement *JsonArrayGet(const JsonElement *const array, const size_t index) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); return JsonAt(array, index); } bool JsonArrayContainsOnlyPrimitives(JsonElement *const array) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); for (size_t i = 0; i < JsonLength(array); i++) { JsonElement *child = JsonArrayGet(array, i); if (child->type != JSON_ELEMENT_TYPE_PRIMITIVE) { return false; } } return true; } void JsonContainerReverse(JsonElement *const array) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); SeqReverse(array->container.children); } // ******************************************************************************************* // Primitive Functions // ******************************************************************************************* JsonElement *JsonStringCreate(const char *const value) { assert(value != NULL); return JsonElementCreatePrimitive( JSON_PRIMITIVE_TYPE_STRING, xstrdup(value)); } JsonElement *JsonIntegerCreate(const int value) { char *buffer; xasprintf(&buffer, "%d", value); return JsonElementCreatePrimitive(JSON_PRIMITIVE_TYPE_INTEGER, buffer); } JsonElement *JsonIntegerCreate64(const int64_t value) { char *buffer; xasprintf(&buffer, "%" PRIi64, value); return JsonElementCreatePrimitive(JSON_PRIMITIVE_TYPE_INTEGER, buffer); } JsonElement *JsonRealCreate(double value) { if (isnan(value) || !isfinite(value)) { value = 0.0; } char *buffer = xcalloc(32, sizeof(char)); snprintf(buffer, 32, "%.4f", value); return JsonElementCreatePrimitive(JSON_PRIMITIVE_TYPE_REAL, buffer); } JsonElement *JsonBoolCreate(const bool value) { const char *const as_string = value ? JSON_TRUE : JSON_FALSE; return JsonElementCreatePrimitive(JSON_PRIMITIVE_TYPE_BOOL, as_string); } JsonElement *JsonNullCreate() { return JsonElementCreatePrimitive(JSON_PRIMITIVE_TYPE_NULL, JSON_NULL); } // ******************************************************************************************* // Printing // ******************************************************************************************* static void JsonContainerWrite( Writer *writer, const JsonElement *containerElement, size_t indent_level); static void JsonContainerWriteCompact( Writer *writer, const JsonElement *containerElement); static bool IsWhitespace(const char ch) { return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); } static bool IsSeparator(const char ch) { return IsWhitespace(ch) || ch == ',' || ch == ']' || ch == '}'; } static bool IsDigit(const char ch) { // [1,9] return (ch >= 49 && ch <= 57); } static void PrintIndent(Writer *const writer, const int num) { int i = 0; for (i = 0; i < num * SPACES_PER_INDENT; i++) { WriterWriteChar(writer, ' '); } } static void JsonPrimitiveWrite( Writer *const writer, const JsonElement *const primitiveElement, const size_t indent_level) { assert(primitiveElement != NULL); assert(primitiveElement->type == JSON_ELEMENT_TYPE_PRIMITIVE); const char *const value = primitiveElement->primitive.value; if (primitiveElement->primitive.type == JSON_PRIMITIVE_TYPE_STRING) { PrintIndent(writer, indent_level); { char *encoded = JsonEncodeString(value); WriterWriteF(writer, "\"%s\"", encoded); free(encoded); } } else { PrintIndent(writer, indent_level); WriterWrite(writer, value); } } static void JsonArrayWrite( Writer *const writer, const JsonElement *const array, const size_t indent_level) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(array->container.children != NULL); if (JsonLength(array) == 0) { WriterWrite(writer, "[]"); return; } WriterWrite(writer, "[\n"); Seq *const children = array->container.children; const size_t length = SeqLength(children); for (size_t i = 0; i < length; i++) { JsonElement *const child = SeqAt(children, i); switch (child->type) { case JSON_ELEMENT_TYPE_PRIMITIVE: JsonPrimitiveWrite(writer, child, indent_level + 1); break; case JSON_ELEMENT_TYPE_CONTAINER: PrintIndent(writer, indent_level + 1); JsonContainerWrite(writer, child, indent_level + 1); break; default: UnexpectedError("Unknown JSON element type: %d", child->type); } if (i < length - 1) { WriterWrite(writer, ",\n"); } else { WriterWrite(writer, "\n"); } } PrintIndent(writer, indent_level); WriterWriteChar(writer, ']'); } int JsonElementPropertyCompare( const void *const e1, const void *const e2, ARG_UNUSED void *const user_data) { assert(e1 != NULL); assert(e2 != NULL); return strcmp( ((JsonElement *) e1)->propertyName, ((JsonElement *) e2)->propertyName); } #ifndef NDEBUG // gcc would complain about unused function static bool all_children_have_keys(const JsonElement *const object) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); Seq *const children = object->container.children; const size_t length = SeqLength(children); for (size_t i = 0; i < length; i++) { const JsonElement *const child = SeqAt(children, i); if (child->propertyName == NULL) { return false; } } return true; } #endif void JsonObjectWrite( Writer *const writer, const JsonElement *const object, const size_t indent_level) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); assert(object->container.children != NULL); WriterWrite(writer, "{\n"); assert(all_children_have_keys(object)); // sort the children Seq so the output is canonical (keys are sorted) // we've already asserted that the children have a valid propertyName JsonSort(object, (JsonComparator *) JsonElementPropertyCompare, NULL); Seq *const children = object->container.children; const size_t length = SeqLength(children); for (size_t i = 0; i < length; i++) { JsonElement *child = SeqAt(children, i); PrintIndent(writer, indent_level + 1); assert(child->propertyName != NULL); WriterWriteF(writer, "\"%s\": ", child->propertyName); switch (child->type) { case JSON_ELEMENT_TYPE_PRIMITIVE: JsonPrimitiveWrite(writer, child, 0); break; case JSON_ELEMENT_TYPE_CONTAINER: JsonContainerWrite(writer, child, indent_level + 1); break; default: UnexpectedError("Unknown JSON element type: %d", child->type); } if (i < length - 1) { WriterWriteChar(writer, ','); } WriterWrite(writer, "\n"); } PrintIndent(writer, indent_level); WriterWriteChar(writer, '}'); } static void JsonContainerWrite( Writer *const writer, const JsonElement *const container, const size_t indent_level) { assert(container != NULL); assert(container->type == JSON_ELEMENT_TYPE_CONTAINER); switch (container->container.type) { case JSON_CONTAINER_TYPE_OBJECT: JsonObjectWrite(writer, container, indent_level); break; case JSON_CONTAINER_TYPE_ARRAY: JsonArrayWrite(writer, container, indent_level); } } void JsonWrite( Writer *const writer, const JsonElement *const element, const size_t indent_level) { assert(writer != NULL); assert(element != NULL); switch (element->type) { case JSON_ELEMENT_TYPE_CONTAINER: JsonContainerWrite(writer, element, indent_level); break; case JSON_ELEMENT_TYPE_PRIMITIVE: JsonPrimitiveWrite(writer, element, indent_level); break; default: UnexpectedError("Unknown JSON element type: %d", element->type); } } static void JsonArrayWriteCompact( Writer *const writer, const JsonElement *const array) { assert(array != NULL); assert(array->type == JSON_ELEMENT_TYPE_CONTAINER); assert(array->container.type == JSON_CONTAINER_TYPE_ARRAY); assert(array->container.children != NULL); if (JsonLength(array) == 0) { WriterWrite(writer, "[]"); return; } WriterWrite(writer, "["); Seq *const children = array->container.children; const size_t length = SeqLength(children); for (size_t i = 0; i < length; i++) { JsonElement *const child = SeqAt(children, i); assert(child != NULL); switch (child->type) { case JSON_ELEMENT_TYPE_PRIMITIVE: JsonPrimitiveWrite(writer, child, 0); break; case JSON_ELEMENT_TYPE_CONTAINER: JsonContainerWriteCompact(writer, child); break; default: UnexpectedError("Unknown JSON element type: %d", child->type); } if (i < length - 1) { WriterWrite(writer, ","); } } WriterWriteChar(writer, ']'); } static void JsonObjectWriteCompact( Writer *const writer, const JsonElement *const object) { assert(object != NULL); assert(object->type == JSON_ELEMENT_TYPE_CONTAINER); assert(object->container.type == JSON_CONTAINER_TYPE_OBJECT); WriterWrite(writer, "{"); assert(all_children_have_keys(object)); // sort the children Seq so the output is canonical (keys are sorted) // we've already asserted that the children have a valid propertyName JsonSort(object, (JsonComparator *) JsonElementPropertyCompare, NULL); Seq *const children = object->container.children; const size_t length = SeqLength(children); for (size_t i = 0; i < length; i++) { JsonElement *child = SeqAt(children, i); WriterWriteF(writer, "\"%s\":", child->propertyName); switch (child->type) { case JSON_ELEMENT_TYPE_PRIMITIVE: JsonPrimitiveWrite(writer, child, 0); break; case JSON_ELEMENT_TYPE_CONTAINER: JsonContainerWriteCompact(writer, child); break; default: UnexpectedError("Unknown JSON element type: %d", child->type); } if (i < length - 1) { WriterWriteChar(writer, ','); } } WriterWriteChar(writer, '}'); } static void JsonContainerWriteCompact( Writer *const writer, const JsonElement *const container) { assert(container != NULL); assert(container->type == JSON_ELEMENT_TYPE_CONTAINER); switch (container->container.type) { case JSON_CONTAINER_TYPE_OBJECT: JsonObjectWriteCompact(writer, container); break; case JSON_CONTAINER_TYPE_ARRAY: JsonArrayWriteCompact(writer, container); } } void JsonWriteCompact(Writer *const w, const JsonElement *const element) { assert(w != NULL); assert(element != NULL); switch (element->type) { case JSON_ELEMENT_TYPE_CONTAINER: JsonContainerWriteCompact(w, element); break; case JSON_ELEMENT_TYPE_PRIMITIVE: JsonPrimitiveWrite(w, element, 0); break; default: UnexpectedError("Unknown JSON element type: %d", element->type); } } // ******************************************************************************************* // Parsing // ******************************************************************************************* static JsonParseError JsonParseAsObject( void *lookup_context, JsonLookup *lookup_function, const char **data, JsonElement **json_out); static JsonElement *JsonParseAsBoolean(const char **const data) { assert(data != NULL); if (StringStartsWith(*data, "true")) { char next = *(*data + 4); if (IsSeparator(next) || next == '\0') { *data += 3; return JsonBoolCreate(true); } } else if (StringStartsWith(*data, "false")) { char next = *(*data + 5); if (IsSeparator(next) || next == '\0') { *data += 4; return JsonBoolCreate(false); } } return NULL; } static JsonElement *JsonParseAsNull(const char **const data) { assert(data != NULL); if (StringStartsWith(*data, "null")) { char next = *(*data + 4); if (IsSeparator(next) || next == '\0') { *data += 3; return JsonNullCreate(); } } return NULL; } const char *JsonParseErrorToString(const JsonParseError error) { assert(error < JSON_PARSE_ERROR_MAX); static const char *const parse_errors[JSON_PARSE_ERROR_MAX] = { [JSON_PARSE_OK] = "Success", [JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_START] = "Unable to parse json data as string, did not start with doublequote", [JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_END] = "Unable to parse json data as string, did not end with doublequote", [JSON_PARSE_ERROR_NUMBER_EXPONENT_NEGATIVE] = "Unable to parse json data as number, - not at the start or not after exponent", [JSON_PARSE_ERROR_NUMBER_EXPONENT_POSITIVE] = "Unable to parse json data as number, + without preceding exponent", [JSON_PARSE_ERROR_NUMBER_DUPLICATE_ZERO] = "Unable to parse json data as number, started with 0 before dot or exponent, duplicate 0 seen", [JSON_PARSE_ERROR_NUMBER_NO_DIGIT] = "Unable to parse json data as number, dot not preceded by digit", [JSON_PARSE_ERROR_NUMBER_MULTIPLE_DOTS] = "Unable to parse json data as number, two or more dots (decimal points)", [JSON_PARSE_ERROR_NUMBER_EXPONENT_DUPLICATE] = "Unable to parse json data as number, duplicate exponent", [JSON_PARSE_ERROR_NUMBER_EXPONENT_DIGIT] = "Unable to parse json data as number, exponent without preceding digit", [JSON_PARSE_ERROR_NUMBER_EXPONENT_FOLLOW_LEADING_ZERO] = "Unable to parse json data as number, dot or exponent must follow leading 0", [JSON_PARSE_ERROR_NUMBER_BAD_SYMBOL] = "Unable to parse json data as number, invalid symbol", [JSON_PARSE_ERROR_NUMBER_DIGIT_END] = "Unable to parse json data as string, did not end with digit", [JSON_PARSE_ERROR_ARRAY_START] = "Unable to parse json data as array, did not start with '['", [JSON_PARSE_ERROR_ARRAY_END] = "Unable to parse json data as array, did not end with ']'", [JSON_PARSE_ERROR_ARRAY_COMMA] = "Unable to parse json data as array, extraneous commas", [JSON_PARSE_ERROR_OBJECT_BAD_SYMBOL] = "Unable to parse json data as object, unrecognized token beginning entry", [JSON_PARSE_ERROR_OBJECT_START] = "Unable to parse json data as object, did not start with '{'", [JSON_PARSE_ERROR_OBJECT_END] = "Unable to parse json data as string, did not end with '}'", [JSON_PARSE_ERROR_OBJECT_COLON] = "Unable to parse json data as object, ':' seen without having specified an l-value", [JSON_PARSE_ERROR_OBJECT_COMMA] = "Unable to parse json data as object, ',' seen without having specified an r-value", [JSON_PARSE_ERROR_OBJECT_ARRAY_LVAL] = "Unable to parse json data as object, array not allowed as l-value", [JSON_PARSE_ERROR_OBJECT_OBJECT_LVAL] = "Unable to parse json data as object, object not allowed as l-value", [JSON_PARSE_ERROR_OBJECT_OPEN_LVAL] = "Unable to parse json data as object, tried to close object having opened an l-value", [JSON_PARSE_ERROR_INVALID_START] = "Unwilling to parse json data starting with invalid character", [JSON_PARSE_ERROR_INVALID_END] = "Unwilling to parse json data with trailing non-whitespace characters", [JSON_PARSE_ERROR_TRUNCATED] = "Unable to parse JSON without truncating", [JSON_PARSE_ERROR_NO_LIBYAML] = "CFEngine was not built with libyaml support", [JSON_PARSE_ERROR_LIBYAML_FAILURE] = "libyaml internal failure", [JSON_PARSE_ERROR_NO_SUCH_FILE] = "No such file or directory", [JSON_PARSE_ERROR_NO_DATA] = "No data"}; return parse_errors[error]; } static JsonParseError JsonParseAsString( const char **const data, char **const str_out) { assert(data != NULL); assert(*data != NULL); assert(str_out != NULL); /* NB: although JavaScript supports both single and double quotes * as string delimiters, JSON only supports double quotes. */ if (**data != '"') { *str_out = NULL; return JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_START; } Writer *writer = StringWriter(); for (*data = *data + 1; **data != '\0'; *data = *data + 1) { switch (**data) { case '"': *str_out = StringWriterClose(writer); return JSON_PARSE_OK; case '\\': *data = *data + 1; switch (**data) { case '\\': break; case '"': break; case '/': break; case 'b': WriterWriteChar(writer, '\b'); continue; case 'f': WriterWriteChar(writer, '\f'); continue; case 'n': WriterWriteChar(writer, '\n'); continue; case 'r': WriterWriteChar(writer, '\r'); continue; case 't': WriterWriteChar(writer, '\t'); continue; default: /* Unrecognised escape sequence. * * For example, we fail to handle Unicode escapes - * \u{hex digits} - we have no way to represent the * character they denote. So keep them verbatim, for * want of any other way to handle them; but warn. */ Log(LOG_LEVEL_DEBUG, "Keeping verbatim unrecognised JSON escape '%.6s'", *data - 1); // Include the \ in the displayed escape WriterWriteChar(writer, '\\'); break; } /* fall through */ default: WriterWriteChar(writer, **data); break; } } WriterClose(writer); *str_out = NULL; return JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_END; } JsonParseError JsonParseAsNumber( const char **const data, JsonElement **const json_out) { assert(data != NULL); assert(*data != NULL); assert(json_out != NULL); Writer *writer = StringWriter(); bool zero_started = false; bool seen_dot = false; bool seen_exponent = false; char prev_char = 0; for (*data = *data; **data != '\0' && !IsSeparator(**data); prev_char = **data, *data = *data + 1) { switch (**data) { case '-': if (prev_char != 0 && prev_char != 'e' && prev_char != 'E') { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_EXPONENT_NEGATIVE; } break; case '+': if (prev_char != 'e' && prev_char != 'E') { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_EXPONENT_POSITIVE; } break; case '0': if (zero_started && !seen_dot && !seen_exponent) { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_DUPLICATE_ZERO; } if (prev_char == 0) { zero_started = true; } break; case '.': if (seen_dot) { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_MULTIPLE_DOTS; } if (prev_char != '0' && !IsDigit(prev_char)) { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_NO_DIGIT; } seen_dot = true; break; case 'e': case 'E': if (seen_exponent) { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_EXPONENT_DUPLICATE; } else if (!IsDigit(prev_char) && prev_char != '0') { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_EXPONENT_DIGIT; } seen_exponent = true; break; default: if (zero_started && !seen_dot && !seen_exponent) { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_EXPONENT_FOLLOW_LEADING_ZERO; } if (!IsDigit(**data)) { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_BAD_SYMBOL; } break; } WriterWriteChar(writer, **data); } if (prev_char != '0' && !IsDigit(prev_char)) { *json_out = NULL; WriterClose(writer); return JSON_PARSE_ERROR_NUMBER_DIGIT_END; } // rewind 1 char so caller will see separator next *data = *data - 1; if (seen_dot) { *json_out = JsonElementCreatePrimitive( JSON_PRIMITIVE_TYPE_REAL, StringWriterClose(writer)); return JSON_PARSE_OK; } else { *json_out = JsonElementCreatePrimitive( JSON_PRIMITIVE_TYPE_INTEGER, StringWriterClose(writer)); return JSON_PARSE_OK; } } static JsonParseError JsonParseAsPrimitive( const char **const data, JsonElement **const json_out) { assert(json_out != NULL); assert(data != NULL); assert(*data != NULL); if (**data == '"') { char *value = NULL; const JsonParseError err = JsonParseAsString(data, &value); if (err != JSON_PARSE_OK) { return err; } *json_out = JsonElementCreatePrimitive( JSON_PRIMITIVE_TYPE_STRING, JsonDecodeString(value)); free(value); return JSON_PARSE_OK; } else { if (**data == '-' || **data == '0' || IsDigit(**data)) { const JsonParseError err = JsonParseAsNumber(data, json_out); if (err != JSON_PARSE_OK) { return err; } return JSON_PARSE_OK; } JsonElement *const child_bool = JsonParseAsBoolean(data); if (child_bool != NULL) { *json_out = child_bool; return JSON_PARSE_OK; } JsonElement *const child_null = JsonParseAsNull(data); if (child_null != NULL) { *json_out = child_null; return JSON_PARSE_OK; } *json_out = NULL; return JSON_PARSE_ERROR_OBJECT_BAD_SYMBOL; } } static JsonParseError JsonParseAsArray( void *const lookup_context, JsonLookup *const lookup_function, const char **const data, JsonElement **const json_out) { assert(json_out != NULL); assert(data != NULL); assert(*data != NULL); if (**data != '[') { *json_out = NULL; return JSON_PARSE_ERROR_ARRAY_START; } JsonElement *array = JsonArrayCreate(DEFAULT_CONTAINER_CAPACITY); char prev_char = '['; for (*data = *data + 1; **data != '\0'; *data = *data + 1) { if (IsWhitespace(**data)) { continue; } switch (**data) { case '"': { char *value = NULL; JsonParseError err = JsonParseAsString(data, &value); if (err != JSON_PARSE_OK) { return err; } JsonArrayAppendElement( array, JsonElementCreatePrimitive( JSON_PRIMITIVE_TYPE_STRING, JsonDecodeString(value))); free(value); } break; case '[': { if (prev_char != '[' && prev_char != ',') { JsonDestroy(array); return JSON_PARSE_ERROR_ARRAY_START; } JsonElement *child_array = NULL; JsonParseError err = JsonParseAsArray( lookup_context, lookup_function, data, &child_array); if (err != JSON_PARSE_OK) { JsonDestroy(array); return err; } assert(child_array); JsonArrayAppendArray(array, child_array); } break; case '{': { if (prev_char != '[' && prev_char != ',') { JsonDestroy(array); return JSON_PARSE_ERROR_ARRAY_START; } JsonElement *child_object = NULL; JsonParseError err = JsonParseAsObject( lookup_context, lookup_function, data, &child_object); if (err != JSON_PARSE_OK) { JsonDestroy(array); return err; } assert(child_object); JsonArrayAppendObject(array, child_object); } break; case ',': if (prev_char == ',' || prev_char == '[') { JsonDestroy(array); return JSON_PARSE_ERROR_ARRAY_COMMA; } break; case ']': *json_out = array; return JSON_PARSE_OK; default: if (**data == '-' || **data == '0' || IsDigit(**data)) { JsonElement *child = NULL; JsonParseError err = JsonParseAsNumber(data, &child); if (err != JSON_PARSE_OK) { JsonDestroy(array); return err; } assert(child); JsonArrayAppendElement(array, child); break; } JsonElement *child_bool = JsonParseAsBoolean(data); if (child_bool != NULL) { JsonArrayAppendElement(array, child_bool); break; } JsonElement *child_null = JsonParseAsNull(data); if (child_null != NULL) { JsonArrayAppendElement(array, child_null); break; } if (lookup_function != NULL) { JsonElement *child_ref = (*lookup_function)(lookup_context, data); if (child_ref != NULL) { JsonArrayAppendElement(array, child_ref); break; } } *json_out = NULL; JsonDestroy(array); return JSON_PARSE_ERROR_OBJECT_BAD_SYMBOL; } prev_char = **data; } *json_out = NULL; JsonDestroy(array); return JSON_PARSE_ERROR_ARRAY_END; } static bool wc(char c) { // word character, \w in regex return (isalnum(c) || c == '_'); } static const char *unquoted_key_with_colon(const char *data) { // Implements the regex: ^\w[-\w]*\s*: if (!wc(data[0])) { return NULL; } int i; for (i = 1; data[i] != '\0' && (data[i] == '-' || wc(data[i])); ++i) { // Skip past word characters (\w) and dashes } for (; data[i] != '\0' && IsWhitespace(data[i]); ++i) { // Skip past whitespace } if (data[i] != ':') { return NULL; } return data + i; } static JsonParseError JsonParseAsObject( void *const lookup_context, JsonLookup *const lookup_function, const char **const data, JsonElement **const json_out) { assert(json_out != NULL); assert(data != NULL); assert(*data != NULL); if (**data != '{') { *json_out = NULL; return JSON_PARSE_ERROR_ARRAY_START; } JsonElement *object = JsonObjectCreate(DEFAULT_CONTAINER_CAPACITY); char *property_name = NULL; char prev_char = '{'; for (*data = *data + 1; **data != '\0'; *data = *data + 1) { if (IsWhitespace(**data)) { continue; } switch (**data) { case '"': if (property_name != NULL) { char *property_value = NULL; JsonParseError err = JsonParseAsString(data, &property_value); if (err != JSON_PARSE_OK) { free(property_name); JsonDestroy(object); return err; } assert(property_value); JsonObjectAppendElement( object, property_name, JsonElementCreatePrimitive( JSON_PRIMITIVE_TYPE_STRING, JsonDecodeString(property_value))); free(property_value); free(property_name); property_name = NULL; } else { property_name = NULL; JsonParseError err = JsonParseAsString(data, &property_name); if (err != JSON_PARSE_OK) { JsonDestroy(object); return err; } assert(property_name); } break; case ':': if (property_name == NULL || prev_char == ':' || prev_char == ',') { *json_out = NULL; free(property_name); JsonDestroy(object); return JSON_PARSE_ERROR_OBJECT_COLON; } break; case ',': if (property_name != NULL || prev_char == ':' || prev_char == ',') { free(property_name); JsonDestroy(object); return JSON_PARSE_ERROR_OBJECT_COMMA; } break; case '[': if (property_name != NULL) { JsonElement *child_array = NULL; JsonParseError err = JsonParseAsArray( lookup_context, lookup_function, data, &child_array); if (err != JSON_PARSE_OK) { free(property_name); JsonDestroy(object); return err; } JsonObjectAppendArray(object, property_name, child_array); free(property_name); property_name = NULL; } else { free(property_name); JsonDestroy(object); return JSON_PARSE_ERROR_OBJECT_ARRAY_LVAL; } break; case '{': if (property_name != NULL) { JsonElement *child_object = NULL; JsonParseError err = JsonParseAsObject( lookup_context, lookup_function, data, &child_object); if (err != JSON_PARSE_OK) { free(property_name); JsonDestroy(object); return err; } JsonObjectAppendObject(object, property_name, child_object); free(property_name); property_name = NULL; } else { *json_out = NULL; free(property_name); JsonDestroy(object); return JSON_PARSE_ERROR_OBJECT_OBJECT_LVAL; } break; case '}': if (property_name != NULL) { *json_out = NULL; free(property_name); JsonDestroy(object); return JSON_PARSE_ERROR_OBJECT_OPEN_LVAL; } free(property_name); *json_out = object; return JSON_PARSE_OK; default: { const char *colon = NULL; // Note the character class excludes ':'. // This will match the key from { foo : 2 } but not { -foo: 2 } if (property_name == NULL && (colon = unquoted_key_with_colon(*data)) != NULL) { // Step backwards until we are on the last whitespace. // Note that this is safe because the above function guarantees // we will find at least one non-whitespace character as we // go backwards. const char *ws = colon; while (IsWhitespace(*(ws - 1))) { ws -= 1; } property_name = xstrndup(*data, ws - *data); *data = colon; break; } else if (property_name != NULL) { if (**data == '-' || **data == '0' || IsDigit(**data)) { JsonElement *child = NULL; JsonParseError err = JsonParseAsNumber(data, &child); if (err != JSON_PARSE_OK) { free(property_name); JsonDestroy(object); return err; } JsonObjectAppendElement(object, property_name, child); free(property_name); property_name = NULL; break; } JsonElement *child_bool = JsonParseAsBoolean(data); if (child_bool != NULL) { JsonObjectAppendElement(object, property_name, child_bool); free(property_name); property_name = NULL; break; } JsonElement *child_null = JsonParseAsNull(data); if (child_null != NULL) { JsonObjectAppendElement(object, property_name, child_null); free(property_name); property_name = NULL; break; } if (lookup_function != NULL) { JsonElement *child_ref = (*lookup_function)(lookup_context, data); if (child_ref != NULL) { JsonObjectAppendElement( object, property_name, child_ref); free(property_name); property_name = NULL; break; } } } *json_out = NULL; free(property_name); JsonDestroy(object); return JSON_PARSE_ERROR_OBJECT_BAD_SYMBOL; } // default } // switch prev_char = **data; } *json_out = NULL; free(property_name); JsonDestroy(object); return JSON_PARSE_ERROR_OBJECT_END; } JsonParseError JsonParse(const char **const data, JsonElement **const json_out) { return JsonParseWithLookup(NULL, NULL, data, json_out); } JsonParseError JsonParseAll(const char **const data, JsonElement **const json_out) { JsonParseError error = JsonParseWithLookup(NULL, NULL, data, json_out); if (error == JSON_PARSE_OK && **data != '\0') { /* The parser has advanced the data pointer up to the last byte * processed. Thus every subsequent character until the nullbyte * should be whitespace. */ for (const char *ch = (*data) + 1; *ch != '\0'; ch++) { if (isspace(*ch)) { continue; } JsonDestroy(*json_out); *json_out = NULL; return JSON_PARSE_ERROR_INVALID_END; } } return error; } JsonParseError JsonParseWithLookup( void *const lookup_context, JsonLookup *const lookup_function, const char **const data, JsonElement **const json_out) { assert(data != NULL); assert(*data != NULL); if (data == NULL || *data == NULL) { return JSON_PARSE_ERROR_NO_DATA; } while (**data) { if (**data == '{') { return JsonParseAsObject( lookup_context, lookup_function, data, json_out); } else if (**data == '[') { return JsonParseAsArray( lookup_context, lookup_function, data, json_out); } else if (IsWhitespace(**data)) { (*data)++; } else { return JsonParseAsPrimitive(data, json_out); } } return JSON_PARSE_ERROR_NO_DATA; } JsonParseError JsonParseAnyFile( const char *const path, const size_t size_max, JsonElement **const json_out, const bool yaml_format) { assert(json_out != NULL); bool truncated = false; Writer *contents = FileRead(path, size_max, &truncated); if (contents == NULL) { return JSON_PARSE_ERROR_NO_SUCH_FILE; } else if (truncated) { return JSON_PARSE_ERROR_TRUNCATED; } assert(json_out); *json_out = NULL; const char *data = StringWriterData(contents); JsonParseError err; if (yaml_format) { err = JsonParseYamlString(&data, json_out); } else { err = JsonParse(&data, json_out); } WriterClose(contents); return err; } JsonParseError JsonParseFile( const char *const path, const size_t size_max, JsonElement **const json_out) { return JsonParseAnyFile(path, size_max, json_out, false); } bool JsonWalk(JsonElement *element, JsonElementVisitor object_visitor, JsonElementVisitor array_visitor, JsonElementVisitor primitive_visitor, void *data) { assert(element != NULL); if (element->type == JSON_ELEMENT_TYPE_PRIMITIVE) { if (primitive_visitor != NULL) { return primitive_visitor(element, data); } else { return true; } } assert(element->type == JSON_ELEMENT_TYPE_CONTAINER); if (element->container.type == JSON_CONTAINER_TYPE_ARRAY) { if (array_visitor != NULL) { bool keep_going = array_visitor(element, data); if (!keep_going) { return false; } } } else { assert(element->container.type == JSON_CONTAINER_TYPE_OBJECT); if (object_visitor != NULL) { bool keep_going = object_visitor(element, data); if (!keep_going) { return false; } } } bool keep_going = true; JsonIterator iter = JsonIteratorInit(element); while (keep_going && JsonIteratorHasMore(&iter)) { JsonElement *child = JsonIteratorNextValue(&iter); keep_going = JsonWalk(child, object_visitor, array_visitor, primitive_visitor, data); } return keep_going; } bool JsonErrorVisitor(ARG_UNUSED JsonElement *element, ARG_UNUSED void *data) { return false; } /*******************************************************************/ #ifdef WITH_PCRE2 #include // returns NULL on any failure // takes either a pre-compiled pattern OR a regex (one of the two shouldn't be // NULL) JsonElement *StringCaptureData( const Regex *const regex, const char *const pattern, const char *const data) { assert(regex != NULL || pattern != NULL); assert(data != NULL); Seq *s; if (regex != NULL) { s = StringMatchCapturesWithPrecompiledRegex(regex, data, true); } else { s = StringMatchCaptures(pattern, data, true); } const size_t length = (s != NULL) ? SeqLength(s) : 0; if (length == 0) { SeqDestroy(s); return NULL; } JsonElement *json = JsonObjectCreate(length / 2); for (size_t i = 1; i < length; i += 2) { Buffer *key = SeqAt(s, i - 1); Buffer *value = SeqAt(s, i); JsonObjectAppendString(json, BufferData(key), BufferData(value)); } SeqDestroy(s); JsonObjectRemoveKey(json, "0"); return json; } #endif // WITH_PCRE2 cfengine-3.24.2/libntech/libutils/regex.h0000644000000000000000000000474215010704321020260 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_REGEX_H #define CFENGINE_REGEX_H #include // bool /* Set by ./configure allowing us to avoid #include here. */ #define WITH_PCRE2 1 #ifdef WITH_PCRE2 #define PCRE2_CODE_UNIT_WIDTH 8 #include #else #error "Regex functionality requires PCRE2" #endif #include /* Seq */ /** * @note: The definition of the type Regex may change in the future, so code * using this header should avoid using pcre2_code and use Regex instead * and use RegexDestroy() instead of pcre2_code_free(). */ typedef pcre2_code Regex; #define CFENGINE_REGEX_WHITESPACE_IN_CONTEXTS ".*[_A-Za-z0-9][ \\t]+[_A-Za-z0-9].*" /* Try to use CompileRegex() and StringMatchWithPrecompiledRegex(). */ Regex *CompileRegex(const char *pattern); void RegexDestroy(Regex *regex); bool StringMatch(const char *pattern, const char *str, size_t *start, size_t *end); bool StringMatchWithPrecompiledRegex(const Regex *regex, const char *str, size_t *start, size_t *end); bool StringMatchFull(const char *pattern, const char *str); bool StringMatchFullWithPrecompiledRegex(const Regex *regex, const char *str); Seq *StringMatchCaptures(const char *pattern, const char *str, const bool return_names); Seq *StringMatchCapturesWithPrecompiledRegex(const Regex *pattern, const char *str, const bool return_names); bool CompareStringOrRegex(const char *value, const char *compareTo, bool regex); /* Does not free rx! */ bool RegexPartialMatch(const Regex *regex, const char *teststring); #endif /* CFENGINE_REGEX_H */ cfengine-3.24.2/libntech/libutils/xml_writer.h0000644000000000000000000000335015010704254021341 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_XML_WRITER_H #define CFENGINE_XML_WRITER_H #include typedef struct { const char *name; const char *value; } XmlAttribute; void XmlComment(Writer *writer, const char *comment); /* INSERT START XML ELEMENT -> */ /* TAKE PARAM attr_cnt, STRUCT XmlAttribute, STRUCT XmlAttribute ... */ void XmlStartTag(Writer *writer, const char *tag_name, int attr_cnt, ...); void XmlEndTag(Writer *writer, const char *tag_name); /* INSERT XML TAG -> value */ /* TAKE PARAM attr_cnt, STRUCT XmlAttribute, STRUCT XmgAttribute ... */ void XmlTag(Writer *writer, const char *tag_name, const char *value, int attr_cnt, ...); /* String content, properly escaped */ void XmlContent(Writer *writer, const char *value); #endif cfengine-3.24.2/libntech/libutils/map.c0000644000000000000000000001736015010704254017723 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include /* * This associative array implementation uses array with linear search up to * TINY_LIMIT elements, and then converts into full-fledged hash table with open * addressing. * * There is a lot of small hash tables, both iterating and deleting them as a * hashtable takes a lot of time, especially given associative hash tables are * created and destroyed for each scope entered and left. */ /* FIXME: make configurable */ #define DEFAULT_HASHMAP_INIT_SIZE 128 struct Map_ { MapHashFn hash_fn; union { ArrayMap *arraymap; HashMap *hashmap; }; }; static unsigned IdentityHashFn(const void *ptr, ARG_UNUSED unsigned int seed) { return (unsigned)(uintptr_t)ptr; } static bool IdentityEqualFn(const void *p1, const void *p2) { return p1 == p2; } static void NopDestroyFn(ARG_UNUSED void *p1) { } /* * hash_fn is used as a flag "this map uses ArrayMap still". We could have a * separate boolean flag for that, but given we have to store hash_fn somewhere * anyway, let's reuse it this way. Saves us 4-8 bytes for each map. */ static bool IsArrayMap(const Map *map) { assert(map != NULL); return map->hash_fn != NULL; } Map *MapNew(MapHashFn hash_fn, MapKeyEqualFn equal_fn, MapDestroyDataFn destroy_key_fn, MapDestroyDataFn destroy_value_fn) { if (hash_fn == NULL) { hash_fn = &IdentityHashFn; } if (equal_fn == NULL) { equal_fn = &IdentityEqualFn; } if (destroy_key_fn == NULL) { destroy_key_fn = &NopDestroyFn; } if (destroy_value_fn == NULL) { destroy_value_fn = &NopDestroyFn; } Map *map = xcalloc(1, sizeof(Map)); map->arraymap = ArrayMapNew(equal_fn, destroy_key_fn, destroy_value_fn); map->hash_fn = hash_fn; return map; } size_t MapSize(const Map *map) { assert(map != NULL); if (IsArrayMap(map)) { return map->arraymap->size; } else { return map->hashmap->load; } } static void ConvertToHashMap(Map *map) { assert(map != NULL); HashMap *hashmap = HashMapNew(map->hash_fn, map->arraymap->equal_fn, map->arraymap->destroy_key_fn, map->arraymap->destroy_value_fn, DEFAULT_HASHMAP_INIT_SIZE); /* We have to use internals of ArrayMap here, as we don't want to destroy the values in ArrayMapDestroy */ for (int i = 0; i < map->arraymap->size; ++i) { HashMapInsert(hashmap, map->arraymap->values[i].key, map->arraymap->values[i].value); } free(map->arraymap->values); free(map->arraymap); map->hashmap = hashmap; map->hash_fn = NULL; } bool MapInsert(Map *map, void *key, void *value) { assert(map != NULL); /* MapGet() is not capable of handling NULL values. */ assert(key != NULL); assert(value != NULL); if (IsArrayMap(map)) { int ret = ArrayMapInsert(map->arraymap, key, value); if (ret != 0) { /* Return true if value was replaced, false if key-value was * inserted as new. */ return (ret == 1); } /* Does not fit in ArrayMap, must convert to HashMap. */ ConvertToHashMap(map); } return HashMapInsert(map->hashmap, key, value); } /* * The best we can get out of C type system. Caller should make sure that if * argument is const, it does not modify the result. */ static MapKeyValue *MapGetRaw(const Map *map, const void *key) { assert(map != NULL); if (IsArrayMap(map)) { return ArrayMapGet((ArrayMap *)map->arraymap, key); } else { return HashMapGet((HashMap *)map->hashmap, key); } } bool MapHasKey(const Map *map, const void *key) { assert(map != NULL); assert(key != NULL); return MapGetRaw(map, key) != NULL; } /* NULL return means not found, or value was NULL! TODO fix, it should only * mean one thing. I added the assert() to make sure we never store NULL * values. */ void *MapGet(Map *map, const void *key) { assert(map != NULL); MapKeyValue *kv = MapGetRaw(map, key); if (kv != NULL) { assert(kv->value != NULL); return kv->value; } return NULL; } bool MapRemove(Map *map, const void *key) { assert(map != NULL); if (IsArrayMap(map)) { return ArrayMapRemove(map->arraymap, key); } else { return HashMapRemove(map->hashmap, key); } } void MapClear(Map *map) { assert(map != NULL); if (IsArrayMap(map)) { ArrayMapClear(map->arraymap); } else { HashMapClear(map->hashmap); } } void MapSoftDestroy(Map *map) { if (map) { if (IsArrayMap(map)) { ArrayMapSoftDestroy(map->arraymap); } else { HashMapSoftDestroy(map->hashmap); } free(map); } } void MapDestroy(Map *map) { if (map) { if (IsArrayMap(map)) { ArrayMapDestroy(map->arraymap); } else { HashMapDestroy(map->hashmap); } free(map); } } bool MapContainsSameKeys(const Map *map1, const Map *map2) { assert(map1 != NULL); assert(map2 != NULL); MapIterator i = MapIteratorInit((Map *)map1); MapKeyValue *item; size_t count = 0; while ((item = MapIteratorNext(&i))) { count++; if (!MapHasKey(map2, item->key)) { return false; } } return (count == MapSize(map2)); } void MapPrintStats(const Map *map, FILE *f) { assert(map != NULL); fprintf(f, "================ Map statistics ================\n"); if (IsArrayMap(map)) { fprintf(f, "Map is too small, fits in a small array.\n"); } else { HashMapPrintStats(map->hashmap, f); } fprintf(f, "================================================\n"); } /******************************************************************************/ MapIterator MapIteratorInit(Map *map) { assert(map != NULL); MapIterator i; if (IsArrayMap(map)) { i.is_array = true; i.arraymap_iter = ArrayMapIteratorInit(map->arraymap); } else { i.is_array = false; i.hashmap_iter = HashMapIteratorInit(map->hashmap); } return i; } MapKeyValue *MapIteratorNext(MapIterator *i) { if (i->is_array) { return ArrayMapIteratorNext(&i->arraymap_iter); } else { return HashMapIteratorNext(&i->hashmap_iter); } } TYPED_MAP_DEFINE(String, char *, char *, StringHash_untyped, StringEqual_untyped, &free, &free) cfengine-3.24.2/libntech/libutils/printsize.h0000644000000000000000000000575015010704254021202 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PRINTSIZE_H #define CFENGINE_PRINTSIZE_H /** Size of buffer needed to sprintf() an integral value. * * The constant 53/22 is a (very slightly) high approximation to * log(256)/log(10), the number of decimal digits needed per byte of * the value. The offset of 3 accounts for: rounding details, the * '\0' you need at the end of the buffer and the sign. The last is a * wasted byte when using "%u", but it's simpler this way ! * * This macro should be preferred over using a char [64] buffer (or * 128 or 32 or whatever guess you've made at "big enough") and * trusting that your integer shall fit - for now it saves wasting * stack space; one day it may even (when we have bigger integral * types) save us a buffer over-run. Limitation: if CHAR_BIT ever * isn't 8, we should change the / 22 to * CHAR_BIT / 176. * * This deals with the simple case of a "%d", possibly with type * modifiers (jhzl, etc.) or sign (%+d). If you're using fancier * modifiers (e.g. field-width), you need to think about what effect * they have on the print width (max of field-width and this macro); * if there is other text in your format, you need to allow space for * it, too. * * If you are casting the value to be formatted (e.g. because there's * no modifier for its type), applying this macro to the value shall * get the maximum size that a %d-based format can produce for it (its * value can't be any bigger, even if it's cast to a huge type); but, * if you're using a %u-based format and the value is signed, you * should call this macro on the type to which you're casting it * (because, if it's negative, it'll wrap to a huge value of the cast * type). * * @param #what The integral expression or its type. Is not evaluated * at run-time, only passed to sizeof() at compile-time. * * @return The size for a buffer big enough to hold sprintf()'s * representation of an integer of this type. This is a compile-time * constant, so can be used in static array declarations or struct * member array declarations. */ #define PRINTSIZE(what) (3 + 53 * sizeof(what) / 22) #endif /* CFENGINE_PRINTSIZE_H */ cfengine-3.24.2/libntech/libutils/rb-tree.h0000644000000000000000000000452315010704254020510 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_RB_TREE_H #define CFENGINE_RB_TREE_H #include #include /* size_t */ typedef struct RBTree_ RBTree; typedef struct RBTreeIterator_ RBTreeIterator; typedef void *RBTreeKeyCopyFn(const void *key); typedef int RBTreeKeyCompareFn(const void *a, const void *b); typedef void RBTreeKeyDestroyFn(void *key); typedef void *RBTreeValueCopyFn(const void *key); typedef int RBTreeValueCompareFn(const void *a, const void *b); typedef void RBTreeValueDestroyFn(void *key); typedef bool RBTreePredicate(const void *key, const void *value, void *user_data); RBTree *RBTreeNew(RBTreeKeyCopyFn *key_copy, RBTreeKeyCompareFn *key_compare, RBTreeKeyDestroyFn *key_destroy, RBTreeValueCopyFn *value_copy, RBTreeValueCompareFn *value_compare, RBTreeValueDestroyFn *value_destroy); RBTree *RBTreeCopy(const RBTree *tree, RBTreePredicate *filter, void *user_data); bool RBTreeEqual(const void *a, const void *b); void RBTreeDestroy(void *rb_tree); bool RBTreePut(RBTree *tree, const void *key, const void *value); void *RBTreeGet(const RBTree *tree, const void *key); bool RBTreeRemove(RBTree *tree, const void *key); void RBTreeClear(RBTree *tree); size_t RBTreeSize(const RBTree *tree); RBTreeIterator *RBTreeIteratorNew(const RBTree *tree); bool RBTreeIteratorNext(RBTreeIterator *iter, void **key, void **value); void RBTreeIteratorDestroy(void *_rb_iter); #endif cfengine-3.24.2/libntech/libutils/stack.h0000644000000000000000000000654015010704254020256 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_STACK_H #define CFENGINE_STACK_H #include // size_t typedef struct Stack_ Stack; /** @brief Creates a new stack with specified capacity. @param [in] initial_capacity Initial capacity, defaults to 1. @param [in] ItemDestroy Function used to destroy data elements. */ Stack *StackNew(size_t initial_capacity, void (*ItemDestroy) ()); /** @brief Destroys the stack and frees the memory it occupies. @param [in] stack The stack to destroy. @warning Stack should only be destroyed if all threads are joined */ void StackDestroy(Stack *stack); /** @brief Frees the memory allocated for the data pointer and the struct itself. @param [in] stack The stack to free. */ void StackSoftDestroy(Stack *stack); /** @brief Returns and removes the last element added to the stack. @note Will return NULL if stack is empty. @param [in] stack The stack to pop from. @return A pointer to the last data added. */ void *StackPop(Stack *stack); /** @brief Returns the last element added to the stack, without removing it. @note Will return NULL if stack is empty. @param [in] stack The stack to pop from. @return A pointer to the last data added. */ void *StackTop(Stack *stack); /** @brief Adds a new item on top of the stack. @param [in] stack The stack to push to. @param [in] item The item to push. */ void StackPush(Stack *stack, void *item); /** @brief Adds a new item on top of the stack and returns the current size. @param [in] stack The stack to push to. @param [in] item The item to push. @return The amount of elements in the stack. */ size_t StackPushReportCount(Stack *stack, void *item); /** @brief Get current number of items in stack. @note On NULL stack, returns 0. @param [in] stack The stack. @return The amount of elements in the stack. */ size_t StackCount(Stack const *stack); /** @brief Get current capacity of stack. @note On NULL stack, returns 0. @param [in] stack The stack. @return The current capacity of the stack. */ size_t StackCapacity(Stack const *stack); /** @brief Create a shallow copy of a given stack. @note This makes a new stack pointing to the same memory as the old stack. @param [in] stack The stack. @return A new stack pointing to the same data. */ Stack *StackCopy(Stack const *stack); /** @brief Checks if a stack is empty. @param [in] stack The stack. @return Returns true if stack is empty, false otherwise. */ bool StackIsEmpty(Stack const *stack); #endif cfengine-3.24.2/libntech/libutils/buffer.c0000644000000000000000000006136115010704254020417 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #ifdef WITH_PCRE2 #define PCRE2_CODE_UNIT_WIDTH 8 #include #endif #include #include Buffer *BufferNewWithCapacity(size_t initial_capacity) { Buffer *buffer = xmalloc(sizeof(Buffer)); buffer->capacity = initial_capacity; buffer->buffer = xmalloc(buffer->capacity); buffer->buffer[0] = '\0'; buffer->mode = BUFFER_BEHAVIOR_CSTRING; buffer->used = 0; return buffer; } Buffer *BufferNew(void) { return BufferNewWithCapacity(DEFAULT_BUFFER_CAPACITY); } static void ExpandIfNeeded(Buffer *buffer, size_t needed) { assert(buffer != NULL); if (needed >= buffer->capacity) { size_t new_capacity = UpperPowerOfTwo(needed + 1); buffer->buffer = xrealloc(buffer->buffer, new_capacity); buffer->capacity = new_capacity; } } Buffer* BufferNewFrom(const char *data, size_t length) { Buffer *buffer = BufferNewWithCapacity(length + 1); BufferAppend(buffer, data, length); return buffer; } void BufferDestroy(Buffer *buffer) { if (buffer != NULL) { free(buffer->buffer); free(buffer); } } char *BufferClose(Buffer *buffer) { assert(buffer != NULL); char *detached = buffer->buffer; free(buffer); return detached; } Buffer *BufferCopy(const Buffer *source) { assert(source != NULL); return BufferNewFrom(source->buffer, source->used); } int BufferCompare(const Buffer *buffer1, const Buffer *buffer2) { assert(buffer1 != NULL); assert(buffer2 != NULL); /* * Rules for comparison: * 2. Check the content * 2.1. If modes are different, check until the first '\0' * 2.2. If sizes are different, check until the first buffer ends. */ if (buffer1->mode == buffer2->mode) { if (buffer1->mode == BUFFER_BEHAVIOR_CSTRING) { /* * C String comparison */ // Adding this as strcmp gives difference of the buffer values in aarch64 // Whereas it gives 1, 0 or -1 in other platforms accordingly. int compare_result = strcmp(buffer1->buffer, buffer2->buffer); if (compare_result != 0) { compare_result = compare_result / abs(compare_result); } return compare_result; } else { /* * BUFFER_BEHAVIOR_BYTEARRAY * Byte by byte comparison */ size_t i = 0; if (buffer1->used < buffer2->used) { for (i = 0; i < buffer1->used; ++i) { if (buffer1->buffer[i] < buffer2->buffer[i]) { return -1; } else if (buffer1->buffer[i] > buffer2->buffer[i]) { return 1; } } return -1; } else if (buffer1->used == buffer2->used) { for (i = 0; i < buffer1->used; ++i) { if (buffer1->buffer[i] < buffer2->buffer[i]) { return -1; } else if (buffer1->buffer[i] > buffer2->buffer[i]) { return 1; } } } else { for (i = 0; i < buffer2->used; ++i) { if (buffer1->buffer[i] < buffer2->buffer[i]) { return -1; } else if (buffer1->buffer[i] > buffer2->buffer[i]) { return 1; } } return 1; } } } else { /* * Mixed comparison * Notice that every BYTEARRAY was born as a CSTRING. * When we switch back to CSTRING we adjust the length to * match the first '\0'. */ size_t i = 0; if (buffer1->used < buffer2->used) { for (i = 0; i < buffer1->used; ++i) { if (buffer1->buffer[i] < buffer2->buffer[i]) { return -1; } else if (buffer1->buffer[i] > buffer2->buffer[i]) { return 1; } } return -1; } else if (buffer1->used == buffer2->used) { for (i = 0; i < buffer1->used; ++i) { if (buffer1->buffer[i] < buffer2->buffer[i]) { return -1; } else if (buffer1->buffer[i] > buffer2->buffer[i]) { return 1; } } } else { for (i = 0; i < buffer2->used; ++i) { if (buffer1->buffer[i] < buffer2->buffer[i]) { return -1; } else if (buffer1->buffer[i] > buffer2->buffer[i]) { return 1; } } return 1; } } /* * We did all we could and the buffers seems to be equal. */ return 0; } void BufferSet(Buffer *buffer, const char *bytes, size_t length) { assert(buffer != NULL); assert(bytes != NULL); BufferClear(buffer); BufferAppend(buffer, bytes, length); } char *BufferGet(Buffer *buffer) { assert(buffer != NULL); buffer->unsafe = true; return buffer->buffer; } void BufferAppendString(Buffer *buffer, const char *str) { assert(buffer != NULL); size_t len = strlen(str); ExpandIfNeeded(buffer, buffer->used + len + 1); memcpy(buffer->buffer + buffer->used, str, len); buffer->used += len; buffer->buffer[buffer->used] = '\0'; } void BufferTrimToMaxLength(Buffer *buffer, size_t max) { assert(buffer != NULL); if (buffer->used > max) { buffer->used = max; // no need to call ExpandIfNeeded buffer->buffer[buffer->used] = '\0'; } } void BufferAppend(Buffer *buffer, const char *bytes, size_t length) { assert(buffer != NULL); assert(bytes != NULL); if (length == 0) { return; } switch (buffer->mode) { case BUFFER_BEHAVIOR_CSTRING: { size_t actual_length = strnlen(bytes, length); ExpandIfNeeded(buffer, buffer->used + actual_length + 1); memcpy(buffer->buffer + buffer->used, bytes, actual_length); buffer->used += actual_length; buffer->buffer[buffer->used] = '\0'; } break; case BUFFER_BEHAVIOR_BYTEARRAY: ExpandIfNeeded(buffer, buffer->used + length); memcpy(buffer->buffer + buffer->used, bytes, length); buffer->used += length; break; } } void BufferAppendChar(Buffer *buffer, char byte) { assert(buffer != NULL); if (buffer->used < (buffer->capacity - 1)) { buffer->buffer[buffer->used] = byte; buffer->used++; if (buffer->mode == BUFFER_BEHAVIOR_CSTRING) { buffer->buffer[buffer->used] = '\0'; } } else { BufferAppend(buffer, &byte, 1); } } void BufferAppendF(Buffer *buffer, const char *format, ...) { assert(buffer != NULL); assert(format != NULL); va_list ap; va_list aq; va_start(ap, format); va_copy(aq, ap); int printed = vsnprintf(buffer->buffer + buffer->used, buffer->capacity - buffer->used, format, aq); assert(printed >= 0); if ((size_t) printed >= (buffer->capacity - buffer->used)) { /* * Allocate a larger buffer and retry. * Now is when having a copy of the list pays off :-) */ ExpandIfNeeded(buffer, buffer->used + printed); printed = vsnprintf(buffer->buffer + buffer->used, buffer->capacity - buffer->used, format, ap); buffer->used += printed; } else { buffer->used += printed; } va_end(aq); va_end(ap); } int BufferPrintf(Buffer *buffer, const char *format, ...) { assert(buffer != NULL); assert(format != NULL); /* * We declare two lists, in case we need to reiterate over the list because the buffer was * too small. */ va_list ap; va_list aq; va_start(ap, format); va_copy(aq, ap); /* * We don't know how big of a buffer we will need. It might be that we have enough space * or it might be that we don't have enough space. Unfortunately, we cannot reiterate over * a va_list, so our only solution is to tell the caller to retry the call. We signal this * by returning zero. Before doing that we increase the buffer to a suitable size. * The tricky part is the implicit sharing and the reference counting, if we are not shared then * everything is easy, however if we are shared then we need a different strategy. */ int printed = vsnprintf(buffer->buffer, buffer->capacity, format, aq); if (printed < 0) { // vsnprintf failed! } else if ((size_t) printed >= buffer->capacity) { /* * Allocate a larger buffer and retry. * Now is when having a copy of the list pays off :-) */ ExpandIfNeeded(buffer, printed); buffer->used = 0; printed = vsnprintf(buffer->buffer, buffer->capacity, format, ap); buffer->used = printed; } else { buffer->used = printed; } va_end(aq); va_end(ap); return printed; } // NB! Make sure to sanitize format if taken from user input int BufferVPrintf(Buffer *buffer, const char *format, va_list ap) { assert(buffer != NULL); assert(format != NULL); va_list aq; va_copy(aq, ap); /* * We don't know how big of a buffer we will need. It might be that we have enough space * or it might be that we don't have enough space. Unfortunately, we cannot reiterate over * a va_list, so our only solution is to tell the caller to retry the call. We signal this * by returning zero. Before doing that we increase the buffer to a suitable size. * The tricky part is the implicit sharing and the reference counting, if we are not shared then * everything is easy, however if we are shared then we need a different strategy. */ int printed = vsnprintf(buffer->buffer, buffer->capacity, format, aq); if (printed < 0) { // vsnprintf failed! } else if ((size_t) printed >= buffer->capacity) { ExpandIfNeeded(buffer, printed); buffer->used = 0; printed = vsnprintf(buffer->buffer, buffer->capacity, format, ap); buffer->used = printed; } else { buffer->used = printed; } va_end(aq); return printed; } #ifdef WITH_PCRE2 static char *ExpandCFESpecialReplacements(const pcre2_code *regex, const char *orig_str, size_t orig_str_len, pcre2_match_data *md, const char *substitute) { /* pcre2_substitute() supports '$n' backreferences in the substitution * string, but not '\n' so we need to translate '\n' into '$n'. */ /* And the regex_replace() CFEngine policy function needs this: * In addition, $+ is replaced with the capture count. $' (dollar sign + * single quote) is the part of the string after the regex match. $` * (dollar sign + backtick) is the part of the string before the regex * match. $& holds the entire regex match. * * Moreover, according to the function's acceptance tests, backreferences * with no respective capture group should be replaced with empty strings. */ bool has_special_seq = false; bool has_backslash_bref = false; int highest_bref = -1; for (const char *c = substitute; *c != '\0'; c++) { if ((c[0] == '$') && ((c[1] == '+') || (c[1] == '`') || (c[1] == '\'') || (c[1] == '&'))) { has_special_seq = true; } else if ((c[0] == '\\') && isdigit(c[1])) { has_backslash_bref = true; if ((c[1] - '0') > highest_bref) { highest_bref = c[1] - '0'; } } else if ((c[0] == '$') && isdigit(c[1]) && ((c[1] - '0') > highest_bref)) { highest_bref = c[1] - '0'; } } uint32_t n_captures_info = 0; NDEBUG_UNUSED int ret = pcre2_pattern_info(regex, PCRE2_INFO_CAPTURECOUNT, &n_captures_info); assert(ret == 0); /* can't really fail */ /* for signed comparisons */ int n_captures = n_captures_info; if (!has_special_seq && !has_backslash_bref && (highest_bref <= n_captures)) { /* nothing to do */ return NULL; } /* else we probably need to do some replacements */ size_t subst_len = strlen(substitute); Buffer *new_subst_buf; /* First, let's replace the special $-sequences. */ if (has_special_seq) { new_subst_buf = BufferNewWithCapacity(subst_len); size_t *ovec = pcre2_get_ovector_pointer(md); const char *match_start = orig_str + ovec[0]; const char *match_end = orig_str + ovec[1]; const char *dollar = strchr(substitute, '$'); const char *subst_offset = substitute; while (dollar != NULL) { if (dollar[1] == '+') { BufferAppend(new_subst_buf, subst_offset, dollar - subst_offset); BufferAppendF(new_subst_buf, "%"PRIu32, n_captures); subst_offset = dollar + 2; } else if (dollar[1] == '`') { BufferAppend(new_subst_buf, subst_offset, dollar - subst_offset); BufferAppend(new_subst_buf, orig_str, match_start - orig_str); subst_offset = dollar + 2; } else if (dollar[1] == '\'') { BufferAppend(new_subst_buf, subst_offset, dollar - subst_offset); BufferAppend(new_subst_buf, match_end, (orig_str + orig_str_len) - match_end); subst_offset = dollar + 2; } else if (dollar[1] == '&') { BufferAppend(new_subst_buf, subst_offset, dollar - subst_offset); BufferAppend(new_subst_buf, match_start, match_end - match_start); subst_offset = dollar + 2; } /* else a $-sequence we don't care about here */ dollar = strchr(dollar + 1, '$'); } BufferAppend(new_subst_buf, subst_offset, (substitute + subst_len) - subst_offset); } else { new_subst_buf = BufferNewFrom(substitute, subst_len); } /* Now, let's deal with the \n sequences (if any)*/ char *buf_data = BufferGet(new_subst_buf); if (has_backslash_bref) { /* start with the first backslash in the substitute copy */ char *backslash = strchr(buf_data, '\\'); assert(backslash != NULL); /* must still be there */ do { /* it's safe to check the byte after the backslash because it will * either be the next character or the NUL byte */ if (isdigit(backslash[1])) { backslash[0] = '$'; } backslash = strchr(backslash + 1, '\\'); } while (backslash != NULL); } /* Finally, remove the backreferences with no respective capture groups */ if (highest_bref > n_captures) { subst_len = BufferSize(new_subst_buf); size_t i = 0; /* first, skip the part before the first '$' */ while ((i < subst_len) && (buf_data[i] != '$')) { i++; } assert(i < subst_len); /* there must be a '$' if highest_bref > n_captures */ /* now, delete all invalid backrefs */ size_t offset = 0; while (i < subst_len) { if ((buf_data[i] == '$') && isdigit(buf_data[i + 1]) && (atoi(buf_data + i + 1) > n_captures)) { /* skip the '$' */ i++; offset++; while (isdigit(buf_data[i])) { /* skip the number */ i++; offset++; } } else { /* just copy the character and move to the next one */ buf_data[i - offset] = buf_data[i]; i++; } } BufferTrimToMaxLength(new_subst_buf, subst_len - offset); } return BufferClose(new_subst_buf); } // returns NULL on success, otherwise an error string const char* BufferSearchAndReplace(Buffer *buffer, const char *pattern, const char *substitute, const char *options) { assert(buffer != NULL); assert(pattern != NULL); assert(substitute != NULL); assert(options != NULL); static const char *replacement_error_msg = "regex replacement error (see logs for details)"; /* no default compile opts */ uint32_t compile_opts = 0; /* ensure we get the needed buffer size | substitute with the first match done */ uint32_t subst_opts = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH | PCRE2_SUBSTITUTE_MATCHED; for (const char *opt_c = options; *opt_c != '\0'; opt_c++) { switch(*opt_c) { case 'i': compile_opts |= PCRE2_CASELESS; break; case 'm': compile_opts |= PCRE2_MULTILINE; break; case 's': compile_opts |= PCRE2_DOTALL; break; case 'x': compile_opts |= PCRE2_EXTENDED; break; case 'U': compile_opts |= PCRE2_UNGREEDY; break; case 'g': subst_opts |= PCRE2_SUBSTITUTE_GLOBAL; break; case 'T': subst_opts |= PCRE2_SUBSTITUTE_LITERAL; break; default: assert(false); Log(LOG_LEVEL_WARNING, "Unsupported regex option '%c'", *opt_c); } } int err_code; PCRE2_SIZE err_offset; pcre2_code *regex = pcre2_compile((PCRE2_SPTR) pattern, PCRE2_ZERO_TERMINATED, compile_opts, &err_code, &err_offset, NULL); if (regex == NULL) { char err_msg[128]; if (pcre2_get_error_message(err_code, (PCRE2_UCHAR*) err_msg, sizeof(err_msg)) != PCRE2_ERROR_BADDATA) { Log(LOG_LEVEL_ERR, "Failed to compile regex from pattern '%s': '%s' [offset: %zd]", pattern, err_msg, err_offset); } else { Log(LOG_LEVEL_ERR, "Failed to compile regex from pattern '%s'", pattern); } return replacement_error_msg; } pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(regex, NULL); int ret = pcre2_match(regex, (PCRE2_SPTR) BufferData(buffer), BufferSize(buffer), 0, 0, match_data, NULL); assert(ret != 0); /* too small ovector in match_data which should never happen */ if (ret < -1) { /* error */ pcre2_match_data_free(match_data); pcre2_code_free(regex); char err_msg[128]; if (pcre2_get_error_message(err_code, (PCRE2_UCHAR*) err_msg, sizeof(err_msg)) != PCRE2_ERROR_BADDATA) { Log(LOG_LEVEL_ERR, "Match error with pattern '%s' on '%s': '%s'", pattern, BufferData(buffer), err_msg); } else { Log(LOG_LEVEL_ERR, "Unknown match error with pattern '%s' on '%s'", pattern, BufferData(buffer)); } return replacement_error_msg; } else if (ret == -1) { /* no match => no change needed in the buffer*/ pcre2_match_data_free(match_data); pcre2_code_free(regex); return NULL; } /* else: some match */ char *subst_copy = ExpandCFESpecialReplacements(regex, BufferData(buffer), BufferSize(buffer), match_data, substitute); if (subst_copy != NULL) { substitute = subst_copy; } /* We don't know how much space we will need for the result, let's start * with twice the size of the input and expand it if needed. */ bool had_enough_space = false; size_t out_size = BufferSize(buffer) * 2; char *result = xmalloc(out_size); while (!had_enough_space) { ret = pcre2_substitute(regex, (PCRE2_SPTR) BufferData(buffer), BufferSize(buffer), 0, subst_opts, match_data, NULL, (PCRE2_SPTR) substitute, PCRE2_ZERO_TERMINATED, result, &out_size); if (ret == PCRE2_ERROR_NOMEMORY) { result = xrealloc(result, out_size); } had_enough_space = (ret != PCRE2_ERROR_NOMEMORY); } if (ret < 0) { char err_msg[128]; if (pcre2_get_error_message(ret, (PCRE2_UCHAR*) err_msg, sizeof(err_msg)) != PCRE2_ERROR_BADDATA) { Log(LOG_LEVEL_ERR, "Regular expression replacement error: '%s' (replacing '%s' in '%s')", err_msg, substitute, BufferData(buffer)); } else { Log(LOG_LEVEL_ERR, "Unknown regular expression replacement error (replacing '%s' in '%s')", substitute, BufferData(buffer)); } } BufferSet(buffer, result, out_size); pcre2_match_data_free(match_data); pcre2_code_free(regex); free(result); free(subst_copy); return (ret >= 0) ? NULL : replacement_error_msg; } #endif // WITH_PCRE2 void BufferClear(Buffer *buffer) { assert(buffer != NULL); buffer->used = 0; buffer->buffer[0] = '\0'; } size_t BufferSize(const Buffer *buffer) { assert(buffer != NULL); return buffer != NULL ? buffer->used : 0; } const char *BufferData(const Buffer *buffer) { assert(buffer != NULL); return buffer != NULL ? buffer->buffer : NULL; } void BufferCanonify(Buffer *buffer) { assert(buffer != NULL); if (buffer != NULL && buffer->buffer != NULL) { CanonifyNameInPlace(buffer->buffer); } } BufferBehavior BufferMode(const Buffer *buffer) { assert(buffer != NULL); return buffer != NULL ? buffer->mode : BUFFER_BEHAVIOR_BYTEARRAY; } void BufferSetMode(Buffer *buffer, BufferBehavior mode) { assert(buffer != NULL); assert(mode == BUFFER_BEHAVIOR_CSTRING || mode == BUFFER_BEHAVIOR_BYTEARRAY); /* * If we switch from BYTEARRAY mode to CSTRING then we need to adjust the * length to the first '\0'. This makes our life easier in the long run. */ if (BUFFER_BEHAVIOR_CSTRING == mode) { for (size_t i = 0; i < buffer->used; ++i) { if (buffer->buffer[i] == '\0') { buffer->used = i; break; } } } buffer->mode = mode; } Buffer* BufferFilter(Buffer *buffer, BufferFilterFn filter, const bool invert) { assert(buffer != NULL); Buffer *filtered = BufferNew(); for (size_t i = 0; i < buffer->used; ++i) { bool test = (*filter)(buffer->buffer[i]); if (invert) { test = !test; } if (test) { BufferAppendChar(filtered, buffer->buffer[i]); } } return filtered; } void BufferRewrite(Buffer *buffer, BufferFilterFn filter, const bool invert) { assert(buffer != NULL); Buffer *rewrite = BufferFilter(buffer, filter, invert); BufferSet(buffer, BufferData(rewrite), BufferSize(rewrite)); BufferDestroy(rewrite); } size_t BufferCapacity(const Buffer *buffer) { assert(buffer != NULL); return buffer != NULL ? buffer->capacity : 0; } cfengine-3.24.2/libntech/libutils/csv_writer.h0000644000000000000000000000306515010704254021337 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CSV_WRITER_H #define CFENGINE_CSV_WRITER_H /* * This writer implements CSV as in RFC 4180 */ #include typedef struct CsvWriter_ CsvWriter; CsvWriter *CsvWriterOpenSpecifyTerminate(Writer *w, bool terminate_last_line); CsvWriter *CsvWriterOpen(Writer *w); void CsvWriterField(CsvWriter *csvw, const char *str); void CsvWriterFieldF(CsvWriter *csvw, const char *fmt, ...) FUNC_ATTR_PRINTF(2, 3); void CsvWriterNewRecord(CsvWriter *csvw); /* Does not close underlying Writer, but flushes all pending data */ void CsvWriterClose(CsvWriter *csvw); /** * @return The instance of the underlying writer */ Writer *CsvWriterGetWriter(CsvWriter *csvw); #endif cfengine-3.24.2/libntech/libutils/ip_address.h0000644000000000000000000000774015010704254021271 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_IP_ADDRESS_H #define CFENGINE_IP_ADDRESS_H #include typedef struct IPAddress IPAddress; typedef enum { IP_ADDRESS_TYPE_IPV4, IP_ADDRESS_TYPE_IPV6 } IPAddressVersion; /** @brief Creates a new IPAddress object from a string. @param source Buffer containing the string representation of the ip address. @return A fully formed IPAddress object or NULL if there was an error parsing the source. */ IPAddress *IPAddressNew(Buffer *source); /** @brief Creates a new IPAddress object from a hex string (as in procfs). @param source Buffer containing the string representation of the ip address. @return A fully formed IPAddress object or NULL if there was an error parsing the source. */ IPAddress *IPAddressNewHex(Buffer *source); /** @brief Destroys an IPAddress object. @param address IPAddress object to be destroyed. */ int IPAddressDestroy(IPAddress **address); /** @brief Returns the type of address. @param address Address object. @return The type of address or -1 in case of error. */ int IPAddressType(IPAddress *address); /** @brief Produces a fully usable IPV6 or IPV4 address string representation. @param address IPAddress object. @return A buffer containing an IPV4 or IPV6 address or NULL in case the given address was invalid. */ Buffer *IPAddressGetAddress(IPAddress *address); /** @brief Recovers the appropriate port from the given address. @param address IPAddress object. @return A valid port for connections or -1 if it was not available. */ int IPAddressGetPort(IPAddress *address); /** @brief Compares two IP addresses. @param a IP address of the first object. @param b IP address of the second object. @return 1 if both addresses are equal, 0 if they are not and -1 in case of error. */ int IPAddressIsEqual(IPAddress *a, IPAddress *b); /** @brief Checks if a given string is a properly formed IP Address. @param source Buffer containing the string. @param address Optional parameter. If given and not NULL then an IPAdress structure will be created from the string. @return Returns true if the string is a valid IP Address and false if not. The address parameter is populated accordingly. */ bool IPAddressIsIPAddress(Buffer *source, IPAddress **address); /** @brief Compares two IP addresses for sorting. @param a IP address of the first object. @param b IP address of the second object. @return true if a < b, false otherwise. */ bool IPAddressCompareLess(IPAddress *a, IPAddress *b); /** * @brief Check if string is localhost IPv4-/IPv6 addresses. * * For IPv4, any address in the range 127.0.0.0/8 is local host. E.g. * '127.0.0.1', '127.1.2.3', 127.0.0.0' or '127.255.255.255'. * * For IPv6, '::1' is the one and only local host address. IPv6 * addresses can be written in long- and short-form, as well as * something in-between (e.g. 0:0:0:0:0:0:0:1 / ::1 / 0:0::0:1). All of * these forms are accepted. * @param str The string to check. * @return True if string is localhost, else false. */ bool StringIsLocalHostIP(const char *str); #endif // CFENGINE_IP_ADDRESS_H cfengine-3.24.2/libntech/libutils/json-yaml.h0000644000000000000000000000336515010704321021057 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_JSON_YAML_H #define CFENGINE_JSON_YAML_H #include /* Set by ./configure allowing us to avoid #include here. */ // #undef HAVE_LIBYAML #ifdef HAVE_LIBYAML #include #endif /** @brief Parse a YAML string to create a JsonElement @param data [in Pointer to the string to parse @param json_out Resulting JSON object @returns See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParseYamlString(const char **data, JsonElement **json_out); /** * @brief Convenience function to parse JSON from a YAML file * @param path Path to the file * @param size_max Maximum size to read in memory * @param json_out Resulting JSON object * @return See JsonParseError and JsonParseErrorToString */ JsonParseError JsonParseYamlFile(const char *path, size_t size_max, JsonElement **json_out); #endif // CFENGINE_JSON_YAML_H cfengine-3.24.2/libntech/libutils/threaded_queue.h0000644000000000000000000001366015010704254022136 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_THREADED_QUEUE_H #define CFENGINE_THREADED_QUEUE_H #include typedef struct ThreadedQueue_ ThreadedQueue; /** @brief Creates a new thread safe queue with specified capacity. @param [in] initial_capacity Initial capacity, defaults to 1. @param [in] ItemDestroy Function used to destroy data elements. */ ThreadedQueue *ThreadedQueueNew(size_t initial_capacity, void (ItemDestroy) (void *item)); /** @brief Destroys the queue and frees the memory it occupies. @warning ThreadedQueue should only be destroyed if all threads are joined @param [in] queue The queue to destroy. */ void ThreadedQueueDestroy(ThreadedQueue *queue); /** @brief Frees the memory allocated for the data pointer and the struct itself. @param [in] queue The queue to free. */ void ThreadedQueueSoftDestroy(ThreadedQueue *queue); /** @brief Returns and removes the first element of the queue. @note If queue is empty, blocks for `timeout` seconds or until signalled. If THREAD_WAIT_INDEFINITELY is specified, waits forever until signal is given. If it times out, it returns false. @param [in] queue The queue to pop from. @param [out] item The item at the first poisition in the queue. @param [in] timeout Timeout for blocking in seconds. @return true on success, false if timed out or queue was empty. */ bool ThreadedQueuePop(ThreadedQueue *queue, void **item, int timeout); /** @brief Pops num elements from the queue into data_array, returns amount. @note If queue is empty, blocks for `timeout` seconds or until signalled. If THREAD_WAIT_INDEFINITELY is specified, waits forever until signalled. If it times out, it returns 0 and sets *data_array to NULL. @warning The pointer array will have to be freed manually. @param [in] queue The queue to pop from. @param [out] data_array Pointer to location to put popped elements. @param [in] timeout Timeout for blocking in seconds. @return Amount of elements popped. */ size_t ThreadedQueuePopN(ThreadedQueue *queue, void ***data_array, size_t num, int timeout); /** * @brief Same as ThreadedQueuePopN() above, but pops into a given array. * @warning The caller is responsible for making sure that up to #num items fit * into the given array. * @see ThreadedQueuePopN() */ size_t ThreadedQueuePopNIntoArray(ThreadedQueue *queue, void **data_array, size_t num, int timeout); /** @brief Pushes a new item on top of the queue, returns current size. @param [in] queue The queue to push to. @param [in] item The item to push. @return Current amount of elements in the queue. */ size_t ThreadedQueuePush(ThreadedQueue *queue, void *item); /** @brief Pushes new items on top of the queue, returns current size. @param [in] queue The queue to push to. @param [in] items The items to push. @param [in] n_items Number of items from #items to push. @return Current amount of elements in the queue. */ size_t ThreadedQueuePushN(ThreadedQueue *queue, void **items, size_t n_items); /** @brief Get current number of items in queue. @note On NULL queue, returns 0. @param [in] queue The queue. @return The amount of elements in the queue. */ size_t ThreadedQueueCount(ThreadedQueue const *queue); /** @brief Get current capacity of queue. @note On NULL queue, returns 0. @param [in] queue The queue. @return The current capacity of the queue. */ size_t ThreadedQueueCapacity(ThreadedQueue const *queue); /** @brief Checks if a queue is empty. @param [in] queue The queue. @return Returns true if queue is empty, false otherwise. */ bool ThreadedQueueIsEmpty(ThreadedQueue const *queue); /** @brief Waits until queue is empty. @note Useful for situations where you want to wait before populating the queue. Timeout can be set to THREAD_BLOCK_INDEFINITELY to wait forever. Otherwise waits the amount of seconds specified. @param [in] queue The queue. @param [in] timeout Amount of seconds to wait before timing out. @return True if it successfully waited, false if it timed out. */ bool ThreadedQueueWaitEmpty(ThreadedQueue const *queue, int timeout); /** @brief Create a shallow copy of a given queue. @note This makes a new queue pointing to the same memory as the old queue. @note Is only thread safe if original queue was also thread safe. @param [in] queue The queue. @return A new queue pointing to the same data. */ ThreadedQueue *ThreadedQueueCopy(ThreadedQueue *queue); /** * @brief Clear (empty) the queue. */ void ThreadedQueueClear(ThreadedQueue *queue); /** * @brief Clear (empty) the queue and push one item into it. * @note This is an atomic version of ThreadedQueueClear(); ThreadedQueuePush() * useful for replacing contents of the queue with a new single item. * @return Current amount of elements in the queue. */ size_t ThreadedQueueClearAndPush(ThreadedQueue *queue, void *item); #endif cfengine-3.24.2/libntech/libutils/encode.h0000644000000000000000000000202015010704254020373 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ENCODE_H #define CFENGINE_ENCODE_H char *StringEncodeBase64(const char *str, size_t len); #endif /* CFENGINE_ENCODE_H */ cfengine-3.24.2/libntech/libutils/list.h0000644000000000000000000003302215010704254020117 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LIST_H #define CFENGINE_LIST_H #include #include /** @brief Double linked list implementation. A linked list is to be used when data needs to be stored and then sequentially processed, not for quick lookups. Prime examples of bad usage of a linked list is for instance having a list of files and then iterating over the list to find a particular file based on the name. A Map will be much better for this type of usage. A good usage for a linked list is to store a list of files that need to be changed sequentially. For instance a list of files that need to change permissions. A linked list should not be used when fast retrieval is important, for that it is better to use a Map. The implementation of the list is kept intentionally opaque, so we can change it in the future. It provides a reference counted list with copy on write. In order for this to work the user needs to provide at least a copy function. The List is used at its full potential if the user provides three helper functions: - copy(void *source, void **destination) - compare(void *a, void *b) - destroy(void *element) It is highly recommend to at least implement the copy function, since that is the key for the copy on write implementation. The destroy function is recommended to avoid leaking memory whenever an element is destroyed. Notice that the list never copies the elements, so as long as the user still has access to the elements this function does not need to be implemented and the user then needs to delete the elements afterwards. The compare function is a nice to have function. It is used when the user wants to remove elements, in order to find the right element to delete. If this function is not provided, then the list will try to match the pointer. These three helper functions can assume that they will never be called with NULL pointers. A special note on the copy function. The copy function is analog to the copy constructor in C++, it takes a properly constructed element and produces a newly created element that is a copy of the previous one. The copy function needs to allocate memory for the new element and then fill it with the proper data. It should be avoid moving pointers around, it should copy the content to the new element so the new element is not tied to the previous element. The list can have many iterators, but only one mutable iterator at any given time. The difference between a normal iterator and a mutable iterator is the fact that with normal iterators only additions can be performed to the list without invalidating the iterator, while the mutable iterator allows any kind of change. Be aware that removing from the list, either by using remove or via the mutable iterator will invalidate all the normal iterators. Simple way to iterate over the list: ListIterator *i = ListIteratorGet(list); int r = 0; for (r = ListIteratorFirst(i); r == 0; r = ListIteratorNext(i)) { MyData = ListIteratorData(i); ... Do something with the data. ... } */ typedef struct List List; typedef struct ListMutableIterator ListMutableIterator; typedef struct ListIterator ListIterator; /** @brief Initialization of a linked list. @param compare Compare functions for the elements of the list. Same semantic as strcmp. @param copy Copies one element into a new element. @param destroy Destroys an element. @return A fully initialized list ready to be used or -1 in case of error. */ List *ListNew(int (*compare)(const void *, const void *), void (*copy)(const void *source, void **destination), void (*destroy)(void *)); /** @brief Destroy a linked list. @param list List to be destroyed. It can be a NULL pointer. @return 0 if destroyed, -1 otherwise. */ int ListDestroy(List **list); /** @brief Performs a shallow copy of a linked list. A shallow copy is a copy that does not copy the elements but only the list structure. This is done by internal reference counting. If any of the lists is modified afterwards then a deep copy of the list is triggered and all the elements are copied. @param origin Original list to be copied. @param destination List to be copied to. @return 0 if copied, -1 otherwise. @remark If no copy function is provided, then this function returns -1. */ int ListCopy(List *origin, List **destination); /** @brief Adds an element to the beginning of the list. Notice that we do not copy the element, so if the original element is free'd there will be a dangling pointer. We used to change the state of the list after adding an element, but now we don't do it. The reason is because adding an element is not destructive, no iterators will be affected by this, while removing it is destructive. An iterator might be pointing to the dark side of the moon after a removal operation. If the list is shared this will trigger a deep copy of the list. @param list Linked list. @param payload Data to be added. @return 0 if prepended, -1 otherwise. */ int ListPrepend(List *list, void *payload); /** @brief Adds an element to the end of the list. Notice that we do not copy the element, so if the original element is free'd there will be a dangling pointer. We used to change the state of the list after adding an element, but now we don't do it. The reason is because adding an element is not destructive, no iterators will be affected by this, while removing it is destructive. An iterator might be pointing to the dark side of the moon after a removal operation. If the list is shared this will trigger a deep copy of the list. @param list Linked list. @param payload Data to be added. @return 0 if appended, -1 otherwise. */ int ListAppend(List *list, void *payload); /** @brief Removes an element from the linked list. Removes the first element that matches the payload. It starts looking from the beginning of the list. Notice that this might trigger a deep copy of the list. This only happens if the list was copied before. @param list Linked list. @param payload Data to be removed. @return 0 if removed, -1 otherwise. */ int ListRemove(List *list, void *payload); /** @brief Returns the number of elements on a given linked list. @param list Linked list. @return The number of elements on the list. */ int ListCount(const List *list); /** @brief Gets an iterator for a given linked list. This iterator will be invalid if data is removed from the list. It will still be valid after a new addition though. @note After creation the iterator will be pointing to the first item of the list. @param list Linked list @param iterator Iterator. @return A fully initialized iterator or NULL in case of error. */ ListIterator *ListIteratorGet(const List *list); /** @brief Releases the memory associated with an iterator. This function exists only to free the memory associated with the iterator, there is no strong connection between the iterator and the list. @note It is not possible to get an iterator for an empty list. @param iterator Iterator. @return 0 if released, -1 otherwise. */ int ListIteratorDestroy(ListIterator **iterator); /** @brief Moves the iterator to the first element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListIteratorFirst(ListIterator *iterator); /** @brief Moves the iterator to the last element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListIteratorLast(ListIterator *iterator); /** @brief Moves the iterator to the next element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListIteratorNext(ListIterator *iterator); /** @brief Moves the iterator to the previous element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListIteratorPrevious(ListIterator *iterator); /** @brief Returns the data associated with the current element. @param iterator Iterator. @return Pointer to the data or NULL if it was not possible. */ void *ListIteratorData(const ListIterator *iterator); /** @brief Checks if the iterator has a next element @return True if it has a next element or False if not. */ bool ListIteratorHasNext(const ListIterator *iterator); /** @brief Checks if the iterator has a previous element @return True if it has a previous element or False if not. */ bool ListIteratorHasPrevious(const ListIterator *iterator); /** @brief Creates a new mutable iterator. A mutable iterator can be used for the same kind of operations as a normal iterator, but it can also be used to add and remove elements while iterating over the list. Any removal operation will invalidate all the normal iterators though. Since there can be only one mutable iterator for a list at any given time, the creation of a second iterator will fail. @note After creation the iterator will be pointing to the first item of the list. @param iterator Iterator to be initialized. @return A fully initialized iterator or NULL in case of error. */ ListMutableIterator *ListMutableIteratorGet(List *list); /** @brief Releases the memory associated with an iterator. This function has to be called for mutable iterators, otherwise the list will think there is already one mutable iterator and the creation of new mutable iterators will not be possible. @note It is not possible to get an iterator for an empty list. @param iterator Iterator. @return 0 if released, -1 otherwise. */ int ListMutableIteratorRelease(ListMutableIterator **iterator); /** @brief Moves the iterator to the first element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListMutableIteratorFirst(ListMutableIterator *iterator); /** @brief Moves the iterator to the last element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListMutableIteratorLast(ListMutableIterator *iterator); /** @brief Moves the iterator to the next element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListMutableIteratorNext(ListMutableIterator *iterator); /** @brief Moves the iterator to the previous element of the list. @param iterator Iterator. @return 0 if it was possible to move, -1 otherwise. */ int ListMutableIteratorPrevious(ListMutableIterator *iterator); /** @brief Returns the data associated with the current element. @param iterator Iterator. @return Pointer to the data or NULL if it was not possible. */ void *ListMutableIteratorData(const ListMutableIterator *iterator); /** @brief Removes the current element from the list. After this operation all the normal iterators are invalid. The iterator might be pointing to the next element, or in the case of removing the last element, to the previous element. Although it is supported to remove elements from the list bypassing the iterator, i.e. calling ListRemove, this might bring unintended side effects. The iterator might be moved to another element, therefore special care must be taken when mixing removal both from the list and from the iterator. @param iterator Iterator @return 0 if removed, -1 otherwise. */ int ListMutableIteratorRemove(ListMutableIterator *iterator); /** @brief Prepends element on front of the element pointed by the iterator. An important clarification, the iterator still points to the same element after this operation. It is up to the user to move the iterator to the prepended element. All the light operators are still valid after this operation. @param iterator Iterator @param payload Element to be prepended. @return 0 if prepended, -1 in case of error. */ int ListMutableIteratorPrepend(ListMutableIterator *iterator, void *payload); /** @brief Appends element after the element pointed by the iterator. An important clarification, the iterator still points to the same element after this operation. It is up to the user to move the iterator to the appended element. All the light operators are still valid after this operation. @param iterator Iterator @param payload Element to be appended. @return 0 if appended, -1 in case of error. */ int ListMutableIteratorAppend(ListMutableIterator *iterator, void *payload); /** @brief Checks if the iterator has a next element @return True if it has a next element or False if not. */ bool ListMutableIteratorHasNext(const ListMutableIterator *iterator); /** @brief Checks if the iterator has a previous element @return True if it has a previous element or False if not. */ bool ListMutableIteratorHasPrevious(const ListMutableIterator *iterator); #endif // CFENGINE_LIST_H cfengine-3.24.2/libntech/libutils/statistics.h0000644000000000000000000000226715010704254021345 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_STATISTICS_H #define CFENGINE_STATISTICS_H typedef struct { double q; double expect; double var; double dq; } QPoint; double GAverage(double anew, double aold, double p); QPoint QAverage(QPoint old_value, double new_value, double p); QPoint QDefinite(double value); #endif cfengine-3.24.2/libntech/libutils/passopenfile.h0000644000000000000000000001037615010704254021643 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PASSOPENFILE_H #define CFENGINE_PASSOPENFILE_H /* Sharing file descriptors between processes. * * This presumes a local communication socket (archetypically a Unix * Domain Socket, opened with domain AF_UNIX - also known as AF_LOCAL) * between two processes on a single machine. One process has an open * file descriptor (and possibly some accompanying data), to be passed * to the other process. The former Put()s, the latter Get()s to * implement this. See ../tests/unit/passopenfile_test.c for a test * that illustrates usage. * * The accompanying text is optional: if NULL is passed to Put(), * Get() shall receive NULL; in contrast, any non-NULL pointer (even * to an empty string) shall result in Get() allocating memory in * which to receive a copy (even if it's just allocating one byte in * which to store a '\0'). Texts over 1023 bytes shall be truncated. * * Details of how the local socket is established are left to the * callers; one end shall need to bind() a listen()ing socket so that * the other can connect() one end and the first can accept() the * other end. Callers are responsible for ensuring the local sockets * are ready for use, e.g. by calling select(). * * This allows a process that has accept()ed a connection to hand off * its socket (and the information accept() gave it about the other * end) to another process for handling; or allows one process to * initiate a connection and then hand it off to another to work with * it. We use this where there is one process that naturally should * do certain jobs but some other process to which initiating the * connection, or accept()ing it, is more practical. * * Passing local file descriptors can also be used for privilege * separation, with a privileged process sending open descriptors to a * worker process that lacks privileges to open the files but handles * untrusted data so can't be trusted to perform access control * reliably. However (see following) this only works on Unix. * * On MinGW (i.e. MS-Win), the present implementation can only pass * sockets, not local file descriptors. It also may block, calling * select(), in its improvised protocol for exchanging needed * information over the local sockets. * * The essential activity here is the same as GNUlib's passfd, albeit * with a slightly different API (most notably, providing for * transmission of a text message accompanying the descriptor). */ /* Send a file descriptor to another process. * * @param uds The local communications socket. * @param descriptor Descriptor for the open file to transfer. * @param text NULL or a '\0'-terminated string to transmit. * @return True on successful transmission. */ extern bool PassOpenFile_Put(int uds, int descriptor, const char *text); /* Receive a file descriptor from another process. * * On success, the caller is responsible for close()ing the descriptor * and free()ing the text (if any). If text == NULL is passed, any * text transmitted with the descriptor is (read, if necessary, and) * discarded; otherwise, on failure, *text should be treated as * uninitialised (even if it was initialised before). * * @param uds The local communications socket. * @param text Pointer to where to record the returned string. * @return The received descriptor or, on failure, -1. */ extern int PassOpenFile_Get(int uds, char **text); #endif /* CFENGINE_PASSOPENFILE_H */ cfengine-3.24.2/libntech/libutils/misc_lib.h0000644000000000000000000001177315010704254020736 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MISC_LIB_H #define CFENGINE_MISC_LIB_H #include #include /* size_t */ #include #define ProgrammingError(...) __ProgrammingError(__FILE__, __LINE__, __VA_ARGS__) /* TODO UnexpectedError() needs * to be rate limited to avoid spamming the console. */ #ifndef NDEBUG # define UnexpectedError(...) __ProgrammingError(__FILE__, __LINE__, __VA_ARGS__) #else # define UnexpectedError(...) __UnexpectedError(__FILE__, __LINE__, __VA_ARGS__) #endif /** * CF_ASSERT(condition, message...) * * If NDEBUG is defined then the #message is printed and execution continues, * else execution aborts. */ # define CF_ASSERT(condition, ...) \ do { \ if (!(condition)) \ UnexpectedError(__VA_ARGS__); \ } while(0) /** * CF_ASSERT_FIX(condition, fix, message...) * * If NDEBUG is defined then the #message is printed, the #fix is executed, * and execution continues. If not NDEBUG, the #fix is ignored and execution * is aborted. */ # define CF_ASSERT_FIX(condition, fix, ...) \ { \ if (!(condition)) \ { \ UnexpectedError(__VA_ARGS__); \ (fix); \ } \ } #define ISPOW2(n) ( (n)>0 && ((((n) & ((n)-1)) == 0)) ) #define ABS(n) ( (n<0) ? (-n) : (n) ) /** * Hack to get optional- and required-arguments with short options to work the * same way. * * If the option has an optional argument, it must be written * directly after the option character if present. * - getopt(1) - Linux man page * * This means that getopt expects an option "-o" with an optional argument * "foo" to be passed like this: "-ofoo". While an option "-r" with a * required argument "bar" is expected to be passed like this: "-r bar". * * Confusing, right? This little hack makes sure that the option-character and * the optional argument can also be separated by a whitespace-character. This * way optional- and required-arguments can be passed in the same fashion. * * This is how it works: * If optarg is NULL, we check whether the next string in argv is an option * (the variable optind has the index of the next element to be processed in * argv). If this is not the case, we assume it is an argument. The argument * is extracted and optind is advanced accordingly. * * This is how you use it: * ``` * case 'o': * if (OPTIONAL_ARGUMENT_IS_PRESENT) * { * // Handle is present * } * else * { * // Handle is not present * } * break; * ``` */ #define OPTIONAL_ARGUMENT_IS_PRESENT \ ((optarg == NULL && optind < argc && argv[optind][0] != '-') \ ? (bool) (optarg = argv[optind++]) \ : (optarg != NULL)) /* In contrast to the standard C modulus operator (%), this gives you an unsigned modulus. So where -1 % 3 => -1, UnsignedModulus(-1, 3) => 2. */ unsigned long UnsignedModulus(long dividend, long divisor); size_t UpperPowerOfTwo(size_t v); void __ProgrammingError(const char *file, int lineno, const char *format, ...) \ FUNC_ATTR_PRINTF(3, 4) FUNC_ATTR_NORETURN; void __UnexpectedError(const char *file, int lineno, const char *format, ...) \ FUNC_ATTR_PRINTF(3, 4); /** * Unchecked versions of common functions, i.e. functions that no longer * return anything, but try to continue in case of failure. * * @NOTE call these only with arguments that will always succeed! */ void xclock_gettime(clockid_t clk_id, struct timespec *ts); void xsnprintf(char *str, size_t str_size, const char *format, ...); int setenv_wrapper(const char *name, const char *value, int overwrite); int putenv_wrapper(const char *str); #endif cfengine-3.24.2/libntech/libutils/rb-tree.c0000644000000000000000000004033715010704254020506 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include typedef struct RBNode_ RBNode; struct RBNode_ { void *key; void *value; bool red; RBNode *parent; RBNode *left; RBNode *right; }; struct RBTree_ { void *(*KeyCopy)(const void *key); int (*KeyCompare)(const void *a, const void *b); void (*KeyDestroy)(void *key); void *(*ValueCopy)(const void *key); int (*ValueCompare)(const void *a, const void *b); void (*ValueDestroy)(void *key); struct RBNode_ *root; struct RBNode_ *nil; size_t size; }; struct RBTreeIterator_ { const RBTree *tree; RBNode *curr; }; static void PutFix_(RBTree *tree, RBNode *z); static RBNode *Next_(const RBTree *tree, const RBNode *node); static void VerifyTree_(RBTree *tree); static int PointerCompare_(const void *a, const void *b) { return a - b; } static void NoopDestroy_(ARG_UNUSED void *a) { return; } static void *NoopCopy_(const void *a) { return (void *)a; } static RBNode *NodeNew_(RBTree *tree, RBNode *parent, bool red, const void *key, const void *value) { RBNode *node = xmalloc(sizeof(RBNode)); node->parent = parent; node->red = red; node->key = tree->KeyCopy(key); node->value = tree->ValueCopy(value); node->left = tree->nil; node->right = tree->nil; return node; } static void NodeDestroy_(RBTree *tree, RBNode *node) { if (node) { tree->KeyDestroy(node->key); tree->ValueDestroy(node->value); free(node); } } static void Reset_(RBTree *tree) { tree->nil->key = tree->nil->value = NULL; tree->nil->red = false; tree->nil->parent = tree->nil->left = tree->nil->right = tree->nil; tree->root->key = tree->root->value = NULL; tree->root->red = false; tree->root->parent = tree->root->left = tree->root->right = tree->nil; tree->size = 0; } RBTree *RBTreeNew(void *(*KeyCopy)(const void *key), int (*KeyCompare)(const void *a, const void *b), void (*KeyDestroy)(void *key), void *(*ValueCopy)(const void *key), int (*ValueCompare)(const void *a, const void *b), void (*ValueDestroy)(void *key)) { assert(!(KeyCopy && KeyDestroy) || (KeyCopy && KeyDestroy)); assert(!(ValueCopy && ValueDestroy) || (ValueCopy && ValueDestroy)); RBTree *t = xmalloc(sizeof(RBTree)); t->KeyCopy = KeyCopy ? KeyCopy : NoopCopy_; t->KeyCompare = KeyCompare ? KeyCompare : PointerCompare_; t->KeyDestroy = KeyDestroy ? KeyDestroy : NoopDestroy_; t->ValueCopy = ValueCopy ? ValueCopy : NoopCopy_; t->ValueCompare = ValueCompare ? ValueCompare : PointerCompare_; t->ValueDestroy = ValueDestroy ? ValueDestroy : NoopDestroy_; t->nil = xcalloc(1, sizeof(RBNode)); t->root = xcalloc(1, sizeof(RBNode)); Reset_(t); return t; } static void TreeDestroy_(RBTree *tree, RBNode *x) { if (x != tree->nil) { TreeDestroy_(tree, x->left); TreeDestroy_(tree, x->right); NodeDestroy_(tree, x); } } RBTree *RBTreeCopy(const RBTree *tree, RBTreePredicate *filter, void *user_data) { RBNode **nodes = xmalloc(tree->size * sizeof(RBNode *)); size_t node_count = 0; { RBTreeIterator *iter = NULL; for (iter = RBTreeIteratorNew(tree); iter->curr != iter->tree->nil; iter->curr = Next_(iter->tree, iter->curr)) { if (!filter || filter(iter->curr->key, iter->curr->value, user_data)) { nodes[node_count] = iter->curr; node_count++; } } RBTreeIteratorDestroy(iter); } RBTree *copy = RBTreeNew(tree->KeyCopy, tree->KeyCompare, tree->KeyDestroy, tree->ValueCopy, tree->ValueCompare, tree->ValueDestroy); RBNode *node = NULL; // [0, 1, 2, 3, 4] if ((node_count % 2) != 0) { node = nodes[node_count / 2]; RBTreePut(copy, node->key, node->value); node_count--; } else { node = copy->root; } assert((node_count % 2) == 0); // [0, 1, 2, 3] for (size_t i = 0; i < (node_count / 2); i += 1) { node = nodes[(node_count / 2) + i]; RBTreePut(copy, node->key, node->value); node = nodes[(node_count / 2) - i - 1]; RBTreePut(copy, node->key, node->value); } free(nodes); VerifyTree_(copy); return copy; } bool RBTreeEqual(const void *_a, const void *_b) { const RBTree *a = _a, *b = _b; if (a == b) { return true; } if (a == NULL || b == NULL) { return false; } if (a->KeyCompare != b->KeyCompare || a->ValueCompare != b->ValueCompare) { return false; } if (RBTreeSize(a) != RBTreeSize(b)) { return false; } RBTreeIterator *it_a = RBTreeIteratorNew(a); RBTreeIterator *it_b = RBTreeIteratorNew(b); void *a_key, *a_val, *b_key, *b_val; while (RBTreeIteratorNext(it_a, &a_key, &a_val) && RBTreeIteratorNext(it_b, &b_key, &b_val)) { if (a->KeyCompare(a_key, b_key) != 0 || b->ValueCompare(a_val, b_val)) { RBTreeIteratorDestroy(it_a); RBTreeIteratorDestroy(it_b); return false; } } RBTreeIteratorDestroy(it_a); RBTreeIteratorDestroy(it_b); return true; } void RBTreeDestroy(void *rb_tree) { RBTree *tree = rb_tree; if (tree) { TreeDestroy_(tree, tree->root->left); free(tree->root); free(tree->nil); free(tree); } } static void RotateLeft_(RBTree *tree, RBNode *x) { assert(!tree->nil->red); RBNode *y = x->right; x->right = y->left; if (y->left != tree->nil) { y->left->parent = x; } y->parent = x->parent; if (x == x->parent->left) { x->parent->left = y; } else { x->parent->right = y; } y->left = x; x->parent = y; assert(!tree->nil->red); } static void RotateRight_(RBTree *tree, RBNode *y) { assert(!tree->nil->red); RBNode *x = y->left; y->left = x->right; if (x->right != tree->nil) { x->right->parent = y; } x->parent = y->parent; if (y == y->parent->left) { y->parent->left = x; } else { y->parent->right = x; } x->right = y; y->parent = x; assert(!tree->nil->red); } typedef struct { bool replaced; RBNode *node; } InsertResult_; static void PutFix_(RBTree *tree, RBNode *z) { while (z->parent->red) { if (z->parent == z->parent->parent->left) { RBNode *y = z->parent->parent->right; if (y->red) { // case 1 z->parent->red = false; y->red = false; z->parent->parent->red = true; z = z->parent->parent; } else { if (z == z->parent->right) { // case 2 z = z->parent; RotateLeft_(tree, z); } // case 3 z->parent->red = false; z->parent->parent->red = true; RotateRight_(tree, z->parent->parent); } } else { RBNode *y = z->parent->parent->left; if (y->red) { // case 1 z->parent->red = false; y->red = false; z->parent->parent->red = true; z = z->parent->parent; } else { if (z == z->parent->left) { // case 2 z = z->parent; RotateRight_(tree, z); } // case 3 z->parent->red = false; z->parent->parent->red = true; RotateLeft_(tree, z->parent->parent); } } } tree->root->left->red = false; assert(!tree->nil->red); assert(!tree->root->red); } bool RBTreePut(RBTree *tree, const void *key, const void *value) { RBNode *y = tree->root; RBNode *x = tree->root->left; while (x != tree->nil) { y = x; int cmp = tree->KeyCompare(key, x->key); if (cmp == 0) { tree->KeyDestroy(x->key); x->key = tree->KeyCopy(key); tree->ValueDestroy(x->value); x->value = tree->ValueCopy(value); return true; } x = (cmp < 0) ? x->left : x->right; } RBNode *z = NodeNew_(tree, y, true, key, value); if (y == tree->root || tree->KeyCompare(z->key, y->key) < 0) { y->left = z; } else { y->right = z; } PutFix_(tree, z); tree->size++; return false; } static RBNode *Next_(const RBTree *tree, const RBNode *node) { if (node->right != tree->nil) { RBNode *curr; for (curr = node->right; curr->left != tree->nil; curr = curr->left); return curr; } else { RBNode *curr; for (curr = node->parent; node == curr->right; node = curr, curr = curr->parent); return (curr != tree->root) ? curr : tree->nil; } } static RBNode *Get_(const RBTree *tree, const void *key) { assert(!tree->nil->red); RBNode *curr = tree->root->left; while (curr != tree->nil) { int cmp = tree->KeyCompare(key, curr->key); if (cmp == 0) { return curr; } else if (cmp < 0) { curr = curr->left; } else { curr = curr->right; } } assert(!tree->nil->red); return curr; } void *RBTreeGet(const RBTree *tree, const void *key) { RBNode *node = Get_(tree, key); return node != tree->nil ? node->value : NULL; } void RemoveFix_(RBTree *tree, RBNode *x) { assert(!tree->nil->red); RBNode *root = tree->root->left; RBNode *w; while (x != root && !x->red) { if (x == x->parent->left) { w = x->parent->right; if (w->red) { w->red = false; x->parent->red = true; RotateLeft_(tree, x->parent); w = x->parent->right; } if (!w->left->red && !w->right->red) { w->red = true; x = x->parent; } else { if (!w->right->red) { w->left->red = false; w->red = true; RotateRight_(tree, w); w = x->parent->right; } w->red = x->parent->red; x->parent->red = false; w->right->red = false; RotateLeft_(tree, x->parent); x = root; } } else { w = x->parent->left; if (w->red) { w->red = false; x->parent->red = true; RotateRight_(tree, x->parent); w = x->parent->left; } if (!w->left->red && !w->right->red) { w->red = true; x = x->parent; } else { if (!w->left->red) { w->right->red = false; w->red = true; RotateLeft_(tree, w); w = x->parent->left; } w->red = x->parent->red; x->parent->red = false; w->left->red = false; RotateRight_(tree, x->parent); x = root; } } } x->red = false; assert(!tree->nil->red); } bool RBTreeRemove(RBTree *tree, const void *key) { assert(!tree->nil->red); RBNode *z = Get_(tree, key); if (z == tree->nil) { return false; } RBNode *y = ((z->left == tree->nil) || (z->right == tree->nil)) ? z : Next_(tree, z); RBNode *x = (y->left == tree->nil) ? y->right : y->left; x->parent = y->parent; if (tree->root == x->parent) { tree->root->left = x; } else { if (y == y->parent->left) { y->parent->left = x; } else { y->parent->right = x; } } if (z != y) { assert(y != tree->nil); assert(!tree->nil->red); if (!y->red) { RemoveFix_(tree, x); } y->left = z->left; y->right = z->right; y->parent = z->parent; y->red = z->red; z->left->parent = y; z->right->parent = y; if (z == z->parent->left) { z->parent->left = y; } else { z->parent->right = y; } NodeDestroy_(tree, z); } else { if (!y->red) { RemoveFix_(tree, x); } NodeDestroy_(tree, y); } assert(!tree->nil->red); tree->size--; return true; } void ClearRecursive_(RBTree *tree, RBNode *node) { if (node == tree->nil) { return; } ClearRecursive_(tree, node->left); ClearRecursive_(tree, node->right); NodeDestroy_(tree, node); } void RBTreeClear(RBTree *tree) { assert(tree); ClearRecursive_(tree, tree->root); tree->root = xcalloc(1, sizeof(RBNode)); Reset_(tree); } size_t RBTreeSize(const RBTree *tree) { return tree->size; } RBTreeIterator *RBTreeIteratorNew(const RBTree *tree) { RBTreeIterator *iter = xmalloc(sizeof(RBTreeIterator)); iter->tree = tree; for (iter->curr = iter->tree->root; iter->curr->left != tree->nil; iter->curr = iter->curr->left); return iter; } bool Peek_(RBTreeIterator *iter, void **key, void **value) { if (iter->tree->size == 0) { return false; } if (iter->curr == iter->tree->nil) { return false; } if (key) { *key = iter->curr->key; } if (value) { *value = iter->curr->value; } return true; } bool RBTreeIteratorNext(RBTreeIterator *iter, void **key, void **value) { if (Peek_(iter, key, value)) { iter->curr = Next_(iter->tree, iter->curr); return true; } else { return false; } } void RBTreeIteratorDestroy(void *_rb_iter) { free(_rb_iter); } static void VerifyNode_(RBTree *tree, RBNode *node, int black_count, int *path_black_count) { if (node->red) { assert(!node->left->red); assert(!node->right->red); } else { black_count++; } if (node == tree->nil) { assert(!node->red); if ((*path_black_count) == -1) { *path_black_count = black_count; } else { assert(black_count == *path_black_count); } } else { VerifyNode_(tree, node->left, black_count, path_black_count); VerifyNode_(tree, node->right, black_count, path_black_count); } } static void VerifyTree_(RBTree *tree) { assert(!tree->root->red); assert(!tree->root->key); assert(!tree->root->value); assert(!tree->nil->red); assert(!tree->nil->key); assert(!tree->nil->value); int path_black_count = -1; VerifyNode_(tree, tree->root->left, 0, &path_black_count); } cfengine-3.24.2/libntech/libutils/hash.c0000644000000000000000000004325415010704254020072 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* EVP_* */ #include /* BN_bn2bin */ #include #include #include #include #include #include static const char *const CF_DIGEST_TYPES[10] = { "md5", "sha224", "sha256", "sha384", "sha512", "sha1", "sha", "best", "crypt", NULL }; static const int CF_DIGEST_SIZES[10] = { CF_MD5_LEN, CF_SHA224_LEN, CF_SHA256_LEN, CF_SHA384_LEN, CF_SHA512_LEN, CF_SHA1_LEN, CF_SHA_LEN, CF_BEST_LEN, CF_CRYPT_LEN, CF_NO_HASH }; struct Hash { unsigned char digest[EVP_MAX_MD_SIZE]; char printable[EVP_MAX_MD_SIZE * 4]; HashMethod method; HashSize size; }; /* * These methods are not exported through the public API. * These are internal methods used by the constructors of a * Hash object. Do not export them since they have very little * meaning outside of the constructors. */ Hash *HashBasicInit(HashMethod method) { Hash *hash = xcalloc (1, sizeof(Hash)); hash->size = CF_DIGEST_SIZES[method]; hash->method = method; return hash; } void HashCalculatePrintableRepresentation(Hash *hash) { switch (hash->method) { case HASH_METHOD_MD5: strcpy(hash->printable, "MD5="); break; case HASH_METHOD_SHA224: case HASH_METHOD_SHA256: case HASH_METHOD_SHA384: case HASH_METHOD_SHA512: case HASH_METHOD_SHA: case HASH_METHOD_SHA1: strcpy(hash->printable, "SHA="); break; default: strcpy(hash->printable, "UNK="); break; } unsigned int i; for (i = 0; i < hash->size; i++) { snprintf(hash->printable + 4 + 2 * i, sizeof(hash->printable) - (4 + 2 * i), "%02x", hash->digest[i]); } hash->printable[4 + 2 * hash->size] = '\0'; } /* * Constructors * All constructors call two common methods: HashBasicInit(...) and HashCalculatePrintableRepresentation(...). * Each constructor reads the data to create the Hash from different sources so after the basic * initialization and up to the point where the hash is computed, each follows its own path. */ Hash *HashNew(const char *data, const unsigned int length, HashMethod method) { if (!data || (length == 0)) { return NULL; } if (method >= HASH_METHOD_NONE) { return NULL; } /* * OpenSSL documentation marked EVP_DigestInit and EVP_DigestFinal functions as deprecated and * recommends moving to EVP_DigestInit_ex and EVP_DigestFinal_ex. */ const EVP_MD *md = NULL; md = EVP_get_digestbyname(CF_DIGEST_TYPES[method]); if (md == NULL) { Log(LOG_LEVEL_INFO, "Digest type %s not supported by OpenSSL library", CF_DIGEST_TYPES[method]); return NULL; } EVP_MD_CTX *const context = EVP_MD_CTX_create(); if (context == NULL) { Log(LOG_LEVEL_ERR, "Could not allocate openssl hash context"); return NULL; } Hash *hash = HashBasicInit(method); EVP_DigestInit_ex(context, md, NULL); EVP_DigestUpdate(context, data, (size_t) length); unsigned int digest_length; EVP_DigestFinal_ex(context, hash->digest, &digest_length); EVP_MD_CTX_destroy(context); /* Update the printable representation */ HashCalculatePrintableRepresentation(hash); return hash; } Hash *HashNewFromDescriptor(const int descriptor, HashMethod method) { if (descriptor < 0) { return NULL; } if (method >= HASH_METHOD_NONE) { return NULL; } const EVP_MD *const md = HashDigestFromId(method); if (md == NULL) { Log(LOG_LEVEL_INFO, "Digest (type=%d) not supported by OpenSSL library", method); return NULL; } EVP_MD_CTX *const context = EVP_MD_CTX_create(); if (context == NULL) { Log(LOG_LEVEL_ERR, "Could not allocate openssl hash context"); return NULL; } if (EVP_DigestInit_ex(context, md, NULL) != 1) { Log(LOG_LEVEL_ERR, "Could not initialize openssl hash context"); EVP_MD_CTX_destroy(context); return NULL; } ssize_t read_count = 0; char buffer[1024]; do { read_count = read(descriptor, buffer, 1024); EVP_DigestUpdate(context, buffer, (size_t) read_count); } while (read_count > 0); Hash *const hash = HashBasicInit(method); // xcalloc, cannot be NULL unsigned int md_len; EVP_DigestFinal_ex(context, hash->digest, &md_len); /* Update the printable representation */ HashCalculatePrintableRepresentation(hash); EVP_MD_CTX_destroy(context); return hash; } Hash *HashNewFromKey(const RSA *rsa, HashMethod method) { if (rsa == NULL) { return NULL; } if (method >= HASH_METHOD_NONE) { return NULL; } const BIGNUM *n, *e; RSA_get0_key(rsa, &n, &e, NULL); size_t n_len = (n == NULL) ? 0 : (size_t) BN_num_bytes(n); size_t e_len = (e == NULL) ? 0 : (size_t) BN_num_bytes(e); size_t buf_len = MAX(n_len, e_len); if (buf_len <= 0) { // Should never happen Log(LOG_LEVEL_ERR, "Invalid RSA key, internal OpenSSL related error"); return NULL; } const EVP_MD *md = EVP_get_digestbyname(CF_DIGEST_TYPES[method]); if (md == NULL) { Log(LOG_LEVEL_INFO, "Digest type %s not supported by OpenSSL library", CF_DIGEST_TYPES[method]); return NULL; } EVP_MD_CTX *context = EVP_MD_CTX_new(); if (context == NULL) { Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context"); return NULL; } if (EVP_DigestInit_ex(context, md, NULL) != 1) { EVP_MD_CTX_free(context); return NULL; } unsigned char buffer[buf_len]; size_t actlen; actlen = BN_bn2bin(n, buffer); CF_ASSERT(actlen <= buf_len, "Buffer overflow n, %zu > %zu!", actlen, buf_len); EVP_DigestUpdate(context, buffer, actlen); actlen = BN_bn2bin(e, buffer); CF_ASSERT(actlen <= buf_len, "Buffer overflow e, %zu > %zu!", actlen, buf_len); EVP_DigestUpdate(context, buffer, actlen); Hash *hash = HashBasicInit(method); unsigned int digest_length; EVP_DigestFinal_ex(context, hash->digest, &digest_length); EVP_MD_CTX_free(context); /* Update the printable representation */ HashCalculatePrintableRepresentation(hash); return hash; } void HashDestroy(Hash **hash) { if (!hash || !*hash) { return; } free (*hash); *hash = NULL; } int HashCopy(Hash *origin, Hash **destination) { if (!origin || !destination) { return -1; } *destination = xmalloc(sizeof(Hash)); memcpy((*destination)->digest, origin->digest, origin->size); strlcpy((*destination)->printable, origin->printable, (EVP_MAX_MD_SIZE * 4)); (*destination)->method = origin->method; (*destination)->size = origin->size; return 0; } bool HashEqual(const Hash *a, const Hash *b) { if (!a && !b) { return true; } if (!a && b) { return false; } if (a && !b) { return false; } if (a->method != b->method) { return false; } size_t i = 0; for (i = 0; i < a->size; ++i) { if (a->digest[i] != b->digest[i]) { return false; } } return true; } const unsigned char *HashData(const Hash *hash, unsigned int *length) { if (!hash || !length) { return NULL; } *length = hash->size; return hash->digest; } const char *HashPrintable(const Hash *hash) { return hash ? hash->printable : NULL; } HashMethod HashType(const Hash *hash) { return hash ? hash->method : HASH_METHOD_NONE; } HashSize HashLength(const Hash *hash) { return hash ? hash->size : CF_NO_HASH; } /* Class methods */ HashMethod HashIdFromName(const char *hash_name) { int i; for (i = 0; CF_DIGEST_TYPES[i] != NULL; i++) { if (hash_name && (strcmp(hash_name, CF_DIGEST_TYPES[i]) == 0)) { return (HashMethod) i; } } return HASH_METHOD_NONE; } const char *HashNameFromId(HashMethod hash_id) { assert(hash_id >= 0); return (hash_id >= HASH_METHOD_NONE) ? NULL : CF_DIGEST_TYPES[hash_id]; } const EVP_MD *HashDigestFromId(HashMethod type) { const char *const name = HashNameFromId(type); if (name == NULL) { return NULL; } return EVP_get_digestbyname(name); } HashSize HashSizeFromId(HashMethod hash_id) { assert(hash_id >= 0); return (hash_id >= HASH_METHOD_NONE) ? CF_NO_HASH : CF_DIGEST_SIZES[hash_id]; } static void HashFile_Stream( FILE *const file, unsigned char digest[EVP_MAX_MD_SIZE + 1], const HashMethod type) { assert(file != NULL); const EVP_MD *const md = HashDigestFromId(type); if (md == NULL) { Log(LOG_LEVEL_ERR, "Could not determine function for file hashing (type=%d)", (int) type); return; } EVP_MD_CTX *const context = EVP_MD_CTX_new(); if (context == NULL) { Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context"); return; } if (EVP_DigestInit(context, md) == 1) { unsigned char buffer[1024]; size_t len; while ((len = fread(buffer, 1, 1024, file))) { EVP_DigestUpdate(context, buffer, len); } unsigned int digest_length; EVP_DigestFinal(context, digest, &digest_length); } EVP_MD_CTX_free(context); } /** * @param text_mode whether to read the file in text mode or not (binary mode) * @note Reading/writing file in text mode on Windows changes Unix newlines * into Windows newlines. */ void HashFile( const char *const filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, bool text_mode) { assert(filename != NULL); assert(digest != NULL); memset(digest, 0, EVP_MAX_MD_SIZE + 1); FILE *file = NULL; if (text_mode) { file = safe_fopen(filename, "rt"); } else { file = safe_fopen(filename, "rb"); } if (file == NULL) { Log(LOG_LEVEL_INFO, "Cannot open file for hashing '%s'. (fopen: %s)", filename, GetErrorStr()); return; } HashFile_Stream(file, digest, type); fclose(file); } /*******************************************************************/ void HashString( const char *const buffer, const int len, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type) { assert(buffer != NULL); assert(digest != NULL); assert(type != HASH_METHOD_CRYPT); memset(digest, 0, EVP_MAX_MD_SIZE + 1); if (type == HASH_METHOD_CRYPT) { Log(LOG_LEVEL_ERR, "The crypt support is not presently implemented, please use another algorithm instead"); return; } const EVP_MD *const md = HashDigestFromId(type); if (md == NULL) { Log(LOG_LEVEL_ERR, "Could not determine function for file hashing (type=%d)", (int) type); return; } EVP_MD_CTX *const context = EVP_MD_CTX_new(); if (context == NULL) { Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context"); return; } if (EVP_DigestInit(context, md) == 1) { EVP_DigestUpdate(context, buffer, len); EVP_DigestFinal(context, digest, NULL); } else { Log(LOG_LEVEL_ERR, "Failed to initialize digest for hashing: '%s'", buffer); } EVP_MD_CTX_free(context); } /*******************************************************************/ void HashPubKey( const RSA *const key, unsigned char digest[EVP_MAX_MD_SIZE + 1], const HashMethod type) { assert(key != NULL); assert(type != HASH_METHOD_CRYPT); memset(digest, 0, EVP_MAX_MD_SIZE + 1); if (type == HASH_METHOD_CRYPT) { Log(LOG_LEVEL_ERR, "The crypt support is not presently implemented, please use sha256 instead"); return; } const EVP_MD *const md = HashDigestFromId(type); if (md == NULL) { Log(LOG_LEVEL_ERR, "Could not determine function for file hashing (type=%d)", (int) type); return; } EVP_MD_CTX *const context = EVP_MD_CTX_new(); if (context == NULL) { Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context"); return; } if (EVP_DigestInit(context, md) == 1) { const BIGNUM *n, *e; RSA_get0_key(key, &n, &e, NULL); const size_t n_len = (n == NULL) ? 0 : (size_t) BN_num_bytes(n); const size_t e_len = (e == NULL) ? 0 : (size_t) BN_num_bytes(e); const size_t buf_len = MAX(n_len, e_len); unsigned char buffer[buf_len]; size_t actlen; actlen = BN_bn2bin(n, buffer); CF_ASSERT(actlen <= buf_len, "Buffer overflow n, %zu > %zu!", actlen, buf_len); EVP_DigestUpdate(context, buffer, actlen); actlen = BN_bn2bin(e, buffer); CF_ASSERT(actlen <= buf_len, "Buffer overflow e, %zu > %zu!", actlen, buf_len); EVP_DigestUpdate(context, buffer, actlen); unsigned int digest_length; EVP_DigestFinal(context, digest, &digest_length); } EVP_MD_CTX_free(context); } /*******************************************************************/ bool HashesMatch( const unsigned char digest1[EVP_MAX_MD_SIZE + 1], const unsigned char digest2[EVP_MAX_MD_SIZE + 1], HashMethod type) { const HashSize size = HashSizeFromId(type); if (size <= 0) // HashSize is an enum (so int) { return false; } return (memcmp(digest1, digest2, size) == 0); } /* TODO rewrite this ugliness, currently it's not safe, it truncates! */ /** * @WARNING #dst must have enough space to hold the result! */ char *HashPrintSafe(char *dst, size_t dst_size, const unsigned char *digest, HashMethod type, bool use_prefix) { const char *prefix; if (use_prefix) { prefix = type == HASH_METHOD_MD5 ? "MD5=" : "SHA="; } else { prefix = ""; } size_t dst_len = MIN(dst_size - 1, strlen(prefix)); memcpy(dst, prefix, dst_len); size_t digest_len = HashSizeFromId(type); assert(dst_size >= strlen(prefix) + digest_len*2 + 1); #ifndef NDEBUG // Avoids warning. size_t ret = #endif StringBytesToHex(&dst[dst_len], dst_size - dst_len, digest, digest_len); assert(ret == 2 * digest_len); #if 0 /* TODO return proper exit status and check it in the callers */ if (ret < 2 * digest_len) { return NULL; } #endif return dst; } char *SkipHashType(char *hash) { char *str = hash; if(STARTSWITH(hash, "MD5=") || STARTSWITH(hash, "SHA=")) { str = hash + 4; } return str; } size_t StringCopyTruncateAndHashIfNecessary( const char *const src, char *const dst, size_t dst_size) { assert(src != NULL); assert(dst != NULL); assert(dst_size > (32 + 5)); // Must be big enough for MD5 hex and prefix const size_t length = StringCopy(src, dst, dst_size); if (length < dst_size) { // String length smaller than destination buffer size // safe to return, no truncation/hashing necessary return length; } assert(length == dst_size); const char md5_prefix[] = "#MD5="; const size_t md5_prefix_length = sizeof(md5_prefix) - 1; const size_t md5_hex_length = 32; const size_t md5_string_length = md5_hex_length + md5_prefix_length; assert(dst_size > md5_string_length); assert(md5_prefix_length == strlen(md5_prefix)); // Hash the original string using MD5: unsigned char digest[EVP_MAX_MD_SIZE + 1]; HashString(src, strlen(src), digest, HASH_METHOD_MD5); // Calculate where the hash should start: char *const terminator = dst + dst_size - 1; assert(*terminator == '\0'); char *const hash_prefix_start = terminator - md5_string_length; assert(hash_prefix_start >= dst); char *const hash_start = hash_prefix_start + sizeof(md5_prefix) - 1; assert(hash_start > hash_prefix_start); // Insert the "#MD5=" part into dst; memcpy(hash_prefix_start, md5_prefix, md5_prefix_length); // Produce the hex string representation of MD5 hash: // (Overwrite the last part of dst) const char lookup[]="0123456789abcdef"; assert((md5_hex_length % 2) == 0); for (size_t i = 0; i < md5_hex_length / 2; i++) { hash_start[i * 2] = lookup[digest[i] >> 4]; hash_start[i * 2 + 1] = lookup[digest[i] & 0xf]; } assert(hash_start[md5_hex_length] == '\0'); assert(hash_start + md5_hex_length == terminator); return dst_size; } cfengine-3.24.2/libntech/libutils/definitions.h0000644000000000000000000000530715010704254021464 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_DEFINITIONS_H #define CFENGINE_DEFINITIONS_H /***************************************************************************** * Metric prefixes *****************************************************************************/ #define KIBIBYTE(n) (n * 1024UL) #define MEBIBYTE(n) (n * 1024UL * 1024UL) #define GIBIBYTE(n) (n * 1024ULL * 1024ULL * 1024ULL) #define TEBIBYTE(n) (n * 1024ULL * 1024ULL * 1024ULL * 1024ULL) /***************************************************************************** * Size related defines * *****************************************************************************/ #define CF_MAXSIZE 102400000 #define CF_BILLION 1000000000L #define CF_BLOWFISHSIZE 16 #define CF_BUFFERMARGIN 128 #define CF_MAXVARSIZE 1024 #define CF_MAXSIDSIZE 2048 /* Windows only: Max size (bytes) of security identifiers */ // Limit database names and table names so they can be combined // into CF_MAXVARSIZE without truncation // NOTE: Databases like PostgreSQL and MySQL actually have stricter limits #define CF_MAXTABLENAMESIZE 256 #define CF_MAXDBNAMESIZE 256 /* Max size of plaintext in one transaction, see net.c:SendTransaction(), leave space for encryption padding (assuming max 64*8 = 512-bit cipher block size). */ #define CF_SMALLBUF 128 #define CF_BUFSIZE 4096 #define CF_EXPANDSIZE (2 * CF_BUFSIZE) /***************************************************************************** * File permissions * *****************************************************************************/ // 0600 - Read/Write for owner #define CF_PERMS_DEFAULT S_IRUSR | S_IWUSR // 0644 - World readable #define CF_PERMS_SHARED CF_PERMS_DEFAULT | S_IRGRP | S_IROTH #endif // CFENGINE_DEFINITIONS_H cfengine-3.24.2/libntech/libutils/threaded_deque.h0000644000000000000000000001522715010704254022116 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_THREADED_DEQUE_H #define CFENGINE_THREADED_DEQUE_H #include typedef struct ThreadedDeque_ ThreadedDeque; /** @brief Creates a new thread safe deque with specified capacity. @param [in] initial_capacity Initial capacity, defaults to 1. @param [in] ItemDestroy Function used to destroy data elements. @return A new ThreadedDeque on success, NULL if pthread_mutex_init or pthread_cond_init fails. */ ThreadedDeque *ThreadedDequeNew(size_t initial_capacity, void (ItemDestroy) (void *item)); /** @brief Destroys the deque and frees the memory it occupies. @warning ThreadedDeque should only be destroyed if all threads are joined @param [in] deque The deque to destroy. */ void ThreadedDequeDestroy(ThreadedDeque *deque); /** @brief Frees the memory allocated for the pointers and the struct. @param [in] deque The deque to free. */ void ThreadedDequeSoftDestroy(ThreadedDeque *deque); /** @brief Returns and removes the leftmost element of the deque. @note If deque is empty, blocks for `timeout` seconds or until signalled. If THREAD_WAIT_INDEFINITELY is specified, waits forever until signal is given. If it times out, it returns false. @param [in] deque The deque to pop from. @param [out] item The item at the first poisition in the deque. @param [in] timeout Timeout for blocking in seconds. @return true on success, false if timed out or deque was empty. */ bool ThreadedDequePopLeft(ThreadedDeque *deque, void **item, int timeout); /** @brief Returns and removes the rightmost element of the deque. @note If deque is empty, blocks for `timeout` seconds or until signalled. If THREAD_WAIT_INDEFINITELY is specified, waits forever until signal is given. If it times out, it returns false. @param [in] deque The deque to pop from. @param [out] item The item at the first poisition in the deque. @param [in] timeout Timeout for blocking in seconds. @return true on success, false if timed out or deque was empty. */ bool ThreadedDequePopRight(ThreadedDeque *deque, void **item, int timeout); /** @brief Pops num elements from the left in deque into data_array. @note If deque is empty, blocks for `timeout` seconds or until signalled. If THREAD_WAIT_INDEFINITELY is specified, waits forever until signalled. If it times out, it returns 0 and sets *data_array to NULL. @warning The pointer array will have to be freed manually. @param [in] deque The deque to pop from. @param [out] data_array Pointer to location to put popped elements. @param [in] timeout Timeout for blocking in seconds. @return Amount of elements popped. */ size_t ThreadedDequePopLeftN(ThreadedDeque *deque, void ***data_array, size_t num, int timeout); /** @brief Pops num elements from the right in deque into data_array. @note If deque is empty, blocks for `timeout` seconds or until signalled. If THREAD_WAIT_INDEFINITELY is specified, waits forever until signalled. If it times out, it returns 0 and sets *data_array to NULL. @warning The pointer array will have to be freed manually. @param [in] deque The deque to pop from. @param [out] data_array Pointer to location to put popped elements. @param [in] timeout Timeout for blocking in seconds. @return Amount of elements popped. */ size_t ThreadedDequePopRightN(ThreadedDeque *deque, void ***data_array, size_t num, int timeout); /** @brief Pushes item to left end of the deque, returns current size. @param [in] deque The deque to push to. @param [in] item The item to push. @return Current amount of elements in the deque. */ size_t ThreadedDequePushLeft(ThreadedDeque *deque, void *item); /** @brief Pushes item to right end of the deque, returns current size. @param [in] deque The deque to push to. @param [in] item The item to push. @return Current amount of elements in the deque. */ size_t ThreadedDequePushRight(ThreadedDeque *deque, void *item); /** @brief Get current number of items in deque. @note On NULL deque, returns 0. @param [in] deque The deque. @return The amount of elements in the deque. */ size_t ThreadedDequeCount(ThreadedDeque const *deque); /** @brief Get current capacity of deque. @note On NULL deque, returns 0. @param [in] deque The deque. @return The current capacity of the deque. */ size_t ThreadedDequeCapacity(ThreadedDeque const *deque); /** @brief Checks if a deque is empty. @param [in] deque The deque. @return Returns true if deque is empty, false otherwise. */ bool ThreadedDequeIsEmpty(ThreadedDeque const *deque); /** @brief Waits until deque is empty. @note Useful for situations where you want to wait before populating the deque. Timeout can be set to THREAD_BLOCK_INDEFINITELY to wait forever. Otherwise waits the amount of seconds specified. @param [in] deque The deque. @param [in] timeout Amount of seconds to wait before timing out. @return True if it successfully waited, false if it timed out. */ bool ThreadedDequeWaitEmpty(ThreadedDeque const *deque, int timeout); /** @brief Create a shallow copy of a given deque. @note This makes a new deque pointing to the same memory as the old deque. @note Is only thread safe if original deque was also thread safe. @param [in] deque The deque. @return A new deque pointing to the same data. */ ThreadedDeque *ThreadedDequeCopy(ThreadedDeque *deque); #endif // CFENGINE_THREADED_DEQUE_H cfengine-3.24.2/libntech/libutils/hash_method.h0000644000000000000000000000322615010704254021432 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * HashMethod (unfortunately) needs to be defined in cf3.defs.h. By putting it * separate here we avoid cf3.defs.h pulling the whole OpenSSL includes that * hash.h has. */ #ifndef CFENGINE_HASH_METHOD_H #define CFENGINE_HASH_METHOD_H typedef enum { HASH_METHOD_MD5, HASH_METHOD_SHA224, HASH_METHOD_SHA256, HASH_METHOD_SHA384, HASH_METHOD_SHA512, HASH_METHOD_SHA1, HASH_METHOD_SHA, HASH_METHOD_BEST, HASH_METHOD_CRYPT, HASH_METHOD_NONE } HashMethod; typedef enum { CF_MD5_LEN = 16, CF_SHA224_LEN = 28, CF_SHA256_LEN = 32, CF_SHA384_LEN = 48, CF_SHA512_LEN = 64, CF_SHA1_LEN = 20, CF_SHA_LEN = 20, CF_BEST_LEN = 0, CF_CRYPT_LEN = 64, CF_NO_HASH = 0 } HashSize; #endif /* CFENGINE_HASH_METHOD_H */ cfengine-3.24.2/libntech/libutils/string_lib.h0000644000000000000000000003144515010704254021307 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_STRING_LIB_H #define CFENGINE_STRING_LIB_H #include // bool #include // int64_t #include // strstr() #include // va_list #include #include // ssize_t typedef struct { const char *data; size_t len; } StringRef; #define NULL_OR_EMPTY(str) \ ((str == NULL) || (str[0] == '\0')) #define NOT_NULL_AND_EMPTY(str) \ ((str != NULL) && (str[0] == '\0')) #define STARTSWITH(str,start) \ (strncmp(str,start,strlen(start)) == 0) #define SAFENULL(str) \ (str != NULL ? str : "(null)") #ifndef EMPTY_STRING_TO_NULL #define EMPTY_STRING_TO_NULL(string) ((SafeStringLength(string) != 0)? string : NULL) #endif #ifndef NULL_TO_EMPTY_STRING #define NULL_TO_EMPTY_STRING(string) (string? string : "") #endif unsigned int StringHash (const char *str, unsigned int seed); unsigned int StringHash_untyped(const void *str, unsigned int seed); char ToLower(char ch); char ToUpper(char ch); void ToUpperStrInplace(char *str); void ToLowerStrInplace(char *str); int StringDecimalToLong(const char *str, long *value_out) FUNC_WARN_UNUSED_RESULT; int StringToLong(const char *str, long *value_out) FUNC_WARN_UNUSED_RESULT; void LogStringToLongError(const char *str_attempted, const char *id, int error_code); long StringToLongDefaultOnError(const char *str, long default_return); long StringToLongExitOnError(const char *str); long StringToLongUnsafe(const char *str); // Deprecated, do not use int StringToUlong(const char *str, unsigned long *value_out) FUNC_WARN_UNUSED_RESULT; unsigned long StringToUlongDefaultOnError(const char *str, unsigned long default_return); unsigned long StringToUlongExitOnError(const char *str); int StringToInt64(const char *str, int64_t *value_out); int64_t StringToInt64DefaultOnError(const char *str, int64_t default_return); int64_t StringToInt64ExitOnError(const char *str); char *StringFromLong(long number); double StringToDouble(const char *str); char *StringFromDouble(double number); char *NULLStringToEmpty(char *str); bool StringIsNumeric(const char *name); bool StringIsPrintable(const char *name); /** * @brief Check if a char is "printable", replacement for isprint * * isprint takes a (signed) int, so if you send in a (signed) char there is an * implicit cast. This can be problematic, since 0xF0 becomes 0xFFFFF0. * * Additionally, at least on HPUX, isprint returns true for some values above * 127, depending on locale. * * Thus, this replacement works the same everywhere, and can be used when you * want predictable results, even though it will return false for some values * which might be possible to print in your environment / locale. * * @param c [in] Character to evaluate * @return True if c is part of the printable ascii range */ static inline bool CharIsPrintableAscii(const char c) { return (c >= ' ' && c <= '~'); } bool EmptyString(const char *s); static inline bool StringContains(const char *const haystack, const char *const needle) { return (strstr(haystack, needle) != NULL); } static inline bool StringContainsChar(const char *const haystack, const char needle) { return (strchr(haystack, needle) != NULL); } size_t StringBytesToHex(char *dst, size_t dst_size, const unsigned char *src_bytes, size_t src_len); char *SafeStringDuplicate(const char *str); char *SafeStringNDuplicate(const char *str, size_t size); int SafeStringLength(const char *str); int StringSafeCompare(const char *a, const char *b); bool StringEqual (const char *a, const char *b); /** * @brief Check for string in array of strings. * @param str string to check for. * @param array array of strings to search. * @param n_items number of elements in array. * @return true if string is found in array. */ static inline bool IsStringInArray( const char *const str, const char *const *const array, const size_t n_items) { assert(str != NULL); assert(array != NULL); for (size_t i = 0; i < n_items; i++) { assert(array[i] != NULL); if (StringEqual(array[i], str)) { return true; } } return false; } int StringSafeCompareN(const char *a, const char *b, size_t n); bool StringEqualN (const char *a, const char *b, size_t n); int StringSafeCompare_IgnoreCase(const char *a, const char *b); bool StringEqual_IgnoreCase (const char *a, const char *b); int StringSafeCompareN_IgnoreCase(const char *a, const char *b, size_t n); bool StringEqualN_IgnoreCase (const char *a, const char *b, size_t n); bool StringEqual_untyped(const void *a, const void *b); char *StringConcatenate(size_t count, const char *first, ...); char *StringSubstring(const char *source, size_t source_len, int start, int len); /* Allocates the result */ char *SearchAndReplace(const char *source, const char *search, const char *replace); ssize_t StringReplace(char *buf, size_t buf_size, const char *find, const char *replace); ssize_t StringReplaceN(char *buf, size_t buf_size, const char *find, const char *replace, size_t n); bool IsStrIn(const char *str, const char *const strs[]); bool IsStrCaseIn(const char *str, const char *const strs[]); size_t StringCountTokens(const char *str, size_t len, const char *seps); StringRef StringGetToken(const char *str, size_t len, size_t index, const char *seps); char **String2StringArray(const char *str, char separator); void FreeStringArray(char **strs); int CountChar(const char *string, char sp); void ReplaceChar(const char *in, char *out, int outSz, char from, char to); void ReplaceTrailingChar(char *str, char from, char to); char *EscapeCharCopy(const char *str, char to_escape, char escape_with); char *ScanPastChars(char *scanpast, char *input); /** * @brief Strips the newline character off a string, in place * @param str The string to strip * @param max_length Maximum length of input string * @return 0 if successful, -1 if the input string was longer than allowed (max_length). */ int StripTrailingNewline(char *str, size_t max_length); /** * @brief Remove trailing spaces * @param str * @param max_length Maximum length of input string * @return 0 if successful, -1 if Chop was called on a string that seemed to have no terminator */ int Chop(char *str, size_t max_length); char *TrimWhitespace(char *s); size_t TrimCSVLineCRLF(char *data); size_t TrimCSVLineCRLFStrict(char *data); /** * @brief Erase part of a string using memmove() * * String must be NUL-terminated. Indices from start, up to but not including * end are erased. The number of bytes erased is end - start. If start == end, * no bytes are erased. Assumes: 0 <= start <= end <= strlen(s) */ void StringCloseHole(char *s, size_t start, size_t end); /** * @brief Check if a string ends with the given suffix * @param str * @param suffix * @param case_fold whether the comparison is case-insensitive * @return True if suffix matches */ bool StringEndsWithCase(const char *str, const char *suffix, const bool case_fold); /** * @brief Check if a string ends with the given suffix * @param str * @param suffix * @return True if suffix matches */ bool StringEndsWith(const char *str, const char *suffix); /** * @brief Check if a string starts with the given prefix * @param str * @param prefix * @return True if prefix matches */ bool StringStartsWith(const char *str, const char *prefix); /** * @brief Format string like vsprintf and return formatted string allocated * on heap as a return value. */ char *StringVFormat(const char *fmt, va_list ap); /** * @brief Format string like sprintf and return formatted string allocated on * heap as a return value. * * @param format Formatting string * @return formatted string (on heap) or NULL in case of error. errno is set in * the latter case (see errno codes for sprintf). */ char *StringFormat(const char *fmt, ...) FUNC_WARN_UNUSED_RESULT FUNC_ATTR_PRINTF(1, 2); /** * @brief Copy a string from `from` to `to` (a buffer of at least buf_size) * * The destination (`to`) is guaranteed to be NUL terminated, * `to[buf_size-1]` will always be '\0'. If the string is shorter * the additional trailing bytes are also zeroed. * * The source (`from`) must either be NUL terminated or big enough * to read buf_size characters, even though only buf_size - 1 of them * end up in the output buffer. * * The return value is equal to `strlen(to)`, for large data sizes this * is useful since it doesn't require a second pass through the data. * The return value should be checked, if it is >= buf_size, it means * the string was truncated because it was too long. Expressed in another * way, the return value is the number of bytes read from the input (`from`) * excluding the terminating `\0` byte (up to buf_size characters will be * read). * * @note `from` and `to` must not overlap * @warning Regardless of `strlen(from)`, `to` must be at least `buf_size` big * @param[in] from String to copy from, up to buf_size bytes are read * @param[out] to Output buffer (minimum buf_size), always '\0' terminated * @param[in] buf_size Maximum buffer size to write (including '\0' byte) * @return String length of `to`, or `buf_size` in case of overflow */ size_t StringCopy(const char *from, char *to, size_t buf_size); void *memcchr(const void *buf, int c, size_t buf_size); bool StringNotMatchingSetCapped(const char *isp, size_t limit, const char *exclude, char *obuf); /** * @brief Appends src to dst, but will not exceed n bytes in dst, including the terminating null. * @param dst Destination string. * @param src Source string. * @param n Total size of dst buffer. The string will be truncated if this is exceeded. * @return True if append was successful, false if the operation caused an overflow. */ bool StringAppend(char *dst, const char *src, size_t n); char *StringCanonify(char *dst, const char *src); bool PathAppend(char *path, size_t path_size, const char *leaf, char sep); void StrCat(char *dst, size_t dst_size, size_t *dst_len, const char *src, size_t src_len); void StrCatDelim(char *dst, size_t dst_size, size_t *dst_len, const char *src, char sep); void CanonifyNameInPlace(char *str); /** * @brief Check if a command line argument matches a short or long option * * Useful for smaller binaries, when getopt seems overkill and you just want * something simple. A match means it's either equal to shortopt or equal to * (the first part of) longopt. shortopt is compared case sensitively, * while longopt is compared case insensitively. * * As an example, `--INFO` would match the longopt `--inform`. * * It doesn't (cannot) detect ambiguities when there are multiple options. * In many cases, where you need more flexibility and consistency, it's better * to use getopt or something similar. * * @param[in] supplied User supplied argument from command line (trimmed word) * @param[out] longopt Long option alternative to check (ex. "--help") * @param[out] shortopt Short option alternative to check (ex. "-H") * @return True if `supplied` _matches_ `longopt` or `shortopt` */ bool StringMatchesOption( const char *supplied, const char *longopt, const char *shortopt); /** * @brief Finds the first occurrence of substring in string. * @param[in] str String to search in (not NULL). * @param[in] sub Substring to search for (not NULL). * @param[in] from Index to search from. * @param[in] to Index to search to (but not including). * @note This function never scans beyond the NUL-bytes terminating the strings. * Thus, one can safely (i.e., without risking memory access violation) * use larger indices than the strings themselves. However, then you * wouldn't find what you're looking for ;) Likewise, it's safe to search * for substrings larger than the string to search in itself. * @return Index of first occurrence of sub in str, or -1 if not found. */ ssize_t StringFind(const char *str, const char *sub, size_t from, size_t to); #endif cfengine-3.24.2/libntech/libutils/writer.h.in0000644000000000000000000000572415010704254021075 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_WRITER_H #define CFENGINE_WRITER_H /* * Abstract "writer". * * Writes passed data either to * passed FILE*, or * memory buffer */ typedef struct Writer_ Writer; #include // FILE #include // bool #include // va_list #include /* Set by ./configure allowing us to avoid #include here. */ @HAVE_GETOPT_H_DEFINE@ #ifdef HAVE_GETOPT_H #include #else #ifndef _GETOPT_H /* in case something included it from somewhere anyway */ /* We actually only need the 'struct option' type from the header here so just * defined it ourselves if we cannot get it from the header. */ struct option { const char *name; int has_arg; int *flag; int val; }; #endif /* _GETOPT_H */ #endif /* HAVE_GETOPT_H */ Writer *FileWriter(FILE *); Writer *StringWriter(void); size_t WriterWriteF(Writer *writer, const char *fmt, ...) FUNC_ATTR_PRINTF(2, 3); size_t WriterWriteVF(Writer *writer, const char *fmt, va_list ap) FUNC_ATTR_PRINTF(2, 0); size_t WriterWrite(Writer *writer, const char *str); size_t WriterWriteLen(Writer *writer, const char *str, size_t len); size_t WriterWriteChar(Writer *writer, char c); size_t StringWriterLength(const Writer *writer); const char *StringWriterData(const Writer *writer); void WriterClose(Writer *writer); /* Returns modifiable string and destroys itself */ char *StringWriterClose(Writer *writer) FUNC_WARN_UNUSED_RESULT; /* Returns the open file and destroys itself */ FILE *FileWriterDetach(Writer *writer); /* Commonly used on a FileWriter(stdout), ignoring return; so don't * try to warn on unused result ! */ typedef struct { const char *name; const char *description; const char *usage; } Description; typedef struct { const char *name; const char *website; const char *copyright; } Component; void WriterWriteHelp(Writer *w, const Component *component, const struct option options[], const char *const hints[], const Description *commands, bool command_first, bool accepts_file_argument); #endif cfengine-3.24.2/libntech/libutils/string_lib.c0000644000000000000000000012173215010704254021301 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include // CF_BUFSIZE #include // nt_static_assert() #include char *StringVFormat(const char *fmt, va_list ap) { char *value; int ret = xvasprintf(&value, fmt, ap); if (ret < 0) { return NULL; } else { return value; } } char *StringFormat(const char *fmt, ...) { va_list ap; va_start(ap, fmt); char *res = StringVFormat(fmt, ap); va_end(ap); return res; } size_t StringCopy(const char *const from, char *const to, const size_t buf_size) { assert(from != NULL); assert(to != NULL); assert(from != to); memset(to, 0, buf_size); strncpy(to, from, buf_size); if (to[buf_size-1] != '\0') { to[buf_size-1] = '\0'; return buf_size; } return strlen(to); // TODO - Replace the extra pass by using stpncpy: /* // stpncpy has bad/unsafe behavior when string is too long: // * Does not NUL terminate // * Returns a pointer to potentially invalid memory // These issues have to be handled (even for correct arguments) const char *const end = stpncpy(to, from, buf_size); assert(end >= to); const long len = end - to; to[buf_size] = '\0'; return len; */ } unsigned int StringHash(const char *str, unsigned int seed) { assert(str != NULL); unsigned const char *p = (unsigned const char *) str; unsigned int h = seed; // NULL is not allowed, but we will prevent segfault anyway: size_t len = (str != NULL) ? strlen(str) : 0; /* https://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time */ for (size_t i = 0; i < len; i++) { h += p[i]; h += (h << 10); h ^= (h >> 6); } h += (h << 3); h ^= (h >> 11); h += (h << 15); return h; } unsigned int StringHash_untyped(const void *str, unsigned int seed) { return StringHash(str, seed); } char ToLower(char ch) { if (isupper((unsigned char) ch)) { return (ch - 'A' + 'a'); } else { return (ch); } } /*********************************************************************/ char ToUpper(char ch) { if ((isdigit((unsigned char) ch)) || (ispunct((unsigned char) ch))) { return (ch); } if (isupper((unsigned char) ch)) { return (ch); } else { return (ch - 'a' + 'A'); } } /*********************************************************************/ void ToUpperStrInplace(char *str) { for (; *str != '\0'; str++) { *str = ToUpper(*str); } } /*********************************************************************/ void ToLowerStrInplace(char *str) { for (; *str != '\0'; str++) { *str = ToLower(*str); } } /*********************************************************************/ char *SafeStringDuplicate(const char *str) { if (str == NULL) { return NULL; } return xstrdup(str); } /*********************************************************************/ char *SafeStringNDuplicate(const char *str, size_t size) { if (str == NULL) { return NULL; } return xstrndup(str, size); } /*********************************************************************/ int SafeStringLength(const char *str) { if (str == NULL) { return 0; } return strlen(str); } // Compare two pointers (strings) where exactly one is NULL static int NullCompare(const void *const a, const void *const b) { assert(a != b); assert(a == NULL || b == NULL); if (a != NULL) { return 1; } if (b != NULL) { return -1; } // Should never happen ProgrammingError("Programming Error: NullCompare failed"); return 101; } int StringSafeCompare(const char *const a, const char *const b) { if (a == b) // Same address or both NULL { return 0; } if (a != NULL && b != NULL) { // Adding this as strcmp gives difference of the buffer values in aarch64 // Whereas it gives 1, 0 or -1 in other platforms accordingly. int compare_result = strcmp(a, b); if (compare_result != 0) { compare_result = compare_result / abs(compare_result); } return compare_result; } // Weird edge cases where one is NULL: return NullCompare(a, b); } int StringSafeCompareN(const char *const a, const char *const b, const size_t n) { if (a == b) // Same address or both NULL { return 0; } if (a != NULL && b != NULL) { return strncmp(a, b, n); } // Weird edge cases where one is NULL: return NullCompare(a, b); } bool StringEqual(const char *const a, const char *const b) { return (StringSafeCompare(a, b) == 0); } bool StringEqualN(const char *const a, const char *const b, const size_t n) { return (StringSafeCompareN(a, b, n) == 0); } int StringSafeCompare_IgnoreCase(const char *const a, const char *const b) { if (a == b) // Same address or both NULL { return 0; } if (a != NULL && b != NULL) { return strcasecmp(a, b); } // Weird edge cases where one is NULL: return NullCompare(a, b); } int StringSafeCompareN_IgnoreCase(const char *const a, const char *const b, const size_t n) { if (a == b) // Same address or both NULL { return 0; } if (a != NULL && b != NULL) { return strncasecmp(a, b, n); } // Weird edge cases where one is NULL: return NullCompare(a, b); } bool StringEqual_IgnoreCase(const char *const a, const char *const b) { return (StringSafeCompare_IgnoreCase(a, b) == 0); } bool StringEqualN_IgnoreCase(const char *const a, const char *const b, const size_t n) { return (StringSafeCompareN_IgnoreCase(a, b, n) == 0); } bool StringEqual_untyped(const void *a, const void *b) { return StringEqual(a, b); } /*********************************************************************/ char *SearchAndReplace(const char *source, const char *search, const char *replace) { const char *source_ptr = source; if ((source == NULL) || (search == NULL) || (replace == NULL)) { ProgrammingError("Programming error: NULL argument is passed to SearchAndReplace"); } if (strcmp(search, "") == 0) { return xstrdup(source); } Writer *w = StringWriter(); for (;;) { const char *found_ptr = strstr(source_ptr, search); if (found_ptr == NULL) { WriterWrite(w, source_ptr); return StringWriterClose(w); } WriterWriteLen(w, source_ptr, found_ptr - source_ptr); WriterWrite(w, replace); source_ptr += found_ptr - source_ptr + strlen(search); } } /*********************************************************************/ char *StringConcatenate(size_t count, const char *first, ...) { if (count < 1) { return NULL; } size_t total_length = first ? strlen(first) : 0; va_list args; va_start(args, first); for (size_t i = 1; i < count; i++) { const char *arg = va_arg(args, const char*); if (arg) { total_length += strlen(arg); } } va_end(args); char *result = xcalloc(total_length + 1, sizeof(char)); if (first) { strcat(result, first); } va_start(args, first); for (size_t i = 1; i < count; i++) { const char *arg = va_arg(args, const char *); if (arg) { strcat(result, arg); } } va_end(args); return result; } /*********************************************************************/ char *StringSubstring(const char *source, size_t source_len, int start, int len) { ssize_t end = -1; if (len == 0) { return SafeStringDuplicate(""); } else if (len < 0) { end = source_len + len - 1; } else { end = start + len - 1; } end = MIN(end, source_len - 1); if (start < 0) { start = source_len + start; } if (start >= end) { return NULL; } char *result = xcalloc(end - start + 2, sizeof(char)); memcpy(result, source + start, end - start + 1); return result; } /*********************************************************************/ bool StringIsNumeric(const char *s) { for (; *s; s++) { if (!isdigit((unsigned char)*s)) { return false; } } return true; } bool StringIsPrintable(const char *s) { for (; *s; s++) { if (!isprint((unsigned char)*s)) { return false; } } return true; } bool EmptyString(const char *s) { const char *sp; for (sp = s; *sp != '\0'; sp++) { if (!isspace((unsigned char)*sp)) { return false; } } return true; } /*********************************************************************/ /** * @brief Converts a string of numerals in base 10 to a long integer. * * Result is stored in *value_out, return value should be checked. * On error *value_out is unmodified and an error code is returned. * Leading spaces in input string are skipped. * String numeral must be terminated by NULL byte or space (isspace). * * @see StringToLongExitOnError() * @see StringToLongDefaultOnError() * @param[in] str String with numerals to convert, cannot be NULL * @param[out] value_out Where to store result on success, cannot be NULL * @return 0 on success, error code otherwise (see source code) */ int StringToLong(const char *str, long *value_out) { nt_static_assert(ERANGE != 0); assert(str != NULL); assert(value_out != NULL); char *endptr = NULL; errno = 0; const long val = strtol(str, &endptr, 10); if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))) { return ERANGE; // Overflow or underflow } if (endptr == str) { return -81; // No digits found } if (endptr == NULL) { return -82; // endpointer not set by strtol } if (*endptr != '\0' && !isspace(*endptr)) { return -83; // string not properly terminated } if (errno != 0) { return errno; // Unknown error } *value_out = val; return 0; } /** * @brief Convert a string representing a real number to int, discarding the decimal part. * * Attempts to find the first '.' character in order to copy the integer part to a * temporary array before passing it to StringToLong. Should the input string be * an entire integer by itself no copying occurs. The integer part must NOT exceed 12 digits. * * @param[in] str String matching the regex \d+(\.\d+)?, cannot be NULL * @param[out] value_out Where to store result on success, cannot be NULL * @return 0 on success, -84 if the integer part is too long or other error code otherwise (see StringToLong source code) */ int StringDecimalToLong(const char *str, long *value_out) { assert(str != NULL); assert(value_out != NULL); size_t len_of_int_part = strcspn(str, "."); if (len_of_int_part > PRINTSIZE(INT_MAX)) { return -84; // Integer part too large to allocate buffer } if (len_of_int_part == 0 || str[len_of_int_part] == '\0') { return StringToLong(str, value_out); } char int_part[len_of_int_part + 1]; strncpy(int_part, str, len_of_int_part); int_part[len_of_int_part] = '\0'; return StringToLong(int_part, value_out); } /** * @brief Log StringToLong & StringToUlong & StringDecimalToLong conversion error * with an identifier for debugging. */ void LogStringToLongError(const char *str_attempted, const char *id, int error_code) { assert(error_code != 0); const char *error_str = "Unknown"; switch (error_code) { case ERANGE: error_str = "Overflow"; break; case -81: error_str = "No digits"; break; case -82: error_str = "No endpointer"; break; case -83: error_str = "Not terminated"; break; case -84: error_str = "Integer part too large"; break; } Log(LOG_LEVEL_ERR, "Conversion error (%d - %s) on '%s' (%s)", error_code, error_str, str_attempted, id); } /** * @brief Converts a string of numerals in base 10 to a long integer, * uses a default value if errors occur. * * @see StringToLong() * @param[in] str String with numerals to convert, cannot be NULL * @param[in] default_return Value to return on error * @return Result of conversion (or default_return in case of error) */ long StringToLongDefaultOnError(const char *str, long default_return) { assert(str != NULL); long result = 0; int return_code = StringToLong(str, &result); if (return_code != 0) { // Do not log anything because this can be used frequently return default_return; } return result; } /** * @brief Converts a string of numerals in base 10 to a long integer, exits on error. * * Only use this function in contexts/components where it is acceptable * to immediately exit when something goes wrong. * * @warning This function can exit the process based on string contents * @see StringToLong() * @param[in] str String with numerals to convert, cannot be NULL * @return Result of conversion */ long StringToLongExitOnError(const char *str) { assert(str != NULL); long result; int return_code = StringToLong(str, &result); if (return_code != 0) { LogStringToLongError(str, "StringToLongExitOnError", return_code); DoCleanupAndExit(EXIT_FAILURE); } return result; } /** * @brief Converts a string of numerals in base 10 to a unsigned long * integer. * * Result is stored in *value_out, return value should be checked. * On error *value_out is unmodified and an error code is returned. * Leading spaces in input string are skipped. * String numeral must be terminated by NULL byte or space (isspace). * * @see StringToUlongExitOnError() * @see StringToUlongDefaultOnError() * @param[in] str String with numerals to convert, cannot be NULL * @param[out] value_out Where to store result on success, cannot be NULL * @return 0 on success, error code otherwise (see source code) */ int StringToUlong(const char *str, unsigned long *value_out) { nt_static_assert(ERANGE != 0); assert(str != NULL); assert(value_out != NULL); char *endptr = NULL; errno = 0; const unsigned long val = strtoul(str, &endptr, 10); if ((errno == ERANGE && val == ULONG_MAX)) { return ERANGE; // Overflow } // Negative numbers should cause underflow if (val > 0) // "-0" is ok { const char *ch = str; while (ch < endptr && isspace(*ch)) ch++; if (*ch == '-') { return ERANGE; // Underflow } } if (endptr == str) { return -81; // No digits found } if (endptr == NULL) { return -82; // endpointer not set by strtol } if (*endptr != '\0' && !isspace(*endptr)) { return -83; // string not properly terminated } if (errno != 0) { return errno; // Unknown error } *value_out = val; return 0; } /** * @brief Converts a string of numerals in base 10 to a unsigned long * integer, uses a default value if errors occur. * * @see StringToUlong() * @param[in] str String with numerals to convert, cannot be NULL * @param[in] default_return Value to return on error * @return Result of conversion (or default_return in case of error) */ unsigned long StringToUlongDefaultOnError(const char *str, unsigned long default_return) { assert(str != NULL); unsigned long result = 0; int return_code = StringToUlong(str, &result); if (return_code != 0) { // Do not log anything because this can be used frequently return default_return; } return result; } /** * @brief Converts a string of numerals in base 10 to a unsigned long * integer, exits on error. * * Only use this function in contexts/components where it is acceptable * to immediately exit when something goes wrong. * * @warning This function can exit the process based on string contents * @see StringToUlong() * @param[in] str String with numerals to convert, cannot be NULL * @return Result of conversion */ unsigned long StringToUlongExitOnError(const char *str) { assert(str != NULL); unsigned long result; int return_code = StringToUlong(str, &result); if (return_code != 0) { LogStringToLongError(str, "StringToUlongExitOnError", return_code); DoCleanupAndExit(EXIT_FAILURE); } return result; } /** * @brief Converts a string of numerals in base 10 to 64-bit signed int * * Result is stored in *value_out, return value should be checked. * On error *value_out is unmodified and false is returned. * * @see StringToLong() * @param[in] str String with numerals to convert, cannot be NULL * @param[out] value_out Where to store result on success, cannot be NULL * @return 0 on success, error code otherwise (see source code) */ int StringToInt64(const char *str, int64_t *value_out) { nt_static_assert(sizeof(int64_t) == sizeof(intmax_t)); nt_static_assert(ERANGE != 0); assert(str != NULL); assert(value_out != NULL); char *endptr = NULL; int64_t val; errno = 0; val = strtoimax(str, &endptr, 10); if ((errno == ERANGE && (val == INTMAX_MAX || val == INTMAX_MIN))) { return ERANGE; // Overflow or underflow } if (endptr == str) { return -81; // No digits found } if (endptr == NULL) { return -82; // endpointer not set by strtol } if (*endptr != '\0' && !isspace(*endptr)) { return -83; // string not properly terminated } if (errno != 0) { return errno; // Unknown error } *value_out = val; return 0; } /** * @brief Convert a string to int64_t, exits if parsing fails * * Only use this function in contexts/components where it is acceptable * to immediately exit when something goes wrong. * * @warning This function can exit the process based on string contents * @see StringToInt64() * @see StringToLongExitOnError() * @param[in] str String with numerals to convert, cannot be NULL * @return Result of conversion */ int64_t StringToInt64ExitOnError(const char *str) { assert(str != NULL); int64_t result; const int error_code = StringToInt64(str, &result); if (error_code != 0) { LogStringToLongError(str, "StringToInt64ExitOnError", error_code); DoCleanupAndExit(EXIT_FAILURE); } return result; } /** * @brief Converts a string to int64_t, with a default value in case of errors * * @see StringToInt64() * @see StringToLongDefaultOnError() * @param[in] str String with numerals to convert, cannot be NULL * @param[in] default_return Value to return on error * @return Result of conversion */ int64_t StringToInt64DefaultOnError(const char *str, int64_t default_return) { assert(str != NULL); int64_t result; const int error_code = StringToInt64(str, &result); if (error_code != 0) { return default_return; } return result; } /** * @brief Convert a string of numerals to a long integer (deprecated). * * @warning This function is deprecated, do not use it * @warning This function can exit the process based on string contents * @see StringToLongExitOnError() * @param[in] str String with numerals to convert, cannot be NULL * @return Result of conversion */ long StringToLongUnsafe(const char *str) { assert(str); char *end; long result = strtol(str, &end, 10); // This is bad: assert(!*end && "Failed to convert string to long"); return result; } char *StringFromLong(long number) { char *str = xcalloc(32, sizeof(char)); snprintf(str, 32, "%ld", number); return str; } /*********************************************************************/ double StringToDouble(const char *str) { assert(str); char *end; double result = strtod(str, &end); assert(!*end && "Failed to convert string to double"); return result; } char *StringFromDouble(double number) { return StringFormat("%.2f", number); } /*********************************************************************/ char *NULLStringToEmpty(char *str) { if(!str) { return ""; } return str; } /** * @NOTE this function always '\0'-terminates the destination string #dst. * @return length of written string #dst. */ size_t StringBytesToHex(char *dst, size_t dst_size, const unsigned char *src_bytes, size_t src_len) { static const char *const hex_chars = "0123456789abcdef"; size_t i = 0; while ((i < src_len) && (i*2 + 2 < dst_size)) /* room for 2 more hex chars */ { dst[2*i] = hex_chars[(src_bytes[i] >> 4) & 0xf]; dst[2*i + 1] = hex_chars[src_bytes[i] & 0xf]; i++; } assert(2*i < dst_size); dst[2*i] = '\0'; return 2*i; } bool IsStrIn(const char *str, const char *const strs[]) { int i; for (i = 0; strs[i]; ++i) { if (strcmp(str, strs[i]) == 0) { return true; } } return false; } bool IsStrCaseIn(const char *str, const char *const strs[]) { int i; for (i = 0; strs[i]; ++i) { if (strcasecmp(str, strs[i]) == 0) { return true; } } return false; } int CountChar(const char *string, char sep) { int count = 0; if (string == NULL) { return 0; } if (string && (strlen(string) == 0)) { return 0; } for (const char *sp = string; *sp != '\0'; sp++) { if ((*sp == '\\') && (*(sp + 1) == sep)) { ++sp; } else if (*sp == sep) { count++; } } return count; } void ReplaceChar(const char *in, char *out, int outSz, char from, char to) /* Replaces all occurrences of 'from' to 'to' in preallocated * string 'out'. */ { int len; int i; memset(out, 0, outSz); len = strlen(in); for (i = 0; (i < len) && (i < outSz - 1); i++) { if (in[i] == from) { out[i] = to; } else { out[i] = in[i]; } } } /** * Replace all occurrences of #find with #replace. * * @return the length of #buf or -1 in case of overflow, or 0 if no replace * took place. */ ssize_t StringReplace(char *buf, size_t buf_size, const char *find, const char *replace) { return StringReplaceN(buf, buf_size, find, replace, buf_size); } /** * Replace the first at most #n occurrences of #find in #buf with #replace. * * @return the length of #buf or -1 in case of overflow, or 0 if no replace * took place. */ ssize_t StringReplaceN(char *buf, size_t buf_size, const char *find, const char *replace, size_t n) { assert(find[0] != '\0'); if (n == 0) { return 0; } char *p = strstr(buf, find); if (p == NULL) { return 0; } size_t find_len = strlen(find); size_t replace_len = strlen(replace); size_t buf_len = strlen(buf); size_t buf_idx = 0; char tmp[buf_size]; ssize_t tmp_len = 0; /* Do all replacements we find. */ do { size_t buf_newidx = p - buf; size_t prefix_len = buf_newidx - buf_idx; if (tmp_len + prefix_len + replace_len >= buf_size) { return -1; } memcpy(&tmp[tmp_len], &buf[buf_idx], prefix_len); tmp_len += prefix_len; memcpy(&tmp[tmp_len], replace, replace_len); tmp_len += replace_len; buf_idx = buf_newidx + find_len; p = strstr(&buf[buf_idx], find); n--; } while ((p != NULL) && (n > 0)); /* Copy leftover plus terminating '\0'. */ size_t leftover_len = buf_len - buf_idx; if (tmp_len + leftover_len >= buf_size) { return -1; } memcpy(&tmp[tmp_len], &buf[buf_idx], leftover_len + 1); tmp_len += leftover_len; /* And finally copy to source, we are supposed to modify it in place. */ memcpy(buf, tmp, tmp_len + 1); return tmp_len; } void ReplaceTrailingChar(char *str, char from, char to) /* Replaces any unwanted last char in str. */ { int strLen; strLen = SafeStringLength(str); if (strLen == 0) { return; } if (str[strLen - 1] == from) { str[strLen - 1] = to; } } static StringRef StringRefNull(void) { return (StringRef) { .data = NULL, .len = 0 }; } size_t StringCountTokens(const char *str, size_t len, const char *seps) { size_t num_tokens = 0; bool in_token = false; for (size_t i = 0; i < len; i++) { if (strchr(seps, str[i])) { in_token = false; } else { if (!in_token) { num_tokens++; } in_token = true; } } return num_tokens; } static StringRef StringNextToken(const char *str, size_t len, const char *seps) { size_t start = 0; bool found = false; for (size_t i = 0; i < len; i++) { if (strchr(seps, str[i])) { if (found) { assert(i > 0); return (StringRef) { .data = str + start, .len = i - start }; } } else { if (!found) { found = true; start = i; } } } if (found) { return (StringRef) { .data = str + start, .len = len - start }; } else { return StringRefNull(); } } StringRef StringGetToken(const char *str, size_t len, size_t index, const char *seps) { StringRef ref = StringNextToken(str, len, seps); for (size_t i = 0; i < index; i++) { if (!ref.data) { return ref; } len = len - (ref.data - str + ref.len); str = ref.data + ref.len; ref = StringNextToken(str, len, seps); } return ref; } char **String2StringArray(const char *str, char separator) /** * Parse CSVs into char **. * MEMORY NOTE: Caller must free return value with FreeStringArray(). **/ { int i = 0, len; if (str == NULL) { return NULL; } for (const char *sp = str; *sp != '\0'; sp++) { if (*sp == separator) { i++; } } char **arr = (char **) xcalloc(i + 2, sizeof(char *)); const char *sp = str; i = 0; while (sp) { const char *esp = strchr(sp, separator); if (esp) { len = esp - sp; esp++; } else { len = strlen(sp); } arr[i] = xcalloc(len + 1, sizeof(char)); memcpy(arr[i], sp, len); sp = esp; i++; } return arr; } void FreeStringArray(char **strs) { int i; if (strs == NULL) { return; } for (i = 0; strs[i] != NULL; i++) { free(strs[i]); strs[i] = NULL; } free(strs); } char *EscapeCharCopy(const char *str, char to_escape, char escape_with) /* * Escapes the 'to_escape'-chars found in str, by prefixing them with 'escape_with'. * Returns newly allocated string. */ { assert(str); size_t in_size = strlen(str); if(in_size > (SIZE_MAX / 2) - 1) { ProgrammingError("Buffer passed to EscapeCharCopy() too large (in_size=%zd)", in_size); } size_t out_size = in_size + CountChar(str, to_escape) + 1; char *out = xcalloc(1, out_size); const char *in_pos = str; char *out_pos = out; for(; *in_pos != '\0'; in_pos++, out_pos++) { if(*in_pos == to_escape) { *out_pos = escape_with; out_pos++; } *out_pos = *in_pos; } return out; } char *ScanPastChars(char *scanpast, char *input) { char *pos = input; while ((*pos != '\0') && (strchr(scanpast, *pos))) { pos++; } return pos; } int StripTrailingNewline(char *str, size_t max_length) { if (str) { size_t i = strnlen(str, max_length + 1); if (i > max_length) /* See off-by-one comment below */ { return -1; } while (i > 0 && str[i - 1] == '\n') { i--; } assert(str[i] == '\0' || str[i] == '\n'); str[i] = '\0'; } return 0; } /** * Removes trailing whitespace from a string. * * @WARNING Off-by-one quirk in max_length. * * Both StripTrailngNewline() and Chop() have long allowed callers to * pass (effectively) the strlen(str) rather than the size of memory * (which is at least strlen() + 1) in the buffer. The present * incarnation thus reads max_length as max-strlen(), not as size of * the buffer. It may be sensible to review all callers and change so * that max_length is the buffer size instead. * * TODO change Chop() to accept str_len parameter. It goes without saying that * the callers should call it as: Chop(s, strlen(s)); */ int Chop(char *str, size_t max_length) { if (str) { size_t i = strnlen(str, max_length + 1); if (i > max_length) /* See off-by-one comment above */ { /* Given that many callers don't even check Chop's return value, * we should NULL-terminate the string here. TODO. */ return -1; } while (i > 0 && isspace((unsigned char)str[i-1])) { i--; } assert(str[i] == '\0' || isspace((unsigned char)str[i])); str[i] = '\0'; } return 0; } char *TrimWhitespace(char *s) { assert(s); // Leading whitespace: while (isspace(s[0])) { ++s; } // Empty string (only whitespace): if (s[0] == '\0') { return s; } // Trailing whitespace: char *end = s + strlen(s) - 1; // Last byte before '\0' while ( isspace(end[0]) ) { --end; } end[1] = '\0'; // Null terminate string after last non space char return s; } /** * @brief Remove the CRLF at the end of a CSV line, if it exists * * For use in networking / reporting protocols. For old clients which send a * CRLF it will remove exactly 1 occurence of CRLF. For new clients which * don't send CRLF, it will remove nothing. Thus, it should be compatible * with both. Does not trim any other whitespace, because we don't expect any * other whitespace to be there, and if it did, this could mask important * errors. * * @see CsvWriterNewRecord() * @param data NUL-terminated string with one line of CSV data, cannot be NULL * @return strlen(data), after trimming */ size_t TrimCSVLineCRLF(char *const data) { assert(data != NULL); size_t length = strlen(data); assert(data[length] == '\0'); if (length < 2) { return length; } if (data[length - 2] == '\r' && data[length - 1] == '\n') { data[length - 2] = '\0'; data[length - 1] = '\0'; length -= 2; } assert(length == strlen(data)); return length; } /** * @brief Remove the CRLF at the end of a non-empty CSV line, if it exists * * Based on `TrimCSVLineCRLF()`, adds a lot of assertions for bad cases we * want to detect in testing. * * @see TrimCSVLineCRLF() * @param data NUL-terminated string with one line of CSV data, cannot be NULL * @return strlen(data), after trimming */ size_t TrimCSVLineCRLFStrict(char *const data) { assert(data != NULL); assert(strlen(data) > 0); assert(strlen(data) < 4096); assert(!isspace(data[0])); const size_t length = TrimCSVLineCRLF(data); assert(length == strlen(data)); assert(length > 0); assert(!isspace(data[length - 1])); assert(!isspace(data[0])); return length; } void StringCloseHole(char *s, const size_t start, const size_t end) { assert(s != NULL); assert(start <= end && end <= strlen(s)); assert((end - start) <= strlen(s)); if (end > start) { memmove(s + start, s + end, /* The 1+ ensures we copy the final '\0' */ strlen(s + end) + 1); } } bool StringEndsWithCase(const char *str, const char *suffix, const bool case_fold) { size_t str_len = strlen(str); size_t suffix_len = strlen(suffix); if (suffix_len > str_len) { return false; } for (size_t i = 0; i < suffix_len; i++) { char a = str[str_len - i - 1]; char b = suffix[suffix_len - i - 1]; if (case_fold) { a = ToLower(a); b = ToLower(b); } if (a != b) { return false; } } return true; } bool StringEndsWith(const char *str, const char *suffix) { return StringEndsWithCase(str, suffix, false); } bool StringStartsWith(const char *str, const char *prefix) { int str_len = strlen(str); int prefix_len = strlen(prefix); if (prefix_len > str_len) { return false; } for (int i = 0; i < prefix_len; i++) { if (str[i] != prefix[i]) { return false; } } return true; } /** * Returns pointer to the first byte in #buf that is not #c. Returns NULL if * all of #buf contains only bytes of value #c. * * @NOTE this functions complements memchr() from POSIX. * * @TODO move to libcompat, it appears to be available in some systems. */ void *memcchr(const void *buf, int c, size_t buf_size) { const char *cbuf = buf; for (size_t i = 0; i < buf_size; i++) { if (cbuf[i] != c) { return (void *) &cbuf[i]; /* cast-away const */ } } return NULL; } /* * @brief extract info from input string given two types of constraints: * - length of the extracted string is bounded * - extracted string should stop at first element of an exclude list * * @param[in] isp : the string to scan * @param[in] limit : size limit on the output string (including '\0') * @param[in] exclude : characters to be excluded from output buffer * @param[out] obuf : the output buffer * @retval true if string was capped, false if not */ bool StringNotMatchingSetCapped(const char *isp, size_t limit, const char *exclude, char *obuf) { size_t l = strcspn(isp, exclude); if (l < limit-1) { memcpy(obuf, isp, l); obuf[l]='\0'; return false; } else { memcpy(obuf, isp, limit-1); obuf[limit-1]='\0'; return true; } } bool StringAppend(char *dst, const char *src, size_t n) { size_t i, j; n--; for (i = 0; i < n && dst[i]; i++) { } for (j = 0; i < n && src[j]; i++, j++) { dst[i] = src[j]; } dst[i] = '\0'; return (i < n || !src[j]); } /** * Canonify #src into #dst. * * @WARNING you must make sure sizeof(dst) is adequate! * * @return always #dst. */ char *StringCanonify(char *dst, const char *src) { while (*src != '\0') { if (isalnum((unsigned char) *src)) { *dst = *src; } else { *dst = '_'; } src++; dst++; } *dst = '\0'; return dst; } /** * Append #sep if not already there, and then append #leaf. */ bool PathAppend(char *path, size_t path_size, const char *leaf, char sep) { size_t path_len = strlen(path); size_t leaf_len = strlen(leaf); if (path_len > 0 && path[path_len - 1] == sep) { /* Path already has separator. */ path_len--; } if (path_len + 1 + leaf_len >= path_size) { return false; /* overflow */ } path[path_len] = sep; memcpy(&path[path_len + 1], leaf, leaf_len + 1); return true; } /** * Append #src string to #dst, useful for static allocated buffers. * * @param #dst_len if not NULL then it must contain the lenth of #dst and must * return the total needed length of the result in #dst, even * when truncation occurs. * @param #src_len if not 0, then this many bytes * from #src shall be concatenated to #dst. * * @NOTE if truncation happened, then the value returned in #dst_len shall be * greater than or equal to #dst_size (indicating the real size needed * for successful concatenation), and the real length of the truncated * string in #dst shall be #dst_size - 1. * * @NOTE it is legal for #dst_len to be >= dst_size already when the function * is called. In that case nothing will be appended, only #dst_len will * be updated with the extra size needed. */ void StrCat(char *dst, size_t dst_size, size_t *dst_len, const char *src, size_t src_len) { size_t dlen = (dst_len != NULL) ? *dst_len : strlen(dst); size_t slen = (src_len != 0) ? src_len : strlen(src); size_t needed_len = dlen + slen; if (dlen + 1 >= dst_size) /* dst already full or overflown */ { /* Append nothing, only update *dst_len. */ } else if (needed_len < dst_size) /* it fits */ { memcpy(&dst[dlen], src, slen); dst[needed_len] = '\0'; } else /* truncation */ { assert(dlen + slen >= dst_size); memcpy(&dst[dlen], src, dst_size - dlen - 1); dst[dst_size - 1] = '\0'; } if (dst_len != NULL) { *dst_len = needed_len; } } /** * Append #src to #dst, delimited with #sep if #dst was not empty. * * @param #dst_len In-out parameter. If not NULL it is taken into account as * the current length of #dst, and updated as such. * * @NOTE if after returning *dst_len>=dst_size, this indicates that *nothing * was appended*, and the value is the size needed for success. * */ void StrCatDelim(char *dst, size_t dst_size, size_t *dst_len, const char *src, char sep) { size_t dlen = (dst_len != NULL) ? *dst_len : strlen(dst); size_t slen = strlen(src); size_t needed_len = dlen + slen; if (dlen > 0) { needed_len++; /* separator must be prepended */ } if (dlen + 1 >= dst_size) /* dst already full or overflown */ { /* Append nothing, only update *dst_len. */ } else if (needed_len < dst_size) /* it fits */ { /* Prepend separator if not empty. */ if (dlen > 0) { dst[dlen] = sep;; dlen++; } memcpy(&dst[dlen], src, slen); dst[needed_len] = '\0'; } else /* does not fit */ { /* Append nothing, only update *dst_len. */ } if (dst_len != NULL) { *dst_len = needed_len; } } /*********************************************************************/ void CanonifyNameInPlace(char *s) { for (; *s != '\0'; s++) { if (!isalnum((unsigned char) *s)) { *s = '_'; } } } bool StringMatchesOption( const char *const supplied, const char *const longopt, const char *const shortopt) { assert(supplied != NULL); assert(shortopt != NULL); assert(longopt != NULL); assert(strlen(shortopt) == 2); assert(strlen(longopt) >= 3); assert(shortopt[0] == '-' && shortopt[1] != '-'); assert(longopt[0] == '-' && longopt[1] == '-' && longopt[2] != '-'); const size_t length = strlen(supplied); if (length <= 1) { return false; } else if (length == 2) { return StringEqual(supplied, shortopt); } return StringEqualN_IgnoreCase(supplied, longopt, length); } ssize_t StringFind( const char *const str, const char *const sub, const size_t from, const size_t to) { assert(str != NULL); assert(sub != NULL); const size_t strl = strlen(str); const size_t subl = strlen(sub); for (size_t i = from; i < MIN(strl, to); i++) { if (strncmp(str + i, sub, subl) == 0) { return i; } } return -1; } cfengine-3.24.2/libntech/libutils/threaded_stack.h0000644000000000000000000000646315010704254022122 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_THREADED_STACK_H #define CFENGINE_THREADED_STACK_H #include typedef struct ThreadedStack_ ThreadedStack; /** @brief Creates a new stack with specified capacity. @param [in] initial_capacity Initial capacity, defaults to 1. @param [in] ItemDestroy Function used to destroy data elements. */ ThreadedStack *ThreadedStackNew(size_t initial_capacity, void (*ItemDestroy) ()); /** @brief Destroys the stack and frees the memory it occupies. @param [in] stack The stack to destroy. @warning ThreadedStack should only be destroyed if all threads are joined */ void ThreadedStackDestroy(ThreadedStack *stack); /** @brief Frees the memory allocated for the data pointer and the struct itself. @param [in] stack The stack to free. */ void ThreadedStackSoftDestroy(ThreadedStack *stack); /** @brief Returns and removes the last element added to the stack. @note Will return NULL if stack is empty. @param [in] stack The stack to pop from. @return A pointer to the last data added. */ void *ThreadedStackPop(ThreadedStack *stack); /** @brief Adds a new item on top of the stack. @param [in] stack The stack to push to. @param [in] item The item to push. */ void ThreadedStackPush(ThreadedStack *stack, void *item); /** @brief Adds a new item on top of the stack and returns the current size. @param [in] stack The stack to push to. @param [in] item The item to push. @return The amount of elements in the stack. */ size_t ThreadedStackPushReportCount(ThreadedStack *stack, void *item); /** @brief Get current number of items in stack. @note On NULL stack, returns 0. @param [in] stack The stack. @return The amount of elements in the stack. */ size_t ThreadedStackCount(ThreadedStack const *stack); /** @brief Get current capacity of stack. @note On NULL stack, returns 0. @param [in] stack The stack. @return The current capacity of the stack. */ size_t ThreadedStackCapacity(ThreadedStack const *stack); /** @brief Create a shallow copy of a given stack. @note This makes a new stack pointing to the same memory as the old stack. @param [in] stack The stack. @return A new stack pointing to the same data. */ ThreadedStack *ThreadedStackCopy(ThreadedStack const *stack); /** @brief Checks if a stack is empty. @param [in] stack The stack. @return Returns true if stack is empty, false otherwise. */ bool ThreadedStackIsEmpty(ThreadedStack const *stack); #endif cfengine-3.24.2/libntech/libutils/man.c0000644000000000000000000002244515010704254017721 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include static void WriteCopyright(Writer *out) { static const char *const copyright = ".\\\"Copyright 2024 Northern.tech AS\n" ".\\\"\n" ".\\\"This file is part of CFEngine 3 - written and maintained by Northern.tech AS.\n" ".\\\"\n" ".\\\"This program is free software; you can redistribute it and/or modify it\n" ".\\\"under the terms of the GNU General Public License as published by the\n" ".\\\"Free Software Foundation; version 3.\n" ".\\\"\n" ".\\\"This program is distributed in the hope that it will be useful,\n" ".\\\"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" ".\\\"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" ".\\\"GNU General Public License for more details.\n" ".\\\"\n" ".\\\"You should have received a copy of the GNU General Public License\n" ".\\\"along with this program; if not, write to the Free Software\n" ".\\\"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n" ".\\\"\n" ".\\\"To the extent this program is licensed as part of the Enterprise\n" ".\\\"versions of CFEngine, the applicable Commercial Open Source License\n" ".\\\"(COSL) may apply to this file if you as a licensee so wish it. See\n" ".\\\"included file COSL.txt.\n"; WriterWrite(out, copyright); } static void WriteHeader(Writer *out, const char *program, time_t last_modified) { char program_upper[256] = { 0 }; snprintf(program_upper, 255, "%s", program); ToUpperStrInplace(program_upper); char date_modified[20] = { 0 }; { struct tm t; gmtime_r(&last_modified, &t); strftime(date_modified, 19, "%Y-%m-%d", &t); } WriterWriteF(out, ".TH %s 8 \"%s\" \"CFEngine\" \"System Administration\"\n", program_upper, date_modified); } static void WriteAvailability(Writer *out, const char *program) { static const char *const availability = ".SH AVAILABILITY\n" "%s is part of CFEngine.\n" ".br\n" "Binary packages may be downloaded from https://cfengine.com/download/.\n" ".br\n" "The source code is available at https://github.com/cfengine/\n"; WriterWriteF(out, availability, program); } static void WriteAuthor(Writer *out) { static const char *const author = ".SH AUTHOR\n" "Mark Burgess and Northern.tech AS\n"; WriterWrite(out, author); } static void WriteName(Writer *out, const char *program, const char *short_description) { static const char *const author = ".SH NAME\n" "%s \\- %s\n"; WriterWriteF(out, author, program, short_description); } static void WriteSynopsis(Writer *out, const char *program, bool command, bool command_first, bool accepts_file_argument) { WriterWrite(out, ".SH SYNOPSIS\n"); WriterWriteF(out, ".B %s\n", program); if (command && command_first) { WriterWrite(out, ".RI COMMAND\n"); } WriterWrite(out, ".RI [ OPTION ]...\n"); if (command && !command_first) { WriterWrite(out, ".RI COMMAND\n"); } if (accepts_file_argument) { WriterWrite(out, ".RI [ FILE ]\n"); } else { WriterWrite(out, "\n"); } } static void WriteDescription(Writer *out, const char *description) { WriterWriteF(out, ".SH DESCRIPTION\n%s\n", description); } static void WriteCommands(Writer *out, const Description *commands) { assert(commands != NULL); WriterWrite(out, ".SH COMMANDS\n"); for (int i = 0; commands[i].name != NULL; i++) { WriterWriteF(out, ".IP \"%s\"\n", commands[i].name); WriterWriteF(out, "%s.\n", commands[i].description); WriterWrite(out, ".br\n"); WriterWriteF(out, "Usage: %s\n", commands[i].usage); } } static void WriteOptions(Writer *out, const struct option options[], const char *const option_hints[]) { WriterWrite(out, ".SH OPTIONS\n"); for (int i = 0; options[i].name != NULL; i++) { char short_option[] = ", -*"; if (options[i].val < 128 && options[i].val > 0) { // Within ASCII range, means there is a short option. short_option[3] = options[i].val; } else { // No short option. short_option[0] = '\0'; } if (options[i].has_arg) { WriterWriteF(out, ".IP \"--%s%s value\"\n%s\n", options[i].name, short_option, option_hints[i]); } else { WriterWriteF(out, ".IP \"--%s%s\"\n%s\n", options[i].name, short_option, option_hints[i]); } } } static void WriteSeeAlso(Writer *out) { static const char *const see_also = ".SH \"SEE ALSO\"\n" ".BR cf-promises (8),\n" ".BR cf-agent (8),\n" ".BR cf-serverd (8),\n" ".BR cf-execd (8),\n" ".BR cf-monitord (8),\n" ".BR cf-runagent (8),\n" ".BR cf-key (8)\n"; WriterWrite(out, see_also); } static void WriteBugs(Writer *out) { static const char *const bugs = ".SH BUGS\n" "Please see the public bug-tracker at https://northerntech.atlassian.net/projects/CFE/.\n" ".br\n" "GitHub pull-requests may be submitted to https://github.com/cfengine/core/.\n"; WriterWrite(out, bugs); } static void WriteCFEngine(Writer *out) { static const char *const cfengine = ".SH CFENGINE\n" "CFEngine provides automated configuration management of large-scale computer systems. A system administrator " "describes the desired state of a system using CFEngine policy code. The program \\fBcf-agent\\fR reads policy code " "and attempts to bring the current system state to the desired state described. Policy code is downloaded by " "\\fBcf-agent\\fR from a \\fBcf-serverd\\fR daemon. The daemon \\fBcf-execd\\fR is responsible for running " "\\fBcf-agent\\fR periodically.\n" ".br\n" "Documentation for CFEngine is available at https://docs.cfengine.com/.\n"; WriterWrite(out, cfengine); } static void WritePromiseTheory(Writer *out) { static const char *const promise_theory = ".SH PROMISE THEORY\n" "CFEngine is built on principles from promise theory, proposed by Mark Burgess in 2004. " "Promise theory is a model of voluntary cooperation between individual, autonomous " "actors or agents who publish their intentions to one another in the form of promises. " "A promise is a declaration of intent whose purpose is to increase the recipient's certainty " "about a claim of past, present or future behaviour. For a promise to increase certainty, " "the recipient needs to trust the promiser, but trust can also be built on the verification " "that previous promises have been kept, thus trust plays a symbiotic relationship with promises. \n" ".br\n" "For an introduction to promise theory, please see http://arxiv.org/abs/0810.3294/\n"; WriterWrite(out, promise_theory); } void ManPageWrite(Writer *out, const char *program, time_t last_modified, const char *short_description, const char *long_description, const struct option options[], const char *const option_hints[], const Description *commands, bool command_first, bool accepts_file_argument) { time_t overridetime; char *source_date_epoch = getenv("SOURCE_DATE_EPOCH"); if (source_date_epoch != NULL && (overridetime = (time_t)strtoll(source_date_epoch, NULL, 10)) > 0) { last_modified = overridetime; } WriteCopyright(out); WriteHeader(out, program, last_modified); WriteName(out, program, short_description); WriteSynopsis(out, program, (commands != NULL), command_first, accepts_file_argument); WriteDescription(out, long_description); if (commands != NULL) { WriteCommands(out, commands); } WriteOptions(out, options, option_hints); WriteCFEngine(out); WritePromiseTheory(out); WriteAvailability(out, program); WriteBugs(out); WriteSeeAlso(out); WriteAuthor(out); } cfengine-3.24.2/libntech/libutils/file_lib.c0000644000000000000000000016420015010704254020707 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include /* CF_PERMS_DEFAULT */ #include #include #include /* memcchr */ #include /* below are includes for the fancy efficient file/data copying on Linux */ #ifdef __linux__ #ifdef HAVE_LINUX_FS_H #include /* FICLONE */ #endif #include #include #ifdef HAVE_SYS_SENDFILE_H #include #endif #include #include /* copy_file_range(), lseek() */ #endif /* __linux__ */ #ifdef __MINGW32__ #include /* LockFileEx and friends */ #endif #define SYMLINK_MAX_DEPTH 32 bool FileCanOpen(const char *path, const char *modes) { FILE *test = NULL; if ((test = fopen(path, modes)) != NULL) { fclose(test); return true; } else { return false; } } #define READ_BUFSIZE 4096 Writer *FileRead(const char *filename, size_t max_size, bool *truncated) { int fd = safe_open(filename, O_RDONLY); if (fd == -1) { return NULL; } Writer *w = FileReadFromFd(fd, max_size, truncated); close(fd); return w; } ssize_t ReadFileStreamToBuffer(FILE *file, size_t max_bytes, char *buf) { size_t bytes_read = 0; size_t n = 0; while (bytes_read < max_bytes) { n = fread(buf + bytes_read, 1, max_bytes - bytes_read, file); if (ferror(file) && !feof(file)) { return FILE_ERROR_READ; } else if (n == 0) { break; } bytes_read += n; } if (ferror(file)) { return FILE_ERROR_READ; } return bytes_read; } bool File_Copy(const char *src, const char *dst) { assert(src != NULL); assert(dst != NULL); Log(LOG_LEVEL_INFO, "Copying: '%s' -> '%s'", src, dst); FILE *in = safe_fopen(src, "r"); if (in == NULL) { Log(LOG_LEVEL_ERR, "Could not open '%s' (%s)", src, strerror(errno)); return false; } FILE *out = safe_fopen_create_perms(dst, "w", CF_PERMS_DEFAULT); if (out == NULL) { Log(LOG_LEVEL_ERR, "Could not open '%s' (%s)", dst, strerror(errno)); fclose(in); return false; } size_t bytes_in = 0; size_t bytes_out = 0; bool ret = true; do { #define BUFSIZE 1024 char buf[BUFSIZE] = {0}; bytes_in = fread(buf, sizeof(char), sizeof(buf), in); bytes_out = fwrite(buf, sizeof(char), bytes_in, out); while (bytes_out < bytes_in && !ferror(out)) { bytes_out += fwrite( buf + bytes_out, sizeof(char), bytes_in - bytes_out, out); } } while (!feof(in) && !ferror(in) && !ferror(out) && bytes_in == bytes_out); if (ferror(in)) { Log(LOG_LEVEL_ERR, "Error encountered while reading '%s'", src); ret = false; } else if (ferror(out)) { Log(LOG_LEVEL_ERR, "Error encountered while writing '%s'", dst); ret = false; } else if (bytes_in != bytes_out) { Log(LOG_LEVEL_ERR, "Did not copy the whole file"); ret = false; } const int i = fclose(in); if (i != 0) { Log(LOG_LEVEL_ERR, "Error encountered while closing '%s' (%s)", src, strerror(errno)); ret = false; } const int o = fclose(out); if (o != 0) { Log(LOG_LEVEL_ERR, "Error encountered while closing '%s' (%s)", dst, strerror(errno)); ret = false; } return ret; } bool File_CopyToDir(const char *src, const char *dst_dir) { assert(src != NULL); assert(dst_dir != NULL); assert(StringEndsWith(dst_dir, FILE_SEPARATOR_STR)); const char *filename = Path_Basename(src); if (filename == NULL) { Log(LOG_LEVEL_ERR, "Cannot find filename in '%s'", src); return false; } char dst[PATH_MAX] = {0}; const int s = snprintf(dst, PATH_MAX, "%s%s", dst_dir, filename); if (s >= PATH_MAX) { Log(LOG_LEVEL_ERR, "Copy destination path too long: '%s...'", dst); return false; } if (!File_Copy(src, dst)) { Log(LOG_LEVEL_ERR, "Copying '%s' failed", filename); return false; } return true; } Writer *FileReadFromFd(int fd, size_t max_size, bool *truncated) { if (truncated) { *truncated = false; } Writer *w = StringWriter(); for (;;) { char buf[READ_BUFSIZE]; /* Reading more data than needed is deliberate. It is a truncation detection. */ ssize_t read_ = read(fd, buf, READ_BUFSIZE); if (read_ == 0) { /* Done. */ return w; } else if (read_ < 0) { if (errno != EINTR) { /* Something went wrong. */ WriterClose(w); return NULL; } /* Else: interrupted - try again. */ } else if (read_ + StringWriterLength(w) > max_size) { WriterWriteLen(w, buf, max_size - StringWriterLength(w)); /* Reached limit - stop. */ if (truncated) { *truncated = true; } return w; } else /* Filled buffer; copy and ask for more. */ { WriterWriteLen(w, buf, read_); } } } ssize_t FullWrite(int desc, const char *ptr, size_t len) { ssize_t total_written = 0; while (len > 0) { int written = write(desc, ptr, len); if (written < 0) { if (errno == EINTR) { continue; } return written; } total_written += written; ptr += written; len -= written; } return total_written; } ssize_t FullRead(int fd, char *ptr, size_t len) { ssize_t total_read = 0; while (len > 0) { ssize_t bytes_read = read(fd, ptr, len); if (bytes_read < 0) { if (errno == EINTR) { continue; } return -1; } if (bytes_read == 0) { return total_read; } total_read += bytes_read; ptr += bytes_read; len -= bytes_read; } return total_read; } /** * @note difference with files_names.h:IsDir() is that this doesn't * follow symlinks, so a symlink is never a directory... */ bool IsDirReal(const char *path) { struct stat s; if (lstat(path, &s) == -1) { return false; // Error } return (S_ISDIR(s.st_mode) != 0); } #ifndef __MINGW32__ NewLineMode FileNewLineMode(ARG_UNUSED const char *file) { return NewLineMode_Unix; } #endif // !__MINGW32__ bool IsWindowsNetworkPath(const char *const path) { #ifdef _WIN32 int off = 0; while (path[off] == '\"') { // Bypass quoted strings off += 1; } if (IsFileSep(path[off]) && IsFileSep(path[off + 1])) { return true; } #else // _WIN32 UNUSED(path); #endif // _WIN32 return false; } bool IsWindowsDiskPath(const char *const path) { #ifdef _WIN32 int off = 0; while (path[off] == '\"') { // Bypass quoted strings off += 1; } if (isalpha(path[off]) && path[off + 1] == ':' && IsFileSep(path[off + 2])) { return true; } #else // _WIN32 UNUSED(path); #endif // _WIN32 return false; } bool IsAbsoluteFileName(const char *f) { int off = 0; // Check for quoted strings for (off = 0; f[off] == '\"'; off++) { } if (IsWindowsNetworkPath(f)) { return true; } if (IsWindowsDiskPath(f)) { return true; } if (IsFileSep(f[off])) { return true; } return false; } /* We assume that s is at least MAX_FILENAME large. * MapName() is thread-safe, but the argument is modified. */ #ifdef _WIN32 # if defined(__MINGW32__) char *MapNameCopy(const char *s) { char *str = xstrdup(s); char *c = str; while ((c = strchr(c, '/'))) { *c = '\\'; } return str; } char *MapName(char *s) { char *c = s; while ((c = strchr(c, '/'))) { *c = '\\'; } return s; } # elif defined(__CYGWIN__) char *MapNameCopy(const char *s) { Writer *w = StringWriter(); /* c:\a\b -> /cygdrive/c\a\b */ if (s[0] && isalpha(s[0]) && s[1] == ':') { WriterWriteF(w, "/cygdrive/%c", s[0]); s += 2; } for (; *s; s++) { /* a//b//c -> a/b/c */ /* a\\b\\c -> a\b\c */ if (IsFileSep(*s) && IsFileSep(*(s + 1))) { continue; } /* a\b\c -> a/b/c */ WriterWriteChar(w, *s == '\\' ? '/' : *s); } return StringWriterClose(w); } char *MapName(char *s) { char *ret = MapNameCopy(s); if (strlcpy(s, ret, MAX_FILENAME) >= MAX_FILENAME) { FatalError(ctx, "Expanded path (%s) is longer than MAX_FILENAME (" TO_STRING(MAX_FILENAME) ") characters", ret); } free(ret); return s; } # else/* !__MINGW32__ && !__CYGWIN__ */ # error Unknown NT-based compilation environment # endif/* __MINGW32__ || __CYGWIN__ */ #else /* !_WIN32 */ char *MapName(char *s) { return s; } char *MapNameCopy(const char *s) { return xstrdup(s); } #endif /* !_WIN32 */ char *MapNameForward(char *s) /* Like MapName(), but maps all slashes to forward */ { while ((s = strchr(s, '\\'))) { *s = '/'; } return s; } #ifdef TEST_SYMLINK_ATOMICITY void switch_symlink_hook(); #define TEST_SYMLINK_SWITCH_POINT switch_symlink_hook(); #else #define TEST_SYMLINK_SWITCH_POINT #endif void PathWalk( const char *const path, PathWalkFn callback, void *const data, PathWalkCopyFn copy, PathWalkDestroyFn destroy) { assert(path != NULL); assert(callback != NULL); Seq *const children = ListDir(path, NULL); if (children == NULL) { Log( LOG_LEVEL_DEBUG, "Failed to list directory '%s'. Subdirectories will not be " "iterated.", path); return; } const size_t n_children = SeqLength(children); Seq *const dirnames = SeqNew(1, free); Seq *const filenames = SeqNew(1, free); for (size_t i = 0; i < n_children; i++) { char *const child = SeqAt(children, i); /* The basename(3) function might potentially mutate the argument. * Thus, we make a copy to pass instead. */ char buf[PATH_MAX]; const size_t ret = StringCopy(child, buf, PATH_MAX); if (ret >= PATH_MAX) { Log(LOG_LEVEL_ERR, "Failed to copy path: Path too long (%zu >= %d)", ret, PATH_MAX); SeqDestroy(dirnames); SeqDestroy(filenames); return; } const char *const b_name = basename(buf); /* We don't iterate the '.' and '..' directory entries as it would cause * infinite recursion. */ if (StringEqual(b_name, ".") || StringEqual(b_name, "..")) { continue; } // Note that stat(2) follows symbolic links. struct stat sb; if (stat(child, &sb) == 0) { char *const dup = xstrdup(b_name); if (sb.st_mode & S_IFDIR) { SeqAppend(dirnames, dup); } else { SeqAppend(filenames, dup); } } else { Log(LOG_LEVEL_DEBUG, "Failed to stat file '%s': %s", child, GetErrorStr()); } } SeqDestroy(children); callback(path, dirnames, filenames, data); SeqDestroy(filenames); // Recursively walk through subdirectories. const size_t n_dirs = SeqLength(dirnames); for (size_t i = 0; i < n_dirs; i++) { const char *const dir = SeqAt(dirnames, i); if (dir != NULL) { char *const duplicate = (copy != NULL) ? copy(data) : data; if (StringEqual(path, ".")) { PathWalk(dir, callback, duplicate, copy, destroy); } else { char *next = Path_JoinAlloc(path, dir); PathWalk(next, callback, duplicate, copy, destroy); free(next); } if (copy != NULL && destroy != NULL) { destroy(duplicate); } } } SeqDestroy(dirnames); } Seq *ListDir(const char *dir, const char *extension) { Dir *dirh = DirOpen(dir); if (dirh == NULL) { return NULL; } Seq *contents = SeqNew(10, free); const struct dirent *dirp; while ((dirp = DirRead(dirh)) != NULL) { const char *name = dirp->d_name; if (extension == NULL || StringEndsWithCase(name, extension, true)) { SeqAppend(contents, Path_JoinAlloc(dir, name)); } } DirClose(dirh); return contents; } mode_t SetUmask(mode_t new_mask) { const mode_t old_mask = umask(new_mask); Log(LOG_LEVEL_DEBUG, "Set umask to %o, was %o", new_mask, old_mask); return old_mask; } void RestoreUmask(mode_t old_mask) { umask(old_mask); Log(LOG_LEVEL_DEBUG, "Restored umask to %o", old_mask); } /** * Opens a file safely, with default (strict) permissions on creation. * See safe_open_create_perms for more documentation. * * @param pathname The path to open. * @param flags Same flags as for system open(). * @return Same errors as open(). */ int safe_open(const char *pathname, int flags) { return safe_open_create_perms(pathname, flags, CF_PERMS_DEFAULT); } /** * Opens a file safely. It will follow symlinks, but only if the symlink is * trusted, that is, if the owner of the symlink and the owner of the target are * the same, or if the owner of the symlink is either root or the user running * the current process. All components are checked, even symlinks encountered in * earlier parts of the path name. * * It should always be used when opening a file or directory that is not * guaranteed to be owned by root. * * safe_open and safe_fopen both default to secure (0600) file creation perms. * The _create_perms variants allow you to explicitly set different permissions. * * @param pathname The path to open * @param flags Same flags as for system open() * @param create_perms Permissions for file, only relevant on file creation * @return Same errors as open() * @see safe_fopen_create_perms() * @see safe_open() */ int safe_open_create_perms( const char *const pathname, int flags, const mode_t create_perms) { if (flags & O_TRUNC) { /* Undefined behaviour otherwise, according to the standard. */ assert((flags & O_RDWR) || (flags & O_WRONLY)); } if (!pathname) { errno = EINVAL; return -1; } if (*pathname == '\0') { errno = ENOENT; return -1; } #ifdef __MINGW32__ // Windows gets off easy. No symlinks there. return open(pathname, flags, create_perms); #elif defined(__ANDROID__) // if effective user is not root then don't try to open // all paths from '/' up, might not have permissions. uid_t p_euid = geteuid(); if (p_euid != 0) { return open(pathname, flags, create_perms); } #else // !__MINGW32__ and !__ANDROID__ const size_t path_bufsize = strlen(pathname) + 1; char path[path_bufsize]; const size_t res_len = StringCopy(pathname, path, path_bufsize); UNUSED(res_len); assert(res_len == strlen(pathname)); int currentfd; const char *first_dir; bool trunc = false; const int orig_flags = flags; char *next_component = path; bool p_uid; if (*next_component == '/') { first_dir = "/"; // Eliminate double slashes. while (*(++next_component) == '/') { /*noop*/ } if (!*next_component) { next_component = NULL; } } else { first_dir = "."; } currentfd = openat(AT_FDCWD, first_dir, O_RDONLY); if (currentfd < 0) { return -1; } // current process user id p_uid = geteuid(); size_t final_size = (size_t) -1; while (next_component) { char *component = next_component; next_component = strchr(component + 1, '/'); // Used to restore the slashes in the final path component. char *restore_slash = NULL; if (next_component) { restore_slash = next_component; *next_component = '\0'; // Eliminate double slashes. while (*(++next_component) == '/') { /*noop*/ } if (!*next_component) { next_component = NULL; } else { restore_slash = NULL; } } // In cases of a race condition when creating a file, our attempt to open it may fail // (see O_EXCL and O_CREAT flags below). However, this can happen even under normal // circumstances, if we are unlucky; it does not mean that someone is up to something bad. // So retry it a few times before giving up. int attempts = 3; trunc = false; while (true) { if (( (orig_flags & O_RDWR) || (orig_flags & O_WRONLY)) && (orig_flags & O_TRUNC)) { trunc = true; /* We need to check after we have opened the file whether we * opened the right one. But if we truncate it, the damage is * already done, we have destroyed the contents, and that file * might have been a symlink to /etc/shadow! So save that flag * and apply the truncation afterwards instead. */ flags &= ~O_TRUNC; } if (restore_slash) { *restore_slash = '\0'; } struct stat stat_before, stat_after; int stat_before_result = fstatat(currentfd, component, &stat_before, AT_SYMLINK_NOFOLLOW); if (stat_before_result < 0 && (errno != ENOENT || next_component // Meaning "not a leaf". || !(flags & O_CREAT))) { close(currentfd); return -1; } /* * This testing entry point is about the following real-world * scenario: There can be an attacker that at this point * overwrites the existing file or writes a file, invalidating * basically the previous fstatat(). * * - We make sure that can't happen if the file did not exist, by * creating with O_EXCL. * - We make sure that can't happen if the file existed, by * comparing with fstat() result after the open(). * */ TEST_SYMLINK_SWITCH_POINT if (!next_component) /* last component */ { if (stat_before_result < 0) { assert(flags & O_CREAT); // Doesn't exist. Make sure *we* create it. flags |= O_EXCL; /* No need to ftruncate() the file at the end. */ trunc = false; } else { if ((flags & O_CREAT) && (flags & O_EXCL)) { close(currentfd); errno = EEXIST; return -1; } // Already exists. Make sure we *don't* create it. flags &= ~O_CREAT; } if (restore_slash) { *restore_slash = '/'; } int filefd = openat(currentfd, component, flags, create_perms); if (filefd < 0) { if ((stat_before_result < 0 && !(orig_flags & O_EXCL) && errno == EEXIST) || (stat_before_result >= 0 && (orig_flags & O_CREAT) && errno == ENOENT)) { if (--attempts >= 0) { // Might be our fault. Try again. flags = orig_flags; continue; } else { // Too many attempts. Give up. // Most likely a link that is in the way of file creation, but can also // be a file that is constantly created and deleted (race condition). // It is not possible to separate between the two, so return EACCES to // signal that we denied access. errno = EACCES; } } close(currentfd); return -1; } close(currentfd); currentfd = filefd; } else { int new_currentfd = openat(currentfd, component, O_RDONLY); close(currentfd); if (new_currentfd < 0) { return -1; } currentfd = new_currentfd; } /* If file did exist, we fstat() again and compare with previous. */ if (stat_before_result == 0) { if (fstat(currentfd, &stat_after) < 0) { close(currentfd); return -1; } // Some attacks may use symlinks to get higher privileges // The safe cases are: // * symlinks owned by root // * symlinks owned by the user running the process // * symlinks that have the same owner and group as the destination if (stat_before.st_uid != 0 && stat_before.st_uid != p_uid && (stat_before.st_uid != stat_after.st_uid || stat_before.st_gid != stat_after.st_gid)) { close(currentfd); Log(LOG_LEVEL_ERR, "Cannot follow symlink '%s'; it is not " "owned by root or the user running this process, and " "the target owner and/or group differs from that of " "the symlink itself.", pathname); // Return ENOLINK to signal that the link cannot be followed // ('Link has been severed'). errno = ENOLINK; return -1; } final_size = (size_t) stat_after.st_size; } // If we got here, we've been successful, so don't try again. break; } } /* Truncate if O_CREAT and the file preexisted. */ if (trunc) { /* Do not truncate if the size is already zero, some * filesystems don't support ftruncate() with offset>=size. */ assert(final_size != (size_t) -1); if (final_size != 0) { int tr_ret = ftruncate(currentfd, 0); if (tr_ret < 0) { Log(LOG_LEVEL_ERR, "safe_open: unexpected failure (ftruncate: %s)", GetErrorStr()); close(currentfd); return -1; } } } return currentfd; #endif // !__MINGW32__ } FILE *safe_fopen(const char *const path, const char *const mode) { return safe_fopen_create_perms(path, mode, CF_PERMS_DEFAULT); } /** * Opens a file safely. It will follow symlinks, but only if the symlink is trusted, * that is, if the owner of the symlink and the owner of the target are the same, * or if the owner of the symlink is either root or the user running the current process. * All components are checked, even symlinks encountered in earlier parts of the * path name. * * It should always be used when opening a directory that is not guaranteed to be * owned by root. * * @param pathname The path to open. * @param flags Same mode as for system fopen(). * @param create_perms Permissions for file, only relevant on file creation. * @return Same errors as fopen(). */ FILE *safe_fopen_create_perms( const char *const path, const char *const mode, const mode_t create_perms) { if (!path || !mode) { errno = EINVAL; return NULL; } char fdopen_mode_str[3] = {0}; int fdopen_mode_idx = 0; int flags = 0; for (int c = 0; mode[c]; c++) { /* Ignore mode letters not supported in fdopen() for the mode string * that we will later use in fdopen(). Mode letters like 'x' will for * example cause fdopen() to return error on Windows. According to the * man page fdopen(3), the mode must be one of "r", "r+", "w", "w+", * "a", "a+". Windows also have additional characters that are * Microsoft extensions, but advice against using them to preserve * ANSI portability. */ if (strchr("rwa+", mode[c]) != NULL) { if (fdopen_mode_idx >= (sizeof(fdopen_mode_str) - 1)) { ProgrammingError("Invalid flag for fdopen: %s", mode); } fdopen_mode_str[fdopen_mode_idx++] = mode[c]; } switch (mode[c]) { case 'r': flags |= O_RDONLY; break; case 'w': flags |= O_WRONLY | O_TRUNC | O_CREAT; break; case 'a': flags |= O_WRONLY | O_CREAT; break; case '+': flags &= ~(O_RDONLY | O_WRONLY); flags |= O_RDWR; break; case 'b': flags |= O_BINARY; break; case 't': flags |= O_TEXT; break; case 'x': flags |= O_EXCL; break; default: ProgrammingError("Invalid flag for fopen: %s", mode); return NULL; } } int fd = safe_open_create_perms(path, flags, create_perms); if (fd < 0) { return NULL; } FILE *ret = fdopen(fd, fdopen_mode_str); if (!ret) { close(fd); return NULL; } if (mode[0] == 'a') { if (fseek(ret, 0, SEEK_END) < 0) { fclose(ret); return NULL; } } return ret; } /** * Use this instead of chdir(). It changes into the directory safely, using safe_open(). * @param path Path to change into. * @return Same return values as chdir(). */ int safe_chdir(const char *path) { #ifdef __MINGW32__ return chdir(path); #else // !__MINGW32__ int fd = safe_open(path, O_RDONLY); if (fd < 0) { return -1; } if (fchdir(fd) < 0) { close(fd); return -1; } close(fd); return 0; #endif // !__MINGW32__ } #ifndef __MINGW32__ /** * Opens the true parent dir of the file in the path given. The notable * difference from doing it the naive way (open(dirname(path))) is that it * can follow the symlinks of the path, ending up in the true parent dir of the * path. It follows the same safe mechanisms as `safe_open()` to do so. If * AT_SYMLINK_NOFOLLOW is given, it is equivalent to doing it the naive way (but * still following "safe" semantics). * @param path Path to open parent directory of. * @param flags Flags to use for fchownat. * @param link_user If we have traversed a link already, which user was it. * @param link_group If we have traversed a link already, which group was it. * @param traversed_link Whether we have traversed a link. If this is false the * two previus arguments are ignored. This is used enforce * the correct UID/GID combination when following links. * Initially this is false, but will be set to true in * sub invocations if we follow a link. * @param loop_countdown Protection against infinite loop following. * @param true_leaf Place to store the true leaf name (basename) *initialized * to %NULL* or %NULL * @return File descriptor pointing to the parent directory of path, or -1 on * error. */ static int safe_open_true_parent_dir(const char *path, int flags, uid_t link_user, gid_t link_group, bool traversed_link, int loop_countdown, char **true_leaf) { assert((true_leaf == NULL) || (*true_leaf == NULL)); int dirfd = -1; int ret = -1; char *parent_dir_alloc = xstrdup(path); char *leaf_alloc = xstrdup(path); char *parent_dir = dirname(parent_dir_alloc); char *leaf = basename(leaf_alloc); struct stat statbuf; uid_t p_uid = geteuid(); if ((dirfd = safe_open(parent_dir, O_RDONLY)) == -1) { goto cleanup; } if ((ret = fstatat(dirfd, leaf, &statbuf, AT_SYMLINK_NOFOLLOW)) == -1) { goto cleanup; } // Some attacks may use symlinks to get higher privileges // The safe cases are: // * symlinks owned by root // * symlinks owned by the user running the process // * symlinks that have the same owner and group as the destination if (traversed_link && link_user != 0 && link_user != p_uid && (link_user != statbuf.st_uid || link_group != statbuf.st_gid)) { errno = ENOLINK; ret = -1; goto cleanup; } if (S_ISLNK(statbuf.st_mode) && !(flags & AT_SYMLINK_NOFOLLOW)) { if (--loop_countdown <= 0) { ret = -1; errno = ELOOP; goto cleanup; } // Add one byte for '\0', and one byte to make sure size doesn't change // in between calls. char *link = xmalloc(statbuf.st_size + 2); ret = readlinkat(dirfd, leaf, link, statbuf.st_size + 1); if (ret < 0 || ret > statbuf.st_size) { // Link either disappeared or was changed under our feet. Be safe // and bail out. free(link); errno = ENOLINK; ret = -1; goto cleanup; } link[ret] = '\0'; char *resolved_link; if (link[0] == FILE_SEPARATOR) { // Takes ownership of link's memory, so no free(). resolved_link = link; } else { xasprintf(&resolved_link, "%s%c%s", parent_dir, FILE_SEPARATOR, link); free(link); } ret = safe_open_true_parent_dir(resolved_link, flags, statbuf.st_uid, statbuf.st_gid, true, loop_countdown, true_leaf); free(resolved_link); goto cleanup; } // We now know it either isn't a link, or we don't want to follow it if it // is. Return the parent dir. ret = dirfd; dirfd = -1; cleanup: free(parent_dir_alloc); /* We only want to set this once, in the deepest recursive call of this * function (see above). */ if ((true_leaf != NULL) && (*true_leaf == NULL)) { *true_leaf = xstrdup(leaf); } free(leaf_alloc); if (dirfd != -1) { close(dirfd); } return ret; } /** * Implementation of safe_chown. * @param path Path to chown. * @param owner Owner to set on path. * @param group Group to set on path. * @param flags Flags to use for fchownat. */ static int safe_chown_impl(const char *path, uid_t owner, gid_t group, int flags) { int dirfd; char *leaf_alloc = NULL; char *leaf; if ((flags & AT_SYMLINK_NOFOLLOW) != 0) { /* SYMLINK_NOFOLLOW set, we can take leaf name from path */ dirfd = safe_open_true_parent_dir(path, flags, 0, 0, false, SYMLINK_MAX_DEPTH, NULL); leaf_alloc = xstrdup(path); leaf = basename(leaf_alloc); } else { /* no SYMLINK_NOFOLLOW -> follow symlinks, thus we need the real leaf * name */ dirfd = safe_open_true_parent_dir(path, flags, 0, 0, false, SYMLINK_MAX_DEPTH, &leaf_alloc); leaf = leaf_alloc; } if (dirfd < 0) { free(leaf_alloc); return -1; } // We now know it either isn't a link, or we don't want to follow it if it // is. In either case make sure we don't try to follow it. flags |= AT_SYMLINK_NOFOLLOW; int ret = fchownat(dirfd, leaf, owner, group, flags); free(leaf_alloc); close(dirfd); return ret; } #endif // !__MINGW32__ /** * Use this instead of chown(). It changes file owner safely, using safe_open(). * @param path Path to operate on. * @param owner Owner. * @param group Group. * @return Same return values as chown(). */ int safe_chown(const char *path, uid_t owner, gid_t group) { #ifdef __MINGW32__ return chown(path, owner, group); #else // !__MINGW32__ return safe_chown_impl(path, owner, group, 0); #endif // !__MINGW32__ } /** * Use this instead of lchown(). It changes file owner safely, using safe_open(). * @param path Path to operate on. * @param owner Owner. * @param group Group. * @return Same return values as lchown(). */ #ifndef __MINGW32__ int safe_lchown(const char *path, uid_t owner, gid_t group) { return safe_chown_impl(path, owner, group, AT_SYMLINK_NOFOLLOW); } #endif // !__MINGW32__ /** * Use this instead of chmod(). It changes file permissions safely, using safe_open(). * @param path Path to operate on. * @param mode Permissions. * @return Same return values as chmod(). */ int safe_chmod(const char *path, mode_t mode) { #ifdef __MINGW32__ return chmod(path, mode); #else // !__MINGW32__ int dirfd = -1; int ret = -1; char *leaf_alloc = NULL; if ((dirfd = safe_open_true_parent_dir(path, 0, 0, 0, false, SYMLINK_MAX_DEPTH, &leaf_alloc)) == -1) { goto cleanup; } char *leaf = basename(leaf_alloc); struct stat statbuf; if ((ret = fstatat(dirfd, leaf, &statbuf, AT_SYMLINK_NOFOLLOW)) == -1) { goto cleanup; } uid_t olduid = 0; if (S_ISFIFO(statbuf.st_mode) || S_ISSOCK(statbuf.st_mode)) { /* For FIFOs/sockets we cannot resort to the method of opening the file first, since it might block. But we also cannot use chmod directly, because the file may be switched with a symlink to a sensitive file under our feet, and there is no way to avoid following it. So instead, switch effective UID to the owner of the FIFO, and then use chmod. */ /* save old euid */ olduid = geteuid(); if ((ret = seteuid(statbuf.st_uid)) == -1) { goto cleanup; } ret = fchmodat(dirfd, leaf, mode, 0); // Make sure EUID is set back before we check error condition, so that we // never return with lowered privileges. if (seteuid(olduid) == -1) { ProgrammingError("safe_chmod: Could not set EUID back. Should never happen."); } goto cleanup; } int file_fd = safe_open(path, 0); if (file_fd < 0) { ret = -1; goto cleanup; } ret = fchmod(file_fd, mode); close(file_fd); cleanup: free(leaf_alloc); if (dirfd != -1) { close(dirfd); } return ret; #endif // !__MINGW32__ } /** * Use this instead of creat(). It creates a file safely, using safe_open(). * @param path Path to operate on. * @param mode Permissions. * @return Same return values as creat(). */ int safe_creat(const char *pathname, mode_t mode) { return safe_open_create_perms(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); } // Windows implementation in Enterprise. #ifndef _WIN32 bool SetCloseOnExec(int fd, bool enable) { int flags = fcntl(fd, F_GETFD); if (enable) { flags |= FD_CLOEXEC; } else { flags &= ~FD_CLOEXEC; } return (fcntl(fd, F_SETFD, flags) == 0); } #endif // !_WIN32 static bool DeleteDirectoryTreeInternal(const char *basepath, const char *path) { Dir *dirh = DirOpen(path); const struct dirent *dirp; bool failed = false; if (dirh == NULL) { if (errno == ENOENT) { /* Directory disappeared on its own */ return true; } Log(LOG_LEVEL_INFO, "Unable to open directory '%s' during purge of directory tree '%s' (opendir: %s)", path, basepath, GetErrorStr()); return false; } for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, "..")) { continue; } char subpath[PATH_MAX]; snprintf(subpath, sizeof(subpath), "%s" FILE_SEPARATOR_STR "%s", path, dirp->d_name); struct stat lsb; if (lstat(subpath, &lsb) == -1) { if (errno == ENOENT) { /* File disappeared on its own */ continue; } Log(LOG_LEVEL_VERBOSE, "Unable to stat file '%s' during purge of directory tree '%s' (lstat: %s)", path, basepath, GetErrorStr()); failed = true; } else { if (S_ISDIR(lsb.st_mode)) { if (!DeleteDirectoryTreeInternal(basepath, subpath)) { failed = true; } if (rmdir(subpath) == -1) { failed = true; } } else { if (unlink(subpath) == -1) { if (errno == ENOENT) { /* File disappeared on its own */ continue; } Log(LOG_LEVEL_VERBOSE, "Unable to remove file '%s' during purge of directory tree '%s'. (unlink: %s)", subpath, basepath, GetErrorStr()); failed = true; } } } } DirClose(dirh); return !failed; } bool DeleteDirectoryTree(const char *path) { return DeleteDirectoryTreeInternal(path, path); } /** * @NOTE Better use FileSparseCopy() if you are copying file to file * (that one callse this function). * * @NOTE Always use FileSparseWrite() to close the file descriptor, to avoid * losing data. */ bool FileSparseWrite(int fd, const void *buf, size_t count, bool *wrote_hole) { bool all_zeroes = (memcchr(buf, '\0', count) == NULL); if (all_zeroes) /* write a hole */ { off_t seek_ret = lseek(fd, count, SEEK_CUR); if (seek_ret == (off_t) -1) { Log(LOG_LEVEL_ERR, "Failed to write a hole in sparse file (lseek: %s)", GetErrorStr()); return false; } } else /* write normally */ { ssize_t w_ret = FullWrite(fd, buf, count); if (w_ret < 0) { Log(LOG_LEVEL_ERR, "Failed to write to destination file (write: %s)", GetErrorStr()); return false; } } *wrote_hole = all_zeroes; return true; } /** * Below is a basic implementation of copying sparse files shoveling data from * sd to dd detecting blocks of zeroes. * * On Linux, we try more fancy and efficient approaches than what is done * below if any are supported. */ #ifdef __linux__ #if HAVE_SENDFILE || HAVE_COPY_FILE_RANGE #if HAVE_DECL_SEEK_DATA && HAVE_DECL_FALLOC_FL_PUNCH_HOLE #define SMART_FILE_COPY_SYSCALLS_AVAILABLE 1 #define SMART_SYSCALLS_UNUSED ARG_UNUSED #endif /* HAVE_DECL_SEEK_DATA && HAVE_DECL_FALLOC_FL_PUNCH_HOLE */ #endif /* HAVE_SENDFILE || HAVE_COPY_FILE_RANGE */ #endif /* __linux__ */ #ifndef SMART_FILE_COPY_SYSCALLS_AVAILABLE #define SMART_FILE_COPY_SYSCALLS_AVAILABLE 0 #define SMART_SYSCALLS_UNUSED #endif SMART_SYSCALLS_UNUSED static bool FileSparseCopyShoveling(int sd, const char *src_name, int dd, const char *dst_name, size_t blk_size, size_t *total_bytes_written, bool *last_write_was_a_hole) { assert(total_bytes_written != NULL); assert(last_write_was_a_hole != NULL); const size_t buf_size = blk_size; void *buf = xmalloc(buf_size); size_t n_read_total = 0; bool retval = false; *last_write_was_a_hole = false; while (true) { ssize_t n_read = FullRead(sd, buf, buf_size); if (n_read < 0) { Log(LOG_LEVEL_ERR, "Unable to read source file while copying '%s' to '%s'" " (read: %s)", src_name, dst_name, GetErrorStr()); break; } else if (n_read == 0) /* EOF */ { retval = true; break; } bool ret = FileSparseWrite(dd, buf, n_read, last_write_was_a_hole); if (!ret) { Log(LOG_LEVEL_ERR, "Failed to copy '%s' to '%s'", src_name, dst_name); break; } n_read_total += n_read; } free(buf); *total_bytes_written = n_read_total; return retval; } /** * Copy data jumping over areas filled by '\0' greater than blk_size, so * files automatically become sparse if possible. * * File descriptors should already be open, the filenames #source and * #destination are only for logging purposes. * * @NOTE Always use FileSparseClose() to close the file descriptor, to avoid * losing data. */ bool FileSparseCopy(int sd, const char *src_name, int dd, const char *dst_name, SMART_SYSCALLS_UNUSED size_t blk_size, size_t *total_bytes_written, bool *last_write_was_a_hole) { assert(total_bytes_written != NULL); assert(last_write_was_a_hole != NULL); #if !SMART_FILE_COPY_SYSCALLS_AVAILABLE return FileSparseCopyShoveling(sd, src_name, dd, dst_name, blk_size, total_bytes_written, last_write_was_a_hole); #else /* We rely on the errno value below so make sure it's not spoofed by an * error from outside. */ errno = 0; size_t input_size; struct stat in_sb; if (fstat(sd, &in_sb) == 0) { input_size = in_sb.st_size; } else { Log(LOG_LEVEL_ERR, "Failed to stat() '%s': %m", src_name); *total_bytes_written = 0; return false; } bool same_dev = false; struct stat out_sb; if (fstat(dd, &out_sb) == 0) { same_dev = in_sb.st_dev == out_sb.st_dev; } else { Log(LOG_LEVEL_ERR, "Failed to stat() '%s': %m", dst_name); *total_bytes_written = 0; return false; } #if HAVE_DECL_FICLONE if (same_dev) { /* If they are on the same device, first try to use FICLONE * (man:ioctl_ficlone(2)) if available because nothing can beat that. * However, it can easily fail if the FS doesn't support it or if we are * making a copy accross multiple file systems. */ if (ioctl(dd, FICLONE, sd) == 0) { Log(LOG_LEVEL_VERBOSE, "'%s' copied successfully to '%s'", src_name, dst_name); *total_bytes_written = input_size; *last_write_was_a_hole = false; return true; } else { Log(LOG_LEVEL_DEBUG, "Failed to use FICLONE to copy '%s' to '%s': %m", src_name, dst_name); /* let's try other things */ errno = 0; } } #endif /* HAVE_DECL_FICLONE */ if (ftruncate(dd, input_size) != 0) { Log(LOG_LEVEL_ERR, "Failed to preset size for '%s': %m", dst_name); *total_bytes_written = 0; return false; } if (in_sb.st_blocks == 0) { /* Nothing to copy. */ Log(LOG_LEVEL_VERBOSE, "'%s' copied successfully to '%s'", src_name, dst_name); *total_bytes_written = input_size; *last_write_was_a_hole = false; return true; } /* man:inode(7) says about st_blocks: * This field indicates the number of blocks allocated to the file, 512-byte * units, (This may be smaller than st_size/512 when the file has holes.) * The POSIX.1 standard notes that the unit for the st_blocks member of the stat * structure is not defined by the standard. On many implementations it is 512 * bytes; on a few systems, a different unit is used, such as 1024. Furthermore, * the unit may differ on a per-filesystem basis. * So using 512 is the best we can do although it might not be perfect. */ if (fallocate(dd, FALLOC_FL_KEEP_SIZE|FALLOC_FL_PUNCH_HOLE, 0, in_sb.st_blocks * 512) != 0) { Log((errno == EOPNOTSUPP) ? LOG_LEVEL_VERBOSE : LOG_LEVEL_ERR, "Failed to pre-allocate space for '%s': %m", dst_name); if (errno != EOPNOTSUPP) { *total_bytes_written = 0; return false; } } off_t in_pos = 0; off_t out_pos = 0; bool done = false; int error = 0; while (!done) { error = 0; in_pos = lseek(sd, in_pos, SEEK_DATA); if (in_pos == -1) { if (errno == ENXIO) { /* ENXIO means we are either seeking past the end of file or that we seek data and there is only a hole till the end of the file. IOW, we are done. */ done = true; break; } else { error = errno; Log(LOG_LEVEL_ERR, "Failed to seek to next data in '%s'", src_name); break; } } if (in_pos != out_pos) { out_pos = lseek(dd, in_pos - out_pos, SEEK_CUR); if (out_pos == -1) { error = errno; Log(LOG_LEVEL_ERR, "Failed to advance descriptor in '%s'", dst_name); break; } } off_t next_hole = lseek(sd, in_pos, SEEK_HOLE); if (next_hole == -1) { error = errno; Log(LOG_LEVEL_ERR, "Failed to find next hole in '%s'", src_name); break; } if (lseek(sd, in_pos, SEEK_SET) == -1) { error = errno; Log(LOG_LEVEL_ERR, "Failed to seek back to data in '%s'", src_name); break; } ssize_t n_copied; #ifdef HAVE_COPY_FILE_RANGE /* copy_file_range() only works on the same device (file system), but * unlike sendfile() it can actually create reflinks instead of copying * the data. */ if (same_dev) { n_copied = copy_file_range(sd, NULL, dd, NULL, next_hole - in_pos, 0); error = errno; } else #endif /* HAVE_COPY_FILE_RANGE */ { n_copied = sendfile(dd, sd, NULL, next_hole - in_pos); error = errno; } if (n_copied > 0) { in_pos += n_copied; out_pos += n_copied; *total_bytes_written += n_copied; } done = ((n_copied <= 0) || ((size_t) in_pos == input_size)); } *last_write_was_a_hole = false; return (error == 0); #endif /* SMART_FILE_COPY_SYSCALLS_AVAILABLE */ } #undef SMART_FILE_COPY_SYSCALLS_AVAILABLE /** * Always close a written sparse file using this function, else truncation * might occur if the last part was a hole. * * If the tail of the file was a hole (and hence lseek(2)ed on destination * instead of being written), do a ftruncate(2) here to ensure the whole file * is written to the disc. But ftruncate() fails with EPERM on non-native * Linux filesystems (e.g. vfat, vboxfs) when the count is >= than the * size of the file. So we write() one byte and then ftruncate() it back. * * No need for this function to return anything, since the filedescriptor is * (attempted to) closed in either success or failure. * * TODO? instead of needing the #total_bytes_written parameter, we could * figure the offset after writing the one byte using lseek(fd,0,SEEK_CUR) and * truncate -1 from that offset. It's probably not worth adding an extra * system call for simplifying code. */ bool FileSparseClose(int fd, const char *filename, bool do_sync, SMART_SYSCALLS_UNUSED size_t total_bytes_written, SMART_SYSCALLS_UNUSED bool last_write_was_hole) { #if SMART_FILE_COPY_SYSCALLS_AVAILABLE /* Not much to do here with smart syscalls (see above). */ bool success = true; if (do_sync && (fsync(fd) != 0)) { Log(LOG_LEVEL_WARNING, "Could not sync to disk file '%s': %m)", filename); success = false; } close(fd); return success; #else if (last_write_was_hole) { ssize_t ret1 = FullWrite(fd, "", 1); if (ret1 == -1) { Log(LOG_LEVEL_ERR, "Failed to close sparse file '%s' (write: %s)", filename, GetErrorStr()); close(fd); return false; } int ret2 = ftruncate(fd, total_bytes_written); if (ret2 == -1) { Log(LOG_LEVEL_ERR, "Failed to close sparse file '%s' (ftruncate: %s)", filename, GetErrorStr()); close(fd); return false; } } if (do_sync) { if (fsync(fd) != 0) { Log(LOG_LEVEL_WARNING, "Could not sync to disk file '%s' (fsync: %s)", filename, GetErrorStr()); } } int ret3 = close(fd); if (ret3 == -1) { Log(LOG_LEVEL_ERR, "Failed to close file '%s' (close: %s)", filename, GetErrorStr()); return false; } return true; #endif /* SMART_FILE_COPY_SYSCALLS_AVAILABLE */ } #undef SMART_FILE_COPY_SYSCALLS_AVAILABLE ssize_t CfReadLine(char **buff, size_t *size, FILE *fp) { ssize_t b = getline(buff, size, fp); assert(b != 0 && "To the best of my knowledge, getline never returns zero"); if (b > 0) { if ((*buff)[b - 1] == '\n') { (*buff)[b - 1] = '\0'; b--; } } return b; } ssize_t CfReadLines(char **buff, size_t *size, FILE *fp, Seq *lines) { assert(size != NULL); assert(fp != NULL); assert(lines != NULL); assert((buff != NULL) || *size == 0); ssize_t appended = 0; ssize_t ret; bool free_buff = (buff == NULL); while (!feof(fp)) { assert((buff != NULL) || *size == 0); ret = CfReadLine(buff, size, fp); if (ret == -1) { if (!feof(fp)) { if (free_buff) { free(*buff); } return -1; } } else { SeqAppend(lines, xstrdup(*buff)); appended++; } } if (free_buff) { free(*buff); } return appended; } /*******************************************************************/ const char* GetRelocatedProcdirRoot() { const char *procdir = getenv("CFENGINE_TEST_OVERRIDE_PROCDIR"); if (procdir == NULL) { procdir = ""; } else { Log(LOG_LEVEL_VERBOSE, "Overriding /proc location to be %s", procdir); } return procdir; } #if !defined(__MINGW32__) static int LockFD(int fd, short int lock_type, bool wait) { struct flock lock_spec = { .l_type = lock_type, .l_whence = SEEK_SET, .l_start = 0, /* start of the region to which the lock applies */ .l_len = 0 /* till EOF */ }; if (wait) { while (fcntl(fd, F_SETLKW, &lock_spec) == -1) { if (errno != EINTR) { Log(LOG_LEVEL_DEBUG, "Failed to acquire file lock for FD %d: %s", fd, GetErrorStr()); return -1; } } return 0; } else { if (fcntl(fd, F_SETLK, &lock_spec) == -1) { Log(LOG_LEVEL_DEBUG, "Failed to acquire file lock for FD %d: %s", fd, GetErrorStr()); return -1; } /* else */ return 0; } } static int UnlockFD(int fd) { struct flock lock_spec = { .l_type = F_UNLCK, .l_whence = SEEK_SET, .l_start = 0, /* start of the region to which the lock applies */ .l_len = 0 /* till EOF */ }; if (fcntl(fd, F_SETLK, &lock_spec) == -1) { Log(LOG_LEVEL_DEBUG, "Failed to release file lock for FD %d: %s", fd, GetErrorStr()); return -1; } /* else */ return 0; } int ExclusiveFileLock(FileLock *lock, bool wait) { assert(lock != NULL); assert(lock->fd >= 0); return LockFD(lock->fd, F_WRLCK, wait); } int SharedFileLock(FileLock *lock, bool wait) { assert(lock != NULL); assert(lock->fd >= 0); return LockFD(lock->fd, F_RDLCK, wait); } bool ExclusiveFileLockCheck(FileLock *lock) { assert(lock != NULL); assert(lock->fd >= 0); struct flock lock_spec = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 0, /* start of the region to which the lock applies */ .l_len = 0 /* till EOF */ }; if (fcntl(lock->fd, F_GETLK, &lock_spec) == -1) { /* should never happen */ Log(LOG_LEVEL_ERR, "Error when checking locks on FD %d", lock->fd); return false; } return (lock_spec.l_type == F_UNLCK); } int ExclusiveFileUnlock(FileLock *lock, bool close_fd) { assert(lock != NULL); assert(lock->fd >= 0); if (close_fd) { /* also releases the lock */ int ret = close(lock->fd); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to close lock file with FD %d: %s", lock->fd, GetErrorStr()); lock->fd = -1; return -1; } /* else*/ lock->fd = -1; return 0; } else { return UnlockFD(lock->fd); } } int SharedFileUnlock(FileLock *lock, bool close_fd) { assert(lock != NULL); assert(lock->fd >= 0); /* unlocking is the same for both kinds of locks */ return ExclusiveFileUnlock(lock, close_fd); } #else /* __MINGW32__ */ static int LockFD(int fd, DWORD flags, bool wait) { OVERLAPPED ol = { 0 }; ol.Offset = INT_MAX; if (!wait) { flags |= LOCKFILE_FAIL_IMMEDIATELY; } HANDLE fh = (HANDLE)_get_osfhandle(fd); if (!LockFileEx(fh, flags, 0, 1, 0, &ol)) { Log(LOG_LEVEL_DEBUG, "Failed to acquire file lock for FD %d: %s", fd, GetErrorStr()); return -1; } return 0; } int ExclusiveFileLock(FileLock *lock, bool wait) { assert(lock != NULL); assert(lock->fd >= 0); return LockFD(lock->fd, LOCKFILE_EXCLUSIVE_LOCK, wait); } int SharedFileLock(FileLock *lock, bool wait) { assert(lock != NULL); assert(lock->fd >= 0); return LockFD(lock->fd, 0, wait); } static int UnlockFD(int fd) { OVERLAPPED ol = { 0 }; ol.Offset = INT_MAX; HANDLE fh = (HANDLE)_get_osfhandle(fd); if (!UnlockFileEx(fh, 0, 1, 0, &ol)) { Log(LOG_LEVEL_DEBUG, "Failed to release file lock for FD %d: %s", fd, GetErrorStr()); return -1; } return 0; } bool ExclusiveFileLockCheck(FileLock *lock) { /* XXX: there seems to be no way to check if the current process is holding * a lock on a file */ return false; } int ExclusiveFileUnlock(FileLock *lock, bool close_fd) { assert(lock != NULL); assert(lock->fd >= 0); int ret = UnlockFD(lock->fd); if (close_fd) { close(lock->fd); lock->fd = -1; } return ret; } int SharedFileUnlock(FileLock *lock, bool close_fd) { assert(lock != NULL); assert(lock->fd >= 0); /* unlocking is the same for both kinds of locks */ return ExclusiveFileUnlock(lock, close_fd); } #endif /* __MINGW32__ */ int ExclusiveFileLockPath(FileLock *lock, const char *fpath, bool wait) { assert(lock != NULL); assert(lock->fd < 0); int fd = safe_open(fpath, O_CREAT|O_RDWR); if (fd < 0) { Log(LOG_LEVEL_ERR, "Failed to open '%s' for locking", fpath); return -2; } lock->fd = fd; int ret = ExclusiveFileLock(lock, wait); if (ret != 0) { lock->fd = -1; } return ret; } int SharedFileLockPath(FileLock *lock, const char *fpath, bool wait) { assert(lock != NULL); assert(lock->fd < 0); int fd = safe_open(fpath, O_CREAT|O_RDONLY); if (fd < 0) { Log(LOG_LEVEL_ERR, "Failed to open '%s' for locking", fpath); return -2; } lock->fd = fd; int ret = SharedFileLock(lock, wait); if (ret != 0) { lock->fd = -1; } return ret; } cfengine-3.24.2/libntech/libutils/regex.h.in0000644000000000000000000000474115010704254020671 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_REGEX_H #define CFENGINE_REGEX_H #include // bool /* Set by ./configure allowing us to avoid #include here. */ @WITH_PCRE2_DEFINE@ #ifdef WITH_PCRE2 #define PCRE2_CODE_UNIT_WIDTH 8 #include #else #error "Regex functionality requires PCRE2" #endif #include /* Seq */ /** * @note: The definition of the type Regex may change in the future, so code * using this header should avoid using pcre2_code and use Regex instead * and use RegexDestroy() instead of pcre2_code_free(). */ typedef pcre2_code Regex; #define CFENGINE_REGEX_WHITESPACE_IN_CONTEXTS ".*[_A-Za-z0-9][ \\t]+[_A-Za-z0-9].*" /* Try to use CompileRegex() and StringMatchWithPrecompiledRegex(). */ Regex *CompileRegex(const char *pattern); void RegexDestroy(Regex *regex); bool StringMatch(const char *pattern, const char *str, size_t *start, size_t *end); bool StringMatchWithPrecompiledRegex(const Regex *regex, const char *str, size_t *start, size_t *end); bool StringMatchFull(const char *pattern, const char *str); bool StringMatchFullWithPrecompiledRegex(const Regex *regex, const char *str); Seq *StringMatchCaptures(const char *pattern, const char *str, const bool return_names); Seq *StringMatchCapturesWithPrecompiledRegex(const Regex *pattern, const char *str, const bool return_names); bool CompareStringOrRegex(const char *value, const char *compareTo, bool regex); /* Does not free rx! */ bool RegexPartialMatch(const Regex *regex, const char *teststring); #endif /* CFENGINE_REGEX_H */ cfengine-3.24.2/libntech/libutils/writer.c0000644000000000000000000002177215010704254020464 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include typedef enum { WT_STRING, WT_FILE, } WriterType; typedef struct { char *data; size_t len; /* Does not include trailing zero */ size_t allocated; /* Includes trailing zero */ } StringWriterImpl; struct Writer_ { WriterType type; union { StringWriterImpl string; FILE *file; }; }; /*********************************************************************/ Writer *FileWriter(FILE *file) { Writer *writer = xcalloc(1, sizeof(Writer)); writer->type = WT_FILE; writer->file = file; return writer; } /*********************************************************************/ Writer *StringWriter(void) { Writer *writer = xcalloc(1, sizeof(Writer)); writer->type = WT_STRING; writer->string.data = xstrdup(""); writer->string.allocated = 1; writer->string.len = 0; return writer; } /*********************************************************************/ static void StringWriterReallocate(Writer *writer, size_t extra_length) { assert(writer != NULL); writer->string.allocated = MAX(writer->string.allocated * 2, writer->string.len + extra_length + 1); writer->string.data = xrealloc(writer->string.data, writer->string.allocated); } static size_t StringWriterWriteChar(Writer *writer, char c) { assert(writer != NULL); if (writer->string.len + 2 > writer->string.allocated) { StringWriterReallocate(writer, 2); } writer->string.data[writer->string.len] = c; writer->string.data[writer->string.len + 1] = '\0'; writer->string.len++; return 1; } static size_t StringWriterWriteLen(Writer *writer, const char *str, size_t len_) { assert(writer != NULL); /* NB: str[:len_] may come from read(), which hasn't '\0'-terminated */ size_t len = strnlen(str, len_); if (writer->string.len + len + 1 > writer->string.allocated) { StringWriterReallocate(writer, len); } memcpy(writer->string.data + writer->string.len, str, len); writer->string.data[writer->string.len + len] = '\0'; writer->string.len += len; return len; } /*********************************************************************/ static size_t FileWriterWriteF(Writer *writer, const char *fmt, va_list ap) { assert(writer != NULL); return vfprintf(writer->file, fmt, ap); } /*********************************************************************/ static size_t FileWriterWriteLen(Writer *writer, const char *str, size_t len_) { assert(writer != NULL); size_t len = strnlen(str, len_); #ifdef CFENGINE_TEST return CFENGINE_TEST_fwrite(str, 1, len, writer->file); #else return fwrite(str, 1, len, writer->file); #endif } /*********************************************************************/ size_t WriterWriteF(Writer *writer, const char *fmt, ...) { va_list ap; va_start(ap, fmt); size_t size = WriterWriteVF(writer, fmt, ap); va_end(ap); return size; } /*********************************************************************/ size_t WriterWriteVF(Writer *writer, const char *fmt, va_list ap) { assert(writer != NULL); if (writer->type == WT_STRING) { char *str = NULL; xvasprintf(&str, fmt, ap); size_t size = StringWriterWriteLen(writer, str, INT_MAX); free(str); return size; } else { return FileWriterWriteF(writer, fmt, ap); } } /*********************************************************************/ size_t WriterWriteLen(Writer *writer, const char *str, size_t len) { assert(writer != NULL); if (writer->type == WT_STRING) { return StringWriterWriteLen(writer, str, len); } else { return FileWriterWriteLen(writer, str, len); } } /*********************************************************************/ size_t WriterWrite(Writer *writer, const char *str) { return WriterWriteLen(writer, str, INT_MAX); } /*********************************************************************/ size_t WriterWriteChar(Writer *writer, char c) { assert(writer != NULL); if (writer->type == WT_STRING) { return StringWriterWriteChar(writer, c); } else { char s[2] = { c, '\0' }; return FileWriterWriteLen(writer, s, 1); } } /*********************************************************************/ size_t StringWriterLength(const Writer *writer) { assert(writer != NULL); if (writer->type != WT_STRING) { ProgrammingError("Wrong writer type"); } return writer->string.len; } /*********************************************************************/ const char *StringWriterData(const Writer *writer) { assert(writer != NULL); if (writer->type != WT_STRING) { ProgrammingError("Wrong writer type"); } return writer->string.data; } /*********************************************************************/ void WriterClose(Writer *writer) { assert(writer != NULL); if (writer->type == WT_STRING) { free(writer->string.data); } else { #ifdef CFENGINE_TEST CFENGINE_TEST_fclose(writer->file); #else fclose(writer->file); #endif } free(writer); } /*********************************************************************/ char *StringWriterClose(Writer *writer) // NOTE: transfer of ownership for allocated return value { assert(writer != NULL); if (writer->type != WT_STRING) { ProgrammingError("Wrong writer type"); } char *data = writer->string.data; free(writer); return data; } FILE *FileWriterDetach(Writer *writer) { assert(writer != NULL); if (writer->type != WT_FILE) { ProgrammingError("Wrong writer type"); } FILE *file = writer->file; free(writer); return file; } static void WriterWriteOptions(Writer *w, const struct option options[], const char *const hints[]) { WriterWriteF(w, "\nOptions:\n"); for (int i = 0; options[i].name != NULL; i++) { char short_option[] = ", -*"; if (options[i].val < 128 && options[i].val > 0) { // Within ASCII range, means there is a short option. short_option[3] = options[i].val; } else { // No short option. short_option[0] = '\0'; } if (options[i].has_arg) { WriterWriteF(w, " --%-12s%s value - %s\n", options[i].name, short_option, hints[i]); } else { WriterWriteF(w, " --%-12s%-10s - %s\n", options[i].name, short_option, hints[i]); } } } static void WriterWriteCommands(Writer *w, const Description *commands) { assert(commands != NULL); WriterWriteF(w, "\nCommands:\n"); for (int i = 0; commands[i].name != NULL; i++) { WriterWriteF(w, " %-12s - %s.\n", commands[i].name, commands[i].description); WriterWriteF(w, " %-12s Usage: %s\n", "", commands[i].usage); } } void WriterWriteHelp(Writer *w, const Component *component, const struct option options[], const char *const hints[], const Description *commands, bool command_first, bool accepts_file_argument) { assert (component != NULL); assert (component->name != NULL); WriterWriteF(w, "Usage: %s%s [OPTIONS]%s%s\n", component->name, (commands && command_first) ? " COMMAND" : "", (commands && !command_first) ? " COMMAND" : "", accepts_file_argument ? " [FILE]" : ""); if ((commands != NULL) && command_first) { WriterWriteCommands(w, commands); } WriterWriteOptions(w, options, hints); if ((commands != NULL) && !command_first) { WriterWriteCommands(w, commands); } if (component->website != NULL) { WriterWriteF(w, "\nWebsite: %s\n", component->website); } if (component->copyright != NULL) { WriterWriteF(w, "This software is Copyright %s.\n", component->copyright); } } cfengine-3.24.2/libntech/LICENSE0000644000000000000000000004531015010704254016154 0ustar00rootroot00000000000000This file contains a copy of: 1) Apache License Version 2.0 2) The Commercial Open Source License (COSL) ---------------------------------------------------------------------------- libntech is provided under the terms of the Apache License Version 2.0 (below). On some systems, code under the Frontier Artistic License (libcompat/snprintf) might become compiled. This is compatible with the Apache License. Users of the software may, at their option, choose the COSL license below as part of the enterprise CFEngine product. ------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ------------------------------------------------------------------------------ COMMERCIAL OPEN SOURCE LICENSE This CFEngine commercial open source license ("COSL") is entered into between Northern.tech AS, a Norwegian company, as licensor and a) the Customer entity stipulated on a complete agreement front page (“Front pageâ€), b) any entity or natural person downloading, installing or taking the Software or any part of it into use, or c) any entity or person who otherwise has agreed to be bound by these terms (collectively the "Licensee"). 1 LICENSE 1.1 General The Software is licensed on a consecutive basis (rental) or perpetually, as stipulated on the Front page. See 1.2 and 1.3 below respectively. The following shall apply to either type of license grants. Subject to the terms of this COSL and other agreement between the parties, Northern.tech hereby grants to Licensee a non-exclusive, non-transferable, non-sublicensable and limited license to install, use, study and modify the number of copies of the Software on the number of Instances stipulated on the Front page for use within its organization. The number of Instances the Software may be installed on may be changed by the Customer from time to time, provided ample notice is given to Northern.tech. See Front page for reporting. The Licensee may modify, adapt and create derivative works based upon the Software, for use within its organisation and for sharing between other consecutive licensees under the COSL. Therefore, the Licensee shall have access to the source code of the Software. However, the Licensee shall not reproduce, distribute, resell, rent, lease or disclose the Software in any manner or form to any other third party not holding a COSL to the Software. Licensee may not transfer any of its rights under this COSL without the prior and express written consent of Northern.tech. Any CFEngine software component used by both the CFEngine enterprise version and CFEngine community edition is licensed under the terms of this COSL if the Licensee does not state in writing to Northern.tech that the Licensee instead wish to license the component in question under the GNU General Public License (GPL) v.3.0 or other applicable license. Third party software is licensed under the license of such third party. 1.2 Consecutive license grant (subscription) If the license grant is agreed to be consecutive (see stipulation on Front page), it shall be effective for the period the consecutive license fee (subscription fee) is paid and this license is otherwise complied to. The payment of the consecutive license fee entitles the Customer to Updates and New versions of the Software (as stipulated in appendix 1). 1.3 Perpetual license grant If the license grant is agreed to be perpetual (see stipulation on Front page), the grant is for ever, provided the license terms are complied to. The perpetual license grant is limited to current the version of the Software at the Effective date. Updates or New versions of the Software are not included, unless stated on the Front page (subject to additional fee). 2 DEFINITIONS The following definitions shall apply to the COSL: “Instances†means each physical or virtual computer (server or client), onto which an installation of the Software takes place. “New version†(of the Software) means a new edition of the Software containing functionality or properties not present in the previous edition of the Software. "Software" means: a) the CFEngine Enterprise data centre administration software downloaded by the Licensee or otherwise given access to including bundled documentation and other material, as described at http://www.cfengine.com/; and b) new versions and updates to such software provided by Northern.tech, and “Update†(of Software) means smaller adjustments of the Software with the existing functionality, normally by way of installation of new copy of the Software. 3 FEES The Licensee shall pay a license fee per Instance the Software is installed on for the license granted herein; either: a) per time unit (as agreed) e.g. year, for consecutive license grants, or b) once, for perpetual license grants, for the number of Instances stated on the Front page, or any later adjustments. See the Front page for further details. 4 INTELLECTUAL PROPERTY RIGHTS Northern.tech and its suppliers do not by this COSL transfer any copyrights or other intellectual property rights relating to the Software to the Licensee. Such rights are protected by intellectual property legislation in the United States, Europe and other jurisdictions and by international treaty provisions. Northern.tech and its suppliers retain all rights in the Software that are not expressly granted to the Licensee through this COSL. Licensee is not allowed to remove, alter or destroy any proprietary, trademark or copyright markings or notices placed upon or contained within the Software. 5 TERMINATION Northern.tech may terminate the COSL if the Licensee fails to comply with the terms of this COSL, hereunder fails to pay the stipulated fees. In the event of such termination, the Licensee shall immediately stop using the Software, return any received media and documentation, and destroy or permanently delete any installed versions of the Software, and confirm such destruction or deletion in writing within 7 days. 6 IDEMNIFICATION If the Software (except for third party software) during the term of the license grant is held by a court of competent jurisdiction to infringe any third party intellectual property rights and the Licensee incurs loss or expense as a result of such holding, then Licenee's sole remedy shall be, and Northern.tech will, at its option: (i) obtain the right for Licensse to continue to use the Software consistent with the COSL; (ii) modify the Software so that it becomes non-infringing; (iii) replace the infringing component with a non-infringing component, or (iv) refund monies paid by Licensee under the Agreement during the prior six (6) months to the court holding (for consecutive license grants) or a forth of any perpetual license fee paid, and all Licensees rights and licenses under this Agreement shall automatically terminate. The Licensee is aware that the Software is also comprised of third party software, mostly open source software. Such third party software are subject to its individual license terms, and any claims shall be directed at the ultimate right holder to that software. Consequently Northern.tech is not liable for any defective title in such third party software. See schedule 5 for a list of software contained by the Software with related licenses. 7 NO WARRANTY To the maximum extent permitted by law, Northern.tech disclaims any warranty for the Software (except as stated in clause 6). The Software, any services and any related documentation is provided on an "as is" basis without warranty of any kind, whether express or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose or non-infringement (except as stated in clause 6). Hereunder the parties acknowledges that Northern.tech does not warrant for the performance of any data centre on which the Software runs, or the absence of any errors in the Software, and that any such errors does not constitute a contractual defect. 8 LIABILITY The liability of the parties in contract, tort (including negligence) or otherwise shall for all incidents during the entire term of the COSL be limited to a fifth of the fees paid for a perpetual license or the annual consecutive license fees paid for the Software causing the damage or loss, up to a maximum of NOK 100 000. Northern.tech or its suppliers shall not be liable for any special, incidental, indirect or consequential damages whatsoever (including, without limitation, damages for loss of business profits, lost savings, business interruption, loss of business information, personal injury, loss of privacy, loss of goodwill or any other financial loss) arising out of the use of or inability to use the Software, even if advised of the possibility of such damages. 9 THIRD-PARTY TERMS For third-party software that is made available to the Licensee by Northern.tech, the current terms of the relevant third party software supplier shall apply. cfengine-3.24.2/libntech/libcompat/0000755000000000000000000000000015010704322017112 5ustar00rootroot00000000000000cfengine-3.24.2/libntech/libcompat/Makefile.am0000644000000000000000000000222615010704254021154 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcompat.la AM_CPPFLAGS = -I$(top_srcdir)/libutils # platform.h libcompat_la_LIBADD = $(LTLIBOBJS) libcompat_la_SOURCES = \ generic_at.c generic_at.h CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ cfengine-3.24.2/libntech/libcompat/srand48.c0000644000000000000000000000207115010704254020545 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_DECL_SRAND48 void srand48(long seed); #endif void srand48(long seed) { srand((unsigned) seed); } cfengine-3.24.2/libntech/libcompat/strdup.c0000644000000000000000000000233715010704254020610 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if !HAVE_DECL_STRDUP char *strdup(const char *str); #endif char *strdup(const char *str) { const long len = strlen(str) + 1; char *sp = malloc( len ); if (sp == NULL) { return NULL; } memcpy(sp, str, len); return sp; } cfengine-3.24.2/libntech/libcompat/pthread_sigmask.c0000644000000000000000000000257115010704254022434 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #define _POSIX #include #include #include /* MinGW #defines pthread_sigmask(A,B,C) to "0", which creates problems in the * function implementation. */ #undef pthread_sigmask int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset); /* * Stub implementation. Previously pthread_sigmask was just #ifdef'ed out. */ int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset) { return 0; } cfengine-3.24.2/libntech/libcompat/closefrom.c0000644000000000000000000000547515010704254021266 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #ifdef HAVE_SYS_PSTAT_H # include #endif /* * Does the same as FreeBSD's closefrom: Close all file descriptors higher than * the given one. */ int closefrom(int fd) { #ifdef F_CLOSEM return (fcntl(fd, F_CLOSEM, 0) == -1) ? -1 : 0; #elif defined(HAVE_PSTAT_GETFILE2) const int block_size = 100; struct pst_fileinfo2 info[block_size]; pid_t our_pid = getpid(); while (true) { int count = pstat_getfile2(info, sizeof(info[0]), block_size, 0, our_pid); if (count < 0) { return -1; } else if (count == 0) { break; } for (int info_index = 0; info_index < count; info_index++) { close(info[info_index].psf_fd); } } #else # ifndef _WIN32 char proc_dir[50]; xsnprintf(proc_dir, sizeof(proc_dir), "/proc/%i/fd", getpid()); DIR *iter = opendir(proc_dir); if (iter) { int iter_fd = dirfd(iter); const struct dirent *entry; while ((entry = readdir(iter))) { int curr_fd; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } if (sscanf(entry->d_name, "%i", &curr_fd) != 1) { closedir(iter); errno = EBADF; return -1; } if (curr_fd != iter_fd && curr_fd >= fd) { close(curr_fd); } } closedir(iter); return 0; } # endif // !_WIN32 // Fall back to closing every file descriptor. Very inefficient, but will // work. # ifdef _SC_OPEN_MAX long max_fds = sysconf(_SC_OPEN_MAX); # else long max_fds = 1024; # endif for (long curr_fd = fd; curr_fd < max_fds; curr_fd++) { close(curr_fd); } #endif return 0; } cfengine-3.24.2/libntech/libcompat/memmem.c0000644000000000000000000000310215010704254020533 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include /* size_t */ void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { const char *start; /* Just to avoid casts. */ const char *h = haystack; const char *n = needle; for (start = h; start < h + haystacklen; start++) { size_t len = 0; while (len < needlelen && start + len < h + haystacklen && start[len] == n[len]) { len++; } if (len == needlelen) { return (void *) start; } } return NULL; } cfengine-3.24.2/libntech/libcompat/strndup.c0000644000000000000000000000254015010704254020762 0ustar00rootroot00000000000000/* $OpenBSD: strndup.c,v 1.1 2010/05/18 22:24:55 tedu Exp $ */ /* * Copyright (c) 2010 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #if !HAVE_DECL_STRNLEN size_t strnlen(const char *str, size_t maxlen); #endif #if !HAVE_DECL_STRNDUP char *strndup(const char *str, size_t n); #endif char * strndup(const char *str, size_t maxlen) { char *copy; size_t len; len = strnlen(str, maxlen); copy = malloc(len + 1); if (copy != NULL) { (void)memcpy(copy, str, len); copy[len] = '\0'; } return copy; } cfengine-3.24.2/libntech/libcompat/strcasestr.c0000644000000000000000000000253015010704254021457 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if !HAVE_DECL_STRCASESTR char *strcasestr(const char *haystack, const char *needle); #endif char *strcasestr(const char *haystack, const char *needle) { size_t needlelen = strlen(needle); for (const char *sp = haystack; *sp; sp++) { if (strncasecmp(sp, needle, needlelen) == 0) { return (char *) sp; } } return NULL; } cfengine-3.24.2/libntech/libcompat/fchownat.c0000644000000000000000000000346115010704254021077 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #ifndef __MINGW32__ typedef struct { const char *pathname; uid_t owner; gid_t group; int flags; } fchownat_data; static int fchownat_inner(void *generic_data) { fchownat_data *data = generic_data; if (data->flags & AT_SYMLINK_NOFOLLOW) { return lchown(data->pathname, data->owner, data->group); } else { return chown(data->pathname, data->owner, data->group); } } static void cleanup(ARG_UNUSED void *generic_data) { } int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags) { fchownat_data data; data.pathname = pathname; data.owner = owner; data.group = group; data.flags = flags; return generic_at_function(dirfd, &fchownat_inner, &cleanup, &data); } #endif // !__MINGW32__ cfengine-3.24.2/libntech/libcompat/memrchr.c0000644000000000000000000000242515010704254020722 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include /* size_t */ void *memrchr(const void *s, int c, size_t n) { unsigned char *s_end = (unsigned char *) s + n - 1; while (n > 0) { if ((*s_end) == (unsigned char) c) { return s_end; } s_end--; n--; } return NULL; } cfengine-3.24.2/libntech/libcompat/localtime_r.c0000644000000000000000000000262415010704254021560 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if !HAVE_DECL_LOCALTIME_R struct tm *localtime_r(const time_t *timep, struct tm *result); #endif #if defined(__MINGW32__) /* On Windows, localtime buffer is thread-specific, so using it in place of the reentrant version is safe */ struct tm *localtime_r(const time_t *timep, struct tm *result) { struct tm *ret = localtime(timep); if (ret) { memcpy(result, ret, sizeof(struct tm)); } return ret; } #endif cfengine-3.24.2/libntech/libcompat/strstr.c0000644000000000000000000000246415010704254020631 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_DECL_STRSTR char *strstr(const char *haystack, const char *needle); #endif char *strstr(const char *haystack, const char *needle) { size_t needlelen = strlen(needle); for (const char *sp = haystack; *sp; sp++) { if (strncmp(sp, needle, needlelen) == 0) { return (char *) sp; } } return NULL; } cfengine-3.24.2/libntech/libcompat/strnlen.c0000644000000000000000000000226615010704254020755 0ustar00rootroot00000000000000/* $OpenBSD: strnlen.c,v 1.3 2010/06/02 12:58:12 millert Exp $ */ /* * Copyright (c) 2010 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if !HAVE_DECL_STRNLEN size_t strnlen(const char *str, size_t maxlen); #endif size_t strnlen(const char *str, size_t maxlen) { const char *cp; for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) ; return (size_t)(cp - str); } cfengine-3.24.2/libntech/libcompat/snprintf.c0000644000000000000000000015352715010704254021142 0ustar00rootroot00000000000000/* $Id: snprintf.c,v 1.9 2008/01/20 14:02:00 holger Exp $ */ /* * Copyright (c) 1995 Patrick Powell. * * This code is based on code written by Patrick Powell . * It may be used for any purpose as long as this notice remains intact on all * source code distributions. */ /* * Copyright (c) 2008 Holger Weiss. * * This version of the code is maintained by Holger Weiss . * My changes to the code may freely be used, modified and/or redistributed for * any purpose. It would be nice if additions and fixes to this file (including * trivial code cleanups) would be sent back in order to let me include them in * the version available at . * However, this is not a requirement for using or redistributing (possibly * modified) versions of this file, nor is leaving this notice intact mandatory. */ /* * History * * 2014-04-03 Dimitrios Apostolou : * * snprintf.c: Provided replacement functions for [v][f]printf(). * snprintf.m4: Always check for locale.h and other header files * so that the tests in this file run correctly. * snprintf.m4: _HW_FUNC_XPRINTF_REPLACE was being skipped when configure * was being re-run with cache enabled (-C). Now * AC_LIBOBJ(snprintf) might be called multiple times but * shouldn't matter. * * 2008-01-20 Holger Weiss for C99-snprintf 1.1: * * Fixed the detection of infinite floating point values on IRIX (and * possibly other systems) and applied another few minor cleanups. * * 2008-01-06 Holger Weiss for C99-snprintf 1.0: * * Added a lot of new features, fixed many bugs, and incorporated various * improvements done by Andrew Tridgell , Russ Allbery * , Hrvoje Niksic , Damien Miller * , and others for the Samba, INN, Wget, and OpenSSH * projects. The additions include: support the "e", "E", "g", "G", and * "F" conversion specifiers (and use conversion style "f" or "F" for the * still unsupported "a" and "A" specifiers); support the "hh", "ll", "j", * "t", and "z" length modifiers; support the "#" flag and the (non-C99) * "'" flag; use localeconv(3) (if available) to get both the current * locale's decimal point character and the separator between groups of * digits; fix the handling of various corner cases of field width and * precision specifications; fix various floating point conversion bugs; * handle infinite and NaN floating point values; don't attempt to write to * the output buffer (which may be NULL) if a size of zero was specified; * check for integer overflow of the field width, precision, and return * values and during the floating point conversion; use the OUTCHAR() macro * instead of a function for better performance; provide asprintf(3) and * vasprintf(3) functions; add new test cases. The replacement functions * have been renamed to use an "rpl_" prefix, the function calls in the * main project (and in this file) must be redefined accordingly for each * replacement function which is needed (by using Autoconf or other means). * Various other minor improvements have been applied and the coding style * was cleaned up for consistency. * * 2007-07-23 Holger Weiss for Mutt 1.5.13: * * C99 compliant snprintf(3) and vsnprintf(3) functions return the number * of characters that would have been written to a sufficiently sized * buffer (excluding the '\0'). The original code simply returned the * length of the resulting output string, so that's been fixed. * * 1998-03-05 Michael Elkins for Mutt 0.90.8: * * The original code assumed that both snprintf(3) and vsnprintf(3) were * missing. Some systems only have snprintf(3) but not vsnprintf(3), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * 1998-01-27 Thomas Roessler for Mutt 0.89i: * * The PGP code was using unsigned hexadecimal formats. Unfortunately, * unsigned formats simply didn't work. * * 1997-10-22 Brandon Long for Mutt 0.87.1: * * Ok, added some minimal floating point support, which means this probably * requires libm on most operating systems. Don't yet support the exponent * (e,E) and sigfig (g,G). Also, fmtint() was pretty badly broken, it just * wasn't being exercised in ways which showed it, so that's been fixed. * Also, formatted the code to Mutt conventions, and removed dead code left * over from the original. Also, there is now a builtin-test, run with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf * * 2996-09-15 Brandon Long for Mutt 0.43: * * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything from the * normal C string format, at least as far as I can tell from the Solaris * 2.5 printf(3S) man page. */ /* * ToDo * * - Add wide character support. * - Add support for "%a" and "%A" conversions. * - Create test routines which predefine the expected results. Our test cases * usually expose bugs in system implementations rather than in ours :-) */ /* * Usage * * 1) The following preprocessor macros should be defined to 1 if the feature or * file in question is available on the target system (by using Autoconf or * other means), though basic functionality should be available as long as * HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly: * * HAVE_VSNPRINTF * HAVE_SNPRINTF * HAVE_VASPRINTF * HAVE_ASPRINTF * HAVE_STDARG_H * HAVE_STDDEF_H * HAVE_STDINT_H * HAVE_STDLIB_H * HAVE_INTTYPES_H * HAVE_LOCALE_H * HAVE_LOCALECONV * HAVE_LCONV_DECIMAL_POINT * HAVE_LCONV_THOUSANDS_SEP * HAVE_LONG_DOUBLE * HAVE_LONG_LONG_INT * HAVE_UNSIGNED_LONG_LONG_INT * HAVE_INTMAX_T * HAVE_UINTMAX_T * HAVE_UINTPTR_T * HAVE_PTRDIFF_T * HAVE_VA_COPY * HAVE___VA_COPY * * 2) The calls to the functions which should be replaced must be redefined * throughout the project files (by using Autoconf or other means): * * #define vsnprintf rpl_vsnprintf * #define snprintf rpl_snprintf * #define vasprintf rpl_vasprintf * #define asprintf rpl_asprintf * * 3) The required replacement functions should be declared in some header file * included throughout the project files: * * #if HAVE_CONFIG_H * #include * #endif * #if HAVE_STDARG_H * #include * #if !HAVE_VSNPRINTF * int rpl_vsnprintf(char *, size_t, const char *, va_list); * #endif * #if !HAVE_SNPRINTF * int rpl_snprintf(char *, size_t, const char *, ...); * #endif * #if !HAVE_VASPRINTF * int rpl_vasprintf(char **, const char *, va_list); * #endif * #if !HAVE_ASPRINTF * int rpl_asprintf(char **, const char *, ...); * #endif * #endif * * Autoconf macros for handling step 1 and step 2 are available at * . */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #if TEST_SNPRINTF #include /* For pow(3), NAN, and INFINITY. */ #include /* For strcmp(3). */ #if defined(__NetBSD__) || \ defined(__FreeBSD__) || \ defined(__OpenBSD__) || \ defined(__NeXT__) || \ defined(__bsd__) #define OS_BSD 1 #elif defined(sgi) || defined(__sgi) #ifndef __c99 #define __c99 /* Force C99 mode to get included on IRIX 6.5.30. */ #endif /* !defined(__c99) */ #define OS_IRIX 1 #define OS_SYSV 1 #elif defined(__svr4__) #define OS_SYSV 1 #elif defined(__linux__) #define OS_LINUX 1 #endif /* defined(__NetBSD__) || defined(__FreeBSD__) || [...] */ #if HAVE_CONFIG_H /* Undefine definitions possibly done in config.h. */ #ifdef HAVE_SNPRINTF #undef HAVE_SNPRINTF #endif /* defined(HAVE_SNPRINTF) */ #ifdef HAVE_VSNPRINTF #undef HAVE_VSNPRINTF #endif /* defined(HAVE_VSNPRINTF) */ #ifdef HAVE_ASPRINTF #undef HAVE_ASPRINTF #endif /* defined(HAVE_ASPRINTF) */ #ifdef HAVE_VASPRINTF #undef HAVE_VASPRINTF #endif /* defined(HAVE_VASPRINTF) */ #ifdef snprintf #undef snprintf #endif /* defined(snprintf) */ #ifdef vsnprintf #undef vsnprintf #endif /* defined(vsnprintf) */ #ifdef asprintf #undef asprintf #endif /* defined(asprintf) */ #ifdef vasprintf #undef vasprintf #endif /* defined(vasprintf) */ #else /* By default, we assume a modern system for testing. */ #ifndef HAVE_STDARG_H #define HAVE_STDARG_H 1 #endif /* HAVE_STDARG_H */ #ifndef HAVE_STDDEF_H #define HAVE_STDDEF_H 1 #endif /* HAVE_STDDEF_H */ #ifndef HAVE_STDINT_H #define HAVE_STDINT_H 1 #endif /* HAVE_STDINT_H */ #ifndef HAVE_STDLIB_H #define HAVE_STDLIB_H 1 #endif /* HAVE_STDLIB_H */ #ifndef HAVE_INTTYPES_H #define HAVE_INTTYPES_H 1 #endif /* HAVE_INTTYPES_H */ #ifndef HAVE_LOCALE_H #define HAVE_LOCALE_H 1 #endif /* HAVE_LOCALE_H */ #ifndef HAVE_LOCALECONV #define HAVE_LOCALECONV 1 #endif /* !defined(HAVE_LOCALECONV) */ #ifndef HAVE_LCONV_DECIMAL_POINT #define HAVE_LCONV_DECIMAL_POINT 1 #endif /* HAVE_LCONV_DECIMAL_POINT */ #ifndef HAVE_LCONV_THOUSANDS_SEP #define HAVE_LCONV_THOUSANDS_SEP 1 #endif /* HAVE_LCONV_THOUSANDS_SEP */ #ifndef HAVE_LONG_DOUBLE #define HAVE_LONG_DOUBLE 1 #endif /* !defined(HAVE_LONG_DOUBLE) */ #ifndef HAVE_LONG_LONG_INT #define HAVE_LONG_LONG_INT 1 #endif /* !defined(HAVE_LONG_LONG_INT) */ #ifndef HAVE_UNSIGNED_LONG_LONG_INT #define HAVE_UNSIGNED_LONG_LONG_INT 1 #endif /* !defined(HAVE_UNSIGNED_LONG_LONG_INT) */ #ifndef HAVE_INTMAX_T #define HAVE_INTMAX_T 1 #endif /* !defined(HAVE_INTMAX_T) */ #ifndef HAVE_UINTMAX_T #define HAVE_UINTMAX_T 1 #endif /* !defined(HAVE_UINTMAX_T) */ #ifndef HAVE_UINTPTR_T #define HAVE_UINTPTR_T 1 #endif /* !defined(HAVE_UINTPTR_T) */ #ifndef HAVE_PTRDIFF_T #define HAVE_PTRDIFF_T 1 #endif /* !defined(HAVE_PTRDIFF_T) */ #ifndef HAVE_VA_COPY #define HAVE_VA_COPY 1 #endif /* !defined(HAVE_VA_COPY) */ #ifndef HAVE___VA_COPY #define HAVE___VA_COPY 1 #endif /* !defined(HAVE___VA_COPY) */ #endif /* HAVE_CONFIG_H */ #define snprintf rpl_snprintf #define vsnprintf rpl_vsnprintf #define asprintf rpl_asprintf #define vasprintf rpl_vasprintf #endif /* TEST_SNPRINTF */ #if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF # include /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */ # if HAVE_STDLIB_H # include /* For malloc(3). */ # endif /* HAVE_STDLIB_H */ # ifdef VA_START # undef VA_START # endif /* defined(VA_START) */ # ifdef VA_SHIFT # undef VA_SHIFT # endif /* defined(VA_SHIFT) */ # if HAVE_STDARG_H # include # define VA_START(ap, last) va_start(ap, last) # define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */ # else /* Assume is available. */ # include # define VA_START(ap, last) va_start(ap) /* "last" is ignored. */ # define VA_SHIFT(ap, value, type) value = va_arg(ap, type) # endif /* HAVE_STDARG_H */ #if !HAVE_VASPRINTF #ifdef VA_COPY #undef VA_COPY #endif /* defined(VA_COPY) */ #ifdef VA_END_COPY #undef VA_END_COPY #endif /* defined(VA_END_COPY) */ #if HAVE_VA_COPY #define VA_COPY(dest, src) va_copy(dest, src) #define VA_END_COPY(ap) va_end(ap) #elif HAVE___VA_COPY #define VA_COPY(dest, src) __va_copy(dest, src) #define VA_END_COPY(ap) va_end(ap) #else #define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list)) #define VA_END_COPY(ap) /* No-op. */ #define NEED_MYMEMCPY 1 static void *mymemcpy(void *, void *, size_t); #endif /* HAVE_VA_COPY */ #endif /* !HAVE_VASPRINTF */ #if !HAVE_VSNPRINTF #include /* For ERANGE and errno. */ #include /* For *_MAX. */ #if HAVE_INTTYPES_H #include /* For intmax_t (if not defined in ). */ #endif /* HAVE_INTTYPES_H */ #if HAVE_LOCALE_H #include /* For localeconv(3). */ #endif /* HAVE_LOCALE_H */ #if HAVE_STDDEF_H #include /* For ptrdiff_t. */ #endif /* HAVE_STDDEF_H */ #if HAVE_STDINT_H #include /* For intmax_t. */ #endif /* HAVE_STDINT_H */ /* Support for unsigned long long int. We may also need ULLONG_MAX. */ #ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */ #ifdef UINT_MAX #define ULONG_MAX UINT_MAX #else #define ULONG_MAX INT_MAX #endif /* defined(UINT_MAX) */ #endif /* !defined(ULONG_MAX) */ #ifdef ULLONG #undef ULLONG #endif /* defined(ULLONG) */ #if HAVE_UNSIGNED_LONG_LONG_INT #define ULLONG unsigned long long int #ifndef ULLONG_MAX #define ULLONG_MAX ULONG_MAX #endif /* !defined(ULLONG_MAX) */ #else #define ULLONG unsigned long int #ifdef ULLONG_MAX #undef ULLONG_MAX #endif /* defined(ULLONG_MAX) */ #define ULLONG_MAX ULONG_MAX #endif /* HAVE_LONG_LONG_INT */ /* Support for uintmax_t. We also need UINTMAX_MAX. */ #ifdef UINTMAX_T #undef UINTMAX_T #endif /* defined(UINTMAX_T) */ #if HAVE_UINTMAX_T || defined(uintmax_t) #define UINTMAX_T uintmax_t #ifndef UINTMAX_MAX #define UINTMAX_MAX ULLONG_MAX #endif /* !defined(UINTMAX_MAX) */ #else #define UINTMAX_T ULLONG #ifdef UINTMAX_MAX #undef UINTMAX_MAX #endif /* defined(UINTMAX_MAX) */ #define UINTMAX_MAX ULLONG_MAX #endif /* HAVE_UINTMAX_T || defined(uintmax_t) */ /* Support for long double. */ #ifndef LDOUBLE #if HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif /* HAVE_LONG_DOUBLE */ #endif /* !defined(LDOUBLE) */ /* Support for long long int. */ #ifndef LLONG #if HAVE_LONG_LONG_INT #define LLONG long long int #else #define LLONG long int #endif /* HAVE_LONG_LONG_INT */ #endif /* !defined(LLONG) */ /* Support for intmax_t. */ #ifndef INTMAX_T #if HAVE_INTMAX_T || defined(intmax_t) #define INTMAX_T intmax_t #else #define INTMAX_T LLONG #endif /* HAVE_INTMAX_T || defined(intmax_t) */ #endif /* !defined(INTMAX_T) */ /* Support for uintptr_t. */ #ifndef UINTPTR_T #if HAVE_UINTPTR_T || defined(uintptr_t) #define UINTPTR_T uintptr_t #else #define UINTPTR_T unsigned long int #endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ #endif /* !defined(UINTPTR_T) */ /* Support for ptrdiff_t. */ #ifndef PTRDIFF_T #if HAVE_PTRDIFF_T || defined(ptrdiff_t) #define PTRDIFF_T ptrdiff_t #else #define PTRDIFF_T long int #endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */ #endif /* !defined(PTRDIFF_T) */ /* * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99: * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an * unsigned type if necessary. This should work just fine in practice. */ #ifndef UPTRDIFF_T #define UPTRDIFF_T PTRDIFF_T #endif /* !defined(UPTRDIFF_T) */ /* * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7). * However, we'll simply use size_t and convert it to a signed type if * necessary. This should work just fine in practice. */ #ifndef SSIZE_T #define SSIZE_T size_t #endif /* !defined(SSIZE_T) */ /* Either ERANGE or E2BIG should be available everywhere. */ #ifndef ERANGE #define ERANGE E2BIG #endif /* !defined(ERANGE) */ #ifndef EOVERFLOW #define EOVERFLOW ERANGE #endif /* !defined(EOVERFLOW) */ /* * Buffer size to hold the octal string representation of UINT128_MAX without * nul-termination ("3777777777777777777777777777777777777777777"). */ #ifdef MAX_CONVERT_LENGTH #undef MAX_CONVERT_LENGTH #endif /* defined(MAX_CONVERT_LENGTH) */ #define MAX_CONVERT_LENGTH 43 /* Format read states. */ #define PRINT_S_DEFAULT 0 #define PRINT_S_FLAGS 1 #define PRINT_S_WIDTH 2 #define PRINT_S_DOT 3 #define PRINT_S_PRECISION 4 #define PRINT_S_MOD 5 #define PRINT_S_CONV 6 /* Format flags. */ #define PRINT_F_MINUS (1 << 0) #define PRINT_F_PLUS (1 << 1) #define PRINT_F_SPACE (1 << 2) #define PRINT_F_NUM (1 << 3) #define PRINT_F_ZERO (1 << 4) #define PRINT_F_QUOTE (1 << 5) #define PRINT_F_UP (1 << 6) #define PRINT_F_UNSIGNED (1 << 7) #define PRINT_F_TYPE_G (1 << 8) #define PRINT_F_TYPE_E (1 << 9) /* Conversion flags. */ #define PRINT_C_CHAR 1 #define PRINT_C_SHORT 2 #define PRINT_C_LONG 3 #define PRINT_C_LLONG 4 #define PRINT_C_LDOUBLE 5 #define PRINT_C_SIZE 6 #define PRINT_C_PTRDIFF 7 #define PRINT_C_INTMAX 8 #ifndef MAX #define MAX(x, y) ((x >= y) ? x : y) #endif /* !defined(MAX) */ #ifndef CHARTOINT #define CHARTOINT(ch) (ch - '0') #endif /* !defined(CHARTOINT) */ #ifndef ISDIGIT #define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9') #endif /* !defined(ISDIGIT) */ #ifndef ISNAN #define ISNAN(x) (x != x) #endif /* !defined(ISNAN) */ #ifndef ISINF #define ISINF(x) (x != 0.0 && x + x == x) #endif /* !defined(ISINF) */ #ifdef OUTCHAR #undef OUTCHAR #endif /* defined(OUTCHAR) */ #define OUTCHAR(str, len, size, ch) \ do { \ if (len + 1 < size) \ str[len] = ch; \ (len)++; \ } while (/* CONSTCOND */ 0) static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); static void printsep(char *, size_t *, size_t); static int getnumsep(int); static int getexponent(LDOUBLE); static int convert(UINTMAX_T, char *, size_t, int, int); static UINTMAX_T cast(LDOUBLE); static UINTMAX_T myround(LDOUBLE); static LDOUBLE mypow10(int); /*extern int errno;*/ int rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) { LDOUBLE fvalue; INTMAX_T value; unsigned char cvalue; const char *strvalue; INTMAX_T *intmaxptr; PTRDIFF_T *ptrdiffptr; SSIZE_T *sizeptr; LLONG *llongptr; long int *longptr; int *intptr; short int *shortptr; signed char *charptr; size_t len = 0; int overflow = 0; int base = 0; int cflags = 0; int flags = 0; int width = 0; int precision = -1; int state = PRINT_S_DEFAULT; char ch = *format++; /* * C99 says: "If `n' is zero, nothing is written, and `s' may be a null * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer * even if a size larger than zero was specified. At least NetBSD's * snprintf(3) does the same, as well as other versions of this file. * (Though some of these versions will write to a non-NULL buffer even * if a size of zero was specified, which violates the standard.) */ if (str == NULL && size != 0) size = 0; while (ch != '\0') switch (state) { case PRINT_S_DEFAULT: if (ch == '%') state = PRINT_S_FLAGS; else OUTCHAR(str, len, size, ch); ch = *format++; break; case PRINT_S_FLAGS: switch (ch) { case '-': flags |= PRINT_F_MINUS; ch = *format++; break; case '+': flags |= PRINT_F_PLUS; ch = *format++; break; case ' ': flags |= PRINT_F_SPACE; ch = *format++; break; case '#': flags |= PRINT_F_NUM; ch = *format++; break; case '0': flags |= PRINT_F_ZERO; ch = *format++; break; case '\'': /* SUSv2 flag (not in C99). */ flags |= PRINT_F_QUOTE; ch = *format++; break; default: state = PRINT_S_WIDTH; break; } break; case PRINT_S_WIDTH: if (ISDIGIT(ch)) { ch = CHARTOINT(ch); if (width > (INT_MAX - ch) / 10) { overflow = 1; goto out; } width = 10 * width + ch; ch = *format++; } else if (ch == '*') { /* * C99 says: "A negative field width argument is * taken as a `-' flag followed by a positive * field width." (7.19.6.1, 5) */ if ((width = va_arg(args, int)) < 0) { flags |= PRINT_F_MINUS; width = -width; } ch = *format++; state = PRINT_S_DOT; } else state = PRINT_S_DOT; break; case PRINT_S_DOT: if (ch == '.') { state = PRINT_S_PRECISION; ch = *format++; } else state = PRINT_S_MOD; break; case PRINT_S_PRECISION: if (precision == -1) precision = 0; if (ISDIGIT(ch)) { ch = CHARTOINT(ch); if (precision > (INT_MAX - ch) / 10) { overflow = 1; goto out; } precision = 10 * precision + ch; ch = *format++; } else if (ch == '*') { /* * C99 says: "A negative precision argument is * taken as if the precision were omitted." * (7.19.6.1, 5) */ if ((precision = va_arg(args, int)) < 0) precision = -1; ch = *format++; state = PRINT_S_MOD; } else state = PRINT_S_MOD; break; case PRINT_S_MOD: switch (ch) { case 'h': ch = *format++; if (ch == 'h') { /* It's a char. */ ch = *format++; cflags = PRINT_C_CHAR; } else cflags = PRINT_C_SHORT; break; case 'l': ch = *format++; if (ch == 'l') { /* It's a long long. */ ch = *format++; cflags = PRINT_C_LLONG; } else cflags = PRINT_C_LONG; break; case 'L': cflags = PRINT_C_LDOUBLE; ch = *format++; break; case 'j': cflags = PRINT_C_INTMAX; ch = *format++; break; case 't': cflags = PRINT_C_PTRDIFF; ch = *format++; break; case 'z': cflags = PRINT_C_SIZE; ch = *format++; break; } state = PRINT_S_CONV; break; case PRINT_S_CONV: switch (ch) { case 'd': /* FALLTHROUGH */ case 'i': switch (cflags) { case PRINT_C_CHAR: value = (signed char)va_arg(args, int); break; case PRINT_C_SHORT: value = (short int)va_arg(args, int); break; case PRINT_C_LONG: value = va_arg(args, long int); break; case PRINT_C_LLONG: value = va_arg(args, LLONG); break; case PRINT_C_SIZE: value = va_arg(args, SSIZE_T); break; case PRINT_C_INTMAX: value = va_arg(args, INTMAX_T); break; case PRINT_C_PTRDIFF: value = va_arg(args, PTRDIFF_T); break; default: value = va_arg(args, int); break; } fmtint(str, &len, size, value, 10, width, precision, flags); break; case 'X': flags |= PRINT_F_UP; /* FALLTHROUGH */ case 'x': base = 16; /* FALLTHROUGH */ case 'o': if (base == 0) base = 8; /* FALLTHROUGH */ case 'u': if (base == 0) base = 10; flags |= PRINT_F_UNSIGNED; switch (cflags) { case PRINT_C_CHAR: value = (unsigned char)va_arg(args, unsigned int); break; case PRINT_C_SHORT: value = (unsigned short int)va_arg(args, unsigned int); break; case PRINT_C_LONG: value = va_arg(args, unsigned long int); break; case PRINT_C_LLONG: value = va_arg(args, ULLONG); break; case PRINT_C_SIZE: value = va_arg(args, size_t); break; case PRINT_C_INTMAX: value = va_arg(args, UINTMAX_T); break; case PRINT_C_PTRDIFF: value = va_arg(args, UPTRDIFF_T); break; default: value = va_arg(args, unsigned int); break; } fmtint(str, &len, size, value, base, width, precision, flags); break; case 'A': /* Not yet supported, we'll use "%F". */ /* FALLTHROUGH */ case 'F': flags |= PRINT_F_UP; case 'a': /* Not yet supported, we'll use "%f". */ /* FALLTHROUGH */ case 'f': if (cflags == PRINT_C_LDOUBLE) fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); fmtflt(str, &len, size, fvalue, width, precision, flags, &overflow); if (overflow) goto out; break; case 'E': flags |= PRINT_F_UP; /* FALLTHROUGH */ case 'e': flags |= PRINT_F_TYPE_E; if (cflags == PRINT_C_LDOUBLE) fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); fmtflt(str, &len, size, fvalue, width, precision, flags, &overflow); if (overflow) goto out; break; case 'G': flags |= PRINT_F_UP; /* FALLTHROUGH */ case 'g': flags |= PRINT_F_TYPE_G; if (cflags == PRINT_C_LDOUBLE) fvalue = va_arg(args, LDOUBLE); else fvalue = va_arg(args, double); /* * If the precision is zero, it is treated as * one (cf. C99: 7.19.6.1, 8). */ if (precision == 0) precision = 1; fmtflt(str, &len, size, fvalue, width, precision, flags, &overflow); if (overflow) goto out; break; case 'c': cvalue = va_arg(args, int); OUTCHAR(str, len, size, cvalue); break; case 's': strvalue = va_arg(args, char *); fmtstr(str, &len, size, strvalue, width, precision, flags); break; case 'p': /* * C99 says: "The value of the pointer is * converted to a sequence of printing * characters, in an implementation-defined * manner." (C99: 7.19.6.1, 8) */ if ((strvalue = va_arg(args, void *)) == NULL) /* * We use the glibc format. BSD prints * "0x0", SysV "0". */ fmtstr(str, &len, size, "(nil)", width, -1, flags); else { /* * We use the BSD/glibc format. SysV * omits the "0x" prefix (which we emit * using the PRINT_F_NUM flag). */ flags |= PRINT_F_NUM; flags |= PRINT_F_UNSIGNED; fmtint(str, &len, size, (UINTPTR_T)strvalue, 16, width, precision, flags); } break; case 'n': switch (cflags) { case PRINT_C_CHAR: charptr = va_arg(args, signed char *); *charptr = len; break; case PRINT_C_SHORT: shortptr = va_arg(args, short int *); *shortptr = len; break; case PRINT_C_LONG: longptr = va_arg(args, long int *); *longptr = len; break; case PRINT_C_LLONG: llongptr = va_arg(args, LLONG *); *llongptr = len; break; case PRINT_C_SIZE: /* * C99 says that with the "z" length * modifier, "a following `n' conversion * specifier applies to a pointer to a * signed integer type corresponding to * size_t argument." (7.19.6.1, 7) */ sizeptr = va_arg(args, SSIZE_T *); *sizeptr = len; break; case PRINT_C_INTMAX: intmaxptr = va_arg(args, INTMAX_T *); *intmaxptr = len; break; case PRINT_C_PTRDIFF: ptrdiffptr = va_arg(args, PTRDIFF_T *); *ptrdiffptr = len; break; default: intptr = va_arg(args, int *); *intptr = len; break; } break; case '%': /* Print a "%" character verbatim. */ OUTCHAR(str, len, size, ch); break; default: /* Skip other characters. */ break; } ch = *format++; state = PRINT_S_DEFAULT; base = cflags = flags = width = 0; precision = -1; break; } out: if (len < size) str[len] = '\0'; else if (size > 0) str[size - 1] = '\0'; if (overflow || len >= INT_MAX) { errno = overflow ? EOVERFLOW : ERANGE; return -1; } return (int)len; } static void fmtstr(char *str, size_t *len, size_t size, const char *value, int width, int precision, int flags) { int padlen, strln; /* Amount to pad. */ int noprecision = (precision == -1); if (value == NULL) /* We're forgiving. */ value = "(null)"; /* If a precision was specified, don't read the string past it. */ for (strln = 0; value[strln] != '\0' && (noprecision || strln < precision); strln++) continue; if ((padlen = width - strln) < 0) padlen = 0; if (flags & PRINT_F_MINUS) /* Left justify. */ padlen = -padlen; while (padlen > 0) { /* Leading spaces. */ OUTCHAR(str, *len, size, ' '); padlen--; } while (*value != '\0' && (noprecision || precision-- > 0)) { OUTCHAR(str, *len, size, *value); value++; } while (padlen < 0) { /* Trailing spaces. */ OUTCHAR(str, *len, size, ' '); padlen++; } } static void fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width, int precision, int flags) { UINTMAX_T uvalue; char iconvert[MAX_CONVERT_LENGTH]; char sign = 0; char hexprefix = 0; int spadlen = 0; /* Amount to space pad. */ int zpadlen = 0; /* Amount to zero pad. */ int pos; int separators = (flags & PRINT_F_QUOTE); int noprecision = (precision == -1); if (flags & PRINT_F_UNSIGNED) uvalue = value; else { uvalue = (value >= 0) ? value : -value; if (value < 0) sign = '-'; else if (flags & PRINT_F_PLUS) /* Do a sign. */ sign = '+'; else if (flags & PRINT_F_SPACE) sign = ' '; } pos = convert(uvalue, iconvert, sizeof(iconvert), base, flags & PRINT_F_UP); if (flags & PRINT_F_NUM && uvalue != 0) { /* * C99 says: "The result is converted to an `alternative form'. * For `o' conversion, it increases the precision, if and only * if necessary, to force the first digit of the result to be a * zero (if the value and precision are both 0, a single 0 is * printed). For `x' (or `X') conversion, a nonzero result has * `0x' (or `0X') prefixed to it." (7.19.6.1, 6) */ switch (base) { case 8: if (precision <= pos) precision = pos + 1; break; case 16: hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x'; break; } } if (separators) /* Get the number of group separators we'll print. */ separators = getnumsep(pos); zpadlen = precision - pos - separators; spadlen = width /* Minimum field width. */ - separators /* Number of separators. */ - MAX(precision, pos) /* Number of integer digits. */ - ((sign != 0) ? 1 : 0) /* Will we print a sign? */ - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */ if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; /* * C99 says: "If the `0' and `-' flags both appear, the `0' flag is * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a * precision is specified, the `0' flag is ignored." (7.19.6.1, 6) */ if (flags & PRINT_F_MINUS) /* Left justify. */ spadlen = -spadlen; else if (flags & PRINT_F_ZERO && noprecision) { zpadlen += spadlen; spadlen = 0; } while (spadlen > 0) { /* Leading spaces. */ OUTCHAR(str, *len, size, ' '); spadlen--; } if (sign != 0) /* Sign. */ OUTCHAR(str, *len, size, sign); if (hexprefix != 0) { /* A "0x" or "0X" prefix. */ OUTCHAR(str, *len, size, '0'); OUTCHAR(str, *len, size, hexprefix); } while (zpadlen > 0) { /* Leading zeros. */ OUTCHAR(str, *len, size, '0'); zpadlen--; } while (pos > 0) { /* The actual digits. */ pos--; OUTCHAR(str, *len, size, iconvert[pos]); if (separators > 0 && pos > 0 && pos % 3 == 0) printsep(str, len, size); } while (spadlen < 0) { /* Trailing spaces. */ OUTCHAR(str, *len, size, ' '); spadlen++; } } static void fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width, int precision, int flags, int *overflow) { LDOUBLE ufvalue; UINTMAX_T intpart; UINTMAX_T fracpart; UINTMAX_T mask; const char *infnan = NULL; char iconvert[MAX_CONVERT_LENGTH]; char fconvert[MAX_CONVERT_LENGTH]; char econvert[4]; /* "e-12" (without nul-termination). */ char esign = 0; char sign = 0; int leadfraczeros = 0; int exponent = 0; int emitpoint = 0; int omitzeros = 0; int omitcount = 0; int padlen = 0; int epos = 0; int fpos = 0; int ipos = 0; int separators = (flags & PRINT_F_QUOTE); int estyle = (flags & PRINT_F_TYPE_E); #if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT struct lconv *lc = localeconv(); #endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ /* * AIX' man page says the default is 0, but C99 and at least Solaris' * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX * defaults to 6. */ if (precision == -1) precision = 6; if (fvalue < 0.0) sign = '-'; else if (flags & PRINT_F_PLUS) /* Do a sign. */ sign = '+'; else if (flags & PRINT_F_SPACE) sign = ' '; if (ISNAN(fvalue)) infnan = (flags & PRINT_F_UP) ? "NAN" : "nan"; else if (ISINF(fvalue)) infnan = (flags & PRINT_F_UP) ? "INF" : "inf"; if (infnan != NULL) { if (sign != 0) iconvert[ipos++] = sign; while (*infnan != '\0') iconvert[ipos++] = *infnan++; fmtstr(str, len, size, iconvert, width, ipos, flags); return; } /* "%e" (or "%E") or "%g" (or "%G") conversion. */ if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) { if (flags & PRINT_F_TYPE_G) { /* * For "%g" (and "%G") conversions, the precision * specifies the number of significant digits, which * includes the digits in the integer part. The * conversion will or will not be using "e-style" (like * "%e" or "%E" conversions) depending on the precision * and on the exponent. However, the exponent can be * affected by rounding the converted value, so we'll * leave this decision for later. Until then, we'll * assume that we're going to do an "e-style" conversion * (in order to get the exponent calculated). For * "e-style", the precision must be decremented by one. */ precision--; /* * For "%g" (and "%G") conversions, trailing zeros are * removed from the fractional portion of the result * unless the "#" flag was specified. */ if (!(flags & PRINT_F_NUM)) omitzeros = 1; } exponent = getexponent(fvalue); estyle = 1; } again: /* * Sorry, we only support 9, 19, or 38 digits (that is, the number of * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value * minus one) past the decimal point due to our conversion method. */ switch (sizeof(UINTMAX_T)) { case 16: if (precision > 38) precision = 38; break; case 8: if (precision > 19) precision = 19; break; default: if (precision > 9) precision = 9; break; } ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue; if (estyle) /* We want exactly one integer digit. */ ufvalue /= mypow10(exponent); if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { *overflow = 1; return; } /* * Factor of ten with the number of digits needed for the fractional * part. For example, if the precision is 3, the mask will be 1000. */ mask = mypow10(precision); /* * We "cheat" by converting the fractional part to integer by * multiplying by a factor of ten. */ if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { /* * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 * (because precision = 3). Now, myround(1000 * 0.99962) will * return 1000. So, the integer part must be incremented by one * and the fractional part must be set to zero. */ intpart++; fracpart = 0; if (estyle && intpart == 10) { /* * The value was rounded up to ten, but we only want one * integer digit if using "e-style". So, the integer * part must be set to one and the exponent must be * incremented by one. */ intpart = 1; exponent++; } } /* * Now that we know the real exponent, we can check whether or not to * use "e-style" for "%g" (and "%G") conversions. If we don't need * "e-style", the precision must be adjusted and the integer and * fractional parts must be recalculated from the original value. * * C99 says: "Let P equal the precision if nonzero, 6 if the precision * is omitted, or 1 if the precision is zero. Then, if a conversion * with style `E' would have an exponent of X: * * - if P > X >= -4, the conversion is with style `f' (or `F') and * precision P - (X + 1). * * - otherwise, the conversion is with style `e' (or `E') and precision * P - 1." (7.19.6.1, 8) * * Note that we had decremented the precision by one. */ if (flags & PRINT_F_TYPE_G && estyle && precision + 1 > exponent && exponent >= -4) { precision -= exponent; estyle = 0; goto again; } if (estyle) { if (exponent < 0) { exponent = -exponent; esign = '-'; } else esign = '+'; /* * Convert the exponent. The sizeof(econvert) is 4. So, the * econvert buffer can hold e.g. "e+99" and "e-99". We don't * support an exponent which contains more than two digits. * Therefore, the following stores are safe. */ epos = convert(exponent, econvert, 2, 10, 0); /* * C99 says: "The exponent always contains at least two digits, * and only as many more digits as necessary to represent the * exponent." (7.19.6.1, 8) */ if (epos == 1) econvert[epos++] = '0'; econvert[epos++] = esign; econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e'; } /* Convert the integer part and the fractional part. */ ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0); if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */ fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0); leadfraczeros = precision - fpos; if (omitzeros) { if (fpos > 0) /* Omit trailing fractional part zeros. */ while (omitcount < fpos && fconvert[omitcount] == '0') omitcount++; else { /* The fractional part is zero, omit it completely. */ omitcount = precision; leadfraczeros = 0; } precision -= omitcount; } /* * Print a decimal point if either the fractional part is non-zero * and/or the "#" flag was specified. */ if (precision > 0 || flags & PRINT_F_NUM) emitpoint = 1; if (separators) /* Get the number of group separators we'll print. */ separators = getnumsep(ipos); padlen = width /* Minimum field width. */ - ipos /* Number of integer digits. */ - epos /* Number of exponent characters. */ - precision /* Number of fractional digits. */ - separators /* Number of group separators. */ - (emitpoint ? 1 : 0) /* Will we print a decimal point? */ - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */ if (padlen < 0) padlen = 0; /* * C99 says: "If the `0' and `-' flags both appear, the `0' flag is * ignored." (7.19.6.1, 6) */ if (flags & PRINT_F_MINUS) /* Left justifty. */ padlen = -padlen; else if (flags & PRINT_F_ZERO && padlen > 0) { if (sign != 0) { /* Sign. */ OUTCHAR(str, *len, size, sign); sign = 0; } while (padlen > 0) { /* Leading zeros. */ OUTCHAR(str, *len, size, '0'); padlen--; } } while (padlen > 0) { /* Leading spaces. */ OUTCHAR(str, *len, size, ' '); padlen--; } if (sign != 0) /* Sign. */ OUTCHAR(str, *len, size, sign); while (ipos > 0) { /* Integer part. */ ipos--; OUTCHAR(str, *len, size, iconvert[ipos]); if (separators > 0 && ipos > 0 && ipos % 3 == 0) printsep(str, len, size); } if (emitpoint) { /* Decimal point. */ #if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT if (lc->decimal_point != NULL && *lc->decimal_point != '\0') OUTCHAR(str, *len, size, *lc->decimal_point); else /* We'll always print some decimal point character. */ #endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ OUTCHAR(str, *len, size, '.'); } while (leadfraczeros > 0) { /* Leading fractional part zeros. */ OUTCHAR(str, *len, size, '0'); leadfraczeros--; } while (fpos > omitcount) { /* The remaining fractional part. */ fpos--; OUTCHAR(str, *len, size, fconvert[fpos]); } while (epos > 0) { /* Exponent. */ epos--; OUTCHAR(str, *len, size, econvert[epos]); } while (padlen < 0) { /* Trailing spaces. */ OUTCHAR(str, *len, size, ' '); padlen++; } } static void printsep(char *str, size_t *len, size_t size) { #if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP struct lconv *lc = localeconv(); int i; if (lc->thousands_sep != NULL) for (i = 0; lc->thousands_sep[i] != '\0'; i++) OUTCHAR(str, *len, size, lc->thousands_sep[i]); else #endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ OUTCHAR(str, *len, size, ','); } static int getnumsep(int digits) { int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3; #if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP int strln; struct lconv *lc = localeconv(); /* We support an arbitrary separator length (including zero). */ if (lc->thousands_sep != NULL) { for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++) continue; separators *= strln; } #endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ return separators; } static int getexponent(LDOUBLE value) { LDOUBLE tmp = (value >= 0.0) ? value : -value; int exponent = 0; /* * We check for 99 > exponent > -99 in order to work around possible * endless loops which could happen (at least) in the second loop (at * least) if we're called with an infinite value. However, we checked * for infinity before calling this function using our ISINF() macro, so * this might be somewhat paranoid. */ while (tmp < 1.0 && tmp > 0.0 && --exponent > -99) tmp *= 10; while (tmp >= 10.0 && ++exponent < 99) tmp /= 10; return exponent; } static int convert(UINTMAX_T value, char *buf, size_t size, int base, int caps) { const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; size_t pos = 0; /* We return an unterminated buffer with the digits in reverse order. */ do { buf[pos++] = digits[value % base]; value /= base; } while (value != 0 && pos < size); return (int)pos; } static UINTMAX_T cast(LDOUBLE value) { UINTMAX_T result; /* * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be * represented exactly as an LDOUBLE value (but is less than LDBL_MAX), * it may be increased to the nearest higher representable value for the * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE * value although converting the latter to UINTMAX_T would overflow. */ if (value >= UINTMAX_MAX) return UINTMAX_MAX; result = value; /* * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates * the standard). Sigh. */ return (result <= value) ? result : result - 1; } static UINTMAX_T myround(LDOUBLE value) { UINTMAX_T intpart = cast(value); return ((value -= intpart) < 0.5) ? intpart : intpart + 1; } static LDOUBLE mypow10(int exponent) { LDOUBLE result = 1; while (exponent > 0) { result *= 10; exponent--; } while (exponent < 0) { result /= 10; exponent++; } return result; } #endif /* !HAVE_VSNPRINTF */ #if !HAVE_VASPRINTF #if NEED_MYMEMCPY void * mymemcpy(void *dst, void *src, size_t len) { const char *from = src; char *to = dst; /* No need for optimization, we use this only to replace va_copy(3). */ while (len-- > 0) *to++ = *from++; return dst; } #endif /* NEED_MYMEMCPY */ int rpl_vasprintf(char **ret, const char *format, va_list ap) { size_t size; int len; va_list aq; VA_COPY(aq, ap); len = vsnprintf(NULL, 0, format, aq); VA_END_COPY(aq); if (len < 0 || (*ret = malloc(size = len + 1)) == NULL) return -1; return vsnprintf(*ret, size, format, ap); } #endif /* !HAVE_VASPRINTF */ #if !HAVE_SNPRINTF #if HAVE_STDARG_H int rpl_snprintf(char *str, size_t size, const char *format, ...) #else int rpl_snprintf(va_alist) va_dcl #endif /* HAVE_STDARG_H */ { #if !HAVE_STDARG_H char *str; size_t size; char *format; #endif /* HAVE_STDARG_H */ va_list ap; int len; VA_START(ap, format); VA_SHIFT(ap, str, char *); VA_SHIFT(ap, size, size_t); VA_SHIFT(ap, format, const char *); len = vsnprintf(str, size, format, ap); va_end(ap); return len; } #endif /* !HAVE_SNPRINTF */ #if !HAVE_ASPRINTF #if HAVE_STDARG_H int rpl_asprintf(char **ret, const char *format, ...) #else int rpl_asprintf(va_alist) va_dcl #endif /* HAVE_STDARG_H */ { #if !HAVE_STDARG_H char **ret; char *format; #endif /* HAVE_STDARG_H */ va_list ap; int len; VA_START(ap, format); VA_SHIFT(ap, ret, char **); VA_SHIFT(ap, format, const char *); len = vasprintf(ret, format, ap); va_end(ap); return len; } #endif /* !HAVE_ASPRINTF */ /* If [v]snprintf() does not exist or is not C99 compatible, then we assume * that [v]printf() and [v]fprintf() need to be provided as well. */ #if !HAVE_VSNPRINTF int rpl_vfprintf(FILE *stream, const char *format, va_list ap) { va_list ap2; char staticbuf[1024]; char *buf = staticbuf; /* Try to write to staticbuf. */ va_copy(ap2, ap); int len = vsnprintf(staticbuf, sizeof(staticbuf), format, ap2); va_end(ap2); /* Was the output truncated? */ if (len >= sizeof(staticbuf)) { size_t buf_size = len + 1; buf = malloc(buf_size); if (buf == NULL) { return -1; } /* Write to the allocated buffer. */ va_copy(ap2, ap); len = vsnprintf(buf, buf_size, format, ap2); va_end(ap2); /* Truncated again! Should never happen! */ if (len >= buf_size) { len = -1; } } /* Finally write to the stream. */ if (len > 0) { len = fwrite(buf, 1, len, stream); } if (buf != staticbuf) { free(buf); } return len; } int rpl_vprintf(const char *format, va_list ap) { va_list ap2; va_copy(ap2, ap); int len = vfprintf(stdout, format, ap); va_end(ap2); return len; } #endif #if !HAVE_SNPRINTF int rpl_fprintf(FILE *stream, const char *format, ...) { va_list ap; int len; va_start(ap, format); len = vfprintf(stream, format, ap); va_end(ap); return len; } int rpl_printf(const char *format, ...) { va_list ap; va_start(ap, format); int len = vprintf(format, ap); va_end(ap); return len; } #endif #else /* Dummy declaration to avoid empty translation unit warnings. */ int main(void); #endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */ #if TEST_SNPRINTF /* sprintf() is marked as deprecated in CFEngine, but here we use it on * purpose to compare this snprintf() implementation to the system's * implementation. So avoid emitting the warning. */ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" static int snprintf_rigorous_test(void) { const char *float_fmt[] = { /* "%E" and "%e" formats. */ #if HAVE_LONG_LONG_INT && !OS_BSD && !OS_IRIX "%.16e", "%22.16e", "%022.16e", "%-22.16e", "%#+'022.16e", #endif /* HAVE_LONG_LONG_INT && !OS_BSD && !OS_IRIX */ "foo|%#+0123.9E|bar", "%-123.9e", "%123.9e", "%+23.9e", "%+05.8e", "%-05.8e", "%05.8e", "%+5.8e", "%-5.8e", "% 5.8e", "%5.8e", "%+4.9e", #if !OS_LINUX /* glibc sometimes gets these wrong. */ "%+#010.0e", "%#10.1e", "%10.5e", "% 10.5e", "%5.0e", "%5.e", "%#5.0e", "%#5.e", "%3.2e", "%3.1e", "%-1.5e", "%1.5e", "%01.3e", "%1.e", "%.1e", "%#.0e", "%+.0e", "% .0e", "%.0e", "%#.e", "%+.e", "% .e", "%.e", "%4e", "%e", "%E", #endif /* !OS_LINUX */ /* "%F" and "%f" formats. */ #if !OS_BSD && !OS_IRIX "% '022f", "%+'022f", "%-'22f", "%'22f", #if HAVE_LONG_LONG_INT "%.16f", "%22.16f", "%022.16f", "%-22.16f", "%#+'022.16f", #endif /* HAVE_LONG_LONG_INT */ #endif /* !OS_BSD && !OS_IRIX */ "foo|%#+0123.9F|bar", "%-123.9f", "%123.9f", "%+23.9f", "%+#010.0f", "%#10.1f", "%10.5f", "% 10.5f", "%+05.8f", "%-05.8f", "%05.8f", "%+5.8f", "%-5.8f", "% 5.8f", "%5.8f", "%5.0f", "%5.f", "%#5.0f", "%#5.f", "%+4.9f", "%3.2f", "%3.1f", "%-1.5f", "%1.5f", "%01.3f", "%1.f", "%.1f", "%#.0f", "%+.0f", "% .0f", "%.0f", "%#.f", "%+.f", "% .f", "%.f", "%4f", "%f", "%F", /* "%G" and "%g" formats. */ #if !OS_BSD && !OS_IRIX && !OS_LINUX "% '022g", "%+'022g", "%-'22g", "%'22g", #if HAVE_LONG_LONG_INT "%.16g", "%22.16g", "%022.16g", "%-22.16g", "%#+'022.16g", #endif /* HAVE_LONG_LONG_INT */ #endif /* !OS_BSD && !OS_IRIX && !OS_LINUX */ "foo|%#+0123.9G|bar", "%-123.9g", "%123.9g", "%+23.9g", "%+05.8g", "%-05.8g", "%05.8g", "%+5.8g", "%-5.8g", "% 5.8g", "%5.8g", "%+4.9g", #if !OS_LINUX /* glibc sometimes gets these wrong. */ "%+#010.0g", "%#10.1g", "%10.5g", "% 10.5g", "%5.0g", "%5.g", "%#5.0g", "%#5.g", "%3.2g", "%3.1g", "%-1.5g", "%1.5g", "%01.3g", "%1.g", "%.1g", "%#.0g", "%+.0g", "% .0g", "%.0g", "%#.g", "%+.g", "% .g", "%.g", "%4g", "%g", "%G", #endif /* !OS_LINUX */ NULL }; double float_val[] = { -4.136, -134.52, -5.04030201, -3410.01234, -999999.999999, -913450.29876, -913450.2, -91345.2, -9134.2, -913.2, -91.2, -9.2, -9.9, 4.136, 134.52, 5.04030201, 3410.01234, 999999.999999, 913450.29876, 913450.2, 91345.2, 9134.2, 913.2, 91.2, 9.2, 9.9, 9.96, 9.996, 9.9996, 9.99996, 9.999996, 9.9999996, 9.99999996, 0.99999996, 0.99999999, 0.09999999, 0.00999999, 0.00099999, 0.00009999, 0.00000999, 0.00000099, 0.00000009, 0.00000001, 0.0000001, 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1.0, 1.5, -1.5, -1.0, -0.1, #if !OS_BSD /* BSD sometimes gets these wrong. */ #ifdef INFINITY INFINITY, -INFINITY, #endif /* defined(INFINITY) */ #ifdef NAN NAN, #endif /* defined(NAN) */ #endif /* !OS_BSD */ 0 }; const char *long_fmt[] = { "foo|%0123ld|bar", #if !OS_IRIX "% '0123ld", "%+'0123ld", "%-'123ld", "%'123ld", #endif /* !OS_IRiX */ "%123.9ld", "% 123.9ld", "%+123.9ld", "%-123.9ld", "%0123ld", "% 0123ld", "%+0123ld", "%-0123ld", "%10.5ld", "% 10.5ld", "%+10.5ld", "%-10.5ld", "%010ld", "% 010ld", "%+010ld", "%-010ld", "%4.2ld", "% 4.2ld", "%+4.2ld", "%-4.2ld", "%04ld", "% 04ld", "%+04ld", "%-04ld", "%5.5ld", "%+22.33ld", "%01.3ld", "%1.5ld", "%-1.5ld", "%44ld", "%4ld", "%4.0ld", "%4.ld", "%.44ld", "%.4ld", "%.0ld", "%.ld", "%ld", NULL }; long int long_val[] = { #ifdef LONG_MAX LONG_MAX, #endif /* LONG_MAX */ #ifdef LONG_MIN LONG_MIN, #endif /* LONG_MIN */ -91340, 91340, 341, 134, 0203, -1, 1, 0 }; const char *ulong_fmt[] = { /* "%u" formats. */ "foo|%0123lu|bar", #if !OS_IRIX "% '0123lu", "%+'0123lu", "%-'123lu", "%'123lu", #endif /* !OS_IRiX */ "%123.9lu", "% 123.9lu", "%+123.9lu", "%-123.9lu", "%0123lu", "% 0123lu", "%+0123lu", "%-0123lu", "%5.5lu", "%+22.33lu", "%01.3lu", "%1.5lu", "%-1.5lu", "%44lu", "%lu", /* "%o" formats. */ "foo|%#0123lo|bar", "%#123.9lo", "%# 123.9lo", "%#+123.9lo", "%#-123.9lo", "%#0123lo", "%# 0123lo", "%#+0123lo", "%#-0123lo", "%#5.5lo", "%#+22.33lo", "%#01.3lo", "%#1.5lo", "%#-1.5lo", "%#44lo", "%#lo", "%123.9lo", "% 123.9lo", "%+123.9lo", "%-123.9lo", "%0123lo", "% 0123lo", "%+0123lo", "%-0123lo", "%5.5lo", "%+22.33lo", "%01.3lo", "%1.5lo", "%-1.5lo", "%44lo", "%lo", /* "%X" and "%x" formats. */ "foo|%#0123lX|bar", "%#123.9lx", "%# 123.9lx", "%#+123.9lx", "%#-123.9lx", "%#0123lx", "%# 0123lx", "%#+0123lx", "%#-0123lx", "%#5.5lx", "%#+22.33lx", "%#01.3lx", "%#1.5lx", "%#-1.5lx", "%#44lx", "%#lx", "%#lX", "%123.9lx", "% 123.9lx", "%+123.9lx", "%-123.9lx", "%0123lx", "% 0123lx", "%+0123lx", "%-0123lx", "%5.5lx", "%+22.33lx", "%01.3lx", "%1.5lx", "%-1.5lx", "%44lx", "%lx", "%lX", NULL }; unsigned long int ulong_val[] = { #ifdef ULONG_MAX ULONG_MAX, #endif /* ULONG_MAX */ 91340, 341, 134, 0203, 1, 0 }; const char *llong_fmt[] = { "foo|%0123lld|bar", "%123.9lld", "% 123.9lld", "%+123.9lld", "%-123.9lld", "%0123lld", "% 0123lld", "%+0123lld", "%-0123lld", "%5.5lld", "%+22.33lld", "%01.3lld", "%1.5lld", "%-1.5lld", "%44lld", "%lld", NULL }; LLONG llong_val[] = { #ifdef LLONG_MAX LLONG_MAX, #endif /* LLONG_MAX */ #ifdef LLONG_MIN LLONG_MIN, #endif /* LLONG_MIN */ -91340, 91340, 341, 134, 0203, -1, 1, 0 }; const char *string_fmt[] = { "foo|%10.10s|bar", "%-10.10s", "%10.10s", "%10.5s", "%5.10s", "%10.1s", "%1.10s", "%10.0s", "%0.10s", "%-42.5s", "%2.s", "%.10s", "%.1s", "%.0s", "%.s", "%4s", "%s", NULL }; const char *string_val[] = { "Hello", "Hello, world!", "Sound check: One, two, three.", "This string is a little longer than the other strings.", "1", "", NULL }; #if !OS_SYSV /* SysV uses a different format than we do. */ const char *pointer_fmt[] = { "foo|%p|bar", "%42p", "%p", NULL }; const char *pointer_val[] = { *pointer_fmt, *string_fmt, *string_val, NULL }; #endif /* !OS_SYSV */ char buf1[1024], buf2[1024]; double value, digits = 9.123456789012345678901234567890123456789; int i, j, r1, r2, failed = 0, num = 0; /* * Use -DTEST_NILS in order to also test the conversion of nil values. Might * segfault on systems which don't support converting a NULL pointer with "%s" * and lets some test cases fail against BSD and glibc due to bugs in their * implementations. */ #ifndef TEST_NILS #define TEST_NILS 0 #elif TEST_NILS #undef TEST_NILS #define TEST_NILS 1 #endif /* !defined(TEST_NILS) */ #ifdef TEST #undef TEST #endif /* defined(TEST) */ #define TEST(fmt, val) \ do { \ for (i = 0; fmt[i] != NULL; i++) \ for (j = 0; j == 0 || val[j - TEST_NILS] != 0; j++) { \ r1 = sprintf(buf1, fmt[i], val[j]); \ r2 = snprintf(buf2, sizeof(buf2), fmt[i], val[j]); \ if (strcmp(buf1, buf2) != 0 || r1 != r2) { \ (void)printf("Results don't match, " \ "format string: %s\n" \ "\t sprintf(3): [%s] (%d)\n" \ "\tsnprintf(3): [%s] (%d)\n", \ fmt[i], buf1, r1, buf2, r2); \ failed++; \ } \ num++; \ } \ } while (/* CONSTCOND */ 0) #if HAVE_LOCALE_H (void)setlocale(LC_ALL, ""); #endif /* HAVE_LOCALE_H */ (void)puts("=== Testing our snprintf(3) against your system's sprintf(3). ===\n"); TEST(float_fmt, float_val); TEST(long_fmt, long_val); TEST(ulong_fmt, ulong_val); TEST(llong_fmt, llong_val); TEST(string_fmt, string_val); #if !OS_SYSV /* SysV uses a different format than we do. */ TEST(pointer_fmt, pointer_val); #endif /* !OS_SYSV */ (void)printf("Result: %d out of %d tests failed.\n", failed, num); (void)fputs("Checking how many digits we support: ", stdout); for (i = 0; i < 100; i++) { value = pow(10, i) * digits; (void)sprintf(buf1, "%.1f", value); (void)snprintf(buf2, sizeof(buf2), "%.1f", value); if (strcmp(buf1, buf2) != 0) { (void)printf("apparently %d.\n", i); break; } } return (failed == 0) ? 0 : 1; } #endif /* TEST_SNPRINTF */ /* vim: set joinspaces textwidth=80: */ cfengine-3.24.2/libntech/libcompat/rpl_ctime.c0000644000000000000000000000213515010704254021241 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of Cfengine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include char *cf_strtimestamp_local(const time_t time, char *buf); char *rpl_ctime(const time_t *timep) { static char buf[26]; return cf_strtimestamp_local(*timep, buf); } cfengine-3.24.2/libntech/libcompat/readlinkat.c0000644000000000000000000000320215010704254021375 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #ifndef __MINGW32__ typedef struct { const char *pathname; char *buf; size_t bufsize; } readlinkat_data; static int readlinkat_inner(void *generic_data) { readlinkat_data *data = generic_data; return readlink(data->pathname, data->buf, data->bufsize); } static void cleanup(ARG_UNUSED void *generic_data) { } int readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize) { readlinkat_data data; data.pathname = pathname; data.buf = buf; data.bufsize = bufsize; return generic_at_function(dirfd, &readlinkat_inner, &cleanup, &data); } #endif // !__MINGW32__ cfengine-3.24.2/libntech/libcompat/strlcat.c0000644000000000000000000000337515010704254020746 0ustar00rootroot00000000000000/* $OpenBSD: strlcat.c,v 1.12 2005/03/30 20:13:52 otto Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include size_t strlcat(char *dst, const char *src, size_t siz); /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). * Returns strlen(src) + MIN(siz, strlen(initial dst)). * If retval >= siz, truncation occurred. */ size_t strlcat(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } cfengine-3.24.2/libntech/libcompat/fchmodat.c0000644000000000000000000000333715010704254021055 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #ifndef __MINGW32__ typedef struct { const char *pathname; mode_t mode; int flags; } fchmodat_data; static int fchmodat_inner(void *generic_data) { fchmodat_data *data = generic_data; if (data->flags & AT_SYMLINK_NOFOLLOW) { errno = ENOTSUP; return -1; } return chmod(data->pathname, data->mode); } static void cleanup(ARG_UNUSED void *generic_data) { } int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags) { fchmodat_data data = { .pathname = pathname, .mode = mode, .flags = flags, }; return generic_at_function(dirfd, &fchmodat_inner, &cleanup, &data); } #endif // !__MINGW32__ cfengine-3.24.2/libntech/libcompat/gmtime_r.c0000644000000000000000000000260515010704254021070 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if !HAVE_DECL_GMTIME_R struct tm *gmtime_r(const time_t *timep, struct tm *result); #endif #if defined(__MINGW32__) /* On Windows, gmtime buffer is thread-specific, so using it in place of the reentrant version is safe */ struct tm *gmtime_r(const time_t *timep, struct tm *result) { struct tm *ret = gmtime(timep); if (ret) { memcpy(result, ret, sizeof(struct tm)); } return ret; } #endif cfengine-3.24.2/libntech/libcompat/openat.c0000644000000000000000000000360715010704254020556 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #ifndef __MINGW32__ typedef struct { const char *pathname; int flags; mode_t mode; int fd; } openat_data; static int openat_inner(void *generic_data) { openat_data *data = generic_data; data->fd = open(data->pathname, data->flags, data->mode); return data->fd; } static void cleanup(void *generic_data) { openat_data *data = generic_data; if (data->fd >= 0) { close(data->fd); } } int openat(int dirfd, const char *pathname, int flags, ...) { openat_data data; data.pathname = pathname; data.flags = flags; if (flags & O_CREAT) { va_list ap; va_start(ap, flags); data.mode = va_arg(ap, int); va_end(ap); } else { data.mode = 0; } data.fd = -1; return generic_at_function(dirfd, &openat_inner, &cleanup, &data); } #endif // !__MINGW32__ cfengine-3.24.2/libntech/libcompat/strsep.c0000644000000000000000000000502415010704254020603 0ustar00rootroot00000000000000/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if !HAVE_DECL_STRSEP char *strsep(char **stringp, const char *delim); #endif /* * Get next token from string *stringp, where tokens are possibly-empty * strings separated by characters from delim. * * Writes NULs into the string at *stringp to end tokens. * delim need not remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no more tokens). * * If *stringp is NULL, strsep returns NULL. */ char * strsep(char **stringp, const char *delim) { char *s; const char *spanp; int c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } cfengine-3.24.2/libntech/libcompat/strcasecmp.c0000644000000000000000000000277115010704254021435 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #if !HAVE_DECL_STRCASECMP int strcasecmp(const char *s1, const char *s2); #endif int strcasecmp(const char *s1, const char *s2) { for (;;) { if (*s1 == '\0' && *s2 == '\0') { break; } if (*s1 == '\0') { return -1; } if (*s2 == '\0') { return 1; } if (tolower(*s1) < tolower(*s2)) { return -1; } if (tolower(*s1) > tolower(*s2)) { return 1; } s1++; s2++; } return 0; } cfengine-3.24.2/libntech/libcompat/drand48.c0000644000000000000000000000221115010704254020522 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_DECL_DRAND48 double drand48(void); #endif /* Return a random value between in [0,1). */ double drand48(void) { return (double) rand() / ((double) (RAND_MAX) + 1.0); } cfengine-3.24.2/libntech/libcompat/strlcpy.c0000644000000000000000000000320215010704254020757 0ustar00rootroot00000000000000/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H # include #endif #include #include size_t strlcpy(char *dst, const char *src, size_t siz); /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcpy(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0) { while (--n != 0) { if ((*d++ = *s++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } cfengine-3.24.2/libntech/libcompat/generic_at.h0000644000000000000000000000200315010704254021362 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef __MINGW32__ int generic_at_function(int dirfd, int (*func)(void *data), void (*cleanup)(void *data), void *data); #endif cfengine-3.24.2/libntech/libcompat/getline.c0000644000000000000000000000724315010704254020717 0ustar00rootroot00000000000000/* Implementations of the getdelim() and getline() functions from POSIX 2008, just in case your libc doesn't have them. getdelim() reads from a stream until a specified delimiter is encountered. getline() reads from a stream until a newline is encountered. See: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getdelim.html NOTE: It is always the caller's responsibility to free the line buffer, even when an error occurs. Copyright (c) 2011 James E. Ingram Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #if !HAVE_DECL_GETLINE ssize_t getline(char **lineptr, size_t *n, FILE *stream); #endif #ifndef SSIZE_MAX #define SSIZE_MAX 32767 #endif #define _GETDELIM_GROWBY 4096 /* amount to grow line buffer by */ #define _GETDELIM_MINLEN 4 /* minimum line buffer size */ static ssize_t getdelim(char **restrict lineptr, size_t *restrict n, int delimiter, FILE *restrict stream) { char *buf, *pos; int c; ssize_t bytes; if (lineptr == NULL || n == NULL) { errno = EINVAL; return -1; } if (stream == NULL) { errno = EBADF; return -1; } /* resize (or allocate) the line buffer if necessary */ buf = *lineptr; if (buf == NULL || *n < _GETDELIM_MINLEN) { buf = realloc(*lineptr, _GETDELIM_GROWBY); if (buf == NULL) { /* ENOMEM */ return -1; } *n = _GETDELIM_GROWBY; *lineptr = buf; } /* read characters until delimiter is found, end of file is reached, or an error occurs. */ bytes = 0; pos = buf; while ((c = getc(stream)) != EOF) { if (bytes + 1 >= SSIZE_MAX) { errno = ERANGE; return -1; } bytes++; if (bytes >= *n - 1) { buf = realloc(*lineptr, *n + _GETDELIM_GROWBY); if (buf == NULL) { /* ENOMEM */ return -1; } *n += _GETDELIM_GROWBY; pos = buf + bytes - 1; *lineptr = buf; } *pos++ = (char) c; if (c == delimiter) { break; } } if (ferror(stream) || (feof(stream) && (bytes == 0))) { /* EOF, or an error from getc(). */ return -1; } *pos = '\0'; return bytes; } ssize_t getline(char **restrict lineptr, size_t *restrict n, FILE *restrict stream) { return getdelim(lineptr, n, '\n', stream); } cfengine-3.24.2/libntech/libcompat/generic_at.c0000644000000000000000000001052715010704254021367 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #ifndef __MINGW32__ /* * Implements a generic interface to implement the POSIX-2008 *at * functions (openat, fstatat, fchownat, etc.). */ /* * This function uses fchdir() to preserve integrity when querying * a file from a directory descriptor. It's ugly but it's the only way * to be secure. * Using fchdir() in *at functions means that we can potentially * conflict with chdir()/fchdir() being used elsewhere. For this to be * safe, the program must fulfill at least one of the following * criteria: * 1. Be single threaded. * 2. Not use chdir() anywhere else but here. * 3. Do all file operations (including chdir) in one thread. * 4. Use the CHDIR_LOCK in this file. * Currently, cf-agent fulfills criterion 1. All the others fulfill * criterion 2. */ // To prevent several threads from stepping on each other's toes // when using fchdir(). static pthread_mutex_t CHDIR_LOCK = PTHREAD_MUTEX_INITIALIZER; /** * Generic *at function. * @param dirfd File descriptor pointing to directory to do lookup in. * AT_FDCWD constant means to look in current directory. * @param func Function to call while in the directory. * @param cleanup Function to call if we need to clean up because of a failed call. * @param data Private data for the supplied functions. */ int generic_at_function(int dirfd, int (*func)(void *data), void (*cleanup)(void *data), void *data) { int cwd; int mutex_err; int saved_errno; mutex_err = pthread_mutex_lock(&CHDIR_LOCK); if (mutex_err) { UnexpectedError("Error when locking CHDIR_LOCK. Should never happen. (pthread_mutex_lock: '%s')", GetErrorStrFromCode(mutex_err)); } if (dirfd != AT_FDCWD) { cwd = open(".", O_RDONLY); if (cwd < 0) { mutex_err = pthread_mutex_unlock(&CHDIR_LOCK); if (mutex_err) { UnexpectedError("Error when unlocking CHDIR_LOCK. Should never happen. (pthread_mutex_unlock: '%s')", GetErrorStrFromCode(mutex_err)); } return -1; } if (fchdir(dirfd) < 0) { close(cwd); mutex_err = pthread_mutex_unlock(&CHDIR_LOCK); if (mutex_err) { UnexpectedError("Error when unlocking CHDIR_LOCK. Should never happen. (pthread_mutex_unlock: '%s')", GetErrorStrFromCode(mutex_err)); } return -1; } } int result = func(data); saved_errno = errno; int fchdir_ret = -1; // initialize to error to catch code paths that don't set but test if (dirfd != AT_FDCWD) { fchdir_ret = fchdir(cwd); close(cwd); } mutex_err = pthread_mutex_unlock(&CHDIR_LOCK); if (mutex_err) { UnexpectedError("Error when unlocking CHDIR_LOCK. Should never happen. (pthread_mutex_unlock: '%s')", GetErrorStrFromCode(mutex_err)); } if (dirfd != AT_FDCWD) { if (fchdir_ret < 0) { cleanup(data); Log(LOG_LEVEL_WARNING, "Could not return to original working directory in '%s'. " "Things may not behave as expected. (fchdir: '%s')", __FUNCTION__, GetErrorStr()); return -1; } } errno = saved_errno; return result; } #endif // !__MINGW32__ cfengine-3.24.2/libntech/libcompat/strncasecmp.c0000644000000000000000000000301415010704254021602 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #if !HAVE_DECL_STRCASECMP int strncasecmp(const char *s1, const char *s2); #endif int strncasecmp(const char *s1, const char *s2, size_t n) { while (n-- > 0) { if (*s1 == '\0' && *s2 == '\0') { break; } if (*s1 == '\0') { return -1; } if (*s2 == '\0') { return 1; } if (tolower(*s1) < tolower(*s2)) { return -1; } if (tolower(*s1) > tolower(*s2)) { return 1; } s1++; s2++; } return 0; } cfengine-3.24.2/libntech/libcompat/getaddrinfo.c0000644000000000000000000002503315010704254021553 0ustar00rootroot00000000000000/* PostgreSQL Database Management System (formerly known as Postgres, then as Postgres95) Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of California Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ /*------------------------------------------------------------------------- * * getaddrinfo.c * Support getaddrinfo() on platforms that don't have it. * * We also supply getnameinfo() here, assuming that the platform will have * it if and only if it has getaddrinfo(). If this proves false on some * platform, we'll need to split this file and provide a separate configure * test for getnameinfo(). * * Copyright (c) 2003-2007, PostgreSQL Global Development Group * * Copyright (C) 2007 Jeremy Allison. * Modified to return multiple IPv4 addresses for Samba. * *------------------------------------------------------------------------- */ #include #ifndef SMB_MALLOC #define SMB_MALLOC(s) malloc(s) #endif #ifndef SMB_STRDUP #define SMB_STRDUP(s) strdup(s) #endif #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 255 #endif static int check_hostent_err(struct hostent *hp) { #ifndef INET6 extern int h_errno; #endif if (!hp) { switch (h_errno) { case HOST_NOT_FOUND: case NO_DATA: return EAI_NONAME; case TRY_AGAIN: return EAI_AGAIN; case NO_RECOVERY: default: return EAI_FAIL; } } if (!hp->h_name || hp->h_addrtype != AF_INET) { return EAI_FAIL; } return 0; } static char *canon_name_from_hostent(struct hostent *hp, int *perr) { char *ret = NULL; *perr = check_hostent_err(hp); if (*perr) { return NULL; } ret = SMB_STRDUP(hp->h_name); if (!ret) { *perr = EAI_MEMORY; } return ret; } static char *get_my_canon_name(int *perr) { char name[HOST_NAME_MAX+1]; if (gethostname(name, HOST_NAME_MAX) == -1) { *perr = EAI_FAIL; return NULL; } /* Ensure null termination. */ name[HOST_NAME_MAX] = '\0'; return canon_name_from_hostent(gethostbyname(name), perr); } static char *get_canon_name_from_addr(struct in_addr ip, int *perr) { return canon_name_from_hostent( gethostbyaddr((void *)&ip, sizeof ip, AF_INET), perr); } static struct addrinfo *alloc_entry(const struct addrinfo *hints, struct in_addr ip, unsigned short port) { struct sockaddr_in *psin = NULL; struct addrinfo *ai = SMB_MALLOC(sizeof(*ai)); if (!ai) { return NULL; } memset(ai, '\0', sizeof(*ai)); psin = SMB_MALLOC(sizeof(*psin)); if (!psin) { free(ai); return NULL; } memset(psin, '\0', sizeof(*psin)); psin->sin_family = AF_INET; psin->sin_port = htons(port); psin->sin_addr = ip; ai->ai_flags = 0; ai->ai_family = AF_INET; ai->ai_socktype = hints->ai_socktype; ai->ai_protocol = hints->ai_protocol; ai->ai_addrlen = sizeof(*psin); ai->ai_addr = (struct sockaddr *) psin; ai->ai_canonname = NULL; ai->ai_next = NULL; return ai; } /* * get address info for a single ipv4 address. * * Bugs: - servname can only be a number, not text. */ static int getaddr_info_single_addr(const char *service, uint32_t addr, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo *ai = NULL; struct in_addr ip; unsigned short port = 0; if (service) { port = (unsigned short)atoi(service); } ip.s_addr = htonl(addr); ai = alloc_entry(hints, ip, port); if (!ai) { return EAI_MEMORY; } /* If we're asked for the canonical name, * make sure it returns correctly. */ if (!(hints->ai_flags & AI_NUMERICSERV) && hints->ai_flags & AI_CANONNAME) { int err; if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) { ai->ai_canonname = get_my_canon_name(&err); } else { ai->ai_canonname = get_canon_name_from_addr(ip,&err); } if (ai->ai_canonname == NULL) { freeaddrinfo(ai); return err; } } *res = ai; return 0; } /* * get address info for multiple ipv4 addresses. * * Bugs: - servname can only be a number, not text. */ static int getaddr_info_name(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct addrinfo *listp = NULL, *prevp = NULL; char **pptr = NULL; int err; struct hostent *hp = NULL; unsigned short port = 0; if (service) { port = (unsigned short)atoi(service); } hp = gethostbyname(node); err = check_hostent_err(hp); if (err) { return err; } for(pptr = hp->h_addr_list; *pptr; pptr++) { struct in_addr ip = *(struct in_addr *)*pptr; struct addrinfo *ai = alloc_entry(hints, ip, port); if (!ai) { freeaddrinfo(listp); return EAI_MEMORY; } if (!listp) { listp = ai; prevp = ai; ai->ai_canonname = SMB_STRDUP(hp->h_name); if (!ai->ai_canonname) { freeaddrinfo(listp); return EAI_MEMORY; } } else { prevp->ai_next = ai; prevp = ai; } } *res = listp; return 0; } /* * get address info for ipv4 sockets. * * Bugs: - servname can only be a number, not text. */ int getaddrinfo(const char *node, const char *service, const struct addrinfo * hintp, struct addrinfo ** res) { struct addrinfo hints; /* Setup the hints struct. */ if (hintp == NULL) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; } else { memcpy(&hints, hintp, sizeof(hints)); } if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) { return EAI_FAMILY; } if (hints.ai_socktype == 0) { hints.ai_socktype = SOCK_STREAM; } if (!node && !service) { return EAI_NONAME; } if (node) { if (node[0] == '\0') { return getaddr_info_single_addr(service, INADDR_ANY, &hints, res); } else if (hints.ai_flags & AI_NUMERICHOST) { struct in_addr ip; if (inet_pton(AF_INET, node, &ip) <= 0) return EAI_FAIL; return getaddr_info_single_addr(service, ntohl(ip.s_addr), &hints, res); } else { return getaddr_info_name(node, service, &hints, res); } } else if (hints.ai_flags & AI_PASSIVE) { return getaddr_info_single_addr(service, INADDR_ANY, &hints, res); } return getaddr_info_single_addr(service, INADDR_LOOPBACK, &hints, res); } void freeaddrinfo(struct addrinfo *res) { struct addrinfo *next = NULL; for (;res; res = next) { next = res->ai_next; if (res->ai_canonname) { free(res->ai_canonname); } if (res->ai_addr) { free(res->ai_addr); } free(res); } } const char *gai_strerror(int errcode) { #ifdef HAVE_HSTRERROR int hcode; switch (errcode) { case EAI_NONAME: hcode = HOST_NOT_FOUND; break; case EAI_AGAIN: hcode = TRY_AGAIN; break; case EAI_FAIL: default: hcode = NO_RECOVERY; break; } return hstrerror(hcode); #else /* !HAVE_HSTRERROR */ switch (errcode) { case EAI_NONAME: return "Unknown host"; case EAI_AGAIN: return "Host name lookup failure"; #ifdef EAI_BADFLAGS case EAI_BADFLAGS: return "Invalid argument"; #endif #ifdef EAI_FAMILY case EAI_FAMILY: return "Address family not supported"; #endif #ifdef EAI_MEMORY case EAI_MEMORY: return "Not enough memory"; #endif #ifdef EAI_NODATA case EAI_NODATA: return "No host data of that type was found"; #endif #ifdef EAI_SERVICE case EAI_SERVICE: return "Class type not found"; #endif #ifdef EAI_SOCKTYPE case EAI_SOCKTYPE: return "Socket type not supported"; #endif default: return "Unknown server error"; } #endif /* HAVE_HSTRERROR */ } static int gethostnameinfo(const struct sockaddr *sa, char *node, size_t nodelen, int flags) { int ret = -1; char *p = NULL; if (!(flags & NI_NUMERICHOST)) { struct hostent *hp = gethostbyaddr( (void *)&((struct sockaddr_in *)sa)->sin_addr, sizeof (struct in_addr), sa->sa_family); ret = check_hostent_err(hp); if (ret == 0) { /* Name looked up successfully. */ ret = snprintf(node, nodelen, "%s", hp->h_name); if (ret < 0 || (size_t)ret >= nodelen) { return EAI_MEMORY; } if (flags & NI_NOFQDN) { p = strchr(node,'.'); if (p) { *p = '\0'; } } return 0; } if (flags & NI_NAMEREQD) { /* If we require a name and didn't get one, * automatically fail. */ return ret; } /* Otherwise just fall into the numeric host code... */ } p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); ret = snprintf(node, nodelen, "%s", p); if (ret < 0 || (size_t)ret >= nodelen) { return EAI_MEMORY; } return 0; } static int getservicenameinfo(const struct sockaddr *sa, char *service, size_t servicelen, int flags) { int ret = -1; int port = ntohs(((struct sockaddr_in *)sa)->sin_port); if (!(flags & NI_NUMERICSERV)) { struct servent *se = getservbyport( port, (flags & NI_DGRAM) ? "udp" : "tcp"); if (se && se->s_name) { /* Service name looked up successfully. */ ret = snprintf(service, servicelen, "%s", se->s_name); if (ret < 0 || (size_t)ret >= servicelen) { return EAI_MEMORY; } return 0; } /* Otherwise just fall into the numeric service code... */ } ret = snprintf(service, servicelen, "%d", port); if (ret < 0 || (size_t)ret >= servicelen) { return EAI_MEMORY; } return 0; } /* * Convert an ipv4 address to a hostname. * * Bugs: - No IPv6 support. */ int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags) { /* Invalid arguments. */ if (sa == NULL || (node == NULL && service == NULL)) { return EAI_FAIL; } if (sa->sa_family != AF_INET) { return EAI_FAIL; } if (salen < (socklen_t)sizeof (struct sockaddr_in)) { return EAI_FAIL; } if (node) { int ret = gethostnameinfo(sa, node, nodelen, flags); if (ret) return ret; } if (service) { return getservicenameinfo(sa, service, servicelen, flags); } return 0; } cfengine-3.24.2/libntech/libcompat/Makefile.in0000644000000000000000000006051115010704273021167 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = libcompat ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/tar.m4 \ $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcompat_la_DEPENDENCIES = $(LTLIBOBJS) am_libcompat_la_OBJECTS = generic_at.lo libcompat_la_OBJECTS = $(am_libcompat_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcompat_la_SOURCES) DIST_SOURCES = $(libcompat_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ clock_gettime.c closefrom.c dirfd.c drand48.c fchmodat.c \ fchownat.c fstatat.c getaddrinfo.c getline.c gmtime_r.c \ inet_ntop.c inet_pton.c localtime_r.c log2.c memdup.c memmem.c \ memrchr.c mkdtemp.c nanosleep.c openat.c \ pthread_attr_setstacksize.c pthread_sigmask.c readlinkat.c \ round.c rpl_ctime.c seteuid.c setlinebuf.c snprintf.c \ srand48.c stpncpy.c strcasecmp.c strcasestr.c strchrnul.c \ strdup.c strerror.c strlcat.c strlcpy.c strncasecmp.c \ strndup.c strnlen.c strrstr.c strsep.c strsignal.c strstr.c \ unsetenv.c DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GREP = @GREP@ HAVE_CLOCKID_T_DEFINE = @HAVE_CLOCKID_T_DEFINE@ HAVE_GETOPT_H_DEFINE = @HAVE_GETOPT_H_DEFINE@ HAVE_LIBYAML_DEFINE = @HAVE_LIBYAML_DEFINE@ HOSTNAME = @HOSTNAME@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ NO_TAUTOLOGICAL_CC_OPTION = @NO_TAUTOLOGICAL_CC_OPTION@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_LOGGING_CFLAGS = @SYSTEMD_LOGGING_CFLAGS@ SYSTEMD_LOGGING_CPPFLAGS = @SYSTEMD_LOGGING_CPPFLAGS@ SYSTEMD_LOGGING_LDFLAGS = @SYSTEMD_LOGGING_LDFLAGS@ SYSTEMD_LOGGING_LIBS = @SYSTEMD_LOGGING_LIBS@ SYSTEMD_LOGGING_PATH = @SYSTEMD_LOGGING_PATH@ VERSION = @VERSION@ WITH_PCRE2_DEFINE = @WITH_PCRE2_DEFINE@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcompat.la AM_CPPFLAGS = -I$(top_srcdir)/libutils # platform.h libcompat_la_LIBADD = $(LTLIBOBJS) libcompat_la_SOURCES = \ generic_at.c generic_at.h CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libcompat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libcompat/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcompat.la: $(libcompat_la_OBJECTS) $(libcompat_la_DEPENDENCIES) $(EXTRA_libcompat_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcompat_la_OBJECTS) $(libcompat_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/clock_gettime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/closefrom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dirfd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/drand48.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fchmodat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fchownat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fstatat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getaddrinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gmtime_r.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/inet_ntop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/inet_pton.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/localtime_r.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/log2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memdup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memmem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memrchr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mkdtemp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/nanosleep.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/openat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pthread_attr_setstacksize.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pthread_sigmask.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/readlinkat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/round.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/rpl_ctime.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/seteuid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/setlinebuf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/snprintf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/srand48.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/stpncpy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strcasecmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strcasestr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strchrnul.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strdup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strlcat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strlcpy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strncasecmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strndup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strnlen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strrstr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strsep.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strsignal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strstr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/unsetenv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generic_at.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libntech/libcompat/clock_gettime.c0000644000000000000000000000211415010704254022071 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include int clock_gettime(ARG_UNUSED clockid_t clock_id, struct timespec *tp) { tp->tv_sec = time(NULL); tp->tv_nsec = 0; return 0; } cfengine-3.24.2/libntech/libcompat/dirfd.c0000644000000000000000000000254015010704254020353 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef HAVE_DIRENT_H # include #endif #if !HAVE_DECL_DIRFD int dirfd(DIR *dirp); #endif /* Under Solaris, HP-UX and AIX dirfd(3) is just looking inside DIR structure */ #if defined(__sun) int dirfd(DIR *dirp) { return dirp->d_fd != -1 ? dirp->d_fd : ENOTSUP; } #elif defined(__hpux) || defined(_AIX) int dirfd(DIR *dirp) { return dirp->dd_fd != -1 ? dirp->dd_fd : ENOTSUP; } #endif cfengine-3.24.2/libntech/libcompat/log2.c0000644000000000000000000000171315010704254020127 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include double log2(double x) { return log(x) / log(2); } cfengine-3.24.2/libntech/libcompat/round.c0000644000000000000000000000260715010704254020416 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_DECL_ROUND double round(double x); #endif double round(double x) { if (x >= 0.0) { double y = floor(x); if (x - y >= 0.5) { return y + 1.0; } else { return y; } } else { double y = ceil(x); if (y - x >= 0.5) { return y - 1.0; } else { return y; } } } cfengine-3.24.2/libntech/libcompat/memdup.c0000644000000000000000000000232215010704254020550 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #if !HAVE_DECL_MEMDUP void *memdup(const void *data, size_t size); #endif void *memdup(const void *data, size_t size) { void *m = malloc(size); if (m == NULL) { return NULL; } memcpy(m, data, size); return m; } cfengine-3.24.2/libntech/libcompat/stpncpy.c0000644000000000000000000000356615010704254020774 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #if !HAVE_DECL_STPNCPY char *stpncpy(char *dst, const char *src, size_t len); #endif // Copy at most len bytes, including NUL terminating byte // if src is too long, don't add terminating NUL byte // if src is shorter than len, fill remainder with NUL bytes // return pointer to terminator in dst // if no terminator, return dst + len (address after last byte written) // // This is not the fastest way to implement stpncpy, and it is only // used where it is missing (mingw/windows) char *stpncpy(char *dst, const char *src, size_t len) { assert(dst != NULL); assert(src != NULL); assert(dst != src); for (int i = 0; i < len; ++i) { const char copy_byte = src[i]; dst[i] = copy_byte; if (copy_byte == '\0') { // Zero fill and return: for (int j = i+1; j < len; ++j) { dst[j] = '\0'; } return dst + i; } } return dst + len; } cfengine-3.24.2/libntech/libcompat/inet_pton.c0000644000000000000000000001214115010704254021260 0ustar00rootroot00000000000000/* * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #if defined(_WIN32) && !defined(EAFNOSUPPORT) #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif #define NS_INT16SZ 2 #define NS_INADDRSZ 4 #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4(const char *src, unsigned char *dst); #ifdef INET6 static int inet_pton6(const char *src, unsigned char *dst); #endif /* int * inet_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * author: * Paul Vixie, 1996. */ int inet_pton(int af, const char *src, void *dst) { switch (af) { case AF_INET: return (inet_pton4(src, dst)); #ifdef INET6 case AF_INET6: return (inet_pton6(src, dst)); #endif default: errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ } /* int * inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int inet_pton4(src, dst) const char *src; unsigned char *dst; { static const char digits[] = "0123456789"; int saw_digit, octets, ch; unsigned char tmp[NS_INADDRSZ] = {0}; unsigned char *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr(digits, ch)) != NULL) { unsigned int new = *tp * 10 + (pch - digits); if (new > 255) return (0); *tp = new; if (! saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); *++tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); memcpy(dst, tmp, NS_INADDRSZ); return (1); } /* int * inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: * (1) does not touch `dst' unless it's returning 1. * (2) :: in a full address is silently ignored. * credit: * inspired by Mark Andrews. * author: * Paul Vixie, 1996. */ #ifdef INET6 static int inet_pton6(src, dst) const char *src; unsigned char *dst; { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; unsigned int val; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; saw_xdigit = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (val > 0xffff) return (0); saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) return (0); colonp = tp; continue; } if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; saw_xdigit = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += NS_INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (saw_xdigit) { if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char) (val >> 8) & 0xff; *tp++ = (unsigned char) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } #endif cfengine-3.24.2/libntech/libcompat/strrstr.c0000644000000000000000000000375715010704254021021 0ustar00rootroot00000000000000/* Part of publib. Copyright (c) 1994-2006 Lars Wirzenius. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * strrstr.c -- find last occurrence of string in another string * * Part of publib. See man page for more information. * "@(#)publib-strutil:$Id: strrstr.c,v 1.1.1.1 1994/02/03 17:25:29 liw Exp $" */ #include #include #if !HAVE_DECL_STRRSTR char *strrstr(const char *haystack, const char *needle); #endif char *strrstr(const char *str, const char *pat) { size_t len, patlen; const char *p; assert(str != NULL); assert(pat != NULL); len = strlen(str); patlen = strlen(pat); if (patlen > len) return NULL; for (p = str + (len - patlen); p > str; --p) if (*p == *pat && strncmp(p, pat, patlen) == 0) return (char *) p; return NULL; } cfengine-3.24.2/libntech/libcompat/strsignal.c0000644000000000000000000000236115010704254021272 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_SNPRINTF int rpl_snprintf(char *, size_t, const char *, ...); #endif #if !HAVE_DECL_STRSIGNAL char *strsignal(int sig); #endif #include static char SIGNAL_TEXT[16]; char *strsignal(int sig) { snprintf(SIGNAL_TEXT, 16, "Signal #%d", sig); return SIGNAL_TEXT; } cfengine-3.24.2/libntech/libcompat/strerror.c0000644000000000000000000000220115010704254021137 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_DECL_STRERROR char *strerror(int err); #endif char *strerror(int err) { static char buffer[20]; snprintf(buffer, 20, "Error number %d\n", err); return buffer; } cfengine-3.24.2/libntech/libcompat/strchrnul.c0000644000000000000000000000060515010704254021307 0ustar00rootroot00000000000000#ifdef HAVE_CONFIG_H # include #endif #include /* strlen,strchr */ #include /* size_t */ char *strchrnul(const char *s, int c) { char *p = strchr(s, c); if (p == NULL) { return (char *)(s + strlen(s)); } else { return p; } } cfengine-3.24.2/libntech/libcompat/mkdtemp.c0000644000000000000000000000275015010704254020727 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #define MAXTRY 999999 char *mkdtemp(char *template) { char *xxx = strrstr(template, "XXXXXX"); if (xxx == NULL || strcmp(xxx, "XXXXXX") != 0) { errno = EINVAL; return NULL; } for (int i = 0; i <= MAXTRY; ++i) { snprintf(xxx, 7, "%06d", i); int fd = mkdir(template, S_IRUSR | S_IWUSR | S_IXUSR); if (fd >= 0) { close(fd); return template; } if (errno != EEXIST) { return NULL; } } errno = EEXIST; return NULL; } cfengine-3.24.2/libntech/libcompat/seteuid.c0000644000000000000000000000205515010704254020726 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include int seteuid(uid_t uid) { # ifdef HAVE_SETREUID return setreuid(-1, uid); # else return -1; # endif } cfengine-3.24.2/libntech/libcompat/pthread_attr_setstacksize.c0000644000000000000000000000223315010704254024537 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_DECL_PTHREAD_ATTR_SETSTACKSIZE int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); # endif int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) { return 0; } cfengine-3.24.2/libntech/libcompat/inet_ntop.c0000644000000000000000000001164015010704254021263 0ustar00rootroot00000000000000/* * Copyright (C) 1996-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #if defined(_WIN32) && !defined(EAFNOSUPPORT) #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif #define NS_INT16SZ 2 #define NS_IN6ADDRSZ 16 /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size); #ifdef AF_INET6 static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); #endif /* char * * isc_net_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * author: * Paul Vixie, 1996. */ const char * inet_ntop(int af, const void *src, char *dst, socklen_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); #ifdef AF_INET6 case AF_INET6: return (inet_ntop6(src, dst, size)); #endif default: errno = EAFNOSUPPORT; return (NULL); } /* NOTREACHED */ } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a unsigned char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const unsigned char *src, char *dst, size_t size) { static const char *fmt = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; size_t len; len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); if (len >= size) { errno = ENOSPC; return (NULL); } memcpy(dst, tmp, len + 1); return (dst); } /* const char * * isc_inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ #ifdef AF_INET6 static const char * inet_ntop6(const unsigned char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; struct { int base, len; } best, cur; unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i, inc; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) return (NULL); tp += strlen(tp); break; } inc = snprintf(tp, 5, "%x", words[i]); assert(inc < 5); tp += inc; } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } memcpy(dst, tmp, tp - tmp); return (dst); } #endif /* AF_INET6 */ cfengine-3.24.2/libntech/libcompat/setlinebuf.c0000644000000000000000000000262115010704254021423 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #if !HAVE_DECL_SETLINEBUF void setlinebuf(FILE *stream); #endif #ifdef _WIN32 /* Line buffered mode doesn't work on Windows, as documented here: https://msdn.microsoft.com/en-us/library/86cebhfs.aspx (setvbuf) It will fall back to block buffering, so in that case it is better to select no buffering. */ # define IO_MODE _IONBF #else # define IO_MODE _IOLBF #endif void setlinebuf(FILE *stream) { setvbuf(stream, (char *) NULL, IO_MODE, 0); } cfengine-3.24.2/libntech/libcompat/fstatat.c0000644000000000000000000000333615010704254020735 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #ifndef __MINGW32__ typedef struct { const char *pathname; struct stat *buf; int flags; } fstatat_data; static int fstatat_inner(void *generic_data) { fstatat_data *data = generic_data; if (data->flags & AT_SYMLINK_NOFOLLOW) { return lstat(data->pathname, data->buf); } else { return stat(data->pathname, data->buf); } } static void cleanup(ARG_UNUSED void *generic_data) { } int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags) { fstatat_data data; data.pathname = pathname; data.buf = buf; data.flags = flags; return generic_at_function(dirfd, &fstatat_inner, &cleanup, &data); } #endif // !__MINGW32__ cfengine-3.24.2/libntech/libcompat/unsetenv.c0000644000000000000000000000451515010704254021136 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #if !HAVE_DECL_UNSETENV int unsetenv(const char *name); #endif /* Under MinGW putenv('var=') will remove variable from environment */ #ifdef __MINGW32__ int unsetenv(const char *name) { int retval; char *buf; if (name == NULL || *name == 0 || strchr(name, '=') != 0) { errno = EINVAL; return -1; } buf = malloc(strlen(name) + 2); if (!buf) { errno = ENOMEM; return -1; } sprintf(buf, "%s=", name); retval = putenv(buf); free(buf); return retval; } #endif /* * Under SVR4 (Solaris 8/9, HP-UX 11.11) we need to manually update 'environ' * variable */ #if defined(__sun) || defined (__hpux) /* * Note: this function will leak memory as we don't know how to free data * previously used by environment variables. */ extern char **environ; int unsetenv(const char *name) { char **c; int len; if (name == NULL || *name == 0 || strchr(name, '=') != 0) { errno = EINVAL; return -1; } len = strlen(name); /* Find variable */ for (c = environ; *c; ++c) { if (strncmp(name, *c, len) == 0 && ((*c)[len] == '=' || (*c)[len] == 0)) { break; } } /* Shift remaining values */ for (; *c; ++c) { *c = *(c + 1); } return 0; } #endif cfengine-3.24.2/libntech/libcompat/nanosleep.c0000644000000000000000000000246515010704254021255 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * NB! Does not calculate "remaining time" */ #ifdef HAVE_CONFIG_H # include #endif #ifdef __MINGW32__ # include # include int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { if (rmtp) { rmtp->tv_sec = 0; rmtp->tv_nsec = 0; } DWORD timeout = rqtp->tv_sec * 1000L + (rqtp->tv_nsec + 999999) / 1000000; Sleep(timeout); return 0; } #endif cfengine-3.24.2/libenv/0000755000000000000000000000000015010704322014627 5ustar00rootroot00000000000000cfengine-3.24.2/libenv/Makefile.am0000644000000000000000000000372715010704253016677 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libenv.la libenv_la_SOURCES = \ constants.c constants.h \ sysinfo.c sysinfo.h sysinfo_priv.h \ time_classes.c time_classes.h \ zones.c zones.h if !NT libenv_la_SOURCES += \ unix_iface.c endif if SOLARIS libenv_la_LIBADD = -lkstat endif AM_CPPFLAGS = -I$(top_srcdir)/libntech/libutils AM_CPPFLAGS += $(OPENSSL_CPPFLAGS) # because libutils needs it AM_CPPFLAGS += $(PCRE2_CPPFLAGS) # Those dependencies are ought to go away ASAP AM_CPPFLAGS += -I$(top_srcdir)/libcfnet AM_CPPFLAGS += -I$(top_srcdir)/libpromises CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = config.h.in # libcompat dependency .PRECIOUS: ../libntech/libcompat/libcompat.la ../libntech/libcompat/libcompat.la: $(MAKE) -C ../libntech/libcompat $(AM_MAKEFLAGS) libcompat.la cfengine-3.24.2/libenv/zones.h0000644000000000000000000000234115010704253016141 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ZONES_H #define CFENGINE_ZONES_H #include #ifndef __MINGW32__ bool IsGlobalZone(); bool ForeignZone(char *s); int CurrentZoneName(char *s);/* s must point to at least ZONENAME_MAX bytes of space */ #endif #endif // ZONES_H cfengine-3.24.2/libenv/sysinfo_priv.h0000644000000000000000000000225415010704253017540 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SYSINFO_PRIV_H #define CFENGINE_SYSINFO_PRIV_H #include void DiscoverVersion(EvalContext *ctx); void DetectDomainName(EvalContext *ctx, const char *orig_nodename); #endif cfengine-3.24.2/libenv/unix_iface.c0000644000000000000000000015605615010704253017125 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include /* SeqStringFromString */ #include /* StringMatchFull */ #include /* StringCaptureData() */ #include #include #include #include #include #include #ifdef HAVE_SYS_JAIL_H # include #endif #ifdef HAVE_GETIFADDRS # include # ifdef HAVE_NET_IF_DL_H # include # endif #endif #ifdef HAVE_NET_IF_ARP_H # include #endif #define CF_IFREQ 2048 /* Reportedly the largest size that does not segfault 32/64 bit */ #define CF_IGNORE_INTERFACES "ignore_interfaces.rx" #define IPV6_PREFIX "ipv6_" #ifndef __MINGW32__ # if defined(HAVE_STRUCT_SOCKADDR_SA_LEN) && !defined(__NetBSD__) # ifdef _SIZEOF_ADDR_IFREQ # define SIZEOF_IFREQ(x) _SIZEOF_ADDR_IFREQ(x) # else # define SIZEOF_IFREQ(x) \ ((x).ifr_addr.sa_len > sizeof(struct sockaddr) ? \ (sizeof(struct ifreq) - sizeof(struct sockaddr) + \ (x).ifr_addr.sa_len) : sizeof(struct ifreq)) # endif # else # define SIZEOF_IFREQ(x) sizeof(struct ifreq) # endif #ifdef _AIX #include #include static int aix_get_mac_addr(const char *device_name, uint8_t mac[6]); #endif static void FindV6InterfacesInfo(EvalContext *ctx, Rlist **interfaces, Rlist **hardware, Rlist **ips); static bool IgnoreJailInterface(int ifaceidx, struct sockaddr_in *inaddr); static bool IgnoreInterface(char *name); static void InitIgnoreInterfaces(void); static Rlist *IGNORE_INTERFACES = NULL; /* GLOBAL_E */ typedef void (*ProcPostProcessFn)(void *ctx, void *json); typedef JsonElement * (*ProcTiebreakerFn)(JsonElement *prev_item, JsonElement *this_item); /*********************************************************************/ /******************************************************************/ static bool IgnoreJailInterface( #if !defined(HAVE_JAIL_GET) ARG_UNUSED int ifaceidx, ARG_UNUSED struct sockaddr_in *inaddr #else int ifaceidx, struct sockaddr_in *inaddr #endif ) { /* FreeBSD jails */ # ifdef HAVE_JAIL_GET struct iovec fbsd_jparams[4]; struct in_addr fbsd_jia; int fbsd_lastjid = 0; *(const void **) &fbsd_jparams[0].iov_base = "lastjid"; fbsd_jparams[0].iov_len = sizeof("lastjid"); fbsd_jparams[1].iov_base = &fbsd_lastjid; fbsd_jparams[1].iov_len = sizeof(fbsd_lastjid); *(const void **) &fbsd_jparams[2].iov_base = "ip4.addr"; fbsd_jparams[2].iov_len = sizeof("ip4.addr"); fbsd_jparams[3].iov_len = sizeof(struct in_addr); fbsd_jparams[3].iov_base = &fbsd_jia; while ((fbsd_lastjid = jail_get(fbsd_jparams, 4, 0)) > 0) { if (fbsd_jia.s_addr == inaddr->sin_addr.s_addr) { Log(LOG_LEVEL_VERBOSE, "Interface %d belongs to a FreeBSD jail %s", ifaceidx, inet_ntoa(fbsd_jia)); return true; } } # endif return false; } /******************************************************************/ static void GetMacAddress(EvalContext *ctx, ARG_UNUSED int fd, struct ifreq *ifr, struct ifreq *ifp, Rlist **interfaces, Rlist **hardware) { char name[CF_MAXVARSIZE]; snprintf(name, sizeof(name), "hardware_mac[%s]", CanonifyName(ifp->ifr_name)); // mac address on a loopback interface doesn't make sense if (ifr->ifr_flags & IFF_LOOPBACK) { return; } # if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR) && !defined(__ANDROID__) char hw_mac[CF_MAXVARSIZE]; if ((ioctl(fd, SIOCGIFHWADDR, ifr) == -1)) { Log(LOG_LEVEL_ERR, "Couldn't get mac address for '%s' interface. (ioctl: %s)", ifr->ifr_name, GetErrorStr()); return; } snprintf(hw_mac, sizeof(hw_mac), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (unsigned char) ifr->ifr_hwaddr.sa_data[0], (unsigned char) ifr->ifr_hwaddr.sa_data[1], (unsigned char) ifr->ifr_hwaddr.sa_data[2], (unsigned char) ifr->ifr_hwaddr.sa_data[3], (unsigned char) ifr->ifr_hwaddr.sa_data[4], (unsigned char) ifr->ifr_hwaddr.sa_data[5]); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, hw_mac, CF_DATA_TYPE_STRING, "source=agent"); if (!RlistContainsString(*hardware, hw_mac)) { RlistAppend(hardware, hw_mac, RVAL_TYPE_SCALAR); } if (!RlistContainsString(*interfaces, ifp->ifr_name)) { RlistAppend(interfaces, ifp->ifr_name, RVAL_TYPE_SCALAR); } snprintf(name, sizeof(name), "mac_%s", CanonifyName(hw_mac)); EvalContextClassPutHard(ctx, name, "inventory,attribute_name=none,source=agent"); # elif defined(HAVE_GETIFADDRS) && !defined(__sun) char hw_mac[CF_MAXVARSIZE]; char *mac_pointer = NULL; struct ifaddrs *ifaddr, *ifa; if (getifaddrs(&ifaddr) == -1) { Log(LOG_LEVEL_ERR, "!! Could not get interface %s addresses", ifp->ifr_name); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, "mac_unknown", CF_DATA_TYPE_STRING, "source=agent"); EvalContextClassPutHard(ctx, "mac_unknown", "source=agent"); return; } for (ifa = ifaddr; ifa != NULL; ifa=ifa->ifa_next) { if ( strcmp(ifa->ifa_name, ifp->ifr_name) == 0) { if (ifa->ifa_addr == NULL) { Log(LOG_LEVEL_VERBOSE, "Interface '%s' has no address information", ifa->ifa_name); continue; } #if AF_LINK if (ifa->ifa_addr->sa_family == AF_LINK) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr; mac_pointer = (char *) LLADDR(sdl); } #elif AF_PACKET if (ifa->ifa_addr->sa_family == AF_PACKET) { struct sockaddr_ll *sll = (struct sockaddr_ll *)ifa->ifa_addr; mac_pointer = (char *) sll->sll_addr; } #else # error "AF_LINK or AF_PACKET must be available for GetMacAddress() currently" #endif if (mac_pointer == NULL) { Log(LOG_LEVEL_VERBOSE, "Couldn't get Physical-layer address from interface '%s'", ifr->ifr_name); continue; } snprintf(hw_mac, sizeof(hw_mac), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (unsigned char) mac_pointer[0], (unsigned char) mac_pointer[1], (unsigned char) mac_pointer[2], (unsigned char) mac_pointer[3], (unsigned char) mac_pointer[4], (unsigned char) mac_pointer[5]); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, hw_mac, CF_DATA_TYPE_STRING, "source=agent"); if (!RlistContainsString(*hardware, hw_mac)) { RlistAppend(hardware, hw_mac, RVAL_TYPE_SCALAR); } RlistAppend(interfaces, ifa->ifa_name, RVAL_TYPE_SCALAR); snprintf(name, sizeof(name), "mac_%s", CanonifyName(hw_mac)); EvalContextClassPutHard(ctx, name, "source=agent"); } } freeifaddrs(ifaddr); # elif defined(_AIX) && !defined(HAVE_GETIFADDRS) char hw_mac[CF_MAXVARSIZE]; char mac[CF_MAXVARSIZE]; if (aix_get_mac_addr(ifp->ifr_name, mac) == 0) { sprintf(hw_mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, hw_mac, CF_DATA_TYPE_STRING, "source=agent"); if (!RlistContainsString(*hardware, hw_mac)) { RlistAppend(hardware, hw_mac, RVAL_TYPE_SCALAR); } if (!RlistContainsString(*interfaces, ifp->ifr_name)) { RlistAppend(interfaces, ifp->ifr_name, RVAL_TYPE_SCALAR); } snprintf(name, CF_MAXVARSIZE, "mac_%s", CanonifyName(hw_mac)); EvalContextClassPutHard(ctx, name, "inventory,attribute_name=none,source=agent"); } else { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, "mac_unknown", CF_DATA_TYPE_STRING, "source=agent"); EvalContextClassPutHard(ctx, "mac_unknown", "source=agent"); } # elif defined(SIOCGARP) struct arpreq arpreq; ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = ((struct sockaddr_in *) &ifp->ifr_addr)->sin_addr.s_addr; if (ioctl(fd, SIOCGARP, &arpreq) == -1) { // ENXIO happens if there is no MAC address assigned, which is not that // uncommon. LogLevel log_level = (errno == ENXIO) ? LOG_LEVEL_VERBOSE : LOG_LEVEL_ERR; Log(log_level, "Could not get interface '%s' addresses (ioctl(SIOCGARP): %s)", ifp->ifr_name, GetErrorStr()); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, "mac_unknown", CF_DATA_TYPE_STRING, "source=agent"); EvalContextClassPutHard(ctx, "mac_unknown", "source=agent"); return; } char hw_mac[CF_MAXVARSIZE]; snprintf(hw_mac, sizeof(hw_mac), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (unsigned char) arpreq.arp_ha.sa_data[0], (unsigned char) arpreq.arp_ha.sa_data[1], (unsigned char) arpreq.arp_ha.sa_data[2], (unsigned char) arpreq.arp_ha.sa_data[3], (unsigned char) arpreq.arp_ha.sa_data[4], (unsigned char) arpreq.arp_ha.sa_data[5]); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, hw_mac, CF_DATA_TYPE_STRING, "source=agent"); if (!RlistContainsString(*hardware, hw_mac)) { RlistAppend(hardware, hw_mac, RVAL_TYPE_SCALAR); } if (!RlistContainsString(*interfaces, ifp->ifr_name)) { RlistAppend(interfaces, ifp->ifr_name, RVAL_TYPE_SCALAR); } snprintf(name, sizeof(name), "mac_%s", CanonifyName(hw_mac)); EvalContextClassPutHard(ctx, name, "inventory,attribute_name=none,source=agent"); # else EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, "mac_unknown", CF_DATA_TYPE_STRING, "source=agent"); EvalContextClassPutHard(ctx, "mac_unknown", "source=agent"); # endif } /******************************************************************/ static void GetInterfaceFlags(EvalContext *ctx, struct ifreq *ifr, Rlist **flags) { char name[CF_MAXVARSIZE]; char buffer[CF_BUFSIZE] = ""; char *fp = NULL; snprintf(name, sizeof(name), "interface_flags[%s]", ifr->ifr_name); if (ifr->ifr_flags & IFF_UP) strcat(buffer, " up"); if (ifr->ifr_flags & IFF_BROADCAST) strcat(buffer, " broadcast"); if (ifr->ifr_flags & IFF_DEBUG) strcat(buffer, " debug"); if (ifr->ifr_flags & IFF_LOOPBACK) strcat(buffer, " loopback"); if (ifr->ifr_flags & IFF_POINTOPOINT) strcat(buffer, " pointopoint"); #ifdef IFF_NOTRAILERS if (ifr->ifr_flags & IFF_NOTRAILERS) strcat(buffer, " notrailers"); #endif if (ifr->ifr_flags & IFF_RUNNING) strcat(buffer, " running"); if (ifr->ifr_flags & IFF_NOARP) strcat(buffer, " noarp"); if (ifr->ifr_flags & IFF_PROMISC) strcat(buffer, " promisc"); if (ifr->ifr_flags & IFF_ALLMULTI) strcat(buffer, " allmulti"); if (ifr->ifr_flags & IFF_MULTICAST) strcat(buffer, " multicast"); // If a least 1 flag is found if (strlen(buffer) > 1) { // Skip leading space fp = buffer + 1; EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, fp, CF_DATA_TYPE_STRING, "source=agent"); RlistAppend(flags, fp, RVAL_TYPE_SCALAR); } } /******************************************************************/ void GetInterfacesInfo(EvalContext *ctx) { bool address_set = false; int fd, len, i, j; struct ifreq ifbuf[CF_IFREQ], ifr, *ifp; struct ifconf list; struct sockaddr_in *sin; char *sp, workbuf[CF_BUFSIZE]; char ip[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE]; Rlist *interfaces = NULL, *hardware = NULL, *flags = NULL, *ips = NULL; /* This function may be called many times, while interfaces come and go */ /* TODO cache results for non-daemon processes? */ EvalContextDeleteIpAddresses(ctx); memset(ifbuf, 0, sizeof(ifbuf)); InitIgnoreInterfaces(); if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { Log(LOG_LEVEL_ERR, "Couldn't open socket. (socket: %s)", GetErrorStr()); DoCleanupAndExit(EXIT_FAILURE); } list.ifc_len = sizeof(ifbuf); list.ifc_req = ifbuf; /* WARNING: *BSD use unsigned long as second argument to ioctl() while * POSIX specifies *signed* int. Using the largest possible signed type is * the best strategy.*/ #ifdef SIOCGIFCONF intmax_t request = SIOCGIFCONF; #else intmax_t request = OSIOCGIFCONF; #endif int ret = ioctl(fd, request, &list); if (ret == -1) { Log(LOG_LEVEL_ERR, "Couldn't get interfaces (ioctl(SIOCGIFCONF): %s)", GetErrorStr()); DoCleanupAndExit(EXIT_FAILURE); } if (list.ifc_len < (int) sizeof(struct ifreq)) { Log(LOG_LEVEL_VERBOSE, "Interface list returned is too small (%d bytes), " "assuming no interfaces present", list.ifc_len); list.ifc_len = 0; } char last_name[sizeof(ifp->ifr_name)] = ""; for (j = 0, len = 0, ifp = list.ifc_req; len < list.ifc_len; len += SIZEOF_IFREQ(*ifp), j++, ifp = (struct ifreq *) ((char *) ifp + SIZEOF_IFREQ(*ifp))) { if (ifp->ifr_addr.sa_family == 0) { continue; } if (strlen(ifp->ifr_name) == 0) { continue; } /* Skip network interfaces listed in ignore_interfaces.rx */ if (IgnoreInterface(ifp->ifr_name)) { continue; } else { Log(LOG_LEVEL_VERBOSE, "Interface %d: %s", j + 1, ifp->ifr_name); } /* If interface name appears a second time in a row then it has more than one IP addresses (linux: ip addr add $IP dev $IF). But the variable is already added so don't set it again. */ if (strcmp(last_name, ifp->ifr_name) != 0) { strcpy(last_name, ifp->ifr_name); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "interface", last_name, CF_DATA_TYPE_STRING, "source=agent"); } snprintf(workbuf, sizeof(workbuf), "net_iface_%s", CanonifyName(ifp->ifr_name)); EvalContextClassPutHard(ctx, workbuf, "source=agent"); /* TODO IPv6 should be handled transparently */ if (ifp->ifr_addr.sa_family == AF_INET) { strlcpy(ifr.ifr_name, ifp->ifr_name, sizeof(ifp->ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { Log(LOG_LEVEL_ERR, "No such network device. (ioctl: %s)", GetErrorStr()); continue; } else { GetInterfaceFlags(ctx, &ifr, &flags); } if (ifr.ifr_flags & IFF_UP) { sin = (struct sockaddr_in *) &ifp->ifr_addr; if (IgnoreJailInterface(j + 1, sin)) { Log(LOG_LEVEL_VERBOSE, "Ignoring interface %d", j + 1); continue; } /* No DNS lookup, just convert IP address to string. */ char txtaddr[CF_MAX_IP_LEN] = ""; nt_static_assert(sizeof(VIPADDRESS) >= sizeof(txtaddr)); getnameinfo((struct sockaddr *) sin, sizeof(*sin), txtaddr, sizeof(txtaddr), NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_DEBUG, "Adding hostip '%s'", txtaddr); EvalContextClassPutHard(ctx, txtaddr, "inventory,attribute_name=none,source=agent"); if (strcmp(txtaddr, "0.0.0.0") == 0) { /* TODO remove, interface address can't be 0.0.0.0 and * even then DNS is not a safe way to set a variable... */ Log(LOG_LEVEL_VERBOSE, "Cannot discover hardware IP, using DNS value"); nt_static_assert(sizeof(ip) >= sizeof(VIPADDRESS) + sizeof("ipv4_")); strcpy(ip, "ipv4_"); strcat(ip, VIPADDRESS); EvalContextAddIpAddress(ctx, VIPADDRESS, NULL); // we don't know the interface RlistAppendScalar(&ips, VIPADDRESS); for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; EvalContextClassPutHard(ctx, ip, "inventory,attribute_name=none,source=agent"); } } strcpy(ip, VIPADDRESS); i = 3; for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; snprintf(name, sizeof(name), "ipv4_%d[%s]", i--, CanonifyName(VIPADDRESS)); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, ip, CF_DATA_TYPE_STRING, "source=agent"); } } continue; } nt_static_assert(sizeof(ip) >= sizeof(txtaddr) + sizeof("ipv4_")); strcpy(ip, "ipv4_"); strcat(ip, txtaddr); EvalContextClassPutHard(ctx, ip, "inventory,attribute_name=none,source=agent"); /* VIPADDRESS has already been set to the DNS address of * VFQNAME by GetNameInfo3() during initialisation. Here we * reset VIPADDRESS to the address of the first non-loopback * interface. */ if (!address_set && !(ifr.ifr_flags & IFF_LOOPBACK)) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "ipv4", txtaddr, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=none"); strcpy(VIPADDRESS, txtaddr); Log(LOG_LEVEL_VERBOSE, "IP address of host set to %s", VIPADDRESS); address_set = true; } EvalContextAddIpAddress(ctx, txtaddr, CanonifyName(ifp->ifr_name)); RlistAppendScalar(&ips, txtaddr); for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; EvalContextClassPutHard(ctx, ip, "inventory,attribute_name=none,source=agent"); } } // Set the IPv4 on interface array strcpy(ip, txtaddr); snprintf(name, sizeof(name), "ipv4[%s]", CanonifyName(ifp->ifr_name)); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, ip, CF_DATA_TYPE_STRING, "source=agent"); // generate the reverse mapping snprintf(name, sizeof(name), "ip2iface[%s]", txtaddr); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, CanonifyName(ifp->ifr_name), CF_DATA_TYPE_STRING, "source=agent"); i = 3; for (sp = ip + strlen(ip) - 1; (sp > ip); sp--) { if (*sp == '.') { *sp = '\0'; snprintf(name, sizeof(name), "ipv4_%d[%s]", i--, CanonifyName(ifp->ifr_name)); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, name, ip, CF_DATA_TYPE_STRING, "source=agent"); } } } // Set the hardware/mac address array GetMacAddress(ctx, fd, &ifr, ifp, &interfaces, &hardware); } } close(fd); FindV6InterfacesInfo(ctx, &interfaces, &hardware, &ips); if (interfaces) { // Define sys.interfaces: EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "interfaces", interfaces, CF_DATA_TYPE_STRING_LIST, "inventory,source=agent,attribute_name=Interfaces"); } if (hardware) { // Define sys.hardware_addresses: EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "hardware_addresses", hardware, CF_DATA_TYPE_STRING_LIST, "inventory,source=agent,attribute_name=MAC addresses"); } if (flags) { // Define sys.hardware_flags: EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "hardware_flags", flags, CF_DATA_TYPE_STRING_LIST, "source=agent"); } if (ips) { // Define sys.ip_addresses: EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "ip_addresses", ips, CF_DATA_TYPE_STRING_LIST, "source=agent"); } RlistDestroy(interfaces); RlistDestroy(hardware); RlistDestroy(flags); RlistDestroy(ips); } /*******************************************************************/ static void FindV6InterfacesInfo(EvalContext *ctx, Rlist **interfaces, Rlist **hardware, Rlist **ips) { assert(interfaces != NULL); assert(hardware != NULL); FILE *pp = NULL; /* Whatever the manuals might say, you cannot get IPV6 interface configuration from the ioctls. This seems to be implemented in a non standard way across OSes BSDi has done getifaddrs(), solaris 8 has a new ioctl, Stevens book shows the suggestion which has not been implemented... */ Log(LOG_LEVEL_VERBOSE, "Trying to locate my IPv6 address"); #if defined(__CYGWIN__) /* NT cannot do this */ return; #elif defined(__hpux) if ((pp = cf_popen("/usr/sbin/ifconfig -a", "r", true)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find interface info"); return; } #elif defined(_AIX) if ((pp = cf_popen("/etc/ifconfig -a", "r", true)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find interface info"); return; } #else if ((!FileCanOpen("/sbin/ifconfig", "r") || ((pp = cf_popen("/sbin/ifconfig -a", "r", true)) == NULL)) && (!FileCanOpen("/bin/ifconfig", "r") || ((pp = cf_popen("/bin/ifconfig -a", "r", true)) == NULL))) { Log(LOG_LEVEL_VERBOSE, "Could not find interface info"); return; } #endif /* Don't know the output format of ifconfig on all these .. hope for the best*/ char ifconfig_line[CF_BUFSIZE]; char current_interface[CF_BUFSIZE]; current_interface[0] = '\0'; for(;;) { if (fgets(ifconfig_line, sizeof(ifconfig_line), pp) == NULL) { if (ferror(pp)) { UnexpectedError("Failed to read line from stream"); break; } else /* feof */ { break; } } if (!isspace(ifconfig_line[0])) // Name of interface followed by colon { // Find colon: const char *colon = strchr(ifconfig_line, ':'); if (colon != NULL) { // Bytes to "copy" includes colon(src)/NUL-byte(dst): const size_t bytes_to_copy = colon - ifconfig_line + 1; assert(bytes_to_copy <= sizeof(current_interface)); const size_t src_length = StringCopy( ifconfig_line, current_interface, bytes_to_copy); // StringCopy effectively returns the length of the src string, // up to (inclusive) a maximum of passed in buffer size // We know there was more data, at least a colon: assert(src_length == bytes_to_copy); NDEBUG_UNUSED const size_t dst_length = src_length - 1; // We copied everything up to, but not including, the colon: assert(ifconfig_line[dst_length] == ':'); assert(current_interface[dst_length] == '\0'); } } if (IgnoreInterface(current_interface)) { // Ignore interfaces listed in ignore_interfaces.rx continue; } const char *const stripped_ifconfig_line = TrimWhitespace(ifconfig_line); if (StringStartsWith(stripped_ifconfig_line, "ether ")) { Seq *const ether_line = SeqStringFromString(stripped_ifconfig_line, ' '); const size_t length = SeqLength(ether_line); if (length < 2) { Log(LOG_LEVEL_ERR, "Failed to parse hw_mac address for: %s", current_interface); } else { const char *const hw_mac = SeqAt(ether_line, 1); if (!RlistContainsString(*hardware, hw_mac)) { Log(LOG_LEVEL_VERBOSE, "Adding MAC address: %s for %s", hw_mac, current_interface); RlistAppendString(hardware, hw_mac); char variable_name[CF_MAXVARSIZE]; snprintf( variable_name, sizeof(variable_name), "hardware_mac[%s]", CanonifyName(current_interface)); EvalContextVariablePutSpecial( ctx, SPECIAL_SCOPE_SYS, variable_name, hw_mac, CF_DATA_TYPE_STRING, "source=agent,derived-from=ifconfig"); } } SeqDestroy(ether_line); } if (strcasestr(ifconfig_line, "inet6")) { Item *ip, *list = NULL; char *sp; list = SplitStringAsItemList(ifconfig_line, ' '); for (ip = list; ip != NULL; ip = ip->next) { for (sp = ip->name; *sp != '\0'; sp++) { if (*sp == '/') /* Remove CIDR mask */ { *sp = '\0'; } } if ((IsIPV6Address(ip->name)) && ((strcmp(ip->name, "::1") != 0))) { char prefixed_ip[CF_MAX_IP_LEN + sizeof(IPV6_PREFIX)] = {0}; Log(LOG_LEVEL_VERBOSE, "Found IPv6 address %s", ip->name); if (current_interface[0] != '\0' && !IgnoreInterface(current_interface)) { EvalContextAddIpAddress( ctx, ip->name, current_interface); EvalContextClassPutHard( ctx, ip->name, "inventory,attribute_name=none,source=agent"); xsnprintf( prefixed_ip, sizeof(prefixed_ip), IPV6_PREFIX "%s", ip->name); EvalContextClassPutHard( ctx, prefixed_ip, "inventory,attribute_name=none,source=agent"); // Add IPv6 address to sys.ip_addresses RlistAppendString(ips, ip->name); if (!RlistContainsString( *interfaces, current_interface)) { RlistAppendString(interfaces, current_interface); } } } } DeleteItemList(list); } } cf_pclose(pp); } /*******************************************************************/ static void InitIgnoreInterfaces() { FILE *fin; char filename[CF_BUFSIZE], regex[256]; int ret = snprintf( filename, sizeof(filename), "%s%c%s", GetWorkDir(), FILE_SEPARATOR, CF_IGNORE_INTERFACES); assert(ret >= 0 && (size_t) ret < sizeof(filename)); if ((fin = fopen(filename, "r")) == NULL) { Log((errno == ENOENT) ? LOG_LEVEL_VERBOSE : LOG_LEVEL_ERR, "Failed to open interface exception file %s: %s", filename, GetErrorStr()); /* LEGACY: The 'ignore_interfaces.rx' file was previously located in * $(sys.inputdir). Consequently, if the file is found in this * directory but not in $(sys.workdir), we will still process it, but * issue a warning. */ ret = snprintf( filename, sizeof(filename), "%s%c%s", GetInputDir(), FILE_SEPARATOR, CF_IGNORE_INTERFACES); assert(ret >= 0 && (size_t) ret < sizeof(filename)); if ((fin = fopen(filename, "r")) == NULL) { Log((errno == ENOENT) ? LOG_LEVEL_VERBOSE : LOG_LEVEL_ERR, "Failed to open interface exception file %s: %s", filename, GetErrorStr()); return; } Log(LOG_LEVEL_WARNING, "Found interface exception file %s in %s but it should be in %s. " "Please consider moving it to the appropriate location.", CF_IGNORE_INTERFACES, GetInputDir(), GetWorkDir()); } while (!feof(fin)) { regex[0] = '\0'; int scanCount = fscanf(fin, "%255s", regex); if (ferror(fin) != 0) { Log(LOG_LEVEL_ERR, "Failed to read interface exception file %s: %s", filename, GetErrorStr()); break; } if (scanCount != 0 && *regex != '\0') { RlistPrependScalarIdemp(&IGNORE_INTERFACES, regex); } } fclose(fin); } /*******************************************************************/ static bool IgnoreInterface(char *name) { Rlist *rp; for (rp = IGNORE_INTERFACES; rp != NULL; rp=rp->next) { /* FIXME: review this strcmp. Moved out from StringMatch */ if (!strcmp(RlistScalarValue(rp), name) || StringMatchFull(RlistScalarValue(rp), name)) { Log(LOG_LEVEL_VERBOSE, "Ignoring interface '%s' because it matches '%s'",name,CF_IGNORE_INTERFACES); return true; } } return false; } #ifdef _AIX static int aix_get_mac_addr(const char *device_name, uint8_t mac[6]) { size_t ksize; struct kinfo_ndd *ndd; int count, i; ksize = getkerninfo(KINFO_NDD, 0, 0, 0); if (ksize == 0) { errno = ENOSYS; return -1; } ndd = (struct kinfo_ndd *)xmalloc(ksize); if (ndd == NULL) { errno = ENOMEM; return -1; } if (getkerninfo(KINFO_NDD, ndd, &ksize, 0) == -1) { errno = ENOSYS; return -1; } count= ksize/sizeof(struct kinfo_ndd); for (i=0;i= RankIPv6Address(prev_addr)) { return this_item; } else { return prev_item; } } /*******************************************************************/ static const char* GetPortStateString(ARG_LINUX_ONLY int state) { # if defined (__linux__) switch (state) { case TCP_ESTABLISHED: return "ESTABLISHED"; case TCP_SYN_SENT: return "SYN_SENT"; case TCP_SYN_RECV: return "SYN_RECV"; case TCP_FIN_WAIT1: return "FIN_WAIT1"; case TCP_FIN_WAIT2: return "FIN_WAIT2"; case TCP_TIME_WAIT: return "TIME_WAIT"; case TCP_CLOSE: return "CLOSE"; case TCP_CLOSE_WAIT: return "CLOSE_WAIT"; case TCP_LAST_ACK: return "LAST_ACK"; case TCP_LISTEN: return "LISTEN"; case TCP_CLOSING: return "CLOSING"; } # endif return "UNKNOWN"; } // used in evalfunction.c but defined here so // JsonRewriteParsedIPAddress() etc. can stay local void NetworkingPortsPostProcessInfo(ARG_UNUSED void *passed_ctx, void *json) { JsonElement *conn = json; if (conn != NULL) { JsonRewriteParsedIPAddress(conn, "raw_local", "local", true); JsonRewriteParsedIPAddress(conn, "raw_remote", "remote", true); long num_state = JsonExtractParsedNumber(conn, "raw_state", "temp_state", false, false); if (JsonObjectGetAsString(conn, "temp_state") != NULL) { JsonObjectRemoveKey(conn, "temp_state"); JsonObjectAppendString(conn, "state", GetPortStateString(num_state)); } } } /*******************************************************************/ static JsonElement* GetNetworkingStatsInfo(const char *filename) { JsonElement *stats = NULL; assert(filename); FILE *fin = safe_fopen(filename, "rt"); if (fin) { Log(LOG_LEVEL_VERBOSE, "Reading netstat info from %s", filename); size_t header_line_size = CF_BUFSIZE; char *header_line = xmalloc(header_line_size); stats = JsonObjectCreate(2); while (CfReadLine(&header_line, &header_line_size, fin) != -1) { char* colon_ptr = strchr(header_line, ':'); if (colon_ptr != NULL && colon_ptr+2 < header_line + strlen(header_line)) { JsonElement *stat = JsonObjectCreate(3); Buffer *type = BufferNewFrom(header_line, colon_ptr - header_line); size_t type_length = BufferSize(type); Rlist *info = RlistFromSplitString(colon_ptr+2, ' '); size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); if (CfReadLine(&line, &line_size, fin) != -1) { if (strlen(line) > type_length+2) { Rlist *data = RlistFromSplitString(line+type_length+2, ' '); for (const Rlist *rp = info, *rdp = data; rp != NULL && rdp != NULL; rp = rp->next, rdp = rdp->next) { JsonObjectAppendString(stat, RlistScalarValue(rp), RlistScalarValue(rdp)); } RlistDestroy(data); } } JsonObjectAppendElement(stats, BufferData(type), stat); free(line); RlistDestroy(info); BufferDestroy(type); } } free(header_line); fclose(fin); } return stats; } /*******************************************************************/ // always returns the parsed data. If the key is not NULL, also // creates a sys.KEY variable. JsonElement* GetProcFileInfo(EvalContext *ctx, const char* filename, const char* key, const char* extracted_key, ProcPostProcessFn post, ProcTiebreakerFn tiebreak, const char* pattern) { JsonElement *info = NULL; bool extract_key_mode = (extracted_key != NULL); FILE *fin = safe_fopen(filename, "rt"); if (fin) { Log(LOG_LEVEL_VERBOSE, "Reading %s info from %s", key, filename); Regex *regex = CompileRegex(pattern); if (regex != NULL) { size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); info = extract_key_mode ? JsonObjectCreate(10) : JsonArrayCreate(10); while (CfReadLine(&line, &line_size, fin) != -1) { JsonElement *item = StringCaptureData(regex, NULL, line); if (item != NULL) { if (post != NULL) { (*post)(ctx, item); } if (extract_key_mode) { const char *extracted_key_value = JsonObjectGetAsString(item, extracted_key); if (extracted_key_value == NULL) { Log(LOG_LEVEL_ERR, "While parsing %s, looked to extract key %s but couldn't find it in line %s", filename, extracted_key, line); } else { JsonElement *prev_item = JsonObjectGet(info, extracted_key_value); Log(LOG_LEVEL_DEBUG, "While parsing %s, got key %s from line %s", filename, extracted_key_value, line); if (prev_item != NULL && tiebreak != NULL) { JsonElement *winner = (*tiebreak)(prev_item, item); if (winner == prev_item) { Log(LOG_LEVEL_DEBUG, "Multiple entries for key %s, preferring previous value", extracted_key_value); JsonDestroy(item); item = NULL; } else { Log(LOG_LEVEL_DEBUG, "Multiple entries for key %s, preferring new value", extracted_key_value); } } if (item != NULL) { JsonObjectAppendElement(info, extracted_key_value, item); } } } else { JsonArrayAppendElement(info, item); } } } free(line); if (key != NULL) { Buffer *varname = BufferNew(); BufferPrintf(varname, "%s", key); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, BufferData(varname), info, CF_DATA_TYPE_CONTAINER, "networking,/proc,source=agent,procfs"); BufferDestroy(varname); } RegexDestroy(regex); } fclose(fin); } return info; } /*******************************************************************/ void GetNetworkingInfo(EvalContext *ctx) { const char *procdir_root = GetRelocatedProcdirRoot(); Buffer *pbuf = BufferNew(); JsonElement *inet = JsonObjectCreate(2); BufferPrintf(pbuf, "%s/proc/net/netstat", procdir_root); JsonElement *inet_stats = GetNetworkingStatsInfo(BufferData(pbuf)); if (inet_stats != NULL) { JsonObjectAppendElement(inet, "stats", inet_stats); } BufferPrintf(pbuf, "%s/proc/net/route", procdir_root); JsonElement *routes = GetProcFileInfo(ctx, BufferData(pbuf), NULL, NULL, &NetworkingRoutesPostProcessInfo, NULL, // format: Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT // eth0 00000000 0102A8C0 0003 0 0 1024 00000000 0 0 0 "^(?\\S+)\\t(?[[:xdigit:]]+)\\t(?[[:xdigit:]]+)\\t(?[[:xdigit:]]+)\\t(?\\d+)\\t(?\\d+)\\t(?[[:xdigit:]]+)\\t(?[[:xdigit:]]+)\\t(?\\d+)\\t(?\\d+)\\t(?[[:xdigit:]]+)"); if (routes != NULL && JsonGetElementType(routes) == JSON_ELEMENT_TYPE_CONTAINER) { JsonObjectAppendElement(inet, "routes", routes); JsonIterator iter = JsonIteratorInit(routes); const JsonElement *default_route = NULL; long lowest_metric = 0; const JsonElement *route = NULL; while ((route = JsonIteratorNextValue(&iter))) { JsonElement *active = JsonObjectGet(route, "active_default_gateway"); if (active != NULL && JsonGetElementType(active) == JSON_ELEMENT_TYPE_PRIMITIVE && JsonGetPrimitiveType(active) == JSON_PRIMITIVE_TYPE_BOOL && JsonPrimitiveGetAsBool(active)) { JsonElement *metric = JsonObjectGet(route, "metric"); if (metric != NULL && JsonGetElementType(metric) == JSON_ELEMENT_TYPE_PRIMITIVE && JsonGetPrimitiveType(metric) == JSON_PRIMITIVE_TYPE_INTEGER && (default_route == NULL || JsonPrimitiveGetAsInteger(metric) < lowest_metric)) { default_route = route; } } } if (default_route != NULL) { JsonObjectAppendString(inet, "default_gateway", JsonObjectGetAsString(default_route, "gateway")); JsonObjectAppendElement(inet, "default_route", JsonCopy(default_route)); } } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "inet", inet, CF_DATA_TYPE_CONTAINER, "networking,/proc,source=agent,procfs"); JsonDestroy(inet); JsonElement *inet6 = JsonObjectCreate(3); BufferPrintf(pbuf, "%s/proc/net/snmp6", procdir_root); JsonElement *inet6_stats = GetProcFileInfo(ctx, BufferData(pbuf), NULL, NULL, NULL, NULL, "^\\s*(?\\S+)\\s+(?\\d+)"); if (inet6_stats != NULL) { // map the key to the value (as a number) in the "stats" map JsonElement *rewrite = JsonObjectCreate(JsonLength(inet6_stats)); JsonIterator iter = JsonIteratorInit(inet6_stats); const JsonElement *stat = NULL; while ((stat = JsonIteratorNextValue(&iter))) { long num = 0; const char* key = JsonObjectGetAsString(stat, "key"); const char* value = JsonObjectGetAsString(stat, "value"); if (key && value && sscanf(value, "%ld", &num) == 1) { JsonObjectAppendInteger(rewrite, key, num); } } JsonObjectAppendElement(inet6, "stats", rewrite); JsonDestroy(inet6_stats); } BufferPrintf(pbuf, "%s/proc/net/ipv6_route", procdir_root); JsonElement *inet6_routes = GetProcFileInfo(ctx, BufferData(pbuf), NULL, NULL, &NetworkingIPv6RoutesPostProcessInfo, NULL, // format: dest dest_prefix source source_prefix next_hop metric refcnt use flags interface // fe800000000000000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000000 00000000 00000001 eth0 "^(?[[:xdigit:]]+)\\s+(?[[:xdigit:]]+)\\s+" "(?[[:xdigit:]]+)\\s+(?[[:xdigit:]]+)\\s+" "(?[[:xdigit:]]+)\\s+(?[[:xdigit:]]+)\\s+" "(?\\d+)\\s+(?\\d+)\\s+" "(?[[:xdigit:]]+)\\s+(?\\S+)"); if (inet6_routes != NULL) { JsonObjectAppendElement(inet6, "routes", inet6_routes); } BufferPrintf(pbuf, "%s/proc/net/if_inet6", procdir_root); JsonElement *inet6_addresses = GetProcFileInfo(ctx, BufferData(pbuf), NULL, "interface", &NetworkingIPv6AddressesPostProcessInfo, &NetworkingIPv6AddressesTiebreaker, // format: address device_number prefix_length scope flags interface_name // 00000000000000000000000000000001 01 80 10 80 lo // fe80000000000000004249fffebdd7b4 04 40 20 80 docker0 // fe80000000000000c27cd1fffe3eada6 02 40 20 80 enp4s0 "^(?[[:xdigit:]]+)\\s+(?[[:xdigit:]]+)\\s+" "(?[[:xdigit:]]+)\\s+(?[[:xdigit:]]+)\\s+" "(?[[:xdigit:]]+)\\s+(?\\S+)"); if (inet6_addresses != NULL) { JsonObjectAppendElement(inet6, "addresses", inet6_addresses); } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "inet6", inet6, CF_DATA_TYPE_CONTAINER, "networking,/proc,source=agent,procfs"); JsonDestroy(inet6); // Inter-| Receive | Transmit // face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed // eth0: 74850544807 75236137 0 0 0 0 0 1108775 63111535625 74696758 0 0 0 0 0 0 BufferPrintf(pbuf, "%s/proc/net/dev", procdir_root); JsonElement *interfaces_data = GetProcFileInfo(ctx, BufferData(pbuf), "interfaces_data", "device", NULL, NULL, "^\\s*(?[^:]+)\\s*:\\s*" // All of the below are just decimal digits separated by spaces "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)\\s+" "(?\\d+)"); JsonDestroy(interfaces_data); BufferDestroy(pbuf); } JsonElement* GetNetworkingConnections(EvalContext *ctx) { const char *procdir_root = GetRelocatedProcdirRoot(); JsonElement *json = JsonObjectCreate(5); const char* ports_regex = "^\\s*\\d+:\\s+(?[0-9A-F:]+)\\s+(?[0-9A-F:]+)\\s+(?[0-9]+)"; JsonElement *data = NULL; Buffer *pbuf = BufferNew(); BufferPrintf(pbuf, "%s/proc/net/tcp", procdir_root); data = GetProcFileInfo(ctx, BufferData(pbuf), NULL, NULL, &NetworkingPortsPostProcessInfo, NULL, ports_regex); if (data != NULL) { JsonObjectAppendElement(json, "tcp", data); } BufferPrintf(pbuf, "%s/proc/net/tcp6", procdir_root); data = GetProcFileInfo(ctx, BufferData(pbuf), NULL, NULL, &NetworkingPortsPostProcessInfo, NULL, ports_regex); if (data != NULL) { JsonObjectAppendElement(json, "tcp6", data); } BufferPrintf(pbuf, "%s/proc/net/udp", procdir_root); data = GetProcFileInfo(ctx, BufferData(pbuf), NULL, NULL, &NetworkingPortsPostProcessInfo, NULL, ports_regex); if (data != NULL) { JsonObjectAppendElement(json, "udp", data); } BufferPrintf(pbuf, "%s/proc/net/udp6", procdir_root); data = GetProcFileInfo(ctx, BufferData(pbuf), NULL, NULL, &NetworkingPortsPostProcessInfo, NULL, ports_regex); if (data != NULL) { JsonObjectAppendElement(json, "udp6", data); } BufferDestroy(pbuf); if (JsonLength(json) < 1) { // nothing was collected, this is a failure JsonDestroy(json); return NULL; } return json; } #endif /* !__MINGW32__ */ cfengine-3.24.2/libenv/time_classes.h0000644000000000000000000000346215010704253017463 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_TIME_CLASSES_H #define CFENGINE_TIME_CLASSES_H #include /** * @brief Get a string set of time classes based on a timestamp. * @param time Unix timestamp * @return Set of time classes or NULL in case of error. * @note On success, returned value must be free'd using StringSetDestroy(). * @example GetTimeClasses(1716989621) in the GMT+2 timezone would return the * following classes: { 'Afternoon', 'Day29', 'GMT_Afternoon', * 'GMT_Day29', 'GMT_Hr13', 'GMT_Hr13_Q3', 'GMT_Lcycle_2', 'GMT_May', * 'GMT_Min30_35', 'GMT_Min33', 'GMT_Q3', 'GMT_Wednesday', * 'GMT_Yr2024', 'Hr15', 'Hr15_Q3', 'Lcycle_2', 'May', 'Min30_35', * 'Min33', 'Q3', 'Wednesday', 'Yr2024' } */ StringSet *GetTimeClasses(time_t time); void UpdateTimeClasses(EvalContext *ctx, time_t t); #endif cfengine-3.24.2/libenv/constants.h0000644000000000000000000000231515010704253017020 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CONSTANTS_H #define CFENGINE_CONSTANTS_H #include /* TODO libpromises depends on libenv, the opposite should not happen! */ #include void LoadSystemConstants(EvalContext *ctx); #endif cfengine-3.24.2/libenv/constants.c0000644000000000000000000000415515010704253017017 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #ifdef _WIN32 #define LINESEP "\r\n" #else #define LINESEP "\n" #endif void LoadSystemConstants(EvalContext *ctx) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "at", "@", CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "dollar", "$", CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "n", "\n", CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "r", "\r", CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "t", "\t", CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "endl", "\n", CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "dirsep", FILE_SEPARATOR_STR, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_CONST, "linesep", LINESEP, CF_DATA_TYPE_STRING, "source=agent"); /* NewScalar("const","0","\0",cf_str); - this cannot work */ } cfengine-3.24.2/libenv/Makefile.in0000644000000000000000000005717215010704300016704 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @NT_FALSE@am__append_1 = \ @NT_FALSE@ unix_iface.c subdir = libenv ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libenv_la_DEPENDENCIES = am__libenv_la_SOURCES_DIST = constants.c constants.h sysinfo.c \ sysinfo.h sysinfo_priv.h time_classes.c time_classes.h zones.c \ zones.h unix_iface.c @NT_FALSE@am__objects_1 = unix_iface.lo am_libenv_la_OBJECTS = constants.lo sysinfo.lo time_classes.lo \ zones.lo $(am__objects_1) libenv_la_OBJECTS = $(am_libenv_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libenv_la_SOURCES) DIST_SOURCES = $(am__libenv_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libenv.la libenv_la_SOURCES = constants.c constants.h sysinfo.c sysinfo.h \ sysinfo_priv.h time_classes.c time_classes.h zones.c zones.h \ $(am__append_1) @SOLARIS_TRUE@libenv_la_LIBADD = -lkstat # Those dependencies are ought to go away ASAP AM_CPPFLAGS = -I$(top_srcdir)/libntech/libutils $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) -I$(top_srcdir)/libcfnet \ -I$(top_srcdir)/libpromises CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = config.h.in all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libenv/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libenv/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libenv.la: $(libenv_la_OBJECTS) $(libenv_la_DEPENDENCIES) $(EXTRA_libenv_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libenv_la_OBJECTS) $(libenv_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constants.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_classes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_iface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zones.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # libcompat dependency .PRECIOUS: ../libntech/libcompat/libcompat.la ../libntech/libcompat/libcompat.la: $(MAKE) -C ../libntech/libcompat $(AM_MAKEFLAGS) libcompat.la # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libenv/sysinfo.c0000644000000000000000000036344215010704253016504 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #define PCRE2_CODE_UNIT_WIDTH 8 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* StringMatchFull */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* GetCurrentUserName() */ #ifdef HAVE_ZONE_H # include #endif // HP-UX mpctl() for $(sys.cpus) on HP-UX - Mantis #1069 #ifdef HAVE_SYS_MPCTL_H # include #endif /* Linux. WARNING keep this before the #include because of glibc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=140 */ #ifdef HAVE_STRUCT_SYSINFO_UPTIME # include #endif /* BSD, MAC OS X uptime calculation use KERN_BOOTTIME sysctl. */ #ifdef HAVE_SYS_SYSCTL_H # ifdef HAVE_SYS_PARAM_H # include # endif # ifdef __linux__ # include # else # include # endif #endif /*****************************************************/ // Uptime calculation settings for GetUptimeSeconds() - Mantis #1134 /* Listed here in priority order, i.e. first come the platform-specific * ways. If nothing works, one of the last, most generic ways should. */ #ifndef __MINGW32__ /* Windows is implemented in Enterprise */ // HP-UX: pstat_getproc(2) on init (pid 1) #if defined(__hpux) # include # include # define BOOT_TIME_WITH_PSTAT_GETPROC // Solaris: kstat() for kernel statistics // See http://dsc.sun.com/solaris/articles/kstatc.html // BSD also has a kstat.h (albeit in sys), so check __sun just to be paranoid /** * @WARNING: Commented out because inside a Solaris 10 zone this gives the * uptime of the host machine (the hypervisor). We thus choose to * use UTMP for Solaris. */ /* #elif defined(__sun) && defined(HAVE_KSTAT_H) # include # define BOOT_TIME_WITH_KSTAT */ // BSD: sysctl(3) to get kern.boottime, CPU count, etc. // See http://www.unix.com/man-page/FreeBSD/3/sysctl/ // Linux also has sys/sysctl.h, so we check KERN_BOOTTIME to make sure it's BSD #elif defined(HAVE_SYS_SYSCTL_H) && defined(KERN_BOOTTIME) # define BOOT_TIME_WITH_SYSCTL // GNU/Linux: struct sysinfo.uptime #elif defined(HAVE_STRUCT_SYSINFO_UPTIME) # define BOOT_TIME_WITH_SYSINFO /* Generic System V way, available in most platforms. */ #elif defined(HAVE_UTMP_H) # include # define BOOT_TIME_WITH_UTMP /* POSIX alternative (utmp.h does not exist on BSDs). */ #elif defined(HAVE_UTMPX_H) # include # define BOOT_TIME_WITH_UTMPX #else // Most generic way: {stat("/proc/1")}.st_ctime // TODO in Solaris zones init is not guaranteed to be PID 1! #define BOOT_TIME_WITH_PROCFS #endif /* Fallback uptime calculation: Parse the "uptime" command in case the * platform-specific way fails or returns absurd number. */ static time_t GetBootTimeFromUptimeCommand(time_t now); #endif /* ifndef __MINGW32__ */ #define LSB_RELEASE_FILENAME "/etc/lsb-release" #define DEBIAN_VERSION_FILENAME "/etc/debian_version" #define DEBIAN_ISSUE_FILENAME "/etc/issue" /*****************************************************/ static char *FindNextInteger(char *str, char **num); void CalculateDomainName(const char *nodename, const char *dnsname, char *fqname, size_t fqname_size, char *uqname, size_t uqname_size, char *domain, size_t domain_size); #ifdef __linux__ static int Linux_Fedora_Version(EvalContext *ctx); static int Linux_Redhat_Version(EvalContext *ctx); static void Linux_Amazon_Version(EvalContext *ctx); static void Linux_Alpine_Version(EvalContext *ctx); static void Linux_Oracle_VM_Server_Version(EvalContext *ctx); static void Linux_Oracle_Version(EvalContext *ctx); static int Linux_Suse_Version(EvalContext *ctx); static int Linux_Slackware_Version(EvalContext *ctx, char *filename); static int Linux_Debian_Version(EvalContext *ctx); static int Linux_Misc_Version(EvalContext *ctx); static int Linux_Mandrake_Version(EvalContext *ctx); static int Linux_Mandriva_Version(EvalContext *ctx); static int Linux_Mandriva_Version_Real(EvalContext *ctx, char *filename, char *relstring, char *vendor); static int VM_Version(EvalContext *ctx); static int Xen_Domain(EvalContext *ctx); static int EOS_Version(EvalContext *ctx); static int MiscOS(EvalContext *ctx); static void OpenVZ_Detect(EvalContext *ctx); static bool ReadLine(const char *filename, char *buf, int bufsize); static FILE *ReadFirstLine(const char *filename, char *buf, int bufsize); #endif #ifdef XEN_CPUID_SUPPORT static void Xen_Cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); static bool Xen_Hv_Check(void); #endif static void GetCPUInfo(EvalContext *ctx); static const char *const CLASSATTRIBUTES[][3] = { [PLATFORM_CONTEXT_UNKNOWN] = {"-", "-", "-"}, /* as appear here are matched. The fields are sysname and machine */ [PLATFORM_CONTEXT_OPENVZ] = {"virt_host_vz_vzps", ".*", ".*"}, /* VZ with vzps */ [PLATFORM_CONTEXT_HP] = {"hp-ux", ".*", ".*"}, /* hpux */ [PLATFORM_CONTEXT_AIX] = {"aix", ".*", ".*"}, /* aix */ [PLATFORM_CONTEXT_LINUX] = {"linux", ".*", ".*"}, /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = {"busybox", ".*", ".*"}, /* linux w/ busybox - warning uname returns linux */ [PLATFORM_CONTEXT_SOLARIS] = {"sunos", ".*", "5\\.1[1-9].*"}, /* new solaris, SunOS >= 5.11 */ [PLATFORM_CONTEXT_SUN_SOLARIS] = {"sunos", ".*", "5\\.([2-9]|10)(\\..*)?"}, /* old solaris, SunOS < 5.11 */ [PLATFORM_CONTEXT_FREEBSD] = {"freebsd", ".*", ".*"}, /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = {"netbsd", ".*", ".*"}, /* NetBSD */ [PLATFORM_CONTEXT_CRAYOS] = {"sn.*", "cray*", ".*"}, /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = {"cygwin_nt.*", ".*", ".*"}, /* NT (cygwin) */ [PLATFORM_CONTEXT_SYSTEMV] = {"unix_sv", ".*", ".*"}, /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = {"openbsd", ".*", ".*"}, /* OpenBSD */ [PLATFORM_CONTEXT_CFSCO] = {"sco_sv", ".*", ".*"}, /* SCO */ [PLATFORM_CONTEXT_DARWIN] = {"darwin", ".*", ".*"}, /* Darwin, aka MacOS X */ [PLATFORM_CONTEXT_QNX] = {"qnx", ".*", ".*"}, /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = {"dragonfly", ".*", ".*"}, /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = {"windows_nt.*", ".*", ".*"}, /* NT (native) */ [PLATFORM_CONTEXT_VMWARE] = {"vmkernel", ".*", ".*"}, /* VMWARE / ESX */ [PLATFORM_CONTEXT_ANDROID] = {"android", ".*", ".*"}, /* android: Warning uname returns linux */ }; static const char *const VRESOLVCONF[] = { [PLATFORM_CONTEXT_UNKNOWN] = "-", [PLATFORM_CONTEXT_OPENVZ] = "/etc/resolv.conf", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/etc/resolv.conf", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/etc/resolv.conf", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/etc/resolv.conf", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "/etc/resolv.conf", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/etc/resolv.conf", /* new solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/etc/resolv.conf", /* old solaris */ [PLATFORM_CONTEXT_FREEBSD] = "/etc/resolv.conf", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/etc/resolv.conf", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/etc/resolv.conf", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "/etc/resolv.conf", /* NT */ [PLATFORM_CONTEXT_SYSTEMV] = "/etc/resolv.conf", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/etc/resolv.conf", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/etc/resolv.conf", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "/etc/resolv.conf", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/etc/resolv.conf", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/etc/resolv.conf", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "/etc/resolv.conf", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "", /* android */ }; static const char *const VMAILDIR[] = { [PLATFORM_CONTEXT_UNKNOWN] = "-", [PLATFORM_CONTEXT_OPENVZ] = "/var/spool/mail", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/var/mail", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/var/spool/mail", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/var/spool/mail", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/var/mail", /* new solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/var/mail", /* old solaris */ [PLATFORM_CONTEXT_FREEBSD] = "/var/mail", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/var/mail", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/usr/mail", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "N/A", /* NT */ [PLATFORM_CONTEXT_SYSTEMV] = "/var/mail", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/var/mail", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/var/spool/mail", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "/var/mail", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/var/spool/mail", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/var/mail", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "/var/spool/mail", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "", /* android */ }; static const char *const VEXPORTS[] = { [PLATFORM_CONTEXT_UNKNOWN] = "-", [PLATFORM_CONTEXT_OPENVZ] = "/etc/exports", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/etc/exports", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/etc/exports", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/etc/exports", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/etc/dfs/dfstab", /* new solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/etc/dfs/dfstab", /* old solaris */ [PLATFORM_CONTEXT_FREEBSD] = "/etc/exports", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/etc/exports", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/etc/exports", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "/etc/exports", /* NT */ [PLATFORM_CONTEXT_SYSTEMV] = "/etc/dfs/dfstab", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/etc/exports", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/etc/dfs/dfstab", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "/etc/exports", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/etc/exports", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/etc/exports", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "none", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "" , /* android */ }; /*******************************************************************/ void CalculateDomainName(const char *nodename, const char *dnsname, char *fqname, size_t fqname_size, char *uqname, size_t uqname_size, char *domain, size_t domain_size) { if (strstr(dnsname, ".")) { strlcpy(fqname, dnsname, fqname_size); } else { strlcpy(fqname, nodename, fqname_size); } if ((strncmp(nodename, fqname, strlen(nodename)) == 0) && (fqname[strlen(nodename)] == '.')) { /* If hostname is not qualified */ strlcpy(domain, fqname + strlen(nodename) + 1, domain_size); strlcpy(uqname, nodename, uqname_size); } else { /* If hostname is qualified */ char *p = strchr(nodename, '.'); if (p != NULL) { strlcpy(uqname, nodename, MIN(uqname_size, p - nodename + 1)); strlcpy(domain, p + 1, domain_size); } else { strlcpy(uqname, nodename, uqname_size); strlcpy(domain, "", domain_size); } } } /*******************************************************************/ void DetectDomainName(EvalContext *ctx, const char *orig_nodename) { char nodename[CF_BUFSIZE]; strlcpy(nodename, orig_nodename, sizeof(nodename)); ToLowerStrInplace(nodename); char dnsname[CF_BUFSIZE] = ""; char fqn[CF_BUFSIZE]; if (gethostname(fqn, sizeof(fqn)) != -1) { struct hostent *hp; if ((hp = gethostbyname(fqn))) { strlcpy(dnsname, hp->h_name, sizeof(dnsname)); ToLowerStrInplace(dnsname); } } nt_static_assert(sizeof(VFQNAME) > 255); nt_static_assert(sizeof(VUQNAME) > 255); nt_static_assert(sizeof(VDOMAIN) > 255); CalculateDomainName(nodename, dnsname, VFQNAME, sizeof(VFQNAME), VUQNAME, sizeof(VUQNAME), VDOMAIN, sizeof(VDOMAIN)); // Note: We don't expect hostnames or domain names above 255 // Not supported by DNS: // https://tools.ietf.org/html/rfc2181#section-11 // So let's print some warnings: if (strlen(VUQNAME) > 255) { Log(LOG_LEVEL_WARNING, "Long host name '%s' (%zu bytes) will may cause issues", VUQNAME, strlen(VUQNAME)); } if (strlen(VDOMAIN) > 255) { Log(LOG_LEVEL_WARNING, "Long domain name '%s' (%zu bytes) will may cause issues", VDOMAIN, strlen(VDOMAIN)); } /* * VFQNAME = a.b.c.d -> * NewClass("a.b.c.d") * NewClass("b.c.d") * NewClass("c.d") * NewClass("d") */ char *ptr = VFQNAME; do { EvalContextClassPutHard(ctx, ptr, "inventory,attribute_name=none,source=agent,derived-from=sys.fqhost"); ptr = strchr(ptr, '.'); if (ptr != NULL) { ptr++; } } while (ptr != NULL); EvalContextClassPutHard(ctx, VUQNAME, "source=agent,derived-from=sys.uqhost"); EvalContextClassPutHard(ctx, VDOMAIN, "source=agent,derived-from=sys.domain"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "host", nodename, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=none"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "uqhost", VUQNAME, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=none"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "fqhost", VFQNAME, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=Host name"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "domain", VDOMAIN, CF_DATA_TYPE_STRING, "source=agent"); } /*******************************************************************/ void DiscoverVersion(EvalContext *ctx) { int major = 0; int minor = 0; int patch = 0; char workbuf[CF_BUFSIZE]; if (sscanf(Version(), "%d.%d.%d", &major, &minor, &patch) == 3) { snprintf(workbuf, CF_MAXVARSIZE, "%d", major); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version_major", workbuf, CF_DATA_TYPE_STRING, "source=agent"); snprintf(workbuf, CF_MAXVARSIZE, "%d", minor); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version_minor", workbuf, CF_DATA_TYPE_STRING, "source=agent"); snprintf(workbuf, CF_MAXVARSIZE, "%d", patch); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version_patch", workbuf, CF_DATA_TYPE_STRING, "source=agent"); } else { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version_major", "BAD VERSION " VERSION, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version_minor", "BAD VERSION " VERSION, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version_patch", "BAD VERSION " VERSION, CF_DATA_TYPE_STRING, "source=agent"); } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version_release", RELEASE, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "local_libdir", "lib", CF_DATA_TYPE_STRING, "source=agent"); snprintf(workbuf, CF_BUFSIZE, "%s%cinputs%clib", GetWorkDir(), FILE_SEPARATOR, FILE_SEPARATOR); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "libdir", workbuf, CF_DATA_TYPE_STRING, "source=agent"); } static void GetNameInfo3(EvalContext *ctx) { int i; char *sp, workbuf[CF_BUFSIZE]; time_t tloc; struct hostent *hp; struct sockaddr_in cin; unsigned char digest[EVP_MAX_MD_SIZE + 1]; const char* const workdir = GetWorkDir(); const char* const bindir = GetBinDir(); #ifdef _AIX char real_version[_SYS_NMLN]; #endif #if defined(HAVE_SYSINFO) && (defined(SI_ARCHITECTURE) || defined(SI_PLATFORM)) long sz; #endif #define COMPONENTS_SIZE 17 // This is used for $(sys.cf_agent), $(sys.cf_serverd) ... : char *components[COMPONENTS_SIZE] = { "cf-twin", "cf-agent", "cf-serverd", "cf-monitord", "cf-know", "cf-report", "cf-key", "cf-runagent", "cf-execd", "cf-hub", "cf-reactor", "cf-promises", "cf-upgrade", "cf-net", "cf-check", "cf-secret", NULL }; int have_component[COMPONENTS_SIZE] = {0}; struct stat sb; char name[CF_MAXVARSIZE], quoteName[CF_MAXVARSIZE + 2], shortname[CF_MAXVARSIZE]; if (uname(&VSYSNAME) == -1) { Log(LOG_LEVEL_ERR, "Couldn't get kernel name info!. (uname: %s)", GetErrorStr()); memset(&VSYSNAME, 0, sizeof(VSYSNAME)); } #ifdef _AIX snprintf(real_version, _SYS_NMLN, "%.80s.%.80s", VSYSNAME.version, VSYSNAME.release); strlcpy(VSYSNAME.release, real_version, _SYS_NMLN); #endif #if defined(__ANDROID__) && !defined(__TERMUX__) /* * uname cannot differentiate android from linux */ strcpy(VSYSNAME.sysname, "android"); #endif #ifdef __BUSYBOX__ /* * uname cannot differentiate a busybox toolset from a normal GNU linux toolset */ strcpy(VSYSNAME.sysname, "busybox"); #endif ToLowerStrInplace(VSYSNAME.sysname); ToLowerStrInplace(VSYSNAME.machine); #ifdef _AIX switch (_system_configuration.architecture) { case POWER_RS: strlcpy(VSYSNAME.machine, "power", _SYS_NMLN); break; case POWER_PC: strlcpy(VSYSNAME.machine, "powerpc", _SYS_NMLN); break; case IA64: strlcpy(VSYSNAME.machine, "ia64", _SYS_NMLN); break; } #endif /* * solarisx86 is a historically defined class for Solaris on x86. We have to * define it manually now. */ #ifdef __sun if (strcmp(VSYSNAME.machine, "i86pc") == 0) { EvalContextClassPutHard(ctx, "solarisx86", "inventory,attribute_name=none,source=agent"); } #endif DetectDomainName(ctx, VSYSNAME.nodename); if ((tloc = time((time_t *) NULL)) == -1) { Log(LOG_LEVEL_ERR, "Couldn't read system clock"); } else { snprintf(workbuf, CF_BUFSIZE, "%jd", (intmax_t) tloc); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "systime", workbuf, CF_DATA_TYPE_INT, "time_based,source=agent"); snprintf(workbuf, CF_BUFSIZE, "%jd", (intmax_t) tloc / SECONDS_PER_DAY); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "sysday", workbuf, CF_DATA_TYPE_INT, "time_based,source=agent"); i = GetUptimeMinutes(tloc); if (i != -1) { snprintf(workbuf, CF_BUFSIZE, "%d", i); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "uptime", workbuf, CF_DATA_TYPE_INT, "inventory,time_based,source=agent,attribute_name=Uptime minutes"); } } bool found = false; for (i = 0; !found && (i < PLATFORM_CONTEXT_MAX); i++) { char sysname[CF_BUFSIZE]; strlcpy(sysname, VSYSNAME.sysname, CF_BUFSIZE); ToLowerStrInplace(sysname); /* FIXME: review those strcmps. Moved out from StringMatch */ if (!strcmp(CLASSATTRIBUTES[i][0], sysname) || StringMatchFull(CLASSATTRIBUTES[i][0], sysname)) { if (!strcmp(CLASSATTRIBUTES[i][1], VSYSNAME.machine) || StringMatchFull(CLASSATTRIBUTES[i][1], VSYSNAME.machine)) { if (!strcmp(CLASSATTRIBUTES[i][2], VSYSNAME.release) || StringMatchFull(CLASSATTRIBUTES[i][2], VSYSNAME.release)) { EvalContextClassPutHard(ctx, CLASSTEXT[i], "inventory,attribute_name=none,source=agent,derived-from=sys.class"); found = true; VSYSTEMHARDCLASS = (PlatformContext) i; VPSHARDCLASS = (PlatformContext) i; /* this one can be overriden at vz detection */ EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "class", CLASSTEXT[i], CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=Kernel"); } } else { Log(LOG_LEVEL_DEBUG, "I recognize '%s' but not '%s'", VSYSNAME.sysname, VSYSNAME.machine); continue; } } } if (!found) { i = 0; } Log(LOG_LEVEL_VERBOSE, "%s - ready", NameVersion()); Banner("Environment discovery"); snprintf(workbuf, CF_BUFSIZE, "%s", CLASSTEXT[i]); // See: cppcheck_suppressions.txt Log(LOG_LEVEL_VERBOSE, "Host name is: %s", VSYSNAME.nodename); Log(LOG_LEVEL_VERBOSE, "Operating System Type is %s", VSYSNAME.sysname); Log(LOG_LEVEL_VERBOSE, "Operating System Release is %s", VSYSNAME.release); Log(LOG_LEVEL_VERBOSE, "Architecture = %s", VSYSNAME.machine); Log(LOG_LEVEL_VERBOSE, "CFEngine detected operating system description is %s", workbuf); Log(LOG_LEVEL_VERBOSE, "The time is now %s", ctime(&tloc)); snprintf(workbuf, CF_MAXVARSIZE, "%s", ctime(&tloc)); Chop(workbuf, CF_EXPANDSIZE); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "date", workbuf, CF_DATA_TYPE_STRING, "time_based,source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cdate", CanonifyName(workbuf), CF_DATA_TYPE_STRING, "time_based,source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "os", VSYSNAME.sysname, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "release", VSYSNAME.release, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=Kernel Release"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "version", VSYSNAME.version, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "arch", VSYSNAME.machine, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=Architecture"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "workdir", workdir, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "fstab", VFSTAB[VSYSTEMHARDCLASS], CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "resolv", VRESOLVCONF[VSYSTEMHARDCLASS], CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "maildir", VMAILDIR[VSYSTEMHARDCLASS], CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "exports", VEXPORTS[VSYSTEMHARDCLASS], CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "logdir", GetLogDir(), CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "piddir", GetPidDir(), CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "statedir", GetStateDir(), CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "masterdir", GetMasterDir(), CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "inputdir", GetInputDir(), CF_DATA_TYPE_STRING, "source=agent"); snprintf(workbuf, CF_BUFSIZE, "%s", bindir); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "bindir", workbuf, CF_DATA_TYPE_STRING, "source=agent"); snprintf(workbuf, CF_BUFSIZE, "%s%cpromises.cf", GetInputDir(), FILE_SEPARATOR); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "default_policy_path", workbuf, CF_DATA_TYPE_STRING, "source=agent"); snprintf(workbuf, CF_BUFSIZE, "%s%cfailsafe.cf", GetInputDir(), FILE_SEPARATOR); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "failsafe_policy_path", workbuf, CF_DATA_TYPE_STRING, "source=agent"); snprintf(workbuf, CF_BUFSIZE, "%s%cupdate.cf", GetInputDir(), FILE_SEPARATOR); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "update_policy_path", workbuf, CF_DATA_TYPE_STRING, "source=agent"); /* FIXME: type conversion */ EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cf_version", (char *) Version(), CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=CFEngine version"); DiscoverVersion(ctx); if (PUBKEY) { char pubkey_digest[CF_HOSTKEY_STRING_SIZE] = { 0 }; HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST); HashPrintSafe(pubkey_digest, sizeof(pubkey_digest), digest, CF_DEFAULT_DIGEST, true); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "key_digest", pubkey_digest, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=CFEngine ID"); snprintf(workbuf, CF_MAXVARSIZE - 1, "PK_%s", pubkey_digest); CanonifyNameInPlace(workbuf); EvalContextClassPutHard(ctx, workbuf, "inventory,attribute_name=none,source=agent,derived-from=sys.key_digest"); } for (i = 0; components[i] != NULL; i++) { snprintf(shortname, CF_MAXVARSIZE - 1, "%s", CanonifyName(components[i])); #if defined(_WIN32) // twin has own dir, and is named agent if (i == 0) { snprintf(name, CF_MAXVARSIZE - 1, "%s-twin%ccf-agent.exe", bindir, FILE_SEPARATOR); } else { snprintf(name, CF_MAXVARSIZE - 1, "%s%c%s.exe", bindir, FILE_SEPARATOR, components[i]); } #else snprintf(name, CF_MAXVARSIZE - 1, "%s%c%s", bindir, FILE_SEPARATOR, components[i]); #endif have_component[i] = false; if (stat(name, &sb) != -1) { snprintf(quoteName, sizeof(quoteName), "\"%s\"", name); // Sets $(sys.cf_agent), $(sys.cf_serverd) $(sys.cf_execd) etc. // to their respective /bin paths EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, shortname, quoteName, CF_DATA_TYPE_STRING, "cfe_internal,source=agent"); have_component[i] = true; } } // If no twin, fail over the agent if (!have_component[0]) { snprintf(shortname, CF_MAXVARSIZE - 1, "%s", CanonifyName(components[0])); #if defined(_WIN32) snprintf(name, CF_MAXVARSIZE - 1, "%s%c%s.exe", bindir, FILE_SEPARATOR, components[1]); #else snprintf(name, CF_MAXVARSIZE - 1, "%s%c%s", bindir, FILE_SEPARATOR, components[1]); #endif if (stat(name, &sb) != -1) { snprintf(quoteName, sizeof(quoteName), "\"%s\"", name); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, shortname, quoteName, CF_DATA_TYPE_STRING, "cfe_internal,source=agent"); } } /* Windows special directories and tools */ #ifdef __MINGW32__ if (NovaWin_GetWinDir(workbuf, sizeof(workbuf))) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "windir", workbuf, CF_DATA_TYPE_STRING, "source=agent"); } if (NovaWin_GetSysDir(workbuf, sizeof(workbuf))) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "winsysdir", workbuf, CF_DATA_TYPE_STRING, "source=agent"); char filename[CF_BUFSIZE]; if (snprintf(filename, sizeof(filename), "%s%s", workbuf, "\\WindowsPowerShell\\v1.0\\powershell.exe") < sizeof(filename)) { if (NovaWin_FileExists(filename)) { EvalContextClassPutHard(ctx, "powershell", "inventory,attribute_name=none,source=agent"); Log(LOG_LEVEL_VERBOSE, "Additional hard class defined as: %s", "powershell"); } } } if (NovaWin_GetProgDir(workbuf, sizeof(workbuf))) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "winprogdir", workbuf, CF_DATA_TYPE_STRING, "source=agent"); } # ifdef _WIN64 // only available on 64 bit windows systems if (NovaWin_GetEnv("PROGRAMFILES(x86)", workbuf, sizeof(workbuf))) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "winprogdir86", workbuf, CF_DATA_TYPE_STRING, "source=agent"); } # else/* NOT _WIN64 */ EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "winprogdir86", "", CF_DATA_TYPE_STRING, "source=agent"); # endif #endif /* !__MINGW32__ */ EnterpriseContext(ctx); snprintf(workbuf, sizeof(workbuf), "%u_bit", (unsigned) sizeof(void*) * 8); EvalContextClassPutHard(ctx, workbuf, "source=agent"); Log(LOG_LEVEL_VERBOSE, "Additional hard class defined as: %s", CanonifyName(workbuf)); snprintf(workbuf, CF_BUFSIZE, "%s_%s", VSYSNAME.sysname, VSYSNAME.release); EvalContextClassPutHard(ctx, workbuf, "inventory,attribute_name=none,source=agent,derived-from=sys.sysname,derived-from=sys.release"); EvalContextClassPutHard(ctx, VSYSNAME.machine, "source=agent,derived-from=sys.machine"); Log(LOG_LEVEL_VERBOSE, "Additional hard class defined as: %s", CanonifyName(workbuf)); snprintf(workbuf, CF_BUFSIZE, "%s_%s", VSYSNAME.sysname, VSYSNAME.machine); EvalContextClassPutHard(ctx, workbuf, "source=agent,derived-from=sys.sysname,derived-from=sys.machine"); Log(LOG_LEVEL_VERBOSE, "Additional hard class defined as: %s", CanonifyName(workbuf)); snprintf(workbuf, CF_BUFSIZE, "%s_%s_%s", VSYSNAME.sysname, VSYSNAME.machine, VSYSNAME.release); EvalContextClassPutHard(ctx, workbuf, "source=agent,derived-from=sys.sysname,derived-from=sys.machine,derived-from=sys.release"); Log(LOG_LEVEL_VERBOSE, "Additional hard class defined as: %s", CanonifyName(workbuf)); #ifdef HAVE_SYSINFO # ifdef SI_ARCHITECTURE sz = sysinfo(SI_ARCHITECTURE, workbuf, CF_BUFSIZE); if (sz == -1) { Log(LOG_LEVEL_VERBOSE, "cfengine internal: sysinfo returned -1"); } else { EvalContextClassPutHard(ctx, workbuf, "inventory,attribute_name=none,source=agent"); Log(LOG_LEVEL_VERBOSE, "Additional hard class defined as: %s", workbuf); } # endif # ifdef SI_PLATFORM sz = sysinfo(SI_PLATFORM, workbuf, CF_BUFSIZE); if (sz == -1) { Log(LOG_LEVEL_VERBOSE, "cfengine internal: sysinfo returned -1"); } else { EvalContextClassPutHard(ctx, workbuf, "inventory,attribute_name=none,source=agent"); Log(LOG_LEVEL_VERBOSE, "Additional hard class defined as: %s", workbuf); } # endif #endif snprintf(workbuf, CF_BUFSIZE, "%s_%s_%s_%s", VSYSNAME.sysname, VSYSNAME.machine, VSYSNAME.release, VSYSNAME.version); if (strlen(workbuf) > CF_MAXVARSIZE - 2) { Log(LOG_LEVEL_VERBOSE, "cfengine internal: $(arch) overflows CF_MAXVARSIZE! Truncating"); } sp = xstrdup(CanonifyName(workbuf)); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "long_arch", sp, CF_DATA_TYPE_STRING, "source=agent"); EvalContextClassPutHard(ctx, sp, "source=agent,derived-from=sys.long_arch"); free(sp); snprintf(workbuf, CF_BUFSIZE, "%s_%s", VSYSNAME.sysname, VSYSNAME.machine); sp = xstrdup(CanonifyName(workbuf)); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "ostype", sp, CF_DATA_TYPE_STRING, "source=agent"); EvalContextClassPutHard(ctx, sp, "inventory,attribute_name=none,source=agent,derived-from=sys.ostype"); free(sp); if (!found) { Log(LOG_LEVEL_ERR, "I don't understand what architecture this is"); } char compile_str[] = "compiled_on_"; size_t compile_str_len = sizeof(compile_str); strcpy(workbuf, compile_str); strlcat(workbuf, CanonifyName(AUTOCONF_SYSNAME), CF_BUFSIZE - compile_str_len); EvalContextClassPutHard(ctx, workbuf, "source=agent"); Log(LOG_LEVEL_VERBOSE, "GNU autoconf class from compile time: %s", workbuf); /* Get IP address from nameserver */ if ((hp = gethostbyname(VFQNAME)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Hostname lookup failed on node name '%s'", VSYSNAME.nodename); return; } else { memset(&cin, 0, sizeof(cin)); cin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr; Log(LOG_LEVEL_VERBOSE, "Address given by nameserver: %s", inet_ntoa(cin.sin_addr)); strcpy(VIPADDRESS, inet_ntoa(cin.sin_addr)); for (i = 0; hp->h_aliases[i] != NULL; i++) { Log(LOG_LEVEL_DEBUG, "Adding alias '%s'", hp->h_aliases[i]); EvalContextClassPutHard(ctx, hp->h_aliases[i], "inventory,attribute_name=none,source=agent,based-on=sys.fqhost"); } } #ifdef HAVE_GETZONEID zoneid_t zid; char zone[ZONENAME_MAX]; char vbuff[CF_BUFSIZE]; zid = getzoneid(); getzonenamebyid(zid, zone, ZONENAME_MAX); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "zone", zone, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=Solaris zone"); snprintf(vbuff, CF_BUFSIZE - 1, "zone_%s", zone); EvalContextClassPutHard(ctx, vbuff, "source=agent,derived-from=sys.zone"); if (strcmp(zone, "global") == 0) { Log(LOG_LEVEL_VERBOSE, "CFEngine seems to be running inside a global solaris zone of name '%s'", zone); } else { Log(LOG_LEVEL_VERBOSE, "CFEngine seems to be running inside a local solaris zone of name '%s'", zone); } #endif } /*******************************************************************/ void LoadSlowlyVaryingObservations(EvalContext *ctx) { CF_DB *dbp; CF_DBC *dbcp; char *key; void *stored; int ksize, vsize; if (!OpenDB(&dbp, dbid_static)) { return; } /* Acquire a cursor for the database. */ if (!NewDBCursor(dbp, &dbcp)) { Log(LOG_LEVEL_INFO, "Unable to scan class db"); CloseDB(dbp); return; } while (NextDB(dbcp, &key, &ksize, &stored, &vsize)) { if (key == NULL || stored == NULL) { continue; } char lval[1024]; int type_i; int ret = sscanf(key, "%1023[^:]:%d", lval, &type_i); if (ret == 2) { DataType type = type_i; switch (type) { case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_MON, lval, stored, type, "monitoring,source=observation"); break; case CF_DATA_TYPE_STRING_LIST: { Rlist *list = RlistFromSplitString(stored, ','); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_MON, lval, list, CF_DATA_TYPE_STRING_LIST, "monitoring,source=observation"); RlistDestroy(list); break; } case CF_DATA_TYPE_COUNTER: EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_MON, lval, stored, CF_DATA_TYPE_STRING, "monitoring,source=observation"); break; default: Log(LOG_LEVEL_ERR, "Unexpected monitoring type %d found in dbid_static database", (int) type); } } } DeleteDBCursor(dbcp); CloseDB(dbp); } static void Get3Environment(EvalContext *ctx) { char env[CF_BUFSIZE], context[CF_BUFSIZE], name[CF_MAXVARSIZE], value[CF_BUFSIZE]; struct stat statbuf; time_t now = time(NULL); Log(LOG_LEVEL_VERBOSE, "Looking for environment from cf-monitord..."); snprintf(env, CF_BUFSIZE, "%s/%s", GetStateDir(), CF_ENV_FILE); MapName(env); FILE *fp = safe_fopen(env, "r"); if (fp == NULL) { Log(LOG_LEVEL_VERBOSE, "Unable to detect environment from cf-monitord"); return; } int fd = fileno(fp); if (fstat(fd, &statbuf) == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to detect environment from cf-monitord"); fclose(fp); return; } if (statbuf.st_mtime < (now - 60 * 60)) { Log(LOG_LEVEL_VERBOSE, "Environment data are too old - discarding"); unlink(env); fclose(fp); return; } snprintf(value, CF_MAXVARSIZE - 1, "%s", ctime(&statbuf.st_mtime)); if (Chop(value, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_MON, "env_time", value, CF_DATA_TYPE_STRING, "time_based,source=agent"); Log(LOG_LEVEL_VERBOSE, "Loading environment..."); for(;;) { name[0] = '\0'; value[0] = '\0'; if (fgets(context, sizeof(context), fp) == NULL) { if (ferror(fp)) { UnexpectedError("Failed to read line from stream"); break; } else /* feof */ { break; } } if (*context == '@') { nt_static_assert((sizeof(name)) > 255); nt_static_assert((sizeof(value)) > 255); if (sscanf(context + 1, "%255[^=]=%255[^\n]", name, value) == 2) { Log(LOG_LEVEL_DEBUG, "Setting new monitoring list '%s' => '%s'", name, value); Rlist *list = RlistParseShown(value); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_MON, name, list, CF_DATA_TYPE_STRING_LIST, "monitoring,source=environment"); RlistDestroy(list); } else { Log(LOG_LEVEL_ERR, "Failed to parse '%s' as '@variable=list' monitoring list", context); } } else if (strchr(context, '=')) { nt_static_assert((sizeof(name)) > 255); nt_static_assert((sizeof(value)) > 255); if (sscanf(context, "%255[^=]=%255[^\n]", name, value) == 2) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_MON, name, value, CF_DATA_TYPE_STRING, "monitoring,source=environment"); Log(LOG_LEVEL_DEBUG, "Setting new monitoring scalar '%s' => '%s'", name, value); } else { Log(LOG_LEVEL_ERR, "Failed to parse '%s' as 'variable=value' monitoring scalar", context); } } else { StripTrailingNewline(context, CF_BUFSIZE); EvalContextClassPutHard(ctx, context, "monitoring,source=environment"); } } fclose(fp); Log(LOG_LEVEL_VERBOSE, "Environment data loaded"); LoadSlowlyVaryingObservations(ctx); } static void BuiltinClasses(EvalContext *ctx) { char vbuff[CF_BUFSIZE]; EvalContextClassPutHard(ctx, "any", "source=agent"); /* This is a reserved word / wildcard */ snprintf(vbuff, CF_BUFSIZE, "cfengine_%s", CanonifyName(Version())); CreateHardClassesFromCanonification(ctx, vbuff, "inventory,attribute_name=none,source=agent"); CreateHardClassesFromFeatures(ctx, "source=agent"); } /*******************************************************************/ void CreateHardClassesFromCanonification(EvalContext *ctx, const char *canonified, char *tags) { char buf[CF_MAXVARSIZE]; strlcpy(buf, canonified, sizeof(buf)); EvalContextClassPutHard(ctx, buf, tags); char *sp; while ((sp = strrchr(buf, '_'))) { *sp = 0; EvalContextClassPutHard(ctx, buf, tags); } } static void SetFlavor(EvalContext *ctx, const char *flavor) { EvalContextClassPutHard(ctx, flavor, "inventory,attribute_name=none,source=agent,derived-from=sys.flavor"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "flavour", flavor, CF_DATA_TYPE_STRING, "source=agent"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "flavor", flavor, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=none"); } #if defined __linux__ || __MINGW32__ /** * @brief Combines OS and version string to define flavor variable and class * * @note Input strings should be canonified before calling */ static void SetFlavor2( EvalContext *const ctx, const char *const id, const char *const major_version) { assert(ctx != NULL); assert(id != NULL); assert(major_version != NULL); char *flavor; xasprintf(&flavor, "%s_%s", id, major_version); SetFlavor(ctx, flavor); free(flavor); } #endif #ifdef __linux__ /** * @brief Combines OS and version string to define multiple hard classes * * @note Input strings should be canonified before calling */ static void DefineVersionedHardClasses( EvalContext *const ctx, const char *const tags, const char *const id, const char *const version) { assert(ctx != NULL); assert(id != NULL); assert(version != NULL); char *class; xasprintf(&class, "%s_%s", id, version); // Strip away version number to define multiple hard classes // Example: coreos_1185_3_0 -> coreos_1185_3 -> coreos_1185 -> coreos char *last_underscore = strrchr(class, '_'); while ( last_underscore != NULL ) { EvalContextClassPutHard(ctx, class, tags); *last_underscore = '\0'; last_underscore = strrchr(class, '_'); } EvalContextClassPutHard(ctx, class, tags); free(class); } static void OSReleaseParse(EvalContext *ctx, const char *file_path) { JsonElement *os_release_json = JsonReadDataFile("system info discovery", file_path, DATAFILETYPE_ENV, 100 * 1024); if (os_release_json != NULL) { char *tags; xasprintf(&tags, "inventory,attribute_name=none,source=agent,derived-from-file=%s", file_path); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "os_release", os_release_json, CF_DATA_TYPE_CONTAINER, tags); const char *const_os_release_id = JsonObjectGetAsString(os_release_json, "ID"); const char *const_os_release_version_id = JsonObjectGetAsString(os_release_json, "VERSION_ID"); char *os_release_id = SafeStringDuplicate(const_os_release_id); char *os_release_version_id = SafeStringDuplicate(const_os_release_version_id); if (os_release_id != NULL) { CanonifyNameInPlace(os_release_id); const char *alias = NULL; if (StringEqual(os_release_id, "rhel")) { alias = "redhat"; } else if (StringEqual(os_release_id, "opensuse") || StringEqual(os_release_id, "sles")) { alias = "suse"; } if (os_release_version_id == NULL) { // if VERSION_ID doesn't exist, define only one hard class: EvalContextClassPutHard(ctx, os_release_id, tags); if (alias != NULL) { EvalContextClassPutHard(ctx, alias, tags); } } else // if VERSION_ID exists set flavor and multiple hard classes: { CanonifyNameInPlace(os_release_version_id); // Set the flavor to be ID + major version (derived from VERSION_ID) char *first_underscore = strchr(os_release_version_id, '_'); if (first_underscore != NULL) { // Temporarily modify os_release_version_id to be major version *first_underscore = '\0'; SetFlavor2(ctx, os_release_id, os_release_version_id); *first_underscore = '_'; } else { SetFlavor2(ctx, os_release_id, os_release_version_id); } // One of the hard classes is already set by SetFlavor // but it seems excessive to try to skip this: DefineVersionedHardClasses(ctx, tags, os_release_id, os_release_version_id); if (alias != NULL) { DefineVersionedHardClasses(ctx, tags, alias, os_release_version_id); } } } free(os_release_version_id); free(os_release_id); free(tags); JsonDestroy(os_release_json); } } #endif static void OSClasses(EvalContext *ctx) { #ifdef __linux__ /* First we check if init process is systemd, and set "systemd" hard class. */ { char init_path[CF_BUFSIZE]; if (ReadLine("/proc/1/cmdline", init_path, sizeof(init_path))) { /* Follow possible symlinks. */ char resolved_path[PATH_MAX]; /* realpath() needs PATH_MAX */ if (realpath(init_path, resolved_path) != NULL && strlen(resolved_path) < sizeof(init_path)) { strcpy(init_path, resolved_path); } /* Check if string ends with "/systemd". */ char *p; char *next_p = NULL; const char *term = "/systemd"; do { p = next_p; next_p = strstr(next_p ? next_p+strlen(term) : init_path, term); } while (next_p); if (p != NULL && p[strlen("/systemd")] == '\0') { EvalContextClassPutHard(ctx, "systemd", "inventory,attribute_name=none,source=agent"); } } } struct stat statbuf; // os-release is used to set sys.os_release, sys.flavor and hard classes if (access("/etc/os-release", R_OK) != -1) { OSReleaseParse(ctx, "/etc/os-release"); } else if (access("/usr/lib/os-release", R_OK) != -1) { OSReleaseParse(ctx, "/usr/lib/os-release"); } /* Mandrake/Mandriva, Fedora and Oracle VM Server supply /etc/redhat-release, so we test for those distributions first */ if (stat("/etc/mandriva-release", &statbuf) != -1) { Linux_Mandriva_Version(ctx); } else if (stat("/etc/mandrake-release", &statbuf) != -1) { Linux_Mandrake_Version(ctx); } else if (stat("/etc/fedora-release", &statbuf) != -1) { Linux_Fedora_Version(ctx); } else if (stat("/etc/ovs-release", &statbuf) != -1) { Linux_Oracle_VM_Server_Version(ctx); } else if (stat("/etc/redhat-release", &statbuf) != -1) { Linux_Redhat_Version(ctx); } /* Oracle Linux >= 6 supplies separate /etc/oracle-release alongside /etc/redhat-release, use it to precisely identify version */ if (stat("/etc/oracle-release", &statbuf) != -1) { Linux_Oracle_Version(ctx); } if (stat("/etc/generic-release", &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "This appears to be a sun cobalt system."); SetFlavor(ctx, "SunCobalt"); } if (stat("/etc/SuSE-release", &statbuf) != -1) { Linux_Suse_Version(ctx); } if (stat("/etc/system-release", &statbuf) != -1) { Linux_Amazon_Version(ctx); } # define SLACKWARE_ANCIENT_VERSION_FILENAME "/etc/slackware-release" # define SLACKWARE_VERSION_FILENAME "/etc/slackware-version" if (stat(SLACKWARE_VERSION_FILENAME, &statbuf) != -1) { Linux_Slackware_Version(ctx, SLACKWARE_VERSION_FILENAME); } else if (stat(SLACKWARE_ANCIENT_VERSION_FILENAME, &statbuf) != -1) { Linux_Slackware_Version(ctx, SLACKWARE_ANCIENT_VERSION_FILENAME); } if (stat(DEBIAN_VERSION_FILENAME, &statbuf) != -1) { Linux_Debian_Version(ctx); } if (stat(LSB_RELEASE_FILENAME, &statbuf) != -1) { Linux_Misc_Version(ctx); } if (stat("/usr/bin/aptitude", &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "This system seems to have the aptitude package system"); EvalContextClassPutHard(ctx, "have_aptitude", "inventory,attribute_name=none,source=agent"); } if (stat("/etc/UnitedLinux-release", &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "This appears to be a UnitedLinux system."); SetFlavor(ctx, "UnitedLinux"); } if (stat("/etc/alpine-release", &statbuf) != -1) { Linux_Alpine_Version(ctx); } if (stat("/etc/gentoo-release", &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "This appears to be a gentoo system."); SetFlavor(ctx, "gentoo"); } if (stat("/etc/arch-release", &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "This appears to be an Arch Linux system."); SetFlavor(ctx, "archlinux"); } if (stat("/proc/vmware/version", &statbuf) != -1 || stat("/etc/vmware-release", &statbuf) != -1) { VM_Version(ctx); } else if (stat("/etc/vmware", &statbuf) != -1 && S_ISDIR(statbuf.st_mode)) { VM_Version(ctx); } if (stat("/proc/xen/capabilities", &statbuf) != -1) { Xen_Domain(ctx); } if (stat("/etc/Eos-release", &statbuf) != -1) { EOS_Version(ctx); SetFlavor(ctx, "Eos"); } if (stat("/etc/issue", &statbuf) != -1) { MiscOS(ctx); } if (stat("/proc/self/status", &statbuf) != -1) { OpenVZ_Detect(ctx); } #else char vbuff[CF_MAXVARSIZE]; #ifdef _AIX strlcpy(vbuff, VSYSNAME.version, CF_MAXVARSIZE); #else strlcpy(vbuff, VSYSNAME.release, CF_MAXVARSIZE); #endif for (char *sp = vbuff; *sp != '\0'; sp++) { if (*sp == '-') { *sp = '\0'; break; } } char context[CF_BUFSIZE]; snprintf(context, CF_BUFSIZE, "%s_%s", VSYSNAME.sysname, vbuff); SetFlavor(ctx, context); #ifdef __hpux /* * Define a hard class with just the version major number of HP-UX * * For example, when being run on HP-UX B.11.23 the following class will * be defined: hpux_11 */ // Extract major version number char *major = NULL; for (char *sp = vbuff; *sp != '\0'; sp++) { if (major == NULL && isdigit(*sp)) { major = sp; } else if (!isdigit(*sp)) { *sp = '\0'; } } if (major != NULL) { snprintf(context, CF_BUFSIZE, "hpux_%s", major); EvalContextClassPutHard(ctx, context, "source=agent,derived-from=sys.flavor"); } #endif #ifdef __FreeBSD__ /* * Define a hard class with just the version major number on FreeBSD * * For example, when being run on either FreeBSD 10.0 or 10.1 a class * called freebsd_10 will be defined */ for (char *sp = vbuff; *sp != '\0'; sp++) { if (*sp == '.') { *sp = '\0'; break; } } snprintf(context, CF_BUFSIZE, "%s_%s", VSYSNAME.sysname, vbuff); EvalContextClassPutHard(ctx, context, "source=agent,derived-from=sys.flavor"); #endif #endif #ifdef XEN_CPUID_SUPPORT if (Xen_Hv_Check()) { Log(LOG_LEVEL_VERBOSE, "This appears to be a xen hv system."); EvalContextClassPutHard(ctx, "xen", "inventory,attribute_name=Virtual host,source=agent"); EvalContextClassPutHard(ctx, "xen_domu_hv", "source=agent"); } #endif /* XEN_CPUID_SUPPORT */ GetCPUInfo(ctx); #ifdef __CYGWIN__ for (char *sp = VSYSNAME.sysname; *sp != '\0'; sp++) { if (*sp == '-') { sp++; if (strncmp(sp, "5.0", 3) == 0) { Log(LOG_LEVEL_VERBOSE, "This appears to be Windows 2000"); EvalContextClassPutHard(ctx, "Win2000", "inventory,attribute_name=none,source=agent"); } if (strncmp(sp, "5.1", 3) == 0) { Log(LOG_LEVEL_VERBOSE, "This appears to be Windows XP"); EvalContextClassPutHard(ctx, "WinXP", "inventory,attribute_name=none,source=agent"); } if (strncmp(sp, "5.2", 3) == 0) { Log(LOG_LEVEL_VERBOSE, "This appears to be Windows Server 2003"); EvalContextClassPutHard(ctx, "WinServer2003", "inventory,attribute_name=none,source=agent"); } if (strncmp(sp, "6.1", 3) == 0) { Log(LOG_LEVEL_VERBOSE, "This appears to be Windows Vista"); EvalContextClassPutHard(ctx, "WinVista", "inventory,attribute_name=none,source=agent"); } if (strncmp(sp, "6.3", 3) == 0) { Log(LOG_LEVEL_VERBOSE, "This appears to be Windows Server 2008"); EvalContextClassPutHard(ctx, "WinServer2008", "inventory,attribute_name=none,source=agent"); } } } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "crontab", "", CF_DATA_TYPE_STRING, "source=agent"); #endif /* __CYGWIN__ */ #ifdef __MINGW32__ EvalContextClassPutHard(ctx, VSYSNAME.release, "inventory,attribute_name=none,source=agent,derived-from=sys.release"); // code name - e.g. Windows Vista EvalContextClassPutHard(ctx, VSYSNAME.version, "inventory,attribute_name=none,source=agent,derived-from=sys.version"); // service pack number - e.g. Service Pack 3 if (strstr(VSYSNAME.sysname, "workstation")) { EvalContextClassPutHard(ctx, "WinWorkstation", "inventory,attribute_name=Windows roles,source=agent,derived-from=sys.sysname"); } else if (strstr(VSYSNAME.sysname, "server")) { EvalContextClassPutHard(ctx, "WinServer", "inventory,attribute_name=Windows roles,source=agent,derived-from=sys.sysname"); } else if (strstr(VSYSNAME.sysname, "domain controller")) { EvalContextClassPutHard(ctx, "DomainController", "inventory,attribute_name=Windows roles,source=agent,derived-from=sys.sysname"); EvalContextClassPutHard(ctx, "WinServer", "inventory,attribute_name=Windows roles,source=agent,derived-from=sys.sysname"); } else { EvalContextClassPutHard(ctx, "unknown_ostype", "source=agent,derived-from=sys.sysname"); } char *release = SafeStringDuplicate(VSYSNAME.release); char *major = NULL; FindNextInteger(release, &major); if (NULL_OR_EMPTY(major)) { SetFlavor(ctx, "windows"); } else { SetFlavor2(ctx, "windows", major); } free(release); #endif /* __MINGW32__ */ #ifndef _WIN32 char user_name[CF_SMALLBUF]; if (GetCurrentUserName(user_name, sizeof(user_name))) { char vbuff[CF_BUFSIZE]; if (EvalContextClassGet(ctx, NULL, "SUSE")) { snprintf(vbuff, CF_BUFSIZE, "/var/spool/cron/tabs/%s", user_name); } else if (EvalContextClassGet(ctx, NULL, "redhat")) { snprintf(vbuff, CF_BUFSIZE, "/var/spool/cron/%s", user_name); } else if (EvalContextClassGet(ctx, NULL, "freebsd")) { snprintf(vbuff, CF_BUFSIZE, "/var/cron/tabs/%s", user_name); } else { snprintf(vbuff, CF_BUFSIZE, "/var/spool/cron/crontabs/%s", user_name); } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "crontab", vbuff, CF_DATA_TYPE_STRING, "source=agent"); } #endif #if defined(__ANDROID__) SetFlavor(ctx, "android"); #endif /* termux flavor should over-ride android flavor */ #if defined(__TERMUX__) SetFlavor(ctx, "termux"); #endif #ifdef __sun if (StringMatchFull("joyent.*", VSYSNAME.version)) { EvalContextClassPutHard(ctx, "smartos", "inventory,attribute_name=none,source=agent,derived-from=sys.version"); EvalContextClassPutHard(ctx, "smartmachine", "source=agent,derived-from=sys.version"); } #endif /* FIXME: this variable needs redhat/SUSE/debian classes to be defined and * hence can't be initialized earlier */ if (EvalContextClassGet(ctx, NULL, "redhat")) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "doc_root", "/var/www/html", CF_DATA_TYPE_STRING, "source=agent"); } if (EvalContextClassGet(ctx, NULL, "SUSE")) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "doc_root", "/srv/www/htdocs", CF_DATA_TYPE_STRING, "source=agent"); } if (EvalContextClassGet(ctx, NULL, "debian")) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "doc_root", "/var/www", CF_DATA_TYPE_STRING, "source=agent"); } } /*********************************************************************************/ #ifdef __linux__ static void Linux_Oracle_VM_Server_Version(EvalContext *ctx) { char relstring[CF_MAXVARSIZE]; char *r; int major, minor, patch; int revcomps; #define ORACLE_VM_SERVER_REL_FILENAME "/etc/ovs-release" #define ORACLE_VM_SERVER_ID "Oracle VM server" Log(LOG_LEVEL_VERBOSE, "This appears to be Oracle VM Server"); EvalContextClassPutHard(ctx, "redhat", "inventory,attribute_name=none,source=agent"); EvalContextClassPutHard(ctx, "oraclevmserver", "inventory,attribute_name=Virtual host,source=agent"); if (!ReadLine(ORACLE_VM_SERVER_REL_FILENAME, relstring, sizeof(relstring))) { return; } if (strncmp(relstring, ORACLE_VM_SERVER_ID, strlen(ORACLE_VM_SERVER_ID))) { Log(LOG_LEVEL_VERBOSE, "Could not identify distribution from %s", ORACLE_VM_SERVER_REL_FILENAME); return; } if ((r = strstr(relstring, "release ")) == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find distribution version in %s", ORACLE_VM_SERVER_REL_FILENAME); return; } revcomps = sscanf(r + strlen("release "), "%d.%d.%d", &major, &minor, &patch); if (revcomps > 0) { char buf[CF_BUFSIZE]; snprintf(buf, CF_BUFSIZE, "oraclevmserver_%d", major); SetFlavor(ctx, buf); } if (revcomps > 1) { char buf[CF_BUFSIZE]; snprintf(buf, CF_BUFSIZE, "oraclevmserver_%d_%d", major, minor); EvalContextClassPutHard(ctx, buf, "inventory,attribute_name=none,source=agent"); } if (revcomps > 2) { char buf[CF_BUFSIZE]; snprintf(buf, CF_BUFSIZE, "oraclevmserver_%d_%d_%d", major, minor, patch); EvalContextClassPutHard(ctx, buf, "inventory,attribute_name=none,source=agent"); } } /*********************************************************************************/ static void Linux_Oracle_Version(EvalContext *ctx) { char relstring[CF_MAXVARSIZE]; char *r; int major, minor; #define ORACLE_REL_FILENAME "/etc/oracle-release" #define ORACLE_ID "Oracle Linux Server" Log(LOG_LEVEL_VERBOSE, "This appears to be Oracle Linux"); EvalContextClassPutHard(ctx, "oracle", "inventory,attribute_name=none,source=agent"); if (!ReadLine(ORACLE_REL_FILENAME, relstring, sizeof(relstring))) { return; } if (strncmp(relstring, ORACLE_ID, strlen(ORACLE_ID))) { Log(LOG_LEVEL_VERBOSE, "Could not identify distribution from %s", ORACLE_REL_FILENAME); return; } if ((r = strstr(relstring, "release ")) == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find distribution version in %s", ORACLE_REL_FILENAME); return; } if (sscanf(r + strlen("release "), "%d.%d", &major, &minor) == 2) { char buf[CF_BUFSIZE]; snprintf(buf, CF_BUFSIZE, "oracle_%d", major); SetFlavor(ctx, buf); snprintf(buf, CF_BUFSIZE, "oracle_%d_%d", major, minor); EvalContextClassPutHard(ctx, buf, "inventory,attribute_name=none,source=agent"); } } /*********************************************************************************/ static int Linux_Fedora_Version(EvalContext *ctx) { #define FEDORA_ID "Fedora" #define RELEASE_FLAG "release " /* We are looking for one of the following strings... * * Fedora Core release 1 (Yarrow) * Fedora release 7 (Zodfoobar) */ #define FEDORA_REL_FILENAME "/etc/fedora-release" /* The full string read in from fedora-release */ char relstring[CF_MAXVARSIZE]; Log(LOG_LEVEL_VERBOSE, "This appears to be a fedora system."); EvalContextClassPutHard(ctx, "redhat", "inventory,attribute_name=none,source=agent"); EvalContextClassPutHard(ctx, "fedora", "inventory,attribute_name=none,source=agent"); /* Grab the first line from the file and then close it. */ if (!ReadLine(FEDORA_REL_FILENAME, relstring, sizeof(relstring))) { return 1; } Log(LOG_LEVEL_VERBOSE, "Looking for fedora core linux info..."); char *vendor = ""; if (!strncmp(relstring, FEDORA_ID, strlen(FEDORA_ID))) { vendor = "fedora"; } else { Log(LOG_LEVEL_VERBOSE, "Could not identify OS distro from %s", FEDORA_REL_FILENAME); return 2; } /* Now, grok the release. We assume that all the strings will * have the word 'release' before the numerical release. */ int major = -1; char strmajor[PRINTSIZE(major)]; char *release = strstr(relstring, RELEASE_FLAG); if (release == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find a numeric OS release in %s", FEDORA_REL_FILENAME); return 2; } else { release += strlen(RELEASE_FLAG); strmajor[0] = '\0'; if (sscanf(release, "%d", &major) != 0) { xsnprintf(strmajor, sizeof(strmajor), "%d", major); } } if (major != -1 && vendor[0] != '\0') { char classbuf[CF_MAXVARSIZE]; classbuf[0] = '\0'; strcat(classbuf, vendor); EvalContextClassPutHard(ctx,classbuf, "inventory,attribute_name=none,source=agent"); strcat(classbuf, "_"); strcat(classbuf, strmajor); SetFlavor(ctx, classbuf); } return 0; } /*********************************************************************************/ static int Linux_Redhat_Version(EvalContext *ctx) { #define REDHAT_ID "Red Hat Linux" #define REDHAT_ENT_ID "Red Hat Enterprise Linux" #define REDHAT_AS_ID "Red Hat Enterprise Linux AS" #define REDHAT_AS21_ID "Red Hat Linux Advanced Server" #define REDHAT_ES_ID "Red Hat Enterprise Linux ES" #define REDHAT_WS_ID "Red Hat Enterprise Linux WS" #define REDHAT_C_ID "Red Hat Enterprise Linux Client" #define REDHAT_S_ID "Red Hat Enterprise Linux Server" #define REDHAT_W_ID "Red Hat Enterprise Linux Workstation" #define REDHAT_CN_ID "Red Hat Enterprise Linux ComputeNode" #define MANDRAKE_ID "Linux Mandrake" #define MANDRAKE_10_1_ID "Mandrakelinux" #define WHITEBOX_ID "White Box Enterprise Linux" #define CENTOS_ID "CentOS" #define SCIENTIFIC_SL_ID "Scientific Linux SL" #define SCIENTIFIC_SL6_ID "Scientific Linux" #define SCIENTIFIC_CERN_ID "Scientific Linux CERN" #define RELEASE_FLAG "release " #define ORACLE_4_5_ID "Enterprise Linux Enterprise Linux Server" /* We are looking for one of the following strings... * * Red Hat Linux release 6.2 (Zoot) * Red Hat Enterprise Linux release 8.0 (Ootpa) * Red Hat Linux Advanced Server release 2.1AS (Pensacola) * Red Hat Enterprise Linux AS release 3 (Taroon) * Red Hat Enterprise Linux WS release 3 (Taroon) * Red Hat Enterprise Linux Client release 5 (Tikanga) * Red Hat Enterprise Linux Server release 5 (Tikanga) * Linux Mandrake release 7.1 (helium) * Red Hat Enterprise Linux ES release 2.1 (Panama) * White Box Enterprise linux release 3.0 (Liberation) * Scientific Linux SL Release 4.0 (Beryllium) * CentOS release 4.0 (Final) */ #define RH_REL_FILENAME "/etc/redhat-release" Log(LOG_LEVEL_VERBOSE, "This appears to be a redhat (or redhat-based) system."); EvalContextClassPutHard(ctx, "redhat", "inventory,attribute_name=none,source=agent,derived-from-file="RH_REL_FILENAME); /* Grab the first line from the file and then close it. */ char relstring[CF_MAXVARSIZE]; if (!ReadLine(RH_REL_FILENAME, relstring, sizeof(relstring))) { return 1; } Log(LOG_LEVEL_VERBOSE, "Looking for redhat linux info in '%s'", relstring); /* First, try to grok the vendor and edition (if any) */ char *edition = ""; /* as (Advanced Server, Enterprise) */ char *vendor = ""; /* Red Hat, Mandrake */ if (!strncmp(relstring, REDHAT_ES_ID, strlen(REDHAT_ES_ID))) { vendor = "redhat"; edition = "es"; } else if (!strncmp(relstring, REDHAT_WS_ID, strlen(REDHAT_WS_ID))) { vendor = "redhat"; edition = "ws"; } else if (!strncmp(relstring, REDHAT_WS_ID, strlen(REDHAT_WS_ID))) { vendor = "redhat"; edition = "ws"; } else if (!strncmp(relstring, REDHAT_AS_ID, strlen(REDHAT_AS_ID)) || !strncmp(relstring, REDHAT_AS21_ID, strlen(REDHAT_AS21_ID))) { vendor = "redhat"; edition = "as"; } else if (!strncmp(relstring, REDHAT_S_ID, strlen(REDHAT_S_ID))) { vendor = "redhat"; edition = "s"; } else if (!strncmp(relstring, REDHAT_C_ID, strlen(REDHAT_C_ID)) || !strncmp(relstring, REDHAT_W_ID, strlen(REDHAT_W_ID))) { vendor = "redhat"; edition = "c"; } else if (!strncmp(relstring, REDHAT_CN_ID, strlen(REDHAT_CN_ID))) { vendor = "redhat"; edition = "cn"; } else if (!strncmp(relstring, REDHAT_ID, strlen(REDHAT_ID))) { vendor = "redhat"; } else if (!strncmp(relstring, REDHAT_ENT_ID, strlen(REDHAT_ENT_ID))) { vendor = "redhat"; } else if (!strncmp(relstring, MANDRAKE_ID, strlen(MANDRAKE_ID))) { vendor = "mandrake"; } else if (!strncmp(relstring, MANDRAKE_10_1_ID, strlen(MANDRAKE_10_1_ID))) { vendor = "mandrake"; } else if (!strncmp(relstring, WHITEBOX_ID, strlen(WHITEBOX_ID))) { vendor = "whitebox"; } else if (!strncmp(relstring, SCIENTIFIC_SL_ID, strlen(SCIENTIFIC_SL_ID))) { vendor = "scientific"; edition = "sl"; } else if (!strncmp(relstring, SCIENTIFIC_CERN_ID, strlen(SCIENTIFIC_CERN_ID))) { vendor = "scientific"; edition = "cern"; } else if (!strncmp(relstring, SCIENTIFIC_SL6_ID, strlen(SCIENTIFIC_SL6_ID))) { vendor = "scientific"; edition = "sl"; } else if (!strncmp(relstring, CENTOS_ID, strlen(CENTOS_ID))) { vendor = "centos"; } else if (!strncmp(relstring, ORACLE_4_5_ID, strlen(ORACLE_4_5_ID))) { vendor = "oracle"; edition = "s"; } else { Log(LOG_LEVEL_VERBOSE, "Could not identify OS distro from %s", RH_REL_FILENAME); return 2; } /* Now, grok the release. For AS, we neglect the AS at the end of the * numerical release because we already figured out that it *is* AS * from the information above. We assume that all the strings will * have the word 'release' before the numerical release. */ /* Convert relstring to lowercase so that vendors like Scientific Linux don't fall through the cracks. */ for (size_t i = 0; i < strlen(relstring); i++) { relstring[i] = tolower(relstring[i]); } /* Where the numerical release will be found */ int major = -1, minor = -1; char strmajor[PRINTSIZE(major)], strminor[PRINTSIZE(minor)]; char *release = strstr(relstring, RELEASE_FLAG); if (release == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find a numeric OS release in %s", RH_REL_FILENAME); return 2; } else { release += strlen(RELEASE_FLAG); if (sscanf(release, "%d.%d", &major, &minor) == 2) { xsnprintf(strmajor, sizeof(strmajor), "%d", major); xsnprintf(strminor, sizeof(strminor), "%d", minor); } /* red hat 9 is *not* red hat 9.0. * and same thing with RHEL AS 3 */ else if (sscanf(release, "%d", &major) == 1) { xsnprintf(strmajor, sizeof(strmajor), "%d", major); minor = -2; } } char classbuf[CF_MAXVARSIZE]; if (major != -1 && minor != -1 && (strcmp(vendor, "") != 0)) { classbuf[0] = '\0'; strcat(classbuf, vendor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent,derived-from-file="RH_REL_FILENAME); strcat(classbuf, "_"); if (strcmp(edition, "") != 0) { strcat(classbuf, edition); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent,derived-from-file="RH_REL_FILENAME); strcat(classbuf, "_"); } strcat(classbuf, strmajor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent,derived-from-file="RH_REL_FILENAME); if (minor != -2) { strcat(classbuf, "_"); strcat(classbuf, strminor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent,derived-from-file="RH_REL_FILENAME); } } // Now a version without the edition if (major != -1 && minor != -1 && vendor[0] != '\0') { classbuf[0] = '\0'; strcat(classbuf, vendor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent,derived-from-file="RH_REL_FILENAME); strcat(classbuf, "_"); strcat(classbuf, strmajor); SetFlavor(ctx, classbuf); if (minor != -2) { strcat(classbuf, "_"); strcat(classbuf, strminor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent,derived-from-file="RH_REL_FILENAME); } } return 0; } /******************************************************************/ static int Linux_Suse_Version(EvalContext *ctx) { #define SUSE_REL_FILENAME "/etc/SuSE-release" /* Check if it's a SUSE Enterprise version (all in lowercase) */ #define SUSE_SLES8_ID "suse sles-8" #define SUSE_SLES_ID "suse linux enterprise server" #define SUSE_SLED_ID "suse linux enterprise desktop" #define SUSE_RELEASE_FLAG "linux " char classbuf[CF_MAXVARSIZE]; Log(LOG_LEVEL_VERBOSE, "This appears to be a SUSE system."); EvalContextClassPutHard(ctx, "SUSE", "inventory,attribute_name=none,source=agent"); EvalContextClassPutHard(ctx, "suse", "inventory,attribute_name=none,source=agent"); /* The correct spelling for SUSE is "SUSE" but CFEngine used to use "SuSE". * Keep this for backwards compatibility until CFEngine 3.7 */ EvalContextClassPutHard(ctx, "SuSE", "inventory,attribute_name=none,source=agent"); /* Grab the first line from the SuSE-release file and then close it. */ char relstring[CF_MAXVARSIZE]; FILE *fp = ReadFirstLine(SUSE_REL_FILENAME, relstring, sizeof(relstring)); if (fp == NULL) { return 1; } char vbuf[CF_BUFSIZE], strversion[CF_MAXVARSIZE], strpatch[CF_MAXVARSIZE]; strversion[0] = '\0'; strpatch[0] = '\0'; int major = -1, minor = -1; while (fgets(vbuf, sizeof(vbuf), fp) != NULL) { if (strncmp(vbuf, "VERSION", strlen("version")) == 0) { strlcpy(strversion, vbuf, sizeof(strversion)); sscanf(vbuf, "VERSION = %d", &major); } if (strncmp(vbuf, "PATCH", strlen("PATCH")) == 0) { strlcpy(strpatch, vbuf, sizeof(strpatch)); sscanf(vbuf, "PATCHLEVEL = %d", &minor); } } if (ferror(fp)) { UnexpectedError("Failed to read line from stream"); } else { assert(feof(fp)); } fclose(fp); /* Check if it's a SUSE Enterprise version */ Log(LOG_LEVEL_VERBOSE, "Looking for SUSE enterprise info in '%s'", relstring); /* Convert relstring to lowercase to handle rename of SuSE to * SUSE with SUSE 10.0. */ for (size_t i = 0; i < strlen(relstring); i++) { relstring[i] = tolower(relstring[i]); } /* Check if it's a SUSE Enterprise version (all in lowercase) */ if (!strncmp(relstring, SUSE_SLES8_ID, strlen(SUSE_SLES8_ID))) { classbuf[0] = '\0'; strcat(classbuf, "SLES8"); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); } else if (strncmp(relstring, "sles", 4) == 0) { Item *list, *ip; nt_static_assert((sizeof(vbuf)) > 255); sscanf(relstring, "%255[-_a-zA-Z0-9]", vbuf); EvalContextClassPutHard(ctx, vbuf, "inventory,attribute_name=none,source=agent"); list = SplitString(vbuf, '-'); for (ip = list; ip != NULL; ip = ip->next) { EvalContextClassPutHard(ctx, ip->name, "inventory,attribute_name=none,source=agent"); } DeleteItemList(list); } else { for (int version = 9; version < 13; version++) { snprintf(vbuf, CF_BUFSIZE, "%s %d ", SUSE_SLES_ID, version); Log(LOG_LEVEL_DEBUG, "Checking for SUSE [%s]", vbuf); if (!strncmp(relstring, vbuf, strlen(vbuf))) { snprintf(classbuf, CF_MAXVARSIZE, "SLES%d", version); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); } else { snprintf(vbuf, CF_BUFSIZE, "%s %d ", SUSE_SLED_ID, version); Log(LOG_LEVEL_DEBUG, "Checking for SUSE [%s]", vbuf); if (!strncmp(relstring, vbuf, strlen(vbuf))) { snprintf(classbuf, CF_MAXVARSIZE, "SLED%d", version); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); } } } } /* Determine release version. We assume that the version follows * the string "SuSE Linux" or "SUSE LINUX". */ char *release = strstr(relstring, SUSE_RELEASE_FLAG); if (release == NULL) { release = strstr(relstring, "opensuse"); if (release == NULL) { release = strversion; } } if (release == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find a numeric OS release in %s", SUSE_REL_FILENAME); return 2; } else { char strmajor[CF_MAXVARSIZE], strminor[CF_MAXVARSIZE]; if (strchr(release, '.')) { sscanf(release, "%*s %d.%d", &major, &minor); xsnprintf(strmajor, sizeof(strmajor), "%d", major); xsnprintf(strminor, sizeof(strminor), "%d", minor); if (major != -1 && minor != -1) { strcpy(classbuf, "SUSE"); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); strcat(classbuf, "_"); strcat(classbuf, strmajor); SetFlavor(ctx, classbuf); strcat(classbuf, "_"); strcat(classbuf, strminor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); /* The correct spelling for SUSE is "SUSE" but CFEngine used to use "SuSE". * Keep this for backwards compatibility until CFEngine 3.7 */ strcpy(classbuf, "SuSE"); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); strcat(classbuf, "_"); strcat(classbuf, strmajor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); strcat(classbuf, "_"); strcat(classbuf, strminor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); Log(LOG_LEVEL_VERBOSE, "Discovered SUSE version %s", classbuf); return 0; } } else { nt_static_assert((sizeof(strmajor)) > 255); nt_static_assert((sizeof(strminor)) > 255); sscanf(strversion, "VERSION = %255s", strmajor); sscanf(strpatch, "PATCHLEVEL = %255s", strminor); if (major != -1 && minor != -1) { strcpy(classbuf, "SLES"); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); strcat(classbuf, "_"); strcat(classbuf, strmajor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); strcat(classbuf, "_"); strcat(classbuf, strminor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); snprintf(classbuf, CF_MAXVARSIZE, "SUSE_%d", major); SetFlavor(ctx, classbuf); /* The correct spelling for SUSE is "SUSE" but CFEngine used to use "SuSE". * Keep this for backwards compatibility until CFEngine 3.7 */ snprintf(classbuf, CF_MAXVARSIZE, "SuSE_%d", major); EvalContextClassPutHard(ctx, classbuf, "source=agent"); Log(LOG_LEVEL_VERBOSE, "Discovered SUSE version %s", classbuf); return 0; } } } Log(LOG_LEVEL_VERBOSE, "Could not find a numeric OS release in %s", SUSE_REL_FILENAME); return 0; } /******************************************************************/ static int Linux_Slackware_Version(EvalContext *ctx, char *filename) { int major = -1; int minor = -1; int release = -1; char classname[CF_MAXVARSIZE] = ""; char buffer[CF_MAXVARSIZE]; Log(LOG_LEVEL_VERBOSE, "This appears to be a slackware system."); EvalContextClassPutHard(ctx, "slackware", "inventory,attribute_name=none,source=agent"); if (!ReadLine(filename, buffer, sizeof(buffer))) { return 1; } Log(LOG_LEVEL_VERBOSE, "Looking for Slackware version..."); switch (sscanf(buffer, "Slackware %d.%d.%d", &major, &minor, &release)) { case 3: Log(LOG_LEVEL_VERBOSE, "This appears to be a Slackware %u.%u.%u system.", major, minor, release); snprintf(classname, CF_MAXVARSIZE, "slackware_%u_%u_%u", major, minor, release); EvalContextClassPutHard(ctx, classname, "inventory,attribute_name=none,source=agent"); /* Fall-through */ case 2: Log(LOG_LEVEL_VERBOSE, "This appears to be a Slackware %u.%u system.", major, minor); snprintf(classname, CF_MAXVARSIZE, "slackware_%u_%u", major, minor); EvalContextClassPutHard(ctx, classname, "inventory,attribute_name=none,source=agent"); /* Fall-through */ case 1: Log(LOG_LEVEL_VERBOSE, "This appears to be a Slackware %u system.", major); snprintf(classname, CF_MAXVARSIZE, "slackware_%u", major); EvalContextClassPutHard(ctx, classname, "inventory,attribute_name=none,source=agent"); break; case 0: Log(LOG_LEVEL_VERBOSE, "No Slackware version number found."); return 2; } return 0; } /* * @brief Purge /etc/issue escapes on debian * * On debian, /etc/issue can include special characters escaped with * '\\' or '@'. This function removes such escape sequences. * * @param[in,out] buffer: string to be sanitized */ static void LinuxDebianSanitizeIssue(char *buffer) { bool escaped = false; char *dst = buffer, *src = buffer, *tail = dst; while (*src != '\0') { char here = *src; src++; if (here == '\\' || here == '@' || escaped) { /* Skip over escapes and the character each acts on. */ escaped = !escaped; } else { /* Copy everything else verbatim: */ *dst = here; dst++; /* Keep track of (just after) last non-space: */ if (!isspace(here)) { tail = dst; } } } assert(tail == dst || isspace(*tail)); *tail = '\0'; } /******************************************************************/ static int Linux_Misc_Version(EvalContext *ctx) { char flavor[CF_MAXVARSIZE]; char version[256]; char buffer[CF_BUFSIZE]; const char *os = NULL; version[0] = '\0'; FILE *fp = safe_fopen(LSB_RELEASE_FILENAME, "r"); if (fp != NULL) { while (!feof(fp)) { if (fgets(buffer, CF_BUFSIZE, fp) == NULL) { if (ferror(fp)) { break; } continue; } if (strstr(buffer, "Cumulus")) { EvalContextClassPutHard(ctx, "cumulus", "inventory,attribute_name=none,source=agent"); os = "cumulus"; } char *sp = strstr(buffer, "DISTRIB_RELEASE="); if (sp) { version[0] = '\0'; nt_static_assert((sizeof(version)) > 255); sscanf(sp + strlen("DISTRIB_RELEASE="), "%255[^\n]", version); CanonifyNameInPlace(version); } } fclose(fp); } if (os != NULL && version[0] != '\0') { snprintf(flavor, CF_MAXVARSIZE, "%s_%s", os, version); SetFlavor(ctx, flavor); return 1; } return 0; } /******************************************************************/ static int Linux_Debian_Version(EvalContext *ctx) { int major = -1; int release = -1; int result; char classname[CF_MAXVARSIZE], buffer[CF_MAXVARSIZE], os[CF_MAXVARSIZE]; char version[256]; // Size must agree with sscanfs below Log(LOG_LEVEL_VERBOSE, "This appears to be a debian system."); EvalContextClassPutHard( ctx, "debian", "inventory,attribute_name=none,source=agent,derived-from-file="DEBIAN_VERSION_FILENAME); buffer[0] = classname[0] = '\0'; Log(LOG_LEVEL_VERBOSE, "Looking for Debian version..."); if (!ReadLine(DEBIAN_VERSION_FILENAME, buffer, sizeof(buffer))) { return 1; } result = sscanf(buffer, "%d.%d", &major, &release); switch (result) { case 2: Log(LOG_LEVEL_VERBOSE, "This appears to be a Debian %u.%u system.", major, release); snprintf(classname, CF_MAXVARSIZE, "debian_%u_%u", major, release); EvalContextClassPutHard( ctx, classname, "inventory,attribute_name=none,source=agent,derived-from-file="DEBIAN_VERSION_FILENAME); snprintf(classname, CF_MAXVARSIZE, "debian_%u", major); SetFlavor(ctx, classname); break; case 1: Log(LOG_LEVEL_VERBOSE, "This appears to be a Debian %u system.", major); snprintf(classname, CF_MAXVARSIZE, "debian_%u", major); SetFlavor(ctx, classname); break; default: version[0] = '\0'; nt_static_assert((sizeof(version)) > 25); sscanf(buffer, "%25[^/]", version); if (strlen(version) > 0) { snprintf(classname, CF_MAXVARSIZE, "debian_%s", version); EvalContextClassPutHard( ctx, classname, "inventory,attribute_name=none,source=agent,derived-from-file="DEBIAN_VERSION_FILENAME); } break; } if (!ReadLine(DEBIAN_ISSUE_FILENAME, buffer, sizeof(buffer))) { return 1; } os[0] = '\0'; nt_static_assert((sizeof(os)) > 250); sscanf(buffer, "%250s", os); if (strcmp(os, "Debian") == 0) { LinuxDebianSanitizeIssue(buffer); nt_static_assert((sizeof(version)) > 255); sscanf(buffer, "%*s %*s %255[^./]", version); snprintf(buffer, CF_MAXVARSIZE, "debian_%s", version); EvalContextClassPutHard( ctx, "debian", "inventory,attribute_name=none,source=agent,derived-from-file="DEBIAN_ISSUE_FILENAME); SetFlavor(ctx, buffer); } else if (strcmp(os, "Ubuntu") == 0) { LinuxDebianSanitizeIssue(buffer); char minor[256] = {0}; nt_static_assert((sizeof(version)) > 255); sscanf(buffer, "%*s %255[^.].%255s", version, minor); snprintf(buffer, CF_MAXVARSIZE, "ubuntu_%s", version); SetFlavor(ctx, buffer); EvalContextClassPutHard( ctx, "ubuntu", "inventory,attribute_name=none,source=agent,derived-from-file="DEBIAN_ISSUE_FILENAME); if (release >= 0) { snprintf(buffer, CF_MAXVARSIZE, "ubuntu_%s_%s", version, minor); EvalContextClassPutHard( ctx, buffer, "inventory,attribute_name=none,source=agent,derived-from-file="DEBIAN_ISSUE_FILENAME); } } return 0; } /******************************************************************/ static int Linux_Mandrake_Version(EvalContext *ctx) { /* We are looking for one of the following strings... */ #define MANDRAKE_ID "Linux Mandrake" #define MANDRAKE_REV_ID "Mandrake Linux" #define MANDRAKE_10_1_ID "Mandrakelinux" #define MANDRAKE_REL_FILENAME "/etc/mandrake-release" char relstring[CF_MAXVARSIZE]; char *vendor = NULL; Log(LOG_LEVEL_VERBOSE, "This appears to be a mandrake system."); EvalContextClassPutHard(ctx, "Mandrake", "inventory,attribute_name=none,source=agent"); if (!ReadLine(MANDRAKE_REL_FILENAME, relstring, sizeof(relstring))) { return 1; } Log(LOG_LEVEL_VERBOSE, "Looking for Mandrake linux info in '%s'", relstring); /* Older Mandrakes had the 'Mandrake Linux' string in reverse order */ if (!strncmp(relstring, MANDRAKE_ID, strlen(MANDRAKE_ID))) { vendor = "mandrake"; } else if (!strncmp(relstring, MANDRAKE_REV_ID, strlen(MANDRAKE_REV_ID))) { vendor = "mandrake"; } else if (!strncmp(relstring, MANDRAKE_10_1_ID, strlen(MANDRAKE_10_1_ID))) { vendor = "mandrake"; } else { Log(LOG_LEVEL_VERBOSE, "Could not identify OS distro from %s", MANDRAKE_REL_FILENAME); return 2; } return Linux_Mandriva_Version_Real(ctx, MANDRAKE_REL_FILENAME, relstring, vendor); } /******************************************************************/ static int Linux_Mandriva_Version(EvalContext *ctx) { /* We are looking for the following strings... */ #define MANDRIVA_ID "Mandriva Linux" #define MANDRIVA_REL_FILENAME "/etc/mandriva-release" char relstring[CF_MAXVARSIZE]; char *vendor = NULL; Log(LOG_LEVEL_VERBOSE, "This appears to be a mandriva system."); EvalContextClassPutHard(ctx, "Mandrake", "inventory,attribute_name=none,source=agent"); EvalContextClassPutHard(ctx, "Mandriva", "inventory,attribute_name=none,source=agent"); if (!ReadLine(MANDRIVA_REL_FILENAME, relstring, sizeof(relstring))) { return 1; } Log(LOG_LEVEL_VERBOSE, "Looking for Mandriva linux info in '%s'", relstring); if (!strncmp(relstring, MANDRIVA_ID, strlen(MANDRIVA_ID))) { vendor = "mandriva"; } else { Log(LOG_LEVEL_VERBOSE, "Could not identify OS distro from '%s'", MANDRIVA_REL_FILENAME); return 2; } return Linux_Mandriva_Version_Real(ctx, MANDRIVA_REL_FILENAME, relstring, vendor); } /******************************************************************/ static int Linux_Mandriva_Version_Real(EvalContext *ctx, char *filename, char *relstring, char *vendor) { int major = -1, minor = -1; char strmajor[PRINTSIZE(major)], strminor[PRINTSIZE(minor)]; #define RELEASE_FLAG "release " char *release = strstr(relstring, RELEASE_FLAG); if (release == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not find a numeric OS release in %s", filename); return 2; } else { release += strlen(RELEASE_FLAG); if (sscanf(release, "%d.%d", &major, &minor) == 2) { xsnprintf(strmajor, sizeof(strmajor), "%d", major); xsnprintf(strminor, sizeof(strminor), "%d", minor); } else { Log(LOG_LEVEL_VERBOSE, "Could not break down release version numbers in %s", filename); } } if (major != -1 && minor != -1 && strcmp(vendor, "")) { char classbuf[CF_MAXVARSIZE]; classbuf[0] = '\0'; strcat(classbuf, vendor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); strcat(classbuf, "_"); strcat(classbuf, strmajor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); if (minor != -2) { strcat(classbuf, "_"); strcat(classbuf, strminor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); } } return 0; } /******************************************************************/ static void Linux_Amazon_Version(EvalContext *ctx) { char buffer[CF_BUFSIZE]; // Amazon Linux release 2 (Karoo) if (ReadLine("/etc/system-release", buffer, sizeof(buffer))) { if (strstr(buffer, "Amazon") != NULL) { EvalContextClassPutHard(ctx, "amazon_linux", "inventory,attribute_name=none,source=agent" ",derived-from-file=/etc/system-release"); char version[128]; if (sscanf(buffer, "%*s %*s %*s %127s", version) == 1) { char class[CF_MAXVARSIZE]; CanonifyNameInPlace(version); snprintf(class, sizeof(class), "amazon_linux_%s", version); EvalContextClassPutHard(ctx, class, "inventory,attribute_name=none,source=agent" ",derived-from-file=/etc/system-release"); SetFlavor(ctx, class); } else { SetFlavor(ctx, "amazon_linux"); } // We set this class for backwards compatibility EvalContextClassPutHard(ctx, "AmazonLinux", "inventory,attribute_name=none,source=agent," "derived-from=sys.flavor"); } } } /******************************************************************/ static void Linux_Alpine_Version(EvalContext *ctx) { char buffer[CF_BUFSIZE]; Log(LOG_LEVEL_VERBOSE, "This appears to be an AlpineLinux system."); EvalContextClassPutHard(ctx, "alpine_linux", "inventory,attribute_name=none,source=agent" ",derived-from-file=/etc/alpine-release"); if (ReadLine("/etc/alpine-release", buffer, sizeof(buffer))) { char version[128]; if (sscanf(buffer, "%127s", version) == 1) { char class[CF_MAXVARSIZE]; CanonifyNameInPlace(version); snprintf(class, sizeof(class), "alpine_linux_%s", version); EvalContextClassPutHard(ctx, class, "inventory,attribute_name=none,source=agent" ",derived-from-file=/etc/alpine-release"); } } SetFlavor(ctx, "alpinelinux"); } /******************************************************************/ static int EOS_Version(EvalContext *ctx) { char buffer[CF_BUFSIZE]; // e.g. Arista Networks EOS 4.10.2 if (ReadLine("/etc/Eos-release", buffer, sizeof(buffer))) { if (strstr(buffer, "EOS")) { char version[256], class[CF_MAXVARSIZE]; EvalContextClassPutHard(ctx, "eos", "inventory,attribute_name=none,source=agent"); EvalContextClassPutHard(ctx, "arista", "source=agent"); version[0] = '\0'; sscanf(buffer, "%*s %*s %*s %255s", version); CanonifyNameInPlace(version); snprintf(class, CF_MAXVARSIZE, "eos_%s", version); EvalContextClassPutHard(ctx, class, "inventory,attribute_name=none,source=agent"); } } return 0; } /******************************************************************/ static int MiscOS(EvalContext *ctx) { char buffer[CF_BUFSIZE]; // e.g. BIG-IP 10.1.0 Build 3341.1084 if (ReadLine("/etc/issue", buffer, sizeof(buffer))) { if (strstr(buffer, "BIG-IP")) { char version[256], build[256], class[CF_MAXVARSIZE]; EvalContextClassPutHard(ctx, "big_ip", "inventory,attribute_name=none,source=agent"); sscanf(buffer, "%*s %255s %*s %255s", version, build); CanonifyNameInPlace(version); CanonifyNameInPlace(build); snprintf(class, CF_MAXVARSIZE, "big_ip_%s", version); EvalContextClassPutHard(ctx, class, "inventory,attribute_name=none,source=agent"); snprintf(class, CF_MAXVARSIZE, "big_ip_%s_%s", version, build); EvalContextClassPutHard(ctx, class, "inventory,attribute_name=none,source=agent"); SetFlavor(ctx, "BIG-IP"); } } return 0; } /******************************************************************/ static int VM_Version(EvalContext *ctx) { char *sp, buffer[CF_BUFSIZE], classbuf[CF_BUFSIZE], version[256]; int major, minor, bug; int sufficient = 0; Log(LOG_LEVEL_VERBOSE, "This appears to be a VMware Server ESX/xSX system."); EvalContextClassPutHard(ctx, "VMware", "inventory,attribute_name=Virtual host,source=agent"); /* VMware Server ESX >= 3 has version info in /proc */ if (ReadLine("/proc/vmware/version", buffer, sizeof(buffer))) { if (sscanf(buffer, "VMware ESX Server %d.%d.%d", &major, &minor, &bug) > 0) { snprintf(classbuf, CF_BUFSIZE, "VMware ESX Server %d", major); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); snprintf(classbuf, CF_BUFSIZE, "VMware ESX Server %d.%d", major, minor); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); snprintf(classbuf, CF_BUFSIZE, "VMware ESX Server %d.%d.%d", major, minor, bug); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); sufficient = 1; } else if (sscanf(buffer, "VMware ESX Server %255s", version) > 0) { snprintf(classbuf, CF_BUFSIZE, "VMware ESX Server %s", version); EvalContextClassPutHard(ctx, classbuf, "inventory,attribute_name=none,source=agent"); sufficient = 1; } } /* Fall back to checking for other files */ if (sufficient < 1 && (ReadLine("/etc/vmware-release", buffer, sizeof(buffer)) || ReadLine("/etc/issue", buffer, sizeof(buffer)))) { EvalContextClassPutHard(ctx, buffer, "inventory,attribute_name=none,source=agent"); /* Strip off the release code name e.g. "(Dali)" */ if ((sp = strchr(buffer, '(')) != NULL) { *sp = 0; Chop(buffer, CF_EXPANDSIZE); EvalContextClassPutHard(ctx, buffer, "inventory,attribute_name=none,source=agent"); } sufficient = 1; } return sufficient < 1 ? 1 : 0; } /******************************************************************/ static int Xen_Domain(EvalContext *ctx) { int sufficient = 0; Log(LOG_LEVEL_VERBOSE, "This appears to be a xen pv system."); EvalContextClassPutHard(ctx, "xen", "inventory,attribute_name=Virtual host,source=agent"); /* xen host will have "control_d" in /proc/xen/capabilities, xen guest will not */ FILE *fp = safe_fopen("/proc/xen/capabilities", "r"); if (fp != NULL) { size_t buffer_size = CF_BUFSIZE; char *buffer = xmalloc(buffer_size); for (;;) { ssize_t res = CfReadLine(&buffer, &buffer_size, fp); if (res == -1) { if (!feof(fp)) { /* Failure reading Xen capabilites. Do we care? */ fclose(fp); free(buffer); return 1; } else { break; } } if (strstr(buffer, "control_d")) { EvalContextClassPutHard(ctx, "xen_dom0", "inventory,attribute_name=Virtual host,source=agent"); sufficient = 1; } } if (!sufficient) { EvalContextClassPutHard(ctx, "xen_domu_pv", "inventory,attribute_name=Virtual host,source=agent"); sufficient = 1; } fclose(fp); free(buffer); } return sufficient < 1 ? 1 : 0; } /******************************************************************/ static void OpenVZ_Detect(EvalContext *ctx) { /* paths to file defining the type of vm (guest or host) */ #define OPENVZ_HOST_FILENAME "/proc/bc/0" #define OPENVZ_GUEST_FILENAME "/proc/vz" /* path to the vzps binary */ #define OPENVZ_VZPS_FILE "/bin/vzps" struct stat statbuf; /* The file /proc/bc/0 is present on host The file /proc/vz is present on guest If the host has /bin/vzps, we should use it for checking processes */ if (stat(OPENVZ_HOST_FILENAME, &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "This appears to be an OpenVZ/Virtuozzo/Parallels Cloud Server host system.\n"); EvalContextClassPutHard(ctx, "virt_host_vz", "inventory,attribute_name=Virtual host,source=agent"); /* if the file /bin/vzps is there, it is safe to use the processes promise type */ if (stat(OPENVZ_VZPS_FILE, &statbuf) != -1) { EvalContextClassPutHard(ctx, "virt_host_vz_vzps", "inventory,attribute_name=Virtual host,source=agent"); /* here we must redefine the value of VPSHARDCLASS */ for (int i = 0; i < PLATFORM_CONTEXT_MAX; i++) { if (!strcmp(CLASSATTRIBUTES[i][0], "virt_host_vz_vzps")) { VPSHARDCLASS = (PlatformContext) i; break; } } } else { Log(LOG_LEVEL_NOTICE, "This OpenVZ/Virtuozzo/Parallels Cloud Server host system does not have vzps installed; the processes promise type may not work as expected.\n"); } } else if (stat(OPENVZ_GUEST_FILENAME, &statbuf) != -1) { Log(LOG_LEVEL_VERBOSE, "This appears to be an OpenVZ/Virtuozzo/Parallels Cloud Server guest system.\n"); EvalContextClassPutHard(ctx, "virt_guest_vz", "inventory,attribute_name=Virtual host,source=agent"); } } /******************************************************************/ static bool ReadLine(const char *filename, char *buf, int bufsize) { FILE *fp = ReadFirstLine(filename, buf, bufsize); if (fp == NULL) { return false; } else { fclose(fp); return true; } } static FILE *ReadFirstLine(const char *filename, char *buf, int bufsize) { FILE *fp = safe_fopen(filename, "r"); if (fp == NULL) { return NULL; } if (fgets(buf, bufsize, fp) == NULL) { fclose(fp); return NULL; } StripTrailingNewline(buf, CF_EXPANDSIZE); return fp; } #endif /* __linux__ */ /******************************************************************/ #ifdef XEN_CPUID_SUPPORT /* Borrowed and modified from Xen source/tools/libxc/xc_cpuid_x86.c */ static void Xen_Cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { # ifdef __i386__ /* On i386, %ebx register needs to be saved before usage and restored * thereafter for PIC-compliant code on i386. */ asm("push %%ebx; cpuid; mov %%ebx,%1; pop %%ebx" : "=a"(*eax), "=r"(*ebx), "=c"(*ecx), "=d"(*edx) : "0" (idx), "2" (0) ); # else asm("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "0" (idx), "2" (0) ); # endif } /******************************************************************/ static bool Xen_Hv_Check(void) { /* CPUID interface to Xen from arch-x86/cpuid.h: * Leaf 1 (0x40000000) * EAX: Largest Xen-information leaf. All leaves up to an including @EAX * are supported by the Xen host. * EBX-EDX: "XenVMMXenVMM" signature, allowing positive identification * of a Xen host. * * Additional information can be found in the Hypervisor CPUID * Interface Proposal (https://lkml.org/lkml/2008/10/1/246) */ uint32_t eax, base; union { uint32_t u[3]; char s[13]; } sig = {{0}}; /* * For compatibility with other hypervisor interfaces, the Xen cpuid leaves * can be found at the first otherwise unused 0x100 aligned boundary starting * from 0x40000000. * * e.g If viridian extensions are enabled for an HVM domain, the Xen cpuid * leaves will start at 0x40000100 */ for (base = 0x40000000; base < 0x40010000; base += 0x100) { Xen_Cpuid(base, &eax, &sig.u[0], &sig.u[1], &sig.u[2]); if (memcmp("XenVMMXenVMM", &sig.s[0], 12) == 0) { /* The highest basic calling parameter (largest value that EAX can * be set to before calling CPUID) is returned in EAX. */ if ((eax - base) < 2) { Log(LOG_LEVEL_DEBUG, "Insufficient Xen CPUID Leaves (eax=%x at base %x)", eax, base); return false; } Log(LOG_LEVEL_DEBUG, "Found Xen CPUID Leaf (eax=%x at base %x)", eax, base); return true; } } return false; } #endif /* XEN_CPUID_SUPPORT */ static void GetCPUInfo(EvalContext *ctx) { #if defined(MINGW) || defined(NT) Log(LOG_LEVEL_VERBOSE, "!! cpu count not implemented on Windows platform"); return; #else int count = 0; // http://preview.tinyurl.com/c9l2sh - StackOverflow on cross-platform CPU counting #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) // Linux, AIX, Solaris, Darwin >= 10.4 count = (int)sysconf(_SC_NPROCESSORS_ONLN); #endif #if defined(HAVE_SYS_SYSCTL_H) && defined(HW_NCPU) // BSD-derived platforms int mib[2] = { CTL_HW, HW_NCPU }; size_t len; len = sizeof(count); if(sysctl(mib, 2, &count, &len, NULL, 0) < 0) { Log(LOG_LEVEL_ERR, "!! failed to get cpu count: %s", strerror(errno)); } #endif #ifdef HAVE_SYS_MPCTL_H // Itanium processors have Intel Hyper-Threading virtual-core capability, // and the MPC_GETNUMCORES_SYS operation counts each HT virtual core, // which is equivalent to what the /proc/stat scan delivers for Linux. // // A build on 11i v3 PA would have the GETNUMCORES define, but if run on an // 11i v1 system it would fail since that OS release has only GETNUMSPUS. // So in the presence of GETNUMCORES, we check for an invalid arg error // and fall back to GETNUMSPUS if necessary. An 11i v1 build would work // normally on 11i v3, because on PA-RISC cores == spus since there's no // HT on PA-RISC, and 11i v1 only runs on PA-RISC. # ifdef MPC_GETNUMCORES_SYS count = mpctl(MPC_GETNUMCORES_SYS, 0, 0); if (count == -1 && errno == EINVAL) { count = mpctl(MPC_GETNUMSPUS_SYS, 0, 0); } # else count = mpctl(MPC_GETNUMSPUS_SYS, 0, 0); // PA-RISC processor count # endif #endif /* HAVE_SYS_MPCTL_H */ if (count < 1) { Log(LOG_LEVEL_VERBOSE, "invalid processor count: %d", count); return; } Log(LOG_LEVEL_VERBOSE, "Found %d processor%s", count, count > 1 ? "s" : ""); char buf[CF_SMALLBUF] = "1_cpu"; if (count == 1) { EvalContextClassPutHard(ctx, buf, "source=agent,derived-from=sys.cpus"); // "1_cpu" from init - change if buf is ever used above EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cpus", "1", CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=CPU logical cores"); } else { snprintf(buf, CF_SMALLBUF, "%d_cpus", count); EvalContextClassPutHard(ctx, buf, "source=agent,derived-from=sys.cpus"); snprintf(buf, CF_SMALLBUF, "%d", count); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "cpus", buf, CF_DATA_TYPE_STRING, "inventory,source=agent,attribute_name=CPU logical cores"); } #endif /* MINGW || NT */ } /******************************************************************/ // Implemented in Windows specific section. #ifndef __MINGW32__ /** Return the number of seconds the system has been online given the current time() as an argument, or return -1 if unavailable or unimplemented. */ int GetUptimeSeconds(time_t now) { time_t boot_time = 0; errno = 0; #if defined(BOOT_TIME_WITH_SYSINFO) // Most GNU, Linux platforms struct sysinfo s; if (sysinfo(&s) == 0) { // Don't return yet, sanity checking below boot_time = now - s.uptime; } #elif defined(BOOT_TIME_WITH_KSTAT) // Solaris platform /* From command line you can get this with: kstat -p unix:0:system_misc:boot_time */ kstat_ctl_t *kc = kstat_open(); if(kc != 0) { kstat_t *kp = kstat_lookup(kc, "unix", 0, "system_misc"); if(kp != 0) { if (kstat_read(kc, kp, NULL) != -1) { kstat_named_t *knp = kstat_data_lookup(kp, "boot_time"); if (knp != NULL) { boot_time = knp->value.ui32; } } } kstat_close(kc); } #elif defined(BOOT_TIME_WITH_PSTAT_GETPROC) // HP-UX platform only struct pst_status p; if (pstat_getproc(&p, sizeof(p), 0, 1) == 1) { boot_time = (time_t)p.pst_start; } #elif defined(BOOT_TIME_WITH_SYSCTL) // BSD-derived platforms int mib[2] = { CTL_KERN, KERN_BOOTTIME }; struct timeval boot; size_t len = sizeof(boot); if (sysctl(mib, 2, &boot, &len, NULL, 0) == 0) { boot_time = boot.tv_sec; } #elif defined(BOOT_TIME_WITH_PROCFS) struct stat p; if (stat("/proc/1", &p) == 0) { boot_time = p.st_ctime; } #elif defined(BOOT_TIME_WITH_UTMP) /* SystemV, highly portable way */ struct utmp query = { .ut_type = BOOT_TIME }; struct utmp *result; setutent(); result = getutid(&query); if (result != NULL) { boot_time = result->ut_time; } endutent(); #elif defined(BOOT_TIME_WITH_UTMPX) /* POSIX way */ struct utmpx query = { .ut_type = BOOT_TIME }; struct utmpx *result; setutxent(); result = getutxid(&query); if (result != NULL) { boot_time = result->ut_tv.tv_sec; } endutxent(); #endif if(errno) { Log(LOG_LEVEL_VERBOSE, "boot time discovery error: %s", GetErrorStr()); } if(boot_time > now || boot_time <= 0) { Log(LOG_LEVEL_VERBOSE, "invalid boot time found; trying uptime command"); boot_time = GetBootTimeFromUptimeCommand(now); } return boot_time > 0 ? now - boot_time : -1; } #endif // !__MINGW32__ int GetUptimeMinutes(time_t now) { return GetUptimeSeconds(now) / SECONDS_PER_MINUTE; } /******************************************************************/ // Last resort: parse the output of the uptime command with a PCRE regexp // and convert the uptime to boot time using "now" argument. // // The regexp needs to match all variants of the uptime command's output. // Solaris 8/9/10: 10:45am up 109 day(s), 19:56, 1 user, load average: // HP-UX 11.11: 9:24am up 1 min, 1 user, load average: // 8:23am up 23 hrs, 0 users, load average: // 9:33am up 2 days, 10 mins, 0 users, load average: // 11:23am up 2 days, 2 hrs, 0 users, load average: // Red Hat Linux: 10:51:23 up 5 days, 19:54, 1 user, load average: // // UPTIME_BACKREFS must be set to this regexp's maximum backreference // index number (i.e., the count of left-parentheses): #define UPTIME_REGEXP " up (\\d+ day[^,]*,|) *(\\d+( ho?u?r|:(\\d+))|(\\d+) min)" #define UPTIME_BACKREFS 5 static time_t GetBootTimeFromUptimeCommand(time_t now) { FILE *uptimecmd; char *backref = NULL; const char *uptimepath = "/usr/bin/uptime"; time_t uptime = 0; int err_code; size_t err_offset; pcre2_code *regex = pcre2_compile((PCRE2_SPTR) UPTIME_REGEXP, PCRE2_ZERO_TERMINATED, 0, &err_code, &err_offset, NULL); if (regex == NULL) { Log(LOG_LEVEL_DEBUG, "failed to compile regexp to parse uptime command"); return(-1); } // Try "/usr/bin/uptime" first, then "/bin/uptime" uptimecmd = cf_popen(uptimepath, "r", false); uptimecmd = uptimecmd ? uptimecmd : cf_popen((uptimepath + 4), "r", false); if (!uptimecmd) { Log(LOG_LEVEL_ERR, "uptime failed: (cf_popen: %s)", GetErrorStr()); pcre2_code_free(regex); return -1; } size_t uptime_output_size = CF_SMALLBUF; char *uptime_output = xmalloc(uptime_output_size); ssize_t n_read = CfReadLine(&uptime_output, &uptime_output_size, uptimecmd); cf_pclose(uptimecmd); if (n_read == -1 && !feof(uptimecmd)) { Log(LOG_LEVEL_ERR, "Reading uptime output failed. (getline: '%s')", GetErrorStr()); pcre2_code_free(regex); return -1; } pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(regex, NULL); if ((n_read > 0) && (pcre2_match(regex, (PCRE2_SPTR) uptime_output, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL) > 1)) { size_t *ovector = pcre2_get_ovector_pointer(match_data); for (int i = 1; i <= UPTIME_BACKREFS ; i++) { if (ovector[i * 2 + 1] - ovector[i * 2] == 0) // strlen(backref) { continue; } backref = uptime_output + ovector[i * 2]; // atoi() ignores non-digits, so no need to null-terminate backref time_t seconds; switch(i) { case 1: // Day seconds = SECONDS_PER_DAY; break; case 2: // Hour seconds = SECONDS_PER_HOUR; break; case 4: // Minute case 5: seconds = SECONDS_PER_MINUTE; break; default: seconds = 0; } uptime += ((time_t) atoi(backref)) * seconds; } } else { Log(LOG_LEVEL_ERR, "uptime PCRE match failed: regexp: '%s', uptime: '%s'", UPTIME_REGEXP, uptime_output); } pcre2_match_data_free(match_data); pcre2_code_free(regex); Log(LOG_LEVEL_VERBOSE, "Reading boot time from uptime command successful."); return(uptime ? (now - uptime) : -1); } /*****************************************************************************/ /* TODO accept a const char * and move the ifdefs away from * evalfunction.c:FnCallGetUserInfo() to here. */ JsonElement* GetUserInfo(const void *passwd) { #ifdef __MINGW32__ return NULL; #else /* !__MINGW32__ */ // we lose the const to set pw if passwd is NULL struct passwd *pw = (struct passwd*) passwd; if (pw == NULL) { pw = getpwuid(getuid()); } if (pw == NULL) { return NULL; } JsonElement *result = JsonObjectCreate(10); JsonObjectAppendString(result, "username", pw->pw_name); JsonObjectAppendString(result, "description", pw->pw_gecos); JsonObjectAppendString(result, "home_dir", pw->pw_dir); JsonObjectAppendString(result, "shell", pw->pw_shell); JsonObjectAppendInteger(result, "uid", pw->pw_uid); JsonObjectAppendInteger(result, "gid", pw->pw_gid); //JsonObjectAppendBool(result, "locked", IsAccountLocked(pw->pw_name, pw)); // TODO: password: { format: "hash", data: { ...GetPasswordHash()... } } // TODO: group_primary: name of group // TODO: groups_secondary: [ names of groups ] // TODO: gids_secondary: [ gids of groups ] return result; #endif } /*****************************************************************************/ void GetSysVars(EvalContext *ctx) { /* Get info for current user. */ JsonElement *info = GetUserInfo(NULL); if (info != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "user_data", info, CF_DATA_TYPE_CONTAINER, "source=agent,user_info"); JsonDestroy(info); } } /*****************************************************************************/ void GetDefVars(EvalContext *ctx) { EvalContextVariablePutSpecial( ctx, SPECIAL_SCOPE_DEF, "jq", "jq --compact-output --monochrome-output --ascii-output --unbuffered --sort-keys", CF_DATA_TYPE_STRING, "invocation,source=agent,command_name=jq"); } /*****************************************************************************/ static void SysOSNameHuman(EvalContext *ctx) { // This function sets the $(sys.os_name_human) variable assert(ctx != NULL); const char *const lval = "os_name_human"; /** * Order is important. The first if-statement is more specific and wins. * E.g. prefer Ubuntu over Debian. */ if (EvalContextClassGet(ctx, NULL, "ubuntu") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Ubuntu", CF_DATA_TYPE_STRING, "source=agent,derived-from=ubuntu"); } else if (EvalContextClassGet(ctx, NULL, "debian") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Debian", CF_DATA_TYPE_STRING, "source=agent,derived-from=debian"); } else if (EvalContextClassGet(ctx, NULL, "centos") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "CentOS", CF_DATA_TYPE_STRING, "source=agent,derived-from=centos"); } else if (EvalContextClassGet(ctx, NULL, "fedora") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Fedora", CF_DATA_TYPE_STRING, "source=agent,derived-from=fedora"); } else if (EvalContextClassGet(ctx, NULL, "redhat") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "RHEL", CF_DATA_TYPE_STRING, "source=agent,derived-from=redhat"); } else if (EvalContextClassGet(ctx, NULL, "aix") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "AIX", CF_DATA_TYPE_STRING, "source=agent,derived-from=aix"); } else if (EvalContextClassGet(ctx, NULL, "hpux") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "HP-UX", CF_DATA_TYPE_STRING, "source=agent,derived-from=hpux"); } else if (EvalContextClassGet(ctx, NULL, "opensuse") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "OpenSUSE", CF_DATA_TYPE_STRING, "source=agent,derived-from=opensuse"); } else if (EvalContextClassGet(ctx, NULL, "suse") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "SUSE", CF_DATA_TYPE_STRING, "source=agent,derived-from=suse"); } else if (EvalContextClassGet(ctx, NULL, "macos") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "macOS", CF_DATA_TYPE_STRING, "source=agent,derived-from=macos"); } else if (EvalContextClassGet(ctx, NULL, "windows") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Windows", CF_DATA_TYPE_STRING, "source=agent,derived-from=windows"); } else if (EvalContextClassGet(ctx, NULL, "freebsd") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "FreeBSD", CF_DATA_TYPE_STRING, "source=agent,derived-from=freebsd"); } else if (EvalContextClassGet(ctx, NULL, "openbsd") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "OpenBSD", CF_DATA_TYPE_STRING, "source=agent,derived-from=openbsd"); } else if (EvalContextClassGet(ctx, NULL, "netbsd") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "NetBSD", CF_DATA_TYPE_STRING, "source=agent,derived-from=netbsd"); } else if (EvalContextClassGet(ctx, NULL, "solaris") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Solaris", CF_DATA_TYPE_STRING, "source=agent,derived-from=solaris"); } else if (EvalContextClassGet(ctx, NULL, "amazon_linux") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Amazon", CF_DATA_TYPE_STRING, "source=agent,derived-from=amazon_linux"); } else if (EvalContextClassGet(ctx, NULL, "arch") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Arch", CF_DATA_TYPE_STRING, "source=agent,derived-from=arch"); } else if (EvalContextClassGet(ctx, NULL, "postmarketos") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "postmarketOS", CF_DATA_TYPE_STRING, "source=agent,derived-from=postmarketos"); } else if (EvalContextClassGet(ctx, NULL, "alpine") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Alpine", CF_DATA_TYPE_STRING, "source=agent,derived-from=alpine"); } else { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, "Unknown", CF_DATA_TYPE_STRING, "source=agent"); Log(LOG_LEVEL_WARNING, "Operating System not properly recognized, setting sys.os_name_human to \"Unknown\", please submit a bug report for us to fix this"); } } /*****************************************************************************/ /** * Find next integer from string in place. Leading zero's are included. * * @param [in] str string to extract next integer from * @param [out] num pointer to start of next integer or %NULL if no integer * number was found * * @return pointer to the remaining string in `str` or %NULL if no remainder * * @note `str` will be mutated */ static char *FindNextInteger(char *str, char **num) { if (str == NULL) { *num = NULL; return NULL; } char *ptr = str; while (*ptr != '\0' && !isdigit(*ptr)) { ++ptr; } if (*ptr == '\0') { /* no integer found */ *num = NULL; return NULL; } *num = ptr++; while (*ptr != '\0' && isdigit(*ptr)) { ++ptr; } if (*ptr == '\0') { /* no remainder */ return NULL; } *ptr++ = '\0'; return ptr; } static void SysOsVersionMajor(EvalContext *ctx) { const char *const_flavor = EvalContextVariableGetSpecialString( ctx, SPECIAL_SCOPE_SYS, "flavor"); char *flavor = SafeStringDuplicate(const_flavor); char *major; char *next = FindNextInteger(flavor, &major); if (flavor != NULL) { if (StringStartsWith(const_flavor, "solaris") || StringStartsWith(const_flavor, "sunos")) { /* In this case the major version comes second. * E.g. SunOS 5.11 where 11 is the major release number. * Thus, we need to get the next number. */ FindNextInteger(next, &major); } } if (NULL_OR_EMPTY(major)) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "os_version_major", "Unknown", CF_DATA_TYPE_STRING, "source=agent"); } else { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "os_version_major", major, CF_DATA_TYPE_STRING, "source=agent,derived-from=flavor"); } free(flavor); } /*****************************************************************************/ void DetectEnvironment(EvalContext *ctx) { GetNameInfo3(ctx); GetInterfacesInfo(ctx); GetNetworkingInfo(ctx); Get3Environment(ctx); BuiltinClasses(ctx); OSClasses(ctx); GetSysVars(ctx); GetDefVars(ctx); SysOSNameHuman(ctx); SysOsVersionMajor(ctx); } cfengine-3.24.2/libenv/time_classes.c0000644000000000000000000001105515010704253017453 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static void RemoveTimeClass(EvalContext *ctx, const char* tags) { Rlist *tags_rlist = RlistFromSplitString(tags, ','); ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); StringSet *global_matches = ClassesMatching(ctx, iter, ".*", tags_rlist, false); ClassTableIteratorDestroy(iter); StringSetIterator it = StringSetIteratorInit(global_matches); const char *element = NULL; while ((element = StringSetIteratorNext(&it))) { EvalContextClassRemove(ctx, NULL, element); } StringSetDestroy(global_matches); RlistDestroy(tags_rlist); } StringSet *GetTimeClasses(time_t time) { // The first element is the local timezone const char* tz_prefix[2] = { "", "GMT_" }; const char* tz_function[2] = { "localtime_r", "gmtime_r" }; struct tm tz_parsed_time[2]; const struct tm* tz_tm[2] = { localtime_r(&time, &(tz_parsed_time[0])), gmtime_r(&time, &(tz_parsed_time[1])) }; StringSet *classes = StringSetNew(); for (int tz = 0; tz < 2; tz++) { int day_text_index, quarter, interval_start, interval_end; if (tz_tm[tz] == NULL) { Log(LOG_LEVEL_ERR, "Unable to parse passed time. (%s: %s)", tz_function[tz], GetErrorStr()); return NULL; } /* Lifecycle */ StringSetAddF(classes, "%sLcycle_%d", tz_prefix[tz], ((tz_parsed_time[tz].tm_year + 1900) % 3)); /* Year */ StringSetAddF(classes, "%sYr%04d", tz_prefix[tz], tz_parsed_time[tz].tm_year + 1900); /* Month */ StringSetAddF(classes, "%s%s", tz_prefix[tz], MONTH_TEXT[tz_parsed_time[tz].tm_mon]); /* Day of week */ /* Monday is 1 in tm_wday, 0 in DAY_TEXT Tuesday is 2 in tm_wday, 1 in DAY_TEXT ... Sunday is 0 in tm_wday, 6 in DAY_TEXT */ day_text_index = (tz_parsed_time[tz].tm_wday + 6) % 7; StringSetAddF(classes, "%s%s", tz_prefix[tz], DAY_TEXT[day_text_index]); /* Day */ StringSetAddF(classes, "%sDay%d", tz_prefix[tz], tz_parsed_time[tz].tm_mday); /* Shift */ StringSetAddF(classes, "%s%s", tz_prefix[tz], SHIFT_TEXT[tz_parsed_time[tz].tm_hour / 6]); /* Hour */ StringSetAddF(classes, "%sHr%02d", tz_prefix[tz], tz_parsed_time[tz].tm_hour); StringSetAddF(classes, "%sHr%d", tz_prefix[tz], tz_parsed_time[tz].tm_hour); /* Quarter */ quarter = tz_parsed_time[tz].tm_min / 15 + 1; StringSetAddF(classes, "%sQ%d", tz_prefix[tz], quarter); StringSetAddF(classes, "%sHr%02d_Q%d", tz_prefix[tz], tz_parsed_time[tz].tm_hour, quarter); /* Minute */ StringSetAddF(classes, "%sMin%02d", tz_prefix[tz], tz_parsed_time[tz].tm_min); interval_start = (tz_parsed_time[tz].tm_min / 5) * 5; interval_end = (interval_start + 5) % 60; StringSetAddF(classes, "%sMin%02d_%02d", tz_prefix[tz], interval_start, interval_end); } return classes; } static void AddTimeClass(EvalContext *ctx, time_t time, const char* tags) { StringSet *time_classes = GetTimeClasses(time); if (time_classes == NULL) { return; } StringSetIterator iter = StringSetIteratorInit(time_classes); const char *time_class = NULL; while ((time_class = StringSetIteratorNext(&iter)) != NULL) { EvalContextClassPutHard(ctx, time_class, tags); } StringSetDestroy(time_classes); } void UpdateTimeClasses(EvalContext *ctx, time_t t) { RemoveTimeClass(ctx, "cfengine_internal_time_based_autoremove"); AddTimeClass(ctx, t, "time_based,cfengine_internal_time_based_autoremove,source=agent"); } cfengine-3.24.2/libenv/zones.c0000644000000000000000000000437615010704253016146 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #ifdef HAVE_ZONE_H # include #endif #ifndef __MINGW32__ bool IsGlobalZone() { #ifdef HAVE_GETZONEID zoneid_t zid; char zone[ZONENAME_MAX]; zid = getzoneid(); getzonenamebyid(zid, zone, ZONENAME_MAX); if (strcmp(zone, "global") == 0) { return true; } #endif return false; } bool ForeignZone(char *s) { // We want to keep the banner if (strstr(s, "PID")) { return false; } # ifdef HAVE_GETZONEID zoneid_t zid; char *sp, zone[ZONENAME_MAX]; zid = getzoneid(); getzonenamebyid(zid, zone, ZONENAME_MAX); if (strcmp(zone, "global") == 0) { if (StringStartsWith(s, "global") && isspace(s[6])) { for (sp = s + strlen(s) - 1; isspace(*sp); sp--) { *sp = '\0'; } return false; } else { return true; } } # endif return false; } #ifdef HAVE_GETZONEID #define ZONE_ONLY #else #define ZONE_ONLY ARG_UNUSED #endif int CurrentZoneName(ZONE_ONLY char *s) { # ifdef HAVE_GETZONEID zoneid_t zid = getzoneid(); if (zid >= 0) { return getzonenamebyid(zid, s, ZONENAME_MAX); } # endif return -1; } #endif // !__MINGW32__ cfengine-3.24.2/libenv/sysinfo.h0000644000000000000000000000302015010704253016470 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SYSINFO_H #define CFENGINE_SYSINFO_H /* TODO libpromises depends on libenv, the opposite should not happen! */ #include void DetectEnvironment(EvalContext *ctx); void CreateHardClassesFromCanonification(EvalContext *ctx, const char *canonified, char *tags); int GetUptimeMinutes(time_t now); int GetUptimeSeconds(time_t now); void GetInterfacesInfo(EvalContext *ctx); void GetNetworkingInfo(EvalContext *ctx); JsonElement* GetNetworkingConnections(EvalContext *ctx); JsonElement* GetUserInfo(const void *passwd); #endif cfengine-3.24.2/m4/0000755000000000000000000000000015010704322013670 5ustar00rootroot00000000000000cfengine-3.24.2/m4/adl_recursive_eval.m40000644000000000000000000000116715010704253020000 0ustar00rootroot00000000000000dnl adl_RECURSIVE_EVAL(VALUE, RESULT) dnl ================================= dnl Interpolate the VALUE in loop until it doesn't change, dnl and set the result to $RESULT. dnl WARNING: It's easy to get an infinite loop with some unsane input. AC_DEFUN([adl_RECURSIVE_EVAL], [_lcl_receval="$1" $2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do _lcl_receval_old="[$]_lcl_receval" eval _lcl_receval="\"[$]_lcl_receval\"" done echo "[$]_lcl_receval")`]) cfengine-3.24.2/m4/lt~obsolete.m40000644000000000000000000001377415010704273016525 0ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) cfengine-3.24.2/m4/old-autoconf.m40000644000000000000000000001260715010704253016535 0ustar00rootroot00000000000000AC_DEFUN([AC_TYPE_LONG_DOUBLE], [ AC_CACHE_CHECK([for long double], [ac_cv_type_long_double], [if test "$GCC" = yes; then ac_cv_type_long_double=yes else AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [[/* The Stardent Vistra knows sizeof (long double), but does not support it. */ long double foo = 0.0L;]], [[/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ sizeof (double) <= sizeof (long double)]])], [ac_cv_type_long_double=yes], [ac_cv_type_long_double=no]) fi]) if test $ac_cv_type_long_double = yes; then AC_DEFINE([HAVE_LONG_DOUBLE], 1, [Define to 1 if the system has the type `long double'.]) fi ]) AC_DEFUN([AC_TYPE_LONG_LONG_INT], [ AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], [AC_LINK_IFELSE( [_AC_TYPE_LONG_LONG_SNIPPET], [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. dnl If cross compiling, assume the bug isn't important, since dnl nobody cross compiles for this platform as far as we know. AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[@%:@include @%:@ifndef LLONG_MAX @%:@ define HALF \ (1LL << (sizeof (long long int) * CHAR_BIT - 2)) @%:@ define LLONG_MAX (HALF - 1 + HALF) @%:@endif]], [[long long int n = 1; int i; for (i = 0; ; i++) { long long int m = n << i; if (m >> i != n) return 1; if (LLONG_MAX / 2 < m) break; } return 0;]])], [ac_cv_type_long_long_int=yes], [ac_cv_type_long_long_int=no], [ac_cv_type_long_long_int=yes])], [ac_cv_type_long_long_int=no])]) if test $ac_cv_type_long_long_int = yes; then AC_DEFINE([HAVE_LONG_LONG_INT], 1, [Define to 1 if the system has the type `long long int'.]) fi ]) AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], [ AC_CACHE_CHECK([for unsigned long long int], [ac_cv_type_unsigned_long_long_int], [AC_LINK_IFELSE( [_AC_TYPE_LONG_LONG_SNIPPET], [ac_cv_type_unsigned_long_long_int=yes], [ac_cv_type_unsigned_long_long_int=no])]) if test $ac_cv_type_unsigned_long_long_int = yes; then AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1, [Define to 1 if the system has the type `unsigned long long int'.]) fi ]) AC_DEFUN([AC_TYPE_INTMAX_T], [ AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) AC_CHECK_TYPE([intmax_t], [AC_DEFINE([HAVE_INTMAX_T], 1, [Define to 1 if the system has the type `intmax_t'.])], [test $ac_cv_type_long_long_int = yes \ && ac_type='long long int' \ || ac_type='long int' AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], [Define to the widest signed integer type if and do not define.])]) ]) AC_DEFUN([AC_TYPE_UINTMAX_T], [ AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) AC_CHECK_TYPE([uintmax_t], [AC_DEFINE([HAVE_UINTMAX_T], 1, [Define to 1 if the system has the type `uintmax_t'.])], [test $ac_cv_type_unsigned_long_long_int = yes \ && ac_type='unsigned long long int' \ || ac_type='unsigned long int' AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type], [Define to the widest unsigned integer type if and do not define.])]) ]) AC_DEFUN([AC_TYPE_UINTPTR_T], [ AC_CHECK_TYPE([uintptr_t], [AC_DEFINE([HAVE_UINTPTR_T], 1, [Define to 1 if the system has the type `uintptr_t'.])], [for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do AC_COMPILE_IFELSE( [AC_LANG_BOOL_COMPILE_TRY( [AC_INCLUDES_DEFAULT], [[sizeof (void *) <= sizeof ($ac_type)]])], [AC_DEFINE_UNQUOTED([uintptr_t], [$ac_type], [Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it.]) ac_type=]) test -z "$ac_type" && break done]) ]) AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], [ AC_LANG_PROGRAM( [[/* For now, do not test the preprocessor; as of 2007 there are too many implementations with broken preprocessors. Perhaps this can be revisited in 2012. In the meantime, code should not expect #if to work with literals wider than 32 bits. */ /* Test literals. */ long long int ll = 9223372036854775807ll; long long int nll = -9223372036854775807LL; unsigned long long int ull = 18446744073709551615ULL; /* Test constant expressions. */ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 ? 1 : -1)]; int i = 63;]], [[/* Test availability of runtime routines for shift and division. */ long long int llmax = 9223372036854775807ll; unsigned long long int ullmax = 18446744073709551615ull; return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) | (llmax / ll) | (llmax % ll) | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) | (ullmax / ull) | (ullmax % ull));]]) ]) cfengine-3.24.2/m4/ltsugar.m40000644000000000000000000001044015010704273015617 0ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) cfengine-3.24.2/m4/ltversion.m40000644000000000000000000000127315010704273016167 0ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) cfengine-3.24.2/m4/ltoptions.m40000644000000000000000000003426215010704273016201 0ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) cfengine-3.24.2/m4/cf3_platforms.m40000644000000000000000000000407615010704253016706 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # # OS kernels conditionals. Don't use those unless it is really needed (if code # depends on the *kernel* feature, and even then -- some kernel features are # shared by different kernels). # # Good example: use LINUX to select code which uses inotify and netlink sockets. # Bad example: use LINUX to select code which parses output of coreutils' ps(1). # AM_CONDITIONAL([LINUX], [test -n "`echo ${target_os} | grep linux`"]) AM_CONDITIONAL([MACOSX], [test -n "`echo ${target_os} | grep darwin`"]) AM_CONDITIONAL([SOLARIS], [test -n "`(echo ${target_os} | egrep 'solaris|sunos')`"]) AM_CONDITIONAL([NT], [test -n "`(echo ${target_os} | egrep 'mingw|cygwin')`"]) AM_CONDITIONAL([CYGWIN], [test -n "`(echo ${target_os} | egrep 'cygwin')`"]) AM_CONDITIONAL([AIX], [test -n "`(echo ${target_os} | grep aix)`"]) AM_CONDITIONAL([HPUX], [test -n "`(echo ${target_os} | egrep 'hpux|hp-ux')`"]) AM_CONDITIONAL([FREEBSD], [test -n "`(echo ${target_os} | grep freebsd)`"]) AM_CONDITIONAL([NETBSD], [test -n "`(echo ${target_os} | grep netbsd)`"]) AM_CONDITIONAL([XNU], [test -n "`(echo ${target_os} | grep darwin)`"]) cfengine-3.24.2/m4/snprintf.m40000644000000000000000000002341215010704253016002 0ustar00rootroot00000000000000# $Id: snprintf.m4,v 1.1.1.1 2008/01/06 03:24:00 holger Exp $ # Copyright (c) 2008 Holger Weiss . # # This code may freely be used, modified and/or redistributed for any purpose. # It would be nice if additions and fixes to this file (including trivial code # cleanups) would be sent back in order to let me include them in the version # available at . However, this is # not a requirement for using or redistributing (possibly modified) versions of # this file, nor is leaving this notice intact mandatory. # HW_HEADER_STDARG_H # ------------------ # Define HAVE_STDARG_H to 1 if is available. AC_DEFUN([HW_HEADER_STDARG_H], [ AC_CHECK_HEADERS([stdarg.h]) ])# HW_HEADER_STDARG_H # HW_HEADER_VARARGS_H # ------------------- # Define HAVE_VARARGS_H to 1 if is available. AC_DEFUN([HW_HEADER_VARARGS_H], [ AC_CHECK_HEADERS([varargs.h]) ])# HW_HEADER_VARARGS_H # HW_FUNC_VA_COPY # --------------- # Set $hw_cv_func_va_copy to "yes" or "no". Define HAVE_VA_COPY to 1 if # $hw_cv_func_va_copy is set to "yes". Note that it's "unspecified whether # va_copy and va_end are macros or identifiers declared with external linkage." # (C99: 7.15.1, 1) Therefore, the presence of va_copy(3) cannot simply "be # tested with #ifdef", as suggested by the Autoconf manual (5.5.1). AC_DEFUN([HW_FUNC_VA_COPY], [ AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H. AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H. AC_CACHE_CHECK([for va_copy], [hw_cv_func_va_copy], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif]], [[va_list ap, aq; va_copy(aq, ap);]])], [hw_cv_func_va_copy=yes], [hw_cv_func_va_copy=no], [hw_cv_func_va_copy=no])]) AS_IF([test "$hw_cv_func_va_copy" = yes], [AC_DEFINE([HAVE_VA_COPY], [1], [Define to 1 if you have the `va_copy' function or macro.])]) ])# HW_FUNC_VA_COPY # HW_FUNC___VA_COPY # ----------------- # Set $hw_cv_func___va_copy to "yes" or "no". Define HAVE___VA_COPY to 1 if # $hw_cv_func___va_copy is set to "yes". AC_DEFUN([HW_FUNC___VA_COPY], [ AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H. AC_REQUIRE([HW_HEADER_VARARGS_H])dnl Our check evaluates HAVE_VARARGS_H. AC_CACHE_CHECK([for __va_copy], [hw_cv_func___va_copy], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_STDARG_H #include #elif HAVE_VARARGS_H #include #endif]], [[va_list ap, aq; __va_copy(aq, ap);]])], [hw_cv_func___va_copy=yes], [hw_cv_func___va_copy=no], [hw_cv_func___va_copy=no])]) AS_IF([test "$hw_cv_func___va_copy" = yes], [AC_DEFINE([HAVE___VA_COPY], [1], [Define to 1 if you have the `__va_copy' function or macro.])]) ])# HW_FUNC___VA_COPY # HW_FUNC_VSNPRINTF # ----------------- # Set $hw_cv_func_vsnprintf and $hw_cv_func_vsnprintf_c99 to "yes" or "no", # respectively. Define HAVE_VSNPRINTF to 1 only if $hw_cv_func_vsnprintf_c99 # is set to "yes". Otherwise, define vsnprintf to rpl_vsnprintf and make sure # the replacement function will be built. AC_DEFUN([HW_FUNC_VSNPRINTF], [ AC_REQUIRE([HW_HEADER_STDARG_H])dnl Our check evaluates HAVE_STDARG_H. dnl The following checks are not *required* to HAVE_VSNPRINTF, but they dnl should be checked (and pass!) for the test in snprintf.c to pass. AC_CHECK_HEADERS([inttypes.h locale.h stddef.h stdint.h]) AC_CHECK_MEMBERS([struct lconv.decimal_point, struct lconv.thousands_sep], [], [], [#include ]) AC_TYPE_LONG_DOUBLE AC_TYPE_LONG_LONG_INT AC_TYPE_UNSIGNED_LONG_LONG_INT AC_TYPE_SIZE_T AC_TYPE_INTMAX_T AC_TYPE_UINTMAX_T AC_TYPE_UINTPTR_T AC_CHECK_TYPES([ptrdiff_t]) AC_CHECK_FUNCS([localeconv]) AC_CHECK_FUNC([vsnprintf], [hw_cv_func_vsnprintf=yes], [hw_cv_func_vsnprintf=no]) AS_IF([test "$hw_cv_func_vsnprintf" = yes], [AC_CACHE_CHECK([whether vsnprintf is C99 compliant], [hw_cv_func_vsnprintf_c99], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#if HAVE_STDARG_H #include #endif #include static int testprintf(char *buf, size_t size, const char *format, ...) { int result; va_list ap; va_start(ap, format); result = vsnprintf(buf, size, format, ap); va_end(ap); return result; }]], [[char buf[43]; if (testprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || testprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || testprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ testprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1;]])], [hw_cv_func_vsnprintf_c99=yes], [hw_cv_func_vsnprintf_c99=no], [hw_cv_func_vsnprintf_c99=no])])], [hw_cv_func_snprintf_c99=no]) AS_IF( [test "$hw_cv_func_vsnprintf_c99" = yes], [AC_DEFINE([HAVE_VSNPRINTF], [1], [Define to 1 if you have a C99 compliant `vsnprintf' function.])], [ AC_DEFINE([vsnprintf], [rpl_vsnprintf], [Define to rpl_vsnprintf if the replacement function should be used.]) AC_DEFINE([vprintf], [rpl_vprintf], [Define to rpl_vprintf if the replacement function should be used.]) AC_DEFINE([vfprintf], [rpl_vfprintf], [Define to rpl_vfprintf if the replacement function should be used.]) _HW_FUNC_XPRINTF_REPLACE ]) ])# HW_FUNC_VSNPRINTF # HW_FUNC_SNPRINTF # ---------------- # Set $hw_cv_func_snprintf and $hw_cv_func_snprintf_c99 to "yes" or "no", # respectively. Define HAVE_SNPRINTF to 1 only if $hw_cv_func_snprintf_c99 # is set to "yes". Otherwise, define snprintf to rpl_snprintf and make sure # the replacement function will be built. AC_DEFUN([HW_FUNC_SNPRINTF], [ AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our snprintf(3) calls vsnprintf(3). AC_CHECK_FUNC([snprintf], [hw_cv_func_snprintf=yes], [hw_cv_func_snprintf=no]) AS_IF([test "$hw_cv_func_snprintf" = yes], [AC_CACHE_CHECK([whether snprintf is C99 compliant], [hw_cv_func_snprintf_c99], [AC_RUN_IFELSE( [AC_LANG_PROGRAM([[#include ]], [[char buf[43]; if (snprintf(buf, 4, "The answer is %27.2g.", 42.0) != 42 || snprintf(buf, 0, "No, it's %32zu.", (size_t)42) != 42 || buf[0] != 'T' || buf[3] != '\0' || snprintf(NULL, 0, "") != 0 || /* POSSIBLE SEGFAULT ON NON-C99 LIBCs!!! */ snprintf(NULL, 0, "Some actual %18s formatting.\nblah %d.\n", "42", 1) != 51) return 1;]])], [hw_cv_func_snprintf_c99=yes], [hw_cv_func_snprintf_c99=no], [hw_cv_func_snprintf_c99=no])])], [hw_cv_func_snprintf_c99=no]) AS_IF( [test "$hw_cv_func_snprintf_c99" = yes], [AC_DEFINE([HAVE_SNPRINTF], [1], [Define to 1 if you have a C99 compliant `snprintf' function.])], [ AC_DEFINE([snprintf], [rpl_snprintf], [Define to rpl_snprintf if the replacement function should be used.]) AC_DEFINE([printf], [rpl_printf], [Define to rpl_printf if the replacement function should be used.]) AC_DEFINE([fprintf], [rpl_fprintf], [Define to rpl_fprintf if the replacement function should be used.]) _HW_FUNC_XPRINTF_REPLACE ]) ])# HW_FUNC_SNPRINTF # HW_FUNC_VASPRINTF # ----------------- # Set $hw_cv_func_vasprintf to "yes" or "no". Define HAVE_VASPRINTF to 1 if # $hw_cv_func_vasprintf is set to "yes". Otherwise, define vasprintf to # rpl_vasprintf and make sure the replacement function will be built. AC_DEFUN([HW_FUNC_VASPRINTF], [ AC_REQUIRE([HW_FUNC_VSNPRINTF])dnl Our vasprintf(3) calls vsnprintf(3). # Don't even bother checking for vasprintf if snprintf was standards # incompliant, this one is going to be too. AS_IF([test "$hw_cv_func_snprintf_c99" = yes], [AC_CHECK_FUNCS([vasprintf], [hw_cv_func_vasprintf=yes], [hw_cv_func_vasprintf=no]) ], [hw_cv_func_vasprintf=no]) AS_IF([test "$hw_cv_func_vasprintf" = no], [AC_DEFINE([vasprintf], [rpl_vasprintf], [Define to rpl_vasprintf if the replacement function should be used.]) AC_CHECK_HEADERS([stdlib.h]) HW_FUNC_VA_COPY AS_IF([test "$hw_cv_func_va_copy" = no], [HW_FUNC___VA_COPY]) _HW_FUNC_XPRINTF_REPLACE]) ])# HW_FUNC_VASPRINTF # HW_FUNC_ASPRINTF # ---------------- # Set $hw_cv_func_asprintf to "yes" or "no". Define HAVE_ASPRINTF to 1 if # $hw_cv_func_asprintf is set to "yes". Otherwise, define asprintf to # rpl_asprintf and make sure the replacement function will be built. AC_DEFUN([HW_FUNC_ASPRINTF], [ AC_REQUIRE([HW_FUNC_VASPRINTF])dnl Our asprintf(3) calls vasprintf(3). # Don't even bother checking for asprintf if snprintf was standards # incompliant, this one is going to be too. AS_IF([test "$hw_cv_func_snprintf_c99" = yes], [AC_CHECK_FUNCS([asprintf], [hw_cv_func_asprintf=yes], [hw_cv_func_asprintf=no]) ], [hw_cv_func_asprintf=no]) AS_IF([test "$hw_cv_func_asprintf" = no], [AC_DEFINE([asprintf], [rpl_asprintf], [Define to rpl_asprintf if the replacement function should be used.]) _HW_FUNC_XPRINTF_REPLACE]) ])# HW_FUNC_ASPRINTF # _HW_FUNC_XPRINTF_REPLACE # ------------------------ # Arrange for building snprintf.c. Must be called if one or more of the # functions provided by snprintf.c are needed. # XXX: We provide an empty version of this macro because building snprintf.c is # taken care of in libntech/libutils and its libcompat not in libcfecompat. AC_DEFUN([_HW_FUNC_XPRINTF_REPLACE], [ ])# _HW_FUNC_XPRINTF_REPLACE dnl vim: set joinspaces textwidth=80: cfengine-3.24.2/m4/acinclude.m40000644000000000000000000001705615010704253016075 0ustar00rootroot00000000000000dnl From http://ac-archive.sourceforge.net/ac-archive/acx_pthread.html AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE AC_LANG_C acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) AC_MSG_RESULT($acx_pthread_ok) if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt -mthreads pthread --thread-safe pthread-config pthreadGC2" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [acx_pthread_ok=yes]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($acx_pthread_ok) if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_TRY_LINK([#include ], [int attr=$attr; return attr;], [attr_name=$attr; break]) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else acx_pthread_ok=no $2 fi AC_LANG_RESTORE ])dnl ACX_PTHREAD m4_ifdef([AC_PROG_MKDIR_P], [ dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed. m4_define([AC_PROG_MKDIR_P], m4_defn([AC_PROG_MKDIR_P])[ AC_SUBST([MKDIR_P])])], [ dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P. AC_DEFUN([AC_PROG_MKDIR_P], [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake MKDIR_P='$(mkdir_p)' AC_SUBST([MKDIR_P])])]) cfengine-3.24.2/m4/cf3_path_root_prog.m40000644000000000000000000000351215010704253017717 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # CF3_PATH_ROOT_PROG(variable, program, value-if-not-found, path = $PATH) # -------------------------------------- # # This function has almost the same semantics as the AC_PATH_PROG # function. The difference is that this will detect tools that are # runnable by root, but not by the current user. These tools are # typically used not by the build, but by CFEngine itself, after # it is installed. # AC_DEFUN([CF3_PATH_ROOT_PROG], [ found=0 AS_IF([test "x$4" = "x"], [ path=$PATH ], [ path=$4 ]) AS_ECHO_N(["checking for $2... "]) for i in $(echo $path | sed -e 's/:/ /g'); do AS_IF([test -e $i/$2 && ls -ld $i/$2 | grep ['^[^ ][^ ][^ ][xs][^ ][^ ][^ ][^ ][^ ][^ ]'] > /dev/null], [ $1=$i/$2 found=1 break ]) done AS_IF([test "$found" = "1"], [ AS_ECHO(["$][$1"]) ], [ AS_ECHO([no]) $1=$3 ]) ]) cfengine-3.24.2/m4/libtool.m40000644000000000000000000112617115010704273015614 0ustar00rootroot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS cfengine-3.24.2/m4/tar.m40000644000000000000000000001235115010704253014725 0ustar00rootroot00000000000000# Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2015 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done # Work around CFEngine redmine #6925 by using --hard-dereference. AM_RUN_LOG([$_am_tar --hard-dereference 2>&1 | grep 'unrecognized option']) # Check if --hard-dereference is supported by this version of GNU Tar if test "$ac_status" -eq 0; then _am_gnutar_hard_dereference=false am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' else _am_gnutar_hard_dereference=true am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) --hard-dereference -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) --hard-dereference -chf - "'"$tardir"' fi am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) if test $_am_tool = gnutar; then # We've checked already, so we're just printing here AC_MSG_CHECKING([if GNU tar supports --hard-dereference]) if test x$_am_gnutar_hard_dereference = xtrue; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR cfengine-3.24.2/m4/cf3_with_library.m40000644000000000000000000000600015010704253017363 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # CF3_WITH_LIBRARY(library-name, checks) # -------------------------------------- # # This function popluates CFLAGS, CPPFLAGS and LDFLAGS from the # --with-$library=PATH and runs a second argument with those options. # # After execution flags are returned to previous state, but available in # ${LIBRARY}_{CFLAGS,LDFLAGS}. Path is available in ${LIBRARY}_PATH. # # Libraries added to LIBS are available as ${LIBRARY}_LIBS afterwards. # AC_DEFUN([CF3_WITH_LIBRARY], [ m4_define([ULN],m4_toupper($1)) # # Populate ${LIBRARY}_{PATH,CFLAGS,LDFLAGS} according to arguments # if test "x$with_[$1]" != xyes && test "x$with_[$1]" != xcheck && test "x$with_[$1]" != x then test -z "$ULN[]_PATH" && ULN[]_PATH="$with_[$1]" if test "x$with_[$1]" != x/usr && test "x$with_[$1]" != x/ then test -z "$ULN[]_CFLAGS" && ULN[]_CFLAGS="" test -z "$ULN[]_CPPFLAGS" && ULN[]_CPPFLAGS="-I$with_[$1]/include" test -z "$ULN[]_LDFLAGS" && ULN[]_LDFLAGS="-L$with_[$1]/lib" fi else ULN[]_PATH="default path" fi # # Save old environment # save_CFLAGS="$CFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LDFLAGS="$LDFLAGS" save_LIBS="$LIBS" CFLAGS="$CFLAGS $ULN[]_CFLAGS" CPPFLAGS="$CPPFLAGS $ULN[]_CPPFLAGS" LDFLAGS="$LDFLAGS $ULN[]_LDFLAGS" # # Run checks passed as argument # $2 # # Pick up any libraries added by tests # test -z "$ULN[]_LIBS" && ULN[]_LIBS="$LIBS" # # libtool understands -R$path, but we are not using libtool in configure # snippets, so -R$path goes to $pkg_LDFLAGS only after autoconf tests # if test "x$with_[$1]" != xyes && test "x$with_[$1]" != xcheck && test "x$with_[$1]" != x/usr && test "x$with_[$1]" != x/ then ULN[]_LDFLAGS="$ULN[]_LDFLAGS -R$with_[$1]/lib" fi # # Restore pristine environment # CFLAGS="$save_CFLAGS" CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" AC_SUBST(ULN[]_PATH) AC_SUBST(ULN[]_CPPFLAGS) AC_SUBST(ULN[]_CFLAGS) AC_SUBST(ULN[]_LDFLAGS) AC_SUBST(ULN[]_LIBS) ]) cfengine-3.24.2/m4/cf3_check_proper_func.m40000644000000000000000000000513415010704253020352 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # dnl dnl Arguments: dnl $1 - function name dnl $2 - headers (to compile $3) dnl $3 - body for compilation dnl $4 - function invocation dnl dnl This macro checks that the function (argument 1) is defined, dnl and that the code piece (arguments 2, 3, like in AC_LANG_PROGRAM) can be dnl compiled. dnl dnl If the code compiles successfully, it defines HAVE_$1_PROPER macro. dnl dnl If the code fails, it adds '$4' to $post_macros variable. dnl If you want rpl_$1.c to be compiled as a replacement, call dnl CF3_REPLACE_PROPER_FUNC with the same function name. dnl dnl ** How to use ** dnl dnl CF3_CHECK_PROPER_FUNC(function, [#include ], [void function(FILE *);], [#define function rpl_function]) dnl CF3_REPLACE_PROPER_FUNC(function) dnl dnl Then in libutils/platform.h: dnl dnl #if !HAVE_FUNCTION_PROPER dnl void rpl_function(FILE *); dnl #endif dnl dnl And libcompat/rpl_function.c: dnl dnl #include "platform.h" dnl dnl void rpl_function(FILE *) { ... } dnl AC_DEFUN([CF3_CHECK_PROPER_FUNC], [ AC_CHECK_FUNC([$1], [], [AC_MSG_ERROR([Unable to find function $1])]) AC_CACHE_CHECK([whether $1 is properly declared], [hw_cv_func_$1_proper], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([$2],[$3])], [hw_cv_func_$1_proper=yes], [hw_cv_func_$1_proper=no])]) AC_SUBST([hw_cv_func_$1_proper]) AS_IF([test "$hw_cv_func_$1_proper" = yes], [AC_DEFINE([HAVE_$1_PROPER], [1], [Define to 1 if you have properly defined `$1' function])], [post_macros="$post_macros $4"]) ]) AC_DEFUN([CF3_REPLACE_PROPER_FUNC], [ AS_IF([test "$hw_cv_func_$1_proper" = "no"], [AC_LIBOBJ(rpl_$1)] ) ]) cfengine-3.24.2/m4/cf3_gcc_flags.m40000644000000000000000000000603215010704253016601 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # dnl #################################################################### dnl Set GCC CFLAGS only if using GCC. dnl #################################################################### AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ #if defined __HP_cc #This is HP-UX ANSI C #endif ]])], [ HP_UX_AC="no"], [ CFLAGS="$CFLAGS -Agcc" CPPFLAGS="$CPPFLAGS -Agcc" HP_UX_AC="yes"]) AC_MSG_CHECKING(for HP-UX aC) if test "x$HP_UX_AC" = "xyes"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi AC_MSG_CHECKING(for GCC specific compile flags) if test x"$GCC" = "xyes" && test x"$HP_UX_AC" != x"yes"; then CFLAGS="$CFLAGS -g -Wall" CPPFLAGS="$CPPFLAGS -std=gnu99" AC_MSG_RESULT(yes) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wno-pointer-sign" AC_MSG_CHECKING(for -Wno-pointer-sign) AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main() {}])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) CFLAGS="$save_CFLAGS"]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror=implicit-function-declaration" AC_MSG_CHECKING(for -Werror=implicit-function-declaration) AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main() {}])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) CFLAGS="$save_CFLAGS"]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Wunused-parameter" AC_MSG_CHECKING(for -Wunused-parameter) AC_COMPILE_IFELSE([AC_LANG_SOURCE([int main() {}])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) CFLAGS="$save_CFLAGS"]) dnl Clang does not like 'const const' construct arising from dnl expansion of TYPED_SET_DECLARE macro dnl dnl This check is relying on explicit compilator detection due to dnl GCC irregularities checking for -Wno-* command-line options dnl (command line is not fully checked until actual warning occurs) AC_MSG_CHECKING(for -Wno-duplicate-decl-specifier) AC_COMPILE_IFELSE([AC_LANG_SOURCE([#ifndef __clang__ # error Not a clang #endif int main() {}])], [AC_MSG_RESULT(yes) CFLAGS="$save_CFLAGS -Wno-duplicate-decl-specifier"], [AC_MSG_RESULT(no)]) else AC_MSG_RESULT(no) fi cfengine-3.24.2/README.md0000644000000000000000000000732215010704253014636 0ustar00rootroot00000000000000[![Gitter chat](https://badges.gitter.im/cfengine/core.png)](https://gitter.im/cfengine/core) # CFEngine 3 CFEngine 3 is a popular open source configuration management system. Its primary function is to provide automated configuration and maintenance of large-scale computer systems. ## Source code repositories CFEngine is comprised of several source code repositories. As you might be looking for another part of the open source code base, here is a list to ease navigation: * [core](https://github.com/cfengine/core) (This repo) - The C source code for core components, like cf-agent and cf-serverd. * [libntech](https://github.com/NorthernTechHQ/libntech) (submodule in core) - Library of reusable C code, such as data structures, string manipulation, JSON parsing, file handling, etc. * [core/contrib](https://github.com/cfengine/core/tree/master/contrib) (subdirectory in core) - User-contributed tools and scripts * [masterfiles](https://github.com/cfengine/masterfiles) - The Masterfiles Policy Framework (MPF) contains the default policy (.cf) files * [documentation](https://github.com/cfengine/documentation) - Documentation on how CFEngine components work, the policy language, the enterprise features, etc. * [cf-remote](https://github.com/cfengine/cf-remote) - Tooling to make deploying / testing CFEngine across many remote instances easy * [buildscripts](https://github.com/cfengine/buildscripts) - Scripts and files needed to build installer packages across a wide variety of supported platforms (Each repo also contains some supporting code/files, such as tests, scripts, documentation, etc.). ## Installation Pre-built installers are available from our website: * [Download CFEngine Enterprise Installers](https://cfengine.com/product/cfengine-enterprise-free-25/) * [Download CFEngine Community Installers](https://cfengine.com/product/community/) To install from source please see the [INSTALL](https://github.com/cfengine/core/blob/master/INSTALL) file for prerequisites and build instructions. ## License As per the [LICENSE](https://github.com/cfengine/core/blob/master/LICENSE) file, CFEngine Community is licensed under the GNU General Public License, version 3. All the files in this repository are licensed under GNU GPL version 3, unless stated otherwise in the copyright notice inside the particular file. ## Example Usage In order to use the built cf-agent in the source tree you must add a $HOME/.cfagent/bin/cf-promises file: $ pwd /core $ echo "cd $(pwd); cf-promises/cf-promises \"\$@\"" > ~/.cfagent/bin/cf-promises ### Hello World The following code demonstrates simple CFEngine output through a reports promise. ```cfengine3 bundle agent main { reports: "Hello, world"; } ``` The following policy code may be executed with cf-agent (the main CFEngine binary) as follows. ```bash $ cf-agent/cf-agent ./hello.cf R: Hello, world ``` ## Debugging As this project uses autotools you must use libtool to run gdb/lldb/debuggers ./libtool --mode=execute ./cf-agent/cf-agent ## Contributing Please see the [CONTRIBUTING.md](https://github.com/cfengine/core/blob/master/CONTRIBUTING.md) file. ## Relationship to CFEngine 2 CFEngine 3 is *not* a drop-in upgrade for CFEngine 2 installations. It is a significantly more powerful version, but it is incompatible with the CFEngine 2 policy language. The server part of CFEngine 3 supports the network protocol of CFEngine 2, so you may upgrade your installation gradually. # Authors CFEngine was originally created by Mark Burgess with many contributions from around the world. Thanks [everyone](https://github.com/cfengine/core/blob/master/AUTHORS)! [CFEngine](https://cfengine.com) is sponsored by [Northern.tech AS](https://northern.tech) cfengine-3.24.2/ext/0000755000000000000000000000000015010704323014151 5ustar00rootroot00000000000000cfengine-3.24.2/ext/Makefile.am0000644000000000000000000000206015010704253016205 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # bin_PROGRAMS = rpmvercmp LDADD = ../libntech/libcompat/libcompat.la cfengine-3.24.2/ext/Makefile.in0000644000000000000000000005566715010704300016234 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = rpmvercmp$(EXEEXT) subdir = ext ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) rpmvercmp_SOURCES = rpmvercmp.c rpmvercmp_OBJECTS = rpmvercmp.$(OBJEXT) rpmvercmp_LDADD = $(LDADD) rpmvercmp_DEPENDENCIES = ../libntech/libcompat/libcompat.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = rpmvercmp.c DIST_SOURCES = rpmvercmp.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ LDADD = ../libntech/libcompat/libcompat.la all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ext/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu ext/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list rpmvercmp$(EXEEXT): $(rpmvercmp_OBJECTS) $(rpmvercmp_DEPENDENCIES) $(EXTRA_rpmvercmp_DEPENDENCIES) @rm -f rpmvercmp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rpmvercmp_OBJECTS) $(rpmvercmp_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpmvercmp.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/ext/rpmvercmp.c0000644000000000000000000001517115010704253016337 0ustar00rootroot00000000000000/* rpmvercmp.c contains code from RPM project, licensed as the following: RPM and it's source code are covered under two separate licenses. The entire code base may be distributed under the terms of the GNU General Public License (GPL), which appears immediately below. Alternatively, all of the source code in the lib subdirectory of the RPM source code distribution as well as any code derived from that code may instead be distributed under the GNU Library General Public License (LGPL), at the choice of the distributor. The complete text of the LGPL appears at the bottom of this file. This alternatively is allowed to enable applications to be linked against the RPM library (commonly called librpm) without forcing such applications to be distributed under the GPL. Any questions regarding the licensing of RPM should be addressed to marc@redhat.com and ewt@redhat.com. */ #include #include #include #include #include static inline int rstreq(const char *s1, const char *s2) { return (strcmp(s1, s2) == 0); } static inline int rislower(int c) { return (c >= 'a' && c <= 'z'); } static inline int risupper(int c) { return (c >= 'A' && c <= 'Z'); } static inline int risalpha(int c) { return (rislower(c) || risupper(c)); } static inline int risdigit(int c) { return (c >= '0' && c <= '9'); } static inline int risalnum(int c) { return (risalpha(c) || risdigit(c)); } static int rpmvercmp(const char * a, const char * b) { /* easy comparison to see if versions are identical */ if (rstreq(a, b)) return 0; char oldch1, oldch2; char abuf[strlen(a)+1], bbuf[strlen(b)+1]; char *str1 = abuf, *str2 = bbuf; char * one, * two; int rc; int isnum; strcpy(str1, a); strcpy(str2, b); one = str1; two = str2; /* loop through each version segment of str1 and str2 and compare them */ while (*one || *two) { while (*one && !risalnum(*one) && *one != '~') one++; while (*two && !risalnum(*two) && *two != '~') two++; /* handle the tilde separator, it sorts before everything else */ if (*one == '~' || *two == '~') { if (*one != '~') return 1; if (*two != '~') return -1; one++; two++; continue; } /* If we ran to the end of either, we are finished with the loop */ if (!(*one && *two)) break; str1 = one; str2 = two; /* grab first completely alpha or completely numeric segment */ /* leave one and two pointing to the start of the alpha or numeric */ /* segment and walk str1 and str2 to end of segment */ if (risdigit(*str1)) { while (*str1 && risdigit(*str1)) str1++; while (*str2 && risdigit(*str2)) str2++; isnum = 1; } else { while (*str1 && risalpha(*str1)) str1++; while (*str2 && risalpha(*str2)) str2++; isnum = 0; } /* save character at the end of the alpha or numeric segment */ /* so that they can be restored after the comparison */ oldch1 = *str1; *str1 = '\0'; oldch2 = *str2; *str2 = '\0'; /* this cannot happen, as we previously tested to make sure that */ /* the first string has a non-null segment */ if (one == str1) return -1; /* arbitrary */ /* take care of the case where the two version segments are */ /* different types: one numeric, the other alpha (i.e. empty) */ /* numeric segments are always newer than alpha segments */ /* XXX See patch #60884 (and details) from bugzilla #50977. */ if (two == str2) return (isnum ? 1 : -1); if (isnum) { size_t onelen, twolen; /* this used to be done by converting the digit segments */ /* to ints using atoi() - it's changed because long */ /* digit segments can overflow an int - this should fix that. */ /* throw away any leading zeros - it's a number, right? */ while (*one == '0') one++; while (*two == '0') two++; /* whichever number has more digits wins */ onelen = strlen(one); twolen = strlen(two); if (onelen > twolen) return 1; if (twolen > onelen) return -1; } /* strcmp will return which one is greater - even if the two */ /* segments are alpha or if they are numeric. don't return */ /* if they are equal because there might be more segments to */ /* compare */ rc = strcmp(one, two); if (rc) return (rc < 1 ? -1 : 1); /* restore character that was replaced by null above */ *str1 = oldch1; one = str1; *str2 = oldch2; two = str2; } /* this catches the case where all numeric and alpha segments have */ /* compared identically but the segment sepparating characters were */ /* different */ if ((!*one) && (!*two)) return 0; /* whichever version still has characters left over wins */ if (!*one) return -1; else return 1; } typedef struct { char *epoch; char *version; char *release; } EVR; static void parseEVR(char * evr, EVR *evr_parsed) { char *s, *se; s = evr; while (*s && risdigit(*s)) s++; /* s points to epoch terminator */ se = strrchr(s, '-'); /* se points to version terminator */ if (*s == ':') { evr_parsed->epoch = evr; *s++ = '\0'; evr_parsed->version = s; if (*(evr_parsed->epoch) == '\0') evr_parsed->epoch = "0"; } else { evr_parsed->epoch = NULL; /* XXX disable epoch compare if missing */ evr_parsed->version = evr; } if (se) { *se++ = '\0'; evr_parsed->release = se; } else { evr_parsed->release = NULL; } } static int rpmVersionCompare(EVR *first, EVR *second) { uint32_t epochOne = first->epoch ? atoi(first->epoch) : 0; uint32_t epochTwo = second->epoch ? atoi(second->epoch) : 0; int rc; if (epochOne < epochTwo) return -1; else if (epochOne > epochTwo) return 1; rc = rpmvercmp(first->version, second->version); if (rc) return rc; return rpmvercmp(first->release ? first->release : "", second->release ? second->release : ""); } static void usage(void) { fprintf(stderr, "Usage: rpmvercmp lt \n"); fprintf(stderr, " rpmvercmp eq \n"); fprintf(stderr, "\n"); fprintf(stderr, "Returns 0 if requested comparison holds, 1 otherwise\n"); } int main(int argc, char **argv) { if (argc != 4) { usage(); exit(255); } if (!rstreq(argv[2], "lt") && !rstreq(argv[2], "eq")) { usage(); exit(255); } EVR first, second; parseEVR(argv[1], &first); parseEVR(argv[3], &second); int rc = rpmVersionCompare(&first, &second); if (rstreq(argv[2], "lt")) { exit(rc == -1 ? EXIT_SUCCESS : EXIT_FAILURE); } else { exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } } cfengine-3.24.2/config.guess0000755000000000000000000012564415010704300015700 0ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-10-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || \ echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; mips64el:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac cat >&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: cfengine-3.24.2/config.sub0000755000000000000000000010676315010704300015344 0ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-11-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: cfengine-3.24.2/INSTALL0000644000000000000000000001153715010704253014413 0ustar00rootroot00000000000000PREREQUISITES ------------- In order to build CFEngine you need the following tools and libraries installed: * C compiler supporting C90 + selected C99 constructs: - _Bool type - anonymous aggregates "(MyType) { .foo = 1, .bar = 2 }" - declarations in "for" loop - named initializers - uintmax_t and corresponding printf/scanf formats The following compilers are known to work: - gcc >= 3.0 - clang >= 2.6 * GNU make * PAM library * OpenSSL library * PCRE2 library * POSIX threads (pthreads) library, if not provided by the operating system * Latest available LMDB (Lightning Memory-mapped DataBase), Tokyo Cabinet or QDBM * MySQL client library (optional) * PostgreSQL client library (optional) * libacl library (optional) In order to build CFEngine cloned from git, you will need the following additional tools: * GNU Automake >= 1.10.1 * GNU Autoconf >= 2.60 * GNU Libtool >= 1.5.24 * Yacc (note: GNU Bison 2.4.2 has troubles invoking m4) * Lex Latest stable versions of the tools and libraries are generally advised. See INSTALL DEPENDENCIES below for example of deps for various systems. OPERATING SYSTEMS ----------------- CFEngine is regularly built and tested on the following operating systems: * GNU/Linux (many distributions) * Solaris * Windows with MinGW HARDWARE PLATFORMS ------------------ CFEngine is regularly built and tested on the following CPU architectures: * x86 * x86-64 * SPARC OTHER CONFIGURATIONS -------------------- In case you have successfully compiled CFEngine on a different OS and/or using different tools or versions of tools, please report it to help-cfengine@ mailing list[1]. Please consider running a testsuite (see below), and posting results to mailing list too. [1] https://groups.google.com/forum/#!forum/help-cfengine BUILD INSTRUCTIONS ------------------ From tarball: $ ./configure [configure options] $ make [-jN] From git checkout: $ ./autogen.sh [configure options] $ make [-jN] See the available configure options: $ ./configure --help or $ ./autogen.sh --help INSTALLATION INSTRUCTIONS ------------------------- CFEngine might be installed in two configurations: * (default) Native CFEngine file layout. Everything is installed in /var/cfengine, laid out as a "secondary FHS root". This layout is designed to keep CFEngine running even if most of the system is broken (e.g. /usr is not mounted due to NFS breakage). * FHS file layout, enabled by --enable-fhs. This layout follows FHS 2.3. After the build process has completed (see BUILD INSTRUCTIONS above), type: $ make install RUNNING TESTSUITE ----------------- Please refer to the instructions in tests/README file. INSTALL DEPENDENCIES -------------------- Here we have examples of command lines for various systems to install dependencies needed to build. The version and date checked are noted in parenthesis. Please submit PRs with updates to this information. * RedHat/CentOS (rhel-9 2023-10-09) On CentOS: sudo yum install epel-release && sudo yum update Or on RHEL, replacing the version number with yours: sudo subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms && sudo yum update sudo yum install -y gcc gdb make git libtool autoconf automake byacc flex openssl-devel pcre2-devel lmdb-devel pam-devel flex-devel libyaml-devel fakeroot libxml2-devel For SELinux support you will need selinux-policy-devel package and specify `--with-selinux-policy` to `autogen.sh` or `configure` * Debian (Debian 12 2023-10-09) sudo apt-get install -y build-essential git libtool autoconf automake bison flex libssl-dev libpcre2-dev libbison-dev libacl1 libacl1-dev lmdb-utils liblmdb-dev libpam0g-dev libtool libyaml-dev libxml2-dev * NetBSD (9.3 2024-03-01) doas pkgin install automake autoconf bison pcre2 m4 libtool lmdb gmake LDFLAGS=-L/usr/pkg/lib CPPFLAGS=-I/usr/pkg/include ./autogen.sh --enable-debug --without-systemd-service --without-systemd-socket gmake -j8 doas /usr/pkg/bin/gmake install * OpenBSD (7.4 2024-02-15) pkg_add git automake-1.16.5 autoconf-2.71 bison pcre2 m4 libtool lmdb gmake MAKE=/usr/local/bin/gmake LDFLAGS=-L/usr/local/lib CPPFLAGS=-I/usr/local/include AUTOMAKE_VERSION=1.16 AUTOCONF_VERSION=2.71 ./autogen.sh --enable-debug gmake -j8 doas gmake install * FreeBSD (12.1 2020-04-07) See docs/BSD.md * SUSE (Tumbleweed 2020-02-02) sudo zypper install gdb gcc make lmdb autoconf automake libtool git python3 pcre2-devel libopenssl-devel pam-devel * AlpineOS (3.11.3 x86_64 2020-04-13) sudo apk add alpine-sdk lmdb-dev openssl-dev bison flex-dev acl-dev pcre2-dev autoconf automake libtool git python3 gdb ./autogen.sh --without-pam * Termux (2020-04-24) pkg install build-essential git autoconf automake bison flex liblmdb openssl pcre2 libacl libyaml ./autogen.sh --without-pam * OSX (2021-10-20) brew install openssl lmdb autoconf automake libtool bison flex pcre2 m4 gcc make ./autogen.sh --enable-debug cfengine-3.24.2/cf-key/0000755000000000000000000000000015010704322014526 5ustar00rootroot00000000000000cfengine-3.24.2/cf-key/Makefile.am0000644000000000000000000000315215010704253016566 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-key.la AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libpromises \ $(PCRE2_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(OPENSSL_CFLAGS) \ $(PCRE2_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_key_la_SOURCES = \ cf-key.c \ cf-key-functions.c cf-key-functions.h libcf_key_la_LIBADD = ../libpromises/libpromises.la if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-key cf_key_LDADD = libcf-key.la cf_key_SOURCES = endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-key/cf-key.c0000644000000000000000000003154715010704253016065 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* FILE_SEPARATOR */ #include #include bool SHOWHOSTS = false; /* GLOBAL_A */ bool NO_TRUNCATE = false; /* GLOBAL_A */ bool FORCEREMOVAL = false; /* GLOBAL_A */ bool REMOVEKEYS = false; /* GLOBAL_A */ bool LICENSE_INSTALL = false; /* GLOBAL_A */ char LICENSE_SOURCE[MAX_FILENAME] = ""; /* GLOBAL_A */ const char *remove_keys_host = NULL; /* GLOBAL_A */ static char *print_digest_arg = NULL; /* GLOBAL_A */ static char *trust_key_arg = NULL; /* GLOBAL_A */ static char *KEY_PATH = NULL; /* GLOBAL_A */ static int KEY_SIZE = 2048; /* GLOBAL_A */ bool LOOKUP_HOSTS = true; /* GLOBAL_A */ static GenericAgentConfig *CheckOpts(int argc, char **argv); /*******************************************************************/ /* Command line options */ /*******************************************************************/ static const char *const CF_KEY_SHORT_DESCRIPTION = "make private/public key-pairs for CFEngine authentication"; static const char *const CF_KEY_MANPAGE_LONG_DESCRIPTION = "The CFEngine key generator makes key pairs for remote authentication.\n"; static const Component COMPONENT = { .name = "cf-key", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; #define TIMESTAMP_VAL 1234 // Anything outside ASCII range. static const struct option OPTIONS[] = { {"help", no_argument, 0, 'h'}, {"inform", no_argument, 0, 'I'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"log-level", required_argument, 0, 'g'}, {"output-file", required_argument, 0, 'f'}, {"key-type", required_argument, 0, 'T'}, {"show-hosts", no_argument, 0, 's'}, {"no-truncate", no_argument, 0, 'N'}, {"remove-keys", required_argument, 0, 'r'}, {"force-removal", no_argument, 0, 'x'}, {"install-license", required_argument, 0, 'l'}, {"print-digest", optional_argument, 0, 'p'}, {"trust-key", required_argument, 0, 't'}, {"color", optional_argument, 0, 'C'}, {"timestamp", no_argument, 0, TIMESTAMP_VAL}, {"numeric", no_argument, 0, 'n'}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Print basic information about key generation", "Enable debugging output", "Output verbose information about the behaviour of cf-key", "Output the version of the software", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Specify an alternative output file than the default.", "Specify a RSA key size in bits, the default value is 2048.", "Show lastseen hostnames and IP addresses", "Don't truncate -s / --show-hosts output", "Remove keys for specified hostname/IP/MD5/SHA (cf-key -r SHA=12345, cf-key -r MD5=12345, cf-key -r host001, cf-key -r 203.0.113.1)", "Force removal of keys", "Install license file on Enterprise server (CFEngine Enterprise Only)", "Print digest of the specified public key", "Make cf-serverd/cf-agent trust the specified public key. Argument value is of the form [[USER@]IPADDR:]FILENAME where FILENAME is the local path of the public key for client at IPADDR address.", "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", "Log timestamps on each line of log output", "Do not lookup host names", NULL }; /*****************************************************************************/ typedef void (*CfKeySigHandler)(int signum); bool cf_key_interrupted = false; static void handleShowKeysSignal(int signum) { cf_key_interrupted = true; signal(signum, handleShowKeysSignal); } static void SetupSignalsForCfKey(CfKeySigHandler sighandler) { signal(SIGINT, sighandler); signal(SIGTERM, sighandler); signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGBUS, HandleSignalsForAgent); signal(SIGUSR1, HandleSignalsForAgent); signal(SIGUSR2, HandleSignalsForAgent); } int main(int argc, char *argv[]) { SetupSignalsForCfKey(HandleSignalsForAgent); GenericAgentConfig *config = CheckOpts(argc, argv); EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); const char *program_invocation_name = argv[0]; const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR); const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name); GenericAgentDiscoverContext(ctx, config, program_name); if (SHOWHOSTS) { SetupSignalsForCfKey(handleShowKeysSignal); ShowLastSeenHosts(!NO_TRUNCATE); GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return EXIT_SUCCESS; } if (print_digest_arg) { int rc = PrintDigest(print_digest_arg); free(print_digest_arg); GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return rc; } GenericAgentPostLoadInit(ctx); if (REMOVEKEYS) { int status; if (FORCEREMOVAL) { if (!strncmp(remove_keys_host, "SHA=", 3) || !strncmp(remove_keys_host, "MD5=", 3)) { status = ForceKeyRemoval(remove_keys_host); } else { status = ForceIpAddressRemoval(remove_keys_host); } } else { status = RemoveKeys(remove_keys_host, true); if (status == 0 || status == 1) { Log (LOG_LEVEL_VERBOSE, "Forced removal of entry '%s' was successful", remove_keys_host); status = EXIT_SUCCESS; } } GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return status; } if(LICENSE_INSTALL) { bool success = LicenseInstall(LICENSE_SOURCE); GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return success ? EXIT_SUCCESS : EXIT_FAILURE; } if (trust_key_arg != NULL) { char *filename, *ipaddr, *username; /* We will modify the argument to --trust-key. */ char *arg = xstrdup(trust_key_arg); ParseKeyArg(arg, &filename, &ipaddr, &username); /* Server IP address required to trust key on the client side. */ if (ipaddr == NULL) { Log(LOG_LEVEL_NOTICE, "Establishing trust might be incomplete. " "For completeness, use --trust-key IPADDR:filename"); } bool ret = TrustKey(filename, ipaddr, username); free(arg); GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return ret ? EXIT_SUCCESS : EXIT_FAILURE; } char *public_key_file, *private_key_file; if (KEY_PATH) { xasprintf(&public_key_file, "%s.pub", KEY_PATH); xasprintf(&private_key_file, "%s.priv", KEY_PATH); } else { public_key_file = PublicKeyFile(GetWorkDir()); private_key_file = PrivateKeyFile(GetWorkDir()); } bool ret = KeepKeyPromises(public_key_file, private_key_file, KEY_SIZE); free(public_key_file); free(private_key_file); GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return ret ? EXIT_SUCCESS : EXIT_FAILURE; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static void PrintHelp() { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, false); FileWriterDetach(w); } static GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int c; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_KEYGEN, GetTTYInteractive()); while ((c = getopt_long(argc, argv, "dvIf:g:T:VMp::sNr:xt:hl:C::n", OPTIONS, NULL)) != -1) { switch (c) { case 'f': KEY_PATH = optarg; break; case 'T': KEY_SIZE = StringToLongExitOnError(optarg); break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } GenericAgentConfigDestroy(config); DoCleanupAndExit(EXIT_SUCCESS); case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'p': /* print digest */ if (OPTIONAL_ARGUMENT_IS_PRESENT) { print_digest_arg = xstrdup(optarg); } else { print_digest_arg = PublicKeyFile(GetWorkDir()); } break; case 's': SHOWHOSTS = true; break; case 'N': NO_TRUNCATE = true; break; case 'x': FORCEREMOVAL = true; break; case 'r': REMOVEKEYS = true; remove_keys_host = optarg; break; case 'l': LICENSE_INSTALL = true; strlcpy(LICENSE_SOURCE, optarg, sizeof(LICENSE_SOURCE)); break; case 't': trust_key_arg = optarg; break; case 'h': PrintHelp(); GenericAgentConfigDestroy(config); DoCleanupAndExit(EXIT_SUCCESS); case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-key", time(NULL), CF_KEY_SHORT_DESCRIPTION, CF_KEY_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, false); FileWriterDetach(out); GenericAgentConfigDestroy(config); DoCleanupAndExit(EXIT_SUCCESS); } case 'C': if (!GenericAgentConfigParseColor(config, (OPTIONAL_ARGUMENT_IS_PRESENT) ? optarg : "auto")) { GenericAgentConfigDestroy(config); DoCleanupAndExit(EXIT_FAILURE); } break; case TIMESTAMP_VAL: LoggingEnableTimestamps(true); break; case 'n': LOOKUP_HOSTS = false; break; default: PrintHelp(); GenericAgentConfigDestroy(config); DoCleanupAndExit(EXIT_FAILURE); } } if (NO_TRUNCATE && !SHOWHOSTS) { PrintHelp(); Log(LOG_LEVEL_ERR, "--no-truncate / -N option is only for --show-hosts / -s"); GenericAgentConfigDestroy(config); DoCleanupAndExit(EXIT_FAILURE); } return config; } cfengine-3.24.2/cf-key/Makefile.in0000644000000000000000000006273715010704300016606 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-key$(EXEEXT) subdir = cf-key ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_key_la_DEPENDENCIES = ../libpromises/libpromises.la am_libcf_key_la_OBJECTS = cf-key.lo cf-key-functions.lo libcf_key_la_OBJECTS = $(am_libcf_key_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_cf_key_OBJECTS = cf_key_OBJECTS = $(am_cf_key_OBJECTS) @BUILTIN_EXTENSIONS_FALSE@cf_key_DEPENDENCIES = libcf-key.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_key_la_SOURCES) $(cf_key_SOURCES) DIST_SOURCES = $(libcf_key_la_SOURCES) $(cf_key_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-key.la AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libpromises \ $(PCRE2_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(OPENSSL_CFLAGS) \ $(PCRE2_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_key_la_SOURCES = \ cf-key.c \ cf-key-functions.c cf-key-functions.h libcf_key_la_LIBADD = ../libpromises/libpromises.la @BUILTIN_EXTENSIONS_FALSE@cf_key_LDADD = libcf-key.la @BUILTIN_EXTENSIONS_FALSE@cf_key_SOURCES = CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-key/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-key/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-key.la: $(libcf_key_la_OBJECTS) $(libcf_key_la_DEPENDENCIES) $(EXTRA_libcf_key_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_key_la_OBJECTS) $(libcf_key_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-key$(EXEEXT): $(cf_key_OBJECTS) $(cf_key_DEPENDENCIES) $(EXTRA_cf_key_DEPENDENCIES) @rm -f cf-key$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_key_OBJECTS) $(cf_key_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-key-functions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-key.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-key/cf-key-functions.h0000644000000000000000000000334615010704253020074 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CFKEYFUNCTIONS_H #define CFENGINE_CFKEYFUNCTIONS_H #include #include #include #include #include #include #include #include #include #include #include extern bool LOOKUP_HOSTS; int PrintDigest(const char *pubkey); void ParseKeyArg(char *keyarg, char **filename, char **ipaddr, char **username); void ShowLastSeenHosts(bool truncate); int RemoveKeys(const char *input, bool must_be_coherent); bool KeepKeyPromises(const char *public_key_file, const char *private_key_file, const int key_size); int ForceKeyRemoval(const char *key); int ForceIpAddressRemoval(const char *ip); #endif // CFKEYFUNCTIONS_H cfengine-3.24.2/cf-key/cf-key-functions.c0000644000000000000000000003351315010704253020066 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* BN_*, BIGNUM */ #include /* RAND_* */ #include #include #include #include #include #include #include #include #include #include #include #include /*****************************************************************************/ /** Print digest of the specified public key file. Return 0 on success and 1 on error. */ int PrintDigest(const char *pubkey) { char *digeststr = LoadPubkeyDigest(pubkey); if (digeststr == NULL) { return 1; /* ERROR exitcode */ } fprintf(stdout, "%s\n", digeststr); free(digeststr); return 0; /* OK exitcode */ } /** * Split a "key" argument of the form "[[user@]address:]filename" into * components (public) key file name, IP address, and (remote) user * name. Pointers to the corresponding segments of the #keyarg * string will be written into the three output arguments #filename, * #ipaddr, and #username. (Hence, the three output string have * the same lifetime/scope as the #keyarg string.) * * The only required component is the file name. If IP address is * missing, NULL is written into the #ipaddr pointer. If the * username is missing, #username will point to the constant string * "root". * * @NOTE the #keyarg argument is modified by this function! */ void ParseKeyArg(char *keyarg, char **filename, char **ipaddr, char **username) { char *s; /* set defaults */ *ipaddr = NULL; *username = "root"; /* use rightmost colon so we can cope with IPv6 addresses */ s = strrchr(keyarg, ':'); if (s == NULL) { /* no colon, entire argument is a filename */ *filename = keyarg; return; } *s = '\0'; /* split string */ *filename = s + 1; /* filename starts at 1st character after ':' */ s = strchr(keyarg, '@'); if (s == NULL) { /* no username given, use default */ *ipaddr = keyarg; return; } *s = '\0'; *ipaddr = s + 1; *username = keyarg; /* special case: if we got user@:/path/to/file then reset ipaddr to NULL instead of empty string */ if (**ipaddr == '\0') { *ipaddr = NULL; } return; } extern bool cf_key_interrupted; #define HOST_FMT_TRUNCATE "%-10.10s %-40.40s %-25.25s %-26.26s %-s\n" #define HOST_FMT_NO_TRUNCATE "%s\t%s\t%s\t%s\t%s\n" typedef struct _HostPrintState { int count; bool truncate; } HostPrintState; static bool ShowHost( const char *const hostkey, const char *const address, bool incoming, const KeyHostSeen *const quality, void *const ctx) { HostPrintState *const state = ctx; char hostname[NI_MAXHOST]; if (LOOKUP_HOSTS) { int ret = IPString2Hostname(hostname, address, sizeof(hostname)); if (ret == -1) { strcpy(hostname, "-"); } } else { strlcpy(hostname, address, sizeof(hostname)); } ++(state->count); bool truncate = state->truncate; char timebuf[26]; printf(truncate ? HOST_FMT_TRUNCATE : HOST_FMT_NO_TRUNCATE, incoming ? "Incoming" : "Outgoing", address, hostname, cf_strtimestamp_local(quality->lastseen, timebuf), hostkey); return !cf_key_interrupted; } void ShowLastSeenHosts(bool truncate) { HostPrintState state = { 0 }; state.count = 0; state.truncate = truncate; printf( truncate ? HOST_FMT_TRUNCATE : HOST_FMT_NO_TRUNCATE, "Direction", "IP", "Name", "Last connection", "Key"); if (!ScanLastSeenQuality(ShowHost, &state)) { Log(LOG_LEVEL_ERR, "Unable to show lastseen database"); return; } printf("Total Entries: %d\n", state.count); } /** * @brief removes all traces of entry 'input' from lastseen and filesystem * * @param[in] key digest (SHA/MD5 format) or free host name string * @param[in] must_be_coherent. false : delete if lastseen is incoherent, * true : don't if lastseen is incoherent * @retval 0 if entry was deleted, >0 otherwise */ int RemoveKeys(const char *input, bool must_be_coherent) { int res = 0; char equivalent[CF_BUFSIZE]; equivalent[0] = '\0'; res = RemoveKeysFromLastSeen(input, must_be_coherent, equivalent, sizeof(equivalent)); if (res!=0) { return res; } Log(LOG_LEVEL_INFO, "Removed corresponding entries from lastseen database."); int removed_input = RemovePublicKey(input); int removed_equivalent = RemovePublicKey(equivalent); if ((removed_input == -1) || (removed_equivalent == -1)) { Log(LOG_LEVEL_ERR, "Last seen database: unable to remove keys for the entry '%s'", input); return 255; } else if (removed_input + removed_equivalent == 0) { Log(LOG_LEVEL_ERR, "No key file(s) for entry '%s' were found on the filesystem", input); return 1; } else { Log(LOG_LEVEL_INFO, "Removed %d corresponding key file(s) from filesystem.", removed_input + removed_equivalent); return 0; } return -1; } static bool KeepKeyPromisesRSA(RSA *pair, const char *public_key_file, const char *private_key_file) { FILE *fp = safe_fopen_create_perms(private_key_file, "w", 0600); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Error while writing private key file '%s' (fopen: %s)", private_key_file, GetErrorStr()); return false; } Log(LOG_LEVEL_VERBOSE, "Writing private key to '%s'", private_key_file); int res = PEM_write_RSAPrivateKey(fp, pair, NULL, NULL, 0, NULL, NULL); fclose(fp); if (res == 0) { Log(LOG_LEVEL_ERR, "Couldn't write private key. (PEM_write_RSAPrivateKey: %s)", CryptoLastErrorString()); return false; } fp = safe_fopen_create_perms(public_key_file, "w", 0600); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Error while writing public key file '%s' (fopen: %s)", public_key_file, GetErrorStr()); return false; } Log(LOG_LEVEL_VERBOSE, "Writing public key to file '%s'", public_key_file); if (!PEM_write_RSAPublicKey(fp, pair)) { Log(LOG_LEVEL_ERR, "Unable to write public key. (PEM_write_RSAPublicKey: %s)", CryptoLastErrorString()); return false; } fclose(fp); char vbuff[CF_BUFSIZE]; snprintf(vbuff, CF_BUFSIZE, "%s%crandseed", GetWorkDir(), FILE_SEPARATOR); Log(LOG_LEVEL_VERBOSE, "Using '%s' for randseed", vbuff); if (RAND_write_file(vbuff) != 1024) { Log(LOG_LEVEL_ERR, "Unable to write randseed"); unlink(vbuff); /* randseed isn't safe to use */ return false; } if (chmod(vbuff, 0600) != 0) { Log(LOG_LEVEL_ERR, "Unable to set permissions on '%s' (chmod: %s)", vbuff, GetErrorStr()); return false; } return true; } bool KeepKeyPromises(const char *public_key_file, const char *private_key_file, const int key_size) { struct stat statbuf; if (stat(public_key_file, &statbuf) != -1) { Log(LOG_LEVEL_ERR, "A key file already exists at %s", public_key_file); return false; } if (stat(private_key_file, &statbuf) != -1) { Log(LOG_LEVEL_ERR, "A key file already exists at %s", private_key_file); return false; } Log(LOG_LEVEL_INFO, "Making a key pair for CFEngine, please wait, this could take a minute..."); RSA *pair = RSA_new(); BIGNUM *rsa_bignum = BN_new(); if (pair != NULL && rsa_bignum != NULL) { BN_set_word(rsa_bignum, RSA_F4); int res = RSA_generate_key_ex(pair, key_size, rsa_bignum, NULL); if (res == 0) { DESTROY_AND_NULL(RSA_free, pair); // pair = NULL } } else { DESTROY_AND_NULL(RSA_free, pair); // pair = NULL } BN_clear_free(rsa_bignum); if (pair == NULL) { Log(LOG_LEVEL_ERR, "Unable to generate cryptographic key (RSA_generate_key: %s)", CryptoLastErrorString()); return false; } bool ret = KeepKeyPromisesRSA(pair, public_key_file, private_key_file); RSA_free(pair); return ret; } ENTERPRISE_FUNC_1ARG_DEFINE_STUB(bool, LicenseInstall, ARG_UNUSED char *, path_source) { Log(LOG_LEVEL_ERR, "License installation only applies to CFEngine Enterprise"); return false; } int ForceKeyRemoval(const char *hash) { /** Removal of a key hash is made of two passes : Pass #1 (read-only) -> fetches the IP addresses directly linked to the hash key Pass #2 (made of deletes) -> remove all the IP addresses in the previous list -> remove the physical key.pub from the filesystem WARNING: Please backup your lastseen database before calling this function in the case where a 1-to-1 relatioship between the IP and a single keyhash does not exist **/ CF_DB *dbp; CF_DBC *dbcp; char *key; void *value; int ksize, vsize; Seq *hostips = SeqNew(100, free); if (OpenDB(&dbp, dbid_lastseen)) { if (NewDBCursor(dbp, &dbcp)) { while (NextDB(dbcp, &key, &ksize, &value, &vsize)) { if ((key[0] != 'a') || (value == NULL)) { continue; } if (!strncmp(hash, value, strlen(hash))) { SeqAppend(hostips, xstrdup(key + 1)); } } DeleteDBCursor(dbcp); } CloseDB(dbp); } if (OpenDB(&dbp, dbid_lastseen)) { char tmp[CF_BUFSIZE]; snprintf(tmp, CF_BUFSIZE, "k%s", hash); char vtmp[CF_BUFSIZE]; if (!ReadDB(dbp, tmp, &vtmp, sizeof(vtmp))) { Log(LOG_LEVEL_ERR, "Failed to read the main hash key entry '%s'. Will continue to purge other entries related to it.", hash); } else { SeqAppend(hostips, xstrdup(vtmp + 1)); } snprintf(tmp, CF_BUFSIZE, "k%s", hash); DeleteDB(dbp, tmp); snprintf(tmp, CF_BUFSIZE, "qi%s", hash); DeleteDB(dbp, tmp); snprintf(tmp, CF_BUFSIZE, "qo%s", hash); DeleteDB(dbp, tmp); RemovePublicKey(hash); for (size_t i = 0; i < SeqLength(hostips); ++i) { const char *myip = SeqAt(hostips, i); snprintf(tmp, CF_BUFSIZE, "a%s", myip); DeleteDB(dbp, tmp); } CloseDB(dbp); } SeqDestroy(hostips); return 0; } int ForceIpAddressRemoval(const char *ip) { /** Removal of an ip is made of two passes : Pass #1 (read-only) -> fetches the key hashes directly linked to the ip address Pass #2 (made of deletes) -> remove all the key hashes in the previous list -> remove the physical key hashes .pub files from the filesystem WARNING: Please backup your lastseen database before calling this function in the case where a 1-to-1 relatioship between the IP and a single keyhash does not exist **/ CF_DB *dbp; CF_DBC *dbcp; char *key; void *value; int ksize, vsize; Seq *hostkeys = SeqNew(100, free); if (OpenDB(&dbp, dbid_lastseen)) { if (NewDBCursor(dbp, &dbcp)) { while (NextDB(dbcp, &key, &ksize, &value, &vsize)) { if ((key[0] != 'k') || (value == NULL)) { continue; } if (!strncmp(ip, value, strlen(ip))) { SeqAppend(hostkeys, xstrdup(key + 1)); } } DeleteDBCursor(dbcp); } CloseDB(dbp); } if (OpenDB(&dbp, dbid_lastseen)) { char tmp[CF_BUFSIZE]; snprintf(tmp, CF_BUFSIZE, "a%s", ip); char vtmp[CF_BUFSIZE]; if (!ReadDB(dbp, tmp, &vtmp, sizeof(vtmp))) { Log(LOG_LEVEL_ERR, "Failed to read the main ip address entry '%s'. Will continue to purge other entries related to it.", ip); } else { SeqAppend(hostkeys, xstrdup(vtmp + 1)); } snprintf(tmp, CF_BUFSIZE, "a%s", ip); DeleteDB(dbp, tmp); for (size_t i = 0; i < SeqLength(hostkeys); ++i) { const char *myk = SeqAt(hostkeys, i); snprintf(tmp, CF_BUFSIZE, "k%s", myk); DeleteDB(dbp, tmp); snprintf(tmp, CF_BUFSIZE, "qi%s", myk); DeleteDB(dbp, tmp); snprintf(tmp, CF_BUFSIZE, "qo%s", myk); DeleteDB(dbp, tmp); RemovePublicKey(myk); } CloseDB(dbp); } SeqDestroy(hostkeys); return 0; } cfengine-3.24.2/depcomp0000755000000000000000000005601615010704301014732 0ustar00rootroot00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/cf-monitord/0000755000000000000000000000000015010704322015571 5ustar00rootroot00000000000000cfengine-3.24.2/cf-monitord/mon_cpu.c0000644000000000000000000000710615010704253017404 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #if !defined(__MINGW32__) /* Constants */ # define MON_CPU_MAX 4 /* Globals */ static double LAST_CPU_Q[MON_CPU_MAX + 1] = { 0.0 }; static long LAST_CPU_T[MON_CPU_MAX + 1] = { 0 }; /* Implementation */ void MonCPUGatherData(double *cf_this) { double q, dq; char cpuname[CF_MAXVARSIZE], buf[CF_BUFSIZE]; long cpuidx, userticks = 0, niceticks = 0, systemticks = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; long total_time = 1; enum observables slot = ob_spare; FILE *fp = safe_fopen("/proc/stat", "r"); if (fp == NULL) { Log(LOG_LEVEL_VERBOSE, "Could not open /proc/stat while gathering CPU data (fopen: %s)", GetErrorStr()); return; } Log(LOG_LEVEL_VERBOSE, "Reading /proc/stat utilization data -------"); while (!feof(fp)) { if (fgets(buf, sizeof(buf), fp) == NULL) { break; } nt_static_assert(CF_MAXVARSIZE == 1024); if (sscanf(buf, "%1023s%ld%ld%ld%ld%ld%ld%ld", cpuname, &userticks, &niceticks, &systemticks, &idle, &iowait, &irq, &softirq) != 8) { Log(LOG_LEVEL_VERBOSE, "Could not scan /proc/stat line: %60s", buf); continue; } total_time = (userticks + niceticks + systemticks + idle); q = 100.0 * (double) (total_time - idle); if (strcmp(cpuname, "cpu") == 0) { Log(LOG_LEVEL_VERBOSE, "Found aggregate CPU"); slot = ob_cpuall; cpuidx = MON_CPU_MAX; } else if (strncmp(cpuname, "cpu", 3) == 0) { if (sscanf(cpuname, "cpu%ld", &cpuidx) == 1) { if ((cpuidx < 0) || (cpuidx >= MON_CPU_MAX)) { continue; } } else { continue; } slot = ob_cpu0 + cpuidx; } else { Log(LOG_LEVEL_VERBOSE, "Found nothing (%s)", cpuname); slot = ob_spare; fclose(fp); return; } dq = (q - LAST_CPU_Q[cpuidx]) / (double) (total_time - LAST_CPU_T[cpuidx]); /* % Utilization */ if ((dq > 100) || (dq < 0)) // Counter wrap around { dq = 50; } cf_this[slot] = dq; LAST_CPU_Q[cpuidx] = q; LAST_CPU_T[cpuidx] = total_time; Log(LOG_LEVEL_VERBOSE, "Set %s=%d to %.1lf after %ld 100ths of a second ", OBSERVABLES[slot][1], slot, cf_this[slot], total_time); } fclose(fp); } #endif /* !__MINGW32__ */ cfengine-3.24.2/cf-monitord/Makefile.am0000644000000000000000000000513215010704253017631 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-monitord.la AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libenv \ -I$(srcdir)/../libpromises \ $(PCRE2_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_monitord_la_LIBADD = ../libpromises/libpromises.la libcf_monitord_la_SOURCES = \ verify_measurements.c verify_measurements.h \ env_monitor.c env_monitor.h \ mon.h \ mon_cpu.c \ mon_disk.c \ mon_entropy.c \ mon_load.c \ mon_network_sniffer.c \ mon_network.c \ mon_processes.c \ mon_temp.c \ history.c history.h \ mon_cumulative.c mon_cumulative.h \ probes.c probes.h \ monitoring.c monitoring.h \ cf-monitord.c if LINUX libcf_monitord_la_SOURCES += mon_io_linux.c mon_mem_linux.c proc_net_parsing.c proc_net_parsing.h endif if SOLARIS libcf_monitord_la_SOURCES += mon_mem_solaris.c shared_kstat.c shared_kstat.h endif if !LINUX libcf_monitord_la_SOURCES += mon_io_stub.c if !SOLARIS libcf_monitord_la_SOURCES += mon_mem_stub.c endif endif TESTS = if LINUX TESTS += get_socket_info noinst_PROGRAMS = get_socket_info get_socket_info_SOURCES = get_socket_info.c get_socket_info_LDADD = ../libntech/libutils/libutils.la \ $(PCRE2_LIBS) \ $(LIBYAML_LIBS) \ libcf-monitord.la endif if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-monitord # Workaround for automake madness (try removing it if you want to know why). cf_monitord_CFLAGS = $(AM_CFLAGS) cf_monitord_LDADD = libcf-monitord.la endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-monitord/mon_cumulative.c0000644000000000000000000000654315010704253020777 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include /* * Cumulative statistics support and conversion to instant values */ typedef struct PrevValue_ PrevValue; struct PrevValue_ { char *name; char *subname; union { unsigned u32; unsigned long long u64; } value; time_t timestamp; PrevValue *next; }; /* Globals */ static PrevValue *values; /* Implementation */ static PrevValue *AppendNewValue(const char *name, const char *subname, time_t timestamp) { PrevValue *v = xmalloc(sizeof(PrevValue)); v->name = xstrdup(name); v->subname = xstrdup(subname); v->timestamp = timestamp; v->next = values; values = v; return v; } unsigned GetInstantUint32Value(const char *name, const char *subname, unsigned value, time_t timestamp) { PrevValue *v; for (v = values; v; v = v->next) { if (!strcmp(v->name, name) && !strcmp(v->subname, subname)) { unsigned diff; unsigned difft; /* Check for wraparound */ if (value < v->value.u32) { diff = INT_MAX - v->value.u32 + value; } else { diff = value - v->value.u32; } difft = timestamp - v->timestamp; v->value.u32 = value; v->timestamp = timestamp; if (difft != 0) { return diff / difft; } else { return (unsigned) -1; } } } AppendNewValue(name, subname, timestamp)->value.u32 = value; return (unsigned) -1; } unsigned long long GetInstantUint64Value(const char *name, const char *subname, unsigned long long value, time_t timestamp) { PrevValue *v; for (v = values; v; v = v->next) { if (!strcmp(v->name, name) && !strcmp(v->subname, subname)) { unsigned long long diff = value - v->value.u64; unsigned difft = timestamp - v->timestamp; v->value.u64 = value; v->timestamp = timestamp; if (difft != 0) { return diff / difft; } else { return (unsigned long long) -1; } } } AppendNewValue(name, subname, timestamp)->value.u64 = value; return (unsigned long long) -1; } cfengine-3.24.2/cf-monitord/shared_kstat.c0000644000000000000000000000252415010704253020417 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static kstat_ctl_t *kstat; kstat_ctl_t *GetKstatHandle(void) { if (!kstat) { kstat = kstat_open(); if (!kstat) { Log(LOG_LEVEL_ERR, "Unable to open Solaris kstat subsystem (kstat_open)"); } } else { kstat_chain_update(kstat); } return kstat; } cfengine-3.24.2/cf-monitord/mon_mem_solaris.c0000644000000000000000000001037415010704253021130 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /* NovaRegisterSlot */ #include #define KB 1024 /************************************************************************/ static void GetTotalMemory(double *cf_this) { int total_slot = NovaRegisterSlot(MON_MEM_TOTAL, "Total system memory", "megabytes", 512.0l, 4096.0l, true); if (total_slot != -1) { long long memory = ((long long) sysconf(_SC_PAGESIZE)) * sysconf(_SC_PHYS_PAGES); cf_this[total_slot] = memory / KB / KB; } } /************************************************************************/ static void GetKstatInfo(double *cf_this) { kstat_ctl_t *kstat = GetKstatHandle(); kstat_t *k; int free_slot = NovaRegisterSlot(MON_MEM_FREE, "Free system memory", "megabytes", 0.0l, 4096.0l, true); vminfo_t vminfo; sysinfo_t sysinfo; if (!kstat) { return; } if ((k = kstat_lookup(kstat, "unix", 0, "sysinfo")) == NULL) { Log(LOG_LEVEL_ERR, "Unable to lookup sysinfo in kstat (kstat_lookup)"); return; } if (kstat_read(kstat, k, &sysinfo) == -1) { Log(LOG_LEVEL_ERR, "Unable to read sysinfo from kstat (kstat_read)"); return; } if ((k = kstat_lookup(kstat, "unix", 0, "vminfo")) == NULL) { Log(LOG_LEVEL_ERR, "Unable to lookup vminfo in kstat (kstat_lookup)"); return; } if (kstat_read(kstat, k, &vminfo) == -1) { Log(LOG_LEVEL_ERR, "Unable to read vminfo from kstat (kstat_read)"); return; } uint64_t freemem = GetInstantUint64Value("mem", "free", vminfo.freemem, sysinfo.updates); if (free_slot != -1) { if (freemem != (unsigned long long) -1) { cf_this[free_slot] = ((double) freemem) * sysconf(_SC_PAGESIZE) / KB / KB; } } uint64_t swap_resv = GetInstantUint64Value("swap", "resv", vminfo.swap_resv, sysinfo.updates); uint64_t swap_avail = GetInstantUint64Value("swap", "avail", vminfo.swap_avail, sysinfo.updates); if (swap_resv != (uint64_t) - 1 && swap_avail != (uint64_t) - 1) { int swap_slot = NovaRegisterSlot(MON_MEM_SWAP, "Total swap size", "megabytes", 0.0l, 4096.0l, true); int free_swap_slot = NovaRegisterSlot(MON_MEM_FREE_SWAP, "Free swap size", "megabytes", 0.0l, 4096.0l, true); if (swap_slot != -1) { cf_this[swap_slot] = ((double) swap_resv + swap_avail) * sysconf(_SC_PAGESIZE) / KB / KB; } if (free_swap_slot != -1) { cf_this[free_swap_slot] = ((double) swap_avail) * sysconf(_SC_PAGESIZE) / KB / KB; } } } /************************************************************************/ static void MonMemoryGatherData(double *cf_this) { GetTotalMemory(cf_this); GetKstatInfo(cf_this); } /************************************************************************/ ProbeGatherData MonMemoryInit(const char **name, const char **error) { *name = "Solaris kstat subsystem"; *error = NULL; return &MonMemoryGatherData; } cfengine-3.24.2/cf-monitord/history.h0000644000000000000000000000240115010704253017443 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_HISTORY_H #define CFENGINE_HISTORY_H #include PromiseResult VerifyMeasurement(EvalContext *ctx, double *this, const Attributes *a, const Promise *pp); void HistoryUpdate(EvalContext *ctx, const Averages *newvals); #endif cfengine-3.24.2/cf-monitord/mon_mem_linux.c0000644000000000000000000001044515010704253020612 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /************************************************************************/ /* Generic "Key: Numeric Value" parser */ /************************************************************************/ /* Getting data from /proc/meminfo - All values are in bytes */ typedef struct { off_t total; off_t free; off_t cached; off_t swap; off_t free_swap; } MemoryInfo; #define KB 1024 static bool AcceptMemoryField(const char *field, off_t value, void *param) { MemoryInfo *info = param; value *= KB; if (!strcmp(field, "MemTotal")) { info->total = value; } else if (!strcmp(field, "MemFree")) { info->free = value; } else if (!strcmp(field, "Cached")) { info->cached = value; } else if (!strcmp(field, "SwapTotal")) { info->swap = value; } else if (!strcmp(field, "SwapFree")) { info->free_swap = value; } return true; } /************************************************************************/ static void MonMeminfoGatherData(double *cf_this) { MemoryInfo info = { 0 }; FILE *fh = safe_fopen("/proc/meminfo", "r"); if (fh == NULL) { Log(LOG_LEVEL_ERR, "Unable to open /proc/meminfo. (fopen: %s)", GetErrorStr()); return; } if (ParseKeyNumericValue(fh, &AcceptMemoryField, &info)) { int total_slot = NovaRegisterSlot(MON_MEM_TOTAL, "Total system memory", "megabytes", 512.0f, 4096.0f, true); int free_slot = NovaRegisterSlot(MON_MEM_FREE, "Free system memory", "megabytes", 0.0f, 4096.0f, true); int cached_slot = NovaRegisterSlot(MON_MEM_CACHED, "Size of disk cache", "megabytes", 0.0f, 4096.0f, true); int swap_slot = NovaRegisterSlot(MON_MEM_SWAP, "Total swap size", "megabytes", 0.0f, 4096.0f, true); int free_swap_slot = NovaRegisterSlot(MON_MEM_FREE_SWAP, "Free swap size", "megabytes", 0.0f, 8192.0f, true); if (total_slot != -1) { cf_this[total_slot] = ((double) info.total) / KB / KB; } if (free_slot != -1) { cf_this[free_slot] = ((double) info.free) / KB / KB; } if (cached_slot != -1) { cf_this[cached_slot] = ((double) info.cached) / KB / KB; } if (swap_slot != -1) { cf_this[swap_slot] = ((double) info.swap) / KB / KB; } if (free_swap_slot != -1) { cf_this[free_swap_slot] = ((double) info.free_swap) / KB / KB; } } else { Log(LOG_LEVEL_ERR, "Unable to parse /proc/meminfo"); } fclose(fh); } /************************************************************************/ ProbeGatherData MonMemoryInit(const char **name, const char **error) { if (access("/proc/meminfo", R_OK) == 0) { *name = "Linux /proc/meminfo statistics"; *error = NULL; return &MonMeminfoGatherData; } else { *name = NULL; *error = "/proc/meminfo is not readable"; return NULL; } } cfengine-3.24.2/cf-monitord/history.c0000644000000000000000000006164515010704253017455 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* MakeTimekey */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* StringMatchFull */ #include #include #include #include #include #define CF_DUNBAR_WORK 30 typedef struct { char *path; Item *output; } CustomMeasurement; static int MONITOR_RESTARTED = true; static CustomMeasurement ENTERPRISE_DATA[CF_DUNBAR_WORK]; static void PutRecordForTime(CF_DB *db, time_t time, const Averages *values) { char timekey[CF_MAXVARSIZE]; MakeTimekey(time, timekey); WriteDB(db, timekey, values, sizeof(Averages)); } static void Nova_SaveFilePosition(const char *handle, const char *name, long fileptr) { CF_DB *dbp; char *key = StringConcatenate(2, handle, name); if (!OpenDB(&dbp, dbid_static)) { return; } Log(LOG_LEVEL_VERBOSE, "Saving state for %s at %ld", key, fileptr); WriteDB(dbp, key, &fileptr, sizeof(long)); CloseDB(dbp); free(key); } static long Nova_RestoreFilePosition(const char *handle, const char *name) { CF_DB *dbp; long fileptr; char *key = StringConcatenate(2, handle, name); if (!OpenDB(&dbp, dbid_static)) { return 0L; } ReadDB(dbp, key, &fileptr, sizeof(long)); Log(LOG_LEVEL_VERBOSE, "Resuming state for %s at %ld", key, fileptr); CloseDB(dbp); free(key); return fileptr; } static void Nova_DumpSlowlyVaryingObservations(void) { CF_DB *dbp; CF_DBC *dbcp; char *key; void *stored; int ksize, vsize; char name[CF_BUFSIZE]; if (!OpenDB(&dbp, dbid_static)) { return; } snprintf(name, CF_BUFSIZE - 1, "%s%cstatic_data", GetStateDir(), FILE_SEPARATOR); FILE *fout = safe_fopen(name, "w"); if (fout == NULL) { Log(LOG_LEVEL_ERR, "Unable to save discovery data in '%s'. (fopen: %s)", name, GetErrorStr()); CloseDB(dbp); return; } /* Acquire a cursor for the database. */ if (!NewDBCursor(dbp, &dbcp)) { Log(LOG_LEVEL_INFO, "Unable to scan class db"); CloseDB(dbp); return; } while (NextDB(dbcp, &key, &ksize, &stored, &vsize)) { char buf[CF_MAXVARSIZE], lval[CF_MAXVARSIZE], rval[CF_BUFSIZE]; strncpy(buf, key, CF_MAXVARSIZE - 1); sscanf(buf, "%s:", lval); if (stored != NULL) { strncpy(rval, stored, CF_BUFSIZE - 1); fprintf(fout, "%s:%s\n", lval, rval); } } DeleteDBCursor(dbcp); CloseDB(dbp); fclose(fout); } static void Nova_HistoryUpdate(time_t time, const Averages *newvals) { CF_DB *dbp; if (!OpenDB(&dbp, dbid_history)) { return; } PutRecordForTime(dbp, time, newvals); CloseDB(dbp); } static Item *NovaReSample(EvalContext *ctx, int slot, const Attributes *attr, const Promise *pp, PromiseResult *result) { assert(attr != NULL); assert(pp != NULL); Attributes a = *attr; // TODO: try to remove this local copy CfLock thislock; char eventname[CF_BUFSIZE]; struct timespec start; FILE *fin = NULL; mode_t maskval = 0; const char *handle = PromiseGetHandle(pp); if (a.measure.stream_type && strcmp(a.measure.stream_type, "pipe") == 0) { if (!IsExecutable(CommandArg0(pp->promiser))) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "%s promises to be executable but isn't\n", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return NULL; } else { Log(LOG_LEVEL_VERBOSE, "Promiser string contains a valid executable (%s) - ok", CommandArg0(pp->promiser)); } } // Force a measurement if restarted: const int ifelapsed = MONITOR_RESTARTED ? 0 : a.transaction.ifelapsed; const int expireafter = a.transaction.expireafter; CFSTARTTIME = time(NULL); thislock = AcquireLock(ctx, pp->promiser, VUQNAME, CFSTARTTIME, ifelapsed, expireafter, pp, false); if (thislock.lock == NULL) { if (strcmp(a.measure.history_type, "log") == 0) { DeleteItemList(ENTERPRISE_DATA[slot].output); ENTERPRISE_DATA[slot].output = NULL; } else { /* If static or time-series, and too soon or busy then use a cached value to avoid artificial gaps in the history */ } MONITOR_RESTARTED = false; return ENTERPRISE_DATA[slot].output; } else { DeleteItemList(ENTERPRISE_DATA[slot].output); ENTERPRISE_DATA[slot].output = NULL; Log(LOG_LEVEL_INFO, "Sampling \'%s\' ...(timeout=%d,owner=%ju,group=%ju)", pp->promiser, a.contain.timeout, (uintmax_t)a.contain.owner, (uintmax_t)a.contain.group); start = BeginMeasure(); if (a.contain.timeout != 0) { SetTimeOut(a.contain.timeout); } /* Stream types */ if (a.measure.stream_type && strcmp(a.measure.stream_type, "file") == 0) { long filepos = 0; struct stat sb; Log(LOG_LEVEL_VERBOSE, "Stream \"%s\" is a plain file", pp->promiser); if (stat(pp->promiser, &sb) == -1) { Log(LOG_LEVEL_INFO, "Unable to find stream '%s'. (stat: %s)", pp->promiser, GetErrorStr()); YieldCurrentLock(thislock); MONITOR_RESTARTED = false; return NULL; } fin = safe_fopen(pp->promiser, "r"); if (a.measure.growing) { filepos = Nova_RestoreFilePosition(handle, pp->promiser); if (sb.st_size >= filepos) { fseek(fin, filepos, SEEK_SET); } } } else if (a.measure.stream_type && strcmp(a.measure.stream_type, "pipe") == 0) { Log(LOG_LEVEL_VERBOSE, "(Setting pipe umask to %jo)", (uintmax_t)a.contain.umask); maskval = umask(a.contain.umask); if (a.contain.umask == 0) { Log(LOG_LEVEL_VERBOSE, "Programming %s running with umask 0! Use umask= to set", pp->promiser); } // Mark: This is strange that we used these wrappers. Currently no way of setting these a.contain.owner = -1; a.contain.group = -1; a.contain.chdir = NULL; a.contain.chroot = NULL; // Mark: they were unset, and would fail for non-root(!) if (a.contain.shelltype == SHELL_TYPE_POWERSHELL) { #ifdef __MINGW32__ fin = cf_popen_powershell_setuid(pp->promiser, "r", a.contain.owner, a.contain.group, a.contain.chdir, a.contain.chroot, false); #else // !__MINGW32__ Log(LOG_LEVEL_ERR, "Powershell is only supported on Windows"); YieldCurrentLock(thislock); MONITOR_RESTARTED = false; return NULL; #endif // !__MINGW32__ } else if (a.contain.shelltype == SHELL_TYPE_USE) { fin = cf_popen_shsetuid(pp->promiser, "r", a.contain.owner, a.contain.group, a.contain.chdir, a.contain.chroot, false); } else { fin = cf_popensetuid(pp->promiser, NULL, "r", a.contain.owner, a.contain.group, a.contain.chdir, a.contain.chroot, false); } } /* generic file stream */ if (fin == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Couldn't open pipe to command '%s'. (cf_popen: %s)", pp->promiser, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); YieldCurrentLock(thislock); MONITOR_RESTARTED = false; return ENTERPRISE_DATA[slot].output; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = CfReadLine(&line, &line_size, fin); if (res == -1) { if (!feof(fin)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_TIMEOUT, pp, &a, "Sample stream '%s'. (fread: %s)", pp->promiser, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_TIMEOUT); YieldCurrentLock(thislock); free(line); return ENTERPRISE_DATA[slot].output; } else { break; } } AppendItem(&(ENTERPRISE_DATA[slot].output), line, NULL); Log(LOG_LEVEL_INFO, "Sampling => %s", line); } free(line); if (a.measure.stream_type && strcmp(a.measure.stream_type, "file") == 0) { long fileptr = ftell(fin); fclose(fin); Nova_SaveFilePosition(handle, pp->promiser, fileptr); } else if (a.measure.stream_type && strcmp(a.measure.stream_type, "pipe") == 0) { cf_pclose(fin); } } if (a.contain.timeout != 0) { alarm(0); signal(SIGALRM, SIG_DFL); } Log(LOG_LEVEL_INFO, "Collected sample of %s", pp->promiser); umask(maskval); YieldCurrentLock(thislock); MONITOR_RESTARTED = false; snprintf(eventname, CF_BUFSIZE - 1, "Sample(%s)", pp->promiser); EndMeasure(eventname, start); return ENTERPRISE_DATA[slot].output; } void HistoryUpdate(EvalContext *ctx, const Averages *const newvals) { CfLock thislock; time_t now = time(NULL); /* We do this only once per hour - this should not be changed */ Banner("Update long-term history"); Policy *history_db_policy = PolicyNew(); Promise *pp = NULL; { Bundle *bp = PolicyAppendBundle(history_db_policy, NamespaceDefault(), "history_db_bundle", "agent", NULL, NULL); BundleSection *sp = BundleAppendSection(bp, "history_db"); pp = BundleSectionAppendPromise(sp, "the long term memory", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL, NULL); } assert(pp); thislock = AcquireLock(ctx, pp->promiser, VUQNAME, now, 59, 0, pp, false); if (thislock.lock == NULL) { PolicyDestroy(history_db_policy); return; } /* Refresh the class context of the agent */ EvalContextClear(ctx); DetectEnvironment(ctx); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); EvalContextHeapPersistentLoadAll(ctx); LoadSystemConstants(ctx); YieldCurrentLock(thislock); PolicyDestroy(history_db_policy); Nova_HistoryUpdate(CFSTARTTIME, newvals); Nova_DumpSlowlyVaryingObservations(); } static Item *NovaGetMeasurementStream(EvalContext *ctx, const Attributes *a, const Promise *pp, PromiseResult *result) { int i; for (i = 0; (i < CF_DUNBAR_WORK) && (ENTERPRISE_DATA[i].path != NULL); i++) { if (StringEqual(ENTERPRISE_DATA[i].path, pp->promiser)) { ENTERPRISE_DATA[i].output = NovaReSample(ctx, i, a, pp, result); return ENTERPRISE_DATA[i].output; } } /* if empty slot found */ if (i < CF_DUNBAR_WORK) { assert(ENTERPRISE_DATA[i].path == NULL); ENTERPRISE_DATA[i].path = xstrdup(pp->promiser); ENTERPRISE_DATA[i].output = NovaReSample(ctx, i, a, pp, result); return ENTERPRISE_DATA[i].output; } else { return NULL; } } static PromiseResult NovaExtractValueFromStream(EvalContext *ctx, const char *handle, Item *stream, const Attributes *a, const Promise *pp, double *value_out) { char value[CF_MAXVARSIZE]; int count = 1, found = false, match_count = 0, done = false; double real_val = 0; Item *ip, *match = NULL; bool ok_conversion = true; for (ip = stream; ip != NULL; ip = ip->next) { if (count == a->measure.select_line_number) { found = true; match = ip; match_count++; } if (a->measure.select_line_matching && StringMatchFull(a->measure.select_line_matching, ip->name)) { Log(LOG_LEVEL_VERBOSE, " Found regex '%s' matches line '%s'", a->measure.select_line_matching, ip->name); found = true; match = ip; if (a->measure.extraction_regex) { switch (a->measure.data_type) { case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: case CF_DATA_TYPE_COUNTER: strncpy(value, ExtractFirstReference(a->measure.extraction_regex, match->name), CF_MAXVARSIZE - 1); if (strcmp(value, "CF_NOMATCH") == 0) { ok_conversion = false; Log(LOG_LEVEL_VERBOSE, "Was not able to match a value with '%s' on '%s'", a->measure.extraction_regex, match->name); } else { if (ok_conversion) { Log(LOG_LEVEL_VERBOSE, "Found candidate match value of '%s'", value); if (a->measure.policy == MEASURE_POLICY_SUM || a->measure.policy == MEASURE_POLICY_AVERAGE) { double delta = 0; if (DoubleFromString(value, &delta)) { real_val += delta; } else { Log(LOG_LEVEL_ERR, "Error in double conversion from string value: %s", value); return PROMISE_RESULT_FAIL; } } else { if (!DoubleFromString(value, &real_val)) { Log(LOG_LEVEL_ERR, "Error in double conversion from string value: %s", value); return PROMISE_RESULT_FAIL; } } match_count++; if (a->measure.policy == MEASURE_POLICY_FIRST) { done = true; } } } break; default: Log(LOG_LEVEL_ERR, "Unexpected data type in data_type attribute: %d", a->measure.data_type); } } } count++; if (done) { break; } } if (!found) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_FAIL, pp, a, "Could not locate the line for promise '%s'", handle); *value_out = 0.0; return PROMISE_RESULT_FAIL; } switch (a->measure.data_type) { case CF_DATA_TYPE_COUNTER: real_val = (double) match_count; break; case CF_DATA_TYPE_INT: if (match_count > 1) { Log(LOG_LEVEL_INFO, "Warning: %d lines matched the line_selection \"%s\"- making best average", match_count, a->measure.select_line_matching); } if (match_count > 0 && a->measure.policy == MEASURE_POLICY_AVERAGE) // If not "average" then "sum" { real_val /= match_count; } break; case CF_DATA_TYPE_REAL: if (match_count > 1) { Log(LOG_LEVEL_INFO, "Warning: %d lines matched the line_selection \"%s\"- making best average", match_count, a->measure.select_line_matching); } if (match_count > 0) { real_val /= match_count; } break; default: Log(LOG_LEVEL_ERR, "Unexpected data type in data_type attribute: %d", a->measure.data_type); } if (!ok_conversion) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to extract a value from the matched line '%s'", match->name); PromiseRef(LOG_LEVEL_INFO, pp); *value_out = 0.0; return PROMISE_RESULT_FAIL; } Log(LOG_LEVEL_INFO, "Extracted value \"%f\" for promise \"%s\"", real_val, handle); *value_out = real_val; return PROMISE_RESULT_NOOP; } static void NovaLogSymbolicValue(EvalContext *ctx, const char *handle, Item *stream, const Attributes *a, const Promise *pp, PromiseResult *result) { char value[CF_BUFSIZE], sdate[CF_MAXVARSIZE], filename[CF_BUFSIZE]; int count = 1, found = false, match_count = 0; Item *ip, *match = NULL, *matches = NULL; time_t now = time(NULL); if (stream == NULL) { Log(LOG_LEVEL_VERBOSE, "No stream to measure"); return; } Log(LOG_LEVEL_VERBOSE, "Locate and log sample ..."); for (ip = stream; ip != NULL; ip = ip->next) { if (ip->name == NULL) { continue; } if (count == a->measure.select_line_number) { Log(LOG_LEVEL_VERBOSE, "Found line %d by number...", count); found = true; match_count = 1; match = ip; if (a->measure.extraction_regex) { Log(LOG_LEVEL_VERBOSE, "Now looking for a matching extractor \"%s\"", a->measure.extraction_regex); strncpy(value, ExtractFirstReference(a->measure.extraction_regex, match->name), CF_MAXVARSIZE - 1); Log(LOG_LEVEL_INFO, "Extracted value \"%s\" for promise \"%s\"", value, handle); AppendItem(&matches, value, NULL); } else { Log(LOG_LEVEL_INFO, "Using entire line \"%s\" for promise \"%s\"", match->name, handle); AppendItem(&matches, match->name, NULL); } break; } if (a->measure.select_line_matching && StringMatchFull(a->measure.select_line_matching, ip->name)) { Log(LOG_LEVEL_VERBOSE, "Found line %d by pattern...", count); found = true; match = ip; match_count++; if (a->measure.extraction_regex) { Log(LOG_LEVEL_VERBOSE, "Now looking for a matching extractor \"%s\"", a->measure.extraction_regex); strncpy(value, ExtractFirstReference(a->measure.extraction_regex, match->name), CF_MAXVARSIZE - 1); Log(LOG_LEVEL_INFO, "Extracted value \"%s\" for promise \"%s\"", value, handle); AppendItem(&matches, value, NULL); } else { Log(LOG_LEVEL_INFO, "Using entire line \"%s\" for promise \"%s\"", match->name, handle); AppendItem(&matches, match->name, NULL); } } count++; } if (!found) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Promiser '%s' found no matching line.", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return; } if (match_count > 1) { Log(LOG_LEVEL_INFO, "Warning: %d lines matched the line_selection \"%s\"- matching to last", match_count, a->measure.select_line_matching); } switch (a->measure.data_type) { case CF_DATA_TYPE_COUNTER: Log(LOG_LEVEL_VERBOSE, "Counted %d for %s", match_count, handle); snprintf(value, CF_MAXVARSIZE, "%d", match_count); break; case CF_DATA_TYPE_STRING_LIST: ItemList2CSV_bound(matches, value, sizeof(value), ','); break; default: snprintf(value, CF_BUFSIZE, "%s", matches->name); } DeleteItemList(matches); if (a->measure.history_type && strcmp(a->measure.history_type, "log") == 0) { snprintf(filename, CF_BUFSIZE, "%s%c%s_measure.log", GetStateDir(), FILE_SEPARATOR, handle); FILE *fout = safe_fopen(filename, "a"); if (fout == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to open the output log \"%s\"", filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); PromiseRef(LOG_LEVEL_ERR, pp); return; } strncpy(sdate, ctime(&now), CF_MAXVARSIZE - 1); if (Chop(sdate, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } fprintf(fout, "%s,%ld,%s\n", sdate, (long) now, value); Log(LOG_LEVEL_VERBOSE, "Logging: %s,%s to %s", sdate, value, filename); fclose(fout); } else // scalar or static { CF_DB *dbp; char id[CF_MAXVARSIZE]; if (!OpenDB(&dbp, dbid_static)) { return; } snprintf(id, CF_MAXVARSIZE - 1, "%s:%d", handle, a->measure.data_type); WriteDB(dbp, id, value, strlen(value) + 1); CloseDB(dbp); } } PromiseResult VerifyMeasurement(EvalContext *ctx, double *this, const Attributes *a, const Promise *pp) { const char *handle = PromiseGetHandle(pp); Item *stream = NULL; int slot = 0; double new_value; if (!handle) { Log(LOG_LEVEL_ERR, "The promised measurement has no handle to register it by."); return PROMISE_RESULT_NOOP; } else { Log(LOG_LEVEL_VERBOSE, "Considering promise \"%s\"", handle); } PromiseResult result = PROMISE_RESULT_NOOP; switch (a->measure.data_type) { case CF_DATA_TYPE_COUNTER: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: /* First see if we can accommodate this measurement */ Log(LOG_LEVEL_VERBOSE, "Promise '%s' is numerical in nature", handle); stream = NovaGetMeasurementStream(ctx, a, pp, &result); if (strcmp(a->measure.history_type, "weekly") == 0) { if ((slot = NovaRegisterSlot(handle, pp->comment ? pp->comment : "User defined measure", a->measure.units ? a->measure.units : "unknown", 0.0f, 100.0f, true)) < 0) { return result; } result = PromiseResultUpdate(result, NovaExtractValueFromStream(ctx, handle, stream, a, pp, &this[slot])); Log(LOG_LEVEL_VERBOSE, "Setting Nova slot %d=%s to %lf", slot, handle, this[slot]); } else if (strcmp(a->measure.history_type, "log") == 0) { Log(LOG_LEVEL_VERBOSE, "Promise to log a numerical value"); NovaLogSymbolicValue(ctx, handle, stream, a, pp, &result); } else /* static */ { Log(LOG_LEVEL_VERBOSE, "Promise to store a static numerical value"); result = PromiseResultUpdate(result, NovaExtractValueFromStream(ctx, handle, stream, a, pp, &new_value)); NovaNamedEvent(handle, new_value); } break; default: Log(LOG_LEVEL_VERBOSE, "Promise '%s' is symbolic in nature", handle); stream = NovaGetMeasurementStream(ctx, a, pp, &result); NovaLogSymbolicValue(ctx, handle, stream, a, pp, &result); break; } return result; // stream gets de-allocated in ReSample } cfengine-3.24.2/cf-monitord/mon.h0000644000000000000000000000377115010704253016546 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MON_H #define CFENGINE_MON_H /* mon_entropy.c */ void MonEntropyClassesInit(void); void MonEntropyClassesReset(void); void MonEntropyClassesSet(const char *service, const char *direction, double entropy); void MonEntropyClassesPublish(FILE *fp); void MonEntropyPurgeUnused(char *name); double MonEntropyCalculate(const Item *items); /* mon_cpu.c */ void MonCPUGatherData(double *cf_this); /* mon_disk.c */ void MonDiskGatherData(double *cf_this); /* mon_load.c */ void MonLoadGatherData(double *cf_this); /* mon_network.c */ void MonNetworkInit(void); void MonNetworkGatherData(double *cf_this); /* mon_network_sniffer.c */ void MonNetworkSnifferInit(void); void MonNetworkSnifferOpen(void); void MonNetworkSnifferEnable(bool enable); void MonNetworkSnifferSniff(Item *ip_addresses, long iteration, double *cf_this); void MonNetworkSnifferGatherData(void); /* mon_processes.c */ void MonProcessesGatherData(double *cf_this); /* mon_temp.c */ void MonTempInit(void); void MonTempGatherData(double *cf_this); #endif cfengine-3.24.2/cf-monitord/get_socket_info.c0000644000000000000000000001243115010704253021103 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include int main() { FILE *fp = fopen("/proc/net/tcp", "r"); size_t buff_size = 256; char *buff = xmalloc(buff_size); /* Read the header */ ssize_t ret = CfReadLine(&buff, &buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp"); free(buff); return 1; } /* Read real data */ Seq *lines = SeqNew(64, free); ret = CfReadLines(&buff, &buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp"); SeqDestroy(lines); free(buff); return 1; } /* else */ char local_addr[INET_ADDRSTRLEN]; char remote_addr[INET_ADDRSTRLEN]; uint32_t l_port, r_port; SocketState state; for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv4SocketInfo(line, local_addr, &l_port, remote_addr, &r_port, &state)) { printf("%s:%d -> %s:%d%s\n", local_addr, l_port, remote_addr, r_port, (state == SOCK_STATE_LISTEN) ? " [LISTEN]" : ""); } } SeqClear(lines); char local_addr6[INET6_ADDRSTRLEN]; char remote_addr6[INET6_ADDRSTRLEN]; fp = fopen("/proc/net/tcp6", "r"); if (fp != NULL) { ret = CfReadLine(&buff, &buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp6"); SeqDestroy(lines); free(buff); return 1; } /* Read real data */ ret = CfReadLines(&buff, &buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp6"); SeqDestroy(lines); free(buff); return 1; } /* else */ for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv6SocketInfo(line, local_addr6, &l_port, remote_addr6, &r_port, &state)) { printf("%s:%d -> %s:%d%s\n", local_addr6, l_port, remote_addr6, r_port, (state == SOCK_STATE_LISTEN) ? " [LISTEN]" : ""); } } SeqClear(lines); } fp = fopen("/proc/net/udp", "r"); ret = CfReadLine(&buff, &buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp"); SeqDestroy(lines); free(buff); return 1; } /* Read real data */ ret = CfReadLines(&buff, &buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp"); SeqDestroy(lines); free(buff); return 1; } /* else */ for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv4SocketInfo(line, local_addr, &l_port, remote_addr, &r_port, &state)) { printf("%s:%d -> %s:%d [udp]\n", local_addr, l_port, remote_addr, r_port); } } SeqClear(lines); fp = fopen("/proc/net/udp6", "r"); if (fp != NULL) { ret = CfReadLine(&buff, &buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp6"); SeqDestroy(lines); free(buff); return 1; } /* Read real data */ ret = CfReadLines(&buff, &buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp6"); SeqDestroy(lines); free(buff); return 1; } /* else */ for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv6SocketInfo(line, local_addr6, &l_port, remote_addr6, &r_port, &state)) { printf("%s:%d -> %s:%d [udp6]\n", local_addr6, l_port, remote_addr6, r_port); } } } SeqDestroy(lines); free(buff); return 0; } cfengine-3.24.2/cf-monitord/probes.h0000644000000000000000000000411415010704253017237 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROBES_H #define CFENGINE_PROBES_H #include void MonOtherInit(); void MonOtherGatherData(double *cf_this); /* * Type of callback collecting actual probe data. */ typedef void (*ProbeGatherData) (double *cf_this); /* * Type of probe initialization function. * * Probe initialization function should either return callback and name of probe * provider in "name" argument, or NULL and error description in "error" * argument. * * Caller does not free data returned in "name" or "error". */ typedef ProbeGatherData(*ProbeInit) (const char **name, const char **error); /* * Existing probes and their identifiers */ #define MON_IO_READS "io_reads" #define MON_IO_WRITES "io_writes" #define MON_IO_READDATA "io_readdata" #define MON_IO_WRITTENDATA "io_writtendata" ProbeGatherData MonIoInit(const char **name, const char **error); #define MON_MEM_TOTAL "mem_total" #define MON_MEM_FREE "mem_free" #define MON_MEM_CACHED "mem_cached" #define MON_MEM_SWAP "mem_swap" #define MON_MEM_FREE_SWAP "mem_freeswap" ProbeGatherData MonMemoryInit(const char **name, const char **error); #endif cfengine-3.24.2/cf-monitord/proc_net_parsing.h0000644000000000000000000000525715010704253021312 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef _CFE_PROC_NET_PARSING_H_ #define _CFE_PROC_NET_PARSING_H_ #include /* Taken from https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/misc/ss.c#n221 */ typedef enum { SOCK_STATE_UNKNOWN = 0, SOCK_STATE_ESTAB, SOCK_STATE_SYN_SENT, SOCK_STATE_SYN_RECV, SOCK_STATE_FIN_WAIT1, SOCK_STATE_FIN_WAIT2, SOCK_STATE_TIME_WAIT, SOCK_STATE_UNCONN, SOCK_STATE_CLOSE_WAIT, SOCK_STATE_LAST_ACK, SOCK_STATE_LISTEN, SOCK_STATE_CLOSING, } SocketState; #ifdef __linux__ bool ParseIPv4SocketInfo(const char *line, char local_addr[INET_ADDRSTRLEN], uint32_t *local_port, char remote_addr[INET_ADDRSTRLEN], uint32_t *remote_port, SocketState *state); bool ParseIPv6SocketInfo(const char *line, char local_addr[INET6_ADDRSTRLEN], uint32_t *local_port, char remote_addr[INET6_ADDRSTRLEN], uint32_t *remote_port, SocketState *state); #else /* __linux__ */ bool ParseIPv4SocketInfo(const char *line, char local_addr[INET_ADDRSTRLEN], uint32_t *local_port, char remote_addr[INET_ADDRSTRLEN], uint32_t *remote_port, SocketState *state) __attribute__((error ("Only supported on Linux"))); bool ParseIPv6SocketInfo(const char *line, char local_addr[INET6_ADDRSTRLEN], uint32_t *local_port, char remote_addr[INET6_ADDRSTRLEN], uint32_t *remote_port, SocketState *state) __attribute__((error ("Only supported on Linux"))); #endif /* __linux__ */ #endif /* _CFE_PROC_NET_PARSING_H_ */ cfengine-3.24.2/cf-monitord/mon_network_sniffer.c0000644000000000000000000004034215010704253022021 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include typedef enum { IP_TYPES_ICMP, IP_TYPES_UDP, IP_TYPES_DNS, IP_TYPES_TCP_SYN, IP_TYPES_TCP_ACK, IP_TYPES_TCP_FIN, IP_TYPES_TCP_MISC } IPTypes; /* Constants */ #define CF_TCPDUMP_COMM "/usr/sbin/tcpdump -t -n -v" static const int SLEEPTIME = 2.5 * 60; /* Should be a fraction of 5 minutes */ static const char *const TCPNAMES[CF_NETATTR] = { "icmp", "udp", "dns", "tcpsyn", "tcpack", "tcpfin", "misc" }; /* Global variables */ static bool TCPDUMP = false; static bool TCPPAUSE = false; static FILE *TCPPIPE = NULL; static Item *NETIN_DIST[CF_NETATTR] = { NULL }; static Item *NETOUT_DIST[CF_NETATTR] = { NULL }; /* Prototypes */ static void Sniff(Item *ip_addresses, long iteration, double *cf_this); static void AnalyzeArrival(Item *ip_addresses, long iteration, char *arrival, double *cf_this); static void DePort(char *address); /* Implementation */ void MonNetworkSnifferSniff(Item *ip_addresses, long iteration, double *cf_this) { if (TCPDUMP) { Sniff(ip_addresses, iteration, cf_this); } else { sleep(SLEEPTIME); } } /******************************************************************************/ void MonNetworkSnifferOpen(void) { char tcpbuffer[CF_BUFSIZE]; if (TCPDUMP) { struct stat statbuf; char buffer[CF_MAXVARSIZE]; sscanf(CF_TCPDUMP_COMM, "%s", buffer); if (stat(buffer, &statbuf) != -1) { if ((TCPPIPE = cf_popen(CF_TCPDUMP_COMM, "r", true)) == NULL) { TCPDUMP = false; } /* Skip first banner */ if (fgets(tcpbuffer, sizeof(tcpbuffer), TCPPIPE) == NULL) { UnexpectedError("Failed to read output from '%s'", CF_TCPDUMP_COMM); cf_pclose(TCPPIPE); TCPPIPE = NULL; TCPDUMP = false; } } else { TCPDUMP = false; } } } /******************************************************************************/ void MonNetworkSnifferEnable(bool enable) { TCPDUMP = enable; Log(LOG_LEVEL_DEBUG, "use tcpdump = %d", TCPDUMP); } /******************************************************************************/ static void CfenvTimeOut(ARG_UNUSED int signum) { alarm(0); TCPPAUSE = true; Log(LOG_LEVEL_VERBOSE, "Time out"); } /******************************************************************************/ static void Sniff(Item *ip_addresses, long iteration, double *cf_this) { char tcpbuffer[CF_BUFSIZE]; Log(LOG_LEVEL_VERBOSE, "Reading from tcpdump..."); memset(tcpbuffer, 0, CF_BUFSIZE); signal(SIGALRM, CfenvTimeOut); alarm(SLEEPTIME); TCPPAUSE = false; while (!feof(TCPPIPE) && !IsPendingTermination()) { if (TCPPAUSE) { break; } if (fgets(tcpbuffer, sizeof(tcpbuffer), TCPPIPE) == NULL) { UnexpectedError("Unable to read data from tcpdump; closing pipe"); cf_pclose(TCPPIPE); TCPPIPE = NULL; TCPDUMP = false; break; } if (TCPPAUSE) { break; } if (strstr(tcpbuffer, "tcpdump:")) /* Error message protect sleeptime */ { Log(LOG_LEVEL_DEBUG, "Error - '%s'", tcpbuffer); alarm(0); TCPDUMP = false; break; } AnalyzeArrival(ip_addresses, iteration, tcpbuffer, cf_this); } signal(SIGALRM, SIG_DFL); TCPPAUSE = false; fflush(TCPPIPE); } /******************************************************************************/ static void IncrementCounter(Item **list, char *name) { if (!IsItemIn(*list, name)) { AppendItem(list, name, ""); } IncrementItemListCounter(*list, name); } /* This coarsely classifies TCP dump data */ static void AnalyzeArrival(Item *ip_addresses, long iteration, char *arrival, double *cf_this) { char src[CF_BUFSIZE]; char dest[sizeof(src) + sizeof(" NETBIOS") - 1]; char flag = '.', *arr; int isme_dest, isme_src; src[0] = dest[0] = '\0'; if (strstr(arrival, "listening")) { return; } if (Chop(arrival, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } /* Most hosts have only a few dominant services, so anomalies will show up even in the traffic without looking too closely. This will apply only to the main interface .. not multifaces New format in tcpdump IP (tos 0x10, ttl 64, id 14587, offset 0, flags [DF], proto TCP (6), length 692) 128.39.89.232.22 > 84.215.40.125.48022: P 1546432:1547072(640) ack 1969 win 1593 IP (tos 0x0, ttl 251, id 14109, offset 0, flags [DF], proto UDP (17), length 115) 84.208.20.110.53 > 192.168.1.103.32769: 45266 NXDomain 0/1/0 (87) arp who-has 192.168.1.1 tell 192.168.1.103 arp reply 192.168.1.1 is-at 00:1d:7e:28:22:c6 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 192.168.1.103 > 128.39.89.10: ICMP echo request, id 48474, seq 1, length 64 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84) 192.168.1.103 > 128.39.89.10: ICMP echo request, id 48474, seq 2, length 64 */ for (arr = strstr(arrival, "length"); (arr != NULL) && (*arr != ')'); arr++) { } if (arr == NULL) { arr = arrival; } else { arr++; } if ((strstr(arrival, "proto TCP")) || (strstr(arrival, "ack"))) { nt_static_assert(sizeof(src) == CF_BUFSIZE); nt_static_assert(sizeof(dest) >= CF_BUFSIZE); nt_static_assert(CF_BUFSIZE == 4096); sscanf(arr, "%4095s %*c %4095s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); switch (flag) { case 'S': Log(LOG_LEVEL_DEBUG, "%ld: TCP new connection from '%s' to '%s' - i am '%s'", iteration, src, dest, VIPADDRESS); if (isme_dest) { cf_this[ob_tcpsyn_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_SYN]), src); } else if (isme_src) { cf_this[ob_tcpsyn_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_SYN]), dest); } break; case 'F': Log(LOG_LEVEL_DEBUG, "%ld: TCP end connection from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_tcpfin_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_FIN]), src); } else if (isme_src) { cf_this[ob_tcpfin_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_FIN]), dest); } break; default: Log(LOG_LEVEL_DEBUG, "%ld: TCP established from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_tcpack_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_ACK]), src); } else if (isme_src) { cf_this[ob_tcpack_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_ACK]), dest); } break; } } else if (strstr(arrival, ".53")) { nt_static_assert(sizeof(src) == CF_BUFSIZE); nt_static_assert(sizeof(dest) >= CF_BUFSIZE); nt_static_assert(CF_BUFSIZE == 4096); sscanf(arr, "%4095s %*c %4095s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); Log(LOG_LEVEL_DEBUG, "%ld: DNS packet from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_dns_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_DNS]), src); } else if (isme_src) { cf_this[ob_dns_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_TCP_ACK]), dest); } } else if (strstr(arrival, "proto UDP")) { nt_static_assert(sizeof(src) == CF_BUFSIZE); nt_static_assert(sizeof(dest) >= CF_BUFSIZE); nt_static_assert(CF_BUFSIZE == 4096); sscanf(arr, "%4095s %*c %4095s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); Log(LOG_LEVEL_DEBUG, "%ld: UDP packet from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_udp_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_UDP]), src); } else if (isme_src) { cf_this[ob_udp_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_UDP]), dest); } } else if (strstr(arrival, "proto ICMP")) { nt_static_assert(sizeof(src) == CF_BUFSIZE); nt_static_assert(sizeof(dest) >= CF_BUFSIZE); nt_static_assert(CF_BUFSIZE == 4096); sscanf(arr, "%4095s %*c %4095s %c ", src, dest, &flag); DePort(src); DePort(dest); isme_dest = IsInterfaceAddress(ip_addresses, dest); isme_src = IsInterfaceAddress(ip_addresses, src); Log(LOG_LEVEL_DEBUG, "%ld: ICMP packet from '%s' to '%s'", iteration, src, dest); if (isme_dest) { cf_this[ob_icmp_in]++; IncrementCounter(&(NETIN_DIST[IP_TYPES_ICMP]), src); } else if (isme_src) { cf_this[ob_icmp_out]++; IncrementCounter(&(NETOUT_DIST[IP_TYPES_ICMP]), src); } } else { Log(LOG_LEVEL_DEBUG, "%ld: Miscellaneous undirected packet (%.100s)", iteration, arrival); cf_this[ob_tcpmisc_in]++; /* Here we don't know what source will be, but .... */ nt_static_assert(sizeof(src) == CF_BUFSIZE); nt_static_assert(CF_BUFSIZE == 4096); sscanf(arrival, "%4095s", src); if (!isdigit((int) *src)) { Log(LOG_LEVEL_DEBUG, "Assuming continuation line..."); return; } DePort(src); if (strstr(arrival, ".138")) { nt_static_assert(sizeof(dest) >= (sizeof(src) + sizeof(" NETBIOS") - 1)); snprintf(dest, sizeof(dest), "%s NETBIOS", src); } else if (strstr(arrival, ".2049")) { nt_static_assert(sizeof(dest) >= (sizeof(src) + sizeof(" NFS") - 1)); snprintf(dest, sizeof(dest), "%s NFS", src); } else { nt_static_assert(sizeof(dest) > 60); strncpy(dest, src, 60); dest[60] = '\0'; } IncrementCounter(&(NETIN_DIST[IP_TYPES_TCP_MISC]), dest); } } /******************************************************************************/ static void SaveTCPEntropyData(Item *list, int i, char *inout) { Item *ip; char filename[CF_BUFSIZE]; Log(LOG_LEVEL_VERBOSE, "TCP Save '%s'", TCPNAMES[i]); if (list == NULL) { Log(LOG_LEVEL_VERBOSE, "No %s-%s events", TCPNAMES[i], inout); return; } if (strncmp(inout, "in", 2) == 0) { snprintf(filename, CF_BUFSIZE, "%s%ccf_incoming.%s", GetStateDir(), FILE_SEPARATOR, TCPNAMES[i]); } else { snprintf(filename, CF_BUFSIZE, "%s%ccf_outgoing.%s", GetStateDir(), FILE_SEPARATOR, TCPNAMES[i]); } Log(LOG_LEVEL_VERBOSE, "TCP Save '%s'", filename); FILE *fp = safe_fopen(filename, "w"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't save TCP entropy to '%s' (fopen: %s)", filename, GetErrorStr()); return; } for (ip = list; ip != NULL; ip = ip->next) { fprintf(fp, "%d %s\n", ip->counter, ip->name); } fclose(fp); } /******************************************************************************/ void MonNetworkSnifferGatherData(void) { int i; char vbuff[CF_BUFSIZE]; const char* const statedir = GetStateDir(); for (i = 0; i < CF_NETATTR; i++) { struct stat statbuf; double entropy; time_t now = time(NULL); Log(LOG_LEVEL_DEBUG, "save incoming '%s'", TCPNAMES[i]); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_incoming.%s", statedir, FILE_SEPARATOR, TCPNAMES[i]); if (stat(vbuff, &statbuf) != -1) { if (ItemListSize(NETIN_DIST[i]) < (size_t) statbuf.st_size && now < statbuf.st_mtime + 40 * 60) { Log(LOG_LEVEL_VERBOSE, "New state %s is smaller, retaining old for 40 mins longer", TCPNAMES[i]); DeleteItemList(NETIN_DIST[i]); NETIN_DIST[i] = NULL; continue; } } SaveTCPEntropyData(NETIN_DIST[i], i, "in"); entropy = MonEntropyCalculate(NETIN_DIST[i]); MonEntropyClassesSet(TCPNAMES[i], "in", entropy); DeleteItemList(NETIN_DIST[i]); NETIN_DIST[i] = NULL; } for (i = 0; i < CF_NETATTR; i++) { struct stat statbuf; double entropy; time_t now = time(NULL); Log(LOG_LEVEL_DEBUG, "save outgoing '%s'", TCPNAMES[i]); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_outgoing.%s", statedir, FILE_SEPARATOR, TCPNAMES[i]); if (stat(vbuff, &statbuf) != -1) { if (ItemListSize(NETOUT_DIST[i]) < (size_t) statbuf.st_size && now < statbuf.st_mtime + 40 * 60) { Log(LOG_LEVEL_VERBOSE, "New state '%s' is smaller, retaining old for 40 mins longer", TCPNAMES[i]); DeleteItemList(NETOUT_DIST[i]); NETOUT_DIST[i] = NULL; continue; } } SaveTCPEntropyData(NETOUT_DIST[i], i, "out"); entropy = MonEntropyCalculate(NETOUT_DIST[i]); MonEntropyClassesSet(TCPNAMES[i], "out", entropy); DeleteItemList(NETOUT_DIST[i]); NETOUT_DIST[i] = NULL; } } void DePort(char *address) { char *sp, *chop, *fc = NULL, *fd = NULL, *ld = NULL; int ccount = 0, dcount = 0; /* Start looking for ethernet/ipv6 addresses */ for (sp = address; *sp != '\0'; sp++) { if (*sp == ':') { if (!fc) { fc = sp; } ccount++; } if (*sp == '.') { if (!fd) { fd = sp; } ld = sp; dcount++; } } if (!fd) { /* This does not look like an IP address+port, maybe ethernet */ return; } if (dcount == 4) { chop = ld; } else if ((dcount > 1) && (fc != NULL)) { chop = fc; } else if ((ccount > 1) && (fd != NULL)) { chop = fd; } else { /* Don't recognize address */ return; } if (chop < address + strlen(address)) { *chop = '\0'; } return; } cfengine-3.24.2/cf-monitord/mon_io_linux.c0000644000000000000000000002052115010704253020437 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #define SYSFSBLOCK "/sys/class/block/" #define KB 1024 /************************************************************************/ static void SysfsizeDeviceName(char *name) { while ((name = strchr(name, '/'))) { *name = '!'; } } static int DiskSectorSize(const char *sysfsname) { char sysfspath[CF_BUFSIZE]; int size = 512; /* Long-time default value */ if (snprintf(sysfspath, CF_BUFSIZE, SYSFSBLOCK "%s/queue/logical_block_size", sysfsname) >= CF_BUFSIZE) { /* FIXME: report overlong string */ return -1; } FILE *fh = safe_fopen(sysfspath, "r"); if (fh == NULL) { /* * Older Linux systems don't work correctly with new 4K drives. It's safe to * report 512 here */ } else { if (fscanf(fh, "%d", &size) != 1) { if (ferror(fh)) { Log(LOG_LEVEL_ERR, "Unable to read sector size for '%s'. Assuming 512 bytes. (fscanf: %s)", sysfsname, GetErrorStr()); } else { Log(LOG_LEVEL_ERR, "Unable to read sector size for %s. Assuming 512 bytes.", sysfsname); } } fclose(fh); } return size; } static bool IsPartition(const char *sysfsname) { char sysfspath[CF_BUFSIZE]; if (snprintf(sysfspath, CF_BUFSIZE, "%s/partition", SYSFSBLOCK) >= CF_BUFSIZE) { /* FIXME: report overlong string */ return false; } if (access(sysfspath, F_OK) == 0) { return true; } if (errno != ENOENT) { Log(LOG_LEVEL_ERR, "Unable to detect whether block device %s is a partition. (access: %s)", sysfsname, GetErrorStr()); } return false; } static bool IsStackedDevice(const char *sysfsname) { /* "Stacked" as LVM or cryptfs volume */ char sysfspath[CF_BUFSIZE]; DIR *dir; struct dirent *dirent; if (snprintf(sysfspath, CF_BUFSIZE, "%s/slaves", SYSFSBLOCK) >= CF_BUFSIZE) { /* FIXME: report overlong string */ return false; } if (!(dir = opendir(sysfspath))) { /* We don't have any information */ return false; } errno = 0; while ((dirent = readdir(dir))) { if (strcmp(dirent->d_name, ".") && strcmp(dirent->d_name, "..")) { /* Found a file inside. It's a stacked device. */ closedir(dir); return true; } } if (errno) { Log(LOG_LEVEL_ERR, "Unable to read 'slaves' sysfs subdirectory for '%s'. (readdir: %s)", sysfsname, GetErrorStr()); } closedir(dir); return false; } static bool IsPhysicalDevice(const char *sysfsname) { return !IsPartition(sysfsname) && !IsStackedDevice(sysfsname); } /************************************************************************/ static void MonIoDiskstatsGatherData(double *cf_this) { char buf[CF_BUFSIZE]; FILE *fh; time_t now = time(NULL); unsigned long long totalreads = 0, totalwrites = 0; unsigned long long totalreadbytes = 0, totalwrittenbytes = 0; if (!(fh = fopen("/proc/diskstats", "r"))) { Log(LOG_LEVEL_ERR, "Error trying to open /proc/diskstats. (fopen: %s)", GetErrorStr()); return; } /* Read per-disk statistics */ while (fgets(buf, CF_BUFSIZE, fh)) { unsigned long reads, writes, readsectors, writtensectors; /* Format sanity check */ if (!strchr(buf, '\n')) { Log(LOG_LEVEL_ERR, "/proc/diskstats format error: read overlong string (> " TO_STRING(CF_BUFSIZE) " bytes)"); goto err; } if (StripTrailingNewline(buf, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "StripTrailingNewline was called on an overlong string"); } char diskname[256]; if (sscanf(buf, "%*u %*u %255s %lu %*u %lu %*u %lu %*u %lu", diskname, &reads, &readsectors, &writes, &writtensectors) != 5) { Log(LOG_LEVEL_ERR, "Wrong /proc/diskstats line format: %s", buf); continue; } SysfsizeDeviceName(diskname); if (!reads && !readsectors && !writes && !writtensectors) { /* Not a disk. Something virtual: loopback or similar */ continue; } if (!IsPhysicalDevice(diskname)) { continue; } reads = GetInstantUint32Value(diskname, "reads", reads, now); writes = GetInstantUint32Value(diskname, "writes", writes, now); readsectors = GetInstantUint32Value(diskname, "readsectors", readsectors, now); writtensectors = GetInstantUint32Value(diskname, "writtensectors", writtensectors, now); if (reads != (unsigned) -1) { int sectorsize = DiskSectorSize(diskname); totalreads += reads; totalwrites += writes; totalreadbytes += ((unsigned long long) readsectors) * sectorsize; totalwrittenbytes += ((unsigned long long) writtensectors) * sectorsize; } } if (ferror(fh)) { Log(LOG_LEVEL_ERR, "Error reading /proc/diskstats. (fgets: %s)", GetErrorStr()); goto err; } /* Summarize */ int reads_slot = NovaRegisterSlot(MON_IO_READS, "Number of I/O reads", "reads per second", 0.0, 1000.0, true); int writes_slot = NovaRegisterSlot(MON_IO_WRITES, "Number of I/O writes", "writes per second", 0.0f, 1000.0f, true); int readdata_slot = NovaRegisterSlot(MON_IO_READDATA, "Aggregate mount of data read across all devices", "megabytes/s", 0.0, 1000.0, true); int writtendata_slot = NovaRegisterSlot(MON_IO_WRITTENDATA, "Aggregate amount of data written across all devices", "megabytes/s", 0.0, 1000.0, true); if (reads_slot != -1 && totalreads != 0) { cf_this[reads_slot] = totalreads; } if (writes_slot != -1 && totalwrites != 0) { cf_this[writes_slot] = totalwrites; } if (readdata_slot != -1 && totalreadbytes != 0) { cf_this[readdata_slot] = ((double) totalreadbytes) / KB / KB; } if (writtendata_slot != -1 && totalwrittenbytes != 0) { cf_this[writtendata_slot] = ((double) totalwrittenbytes) / KB / KB; } err: fclose(fh); } /************************************************************************/ static void MonIoPartitionsGatherData(ARG_UNUSED double *cf_this) { /* FIXME: Not implemented */ } /************************************************************************/ ProbeGatherData MonIoInit(const char **name, const char **error) { if (access("/proc/diskstats", R_OK) == 0) { *name = "Linux 2.6 /proc/diskstats statistics"; *error = NULL; return &MonIoDiskstatsGatherData; } else if (access("/proc/partitions", R_OK) == 0) { *name = "Linux 2.4 /proc/partitions statistics"; *error = NULL; return &MonIoPartitionsGatherData; } else { *name = NULL; *error = "/proc/diskstats and /proc/partitions are not available"; return NULL; } } cfengine-3.24.2/cf-monitord/mon_load.c0000644000000000000000000000326315010704253017534 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #ifdef HAVE_SYS_LOADAVG_H # include #else # define LOADAVG_5MIN 1 #endif #include /* Implementation */ #ifdef HAVE_GETLOADAVG void MonLoadGatherData(double *cf_this) { double load[LOADAVG_5MIN], sum = 0.0; int i, n; if ((n = getloadavg(load, LOADAVG_5MIN)) == -1) { cf_this[ob_loadavg] = 0.0; } for (i = 0; i < n; ++i) { sum += load[i]; } sum /= (double) n; cf_this[ob_loadavg] = sum; Log(LOG_LEVEL_VERBOSE, "Load Average = %.2lf", cf_this[ob_loadavg]); } #else void MonLoadGatherData(double *cf_this) { Log(LOG_LEVEL_DEBUG, "Average load data is not available."); } #endif cfengine-3.24.2/cf-monitord/Makefile.in0000644000000000000000000010770615010704300017645 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @LINUX_TRUE@am__append_1 = mon_io_linux.c mon_mem_linux.c proc_net_parsing.c proc_net_parsing.h @SOLARIS_TRUE@am__append_2 = mon_mem_solaris.c shared_kstat.c shared_kstat.h @LINUX_FALSE@am__append_3 = mon_io_stub.c @LINUX_FALSE@@SOLARIS_FALSE@am__append_4 = mon_mem_stub.c TESTS = $(am__EXEEXT_1) @LINUX_TRUE@am__append_5 = get_socket_info @LINUX_TRUE@noinst_PROGRAMS = get_socket_info$(EXEEXT) @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-monitord$(EXEEXT) subdir = cf-monitord ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_monitord_la_DEPENDENCIES = ../libpromises/libpromises.la am__libcf_monitord_la_SOURCES_DIST = verify_measurements.c \ verify_measurements.h env_monitor.c env_monitor.h mon.h \ mon_cpu.c mon_disk.c mon_entropy.c mon_load.c \ mon_network_sniffer.c mon_network.c mon_processes.c mon_temp.c \ history.c history.h mon_cumulative.c mon_cumulative.h probes.c \ probes.h monitoring.c monitoring.h cf-monitord.c \ mon_io_linux.c mon_mem_linux.c proc_net_parsing.c \ proc_net_parsing.h mon_mem_solaris.c shared_kstat.c \ shared_kstat.h mon_io_stub.c mon_mem_stub.c @LINUX_TRUE@am__objects_1 = mon_io_linux.lo mon_mem_linux.lo \ @LINUX_TRUE@ proc_net_parsing.lo @SOLARIS_TRUE@am__objects_2 = mon_mem_solaris.lo shared_kstat.lo @LINUX_FALSE@am__objects_3 = mon_io_stub.lo @LINUX_FALSE@@SOLARIS_FALSE@am__objects_4 = mon_mem_stub.lo am_libcf_monitord_la_OBJECTS = verify_measurements.lo env_monitor.lo \ mon_cpu.lo mon_disk.lo mon_entropy.lo mon_load.lo \ mon_network_sniffer.lo mon_network.lo mon_processes.lo \ mon_temp.lo history.lo mon_cumulative.lo probes.lo \ monitoring.lo cf-monitord.lo $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) libcf_monitord_la_OBJECTS = $(am_libcf_monitord_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) cf_monitord_SOURCES = cf-monitord.c cf_monitord_OBJECTS = cf_monitord-cf-monitord.$(OBJEXT) @BUILTIN_EXTENSIONS_FALSE@cf_monitord_DEPENDENCIES = \ @BUILTIN_EXTENSIONS_FALSE@ libcf-monitord.la cf_monitord_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(cf_monitord_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__get_socket_info_SOURCES_DIST = get_socket_info.c @LINUX_TRUE@am_get_socket_info_OBJECTS = get_socket_info.$(OBJEXT) get_socket_info_OBJECTS = $(am_get_socket_info_OBJECTS) am__DEPENDENCIES_1 = @LINUX_TRUE@get_socket_info_DEPENDENCIES = \ @LINUX_TRUE@ ../libntech/libutils/libutils.la \ @LINUX_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @LINUX_TRUE@ libcf-monitord.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_monitord_la_SOURCES) cf-monitord.c \ $(get_socket_info_SOURCES) DIST_SOURCES = $(am__libcf_monitord_la_SOURCES_DIST) cf-monitord.c \ $(am__get_socket_info_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } @LINUX_TRUE@am__EXEEXT_1 = get_socket_info$(EXEEXT) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-monitord.la AM_CPPFLAGS = \ -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libenv \ -I$(srcdir)/../libpromises \ $(PCRE2_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_monitord_la_LIBADD = ../libpromises/libpromises.la libcf_monitord_la_SOURCES = verify_measurements.c \ verify_measurements.h env_monitor.c env_monitor.h mon.h \ mon_cpu.c mon_disk.c mon_entropy.c mon_load.c \ mon_network_sniffer.c mon_network.c mon_processes.c mon_temp.c \ history.c history.h mon_cumulative.c mon_cumulative.h probes.c \ probes.h monitoring.c monitoring.h cf-monitord.c \ $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) @LINUX_TRUE@get_socket_info_SOURCES = get_socket_info.c @LINUX_TRUE@get_socket_info_LDADD = ../libntech/libutils/libutils.la \ @LINUX_TRUE@ $(PCRE2_LIBS) \ @LINUX_TRUE@ $(LIBYAML_LIBS) \ @LINUX_TRUE@ libcf-monitord.la # Workaround for automake madness (try removing it if you want to know why). @BUILTIN_EXTENSIONS_FALSE@cf_monitord_CFLAGS = $(AM_CFLAGS) @BUILTIN_EXTENSIONS_FALSE@cf_monitord_LDADD = libcf-monitord.la CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-monitord/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-monitord/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-monitord.la: $(libcf_monitord_la_OBJECTS) $(libcf_monitord_la_DEPENDENCIES) $(EXTRA_libcf_monitord_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_monitord_la_OBJECTS) $(libcf_monitord_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-monitord$(EXEEXT): $(cf_monitord_OBJECTS) $(cf_monitord_DEPENDENCIES) $(EXTRA_cf_monitord_DEPENDENCIES) @rm -f cf-monitord$(EXEEXT) $(AM_V_CCLD)$(cf_monitord_LINK) $(cf_monitord_OBJECTS) $(cf_monitord_LDADD) $(LIBS) get_socket_info$(EXEEXT): $(get_socket_info_OBJECTS) $(get_socket_info_DEPENDENCIES) $(EXTRA_get_socket_info_DEPENDENCIES) @rm -f get_socket_info$(EXEEXT) $(AM_V_CCLD)$(LINK) $(get_socket_info_OBJECTS) $(get_socket_info_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-monitord.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_monitord-cf-monitord.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env_monitor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_socket_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/history.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_cpu.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_cumulative.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_disk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_entropy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_io_linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_io_stub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_load.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_mem_linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_mem_solaris.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_mem_stub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_network.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_network_sniffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_processes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_temp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitoring.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/probes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc_net_parsing.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shared_kstat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_measurements.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cf_monitord-cf-monitord.o: cf-monitord.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_monitord_CFLAGS) $(CFLAGS) -MT cf_monitord-cf-monitord.o -MD -MP -MF $(DEPDIR)/cf_monitord-cf-monitord.Tpo -c -o cf_monitord-cf-monitord.o `test -f 'cf-monitord.c' || echo '$(srcdir)/'`cf-monitord.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_monitord-cf-monitord.Tpo $(DEPDIR)/cf_monitord-cf-monitord.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-monitord.c' object='cf_monitord-cf-monitord.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_monitord_CFLAGS) $(CFLAGS) -c -o cf_monitord-cf-monitord.o `test -f 'cf-monitord.c' || echo '$(srcdir)/'`cf-monitord.c cf_monitord-cf-monitord.obj: cf-monitord.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_monitord_CFLAGS) $(CFLAGS) -MT cf_monitord-cf-monitord.obj -MD -MP -MF $(DEPDIR)/cf_monitord-cf-monitord.Tpo -c -o cf_monitord-cf-monitord.obj `if test -f 'cf-monitord.c'; then $(CYGPATH_W) 'cf-monitord.c'; else $(CYGPATH_W) '$(srcdir)/cf-monitord.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_monitord-cf-monitord.Tpo $(DEPDIR)/cf_monitord-cf-monitord.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-monitord.c' object='cf_monitord-cf-monitord.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_monitord_CFLAGS) $(CFLAGS) -c -o cf_monitord-cf-monitord.obj `if test -f 'cf-monitord.c'; then $(CYGPATH_W) 'cf-monitord.c'; else $(CYGPATH_W) '$(srcdir)/cf-monitord.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-monitord/cf-monitord.c0000644000000000000000000002634215010704253020170 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* FILE_SEPARATOR */ typedef enum { MONITOR_CONTROL_FORGET_RATE, MONITOR_CONTROL_MONITOR_FACILITY, MONITOR_CONTROL_HISTOGRAMS, MONITOR_CONTROL_TCP_DUMP, MONITOR_CONTROL_NONE } MonitorControl; static void ThisAgentInit(EvalContext *ctx); static GenericAgentConfig *CheckOpts(int argc, char **argv); static void KeepPromises(EvalContext *ctx, const Policy *policy); /*****************************************************************************/ /* Globals */ /*****************************************************************************/ extern int NO_FORK; extern const ConstraintSyntax CFM_CONTROLBODY[]; /*******************************************************************/ /* Command line options */ /*******************************************************************/ static const char *const CF_MONITORD_SHORT_DESCRIPTION = "monitoring daemon for CFEngine"; static const char *const CF_MONITORD_MANPAGE_LONG_DESCRIPTION = "cf-monitord is the monitoring daemon for CFEngine. It samples probes defined in policy code and attempts to learn the " "normal system state based on current and past observations. Current estimates are made available as " "special variables (e.g. $(mon.av_cpu)) to cf-agent, which may use them to inform policy decisions."; static const Component COMPONENT = { .name = "cf-monitord", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"help", no_argument, 0, 'h'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"dry-run", no_argument, 0, 'n'}, {"version", no_argument, 0, 'V'}, {"no-lock", no_argument, 0, 'K'}, {"file", required_argument, 0, 'f'}, {"log-level", required_argument, 0, 'g'}, {"inform", no_argument, 0, 'I'}, {"diagnostic", no_argument, 0, 'x'}, {"no-fork", no_argument, 0, 'F'}, {"histograms", no_argument, 0, 'H'}, {"tcpdump", no_argument, 0, 'T'}, {"color", optional_argument, 0, 'C'}, {"timestamp", no_argument, 0, 'l'}, /* Only long option for the rest */ {"ignore-preferred-augments", no_argument, 0, 0}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Enable debugging output", "Output verbose information about the behaviour of cf-monitord", "All talk and no action mode - make no changes, only inform of promises not kept", "Output the version of the software", "Ignore system lock", "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Print basic information about changes made to the system, i.e. promises repaired", "Activate internal diagnostics (developers only)", "Run process in foreground, not as a daemon", "Ignored for backward compatibility", "Interface with tcpdump if available to collect data about network", "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", "Log timestamps on each line of log output", "Ignore def_preferred.json file in favor of def.json", NULL }; /*****************************************************************************/ int main(int argc, char *argv[]) { GenericAgentConfig *config = CheckOpts(argc, argv); EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); const char *program_invocation_name = argv[0]; const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR); const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name); GenericAgentDiscoverContext(ctx, config, program_name); Policy *policy = LoadPolicy(ctx, config); GenericAgentPostLoadInit(ctx); ThisAgentInit(ctx); KeepPromises(ctx, policy); MonitorStartServer(ctx, policy); PolicyDestroy(policy); GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return 0; } /*******************************************************************/ static GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int c; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_MONITOR, GetTTYInteractive()); int longopt_idx; while ((c = getopt_long(argc, argv, "dvnIf:g:VSxHTKMFhC::l", OPTIONS, &longopt_idx)) != -1) { switch (c) { case 'f': GenericAgentConfigSetInputFile(config, GetInputDir(), optarg); MINUSF = true; break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); NO_FORK = true; break; case 'K': config->ignore_locks = true; break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); NO_FORK = true; break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'F': NO_FORK = true; break; case 'H': /* Keep accepting this option for compatibility -- no longer used */ break; case 'T': MonNetworkSnifferEnable(true); break; case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'h': { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-monitord", time(NULL), CF_MONITORD_SHORT_DESCRIPTION, CF_MONITORD_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(out); DoCleanupAndExit(EXIT_SUCCESS); } case 'x': Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired."); DoCleanupAndExit(EXIT_SUCCESS); case 'C': if (!GenericAgentConfigParseColor(config, optarg)) { DoCleanupAndExit(EXIT_FAILURE); } break; case 'l': LoggingEnableTimestamps(true); break; /* long options only */ case 0: { const char *const option_name = OPTIONS[longopt_idx].name; if (StringEqual(option_name, "ignore-preferred-augments")) { config->ignore_preferred_augments = true; } break; } default: { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_FAILURE); } } if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind)) { Log(LOG_LEVEL_ERR, "Too many arguments"); DoCleanupAndExit(EXIT_FAILURE); } return config; } /*****************************************************************************/ static void KeepPromises(EvalContext *ctx, const Policy *policy) { Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_MONITOR); if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_monitor"); const void *value = EvalContextVariableGet(ctx, ref, NULL); VarRefDestroy(ref); if (!value) { Log(LOG_LEVEL_ERR, "Unknown lval '%s' in monitor control body", cp->lval); continue; } if (strcmp(cp->lval, CFM_CONTROLBODY[MONITOR_CONTROL_HISTOGRAMS].lval) == 0) { /* Keep accepting this option for backward compatibility. */ continue; } if (strcmp(cp->lval, CFM_CONTROLBODY[MONITOR_CONTROL_TCP_DUMP].lval) == 0) { MonNetworkSnifferEnable(BooleanFromString(value)); continue; } if (strcmp(cp->lval, CFM_CONTROLBODY[MONITOR_CONTROL_FORGET_RATE].lval) == 0) { sscanf(value, "%lf", &FORGETRATE); Log(LOG_LEVEL_DEBUG, "forget rate %f", FORGETRATE); continue; } if (StringEqual(cp->lval, CFM_CONTROLBODY[MONITOR_CONTROL_MONITOR_FACILITY].lval)) { SetFacility(value); continue; } } } } /*****************************************************************************/ /* Level 1 */ /*****************************************************************************/ static void ThisAgentInit(EvalContext *ctx) { umask(077); strcpy(VPREFIX, "cf-monitord"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); signal(SIGINT, HandleSignalsForDaemon); signal(SIGTERM, HandleSignalsForDaemon); signal(SIGBUS, HandleSignalsForDaemon); signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, HandleSignalsForDaemon); signal(SIGUSR2, HandleSignalsForDaemon); FORGETRATE = 0.6; MonitorInitialize(); } cfengine-3.24.2/cf-monitord/monitoring.h0000644000000000000000000000303315010704253020131 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CF_MONITORING_H #define CF_MONITORING_H #include int NovaRegisterSlot(const char *name, const char *description, const char *units, double expected_minimum, double expected_maximum, bool consolidable); void NovaNamedEvent(const char *eventname, double value); void GetObservable(int i, char *name, size_t name_size, char *desc, size_t desc_size); void SetMeasurementPromises(Item ** classlist); void LoadSlowlyVaryingObservations(EvalContext *ctx); void MakeTimekey(time_t time, char *result); #endif cfengine-3.24.2/cf-monitord/mon_entropy.c0000644000000000000000000000640415010704253020315 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* Globals */ static Item *ENTROPIES = NULL; /* Implementation */ void MonEntropyClassesInit(void) { } /****************************************************************************/ void MonEntropyClassesReset(void) { ENTROPIES = NULL; /*? */ } /****************************************************************************/ /* * This function calculates entropy of items distribution. * * Let's define: * N = length of items list * q_i = items[i]->counter * p_i = q_i / sum_{i=1..N}(q_i) * -- normalized values, or probability of i-th class amongst all * * Entropy is * --- * - > q_i * ln(q_i) * --- i=0..N * E = ------------------------- * ln(N) * * Divisor is a uncertainty per digit, to normalize it to [0..1] we divide it * by ln(N). */ double MonEntropyCalculate(const Item *items) { double S = 0.0; double sum = 0.0; int numclasses = 0; const Item *i; for (i = items; i; i = i->next) { sum += i->counter; numclasses++; } if (numclasses < 2) { return 0.0; } for (i = items; i; i = i->next) { double q = ((double) i->counter) / sum; S -= q * log(q); } return S / log(numclasses); } /****************************************************************************/ void MonEntropyClassesSet(const char *service, const char *direction, double entropy) { char class[CF_MAXVARSIZE]; const char *class_type = "medium"; if (entropy > 0.9) { class_type = "high"; } if (entropy < 0.2) { class_type = "low"; } snprintf(class, CF_MAXVARSIZE, "entropy_%s_%s_%s", service, direction, class_type); AppendItem(&ENTROPIES, class, ""); } /****************************************************************************/ void MonEntropyPurgeUnused(char *name) { // Don't set setentropy is there is no corresponding class DeleteItemMatching(&ENTROPIES, name); } /****************************************************************************/ void MonEntropyClassesPublish(FILE *fp) { for (Item *ip = ENTROPIES; ip != NULL; ip = ip->next) { fprintf(fp, "%s\n", ip->name); } DeleteItemList(ENTROPIES); } cfengine-3.24.2/cf-monitord/mon_io_stub.c0000644000000000000000000000222215010704253020253 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include ProbeGatherData MonIoInit(const char **name, const char **error) { *name = ""; *error = "Not avaliable"; return NULL; } cfengine-3.24.2/cf-monitord/mon_temp.c0000644000000000000000000002777615010704253017601 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include /* Globals */ static bool ACPI = false; static bool SYSTHERMAL = false; static bool LMSENSORS = false; /* Prototypes */ #if defined(__linux__) static bool GetAcpi(double *cf_this); static bool GetSysThermal(double *cf_this); static bool GetLMSensors(double *cf_this); #endif /* Implementation */ /****************************************************************************** * Motherboard sensors - how to standardize this somehow * We're mainly interested in temperature and power consumption, but only the * temperature is generally available. Several temperatures exist too ... ******************************************************************************/ #if defined(__linux__) void MonTempGatherData(double *cf_this) { if (ACPI && GetAcpi(cf_this)) { return; } if (SYSTHERMAL && GetSysThermal(cf_this)) { return; } if (LMSENSORS && GetLMSensors(cf_this)) { return; } } #else void MonTempGatherData(ARG_UNUSED double *cf_this) { } #endif /******************************************************************************/ void MonTempInit(void) { struct stat statbuf; for (int i = 0; i < 4; i++) { char s[128]; xsnprintf(s, sizeof(s), "/sys/devices/virtual/thermal/thermal_zone%d", i); if (stat(s, &statbuf) != -1) { Log(LOG_LEVEL_DEBUG, "Found a thermal device in /sys"); SYSTHERMAL = true; } } if (stat("/proc/acpi/thermal_zone", &statbuf) != -1) { Log(LOG_LEVEL_DEBUG, "Found an acpi service"); ACPI = true; } if (stat("/usr/bin/sensors", &statbuf) != -1) { if (statbuf.st_mode & 0111) { Log(LOG_LEVEL_DEBUG, "Found an lmsensor system"); LMSENSORS = true; } } } /******************************************************************************/ #if defined(__linux__) static bool GetAcpi(double *cf_this) { Dir *dirh; FILE *fp; const struct dirent *dirp; int count; char path[CF_BUFSIZE], buf[CF_BUFSIZE], index[4]; double temp; if ((dirh = DirOpen("/proc/acpi/thermal_zone")) == NULL) { Log(LOG_LEVEL_VERBOSE, "Can't open directory '%s'. (opendir: %s)", path, GetErrorStr()); return false; } for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, "..")) { continue; } snprintf(path, CF_BUFSIZE, "/proc/acpi/thermal_zone/%s/temperature", dirp->d_name); if ((fp = fopen(path, "r")) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open '%s' to gather temperature data (fopen: %s)", path, GetErrorStr()); continue; } if (fgets(buf, sizeof(buf), fp) == NULL) { Log(LOG_LEVEL_ERR, "Failed to read line from stream '%s'", path); fclose(fp); continue; } temp = 0.0; sscanf(buf, "%*s %lf", &temp); for (count = 0; count < 4; count++) { snprintf(index, 2, "%d", count); if (strstr(dirp->d_name, index)) { switch (count) { case 0: cf_this[ob_temp0] = temp; break; case 1: cf_this[ob_temp1] = temp; break; case 2: cf_this[ob_temp2] = temp; break; case 3: cf_this[ob_temp3] = temp; break; } Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf", count, temp); } } fclose(fp); } DirClose(dirh); return true; } /******************************************************************************/ static bool GetSysThermal(double *cf_this) { FILE *fp; int count; bool retval = false; for (count = 0; count < 4; count++) { double temp = 0; char path[128]; xsnprintf(path, sizeof(path), "/sys/devices/virtual/thermal/thermal_zone%d/temp", count); if ((fp = fopen(path, "r")) == NULL) { Log(LOG_LEVEL_INFO, "Couldn't open '%s'", path); continue; } char buf[128]; if (fgets(buf, sizeof(buf), fp) == NULL) { Log(LOG_LEVEL_INFO, "Failed to read line from stream '%s'", path); fclose(fp); continue; } int ret = sscanf(buf, "%lf", &temp); if (ret == 1) { switch (count) { case 0: cf_this[ob_temp0] = temp; break; case 1: cf_this[ob_temp1] = temp; break; case 2: cf_this[ob_temp2] = temp; break; case 3: cf_this[ob_temp3] = temp; break; } Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf", count, temp); retval = true; } else { Log(LOG_LEVEL_INFO, "Failed to read number from: %s", path); } fclose(fp); } return retval; } /******************************************************************************/ static bool GetLMSensors(double *cf_this) { FILE *pp; Item *ip, *list = NULL; double temp = 0; char name[CF_BUFSIZE]; int count; cf_this[ob_temp0] = 0.0; cf_this[ob_temp1] = 0.0; cf_this[ob_temp2] = 0.0; cf_this[ob_temp3] = 0.0; if ((pp = cf_popen("/usr/bin/sensors", "r", true)) == NULL) { LMSENSORS = false; /* Broken */ return false; } { size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp); if (res <= 0) { /* FIXME: do we need to log anything here? */ cf_pclose(pp); free(vbuff); return false; } for (;;) { ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp); if (res == -1) { if (!feof(pp)) { /* FIXME: Do we need to log anything here? */ cf_pclose(pp); free(vbuff); return false; } else { break; } } if (strstr(vbuff, "Temp") || strstr(vbuff, "temp")) { PrependItem(&list, vbuff, NULL); } } cf_pclose(pp); free(vbuff); } if (ListLen(list) > 0) { Log(LOG_LEVEL_DEBUG, "LM Sensors seemed to return ok data"); } else { return false; } /* lmsensor names are hopelessly inconsistent - so try a few things */ for (ip = list; ip != NULL; ip = ip->next) { for (count = 0; count < 4; count++) { snprintf(name, 16, "CPU%d Temp:", count); if (strncmp(ip->name, name, strlen(name)) == 0) { sscanf(ip->name, "%*[^:]: %lf", &temp); switch (count) { case 0: cf_this[ob_temp0] = temp; break; case 1: cf_this[ob_temp1] = temp; break; case 2: cf_this[ob_temp2] = temp; break; case 3: cf_this[ob_temp3] = temp; break; } Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf from what looks like cpu temperature", count, temp); } } } if (cf_this[ob_temp0] != 0) { /* We got something plausible */ return true; } /* Alternative name Core x: */ for (ip = list; ip != NULL; ip = ip->next) { for (count = 0; count < 4; count++) { snprintf(name, 16, "Core %d:", count); if (strncmp(ip->name, name, strlen(name)) == 0) { sscanf(ip->name, "%*[^:]: %lf", &temp); switch (count) { case 0: cf_this[ob_temp0] = temp; break; case 1: cf_this[ob_temp1] = temp; break; case 2: cf_this[ob_temp2] = temp; break; case 3: cf_this[ob_temp3] = temp; break; } Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf from what looks like core temperatures", count, temp); } } } if (cf_this[ob_temp0] != 0) { /* We got something plausible */ return true; } for (ip = list; ip != NULL; ip = ip->next) { if (strncmp(ip->name, "CPU Temp:", strlen("CPU Temp:")) == 0) { sscanf(ip->name, "%*[^:]: %lf", &temp); Log(LOG_LEVEL_DEBUG, "Setting temp0 to CPU Temp"); cf_this[ob_temp0] = temp; } if (strncmp(ip->name, "M/B Temp:", strlen("M/B Temp:")) == 0) { sscanf(ip->name, "%*[^:]: %lf", &temp); Log(LOG_LEVEL_DEBUG, "Setting temp0 to M/B Temp"); cf_this[ob_temp1] = temp; } if (strncmp(ip->name, "Sys Temp:", strlen("Sys Temp:")) == 0) { sscanf(ip->name, "%*[^:]: %lf", &temp); Log(LOG_LEVEL_DEBUG, "Setting temp0 to Sys Temp"); cf_this[ob_temp2] = temp; } if (strncmp(ip->name, "AUX Temp:", strlen("AUX Temp:")) == 0) { sscanf(ip->name, "%*[^:]: %lf", &temp); Log(LOG_LEVEL_DEBUG, "Setting temp0 to AUX Temp"); cf_this[ob_temp3] = temp; } } if (cf_this[ob_temp0] != 0) { /* We got something plausible */ return true; } /* Alternative name Core x: */ for (ip = list; ip != NULL; ip = ip->next) { for (count = 0; count < 4; count++) { snprintf(name, 16, "temp%d:", count); if (strncmp(ip->name, name, strlen(name)) == 0) { sscanf(ip->name, "%*[^:]: %lf", &temp); switch (count) { case 0: cf_this[ob_temp0] = temp; break; case 1: cf_this[ob_temp1] = temp; break; case 2: cf_this[ob_temp2] = temp; break; case 3: cf_this[ob_temp3] = temp; break; } Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf", count, temp); } } } /* Give up? */ DeleteItemList(list); return true; } #endif cfengine-3.24.2/cf-monitord/mon_disk.c0000644000000000000000000000570615010704253017553 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* Globals */ static double LASTQ[CF_OBSERVABLES] = { 0.0 }; /* Prototypes */ static int GetFileGrowth(const char *filename, enum observables index); /* Implementation */ void MonDiskGatherData(double *cf_this) { char accesslog[CF_BUFSIZE]; char errorlog[CF_BUFSIZE]; char syslog[CF_BUFSIZE]; char messages[CF_BUFSIZE]; Log(LOG_LEVEL_VERBOSE, "Gathering disk data"); cf_this[ob_diskfree] = GetDiskUsage("/", CF_SIZE_PERCENT); Log(LOG_LEVEL_VERBOSE, "Disk free = %.0lf%%", cf_this[ob_diskfree]); /* Here would should have some detection based on OS type VSYSTEMHARDCLASS */ strcpy(accesslog, "/var/log/apache2/access_log"); strcpy(errorlog, "/var/log/apache2/error_log"); strcpy(syslog, "/var/log/syslog"); strcpy(messages, "/var/log/messages"); cf_this[ob_webaccess] = GetFileGrowth(accesslog, ob_webaccess); Log(LOG_LEVEL_VERBOSE, "Webaccess = %.2lf%%", cf_this[ob_webaccess]); cf_this[ob_weberrors] = GetFileGrowth(errorlog, ob_weberrors); Log(LOG_LEVEL_VERBOSE, "Web error = %.2lf%%", cf_this[ob_weberrors]); cf_this[ob_syslog] = GetFileGrowth(syslog, ob_syslog); Log(LOG_LEVEL_VERBOSE, "Syslog = %.2lf%%", cf_this[ob_syslog]); cf_this[ob_messages] = GetFileGrowth(messages, ob_messages); Log(LOG_LEVEL_VERBOSE, "Messages = %.2lf%%", cf_this[ob_messages]); } /****************************************************************************/ static int GetFileGrowth(const char *filename, enum observables index) { struct stat statbuf; size_t q; double dq; if (stat(filename, &statbuf) == -1) { return 0; } q = statbuf.st_size; Log(LOG_LEVEL_VERBOSE, "GetFileGrowth(%s) = %zu", filename, q); dq = (double) q - LASTQ[index]; if (LASTQ[index] == 0) { LASTQ[index] = q; return (int) (q / 100 + 0.5); /* arbitrary spike mitigation */ } LASTQ[index] = q; return (int) (dq + 0.5); } cfengine-3.24.2/cf-monitord/mon_processes.c0000644000000000000000000001023615010704253020621 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include // SetUmask() #include #include #include #include /* Prototypes */ #ifndef __MINGW32__ static bool GatherProcessUsers(Item **userList, int *userListSz, int *numRootProcs, int *numOtherProcs); #endif /* Implementation */ void MonProcessesGatherData(double *cf_this) { Item *userList = NULL; int numProcUsers = 0; int numRootProcs = 0; int numOtherProcs = 0; if (!GatherProcessUsers(&userList, &numProcUsers, &numRootProcs, &numOtherProcs)) { return; } cf_this[ob_users] += numProcUsers; cf_this[ob_rootprocs] += numRootProcs; cf_this[ob_otherprocs] += numOtherProcs; char vbuff[CF_MAXVARSIZE]; xsnprintf(vbuff, sizeof(vbuff), "%s/cf_users", GetStateDir()); MapName(vbuff); const mode_t old_umask = SetUmask(0077); RawSaveItemList(userList, vbuff, NewLineMode_Unix); RestoreUmask(old_umask); DeleteItemList(userList); Log(LOG_LEVEL_VERBOSE, "(Users,root,other) = (%d,%d,%d)", (int) cf_this[ob_users], (int) cf_this[ob_rootprocs], (int) cf_this[ob_otherprocs]); } #ifndef __MINGW32__ static bool GatherProcessUsers(Item **userList, int *userListSz, int *numRootProcs, int *numOtherProcs) { char pscomm[CF_BUFSIZE]; xsnprintf(pscomm, sizeof(pscomm), "%s %s", VPSCOMM[VPSHARDCLASS], VPSOPTS[VPSHARDCLASS]); FILE *pp; if ((pp = cf_popen(pscomm, "r", true)) == NULL) { /* FIXME: no logging */ return false; } size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); /* Ignore first line -- header */ ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp); if (res <= 0) { /* FIXME: no logging */ cf_pclose(pp); free(vbuff); return false; } for (;;) { res = CfReadLine(&vbuff, &vbuff_size, pp); if (res == -1) { if (!feof(pp)) { /* FIXME: no logging */ cf_pclose(pp); free(vbuff); return false; } else { break; } } char user[64]; int ret = sscanf(vbuff, " %63s ", user); /* CFE-1560: Skip the username if it starts with a digit, this means * that we are reading the PID! Happens on some platforms (e.g. AIX) * where zombie processes have an empty username field in ps. */ if (ret != 1 || user[0] == '\0' || isdigit(user[0])) { continue; } if (!IsItemIn(*userList, user)) { PrependItem(userList, user, NULL); (*userListSz)++; } if (strcmp(user, "root") == 0) { (*numRootProcs)++; } else { (*numOtherProcs)++; } } if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { char *s = ItemList2CSV(*userList); Log(LOG_LEVEL_DEBUG, "Users in the process table: (%s)", s); free(s); } cf_pclose(pp); free(vbuff); return true; } #endif cfengine-3.24.2/cf-monitord/monitoring.c0000644000000000000000000002172115010704253020130 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void NovaNamedEvent(const char *eventname, double value) { Event ev_new, ev_old; time_t now = time(NULL); CF_DB *dbp; if (!OpenDB(&dbp, dbid_measure)) { return; } ev_new.t = now; if (ReadDB(dbp, eventname, &ev_old, sizeof(ev_old))) { if (isnan(ev_old.Q.expect)) { ev_old.Q.expect = value; } if (isnan(ev_old.Q.var)) { ev_old.Q.var = 0; } ev_new.Q = QAverage(ev_old.Q, value, 0.7); } else { ev_new.Q = QDefinite(value); } Log(LOG_LEVEL_VERBOSE, "Wrote scalar named event \"%s\" = (%.2lf,%.2lf,%.2lf)", eventname, ev_new.Q.q, ev_new.Q.expect, sqrt(ev_new.Q.var)); WriteDB(dbp, eventname, &ev_new, sizeof(ev_new)); CloseDB(dbp); } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static void Nova_DumpSlots(void) { #define MAX_KEY_FILE_SIZE 16384 /* usually around 4000, cannot grow much */ char filename[CF_BUFSIZE]; int i; snprintf(filename, CF_BUFSIZE - 1, "%s%cts_key", GetStateDir(), FILE_SEPARATOR); char file_contents_new[MAX_KEY_FILE_SIZE] = {0}; for (i = 0; i < CF_OBSERVABLES; i++) { char line[CF_MAXVARSIZE]; if (NovaHasSlot(i)) { snprintf(line, sizeof(line), "%d,%s,%s,%s,%.3lf,%.3lf,%d\n", i, NULLStringToEmpty((char*)NovaGetSlotName(i)), NULLStringToEmpty((char*)NovaGetSlotDescription(i)), NULLStringToEmpty((char*)NovaGetSlotUnits(i)), NovaGetSlotExpectedMinimum(i), NovaGetSlotExpectedMaximum(i), NovaIsSlotConsolidable(i) ? 1 : 0); } else { snprintf(line, sizeof(line), "%d,spare,unused\n", i); } strlcat(file_contents_new, line, sizeof(file_contents_new)); } bool contents_changed = true; Writer *w = FileRead(filename, MAX_KEY_FILE_SIZE, NULL); if (w) { if(strcmp(StringWriterData(w), file_contents_new) == 0) { contents_changed = false; } WriterClose(w); } if(contents_changed) { Log(LOG_LEVEL_VERBOSE, "Updating %s with new slot information", filename); if(!FileWriteOver(filename, file_contents_new)) { Log(LOG_LEVEL_ERR, "Nova_DumpSlots: Could not write file '%s'. (FileWriteOver: %s)", filename, GetErrorStr()); } } } void GetObservable(int i, char *name, size_t name_size, char *desc, size_t desc_size) { Nova_LoadSlots(); if (i < ob_spare) { strncpy(name, OBSERVABLES[i][0], name_size - 1); strncpy(desc, OBSERVABLES[i][1], desc_size - 1); } else { if (SLOTS[i - ob_spare]) { strncpy(name, SLOTS[i - ob_spare]->name, name_size - 1); strncpy(desc, SLOTS[i - ob_spare]->description, desc_size - 1); } else { strncpy(name, OBSERVABLES[i][0], name_size - 1); strncpy(desc, OBSERVABLES[i][1], desc_size - 1); } } } void SetMeasurementPromises(Item ** classlist) { CF_DB *dbp; CF_DBC *dbcp; char eventname[CF_MAXVARSIZE], assignment[CF_BUFSIZE]; Event entry; char *key; void *stored; int ksize, vsize; if (!OpenDB(&dbp, dbid_measure)) { return; } if (!NewDBCursor(dbp, &dbcp)) { Log(LOG_LEVEL_INFO, "Unable to scan class db"); CloseDB(dbp); return; } memset(&entry, 0, sizeof(entry)); while (NextDB(dbcp, &key, &ksize, &stored, &vsize)) { if (stored != NULL) { if (sizeof(entry) < (size_t) vsize) { Log(LOG_LEVEL_ERR, "Invalid entry in measurements database. Expected size: %zu, actual size: %d", sizeof(entry), vsize); continue; } strcpy(eventname, (char *) key); memcpy(&entry, stored, MIN(vsize, sizeof(entry))); Log(LOG_LEVEL_VERBOSE, "Setting measurement event %s", eventname); // a.measure.data_type is not longer known here, so look for zero decimals if ((int) (entry.Q.q * 10) % 10 == 0) { snprintf(assignment, CF_BUFSIZE - 1, "value_%s=%.0lf", eventname, entry.Q.q); } else { snprintf(assignment, CF_BUFSIZE - 1, "value_%s=%.2lf", eventname, entry.Q.q); } AppendItem(classlist, assignment, NULL); snprintf(assignment, CF_BUFSIZE - 1, "av_%s=%.2lf", eventname, entry.Q.expect); AppendItem(classlist, assignment, NULL); snprintf(assignment, CF_BUFSIZE - 1, "dev_%s=%.2lf", eventname, sqrt(entry.Q.var)); AppendItem(classlist, assignment, NULL); } } DeleteDBCursor(dbcp); CloseDB(dbp); } /*****************************************************************************/ /* Clock handling */ /*****************************************************************************/ /* MB: We want to solve the geometric series problem to simulate an unbiased average over a grain size for long history aggregation at zero cost, i.e. we'd ideally like to have w = (1-w)^n for all n The true average is expensive to compute, so forget the brute force approach because this gives a pretty good result. The eqn above has no actual solution but we can approximate numerically to w = 0.01, see this test to show that the distribution is flat: main () { int i,j; double w = 0.01,wp; for (i = 1; i < 20; i++) { printf("("); wp = w; for (j = 1; j < i; j++) { printf("%f,",wp); wp *= (1- w); } printf(")\n"); } } */ /*****************************************************************************/ /* Level */ /*****************************************************************************/ static int NovaGetSlot(const char *name) { int i; Nova_LoadSlots(); /* First try to find existing slot */ for (i = 0; i < CF_OBSERVABLES - ob_spare; ++i) { if (SLOTS[i] && !strcmp(SLOTS[i]->name, name)) { Log(LOG_LEVEL_VERBOSE, "Using slot ob_spare+%d (%d) for %s", i, i + ob_spare, name); return i + ob_spare; } } /* Then find the spare one */ for (i = 0; i < CF_OBSERVABLES - ob_spare; ++i) { if (!SLOTS[i]) { Log(LOG_LEVEL_VERBOSE, "Using empty slot ob_spare+%d (%d) for %s", i, i + ob_spare, name); return i + ob_spare; } } Log(LOG_LEVEL_ERR, "Measurement slots are all in use - it is not helpful to measure too much, you can't usefully follow this many variables"); return -1; } /*****************************************************************************/ int NovaRegisterSlot(const char *name, const char *description, const char *units, double expected_minimum, double expected_maximum, bool consolidable) { int slot = NovaGetSlot(name); if (slot == -1) { return -1; } Nova_FreeSlot(SLOTS[slot - ob_spare]); SLOTS[slot - ob_spare] = Nova_MakeSlot(name, description, units, expected_minimum, expected_maximum, consolidable); Nova_DumpSlots(); return slot; } cfengine-3.24.2/cf-monitord/shared_kstat.h0000644000000000000000000000225115010704253020421 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SHARED_KSTAT_H #define CFENGINE_SHARED_KSTAT_H #include #include /* Shared access to Solaris kstat service */ kstat_ctl_t *GetKstatHandle(void); #endif cfengine-3.24.2/cf-monitord/env_monitor.c0000644000000000000000000010247315010704253020306 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // WritePID #include #include // SetUmask() #include #include #include #include #include /* MonOtherInit,MonOtherGatherData */ #include /* HistoryUpdate */ #include /* GetObservable */ #include /*****************************************************************************/ /* Globals */ /*****************************************************************************/ #define CF_ENVNEW_FILE "env_data.new" #define cf_noise_threshold 6 /* number that does not warrant large anomaly status */ #define MON_THRESHOLD_HIGH 1000000 // samples should stay below this threshold #define LDT_BUFSIZE 10 double FORGETRATE = 0.7; static char ENVFILE_NEW[CF_BUFSIZE] = ""; static char ENVFILE[CF_BUFSIZE] = ""; static double HISTOGRAM[CF_OBSERVABLES][7][CF_GRAINS] = { { { 0.0 } } }; /* persistent observations */ static double CF_THIS[CF_OBSERVABLES] = { 0.0 }; /* Work */ static long ITER = 0; /* Iteration since start */ static double AGE = 0.0, WAGE = 0.0; /* Age and weekly age of database */ static Averages LOCALAV = { 0 }; /* Leap Detection vars */ static double LDT_BUF[CF_OBSERVABLES][LDT_BUFSIZE] = { { 0 } }; static double LDT_SUM[CF_OBSERVABLES] = { 0 }; static double LDT_AVG[CF_OBSERVABLES] = { 0 }; static double CHI_LIMIT[CF_OBSERVABLES] = { 0 }; static double CHI[CF_OBSERVABLES] = { 0 }; static double LDT_MAX[CF_OBSERVABLES] = { 0 }; static int LDT_POS = 0; static int LDT_FULL = false; int NO_FORK = false; /*******************************************************************/ /* Prototypes */ /*******************************************************************/ static void GetDatabaseAge(void); static void LoadHistogram(void); static void GetQ(EvalContext *ctx, const Policy *policy); static Averages EvalAvQ(EvalContext *ctx, char *timekey); static void ArmClasses(EvalContext *ctx, const Averages *newvals); static void GatherPromisedMeasures(EvalContext *ctx, const Policy *policy); static void LeapDetection(void); static Averages *GetCurrentAverages(char *timekey); static void UpdateAverages(EvalContext *ctx, char *timekey, const Averages *newvals); static void UpdateDistributions(EvalContext *ctx, char *timekey, Averages *av); static double WAverage(double new_val, double old_val, double age); static double SetClasses(EvalContext *ctx, char *name, double variable, double av_expect, double av_var, double localav_expect, double localav_var, Item **classlist); static void SetVariable(char *name, double now, double average, double stddev, Item **list); static double RejectAnomaly(double new, double av, double var, double av2, double var2); static void ZeroArrivals(void); static PromiseResult KeepMonitorPromise(EvalContext *ctx, const Promise *pp, void *param); /****************************************************************/ void MonitorInitialize(void) { int i, j, k; char vbuff[CF_BUFSIZE]; const char* const statedir = GetStateDir(); snprintf(vbuff, sizeof(vbuff), "%s/cf_users", statedir); MapName(vbuff); CreateEmptyFile(vbuff); snprintf(ENVFILE_NEW, CF_BUFSIZE, "%s/%s", statedir, CF_ENVNEW_FILE); MapName(ENVFILE_NEW); snprintf(ENVFILE, CF_BUFSIZE, "%s/%s", statedir, CF_ENV_FILE); MapName(ENVFILE); MonEntropyClassesInit(); GetDatabaseAge(); for (i = 0; i < CF_OBSERVABLES; i++) { LOCALAV.Q[i] = QDefinite(0.0); } for (i = 0; i < CF_OBSERVABLES; i++) { for (j = 0; j < 7; j++) { for (k = 0; k < CF_GRAINS; k++) { HISTOGRAM[i][j][k] = 0; } } } for (i = 0; i < CF_OBSERVABLES; i++) { CHI[i] = 0; CHI_LIMIT[i] = 0.1; LDT_AVG[i] = 0; LDT_SUM[i] = 0; } srand((unsigned int) time(NULL)); LoadHistogram(); /* Look for local sensors - this is unfortunately linux-centric */ MonNetworkInit(); MonTempInit(); MonOtherInit(); Log(LOG_LEVEL_DEBUG, "Finished with monitor initialization"); } /*********************************************************************/ /* Level 2 */ /*********************************************************************/ static void GetDatabaseAge() { CF_DB *dbp; if (!OpenDB(&dbp, dbid_observations)) { return; } if (ReadDB(dbp, "DATABASE_AGE", &AGE, sizeof(double))) { WAGE = AGE / SECONDS_PER_WEEK * CF_MEASURE_INTERVAL; Log(LOG_LEVEL_DEBUG, "Previous DATABASE_AGE %f", AGE); } else { Log(LOG_LEVEL_DEBUG, "No previous DATABASE_AGE"); AGE = 0.0; } CloseDB(dbp); } /*********************************************************************/ static void LoadHistogram(void) { int i, day, position; double maxval[CF_OBSERVABLES]; char filename[CF_BUFSIZE]; snprintf(filename, CF_BUFSIZE, "%s%chistograms", GetStateDir(), FILE_SEPARATOR); FILE *fp = safe_fopen(filename, "r"); if (fp == NULL) { Log(LOG_LEVEL_VERBOSE, "Unable to load histogram data from '%s' (fopen: %s)", filename, GetErrorStr()); return; } for (i = 0; i < CF_OBSERVABLES; i++) { maxval[i] = 1.0; } for (position = 0; position < CF_GRAINS; position++) { if (fscanf(fp, "%d ", &position) != 1) { Log(LOG_LEVEL_ERR, "Format error in histogram file '%s' - aborting", filename); break; } for (i = 0; i < CF_OBSERVABLES; i++) { for (day = 0; day < 7; day++) { if (fscanf(fp, "%lf ", &(HISTOGRAM[i][day][position])) != 1) { Log(LOG_LEVEL_VERBOSE, "Format error in histogram file '%s'. (fscanf: %s)", filename, GetErrorStr()); HISTOGRAM[i][day][position] = 0; } if (HISTOGRAM[i][day][position] < 0) { HISTOGRAM[i][day][position] = 0; } if (HISTOGRAM[i][day][position] > maxval[i]) { maxval[i] = HISTOGRAM[i][day][position]; } HISTOGRAM[i][day][position] *= 1000.0 / maxval[i]; } } } fclose(fp); } /*********************************************************************/ void MonitorStartServer(EvalContext *ctx, const Policy *policy) { char timekey[CF_SMALLBUF]; Averages averages; Policy *monitor_cfengine_policy = PolicyNew(); Promise *pp = NULL; { Bundle *bp = PolicyAppendBundle(monitor_cfengine_policy, NamespaceDefault(), "monitor_cfengine_bundle", "agent", NULL, NULL); BundleSection *sp = BundleAppendSection(bp, "monitor_cfengine"); pp = BundleSectionAppendPromise(sp, "the monitor daemon", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL, NULL); } assert(pp); CfLock thislock; #ifdef __MINGW32__ if (!NO_FORK) { Log(LOG_LEVEL_VERBOSE, "Windows does not support starting processes in the background - starting in foreground"); } #else /* !__MINGW32__ */ if ((!NO_FORK) && (fork() != 0)) { Log(LOG_LEVEL_INFO, "cf-monitord: starting"); _exit(EXIT_SUCCESS); } if (!NO_FORK) { ActAsDaemon(); } #endif /* !__MINGW32__ */ thislock = AcquireLock(ctx, pp->promiser, VUQNAME, CFSTARTTIME, 0, 0, pp, false); if (thislock.lock == NULL) { PolicyDestroy(monitor_cfengine_policy); return; } WritePID("cf-monitord.pid"); MonNetworkSnifferOpen(); while (!IsPendingTermination()) { GetQ(ctx, policy); snprintf(timekey, sizeof(timekey), "%s", GenTimeKey(time(NULL))); averages = EvalAvQ(ctx, timekey); LeapDetection(); ArmClasses(ctx, &averages); ZeroArrivals(); MonNetworkSnifferSniff(EvalContextGetIpAddresses(ctx), ITER, CF_THIS); ITER++; } PolicyDestroy(monitor_cfengine_policy); YieldCurrentLock(thislock); } /*********************************************************************/ static void GetQ(EvalContext *ctx, const Policy *policy) { MonEntropyClassesReset(); ZeroArrivals(); MonProcessesGatherData(CF_THIS); MonDiskGatherData(CF_THIS); #ifndef __MINGW32__ MonCPUGatherData(CF_THIS); MonLoadGatherData(CF_THIS); MonNetworkGatherData(CF_THIS); MonNetworkSnifferGatherData(); MonTempGatherData(CF_THIS); #endif /* !__MINGW32__ */ MonOtherGatherData(CF_THIS); GatherPromisedMeasures(ctx, policy); } /*********************************************************************/ static Averages EvalAvQ(EvalContext *ctx, char *t) { Averages *lastweek_vals, newvals; double last5_vals[CF_OBSERVABLES]; char name[CF_MAXVARSIZE]; time_t now = time(NULL); int i; for (i = 0; i < CF_OBSERVABLES; i++) { last5_vals[i] = 0.0; } Banner("Evaluating and storing new weekly averages"); if ((lastweek_vals = GetCurrentAverages(t)) == NULL) { Log(LOG_LEVEL_ERR, "Error reading average database"); DoCleanupAndExit(EXIT_FAILURE); } /* Discard any apparently anomalous behaviour before renormalizing database */ for (i = 0; i < CF_OBSERVABLES; i++) { double delta2; char desc[CF_BUFSIZE]; double This; name[0] = '\0'; GetObservable(i, name, sizeof(name), desc, sizeof(desc)); /* Overflow protection */ if (lastweek_vals->Q[i].expect < 0) { lastweek_vals->Q[i].expect = 0; } if (lastweek_vals->Q[i].q < 0) { lastweek_vals->Q[i].q = 0; } if (lastweek_vals->Q[i].var < 0) { lastweek_vals->Q[i].var = 0; } // lastweek_vals is last week's stored data This = RejectAnomaly(CF_THIS[i], lastweek_vals->Q[i].expect, lastweek_vals->Q[i].var, LOCALAV.Q[i].expect, LOCALAV.Q[i].var); newvals.Q[i].q = This; newvals.last_seen = now; // Record the freshness of this slot LOCALAV.Q[i].q = This; Log(LOG_LEVEL_DEBUG, "Previous week's '%s.q' %lf", name, lastweek_vals->Q[i].q); Log(LOG_LEVEL_DEBUG, "Previous week's '%s.var' %lf", name, lastweek_vals->Q[i].var); Log(LOG_LEVEL_DEBUG, "Previous week's '%s.ex' %lf", name, lastweek_vals->Q[i].expect); Log(LOG_LEVEL_DEBUG, "Just measured: CF_THIS[%s] = %lf", name, CF_THIS[i]); Log(LOG_LEVEL_DEBUG, "Just sanitized: This[%s] = %lf", name, This); newvals.Q[i].expect = WAverage(This, lastweek_vals->Q[i].expect, WAGE); LOCALAV.Q[i].expect = WAverage(newvals.Q[i].expect, LOCALAV.Q[i].expect, ITER); if (last5_vals[i] > 0) { newvals.Q[i].dq = newvals.Q[i].q - last5_vals[i]; LOCALAV.Q[i].dq = newvals.Q[i].q - last5_vals[i]; } else { newvals.Q[i].dq = 0; LOCALAV.Q[i].dq = 0; } // Save the last measured value as the value "from five minutes ago" to get the gradient last5_vals[i] = newvals.Q[i].q; delta2 = (This - lastweek_vals->Q[i].expect) * (This - lastweek_vals->Q[i].expect); if (lastweek_vals->Q[i].var > delta2 * 2.0) { /* Clean up past anomalies */ newvals.Q[i].var = delta2; LOCALAV.Q[i].var = WAverage(newvals.Q[i].var, LOCALAV.Q[i].var, ITER); } else { newvals.Q[i].var = WAverage(delta2, lastweek_vals->Q[i].var, WAGE); LOCALAV.Q[i].var = WAverage(newvals.Q[i].var, LOCALAV.Q[i].var, ITER); } Log(LOG_LEVEL_VERBOSE, "[%d] %s q=%lf, var=%lf, ex=%lf", i, name, newvals.Q[i].q, newvals.Q[i].var, newvals.Q[i].expect); Log(LOG_LEVEL_VERBOSE, "[%d] = %lf -> (%lf#%lf) local [%lf#%lf]", i, This, newvals.Q[i].expect, sqrt(newvals.Q[i].var), LOCALAV.Q[i].expect, sqrt(LOCALAV.Q[i].var)); if (This > 0) { Log(LOG_LEVEL_VERBOSE, "Storing %.2lf in %s", This, name); } } UpdateAverages(ctx, t, &newvals); UpdateDistributions(ctx, t, lastweek_vals); /* Distribution about mean */ return newvals; } /*********************************************************************/ static void LeapDetection(void) { int i, last_pos = LDT_POS; double n1, n2, d; double padding = 0.2; if (++LDT_POS >= LDT_BUFSIZE) { LDT_POS = 0; if (!LDT_FULL) { Log(LOG_LEVEL_DEBUG, "LDT Buffer full at %d", LDT_BUFSIZE); LDT_FULL = true; } } for (i = 0; i < CF_OBSERVABLES; i++) { /* First do some anomaly rejection. Sudden jumps must be numerical errors. */ if ((LDT_BUF[i][last_pos] > 0) && ((CF_THIS[i] / LDT_BUF[i][last_pos]) > 1000)) { CF_THIS[i] = LDT_BUF[i][last_pos]; } /* Note AVG should contain n+1 but not SUM, hence funny increments */ LDT_AVG[i] = LDT_AVG[i] + CF_THIS[i] / ((double) LDT_BUFSIZE + 1.0); d = (double) (LDT_BUFSIZE * (LDT_BUFSIZE + 1)) * LDT_AVG[i]; if (LDT_FULL && (LDT_POS == 0)) { n2 = (LDT_SUM[i] - (double) LDT_BUFSIZE * LDT_MAX[i]); if (d < 0.001) { CHI_LIMIT[i] = 0.5; } else { CHI_LIMIT[i] = padding + sqrt(n2 * n2 / d); } LDT_MAX[i] = 0.0; } if (CF_THIS[i] > LDT_MAX[i]) { LDT_MAX[i] = CF_THIS[i]; } n1 = (LDT_SUM[i] - (double) LDT_BUFSIZE * CF_THIS[i]); if (d < 0.001) { CHI[i] = 0.0; } else { CHI[i] = sqrt(n1 * n1 / d); } LDT_AVG[i] = LDT_AVG[i] - LDT_BUF[i][LDT_POS] / ((double) LDT_BUFSIZE + 1.0); LDT_BUF[i][LDT_POS] = CF_THIS[i]; LDT_SUM[i] = LDT_SUM[i] - LDT_BUF[i][LDT_POS] + CF_THIS[i]; } } /*********************************************************************/ static void PublishEnvironment(Item *classes) { unlink(ENVFILE_NEW); const mode_t old_umask = SetUmask(0077); FILE *fp = safe_fopen(ENVFILE_NEW, "a"); RestoreUmask(old_umask); if (fp == NULL) { return; } for (Item *ip = classes; ip != NULL; ip = ip->next) { fprintf(fp, "%s\n", ip->name); } MonEntropyClassesPublish(fp); fclose(fp); rename(ENVFILE_NEW, ENVFILE); } /*********************************************************************/ static void AddOpenPorts(const char *name, const Item *value, Item **mon_data) { Writer *w = StringWriter(); WriterWriteF(w, "@%s=", name); PrintItemList(value, w); if (StringWriterLength(w) <= 1500) { AppendItem(mon_data, StringWriterData(w), NULL); } WriterClose(w); } static void ArmClasses(EvalContext *ctx, const Averages *const av) { assert(av != NULL); double sigma; Item *ip, *mon_data = NULL; int i, j, k; char buff[CF_BUFSIZE], ldt_buff[CF_BUFSIZE]; char name[CF_MAXVARSIZE - 100]; /* used for names of variables with all sorts of prefixes */ static int anomaly[CF_OBSERVABLES][LDT_BUFSIZE] = { { 0 } }; extern Item *ALL_INCOMING; extern Item *MON_UDP4, *MON_UDP6, *MON_TCP4, *MON_TCP6; for (i = 0; i < CF_OBSERVABLES; i++) { char desc[CF_BUFSIZE]; GetObservable(i, name, sizeof(name), desc, sizeof(desc)); sigma = SetClasses(ctx, name, CF_THIS[i], av->Q[i].expect, av->Q[i].var, LOCALAV.Q[i].expect, LOCALAV.Q[i].var, &mon_data); SetVariable(name, CF_THIS[i], av->Q[i].expect, sigma, &mon_data); /* LDT */ ldt_buff[0] = '\0'; anomaly[i][LDT_POS] = false; if (!LDT_FULL) { anomaly[i][LDT_POS] = false; } if (LDT_FULL && (CHI[i] > CHI_LIMIT[i])) { anomaly[i][LDT_POS] = true; /* Remember the last anomaly value */ Log(LOG_LEVEL_VERBOSE, "LDT(%d) in %s chi = %.2f thresh %.2f ", LDT_POS, name, CHI[i], CHI_LIMIT[i]); /* Last printed element is now */ for (j = LDT_POS + 1, k = 0; k < LDT_BUFSIZE; j++, k++) { if (j == LDT_BUFSIZE) /* Wrap */ { j = 0; } if (anomaly[i][j]) { snprintf(buff, CF_BUFSIZE, " *%.2f*", LDT_BUF[i][j]); } else { snprintf(buff, CF_BUFSIZE, " %.2f", LDT_BUF[i][j]); } strcat(ldt_buff, buff); } if (CF_THIS[i] > av->Q[i].expect) { snprintf(buff, CF_BUFSIZE, "%s_high_ldt", name); } else { snprintf(buff, CF_BUFSIZE, "%s_low_ldt", name); } AppendItem(&mon_data, buff, "2"); EvalContextHeapPersistentSave(ctx, buff, CF_PERSISTENCE, CONTEXT_STATE_POLICY_PRESERVE, ""); EvalContextClassPutSoft(ctx, buff, CONTEXT_SCOPE_NAMESPACE, ""); } else { for (j = LDT_POS + 1, k = 0; k < LDT_BUFSIZE; j++, k++) { if (j == LDT_BUFSIZE) /* Wrap */ { j = 0; } if (anomaly[i][j]) { snprintf(buff, CF_BUFSIZE, " *%.2f*", LDT_BUF[i][j]); } else { snprintf(buff, CF_BUFSIZE, " %.2f", LDT_BUF[i][j]); } strcat(ldt_buff, buff); } } } SetMeasurementPromises(&mon_data); // Report on the open ports, in various ways AddOpenPorts("listening_ports", ALL_INCOMING, &mon_data); AddOpenPorts("listening_udp6_ports", MON_UDP6, &mon_data); AddOpenPorts("listening_udp4_ports", MON_UDP4, &mon_data); AddOpenPorts("listening_tcp6_ports", MON_TCP6, &mon_data); AddOpenPorts("listening_tcp4_ports", MON_TCP4, &mon_data); // Port addresses if (ListLen(MON_TCP6) + ListLen(MON_TCP4) > 512) { Log(LOG_LEVEL_INFO, "Disabling address information of TCP ports in LISTEN state: more than 512 listening ports are detected"); } else { for (ip = MON_TCP6; ip != NULL; ip=ip->next) { snprintf(buff,CF_BUFSIZE,"tcp6_port_addr[%s]=%s",ip->name,ip->classes); AppendItem(&mon_data, buff, NULL); } for (ip = MON_TCP4; ip != NULL; ip=ip->next) { snprintf(buff,CF_BUFSIZE,"tcp4_port_addr[%s]=%s",ip->name,ip->classes); AppendItem(&mon_data, buff, NULL); } } for (ip = MON_UDP6; ip != NULL; ip=ip->next) { snprintf(buff,CF_BUFSIZE,"udp6_port_addr[%s]=%s",ip->name,ip->classes); AppendItem(&mon_data, buff, NULL); } for (ip = MON_UDP4; ip != NULL; ip=ip->next) { snprintf(buff,CF_BUFSIZE,"udp4_port_addr[%s]=%s",ip->name,ip->classes); AppendItem(&mon_data, buff, NULL); } PublishEnvironment(mon_data); DeleteItemList(mon_data); } /*****************************************************************************/ static Averages *GetCurrentAverages(char *timekey) { CF_DB *dbp; static Averages entry; /* No need to initialize */ if (!OpenDB(&dbp, dbid_observations)) { return NULL; } memset(&entry, 0, sizeof(entry)); AGE++; WAGE = AGE / SECONDS_PER_WEEK * CF_MEASURE_INTERVAL; if (ReadDB(dbp, timekey, &entry, sizeof(Averages))) { int i; for (i = 0; i < CF_OBSERVABLES; i++) { Log(LOG_LEVEL_DEBUG, "Previous values (%lf,..) for time index '%s'", entry.Q[i].expect, timekey); } } else { Log(LOG_LEVEL_DEBUG, "No previous value for time index '%s'", timekey); } CloseDB(dbp); return &entry; } /*****************************************************************************/ static void UpdateAverages(EvalContext *ctx, char *timekey, const Averages *const newvals) { assert(newvals != NULL); CF_DB *dbp; if (!OpenDB(&dbp, dbid_observations)) { return; } Log(LOG_LEVEL_INFO, "Updated averages at '%s'", timekey); WriteDB(dbp, timekey, newvals, sizeof(Averages)); WriteDB(dbp, "DATABASE_AGE", &AGE, sizeof(double)); CloseDB(dbp); HistoryUpdate(ctx, newvals); } static int Day2Number(const char *datestring) { int i = 0; for (i = 0; i < 7; i++) { if (strncmp(datestring, DAY_TEXT[i], 3) == 0) { return i; } } return -1; } static void UpdateDistributions(EvalContext *ctx, char *timekey, Averages *av) { int position, day, i; char filename[CF_BUFSIZE]; /* Take an interval of 4 standard deviations from -2 to +2, divided into CF_GRAINS parts. Centre each measurement on CF_GRAINS/2 and scale each measurement by the std-deviation for the current time. */ if (IsDefinedClass(ctx, "Min40_45")) { day = Day2Number(timekey); for (i = 0; i < CF_OBSERVABLES; i++) { position = CF_GRAINS / 2 + (int) (0.5 + (CF_THIS[i] - av->Q[i].expect) * CF_GRAINS / (4 * sqrt((av->Q[i].var)))); if ((0 <= position) && (position < CF_GRAINS)) { HISTOGRAM[i][day][position]++; } } snprintf(filename, CF_BUFSIZE, "%s%chistograms", GetStateDir(), FILE_SEPARATOR); FILE *fp = safe_fopen(filename, "w"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Unable to save histograms to '%s' (fopen: %s)", filename, GetErrorStr()); return; } for (position = 0; position < CF_GRAINS; position++) { fprintf(fp, "%d ", position); for (i = 0; i < CF_OBSERVABLES; i++) { for (day = 0; day < 7; day++) { fprintf(fp, "%.0lf ", HISTOGRAM[i][day][position]); } } fprintf(fp, "\n"); } fclose(fp); } } /*****************************************************************************/ /* This function performs a weighted average of an old and a new measured value. Weights depend on the age of the data. If one or both values are "unreasonably" large (>9999999) they will be ignored. */ /* For a couple of weeks, learn eagerly. Otherwise variances will be way too large. Then downplay newer data somewhat, and rely on experience of a couple of months of data ... */ static double WAverage(double new_val, double old_val, double age) { const double cf_sane_monitor_limit = 9999999.0; double average, weight_new, weight_old; // First do some database corruption self-healing const bool old_bad = (old_val > cf_sane_monitor_limit); const bool new_bad = (new_val > cf_sane_monitor_limit); if (old_bad && new_bad) { return 0.0; } else if (old_bad) { return new_val; } else if (new_bad) { return old_val; } // Now look at the self-learning if ((FORGETRATE > 0.9) || (FORGETRATE < 0.1)) { FORGETRATE = 0.6; } // More aggressive learning for young database if (age < 2.0) { weight_new = FORGETRATE; weight_old = (1.0 - FORGETRATE); } else { weight_new = (1.0 - FORGETRATE); weight_old = FORGETRATE; } if ((old_val == 0) && (new_val == 0)) { return 0.0; } /* * Average = (w1*v1 + w2*v2) / (w1 + w2) * * w1 + w2 always equals to 1, so we omit it for better precision and * performance. */ average = (weight_new * new_val + weight_old * old_val); if (average < 0) { /* Accuracy lost - something wrong */ return 0.0; } return average; } /*****************************************************************************/ static double SetClasses(EvalContext *ctx, char *name, double variable, double av_expect, double av_var, double localav_expect, double localav_var, Item **classlist) { char buffer[CF_BUFSIZE], buffer2[CF_BUFSIZE]; double dev, delta, sigma, ldelta, lsigma, sig; delta = variable - av_expect; sigma = sqrt(av_var); ldelta = variable - localav_expect; lsigma = sqrt(localav_var); sig = sqrt(sigma * sigma + lsigma * lsigma); Log(LOG_LEVEL_DEBUG, "delta = %lf, sigma = %lf, lsigma = %lf, sig = %lf", delta, sigma, lsigma, sig); if ((sigma == 0.0) || (lsigma == 0.0)) { Log(LOG_LEVEL_DEBUG, "No sigma variation .. can't measure class"); snprintf(buffer, CF_MAXVARSIZE, "entropy_%s.*", name); MonEntropyPurgeUnused(buffer); return sig; } Log(LOG_LEVEL_DEBUG, "Setting classes for '%s'...", name); if (fabs(delta) < cf_noise_threshold) /* Arbitrary limits on sensitivity */ { Log(LOG_LEVEL_DEBUG, "Sensitivity too high"); buffer[0] = '\0'; strcpy(buffer, name); if ((delta > 0) && (ldelta > 0)) { strcat(buffer, "_high"); } else if ((delta < 0) && (ldelta < 0)) { strcat(buffer, "_low"); } else { strcat(buffer, "_normal"); } AppendItem(classlist, buffer, "0"); dev = sqrt(delta * delta / (1.0 + sigma * sigma) + ldelta * ldelta / (1.0 + lsigma * lsigma)); if (dev > 2.0 * sqrt(2.0)) { strcpy(buffer2, buffer); strcat(buffer2, "_microanomaly"); AppendItem(classlist, buffer2, "2"); EvalContextHeapPersistentSave(ctx, buffer2, CF_PERSISTENCE, CONTEXT_STATE_POLICY_PRESERVE, ""); EvalContextClassPutSoft(ctx, buffer2, CONTEXT_SCOPE_NAMESPACE, ""); } return sig; /* Granularity makes this silly */ } else { buffer[0] = '\0'; strcpy(buffer, name); if ((delta > 0) && (ldelta > 0)) { strcat(buffer, "_high"); } else if ((delta < 0) && (ldelta < 0)) { strcat(buffer, "_low"); } else { strcat(buffer, "_normal"); } dev = sqrt(delta * delta / (1.0 + sigma * sigma) + ldelta * ldelta / (1.0 + lsigma * lsigma)); if (dev <= sqrt(2.0)) { strcpy(buffer2, buffer); strcat(buffer2, "_normal"); AppendItem(classlist, buffer2, "0"); } else { strcpy(buffer2, buffer); strcat(buffer2, "_dev1"); AppendItem(classlist, buffer2, "0"); } /* Now use persistent classes so that serious anomalies last for about 2 autocorrelation lengths, so that they can be cross correlated and seen by normally scheduled cfagent processes ... */ if (dev > 2.0 * sqrt(2.0)) { strcpy(buffer2, buffer); strcat(buffer2, "_dev2"); AppendItem(classlist, buffer2, "2"); EvalContextHeapPersistentSave(ctx, buffer2, CF_PERSISTENCE, CONTEXT_STATE_POLICY_PRESERVE, ""); EvalContextClassPutSoft(ctx, buffer2, CONTEXT_SCOPE_NAMESPACE, ""); } if (dev > 3.0 * sqrt(2.0)) { strcpy(buffer2, buffer); strcat(buffer2, "_anomaly"); AppendItem(classlist, buffer2, "3"); EvalContextHeapPersistentSave(ctx, buffer2, CF_PERSISTENCE, CONTEXT_STATE_POLICY_PRESERVE, ""); EvalContextClassPutSoft(ctx, buffer2, CONTEXT_SCOPE_NAMESPACE, ""); } return sig; } } /*****************************************************************************/ static void SetVariable(char *name, double value, double average, double stddev, Item **classlist) { char var[CF_BUFSIZE]; snprintf(var, CF_MAXVARSIZE, "value_%s=%.2lf", name, value); AppendItem(classlist, var, ""); snprintf(var, CF_MAXVARSIZE, "av_%s=%.2lf", name, average); AppendItem(classlist, var, ""); snprintf(var, CF_MAXVARSIZE, "dev_%s=%.2lf", name, stddev); AppendItem(classlist, var, ""); } /*****************************************************************************/ static void ZeroArrivals() { memset(CF_THIS, 0, sizeof(CF_THIS)); } /*****************************************************************************/ static double RejectAnomaly(double new, double average, double variance, double localav, double localvar) { double dev = sqrt(variance + localvar); /* Geometrical average dev */ double delta; int bigger; if (average == 0) { return new; } if (new > MON_THRESHOLD_HIGH * 4.0) { return 0.0; } if (new > MON_THRESHOLD_HIGH) { return average; } if ((new - average) * (new - average) < cf_noise_threshold * cf_noise_threshold) { return new; } if (new - average > 0) { bigger = true; } else { bigger = false; } /* This routine puts some inertia into the changes, so that the system doesn't respond to every little change ... IR and UV cutoff */ delta = sqrt((new - average) * (new - average) + (new - localav) * (new - localav)); if (delta > 4.0 * dev) /* IR */ { srand48((unsigned int) time(NULL)); if (drand48() < 0.7) /* 70% chance of using full value - as in learning policy */ { return new; } else { if (bigger) { return average + 2.0 * dev; } else { return average - 2.0 * dev; } } } else { Log(LOG_LEVEL_VERBOSE, "Value accepted"); return new; } } /***************************************************************/ /* Level 5 */ /***************************************************************/ static void GatherPromisedMeasures(EvalContext *ctx, const Policy *policy) { for (size_t i = 0; i < SeqLength(policy->bundles); i++) { const Bundle *bp = SeqAt(policy->bundles, i); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); if ((strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_MONITOR]) == 0) || (strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0)) { for (size_t j = 0; j < SeqLength(bp->sections); j++) { BundleSection *sp = SeqAt(bp->sections, j); EvalContextStackPushBundleSectionFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepMonitorPromise, NULL); } EvalContextStackPopFrame(ctx); } } EvalContextStackPopFrame(ctx); } EvalContextClear(ctx); DetectEnvironment(ctx); } /*********************************************************************/ /* Level */ /*********************************************************************/ static PromiseResult KeepMonitorPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert(param == NULL); if (strcmp("vars", PromiseGetPromiseType(pp)) == 0) { return PROMISE_RESULT_NOOP; } else if (strcmp("classes", PromiseGetPromiseType(pp)) == 0) { return VerifyClassPromise(ctx, pp, NULL); } else if (strcmp("measurements", PromiseGetPromiseType(pp)) == 0) { PromiseResult result = VerifyMeasurementPromise(ctx, CF_THIS, pp); return result; } else if (strcmp("reports", PromiseGetPromiseType(pp)) == 0) { return PROMISE_RESULT_NOOP; } assert(false && "Unknown promise type"); return PROMISE_RESULT_NOOP; } cfengine-3.24.2/cf-monitord/verify_measurements.h0000644000000000000000000000226415010704253022045 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_MEASUREMENTS_H #define CFENGINE_VERIFY_MEASUREMENTS_H #include PromiseResult VerifyMeasurementPromise(EvalContext *ctx, double *measurement, const Promise *pp); #endif cfengine-3.24.2/cf-monitord/mon_cumulative.h0000644000000000000000000000252415010704253020777 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_MON_CUMULATIVE_H #define CFENGINE_MON_CUMULATIVE_H #include unsigned GetInstantUint32Value(const char *name, const char *subname, unsigned value, time_t timestamp); unsigned long long GetInstantUint64Value(const char *name, const char *subname, unsigned long long value, time_t timestamp); #endif cfengine-3.24.2/cf-monitord/mon_network.c0000644000000000000000000006067415010704253020317 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include // SetUmask() #include #include #ifdef __linux__ #include #endif /* Globals */ Item *ALL_INCOMING = NULL; Item *MON_UDP4 = NULL, *MON_UDP6 = NULL, *MON_TCP4 = NULL, *MON_TCP6 = NULL; typedef enum { cfn_udp4 = 0, cfn_udp6, cfn_tcp4, cfn_tcp6, cfn_unknown, } SocketType; /*******************************************************************/ /* Anomaly */ /*******************************************************************/ typedef struct { uint32_t port; char *portnr; char *name; enum observables in; enum observables out; } Sock; static const Sock ECGSOCKS[] = /* extended to map old to new using enum */ { {137, "137", "netbiosns", ob_netbiosns_in, ob_netbiosns_out}, {138, "138", "netbiosdgm", ob_netbiosdgm_in, ob_netbiosdgm_out}, {139, "139", "netbiosssn", ob_netbiosssn_in, ob_netbiosssn_out}, {445, "445", "microsoft_ds", ob_microsoft_ds_in, ob_microsoft_ds_out}, {5308, "5308", "cfengine", ob_cfengine_in, ob_cfengine_out}, {2049, "2049", "nfsd", ob_nfsd_in, ob_nfsd_out}, {25, "25", "smtp", ob_smtp_in, ob_smtp_out}, {80, "80", "www", ob_www_in, ob_www_out}, {8080, "8080", "www-alt", ob_www_alt_in, ob_www_alt_out}, {21, "21", "ftp", ob_ftp_in, ob_ftp_out}, {22, "22", "ssh", ob_ssh_in, ob_ssh_out}, {433, "443", "wwws", ob_wwws_in, ob_wwws_out}, {143, "143", "imap", ob_imap_in, ob_imap_out}, {993, "993", "imaps", ob_imaps_in, ob_imaps_out}, {389, "389", "ldap", ob_ldap_in, ob_ldap_out}, {636, "636", "ldaps", ob_ldaps_in, ob_ldaps_out}, {27017, "27017", "mongo", ob_mongo_in, ob_mongo_out}, {3306, "3306", "mysql", ob_mysql_in, ob_mysql_out}, {5432, "5432", "postgresql", ob_postgresql_in, ob_postgresql_out}, {631, "631", "ipp", ob_ipp_in, ob_ipp_out}, }; #define ATTR (sizeof(ECGSOCKS) / sizeof(ECGSOCKS[0])) static const char *const VNETSTAT[] = { [PLATFORM_CONTEXT_UNKNOWN] = "-", [PLATFORM_CONTEXT_OPENVZ] = "/bin/netstat", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/usr/bin/netstat", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/usr/bin/netstat", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/bin/netstat", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "/bin/netstat", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/usr/bin/netstat", /* solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/usr/bin/netstat", /* solaris */ [PLATFORM_CONTEXT_FREEBSD] = "/usr/bin/netstat", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/usr/bin/netstat", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/usr/ucb/netstat", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "/cygdrive/c/WINNT/System32/netstat", /* CygWin */ [PLATFORM_CONTEXT_SYSTEMV] = "/usr/bin/netstat", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/usr/bin/netstat", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/usr/bin/netstat", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "/usr/sbin/netstat", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/usr/bin/netstat", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/usr/bin/netstat", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "mingw-invalid", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "/usr/bin/netstat", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "/system/xbin/netstat", /* android */ }; /* Implementation */ void MonNetworkInit(void) { DeleteItemList(MON_TCP4); DeleteItemList(MON_TCP6); DeleteItemList(MON_UDP4); DeleteItemList(MON_UDP6); MON_UDP4 = MON_UDP6 = MON_TCP4 = MON_TCP6 = NULL; char vbuff[CF_BUFSIZE]; const char* const statedir = GetStateDir(); const char* const file_stems[] = { "cf_incoming", "cf_outgoing" }; const size_t num_files = sizeof(file_stems) / sizeof(char*); for (size_t i = 0; i < ATTR; i++) { for (size_t j = 0; j < num_files; j++) { snprintf(vbuff, CF_BUFSIZE, "%s/%s.%s", statedir, file_stems[j], ECGSOCKS[i].name); MapName(vbuff); CreateEmptyFile(vbuff); } } } /******************************************************************************/ static void SetNetworkEntropyClasses(const char *service, const char *direction, const Item *list) { const Item *ip; Item *addresses = NULL; double entropy; for (ip = list; ip != NULL; ip = ip->next) { if (strlen(ip->name) > 0) { char local[CF_BUFSIZE]; char remote[CF_BUFSIZE]; char vbuff[CF_BUFSIZE]; char *sp; if (strncmp(ip->name, "tcp", 3) == 0) { sscanf(ip->name, "%*s %*s %*s %s %s", local, remote); /* linux-like */ } else { sscanf(ip->name, "%s %s", local, remote); /* solaris-like */ } strncpy(vbuff, remote, CF_BUFSIZE - 1); vbuff[CF_BUFSIZE-1] = '\0'; for (sp = vbuff + strlen(vbuff) - 1; isdigit((int) *sp) && (sp > vbuff); sp--) { } *sp = '\0'; if (!IsItemIn(addresses, vbuff)) { AppendItem(&addresses, vbuff, ""); } IncrementItemListCounter(addresses, vbuff); } } entropy = MonEntropyCalculate(addresses); MonEntropyClassesSet(service, direction, entropy); DeleteItemList(addresses); } /******************************************************************************/ static void SaveNetworkData(Item * const *in, Item * const *out); static void GetNetworkDataFromNetstat(FILE *fp, double *cf_this, Item **in, Item **out); #ifdef __linux__ static bool GetNetworkDataFromProcNet(double *cf_this, Item **in, Item **out); #endif static inline void ResetNetworkData() { DeleteItemList(ALL_INCOMING); ALL_INCOMING = NULL; DeleteItemList(MON_TCP4); DeleteItemList(MON_TCP6); DeleteItemList(MON_UDP4); DeleteItemList(MON_UDP6); MON_UDP4 = MON_UDP6 = MON_TCP4 = MON_TCP6 = NULL; } void MonNetworkGatherData(double *cf_this) { ResetNetworkData(); Item *in[ATTR] = {0}; Item *out[ATTR] = {0}; #ifdef __linux__ /* On Linux, prefer parsing data from /proc/net with our custom code (more * efficient), but fall back to netstat if proc parsing fails. */ if ((access("/proc/net/tcp", R_OK) != 0) || !GetNetworkDataFromProcNet(cf_this, in, out)) #endif { char comm[PATH_MAX + 4] = {0}; /* path to the binary + " -an" */ strncpy(comm, VNETSTAT[VSYSTEMHARDCLASS], (sizeof(comm) - 1)); if (!FileCanOpen(comm, "r")) { Log(LOG_LEVEL_VERBOSE, "Cannot open '%s', aborting gathering of network data (monitoring)", comm); return; } strncat(comm, " -an", sizeof(comm) - 1); FILE *pp; if ((pp = cf_popen(comm, "r", true)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Opening '%s' failed, aborting gathering of network data (monitoring)", comm); return; } GetNetworkDataFromNetstat(pp, cf_this, in, out); cf_pclose(pp); } /* Now save the state for ShowState() the state is not smaller than the last or at least 40 minutes older. This mirrors the persistence of the maxima classes */ SaveNetworkData(in, out); } #ifdef __linux__ static inline void SaveSocketInfo(const char *local_addr, uint32_t local_port, uint32_t remote_port, SocketState state, SocketType type, const char *socket_info, double *cf_this, Item **in, Item **out) { Log(LOG_LEVEL_DEBUG, "Saving socket info '%s:%d:%d [%d, %d]", local_addr, local_port, remote_port, state, type); if (state == SOCK_STATE_LISTEN) { char port_str[CF_MAX_PORT_LEN]; snprintf(port_str, sizeof(port_str), "%d", local_port); IdempPrependItem(&ALL_INCOMING, port_str, NULL); switch (type) { case cfn_tcp4: IdempPrependItem(&MON_TCP4, port_str, local_addr); break; case cfn_tcp6: IdempPrependItem(&MON_TCP6, port_str, local_addr); break; case cfn_udp4: IdempPrependItem(&MON_UDP4, port_str, local_addr); break; case cfn_udp6: IdempPrependItem(&MON_UDP6, port_str, local_addr); break; default: debug_abort_if_reached(); break; } } for (size_t i = 0; i < ATTR; i++) { if (local_port == ECGSOCKS[i].port) { cf_this[ECGSOCKS[i].in]++; AppendItem(&in[i], socket_info, ""); } if (remote_port == ECGSOCKS[i].port) { cf_this[ECGSOCKS[i].out]++; AppendItem(&out[i], socket_info, ""); } } } static inline bool GetNetworkDataFromProcNetTCP(char local_addr[INET_ADDRSTRLEN], char remote_addr[INET_ADDRSTRLEN], char **buff, size_t *buff_size, Seq *lines, double *cf_this, Item **in, Item **out) { FILE *fp = fopen("/proc/net/tcp", "r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Failed to open /proc/net/tcp for reading"); return false; } /* Read the header */ ssize_t ret = CfReadLine(buff, buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp"); fclose(fp); return false; } /* Read real data */ ret = CfReadLines(buff, buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp"); fclose(fp); return false; } Log(LOG_LEVEL_VERBOSE, "Read %zu lines from /proc/net/tcp", ret); uint32_t l_port, r_port; SocketState state; for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv4SocketInfo(line, local_addr, &l_port, remote_addr, &r_port, &state)) { SaveSocketInfo(local_addr, l_port, r_port, state, cfn_tcp4, line, cf_this, in, out); } } fclose(fp); SeqClear(lines); return true; } static inline bool GetNetworkDataFromProcNetTCP6(char local_addr6[INET6_ADDRSTRLEN], char remote_addr6[INET6_ADDRSTRLEN], char **buff, size_t *buff_size, Seq *lines, double *cf_this, Item **in, Item **out) { FILE *fp = fopen("/proc/net/tcp6", "r"); if (fp == NULL) { /* IPv6 may be completely disabled in kernel so this should be handled gracefully. */ Log(LOG_LEVEL_VERBOSE, "Failed to read data from /proc/net/tcp6"); return true; } ssize_t ret = CfReadLine(buff, buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp6"); fclose(fp); return false; } /* Read real data */ ret = CfReadLines(buff, buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/tcp6"); fclose(fp); return false; } Log(LOG_LEVEL_VERBOSE, "Read %zu lines from /proc/net/tcp6", ret); uint32_t l_port, r_port; SocketState state; for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv6SocketInfo(line, local_addr6, &l_port, remote_addr6, &r_port, &state)) { SaveSocketInfo(local_addr6, l_port, r_port, state, cfn_tcp6, line, cf_this, in, out); } } fclose(fp); SeqClear(lines); return true; } static inline bool GetNetworkDataFromProcNetUDP(char local_addr[INET_ADDRSTRLEN], char remote_addr[INET_ADDRSTRLEN], char **buff, size_t *buff_size, Seq *lines, double *cf_this, Item **in, Item **out) { FILE *fp = fopen("/proc/net/udp", "r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Failed to open /proc/net/udp for reading"); return false; } /* Read the header */ ssize_t ret = CfReadLine(buff, buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp"); fclose(fp); return false; } /* Read real data */ ret = CfReadLines(buff, buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp"); fclose(fp); return false; } Log(LOG_LEVEL_VERBOSE, "Read %zu lines from /proc/net/udp", ret); uint32_t l_port, r_port; SocketState state; for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv4SocketInfo(line, local_addr, &l_port, remote_addr, &r_port, &state)) { SaveSocketInfo(local_addr, l_port, r_port, state, cfn_udp4, line, cf_this, in, out); } } fclose(fp); SeqClear(lines); return true; } static inline bool GetNetworkDataFromProcNetUDP6(char local_addr6[INET6_ADDRSTRLEN], char remote_addr6[INET6_ADDRSTRLEN], char **buff, size_t *buff_size, Seq *lines, double *cf_this, Item **in, Item **out) { FILE *fp = fopen("/proc/net/udp6", "r"); if (fp == NULL) { /* IPv6 may be completely disabled in kernel so this should be handled gracefully. */ Log(LOG_LEVEL_VERBOSE, "Failed to read data from /proc/net/udp6"); return true; } ssize_t ret = CfReadLine(buff, buff_size, fp); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp6"); fclose(fp); return false; } /* Read real data */ ret = CfReadLines(buff, buff_size, fp, lines); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to read data from /proc/net/udp6"); fclose(fp); return false; } Log(LOG_LEVEL_VERBOSE, "Read %zu lines from /proc/net/udp6", ret); uint32_t l_port, r_port; SocketState state; for (size_t i = 0; i < (size_t) ret; i++) { char *line = SeqAt(lines,i); if (ParseIPv6SocketInfo(line, local_addr6, &l_port, remote_addr6, &r_port, &state)) { SaveSocketInfo(local_addr6, l_port, r_port, state, cfn_udp6, line, cf_this, in, out); } } fclose(fp); SeqClear(lines); return true; } static bool GetNetworkDataFromProcNet(double *cf_this, Item **in, Item **out) { bool result = true; Seq *lines = SeqNew(64, free); size_t buff_size = 256; char *buff = xmalloc(buff_size); { char local_addr[INET_ADDRSTRLEN]; char remote_addr[INET_ADDRSTRLEN]; if (!GetNetworkDataFromProcNetTCP(local_addr, remote_addr, &buff, &buff_size, lines, cf_this, in, out)) { SeqDestroy(lines); free(buff); return false; } SeqClear(lines); if (!GetNetworkDataFromProcNetUDP(local_addr, remote_addr, &buff, &buff_size, lines, cf_this, in, out)) { SeqDestroy(lines); free(buff); return false; } SeqClear(lines); } { char local_addr6[INET6_ADDRSTRLEN]; char remote_addr6[INET6_ADDRSTRLEN]; if (!GetNetworkDataFromProcNetTCP6(local_addr6, remote_addr6, &buff, &buff_size, lines, cf_this, in, out)) { Log(LOG_LEVEL_VERBOSE, "Failed to get IPv6 TCP sockets information"); } SeqClear(lines); if (!GetNetworkDataFromProcNetUDP6(local_addr6, remote_addr6, &buff, &buff_size, lines, cf_this, in, out)) { Log(LOG_LEVEL_VERBOSE, "Failed to get IPv6 UDP sockets information"); } } SeqDestroy(lines); free(buff); return result; } #endif /* __linux__ */ static void GetNetworkDataFromNetstat(FILE *fp, double *cf_this, Item **in, Item **out) { enum cf_netstat_type { cfn_new, cfn_old } type = cfn_new; SocketType packet = cfn_tcp4; size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); for (;;) { char local[CF_MAX_IP_LEN + CF_MAX_PORT_LEN] = {0}; char remote[CF_MAX_IP_LEN + CF_MAX_PORT_LEN] = {0}; ssize_t res = CfReadLine(&vbuff, &vbuff_size, fp); if (res == -1) { if (!feof(fp)) { Log(LOG_LEVEL_DEBUG, "Error occured while reading data from 'netstat' " "(CfReadLine/getline returned -1 but no EOF found)"); free(vbuff); return; } else { break; } } if (strstr(vbuff, "UNIX")) { break; } if (!((strstr(vbuff, ":")) || (strstr(vbuff, ".")))) { continue; } /* Different formats here ... ugh.. pick a model */ // If this is old style, we look for chapter headings, e.g. "TCP: IPv4" if ((strncmp(vbuff,"UDP:",4) == 0) && (strstr(vbuff+4,"6"))) { packet = cfn_udp6; type = cfn_old; continue; } else if ((strncmp(vbuff,"TCP:",4) == 0) && (strstr(vbuff+4,"6"))) { packet = cfn_tcp6; type = cfn_old; continue; } else if ((strncmp(vbuff,"UDP:",4) == 0) && (strstr(vbuff+4,"4"))) { packet = cfn_udp4; type = cfn_old; continue; } else if ((strncmp(vbuff,"TCP:",4) == 0) && (strstr(vbuff+4,"4"))) { packet = cfn_tcp4; type = cfn_old; continue; } // Line by line state in modern/linux output if (strncmp(vbuff,"udp6",4) == 0) { packet = cfn_udp6; type = cfn_new; } else if (strncmp(vbuff,"tcp6",4) == 0) { packet = cfn_tcp6; type = cfn_new; } else if (strncmp(vbuff,"udp",3) == 0) { packet = cfn_udp4; type = cfn_new; } else if (strncmp(vbuff,"tcp",3) == 0) { packet = cfn_tcp4; type = cfn_new; } // End extract type switch (type) { case cfn_new: sscanf(vbuff, "%*s %*s %*s %s %s", local, remote); /* linux-like */ break; case cfn_old: sscanf(vbuff, "%s %s", local, remote); break; } if (strlen(local) == 0) { continue; } // Extract the port number from the end of the string char *sp; for (sp = local + strlen(local); (*sp != '.') && (*sp != ':') && (sp > local); sp--) { } *sp = '\0'; // Separate address from port number sp++; char *localport = sp; if (strstr(vbuff, "LISTEN")) { // General bucket IdempPrependItem(&ALL_INCOMING, sp, NULL); // Categories the incoming ports by packet types switch (packet) { case cfn_udp4: IdempPrependItem(&MON_UDP4, sp, local); break; case cfn_udp6: IdempPrependItem(&MON_UDP6, sp, local); break; case cfn_tcp4: IdempPrependItem(&MON_TCP4, localport, local); break; case cfn_tcp6: IdempPrependItem(&MON_TCP6, localport, local); break; default: break; } } // Now look at outgoing for (sp = remote + strlen(remote) - 1; (sp >= remote) && (isdigit((int) *sp)); sp--) { } sp++; char *remoteport = sp; // Now look for the specific vital signs to count frequencies for (size_t i = 0; i < ATTR; i++) { if (strcmp(localport, ECGSOCKS[i].portnr) == 0) { cf_this[ECGSOCKS[i].in]++; AppendItem(&in[i], vbuff, ""); } if (strcmp(remoteport, ECGSOCKS[i].portnr) == 0) { cf_this[ECGSOCKS[i].out]++; AppendItem(&out[i], vbuff, ""); } } } free(vbuff); } static void SaveNetworkData(Item * const *in, Item * const *out) { const char* const statedir = GetStateDir(); char vbuff[CF_BUFSIZE]; for (size_t i = 0; i < ATTR; i++) { struct stat statbuf; time_t now = time(NULL); Log(LOG_LEVEL_DEBUG, "save incoming '%s'", ECGSOCKS[i].name); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_incoming.%s", statedir, FILE_SEPARATOR, ECGSOCKS[i].name); if (stat(vbuff, &statbuf) != -1) { if (ItemListSize(in[i]) < (size_t) statbuf.st_size && now < statbuf.st_mtime + 40 * 60) { Log(LOG_LEVEL_VERBOSE, "New state '%s' is smaller, retaining old for 40 mins longer", ECGSOCKS[i].name); DeleteItemList(in[i]); continue; } } SetNetworkEntropyClasses(CanonifyName(ECGSOCKS[i].name), "in", in[i]); const mode_t old_umask = SetUmask(0077); RawSaveItemList(in[i], vbuff, NewLineMode_Unix); RestoreUmask(old_umask); DeleteItemList(in[i]); Log(LOG_LEVEL_DEBUG, "Saved in netstat data in '%s'", vbuff); } for (size_t i = 0; i < ATTR; i++) { struct stat statbuf; time_t now = time(NULL); Log(LOG_LEVEL_DEBUG, "save outgoing '%s'", ECGSOCKS[i].name); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_outgoing.%s", statedir, FILE_SEPARATOR, ECGSOCKS[i].name); if (stat(vbuff, &statbuf) != -1) { if (ItemListSize(out[i]) < (size_t) statbuf.st_size && now < statbuf.st_mtime + 40 * 60) { Log(LOG_LEVEL_VERBOSE, "New state '%s' is smaller, retaining old for 40 mins longer", ECGSOCKS[i].name); DeleteItemList(out[i]); continue; } } SetNetworkEntropyClasses(CanonifyName(ECGSOCKS[i].name), "out", out[i]); const mode_t old_umask = SetUmask(0077); RawSaveItemList(out[i], vbuff, NewLineMode_Unix); RestoreUmask(old_umask); Log(LOG_LEVEL_DEBUG, "Saved out netstat data in '%s'", vbuff); DeleteItemList(out[i]); } } cfengine-3.24.2/cf-monitord/mon_mem_stub.c0000644000000000000000000000222615010704253020426 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include ProbeGatherData MonMemoryInit(const char **name, const char **error) { *name = ""; *error = "Not avaliable"; return NULL; } cfengine-3.24.2/cf-monitord/probes.c0000644000000000000000000000525015010704253017234 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include /* Structs */ typedef struct { const char *name; ProbeInit init; } Probe; /* Constants */ static const Probe ENTERPRISE_PROBES[] = { {"Input/output", &MonIoInit}, {"Memory", &MonMemoryInit}, }; /* Globals */ static ProbeGatherData ENTERPRISE_PROBES_GATHERERS[sizeof(ENTERPRISE_PROBES) / sizeof(ENTERPRISE_PROBES[0])]; void MonOtherInit() { Log(LOG_LEVEL_VERBOSE, "Starting initialization of static Nova monitoring probes."); for (size_t i = 0; i < sizeof(ENTERPRISE_PROBES) / sizeof(ENTERPRISE_PROBES[0]); ++i) { const Probe *probe = &ENTERPRISE_PROBES[i]; const char *provider; const char *error; if ((ENTERPRISE_PROBES_GATHERERS[i] = (probe->init) (&provider, &error))) { Log(LOG_LEVEL_VERBOSE, " * %s: %s.", probe->name, provider); } else { Log(LOG_LEVEL_VERBOSE, " * %s: Disabled: %s.", probe->name, error); } } Log(LOG_LEVEL_VERBOSE, "Initialization of static Nova monitoring probes is finished."); } /****************************************************************************/ void MonOtherGatherData(double *cf_this) { Log(LOG_LEVEL_VERBOSE, "Gathering data from static Nova monitoring probes."); for (size_t i = 0; i < sizeof(ENTERPRISE_PROBES) / sizeof(ENTERPRISE_PROBES[0]); ++i) { const char *probename = ENTERPRISE_PROBES[i].name; ProbeGatherData gatherer = ENTERPRISE_PROBES_GATHERERS[i]; if (gatherer) { Log(LOG_LEVEL_VERBOSE, " * %s", probename); (*gatherer) (cf_this); } } Log(LOG_LEVEL_VERBOSE, "Gathering data from static Nova monitoring probes is finished."); } cfengine-3.24.2/cf-monitord/env_monitor.h0000644000000000000000000000227015010704253020305 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ENV_MONITOR_H #define CFENGINE_ENV_MONITOR_H #include extern double FORGETRATE; void MonitorInitialize(void); void MonitorStartServer(EvalContext *ctx, const Policy *policy); #endif cfengine-3.24.2/cf-monitord/verify_measurements.c0000644000000000000000000000722415010704253022041 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include /* VerifyMeasurement */ static bool CheckMeasureSanity(Measurement m, const Promise *pp); /*****************************************************************************/ PromiseResult VerifyMeasurementPromise(EvalContext *ctx, double *measurement, const Promise *pp) { PromiseBanner(ctx, pp); Attributes a = GetMeasurementAttributes(ctx, pp); if (!CheckMeasureSanity(a.measure, pp)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "Measurement promise is not valid"); return PROMISE_RESULT_INTERRUPTED; } return VerifyMeasurement(ctx, measurement, &a, pp); } /*****************************************************************************/ static bool CheckMeasureSanity(Measurement m, const Promise *pp) { bool retval = true; if (!IsAbsPath(pp->promiser)) { Log(LOG_LEVEL_ERR, "The promiser '%s' of a measurement was not an absolute path", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); retval = false; } if (m.data_type == CF_DATA_TYPE_NONE) { Log(LOG_LEVEL_ERR, "The promiser '%s' did not specify a data type", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); retval = false; } else { if ((m.history_type) && (strcmp(m.history_type, "weekly") == 0)) { switch (m.data_type) { case CF_DATA_TYPE_COUNTER: case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: break; default: Log(LOG_LEVEL_ERR, "The promiser '%s' cannot have history type weekly as it is not a number", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); retval = false; break; } } } if ((m.select_line_matching) && (m.select_line_number != CF_NOINT)) { Log(LOG_LEVEL_ERR, "The promiser '%s' cannot select both a line by pattern and by number", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); retval = false; } if (!m.extraction_regex) { Log(LOG_LEVEL_VERBOSE, "No extraction regex, so assuming whole line is the value"); } else { if ((!strchr(m.extraction_regex, '(')) && (!strchr(m.extraction_regex, ')'))) { Log(LOG_LEVEL_ERR, "The extraction_regex must contain a single backreference for the extraction"); retval = false; } } return retval; } cfengine-3.24.2/cf-monitord/proc_net_parsing.c0000644000000000000000000001147715010704253021306 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* strchr() */ #include #include #include /* Inspired by https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/misc/ss.c#n2404 */ static bool SplitProcNetLine(const char *line, char **local, char **remote, char **state) { /* Example data: * 2: B400A8C0:9DAE 38420D1F:01BB 01 00000000:00000000 ... (IPv4) * 0: 00000000000000000000000001000000:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 ... (IPv6) */ char *p; if ((p = strchr(line, ':')) == NULL) { return false; } *local = p + 2; if ((p = strchr(*local, ':')) == NULL) { return false; } *remote = p + 6; if ((p = strchr(*remote, ':')) == NULL) { return false; } *state = p + 6; return true; } bool ParseIPv4SocketInfo(const char *line, char local_addr[INET_ADDRSTRLEN], uint32_t *local_port, char remote_addr[INET_ADDRSTRLEN], uint32_t *remote_port, SocketState *state) { char *local, *remote, *state_str; if (!SplitProcNetLine(line, &local, &remote, &state_str)) { return false; } /* else */ struct in_addr l_addr; if (sscanf(local, "%x:%x", &(l_addr.s_addr), local_port) != 2) { Log(LOG_LEVEL_ERR,"Failed to parse local addr:port from line '%s'\n", line); return false; } struct in_addr r_addr; if (sscanf(remote, "%x:%x", &(r_addr.s_addr), remote_port) != 2) { Log(LOG_LEVEL_ERR, "Failed to parse remote addr:port from line '%s'\n", line); return false; } if (sscanf(state_str, "%x", state) != 1) { Log(LOG_LEVEL_ERR, "Failed to parse state from line '%s'\n", line); return false; } if (inet_ntop(AF_INET, &l_addr, local_addr, INET_ADDRSTRLEN) == NULL) { Log(LOG_LEVEL_ERR, "Failed to get ASCII representation of local address"); return false; } if (inet_ntop(AF_INET, &r_addr, remote_addr, INET_ADDRSTRLEN) == NULL) { Log(LOG_LEVEL_ERR, "Failed to get ASCII representation of remote address"); return false; } return true; } bool ParseIPv6SocketInfo(const char *line, char local_addr[INET6_ADDRSTRLEN], uint32_t *local_port, char remote_addr[INET6_ADDRSTRLEN], uint32_t *remote_port, SocketState *state) { char *local, *remote, *state_str; if (!SplitProcNetLine(line, &local, &remote, &state_str)) { return false; } /* else */ struct in6_addr l_addr; uint32_t *addr_data = (uint32_t*) l_addr.s6_addr; if (sscanf(local, "%08x%08x%08x%08x:%x", addr_data, addr_data + 1, addr_data + 2, addr_data + 3, local_port) != 5) { Log(LOG_LEVEL_ERR,"Failed to parse local addr:port from line '%s'\n", line); return false; } struct in6_addr r_addr; addr_data = (uint32_t*) r_addr.s6_addr; if (sscanf(remote, "%08x%08x%08x%08x:%x", addr_data, addr_data + 1, addr_data + 2, addr_data + 3, remote_port) != 5) { Log(LOG_LEVEL_ERR, "Failed to parse remote addr:port from line '%s'\n", line); return false; } if (sscanf(state_str, "%x", state) != 1) { Log(LOG_LEVEL_ERR, "Failed to parse state from line '%s'\n", line); return false; } if (inet_ntop(AF_INET6, &l_addr, local_addr, INET6_ADDRSTRLEN) == NULL) { Log(LOG_LEVEL_ERR, "Failed to get ASCII representation of local address"); return false; } if (inet_ntop(AF_INET6, &r_addr, remote_addr, INET6_ADDRSTRLEN) == NULL) { Log(LOG_LEVEL_ERR, "Failed to get ASCII representation of remote address"); return false; } return true; } cfengine-3.24.2/python/0000755000000000000000000000000015010704323014672 5ustar00rootroot00000000000000cfengine-3.24.2/python/Makefile.am0000644000000000000000000000227715010704253016740 0ustar00rootroot00000000000000# # Copyright 2024 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # pythonbindingsdir = $(libdir)/python dist_pythonbindings_DATA = README if !NDEBUG if LINUX # The dbm_test_api is only compile in on Linux in debug builds. dist_pythonbindings_DATA += test_cfe_db.py endif endif cfengine-3.24.2/python/Makefile.in0000644000000000000000000004663715010704301016753 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2024 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ # The dbm_test_api is only compile in on Linux in debug builds. @LINUX_TRUE@@NDEBUG_FALSE@am__append_1 = test_cfe_db.py subdir = python ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am \ $(am__dist_pythonbindings_DATA_DIST) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__dist_pythonbindings_DATA_DIST = README test_cfe_db.py am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pythonbindingsdir)" DATA = $(dist_pythonbindings_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ pythonbindingsdir = $(libdir)/python dist_pythonbindings_DATA = README $(am__append_1) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu python/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu python/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_pythonbindingsDATA: $(dist_pythonbindings_DATA) @$(NORMAL_INSTALL) @list='$(dist_pythonbindings_DATA)'; test -n "$(pythonbindingsdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pythonbindingsdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pythonbindingsdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pythonbindingsdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pythonbindingsdir)" || exit $$?; \ done uninstall-dist_pythonbindingsDATA: @$(NORMAL_UNINSTALL) @list='$(dist_pythonbindings_DATA)'; test -n "$(pythonbindingsdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pythonbindingsdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(pythonbindingsdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_pythonbindingsDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_pythonbindingsDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_pythonbindingsDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-dist_pythonbindingsDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/python/README0000644000000000000000000000066615010704253015564 0ustar00rootroot00000000000000This directory contains Python packages and modules for working with CFEngine and its libraries. If you want to use one of these, PYTHONPATH and LD_LIBRARY_PATH variables can make things easier when used like this: PYTHONPATH=/var/cfengine/lib/python LD_LIBRARY_PATH=/var/cfengine/lib python3 That will make sure that the bindings are found by Python and that CFEngine's libraries are found by dlopen() (used by ctypes.CDLL() etc.). cfengine-3.24.2/python/test_cfe_db.py0000644000000000000000000000511415010704253017510 0ustar00rootroot00000000000000import ctypes # Based on the dbid enum from libpromises/dbm_api.h dbs = ( "classes", # Deprecated "variables", # Deprecated "performance", "checksums", # Deprecated "filestats", # Deprecated "changes", "observations", "state", "lastseen", "audit", "locks", "history", "measure", "static", "scalars", "windows_registry", "cache", "license", "value", "agent_execution", "bundles", # Deprecated "packages_installed", # new package promise installed packages list "packages_updates", # new package promise list of available updates "cookies", # Enterprise reporting cookies for duplicate host detection ) def get_db_id(db_name): return dbs.index(db_name) class _SimulationStruct(ctypes.Structure): pass class _FilamentStruct(ctypes.Structure): pass _promises = ctypes.CDLL("libpromises.so.3.0.6") _promises.SimulateDBLoad.restype = ctypes.POINTER(_SimulationStruct) _promises.SimulateDBLoad.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_long, ctypes.c_long, ctypes.c_int, ctypes.c_int, ctypes.c_long, ctypes.c_long, ctypes.c_long, ctypes.c_long] def SimulateDBLoad(db_id, read_keys_refresh_s=5, read_min_interval_ms=100, read_max_interval_ms=200, write_sample_size_pct=50, write_prune_interval_s=10, write_min_interval_ms=200, write_max_interval_ms=400, iter_min_interval_ms=1000, iter_max_interval_ms=2000): return _promises.SimulateDBLoad(db_id, read_keys_refresh_s, read_min_interval_ms, read_max_interval_ms, write_sample_size_pct, write_prune_interval_s, write_min_interval_ms, write_max_interval_ms, iter_min_interval_ms, iter_max_interval_ms) _promises.StopSimulation.restype = None # void _promises.StopSimulation.argtypes = [ctypes.POINTER(_SimulationStruct)] def StopSimulation(simulation): _promises.StopSimulation(simulation) _promises.FillUpDB.restype = ctypes.POINTER(_FilamentStruct) _promises.FillUpDB.argtypes = [ctypes.c_int, ctypes.c_int] def FillUpDB(db_id, usage): return _promises.FillUpDB(db_id, usage) _promises.RemoveFilament.restype = None # void _promises.RemoveFilament.argtypes = [ctypes.POINTER(_FilamentStruct)] def RemoveFilament(filament): _promises.RemoveFilament(filament) cfengine-3.24.2/libcfecompat/0000755000000000000000000000000015010704322016000 5ustar00rootroot00000000000000cfengine-3.24.2/libcfecompat/Makefile.am0000644000000000000000000000265215010704253020044 0ustar00rootroot00000000000000# # Copyright 2024 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcfecompat.la AM_CPPFLAGS = -I$(top_srcdir)/libntech/libutils # platform.h libcfecompat_la_LIBADD = $(LTLIBOBJS) libcfecompat_la_SOURCES = \ unused.c EXTRA_DIST = \ cfecompat.h \ compat_getopt.h if NO_SYSTEM_GETOPT_H BUILT_SOURCES = getopt.h getopt.h: cp $(srcdir)/compat_getopt.h $(srcdir)/getopt.h libcfecompat_la_SOURCES += \ getopt.c \ getopt1.c nodist_libcfecompat_la_SOURCES = getopt.h endif cfengine-3.24.2/libcfecompat/getopt.c0000644000000000000000000005053315010704253017457 0ustar00rootroot00000000000000/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #endif /* GNU C library. */ char *getenv(const char *name); /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #include #define my_index strchr /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange ( char **argv ) { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ static const char * _getopt_initialize ( const char *optstring ) { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind = 1; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal ( int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only ) { optarg = NULL; if (optind == 0) optstring = _getopt_initialize (optstring); if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0')) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if (nameend - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); else fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt ( int argc, char *const *argv, const char *optstring ) { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit(EXIT_SUCCESS); } #endif /* TEST */ cfengine-3.24.2/libcfecompat/unused.c0000644000000000000000000000217515010704253017457 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* We need at least something to always be part of libcfecompat and this * functions is just good enough for it. */ void __unused_cfecompat_function() {}; cfengine-3.24.2/libcfecompat/cfecompat.h0000644000000000000000000000210615010704253020114 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #if !HAVE_DECL_GETLOADAVG int getloadavg (double loadavg[], int nelem); #endif cfengine-3.24.2/libcfecompat/getopt1.c0000644000000000000000000001034315010704253017533 0ustar00rootroot00000000000000/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #else char *getenv (); #endif #ifndef NULL #define NULL 0 #endif int getopt_long ( int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index ) { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only ( int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index ) { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == EOF) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit(EXIT_SUCCESS); } #endif /* TEST */ cfengine-3.24.2/libcfecompat/Makefile.in0000644000000000000000000005657215010704300020060 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2024 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @NO_SYSTEM_GETOPT_H_TRUE@am__append_1 = \ @NO_SYSTEM_GETOPT_H_TRUE@ getopt.c \ @NO_SYSTEM_GETOPT_H_TRUE@ getopt1.c subdir = libcfecompat ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcfecompat_la_DEPENDENCIES = $(LTLIBOBJS) am__libcfecompat_la_SOURCES_DIST = unused.c getopt.c getopt1.c @NO_SYSTEM_GETOPT_H_TRUE@am__objects_1 = getopt.lo getopt1.lo am_libcfecompat_la_OBJECTS = unused.lo $(am__objects_1) nodist_libcfecompat_la_OBJECTS = libcfecompat_la_OBJECTS = $(am_libcfecompat_la_OBJECTS) \ $(nodist_libcfecompat_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcfecompat_la_SOURCES) $(nodist_libcfecompat_la_SOURCES) DIST_SOURCES = $(am__libcfecompat_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ getloadavg.c DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ noinst_LTLIBRARIES = libcfecompat.la AM_CPPFLAGS = -I$(top_srcdir)/libntech/libutils # platform.h libcfecompat_la_LIBADD = $(LTLIBOBJS) libcfecompat_la_SOURCES = unused.c $(am__append_1) EXTRA_DIST = \ cfecompat.h \ compat_getopt.h @NO_SYSTEM_GETOPT_H_TRUE@BUILT_SOURCES = getopt.h @NO_SYSTEM_GETOPT_H_TRUE@nodist_libcfecompat_la_SOURCES = getopt.h all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libcfecompat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libcfecompat/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcfecompat.la: $(libcfecompat_la_OBJECTS) $(libcfecompat_la_DEPENDENCIES) $(EXTRA_libcfecompat_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcfecompat_la_OBJECTS) $(libcfecompat_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getloadavg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unused.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile @NO_SYSTEM_GETOPT_H_TRUE@getopt.h: @NO_SYSTEM_GETOPT_H_TRUE@ cp $(srcdir)/compat_getopt.h $(srcdir)/getopt.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libcfecompat/getloadavg.c0000644000000000000000000006245115010704253020274 0ustar00rootroot00000000000000/* Get the system load averages. Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994, 1995, 1997 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Compile-time symbols that this file uses: HAVE_PSTAT_GETDYNAMIC Define this if your system has the pstat_getdynamic function. I think it is unique to HPUX9. The best way to get the definition is through the AC_FUNC_GETLOADAVG macro that comes with autoconf 2.13 or newer. If that isn't an option, then just put AC_CHECK_FUNCS(pstat_getdynamic) in your configure.in file. FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. KERNEL_FILE Pathname of the kernel to nlist. LDAV_CVT() Scale the load average from the kernel. Returns a double. LDAV_SYMBOL Name of kernel symbol giving load average. LOAD_AVE_TYPE Type of the load average array in the kernel. Must be defined unless one of apollo, DGUX, NeXT, or UMAX is defined; or we have libkstat; otherwise, no load average is available. NLIST_STRUCT Include nlist.h, not a.out.h, and the nlist n_name element is a pointer, not an array. NLIST_NAME_UNION struct nlist has an n_un member, not n_name. LINUX_LDAV_FILE [__linux__]: File containing load averages. Specific system predefines this file uses, aside from setting default values if not emacs: apollo BSD Real BSD, not just BSD-like. convex DGUX eunice UNIX emulator under VMS. hpux __MSDOS__ No-op for MSDOS. NeXT sgi sequent Sequent Dynix 3.x.x (BSD) _SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV) sony_news NEWS-OS (works at least for 4.1C) UMAX UMAX4_3 VMS WINDOWS32 No-op for Windows95/NT. __linux__ Linux: assumes /proc filesystem mounted. Support from Michael K. Johnson. __NetBSD__ NetBSD: assumes /kern filesystem mounted. In addition, to avoid nesting many #ifdefs, we internally set LDAV_DONE to indicate that the load average has been computed. We also #define LDAV_PRIVILEGED if a program will require special installation to be able to call getloadavg. */ /* This should always be first. */ # include #ifdef HAVE_NLIST_H /* What autoconf defines. */ # undef NLIST_STRUCT # define NLIST_STRUCT #endif #include /* Both the Emacs and non-Emacs sections want this. Some configuration files' definitions for the LOAD_AVE_CVT macro (like sparc.h's) use macros like FSCALE, defined here. */ #if defined (unix) || defined (__unix) # include #endif /* Exclude all the code except the test program at the end if the system has its own `getloadavg' function. The declaration of `errno' is needed by the test program as well as the function itself, so it comes first. */ #include #ifndef errno extern int errno; #endif #ifndef HAVE_GETLOADAVG /* The existing Emacs configuration files define a macro called LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and returns the load average multiplied by 100. What we actually want is a macro called LDAV_CVT, which returns the load average as an unmultiplied double. For backwards compatibility, we'll define LDAV_CVT in terms of LOAD_AVE_CVT, but future machine config files should just define LDAV_CVT directly. */ # if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT) # define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) # endif # if !defined (BSD) && defined (ultrix) /* Ultrix behaves like BSD on Vaxen. */ # define BSD # endif # ifdef NeXT /* NeXT in the 2.{0,1,2} releases defines BSD in , which conflicts with the definition understood in this file, that this really is BSD. */ # undef BSD /* NeXT defines FSCALE in . However, we take FSCALE being defined to mean that the nlist method should be used, which is not true. */ # undef FSCALE # endif /* Same issues as for NeXT apply to the HURD-based GNU system. */ # ifdef __GNU__ # undef BSD # undef FSCALE # endif /* __GNU__ */ /* Set values that are different from the defaults, which are set a little farther down with #ifndef. */ /* Some shorthands. */ # if defined (HPUX) && !defined (hpux) # define hpux # endif # if defined (__hpux) && !defined (hpux) # define hpux # endif # if defined (__sun) && !defined (sun) # define sun # endif # if defined(hp300) && !defined(hpux) # define MORE_BSD # endif # if defined(ultrix) && defined(mips) # define decstation # endif # if defined (__SVR4) && !defined (SVR4) # define SVR4 # endif # if (defined(sun) && defined(SVR4)) || defined (SOLARIS2) # define SUNOS_5 # endif # if defined (__osf__) && (defined (__alpha) || defined (__alpha__)) # define OSF_ALPHA # include # include # include # include # endif # if defined (__osf__) && (defined (mips) || defined (__mips__)) # define OSF_MIPS # include # endif /* UTek's /bin/cc on the 4300 has no architecture specific cpp define by default, but _MACH_IND_SYS_TYPES is defined in . Combine that with a couple of other things and we'll have a unique match. */ # if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES) # define tek4300 /* Define by emacs, but not by other users. */ # endif /* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ # ifndef LOAD_AVE_TYPE # ifdef MORE_BSD # define LOAD_AVE_TYPE long # endif # ifdef sun # define LOAD_AVE_TYPE long # endif # ifdef decstation # define LOAD_AVE_TYPE long # endif # ifdef _SEQUENT_ # define LOAD_AVE_TYPE long # endif # ifdef sgi # define LOAD_AVE_TYPE long # endif # ifdef SVR4 # define LOAD_AVE_TYPE long # endif # ifdef sony_news # define LOAD_AVE_TYPE long # endif # ifdef sequent # define LOAD_AVE_TYPE long # endif # ifdef OSF_ALPHA # define LOAD_AVE_TYPE long # endif # if defined (ardent) && defined (titan) # define LOAD_AVE_TYPE long # endif # ifdef tek4300 # define LOAD_AVE_TYPE long # endif # if defined(alliant) && defined(i860) /* Alliant FX/2800 */ # define LOAD_AVE_TYPE long # endif # ifdef _AIX # define LOAD_AVE_TYPE long # endif # ifdef convex # define LOAD_AVE_TYPE double # ifndef LDAV_CVT # define LDAV_CVT(n) (n) # endif # endif # endif /* No LOAD_AVE_TYPE. */ # ifdef OSF_ALPHA /* defines an incorrect value for FSCALE on Alpha OSF/1, according to ghazi@noc.rutgers.edu. */ # undef FSCALE # define FSCALE 1024.0 # endif # if defined(alliant) && defined(i860) /* Alliant FX/2800 */ /* defines an incorrect value for FSCALE on an Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */ # undef FSCALE # define FSCALE 100.0 # endif # ifndef FSCALE /* SunOS and some others define FSCALE in sys/param.h. */ # ifdef MORE_BSD # define FSCALE 2048.0 # endif # if defined(MIPS) || defined(SVR4) || defined(decstation) # define FSCALE 256 # endif # if defined (sgi) || defined (sequent) /* Sometimes both MIPS and sgi are defined, so FSCALE was just defined above under #ifdef MIPS. But we want the sgi value. */ # undef FSCALE # define FSCALE 1000.0 # endif # if defined (ardent) && defined (titan) # define FSCALE 65536.0 # endif # ifdef tek4300 # define FSCALE 100.0 # endif # ifdef _AIX # define FSCALE 65536.0 # endif # endif /* Not FSCALE. */ # if !defined (LDAV_CVT) && defined (FSCALE) # define LDAV_CVT(n) (((double) (n)) / FSCALE) # endif # if defined(sgi) || (defined(mips) && !defined(BSD)) # define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31)) # endif # if !defined (KERNEL_FILE) && defined (sequent) # define KERNEL_FILE "/dynix" # endif # if !defined (KERNEL_FILE) && defined (hpux) # define KERNEL_FILE "/hp-ux" # endif # if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || (defined (ardent) && defined (titan))) # define KERNEL_FILE "/unix" # endif # if !defined (LDAV_SYMBOL) && defined (alliant) # define LDAV_SYMBOL "_Loadavg" # endif # if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX)) # define LDAV_SYMBOL "avenrun" # endif # ifdef HAVE_UNISTD_H # include # endif # include /* LOAD_AVE_TYPE should only get defined if we're going to use the nlist method. */ # if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) # define LOAD_AVE_TYPE double # endif # ifdef LOAD_AVE_TYPE # ifndef VMS # ifndef __linux__ # ifndef NLIST_STRUCT # include # else /* NLIST_STRUCT */ # include # endif /* NLIST_STRUCT */ # ifdef SUNOS_5 # include //# include # include # endif # if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) # include # endif # ifndef KERNEL_FILE # define KERNEL_FILE "/vmunix" # endif /* KERNEL_FILE */ # ifndef LDAV_SYMBOL # define LDAV_SYMBOL "_avenrun" # endif /* LDAV_SYMBOL */ # endif /* __linux__ */ # else /* VMS */ # ifndef eunice # include # include # else /* eunice */ # include # endif /* eunice */ # endif /* VMS */ # ifndef LDAV_CVT # define LDAV_CVT(n) ((double) (n)) # endif /* !LDAV_CVT */ # endif /* LOAD_AVE_TYPE */ # if defined(__GNU__) && !defined (NeXT) /* Note that NeXT Openstep defines __GNU__ even though it should not. */ /* GNU system acts much like NeXT, for load average purposes, but not exactly. */ # define NeXT # define host_self mach_host_self # endif # ifdef NeXT # ifdef HAVE_MACH_MACH_H # include # else # include # endif # endif /* NeXT */ # ifdef sgi # include # endif /* sgi */ # ifdef UMAX # include # include # include # include # include # ifdef UMAX_43 # include # include # include # include # include # else /* Not UMAX_43. */ # include # include # include # include # include # include # endif /* Not UMAX_43. */ # endif /* UMAX */ # ifdef DGUX # include # endif # if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION) # include # else # include # endif /* Avoid static vars inside a function since in HPUX they dump as pure. */ # ifdef NeXT static processor_set_t default_set; static int getloadavg_initialized; # endif /* NeXT */ # ifdef UMAX static unsigned int cpus = 0; static unsigned int samples; # endif /* UMAX */ # ifdef DGUX static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ # endif /* DGUX */ #if !defined(HAVE_LIBKSTAT) && defined(LOAD_AVE_TYPE) /* File descriptor open to /dev/kmem or VMS load ave driver. */ static int channel; /* Nonzero iff channel is valid. */ static int getloadavg_initialized; /* Offset in kmem to seek to read load average, or 0 means invalid. */ static long offset; #if !defined(VMS) && !defined(sgi) && !defined(__linux__) static struct nlist nl[2]; #endif /* Not VMS or sgi */ #ifdef SUNOS_5 static kvm_t *kd; #endif /* SUNOS_5 */ #endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */ /* Put the 1 minute, 5 minute and 15 minute load averages into the first NELEM elements of LOADAVG. Return the number written (never more than 3, but may be less than NELEM), or -1 if an error occurred. */ int getloadavg (double loadavg[], int nelem); int getloadavg (loadavg, nelem) double loadavg[]; int nelem; { int elem = 0; /* Return value. */ # ifdef NO_GET_LOAD_AVG # define LDAV_DONE /* Set errno to zero to indicate that there was no particular error; this function just can't work at all on this system. */ errno = 0; elem = -1; # endif # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Use libkstat because we don't have to be root. */ # define LDAV_DONE kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; kc = kstat_open (); if (kc == 0) return -1; ksp = kstat_lookup (kc, "unix", 0, "system_misc"); if (ksp == 0 ) return -1; if (kstat_read (kc, ksp, 0) == -1) return -1; kn = kstat_data_lookup (ksp, "avenrun_1min"); if (kn == 0) { /* Return -1 if no load average information is available. */ nelem = 0; elem = -1; } if (nelem >= 1) loadavg[elem++] = (double) kn->value.ul/FSCALE; if (nelem >= 2) { kn = kstat_data_lookup (ksp, "avenrun_5min"); if (kn != 0) { loadavg[elem++] = (double) kn->value.ul/FSCALE; if (nelem >= 3) { kn = kstat_data_lookup (ksp, "avenrun_15min"); if (kn != 0) loadavg[elem++] = (double) kn->value.ul/FSCALE; } } } kstat_close (kc); # endif /* HAVE_LIBKSTAT */ # if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) /* Use pstat_getdynamic() because we don't have to be root. */ # define LDAV_DONE # undef LOAD_AVE_TYPE struct pst_dynamic dyn_info; if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0) return -1; if (nelem > 0) loadavg[elem++] = dyn_info.psd_avg_1_min; if (nelem > 1) loadavg[elem++] = dyn_info.psd_avg_5_min; if (nelem > 2) loadavg[elem++] = dyn_info.psd_avg_15_min; # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ # if !defined (LDAV_DONE) && defined (__linux__) # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef LINUX_LDAV_FILE # define LINUX_LDAV_FILE "/proc/loadavg" # endif char ldavgbuf[40]; double load_ave[3]; int fd, count; fd = open (LINUX_LDAV_FILE, O_RDONLY); if (fd == -1) return -1; count = read (fd, ldavgbuf, 40); (void) close (fd); if (count <= 0) return -1; count = sscanf (ldavgbuf, "%lf %lf %lf", &load_ave[0], &load_ave[1], &load_ave[2]); if (count < 1) return -1; for (elem = 0; elem < nelem && elem < count; elem++) loadavg[elem] = load_ave[elem]; return elem; # endif /* __linux__ */ # if !defined (LDAV_DONE) && defined (__NetBSD__) # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef NETBSD_LDAV_FILE # define NETBSD_LDAV_FILE "/kern/loadavg" # endif unsigned long int load_ave[3], scale; int count; FILE *fp; fp = fopen (NETBSD_LDAV_FILE, "r"); if (fp == NULL) return -1; count = fscanf (fp, "%lu %lu %lu %lu\n", &load_ave[0], &load_ave[1], &load_ave[2], &scale); (void) fclose (fp); if (count != 4) return -1; for (elem = 0; elem < nelem; elem++) loadavg[elem] = (double) load_ave[elem] / (double) scale; return elem; # endif /* __NetBSD__ */ # if !defined (LDAV_DONE) && defined (NeXT) # define LDAV_DONE /* The NeXT code was adapted from iscreen 3.2. */ host_t host; struct processor_set_basic_info info; unsigned info_count; /* We only know how to get the 1-minute average for this system, so even if the caller asks for more than 1, we only return 1. */ if (!getloadavg_initialized) { if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) getloadavg_initialized = 1; } if (getloadavg_initialized) { info_count = PROCESSOR_SET_BASIC_INFO_COUNT; if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, (processor_set_info_t) &info, &info_count) != KERN_SUCCESS) getloadavg_initialized = 0; else { if (nelem > 0) loadavg[elem++] = (double) info.load_average / LOAD_SCALE; } } if (!getloadavg_initialized) return -1; # endif /* NeXT */ # if !defined (LDAV_DONE) && defined (UMAX) # define LDAV_DONE /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not have a /dev/kmem. Information about the workings of the running kernel can be gathered with inq_stats system calls. We only know how to get the 1-minute average for this system. */ struct proc_summary proc_sum_data; struct stat_descr proc_info; double load; register unsigned int i, j; if (cpus == 0) { register unsigned int c, i; struct cpu_config conf; struct stat_descr desc; desc.sd_next = 0; desc.sd_subsys = SUBSYS_CPU; desc.sd_type = CPUTYPE_CONFIG; desc.sd_addr = (char *) &conf; desc.sd_size = sizeof conf; if (inq_stats (1, &desc)) return -1; c = 0; for (i = 0; i < conf.config_maxclass; ++i) { struct class_stats stats; memset(&stats, 0, sizeof stats); desc.sd_type = CPUTYPE_CLASS; desc.sd_objid = i; desc.sd_addr = (char *) &stats; desc.sd_size = sizeof stats; if (inq_stats (1, &desc)) return -1; c += stats.class_numcpus; } cpus = c; samples = cpus < 2 ? 3 : (2 * cpus / 3); } proc_info.sd_next = 0; proc_info.sd_subsys = SUBSYS_PROC; proc_info.sd_type = PROCTYPE_SUMMARY; proc_info.sd_addr = (char *) &proc_sum_data; proc_info.sd_size = sizeof (struct proc_summary); proc_info.sd_sizeused = 0; if (inq_stats (1, &proc_info) != 0) return -1; load = proc_sum_data.ps_nrunnable; j = 0; for (i = samples - 1; i > 0; --i) { load += proc_sum_data.ps_nrun[j]; if (j++ == PS_NRUNSIZE) j = 0; } if (nelem > 0) loadavg[elem++] = load / samples / cpus; # endif /* UMAX */ # if !defined (LDAV_DONE) && defined (DGUX) # define LDAV_DONE /* This call can return -1 for an error, but with good args it's not supposed to fail. The first argument is for no apparent reason of type `long int *'. */ dg_sys_info ((long int *) &load_info, DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); if (nelem > 0) loadavg[elem++] = load_info.one_minute; if (nelem > 1) loadavg[elem++] = load_info.five_minute; if (nelem > 2) loadavg[elem++] = load_info.fifteen_minute; # endif /* DGUX */ # if !defined (LDAV_DONE) && defined (apollo) # define LDAV_DONE /* Apollo code from lisch@mentorg.com (Ray Lischner). This system call is not documented. The load average is obtained as three long integers, for the load average over the past minute, five minutes, and fifteen minutes. Each value is a scaled integer, with 16 bits of integer part and 16 bits of fraction part. I'm not sure which operating system first supported this system call, but I know that SR10.2 supports it. */ extern void proc1_$get_loadav (); unsigned long load_ave[3]; proc1_$get_loadav (load_ave); if (nelem > 0) loadavg[elem++] = load_ave[0] / 65536.0; if (nelem > 1) loadavg[elem++] = load_ave[1] / 65536.0; if (nelem > 2) loadavg[elem++] = load_ave[2] / 65536.0; # endif /* apollo */ # if !defined (LDAV_DONE) && defined (OSF_MIPS) # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); loadavg[elem++] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[0] : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale)); # endif /* OSF_MIPS */ # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) # define LDAV_DONE /* A faithful emulation is going to have to be saved for a rainy day. */ for ( ; elem < nelem; elem++) { loadavg[elem] = 0.0; } # endif /* __MSDOS__ || WINDOWS32 */ # if !defined (LDAV_DONE) && defined (OSF_ALPHA) # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); for (elem = 0; elem < nelem; elem++) loadavg[elem] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[elem] : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); # endif /* OSF_ALPHA */ # if !defined (LDAV_DONE) && defined (VMS) /* VMS specific code -- read from the Load Ave driver. */ LOAD_AVE_TYPE load_ave[3]; static int getloadavg_initialized = 0; # ifdef eunice struct { int dsc$w_length; char *dsc$a_pointer; } descriptor; # endif /* Ensure that there is a channel open to the load ave device. */ if (!getloadavg_initialized) { /* Attempt to open the channel. */ # ifdef eunice descriptor.dsc$w_length = 18; descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE"; # else $DESCRIPTOR (descriptor, "LAV0:"); # endif if (sys$assign (&descriptor, &channel, 0, 0) & 1) getloadavg_initialized = 1; } /* Read the load average vector. */ if (getloadavg_initialized && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0, load_ave, 12, 0, 0, 0, 0) & 1)) { sys$dassgn (channel); getloadavg_initialized = 0; } if (!getloadavg_initialized) return -1; # endif /* VMS */ # if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) /* UNIX-specific code -- read the average from /dev/kmem. */ # define LDAV_PRIVILEGED /* This code requires special installation. */ LOAD_AVE_TYPE load_ave[3]; /* Get the address of LDAV_SYMBOL. */ if (offset == 0) { # ifndef sgi # ifndef NLIST_STRUCT strcpy (nl[0].n_name, LDAV_SYMBOL); strcpy (nl[1].n_name, ""); # else /* NLIST_STRUCT */ # ifdef NLIST_NAME_UNION nl[0].n_un.n_name = LDAV_SYMBOL; nl[1].n_un.n_name = 0; # else /* not NLIST_NAME_UNION */ nl[0].n_name = LDAV_SYMBOL; nl[1].n_name = 0; # endif /* not NLIST_NAME_UNION */ # endif /* NLIST_STRUCT */ # ifndef SUNOS_5 if ( # if !(defined (_AIX) && !defined (ps2)) nlist (KERNEL_FILE, nl) # else /* _AIX */ knlist (nl, 1, sizeof (nl[0])) # endif >= 0) /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */ { # ifdef FIXUP_KERNEL_SYMBOL_ADDR FIXUP_KERNEL_SYMBOL_ADDR (nl); # endif offset = nl[0].n_value; } # endif /* !SUNOS_5 */ # else /* sgi */ int ldav_off; ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); if (ldav_off != -1) offset = (long) ldav_off & 0x7fffffff; # endif /* sgi */ } /* Make sure we have /dev/kmem open. */ if (!getloadavg_initialized) { # ifndef SUNOS_5 channel = open ("/dev/kmem", 0); if (channel >= 0) { /* Set the channel to close on exec, so it does not litter any child's descriptor table. */ # ifdef F_SETFD # ifndef FD_CLOEXEC # define FD_CLOEXEC 1 # endif (void) fcntl (channel, F_SETFD, FD_CLOEXEC); # endif getloadavg_initialized = 1; } # else /* SUNOS_5 */ /* We pass 0 for the kernel, corefile, and swapfile names to use the currently running kernel. */ kd = kvm_open (0, 0, 0, O_RDONLY, 0); if (kd != 0) { /* nlist the currently running kernel. */ kvm_nlist (kd, nl); offset = nl[0].n_value; getloadavg_initialized = 1; } # endif /* SUNOS_5 */ } /* If we can, get the load average values. */ if (offset && getloadavg_initialized) { /* Try to read the load. */ # ifndef SUNOS_5 if (lseek (channel, offset, 0) == -1L || read (channel, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { close (channel); getloadavg_initialized = 0; } # else /* SUNOS_5 */ if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { kvm_close (kd); getloadavg_initialized = 0; } # endif /* SUNOS_5 */ } if (offset == 0 || !getloadavg_initialized) return -1; # endif /* LOAD_AVE_TYPE and not VMS */ # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ if (nelem > 0) loadavg[elem++] = LDAV_CVT (load_ave[0]); if (nelem > 1) loadavg[elem++] = LDAV_CVT (load_ave[1]); if (nelem > 2) loadavg[elem++] = LDAV_CVT (load_ave[2]); # define LDAV_DONE # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ # ifdef LDAV_DONE return elem; # else /* Set errno to zero to indicate that there was no particular error; this function just can't work at all on this system. */ errno = 0; return -1; # endif } #endif /* ! HAVE_GETLOADAVG */ #ifdef TEST int main (argc, argv) int argc; char **argv; { int naptime = 0; if (argc > 1) naptime = atoi (argv[1]); while (1) { double avg[3]; int loads; errno = 0; /* Don't be misled if it doesn't set errno. */ loads = getloadavg (avg, 3); if (loads == -1) { perror ("Error getting load average"); exit (1); } if (loads > 0) printf ("1-minute: %f ", avg[0]); if (loads > 1) printf ("5-minute: %f ", avg[1]); if (loads > 2) printf ("15-minute: %f ", avg[2]); if (loads > 0) putchar ('\n'); if (naptime == 0) break; sleep (naptime); } exit (0); } #endif /* TEST */ cfengine-3.24.2/libcfecompat/compat_getopt.h0000644000000000000000000001116415010704253021024 0ustar00rootroot00000000000000/* Declarations for getopt. Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #define __GETOPT_H__ 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if defined (__STDC__) && __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if defined (__STDC__) && __STDC__ #if defined (__GNU_LIBRARY__) || defined (__APPLE__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C and MacOS libraries. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ or __APPLE__ */ extern int getopt (); #endif /* __GNU_LIBRARY__ || __APPLE__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ cfengine-3.24.2/cf-testd/0000755000000000000000000000000015010704323015062 5ustar00rootroot00000000000000cfengine-3.24.2/cf-testd/Makefile.am0000644000000000000000000000335615010704253017127 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-testd.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libenv \ -I$(srcdir)/../cf-serverd \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_testd_la_LIBADD = \ ../libpromises/libpromises.la \ ../cf-serverd/libcf-serverd.la libcf_testd_la_SOURCES = \ cf-testd.c if !BUILTIN_EXTENSIONS noinst_PROGRAMS = cf-testd # Workaround for automake madness (try removing it if you want to know why). cf_testd_CFLAGS = $(AM_CFLAGS) cf_testd_LDADD = libcf-testd.la endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-testd/Makefile.in0000644000000000000000000006344315010704300017134 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@noinst_PROGRAMS = cf-testd$(EXEEXT) subdir = cf-testd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_testd_la_DEPENDENCIES = ../libpromises/libpromises.la \ ../cf-serverd/libcf-serverd.la am_libcf_testd_la_OBJECTS = cf-testd.lo libcf_testd_la_OBJECTS = $(am_libcf_testd_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = PROGRAMS = $(noinst_PROGRAMS) cf_testd_SOURCES = cf-testd.c cf_testd_OBJECTS = cf_testd-cf-testd.$(OBJEXT) @BUILTIN_EXTENSIONS_FALSE@cf_testd_DEPENDENCIES = libcf-testd.la cf_testd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(cf_testd_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_testd_la_SOURCES) cf-testd.c DIST_SOURCES = $(libcf_testd_la_SOURCES) cf-testd.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-testd.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libenv \ -I$(srcdir)/../cf-serverd \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_testd_la_LIBADD = \ ../libpromises/libpromises.la \ ../cf-serverd/libcf-serverd.la libcf_testd_la_SOURCES = \ cf-testd.c # Workaround for automake madness (try removing it if you want to know why). @BUILTIN_EXTENSIONS_FALSE@cf_testd_CFLAGS = $(AM_CFLAGS) @BUILTIN_EXTENSIONS_FALSE@cf_testd_LDADD = libcf-testd.la CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-testd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-testd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-testd.la: $(libcf_testd_la_OBJECTS) $(libcf_testd_la_DEPENDENCIES) $(EXTRA_libcf_testd_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_testd_la_OBJECTS) $(libcf_testd_la_LIBADD) $(LIBS) clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-testd$(EXEEXT): $(cf_testd_OBJECTS) $(cf_testd_DEPENDENCIES) $(EXTRA_cf_testd_DEPENDENCIES) @rm -f cf-testd$(EXEEXT) $(AM_V_CCLD)$(cf_testd_LINK) $(cf_testd_OBJECTS) $(cf_testd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-testd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_testd-cf-testd.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cf_testd-cf-testd.o: cf-testd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_testd_CFLAGS) $(CFLAGS) -MT cf_testd-cf-testd.o -MD -MP -MF $(DEPDIR)/cf_testd-cf-testd.Tpo -c -o cf_testd-cf-testd.o `test -f 'cf-testd.c' || echo '$(srcdir)/'`cf-testd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_testd-cf-testd.Tpo $(DEPDIR)/cf_testd-cf-testd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-testd.c' object='cf_testd-cf-testd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_testd_CFLAGS) $(CFLAGS) -c -o cf_testd-cf-testd.o `test -f 'cf-testd.c' || echo '$(srcdir)/'`cf-testd.c cf_testd-cf-testd.obj: cf-testd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_testd_CFLAGS) $(CFLAGS) -MT cf_testd-cf-testd.obj -MD -MP -MF $(DEPDIR)/cf_testd-cf-testd.Tpo -c -o cf_testd-cf-testd.obj `if test -f 'cf-testd.c'; then $(CYGPATH_W) 'cf-testd.c'; else $(CYGPATH_W) '$(srcdir)/cf-testd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_testd-cf-testd.Tpo $(DEPDIR)/cf_testd-cf-testd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-testd.c' object='cf_testd-cf-testd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_testd_CFLAGS) $(CFLAGS) -c -o cf_testd-cf-testd.obj `if test -f 'cf-testd.c'; then $(CYGPATH_W) 'cf-testd.c'; else $(CYGPATH_W) '$(srcdir)/cf-testd.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-testd/cf-testd.c0000644000000000000000000006165515010704253016756 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include // cfnet_init #include // CryptoInitialize #include // GetAmPolicyHub #include #include // MapAddress #include // ActAsDaemon #include // DeleteItemList #include // GetInputDir #include // LoadPolicy #include // AcquireLock #include // ManPageWrite #include // ThreadLock #include #include // ERR_get_error #include // PolicyServerReadFile #include // PRINTSIZE #include // acl_Free #include // InitServer #include #include // ServerTLSInitialize #include // Summarize #include // ReloadConfigRequested #include // StringFormat, etc. #include // DetectEnvironment #include // CLASSTEXT #include // UpdateTimeClasses #include // SetReferenceTime #include // TLSLogError #include // thread-specific log prefix #include #ifndef __MINGW32__ #include #include #include #else #include #include #endif #define CFTESTD_QUEUE_SIZE 10 #define WAIT_CHECK_TIMEOUT 5 /* Strictly speaking/programming, this should use a lock, but it's not needed * for this testing tool. The worst that can happen is that some threads would * do one more WaitForIncoming iteration (WAIT_CHECK_TIMEOUT seconds). */ static bool TERMINATE = false; // ============================= CFTestD_Config ============================== typedef struct { char *report_file; char *report_data; Seq *report; int report_len; char *key_file; RSA *priv_key; RSA *pub_key; SSL_CTX *ssl_ctx; char *address; pthread_t t_id; int ret; } CFTestD_Config; /*******************************************************************/ /* Command line option parsing */ /*******************************************************************/ static const Component COMPONENT = { .name = "cf-testd", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"address", required_argument, 0, 'a'}, {"debug", no_argument, 0, 'd'}, {"log-level", required_argument, 0, 'g'}, {"help", no_argument, 0, 'h'}, {"inform", no_argument, 0, 'I'}, {"jobs", required_argument, 0, 'j'}, {"key-file", required_argument, 0, 'k'}, {"timestamp", no_argument, 0, 'l'}, {"port", required_argument, 0, 'p'}, {"report", required_argument, 0, 'r'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {NULL, 0, 0, '\0'}}; static const char *const HINTS[] = { "Bind to a specific address", "Enable debugging output", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Print the help message", "Print basic information about what cf-testd does", "Number of jobs (threads) to run in parallel. Use '%d' in the report path" " and key file path (will be replaced by the thread number, starting with" " 0). Threads will bind to different addresses incrementally.", "Specify a path to the key (private) to use for communication", "Log timestamps on each line of log output", "Set the port cf-testd will listen on", "Read report from file", "Output verbose information about the behaviour of the agent", "Output the version of the software", NULL}; CFTestD_Config *CFTestD_ConfigInit() { CFTestD_Config *r = (CFTestD_Config *)(xcalloc(1, sizeof(CFTestD_Config))); return r; } void CFTestD_ConfigDestroy(CFTestD_Config *config) { free(config->report_file); SeqDestroy(config->report); free(config->key_file); free(config->address); free(config); } void CFTestD_Help() { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } CFTestD_Config *CFTestD_CheckOpts(int argc, char **argv, long *n_threads) { extern char *optarg; int c; CFTestD_Config *config = CFTestD_ConfigInit(); assert(config != NULL); while ((c = getopt_long(argc, argv, "a:df:g:hIj:k:lp:vV", OPTIONS, NULL)) != -1) { switch (c) { case 'a': config->address = xstrdup(optarg); break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case 'h': CFTestD_Help(); DoCleanupAndExit(EXIT_SUCCESS); case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'j': { int ret = StringToLong(optarg, n_threads); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to parse number of threads/jobs from '%s'\n", optarg); *n_threads = 1; } break; } case 'k': config->key_file = xstrdup(optarg); break; case 'l': LoggingEnableTimestamps(true); break; case 'p': { bool ret = SetCfenginePort(optarg); if (!ret) { /* the function call above logs an error for us (if any) */ DoCleanupAndExit(EXIT_FAILURE); } break; } case 'r': config->report_file = xstrdup(optarg); break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); break; case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); default: CFTestD_Help(); DoCleanupAndExit(EXIT_FAILURE); } } if (optind < argc) // More unparsed arguments left after getopt_long { // Enumerate and print all invalid arguments: Log(LOG_LEVEL_ERR, "Invalid command line arguments:"); int start = optind; int stop = argc; int total = stop - start; for (int i = 0; i < total; ++i) { Log(LOG_LEVEL_ERR, "[%d/%d]: %s\n", i + 1, total, argv[start + i]); } } return config; } bool CFTestD_TLSSessionEstablish(ServerConnectionState *conn, CFTestD_Config *config) { if (conn->conn_info->status == CONNECTIONINFO_STATUS_ESTABLISHED) { return true; } bool established = BasicServerTLSSessionEstablish(conn, config->ssl_ctx); if (!established) { return false; } Log(LOG_LEVEL_VERBOSE, "TLS session established, checking trust..."); /* Send/Receive "CFE_v%d" version string, agree on version, receive identity (username) of peer. */ char username[sizeof(conn->username)] = ""; bool id_success = ServerIdentificationDialog( conn->conn_info, username, sizeof(username) ); if (!id_success) { return false; } /* No CAUTH, SAUTH in non-classic protocol. */ conn->user_data_set = true; conn->rsa_auth = true; ServerSendWelcome(conn); return true; } bool CFTestD_GetServerQuery( ServerConnectionState *conn, char *recvbuffer, CFTestD_Config *config) { char query[CF_BUFSIZE]; Seq *report = config->report; const int report_len = config->report_len; ConnectionInfo *const conn_info = conn->conn_info; query[0] = '\0'; sscanf(recvbuffer, "QUERY %255[^\n]", query); if (strlen(query) == 0) { return false; } if (report_len == 0) { Log(LOG_LEVEL_INFO, "No report file argument so returning canned data from enterprise plugin server\n"); return CFTestD_ReturnQueryData(conn, query); } Log(LOG_LEVEL_INFO, "Report file argument specified. Returning report of length %d", report_len); const size_t n_report_lines = SeqLength(report); assert(n_report_lines > 1); char *ts = SeqAt(report, 0); char *header = StringFormat("CFR: 0 %s %d\n", ts, report_len); SendTransaction(conn_info, header, SafeStringLength(header), CF_MORE); free(header); for (size_t i = 1; i < n_report_lines; i++) { const char *report_line = SeqAt(report, i); SendTransaction(conn_info, report_line, SafeStringLength(report_line), CF_MORE); } const char end_reply[] = "QUERY complete"; SendTransaction(conn_info, end_reply, SafeStringLength(end_reply), CF_DONE); return true; } static bool CFTestD_ProtocolError( ServerConnectionState *conn, const char *recvbuffer, char *sendbuffer) { strcpy(sendbuffer, "BAD: Request denied"); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); Log(LOG_LEVEL_INFO, "Closing connection due to illegal request: %s", recvbuffer); return false; } static bool CFTestD_BusyLoop( ServerConnectionState *conn, CFTestD_Config *config) { char recvbuffer[CF_BUFSIZE + CF_BUFEXT] = ""; char sendbuffer[CF_BUFSIZE - CF_INBAND_OFFSET] = ""; const int received = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); if (received == -1) { /* Already Log()ged in case of error. */ return false; } if (received > CF_BUFSIZE - 1) { UnexpectedError("Received transaction of size %d", received); return false; } if (strlen(recvbuffer) == 0) { Log(LOG_LEVEL_WARNING, "Got NULL transmission (of size %d)", received); return true; } /* Don't process request if we're signalled to exit. */ if (IsPendingTermination()) { Log(LOG_LEVEL_VERBOSE, "Server must exit, closing connection"); return false; } // See BusyWithNewProtocol() in server_tls.c for how to add other commands switch (GetCommandNew(recvbuffer)) { case PROTOCOL_COMMAND_COOKIE: { const char response[] = "COOKIES 0 0"; const size_t size = sizeof(response) - 1; SendTransaction(conn->conn_info, response, size, CF_DONE); return true; break; } case PROTOCOL_COMMAND_QUERY: { char query[256], name[128]; int ret1 = sscanf(recvbuffer, "QUERY %255[^\n]", query); int ret2 = sscanf(recvbuffer, "QUERY %127s", name); if (ret1 != 1 || ret2 != 1) { return CFTestD_ProtocolError(conn, recvbuffer, sendbuffer); } if (CFTestD_GetServerQuery(conn, recvbuffer, config)) { return true; } break; } case PROTOCOL_COMMAND_BAD: default: Log(LOG_LEVEL_WARNING, "Unexpected protocol command: %s", recvbuffer); } return CFTestD_ProtocolError(conn, recvbuffer, sendbuffer); } static ServerConnectionState *CFTestD_NewConn(ConnectionInfo *info) { #if 1 /* TODO: why do we do this ? We fail if getsockname() fails, but * don't use the information it returned. Was the intent to use * it to fill in conn->ipaddr ? */ struct sockaddr_storage addr; socklen_t size = sizeof(addr); int sockfd = ConnectionInfoSocket(info); int sockname = getsockname(sockfd, (struct sockaddr *)&addr, &size); if (sockname == -1) { Log(LOG_LEVEL_ERR, "Could not obtain socket address. (getsockname: '%s')", GetErrorStr()); return NULL; } #endif ServerConnectionState *conn = xcalloc(1, sizeof(*conn)); conn->ctx = NULL; conn->conn_info = info; conn->encryption_type = 'c'; /* Only public files (chmod o+r) accessible to non-root */ conn->uid = CF_UNKNOWN_OWNER; /* Careful, 0 is root! */ /* conn->maproot is false: only public files (chmod o+r) are accessible */ Log(LOG_LEVEL_DEBUG, "New connection (socket %d).", ConnectionInfoSocket(info)); return conn; } static void CFTestD_DeleteConn(ServerConnectionState *conn) { int sd = ConnectionInfoSocket(conn->conn_info); if (sd != SOCKET_INVALID) { cf_closesocket(sd); } ConnectionInfoDestroy(&conn->conn_info); free(conn->session_key); free(conn); } static void *CFTestD_HandleConnection(ServerConnectionState *conn, CFTestD_Config *config) { Log(LOG_LEVEL_INFO, "Accepting connection"); bool established = CFTestD_TLSSessionEstablish(conn, config); if (!established) { Log(LOG_LEVEL_ERR, "Could not establish TLS Session"); return NULL; } int ret = getnameinfo( (const struct sockaddr *)&conn->conn_info->ss, conn->conn_info->ss_len, conn->revdns, sizeof(conn->revdns), NULL, 0, NI_NAMEREQD); if (ret != 0) { Log(LOG_LEVEL_INFO, "Reverse lookup failed (getnameinfo: %s)!", gai_strerror(ret)); } else { Log(LOG_LEVEL_INFO, "Hostname (reverse looked up): %s", conn->revdns); } while (CFTestD_BusyLoop(conn, config)) { } CFTestD_DeleteConn(conn); return NULL; } static void CFTestD_SpawnConnection( const char *ipaddr, ConnectionInfo *info, CFTestD_Config *config) { ServerConnectionState *conn = CFTestD_NewConn(info); ConnectionInfoSocket(info); strlcpy(conn->ipaddr, ipaddr, CF_MAX_IP_LEN); Log(LOG_LEVEL_WARNING, "Connection is being handled from main loop!"); CFTestD_HandleConnection(conn, config); } /* Try to accept a connection; handle if we get one. */ static void CFTestD_AcceptAndHandle(int sd, CFTestD_Config *config) { /* TODO embed ConnectionInfo into ServerConnectionState. */ ConnectionInfo *info = ConnectionInfoNew(); /* Uses xcalloc() */ info->ss_len = sizeof(info->ss); info->sd = accept(sd, (struct sockaddr *)&info->ss, &info->ss_len); if (info->sd == -1) { Log(LOG_LEVEL_INFO, "Error accepting connection (%s)", GetErrorStr()); ConnectionInfoDestroy(&info); return; } Log(LOG_LEVEL_DEBUG, "Socket descriptor returned from accept(): %d", info->sd); /* Just convert IP address to string, no DNS lookup. */ char ipaddr[CF_MAX_IP_LEN] = ""; getnameinfo( (const struct sockaddr *)&info->ss, info->ss_len, ipaddr, sizeof(ipaddr), NULL, 0, NI_NUMERICHOST); /* IPv4 mapped addresses (e.g. "::ffff:192.168.1.2") are * hereby represented with their IPv4 counterpart. */ CFTestD_SpawnConnection(MapAddress(ipaddr), info, config); } int CFTestD_StartServer(CFTestD_Config *config) { int ret = -1; bool tls_init_ok = ServerTLSInitialize(config->priv_key, config->pub_key, &(config->ssl_ctx)); if (!tls_init_ok) { return -1; } int sd = InitServer(CFTESTD_QUEUE_SIZE, config->address); int selected = 0; while (!TERMINATE && (selected != -1)) { selected = WaitForIncoming(sd, WAIT_CHECK_TIMEOUT); if (selected > 0) { Log(LOG_LEVEL_DEBUG, "select(): %d", selected); CFTestD_AcceptAndHandle(sd, config); } } if (!TERMINATE) { Log(LOG_LEVEL_ERR, "Error while waiting for connections. (select: %s)", GetErrorStr()); } else { ret = 0; } Log(LOG_LEVEL_NOTICE, "Cleaning up and exiting..."); if (sd != -1) { Log(LOG_LEVEL_VERBOSE, "Closing listening socket"); cf_closesocket(sd); } return ret; } static char *LogAddPrefix(LoggingPrivContext *log_ctx, ARG_UNUSED LogLevel level, const char *raw) { const char *ip_addr = log_ctx->param; return ip_addr ? StringConcatenate(4, "[", ip_addr, "] ", raw) : xstrdup(raw); } static bool CFTestD_GetReportLine(char *data, char **report_line_start, size_t *report_line_length) { int ret = sscanf(data, "%10zd", report_line_length); if (ret != 1) { /* incorrect number of items scanned (could be EOF) */ return false; } *report_line_start = data + 10; return true; } static void *CFTestD_ServeReport(void *config_arg) { CFTestD_Config *config = (CFTestD_Config *) config_arg; /* Set prefix for all Log()ging: */ LoggingPrivContext *prior = LoggingPrivGetContext(); LoggingPrivContext log_ctx = { .log_hook = LogAddPrefix, .param = config->address }; LoggingPrivSetContext(&log_ctx); char *priv_key_path = NULL; char *pub_key_path = NULL; if (config->key_file != NULL) { priv_key_path = config->key_file; pub_key_path = xstrdup(priv_key_path); StringReplace(pub_key_path, strlen(pub_key_path) + 1, "priv", "pub"); } LoadSecretKeys(priv_key_path, pub_key_path, &(config->priv_key), &(config->pub_key)); free(pub_key_path); char *report_file = config->report_file; if (report_file != NULL) { Log(LOG_LEVEL_NOTICE, "Got file argument: '%s'", report_file); if (!FileCanOpen(report_file, "r")) { Log(LOG_LEVEL_ERR, "Can't open file '%s' for reading", report_file); DoCleanupAndExit(EXIT_FAILURE); } Writer *contents = FileRead(report_file, SIZE_MAX, NULL); if (!contents) { Log(LOG_LEVEL_ERR, "Error reading report file '%s'", report_file); DoCleanupAndExit(EXIT_FAILURE); } size_t report_data_len = StringWriterLength(contents); config->report_data = StringWriterClose(contents); Seq *report = SeqNew(64, NULL); size_t report_len = 0; StringRef ts_ref = StringGetToken(config->report_data, report_data_len, 0, "\n"); char *ts = (char *) ts_ref.data; *(ts + ts_ref.len) = '\0'; SeqAppend(report, ts); /* start right after the newline after the timestamp header */ char *position = ts + ts_ref.len + 1; char *report_line; size_t report_line_len; while (CFTestD_GetReportLine(position, &report_line, &report_line_len)) { *(report_line + report_line_len) = '\0'; SeqAppend(report, report_line); report_len += report_line_len; position = report_line + report_line_len + 1; /* there's an extra newline after each report_line */ } config->report = report; config->report_len = report_len; Log(LOG_LEVEL_NOTICE, "Read %d bytes for report contents", config->report_len); if (config->report_len <= 0) { Log(LOG_LEVEL_ERR, "Report file contained no bytes"); DoCleanupAndExit(EXIT_FAILURE); } } Log(LOG_LEVEL_INFO, "Starting server at %s...", config->address); fflush(stdout); // for debugging startup config->ret = CFTestD_StartServer(config); free(config->report_data); /* we don't really need to do this here because the process is about the * terminate, but it's a good way the cleanup actually works and doesn't * cause a segfault or something */ ServerTLSDeInitialize(&(config->priv_key), &(config->pub_key), &(config->ssl_ctx)); LoggingPrivSetContext(prior); return NULL; } static void HandleSignal(int signum) { switch (signum) { case SIGTERM: case SIGINT: // flush all logging before process ends. fflush(stdout); fprintf(stderr, "Terminating...\n"); TERMINATE = true; break; default: break; } } /** * @param ip_str string representation of an IPv4 address (the usual one, with * 4 octets separated by dots) * @return a new string representing the incremented IP address (HAS TO BE FREED) */ static char *IncrementIPaddress(const char *ip_str) { uint32_t ip = (uint32_t) inet_addr(ip_str); if (ip == INADDR_NONE) { Log(LOG_LEVEL_ERR, "Failed to parse address: '%s'", ip_str); return NULL; } int step = 1; char *last_dot = strrchr(ip_str, '.'); assert(last_dot != NULL); /* the doc comment says there must be dots! */ if (StringEqual(last_dot + 1, "255")) { /* avoid the network address (ending with 0) */ step = 2; } else if (StringEqual(last_dot + 1, "254")) { /* avoid the broadcast address and the network address */ step = 3; } uint32_t ip_num = ntohl(ip); ip_num += step; ip = htonl(ip_num); struct in_addr ip_struct; ip_struct.s_addr = ip; return xstrdup(inet_ntoa(ip_struct)); } int main(int argc, char *argv[]) { signal(SIGINT, HandleSignal); signal(SIGTERM, HandleSignal); Log(LOG_LEVEL_VERBOSE, "Starting cf-testd"); cfnet_init(NULL, NULL); MakeSignalPipe(); long n_threads = 1; CFTestD_Config *config = CFTestD_CheckOpts(argc, argv, &n_threads); if (config->address == NULL) { /* default to localhost */ config->address = xstrdup("127.0.0.1"); } CFTestD_Config **thread_configs = (CFTestD_Config**) xcalloc(n_threads, sizeof(CFTestD_Config*)); for (int i = 0; i < n_threads; i++) { thread_configs[i] = (CFTestD_Config*) xcalloc(1, sizeof(CFTestD_Config)); char *thread_num_str; xasprintf(&thread_num_str, "%d", i); if (config->report_file != NULL && strstr(config->report_file, "%d") != NULL) { /* replace the (first) '%d' with the thread number */ size_t report_file_len = strlen(config->report_file) + strlen(thread_num_str) - 2 + 1; thread_configs[i]->report_file = xmalloc(report_file_len); StringReplaceN(thread_configs[i]->report_file, report_file_len, "%d", thread_num_str, 1); } else { thread_configs[i]->report_file = SafeStringDuplicate(config->report_file); } if (config->key_file != NULL && strstr(config->key_file, "%d") != NULL) { /* replace the (first) '%d' with the thread number */ size_t key_file_len = strlen(config->key_file) + strlen(thread_num_str) - 2 + 1; thread_configs[i]->key_file = xmalloc(key_file_len); StringReplaceN(thread_configs[i]->key_file, key_file_len, "%d", thread_num_str, 1); } else { thread_configs[i]->key_file = SafeStringDuplicate(config->key_file); } if (i == 0) { thread_configs[i]->address = xstrdup(config->address); } else { thread_configs[i]->address = IncrementIPaddress(thread_configs[i-1]->address); } free(thread_num_str); } CFTestD_ConfigDestroy(config); bool failure = false; for (int i = 0; !failure && (i < n_threads); i++) { int ret = pthread_create(&(thread_configs[i]->t_id), NULL, CFTestD_ServeReport, thread_configs[i]); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to create a new thread nr. %d: %s\n", i, strerror(ret)); failure = true; } } if (failure) { CallCleanupFunctions(); return EXIT_FAILURE; } for (int i = 0; i < n_threads; i++) { int ret = pthread_join(thread_configs[i]->t_id, NULL); if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to join the thread nr. %d: %s\n", i, strerror(ret)); } else { failure = failure && (thread_configs[i]->ret != 0); } CFTestD_ConfigDestroy(thread_configs[i]); } CallCleanupFunctions(); return failure ? EXIT_FAILURE : EXIT_SUCCESS; } cfengine-3.24.2/misc/0000755000000000000000000000000015010704323014304 5ustar00rootroot00000000000000cfengine-3.24.2/misc/Makefile.am0000644000000000000000000000225415010704253016345 0ustar00rootroot00000000000000SUBDIRS = selinux # include unconditionally in the distribution tarball EXTRA_DIST= init.d/cfengine3.in \ systemd/cf-apache.service.in \ systemd/cf-execd.service.in \ systemd/cf-hub.service.in \ systemd/cf-monitord.service.in \ systemd/cf-postgres.service.in \ systemd/cf-serverd.service.in \ systemd/cfengine3.service.in # The following files are generated from the previous ones, during ./configure if WITH_INIT_D_SCRIPT initddir = $(INIT_D_PATH) initd_SCRIPTS = init.d/cfengine3 endif if WITH_SYSTEMD_SERVICE systemddir = $(SYSTEMD_SERVICE_PATH) systemd_DATA = systemd/cfengine3.service systemd_DATA += systemd/cf-apache.service systemd_DATA += systemd/cf-execd.service systemd_DATA += systemd/cf-hub.service systemd_DATA += systemd/cf-reactor.service systemd_DATA += systemd/cf-monitord.service systemd_DATA += systemd/cf-postgres.service systemd_DATA += systemd/cf-serverd.service install-data-hook: -systemctl --no-ask-password daemon-reload endif dist_bin_SCRIPTS = cf-support check-local: @if command -v shellcheck 2>/dev/null; then \ shellcheck --version; \ shellcheck cf-support; \ else \ echo "Install shellcheck to check cf-support script."; \ fi cfengine-3.24.2/misc/Makefile.in0000644000000000000000000007165215010704300016357 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = misc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(initddir)" \ "$(DESTDIR)$(systemddir)" SCRIPTS = $(dist_bin_SCRIPTS) $(initd_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(systemd_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ SUBDIRS = selinux # include unconditionally in the distribution tarball EXTRA_DIST = init.d/cfengine3.in \ systemd/cf-apache.service.in \ systemd/cf-execd.service.in \ systemd/cf-hub.service.in \ systemd/cf-monitord.service.in \ systemd/cf-postgres.service.in \ systemd/cf-serverd.service.in \ systemd/cfengine3.service.in # The following files are generated from the previous ones, during ./configure @WITH_INIT_D_SCRIPT_TRUE@initddir = $(INIT_D_PATH) @WITH_INIT_D_SCRIPT_TRUE@initd_SCRIPTS = init.d/cfengine3 @WITH_SYSTEMD_SERVICE_TRUE@systemddir = $(SYSTEMD_SERVICE_PATH) @WITH_SYSTEMD_SERVICE_TRUE@systemd_DATA = systemd/cfengine3.service \ @WITH_SYSTEMD_SERVICE_TRUE@ systemd/cf-apache.service \ @WITH_SYSTEMD_SERVICE_TRUE@ systemd/cf-execd.service \ @WITH_SYSTEMD_SERVICE_TRUE@ systemd/cf-hub.service \ @WITH_SYSTEMD_SERVICE_TRUE@ systemd/cf-reactor.service \ @WITH_SYSTEMD_SERVICE_TRUE@ systemd/cf-monitord.service \ @WITH_SYSTEMD_SERVICE_TRUE@ systemd/cf-postgres.service \ @WITH_SYSTEMD_SERVICE_TRUE@ systemd/cf-serverd.service dist_bin_SCRIPTS = cf-support all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu misc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu misc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-dist_binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) install-initdSCRIPTS: $(initd_SCRIPTS) @$(NORMAL_INSTALL) @list='$(initd_SCRIPTS)'; test -n "$(initddir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(initddir)'"; \ $(MKDIR_P) "$(DESTDIR)$(initddir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(initddir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(initddir)$$dir" || exit $$?; \ } \ ; done uninstall-initdSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(initd_SCRIPTS)'; test -n "$(initddir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(initddir)'; $(am__uninstall_files_from_dir) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-systemdDATA: $(systemd_DATA) @$(NORMAL_INSTALL) @list='$(systemd_DATA)'; test -n "$(systemddir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(systemddir)'"; \ $(MKDIR_P) "$(DESTDIR)$(systemddir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemddir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(systemddir)" || exit $$?; \ done uninstall-systemdDATA: @$(NORMAL_UNINSTALL) @list='$(systemd_DATA)'; test -n "$(systemddir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(systemddir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-local check: check-recursive all-am: Makefile $(SCRIPTS) $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(initddir)" "$(DESTDIR)$(systemddir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @WITH_SYSTEMD_SERVICE_FALSE@install-data-hook: clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-initdSCRIPTS install-systemdDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-dist_binSCRIPTS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-dist_binSCRIPTS uninstall-initdSCRIPTS \ uninstall-systemdDATA .MAKE: $(am__recursive_targets) check-am install-am install-data-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am check-local clean clean-generic clean-libtool \ cscopelist-am ctags ctags-am distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-data-hook install-dist_binSCRIPTS \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-initdSCRIPTS install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip install-systemdDATA \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-dist_binSCRIPTS \ uninstall-initdSCRIPTS uninstall-systemdDATA .PRECIOUS: Makefile @WITH_SYSTEMD_SERVICE_TRUE@install-data-hook: @WITH_SYSTEMD_SERVICE_TRUE@ -systemctl --no-ask-password daemon-reload check-local: @if command -v shellcheck 2>/dev/null; then \ shellcheck --version; \ shellcheck cf-support; \ else \ echo "Install shellcheck to check cf-support script."; \ fi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/misc/selinux/0000755000000000000000000000000015010704323015773 5ustar00rootroot00000000000000cfengine-3.24.2/misc/selinux/Makefile.am0000644000000000000000000000150715010704253020034 0ustar00rootroot00000000000000if WITH_SELINUX cfengine-enterprise.te: cfengine-enterprise.te.all $(PLATFORM_SELINUX_POLICIES) cat cfengine-enterprise.te.all $(PLATFORM_SELINUX_POLICIES) > cfengine-enterprise.te cfengine-enterprise.pp: cfengine-enterprise.te cfengine-enterprise.fc $(MAKE) -f /usr/share/selinux/devel/Makefile -j1 selinuxdir = $(prefix)/selinux selinux_DATA = cfengine-enterprise.pp selinux_DATA += cfengine-enterprise.te selinux_DATA += cfengine-enterprise.fc clean-local: rm -rf tmp endif # explicit DISTFILES are required for these files to be part of a 'make dist' # tarball even without running './configure --with-selinux-policy' DISTFILES = Makefile.in Makefile.am cfengine-enterprise.fc cfengine-enterprise.te.all DISTFILES += cfengine-enterprise.te.el9 CLEANFILES = cfengine-enterprise.pp cfengine-enterprise.if cfengine-enterprise.te cfengine-3.24.2/misc/selinux/cfengine-enterprise.te.all0000644000000000000000000014023615010704253023040 0ustar00rootroot00000000000000# SELinux policy module for CFEngine Enterprise # # This is a complementary module for the upstream cfengine module [1]. # # [1] https://github.com/fedora-selinux/selinux-policy-contrib/blob/rawhide/cfengine.te # module cfengine-enterprise 1.0; # 'require' is something like 'import' -- we need to list here all the things # used in this policy module require { attribute domain; attribute entry_type; attribute file_type; attribute exec_type; attribute non_security_file_type; attribute non_auth_file_type; type bin_t; type cert_t; type devlog_t; type kernel_t; type var_t; type var_log_t; type fs_t; type unconfined_t; type unreserved_port_t; type user_cron_spool_t; type cfengine_serverd_t; type cfengine_execd_exec_t; type net_conf_t; type node_t; type passwd_file_t; type ping_exec_t; type proc_t; type proc_net_t; type proc_xen_t; type proc_security_t; type cfengine_serverd_exec_t; type http_port_t; type ldap_port_t; type postgresql_port_t; type smtp_port_t; type ssh_port_t; type rpm_exec_t; type rpm_var_lib_t; type sssd_t; type sssd_public_t; type sssd_var_lib_t; type sysfs_t; type sysctl_net_t; type system_cron_spool_t; type systemd_unit_file_t; type hugetlbfs_t; type init_exec_t; type init_var_run_t; type ifconfig_t; type ifconfig_exec_t; type journalctl_exec_t; type cfengine_execd_t; type cfengine_log_t; type systemd_systemctl_exec_t; type useradd_exec_t; type cfengine_monitord_t; type dmidecode_exec_t; type init_t; type cfengine_monitord_exec_t; type gpg_exec_t; type shadow_t; type cfengine_var_lib_t; type crontab_exec_t; type hostname_exec_t; type groupadd_exec_t; type shell_exec_t; type semanage_exec_t; type syslogd_var_run_t; type system_dbusd_t; type system_dbusd_var_run_t; type tmp_t; type tmpfs_t; role system_r; type tty_device_t; type user_devpts_t; type sysctl_t; type postfix_etc_t; type postfix_master_t; type postfix_postdrop_exec_t; type postfix_public_t; type postfix_spool_t; type sendmail_exec_t; type sshd_t; type ssh_exec_t; type ssh_home_t; type rpm_script_t; type fsadm_exec_t; type lvm_exec_t; class lockdown { confidentiality integrity }; class tcp_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown name_connect accept listen name_bind node_bind }; class mctp_socket { ioctl read write create getattr setattr lock relabelfrom relabelto append map bind connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg name_bind }; class udp_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown node_bind }; class sock_file { create write getattr setattr unlink }; class rawip_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class packet_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class unix_stream_socket { create ioctl read getattr lock write setattr append bind connect connectto getopt setopt shutdown }; class unix_dgram_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown sendto }; class appletalk_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_route_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown nlmsg_read getopt }; class netlink_firewall_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_tcpdiag_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_nflog_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_xfrm_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_selinux_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_audit_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_ip6fw_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_dnrt_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_kobject_uevent_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class tun_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_iscsi_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_fib_lookup_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_connector_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_netfilter_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_generic_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_scsitransport_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_rdma_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netlink_crypto_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class sctp_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class icmp_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class ax25_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class ipx_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class netrom_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class atmpvc_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class x25_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class xdp_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class rose_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class decnet_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class atmsvc_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class rds_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class irda_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class pppox_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class llc_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class can_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class tipc_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class bluetooth_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class iucv_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class rxrpc_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class isdn_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class phonet_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class ieee802154_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class caif_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class alg_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class nfc_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class vsock_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class kcm_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class qipcrtr_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class smc_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class bridge_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class dccp_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class ib_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class mpls_socket { create ioctl read getattr lock write setattr append bind connect getopt setopt shutdown }; class process { setrlimit transition dyntransition execstack execheap execmem signull siginh getattr sigchld }; class fd use; class file { execute execute_no_trans getattr ioctl map open read unlink write entrypoint lock link rename append setattr create relabelfrom relabelto watch watch_reads }; class fifo_file { create open getattr setattr read write append rename link unlink ioctl lock relabelfrom relabelto }; class dir { getattr read search open write add_name remove_name lock ioctl create setattr rmdir }; class filesystem getattr; class lnk_file { create getattr read unlink }; class capability { dac_read_search sys_module chown dac_read_search dac_override fowner fsetid sys_admin mknod net_raw net_admin sys_nice sys_rawio sys_resource setuid setgid sys_nice sys_ptrace kill net_bind_service }; class cap_userns sys_ptrace; class capability2 { mac_admin mac_override block_suspend syslog wake_alarm }; class association { sendto recvfrom setcontext polmatch }; class security setsecparam; class service { start stop status reload enable disable }; class system { module_request }; class memprotect mmap_zero; class peer recv; class chr_file { getattr }; } #============= cfengine_agent_t ============= # define an *unconfined* domain for the agent (so that it can access/do anything) type cfengine_agent_t; typeattribute cfengine_agent_t domain; role system_r types cfengine_agent_t; # this is a macro invocation, the file has to be processed with # make -f /usr/share/selinux/devel/Makefile unconfined_domain(cfengine_agent_t) # /var/cfengine/bin/cf-agent has the 'cfengine_agent_exec_t' context which is an # entrypoint for the 'cfengine_agent_t' domain type cfengine_agent_exec_t; typeattribute cfengine_agent_exec_t entry_type; typeattribute cfengine_agent_exec_t exec_type; typeattribute cfengine_agent_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_agent_exec_t; allow cfengine_agent_t cfengine_agent_exec_t:file entrypoint; allow cfengine_agent_t cfengine_agent_exec_t:file { ioctl read getattr lock map execute open }; # cf-agent needs to be able to transition into the domain of RPM scriplets allow cfengine_agent_t rpm_script_t:process transition; #============= cfengine_execd_t ============== # allow cf-execd to run cf-agent and make sure the forked process run in the # unconfined cfengine_agent_t domain type_transition cfengine_execd_t cfengine_agent_exec_t:process cfengine_agent_t; allow cfengine_execd_t cfengine_agent_t:process transition; allow cfengine_execd_t cfengine_agent_exec_t:file { open read execute map getattr }; # allow cf-execd to use/execute libpromises.so allow cfengine_execd_t cfengine_var_lib_t:file map; allow cfengine_execd_t cfengine_var_lib_t:file execute; # allow cf-execd to execute cf-promises allow cfengine_execd_t cfengine_var_lib_t:file execute_no_trans; # allow cf-promises run by cf-execd to getattr everywhere and read symlinks files_getattr_all_dirs(cfengine_execd_t) files_getattr_all_files(cfengine_execd_t) files_read_all_symlinks(cfengine_execd_t) # TODO: this should not be needed allow cfengine_execd_t ssh_port_t:tcp_socket name_connect; allow cfengine_execd_t proc_xen_t:dir search; allow cfengine_execd_t cfengine_log_t:file { read unlink write }; allow cfengine_execd_t cfengine_log_t:lnk_file { create getattr read unlink }; allow cfengine_execd_t cfengine_log_t:dir add_name; allow cfengine_execd_t cfengine_monitord_exec_t:file getattr; allow cfengine_execd_t cfengine_serverd_exec_t:file getattr; allow cfengine_execd_t cfengine_hub_exec_t:file getattr; allow cfengine_execd_t cfengine_reactor_exec_t:file getattr; # allow cf-execd to work with local/UNIX sockets allow cfengine_execd_t cfengine_var_lib_t:sock_file { create unlink getattr setattr }; allow cfengine_execd_t self:capability sys_ptrace; allow cfengine_execd_t self:cap_userns sys_ptrace; allow cfengine_execd_t crontab_exec_t:file getattr; allow cfengine_execd_t dmidecode_exec_t:file getattr; allow cfengine_execd_t fs_t:filesystem getattr; allow cfengine_execd_t gpg_exec_t:file getattr; allow cfengine_execd_t groupadd_exec_t:file getattr; allow cfengine_execd_t hostname_exec_t:file getattr; allow cfengine_execd_t init_exec_t:file getattr; allow cfengine_execd_t init_t:unix_stream_socket connectto; allow cfengine_execd_t journalctl_exec_t:file getattr; allow cfengine_execd_t ping_exec_t:file getattr; allow cfengine_execd_t proc_net_t:file { getattr open read }; allow cfengine_execd_t proc_net_t:lnk_file { getattr read }; allow cfengine_execd_t proc_security_t:file { getattr open read }; allow cfengine_execd_t rpm_exec_t:file getattr; allow cfengine_execd_t rpm_var_lib_t:dir search; allow cfengine_execd_t rpm_var_lib_t:file open; allow cfengine_execd_t self:capability dac_read_search; allow cfengine_execd_t shadow_t:file { getattr open read }; allow cfengine_execd_t smtp_port_t:tcp_socket name_connect; allow cfengine_execd_t system_cron_spool_t:dir getattr; allow cfengine_execd_t systemd_systemctl_exec_t:file getattr; allow cfengine_execd_t systemd_unit_file_t:dir search; allow cfengine_execd_t systemd_unit_file_t:file getattr; allow cfengine_execd_t unreserved_port_t:tcp_socket name_connect; allow cfengine_execd_t user_cron_spool_t:dir getattr; allow cfengine_execd_t useradd_exec_t:file getattr; allow cfengine_execd_t var_t:dir read; allow cfengine_execd_t semanage_exec_t:file getattr; allow cfengine_execd_t tty_device_t:chr_file getattr; allow cfengine_execd_t user_devpts_t:chr_file getattr; allow cfengine_execd_t ssh_exec_t:file getattr; #============= cfengine_monitord_t ============== # allow cf-monitord to use/execute libpromises.so allow cfengine_monitord_t cfengine_var_lib_t:file map; allow cfengine_monitord_t cfengine_var_lib_t:file execute; # allow cf-monitord to execute cf-promises allow cfengine_monitord_t cfengine_var_lib_t:file execute_no_trans; # allow cf-promises run by cf-monitord to getattr everywhere and read symlinks files_getattr_all_dirs(cfengine_monitord_t) files_getattr_all_files(cfengine_monitord_t) files_read_all_symlinks(cfengine_monitord_t) allow cfengine_monitord_t cfengine_execd_exec_t:file getattr; allow cfengine_monitord_t cfengine_serverd_exec_t:file getattr; allow cfengine_monitord_t cfengine_agent_exec_t:file getattr; allow cfengine_monitord_t cfengine_hub_exec_t:file getattr; allow cfengine_monitord_t cfengine_reactor_exec_t:file getattr; allow cfengine_monitord_t var_log_t:file { open read }; # cf-monitord collects arbitrary system data so needs complete access to filesystems and files fs_unconfined(cfengine_monitord_t) files_unconfined(cfengine_monitord_t) allow cfengine_monitord_t self:capability { dac_override dac_read_search sys_ptrace }; allow cfengine_monitord_t self:cap_userns sys_ptrace; allow cfengine_monitord_t crontab_exec_t:file getattr; allow cfengine_monitord_t dmidecode_exec_t:file getattr; allow cfengine_monitord_t groupadd_exec_t:file getattr; allow cfengine_monitord_t hostname_exec_t:file getattr; allow cfengine_monitord_t init_exec_t:file getattr; allow cfengine_monitord_t journalctl_exec_t:file getattr; allow cfengine_monitord_t ping_exec_t:file getattr; allow cfengine_monitord_t rpm_exec_t:file getattr; allow cfengine_monitord_t shadow_t:file getattr; allow cfengine_monitord_t systemd_systemctl_exec_t:file getattr; allow cfengine_monitord_t user_cron_spool_t:dir getattr; allow cfengine_monitord_t useradd_exec_t:file getattr; allow cfengine_monitord_t var_t:dir read; allow cfengine_monitord_t semanage_exec_t:file getattr; allow cfengine_monitord_t tty_device_t:chr_file getattr; allow cfengine_monitord_t user_devpts_t:chr_file getattr; allow cfengine_monitord_t sysctl_t:dir read; allow cfengine_monitord_t ssh_exec_t:file getattr; allow cfengine_monitord_t proc_net_t:file { getattr open read }; allow cfengine_monitord_t proc_security_t:file { getattr open read }; # TODO: this should not be needed allow cfengine_monitord_t proc_xen_t:dir search; #============= cfengine_serverd_t ============== # allow cf-serverd to run cf-agent and make sure the forked process run in the # unconfined cfengine_agent_t domain allow cfengine_serverd_t cfengine_agent_exec_t:file { open read execute execute_no_trans map getattr }; type_transition cfengine_serverd_t cfengine_agent_exec_t:process cfengine_agent_t; allow cfengine_serverd_t cfengine_agent_t:process transition; # allow cf-serverd to use/execute libpromises.so allow cfengine_serverd_t cfengine_var_lib_t:file map; allow cfengine_serverd_t cfengine_var_lib_t:file execute; # allow cf-serverd to execute cf-promises allow cfengine_serverd_t cfengine_var_lib_t:file execute_no_trans; # allow cf-promises run by cf-serverd to getattr everywhere and read symlinks files_getattr_all_dirs(cfengine_serverd_t) files_getattr_all_files(cfengine_serverd_t) files_read_all_symlinks(cfengine_serverd_t) # allow cf-serverd to connect to the CFEngine port and to write into a local socket (in case of # call-collect on hosts and the hub itself, respectively) allow cfengine_serverd_t unreserved_port_t:tcp_socket name_connect; allow cfengine_serverd_t cfengine_var_lib_t:sock_file { getattr write }; allow cfengine_serverd_t cfengine_hub_t:unix_stream_socket connectto; # allow cf-serverd to set its own limits, e.g. def.control_server_maxconnections allow cfengine_serverd_t self:capability sys_resource; # TODO: this should not be needed allow cfengine_serverd_t ssh_port_t:tcp_socket name_connect; allow cfengine_serverd_t proc_xen_t:dir search; allow cfengine_serverd_t cfengine_execd_exec_t:file getattr; allow cfengine_serverd_t cfengine_monitord_exec_t:file getattr; allow cfengine_serverd_t cfengine_hub_exec_t:file getattr; allow cfengine_serverd_t cfengine_reactor_exec_t:file getattr; allow cfengine_serverd_t cfengine_log_t:lnk_file getattr; allow cfengine_serverd_t crontab_exec_t:file getattr; allow cfengine_serverd_t dmidecode_exec_t:file getattr; allow cfengine_serverd_t fs_t:filesystem getattr; allow cfengine_serverd_t groupadd_exec_t:file getattr; allow cfengine_serverd_t hostname_exec_t:file getattr; allow cfengine_serverd_t init_exec_t:file getattr; allow cfengine_serverd_t init_t:dir { getattr open search read } ; # /proc/1 analysis allow cfengine_serverd_t init_t:file { getattr open read }; allow cfengine_serverd_t journalctl_exec_t:file getattr; allow cfengine_serverd_t ping_exec_t:file getattr; allow cfengine_serverd_t proc_net_t:file { getattr open read }; allow cfengine_serverd_t proc_net_t:lnk_file { getattr read }; allow cfengine_serverd_t proc_security_t:file { getattr open read }; allow cfengine_serverd_t rpm_exec_t:file getattr; allow cfengine_serverd_t self:process setrlimit; allow cfengine_serverd_t self:tcp_socket { accept listen }; allow cfengine_serverd_t shadow_t:file getattr; allow cfengine_serverd_t systemd_systemctl_exec_t:file getattr; allow cfengine_serverd_t unreserved_port_t:tcp_socket name_bind; allow cfengine_serverd_t user_cron_spool_t:dir getattr; allow cfengine_serverd_t useradd_exec_t:file getattr; allow cfengine_serverd_t var_t:dir read; allow cfengine_serverd_t semanage_exec_t:file getattr; allow cfengine_serverd_t ssh_exec_t:file getattr; #============= cfengine_hub_t ============== type cfengine_hub_t; typeattribute cfengine_hub_t domain; role system_r types cfengine_hub_t; # /var/cfengine/bin/cf-hub has the 'cfengine_hub_exec_t' context which is an # entrypoint for the 'cfengine_hub_t' domain type cfengine_hub_exec_t; typeattribute cfengine_hub_exec_t entry_type; typeattribute cfengine_hub_exec_t exec_type; typeattribute cfengine_hub_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_hub_exec_t; type_transition init_t cfengine_hub_exec_t:process cfengine_hub_t; allow init_t cfengine_hub_t:process transition; allow init_t cfengine_hub_exec_t:file { execute open read }; allow init_t cfengine_hub_t:process siginh; allow cfengine_hub_t cfengine_hub_exec_t:file entrypoint; allow cfengine_hub_t cfengine_hub_exec_t:file { ioctl read getattr lock map execute open }; # the following file permissions for cf-hub are not needed if masterfiles includes fixes from ENT-12954 making inventory and paths standard library bundles agent instead of common. allow cfengine_hub_t fsadm_exec_t:file getattr; allow cfengine_hub_t lvm_exec_t:file getattr; # allow cf-hub to use/execute libpromises.so allow cfengine_hub_t cfengine_var_lib_t:file map; allow cfengine_hub_t cfengine_var_lib_t:file execute; allow cfengine_hub_t cfengine_var_lib_t:file { getattr open read }; # allow cf-hub to read/write from/to a socket owned by cf-serverd (passed in # case of call-collect) allow cfengine_hub_t cfengine_serverd_t:tcp_socket { read write setopt }; allow cfengine_hub_t cfengine_agent_exec_t:file getattr; allow cfengine_hub_t cfengine_execd_exec_t:file getattr; allow cfengine_hub_t cfengine_monitord_exec_t:file getattr; allow cfengine_hub_t cfengine_serverd_exec_t:file getattr; allow cfengine_hub_t cfengine_reactor_exec_t:file getattr; allow cfengine_hub_t cfengine_postgres_t:unix_stream_socket connectto; allow cfengine_hub_t unreserved_port_t:tcp_socket name_connect; allow cfengine_hub_t cfengine_log_t:dir getattr; allow cfengine_hub_t cfengine_var_lib_t:dir { add_name create getattr open read search write remove_name }; allow cfengine_hub_t cfengine_var_lib_t:file { create ioctl lock write unlink }; allow cfengine_hub_t cfengine_var_lib_t:lnk_file { getattr read }; allow cfengine_hub_t cfengine_var_lib_t:sock_file { create unlink }; allow cfengine_hub_t bin_t:file map; allow cfengine_hub_t bin_t:file { execute execute_no_trans }; allow cfengine_hub_t cert_t:dir { getattr open read search }; allow cfengine_hub_t cert_t:file { getattr open read }; allow cfengine_hub_t crontab_exec_t:file getattr; allow cfengine_hub_t devlog_t:lnk_file read; allow cfengine_hub_t devlog_t:sock_file write; allow cfengine_hub_t dmidecode_exec_t:file getattr; allow cfengine_hub_t fs_t:filesystem getattr; allow cfengine_hub_t groupadd_exec_t:file getattr; allow cfengine_hub_t hostname_exec_t:file getattr; allow cfengine_hub_t init_exec_t:file getattr; allow cfengine_hub_t init_t:dir { getattr open read search }; allow cfengine_hub_t init_t:file { getattr open read }; allow cfengine_hub_t init_t:unix_stream_socket { ioctl getattr read write }; # systemd, PAM? allow cfengine_hub_t init_var_run_t:dir search; allow cfengine_hub_t journalctl_exec_t:file getattr; allow cfengine_hub_t kernel_t:unix_dgram_socket sendto; allow cfengine_hub_t net_conf_t:file { getattr open read }; allow cfengine_hub_t passwd_file_t:file { getattr open read }; allow cfengine_hub_t ping_exec_t:file getattr; allow cfengine_hub_t proc_net_t:file { getattr open read }; allow cfengine_hub_t proc_net_t:lnk_file { getattr read }; allow cfengine_hub_t proc_security_t:file { getattr open read }; allow cfengine_hub_t proc_t:dir read; allow cfengine_hub_t rpm_exec_t:file getattr; allow cfengine_hub_t self:capability dac_override; allow cfengine_hub_t self:tcp_socket { connect create getopt setopt read write }; allow cfengine_hub_t self:udp_socket { connect create getattr ioctl setopt read write }; allow cfengine_hub_t self:netlink_route_socket { create getopt setopt bind getattr read write }; allow cfengine_hub_t self:unix_dgram_socket { create connect read write }; allow cfengine_hub_t semanage_exec_t:file getattr; allow cfengine_hub_t shadow_t:file getattr; allow cfengine_hub_t sssd_public_t:dir search; allow cfengine_hub_t sssd_public_t:file map; allow cfengine_hub_t sssd_public_t:file { getattr open read }; allow cfengine_hub_t sssd_t:unix_stream_socket connectto; allow cfengine_hub_t sssd_var_lib_t:dir search; allow cfengine_hub_t sssd_var_lib_t:sock_file write; allow cfengine_hub_t sysctl_net_t:dir search; allow cfengine_hub_t sysfs_t:dir read; allow cfengine_hub_t sysfs_t:file { getattr open read }; allow cfengine_hub_t syslogd_var_run_t:dir search; allow cfengine_hub_t systemd_systemctl_exec_t:file getattr; allow cfengine_hub_t tmp_t:sock_file write; allow cfengine_hub_t user_cron_spool_t:dir getattr; allow cfengine_hub_t useradd_exec_t:file getattr; allow cfengine_hub_t var_t:dir read; allow cfengine_hub_t ssh_exec_t:file getattr; # Use of the TLS kernel module allow cfengine_hub_t kernel_t:system module_request; # TODO: these should not be needed # this is a macro invocation, the file has to be processed with # make -f /usr/share/selinux/devel/Makefile sysnet_domtrans_ifconfig(cfengine_hub_t) allow cfengine_hub_t shell_exec_t:file map; allow cfengine_hub_t shell_exec_t:file { execute execute_no_trans }; allow cfengine_hub_t proc_xen_t:dir search; #============= cfengine_postgres_t ============== type cfengine_postgres_t; typeattribute cfengine_postgres_t domain; role system_r types cfengine_postgres_t; # /var/cfengine/bin/cf-postgres has the 'cfengine_postgres_exec_t' context which is an # entrypoint for the 'cfengine_postgres_t' domain type cfengine_postgres_exec_t; typeattribute cfengine_postgres_exec_t entry_type; typeattribute cfengine_postgres_exec_t exec_type; typeattribute cfengine_postgres_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_postgres_exec_t; type_transition init_t cfengine_postgres_exec_t:process cfengine_postgres_t; allow init_t cfengine_postgres_t:process transition; allow init_t cfengine_postgres_exec_t:file { execute open read }; allow init_t cfengine_postgres_t:process siginh; allow cfengine_postgres_t cfengine_postgres_exec_t:file entrypoint; allow cfengine_postgres_t cfengine_postgres_exec_t:file { ioctl read getattr lock map execute open }; # TODO: Why are 'map', 'execute' and 'execute_no_trans' needed for postgres? allow cfengine_postgres_t cfengine_var_lib_t:file map; allow cfengine_postgres_t cfengine_var_lib_t:file { create execute execute_no_trans getattr link open read rename unlink write rename }; allow cfengine_postgres_t cfengine_var_lib_t:lnk_file read; allow cfengine_postgres_t cfengine_var_lib_t:dir { add_name getattr open create read remove_name search write }; allow cfengine_postgres_t postgresql_port_t:tcp_socket name_bind; allow cfengine_postgres_t cert_t:dir { getattr open read search }; allow cfengine_postgres_t cert_t:file { getattr open read }; allow cfengine_postgres_t hugetlbfs_t:file map; allow cfengine_postgres_t hugetlbfs_t:file { read write }; allow cfengine_postgres_t init_t:unix_stream_socket { getattr ioctl read write }; # pg_ctl, systemd, PAM? allow cfengine_postgres_t init_var_run_t:dir search; allow cfengine_postgres_t system_dbusd_var_run_t:dir search; allow cfengine_postgres_t net_conf_t:file { getattr open read }; allow cfengine_postgres_t node_t:tcp_socket node_bind; allow cfengine_postgres_t node_t:udp_socket node_bind; allow cfengine_postgres_t proc_t:file { getattr open read }; allow cfengine_postgres_t self:netlink_route_socket { bind create getattr nlmsg_read read write }; allow cfengine_postgres_t self:tcp_socket { bind create listen setopt read write }; allow cfengine_postgres_t self:udp_socket { bind connect create getattr getopt read write }; allow cfengine_postgres_t self:unix_stream_socket connectto; allow cfengine_postgres_t sssd_public_t:dir search; allow cfengine_postgres_t sssd_public_t:file map; allow cfengine_postgres_t sssd_public_t:file { getattr open read }; allow cfengine_postgres_t sssd_var_lib_t:sock_file write; allow cfengine_postgres_t sssd_var_lib_t:dir search; allow cfengine_postgres_t sssd_t:unix_stream_socket connectto; allow cfengine_postgres_t tmp_t:dir { add_name write remove_name }; allow cfengine_postgres_t tmp_t:file { create open write unlink }; allow cfengine_postgres_t tmp_t:sock_file { create setattr unlink write }; allow cfengine_postgres_t tmpfs_t:dir { add_name write remove_name }; allow cfengine_postgres_t tmpfs_t:file { create open read write map unlink getattr }; allow cfengine_postgres_t tmpfs_t:filesystem getattr; allow cfengine_postgres_t var_log_t:file { append open }; # so that PostgreSQL can check if cfpostgres user/group exists allow cfengine_postgres_t passwd_file_t:file { open read getattr }; # Needed for systemd to be able to check PostgreSQL's PID file allow init_t cfengine_var_lib_t:dir { read remove_name write }; allow init_t cfengine_var_lib_t:file { getattr open read unlink ioctl }; # TODO: these should not be needed allow cfengine_postgres_t shell_exec_t:file map; allow cfengine_postgres_t shell_exec_t:file { execute execute_no_trans }; #============= cfengine_httpd_t ============== type cfengine_httpd_t; typeattribute cfengine_httpd_t domain; role system_r types cfengine_httpd_t; # /var/cfengine/httpd/bin/* files have the 'cfengine_httpd_exec_t' context which # is an entrypoint for the 'cfengine_httpd_t' domain type cfengine_httpd_exec_t; typeattribute cfengine_httpd_exec_t entry_type; typeattribute cfengine_httpd_exec_t exec_type; typeattribute cfengine_httpd_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_httpd_exec_t; type_transition init_t cfengine_httpd_exec_t:process cfengine_httpd_t; allow init_t cfengine_httpd_t:process transition; allow init_t cfengine_httpd_exec_t:file { execute getattr open read }; allow init_t cfengine_httpd_t:process siginh; allow cfengine_httpd_t cfengine_httpd_exec_t:file entrypoint; allow cfengine_httpd_t cfengine_httpd_exec_t:file { ioctl read getattr lock map execute open }; allow cfengine_httpd_t cert_t:dir { getattr open read search }; allow cfengine_httpd_t cert_t:file { getattr open read }; allow cfengine_httpd_t cert_t:lnk_file read; allow cfengine_httpd_t cfengine_httpd_exec_t:file execute_no_trans; allow cfengine_httpd_t cfengine_postgres_t:unix_stream_socket connectto; # allow httpd to use our custom compiled module allow cfengine_httpd_t cfengine_var_lib_t:file map; allow cfengine_httpd_t cfengine_var_lib_t:file { append create execute getattr ioctl lock open read setattr unlink write rename }; allow cfengine_httpd_t cfengine_var_lib_t:dir { add_name getattr open read remove_name search write create }; allow cfengine_httpd_t cfengine_var_lib_t:lnk_file read; # allow httpd/php to work with cf-execd sockets allow cfengine_httpd_t cfengine_execd_t:unix_stream_socket connectto; allow cfengine_httpd_t cfengine_var_lib_t:sock_file write; # allow httpd/php to upload notification/alert scripts allow cfengine_httpd_t cfengine_action_script_exec_t:dir { add_name getattr search write remove_name }; allow cfengine_httpd_t cfengine_action_script_exec_t:file { create write setattr unlink }; # sending reports via email allow cfengine_httpd_t postfix_etc_t:dir { getattr open read search }; allow cfengine_httpd_t postfix_etc_t:file { getattr open read }; allow cfengine_httpd_t postfix_master_t:unix_stream_socket connectto; allow cfengine_httpd_t postfix_postdrop_exec_t:file { execute execute_no_trans map open read }; allow cfengine_httpd_t postfix_public_t:dir search; allow cfengine_httpd_t postfix_public_t:sock_file { getattr write }; allow cfengine_httpd_t postfix_spool_t:dir { add_name remove_name search write }; allow cfengine_httpd_t postfix_spool_t:file { create getattr open read rename setattr write }; allow cfengine_httpd_t self:process setrlimit; allow cfengine_httpd_t sendmail_exec_t:file { execute execute_no_trans getattr map open read }; allow cfengine_httpd_t devlog_t:lnk_file read; allow cfengine_httpd_t devlog_t:sock_file write; allow cfengine_httpd_t http_port_t:tcp_socket { name_bind name_connect }; allow cfengine_httpd_t init_t:dbus send_msg; allow cfengine_httpd_t init_t:unix_stream_socket { getattr ioctl read write }; # apachectl allow cfengine_httpd_t init_var_run_t:dir search; allow cfengine_httpd_t kernel_t:unix_dgram_socket sendto; allow cfengine_httpd_t net_conf_t:file { getattr open read }; allow cfengine_httpd_t node_t:tcp_socket node_bind; allow cfengine_httpd_t self:capability { dac_override dac_read_search kill net_bind_service setgid setuid net_admin }; allow cfengine_httpd_t self:netlink_route_socket { bind create getattr nlmsg_read read write }; allow cfengine_httpd_t self:process execmem; allow cfengine_httpd_t unconfined_t:process signull; allow cfengine_httpd_t self:tcp_socket { accept bind connect create getattr getopt listen setopt shutdown read write ioctl setattr append name_connect }; allow cfengine_httpd_t self:udp_socket { create ioctl read getattr write setattr append connect getopt setopt shutdown setattr }; allow cfengine_httpd_t self:unix_dgram_socket { connect create }; allow cfengine_httpd_t sssd_public_t:dir search; allow cfengine_httpd_t sssd_public_t:file map; allow cfengine_httpd_t sssd_public_t:file { getattr open read }; allow cfengine_httpd_t sssd_t:unix_stream_socket connectto; allow cfengine_httpd_t sssd_var_lib_t:dir search; allow cfengine_httpd_t sssd_var_lib_t:sock_file write; allow cfengine_httpd_t syslogd_var_run_t:dir search; allow cfengine_httpd_t tmp_t:sock_file write; allow cfengine_httpd_t tmp_t:file { create setattr unlink write rename open }; allow cfengine_httpd_t tmp_t:dir { add_name remove_name write read }; allow cfengine_httpd_t var_t:dir read; # apparently, httpd creates some temporary bits in /tmp that it needs to mmap() allow cfengine_httpd_t tmp_t:file map; # httpd/PHP needs to be able to send emails via an external SMTP server allow cfengine_httpd_t smtp_port_t:tcp_socket name_connect; # httpd/PHP needs to be able to contact LDAP servers allow cfengine_httpd_t ldap_port_t:tcp_socket name_connect; # Bidirectional DBus communication between httpd and systemd allow cfengine_httpd_t system_dbusd_t:dbus send_msg; allow cfengine_httpd_t system_dbusd_t:unix_stream_socket connectto; allow cfengine_httpd_t system_dbusd_var_run_t:dir search; allow cfengine_httpd_t system_dbusd_var_run_t:sock_file write; allow init_t cfengine_httpd_t:dbus send_msg; # allow httpd to run 'ps' and thus gather information about all running processes on the system # this is a macro invocation, the file has to be processed with # make -f /usr/share/selinux/devel/Makefile ps_process_pattern(cfengine_httpd_t, domain) allow cfengine_httpd_t bin_t:file { map execute execute_no_trans }; allow cfengine_httpd_t proc_t:dir read; allow cfengine_httpd_t proc_t:file { open read }; # TODO: these should not be needed allow cfengine_httpd_t passwd_file_t:file { getattr open read }; allow cfengine_httpd_t shell_exec_t:file map; allow cfengine_httpd_t shell_exec_t:file { execute execute_no_trans }; #============= cfengine_apachectl_t ============== type cfengine_apachectl_t; typeattribute cfengine_apachectl_t domain; role system_r types cfengine_apachectl_t; # /var/cfengine/httpd/bin/apachectl has the 'cfengine_apachectl_exec_t' context which # is an entrypoint for the 'cfengine_apachectl_t' domain type cfengine_apachectl_exec_t; typeattribute cfengine_apachectl_exec_t entry_type; typeattribute cfengine_apachectl_exec_t exec_type; typeattribute cfengine_apachectl_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_apachectl_exec_t; # allow transitions from init_t (systemd) to cfengine_apachectl_t to cfengine_httpd_t type_transition init_t cfengine_apachectl_exec_t:process cfengine_apachectl_t; allow init_t cfengine_apachectl_t:process transition; allow init_t cfengine_apachectl_exec_t:file { execute getattr open read }; allow init_t cfengine_apachectl_t:process siginh; type_transition cfengine_apachectl_t cfengine_httpd_exec_t:process cfengine_httpd_t; allow cfengine_apachectl_t cfengine_httpd_t:process transition; allow cfengine_apachectl_t cfengine_httpd_exec_t:file { execute getattr open read }; allow cfengine_apachectl_t cfengine_httpd_t:process siginh; allow cfengine_apachectl_t cfengine_apachectl_exec_t:file entrypoint; allow cfengine_apachectl_t cfengine_apachectl_exec_t:file { ioctl read getattr lock map execute open }; allow cfengine_apachectl_t cfengine_var_lib_t:dir search; allow cfengine_apachectl_t cfengine_var_lib_t:file { getattr open read }; allow cfengine_apachectl_t init_t:unix_stream_socket ioctl; allow cfengine_apachectl_t passwd_file_t:file { getattr open read }; allow cfengine_apachectl_t shell_exec_t:file { map execute }; allow cfengine_apachectl_t sssd_public_t:dir search; allow cfengine_apachectl_t sssd_public_t:file { getattr open read map }; allow cfengine_apachectl_t sssd_t:unix_stream_socket connectto; allow cfengine_apachectl_t sssd_var_lib_t:dir search; allow cfengine_apachectl_t sssd_var_lib_t:sock_file write; allow cfengine_apachectl_t bin_t:file { execute execute_no_trans map }; allow cfengine_apachectl_t proc_t:dir read; allow cfengine_apachectl_t proc_t:file { open read }; # allow apachectl to run 'ps' and thus gather information about all running processes on the system # this is a macro invocation, the file has to be processed with # make -f /usr/share/selinux/devel/Makefile ps_process_pattern(cfengine_apachectl_t, domain) # ps_process_pattern() above doesn't include needed sys_ptrace capability for apachectl to run 'ps' allow cfengine_apachectl_t self:cap_userns sys_ptrace; #============= cfengine_reactor_t ============== type cfengine_reactor_t; typeattribute cfengine_reactor_t domain; role system_r types cfengine_reactor_t; # /var/cfengine/bin/cf-reactor has the 'cfengine_reactor_exec_t' context which is an # entrypoint for the 'cfengine_reactor_t' domain type cfengine_reactor_exec_t; typeattribute cfengine_reactor_exec_t entry_type; typeattribute cfengine_reactor_exec_t exec_type; typeattribute cfengine_reactor_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_reactor_exec_t; type_transition init_t cfengine_reactor_exec_t:process cfengine_reactor_t; allow init_t cfengine_reactor_t:process transition; allow init_t cfengine_reactor_exec_t:file { execute open read }; allow init_t cfengine_reactor_t:process siginh; type_transition cfengine_reactor_t cfengine_cfbs_exec_t:process cfengine_cfbs_t; allow cfengine_reactor_t cfengine_cfbs_t:process transition; allow cfengine_reactor_t cfengine_cfbs_exec_t:file { execute open read }; # cf-reactor runs PHP code to evaluate alerts (as cfapache user) allow cfengine_reactor_t cfengine_httpd_exec_t:file { execute execute_no_trans getattr open read map }; allow cfengine_reactor_t self:capability { setgid setuid }; allow cfengine_reactor_t self:process { execmem setrlimit }; allow cfengine_reactor_t cfengine_reactor_exec_t:file entrypoint; allow cfengine_reactor_t cfengine_reactor_exec_t:file { ioctl read getattr lock map execute open }; # allow cf-reactor to use/execute libpromises.so allow cfengine_reactor_t cfengine_var_lib_t:file map; allow cfengine_reactor_t cfengine_var_lib_t:file execute; allow cfengine_reactor_t cfengine_var_lib_t:file { getattr open read }; allow cfengine_reactor_t cfengine_postgres_t:unix_stream_socket connectto; allow cfengine_reactor_t cfengine_log_t:dir getattr; allow cfengine_reactor_t cfengine_var_lib_t:dir { add_name getattr create open read search write remove_name setattr rmdir }; allow cfengine_reactor_t cfengine_var_lib_t:file { create ioctl lock write unlink append setattr link rename execute execute_no_trans }; allow cfengine_reactor_t cfengine_var_lib_t:lnk_file { getattr read create unlink }; allow cfengine_reactor_t passwd_file_t:file { open read getattr }; allow cfengine_reactor_t self:capability { dac_override dac_read_search chown fsetid }; allow cfengine_reactor_t self:unix_dgram_socket { create connect }; allow cfengine_reactor_t sssd_var_lib_t:dir search; allow cfengine_reactor_t sssd_var_lib_t:sock_file write; allow cfengine_reactor_t sssd_public_t:dir search; allow cfengine_reactor_t sssd_public_t:file { open read getattr map }; allow cfengine_reactor_t sssd_t:unix_stream_socket connectto; allow cfengine_reactor_t tmp_t:sock_file write; allow cfengine_reactor_t tmp_t:dir { add_name remove_name read write }; allow cfengine_reactor_t tmp_t:file { create open setattr unlink write }; allow cfengine_reactor_t devlog_t:sock_file write; allow cfengine_reactor_t devlog_t:lnk_file read; allow cfengine_reactor_t syslogd_var_run_t:dir search; allow cfengine_reactor_t kernel_t:unix_dgram_socket sendto; allow cfengine_reactor_t kernel_t:unix_stream_socket connectto; allow cfengine_reactor_t init_var_run_t:dir search; allow cfengine_reactor_t init_t:unix_stream_socket { getattr ioctl }; allow cfengine_reactor_t var_t:dir read; allow cfengine_reactor_t bin_t:file { execute execute_no_trans map }; allow cfengine_reactor_t fs_t:filesystem getattr; allow cfengine_reactor_t shell_exec_t:file map; allow cfengine_reactor_t shell_exec_t:file { execute execute_no_trans }; allow cfengine_reactor_t cert_t:dir { getattr open read search }; allow cfengine_reactor_t cert_t:file { getattr open read }; allow cfengine_reactor_t cert_t:lnk_file read; allow cfengine_reactor_t http_port_t:tcp_socket name_connect; allow cfengine_reactor_t net_conf_t:file { getattr open read }; allow cfengine_reactor_t self:netlink_route_socket { bind create getattr nlmsg_read read write }; allow cfengine_reactor_t self:tcp_socket { create ioctl read getattr write setattr append connect getopt setopt shutdown name_connect }; allow cfengine_reactor_t self:udp_socket { create ioctl read getattr write setattr append connect getopt setopt shutdown }; allow cfengine_reactor_t self:unix_stream_socket connectto; allow cfengine_reactor_t ssh_exec_t:file map; allow cfengine_reactor_t ssh_exec_t:file { execute execute_no_trans getattr open read }; allow cfengine_reactor_t ssh_home_t:dir { getattr search }; allow cfengine_reactor_t ssh_port_t:tcp_socket name_connect; # Allow cf-reactor to run scheduled reports and send them via email allow cfengine_reactor_t postfix_etc_t:dir { getattr open read search }; allow cfengine_reactor_t postfix_etc_t:file { getattr open read }; allow cfengine_reactor_t postfix_master_t:unix_stream_socket connectto; allow cfengine_reactor_t postfix_postdrop_exec_t:file map; allow cfengine_reactor_t postfix_postdrop_exec_t:file { execute execute_no_trans open read }; allow cfengine_reactor_t postfix_public_t:dir search; allow cfengine_reactor_t postfix_public_t:sock_file { getattr write }; allow cfengine_reactor_t postfix_spool_t:dir { add_name remove_name search write }; allow cfengine_reactor_t postfix_spool_t:file { create getattr open read rename setattr write }; allow cfengine_reactor_t sendmail_exec_t:file map; allow cfengine_reactor_t sendmail_exec_t:file { execute execute_no_trans open read }; #============= cfengine_action_script_t ============== # A special type and domain for action (notification/alert) scripts executed by # PHP. They can do anything, so they need to run in an unconstrained domain. At # the same time we don't want our Apache and PHP to do anything so these scripts # cannot just run in the http_t domain. type cfengine_action_script_t; typeattribute cfengine_action_script_t domain; role system_r types cfengine_action_script_t; # this is a macro invocation, the file has to be processed with # make -f /usr/share/selinux/devel/Makefile unconfined_domain(cfengine_action_script_t) # /opt/cfengine/notification_scripts/* files have the # 'cfengine_action_script_exec_t' context which is an entrypoint for the # 'cfengine_action_script_t' domain type cfengine_action_script_exec_t; typeattribute cfengine_action_script_exec_t entry_type; typeattribute cfengine_action_script_exec_t exec_type; typeattribute cfengine_action_script_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_action_script_exec_t; # cf-apache/httpd manipulates with the action scripts allow cfengine_httpd_t cfengine_action_script_exec_t:file { getattr open read }; # cf-reactor runs alerts periodically and these can trigger custom action scripts type_transition cfengine_reactor_t cfengine_action_script_exec_t:process cfengine_action_script_t; allow cfengine_reactor_t cfengine_action_script_t:process transition; allow cfengine_reactor_t cfengine_action_script_exec_t:file { execute execute_no_trans getattr open read }; allow cfengine_reactor_t cfengine_action_script_exec_t:dir { getattr search }; allow cfengine_reactor_t cfengine_action_script_t:process siginh; allow cfengine_action_script_t cfengine_action_script_exec_t:file entrypoint; allow cfengine_action_script_t cfengine_action_script_exec_t:file { ioctl read getattr lock map execute open }; #============= cfengine_cfbs_t ============== type cfengine_cfbs_t; typeattribute cfengine_cfbs_t domain; role system_r types cfengine_cfbs_t; # /var/cfengine/bin/cf-cfbs has the 'cfengine_cfbs_exec_t' context which is an # entrypoint for the 'cfengine_cfbs_t' domain type cfengine_cfbs_exec_t; typeattribute cfengine_cfbs_exec_t entry_type; typeattribute cfengine_cfbs_exec_t exec_type; typeattribute cfengine_cfbs_exec_t file_type, non_security_file_type, non_auth_file_type; role object_r types cfengine_cfbs_exec_t; allow cfengine_cfbs_t cfengine_cfbs_exec_t:file entrypoint; allow cfengine_cfbs_t cfengine_cfbs_exec_t:file { ioctl read getattr lock map execute open }; allow cfengine_cfbs_t cfengine_var_lib_t:dir { add_name getattr create open read search write remove_name setattr }; allow cfengine_cfbs_t cfengine_var_lib_t:file { create ioctl lock write unlink append setattr link rename execute execute_no_trans map getattr open read }; allow cfengine_cfbs_t cfengine_var_lib_t:lnk_file { getattr read create unlink }; allow cfengine_cfbs_t cfengine_reactor_t:fifo_file { getattr ioctl read write }; allow cfengine_cfbs_t bin_t:file { map execute }; # cfbs runs some commands in a shell allow cfengine_cfbs_t shell_exec_t:file map; allow cfengine_cfbs_t shell_exec_t:file { execute execute_no_trans }; allow cfengine_cfbs_t cert_t:dir { getattr open read search }; allow cfengine_cfbs_t cert_t:file { getattr open read }; allow cfengine_cfbs_t cert_t:lnk_file read; allow cfengine_cfbs_t http_port_t:tcp_socket name_connect; allow cfengine_cfbs_t net_conf_t:file { getattr open read }; allow cfengine_cfbs_t passwd_file_t:file { getattr open read }; allow cfengine_cfbs_t self:capability dac_override; allow cfengine_cfbs_t self:netlink_route_socket { bind create getattr nlmsg_read read write }; allow cfengine_cfbs_t self:tcp_socket { create ioctl read getattr write setattr append connect getopt setopt shutdown name_connect }; allow cfengine_cfbs_t self:udp_socket { create ioctl read getattr write setattr append connect getopt setopt shutdown }; allow cfengine_cfbs_t sssd_public_t:dir search; allow cfengine_cfbs_t sssd_public_t:file { map getattr open read }; allow cfengine_cfbs_t sssd_t:unix_stream_socket connectto; allow cfengine_cfbs_t sssd_var_lib_t:dir search; allow cfengine_cfbs_t sssd_var_lib_t:sock_file write; #============= special rules for Federated Reporting ============= # sshd needs access to files in /opt/cfengine allow sshd_t cfengine_var_lib_t:file { getattr open read }; #============= TO REMOVE ============== # Daemons should have proper access to files based on DAC rules (file # permissions), not just because they run under root. dontaudit cfengine_execd_t self:capability dac_override; dontaudit cfengine_serverd_t self:capability { dac_override dac_read_search }; # cf-promises run by the daemons shouldn't check if a function is available in # PostgreSQL, the respective returnszero() is in an agent bundle dontaudit cfengine_execd_t cfengine_postgres_t:unix_stream_socket connectto; dontaudit cfengine_execd_t tmp_t:sock_file write; dontaudit cfengine_serverd_t cfengine_postgres_t:unix_stream_socket connectto; dontaudit cfengine_serverd_t tmp_t:sock_file write; cfengine-3.24.2/misc/selinux/Makefile.in0000644000000000000000000004567715010704301020057 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = misc/selinux ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(selinuxdir)" DATA = $(selinux_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ @WITH_SELINUX_TRUE@selinuxdir = $(prefix)/selinux @WITH_SELINUX_TRUE@selinux_DATA = cfengine-enterprise.pp \ @WITH_SELINUX_TRUE@ cfengine-enterprise.te \ @WITH_SELINUX_TRUE@ cfengine-enterprise.fc # explicit DISTFILES are required for these files to be part of a 'make dist' # tarball even without running './configure --with-selinux-policy' DISTFILES = Makefile.in Makefile.am cfengine-enterprise.fc \ cfengine-enterprise.te.all cfengine-enterprise.te.el9 CLEANFILES = cfengine-enterprise.pp cfengine-enterprise.if cfengine-enterprise.te all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu misc/selinux/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu misc/selinux/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-selinuxDATA: $(selinux_DATA) @$(NORMAL_INSTALL) @list='$(selinux_DATA)'; test -n "$(selinuxdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(selinuxdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(selinuxdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(selinuxdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(selinuxdir)" || exit $$?; \ done uninstall-selinuxDATA: @$(NORMAL_UNINSTALL) @list='$(selinux_DATA)'; test -n "$(selinuxdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(selinuxdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(selinuxdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." @WITH_SELINUX_FALSE@clean-local: clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-selinuxDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-selinuxDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-selinuxDATA install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags-am uninstall uninstall-am uninstall-selinuxDATA .PRECIOUS: Makefile @WITH_SELINUX_TRUE@cfengine-enterprise.te: cfengine-enterprise.te.all $(PLATFORM_SELINUX_POLICIES) @WITH_SELINUX_TRUE@ cat cfengine-enterprise.te.all $(PLATFORM_SELINUX_POLICIES) > cfengine-enterprise.te @WITH_SELINUX_TRUE@cfengine-enterprise.pp: cfengine-enterprise.te cfengine-enterprise.fc @WITH_SELINUX_TRUE@ $(MAKE) -f /usr/share/selinux/devel/Makefile -j1 @WITH_SELINUX_TRUE@clean-local: @WITH_SELINUX_TRUE@ rm -rf tmp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/misc/selinux/cfengine-enterprise.fc0000644000000000000000000000225415010704253022246 0ustar00rootroot00000000000000/var/cfengine/bin/cf-execd -- gen_context(system_u:object_r:cfengine_execd_exec_t,s0) /var/cfengine/bin/cf-serverd -- gen_context(system_u:object_r:cfengine_serverd_exec_t,s0) /var/cfengine/bin/cf-monitord -- gen_context(system_u:object_r:cfengine_monitord_exec_t,s0) /var/cfengine/bin/cf-agent -- gen_context(system_u:object_r:cfengine_agent_exec_t,s0) /var/cfengine/bin/cf-hub -- gen_context(system_u:object_r:cfengine_hub_exec_t,s0) /var/cfengine/bin/cf-reactor -- gen_context(system_u:object_r:cfengine_reactor_exec_t,s0) /var/cfengine/bin/cfbs -- gen_context(system_u:object_r:cfengine_cfbs_exec_t,s0) /var/cfengine/bin/pg.* -- gen_context(system_u:object_r:cfengine_postgres_exec_t,s0) /var/cfengine/httpd/bin/apachectl -- gen_context(system_u:object_r:cfengine_apachectl_exec_t,s0) /var/cfengine/httpd/bin/.* -- gen_context(system_u:object_r:cfengine_httpd_exec_t,s0) /var/cfengine/httpd/php/bin/.* -- gen_context(system_u:object_r:cfengine_httpd_exec_t,s0) /opt/cfengine(/.*)? gen_context(system_u:object_r:cfengine_var_lib_t,s0) /opt/cfengine/notification_scripts(/.*)? gen_context(system_u:object_r:cfengine_action_script_exec_t,s0) cfengine-3.24.2/misc/selinux/cfengine-enterprise.te.el90000644000000000000000000000147015010704253022755 0ustar00rootroot00000000000000require { type systemd_userdbd_runtime_t; type http_port_t; } # PAM module for dynamic users allow cfengine_httpd_t systemd_userdbd_runtime_t:dir { getattr open read search }; allow cfengine_httpd_t systemd_userdbd_runtime_t:sock_file write; allow cfengine_httpd_t kernel_t:unix_stream_socket connectto; allow cfengine_reactor_t systemd_userdbd_runtime_t:dir { getattr open read search }; allow cfengine_reactor_t systemd_userdbd_runtime_t:sock_file write; # selinux-policy 38.1.45 requires the following http_port permissions whereas 3.14.3 does not. # these permissions are not be needed if changes from ENT-12954 to masterfiles policy move inventory from common to an agent bundle are in place. allow cfengine_serverd_t http_port_t:tcp_socket name_connect; allow cfengine_execd_t http_port_t:tcp_socket name_connect; cfengine-3.24.2/misc/init.d/0000755000000000000000000000000015010704322015470 5ustar00rootroot00000000000000cfengine-3.24.2/misc/init.d/cfengine3.in0000644000000000000000000004556515010704253017703 0ustar00rootroot00000000000000#!/bin/sh # # cfengine3 # # # Created by Nakarin Phooripoom on 22/6/2011. # Copyright 2021 Northern.tech AS. # ### BEGIN INIT INFO # Provides: cfengine3 # Required-Start: $local_fs $remote_fs $network $time # Required-Stop: $local_fs $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: GNU configuration engine # Description: Tool for configuring and maintaining network machines ### END INIT INFO # # chkconfig: 2345 60 40 # description: Starts the cfengine daemons for remote and periodic \ # execution of cfengine and for environment monitoring. # set -e # # Detect and replace non-POSIX shell # try_exec() { type "$1" > /dev/null 2>&1 && exec "$@" } broken_posix_shell() { unset foo local foo=1 test "$foo" != "1" } if broken_posix_shell >/dev/null 2>&1; then try_exec /usr/xpg4/bin/sh "$0" "$@" echo "No compatible shell script interpreter found." echo "Please find a POSIX shell for your system." exit 42 fi ##### start: Defined variables and conditios ##### PREFIX=${CFTEST_PREFIX:-@workdir@} INPUTDIR=@inputdir@ if [ "$INPUTDIR" = "default" ]; then INPUTDIR="$PREFIX/inputs" fi CFEXECD=${CFTEST_CFEXECD:-$PREFIX/bin/cf-execd} CFSERVD=${CFTEST_CFSERVD:-$PREFIX/bin/cf-serverd} CFMOND=${CFTEST_CFMOND:-$PREFIX/bin/cf-monitord} CFAGENT=${CFTEST_CFAGENT:-$PREFIX/bin/cf-agent} PIDFILE_TEMPLATE=$PREFIX/%s.pid STOP_ATTEMPTS=6 # From which point we start using SIGKILL. KILL_THRESHOLD=4 FORCE_KILL=0 CFENTERPRISE_INITD=$PREFIX/bin/cfengine3-nova-hub-init-d.sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PREFIX/bin # ensure that we use RPATH/loader entries from our binaries and not from the environment unset LIBPATH # AIX < 5.3 unset LD_LIBRARY_PATH # Has the package been 'removed' but not purged? test -f $CFEXECD || exit 0 # default is no OS SUSE=0 REDHAT=0 DEBIAN=0 # SuSE if [ -d /var/lock/subsys ] && [ -f /usr/bin/zypper ]; then SUSE=1 fi # RedHat4/RedHat5/CentOS/Fedora if [ -f /usr/bin/yum ] || [ -f /usr/sbin/up2date ]; then if [ -d /var/lock/subsys ]; then REDHAT=1 fi fi # Debian/Ubuntu if [ -f /etc/debian_version ] && [ -f /usr/bin/apt-get ]; then DEBIAN=1 if [ -d /run/lock ]; then LOCKDIR=/run/lock else LOCKDIR=/var/lock fi fi if [ -z "$LOCKDIR" ]; then LOCKDIR=/var/lock fi # default control file if [ "$DEBIAN" = "1" ]; then DEFAULT=/etc/default/cfengine3 INIT_FUNCTIONS=/lib/lsb/init-functions if [ -e "$INIT_FUNCTIONS" ]; then . "$INIT_FUNCTIONS" fi else DEFAULT=/etc/sysconfig/cfengine3 fi if [ -f $DEFAULT ]; then . $DEFAULT else RUN_CF_EXECD=1 RUN_CF_SERVERD=1 RUN_CF_MONITORD=1 fi # Check /sbin/startproc for SUSE if [ -x /sbin/startproc ] && [ -f /etc/rc.status ]; then . /etc/rc.status rc_reset PROC=1 else PROC=0 fi # Source function library. (Redhat/Centos/Fedora) if [ -f /usr/bin/yum ] && [ -f /etc/rc.d/init.d/functions ]; then . /etc/rc.d/init.d/functions FUNC=1 else FUNC=0 fi # Check something for Debian/Ubuntu if [ -x /sbin/start-stop-daemon ]; then SSD=1 else SSD=0 fi CURRENT_PS_UID=__none__ INSIDE_CONTAINER=-1 if ps --help 2>/dev/null | egrep -e '--cols\b' > /dev/null || ps --help output 2>/dev/null | egrep -e '--cols\b'; then # There is a bug in SUSE which means that ps output will be truncated even # when piped to grep, if the terminal size is small. However using --cols # will override it. NOTE: On Suse 12 and 15, `ps` mentions `--cols` only # in `ps --help output` only. PS_OPTIONS="--cols 200" else PS_OPTIONS= fi OS="$(uname)" ##### end: Defined variables and conditions ##### ##### start: Defined functions ##### # Takes a process string to match and returns a list of PIDs. # Argument can optionally be preceded by "--ignore-user" to disable matching of # the calling user's UID. cf_get_matching_pids() { # "ps" is an extremely incompatible tool, with differing options and output # format almost everywhere. However, some things we can rely on: "ps -ef" # seems to be supported everywhere, and we can usually rely on UID being the # first field, PID and PPID the second and third, and command line the last # field. In between there is a mess, and we stay away from it. We use this # to match against the UID of the calling user. # # We also do some much more non-portable operations to try to avoid # processes inside containers. if [ "$CURRENT_PS_UID" = "__none__" ]; then CURRENT_PS_UID="$(ps $PS_OPTIONS -ef |egrep "^ *[^ ]+ +$$ "|awk -F' ' '{print $1}')" fi if [ $INSIDE_CONTAINER = -1 ]; then # Are we inside a container? if [ -f /proc/self/cgroup ] && sed 's_/\(-\|system\|user\).slice__;s_/user-[0-9]*.slice__;s_/session-[0-9]*.scope__;s_/cfengine3.service__' /proc/self/cgroup | egrep '[0-9]+:devices:/[^:]' > /dev/null; then INSIDE_CONTAINER=1 else INSIDE_CONTAINER=0 fi fi local ignore_user=0 if [ "$1" = "--ignore-user" ]; then ignore_user=1 shift fi case "$OS" in SunOS) local user_flag=-U local user_string="$CURRENT_PS_UID" if [ $ignore_user = 1 ]; then user_flag= user_string= fi if [ -x /usr/bin/zonename ];then /usr/bin/pgrep -f -z "$(/usr/bin/zonename)" $user_flag "$user_string" "$1" else /usr/bin/pgrep -f $user_flag "$user_string" "$1" fi ;; *) local user_string="$CURRENT_PS_UID" if [ $ignore_user = 1 ]; then # Match any user. user_string="[^ ]+" fi local pids="$(ps $PS_OPTIONS -ef|grep -v grep|egrep "^ *$user_string .*$1"|awk -F' ' '{print $2}')" for pid in $pids; do # If the last character of the cgroup is not the root directory, # then this is a container process. if [ -f /proc/$pid/cgroup ] && sed 's_/\(-\|system\|user\).slice__;s_/user-[0-9]*.slice__;s_/session-[0-9]*.scope__;s_/cfengine3.service__;s_/cf-execd.service__;s_/cf-serverd.service__;s_/cf-monitord.service__' /proc/$pid/cgroup | egrep '[0-9]+:devices:/[^:]' > /dev/null; then if [ $INSIDE_CONTAINER = 1 ]; then echo $pid fi else if [ $INSIDE_CONTAINER = 0 ]; then echo $pid fi fi done ;; esac } cf_pidfile_pid() { local pidfile="$1" if egrep -v '^ *[0-9]+ *$' "$pidfile" > /dev/null 2>&1; then echo "Malformed PID file: $pidfile." 1>&2 elif [ -f "$pidfile" ]; then cat "$pidfile" fi } cf_get_daemon_pid() { local daemon="$1" local base_daemon="$(basename "$daemon")" local pidfile="$(printf "$PIDFILE_TEMPLATE" "$base_daemon")" local pidfile_pid local matching_pids # Try to get the PID of the daemon process from the pidfile and make sure it # is valid. pidfile_pid="$(cf_pidfile_pid "$pidfile")" matching_pids="$(cf_get_matching_pids "$base_daemon")" if [ -n "$pidfile_pid" ]; then if echo "$matching_pids" | grep "^$pidfile_pid\$" >/dev/null; then # A valid PID from the pidfile, let's report it. echo "$pidfile_pid" return else # PID from the pid file not in the matching pids -> must be a # leftover. Let's remove it. rm -f "$pidfile" fi; fi; # No or invalid pidfile, let's report the matching PIDs. echo "$matching_pids" } cf_start_daemon() { local daemon="$1" shift local base_daemon="$(basename "$daemon")" echo -n "Starting $base_daemon..." # Redhat/Centos/Fedora if [ "$REDHAT" = "1" ] && [ "$FUNC" = "1" ]; then daemon "$daemon" "$@" cf_touch "/var/lock/subsys/$base_daemon" cf_touch "/var/lock/subsys/cfengine3" elif [ "$REDHAT" = "1" ] && [ "$FUNC" = "0" ]; then "$daemon" "$@" cf_touch "/var/lock/subsys/$base_daemon" cf_touch "/var/lock/subsys/cfengine3" # SUSE elif [ "$SUSE" = "1" ] && [ "$PROC" = "1" ]; then /sbin/startproc "$daemon" "$@" rc_status -v cf_touch "/var/run/$base_daemon.pid" elif [ "$SUSE" = "1" ] && [ "$PROC" = "0" ]; then "$daemon" "$@" cf_touch "/var/run/$base_daemon.pid" # Debian/Ubuntu elif [ "$DEBIAN" = "1" ] && [ "$SSD" = "1" ]; then /sbin/start-stop-daemon --start --pidfile "$(printf "$PIDFILE_TEMPLATE" "$base_daemon")" --exec "$daemon" -- "$@" cf_touch "$LOCKDIR/$base_daemon" elif [ "$DEBIAN" = "1" ] && [ "$SSD" = "0" ]; then "$daemon" "$@" cf_touch "$LOCKDIR/$base_daemon" # All others else "$daemon" "$@" fi echo } # Return 0 if any daemon was attempted killed, 1 otherwise. cf_stop_daemon() { local daemon="$1" local base_daemon="$(basename "$daemon")" local pidfile="$(printf "$PIDFILE_TEMPLATE" "$base_daemon")" local pids local ret=1 pids="$(cf_get_daemon_pid $daemon)" if [ -z "$pids" ]; then return 1 fi echo "Shutting down $base_daemon..." local iter=1 local signal=TERM while [ $iter -le $STOP_ATTEMPTS ] && [ -n "$pids" ]; do ret=0 if [ $iter -ge $KILL_THRESHOLD ] || [ $FORCE_KILL = 1 ]; then signal=KILL fi if [ $iter -ge 2 ]; then # Give the daemon some time to do its cleanup and actually # terminate. Then check its state again. sleep 2 pids="$(cf_get_daemon_pid $daemon)" fi if [ "$signal" != "KILL" ] && [ -f "$pidfile" ] && [ "$DEBIAN" = "1" ] && [ "$SSD" = "1" ]; then # Debian/Ubuntu with start-stop-daemon. /sbin/start-stop-daemon -o --stop --pidfile "$pidfile" --retry 5 --name "$base_daemon" >/dev/null 2>&1 else # All others, or if there is no pidfile, or if using SIGKILL. for pid in $pids; do kill -$signal "$pid" >/dev/null 2>&1 if [ "$signal" = "KILL" ]; then # If using SIGKILL, the daemons won't be able to do this themselves. rm -f "$pidfile" fi done fi pids="$(cf_get_daemon_pid $daemon)" iter=$(($iter+1)) done # Redhat/Centos/Fedora if [ "$REDHAT" = "1" ] && [ "$FUNC" = "1" ]; then if [ -f "/var/lock/subsys/$base_daemon" ]; then cf_rm -f "/var/lock/subsys/$base_daemon" cf_rm -f "/var/lock/subsys/cfengine3" fi elif [ "$REDHAT" = "1" ] && [ "$FUNC" = "0" ]; then if [ -f "/var/lock/subsys/$base_daemon" ]; then cf_rm -f "/var/lock/subsys/$base_daemon" cf_rm -f "/var/lock/subsys/cfengine3" fi # SUSE elif [ "$SUSE" = "1" ] && [ "$PROC" = "1" ]; then rc_status -v if [ -f "/var/run/$base_daemon.pid" ]; then cf_rm "/var/run/$base_daemon.pid" fi elif [ "$SUSE" = "1" ] && [ "$PROC" = "0" ]; then if [ -f "/var/run/$base_daemon.pid" ]; then cf_rm "/var/run/$base_daemon.pid" fi # Debian/Ubuntu elif [ "$DEBIAN" = "1" ] && [ "$SSD" = "1" ]; then if [ -f "$LOCKDIR/$base_daemon" ]; then cf_rm "$LOCKDIR/$base_daemon" fi elif [ "$DEBIAN" = "1" ] && [ "$SSD" = "0" ]; then if [ -f "$LOCKDIR/$base_daemon" ]; then cf_rm "$LOCKDIR/$base_daemon" fi fi return $ret } # Returns 0 if agents were found, 1 if not. cf_stop_agents() { local base_agent="$(basename "$CFAGENT")" local not_found=1 local ret=1 local signal=TERM local iter=1 while [ $iter -le $STOP_ATTEMPTS ]; do if [ $iter -ge $KILL_THRESHOLD ] || [ $FORCE_KILL = 1 ]; then signal=KILL fi if [ $iter -gt 2 ]; then # If we failed at first, give things time to settle. sleep 2 fi not_found=1 for pid in $(cf_get_matching_pids "$CFAGENT"); do not_found=0 ret=0 kill -$signal $pid done if [ $not_found = 1 ]; then break fi iter=$(($iter+1)) done return $ret } cf_status_daemon() { local daemon="$1" local base_daemon="$(basename "$daemon")" local pidfile="$(printf "$PIDFILE_TEMPLATE" "$base_daemon")" local daemon_status="$(cf_pidfile_pid "$pidfile")" local pids="$(cf_get_matching_pids "$base_daemon")" if [ -f "$pidfile" ] && ! echo "$pids" | grep "$daemon_status" > /dev/null; then echo "Warning: PID file '$pidfile' does not contain the right PID ('$pids' != '$daemon_status'). Should restart CFEngine." fi # https is expected to have multiple pids, skip detection of multiple # pids to avoid false alarms if [ "${base_daemon}" != "httpd" ] && [ "${base_daemon}" != "cf-hub" ]; then # Lack of quotes around $pids is important to eliminate newlines. if [ -n "$(echo $pids | grep '[^0-9]')" ]; then echo "Warning: Multiple $base_daemon processes present. Should restart CFEngine." fi fi if [ -n "$pids" ]; then if [ "$REDHAT" = "1" ] && [ "$FUNC" = "1" ]; then status "$daemon" elif [ "$SUSE" = "1" ] && [ "$PROC" = "1" ]; then printf 'Checking for %s ' "$base_daemon" checkproc "$daemon" rc_status -v else # The additional "echo" is to eliminate newlines in $pids. echo "$base_daemon is running..." fi else echo "$base_daemon is not running" return 3 fi } cf_start_core_daemons() { # start cf-execd if [ "$RUN_CF_EXECD" = "1" ]; then cf_start_daemon "$CFEXECD" fi # start cf-serverd if [ "$RUN_CF_SERVERD" = "1" ]; then cf_start_daemon "$CFSERVD" fi # start cf-monitord if [ "$RUN_CF_MONITORD" = "1" ]; then cf_start_daemon "$CFMOND" fi } cf_stop_core_daemons() { # Stopping the CFEngine daemons is sometimes extremely tricky, because the # killing of a daemon may coincide with the spawning of a new agent, which # will spawn a new daemon and bring us right back to the start. So we always # kill both, making sure they are dead, and once we have, we go back and do # one more complete round of process detection to make *sure* that nothing # is alive. As long as something is alive we will always require another # round, up to STOP_ATTEMPTS times. local iter=1 while [ $iter -le $STOP_ATTEMPTS ]; do local any_process_present=0 if [ $iter -ge 2 ]; then # Let's wait a bit before the second attempt. sleep 2 fi if [ $iter -ge $KILL_THRESHOLD ]; then # The stopping functions internally use SIGKILL if they feel the # need, but only after some time, so we still force it here, in case # we have a fork()-bomb-like situation where each kill results in a # new daemon or agent. FORCE_KILL=1 fi # First stop any agents running because they may start the daemons we # will be stopping behind our back. cf_stop_agents && any_process_present=1 # shutdown cf-execd if [ "$RUN_CF_EXECD" = "1" ]; then cf_stop_daemon "$CFEXECD" && any_process_present=1 fi # shutdown cf-serverd if [ "$RUN_CF_SERVERD" = "1" ]; then cf_stop_daemon "$CFSERVD" && any_process_present=1 fi # shutdown cf-monitord if [ "$RUN_CF_MONITORD" = "1" ]; then cf_stop_daemon "$CFMOND" && any_process_present=1 fi # In case agents were spawned just as we were trying to kill the # daemons, try killing those too. cf_stop_agents && any_process_present=1 if [ $any_process_present = 0 ]; then break fi iter=$(($iter+1)) done } cf_status_core_daemons() { local cf_status_core_daemons_exit=0 # status cf-execd if [ "$RUN_CF_EXECD" = "1" ]; then cf_status_daemon "$CFEXECD" if [ "$?" = "3" ]; then cf_status_core_daemons_exit=3 fi fi # status cf-serverd if [ "$RUN_CF_SERVERD" = "1" ]; then cf_status_daemon "$CFSERVD" if [ "$?" = "3" ]; then cf_status_core_daemons_exit=3 fi fi # status cf-monitord if [ "$RUN_CF_MONITORD" = "1" ]; then cf_status_daemon "$CFMOND" if [ "$?" = "3" ]; then cf_status_core_daemons_exit=3 fi fi # Return the exit code return $cf_status_core_daemons_exit } cf_touch() { # Not during testing. if [ -z "$CFTEST_PREFIX" ]; then touch "$@" fi } cf_rm() { # Not during testing. if [ -z "$CFTEST_PREFIX" ]; then rm "$@" fi } ##### end: Defined functions ##### ##### Source enterprise script, if present ##### if [ -f "$CFENTERPRISE_INITD" ]; then ENTERPRISE_SERVER=1 CALLED_FROM_INITSCRIPT="1" . "$CFENTERPRISE_INITD" else ENTERPRISE_SERVER=0 alias enterprise_start=true alias enterprise_stop=true alias enterprise_status=true fi ### start scripting here ### case "$1" in start) if ! [ -f $INPUTDIR/promises.cf ]; then # Prevent the enterprise scripts from launching any non-web # related stuff when we are not bootstrapped. export CF_ONLY_WEB_SERVICES=1 fi # Start Enterprise services. enterprise_start if [ "$CF_ONLY_WEB_SERVICES" = "1" ]; then if [ "$ENTERPRISE_SERVER" = "1" ]; then # Enterprise servers automatically run "start" as part of package installation, # at which point they don't have policy in inputs/, because they are not bootstrapped. # This is not an error, like for community or enterprise clients (case below). exit 0 fi # On hosts we do not start any process when there is no # policy, so indicate this as an error. echo "No policy found in $INPUTDIR/promises.cf, not starting core daemons" >&2 exit 1 fi cf_start_core_daemons exit 0 ;; stop) if [ "$CF_ONLY_WEB_SERVICES" != "1" ]; then cf_stop_core_daemons fi # Stop Enterprise services. enterprise_stop exit 0 ;; status) if [ "$CF_ONLY_WEB_SERVICES" = "1" ]; then exit 0 fi # Status Enterprise services. enterprise_status cf_status_core_daemons exit $? ;; restart|reload|force-reload) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop|status|restart|reload|force-reload}" >&2 exit 1 ;; esac cfengine-3.24.2/misc/systemd/0000755000000000000000000000000015010704322015773 5ustar00rootroot00000000000000cfengine-3.24.2/misc/systemd/cfengine3.service.in0000644000000000000000000000154515010704253021633 0ustar00rootroot00000000000000[Unit] Description=CFEngine 3 umbrella service Documentation=https://docs.cfengine.com/ https://northerntech.atlassian.net After=syslog.target # Try to start all the sub-services. 'Wants' is fault-tolerant so if some are # missing or impossible to start, no big deal. Wants=cf-serverd.service Wants=cf-execd.service Wants=cf-monitord.service Wants=cf-postgres.service Wants=cf-apache.service Wants=cf-hub.service Wants=cf-reactor.service # Ensure synchronous stop behavior Before=cf-serverd.service Before=cf-execd.service Before=cf-monitord.service Before=cf-postgres.service Before=cf-apache.service Before=cf-hub.service Before=cf-reactor.service [Install] WantedBy=multi-user.target [Service] Type=oneshot RemainAfterExit=yes # Nothing to do here, we just need to make sure the specific services to be # started/stopped. ExecStart=/bin/true ExecStop=/bin/true cfengine-3.24.2/misc/systemd/cf-monitord.service.in0000644000000000000000000000046515010704253022213 0ustar00rootroot00000000000000[Unit] Description=CFEngine Monitor Daemon After=syslog.target ConditionPathExists=@bindir@/cf-monitord ConditionPathExists=@workdir@/inputs/promises.cf PartOf=cfengine3.service [Service] Type=simple ExecStart=@bindir@/cf-monitord --no-fork Restart=always RestartSec=10 [Install] WantedBy=multi-user.target cfengine-3.24.2/misc/systemd/cf-execd.service.in0000644000000000000000000000050515010704253021443 0ustar00rootroot00000000000000[Unit] Description=CFEngine Execution Scheduler After=syslog.target ConditionPathExists=@bindir@/cf-execd ConditionPathExists=@workdir@/inputs/promises.cf PartOf=cfengine3.service [Service] Type=simple ExecStart=@bindir@/cf-execd --no-fork Restart=always RestartSec=10 KillMode=process [Install] WantedBy=multi-user.target cfengine-3.24.2/misc/systemd/cf-apache.service.in0000644000000000000000000000073015010704253021574 0ustar00rootroot00000000000000[Unit] Description=CFEngine Enterprise Webserver After=syslog.target Wants=cf-postgres.service After=cf-postgres.service ConditionPathExists=@workdir@/httpd/bin/apachectl PartOf=cfengine3.service [Service] Type=forking ExecStart=@workdir@/httpd/bin/apachectl start ExecStop=@workdir@/httpd/bin/apachectl stop ExecReload=@workdir@/httpd/bin/apachectl graceful PIDFile=@workdir@/httpd/httpd.pid Restart=always RestartSec=10 UMask=0177 [Install] WantedBy=multi-user.target cfengine-3.24.2/misc/systemd/cf-serverd.service.in0000644000000000000000000000061315010704253022025 0ustar00rootroot00000000000000[Unit] Description=CFEngine Enterprise file server After=syslog.target After=network-online.target ConditionPathExists=@bindir@/cf-serverd ConditionPathExists=@workdir@/policy_server.dat ConditionPathExists=@workdir@/inputs/promises.cf PartOf=cfengine3.service [Service] Type=simple ExecStart=@bindir@/cf-serverd --no-fork Restart=always RestartSec=10 [Install] WantedBy=network-online.target cfengine-3.24.2/misc/systemd/cf-reactor.service.in0000644000000000000000000000062015010704253022010 0ustar00rootroot00000000000000[Unit] Description=CFEngine Enterprise event reaction daemon PartOf=cfengine3.service ConditionPathExists=@bindir@/cf-reactor ConditionPathExists=@workdir@/inputs/promises.cf After=syslog.target After=network.target Wants=cf-postgres.service After=cf-postgres.service [Service] Type=simple ExecStart=@bindir@/cf-reactor --no-fork Restart=always RestartSec=10 [Install] WantedBy=multi-user.target cfengine-3.24.2/misc/systemd/cf-postgres.service.in0000644000000000000000000000206715010704253022226 0ustar00rootroot00000000000000[Unit] Description=CFEngine Enterprise PostgreSQL Database After=syslog.target ConditionPathExists=@bindir@/pg_ctl PartOf=cfengine3.service [Service] Type=forking WorkingDirectory=/tmp User=cfpostgres Restart=always RestartSec=10 PIDFile=@workdir@/state/pg/data/postmaster.pid SyslogIdentifier=postgres # Disable OOM kill on the postmaster OOMScoreAdjust=-1000 # ... but allow it still to be effective for child processes # (note that these settings are ignored by Postgres releases before 9.5) Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj Environment=PG_OOM_ADJUST_VALUE=0 # Maximum number of seconds pg_ctl will wait for postgres to start. Note that # PGSTARTTIMEOUT should be less than TimeoutSec value. #Environment=PGSTARTTIMEOUT=270 Environment=PGDATA=@workdir@/state/pg/data ExecStart=@bindir@/pg_ctl -w -D ${PGDATA} -l /var/log/postgresql.log start ExecStop=@bindir@/pg_ctl -w -D ${PGDATA} -l /var/log/postgresql.log stop -m fast ExecReload=@bindir@/pg_ctl -w -D ${PGDATA} -l /var/log/postgresql.log reload -m fast [Install] WantedBy=multi-user.target cfengine-3.24.2/misc/systemd/cf-hub.service.in0000644000000000000000000000060715010704253021134 0ustar00rootroot00000000000000[Unit] Description=CFEngine Enterprise Hub Report Collector PartOf=cfengine3.service ConditionPathExists=@bindir@/cf-hub ConditionPathExists=@workdir@/inputs/promises.cf After=syslog.target After=network.target Wants=cf-postgres.service After=cf-postgres.service [Service] Type=simple ExecStart=@bindir@/cf-hub --no-fork Restart=always RestartSec=10 [Install] WantedBy=multi-user.target cfengine-3.24.2/misc/cf-support0000755000000000000000000003611615010704253016345 0ustar00rootroot00000000000000#!/usr/bin/env sh # this script works with plain old POSIX sh so have to allow legacy subshell `command` instead of using $(command) # shellcheck disable=SC2006 # be double-certain that we have needed PATH entries regardless of execution environment PATH=/usr/contrib/bin:$PATH; export PATH # hpux PATH=/usr/sbin:$PATH; export PATH # solaris PATH=/usr/bin:$PATH; export PATH # sol10sparc has showrev in /usr/bin WORKDIR=/var/cfengine; export WORKDIR BINDIR="$WORKDIR/bin"; export BINDIR non_interactive=0; export non_interactive if [ $# -gt 1 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then echo "usage: `basename "$0"` [OPTIONS]" echo '' echo 'Options:' echo ' --yes, -y - Non-interactive use. Assume no ticket number and assume include masterfiles.' echo ' --help, -h - Print the help message' echo '' echo 'Website: https://cfengine.com' echo 'This software is Copyright 2024 Northern.tech AS.' exit 1 fi if [ "$1" = "-M" ]; then cat </dev/null; then echo "Please install gzip. This is required in order to minimize size of support collection." exit 1 fi if [ $non_interactive -eq 0 ]; then printf "If you have it, please enter your support case number: " read -r case_number fi case_number="${case_number:-NA}" timestamp=`date +%Y-%m-%d-%H%M` collection="cfengine_support_case_$case_number-`hostname`-$timestamp" make_temp_dir() { if command -v mktemp >/dev/null && [ "$OS" != "hpux" ]; then mktemp -d else # shellcheck disable=SC2021 # ^^ legacy/POSIX requires square brackets _tmp="/tmp/`LC_CTYPE=C tr -dc "[A-Z][a-z][0-9]" /dev/null`" mkdir "$_tmp" echo "$_tmp" fi } # determine operating system flavor if command -v swlist 2>/dev/null; then OS="hpux" elif command -v oslevel 2>/dev/null; then OS=aix elif [ -f /etc/release ]; then OS=solaris OS_VERSION=$(uname -r) elif [ -f /etc/redhat-release ] || [ -f /etc/os-release ] || [ -f /etc/lsb-release ]; then OS=linux elif command -v system_profiler 2>/dev/null; then OS=macos else echo "unable to determine operating system, will try generic unix commands." OS=unix fi tmpdir="`make_temp_dir`/$collection" export tmpdir mkdir -p "$tmpdir" echo "Analyzing CFEngine core dumps" _core_log="$tmpdir"/core-dump.log if command -v sysctl >/dev/null; then _sysctl_kernel_core_pattern="$(sysctl -n kernel.core_pattern)" else _sysctl_kernel_core_pattern="" fi if expr "$_sysctl_kernel_core_pattern" : ".*/systemd-coredump.*" > /dev/null 2>&1; then echo "Found systemd-coredump used in sysctl kernel.core_pattern \"$_sysctl_kernel_core_pattern\"" echo "Using coredumpctl to analyze CFEngine core dumps" coredumpctl info /var/cfengine/bin/cf-* 2>/dev/null >> "$_core_log" || true elif command -v apport-unpack >/dev/null; then echo "Using apport-unpack to analyze CFEngine core dumps" # each crash report has a line with ExecutablePath: which tells us if it is a CFEngine core dump crash_reports=`grep -H "ExecutablePath: /var/cfengine/bin" /var/crash/* | sed "s/:ExecutablePath.*$//"` if [ -n "$crash_reports" ]; then if ! command -v gdb >/dev/null; then echo "CFEngine related core dumps were found but gdb is not installed. Please install gdb and retry the cf-support command." exit 1 fi # process crash reports with tmp dirs and all for report in $crash_reports; do tmp=`make_temp_dir` apport-unpack "$report" "$tmp" exe=`cat "$tmp/ExecutablePath"` # print out report up to the embedded core dump file # --null-data separate lines by NUL characters sed --null-data 's/CoreDump:.*$//' "$report" >> "$_core_log" gdb "$exe" --core="$tmp/CoreDump" -batch -ex "thread apply all bt full" >> "$_core_log" 2>&1 rm -rf "$tmp" done fi else if [ "$non_interactive" -eq 0 ]; then printf "Analyze coredumps found under /var/cfengine/bin? [Y//n]: " read -r response fi response=${response:-/var/cfengine/bin} if [ "$response" != "n" ]; then # file command on core files results in lines like the following which we parse for cf-* binaries # core: ELF 64-bit LSB core file, x86-64, version 1 (SYSV), SVR4-style, from '/var/cfengine/bin/cf-key', real uid: 0, effective uid: 0, realgid: 0, effective gid: 0, execfn: '/var/cfengine/bin/cf-key', platform: 'x86_64' cf_core_files=`find "$response/." \( -name . -o -prune \) -name 'core*' -type f -exec file {} \; 2>/dev/null | grep "core file" | grep "cf-" | cut -d' ' -f1 | sed 's/:$//'` if [ -n "$cf_core_files" ]; then if [ "$OS" != "solaris" ]; then if ! command -v gdb >/dev/null; then echo "Please install gdb. This is required in order to analyze core dumps." echo "Core dumps needing to be analyzed will be listed below:" fi fi for core_file in $cf_core_files; do file "$core_file" >> "$_core_log" if [ "$OS" = "solaris" ]; then pstack "$core_file" >> "$_core_log" 2>&1 elif command -v gdb >/dev/null; then execfn=`file "$core_file" | sed 's/,/\n/g' | grep execfn | cut -d: -f2 | sed "s/[' ]//g"` exe="`realpath "$execfn"`" gdb "$exe" --core="$core_file" -batch -ex "thread apply all bt full" >> "$_core_log" 2>&1 else # shellcheck disable=SC2012 ls -l "$core_file" | tee "$_core_log" fi done fi fi fi info_file="$tmpdir/system-info.txt" export info_file file_add() { filename="`basename "$1"`" if [ -f "$1" ]; then cp "$1" "$tmpdir"/"$filename" echo "Added file $1" else echo "$1 file not found" >> "$info_file" fi } gzip_add() { filename="`basename "$1"`" if [ -f "$1" ]; then gzip -c "$1" > "$tmpdir"/"$filename".gz echo "Added compressed copy of file $1" else echo "$1 file not found" >> "$info_file" fi } log_cmd() { cmd="`echo "$1" | awk '{print $1}'`" if command -v "$cmd" 2>/dev/null >/dev/null; then echo "** $1" >> "$info_file" sh -c "$1" >> "$info_file" 2>&1 || true echo >> "$info_file" # one newline for easier to read output echo "Captured output of command $1" else echo "Command not found: $cmd" fi } # first, collect basic information about the system log_cmd "uname -a" log_cmd "$BINDIR/cf-promises -V" if [ "$OS" = "solaris" ]; then log_cmd "prtconf" # system configuration, memory size, peripherals log_cmd "psrinfo -v" # verbose information about each processor, on-line since, type, speed if [ "$OS_VERSION" = "5.10" ]; then log_cmd "showrev" # hostname, hostid, release, kernel architecture, application architecutre, kernel version fi log_cmd "vmstat" # equivalent of free -h log_cmd "zonename" # either global, or a named zone if command -v zonestat 2>/dev/null; then log_cmd "zonestat 1 1" # get information about memory/cpu in this zone fi elif [ "$OS" = "hpux" ]; then if [ -x /opt/ignite/bin/print_manifest ]; then log_cmd "/opt/ignite/bin/print_manifest" # contains info provided by other commands below else log_cmd "swlist" # list of bundles installed, includes HPUX-OE base os version log_cmd "model" # type of machine # machinfo provides cpu, speed, memory, firmware, platform, id, serial, OS, nodename/hostname, release, sysname if command -v machinfo 2>/dev/null; then log_cmd "machinfo" fi fi # regardless, report status of interfaces/volumes and memory log_cmd "dmesg" # not syslog related like on linux elif [ "$OS" = "aix" ]; then log_cmd "prtconf" # model, type, cpus, speed, memory, firmware, network info, volume groups, peripherals/resources log_cmd "oslevel -s" # OS version else # linux and "generic" unices like macos/bsds? log_cmd "lscpu" log_cmd "free -m" log_cmd "hostname" [ -f "/etc/os-release" ] && log_cmd "cat /etc/os-release" fi # filesystems and usage if [ "$OS" != "solaris" ] && [ "$OS" != "aix" ]; then file_add "/etc/fstab" fi log_cmd "mount" if [ "$OS" != "hpux" ] && [ "$OS" != "aix" ]; then log_cmd "df -h" else log_cmd "df -g" # only needed on hpux/aix, -h is not available fi # processes # shellcheck disable=SC2166 # ^^ allow grouping in test expression if [ "$OS" = "hpux" ] || [ \( "$OS" = "solaris" -a "$OS_VERSION" = "5.10" \) ]; then ps -efl >processes.log 2>&1 else ps auwwx >processes.log 2>&1 fi # top procs if [ "$OS" = "hpux" ]; then # use -f option to force -d1 and include no console codes top -f /tmp/top.log file_add /tmp/top.log rm /tmp/top.log elif [ "$OS" = "aix" ] || [ "$OS" = "solaris" ]; then log_cmd "ps aux | head -1; ps aux | sed '1d' | sort -rn +2 | head -10" else log_cmd "top -b -H -c -n1" fi # network interfaces if [ "$OS" = "hpux" ] || [ "$OS" = "solaris" ] || [ "$OS" = "aix" ]; then log_cmd "netstat -in" else log_cmd "netstat -ie" fi if [ "$OS" = "aix" ] || [ "$OS" = "solaris" ]; then log_cmd "ifconfig -a" elif [ "$OS" = "hpux" ]; then lanscan -p | while read -r lan do log_cmd "ifconfig lan${lan}" done 2>/dev/null else log_cmd "ifconfig" fi # open file handles if command -v lsof 2>/dev/null >/dev/null; then lsof > "$tmpdir/lsof.txt" echo "Captured output of command lsof" fi # CFEngine specific log_cmd "$BINDIR/cf-key -p $WORKDIR/ppkeys/localhost.pub" log_cmd "grep 'version =' $WORKDIR/inputs/promises.cf" log_cmd "$BINDIR/cf-key -s -n" log_cmd "$BINDIR/cf-check diagnose" $BINDIR/cf-promises --show-classes --show-vars > "$tmpdir/classes-and-vars.txt" 2>&1 $BINDIR/cf-agent --no-lock --file update.cf --show-evaluated-classes --show-evaluated-vars > "$tmpdir/update-evaluated-classes-and-vars.txt" 2>&1 $BINDIR/cf-agent --no-lock --file promises.cf --show-evaluated-classes --show-evaluated-vars > "$tmpdir/promises-evaluated-classes-and-vars.txt" 2>&1 if command -v systemctl >/dev/null; then log_cmd "systemctl status cfengine3" log_cmd "systemctl status cf-*" elif [ -x /etc/init.d/cfengine3 ]; then log_cmd "/etc/init.d/cfengine3 status" else echo "No way to check on cfengine service status" fi for f in /var/log/CFEngine-Install*; do gzip_add "$f" done # system log [ -f /var/log/messages ] && syslog_cmd="cat /var/log/messages" [ -f /var/log/syslog ] && syslog_cmd="cat /var/log/syslog" command -v journalctl >/dev/null && syslog_cmd="journalctl" [ -z "$syslog_cmd" ] && syslog_cmd="dmesg" if [ "$OS" = "solaris" ]; then syslog_cmd="cat /var/adm/messages*" fi _syslog_filtered="$tmpdir"/syslog-filtered-for-cfengine.log.gz if [ "$OS" = "aix" ]; then syslog_cmd="errpt -a" # error report can reference cfengine, reports are delimitted by bars of `-` characters echo "r !errpt -a g/cfengine/?---?,/---/p" | ed > "$_syslog_filtered" || true else $syslog_cmd | sed -n '/[Cc][Ff][Ee-]/p' | gzip -c > "$_syslog_filtered" || true fi echo "Captured output of $syslog_cmd filtered for cf-|CFEngine" # cf- component related SELinux denials if command -v ausearch >/dev/null; then ausearch -m avc -su cfengine > "$tmpdir"/ausearch-cfengine-avcs.log fi gzip_add $WORKDIR/outputs/previous gzip_add $WORKDIR/outputs/dc-scripts.log # masterfiles-stage log file_add $WORKDIR/policy_server.dat if [ -f $WORKDIR/share/cf-support-nova-hub.sh ]; then # shellcheck source=/dev/null . $WORKDIR/share/cf-support-nova-hub.sh fi # Here we create the tarball one directory up # to preserve a top-level of $collection in the tarball. # This gives a nice context of timestamp, hostname and support ticket # if provided. (see $collection definition above) tar cvf - -C "$tmpdir"/.. "$collection" | gzip > "$collection.tar.gz" rm -rf "$tmpdir" echo "Please send $collection.tar.gz to CFEngine support staff." cfengine-3.24.2/cf-runagent/0000755000000000000000000000000015010704322015561 5ustar00rootroot00000000000000cfengine-3.24.2/cf-runagent/Makefile.am0000644000000000000000000000312515010704253017621 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-runagent.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libcfecompat \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_runagent_la_LIBADD = ../libpromises/libpromises.la libcf_runagent_la_SOURCES = cf-runagent.c if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-runagent cf_runagent_LDADD = libcf-runagent.la cf_runagent_SOURCES = endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-runagent/Makefile.in0000644000000000000000000006303615010704300017632 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-runagent$(EXEEXT) subdir = cf-runagent ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_runagent_la_DEPENDENCIES = ../libpromises/libpromises.la am_libcf_runagent_la_OBJECTS = cf-runagent.lo libcf_runagent_la_OBJECTS = $(am_libcf_runagent_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_cf_runagent_OBJECTS = cf_runagent_OBJECTS = $(am_cf_runagent_OBJECTS) @BUILTIN_EXTENSIONS_FALSE@cf_runagent_DEPENDENCIES = \ @BUILTIN_EXTENSIONS_FALSE@ libcf-runagent.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_runagent_la_SOURCES) $(cf_runagent_SOURCES) DIST_SOURCES = $(libcf_runagent_la_SOURCES) $(cf_runagent_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-runagent.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libcfecompat \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_runagent_la_LIBADD = ../libpromises/libpromises.la libcf_runagent_la_SOURCES = cf-runagent.c @BUILTIN_EXTENSIONS_FALSE@cf_runagent_LDADD = libcf-runagent.la @BUILTIN_EXTENSIONS_FALSE@cf_runagent_SOURCES = CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-runagent/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-runagent/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-runagent.la: $(libcf_runagent_la_OBJECTS) $(libcf_runagent_la_DEPENDENCIES) $(EXTRA_libcf_runagent_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_runagent_la_OBJECTS) $(libcf_runagent_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-runagent$(EXEEXT): $(cf_runagent_OBJECTS) $(cf_runagent_DEPENDENCIES) $(EXTRA_cf_runagent_DEPENDENCIES) @rm -f cf-runagent$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_runagent_OBJECTS) $(cf_runagent_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-runagent.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-runagent/cf-runagent.c0000644000000000000000000007063315010704253020152 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* ProtocolVersionParse */ #include #include #include #define CF_RA_EXIT_CODE_OTHER_ERR 101 typedef enum { RUNAGENT_CONTROL_HOSTS, RUNAGENT_CONTROL_PORT_NUMBER, RUNAGENT_CONTROL_FORCE_IPV4, RUNAGENT_CONTROL_TRUSTKEY, RUNAGENT_CONTROL_ENCRYPT, RUNAGENT_CONTROL_BACKGROUND, RUNAGENT_CONTROL_MAX_CHILD, RUNAGENT_CONTROL_OUTPUT_TO_FILE, RUNAGENT_CONTROL_OUTPUT_DIRECTORY, RUNAGENT_CONTROL_TIMEOUT, RUNAGENT_CONTROL_NONE } RunagentControl; static void ThisAgentInit(void); static GenericAgentConfig *CheckOpts(int argc, char **argv); static void KeepControlPromises(EvalContext *ctx, const Policy *policy); static int HailServer(const EvalContext *ctx, const GenericAgentConfig *config, char *host); static void SendClassData(AgentConnection *conn); static int HailExec(AgentConnection *conn, char *peer); static FILE *NewStream(char *name); /*******************************************************************/ /* Command line options */ /*******************************************************************/ static const char *const CF_RUNAGENT_SHORT_DESCRIPTION = "activate cf-agent on a remote host"; static const char *const CF_RUNAGENT_MANPAGE_LONG_DESCRIPTION = "cf-runagent connects to a list of running instances of " "cf-serverd. It allows foregoing the usual cf-execd schedule " "to activate cf-agent. Additionally, a user " "may send classes to be defined on the remote\n" "host. Two kinds of classes may be sent: classes to decide " "on which hosts cf-agent will be started, and classes that " "the user requests cf-agent should define on execution. " "The latter type is regulated by cf-serverd's role based access control."; static const Component COMPONENT = { .name = "cf-runagent", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"help", no_argument, 0, 'h'}, {"background", optional_argument, 0, 'b'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"log-level", required_argument, 0, 'g'}, {"dry-run", no_argument, 0, 'n'}, {"version", no_argument, 0, 'V'}, {"file", required_argument, 0, 'f'}, {"define-class", required_argument, 0, 'D'}, {"select-class", required_argument, 0, 's'}, {"inform", no_argument, 0, 'I'}, {"remote-options", required_argument, 0, 'o'}, {"diagnostic", no_argument, 0, 'x'}, {"hail", required_argument, 0, 'H'}, {"interactive", no_argument, 0, 'i'}, {"timeout", required_argument, 0, 't'}, {"color", optional_argument, 0, 'C'}, {"timestamp", no_argument, 0, 'l'}, /* Only long option for the rest */ {"ignore-preferred-augments", no_argument, 0, 0}, {"log-modules", required_argument, 0, 0}, {"remote-bundles", required_argument, 0, 0}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Parallelize connections (50 by default)", "Enable debugging output", "Output verbose information about the behaviour of cf-runagent", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "All talk and no action mode - make no changes, only inform of promises not kept", "Output the version of the software", "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.", "Define a list of comma separated classes to be sent to a remote agent", "Define a list of comma separated classes to be used to select remote agents by constraint", "Print basic information about changes made to the system, i.e. promises repaired", "(deprecated)", "(deprecated)", "Hail the following comma-separated lists of hosts, overriding default list", "Enable interactive mode for key trust", "Connection timeout, seconds", "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", "Log timestamps on each line of log output", "Ignore def_preferred.json file in favor of def.json", "Enable even more detailed debug logging for specific areas of the implementation. Use together with '-d'. Use --log-modules=help for a list of available modules", "Bundles to execute on the remote agent", NULL }; extern const ConstraintSyntax CFR_CONTROLBODY[]; int INTERACTIVE = false; /* GLOBAL_A */ int OUTPUT_TO_FILE = false; /* GLOBAL_P */ char OUTPUT_DIRECTORY[CF_BUFSIZE] = ""; /* GLOBAL_P */ int BACKGROUND = false; /* GLOBAL_P GLOBAL_A */ int MAXCHILD = 50; /* GLOBAL_P GLOBAL_A */ const Rlist *HOSTLIST = NULL; /* GLOBAL_P GLOBAL_A */ char SENDCLASSES[CF_MAXVARSIZE] = ""; /* GLOBAL_A */ char DEFINECLASSES[CF_MAXVARSIZE] = ""; /* GLOBAL_A */ char REMOTEBUNDLES[CF_MAXVARSIZE] = ""; /*****************************************************************************/ /** * @param is_exit_code whether #remote_exit_status is a exit code directly * (#true) or a status from wait() (#false) */ static inline void UpdateExitCode(int *exit_code, int remote_exit_status, bool one_host, bool is_exit_code) { assert(exit_code != NULL); if (one_host) { if (is_exit_code) { *exit_code = remote_exit_status; return; } if (WIFEXITED(remote_exit_status)) { *exit_code = WEXITSTATUS(remote_exit_status); return; } *exit_code = CF_RA_EXIT_CODE_OTHER_ERR; return; } /* Other error should always take priority, otherwise, count failed remote * agent runs. */ if ((*exit_code < CF_RA_EXIT_CODE_OTHER_ERR) && (!WIFEXITED(remote_exit_status) || (WEXITSTATUS(remote_exit_status) != EXIT_SUCCESS))) { *exit_code = MIN(*exit_code + 1, 100); } } int main(int argc, char *argv[]) { #if !defined(__MINGW32__) int count = 0; int status; int pid; #endif GenericAgentConfig *config = CheckOpts(argc, argv); EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); const char *program_invocation_name = argv[0]; const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR); const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name); GenericAgentDiscoverContext(ctx, config, program_name); Policy *policy = LoadPolicy(ctx, config); GenericAgentPostLoadInit(ctx); ThisAgentInit(); KeepControlPromises(ctx, policy); // Set RUNATTR using copy /* Exit codes: * - exit code from the remote agent run if only 1 host specified * - number of failed remote agent runs up to 100 otherwise * - >100 in case of other errors */ int exit_code = 0; if (BACKGROUND && INTERACTIVE) { Log(LOG_LEVEL_ERR, "You cannot specify background mode and interactive mode together"); DoCleanupAndExit(CF_RA_EXIT_CODE_OTHER_ERR); } /* HvB */ const bool one_host = (HOSTLIST != NULL) && (HOSTLIST->next == NULL); if (HOSTLIST) { const Rlist *rp = HOSTLIST; while (rp != NULL) { #ifdef __MINGW32__ if (BACKGROUND) { Log(LOG_LEVEL_VERBOSE, "Windows does not support starting processes in the background - starting in foreground"); BACKGROUND = false; } #else if (BACKGROUND) /* parallel */ { if (count < MAXCHILD) { if (fork() == 0) /* child process */ { int remote_exit_code = HailServer(ctx, config, RlistScalarValue(rp)); DoCleanupAndExit(remote_exit_code >= 0 ? remote_exit_code : CF_RA_EXIT_CODE_OTHER_ERR); } else /* parent process */ { rp = rp->next; count++; } } else { pid = wait(&status); Log(LOG_LEVEL_DEBUG, "child = %d, child number = %d", pid, count); count--; UpdateExitCode(&exit_code, status, one_host, false); } } else /* serial */ #endif /* __MINGW32__ */ { int remote_exit_code = HailServer(ctx, config, RlistScalarValue(rp)); UpdateExitCode(&exit_code, remote_exit_code, one_host, true); rp = rp->next; } } /* end while */ } /* end if HOSTLIST */ #ifndef __MINGW32__ if (BACKGROUND) { Log(LOG_LEVEL_NOTICE, "Waiting for child processes to finish"); while (count > 0) { pid = wait(&status); Log(LOG_LEVEL_VERBOSE, "Child %d ended, number %d", pid, count); count--; UpdateExitCode(&exit_code, status, one_host, false); } } #endif PolicyDestroy(policy); GenericAgentFinalize(ctx, config); CallCleanupFunctions(); return exit_code; } /*******************************************************************/ static GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int c; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_RUNAGENT, GetTTYInteractive()); DEFINECLASSES[0] = '\0'; SENDCLASSES[0] = '\0'; REMOTEBUNDLES[0] = '\0'; int longopt_idx; while ((c = getopt_long(argc, argv, "t:q:db::vnKhIif:g:D:VSxo:s:MH:C::l", OPTIONS, &longopt_idx)) != -1) { switch (c) { case 'f': GenericAgentConfigSetInputFile(config, GetInputDir(), optarg); MINUSF = true; break; case 'b': BACKGROUND = true; if (optarg) { MAXCHILD = StringToLongExitOnError(optarg); } break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case 'K': config->ignore_locks = true; break; case 's': { size_t len = strlen(SENDCLASSES); StrCatDelim(SENDCLASSES, sizeof(SENDCLASSES), &len, optarg, ','); if (len >= sizeof(SENDCLASSES)) { Log(LOG_LEVEL_ERR, "Argument too long (-s)"); DoCleanupAndExit(EXIT_FAILURE); } break; } case 'D': { size_t len = strlen(DEFINECLASSES); StrCatDelim(DEFINECLASSES, sizeof(DEFINECLASSES), &len, optarg, ','); if (len >= sizeof(DEFINECLASSES)) { Log(LOG_LEVEL_ERR, "Argument too long (-D)"); DoCleanupAndExit(EXIT_FAILURE); } break; } case 'H': HOSTLIST = RlistFromSplitString(optarg, ','); break; case 'o': Log(LOG_LEVEL_ERR, "Option \"-o\" has been deprecated," " you can not pass arbitrary arguments to remote cf-agent"); DoCleanupAndExit(EXIT_FAILURE); break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'i': INTERACTIVE = true; break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'n': EVAL_MODE = EVAL_MODE_DRY_RUN; config->ignore_locks = true; break; case 't': CONNTIMEOUT = StringToLongExitOnError(optarg); break; case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'h': { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-runagent", time(NULL), CF_RUNAGENT_SHORT_DESCRIPTION, CF_RUNAGENT_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(out); DoCleanupAndExit(EXIT_SUCCESS); } case 'x': Log(LOG_LEVEL_ERR, "Option \"-x\" has been deprecated"); DoCleanupAndExit(EXIT_FAILURE); case 'C': if (!GenericAgentConfigParseColor(config, optarg)) { DoCleanupAndExit(EXIT_FAILURE); } break; case 'l': LoggingEnableTimestamps(true); break; /* long options only */ case 0: { const char *const option_name = OPTIONS[longopt_idx].name; if (StringEqual(option_name, "ignore-preferred-augments")) { config->ignore_preferred_augments = true; } else if (strcmp(OPTIONS[longopt_idx].name, "log-modules") == 0) { bool ret = LogEnableModulesFromString(optarg); if (!ret) { DoCleanupAndExit(EXIT_FAILURE); } } else if (strcmp(OPTIONS[longopt_idx].name, "remote-bundles") == 0) { size_t len = strlen(REMOTEBUNDLES); StrCatDelim(REMOTEBUNDLES, sizeof(REMOTEBUNDLES), &len, optarg, ','); if (len >= sizeof(REMOTEBUNDLES)) { Log(LOG_LEVEL_ERR, "Argument too long (--remote-bundles)"); DoCleanupAndExit(EXIT_FAILURE); } } break; } default: { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_FAILURE); } } if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind)) { Log(LOG_LEVEL_ERR, "Too many arguments"); DoCleanupAndExit(EXIT_FAILURE); } return config; } /*******************************************************************/ static void ThisAgentInit(void) { umask(077); } /********************************************************************/ static int HailServer(const EvalContext *ctx, const GenericAgentConfig *config, char *host) { assert(host != NULL); AgentConnection *conn; char hostkey[CF_HOSTKEY_STRING_SIZE], user[CF_SMALLBUF]; bool gotkey; char reply[8]; bool trustkey = false; char *hostname, *port; ParseHostPort(host, &hostname, &port); if (hostname == NULL) { Log(LOG_LEVEL_INFO, "No remote hosts were specified to connect to"); return -1; } if (port == NULL) { port = "5308"; } char ipaddr[CF_MAX_IP_LEN]; if (Hostname2IPString(ipaddr, hostname, sizeof(ipaddr)) == -1) { Log(LOG_LEVEL_ERR, "HailServer: ERROR, could not resolve '%s'", hostname); return -1; } Address2Hostkey(hostkey, sizeof(hostkey), ipaddr); GetCurrentUserName(user, sizeof(user)); if (INTERACTIVE) { Log(LOG_LEVEL_VERBOSE, "Using interactive key trust..."); gotkey = HavePublicKey(user, ipaddr, hostkey) != NULL; if (!gotkey) { /* TODO print the hash of the connecting host. But to do that we * should open the connection first, and somehow pass that hash * here! redmine#7212 */ printf("WARNING - You do not have a public key from host %s = %s\n", hostname, ipaddr); printf(" Do you want to accept one on trust? (yes/no)\n\n--> "); while (true) { if (fgets(reply, sizeof(reply), stdin) == NULL) { FatalError(ctx, "EOF trying to read answer from terminal"); } if (Chop(reply, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } if (strcmp(reply, "yes") == 0) { printf("Will trust the key...\n"); trustkey = true; break; } else if (strcmp(reply, "no") == 0) { printf("Will not trust the key...\n"); trustkey = false; break; } else { printf("Please reply yes or no...(%s)\n", reply); } } } } #ifndef __MINGW32__ if (BACKGROUND) { Log(LOG_LEVEL_INFO, "Hailing %s : %s (in the background)", hostname, port); } else #endif { Log(LOG_LEVEL_INFO, "........................................................................"); Log(LOG_LEVEL_INFO, "Hailing %s : %s", hostname, port); Log(LOG_LEVEL_INFO, "........................................................................"); } ConnectionFlags connflags = { .protocol_version = config->protocol_version, .trust_server = trustkey, .off_the_record = false }; int err = 0; conn = ServerConnection(hostname, port, NULL, CONNTIMEOUT, connflags, &err); if (conn == NULL) { Log(LOG_LEVEL_ERR, "Failed to connect to host: %s", hostname); return -1; } /* Send EXEC command. */ return HailExec(conn, hostname); } /********************************************************************/ /* Level 2 */ /********************************************************************/ static void KeepControlPromises(EvalContext *ctx, const Policy *policy) { Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_RUNAGENT); if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_runagent"); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); /* If var not found, or if it's an empty list. */ if (value_type == CF_DATA_TYPE_NONE || value == NULL) { Log(LOG_LEVEL_ERR, "Unknown lval '%s' in runagent control body", cp->lval); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_FORCE_IPV4].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TRUSTKEY].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_ENCRYPT].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_BACKGROUND].lval) == 0) { /* * Only process this option if are is no -b or -i options specified on * command line. */ if (BACKGROUND || INTERACTIVE) { Log(LOG_LEVEL_WARNING, "'background_children' setting from 'body runagent control' is overridden by command-line option."); } else { BACKGROUND = BooleanFromString(value); } continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_MAX_CHILD].lval) == 0) { MAXCHILD = (short) IntFromString(value); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_TO_FILE].lval) == 0) { OUTPUT_TO_FILE = BooleanFromString(value); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_DIRECTORY].lval) == 0) { if (strlen(value) >= sizeof(OUTPUT_DIRECTORY)) { Log(LOG_LEVEL_ERR, "Could not set output direcory to '%s' - too long path", (const char *) value); } else if (IsAbsPath(value)) { strlcpy(OUTPUT_DIRECTORY, value, sizeof(OUTPUT_DIRECTORY)); Log(LOG_LEVEL_VERBOSE, "Setting output direcory to '%s'", OUTPUT_DIRECTORY); } continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TIMEOUT].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_HOSTS].lval) == 0) { if (HOSTLIST == NULL) // Don't override if command line setting { HOSTLIST = value; } continue; } } } const char *expire_after = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER); if (expire_after) { LASTSEENEXPIREAFTER = IntFromString(expire_after) * 60; } } static void SendClassData(AgentConnection *conn) { Rlist *classes, *rp; classes = RlistFromSplitRegex(SENDCLASSES, "[,: ]", 99, false); for (rp = classes; rp != NULL; rp = rp->next) { if (SendTransaction(conn->conn_info, RlistScalarValue(rp), 0, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Transaction failed. (send: %s)", GetErrorStr()); return; } } if (SendTransaction(conn->conn_info, CFD_TERMINATOR, 0, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Transaction failed. (send: %s)", GetErrorStr()); return; } } /********************************************************************/ static int HailExec(AgentConnection *conn, char *peer) { char sendbuf[CF_BUFSIZE - CF_INBAND_OFFSET] = "EXEC"; size_t sendbuf_len = strlen(sendbuf); if (!NULL_OR_EMPTY(DEFINECLASSES)) { StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, " -D", 0); StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, DEFINECLASSES, 0); } if (!NULL_OR_EMPTY(REMOTEBUNDLES)) { StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, " -b ", 0); StrCat(sendbuf, sizeof(sendbuf), &sendbuf_len, REMOTEBUNDLES, 0); } if (sendbuf_len >= sizeof(sendbuf)) { Log(LOG_LEVEL_ERR, "Command longer than maximum transaction packet"); DisconnectServer(conn); return -1; } if (SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Transmission rejected. (send: %s)", GetErrorStr()); DisconnectServer(conn); return -1; } /* TODO we are sending class data right after EXEC, when the server might * have already rejected us with BAD reply. So this class data with the * CFD_TERMINATOR will be interpreted by the server as a new, bogus * protocol command, and the server will complain. */ SendClassData(conn); char recvbuffer[CF_BUFSIZE]; FILE *fp = NewStream(peer); int exit_code = -1; while (true) { memset(recvbuffer, 0, sizeof(recvbuffer)); if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { break; } if (strncmp(recvbuffer, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) { break; } const size_t recv_len = strlen(recvbuffer); const char *ipaddr = conn->remoteip; if (strncmp(recvbuffer, "BAD:", 4) == 0) { fprintf(fp, "%s> !! %s\n", ipaddr, recvbuffer + 4); } /* cf-serverd >= 3.7 quotes command output with "> ". */ else if (strncmp(recvbuffer, "> ", 2) == 0) { fprintf(fp, "%s> -> %s", ipaddr, &recvbuffer[2]); } else { /* '(exit code: N)' is a special line, not prefixed with '>' (so not * part of output) and sent last by new cf-serverd (3.18.0+) */ if (StringStartsWith(recvbuffer, "(exit code:")) { /* Should never show up twice. */ assert(exit_code == -1); int scanned = sscanf(recvbuffer, "(exit code: %d)", &exit_code); if (scanned != 1) { Log(LOG_LEVEL_ERR, "Failed to parse exit code from '%s'", recvbuffer); } } fprintf(fp, "%s> %s", ipaddr, recvbuffer); } if (recv_len > 0 && recvbuffer[recv_len - 1] != '\n') { /* We'll be printing double newlines here with new cf-serverd * versions, so check for already trailing newlines. */ /* TODO deprecate this path in a couple of versions. cf-serverd is * supposed to munch the newlines so we must always append one. */ fputc('\n', fp); } } if (fp != stdout) { fclose(fp); } DisconnectServer(conn); return exit_code; } /********************************************************************/ /* Level */ /********************************************************************/ static FILE *NewStream(char *name) { char *filename; if (OUTPUT_DIRECTORY[0] != '\0') { xasprintf(&filename, "%s/%s_runagent.out", OUTPUT_DIRECTORY, name); } else { xasprintf(&filename, "%s%coutputs%c%s_runagent.out", GetWorkDir(), FILE_SEPARATOR, FILE_SEPARATOR, name); } FILE *fp; if (OUTPUT_TO_FILE) { printf("Opening file... %s\n", filename); fp = safe_fopen(filename, "w"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Unable to open file '%s' (fopen: %s)", filename, GetErrorStr()); fp = stdout; } } else { fp = stdout; } free(filename); return fp; } cfengine-3.24.2/cf-serverd/0000755000000000000000000000000015010704323015411 5ustar00rootroot00000000000000cfengine-3.24.2/cf-serverd/Makefile.am0000644000000000000000000000403315010704253017447 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-serverd.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libenv \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(OPENSSL_CFLAGS) \ $(PTHREAD_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_serverd_la_LIBADD = ../libpromises/libpromises.la libcf_serverd_la_SOURCES = \ cf-serverd.c \ cf-serverd-enterprise-stubs.c cf-serverd-enterprise-stubs.h \ cf-serverd-functions.c cf-serverd-functions.h \ server_common.c server_common.h \ server.c server.h \ server_transform.c server_transform.h \ server_classic.c server_classic.h \ server_tls.c server_tls.h \ server_access.c server_access.h \ strlist.c strlist.h if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-serverd # Workaround for automake madness (try removing it if you want to know why). cf_serverd_CFLAGS = $(AM_CFLAGS) cf_serverd_LDADD = libcf-serverd.la endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-serverd/server_common.h0000644000000000000000000000640415010704253020446 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SERVER_COMMON_H #define CFENGINE_SERVER_COMMON_H #define CF_BUFEXT 128 #include #include /* EvalContext */ #include /* ServerConnectionState */ void RefuseAccess(ServerConnectionState *conn, char *errmesg); bool AllowedUser(char *user); /* Checks whatever user name contains characters we are considering to be invalid */ bool IsUserNameValid(const char *username); bool MatchClasses(const EvalContext *ctx, ServerConnectionState *conn); void Terminate(ConnectionInfo *connection); void CfGetFile(ServerFileGetState *args); void CfEncryptGetFile(ServerFileGetState *args); int StatFile(ServerConnectionState *conn, char *sendbuffer, char *ofilename); void ReplyServerContext(ServerConnectionState *conn, int encrypted, Item *classes); int CfOpenDirectory(ServerConnectionState *conn, char *sendbuffer, char *oldDirname); int CfSecOpenDirectory(ServerConnectionState *conn, char *sendbuffer, char *dirname); void GetServerLiteral(EvalContext *ctx, ServerConnectionState *conn, char *sendbuffer, char *recvbuffer, int encrypted); bool GetServerQuery(ServerConnectionState *conn, char *recvbuffer, int encrypted); bool CompareLocalHash(const char *filename, const unsigned char digest[EVP_MAX_MD_SIZE + 1], char sendbuffer[CFD_FALSE_SIZE]); Item *ListPersistentClasses(void); bool PathRemoveTrailingSlash(char *s, size_t s_len); bool PathAppendTrailingSlash(char *s, size_t s_len); size_t ReplaceSpecialVariables(char *buf, size_t buf_size, const char *find1, const char *repl1, const char *find2, const char *repl2, const char *find3, const char *repl3); size_t ShortcutsExpand(char *path, size_t path_size, const StringMap *shortcuts, const char *ipaddr, const char *hostname, const char *key); size_t PreprocessRequestPath(char *reqpath, size_t reqpath_size); void SetConnIdentity(ServerConnectionState *conn, const char *username); bool DoExec2(const EvalContext *ctx, ServerConnectionState *conn, char *exec_args, char *sendbuf, size_t sendbuf_size); #endif /* CFENGINE_SERVER_COMMON_H */ cfengine-3.24.2/cf-serverd/server_classic.h0000644000000000000000000000230515010704253020573 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SERVER_CLASSIC_H #define CFENGINE_SERVER_CLASSIC_H #include #include #include "server.h" extern bool BusyWithClassicConnection(EvalContext *ctx, ServerConnectionState *conn); #endif cfengine-3.24.2/cf-serverd/server.h0000644000000000000000000001143315010704253017074 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SERVER_H #define CFENGINE_SERVER_H #include #include /* AgentConnection */ #include //******************************************************************* // TYPES //******************************************************************* typedef struct Auth_ Auth; /* Access rights for a path, literal, context (classpattern), variable */ /* LEGACY CODE the new struct is paths_acl etc. */ struct Auth_ { char *path; int literal; int classpattern; int variable; Item *accesslist; /* which hosts -- IP or hostnames */ Item *maproot; /* which hosts should have root read access */ int encrypt; /* which files HAVE to be transmitted securely */ Auth *next; }; typedef struct { Item *connectionlist; /* List of currently open connections */ /* body server control options */ Item *nonattackerlist; /* "allowconnects" */ Item *attackerlist; /* "denyconnects" */ Item *allowuserlist; /* "allowusers" */ Item *multiconnlist; /* "allowallconnects" */ Item *trustkeylist; /* "trustkeysfrom" */ Item *allowlegacyconnects; char *allowciphers; char *allowtlsversion; /* ACL for resource_type "path". */ Auth *admit; Auth *admittail; Auth *deny; Auth *denytail; /* ACL for resource_type "literal", "query", "context", "variable". */ Auth *varadmit; Auth *varadmittail; Auth *vardeny; Auth *vardenytail; int logconns; /* bundle server access_rules: shortcut for ACL entries, which expands to * the ACL entry when seen in client requests. */ StringMap *path_shortcuts; } ServerAccess; /* TODO rename to IncomingConnection */ struct ServerConnectionState_ { ConnectionInfo *conn_info; /* TODO sockaddr_storage, even though we can keep the text as cache. */ char ipaddr[CF_MAX_IP_LEN]; /* TODO this is too big at 1025; maybe allocate dynamically from a pool? */ char revdns[NI_MAXHOST]; /* only populated in new protocol */ #ifdef __MINGW32__ char sid[CF_MAXSIDSIZE]; /* 2K size too big! */ #endif uid_t uid; /* TODO move username, hostname etc to a new struct identity. */ char username[CF_MAXVARSIZE]; /* The following are NOT POPULATED with the new protocol, * TODO DEPRECATE! */ /* hostname is copied from client-supplied CAUTH command */ char hostname[CF_MAXVARSIZE]; bool user_data_set; bool rsa_auth; /* TODO DANGEROUS! this is set for the whole connection if only one path * is admitted as maproot. */ int maproot; unsigned char *session_key; char encryption_type; /* TODO pass it through function arguments, EvalContext has nothing to do * with connection-specific data. */ EvalContext *ctx; bool dump_reports; }; typedef struct { ServerConnectionState *conn; int encrypt; int buf_size; char *replybuff; char *replyfile; } ServerFileGetState; /* Used in cf-serverd-functions.c. */ void ServerEntryPoint(EvalContext *ctx, const char *ipaddr, ConnectionInfo *info); AgentConnection *ExtractCallBackChannel(ServerConnectionState *conn); //******************************************************************* // STATE //******************************************************************* #define CLOCK_DRIFT 3600 extern int ACTIVE_THREADS; extern int CFD_MAXPROCESSES; extern bool DENYBADCLOCKS; extern int MAXTRIES; extern bool LOGENCRYPT; extern int COLLECT_INTERVAL; extern bool SERVER_LISTEN; extern ServerAccess SERVER_ACCESS; extern char CFRUNCOMMAND[CF_MAXVARSIZE]; extern bool NEED_REVERSE_LOOKUP; #endif cfengine-3.24.2/cf-serverd/strlist.h0000644000000000000000000000714715010704253017301 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_STRLIST_H #define CFENGINE_STRLIST_H #include /** * Simple length-aware string type. Allocate with string_New. Free * simply with free(). */ struct string { size_t len; /* str length not counting terminating-'\0' */ // size_t size; /* str allocated size */ char str[]; }; struct string *string_New(const char *s); bool string_BoolCompare(const struct string *s1, const struct string *s2); size_t string_MatchCount(const struct string *s1, const struct string *s2); size_t string_ReverseMatchCount(const struct string *s1, const struct string *s2); typedef int (*StringComparatorF)(const struct string **, const struct string **); int string_Compare(const struct string **s1, const struct string **s2); int string_CompareFromEnd(const struct string **s1, const struct string **s2); /** * strlist is a list of #len strings. * * @note strlist can be NULL, which is equivalent to having 0 elements. In * fact, NULL is the properly initialised strlist, it will be * automatically allocated after using StrList_Insert() or * StrList_Append(). * * @note strlist can be a container for *any* kind of data, not only strings, * as long as it is a one-piece memory block, and a struct with first * field being "size_t len". '\0' termination is not needed at any * point, so just insert/append your custom buffers. * To use it like that use the Raw family of functions. */ typedef struct strlist { size_t len; size_t alloc_len; /* for realloc() economy */ struct string *list[]; } StrList; size_t StrList_Len(const StrList *sl); char *StrList_At(const StrList *sl, size_t idx); size_t StrList_Insert(StrList **sl, const char *s, size_t idx); size_t StrList_Append(StrList **sl, const char *s); void StrList_Finalise(StrList **sl); void StrList_Free(StrList **sl); void StrList_Sort(StrList *sl, StringComparatorF f); bool StrList_BinarySearchString(const StrList *slp, const struct string *s, size_t *position); bool StrList_BinarySearch(const StrList *slp, const char *s, size_t *position); size_t StrList_SearchLongestPrefix(const StrList *sl, const char *s, size_t s_len, char separator, bool direction_forward); size_t StrList_SearchForPrefix(const StrList *sl, const char *s, size_t s_len, bool direction_forward); #endif cfengine-3.24.2/cf-serverd/server_access.h0000644000000000000000000001150215010704253020412 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ACCESS_H #define CFENGINE_ACCESS_H #include #include /* StringMap */ #include "strlist.h" /* StrList */ /** * Access control list referring to one resource, e.g. path, class, variable, * literal, bundle. * * @note: Each strlist might be NULL, which is equivalent to having 0 * elements. * * @note: Currently these lists are binary searched, so after filling them up * make sure you call StrList_Sort() to sort them. */ struct admitdeny_acl { StrList *ips; /* admit_ips, deny_ips */ StrList *hostnames; /* admit_hostnames, deny_hostnames */ StrList *keys; /* admit_keys, deny_keys */ StrList *usernames; /* currently used only in roles access promise */ }; /** * This is a list of all resorce ACLs for one resource. E.g. for resource_type * == path, this should contain a list of all paths together with a list of * ACLs (struct resource_acl) referring to the relevant path. * * @note Currently this list of resource_names may be binary searched so it * must be sorted once populated. * * @WARNING Remember to store directories *always* with traling '/', else they * won't match for children dirs (on purpose, and this functionality * was built into StrList_SearchLongestPrefix()). */ struct acl { // enum acl_type resource_type; size_t len; /* Length of resource_names,acls[] */ size_t alloc_len; /* Used for realloc() economy */ StrList *resource_names; /* paths, class names, variables etc */ struct resource_acl { struct admitdeny_acl admit; struct admitdeny_acl deny; } acls[]; }; /* These acls are set on server startup or when promises change, and are * read-only for the rest of their life, thus are thread-safe. */ /* The paths_acl should be populated with directories having a trailing '/' * to be able to tell apart from files. */ extern struct acl *paths_acl; extern struct acl *classes_acl; /* remoteclassesmatching */ extern struct acl *vars_acl; /* remotescalar */ extern struct acl *literals_acl; extern struct acl *query_acl; /* reporting */ extern struct acl *bundles_acl; /* cf-runagent connections*/ /* Roles ACL contains classes regexes under resource_names, but currently only * lists of admit usernames under the admitdeny_acl, no * ips,hostnames,keys. It's used for the "roles" access promise. TODO convert * to a common access promise with resource_type=>"role". */ extern struct acl *roles_acl; /* cf-runagent connections */ size_t ReplaceSpecialVariables(char *buf, size_t buf_size, const char *find1, const char *repl1, const char *find2, const char *repl2, const char *find3, const char *repl3); size_t acl_SortedInsert(struct acl **a, const char *handle); void acl_Free(struct acl *a); void acl_Summarise(const struct acl *acl, const char *title); /* TODO instead of getting all kind of different parameters like * ipaddr,hostname,key, the following functions should get a * "struct peer_id" with all this plus more. */ bool acl_CheckExact(const struct acl *acl, const char *req_string, const char *ipaddr, const char *hostname, const char *key); bool acl_CheckPath(const struct acl *acl, const char *reqpath, const char *ipaddr, const char *hostname, const char *key); bool acl_CheckRegex(const struct acl *acl, const char *req_string, const char *ipaddr, const char *hostname, const char *key, const char *username); #endif cfengine-3.24.2/cf-serverd/cf-serverd-functions.c0000644000000000000000000007376615010704253021650 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* ServerTLSInitialize */ #include #include #include #include #include #include #include #include #include #include #if HAVE_SYSTEMD_SD_DAEMON_H #include // sd_notifyf #endif // HAVE_SYSTEMD_SD_DAEMON_H #define WAIT_INCOMING_TIMEOUT 10 /* see man:listen(3) */ #define DEFAULT_LISTEN_QUEUE_SIZE 128 #define MAX_LISTEN_QUEUE_SIZE 2048 int NO_FORK = false; /* GLOBAL_A */ int GRACEFUL = 0; /*******************************************************************/ /* Command line option parsing */ /*******************************************************************/ static const char *const CF_SERVERD_SHORT_DESCRIPTION = "CFEngine file server daemon"; static const char *const CF_SERVERD_MANPAGE_LONG_DESCRIPTION = "cf-serverd is a socket listening daemon providing two services: it acts as a file server for remote file copying " "and it allows an authorized cf-runagent to start a cf-agent run. cf-agent typically connects to a " "cf-serverd instance to request updated policy code, but may also request additional files for download. " "cf-serverd employs role based access control (defined in policy code) to authorize requests. " "Note: this daemon reloads it's config when the SIGHUP signal is received."; static const Component COMPONENT = { .name = "cf-serverd", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"help", no_argument, 0, 'h'}, {"log-level", required_argument, 0, 'g'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"file", required_argument, 0, 'f'}, {"define", required_argument, 0, 'D'}, {"negate", required_argument, 0, 'N'}, {"no-lock", no_argument, 0, 'K'}, {"inform", no_argument, 0, 'I'}, {"diagnostic", no_argument, 0, 'x'}, {"no-fork", no_argument, 0, 'F'}, {"ld-library-path", required_argument, 0, 'L'}, {"generate-avahi-conf", no_argument, 0, 'A'}, {"color", optional_argument, 0, 'C'}, {"timestamp", no_argument, 0, 'l'}, {"graceful-detach", optional_argument, 0, 't'}, /* Only long option for the rest */ {"ignore-preferred-augments", no_argument, 0, 0}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Enable debugging output", "Output verbose information about the behaviour of the agent", "Output the version of the software", "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.", "Define a list of comma separated classes to be defined at the start of execution", "Define a list of comma separated classes to be undefined at the start of execution", "Ignore locking constraints during execution (ifelapsed/expireafter) if \"too soon\" to run", "Print basic information about changes made to the system, i.e. promises repaired", "Activate internal diagnostics (developers only)", "Run as a foreground processes (do not fork)", "Set the internal value of LD_LIBRARY_PATH for child processes", "Generates avahi configuration file to enable policy server to be discovered in the network", "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", "Log timestamps on each line of log output", "Terminate gracefully on SIGHUP by detaching from systemd and waiting n seconds before terminating", "Ignore def_preferred.json file in favor of def.json", NULL }; #ifdef HAVE_AVAHI_CLIENT_CLIENT_H #ifdef HAVE_AVAHI_COMMON_ADDRESS_H static int GenerateAvahiConfig(const char *path) { FILE *fout = safe_fopen(path, "w+"); if (fout == NULL) { Log(LOG_LEVEL_ERR, "Unable to open '%s'", path); return -1; } Writer *writer = FileWriter(fout); fprintf(fout, "\n"); fprintf(fout, "\n"); XmlComment(writer, "This file has been automatically generated by cf-serverd."); XmlStartTag(writer, "service-group", 0); FprintAvahiCfengineTag(fout); XmlStartTag(writer, "service", 0); XmlTag(writer, "type", "_cfenginehub._tcp",0); DetermineCfenginePort(); XmlStartTag(writer, "port", 0); WriterWriteF(writer, "%d", CFENGINE_PORT); XmlEndTag(writer, "port"); XmlEndTag(writer, "service"); XmlEndTag(writer, "service-group"); fclose(fout); return 0; } #define SUPPORT_AVAHI_CONFIG #endif #endif GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int c; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_SERVER, GetTTYInteractive()); int longopt_idx; while ((c = getopt_long(argc, argv, "dvIKf:g:D:N:VSxLFMhAC::lt::", OPTIONS, &longopt_idx)) != -1) { switch (c) { case 'f': GenericAgentConfigSetInputFile(config, GetInputDir(), optarg); MINUSF = true; break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); NO_FORK = true; break; case 'K': config->ignore_locks = true; break; case 'D': { StringSet *defined_classes = StringSetFromString(optarg, ','); if (! config->heap_soft) { config->heap_soft = defined_classes; } else { StringSetJoin(config->heap_soft, defined_classes, xstrdup); StringSetDestroy(defined_classes); } } break; case 'N': { StringSet *negated_classes = StringSetFromString(optarg, ','); if (! config->heap_negated) { config->heap_negated = negated_classes; } else { StringSetJoin(config->heap_negated, negated_classes, xstrdup); StringSetDestroy(negated_classes); } } break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); NO_FORK = true; break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'F': NO_FORK = true; break; case 'L': { Log(LOG_LEVEL_VERBOSE, "Setting LD_LIBRARY_PATH to '%s'", optarg); setenv_wrapper("LD_LIBRARY_PATH", optarg, 1); break; } case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'h': { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-serverd", time(NULL), CF_SERVERD_SHORT_DESCRIPTION, CF_SERVERD_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(out); DoCleanupAndExit(EXIT_SUCCESS); } case 'x': Log(LOG_LEVEL_ERR, "Self-diagnostic functionality is retired."); DoCleanupAndExit(EXIT_SUCCESS); case 'A': #ifdef SUPPORT_AVAHI_CONFIG Log(LOG_LEVEL_NOTICE, "Generating Avahi configuration file."); if (GenerateAvahiConfig("/etc/avahi/services/cfengine-hub.service") != 0) { DoCleanupAndExit(EXIT_FAILURE); } cf_popen("/etc/init.d/avahi-daemon restart", "r", true); Log(LOG_LEVEL_NOTICE, "Avahi configuration file generated successfully."); #else Log(LOG_LEVEL_ERR, "Generating avahi configuration can only be done when avahi-daemon and libavahi are installed on the machine."); #endif DoCleanupAndExit(EXIT_SUCCESS); case 'C': if (!GenericAgentConfigParseColor(config, optarg)) { DoCleanupAndExit(EXIT_FAILURE); } break; case 'l': LoggingEnableTimestamps(true); break; case 't': if (optarg == NULL) { GRACEFUL = 60; } else { GRACEFUL = StringToLongExitOnError(optarg); } break; /* long options only */ case 0: { const char *const option_name = OPTIONS[longopt_idx].name; if (StringEqual(option_name, "ignore-preferred-augments")) { config->ignore_preferred_augments = true; } break; } default: { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_FAILURE); } } if (!GenericAgentConfigParseArguments(config, argc - optind, argv + optind)) { Log(LOG_LEVEL_ERR, "Too many arguments"); DoCleanupAndExit(EXIT_FAILURE); } return config; } /*********************************************************************/ /* Policy Reloading */ /*********************************************************************/ static void DeleteAuthList(Auth **list, Auth **list_tail) { Auth *ap = *list; while (ap != NULL) { Auth *ap_next = ap->next; DeleteItemList(ap->accesslist); DeleteItemList(ap->maproot); free(ap->path); free(ap); /* Just make sure the tail was consistent. */ if (ap_next == NULL) assert(ap == *list_tail); ap = ap_next; } *list = NULL; *list_tail = NULL; } /* Must not be called unless ACTIVE_THREADS is zero: */ static void ClearAuthAndACLs(void) { /* Must have no currently open connections to free the ACLs. */ assert(SERVER_ACCESS.connectionlist == NULL); /* Bundle server access_rules legacy ACLs */ DeleteAuthList(&SERVER_ACCESS.admit, &SERVER_ACCESS.admittail); DeleteAuthList(&SERVER_ACCESS.deny, &SERVER_ACCESS.denytail); DeleteAuthList(&SERVER_ACCESS.varadmit, &SERVER_ACCESS.varadmittail); DeleteAuthList(&SERVER_ACCESS.vardeny, &SERVER_ACCESS.vardenytail); /* body server control ACLs */ DeleteItemList(SERVER_ACCESS.trustkeylist); SERVER_ACCESS.trustkeylist = NULL; DeleteItemList(SERVER_ACCESS.attackerlist); SERVER_ACCESS.attackerlist = NULL; DeleteItemList(SERVER_ACCESS.nonattackerlist); SERVER_ACCESS.nonattackerlist = NULL; DeleteItemList(SERVER_ACCESS.allowuserlist); SERVER_ACCESS.allowuserlist = NULL; DeleteItemList(SERVER_ACCESS.multiconnlist); SERVER_ACCESS.multiconnlist = NULL; DeleteItemList(SERVER_ACCESS.allowuserlist); SERVER_ACCESS.allowuserlist = NULL; DeleteItemList(SERVER_ACCESS.allowlegacyconnects); SERVER_ACCESS.allowlegacyconnects = NULL; StringMapDestroy(SERVER_ACCESS.path_shortcuts); SERVER_ACCESS.path_shortcuts = NULL; free(SERVER_ACCESS.allowciphers); SERVER_ACCESS.allowciphers = NULL; free(SERVER_ACCESS.allowtlsversion); SERVER_ACCESS.allowtlsversion = NULL; /* body server control new ACLs */ NEED_REVERSE_LOOKUP = false; acl_Free(paths_acl); paths_acl = NULL; acl_Free(classes_acl); classes_acl = NULL; acl_Free(vars_acl); vars_acl = NULL; acl_Free(literals_acl); literals_acl = NULL; acl_Free(query_acl); query_acl = NULL; acl_Free(bundles_acl); bundles_acl = NULL; acl_Free(roles_acl); roles_acl = NULL; } static void CheckFileChanges(EvalContext *ctx, Policy **policy, GenericAgentConfig *config) { Log(LOG_LEVEL_DEBUG, "Checking file updates for input file '%s'", config->input_file); time_t validated_at = ReadTimestampFromPolicyValidatedFile(config, NULL); bool reload_config = false; if (config->agent_specific.daemon.last_validated_at < validated_at) { Log(LOG_LEVEL_VERBOSE, "New promises detected..."); reload_config = true; } if (ReloadConfigRequested()) { Log(LOG_LEVEL_VERBOSE, "Force reload of inputs files..."); reload_config = true; } if (reload_config) { ClearRequestReloadConfig(); /* Rereading policies now, so update timestamp. */ config->agent_specific.daemon.last_validated_at = validated_at; if (GenericAgentArePromisesValid(config)) { Log(LOG_LEVEL_NOTICE, "Rereading policy file '%s'", config->input_file); /* STEP 1: Free everything */ EvalContextClear(ctx); strcpy(VDOMAIN, "undefined.domain"); ClearAuthAndACLs(); PolicyDestroy(*policy); *policy = NULL; /* STEP 2: Set Environment, Parse and Evaluate policy */ /* * TODO why is this done separately here? What's the difference to * calling the same steps as in cf-serverd.c:main()? Those are: * GenericAgentConfigApply(); // not here! * GenericAgentDiscoverContext(); // not here! * EvalContextClassPutHard("server"); // only here! * if (GenericAgentCheckPolicy()) // not here! * policy = LoadPolicy(); * ThisAgentInit(); // not here, only calls umask() * ReloadHAConfig(); // only here! * KeepPromises(); * Summarize(); * Plus the following from within StartServer() which is only * called during startup: * InitSignals(); // not here * ServerTLSInitialize(); // not here * SetServerListenState(); // not here * InitServer() // not here * PolicyNew()+AcquireServerLock() // not here * PrepareServer(sd); // not here * CollectCallStart(); // both */ EvalContextSetPolicyServerFromFile(ctx, GetWorkDir()); UpdateLastPolicyUpdateTime(ctx); DetectEnvironment(ctx); GenericAgentDiscoverContext(ctx, config, NULL); /* During startup this is done in GenericAgentDiscoverContext(). */ EvalContextClassPutHard(ctx, CF_AGENTTYPES[AGENT_TYPE_SERVER], "cfe_internal,source=agent"); time_t t = SetReferenceTime(); UpdateTimeClasses(ctx, t); /* TODO BUG: this modifies config, but previous config has not * been reset/free'd. Ideally we would want LoadPolicy to not * modify config at all, but only modify ctx. */ *policy = LoadPolicy(ctx, config); /* Reload HA related configuration */ ReloadHAConfig(); bool unresolved_constraints; KeepPromises(ctx, *policy, config, &unresolved_constraints); Summarize(); if (unresolved_constraints) { Log(LOG_LEVEL_WARNING, "Unresolved variables found in cf-serverd policy, scheduling policy reload"); RequestReloadConfig(); } } else { Log(LOG_LEVEL_INFO, "File changes contain errors -- ignoring"); } } else { Log(LOG_LEVEL_DEBUG, "No new promises found"); EvalContextUpdateDumpReports(ctx); } } /* Set up standard signal-handling. */ static void InitSignals() { MakeSignalPipe(); signal(SIGINT, HandleSignalsForDaemon); signal(SIGTERM, HandleSignalsForDaemon); signal(SIGBUS, HandleSignalsForDaemon); signal(SIGHUP, HandleSignalsForDaemon); signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, HandleSignalsForDaemon); signal(SIGUSR2, HandleSignalsForDaemon); } /* Prepare synthetic agent promise and lock it. */ static CfLock AcquireServerLock(EvalContext *ctx, GenericAgentConfig *config, Policy *server_policy) { Promise *pp = NULL; { Bundle *bp = PolicyAppendBundle(server_policy, NamespaceDefault(), "server_cfengine_bundle", "agent", NULL, NULL); BundleSection *sp = BundleAppendSection(bp, "server_cfengine"); pp = BundleSectionAppendPromise(sp, config->input_file, (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL, NULL); } assert(pp); return AcquireLock(ctx, pp->promiser, VUQNAME, CFSTARTTIME, 0, 1, pp, false); } /* Final preparations for running as server */ static void PrepareServer(int sd) { if (sd != -1) { Log(LOG_LEVEL_VERBOSE, "Listening for connections on socket descriptor %d ...", sd); } if (!NO_FORK) #ifdef __MINGW32__ { Log(LOG_LEVEL_VERBOSE, "Windows does not support starting processes in the background - running in foreground"); } #else { if (fork() != 0) /* parent */ { _exit(EXIT_SUCCESS); } ActAsDaemon(); } #endif /* Close sd on exec, needed for not passing the socket to cf-runagent * spawned commands. */ SetCloseOnExec(sd, true); Log(LOG_LEVEL_NOTICE, "Server is starting..."); WritePID("cf-serverd.pid"); /* Arranges for cleanup() to tidy it away */ } #if HAVE_SYSTEMD_SD_DAEMON_H /* Graceful Stop * This runs a new main process that will die and that init can restart (as systemd can do). * This can prevent systemd from killing us if there is a problem. * But this makes it possible to finish handling connections while systemd tries to restart us. * If there is no systemd make sure alternative init restarts us. */ static void GracefulStop() { Log(LOG_LEVEL_NOTICE, "Stopping gracefully"); /* Fork twice and tell systemd to follow our grand child * The child will exit and systemd will follow grand child * The grand child will exit and systemd will ignore us */ int child_pipe[2]; if (pipe(child_pipe) == -1) { Log(LOG_LEVEL_ERR, "Cannot detach graceful process (no pipe)"); return; } #ifdef HAVE_SD_NOTIFY_BARRIER unsigned char anything = 1; int grand_child_pipe[2]; if (pipe(grand_child_pipe) == -1) { Log(LOG_LEVEL_ERR, "Cannot detach graceful process (no pipe)"); return; } #endif pid_t child_pid = fork(); if (child_pid == 0) { /* Child */ /* double fork to reattach to init, otherwise it doesn't receive sigchild */ pid_t grand_child_pid = fork(); if (grand_child_pid == 0) { /* grand child */ /* Wait for systemd to follow us then exit. */ #ifdef HAVE_SD_NOTIFY_BARRIER /* use sd_notify_barrier in parent to know when to exit on recent versions of systemd */ close(grand_child_pipe[1]); read(grand_child_pipe[0], &anything, sizeof(anything)); close(grand_child_pipe[0]); #else /* use sleep synchronization on old systemd */ sleep(2); #endif exit(0); } else { #ifdef HAVE_SD_NOTIFY_BARRIER /* not needed here */ close(grand_child_pipe[0]); close(grand_child_pipe[1]); #endif /* first child */ /* Send grand child pid to parent then exit to give grand child to systemd */ close(child_pipe[0]); write(child_pipe[1], &grand_child_pid, sizeof(grand_child_pid)); close(child_pipe[1]); exit(0); } } else { /* Parent */ pid_t grand_child_pid; /* read grand child pid from first child */ close(child_pipe[1]); read(child_pipe[0], &grand_child_pid, sizeof(grand_child_pid)); close(child_pipe[0]); waitpid(child_pid, NULL, 0); /* send it to systemd */ sd_notifyf(0, "MAINPID=%d", grand_child_pid); #ifdef HAVE_SD_NOTIFY_BARRIER sd_notify_barrier(0, 2 * 1000000); /* notify grand child it can die */ close(grand_child_pipe[0]); write(grand_child_pipe[0], &anything, sizeof(anything)); close(grand_child_pipe[1]); #endif } } #endif // HAVE_SYSTEMD_SD_DAEMON_H /* Wait for connection-handler threads to finish their work. * * @return Number of live threads remaining after waiting. */ static int WaitOnThreads(int graceful_time) { int result = 1; for (int i = graceful_time; i > 0; i--) { ThreadLock(cft_server_children); result = ACTIVE_THREADS; ThreadUnlock(cft_server_children); if (result == 0) { break; } Log(LOG_LEVEL_VERBOSE, "Waiting %ds for %d connection threads to finish", i, result); sleep(1); } if (result > 0) { Log(LOG_LEVEL_VERBOSE, "There are %d connection threads left, exiting anyway", result); } else { assert(result == 0); Log(LOG_LEVEL_VERBOSE, "All threads are done, cleaning up allocations"); ClearAuthAndACLs(); ServerTLSDeInitialize(NULL, NULL, NULL); } return result; } static void CollectCallIfDue(EvalContext *ctx) { /* Check whether we have established peering with a hub */ if (CollectCallHasPending()) { extern int COLLECT_WINDOW; int waiting_queue = 0; int new_client = CollectCallGetPending(&waiting_queue); assert(new_client >= 0); if (waiting_queue > COLLECT_WINDOW) { Log(LOG_LEVEL_INFO, "Abandoning collect call attempt with queue longer than collect_window [%d > %d]", waiting_queue, COLLECT_WINDOW); cf_closesocket(new_client); CollectCallMarkProcessed(); } else { ConnectionInfo *info = ConnectionInfoNew(); assert(info); Log(LOG_LEVEL_DEBUG, "Hub has %d seconds to complete report collection (collect_window)", COLLECT_WINDOW); ConnectionInfoSetSocket(info, new_client); info->is_call_collect = true; /* Mark processed when done. */ ServerEntryPoint(ctx, PolicyServerGetIP(), info); } } } /* Check for new policy just before spawning a thread. * * Server reconfiguration can only happen when no threads are active, * so this is a good time to do it; but we do still have to check for * running threads. */ static void PolicyUpdateIfSafe(EvalContext *ctx, Policy **policy, GenericAgentConfig *config) { ThreadLock(cft_server_children); int prior = COLLECT_INTERVAL; if (ACTIVE_THREADS == 0) { CheckFileChanges(ctx, policy, config); } ThreadUnlock(cft_server_children); /* Check for change in call-collect interval: */ if (prior != COLLECT_INTERVAL) { /* Start, stop or change schedule, as appropriate. */ CollectCallStart(COLLECT_INTERVAL); } } /* Try to accept a connection; handle if we get one. */ static void AcceptAndHandle(EvalContext *ctx, int sd) { /* TODO embed ConnectionInfo into ServerConnectionState. */ ConnectionInfo *info = ConnectionInfoNew(); /* Uses xcalloc() */ info->ss_len = sizeof(info->ss); info->sd = accept(sd, (struct sockaddr *) &info->ss, &info->ss_len); if (info->sd == -1) { Log(LOG_LEVEL_INFO, "Error accepting connection (%s)", GetErrorStr()); ConnectionInfoDestroy(&info); return; } Log(LOG_LEVEL_DEBUG, "Socket descriptor returned from accept(): %d", info->sd); /* Just convert IP address to string, no DNS lookup. */ char ipaddr[CF_MAX_IP_LEN] = ""; getnameinfo((const struct sockaddr *) &info->ss, info->ss_len, ipaddr, sizeof(ipaddr), NULL, 0, NI_NUMERICHOST); /* IPv4 mapped addresses (e.g. "::ffff:192.168.1.2") are * hereby represented with their IPv4 counterpart. */ ServerEntryPoint(ctx, MapAddress(ipaddr), info); } static size_t GetListenQueueSize(void) { const char *const queue_size_var = getenv("CF_SERVERD_LISTEN_QUEUE_SIZE"); if (queue_size_var != NULL) { long queue_size; int ret = StringToLong(queue_size_var, &queue_size); if ((ret == 0) && (queue_size > 0) && (queue_size <= MAX_LISTEN_QUEUE_SIZE)) { return (size_t) queue_size; } Log(LOG_LEVEL_WARNING, "$CF_SERVERD_LISTEN_QUEUE_SIZE = '%s' doesn't specify a valid number for listen queue size, " "falling back to default (%d).", queue_size_var, DEFAULT_LISTEN_QUEUE_SIZE); } return DEFAULT_LISTEN_QUEUE_SIZE; } /** * @retval >0 Number of threads still working * @retval 0 All threads are done * @retval -1 Server didn't run */ int StartServer(EvalContext *ctx, Policy **policy, GenericAgentConfig *config) { InitSignals(); bool tls_init_ok = ServerTLSInitialize(NULL, NULL, NULL); if (!tls_init_ok) { return -1; } size_t queue_size = GetListenQueueSize(); int sd = SetServerListenState(ctx, queue_size, NULL, SERVER_LISTEN, &InitServer); /* Necessary for our use of select() to work in WaitForIncoming(): */ assert((size_t) sd < sizeof(fd_set) * CHAR_BIT && (size_t) GetSignalPipe() < sizeof(fd_set) * CHAR_BIT); Policy *server_cfengine_policy = PolicyNew(); CfLock thislock = AcquireServerLock(ctx, config, server_cfengine_policy); if (thislock.lock == NULL) { PolicyDestroy(server_cfengine_policy); if (sd >= 0) { cf_closesocket(sd); } return -1; } PrepareServer(sd); CollectCallStart(COLLECT_INTERVAL); while (!IsPendingTermination()) { CollectCallIfDue(ctx); int selected = WaitForIncoming(sd, WAIT_INCOMING_TIMEOUT); Log(LOG_LEVEL_DEBUG, "select(): %d", selected); if (selected == -1) { Log(LOG_LEVEL_ERR, "Error while waiting for connections. (select: %s)", GetErrorStr()); break; } else if (selected >= 0) /* timeout or success */ { PolicyUpdateIfSafe(ctx, policy, config); /* Is there a new connection pending at our listening socket? */ if (selected > 0) { AcceptAndHandle(ctx, sd); } } /* else: interrupted, maybe pending termination. */ #if HAVE_SYSTEMD_SD_DAEMON_H /* if we have a reload config requested but not yet processed * it means we still have clients, let's do a graceful restart */ if (ReloadConfigRequested() && GRACEFUL != 0) { Log(LOG_LEVEL_INFO, "Doing a Graceful restart"); break; } #endif } Log(LOG_LEVEL_NOTICE, "Cleaning up and exiting..."); CollectCallStop(); if (sd != -1) { Log(LOG_LEVEL_VERBOSE, "Closing listening socket"); cf_closesocket(sd); /* Close listening socket */ } int threads_left; #if HAVE_SYSTEMD_SD_DAEMON_H if (ReloadConfigRequested() && GRACEFUL != 0) { /* This is a graceful restart */ YieldCurrentLock(thislock); // must be done before restart GracefulStop(); threads_left = WaitOnThreads(GRACEFUL); } else #endif { /* This is a graceful exit, give 2 seconds chance to threads. */ threads_left = WaitOnThreads(2); YieldCurrentLock(thislock); // can we do this one first too ? } PolicyDestroy(server_cfengine_policy); return threads_left; } cfengine-3.24.2/cf-serverd/server.c0000644000000000000000000003730415010704253017074 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include /* SendTransaction,ReceiveTransaction */ #include /* TLSVerifyPeer */ #include #include #include #include #include #include /* ProtocolIsTLS() */ #include /* ServerTLS* */ #include #include #include #include /* LoggingPrivSetContext */ #include #include "server_classic.h" /* BusyWithClassicConnection */ /* The only exported function in this file is the following, used only in cf-serverd-functions.c. void ServerEntryPoint(EvalContext *ctx, const char *ipaddr, ConnectionInfo *info); TODO move this file to cf-serverd-functions.c or most probably server_common.c. */ //****************************************************************** // GLOBAL STATE //****************************************************************** int ACTIVE_THREADS = 0; /* GLOBAL_X */ int CFD_MAXPROCESSES = 0; /* GLOBAL_P */ bool DENYBADCLOCKS = true; /* GLOBAL_P */ int MAXTRIES = 5; /* GLOBAL_P */ bool LOGENCRYPT = false; /* GLOBAL_P */ int COLLECT_INTERVAL = 0; /* GLOBAL_P */ int COLLECT_WINDOW = 30; /* GLOBAL_P */ bool SERVER_LISTEN = true; /* GLOBAL_P */ ServerAccess SERVER_ACCESS = { 0 }; /* GLOBAL_P */ char CFRUNCOMMAND[CF_MAXVARSIZE] = { 0 }; /* GLOBAL_P */ /******************************************************************/ static void SpawnConnection(EvalContext *ctx, const char *ipaddr, ConnectionInfo *info); static void PurgeOldConnections(Item **list, time_t now); static void *HandleConnection(void *conn); static ServerConnectionState *NewConn(EvalContext *ctx, ConnectionInfo *info); static void DeleteConn(ServerConnectionState *conn); /****************************************************************************/ void ServerEntryPoint(EvalContext *ctx, const char *ipaddr, ConnectionInfo *info) { Log(LOG_LEVEL_VERBOSE, "Obtained IP address of '%s' on socket %d from accept", ipaddr, ConnectionInfoSocket(info)); /* TODO change nonattackerlist, attackerlist and especially connectionlist * to binary searched lists, or remove them from the main thread! */ if (SERVER_ACCESS.nonattackerlist && !IsMatchItemIn(SERVER_ACCESS.nonattackerlist, ipaddr)) { Log(LOG_LEVEL_ERR, "Remote host '%s' not in allowconnects, denying connection", ipaddr); } else if (IsMatchItemIn(SERVER_ACCESS.attackerlist, ipaddr)) { Log(LOG_LEVEL_ERR, "Remote host '%s' is in denyconnects, denying connection", ipaddr); } else { time_t now = time(NULL); if (now == -1) { now = 0; } PurgeOldConnections(&SERVER_ACCESS.connectionlist, now); bool allow = IsMatchItemIn(SERVER_ACCESS.multiconnlist, ipaddr); if (!allow) { ThreadLock(cft_count); /* At most one connection allowed for this host: */ allow = !IsItemIn(SERVER_ACCESS.connectionlist, ipaddr); ThreadUnlock(cft_count); if (!allow) /* Duplicate. */ { Log(LOG_LEVEL_ERR, "Remote host '%s' is not in allowallconnects, denying second simultaneous connection", ipaddr); } } if (allow) { char intime[PRINTSIZE(now)]; xsnprintf(intime, sizeof(intime), "%jd", (intmax_t) now); ThreadLock(cft_count); PrependItem(&SERVER_ACCESS.connectionlist, ipaddr, intime); ThreadUnlock(cft_count); SpawnConnection(ctx, ipaddr, info); return; /* Success */ } } /* Tidy up on failure: */ if (info->is_call_collect) { CollectCallMarkProcessed(); } cf_closesocket(ConnectionInfoSocket(info)); ConnectionInfoDestroy(&info); } /**********************************************************************/ static void PurgeOldConnections(Item **list, time_t now) /* Some connections might not terminate properly. These should be cleaned every couple of hours. That should be enough to prevent spamming. */ { assert(list != NULL); Log(LOG_LEVEL_DEBUG, "Purging Old Connections..."); ThreadLock(cft_count); Item *next; for (Item *ip = *list; ip != NULL; ip = next) { int then = 0; sscanf(ip->classes, "%d", &then); next = ip->next; if (now > then + 2 * SECONDS_PER_HOUR) { Log(LOG_LEVEL_VERBOSE, "IP address '%s' has been more than two hours in connection list, purging", ip->name); DeleteItem(list, ip); } } ThreadUnlock(cft_count); Log(LOG_LEVEL_DEBUG, "Done purging old connections"); } /*********************************************************************/ static void SpawnConnection(EvalContext *ctx, const char *ipaddr, ConnectionInfo *info) { ServerConnectionState *conn = NULL; int ret; pthread_t tid; pthread_attr_t threadattrs; conn = NewConn(ctx, info); /* freed in HandleConnection */ int sd_accepted = ConnectionInfoSocket(info); strlcpy(conn->ipaddr, ipaddr, CF_MAX_IP_LEN ); Log(LOG_LEVEL_VERBOSE, "New connection (from %s, sd %d), spawning new thread...", conn->ipaddr, sd_accepted); ret = pthread_attr_init(&threadattrs); if (ret != 0) { Log(LOG_LEVEL_ERR, "SpawnConnection: Unable to initialize thread attributes (%s)", GetErrorStr()); goto err; } ret = pthread_attr_setdetachstate(&threadattrs, PTHREAD_CREATE_DETACHED); if (ret != 0) { Log(LOG_LEVEL_ERR, "SpawnConnection: Unable to set thread to detached state (%s).", GetErrorStr()); goto cleanup; } ret = pthread_attr_setstacksize(&threadattrs, 1024 * 1024); if (ret != 0) { Log(LOG_LEVEL_WARNING, "SpawnConnection: Unable to set thread stack size (%s).", GetErrorStr()); /* Continue with default thread stack size. */ } ret = pthread_create(&tid, &threadattrs, HandleConnection, conn); if (ret != 0) { errno = ret; Log(LOG_LEVEL_ERR, "Unable to spawn worker thread. (pthread_create: %s)", GetErrorStr()); goto cleanup; } cleanup: pthread_attr_destroy(&threadattrs); err: if (ret != 0) { Log(LOG_LEVEL_WARNING, "Thread is being handled from main loop!"); HandleConnection(conn); } } /*********************************************************************/ static void DisableSendDelays(int sockfd) { int yes = 1; if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *) &yes, sizeof(yes)) == -1) { Log(LOG_LEVEL_INFO, "Unable to disable Nagle algorithm, expect performance problems. (setsockopt(TCP_NODELAY): %s)", GetErrorStr()); } } /*********************************************************************/ /* TODO performance fix this to avoid the StringConcatenate() reallocations, * if only we could set a static logging prefix. */ static char *LogHook(LoggingPrivContext *log_ctx, ARG_UNUSED LogLevel level, const char *message) { const char *aligned_ipaddr = log_ctx->param; return StringConcatenate(2, aligned_ipaddr, message); } /* TRIES: counts the number of consecutive connections dropped. */ static int TRIES = 0; static void *HandleConnection(void *c) { ServerConnectionState *conn = c; int ret; /* Set logging prefix to be the IP address for all of thread's lifetime. */ /* These stack-allocated variables should be valid for all the lifetime of * the thread. */ char aligned_ipaddr[CF_MAX_IP_LEN + 2]; LoggingPrivContext log_ctx = { .log_hook = LogHook, .param = aligned_ipaddr }; strlcpy(aligned_ipaddr, conn->ipaddr, sizeof(aligned_ipaddr)); strlcat(aligned_ipaddr, "> ", sizeof(aligned_ipaddr)); /* Pad with enough spaces for IPv4 addresses to be aligned. Max chars are * 15 for the address plus two for "> " == 17. */ size_t len; for (len = strlen(aligned_ipaddr); len < 17; len++) { aligned_ipaddr[len] = ' '; } aligned_ipaddr[len] = '\0'; LoggingPrivSetContext(&log_ctx); Log(LOG_LEVEL_INFO, "Accepting connection"); /* We test if number of active threads is greater than max, if so we deny connection, if it happened too many times within a short timeframe then we kill ourself.TODO this test should be done *before* spawning the thread. */ ThreadLock(cft_server_children); if (ACTIVE_THREADS > CFD_MAXPROCESSES) { if (TRIES > MAXTRIES) { /* This happens when no thread was freed while we had to drop 5 * (or maxconnections/3) consecutive connections, because none of * the existing threads finished. */ Log(LOG_LEVEL_CRIT, "Server seems to be paralyzed. DOS attack? " "Committing apoptosis..."); ThreadUnlock(cft_server_children); FatalError(conn->ctx, "Terminating"); } TRIES++; Log(LOG_LEVEL_ERR, "Too many threads (%d > %d), dropping connection! " "Increase server maxconnections?", ACTIVE_THREADS, CFD_MAXPROCESSES); ThreadUnlock(cft_server_children); goto conndone; } ACTIVE_THREADS++; TRIES = 0; ThreadUnlock(cft_server_children); DisableSendDelays(ConnectionInfoSocket(conn->conn_info)); /* 20 times the connect() timeout should be enough to avoid MD5 * computation timeouts on big files on old slow Solaris 8 machines. */ SetReceiveTimeout(ConnectionInfoSocket(conn->conn_info), CONNTIMEOUT * 20 * 1000); if (conn->conn_info->status != CONNECTIONINFO_STATUS_ESTABLISHED) { /* Decide the protocol used. */ bool success = ServerTLSPeek(conn->conn_info); if (!success) { goto dethread; } } ProtocolVersion protocol_version = ConnectionInfoProtocolVersion(conn->conn_info); if (ProtocolIsTLS(protocol_version)) { bool established = ServerTLSSessionEstablish(conn, NULL); if (!established) { goto dethread; } } else if (ProtocolIsClassic(protocol_version)) { /* This connection is legacy protocol. * We are not allowing it by default. */ if (!IsMatchItemIn(SERVER_ACCESS.allowlegacyconnects, conn->ipaddr)) { Log(LOG_LEVEL_INFO, "Connection is not using latest protocol, denying"); goto dethread; } } else { UnexpectedError("HandleConnection: ProtocolVersion %d!", ConnectionInfoProtocolVersion(conn->conn_info)); goto dethread; } /* ========================= MAIN LOOPS ========================= */ if (ProtocolIsTLS(protocol_version)) { /* New protocol does DNS reverse look up of the connected * IP address, to check hostname access_rules. */ if (NEED_REVERSE_LOOKUP) { ret = getnameinfo((const struct sockaddr *) &conn->conn_info->ss, conn->conn_info->ss_len, conn->revdns, sizeof(conn->revdns), NULL, 0, NI_NAMEREQD); if (ret != 0) { Log(LOG_LEVEL_INFO, "Reverse lookup failed (getnameinfo: %s)!", gai_strerror(ret)); } else { Log(LOG_LEVEL_INFO, "Hostname (reverse looked up): %s", conn->revdns); } } while (BusyWithNewProtocol(conn->ctx, conn)) { } } else if (ProtocolIsClassic(protocol_version)) { while (BusyWithClassicConnection(conn->ctx, conn)) { } } else { assert(!"Bogus protocol version - but we checked that already !"); } /* ============================================================ */ Log(LOG_LEVEL_INFO, "Closing connection, terminating thread"); dethread: ThreadLock(cft_server_children); ACTIVE_THREADS--; ThreadUnlock(cft_server_children); conndone: if (conn->conn_info->is_call_collect) { CollectCallMarkProcessed(); } DeleteConn(conn); return NULL; } /***************************************************************/ /* Toolkit/Class: conn */ /***************************************************************/ static ServerConnectionState *NewConn(EvalContext *ctx, ConnectionInfo *info) { #if 1 /* TODO: why do we do this ? We fail if getsockname() fails, but * don't use the information it returned. Was the intent to use * it to fill in conn->ipaddr ? */ struct sockaddr_storage addr; socklen_t size = sizeof(addr); if (getsockname(ConnectionInfoSocket(info), (struct sockaddr *)&addr, &size) == -1) { Log(LOG_LEVEL_ERR, "Could not obtain socket address. (getsockname: '%s')", GetErrorStr()); return NULL; } #endif ServerConnectionState *conn = xcalloc(1, sizeof(*conn)); conn->ctx = ctx; conn->conn_info = info; conn->encryption_type = 'c'; conn->dump_reports = EvalContextGetDumpReports(ctx); /* Only public files (chmod o+r) accessible to non-root */ conn->uid = CF_UNKNOWN_OWNER; /* Careful, 0 is root! */ /* conn->maproot is false: only public files (chmod o+r) are accessible */ Log(LOG_LEVEL_DEBUG, "New connection (socket %d).", ConnectionInfoSocket(info)); return conn; } /** * @note This function is thread-safe. Do NOT wrap it with mutex! */ static void DeleteConn(ServerConnectionState *conn) { int sd = ConnectionInfoSocket(conn->conn_info); if (sd != SOCKET_INVALID) { cf_closesocket(sd); } ConnectionInfoDestroy(&conn->conn_info); if (conn->ipaddr[0] != '\0') { ThreadLock(cft_count); DeleteItemMatching(&SERVER_ACCESS.connectionlist, conn->ipaddr); ThreadUnlock(cft_count); } *conn = (ServerConnectionState) {0}; free(conn->session_key); free(conn); } cfengine-3.24.2/cf-serverd/server_transform.c0000644000000000000000000014617615010704253021177 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* HashControls */ #include /* IsDirReal */ #include /* IsRegex */ #include #include #include #include // GetWorkDir() #include "server_common.h" /* PreprocessRequestPath */ #include "server_access.h" #include "strlist.h" #include static PromiseResult KeepServerPromise(EvalContext *ctx, const Promise *pp, void *param); static void InstallServerAuthPath(const char *path, Auth **list, Auth **listtail); static void KeepServerRolePromise(EvalContext *ctx, const Promise *pp); static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy); static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config, bool *unresolved_vars); static void KeepBundlesAccessPromise(EvalContext *ctx, const Promise *pp); static Auth *GetAuthPath(const char *path, Auth *list); extern int COLLECT_INTERVAL; extern int COLLECT_WINDOW; extern bool SERVER_LISTEN; /*******************************************************************/ /* GLOBAL VARIABLES */ /*******************************************************************/ extern int CFD_MAXPROCESSES; extern int NO_FORK; extern bool DENYBADCLOCKS; extern int MAXTRIES; extern bool LOGENCRYPT; /*******************************************************************/ static void KeepFileAccessPromise(const EvalContext *ctx, const Promise *pp); static void KeepLiteralAccessPromise(EvalContext *ctx, const Promise *pp, const char *type); static void KeepQueryAccessPromise(EvalContext *ctx, const Promise *pp); /*******************************************************************/ /* Level */ /*******************************************************************/ void Summarize() { Auth *ptr; Item *ip, *ipr; Log(LOG_LEVEL_VERBOSE, " === BEGIN summary of access promises === "); Log(LOG_LEVEL_VERBOSE, "Host IPs allowed connection access (allowconnects):"); for (ip = SERVER_ACCESS.nonattackerlist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\tIP: %s", ip->name); } Log(LOG_LEVEL_VERBOSE, "Host IPs denied connection access (denyconnects):"); for (ip = SERVER_ACCESS.attackerlist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\tIP: %s", ip->name); } Log(LOG_LEVEL_VERBOSE, "Host IPs allowed multiple connection access (allowallconnects):"); for (ip = SERVER_ACCESS.multiconnlist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\tIP: %s", ip->name); } Log(LOG_LEVEL_VERBOSE, "Host IPs whose keys we shall establish trust to (trustkeysfrom):"); for (ip = SERVER_ACCESS.trustkeylist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\tIP: %s", ip->name); } Log(LOG_LEVEL_VERBOSE, "Host IPs allowed legacy connections (allowlegacyconnects):"); for (ip = SERVER_ACCESS.allowlegacyconnects; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\tIP: %s", ip->name); } Log(LOG_LEVEL_VERBOSE, "Users from whom we accept cf-runagent connections (allowusers):"); for (ip = SERVER_ACCESS.allowuserlist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\tUSER: %s", ip->name); } Log(LOG_LEVEL_VERBOSE, "Access control lists:"); acl_Summarise(paths_acl, "Path"); acl_Summarise(classes_acl, "Class"); acl_Summarise(vars_acl, "Variable"); acl_Summarise(literals_acl, "Literal"); acl_Summarise(query_acl, "Query"); acl_Summarise(roles_acl, "Role"); acl_Summarise(bundles_acl, "Bundle"); Log(LOG_LEVEL_VERBOSE, "Access control lists for the classic network protocol:"); for (ptr = SERVER_ACCESS.admit; ptr != NULL; ptr = ptr->next) { /* Don't report empty entries. */ if (ptr->maproot != NULL || ptr->accesslist != NULL) { Log(LOG_LEVEL_VERBOSE, "\tPath: %s", ptr->path); } for (ipr = ptr->maproot; ipr != NULL; ipr = ipr->next) { Log(LOG_LEVEL_VERBOSE, "\t\tmaproot user: %s,", ipr->name); } for (ip = ptr->accesslist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\t\tadmit: %s", ip->name); } } for (ptr = SERVER_ACCESS.deny; ptr != NULL; ptr = ptr->next) { /* Don't report empty entries. */ if (ptr->accesslist != NULL) { Log(LOG_LEVEL_VERBOSE, "\tPath: %s", ptr->path); } for (ip = ptr->accesslist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "\t\tdeny: %s", ip->name); } } for (ptr = SERVER_ACCESS.varadmit; ptr != NULL; ptr = ptr->next) { Log(LOG_LEVEL_VERBOSE, "Object: %s", ptr->path); for (ipr = ptr->maproot; ipr != NULL; ipr = ipr->next) { Log(LOG_LEVEL_VERBOSE, "%s,", ipr->name); } for (ip = ptr->accesslist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "Admit '%s' root=", ip->name); } } for (ptr = SERVER_ACCESS.vardeny; ptr != NULL; ptr = ptr->next) { Log(LOG_LEVEL_VERBOSE, "Object %s", ptr->path); for (ip = ptr->accesslist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "Deny '%s'", ip->name); } } Log(LOG_LEVEL_VERBOSE, " === END summary of access promises === "); } void KeepPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config, bool *unresolved_constraints) { if (paths_acl != NULL || classes_acl != NULL || vars_acl != NULL || literals_acl != NULL || query_acl != NULL || bundles_acl != NULL || roles_acl != NULL || SERVER_ACCESS.path_shortcuts != NULL) { UnexpectedError("ACLs are not NULL - we are probably leaking memory!"); } paths_acl = calloc(1, sizeof(*paths_acl)); classes_acl = calloc(1, sizeof(*classes_acl)); vars_acl = calloc(1, sizeof(*vars_acl)); literals_acl = calloc(1, sizeof(*literals_acl)); query_acl = calloc(1, sizeof(*query_acl)); bundles_acl = calloc(1, sizeof(*bundles_acl)); roles_acl = calloc(1, sizeof(*roles_acl)); SERVER_ACCESS.path_shortcuts = StringMapNew(); if (paths_acl == NULL || classes_acl == NULL || vars_acl == NULL || literals_acl == NULL || query_acl == NULL || bundles_acl == NULL || roles_acl == NULL || SERVER_ACCESS.path_shortcuts == NULL) { Log(LOG_LEVEL_CRIT, "calloc: %s", GetErrorStr()); DoCleanupAndExit(255); } KeepControlPromises(ctx, policy, config, unresolved_constraints); KeepPromiseBundles(ctx, policy); } /*******************************************************************/ static bool SetMaxOpenFiles(int n) #ifdef HAVE_SYS_RESOURCE_H { const struct rlimit lim = { .rlim_cur = n, .rlim_max = n, }; int ret = setrlimit(RLIMIT_NOFILE, &lim); if (ret == -1) { Log(LOG_LEVEL_INFO, "Failed setting max open files limit" " (setrlimit(NOFILE, %d): %s)", n, GetErrorStr()); Log(LOG_LEVEL_INFO, "Please ensure that 'nofile' ulimit is at least 5x maxconnections"); return false; } else { Log(LOG_LEVEL_VERBOSE, "Setting max open files rlimit to %d", n); return true; } } #else /* MinGW */ { Log(LOG_LEVEL_VERBOSE, "Platform does not support setrlimit(NOFILE), max open files not set"); return false; } #endif /* HAVE_SYS_RESOURCE_H */ static bool ValueHasUnresolvedVars(const void *value, DataType value_type) { switch (value_type) { case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: case CF_DATA_TYPE_OPTION: /* All just strings, actually. */ return StringContainsUnresolved((const char *) value); case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_OPTION_LIST: /* All just lists of strings, actually. */ for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (StringContainsUnresolved(RlistScalarValue(rp))) { return true; } } return false; /* * TODO: Support for other types in case this is moved somewhere else and is * supposed to be used in more generic cases than to check cf-serverd * constraint values. See libpromises/cmdb.c for checking unresolved * vars in JSON objects (CF_DATA_TYPE_CONTAINER). */ default: Log(LOG_LEVEL_WARNING, "Unsupported type for checking unresolved vars"); debug_abort_if_reached(); return false; } } static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config, bool *unresolved_vars) { CFD_MAXPROCESSES = 30; MAXTRIES = 5; DENYBADCLOCKS = true; CFRUNCOMMAND[0] = '\0'; SetChecksumUpdatesDefault(ctx, true); if (unresolved_vars != NULL) { *unresolved_vars = false; } /* Keep promised agent behaviour - control bodies */ Banner("Server control promises.."); PolicyResolve(ctx, policy, config); /* Now expand */ Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_SERVER); #define IsControlBody(e) (strcmp(cp->lval, CFS_CONTROLBODY[e].lval) == 0) if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_server"); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); if (unresolved_vars != NULL) { *unresolved_vars |= ValueHasUnresolvedVars(value, value_type); } if (IsControlBody(SERVER_CONTROL_SERVER_FACILITY)) { SetFacility(value); } else if (IsControlBody(SERVER_CONTROL_DENY_BAD_CLOCKS)) { DENYBADCLOCKS = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting denybadclocks to '%s'", DENYBADCLOCKS ? "true" : "false"); } else if (IsControlBody(SERVER_CONTROL_LOG_ENCRYPTED_TRANSFERS)) { LOGENCRYPT = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting logencrypt to '%s'", LOGENCRYPT ? "true" : "false"); } else if (IsControlBody(SERVER_CONTROL_LOG_ALL_CONNECTIONS)) { SERVER_ACCESS.logconns = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting logconns to %d", SERVER_ACCESS.logconns); } else if (IsControlBody(SERVER_CONTROL_MAX_CONNECTIONS)) { CFD_MAXPROCESSES = (int) IntFromString(value); /* Ease apoptosis limits. */ MAXTRIES = CFD_MAXPROCESSES / 3; /* The handling of max_readers in LMDB is not ideal, but * here is how it is right now: We know that both cf-serverd and * cf-hub will access the lastseen database. Worst case every * single thread and process will do it at the same time, and * this has in fact been observed. So we add the maximum of * those two values together to provide a safe ceiling. In * addition, cf-agent can access the database occasionally as * well, so add a few extra for that too. */ Log(LOG_LEVEL_VERBOSE, "Setting maxconnections to %d", CFD_MAXPROCESSES); DBSetMaximumConcurrentTransactions(CFD_MAXPROCESSES + EnterpriseGetMaxCfHubProcesses() + 10); /* Set RLIMIT_NOFILE to be enough for all threads. */ SetMaxOpenFiles(CFD_MAXPROCESSES * 5 + 10); } else if (IsControlBody(SERVER_CONTROL_CALL_COLLECT_INTERVAL)) { COLLECT_INTERVAL = (int) 60 * IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting call_collect_interval to %d (seconds)", COLLECT_INTERVAL); } else if (IsControlBody(SERVER_CONTROL_LISTEN)) { SERVER_LISTEN = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting server listen to '%s' ", SERVER_LISTEN ? "true" : "false"); } else if (IsControlBody(SERVER_CONTROL_CALL_COLLECT_WINDOW)) { COLLECT_WINDOW = (int) IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting collect_window to %d (seconds)", COLLECT_WINDOW); } else if (IsControlBody(SERVER_CONTROL_CFRUNCOMMAND)) { if (strlen(value) >= sizeof(CFRUNCOMMAND)) { Log(LOG_LEVEL_ERR, "cfruncommand too long (>%zu), leaving empty", sizeof(CFRUNCOMMAND)); } else { memcpy(CFRUNCOMMAND, value, strlen(value) + 1); Log(LOG_LEVEL_VERBOSE, "Setting cfruncommand to: %s", CFRUNCOMMAND); } } else if (IsControlBody(SERVER_CONTROL_ALLOW_CONNECTS)) { Log(LOG_LEVEL_VERBOSE, "Setting allowing connections from ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (!IsItemIn(SERVER_ACCESS.nonattackerlist, RlistScalarValue(rp))) { PrependItem(&SERVER_ACCESS.nonattackerlist, RlistScalarValue(rp), cp->classes); } } } else if (IsControlBody(SERVER_CONTROL_DENY_CONNECTS)) { Log(LOG_LEVEL_VERBOSE, "Setting denying connections from ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (!IsItemIn(SERVER_ACCESS.attackerlist, RlistScalarValue(rp))) { PrependItem(&SERVER_ACCESS.attackerlist, RlistScalarValue(rp), cp->classes); } } } else if (IsControlBody(SERVER_CONTROL_SKIP_VERIFY)) { /* Skip. */ } else if (IsControlBody(SERVER_CONTROL_ALLOW_ALL_CONNECTS)) { Log(LOG_LEVEL_VERBOSE, "Setting allowing multiple connections from ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (!IsItemIn(SERVER_ACCESS.multiconnlist, RlistScalarValue(rp))) { PrependItem(&SERVER_ACCESS.multiconnlist, RlistScalarValue(rp), cp->classes); } } } else if (IsControlBody(SERVER_CONTROL_ALLOW_USERS)) { Log(LOG_LEVEL_VERBOSE, "SET Allowing users ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (!IsItemIn(SERVER_ACCESS.allowuserlist, RlistScalarValue(rp))) { PrependItem(&SERVER_ACCESS.allowuserlist, RlistScalarValue(rp), cp->classes); } } } else if (IsControlBody(SERVER_CONTROL_TRUST_KEYS_FROM)) { Log(LOG_LEVEL_VERBOSE, "Setting 'trustkeysfrom' ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (!IsItemIn(SERVER_ACCESS.trustkeylist, RlistScalarValue(rp))) { PrependItem(&SERVER_ACCESS.trustkeylist, RlistScalarValue(rp), cp->classes); } } } else if (IsControlBody(SERVER_CONTROL_ALLOWLEGACYCONNECTS)) { Log(LOG_LEVEL_VERBOSE, "Setting 'allowlegacyconnects' ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (!IsItemIn(SERVER_ACCESS.allowlegacyconnects, RlistScalarValue(rp))) { PrependItem(&SERVER_ACCESS.allowlegacyconnects, RlistScalarValue(rp), cp->classes); } } } else if (IsControlBody(SERVER_CONTROL_PORT_NUMBER)) { bool ret = SetCfenginePort(value); assert(ret); if (ret == false) { Log(LOG_LEVEL_VERBOSE, "Could not set port number, continuing (See errors above)"); } } else if (IsControlBody(SERVER_CONTROL_BIND_TO_INTERFACE)) { SetBindInterface(value); } else if (IsControlBody(SERVER_CONTROL_ALLOWCIPHERS)) { assert(SERVER_ACCESS.allowciphers == NULL); /* no leak */ SERVER_ACCESS.allowciphers = xstrdup(value); Log(LOG_LEVEL_VERBOSE, "Setting allowciphers to: %s", SERVER_ACCESS.allowciphers); } else if (IsControlBody(SERVER_CONTROL_ALLOWTLSVERSION)) { assert(SERVER_ACCESS.allowtlsversion == NULL); /* no leak */ SERVER_ACCESS.allowtlsversion = xstrdup(value); Log(LOG_LEVEL_VERBOSE, "Setting allowtlsversion to: %s", SERVER_ACCESS.allowtlsversion); } } #undef IsControlBody } const void *value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_SYSLOG_HOST); if (value) { /* Don't resolve syslog_host now, better do it per log request. */ if (!SetSyslogHost(value)) { Log(LOG_LEVEL_ERR, "Failed to set syslog_host, '%s' too long", (const char *)value); } else { Log(LOG_LEVEL_VERBOSE, "Setting syslog_host to '%s'", (const char *)value); } } value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_SYSLOG_PORT); if (value) { SetSyslogPort(IntFromString(value)); } value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_FIPS_MODE); if (value) { FIPS_MODE = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting FIPS mode to to '%s'", FIPS_MODE ? "true" : "false"); } value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER); if (value) { LASTSEENEXPIREAFTER = IntFromString(value) * 60; } value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_BWLIMIT); if (value) { double bval; if (DoubleFromString(value, &bval)) { bwlimit_kbytes = (uint32_t) ( bval / 1000.0); Log(LOG_LEVEL_VERBOSE, "Setting rate limit to %d kBytes/sec", bwlimit_kbytes); } } if (config->agent_type == AGENT_TYPE_SERVER) { EvalContextUpdateDumpReports(ctx); } } /*********************************************************************/ /* Sequence in which server promise types should be evaluated */ static const char *const SERVER_TYPESEQUENCE[] = { "meta", "vars", "classes", "roles", "access", NULL }; static const char *const COMMON_TYPESEQUENCE[] = { "meta", "vars", "classes", "reports", NULL }; /* Check if promise is NOT belonging to default server types * (see SERVER_TYPESEQUENCE)*/ static bool IsPromiseTypeNotInTypeSequence(const char *promise_type, const char * const *seq) { for (int type = 0; seq[type] != NULL; type++) { if (strcmp(promise_type, seq[type]) == 0) { return false; } } return true; } static void EvaluateBundle(EvalContext *ctx, const Bundle *bp, const char * const *seq) { EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (int type = 0; seq[type] != NULL; type++) { const BundleSection *sp = BundleGetSection((Bundle *)bp, seq[type]); /* Some promise types might not be there. */ if (!sp || SeqLength(sp->promises) == 0) { Log(LOG_LEVEL_DEBUG, "No promise type %s in bundle %s", seq[type], bp->name); continue; } EvalContextStackPushBundleSectionFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } /* Check if we are having some other promise types which we * should evaluate. THIS IS ONLY FOR BACKWARD COMPATIBILITY! */ for (size_t j = 0; j < SeqLength(bp->sections); j++) { BundleSection *sp = SeqAt(bp->sections, j); /* Skipping evaluation of promise as this was evaluated in * loop above. */ if (!IsPromiseTypeNotInTypeSequence(sp->promise_type, seq)) { Log(LOG_LEVEL_DEBUG, "Skipping subsequent evaluation of " "promise type %s in bundle %s", sp->promise_type, bp->name); continue; } Log(LOG_LEVEL_WARNING, "Trying to evaluate unsupported/obsolete " "promise type %s in %s bundle %s", sp->promise_type, bp->type, bp->name); EvalContextStackPushBundleSectionFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); } static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy) { /* Dial up the generic promise expansion with a callback */ CleanReportBookFilterSet(); for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); bool server_bundle = strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_SERVER]) == 0; bool common_bundle = strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0; if (server_bundle || common_bundle) { if (RlistLen(bp->args) > 0) { Log(LOG_LEVEL_WARNING, "Cannot implicitly evaluate bundle '%s %s', as this bundle takes arguments.", bp->type, bp->name); continue; } } if (server_bundle) { EvaluateBundle(ctx, bp, SERVER_TYPESEQUENCE); } else if (common_bundle) { EvaluateBundle(ctx, bp, COMMON_TYPESEQUENCE); } } } static PromiseResult KeepServerPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert(!param); PromiseBanner(ctx, pp); if (strcmp(PromiseGetPromiseType(pp), "vars") == 0) { return VerifyVarPromise(ctx, pp, NULL); } if (strcmp(PromiseGetPromiseType(pp), "classes") == 0) { return VerifyClassPromise(ctx, pp, NULL); } /* Warn if promise locking was used with a promise that doesn't support it. * That applies to both of the below promise types while 'vars' and * 'classes' handle this on their own. */ int ifelapsed = PromiseGetConstraintAsInt(ctx, "ifelapsed", pp); if (ifelapsed != CF_NOINT) { Log(LOG_LEVEL_WARNING, "ifelapsed attribute specified in action body for %s promise '%s'," " but %s promises do not support promise locking", PromiseGetPromiseType(pp), pp->promiser, PromiseGetPromiseType(pp)); } int expireafter = PromiseGetConstraintAsInt(ctx, "expireafter", pp); if (expireafter != CF_NOINT) { Log(LOG_LEVEL_WARNING, "expireafter attribute specified in action body for %s promise '%s'," " but %s promises do not support promise locking", PromiseGetPromiseType(pp), pp->promiser, PromiseGetPromiseType(pp)); } if (strcmp(PromiseGetPromiseType(pp), "access") == 0) { const char *resource_type = PromiseGetConstraintAsRval(pp, "resource_type", RVAL_TYPE_SCALAR); /* Default resource_type in access_rules is "path" */ if (resource_type == NULL || strcmp(resource_type, "path") == 0) { KeepFileAccessPromise(ctx, pp); return PROMISE_RESULT_NOOP; } else if (strcmp(resource_type, "literal") == 0) { KeepLiteralAccessPromise(ctx, pp, "literal"); return PROMISE_RESULT_NOOP; } else if (strcmp(resource_type, "variable") == 0) { KeepLiteralAccessPromise(ctx, pp, "variable"); return PROMISE_RESULT_NOOP; } else if (strcmp(resource_type, "query") == 0) { KeepQueryAccessPromise(ctx, pp); KeepReportDataSelectAccessPromise(pp); return PROMISE_RESULT_NOOP; } else if (strcmp(resource_type, "context") == 0) { KeepLiteralAccessPromise(ctx, pp, "context"); return PROMISE_RESULT_NOOP; } else if (strcmp(resource_type, "bundle") == 0) { KeepBundlesAccessPromise(ctx, pp); return PROMISE_RESULT_NOOP; } } else if (strcmp(PromiseGetPromiseType(pp), "roles") == 0) { KeepServerRolePromise(ctx, pp); return PROMISE_RESULT_NOOP; } return PROMISE_RESULT_NOOP; } /*********************************************************************/ enum admit_type { ADMIT_TYPE_IP, ADMIT_TYPE_HOSTNAME, ADMIT_TYPE_KEY, ADMIT_TYPE_OTHER }; /* Check if the given string is an IP subnet, a hostname, a key, or none of * the above. */ static enum admit_type AdmitType(const char *s) { if (strncmp(s, "SHA=", strlen("SHA=")) == 0 || strncmp(s, "MD5=", strlen("MD5=")) == 0) { return ADMIT_TYPE_KEY; } /* IPv4 or IPv6 subnet mask or regex. */ /* TODO change this to "0123456789abcdef.:/", no regex allowed. */ else if (s[strspn(s, "0123456789abcdef.:/[-]*()\\")] == '\0') { return ADMIT_TYPE_IP; } else { return ADMIT_TYPE_HOSTNAME; } } /** * Map old-style regex-or-hostname #host to new-style host-or-domain * and append it to #sl. * * Old-style ACLs could include regexes to be matched against host * names; but new-style ones only support sub-domain matching. If the * old-style host regex looks like ".*\.sub\.domain\.tld" we can take * it in as ".sub.domain.tld"; otherwise, we can only really map exact * match hostnames. However, we know some old policy (including our * own masterfiles) had cases of .*sub.domain.tld and it's possible * that someone might include a new-style .sub.domain.tld by mistake * in an (old-style) accept list; so cope with these cases, too. * * @param sl The string-list to which to add entries. * @param host The name-or-regex to add to the ACL. * @return An index at which an entry was added to the list (there may * be another), or -1 if nothing added. */ static size_t StrList_AppendRegexHostname(StrList **sl, const char *host) { if (IsRegex(host)) { if (host[strcspn(host, "({[|+?]})")] != '\0') { return -1; /* Not a regex we can sensibly massage; discard. */ } bool skip[2] = { false, false }; /* { domain, host } passes below */ const char *name = host; if (name[0] == '^') /* Was always implicit; but read as hint to intent. */ { /* Default to skipping domain-form if anchored explicitly: */ skip[0] = true; /* Over-ridden below if followed by .* of course. */ name++; } if (StringStartsWith(name, ".*")) { skip[0] = false; /* Domain-form should match */ name += 2; } if (StringStartsWith(name, "\\.")) { /* Skip host-form, as the regex definitely wants something * before the given name. */ skip[1] = true; name += 2; } if (strchr(name, '*') != NULL) { /* Can't handle a * later than the preamble. */ return (size_t) -1; } if (name > host || strchr(host, '\\') != NULL) { /* 2: leading '.' and final '\0' */ char copy[2 + strlen(name)], *c = copy; c++[0] = '.'; /* For domain-form; and copy+1 gives host-form. */ /* Now copy the rest of the name, de-regex-ifying as we go: */ for (const char *p = name; p[0] != '\0'; p++) { if (p[0] == '\\') { p++; if (p[0] != '.') { /* Regex includes a non-dot escape */ return (size_t) -1; } } #if 0 else if (p[0] == '.') { /* In principle, this is a special character; but * it may just be an unescaped dot, so let it be. */ } #endif c++[0] = p[0]; } assert(c < copy + sizeof(copy)); c[0] = '\0'; /* Now, for host then domain, add entry if suitable */ int pass = 2; size_t ret = -1; while (pass > 0) { pass--; if (!skip[pass]) /* pass 0 is domain, pass 1 is host */ { ret = StrList_Append(sl, copy + pass); } } return ret; } /* IsRegex() is true but we treat it just as a name! */ } /* Just a simple host name. */ return StrList_Append(sl, host); } bool NEED_REVERSE_LOOKUP = false; static void TurnOnReverseLookups() { if (!NEED_REVERSE_LOOKUP) { Log(LOG_LEVEL_INFO, "Found hostname admit/deny in access_rules, " "turning on reverse DNS lookups for every connection"); NEED_REVERSE_LOOKUP = true; } } static size_t racl_SmartAppend(struct admitdeny_acl *ad, const char *entry) { size_t ret; switch (AdmitType(entry)) { case ADMIT_TYPE_IP: /* TODO convert IP string to binary representation. */ ret = StrList_Append(&ad->ips, entry); break; case ADMIT_TYPE_KEY: ret = StrList_Append(&ad->keys, entry); break; case ADMIT_TYPE_HOSTNAME: ret = StrList_AppendRegexHostname(&ad->hostnames, entry); /* If any hostname rule got added, * turn on reverse DNS lookup in the new protocol. */ if (ret != (size_t) -1) { TurnOnReverseLookups(); } break; default: Log(LOG_LEVEL_WARNING, "Access rule 'admit: %s' is not IP, hostname or key, ignoring", entry); ret = (size_t) -1; } return ret; } /* Package hostname as regex, if needed. * * @param old The old Auth structure to which to add. * @param host The new acl_hostnames entry to add to it. */ static void NewHostToOldACL(Auth *old, const char *host) { if (host[0] == '.') /* Domain - transform to regex: */ { int extra = 2; /* For leading ".*" */ const char *dot = host; do { do { dot++; /* Step over prior dot. */ } while (dot[0] == '.'); /* Treat many dots as one. */ extra++; /* For a backslash before the dot */ dot = strchr(dot, '.'); } while (dot); char regex[strlen(host) + extra], *dst = regex; dst++[0] = '.'; dst++[0] = '*'; dot = host; do { /* Insert literal dot. */ assert(dot[0] == '.'); dst++[0] = '\\'; dst++[0] = '.'; do /* Step over prior dot(s), as before. */ { dot++; } while (dot[0] == '.'); /* Identify next fragment: */ const char *d = strchr(dot, '.'); size_t len = d ? (size_t) (d - dot) : strlen(dot); /* Copy fragment: */ memcpy(dst, dot, len); dst += len; /* Advance: */ dot = d; } while (dot); /* Terminate: */ assert(dst < regex + sizeof(regex)); dst[0] = '\0'; /* Add to list: */ PrependItem(&(old->accesslist), regex, NULL); } else { /* Simple host-name; just add it: */ PrependItem(&(old->accesslist), host, NULL); } } /** * Add access rules to the given ACL #acl according to the constraints in the * particular access promise. * * For legacy reasons (non-TLS connections), build also the #ap (access Auth) * and #dp (deny Auth), if they are not NULL. */ static void AccessPromise_AddAccessConstraints(const EvalContext *ctx, const Promise *pp, struct resource_acl *racl, Auth *ap, Auth *dp) { for (size_t i = 0; i < SeqLength(pp->conlist); i++) { const Constraint *cp = SeqAt(pp->conlist, i); size_t ret = -2; if (!IsDefinedClass(ctx, cp->classes)) { continue; } switch (cp->rval.type) { #define IsAccessBody(e) (strcmp(cp->lval, CF_REMACCESS_BODIES[e].lval) == 0) case RVAL_TYPE_SCALAR: if (ap != NULL && IsAccessBody(REMOTE_ACCESS_IFENCRYPTED)) { ap->encrypt = BooleanFromString(cp->rval.item); } else if (IsAccessBody(REMOTE_ACCESS_SHORTCUT)) { const char *shortcut = cp->rval.item; if (strchr(shortcut, FILE_SEPARATOR) != NULL) { Log(LOG_LEVEL_ERR, "slashes are forbidden in ACL shortcut: %s", shortcut); } else if (StringMapHasKey(SERVER_ACCESS.path_shortcuts, shortcut)) { Log(LOG_LEVEL_WARNING, "Already existing shortcut for path '%s' was replaced", pp->promiser); } else { StringMapInsert(SERVER_ACCESS.path_shortcuts, xstrdup(shortcut), xstrdup(pp->promiser)); Log(LOG_LEVEL_DEBUG, "Added shortcut '%s' for path: %s", shortcut, pp->promiser); } } break; case RVAL_TYPE_LIST: for (const Rlist *rp = (const Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { /* TODO keys, ips, hostnames are valid such strings. */ if (IsAccessBody(REMOTE_ACCESS_ADMITIPS)) { ret = StrList_Append(&racl->admit.ips, RlistScalarValue(rp)); if (ap != NULL) { PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL); } } else if (IsAccessBody(REMOTE_ACCESS_DENYIPS)) { ret = StrList_Append(&racl->deny.ips, RlistScalarValue(rp)); if (dp != NULL) { PrependItem(&(dp->accesslist), RlistScalarValue(rp), NULL); } } else if (IsAccessBody(REMOTE_ACCESS_ADMITHOSTNAMES)) { ret = StrList_Append(&racl->admit.hostnames, RlistScalarValue(rp)); /* If any hostname rule got added, * turn on reverse DNS lookup in the new protocol. */ if (ret != (size_t) -1) { TurnOnReverseLookups(); } if (ap != NULL) { NewHostToOldACL(ap, RlistScalarValue(rp)); } } else if (IsAccessBody(REMOTE_ACCESS_DENYHOSTNAMES)) { ret = StrList_Append(&racl->deny.hostnames, RlistScalarValue(rp)); /* If any hostname rule got added, * turn on reverse DNS lookup in the new protocol. */ if (ret != (size_t) -1) { TurnOnReverseLookups(); } if (dp != NULL) { NewHostToOldACL(dp, RlistScalarValue(rp)); } } else if (IsAccessBody(REMOTE_ACCESS_ADMITKEYS)) { ret = StrList_Append(&racl->admit.keys, RlistScalarValue(rp)); } else if (IsAccessBody(REMOTE_ACCESS_DENYKEYS)) { ret = StrList_Append(&racl->deny.keys, RlistScalarValue(rp)); } /* Legacy stuff */ else if (IsAccessBody(REMOTE_ACCESS_ADMIT)) { ret = racl_SmartAppend(&racl->admit, RlistScalarValue(rp)); if (ap != NULL) { PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL); } } else if (IsAccessBody(REMOTE_ACCESS_DENY)) { ret = racl_SmartAppend(&racl->deny, RlistScalarValue(rp)); if (dp != NULL) { PrependItem(&(dp->accesslist), RlistScalarValue(rp), NULL); } } else if (ap != NULL && IsAccessBody(REMOTE_ACCESS_MAPROOT)) { PrependItem(&(ap->maproot), RlistScalarValue(rp), NULL); } } if (ret == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "StrList_Append: %s", GetErrorStr()); DoCleanupAndExit(255); } break; default: UnexpectedError("Unknown constraint type!"); break; #undef IsAccessBody } } StrList_Finalise(&racl->admit.ips); StrList_Sort(racl->admit.ips, string_Compare); StrList_Finalise(&racl->admit.hostnames); StrList_Sort(racl->admit.hostnames, string_CompareFromEnd); StrList_Finalise(&racl->admit.keys); StrList_Sort(racl->admit.keys, string_Compare); StrList_Finalise(&racl->deny.ips); StrList_Sort(racl->deny.ips, string_Compare); StrList_Finalise(&racl->deny.hostnames); StrList_Sort(racl->deny.hostnames, string_CompareFromEnd); StrList_Finalise(&racl->deny.keys); StrList_Sort(racl->deny.keys, string_Compare); } /* It is allowed to have duplicate handles (paths or class names or variables * etc) in bundle server access_rules in policy files, but the lists here * should have unique entries. This, we make sure here. */ static Auth *GetOrCreateAuth(const char *handle, Auth **authchain, Auth **authchain_tail) { Auth *a = GetAuthPath(handle, *authchain); if (!a) { InstallServerAuthPath(handle, authchain, authchain_tail); a = GetAuthPath(handle, *authchain); } return a; } static void KeepFileAccessPromise(const EvalContext *ctx, const Promise *pp) { char path[PATH_MAX]; size_t path_len = strlen(pp->promiser); if (path_len > sizeof(path) - 1) { goto err_too_long; } memcpy(path, pp->promiser, path_len + 1); /* Resolve symlinks and canonicalise access_rules path. */ size_t ret2 = PreprocessRequestPath(path, sizeof(path)); if (ret2 == (size_t) -1) { if (errno != ENOENT) /* something went wrong */ { Log(LOG_LEVEL_ERR, "Failed to canonicalize path '%s' in access_rules, ignoring!", pp->promiser); return; } else /* file does not exist, it doesn't matter */ { Log(LOG_LEVEL_INFO, "Path does not exist, it's added as-is in access rules: %s", path); Log(LOG_LEVEL_INFO, "WARNING: this means that (not) having a trailing slash defines if it's (not) a directory!"); /* Legacy: convert trailing "/." to "/" */ if (path_len >= 2 && path[path_len - 1] == '.' && path[path_len - 2] == '/') { path[path_len - 1] = '\0'; path_len--; } } } else /* file exists, path canonicalised */ { /* If it's a directory append trailing '/' */ path_len = ret2; bool is_dir = IsDirReal(path); if (is_dir && path[path_len - 1] != FILE_SEPARATOR) { if (path_len + 2 > sizeof(path)) { goto err_too_long; } PathAppendTrailingSlash(path, path_len); path_len++; } } size_t pos = acl_SortedInsert(&paths_acl, path); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); DoCleanupAndExit(255); } /* Legacy code */ if (path_len != 1) { DeleteSlash(path); } Auth *ap = GetOrCreateAuth(path, &SERVER_ACCESS.admit, &SERVER_ACCESS.admittail); Auth *dp = GetOrCreateAuth(path, &SERVER_ACCESS.deny, &SERVER_ACCESS.denytail); AccessPromise_AddAccessConstraints(ctx, pp, &paths_acl->acls[pos], ap, dp); return; err_too_long: Log(LOG_LEVEL_ERR, "Path '%s' in access_rules is too long (%zu > %d), ignoring!", pp->promiser, strlen(pp->promiser), PATH_MAX); return; } /*********************************************************************/ void KeepLiteralAccessPromise(EvalContext *ctx, const Promise *pp, const char *type) { Auth *ap, *dp; const char *handle = PromiseGetHandle(pp); if (handle == NULL && strcmp(type, "literal") == 0) { Log(LOG_LEVEL_ERR, "Access to literal server data requires you to define a promise handle for reference"); return; } if (strcmp(type, "literal") == 0) { Log(LOG_LEVEL_VERBOSE,"Looking at literal access promise '%s', type '%s'", pp->promiser, type); ap = GetOrCreateAuth(handle, &SERVER_ACCESS.varadmit, &SERVER_ACCESS.varadmittail); dp = GetOrCreateAuth(handle, &SERVER_ACCESS.vardeny, &SERVER_ACCESS.vardenytail); RegisterLiteralServerData(ctx, handle, pp); ap->literal = true; size_t pos = acl_SortedInsert(&literals_acl, handle); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); DoCleanupAndExit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &literals_acl->acls[pos], ap, dp); } else { Log(LOG_LEVEL_VERBOSE,"Looking at context/var access promise '%s', type '%s'", pp->promiser, type); ap = GetOrCreateAuth(pp->promiser, &SERVER_ACCESS.varadmit, &SERVER_ACCESS.varadmittail); dp = GetOrCreateAuth(pp->promiser, &SERVER_ACCESS.vardeny, &SERVER_ACCESS.vardenytail); if (strcmp(type, "context") == 0) { ap->classpattern = true; size_t pos = acl_SortedInsert(&classes_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); DoCleanupAndExit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &classes_acl->acls[pos], ap, dp); } else if (strcmp(type, "variable") == 0) { ap->variable = true; size_t pos = acl_SortedInsert(&vars_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); DoCleanupAndExit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &vars_acl->acls[pos], ap, dp); } } } /*********************************************************************/ static void KeepQueryAccessPromise(EvalContext *ctx, const Promise *pp) { Auth *dp = GetOrCreateAuth(pp->promiser, &SERVER_ACCESS.vardeny, &SERVER_ACCESS.vardenytail), *ap = GetOrCreateAuth(pp->promiser, &SERVER_ACCESS.varadmit, &SERVER_ACCESS.varadmittail); RegisterLiteralServerData(ctx, pp->promiser, pp); ap->literal = true; size_t pos = acl_SortedInsert(&query_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); DoCleanupAndExit(255); } AccessPromise_AddAccessConstraints(ctx, pp, &query_acl->acls[pos], ap, dp); } static void KeepBundlesAccessPromise(EvalContext *ctx, const Promise *pp) { size_t pos = acl_SortedInsert(&bundles_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); DoCleanupAndExit(255); } /* Last params are NULL because we don't have * old-school Auth type ACLs here. */ AccessPromise_AddAccessConstraints(ctx, pp, &bundles_acl->acls[pos], NULL, NULL); } /*********************************************************************/ /** * The "roles" access promise is for remote class activation by means of * cf-runagent -D: * * pp->promiser is a regex to match classes. * pp->conlist is an slist of usernames. */ static void KeepServerRolePromise(EvalContext *ctx, const Promise *pp) { size_t pos = acl_SortedInsert(&roles_acl, pp->promiser); if (pos == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "acl_Insert: %s", GetErrorStr()); DoCleanupAndExit(255); } size_t i = SeqLength(pp->conlist); while (i > 0) { i--; Constraint *cp = SeqAt(pp->conlist, i); char const * const authorizer = CF_REMROLE_BODIES[REMOTE_ROLE_AUTHORIZE].lval; if (strcmp(cp->lval, authorizer) == 0) { if (cp->rval.type != RVAL_TYPE_LIST) { Log(LOG_LEVEL_ERR, "Right-hand side of authorize promise for '%s' should be a list", pp->promiser); } else if (IsDefinedClass(ctx, cp->classes)) { for (const Rlist *rp = cp->rval.item; rp != NULL; rp = rp->next) { /* The "roles" access promise currently only supports * listing usernames to admit access to, nothing more. */ struct resource_acl *racl = &roles_acl->acls[pos]; size_t zret = StrList_Append(&racl->admit.usernames, RlistScalarValue(rp)); if (zret == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "StrList_Append: %s", GetErrorStr()); DoCleanupAndExit(255); } } } } else if (strcmp(cp->lval, "comment") != 0 && strcmp(cp->lval, "handle") != 0 && /* Are there other known list constraints ? if not, skip this: */ cp->rval.type != RVAL_TYPE_LIST) { Log(LOG_LEVEL_WARNING, "Unrecognised promise '%s' for %s", cp->lval, pp->promiser); } } } static void InstallServerAuthPath(const char *path, Auth **list, Auth **listtail) { Auth **nextp = *listtail ? &((*listtail)->next) : list; assert(*nextp == NULL); *listtail = *nextp = xcalloc(1, sizeof(Auth)); (*nextp)->path = xstrdup(path); #ifdef __MINGW32__ for (char *p = (*nextp)->path; *p != '\0'; p++) { *p = ToLower(*p); } #endif /* __MINGW32__ */ } static Auth *GetAuthPath(const char *path, Auth *list) { size_t path_len = strlen(path); char unslashed_path[path_len + 1]; memcpy(unslashed_path, path, path_len + 1); #ifdef __MINGW32__ ToLowerStrInplace(unslashed_path); #endif if (path_len != 1) { DeleteSlash(unslashed_path); } for (Auth *ap = list; ap != NULL; ap = ap->next) { if (strcmp(ap->path, unslashed_path) == 0) { return ap; } } return NULL; } cfengine-3.24.2/cf-serverd/server_transform.h0000644000000000000000000000234715010704253021173 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SERVER_TRANSFORM_H #define CFENGINE_SERVER_TRANSFORM_H #include #include void Summarize(void); void KeepPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config, bool *unresolved_constraints); #endif cfengine-3.24.2/cf-serverd/cf-serverd.c0000644000000000000000000000566115010704253017627 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* CleanReportBookFilterSet() */ #include #include #include #include #include /* RequestReloadConfig() */ static void ThisAgentInit(void) { umask(077); } int main(int argc, char *argv[]) { /* Ensure that if fd 0,1,2 are closed, we reserve them to avoid opening * the listening socket on them and closing it later when daemonising. */ int fd = -1; do { fd = open(NULLFILE, O_RDWR, 0); } while (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO); close(fd); GenericAgentConfig *config = CheckOpts(argc, argv); EvalContext *ctx = EvalContextNew(); GenericAgentConfigApply(ctx, config); const char *program_invocation_name = argv[0]; const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR); const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name); GenericAgentDiscoverContext(ctx, config, program_name); Policy *policy = SelectAndLoadPolicy(config, ctx, false, false); if (!policy) { Log(LOG_LEVEL_ERR, "Error reading CFEngine policy. Exiting..."); DoCleanupAndExit(EXIT_FAILURE); } GenericAgentPostLoadInit(ctx); ThisAgentInit(); bool unresolved_constraints; KeepPromises(ctx, policy, config, &unresolved_constraints); Summarize(); if (unresolved_constraints) { Log(LOG_LEVEL_WARNING, "Unresolved variables found in cf-serverd policy, scheduling policy reload"); RequestReloadConfig(); } int threads_left = StartServer(ctx, &policy, config); if (threads_left <= 0) { PolicyDestroy(policy); GenericAgentFinalize(ctx, config); CleanReportBookFilterSet(); } CallCleanupFunctions(); return 0; } cfengine-3.24.2/cf-serverd/strlist.c0000644000000000000000000005150515010704253017271 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include "strlist.h" #include #include int memrcmp(const void *p1, const void *p2, size_t n) { const char *s1 = p1; const char *s2 = p2; while (n > 0) { if (*s1 != *s2) { return *s1 - *s2; } s1--; s2--; n--; } return 0; } /***************************** STRING ***************************************/ struct string *string_New(const char *s) { size_t s_len = strlen(s); struct string *p = malloc(sizeof(*p) + s_len + 1); if (p != NULL) { p->len = s_len; /* p->size = s_len + 1; */ memcpy(p->str, s, s_len + 1); } return p; } /* Compare without ordering, returning only true or false. */ bool string_BoolCompare(const struct string *s1, const struct string *s2) { bool result = false; if (s1->len == s2->len) { result = (memcmp(s1->str, s2->str, s1->len) == 0); } return result; } /* Compare and return -1, 0, 1 according to alphabetical order. */ int string_Compare(const struct string **sp1, const struct string **sp2) { const struct string *s1 = *sp1; const struct string *s2 = *sp2; int result; if (s1->len < s2->len) { if (s1->len == 0) { return -1; } else { result = memcmp(s1->str, s2->str, s1->len); return result == 0 ? -1 : result; } } else if (s1->len > s2->len) { if (s2->len == 0) { return 1; } else { result = memcmp(s1->str, s2->str, s2->len); return result == 0 ? 1 : result; } } else /* s1->len == s2->len */ { if (s1->len == 0) /* both are zero length strings */ { return 0; } else { return memcmp(s1->str, s2->str, s1->len); } } } /** * Compare two strings starting from their end. */ int string_CompareFromEnd(const struct string **sp1, const struct string **sp2) { const struct string *s1 = *sp1; const struct string *s2 = *sp2; int result; /* Pointer to last char of s1 and s2. */ const char *last1 = &s1->str[s1->len - 1]; const char *last2 = &s2->str[s2->len - 1]; if (s1->len < s2->len) { result = memrcmp(last1, last2, s1->len); return result == 0 ? -1 : result; } else if (s1->len > s2->len) { result = memrcmp(last1, last2, s2->len); return result == 0 ? 1 : result; } else /* s1->len == s2->len */ { return memrcmp(last1, last2, s1->len); } } /** * Compare two strings. * * @return the length of the substring that matches. To find out if the two * strings match exactly you must also check if * s1->len == s2->len == return_value. */ size_t string_MatchCount(const struct string *s1, const struct string *s2) { size_t len = MIN(s1->len, s2->len); size_t i = 0; while (i < len && s1->str[i] == s2->str[i]) { i++; } return i; } /** * Compare two strings starting from their end. * * @return the length of the substring that matches. To find out if the two * strings match exactly you must also check if * s1->len == s2->len == return_value. */ size_t string_ReverseMatchCount(const struct string *s1, const struct string *s2) { size_t len = MIN(s1->len, s2->len); const char *last1 = &s1->str[s1->len - 1]; const char *last2 = &s2->str[s2->len - 1]; size_t i = 0; while (i < len && *last1 == *last2) { i++; } return i; } /***************************** STRLIST **************************************/ size_t StrList_Len(const StrList *sl) { return (sl == NULL) ? 0 : sl->len; } char *StrList_At(const StrList *sl, size_t idx) { assert(sl != NULL); assert(idx < sl->len); return sl->list[idx]->str; } /** * Insert s at the given index, reallocating if necessary. * * @return index of the newly inserted string. If -1 (i.e. MAXINT) is returned * then something went horribly wrong. * * @note It is valid for sl to be NULL, which is equivalent to being empty. * */ size_t StrList_Insert(StrList **sl, const char *s, size_t idx) { assert(s != NULL); StrList *slp = *sl; /* for clarity only */ size_t new_alloc_len = 0; /* 0 means no reallocation is needed */ if ((slp == NULL && idx > 0) || (slp != NULL && idx > slp->len)) { ProgrammingError("StrList_Insert: Out of bounds index %zu", idx); } if (slp == NULL) { slp = calloc(1, sizeof(*slp) + sizeof(*slp->list) * 1); if (slp == NULL) { return (size_t) -1; } slp->alloc_len = 1; *sl = slp; } else if (slp->alloc_len == 0) { assert (slp->len == 0); new_alloc_len = 1; } else if (slp->len == slp->alloc_len) /* need more space */ { new_alloc_len = slp->alloc_len * 2; } if (new_alloc_len > 0) /* reallocation is needed */ { StrList *p = realloc(slp, sizeof(*p) + sizeof (*p->list) * new_alloc_len); if (p == NULL) { return (size_t) -1; } slp = p; slp->alloc_len = new_alloc_len; *sl = slp; /* Change the caller's variable */ } struct string *str = string_New(s); if (str == NULL) { /* Our list has grown but contents are the same, we can exit clean. */ return (size_t) -1; } assert(slp->len < slp->alloc_len); memmove(&slp->list[idx + 1], &slp->list[idx], /* Make room */ (slp->len - idx) * sizeof(slp->list[idx])); slp->list[idx] = str; /* Insert element */ slp->len++; return idx; } /** * Appends a string to strlist sl, reallocating if necessary. It returns NULL * if reallocation failed, in which case the initial strlist is still valid. * Else it returns a pointer to the newly appended string. * * @note It is valid for *sl to be NULL, which is equivalent to being empty. */ size_t StrList_Append(StrList **sl, const char *s) { assert(s != NULL); size_t ret; if (*sl == NULL) { ret = StrList_Insert(sl, s, 0); } else { ret = StrList_Insert(sl, s, (*sl)->len); } return ret; } /** * Trim allocated memory to the minimum needed. Free the whole struct if * deemed necessary. This function will never fail. In the unlikely event that * realloc() fails to reduce the allocated amount, then we just keep the same * memory and log an UnexpectedError. * * @param **sl in-out param, might become NULL if the struct was freed. */ void StrList_Finalise(StrList **sl) { StrList *slp = *sl; /* for clarity only */ if (slp == NULL) { return; } assert(slp->len <= slp->alloc_len); if (slp->len == 0) { free(slp); slp = NULL; } else if (slp->len < slp->alloc_len) { StrList *p = realloc(slp, sizeof(*p) + sizeof (*p->list) * slp->len); if (p == NULL) { UnexpectedError("realloc() returned error even though we asked to *reduce* allocated amount: %s", GetErrorStr()); } else { slp = p; slp->alloc_len = slp->len; } } *sl = slp; } /** * Frees everything and sets the strlist back to NULL, i.e. empty. */ void StrList_Free(StrList **sl) { StrList *slp = *sl; /* for clarity */ if (slp == NULL) { return; } size_t i; for (i = 0; i < slp->len; i++) { free(slp->list[i]); } free(slp); *sl = NULL; } void StrList_Sort(StrList *sl, StringComparatorF comparator) { if (sl != NULL && sl->len > 0) { qsort(sl->list, sl->len, sizeof(sl->list[0]), (int (*)(const void *, const void *)) comparator); } } /** * A different binary search, calls libc's bsearch which also means it's also * limited by it: if element is not found only failure can be returned. * * @return index of match or (size_t) -1 if not found */ size_t StrList_bsearch(const StrList *sl, const struct string *s, StringComparatorF comparator) { if (sl != NULL && sl->len > 0) { struct string **ret = bsearch(&s, sl->list, sl->len, sizeof(sl->list[0]), (int (*)(const void *, const void *)) comparator); struct string * const *base = &sl->list[0]; return (ret == NULL) ? (size_t) -1 : (size_t) (ret - base); } else { return (size_t) -1; } } /** * Binary search for the string. Obviously the list must be sorted. * If element not found return the position it should be inserted in. * * @param position returns either the index where it was found, or * the index where it should be inserted in to keep it sorted. */ bool StrList_BinarySearchString(const StrList *slp, const struct string *s, size_t *position) { if (slp == NULL) { *position = 0; return false; } size_t min = 0; size_t max = slp->len; /* -1 produces "Not found" if we don't iterate at all (empty list). */ int ret = -1; size_t mid = 0; while (min < max) { mid = min + (max - min) / 2; const struct string *s_mid = slp->list[mid]; ret = string_Compare(&s, &s_mid); if (ret == -1) /* s < list[mid] */ { max = mid; } else if (ret == 1) /* s > list[mid] */ { min = mid + 1; } else /* s == list[mid] */ { break; } } *position = mid; return (ret == 0); } /** * Same as previous, but accepts a raw char* pointer rather than a struct * string. */ bool StrList_BinarySearch(const StrList *slp, const char *s, size_t *position) { if (slp == NULL) { *position = 0; return false; } size_t min = 0; size_t max = slp->len; /* -1 produces "Not found" if we don't iterate at all (empty list). */ int ret = -1; size_t mid = 0; while (min < max) { mid = min + (max - min) / 2; ret = strcmp(s, slp->list[mid]->str); if (ret < 0) /* s < list[mid] */ { max = mid; } else if (ret > 0) /* s > list[mid] */ { min = mid + 1; /* insert *after* the comparison point, if we exit. */ mid++; } else /* s == list[mid] */ { break; } } *position = mid; return (ret == 0); } /* Search a sorted strlist for string s, of s_len, in forward or backward * direction (for the latter the strlist must be sorted with * string_CompareFromEnd()). */ static size_t StrList_BinarySearchExtended(const StrList *sl, const char *s, size_t s_len, bool direction_forward, size_t *min, size_t *max) { size_t found = -1; size_t priv_min = *min; size_t priv_max = *max; assert(s_len > 0); assert(priv_min < priv_max); assert(priv_max <= sl->len); while (priv_min < priv_max) { size_t pos = (priv_max - priv_min) / 2 + priv_min; const char *s2 = sl->list[pos]->str; size_t s2_len = sl->list[pos]->len; size_t min_len = MIN(s_len, s2_len); int match; if (direction_forward) { match = memcmp(s, sl->list[pos]->str, min_len); } else { match = memrcmp(s, &s2[s2_len - 1], min_len); } if (match == 0) { if (sl->list[pos]->len == s_len) { /* Exact match, we know the list has no duplicates so it's * the first match. */ found = pos; /* We might as well not search here later, when s_len is * longer, because longer means it won't match this. */ *min = pos + 1; break; } else { /* Prefix match, sl[pos] is superstring of s. That means * that the exact match may be before. */ priv_max = pos; /* However we keep this as a different case because we must * not change *max, since that position might match a search * later, with bigger s_len. */ } } else if (match < 0) /* s < sl[pos] */ { priv_max = pos; /* This position will never match, no matter how big s_len grows * in later searches. Thus we change *max to avoid searching * here. */ *max = priv_max; } else /* s > sl[pos] */ { priv_min = pos + 1; /* Same here, this position will never match even for longer s. */ *min = priv_min; } } return found; } /** * Find the longest string in #sl that is a prefix of #s (of length #s_len and * not necessarily '\0'-terminated), delimited by #separator. * * @param #s_len can be the length of #s, since #s is not necessarily * '\0'-terminated. Is #s_len is 0, then #s is assumed to be * '\0'-terminated and length is computed with strlen(). * @note this means that #s can't be 0 bytes... * * @example if #sl is { "/a/", "/a/b/", "/a/c/" } and we are searching for * #s="/a/d/f" with #separator='/' then this function returns 0, which * is the index of "/a/". * * @example if #sl is { ".com", ".net", ".cfengine.com" } and we are searching * for #s="cfengine.com" with #separator='.' and * #direction_forward=false, then this function returns 0, which is * the index of ".com". * if we searched for #s="www.cfengine.com" then it would return 2, * which is the index of "www.cfengine.com". */ size_t StrList_SearchLongestPrefix(const StrList *sl, const char *s, size_t s_len, char separator, bool direction_forward) { /* Remember, NULL strlist is equivalent to empty strlist. */ if (sl == NULL) { return (size_t) -1; } if (s_len == 0) { s_len = strlen(s); } size_t found = -1; size_t old_found = -1; size_t s_prefix_len = 0; size_t min = 0; size_t max = sl->len; bool longer_match_possible = true; /* Keep searching until we've searched the whole length, or until there is * no reason to keep going. */ while (longer_match_possible && (s_prefix_len < s_len)) { char *separator_at; if (direction_forward) { /* Find next separator, skipping the previous one. */ separator_at = memchr(&s[s_prefix_len], separator, s_len - s_prefix_len); s_prefix_len = separator_at - &s[0] + 1; } else { /* In this case, SearchLongestPrefix should be SearchLongestSuffix. * Find next separator from the end, skipping the previous one. */ separator_at = memrchr(s, separator, s_len - s_prefix_len); s_prefix_len = &s[s_len - 1] - separator_at + 1; } if (separator_at == NULL) { s_prefix_len = s_len; /* No separator found, use all string */ } /* printf("StrList_SearchLongestPrefix %s: " */ /* "'%s' len:%zu prefix_len:%zu\n", */ /* direction_forward == true ? "forward" : "backward", */ /* s, s_len, s_prefix_len); */ assert(s_prefix_len <= s_len); if (found != (size_t) -1) { /* Keep the smaller string match in case we don't match again. */ old_found = found; } found = StrList_BinarySearchExtended(sl, direction_forward == true ? s : &s[s_len - 1], s_prefix_len, direction_forward, &min, &max); /* If not even a superstring was found then don't keep trying. */ longer_match_possible = (min < max); } found = (found == (size_t) -1) ? old_found : found; /* printf("StrList_SearchLongestPrefix s:'%s' len:%zu found:'%s'\n", */ /* s, s_len, (found == -1) ? "NONE" : sl->list[found]->str); */ return found; } /** * Search within the given strlist for any prefix of the string #s (or exact * match). Not guaranteed it will return the shortest or longest prefix, just * that it will return *fast* once a prefix or exact match is found. * * @param #direction_forward if set to false then search is done for suffix, * not prefix. * @return the index of the found string, (size_t) -1 if not found. */ size_t StrList_SearchForPrefix(const StrList *sl, const char *s, size_t s_len, bool direction_forward) { /* Remember, NULL strlist is equivalent to empty strlist. */ if (sl == NULL) { return (size_t) -1; } if (s_len == 0) { s_len = strlen(s); } size_t min = 0; size_t max = sl->len; size_t chr_idx = 0; size_t prev_chr_idx = chr_idx; while (min < max) { size_t mid = min + (max - min) / 2; const char *s2 = sl->list[mid]->str; size_t s2_len = sl->list[mid]->len; size_t min_len = MIN(s_len, s2_len); /* We didn't find a string in last iteration so now we are at a * different position (mid) in strlist. Nobody guarantees that the * first bytes still match, so we'll have to reset * chr_idx. Nevertheless, we are sure that the first prev_chr_index * bytes match, because they have already matched twice. */ size_t min_chr_idx = MIN(prev_chr_idx, chr_idx); prev_chr_idx = chr_idx; /* Count the matching characters. */ chr_idx = min_chr_idx; if (direction_forward) { while (chr_idx < min_len && s[chr_idx] == s2[chr_idx]) { chr_idx++; } } else { while (chr_idx < min_len && s[s_len - 1 - chr_idx] == s2[s2_len - 1 - chr_idx]) { chr_idx++; } } if (chr_idx == s_len) { if (s_len == s2_len) { /* We found an exact match. */ return mid; } else { assert(s_len < s2_len); /* We found a superstring of s (i.e. s is a prefix). Don't do * anything, need to keep searching for smaller strings. */ } } else if (chr_idx == s2_len) { /* We found a prefix of s. */ return mid; } /* No match, need to keep searching... */ int compar = s[chr_idx] - sl->list[mid]->str[chr_idx]; if (compar < 0) { max = mid; } else { assert(compar > 0); min = mid + 1; } } return (size_t) -1; } cfengine-3.24.2/cf-serverd/Makefile.in0000644000000000000000000007164615010704300017467 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-serverd$(EXEEXT) subdir = cf-serverd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_serverd_la_DEPENDENCIES = ../libpromises/libpromises.la am_libcf_serverd_la_OBJECTS = cf-serverd.lo \ cf-serverd-enterprise-stubs.lo cf-serverd-functions.lo \ server_common.lo server.lo server_transform.lo \ server_classic.lo server_tls.lo server_access.lo strlist.lo libcf_serverd_la_OBJECTS = $(am_libcf_serverd_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) cf_serverd_SOURCES = cf-serverd.c cf_serverd_OBJECTS = cf_serverd-cf-serverd.$(OBJEXT) @BUILTIN_EXTENSIONS_FALSE@cf_serverd_DEPENDENCIES = libcf-serverd.la cf_serverd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(cf_serverd_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_serverd_la_SOURCES) cf-serverd.c DIST_SOURCES = $(libcf_serverd_la_SOURCES) cf-serverd.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-serverd.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libenv \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(OPENSSL_CFLAGS) \ $(PTHREAD_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_serverd_la_LIBADD = ../libpromises/libpromises.la libcf_serverd_la_SOURCES = \ cf-serverd.c \ cf-serverd-enterprise-stubs.c cf-serverd-enterprise-stubs.h \ cf-serverd-functions.c cf-serverd-functions.h \ server_common.c server_common.h \ server.c server.h \ server_transform.c server_transform.h \ server_classic.c server_classic.h \ server_tls.c server_tls.h \ server_access.c server_access.h \ strlist.c strlist.h # Workaround for automake madness (try removing it if you want to know why). @BUILTIN_EXTENSIONS_FALSE@cf_serverd_CFLAGS = $(AM_CFLAGS) @BUILTIN_EXTENSIONS_FALSE@cf_serverd_LDADD = libcf-serverd.la CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-serverd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-serverd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-serverd.la: $(libcf_serverd_la_OBJECTS) $(libcf_serverd_la_DEPENDENCIES) $(EXTRA_libcf_serverd_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_serverd_la_OBJECTS) $(libcf_serverd_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-serverd$(EXEEXT): $(cf_serverd_OBJECTS) $(cf_serverd_DEPENDENCIES) $(EXTRA_cf_serverd_DEPENDENCIES) @rm -f cf-serverd$(EXEEXT) $(AM_V_CCLD)$(cf_serverd_LINK) $(cf_serverd_OBJECTS) $(cf_serverd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-serverd-enterprise-stubs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-serverd-functions.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-serverd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_serverd-cf-serverd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_classic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_tls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_transform.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlist.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cf_serverd-cf-serverd.o: cf-serverd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_serverd_CFLAGS) $(CFLAGS) -MT cf_serverd-cf-serverd.o -MD -MP -MF $(DEPDIR)/cf_serverd-cf-serverd.Tpo -c -o cf_serverd-cf-serverd.o `test -f 'cf-serverd.c' || echo '$(srcdir)/'`cf-serverd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_serverd-cf-serverd.Tpo $(DEPDIR)/cf_serverd-cf-serverd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-serverd.c' object='cf_serverd-cf-serverd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_serverd_CFLAGS) $(CFLAGS) -c -o cf_serverd-cf-serverd.o `test -f 'cf-serverd.c' || echo '$(srcdir)/'`cf-serverd.c cf_serverd-cf-serverd.obj: cf-serverd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_serverd_CFLAGS) $(CFLAGS) -MT cf_serverd-cf-serverd.obj -MD -MP -MF $(DEPDIR)/cf_serverd-cf-serverd.Tpo -c -o cf_serverd-cf-serverd.obj `if test -f 'cf-serverd.c'; then $(CYGPATH_W) 'cf-serverd.c'; else $(CYGPATH_W) '$(srcdir)/cf-serverd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_serverd-cf-serverd.Tpo $(DEPDIR)/cf_serverd-cf-serverd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-serverd.c' object='cf_serverd-cf-serverd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_serverd_CFLAGS) $(CFLAGS) -c -o cf_serverd-cf-serverd.obj `if test -f 'cf-serverd.c'; then $(CYGPATH_W) 'cf-serverd.c'; else $(CYGPATH_W) '$(srcdir)/cf-serverd.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-serverd/cf-serverd-functions.h0000644000000000000000000000313215010704253021631 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CF_SERVERD_FUNCTIONS_H #define CFENGINE_CF_SERVERD_FUNCTIONS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef int (*InitServerFunction)(size_t queue_size, char *bind_address); GenericAgentConfig *CheckOpts(int argc, char **argv); int StartServer(EvalContext *ctx, Policy **policy, GenericAgentConfig *config); #endif cfengine-3.24.2/cf-serverd/server_tls.h0000644000000000000000000000505715010704253017763 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SERVER_TLS_H #define CFENGINE_SERVER_TLS_H #include #include /* EvalContext */ #include /* ConnectionInfo */ #include /* ServerConnectionState */ typedef enum { PROTOCOL_COMMAND_EXEC = 0, PROTOCOL_COMMAND_GET, PROTOCOL_COMMAND_OPENDIR, PROTOCOL_COMMAND_SYNCH, PROTOCOL_COMMAND_MD5, PROTOCOL_COMMAND_VERSION, PROTOCOL_COMMAND_VAR, PROTOCOL_COMMAND_CONTEXT, PROTOCOL_COMMAND_QUERY, PROTOCOL_COMMAND_CALL_ME_BACK, PROTOCOL_COMMAND_COOKIE, PROTOCOL_COMMAND_BAD } ProtocolCommandNew; static const char *const PROTOCOL_NEW[PROTOCOL_COMMAND_BAD + 1] = { "EXEC", "GET", "OPENDIR", "SYNCH", "MD5", "VERSION", "VAR", "CONTEXT", "QUERY", "SCALLBACK", "COOKIE", NULL }; bool ServerTLSInitialize(RSA *priv_key, RSA *pub_key, SSL_CTX **ctx); void ServerTLSDeInitialize(RSA **priv_key, RSA **pub_key, SSL_CTX **ctx); bool ServerTLSPeek(ConnectionInfo *conn_info); bool BasicServerTLSSessionEstablish(ServerConnectionState *conn, SSL_CTX *ssl_ctx); bool ServerTLSSessionEstablish(ServerConnectionState *conn, SSL_CTX *ssl_ctx); bool BusyWithNewProtocol(EvalContext *ctx, ServerConnectionState *conn); bool ServerSendWelcome(const ServerConnectionState *conn); bool ServerIdentificationDialog(ConnectionInfo *conn_info, char *username, size_t username_size); ProtocolCommandNew GetCommandNew(char *str); #endif /* CFENGINE_SERVER_TLS_H */ cfengine-3.24.2/cf-serverd/cf-serverd-enterprise-stubs.h0000644000000000000000000000532515010704253023145 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CF_SERVERD_ENTERPRISE_STUBS_H #define CFENGINE_CF_SERVERD_ENTERPRISE_STUBS_H #include #include struct ServerConnectionState; ENTERPRISE_VOID_FUNC_3ARG_DECLARE(void, RegisterLiteralServerData, EvalContext *, ctx, const char *, handle, const Promise *, pp); ENTERPRISE_FUNC_3ARG_DECLARE(int, ReturnLiteralData, EvalContext *, ctx, char *, handle, char *, ret); ENTERPRISE_FUNC_5ARG_DECLARE(int, SetServerListenState, EvalContext *, ctx, size_t, queue_size, char *, bind_address, bool, server_listen, InitServerFunction, InitServerPtr); typedef void (*ServerEntryPointFunction)(EvalContext *ctx, char *ipaddr, ConnectionInfo *info); ENTERPRISE_FUNC_1ARG_DECLARE(bool, ReceiveCollectCall, ServerConnectionState *, conn); ENTERPRISE_FUNC_1ARG_DECLARE(bool, ReturnCookies, ServerConnectionState *, conn); ENTERPRISE_FUNC_3ARG_DECLARE(bool, ReturnQueryData, ServerConnectionState *, conn, char *, menu, int, encrypt); ENTERPRISE_FUNC_2ARG_DECLARE(bool, CFTestD_ReturnQueryData, ServerConnectionState *, conn, char *, menu); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, KeepReportDataSelectAccessPromise, const Promise *, pp); ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, CleanReportBookFilterSet); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, FprintAvahiCfengineTag, FILE *, fp); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, CollectCallStart, ARG_UNUSED int, interval); ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, CollectCallStop); ENTERPRISE_FUNC_0ARG_DECLARE(bool, CollectCallHasPending); ENTERPRISE_FUNC_1ARG_DECLARE(int, CollectCallGetPending, ARG_UNUSED int *, queue_length); ENTERPRISE_VOID_FUNC_0ARG_DECLARE(void, CollectCallMarkProcessed); #endif cfengine-3.24.2/cf-serverd/server_common.c0000644000000000000000000016225415010704253020447 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ static const int CF_NOSIZE = -1; #include #include /* ItemList2CSV_bound */ #include /* ToLower,StrCatDelim */ #include /* StringMatchFull */ #include /* EncryptString */ #include #include #include #include #include #include #include #include /* IsRegexItemIn */ #include #include /* SendSocketStream */ #include /* SendTransaction,ReceiveTransaction */ #include /* ERR_get_error */ #include /* ProtocolIsKnown() */ #include /* TLSSend */ #include #include #include #include /* UnexpectedError */ #include /* NovaWin_UserNameToSid */ #include /* ThreadLock */ #include /* struct Stat */ #include /* GetUserID() */ #include "server_access.h" /* NOTE: Always Log(LOG_LEVEL_INFO) before calling RefuseAccess(), so that * some clue is printed in the cf-serverd logs. */ void RefuseAccess(ServerConnectionState *conn, char *errmesg) { SendTransaction(conn->conn_info, CF_FAILEDSTR, 0, CF_DONE); /* TODO remove logging, it's done elsewhere. */ Log(LOG_LEVEL_VERBOSE, "REFUSAL to user='%s' of request: %s", NULL_OR_EMPTY(conn->username) ? "?" : conn->username, errmesg); } bool IsUserNameValid(const char *username) { /* Add whatever characters are considered invalid in username */ const char *invalid_username_characters = "\\/"; if (strpbrk(username, invalid_username_characters) == NULL) { return true; } return false; } bool AllowedUser(char *user) { if (IsItemIn(SERVER_ACCESS.allowuserlist, user)) { Log(LOG_LEVEL_DEBUG, "User %s granted connection privileges", user); return true; } Log(LOG_LEVEL_DEBUG, "User %s is not allowed on this server", user); return false; } Item *ListPersistentClasses() { Log(LOG_LEVEL_VERBOSE, "Scanning for all persistent classes"); CF_DB *dbp; CF_DBC *dbcp; if (!OpenDB(&dbp, dbid_state)) { char *db_path = DBIdToPath(dbid_state); Log(LOG_LEVEL_ERR, "Unable to open persistent classes database '%s'", db_path); free(db_path); return NULL; } if (!NewDBCursor(dbp, &dbcp)) { char *db_path = DBIdToPath(dbid_state); Log(LOG_LEVEL_ERR, "Unable to get cursor for persistent classes database '%s'", db_path); free(db_path); CloseDB(dbp); return NULL; } const PersistentClassInfo *value; int ksize, vsize; char *key; size_t count = 0; time_t now = time(NULL); Item *persistent_classes = NULL; while (NextDB(dbcp, &key, &ksize, (void **)&value, &vsize)) { if (now > value->expires) { Log(LOG_LEVEL_DEBUG, "Persistent class %s expired, removing from database", key); DBCursorDeleteEntry(dbcp); } else { count++; PrependItem(&persistent_classes, key, NULL); } } DeleteDBCursor(dbcp); CloseDB(dbp); if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { char logbuf[CF_BUFSIZE]; ItemList2CSV_bound(persistent_classes, logbuf, sizeof(logbuf), ' '); Log(LOG_LEVEL_VERBOSE, "Found %zu valid persistent classes in state database: %s", count, logbuf); } return persistent_classes; } static void ReplyNothing(ServerConnectionState *conn) { char buffer[CF_BUFSIZE]; snprintf(buffer, CF_BUFSIZE, "Hello %s (%s), nothing relevant to do here...\n\n", conn->hostname, conn->ipaddr); if (SendTransaction(conn->conn_info, buffer, 0, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Unable to send transaction. (send: %s)", GetErrorStr()); } } /* Used only in EXEC protocol command, to check if any of the received classes * is defined in the server. */ bool MatchClasses(const EvalContext *ctx, ServerConnectionState *conn) { char recvbuffer[CF_BUFSIZE]; Item *classlist = NULL, *ip; int count = 0; while (true && (count < 10)) /* arbitrary check to avoid infinite loop, DoS attack */ { count++; if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to read data from network. (ReceiveTransaction: %s)", GetErrorStr()); return false; } if (strncmp(recvbuffer, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) { Log(LOG_LEVEL_DEBUG, "Got CFD_TERMINATOR"); if (count == 1) { /* This is the common case, that cf-runagent had no "-s class1,class2" argument. */ Log(LOG_LEVEL_DEBUG, "No classes were sent, assuming no restrictions..."); return true; } break; } Log(LOG_LEVEL_DEBUG, "Got class buffer: %s", recvbuffer); classlist = SplitStringAsItemList(recvbuffer, ' '); for (ip = classlist; ip != NULL; ip = ip->next) { Log(LOG_LEVEL_VERBOSE, "Checking whether class %s can be identified as me...", ip->name); if (IsDefinedClass(ctx, ip->name)) { Log(LOG_LEVEL_DEBUG, "Class '%s' matched, accepting...", ip->name); DeleteItemList(classlist); return true; } { /* What the heck are we doing here? */ /* Hmmm so we iterate over all classes to see if the regex * received (ip->name) matches (StringMatchFull) to any local * class (expr)... SLOW! Change the spec! Don't accept * regexes! How many will be affected if a specific class has * to be set to run command, instead of matching a pattern? * It's safer anyway... */ ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls = NULL; while ((cls = ClassTableIteratorNext(iter))) { char *expr = ClassRefToString(cls->ns, cls->name); /* FIXME: review this strcmp. Moved out from StringMatch */ bool match = (strcmp(ip->name, expr) == 0 || StringMatchFull(ip->name, expr)); free(expr); if (match) { Log(LOG_LEVEL_DEBUG, "Class matched regular expression '%s', accepting...", ip->name); DeleteItemList(classlist); return true; } } ClassTableIteratorDestroy(iter); } if (strncmp(ip->name, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) { Log(LOG_LEVEL_VERBOSE, "No classes matched, rejecting...."); ReplyNothing(conn); DeleteItemList(classlist); return false; } } } ReplyNothing(conn); Log(LOG_LEVEL_VERBOSE, "No classes matched, rejecting...."); DeleteItemList(classlist); return false; } /* TODO deprecate this function, only a simple SendTransaction(CFD_TERMINATOR) * should be enough, without even error printing (it's already done in * SendTransaction()). */ void Terminate(ConnectionInfo *connection) { /* We send a trailing NULL in this transaction packet. TODO WHY? */ if (SendTransaction(connection, CFD_TERMINATOR, strlen(CFD_TERMINATOR) + 1, CF_DONE) == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to reply with terminator. (send: %s)", GetErrorStr()); } } static bool TransferRights( const ServerConnectionState *conn, const char *filename, const struct stat *sb) { Log(LOG_LEVEL_DEBUG, "Checking ownership of file: %s", filename); /* Don't do any check if connected user claims to be "root" or if * "maproot" in access_rules contains the connecting IP address. */ if ((conn->uid == 0) || (conn->maproot)) { Log(LOG_LEVEL_DEBUG, "Access granted because %s", (conn->uid == 0) ? "remote user is root" : "of maproot"); return true; /* access granted */ } #ifdef __MINGW32__ SECURITY_DESCRIPTOR *secDesc; SID *ownerSid; if (GetNamedSecurityInfo( filename, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, (PSID *) &ownerSid, NULL, NULL, NULL, (void **) &secDesc) != ERROR_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not retrieve owner of file '%s' " "(GetNamedSecurityInfo: %s)", filename, GetErrorStr()); return false; } LocalFree(secDesc); if (!IsValidSid(conn->sid) || !EqualSid(ownerSid, conn->sid)) { /* If "maproot" we've already granted access. */ assert(!conn->maproot); Log(LOG_LEVEL_INFO, "Remote user '%s' is not the owner of the file, access denied, " "consider maproot", conn->username); return false; } Log(LOG_LEVEL_DEBUG, "User '%s' is the owner of the file, access granted", conn->username); #else /* UNIX systems - common path */ if (sb->st_uid != conn->uid) /* does not own the file */ { if (!(sb->st_mode & S_IROTH)) /* file not world readable */ { Log(LOG_LEVEL_INFO, "Remote user '%s' is not owner of the file, access denied, " "consider maproot or making file world-readable", conn->username); return false; } else { Log(LOG_LEVEL_DEBUG, "Remote user '%s' is not the owner of the file, " "but file is world readable, access granted", conn->username); /* access granted */ } } else { Log(LOG_LEVEL_DEBUG, "User '%s' is the owner of the file, access granted", conn->username); /* access granted */ } /* ADMIT ACCESS, to summarise the following condition is now true: */ /* Remote user is root, where "user" is just a string in the protocol, he * might claim whatever he wants but will be able to login only if the * user-key.pub key is found, */ assert((conn->uid == 0) || /* OR remote IP has maproot in the file's access_rules, */ (conn->maproot == true) || /* OR file is owned by the same username the user claimed - useless or * even dangerous outside NIS, KERBEROS or LDAP authenticated domains, */ (sb->st_uid == conn->uid) || /* OR file is readable by everyone */ (sb->st_mode & S_IROTH)); #endif return true; } static void AbortTransfer(ConnectionInfo *connection, char *filename) { Log(LOG_LEVEL_VERBOSE, "Aborting transfer of file due to source changes"); char sendbuffer[CF_BUFSIZE]; snprintf(sendbuffer, CF_BUFSIZE, "%s%s: %s", CF_CHANGEDSTR1, CF_CHANGEDSTR2, filename); if (SendTransaction(connection, sendbuffer, 0, CF_DONE) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); } } static void FailedTransfer(ConnectionInfo *connection) { Log(LOG_LEVEL_VERBOSE, "Transfer failure"); char sendbuffer[CF_BUFSIZE]; snprintf(sendbuffer, CF_BUFSIZE, "%s", CF_FAILEDSTR); if (SendTransaction(connection, sendbuffer, 0, CF_DONE) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); } } void CfGetFile(ServerFileGetState *args) { int fd; off_t n_read, total = 0, sendlen = 0, count = 0; char sendbuffer[CF_BUFSIZE + 256], filename[CF_BUFSIZE - 128]; struct stat sb; int blocksize = 2048; ConnectionInfo *conn_info = args->conn->conn_info; TranslatePath(args->replyfile, filename, sizeof(filename)); stat(filename, &sb); Log(LOG_LEVEL_DEBUG, "CfGetFile('%s'), size = %jd", filename, (intmax_t) sb.st_size); /* Now check to see if we have remote permission */ if (!TransferRights(args->conn, filename, &sb)) { Log(LOG_LEVEL_INFO, "REFUSE access to file: %s", filename); RefuseAccess(args->conn, args->replyfile); snprintf(sendbuffer, CF_BUFSIZE, "%s", CF_FAILEDSTR); const ProtocolVersion version = ConnectionInfoProtocolVersion(conn_info); assert(ProtocolIsKnown(version)); if (ProtocolIsClassic(version)) { SendSocketStream(ConnectionInfoSocket(conn_info), sendbuffer, args->buf_size); } else if (ProtocolIsTLS(version)) { TLSSend(ConnectionInfoSSL(conn_info), sendbuffer, args->buf_size); } return; } /* File transfer */ if ((fd = safe_open(filename, O_RDONLY)) == -1) { Log(LOG_LEVEL_ERR, "Open error of file '%s'. (open: %s)", filename, GetErrorStr()); snprintf(sendbuffer, CF_BUFSIZE, "%s", CF_FAILEDSTR); const ProtocolVersion version = ConnectionInfoProtocolVersion(conn_info); assert(ProtocolIsKnown(version)); if (ProtocolIsClassic(version)) { SendSocketStream(ConnectionInfoSocket(conn_info), sendbuffer, args->buf_size); } else if (ProtocolIsTLS(version)) { TLSSend(ConnectionInfoSSL(conn_info), sendbuffer, args->buf_size); } } else { int div = 3; if (sb.st_size > 10485760L) /* File larger than 10 MB, checks every 64kB */ { div = 32; } while (true) { memset(sendbuffer, 0, CF_BUFSIZE); Log(LOG_LEVEL_DEBUG, "Now reading from disk..."); if ((n_read = read(fd, sendbuffer, blocksize)) == -1) { Log(LOG_LEVEL_ERR, "Read failed in GetFile. (read: %s)", GetErrorStr()); break; } if (n_read == 0) { break; } else { off_t savedlen = sb.st_size; /* check the file is not changing at source */ if (count++ % div == 0) /* Don't do this too often */ { if (stat(filename, &sb)) { Log(LOG_LEVEL_ERR, "Cannot stat file '%s'. (stat: %s)", filename, GetErrorStr()); break; } } if (sb.st_size != savedlen) { snprintf(sendbuffer, CF_BUFSIZE, "%s%s: %s", CF_CHANGEDSTR1, CF_CHANGEDSTR2, filename); const ProtocolVersion version = ConnectionInfoProtocolVersion(conn_info); if (ProtocolIsClassic(version)) { if (SendSocketStream(ConnectionInfoSocket(conn_info), sendbuffer, blocksize) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); } } else if (ProtocolIsTLS(version)) { if (TLSSend(ConnectionInfoSSL(conn_info), sendbuffer, blocksize) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); } } Log(LOG_LEVEL_DEBUG, "Aborting transfer after %jd: file is changing rapidly at source.", (intmax_t) total); break; } if ((savedlen - total) / blocksize > 0) { sendlen = blocksize; } else if (savedlen != 0) { sendlen = (savedlen - total); } } total += n_read; const ProtocolVersion version = ConnectionInfoProtocolVersion(conn_info); if (ProtocolIsClassic(version)) { if (SendSocketStream(ConnectionInfoSocket(conn_info), sendbuffer, sendlen) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); break; } } else if (ProtocolIsTLS(version)) { if (TLSSend(ConnectionInfoSSL(conn_info), sendbuffer, sendlen) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); break; } } } close(fd); } } void CfEncryptGetFile(ServerFileGetState *args) /* Because the stream doesn't end for each file, we need to know the exact number of bytes transmitted, which might change during encryption, hence we need to handle this with transactions */ { int fd, n_read, cipherlen = 0, finlen = 0; off_t total = 0, count = 0; char filename[CF_BUFSIZE]; unsigned char sendbuffer[CF_BUFSIZE + 256]; unsigned char out[CF_BUFSIZE]; unsigned char iv[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; int blocksize = CF_BUFSIZE - 4 * CF_INBAND_OFFSET; struct stat sb; ConnectionInfo *conn_info = args->conn->conn_info; const unsigned char *const key = args->conn->session_key; const char enctype = args->conn->encryption_type; TranslatePath(args->replyfile, filename, sizeof(filename)); stat(filename, &sb); Log(LOG_LEVEL_DEBUG, "CfEncryptGetFile('%s'), size = %jd", filename, (intmax_t) sb.st_size); /* Now check to see if we have remote permission */ if (!TransferRights(args->conn, filename, &sb)) { Log(LOG_LEVEL_INFO, "REFUSE access to file: %s", filename); RefuseAccess(args->conn, args->replyfile); FailedTransfer(conn_info); return; } EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { Log(LOG_LEVEL_ERR, "Failed to allocate cipher: %s", TLSErrorString(ERR_get_error())); return; } if ((fd = safe_open(filename, O_RDONLY)) == -1) { Log(LOG_LEVEL_ERR, "Open error of file '%s'. (open: %s)", filename, GetErrorStr()); FailedTransfer(conn_info); } else { int div = 3; if (sb.st_size > 10485760L) /* File larger than 10 MB, checks every 64kB */ { div = 32; } while (true) { memset(sendbuffer, 0, CF_BUFSIZE); if ((n_read = read(fd, sendbuffer, blocksize)) == -1) { Log(LOG_LEVEL_ERR, "Read failed in EncryptGetFile. (read: %s)", GetErrorStr()); break; } off_t savedlen = sb.st_size; if (count++ % div == 0) /* Don't do this too often */ { Log(LOG_LEVEL_DEBUG, "Restatting '%s' - size %d", filename, n_read); if (stat(filename, &sb)) { Log(LOG_LEVEL_ERR, "Cannot stat file '%s' (stat: %s)", filename, GetErrorStr()); break; } } if (sb.st_size != savedlen) { AbortTransfer(conn_info, filename); break; } total += n_read; if (n_read > 0) { EVP_EncryptInit_ex(ctx, CfengineCipher(enctype), NULL, key, iv); if (!EVP_EncryptUpdate(ctx, out, &cipherlen, sendbuffer, n_read)) { FailedTransfer(conn_info); EVP_CIPHER_CTX_free(ctx); close(fd); return; } if (!EVP_EncryptFinal_ex(ctx, out + cipherlen, &finlen)) { FailedTransfer(conn_info); EVP_CIPHER_CTX_free(ctx); close(fd); return; } } if (total >= savedlen) { if (SendTransaction(conn_info, (const char *) out, cipherlen + finlen, CF_DONE) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); EVP_CIPHER_CTX_free(ctx); close(fd); return; } break; } else { if (SendTransaction(conn_info, (const char *) out, cipherlen + finlen, CF_MORE) == -1) { Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr()); close(fd); EVP_CIPHER_CTX_free(ctx); return; } } } } EVP_CIPHER_CTX_free(ctx); close(fd); } int StatFile(ServerConnectionState *conn, char *sendbuffer, char *ofilename) /* Because we do not know the size or structure of remote datatypes,*/ /* the simplest way to transfer the data is to convert them into */ /* plain text and interpret them on the other side. */ { Stat cfst; struct stat statbuf, statlinkbuf; char linkbuf[CF_BUFSIZE], filename[CF_BUFSIZE - 128]; int islink = false; TranslatePath(ofilename, filename, sizeof(filename)); memset(&cfst, 0, sizeof(Stat)); if (strlen(ReadLastNode(filename)) > CF_MAXLINKSIZE) { snprintf(sendbuffer, CF_MSGSIZE, "BAD: Filename suspiciously long [%s]", filename); Log(LOG_LEVEL_ERR, "%s", sendbuffer); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return -1; } if (lstat(filename, &statbuf) == -1) { snprintf(sendbuffer, CF_MSGSIZE, "BAD: unable to stat file %s", filename); Log(LOG_LEVEL_VERBOSE, "%s. (lstat: %s)", sendbuffer, GetErrorStr()); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return -1; } cfst.cf_readlink = NULL; cfst.cf_lmode = 0; cfst.cf_nlink = CF_NOSIZE; memset(linkbuf, 0, CF_BUFSIZE); #ifndef __MINGW32__ // windows doesn't support symbolic links if (S_ISLNK(statbuf.st_mode)) { islink = true; cfst.cf_type = FILE_TYPE_LINK; /* pointless - overwritten */ cfst.cf_lmode = statbuf.st_mode & 07777; cfst.cf_nlink = statbuf.st_nlink; if (readlink(filename, linkbuf, CF_BUFSIZE - 1) == -1) { strcpy(sendbuffer, "BAD: unable to read link"); Log(LOG_LEVEL_ERR, "%s. (readlink: %s)", sendbuffer, GetErrorStr()); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return -1; } Log(LOG_LEVEL_DEBUG, "readlink '%s'", linkbuf); cfst.cf_readlink = linkbuf; } if (islink && (stat(filename, &statlinkbuf) != -1)) /* linktype=copy used by agent */ { Log(LOG_LEVEL_DEBUG, "Getting size of link deref '%s'", linkbuf); statbuf.st_size = statlinkbuf.st_size; statbuf.st_mode = statlinkbuf.st_mode; statbuf.st_uid = statlinkbuf.st_uid; statbuf.st_gid = statlinkbuf.st_gid; statbuf.st_mtime = statlinkbuf.st_mtime; statbuf.st_ctime = statlinkbuf.st_ctime; } #endif /* !__MINGW32__ */ if (S_ISDIR(statbuf.st_mode)) { cfst.cf_type = FILE_TYPE_DIR; } if (S_ISREG(statbuf.st_mode)) { cfst.cf_type = FILE_TYPE_REGULAR; } if (S_ISSOCK(statbuf.st_mode)) { cfst.cf_type = FILE_TYPE_SOCK; } if (S_ISCHR(statbuf.st_mode)) { cfst.cf_type = FILE_TYPE_CHAR_; } if (S_ISBLK(statbuf.st_mode)) { cfst.cf_type = FILE_TYPE_BLOCK; } if (S_ISFIFO(statbuf.st_mode)) { cfst.cf_type = FILE_TYPE_FIFO; } cfst.cf_mode = statbuf.st_mode & 07777; cfst.cf_uid = statbuf.st_uid & 0xFFFFFFFF; cfst.cf_gid = statbuf.st_gid & 0xFFFFFFFF; cfst.cf_size = statbuf.st_size; cfst.cf_atime = statbuf.st_atime; cfst.cf_mtime = statbuf.st_mtime; cfst.cf_ctime = statbuf.st_ctime; cfst.cf_ino = statbuf.st_ino; cfst.cf_dev = statbuf.st_dev; cfst.cf_readlink = linkbuf; if (cfst.cf_nlink == CF_NOSIZE) { cfst.cf_nlink = statbuf.st_nlink; } /* Is file sparse? */ if (statbuf.st_size > ST_NBYTES(statbuf)) { cfst.cf_makeholes = 1; /* must have a hole to get checksum right */ } else { cfst.cf_makeholes = 0; } memset(sendbuffer, 0, CF_MSGSIZE); /* send as plain text */ Log(LOG_LEVEL_DEBUG, "OK: type = %d, mode = %jo, lmode = %jo, " "uid = %ju, gid = %ju, size = %jd, atime=%jd, mtime = %jd", cfst.cf_type, (uintmax_t) cfst.cf_mode, (uintmax_t) cfst.cf_lmode, (uintmax_t) cfst.cf_uid, (uintmax_t) cfst.cf_gid, (intmax_t) cfst.cf_size, (intmax_t) cfst.cf_atime, (intmax_t) cfst.cf_mtime); snprintf(sendbuffer, CF_MSGSIZE, "OK: %d %ju %ju %ju %ju %jd %jd %jd %jd %d %d %d %jd", cfst.cf_type, (uintmax_t) cfst.cf_mode, (uintmax_t) cfst.cf_lmode, (uintmax_t) cfst.cf_uid, (uintmax_t) cfst.cf_gid, (intmax_t) cfst.cf_size, (intmax_t) cfst.cf_atime, (intmax_t) cfst.cf_mtime, (intmax_t) cfst.cf_ctime, cfst.cf_makeholes, cfst.cf_ino, cfst.cf_nlink, (intmax_t) cfst.cf_dev); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); memset(sendbuffer, 0, CF_MSGSIZE); if (cfst.cf_readlink != NULL) { strcpy(sendbuffer, "OK:"); strcat(sendbuffer, cfst.cf_readlink); } else { strcpy(sendbuffer, "OK:"); } SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return 0; } bool CompareLocalHash(const char *filename, const unsigned char digest[EVP_MAX_MD_SIZE + 1], char sendbuffer[CFD_FALSE_SIZE]) { nt_static_assert(CFD_FALSE_SIZE == (strlen(CFD_FALSE) + 1)); nt_static_assert(strlen(CFD_FALSE) >= strlen(CFD_TRUE)); char translated_filename[CF_BUFSIZE] = { 0 }; TranslatePath(filename, translated_filename, sizeof(translated_filename)); unsigned char file_digest[EVP_MAX_MD_SIZE + 1] = { 0 }; /* TODO connection might timeout if this takes long! */ HashFile(translated_filename, file_digest, CF_DEFAULT_DIGEST, false); if (HashesMatch(digest, file_digest, CF_DEFAULT_DIGEST)) { strcpy(sendbuffer, CFD_FALSE); Log(LOG_LEVEL_DEBUG, "Hashes matched ok"); return true; } else { strcpy(sendbuffer, CFD_TRUE); Log(LOG_LEVEL_DEBUG, "Hashes didn't match"); return false; } } void GetServerLiteral(EvalContext *ctx, ServerConnectionState *conn, char *sendbuffer, char *recvbuffer, int encrypted) { char handle[CF_BUFSIZE], out[CF_BUFSIZE]; int cipherlen; sscanf(recvbuffer, "VAR %255[^\n]", handle); if (ReturnLiteralData(ctx, handle, out)) { memset(sendbuffer, 0, CF_BUFSIZE); snprintf(sendbuffer, CF_BUFSIZE, "%s", out); } else { memset(sendbuffer, 0, CF_BUFSIZE); snprintf(sendbuffer, CF_BUFSIZE, "BAD: Not found"); } if (encrypted) { cipherlen = EncryptString(out, sizeof(out), sendbuffer, strlen(sendbuffer) + 1, conn->encryption_type, conn->session_key); SendTransaction(conn->conn_info, out, cipherlen, CF_DONE); } else { SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); } } bool GetServerQuery(ServerConnectionState *conn, char *recvbuffer, int encrypt) { char query[CF_BUFSIZE]; query[0] = '\0'; sscanf(recvbuffer, "QUERY %255[^\n]", query); if (strlen(query) == 0) { return false; } return ReturnQueryData(conn, query, encrypt); } void ReplyServerContext(ServerConnectionState *conn, int encrypted, Item *classes) { char sendbuffer[CF_BUFSIZE - CF_INBAND_OFFSET]; size_t ret = ItemList2CSV_bound(classes, sendbuffer, sizeof(sendbuffer), ','); if (ret >= sizeof(sendbuffer)) { Log(LOG_LEVEL_ERR, "Overflow: classes don't fit in send buffer"); } DeleteItemList(classes); if (encrypted) { char out[CF_BUFSIZE]; int cipherlen = EncryptString(out, sizeof(out), sendbuffer, strlen(sendbuffer) + 1, conn->encryption_type, conn->session_key); SendTransaction(conn->conn_info, out, cipherlen, CF_DONE); } else { SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); } } int CfOpenDirectory(ServerConnectionState *conn, char *sendbuffer, char *oldDirname) { Dir *dirh; const struct dirent *dirp; int offset; char dirname[CF_BUFSIZE - 128]; TranslatePath(oldDirname, dirname, sizeof(dirname)); if (!IsAbsoluteFileName(dirname)) { strcpy(sendbuffer, "BAD: request to access a non-absolute filename"); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return -1; } if ((dirh = DirOpen(dirname)) == NULL) { Log(LOG_LEVEL_INFO, "Couldn't open directory '%s' (DirOpen:%s)", dirname, GetErrorStr()); snprintf(sendbuffer, CF_BUFSIZE, "BAD: cfengine, couldn't open dir %s", dirname); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return -1; } /* Pack names for transmission */ offset = 0; for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { /* Always leave MAXLINKSIZE bytes for CFD_TERMINATOR. Why??? */ if (strlen(dirp->d_name) + 1 + offset >= CF_BUFSIZE - CF_MAXLINKSIZE) { /* Double '\0' indicates end of packet. */ sendbuffer[offset] = '\0'; SendTransaction(conn->conn_info, sendbuffer, offset + 1, CF_MORE); offset = 0; /* new packet */ } /* TODO fix copying names greater than 256. */ strlcpy(sendbuffer + offset, dirp->d_name, CF_MAXLINKSIZE); offset += strlen(dirp->d_name) + 1; /* +1 for '\0' */ } strcpy(sendbuffer + offset, CFD_TERMINATOR); offset += strlen(CFD_TERMINATOR) + 1; /* +1 for '\0' */ /* Double '\0' indicates end of packet. */ sendbuffer[offset] = '\0'; SendTransaction(conn->conn_info, sendbuffer, offset + 1, CF_DONE); DirClose(dirh); return 0; } /**************************************************************/ int CfSecOpenDirectory(ServerConnectionState *conn, char *sendbuffer, char *dirname) { Dir *dirh; const struct dirent *dirp; int offset, cipherlen; char out[CF_BUFSIZE]; if (!IsAbsoluteFileName(dirname)) { strcpy(sendbuffer, "BAD: request to access a non-absolute filename"); cipherlen = EncryptString(out, sizeof(out), sendbuffer, strlen(sendbuffer) + 1, conn->encryption_type, conn->session_key); SendTransaction(conn->conn_info, out, cipherlen, CF_DONE); return -1; } if ((dirh = DirOpen(dirname)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Couldn't open dir %s", dirname); snprintf(sendbuffer, CF_BUFSIZE, "BAD: cfengine, couldn't open dir %s", dirname); cipherlen = EncryptString(out, sizeof(out), sendbuffer, strlen(sendbuffer) + 1, conn->encryption_type, conn->session_key); SendTransaction(conn->conn_info, out, cipherlen, CF_DONE); return -1; } /* Pack names for transmission */ memset(sendbuffer, 0, CF_BUFSIZE); offset = 0; for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (strlen(dirp->d_name) + 1 + offset >= CF_BUFSIZE - CF_MAXLINKSIZE) { cipherlen = EncryptString(out, sizeof(out), sendbuffer, offset + 1, conn->encryption_type, conn->session_key); SendTransaction(conn->conn_info, out, cipherlen, CF_MORE); offset = 0; memset(sendbuffer, 0, CF_BUFSIZE); memset(out, 0, CF_BUFSIZE); } strlcpy(sendbuffer + offset, dirp->d_name, CF_MAXLINKSIZE); /* + zero byte separator */ offset += strlen(dirp->d_name) + 1; } strcpy(sendbuffer + offset, CFD_TERMINATOR); cipherlen = EncryptString(out, sizeof(out), sendbuffer, offset + 2 + strlen(CFD_TERMINATOR), conn->encryption_type, conn->session_key); SendTransaction(conn->conn_info, out, cipherlen, CF_DONE); DirClose(dirh); return 0; } /********************* MISC UTILITY FUNCTIONS *************************/ /** * Search and replace occurrences of #find1, #find2, #find3, with * #repl1, #repl2, #repl3 respectively. * * "$(connection.ip)" from "191.168.0.1" * "$(connection.hostname)" from "blah.cfengine.com", * "$(connection.key)" from "SHA=asdfghjkl" * * @return the output length of #buf, (size_t) -1 if overflow would occur, * or 0 if no replacement happened and #buf was not touched. * * @TODO change the function to more generic interface accepting arbitrary * find/replace pairs. */ size_t ReplaceSpecialVariables(char *buf, size_t buf_size, const char *find1, const char *repl1, const char *find2, const char *repl2, const char *find3, const char *repl3) { size_t ret = 0; if ((find1 != NULL) && (find1[0] != '\0') && (repl1 != NULL) && (repl1[0] != '\0')) { size_t ret2 = StringReplace(buf, buf_size, find1, repl1); ret = MAX(ret, ret2); /* size_t is unsigned, thus -1 wins */ } if ((ret != (size_t) -1) && (find2 != NULL) && (find2[0] != '\0') && (repl2 != NULL) && (repl2[0] != '\0')) { size_t ret2 = StringReplace(buf, buf_size, find2, repl2); ret = MAX(ret, ret2); } if ((ret != (size_t) -1) && (find3 != NULL) && (find3[0] != '\0') && (repl3 != NULL) && (repl3[0] != '\0')) { size_t ret2 = StringReplace(buf, buf_size, find3, repl3); ret = MAX(ret, ret2); } /* Zero is returned only if all of the above were zero. */ return ret; } /** * Remove trailing FILE_SEPARATOR, unless we're referring to root dir: '/' or 'a:\' */ bool PathRemoveTrailingSlash(char *s, size_t s_len) { char *first_separator = strchr(s, FILE_SEPARATOR); if (first_separator != NULL && s[s_len-1] == FILE_SEPARATOR && &s[s_len-1] != first_separator) { s[s_len-1] = '\0'; return true; } return false; } /** * Append a trailing FILE_SEPARATOR if it's not there. */ bool PathAppendTrailingSlash(char *s, size_t s_len) { if (s_len > 0 && s[s_len-1] != FILE_SEPARATOR) { s[s_len] = FILE_SEPARATOR; s[s_len+1] = '\0'; return true; } return false; } /* We use this instead of IsAbsoluteFileName() which also checks for * quotes. There is no meaning in receiving quoted strings over the * network. */ static bool PathIsAbsolute(const char *s) { bool result = false; #if defined(__MINGW32__) if (isalpha(s[0]) && (s[1] == ':') && (s[2] == FILE_SEPARATOR)) { result = true; /* A:\ */ } else /* \\ */ { result = (s[0] == FILE_SEPARATOR && s[1] == FILE_SEPARATOR); } #else if (s[0] == FILE_SEPARATOR) /* / */ { result = true; } #endif return result; } /** * If #path is relative, expand the first part accorting to #shortcuts, doing * any replacements of special variables "$(connection.*)" on the way, with * the provided #ipaddr, #hostname, #key. * * @return the length of the new string or 0 if no replace took place. -1 in * case of overflow. */ size_t ShortcutsExpand(char *path, size_t path_size, const StringMap *shortcuts, const char *ipaddr, const char *hostname, const char *key) { char dst[path_size]; size_t path_len = strlen(path); if (path_len == 0) { UnexpectedError("ShortcutsExpand: 0 length string!"); return (size_t) -1; } if (!PathIsAbsolute(path)) { char *separ = strchr(path, FILE_SEPARATOR); size_t first_part_len; if (separ != NULL) { first_part_len = separ - path; assert(first_part_len < path_len); } else { first_part_len = path_len; } size_t second_part_len = path_len - first_part_len; /* '\0'-terminate first_part, do StringMapGet(), undo '\0'-term */ char separ_char = path[first_part_len]; path[first_part_len] = '\0'; char *replacement = StringMapGet(shortcuts, path); path[first_part_len] = separ_char; /* Either the first_part ends with separator, or its all the string */ assert(separ_char == FILE_SEPARATOR || separ_char == '\0'); if (replacement != NULL) /* we found a shortcut */ { size_t replacement_len = strlen(replacement); if (replacement_len + 1 > path_size) { goto err_too_long; } /* Replacement path for shortcut was found, but it may contain * special variables such as $(connection.ip), that we also need * to expand. */ /* TODO if StrAnyStr(replacement, "$(connection.ip)", "$(connection.hostname)", "$(connection.key)") */ char replacement_expanded[path_size]; memcpy(replacement_expanded, replacement, replacement_len + 1); size_t ret = ReplaceSpecialVariables(replacement_expanded, sizeof(replacement_expanded), "$(connection.ip)", ipaddr, "$(connection.hostname)", hostname, "$(connection.key)", key); size_t replacement_expanded_len; /* (ret == -1) is checked later. */ if (ret == 0) /* No expansion took place */ { replacement_expanded_len = replacement_len; } else { replacement_expanded_len = ret; } size_t dst_len = replacement_expanded_len + second_part_len; if (ret == (size_t) -1 || dst_len + 1 > path_size) { goto err_too_long; } /* Assemble final result. */ memcpy(dst, replacement_expanded, replacement_expanded_len); /* Second part may be empty, then this only copies '\0'. */ memcpy(&dst[replacement_expanded_len], &path[first_part_len], second_part_len + 1); Log(LOG_LEVEL_DEBUG, "ShortcutsExpand: Path '%s' became: %s", path, dst); /* Copy back to path. */ memcpy(path, dst, dst_len + 1); return dst_len; } } /* No expansion took place, either because path was absolute, or because * no shortcut was found. */ return 0; err_too_long: Log(LOG_LEVEL_INFO, "Path too long after shortcut expansion!"); return (size_t) -1; } /** * Canonicalize a path, ensure it is absolute, and resolve all symlinks. * In detail: * * 1. MinGW: Translate to windows-compatible: slashes to FILE_SEPARATOR * and uppercase to lowercase. * 2. Ensure the path is absolute. * 3. Resolve symlinks, resolve '.' and '..' and remove double '/' * WARNING this will currently fail if file does not exist, * returning -1 and setting errno==ENOENT! * * @note trailing slash is left as is if it's there. * @note #reqpath is written in place (if success was returned). It is always * an absolute path. * @note #reqpath is invalid to be of zero length. * @note #reqpath_size must be at least PATH_MAX. * * @return the length of #reqpath after preprocessing. In case of error * return (size_t) -1. */ size_t PreprocessRequestPath(char *reqpath, size_t reqpath_size) { errno = 0; /* on return, errno might be set from realpath() */ char dst[reqpath_size]; size_t reqpath_len = strlen(reqpath); if (reqpath_len == 0) { UnexpectedError("PreprocessRequestPath: 0 length string!"); return (size_t) -1; } /* Translate all slashes to backslashes on Windows so that all the rest * of work is done using FILE_SEPARATOR. THIS HAS TO BE FIRST. */ #if defined(__MINGW32__) { char *p = reqpath; while ((p = strchr(p, '/')) != NULL) { *p = FILE_SEPARATOR; } /* Also convert everything to lowercase. */ ToLowerStrInplace(reqpath); } #endif if (!PathIsAbsolute(reqpath)) { Log(LOG_LEVEL_INFO, "Relative paths are not allowed: %s", reqpath); return (size_t) -1; } /* TODO replace realpath with Solaris' resolvepath(), in all * platforms. That one does not check for existence, just resolves * symlinks and canonicalises. Ideally we would want the following: * * PathResolve(dst, src, dst_size, basedir); * * - It prepends basedir if path relative (could be the shortcut) * - It compresses double '/', '..', '.' * - It follows each component of the path replacing symlinks * - errno = ENOENT if path component does not exist, but keeps * compressing path anyway. * - Leaves trailing slash as it was passed to it. * OR appends it depending on last component ISDIR. */ assert(sizeof(dst) >= PATH_MAX); /* needed for realpath() */ char *p = realpath(reqpath, dst); if (p == NULL) { /* TODO If path does not exist try to canonicalise only directory. INSECURE?*/ /* if (errno == ENOENT) */ /* { */ /* } */ struct stat statbuf; if ((lstat(reqpath, &statbuf) == 0) && S_ISLNK(statbuf.st_mode)) { Log(LOG_LEVEL_VERBOSE, "Requested file is a dead symbolic link (filename: %s)", reqpath); strlcpy(dst, reqpath, CF_BUFSIZE); } else { Log(LOG_LEVEL_INFO, "Failed to canonicalise filename '%s' (realpath: %s)", reqpath, GetErrorStr()); return (size_t) -1; } } size_t dst_len = strlen(dst); /* Some realpath()s remove trailing '/' even for dirs! Put it back if * original request had it. */ if (reqpath[reqpath_len - 1] == FILE_SEPARATOR && dst[dst_len - 1] != FILE_SEPARATOR) { if (dst_len + 2 > sizeof(dst)) { Log(LOG_LEVEL_INFO, "Error, path too long: %s", reqpath); return (size_t) -1; } PathAppendTrailingSlash(dst, dst_len); dst_len++; } memcpy(reqpath, dst, dst_len + 1); reqpath_len = dst_len; return reqpath_len; } /** * Set conn->uid (and conn->sid on Windows). */ void SetConnIdentity(ServerConnectionState *conn, const char *username) { size_t username_len = strlen(username); conn->uid = CF_UNKNOWN_OWNER; conn->username[0] = '\0'; if (username_len < sizeof(conn->username)) { memcpy(conn->username, username, username_len + 1); } bool is_root = strcmp(conn->username, "root") == 0; if (is_root) { /* If the remote user identifies himself as root, even on Windows * cf-serverd must grant access to all files. uid==0 is checked later * in TranferRights() for that. */ conn->uid = 0; } #ifdef __MINGW32__ /* NT uses security identifier instead of uid */ if (!NovaWin_UserNameToSid(conn->username, (SID *) conn->sid, CF_MAXSIDSIZE, !is_root)) { memset(conn->sid, 0, CF_MAXSIDSIZE); /* is invalid sid - discarded */ } #else /* UNIX - common path */ if (conn->uid == CF_UNKNOWN_OWNER) /* skip looking up UID for root */ { static pthread_mutex_t pwnam_mtx = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; ThreadLock(&pwnam_mtx); /* TODO Redmine#7643: looking up the UID is expensive and should * not be needed, since today's agent machine VS hub most probably * do not share the accounts. */ GetUserID(conn->username, &(conn->uid), LOG_LEVEL_VERBOSE); ThreadUnlock(&pwnam_mtx); } #endif } static bool CharsetAcceptable(const char *s, size_t s_len) { const char *ACCEPT = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:"; size_t acceptable_chars = strspn(s, ACCEPT); if (s_len == 0) { s_len = strlen(s); } if (acceptable_chars < s_len) { Log(LOG_LEVEL_INFO, "llegal character in column %zu of: %s", acceptable_chars, s); return false; } return true; } /** * @param #args_start is a comma separated list of words, which may be * prefixed with spaces and suffixed with spaces and other * words. Example: " asd,fgh,jk blah". In this example the * list has 3 words, and "blah" is not one of them. * * Both #args_start and #args_len are in-out parameters. * At the end of execution #args_start returns the real start of the list, and * #args_len the real length. */ static bool AuthorizeDelimitedArgs(const ServerConnectionState *conn, struct acl *acl, char **args_start, size_t *args_len) { char *s; size_t s_len, skip; assert(args_start != NULL); assert(args_len != NULL); /* Give the name s and s_len purely for ease of use. */ s_len = *args_len; s = *args_start; /* Skip spaces in the beginning of argument list. */ skip = strspn(s, " \t"); s += skip; if (s_len == 0) /* if end was not given, find it */ { s_len = strcspn(s, " \t"); } else /* if end was given */ { s_len = (skip <= s_len) ? (s_len - skip) : 0; } /* Admit, unless any token fails to be authorised. */ bool admit = true; if (s_len > 0) { const char tmp_c = s[s_len]; s[s_len] = '\0'; /* Iterate over comma-separated list. */ char *token = &s[0]; while (token < &s[s_len] && admit) { char *token_end = strchrnul(token, ','); const char tmp_sep = *token_end; *token_end = '\0'; if (!CharsetAcceptable(token, 0) || !acl_CheckRegex(acl, token, conn->ipaddr, conn->revdns, KeyPrintableHash(conn->conn_info->remote_key), conn->username)) { Log(LOG_LEVEL_INFO, "Access denied to: %s", token); admit = false; /* EARLY RETURN */ } *token_end = tmp_sep; token = token_end + 1; } s[s_len] = tmp_c; } *args_start = s; *args_len = s_len; return admit; } /** * @return #true if the connection should remain open for next requests, or * #false if the server should actively close it - for example when * protocol errors have occurred. */ bool DoExec2(const EvalContext *ctx, ServerConnectionState *conn, char *exec_args, char *sendbuf, size_t sendbuf_size) { assert(conn != NULL); /* STEP 0: Verify cfruncommand was successfully configured. */ if (NULL_OR_EMPTY(CFRUNCOMMAND)) { Log(LOG_LEVEL_INFO, "EXEC denied due to empty cfruncommand"); RefuseAccess(conn, "EXEC"); return false; } /* STEP 1: Resolve and check permissions of CFRUNCOMMAND's arg0. IT is * done now and not at configuration time, as the file stat may * have changed since then. */ { char arg0[PATH_MAX]; if (CommandArg0_bound(arg0, CFRUNCOMMAND, sizeof(arg0)) == (size_t) -1 || PreprocessRequestPath(arg0, sizeof(arg0)) == (size_t) -1) { Log(LOG_LEVEL_INFO, "EXEC failed, invalid cfruncommand arg0"); RefuseAccess(conn, "EXEC"); return false; } /* Check body server access_rules, whether arg0 is authorized. */ /* TODO EXEC should not just use paths_acl access control, but * specific "exec_path" ACL. Then different command execution could be * allowed per host, and the host could even set argv[0] in his EXEC * request, rather than only the arguments. */ if (acl_CheckPath(paths_acl, arg0, conn->ipaddr, conn->revdns, KeyPrintableHash(conn->conn_info->remote_key)) == false) { Log(LOG_LEVEL_INFO, "EXEC denied due to ACL for file: %s", arg0); RefuseAccess(conn, "EXEC"); return false; } } /* STEP 2: Check body server control "allowusers" */ if (!AllowedUser(conn->username)) { Log(LOG_LEVEL_INFO, "EXEC denied due to not allowed user: %s", conn->username); RefuseAccess(conn, "EXEC"); return false; } /* STEP 3: This matches cf-runagent -s class1,class2 against classes * set during cf-serverd's policy evaluation. */ if (!MatchClasses(ctx, conn)) { snprintf(sendbuf, sendbuf_size, "EXEC denied due to failed class match (check cf-serverd verbose output)"); Log(LOG_LEVEL_INFO, "%s", sendbuf); SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE); return true; } /* STEP 4: Parse and authorise the EXEC arguments, which will be used as * arguments to CFRUNCOMMAND. Currently we only accept * [ -D classlist ] and [ -b bundlesequence ] arguments. */ char cmdbuf[CF_BUFSIZE] = ""; size_t cmdbuf_len = 0; nt_static_assert(sizeof(CFRUNCOMMAND) <= sizeof(cmdbuf)); StrCat(cmdbuf, sizeof(cmdbuf), &cmdbuf_len, CFRUNCOMMAND, 0); exec_args += strspn(exec_args, " \t"); /* skip spaces */ while (exec_args[0] != '\0') { if (strncmp(exec_args, "-D", 2) == 0) { exec_args += 2; char *classlist = exec_args; size_t classlist_len = 0; bool allow = AuthorizeDelimitedArgs(conn, roles_acl, &classlist, &classlist_len); if (!allow) { snprintf(sendbuf, sendbuf_size, "EXEC denied role activation (check cf-serverd verbose output)"); Log(LOG_LEVEL_INFO, "%s", sendbuf); SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE); return true; } if (classlist_len > 0) { /* Append "-D classlist" to cfruncommand. */ StrCat(cmdbuf, sizeof(cmdbuf), &cmdbuf_len, " -D ", 0); StrCat(cmdbuf, sizeof(cmdbuf), &cmdbuf_len, classlist, classlist_len); } exec_args = classlist + classlist_len; } else if (strncmp(exec_args, "-b", 2) == 0) { exec_args += 2; char *bundlesequence = exec_args; size_t bundlesequence_len = 0; bool allow = AuthorizeDelimitedArgs(conn, bundles_acl, &bundlesequence, &bundlesequence_len); if (!allow) { snprintf(sendbuf, sendbuf_size, "EXEC denied bundle activation (check cf-serverd verbose output)"); Log(LOG_LEVEL_INFO, "%s", sendbuf); SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE); return true; } if (bundlesequence_len > 0) { /* Append "--bundlesequence bundlesequence" to cfruncommand. */ StrCat(cmdbuf, sizeof(cmdbuf), &cmdbuf_len, " --bundlesequence ", 0); StrCat(cmdbuf, sizeof(cmdbuf), &cmdbuf_len, bundlesequence, bundlesequence_len); } exec_args = bundlesequence + bundlesequence_len; } else /* disallowed parameter */ { snprintf(sendbuf, sendbuf_size, "EXEC denied: invalid arguments: %s", exec_args); Log(LOG_LEVEL_INFO, "%s", sendbuf); SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE); return true; } exec_args += strspn(exec_args, " \t"); /* skip spaces */ } if (cmdbuf_len >= sizeof(cmdbuf)) { snprintf(sendbuf, sendbuf_size, "EXEC denied: too long (%zu B) command: %s", cmdbuf_len, cmdbuf); Log(LOG_LEVEL_INFO, "%s", sendbuf); SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE); return false; } /* STEP 5: RUN CFRUNCOMMAND. */ snprintf(sendbuf, sendbuf_size, "cf-serverd executing cfruncommand: %s\n", cmdbuf); SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE); Log(LOG_LEVEL_INFO, "%s", sendbuf); FILE *pp = cf_popen(cmdbuf, "r", true); if (pp == NULL) { snprintf(sendbuf, sendbuf_size, "Unable to run '%s' (pipe: %s)", cmdbuf, GetErrorStr()); Log(LOG_LEVEL_INFO, "%s", sendbuf); SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE); return false; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); while (true) { ssize_t res = CfReadLine(&line, &line_size, pp); if (res == -1) { if (!feof(pp)) { /* Error reading, discard all unconsumed input before * aborting - linux-specific! */ fflush(pp); } break; } /* NOTICE: we can't SendTransaction() overlong strings, and we need to * prepend and append to the string. */ size_t line_len = strlen(line); if (line_len >= sendbuf_size - 5) { line[sendbuf_size - 5] = '\0'; } /* Prefixing output with "> " and postfixing with '\n' is new * behaviour as of 3.7.0. Prefixing happens to avoid zero-length * transaction packet. */ /* Old cf-runagent versions do not append a newline, so we must do * it here. New ones do though, so TODO deprecate. */ xsnprintf(sendbuf, sendbuf_size, "> %s\n", line); if (SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE) == -1) { Log(LOG_LEVEL_INFO, "Sending failed, aborting EXEC (send: %s)", GetErrorStr()); break; } } free(line); int exit_code = cf_pclose(pp); if (exit_code >= 0) { xsnprintf(sendbuf, sendbuf_size, "(exit code: %d)\n", exit_code); if (SendTransaction(conn->conn_info, sendbuf, 0, CF_DONE) == -1) { Log(LOG_LEVEL_INFO, "Failed to send exit code from EXEC agent run"); } } return true; } cfengine-3.24.2/cf-serverd/server_access.c0000644000000000000000000004630215010704253020413 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include "server_access.h" #include "strlist.h" #include "server.h" #include /* FuzzySetMatch */ #include /* StringMatchFull TODO REMOVE */ #include #include #include struct acl *paths_acl; struct acl *classes_acl; struct acl *vars_acl; struct acl *literals_acl; struct acl *query_acl; struct acl *bundles_acl; struct acl *roles_acl; /** * Run this function on every resource (file, class, var etc) access to * grant/deny rights. Currently it checks if: * 1. #ipaddr matches the subnet expression in {admit,deny}_ips * 2. #hostname matches the subdomain expression in {admit,deny}_hostnames * 3. #key is searched as-is in {admit,deny}_keys * 4. #username is searched as-is in {admit,deny}_usernames * * @param #found If not NULL then it returns whether the denial was implicit * (found=false) or explicit (found=true). If not NULL it also * changes the way the ACLs are traversed to a SLOWER mode, * since every entry has to be checked for explicit denial. * * @return Default is false, i.e. deny. If a match is found in #acl->admit.* * then return true, unless a match is also found in #acl->deny.* in * which case return false. * * @TODO preprocess our global ACL the moment a client connects, and store in * ServerConnectionState a list of objects that he can access. That way * only his relevant resources will be stored in e.g. {admit,deny}_paths * lists, and running through these two lists on every file request will * be much faster. */ static bool access_CheckResource(const struct resource_acl *acl, bool *found, const char *ipaddr, const char *hostname, const char *key, const char *username) { bool access = false; /* DENY by default */ bool have_match = false; /* No matching rule found yet */ /* First we check for admission, secondly for denial, so that denial takes * precedence. */ if (!NULL_OR_EMPTY(ipaddr) && acl->admit.ips != NULL) { /* Still using legacy code here, doing linear search over all IPs in * textual representation... too CPU intensive! TODO store the ACL as * one list of struct sockaddr_storage, together with CIDR notation * subnet length. */ const char *rule = NULL; for (size_t i = 0; i < StrList_Len(acl->admit.ips); i++) { if (FuzzySetMatch(StrList_At(acl->admit.ips, i), ipaddr) == 0 || /* Legacy regex matching, TODO DEPRECATE */ StringMatchFull(StrList_At(acl->admit.ips, i), ipaddr)) { rule = StrList_At(acl->admit.ips, i); break; } } if (rule != NULL) { Log(LOG_LEVEL_DEBUG, "Admit IP due to rule: %s", rule); access = true; have_match = true; } } if (!access && !NULL_OR_EMPTY(hostname) && acl->admit.hostnames != NULL) { size_t pos = StrList_SearchLongestPrefix(acl->admit.hostnames, hostname, 0, '.', false); /* === Legacy regex matching, slow, TODO DEPRECATE === */ if (pos == (size_t) -1) { for (size_t i = 0; i < StrList_Len(acl->admit.hostnames); i++) { if (StringMatchFull(StrList_At(acl->admit.hostnames, i), hostname)) { pos = i; break; } } } /* =================================================== */ if (pos != (size_t) -1) { Log(LOG_LEVEL_DEBUG, "Admit hostname due to rule: %s", StrList_At(acl->admit.hostnames, pos)); access = true; have_match = true; } else { Log(LOG_LEVEL_VERBOSE, "Hostname '%s' not admitted", hostname); } } if (!access && !NULL_OR_EMPTY(key) && acl->admit.keys != NULL) { size_t pos; bool ret = StrList_BinarySearch(acl->admit.keys, key, &pos); if (ret) { Log(LOG_LEVEL_DEBUG, "Admit key due to rule: %s", StrList_At(acl->admit.keys, pos)); access = true; have_match = true; } } if (!access && !NULL_OR_EMPTY(username) && acl->admit.usernames != NULL) { size_t pos; bool ret = StrList_BinarySearch(acl->admit.usernames, username, &pos); if (ret) { Log(LOG_LEVEL_DEBUG, "Admit username due to rule: %s", StrList_At(acl->admit.usernames, pos)); access = true; have_match = true; } } /* An admit rule was not found, and we don't care whether the denial is * explicit or implicit: we can finish now. */ if (!access && found == NULL) { assert(!have_match); return false; /* EARLY RETURN! */ } /* If access has been granted, we might need to deny it based on ACL. */ /* Same goes if access has not been granted and "found" is not NULL, in * which case we have to return in "found", whether an explicit denial * rule matched or not. */ assert((access && have_match) || (!access && !have_match && found != NULL)); if ((access || !have_match) && !NULL_OR_EMPTY(ipaddr) && acl->deny.ips != NULL) { const char *rule = NULL; for (size_t i = 0; i < StrList_Len(acl->deny.ips); i++) { if (FuzzySetMatch(StrList_At(acl->deny.ips, i), ipaddr) == 0 || /* Legacy regex matching, TODO DEPRECATE */ StringMatchFull(StrList_At(acl->deny.ips, i), ipaddr)) { rule = StrList_At(acl->deny.ips, i); break; } } if (rule != NULL) { Log(LOG_LEVEL_DEBUG, "Deny IP due to rule: %s", rule); access = false; have_match = true; } } if ((access || !have_match) && !NULL_OR_EMPTY(hostname) && acl->deny.hostnames != NULL) { size_t pos = StrList_SearchLongestPrefix(acl->deny.hostnames, hostname, 0, '.', false); /* === Legacy regex matching, slow, TODO DEPRECATE === */ if (pos == (size_t) -1) { for (size_t i = 0; i < StrList_Len(acl->deny.hostnames); i++) { if (StringMatchFull(StrList_At(acl->deny.hostnames, i), hostname)) { pos = i; break; } } } /* =================================================== */ if (pos != (size_t) -1) { Log(LOG_LEVEL_DEBUG, "Deny hostname due to rule: %s", StrList_At(acl->deny.hostnames, pos)); access = false; have_match = true; } } if ((access || !have_match) && !NULL_OR_EMPTY(key) && acl->deny.keys != NULL) { size_t pos; bool ret = StrList_BinarySearch(acl->deny.keys, key, &pos); if (ret) { Log(LOG_LEVEL_DEBUG, "Deny key due to rule: %s", StrList_At(acl->deny.keys, pos)); access = false; have_match = true; } } if ((access || !have_match) && !NULL_OR_EMPTY(username) && acl->deny.usernames != NULL) { size_t pos; bool ret = StrList_BinarySearch(acl->deny.usernames, username, &pos); if (ret) { Log(LOG_LEVEL_DEBUG, "Deny username due to rule: %s", StrList_At(acl->deny.usernames, pos)); access = false; have_match = true; } } /* We can't have implicit admittance, admittance must always be explicit. */ assert(! (access && !have_match)); if (found != NULL) { *found = have_match; } return access; } /** * Search #req_path in #acl, if found check its rules. The longest parent * directory of #req_path is searched, or an exact match. Directories *must* * end with FILE_SEPARATOR in the ACL list. * * @return If ACL entry is found, and host is listed in there return * true. Else return false. */ bool acl_CheckPath(const struct acl *acl, const char *reqpath, const char *ipaddr, const char *hostname, const char *key) { bool access = false; /* Deny access by default */ size_t reqpath_len = strlen(reqpath); /* CHECK 1: Search for parent directory or exact entry in ACL. */ size_t pos = StrList_SearchLongestPrefix(acl->resource_names, reqpath, reqpath_len, FILE_SEPARATOR, true); if (pos != (size_t) -1) /* acl entry was found */ { const struct resource_acl *racl = &acl->acls[pos]; bool ret = access_CheckResource(racl, NULL, ipaddr, hostname, key, NULL); if (ret == true) /* entry found that grants access */ { access = true; } Log(LOG_LEVEL_DEBUG, "acl_CheckPath: '%s' found in ACL entry '%s', admit=%s", reqpath, acl->resource_names->list[pos]->str, ret == true ? "true" : "false"); } /* CHECK 2: replace ACL entry parts with special variables (if applicable), * e.g. turn "/path/to/192.168.1.1.json" * to "/path/to/$(connection.ip).json" */ char mangled_path[PATH_MAX]; memcpy(mangled_path, reqpath, reqpath_len + 1); size_t mangled_path_len = ReplaceSpecialVariables(mangled_path, sizeof(mangled_path), ipaddr, "$(connection.ip)", hostname, "$(connection.hostname)", key, "$(connection.key)"); /* If there were special variables replaced */ if (mangled_path_len != 0 && mangled_path_len != (size_t) -1) /* Overflow, TODO handle separately. */ { size_t pos2 = StrList_SearchLongestPrefix(acl->resource_names, mangled_path, mangled_path_len, FILE_SEPARATOR, true); if (pos2 != (size_t) -1) /* acl entry was found */ { /* TODO make sure this match is more specific than the other one. */ const struct resource_acl *racl = &acl->acls[pos2]; /* Check if the magic strings are allowed or denied. */ bool ret = access_CheckResource(racl, NULL, "$(connection.ip)", "$(connection.hostname)", "$(connection.key)", NULL); if (ret == true) /* entry found that grants access */ { access = true; } Log(LOG_LEVEL_DEBUG, "acl_CheckPath: '%s' found in ACL entry '%s', admit=%s", mangled_path, acl->resource_names->list[pos2]->str, ret == true ? "true" : "false"); } } return access; } bool acl_CheckExact(const struct acl *acl, const char *req_string, const char *ipaddr, const char *hostname, const char *key) { bool access = false; size_t pos = -1; bool found = StrList_BinarySearch(acl->resource_names, req_string, &pos); if (found) { const struct resource_acl *racl = &acl->acls[pos]; bool ret = access_CheckResource(racl, NULL, ipaddr, hostname, key, NULL); if (ret == true) /* entry found that grants access */ { access = true; } } return access; } /** * Go linearly over all the #acl and check every rule if it matches. * ADMIT only if at least one rule matches admit and none matches deny. * DENY if no rule matches OR if at least one matches deny. */ bool acl_CheckRegex(const struct acl *acl, const char *req_string, const char *ipaddr, const char *hostname, const char *key, const char *username) { bool retval = false; /* For all ACLs */ for (size_t i = 0; i < acl->len; i++) { const char *regex = acl->resource_names->list[i]->str; /* Does this ACL matches the req_string? */ if (StringMatchFull(regex, req_string)) { const struct resource_acl *racl = &acl->acls[i]; /* Does this ACL apply to this host? */ bool found; bool admit = access_CheckResource(racl, &found, ipaddr, hostname, key, username); if (found && !admit) { return false; } else if (found && admit) { retval = true; } else { /* If it's not found, there should be no admittance. */ assert(!found); assert(!admit); /* We are not touching retval, because it was possibly found * before and retval has been set to "true". */ } } } return retval; } /** * Search the list of resources for the handle. If found return the index of * the resource ACL that corresponds to that handle, else add the handle with * empty ACL, reallocating if necessary. The new handle is inserted in the * proper position to keep the acl->resource_names list sorted. * * @note acl->resource_names list should already be sorted, no problem if all * inserts are done with this function. * * @return the index of the resource_acl corresponding to handle. -1 means * reallocation failed, but existing values are still valid. */ size_t acl_SortedInsert(struct acl **a, const char *handle) { assert(handle != NULL); struct acl *acl = *a; /* for clarity */ size_t position = (size_t) -1; bool found = StrList_BinarySearch(acl->resource_names, handle, &position); if (found) { /* Found it, return existing entry. */ assert(position < acl->len); return position; } /* handle is not in acl, we must insert at the position returned. */ assert(position <= acl->len); /* 1. Check if reallocation is needed. */ if (acl->len == acl->alloc_len) { size_t new_alloc_len = acl->alloc_len * 2; if (new_alloc_len == 0) { new_alloc_len = 1; } struct acl *p = realloc(acl, sizeof(*p) + sizeof(*p->acls) * new_alloc_len); if (p == NULL) { return (size_t) -1; } acl = p; acl->alloc_len = new_alloc_len; *a = acl; /* Change the caller's variable */ } /* 2. We now have enough space, so insert the resource at the proper index. */ size_t ret = StrList_Insert(&acl->resource_names, handle, position); if (ret == (size_t) -1) { /* realloc() failed but the data structure is still valid. */ return (size_t) -1; } /* 3. Make room. */ memmove(&acl->acls[position + 1], &acl->acls[position], (acl->len - position) * sizeof(acl->acls[position])); acl->len++; /* 4. Initialise all ACLs for the resource as empty. */ acl->acls[position] = (struct resource_acl) { {0}, {0} }; /* NULL acls <=> empty */ Log(LOG_LEVEL_DEBUG, "Inserted in ACL position %zu: %s", position, handle); assert(acl->len == StrList_Len(acl->resource_names)); return position; } void acl_Free(struct acl *a) { StrList_Free(&a->resource_names); size_t i; for (i = 0; i < a->len; i++) { StrList_Free(&a->acls[i].admit.ips); StrList_Free(&a->acls[i].admit.hostnames); StrList_Free(&a->acls[i].admit.usernames); StrList_Free(&a->acls[i].admit.keys); StrList_Free(&a->acls[i].deny.ips); StrList_Free(&a->acls[i].deny.hostnames); StrList_Free(&a->acls[i].deny.keys); } free(a); } void acl_Summarise(const struct acl *acl, const char *title) { assert(acl->len == StrList_Len(acl->resource_names)); size_t i, j; for (i = 0; i < acl->len; i++) { Log(LOG_LEVEL_VERBOSE, "\t%s: %s", title, StrList_At(acl->resource_names, i)); const struct resource_acl *racl = &acl->acls[i]; for (j = 0; j < StrList_Len(racl->admit.ips); j++) { Log(LOG_LEVEL_VERBOSE, "\t\tadmit_ips: %s", StrList_At(racl->admit.ips, j)); } for (j = 0; j < StrList_Len(racl->admit.hostnames); j++) { Log(LOG_LEVEL_VERBOSE, "\t\tadmit_hostnames: %s", StrList_At(racl->admit.hostnames, j)); } for (j = 0; j < StrList_Len(racl->admit.keys); j++) { Log(LOG_LEVEL_VERBOSE, "\t\tadmit_keys: %s", StrList_At(racl->admit.keys, j)); } for (j = 0; j < StrList_Len(racl->deny.ips); j++) { Log(LOG_LEVEL_VERBOSE, "\t\tdeny_ips: %s", StrList_At(racl->deny.ips, j)); } for (j = 0; j < StrList_Len(racl->deny.hostnames); j++) { Log(LOG_LEVEL_VERBOSE, "\t\tdeny_hostnames: %s", StrList_At(racl->deny.hostnames, j)); } for (j = 0; j < StrList_Len(racl->deny.keys); j++) { Log(LOG_LEVEL_VERBOSE, "\t\tdeny_keys: %s", StrList_At(racl->deny.keys, j)); } } } cfengine-3.24.2/cf-serverd/server_tls.c0000644000000000000000000011006615010704253017753 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include // ParseProtocolVersionNetwork() #include /* ERR_get_error */ #include /* DecryptString */ #include #include #include /* IsMatchItemIn */ #include /* LastSaw1 */ #include /* SendTransaction,ReceiveTransaction */ #include /* TLSSend */ #include #include #include /* StringMatchFull */ #include #include /* IsDirReal */ #include "server_access.h" /* access_CheckResource, acl_CheckExact */ static SSL_CTX *SSLSERVERCONTEXT = NULL; #define MAX_ACCEPT_RETRIES 5 /** * @param[in] priv_key private key to use (or %NULL to use the global PRIVKEY) * @param[in] pub_key public key to use (or %NULL to use the global PUBKEY) * @param[out] ssl_ctx place to store the SSL context (or %NULL to use the * global SSL_CTX) * @warning Make sure you've called CryptoInitialize() first! */ bool ServerTLSInitialize(RSA *priv_key, RSA *pub_key, SSL_CTX **ssl_ctx) { int ret; if (priv_key == NULL) { /* private key not specified, use the global one */ priv_key = PRIVKEY; } if (pub_key == NULL) { /* public key not specified, use the global one */ pub_key = PUBKEY; } if (priv_key == NULL || pub_key == NULL) { Log(LOG_LEVEL_ERR, "Public/private key pair not loaded," " please create one using cf-key"); return false; } if (!TLSGenericInitialize()) { return false; } if (ssl_ctx == NULL) { ssl_ctx = &SSLSERVERCONTEXT; } assert(*ssl_ctx == NULL); *ssl_ctx = SSL_CTX_new(SSLv23_server_method()); if (*ssl_ctx == NULL) { Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s", TLSErrorString(ERR_get_error())); return false; } TLSSetDefaultOptions(*ssl_ctx, SERVER_ACCESS.allowtlsversion); /* * CFEngine is not a web server so it does not need to support many * ciphers. It only allows a safe but very common subset by default, * extensible via "allowciphers" in body server control. By default * the server side allows: * * AES256-GCM-SHA384: most high-grade RSA-based cipher from TLSv1.2 * AES256-SHA: most backwards compatible but high-grade, from SSLv3 * TLS_AES_256_GCM_SHA384: most high-grade RSA-based cipher from TLSv1.3 * * Client side is using the OpenSSL's defaults by default. */ const char *cipher_list = SERVER_ACCESS.allowciphers; if (cipher_list == NULL) { #ifdef SSL_OP_NO_TLSv1_3 /* defined if TLS 1.3 is supported */ cipher_list = "AES256-GCM-SHA384:AES256-SHA:TLS_AES_256_GCM_SHA384"; #else cipher_list = "AES256-GCM-SHA384:AES256-SHA"; #endif } if (!TLSSetCipherList(*ssl_ctx, cipher_list)) { goto err; } /* Create cert into memory and load it into SSL context. */ X509 *cert = TLSGenerateCertFromPrivKey(priv_key); if (cert == NULL) { Log(LOG_LEVEL_ERR, "Failed to generate in-memory certificate from private key"); goto err; } SSL_CTX_use_certificate(*ssl_ctx, cert); X509_free(cert); ret = SSL_CTX_use_RSAPrivateKey(*ssl_ctx, priv_key); if (ret != 1) { Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s", TLSErrorString(ERR_get_error())); goto err; } /* Verify cert consistency. */ ret = SSL_CTX_check_private_key(*ssl_ctx); if (ret != 1) { Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s", TLSErrorString(ERR_get_error())); goto err; } return true; err: SSL_CTX_free(*ssl_ctx); *ssl_ctx = NULL; return false; } /** * @param[in,out] priv_key private key to deinitalize (or %NULL to use the * global PRIVKEY) * @param[in,out] pub_key public key to deinitialize (or %NULL to use the * global PUBKEY) * @param[in,out] ssl_ctx the SSL context to deinitialize (or %NULL to use the * global SSL_CTX) */ void ServerTLSDeInitialize(RSA **priv_key, RSA **pub_key, SSL_CTX **ssl_ctx) { if (priv_key == NULL) { priv_key = &PRIVKEY; } if (pub_key == NULL) { pub_key = &PUBKEY; } if (ssl_ctx == NULL) { ssl_ctx = &SSLSERVERCONTEXT; } if (*pub_key) { RSA_free(*pub_key); *pub_key = NULL; } if (*priv_key) { RSA_free(*priv_key); *priv_key = NULL; } if (*ssl_ctx != NULL) { SSL_CTX_free(*ssl_ctx); *ssl_ctx = NULL; } } /** * @brief Set the connection type to CLASSIC or TLS. * It is performed by peeking into the TLS connection to read the first bytes, * and if it's a CAUTH protocol command use the old protocol loop, else use * the TLS protocol loop. * This must be the first thing we run on an accepted connection. * * @return true for success, false otherwise. */ bool ServerTLSPeek(ConnectionInfo *conn_info) { assert(conn_info != NULL); assert(SSLSERVERCONTEXT != NULL); assert(PRIVKEY != NULL); assert(PUBKEY != NULL); assert(ConnectionInfoProtocolVersion(conn_info) == CF_PROTOCOL_UNDEFINED); const int peek_size = CF_INBAND_OFFSET + sizeof("CAUTH"); char buf[peek_size]; ssize_t got = recv(ConnectionInfoSocket(conn_info), buf, sizeof(buf), MSG_PEEK); assert(got <= peek_size); if (got < 0) { assert(got == -1); Log(LOG_LEVEL_ERR, "TCP receive error: %s", GetErrorStr()); return false; } else if (got == 0) { Log(LOG_LEVEL_INFO, "Peer closed TCP connection without sending data!"); return false; } else if (got < peek_size) { Log(LOG_LEVEL_INFO, "Peer sent only %zd bytes! Considering the protocol as Classic", got); ConnectionInfoSetProtocolVersion(conn_info, CF_PROTOCOL_CLASSIC); } else if (memcmp(&buf[CF_INBAND_OFFSET], "CAUTH", strlen("CAUTH")) == 0) { Log(LOG_LEVEL_VERBOSE, "Peeked CAUTH in TCP stream, considering the protocol as Classic"); ConnectionInfoSetProtocolVersion(conn_info, CF_PROTOCOL_CLASSIC); } else /* got==peek_size && not "CAUTH" */ { Log(LOG_LEVEL_VERBOSE, "Peeked nothing important in TCP stream, considering the protocol as TLS"); ConnectionInfoSetProtocolVersion(conn_info, CF_PROTOCOL_TLS); } LogRaw(LOG_LEVEL_DEBUG, "Peeked data: ", buf, got); return true; } /** * 1. Send "CFE_v%d" server hello. * 2. Receive two lines: One "CFE_v%d" with the protocol version the client * wishes to have, and one "IDENTITY USERNAME=blah ..." with identification * information for the client. * * @note For Identification dialog to end successfully, one "OK WELCOME" line * must be sent right after this function, after identity is verified. * * @TODO More protocol identity. E.g. * IDENTITY USERNAME=xxx HOSTNAME=xxx CUSTOMNAME=xxx * * @retval true if protocol version was successfully negotiated and IDENTITY * command was parsed correctly. Identity fields (only #username for * now) have the respective string values, or they are empty if field * was not on IDENTITY line. #conn_info->protocol has been updated * with the negotiated protocol version. * @retval false in case of error. */ bool ServerIdentificationDialog(ConnectionInfo *conn_info, char *username, size_t username_size) { int ret; char input[1024] = ""; /* Send "CFE_v%d cf-serverd version". */ char version_string[CF_MAXVARSIZE]; int len = snprintf(version_string, sizeof(version_string), "CFE_v%d cf-serverd %s\n", CF_PROTOCOL_LATEST, VERSION); ret = TLSSend(conn_info->ssl, version_string, len); if (ret != len) { Log(LOG_LEVEL_NOTICE, "Connection was hung up!"); return false; } /* Receive CFE_v%d ... \n IDENTITY USERNAME=... */ int input_len = TLSRecvLines(conn_info->ssl, input, sizeof(input)); if (input_len <= 0) { Log(LOG_LEVEL_NOTICE, "Client closed connection early! He probably does not trust our key..."); return false; } const ProtocolVersion protocol = ParseProtocolVersionNetwork(input); if (ProtocolIsUndefined(protocol)) { Log(LOG_LEVEL_NOTICE, "Protocol version negotiation failed! Received: %s", input); return false; } /* This is already inside TLS code, so TLS is required at this point*/ if (ProtocolIsClassic(protocol)) { Log(LOG_LEVEL_NOTICE, "Client advertises disallowed protocol version: %d", protocol); return false; } if (ProtocolIsTooNew(protocol)) { Log(LOG_LEVEL_NOTICE, "Client attempted a protocol version which is too new for us: %d", protocol); return false; } assert(ProtocolIsKnown(protocol)); /* Did we receive 2nd line or do we need to receive again? */ const char id_line[] = "\nIDENTITY "; char *line2 = memmem(input, input_len, id_line, strlen(id_line)); if (line2 == NULL) { /* Wait for 2nd line to arrive. */ input_len = TLSRecvLines(conn_info->ssl, input, sizeof(input)); if (input_len <= 0) { Log(LOG_LEVEL_NOTICE, "Client closed connection during identification dialog!"); return false; } line2 = input; } else { line2++; /* skip '\n' */ } /***** Parse all IDENTITY fields from line2 *****/ char word1[1024], word2[1024]; int line2_pos = 0, chars_read = 0; /* Reset all identity variables, we'll set them according to fields * on IDENTITY line. For now only "username" setting exists... */ username[0] = '\0'; /* Assert sscanf() is safe to use. */ nt_static_assert(sizeof(word1) >= sizeof(input)); nt_static_assert(sizeof(word2) >= sizeof(input)); ret = sscanf(line2, "IDENTITY %[^=]=%s%n", word1, word2, &chars_read); while (ret >= 2) { /* Found USERNAME identity setting */ if (strcmp(word1, "USERNAME") == 0) { if ((strlen(word2) < username_size) && (IsUserNameValid(word2) == true)) { strcpy(username, word2); } else { Log(LOG_LEVEL_NOTICE, "Received invalid IDENTITY: %s=%s", word1, word2); return false; } Log(LOG_LEVEL_VERBOSE, "Setting IDENTITY: %s=%s", word1, word2); } /* ... else if (strcmp()) for other acceptable IDENTITY parameters. */ else { Log(LOG_LEVEL_VERBOSE, "Received unknown IDENTITY parameter: %s=%s", word1, word2); } line2_pos += chars_read; ret = sscanf(&line2[line2_pos], " %[^=]=%s%n", word1, word2, &chars_read); } /* Version client and server agreed on. */ assert(ProtocolIsKnown(protocol)); conn_info->protocol = protocol; return true; } bool ServerSendWelcome(const ServerConnectionState *conn) { char s[1024] = "OK WELCOME"; size_t len = strlen(s); int ret; /* "OK WELCOME" is the important part. The rest is just extra verbosity. */ if (conn->username[0] != '\0') { ret = snprintf(&s[len], sizeof(s) - len, " %s=%s", "USERNAME", conn->username); if (ret < 0) { Log(LOG_LEVEL_ERR, "Unexpected failure from snprintf (%d - %s) while " "constructing OK WELCOME message (ServerSendWelcome)", errno, GetErrorStr()); return false; } else if ((size_t) ret >= sizeof(s) - len) { Log(LOG_LEVEL_NOTICE, "Sending OK WELCOME message truncated: %s", s); return false; } len += ret; } /* Overwrite the terminating '\0', we don't need it anyway. */ s[len] = '\n'; len++; ret = TLSSend(conn->conn_info->ssl, s, len); if (ret == -1) { return false; } return true; } /** * @brief Accept a TLS connection and authenticate and identify. * * Doesn't include code for verifying key and lastseen * * @param conn connection state * @param ssl_ctx SSL context to use for the session (or %NULL to use the * default SSLSERVERCONTEXT) * * @see ServerTLSSessionEstablish * @return true for success false otherwise */ bool BasicServerTLSSessionEstablish(ServerConnectionState *conn, SSL_CTX *ssl_ctx) { if (conn->conn_info->status == CONNECTIONINFO_STATUS_ESTABLISHED) { return true; } if (ssl_ctx == NULL) { ssl_ctx = SSLSERVERCONTEXT; } assert(ConnectionInfoSSL(conn->conn_info) == NULL); SSL *ssl = SSL_new(ssl_ctx); if (ssl == NULL) { Log(LOG_LEVEL_ERR, "SSL_new: %s", TLSErrorString(ERR_get_error())); return false; } ConnectionInfoSetSSL(conn->conn_info, ssl); /* Pass conn_info inside the ssl struct for TLSVerifyCallback(). */ SSL_set_ex_data(ssl, CONNECTIONINFO_SSL_IDX, conn->conn_info); /* Now we are letting OpenSSL take over the open socket. */ SSL_set_fd(ssl, ConnectionInfoSocket(conn->conn_info)); int remaining_tries = MAX_ACCEPT_RETRIES; int ret = -1; bool should_retry = true; while ((ret < 0) && should_retry) { ret = SSL_accept(ssl); if (ret < 0) { int code = TLSLogError(ssl, LOG_LEVEL_VERBOSE, "SSL accept failed", ret); should_retry = ((remaining_tries > 0) && ((code == SSL_ERROR_WANT_READ) || (code == SSL_ERROR_WANT_WRITE))); } if ((ret < 0) && should_retry) { sleep(1); remaining_tries--; } } if (ret <= 0) { TLSLogError(ssl, LOG_LEVEL_ERR, "Failed to accept TLS connection", ret); return false; } Log(LOG_LEVEL_VERBOSE, "TLS version negotiated: %8s; Cipher: %s,%s", SSL_get_version(ssl), SSL_get_cipher_name(ssl), SSL_get_cipher_version(ssl)); return true; } /** * @brief Accept a TLS connection and authenticate and identify. * * This function uses trustkeys to trust new keys and updates lastseen * * @param conn connection state * @param ssl_ctx SSL context to use for the session (or %NULL to use the * default SSLSERVERCONTEXT) * * @see BasicServerTLSSessionEstablish * @note Various fields in #conn are set, like username and keyhash. * @return true for success false otherwise */ bool ServerTLSSessionEstablish(ServerConnectionState *conn, SSL_CTX *ssl_ctx) { if (conn->conn_info->status == CONNECTIONINFO_STATUS_ESTABLISHED) { return true; } bool established = BasicServerTLSSessionEstablish(conn, ssl_ctx); if (!established) { return false; } Log(LOG_LEVEL_VERBOSE, "TLS session established, checking trust..."); /* Send/Receive "CFE_v%d" version string, agree on version, receive identity (username) of peer. */ char username[sizeof(conn->username)] = ""; bool id_success = ServerIdentificationDialog(conn->conn_info, username, sizeof(username)); if (!id_success) { return false; } /* We *now* (maybe a bit late) verify the key that the client sent us in * the TLS handshake, since we need the username to do so. TODO in the * future store keys irrelevant of username, so that we can match them * before IDENTIFY. */ int ret = TLSVerifyPeer(conn->conn_info, conn->ipaddr, username); if (ret == -1) /* error */ { return false; } if (ret == 1) /* trusted key */ { Log(LOG_LEVEL_VERBOSE, "%s: Client is TRUSTED, public key MATCHES stored one.", KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); } if (ret == 0) /* untrusted key */ { if ((SERVER_ACCESS.trustkeylist != NULL) && (IsMatchItemIn(SERVER_ACCESS.trustkeylist, conn->ipaddr))) { Log(LOG_LEVEL_VERBOSE, "Peer was found in \"trustkeysfrom\" list"); Log(LOG_LEVEL_NOTICE, "Trusting new key: %s", KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); SavePublicKey(username, KeyPrintableHash(conn->conn_info->remote_key), KeyRSA(ConnectionInfoKey(conn->conn_info))); } else { Log(LOG_LEVEL_NOTICE, "TRUST FAILED, peer presented an untrusted key, dropping connection!"); Log(LOG_LEVEL_VERBOSE, "Add peer to \"trustkeysfrom\" if you really want to start trusting this new key."); return false; } } /* All checks succeeded, set conn->uid (conn->sid for Windows) * according to the received USERNAME identity. */ SetConnIdentity(conn, username); /* No CAUTH, SAUTH in non-classic protocol. */ conn->user_data_set = true; conn->rsa_auth = true; LastSaw1(conn->ipaddr, KeyPrintableHash(ConnectionInfoKey(conn->conn_info)), LAST_SEEN_ROLE_ACCEPT); ServerSendWelcome(conn); return true; } //******************************************************************* // COMMANDS //******************************************************************* ProtocolCommandNew GetCommandNew(char *str) { int i; for (i = 0; PROTOCOL_NEW[i] != NULL; i++) { int cmdlen = strlen(PROTOCOL_NEW[i]); if ((strncmp(str, PROTOCOL_NEW[i], cmdlen) == 0) && (str[cmdlen] == ' ' || str[cmdlen] == '\0')) { return i; } } assert (i == PROTOCOL_COMMAND_BAD); return i; } /** * Currently this function returns false when we want the connection * closed, and true, when we want to proceed further with requests. * * @TODO So we need this function to return more than true/false, because now * we return true even when access is denied! E.g. return -1 for error, 0 on * success, 1 on access denied. It can be an option if connection will close * on denial. */ bool BusyWithNewProtocol(EvalContext *ctx, ServerConnectionState *conn) { assert(conn != NULL); /* The CF_BUFEXT extra space is there to ensure we're not *reading* out of * bounds in commands that carry extra binary arguments, like MD5. */ char recvbuffer[CF_BUFSIZE + CF_BUFEXT] = { 0 }; /* This size is the max we can SendTransaction(). */ char sendbuffer[CF_BUFSIZE - CF_INBAND_OFFSET] = { 0 }; char filename[CF_BUFSIZE + 1]; /* +1 for appending slash sometimes */ ServerFileGetState get_args = { 0 }; /* We already encrypt because of the TLS layer, no need to encrypt more. */ const int encrypted = 0; /* Legacy stuff only for old protocol. */ assert(conn->rsa_auth == true); assert(conn->user_data_set == true); /* Receive up to CF_BUFSIZE - 1 bytes. */ const int received = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); if (received == -1) { /* Already Log()ged in case of error. */ return false; } if (received > CF_BUFSIZE - 1) { UnexpectedError("Received transaction of size %d", received); return false; } if (strlen(recvbuffer) == 0) { Log(LOG_LEVEL_WARNING, "Got NULL transmission (of size %d)", received); return true; } /* Don't process request if we're signalled to exit. */ if (IsPendingTermination()) { Log(LOG_LEVEL_VERBOSE, "Server must exit, closing connection"); return false; } /* TODO break recvbuffer here: command, param1, param2 etc. */ switch (GetCommandNew(recvbuffer)) { case PROTOCOL_COMMAND_EXEC: { const size_t EXEC_len = strlen(PROTOCOL_NEW[PROTOCOL_COMMAND_EXEC]); /* Assert recvbuffer starts with EXEC. */ assert(strncmp(PROTOCOL_NEW[PROTOCOL_COMMAND_EXEC], recvbuffer, EXEC_len) == 0); char *args = &recvbuffer[EXEC_len]; args += strspn(args, " \t"); /* bypass spaces */ Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Received:", "EXEC", args); bool b = DoExec2(ctx, conn, args, sendbuffer, sizeof(sendbuffer)); /* In the end we might keep the connection open (return true) to be * ready for next requests, but we must always send the TERMINATOR * string so that the client can close the connection at will. */ Terminate(conn->conn_info); return b; } case PROTOCOL_COMMAND_VERSION: snprintf(sendbuffer, sizeof(sendbuffer), "OK: %s", Version()); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return true; case PROTOCOL_COMMAND_GET: { int ret = sscanf(recvbuffer, "GET %d %[^\n]", &(get_args.buf_size), filename); if (ret != 2 || get_args.buf_size <= 0 || get_args.buf_size > CF_BUFSIZE) { goto protocol_error; } Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Received:", "GET", filename); /* TODO batch all the following in one function since it's very * similar in all of GET, OPENDIR and STAT. */ size_t zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { goto protocol_error; } zret = PreprocessRequestPath(filename, sizeof(filename)); if (zret == (size_t) -1) { RefuseAccess(conn, recvbuffer); return true; } PathRemoveTrailingSlash(filename, strlen(filename)); Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Translated to:", "GET", filename); if (acl_CheckPath(paths_acl, filename, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))) == false) { Log(LOG_LEVEL_INFO, "access denied to GET: %s", filename); RefuseAccess(conn, recvbuffer); return true; } memset(sendbuffer, 0, sizeof(sendbuffer)); if (get_args.buf_size >= CF_BUFSIZE) { get_args.buf_size = 2048; } /* TODO eliminate! */ get_args.conn = conn; get_args.encrypt = false; get_args.replybuff = sendbuffer; get_args.replyfile = filename; CfGetFile(&get_args); return true; } case PROTOCOL_COMMAND_OPENDIR: { memset(filename, 0, sizeof(filename)); int ret = sscanf(recvbuffer, "OPENDIR %[^\n]", filename); if (ret != 1) { goto protocol_error; } Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Received:", "OPENDIR", filename); /* sizeof()-1 because we need one extra byte for appending '/' afterwards. */ size_t zret = ShortcutsExpand(filename, sizeof(filename) - 1, SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { goto protocol_error; } zret = PreprocessRequestPath(filename, sizeof(filename) - 1); if (zret == (size_t) -1) { RefuseAccess(conn, recvbuffer); return true; } /* OPENDIR *must* be directory. */ PathAppendTrailingSlash(filename, strlen(filename)); Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Translated to:", "OPENDIR", filename); if (acl_CheckPath(paths_acl, filename, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))) == false) { Log(LOG_LEVEL_INFO, "access denied to OPENDIR: %s", filename); RefuseAccess(conn, recvbuffer); return true; } CfOpenDirectory(conn, sendbuffer, filename); return true; } case PROTOCOL_COMMAND_SYNCH: { long time_no_see = 0; memset(filename, 0, sizeof(filename)); int ret = sscanf(recvbuffer, "SYNCH %ld STAT %[^\n]", &time_no_see, filename); if (ret != 2 || filename[0] == '\0') { goto protocol_error; } time_t tloc = time(NULL); if (tloc == -1) { /* Should never happen. */ Log(LOG_LEVEL_ERR, "Couldn't read system clock. (time: %s)", GetErrorStr()); SendTransaction(conn->conn_info, "BAD: clocks out of synch", 0, CF_DONE); return true; } time_t trem = (time_t) time_no_see; int drift = (int) (tloc - trem); Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Received:", "STAT", filename); /* sizeof()-1 because we need one extra byte for appending '/' afterwards. */ size_t zret = ShortcutsExpand(filename, sizeof(filename) - 1, SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { goto protocol_error; } zret = PreprocessRequestPath(filename, sizeof(filename) - 1); if (zret == (size_t) -1) { RefuseAccess(conn, recvbuffer); return true; } if (IsDirReal(filename)) { PathAppendTrailingSlash(filename, strlen(filename)); } else { PathRemoveTrailingSlash(filename, strlen(filename)); } Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Translated to:", "STAT", filename); if (acl_CheckPath(paths_acl, filename, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))) == false) { Log(LOG_LEVEL_INFO, "access denied to STAT: %s", filename); RefuseAccess(conn, recvbuffer); return true; } Log(LOG_LEVEL_DEBUG, "Clocks were off by %ld", (long) tloc - (long) trem); if (DENYBADCLOCKS && (drift * drift > CLOCK_DRIFT * CLOCK_DRIFT)) { snprintf(sendbuffer, sizeof(sendbuffer), "BAD: Clocks are too far unsynchronized %ld/%ld", (long) tloc, (long) trem); Log(LOG_LEVEL_INFO, "denybadclocks %s", sendbuffer); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return true; } StatFile(conn, sendbuffer, filename); return true; } case PROTOCOL_COMMAND_MD5: { int ret = sscanf(recvbuffer, "MD5 %[^\n]", filename); if (ret != 1) { goto protocol_error; } Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Received:", "MD5", filename); /* TODO batch all the following in one function since it's very * similar in all of GET, OPENDIR and STAT. */ size_t zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { goto protocol_error; } zret = PreprocessRequestPath(filename, sizeof(filename)); if (zret == (size_t) -1) { RefuseAccess(conn, recvbuffer); return true; } PathRemoveTrailingSlash(filename, strlen(filename)); Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Translated to:", "MD5", filename); if (acl_CheckPath(paths_acl, filename, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))) == false) { Log(LOG_LEVEL_INFO, "access denied to file: %s", filename); RefuseAccess(conn, recvbuffer); return true; } assert(CF_DEFAULT_DIGEST_LEN <= EVP_MAX_MD_SIZE); unsigned char digest[EVP_MAX_MD_SIZE + 1]; assert(CF_BUFSIZE + CF_SMALL_OFFSET + (size_t) CF_DEFAULT_DIGEST_LEN <= sizeof(recvbuffer)); memcpy(digest, recvbuffer + strlen(recvbuffer) + CF_SMALL_OFFSET, CF_DEFAULT_DIGEST_LEN); CompareLocalHash(filename, digest, sendbuffer); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return true; } case PROTOCOL_COMMAND_VAR: { char var[256]; int ret = sscanf(recvbuffer, "VAR %255[^\n]", var); if (ret != 1) { goto protocol_error; } /* TODO if this is literals_acl, then when should I check vars_acl? */ if (acl_CheckExact(literals_acl, var, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))) == false) { Log(LOG_LEVEL_INFO, "access denied to variable: %s", var); RefuseAccess(conn, recvbuffer); return true; } GetServerLiteral(ctx, conn, sendbuffer, recvbuffer, encrypted); return true; } case PROTOCOL_COMMAND_CONTEXT: { char client_regex[256]; int ret = sscanf(recvbuffer, "CONTEXT %255[^\n]", client_regex); if (ret != 1) { goto protocol_error; } Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Received:", "CONTEXT", client_regex); /* WARNING: this comes from legacy code and must be killed if we care * about performance. We should not accept regular expressions from * the client, but this will break backwards compatibility. * * I replicated the code in raw form here to emphasize complexity, * it's the only *slow* command currently in the protocol. */ Item *persistent_classes = ListPersistentClasses(); Item *matched_classes = NULL; /* For all persistent classes */ for (Item *ip = persistent_classes; ip != NULL; ip = ip->next) { const char *class_name = ip->name; /* Does this class match the regex the client sent? */ if (StringMatchFull(client_regex, class_name)) { /* Is this class allowed to be given to the specific * host, according to the regexes in the ACLs? */ if (acl_CheckRegex(classes_acl, class_name, conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info)), NULL) == true) { Log(LOG_LEVEL_DEBUG, "Access granted to class: %s", class_name); PrependItem(&matched_classes, class_name, NULL); } } } if (matched_classes == NULL) { Log(LOG_LEVEL_INFO, "No allowed classes for remoteclassesmatching: %s", client_regex); RefuseAccess(conn, recvbuffer); return true; } ReplyServerContext(conn, encrypted, matched_classes); return true; } case PROTOCOL_COMMAND_QUERY: { char query[256], name[128]; int ret1 = sscanf(recvbuffer, "QUERY %255[^\n]", query); int ret2 = sscanf(recvbuffer, "QUERY %127s", name); if (ret1 != 1 || ret2 != 1) { goto protocol_error; } const char *hostkey = KeyPrintableHash( ConnectionInfoKey(conn->conn_info)); const bool access_to_query = acl_CheckExact( query_acl, name, conn->ipaddr, conn->revdns, hostkey); if (!access_to_query) { Log(LOG_LEVEL_INFO, "access denied to query: %s", query); RefuseAccess(conn, recvbuffer); return true; } if (GetServerQuery(conn, recvbuffer, encrypted)) { return true; } break; } case PROTOCOL_COMMAND_COOKIE: { if (ConnectionInfoProtocolVersion(conn->conn_info) < CF_PROTOCOL_COOKIE) { goto protocol_error; } const char *hostkey = KeyPrintableHash( ConnectionInfoKey(conn->conn_info)); const bool access_to_query_delta = acl_CheckExact( query_acl, "delta", conn->ipaddr, conn->revdns, hostkey); if (!access_to_query_delta) { Log(LOG_LEVEL_INFO, "access denied to cookie query: %s", recvbuffer); RefuseAccess(conn, recvbuffer); return true; } if (ReturnCookies(conn)) { return true; } break; } case PROTOCOL_COMMAND_CALL_ME_BACK: /* Server side, handing the collect call off to cf-hub. */ if (acl_CheckExact(query_acl, "collect_calls", conn->ipaddr, conn->revdns, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))) == false) { Log(LOG_LEVEL_INFO, "access denied to Call-Collect, check the ACL for class: collect_calls"); return false; } ReceiveCollectCall(conn); /* On success that returned true; otherwise, it did all * relevant Log()ging. Either way, we're no longer busy with * it and our caller can close the connection: */ return false; case PROTOCOL_COMMAND_BAD: Log(LOG_LEVEL_WARNING, "Unexpected protocol command: %s", recvbuffer); } /* We should only reach this point if something went really bad, and * close connection. In all other cases (like access denied) connection * shouldn't be closed. */ protocol_error: strcpy(sendbuffer, "BAD: Request denied"); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); Log(LOG_LEVEL_INFO, "Closing connection due to illegal request: %s", recvbuffer); return false; } cfengine-3.24.2/cf-serverd/server_classic.c0000644000000000000000000015023615010704253020575 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* BN_* */ #include /* ERR_get_error */ #include #include /* IsMatchItemIn */ #include /* IsRegexItemIn */ #include /* ReceiveTransaction,SendTransaction */ #include #include /* ToLowerStrInplace */ #include /* StringMatchFull */ #include /* LastSaw1 */ #include /* HashString */ #include /* HavePublicKey */ #include /* ReceiveCollectCall */ #include #include "server.h" /* ServerConnectionState */ #include "server_common.h" /* ListPersistentClasses */ /* Functionality needed exclusively for the classic protocol. */ //******************************************************************* // COMMANDS //******************************************************************* typedef enum { PROTOCOL_COMMAND_EXEC, PROTOCOL_COMMAND_AUTH, PROTOCOL_COMMAND_GET, PROTOCOL_COMMAND_OPENDIR, PROTOCOL_COMMAND_SYNC, PROTOCOL_COMMAND_CONTEXTS, PROTOCOL_COMMAND_MD5, PROTOCOL_COMMAND_MD5_SECURE, PROTOCOL_COMMAND_AUTH_PLAIN, PROTOCOL_COMMAND_AUTH_SECURE, PROTOCOL_COMMAND_SYNC_SECURE, PROTOCOL_COMMAND_GET_SECURE, PROTOCOL_COMMAND_VERSION, PROTOCOL_COMMAND_OPENDIR_SECURE, PROTOCOL_COMMAND_VAR, PROTOCOL_COMMAND_VAR_SECURE, PROTOCOL_COMMAND_CONTEXT, PROTOCOL_COMMAND_CONTEXT_SECURE, PROTOCOL_COMMAND_QUERY_SECURE, PROTOCOL_COMMAND_CALL_ME_BACK, PROTOCOL_COMMAND_BAD } ProtocolCommandClassic; static const char *PROTOCOL_CLASSIC[] = { "EXEC", "AUTH", /* old protocol */ "GET", "OPENDIR", "SYNCH", "CLASSES", "MD5", "SMD5", "CAUTH", "SAUTH", "SSYNCH", "SGET", "VERSION", "SOPENDIR", "VAR", "SVAR", "CONTEXT", "SCONTEXT", "SQUERY", "SCALLBACK", NULL }; static ProtocolCommandClassic GetCommandClassic(char *str) { int i; for (i = 0; PROTOCOL_CLASSIC[i] != NULL; i++) { int cmdlen = strlen(PROTOCOL_CLASSIC[i]); if ((strncmp(str, PROTOCOL_CLASSIC[i], cmdlen) == 0) && (str[cmdlen] == ' ' || str[cmdlen] == '\0')) { return i; } } assert (i == PROTOCOL_COMMAND_BAD); return i; } /* 'resolved' argument needs to be at least CF_BUFSIZE long */ static bool ResolveFilename(const char *req_path, char *res_path) { #if !defined _WIN32 if (realpath(req_path, res_path) == NULL) { return false; } #else memset(res_path, 0, CF_BUFSIZE); CompressPath(res_path, CF_BUFSIZE, req_path); #endif /* Adjust for forward slashes */ MapName(res_path); /* NT has case-insensitive path names */ #ifdef __MINGW32__ int i; for (i = 0; i < strlen(res_path); i++) { res_path[i] = ToLower(res_path[i]); } #endif /* __MINGW32__ */ return true; } static bool PathMatch(const char *stem, const char *request) { const size_t stemlen = strlen(stem); if (strcmp(stem, FILE_SEPARATOR_STR) == 0) { /* Matches everything: */ return true; } if (strcmp(stem, request) == 0) { /* An exact match is a match: */ return true; } /* Otherwise, match only if stem names a parent directory of request: */ return (strlen(request) > stemlen && request[stemlen] == FILE_SEPARATOR && strncmp(stem, request, stemlen) == 0); } static bool AccessControl(EvalContext *ctx, const char *req_path, ServerConnectionState *conn, int encrypt) { bool access = false; char transrequest[CF_BUFSIZE]; struct stat statbuf; char translated_req_path[CF_BUFSIZE]; char transpath[CF_BUFSIZE]; /* * /var/cfengine -> $workdir translation. */ TranslatePath(req_path, translated_req_path, sizeof(translated_req_path)); if (ResolveFilename(translated_req_path, transrequest)) { Log(LOG_LEVEL_VERBOSE, "Filename %s is resolved to %s", translated_req_path, transrequest); } else if ((lstat(translated_req_path, &statbuf) == -1) && !S_ISLNK(statbuf.st_mode)) { Log(LOG_LEVEL_INFO, "Couldn't resolve (realpath: %s) filename: %s", GetErrorStr(), translated_req_path); return false; /* can't continue without transrequest */ } else { Log(LOG_LEVEL_VERBOSE, "Requested file is a dead symbolic link (filename: %s)", translated_req_path); strlcpy(transrequest, translated_req_path, CF_BUFSIZE); } if (lstat(transrequest, &statbuf) == -1) { Log(LOG_LEVEL_INFO, "Couldn't stat (lstat: %s) filename: %s", GetErrorStr(), transrequest); return false; } Log(LOG_LEVEL_DEBUG, "AccessControl, match (%s,%s) encrypt request = %d", transrequest, conn->hostname, encrypt); if (SERVER_ACCESS.admit == NULL) { Log(LOG_LEVEL_INFO, "cf-serverd access list is empty, no files are visible"); return false; } conn->maproot = false; for (Auth *ap = SERVER_ACCESS.admit; ap != NULL; ap = ap->next) { Log(LOG_LEVEL_DEBUG, "Examining rule in access list (%s,%s)", transrequest, ap->path); /* TODO MapName when constructing this list. */ strlcpy(transpath, ap->path, CF_BUFSIZE); MapName(transpath); if (PathMatch(transpath, transrequest)) { Log(LOG_LEVEL_VERBOSE, "Found a matching rule in access list (%s in %s)", transrequest, transpath); if (stat(transpath, &statbuf) == -1) { Log(LOG_LEVEL_INFO, "Warning cannot stat file object %s in admit/grant, or access list refers to dangling link", transpath); continue; } if (!encrypt && ap->encrypt) { Log(LOG_LEVEL_ERR, "File %s requires encrypt connection...will not serve", transpath); access = false; } else { Log(LOG_LEVEL_DEBUG, "Checking whether to map root privileges.."); if (IsMatchItemIn(ap->maproot, conn->ipaddr) || IsRegexItemIn(ctx, ap->maproot, conn->hostname)) { conn->maproot = true; Log(LOG_LEVEL_VERBOSE, "Mapping root privileges to access non-root files"); } if (IsMatchItemIn(ap->accesslist, conn->ipaddr) || IsRegexItemIn(ctx, ap->accesslist, conn->hostname)) { access = true; Log(LOG_LEVEL_DEBUG, "Access granted to host: %s", conn->ipaddr); } } break; } } for (Auth *dp = SERVER_ACCESS.deny; dp != NULL; dp = dp->next) { strlcpy(transpath, dp->path, CF_BUFSIZE); MapName(transpath); if (PathMatch(transpath, transrequest)) { if ((IsMatchItemIn(dp->accesslist, conn->ipaddr)) || (IsRegexItemIn(ctx, dp->accesslist, conn->hostname))) { access = false; Log(LOG_LEVEL_INFO, "Host '%s' in deny list, explicitly denying access to '%s' in '%s'", conn->ipaddr, transrequest, transpath); break; } } } if (access) { Log(LOG_LEVEL_VERBOSE, "Host %s granted access to %s", conn->hostname, req_path); if (encrypt && LOGENCRYPT) { /* Log files that were marked as requiring encryption */ Log(LOG_LEVEL_INFO, "Host %s granted access to %s", conn->hostname, req_path); } } else { Log(LOG_LEVEL_INFO, "Host %s denied access to %s", conn->hostname, req_path); } return access; } /* Checks the "varadmit" legacy ACL. */ static int LiteralAccessControl(EvalContext *ctx, char *in, ServerConnectionState *conn, int encrypt) { Auth *ap; int access = false; char name[CF_BUFSIZE]; name[0] = '\0'; if (strncmp(in, "VAR", 3) == 0) { sscanf(in, "VAR %255[^\n]", name); } else if (strncmp(in, "CALL_ME_BACK", strlen("CALL_ME_BACK")) == 0) { sscanf(in, "CALL_ME_BACK %255[^\n]", name); } else { sscanf(in, "QUERY %128s", name); } conn->maproot = false; for (ap = SERVER_ACCESS.varadmit; ap != NULL; ap = ap->next) { Log(LOG_LEVEL_VERBOSE, "Examining rule in access list (%s,%s)?", name, ap->path); if (strcmp(ap->path, name) == 0) /* exact match */ { Log(LOG_LEVEL_VERBOSE, "Found a matching rule in access list (%s in %s)", name, ap->path); if ((!ap->literal) && (!ap->variable)) { Log(LOG_LEVEL_ERR, "Variable/query '%s' requires a literal server item...cannot set variable directly by path", ap->path); access = false; break; } if (!encrypt && ap->encrypt) { Log(LOG_LEVEL_ERR, "Variable %s requires encrypt connection...will not serve", name); access = false; break; } else { Log(LOG_LEVEL_DEBUG, "Checking whether to map root privileges"); if ((IsMatchItemIn(ap->maproot, conn->ipaddr)) || (IsRegexItemIn(ctx, ap->maproot, conn->hostname))) { conn->maproot = true; Log(LOG_LEVEL_VERBOSE, "Mapping root privileges"); } else { Log(LOG_LEVEL_VERBOSE, "No root privileges granted"); } if ((IsMatchItemIn(ap->accesslist, conn->ipaddr)) || (IsRegexItemIn(ctx, ap->accesslist, conn->hostname))) { access = true; Log(LOG_LEVEL_DEBUG, "Access privileges - match found"); } } } } for (ap = SERVER_ACCESS.vardeny; ap != NULL; ap = ap->next) { if (strcmp(ap->path, name) == 0) { if ((IsMatchItemIn(ap->accesslist, conn->ipaddr)) || (IsRegexItemIn(ctx, ap->accesslist, conn->hostname))) { access = false; Log(LOG_LEVEL_VERBOSE, "Host %s explicitly denied access to %s", conn->hostname, name); break; } } } if (access) { Log(LOG_LEVEL_VERBOSE, "Host %s granted access to literal '%s'", conn->hostname, name); if (encrypt && LOGENCRYPT) { /* Log files that were marked as requiring encryption */ Log(LOG_LEVEL_INFO, "Host %s granted access to literal '%s'", conn->hostname, name); } } else { Log(LOG_LEVEL_VERBOSE, "Host %s denied access to literal '%s'", conn->hostname, name); } return access; } /* Checks the "varadmit" legacy ACL. */ static Item *ContextAccessControl(EvalContext *ctx, char *in, ServerConnectionState *conn, int encrypt) { Auth *ap; int access = false; char client_regex[CF_BUFSIZE]; Item *ip, *matches = NULL; int ret = sscanf(in, "CONTEXT %255[^\n]", client_regex); Item *persistent_classes = ListPersistentClasses(); if (ret != 1 || persistent_classes == NULL) { return NULL; } for (ip = persistent_classes; ip != NULL; ip = ip->next) { /* Does the class match the regex that the agent requested? */ if (StringMatchFull(client_regex, ip->name)) { for (ap = SERVER_ACCESS.varadmit; ap != NULL; ap = ap->next) { /* Does the class match any of the regex in ACLs? */ if (StringMatchFull(ap->path, ip->name)) { Log(LOG_LEVEL_VERBOSE, "Found a matching rule in access list (%s in %s)", ip->name, ap->path); if (!ap->classpattern) { Log(LOG_LEVEL_ERR, "Context %s requires a literal server item... " "cannot set variable directly by path", ap->path); access = false; continue; } if (!encrypt && ap->encrypt) { Log(LOG_LEVEL_ERR, "Context %s requires encrypt connection... " "will not serve", ip->name); access = false; break; } else { Log(LOG_LEVEL_DEBUG, "Checking whether to map root privileges"); if ((IsMatchItemIn(ap->maproot, conn->ipaddr)) || (IsRegexItemIn(ctx, ap->maproot, conn->hostname))) { conn->maproot = true; Log(LOG_LEVEL_VERBOSE, "Mapping root privileges"); } else { Log(LOG_LEVEL_VERBOSE, "No root privileges granted"); } if ((IsMatchItemIn(ap->accesslist, conn->ipaddr)) || (IsRegexItemIn(ctx, ap->accesslist, conn->hostname))) { access = true; Log(LOG_LEVEL_DEBUG, "Access privileges - match found"); } } } } for (ap = SERVER_ACCESS.vardeny; ap != NULL; ap = ap->next) { if (strcmp(ap->path, ip->name) == 0) { if ((IsMatchItemIn(ap->accesslist, conn->ipaddr)) || (IsRegexItemIn(ctx, ap->accesslist, conn->hostname))) { access = false; Log(LOG_LEVEL_VERBOSE, "Host %s explicitly denied access to context %s", conn->hostname, ip->name); break; } } } if (access) { Log(LOG_LEVEL_VERBOSE, "Host %s granted access to context '%s'", conn->hostname, ip->name); AppendItem(&matches, ip->name, NULL); if (encrypt && LOGENCRYPT) { /* Log files that were marked as requiring encryption */ Log(LOG_LEVEL_INFO, "Host %s granted access to context '%s'", conn->hostname, ip->name); } } else { Log(LOG_LEVEL_VERBOSE, "Host %s denied access to context '%s'", conn->hostname, ip->name); } } } DeleteItemList(persistent_classes); return matches; } static int cfscanf(char *in, int len1, int len2, char *out1, char *out2, char *out3) { int len3 = 0; char *sp; sp = in; memcpy(out1, sp, len1); out1[len1] = '\0'; sp += len1 + 1; memcpy(out2, sp, len2); sp += len2 + 1; len3 = strlen(sp); memcpy(out3, sp, len3); out3[len3] = '\0'; return (len1 + len2 + len3 + 2); } static void SetConnectionData(ServerConnectionState *conn, char *buf) { char ipstring[CF_MAXVARSIZE], fqname[CF_MAXVARSIZE], username[CF_MAXVARSIZE]; Log(LOG_LEVEL_DEBUG, "Connecting host identifies itself as '%s'", buf); memset(ipstring, 0, CF_MAXVARSIZE); memset(fqname, 0, CF_MAXVARSIZE); memset(username, 0, CF_MAXVARSIZE); sscanf(buf, "%255s %255s %255s", ipstring, fqname, username); /* The "ipstring" that the client sends is currently *ignored* as * conn->ipaddr is always set from the connecting socket address. */ Log(LOG_LEVEL_DEBUG, "(ipstring=[%s],fqname=[%s],username=[%s],socket=[%s])", ipstring, fqname, username, conn->ipaddr); ToLowerStrInplace(fqname); strlcpy(conn->hostname, fqname, CF_MAXVARSIZE); SetConnIdentity(conn, username); } static bool CheckStoreKey(ServerConnectionState *conn, RSA *key) { RSA *savedkey; const char *udigest = KeyPrintableHash(ConnectionInfoKey(conn->conn_info)); assert(udigest != NULL); if ((savedkey = HavePublicKey(conn->username, conn->ipaddr, udigest))) { Log(LOG_LEVEL_VERBOSE, "A public key was already known from %s/%s - no trust required", conn->hostname, conn->ipaddr); const BIGNUM *key_n, *key_e, *savedkey_n, *savedkey_e; RSA_get0_key(key, &key_n, &key_e, NULL); RSA_get0_key(savedkey, &savedkey_n, &savedkey_e, NULL); if ((BN_cmp(savedkey_e, key_e) == 0) && (BN_cmp(savedkey_n, key_n) == 0)) { Log(LOG_LEVEL_VERBOSE, "The public key identity was confirmed as %s@%s", conn->username, conn->hostname); SendTransaction(conn->conn_info, "OK: key accepted", 0, CF_DONE); RSA_free(savedkey); return true; } } /* Finally, if we're still here then the key is new (not in ppkeys * directory): Allow access only if host is listed in "trustkeysfrom" body * server control option. */ if ((SERVER_ACCESS.trustkeylist != NULL) && (IsMatchItemIn(SERVER_ACCESS.trustkeylist, conn->ipaddr))) { Log(LOG_LEVEL_VERBOSE, "Host %s/%s was found in the list of hosts to trust", conn->hostname, conn->ipaddr); SendTransaction(conn->conn_info, "OK: unknown key was accepted on trust", 0, CF_DONE); SavePublicKey(conn->username, udigest, key); return true; } else { Log(LOG_LEVEL_VERBOSE, "No previous key found, and unable to accept this one on trust"); SendTransaction(conn->conn_info, "BAD: key could not be accepted on trust", 0, CF_DONE); return false; } } static bool AuthenticationDialogue(ServerConnectionState *conn, char *recvbuffer, unsigned int recvlen) { unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 }; if (PRIVKEY == NULL || PUBKEY == NULL) { Log(LOG_LEVEL_ERR, "No public/private key pair is loaded," " please create one using cf-key"); return false; } int PRIVKEY_size = RSA_size(PRIVKEY); int digestLen; HashMethod digestType; if (FIPS_MODE) { digestType = CF_DEFAULT_DIGEST; digestLen = CF_DEFAULT_DIGEST_LEN; } else { digestType = HASH_METHOD_MD5; digestLen = CF_MD5_LEN; } /* parameters received in SAUTH command */ char iscrypt, enterprise_field; /* proposition C1 - SAUTH command */ { char sauth[10] = { 0 }; unsigned int crypt_len; /* received encrypted challenge length */ unsigned int challenge_len; /* challenge length after decryption */ int nparam = sscanf(recvbuffer, "%9s %c %u %u %c", sauth, &iscrypt, &crypt_len, &challenge_len, &enterprise_field); if (nparam >= 1 && strcmp(sauth, "SAUTH") != 0) { Log(LOG_LEVEL_ERR, "Authentication failure: " "was expecting SAUTH command but got '%s'", sauth); return false; } if (nparam != 5 && nparam != 4) { Log(LOG_LEVEL_ERR, "Authentication failure: " "peer sent only %d arguments to SAUTH command", nparam - 1); return false; } /* CFEngine 2 had no enterprise/community differentiation. */ if (nparam == 4) { Log(LOG_LEVEL_VERBOSE, "Peer sent only 4 parameters, " "assuming it is a legacy community client"); enterprise_field = 'c'; } if ((challenge_len == 0) || (crypt_len == 0)) { Log(LOG_LEVEL_ERR, "Authentication failure: received unexpected challenge length " "(%u that decrypts to %u bytes)", challenge_len, crypt_len); return false; } if (crypt_len > CF_NONCELEN * 2) { Log(LOG_LEVEL_ERR, "Authentication failure: " "received encrypted challenge is too long " "(%d bytes)", crypt_len); return false; } if (challenge_len > CF_NONCELEN * 2) { Log(LOG_LEVEL_ERR, "Authentication failure: " "received challenge is too long (%u bytes)", challenge_len); return false; } Log(LOG_LEVEL_DEBUG, "Challenge encryption = %c, challenge_len = %u, crypt_len = %u", iscrypt, challenge_len, crypt_len); char *challenge; char decrypted_challenge[PRIVKEY_size]; if (iscrypt == 'y') /* challenge came encrypted */ { if (recvlen < CF_RSA_PROTO_OFFSET + crypt_len) { Log(LOG_LEVEL_ERR, "Authentication failure: peer sent only %d " "bytes as encrypted challenge but claims to have sent %u bytes", recvlen - CF_RSA_PROTO_OFFSET, crypt_len); } int ret = RSA_private_decrypt( crypt_len, (const unsigned char *) recvbuffer + CF_RSA_PROTO_OFFSET, (unsigned char *) decrypted_challenge, PRIVKEY, RSA_PKCS1_PADDING); if (ret < 0) { Log(LOG_LEVEL_ERR, "Authentication failure: " "private decrypt of received challenge failed (%s)", CryptoLastErrorString()); Log(LOG_LEVEL_ERR, "Probably the client has wrong public key for this server"); return false; } if ((unsigned int) ret != challenge_len) { Log(LOG_LEVEL_ERR, "Authentication failure: " "private decrypt of received challenge (%u bytes) " "resulted in %d bytes instead of promised %u bytes", crypt_len, ret, challenge_len); return false; } challenge = decrypted_challenge; } else /* challenge came unencrypted */ { if (challenge_len != crypt_len) { Log(LOG_LEVEL_ERR, "Authentication failure: peer sent illegal challenge " "(challenge_len %u != crypt_len %u)", challenge_len, crypt_len); return false; } if (recvlen < CF_RSA_PROTO_OFFSET + challenge_len) { Log(LOG_LEVEL_ERR, "Authentication failure: peer sent only %d " "bytes as challenge but claims to have sent %u bytes", recvlen - CF_RSA_PROTO_OFFSET, challenge_len); return false; } challenge = &recvbuffer[CF_RSA_PROTO_OFFSET]; } /* Client's ID is now established by key or trusted, reply with digest */ HashString(challenge, challenge_len, digest, digestType); } BIGNUM *newkey_n, *newkey_e; /* proposition C2 - Receive client's public key modulus */ { int len_n = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); if (len_n == -1) { Log(LOG_LEVEL_ERR, "Authentication failure: " "error while receiving public key modulus"); return false; } if ((newkey_n = BN_mpi2bn((unsigned char *) recvbuffer, len_n, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Authentication failure: " "private decrypt of received public key modulus failed " "(%s)", CryptoLastErrorString()); return false; } } /* proposition C3 - Receive client's public key exponent. */ { int len_e = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); if (len_e == -1) { Log(LOG_LEVEL_ERR, "Authentication failure: " "error while receiving public key exponent"); return false; } if ((newkey_e = BN_mpi2bn((unsigned char *) recvbuffer, len_e, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Authentication failure: " "private decrypt of received public key exponent failed " "(%s)", CryptoLastErrorString()); BN_free(newkey_n); return false; } } RSA *newkey = RSA_new(); if (newkey == NULL) { Log(LOG_LEVEL_ERR, "Failed to allocate RSA key: %s", TLSErrorString(ERR_get_error())); BN_free(newkey_n); BN_free(newkey_e); return false; } if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { Log(LOG_LEVEL_ERR, "Failed to set RSA key: %s", TLSErrorString(ERR_get_error())); BN_free(newkey_n); BN_free(newkey_e); RSA_free(newkey); return false; } /* Compute and store hash of the client's public key. */ { Key *key = KeyNew(newkey, CF_DEFAULT_DIGEST); conn->conn_info->remote_key = key; Log(LOG_LEVEL_VERBOSE, "Peer's identity is: %s", KeyPrintableHash(key)); LastSaw1(conn->ipaddr, KeyPrintableHash(key), LAST_SEEN_ROLE_ACCEPT); /* Do we want to trust the received key? */ if (!CheckStoreKey(conn, newkey)) /* conceals proposition S1 */ { return false; } } /* proposition S2 - reply with digest of challenge. */ { Log(LOG_LEVEL_DEBUG, "Sending challenge response"); SendTransaction(conn->conn_info, (const char *) digest, digestLen, CF_DONE); } /* proposition S3 - send counter-challenge */ { BIGNUM *counter_challenge_BN = BN_new(); if (counter_challenge_BN == NULL) { Log(LOG_LEVEL_ERR, "Authentication failure: " "cannot allocate BIGNUM structure for counter-challenge"); return false; } BN_rand(counter_challenge_BN, CF_NONCELEN, 0, 0); unsigned char counter_challenge[CF_BUFSIZE]; int counter_challenge_len = BN_bn2mpi(counter_challenge_BN, counter_challenge); BN_free(counter_challenge_BN); /* Compute counter-challenge digest. */ HashString((const char *) counter_challenge, counter_challenge_len, digest, digestType); /* Encryption buffer is always RSA_size(key) and buffer needs 11 bytes, * see RSA_public_encrypt manual. */ int encrypted_len = RSA_size(newkey); unsigned char encrypted_counter_challenge[encrypted_len]; assert(counter_challenge_len < encrypted_len - 11); int ret = RSA_public_encrypt(counter_challenge_len, counter_challenge, encrypted_counter_challenge, newkey, RSA_PKCS1_PADDING); if (ret != encrypted_len) { if (ret == -1) { Log(LOG_LEVEL_ERR, "Authentication failure: " "public encryption of counter-challenge failed " "(%s)", CryptoLastErrorString()); } else { Log(LOG_LEVEL_ERR, "Authentication failure: " "public encryption of counter-challenge failed " "(result length %d but should be %d)", ret, encrypted_len); } return false; } Log(LOG_LEVEL_DEBUG, "Sending counter-challenge"); SendTransaction(conn->conn_info, (const char *) encrypted_counter_challenge, encrypted_len, CF_DONE); } /* proposition S4, S5 - If the client doesn't have our public key, send it. */ { if (iscrypt != 'y') { Log(LOG_LEVEL_DEBUG, "Sending server's public key"); unsigned char bignum_buf[CF_BUFSIZE] = { 0 }; const BIGNUM *n, *e; RSA_get0_key(PUBKEY, &n, &e, NULL); /* proposition S4 - conditional */ int len_n = BN_bn2mpi(n, bignum_buf); SendTransaction(conn->conn_info, (const char *) bignum_buf, len_n, CF_DONE); /* proposition S5 - conditional */ int len_e = BN_bn2mpi(e, bignum_buf); SendTransaction(conn->conn_info, (const char *) bignum_buf, len_e, CF_DONE); } } /* proposition C4 - Receive counter-challenge response. */ { unsigned char recv_buf[CF_BUFSIZE] = { 0 }; int recv_len = ReceiveTransaction(conn->conn_info, (char *) recv_buf, NULL); if (recv_len < digestLen) { if (recv_len == -1) { Log(LOG_LEVEL_ERR, "Authentication failure: " "error receiving counter-challenge response; " "maybe the client does not trust our key?"); } else /* 0 < recv_len < expected_len */ { Log(LOG_LEVEL_ERR, "Authentication failure: " "error receiving counter-challenge response, " "only got %d out of %d bytes", recv_len, digestLen); } return false; } if (HashesMatch(digest, recv_buf, digestType)) { Log(LOG_LEVEL_VERBOSE, "Authentication of client %s/%s achieved", conn->hostname, conn->ipaddr); } else { Log(LOG_LEVEL_ERR, "Authentication failure: " "counter-challenge response was incorrect"); return false; } } /* proposition C5 - Receive session key */ { Log(LOG_LEVEL_DEBUG, "Receiving session key from client..."); unsigned char session_key[CF_BUFSIZE] = { 0 }; int session_key_size = CfSessionKeySize(enterprise_field); int keylen = ReceiveTransaction(conn->conn_info, (char *) session_key, NULL); Log(LOG_LEVEL_DEBUG, "Received encrypted session key of %d bytes, " "should decrypt to %d bytes", keylen, session_key_size); if (keylen == -1) { Log(LOG_LEVEL_ERR, "Authentication failure: " "error receiving session key"); return false; } if (keylen > CF_BUFSIZE / 2) { Log(LOG_LEVEL_ERR, "Authentication failure: " "session key received is too long (%d bytes)", keylen); return false; } conn->session_key = xmalloc(session_key_size); conn->encryption_type = enterprise_field; if (keylen == CF_BLOWFISHSIZE) /* Support the old non-ecnrypted for upgrade */ { memcpy(conn->session_key, session_key, session_key_size); } else { unsigned char decrypted_session_key[PRIVKEY_size]; int ret = RSA_private_decrypt(keylen, session_key, decrypted_session_key, PRIVKEY, RSA_PKCS1_PADDING); if (ret != session_key_size) { if (ret < 0) { Log(LOG_LEVEL_ERR, "Authentication failure: " "private decrypt of session key failed " "(%s)", CryptoLastErrorString()); } else { Log(LOG_LEVEL_ERR, "Authentication failure: " "session key decrypts to invalid size, " "expected %d but got %d bytes", session_key_size, ret); } return false; } memcpy(conn->session_key, decrypted_session_key, session_key_size); } } return true; } bool BusyWithClassicConnection(EvalContext *ctx, ServerConnectionState *conn) { time_t tloc, trem = 0; char recvbuffer[CF_BUFSIZE + CF_BUFEXT], check[CF_BUFSIZE]; char sendbuffer[CF_BUFSIZE] = { 0 }; char filename[CF_BUFSIZE], buffer[CF_BUFSIZE], out[CF_BUFSIZE]; long time_no_see = 0; unsigned int len = 0; int drift, plainlen, received, encrypted = 0; size_t zret; ServerFileGetState get_args; Item *classes; memset(recvbuffer, 0, CF_BUFSIZE + CF_BUFEXT); memset(&get_args, 0, sizeof(get_args)); received = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); if (received < 0) { return false; } if (strlen(recvbuffer) == 0) { Log(LOG_LEVEL_WARNING, "Got NULL transmission, skipping!"); return true; } /* Don't process request if we're signalled to exit. */ if (IsPendingTermination()) { Log(LOG_LEVEL_VERBOSE, "Server must exit, closing connection"); return false; } ProtocolCommandClassic command = GetCommandClassic(recvbuffer); switch (command) { /* Plain text authentication; this MUST be the first command client using classic protocol is sending. */ case PROTOCOL_COMMAND_AUTH_PLAIN: SetConnectionData(conn, (char *) (recvbuffer + strlen("CAUTH "))); if (!IsUserNameValid(conn->username)) { Log(LOG_LEVEL_INFO, "Client is sending wrong username: %s", conn->username); RefuseAccess(conn, recvbuffer); return false; } /* This is used only for forcing correct state of state machine while connecting and authenticating user using classic protocol. */ conn->user_data_set = true; return true; /* This MUST be exactly second command client using classic protocol is sending. This is where key agreement takes place. */ case PROTOCOL_COMMAND_AUTH_SECURE: /* First command was omitted by client; this is protocol violation. */ if (!conn->user_data_set) { Log(LOG_LEVEL_INFO, "Client is not verified; rejecting connection"); RefuseAccess(conn, recvbuffer); return false; } conn->rsa_auth = AuthenticationDialogue(conn, recvbuffer, received); if (!conn->rsa_auth) { Log(LOG_LEVEL_INFO, "Auth dialogue error"); RefuseAccess(conn, recvbuffer); return false; } return true; default: break; } /* At this point we should have both user_data_set and rsa_auth set to perform any operation. We can check only for second one as without first it won't be set up. */ if (!conn->rsa_auth) { Log(LOG_LEVEL_INFO, "REFUSAL due to no RSA authentication (command: %d)", command); RefuseAccess(conn, recvbuffer); return false; } /* We have to have key at this point. */ assert(conn->session_key); /* At this point we can safely do next switch and make sure user is * authenticated. */ switch (command) { case PROTOCOL_COMMAND_EXEC: { const size_t EXEC_len = strlen(PROTOCOL_CLASSIC[PROTOCOL_COMMAND_EXEC]); /* Assert recvbuffer starts with EXEC. */ assert(strncmp(PROTOCOL_CLASSIC[PROTOCOL_COMMAND_EXEC], recvbuffer, EXEC_len) == 0); char *args = &recvbuffer[EXEC_len]; args += strspn(args, " \t"); /* bypass spaces */ Log(LOG_LEVEL_VERBOSE, "%14s %7s %s", "Received:", "EXEC", args); bool b = DoExec2(ctx, conn, args, sendbuffer, sizeof(sendbuffer)); /* In the end we might keep the connection open (return true) to be * ready for next requests, but we must always send the TERMINATOR * string so that the client can close the connection at will. */ Terminate(conn->conn_info); return b; } case PROTOCOL_COMMAND_VERSION: snprintf(sendbuffer, sizeof(sendbuffer), "OK: %s", Version()); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return conn->user_data_set; case PROTOCOL_COMMAND_GET: memset(filename, 0, CF_BUFSIZE); sscanf(recvbuffer, "GET %d %[^\n]", &(get_args.buf_size), filename); if ((get_args.buf_size < 0) || (get_args.buf_size > CF_BUFSIZE)) { Log(LOG_LEVEL_INFO, "GET buffer out of bounds"); RefuseAccess(conn, recvbuffer); return false; } zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->hostname, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { Log(LOG_LEVEL_VERBOSE, "Expanding filename (%s) made it too long (>= %zu)", filename, sizeof(filename)); return false; } if (!AccessControl(ctx, filename, conn, false)) { Log(LOG_LEVEL_INFO, "Access denied to get object"); RefuseAccess(conn, recvbuffer); return true; } memset(sendbuffer, 0, sizeof(sendbuffer)); if (get_args.buf_size >= CF_BUFSIZE) { get_args.buf_size = 2048; } get_args.conn = conn; get_args.encrypt = false; get_args.replybuff = sendbuffer; get_args.replyfile = filename; CfGetFile(&get_args); return true; case PROTOCOL_COMMAND_GET_SECURE: memset(buffer, 0, CF_BUFSIZE); sscanf(recvbuffer, "SGET %u %d", &len, &(get_args.buf_size)); if ((unsigned int) received != len + CF_PROTO_OFFSET) { Log(LOG_LEVEL_INFO, "Protocol error SGET"); RefuseAccess(conn, recvbuffer); return false; } plainlen = DecryptString(buffer, sizeof(buffer), recvbuffer + CF_PROTO_OFFSET, len, conn->encryption_type, conn->session_key); cfscanf(buffer, strlen("GET"), strlen("dummykey"), check, sendbuffer, filename); if (strcmp(check, "GET") != 0) { Log(LOG_LEVEL_INFO, "SGET/GET problem"); RefuseAccess(conn, recvbuffer); return true; } if ((get_args.buf_size < 0) || (get_args.buf_size > 8192)) { Log(LOG_LEVEL_INFO, "SGET bounding error"); RefuseAccess(conn, recvbuffer); return false; } if (get_args.buf_size >= CF_BUFSIZE) { get_args.buf_size = 2048; } zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->hostname, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { Log(LOG_LEVEL_VERBOSE, "Expanding filename (%s) made it too long (>= %zu)", filename, sizeof(filename)); return false; } Log(LOG_LEVEL_DEBUG, "Confirm decryption, and thus validity of caller"); Log(LOG_LEVEL_DEBUG, "SGET '%s' with blocksize %d", filename, get_args.buf_size); if (!AccessControl(ctx, filename, conn, true)) { Log(LOG_LEVEL_INFO, "Access control error"); RefuseAccess(conn, recvbuffer); return false; } memset(sendbuffer, 0, sizeof(sendbuffer)); get_args.conn = conn; get_args.encrypt = true; get_args.replybuff = sendbuffer; get_args.replyfile = filename; CfEncryptGetFile(&get_args); return true; case PROTOCOL_COMMAND_OPENDIR_SECURE: memset(buffer, 0, CF_BUFSIZE); sscanf(recvbuffer, "SOPENDIR %u", &len); if ((len >= sizeof(out)) || ((unsigned int) received != (len + CF_PROTO_OFFSET))) { Log(LOG_LEVEL_INFO, "Protocol error OPENDIR: %d", len); RefuseAccess(conn, recvbuffer); return false; } memcpy(out, recvbuffer + CF_PROTO_OFFSET, len); plainlen = DecryptString(recvbuffer, sizeof(recvbuffer), out, len, conn->encryption_type, conn->session_key); if (strncmp(recvbuffer, "OPENDIR", 7) != 0) { Log(LOG_LEVEL_INFO, "Opendir failed to decrypt"); RefuseAccess(conn, recvbuffer); return true; } memset(filename, 0, CF_BUFSIZE); sscanf(recvbuffer, "OPENDIR %[^\n]", filename); zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->hostname, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { Log(LOG_LEVEL_VERBOSE, "Expanding filename (%s) made it too long (>= %zu)", filename, sizeof(filename)); return false; } if (!AccessControl(ctx, filename, conn, true)) /* opendir don't care about privacy */ { Log(LOG_LEVEL_INFO, "Access error"); RefuseAccess(conn, recvbuffer); return false; } CfSecOpenDirectory(conn, sendbuffer, filename); return true; case PROTOCOL_COMMAND_OPENDIR: memset(filename, 0, CF_BUFSIZE); sscanf(recvbuffer, "OPENDIR %[^\n]", filename); zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->hostname, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { Log(LOG_LEVEL_VERBOSE, "Expanding filename (%s) made it too long (>= %zu)", filename, sizeof(filename)); return false; } if (!AccessControl(ctx, filename, conn, false)) /* opendir don't care about privacy */ { Log(LOG_LEVEL_INFO, "DIR access error"); RefuseAccess(conn, recvbuffer); return false; } CfOpenDirectory(conn, sendbuffer, filename); return true; case PROTOCOL_COMMAND_SYNC_SECURE: memset(buffer, 0, CF_BUFSIZE); sscanf(recvbuffer, "SSYNCH %u", &len); if ((len >= sizeof(out)) || ((unsigned int) received != (len + CF_PROTO_OFFSET))) { Log(LOG_LEVEL_INFO, "Protocol error SSYNCH: %d", len); RefuseAccess(conn, recvbuffer); return false; } memcpy(out, recvbuffer + CF_PROTO_OFFSET, len); plainlen = DecryptString(recvbuffer, sizeof(recvbuffer), out, len, conn->encryption_type, conn->session_key); if (plainlen < 0) { DebugBinOut((char *) conn->session_key, 32, "Session key"); Log(LOG_LEVEL_ERR, "Bad decrypt (%d)", len); } if (strncmp(recvbuffer, "SYNCH", 5) != 0) { Log(LOG_LEVEL_INFO, "No synch"); RefuseAccess(conn, recvbuffer); return true; } /* fall through */ case PROTOCOL_COMMAND_SYNC: memset(filename, 0, CF_BUFSIZE); sscanf(recvbuffer, "SYNCH %ld STAT %[^\n]", &time_no_see, filename); trem = (time_t) time_no_see; if (filename[0] == '\0') { break; } if ((tloc = time((time_t *) NULL)) == -1) { Log(LOG_LEVEL_INFO, "Couldn't read system clock. (time: %s)", GetErrorStr()); SendTransaction(conn->conn_info, "BAD: clocks out of synch", 0, CF_DONE); return true; } drift = (int) (tloc - trem); zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->hostname, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { Log(LOG_LEVEL_VERBOSE, "Expanding filename (%s) made it too long (>= %zu)", filename, sizeof(filename)); return false; } if (!AccessControl(ctx, filename, conn, true)) { Log(LOG_LEVEL_INFO, "Access control in sync"); RefuseAccess(conn, recvbuffer); return true; } if (DENYBADCLOCKS && (drift * drift > CLOCK_DRIFT * CLOCK_DRIFT)) { snprintf(sendbuffer, sizeof(sendbuffer), "BAD: Clocks are too far unsynchronized %ld/%ld", (long) tloc, (long) trem); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return true; } else { Log(LOG_LEVEL_DEBUG, "Clocks were off by %ld", (long) tloc - (long) trem); StatFile(conn, sendbuffer, filename); } return true; case PROTOCOL_COMMAND_MD5_SECURE: sscanf(recvbuffer, "SMD5 %u", &len); if ((len >= sizeof(out)) || ((unsigned int) received != (len + CF_PROTO_OFFSET))) { Log(LOG_LEVEL_INFO, "Decryption error"); RefuseAccess(conn, recvbuffer); return true; } memcpy(out, recvbuffer + CF_PROTO_OFFSET, len); plainlen = DecryptString(recvbuffer, sizeof(recvbuffer), out, len, conn->encryption_type, conn->session_key); if (strncmp(recvbuffer, "MD5", 3) != 0) { Log(LOG_LEVEL_INFO, "MD5 protocol error"); RefuseAccess(conn, recvbuffer); return false; } encrypted = true; /* fall through */ case PROTOCOL_COMMAND_MD5: memset(filename, 0, sizeof(filename)); sscanf(recvbuffer, "MD5 %[^\n]", filename); zret = ShortcutsExpand(filename, sizeof(filename), SERVER_ACCESS.path_shortcuts, conn->ipaddr, conn->hostname, KeyPrintableHash(ConnectionInfoKey(conn->conn_info))); if (zret == (size_t) -1) { Log(LOG_LEVEL_VERBOSE, "Expanding filename (%s) made it too long (>= %zu)", filename, sizeof(filename)); return false; } if (!AccessControl(ctx, filename, conn, encrypted)) { Log(LOG_LEVEL_INFO, "Access denied to get object"); RefuseAccess(conn, recvbuffer); return true; } assert(CF_DEFAULT_DIGEST_LEN <= EVP_MAX_MD_SIZE); unsigned char digest[EVP_MAX_MD_SIZE + 1]; assert(CF_BUFSIZE + CF_SMALL_OFFSET + (unsigned long) CF_DEFAULT_DIGEST_LEN <= sizeof(recvbuffer)); memcpy(digest, recvbuffer + strlen(recvbuffer) + CF_SMALL_OFFSET, CF_DEFAULT_DIGEST_LEN); CompareLocalHash(filename, digest, sendbuffer); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); return true; case PROTOCOL_COMMAND_VAR_SECURE: sscanf(recvbuffer, "SVAR %u", &len); if ((len >= sizeof(out)) || ((unsigned int) received != (len + CF_PROTO_OFFSET))) { Log(LOG_LEVEL_INFO, "Decrypt error SVAR"); RefuseAccess(conn, "decrypt error SVAR"); return true; } memcpy(out, recvbuffer + CF_PROTO_OFFSET, len); plainlen = DecryptString(recvbuffer, sizeof(recvbuffer), out, len, conn->encryption_type, conn->session_key); encrypted = true; if (strncmp(recvbuffer, "VAR", 3) != 0) { Log(LOG_LEVEL_INFO, "VAR protocol defect"); RefuseAccess(conn, "decryption failure"); return false; } /* fall through */ case PROTOCOL_COMMAND_VAR: if (!LiteralAccessControl(ctx, recvbuffer, conn, encrypted)) { Log(LOG_LEVEL_INFO, "Literal access failure"); RefuseAccess(conn, recvbuffer); return false; } GetServerLiteral(ctx, conn, sendbuffer, recvbuffer, encrypted); return true; case PROTOCOL_COMMAND_CONTEXT_SECURE: sscanf(recvbuffer, "SCONTEXT %u", &len); if ((len >= sizeof(out)) || ((unsigned int) received != (len + CF_PROTO_OFFSET))) { Log(LOG_LEVEL_INFO, "Decrypt error SCONTEXT, len,received = %d,%d", len, received); RefuseAccess(conn, "decrypt error SCONTEXT"); return true; } memcpy(out, recvbuffer + CF_PROTO_OFFSET, len); plainlen = DecryptString(recvbuffer, sizeof(recvbuffer), out, len, conn->encryption_type, conn->session_key); encrypted = true; if (strncmp(recvbuffer, "CONTEXT", 7) != 0) { Log(LOG_LEVEL_INFO, "CONTEXT protocol defect..."); RefuseAccess(conn, "Decryption failed?"); return false; } /* fall through */ case PROTOCOL_COMMAND_CONTEXT: if ((classes = ContextAccessControl(ctx, recvbuffer, conn, encrypted)) == NULL) { Log(LOG_LEVEL_INFO, "Context access failure on %s", recvbuffer); RefuseAccess(conn, recvbuffer); return false; } ReplyServerContext(conn, encrypted, classes); return true; case PROTOCOL_COMMAND_QUERY_SECURE: sscanf(recvbuffer, "SQUERY %u", &len); if ((len >= sizeof(out)) || ((unsigned int) received != (len + CF_PROTO_OFFSET))) { Log(LOG_LEVEL_INFO, "Decrypt error SQUERY"); RefuseAccess(conn, "decrypt error SQUERY"); return true; } memcpy(out, recvbuffer + CF_PROTO_OFFSET, len); plainlen = DecryptString(recvbuffer, sizeof(recvbuffer), out, len, conn->encryption_type, conn->session_key); if (strncmp(recvbuffer, "QUERY", 5) != 0) { Log(LOG_LEVEL_INFO, "QUERY protocol defect"); RefuseAccess(conn, "decryption failure"); return false; } if (!LiteralAccessControl(ctx, recvbuffer, conn, true)) { Log(LOG_LEVEL_INFO, "Query access failure"); RefuseAccess(conn, recvbuffer); return false; } if (GetServerQuery(conn, recvbuffer, true)) /* always encrypt */ { return true; } break; case PROTOCOL_COMMAND_CALL_ME_BACK: sscanf(recvbuffer, "SCALLBACK %u", &len); if ((len >= sizeof(out)) || ((unsigned int) received != (len + CF_PROTO_OFFSET))) { Log(LOG_LEVEL_INFO, "Decrypt error CALL_ME_BACK"); return true; } memcpy(out, recvbuffer + CF_PROTO_OFFSET, len); plainlen = DecryptString(recvbuffer, sizeof(recvbuffer), out, len, conn->encryption_type, conn->session_key); if (strncmp(recvbuffer, "CALL_ME_BACK collect_calls", strlen("CALL_ME_BACK collect_calls")) != 0) { Log(LOG_LEVEL_INFO, "CALL_ME_BACK protocol defect"); return false; } if (!LiteralAccessControl(ctx, recvbuffer, conn, true)) { Log(LOG_LEVEL_INFO, "Query access failure"); return false; } ReceiveCollectCall(conn); /* On success that returned true; otherwise, it did all * relevant Log()ging. Either way, we're no longer busy with * it and our caller can close the connection: */ return false; case PROTOCOL_COMMAND_AUTH_PLAIN: case PROTOCOL_COMMAND_AUTH_SECURE: case PROTOCOL_COMMAND_AUTH: case PROTOCOL_COMMAND_CONTEXTS: case PROTOCOL_COMMAND_BAD: Log(LOG_LEVEL_WARNING, "Unexpected protocol command"); } strcpy(sendbuffer, "BAD: Request denied"); SendTransaction(conn->conn_info, sendbuffer, 0, CF_DONE); Log(LOG_LEVEL_INFO, "Closing connection due to request: %s", recvbuffer); return false; } cfengine-3.24.2/cf-serverd/cf-serverd-enterprise-stubs.c0000644000000000000000000000724215010704253023140 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include ENTERPRISE_VOID_FUNC_3ARG_DEFINE_STUB(void, RegisterLiteralServerData, ARG_UNUSED EvalContext *, ctx, ARG_UNUSED const char *, handle, ARG_UNUSED const Promise *, pp) { Log(LOG_LEVEL_VERBOSE, "Access to server literals is only available in CFEngine Enterprise"); } ENTERPRISE_FUNC_3ARG_DEFINE_STUB(int, ReturnLiteralData, ARG_UNUSED EvalContext *, ctx, ARG_UNUSED char *, handle, ARG_UNUSED char *, ret) { Log(LOG_LEVEL_VERBOSE, "Access to server literals is only available in CFEngine Enterprise"); return 0; } ENTERPRISE_FUNC_5ARG_DEFINE_STUB(int, SetServerListenState, ARG_UNUSED EvalContext *, ctx, ARG_UNUSED size_t, queue_size, ARG_UNUSED char *, bind_address, ARG_UNUSED bool, server_listen, InitServerFunction, InitServerPtr) { if (!server_listen) { Log(LOG_LEVEL_VERBOSE, "Disable listening on port is only supported in CFEngine Enterprise"); } return InitServerPtr(queue_size, bind_address); } ENTERPRISE_FUNC_1ARG_DEFINE_STUB(bool, ReceiveCollectCall, ARG_UNUSED ServerConnectionState *, conn) { return false; } ENTERPRISE_FUNC_1ARG_DEFINE_STUB(bool, ReturnCookies, ARG_UNUSED ServerConnectionState *, conn) { return false; } ENTERPRISE_FUNC_3ARG_DEFINE_STUB(bool, ReturnQueryData, ARG_UNUSED ServerConnectionState *, conn, ARG_UNUSED char *, menu, ARG_UNUSED int, encrypt) { return false; } ENTERPRISE_FUNC_2ARG_DEFINE_STUB(bool, CFTestD_ReturnQueryData, ARG_UNUSED ServerConnectionState *, conn, ARG_UNUSED char *, menu) { return false; } ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, KeepReportDataSelectAccessPromise, ARG_UNUSED const Promise *, pp) { Log(LOG_LEVEL_ERR, "Report data select is only available in CFEngine Enterprise"); } ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(void, CleanReportBookFilterSet) { return; } ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, CollectCallStart, ARG_UNUSED int, interval) { } ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(void, CollectCallStop) { } ENTERPRISE_FUNC_0ARG_DEFINE_STUB(bool, CollectCallHasPending) { return false; } ENTERPRISE_FUNC_1ARG_DEFINE_STUB(int, CollectCallGetPending, ARG_UNUSED int *, queue_length) { return -1; } ENTERPRISE_VOID_FUNC_0ARG_DEFINE_STUB(void, CollectCallMarkProcessed) { } ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, FprintAvahiCfengineTag, FILE *, fp) { fprintf(fp,"CFEngine Community %s Policy Server on %s \n", Version(), "%h"); } cfengine-3.24.2/AUTHORS0000644000000000000000000001464415010704253014434 0ustar00rootroot00000000000000Authors list ============ The following lists were obtained from `git shortlog`. In case of any errors and omissions please fix them and submit a pull request. In order to fix an e-mail or a name, please adjust .mailmap file in top level directory. Authors (people with more than 10 commits registered), sorted alphabetically: Kristian Amlie Nick Anderson Dimitrios Apostolou Mark Burgess Craig Comstock Ole Herman S. Elgesem Mikhail Gusarov Volker Hilsheimer Maciej Mrowiec Geir Nygård Maciej Patucha Loic Pefferkorn Bryce Petrini Nakarin Phooripoom Vratislav Podzimek Bishwa Shrestha Eystein Måløy Stenberg Sigurd Teigen Shauna Thomas Karl Hole Totland Carlos Manuel Duclos Vergara Bas van der Vlies Lars Erik Wik Diego Zamboni Ted Zlatanov Contributors (people with fewer than 10 commits registered), sorted alphabetically: Trond Hasle Amundsen Cédric Cabessa Matthieu CERDA P. Christeas Jonathan CLARKE Jeramey Crawford Remi Debay dolanor Brian Bennett Franz Bettag Gonéri Le Bouder Bernard Brandl Melinda Fancsal George Gensure hicham Klaus Kämpf Daniel V. Klein jkrabbe Kuba David Lee Matt Lesko Riccardo Murri William Orr Michael V. Pelletier Russ Poyner Frerich Raabe Laurent Raufaste Jean Remond Andrew Stribblehill James Thompson Aleksey Tsalolikhin Neil H Watson yac Copyright ========= The CFEngine 3 design and code is by Northern.tech AS and all rights are reserved. In order to offer commercial support of CFEngine to customers it is important for Northern.tech AS to have an uncomplicated ownership of rights to CFEngine 3 code in future products. For that reason we will require that substantial code contributions (contributions of sufficient size to warrant copyright) be accompanied by a signed transfer of rights form to Northern.tech AS. Such a transfer will not take away any of your freedoms under the GNU public licence, but will guarantee that community contributions can be included in CFEngine's commercial future, without the need to split CFEngine into multiple versions i.e. this allows Northern.tech AS to make money on commercial versions of CFEngine thus supporting future in-house development. ======================================================================== Northern.tech AS Contributor statement The terms stated below apply to your contribution of computer code and other material to software or projects owned or managed by Northern.tech AS ("project"), and set out the intellectual property rights in the contributed material you transfer to CFEngine. If this contribution is on behalf of a company, "you" will also mean the company you identify below. 1. "Material" and "contribution" shall mean any source code, object code, patch, tool, sample, graphic, specification, manual, documentation, or any other code or other material posted or submitted by you to the project or us. 2. Regarding any worldwide copyrights, or copyright applications and registrations, in your contribution: * You hereby assign to us joint ownership, and to the extent that such assignment is or becomes invalid, ineffective or unenforceable, you hereby grant to us a perpetual, irrevocable, non-exclusive, worldwide, no-charge, royalty-free, unrestricted license to exercise all rights under those copyrights. This includes, at our option, the right to sublicense these same rights to third parties through multiple levels of sublicensees or other licensing arrangements; * You agree that each of us can do all things in relation to your contribution as if each of us were the sole right holder, and if one of us makes a derivative work of your contribution, the one who makes the derivative work (or has it made) will be the sole owner of that derivative work, hereunder make, have made, use, sell, offer to sell, import, and otherwise transfer your contribution in whole or in part; * You agree that neither of us has any duty to consult with, obtain the consent of, pay or render an accounting to the other for any use or distribution of the material. 3. If you own or may license any patent without payment to any third party, you hereby grant us a perpetual, irrevocable, non-exclusive, worldwide, no-charge, royalty-free license to use, transfer and otherwise control such material, to the same extent as described above for copyright. 4. You keep all right, title, and interest in your contribution, exempted only as stated above. The rights that you grant to us under these terms are effective on the date you first submitted a contribution to us, even if your submission took place before the date you sign these terms. Any contribution we make available under any license will also be made available under a suitable FSF (Free Software Foundation) or OSI (Open Source Initiative) approved license. 5. With respect to your contribution, you represent that: * it is an original work and that you can legally grant the rights set out in these terms; * it does not to the best of your knowledge violate any third party's copyrights, trademarks, patents, or other intellectual property rights; and * you are authorized to sign this contract on behalf of your company (if identified below). 6. These terms will be governed by the laws of Norway. Legal venue is Oslo, Norway. If available, please list your github.com username(s) and the name of the project(s) (or project website(s)) for which you would like to contribute materials. Your username: Project name (or project website) and nature of contribution: ______________ _____________________________________________________________ ______________ _____________________________________________________________ ______________ _____________________________________________________________ Your contact information (Please print clearly): Your name: _____________________________________________________________________ Your company's name (if relevant): _____________________________________________ Physical mail address: _________________________________________________________ Phone, fax and email address: __________________________________________________ ________________________________________________________________________________ Signature: _____________________________________________________________________ Date: __________________________________________________________________________ To send these terms to us, scan and email the signed agreement as PDF to contact@cfengine.com cfengine-3.24.2/Makefile.in0000644000000000000000000011667015010704300015424 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = configure_flags.env misc/init.d/cfengine3 \ misc/systemd/cfengine3.service misc/systemd/cf-apache.service \ misc/systemd/cf-execd.service misc/systemd/cf-hub.service \ misc/systemd/cf-reactor.service \ misc/systemd/cf-monitord.service \ misc/systemd/cf-postgres.service \ misc/systemd/cf-serverd.service config.post.h CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(docdir)" DATA = $(doc_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/config.post.h.in $(srcdir)/configure_flags.env.in \ $(top_srcdir)/misc/init.d/cfengine3.in \ $(top_srcdir)/misc/systemd/cf-apache.service.in \ $(top_srcdir)/misc/systemd/cf-execd.service.in \ $(top_srcdir)/misc/systemd/cf-hub.service.in \ $(top_srcdir)/misc/systemd/cf-monitord.service.in \ $(top_srcdir)/misc/systemd/cf-postgres.service.in \ $(top_srcdir)/misc/systemd/cf-reactor.service.in \ $(top_srcdir)/misc/systemd/cf-serverd.service.in \ $(top_srcdir)/misc/systemd/cfengine3.service.in AUTHORS \ ChangeLog INSTALL compile config.guess config.sub install-sh \ ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # AUTOMAKE_OPTIONS = foreign MAKEFLAGS = $(if $(filter-out 0,$(V)),,--no-print-directory --quiet) LCOV_FLAGS = $(if $(filter-out 0,$(V)),,-q) SUBDIRS = \ libntech \ libcfecompat \ libcfnet \ libenv \ cf-check \ libpromises \ cf-agent \ cf-execd \ cf-key \ cf-monitord \ cf-promises \ cf-runagent \ cf-serverd \ cf-testd \ cf-upgrade \ cf-net \ cf-secret \ misc \ python \ ext \ examples \ tests \ contrib/vagrant-ci/centos-9s-x64 # Hide the buildsystem's username, at least with GNU tar. TAR_OPTIONS = --owner=0 --group=0 EXTRA_DIST = ChangeLog INSTALL README.md LICENSE CFVERSION doc_DATA = README.md ChangeLog # # Some basic clean ups # MOSTLYCLEANFILES = *~ # # Get everything removed down to where rebuilding requires: # "configure; make; make install" # DISTCLEANFILES = # # Get everything removed down to where rebuilding requires: # "aclocal; autoconf; autoheader; automake --add-missing" # "configure; make; make install" # MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.sub \ configure install-sh missing mkinstalldirs depcomp ylwrap \ ltmain.sh mdate-sh # # Pass proper flags to aclocal to pick up Libtool macros # ACLOCAL_AMFLAGS = -I m4 ################################################################################ # Identical to what is in libpromises/Makefile.am. # This is because there is a circular dependency libcfnet <-> libpromises # so we need to generate it before everything else. ################################################################################ BUILT_SOURCES = \ $(srcdir)/libpromises/enterprise_extension.c \ $(srcdir)/libpromises/enterprise_extension.h V_PERL = $(cf__v_PERL_$(V)) cf__v_PERL_ = $(cf__v_PERL_$(AM_DEFAULT_VERBOSITY)) cf__v_PERL_0 = @echo " PERL " "$@"; cf__v_PERL_1 = V_SED = $(cf__v_SED_$(V)) cf__v_SED_ = $(cf__v_SED_$(AM_DEFAULT_VERBOSITY)) cf__v_SED_0 = @echo " SED " "$@"; cf__v_SED_1 = # # Get everything removed down to where rebuilding requires: # "make; make install" # CLEANFILES = cfengine-lcov-base.info cfengine-lcov.info \ $(BUILT_SOURCES) all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 configure_flags.env: $(top_builddir)/config.status $(srcdir)/configure_flags.env.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/init.d/cfengine3: $(top_builddir)/config.status $(top_srcdir)/misc/init.d/cfengine3.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cfengine3.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cfengine3.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cf-apache.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cf-apache.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cf-execd.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cf-execd.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cf-hub.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cf-hub.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cf-reactor.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cf-reactor.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cf-monitord.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cf-monitord.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cf-postgres.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cf-postgres.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ misc/systemd/cf-serverd.service: $(top_builddir)/config.status $(top_srcdir)/misc/systemd/cf-serverd.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ config.post.h: $(top_builddir)/config.status $(srcdir)/config.post.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(DATA) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-docDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-docDATA .MAKE: $(am__recursive_targets) all check install install-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-data-local install-docDATA install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-docDATA .PRECIOUS: Makefile export TAR_OPTIONS list: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' install-data-local: $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/inputs $(MKDIR_P) -m 755 $(DESTDIR)$(workdir)/modules $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/outputs $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/ppkeys $(MKDIR_P) -m 700 $(DESTDIR)$(workdir)/plugins $(MKDIR_P) -m 750 $(DESTDIR)$(workdir)/state tar-package: pkgdir=`mktemp -d` && export pkgdir && \ origdir=`pwd` && export origdir && \ $(MAKE) DESTDIR=$$pkgdir install && \ ( cd $$pkgdir && \ find . -name '*.cf*' | xargs -n1 chmod go-w && \ tardir=. && \ $(am__tar) | GZIP=$(GZIP_ENV) gzip -c \ > "$$origdir"/$(PACKAGE)-$(VERSION).pkg.tar.gz \ ) ; \ [ x$$pkgdir != x ] && rm -rf $$pkgdir # # Code coverage # clean-coverage: find -L $(srcdir) -name '*.gcda' -delete run-coverage: -$(MAKE) check -k collect-coverage: mkdir -p coverage $(LCOV) $(LCOV_FLAGS) --capture --initial --directory . --output-file coverage/cfengine-lcov-base.info $(LCOV) $(LCOV_FLAGS) --capture --directory . --output-file coverage/lcov.info --test-name CFENGINE --no-checksum --compat-libtool $(LCOV) $(LCOV_FLAGS) -a coverage/cfengine-lcov-base.info -a coverage/lcov.info --output-file coverage/cfengine-lcov.info $(LCOV) $(LCOV_FLAGS) --remove coverage/lcov.info '/usr/include/*' --output-file coverage/lcov.info LANG=C $(LCOV_GENHTML) $(LCOV_FLAGS) --prefix . --output-directory coverage-html --title "CFEngine Code Coverage" --legend --show-details coverage/lcov.info @echo @echo " Code coverage information: file://"`pwd`"/coverage-html/index.html" @echo " Code coverage summary for IDEs: file://"`pwd`"/coverage/lcov.info" @echo coverage: clean-coverage run-coverage collect-coverage $(srcdir)/libpromises/enterprise_extension.c: libpromises/extensions_template.c.pre libpromises/enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/libpromises/enterprise_extension.sed $< > $@ $(srcdir)/libpromises/enterprise_extension.h: libpromises/extensions_template.h.pre libpromises/enterprise_extension.sed $(V_SED) $(SED) -f $(srcdir)/libpromises/enterprise_extension.sed $< > $@ vm-check: $(MAKE) -C contrib/vagrant-ci/centos-9s-x64/ vm-check vm-check-full: $(MAKE) -C contrib/vagrant-ci/centos-9s-x64/ vm-check-full destroy-vms: $(MAKE) -C contrib/vagrant-ci/centos-9s-x64/ destroy-vms static-check: tests/static-check/run.sh static-check-f%: STATIC_CHECKS_FEDORA_VERSION=$* tests/static-check/run.sh # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/install-sh0000755000000000000000000003546315010704300015363 0ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # $RANDOM is not portable (e.g. dash); use it when possible to # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # As "mkdir -p" follows symlinks and we work in /tmp possibly; so # create the $tmpdir first (and fail if unsuccessful) to make sure # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/compile0000755000000000000000000001624515010704300014732 0ustar00rootroot00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/tests/0000755000000000000000000000000015010704323014513 5ustar00rootroot00000000000000cfengine-3.24.2/tests/Makefile.am0000644000000000000000000000204615010704253016553 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # SUBDIRS = unit load acceptance static-check valgrind-check cfengine-3.24.2/tests/static-check/0000755000000000000000000000000015010704323017055 5ustar00rootroot00000000000000cfengine-3.24.2/tests/static-check/Makefile.am0000644000000000000000000000207715010704253021121 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # DISTFILES = cppcheck_suppressions.txt run_checks.sh run.sh Makefile.in Makefile.am cfengine-3.24.2/tests/static-check/run_checks.sh0000755000000000000000000000471515010704253021551 0ustar00rootroot00000000000000#!/bin/bash set -x n_procs="$(getconf _NPROCESSORS_ONLN)" use_procs=$((n_procs/2)) function check_with_gcc() { # previous runs may have cached configuration based on a different CC rm -f config.cache make clean # here --config-cache enables lots of checks in subdir libntech to re-use checks made in core ./configure --config-cache --enable-debug CC=gcc local gcc_exceptions="-Wno-sign-compare -Wno-enum-int-mismatch" make -j -l${use_procs} --keep-going CFLAGS="-Werror -Wall -Wextra $gcc_exceptions" } function check_with_clang() { # previous runs may have cached configuration based on a different CC rm -f config.cache make clean # here --config-cache enables lots of checks in subdir libntech to re-use checks made in core ./configure --config-cache --enable-debug CC=clang make -j -l${use_procs} --keep-going CFLAGS="-Werror -Wall -Wextra -Wno-sign-compare" } function check_with_cppcheck() { # previous runs may have cached configuration based on a different CC rm -f config.cache make clean # here --config-cache enables lots of checks in subdir libntech to re-use checks made in core ./configure --config-cache --enable-debug make -C libpromises/ bootstrap.inc # needed by libpromises/bootstrap.c # print out cppcheck version for comparisons over time in case of regressions due to newer versions cppcheck --version # cppcheck options: # -I -- include paths # -i -- ignored files/folders # --include= -- force including a file, e.g. config.h # Identified issues are printed to stderr cppcheck --quiet -j${use_procs} --error-exitcode=1 ./ \ --suppressions-list=tests/static-check/cppcheck_suppressions.txt \ --check-level=exhaustive \ --include=config.h \ -I cf-serverd/ -I libpromises/ -I libcfnet/ -I libntech/libutils/ \ -i 3rdparty -i .github/codeql -i libntech/.lgtm -i tests -i libpromises/cf3lex.c \ 2>&1 1>/dev/null } cd "$(dirname $0)"/../../ failure=0 failures="" # in jenkins the workdir is already autogen'd # in github it is not, so do that work here if [ ! -f configure ]; then NO_CONFIGURE=1 ./autogen.sh --enable-debug fi check_with_gcc || { failures="${failures}FAIL: GCC check failed\n"; failure=1; } check_with_clang || { failures="${failures}FAIL: Clang check failed\n"; failure=1; } check_with_cppcheck || { failures="${failures}FAIL: cppcheck failed\n"; failure=1; } echo -en "$failures" exit $failure cfengine-3.24.2/tests/static-check/Makefile.in0000644000000000000000000004143715010704301021127 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tests/static-check ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ DISTFILES = cppcheck_suppressions.txt run_checks.sh run.sh Makefile.in Makefile.am all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/static-check/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/static-check/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/static-check/cppcheck_suppressions.txt0000644000000000000000000000252315010704253024237 0ustar00rootroot00000000000000// suppress warnings for access to individual bytes of a uint32 in platform.h objectIndex:libntech/libutils/platform.h // cppcheck is not clever enough to see that if (i >= PLATFORM_CONTEXT_MAX) then 'found' is false arrayIndexOutOfBounds:libenv/sysinfo.c:587 // 'psin' is assigned to 'ai->ai_addr' and 'ai' is returned to the caller memleak:libntech/libcompat/getaddrinfo.c:153 // cppcheck doesn't understand va_copy() properly va_list_usedBeforeStarted:libntech/libcompat/snprintf.c:1505 va_list_usedBeforeStarted:libntech/libcompat/snprintf.c:1506 // too cryptic code for cppcheck to see that the 'tmp' variable is initialized // through a pointer to the same address space (and the same applies to 'dst') uninitvar:libntech/libcompat/inet_pton.c:115 uninitvar:libntech/libcompat/snprintf.c:1494 // cppcheck doesn't like VA_COPY, it seems Uninit:libntech/libcompat/snprintf.c:1505 // cppcheck completely confused by our macro-based enterprise stubs returnDanglingLifetime:libpromises/enterprise_stubs.c:60 returnDanglingLifetime:libpromises/enterprise_stubs.c:121 returnDanglingLifetime:libpromises/enterprise_stubs.c:128 returnDanglingLifetime:libpromises/enterprise_stubs.c:153 returnDanglingLifetime:libpromises/enterprise_stubs.c:159 returnDanglingLifetime:libpromises/enterprise_stubs.c:165 returnDanglingLifetime:libpromises/enterprise_stubs.c:172 cfengine-3.24.2/tests/static-check/run.sh0000755000000000000000000000306315010704253020224 0ustar00rootroot00000000000000#!/bin/bash # Note that this container build requires about 700MB minimum RAM for dnf to operate # use debian-12+ or rhel-8+, debian-11 buildah seems to fail setting up networking/dns for the container so dnf doesn't work (CFE-4295) set -eE # include E so that create_image() failures bubble up to the surface trap "echo FAILURE" ERR if [ -z "$STATIC_CHECKS_FEDORA_VERSION" ]; then default_f_ver="40" echo "No Fedora version for static checks specified, using the default (Fedora $default_f_ver)" BASE_IMG="fedora:$default_f_ver" STATIC_CHECKS_FEDORA_VERSION="$default_f_ver" else BASE_IMG="fedora:$STATIC_CHECKS_FEDORA_VERSION" fi function create_image() { local c=$(buildah from -q $BASE_IMG) buildah run $c -- dnf -q -y install "@C Development Tools and Libraries" clang cppcheck which >/dev/null 2>&1 buildah run $c -- dnf -q -y install pcre-devel pcre2-devel openssl-devel libxml2-devel pam-devel lmdb-devel libacl-devel libyaml-devel curl-devel libvirt-devel >/dev/null 2>&1 buildah run $c -- dnf clean all >/dev/null 2>&1 buildah commit $c cfengine-static-checker-f$STATIC_CHECKS_FEDORA_VERSION >/dev/null 2>&1 echo $c } set -x # TODO: check how old the image is and recreate if it's too old if buildah inspect cfengine-static-checker-f$STATIC_CHECKS_FEDORA_VERSION >/dev/null 2>&1; then c=$(buildah from cfengine-static-checker-f$STATIC_CHECKS_FEDORA_VERSION) else c=$(create_image) fi trap "buildah rm $c >/dev/null" EXIT buildah copy $c "$(dirname $0)/../../" /tmp/core/ >/dev/null 2>&1 buildah run $c /tmp/core/tests/static-check/run_checks.sh cfengine-3.24.2/tests/unit/0000755000000000000000000000000015010704323015472 5ustar00rootroot00000000000000cfengine-3.24.2/tests/unit/solaris_process_test.c0000644000000000000000000000750515010704253022120 0ustar00rootroot00000000000000#include #include #include #include /* * procfs.h is not 64-bit off_t clean, but the only affected structure is * priovec, which we don't use. Hence we may work around #error in sys/procfs.h * by lying that we are not compiling with large file support (while we do). */ #define _FILE_OFFSET_BITS 32 #include int open(const char *filename, int flags, ...) { if (!strcmp(filename, "/proc/1/psinfo")) { return 1; } if (!strcmp(filename, "/proc/1/status")) { return 101; } if (!strcmp(filename, "/proc/2/status")) { return 102; } if (!strcmp(filename, "/proc/3/status")) { return 103; } errno = ENOENT; return -1; } int fdpos[4]; ssize_t read(int fd, void *buf, size_t bufsize) { if (fd == 1) { if (fdpos[0] == 0) { psinfo_t psinfo; psinfo.pr_start.tv_sec = 100; memcpy(buf, &psinfo, sizeof(psinfo)); fdpos[0] = sizeof(psinfo); return sizeof(psinfo); } else { return 0; } } if (fd == 101) { if (fdpos[1] == 0) { pstatus_t pstatus; pstatus.pr_nlwp = 1; pstatus.pr_lwp.pr_flags = PR_STOPPED; pstatus.pr_lwp.pr_why = PR_SIGNALLED; memcpy(buf, &pstatus, sizeof(pstatus)); fdpos[1] = sizeof(pstatus); return sizeof(pstatus); } else { return 0; } } if (fd == 102) { if (fdpos[2] == 0) { pstatus_t pstatus; pstatus.pr_nlwp = 1; pstatus.pr_lwp.pr_flags = 0; pstatus.pr_lwp.pr_why = 0; memcpy(buf, &pstatus, sizeof(pstatus)); fdpos[2] = sizeof(pstatus); return sizeof(pstatus); } else { return 0; } } if (fd == 103) { if (fdpos[3] == 0) { /* Currently this is unused, the test is switched off. */ pstatus_t pstatus; pstatus.pr_nlwp = 0; /* zombie */ memcpy(buf, &pstatus, sizeof(pstatus)); fdpos[3] = sizeof(pstatus); return sizeof(pstatus); } else { return 0; } } errno = EIO; return -1; } int close(int fd) { return 0; } static void test_get_start_time_process1(void) { time_t t = GetProcessStartTime(1); assert_int_equal(t, 100); } static void test_get_start_time_process2(void) { time_t t = GetProcessStartTime(2); assert_int_equal(t, PROCESS_START_TIME_UNKNOWN); } static void test_get_state_process1(void) { ProcessState s = GetProcessState(1); assert_int_equal(s, PROCESS_STATE_STOPPED); } static void test_get_state_process2(void) { ProcessState s = GetProcessState(2); assert_int_equal(s, PROCESS_STATE_RUNNING); } static void test_get_state_process3(void) { ProcessState s = GetProcessState(3); assert_int_equal(s, PROCESS_STATE_ZOMBIE); } static void test_get_state_process4(void) { ProcessState s = GetProcessState(4); assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_get_start_time_process1), unit_test(test_get_start_time_process2), unit_test(test_get_state_process1), unit_test(test_get_state_process2), /* TODO zombie process unit test for solaris is not currently working * because of the huge amount of hacks needed to actually figure out * if a process is zombie, see libpromises/process_solaris.c. */ // unit_test(test_get_state_process3), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/parser_test.c0000644000000000000000000001641215010704253020177 0ustar00rootroot00000000000000#include #include #include /* xsnprintf */ #include static bool TestParsePolicy(const char *filename) { char path[PATH_MAX]; xsnprintf(path, sizeof(path), "%s/%s", TESTDATADIR, filename); Policy *p = ParserParseFile(AGENT_TYPE_COMMON, path, PARSER_WARNING_ALL, PARSER_WARNING_ALL); bool res = (p != NULL); PolicyDestroy(p); return res; } void test_benchmark(void) { assert_true(TestParsePolicy("benchmark.cf")); } void test_no_bundle_or_body_keyword(void) { assert_false(TestParsePolicy("no_bundle_or_body_keyword.cf")); } void test_bundle_invalid_type(void) { assert_false(TestParsePolicy("bundle_invalid_type.cf")); } void test_constraint_ifvarclass_invalid(void) { assert_false(TestParsePolicy("constraint_ifvarclass_invalid.cf")); } void test_bundle_args_invalid_type(void) { assert_false(TestParsePolicy("bundle_args_invalid_type.cf")); } void test_bundle_args_forgot_cp(void) { assert_false(TestParsePolicy("bundle_args_forgot_cp.cf")); } void test_bundle_body_forgot_ob(void) { assert_false(TestParsePolicy("bundle_body_forgot_ob.cf")); } void test_bundle_custom_promise_type(void) { assert_true(TestParsePolicy("bundle_custom_promise_type.cf")); } void test_bundle_body_wrong_promise_type_token(void) { assert_false(TestParsePolicy("bundle_body_wrong_promise_type_token.cf")); } void test_bundle_body_wrong_statement(void) { assert_false(TestParsePolicy("bundle_body_wrong_statement.cf")); } void test_bundle_body_forgot_semicolon(void) { assert_false(TestParsePolicy("bundle_body_forgot_semicolon.cf")); } void test_bundle_body_promiser_statement_contains_colon(void) { assert_false(TestParsePolicy("bundle_body_promiser_statement_contains_colon.cf")); } void test_bundle_body_promiser_statement_missing_assign(void) { assert_false(TestParsePolicy("bundle_body_promiser_statement_missing_assign.cf")); } void test_bundle_body_promisee_missing_arrow(void) { assert_false(TestParsePolicy("bundle_body_promise_missing_arrow.cf")); } void test_bundle_body_promiser_wrong_constraint_token(void) { assert_false(TestParsePolicy("bundle_body_promiser_wrong_constraint_token.cf")); } void test_bundle_body_promiser_unknown_constraint_id(void) { assert_false(TestParsePolicy("bundle_body_promiser_unknown_constraint_id.cf")); } void test_body_edit_line_common_constraints(void) { assert_true(TestParsePolicy("body_edit_line_common_constraints.cf")); } void test_body_edit_xml_common_constraints(void) { assert_true(TestParsePolicy("body_edit_xml_common_constraints.cf")); } void test_promise_promiser_nonscalar(void) { assert_false(TestParsePolicy("promise_promiser_nonscalar.cf")); } void test_bundle_body_promiser_forgot_colon(void) { assert_false(TestParsePolicy("bundle_body_promiser_forgot_colon.cf")); } void test_bundle_body_promisee_no_colon_allowed(void) { assert_false(TestParsePolicy("bundle_body_promisee_no_colon_allowed.cf")); } void test_bundle_body_forget_cb_eof(void) { assert_false(TestParsePolicy("bundle_body_forget_cb_eof.cf")); } void test_bundle_body_forget_cb_body(void) { assert_false(TestParsePolicy("bundle_body_forget_cb_body.cf")); } void test_bundle_body_forget_cb_bundle(void) { assert_false(TestParsePolicy("bundle_body_forget_cb_bundle.cf")); } void test_body_selection_wrong_token(void) { assert_false(TestParsePolicy("body_selection_wrong_token.cf")); } void test_body_selection_forgot_semicolon(void) { assert_false(TestParsePolicy("body_selection_forgot_semicolon.cf")); } void test_body_selection_unknown_selection_id(void) { assert_false(TestParsePolicy("body_selection_unknown_selection_id.cf")); } void test_body_body_forget_cb_eof(void) { assert_false(TestParsePolicy("body_body_forget_cb_eof.cf")); } void test_body_body_forget_cb_body(void) { assert_false(TestParsePolicy("body_body_forget_cb_body.cf")); } void test_body_body_forget_cb_bundle(void) { assert_false(TestParsePolicy("body_body_forget_cb_bundle.cf")); } void test_rval_list_forgot_colon(void) { assert_false(TestParsePolicy("rval_list_forgot_colon.cf")); } void test_rval_list_wrong_input_type(void) { assert_false(TestParsePolicy("rval_list_wrong_input_type.cf")); } void test_rval_function_forgot_colon(void) { assert_false(TestParsePolicy("rval_function_forgot_colon.cf")); } void test_rval_function_wrong_input_type(void) { assert_false(TestParsePolicy("rval_function_wrong_input_type.cf")); } void test_rval_wrong_input_type(void) { assert_false(TestParsePolicy("rval_wrong_input_type.cf")); } void test_rval_list_forgot_cb_semicolon(void) { assert_false(TestParsePolicy("rval_list_forgot_cb_semicolon.cf")); } void test_rval_list_forgot_cb_colon(void) { assert_false(TestParsePolicy("rval_list_forgot_cb_colon.cf")); } void test_rval_function_forgot_cp_semicolon(void) { assert_false(TestParsePolicy("rval_function_forgot_cp_semicolon.cf")); } void test_rval_function_forgot_cp_colon(void) { assert_false(TestParsePolicy("rval_function_forgot_cp_colon.cf")); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_benchmark), unit_test(test_bundle_invalid_type), unit_test(test_bundle_args_invalid_type), unit_test(test_bundle_args_forgot_cp), unit_test(test_bundle_body_forgot_ob), unit_test(test_bundle_custom_promise_type), unit_test(test_bundle_body_wrong_promise_type_token), unit_test(test_bundle_body_wrong_statement), unit_test(test_bundle_body_forgot_semicolon), unit_test(test_bundle_body_promiser_statement_contains_colon), unit_test(test_bundle_body_promiser_statement_missing_assign), unit_test(test_bundle_body_promiser_wrong_constraint_token), unit_test(test_bundle_body_promiser_unknown_constraint_id), unit_test(test_bundle_body_promiser_forgot_colon), unit_test(test_bundle_body_promisee_no_colon_allowed), unit_test(test_bundle_body_forget_cb_eof), unit_test(test_bundle_body_forget_cb_body), unit_test(test_bundle_body_forget_cb_bundle), unit_test(test_body_edit_line_common_constraints), unit_test(test_body_edit_xml_common_constraints), unit_test(test_bundle_body_promisee_missing_arrow), unit_test(test_body_selection_wrong_token), unit_test(test_body_selection_forgot_semicolon), unit_test(test_body_selection_unknown_selection_id), unit_test(test_body_body_forget_cb_eof), unit_test(test_body_body_forget_cb_body), unit_test(test_body_body_forget_cb_bundle), unit_test(test_promise_promiser_nonscalar), unit_test(test_constraint_ifvarclass_invalid), unit_test(test_rval_list_forgot_colon), unit_test(test_rval_list_wrong_input_type), unit_test(test_rval_list_forgot_cb_semicolon), unit_test(test_rval_list_forgot_cb_colon), unit_test(test_rval_function_forgot_colon), unit_test(test_rval_function_wrong_input_type), unit_test(test_rval_function_forgot_cp_semicolon), unit_test(test_rval_function_forgot_cp_colon), unit_test(test_rval_wrong_input_type), unit_test(test_no_bundle_or_body_keyword) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/logging_test.c0000644000000000000000000000711015010704253020324 0ustar00rootroot00000000000000#include #include #include #include #include // This test uses syslog_client.c directly, without libpromises, // this is necessary so we don't get "undefined symbol" errors: char VFQNAME[CF_MAXVARSIZE]; static struct sockaddr *got_address; #if SENDTO_RETURNS_SSIZE_T > 0 ssize_t sendto(ARG_UNUSED int sockfd, ARG_UNUSED const void *buf, size_t len, ARG_UNUSED int flags, const struct sockaddr *dest_addr, ARG_UNUSED socklen_t addrlen) { free(got_address); // RemoteSysLog can call this multiple times got_address = xmemdup(dest_addr, sizeof(struct sockaddr_in)); return len; } #else /* * We might be naives by thinking that size_t, socklen_t and such are the same size as int. * Given that we are not using them here, we can live with that assumption. */ int sendto(ARG_UNUSED int sockfd, ARG_UNUSED const void *buf, int len, ARG_UNUSED int flags, const void *dest_addr, ARG_UNUSED int addrlen) { free(got_address); // RemoteSysLog can call this multiple times got_address = xmemdup(dest_addr, sizeof(struct sockaddr_in)); return len; } #endif // SENDTO_RETURNS_SSIZE_T > 0 static void test_set_port(void) { SetSyslogPort(5678); RemoteSysLog(LOG_EMERG, "Test string"); if (got_address->sa_family == AF_INET) { assert_int_equal(ntohs(((struct sockaddr_in *) got_address)->sin_port), 5678); } else if (got_address->sa_family == AF_INET6) { assert_int_equal(ntohs(((struct sockaddr_in6 *) got_address)->sin6_port), 5678); } free(got_address); got_address = NULL; // Safe to free(NULL) in another test } static void test_set_host(void) { SetSyslogHost("127.0.0.55"); RemoteSysLog(LOG_EMERG, "Test string"); assert_int_equal(got_address->sa_family, AF_INET); assert_int_equal(ntohl(((struct sockaddr_in *) got_address)->sin_addr.s_addr), 0x7f000037); free(got_address); got_address = NULL; // Safe to free(NULL) in another test } #define check_level(str, lvl) \ {\ assert_int_equal(LogLevelFromString(str), lvl);\ assert_true(StringEqual_IgnoreCase(str, LogLevelToString(lvl)));\ } static void test_log_level(void) { check_level("CRITICAL", LOG_LEVEL_CRIT); check_level("Error", LOG_LEVEL_ERR); check_level("warning", LOG_LEVEL_WARNING); check_level("notice", LOG_LEVEL_NOTICE); check_level("info", LOG_LEVEL_INFO); check_level("verbose", LOG_LEVEL_VERBOSE); check_level("debug", LOG_LEVEL_DEBUG); // LogLevelFromString should accept half typed strings: assert_int_equal(LogLevelFromString("CRIT"), LOG_LEVEL_CRIT); assert_int_equal(LogLevelFromString("ERR"), LOG_LEVEL_ERR); assert_int_equal(LogLevelFromString("warn"), LOG_LEVEL_WARNING); assert_int_equal(LogLevelFromString("I"), LOG_LEVEL_INFO); assert_int_equal(LogLevelFromString("i"), LOG_LEVEL_INFO); assert_int_equal(LogLevelFromString("information"), LOG_LEVEL_INFO); assert_int_equal(LogLevelFromString("v"), LOG_LEVEL_VERBOSE); //LogLevelFromString should return NOTHING in case of error: assert_int_equal(LogLevelFromString(""), LOG_LEVEL_NOTHING); assert_int_equal(LogLevelFromString("IX"), LOG_LEVEL_NOTHING); assert_int_equal(LogLevelFromString("Infotmation"), LOG_LEVEL_NOTHING); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_set_port), unit_test(test_set_host), unit_test(test_log_level), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/syntax_test.c0000644000000000000000000001455415010704253020236 0ustar00rootroot00000000000000#include #include #include /* StringMatchFull */ static void test_lookup_promise_type_agent_vars(void) { const PromiseTypeSyntax *s = PromiseTypeSyntaxGet("agent", "vars"); assert_true(s); assert_string_equal("vars", s->promise_type); } static void test_lookup_promise_type_common_vars(void) { const PromiseTypeSyntax *s = PromiseTypeSyntaxGet("common", "vars"); assert_true(s); assert_string_equal("vars", s->promise_type); } static void test_lookup_promise_type_edit_xml_build_xpath(void) { const PromiseTypeSyntax *s = PromiseTypeSyntaxGet("edit_xml", "build_xpath"); assert_true(s); assert_string_equal("build_xpath", s->promise_type); } static void test_lookup_promise_type_edit_line_delete_lines(void) { const PromiseTypeSyntax *s = PromiseTypeSyntaxGet("edit_line", "delete_lines"); assert_true(s); assert_string_equal("delete_lines", s->promise_type); } static void test_lookup_promise_type_edit_xml_commons(void) { const PromiseTypeSyntax *s = PromiseTypeSyntaxGet("edit_xml", "*"); assert_true(s); assert_string_equal("edit_xml", s->bundle_type); assert_string_equal("*", s->promise_type); } static void test_lookup_promise_type_global_commons(void) { const PromiseTypeSyntax *s = PromiseTypeSyntaxGet("*", "*"); assert_true(s); assert_string_equal("*", s->bundle_type); assert_string_equal("*", s->promise_type); } static void test_lookup_constraint_edit_xml_set_attribute_attribute_value(void) { const PromiseTypeSyntax *s = PromiseTypeSyntaxGet("edit_xml", "set_attribute"); assert_true(s); assert_string_equal("set_attribute", s->promise_type); const ConstraintSyntax *x = PromiseTypeSyntaxGetConstraintSyntax(s, "attribute_value"); assert_true(x); assert_string_equal("attribute_value", x->lval); } static void test_lookup_body_classes(void) { const BodySyntax *x = BodySyntaxGet(PARSER_BLOCK_BODY, "classes"); assert_true(x); const ConstraintSyntax *y = BodySyntaxGetConstraintSyntax(x->constraints, "promise_repaired"); assert_true(y); assert_string_equal("promise_repaired", y->lval); } static void test_lookup_body_process_count(void) { const BodySyntax *x = BodySyntaxGet(PARSER_BLOCK_BODY, "process_count"); assert_true(x); const ConstraintSyntax *y = BodySyntaxGetConstraintSyntax(x->constraints, "match_range"); assert_true(y); assert_string_equal("match_range", y->lval); } static void test_lookup_body_delete_select(void) { const BodySyntax *x = BodySyntaxGet(PARSER_BLOCK_BODY, "delete_select"); assert_true(x); const ConstraintSyntax *y = BodySyntaxGetConstraintSyntax(x->constraints, "delete_if_startwith_from_list"); assert_true(y); assert_string_equal("delete_if_startwith_from_list", y->lval); } static void test_copy_from_servers(void) { const BodySyntax *x = BodySyntaxGet(PARSER_BLOCK_BODY, "copy_from"); assert_true(x); const ConstraintSyntax *y = BodySyntaxGetConstraintSyntax(x->constraints, "servers"); assert_true(y); assert_true(StringMatchFull(y->range.validation_string, "127.0.0.1")); assert_true(StringMatchFull(y->range.validation_string, "www-dashed.stuff.com")); assert_true(StringMatchFull(y->range.validation_string, "2604:2000:8441:e300:224:d7ff:fec5:338")); } static void test_typecheck_null_rval(void) { SyntaxTypeMatch err = CheckConstraintTypeMatch("whatever", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, CF_DATA_TYPE_STRING, "abc", 0); assert_int_equal(SYNTAX_TYPE_MATCH_ERROR_GOT_NULL, err); } static void test_check_parse_variable_name(void) { // Test was added after function // It shows what it actually does (not what was intended) // Allowed variable "names": assert_true(CheckParseVariableName("a")); assert_true(CheckParseVariableName("myvar")); assert_true(CheckParseVariableName("SuperCaliFragilisticExpialidocius")); assert_true(CheckParseVariableName("a.b")); assert_true(CheckParseVariableName("a[b]")); assert_true(CheckParseVariableName("a[b.c]")); assert_true(CheckParseVariableName("a[b.c.d]")); assert_true(CheckParseVariableName("a.b[c.d.e]")); assert_true(CheckParseVariableName("a.b[c.d.e]")); assert_true(CheckParseVariableName("Namespace.var[$(ns.expand)]")); // Not allowed: assert_false(CheckParseVariableName("a.b.c")); assert_false(CheckParseVariableName("abc.def.ghi")); assert_false(CheckParseVariableName(".a")); assert_false(CheckParseVariableName("a.")); assert_false(CheckParseVariableName(".abc")); assert_false(CheckParseVariableName("abc.")); // Reserved: assert_false(CheckParseVariableName("promiser")); assert_false(CheckParseVariableName("handle")); assert_false(CheckParseVariableName("promise_filename")); assert_false(CheckParseVariableName("promise_dirname")); assert_false(CheckParseVariableName("promise_linenumber")); assert_false(CheckParseVariableName("this")); // Edge cases, allowed: assert_true(CheckParseVariableName("")); assert_true(CheckParseVariableName(" ")); assert_true(CheckParseVariableName(" ")); assert_true(CheckParseVariableName("\t")); assert_true(CheckParseVariableName("a[")); assert_true(CheckParseVariableName("a.[")); // Edge cases, not allowed: assert_false(CheckParseVariableName(".")); assert_false(CheckParseVariableName("...")); assert_false(CheckParseVariableName(".[]")); assert_false(CheckParseVariableName(".[][]")); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_lookup_promise_type_agent_vars), unit_test(test_lookup_promise_type_common_vars), unit_test(test_lookup_promise_type_edit_xml_build_xpath), unit_test(test_lookup_promise_type_edit_line_delete_lines), unit_test(test_lookup_promise_type_edit_xml_commons), unit_test(test_lookup_promise_type_global_commons), unit_test(test_lookup_body_classes), unit_test(test_lookup_body_process_count), unit_test(test_lookup_body_delete_select), unit_test(test_lookup_constraint_edit_xml_set_attribute_attribute_value), unit_test(test_copy_from_servers), unit_test(test_typecheck_null_rval), unit_test(test_check_parse_variable_name), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/item_lib_test.c0000644000000000000000000000307615010704253020471 0ustar00rootroot00000000000000#include #include #include /* FIXME: MatchRegion is now internal function of cf-agent */ #if 0 static void test_match_region(void) { EvalContext *ctx =EvalContextNew(); Item *items = NULL; Item *begin, *end; PrependItem(&items, "third", NULL); assert_true(MatchRegion(ctx, "third", items, NULL, false)); end = items; PrependItem(&items, "second", NULL); PrependItem(&items, "first", NULL); begin = items; assert_true(MatchRegion(ctx, "first", begin, end, false)); assert_false(MatchRegion(ctx, "second", begin, end, false)); assert_false(MatchRegion(ctx, "third", begin, end, false)); assert_true(MatchRegion(ctx, "first\nsecond", begin, end, false)); assert_false(MatchRegion(ctx, "first\nthird", begin, end, false)); assert_false(MatchRegion(ctx, "second\nthird", begin, end, false)); assert_false(MatchRegion(ctx, "first\nsecond\nthird", begin, end, false)); assert_true(MatchRegion(ctx, "first", begin, NULL, false)); assert_false(MatchRegion(ctx, "second", begin, NULL, false)); assert_false(MatchRegion(ctx, "third", begin, NULL, false)); assert_true(MatchRegion(ctx, "first\nsecond", begin, NULL, false)); assert_false(MatchRegion(ctx, "first\nthird", begin, NULL, false)); assert_false(MatchRegion(ctx, "second\nthird", begin, NULL, false)); assert_true(MatchRegion(ctx, "first\nsecond\nthird", begin, NULL, false)); } #endif int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { }; return run_tests(tests); } // STUBS cfengine-3.24.2/tests/unit/Makefile.am0000644000000000000000000003107115010704253017532 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Just recursively include in dist tarball all data we need for unit tests EXTRA_DIST = data AM_CPPFLAGS = $(CORE_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) \ -I$(srcdir)/../../libcfecompat \ -I$(srcdir)/../../libcfnet \ -I$(srcdir)/../../libenv \ -I$(srcdir)/../../libpromises \ -I$(srcdir)/../../libntech/libutils \ -I$(srcdir)/../../cf-monitord \ -I$(srcdir)/../../cf-serverd \ -I$(srcdir)/../../cf-agent \ -I$(srcdir)/../../cf-execd \ -I$(srcdir)/../../cf-key \ -I$(srcdir)/../../cf-check \ -DTESTDATADIR='"$(srcdir)/data"' LDADD = ../../libpromises/libpromises.la libtest.la # automake does not support "maude_LIBS" variables. We can only alter # the generic LIBS one. In case the functions are mocked in the test # implementation, then we are pretty sure that they will be overriden by # our local implementation. So we include *everything*... LIBS = $(CORE_LIBS) AM_LDFLAGS = $(CORE_LDFLAGS) AM_CFLAGS = $(PTHREAD_CFLAGS) check_LTLIBRARIES = libtest.la libtest_la_SOURCES = cmockery.c cmockery.h schema.h test.c test.h libtest_la_LIBADD = ../../libntech/libcompat/libcompat.la check_LTLIBRARIES += libstr.la libstr_la_SOURCES = \ ../../libntech/libutils/buffer.c \ ../../libntech/libutils/encode.c \ ../../libntech/libutils/logging.c \ ../../libntech/libutils/misc_lib.c \ ../../libntech/libutils/regex.c \ ../../libntech/libutils/sequence.c \ ../../libntech/libutils/string_lib.c \ ../../libntech/libutils/writer.c libstr_la_LIBADD = libtest.la check_LTLIBRARIES += libdb.la libdb_la_SOURCES = db_stubs.c \ ../../libpromises/dbm_api.c \ ../../libpromises/dbm_quick.c \ ../../libpromises/dbm_tokyocab.c \ ../../libpromises/dbm_lmdb.c \ ../../libpromises/dbm_migration.c \ ../../libpromises/dbm_migration_lastseen.c \ ../../libpromises/global_mutex.c \ ../../cf-check/backup.c \ ../../cf-check/diagnose.c \ ../../cf-check/lmdump.c \ ../../cf-check/repair.c \ ../../cf-check/replicate_lmdb.c \ ../../cf-check/utilities.c \ ../../cf-check/validate.c \ ../../libntech/libutils/logging.c \ ../../libntech/libutils/mutex.c \ ../../libntech/libutils/cleanup.c if HPUX libdb_la_SOURCES += ../../libpromises/cf3globals.c endif libdb_la_LIBADD = libstr.la ../../libntech/libutils/libutils.la #libdb_la_CPPFLAGS = $(LMDB_CPPFLAGS) $(TOKYOCABINET_CPPFLAGS) $(QDBM_CPPFLAGS) # Make sure that source files are compiled to separate object files # libdb_la-file.o libdb_la_CFLAGS = $(AM_CFLAGS) check_PROGRAMS = \ processes_select_test \ arg_split_test \ assoc_test \ getopt_test \ item_test \ rlist_test \ domainname_test \ set_domainname_test \ evalfunction_test \ eval_context_test \ regex_test \ lastseen_test \ lastseen_migration_test \ changes_migration_test \ db_test \ db_concurrent_test \ item_lib_test \ crypto_symmetric_test \ persistent_lock_test \ package_versions_compare_test \ files_lib_test \ files_copy_test \ parsemode_test \ parser_test \ passopenfile_test \ policy_test \ sort_test \ file_name_test \ logging_test \ granules_test \ scope_test \ conversion_test \ files_interfaces_test \ connection_management_test \ expand_test \ string_expressions_test \ var_expressions_test \ process_terminate_unix_test \ process_test \ exec-config-test \ generic_agent_test \ syntax_test \ sysinfo_test \ variable_test \ verify_databases_test \ protocol_test \ mon_cpu_test \ mon_load_test \ mon_processes_test \ mustache_test \ class_test \ key_test \ cf_upgrade_test \ matching_test \ strlist_test \ addr_lib_test \ policy_server_test \ split_process_line_test \ new_packages_promise_test \ iteration_test if HAVE_AVAHI_CLIENT if HAVE_AVAHI_COMMON check_PROGRAMS += \ findhub_test \ avahi_config_test endif endif if !NT check_PROGRAMS += redirection_test noinst_PROGRAMS = redirection_test_stub redirection_test_stub_SOURCES = redirection_test_stub.c endif check_SCRIPTS = dynamic_dependency_test.sh \ tar_portability_test.sh if WITH_INIT_D_SCRIPT check_SCRIPTS += init_script_test.sh endif EXTRA_DIST += $(check_SCRIPTS) TESTS = $(check_PROGRAMS) $(check_SCRIPTS) if MACOSX XFAIL_TESTS = set_domainname_test XFAIL_TESTS += process_test XFAIL_TESTS += mon_processes_test XFAIL_TESTS += rlist_test endif if AIX XFAIL_TESTS = rlist_test endif if HPUX XFAIL_TESTS = mon_load_test # Redmine #3569 endif processes_select_test_SOURCES = processes_select_test.c processes_select_test_LDADD = libtest.la ../../libpromises/libpromises.la # # OS X uses real system calls instead of our stubs unless this option is used # TESTS_ENVIRONMENT = DYLD_FORCE_FLAT_NAMESPACE=yes conversion_test_SOURCES = conversion_test.c ../../libpromises/conversion.c if !BUILTIN_EXTENSIONS check_PROGRAMS += enterprise_extension_test enterprise_extension_test_SOURCES = enterprise_extension_test.c check_LTLIBRARIES += cfengine-enterprise.la cfengine_enterprise_la_SOURCES = enterprise_extension_test_lib.c cfengine_enterprise_la_LDFLAGS = $(AM_LDFLAGS) \ -avoid-version -module -shared -export-dynamic -rpath / EXTRA_enterprise_extension_test_DEPENDENCIES = cfengine-enterprise.la endif set_domainname_test_SOURCES = set_domainname_test.c set_domainname_test_LDADD = libstr.la ../../libpromises/libpromises.la str_test_SOURCES = str_test.c str_test_LDADD = libstr.la regex_test_SOURCES = regex_test.c ../../libpromises/match_scope.c protocol_test_SOURCES = protocol_test.c \ ../../cf-serverd/server_common.c \ ../../cf-serverd/server_tls.c \ ../../cf-serverd/server.c \ ../../cf-serverd/cf-serverd-enterprise-stubs.c \ ../../cf-serverd/server_transform.c \ ../../cf-serverd/cf-serverd-functions.c \ ../../cf-serverd/server_access.c \ ../../cf-serverd/strlist.c protocol_test_LDADD = ../../libpromises/libpromises.la libtest.la if HAVE_AVAHI_CLIENT if HAVE_AVAHI_COMMON findhub_test_SOURCES = findhub_test.c \ ../../cf-agent/findhub.c \ ../../cf-agent/load_avahi.c avahi_config_test_SOURCES = avahi_config_test.c \ ../../cf-serverd/server_common.c \ ../../cf-serverd/server_tls.c \ ../../cf-serverd/server.c \ ../../cf-serverd/server_transform.c \ ../../cf-serverd/cf-serverd-enterprise-stubs.c \ ../../cf-serverd/server_access.c \ ../../cf-serverd/server_classic.c \ ../../cf-serverd/strlist.c avahi_config_test_LDADD = ../../libpromises/libpromises.la libtest.la endif endif db_test_SOURCES = db_test.c db_test_LDADD = libtest.la ../../libpromises/libpromises.la db_concurrent_test_SOURCES = db_concurrent_test.c #db_concurrent_test_CPPFLAGS = $(libdb_la_CPPFLAGS) db_concurrent_test_LDADD = libdb.la lastseen_test_SOURCES = lastseen_test.c \ ../../libntech/libutils/statistics.c #lastseen_test_CPPFLAGS = $(libdb_la_CPPFLAGS) lastseen_test_LDADD = libtest.la ../../libpromises/libpromises.la lastseen_migration_test_SOURCES = lastseen_migration_test.c #lastseen_migration_test_CPPFLAGS = $(libdb_la_CPPFLAGS) lastseen_migration_test_LDADD = ../../libpromises/libpromises.la CLEANFILES = *.gcno *.gcda cfengine-enterprise.so package_versions_compare_test_SOURCES = package_versions_compare_test.c \ ../../cf-agent/package_module.c \ ../../cf-agent/verify_packages.c \ ../../cf-agent/verify_new_packages.c \ ../../cf-agent/vercmp.c \ ../../cf-agent/vercmp_internal.c \ ../../cf-agent/retcode.c \ ../../libpromises/match_scope.c #package_versions_compare_test_CPPFLAGS = $(AM_CPPFLAGS) package_versions_compare_test_LDADD = ../../libpromises/libpromises.la \ libtest.la files_copy_test_SOURCES = files_copy_test.c files_copy_test_LDADD = libtest.la ../../libpromises/libpromises.la sort_test_SOURCES = sort_test.c sort_test_LDADD = libtest.la ../../libpromises/libpromises.la logging_test_SOURCES = logging_test.c \ ../../libpromises/syslog_client.c \ ../../libpromises/patches.c \ ../../libpromises/constants.c logging_test_LDADD = libtest.la ../../libntech/libutils/libutils.la connection_management_test_SOURCES = connection_management_test.c \ ../../cf-serverd/server_common.c \ ../../cf-serverd/server_tls.c connection_management_test_LDADD = ../../libpromises/libpromises.la \ libtest.la \ ../../cf-serverd/libcf-serverd.la rlist_test_SOURCES = rlist_test.c rlist_test_LDADD = libtest.la ../../libpromises/libpromises.la # Workaround for object file basename conflicts, search the web for # "automake created with both libtool and without" rlist_test_CPPFLAGS = $(AM_CPPFLAGS) process_test_LDADD = libtest.la ../../libpromises/libpromises.la if LINUX check_PROGRAMS += linux_process_test linux_process_test_SOURCES = linux_process_test.c \ ../../libpromises/process_unix.c \ ../../libpromises/process_linux.c \ ../../libntech/libutils/file_lib.c linux_process_test_LDADD = libtest.la ../../libntech/libutils/libutils.la endif if AIX check_PROGRAMS += aix_process_test # We need to use -Wl,-bexpall when linking tests binaries on AIX # because they provide dummy versions of some standard functions. set_domainname_test_LDFLAGS = -Wl,-bexpall evalfunction_test_LDFLAGS = -Wl,-bexpall aix_process_test_SOURCES = aix_process_test.c \ ../../libpromises/process_unix.c \ ../../libpromises/process_aix.c \ ../../libntech/libutils/file_lib.c aix_process_test_LDADD = libtest.la ../../libntech/libutils/libutils.la endif if SOLARIS check_PROGRAMS += solaris_process_test solaris_process_test_SOURCES = solaris_process_test.c \ ../../libpromises/process_unix.c \ ../../libpromises/process_solaris.c \ ../../libntech/libutils/file_lib.c solaris_process_test_LDADD = libtest.la ../../libntech/libutils/libutils.la endif process_terminate_unix_test_SOURCES = process_terminate_unix_test.c \ ../../libpromises/process_unix.c process_terminate_unix_test_LDADD = libtest.la ../../libntech/libutils/libutils.la exec_config_test_SOURCES = exec-config-test.c \ ../../cf-execd/exec-config.c ../../cf-execd/execd-config.c exec_config_test_LDADD = libtest.la ../../libpromises/libpromises.la sysinfo_test_LDADD = libtest.la \ ../../libenv/libenv.la \ ../../libpromises/libpromises.la mon_cpu_test_SOURCES = mon_cpu_test.c \ ../../cf-monitord/mon.h \ ../../cf-monitord/mon_cpu.c mon_cpu_test_LDADD = ../../libpromises/libpromises.la libtest.la mon_load_test_SOURCES = mon_load_test.c \ ../../cf-monitord/mon.h \ ../../cf-monitord/mon_load.c mon_load_test_LDADD = ../../libpromises/libpromises.la libtest.la mon_processes_test_SOURCES = mon_processes_test.c \ ../../cf-monitord/mon.h \ ../../cf-monitord/mon_processes.c mon_processes_test_LDADD = ../../libpromises/libpromises.la libtest.la key_test_SOURCES = key_test.c key_test_LDADD = ../../libpromises/libpromises.la \ ../../libntech/libutils/libutils.la \ libtest.la strlist_test_SOURCES = strlist_test.c \ ../../cf-serverd/strlist.c \ ../../cf-serverd/strlist.h verify_databases_test_LDADD = ../../cf-agent/libcf-agent.la libtest.la iteration_test_SOURCES = iteration_test.c cf_upgrade_test_SOURCES = cf_upgrade_test.c \ $(top_srcdir)/cf-upgrade/alloc-mini.c \ $(top_srcdir)/cf-upgrade/alloc-mini.h \ $(top_srcdir)/cf-upgrade/command_line.c \ $(top_srcdir)/cf-upgrade/command_line.h \ $(top_srcdir)/cf-upgrade/configuration.c \ $(top_srcdir)/cf-upgrade/configuration.h \ $(top_srcdir)/cf-upgrade/log.c $(top_srcdir)/cf-upgrade/log.h \ $(top_srcdir)/cf-upgrade/process.c $(top_srcdir)/cf-upgrade/process.h \ $(top_srcdir)/cf-upgrade/update.c \ $(top_srcdir)/cf-upgrade/update.h cf_upgrade_test_CPPFLAGS = -I$(top_srcdir)/cf-upgrade -I$(top_srcdir)/libntech/libutils -I$(top_srcdir) cf_upgrade_test_LDADD = libtest.la ../../libntech/libcompat/libcompat.la if !NT check_PROGRAMS += nfs_test nfs_test_SOURCES = nfs_test.c nfs_test_LDADD = ../../libpromises/libpromises.la libtest.la init_script_test_helper_SOURCES = init_script_test_helper.c init_script_test.sh: init_script_test_helper CLEANFILES += init_script_test_helper endif EXTRA_DIST += init_script_test_helper.c EXTRA_DIST += init_script_test.sh cfengine-3.24.2/tests/unit/files_interfaces_test.c0000644000000000000000000000472015010704253022207 0ustar00rootroot00000000000000#include #include #include /* xsnprintf */ #include // CfReadLine() #define FILE_SIZE (sizeof(FILE_CONTENTS) - 1) #define FILE_LINE "some garbage!" #define FILE_CORRUPTED_LINE "some \0 , gar\0bage!" #define LINE_SIZE (sizeof(FILE_LINE) - 1) char CFWORKDIR[CF_BUFSIZE]; char FILE_NAME[CF_BUFSIZE]; char FILE_NAME_CORRUPT[CF_BUFSIZE]; char FILE_NAME_EMPTY[CF_BUFSIZE]; static void tests_setup(void) { xsnprintf(CFWORKDIR, CF_BUFSIZE, "/tmp/files_interfaces_test.XXXXXX"); mkdtemp(CFWORKDIR); xsnprintf(FILE_NAME, CF_BUFSIZE, "%s/cf_files_interfaces_test", CFWORKDIR); xsnprintf(FILE_NAME_CORRUPT, CF_BUFSIZE, "%s/cf_files_interfaces_test_corrupt", CFWORKDIR); xsnprintf(FILE_NAME_EMPTY, CF_BUFSIZE, "%s/cf_files_interfaces_test_empty", CFWORKDIR); } static void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } static void CreateGarbage(const char *filename) { FILE *fh = fopen(filename, "w"); for(int i = 0; i < 10; ++i) { fwrite(FILE_LINE, 14, 1, fh); } fclose(fh); } static void CreateCorruptedGarbage(const char *filename) { FILE *fh = fopen(filename, "w"); for(int i = 0; i < 10; ++i) { fwrite(FILE_CORRUPTED_LINE, 18, 1, fh); } fclose(fh); } static void test_cfreadline_valid(void) { CreateGarbage(FILE_NAME); FILE *fin = fopen(FILE_NAME, "r"); //test with non-empty file and valid file pointer size_t bs = CF_BUFSIZE; char *b = xmalloc(bs); ssize_t read = CfReadLine(&b, &bs, fin); assert_true(read > 0); assert_string_equal(b, FILE_LINE); if (fin) { fclose(fin); } free(b); } static void test_cfreadline_corrupted(void) { CreateCorruptedGarbage(FILE_NAME); FILE *fin = fopen(FILE_NAME, "r"); size_t bs = CF_BUFSIZE; char *b = xmalloc(bs); //test with non-empty file and valid file pointer ssize_t read = CfReadLine(&b, &bs, fin); assert_true(read > 0); assert_string_not_equal(b, FILE_LINE); if (fin) { fclose(fin); } free(b); } int main() { PRINT_TEST_BANNER(); tests_setup(); const UnitTest tests[] = { unit_test(test_cfreadline_valid), unit_test(test_cfreadline_corrupted), }; PRINT_TEST_BANNER(); int ret = run_tests(tests); tests_teardown(); return ret; } cfengine-3.24.2/tests/unit/process_terminate_unix_test.c0000644000000000000000000001571415010704253023500 0ustar00rootroot00000000000000#include #include #include #include /* This mock implements single fake process with a several tunable parameters: - process' start time, - reaction time for STOP/CONT/INT/TERM/KILL signal, - whether SIGINT/SIGTERM are blocked, - does the caller have permission to send signals to fake process This mock also records what signals were delivered to the process to check later. */ /* Settings */ time_t proc_1_start_time; time_t proc_1_reaction_time; bool proc_1_int_blocked; bool proc_1_term_blocked; bool proc_1_have_access; /* State */ time_t current_time; bool exists; bool stopped; time_t signal_time; bool has_stop; bool has_cont; bool has_int; bool has_term; bool has_kill; /* History */ bool was_stopped; int exit_signal; void InitTime(void) { current_time = 1; } void InitFakeProcess(time_t start_time, time_t reaction_time, bool int_blocked, bool term_blocked, bool have_access) { proc_1_start_time = start_time; proc_1_reaction_time = reaction_time; proc_1_int_blocked = int_blocked; proc_1_term_blocked = term_blocked; proc_1_have_access = have_access; exists = true; stopped = false; signal_time = -1; has_stop = false; has_cont = false; has_int = false; has_term = false; has_kill = false; was_stopped = false; exit_signal = 0; } time_t GetProcessStartTime(pid_t pid) { assert_int_equal(pid, 1); if (proc_1_have_access && exists) { return proc_1_start_time; } else { return PROCESS_START_TIME_UNKNOWN; } } ProcessState GetProcessState(pid_t pid) { assert_int_equal(pid, 1); if (!proc_1_have_access || !exists) { return PROCESS_STATE_DOES_NOT_EXIST; } if (stopped) { return PROCESS_STATE_STOPPED; } else { return PROCESS_STATE_RUNNING; } } void FakeProcessDoSignals(void) { /* React immediately to STOP and CONT in order to properly do the * STOP-kill-CONT sequence inside SafeKill(). */ if (has_stop) { stopped = true; was_stopped = true; has_stop = false; } if (has_cont) { stopped = false; has_cont = false; } /* Do NOT react to other signals if it's not the time yet. */ if (current_time < signal_time) { return; } if (has_int) { if (!proc_1_int_blocked) { exists = false; exit_signal = SIGINT; stopped = false; signal_time = -1; } has_int = false; } if (has_term) { if (!proc_1_term_blocked) { exists = false; exit_signal = SIGTERM; stopped = false; signal_time = -1; } has_term = false; } if (has_kill) { exists = false; exit_signal = SIGKILL; stopped = false; signal_time = -1; has_kill = false; } signal_time = -1; } int kill(pid_t pid, int signal) { assert_int_equal(pid, 1); if (!proc_1_have_access) { errno = EPERM; return -1; } if (!exists) { errno = ESRCH; return -1; } if (signal == 0) { return 0; } if (signal_time == -1) { signal_time = current_time + proc_1_reaction_time; } if (signal == SIGSTOP) { has_stop = true; } else if (signal == SIGCONT) { has_cont = true; } else if (signal == SIGINT) { has_int = true; } else if (signal == SIGTERM) { has_term = true; } else if (signal == SIGKILL) { has_kill = true; } else { errno = EINVAL; return -1; } FakeProcessDoSignals(); return 0; } int nanosleep(const struct timespec *req, struct timespec *rem) { time_t sleep_time; /* Simulate EINTR every second time */ static bool got_eintr = false; if (!got_eintr) { got_eintr = true; sleep_time = 2 * req->tv_nsec / 3; } else { got_eintr = false; sleep_time = req->tv_nsec; } time_t next_time = current_time + sleep_time; if (signal_time != -1 && next_time >= signal_time) { FakeProcessDoSignals(); } current_time = next_time; if (got_eintr) { rem->tv_sec = 0; rem->tv_nsec = req->tv_nsec - sleep_time; errno = EINTR; return -1; } else { return 0; } } /* Tests */ void test_kill_simple_process(void) { InitTime(); InitFakeProcess(12345, 100, false, false, true); int res = GracefulTerminate(1, 12345); assert_true(res); FakeProcessDoSignals(); assert_false(exists); assert_int_equal(exit_signal, SIGINT); } void test_kill_wrong_process(void) { InitTime(); InitFakeProcess(66666, 100, false, false, true); int res = GracefulTerminate(1, 12345); assert_false(res); FakeProcessDoSignals(); assert_true(exists); assert_false(stopped); assert_false(was_stopped); /* We should not touch this process at all */ assert_int_equal(signal_time, (time_t)-1); /* No pending signals either */ } void test_kill_long_reacting_signal(void) { /* This process is very slow in reaction. It should not be left stopped though */ InitTime(); InitFakeProcess(12345, 2000000000, false, false, true); int res = GracefulTerminate(1, 12345); assert_true(res); FakeProcessDoSignals(); /* This process is not even reacting to SIGKILL. */ assert_true(exists); } void test_kill_no_sigint(void) { /* This process blocks SIGINT */ InitTime(); InitFakeProcess(12345, 100, true, false, true); int res = GracefulTerminate(1, 12345); assert_true(res); FakeProcessDoSignals(); assert_false(exists); assert_int_equal(exit_signal, SIGTERM); } void test_kill_no_sigint_sigterm(void) { /* This process only can be killed by SIGKILL */ InitTime(); InitFakeProcess(12345, 100, true, true, true); int res = GracefulTerminate(1, 12345); assert_true(res); /* Sleep a bit so that KILL is processed. */ current_time += 100; FakeProcessDoSignals(); assert_false(exists); assert_int_equal(exit_signal, SIGKILL); } void test_kill_anothers_process(void) { /* This process is not owned by killer */ InitTime(); InitFakeProcess(12345, 100, true, true, false); int res = GracefulTerminate(1, 12345); assert_false(res); FakeProcessDoSignals(); assert_true(exists); assert_false(was_stopped); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_kill_simple_process), unit_test(test_kill_wrong_process), unit_test(test_kill_long_reacting_signal), unit_test(test_kill_no_sigint), unit_test(test_kill_no_sigint_sigterm), unit_test(test_kill_anothers_process), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/init_script_test.sh0000755000000000000000000004000415010704253021417 0ustar00rootroot00000000000000#!/bin/sh ################################################################################ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # ################################################################################ ################################################################################ # Test whether the init script correctly starts and kills processes. ################################################################################ # # Detect and replace non-POSIX shell # try_exec() { type "$1" > /dev/null 2>&1 && exec "$@" } broken_posix_shell() { unset foo local foo=1 test "$foo" != "1" } if broken_posix_shell >/dev/null 2>&1 then try_exec /usr/xpg4/bin/sh "$0" "$@" echo "No compatible shell script interpreter found." echo "Please find a POSIX shell for your system." exit 42 fi ################################################################################ # Preparation ################################################################################ export CFTEST_PREFIX=/tmp/init_script_test.sh.$$ # Use alternate binary names to avoid killing actual system processes. export CFTEST_CFEXECD=$CFTEST_PREFIX/bin/cf-test-execd export CFTEST_CFSERVD=$CFTEST_PREFIX/bin/cf-test-serverd export CFTEST_CFMOND=$CFTEST_PREFIX/bin/cf-test-monitord export CFTEST_CFAGENT=$CFTEST_PREFIX/bin/cf-test-agent export OUTFILE=$CFTEST_PREFIX/outfile rm -rf $CFTEST_PREFIX mkdir -p $CFTEST_PREFIX/bin mkdir -p $CFTEST_PREFIX/inputs # CALL OURSELVES AND EXIT. W-H-Y-? if [ "$1" != "sub-invocation" ] then # Redirect to log, and only print if there's an error. if ! sh -x "$0" sub-invocation > $CFTEST_PREFIX/test-output.log 2>&1 then # Sub-invocation FAILED! echo "FAIL: Output from test:" cat $CFTEST_PREFIX/test-output.log exit 1 else # Sub-invocation SUCCESS exit 0 fi fi # Fail on any error. set -e cp init_script_test_helper $CFTEST_PREFIX/bin/cf-test-execd cp init_script_test_helper $CFTEST_PREFIX/bin/cf-test-serverd cp init_script_test_helper $CFTEST_PREFIX/bin/cf-test-monitord cp init_script_test_helper $CFTEST_PREFIX/bin/cf-test-agent touch $CFTEST_PREFIX/inputs/promises.cf if ps --help | egrep -e '--cols\b' > /dev/null then # There is a bug in SUSE which means that ps output will be truncated even # when piped to grep, if the terminal size is small. However using --cols # will override it. PS_OPTIONS="--cols 200" else PS_OPTIONS= fi ################################################################################ # Functions ################################################################################ match_pid() { if [ "$(ps $PS_OPTIONS -ef|grep -v grep|grep "$1"|awk -F' ' '{print $2}')" != "" ] then return 0 # PID found else return 1 # PID not found fi } matching_pid_exists() { if ! match_pid "$1" then echo "FAIL: No such process: $1" return 1 fi } no_matching_pid_exists() { if match_pid "$1" then echo "FAIL: Unexpected process: $1" return 1 fi } # Shortcut to check that no daemons/agents are running. verify_none_running() { # Save some verbosity ( set +x no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-serverd no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-monitord no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-agent ) } # Simply a workaround for the fact that '!' disables error checking with "set # -e". By using it inside this function, the caller preserves error checking. negate() { ! "$@" } ################################################################################ # Test ################################################################################ echo "TEST: Normal starting" ../../misc/init.d/cfengine3 start matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd matching_pid_exists $CFTEST_PREFIX/bin/cf-test-serverd matching_pid_exists $CFTEST_PREFIX/bin/cf-test-monitord echo "TEST: Normal stopping" ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: Stopping when a daemon is missing" $CFTEST_PREFIX/bin/cf-test-execd ../../misc/init.d/cfengine3 stop verify_none_running $CFTEST_PREFIX/bin/cf-test-monitord ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: Stopping daemons and agents" $CFTEST_PREFIX/bin/cf-test-execd --spawn-process $CFTEST_PREFIX/bin cf-test-agent matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: Stopping daemons and an agent launched just at signal time" $CFTEST_PREFIX/bin/cf-test-execd --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-agent ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: Stopping a chain of daemons and agents each spawning each other" $CFTEST_PREFIX/bin/cf-test-execd \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-agent ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: KILLing a bunch of agents and daemons" # Stopping a ludicrously long chain of daemons and agents each spawning each # other. This will test the SIGKILL capacity of the script, since normal killing # won't be enough before the iteration count runs out. $CFTEST_PREFIX/bin/cf-test-execd \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-agent ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: Stopping a daemon that just won't die" $CFTEST_PREFIX/bin/cf-test-execd --refuse-to-die matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: Most extreme case, a long chain of daemons and agents where they all refuse to die" $CFTEST_PREFIX/bin/cf-test-execd \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-execd --pass-to-next-process \ --refuse-to-die --spawn-process-on-signal $CFTEST_PREFIX/bin cf-test-agent matching_pid_exists $CFTEST_PREFIX/bin/cf-test-execd no_matching_pid_exists $CFTEST_PREFIX/bin/cf-test-agent ../../misc/init.d/cfengine3 stop verify_none_running echo "TEST: Verify that status of one daemon works" verify_none_running $CFTEST_PREFIX/bin/cf-test-execd ../../misc/init.d/cfengine3 status > $OUTFILE \ && retcode=$? || retcode=$? for i in cf-test-serverd cf-test-monitord do cat $OUTFILE | grep "$i.*is not running" done cat $OUTFILE | egrep "cf-test-execd.*(\.|is )running" cat $OUTFILE | negate grep -i "Warning" # When a process is missing retcode must be 3 test $retcode = 3 echo "TEST: Verify that status of all daemons works" $CFTEST_PREFIX/bin/cf-test-serverd $CFTEST_PREFIX/bin/cf-test-monitord ../../misc/init.d/cfengine3 status > $OUTFILE \ && retcode=$? || retcode=$? for i in cf-test-execd cf-test-serverd cf-test-monitord do cat $OUTFILE | egrep "$i.*(\.|is )running" done cat $OUTFILE | negate grep -i "is not running" cat $OUTFILE | negate grep -i "Warning" test $retcode = 0 echo "TEST: Verify that status of no daemons works" ../../misc/init.d/cfengine3 stop verify_none_running ../../misc/init.d/cfengine3 status > $OUTFILE \ && retcode=$? || retcode=$? for i in cf-test-execd cf-test-serverd cf-test-monitord do cat $OUTFILE | grep "$i.*is not running" done cat $OUTFILE | negate egrep -i "(\.|is )running" cat $OUTFILE | negate grep -i "Warning" # When a process is missing retcode must be 3 test $retcode = 3 echo "TEST: Verify that we get warnings about multiple daemons" verify_none_running $CFTEST_PREFIX/bin/cf-test-execd $CFTEST_PREFIX/bin/cf-test-execd ../../misc/init.d/cfengine3 status > $OUTFILE \ && retcode=$? || retcode=$? for i in cf-test-serverd cf-test-monitord do cat $OUTFILE | grep "$i.*is not running" done cat $OUTFILE | egrep "cf-test-execd.*(\.|is )running" cat $OUTFILE | grep -i "Warning.*multiple" test $retcode = 3 # TODO should the retcode really be 3 ? echo "TEST: Verify that we get warnings about wrong PID file" ../../misc/init.d/cfengine3 stop verify_none_running $CFTEST_PREFIX/bin/cf-test-execd echo 9999999 > $CFTEST_PREFIX/cf-test-execd.pid ../../misc/init.d/cfengine3 status > $OUTFILE \ && retcode=$? || retcode=$? for i in cf-test-serverd cf-test-monitord do cat $OUTFILE | grep "$i.*is not running" done cat $OUTFILE | egrep "cf-test-execd.*(\.|is )running" cat $OUTFILE | grep -i "Warning.*$CFTEST_PREFIX/cf-test-execd.pid" test $retcode = 3 # TODO should the retcode really be 3 ? ################################################################################ # Cleanup ################################################################################ ../../misc/init.d/cfengine3 stop rm -rf $CFTEST_PREFIX cfengine-3.24.2/tests/unit/aix_process_test.c0000644000000000000000000000677115010704253021231 0ustar00rootroot00000000000000#include #include #include #include #include /* * AIX 5.3 is missing this declaration */ #ifndef HAVE_GETPROCS64 int getprocs64(void *procsinfo, int sizproc, void *fdsinfo, int sizfd, pid_t *index, int count); #endif int getprocs64(void *procsinfo, int process_size, void *fdsinfo, int sizfd, pid_t *index, int count) { assert_int_equal(count, 1); assert_true(fdsinfo == NULL); struct procentry64* pe = procsinfo; switch (*index) { /* Normal process, running, started 1 jan 2000 00:00:00 */ case 1: memset(pe, 0, sizeof(struct procentry64)); pe->pi_pid = 1; pe->pi_start = 946681200; pe->pi_state = SACTIVE; *index = 2; return 1; /* Normal process, stopped, started 31 dec 1980 23:59:59 */ case 2: memset(pe, 0, sizeof(struct procentry64)); pe->pi_pid = 2; pe->pi_start = 347151599; pe->pi_state = SSTOP; *index = 3; return 1; /* Permission denied, getprocs64 returns EINVAL */ case 666: errno = EINVAL; return -1; /* Non-existing process, getprocs64 returns another process' info */ case 1000: memset(pe, 0, sizeof(struct procentry64)); pe->pi_pid = 1001; pe->pi_start = 312312313; pe->pi_state = SACTIVE; *index = 1002; return 1; /* Non-existing process, table sentinel. getprocs64 return 0 */ case 1000000: return 0; } } static void test_get_start_time_process1(void) { time_t t = GetProcessStartTime(1); assert_int_equal(t, 946681200); } static void test_get_start_time_process2(void) { time_t t2 = GetProcessStartTime(2); assert_int_equal(t2, 347151599); } static void test_get_start_time_process666(void) { time_t t = GetProcessStartTime(666); assert_int_equal(t, PROCESS_START_TIME_UNKNOWN); } static void test_get_start_time_process1000(void) { time_t t = GetProcessStartTime(1000); assert_int_equal(t, PROCESS_START_TIME_UNKNOWN); } static void test_get_start_time_process1000000(void) { time_t t = GetProcessStartTime(1000000); assert_int_equal(t, PROCESS_START_TIME_UNKNOWN); } static void test_get_state_process1(void) { ProcessState s = GetProcessState(1); assert_int_equal(s, PROCESS_STATE_RUNNING); } static void test_get_state_process2(void) { ProcessState s = GetProcessState(2); assert_int_equal(s, PROCESS_STATE_STOPPED); } static void test_get_state_process666(void) { ProcessState s = GetProcessState(666); assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST); } static void test_get_state_process1000(void) { ProcessState s = GetProcessState(1000); assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST); } static void test_get_state_process1000000(void) { ProcessState s = GetProcessState(1000000); assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_get_start_time_process1), unit_test(test_get_start_time_process2), unit_test(test_get_start_time_process666), unit_test(test_get_start_time_process1000), unit_test(test_get_start_time_process1000000), unit_test(test_get_state_process1), unit_test(test_get_state_process2), unit_test(test_get_state_process666), unit_test(test_get_state_process1000), unit_test(test_get_state_process1000000), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/policy_server_test.c0000644000000000000000000001363015010704253021567 0ustar00rootroot00000000000000#include #include #include // PolicyServerGet functions should always return NULL instead of empty: bool test_empty(const char *a) { if(a == NULL) { return false; } if(a[0] == '\0') { return true; } return false; } // assert_int_equal is not ideal for this(prints "1 != 0"), but works #define test_never_empty(a, b, c, d)\ {\ assert_int_equal(test_empty(a), false);\ assert_int_equal(test_empty(b), false);\ assert_int_equal(test_empty(c), false);\ assert_int_equal(test_empty(d), false);\ }\ // General test of all variables (get functions) #define test_one_case_generic(set, get, host, port, ip)\ {\ const char *a, *b, *c, *d;\ PolicyServerSet(set);\ assert_string_int_equal((a = PolicyServerGet()), get);\ assert_string_int_equal((b = PolicyServerGetHost()), host);\ assert_string_int_equal((c = PolicyServerGetPort()), port);\ assert_string_int_equal((d = PolicyServerGetIP()), ip);\ test_never_empty(a, b, c, d);\ }\ // For testing hostnames, doesn't do any hostname->ip resolution: #define test_no_ip_generic(set, get, host, port)\ {\ const char *a, *b, *c;\ PolicyServerSet(set);\ assert_string_int_equal((a = PolicyServerGet()), get);\ assert_string_int_equal((b = PolicyServerGetHost()), host);\ assert_string_int_equal((c = PolicyServerGetPort()), port);\ test_never_empty(a, b, c, NULL);\ }\ // Abbreviation of test_one_case_generic #define test_one_case(bootstrap, host, port, ip)\ {\ test_one_case_generic(bootstrap, bootstrap, host, port, ip);\ }\ // For inputs where we expect everything to return NULL #define test_null_server(input)\ {\ test_one_case_generic(input, NULL, NULL, NULL, NULL);\ }\ // For testing hostnames, doesn't do any hostname->ip resolution: #define test_no_ip(bootstrap, host, port)\ {\ test_no_ip_generic(bootstrap, bootstrap, host, port);\ }\ static void test_PolicyServer_IPv4() { // IPv4: test_one_case( /* Set & Get */ "1.2.3.4", /* Host,port */ NULL, NULL, /* IP Addr */ "1.2.3.4"); test_one_case( /* Set & Get */ "255.255.255.255:80", /* Host,port */ NULL, "80", /* IP Addr */ "255.255.255.255"); test_one_case( /* Set & Get */ " 1.2.3.4:", /* Host,port */ NULL, NULL, /* IP Addr */ "1.2.3.4"); } static void test_PolicyServer_IPv6() { // IPv6 with square brackets: test_one_case( /* Set & Get */ "[ffff::dd:12:34]", /* Host,port */ NULL, NULL, /* IP Addr */ "ffff::dd:12:34"); test_one_case( /* Set & Get */ "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:64000", /* Host,port */ NULL, "64000", /* IP Addr */ "2001:0db8:85a3:0000:0000:8a2e:0370:7334"); test_one_case( /* Set & Get */ "[ffff::dd:12:34]:", /* Host,port */ NULL, NULL, /* IP Addr */ "ffff::dd:12:34"); test_one_case( /* Set & Get */ "[FF01:0:0:0:0:0:0:FB]:12345", /* Host,port */ NULL, "12345", /* IP Addr */ "FF01:0:0:0:0:0:0:FB"); // IPv6 without square brackets: test_one_case( /* Set & Get */ "ffff::dd:12:34", /* Host,port */ NULL, NULL, /* IP Addr */ "ffff::dd:12:34"); test_one_case( /* Set & Get */ "FF01:0:0:0:0:0:0:FB", /* Host,port */ NULL, NULL, /* IP Addr */ "FF01:0:0:0:0:0:0:FB"); test_one_case( /* Set & Get */ "::", /* Host,port */ NULL, NULL, /* IP Addr */ "::"); // IPv4 mapped IPv6 addresses: test_one_case( /* Set & Get */ "::ffff:192.0.2.128", /* Host,port */ NULL, NULL, /* IP Addr */ "::ffff:192.0.2.128"); test_one_case( /* Set & Get */ "[::ffff:192.0.2.128]", /* Host,port */ NULL, NULL, /* IP Addr */ "::ffff:192.0.2.128"); // Other: test_one_case( /* Set & Get */ "ff02::1:ff00:0/104", /* Host,port */ NULL, NULL, /* IP Addr */ "ff02::1:ff00:0/104"); test_one_case( /* Set & Get */ "[ff02::1:ff00:0/104]:9", /* Host,port */ NULL, "9", /* IP Addr */ "ff02::1:ff00:0/104"); } static void test_PolicyServer_Host() { // Hostnames: test_no_ip( /* Set & Get */ "localhost", /* Host,port */ "localhost", NULL); test_no_ip( /* Set & Get */ "localhost:", /* Host,port */ "localhost", NULL); test_no_ip( /* Set & Get */ "localhost:80", /* Host,port */ "localhost", "80"); test_no_ip( /* Set & Get */ "[localhost]", /* Host,port */ "localhost", NULL); test_no_ip( /* Set & Get */ "[localhost]:", /* Host,port */ "localhost", NULL); test_no_ip( /* Set & Get */ "[localhost]:59999", /* Host,port */ "localhost", "59999"); test_no_ip( /* Set & Get */ "[www.cfengine.com]", /* Host,port */ "www.cfengine.com", NULL); test_no_ip( /* Set & Get */ "[www.cfengine.com]:8080", /* Host,port */ "www.cfengine.com", "8080"); test_no_ip( /* Set & Get */ "[www.cfengine.com]:", /* Host,port */ "www.cfengine.com", NULL); } static void test_PolicyServer_Corner() { // These tests expect PolicyServerGet() to return NULL: test_null_server(""); test_null_server(NULL); test_null_server(" "); test_null_server(" \n"); test_null_server("\n"); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_PolicyServer_IPv4), unit_test(test_PolicyServer_IPv6), unit_test(test_PolicyServer_Host), unit_test(test_PolicyServer_Corner) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/db_stubs.c0000644000000000000000000000204315010704253017444 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include bool GetAmPolicyHub() { return true; } cfengine-3.24.2/tests/unit/parsemode_test.c0000644000000000000000000000273715010704253020667 0ustar00rootroot00000000000000#include #include typedef struct { char *string; mode_t plus; mode_t minus; } mode_definition; mode_definition modes[] = { { "666", S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH, S_IXUSR|S_IXGRP|S_IXOTH|S_ISUID|S_ISGID|S_ISVTX }, { "g+w", S_IWGRP, 0 }, { "u+r,u+w,g-w,o-rw", S_IRUSR|S_IWUSR, S_IWGRP|S_IWOTH|S_IROTH }, { NULL, 0, 0 } // last case, still tested }; void test_mode(void) { bool ret = false; mode_t plus = 0; mode_t minus = 0; int mode = 0; do { ret = ParseModeString(modes[mode].string, &plus, &minus); assert_true(ret); assert_int_equal(modes[mode].plus, plus); assert_int_equal(modes[mode].minus, minus); } while (modes[mode++].string); } typedef struct { char *string; bool valid; } validation_mode; validation_mode validation_modes[] = { { "", false }, { "abc", false }, { "222222", false }, { "22222", true }, { NULL, true } // last case, still tested }; void test_validation(void) { int ret = false; mode_t minus = 0; mode_t plus = 0; int mode = 0; do { ret = ParseModeString( validation_modes[mode].string, &plus, &minus); assert_int_equal(validation_modes[mode].valid, ret); } while (validation_modes[mode++].string); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_validation), unit_test(test_mode) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/dynamic_dependency_test.sh0000755000000000000000000000572215010704253022722 0ustar00rootroot00000000000000#!/bin/sh # Tests that the symbols in our static libraries do not occur twice in the # output binaries. Most platforms don't warn about this, but it has potential # ill effects. # # How it can happen: It can happen if we list a static library as a dependency # for libpromises, and then we list the same static library as a dependency for # a binary that depends on libpromises. Then the symbol will be included both # in the library and in the binary. # # What effects does it have: Exactly how the symbols are resolved appears to be # platform dependent, but what can happen is this: At any point, when you call # a duplicate symbol, depending on where you call it from, you will either call # the version in the binary or in the library. This is fine, since they both # contain exactly the same code. However, they do not refer to the same global # symbols. They each have their own set. This means that something that was # initialized in the binary may not be initialized in the library, even though # the symbol name is the same. This has weird effects, like a symbol suddenly # switching from a valid value to zero when the stack trace crosses a library # boundary. # # The problem has been observed on AIX, where the log level randomly switches # between verbose and non-verbose, depending on where the Log() function was # called from. It has also been observed on certain Linux versions (Ubuntu # 12.04). # # How do we test for it: By making sure that functions that are known to be in # the static libraries are undefined in the binaries, which means that they # will link to the shared library version, instead of using their own version. # # Detect and replace non-POSIX shell # try_exec() { type "$1" > /dev/null 2>&1 && exec "$@" } broken_posix_shell() { unset foo local foo=1 test "$foo" != "1" } if broken_posix_shell >/dev/null 2>&1; then try_exec /usr/xpg4/bin/sh "$0" "$@" echo "No compatible shell script interpreter found." echo "Please find a POSIX shell for your system." exit 42 fi cd ../.. # Sanity check that nm works. if ! which nm | grep '^/' >/dev/null; then echo "Could not find nm" exit 2 fi # libutils.a libenv.a libcfnet.a # v v v for symbol in LogSetGlobalLevel GetInterfacesInfo ConnectionInfoNew; do for binary in cf-*; do if test "$binary" = "cf-check" ; then continue fi if test -e "$binary/.libs/$binary"; then LOC="$binary/.libs/$binary" else LOC="$binary/$binary" fi if nm "$LOC" | grep "$symbol" >/dev/null 2>&1 && ! nm -u "$LOC" | grep "$symbol" >/dev/null 2>&1; then echo "$symbol is defined in $binary, but should be undefined." echo "Most likely a static library is listed in the Makefile.am which shouldn't be." echo "Check the *_LDADD statements in $binary/Makefile.am." exit 1 fi done done exit 0 cfengine-3.24.2/tests/unit/generic_agent_test.c0000644000000000000000000001272015010704253021473 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include /* xsnprintf */ #include #include char TEMPDIR[] = "/tmp/generic_agent_test_XXXXXX"; void test_have_tty_interactive_failsafe_is_not_created(void) { CryptoInitialize(); bool simulate_tty_interactive = true; EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON, simulate_tty_interactive); /* Just make sure that file doesn't exist. */ GenericAgentConfigSetInputFile(config, NULL, "/masterfiles/non_existing.cf"); /* This is where failsafe.cf will be created. */ char *failsafe_file = StringFormat("%s%c%s", GetInputDir(), FILE_SEPARATOR, "failsafe.cf"); Policy *policy = SelectAndLoadPolicy(config, ctx, false, false); struct stat buf; /* failsafe.cf shouldn't be created as we have tty_interactive. */ assert_int_equal(stat(failsafe_file, &buf), -1); free(failsafe_file); PolicyDestroy(policy); GenericAgentFinalize(ctx, config); } void test_dont_have_tty_interactive_failsafe_is_created(void) { CryptoInitialize(); bool simulate_tty_interactive = false; EvalContext *ctx = EvalContextNew(); GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON, simulate_tty_interactive); /* Just make sure that file doesn't exist. */ GenericAgentConfigSetInputFile(config, NULL, "/masterfiles/non_existing.cf"); /* This is where failsafe.cf will be created. */ char *failsafe_file = StringFormat("%s%c%s", GetInputDir(), FILE_SEPARATOR, "failsafe.cf"); Policy *policy = SelectAndLoadPolicy(config, ctx, false, false); struct stat buf; /* failsafe.cf should be created as we don't have tty_interactive. */ assert_int_equal(stat(failsafe_file, &buf), 0); unlink(failsafe_file); free(failsafe_file); PolicyDestroy(policy); GenericAgentFinalize(ctx, config); } void test_resolve_absolute_input_path(void) { assert_string_equal("/abs/aux.cf", GenericAgentResolveInputPath(NULL, "/abs/aux.cf")); } void test_resolve_non_anchored_base_path(void) { char inputdir[CF_BUFSIZE] = ""; strlcpy(inputdir, GetInputDir(), sizeof(inputdir)); GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON, false); GenericAgentConfigSetInputFile(config, inputdir, "promises.cf"); char testpath[CF_BUFSIZE]; xsnprintf(testpath, sizeof(testpath), "%s%s", TEMPDIR, "/inputs"); assert_string_equal(testpath, config->input_dir); xsnprintf(testpath, sizeof(testpath), "%s%s", TEMPDIR, "/inputs/promises.cf"); assert_string_equal(testpath, config->input_file); xsnprintf(testpath, sizeof(testpath), "%s%s", TEMPDIR, "/inputs/aux.cf"); assert_string_equal(testpath, GenericAgentResolveInputPath(config, "aux.cf")); xsnprintf(testpath, sizeof(testpath), "%s%s", TEMPDIR, "/inputs/rel/aux.cf"); assert_string_equal(testpath, GenericAgentResolveInputPath(config, "rel/aux.cf")); xsnprintf(testpath, sizeof(testpath), "%s%s", TEMPDIR, "/inputs/./aux.cf"); assert_string_equal(testpath, GenericAgentResolveInputPath(config, "./aux.cf")); xsnprintf(testpath, sizeof(testpath), "%s%s", TEMPDIR, "/inputs/./rel/aux.cf"); assert_string_equal(testpath, GenericAgentResolveInputPath(config, "./rel/aux.cf")); GenericAgentConfigDestroy(config); } void test_resolve_relative_base_path(void) { GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_COMMON, false); GenericAgentConfigSetInputFile(config, GetWorkDir(), "./inputs/promises.cf"); assert_string_equal("./inputs/aux.cf", GenericAgentResolveInputPath(config, "aux.cf")); assert_string_equal("./inputs/rel/aux.cf", GenericAgentResolveInputPath(config, "rel/aux.cf")); assert_string_equal("./inputs/./aux.cf", GenericAgentResolveInputPath(config, "./aux.cf")); assert_string_equal("./inputs/./rel/aux.cf", GenericAgentResolveInputPath(config, "./rel/aux.cf")); GenericAgentConfigDestroy(config); } int main() { if (mkdtemp(TEMPDIR) == NULL) { fprintf(stderr, "Could not create temporary directory\n"); return 1; } char *inputs = NULL; xasprintf(&inputs, "%s/inputs", TEMPDIR); mkdir(inputs, 0755); free(inputs); char *env_var = NULL; xasprintf(&env_var, "CFENGINE_TEST_OVERRIDE_WORKDIR=%s", TEMPDIR); // Will leak, but that's how crappy putenv() is. putenv(env_var); PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_resolve_absolute_input_path), unit_test(test_resolve_non_anchored_base_path), unit_test(test_resolve_relative_base_path), unit_test(test_have_tty_interactive_failsafe_is_not_created), unit_test(test_dont_have_tty_interactive_failsafe_is_created), }; int ret = run_tests(tests); char rm_rf[] = "rm -rf "; char cmd[sizeof(rm_rf) + sizeof(TEMPDIR)]; xsnprintf(cmd, sizeof(cmd), "%s%s", rm_rf, TEMPDIR); ARG_UNUSED int ignore = system(cmd); return ret; } cfengine-3.24.2/tests/unit/granules_test.c0000644000000000000000000000412615010704253020522 0ustar00rootroot00000000000000#include #include /* char *GenTimeKey(time_t now); const char *ShiftSlotToString(int shift_slot); int GetTimeSlot(time_t here_and_now); int GetShiftSlot(time_t here_and_now); time_t GetShiftSlotStart(time_t t); time_t MeasurementSlotStart(time_t t); time_t MeasurementSlotTime(size_t slot, size_t num_slots, time_t now); */ static void test_get_time_slot(void) { assert_int_equal(0, GetTimeSlot(1325462400)); // monday 00:00 assert_int_equal(1152, GetTimeSlot(1325808000)); // friday 00:00 assert_int_equal(2015, GetTimeSlot(1326067020)); // sunday 23:57 } static void test_measurement_slot_start(void) { assert_int_equal(1326066900, MeasurementSlotStart(1326067020)); // sunday 23:57 -> 23:55 } static void test_measurement_slot_time(void) { static const time_t now = 1326066900; // sunday 23:55 assert_int_equal(1325462400, MeasurementSlotTime(0, 2016, now)); // monday 00:00 assert_int_equal(1325808000, MeasurementSlotTime(1152, 2016, now)); // friday 00:00 assert_int_equal(1326066900, MeasurementSlotTime(2015, 2016, now)); // sunday 23:55 } static void test_gen_time_key(void) { assert_string_equal("Mon:Hr00:Min00_05", GenTimeKey(1325462400)); assert_string_equal("Mon:Hr00:Min00_05", GenTimeKey(1325462460)); assert_string_equal("Mon:Hr00:Min00_05", GenTimeKey(1325462520)); assert_string_equal("Mon:Hr00:Min00_05", GenTimeKey(1325462580)); assert_string_equal("Mon:Hr00:Min00_05", GenTimeKey(1325462640)); assert_string_equal("Mon:Hr00:Min05_10", GenTimeKey(1325462700)); assert_string_equal("Mon:Hr00:Min05_10", GenTimeKey(1325462760)); assert_string_equal("Mon:Hr00:Min05_10", GenTimeKey(1325462820)); assert_string_equal("Mon:Hr00:Min05_10", GenTimeKey(1325462880)); assert_string_equal("Mon:Hr00:Min05_10", GenTimeKey(1325462940)); } int main() { const UnitTest tests[] = { unit_test(test_get_time_slot), unit_test(test_measurement_slot_start), unit_test(test_measurement_slot_time), unit_test(test_gen_time_key) }; PRINT_TEST_BANNER(); return run_tests(tests); } cfengine-3.24.2/tests/unit/item_test.c0000644000000000000000000002767215010704253017653 0ustar00rootroot00000000000000#include #include #include static void test_prepend_item(void) { Item *ip = NULL, *list = NULL; ip = PrependItem(&list, "hello", "classes"); assert_int_not_equal(ip, NULL); assert_int_not_equal(list, NULL); DeleteItem(&list, ip); assert_int_equal(list, NULL); } static void test_list_len(void) { Item *list = NULL; PrependItem(&list, "one", "classes"); PrependItem(&list, "two", NULL); PrependItem(&list, "three", NULL); assert_int_equal(ListLen(list), 3); DeleteItemList(list); } /* FIXME: those functions are now internal to cf-agent */ #if 0 static void test_list_select_last_matching_finds_first(void) { EvalContext *ctx = EvalContextNew(); Item *list = NULL, *match = NULL, *prev = NULL; bool result = false; AppendItem(&list, "abc", NULL); AppendItem(&list, "def", NULL); AppendItem(&list, "ghi", NULL); AppendItem(&list, "jkl", NULL); result = SelectLastItemMatching(ctx, "abc", list, NULL, &match, &prev); assert_true(result); assert_int_equal(match, list); assert_int_equal(prev, CF_UNDEFINED_ITEM); DeleteItemList(list); EvalContextDestroy(ctx); } static void test_list_select_last_matching_finds_last(void) { EvalContext *ctx = EvalContextNew(); Item *list = NULL, *match = NULL, *prev = NULL; bool result; AppendItem(&list, "abc", NULL); AppendItem(&list, "def", NULL); AppendItem(&list, "ghi", NULL); AppendItem(&list, "abc", NULL); result = SelectLastItemMatching(ctx, "abc", list, NULL, &match, &prev); assert_true(result); assert_int_equal(match, list->next->next->next); assert_int_equal(prev, list->next->next); DeleteItemList(list); EvalContextDestroy(ctx); } static void test_list_select_last_matching_not_found(void) { EvalContext *ctx = EvalContextNew(); Item *list = NULL, *match = NULL, *prev = NULL; bool result; AppendItem(&list, "abc", NULL); AppendItem(&list, "def", NULL); AppendItem(&list, "ghi", NULL); AppendItem(&list, "abc", NULL); result = SelectLastItemMatching(ctx, "xyz", list, NULL, &match, &prev); assert_false(result); assert_int_equal(match, CF_UNDEFINED_ITEM); assert_int_equal(prev, CF_UNDEFINED_ITEM); DeleteItemList(list); EvalContextDestroy(ctx); } #endif static void test_list_compare(void) { Item *list1 = NULL, *list2 = NULL; bool result; result = ListsCompare(list1, list2); assert_true(result); AppendItem(&list1, "abc", NULL); AppendItem(&list1, "def", NULL); result = ListsCompare(list1, list2); assert_false(result); AppendItem(&list2, "def", NULL); AppendItem(&list2, "abc", NULL); result = ListsCompare(list1, list2); assert_true(result); DeleteItemList(list1); DeleteItemList(list2); } static void test_split_string(void) { Item *actual = NULL, *expected = NULL; /* Simple strings. */ actual = SplitString("", ':'); AppendItem(&expected, "", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("foo", ':'); AppendItem(&expected, "foo", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("foo:bar", ':'); AppendItem(&expected, "foo", NULL); AppendItem(&expected, "bar", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString(":", ':'); AppendItem(&expected, "", NULL); AppendItem(&expected, "", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString(":blah", ':'); AppendItem(&expected, "", NULL); AppendItem(&expected, "blah", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah:", ':'); AppendItem(&expected, "blah", NULL); AppendItem(&expected, "", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah::blue", ':'); AppendItem(&expected, "blah", NULL); AppendItem(&expected, "", NULL); AppendItem(&expected, "blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); /* Escaped separator. */ actual = SplitString("foo\\:bar", ':'); AppendItem(&expected, "foo:bar", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("foo:bar\\:baz", ':'); AppendItem(&expected, "foo", NULL); AppendItem(&expected, "bar:baz", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\:", ':'); AppendItem(&expected, ":", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\:blah", ':'); AppendItem(&expected, ":blah", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah\\:", ':'); AppendItem(&expected, "blah:", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah\\:\\:blue", ':'); AppendItem(&expected, "blah::blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah\\::blue", ':'); AppendItem(&expected, "blah:", NULL); AppendItem(&expected, "blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah:\\:blue", ':'); AppendItem(&expected, "blah", NULL); AppendItem(&expected, ":blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); /* Escaped backslash. */ actual = SplitString("\\\\", ':'); AppendItem(&expected, "\\", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah\\\\blue", ':'); AppendItem(&expected, "blah\\blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah\\\\blue\\:", ':'); AppendItem(&expected, "blah\\blue:", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\\\:", ':'); AppendItem(&expected, "\\", NULL); AppendItem(&expected, "", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString(":\\\\", ':'); AppendItem(&expected, "", NULL); AppendItem(&expected, "\\", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\\\:blah", ':'); AppendItem(&expected, "\\", NULL); AppendItem(&expected, "blah", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\\\\\:", ':'); AppendItem(&expected, "\\:", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\\\\\:blah", ':'); AppendItem(&expected, "\\:blah", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah\\\\:", ':'); AppendItem(&expected, "blah\\", NULL); AppendItem(&expected, "", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\\\:\\\\", ':'); AppendItem(&expected, "\\", NULL); AppendItem(&expected, "\\", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah:\\\\:blue", ':'); AppendItem(&expected, "blah", NULL); AppendItem(&expected, "\\", NULL); AppendItem(&expected, "blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah:\\\\\\:blue", ':'); AppendItem(&expected, "blah", NULL); AppendItem(&expected, "\\:blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("blah\\\\blue", ':'); AppendItem(&expected, "blah\\blue", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); /* End string with backslash, danger of buffer overrun! */ actual = SplitString("blah\\", ':'); AppendItem(&expected, "blah\\", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); actual = SplitString("\\", ':'); AppendItem(&expected, "\\", NULL); assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); /* Backslash as separator - CURRENTLY NOT SUPPORTED! */ /* TODO FIX. */ actual = SplitString("C:\\blah\\blue\\", '\\'); /* for (Item *ip = actual; ip != NULL; ip = ip->next) { printf("%s\n", ip->name); } */ AppendItem(&expected, "C:\\blah\\blue\\", NULL); /* TODO FIX! */ /* AppendItem(&expected, "C:", NULL); */ /* AppendItem(&expected, "blah", NULL); */ /* AppendItem(&expected, "blue", NULL); */ /* AppendItem(&expected, "", NULL); */ assert_true(ListsCompare(actual, expected)); DeleteItemList(actual); actual = NULL; DeleteItemList(expected); expected = NULL; test_progress(); test_progress_end(); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_prepend_item), unit_test(test_list_len), unit_test(test_list_compare), unit_test(test_split_string) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/enterprise_extension_test_lib.c0000644000000000000000000000174115010704253024004 0ustar00rootroot00000000000000#include // Pretend we are an extension. #define BUILDING_ENTERPRISE_EXTENSION #include #include ENTERPRISE_FUNC_2ARG_DECLARE(int64_t, extension_function, int32_t, short_int, int64_t, long_int); ENTERPRISE_FUNC_3ARG_DECLARE(int64_t, extension_function_broken, int32_t, short_int, int64_t, unwanted_par, int64_t, long_int); ENTERPRISE_FUNC_2ARG_DEFINE(int64_t, extension_function, int32_t, short_int, int64_t, long_int) { return short_int * long_int; } // Notice that this function has a different signature from the one in the test .c file. ENTERPRISE_FUNC_3ARG_DEFINE(int64_t, extension_function_broken, int32_t, short_int, int64_t, unwanted_par, int64_t, long_int) { (void)unwanted_par; return short_int * long_int; } const char *GetExtensionLibraryVersion() { const char *version = getenv("CFENGINE_TEST_RETURN_VERSION"); if (version) { return version; } else { return VERSION; } } cfengine-3.24.2/tests/unit/split_process_line_test.c0000644000000000000000000013025215010704253022602 0ustar00rootroot00000000000000#include #define TEST_UNIT_TEST #include static void free_and_null_strings(char **strings) { for (int i = 0; i < CF_PROCCOLS; ++i) { free(strings[i]); strings[i] = NULL; } } /* Actual ps output witnessed. */ static void test_split_line_challenges(void) { /* Collect all test data in one array to make alignments visible: */ static const char *lines[] = { "USER PID SZ VSZ RSS NLWP STIME ELAPSED TIME COMMAND", "operatic 14338 1042534 4170136 2122012 9 Sep15 4-06:11:34 2-09:27:49 /usr/lib/opera/opera" }; char *name[CF_PROCCOLS] = { 0 }; /* Headers */ char *field[CF_PROCCOLS] = { 0 }; /* Content */ int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; int user = 0, nlwp = 5; memset(name, 0, sizeof(name)); memset(field, 0, sizeof(field)); /* Prepare data needed by tests and assert things tests can then assume: */ GetProcessColumnNames(lines[0], name, start, end); assert_string_equal(name[user], "USER"); assert_string_equal(name[nlwp], "NLWP"); assert_true(SplitProcLine(lines[1], 1, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "operatic"); assert_string_equal(field[nlwp], "9"); /* Finally, tidy away fields and headers: */ free_and_null_strings(field); free_and_null_strings(name); } static void test_split_line_elapsed(void) { /* Collect all test data in one array to make alignments visible: */ static const char *lines[] = { "USER PID STAT VSZ NI RSS NLWP STIME ELAPSED TIME COMMAND", "space 14604 S 0 0 0 1 Sep 02 4-03:40:00 00:00:01 true", "block 14604 S 0 0 0 1 Sep02 4-03:40:00 00:00:01 true" }; char *name[CF_PROCCOLS] = { 0 }; /* Headers */ char *field[CF_PROCCOLS] = { 0 }; /* Content */ int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; int user = 0, stime = 7; time_t pstime = 1410000000; /* 2014-09-06 12:40 */ const char began[] = "1409641200"; /* 2014-09-02 9:0 */ /* Prepare data needed by tests and assert things tests can then assume: */ GetProcessColumnNames(lines[0], name, start, end); assert_string_equal(name[user], "USER"); assert_string_equal(name[stime], "STIME"); assert_true(SplitProcLine(lines[2], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "block"); /* Copes when STIME is a date with a space in it. */ assert_string_equal(field[stime], began); free_and_null_strings(field); assert_true(SplitProcLine(lines[1], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "space"); /* Copes when STIME is a date with a space in it. */ assert_string_equal(field[stime], began); /* Finally, tidy away headers: */ free_and_null_strings(name); free_and_null_strings(field); } static void test_split_line_noelapsed(void) { /* Collect all test data in one array to make alignments visible: */ static const char *lines[] = { "USER PID STAT VSZ NI RSS NLWP STIME TIME COMMAND", "space 14604 S 0 0 0 1 Jul 02 00:00:01 true", "block 14604 S 0 0 0 1 Jul02 00:00:01 true" }; char *name[CF_PROCCOLS] = { 0 }; /* Headers */ char *field[CF_PROCCOLS] = { 0 }; /* Content */ int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; int user = 0, stime = 7; time_t pstime = 1410000000; /* Prepare data needed by tests and assert things tests can then assume: */ GetProcessColumnNames(lines[0], name, start, end); assert_string_equal(name[user], "USER"); assert_string_equal(name[stime], "STIME"); assert_true(SplitProcLine(lines[2], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "block"); /* Copes when STIME is a date with a space in it. */ assert_string_equal(field[stime], "Jul02"); free_and_null_strings(field); assert_true(SplitProcLine(lines[1], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "space"); /* Copes when STIME is a date with a space in it. */ assert_string_equal(field[stime], "Jul 02"); /* Finally, tidy away headers: */ free_and_null_strings(name); free_and_null_strings(field); } static void test_split_line_longcmd(void) { static const char *lines[] = { "USER PID STAT VSZ NI RSS NLWP STIME ELAPSED TIME COMMAND", "longcmd 923 S 32536 0 784 1 10:30 71-00:07:43 00:01:49 " "java can end up with some insanely long command-lines, so we need to " "be sure that we don't artificially limit the length of the command " "field that we see when looking at the process table to match for the " "details that the user might be interested in - so here we have an " "absurdly long 'command' field just for the sake of testing that it " "does not get truncated - see RedMine ticket 3974 for working round the " "problems when ps itself does such truncation, but this test is not about " "that so much as our own code not doing such truncation - and now for " "some random drivel repeated a lot to bulk this command line length out " "to more than 4k:" /* 638 bytes thus far, +72 per repeat, * 50 for 4238 > 4096: */ " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens" " the quick brown fox jumped over the lazy dogs after eating the chickens", }; char *name[CF_PROCCOLS] = { 0 }; /* Headers */ char *field[CF_PROCCOLS] = { 0 }; /* Content */ int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; int user = 0, command = 10; time_t pstime = 1410000000; /* Prepare data needed by tests and assert things assumed by test: */ GetProcessColumnNames(lines[0], name, start, end); assert_string_equal(name[user], "USER"); assert_string_equal(name[command], "COMMAND"); assert_true(SplitProcLine(lines[1], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "longcmd"); /* Does not truncate the command. */ assert_string_equal(field[command], lines[1] + start[command]); /* Finally, tidy away headers: */ free_and_null_strings(name); free_and_null_strings(field); } static void test_split_line(void) { /* Collect all test data in one array to make alignments visible: */ static const char *lines[] = { /* Indent any continuation lines so that it's clear that's what they are. */ /* Use the username field as a test name to confirm tests are in sync. */ "USER PID STAT VSZ NI RSS NLWP STIME ELAPSED TIME COMMAND", "timeboth 923 S 32536 0 784 1 10:30 1271-00:07:43 00:01:49 true" " to itself", /* timeright: adapted from a Jenkins run that failed. */ "timeright 941 S 39752 0 4552 1 May20 92-21:17:55 1-02:07:14 true", "timesleft 923 S 32536 0 784 1 10:30 1271-00:07:43 00:01:49 true", "timeleft 923 S 32536 0 784 1 10:30 271-00:07:43 00:01:49 true", "numboth 923 S 32536 0 12784321 1 10:30 71-00:07:43 00:01:49 true", "numleft 923 S 123432536 0 784 1 10:30 71-00:07:43 00:01:49 true", "wordytoright 4 S 0 0 0 1 10:30 54:29 00:00:01 true", "wordright 4 S 0 0 0 1 10:30 54:29 00:00:01 true", /* Long-standing: */ "inspace 923 S 32536 0 784 1 10:30 71-00:07:43 00:01:49 echo" " preserve\t embedded spaces in a text field", "spacey 923 S 32536 0 784 1 10:30 71-00:07:43 00:01:49 echo " "\t \t \r\n\f\n\v\n", "basic 923 S 32536 0 784 1 10:30 71-00:07:43 00:01:49 true", "", NULL }; char *name[CF_PROCCOLS] = { 0 }; /* Headers */ char *field[CF_PROCCOLS] = { 0 }; /* Content */ int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; int user = 0, vsz = 3, rss = 5, stime = 7, command = 10; time_t pstime = 1410000000; /* Prepare data needed by tests and assert things tests can then assume: */ GetProcessColumnNames(lines[0], name, start, end); assert_string_equal(name[user], "USER"); assert_string_equal(name[vsz], "VSZ"); assert_string_equal(name[rss], "RSS"); assert_string_equal(name[stime], "STIME"); assert_string_equal(name[command], "COMMAND"); assert_int_equal(start[command], 69); size_t line = sizeof(lines) / sizeof(const char *); /* Higher indexed tests first; test lines[line] then decrement line. */ assert_false(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); /* NULL */ free_and_null_strings(field); assert_false(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); /* empty */ free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); /* basic */ { /* Each field is as expected: */ const char *each[] = { "basic", "923", "S", "32536", "0", "784", "1", "10:30", "71-00:07:43", "00:01:49", "true" }; for (int i = 0; name[i] != NULL; i++) { assert_in_range(i, 0, sizeof(each) / sizeof(char *) - 1); bool valid = field[i] != NULL && each[i] != NULL; assert_true(valid); assert_string_equal(field[i], each[i]); } /* That incidentally covers numeric (VSZ) and time (ELAPSED, * TIME) fields overflowing to the left (but not so far as to * go under the previous field's header). */ } /* See field[user] checks for names of remaining tests. */ free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "spacey"); /* Discards leading and dangling space in command. */ assert_string_equal(field[command], "echo"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "inspace"); /* Preserves spaces within a text field. */ assert_string_equal(field[command], lines[line] + start[command]); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); /* Handle a text field overflowing to the right. */ assert_string_equal(field[user], "wordright"); /* Shouldn't pollute PID: */ assert_string_equal(field[user + 1], "4"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); /* Handle a text field overflowing under next header. */ assert_string_equal(field[user], "wordytoright"); /* Shouldn't pollute PID: */ assert_string_equal(field[user + 1], "4"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "numleft"); /* Handle numeric field overflowing under previous header. */ assert_string_equal(field[vsz], "123432536"); /* Shouldn't pollute STAT: */ assert_string_equal(field[vsz - 1], "S"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "numboth"); /* Handle numeric field overflowing under previous header. */ assert_string_equal(field[rss], "12784321"); /* Shouldn't pollute STAT or NI: */ assert_string_equal(field[rss - 1], "0"); assert_string_equal(field[rss + 1], "1"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "timeleft"); /* Handle time fields overflowing almost under previous header. */ assert_string_equal(field[stime + 1], "271-00:07:43"); assert_string_equal(field[stime], "10:30"); /* Shouldn't pollute NLWP: */ assert_string_equal(field[stime - 1], "1"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "timesleft"); /* Handle time fields overflowing under previous header. */ assert_string_equal(field[stime + 1], "1271-00:07:43"); assert_string_equal(field[stime], "10:30"); /* Shouldn't pollute NLWP: */ assert_string_equal(field[stime - 1], "1"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "timeright"); /* Handle time field overflowing under next header. */ assert_string_equal(field[command - 1], "1-02:07:14"); /* Shouldn't pollute ELAPSED or COMMAND: */ assert_string_equal(field[stime + 1], "92-21:17:55"); assert_string_equal(field[command], "true"); free_and_null_strings(field); assert_true(SplitProcLine(lines[--line], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "timeboth"); assert_int_equal(command, stime + 3); /* with elapsed and time between */ /* Handle a time field overflowing almost under previous header * while also overflowing right and thus causing the next to * overflow under the field beyond it. */ assert_string_equal(field[command - 1], "00:01:49"); assert_string_equal(field[stime + 1], "1271-00:07:43"); /* Should shunt COMMAND two bytes to the right: */ assert_string_equal(field[command], lines[line] + 2 + start[command]); /* Shouldn't pollute COMMAND, NLWP or STIME: */ assert_string_equal(field[stime], "10:30"); assert_string_equal(field[stime - 1], "1"); assert_int_equal(line, 1); /* Finally, tidy away headers: */ free_and_null_strings(name); free_and_null_strings(field); } static void test_split_line_serious_overspill(void) { /* Test that columns spilling over into other columns do not confuse the parser. Collect all test data in one array to make alignments visible: */ static const char *lines[] = { " USER PID %CPU %MEM SZ RSS TT S STIME TIME COMMAND", " johndoe 8263 0.0 0.2 19890 116241 ? S Jan_16 08:41:40 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4", "noaccess 8264 0.0 0.2 19890 116242 ? S Jan_16 08:41:40 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4", "noaccess 8265 0.0 0.2 19890 116243 ? S Jan_16 08:41:40 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4", NULL }; char *name[CF_PROCCOLS] = { 0 }; /* Headers */ char *field[CF_PROCCOLS] = { 0 }; /* Content */ int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; int user = 0, pid = 1, sz = 4, rss = 5, command = 10; time_t pstime = 1410000000; /* Prepare data needed by tests and assert things tests can then assume: */ GetProcessColumnNames(lines[0], name, start, end); assert_string_equal(name[user], "USER"); assert_string_equal(name[pid], "PID"); assert_string_equal(name[sz], "SZ"); assert_string_equal(name[rss], "RSS"); assert_string_equal(name[command], "COMMAND"); assert_int_equal(start[command], 66); // Test content { assert_true(SplitProcLine(lines[1], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "johndoe"); assert_string_equal(field[pid], "8263"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116241"); assert_string_equal(field[command], lines[1] + 69); free_and_null_strings(field); } { assert_true(SplitProcLine(lines[2], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "noaccess"); assert_string_equal(field[pid], "8264"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116242"); assert_string_equal(field[command], lines[2] + 69); free_and_null_strings(field); } { assert_true(SplitProcLine(lines[3], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "noaccess"); assert_string_equal(field[pid], "8265"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116243"); assert_string_equal(field[command], lines[3] + 69); free_and_null_strings(field); } free_and_null_strings(name); } typedef struct { FILE *fp; const char **lines; } LWData; static void *ListWriter(void *arg) { LWData *data = (LWData *)arg; for (int i = 0; data->lines[i]; i++) { fprintf(data->fp, "%s\n", data->lines[i]); } fclose(data->fp); return NULL; } static void test_platform_extra_table(void) { static const char *lines[] = { " USER PID %CPU %MEM SZ RSS TT S STIME TIME COMMAND", " johndoe 8263 0.0 0.2 19890 116241 ? S Jan_16 08:41:40 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4", "noaccess 8264 0.0 0.2 19890 116242 ? S Jan_16 08:41:40 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4", "noaccess 8265 0.0 0.2 19890 116243 ? S Jan_16 08:41:40 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4", " jenkins 22306 - - 0 0 ? Z - 00:00 ", " jenkins 22307 - - 0 0 ? Z - 00:00 ", " jenkins 22308 - - 0 0 ? Z - 00:00 ", NULL }; static const char *ucb_lines[] = { " PID TT S TIME COMMAND", " 8263 ? S 521:40 /usr/java/bin/java blahblah", // Takes from Solaris 10. Yep, the line really is that long. " 8264 ? S 521:40 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4 -classpath /usr/share/webconsole/private/container/bin/bootstrap.jar:/usr/share/webconsole/private/container/bin/commons-logging.jar:/usr/share/webconsole/private/container/bin/log4j.jar:/usr/java/lib/tools.jar:/usr/java/jre/lib/jsse.jar -Djava.security.manager -Djava.security.policy==/var/webconsole/domains/console/conf/console.policy -Djavax.net.ssl.trustStore=/var/webconsole/domains/console/conf/keystore.jks -Djava.security.auth.login.config=/var/webconsole/domains/console/conf/consolelogin.conf -Dcatalina.home=/usr/share/webconsole/private/container -Dcatalina.base=/var/webconsole/domains/console -Dcom.sun.web.console.home=/usr/share/webconsole -Dcom.sun.web.console.conf=/etc/webconsole/console -Dcom.sun.web.console.base=/var/webconsole/domains/console -Dcom.sun.web.console.logdir=/var/log/webconsole/console -Dcom.sun.web.console.native=/usr/lib/webconsole -Dcom.sun.web.console.appbase=/var/webconsole/domains/console/webapps -Dcom.sun.web.console.secureport=6789 -Dcom.sun.web.console.unsecureport=6788 -Dcom.sun.web.console.unsecurehost=127.0.0.1 -Dwebconsole.default.file=/etc/webconsole/console/default.properties -Dwebconsole.config.file=/etc/webconsole/console/service.properties -Dcom.sun.web.console.startfile=/var/webconsole/tmp/console_start.tmp -Djava.awt.headless=true -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog org.apache.catalina.startup.Bootstrap start", " 8265 ? S 521:40 /usr/java/bin/java blahblah", // Taken from Solaris 10, notice the missing fields. " 22306 Z 0:00 ", " 22307 Z 0:00 ", " 22308 Z 0:00", NULL }; char *name[CF_PROCCOLS] = { 0 }; /* Headers */ char *field[CF_PROCCOLS] = { 0 }; /* Content */ int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; int user = 0, pid = 1, sz = 4, rss = 5, command = 10; time_t pstime = 1410000000; // Prepare to fill "/usr/ucb/ps" table with data. ClearPlatformExtraTable(); int pipefd[2]; assert_int_equal(pipe(pipefd), 0); LWData data; data.fp = fdopen(pipefd[1], "w"); data.lines = ucb_lines; // Feed the pipe from a separate thread. pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t tid; pthread_create(&tid, &attr, &ListWriter, &data); pthread_attr_destroy(&attr); FILE *cmd_output = fdopen(pipefd[0], "r"); UCB_PS_MAP = StringMapNew(); ReadFromUcbPsPipe(cmd_output); /* Prepare data needed by tests and assert things tests can then assume: */ GetProcessColumnNames(lines[0], name, start, end); assert_string_equal(name[user], "USER"); assert_string_equal(name[pid], "PID"); assert_string_equal(name[sz], "SZ"); assert_string_equal(name[rss], "RSS"); assert_string_equal(name[command], "COMMAND"); assert_int_equal(start[command], 66); // Test content { assert_true(SplitProcLine(lines[1], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "johndoe"); assert_string_equal(field[pid], "8263"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116241"); assert_string_equal(field[command], lines[1] + 69); ApplyPlatformExtraTable(name, field); // Now check new and corrected values. assert_string_equal(field[user], "johndoe"); assert_string_equal(field[pid], "8263"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116241"); assert_string_equal(field[command], ucb_lines[1] + 25); free_and_null_strings(field); } { assert_true(SplitProcLine(lines[2], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "noaccess"); assert_string_equal(field[pid], "8264"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116242"); assert_string_equal(field[command], lines[2] + 69); ApplyPlatformExtraTable(name, field); // Now check new and corrected values. assert_string_equal(field[user], "noaccess"); assert_string_equal(field[pid], "8264"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116242"); assert_string_equal(field[command], ucb_lines[2] + 25); free_and_null_strings(field); } { assert_true(SplitProcLine(lines[3], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "noaccess"); assert_string_equal(field[pid], "8265"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116243"); assert_string_equal(field[command], lines[3] + 69); ApplyPlatformExtraTable(name, field); // Now check new and corrected values. assert_string_equal(field[user], "noaccess"); assert_string_equal(field[pid], "8265"); assert_string_equal(field[sz], "19890"); assert_string_equal(field[rss], "116243"); assert_string_equal(field[command], ucb_lines[3] + 25); free_and_null_strings(field); } { assert_true(SplitProcLine(lines[4], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "jenkins"); assert_string_equal(field[pid], "22306"); assert_string_equal(field[sz], "0"); assert_string_equal(field[rss], "0"); assert_string_equal(field[command], lines[4] + 66); ApplyPlatformExtraTable(name, field); // Now check new and corrected values. assert_string_equal(field[user], "jenkins"); assert_string_equal(field[pid], "22306"); assert_string_equal(field[sz], "0"); assert_string_equal(field[rss], "0"); assert_string_equal(field[command], ""); free_and_null_strings(field); } { assert_true(SplitProcLine(lines[5], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "jenkins"); assert_string_equal(field[pid], "22307"); assert_string_equal(field[sz], "0"); assert_string_equal(field[rss], "0"); assert_string_equal(field[command], lines[5] + 66); ApplyPlatformExtraTable(name, field); // Now check new and corrected values. assert_string_equal(field[user], "jenkins"); assert_string_equal(field[pid], "22307"); assert_string_equal(field[sz], "0"); assert_string_equal(field[rss], "0"); assert_string_equal(field[command], ""); free_and_null_strings(field); } { assert_true(SplitProcLine(lines[6], pstime, name, start, end, PCA_AllColumnsPresent, field)); assert_string_equal(field[user], "jenkins"); assert_string_equal(field[pid], "22308"); assert_string_equal(field[sz], "0"); assert_string_equal(field[rss], "0"); assert_string_equal(field[command], lines[6] + 66); ApplyPlatformExtraTable(name, field); // Now check new and corrected values. assert_string_equal(field[user], "jenkins"); assert_string_equal(field[pid], "22308"); assert_string_equal(field[sz], "0"); assert_string_equal(field[rss], "0"); assert_string_equal(field[command], ""); free_and_null_strings(field); } free_and_null_strings(name); fclose(cmd_output); } static void test_platform_specific_ps_examples(void) { enum { // Make sure the order matches the ps lines below. TEST_LINUX = 0, TEST_AIX, TEST_HPUX, TEST_SOLARIS9, TEST_SOLARIS10, TEST_SOLARIS11, TEST_FREEBSD11, TEST_ILLUMOS, NUM_OF_PLATFORMS }; /* Simple, visual way of specifying the expected parse results, each row alternates between the line we want to parse (with header first) and the range we wish the parsing code to extract for us, denoted by '<' and '>'. 'X' is used where they overlap, and '-' if the field is empty. '{' and '}' a special case and means it should get the expected output from the corresponding row in the exception table below. */ const char *pslines[NUM_OF_PLATFORMS][20] = { { // Linux "USER PID PPID PGID %CPU %MEM VSZ NI RSS NLWP STIME ELAPSED TIME COMMAND", "< > < > < > < > < > < > < > <> < > < > < > < > < > < >", "a10040 4831 1 4116 5.4 17.3 2763416 0 1400812 54 Apr04 4-02:54:24 05:25:51 /usr/lib/firefox/firefox", "< > < > X < > < > < > < > X < > <> { } < > < > < >", "a10040 5862 5851 4116 0.0 0.0 0 0 0 1 Apr04 4-02:38:28 00:00:00 [/usr/bin/termin] ", "< > < > < > < > < > < > X X X X { } < > < > < >", NULL }, { // AIX " USER PID PPID PGID %CPU %MEM VSZ NI ST STIME TIME COMMAND", " < > < > < > < > < > < > < > <> <> < > < > < >", " jenkins 1036484 643150 1036484 0.0 0.0 584 20 A 09:29:20 00:00:00 bash", " < > < > < > < > < > < > < > <> X < > < > < >", " 254232 729146 729146 20 Z 00:00:00 ", " - < > < > < > - - - <> X - < > < >", " jenkins 205218 1 205218 0.0 7.0 125384 20 A Mar 16 00:36:46 /usr/java6_64/bin/java -jar slave.jar -jnlpUrl http://jenkins.usdc.cfengine.com/computer/buildslave-aix-5.3-ppc64/slave-agent.jnlp", " < > < > X < > < > < > < > <> X < > < > < >", // Extreme case, a lot of fields missing. This only works when the // process is a zombie and the platform uses the // PCA_ZombieSkipEmptyColumns algorithm (which AIX does). " 205218 1 205218 20 Z", " - < > X < > - - - <> X - - -", NULL }, { // HPUX " UID PID PPID C STIME TTY TIME COMMAND", " < > < > < > X < > < > < > < >", " jenkins 17345 17109 0 09:31:39 pts/0 0:00 perl -e my $v = fork(); if ($v != 0) { sleep(3600); }", " < > < > < > X < > < > < > < >", " jenkins 17374 17345 0 09:31:40 pts/0 0:00 ", " < > < > < > X < > < > < > < >", " root 832 1 0 May 4 ? 0:01 /usr/sbin/automountd", " < > < > X X < > X < > < >", NULL }, { // Solaris 9 " USER PID %CPU %MEM SZ RSS TT S STIME TIME COMMAND", " < > < > < > < > <> < > <> X < > < > < >", " jenkins 29769 0.0 0.0 810 2976 pts/1 S 07:22:43 0:00 /usr/bin/perl ../../ps.pl", " < > < > < > < > < > < > < > X < > < > < >", " jenkins 29835 - - 0 0 ? Z - 0:00 ", " < > < > X X X X X X X < > < >", " jenkins 10026 0.0 0.3 30927 143632 ? S Jan_21 01:18:58 /usr/jdk/jdk1.6.0_45/bin/java -jar slave.jar", " < > < > < > < > < > < > X X < > < > < >", NULL }, { // Solaris 10 " USER PID %CPU %MEM SZ RSS TT S STIME TIME COMMAND", " < > < > < > < > <> < > <> X < > < > < >", " root 19553 0.0 0.0 743 4680 ? S 04:03:10 00:00 /usr/lib/ssh/sshd", " < > < > < > < > < > < > X X < > < > < >", " jenkins 29770 - - 0 0 ? Z - 00:00 ", " < > < > X X X X X X X < > < >", "noaccess 8264 0.0 0.2 19890 116240 ? S Jan_16 08:49:25 /usr/java/bin/java -server -Xmx128m -XX:+UseParallelGC -XX:ParallelGCThreads=4 ", "< > < > < > < > < > < > X X < > < > < >", NULL }, { // Solaris 11 " USER PID %CPU %MEM SZ RSS TT S STIME TIME COMMAND", " < > < > < > < > <> < > <> X < > < > < >", " root 15449 0.0 0.0 835 4904 ? S 04:03:29 00:00 /usr/lib/ssh/sshd", " < > < > < > < > < > < > X X < > < > < >", " jenkins 5409 - - 0 0 ? Z - 00:00 ", " < > < > X X X X X X X < > < >", " jenkins 29997 0.0 0.5 51661 312120 ? S Jan_21 01:18:53 /usr/jdk/jdk1.6.0_45/bin/java -jar slave.jar", " < > < > < > < > < > < > X X < > < > < >", NULL }, { // FreeBSD 11 "USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND", "< > < > < > < > < > < > <> < > < > < > < >", "skreuzer 6506 5.0 0.2 57192 25764 0- S+ 12:39 10:13.37 mosh-server new -c 256 -s -l LANG=en_US.UTF-8", "< > < > < > < > < > < > <> <> < > < > < >", "zookeeper 646 0.0 1.0 4538080 162140 - I 28Feb16 21:46.80 /usr/local/openjdk7/bin/java -Dzookeeper.log.dir=/var/log/zookeeper -Dlog4j.configuration=file:/usr/local/etc/zookeeper/l", "< > < > < > < > < > < > X X < > < > < >", "skreuzer 40046 0.0 0.0 0 0 6 Z+ 21:34 0:00.00 ", "< > < > < > < > X X X <> < > < > < >", "skreuzer 50293 0.0 0.0 20612 5332 3 Is 2Mar16 0:00.62 -zsh (zsh)", "< > < > < > < > < > < > X <> < > < > < >", NULL }, { // Illumos " USER PID %CPU %MEM SZ RSS TT S STIME TIME COMMAND", " < > < > < > < > <> < > <> X < > < > < >", " bahamat 63679 0.0 0.1 1831 4340 pts/13 S 00:15:39 00:00 perl -e $p = fork(); if ($p != 0) { sleep(60); }", " < > < > < > < > < > < > < > X < > < > < >", " bahamat 63680 - - 0 0 ? Z - 00:00 ", " < > < > X X X X X X X < > < >", " root 72601 0.3 0.4 291631 1050796 ? S Feb_25 06:35:07 /opt/local/java/openjdk7/bin/java -Dhudson.DNSMultiCast.disabled=true -Xmx2048m", " < > < > < > < > < > < > X X < > < > < >", NULL } }; // Only half as many elements here, since there is only expected output. const char *exceptions[NUM_OF_PLATFORMS][10] = { { // Linux NULL, "1459762277", "1459763233", NULL }, { // AIX NULL }, { // HPUX NULL }, { // Solaris 9 NULL }, { // Solaris 10 NULL }, { // Solaris 11 NULL }, { // FreeBSD 11 NULL }, { // Illumos NULL } }; char *names[CF_PROCCOLS] = { 0 }; char *fields[CF_PROCCOLS] = { 0 }; int start[CF_PROCCOLS] = { 0 }; int end[CF_PROCCOLS] = { 0 }; memset(names, 0, sizeof(names)); memset(fields, 0, sizeof(fields)); for (int platform = 0; platform < NUM_OF_PLATFORMS; platform++) { PsColumnAlgorithm pca; if (platform == TEST_AIX) { pca = PCA_ZombieSkipEmptyColumns; } else { pca = PCA_AllColumnsPresent; } for (int linenum = 0; pslines[platform][linenum]; linenum += 2) { char **fields_to_check; if (linenum == 0) { GetProcessColumnNames(pslines[platform][linenum], names, start, end); fields_to_check = names; } else { assert_true(SplitProcLine(pslines[platform][linenum], 1460118341, names, start, end, pca, fields)); fields_to_check = fields; } bool in_field = false; int field_start = -1; int field_end = -1; int field_num = 0; bool exception = false; for (int pos = 0;; pos++) { if (!pslines[platform][linenum + 1][pos]) { // There should be no excess space at the end of the // expected replies. assert_int_not_equal(pslines[platform][linenum + 1][pos - 1], ' '); assert_false(in_field); // We should have reached the end of both arrays. assert_int_equal(names[field_num], NULL); if (linenum != 0) { assert_int_equal(fields[field_num], NULL); } break; } switch (pslines[platform][linenum + 1][pos]) { case ' ': break; case '{': exception = true; // fallthrough case '<': assert_false(in_field); in_field = true; field_start = pos; break; case '}': case '>': assert_true(in_field); in_field = false; // + 1 because we want it to be the next byte. field_end = pos + 1; break; case 'X': field_start = pos; // + 1 because we want it to be the next byte. field_end = pos + 1; break; case '-': field_start = pos; // This corresponds to an empty string. field_end = pos; break; default: assert_true(false); break; } if (field_start != -1 && field_end != -1) { if (exception) { assert_string_equal(fields_to_check[field_num], exceptions[platform][linenum / 2]); exception = false; } else { int field_len = field_end - field_start; #if 0 /* DEBUG OUTPUT */ printf("Checking '%s' against '", fields_to_check[field_num]); fwrite(pslines[platform][linenum] + field_start, field_len, 1, stdout); printf("'\n"); #endif /* DEBUG OUTPUT */ // Check if fields are identical. assert_memory_equal(fields_to_check[field_num], pslines[platform][linenum] + field_start, field_len); // And that it's not longer than what we expect. assert_int_equal(fields_to_check[field_num][field_len], '\0'); } field_start = -1; field_end = -1; field_num++; } } free_and_null_strings(fields); } free_and_null_strings(names); } } int main(void) { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_split_line_challenges), unit_test(test_split_line_noelapsed), unit_test(test_split_line_elapsed), unit_test(test_split_line_longcmd), unit_test(test_split_line), unit_test(test_split_line_serious_overspill), unit_test(test_platform_extra_table), unit_test(test_platform_specific_ps_examples), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/arg_split_test.c0000644000000000000000000001555115010704253020672 0ustar00rootroot00000000000000#include #include #include #include #include static void test_split_empty(void) { char **s = ArgSplitCommand("", NULL); assert_true(s); assert_false(*s); ArgFree(s); char *exec, *args; ArgGetExecutableAndArgs("", &exec, &args); assert_false(exec); assert_false(args); } static void test_split_easy(void) { char **s = ArgSplitCommand("zero one two", NULL); assert_string_equal(s[0], "zero"); assert_string_equal(s[1], "one"); assert_string_equal(s[2], "two"); assert_false(s[3]); ArgFree(s); char *exec, *args; ArgGetExecutableAndArgs("zero one two", &exec, &args); assert_string_equal(exec, "zero"); assert_string_equal(args, "one two"); free(exec); free(args); } static void test_split_whitespace_prefix(void) { char **s = ArgSplitCommand(" zero one two", NULL); assert_string_equal(s[0], "zero"); assert_string_equal(s[1], "one"); assert_string_equal(s[2], "two"); assert_false(s[3]); ArgFree(s); char *exec, *args; ArgGetExecutableAndArgs("zero one two", &exec, &args); assert_string_equal(exec, "zero"); assert_string_equal(args, "one two"); free(exec); free(args); } static void test_split_quoted_beginning(void) { char **s = ArgSplitCommand("\"quoted string\" atbeginning", NULL); assert_string_equal(s[0], "quoted string"); assert_string_equal(s[1], "atbeginning"); assert_false(s[2]); ArgFree(s); char *exec, *args; ArgGetExecutableAndArgs("\"quoted string\" atbeginning", &exec, &args); assert_string_equal(exec, "quoted string"); assert_string_equal(args, "atbeginning"); free(exec); free(args); } static void test_split_quoted_end(void) { char **s = ArgSplitCommand("atend 'quoted string'", NULL); assert_string_equal(s[0], "atend"); assert_string_equal(s[1], "quoted string"); assert_false(s[2]); ArgFree(s); char *exec, *args; ArgGetExecutableAndArgs("atend 'quoted string'", &exec, &args); assert_string_equal(exec, "atend"); assert_string_equal(args, "'quoted string'"); free(exec); free(args); } static void test_split_quoted_middle(void) { char **s = ArgSplitCommand("at `quoted string` middle", NULL); assert_string_equal(s[0], "at"); assert_string_equal(s[1], "quoted string"); assert_string_equal(s[2], "middle"); assert_false(s[3]); ArgFree(s); char *exec, *args; ArgGetExecutableAndArgs("at `quoted string` middle", &exec, &args); assert_string_equal(exec, "at"); assert_string_equal(args, "`quoted string` middle"); free(exec); free(args); } static void test_complex_quoting(void) { char **s = ArgSplitCommand("\"foo`'bar\"", NULL); assert_string_equal(s[0], "foo`'bar"); assert_false(s[1]); ArgFree(s); char *exec, *args; ArgGetExecutableAndArgs("\"foo`'bar\"", &exec, &args); assert_string_equal(exec, "foo`'bar"); assert_false(args); free(exec); } static void test_arguments_resize_for_null(void) { /* This test checks that extending returned argument list for NULL terminator * works correctly */ char **s = ArgSplitCommand("0 1 2 3 4 5 6 7", NULL); assert_string_equal(s[7], "7"); assert_false(s[8]); ArgFree(s); } static void test_arguments_resize(void) { char **s = ArgSplitCommand("0 1 2 3 4 5 6 7 8", NULL); assert_string_equal(s[7], "7"); assert_string_equal(s[8], "8"); assert_false(s[9]); ArgFree(s); } static void test_arguments_with_arglist(void) { char *command = "lorem ipsum dolor sit amet"; Seq *arglist = SeqNew(10, NULL); char extra[][32] = { "consectetur adipiscing", "elit", "sed do", "eiusmod" }; for (size_t i = 0; i < sizeof(extra) / sizeof(*extra); i++) { SeqAppend(arglist, extra[i]); } char **argv = ArgSplitCommand(command, arglist); SeqDestroy(arglist); assert_string_equal(argv[0], "lorem"); assert_string_equal(argv[2], "dolor"); assert_string_equal(argv[5], "consectetur adipiscing"); assert_string_equal(argv[8], "eiusmod"); assert_false(argv[9]); ArgFree(argv); } static void test_command_promiser(void) { char *t1 = "/bin/echo"; assert_string_equal(CommandArg0(t1), "/bin/echo"); char *t2 = "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; assert_string_equal(CommandArg0(t2), "/bin/rpm"); char *t3 = "/bin/mount -va"; assert_string_equal(CommandArg0(t3), "/bin/mount"); char *t4 = "\"/bin/echo\""; assert_string_equal(CommandArg0(t4), "/bin/echo"); char *t5 = "\"/bin/echo\" 123"; assert_string_equal(CommandArg0(t5), "/bin/echo"); char *t6 = "\"/bin/echo with space\" 123"; assert_string_equal(CommandArg0(t6), "/bin/echo with space"); char *t7 = "c:\\Windows\\System32\\cmd.exe"; assert_string_equal(CommandArg0(t7), "c:\\Windows\\System32\\cmd.exe"); char *t8 = "\"c:\\Windows\\System32\\cmd.exe\""; assert_string_equal(CommandArg0(t8), "c:\\Windows\\System32\\cmd.exe"); char *t9 = "\"c:\\Windows\\System32\\cmd.exe\" /some args here"; assert_string_equal(CommandArg0(t9), "c:\\Windows\\System32\\cmd.exe"); char *t10 = "\"c:\\Windows\\System32 with space\\cmd.exe\""; assert_string_equal(CommandArg0(t10), "c:\\Windows\\System32 with space\\cmd.exe"); char *t11 = "\"c:\\Windows\\System32 with space\\cmd.exe\" /some args here"; assert_string_equal(CommandArg0(t11), "c:\\Windows\\System32 with space\\cmd.exe"); char *t12 = "\"c:\\Windows\\System32 with space\\cmd.exe\" /some \"args here\""; assert_string_equal(CommandArg0(t12), "c:\\Windows\\System32 with space\\cmd.exe"); char *t13 = "\\\\mycommand"; assert_string_equal(CommandArg0(t13), "\\\\mycommand"); char *t14 = "\\\\myhost\\share\\command.exe"; assert_string_equal(CommandArg0(t14), "\\\\myhost\\share\\command.exe"); char *t15 = "\"\\\\myhost\\share\\command.exe\""; assert_string_equal(CommandArg0(t15), "\\\\myhost\\share\\command.exe"); /* bad input */ char *b1 = "\"/bin/echo 123"; assert_string_equal(CommandArg0(b1), "/bin/echo 123"); char *b2 = "/bin/echo\" 123"; assert_string_equal(CommandArg0(b2), "/bin/echo\""); char *b3 = ""; assert_string_equal(CommandArg0(b3), ""); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_split_empty), unit_test(test_split_easy), unit_test(test_split_whitespace_prefix), unit_test(test_split_quoted_beginning), unit_test(test_split_quoted_middle), unit_test(test_split_quoted_end), unit_test(test_complex_quoting), unit_test(test_arguments_resize_for_null), unit_test(test_arguments_resize), unit_test(test_arguments_with_arglist), unit_test(test_command_promiser), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/evalfunction_test.c0000644000000000000000000000757115010704253021406 0ustar00rootroot00000000000000#include /* Protect against duplicate definition of symbol CF_FNCALL_TYPES since we are * including evalfunction.c */ #define CFENGINE_EVALFUNCTION_TEST_C #include #include static bool netgroup_more = false; #if SETNETGRENT_RETURNS_INT int #else void #endif setnetgrent(const char *netgroup) { if (strcmp(netgroup, "valid_netgroup") == 0) { netgroup_more = true; #if SETNETGRENT_RETURNS_INT return 1; #else return; #endif } netgroup_more = false; #if SETNETGRENT_RETURNS_INT return 0; #endif } int getnetgrent(char **hostp, char **userp, char **domainp) { if (netgroup_more) { *hostp = NULL; *userp = "user"; *domainp = NULL; netgroup_more = false; return 1; } else { return 0; } } static void test_hostinnetgroup_found(void) { EvalContext *ctx = EvalContextNew(); FnCallResult res; Rlist *args = NULL; RlistAppendScalar(&args, "valid_netgroup"); res = FnCallHostInNetgroup(ctx, NULL, NULL, args); assert_string_equal("any", (char *) res.rval.item); RvalDestroy(res.rval); RlistDestroy(args); EvalContextDestroy(ctx); } static void test_hostinnetgroup_not_found(void) { EvalContext *ctx = EvalContextNew(); FnCallResult res; Rlist *args = NULL; RlistAppendScalar(&args, "invalid_netgroup"); res = FnCallHostInNetgroup(ctx, NULL, NULL, args); assert_string_equal("!any", (char *) res.rval.item); RvalDestroy(res.rval); RlistDestroy(args); EvalContextDestroy(ctx); } #define basename_single_testcase(input, suffix, expected) \ { \ FnCallResult res; \ Rlist *args = NULL; \ \ RlistAppendScalar(&args, input); \ if (suffix != NULL) \ { \ RlistAppendScalar(&args, suffix); \ } \ \ FnCall *call = FnCallNew("basename", args); \ \ res = FnCallBasename(NULL, NULL, call, args); \ assert_string_equal(expected, (char *) res.rval.item); \ \ RvalDestroy(res.rval); \ FnCallDestroy(call); \ } static void test_basename(void) { basename_single_testcase("/", NULL, "/"); basename_single_testcase("//", NULL, "/"); basename_single_testcase("///", NULL, "/"); basename_single_testcase("///////", NULL, "/"); basename_single_testcase("./", NULL, "."); basename_single_testcase(".", NULL, "."); basename_single_testcase("", NULL, ""); basename_single_testcase("/foo/bar", NULL, "bar"); basename_single_testcase("/foo/bar/", NULL, "bar"); basename_single_testcase("//a//b///c////", NULL, "c"); basename_single_testcase("", "", ""); basename_single_testcase("/", "", "/"); basename_single_testcase("/foo/bar.txt", ".txt", "bar"); basename_single_testcase("/foo/bar.txt/", ".txt", "bar"); basename_single_testcase("//a//b///c////", "", "c"); basename_single_testcase("//a//b///c////", "blah", "c"); basename_single_testcase("//a//b///c.csv////", ".csv", "c"); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_hostinnetgroup_found), unit_test(test_hostinnetgroup_not_found), unit_test(test_basename), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/init_script_test_helper.c0000644000000000000000000001300715010704253022566 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include char *SPAWN_PROCESS = NULL; char *SPAWN_PROCESS_ON_SIGNAL = NULL; int REFUSE_TO_DIE = 0; char **NEXT_PROCESS_ARGV = NULL; int NEXT_PROCESS_ARGC = 0; char *PIDFILE = NULL; void spawn_process(const char *program) { pid_t pid = fork(); if (pid < 0) { printf("Could not fork\n"); exit(1); } else if (pid == 0) { const char * args[NEXT_PROCESS_ARGC + 2]; // One for program and one for NULL. args[0] = program; for (int c = 1; c <= NEXT_PROCESS_ARGC; c++) { args[c] = NEXT_PROCESS_ARGV[c-1]; } args[NEXT_PROCESS_ARGC + 1] = NULL; execv(program, (char * const *)args); printf("Could not execute %s\n", program); exit(1); } } void signal_handler(int signal) { (void)signal; // No-op. All the handling is in the main loop } void process_signal(void) { if (SPAWN_PROCESS_ON_SIGNAL) { // Insert artificial delay so that a match for the agent right after // attempting to kill the daemon will not work. Trying to make it as // difficult as possible for the killing script! :-) sleep(1); spawn_process(SPAWN_PROCESS_ON_SIGNAL); } if (!REFUSE_TO_DIE) { if (PIDFILE) { unlink(PIDFILE); } exit(0); } } int main(int argc, char **argv) { sigset_t mask; sigemptyset(&mask); struct sigaction sig; memset(&sig, 0, sizeof(sig)); sig.sa_handler = &signal_handler; sig.sa_mask = mask; const int signals[] = { SIGTERM, SIGQUIT, SIGINT, SIGHUP, 0 }; for (int c = 0; signals[c]; c++) { if (sigaction(signals[c], &sig, NULL) != 0) { printf("Unable to set signal handlers\n"); return 1; } } for (int c = 1; c < argc; c++) { if (strcmp(argv[c], "--spawn-process") == 0) { if (++c + 1 >= argc) { printf("%s requires two arguments\n", argv[c]); return 1; } // The reason for splitting the argument into two parts is to avoid // a false match on a process just because the it has an argument // containing the string we are looking for. SPAWN_PROCESS = malloc(strlen(argv[c]) + strlen(argv[c+1]) + 2); sprintf(SPAWN_PROCESS, "%s/%s", argv[c], argv[c+1]); c++; } else if (strcmp(argv[c], "--spawn-process-on-signal") == 0) { if (++c + 1 >= argc) { printf("%s requires two arguments\n", argv[c]); return 1; } // See comment for SPAWN_PROCESS. SPAWN_PROCESS_ON_SIGNAL = malloc(strlen(argv[c]) + strlen(argv[c+1]) + 2); sprintf(SPAWN_PROCESS_ON_SIGNAL, "%s/%s", argv[c], argv[c+1]); c++; } else if (strcmp(argv[c], "--refuse-to-die") == 0) { REFUSE_TO_DIE = 1; } else if (strcmp(argv[c], "--pass-to-next-process") == 0) { // Stops argument processing and passes all remaining arguments to // the spawned process instead. NEXT_PROCESS_ARGV = &argv[++c]; NEXT_PROCESS_ARGC = argc - c; break; } else { printf("Unknown argument: %s\n", argv[c]); return 1; } } const char *piddir = getenv("CFTEST_PREFIX"); if (piddir) { const char *file = strrchr(argv[0], '/'); file++; PIDFILE = malloc(strlen(piddir) + strlen(file) + 6); sprintf(PIDFILE, "%s/%s.pid", piddir, file); } pid_t child = fork(); if (child < 0) { printf("Could not fork\n"); exit(1); } else if (child > 0) { // Daemonize. if (PIDFILE) { FILE *fptr = fopen(PIDFILE, "w"); if (!fptr) { printf("Could not open file %s\n", PIDFILE); exit(1); } fprintf(fptr, "%d\n", (int)child); fclose(fptr); } return 0; } if (SPAWN_PROCESS) { spawn_process(SPAWN_PROCESS); } // 60 seconds of consecutive sleep will end the program, just so that we do // in fact terminate if we are left over. while (sleep(60) != 0) { // If we didn't sleep the whole time, then it must be a signal. process_signal(); } return 1; } cfengine-3.24.2/tests/unit/lastseen_migration_test.c0000644000000000000000000001467315010704253022601 0ustar00rootroot00000000000000#include #include #include #include #include /* xsnprintf */ #include #ifdef LMDB int main() { return 0; } #else typedef struct { char address[128]; double q; double expect; double var; } KeyHostSeen0; char CFWORKDIR[CF_BUFSIZE]; void tests_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/lastseen_migration_test.XXXXXX"; char *workdir = strchr(env, '=') + 1; /* start of the path */ assert(workdir - 1 && workdir[0] == '/'); mkdtemp(workdir); strlcpy(CFWORKDIR, workdir, CF_BUFSIZE); putenv(env); mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); } /* * Provides empty lastseen DB */ static DBHandle *setup(bool clean) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'/*", GetStateDir()); system(cmd); DBHandle *db; OpenDB(&db, dbid_lastseen); if (clean) { /* There is no way to disable hook in OpenDB yet, so just undo * everything */ DBCursor *cursor; if (!NewDBCursor(db, &cursor)) { return NULL; } char *key; void *value; int ksize, vsize; while (NextDB(cursor, &key, &ksize, &value, &vsize)) { DBCursorDeleteEntry(cursor); } if (!DeleteDBCursor(cursor)) { return NULL; } } return db; } static void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } static void test_no_migration(void) { DBHandle *db = setup(true); CloseDB(db); /* Migration on empty DB should produce single "version" key */ assert_int_equal(OpenDB(&db, dbid_lastseen), true); DBCursor *cursor; assert_int_equal(NewDBCursor(db, &cursor), true); char *key; void *value; int ksize, vsize; while (NextDB(cursor, &key, &ksize, &value, &vsize)) { assert_int_equal(ksize, strlen("version") + 1); assert_string_equal(key, "version"); assert_int_equal(vsize, 2); assert_string_equal(value, "1"); } assert_int_equal(DeleteDBCursor(cursor), true); CloseDB(db); } static void test_up_to_date(void) { /* Test that upgrade is not performed if there is already a version * marker */ DBHandle *db = setup(false); const char *value = "+"; assert_int_equal(WriteDB(db, "+++", value, 2), true); CloseDB(db); /* Test that manually inserted key which matches the format of old-style * keys is still present next time database is open, which is an indicator * of database not being upgraded */ assert_int_equal(OpenDB(&db, dbid_lastseen), true); char read_value[CF_BUFSIZE]; assert_int_equal(ReadDB(db, "+++", &read_value, sizeof(read_value)), true); assert_string_equal(read_value, "+"); CloseDB(db); } #define KEYHASH \ "SHA=f7b335bef201230c7bf573b8dedf299fa745efe71e34a9002369248ff8519089" #define KEYHASH_KEY "k" KEYHASH #define KEYHASH_IN "-" KEYHASH #define QUALITY_IN "qi" KEYHASH #define KEYHASH_OUT "+" KEYHASH #define QUALITY_OUT "qo" KEYHASH void test_migrate_single(const char *expected_old_key, const char *expected_quality_key) { /* Test migration of single entry */ DBHandle *db = setup(true); KeyHostSeen0 khs0 = { .q = 666777.0, .expect = 12345.0, .var = 6543210.0, }; strcpy(khs0.address, "1.2.3.4"); assert_int_equal(WriteDB(db, expected_old_key, &khs0, sizeof(khs0)), true); CloseDB(db); assert_int_equal(OpenDB(&db, dbid_lastseen), true); /* Old entry migrated */ assert_int_equal(HasKeyDB(db, expected_old_key, strlen(expected_old_key) + 1), false); /* Version marker */ assert_int_equal(HasKeyDB(db, "version", strlen("version") + 1), true); /* Incoming connection quality */ KeyHostSeen khs; assert_int_equal(ReadDB(db, expected_quality_key, &khs, sizeof(khs)), true); assert_int_equal(khs.lastseen, 666777); assert_double_close(khs.Q.q, 12345.0); assert_double_close(khs.Q.expect, 12345.0); assert_double_close(khs.Q.var, 6543210.0); /* Address mapping */ char address[CF_BUFSIZE]; assert_int_equal(ReadDB(db, KEYHASH_KEY, address, sizeof(address)), true); assert_string_equal(address, "1.2.3.4"); /* Reverse mapping */ char keyhash[CF_BUFSIZE]; assert_int_equal(ReadDB(db, "a1.2.3.4", keyhash, sizeof(keyhash)), true); assert_string_equal(keyhash, KEYHASH); CloseDB(db); } void test_migrate_incoming(void) { test_migrate_single(KEYHASH_IN, QUALITY_IN); } void test_migrate_outgoing(void) { test_migrate_single(KEYHASH_OUT, QUALITY_OUT); } void test_ignore_wrong_sized(void) { /* Test that malformed values are discarded */ DBHandle *db = setup(true); const char *value = "+"; assert_int_equal(WriteDB(db, "+++", value, 2), true); CloseDB(db); assert_int_equal(OpenDB(&db, dbid_lastseen), true); assert_int_equal(HasKeyDB(db, "+++", 4), false); assert_int_equal(HasKeyDB(db, "k++", 4), false); assert_int_equal(HasKeyDB(db, "qi++", 5), false); assert_int_equal(HasKeyDB(db, "qo++", 5), false); assert_int_equal(HasKeyDB(db, "a+", 3), false); CloseDB(db); } int main() { tests_setup(); const UnitTest tests[] = { unit_test(test_no_migration), unit_test(test_up_to_date), unit_test(test_migrate_incoming), unit_test(test_migrate_outgoing), unit_test(test_ignore_wrong_sized), }; PRINT_TEST_BANNER(); int ret = run_tests(tests); tests_teardown(); return ret; } /* STUBS */ void FatalError(ARG_UNUSED char *s, ...) { fail(); exit(42); } HashMethod CF_DEFAULT_DIGEST; pthread_mutex_t *cft_output; char VIPADDRESS[CF_MAX_IP_LEN]; RSA *PUBKEY; bool MINUSF; char *MapAddress(ARG_UNUSED char *addr) { fail(); } char *HashPrintSafe(ARG_UNUSED char *dst, ARG_UNUSED size_t dst_size, ARG_UNUSED const unsigned char *digest, ARG_UNUSED HashMethod type, ARG_UNUSED bool use_prefix) { fail(); } void HashPubKey(ARG_UNUSED const RSA *key, ARG_UNUSED unsigned char digest[EVP_MAX_MD_SIZE + 1], ARG_UNUSED HashMethod type) { fail(); } #endif // LMDB cfengine-3.24.2/tests/unit/passopenfile_test.c0000644000000000000000000011074115010704253021373 0ustar00rootroot00000000000000#include #include #include #include #ifndef __MINGW32__ #include #include #include #endif /* !__MINGW32__ */ #include /* Whether to re-use Unix Domain Sockets * * Strictly, the API is only advertised to be fit for sending *one* * descriptor over each UDS; but there's no reason it shouldn't work * for more - and stressing it is good. Enabling REUSE_UDS thus * semi-abuses the API to stress it a bit more. #define REUSE_UDS */ /* Globals used by the tests. */ static int SPAWNED_PID = -1; /* child used as other process in each test */ static char DIALUP[PATH_MAX] = ""; /* synchronisation file for listen()/connect() */ static bool DIALEDUP = false; /* TODO - not really testing this API, but testing we can use it * securely: test that the listener can secure its socket to only be * connect()ed to by the same user; likewise by one in its group. * Probably put that test in some other file ! */ /* Ensure no stray child is running. */ static void wait_for_child(bool impatient) { if (SPAWNED_PID == -1) /* it's BAD to run kill(-1) */ { return; } while(true) { if (impatient) { errno = 0; int ret = kill(SPAWNED_PID, SIGKILL); if (ret == -1 && errno == ESRCH) { Log(LOG_LEVEL_VERBOSE, "Child process to be killed does not exist (PID %jd)", (intmax_t) SPAWNED_PID); break; /* process does not exist */ } Log(LOG_LEVEL_NOTICE, "Killed previous child process (PID %jd)", (intmax_t) SPAWNED_PID); } if (waitpid(SPAWNED_PID, NULL, 0) > 0) { Log(LOG_LEVEL_VERBOSE, "Child process is dead and has been reaped (PID %jd)", (intmax_t) SPAWNED_PID); break; /* zombie reaped properly */ } } SPAWNED_PID = -1; } static bool wait_for_io(int whom, bool write) { struct timeval tv; fd_set fds; FD_ZERO(&fds); FD_SET(whom, &fds); tv.tv_sec = 10; /* 10s timeout for select() */ tv.tv_usec = 0; int ret; if (write) { ret = select(whom + 1, NULL, &fds, NULL, &tv); } else { ret = select(whom + 1, &fds, NULL, NULL, &tv); } if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed select: %s", GetErrorStr()); } else if (!FD_ISSET(whom, &fds)) { Log(LOG_LEVEL_ERR, "Timed out select() for descriptor %d", whom); } return ret > 0 && FD_ISSET(whom, &fds); } /* Whoever connect()s needs to wait for the other to bind() and listen(): */ static bool wait_for_dialup(bool write) { assert(DIALUP[0] != '\0'); for (int i = 5; i-- > 0;) { if (access(DIALUP, write ? W_OK : R_OK) == 0) /* bind() has happened */ { sleep(1); /* To let listen() happen, too. */ return true; } sleep(1); } Log(LOG_LEVEL_ERR, "Failed to access %s as synchronisation file: %s", DIALUP, GetErrorStr()); return false; } /* Used, via atexit(), to ensure we delete the file if we create it at the * exit of all processes, either parent or children. */ static void clear_listener(void) { if (DIALEDUP) { assert(DIALUP[0] != '\0'); Log(LOG_LEVEL_VERBOSE, "Cleaning up UDS file"); unlink(DIALUP); DIALEDUP = false; } } static void clear_previous_test(void) { /* KILL possible child. */ wait_for_child(true); /* Clear possible UDS file created by this process (parent). */ if (DIALEDUP) { clear_listener(); } /* What if child got KILLed and never cleaned its UDS file? */ struct stat statbuf; if (stat(DIALUP, &statbuf) != -1) { Log(LOG_LEVEL_NOTICE, "UDS file from previous test still exists, " "maybe child did not clean up? Removing and continuing..."); unlink(DIALUP); } } /* Choose a file for the Unix Domain Socket, by which to connect() to the * bind()er. */ static bool choose_dialup_UDS_file(void) { if (DIALUP[0] == '\0') { /* Using insecure tempnam(). * * There really isn't any sensible alternative. What we need * is a file *name* for use in the address we bind() and * connect() to. A file descriptor (from mkstemp) or FILE* * (from tmpfile) does us no good. The former would at least * give us a unique filename, but we'd be unlink()ing the file * it creates in order to actually bind() to it, and we'd have * the exact same race condition as tempnam between when we * bind() and when we connect(). This is a deficiency of the * UDS APIs that we just have to live with. In production, we * need to make sure we use a UDS based on a file somewhere we * secure suitably (e.g. in a directory owned by root and * inaccessible to anyone else). The "cfpof" stands for * CF(Engine) Pass Open File, in case you wondered. */ char *using = tempnam("/tmp", "cfpof"); if (using == NULL) { Log(LOG_LEVEL_ERR, "Failed tempnam: %s", GetErrorStr()); } else { assert(using[0]); /* non-empty */ strlcpy(DIALUP, using, sizeof(DIALUP)); free(using); Log(LOG_LEVEL_VERBOSE, "Synchronising UDS via %s", DIALUP); } } return DIALUP[0] != '\0'; } /* Set up listen()ing socket; used by one process in each test. */ static int setup_listener(void) { /* Create "server" socket, bind() it, listen() on it, return it. */ assert(DIALUP[0] != '\0'); { /* The Unix Domain Socket file was cleaned up in the previous test. */ struct stat statbuf; bool UDS_exists = (stat(DIALUP, &statbuf) != -1); assert_false(UDS_exists); } int server = socket(AF_UNIX, SOCK_STREAM, 0); if (server >= 0) { Log(LOG_LEVEL_VERBOSE, "Opened %d to bind to and listen on.", server); if (server < FD_SETSIZE) /* else problem for FD_SET when select()ing */ { struct sockaddr_un address = { 0 }; assert(strlen(DIALUP) < sizeof(address.sun_path)); address.sun_family = AF_UNIX; strlcpy(address.sun_path, DIALUP, sizeof(address.sun_path)); Log(LOG_LEVEL_VERBOSE, "Attempting to bind(%d, ...)", server); if (bind(server, (struct sockaddr *)&address, sizeof(address)) == 0) { /* That's created the file DIALUP, that we now have a * duty to tidy away. */ DIALEDUP = true; Log(LOG_LEVEL_VERBOSE, "Calling listen(%d, 1)", server); if (listen(server, 2) == 0) { /* Success */ return server; } else { Log(LOG_LEVEL_ERR, "Failed listen: %s", GetErrorStr()); } } else { Log(LOG_LEVEL_ERR, "Failed bind: %s", GetErrorStr()); } } cf_closesocket(server); } else { Log(LOG_LEVEL_ERR, "Failed socket: %s", GetErrorStr()); } return -1; } /* Set up Unix Domain Sockets. * * One of parent and child uses setup_accept(); the other uses * setup_connect(). Each gets a UDS back. One wants to write to the * result, the other wants to read from it. These two two-way choices * give us four tests. */ static int setup_accept(int server, bool write) { /* When listening socket is ready, accept(); wait for the result * to be ready to read/write. */ assert(server >= 0); Log(LOG_LEVEL_VERBOSE, "Calling accept(%d, NULL, NULL)", server); if (wait_for_io(server, false)) { int uds = accept(server, NULL, NULL); if (uds == -1) { Log(LOG_LEVEL_ERR, "Failed accept: %s", GetErrorStr()); } else if (uds < FD_SETSIZE && /* else problem for FD_SET when select()ing */ wait_for_io(uds, write)) { Log(LOG_LEVEL_VERBOSE, "Ready to use accept()ed UDS %d", uds); return uds; /* Success */ } else { Log(LOG_LEVEL_ERR, "Unable to %s on accept()ed Unix Domain Socket", write ? "write" : "read"); cf_closesocket(uds); } } return -1; } static int setup_connect(bool write) { /* Create socket, connect() to the listening socket, wait until * ready to read/write */ int uds = socket(AF_UNIX, SOCK_STREAM, 0); if (uds >= 0) { if (uds < FD_SETSIZE && /* else problem for FD_SET when select()ing */ wait_for_dialup(write)) { struct sockaddr_un address; assert(strlen(DIALUP) < sizeof(address.sun_path)); address.sun_family = AF_UNIX; strlcpy(address.sun_path, DIALUP, sizeof(address.sun_path)); if (connect(uds, (struct sockaddr *)&address, sizeof(address)) == 0 && wait_for_io(uds, write)) { Log(LOG_LEVEL_VERBOSE, "Ready to use connect()ed UDS %d", uds); return uds; /* Success */ } else { Log(LOG_LEVEL_ERR, "Failed connect (or select): %s", GetErrorStr()); } } cf_closesocket(uds); } else { Log(LOG_LEVEL_ERR, "Failed socket: %s", GetErrorStr()); } return -1; } /* Wrapper to set up a Unix Domain Socket. * * Variants on the child/parent processes are given a listening socket * on which to accept() or -1 to tell them to connect(). This * function mediates that choice for them. It probably gets inlined. */ static int setup_uds(int server, bool write) { return server < 0 ? setup_connect(write) : setup_accept(server, write); } /* Reverse of setup_pipe: */ static void close_pipe(int pair[2]) { int idx = 2; while (idx-- > 0) { if (pair[idx] >= 0) { cf_closesocket(pair[idx]); pair[idx] = -1; } } } /* Socket pair used by the conversation between processes over the * exchanged descriptors. */ static bool setup_pipe(int pipe[2]) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe) == 0) { /* No need to make them non-blocking ! */ return true; } Log(LOG_LEVEL_ERR, "Failed socketpair: %s", GetErrorStr()); return false; } /* Check we can use transferred sockets. * * For the parent-child dialogs, we only try one direction. Each end * actually has both ends of the pipe, but trying to communicate both * ways gets mixed up with the communication we're doing with the * given ends. */ const char FALLBACK[] = "\0Fallback Message"; /* Parent's half: checks everything. */ static bool check_hail(int sock, const char *message) { const char *msg = message ? message : (FALLBACK + 1); const size_t msglen = message ? strlen(message) : sizeof(FALLBACK); const char noise[] = "The quick brown fox jumps over the lazy dog"; char buffer[80]; assert(msglen && msglen < sizeof(buffer)); strlcpy(buffer, noise, sizeof(buffer)); errno = 0; ssize_t sent; if (!wait_for_io(sock, true)) { /* wait_for_io already Log()ged. */ } else if (0 > (sent = send(sock, "hello", 6, 0))) { Log(LOG_LEVEL_ERR, "Parent failed to send 'hello': %s", GetErrorStr()); } else if (sent != 6) { Log(LOG_LEVEL_ERR, "Parent sent wrong length (%zd != 5) for 'hello'", sent); } else if (!wait_for_io(sock, false)) { /* wait_for_io already Log()ged. */ } else if (0 > (sent = recv(sock, buffer, sizeof(buffer), 0))) { Log(LOG_LEVEL_ERR, "Parent failed to receive '%s': %s", msg, GetErrorStr()); } else if (sent != msglen) { buffer[MIN(sent, sizeof(buffer) - 1)] = '\0'; Log(LOG_LEVEL_ERR, "Parent received wrong length (%zd != %zd) for '%s' != %s", sent, msglen, (message || buffer[0]) ? buffer : (buffer + 1), msg); } else if (strcmp(buffer + msglen, noise + msglen) != 0) { buffer[sizeof(buffer) - 1] = '\0'; Log(LOG_LEVEL_ERR, "Parent recv() trampled buffer: %s", buffer); } else { buffer[msglen] = '\0'; if (message ? strcmp(buffer, message) == 0 : (buffer[0] == '\0' && strcmp(buffer + 1, FALLBACK + 1) == 0)) { return true; } Log(LOG_LEVEL_ERR, "Parent received wrong text '%s' != '%s'", (message || buffer[0]) ? buffer : (buffer + 1), msg); } return false; } /* Dummy conversational partner for check_hail (used in child). */ static void child_hail(int sock, const char *message) { const size_t msglen = message ? strlen(message) : sizeof(FALLBACK); char buffer[80]; if (wait_for_io(sock, false) && recv(sock, buffer, sizeof(buffer), 0) == 6 && strcmp(buffer, "hello") == 0 && wait_for_io(sock, true)) { send(sock, message ? message : FALLBACK, msglen, 0); } } /* Similar but for a parent talking to self after child died. * * For this one, we test two-way communications, since we're inside a * single process, where that should all work fine. OTOH, we don't * bother with the buffer-overrun checks and other complications * addressed by check_hail(). */ static bool self_hail(int pair[2]) { /* We send these with sizeof(), so include the '\0' endings. * They should thus be received with those endings at buffer[sent - 1]. */ const char exclaim[] = "Dead! Dead!", lament[] = "And never called me mother"; char buffer[80]; ssize_t sent; if (!wait_for_io(pair[0], true)) { /* wait_for_io already Log()ged. */ } else if (0 > (sent = send(pair[0], exclaim, sizeof(exclaim), 0))) { Log(LOG_LEVEL_ERR, "Failed to send exclamation (send: %s)", GetErrorStr()); } else if (sent != sizeof(exclaim)) { Log(LOG_LEVEL_ERR, "Sent wrong-sized exclamation: %zd != %zu", sent, sizeof(exclaim)); } else if (!wait_for_io(pair[1], false)) { /* wait_for_io already Log()ged. */ } else if (0 > (sent = recv(pair[1], buffer, sizeof(buffer), 0))) { Log(LOG_LEVEL_ERR, "Failed to receive exclamation (recv: %s)", GetErrorStr()); } else if (sent != sizeof(exclaim) || buffer[sent - 1]) { buffer[MIN(sent, sizeof(buffer) - 1)] = '\0'; Log(LOG_LEVEL_ERR, "Received wrong-sized exclamation (%zd != %zu): %s", sent, sizeof(exclaim), buffer); } else if (strcmp(buffer, exclaim) != 0) { buffer[MIN(sent, sizeof(buffer) - 1)] = '\0'; Log(LOG_LEVEL_ERR, "Mismatch in exclamation: '%s' != '%s'", buffer, exclaim); } else if (!wait_for_io(pair[1], true)) { /* wait_for_io already Log()ged. */ } else if (0 > (sent = send(pair[1], lament, sizeof(lament), 0))) { Log(LOG_LEVEL_ERR, "Failed to send lament (send: %s)", GetErrorStr()); } else if (sent != sizeof(lament)) { Log(LOG_LEVEL_ERR, "Sent wrong-sized lament: %zd != %zu", sent, sizeof(lament)); } else if (!wait_for_io(pair[0], false)) { /* wait_for_io already Log()ged. */ } else if (0 > (sent = recv(pair[0], buffer, sizeof(buffer), 0))) { Log(LOG_LEVEL_ERR, "Failed to receive lament (recv: %s)", GetErrorStr()); } else if (sent != sizeof(lament)) { buffer[MIN(sent, sizeof(buffer) - 1)] = '\0'; Log(LOG_LEVEL_ERR, "Received wrong-sized lament (%zd != %zu): %s", sent, sizeof(lament), buffer); } else if (strcmp(buffer, lament) != 0) { Log(LOG_LEVEL_ERR, "Mismatch in lament: '%s' != '%s'", buffer, lament); } else { return true; } return false; } /* Variants on the child/parent process. * * In each case the sending process creates a socket pair (setup_pipe) * and passes both ends to the other process; after that, they have * the conversation above (see *_hail) using these sockets. * * For the two-process tests, three things are tested (each setting a * bool variable for the parent): sending a descriptor attending to * any accompanying message (word), sending a descriptor ignoring * message (none) and using one each of the shared descriptors to * communicate between processes (chat). For the test by a parent * after its child has died, only success of the conversation is * recorded to pass back to the parent. * * Naturally, the details (particularly synchronisation) are trickier * than that. See REUSE_UDS, above, for one complication. * * We have one parent_*()/child_*() pair for the parent as sending * process with the child receiving, one pair the other way round and * one for the parent that outlives its child. In each test, one of * parent and child is passed a listening socket on which to accept() * UDS connections; the other is passed -1 and connect()s to it. The * former has a duty to close the listening socket. For each of the * resulting combinations, the two-process tests then have one test in * which the non-ignored message is NULL (*_silent) and another in * which it has some content (*_message). */ static void child_for_outlive(int server) { /* Parent takes, so the child must send. */ int pipe[2]; if (setup_pipe(pipe)) { int uds = setup_uds(server, true); if (uds >= 0) { PassOpenFile_Put(uds, pipe[1], NULL); #ifndef REUSE_UDS cf_closesocket(uds); } uds = setup_uds(server, true); if (uds >= 0) { #endif /* REUSE_UDS */ #ifdef REUSE_UDS wait_for_io(uds, true) && #endif PassOpenFile_Put(uds, pipe[0], NULL); cf_closesocket(uds); } close_pipe(pipe); } if (server != -1) { cf_closesocket(server); } } static bool parent_outlive(int server, bool *chat) { int pair[2] = { -1, -1 }; bool result = true; *chat = false; int uds = setup_uds(server, false); #ifdef REUSE_UDS if (server != -1) { cf_closesocket(server); } #endif if (uds < 0) { result = false; } else { char *text = NULL; pair[1] = PassOpenFile_Get(uds, &text); free(text); text = NULL; #ifndef REUSE_UDS cf_closesocket(uds); } uds = setup_uds(server, false); if (server != -1) { cf_closesocket(server); } if (uds < 0) { result = false; } else { #endif /* REUSE_UDS */ pair[0] = #ifdef REUSE_UDS !wait_for_io(uds, false) ? -1 : #endif PassOpenFile_Get(uds, NULL); cf_closesocket(uds); if (pair[0] < 0) { Log(LOG_LEVEL_ERR, "Parent failed to receive descriptor (ignoring text)"); } else if (pair[1] >= 0) { Log(LOG_LEVEL_VERBOSE, "Parent received both descriptors"); wait_for_child(false); /* Don't kill, be patient. */ *chat = self_hail(pair); } } close_pipe(pair); return result; } /* Child sends descriptors to parent. * * In this case, verifying we get the right message can be done * directly by the parent on receiving the message. */ static void child_for_take(int server, const char *message) { /* Of course, for the parent to take, the child must send. */ int pipe[2]; if (setup_pipe(pipe)) { bool sent = false; int uds = setup_uds(server, true); if (uds >= 0) { sent = PassOpenFile_Put(uds, pipe[1], message); #ifndef REUSE_UDS cf_closesocket(uds); } uds = setup_uds(server, true); if (uds >= 0) { #endif /* REUSE_UDS */ sent = #ifdef REUSE_UDS wait_for_io(uds, true) && #endif PassOpenFile_Put(uds, pipe[0], message) && sent; cf_closesocket(uds); } if (sent) { Log(LOG_LEVEL_VERBOSE, "Child delivered both descriptors"); child_hail(pipe[0], message); } close_pipe(pipe); } if (server != -1) { cf_closesocket(server); } } static bool parent_take(int server, const char *message, bool *word, bool *none, bool *chat) { int pair[2] = { -1, -1 }; bool result = true; *word = *none = *chat = false; int uds = setup_uds(server, false); #ifdef REUSE_UDS if (server != -1) { cf_closesocket(server); } #endif if (uds < 0) { result = false; } else { char *text = NULL; pair[1] = PassOpenFile_Get(uds, &text); *word = pair[1] >= 0 && (message ? text && strcmp(text, message) == 0 : !text); free(text); text = NULL; #ifndef REUSE_UDS cf_closesocket(uds); } uds = setup_uds(server, false); if (server != -1) { cf_closesocket(server); } if (uds < 0) { result = false; } else { #endif /* REUSE_UDS */ pair[0] = #ifdef REUSE_UDS !wait_for_io(uds, false) ? -1 : #endif PassOpenFile_Get(uds, NULL); cf_closesocket(uds); if (pair[0] < 0) { Log(LOG_LEVEL_ERR, "Parent failed to receive descriptor (ignoring text)"); } else { *none = true; if (pair[1] >= 0) { Log(LOG_LEVEL_VERBOSE, "Parent received both descriptors"); *chat = check_hail(pair[1], message); } } } close_pipe(pair); return result; } /* Parent sends to child. * * Verifying the message is transmitted correctly depends on the child * sending the message back as part of the conversation after we * exchange descriptors. */ static void child_for_send(int server) { /* Of course, for the parent to send, the child must take. */ int pair[2] = { -1, -1 }; int uds = setup_uds(server, false); #ifdef REUSE_UDS if (server != -1) { cf_closesocket(server); } #endif if (uds >= 0) { pair[1] = PassOpenFile_Get(uds, NULL); if (pair[1] < 0) { Log(LOG_LEVEL_ERR, "Child failed to receive descriptor (ignoring text)"); } #ifndef REUSE_UDS cf_closesocket(uds); } uds = setup_uds(server, false); if (server >= 0) { cf_closesocket(server); } if (uds >= 0) { #endif /* REUSE_UDS */ char *text = NULL; pair[0] = #ifdef REUSE_UDS !wait_for_io(uds, false) ? -1 : #endif PassOpenFile_Get(uds, &text); cf_closesocket(uds); if (pair[0] < 0) { Log(LOG_LEVEL_ERR, "Child failed to receive descriptor"); } else if (pair[1] >= 0) { Log(LOG_LEVEL_VERBOSE, "Child received both descriptors (%s %s)", text ? "text:" : "no", text ? text : "text"); child_hail(pair[1], text); } free(text); } close_pipe(pair); } static bool parent_send(int server, const char *message, bool *word, bool *none, bool *chat) { /* We have a duty to close(server) if not -1 */ bool result = false; int pipe[2]; *word = *none = *chat = false; if (setup_pipe(pipe)) { result = true; *word = *none = *chat = false; int uds = setup_uds(server, true); if (uds < 0) { result = false; } else { *none = PassOpenFile_Put(uds, pipe[1], message); #ifndef REUSE_UDS cf_closesocket(uds); } uds = setup_uds(server, true); if (uds < 0) { result = false; } else { #endif /* REUSE_UDS */ *word = #ifdef REUSE_UDS wait_for_io(uds, true) && #endif PassOpenFile_Put(uds, pipe[0], message); cf_closesocket(uds); } if (*word && *none) { Log(LOG_LEVEL_VERBOSE, "Parent delivered both descriptors"); *chat = check_hail(pipe[0], message); } close_pipe(pipe); } if (server != -1) { cf_closesocket(server); } return result; } /* The actual tests, built on those tools. * * Classified according to whether parent is listen()ing or * connect()ing, with the child doing the other, and whether parent is * sending or taking descriptors from child. The parent is * responsible for all testing, although the child helps out via the * chatter on exchanged sockets. */ static void test_take_listen_message(void) { clear_previous_test(); const char message[] = "verbiage"; pid_t new_pid = fork(); if (new_pid == 0) { /* child */ child_for_take(-1, message); exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Parent failed to set up listener"); } else { bool word, none, chat; if (parent_take(server, message, &word, &none, &chat)) { assert_true(word && "can receive fd with a message"); assert_true(none && "can receive fd ignoring message"); assert_true(chat && "can use the received fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } Log(LOG_LEVEL_ERR, "Failed to set up UDS"); } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_take_connect_message(void) { clear_previous_test(); const char message[] = "waffle"; pid_t new_pid = fork(); if (new_pid == 0) { /* child */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Child failed to set up listener"); } else { child_for_take(server, message); } exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ bool word, none, chat; if (parent_take(-1, message, &word, &none, &chat)) { assert_true(word && "can receive fd with a message"); assert_true(none && "can receive fd ignoring message"); assert_true(chat && "can use the received fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } Log(LOG_LEVEL_ERR, "Failed to set up parent"); } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_send_listen_message(void) { clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ child_for_send(-1); exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Parent failed to set up listener"); } else { bool word, none, chat; if (parent_send(server, "mumble", &word, &none, &chat)) { assert_true(word && "can transmit fd with a message"); assert_true(none && "can transmit fd ignoring message"); assert_true(chat && "can use the transmitted fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } Log(LOG_LEVEL_ERR, "Failed to set up parent"); } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_send_connect_message(void) { clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Child failed to set up listener"); } else { child_for_send(server); } exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ bool word, none, chat; if (parent_send(-1, "mutter", &word, &none, &chat)) { assert_true(word && "can transmit fd with a message"); assert_true(none && "can transmit fd ignoring message"); assert_true(chat && "can use the transmitted fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_take_listen_silent(void) { clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ child_for_take(-1, NULL); exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Parent failed to set up listener"); } else { bool word, none, chat; if (parent_take(server, NULL, &word, &none, &chat)) { assert_true(word && "can receive fd with no message"); assert_true(none && "can receive fd ignoring no message"); assert_true(chat && "can use the received fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } Log(LOG_LEVEL_ERR, "Failed to set up UDS"); } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_take_connect_silent(void) { clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Child failed to set up listener"); } else { child_for_take(server, NULL); } exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ bool word, none, chat; if (parent_take(-1, NULL, &word, &none, &chat)) { assert_true(word && "can receive fd with no message"); assert_true(none && "can receive fd ignoring no message"); assert_true(chat && "can use the received fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } Log(LOG_LEVEL_ERR, "Failed to set up parent"); } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_send_listen_silent(void) { clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ child_for_send(-1); exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Parent failed to set up listener"); } else { bool word, none, chat; if (parent_send(server, NULL, &word, &none, &chat)) { assert_true(word && "can transmit fd with no message"); assert_true(none && "can transmit fd ignoring no message"); assert_true(chat && "can use the transmitted fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } Log(LOG_LEVEL_ERR, "Failed to set up parent"); } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_send_connect_silent(void) { clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Child failed to set up listener"); } else { child_for_send(server); } exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ bool word, none, chat; if (parent_send(-1, NULL, &word, &none, &chat)) { assert_true(word && "can transmit fd with no message"); assert_true(none && "can transmit fd ignoring no message"); assert_true(chat && "can use the transmitted fds"); if (waitpid(new_pid, NULL, 1) > 0) { SPAWNED_PID = -1; } return; } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_connect_outlive(void) { #ifdef __APPLE__ // FIXME: This test has spurios errors on OS X in travis return; #endif clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ child_for_outlive(-1); exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ bool chat; int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Parent failed to set up listener"); } else if (parent_outlive(server, &chat)) { assert_true(chat && "can use received fds after sender exits"); return; } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } static void test_listen_outlive(void) { #ifdef __APPLE__ // FIXME: This test has spurios errors on OS X in travis return; #endif clear_previous_test(); pid_t new_pid = fork(); if (new_pid == 0) { /* child */ int server = setup_listener(); if (server < 0) { Log(LOG_LEVEL_ERR, "Child failed to set up listener"); } else { child_for_outlive(server); } exit(0); } else if (new_pid > 0) { SPAWNED_PID = new_pid; /* parent */ bool chat; if (parent_outlive(-1, &chat)) { assert_true(chat && "can use received fds after sender exits"); return; } } else { Log(LOG_LEVEL_ERR, "Failed fork: %s", GetErrorStr()); } assert_true(false); } /* The driver */ int main(void) { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_take_listen_message), unit_test(test_take_connect_message), unit_test(test_send_listen_message), unit_test(test_send_connect_message), unit_test(test_take_listen_silent), unit_test(test_take_connect_silent), unit_test(test_send_listen_silent), unit_test(test_send_connect_silent), unit_test(test_connect_outlive), unit_test(test_listen_outlive) }; #if 0 /* 1: toggle as needed. */ LogSetGlobalLevel(LOG_LEVEL_VERBOSE); #endif /* Needed to clean up the UDS created from the children, when they exit(), for each test that the child calls setup_listener. Also cleans the last socket (created by this parent process) when this testsuite exit. */ atexit(clear_listener); int retval; if (choose_dialup_UDS_file() == true) { retval = run_tests(tests); } else { retval = EXIT_FAILURE; } /* Make sure no child is left behind. */ if (SPAWNED_PID >= 0) { kill(SPAWNED_PID, SIGKILL); } return retval; } cfengine-3.24.2/tests/unit/package_versions_compare_test.c0000644000000000000000000002213315010704253023731 0ustar00rootroot00000000000000#include #include #include #include void test_different_name(void) { EvalContext *ctx = EvalContextNew(); PromiseResult result; PackageItem pi = { .name = "pkgone", .version = "1", .arch = "arch" }; Attributes attr = { .packages = { .package_select = PACKAGE_VERSION_COMPARATOR_EQ } }; assert_int_equal(ComparePackages(ctx, "pkgtwo", "1", "arch", &pi, &attr, NULL, "test", &result), VERCMP_NO_MATCH); EvalContextDestroy(ctx); } void test_wildcard_arch(void) { EvalContext *ctx = EvalContextNew(); PromiseResult result; PackageItem pi = { .name = "foobar", .version = "1", .arch = "arch" }; Attributes attr = { .packages = { .package_select = PACKAGE_VERSION_COMPARATOR_EQ } }; assert_int_equal(ComparePackages(ctx, "foobar", "1", "*", &pi, &attr, NULL, "test", &result), VERCMP_MATCH); EvalContextDestroy(ctx); } void test_non_matching_arch(void) { EvalContext *ctx = EvalContextNew(); PromiseResult result; PackageItem pi = { .name = "foobar", .version = "1", .arch = "s390x" }; Attributes attr = { .packages = { .package_select = PACKAGE_VERSION_COMPARATOR_EQ } }; assert_int_equal(ComparePackages(ctx, "foobar", "1", "s390", &pi, &attr, NULL, "test", &result), VERCMP_NO_MATCH); EvalContextDestroy(ctx); } VersionCmpResult DoCompare(const char *lhs, const char *rhs, PackageVersionComparator cmp) { EvalContext *ctx = EvalContextNew(); PromiseResult result; PackageItem pi = { .name = "foobar", .version = (char*)lhs, .arch = "somearch" }; Attributes a = { .packages = { .package_select = cmp, } }; VersionCmpResult cmp_result = ComparePackages(ctx, "foobar", rhs, "somearch", &pi, &a, NULL, "test", &result); EvalContextDestroy(ctx); return cmp_result; } void test_wildcard_version(void) { assert_int_equal(DoCompare("1.0-1", "*", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_MATCH); } void test_eq(void) { assert_int_equal(DoCompare("1.0-1", "1.0-1", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-1", PACKAGE_VERSION_COMPARATOR_NONE), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-2", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_NO_MATCH); } void test_ne(void) { assert_int_equal(DoCompare("1.0-1", "1.0-1", PACKAGE_VERSION_COMPARATOR_NEQ), VERCMP_NO_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-2", PACKAGE_VERSION_COMPARATOR_NEQ), VERCMP_MATCH); } void test_gt_lt(void) { assert_int_equal(DoCompare("1.0-1", "1.0-1", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_NO_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-2", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_NO_MATCH); assert_int_equal(DoCompare("1.0-2", "1.0-1", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-1", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_NO_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-2", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-2", "1.0-1", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_NO_MATCH); } void test_gte_lte(void) { assert_int_equal(DoCompare("1.0-1", "1.0-1", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-2", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_NO_MATCH); assert_int_equal(DoCompare("1.0-2", "1.0-1", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-1", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-1", "1.0-2", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_MATCH); assert_int_equal(DoCompare("1.0-2", "1.0-1", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_NO_MATCH); } void wrong_separators(void) { assert_int_equal(DoCompare("1.0", "1,0", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_ERROR); } void uneven_lengths_1(void) { assert_int_equal(DoCompare("1.0.1", "1.0", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_NO_MATCH); } void uneven_lengths_2(void) { assert_int_equal(DoCompare("1.0.1", "1.0", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_MATCH); } void uneven_lengths_3(void) { assert_int_equal(DoCompare("1.0.1", "1.0", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_NO_MATCH); } void uneven_lengths_4(void) { assert_int_equal(DoCompare("1.0.1", "1.0", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_MATCH); } void uneven_lengths_5(void) { assert_int_equal(DoCompare("1.0.1", "1.0", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_NO_MATCH); } void uneven_lengths_6(void) { assert_int_equal(DoCompare("1.0", "1.0.1", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_NO_MATCH); } void uneven_lengths_7(void) { assert_int_equal(DoCompare("1.0", "1.0.1", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_NO_MATCH); } void uneven_lengths_8(void) { assert_int_equal(DoCompare("1.0", "1.0.1", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_MATCH); } void uneven_lengths_9(void) { assert_int_equal(DoCompare("1.0", "1.0.1", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_NO_MATCH); } void uneven_lengths_10(void) { assert_int_equal(DoCompare("1.0", "1.0.1", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_MATCH); } void uneven_lengths_11(void) { assert_int_equal(DoCompare("1.0-1", "1.0", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_NO_MATCH); } void uneven_lengths_12(void) { assert_int_equal(DoCompare("1.0-1", "1.0", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_MATCH); } void uneven_lengths_13(void) { assert_int_equal(DoCompare("1.0-1", "1.0", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_NO_MATCH); } void uneven_lengths_14(void) { assert_int_equal(DoCompare("1.0-1", "1.0", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_MATCH); } void uneven_lengths_15(void) { assert_int_equal(DoCompare("1.0-1", "1.0", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_NO_MATCH); } void uneven_lengths_16(void) { assert_int_equal(DoCompare("1.0", "1.0-1", PACKAGE_VERSION_COMPARATOR_EQ), VERCMP_NO_MATCH); } void uneven_lengths_17(void) { assert_int_equal(DoCompare("1.0", "1.0-1", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_NO_MATCH); } void uneven_lengths_18(void) { assert_int_equal(DoCompare("1.0", "1.0-1", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_MATCH); } void uneven_lengths_19(void) { assert_int_equal(DoCompare("1.0", "1.0-1", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_NO_MATCH); } void uneven_lengths_20(void) { assert_int_equal(DoCompare("1.0", "1.0-1", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_MATCH); } void invalid_01(void) { assert_int_equal(DoCompare("text-1.0", "1.0", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_ERROR); } void invalid_02(void) { assert_int_equal(DoCompare("text-1.0", "1.0", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_ERROR); } void invalid_03(void) { assert_int_equal(DoCompare("1.0", "text-1.0", PACKAGE_VERSION_COMPARATOR_LE), VERCMP_ERROR); } void invalid_04(void) { assert_int_equal(DoCompare("1.0", "text-1.0", PACKAGE_VERSION_COMPARATOR_GE), VERCMP_ERROR); } void invalid_05(void) { assert_int_equal(DoCompare("text-1.0", "1.0", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_ERROR); } void invalid_06(void) { assert_int_equal(DoCompare("text-1.0", "1.0", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_ERROR); } void invalid_07(void) { assert_int_equal(DoCompare("1.0", "text-1.0", PACKAGE_VERSION_COMPARATOR_LT), VERCMP_ERROR); } void invalid_08(void) { assert_int_equal(DoCompare("1.0", "text-1.0", PACKAGE_VERSION_COMPARATOR_GT), VERCMP_ERROR); } int main() { PRINT_TEST_BANNER(); LogSetGlobalLevel(LOG_LEVEL_VERBOSE); const UnitTest tests[] = { unit_test(test_different_name), unit_test(test_wildcard_arch), unit_test(test_non_matching_arch), unit_test(test_wildcard_version), unit_test(test_eq), unit_test(test_ne), unit_test(test_gt_lt), unit_test(test_gte_lte), unit_test(wrong_separators), unit_test(uneven_lengths_1), unit_test(uneven_lengths_2), unit_test(uneven_lengths_3), unit_test(uneven_lengths_4), unit_test(uneven_lengths_5), unit_test(uneven_lengths_6), unit_test(uneven_lengths_7), unit_test(uneven_lengths_8), unit_test(uneven_lengths_9), unit_test(uneven_lengths_10), unit_test(uneven_lengths_11), unit_test(uneven_lengths_12), unit_test(uneven_lengths_13), unit_test(uneven_lengths_14), unit_test(uneven_lengths_15), unit_test(uneven_lengths_16), unit_test(uneven_lengths_17), unit_test(uneven_lengths_18), unit_test(uneven_lengths_19), unit_test(uneven_lengths_20), unit_test(invalid_01), unit_test(invalid_02), unit_test(invalid_03), unit_test(invalid_04), unit_test(invalid_05), unit_test(invalid_06), unit_test(invalid_07), unit_test(invalid_08), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/iteration_test.c0000644000000000000000000003465715010704253020714 0ustar00rootroot00000000000000#include #include static void test_FindDollarParen(void) { /* not found */ assert_int_equal(FindDollarParen("", 1), 0); assert_int_equal(FindDollarParen(" ", 2), 1); assert_int_equal(FindDollarParen("$", 2), 1); assert_int_equal(FindDollarParen("(", 2), 1); assert_int_equal(FindDollarParen("{", 2), 1); assert_int_equal(FindDollarParen("$ ", 3), 2); assert_int_equal(FindDollarParen("$$", 3), 2); assert_int_equal(FindDollarParen("$[", 3), 2); assert_int_equal(FindDollarParen("($", 3), 2); assert_int_equal(FindDollarParen(" $", 3), 2); assert_int_equal(FindDollarParen(" $[", 4), 3); assert_int_equal(FindDollarParen("$ (", 4), 3); assert_int_equal(FindDollarParen("$ {", 4), 3); /* found */ assert_int_equal(FindDollarParen("${", 3), 0); assert_int_equal(FindDollarParen("$(", 3), 0); assert_int_equal(FindDollarParen(" $(", 4), 1); assert_int_equal(FindDollarParen(" ${", 4), 1); assert_int_equal(FindDollarParen("$$(", 4), 1); assert_int_equal(FindDollarParen("$${", 4), 1); // Detect out of bounds read: // If max is 0, it shouldn't try to deref these invalid pointers: char a = 'a'; assert_int_equal(FindDollarParen((char *)0x1, 0), 0); assert_int_equal(FindDollarParen((&a) + 1, 0), 0); // Should not read past max bytes: char b[1] = {'b'}; assert_int_equal(FindDollarParen(b, 1), 1); char c[8] = {'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c'}; assert_int_equal(FindDollarParen(c, 8), 8); // We had some problems with FindDollarParen reading outside a buffer // so I added these cryptic but useful tests. Some of them will only // fail if you run tests with ASAN, valgrind or similar. } static void test_IsMangled(void) { /* Simply true. */ assert_false(IsMangled("")); assert_false(IsMangled("blah")); assert_false(IsMangled("namespace:blah")); assert_false(IsMangled("scope.blah")); assert_false(IsMangled("namespace:scope.blah")); /* Simply false. */ assert_true(IsMangled("scope#blah")); assert_true(IsMangled("namespace*blah")); assert_true(IsMangled("namespace*scope.blah")); assert_true(IsMangled("namespace:scope#blah")); /* Complicated: nested expansions shouldn't affect result */ assert_false(IsMangled("$(")); assert_false(IsMangled("${")); assert_false(IsMangled("blah$(blue)")); assert_false(IsMangled("blah$(scope.blue)")); assert_false(IsMangled("blah$(scope#blue)")); assert_false(IsMangled("blah$(namespace:blue)")); assert_false(IsMangled("blah$(namespace*blue)")); assert_false(IsMangled("blah$(namespace:scope.blue)")); assert_false(IsMangled("blah$(namespace:scope#blue)")); assert_false(IsMangled("blah$(namespace*scope.blue)")); assert_false(IsMangled("blah$(namespace*scope#blue)")); assert_false(IsMangled("scope.blah$(blue)")); assert_false(IsMangled("scope.blah$(scope.blue)")); assert_false(IsMangled("scope.blah$(scope#blue)")); assert_false(IsMangled("scope.blah$(namespace:blue)")); assert_false(IsMangled("scope.blah$(namespace*blue)")); assert_false(IsMangled("scope.blah$(namespace:scope.blue)")); assert_false(IsMangled("scope.blah$(namespace:scope#blue)")); assert_false(IsMangled("scope.blah$(namespace*scope.blue)")); assert_false(IsMangled("scope.blah$(namespace*scope#blue)")); assert_true(IsMangled("scope#blah$(blue)")); assert_true(IsMangled("scope#blah$(scope.blue)")); assert_true(IsMangled("scope#blah$(scope#blue)")); assert_true(IsMangled("scope#blah$(namespace:blue)")); assert_true(IsMangled("scope#blah$(namespace*blue)")); assert_true(IsMangled("scope#blah$(namespace:scope.blue)")); assert_true(IsMangled("scope#blah$(namespace:scope#blue)")); assert_true(IsMangled("scope#blah$(namespace*scope.blue)")); assert_true(IsMangled("scope#blah$(namespace*scope#blue)")); assert_true(IsMangled("namespace*blah$(blue)")); assert_true(IsMangled("namespace*blah$(scope.blue)")); assert_true(IsMangled("namespace*blah$(scope#blue)")); assert_true(IsMangled("namespace*blah$(namespace:blue)")); assert_true(IsMangled("namespace*blah$(namespace*blue)")); assert_true(IsMangled("namespace*blah$(namespace:scope.blue)")); assert_true(IsMangled("namespace*blah$(namespace:scope#blue)")); assert_true(IsMangled("namespace*blah$(namespace*scope.blue)")); assert_true(IsMangled("namespace*blah$(namespace*scope#blue)")); assert_false(IsMangled("$(scope#blah)")); assert_false(IsMangled("$(namespace*blah)")); assert_false(IsMangled("$(namespace*scope#blah)")); /* Multiple nested expansions, again, none should matter. */ assert_false(IsMangled("blah$(blue$(bleh))")); assert_false(IsMangled("blah$(scope.blue$(scope#bleh))")); /* Array indexes shouldn't affect the result either. */ assert_false(IsMangled("[")); assert_false(IsMangled("blah[$(blue)]")); assert_false(IsMangled("blah$(blue[bleh])")); assert_false(IsMangled("blah[S#i]")); assert_false(IsMangled("blah[S#i][N*i]")); assert_false(IsMangled("blah[S#i][N*i]")); assert_true(IsMangled("S#blah[S.blue]")); assert_true(IsMangled("S#blah[N:blue]")); assert_true(IsMangled("S#blah[S#blue]")); assert_true(IsMangled("N*blah[S.blue]")); assert_true(IsMangled("N*blah[N:blue]")); assert_true(IsMangled("N*S.blah[N:blue]")); assert_true(IsMangled("N*S.blah[S.blue]")); assert_false(IsMangled("S.blah[S#i][N*i]")); assert_true (IsMangled("S#blah[S#i][N*i]")); assert_false(IsMangled("[scope#blah]")); assert_false(IsMangled("[namespace*blah]")); assert_false(IsMangled("[namespace*scope#blah]")); /* Complicated: combine nested variables with array expansions. */ assert_false(IsMangled("[$(")); assert_false(IsMangled("S.blah[$(")); assert_false(IsMangled("S.blah[i]$(blah)")); assert_false(IsMangled("S.blah[$(i)]")); assert_false(IsMangled("S.v[$(i)]")); assert_true (IsMangled("S#v[$(i)]")); assert_true (IsMangled("N*v[$(i)]")); assert_false(IsMangled("N:v[$(i)]")); assert_false(IsMangled("N:v[$(N*i)]")); assert_false(IsMangled("N:v[$(S#i)]")); assert_true (IsMangled("N*v[$(S#i)]")); assert_true (IsMangled("S#v[$(S#i)]")); assert_false(IsMangled("v[$(N*S#i)]")); assert_false(IsMangled("v[$(N:S#i)]")); assert_false(IsMangled("v[$(N*S.i)]")); assert_false(IsMangled("S.v[$(N*S#i)]")); assert_true (IsMangled("S#v[$(N*S#i)]")); assert_false(IsMangled("N:v[$(N*S#i)]")); assert_true (IsMangled("N*v[$(N*S#i)]")); } static void Mangle_TestHelper(const char *orig, const char *expected) { printf("Testing MangleVarRefString: %s\n", orig); char *s = xstrdup(orig); MangleVarRefString(s, strlen(s)); assert_string_equal(s, expected); free(s); } static void Mangle_TestHelperWithLength1(const char *orig, size_t orig_len, const char *expected) { printf("Testing MangleVarRefString: %.*s\n", (int) orig_len, orig); char *s = xstrdup(orig); MangleVarRefString(s, orig_len); assert_string_equal(s, expected); free(s); } /* NOTE: this one changes "orig" in-place. */ static void Mangle_TestHelperWithLength2(char *orig, size_t orig_len, const char *expected, size_t expected_len) { printf("Testing MangleVarRefString: %.*s\n", (int) orig_len, orig); MangleVarRefString(orig, orig_len); assert_memory_equal(orig, expected, expected_len); } static void test_MangleVarRefString(void) { Mangle_TestHelper ("", ""); Mangle_TestHelperWithLength1 ("a", 0, "a"); Mangle_TestHelper ("a.b", "a#b"); /* Force length to 1, no change should occur. */ Mangle_TestHelperWithLength1 ("a.b", 1, "a.b"); Mangle_TestHelper ("a:b", "a*b"); /* Force length to 1, no change should occur. */ Mangle_TestHelperWithLength1 ("a:b", 1, "a:b"); Mangle_TestHelper ("a:b.c", "a*b#c"); /* Force length to 1, no change should occur. */ Mangle_TestHelperWithLength1 ("a:b.c", 1, "a:b.c"); /* Never mangle after array indexing */ Mangle_TestHelper ("a[b.c]", "a[b.c]"); /* "this" scope never gets mangled. */ Mangle_TestHelper ("this.a", "this.a"); /* Inner expansions never get mangled. */ Mangle_TestHelper ("a_$(s.i)", "a_$(s.i)"); Mangle_TestHelper ("a_$(n:i)", "a_$(n:i)"); /* Only before the inner expansion it gets mangled. */ Mangle_TestHelper ("s.a_$(s.i)", "s#a_$(s.i)"); Mangle_TestHelper ("n:a_$(n:i)", "n*a_$(n:i)"); /* Testing non '\0'-terminated char arrays. */ char A[4] = {'a','b','.','c'}; Mangle_TestHelperWithLength2(A, 0, "ab.c", 4); Mangle_TestHelperWithLength2(A, 4, "ab#c", 4); char B[3] = {'a',':','b'}; Mangle_TestHelperWithLength2(B, 0, "a:b", 3); Mangle_TestHelperWithLength2(B, 3, "a*b", 3); char C[1] = {'a'}; Mangle_TestHelperWithLength2(C, 0, "a", 1); Mangle_TestHelperWithLength2(C, 1, "a", 1); } /* NOTE: the two variables "i" and "j" are defined as empty slists in the * EvalContext. */ static void IteratorPrepare_TestHelper( const char *promiser, size_t expected_wheels_num, const char **expected_wheels) { /* INIT EvalContext and Promise. */ EvalContext *evalctx = EvalContextNew(); Policy *policy = PolicyNew(); Bundle *bundle = PolicyAppendBundle(policy, "ns1", "bundle1", "agent", NULL, NULL); BundleSection *section = BundleAppendSection(bundle, "dummy"); Promise *promise = BundleSectionAppendPromise(section, promiser, (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, "any", NULL); EvalContextStackPushBundleFrame(evalctx, bundle, NULL, false); EvalContextStackPushBundleSectionFrame(evalctx, section); PromiseIterator *iterctx = PromiseIteratorNew(promise); char *promiser_copy = xstrdup(promiser); /* Insert the variables "i" and "j" as empty Rlists in the EvalContext, so * that the iteration engine creates wheels for them. */ { VarRef *ref_i = VarRefParseFromBundle("i", bundle); EvalContextVariablePut(evalctx, ref_i, (Rlist *) NULL, CF_DATA_TYPE_STRING_LIST, NULL); VarRefDestroy(ref_i); VarRef *ref_j = VarRefParseFromBundle("j", bundle); EvalContextVariablePut(evalctx, ref_j, (Rlist *) NULL, CF_DATA_TYPE_STRING_LIST, NULL); VarRefDestroy(ref_j); } /* TEST */ printf("Testing PromiseIteratorPrepare: %s\n", promiser); PromiseIteratorPrepare(iterctx, evalctx, promiser_copy); /* CHECK */ assert_true(iterctx->wheels != NULL); size_t wheels_num = SeqLength(iterctx->wheels); assert_int_equal(wheels_num, expected_wheels_num); for (size_t i = 0; i < expected_wheels_num; i++) { const Wheel *wheel = SeqAt(iterctx->wheels, i); assert_string_equal(wheel->varname_unexp, expected_wheels[i]); } /* CLEANUP */ free(promiser_copy); PromiseIteratorDestroy(iterctx); EvalContextStackPopFrame(evalctx); EvalContextStackPopFrame(evalctx); PolicyDestroy(policy); EvalContextDestroy(evalctx); } static void test_PromiseIteratorPrepare(void) { IteratorPrepare_TestHelper("", 0, NULL); /* No wheel added for "blah" because this variable does not resolve. */ IteratorPrepare_TestHelper("$(blah)", 0, NULL); /* "$(i)" is a valid list, but these syntaxes are not correct. */ IteratorPrepare_TestHelper("i", 0, NULL); IteratorPrepare_TestHelper("$i", 0, NULL); IteratorPrepare_TestHelper("$(i", 0, NULL); /* The following however is correct and should add one wheel */ IteratorPrepare_TestHelper("$(i)", 1, (const char *[]) {"i"}); IteratorPrepare_TestHelper("$(i))", 1, (const char *[]) {"i"}); IteratorPrepare_TestHelper("$(i)(", 1, (const char *[]) {"i"}); IteratorPrepare_TestHelper("$(i)$(", 1, (const char *[]) {"i"}); /* The same variable twice should just add one wheel. */ IteratorPrepare_TestHelper("$(i)$(i)", 1, (const char *[]) {"i"}); /* "$(ij)" does not resolve. */ IteratorPrepare_TestHelper("$(i)$(ij)", 1, (const char *[]) {"i"}); /* Both "$(i)" and "$(j)" resolve. */ IteratorPrepare_TestHelper("$(i)$(j)", 2, (const char *[]) {"i","j"}); IteratorPrepare_TestHelper("$(i))$(j)", 2, (const char *[]) {"i","j"}); IteratorPrepare_TestHelper("0$(i)$(j)", 2, (const char *[]) {"i","j"}); IteratorPrepare_TestHelper("$(i)1$(j)", 2, (const char *[]) {"i","j"}); IteratorPrepare_TestHelper("$(i)$(j)2", 2, (const char *[]) {"i","j"}); IteratorPrepare_TestHelper("0$(i)1$(j)", 2, (const char *[]) {"i","j"}); IteratorPrepare_TestHelper("0$(i)1$(j)2", 2, (const char *[]) {"i","j"}); /* Any variable dependent on other variables should be added as a wheel. */ IteratorPrepare_TestHelper("$(A[$(i)][$(j)])", 3, (const char *[]) {"i","j", "A[$(i)][$(j)]"}); /* Even if the inner variables don't resolve. */ IteratorPrepare_TestHelper("$(A[$(blah)][$(blue)])", 1, (const char *[]) {"A[$(blah)][$(blue)]"}); IteratorPrepare_TestHelper("$(A[1][2]) $(A[$(i)][$(j)])", 3, (const char *[]) {"i","j", "A[$(i)][$(j)]"}); IteratorPrepare_TestHelper("$(A[$(B[$(i)])][$(j)])", 4, (const char *[]) {"i", "B[$(i)]", "j", "A[$(B[$(i)])][$(j)]"}); IteratorPrepare_TestHelper("$(A[$(B[$(i)][$(j)])])", 4, (const char *[]) {"i","j", "B[$(i)][$(j)]", "A[$(B[$(i)][$(j)])]"}); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_FindDollarParen), unit_test(test_IsMangled), unit_test(test_MangleVarRefString), unit_test(test_PromiseIteratorPrepare), }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/tests/unit/avahi_config_test.c0000644000000000000000000000316315010704253021317 0ustar00rootroot00000000000000#include #include #include #include static void generateTestFile() { FILE *fp = fopen("/tmp/test_file", "w+"); assert_int_not_equal(fp, NULL); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); FprintAvahiCfengineTag(fp); fprintf(fp, "\n"); fprintf(fp, "_cfenginehub._tcp\n"); DetermineCfenginePort(); fprintf(fp, "\n"); fprintf(fp, "5308\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fclose(fp); } static void test_generateAvahiConfig(void) { generateTestFile(); assert_int_equal(GenerateAvahiConfig("/tmp/avahi_config"), 0); FILE *testfile = fopen("/tmp/test_file", "r+"); assert_int_not_equal(testfile, NULL); FILE *optfile = fopen("/tmp/avahi_config", "r+"); assert_int_not_equal(optfile, NULL); char buffer1[256], buffer2[256]; while (!feof(testfile) && !feof(optfile)) { memset(buffer1, 0, sizeof(buffer1)); memset(buffer2, 0, sizeof(buffer2)); fgets(buffer1, sizeof(buffer1), testfile); fgets(buffer2, sizeof(buffer2), optfile); assert_int_equal(strcmp(buffer1, buffer2), 0); } fclose(testfile); fclose(optfile); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_generateAvahiConfig) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/file_name_test.c0000644000000000000000000002115715010704253020624 0ustar00rootroot00000000000000#include #include #include static void test_first_file_separator(void) { const char *out; const char *in = "/tmp/myfile"; out = FirstFileSeparator(in); assert_true(out == in); in = "tmp/myfile"; out = FirstFileSeparator(in); assert_true(out == in + 3); in = "c:/tmp/myfile"; out = FirstFileSeparator(in); assert_true(out == in + 2); in = "\\\\my\\windows\\share"; out = FirstFileSeparator(in); assert_true(out == in + 1); } static void test_get_parent_directory_copy(void) { char *out; #ifndef _WIN32 /* unix, will fail on windows because of IsFileSep */ out = GetParentDirectoryCopy("/some/path/here"); assert_string_equal(out, "/some/path"); free(out); out = GetParentDirectoryCopy("/some/path/here/dir/"); assert_string_equal(out, "/some/path/here/dir"); free(out); out = GetParentDirectoryCopy("/some/path/here/dir/."); assert_string_equal(out, "/some/path/here/dir"); free(out); out = GetParentDirectoryCopy("/some"); assert_string_equal(out, "/"); free(out); #else /* _WIN32 */ /* windows, will fail on unix because of IsFileSep */ out = GetParentDirectoryCopy("c:\\some\\path with space\\here and now"); assert_string_equal(out, "c:\\some\\path with space"); free(out); out = GetParentDirectoryCopy("c:\\some"); assert_string_equal(out, "c:\\"); free(out); out = GetParentDirectoryCopy("\\\\some\\path"); assert_string_equal(out, "\\\\some"); free(out); out = GetParentDirectoryCopy("\\\\some"); assert_string_equal(out, "\\\\"); free(out); #endif /* _WIN32 */ } static void test_delete_redundant_slashes(void) { { char str[] = "///a//b////c/"; DeleteRedundantSlashes(str); assert_string_equal(str, "/a/b/c/"); } { char str[] = "a//b////c/"; DeleteRedundantSlashes(str); assert_string_equal(str, "a/b/c/"); } { char str[] = "/a/b/c/"; DeleteRedundantSlashes(str); assert_string_equal(str, "/a/b/c/"); } { char str[] = "a///b////c///"; DeleteRedundantSlashes(str); assert_string_equal(str, "a/b/c/"); } { char str[] = "a///b////c"; DeleteRedundantSlashes(str); assert_string_equal(str, "a/b/c"); } { char str[] = "a///b/c"; DeleteRedundantSlashes(str); assert_string_equal(str, "a/b/c"); } { char str[] = "alpha///beta/charlie///zeta"; DeleteRedundantSlashes(str); assert_string_equal(str, "alpha/beta/charlie/zeta"); } { char str[] = "////alpha///beta/charlie///zeta///"; DeleteRedundantSlashes(str); assert_string_equal(str, "/alpha/beta/charlie/zeta/"); } { char str[] = "/a"; DeleteRedundantSlashes(str); assert_string_equal(str, "/a"); } { char str[] = "/alpha"; DeleteRedundantSlashes(str); assert_string_equal(str, "/alpha"); } } static void test_join_paths(void) { char joined[PATH_MAX] = { 0 }; #ifndef _WIN32 /* unix, will fail on windows because of different file separator */ strlcat(joined, "/tmp", PATH_MAX); JoinPaths(joined, PATH_MAX, "test"); assert_string_equal(joined, "/tmp/test"); JoinPaths(joined, PATH_MAX, "/test2"); assert_string_equal(joined, "/tmp/test/test2"); strlcat(joined, "/", PATH_MAX); JoinPaths(joined, PATH_MAX, "test3"); assert_string_equal(joined, "/tmp/test/test2/test3"); strlcat(joined, "/", PATH_MAX); JoinPaths(joined, PATH_MAX, "/test4"); assert_string_equal(joined, "/tmp/test/test2/test3/test4"); memset(joined, 0, PATH_MAX); JoinPaths(joined, PATH_MAX, "test5"); assert_string_equal(joined, "test5"); memset(joined, 0, PATH_MAX); JoinPaths(joined, PATH_MAX, "/test6"); assert_string_equal(joined, "/test6"); memset(joined, 0, PATH_MAX); strlcat(joined, "test6", PATH_MAX); JoinPaths(joined, PATH_MAX, "test7"); assert_string_equal(joined, "test6/test7"); #else /* _WIN32 */ /* windows, will fail on unix because of different file separator */ strlcat(joined, "C:\\tmp", PATH_MAX); JoinPaths(joined, PATH_MAX, "test"); assert_string_equal(joined, "C:\\tmp\\test"); JoinPaths(joined, PATH_MAX, "\\test2"); assert_string_equal(joined, "C:\\tmp\\test\\test2"); strlcat(joined, "\\", PATH_MAX); JoinPaths(joined, PATH_MAX, "test3"); assert_string_equal(joined, "C:\\tmp\\test\\test2\\test3"); strlcat(joined, "\\", PATH_MAX); JoinPaths(joined, PATH_MAX, "\\test4"); assert_string_equal(joined, "C:\\tmp\\test\\test2\\test3\\test4"); memset(joined, 0, PATH_MAX); JoinPaths(joined, PATH_MAX, "test5"); assert_string_equal(joined, "test5"); memset(joined, 0, PATH_MAX); JoinPaths(joined, PATH_MAX, "C:\\test6"); assert_string_equal(joined, "C:\\test6"); memset(joined, 0, PATH_MAX); strlcat(joined, "test6", PATH_MAX); JoinPaths(joined, PATH_MAX, "test7"); assert_string_equal(joined, "test6\\test7"); #endif } static void test_get_absolute_path(void) { char *abs_path = NULL; char expected[PATH_MAX] = { 0 }; char orig[PATH_MAX] = { 0 }; #ifndef _WIN32 /* unix, will fail on windows because of different file separator */ abs_path = GetAbsolutePath("/tmp/test"); assert_string_equal(abs_path, "/tmp/test"); free(abs_path); abs_path = GetAbsolutePath("/tmp/test/../test2"); assert_string_equal(abs_path, "/tmp/test2"); free(abs_path); getcwd(expected, PATH_MAX); abs_path = GetAbsolutePath("test/test2"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "/test/test2", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); getcwd(expected, PATH_MAX); abs_path = GetAbsolutePath("./test"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "/test", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); getcwd(expected, PATH_MAX); abs_path = GetAbsolutePath("test/../test2"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "/test2", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); getcwd(expected, PATH_MAX); strlcat(orig, expected, PATH_MAX); chdir(".."); ChopLastNode(expected); abs_path = GetAbsolutePath("test/test2"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "/test/test2", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); chdir(orig); memset(orig, 0, PATH_MAX); #else /* _WIN32 */ /* windows, will fail on unix because of different file separator */ abs_path = GetAbsolutePath("C:\\tmp\\test"); assert_string_equal(abs_path, "C:\\tmp\\test"); free(abs_path); abs_path = GetAbsolutePath("C:\\tmp\\test\\..\\test2"); assert_string_equal(abs_path, "C:\\tmp\\test2"); free(abs_path); getcwd(expected, PATH_MAX); abs_path = GetAbsolutePath("test\\test2"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "\\test\\test2", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); getcwd(expected, PATH_MAX); abs_path = GetAbsolutePath(".\\test"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "\\test", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); getcwd(expected, PATH_MAX); abs_path = GetAbsolutePath("test\\..\\test2"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "\\test2", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); getcwd(expected, PATH_MAX); strlcat(orig, expected, PATH_MAX); chdir(".."); ChopLastNode(expected); abs_path = GetAbsolutePath("test\\test2"); assert_true(IsAbsoluteFileName(abs_path)); strlcat(expected, "\\test\\test2", PATH_MAX); assert_string_equal(abs_path, expected); free(abs_path); memset(expected, 0, PATH_MAX); chdir(orig); memset(orig, 0, PATH_MAX); #endif } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_first_file_separator), unit_test(test_get_parent_directory_copy), unit_test(test_delete_redundant_slashes), unit_test(test_join_paths), unit_test(test_get_absolute_path) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/addr_lib_test.c0000644000000000000000000001230415010704253020437 0ustar00rootroot00000000000000#include #include #include static void test_ParseHostPort() { char *hostname, *port; char test_string[64]; // Domain name: ParseHostPort(strcpy(test_string, "www.cfengine.com"), &hostname, &port); assert_string_equal(hostname, "www.cfengine.com"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "www.cfengine.com:80"), &hostname, &port); assert_string_equal(hostname, "www.cfengine.com"); assert_string_equal(port, "80"); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "www.cfengine.com:"), &hostname, &port); assert_string_equal(hostname, "www.cfengine.com"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "localhost"), &hostname, &port); assert_string_equal(hostname, "localhost"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "localhost:"), &hostname, &port); assert_string_equal(hostname, "localhost"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "localhost:80"), &hostname, &port); assert_string_equal(hostname, "localhost"); assert_string_equal(port, "80"); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[localhost]"), &hostname, &port); assert_string_equal(hostname, "localhost"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[localhost]:"), &hostname, &port); assert_string_equal(hostname, "localhost"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[localhost]:80"), &hostname, &port); assert_string_equal(hostname, "localhost"); assert_string_equal(port, "80"); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[www.cfengine.com]"), &hostname, &port); assert_string_equal(hostname, "www.cfengine.com"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[www.cfengine.com]:80"), &hostname, &port); assert_string_equal(hostname, "www.cfengine.com"); assert_string_equal(port, "80"); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[www.cfengine.com]:"), &hostname, &port); assert_string_equal(hostname, "www.cfengine.com"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; // IPv4: ParseHostPort(strcpy(test_string, "1.2.3.4"), &hostname, &port); assert_string_equal(hostname, "1.2.3.4"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "1.2.3.4:80"), &hostname, &port); assert_string_equal(hostname, "1.2.3.4"); assert_string_equal(port, "80"); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "1.2.3.4:"), &hostname, &port); assert_string_equal(hostname, "1.2.3.4"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; // IPv6 with square brackets: ParseHostPort(strcpy(test_string, "[ffff::dd:12:34]"), &hostname, &port); assert_string_equal(hostname, "ffff::dd:12:34"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[ffff::dd:12:34]:80"), &hostname, &port); assert_string_equal(hostname, "ffff::dd:12:34"); assert_string_equal(port, "80"); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[ffff::dd:12:34]:"), &hostname, &port); assert_string_equal(hostname, "ffff::dd:12:34"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; // IPv6 without square brackets: ParseHostPort(strcpy(test_string, "ffff::dd:12:34"), &hostname, &port); assert_string_equal(hostname, "ffff::dd:12:34"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; // IPv4 mapped IPv6 addresses: ParseHostPort(strcpy(test_string, "::ffff:192.0.2.128"), &hostname, &port); assert_string_equal(hostname, "::ffff:192.0.2.128"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[::ffff:192.0.2.128]"), &hostname, &port); assert_string_equal(hostname, "::ffff:192.0.2.128"); assert_int_equal(port, NULL); hostname = NULL; port = NULL; /***** CORNER CASES *****/ ParseHostPort(strcpy(test_string, ""), &hostname, &port); assert_int_equal(hostname, NULL); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[]"), &hostname, &port); assert_int_equal(hostname, NULL); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, "[]:"), &hostname, &port); assert_int_equal(hostname, NULL); assert_int_equal(port, NULL); hostname = NULL; port = NULL; ParseHostPort(strcpy(test_string, ":"), &hostname, &port); assert_int_equal(hostname, NULL); assert_int_equal(port, NULL); hostname = NULL; port = NULL; } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_ParseHostPort) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/connection_management_test.c0000644000000000000000000001116015010704253023231 0ustar00rootroot00000000000000#include #include #include /* xsnprintf */ #include #include #include /* PurgeOldConnections */ const int CONNECTION_MAX_AGE_SECONDS = SECONDS_PER_HOUR * 2; /* NOTE: Invalid memory access has been seen in PurgeOldConnections(). This does not always result in a segfault, but running this test in valgrind will detect it. */ static void test_purge_old_connections_nochange(void) { const time_t time_now = 100000; Item *connections = NULL; char time_str[64]; xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS); PrependItem(&connections, "123.123.123.3", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 1); PrependItem(&connections, "123.123.123.2", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 100); PrependItem(&connections, "123.123.123.1", time_str); assert_int_equal(ListLen(connections), 3); PurgeOldConnections(&connections, time_now); assert_int_equal(ListLen(connections), 3); assert_true(IsItemIn(connections, "123.123.123.1")); assert_true(IsItemIn(connections, "123.123.123.2")); assert_true(IsItemIn(connections, "123.123.123.3")); DeleteItemList(connections); } static void test_purge_old_connections_purge_first(void) { const time_t time_now = 100000; Item *connections = NULL; char time_str[64]; xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 100); PrependItem(&connections, "123.123.123.3", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 2); PrependItem(&connections, "123.123.123.2", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS - 5); PrependItem(&connections, "123.123.123.1", time_str); assert_int_equal(ListLen(connections), 3); PurgeOldConnections(&connections, time_now); assert_int_equal(ListLen(connections), 2); assert_false(IsItemIn(connections, "123.123.123.1")); assert_true(IsItemIn(connections, "123.123.123.2")); assert_true(IsItemIn(connections, "123.123.123.3")); DeleteItemList(connections); } static void test_purge_old_connections_purge_middle(void) { const time_t time_now = 100000; Item *connections = NULL; char time_str[64]; xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS); PrependItem(&connections, "123.123.123.3", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS - 1); PrependItem(&connections, "123.123.123.2", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 100); PrependItem(&connections, "123.123.123.1", time_str); assert_int_equal(ListLen(connections), 3); PurgeOldConnections(&connections, time_now); assert_int_equal(ListLen(connections), 2); assert_true(IsItemIn(connections, "123.123.123.1")); assert_false(IsItemIn(connections, "123.123.123.2")); assert_true(IsItemIn(connections, "123.123.123.3")); DeleteItemList(connections); } static void test_purge_old_connections_purge_last(void) { const time_t time_now = 100000; Item *connections = NULL; char time_str[64]; xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS - 100); PrependItem(&connections, "123.123.123.3", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS + 10); PrependItem(&connections, "123.123.123.2", time_str); xsnprintf(time_str, sizeof(time_str), "%ld", time_now - CONNECTION_MAX_AGE_SECONDS); PrependItem(&connections, "123.123.123.1", time_str); assert_int_equal(ListLen(connections), 3); PurgeOldConnections(&connections, time_now); assert_int_equal(ListLen(connections), 2); assert_true(IsItemIn(connections, "123.123.123.1")); assert_true(IsItemIn(connections, "123.123.123.2")); assert_false(IsItemIn(connections, "123.123.123.3")); DeleteItemList(connections); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_purge_old_connections_nochange), unit_test(test_purge_old_connections_purge_first), unit_test(test_purge_old_connections_purge_middle), unit_test(test_purge_old_connections_purge_last) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/test.c0000644000000000000000000000234315010704253016621 0ustar00rootroot00000000000000#include #include #include #include #include char *file_read_string(FILE *in) { fpos_t pos; long size; char *buffer; assert_int_equal(fgetpos(in, &pos), 0); assert_int_equal(fseek(in, 0, SEEK_END), 0); size = ftell(in); assert_true(size >= 0); assert_int_equal(fseek(in, 0, SEEK_SET), 0); buffer = xcalloc(size + 1L, sizeof(char)); assert_int_equal(fread(buffer, 1, size, in), size); assert_int_equal(fsetpos(in, &pos), 0); return buffer; } void assert_file_equal(FILE *a, FILE *b) { char *a_buffer = file_read_string(a); char *b_buffer = file_read_string(b); if (strcmp(a_buffer, b_buffer) != 0) { printf("\n=====\n%s != \n=====\n%s\n", a_buffer, b_buffer); fail(); } free(a_buffer); free(b_buffer); } #define SMALL_DIFF 1e-14 void _assert_double_close(double left, double right, const char *const file, const int line) { if (fabs(left - right) > SMALL_DIFF) { print_error("%f != %f (+- 1e-14)\n", left, right); _fail(file, line); } } void test_progress() { putchar('.'); fflush(stdout); } void test_progress_end() { putchar('\n'); fflush(stdout); } cfengine-3.24.2/tests/unit/var_expressions_test.c0000644000000000000000000001313215010704253022131 0ustar00rootroot00000000000000#include #include static void test_plain_variable_with_no_stuff_in_it(void) { VarRef *ref = VarRefParse("foo"); assert_false(ref->ns); assert_false(ref->scope); assert_string_equal("foo", ref->lval); assert_int_equal(0, ref->num_indices); assert_false(ref->indices); VarRefDestroy(ref); } static void test_scoped(void) { VarRef *ref = VarRefParse("scope.lval"); assert_false(ref->ns); assert_string_equal("scope", ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(0, ref->num_indices); assert_false(ref->indices); VarRefDestroy(ref); } static void test_full(void) { VarRef *ref = VarRefParse("ns:scope.lval"); assert_string_equal("ns", ref->ns); assert_string_equal("scope", ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(0, ref->num_indices); assert_false(ref->indices); VarRefDestroy(ref); } static void test_dotted_array(void) { VarRef *ref = VarRefParse("ns:scope.lval[la.la]"); assert_string_equal("ns", ref->ns); assert_string_equal("scope", ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(1, ref->num_indices); assert_string_equal("la.la", ref->indices[0]); VarRefDestroy(ref); } static void test_levels(void) { VarRef *ref = VarRefParse("ns:scope.lval[x][y][z]"); assert_string_equal("ns", ref->ns); assert_string_equal("scope", ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(3, ref->num_indices); assert_string_equal("x", ref->indices[0]); assert_string_equal("y", ref->indices[1]); assert_string_equal("z", ref->indices[2]); VarRefDestroy(ref); } static void test_unqualified_array(void) { VarRef *ref = VarRefParse("lval[x]"); assert_false(ref->ns); assert_false(ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(1, ref->num_indices); assert_string_equal("x", ref->indices[0]); VarRefDestroy(ref); } static void test_qualified_array(void) { VarRef *ref = VarRefParse("scope.lval[x]"); assert_false(ref->ns); assert_string_equal("scope", ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(1, ref->num_indices); assert_string_equal("x", ref->indices[0]); VarRefDestroy(ref); } static void test_nested_array(void) { VarRef *ref = VarRefParse("scope.lval[$(other[x])]"); assert_false(ref->ns); assert_string_equal("scope", ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(1, ref->num_indices); assert_string_equal("$(other[x])", ref->indices[0]); VarRefDestroy(ref); } static void test_array_with_dot_colon_in_index(void) { VarRef *ref = VarRefParse("lval[x-x.x:x]"); assert_false(ref->ns); assert_false(ref->scope); assert_string_equal("lval", ref->lval); assert_int_equal(1, ref->num_indices); assert_string_equal("x-x.x:x", ref->indices[0]); VarRefDestroy(ref); } static void test_special_scope(void) { Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "ns", "b", "agent", NULL, NULL); { VarRef *ref = VarRefParseFromBundle("c.lval", bp); assert_string_equal("ns", ref->ns); assert_string_equal("c", ref->scope); assert_string_equal("lval", ref->lval); VarRefDestroy(ref); } { VarRef *ref = VarRefParseFromBundle("sys.lval", bp); assert_false(ref->ns); assert_string_equal("sys", ref->scope); assert_string_equal("lval", ref->lval); VarRefDestroy(ref); } PolicyDestroy(p); } static void CheckToStringQualified(const char *str, const char *expect) { VarRef *ref = VarRefParse(str); char *out = VarRefToString(ref, true); assert_string_equal(expect, out); free(out); VarRefDestroy(ref); } static void test_to_string_qualified(void) { CheckToStringQualified("ns:scope.lval[x][y]", "ns:scope.lval[x][y]"); CheckToStringQualified("ns:scope.lval[x]", "ns:scope.lval[x]"); CheckToStringQualified("ns:scope.lval", "ns:scope.lval"); CheckToStringQualified("scope.lval", "default:scope.lval"); CheckToStringQualified("lval", "lval"); } static void test_to_string_unqualified(void) { { VarRef *ref = VarRefParse("ns:scope.lval[x][y]"); char *out = VarRefToString(ref, false); assert_string_equal("lval[x][y]", out); free(out); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("ns:scope.lval[x]"); char *out = VarRefToString(ref, false); assert_string_equal("lval[x]", out); free(out); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("scope.lval"); char *out = VarRefToString(ref, false); assert_string_equal("lval", out); free(out); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("lval"); char *out = VarRefToString(ref, false); assert_string_equal("lval", out); free(out); VarRefDestroy(ref); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_plain_variable_with_no_stuff_in_it), unit_test(test_scoped), unit_test(test_full), unit_test(test_dotted_array), unit_test(test_levels), unit_test(test_unqualified_array), unit_test(test_qualified_array), unit_test(test_nested_array), unit_test(test_array_with_dot_colon_in_index), unit_test(test_special_scope), unit_test(test_to_string_qualified), unit_test(test_to_string_unqualified), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/mustache_test.c0000644000000000000000000000605215010704253020513 0ustar00rootroot00000000000000#include #include #include #include /* xsnprintf */ size_t TestSpecFile(const char *testfile) { char path[PATH_MAX]; xsnprintf(path, sizeof(path), "%s/mustache_%s.json", TESTDATADIR, testfile); Writer *w = FileRead(path, SIZE_MAX, NULL); if (w == NULL) { Log(LOG_LEVEL_ERR, "Error reading JSON input file '%s'", path); fail(); } JsonElement *spec = NULL; const char *data = StringWriterData(w); if (JsonParse(&data, &spec) != JSON_PARSE_OK) { Log(LOG_LEVEL_ERR, "Error parsing JSON input file '%s'", path); fail(); } WriterClose(w); JsonElement *tests = JsonObjectGetAsArray(spec, "tests"); size_t num_failures = 0; for (size_t i = 0; i < JsonLength(tests); i++) { JsonElement *test_obj = JsonAt(tests, i); fprintf(stdout, "Testing %s:%s ...", testfile, JsonObjectGetAsString(test_obj, "name")); Buffer *out = BufferNew(); const char *templ = JsonObjectGetAsString(test_obj, "template"); const char *expected = JsonObjectGetAsString(test_obj, "expected"); const JsonElement *data = JsonObjectGet(test_obj, "data"); if (!MustacheRender(out, templ, data) || strcmp(expected, BufferData(out)) != 0) { num_failures++; fprintf(stdout, "FAIL \n%s\n != \n%s\n", expected, BufferData(out)); } else { fprintf(stdout, "OK\n"); } BufferDestroy(out); } JsonDestroy(spec); return num_failures; } static void test_spec(void) { size_t num_failures = 0; size_t comments_fail = TestSpecFile("comments"); size_t interpolation_fail = TestSpecFile("interpolation"); size_t sections_fail = TestSpecFile("sections"); size_t delimiters_fail = TestSpecFile("delimiters"); size_t inverted_fail = TestSpecFile("inverted"); size_t extra_fail = TestSpecFile("extra"); num_failures = comments_fail + interpolation_fail + sections_fail + delimiters_fail + inverted_fail + extra_fail; if (num_failures > 0) { fprintf(stdout, "Failures in comments: %llu\n", (unsigned long long)comments_fail); fprintf(stdout, "Failures in interpolation: %llu\n", (unsigned long long)interpolation_fail); fprintf(stdout, "Failures in sections: %llu\n", (unsigned long long)sections_fail); fprintf(stdout, "Failures in delimiters: %llu\n", (unsigned long long)delimiters_fail); fprintf(stdout, "Failures in inverted: %llu\n", (unsigned long long)inverted_fail); fprintf(stdout, "Failures in extra: %llu\n", (unsigned long long)inverted_fail); fprintf(stdout, "TOTAL FAILURES: %llu\n", (unsigned long long)num_failures); fail(); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_spec), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/new_packages_promise_test.c0000644000000000000000000000523315010704253023067 0ustar00rootroot00000000000000#include #include #include static inline PackageModuleBody *make_mock_package_module(const char *name, int updates_ifel, int installed_ifel, Rlist *options) { PackageModuleBody *pm = xcalloc(1, sizeof(PackageModuleBody)); pm->name = SafeStringDuplicate(name); pm->installed_ifelapsed = installed_ifel; pm->updates_ifelapsed = updates_ifel; pm->options = RlistCopy(options); return pm; } static void test_add_module_to_context() { EvalContext *ctx = EvalContextNew(); PackageModuleBody *pm = make_mock_package_module("apt_get", 120, 240, NULL); AddPackageModuleToContext(ctx, pm); PackageModuleBody *pm2 = make_mock_package_module("yum", 220, 440, NULL); AddPackageModuleToContext(ctx, pm2); PackagePromiseContext *pp_ctx = GetPackagePromiseContext(ctx); assert_true(pp_ctx != NULL); assert_int_equal(2, SeqLength(pp_ctx->package_modules_bodies)); PackageModuleBody *yum = GetPackageModuleFromContext(ctx, "yum"); assert_true(yum != NULL); assert_int_equal(220, yum->updates_ifelapsed); assert_int_equal(440, yum->installed_ifelapsed); /* make sure that adding body with the same name will not make set larger */ PackageModuleBody *pm3 = make_mock_package_module("yum", 330, 550, NULL); AddPackageModuleToContext(ctx, pm3); assert_int_equal(2, SeqLength(pp_ctx->package_modules_bodies)); /* check if parameters are updated */ yum = GetPackageModuleFromContext(ctx, "yum"); assert_int_equal(330, yum->updates_ifelapsed); assert_int_equal(550, yum->installed_ifelapsed); EvalContextDestroy(ctx); } static void test_default_package_module_settings() { EvalContext *ctx = EvalContextNew(); PackageModuleBody *pm = make_mock_package_module("apt_get", 120, 240, NULL); AddPackageModuleToContext(ctx, pm); PackageModuleBody *pm2 = make_mock_package_module("yum", 220, 440, NULL); AddPackageModuleToContext(ctx, pm2); PackageModuleBody *pm3 = make_mock_package_module("yum_2", 220, 440, NULL); AddPackageModuleToContext(ctx, pm3); AddDefaultPackageModuleToContext(ctx, "apt_get"); PackageModuleBody *def_pm = GetDefaultPackageModuleFromContext(ctx); assert_string_equal("apt_get", def_pm->name); AddDefaultPackageModuleToContext(ctx, "yum"); def_pm = GetDefaultPackageModuleFromContext(ctx); assert_string_equal("yum", def_pm->name); EvalContextDestroy(ctx); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_default_package_module_settings), unit_test(test_add_module_to_context), }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/tests/unit/key_test.c0000644000000000000000000000520315010704253017467 0ustar00rootroot00000000000000#include #include #include #include #include #include #include /* * Initialization */ static int initialized = 0; static RSA *rsa = NULL; void test_setup() { rsa = RSA_new(); if (rsa) { BIGNUM *bn = NULL; bn = BN_new(); if (!bn) { RSA_free(rsa); initialized = 0; return; } BN_set_word(bn, RSA_F4); RSA_generate_key_ex(rsa, 1024, bn, NULL); BN_free(bn); } initialized = 1; } void test_teardown() { rsa = NULL; initialized = 0; } #define ASSERT_IF_NOT_INITIALIZED \ assert_int_equal(1, initialized) /* * Tests */ static void test_key_basic(void) { test_setup(); ASSERT_IF_NOT_INITIALIZED; Key *key = NULL; assert_true(key == NULL); key = KeyNew(rsa, HASH_METHOD_MD5); assert_true(key != NULL); assert_int_equal(HASH_METHOD_MD5, KeyHashMethod(key)); assert_true(rsa == KeyRSA(key)); unsigned int length = 0; assert_true(KeyBinaryHash(key, &length) != NULL); assert_int_equal(CF_MD5_LEN, length); assert_true(KeyPrintableHash(key) != NULL); /* Negative cases */ assert_true(KeyNew(NULL, HASH_METHOD_MD5) == NULL); assert_true(KeyNew(rsa, HASH_METHOD_NONE) == NULL); assert_true(KeyNew(NULL, HASH_METHOD_NONE) == NULL); /* Finish */ KeyDestroy(&key); assert_true(key == NULL); test_teardown(); } static void test_key_hash(void) { test_setup(); ASSERT_IF_NOT_INITIALIZED; Key *key = NULL; assert_true(key == NULL); key = KeyNew(rsa, HASH_METHOD_MD5); assert_true(key != NULL); assert_int_equal(HASH_METHOD_MD5, KeyHashMethod(key)); /* We now examine the first four bytes of the hash, to check the printable bit */ const char *md5_hash = KeyPrintableHash(key); assert_true((md5_hash[0] == 'M') && (md5_hash[1] == 'D') && (md5_hash[2] == '5') && (md5_hash[3] == '=')); /* When we change the hashing algorithm, a new hash is automatically generated. */ assert_int_equal(0, KeySetHashMethod(key, HASH_METHOD_SHA256)); const char *sha256_hash = KeyPrintableHash(key); assert_true((sha256_hash[0] == 'S') && (sha256_hash[1] == 'H') && (sha256_hash[2] == 'A') && (sha256_hash[3] == '=')); KeyDestroy(&key); test_teardown(); } /* * Main routine * Notice the calls to both setup and teardown. */ int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_key_basic), unit_test(test_key_hash) }; OpenSSL_add_all_digests(); int result = run_tests(tests); return result; } cfengine-3.24.2/tests/unit/conversion_test.c0000644000000000000000000002371615010704253021075 0ustar00rootroot00000000000000#include #include #include static void test_string_is_boolean(void) { // This test should be updated if someone changes CF_BOOL: assert_string_equal(CF_BOOL, "true,false,yes,no,on,off"); // Accepted boolean values: assert_true(StringIsBoolean("true")); assert_true(StringIsBoolean("false")); assert_true(StringIsBoolean("yes")); assert_true(StringIsBoolean("no")); assert_true(StringIsBoolean("on")); assert_true(StringIsBoolean("off")); // Anything else is not boolean: assert_false(StringIsBoolean("boolean")); assert_false(StringIsBoolean("bool")); assert_false(StringIsBoolean("")); assert_false(StringIsBoolean(" ")); assert_false(StringIsBoolean(",")); assert_false(StringIsBoolean(",,")); assert_false(StringIsBoolean("()")); assert_false(StringIsBoolean("$(foo)")); assert_false(StringIsBoolean("$(true)")); assert_false(StringIsBoolean("y")); assert_false(StringIsBoolean("n")); assert_false(StringIsBoolean("tru")); assert_false(StringIsBoolean("fals")); assert_false(StringIsBoolean("true,")); assert_false(StringIsBoolean(",false")); assert_false(StringIsBoolean("o,n")); assert_false(StringIsBoolean(" on ")); assert_false(StringIsBoolean("onoff")); assert_false(StringIsBoolean("onon")); } static void test_boolean_from_string(void) { // This test should be updated if someone changes CF_BOOL: assert_string_equal(CF_BOOL, "true,false,yes,no,on,off"); // Expected true values: assert_true(BooleanFromString("true")); assert_true(BooleanFromString("yes")); assert_true(BooleanFromString("on")); // Expected false values: assert_false(BooleanFromString("false")); assert_false(BooleanFromString("no")); assert_false(BooleanFromString("off")); // Edge cases, default to true: assert_true(BooleanFromString("boolean")); assert_true(BooleanFromString("bool")); assert_true(BooleanFromString("")); assert_true(BooleanFromString(" ")); assert_true(BooleanFromString(",")); assert_true(BooleanFromString(",,")); assert_true(BooleanFromString("()")); assert_true(BooleanFromString("$(foo)")); assert_true(BooleanFromString("$(true)")); assert_true(BooleanFromString("y")); assert_true(BooleanFromString("n")); assert_true(BooleanFromString("tru")); assert_true(BooleanFromString("fals")); assert_true(BooleanFromString("true,")); assert_true(BooleanFromString(",false")); assert_true(BooleanFromString("o,n")); assert_true(BooleanFromString(" on ")); assert_true(BooleanFromString("onoff")); assert_true(BooleanFromString("onon")); } static void test_int_from_string(void) { assert_int_equal(IntFromString("0"), 0); assert_int_equal(IntFromString("1"), 1); assert_int_equal(IntFromString(" 1"), 1); assert_int_equal(IntFromString("-1"), (long) -1); assert_int_equal(IntFromString("-1k"), (long) -1000); assert_int_equal(IntFromString("-123"), (long) -123); assert_int_equal(IntFromString("12 "), 12); assert_int_equal(IntFromString("12k "), 12000); assert_int_equal(IntFromString("\t1m "), 1000000); /* ==== SPECIAL CASES ==== */ assert_int_equal(IntFromString("inf"), CF_INFINITY); assert_int_equal(IntFromString("now"), CFSTARTTIME); assert_int_equal(IntFromString("2k"), 2000); assert_int_equal(IntFromString("3K"), 3072); assert_int_equal(IntFromString("4m"), 4000000); assert_int_equal(IntFromString("1M"), 1024 * 1024); /* Percentages are stored as negatives TODO fix. */ assert_int_equal(IntFromString("10%"), (long) -10); /* Unknown quantifiers are just being ignored. */ assert_int_equal(IntFromString("13o"), 13); /* ==== CONTROLLED FAILURES ==== */ assert_int_equal(IntFromString(NULL), CF_NOINT); assert_int_equal(IntFromString(""), CF_NOINT); assert_int_equal(IntFromString(" "), CF_NOINT); assert_int_equal(IntFromString("$(blah)"), CF_NOINT); assert_int_equal(IntFromString("123.45"), CF_NOINT); assert_int_equal(IntFromString("120%"), CF_NOINT); assert_int_equal(IntFromString("-1%"), CF_NOINT); assert_int_equal(IntFromString("14 o"), CF_NOINT); assert_int_equal(IntFromString("2ko"), CF_NOINT); assert_int_equal(IntFromString("3K o"), CF_NOINT); /* The quantifier is not expanded yet. */ assert_int_equal(IntFromString("99$(blah)"), CF_NOINT); } static void test_double_from_string(void) { double val; /* ===== TESTING SUCCESS ===== */ assert_true(DoubleFromString("1.2k", &val)); assert_double_close(1200.0, val); assert_true(DoubleFromString("1m", &val)); assert_double_close(1000000.0, val); assert_true(DoubleFromString("1K", &val)); assert_double_close(1024.0, val); /* Previously reserved as NO_DOUBLE define. */ assert_true(DoubleFromString("-123.45", &val)); assert_double_close(-123.45, val); assert_true(DoubleFromString("0.1", &val)); assert_double_close(0.1, val); /* leading space is OK. */ assert_true(DoubleFromString(" 0.2", &val)); assert_double_close(0.2, val); assert_true(DoubleFromString(" 0.2k", &val)); assert_double_close(200., val); assert_true(DoubleFromString("0.1%", &val)); /* Currently percentages are stored as negatives; TODO FIX! */ assert_double_close(-0.1, val); /* Space quantifier ignored. */ assert_true(DoubleFromString("1233 ", &val)); assert_double_close(1233, val); assert_true(DoubleFromString("1112 ", &val)); assert_double_close(1112, val); /* Invalid quantifier, ignored for backwards compatibility. */ assert_true(DoubleFromString("11.1o", &val)); assert_double_close(11.1, val); /* ===== ERROR RETURN ===== */ /* Verify that parameter is not modified. */ double old_val = val; assert_false(DoubleFromString("", &val)); assert_false(DoubleFromString(" ", &val)); assert_false(DoubleFromString(" ", &val)); assert_false(DoubleFromString("abc", &val)); assert_false(DoubleFromString("G1", &val)); /* Anomalous remainders. */ assert_false(DoubleFromString("123adf", &val)); assert_false(DoubleFromString("123 adf", &val)); assert_false(DoubleFromString("123 adf", &val)); assert_false(DoubleFromString("123 adf", &val)); assert_false(DoubleFromString("123$(remainder)", &val)); assert_true(val == old_val); } static void test_CommandArg0_bound(void) { char dst[128]; size_t zret; zret = CommandArg0_bound(dst, "", sizeof(dst)); assert_string_equal(dst, ""); assert_int_equal(zret, 0); zret = CommandArg0_bound(dst, " ", sizeof(dst)); assert_string_equal(dst, ""); assert_int_equal(zret, 0); zret = CommandArg0_bound(dst, " blah", sizeof(dst)); assert_string_equal(dst, ""); assert_int_equal(zret, 0); zret = CommandArg0_bound(dst, "blah", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "blah blue", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "\"\"", sizeof(dst)); assert_string_equal(dst, ""); assert_int_equal(zret, 0); zret = CommandArg0_bound(dst, "\"blah\"", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "\"blah", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "\"blah blue", sizeof(dst)); assert_string_equal(dst, "blah blue"); assert_int_equal(zret, 9); zret = CommandArg0_bound(dst, "\"\" blus", sizeof(dst)); assert_string_equal(dst, ""); assert_int_equal(zret, 0); zret = CommandArg0_bound(dst, "\"blah\" blue", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "\"blah\"blue", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "blah ", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "\" \"", sizeof(dst)); assert_string_equal(dst, " "); assert_int_equal(zret, 1); zret = CommandArg0_bound(dst, "\" \" ", sizeof(dst)); assert_string_equal(dst, " "); assert_int_equal(zret, 1); zret = CommandArg0_bound(dst, "blah \"blue\"", sizeof(dst)); assert_string_equal(dst, "blah"); assert_int_equal(zret, 4); zret = CommandArg0_bound(dst, "blah\"blue\"", sizeof(dst)); assert_string_equal(dst, "blah\"blue\""); assert_int_equal(zret, 10); zret = CommandArg0_bound(dst, "blah\"blue", sizeof(dst)); assert_string_equal(dst, "blah\"blue"); assert_int_equal(zret, 9); /* TEST OVERFLOW */ zret = CommandArg0_bound(dst, "", 0); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, "blah", 0); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, " ", 0); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, "\"blah\"", 0); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, "blah", 1); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, "\"blah\"", 1); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, "b", 1); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, "\"b\"", 1); assert_int_equal(zret, (size_t) -1); zret = CommandArg0_bound(dst, "", 1); assert_int_equal(zret, 0); /* empty string fits */ zret = CommandArg0_bound(dst, " ", 1); assert_int_equal(zret, 0); /* empty string fits */ } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_string_is_boolean), unit_test(test_boolean_from_string), unit_test(test_int_from_string), unit_test(test_double_from_string), unit_test(test_CommandArg0_bound), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/scope_test.c0000644000000000000000000000102715010704253020010 0ustar00rootroot00000000000000#include #include #include #include static void test_name_join(void) { { char buf[CF_MAXVARSIZE] = { 0 }; JoinScopeName(NULL, "sys", buf); assert_string_equal("sys", buf); } { char buf[CF_MAXVARSIZE] = { 0 }; JoinScopeName("ns", "b", buf); assert_string_equal("ns:b", buf); } } int main() { const UnitTest tests[] = { unit_test(test_name_join), }; PRINT_TEST_BANNER(); return run_tests(tests); } cfengine-3.24.2/tests/unit/test.h0000644000000000000000000000264615010704253016634 0ustar00rootroot00000000000000/* ALWAYS INCLUDE FIRST, so that platform.h is included first as well! */ #ifndef CFENGINE_TEST_H #define CFENGINE_TEST_H #include #include #include #include #include #include /* Use this define for specific overrides inside all our source tree. */ #define CFENGINE_TEST #define PRINT_TEST_BANNER() \ printf("==================================================\n"); \ printf("Starting test: %s\n", __FILE__); \ printf("==================================================\n") char *file_read_string(FILE *in); void assert_file_equal(FILE *a, FILE *b); #define assert_double_close(a, b) _assert_double_close(a, b, __FILE__, __LINE__) void _assert_double_close(double left, double right, const char *const file, const int line); void test_progress(void); void test_progress_end(void); // like assert_string_equal, but better with respect to pointers: // if a and b are NULL, returns true // if a or b is NULL print error using assert_int // if a and b are not NULL, use assert_string #define assert_string_int_equal(a, b)\ {\ const char* x = a;\ const char* y = b;\ if (x!=y)\ {\ if (x==NULL||y==NULL)\ {\ assert_int_equal(x, y);\ }\ else\ {\ assert_string_equal(x, y);\ }\ }\ }\ #endif cfengine-3.24.2/tests/unit/cmockery.h0000644000000000000000000005315215010704253017467 0ustar00rootroot00000000000000/* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CMOCKERY_H_ # define CMOCKERY_H_ /* * These headers or their equivalents should be included prior to including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. */ # if defined(__GNUC__) && (__GNUC__ * 100 >= 3) # define FUNC_ATTR_NORETURN __attribute__((noreturn)) # else/* not gcc >= 3.0 */ # define FUNC_ATTR_NORETURN # endif // For those who are used to __func__ from gcc. # ifndef __func__ # define __func__ __FUNCTION__ # endif /* Largest integral type. This type should be large enough to hold any * pointer or integer supported by the compiler. */ # ifndef LargestIntegralType # define LargestIntegralType unsigned long long # endif// LargestIntegralType // Printf format used to display LargestIntegralType. # ifndef LargestIntegralTypePrintfFormat # ifdef _WIN32 # define LargestIntegralTypePrintfFormat "%I64x" # define LargestIntegralTypePrintfDecimal "%I64d" # else # define LargestIntegralTypePrintfFormat "%llx" # define LargestIntegralTypePrintfDecimal "%lld" # endif // _WIN32 # endif// LargestIntegralTypePrintfFormat // Perform an unsigned cast to LargestIntegralType. # define cast_to_largest_integral_type(value) \ _cast_to_largest_integral_type(sizeof(value), value) // Retrieves a return value for the current function. # define mock() _mock(__func__, __FILE__, __LINE__) /* Stores a value to be returned by the specified function later. * The count parameter returns the number of times the value should be returned * by mock(). If count is set to -1 the value will always be returned. */ # define will_return(function, value) \ _will_return(#function, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), 1) # define will_return_count(function, value, count) \ _will_return(#function, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) /* Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event * parameter is provided it must be allocated on the heap and doesn't need to * be deallocated by the caller. */ # define expect_check(function, parameter, check_function, check_data) \ _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ cast_to_largest_integral_type(check_data), NULL, 0) /* Add an event to check a parameter, using check_expected(), against a set of * values. See will_return() for a description of the count parameter. */ # define expect_in_set(function, parameter, value_array) \ expect_in_set_count(function, parameter, value_array, 1) # define expect_in_set_count(function, parameter, value_array, count) \ _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ sizeof(value_array) / sizeof((value_array)[0]), count) # define expect_not_in_set(function, parameter, value_array) \ expect_not_in_set_count(function, parameter, value_array, 1) # define expect_not_in_set_count(function, parameter, value_array, count) \ _expect_not_in_set( \ #function, #parameter, __FILE__, __LINE__, value_array, \ sizeof(value_array) / sizeof((value_array)[0]), count) /* Add an event to check a parameter, using check_expected(), against a * signed range. Where range is minimum <= value <= maximum. * See will_return() for a description of the count parameter. */ # define expect_in_range(function, parameter, minimum, maximum) \ expect_in_range_count(function, parameter, minimum, maximum, 1) # define expect_in_range_count(function, parameter, minimum, maximum, count) \ _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ maximum, count) /* Add an event to check a parameter, using check_expected(), against a * signed range. Where range is value < minimum or value > maximum. * See will_return() for a description of the count parameter. */ # define expect_not_in_range(function, parameter, minimum, maximum) \ expect_not_in_range_count(function, parameter, minimum, maximum, 1) # define expect_not_in_range_count(function, parameter, minimum, maximum, \ count) \ _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ minimum, maximum, count) /* Add an event to check whether a parameter, using check_expected(), is or * isn't a value. See will_return() for a description of the count parameter. */ # define expect_value(function, parameter, value) \ expect_value_count(function, parameter, value, 1) # define expect_value_count(function, parameter, value, count) \ _expect_value(#function, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) # define expect_not_value(function, parameter, value) \ expect_not_value_count(function, parameter, value, 1) # define expect_not_value_count(function, parameter, value, count) \ _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(value), count) /* Add an event to check whether a parameter, using check_expected(), * is or isn't a string. See will_return() for a description of the count * parameter. */ # define expect_string(function, parameter, string) \ expect_string_count(function, parameter, string, 1) # define expect_string_count(function, parameter, string, count) \ _expect_string(#function, #parameter, __FILE__, __LINE__, \ (const char*)(string), count) # define expect_not_string(function, parameter, string) \ expect_not_string_count(function, parameter, string, 1) # define expect_not_string_count(function, parameter, string, count) \ _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ (const char*)(string), count) /* Add an event to check whether a parameter, using check_expected() does or * doesn't match an area of memory. See will_return() for a description of * the count parameter. */ # define expect_memory(function, parameter, memory, size) \ expect_memory_count(function, parameter, memory, size, 1) # define expect_memory_count(function, parameter, memory, size, count) \ _expect_memory(#function, #parameter, __FILE__, __LINE__, \ (const void*)(memory), size, count) # define expect_not_memory(function, parameter, memory, size) \ expect_not_memory_count(function, parameter, memory, size, 1) # define expect_not_memory_count(function, parameter, memory, size, count) \ _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ (const void*)(memory), size, count) /* Add an event to allow any value for a parameter checked using * check_expected(). See will_return() for a description of the count * parameter. */ # define expect_any(function, parameter) \ expect_any_count(function, parameter, 1) # define expect_any_count(function, parameter, count) \ _expect_any(#function, #parameter, __FILE__, __LINE__, count) /* Determine whether a function parameter is correct. This ensures the next * value queued by one of the expect_*() macros matches the specified variable. */ # define check_expected(parameter) \ _check_expected(__func__, #parameter, __FILE__, __LINE__, \ cast_to_largest_integral_type(parameter)) // Assert that the given expression is true. # define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ __FILE__, __LINE__) // Assert that the given expression is false. # define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ __FILE__, __LINE__) // Assert that the two given integers are equal, otherwise fail. # define assert_int_equal(a, b) \ _assert_int_equal(cast_to_largest_integral_type(a), \ cast_to_largest_integral_type(b), \ __FILE__, __LINE__) // Assert that the two given integers are not equal, otherwise fail. # define assert_int_not_equal(a, b) \ _assert_int_not_equal(cast_to_largest_integral_type(a), \ cast_to_largest_integral_type(b), \ __FILE__, __LINE__) // Assert that the two given strings are equal, otherwise fail. # define assert_string_equal(a, b) \ _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ __LINE__) // Assert that the two given strings are not equal, otherwise fail. # define assert_string_not_equal(a, b) \ _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ __LINE__) // Assert that the two given areas of memory are equal, otherwise fail. # define assert_memory_equal(a, b, size) \ _assert_memory_equal((const char*)(a), (const char*)(b), size, __FILE__, \ __LINE__) // Assert that the two given areas of memory are not equal, otherwise fail. # define assert_memory_not_equal(a, b, size) \ _assert_memory_not_equal((const char*)(a), (const char*)(b), size, \ __FILE__, __LINE__) // Assert that the specified value is >= minimum and <= maximum. # define assert_in_range(value, minimum, maximum) \ _assert_in_range( \ cast_to_largest_integral_type(value), \ cast_to_largest_integral_type(minimum), \ cast_to_largest_integral_type(maximum), __FILE__, __LINE__) // Assert that the specified value is < minimum or > maximum # define assert_not_in_range(value, minimum, maximum) \ _assert_not_in_range( \ cast_to_largest_integral_type(value), \ cast_to_largest_integral_type(minimum), \ cast_to_largest_integral_type(maximum), __FILE__, __LINE__) // Assert that the specified value is within a set. # define assert_in_set(value, values, number_of_values) \ _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) // Assert that the specified value is not within a set. # define assert_not_in_set(value, values, number_of_values) \ _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) // Forces the test to fail immediately and quit. # define fail() _fail(__FILE__, __LINE__) // Generic method to kick off testing # define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL) // Initializes a UnitTest structure. # define unit_test(func) { .name = #func, .f = { .function = func }, .function_type = UNIT_TEST_FUNCTION_TYPE_TEST } # define unit_test_with_state(func) { .name = #func, .f = { .function_with_state = func }, .function_type = UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE } # define unit_test_setup(test, setup) \ { .name = #test "_" #setup, .f = { .function_with_state = setup }, .function_type = UNIT_TEST_FUNCTION_TYPE_SETUP } # define unit_test_teardown(test, teardown) \ { .name = #test "_" #teardown, .f = { .function_with_state = teardown }, .function_type = UNIT_TEST_FUNCTION_TYPE_TEARDOWN } /* Initialize an array of UnitTest structures with a setup function for a test * and a teardown function. Either setup or teardown can be NULL. */ # define unit_test_setup_teardown(test, setup, teardown) \ unit_test_setup(test, setup), \ unit_test_with_state(test), \ unit_test_teardown(test, teardown) /* * Run tests specified by an array of UnitTest structures. The following * example illustrates this macro's use with the unit_test macro. * * void Test0(); * void Test1(); * * int main(int argc, char* argv[]) { * const UnitTest tests[] = { * unit_test(Test0); * unit_test(Test1); * }; * return run_tests(tests); * } */ # define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof(tests)[0], __FILE__) // Dynamic allocators # define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) # define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) # define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) // Redirect malloc, calloc and free to the unit test allocators. # if UNIT_TESTING # define malloc test_malloc # define calloc test_calloc # define free test_free # endif// UNIT_TESTING /* * Ensure mock_assert() is called. If mock_assert() is called the assert * expression string is returned. * For example: * * #define assert mock_assert * * void showmessage(const char *message) { * assert(message); * } * * int main(int argc, const char* argv[]) { * expect_assert_failure(show_message(NULL)); * printf("succeeded\n"); * return 0; * } */ # define expect_assert_failure(function_call) \ { \ const int has_expression = setjmp(global_expect_assert_env); \ global_expecting_assert = 1; \ if (has_expression) { \ print_message("Expected assertion %s occurred\n", \ global_expect_assert_expression); \ global_expecting_assert = 0; \ } else { \ function_call ; \ global_expecting_assert = 0; \ print_error("Expected assert in %s\n", #function_call); \ _fail(__FILE__, __LINE__); \ } \ } // Function prototype for setup, test and teardown functions. typedef void (*UnitTestFunction) (void); typedef void (*UnitTestFunctionWithState) (void **state); // Function that determines whether a function parameter value is correct. typedef int (*CheckParameterValue) (const LargestIntegralType value, const LargestIntegralType check_value_data); // Type of the unit test function. typedef enum UnitTestFunctionType { UNIT_TEST_FUNCTION_TYPE_TEST = 0, UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE, UNIT_TEST_FUNCTION_TYPE_SETUP, UNIT_TEST_FUNCTION_TYPE_TEARDOWN, } UnitTestFunctionType; /* Stores a unit test function with its name and type. * NOTE: Every setup function must be paired with a teardown function. It's * possible to specify NULL function pointers. */ typedef struct UnitTest { const char *name; union { UnitTestFunction function; UnitTestFunctionWithState function_with_state; } f; UnitTestFunctionType function_type; } UnitTest; // Location within some source code. typedef struct SourceLocation { const char *file; int line; } SourceLocation; // Event that's called to check a parameter value. typedef struct CheckParameterEvent { SourceLocation location; const char *parameter_name; CheckParameterValue check_value; LargestIntegralType check_value_data; } CheckParameterEvent; // Used by expect_assert_failure() and mock_assert(). extern int global_expecting_assert; extern const char *global_expect_assert_expression; extern jmp_buf global_expect_assert_env; LargestIntegralType _cast_to_largest_integral_type(size_t size, ...); // Retrieves a value for the given function, as set by "will_return". LargestIntegralType _mock(const char *const function, const char *const file, const int line); void _expect_check(const char *const function, const char *const parameter, const char *const file, const int line, const CheckParameterValue check_function, const LargestIntegralType check_data, CheckParameterEvent *const event, const int count); void _expect_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_not_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count); void _expect_not_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count); void _expect_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count); void _expect_not_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count); void _expect_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count); void _expect_not_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count); void _expect_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count); void _expect_not_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count); void _expect_any(const char *const function, const char *const parameter, const char *const file, const int line, const int count); void _check_expected(const char *const function_name, const char *const parameter_name, const char *file, const int line, const LargestIntegralType value); // Can be used to replace assert in tested code so that in conjunction with // check_assert() it's possible to determine whether an assert condition has // failed without stopping a test. void mock_assert(const int result, const char *const expression, const char *const file, const int line); void _will_return(const char *const function_name, const char *const file, const int line, const LargestIntegralType value, const int count); void _assert_true(const LargestIntegralType result, const char *const expression, const char *const file, const int line); void _assert_int_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line); void _assert_int_not_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line); void _assert_string_equal(const char *const a, const char *const b, const char *const file, const int line); void _assert_string_not_equal(const char *const a, const char *const b, const char *file, const int line); void _assert_memory_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line); void _assert_memory_not_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line); void _assert_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line); void _assert_not_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line); void _assert_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line); void _assert_not_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line); void *_test_malloc(const size_t size, const char *file, const int line); void *_test_calloc(const size_t number_of_elements, const size_t size, const char *file, const int line); void _test_free(void *const ptr, const char *file, const int line); void _fail(const char *const file, const int line) FUNC_ATTR_NORETURN; int _run_test(const char *const function_name, const UnitTestFunction Function, void **const state, const UnitTestFunctionType function_type, const void *const heap_check_point); int _run_tests(const UnitTest *const tests, const size_t number_of_tests, const char *const file); // XML init and output void vinit_xml (const char *const format, va_list args); void vprint_xml(const char *const format, va_list args); void init_xml (const char *const format, ...); void print_xml(const char *const format, ...); void vinit_cunit_run_files (const char *const file, const char *const format, va_list args); void init_cunit_run_files (const char *const file, const char *const format, ...); void append_xml_tmp(const char *ofile, const char *ifile); // Standard output and error print methods. void print_message(const char *const format, ...); void print_error(const char *const format, ...); void vprint_message(const char *const format, va_list args); void vprint_error(const char *const format, va_list args); #endif cfengine-3.24.2/tests/unit/mon_cpu_test.c0000644000000000000000000000341715010704253020344 0ustar00rootroot00000000000000#include "test.h" #include "generic_agent.h" #include "mon.h" static double GetCpuStat() { double q, dq = -1.0; long total_time = 1; FILE *fp; long userticks = 0, niceticks = 0, systemticks = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; char cpuname[CF_MAXVARSIZE], buf[CF_BUFSIZE]; if ((fp = fopen("/proc/stat", "r")) == NULL) { return -1.0; } while (!feof(fp)) { if (fgets(buf, sizeof(buf), fp) == NULL) { break; } if (sscanf(buf, "%s%ld%ld%ld%ld%ld%ld%ld", cpuname, &userticks, &niceticks, &systemticks, &idle, &iowait, &irq, &softirq) != 8) { continue; } total_time = (userticks + niceticks + systemticks + idle); q = 100.0 * (double) (total_time - idle); if (strcmp(cpuname, "cpu") == 0) { dq = q / (double) total_time; if ((dq > 100) || (dq < 0)) { dq = 50; } } } fclose(fp); return dq; } void test_cpu_monitor(void) { double cf_this[100]; double dq1 = GetCpuStat(); if (dq1 == -1.0) { assert_true(1); return; } MonCPUGatherData(cf_this); double dq2 = GetCpuStat(); if (dq2 == -1.0) { assert_true(1); return; } double min = (double) (dq2=lower && cf_this[ob_cpuall]<=upper); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_cpu_monitor), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/variable_test.c0000644000000000000000000002706015010704253020471 0ustar00rootroot00000000000000#include #include #include struct Variable_ { VarRef *ref; Rval rval; DataType type; StringSet *tags; char *comment; const Promise *promise; // The promise that set the present value }; static bool PutVar(VariableTable *table, char *var_str) { VarRef *ref = VarRefParse(var_str); Rval rval = (Rval) { var_str, RVAL_TYPE_SCALAR }; bool ret = VariableTablePut(table, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL); VarRefDestroy(ref); return ret; } static VariableTable *ReferenceTable(void) { VariableTable *t = VariableTableNew(); assert_false(PutVar(t, "scope1.lval1")); assert_false(PutVar(t, "scope1.lval2")); assert_false(PutVar(t, "scope2.lval1")); { VarRef *ref = VarRefParse("scope1.array[one]"); Rval rval = (Rval) { "scope1.array[one]", RVAL_TYPE_SCALAR }; assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL)); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("scope1.array[two]"); Rval rval = (Rval) { "scope1.array[two]", RVAL_TYPE_SCALAR }; assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL)); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("scope1.array[two][three]"); Rval rval = (Rval) { "scope1.array[two][three]", RVAL_TYPE_SCALAR }; assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL)); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("scope1.array[two][four]"); Rval rval = (Rval) { "scope1.array[two][four]", RVAL_TYPE_SCALAR }; assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL)); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("scope3.array[te][st]"); Rval rval = (Rval) { "scope3.array[te][st]", RVAL_TYPE_SCALAR }; assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL)); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("scope3.array[t][e][s][t]"); Rval rval = (Rval) { "scope3.array[t][e][s][t]", RVAL_TYPE_SCALAR }; assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL)); VarRefDestroy(ref); } assert_false(PutVar(t, "ns1:scope1.lval1")); assert_false(PutVar(t, "ns1:scope1.lval2")); assert_false(PutVar(t, "ns1:scope2.lval1")); return t; } static void TestGet(VariableTable *t, const char *ref_str) { VarRef *ref = VarRefParse(ref_str); Variable *v = VariableTableGet(t, ref); assert_true(v != NULL); assert_int_equal(0, VarRefCompare(ref, v->ref)); assert_string_equal(ref_str, RvalScalarValue(v->rval)); VarRefDestroy(ref); } static void test_get_in_default_namespace(void) { VariableTable *t = ReferenceTable(); TestGet(t, "scope1.lval1"); TestGet(t, "scope1.lval2"); TestGet(t, "scope2.lval1"); VariableTableDestroy(t); } // Redmine 6674 static void test_multi_index_array_conflation(void) { VariableTable *t = ReferenceTable(); TestGet(t, "scope3.array[te][st]"); TestGet(t, "scope3.array[t][e][s][t]"); VariableTableDestroy(t); } static void test_get_different_namespaces(void) { VariableTable *t = ReferenceTable(); TestGet(t, "scope1.lval1"); TestGet(t, "ns1:scope1.lval1"); VariableTableDestroy(t); } static void test_get_indices(void) { VariableTable *t = ReferenceTable(); TestGet(t, "scope1.array[one]"); TestGet(t, "scope1.array[two]"); VariableTableDestroy(t); } static void test_replace(void) { VariableTable *t = ReferenceTable(); VarRef *ref = VarRefParse("scope1.lval1"); TestGet(t, "scope1.lval1"); Rval rval = (Rval) { "foo", RVAL_TYPE_SCALAR }; assert_true(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL)); Variable *v = VariableTableGet(t, ref); assert_true(v != NULL); assert_string_equal("foo", RvalScalarValue(v->rval)); VarRefDestroy(ref); VariableTableDestroy(t); } static void test_remove(void) { VariableTable *t = ReferenceTable(); { VarRef *ref = VarRefParse("scope1.array[one]"); assert_true(VariableTableRemove(t, ref)); assert_true(VariableTableGet(t, ref) == NULL); assert_false(VariableTableRemove(t, ref)); assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL)); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("ns1:scope1.lval1"); assert_true(VariableTableRemove(t, ref)); assert_true(VariableTableGet(t, ref) == NULL); assert_false(VariableTableRemove(t, ref)); assert_int_equal(10, VariableTableCount(t, NULL, NULL, NULL)); VarRefDestroy(ref); } VariableTableDestroy(t); } static void test_clear(void) { { VariableTable *t = ReferenceTable(); assert_false(VariableTableClear(t, "xxx", NULL, NULL)); assert_false(VariableTableClear(t, NULL, "xxx", NULL)); assert_false(VariableTableClear(t, NULL, NULL, "xxx")); assert_int_equal(12, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, NULL, NULL, NULL)); assert_int_equal(0, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, "default", NULL, NULL)); assert_int_equal(3, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, "default", "scope1", NULL)); assert_int_equal(6, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, "default", NULL, "array")); assert_int_equal(6, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, "ns1", NULL, NULL)); assert_int_equal(9, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, "ns1", "scope2", NULL)); assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, "default", "scope1", "lval1")); assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } { VariableTable *t = ReferenceTable(); assert_true(VariableTableClear(t, "default", "scope1", "lval1")); assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL)); VariableTableDestroy(t); } } static void test_counting(void) { VariableTable *t = ReferenceTable(); assert_int_equal(12, VariableTableCount(t, NULL, NULL, NULL)); assert_int_equal(9, VariableTableCount(t, "default", NULL, NULL)); assert_int_equal(8, VariableTableCount(t, NULL, "scope1", NULL)); assert_int_equal(6, VariableTableCount(t, "default", "scope1", NULL)); assert_int_equal(4, VariableTableCount(t, NULL, NULL, "lval1")); assert_int_equal(3, VariableTableCount(t, "ns1", NULL, NULL)); assert_int_equal(2, VariableTableCount(t, "ns1", "scope1", NULL)); assert_int_equal(6, VariableTableCount(t, NULL, NULL, "array")); assert_int_equal(1, VariableTableCount(t, "default", "scope1", "lval1")); VariableTableDestroy(t); } static void test_iterate_indices(void) { VariableTable *t = ReferenceTable(); { VarRef *ref = VarRefParse("default:scope1.array"); VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref); unsigned short number_of_entries = 0; while (VariableTableIteratorNext(iter)) { number_of_entries++; } assert_int_equal(4, number_of_entries); VariableTableIteratorDestroy(iter); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("default:scope1.array[two]"); VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref); unsigned short number_of_entries = 0; while (VariableTableIteratorNext(iter)) { number_of_entries++; } assert_int_equal(3, number_of_entries); VariableTableIteratorDestroy(iter); VarRefDestroy(ref); } VariableTableDestroy(t); } // Below test relies on the ordering items in RB tree which is strongly // related to the hash function used. /* No more relevant, RBTree has been replaced with Map. */ #if 0 static void test_iterate_indices_ordering_related(void) { VariableTable *t = ReferenceTable(); { VarRef *ref = VarRefParse("default:scope1.array"); VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref); Variable *v = VariableTableIteratorNext(iter); assert_true(v != NULL); assert_int_equal(1, v->ref->num_indices); assert_string_equal("two", v->ref->indices[0]); v = VariableTableIteratorNext(iter); assert_true(v != NULL); assert_int_equal(2, v->ref->num_indices); assert_string_equal("two", v->ref->indices[0]); assert_string_equal("three", v->ref->indices[1]); v = VariableTableIteratorNext(iter); assert_true(v != NULL); assert_int_equal(2, v->ref->num_indices); assert_string_equal("two", v->ref->indices[0]); assert_string_equal("four", v->ref->indices[1]); v = VariableTableIteratorNext(iter); assert_true(v != NULL); assert_int_equal(1, v->ref->num_indices); assert_string_equal("one", v->ref->indices[0]); assert_false(VariableTableIteratorNext(iter) != NULL); VariableTableIteratorDestroy(iter); VarRefDestroy(ref); } { VarRef *ref = VarRefParse("default:scope1.array[two]"); VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref); Variable *v = VariableTableIteratorNext(iter); assert_true(v != NULL); assert_int_equal(1, v->ref->num_indices); assert_string_equal("two", v->ref->indices[0]); v = VariableTableIteratorNext(iter); assert_true(v != NULL); assert_int_equal(2, v->ref->num_indices); assert_string_equal("two", v->ref->indices[0]); assert_string_equal("three", v->ref->indices[1]); v = VariableTableIteratorNext(iter); assert_true(v != NULL); assert_int_equal(2, v->ref->num_indices); assert_string_equal("two", v->ref->indices[0]); assert_string_equal("four", v->ref->indices[1]); assert_false(VariableTableIteratorNext(iter) != NULL); VariableTableIteratorDestroy(iter); VarRefDestroy(ref); } VariableTableDestroy(t); } #endif int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_get_in_default_namespace), unit_test(test_get_different_namespaces), unit_test(test_get_indices), // unit_test(test_iterate_indices_ordering_related), unit_test(test_multi_index_array_conflation), unit_test(test_replace), unit_test(test_remove), unit_test(test_clear), unit_test(test_counting), unit_test(test_iterate_indices), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/exec-config-test.c0000644000000000000000000001404215010704253021005 0ustar00rootroot00000000000000#include #include #include #include #include #include #include /* xsnprintf */ static Policy *TestParsePolicy(const char *filename) { char path[PATH_MAX]; xsnprintf(path, sizeof(path), "%s/%s", TESTDATADIR, filename); return ParserParseFile(AGENT_TYPE_COMMON, path, PARSER_WARNING_ALL, PARSER_WARNING_ALL); } typedef void (*TestFn)(const EvalContext *ctx, const Policy *policy); static void run_test_in_policy(const char *policy_filename, TestFn fn) { GenericAgentConfig *agent_config = GenericAgentConfigNewDefault(AGENT_TYPE_EXECUTOR, false); EvalContext *ctx = EvalContextNew(); Policy *policy = TestParsePolicy(policy_filename); PolicyResolve(ctx, policy, agent_config); /* Setup global environment */ strcpy(VFQNAME, "localhost.localdomain"); strcpy(VIPADDRESS, "127.0.0.100"); EvalContextAddIpAddress(ctx, "127.0.0.100", "eth0"); EvalContextAddIpAddress(ctx, "127.0.0.101", "eth1"); fn(ctx, policy); PolicyDestroy(policy); GenericAgentFinalize(ctx, agent_config); } static void execd_config_empty_cb(const EvalContext *ctx, const Policy *policy) { ExecdConfig *config = ExecdConfigNew(ctx, policy); assert_int_equal(12, StringSetSize(config->schedule)); assert_int_equal(true, StringSetContains(config->schedule, "Min00")); assert_int_equal(true, StringSetContains(config->schedule, "Min05")); assert_int_equal(true, StringSetContains(config->schedule, "Min10")); assert_int_equal(true, StringSetContains(config->schedule, "Min15")); assert_int_equal(true, StringSetContains(config->schedule, "Min20")); assert_int_equal(true, StringSetContains(config->schedule, "Min25")); assert_int_equal(true, StringSetContains(config->schedule, "Min30")); assert_int_equal(true, StringSetContains(config->schedule, "Min35")); assert_int_equal(true, StringSetContains(config->schedule, "Min40")); assert_int_equal(true, StringSetContains(config->schedule, "Min45")); assert_int_equal(true, StringSetContains(config->schedule, "Min50")); assert_int_equal(true, StringSetContains(config->schedule, "Min55")); assert_int_equal(0, config->splay_time); assert_string_equal("LOG_USER", config->log_facility); ExecdConfigDestroy(config); } static void test_execd_config_empty(void) { run_test_in_policy("body_executor_control_empty.cf", &execd_config_empty_cb); } static void execd_config_full_cb(const EvalContext *ctx, const Policy *policy) { ExecdConfig *config = ExecdConfigNew(ctx, policy); assert_int_equal(2, StringSetSize(config->schedule)); assert_int_equal(true, StringSetContains(config->schedule, "Min00_05")); assert_int_equal(true, StringSetContains(config->schedule, "Min05_10")); /* Splay calculation uses FQNAME and getuid(), so can't predict actual splay value */ assert_int_equal(true, config->splay_time>=0 && config->splay_time<60); assert_string_equal("LOG_LOCAL6", config->log_facility); ExecdConfigDestroy(config); } static void test_execd_config_full(void) { run_test_in_policy("body_executor_control_full.cf", &execd_config_full_cb); } static void exec_config_empty_cb(const EvalContext *ctx, const Policy *policy) { ExecConfig *config = ExecConfigNew(false, ctx, policy); assert_int_equal(false, config->scheduled_run); /* FIXME: exec-config should provide default exec_command */ assert_string_equal("", config->exec_command); assert_string_equal("", config->mail_server); /* FIXME: exec-config should provide default from address */ assert_string_equal("", config->mail_from_address); assert_string_equal("", config->mail_to_address); /* FIXME: exec-config should provide default subject */ assert_string_equal("", config->mail_subject); assert_int_equal(30, config->mail_max_lines); assert_string_equal("localhost.localdomain", config->fq_name); assert_string_equal("127.0.0.100", config->ip_address); assert_string_equal("127.0.0.100 127.0.0.101", config->ip_addresses); ExecConfigDestroy(config); } static void test_exec_config_empty(void) { run_test_in_policy("body_executor_control_empty.cf", &exec_config_empty_cb); } static void CheckFullExecConfig(const ExecConfig *config) { assert_int_equal(true, config->scheduled_run); assert_string_equal("/bin/echo", config->exec_command); assert_int_equal(120, config->agent_expireafter); assert_string_equal("localhost", config->mail_server); assert_string_equal("cfengine@example.org", config->mail_from_address); assert_string_equal("cfengine_mail@example.org", config->mail_to_address); assert_string_equal("Test [localhost/127.0.0.1]", config->mail_subject); assert_int_equal(50, config->mail_max_lines); assert_string_equal("localhost.localdomain", config->fq_name); assert_string_equal("127.0.0.100", config->ip_address); assert_string_equal("127.0.0.100 127.0.0.101", config->ip_addresses); } static void exec_config_full_cb(const EvalContext *ctx, const Policy *policy) { ExecConfig *config = ExecConfigNew(true, ctx, policy); CheckFullExecConfig(config); ExecConfigDestroy(config); } static void test_exec_config_full(void) { run_test_in_policy("body_executor_control_full.cf", &exec_config_full_cb); } static void exec_config_copy_cb(const EvalContext *ctx, const Policy *policy) { ExecConfig *config = ExecConfigNew(true, ctx, policy); ExecConfig *config2 = ExecConfigCopy(config); ExecConfigDestroy(config); CheckFullExecConfig(config2); ExecConfigDestroy(config2); } static void test_exec_config_copy(void) { run_test_in_policy("body_executor_control_full.cf", &exec_config_copy_cb); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_execd_config_empty), unit_test(test_execd_config_full), unit_test(test_exec_config_empty), unit_test(test_exec_config_full), unit_test(test_exec_config_copy), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/nfs_test.c0000644000000000000000000000443515010704253017473 0ustar00rootroot00000000000000#include #include #include #include static void test_MatchFSInFstab(void) { AppendItem(&FSTABLIST, "fileserver1:/vol/vol10 /mnt/fileserver1/vol10 nfs rw,intr,tcp,fg,rdirplus,noatime,_netdev", NULL); AppendItem(&FSTABLIST, "fileserver1:/vol/vol11 /mnt/fileserver1/vol11 nfs rw,intr,tcp,fg,rdirplus,noatime,_netdev", NULL); AppendItem(&FSTABLIST, "#fileserver1:/vol/vol12 /mnt/fileserver1/vol12 nfs rw,intr,tcp,fg,rdirplus,noatime,_netdev", NULL); AppendItem(&FSTABLIST, "UUID=4a147232-42f7-4e56-aa9e-744b09bce719 / ext4 errors=remount-ro 0 1", NULL); AppendItem(&FSTABLIST, "UUID=b2cf5462-a10f-4d7d-b356-ecec5aea2103 none swap sw 0 0", NULL); AppendItem(&FSTABLIST, "none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0", NULL); AppendItem(&FSTABLIST, "fileserver2:/vol/vol10 /mnt/fileserver2/vol10 nfs rw,intr,tcp,fg,noatime", NULL); AppendItem(&FSTABLIST, "fileserver2:/vol/vol11 /mnt/fileserver2/vol11 nfs rw,intr,tcp,fg,noatime", NULL); AppendItem(&FSTABLIST, "#fileserver2:/vol/vol12 /mnt/fileserver2/vol12 nfs rw,intr,tcp,fg,noatime", NULL); AppendItem(&FSTABLIST, "fileserver3:/vol/vol10 /mnt/fileserver3/vol10 nfs rw,intr,tcp,fg #,noatime", NULL); AppendItem(&FSTABLIST, "fileserver3:/vol/vol11 /mnt/fileserver3/vol11 nfs rw,intr,tcp,fg ,noatime # do we want noatime?", NULL); assert_true(MatchFSInFstab("/mnt/fileserver1/vol10")); assert_true(MatchFSInFstab("/mnt/fileserver1/vol11")); assert_false(MatchFSInFstab("/mnt/fileserver1/vol1")); assert_true(MatchFSInFstab("/mnt/fileserver2/vol10")); assert_true(MatchFSInFstab("/mnt/fileserver2/vol11")); assert_false(MatchFSInFstab("/mnt/fileserver2/vol1")); assert_false(MatchFSInFstab("/mnt/fileserver1/vol12")); assert_false(MatchFSInFstab("/mnt/fileserver2/vol12")); assert_true(MatchFSInFstab("/mnt/fileserver3/vol10")); assert_true(MatchFSInFstab("/mnt/fileserver3/vol11")); assert_false(MatchFSInFstab("/mnt/fileserver3/vol1")); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_MatchFSInFstab), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/linux_process_test.c0000644000000000000000000000726215010704253021603 0ustar00rootroot00000000000000#include #include #include #include /* Stubs for /proc//stat. */ static const char *filecontents[2] = { "1 (i()))))))-:!#!#@)) S 1 3927 3927 1025 3927 4202752 359 0 2 0 0 0 0 0 20 0 1 0 65535 19234816 226 18446744073709551615 1 1 0 0 0 0 0 6 0 18446744073709551615 0 0 17 2 0 0 40 0 0", "3929 (getty) T 1 3929 3929 1027 3929 4202752 359 0 1 0 0 0 0 0 20 0 1 0 100000 19234816 225 18446744073709551615 1 1 0 0 0 0 0 6 0 18446744073709551615 0 0 17 0 0 0 42 0 0", }; static int filepos[2]; int open(const char *filename, ARG_UNUSED int flags, ...) { if (!strcmp(filename, "/proc/1/stat")) { filepos[0] = 0; return 0; } else if (!strcmp(filename, "/proc/2/stat")) { filepos[1] = 0; static int got_intr = false; if (!got_intr) { got_intr = true; errno = EINTR; return -1; } return 1; } else if (!strcmp(filename, "/proc/666/stat")) { errno = EACCES; return -1; } else { errno = ENOENT; return -1; } } ssize_t read(int fd, void *buffer, ARG_UNUSED size_t buf_size) { if (fd == 0) { if (filepos[0] < strlen(filecontents[0])) { memcpy(buffer, filecontents[0], strlen(filecontents[0])); filepos[0] = strlen(filecontents[0]); return strlen(filecontents[0]); } else { return 0; } } if (fd == 1) { static bool got_eintr = false; if (!got_eintr) { got_eintr = true; errno = EINTR; return -1; } else { got_eintr = false; } if (filepos[1] < strlen(filecontents[1])) { memcpy(buffer, filecontents[1] + filepos[1], 1); filepos[1]++; return 1; } else { return 0; } } errno = EIO; return -1; } int close(ARG_UNUSED int fd) { return 0; } static void test_get_start_time_process1(void) { time_t t = GetProcessStartTime(1); assert_int_equal(t, 65535 / sysconf(_SC_CLK_TCK)); } static void test_get_start_time_process2(void) { time_t t2 = GetProcessStartTime(2); assert_int_equal(t2, 100000 / sysconf(_SC_CLK_TCK)); } static void test_get_start_time_process3(void) { time_t t3 = GetProcessStartTime(3); assert_int_equal(t3, PROCESS_START_TIME_UNKNOWN); } static void test_get_start_time_process666(void) { time_t t4 = GetProcessStartTime(666); assert_int_equal(t4, PROCESS_START_TIME_UNKNOWN); } static void test_get_state_process1(void) { ProcessState s = GetProcessState(1); assert_int_equal(s, PROCESS_STATE_RUNNING); } static void test_get_state_process2(void) { ProcessState s = GetProcessState(2); assert_int_equal(s, PROCESS_STATE_STOPPED); } static void test_get_state_process3(void) { ProcessState s = GetProcessState(3); assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST); } static void test_get_state_process666(void) { ProcessState s = GetProcessState(666); assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_get_start_time_process1), unit_test(test_get_start_time_process2), unit_test(test_get_start_time_process3), unit_test(test_get_start_time_process666), unit_test(test_get_state_process1), unit_test(test_get_state_process2), unit_test(test_get_state_process3), unit_test(test_get_state_process666), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/Makefile.in0000644000000000000000000062554115010704301017550 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @HPUX_TRUE@am__append_1 = ../../libpromises/cf3globals.c check_PROGRAMS = processes_select_test$(EXEEXT) \ arg_split_test$(EXEEXT) assoc_test$(EXEEXT) \ getopt_test$(EXEEXT) item_test$(EXEEXT) rlist_test$(EXEEXT) \ domainname_test$(EXEEXT) set_domainname_test$(EXEEXT) \ evalfunction_test$(EXEEXT) eval_context_test$(EXEEXT) \ regex_test$(EXEEXT) lastseen_test$(EXEEXT) \ lastseen_migration_test$(EXEEXT) \ changes_migration_test$(EXEEXT) db_test$(EXEEXT) \ db_concurrent_test$(EXEEXT) item_lib_test$(EXEEXT) \ crypto_symmetric_test$(EXEEXT) persistent_lock_test$(EXEEXT) \ package_versions_compare_test$(EXEEXT) files_lib_test$(EXEEXT) \ files_copy_test$(EXEEXT) parsemode_test$(EXEEXT) \ parser_test$(EXEEXT) passopenfile_test$(EXEEXT) \ policy_test$(EXEEXT) sort_test$(EXEEXT) \ file_name_test$(EXEEXT) logging_test$(EXEEXT) \ granules_test$(EXEEXT) scope_test$(EXEEXT) \ conversion_test$(EXEEXT) files_interfaces_test$(EXEEXT) \ connection_management_test$(EXEEXT) expand_test$(EXEEXT) \ string_expressions_test$(EXEEXT) var_expressions_test$(EXEEXT) \ process_terminate_unix_test$(EXEEXT) process_test$(EXEEXT) \ exec-config-test$(EXEEXT) generic_agent_test$(EXEEXT) \ syntax_test$(EXEEXT) sysinfo_test$(EXEEXT) \ variable_test$(EXEEXT) verify_databases_test$(EXEEXT) \ protocol_test$(EXEEXT) mon_cpu_test$(EXEEXT) \ mon_load_test$(EXEEXT) mon_processes_test$(EXEEXT) \ mustache_test$(EXEEXT) class_test$(EXEEXT) key_test$(EXEEXT) \ cf_upgrade_test$(EXEEXT) matching_test$(EXEEXT) \ strlist_test$(EXEEXT) addr_lib_test$(EXEEXT) \ policy_server_test$(EXEEXT) split_process_line_test$(EXEEXT) \ new_packages_promise_test$(EXEEXT) iteration_test$(EXEEXT) \ $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ $(am__EXEEXT_7) @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@am__append_2 = \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ findhub_test \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ avahi_config_test @NT_FALSE@am__append_3 = redirection_test @NT_FALSE@noinst_PROGRAMS = redirection_test_stub$(EXEEXT) @WITH_INIT_D_SCRIPT_TRUE@am__append_4 = init_script_test.sh @AIX_FALSE@@HPUX_FALSE@@MACOSX_TRUE@XFAIL_TESTS = set_domainname_test$(EXEEXT) \ @AIX_FALSE@@HPUX_FALSE@@MACOSX_TRUE@ process_test$(EXEEXT) \ @AIX_FALSE@@HPUX_FALSE@@MACOSX_TRUE@ mon_processes_test$(EXEEXT) \ @AIX_FALSE@@HPUX_FALSE@@MACOSX_TRUE@ rlist_test$(EXEEXT) @AIX_FALSE@@HPUX_TRUE@XFAIL_TESTS = mon_load_test$(EXEEXT) @AIX_TRUE@XFAIL_TESTS = rlist_test$(EXEEXT) @BUILTIN_EXTENSIONS_FALSE@am__append_5 = enterprise_extension_test @BUILTIN_EXTENSIONS_FALSE@am__append_6 = cfengine-enterprise.la @LINUX_TRUE@am__append_7 = linux_process_test @AIX_TRUE@am__append_8 = aix_process_test @SOLARIS_TRUE@am__append_9 = solaris_process_test @NT_FALSE@am__append_10 = nfs_test @NT_FALSE@am__append_11 = init_script_test_helper subdir = tests/unit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = cfengine_enterprise_la_LIBADD = am__cfengine_enterprise_la_SOURCES_DIST = \ enterprise_extension_test_lib.c @BUILTIN_EXTENSIONS_FALSE@am_cfengine_enterprise_la_OBJECTS = \ @BUILTIN_EXTENSIONS_FALSE@ enterprise_extension_test_lib.lo cfengine_enterprise_la_OBJECTS = $(am_cfengine_enterprise_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = cfengine_enterprise_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(cfengine_enterprise_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILTIN_EXTENSIONS_FALSE@am_cfengine_enterprise_la_rpath = libdb_la_DEPENDENCIES = libstr.la ../../libntech/libutils/libutils.la am__libdb_la_SOURCES_DIST = db_stubs.c ../../libpromises/dbm_api.c \ ../../libpromises/dbm_quick.c ../../libpromises/dbm_tokyocab.c \ ../../libpromises/dbm_lmdb.c ../../libpromises/dbm_migration.c \ ../../libpromises/dbm_migration_lastseen.c \ ../../libpromises/global_mutex.c ../../cf-check/backup.c \ ../../cf-check/diagnose.c ../../cf-check/lmdump.c \ ../../cf-check/repair.c ../../cf-check/replicate_lmdb.c \ ../../cf-check/utilities.c ../../cf-check/validate.c \ ../../libntech/libutils/logging.c \ ../../libntech/libutils/mutex.c \ ../../libntech/libutils/cleanup.c \ ../../libpromises/cf3globals.c @HPUX_TRUE@am__objects_1 = libdb_la-cf3globals.lo am_libdb_la_OBJECTS = libdb_la-db_stubs.lo libdb_la-dbm_api.lo \ libdb_la-dbm_quick.lo libdb_la-dbm_tokyocab.lo \ libdb_la-dbm_lmdb.lo libdb_la-dbm_migration.lo \ libdb_la-dbm_migration_lastseen.lo libdb_la-global_mutex.lo \ libdb_la-backup.lo libdb_la-diagnose.lo libdb_la-lmdump.lo \ libdb_la-repair.lo libdb_la-replicate_lmdb.lo \ libdb_la-utilities.lo libdb_la-validate.lo libdb_la-logging.lo \ libdb_la-mutex.lo libdb_la-cleanup.lo $(am__objects_1) libdb_la_OBJECTS = $(am_libdb_la_OBJECTS) libdb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libdb_la_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ libstr_la_DEPENDENCIES = libtest.la am_libstr_la_OBJECTS = buffer.lo encode.lo logging.lo misc_lib.lo \ regex.lo sequence.lo string_lib.lo writer.lo libstr_la_OBJECTS = $(am_libstr_la_OBJECTS) libtest_la_DEPENDENCIES = ../../libntech/libcompat/libcompat.la am_libtest_la_OBJECTS = cmockery.lo test.lo libtest_la_OBJECTS = $(am_libtest_la_OBJECTS) @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@am__EXEEXT_1 = findhub_test$(EXEEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ avahi_config_test$(EXEEXT) @NT_FALSE@am__EXEEXT_2 = redirection_test$(EXEEXT) @BUILTIN_EXTENSIONS_FALSE@am__EXEEXT_3 = \ @BUILTIN_EXTENSIONS_FALSE@ enterprise_extension_test$(EXEEXT) @LINUX_TRUE@am__EXEEXT_4 = linux_process_test$(EXEEXT) @AIX_TRUE@am__EXEEXT_5 = aix_process_test$(EXEEXT) @SOLARIS_TRUE@am__EXEEXT_6 = solaris_process_test$(EXEEXT) @NT_FALSE@am__EXEEXT_7 = nfs_test$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) addr_lib_test_SOURCES = addr_lib_test.c addr_lib_test_OBJECTS = addr_lib_test.$(OBJEXT) addr_lib_test_LDADD = $(LDADD) addr_lib_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am__aix_process_test_SOURCES_DIST = aix_process_test.c \ ../../libpromises/process_unix.c \ ../../libpromises/process_aix.c \ ../../libntech/libutils/file_lib.c @AIX_TRUE@am_aix_process_test_OBJECTS = aix_process_test.$(OBJEXT) \ @AIX_TRUE@ process_unix.$(OBJEXT) process_aix.$(OBJEXT) \ @AIX_TRUE@ file_lib.$(OBJEXT) aix_process_test_OBJECTS = $(am_aix_process_test_OBJECTS) @AIX_TRUE@aix_process_test_DEPENDENCIES = libtest.la \ @AIX_TRUE@ ../../libntech/libutils/libutils.la arg_split_test_SOURCES = arg_split_test.c arg_split_test_OBJECTS = arg_split_test.$(OBJEXT) arg_split_test_LDADD = $(LDADD) arg_split_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la assoc_test_SOURCES = assoc_test.c assoc_test_OBJECTS = assoc_test.$(OBJEXT) assoc_test_LDADD = $(LDADD) assoc_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la am__avahi_config_test_SOURCES_DIST = avahi_config_test.c \ ../../cf-serverd/server_common.c ../../cf-serverd/server_tls.c \ ../../cf-serverd/server.c ../../cf-serverd/server_transform.c \ ../../cf-serverd/cf-serverd-enterprise-stubs.c \ ../../cf-serverd/server_access.c \ ../../cf-serverd/server_classic.c ../../cf-serverd/strlist.c @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@am_avahi_config_test_OBJECTS = avahi_config_test.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ server_common.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ server_tls.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ server.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ server_transform.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ cf-serverd-enterprise-stubs.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ server_access.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ server_classic.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ strlist.$(OBJEXT) avahi_config_test_OBJECTS = $(am_avahi_config_test_OBJECTS) @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@avahi_config_test_DEPENDENCIES = ../../libpromises/libpromises.la \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ libtest.la am_cf_upgrade_test_OBJECTS = \ cf_upgrade_test-cf_upgrade_test.$(OBJEXT) \ cf_upgrade_test-alloc-mini.$(OBJEXT) \ cf_upgrade_test-command_line.$(OBJEXT) \ cf_upgrade_test-configuration.$(OBJEXT) \ cf_upgrade_test-log.$(OBJEXT) \ cf_upgrade_test-process.$(OBJEXT) \ cf_upgrade_test-update.$(OBJEXT) cf_upgrade_test_OBJECTS = $(am_cf_upgrade_test_OBJECTS) cf_upgrade_test_DEPENDENCIES = libtest.la \ ../../libntech/libcompat/libcompat.la changes_migration_test_SOURCES = changes_migration_test.c changes_migration_test_OBJECTS = changes_migration_test.$(OBJEXT) changes_migration_test_LDADD = $(LDADD) changes_migration_test_DEPENDENCIES = \ ../../libpromises/libpromises.la libtest.la class_test_SOURCES = class_test.c class_test_OBJECTS = class_test.$(OBJEXT) class_test_LDADD = $(LDADD) class_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la am_connection_management_test_OBJECTS = \ connection_management_test.$(OBJEXT) server_common.$(OBJEXT) \ server_tls.$(OBJEXT) connection_management_test_OBJECTS = \ $(am_connection_management_test_OBJECTS) connection_management_test_DEPENDENCIES = \ ../../libpromises/libpromises.la libtest.la \ ../../cf-serverd/libcf-serverd.la am_conversion_test_OBJECTS = conversion_test.$(OBJEXT) \ conversion.$(OBJEXT) conversion_test_OBJECTS = $(am_conversion_test_OBJECTS) conversion_test_LDADD = $(LDADD) conversion_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la crypto_symmetric_test_SOURCES = crypto_symmetric_test.c crypto_symmetric_test_OBJECTS = crypto_symmetric_test.$(OBJEXT) crypto_symmetric_test_LDADD = $(LDADD) crypto_symmetric_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am_db_concurrent_test_OBJECTS = db_concurrent_test.$(OBJEXT) db_concurrent_test_OBJECTS = $(am_db_concurrent_test_OBJECTS) db_concurrent_test_DEPENDENCIES = libdb.la am_db_test_OBJECTS = db_test.$(OBJEXT) db_test_OBJECTS = $(am_db_test_OBJECTS) db_test_DEPENDENCIES = libtest.la ../../libpromises/libpromises.la domainname_test_SOURCES = domainname_test.c domainname_test_OBJECTS = domainname_test.$(OBJEXT) domainname_test_LDADD = $(LDADD) domainname_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am__enterprise_extension_test_SOURCES_DIST = \ enterprise_extension_test.c @BUILTIN_EXTENSIONS_FALSE@am_enterprise_extension_test_OBJECTS = \ @BUILTIN_EXTENSIONS_FALSE@ enterprise_extension_test.$(OBJEXT) enterprise_extension_test_OBJECTS = \ $(am_enterprise_extension_test_OBJECTS) enterprise_extension_test_LDADD = $(LDADD) enterprise_extension_test_DEPENDENCIES = \ ../../libpromises/libpromises.la libtest.la eval_context_test_SOURCES = eval_context_test.c eval_context_test_OBJECTS = eval_context_test.$(OBJEXT) eval_context_test_LDADD = $(LDADD) eval_context_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la evalfunction_test_SOURCES = evalfunction_test.c evalfunction_test_OBJECTS = evalfunction_test.$(OBJEXT) evalfunction_test_LDADD = $(LDADD) evalfunction_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la evalfunction_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(evalfunction_test_LDFLAGS) $(LDFLAGS) \ -o $@ am_exec_config_test_OBJECTS = exec-config-test.$(OBJEXT) \ exec-config.$(OBJEXT) execd-config.$(OBJEXT) exec_config_test_OBJECTS = $(am_exec_config_test_OBJECTS) exec_config_test_DEPENDENCIES = libtest.la \ ../../libpromises/libpromises.la expand_test_SOURCES = expand_test.c expand_test_OBJECTS = expand_test.$(OBJEXT) expand_test_LDADD = $(LDADD) expand_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la file_name_test_SOURCES = file_name_test.c file_name_test_OBJECTS = file_name_test.$(OBJEXT) file_name_test_LDADD = $(LDADD) file_name_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am_files_copy_test_OBJECTS = files_copy_test.$(OBJEXT) files_copy_test_OBJECTS = $(am_files_copy_test_OBJECTS) files_copy_test_DEPENDENCIES = libtest.la \ ../../libpromises/libpromises.la files_interfaces_test_SOURCES = files_interfaces_test.c files_interfaces_test_OBJECTS = files_interfaces_test.$(OBJEXT) files_interfaces_test_LDADD = $(LDADD) files_interfaces_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la files_lib_test_SOURCES = files_lib_test.c files_lib_test_OBJECTS = files_lib_test.$(OBJEXT) files_lib_test_LDADD = $(LDADD) files_lib_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am__findhub_test_SOURCES_DIST = findhub_test.c \ ../../cf-agent/findhub.c ../../cf-agent/load_avahi.c @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@am_findhub_test_OBJECTS = findhub_test.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ findhub.$(OBJEXT) \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ load_avahi.$(OBJEXT) findhub_test_OBJECTS = $(am_findhub_test_OBJECTS) findhub_test_LDADD = $(LDADD) findhub_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la generic_agent_test_SOURCES = generic_agent_test.c generic_agent_test_OBJECTS = generic_agent_test.$(OBJEXT) generic_agent_test_LDADD = $(LDADD) generic_agent_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la getopt_test_SOURCES = getopt_test.c getopt_test_OBJECTS = getopt_test.$(OBJEXT) getopt_test_LDADD = $(LDADD) getopt_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la granules_test_SOURCES = granules_test.c granules_test_OBJECTS = granules_test.$(OBJEXT) granules_test_LDADD = $(LDADD) granules_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la item_lib_test_SOURCES = item_lib_test.c item_lib_test_OBJECTS = item_lib_test.$(OBJEXT) item_lib_test_LDADD = $(LDADD) item_lib_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la item_test_SOURCES = item_test.c item_test_OBJECTS = item_test.$(OBJEXT) item_test_LDADD = $(LDADD) item_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la am_iteration_test_OBJECTS = iteration_test.$(OBJEXT) iteration_test_OBJECTS = $(am_iteration_test_OBJECTS) iteration_test_LDADD = $(LDADD) iteration_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am_key_test_OBJECTS = key_test.$(OBJEXT) key_test_OBJECTS = $(am_key_test_OBJECTS) key_test_DEPENDENCIES = ../../libpromises/libpromises.la \ ../../libntech/libutils/libutils.la libtest.la am_lastseen_migration_test_OBJECTS = \ lastseen_migration_test.$(OBJEXT) lastseen_migration_test_OBJECTS = \ $(am_lastseen_migration_test_OBJECTS) lastseen_migration_test_DEPENDENCIES = \ ../../libpromises/libpromises.la am_lastseen_test_OBJECTS = lastseen_test.$(OBJEXT) \ statistics.$(OBJEXT) lastseen_test_OBJECTS = $(am_lastseen_test_OBJECTS) lastseen_test_DEPENDENCIES = libtest.la \ ../../libpromises/libpromises.la am__linux_process_test_SOURCES_DIST = linux_process_test.c \ ../../libpromises/process_unix.c \ ../../libpromises/process_linux.c \ ../../libntech/libutils/file_lib.c @LINUX_TRUE@am_linux_process_test_OBJECTS = \ @LINUX_TRUE@ linux_process_test.$(OBJEXT) \ @LINUX_TRUE@ process_unix.$(OBJEXT) process_linux.$(OBJEXT) \ @LINUX_TRUE@ file_lib.$(OBJEXT) linux_process_test_OBJECTS = $(am_linux_process_test_OBJECTS) @LINUX_TRUE@linux_process_test_DEPENDENCIES = libtest.la \ @LINUX_TRUE@ ../../libntech/libutils/libutils.la am_logging_test_OBJECTS = logging_test.$(OBJEXT) \ syslog_client.$(OBJEXT) patches.$(OBJEXT) constants.$(OBJEXT) logging_test_OBJECTS = $(am_logging_test_OBJECTS) logging_test_DEPENDENCIES = libtest.la \ ../../libntech/libutils/libutils.la matching_test_SOURCES = matching_test.c matching_test_OBJECTS = matching_test.$(OBJEXT) matching_test_LDADD = $(LDADD) matching_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am_mon_cpu_test_OBJECTS = mon_cpu_test.$(OBJEXT) mon_cpu.$(OBJEXT) mon_cpu_test_OBJECTS = $(am_mon_cpu_test_OBJECTS) mon_cpu_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am_mon_load_test_OBJECTS = mon_load_test.$(OBJEXT) mon_load.$(OBJEXT) mon_load_test_OBJECTS = $(am_mon_load_test_OBJECTS) mon_load_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am_mon_processes_test_OBJECTS = mon_processes_test.$(OBJEXT) \ mon_processes.$(OBJEXT) mon_processes_test_OBJECTS = $(am_mon_processes_test_OBJECTS) mon_processes_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la mustache_test_SOURCES = mustache_test.c mustache_test_OBJECTS = mustache_test.$(OBJEXT) mustache_test_LDADD = $(LDADD) mustache_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la new_packages_promise_test_SOURCES = new_packages_promise_test.c new_packages_promise_test_OBJECTS = \ new_packages_promise_test.$(OBJEXT) new_packages_promise_test_LDADD = $(LDADD) new_packages_promise_test_DEPENDENCIES = \ ../../libpromises/libpromises.la libtest.la am__nfs_test_SOURCES_DIST = nfs_test.c @NT_FALSE@am_nfs_test_OBJECTS = nfs_test.$(OBJEXT) nfs_test_OBJECTS = $(am_nfs_test_OBJECTS) @NT_FALSE@nfs_test_DEPENDENCIES = ../../libpromises/libpromises.la \ @NT_FALSE@ libtest.la am_package_versions_compare_test_OBJECTS = \ package_versions_compare_test.$(OBJEXT) \ package_module.$(OBJEXT) verify_packages.$(OBJEXT) \ verify_new_packages.$(OBJEXT) vercmp.$(OBJEXT) \ vercmp_internal.$(OBJEXT) retcode.$(OBJEXT) \ match_scope.$(OBJEXT) package_versions_compare_test_OBJECTS = \ $(am_package_versions_compare_test_OBJECTS) package_versions_compare_test_DEPENDENCIES = \ ../../libpromises/libpromises.la libtest.la parsemode_test_SOURCES = parsemode_test.c parsemode_test_OBJECTS = parsemode_test.$(OBJEXT) parsemode_test_LDADD = $(LDADD) parsemode_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la parser_test_SOURCES = parser_test.c parser_test_OBJECTS = parser_test.$(OBJEXT) parser_test_LDADD = $(LDADD) parser_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la passopenfile_test_SOURCES = passopenfile_test.c passopenfile_test_OBJECTS = passopenfile_test.$(OBJEXT) passopenfile_test_LDADD = $(LDADD) passopenfile_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la persistent_lock_test_SOURCES = persistent_lock_test.c persistent_lock_test_OBJECTS = persistent_lock_test.$(OBJEXT) persistent_lock_test_LDADD = $(LDADD) persistent_lock_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la policy_server_test_SOURCES = policy_server_test.c policy_server_test_OBJECTS = policy_server_test.$(OBJEXT) policy_server_test_LDADD = $(LDADD) policy_server_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la policy_test_SOURCES = policy_test.c policy_test_OBJECTS = policy_test.$(OBJEXT) policy_test_LDADD = $(LDADD) policy_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la am_process_terminate_unix_test_OBJECTS = \ process_terminate_unix_test.$(OBJEXT) process_unix.$(OBJEXT) process_terminate_unix_test_OBJECTS = \ $(am_process_terminate_unix_test_OBJECTS) process_terminate_unix_test_DEPENDENCIES = libtest.la \ ../../libntech/libutils/libutils.la process_test_SOURCES = process_test.c process_test_OBJECTS = process_test.$(OBJEXT) process_test_DEPENDENCIES = libtest.la \ ../../libpromises/libpromises.la am_processes_select_test_OBJECTS = processes_select_test.$(OBJEXT) processes_select_test_OBJECTS = $(am_processes_select_test_OBJECTS) processes_select_test_DEPENDENCIES = libtest.la \ ../../libpromises/libpromises.la am_protocol_test_OBJECTS = protocol_test.$(OBJEXT) \ server_common.$(OBJEXT) server_tls.$(OBJEXT) server.$(OBJEXT) \ cf-serverd-enterprise-stubs.$(OBJEXT) \ server_transform.$(OBJEXT) cf-serverd-functions.$(OBJEXT) \ server_access.$(OBJEXT) strlist.$(OBJEXT) protocol_test_OBJECTS = $(am_protocol_test_OBJECTS) protocol_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la redirection_test_SOURCES = redirection_test.c redirection_test_OBJECTS = redirection_test.$(OBJEXT) redirection_test_LDADD = $(LDADD) redirection_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am__redirection_test_stub_SOURCES_DIST = redirection_test_stub.c @NT_FALSE@am_redirection_test_stub_OBJECTS = \ @NT_FALSE@ redirection_test_stub.$(OBJEXT) redirection_test_stub_OBJECTS = $(am_redirection_test_stub_OBJECTS) redirection_test_stub_LDADD = $(LDADD) redirection_test_stub_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la am_regex_test_OBJECTS = regex_test.$(OBJEXT) match_scope.$(OBJEXT) regex_test_OBJECTS = $(am_regex_test_OBJECTS) regex_test_LDADD = $(LDADD) regex_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la am_rlist_test_OBJECTS = rlist_test-rlist_test.$(OBJEXT) rlist_test_OBJECTS = $(am_rlist_test_OBJECTS) rlist_test_DEPENDENCIES = libtest.la ../../libpromises/libpromises.la scope_test_SOURCES = scope_test.c scope_test_OBJECTS = scope_test.$(OBJEXT) scope_test_LDADD = $(LDADD) scope_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la am_set_domainname_test_OBJECTS = set_domainname_test.$(OBJEXT) set_domainname_test_OBJECTS = $(am_set_domainname_test_OBJECTS) set_domainname_test_DEPENDENCIES = libstr.la \ ../../libpromises/libpromises.la set_domainname_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(set_domainname_test_LDFLAGS) \ $(LDFLAGS) -o $@ am__solaris_process_test_SOURCES_DIST = solaris_process_test.c \ ../../libpromises/process_unix.c \ ../../libpromises/process_solaris.c \ ../../libntech/libutils/file_lib.c @SOLARIS_TRUE@am_solaris_process_test_OBJECTS = \ @SOLARIS_TRUE@ solaris_process_test.$(OBJEXT) \ @SOLARIS_TRUE@ process_unix.$(OBJEXT) process_solaris.$(OBJEXT) \ @SOLARIS_TRUE@ file_lib.$(OBJEXT) solaris_process_test_OBJECTS = $(am_solaris_process_test_OBJECTS) @SOLARIS_TRUE@solaris_process_test_DEPENDENCIES = libtest.la \ @SOLARIS_TRUE@ ../../libntech/libutils/libutils.la am_sort_test_OBJECTS = sort_test.$(OBJEXT) sort_test_OBJECTS = $(am_sort_test_OBJECTS) sort_test_DEPENDENCIES = libtest.la ../../libpromises/libpromises.la split_process_line_test_SOURCES = split_process_line_test.c split_process_line_test_OBJECTS = split_process_line_test.$(OBJEXT) split_process_line_test_LDADD = $(LDADD) split_process_line_test_DEPENDENCIES = \ ../../libpromises/libpromises.la libtest.la string_expressions_test_SOURCES = string_expressions_test.c string_expressions_test_OBJECTS = string_expressions_test.$(OBJEXT) string_expressions_test_LDADD = $(LDADD) string_expressions_test_DEPENDENCIES = \ ../../libpromises/libpromises.la libtest.la am_strlist_test_OBJECTS = strlist_test.$(OBJEXT) strlist.$(OBJEXT) strlist_test_OBJECTS = $(am_strlist_test_OBJECTS) strlist_test_LDADD = $(LDADD) strlist_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la syntax_test_SOURCES = syntax_test.c syntax_test_OBJECTS = syntax_test.$(OBJEXT) syntax_test_LDADD = $(LDADD) syntax_test_DEPENDENCIES = ../../libpromises/libpromises.la libtest.la sysinfo_test_SOURCES = sysinfo_test.c sysinfo_test_OBJECTS = sysinfo_test.$(OBJEXT) sysinfo_test_DEPENDENCIES = libtest.la ../../libenv/libenv.la \ ../../libpromises/libpromises.la var_expressions_test_SOURCES = var_expressions_test.c var_expressions_test_OBJECTS = var_expressions_test.$(OBJEXT) var_expressions_test_LDADD = $(LDADD) var_expressions_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la variable_test_SOURCES = variable_test.c variable_test_OBJECTS = variable_test.$(OBJEXT) variable_test_LDADD = $(LDADD) variable_test_DEPENDENCIES = ../../libpromises/libpromises.la \ libtest.la verify_databases_test_SOURCES = verify_databases_test.c verify_databases_test_OBJECTS = verify_databases_test.$(OBJEXT) verify_databases_test_DEPENDENCIES = ../../cf-agent/libcf-agent.la \ libtest.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cfengine_enterprise_la_SOURCES) $(libdb_la_SOURCES) \ $(libstr_la_SOURCES) $(libtest_la_SOURCES) addr_lib_test.c \ $(aix_process_test_SOURCES) arg_split_test.c assoc_test.c \ $(avahi_config_test_SOURCES) $(cf_upgrade_test_SOURCES) \ changes_migration_test.c class_test.c \ $(connection_management_test_SOURCES) \ $(conversion_test_SOURCES) crypto_symmetric_test.c \ $(db_concurrent_test_SOURCES) $(db_test_SOURCES) \ domainname_test.c $(enterprise_extension_test_SOURCES) \ eval_context_test.c evalfunction_test.c \ $(exec_config_test_SOURCES) expand_test.c file_name_test.c \ $(files_copy_test_SOURCES) files_interfaces_test.c \ files_lib_test.c $(findhub_test_SOURCES) generic_agent_test.c \ getopt_test.c granules_test.c item_lib_test.c item_test.c \ $(iteration_test_SOURCES) $(key_test_SOURCES) \ $(lastseen_migration_test_SOURCES) $(lastseen_test_SOURCES) \ $(linux_process_test_SOURCES) $(logging_test_SOURCES) \ matching_test.c $(mon_cpu_test_SOURCES) \ $(mon_load_test_SOURCES) $(mon_processes_test_SOURCES) \ mustache_test.c new_packages_promise_test.c \ $(nfs_test_SOURCES) $(package_versions_compare_test_SOURCES) \ parsemode_test.c parser_test.c passopenfile_test.c \ persistent_lock_test.c policy_server_test.c policy_test.c \ $(process_terminate_unix_test_SOURCES) process_test.c \ $(processes_select_test_SOURCES) $(protocol_test_SOURCES) \ redirection_test.c $(redirection_test_stub_SOURCES) \ $(regex_test_SOURCES) $(rlist_test_SOURCES) scope_test.c \ $(set_domainname_test_SOURCES) $(solaris_process_test_SOURCES) \ $(sort_test_SOURCES) split_process_line_test.c \ string_expressions_test.c $(strlist_test_SOURCES) \ syntax_test.c sysinfo_test.c var_expressions_test.c \ variable_test.c verify_databases_test.c DIST_SOURCES = $(am__cfengine_enterprise_la_SOURCES_DIST) \ $(am__libdb_la_SOURCES_DIST) $(libstr_la_SOURCES) \ $(libtest_la_SOURCES) addr_lib_test.c \ $(am__aix_process_test_SOURCES_DIST) arg_split_test.c \ assoc_test.c $(am__avahi_config_test_SOURCES_DIST) \ $(cf_upgrade_test_SOURCES) changes_migration_test.c \ class_test.c $(connection_management_test_SOURCES) \ $(conversion_test_SOURCES) crypto_symmetric_test.c \ $(db_concurrent_test_SOURCES) $(db_test_SOURCES) \ domainname_test.c \ $(am__enterprise_extension_test_SOURCES_DIST) \ eval_context_test.c evalfunction_test.c \ $(exec_config_test_SOURCES) expand_test.c file_name_test.c \ $(files_copy_test_SOURCES) files_interfaces_test.c \ files_lib_test.c $(am__findhub_test_SOURCES_DIST) \ generic_agent_test.c getopt_test.c granules_test.c \ item_lib_test.c item_test.c $(iteration_test_SOURCES) \ $(key_test_SOURCES) $(lastseen_migration_test_SOURCES) \ $(lastseen_test_SOURCES) \ $(am__linux_process_test_SOURCES_DIST) $(logging_test_SOURCES) \ matching_test.c $(mon_cpu_test_SOURCES) \ $(mon_load_test_SOURCES) $(mon_processes_test_SOURCES) \ mustache_test.c new_packages_promise_test.c \ $(am__nfs_test_SOURCES_DIST) \ $(package_versions_compare_test_SOURCES) parsemode_test.c \ parser_test.c passopenfile_test.c persistent_lock_test.c \ policy_server_test.c policy_test.c \ $(process_terminate_unix_test_SOURCES) process_test.c \ $(processes_select_test_SOURCES) $(protocol_test_SOURCES) \ redirection_test.c $(am__redirection_test_stub_SOURCES_DIST) \ $(regex_test_SOURCES) $(rlist_test_SOURCES) scope_test.c \ $(set_domainname_test_SOURCES) \ $(am__solaris_process_test_SOURCES_DIST) $(sort_test_SOURCES) \ split_process_line_test.c string_expressions_test.c \ $(strlist_test_SOURCES) syntax_test.c sysinfo_test.c \ var_expressions_test.c variable_test.c verify_databases_test.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ # automake does not support "maude_LIBS" variables. We can only alter # the generic LIBS one. In case the functions are mocked in the test # implementation, then we are pretty sure that they will be overriden by # our local implementation. So we include *everything*... LIBS = $(CORE_LIBS) LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Just recursively include in dist tarball all data we need for unit tests EXTRA_DIST = data $(check_SCRIPTS) init_script_test_helper.c \ init_script_test.sh AM_CPPFLAGS = $(CORE_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) \ -I$(srcdir)/../../libcfecompat \ -I$(srcdir)/../../libcfnet \ -I$(srcdir)/../../libenv \ -I$(srcdir)/../../libpromises \ -I$(srcdir)/../../libntech/libutils \ -I$(srcdir)/../../cf-monitord \ -I$(srcdir)/../../cf-serverd \ -I$(srcdir)/../../cf-agent \ -I$(srcdir)/../../cf-execd \ -I$(srcdir)/../../cf-key \ -I$(srcdir)/../../cf-check \ -DTESTDATADIR='"$(srcdir)/data"' LDADD = ../../libpromises/libpromises.la libtest.la AM_LDFLAGS = $(CORE_LDFLAGS) AM_CFLAGS = $(PTHREAD_CFLAGS) check_LTLIBRARIES = libtest.la libstr.la libdb.la $(am__append_6) libtest_la_SOURCES = cmockery.c cmockery.h schema.h test.c test.h libtest_la_LIBADD = ../../libntech/libcompat/libcompat.la libstr_la_SOURCES = \ ../../libntech/libutils/buffer.c \ ../../libntech/libutils/encode.c \ ../../libntech/libutils/logging.c \ ../../libntech/libutils/misc_lib.c \ ../../libntech/libutils/regex.c \ ../../libntech/libutils/sequence.c \ ../../libntech/libutils/string_lib.c \ ../../libntech/libutils/writer.c libstr_la_LIBADD = libtest.la libdb_la_SOURCES = db_stubs.c ../../libpromises/dbm_api.c \ ../../libpromises/dbm_quick.c ../../libpromises/dbm_tokyocab.c \ ../../libpromises/dbm_lmdb.c ../../libpromises/dbm_migration.c \ ../../libpromises/dbm_migration_lastseen.c \ ../../libpromises/global_mutex.c ../../cf-check/backup.c \ ../../cf-check/diagnose.c ../../cf-check/lmdump.c \ ../../cf-check/repair.c ../../cf-check/replicate_lmdb.c \ ../../cf-check/utilities.c ../../cf-check/validate.c \ ../../libntech/libutils/logging.c \ ../../libntech/libutils/mutex.c \ ../../libntech/libutils/cleanup.c $(am__append_1) libdb_la_LIBADD = libstr.la ../../libntech/libutils/libutils.la #libdb_la_CPPFLAGS = $(LMDB_CPPFLAGS) $(TOKYOCABINET_CPPFLAGS) $(QDBM_CPPFLAGS) # Make sure that source files are compiled to separate object files # libdb_la-file.o libdb_la_CFLAGS = $(AM_CFLAGS) @NT_FALSE@redirection_test_stub_SOURCES = redirection_test_stub.c check_SCRIPTS = dynamic_dependency_test.sh tar_portability_test.sh \ $(am__append_4) TESTS = $(check_PROGRAMS) $(check_SCRIPTS) processes_select_test_SOURCES = processes_select_test.c processes_select_test_LDADD = libtest.la ../../libpromises/libpromises.la # # OS X uses real system calls instead of our stubs unless this option is used # TESTS_ENVIRONMENT = DYLD_FORCE_FLAT_NAMESPACE=yes conversion_test_SOURCES = conversion_test.c ../../libpromises/conversion.c @BUILTIN_EXTENSIONS_FALSE@enterprise_extension_test_SOURCES = enterprise_extension_test.c @BUILTIN_EXTENSIONS_FALSE@cfengine_enterprise_la_SOURCES = enterprise_extension_test_lib.c @BUILTIN_EXTENSIONS_FALSE@cfengine_enterprise_la_LDFLAGS = $(AM_LDFLAGS) \ @BUILTIN_EXTENSIONS_FALSE@ -avoid-version -module -shared -export-dynamic -rpath / @BUILTIN_EXTENSIONS_FALSE@EXTRA_enterprise_extension_test_DEPENDENCIES = cfengine-enterprise.la set_domainname_test_SOURCES = set_domainname_test.c set_domainname_test_LDADD = libstr.la ../../libpromises/libpromises.la str_test_SOURCES = str_test.c str_test_LDADD = libstr.la regex_test_SOURCES = regex_test.c ../../libpromises/match_scope.c protocol_test_SOURCES = protocol_test.c \ ../../cf-serverd/server_common.c \ ../../cf-serverd/server_tls.c \ ../../cf-serverd/server.c \ ../../cf-serverd/cf-serverd-enterprise-stubs.c \ ../../cf-serverd/server_transform.c \ ../../cf-serverd/cf-serverd-functions.c \ ../../cf-serverd/server_access.c \ ../../cf-serverd/strlist.c protocol_test_LDADD = ../../libpromises/libpromises.la libtest.la @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@findhub_test_SOURCES = findhub_test.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-agent/findhub.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-agent/load_avahi.c @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@avahi_config_test_SOURCES = avahi_config_test.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/server_common.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/server_tls.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/server.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/server_transform.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/cf-serverd-enterprise-stubs.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/server_access.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/server_classic.c \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ ../../cf-serverd/strlist.c @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@avahi_config_test_LDADD = ../../libpromises/libpromises.la libtest.la db_test_SOURCES = db_test.c db_test_LDADD = libtest.la ../../libpromises/libpromises.la db_concurrent_test_SOURCES = db_concurrent_test.c #db_concurrent_test_CPPFLAGS = $(libdb_la_CPPFLAGS) db_concurrent_test_LDADD = libdb.la lastseen_test_SOURCES = lastseen_test.c \ ../../libntech/libutils/statistics.c #lastseen_test_CPPFLAGS = $(libdb_la_CPPFLAGS) lastseen_test_LDADD = libtest.la ../../libpromises/libpromises.la lastseen_migration_test_SOURCES = lastseen_migration_test.c #lastseen_migration_test_CPPFLAGS = $(libdb_la_CPPFLAGS) lastseen_migration_test_LDADD = ../../libpromises/libpromises.la CLEANFILES = *.gcno *.gcda cfengine-enterprise.so $(am__append_11) package_versions_compare_test_SOURCES = package_versions_compare_test.c \ ../../cf-agent/package_module.c \ ../../cf-agent/verify_packages.c \ ../../cf-agent/verify_new_packages.c \ ../../cf-agent/vercmp.c \ ../../cf-agent/vercmp_internal.c \ ../../cf-agent/retcode.c \ ../../libpromises/match_scope.c #package_versions_compare_test_CPPFLAGS = $(AM_CPPFLAGS) package_versions_compare_test_LDADD = ../../libpromises/libpromises.la \ libtest.la files_copy_test_SOURCES = files_copy_test.c files_copy_test_LDADD = libtest.la ../../libpromises/libpromises.la sort_test_SOURCES = sort_test.c sort_test_LDADD = libtest.la ../../libpromises/libpromises.la logging_test_SOURCES = logging_test.c \ ../../libpromises/syslog_client.c \ ../../libpromises/patches.c \ ../../libpromises/constants.c logging_test_LDADD = libtest.la ../../libntech/libutils/libutils.la connection_management_test_SOURCES = connection_management_test.c \ ../../cf-serverd/server_common.c \ ../../cf-serverd/server_tls.c connection_management_test_LDADD = ../../libpromises/libpromises.la \ libtest.la \ ../../cf-serverd/libcf-serverd.la rlist_test_SOURCES = rlist_test.c rlist_test_LDADD = libtest.la ../../libpromises/libpromises.la # Workaround for object file basename conflicts, search the web for # "automake created with both libtool and without" rlist_test_CPPFLAGS = $(AM_CPPFLAGS) process_test_LDADD = libtest.la ../../libpromises/libpromises.la @LINUX_TRUE@linux_process_test_SOURCES = linux_process_test.c \ @LINUX_TRUE@ ../../libpromises/process_unix.c \ @LINUX_TRUE@ ../../libpromises/process_linux.c \ @LINUX_TRUE@ ../../libntech/libutils/file_lib.c @LINUX_TRUE@linux_process_test_LDADD = libtest.la ../../libntech/libutils/libutils.la # We need to use -Wl,-bexpall when linking tests binaries on AIX # because they provide dummy versions of some standard functions. @AIX_TRUE@set_domainname_test_LDFLAGS = -Wl,-bexpall @AIX_TRUE@evalfunction_test_LDFLAGS = -Wl,-bexpall @AIX_TRUE@aix_process_test_SOURCES = aix_process_test.c \ @AIX_TRUE@ ../../libpromises/process_unix.c \ @AIX_TRUE@ ../../libpromises/process_aix.c \ @AIX_TRUE@ ../../libntech/libutils/file_lib.c @AIX_TRUE@aix_process_test_LDADD = libtest.la ../../libntech/libutils/libutils.la @SOLARIS_TRUE@solaris_process_test_SOURCES = solaris_process_test.c \ @SOLARIS_TRUE@ ../../libpromises/process_unix.c \ @SOLARIS_TRUE@ ../../libpromises/process_solaris.c \ @SOLARIS_TRUE@ ../../libntech/libutils/file_lib.c @SOLARIS_TRUE@solaris_process_test_LDADD = libtest.la ../../libntech/libutils/libutils.la process_terminate_unix_test_SOURCES = process_terminate_unix_test.c \ ../../libpromises/process_unix.c process_terminate_unix_test_LDADD = libtest.la ../../libntech/libutils/libutils.la exec_config_test_SOURCES = exec-config-test.c \ ../../cf-execd/exec-config.c ../../cf-execd/execd-config.c exec_config_test_LDADD = libtest.la ../../libpromises/libpromises.la sysinfo_test_LDADD = libtest.la \ ../../libenv/libenv.la \ ../../libpromises/libpromises.la mon_cpu_test_SOURCES = mon_cpu_test.c \ ../../cf-monitord/mon.h \ ../../cf-monitord/mon_cpu.c mon_cpu_test_LDADD = ../../libpromises/libpromises.la libtest.la mon_load_test_SOURCES = mon_load_test.c \ ../../cf-monitord/mon.h \ ../../cf-monitord/mon_load.c mon_load_test_LDADD = ../../libpromises/libpromises.la libtest.la mon_processes_test_SOURCES = mon_processes_test.c \ ../../cf-monitord/mon.h \ ../../cf-monitord/mon_processes.c mon_processes_test_LDADD = ../../libpromises/libpromises.la libtest.la key_test_SOURCES = key_test.c key_test_LDADD = ../../libpromises/libpromises.la \ ../../libntech/libutils/libutils.la \ libtest.la strlist_test_SOURCES = strlist_test.c \ ../../cf-serverd/strlist.c \ ../../cf-serverd/strlist.h verify_databases_test_LDADD = ../../cf-agent/libcf-agent.la libtest.la iteration_test_SOURCES = iteration_test.c cf_upgrade_test_SOURCES = cf_upgrade_test.c \ $(top_srcdir)/cf-upgrade/alloc-mini.c \ $(top_srcdir)/cf-upgrade/alloc-mini.h \ $(top_srcdir)/cf-upgrade/command_line.c \ $(top_srcdir)/cf-upgrade/command_line.h \ $(top_srcdir)/cf-upgrade/configuration.c \ $(top_srcdir)/cf-upgrade/configuration.h \ $(top_srcdir)/cf-upgrade/log.c $(top_srcdir)/cf-upgrade/log.h \ $(top_srcdir)/cf-upgrade/process.c $(top_srcdir)/cf-upgrade/process.h \ $(top_srcdir)/cf-upgrade/update.c \ $(top_srcdir)/cf-upgrade/update.h cf_upgrade_test_CPPFLAGS = -I$(top_srcdir)/cf-upgrade -I$(top_srcdir)/libntech/libutils -I$(top_srcdir) cf_upgrade_test_LDADD = libtest.la ../../libntech/libcompat/libcompat.la @NT_FALSE@nfs_test_SOURCES = nfs_test.c @NT_FALSE@nfs_test_LDADD = ../../libpromises/libpromises.la libtest.la @NT_FALSE@init_script_test_helper_SOURCES = init_script_test_helper.c all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/unit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/unit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } cfengine-enterprise.la: $(cfengine_enterprise_la_OBJECTS) $(cfengine_enterprise_la_DEPENDENCIES) $(EXTRA_cfengine_enterprise_la_DEPENDENCIES) $(AM_V_CCLD)$(cfengine_enterprise_la_LINK) $(am_cfengine_enterprise_la_rpath) $(cfengine_enterprise_la_OBJECTS) $(cfengine_enterprise_la_LIBADD) $(LIBS) libdb.la: $(libdb_la_OBJECTS) $(libdb_la_DEPENDENCIES) $(EXTRA_libdb_la_DEPENDENCIES) $(AM_V_CCLD)$(libdb_la_LINK) $(libdb_la_OBJECTS) $(libdb_la_LIBADD) $(LIBS) libstr.la: $(libstr_la_OBJECTS) $(libstr_la_DEPENDENCIES) $(EXTRA_libstr_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libstr_la_OBJECTS) $(libstr_la_LIBADD) $(LIBS) libtest.la: $(libtest_la_OBJECTS) $(libtest_la_DEPENDENCIES) $(EXTRA_libtest_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libtest_la_OBJECTS) $(libtest_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list addr_lib_test$(EXEEXT): $(addr_lib_test_OBJECTS) $(addr_lib_test_DEPENDENCIES) $(EXTRA_addr_lib_test_DEPENDENCIES) @rm -f addr_lib_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(addr_lib_test_OBJECTS) $(addr_lib_test_LDADD) $(LIBS) aix_process_test$(EXEEXT): $(aix_process_test_OBJECTS) $(aix_process_test_DEPENDENCIES) $(EXTRA_aix_process_test_DEPENDENCIES) @rm -f aix_process_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(aix_process_test_OBJECTS) $(aix_process_test_LDADD) $(LIBS) arg_split_test$(EXEEXT): $(arg_split_test_OBJECTS) $(arg_split_test_DEPENDENCIES) $(EXTRA_arg_split_test_DEPENDENCIES) @rm -f arg_split_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(arg_split_test_OBJECTS) $(arg_split_test_LDADD) $(LIBS) assoc_test$(EXEEXT): $(assoc_test_OBJECTS) $(assoc_test_DEPENDENCIES) $(EXTRA_assoc_test_DEPENDENCIES) @rm -f assoc_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(assoc_test_OBJECTS) $(assoc_test_LDADD) $(LIBS) avahi_config_test$(EXEEXT): $(avahi_config_test_OBJECTS) $(avahi_config_test_DEPENDENCIES) $(EXTRA_avahi_config_test_DEPENDENCIES) @rm -f avahi_config_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(avahi_config_test_OBJECTS) $(avahi_config_test_LDADD) $(LIBS) cf_upgrade_test$(EXEEXT): $(cf_upgrade_test_OBJECTS) $(cf_upgrade_test_DEPENDENCIES) $(EXTRA_cf_upgrade_test_DEPENDENCIES) @rm -f cf_upgrade_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_upgrade_test_OBJECTS) $(cf_upgrade_test_LDADD) $(LIBS) changes_migration_test$(EXEEXT): $(changes_migration_test_OBJECTS) $(changes_migration_test_DEPENDENCIES) $(EXTRA_changes_migration_test_DEPENDENCIES) @rm -f changes_migration_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(changes_migration_test_OBJECTS) $(changes_migration_test_LDADD) $(LIBS) class_test$(EXEEXT): $(class_test_OBJECTS) $(class_test_DEPENDENCIES) $(EXTRA_class_test_DEPENDENCIES) @rm -f class_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(class_test_OBJECTS) $(class_test_LDADD) $(LIBS) connection_management_test$(EXEEXT): $(connection_management_test_OBJECTS) $(connection_management_test_DEPENDENCIES) $(EXTRA_connection_management_test_DEPENDENCIES) @rm -f connection_management_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(connection_management_test_OBJECTS) $(connection_management_test_LDADD) $(LIBS) conversion_test$(EXEEXT): $(conversion_test_OBJECTS) $(conversion_test_DEPENDENCIES) $(EXTRA_conversion_test_DEPENDENCIES) @rm -f conversion_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(conversion_test_OBJECTS) $(conversion_test_LDADD) $(LIBS) crypto_symmetric_test$(EXEEXT): $(crypto_symmetric_test_OBJECTS) $(crypto_symmetric_test_DEPENDENCIES) $(EXTRA_crypto_symmetric_test_DEPENDENCIES) @rm -f crypto_symmetric_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(crypto_symmetric_test_OBJECTS) $(crypto_symmetric_test_LDADD) $(LIBS) db_concurrent_test$(EXEEXT): $(db_concurrent_test_OBJECTS) $(db_concurrent_test_DEPENDENCIES) $(EXTRA_db_concurrent_test_DEPENDENCIES) @rm -f db_concurrent_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(db_concurrent_test_OBJECTS) $(db_concurrent_test_LDADD) $(LIBS) db_test$(EXEEXT): $(db_test_OBJECTS) $(db_test_DEPENDENCIES) $(EXTRA_db_test_DEPENDENCIES) @rm -f db_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(db_test_OBJECTS) $(db_test_LDADD) $(LIBS) domainname_test$(EXEEXT): $(domainname_test_OBJECTS) $(domainname_test_DEPENDENCIES) $(EXTRA_domainname_test_DEPENDENCIES) @rm -f domainname_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(domainname_test_OBJECTS) $(domainname_test_LDADD) $(LIBS) enterprise_extension_test$(EXEEXT): $(enterprise_extension_test_OBJECTS) $(enterprise_extension_test_DEPENDENCIES) $(EXTRA_enterprise_extension_test_DEPENDENCIES) @rm -f enterprise_extension_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(enterprise_extension_test_OBJECTS) $(enterprise_extension_test_LDADD) $(LIBS) eval_context_test$(EXEEXT): $(eval_context_test_OBJECTS) $(eval_context_test_DEPENDENCIES) $(EXTRA_eval_context_test_DEPENDENCIES) @rm -f eval_context_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(eval_context_test_OBJECTS) $(eval_context_test_LDADD) $(LIBS) evalfunction_test$(EXEEXT): $(evalfunction_test_OBJECTS) $(evalfunction_test_DEPENDENCIES) $(EXTRA_evalfunction_test_DEPENDENCIES) @rm -f evalfunction_test$(EXEEXT) $(AM_V_CCLD)$(evalfunction_test_LINK) $(evalfunction_test_OBJECTS) $(evalfunction_test_LDADD) $(LIBS) exec-config-test$(EXEEXT): $(exec_config_test_OBJECTS) $(exec_config_test_DEPENDENCIES) $(EXTRA_exec_config_test_DEPENDENCIES) @rm -f exec-config-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(exec_config_test_OBJECTS) $(exec_config_test_LDADD) $(LIBS) expand_test$(EXEEXT): $(expand_test_OBJECTS) $(expand_test_DEPENDENCIES) $(EXTRA_expand_test_DEPENDENCIES) @rm -f expand_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(expand_test_OBJECTS) $(expand_test_LDADD) $(LIBS) file_name_test$(EXEEXT): $(file_name_test_OBJECTS) $(file_name_test_DEPENDENCIES) $(EXTRA_file_name_test_DEPENDENCIES) @rm -f file_name_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(file_name_test_OBJECTS) $(file_name_test_LDADD) $(LIBS) files_copy_test$(EXEEXT): $(files_copy_test_OBJECTS) $(files_copy_test_DEPENDENCIES) $(EXTRA_files_copy_test_DEPENDENCIES) @rm -f files_copy_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(files_copy_test_OBJECTS) $(files_copy_test_LDADD) $(LIBS) files_interfaces_test$(EXEEXT): $(files_interfaces_test_OBJECTS) $(files_interfaces_test_DEPENDENCIES) $(EXTRA_files_interfaces_test_DEPENDENCIES) @rm -f files_interfaces_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(files_interfaces_test_OBJECTS) $(files_interfaces_test_LDADD) $(LIBS) files_lib_test$(EXEEXT): $(files_lib_test_OBJECTS) $(files_lib_test_DEPENDENCIES) $(EXTRA_files_lib_test_DEPENDENCIES) @rm -f files_lib_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(files_lib_test_OBJECTS) $(files_lib_test_LDADD) $(LIBS) findhub_test$(EXEEXT): $(findhub_test_OBJECTS) $(findhub_test_DEPENDENCIES) $(EXTRA_findhub_test_DEPENDENCIES) @rm -f findhub_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(findhub_test_OBJECTS) $(findhub_test_LDADD) $(LIBS) generic_agent_test$(EXEEXT): $(generic_agent_test_OBJECTS) $(generic_agent_test_DEPENDENCIES) $(EXTRA_generic_agent_test_DEPENDENCIES) @rm -f generic_agent_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(generic_agent_test_OBJECTS) $(generic_agent_test_LDADD) $(LIBS) getopt_test$(EXEEXT): $(getopt_test_OBJECTS) $(getopt_test_DEPENDENCIES) $(EXTRA_getopt_test_DEPENDENCIES) @rm -f getopt_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(getopt_test_OBJECTS) $(getopt_test_LDADD) $(LIBS) granules_test$(EXEEXT): $(granules_test_OBJECTS) $(granules_test_DEPENDENCIES) $(EXTRA_granules_test_DEPENDENCIES) @rm -f granules_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(granules_test_OBJECTS) $(granules_test_LDADD) $(LIBS) item_lib_test$(EXEEXT): $(item_lib_test_OBJECTS) $(item_lib_test_DEPENDENCIES) $(EXTRA_item_lib_test_DEPENDENCIES) @rm -f item_lib_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(item_lib_test_OBJECTS) $(item_lib_test_LDADD) $(LIBS) item_test$(EXEEXT): $(item_test_OBJECTS) $(item_test_DEPENDENCIES) $(EXTRA_item_test_DEPENDENCIES) @rm -f item_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(item_test_OBJECTS) $(item_test_LDADD) $(LIBS) iteration_test$(EXEEXT): $(iteration_test_OBJECTS) $(iteration_test_DEPENDENCIES) $(EXTRA_iteration_test_DEPENDENCIES) @rm -f iteration_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(iteration_test_OBJECTS) $(iteration_test_LDADD) $(LIBS) key_test$(EXEEXT): $(key_test_OBJECTS) $(key_test_DEPENDENCIES) $(EXTRA_key_test_DEPENDENCIES) @rm -f key_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(key_test_OBJECTS) $(key_test_LDADD) $(LIBS) lastseen_migration_test$(EXEEXT): $(lastseen_migration_test_OBJECTS) $(lastseen_migration_test_DEPENDENCIES) $(EXTRA_lastseen_migration_test_DEPENDENCIES) @rm -f lastseen_migration_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(lastseen_migration_test_OBJECTS) $(lastseen_migration_test_LDADD) $(LIBS) lastseen_test$(EXEEXT): $(lastseen_test_OBJECTS) $(lastseen_test_DEPENDENCIES) $(EXTRA_lastseen_test_DEPENDENCIES) @rm -f lastseen_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(lastseen_test_OBJECTS) $(lastseen_test_LDADD) $(LIBS) linux_process_test$(EXEEXT): $(linux_process_test_OBJECTS) $(linux_process_test_DEPENDENCIES) $(EXTRA_linux_process_test_DEPENDENCIES) @rm -f linux_process_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(linux_process_test_OBJECTS) $(linux_process_test_LDADD) $(LIBS) logging_test$(EXEEXT): $(logging_test_OBJECTS) $(logging_test_DEPENDENCIES) $(EXTRA_logging_test_DEPENDENCIES) @rm -f logging_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(logging_test_OBJECTS) $(logging_test_LDADD) $(LIBS) matching_test$(EXEEXT): $(matching_test_OBJECTS) $(matching_test_DEPENDENCIES) $(EXTRA_matching_test_DEPENDENCIES) @rm -f matching_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(matching_test_OBJECTS) $(matching_test_LDADD) $(LIBS) mon_cpu_test$(EXEEXT): $(mon_cpu_test_OBJECTS) $(mon_cpu_test_DEPENDENCIES) $(EXTRA_mon_cpu_test_DEPENDENCIES) @rm -f mon_cpu_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(mon_cpu_test_OBJECTS) $(mon_cpu_test_LDADD) $(LIBS) mon_load_test$(EXEEXT): $(mon_load_test_OBJECTS) $(mon_load_test_DEPENDENCIES) $(EXTRA_mon_load_test_DEPENDENCIES) @rm -f mon_load_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(mon_load_test_OBJECTS) $(mon_load_test_LDADD) $(LIBS) mon_processes_test$(EXEEXT): $(mon_processes_test_OBJECTS) $(mon_processes_test_DEPENDENCIES) $(EXTRA_mon_processes_test_DEPENDENCIES) @rm -f mon_processes_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(mon_processes_test_OBJECTS) $(mon_processes_test_LDADD) $(LIBS) mustache_test$(EXEEXT): $(mustache_test_OBJECTS) $(mustache_test_DEPENDENCIES) $(EXTRA_mustache_test_DEPENDENCIES) @rm -f mustache_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(mustache_test_OBJECTS) $(mustache_test_LDADD) $(LIBS) new_packages_promise_test$(EXEEXT): $(new_packages_promise_test_OBJECTS) $(new_packages_promise_test_DEPENDENCIES) $(EXTRA_new_packages_promise_test_DEPENDENCIES) @rm -f new_packages_promise_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(new_packages_promise_test_OBJECTS) $(new_packages_promise_test_LDADD) $(LIBS) nfs_test$(EXEEXT): $(nfs_test_OBJECTS) $(nfs_test_DEPENDENCIES) $(EXTRA_nfs_test_DEPENDENCIES) @rm -f nfs_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(nfs_test_OBJECTS) $(nfs_test_LDADD) $(LIBS) package_versions_compare_test$(EXEEXT): $(package_versions_compare_test_OBJECTS) $(package_versions_compare_test_DEPENDENCIES) $(EXTRA_package_versions_compare_test_DEPENDENCIES) @rm -f package_versions_compare_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(package_versions_compare_test_OBJECTS) $(package_versions_compare_test_LDADD) $(LIBS) parsemode_test$(EXEEXT): $(parsemode_test_OBJECTS) $(parsemode_test_DEPENDENCIES) $(EXTRA_parsemode_test_DEPENDENCIES) @rm -f parsemode_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(parsemode_test_OBJECTS) $(parsemode_test_LDADD) $(LIBS) parser_test$(EXEEXT): $(parser_test_OBJECTS) $(parser_test_DEPENDENCIES) $(EXTRA_parser_test_DEPENDENCIES) @rm -f parser_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(parser_test_OBJECTS) $(parser_test_LDADD) $(LIBS) passopenfile_test$(EXEEXT): $(passopenfile_test_OBJECTS) $(passopenfile_test_DEPENDENCIES) $(EXTRA_passopenfile_test_DEPENDENCIES) @rm -f passopenfile_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(passopenfile_test_OBJECTS) $(passopenfile_test_LDADD) $(LIBS) persistent_lock_test$(EXEEXT): $(persistent_lock_test_OBJECTS) $(persistent_lock_test_DEPENDENCIES) $(EXTRA_persistent_lock_test_DEPENDENCIES) @rm -f persistent_lock_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(persistent_lock_test_OBJECTS) $(persistent_lock_test_LDADD) $(LIBS) policy_server_test$(EXEEXT): $(policy_server_test_OBJECTS) $(policy_server_test_DEPENDENCIES) $(EXTRA_policy_server_test_DEPENDENCIES) @rm -f policy_server_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(policy_server_test_OBJECTS) $(policy_server_test_LDADD) $(LIBS) policy_test$(EXEEXT): $(policy_test_OBJECTS) $(policy_test_DEPENDENCIES) $(EXTRA_policy_test_DEPENDENCIES) @rm -f policy_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(policy_test_OBJECTS) $(policy_test_LDADD) $(LIBS) process_terminate_unix_test$(EXEEXT): $(process_terminate_unix_test_OBJECTS) $(process_terminate_unix_test_DEPENDENCIES) $(EXTRA_process_terminate_unix_test_DEPENDENCIES) @rm -f process_terminate_unix_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(process_terminate_unix_test_OBJECTS) $(process_terminate_unix_test_LDADD) $(LIBS) process_test$(EXEEXT): $(process_test_OBJECTS) $(process_test_DEPENDENCIES) $(EXTRA_process_test_DEPENDENCIES) @rm -f process_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(process_test_OBJECTS) $(process_test_LDADD) $(LIBS) processes_select_test$(EXEEXT): $(processes_select_test_OBJECTS) $(processes_select_test_DEPENDENCIES) $(EXTRA_processes_select_test_DEPENDENCIES) @rm -f processes_select_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(processes_select_test_OBJECTS) $(processes_select_test_LDADD) $(LIBS) protocol_test$(EXEEXT): $(protocol_test_OBJECTS) $(protocol_test_DEPENDENCIES) $(EXTRA_protocol_test_DEPENDENCIES) @rm -f protocol_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(protocol_test_OBJECTS) $(protocol_test_LDADD) $(LIBS) redirection_test$(EXEEXT): $(redirection_test_OBJECTS) $(redirection_test_DEPENDENCIES) $(EXTRA_redirection_test_DEPENDENCIES) @rm -f redirection_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(redirection_test_OBJECTS) $(redirection_test_LDADD) $(LIBS) redirection_test_stub$(EXEEXT): $(redirection_test_stub_OBJECTS) $(redirection_test_stub_DEPENDENCIES) $(EXTRA_redirection_test_stub_DEPENDENCIES) @rm -f redirection_test_stub$(EXEEXT) $(AM_V_CCLD)$(LINK) $(redirection_test_stub_OBJECTS) $(redirection_test_stub_LDADD) $(LIBS) regex_test$(EXEEXT): $(regex_test_OBJECTS) $(regex_test_DEPENDENCIES) $(EXTRA_regex_test_DEPENDENCIES) @rm -f regex_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(regex_test_OBJECTS) $(regex_test_LDADD) $(LIBS) rlist_test$(EXEEXT): $(rlist_test_OBJECTS) $(rlist_test_DEPENDENCIES) $(EXTRA_rlist_test_DEPENDENCIES) @rm -f rlist_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rlist_test_OBJECTS) $(rlist_test_LDADD) $(LIBS) scope_test$(EXEEXT): $(scope_test_OBJECTS) $(scope_test_DEPENDENCIES) $(EXTRA_scope_test_DEPENDENCIES) @rm -f scope_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(scope_test_OBJECTS) $(scope_test_LDADD) $(LIBS) set_domainname_test$(EXEEXT): $(set_domainname_test_OBJECTS) $(set_domainname_test_DEPENDENCIES) $(EXTRA_set_domainname_test_DEPENDENCIES) @rm -f set_domainname_test$(EXEEXT) $(AM_V_CCLD)$(set_domainname_test_LINK) $(set_domainname_test_OBJECTS) $(set_domainname_test_LDADD) $(LIBS) solaris_process_test$(EXEEXT): $(solaris_process_test_OBJECTS) $(solaris_process_test_DEPENDENCIES) $(EXTRA_solaris_process_test_DEPENDENCIES) @rm -f solaris_process_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(solaris_process_test_OBJECTS) $(solaris_process_test_LDADD) $(LIBS) sort_test$(EXEEXT): $(sort_test_OBJECTS) $(sort_test_DEPENDENCIES) $(EXTRA_sort_test_DEPENDENCIES) @rm -f sort_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sort_test_OBJECTS) $(sort_test_LDADD) $(LIBS) split_process_line_test$(EXEEXT): $(split_process_line_test_OBJECTS) $(split_process_line_test_DEPENDENCIES) $(EXTRA_split_process_line_test_DEPENDENCIES) @rm -f split_process_line_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(split_process_line_test_OBJECTS) $(split_process_line_test_LDADD) $(LIBS) string_expressions_test$(EXEEXT): $(string_expressions_test_OBJECTS) $(string_expressions_test_DEPENDENCIES) $(EXTRA_string_expressions_test_DEPENDENCIES) @rm -f string_expressions_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(string_expressions_test_OBJECTS) $(string_expressions_test_LDADD) $(LIBS) strlist_test$(EXEEXT): $(strlist_test_OBJECTS) $(strlist_test_DEPENDENCIES) $(EXTRA_strlist_test_DEPENDENCIES) @rm -f strlist_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(strlist_test_OBJECTS) $(strlist_test_LDADD) $(LIBS) syntax_test$(EXEEXT): $(syntax_test_OBJECTS) $(syntax_test_DEPENDENCIES) $(EXTRA_syntax_test_DEPENDENCIES) @rm -f syntax_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(syntax_test_OBJECTS) $(syntax_test_LDADD) $(LIBS) sysinfo_test$(EXEEXT): $(sysinfo_test_OBJECTS) $(sysinfo_test_DEPENDENCIES) $(EXTRA_sysinfo_test_DEPENDENCIES) @rm -f sysinfo_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sysinfo_test_OBJECTS) $(sysinfo_test_LDADD) $(LIBS) var_expressions_test$(EXEEXT): $(var_expressions_test_OBJECTS) $(var_expressions_test_DEPENDENCIES) $(EXTRA_var_expressions_test_DEPENDENCIES) @rm -f var_expressions_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(var_expressions_test_OBJECTS) $(var_expressions_test_LDADD) $(LIBS) variable_test$(EXEEXT): $(variable_test_OBJECTS) $(variable_test_DEPENDENCIES) $(EXTRA_variable_test_DEPENDENCIES) @rm -f variable_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(variable_test_OBJECTS) $(variable_test_LDADD) $(LIBS) verify_databases_test$(EXEEXT): $(verify_databases_test_OBJECTS) $(verify_databases_test_DEPENDENCIES) $(EXTRA_verify_databases_test_DEPENDENCIES) @rm -f verify_databases_test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(verify_databases_test_OBJECTS) $(verify_databases_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addr_lib_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aix_process_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arg_split_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assoc_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/avahi_config_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-serverd-enterprise-stubs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-serverd-functions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_upgrade_test-alloc-mini.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_upgrade_test-cf_upgrade_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_upgrade_test-command_line.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_upgrade_test-configuration.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_upgrade_test-log.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_upgrade_test-process.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_upgrade_test-update.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changes_migration_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/class_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmockery.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection_management_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constants.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conversion.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conversion_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_symmetric_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db_concurrent_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/domainname_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enterprise_extension_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enterprise_extension_test_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_context_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evalfunction_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exec-config-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exec-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execd-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expand_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_name_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_copy_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_interfaces_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_lib_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findhub.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findhub_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generic_agent_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/granules_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/item_lib_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/item_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iteration_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lastseen_migration_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lastseen_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-backup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-cf3globals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-cleanup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-db_stubs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-dbm_api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-dbm_lmdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-dbm_migration.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-dbm_migration_lastseen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-dbm_quick.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-dbm_tokyocab.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-diagnose.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-global_mutex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-lmdump.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-logging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-mutex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-repair.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-replicate_lmdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-utilities.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdb_la-validate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux_process_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_avahi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/match_scope.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matching_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_cpu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_cpu_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_load.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_load_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_processes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mon_processes_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mustache_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/new_packages_promise_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfs_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/package_module.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/package_versions_compare_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parsemode_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passopenfile_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patches.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/persistent_lock_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy_server_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_aix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_linux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_solaris.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_terminate_unix_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_unix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processes_select_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redirection_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redirection_test_stub.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/retcode.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rlist_test-rlist_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scope_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sequence.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_access.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_classic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_tls.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_transform.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_domainname_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/solaris_process_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sort_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/split_process_line_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statistics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_expressions_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlist_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syntax_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysinfo_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syslog_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/var_expressions_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/variable_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vercmp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vercmp_internal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_databases_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_new_packages.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_packages.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writer.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libdb_la-db_stubs.lo: db_stubs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-db_stubs.lo -MD -MP -MF $(DEPDIR)/libdb_la-db_stubs.Tpo -c -o libdb_la-db_stubs.lo `test -f 'db_stubs.c' || echo '$(srcdir)/'`db_stubs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-db_stubs.Tpo $(DEPDIR)/libdb_la-db_stubs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='db_stubs.c' object='libdb_la-db_stubs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-db_stubs.lo `test -f 'db_stubs.c' || echo '$(srcdir)/'`db_stubs.c libdb_la-dbm_api.lo: ../../libpromises/dbm_api.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-dbm_api.lo -MD -MP -MF $(DEPDIR)/libdb_la-dbm_api.Tpo -c -o libdb_la-dbm_api.lo `test -f '../../libpromises/dbm_api.c' || echo '$(srcdir)/'`../../libpromises/dbm_api.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-dbm_api.Tpo $(DEPDIR)/libdb_la-dbm_api.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/dbm_api.c' object='libdb_la-dbm_api.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-dbm_api.lo `test -f '../../libpromises/dbm_api.c' || echo '$(srcdir)/'`../../libpromises/dbm_api.c libdb_la-dbm_quick.lo: ../../libpromises/dbm_quick.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-dbm_quick.lo -MD -MP -MF $(DEPDIR)/libdb_la-dbm_quick.Tpo -c -o libdb_la-dbm_quick.lo `test -f '../../libpromises/dbm_quick.c' || echo '$(srcdir)/'`../../libpromises/dbm_quick.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-dbm_quick.Tpo $(DEPDIR)/libdb_la-dbm_quick.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/dbm_quick.c' object='libdb_la-dbm_quick.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-dbm_quick.lo `test -f '../../libpromises/dbm_quick.c' || echo '$(srcdir)/'`../../libpromises/dbm_quick.c libdb_la-dbm_tokyocab.lo: ../../libpromises/dbm_tokyocab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-dbm_tokyocab.lo -MD -MP -MF $(DEPDIR)/libdb_la-dbm_tokyocab.Tpo -c -o libdb_la-dbm_tokyocab.lo `test -f '../../libpromises/dbm_tokyocab.c' || echo '$(srcdir)/'`../../libpromises/dbm_tokyocab.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-dbm_tokyocab.Tpo $(DEPDIR)/libdb_la-dbm_tokyocab.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/dbm_tokyocab.c' object='libdb_la-dbm_tokyocab.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-dbm_tokyocab.lo `test -f '../../libpromises/dbm_tokyocab.c' || echo '$(srcdir)/'`../../libpromises/dbm_tokyocab.c libdb_la-dbm_lmdb.lo: ../../libpromises/dbm_lmdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-dbm_lmdb.lo -MD -MP -MF $(DEPDIR)/libdb_la-dbm_lmdb.Tpo -c -o libdb_la-dbm_lmdb.lo `test -f '../../libpromises/dbm_lmdb.c' || echo '$(srcdir)/'`../../libpromises/dbm_lmdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-dbm_lmdb.Tpo $(DEPDIR)/libdb_la-dbm_lmdb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/dbm_lmdb.c' object='libdb_la-dbm_lmdb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-dbm_lmdb.lo `test -f '../../libpromises/dbm_lmdb.c' || echo '$(srcdir)/'`../../libpromises/dbm_lmdb.c libdb_la-dbm_migration.lo: ../../libpromises/dbm_migration.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-dbm_migration.lo -MD -MP -MF $(DEPDIR)/libdb_la-dbm_migration.Tpo -c -o libdb_la-dbm_migration.lo `test -f '../../libpromises/dbm_migration.c' || echo '$(srcdir)/'`../../libpromises/dbm_migration.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-dbm_migration.Tpo $(DEPDIR)/libdb_la-dbm_migration.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/dbm_migration.c' object='libdb_la-dbm_migration.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-dbm_migration.lo `test -f '../../libpromises/dbm_migration.c' || echo '$(srcdir)/'`../../libpromises/dbm_migration.c libdb_la-dbm_migration_lastseen.lo: ../../libpromises/dbm_migration_lastseen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-dbm_migration_lastseen.lo -MD -MP -MF $(DEPDIR)/libdb_la-dbm_migration_lastseen.Tpo -c -o libdb_la-dbm_migration_lastseen.lo `test -f '../../libpromises/dbm_migration_lastseen.c' || echo '$(srcdir)/'`../../libpromises/dbm_migration_lastseen.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-dbm_migration_lastseen.Tpo $(DEPDIR)/libdb_la-dbm_migration_lastseen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/dbm_migration_lastseen.c' object='libdb_la-dbm_migration_lastseen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-dbm_migration_lastseen.lo `test -f '../../libpromises/dbm_migration_lastseen.c' || echo '$(srcdir)/'`../../libpromises/dbm_migration_lastseen.c libdb_la-global_mutex.lo: ../../libpromises/global_mutex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-global_mutex.lo -MD -MP -MF $(DEPDIR)/libdb_la-global_mutex.Tpo -c -o libdb_la-global_mutex.lo `test -f '../../libpromises/global_mutex.c' || echo '$(srcdir)/'`../../libpromises/global_mutex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-global_mutex.Tpo $(DEPDIR)/libdb_la-global_mutex.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/global_mutex.c' object='libdb_la-global_mutex.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-global_mutex.lo `test -f '../../libpromises/global_mutex.c' || echo '$(srcdir)/'`../../libpromises/global_mutex.c libdb_la-backup.lo: ../../cf-check/backup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-backup.lo -MD -MP -MF $(DEPDIR)/libdb_la-backup.Tpo -c -o libdb_la-backup.lo `test -f '../../cf-check/backup.c' || echo '$(srcdir)/'`../../cf-check/backup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-backup.Tpo $(DEPDIR)/libdb_la-backup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-check/backup.c' object='libdb_la-backup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-backup.lo `test -f '../../cf-check/backup.c' || echo '$(srcdir)/'`../../cf-check/backup.c libdb_la-diagnose.lo: ../../cf-check/diagnose.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-diagnose.lo -MD -MP -MF $(DEPDIR)/libdb_la-diagnose.Tpo -c -o libdb_la-diagnose.lo `test -f '../../cf-check/diagnose.c' || echo '$(srcdir)/'`../../cf-check/diagnose.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-diagnose.Tpo $(DEPDIR)/libdb_la-diagnose.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-check/diagnose.c' object='libdb_la-diagnose.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-diagnose.lo `test -f '../../cf-check/diagnose.c' || echo '$(srcdir)/'`../../cf-check/diagnose.c libdb_la-lmdump.lo: ../../cf-check/lmdump.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-lmdump.lo -MD -MP -MF $(DEPDIR)/libdb_la-lmdump.Tpo -c -o libdb_la-lmdump.lo `test -f '../../cf-check/lmdump.c' || echo '$(srcdir)/'`../../cf-check/lmdump.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-lmdump.Tpo $(DEPDIR)/libdb_la-lmdump.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-check/lmdump.c' object='libdb_la-lmdump.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-lmdump.lo `test -f '../../cf-check/lmdump.c' || echo '$(srcdir)/'`../../cf-check/lmdump.c libdb_la-repair.lo: ../../cf-check/repair.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-repair.lo -MD -MP -MF $(DEPDIR)/libdb_la-repair.Tpo -c -o libdb_la-repair.lo `test -f '../../cf-check/repair.c' || echo '$(srcdir)/'`../../cf-check/repair.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-repair.Tpo $(DEPDIR)/libdb_la-repair.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-check/repair.c' object='libdb_la-repair.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-repair.lo `test -f '../../cf-check/repair.c' || echo '$(srcdir)/'`../../cf-check/repair.c libdb_la-replicate_lmdb.lo: ../../cf-check/replicate_lmdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-replicate_lmdb.lo -MD -MP -MF $(DEPDIR)/libdb_la-replicate_lmdb.Tpo -c -o libdb_la-replicate_lmdb.lo `test -f '../../cf-check/replicate_lmdb.c' || echo '$(srcdir)/'`../../cf-check/replicate_lmdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-replicate_lmdb.Tpo $(DEPDIR)/libdb_la-replicate_lmdb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-check/replicate_lmdb.c' object='libdb_la-replicate_lmdb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-replicate_lmdb.lo `test -f '../../cf-check/replicate_lmdb.c' || echo '$(srcdir)/'`../../cf-check/replicate_lmdb.c libdb_la-utilities.lo: ../../cf-check/utilities.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-utilities.lo -MD -MP -MF $(DEPDIR)/libdb_la-utilities.Tpo -c -o libdb_la-utilities.lo `test -f '../../cf-check/utilities.c' || echo '$(srcdir)/'`../../cf-check/utilities.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-utilities.Tpo $(DEPDIR)/libdb_la-utilities.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-check/utilities.c' object='libdb_la-utilities.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-utilities.lo `test -f '../../cf-check/utilities.c' || echo '$(srcdir)/'`../../cf-check/utilities.c libdb_la-validate.lo: ../../cf-check/validate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-validate.lo -MD -MP -MF $(DEPDIR)/libdb_la-validate.Tpo -c -o libdb_la-validate.lo `test -f '../../cf-check/validate.c' || echo '$(srcdir)/'`../../cf-check/validate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-validate.Tpo $(DEPDIR)/libdb_la-validate.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-check/validate.c' object='libdb_la-validate.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-validate.lo `test -f '../../cf-check/validate.c' || echo '$(srcdir)/'`../../cf-check/validate.c libdb_la-logging.lo: ../../libntech/libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-logging.lo -MD -MP -MF $(DEPDIR)/libdb_la-logging.Tpo -c -o libdb_la-logging.lo `test -f '../../libntech/libutils/logging.c' || echo '$(srcdir)/'`../../libntech/libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-logging.Tpo $(DEPDIR)/libdb_la-logging.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/logging.c' object='libdb_la-logging.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-logging.lo `test -f '../../libntech/libutils/logging.c' || echo '$(srcdir)/'`../../libntech/libutils/logging.c libdb_la-mutex.lo: ../../libntech/libutils/mutex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-mutex.lo -MD -MP -MF $(DEPDIR)/libdb_la-mutex.Tpo -c -o libdb_la-mutex.lo `test -f '../../libntech/libutils/mutex.c' || echo '$(srcdir)/'`../../libntech/libutils/mutex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-mutex.Tpo $(DEPDIR)/libdb_la-mutex.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/mutex.c' object='libdb_la-mutex.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-mutex.lo `test -f '../../libntech/libutils/mutex.c' || echo '$(srcdir)/'`../../libntech/libutils/mutex.c libdb_la-cleanup.lo: ../../libntech/libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-cleanup.lo -MD -MP -MF $(DEPDIR)/libdb_la-cleanup.Tpo -c -o libdb_la-cleanup.lo `test -f '../../libntech/libutils/cleanup.c' || echo '$(srcdir)/'`../../libntech/libutils/cleanup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-cleanup.Tpo $(DEPDIR)/libdb_la-cleanup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/cleanup.c' object='libdb_la-cleanup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-cleanup.lo `test -f '../../libntech/libutils/cleanup.c' || echo '$(srcdir)/'`../../libntech/libutils/cleanup.c libdb_la-cf3globals.lo: ../../libpromises/cf3globals.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -MT libdb_la-cf3globals.lo -MD -MP -MF $(DEPDIR)/libdb_la-cf3globals.Tpo -c -o libdb_la-cf3globals.lo `test -f '../../libpromises/cf3globals.c' || echo '$(srcdir)/'`../../libpromises/cf3globals.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdb_la-cf3globals.Tpo $(DEPDIR)/libdb_la-cf3globals.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/cf3globals.c' object='libdb_la-cf3globals.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdb_la_CFLAGS) $(CFLAGS) -c -o libdb_la-cf3globals.lo `test -f '../../libpromises/cf3globals.c' || echo '$(srcdir)/'`../../libpromises/cf3globals.c buffer.lo: ../../libntech/libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT buffer.lo -MD -MP -MF $(DEPDIR)/buffer.Tpo -c -o buffer.lo `test -f '../../libntech/libutils/buffer.c' || echo '$(srcdir)/'`../../libntech/libutils/buffer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/buffer.Tpo $(DEPDIR)/buffer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/buffer.c' object='buffer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o buffer.lo `test -f '../../libntech/libutils/buffer.c' || echo '$(srcdir)/'`../../libntech/libutils/buffer.c encode.lo: ../../libntech/libutils/encode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT encode.lo -MD -MP -MF $(DEPDIR)/encode.Tpo -c -o encode.lo `test -f '../../libntech/libutils/encode.c' || echo '$(srcdir)/'`../../libntech/libutils/encode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/encode.Tpo $(DEPDIR)/encode.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/encode.c' object='encode.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o encode.lo `test -f '../../libntech/libutils/encode.c' || echo '$(srcdir)/'`../../libntech/libutils/encode.c logging.lo: ../../libntech/libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT logging.lo -MD -MP -MF $(DEPDIR)/logging.Tpo -c -o logging.lo `test -f '../../libntech/libutils/logging.c' || echo '$(srcdir)/'`../../libntech/libutils/logging.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/logging.Tpo $(DEPDIR)/logging.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/logging.c' object='logging.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o logging.lo `test -f '../../libntech/libutils/logging.c' || echo '$(srcdir)/'`../../libntech/libutils/logging.c misc_lib.lo: ../../libntech/libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT misc_lib.lo -MD -MP -MF $(DEPDIR)/misc_lib.Tpo -c -o misc_lib.lo `test -f '../../libntech/libutils/misc_lib.c' || echo '$(srcdir)/'`../../libntech/libutils/misc_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/misc_lib.Tpo $(DEPDIR)/misc_lib.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/misc_lib.c' object='misc_lib.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o misc_lib.lo `test -f '../../libntech/libutils/misc_lib.c' || echo '$(srcdir)/'`../../libntech/libutils/misc_lib.c regex.lo: ../../libntech/libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT regex.lo -MD -MP -MF $(DEPDIR)/regex.Tpo -c -o regex.lo `test -f '../../libntech/libutils/regex.c' || echo '$(srcdir)/'`../../libntech/libutils/regex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/regex.Tpo $(DEPDIR)/regex.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/regex.c' object='regex.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o regex.lo `test -f '../../libntech/libutils/regex.c' || echo '$(srcdir)/'`../../libntech/libutils/regex.c sequence.lo: ../../libntech/libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sequence.lo -MD -MP -MF $(DEPDIR)/sequence.Tpo -c -o sequence.lo `test -f '../../libntech/libutils/sequence.c' || echo '$(srcdir)/'`../../libntech/libutils/sequence.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sequence.Tpo $(DEPDIR)/sequence.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/sequence.c' object='sequence.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sequence.lo `test -f '../../libntech/libutils/sequence.c' || echo '$(srcdir)/'`../../libntech/libutils/sequence.c string_lib.lo: ../../libntech/libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT string_lib.lo -MD -MP -MF $(DEPDIR)/string_lib.Tpo -c -o string_lib.lo `test -f '../../libntech/libutils/string_lib.c' || echo '$(srcdir)/'`../../libntech/libutils/string_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/string_lib.Tpo $(DEPDIR)/string_lib.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/string_lib.c' object='string_lib.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o string_lib.lo `test -f '../../libntech/libutils/string_lib.c' || echo '$(srcdir)/'`../../libntech/libutils/string_lib.c writer.lo: ../../libntech/libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT writer.lo -MD -MP -MF $(DEPDIR)/writer.Tpo -c -o writer.lo `test -f '../../libntech/libutils/writer.c' || echo '$(srcdir)/'`../../libntech/libutils/writer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/writer.Tpo $(DEPDIR)/writer.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/writer.c' object='writer.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o writer.lo `test -f '../../libntech/libutils/writer.c' || echo '$(srcdir)/'`../../libntech/libutils/writer.c process_unix.o: ../../libpromises/process_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_unix.o -MD -MP -MF $(DEPDIR)/process_unix.Tpo -c -o process_unix.o `test -f '../../libpromises/process_unix.c' || echo '$(srcdir)/'`../../libpromises/process_unix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_unix.Tpo $(DEPDIR)/process_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_unix.c' object='process_unix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_unix.o `test -f '../../libpromises/process_unix.c' || echo '$(srcdir)/'`../../libpromises/process_unix.c process_unix.obj: ../../libpromises/process_unix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_unix.obj -MD -MP -MF $(DEPDIR)/process_unix.Tpo -c -o process_unix.obj `if test -f '../../libpromises/process_unix.c'; then $(CYGPATH_W) '../../libpromises/process_unix.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_unix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_unix.Tpo $(DEPDIR)/process_unix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_unix.c' object='process_unix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_unix.obj `if test -f '../../libpromises/process_unix.c'; then $(CYGPATH_W) '../../libpromises/process_unix.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_unix.c'; fi` process_aix.o: ../../libpromises/process_aix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_aix.o -MD -MP -MF $(DEPDIR)/process_aix.Tpo -c -o process_aix.o `test -f '../../libpromises/process_aix.c' || echo '$(srcdir)/'`../../libpromises/process_aix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_aix.Tpo $(DEPDIR)/process_aix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_aix.c' object='process_aix.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_aix.o `test -f '../../libpromises/process_aix.c' || echo '$(srcdir)/'`../../libpromises/process_aix.c process_aix.obj: ../../libpromises/process_aix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_aix.obj -MD -MP -MF $(DEPDIR)/process_aix.Tpo -c -o process_aix.obj `if test -f '../../libpromises/process_aix.c'; then $(CYGPATH_W) '../../libpromises/process_aix.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_aix.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_aix.Tpo $(DEPDIR)/process_aix.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_aix.c' object='process_aix.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_aix.obj `if test -f '../../libpromises/process_aix.c'; then $(CYGPATH_W) '../../libpromises/process_aix.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_aix.c'; fi` file_lib.o: ../../libntech/libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib.o -MD -MP -MF $(DEPDIR)/file_lib.Tpo -c -o file_lib.o `test -f '../../libntech/libutils/file_lib.c' || echo '$(srcdir)/'`../../libntech/libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib.Tpo $(DEPDIR)/file_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/file_lib.c' object='file_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib.o `test -f '../../libntech/libutils/file_lib.c' || echo '$(srcdir)/'`../../libntech/libutils/file_lib.c file_lib.obj: ../../libntech/libutils/file_lib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT file_lib.obj -MD -MP -MF $(DEPDIR)/file_lib.Tpo -c -o file_lib.obj `if test -f '../../libntech/libutils/file_lib.c'; then $(CYGPATH_W) '../../libntech/libutils/file_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libntech/libutils/file_lib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/file_lib.Tpo $(DEPDIR)/file_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/file_lib.c' object='file_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o file_lib.obj `if test -f '../../libntech/libutils/file_lib.c'; then $(CYGPATH_W) '../../libntech/libutils/file_lib.c'; else $(CYGPATH_W) '$(srcdir)/../../libntech/libutils/file_lib.c'; fi` server_common.o: ../../cf-serverd/server_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_common.o -MD -MP -MF $(DEPDIR)/server_common.Tpo -c -o server_common.o `test -f '../../cf-serverd/server_common.c' || echo '$(srcdir)/'`../../cf-serverd/server_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_common.Tpo $(DEPDIR)/server_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_common.c' object='server_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_common.o `test -f '../../cf-serverd/server_common.c' || echo '$(srcdir)/'`../../cf-serverd/server_common.c server_common.obj: ../../cf-serverd/server_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_common.obj -MD -MP -MF $(DEPDIR)/server_common.Tpo -c -o server_common.obj `if test -f '../../cf-serverd/server_common.c'; then $(CYGPATH_W) '../../cf-serverd/server_common.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_common.Tpo $(DEPDIR)/server_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_common.c' object='server_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_common.obj `if test -f '../../cf-serverd/server_common.c'; then $(CYGPATH_W) '../../cf-serverd/server_common.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_common.c'; fi` server_tls.o: ../../cf-serverd/server_tls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_tls.o -MD -MP -MF $(DEPDIR)/server_tls.Tpo -c -o server_tls.o `test -f '../../cf-serverd/server_tls.c' || echo '$(srcdir)/'`../../cf-serverd/server_tls.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_tls.Tpo $(DEPDIR)/server_tls.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_tls.c' object='server_tls.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_tls.o `test -f '../../cf-serverd/server_tls.c' || echo '$(srcdir)/'`../../cf-serverd/server_tls.c server_tls.obj: ../../cf-serverd/server_tls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_tls.obj -MD -MP -MF $(DEPDIR)/server_tls.Tpo -c -o server_tls.obj `if test -f '../../cf-serverd/server_tls.c'; then $(CYGPATH_W) '../../cf-serverd/server_tls.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_tls.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_tls.Tpo $(DEPDIR)/server_tls.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_tls.c' object='server_tls.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_tls.obj `if test -f '../../cf-serverd/server_tls.c'; then $(CYGPATH_W) '../../cf-serverd/server_tls.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_tls.c'; fi` server.o: ../../cf-serverd/server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server.o -MD -MP -MF $(DEPDIR)/server.Tpo -c -o server.o `test -f '../../cf-serverd/server.c' || echo '$(srcdir)/'`../../cf-serverd/server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server.Tpo $(DEPDIR)/server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server.c' object='server.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server.o `test -f '../../cf-serverd/server.c' || echo '$(srcdir)/'`../../cf-serverd/server.c server.obj: ../../cf-serverd/server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server.obj -MD -MP -MF $(DEPDIR)/server.Tpo -c -o server.obj `if test -f '../../cf-serverd/server.c'; then $(CYGPATH_W) '../../cf-serverd/server.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server.Tpo $(DEPDIR)/server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server.c' object='server.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server.obj `if test -f '../../cf-serverd/server.c'; then $(CYGPATH_W) '../../cf-serverd/server.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server.c'; fi` server_transform.o: ../../cf-serverd/server_transform.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_transform.o -MD -MP -MF $(DEPDIR)/server_transform.Tpo -c -o server_transform.o `test -f '../../cf-serverd/server_transform.c' || echo '$(srcdir)/'`../../cf-serverd/server_transform.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_transform.Tpo $(DEPDIR)/server_transform.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_transform.c' object='server_transform.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_transform.o `test -f '../../cf-serverd/server_transform.c' || echo '$(srcdir)/'`../../cf-serverd/server_transform.c server_transform.obj: ../../cf-serverd/server_transform.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_transform.obj -MD -MP -MF $(DEPDIR)/server_transform.Tpo -c -o server_transform.obj `if test -f '../../cf-serverd/server_transform.c'; then $(CYGPATH_W) '../../cf-serverd/server_transform.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_transform.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_transform.Tpo $(DEPDIR)/server_transform.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_transform.c' object='server_transform.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_transform.obj `if test -f '../../cf-serverd/server_transform.c'; then $(CYGPATH_W) '../../cf-serverd/server_transform.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_transform.c'; fi` cf-serverd-enterprise-stubs.o: ../../cf-serverd/cf-serverd-enterprise-stubs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf-serverd-enterprise-stubs.o -MD -MP -MF $(DEPDIR)/cf-serverd-enterprise-stubs.Tpo -c -o cf-serverd-enterprise-stubs.o `test -f '../../cf-serverd/cf-serverd-enterprise-stubs.c' || echo '$(srcdir)/'`../../cf-serverd/cf-serverd-enterprise-stubs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf-serverd-enterprise-stubs.Tpo $(DEPDIR)/cf-serverd-enterprise-stubs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/cf-serverd-enterprise-stubs.c' object='cf-serverd-enterprise-stubs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf-serverd-enterprise-stubs.o `test -f '../../cf-serverd/cf-serverd-enterprise-stubs.c' || echo '$(srcdir)/'`../../cf-serverd/cf-serverd-enterprise-stubs.c cf-serverd-enterprise-stubs.obj: ../../cf-serverd/cf-serverd-enterprise-stubs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf-serverd-enterprise-stubs.obj -MD -MP -MF $(DEPDIR)/cf-serverd-enterprise-stubs.Tpo -c -o cf-serverd-enterprise-stubs.obj `if test -f '../../cf-serverd/cf-serverd-enterprise-stubs.c'; then $(CYGPATH_W) '../../cf-serverd/cf-serverd-enterprise-stubs.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/cf-serverd-enterprise-stubs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf-serverd-enterprise-stubs.Tpo $(DEPDIR)/cf-serverd-enterprise-stubs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/cf-serverd-enterprise-stubs.c' object='cf-serverd-enterprise-stubs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf-serverd-enterprise-stubs.obj `if test -f '../../cf-serverd/cf-serverd-enterprise-stubs.c'; then $(CYGPATH_W) '../../cf-serverd/cf-serverd-enterprise-stubs.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/cf-serverd-enterprise-stubs.c'; fi` server_access.o: ../../cf-serverd/server_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_access.o -MD -MP -MF $(DEPDIR)/server_access.Tpo -c -o server_access.o `test -f '../../cf-serverd/server_access.c' || echo '$(srcdir)/'`../../cf-serverd/server_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_access.Tpo $(DEPDIR)/server_access.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_access.c' object='server_access.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_access.o `test -f '../../cf-serverd/server_access.c' || echo '$(srcdir)/'`../../cf-serverd/server_access.c server_access.obj: ../../cf-serverd/server_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_access.obj -MD -MP -MF $(DEPDIR)/server_access.Tpo -c -o server_access.obj `if test -f '../../cf-serverd/server_access.c'; then $(CYGPATH_W) '../../cf-serverd/server_access.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_access.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_access.Tpo $(DEPDIR)/server_access.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_access.c' object='server_access.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_access.obj `if test -f '../../cf-serverd/server_access.c'; then $(CYGPATH_W) '../../cf-serverd/server_access.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_access.c'; fi` server_classic.o: ../../cf-serverd/server_classic.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_classic.o -MD -MP -MF $(DEPDIR)/server_classic.Tpo -c -o server_classic.o `test -f '../../cf-serverd/server_classic.c' || echo '$(srcdir)/'`../../cf-serverd/server_classic.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_classic.Tpo $(DEPDIR)/server_classic.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_classic.c' object='server_classic.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_classic.o `test -f '../../cf-serverd/server_classic.c' || echo '$(srcdir)/'`../../cf-serverd/server_classic.c server_classic.obj: ../../cf-serverd/server_classic.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT server_classic.obj -MD -MP -MF $(DEPDIR)/server_classic.Tpo -c -o server_classic.obj `if test -f '../../cf-serverd/server_classic.c'; then $(CYGPATH_W) '../../cf-serverd/server_classic.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_classic.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_classic.Tpo $(DEPDIR)/server_classic.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/server_classic.c' object='server_classic.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o server_classic.obj `if test -f '../../cf-serverd/server_classic.c'; then $(CYGPATH_W) '../../cf-serverd/server_classic.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/server_classic.c'; fi` strlist.o: ../../cf-serverd/strlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT strlist.o -MD -MP -MF $(DEPDIR)/strlist.Tpo -c -o strlist.o `test -f '../../cf-serverd/strlist.c' || echo '$(srcdir)/'`../../cf-serverd/strlist.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/strlist.Tpo $(DEPDIR)/strlist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/strlist.c' object='strlist.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strlist.o `test -f '../../cf-serverd/strlist.c' || echo '$(srcdir)/'`../../cf-serverd/strlist.c strlist.obj: ../../cf-serverd/strlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT strlist.obj -MD -MP -MF $(DEPDIR)/strlist.Tpo -c -o strlist.obj `if test -f '../../cf-serverd/strlist.c'; then $(CYGPATH_W) '../../cf-serverd/strlist.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/strlist.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/strlist.Tpo $(DEPDIR)/strlist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/strlist.c' object='strlist.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strlist.obj `if test -f '../../cf-serverd/strlist.c'; then $(CYGPATH_W) '../../cf-serverd/strlist.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/strlist.c'; fi` cf_upgrade_test-cf_upgrade_test.o: cf_upgrade_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-cf_upgrade_test.o -MD -MP -MF $(DEPDIR)/cf_upgrade_test-cf_upgrade_test.Tpo -c -o cf_upgrade_test-cf_upgrade_test.o `test -f 'cf_upgrade_test.c' || echo '$(srcdir)/'`cf_upgrade_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-cf_upgrade_test.Tpo $(DEPDIR)/cf_upgrade_test-cf_upgrade_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf_upgrade_test.c' object='cf_upgrade_test-cf_upgrade_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-cf_upgrade_test.o `test -f 'cf_upgrade_test.c' || echo '$(srcdir)/'`cf_upgrade_test.c cf_upgrade_test-cf_upgrade_test.obj: cf_upgrade_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-cf_upgrade_test.obj -MD -MP -MF $(DEPDIR)/cf_upgrade_test-cf_upgrade_test.Tpo -c -o cf_upgrade_test-cf_upgrade_test.obj `if test -f 'cf_upgrade_test.c'; then $(CYGPATH_W) 'cf_upgrade_test.c'; else $(CYGPATH_W) '$(srcdir)/cf_upgrade_test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-cf_upgrade_test.Tpo $(DEPDIR)/cf_upgrade_test-cf_upgrade_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf_upgrade_test.c' object='cf_upgrade_test-cf_upgrade_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-cf_upgrade_test.obj `if test -f 'cf_upgrade_test.c'; then $(CYGPATH_W) 'cf_upgrade_test.c'; else $(CYGPATH_W) '$(srcdir)/cf_upgrade_test.c'; fi` cf_upgrade_test-alloc-mini.o: $(top_srcdir)/cf-upgrade/alloc-mini.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-alloc-mini.o -MD -MP -MF $(DEPDIR)/cf_upgrade_test-alloc-mini.Tpo -c -o cf_upgrade_test-alloc-mini.o `test -f '$(top_srcdir)/cf-upgrade/alloc-mini.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/alloc-mini.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-alloc-mini.Tpo $(DEPDIR)/cf_upgrade_test-alloc-mini.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/alloc-mini.c' object='cf_upgrade_test-alloc-mini.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-alloc-mini.o `test -f '$(top_srcdir)/cf-upgrade/alloc-mini.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/alloc-mini.c cf_upgrade_test-alloc-mini.obj: $(top_srcdir)/cf-upgrade/alloc-mini.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-alloc-mini.obj -MD -MP -MF $(DEPDIR)/cf_upgrade_test-alloc-mini.Tpo -c -o cf_upgrade_test-alloc-mini.obj `if test -f '$(top_srcdir)/cf-upgrade/alloc-mini.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/alloc-mini.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/alloc-mini.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-alloc-mini.Tpo $(DEPDIR)/cf_upgrade_test-alloc-mini.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/alloc-mini.c' object='cf_upgrade_test-alloc-mini.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-alloc-mini.obj `if test -f '$(top_srcdir)/cf-upgrade/alloc-mini.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/alloc-mini.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/alloc-mini.c'; fi` cf_upgrade_test-command_line.o: $(top_srcdir)/cf-upgrade/command_line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-command_line.o -MD -MP -MF $(DEPDIR)/cf_upgrade_test-command_line.Tpo -c -o cf_upgrade_test-command_line.o `test -f '$(top_srcdir)/cf-upgrade/command_line.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/command_line.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-command_line.Tpo $(DEPDIR)/cf_upgrade_test-command_line.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/command_line.c' object='cf_upgrade_test-command_line.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-command_line.o `test -f '$(top_srcdir)/cf-upgrade/command_line.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/command_line.c cf_upgrade_test-command_line.obj: $(top_srcdir)/cf-upgrade/command_line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-command_line.obj -MD -MP -MF $(DEPDIR)/cf_upgrade_test-command_line.Tpo -c -o cf_upgrade_test-command_line.obj `if test -f '$(top_srcdir)/cf-upgrade/command_line.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/command_line.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/command_line.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-command_line.Tpo $(DEPDIR)/cf_upgrade_test-command_line.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/command_line.c' object='cf_upgrade_test-command_line.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-command_line.obj `if test -f '$(top_srcdir)/cf-upgrade/command_line.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/command_line.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/command_line.c'; fi` cf_upgrade_test-configuration.o: $(top_srcdir)/cf-upgrade/configuration.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-configuration.o -MD -MP -MF $(DEPDIR)/cf_upgrade_test-configuration.Tpo -c -o cf_upgrade_test-configuration.o `test -f '$(top_srcdir)/cf-upgrade/configuration.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/configuration.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-configuration.Tpo $(DEPDIR)/cf_upgrade_test-configuration.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/configuration.c' object='cf_upgrade_test-configuration.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-configuration.o `test -f '$(top_srcdir)/cf-upgrade/configuration.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/configuration.c cf_upgrade_test-configuration.obj: $(top_srcdir)/cf-upgrade/configuration.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-configuration.obj -MD -MP -MF $(DEPDIR)/cf_upgrade_test-configuration.Tpo -c -o cf_upgrade_test-configuration.obj `if test -f '$(top_srcdir)/cf-upgrade/configuration.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/configuration.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/configuration.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-configuration.Tpo $(DEPDIR)/cf_upgrade_test-configuration.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/configuration.c' object='cf_upgrade_test-configuration.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-configuration.obj `if test -f '$(top_srcdir)/cf-upgrade/configuration.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/configuration.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/configuration.c'; fi` cf_upgrade_test-log.o: $(top_srcdir)/cf-upgrade/log.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-log.o -MD -MP -MF $(DEPDIR)/cf_upgrade_test-log.Tpo -c -o cf_upgrade_test-log.o `test -f '$(top_srcdir)/cf-upgrade/log.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/log.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-log.Tpo $(DEPDIR)/cf_upgrade_test-log.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/log.c' object='cf_upgrade_test-log.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-log.o `test -f '$(top_srcdir)/cf-upgrade/log.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/log.c cf_upgrade_test-log.obj: $(top_srcdir)/cf-upgrade/log.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-log.obj -MD -MP -MF $(DEPDIR)/cf_upgrade_test-log.Tpo -c -o cf_upgrade_test-log.obj `if test -f '$(top_srcdir)/cf-upgrade/log.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/log.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/log.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-log.Tpo $(DEPDIR)/cf_upgrade_test-log.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/log.c' object='cf_upgrade_test-log.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-log.obj `if test -f '$(top_srcdir)/cf-upgrade/log.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/log.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/log.c'; fi` cf_upgrade_test-process.o: $(top_srcdir)/cf-upgrade/process.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-process.o -MD -MP -MF $(DEPDIR)/cf_upgrade_test-process.Tpo -c -o cf_upgrade_test-process.o `test -f '$(top_srcdir)/cf-upgrade/process.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/process.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-process.Tpo $(DEPDIR)/cf_upgrade_test-process.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/process.c' object='cf_upgrade_test-process.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-process.o `test -f '$(top_srcdir)/cf-upgrade/process.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/process.c cf_upgrade_test-process.obj: $(top_srcdir)/cf-upgrade/process.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-process.obj -MD -MP -MF $(DEPDIR)/cf_upgrade_test-process.Tpo -c -o cf_upgrade_test-process.obj `if test -f '$(top_srcdir)/cf-upgrade/process.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/process.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/process.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-process.Tpo $(DEPDIR)/cf_upgrade_test-process.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/process.c' object='cf_upgrade_test-process.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-process.obj `if test -f '$(top_srcdir)/cf-upgrade/process.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/process.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/process.c'; fi` cf_upgrade_test-update.o: $(top_srcdir)/cf-upgrade/update.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-update.o -MD -MP -MF $(DEPDIR)/cf_upgrade_test-update.Tpo -c -o cf_upgrade_test-update.o `test -f '$(top_srcdir)/cf-upgrade/update.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/update.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-update.Tpo $(DEPDIR)/cf_upgrade_test-update.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/update.c' object='cf_upgrade_test-update.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-update.o `test -f '$(top_srcdir)/cf-upgrade/update.c' || echo '$(srcdir)/'`$(top_srcdir)/cf-upgrade/update.c cf_upgrade_test-update.obj: $(top_srcdir)/cf-upgrade/update.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf_upgrade_test-update.obj -MD -MP -MF $(DEPDIR)/cf_upgrade_test-update.Tpo -c -o cf_upgrade_test-update.obj `if test -f '$(top_srcdir)/cf-upgrade/update.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/update.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/update.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_upgrade_test-update.Tpo $(DEPDIR)/cf_upgrade_test-update.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/cf-upgrade/update.c' object='cf_upgrade_test-update.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cf_upgrade_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf_upgrade_test-update.obj `if test -f '$(top_srcdir)/cf-upgrade/update.c'; then $(CYGPATH_W) '$(top_srcdir)/cf-upgrade/update.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/cf-upgrade/update.c'; fi` conversion.o: ../../libpromises/conversion.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT conversion.o -MD -MP -MF $(DEPDIR)/conversion.Tpo -c -o conversion.o `test -f '../../libpromises/conversion.c' || echo '$(srcdir)/'`../../libpromises/conversion.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/conversion.Tpo $(DEPDIR)/conversion.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/conversion.c' object='conversion.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o conversion.o `test -f '../../libpromises/conversion.c' || echo '$(srcdir)/'`../../libpromises/conversion.c conversion.obj: ../../libpromises/conversion.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT conversion.obj -MD -MP -MF $(DEPDIR)/conversion.Tpo -c -o conversion.obj `if test -f '../../libpromises/conversion.c'; then $(CYGPATH_W) '../../libpromises/conversion.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/conversion.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/conversion.Tpo $(DEPDIR)/conversion.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/conversion.c' object='conversion.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o conversion.obj `if test -f '../../libpromises/conversion.c'; then $(CYGPATH_W) '../../libpromises/conversion.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/conversion.c'; fi` exec-config.o: ../../cf-execd/exec-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exec-config.o -MD -MP -MF $(DEPDIR)/exec-config.Tpo -c -o exec-config.o `test -f '../../cf-execd/exec-config.c' || echo '$(srcdir)/'`../../cf-execd/exec-config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/exec-config.Tpo $(DEPDIR)/exec-config.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-execd/exec-config.c' object='exec-config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exec-config.o `test -f '../../cf-execd/exec-config.c' || echo '$(srcdir)/'`../../cf-execd/exec-config.c exec-config.obj: ../../cf-execd/exec-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT exec-config.obj -MD -MP -MF $(DEPDIR)/exec-config.Tpo -c -o exec-config.obj `if test -f '../../cf-execd/exec-config.c'; then $(CYGPATH_W) '../../cf-execd/exec-config.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-execd/exec-config.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/exec-config.Tpo $(DEPDIR)/exec-config.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-execd/exec-config.c' object='exec-config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o exec-config.obj `if test -f '../../cf-execd/exec-config.c'; then $(CYGPATH_W) '../../cf-execd/exec-config.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-execd/exec-config.c'; fi` execd-config.o: ../../cf-execd/execd-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT execd-config.o -MD -MP -MF $(DEPDIR)/execd-config.Tpo -c -o execd-config.o `test -f '../../cf-execd/execd-config.c' || echo '$(srcdir)/'`../../cf-execd/execd-config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/execd-config.Tpo $(DEPDIR)/execd-config.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-execd/execd-config.c' object='execd-config.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o execd-config.o `test -f '../../cf-execd/execd-config.c' || echo '$(srcdir)/'`../../cf-execd/execd-config.c execd-config.obj: ../../cf-execd/execd-config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT execd-config.obj -MD -MP -MF $(DEPDIR)/execd-config.Tpo -c -o execd-config.obj `if test -f '../../cf-execd/execd-config.c'; then $(CYGPATH_W) '../../cf-execd/execd-config.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-execd/execd-config.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/execd-config.Tpo $(DEPDIR)/execd-config.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-execd/execd-config.c' object='execd-config.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o execd-config.obj `if test -f '../../cf-execd/execd-config.c'; then $(CYGPATH_W) '../../cf-execd/execd-config.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-execd/execd-config.c'; fi` findhub.o: ../../cf-agent/findhub.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findhub.o -MD -MP -MF $(DEPDIR)/findhub.Tpo -c -o findhub.o `test -f '../../cf-agent/findhub.c' || echo '$(srcdir)/'`../../cf-agent/findhub.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findhub.Tpo $(DEPDIR)/findhub.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/findhub.c' object='findhub.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findhub.o `test -f '../../cf-agent/findhub.c' || echo '$(srcdir)/'`../../cf-agent/findhub.c findhub.obj: ../../cf-agent/findhub.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findhub.obj -MD -MP -MF $(DEPDIR)/findhub.Tpo -c -o findhub.obj `if test -f '../../cf-agent/findhub.c'; then $(CYGPATH_W) '../../cf-agent/findhub.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/findhub.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findhub.Tpo $(DEPDIR)/findhub.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/findhub.c' object='findhub.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findhub.obj `if test -f '../../cf-agent/findhub.c'; then $(CYGPATH_W) '../../cf-agent/findhub.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/findhub.c'; fi` load_avahi.o: ../../cf-agent/load_avahi.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT load_avahi.o -MD -MP -MF $(DEPDIR)/load_avahi.Tpo -c -o load_avahi.o `test -f '../../cf-agent/load_avahi.c' || echo '$(srcdir)/'`../../cf-agent/load_avahi.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/load_avahi.Tpo $(DEPDIR)/load_avahi.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/load_avahi.c' object='load_avahi.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o load_avahi.o `test -f '../../cf-agent/load_avahi.c' || echo '$(srcdir)/'`../../cf-agent/load_avahi.c load_avahi.obj: ../../cf-agent/load_avahi.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT load_avahi.obj -MD -MP -MF $(DEPDIR)/load_avahi.Tpo -c -o load_avahi.obj `if test -f '../../cf-agent/load_avahi.c'; then $(CYGPATH_W) '../../cf-agent/load_avahi.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/load_avahi.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/load_avahi.Tpo $(DEPDIR)/load_avahi.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/load_avahi.c' object='load_avahi.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o load_avahi.obj `if test -f '../../cf-agent/load_avahi.c'; then $(CYGPATH_W) '../../cf-agent/load_avahi.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/load_avahi.c'; fi` statistics.o: ../../libntech/libutils/statistics.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT statistics.o -MD -MP -MF $(DEPDIR)/statistics.Tpo -c -o statistics.o `test -f '../../libntech/libutils/statistics.c' || echo '$(srcdir)/'`../../libntech/libutils/statistics.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/statistics.Tpo $(DEPDIR)/statistics.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/statistics.c' object='statistics.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o statistics.o `test -f '../../libntech/libutils/statistics.c' || echo '$(srcdir)/'`../../libntech/libutils/statistics.c statistics.obj: ../../libntech/libutils/statistics.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT statistics.obj -MD -MP -MF $(DEPDIR)/statistics.Tpo -c -o statistics.obj `if test -f '../../libntech/libutils/statistics.c'; then $(CYGPATH_W) '../../libntech/libutils/statistics.c'; else $(CYGPATH_W) '$(srcdir)/../../libntech/libutils/statistics.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/statistics.Tpo $(DEPDIR)/statistics.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libntech/libutils/statistics.c' object='statistics.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o statistics.obj `if test -f '../../libntech/libutils/statistics.c'; then $(CYGPATH_W) '../../libntech/libutils/statistics.c'; else $(CYGPATH_W) '$(srcdir)/../../libntech/libutils/statistics.c'; fi` process_linux.o: ../../libpromises/process_linux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_linux.o -MD -MP -MF $(DEPDIR)/process_linux.Tpo -c -o process_linux.o `test -f '../../libpromises/process_linux.c' || echo '$(srcdir)/'`../../libpromises/process_linux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_linux.Tpo $(DEPDIR)/process_linux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_linux.c' object='process_linux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_linux.o `test -f '../../libpromises/process_linux.c' || echo '$(srcdir)/'`../../libpromises/process_linux.c process_linux.obj: ../../libpromises/process_linux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_linux.obj -MD -MP -MF $(DEPDIR)/process_linux.Tpo -c -o process_linux.obj `if test -f '../../libpromises/process_linux.c'; then $(CYGPATH_W) '../../libpromises/process_linux.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_linux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_linux.Tpo $(DEPDIR)/process_linux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_linux.c' object='process_linux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_linux.obj `if test -f '../../libpromises/process_linux.c'; then $(CYGPATH_W) '../../libpromises/process_linux.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_linux.c'; fi` syslog_client.o: ../../libpromises/syslog_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT syslog_client.o -MD -MP -MF $(DEPDIR)/syslog_client.Tpo -c -o syslog_client.o `test -f '../../libpromises/syslog_client.c' || echo '$(srcdir)/'`../../libpromises/syslog_client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/syslog_client.Tpo $(DEPDIR)/syslog_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/syslog_client.c' object='syslog_client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o syslog_client.o `test -f '../../libpromises/syslog_client.c' || echo '$(srcdir)/'`../../libpromises/syslog_client.c syslog_client.obj: ../../libpromises/syslog_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT syslog_client.obj -MD -MP -MF $(DEPDIR)/syslog_client.Tpo -c -o syslog_client.obj `if test -f '../../libpromises/syslog_client.c'; then $(CYGPATH_W) '../../libpromises/syslog_client.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/syslog_client.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/syslog_client.Tpo $(DEPDIR)/syslog_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/syslog_client.c' object='syslog_client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o syslog_client.obj `if test -f '../../libpromises/syslog_client.c'; then $(CYGPATH_W) '../../libpromises/syslog_client.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/syslog_client.c'; fi` patches.o: ../../libpromises/patches.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT patches.o -MD -MP -MF $(DEPDIR)/patches.Tpo -c -o patches.o `test -f '../../libpromises/patches.c' || echo '$(srcdir)/'`../../libpromises/patches.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/patches.Tpo $(DEPDIR)/patches.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/patches.c' object='patches.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o patches.o `test -f '../../libpromises/patches.c' || echo '$(srcdir)/'`../../libpromises/patches.c patches.obj: ../../libpromises/patches.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT patches.obj -MD -MP -MF $(DEPDIR)/patches.Tpo -c -o patches.obj `if test -f '../../libpromises/patches.c'; then $(CYGPATH_W) '../../libpromises/patches.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/patches.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/patches.Tpo $(DEPDIR)/patches.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/patches.c' object='patches.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o patches.obj `if test -f '../../libpromises/patches.c'; then $(CYGPATH_W) '../../libpromises/patches.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/patches.c'; fi` constants.o: ../../libpromises/constants.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT constants.o -MD -MP -MF $(DEPDIR)/constants.Tpo -c -o constants.o `test -f '../../libpromises/constants.c' || echo '$(srcdir)/'`../../libpromises/constants.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/constants.Tpo $(DEPDIR)/constants.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/constants.c' object='constants.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o constants.o `test -f '../../libpromises/constants.c' || echo '$(srcdir)/'`../../libpromises/constants.c constants.obj: ../../libpromises/constants.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT constants.obj -MD -MP -MF $(DEPDIR)/constants.Tpo -c -o constants.obj `if test -f '../../libpromises/constants.c'; then $(CYGPATH_W) '../../libpromises/constants.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/constants.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/constants.Tpo $(DEPDIR)/constants.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/constants.c' object='constants.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o constants.obj `if test -f '../../libpromises/constants.c'; then $(CYGPATH_W) '../../libpromises/constants.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/constants.c'; fi` mon_cpu.o: ../../cf-monitord/mon_cpu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mon_cpu.o -MD -MP -MF $(DEPDIR)/mon_cpu.Tpo -c -o mon_cpu.o `test -f '../../cf-monitord/mon_cpu.c' || echo '$(srcdir)/'`../../cf-monitord/mon_cpu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mon_cpu.Tpo $(DEPDIR)/mon_cpu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-monitord/mon_cpu.c' object='mon_cpu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mon_cpu.o `test -f '../../cf-monitord/mon_cpu.c' || echo '$(srcdir)/'`../../cf-monitord/mon_cpu.c mon_cpu.obj: ../../cf-monitord/mon_cpu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mon_cpu.obj -MD -MP -MF $(DEPDIR)/mon_cpu.Tpo -c -o mon_cpu.obj `if test -f '../../cf-monitord/mon_cpu.c'; then $(CYGPATH_W) '../../cf-monitord/mon_cpu.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-monitord/mon_cpu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mon_cpu.Tpo $(DEPDIR)/mon_cpu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-monitord/mon_cpu.c' object='mon_cpu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mon_cpu.obj `if test -f '../../cf-monitord/mon_cpu.c'; then $(CYGPATH_W) '../../cf-monitord/mon_cpu.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-monitord/mon_cpu.c'; fi` mon_load.o: ../../cf-monitord/mon_load.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mon_load.o -MD -MP -MF $(DEPDIR)/mon_load.Tpo -c -o mon_load.o `test -f '../../cf-monitord/mon_load.c' || echo '$(srcdir)/'`../../cf-monitord/mon_load.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mon_load.Tpo $(DEPDIR)/mon_load.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-monitord/mon_load.c' object='mon_load.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mon_load.o `test -f '../../cf-monitord/mon_load.c' || echo '$(srcdir)/'`../../cf-monitord/mon_load.c mon_load.obj: ../../cf-monitord/mon_load.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mon_load.obj -MD -MP -MF $(DEPDIR)/mon_load.Tpo -c -o mon_load.obj `if test -f '../../cf-monitord/mon_load.c'; then $(CYGPATH_W) '../../cf-monitord/mon_load.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-monitord/mon_load.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mon_load.Tpo $(DEPDIR)/mon_load.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-monitord/mon_load.c' object='mon_load.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mon_load.obj `if test -f '../../cf-monitord/mon_load.c'; then $(CYGPATH_W) '../../cf-monitord/mon_load.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-monitord/mon_load.c'; fi` mon_processes.o: ../../cf-monitord/mon_processes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mon_processes.o -MD -MP -MF $(DEPDIR)/mon_processes.Tpo -c -o mon_processes.o `test -f '../../cf-monitord/mon_processes.c' || echo '$(srcdir)/'`../../cf-monitord/mon_processes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mon_processes.Tpo $(DEPDIR)/mon_processes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-monitord/mon_processes.c' object='mon_processes.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mon_processes.o `test -f '../../cf-monitord/mon_processes.c' || echo '$(srcdir)/'`../../cf-monitord/mon_processes.c mon_processes.obj: ../../cf-monitord/mon_processes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mon_processes.obj -MD -MP -MF $(DEPDIR)/mon_processes.Tpo -c -o mon_processes.obj `if test -f '../../cf-monitord/mon_processes.c'; then $(CYGPATH_W) '../../cf-monitord/mon_processes.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-monitord/mon_processes.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mon_processes.Tpo $(DEPDIR)/mon_processes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-monitord/mon_processes.c' object='mon_processes.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mon_processes.obj `if test -f '../../cf-monitord/mon_processes.c'; then $(CYGPATH_W) '../../cf-monitord/mon_processes.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-monitord/mon_processes.c'; fi` package_module.o: ../../cf-agent/package_module.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT package_module.o -MD -MP -MF $(DEPDIR)/package_module.Tpo -c -o package_module.o `test -f '../../cf-agent/package_module.c' || echo '$(srcdir)/'`../../cf-agent/package_module.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/package_module.Tpo $(DEPDIR)/package_module.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/package_module.c' object='package_module.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o package_module.o `test -f '../../cf-agent/package_module.c' || echo '$(srcdir)/'`../../cf-agent/package_module.c package_module.obj: ../../cf-agent/package_module.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT package_module.obj -MD -MP -MF $(DEPDIR)/package_module.Tpo -c -o package_module.obj `if test -f '../../cf-agent/package_module.c'; then $(CYGPATH_W) '../../cf-agent/package_module.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/package_module.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/package_module.Tpo $(DEPDIR)/package_module.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/package_module.c' object='package_module.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o package_module.obj `if test -f '../../cf-agent/package_module.c'; then $(CYGPATH_W) '../../cf-agent/package_module.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/package_module.c'; fi` verify_packages.o: ../../cf-agent/verify_packages.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT verify_packages.o -MD -MP -MF $(DEPDIR)/verify_packages.Tpo -c -o verify_packages.o `test -f '../../cf-agent/verify_packages.c' || echo '$(srcdir)/'`../../cf-agent/verify_packages.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/verify_packages.Tpo $(DEPDIR)/verify_packages.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/verify_packages.c' object='verify_packages.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o verify_packages.o `test -f '../../cf-agent/verify_packages.c' || echo '$(srcdir)/'`../../cf-agent/verify_packages.c verify_packages.obj: ../../cf-agent/verify_packages.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT verify_packages.obj -MD -MP -MF $(DEPDIR)/verify_packages.Tpo -c -o verify_packages.obj `if test -f '../../cf-agent/verify_packages.c'; then $(CYGPATH_W) '../../cf-agent/verify_packages.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/verify_packages.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/verify_packages.Tpo $(DEPDIR)/verify_packages.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/verify_packages.c' object='verify_packages.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o verify_packages.obj `if test -f '../../cf-agent/verify_packages.c'; then $(CYGPATH_W) '../../cf-agent/verify_packages.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/verify_packages.c'; fi` verify_new_packages.o: ../../cf-agent/verify_new_packages.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT verify_new_packages.o -MD -MP -MF $(DEPDIR)/verify_new_packages.Tpo -c -o verify_new_packages.o `test -f '../../cf-agent/verify_new_packages.c' || echo '$(srcdir)/'`../../cf-agent/verify_new_packages.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/verify_new_packages.Tpo $(DEPDIR)/verify_new_packages.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/verify_new_packages.c' object='verify_new_packages.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o verify_new_packages.o `test -f '../../cf-agent/verify_new_packages.c' || echo '$(srcdir)/'`../../cf-agent/verify_new_packages.c verify_new_packages.obj: ../../cf-agent/verify_new_packages.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT verify_new_packages.obj -MD -MP -MF $(DEPDIR)/verify_new_packages.Tpo -c -o verify_new_packages.obj `if test -f '../../cf-agent/verify_new_packages.c'; then $(CYGPATH_W) '../../cf-agent/verify_new_packages.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/verify_new_packages.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/verify_new_packages.Tpo $(DEPDIR)/verify_new_packages.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/verify_new_packages.c' object='verify_new_packages.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o verify_new_packages.obj `if test -f '../../cf-agent/verify_new_packages.c'; then $(CYGPATH_W) '../../cf-agent/verify_new_packages.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/verify_new_packages.c'; fi` vercmp.o: ../../cf-agent/vercmp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vercmp.o -MD -MP -MF $(DEPDIR)/vercmp.Tpo -c -o vercmp.o `test -f '../../cf-agent/vercmp.c' || echo '$(srcdir)/'`../../cf-agent/vercmp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vercmp.Tpo $(DEPDIR)/vercmp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/vercmp.c' object='vercmp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vercmp.o `test -f '../../cf-agent/vercmp.c' || echo '$(srcdir)/'`../../cf-agent/vercmp.c vercmp.obj: ../../cf-agent/vercmp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vercmp.obj -MD -MP -MF $(DEPDIR)/vercmp.Tpo -c -o vercmp.obj `if test -f '../../cf-agent/vercmp.c'; then $(CYGPATH_W) '../../cf-agent/vercmp.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/vercmp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vercmp.Tpo $(DEPDIR)/vercmp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/vercmp.c' object='vercmp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vercmp.obj `if test -f '../../cf-agent/vercmp.c'; then $(CYGPATH_W) '../../cf-agent/vercmp.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/vercmp.c'; fi` vercmp_internal.o: ../../cf-agent/vercmp_internal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vercmp_internal.o -MD -MP -MF $(DEPDIR)/vercmp_internal.Tpo -c -o vercmp_internal.o `test -f '../../cf-agent/vercmp_internal.c' || echo '$(srcdir)/'`../../cf-agent/vercmp_internal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vercmp_internal.Tpo $(DEPDIR)/vercmp_internal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/vercmp_internal.c' object='vercmp_internal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vercmp_internal.o `test -f '../../cf-agent/vercmp_internal.c' || echo '$(srcdir)/'`../../cf-agent/vercmp_internal.c vercmp_internal.obj: ../../cf-agent/vercmp_internal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vercmp_internal.obj -MD -MP -MF $(DEPDIR)/vercmp_internal.Tpo -c -o vercmp_internal.obj `if test -f '../../cf-agent/vercmp_internal.c'; then $(CYGPATH_W) '../../cf-agent/vercmp_internal.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/vercmp_internal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vercmp_internal.Tpo $(DEPDIR)/vercmp_internal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/vercmp_internal.c' object='vercmp_internal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vercmp_internal.obj `if test -f '../../cf-agent/vercmp_internal.c'; then $(CYGPATH_W) '../../cf-agent/vercmp_internal.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/vercmp_internal.c'; fi` retcode.o: ../../cf-agent/retcode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT retcode.o -MD -MP -MF $(DEPDIR)/retcode.Tpo -c -o retcode.o `test -f '../../cf-agent/retcode.c' || echo '$(srcdir)/'`../../cf-agent/retcode.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/retcode.Tpo $(DEPDIR)/retcode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/retcode.c' object='retcode.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o retcode.o `test -f '../../cf-agent/retcode.c' || echo '$(srcdir)/'`../../cf-agent/retcode.c retcode.obj: ../../cf-agent/retcode.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT retcode.obj -MD -MP -MF $(DEPDIR)/retcode.Tpo -c -o retcode.obj `if test -f '../../cf-agent/retcode.c'; then $(CYGPATH_W) '../../cf-agent/retcode.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/retcode.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/retcode.Tpo $(DEPDIR)/retcode.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-agent/retcode.c' object='retcode.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o retcode.obj `if test -f '../../cf-agent/retcode.c'; then $(CYGPATH_W) '../../cf-agent/retcode.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-agent/retcode.c'; fi` match_scope.o: ../../libpromises/match_scope.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT match_scope.o -MD -MP -MF $(DEPDIR)/match_scope.Tpo -c -o match_scope.o `test -f '../../libpromises/match_scope.c' || echo '$(srcdir)/'`../../libpromises/match_scope.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/match_scope.Tpo $(DEPDIR)/match_scope.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/match_scope.c' object='match_scope.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o match_scope.o `test -f '../../libpromises/match_scope.c' || echo '$(srcdir)/'`../../libpromises/match_scope.c match_scope.obj: ../../libpromises/match_scope.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT match_scope.obj -MD -MP -MF $(DEPDIR)/match_scope.Tpo -c -o match_scope.obj `if test -f '../../libpromises/match_scope.c'; then $(CYGPATH_W) '../../libpromises/match_scope.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/match_scope.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/match_scope.Tpo $(DEPDIR)/match_scope.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/match_scope.c' object='match_scope.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o match_scope.obj `if test -f '../../libpromises/match_scope.c'; then $(CYGPATH_W) '../../libpromises/match_scope.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/match_scope.c'; fi` cf-serverd-functions.o: ../../cf-serverd/cf-serverd-functions.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf-serverd-functions.o -MD -MP -MF $(DEPDIR)/cf-serverd-functions.Tpo -c -o cf-serverd-functions.o `test -f '../../cf-serverd/cf-serverd-functions.c' || echo '$(srcdir)/'`../../cf-serverd/cf-serverd-functions.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf-serverd-functions.Tpo $(DEPDIR)/cf-serverd-functions.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/cf-serverd-functions.c' object='cf-serverd-functions.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf-serverd-functions.o `test -f '../../cf-serverd/cf-serverd-functions.c' || echo '$(srcdir)/'`../../cf-serverd/cf-serverd-functions.c cf-serverd-functions.obj: ../../cf-serverd/cf-serverd-functions.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cf-serverd-functions.obj -MD -MP -MF $(DEPDIR)/cf-serverd-functions.Tpo -c -o cf-serverd-functions.obj `if test -f '../../cf-serverd/cf-serverd-functions.c'; then $(CYGPATH_W) '../../cf-serverd/cf-serverd-functions.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/cf-serverd-functions.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf-serverd-functions.Tpo $(DEPDIR)/cf-serverd-functions.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../cf-serverd/cf-serverd-functions.c' object='cf-serverd-functions.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cf-serverd-functions.obj `if test -f '../../cf-serverd/cf-serverd-functions.c'; then $(CYGPATH_W) '../../cf-serverd/cf-serverd-functions.c'; else $(CYGPATH_W) '$(srcdir)/../../cf-serverd/cf-serverd-functions.c'; fi` rlist_test-rlist_test.o: rlist_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rlist_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rlist_test-rlist_test.o -MD -MP -MF $(DEPDIR)/rlist_test-rlist_test.Tpo -c -o rlist_test-rlist_test.o `test -f 'rlist_test.c' || echo '$(srcdir)/'`rlist_test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rlist_test-rlist_test.Tpo $(DEPDIR)/rlist_test-rlist_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rlist_test.c' object='rlist_test-rlist_test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rlist_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rlist_test-rlist_test.o `test -f 'rlist_test.c' || echo '$(srcdir)/'`rlist_test.c rlist_test-rlist_test.obj: rlist_test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rlist_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rlist_test-rlist_test.obj -MD -MP -MF $(DEPDIR)/rlist_test-rlist_test.Tpo -c -o rlist_test-rlist_test.obj `if test -f 'rlist_test.c'; then $(CYGPATH_W) 'rlist_test.c'; else $(CYGPATH_W) '$(srcdir)/rlist_test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rlist_test-rlist_test.Tpo $(DEPDIR)/rlist_test-rlist_test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rlist_test.c' object='rlist_test-rlist_test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rlist_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rlist_test-rlist_test.obj `if test -f 'rlist_test.c'; then $(CYGPATH_W) 'rlist_test.c'; else $(CYGPATH_W) '$(srcdir)/rlist_test.c'; fi` process_solaris.o: ../../libpromises/process_solaris.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_solaris.o -MD -MP -MF $(DEPDIR)/process_solaris.Tpo -c -o process_solaris.o `test -f '../../libpromises/process_solaris.c' || echo '$(srcdir)/'`../../libpromises/process_solaris.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_solaris.Tpo $(DEPDIR)/process_solaris.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_solaris.c' object='process_solaris.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_solaris.o `test -f '../../libpromises/process_solaris.c' || echo '$(srcdir)/'`../../libpromises/process_solaris.c process_solaris.obj: ../../libpromises/process_solaris.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT process_solaris.obj -MD -MP -MF $(DEPDIR)/process_solaris.Tpo -c -o process_solaris.obj `if test -f '../../libpromises/process_solaris.c'; then $(CYGPATH_W) '../../libpromises/process_solaris.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_solaris.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/process_solaris.Tpo $(DEPDIR)/process_solaris.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../libpromises/process_solaris.c' object='process_solaris.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o process_solaris.obj `if test -f '../../libpromises/process_solaris.c'; then $(CYGPATH_W) '../../libpromises/process_solaris.c'; else $(CYGPATH_W) '$(srcdir)/../../libpromises/process_solaris.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) \ $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile @NT_FALSE@init_script_test.sh: init_script_test_helper # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/unit/changes_migration_test.c0000644000000000000000000001404515010704253022364 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /* xsnprintf */ #include #define NO_FILES 4 char *CHECKSUM_VALUE[NO_FILES] = { "0001", "0002", "0003", "0004", }; struct stat filestat_value; static void test_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/changes_migration_test.XXXXXX"; char *workdir = strchr(env, '=') + 1; /* start of the path */ assert(workdir - 1 && workdir[0] == '/'); mkdtemp(workdir); putenv(env); mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); CF_DB *db; assert_true(OpenDB(&db, dbid_checksums)); // Hand crafted from the old version of NewIndexKey(). char checksum_key[NO_FILES][30] = { { 'M','D','5','\0','\0','\0','\0','\0', '/','e','t','c','/','h','o','s','t','s','\0' }, { 'M','D','5','\0','\0','\0','\0','\0', '/','e','t','c','/','p','a','s','s','w','d','\0' }, { 'M','D','5','\0','\0','\0','\0','\0', '/','f','i','l','e','1','\0' }, { 'M','D','5','\0','\0','\0','\0','\0', '/','f','i','l','e','2','\0' }, }; for (int c = 0; c < NO_FILES; c++) { int ksize = CHANGES_HASH_FILE_NAME_OFFSET + strlen(checksum_key[c] + CHANGES_HASH_FILE_NAME_OFFSET) + 1; int vsize = strlen(CHECKSUM_VALUE[c]) + 1; assert_true(WriteComplexKeyDB(db, checksum_key[c], ksize, CHECKSUM_VALUE[c], vsize)); } CloseDB(db); assert_true(OpenDB(&db, dbid_filestats)); char *filestat_key[NO_FILES] = { "/etc/hosts", "/etc/passwd", "/file1", "/file2", }; filestat_value.st_uid = 4321; memset(&filestat_value, 0, sizeof(filestat_value)); for (int c = 0; c < NO_FILES; c++) { assert_true(WriteDB(db, filestat_key[c], &filestat_value, sizeof(filestat_value))); } CloseDB(db); } static void test_migration(void) { CF_DB *db; Seq *list = SeqNew(NO_FILES, free); // Hand crafted from the new version of NewIndexKey(). char checksum_key[NO_FILES][30] = { { 'H','_','M','D','5','\0','\0','\0','\0','\0', '/','e','t','c','/','h','o','s','t','s','\0' }, { 'H','_','M','D','5','\0','\0','\0','\0','\0', '/','e','t','c','/','p','a','s','s','w','d','\0' }, { 'H','_','M','D','5','\0','\0','\0','\0','\0', '/','f','i','l','e','1','\0' }, { 'H','_','M','D','5','\0','\0','\0','\0','\0', '/','f','i','l','e','2','\0' }, }; char *filestat_key[NO_FILES] = { "S_/etc/hosts", "S_/etc/passwd", "S_/file1", "S_/file2", }; // Should cause migration to happen. assert_true(FileChangesGetDirectoryList("/etc", list)); assert_int_equal(SeqLength(list), 2); assert_string_equal(SeqAt(list, 0), "hosts"); assert_string_equal(SeqAt(list, 1), "passwd"); SeqClear(list); assert_true(FileChangesGetDirectoryList("/", list)); assert_int_equal(SeqLength(list), 2); assert_string_equal(SeqAt(list, 0), "file1"); assert_string_equal(SeqAt(list, 1), "file2"); SeqDestroy(list); assert_true(OpenDB(&db, dbid_changes)); for (int c = 0; c < NO_FILES; c++) { { int ksize = 2 + CHANGES_HASH_FILE_NAME_OFFSET + strlen(checksum_key[c] + 2 + CHANGES_HASH_FILE_NAME_OFFSET) + 1; int vsize = ValueSizeDB(db, checksum_key[c], ksize); assert_int_equal(vsize, strlen(CHECKSUM_VALUE[c]) + 1); char value[vsize]; assert_true(ReadComplexKeyDB(db, checksum_key[c], ksize, value, vsize)); assert_int_equal(memcmp(value, CHECKSUM_VALUE[c], vsize), 0); } { int vsize = ValueSizeDB(db, filestat_key[c], strlen(filestat_key[c]) + 1); assert_int_equal(vsize, sizeof(struct stat)); char value[vsize]; assert_true(ReadDB(db, filestat_key[c], value, vsize)); assert_int_equal(memcmp(value, &filestat_value, vsize), 0); } } int db_entries = 0; CF_DBC *db_cursor; assert_true(NewDBCursor(db, &db_cursor)); char *key, *value; int ksize, vsize; while (NextDB(db_cursor, &key, &ksize, (void **)&value, &vsize)) { db_entries++; } DeleteDBCursor(db_cursor); // 2 x Directories ("/" and "/etc") // 4 x File hashes // 4 x File stats assert_int_equal(db_entries, 10); CloseDB(db); } static void test_teardown(void) { DeleteDirectoryTree(GetWorkDir()); rmdir(GetWorkDir()); } int main() { const UnitTest tests[] = { unit_test(test_setup), unit_test(test_migration), unit_test(test_teardown), }; PRINT_TEST_BANNER(); int ret = run_tests(tests); return ret; } cfengine-3.24.2/tests/unit/mon_processes_test.c0000644000000000000000000001041315010704253021555 0ustar00rootroot00000000000000#include "test.h" #include "systype.h" #include "generic_agent.h" #include "item_lib.h" #include "mon.h" #include /* LogSetGlobalLevel */ #include /* xsnprintf */ #include char CFWORKDIR[CF_BUFSIZE]; static void tests_setup(void) { xsnprintf(CFWORKDIR, CF_BUFSIZE, "/tmp/mon_processes_test.XXXXXX"); mkdtemp(CFWORKDIR); char buf[CF_BUFSIZE]; xsnprintf(buf, CF_BUFSIZE, "%s", GetStateDir()); mkdir(buf, 0755); } static void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } static bool GetSysUsers( int *userListSz, int *numRootProcs, int *numOtherProcs) { FILE *fp; char user[CF_BUFSIZE]; char vbuff[CF_BUFSIZE]; char cbuff[CF_BUFSIZE]; /* * The best would be to ask only "user" field from ps, but we are asking * for "user,pid". The reason is that we try to mimic cf-monitord's * behaviour, else a different number of users might be detected by the * test, as printing "user,pid" truncates the user column. TODO fix the * ps command to use only "-o user" in both mon_processes.c and this test. */ #if defined(__sun) xsnprintf(cbuff, CF_BUFSIZE, "/bin/ps -eo user,pid > %s/users.txt", CFWORKDIR); #elif defined(_AIX) xsnprintf(cbuff, CF_BUFSIZE, "/bin/ps -N -eo user,pid > %s/users.txt", CFWORKDIR); #elif defined(__hpux) xsnprintf(cbuff, CF_BUFSIZE, "UNIX95=1 /bin/ps -eo user,pid > %s/users.txt", CFWORKDIR); /* SKIP on HP-UX since cf-monitord doesn't count processes correctly! */ return false; #else xsnprintf(cbuff, CF_BUFSIZE, "ps -eo user:30,pid > %s/users.txt", CFWORKDIR); #endif Item *userList = NULL; system(cbuff); xsnprintf(cbuff, CF_BUFSIZE, "%s/users.txt", CFWORKDIR); if ((fp = fopen(cbuff, "r")) == NULL) { return false; } while (fgets(vbuff, CF_BUFSIZE, fp) != NULL) { int ret = sscanf(vbuff, " %s ", user); if (ret != 1 || strcmp(user, "") == 0 || strcmp(user, "USER") == 0 || isdigit(user[0])) { continue; } if (!IsItemIn(userList, user)) { PrependItem(&userList, user, NULL); (*userListSz)++; } if (strcmp(user, "root") == 0) { (*numRootProcs)++; } else { (*numOtherProcs)++; } } fclose(fp); if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { char *s = ItemList2CSV(userList); Log(LOG_LEVEL_DEBUG, "Users in the process table detected from the test: (%s)", s); free(s); } DeleteItemList(userList); return true; } void test_processes_monitor(void) { double cf_this[100] = { 0.0 }; MonProcessesGatherData(cf_this); MonProcessesGatherData(cf_this); MonProcessesGatherData(cf_this); int usr, rusr, ousr; usr = rusr = ousr = 0; bool res = GetSysUsers(&usr, &rusr, &ousr); if (!res) { Log(LOG_LEVEL_NOTICE, "TEST SKIPPED!"); return; } usr = 3*usr; rusr = 3*rusr; ousr = 3*ousr; Log(LOG_LEVEL_NOTICE, "Counted %d/3 different users on the process table," " while CFEngine counted %f/3", usr, cf_this[ob_users]); Log(LOG_LEVEL_NOTICE, "This is a non-deterministic test," " the two numbers should be *about* the same since the 'ps'" " commands run very close to each other"); int upper = (int) ((double) usr*1.20); int lower = (int) ((double) usr*0.80); assert_in_range((long long) cf_this[ob_users], lower, upper); } int main() { LogSetGlobalLevel(LOG_LEVEL_DEBUG); strcpy(CFWORKDIR, "data"); #if defined(__sun) VSYSTEMHARDCLASS = PLATFORM_CONTEXT_SOLARIS; VPSHARDCLASS = PLATFORM_CONTEXT_SOLARIS; #elif defined(_AIX) VSYSTEMHARDCLASS = PLATFORM_CONTEXT_AIX; VPSHARDCLASS = PLATFORM_CONTEXT_AIX; #elif defined(__linux__) VSYSTEMHARDCLASS = PLATFORM_CONTEXT_LINUX; VPSHARDCLASS = PLATFORM_CONTEXT_LINUX; #endif PRINT_TEST_BANNER(); tests_setup(); const UnitTest tests[] = { unit_test(test_processes_monitor), }; int ret = run_tests(tests); tests_teardown(); return ret; } cfengine-3.24.2/tests/unit/README0000644000000000000000000000640415010704253016360 0ustar00rootroot00000000000000How to add unit tests ===================== 1. Make sure what you are trying to write is actually a unit test. A unit test should execute in milliseconds. If you are testing functionality that e.g. requires a generic agent to be set up, consider writing an acceptance test. A unit test should test a small piece of code (a function) in isolation. 2. You typically want to test some function of a datastructure, e.g. CfAssoc. Check to see if a test suite (e.g. assoc_test.c), exists already. If not, create one. 2.1 (Optional) Creating a new test suite Create a new file, e.g. mystruct_test.c, preferably by copying some existing file so you get the boilerplate. In Makefile.am, append mystruct_test to check_PROGRAMS, and add an automake entry such as mystruct_test_SOURCES = $(MOCKERY_SOURCES) mystruct_test.c mystruct_test_LDADD = ../../libpromises/libpromises.la 3. We are using cmockery as our testing framework. Google for it and read/skim their basic intro page. 4. Suppose you want to test your new ToString function for CfAssoc. In assoc_test.c, you could do the following. 4.1 Write the test static test_to_string(void **state) { /* assert some condition here */ } 4.2 In the main function of assoc_test.c, add the test to the suite int main() { const UnitTest tests[] = { unit_test(test_create_destroy), unit_test(test_copy), unit_test(test_to_string) }; return run_tests(tests); } 5. Mocking. Suppose you want to test some function that calls a database, but you don't want to deal with setting up and managing the state of the database. Furthermore, you don't actually want to test the database in this test. What you need to do is to stub out the function. For example, suppose your tested function calls some DB_Insert("host123", 42); A mock function is a dummy replacement function with NOOP functionality, so in this case, in your test suite, you could add a static int written_measure = -1; static void DB_Insert(const char* key, int measure) { written_measure = measure; } Then, if later your function tries to retrieve it back, you could do static int DB_Query(const char*key) { return written_measure; } Now, the key is to not have the test link towards the actual definition of the function, so in Makefile.am, rather than linking against all of libpromises, you probably want to be more specific, for example str_test_SOURCES = $(MOCKERY_SOURCES) str_test.c ../../libpromises/string_lib.c str_test_LDADD = ../../libcompat/libcompat.la Finally, if you made some mocking functions and you think it will be useful to other tests later, consider extracting them in a separate file, e.g. db_mock.c. 6. Memory checking. We don't really care about the quality of code in the unit tests, but we do care that the code tested is not leaking memory. So it's important to free everything you allocate in the test code. Then, to check to see if your code leaks, you can run valgrind --leak-check=yes .libs/lt-mystruct_test Valgrind can do stuff beyond simple leak checking, so learning about it could be a worthwhile investment. cfengine-3.24.2/tests/unit/rlist_test.c0000644000000000000000000006154715010704253020051 0ustar00rootroot00000000000000#include #include #include #include #include #include /* Stubs */ void FatalError(ARG_UNUSED char *s, ...) { mock_assert(0, "0", __FILE__, __LINE__); abort(); } static void test_length(void) { Rlist *list = NULL; assert_int_equal(RlistLen(list), 0); RlistPrepend(&list, "stuff", RVAL_TYPE_SCALAR); assert_int_equal(RlistLen(list), 1); RlistPrepend(&list, "more-stuff", RVAL_TYPE_SCALAR); assert_int_equal(RlistLen(list), 2); RlistDestroy(list); } static void test_equality(void) { Rlist *list1 = RlistFromSplitString("a,b,c", ','); Rlist *list2 = RlistFromSplitString("a,b,c", ','); Rlist *list3 = RlistFromSplitString("z,b,c", ','); Rlist *list4 = RlistFromSplitString("a,b,c,d", ','); assert_true(RlistEqual(list1, list2)); assert_false(RlistEqual(list1, list3)); assert_false(RlistEqual(list1, list4)); RlistDestroy(list1); RlistDestroy(list2); RlistDestroy(list3); RlistDestroy(list4); } static void test_prepend_scalar_idempotent(void) { Rlist *list = NULL; RlistPrependScalarIdemp(&list, "stuff"); RlistPrependScalarIdemp(&list, "stuff"); assert_string_equal(RlistScalarValue(list), "stuff"); assert_int_equal(RlistLen(list), 1); RlistDestroy(list); } static void test_copy(void) { Rlist *list = NULL, *copy = NULL; RlistPrepend(&list, "stuff", RVAL_TYPE_SCALAR); RlistPrepend(&list, "more-stuff", RVAL_TYPE_SCALAR); copy = RlistCopy(list); assert_string_equal(RlistScalarValue(list), RlistScalarValue(copy)); assert_string_equal(RlistScalarValue(list->next), RlistScalarValue(copy->next)); RlistDestroy(list); RlistDestroy(copy); } static void test_rval_to_scalar(void) { Rval rval = { "abc", RVAL_TYPE_SCALAR }; assert_string_equal("abc", RvalScalarValue(rval)); } static void test_rval_to_scalar2(void) { Rval rval = { NULL, RVAL_TYPE_FNCALL }; expect_assert_failure(RvalScalarValue(rval)); } static void test_rval_to_list(void) { Rval rval = { NULL, RVAL_TYPE_SCALAR }; expect_assert_failure(RvalRlistValue(rval)); } static void test_rval_to_list2(void) { Rval rval = { NULL, RVAL_TYPE_LIST }; assert_false(RvalRlistValue(rval)); } static void test_rval_to_fncall(void) { Rval rval = { NULL, RVAL_TYPE_SCALAR }; expect_assert_failure(RvalFnCallValue(rval)); } static void test_rval_to_fncall2(void) { Rval rval = { NULL, RVAL_TYPE_FNCALL }; assert_false(RvalFnCallValue(rval)); } static void test_last(void) { Rlist *l = NULL; assert_true(RlistLast(l) == NULL); RlistAppendScalar(&l, "a"); assert_string_equal("a", RlistScalarValue(RlistLast(l))); RlistAppendScalar(&l, "b"); assert_string_equal("b", RlistScalarValue(RlistLast(l))); RlistDestroy(l); } static bool is_even(void *item, void *data) { // What does this function do? long d = StringToLongDefaultOnError(data, 0); long i = StringToLongExitOnError(item); return i % 2 == d; } static void test_filter(void) { Rlist *list = NULL; for (int i = 0; i < 10; i++) { char *item = StringFromLong(i); RlistAppend(&list, item, RVAL_TYPE_SCALAR); free(item); } assert_int_equal(10, RlistLen(list)); int mod_by = 0; RlistFilter(&list, is_even, &mod_by, free); assert_int_equal(5, RlistLen(list)); int i = 0; for (Rlist *rp = list; rp; rp = rp->next) { int k = StringToLongExitOnError(rp->val.item); assert_int_equal(i, k); i += 2; } RlistDestroy(list); } static void test_filter_everything(void) { Rlist *list = NULL; for (int i = 1; i < 10; i += 2) { char *item = StringFromLong(i); RlistAppend(&list, item, RVAL_TYPE_SCALAR); free(item); } assert_int_equal(5, RlistLen(list)); int mod_by = 0; RlistFilter(&list, is_even, &mod_by, free); assert_int_equal(0, RlistLen(list)); assert_true(list == NULL); } static void test_reverse(void) { Rlist *list = RlistFromSplitString("a,b,c", ','); RlistReverse(&list); assert_int_equal(3, RlistLen(list)); assert_string_equal("c", RlistScalarValue(list)); assert_string_equal("b", RlistScalarValue(list->next)); assert_string_equal("a", RlistScalarValue(list->next->next)); RlistDestroy(list); } static void test_split_escaped(void) { Rlist *list = RlistFromSplitString("a\\,b\\c\\,d,w\\,x\\,y\\,z", ','); assert_int_equal(2, RlistLen(list)); assert_string_equal("a,b\\c,d", RlistScalarValue(list)); assert_string_equal("w,x,y,z", RlistScalarValue(list->next)); RlistDestroy(list); } static void test_split_lines(void) { Rlist *list = RlistFromStringSplitLines(NULL, true); assert_true(list == NULL); list = RlistFromStringSplitLines(NULL, false); assert_true(list == NULL); list = RlistFromStringSplitLines("hello\nworld!\nCheers!\n", true); assert_int_equal(3, RlistLen(list)); assert_string_equal("hello", RlistScalarValue(list)); assert_string_equal("world!", RlistScalarValue(list->next)); assert_string_equal("Cheers!", RlistScalarValue(list->next->next)); /* no empty string here as the last item */ RlistDestroy(list); /* one extra blank line */ list = RlistFromStringSplitLines("hello\nworld!\nCheers!\n\n", true); assert_int_equal(4, RlistLen(list)); assert_string_equal("hello", RlistScalarValue(list)); assert_string_equal("world!", RlistScalarValue(list->next)); assert_string_equal("Cheers!", RlistScalarValue(list->next->next)); assert_string_equal("", RlistScalarValue(list->next->next->next)); RlistDestroy(list); list = RlistFromStringSplitLines("hello\r\nworld!\r\nCheers!\r\n", true); assert_int_equal(3, RlistLen(list)); assert_string_equal("hello", RlistScalarValue(list)); assert_string_equal("world!", RlistScalarValue(list->next)); assert_string_equal("Cheers!", RlistScalarValue(list->next->next)); /* no empty string here as the last item */ RlistDestroy(list); /* one extra blank line */ list = RlistFromStringSplitLines("hello\r\nworld!\r\nCheers!\r\n\r\n", true); assert_int_equal(4, RlistLen(list)); assert_string_equal("hello", RlistScalarValue(list)); assert_string_equal("world!", RlistScalarValue(list->next)); assert_string_equal("Cheers!", RlistScalarValue(list->next->next)); assert_string_equal("", RlistScalarValue(list->next->next->next)); RlistDestroy(list); /* UNIX-like newlines only */ list = RlistFromStringSplitLines("hello\r\nworld!\r\nCheers!\r\n\r\n", false); assert_int_equal(4, RlistLen(list)); assert_string_equal("hello\r", RlistScalarValue(list)); assert_string_equal("world!\r", RlistScalarValue(list->next)); assert_string_equal("Cheers!\r", RlistScalarValue(list->next->next)); assert_string_equal("\r", RlistScalarValue(list->next->next->next)); RlistDestroy(list); } static void test_split_long(void) { char buf[CF_MAXVARSIZE * 2], *tail = buf + CF_MAXVARSIZE; memset(buf, '$', sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; buf[CF_MAXVARSIZE - 1] = ','; Rlist *list = RlistFromSplitString(buf, ','); assert_int_equal(2, RlistLen(list)); assert_string_equal(tail, RlistScalarValue(list)); assert_string_equal(tail, RlistScalarValue(list->next)); RlistDestroy(list); } static void test_split_long_escaped(void) { char buf[CF_MAXVARSIZE * 2 + 2], *tail = buf + CF_MAXVARSIZE + 1; memset(buf, '$', sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; buf[CF_MAXVARSIZE] = ','; memcpy(buf + CF_MAXVARSIZE / 2, "\\,", 2); memcpy(tail + CF_MAXVARSIZE / 2, "\\,", 2); Rlist *list = RlistFromSplitString(buf, ','); assert_int_equal(2, RlistLen(list)); tail[CF_MAXVARSIZE / 2] = '$'; /* blot out the back-slash */ assert_string_equal(tail + 1, RlistScalarValue(list)); assert_string_equal(tail + 1, RlistScalarValue(list->next)); RlistDestroy(list); } /***************************************************************************/ static struct ParseRoulette { int nfields; char *str; } PR[] = { /*Simple */ { 1, "{\"a\"}"}, { 2, "{\"a\",\"b\"}"}, { 3, "{\"a\",\"b\",\"c\"}"}, /*Simple empty */ { 1, "{\"\"}"}, { 2, "{\"\",\"\"}"}, { 3, "{\"\",\"\",\"\"}"}, /*Simple mixed kind of quotations */ { 1, "{\"'\"}"}, { 1, "{'\"'}"}, { 1, "{\",\"}"}, { 1, "{','}"}, { 1, "{\"\\\\\"}"}, { 1, "{'\\\\'}"}, { 1, "{\"}\"}"}, { 1, "{'}'}"}, { 1, "{\"{\"}"}, { 1, "{'{'}"}, { 1, "{\"'\"}"}, { 1, "{'\"'}"}, { 1, "{'\\\",'}"}, /* [",] */ { 1, "{\"\\',\"}"}, /* [",] */ { 1, "{',\\\"'}"}, /* [,"] */ { 1, "{\",\\'\"}"}, /* [,"] */ { 1, "{\",,\"}"}, /* [\\] */ { 1, "{',,'}"}, /* [\\] */ { 1, "{\"\\\\\\\\\"}"}, /* [\\] */ { 1, "{'\\\\\\\\'}"}, /* [\\] */ { 1, "{'\\\\\\\"'}"}, /* [\"] */ { 1, "{\"\\\\\\'\"}"}, /* [\"] */ { 1, "{'\\\"\\\\'}"}, /* ["\] */ { 1, "{\"\\'\\\\\"}"}, /* ["\] */ /*Very long */ { 1, "{\"AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA\"}"}, { 1, "{'AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA'}"}, { 2, "{\"Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa''aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA\" , \"Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\\bbbbbbbbbbbbbbbbbbbbbbbb\\\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb''bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbB\" }"}, { 2, "{'Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA' , 'Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\\bbbbbbbbbbbbbbbbbbbbbbbb\\\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbB' }"}, { 2, "{\"Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa''aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA\" , 'Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\\bbbbbbbbbbbbbbbbbbbbbbbb\\\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbB' }"}, /*Inner space (inside elements) */ { 1, "{\" \"}"}, { 1, "{\" \"}"}, { 1, "{\" \"}"}, { 1, "{\"\t\"}"}, /*Outer space (outside elements) */ { 1, " {\"\"} "}, { 1, " {\"a\"} "}, { 2, " {\"a\",\"b\"} "}, { 1, "{ \"a\" }"}, { 2, "{ \"a\",\"b\" }"}, { 2, "{ \"a\" ,\"b\" }"}, { 2, "{ \"a\", \"b\" }"}, { 2, "{ \"a\", \"b\"} "}, /*Normal */ { 4, " { \" ab,c,d\\\\ \" , ' e,f\\\"g ' ,\"hi\\\\jk\", \"l''m \" } "}, { 21, " { 'A\\\"\\\\ ', \" \\\\\", \"}B\", \"\\\\\\\\\" , \" \\\\C\\'\" , \"\\',\" , ',\\\"D' , \" ,, \", \"E\\\\\\\\F\", \"\", \"{\", \" G '\" , \"\\\\\\'\", ' \\\" H \\\\ ', \", ,\" , \"I\", \" \", \"\\' J \", '\\\",', \",\\'\", \",\" } "}, { 3, "{ \" aaa \", \" bbbb \" , \" cc \" } "}, { 3, " { \" a'a \", \" b''b \" , \" c'c \" } "}, { 3, " { ' a\"a ', ' b\"\"b ' , ' c\"c ' } "}, { 3, " { ' a\"a ', \" b''b \" , ' c\"c ' } "}, { 3, " { ' a,\"a } { ', \" } b','b \" , ' {, c\"c } ' } "}, { -1, (char *)NULL} }; static char *PFR[] = { /* trim left failure */ "", " ", "a", "\"", "'", "\"\"", "''", "'\"", "\"'", /* trim right failure */ "{", "{ ", "{a", "{\"", "{'", "{\"\"", "{''", "{\"'", /* parse failure */ /* un-even number of quotation marks */ "{\"\"\"}", "{\"\",\"}", "{\"\"\"\"}", "{\"\"\"\"\"}", "{\"\",\"\"\"}", "{\"\"\"\",\"}", "{\"\",\"\",\"}", "{'''}", "{'','}", "{''''}", "{'''''}", "{'','''}", "{'''','}", "{\"}", "{'}", "{'','','}", "{\"\"'}", "{\"\",'}", "{\"'\"'}", "{\"\"'\"\"}", "{\"\",'\"\"}", "{'\"\"\",\"}", "{'',\"\",'}", /* Misplaced commas*/ "{\"a\",}", "{,\"a\"}", "{,,\"a\"}", "{\"a\",,\"b\"}", "{'a',}", "{,'a'}", "{,,'a'}", "{'a',,'b'}", "{\"a\",,'b'}", "{'a',,\"b\"}", " {,}", " {,,}", " {,,,}", " {,\"\"}", " {\"\",}", " {,\"\",}", " {\"\",,}", " {\"\",,,}", " {,,\"\",,}", " {\"\",\"\",}", " {\"\",\"\",,}", " { \"\" , \"\" , , }", " {,''}", " {'',}", " {,'',}", " {'',,}", " {'',,,}", " {,,'',,}", " {'','',}", " {'','',,}", " { '' , '' , , }", " {'',\"\",}", " {\"\",'',,}", " { '' , \"\" , , }", " { \"\" , '' , , }", /*Ignore space's oddities */ "\" {\"\"}", "{ {\"\"}", "{\"\"}\"", "{\"\"}\\", "{\"\"} } ", "a{\"\"}", " a {\"\"}", "{a\"\"}", "{ a \"\"}", "{\"\"}a", "{\"\"} a ", "{\"\"a}", "{\"\" a }", "a{\"\"}b", "{a\"\"b}", "a{\"\"b}", "{a\"\"}b", "{\"\"a\"\"}", "{\"\",\"\"a\"\"}", "' {''}", "{ {''}", "{''}'", "{''}\\", "{''} } ", "a{''}", " a {''}", "{a''}", "{ a ''}", "{''}a", "{''} a ", "{''a}", "{'' a }", "a{''}b", "{a''b}", "a{''b}", "{a''}b", "{''a''}", "{'',''a''}", "{''a\"\"}", "{\"\"a''}", "{\"\",''a''}", "{'',\"\"a''}", "{'',''a\"\"}", "{\"\",''a\"\"}", /* Bad type of quotation inside an element */ "{'aa'aa'}", "{\"aa\"aa\"}", "{'aa\"''}", "{'aa\"\"''}", "{\"aa'\"\"}", "{\"aa''\"\"}", "{'aa\"'', 'aa\"\"'',\"aa'\"\"}", "{\"aa\"aa\", 'aa\"'', 'aa\"\"''}", "{ \"aa\"aa\" ,'aa\"\"'',\"aa''\"\" }", NULL }; static void test_new_parser_success() { Rlist *list = NULL; int i = 0; while (PR[i].nfields != -1) { list = RlistParseString(PR[i].str); assert_int_equal(PR[i].nfields, RlistLen(list)); if (list != NULL) { RlistDestroy(list); } i++; } } static void test_new_parser_failure() { int i = 0; Rlist *list = NULL; while (PFR[i] != NULL) { list = RlistParseString(PFR[i]); assert_true(RlistLast(list) == NULL); if(list) RlistDestroy(list); i++; } } static void test_regex_split() { Rlist *list = RlistFromRegexSplitNoOverflow("one-->two-->three", "-+>", 3); assert_int_equal(3, RlistLen(list)); assert_string_equal(RlistScalarValue(list), "one"); assert_string_equal(RlistScalarValue(list->next), "two"); assert_string_equal(RlistScalarValue(list->next->next), "three"); RlistDestroy(list); } static void test_regex_split_too_few_chunks() { Rlist *list = RlistFromRegexSplitNoOverflow("one:two:three", ":", 2); assert_int_equal(2, RlistLen(list)); assert_string_equal(RlistScalarValue(list), "one"); assert_string_equal(RlistScalarValue(list->next), "two:three"); RlistDestroy(list); } static void test_regex_split_too_many_chunks() { Rlist *list = RlistFromRegexSplitNoOverflow("one:two:three:", ":", 10); assert_int_equal(4, RlistLen(list)); assert_string_equal(RlistScalarValue(list), "one"); assert_string_equal(RlistScalarValue(list->next), "two"); assert_string_equal(RlistScalarValue(list->next->next), "three"); assert_string_equal(RlistScalarValue(list->next->next->next), ""); RlistDestroy(list); } static void test_regex_split_empty_chunks() { Rlist *list = RlistFromRegexSplitNoOverflow(":one:two:three:", ":", 5); assert_int_equal(5, RlistLen(list)); assert_string_equal(RlistScalarValue(list), ""); assert_string_equal(RlistScalarValue(list->next), "one"); assert_string_equal(RlistScalarValue(list->next->next), "two"); assert_string_equal(RlistScalarValue(list->next->next->next), "three"); assert_string_equal(RlistScalarValue(list->next->next->next->next), ""); RlistDestroy(list); } static void test_regex_split_no_match() { Rlist *list = RlistFromRegexSplitNoOverflow(":one:two:three:", "/", 2); assert_int_equal(1, RlistLen(list)); assert_string_equal(RlistScalarValue(list), ":one:two:three:"); RlistDestroy(list); } static void test_regex_split_adjacent_separators() { Rlist *list = RlistFromRegexSplitNoOverflow(":one::two::three:", ":", 3); assert_int_equal(3, RlistLen(list)); assert_string_equal(RlistScalarValue(list), ""); assert_string_equal(RlistScalarValue(list->next), "one"); assert_string_equal(RlistScalarValue(list->next->next), ":two::three:"); RlistDestroy(list); list = RlistFromRegexSplitNoOverflow(":one::two:::three:", ":", 4); assert_int_equal(4, RlistLen(list)); assert_string_equal(RlistScalarValue(list), ""); assert_string_equal(RlistScalarValue(list->next), "one"); assert_string_equal(RlistScalarValue(list->next->next), ""); assert_string_equal(RlistScalarValue(list->next->next->next), "two:::three:"); RlistDestroy(list); list = RlistFromRegexSplitNoOverflow(":one::two:::three:", ":", 7); assert_int_equal(7, RlistLen(list)); assert_string_equal(RlistScalarValue(list), ""); assert_string_equal(RlistScalarValue(list->next), "one"); assert_string_equal(RlistScalarValue(list->next->next), ""); assert_string_equal(RlistScalarValue(list->next->next->next), "two"); assert_string_equal(RlistScalarValue(list->next->next->next->next), ""); assert_string_equal(RlistScalarValue(list->next->next->next->next->next), ""); assert_string_equal(RlistScalarValue(list->next->next->next->next->next->next), "three:"); RlistDestroy(list); } static void test_regex_split_real_regex() { //whole string is matched by regex in below example Rlist *list = RlistFromRegexSplitNoOverflow("one-two-three", ".+", 3); assert_int_equal(2, RlistLen(list)); assert_string_equal(RlistScalarValue(list), ""); assert_string_equal(RlistScalarValue(list->next), ""); RlistDestroy(list); list = RlistFromRegexSplitNoOverflow("one>>>two<<<>four", "[<>]+", 4); assert_int_equal(4, RlistLen(list)); assert_string_equal(RlistScalarValue(list), "one"); assert_string_equal(RlistScalarValue(list->next), "two"); assert_string_equal(RlistScalarValue(list->next->next), "three"); assert_string_equal(RlistScalarValue(list->next->next->next), "four"); RlistDestroy(list); } static void test_regex_split_overlapping_delimiters() { Rlist *list = RlistFromRegexSplitNoOverflow("-one---two---three", "--", 3); assert_int_equal(3, RlistLen(list)); assert_string_equal(RlistScalarValue(list), "-one"); assert_string_equal(RlistScalarValue(list->next), "-two"); assert_string_equal(RlistScalarValue(list->next->next), "-three"); RlistDestroy(list); } static void test_rval_write() { Rval rval = { "\"Hello World!\"", RVAL_TYPE_SCALAR }; Writer *writer = StringWriter(); RvalWrite(writer, rval); const char *actual = StringWriterData(writer); assert_string_equal(actual, "\\\"Hello World!\\\""); WriterClose(writer); } static void test_rval_write_quoted() { Rval rval = { "\"Hello World!\"", RVAL_TYPE_SCALAR }; Writer *writer = StringWriter(); RvalWriteQuoted(writer, rval); const char *actual = StringWriterData(writer); assert_string_equal(actual, "\"\\\"Hello World!\\\"\""); WriterClose(writer); } static void test_rval_write_raw() { Rval rval = { "\"Hello World!\"", RVAL_TYPE_SCALAR }; Writer *writer = StringWriter(); RvalWriteRaw(writer, rval); const char *actual = StringWriterData(writer); assert_string_equal(actual, "\"Hello World!\""); WriterClose(writer); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_prepend_scalar_idempotent), unit_test(test_length), unit_test(test_equality), unit_test(test_copy), unit_test(test_rval_to_scalar), unit_test(test_rval_to_scalar2), unit_test(test_rval_to_list), unit_test(test_rval_to_list2), unit_test(test_rval_to_fncall), unit_test(test_rval_to_fncall2), unit_test(test_last), unit_test(test_filter), unit_test(test_filter_everything), unit_test(test_reverse), unit_test(test_split_escaped), unit_test(test_split_lines), unit_test(test_split_long), unit_test(test_split_long_escaped), unit_test(test_new_parser_success), unit_test(test_new_parser_failure), unit_test(test_regex_split), unit_test(test_regex_split_too_few_chunks), unit_test(test_regex_split_too_many_chunks), unit_test(test_regex_split_empty_chunks), unit_test(test_regex_split_no_match), unit_test(test_regex_split_adjacent_separators), unit_test(test_regex_split_real_regex), unit_test(test_regex_split_overlapping_delimiters), unit_test(test_rval_write), unit_test(test_rval_write_quoted), unit_test(test_rval_write_raw), }; return run_tests(tests); } /* ===== Stub out functionality we don't really use. ===== */ /* Silence all "unused parameter" warnings. */ #pragma GCC diagnostic ignored "-Wunused-parameter" char CONTEXTID[32]; void __ProgrammingError(const char *file, int lineno, const char *format, ...) { mock_assert(0, "0", __FILE__, __LINE__); } bool FullTextMatch(const char *regptr, const char *cmpptr) { fail(); } const void *EvalContextVariableGet(const EvalContext *ctx, const VarRef *lval, DataType *type_out) { fail(); } int __ThreadLock(pthread_mutex_t *name) { return true; } int __ThreadUnlock(pthread_mutex_t *name) { return true; } int IsNakedVar(const char *str, char vtype) { fail(); } void FnCallPrint(Writer *writer, const FnCall *fp) { fail(); } void GetNaked(char *s1, const char *s2) { fail(); } /* void Log(LogLevel level, const char *fmt, ...) { fail(); } */ DataType ScopeGetVariable(const char *scope, const char *lval, Rval *returnv) { fail(); } void DeleteAssoc(CfAssoc *ap) { fail(); } CfAssoc *CopyAssoc(CfAssoc *old) { fail(); } FnCall *FnCallCopy(const FnCall *f) { fail(); } void FnCallDestroy(FnCall *fp) { fail(); } int SubStrnCopyChr(char *to, const char *from, int len, char sep) { fail(); } int BlockTextMatch(const char *regexp, const char *teststring, int *s, int *e) { fail(); } JsonElement *FnCallToJson(const FnCall *fp) { fail(); } JsonElement *JsonObjectCreate(size_t initialCapacity) { fail(); } void JsonObjectAppendArray(JsonElement *object, const char *key, JsonElement *array) { fail(); } void JsonObjectAppendString(JsonElement *obj, const char *key, const char *value) { fail(); } JsonElement *JsonArrayCreate(size_t initialCapacity) { fail(); } void JsonArrayAppendString(JsonElement *array, const char *value) { fail(); } void JsonArrayAppendArray(JsonElement *array, JsonElement *childArray) { fail(); } void JsonArrayAppendObject(JsonElement *array, JsonElement *object) { fail(); } JsonElement *JsonStringCreate(const char *value) { fail(); } cfengine-3.24.2/tests/unit/findhub_test.c0000644000000000000000000002054515010704253020324 0ustar00rootroot00000000000000#include #include #include #include /* xsnprintf */ #include #include #include #include #include #include void (*avahi_simple_poll_quit_ptr)(AvahiSimplePoll *); char* (*avahi_address_snprint_ptr)(char *, size_t , const AvahiAddress *); int (*avahi_service_resolver_free_ptr)(AvahiServiceResolver *); int (*avahi_client_errno_ptr)(AvahiClient *); const char* (*avahi_strerror_ptr)(int); AvahiServiceResolver* (*avahi_service_resolver_new_ptr)(AvahiClient *, AvahiIfIndex, AvahiProtocol, const char *, const char *, const char *, AvahiProtocol, AvahiLookupFlags, AvahiServiceResolverCallback, void *); AvahiClient* (*avahi_service_browser_get_client_ptr)(AvahiServiceBrowser *); AvahiClient* (*avahi_service_resolver_get_client_ptr)(AvahiServiceResolver *); AvahiSimplePoll* (*avahi_simple_poll_new_ptr)(); const AvahiPoll* (*avahi_simple_poll_get_ptr)(AvahiSimplePoll *s); AvahiClient* (*avahi_client_new_ptr)(const AvahiPoll *, AvahiClientFlags, AvahiClientCallback, void *, int *); int (*avahi_simple_poll_loop_ptr)(AvahiSimplePoll *); int (*avahi_service_browser_free_ptr)(AvahiServiceBrowser *); void (*avahi_client_free_ptr)(AvahiClient *client); void (*avahi_simple_poll_free_ptr)(AvahiSimplePoll *); AvahiServiceBrowser* (*avahi_service_browser_new_ptr)(AvahiClient *, AvahiIfIndex, AvahiProtocol, const char *, const char *, AvahiLookupFlags, AvahiServiceBrowserCallback, void*); int hostcount; void *dlopen(const char *filename, int flag) { return (void*)1; } void *dlsym(void *handle, const char *symbol) { if (strcmp(symbol, "avahi_simple_poll_quit") == 0) { return &avahi_simple_poll_quit; } else if (strcmp(symbol, "avahi_address_snprint") == 0) { return &avahi_address_snprint; } else if (strcmp(symbol, "avahi_service_resolver_free") == 0) { return &avahi_service_resolver_free; } else if (strcmp(symbol, "avahi_client_errno") == 0) { return &avahi_client_errno; } else if (strcmp(symbol, "avahi_strerror") == 0) { return &avahi_strerror; } else if (strcmp(symbol, "avahi_service_resolver_new") == 0) { return &avahi_service_resolver_new; } else if (strcmp(symbol, "avahi_service_browser_get_client") == 0) { return &avahi_service_browser_get_client; } else if (strcmp(symbol, "avahi_service_resolver_get_client") == 0) { return &avahi_service_resolver_get_client; } else if (strcmp(symbol, "avahi_simple_poll_new") == 0) { return &avahi_simple_poll_new; } else if (strcmp(symbol, "avahi_simple_poll_get") == 0) { return &avahi_simple_poll_get; } else if (strcmp(symbol, "avahi_client_new") == 0) { return &avahi_client_new; } else if (strcmp(symbol, "avahi_simple_poll_loop") == 0) { return &avahi_simple_poll_loop; } else if (strcmp(symbol, "avahi_service_browser_free") == 0) { return &avahi_service_browser_free; } else if (strcmp(symbol, "avahi_client_free") == 0) { return &avahi_client_free; } else if (strcmp(symbol, "avahi_simple_poll_free") == 0) { return &avahi_simple_poll_free; } else if (strcmp(symbol, "avahi_service_browser_new") == 0) { return &avahi_service_browser_new; } return NULL; } int dlclose(void *handle) { return 0; } AvahiSimplePoll *avahi_simple_poll_new() { AvahiSimplePoll *sp = (AvahiSimplePoll*)1; return sp; } void avahi_simple_poll_free(AvahiSimplePoll *poll) { } const AvahiPoll *avahi_simple_poll_get(AvahiSimplePoll *s) { AvahiPoll *p = { 0 }; return p; } void avahi_simple_poll_quit(AvahiSimplePoll *poll) { } char *avahi_address_snprint(char *buffer, size_t size, const AvahiAddress *address) { xsnprintf(buffer, size, "10.0.0.100"); return NULL; } int avahi_service_resolver_free(AvahiServiceResolver *resolver) { return 0; } int avahi_client_errno(AvahiClient *c) { return 1; } const char *avahi_strerror(int error) { return "Avahi error occurred"; } AvahiServiceResolver *avahi_service_resolver_new(AvahiClient *c, AvahiIfIndex index, AvahiProtocol protocol, const char * s1, const char *s2, const char *s3, AvahiProtocol protocol2, AvahiLookupFlags flags, AvahiServiceResolverCallback callback, void *data) { return (AvahiServiceResolver *)1; } AvahiClient *avahi_service_browser_get_client(AvahiServiceBrowser *sb) { return (AvahiClient *)1; } AvahiClient *avahi_service_resolver_get_client(AvahiServiceResolver *sr) { return (AvahiClient *)1; } AvahiClient *avahi_client_new(const AvahiPoll *poll, AvahiClientFlags cf, AvahiClientCallback callback, void *data, int *stat) { if (hostcount == 4) { return NULL; } return (AvahiClient *)1; } int avahi_simple_poll_loop(AvahiSimplePoll *sp) { AvahiAddress *addr = calloc(1, sizeof(AvahiAddress)); AvahiServiceResolver *sr = { (AvahiServiceResolver*)1 }; switch(hostcount) { case 1: resolve_callback(sr, 0, 0, AVAHI_RESOLVER_FOUND, "cfenginehub", "tcp", "local", "host1", addr, 5308, NULL, 0, NULL); return 0; case 2: resolve_callback(sr, 0, 0, AVAHI_RESOLVER_FOUND, "cfenginehub", "tcp", "local", "host1", addr, 5308, NULL, 0, NULL); resolve_callback(sr, 0, 0, AVAHI_RESOLVER_FOUND, "cfenginehub", "tcp", "local", "host2", addr, 1234, NULL, 0, NULL); resolve_callback(sr, 0, 0, AVAHI_RESOLVER_FOUND, "cfenginehub", "tcp", "local", "host3", addr, 4321, NULL, 0, NULL); return 0; default: free(addr); }; return 0; } int avahi_service_browser_free(AvahiServiceBrowser *sb) { return 0; } void avahi_client_free(AvahiClient *c) { } AvahiServiceBrowser *avahi_service_browser_new(AvahiClient *c, AvahiIfIndex index, AvahiProtocol protocol, const char *s1, const char *s2, AvahiLookupFlags flags, AvahiServiceBrowserCallback callback, void *data) { AvahiServiceBrowser *browser = (AvahiServiceBrowser *)1; return browser; } static void test_noHubsFound(void) { List *list = NULL; hostcount = 0; assert_int_equal(ListHubs(&list), 0); assert_int_not_equal(list, NULL); ListDestroy(&list); } static void test_oneHubFound(void) { List *list = NULL; hostcount = 1; assert_int_equal(ListHubs(&list), 1); assert_int_not_equal(list, NULL); ListIterator *i = NULL; i = ListIteratorGet(list); assert_true(i != NULL); HostProperties *host = (HostProperties *)ListIteratorData(i); assert_int_equal(host->Port,5308); assert_string_equal(host->Hostname, "host1"); assert_string_equal(host->IPAddress, "10.0.0.100"); ListIteratorDestroy(&i); ListDestroy(&list); } static void test_multipleHubsFound(void) { List *list = NULL; hostcount = 2; assert_int_equal(ListHubs(&list), 3); assert_int_not_equal(list, NULL); ListIterator *i = NULL; i = ListIteratorGet(list); HostProperties *host1 = (HostProperties *)ListIteratorData(i); assert_int_not_equal(ListIteratorNext(i), -1); HostProperties *host2 = (HostProperties *)ListIteratorData(i); assert_int_not_equal(ListIteratorNext(i), -1); HostProperties *host3 = (HostProperties *)ListIteratorData(i); assert_int_equal(host1->Port, 5308); assert_string_equal(host1->Hostname, "host1"); assert_string_equal(host1->IPAddress, "10.0.0.100"); assert_int_equal(host2->Port, 1234); assert_string_equal(host2->Hostname, "host2"); assert_string_equal(host2->IPAddress, "10.0.0.100"); assert_int_equal(host3->Port, 4321); assert_string_equal(host3->Hostname, "host3"); assert_string_equal(host3->IPAddress, "10.0.0.100"); ListIteratorDestroy(&i); ListDestroy(&list); } static void test_errorOccurred(void) { List *list = NULL; hostcount = 4; assert_int_equal(ListHubs(&list), -1); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_noHubsFound), unit_test(test_oneHubFound), unit_test(test_multipleHubsFound), unit_test(test_errorOccurred) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/expand_test.c0000644000000000000000000004545215010704253020170 0ustar00rootroot00000000000000#include #include #include #include #include #include static void test_extract_scalar_prefix() { Buffer *b = BufferNew(); assert_int_equal(sizeof("hello ") - 1, ExtractScalarPrefix(b, "hello $(world) xy", sizeof("hello $(world) xy") -1)); assert_string_equal("hello ", BufferData(b)); BufferClear(b); assert_int_equal(sizeof("hello (world) xy") -1, ExtractScalarPrefix(b, "hello (world) xy", sizeof("hello (world) xy") -1)); assert_string_equal("hello (world) xy", BufferData(b)); BufferClear(b); assert_int_equal(sizeof("hello$)") -1, ExtractScalarPrefix(b, "hello$)$(world)xy", sizeof("hello$)$(world)xy") -1)); assert_string_equal("hello$)", BufferData(b)); BufferClear(b); assert_int_equal(0, ExtractScalarPrefix(b, "", 0)); assert_string_equal("", BufferData(b)); BufferDestroy(b); } static void test_extract_reference_(const char *scalar, bool expect_success, const char *outer, const char *inner) { Buffer *b = BufferNew(); size_t len = strlen(scalar); bool success = ExtractScalarReference(b, scalar, len, false); assert_true(success == expect_success); assert_string_equal(outer, BufferData(b)); BufferClear(b); success = ExtractScalarReference(b, scalar, len, true); assert_true(success == expect_success); assert_string_equal(inner, BufferData(b)); BufferDestroy(b); } static void test_extract_reference(void) { test_extract_reference_("${stuff}", true, "${stuff}", "stuff"); test_extract_reference_("$(stuff)", true, "$(stuff)", "stuff"); test_extract_reference_("abc $def ${x} y", true, "${x}", "x"); test_extract_reference_("${stuff)", false, "", ""); test_extract_reference_("abc $def", false, "", ""); test_extract_reference_("stuff", false, "", ""); test_extract_reference_("", false, "", ""); test_extract_reference_("abc $xa ", false, "", ""); test_extract_reference_("${}", false, "", ""); test_extract_reference_("x$()a", false, "", ""); test_extract_reference_("$($(x))", true, "$($(x))", "$(x)"); test_extract_reference_("$(x${$(y)})", true, "$(x${$(y)})", "x${$(y)}"); test_extract_reference_("$(x${$(y)}) $(y) ${x${z}}", true, "$(x${$(y)})", "x${$(y)}"); } static void test_isnakedvar() { assert_true(IsNakedVar("$(whatever)", '$')); assert_true(IsNakedVar("${whatever}", '$')); assert_true(IsNakedVar("$(blah$(blue))", '$')); assert_false(IsNakedVar("$(blah)blue", '$')); assert_false(IsNakedVar("blah$(blue)", '$')); assert_false(IsNakedVar("$(blah)$(blue)", '$')); assert_false(IsNakedVar("$(blah}", '$')); } #if 0 static void test_map_iterators_from_rval_empty(void **state) { EvalContext *ctx = *state; Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "default", "none", "agent", NULL, NULL); Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; MapIteratorsFromRval(ctx, bp, (Rval) { "", RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_int_equal(0, RlistLen(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); PolicyDestroy(p); } static void test_map_iterators_from_rval_literal(void **state) { EvalContext *ctx = *state; Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "default", "none", "agent", NULL, NULL); Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; MapIteratorsFromRval(ctx, bp, (Rval) { "snookie", RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_int_equal(0, RlistLen(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); PolicyDestroy(p); } static void test_map_iterators_from_rval_naked_list_var(void **state) { EvalContext *ctx = *state; Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "default", "scope", "agent", NULL, NULL); { Rlist *list = NULL; RlistAppend(&list, "jersey", RVAL_TYPE_SCALAR); VarRef *lval = VarRefParse("scope.jwow"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); VarRefDestroy(lval); RlistDestroy(list); } EvalContextStackPushBundleFrame(ctx, bp, NULL, false); { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; MapIteratorsFromRval(ctx, bp, (Rval) { "${jwow}", RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_int_equal(1, RlistLen(lists)); assert_string_equal("jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${default:scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${default*scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("default*scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } EvalContextStackPopFrame(ctx); PolicyDestroy(p); } static void test_map_iterators_from_rval_naked_list_var_namespace(void **state) { EvalContext *ctx = *state; Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "ns", "scope", "agent", NULL, NULL); { Rlist *list = NULL; RlistAppend(&list, "jersey", RVAL_TYPE_SCALAR); VarRef *lval = VarRefParse("ns:scope.jwow"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); VarRefDestroy(lval); RlistDestroy(list); } EvalContextStackPushBundleFrame(ctx, bp, NULL, false); { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; MapIteratorsFromRval(ctx, bp, (Rval) { "${jwow}", RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_int_equal(1, RlistLen(lists)); assert_string_equal("jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } { Rlist *lists = NULL; Rlist *scalars = NULL; Rlist *containers = NULL; char *str = xstrdup("${ns:scope.jwow}"); MapIteratorsFromRval(ctx, bp, (Rval) { str, RVAL_TYPE_SCALAR }, &scalars, &lists, &containers); assert_string_equal("${ns*scope#jwow}", str); free(str); assert_int_equal(1, RlistLen(lists)); assert_string_equal("ns*scope#jwow", RlistScalarValue(lists)); assert_int_equal(0, RlistLen(scalars)); assert_int_equal(0, RlistLen(containers)); RlistDestroy(lists); } EvalContextStackPopFrame(ctx); PolicyDestroy(p); } #endif static void test_expand_scalar_two_scalars_concat(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.one"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.two"); EvalContextVariablePut(ctx, lval, "second", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Buffer *res = BufferNew(); ExpandScalar(ctx, "default", "bundle", "a $(one) b $(two)c", res); assert_string_equal("a first b secondc", BufferData(res)); BufferDestroy(res); } static void test_expand_scalar_two_scalars_nested(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.one"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.two"); EvalContextVariablePut(ctx, lval, "one", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Buffer *res = BufferNew(); ExpandScalar(ctx, "default", "bundle", "a $($(two))b", res); assert_string_equal("a firstb", BufferData(res)); BufferDestroy(res); } static void test_expand_scalar_array_concat(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.foo[one]"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.foo[two]"); EvalContextVariablePut(ctx, lval, "second", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Buffer *res = BufferNew(); ExpandScalar(ctx, "default", "bundle", "a $(foo[one]) b $(foo[two])c", res); assert_string_equal("a first b secondc", BufferData(res)); BufferDestroy(res); } static void test_expand_scalar_array_with_scalar_arg(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.foo[one]"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.bar"); EvalContextVariablePut(ctx, lval, "one", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Buffer *res = BufferNew(); ExpandScalar(ctx, "default", "bundle", "a$(foo[$(bar)])b", res); assert_string_equal("afirstb", BufferData(res)); BufferDestroy(res); } static void test_expand_scalar_undefined(void **state) { EvalContext *ctx = *state; Buffer *res = BufferNew(); ExpandScalar(ctx, "default", "bundle", "a$(undefined)b", res); assert_string_equal("a$(undefined)b", BufferData(res)); BufferDestroy(res); } static void test_expand_scalar_nested_inner_undefined(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.foo[one]"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Buffer *res = BufferNew(); ExpandScalar(ctx, "default", "bundle", "a$(foo[$(undefined)])b", res); assert_string_equal("a$(foo[$(undefined)])b", BufferData(res)); BufferDestroy(res); } static void test_expand_list_nested(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.i"); EvalContextVariablePut(ctx, lval, "one", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.inner[one]"); Rlist *list = NULL; RlistAppendScalar(&list, "foo"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); RlistDestroy(list); VarRefDestroy(lval); } Rlist *outer = NULL; RlistAppendScalar(&outer, "@{inner[$(i)]}"); Rlist *expanded = ExpandList(ctx, "default", "bundle", outer, true); assert_int_equal(1, RlistLen(expanded)); assert_string_equal("foo", RlistScalarValue(expanded)); RlistDestroy(outer); RlistDestroy(expanded); } static PromiseResult actuator_expand_promise_array_with_scalar_arg( ARG_UNUSED EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert_string_equal("first", pp->promiser); return PROMISE_RESULT_NOOP; } static void test_expand_promise_array_with_scalar_arg(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.foo[one]"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.bar"); EvalContextVariablePut(ctx, lval, "one", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Policy *policy = PolicyNew(); Bundle *bundle = PolicyAppendBundle(policy, NamespaceDefault(), "bundle", "agent", NULL, NULL); BundleSection *section = BundleAppendSection(bundle, "dummy"); Promise *promise = BundleSectionAppendPromise(section, "$(foo[$(bar)])", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, "any", NULL); EvalContextStackPushBundleFrame(ctx, bundle, NULL, false); EvalContextStackPushBundleSectionFrame(ctx, section); ExpandPromise(ctx, promise, actuator_expand_promise_array_with_scalar_arg, NULL); EvalContextStackPopFrame(ctx); EvalContextStackPopFrame(ctx); PolicyDestroy(policy); } static int actuator_state = 0; static PromiseResult actuator_expand_promise_slist( ARG_UNUSED EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { if (strcmp("a", pp->promiser) == 0) { assert_int_equal(0, actuator_state); actuator_state++; } else if (strcmp("b", pp->promiser) == 0) { assert_int_equal(1, actuator_state); actuator_state++; } else { fail(); } return PROMISE_RESULT_NOOP; } static void test_expand_promise_slist(void **state) { actuator_state = 0; EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.foo"); Rlist *list = NULL; RlistAppendScalar(&list, "a"); RlistAppendScalar(&list, "b"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); RlistDestroy(list); VarRefDestroy(lval); } Policy *policy = PolicyNew(); Bundle *bundle = PolicyAppendBundle(policy, NamespaceDefault(), "bundle", "agent", NULL, NULL); BundleSection *section = BundleAppendSection(bundle, "dummy"); Promise *promise = BundleSectionAppendPromise(section, "$(foo)", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, "any", NULL); EvalContextStackPushBundleFrame(ctx, bundle, NULL, false); EvalContextStackPushBundleSectionFrame(ctx, section); ExpandPromise(ctx, promise, actuator_expand_promise_slist, NULL); EvalContextStackPopFrame(ctx); EvalContextStackPopFrame(ctx); assert_int_equal(2, actuator_state); PolicyDestroy(policy); } static PromiseResult actuator_expand_promise_array_with_slist_arg( ARG_UNUSED EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { if (strcmp("first", pp->promiser) == 0) { assert_int_equal(0, actuator_state); actuator_state++; } else if (strcmp("second", pp->promiser) == 0) { assert_int_equal(1, actuator_state); actuator_state++; } else { fprintf(stderr, "Got promiser: '%s'\n", pp->promiser); fail(); } return PROMISE_RESULT_NOOP; } static void test_expand_promise_array_with_slist_arg(void **state) { actuator_state = 0; EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.keys"); Rlist *list = NULL; RlistAppendScalar(&list, "one"); RlistAppendScalar(&list, "two"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); RlistDestroy(list); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.arr[one]"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.arr[two]"); EvalContextVariablePut(ctx, lval, "second", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Policy *policy = PolicyNew(); Bundle *bundle = PolicyAppendBundle(policy, NamespaceDefault(), "bundle", "agent", NULL, NULL); BundleSection *section = BundleAppendSection(bundle, "dummy"); Promise *promise = BundleSectionAppendPromise(section, "$(arr[$(keys)])", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, "any", NULL); EvalContextStackPushBundleFrame(ctx, bundle, NULL, false); EvalContextStackPushBundleSectionFrame(ctx, section); ExpandPromise(ctx, promise, actuator_expand_promise_array_with_slist_arg, NULL); EvalContextStackPopFrame(ctx); EvalContextStackPopFrame(ctx); assert_int_equal(2, actuator_state); PolicyDestroy(policy); } static void test_setup(void **state) { *state = EvalContextNew(); } static void test_teardown(void **state) { EvalContext *ctx = *state; EvalContextDestroy(ctx); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_extract_scalar_prefix), unit_test(test_extract_reference), unit_test(test_isnakedvar), #if 0 unit_test_setup_teardown(test_map_iterators_from_rval_empty, test_setup, test_teardown), unit_test_setup_teardown(test_map_iterators_from_rval_literal, test_setup, test_teardown), unit_test_setup_teardown(test_map_iterators_from_rval_naked_list_var, test_setup, test_teardown), unit_test_setup_teardown(test_map_iterators_from_rval_naked_list_var_namespace, test_setup, test_teardown), #endif unit_test_setup_teardown(test_expand_scalar_two_scalars_concat, test_setup, test_teardown), unit_test_setup_teardown(test_expand_scalar_two_scalars_nested, test_setup, test_teardown), unit_test_setup_teardown(test_expand_scalar_array_concat, test_setup, test_teardown), unit_test_setup_teardown(test_expand_scalar_array_with_scalar_arg, test_setup, test_teardown), unit_test_setup_teardown(test_expand_scalar_undefined, test_setup, test_teardown), unit_test_setup_teardown(test_expand_scalar_nested_inner_undefined, test_setup, test_teardown), unit_test_setup_teardown(test_expand_list_nested, test_setup, test_teardown), unit_test_setup_teardown(test_expand_promise_array_with_scalar_arg, test_setup, test_teardown), unit_test_setup_teardown(test_expand_promise_slist, test_setup, test_teardown), unit_test_setup_teardown(test_expand_promise_array_with_slist_arg, test_setup, test_teardown) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/redirection_test.c0000644000000000000000000000450015010704253021205 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include // dirname /* * This test checks for different types of IPC to check that redirection of * STDIN will work. * This test is only significant in Linux, because this is only used by the * hub process that only runs on Linux. */ static char redirection[] = "/tmp/redirectionXXXXXX"; static char path[PATH_MAX]; static char *message = "This is the message to be written by our helper"; static char message_back[128]; static void test_fd_redirection(void) { assert_true(path != NULL); /* * Create a file for writing, then start a new process and wait for it * to write to the file. * Check the contents of the file. */ int fd = -1; fd = mkstemp(redirection); assert_int_not_equal(-1, fd); /* Start the new process */ int pid = 0; pid = fork(); assert_int_not_equal(-1, pid); if (pid == 0) { /* Child */ dup2(fd, STDIN_FILENO); char *argv[] = { path, message, NULL }; char *envp[] = { NULL }; printf("path: %s\n", path); execve(path, argv, envp); printf("execve failed: %s\n", strerror(errno)); exit(-1); } else { /* Parent */ int status = 0; int options = 0; /* Wait for the child to be done */ assert_int_equal(waitpid(pid, &status, options), pid); /* Did it exit correctly? */ assert_true(WIFEXITED(status)); assert_int_equal(WEXITSTATUS(status), 0); /* Rewind the file so we can check the message */ lseek(fd, 0, SEEK_SET); /* Read back the message */ assert_int_equal(strlen(message), read(fd, message_back, strlen(message))); /* Compare it */ assert_string_equal(message, message_back); } close (fd); } void tests_teardown() { unlink (redirection); } int main(int argc, char **argv) { PRINT_TEST_BANNER(); assert(argc >= 1); /* Find the proper path for our helper */ char *base = dirname(argv[0]); char *helper = "/../redirection_test_stub"; sprintf(path, "%s%s", base, helper); const UnitTest tests[] = { unit_test(test_fd_redirection) }; tests_teardown(); return run_tests(tests); } cfengine-3.24.2/tests/unit/schema.h0000644000000000000000000001451015010704253017106 0ustar00rootroot00000000000000#ifndef SCHEMA_H_ # define SCHEMA_H_ // Printf formatting for xml CUNIT Schema #define CUNIT_INIT \ "<\?xml version=\"1.0\" \?>\n" \ "<\?xml-stylesheet type=\"text/xsl\" href=\"CUnit-Run.xsl\" \?>\n" \ "\n" \ "\n" \ " \n" \ " \n" \ " \n" \ " \n" \ " %s suite \n" #define CUNIT_RUN_TEST_SUCCESS \ " \n" \ " \n" \ " %s \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_START \ " \n" \ " \n" \ " %s \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(%lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(%lld, %lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(%s %s) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_RANGE_LLD \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(value=%lld, min=%lld, max=%lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_FAILURE_ASSERT_SET_LLD \ " \n" \ " \n" \ " %s \n" \ " %s \n" \ " %d \n" \ " %s(value=%lld, number_of_values=%lld) \n" \ " \n" \ " \n" #define CUNIT_RUN_TEST_ERROR \ " \n" \ " \n" \ " %s \n" \ " %d \n" #define CUNIT_RUN_SUMMARY \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " %s \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " \n" \ " \n" \ " %s \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " \n" \ " \n" \ " %s \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " %d \n" \ " \n" \ " \n" \ " File Generated By CUnit v2.1-2 - %s\n" \ " \n" \ "\n" // Printf formatting for xml XS Schema #define XS_INIT_TESTSUITE \ "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>\n" \ "\n" #define XS_TESTCASE \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_RANGE_LLD \ " \n" \ " \n" #define XS_RUN_TEST_FAILURE_ASSERT_SET_LLD \ " \n" \ " \n" #define XS_RUN_TEST_ERROR \ " \n" #define XS_TESTCASE_END \ " \n" #define XS_TESTSUITE_END \ "\n" #endif cfengine-3.24.2/tests/unit/domainname_test.c0000644000000000000000000000662415010704253021017 0ustar00rootroot00000000000000#include #include char fqname[CF_BUFSIZE]; char uqname[CF_BUFSIZE]; char domain[CF_BUFSIZE]; void CalculateDomainName(const char *nodename, const char *dnsname, char *fqname, size_t fqname_size, char *uqname, size_t uqname_size, char *domain, size_t domain_size); static void test_fqname(void) { const char nodename[] = "mylaptop.example.com"; const char dnsname[] = "mylaptop.example.com"; CalculateDomainName(nodename, dnsname, fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, "mylaptop.example.com"); assert_string_equal(uqname, "mylaptop"); assert_string_equal(domain, "example.com"); } static void test_uqname(void) { CalculateDomainName("mylaptop", "mylaptop.example.com", fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, "mylaptop.example.com"); assert_string_equal(uqname, "mylaptop"); assert_string_equal(domain, "example.com"); } static void test_uqname2(void) { CalculateDomainName("user.laptop", "user.laptop.example.com", fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, "user.laptop.example.com"); assert_string_equal(uqname, "user.laptop"); assert_string_equal(domain, "example.com"); } static void test_fqname_not_really_fq(void) { CalculateDomainName("user.laptop", "user.laptop", fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, "user.laptop"); assert_string_equal(uqname, "user"); assert_string_equal(domain, "laptop"); } static void test_fqname_not_really_fq2(void) { CalculateDomainName("laptop", "laptop", fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, "laptop"); assert_string_equal(uqname, "laptop"); assert_string_equal(domain, ""); } static void test_fqname_unresolvable(void) { CalculateDomainName("laptop", "", fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, "laptop"); assert_string_equal(uqname, "laptop"); assert_string_equal(domain, ""); } static void test_no_names(void) { CalculateDomainName("", "", fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, ""); assert_string_equal(uqname, ""); assert_string_equal(domain, ""); } static void test_wrong_fqname(void) { CalculateDomainName("laptop", "a1006.cfengine.com", fqname, sizeof(fqname), uqname, sizeof(uqname), domain, sizeof(domain)); assert_string_equal(fqname, "a1006.cfengine.com"); assert_string_equal(uqname, "laptop"); assert_string_equal(domain, ""); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_fqname), unit_test(test_uqname), unit_test(test_uqname2), unit_test(test_fqname_not_really_fq), unit_test(test_fqname_not_really_fq2), unit_test(test_fqname_unresolvable), unit_test(test_no_names), unit_test(test_wrong_fqname), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/db_test.c0000644000000000000000000001527515010704253017276 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include /* xsnprintf */ char CFWORKDIR[CF_BUFSIZE]; void tests_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/db_test.XXXXXX"; char *workdir = strchr(env, '=') + 1; /* start of the path */ assert(workdir - 1 && workdir[0] == '/'); mkdtemp(workdir); strlcpy(CFWORKDIR, workdir, CF_BUFSIZE); putenv(env); mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); } void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } void test_open_close(void) { // Test that we can simply open and close a database without doing anything. CF_DB *db; assert_int_equal(OpenDB(&db, dbid_classes), true); CloseDB(db); } void test_read_write(void) { // Test that we can do normal reads and write, and that the values are // reflected in the database. CF_DB *db; char value[CF_BUFSIZE]; strcpy(value, "myvalue"); int vsize = strlen(value) + 1; assert_int_equal(OpenDB(&db, dbid_classes), true); assert_int_equal(ReadDB(db, "written_entry", &value, vsize), false); assert_string_equal(value, "myvalue"); assert_int_equal(WriteDB(db, "written_entry", value, vsize), true); strcpy(value, ""); assert_int_equal(ReadDB(db, "written_entry", &value, vsize), true); assert_string_equal(value, "myvalue"); CloseDB(db); // Check also after we reopen the database. assert_int_equal(OpenDB(&db, dbid_classes), true); strcpy(value, ""); assert_int_equal(ReadDB(db, "written_entry", &value, vsize), true); assert_string_equal(value, "myvalue"); CloseDB(db); } void test_iter_modify_entry(void) { /* Test that deleting entry under cursor does not interrupt iteration */ CF_DB *db; assert_int_equal(OpenDB(&db, dbid_classes), true); assert_int_equal(WriteDB(db, "foobar", "abc", 3), true); assert_int_equal(WriteDB(db, "bazbaz", "def", 3), true); assert_int_equal(WriteDB(db, "booo", "ghi", 3), true); CF_DBC *cursor; assert_int_equal(NewDBCursor(db, &cursor), true); char *key; int ksize; void *value; int vsize; assert_int_equal(NextDB(cursor, &key, &ksize, &value, &vsize), true); assert_int_equal(DBCursorWriteEntry(cursor, "eee", 3), true); assert_int_equal(NextDB(cursor, &key, &ksize, &value, &vsize), true); assert_int_equal(NextDB(cursor, &key, &ksize, &value, &vsize), true); assert_int_equal(DeleteDBCursor(cursor), true); CloseDB(db); } void test_iter_delete_entry(void) { /* Test that deleting entry under cursor does not interrupt iteration */ CF_DB *db; assert_int_equal(OpenDB(&db, dbid_classes), true); assert_int_equal(WriteDB(db, "foobar", "abc", 3), true); assert_int_equal(WriteDB(db, "bazbaz", "def", 3), true); assert_int_equal(WriteDB(db, "booo", "ghi", 3), true); CF_DBC *cursor; assert_int_equal(NewDBCursor(db, &cursor), true); char *key; int ksize; void *value; int vsize; assert_int_equal(NextDB(cursor, &key, &ksize, &value, &vsize), true); assert_int_equal(DBCursorDeleteEntry(cursor), true); assert_int_equal(NextDB(cursor, &key, &ksize, &value, &vsize), true); assert_int_equal(NextDB(cursor, &key, &ksize, &value, &vsize), true); assert_int_equal(DeleteDBCursor(cursor), true); CloseDB(db); } #if defined(HAVE_LIBTOKYOCABINET) || defined(HAVE_LIBQDBM) || defined(HAVE_LIBLMDB) static void CreateGarbage(const char *filename) { FILE *fh = fopen(filename, "w"); for(int i = 0; i < 2; ++i) { fwrite("some garbage!", 14, 1, fh); } fclose(fh); } #endif /* HAVE_LIBTOKYOCABINET || HAVE_LIBQDBM */ void test_recreate(void) { /* Test that recreating database works properly */ #ifdef HAVE_LIBTOKYOCABINET char tcdb_db[CF_BUFSIZE]; xsnprintf(tcdb_db, CF_BUFSIZE, "%s/cf_classes.tcdb", GetStateDir()); CreateGarbage(tcdb_db); #endif #ifdef HAVE_LIBQDBM char qdbm_db[CF_BUFSIZE]; xsnprintf(qdbm_db, CF_BUFSIZE, "%s/cf_classes.qdbm", GetStateDir()); CreateGarbage(qdbm_db); #endif #ifdef HAVE_LIBLMDB char lmdb_db[CF_BUFSIZE]; xsnprintf(lmdb_db, CF_BUFSIZE, "%s/cf_classes.lmdb", CFWORKDIR); CreateGarbage(lmdb_db); #endif CF_DB *db; assert_int_equal(OpenDB(&db, dbid_classes), true); CloseDB(db); } void test_old_workdir_db_location(void) { #ifndef LMDB // We manipulate the LMDB file name directly. Not adapted to the others. return; #endif CF_DB *db; char *state_dir; xasprintf(&state_dir, "%s%cstate", GetWorkDir(), FILE_SEPARATOR); if (strcmp(GetStateDir(), state_dir) != 0) { // Test only works when statedir is $(workdir)/state. free(state_dir); return; } assert_true(OpenDB(&db, dbid_lastseen)); assert_true(WriteDB(db, "key", "first_value", strlen("first_value") + 1)); CloseDB(db); char *old_db, *orig_db, *new_db; // Due to caching of the path we need to use a different db when opening the // second time, otherwise the path is not rechecked. xasprintf(&orig_db, "%s%ccf_lastseen.lmdb", GetStateDir(), FILE_SEPARATOR); xasprintf(&old_db, "%s%ccf_audit.lmdb", GetWorkDir(), FILE_SEPARATOR); xasprintf(&new_db, "%s%ccf_audit.lmdb", GetStateDir(), FILE_SEPARATOR); // Copy database to old location. assert_true(CopyRegularFileDisk(orig_db, old_db)); // Change content. assert_true(OpenDB(&db, dbid_lastseen)); assert_true(WriteDB(db, "key", "second_value", strlen("second_value") + 1)); CloseDB(db); // Copy database to new location. assert_true(CopyRegularFileDisk(orig_db, new_db)); char value[CF_BUFSIZE]; // Old location should take precedence. assert_true(OpenDB(&db, dbid_audit)); assert_true(ReadDB(db, "key", value, sizeof(value))); assert_string_equal(value, "first_value"); CloseDB(db); free(state_dir); free(old_db); free(orig_db); free(new_db); } int main() { PRINT_TEST_BANNER(); tests_setup(); const UnitTest tests[] = { unit_test(test_open_close), unit_test(test_read_write), unit_test(test_iter_modify_entry), unit_test(test_iter_delete_entry), unit_test(test_recreate), unit_test(test_old_workdir_db_location), }; PRINT_TEST_BANNER(); int ret = run_tests(tests); tests_teardown(); return ret; } /* STUBS */ void FatalError(ARG_UNUSED char *s, ...) { fail(); exit(42); } cfengine-3.24.2/tests/unit/getopt_test.c0000644000000000000000000001117615010704253020207 0ustar00rootroot00000000000000#include #include #include #include #include #include /* Test that we have a working version of getopt functionality, either * system-provided or our own in libcfecompat. */ static Seq *CheckOpts(int argc, char **argv) { Seq *seq = SeqNew(3, free); const struct option OPTIONS[] = { {"no-arg", no_argument, 0, 'n'}, {"opt-arg", optional_argument, 0, 'o'}, {"req-arg", required_argument, 0, 'r'}, {NULL, 0, 0, '\0'} }; /* Reset optind to 1 in order to restart scanning of argv * - getopt(3) – Linux Manual */ optind = 1; int c; while ((c = getopt_long(argc, argv, "no::r:", OPTIONS, NULL)) != -1) { switch (c) { case 'n': /* no argument */ SeqAppend(seq, xstrdup("none")); break; case 'o': /* optional argument */ if (OPTIONAL_ARGUMENT_IS_PRESENT) { SeqAppend(seq, xstrdup(optarg)); } else { SeqAppend(seq, xstrdup("default")); } break; case 'r': /* required argument */ SeqAppend(seq, xstrdup(optarg)); break; default: assert(false); break; } } return seq; } static void test_GET_OPTIONAL_ARGUMENT(void) { /* optional as middle option */ int argc1 = 6; char *argv1[] = { "program", "-n", "-o", "foo", "-r", "bar" }; Seq *seq1 = CheckOpts(argc1, argv1); assert_int_equal(SeqLength(seq1), 3); assert_string_equal((char *) SeqAt(seq1, 0), "none"); assert_string_equal((char *) SeqAt(seq1, 1), "foo"); assert_string_equal((char *) SeqAt(seq1, 2), "bar"); SeqDestroy(seq1); /* optional as last option */ int argc2 = 6; char *argv2[] = { "program", "-r", "bar", "-n", "-o", "foo" }; Seq *seq2 = CheckOpts(argc2, argv2); assert_int_equal(SeqLength(seq2), 3); assert_string_equal((char *) SeqAt(seq2, 0), "bar"); assert_string_equal((char *) SeqAt(seq2, 1), "none"); assert_string_equal((char *) SeqAt(seq2, 2), "foo"); SeqDestroy(seq2); /* optional as first option */ int argc3 = 6; char *argv3[] = { "program", "-o", "foo", "-r", "bar", "-n" }; Seq *seq3 = CheckOpts(argc3, argv3); assert_int_equal(SeqLength(seq3), 3); assert_string_equal((char *) SeqAt(seq3, 0), "foo"); assert_string_equal((char *) SeqAt(seq3, 1), "bar"); assert_string_equal((char *) SeqAt(seq3, 2), "none"); SeqDestroy(seq3); /* optional with no argument */ int argc4 = 5; char *argv4[] = { "program", "-n", "-o", "-r", "bar" }; Seq *seq4 = CheckOpts(argc4, argv4); assert_int_equal(SeqLength(seq4), 3); assert_string_equal((char *) SeqAt(seq4, 0), "none"); assert_string_equal((char *) SeqAt(seq4, 1), "default"); assert_string_equal((char *) SeqAt(seq4, 2), "bar"); SeqDestroy(seq4); /* optional with argument immediately after */ int argc5 = 5; char *argv5[] = { "program", "-n", "-ofoo", "-r", "bar" }; Seq *seq5 = CheckOpts(argc5, argv5); assert_int_equal(SeqLength(seq5), 3); assert_string_equal((char *) SeqAt(seq5, 0), "none"); assert_string_equal((char *) SeqAt(seq5, 1), "foo"); assert_string_equal((char *) SeqAt(seq5, 2), "bar"); SeqDestroy(seq5); /* optional as only option with argument */ int argc6 = 3; char *argv6[] = { "program", "-o", "foo" }; Seq *seq6 = CheckOpts(argc6, argv6); assert_int_equal(SeqLength(seq6), 1); assert_string_equal((char *) SeqAt(seq6, 0), "foo"); SeqDestroy(seq6); /* optional as only option with argument immediately after */ int argc7 = 2; char *argv7[] = { "program", "-ofoo" }; Seq *seq7 = CheckOpts(argc7, argv7); assert_int_equal(SeqLength(seq7), 1); assert_string_equal((char *) SeqAt(seq7, 0), "foo"); SeqDestroy(seq7); /* optinal as only option with no argument */ int argc8 = 2; char *argv8[] = { "program", "-o" }; Seq *seq8 = CheckOpts(argc8, argv8); assert_int_equal(SeqLength(seq8), 1); assert_string_equal((char *) SeqAt(seq8, 0), "default"); SeqDestroy(seq8); } int main() { srand48(time(NULL)); PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_GET_OPTIONAL_ARGUMENT), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/processes_select_test.c0000644000000000000000000000221615010704253022245 0ustar00rootroot00000000000000#include #include #include #include static void test_SplitProcLine_windows(void) { char buf[CF_BUFSIZE]; snprintf(buf, sizeof(buf), "%-20s %5s %s %s %8s %8s %-3s %s %s %5s %s", "USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY", "STAT", "START", "TIME", "COMMAND"); char *names[CF_PROCCOLS] = {0}; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; GetProcessColumnNames(buf, names, start, end); const char *const proc_line = "NETWORK SERVICE 540 0.0 0.3 5092 11180 ? ? Apr28 00:00 C:\\Windows\\system32\\svchost.exe -k RPCSS -p"; time_t pstime = time(NULL); char *column[CF_PROCCOLS] = {0}; bool ret = SplitProcLine(proc_line, pstime, names, start, end, PCA_AllColumnsPresent, column); assert_true(ret); assert_string_equal(column[0], "NETWORK SERVICE"); for (int i = 0; i < CF_PROCCOLS; i++) { free(names[i]); free(column[i]); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_SplitProcLine_windows), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/regex_test.c0000644000000000000000000000261515010704253020015 0ustar00rootroot00000000000000#include #include #include #include #include static void test_full_text_match(void) { EvalContext *ctx = EvalContextNew(); assert_int_equal(FullTextMatch(ctx, "[a-z]*", "1234abcd6789"), 0); EvalContextDestroy(ctx); } static void test_full_text_match2(void) { EvalContext *ctx = EvalContextNew(); assert_int_not_equal(FullTextMatch(ctx, "[1-4]*[a-z]*.*", "1234abcd6789"), 0); EvalContextDestroy(ctx); } static void test_block_text_match(void) { EvalContext *ctx = EvalContextNew(); int start, end; assert_int_not_equal(BlockTextMatch(ctx, "#[^\n]*", "line 1:\nline2: # comment to end\nline 3: blablab", &start, &end), 0); assert_int_equal(start, 15); assert_int_equal(end, 31); EvalContextDestroy(ctx); } static void test_block_text_match2(void) { EvalContext *ctx = EvalContextNew(); int start, end; assert_int_not_equal(BlockTextMatch(ctx, "[a-z]+", "1234abcd6789", &start, &end), 0); assert_int_equal(start, 4); assert_int_equal(end, 8); EvalContextDestroy(ctx); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_full_text_match), unit_test(test_full_text_match2), unit_test(test_block_text_match), unit_test(test_block_text_match2), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/sysinfo_test.c0000644000000000000000000000605415010704253020376 0ustar00rootroot00000000000000#include #include #include static void test_uptime(void) { /* * Assume we have been online at least one minute, and less than 5 years. * Should be good enough for everyone... */ int uptime = GetUptimeMinutes(time(NULL)); printf("Uptime: %.2f days\n", uptime / (60.0 * 24)); assert_in_range(uptime, 1, 60*24*365*5); } static void FindNextIntegerTestWrapper(char *str, char expected[][KIBIBYTE(1)], int num_expected) { Seq *seq = SeqNew(num_expected, NULL); char *integer; char *next = FindNextInteger(str, &integer); if (integer != NULL) { SeqAppend(seq, integer); } while (next != NULL && integer != NULL) { next = FindNextInteger(next, &integer); if (integer != NULL) { SeqAppend(seq, integer); } } assert_int_equal(num_expected, SeqLength(seq)); for (int i = 0; i < num_expected; i++) { assert_string_equal((char *) SeqAt(seq, i), expected[i]); } SeqDestroy(seq); } static void test_find_next_integer(void) { { char str[] = "Ubuntu 20.04.1 LTS"; char expected[3][KIBIBYTE(1)] = { "20", "04", "1" }; FindNextIntegerTestWrapper(str, expected, 3); } { char str[] = "canonified_5"; char expected[1][KIBIBYTE(1)] = { "5" }; FindNextIntegerTestWrapper(str, expected, 1); } { char str[] = ""; char expected[0][KIBIBYTE(1)] = { }; FindNextIntegerTestWrapper(str, expected, 0); } { char str[] = " "; char expected[0][KIBIBYTE(1)] = { }; FindNextIntegerTestWrapper(str, expected, 0); } { char str[] = " no numbers in sight "; char expected[0][KIBIBYTE(1)] = { }; FindNextIntegerTestWrapper(str, expected, 0); } { char str[] = "0"; char expected[1][KIBIBYTE(1)] = { "0" }; FindNextIntegerTestWrapper(str, expected, 1); } { char str[] = "1k"; char expected[1][KIBIBYTE(1)] = { "1" }; FindNextIntegerTestWrapper(str, expected, 1); } { char str[] = "1234"; char expected[1][KIBIBYTE(1)] = { "1234" }; FindNextIntegerTestWrapper(str, expected, 1); } { char str[] = "1 2 3 4"; char expected[4][KIBIBYTE(1)] = { "1", "2", "3", "4" }; FindNextIntegerTestWrapper(str, expected, 4); } { char str[] = "Debian 9"; char expected[1][KIBIBYTE(1)] = { "9" }; FindNextIntegerTestWrapper(str, expected, 1); } { char str[] = "Cent OS 6.7"; char expected[2][KIBIBYTE(1)] = { "6", "7" }; FindNextIntegerTestWrapper(str, expected, 2); } { char str[] = "CFEngine 3.18.0-2deadbeef"; char expected[4][KIBIBYTE(1)] = { "3", "18", "0", "2" }; FindNextIntegerTestWrapper(str, expected, 4); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_uptime), unit_test(test_find_next_integer) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/eval_context_test.c0000644000000000000000000001176115010704253021400 0ustar00rootroot00000000000000#include #include #include /* xsnprintf */ #include #include char CFWORKDIR[CF_BUFSIZE]; void tests_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/CFENGINE_eval_context_test.XXXXXX"; char *workdir = strchr(env, '='); assert(workdir && workdir[1] == '/'); workdir++; mkdtemp(workdir); strlcpy(CFWORKDIR, workdir, CF_BUFSIZE); putenv(env); mkdir(GetStateDir(), 0766); } void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } static void test_class_persistence(void) { EvalContext *ctx = EvalContextNew(); // simulate old version { CF_DB *dbp; PersistentClassInfo i; assert_true(OpenDB(&dbp, dbid_state)); i.expires = UINT_MAX; i.policy = CONTEXT_STATE_POLICY_RESET; WriteDB(dbp, "old", &i, sizeof(PersistentClassInfo)); CloseDB(dbp); } // e.g. by monitoring EvalContextHeapPersistentSave(ctx, "class1", 3, CONTEXT_STATE_POLICY_PRESERVE, "a,b"); // e.g. by a class promise in a bundle with a namespace { Policy *p = PolicyNew(); Bundle *bp = PolicyAppendBundle(p, "ns1", "bundle1", "agent", NULL, NULL); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); EvalContextHeapPersistentSave(ctx, "class2", 5, CONTEXT_STATE_POLICY_PRESERVE, "x"); EvalContextStackPopFrame(ctx); PolicyDestroy(p); } EvalContextHeapPersistentLoadAll(ctx); { const Class *cls = EvalContextClassGet(ctx, "default", "old"); assert_true(cls != NULL); assert_string_equal("old", cls->name); assert_true(cls->tags != NULL); assert_int_equal(1, StringSetSize(cls->tags)); assert_true(StringSetContains(cls->tags, "source=persistent")); } { const Class *cls = EvalContextClassGet(ctx, "default", "class1"); assert_true(cls != NULL); assert_string_equal("class1", cls->name); assert_true(cls->tags != NULL); assert_int_equal(3, StringSetSize(cls->tags)); assert_true(StringSetContains(cls->tags, "source=persistent")); assert_true(StringSetContains(cls->tags, "a")); assert_true(StringSetContains(cls->tags, "b")); } { const Class *cls = EvalContextClassGet(ctx, "ns1", "class2"); assert_true(cls != NULL); assert_string_equal("ns1", cls->ns); assert_string_equal("class2", cls->name); assert_true(cls->tags != NULL); assert_int_equal(2, StringSetSize(cls->tags)); assert_true(StringSetContains(cls->tags, "source=persistent")); assert_true(StringSetContains(cls->tags, "x")); } EvalContextDestroy(ctx); } void test_changes_chroot(void) { /* Should add '/' to the end implicitly. */ SetChangesChroot("/changes/go/here"); /* The most trivial case. */ const char *chrooted = ToChangesChroot("/etc/issue"); assert_string_equal(chrooted, "/changes/go/here/etc/issue"); /* A shorter path to test that NUL-byte is added/copied properly. */ chrooted = ToChangesChroot("/etc/ab"); assert_string_equal(chrooted, "/changes/go/here/etc/ab"); /* And a longer path again. */ chrooted = ToChangesChroot("/etc/sysctl.d/00-default.conf"); assert_string_equal(chrooted, "/changes/go/here/etc/sysctl.d/00-default.conf"); #ifndef __MINGW32__ /* Inverse should work as expected */ const char *normal = ToNormalRoot(chrooted); assert_string_equal(normal, "/etc/sysctl.d/00-default.conf"); #endif } void test_eval_with_token_from_list(void) { /* The timestamp should generate these classes (among others): * 'GMT_Afternoon', 'GMT_Day29', 'GMT_Hr13', 'GMT_Hr13_Q3', 'GMT_Lcycle_2', * 'GMT_May', 'GMT_Min30_35', 'GMT_Min33', 'GMT_Q3', 'GMT_Wednesday', * 'GMT_Yr2024' */ const time_t timestamp = 1716989621; StringSet *time_classes = GetTimeClasses(timestamp); StringSetIterator iter = StringSetIteratorInit(time_classes); const char *time_class = NULL; while((time_class = StringSetIteratorNext(&iter)) != NULL) { printf("Time class: %s\n", time_class); } assert_true(EvalWithTokenFromList("GMT_Wednesday", time_classes)); assert_false(EvalWithTokenFromList("GMT_Monday", time_classes)); assert_false(EvalWithTokenFromList("GMT_Wednesday.GMT_Monday", time_classes)); assert_true(EvalWithTokenFromList("GMT_Monday|GMT_Wednesday", time_classes)); assert_true(EvalWithTokenFromList("!GMT_Monday", time_classes)); StringSetDestroy(time_classes); } int main() { PRINT_TEST_BANNER(); tests_setup(); const UnitTest tests[] = { unit_test(test_class_persistence), unit_test(test_changes_chroot), unit_test(test_eval_with_token_from_list), }; int ret = run_tests(tests); tests_teardown(); return ret; } cfengine-3.24.2/tests/unit/cf_upgrade_test.c0000644000000000000000000001106415010704253021000 0ustar00rootroot00000000000000#include #include #include #include #include static void test_parse(void) { Configuration *configuration = NULL; char *empty_command_line[] = { "this" }; assert_int_equal (-1, parse(1, empty_command_line, &configuration)); assert_true (configuration == NULL); char *common_command_line[] = { "this", "-b", "backup.sh", "-s", "backup.tar.gz", "-i", "rpm", "-ivh", "package.rpm"}; assert_int_equal(0, parse(9, common_command_line, &configuration)); assert_true(configuration != NULL); assert_string_equal("backup.sh", ConfigurationBackupTool(configuration)); assert_string_equal("backup.tar.gz", ConfigurationBackupPath(configuration)); assert_string_equal("rpm", ConfigurationCommand(configuration)); assert_int_equal(3, ConfigurationNumberOfArguments(configuration)); ConfigurationDestroy(&configuration); assert_true(configuration == NULL); char *full_command_line[] = { "this", "-b", "backup.sh", "-s", "backup.tar.gz", "-c", "copy", "-f", "/opt/cfengine", "-i", "dpkg", "--install", "package.deb" }; assert_int_equal(0, parse(13, full_command_line, &configuration)); assert_true(configuration != NULL); assert_string_equal("backup.sh", ConfigurationBackupTool(configuration)); assert_string_equal("backup.tar.gz", ConfigurationBackupPath(configuration)); assert_string_equal("copy", ConfigurationCopy(configuration)); assert_string_equal("/opt/cfengine", ConfigurationCFEnginePath(configuration)); assert_string_equal("this", ConfigurationCFUpgrade(configuration)); assert_string_equal("dpkg", ConfigurationCommand(configuration)); assert_int_equal(3, ConfigurationNumberOfArguments(configuration)); ConfigurationDestroy(&configuration); assert_true(configuration == NULL); } static void test_configuration(void) { Configuration *configuration = ConfigurationNew(); assert_true(configuration != NULL); assert_true(ConfigurationBackupTool(configuration) == NULL); assert_true(ConfigurationBackupPath(configuration) == NULL); assert_string_equal("/tmp/cf-upgrade", ConfigurationCopy(configuration)); assert_string_equal("/var/cfengine/", ConfigurationCFEnginePath(configuration)); assert_true(ConfigurationCommand(configuration) == NULL); assert_true(ConfigurationCFUpgrade(configuration) == NULL); assert_int_equal(0, ConfigurationNumberOfArguments(configuration)); assert_false(ConfigurationPerformUpdate(configuration)); ConfigurationDestroy(&configuration); assert_true(configuration == NULL); configuration = ConfigurationNew(); char backup_tool[] = "backup.sh"; char backup_path[] = "backup.tar.gz"; char cfupgrade_copy[] = "/tmp/copy"; char cfupgrade[] = "cf-upgrade"; char command[] = "dpkg"; char argument[] = "-ivh"; char cfengine[] = "/opt/cfengine"; ConfigurationSetBackupTool(configuration, backup_tool); assert_string_equal(ConfigurationBackupTool(configuration), backup_tool); ConfigurationSetBackupPath(configuration, backup_path); assert_string_equal(ConfigurationBackupPath(configuration), backup_path); ConfigurationSetCopy(configuration, cfupgrade_copy); assert_string_equal(ConfigurationCopy(configuration), cfupgrade_copy); ConfigurationSetCFUpgrade(configuration, cfupgrade); assert_string_equal(ConfigurationCFUpgrade(configuration), cfupgrade); ConfigurationAddArgument(configuration, command); assert_string_equal(ConfigurationCommand(configuration), command); assert_string_equal(ConfigurationArgument(configuration, 0), command); assert_int_equal(1, ConfigurationNumberOfArguments(configuration)); ConfigurationAddArgument(configuration, argument); assert_string_equal(ConfigurationArgument(configuration, 0), command); assert_string_equal(ConfigurationArgument(configuration, 1), argument); assert_int_equal(2, ConfigurationNumberOfArguments(configuration)); ConfigurationSetCFEnginePath(configuration, cfengine); assert_string_equal(ConfigurationCFEnginePath(configuration), cfengine); assert_int_equal(2, ConfigurationNumberOfArguments(configuration)); ConfigurationDestroy(&configuration); assert_true(configuration == NULL); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_parse), unit_test(test_configuration) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/protocol_test.c0000644000000000000000000003402015010704253020537 0ustar00rootroot00000000000000#include #include #include #include #include #include #include /* GetCommandClassic */ /* * The protocol consists of the following commands: * "EXEC", * "AUTH", * "GET", * "OPENDIR", * "SYNCH", * "CLASSES", * "MD5", * "SMD5", * "CAUTH", * "SAUTH", * "SSYNCH", * "SGET", * "VERSION", * "SOPENDIR", * "VAR", * "SVAR", * "CONTEXT", * "SCONTEXT", * "SQUERY", * "SCALLBACK", */ static void test_command_parser(void) { ProtocolCommandClassic parsed = PROTOCOL_COMMAND_BAD; ProtocolCommandClassic expected = PROTOCOL_COMMAND_BAD; /* * Test all the commands, one by one. */ // EXEC expected = PROTOCOL_COMMAND_EXEC; parsed = GetCommandClassic("EXEC"); assert_int_equal(expected, parsed); // AUTH expected = PROTOCOL_COMMAND_AUTH; parsed = GetCommandClassic("AUTH"); assert_int_equal(expected, parsed); // GET expected = PROTOCOL_COMMAND_GET; parsed = GetCommandClassic("GET"); assert_int_equal(expected, parsed); // OPENDIR expected = PROTOCOL_COMMAND_OPENDIR; parsed = GetCommandClassic("OPENDIR"); assert_int_equal(expected, parsed); // SYNCH expected = PROTOCOL_COMMAND_SYNC; parsed = GetCommandClassic("SYNCH"); assert_int_equal(expected, parsed); // CLASSES expected = PROTOCOL_COMMAND_CONTEXTS; parsed = GetCommandClassic("CLASSES"); assert_int_equal(expected, parsed); // MD5 expected = PROTOCOL_COMMAND_MD5; parsed = GetCommandClassic("MD5"); assert_int_equal(expected, parsed); // SMD5 expected = PROTOCOL_COMMAND_MD5_SECURE; parsed = GetCommandClassic("SMD5"); assert_int_equal(expected, parsed); // CAUTH expected = PROTOCOL_COMMAND_AUTH_PLAIN; parsed = GetCommandClassic("CAUTH"); assert_int_equal(expected, parsed); // SAUTH expected = PROTOCOL_COMMAND_AUTH_SECURE; parsed = GetCommandClassic("SAUTH"); assert_int_equal(expected, parsed); // SSYNCH expected = PROTOCOL_COMMAND_SYNC_SECURE; parsed = GetCommandClassic("SSYNCH"); assert_int_equal(expected, parsed); // SGET expected = PROTOCOL_COMMAND_GET_SECURE; parsed = GetCommandClassic("SGET"); assert_int_equal(expected, parsed); // VERSION expected = PROTOCOL_COMMAND_VERSION; parsed = GetCommandClassic("VERSION"); assert_int_equal(expected, parsed); // SOPENDIR expected = PROTOCOL_COMMAND_OPENDIR_SECURE; parsed = GetCommandClassic("SOPENDIR"); assert_int_equal(expected, parsed); // VAR expected = PROTOCOL_COMMAND_VAR; parsed = GetCommandClassic("VAR"); assert_int_equal(expected, parsed); // SVAR expected = PROTOCOL_COMMAND_VAR_SECURE; parsed = GetCommandClassic("SVAR"); assert_int_equal(expected, parsed); // CONTEXT expected = PROTOCOL_COMMAND_CONTEXT; parsed = GetCommandClassic("CONTEXT"); assert_int_equal(expected, parsed); // SCONTEXT expected = PROTOCOL_COMMAND_CONTEXT_SECURE; parsed = GetCommandClassic("SCONTEXT"); assert_int_equal(expected, parsed); // SQUERY expected = PROTOCOL_COMMAND_QUERY_SECURE; parsed = GetCommandClassic("SQUERY"); assert_int_equal(expected, parsed); // SCALLBACK expected = PROTOCOL_COMMAND_CALL_ME_BACK; parsed = GetCommandClassic("SCALLBACK"); assert_int_equal(expected, parsed); /* * Try using lowercase */ // EXEC expected = PROTOCOL_COMMAND_BAD; parsed = GetCommandClassic("exec"); assert_int_equal(expected, parsed); // AUTH parsed = GetCommandClassic("auth"); assert_int_equal(expected, parsed); // GET parsed = GetCommandClassic("get"); assert_int_equal(expected, parsed); // OPENDIR parsed = GetCommandClassic("opendir"); assert_int_equal(expected, parsed); // SYNCH parsed = GetCommandClassic("synch"); assert_int_equal(expected, parsed); // CLASSES parsed = GetCommandClassic("classes"); assert_int_equal(expected, parsed); // MD5 parsed = GetCommandClassic("md5"); assert_int_equal(expected, parsed); // SMD5 parsed = GetCommandClassic("smd5"); assert_int_equal(expected, parsed); // CAUTH parsed = GetCommandClassic("cauth"); assert_int_equal(expected, parsed); // SAUTH parsed = GetCommandClassic("sauth"); assert_int_equal(expected, parsed); // SSYNCH parsed = GetCommandClassic("synch"); assert_int_equal(expected, parsed); // SGET parsed = GetCommandClassic("sget"); assert_int_equal(expected, parsed); // VERSION parsed = GetCommandClassic("version"); assert_int_equal(expected, parsed); // SOPENDIR parsed = GetCommandClassic("sopendir"); assert_int_equal(expected, parsed); // VAR parsed = GetCommandClassic("var"); assert_int_equal(expected, parsed); // SVAR parsed = GetCommandClassic("svar"); assert_int_equal(expected, parsed); // CONTEXT parsed = GetCommandClassic("context"); assert_int_equal(expected, parsed); // SCONTEXT parsed = GetCommandClassic("scontext"); assert_int_equal(expected, parsed); // SQUERY parsed = GetCommandClassic("squery"); assert_int_equal(expected, parsed); // SCALLBACK parsed = GetCommandClassic("scallback"); assert_int_equal(expected, parsed); /* * Try the commands with something in front */ // EXEC expected = PROTOCOL_COMMAND_BAD; parsed = GetCommandClassic("eEXEC"); assert_int_equal(expected, parsed); // AUTH parsed = GetCommandClassic("aAUTH"); assert_int_equal(expected, parsed); // GET parsed = GetCommandClassic("gGET"); assert_int_equal(expected, parsed); // OPENDIR parsed = GetCommandClassic("oOPENDIR"); assert_int_equal(expected, parsed); // SYNCH parsed = GetCommandClassic("sSYNCH"); assert_int_equal(expected, parsed); // CLASSES parsed = GetCommandClassic("cCLASSES"); assert_int_equal(expected, parsed); // MD5 parsed = GetCommandClassic("mMD5"); assert_int_equal(expected, parsed); // SMD5 parsed = GetCommandClassic("sMD5"); assert_int_equal(expected, parsed); // CAUTH parsed = GetCommandClassic("cCAUTH"); assert_int_equal(expected, parsed); // SAUTH parsed = GetCommandClassic("sSAUTH"); assert_int_equal(expected, parsed); // SSYNCH parsed = GetCommandClassic("sSSYNCH"); assert_int_equal(expected, parsed); // SGET parsed = GetCommandClassic("sSGET"); assert_int_equal(expected, parsed); // VERSION parsed = GetCommandClassic("vVERSION"); assert_int_equal(expected, parsed); // SOPENDIR parsed = GetCommandClassic("sSOPENDIR"); assert_int_equal(expected, parsed); // VAR parsed = GetCommandClassic("vVAR"); assert_int_equal(expected, parsed); // SVAR parsed = GetCommandClassic("sSVAR"); assert_int_equal(expected, parsed); // CONTEXT parsed = GetCommandClassic("cCONTEXT"); assert_int_equal(expected, parsed); // SCONTEXT parsed = GetCommandClassic("sSCONTEXT"); assert_int_equal(expected, parsed); // SQUERY parsed = GetCommandClassic("sSQUERY"); assert_int_equal(expected, parsed); // SCALLBACK parsed = GetCommandClassic("sSCALLBACK"); assert_int_equal(expected, parsed); /* * Try the commands with something after them */ // EXEC expected = PROTOCOL_COMMAND_BAD; parsed = GetCommandClassic("EXECx"); assert_int_equal(expected, parsed); // AUTH parsed = GetCommandClassic("AUTHx"); assert_int_equal(expected, parsed); // GET parsed = GetCommandClassic("GETx"); assert_int_equal(expected, parsed); // OPENDIR parsed = GetCommandClassic("OPENDIRx"); assert_int_equal(expected, parsed); // SYNCH parsed = GetCommandClassic("SYNCHx"); assert_int_equal(expected, parsed); // CLASSES parsed = GetCommandClassic("CLASSESx"); assert_int_equal(expected, parsed); // MD5 parsed = GetCommandClassic("MD5x"); assert_int_equal(expected, parsed); // SMD5 parsed = GetCommandClassic("SMD5x"); assert_int_equal(expected, parsed); // CAUTH parsed = GetCommandClassic("CAUTHx"); assert_int_equal(expected, parsed); // SAUTH parsed = GetCommandClassic("SAUTHx"); assert_int_equal(expected, parsed); // SSYNCH parsed = GetCommandClassic("SSYNCHx"); assert_int_equal(expected, parsed); // SGET parsed = GetCommandClassic("SGETx"); assert_int_equal(expected, parsed); // VERSION parsed = GetCommandClassic("VERSIONx"); assert_int_equal(expected, parsed); // SOPENDIR parsed = GetCommandClassic("SOPENDIRx"); assert_int_equal(expected, parsed); // VAR parsed = GetCommandClassic("VARx"); assert_int_equal(expected, parsed); // SVAR parsed = GetCommandClassic("SVARx"); assert_int_equal(expected, parsed); // CONTEXT parsed = GetCommandClassic("CONTEXTx"); assert_int_equal(expected, parsed); // SCONTEXT parsed = GetCommandClassic("SCONTEXTx"); assert_int_equal(expected, parsed); // SQUERY parsed = GetCommandClassic("SQUERYx"); assert_int_equal(expected, parsed); // SCALLBACK parsed = GetCommandClassic("SCALLBACKx"); assert_int_equal(expected, parsed); /* * Try some common mispellings. */ // EXEC expected = PROTOCOL_COMMAND_BAD; parsed = GetCommandClassic("EXE"); assert_int_equal(expected, parsed); parsed = GetCommandClassic("EXECUTE"); assert_int_equal(expected, parsed); // AUTH parsed = GetCommandClassic("AUTHORIZATION"); assert_int_equal(expected, parsed); // SYNCH parsed = GetCommandClassic("SYNC"); assert_int_equal(expected, parsed); parsed = GetCommandClassic("SYNCHRONIZE"); assert_int_equal(expected, parsed); // CLASSES parsed = GetCommandClassic("CLASS"); assert_int_equal(expected, parsed); // CAUTH parsed = GetCommandClassic("CAUTHORIZATION"); assert_int_equal(expected, parsed); // SAUTH parsed = GetCommandClassic("SAUTHORIZATION"); assert_int_equal(expected, parsed); // SSYNCH parsed = GetCommandClassic("SSYNCHRONIZE"); assert_int_equal(expected, parsed); parsed = GetCommandClassic("SSYNC"); assert_int_equal(expected, parsed); // VERSION parsed = GetCommandClassic("V"); assert_int_equal(expected, parsed); // VAR parsed = GetCommandClassic("VARIABLE"); assert_int_equal(expected, parsed); // SVAR parsed = GetCommandClassic("SVARIABLE"); assert_int_equal(expected, parsed); /* * Finally, try the commands with a space and something else, they should be recognized" */ // EXEC expected = PROTOCOL_COMMAND_EXEC; parsed = GetCommandClassic("EXEC 123"); assert_int_equal(expected, parsed); // AUTH expected = PROTOCOL_COMMAND_AUTH; parsed = GetCommandClassic("AUTH 123"); assert_int_equal(expected, parsed); // GET expected = PROTOCOL_COMMAND_GET; parsed = GetCommandClassic("GET 123"); assert_int_equal(expected, parsed); // OPENDIR expected = PROTOCOL_COMMAND_OPENDIR; parsed = GetCommandClassic("OPENDIR 123"); assert_int_equal(expected, parsed); // SYNCH expected = PROTOCOL_COMMAND_SYNC; parsed = GetCommandClassic("SYNCH 123"); assert_int_equal(expected, parsed); // CLASSES expected = PROTOCOL_COMMAND_CONTEXTS; parsed = GetCommandClassic("CLASSES 123"); assert_int_equal(expected, parsed); // MD5 expected = PROTOCOL_COMMAND_MD5; parsed = GetCommandClassic("MD5 123"); assert_int_equal(expected, parsed); // SMD5 expected = PROTOCOL_COMMAND_MD5_SECURE; parsed = GetCommandClassic("SMD5 123"); assert_int_equal(expected, parsed); // CAUTH expected = PROTOCOL_COMMAND_AUTH_PLAIN; parsed = GetCommandClassic("CAUTH 123"); assert_int_equal(expected, parsed); // SAUTH expected = PROTOCOL_COMMAND_AUTH_SECURE; parsed = GetCommandClassic("SAUTH 123"); assert_int_equal(expected, parsed); // SSYNCH expected = PROTOCOL_COMMAND_SYNC_SECURE; parsed = GetCommandClassic("SSYNCH 123"); assert_int_equal(expected, parsed); // SGET expected = PROTOCOL_COMMAND_GET_SECURE; parsed = GetCommandClassic("SGET 123"); assert_int_equal(expected, parsed); // VERSION expected = PROTOCOL_COMMAND_VERSION; parsed = GetCommandClassic("VERSION 123"); assert_int_equal(expected, parsed); // SOPENDIR expected = PROTOCOL_COMMAND_OPENDIR_SECURE; parsed = GetCommandClassic("SOPENDIR 123"); assert_int_equal(expected, parsed); // VAR expected = PROTOCOL_COMMAND_VAR; parsed = GetCommandClassic("VAR 123"); assert_int_equal(expected, parsed); // SVAR expected = PROTOCOL_COMMAND_VAR_SECURE; parsed = GetCommandClassic("SVAR 123"); assert_int_equal(expected, parsed); // CONTEXT expected = PROTOCOL_COMMAND_CONTEXT; parsed = GetCommandClassic("CONTEXT 123"); assert_int_equal(expected, parsed); // SCONTEXT expected = PROTOCOL_COMMAND_CONTEXT_SECURE; parsed = GetCommandClassic("SCONTEXT 123"); assert_int_equal(expected, parsed); // SQUERY expected = PROTOCOL_COMMAND_QUERY_SECURE; parsed = GetCommandClassic("SQUERY 123"); assert_int_equal(expected, parsed); // SCALLBACK expected = PROTOCOL_COMMAND_CALL_ME_BACK; parsed = GetCommandClassic("SCALLBACK 123"); assert_int_equal(expected, parsed); } static void test_user_name(void) { char invalid_user_name[] = "user\\"; char invalid_user_name2[] = "user//"; char invalid_user_name3[] = "//\\"; char valid_user_name[] = "valid_user"; assert_false(IsUserNameValid(invalid_user_name)); assert_false(IsUserNameValid(invalid_user_name2)); assert_false(IsUserNameValid(invalid_user_name3)); assert_true(IsUserNameValid(valid_user_name)); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_command_parser), unit_test(test_user_name) }; return run_tests(tests); } cfengine-3.24.2/tests/unit/cmockery.c0000644000000000000000000021553115010704253017463 0ustar00rootroot00000000000000/* LCOV_EXCL_STOP */ /* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* LCOV_EXCL_START */ #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_MALLOC_H # include #endif #include #ifndef _WIN32 # include #endif // !_WIN32 #include #include #include #include #include #include #include #include #ifdef _WIN32 # include #endif // _WIN32 #include #include #include /* Backwards compatibility with headers shipped with Visual Studio 2005 and * earlier. */ #ifdef _WIN32 WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); #endif // _WIN32 // Size of guard bytes around dynamically allocated blocks. #define MALLOC_GUARD_SIZE 16 // Pattern used to initialize guard blocks. #define MALLOC_GUARD_PATTERN 0xEF // Pattern used to initialize memory allocated with test_malloc(). #define MALLOC_ALLOC_PATTERN 0xBA #define MALLOC_FREE_PATTERN 0xCD // Alignment of allocated blocks. NOTE: This must be base2. #define MALLOC_ALIGNMENT sizeof(size_t) // Printf formatting for source code locations. #define SOURCE_LOCATION_FORMAT "%s:%d" // Calculates the number of elements in an array. #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) // Declare and initialize the pointer member of ValuePointer variable name // with ptr. #define declare_initialize_value_pointer_pointer(name, ptr) \ ValuePointer name ; \ name.value = 0; \ name.pointer = (void*)(ptr) // Declare and initialize the value member of ValuePointer variable name // with val. #define declare_initialize_value_pointer_value(name, val) \ ValuePointer name ; \ name.value = val // Cast a LargestIntegralType to pointer_type via a ValuePointer. #define cast_largest_integral_type_to_pointer( \ pointer_type, largest_integral_type) \ ((pointer_type)((ValuePointer*)&(largest_integral_type))->pointer) // Used to cast LargestIntegralType to void* and vice versa. typedef union ValuePointer { LargestIntegralType value; void *pointer; } ValuePointer; // Doubly linked list node. typedef struct ListNode { const void *value; int refcount; struct ListNode *next; struct ListNode *prev; } ListNode; // Debug information for malloc(). typedef struct MallocBlockInfo { void *block; // Address of the block returned by malloc(). size_t allocated_size; // Total size of the allocated block. size_t size; // Request block size. SourceLocation location; // Where the block was allocated. ListNode node; // Node within list of all allocated blocks. } MallocBlockInfo; // State of each test. typedef struct TestState { const ListNode *check_point; // Check point of the test if there's a // setup function. void *state; // State associated with the test. } TestState; // Determines whether two values are the same. typedef int (*EqualityFunction) (const void *left, const void *right); // Value of a symbol and the place it was declared. typedef struct SymbolValue { SourceLocation location; LargestIntegralType value; } SymbolValue; /* Contains a list of values for a symbol. * NOTE: Each structure referenced by symbol_values_list_head must have a * SourceLocation as its' first member. */ typedef struct SymbolMapValue { const char *symbol_name; ListNode symbol_values_list_head; } SymbolMapValue; // Used by list_free() to deallocate values referenced by list nodes. typedef void (*CleanupListValue) (const void *value, void *cleanup_value_data); // Structure used to check the range of integer types. typedef struct CheckIntegerRange { CheckParameterEvent event; LargestIntegralType minimum; LargestIntegralType maximum; } CheckIntegerRange; // Structure used to check whether an integer value is in a set. typedef struct CheckIntegerSet { CheckParameterEvent event; const LargestIntegralType *set; size_t size_of_set; } CheckIntegerSet; /* Used to check whether a parameter matches the area of memory referenced by * this structure. */ typedef struct CheckMemoryData { CheckParameterEvent event; const void *memory; size_t size; } CheckMemoryData; static ListNode *list_initialize(ListNode *const node); static ListNode *list_add(ListNode *const head, ListNode *new_node); static ListNode *list_add_value(ListNode *const head, const void *value, const int count); static ListNode *list_remove(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data); static void list_remove_free(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data); static int list_empty(const ListNode *const head); static int list_find(ListNode *const head, const void *value, const EqualityFunction equal_func, ListNode **output); static int list_first(ListNode *const head, ListNode **output); static ListNode *list_free(ListNode *const head, const CleanupListValue cleanup_value, void *const cleanup_value_data); static void add_symbol_value(ListNode *const symbol_map_head, const char *const symbol_names[], const size_t number_of_symbol_names, const void *value, const int count); static int get_symbol_value(ListNode *const symbol_map_head, const char *const symbol_names[], const size_t number_of_symbol_names, void **output); static void free_value(const void *value, void *cleanup_value_data); static void free_symbol_map_value(const void *value, void *cleanup_value_data); static void remove_always_return_values(ListNode *const map_head, const size_t number_of_symbol_names); static int check_for_leftover_values(const ListNode *const map_head, const char *const error_message, const size_t number_of_symbol_names); // This must be called at the beginning of a test to initialize some data // structures. static void initialize_testing(void); // This must be called at the end of a test to free() allocated structures. static void teardown_testing(void); // Keeps track of the calling context returned by setenv() so that the fail() // method can jump out of a test. static jmp_buf global_run_test_env; static int global_running_test = 0; // Keeps track of the calling context returned by setenv() so that // mock_assert() can optionally jump back to expect_assert_failure(). jmp_buf global_expect_assert_env; const char *global_expect_assert_expression; int global_expecting_assert = 0; // Keeps a map of the values that functions will have to return to provide // mocked interfaces. static ListNode global_function_result_map_head; // Location of the last mock value returned was declared. static SourceLocation global_last_mock_value_location; /* Keeps a map of the values that functions expect as parameters to their * mocked interfaces. */ static ListNode global_function_parameter_map_head; // Location of last parameter value checked was declared. static SourceLocation global_last_parameter_location; // List of all currently allocated blocks. static ListNode global_allocated_blocks; // Data of running tests for XML output. static int global_errors; static const char *global_filename; static const char *global_xmlfile; static int global_is_file_writer_test; /* bool, but type not defined here */ #ifndef _WIN32 // Signals caught by exception_handler(). static const int exception_signals[] = { SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGSYS, }; // Default signal functions that should be restored after a test is complete. typedef void (*SignalFunction) (int signal); static SignalFunction default_signal_functions[ARRAY_LENGTH(exception_signals)]; #else // _WIN32 // The default exception filter. static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; // Fatal exceptions. typedef struct ExceptionCodeInfo { DWORD code; const char *description; } ExceptionCodeInfo; # define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} static const ExceptionCodeInfo exception_codes[] = { EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), }; #endif // !_WIN32 static void exit_test(void) FUNC_ATTR_NORETURN; // Exit the currently executing test. static void exit_test(void) { if (global_running_test) { longjmp(global_run_test_env, 1); } else { exit(-1); } } #ifdef _WIN32 // Exit the currently executing test. static void exit_test_no_app(void) { if (global_running_test) { longjmp(global_run_test_env, 1); } } #endif // Initialize a SourceLocation structure. static void initialize_source_location(SourceLocation *const location) { assert_true(location); location->file = NULL; location->line = 0; } // Determine whether a source location is currently set. static int source_location_is_set(const SourceLocation *const location) { assert_true(location); return location->file && location->line; } // Set a source location. static void set_source_location(SourceLocation *const location, const char *const file, const int line) { assert_true(location); location->file = file; location->line = line; } // Create function results and expected parameter lists. void initialize_testing(void) { list_initialize(&global_function_result_map_head); initialize_source_location(&global_last_mock_value_location); list_initialize(&global_function_parameter_map_head); initialize_source_location(&global_last_parameter_location); } static void fail_if_leftover_values(const char *test_name) { int error_occurred = 0; remove_always_return_values(&global_function_result_map_head, 1); if (check_for_leftover_values(&global_function_result_map_head, "%s() has remaining non-returned values.\n", 1)) { print_xml(XS_RUN_TEST_ERROR "\"%s() has remaining non-returned values.\">\n" XS_RUN_TEST_ERROR_END, "fail_if_leftover_values", test_name); error_occurred = 1; } remove_always_return_values(&global_function_parameter_map_head, 2); if (check_for_leftover_values(&global_function_parameter_map_head, "%s parameter still has values that haven't been checked.\n", 2)) { print_xml(XS_RUN_TEST_ERROR "\"%s parameter still has values that haven't been checked.\">\n" XS_RUN_TEST_ERROR_END, "fail_if_leftover_values", test_name); error_occurred = 1; } if (error_occurred) { global_errors++; exit_test(); } } void teardown_testing(void) { list_free(&global_function_result_map_head, free_symbol_map_value, (void *) 0); initialize_source_location(&global_last_mock_value_location); list_free(&global_function_parameter_map_head, free_symbol_map_value, (void *) 1); initialize_source_location(&global_last_parameter_location); } // Initialize a list node. static ListNode *list_initialize(ListNode *const node) { node->value = NULL; node->next = node; node->prev = node; node->refcount = 1; return node; } /* Adds a value at the tail of a given list. * The node referencing the value is allocated from the heap. */ static ListNode *list_add_value(ListNode *const head, const void *value, const int refcount) { ListNode *const new_node = (ListNode *) malloc(sizeof(ListNode)); assert_true(head); assert_true(value); new_node->value = value; new_node->refcount = refcount; return list_add(head, new_node); } // Add new_node to the end of the list. static ListNode *list_add(ListNode *const head, ListNode *new_node) { assert_true(head); assert_true(new_node); new_node->next = head; new_node->prev = head->prev; head->prev->next = new_node; head->prev = new_node; return new_node; } // Remove a node from a list. static ListNode *list_remove(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data) { assert_true(node); node->prev->next = node->next; node->next->prev = node->prev; if (cleanup_value) { cleanup_value(node->value, cleanup_value_data); } return node; } /* Remove a list node from a list and free the node. */ static void list_remove_free(ListNode *const node, const CleanupListValue cleanup_value, void *const cleanup_value_data) { assert_true(node); free(list_remove(node, cleanup_value, cleanup_value_data)); } /* Frees memory kept by a linked list * The cleanup_value function is called for every "value" field of nodes in the * list, except for the head. In addition to each list value, * cleanup_value_data is passed to each call to cleanup_value. The head * of the list is not deallocated. */ static ListNode *list_free(ListNode *const head, const CleanupListValue cleanup_value, void *const cleanup_value_data) { assert_true(head); while (!list_empty(head)) { list_remove_free(head->next, cleanup_value, cleanup_value_data); } return head; } // Determine whether a list is empty. static int list_empty(const ListNode *const head) { assert_true(head); return head->next == head; } /* Find a value in the list using the equal_func to compare each node with the * value. */ static int list_find(ListNode *const head, const void *value, const EqualityFunction equal_func, ListNode **output) { ListNode *current; assert_true(head); for (current = head->next; current != head; current = current->next) { if (equal_func(current->value, value)) { *output = current; return 1; } } return 0; } // Returns the first node of a list static int list_first(ListNode *const head, ListNode **output) { ListNode *target_node; assert_true(head); if (list_empty(head)) { return 0; } target_node = head->next; *output = target_node; return 1; } #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__ * 10) >= 240) # define ARG_UNUSED __attribute__((unused)) #else # define ARG_UNUSED #endif // Deallocate a value referenced by a list. static void free_value(const void *value, ARG_UNUSED void *cleanup_value_data) { assert_true(value); free((void *) value); } // Releases memory associated to a symbol_map_value. static void free_symbol_map_value(const void *value, void *cleanup_value_data) { SymbolMapValue *const map_value = (SymbolMapValue *) value; const uintptr_t children = (uintptr_t) cleanup_value_data; assert_true(value); list_free(&map_value->symbol_values_list_head, children ? free_symbol_map_value : free_value, (void *) (children - 1)); free(map_value); } /* Determine whether a symbol name referenced by a symbol_map_value * matches the specified function name. */ static int symbol_names_match(const void *map_value, const void *symbol) { return !strcmp(((SymbolMapValue *) map_value)->symbol_name, (const char *) symbol); } /* Adds a value to the queue of values associated with the given * hierarchy of symbols. It's assumed value is allocated from the heap. */ static void add_symbol_value(ListNode *const symbol_map_head, const char *const symbol_names[], const size_t number_of_symbol_names, const void *value, const int refcount) { const char *symbol_name; ListNode *target_node; SymbolMapValue *target_map_value; assert_true(symbol_map_head); assert_true((const char *const *)symbol_names); assert_true(number_of_symbol_names); symbol_name = symbol_names[0]; if (!list_find(symbol_map_head, symbol_name, symbol_names_match, &target_node)) { SymbolMapValue *const new_symbol_map_value = malloc(sizeof(*new_symbol_map_value)); new_symbol_map_value->symbol_name = symbol_name; list_initialize(&new_symbol_map_value->symbol_values_list_head); target_node = list_add_value(symbol_map_head, new_symbol_map_value, 1); } target_map_value = (SymbolMapValue *) target_node->value; if (number_of_symbol_names == 1) { list_add_value(&target_map_value->symbol_values_list_head, value, refcount); } else { add_symbol_value(&target_map_value->symbol_values_list_head, &symbol_names[1], number_of_symbol_names - 1, value, refcount); } } /* Gets the next value associated with the given hierarchy of symbols. * The value is returned as an output parameter with the function returning the * node's old refcount value if a value is found, 0 otherwise. * This means that a return value of 1 indicates the node was just removed from * the list. */ static int get_symbol_value(ListNode *const head, const char *const symbol_names[], const size_t number_of_symbol_names, void **output) { const char *symbol_name; ListNode *target_node; assert_true(head); assert_true((const char *const *)symbol_names); assert_true(number_of_symbol_names); assert_true(output); symbol_name = symbol_names[0]; if (list_find(head, symbol_name, symbol_names_match, &target_node)) { SymbolMapValue *map_value; ListNode *child_list; int return_value = 0; assert_true(target_node); assert_true(target_node->value); map_value = (SymbolMapValue *) target_node->value; child_list = &map_value->symbol_values_list_head; if (number_of_symbol_names == 1) { ListNode *value_node = NULL; return_value = list_first(child_list, &value_node); assert_true(return_value); *output = (void *) value_node->value; return_value = value_node->refcount; if (--value_node->refcount == 0) { list_remove_free(value_node, NULL, NULL); } } else { return_value = get_symbol_value(child_list, &symbol_names[1], number_of_symbol_names - 1, output); } if (list_empty(child_list)) { list_remove_free(target_node, free_symbol_map_value, (void *) 0); } return return_value; } else { print_error("No entries for symbol %s.\n", symbol_name); } return 0; } /* Traverse down a tree of symbol values and remove the first symbol value * in each branch that has a refcount < -1 (i.e should always be returned * and has been returned at least once). */ static void remove_always_return_values(ListNode *const map_head, const size_t number_of_symbol_names) { ListNode *current; assert_true(map_head); assert_true(number_of_symbol_names); current = map_head->next; while (current != map_head) { SymbolMapValue *const value = (SymbolMapValue *) current->value; ListNode *const next = current->next; ListNode *child_list; assert_true(value); child_list = &value->symbol_values_list_head; if (!list_empty(child_list)) { if (number_of_symbol_names == 1) { ListNode *const child_node = child_list->next; // If this item has been returned more than once, free it. if (child_node->refcount < -1) { list_remove_free(child_node, free_value, NULL); } } else { remove_always_return_values(child_list, number_of_symbol_names - 1); } } if (list_empty(child_list)) { list_remove_free(current, free_value, NULL); } current = next; } } /* Checks if there are any leftover values set up by the test that were never * retrieved through execution, and fail the test if that is the case. */ static int check_for_leftover_values(const ListNode *const map_head, const char *const error_message, const size_t number_of_symbol_names) { const ListNode *current; int symbols_with_leftover_values = 0; assert_true(map_head); assert_true(number_of_symbol_names); for (current = map_head->next; current != map_head; current = current->next) { const SymbolMapValue *const value = (SymbolMapValue *) current->value; const ListNode *child_list; assert_true(value); child_list = &value->symbol_values_list_head; if (!list_empty(child_list)) { if (number_of_symbol_names == 1) { const ListNode *child_node; print_error(error_message, value->symbol_name); print_error(" Remaining item(s) declared at...\n"); for (child_node = child_list->next; child_node != child_list; child_node = child_node->next) { const SourceLocation *const location = child_node->value; print_error(" " SOURCE_LOCATION_FORMAT "\n", location->file, location->line); } } else { print_error("%s.", value->symbol_name); check_for_leftover_values(child_list, error_message, number_of_symbol_names - 1); } symbols_with_leftover_values++; } } return symbols_with_leftover_values; } LargestIntegralType _cast_to_largest_integral_type(size_t size, ...) { LargestIntegralType ret; va_list args; va_start(args, size); if (size <= sizeof(unsigned int)) { ret = va_arg(args, unsigned int); } else if (size <= sizeof(unsigned long)) { ret = va_arg(args, unsigned long); } else if (size <= sizeof(LargestIntegralType)) { ret = va_arg(args, LargestIntegralType); } else { assert(size <= sizeof(LargestIntegralType)); exit(255); } return ret; } // Get the next return value for the specified mock function. LargestIntegralType _mock(const char *const function, const char *const file, const int line) { void *result; const int rc = get_symbol_value(&global_function_result_map_head, &function, 1, &result); if (rc) { SymbolValue *const symbol = (SymbolValue *) result; const LargestIntegralType value = symbol->value; global_last_mock_value_location = symbol->location; if (rc == 1) { free(symbol); } return value; } else { print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to mock function %s\n", file, line, function); print_xml(XS_RUN_TEST_ERROR "\"ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to mock function %s\"\n", "_mock", file, line, function); if (source_location_is_set(&global_last_mock_value_location)) { print_error("Previously returned mock value was declared at " SOURCE_LOCATION_FORMAT "\n", global_last_mock_value_location.file, global_last_mock_value_location.line); print_xml(" \"Previously returned mock value was declared at " SOURCE_LOCATION_FORMAT "\">\n" XS_RUN_TEST_ERROR_END, global_last_mock_value_location.file, global_last_mock_value_location.line); } else { print_error("There were no previously returned mock values for " "this test.\n"); print_xml(" \"There were no previously returned mock values for this test.\">\n" XS_RUN_TEST_ERROR_END); } global_errors++; exit_test(); } return 0; } // Add a return value for the specified mock function name. void _will_return(const char *const function_name, const char *const file, const int line, const LargestIntegralType value, const int count) { SymbolValue *const return_value = malloc(sizeof(*return_value)); assert_true(count > 0 || count == -1); return_value->value = value; set_source_location(&return_value->location, file, line); add_symbol_value(&global_function_result_map_head, &function_name, 1, return_value, count); } /* Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event * parameter is provided it must be allocated on the heap and doesn't need to * be deallocated by the caller. */ void _expect_check(const char *const function, const char *const parameter, const char *const file, const int line, const CheckParameterValue check_function, const LargestIntegralType check_data, CheckParameterEvent *const event, const int count) { CheckParameterEvent *const check = event ? event : malloc(sizeof(*check)); const char *symbols[] = { function, parameter }; check->parameter_name = parameter; check->check_value = check_function; check->check_value_data = check_data; set_source_location(&check->location, file, line); add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, count); } /* Returns 1 if the specified values are equal. If the values are not equal * an error is displayed and 0 is returned. */ static int values_equal_display_error(const LargestIntegralType left, const LargestIntegralType right) { const int equal = left == right; if (!equal) { print_error(LargestIntegralTypePrintfFormat " != " LargestIntegralTypePrintfFormat "\n", left, right); } return equal; } /* Returns 1 if the specified values are not equal. If the values are equal * an error is displayed and 0 is returned. */ static int values_not_equal_display_error(const LargestIntegralType left, const LargestIntegralType right) { const int not_equal = left != right; if (!not_equal) { print_error(LargestIntegralTypePrintfFormat " == " LargestIntegralTypePrintfFormat "\n", left, right); } return not_equal; } /* Determine whether value is contained within check_integer_set. * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is * returned and an error is displayed. If invert is 1 and the value is not * in the set 1 is returned, otherwise 0 is returned and an error is * displayed. */ static int value_in_set_display_error(const LargestIntegralType value, const CheckIntegerSet *const check_integer_set, const int invert) { int succeeded = invert; assert_true(check_integer_set); { const LargestIntegralType *const set = check_integer_set->set; const size_t size_of_set = check_integer_set->size_of_set; size_t i; for (i = 0; i < size_of_set; i++) { if (set[i] == value) { // If invert = 0 and item is found, succeeded = 1. // If invert = 1 and item is found, succeeded = 0. succeeded = !succeeded; break; } } if (succeeded) { return 1; } print_error(LargestIntegralTypePrintfDecimal " is %sin the set (", value, invert ? "" : "not "); for (i = 0; i < size_of_set; i++) { print_error(LargestIntegralTypePrintfDecimal ", ", set[i]); } print_error(")\n"); } return 0; } /* Determine whether a value is within the specified range. If the value is * within the specified range 1 is returned. If the value isn't within the * specified range an error is displayed and 0 is returned. */ static int integer_in_range_display_error(const LargestIntegralType value, const LargestIntegralType range_min, const LargestIntegralType range_max) { if (value >= range_min && value <= range_max) { return 1; } print_error(LargestIntegralTypePrintfDecimal " is not within the range " LargestIntegralTypePrintfDecimal "-" LargestIntegralTypePrintfDecimal "\n", value, range_min, range_max); return 0; } /* Determine whether a value is within the specified range. If the value * is not within the range 1 is returned. If the value is within the * specified range an error is displayed and zero is returned. */ static int integer_not_in_range_display_error(const LargestIntegralType value, const LargestIntegralType range_min, const LargestIntegralType range_max) { if (value < range_min || value > range_max) { return 1; } print_error(LargestIntegralTypePrintfDecimal " is within the range " LargestIntegralTypePrintfDecimal "-" LargestIntegralTypePrintfDecimal "\n", value, range_min, range_max); return 0; } /* Determine whether the specified strings are equal. If the strings are equal * 1 is returned. If they're not equal an error is displayed and 0 is * returned. */ static int string_equal_display_error(const char *const left, const char *const right) { if (strcmp(left, right) == 0) { return 1; } print_error("\"%s\" != \"%s\"\n", left, right); return 0; } /* Determine whether the specified strings are equal. If the strings are not * equal 1 is returned. If they're not equal an error is displayed and 0 is * returned */ static int string_not_equal_display_error(const char *const left, const char *const right) { if (strcmp(left, right) != 0) { return 1; } print_error("\"%s\" == \"%s\"\n", left, right); return 0; } /* Determine whether the specified areas of memory are equal. If they're equal * 1 is returned otherwise an error is displayed and 0 is returned. */ static int memory_equal_display_error(const char *const a, const char *const b, const size_t size) { int differences = 0; size_t i; for (i = 0; i < size; i++) { const char l = a[i]; const char r = b[i]; if (l != r) { print_error("difference at offset %d 0x%02x 0x%02x\n", i, l, r); differences++; } } if (differences) { print_error("%d bytes of 0x%08x and 0x%08x differ\n", differences, a, b); return 0; } return 1; } /* Determine whether the specified areas of memory are not equal. If they're * not equal 1 is returned otherwise an error is displayed and 0 is * returned. */ static int memory_not_equal_display_error(const char *const a, const char *const b, const size_t size) { int same = 0; size_t i; for (i = 0; i < size; i++) { const char l = a[i]; const char r = b[i]; if (l == r) { same++; } } if (same == size) { print_error("%d bytes of 0x%08x and 0x%08x the same\n", same, a, b); return 0; } return 1; } // CheckParameterValue callback to check whether a value is within a set. static int check_in_set(const LargestIntegralType value, const LargestIntegralType check_value_data) { return value_in_set_display_error(value, cast_largest_integral_type_to_pointer(CheckIntegerSet *, check_value_data), 0); } // CheckParameterValue callback to check whether a value isn't within a set. static int check_not_in_set(const LargestIntegralType value, const LargestIntegralType check_value_data) { return value_in_set_display_error(value, cast_largest_integral_type_to_pointer(CheckIntegerSet *, check_value_data), 1); } /* Create the callback data for check_in_set() or check_not_in_set() and * register a check event. */ static void expect_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const CheckParameterValue check_function, const int count) { CheckIntegerSet *const check_integer_set = malloc(sizeof(*check_integer_set) + (sizeof(values[0]) * number_of_values)); LargestIntegralType *const set = (LargestIntegralType *) (check_integer_set + 1); declare_initialize_value_pointer_pointer(check_data, check_integer_set); assert_true((const unsigned long long *)values); assert_true(number_of_values); memcpy(set, values, number_of_values * sizeof(values[0])); check_integer_set->set = set; _expect_check(function, parameter, file, line, check_function, check_data.value, &check_integer_set->event, count); } // Add an event to check whether a value is in a set. void _expect_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count) { expect_set(function, parameter, file, line, values, number_of_values, check_in_set, count); } // Add an event to check whether a value isn't in a set. void _expect_not_in_set(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count) { expect_set(function, parameter, file, line, values, number_of_values, check_not_in_set, count); } // CheckParameterValue callback to check whether a value is within a range. static int check_in_range(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckIntegerRange *const check_integer_range = cast_largest_integral_type_to_pointer(CheckIntegerRange *, check_value_data); assert_true(check_integer_range); return integer_in_range_display_error(value, check_integer_range->minimum, check_integer_range->maximum); } // CheckParameterValue callback to check whether a value is not within a range. static int check_not_in_range(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckIntegerRange *const check_integer_range = cast_largest_integral_type_to_pointer(CheckIntegerRange *, check_value_data); assert_true(check_integer_range); return integer_not_in_range_display_error(value, check_integer_range->minimum, check_integer_range->maximum); } /* Create the callback data for check_in_range() or check_not_in_range() and * register a check event. */ static void expect_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const CheckParameterValue check_function, const int count) { CheckIntegerRange *const check_integer_range = malloc(sizeof(*check_integer_range)); declare_initialize_value_pointer_pointer(check_data, check_integer_range); check_integer_range->minimum = minimum; check_integer_range->maximum = maximum; _expect_check(function, parameter, file, line, check_function, check_data.value, &check_integer_range->event, count); } // Add an event to determine whether a parameter is within a range. void _expect_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count) { expect_range(function, parameter, file, line, minimum, maximum, check_in_range, count); } // Add an event to determine whether a parameter is not within a range. void _expect_not_in_range(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType minimum, const LargestIntegralType maximum, const int count) { expect_range(function, parameter, file, line, minimum, maximum, check_not_in_range, count); } /* CheckParameterValue callback to check whether a value is equal to an * expected value. */ static int check_value(const LargestIntegralType value, const LargestIntegralType check_value_data) { return values_equal_display_error(value, check_value_data); } // Add an event to check a parameter equals an expected value. void _expect_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count) { _expect_check(function, parameter, file, line, check_value, value, NULL, count); } /* CheckParameterValue callback to check whether a value is not equal to an * expected value. */ static int check_not_value(const LargestIntegralType value, const LargestIntegralType check_value_data) { return values_not_equal_display_error(value, check_value_data); } // Add an event to check a parameter is not equal to an expected value. void _expect_not_value(const char *const function, const char *const parameter, const char *const file, const int line, const LargestIntegralType value, const int count) { _expect_check(function, parameter, file, line, check_not_value, value, NULL, count); } // CheckParameterValue callback to check whether a parameter equals a string. static int check_string(const LargestIntegralType value, const LargestIntegralType check_value_data) { return string_equal_display_error(cast_largest_integral_type_to_pointer(char *, value), cast_largest_integral_type_to_pointer(char *, check_value_data)); } // Add an event to check whether a parameter is equal to a string. void _expect_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count) { declare_initialize_value_pointer_pointer(string_pointer, (char *) string); _expect_check(function, parameter, file, line, check_string, string_pointer.value, NULL, count); } /* CheckParameterValue callback to check whether a parameter is not equals to * a string. */ static int check_not_string(const LargestIntegralType value, const LargestIntegralType check_value_data) { return string_not_equal_display_error(cast_largest_integral_type_to_pointer(char *, value), cast_largest_integral_type_to_pointer(char *, check_value_data)); } // Add an event to check whether a parameter is not equal to a string. void _expect_not_string(const char *const function, const char *const parameter, const char *const file, const int line, const char *string, const int count) { declare_initialize_value_pointer_pointer(string_pointer, (char *) string); _expect_check(function, parameter, file, line, check_not_string, string_pointer.value, NULL, count); } /* CheckParameterValue callback to check whether a parameter equals an area of * memory. */ static int check_memory(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckMemoryData *const check = cast_largest_integral_type_to_pointer(CheckMemoryData *, check_value_data); assert_true(check); return memory_equal_display_error(cast_largest_integral_type_to_pointer(void *, value), check->memory, check->size); } /* Create the callback data for check_memory() or check_not_memory() and * register a check event. */ static void expect_memory_setup(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const CheckParameterValue check_function, const int count) { CheckMemoryData *const check_data = malloc(sizeof(*check_data) + size); void *const mem = (void *) (check_data + 1); declare_initialize_value_pointer_pointer(check_data_pointer, check_data); assert_true(memory); assert_true(size); memcpy(mem, memory, size); check_data->memory = mem; check_data->size = size; _expect_check(function, parameter, file, line, check_function, check_data_pointer.value, &check_data->event, count); } // Add an event to check whether a parameter matches an area of memory. void _expect_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count) { expect_memory_setup(function, parameter, file, line, memory, size, check_memory, count); } /* CheckParameterValue callback to check whether a parameter is not equal to * an area of memory. */ static int check_not_memory(const LargestIntegralType value, const LargestIntegralType check_value_data) { CheckMemoryData *const check = cast_largest_integral_type_to_pointer(CheckMemoryData *, check_value_data); assert_true(check); return memory_not_equal_display_error(cast_largest_integral_type_to_pointer(void *, value), check->memory, check->size); } // Add an event to check whether a parameter doesn't match an area of memory. void _expect_not_memory(const char *const function, const char *const parameter, const char *const file, const int line, const void *const memory, const size_t size, const int count) { expect_memory_setup(function, parameter, file, line, memory, size, check_not_memory, count); } // CheckParameterValue callback that always returns 1. static int check_any(ARG_UNUSED const LargestIntegralType value, ARG_UNUSED const LargestIntegralType check_value_data) { return 1; } // Add an event to allow any value for a parameter. void _expect_any(const char *const function, const char *const parameter, const char *const file, const int line, const int count) { _expect_check(function, parameter, file, line, check_any, 0, NULL, count); } void _check_expected(const char *const function_name, const char *const parameter_name, const char *file, const int line, const LargestIntegralType value) { void *result; const char *symbols[] = { function_name, parameter_name }; const int rc = get_symbol_value(&global_function_parameter_map_head, symbols, 2, &result); if (rc) { CheckParameterEvent *const check = (CheckParameterEvent *) result; int check_succeeded; global_last_parameter_location = check->location; check_succeeded = check->check_value(value, check->check_value_data); if (rc == 1) { free(check); } if (!check_succeeded) { print_error("ERROR: Check of parameter %s, function %s failed\n" "Expected parameter declared at " SOURCE_LOCATION_FORMAT "\n", parameter_name, function_name, global_last_parameter_location.file, global_last_parameter_location.line); print_xml(XS_RUN_TEST_ERROR "\"ERROR: Check of parameter %s, function %s failed\"\n" " \"Expected parameter declared at " SOURCE_LOCATION_FORMAT "\">\n" XS_RUN_TEST_ERROR_END, "check_expected", parameter_name, function_name, global_last_parameter_location.file, global_last_parameter_location.line); global_errors++; _fail(file, line); } } else { print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to check parameter %s of function %s\n", file, line, parameter_name, function_name); print_xml(XS_RUN_TEST_ERROR "\"ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " "to check parameter %s of function %s\"\n", "check_expected", file, line, parameter_name, function_name); if (source_location_is_set(&global_last_parameter_location)) { print_error("Previously declared parameter value was declared at " SOURCE_LOCATION_FORMAT "\n", global_last_parameter_location.file, global_last_parameter_location.line); print_xml(" \"Previously declared parameter value was declared at " SOURCE_LOCATION_FORMAT "\">\n" XS_RUN_TEST_ERROR_END, global_last_parameter_location.file, global_last_parameter_location.line); } else { print_error("There were no previously declared parameter values " "for this test.\n"); print_xml(" \"There were no previously declared parameter values " "for this test.\">\n" XS_RUN_TEST_ERROR_END); } global_errors++; exit_test (); } } // Replacement for assert. void mock_assert(const int result, const char *const expression, const char *const file, const int line) { if (!result) { if (global_expecting_assert) { global_expect_assert_expression = expression; longjmp(global_expect_assert_env, 1); } else { const char *assertname = "mock_assert"; print_error("ASSERT: %s\n", expression); print_xml (XS_RUN_TEST_FAILURE_ASSERT, assertname, result, global_filename, line, assertname, result); _fail(file, line); } } } void _assert_true(const LargestIntegralType result, const char *const expression, const char *const file, const int line) { if (!result) { const char *assertname = "assert_true"; print_error("%s\n", expression); print_xml (XS_RUN_TEST_FAILURE_ASSERT, assertname, result, global_filename, line, assertname, result); _fail(file, line); } } void _assert_int_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line) { if (!values_equal_display_error(a, b)) { const char *assertname = "assert_int_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_int_not_equal(const LargestIntegralType a, const LargestIntegralType b, const char *const file, const int line) { if (!values_not_equal_display_error(a, b)) { const char *assertname = "assert_int_not_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_string_equal(const char *const a, const char *const b, const char *const file, const int line) { if (!string_equal_display_error(a, b)) { const char *assertname = "assert_string_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_string_not_equal(const char *const a, const char *const b, const char *file, const int line) { if (!string_not_equal_display_error(a, b)) { const char *assertname = "assert_string_not_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_STRING, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_memory_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line) { if (!memory_equal_display_error((const char *) a, (const char *) b, size)) { const char *assertname = "assert_memory_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_memory_not_equal(const void *const a, const void *const b, const size_t size, const char *const file, const int line) { if (!memory_not_equal_display_error((const char *) a, (const char *) b, size)) { const char *assertname = "assert_memory_not_equal"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_EQUALITY_LLD, assertname, a, b, global_filename, line, assertname, a, b); _fail(file, line); } } void _assert_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line) { if (!integer_in_range_display_error(value, minimum, maximum)) { const char *assertname = "assert_in_range"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_RANGE_LLD, assertname, value, minimum, maximum, global_filename, line, assertname, value, minimum, maximum); _fail(file, line); } } void _assert_not_in_range(const LargestIntegralType value, const LargestIntegralType minimum, const LargestIntegralType maximum, const char *const file, const int line) { if (!integer_not_in_range_display_error(value, minimum, maximum)) { const char *assertname = "assert_not_in_range"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_RANGE_LLD, assertname, value, minimum, maximum, global_filename, line, assertname, value, minimum, maximum); _fail(file, line); } } void _assert_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line) { CheckIntegerSet check_integer_set; check_integer_set.set = values; check_integer_set.size_of_set = number_of_values; if (!value_in_set_display_error(value, &check_integer_set, 0)) { const char *assertname = "assert_in_set"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_SET_LLD, assertname, value, number_of_values, global_filename, line, assertname, value, number_of_values); _fail(file, line); } } void _assert_not_in_set(const LargestIntegralType value, const LargestIntegralType values[], const size_t number_of_values, const char *const file, const int line) { CheckIntegerSet check_integer_set; check_integer_set.set = values; check_integer_set.size_of_set = number_of_values; if (!value_in_set_display_error(value, &check_integer_set, 1)) { const char *assertname = "assert_not_in_set"; print_xml (XS_RUN_TEST_FAILURE_ASSERT_SET_LLD, assertname, value, number_of_values, global_filename, line, assertname, value, number_of_values); _fail(file, line); } } // Get the list of allocated blocks. static ListNode *get_allocated_blocks_list() { // If it initialized, initialize the list of allocated blocks. if (!global_allocated_blocks.value) { list_initialize(&global_allocated_blocks); global_allocated_blocks.value = (void *) 1; } return &global_allocated_blocks; } // Use the real malloc in this function. #undef malloc void *_test_malloc(const size_t size, const char *file, const int line) { char *ptr; MallocBlockInfo *block_info; ListNode *const block_list = get_allocated_blocks_list(); const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) + sizeof(*block_info) + MALLOC_ALIGNMENT; char *const block = (char *) malloc(allocate_size); assert_true(block); // Calculate the returned address. ptr = (char *) (((size_t) block + MALLOC_GUARD_SIZE + sizeof(*block_info) + MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); // Initialize the guard blocks. memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); memset(ptr, MALLOC_ALLOC_PATTERN, size); block_info = (MallocBlockInfo *) (ptr - (MALLOC_GUARD_SIZE + sizeof(*block_info))); set_source_location(&block_info->location, file, line); block_info->allocated_size = allocate_size; block_info->size = size; block_info->block = block; block_info->node.value = block_info; list_add(block_list, &block_info->node); return ptr; } #define malloc test_malloc void *_test_calloc(const size_t number_of_elements, const size_t size, const char *file, const int line) { void *const ptr = _test_malloc(number_of_elements * size, file, line); if (ptr) { memset(ptr, 0, number_of_elements * size); } return ptr; } // Use the real free in this function. #undef free void _test_free(void *const ptr, const char *file, const int line) { unsigned int i; char *block = (char *) ptr; MallocBlockInfo *block_info; _assert_true(ptr != NULL, "ptr", file, line); block_info = (MallocBlockInfo *) (block - (MALLOC_GUARD_SIZE + sizeof(*block_info))); // Check the guard blocks. { char *guards[2] = { block - MALLOC_GUARD_SIZE, block + block_info->size }; for (i = 0; i < ARRAY_LENGTH(guards); i++) { unsigned int j; char *const guard = guards[i]; for (j = 0; j < MALLOC_GUARD_SIZE; j++) { const char diff = guard[j] - MALLOC_GUARD_PATTERN; if (diff) { print_error("Guard block of 0x%08x size=%d allocated by " SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\n", (size_t) ptr, block_info->size, block_info->location.file, block_info->location.line, (size_t) &guard[j]); print_xml(XS_RUN_TEST_ERROR "\"Guard block of 0x%08x size=%d allocated by " SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\">\n" XS_RUN_TEST_ERROR_END, "test_free", (size_t) ptr, block_info->size, block_info->location.file, block_info->location.line, (size_t) &guard[j]); global_errors++; _fail(file, line); } } } } list_remove(&block_info->node, NULL, NULL); block = block_info->block; memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size); free(block); } #define free test_free // Crudely checkpoint the current heap state. static const ListNode *check_point_allocated_blocks() { return get_allocated_blocks_list()->prev; } /* Display the blocks allocated after the specified check point. This * function returns the number of blocks displayed. */ static int display_allocated_blocks(const ListNode *const check_point) { const ListNode *const head = get_allocated_blocks_list(); const ListNode *node; int allocated_blocks = 0; assert_true(check_point); assert_true(check_point->next); for (node = check_point->next; node != head; node = node->next) { const MallocBlockInfo *const block_info = node->value; assert_true(block_info); if (!allocated_blocks) { print_error("Blocks allocated...\n"); } print_error(" 0x%08x : " SOURCE_LOCATION_FORMAT "\n", block_info->block, block_info->location.file, block_info->location.line); allocated_blocks++; } return allocated_blocks; } // Free all blocks allocated after the specified check point. static void free_allocated_blocks(const ListNode *const check_point) { const ListNode *const head = get_allocated_blocks_list(); const ListNode *node; assert_true(check_point); node = check_point->next; assert_true(node); while (node != head) { MallocBlockInfo *const block_info = (MallocBlockInfo *) node->value; node = node->next; free((char *) block_info + sizeof(*block_info) + MALLOC_GUARD_SIZE); } } // Fail if any any blocks are allocated after the specified check point. static void fail_if_blocks_allocated(const ListNode *const check_point, const char *const test_name) { const int allocated_blocks = display_allocated_blocks(check_point); if (allocated_blocks) { free_allocated_blocks(check_point); print_error("ERROR: %s leaked %d block(s)\n", test_name, allocated_blocks); print_xml(XS_RUN_TEST_ERROR "\"ERROR: %s leaked %d block(s)\">\n" XS_RUN_TEST_ERROR_END, "fail_if_blocks_allocated", test_name, allocated_blocks); global_errors++; exit_test(); } } void _fail(const char *const file, const int line) { print_error("ERROR: " SOURCE_LOCATION_FORMAT " Failure!\n", file, line); exit_test(); } #ifndef _WIN32 static void exception_handler(int sig) { print_error("%s\n", strsignal(sig)); print_xml(XS_RUN_TEST_ERROR "\"%s\">\n" XS_RUN_TEST_ERROR_END, "exception_handler", strsignal(sig)); global_errors++; exit_test(); } #else // _WIN32 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { EXCEPTION_RECORD *const exception_record = exception_pointers->ExceptionRecord; const DWORD code = exception_record->ExceptionCode; unsigned int i; for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) { const ExceptionCodeInfo *const code_info = &exception_codes[i]; if (code == code_info->code) { static int shown_debug_message = 0; fflush(stdout); print_error("%s occurred at 0x%08x.\n", code_info->description, exception_record->ExceptionAddress); print_xml(XS_RUN_TEST_ERROR "\"%s occurred at 0x%08x.\">\n" XS_RUN_TEST_ERROR_END, "exception_filter", code_info->description, exception_record->ExceptionAddress); if (!shown_debug_message) { print_error("\n" "To debug in Visual Studio...\n" "1. Select menu item File->Open Project\n" "2. Change 'Files of type' to 'Executable Files'\n" "3. Open this executable.\n" "4. Select menu item Debug->Start\n" "\n" "Alternatively, set the environment variable \n" "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" "then click 'Debug' in the popup dialog box.\n" "\n"); shown_debug_message = 1; } global_errors++; exit_test_no_app(); return EXCEPTION_EXECUTE_HANDLER; } } return EXCEPTION_CONTINUE_SEARCH; } #endif // !_WIN32 void vinit_xml (const char *const format, va_list args) { FILE* xmlfile = fopen(global_xmlfile, "w"); vfprintf(xmlfile, format, args); fclose(xmlfile); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void init_xml (const char *const format, ...) { if (!global_is_file_writer_test) { va_list args; va_start(args, format); vinit_xml(format, args); va_end(args); } } void vprint_xml(const char *const format, va_list args) { FILE* xmlfile = fopen(global_xmlfile, "a"); vfprintf(xmlfile, format, args); fclose(xmlfile); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void print_xml(const char *const format, ...) { if (!global_is_file_writer_test) { va_list args; va_start(args, format); vprint_xml(format, args); va_end(args); } } void append_xml(const char *ofile, const char *ifile) { if (!global_is_file_writer_test) { char ch; FILE* xmlfile = fopen(ofile, "ab"); FILE* xml_tmp = fopen(ifile, "rb"); while(!feof(xml_tmp)) { ch = getc(xml_tmp); if(!feof(xml_tmp)) { putc(ch, xmlfile); } } fclose(xmlfile); fclose(xml_tmp); } } // Standard output and error print methods. void vprint_message(const char *const format, va_list args) { vprintf(format, args); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void vprint_error(const char *const format, va_list args) { vfprintf(stderr, format, args); #ifdef _WIN32 OutputDebugString(buffer); #endif // _WIN32 } void print_message(const char *const format, ...) { va_list args; va_start(args, format); vprint_message(format, args); va_end(args); } void print_error(const char *const format, ...) { va_list args; va_start(args, format); vprint_error(format, args); va_end(args); } int _run_test(const char *const function_name, const UnitTestFunction Function, void **const state, const UnitTestFunctionType function_type, const void *const heap_check_point) { const ListNode *const check_point = heap_check_point ? heap_check_point : check_point_allocated_blocks(); void *current_state = NULL; int rc = 1; int handle_exceptions = 1; #ifdef _WIN32 handle_exceptions = !IsDebuggerPresent(); #endif // _WIN32 #if UNIT_TESTING_DEBUG handle_exceptions = 0; #endif // UNIT_TESTING_DEBUG if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { default_signal_functions[i] = signal(exception_signals[i], exception_handler); } #else // _WIN32 previous_exception_filter = SetUnhandledExceptionFilter(exception_filter); #endif // !_WIN32 } if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST || function_type == UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE) { print_message("%s: Starting test\n", function_name); } initialize_testing(); global_running_test = 1; if (setjmp(global_run_test_env) == 0) { if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { Function(); } else { ((UnitTestFunctionWithState)Function)(state ? state : ¤t_state); } fail_if_leftover_values(function_name); /* If this is a setup function then ignore any allocated blocks * only ensure they're deallocated on tear down. */ if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { fail_if_blocks_allocated(check_point, function_name); } global_running_test = 0; if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST || function_type == UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE) { print_message("%s: Test completed successfully.\n", function_name); } rc = 0; } else { global_running_test = 0; print_message("%s: Test failed.\n", function_name); } teardown_testing(); if (handle_exceptions) { #ifndef _WIN32 unsigned int i; for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { signal(exception_signals[i], default_signal_functions[i]); } #else // _WIN32 if (previous_exception_filter) { SetUnhandledExceptionFilter(previous_exception_filter); previous_exception_filter = NULL; } #endif // !_WIN32 } return rc; } int _run_tests(const UnitTest *const tests, const size_t number_of_tests, const char *const file) { // Whether to execute the next test. int run_next_test = 1; // Whether the previous test failed. int previous_test_failed = 0; // Check point of the heap state. const ListNode *const check_point = check_point_allocated_blocks(); // Time of testsuite execution time_t time_suite, time_case, time_now; time_t ttime; time(&ttime); char timestamp[1024]; strcpy(timestamp, ctime(&ttime)); timestamp[strlen(timestamp)-1] = '\0'; // Current test being executed. size_t current_test = 0; // Number of tests executed. size_t tests_executed = 0; // Number of failed tests. size_t total_failed = 0; // Number of setup functions. size_t setups = 0; // Number of teardown functions. size_t teardowns = 0; /* A stack of test states. A state is pushed on the stack * when a test setup occurs and popped on tear down. */ TestState *test_states = malloc(number_of_tests * sizeof(*test_states)); size_t number_of_test_states = 0; // Names of the tests that failed. const char **failed_names = malloc(number_of_tests * sizeof(*failed_names)); void **current_state = NULL; // Make sure LargestIntegralType is at least the size of a pointer. assert_true(sizeof(LargestIntegralType) >= sizeof(void *)); //Initialize an xml file and parameters char path[1024] = {0}; char filename[1024] = {0}; char suitename[1024] = {0}; char casename[1024] = {0}; char xmlfile[sizeof(suitename) + sizeof(".xml")] = {0}; int len; strcpy(path, file); strcpy(filename, basename(path)); len = strrchr(filename, '.')-filename; strcpy(suitename, ""); strncat(suitename, filename, len); strcpy(xmlfile, "xml_tmp_suite"); global_filename = filename; global_is_file_writer_test = (0 == strcmp(suitename, "file_writer_test")); global_xmlfile = xmlfile; global_errors = 0; init_xml(""); time(&time_suite); while (current_test < number_of_tests) { const ListNode *test_check_point = NULL; TestState *current_TestState; const UnitTest *const test = &tests[current_test++]; if (!test->f.function) { continue; } switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: case UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE: run_next_test = 1; break; case UNIT_TEST_FUNCTION_TYPE_SETUP: { // Checkpoint the heap before the setup. current_TestState = &test_states[number_of_test_states++]; current_TestState->check_point = check_point_allocated_blocks(); test_check_point = current_TestState->check_point; current_state = ¤t_TestState->state; *current_state = NULL; run_next_test = 1; setups++; break; } case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: // Check the heap based on the last setup checkpoint. assert_true(number_of_test_states); current_TestState = &test_states[--number_of_test_states]; test_check_point = current_TestState->check_point; current_state = ¤t_TestState->state; teardowns++; break; default: print_error("Invalid unit test function type %d\n", test->function_type); print_xml(XS_RUN_TEST_ERROR "\"Invalid unit test function type %d\">\n" XS_RUN_TEST_ERROR_END, "", test->function_type); global_errors++; exit_test(); break; } if (run_next_test) { strcpy(casename, test->name); strcpy(xmlfile, "xml_tmp_case"); init_xml(""); time(&time_case); int failed = _run_test(test->name, test->f.function, current_state, test->function_type, test_check_point); strcpy(xmlfile, "xml_tmp_suite"); time(&time_now); print_xml(XS_TESTCASE, casename, path, difftime(time_now, time_case)); if (failed) { failed_names[total_failed] = test->name; append_xml("xml_tmp_suite", "xml_tmp_case"); } print_xml(XS_TESTCASE_END); switch (test->function_type) { case UNIT_TEST_FUNCTION_TYPE_TEST: case UNIT_TEST_FUNCTION_TYPE_TEST_WITH_STATE: previous_test_failed = failed; total_failed += failed; tests_executed++; break; case UNIT_TEST_FUNCTION_TYPE_SETUP: if (failed) { total_failed++; tests_executed++; // Skip forward until the next test or setup function. run_next_test = 0; } previous_test_failed = 0; break; case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: // If this test failed. if (failed && !previous_test_failed) { total_failed++; } break; default: assert_false("BUG: shouldn't be here!"); break; } } } snprintf(xmlfile, sizeof(xmlfile), "%s.xml", suitename); time(&time_now); init_xml(XS_INIT_TESTSUITE, suitename, timestamp, "localhost", number_of_tests, total_failed, global_errors, difftime(time_now, time_suite)); append_xml(xmlfile, "xml_tmp_suite"); print_xml(XS_TESTSUITE_END); if (total_failed) { size_t i; print_error("%d out of %d tests failed!\n", total_failed, tests_executed); for (i = 0; i < total_failed; i++) { print_error(" %s\n", failed_names[i]); } } else { print_message("All %d tests passed\n", tests_executed); } if (number_of_test_states) { print_error("Mismatched number of setup %d and teardown %d " "functions\n", setups, teardowns); total_failed = -1; } free(test_states); free((void *) failed_names); fail_if_blocks_allocated(check_point, "run_tests"); return (int) total_failed; } /* LCOV_EXCL_STOP */ cfengine-3.24.2/tests/unit/sort_test.c0000644000000000000000000001003615010704253017666 0ustar00rootroot00000000000000#include #include #include #include #include /* * Those testcases only perform smoke testing of sorting functionality. */ void test_sort_item_list_names(void) { Item *head = xcalloc(1, sizeof(Item)); head->name = xstrdup("c"); head->next = xcalloc(1, sizeof(Item)); head->next->name = xstrdup("b"); head->next->next = xcalloc(1, sizeof(Item)); head->next->next->name = xstrdup("a"); Item *sorted = SortItemListNames(head); assert_string_equal(sorted->name, "a"); assert_string_equal(sorted->next->name, "b"); assert_string_equal(sorted->next->next->name, "c"); assert_int_equal(sorted->next->next->next, NULL); DeleteItemList(sorted); } void test_sort_item_list_classes(void) { Item *head = xcalloc(1, sizeof(Item)); head->classes = xstrdup("b"); head->next = xcalloc(1, sizeof(Item)); head->next->classes = xstrdup("c"); head->next->next = xcalloc(1, sizeof(Item)); head->next->next->classes = xstrdup("a"); Item *sorted = SortItemListClasses(head); assert_string_equal(sorted->classes, "a"); assert_string_equal(sorted->next->classes, "b"); assert_string_equal(sorted->next->next->classes, "c"); assert_int_equal(sorted->next->next->next, NULL); DeleteItemList(sorted); } void test_sort_item_list_counters(void) { Item *head = xcalloc(1, sizeof(Item)); head->counter = -1; head->next = xcalloc(1, sizeof(Item)); head->next->counter = 42; head->next->next = xcalloc(1, sizeof(Item)); head->next->next->counter = 146; Item *sorted = SortItemListCounters(head); /* Weird. Counters are sorted backwards */ assert_int_equal(sorted->counter, 146); assert_int_equal(sorted->next->counter, 42); assert_int_equal(sorted->next->next->counter, -1); assert_int_equal(sorted->next->next->next, NULL); DeleteItemList(sorted); } void test_sort_item_list_times(void) { Item *head = xcalloc(1, sizeof(Item)); head->time = 1; head->next = xcalloc(1, sizeof(Item)); head->next->time = 1998; head->next->next = xcalloc(1, sizeof(Item)); head->next->next->time = 4000; Item *sorted = SortItemListCounters(head); assert_int_equal(sorted->time, 4000); assert_int_equal(sorted->next->time, 1998); assert_int_equal(sorted->next->next->time, 1); assert_int_equal(sorted->next->next->next, NULL); DeleteItemList(sorted); } bool FirstItemShorter(const char *lhs, const char *rhs) { return (strlen(lhs) < strlen(rhs)); } void test_sort_rlist(void) { Rlist *list = NULL; RlistAppendScalar(&list, "bbb"); RlistAppendScalar(&list, "cc"); RlistAppendScalar(&list, "a"); Rlist *sorted = SortRlist(list, &FirstItemShorter); assert_string_equal(RlistScalarValue(sorted), "a"); assert_string_equal(RlistScalarValue(sorted->next), "cc"); assert_string_equal(RlistScalarValue(sorted->next->next), "bbb"); assert_int_equal(sorted->next->next->next, NULL); RlistDestroy(sorted); } void test_alpha_sort_rlist_names(void) { Rlist *list = NULL; RlistAppendScalar(&list, "c"); RlistAppendScalar(&list, "a"); RlistAppendScalar(&list, "b"); Rlist *sorted = AlphaSortRListNames(list); assert_string_equal(RlistScalarValue(sorted), "a"); assert_string_equal(RlistScalarValue(sorted->next), "b"); assert_string_equal(RlistScalarValue(sorted->next->next), "c"); assert_int_equal(sorted->next->next->next, NULL); RlistDestroy(sorted); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_sort_item_list_names), unit_test(test_sort_item_list_classes), unit_test(test_sort_item_list_counters), unit_test(test_sort_item_list_times), unit_test(test_sort_rlist), unit_test(test_alpha_sort_rlist_names), }; return run_tests(tests); } /* STUBS */ /* void __ProgrammingError(const char *file, int lineno, const char *format, ...) { fail(); exit(42); } void FatalError(char *s, ...) { fail(); exit(42); } */ cfengine-3.24.2/tests/unit/strlist_test.c0000644000000000000000000002567115010704253020416 0ustar00rootroot00000000000000#include #include #include static StrList *PATH_SL, *HOSTNAME_SL; /* Strings that will be inserted to strlist, listed here in sorted order. */ char *PATH_STRINGS[] = { " ", " ", "/", "/path", "/path/to/file.name", "blah", "waza", }; #define PATH_STRINGS_LEN (sizeof(PATH_STRINGS) / sizeof(PATH_STRINGS[0])) /* Ideally we need the numbers [0..PATH_STRINGS_LEN) in random order in order to * insert non-sorted. To make the test reproducible, here is one random * order. Feel free to experiment with changing this. */ size_t PATH_INSERT_ORDER[PATH_STRINGS_LEN] = { 5, 3, 1, 0, 4, 6, 2 }; /* Strings that will be inserted to strlist, listed here in special sorted * order in the way they should end up after calling * StrList_Sort(string_CompareFromEnd). */ char *HOSTNAME_STRINGS[] = { "*", /* Globs have no special meaning */ ".*", /* Should not match anything */ ".", /* Should not match as well */ "com", /* No match, nobody has "com" fqdn */ "cfengine.com", /* Match this hostname */ ".allowed.cfengine.com", /* Allow everything under this domain */ "www.cfengine.com", /* Match this hostname */ ".no", /* Allow all norwegian hostnames */ }; #define HOSTNAME_STRINGS_LEN (sizeof(HOSTNAME_STRINGS) / sizeof(HOSTNAME_STRINGS[0])) /* Ideally we need the numbers [0..PATH_STRINGS_LEN) in random order in order to * insert non-sorted. To make the test reproducible, here is one random * order. Feel free to experiment with changing this. */ size_t HOSTNAME_INSERT_ORDER[HOSTNAME_STRINGS_LEN] = { 5, 3, 1, 0, 4, 6, 2, 7 }; static StrList *init_strlist(char ** strings, size_t strings_len, size_t *insert_order) { StrList *sl = calloc(1, sizeof(*sl)); /* Insert in random order. */ for (size_t i = 0; i < strings_len; i++) { size_t ret = StrList_Append(&sl, strings[ insert_order[i] ]); assert_int_equal(ret, i); assert_string_equal(StrList_At(sl, i), strings[ insert_order[i] ]); } assert_int_equal(StrList_Len(sl), strings_len); StrList_Finalise(&sl); return sl; } static void test_init_SL() { PATH_SL = init_strlist(PATH_STRINGS, PATH_STRINGS_LEN, PATH_INSERT_ORDER); HOSTNAME_SL = init_strlist(HOSTNAME_STRINGS, HOSTNAME_STRINGS_LEN, HOSTNAME_INSERT_ORDER); } /* Sort PATH_STRLIST using the common way, and HOSTNAME_STRLIST in the order * of reading the strings backwards. */ static void test_StrList_Sort() { StrList_Sort(PATH_SL, string_Compare); assert_int_equal(StrList_Len(PATH_SL), PATH_STRINGS_LEN); for (size_t i = 0; i < PATH_STRINGS_LEN; i++) { assert_string_equal(StrList_At(PATH_SL, i), PATH_STRINGS[i]); } StrList_Sort(HOSTNAME_SL, string_CompareFromEnd); assert_int_equal(StrList_Len(HOSTNAME_SL), HOSTNAME_STRINGS_LEN); for (size_t i = 0; i < HOSTNAME_STRINGS_LEN; i++) { assert_string_equal(StrList_At(HOSTNAME_SL, i), HOSTNAME_STRINGS[i]); } } /* Only search in PATH_STRLIST which is sorted in the common way. */ static void test_StrList_BinarySearch() { size_t pos; bool found; /* Search for existing strings. */ for (size_t i = 0; i < PATH_STRINGS_LEN; i++) { found = StrList_BinarySearch(PATH_SL, PATH_STRINGS[i], &pos); assert_int_equal(found, true); assert_int_equal(pos, i); } /* Search for inexistent entries, check that the returned position is the * one they should be inserted into. */ found = StrList_BinarySearch(PATH_SL, "", &pos); assert_int_equal(found, false); assert_int_equal(pos, 0); /* empty string should always come first */ found = StrList_BinarySearch(PATH_SL, " ", &pos); assert_int_equal(found, false); assert_int_equal(pos, 2); found = StrList_BinarySearch(PATH_SL, "zzz", &pos); assert_int_equal(found, false); assert_int_equal(pos, PATH_STRINGS_LEN); found = StrList_BinarySearch(PATH_SL, "/path/", &pos); assert_int_equal(found, false); assert_int_equal(pos, 4); found = StrList_BinarySearch(PATH_SL, "/path/to", &pos); assert_int_equal(found, false); assert_int_equal(pos, 4); } /* Only search in PATH_STRLIST because it makes sense to search longest prefix * for paths. */ static void test_StrList_SearchLongestPrefix() { /* REMINDER: PATH_STRINGS[] = { " ", " ", "/", "/path", "/path/to/file.name", "blah", "waza" }; */ size_t ret, ret2, ret3; /* These searches all search for "/path", since length is the same. */ ret = StrList_SearchLongestPrefix(PATH_SL, "/path", 0, '/', true); ret2 = StrList_SearchLongestPrefix(PATH_SL, "/path/", 5, '/', true); ret3 = StrList_SearchLongestPrefix(PATH_SL, "/path/to/file.name", 5, '/', true); assert_string_equal(StrList_At(PATH_SL, ret), "/path"); assert_string_equal(StrList_At(PATH_SL, ret2), "/path"); assert_string_equal(StrList_At(PATH_SL, ret3), "/path"); /* Searching for "/path/" does not bring up "/path", but "/", since * directories *must* have a trailing slash. */ ret = StrList_SearchLongestPrefix(PATH_SL, "/path/", 0, '/', true); assert_string_equal(StrList_At(PATH_SL, ret), "/"); ret = StrList_SearchLongestPrefix(PATH_SL, "/path.json", 0, '/', true); assert_string_equal(StrList_At(PATH_SL, ret), "/"); /* We insert a couple more directories and sort again. */ StrList_Append(&PATH_SL, "/path/to/file.namewhatever/whatever"); StrList_Append(&PATH_SL, "/path/to/file.name/whatever/"); StrList_Append(&PATH_SL, "/path/to/"); StrList_Sort(PATH_SL, string_Compare); ret = StrList_SearchLongestPrefix(PATH_SL, "/path/to/file.name", 0, '/', true); assert_string_equal(StrList_At(PATH_SL, ret), "/path/to/file.name"); ret = StrList_SearchLongestPrefix(PATH_SL, "/path/to/file", 0, '/', true); assert_string_equal(StrList_At(PATH_SL, ret), "/path/to/"); ret = StrList_SearchLongestPrefix(PATH_SL, "/path/to/file.name/whatever/blah", 0, '/', true); assert_string_equal(StrList_At(PATH_SL, ret), "/path/to/file.name/whatever/"); ret = StrList_SearchLongestPrefix(PATH_SL, "/path/to/", 0, '/', true); assert_string_equal(StrList_At(PATH_SL, ret), "/path/to/"); } /* Only search in HOSTNAME_STRLIST because it only makes sense to search for * longest suffix with hostnames and subdomains. */ static void test_StrList_SearchLongestSuffix() { /* REMINDER: HOSTNAME_STRINGS[] = { "*", ".*", ".", "com", "cfengine.com", ".allowed.cfengine.com", "www.cfengine.com", ".no" }; */ size_t ret, ret2, ret3, ret4, ret5, ret6, ret7, ret8, ret9, ret10, ret11; ret = StrList_SearchLongestPrefix(HOSTNAME_SL, "cfengine.com", 0, '.', false); ret2 = StrList_SearchLongestPrefix(HOSTNAME_SL, "google.com", 0, '.', false); ret3 = StrList_SearchLongestPrefix(HOSTNAME_SL, "yr.no", 0, '.', false); ret4 = StrList_SearchLongestPrefix(HOSTNAME_SL, "ntua.gr", 0, '.', false); ret5 = StrList_SearchLongestPrefix(HOSTNAME_SL, "disallowed.cfengine.com", 0, '.', false); ret6 = StrList_SearchLongestPrefix(HOSTNAME_SL, "allowed.cfengine.com", 0, '.', false); ret7 = StrList_SearchLongestPrefix(HOSTNAME_SL, "blah.allowed.cfengine.com", 0, '.', false); ret8 = StrList_SearchLongestPrefix(HOSTNAME_SL, "www.cfengine.com", 0, '.', false); ret9 = StrList_SearchLongestPrefix(HOSTNAME_SL, "www1.cfengine.com", 0, '.', false); ret10 = StrList_SearchLongestPrefix(HOSTNAME_SL, "1www.cfengine.com", 0, '.', false); ret11 = StrList_SearchLongestPrefix(HOSTNAME_SL, "no", 0, '.', false); assert_string_equal(StrList_At(HOSTNAME_SL, ret), "cfengine.com"); assert_int_equal(ret2, (size_t) -1); assert_string_equal(StrList_At(HOSTNAME_SL, ret3), ".no"); assert_int_equal(ret4, (size_t) -1); assert_int_equal(ret5, (size_t) -1); assert_int_equal(ret6, (size_t) -1); assert_string_equal(StrList_At(HOSTNAME_SL, ret7), ".allowed.cfengine.com"); assert_string_equal(StrList_At(HOSTNAME_SL, ret8), "www.cfengine.com"); assert_int_equal(ret9, (size_t) -1); assert_int_equal(ret10, (size_t) -1); assert_int_equal(ret11, (size_t) -1); } static void test_StrList_SearchForSuffix() { /* REMINDER: HOSTNAME_STRINGS[] = { "*", ".*", ".", "com", "cfengine.com", ".allowed.cfengine.com", "www.cfengine.com", ".no" }; */ size_t ret, ret2, ret3, ret4, ret5, ret6, ret7, ret8, ret9, ret10, ret11; ret = StrList_SearchForPrefix(HOSTNAME_SL, "cfengine.com", 0, false); ret2 = StrList_SearchForPrefix(HOSTNAME_SL, "google.com", 0, false); ret3 = StrList_SearchForPrefix(HOSTNAME_SL, "yr.no", 0, false); ret4 = StrList_SearchForPrefix(HOSTNAME_SL, "ntua.gr", 0, false); ret5 = StrList_SearchForPrefix(HOSTNAME_SL, "disallowed.cfengine.com", 0, false); ret6 = StrList_SearchForPrefix(HOSTNAME_SL, "allowed.cfengine.com", 0, false); ret7 = StrList_SearchForPrefix(HOSTNAME_SL, "blah.allowed.cfengine.com", 0, false); ret8 = StrList_SearchForPrefix(HOSTNAME_SL, "www.cfengine.com", 0, false); ret9 = StrList_SearchForPrefix(HOSTNAME_SL, "www1.cfengine.com", 0, false); ret10 = StrList_SearchForPrefix(HOSTNAME_SL, "1www.cfengine.com", 0, false); ret11 = StrList_SearchForPrefix(HOSTNAME_SL, "no", 0, false); /* SearchForPrefix() does not guarantee which one of all the matches it * will return if there are many matches. */ /* E.g. the first search might return "cfengine.com" or "com" entry. */ LargestIntegralType set[] = {3, 4}; assert_in_set(ret, set, 2); assert_string_equal(StrList_At(HOSTNAME_SL, ret2), "com"); assert_string_equal(StrList_At(HOSTNAME_SL, ret3), ".no"); assert_int_equal(ret4, (size_t) -1); assert_in_set(ret5, set, 2); assert_in_set(ret6, set, 2); LargestIntegralType set2[] = {3, 4, 5}; assert_in_set(ret7, set2, 3); assert_in_set(ret8, set, 2); assert_in_set(ret9, set, 2); LargestIntegralType set3[] = {3, 4, 6}; assert_in_set(ret10, set3, 3); assert_int_equal(ret11, (size_t) -1); } static void test_StrList_Free() { StrList_Free(&PATH_SL); assert_int_equal(PATH_SL, NULL); StrList_Free(&HOSTNAME_SL); assert_int_equal(HOSTNAME_SL, NULL); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_init_SL), unit_test(test_StrList_Sort), unit_test(test_StrList_BinarySearch), unit_test(test_StrList_SearchLongestPrefix), unit_test(test_StrList_SearchLongestSuffix), unit_test(test_StrList_SearchForSuffix), unit_test(test_StrList_Free) }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/tests/unit/files_lib_test.c0000644000000000000000000001013315010704253020625 0ustar00rootroot00000000000000#include #include #include #include /* xsnprintf */ #define FILE_CONTENTS "8aysd9a8ydhsdkjnaldn12lk\njndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1lkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1lkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1lkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1lkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljew\nnbfdhwjebfkjhbnkjdn1lkdjn1lkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1l\rkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1\r\nlkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1lkjn38aysd9a8ydhsdkjnaldn12lkjndl1jndljewnbfdhwjebfkjhbnkjdn1lkdjn1lkjn3" #define FILE_SIZE (sizeof(FILE_CONTENTS) - 1) char CFWORKDIR[CF_BUFSIZE]; char FILE_NAME[CF_BUFSIZE]; char FILE_NAME_EMPTY[CF_BUFSIZE]; static void tests_setup(void) { xsnprintf(CFWORKDIR, CF_BUFSIZE, "/tmp/files_lib_test.XXXXXX"); mkdtemp(CFWORKDIR); xsnprintf(FILE_NAME, CF_BUFSIZE, "%s/cfengine_file_test", CFWORKDIR); xsnprintf(FILE_NAME_EMPTY, CF_BUFSIZE, "%s/cfengine_file_test_empty", CFWORKDIR); } static void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } void test_file_write(void) { bool res = FileWriteOver(FILE_NAME, FILE_CONTENTS); assert_true(res); } void test_file_read_all(void) { bool truncated; Writer *w = FileRead(FILE_NAME, FILE_SIZE, &truncated); assert_int_equal(StringWriterLength(w), FILE_SIZE); assert_string_equal(StringWriterData(w), FILE_CONTENTS); assert_int_equal(truncated, false); WriterClose(w); Writer *w2 = FileRead(FILE_NAME, FILE_SIZE * 10, &truncated); assert_int_equal(StringWriterLength(w2), FILE_SIZE); assert_string_equal(StringWriterData(w2), FILE_CONTENTS); assert_int_equal(truncated, false); WriterClose(w2); Writer *w3 = FileRead(FILE_NAME, FILE_SIZE * 10, NULL); assert_int_equal(StringWriterLength(w3), FILE_SIZE); assert_string_equal(StringWriterData(w3), FILE_CONTENTS); WriterClose(w3); } void test_file_read_truncate(void) { char expected_output[FILE_SIZE + 1]; bool truncated = false; Writer *w = FileRead(FILE_NAME, FILE_SIZE - 1, &truncated); assert_int_equal(StringWriterLength(w), FILE_SIZE - 1); strlcpy(expected_output, FILE_CONTENTS, FILE_SIZE); assert_string_equal(StringWriterData(w), expected_output); assert_int_equal(truncated, true); WriterClose(w); bool truncated2 = false; Writer *w2 = FileRead(FILE_NAME, 10, &truncated2); assert_int_equal(StringWriterLength(w2), 10); strlcpy(expected_output, FILE_CONTENTS, 11); assert_string_equal(StringWriterData(w2), expected_output); assert_int_equal(truncated2, true); WriterClose(w2); bool truncated3 = false; Writer *w3 = FileRead(FILE_NAME, 1, &truncated3); assert_int_equal(StringWriterLength(w3), 1); strlcpy(expected_output, FILE_CONTENTS, 2); assert_string_equal(StringWriterData(w3), expected_output); assert_int_equal(truncated3, true); WriterClose(w3); } void test_file_read_empty(void) { int creat_fd = creat(FILE_NAME_EMPTY, 0600); assert_true(creat_fd > -1); int close_res = close(creat_fd); assert_int_equal(close_res, 0); bool truncated = true; Writer *w = FileRead(FILE_NAME_EMPTY, 100, &truncated); assert_int_equal(StringWriterLength(w), 0); assert_string_equal(StringWriterData(w), ""); assert_int_equal(truncated, false); WriterClose(w); } void test_file_read_invalid(void) { Writer *w = FileRead("nonexisting file", 100, NULL); assert_false(w); } int main() { PRINT_TEST_BANNER(); tests_setup(); const UnitTest tests[] = { unit_test(test_file_write), unit_test(test_file_read_all), unit_test(test_file_read_truncate), unit_test(test_file_read_empty), unit_test(test_file_read_invalid), }; int ret = run_tests(tests); tests_teardown(); return ret; } cfengine-3.24.2/tests/unit/lastseen_test.c0000644000000000000000000004565415010704253020533 0ustar00rootroot00000000000000#include #include #include #include #include #include /* xsnprintf */ #include char CFWORKDIR[CF_BUFSIZE]; void UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); /* For abbreviation of tests. */ #define IP1 "127.0.0.121" #define IP2 "127.0.0.122" #define IP3 "127.0.0.123" #define KEY1 "SHA=key1" #define KEY2 "SHA=key2" #define KEY3 "SHA=key3" #define ACC LAST_SEEN_ROLE_ACCEPT #define DBHasStr(dbh, s) HasKeyDB(dbh, s, strlen(s)+1) #define DBPutStr(dbh, k, s) WriteDB(dbh, k, s, strlen(s)+1) char tmpbuf[CF_BUFSIZE]; #define DBGetStr(dbh, s) (ReadDB(dbh, s, tmpbuf, sizeof(tmpbuf)) ? tmpbuf : NULL) static void tests_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/lastseen_test.XXXXXX"; char *workdir = strchr(env, '=') + 1; /* start of the path */ assert(workdir - 1 && workdir[0] == '/'); mkdtemp(workdir); strlcpy(CFWORKDIR, workdir, CF_BUFSIZE); putenv(env); mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); } static void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", GetStateDir()); system(cmd); xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", GetWorkDir()); system(cmd); } static void setup(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'/*", GetStateDir()); system(cmd); } static void test_newentry(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 666); DBHandle *db; OpenDB(&db, dbid_lastseen); KeyHostSeen q; assert_int_equal(ReadDB(db, "qiSHA-12345", &q, sizeof(q)), true); assert_false(q.acknowledged); assert_int_equal(q.lastseen, 666); assert_double_close(q.Q.q, 0.0); assert_double_close(q.Q.dq, 0.0); assert_double_close(q.Q.expect, 0.0); assert_double_close(q.Q.var, 0.0); assert_int_equal(ReadDB(db, "qoSHA-12345", &q, sizeof(q)), false); char address[CF_BUFSIZE]; assert_int_equal(ReadDB(db, "kSHA-12345", address, sizeof(address)), true); assert_string_equal(address, "127.0.0.64"); char hostkey[CF_BUFSIZE]; assert_int_equal(ReadDB(db, "a127.0.0.64", hostkey, sizeof(hostkey)), true); assert_string_equal(hostkey, "SHA-12345"); CloseDB(db); } static void test_update(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 1110); DBHandle *db; OpenDB(&db, dbid_lastseen); KeyHostSeen q; assert_int_equal(ReadDB(db, "qiSHA-12345", &q, sizeof(q)), true); assert_false(q.acknowledged); assert_int_equal(q.lastseen, 1110); assert_double_close(q.Q.q, 555.0); assert_double_close(q.Q.dq, 555.0); assert_double_close(q.Q.expect, 222.0); assert_double_close(q.Q.var, 123210.0); CloseDB(db); } static void test_HostkeyToAddress(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555); char *address = HostkeyToAddress("SHA-12345"); assert_string_equal(address, "127.0.0.64"); free(address); } static void test_reverse_missing(void) { setup(); /* Check that resolution return false */ char result[CF_BUFSIZE]; assert_int_equal(Address2Hostkey(result, sizeof(result), "127.0.0.64"), false); } static void test_reverse_conflict(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555); /* Overwrite reverse entry with different one. */ DBHandle *db; OpenDB(&db, dbid_lastseen); assert_int_equal(WriteDB(db, "a127.0.0.64", "SHA-98765", strlen("SHA-98765") + 1), true); /* Check that resolution returns the last forced entry and is not bothered * by the inconsistency (despite outputing a warning). */ char result[CF_BUFSIZE]; assert_int_equal(Address2Hostkey(result, sizeof(result), "127.0.0.64"), true); assert_string_equal(result, "SHA-98765"); /* Both entries still exist despite inconsistency. */ assert_int_equal(DBHasStr(db, "a127.0.0.64"), true); assert_int_equal(DBHasStr(db, "kSHA-12345"), true); /* And the inconsistency (missing entry) is not auto-fixed... :-( */ assert_int_equal(DBHasStr(db, "kSHA-98765"), false); CloseDB(db); } static void test_reverse_missing_forward(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555); DBHandle *db; OpenDB(&db, dbid_lastseen); assert_int_equal(DeleteDB(db, "kSHA-12345"), true); /* Check that resolution returns true despite the missing entry (a warning * should be printed though). */ char result[CF_BUFSIZE]; assert_int_equal(Address2Hostkey(result, sizeof(result), "127.0.0.64"), true); /* Entry still exists despite inconsistency. */ assert_int_equal(DBHasStr(db, "a127.0.0.64"), true); /* And the inconsistency was not auto-fixed, entry is still missing. :-( */ assert_int_equal(DBHasStr(db, "kSHA-12345"), false); CloseDB(db); } static void test_remove(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555); UpdateLastSawHost("SHA-12345", "127.0.0.64", false, 556); //RemoveHostFromLastSeen("SHA-12345"); DeleteDigestFromLastSeen("SHA-12345", NULL, 0, true); DBHandle *db; OpenDB(&db, dbid_lastseen); assert_int_equal(HasKeyDB(db, "qiSHA-12345", strlen("qiSHA-12345") + 1), false); assert_int_equal(HasKeyDB(db, "qoSHA-12345", strlen("qoSHA-12345") + 1), false); assert_int_equal(HasKeyDB(db, "kSHA-12345", strlen("kSHA-12345") + 1), false); assert_int_equal(HasKeyDB(db, "a127.0.0.64", strlen("a127.0.0.64") + 1), false); CloseDB(db); } static void test_remove_no_a_entry(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555); UpdateLastSawHost("SHA-12345", "127.0.0.64", false, 556); DBHandle *db; OpenDB(&db, dbid_lastseen); assert_true(DeleteDB(db, "a127.0.0.64")); assert_false(DeleteDigestFromLastSeen("SHA-12345", NULL, 0, true)); assert_true(DeleteDigestFromLastSeen("SHA-12345", NULL, 0, false)); assert_false(HasKeyDB(db, "qiSHA-12345", strlen("qiSHA-12345") + 1)); assert_false(HasKeyDB(db, "qoSHA-12345", strlen("qoSHA-12345") + 1)); assert_false(HasKeyDB(db, "kSHA-12345", strlen("kSHA-12345") + 1)); assert_false(HasKeyDB(db, "a127.0.0.64", strlen("a127.0.0.64") + 1)); CloseDB(db); } static void test_remove_ip(void) { setup(); UpdateLastSawHost("SHA-12345", "127.0.0.64", true, 555); UpdateLastSawHost("SHA-12345", "127.0.0.64", false, 556); char digest[CF_BUFSIZE]; DeleteIpFromLastSeen("127.0.0.64", digest, sizeof(digest)); DBHandle *db; OpenDB(&db, dbid_lastseen); assert_int_equal(HasKeyDB(db, "qiSHA-12345", strlen("qiSHA-12345") + 1), false); assert_int_equal(HasKeyDB(db, "qoSHA-12345", strlen("qoSHA-12345") + 1), false); assert_int_equal(HasKeyDB(db, "kSHA-12345", strlen("kSHA-12345") + 1), false); assert_int_equal(HasKeyDB(db, "a127.0.0.64", strlen("a127.0.0.64") + 1), false); CloseDB(db); } /* These tests can't be multi-threaded anyway. */ static DBHandle *DBH; static void begin() { bool b = OpenDB(&DBH, dbid_lastseen); assert_int_equal(b, true); //*state = db; } static void end() { CloseDB(DBH); DBH = NULL; char cmd[CF_BUFSIZE]; xsnprintf(cmd, sizeof(cmd), "rm -rf '%s'/*", GetStateDir()); system(cmd); } /** * ============== DB CONSISTENCY TESTS =============== * * @WARNING TO CODER: think twice before you change this test. Changing it to * accommodate your needs means that you change what "consistent" * lastseen database is. Lastseen consistency was transcribed as this * test after a lot of late-hours pondering. * * Are you sure you want to continue? (y/n) */ /** * ===== CONSISTENT CASES ===== * * * 1. Everything is as expected here. * * aIP1 -> KEY1 * kKEY1 -> IP1 * aIP2 -> KEY2 * kKEY2 -> IP2 * * consistent_1a: Fill lastseen DB using the lastseen.h API. * consistent_1b: Same, but fill lastseen DB directly by use of dbm_api.h API. * * * 2. A host connecting from IP1, then connects from IP2. * * aIP1 -> KEY1 * aIP2 -> KEY1 * kKEY1 -> IP2 * * consistent_2a: lastseen.h API. * consistent_2b: dbm_api.h API. * * * 3. The host at IP1 gets reinstalled and changes key from KEY1 to KEY2. * * aIP1 -> KEY2 * kKEY1 -> aIP1 * kKEY2 -> aIP1 * * consistent_3a: lastseen.h API. * consistent_3b: dbm_api.h API. * * * 4. Many hosts can use the same key - a mess, but consistent * (usecase by Bas van der Vlies in scientific clusters). * * aIP1 -> KEY1 * aIP2 -> KEY1 * aIP3 -> KEY1 * kKEY1 -> aIP1 * * * 5. Host connects from IP1 with KEY1, then changes address to IP2 keeps the * same key, later changes key to KEY2. * * aIP1 -> KEY1 * aIP2 -> KEY2 * kKEY1 -> aIP2 * kKEY2 -> aIP2 * * * 6. Similar to previous but can't occur unless somebody restores an old key * on a host. Still the db should be considered consistent. * * aIP1 -> KEY1 * aIP2 -> KEY1 * kKEY1 -> aIP2 * kKEY2 -> aIP2 * * * 7. Similarly messed-up but not inconsistent state. * * aIP1 -> KEY1 * aIP2 -> KEY1 * kKEY1 -> aIP2 * kKEY2 -> aIP1 * * */ /* TODO assert the two DBs from "a" and "b" tests are exactly the same! */ static void test_consistent_1a() { LastSaw1(IP1, KEY1, ACC); LastSaw1(IP2, KEY2, ACC); assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1); assert_string_equal(DBGetStr(DBH, "a"IP2), KEY2); assert_string_equal(DBGetStr(DBH, "k"KEY1), IP1); assert_string_equal(DBGetStr(DBH, "k"KEY2), IP2); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_1b() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true); assert_int_equal(DBPutStr(DBH, "a"IP2, KEY2), true); assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_2a() { LastSaw1(IP1, KEY1, ACC); LastSaw1(IP2, KEY1, ACC); assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1); assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1); assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_2b() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_3a() { LastSaw1(IP1, KEY1, ACC); LastSaw1(IP1, KEY2, ACC); assert_string_equal(DBGetStr(DBH, "a"IP1), KEY2); assert_string_equal(DBGetStr(DBH, "k"KEY1), IP1); assert_string_equal(DBGetStr(DBH, "k"KEY2), IP1); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_3b() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY2), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true); assert_int_equal(DBPutStr(DBH, "k"KEY2, IP1), true); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_4a() { LastSaw1(IP1, KEY1, ACC); LastSaw1(IP2, KEY1, ACC); LastSaw1(IP3, KEY1, ACC); assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1); assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1); assert_string_equal(DBGetStr(DBH, "a"IP3), KEY1); assert_string_equal(DBGetStr(DBH, "k"KEY1), IP3); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_4b() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP3, KEY1), true); /* Just a bit different than what the lastseen API created in the 4a case, * but still consistent. */ assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_5a() { LastSaw1(IP1, KEY1, ACC); LastSaw1(IP2, KEY1, ACC); LastSaw1(IP2, KEY2, ACC); assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1); assert_string_equal(DBGetStr(DBH, "a"IP2), KEY2); assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2); assert_string_equal(DBGetStr(DBH, "k"KEY2), IP2); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_5b() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP2, KEY2), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true); assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_6a() { LastSaw1(IP1, KEY1, ACC); /* initial bootstrap */ LastSaw1(IP2, KEY1, ACC); /* move to new IP */ LastSaw1(IP2, KEY2, ACC); /* issue new key */ LastSaw1(IP2, KEY1, ACC); /* restore old key */ assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1); assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1); assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2); assert_string_equal(DBGetStr(DBH, "k"KEY2), IP2); assert_int_equal(IsLastSeenCoherent(), true); } static void test_consistent_6b() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true); assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true); assert_int_equal(IsLastSeenCoherent(), true); } /** * @NOTE I haven't been able to get the consistent_7 case with regular * dbm_api.h calls. Maybe it should be considered inconsistent state of * the db? */ /* static void test_consistent_7a() { LastSaw1(IP2, KEY1, ACC); LastSaw1(IP1, KEY2, ACC); LastSaw1(IP2, KEY1, ACC); LastSaw1(IP1, KEY1, ACC); assert_string_equal(DBGetStr(DBH, "a"IP1), KEY1); assert_string_equal(DBGetStr(DBH, "a"IP2), KEY1); assert_string_equal(DBGetStr(DBH, "k"KEY1), IP2); assert_string_equal(DBGetStr(DBH, "k"KEY2), IP1); assert_int_equal(IsLastSeenCoherent(), true); } */ static void test_consistent_7b() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP2, KEY1), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true); assert_int_equal(DBPutStr(DBH, "k"KEY2, IP1), true); assert_int_equal(IsLastSeenCoherent(), true); } /** * ===== INCONSISTENT CASES ===== * Should never happen if our software is bug-free! * * * 1. KEY2 appears as a value but not "kKEY2" as a key. * * aIP1 -> KEY2 * * * 2. Same case, a bit more complex example. * * aIP1 -> KEY1 * aIP2 -> KEY2 * aKEY1 -> IP1 * * * 3. IP2 appears as a value but not "aIP2" as a key. * * kKEY1 -> IP2 * * * 4. Same case, a bit more complex example. * * aIP1 -> KEY1 * kKEY1 -> aIP1 * kKEY2 -> aIP2 * * * 5. The two previous cases at the same time! * * kKEY1 -> IP2 * aIP1 -> KEY2 * * * 6. Same, a bit more complex example. * * aIP1 -> KEY1 * aIP3 -> KEY2 * kKEY1 -> IP2 * kKEY3 -> IP2 * */ static void test_inconsistent_1() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY2), true); assert_int_equal(IsLastSeenCoherent(), false); } static void test_inconsistent_2() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP2, KEY2), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true); assert_int_equal(IsLastSeenCoherent(), false); } static void test_inconsistent_3() { assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true); assert_int_equal(IsLastSeenCoherent(), false); } static void test_inconsistent_4() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP1), true); assert_int_equal(DBPutStr(DBH, "k"KEY2, IP2), true); assert_int_equal(IsLastSeenCoherent(), false); } static void test_inconsistent_5() { assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true); assert_int_equal(DBPutStr(DBH, "a"IP1, KEY2), true); assert_int_equal(IsLastSeenCoherent(), false); } static void test_inconsistent_6() { assert_int_equal(DBPutStr(DBH, "a"IP1, KEY1), true); assert_int_equal(DBPutStr(DBH, "a"IP3, KEY2), true); assert_int_equal(DBPutStr(DBH, "k"KEY1, IP2), true); assert_int_equal(DBPutStr(DBH, "k"KEY3, IP2), true); assert_int_equal(IsLastSeenCoherent(), false); } /* TODO run lastseen consistency checks after every cf-serverd *acceptance* * test, deployment test, and stress test! */ int main() { tests_setup(); const UnitTest tests[] = { unit_test(test_newentry), unit_test(test_update), unit_test(test_HostkeyToAddress), unit_test(test_reverse_missing), unit_test(test_reverse_conflict), unit_test(test_reverse_missing_forward), unit_test(test_remove), unit_test(test_remove_no_a_entry), unit_test(test_remove_ip), unit_test_setup_teardown(test_consistent_1a, begin, end), unit_test_setup_teardown(test_consistent_1b, begin, end), unit_test_setup_teardown(test_consistent_2a, begin, end), unit_test_setup_teardown(test_consistent_2b, begin, end), unit_test_setup_teardown(test_consistent_3a, begin, end), unit_test_setup_teardown(test_consistent_3b, begin, end), unit_test_setup_teardown(test_consistent_4a, begin, end), unit_test_setup_teardown(test_consistent_4b, begin, end), unit_test_setup_teardown(test_consistent_5a, begin, end), unit_test_setup_teardown(test_consistent_5b, begin, end), unit_test_setup_teardown(test_consistent_6a, begin, end), unit_test_setup_teardown(test_consistent_6b, begin, end), // unit_test_setup_teardown(test_consistent_7a, begin, end), unit_test_setup_teardown(test_consistent_7b, begin, end), unit_test_setup_teardown(test_inconsistent_1, begin, end), unit_test_setup_teardown(test_inconsistent_2, begin, end), unit_test_setup_teardown(test_inconsistent_3, begin, end), unit_test_setup_teardown(test_inconsistent_4, begin, end), unit_test_setup_teardown(test_inconsistent_5, begin, end), unit_test_setup_teardown(test_inconsistent_6, begin, end), }; PRINT_TEST_BANNER(); int ret = run_tests(tests); tests_teardown(); return ret; } /* STUBS */ void FatalError(ARG_UNUSED char *s, ...) { fail(); exit(42); } pthread_mutex_t *cft_output; char *HashPrintSafe(ARG_UNUSED char *dst, ARG_UNUSED size_t dst_size, ARG_UNUSED const unsigned char *digest, ARG_UNUSED HashMethod type, ARG_UNUSED bool use_prefix) { fail(); } void HashPubKey(ARG_UNUSED const RSA *key, ARG_UNUSED unsigned char digest[EVP_MAX_MD_SIZE + 1], ARG_UNUSED HashMethod type) { fail(); } cfengine-3.24.2/tests/unit/assoc_test.c0000644000000000000000000000053715010704253020014 0ustar00rootroot00000000000000#include #include static void test_create_destroy(void) { CfAssoc *ap = NewAssoc("hello", (Rval) { "world", RVAL_TYPE_SCALAR }, CF_DATA_TYPE_STRING); DeleteAssoc(ap); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_create_destroy), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/process_test.c0000644000000000000000000001646215010704253020366 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /** * This file contains process-handling tests that need to fork() a child process * which totally confuses the unit test framework used by the other tests. */ static bool failure = false; #define assert_int_equal(expr1, expr2) \ if ((expr1) != (expr2)) \ { \ fprintf(stderr, "FAIL: "#expr1" != "#expr2" [%jd != %jd] (%s:%d)\n", ((intmax_t) expr1), ((intmax_t) expr2), __FILE__, __LINE__); \ failure = true; \ } #define assert_int_not_equal(expr1, expr2) \ if ((expr1) == (expr2)) \ { \ fprintf(stderr, "FAIL: "#expr1" == "#expr2" [%jd == %jd] (%s:%d)\n", ((intmax_t) expr1), ((intmax_t) expr2), __FILE__, __LINE__); \ failure = true; \ } #define assert_true(expr) \ if (!(expr)) \ { \ fprintf(stderr, "FAIL: "#expr" is FALSE (%s:%d)\n", __FILE__, __LINE__); \ failure = true; \ } #define assert_false(expr) \ if ((expr)) \ { \ fprintf(stderr, "FAIL: "#expr" is TRUE (%s:%d)\n", __FILE__, __LINE__); \ failure = true; \ } pid_t SPAWNED_PID; pid_t THIS_PID; time_t THIS_STARTTIME; static void test_process_start_time(void) { /* Wait a couple of seconds so that process start time differs. */ printf("Sleeping 2 seconds...\n"); sleep(2); pid_t new_pid = fork(); assert_true(new_pid >= 0); if (new_pid == 0) /* child */ { execl("/bin/sleep", "/bin/sleep", "30", NULL); assert_true(false); /* unreachable */ } SPAWNED_PID = new_pid; time_t newproc_starttime = GetProcessStartTime(new_pid); printf("Spawned a \"sleep\" child with PID %jd and start_time %jd\n", (intmax_t) new_pid, (intmax_t) newproc_starttime); // We might have slipped by a few seconds, but shouldn't be much. assert_int_not_equal(newproc_starttime, PROCESS_START_TIME_UNKNOWN); assert_true(newproc_starttime >= THIS_STARTTIME + 1); assert_true(newproc_starttime <= THIS_STARTTIME + 15); kill(new_pid, SIGKILL); wait(NULL); SPAWNED_PID = 0; } static void test_process_state(void) { int ret; pid_t new_pid = fork(); assert_true(new_pid >= 0); if (new_pid == 0) /* child */ { execl("/bin/sleep", "/bin/sleep", "30", NULL); assert_true(false); /* unreachable */ } SPAWNED_PID = new_pid; printf("Spawned a \"sleep\" child with PID %d\n", new_pid); int state = -1000; for (int c = 0; c < 10; c++) { state = GetProcessState(new_pid); if (state == PROCESS_STATE_RUNNING) { break; } else { usleep(200000); } } printf("Started, state: %d\n", state); assert_int_equal(state, PROCESS_STATE_RUNNING); ret = kill(new_pid, SIGSTOP); assert_int_equal(ret, 0); for (int c = 0; c < 10; c++) { state = GetProcessState(new_pid); if (state == PROCESS_STATE_STOPPED) { break; } else { usleep(200000); } } printf("Stopped, state: %d\n", state); assert_int_equal(state, PROCESS_STATE_STOPPED); ret = kill(new_pid, SIGCONT); assert_int_equal(ret, 0); for (int c = 0; c < 10; c++) { state = GetProcessState(new_pid); if (state == PROCESS_STATE_RUNNING) { break; } else { usleep(200000); } } printf("Resumed, state: %d\n", state); assert_int_equal(state, PROCESS_STATE_RUNNING); /* Terminate the child process and reap the zombie. */ kill(new_pid, SIGKILL); wait(NULL); state = GetProcessState(new_pid); printf("Killed, state: %d\n", state); assert_int_equal(state, PROCESS_STATE_DOES_NOT_EXIST); SPAWNED_PID = 0; } static void test_graceful_terminate(void) { int ret, state; pid_t new_pid = fork(); assert_true(new_pid >= 0); if (new_pid == 0) /* child */ { execl("/bin/sleep", "/bin/sleep", "30", NULL); assert_true(false); /* unreachable */ } time_t start_time = GetProcessStartTime(new_pid); SPAWNED_PID = new_pid; printf("Spawned a \"sleep\" child with PID %jd and start_time %jd\n", (intmax_t) new_pid, (intmax_t) start_time); state = GetProcessState(new_pid); assert_int_equal(state, PROCESS_STATE_RUNNING); printf("Killing child with wrong start_time, child should not die...\n"); ret = GracefulTerminate(new_pid, 12345); /* fake start time */ assert_false(ret); state = GetProcessState(new_pid); assert_int_equal(state, PROCESS_STATE_RUNNING); printf("Killing child with correct start_time, child should die...\n"); ret = GracefulTerminate(new_pid, start_time); assert_true(ret); state = GetProcessState(new_pid); assert_int_equal(state, PROCESS_STATE_ZOMBIE); wait(NULL); /* reap child */ state = GetProcessState(new_pid); assert_int_equal(state, PROCESS_STATE_DOES_NOT_EXIST); printf("Child Dead!\n"); SPAWNED_PID = 0; printf("Killing ourself, should fail...\n"); ret = GracefulTerminate(THIS_PID, THIS_STARTTIME); assert_false(ret); printf("Killing ourself without specifying starttime, should fail...\n"); ret = GracefulTerminate(THIS_PID, PROCESS_START_TIME_UNKNOWN); assert_false(ret); } int main() { puts("=================================================="); puts("Starting test process_test.c"); puts("=================================================="); /* Don't miss the messages about GetProcessStartTime not implemented. */ LogSetGlobalLevel(LOG_LEVEL_DEBUG); THIS_PID = getpid(); THIS_STARTTIME = GetProcessStartTime(THIS_PID); printf("This parent process has PID %jd and start_time %jd\n", (intmax_t) THIS_PID, (intmax_t) THIS_STARTTIME); test_process_start_time(); test_process_state(); test_graceful_terminate(); /* Make sure no child is alive. */ if (SPAWNED_PID > 0) { kill(SPAWNED_PID, SIGKILL); } return failure ? 1 : 0; } cfengine-3.24.2/tests/unit/mon_load_test.c0000644000000000000000000000160715010704253020473 0ustar00rootroot00000000000000#include "test.h" #include "generic_agent.h" #include "mon.h" #include /* getloadavg() */ void test_load_monitor(void) { double cf_this[100]; MonLoadGatherData(cf_this); double load1[2] = {0,0}; double load2[2] = {0,0}; int n1 = getloadavg(load1, 1); int n2 = getloadavg(load2, 1); if (n1==-1 || n2==-1) { assert_true(1); return; } double min = (double) (load2[0]=lower && cf_this[ob_loadavg]<=upper); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_load_monitor), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/db_concurrent_test.c0000644000000000000000000000627515010704253021540 0ustar00rootroot00000000000000#include #include #include #include #include #include #include /* xsnprintf */ char CFWORKDIR[CF_BUFSIZE]; void tests_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/db_concurrent_test.XXXXXX"; char *workdir = strchr(env, '=') + 1; /* start of the path */ assert(workdir - 1 && workdir[0] == '/'); mkdtemp(workdir); strlcpy(CFWORKDIR, workdir, CF_BUFSIZE); putenv(env); mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); } void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } struct arg_struct { int base; }; /***************************************************************** * launch 5 threads * fct(i) * one by one insert * batch insert * one by one update * batch update * delete one by one * batch delete * * join * check * 0 - 1999 * first 100 * last 1900 * first 500, if %20, update +1 * last 1500, if %20, update +1 * first 500, if %50, delete * last 1500, if %50, delete * * 2000- 3999 * 4000- 5999 * 6000- 7999 * 8000- 9999 *****************************************************************/ static void *fct2(void *arguments) { struct arg_struct *args = (struct arg_struct *)arguments; int base = args->base; CF_DB *db; char key[256]; char val[256]; OpenDB(&db, dbid_classes); for(int i = base*2000; i #include #include #include /* xsnprintf */ #include char CFWORKDIR[CF_BUFSIZE]; static void tests_setup(void) { OpenSSL_add_all_digests(); /* FIXME: get rid of hardcoded filenames */ xsnprintf(CFWORKDIR, CF_BUFSIZE, "/tmp/persistent_lock_test.XXXXXX"); mkdtemp(CFWORKDIR); char buf[CF_BUFSIZE]; xsnprintf(buf, CF_BUFSIZE, "%s", GetStateDir()); mkdir(buf, 0755); } static void tests_teardown(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } int main() { PRINT_TEST_BANNER(); tests_setup(); const UnitTest tests[] = { }; int ret = run_tests(tests); tests_teardown(); return ret; } cfengine-3.24.2/tests/unit/crypto_symmetric_test.c0000644000000000000000000000657215010704253022325 0ustar00rootroot00000000000000#include #include #include #define PLAINTEXT "123456789012345678901234567890123" #define KEY "1234567890123456789012345678901234567890123456789012345678901234" /* at least 512 bits long (to be sure) */ // use Blowfish (64-bit block size) for now #define CIPHER_TYPE_CFENGINE 'c' #define CIPHER_BLOCK_SIZE_BYTES 8 static const char CIPHERTEXT_PRECOMPUTED[] = { 0x99, 0xfd, 0x86, 0x9c, 0x17, 0xb9, 0xe4, 0x98, 0xab, 0x01, 0x17, 0x5a, 0x4a, 0xcf, 0xfc, 0x1f, 0xd4, 0xc5, 0xa3, 0xab, 0xf0, 0x1c, 0xa7, 0x39, 0xf1, 0xf4, 0x09, 0xe4, 0xac, 0xb6, 0x44, 0xbb, 0x47, 0xdd, 0xe6, 0xc4, 0x0e, 0x4a, 0x16, 0xf0 }; static int ComputeCiphertextLen(int plaintext_len, int cipher_block_size_bytes) { int last_block_offset = plaintext_len % cipher_block_size_bytes; int padding = cipher_block_size_bytes - last_block_offset; return (plaintext_len + padding); } static void test_cipher_init(void) { unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; unsigned char iv[] = {1,2,3,4,5,6,7,8}; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init(ctx); EVP_EncryptInit_ex(ctx, EVP_bf_cbc(), NULL, key, iv); EVP_CIPHER_CTX_free(ctx); } static void test_symmetric_encrypt(void) { char ciphertext[CF_BUFSIZE]; int plaintext_len = strlen(PLAINTEXT) + 1; int ciphertext_len = EncryptString(ciphertext, sizeof(ciphertext), PLAINTEXT, plaintext_len, CIPHER_TYPE_CFENGINE, KEY); assert_int_equal(ciphertext_len, ComputeCiphertextLen(plaintext_len, CIPHER_BLOCK_SIZE_BYTES)); assert_memory_equal(ciphertext, CIPHERTEXT_PRECOMPUTED, ciphertext_len); } static void test_symmetric_decrypt(void) { char *ciphertext = (char *)CIPHERTEXT_PRECOMPUTED; int ciphertext_len = sizeof(CIPHERTEXT_PRECOMPUTED); char plaintext_out[CF_BUFSIZE]; int plaintext_len = DecryptString(plaintext_out, sizeof(plaintext_out), ciphertext, ciphertext_len, CIPHER_TYPE_CFENGINE, KEY); assert_int_equal(plaintext_len, strlen(PLAINTEXT) + 1); assert_string_equal(plaintext_out, PLAINTEXT); } static void test_cipher_block_size(void) { assert_int_equal(CipherBlockSizeBytes(EVP_bf_cbc()), 8); assert_int_equal(CipherBlockSizeBytes(EVP_aes_256_cbc()), 16); } static void test_cipher_text_size_max(void) { assert_int_equal(CipherTextSizeMax(EVP_aes_256_cbc(), 1), 32); assert_int_equal(CipherTextSizeMax(EVP_aes_256_cbc(), CF_BUFSIZE), 4127); assert_int_equal(CipherTextSizeMax(EVP_bf_cbc(), 1), 16); assert_int_equal(CipherTextSizeMax(EVP_bf_cbc(), CF_BUFSIZE), 4111); } static void test_plain_text_size_max(void) { assert_int_equal(PlainTextSizeMax(EVP_aes_256_cbc(), 1), 33); assert_int_equal(PlainTextSizeMax(EVP_aes_256_cbc(), CF_BUFSIZE), 4128); assert_int_equal(PlainTextSizeMax(EVP_bf_cbc(), 1), 17); assert_int_equal(PlainTextSizeMax(EVP_bf_cbc(), CF_BUFSIZE), 4112); } int main() { PRINT_TEST_BANNER(); CryptoInitialize(); const UnitTest tests[] = { unit_test(test_cipher_init), unit_test(test_symmetric_encrypt), unit_test(test_symmetric_decrypt), unit_test(test_cipher_block_size), unit_test(test_cipher_text_size_max), unit_test(test_plain_text_size_max), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/files_copy_test.c0000644000000000000000000003655015010704253021044 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* FullWrite */ #include /* xsnprintf */ /* CopyRegularFileDisk() is the function we are testing. */ #include /* WARNING on Solaris 11 with ZFS, stat.st_nblocks==1 if you check the file * right after closing it, and it changes to the right value (i.e. how many * 512 chunks the file has) a few seconds later!!! So we force a sync() on * all tests to avoid this! */ bool do_sync = true; // TODO detect in runtime if the filesystem needs to be synced! #define MAYBE_SYNC_NOW if (do_sync) sync() char TEST_DIR[] = "/tmp/files_copy_test-XXXXXX"; char TEST_SUBDIR[256]; char TEST_SRC_FILE[256]; char TEST_DST_FILE[256]; #define TEST_FILENAME "testfile" /* Size must be enough to contain several disk blocks. */ int blk_size; /* defined during init() */ #define TESTFILE_SIZE (blk_size * 8) #define SHORT_REGION (blk_size / 2) /* not enough for hole */ #define LONG_REGION (blk_size * 2) /* hole for sure */ #define GARBAGE "blahblehblohbluebloblebli" #define GARBAGE_LEN (sizeof(GARBAGE) - 1) /* Notice if even one test failed so that we don't clean up. */ #define NTESTS 8 bool test_has_run[NTESTS + 1]; bool success [NTESTS + 1]; /* Some filesystems don't support sparse files at all (swap fs on Solaris is * one example). We create a fully sparse file (seek 1MB further) and check if * it's sparse. If not, WE SKIP ALL SPARSENESS TESTS but we still run this * unit test in order to test for integrity of data. */ bool SPARSE_SUPPORT_OK = true; static bool FsSupportsSparseFiles(const char *filename) { #ifdef __hpux Log(LOG_LEVEL_NOTICE, "HP-UX detected, skipping sparseness tests!" " Not sure why, but on HP-UX with 'vxfs' filesystem," " the sparse files generated have /sometimes/ greater" " 'disk usage' than their true size, and this is verified by du"); return false; #endif #ifdef __APPLE__ Log(LOG_LEVEL_NOTICE, "OS X detected, skipping sparseness tests!"); return false; #endif int fd = open(filename, O_CREAT | O_WRONLY | O_BINARY, 0700); assert_int_not_equal(fd, -1); /* 8MB for our temporary sparse file sounds good. */ const int sparse_file_size = 8 * 1024 * 1024; off_t s_ret = lseek(fd, sparse_file_size, SEEK_CUR); assert_int_equal(s_ret, sparse_file_size); /* Make sure the file is not truncated by writing one byte and taking it back. */ ssize_t w_ret = write(fd, "", 1); assert_int_equal(w_ret, 1); int tr_ret = ftruncate(fd, sparse_file_size); assert_int_equal(tr_ret, 0); /* On ZFS the file needs to be synced, else stat() reports a temporary value for st_blocks! */ fsync(fd); int c_ret = close(fd); assert_int_equal(c_ret, 0); struct stat statbuf; int st_ret = stat(filename, &statbuf); assert_int_not_equal(st_ret, -1); int u_ret = unlink(filename); /* clean up */ assert_int_equal(u_ret, 0); /* ACTUAL TEST: IS THE FILE SPARSE? */ if (ST_NBYTES(statbuf) < statbuf.st_size) { return true; } else { return false; } } static void init(void) { LogSetGlobalLevel(LOG_LEVEL_DEBUG); char *ok = mkdtemp(TEST_DIR); assert_int_not_equal(ok, NULL); /* Set blk_size */ struct stat statbuf; int ret1 = stat(TEST_DIR, &statbuf); assert_int_not_equal(ret1, -1); blk_size = ST_BLKSIZE(statbuf); Log(LOG_LEVEL_NOTICE, "Running sparse file tests with blocksize=%d TESTFILE_SIZE=%d", blk_size, TESTFILE_SIZE); Log(LOG_LEVEL_NOTICE, "Temporary directory: %s", TEST_DIR); // /tmp/files_copy_test-XXXXXX/subdir xsnprintf(TEST_SUBDIR, sizeof(TEST_SUBDIR), "%s/%s", TEST_DIR, "subdir"); // /tmp/files_copy_test-XXXXXX/testfile xsnprintf(TEST_SRC_FILE, sizeof(TEST_SRC_FILE), "%s/%s", TEST_DIR, TEST_FILENAME); // /tmp/files_copy_test-XXXXXX/subdir/testfile xsnprintf(TEST_DST_FILE, sizeof(TEST_DST_FILE), "%s/%s", TEST_SUBDIR, TEST_FILENAME); int ret2 = mkdir(TEST_SUBDIR, 0700); assert_int_equal(ret2, 0); SPARSE_SUPPORT_OK = true; if (!FsSupportsSparseFiles(TEST_DST_FILE)) { Log(LOG_LEVEL_NOTICE, "filesystem for directory '%s' doesn't seem to support sparse files!" " TEST WILL ONLY VERIFY FILE INTEGRITY!", TEST_DIR); SPARSE_SUPPORT_OK = false; } test_has_run[0] = true; success[0] = true; } static void finalise(void) { /* Do not remove evidence if even one test has failed. */ bool all_success = true; for (int i = 0; i < NTESTS; i++) { if (test_has_run[i]) { all_success = all_success && success[i]; } } if (!all_success) { Log(LOG_LEVEL_NOTICE, "Skipping cleanup of test data because of tests failing"); return; } int ret1 = unlink(TEST_DST_FILE); assert_int_equal(ret1, 0); int ret2 = rmdir(TEST_SUBDIR); assert_int_equal(ret2, 0); int ret3 = unlink(TEST_SRC_FILE); assert_int_equal(ret3, 0); int ret5 = rmdir(TEST_DIR); assert_int_equal(ret5, 0); } /* Fill a buffer with non-NULL garbage. */ static void FillBufferWithGarbage(char *buf, size_t buf_size) { for (size_t i = 0; i < TESTFILE_SIZE; i += GARBAGE_LEN) { memcpy(&buf[i], GARBAGE, MIN(buf_size - i, GARBAGE_LEN)); } } static void WriteBufferToFile(const char *name, const void *buf, const size_t count) { int fd = open(name, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0700); assert_int_not_equal(fd, -1); int ret = ftruncate(fd, count); assert_int_not_equal(ret, -1); size_t remaining = count; bool last_wrote_hole; while (remaining > 0) { size_t to_write = MIN(remaining, blk_size); bool success = FileSparseWrite(fd, buf, to_write, &last_wrote_hole); assert_true(success); remaining -= to_write; buf += to_write; } bool success = FileSparseClose(fd, name, true, count, last_wrote_hole); assert_true(success); } static bool CompareFileToBuffer(const char *filename, const void *buf, size_t buf_size) { FILE *f = fopen(filename, "rb"); assert_int_not_equal(f, NULL); size_t total = 0; char filebuf[DEV_BSIZE]; size_t n; while ((n = fread(filebuf, 1, sizeof(filebuf), f)) != 0) { bool differ = (total + n > buf_size); differ = differ || (memcmp(filebuf, buf + total, n) != 0); if (differ) { Log(LOG_LEVEL_DEBUG, "file differs from buffer at pos %zu len %zu", total, n); fclose(f); return false; } total += n; } bool error_happened = (ferror(f) != 0); assert_false(error_happened); if (total != buf_size) { Log(LOG_LEVEL_DEBUG, "filesize:%zu buffersize:%zu ==> differ", total, buf_size); fclose(f); return false; } fclose(f); return true; } /* TODO isolate important code and move to files_lib.c. */ static bool FileIsSparse(const char *filename) { MAYBE_SYNC_NOW; struct stat statbuf; int ret = stat(filename, &statbuf); assert_int_not_equal(ret, -1); Log(LOG_LEVEL_DEBUG, " st_size=%ju ST_NBYTES=%ju ST_NBLOCKS=%ju ST_BLKSIZE=%ju DEV_BSIZE=%ju", (uintmax_t) statbuf.st_size, (uintmax_t) ST_NBYTES(statbuf), (uintmax_t) ST_NBLOCKS(statbuf), (uintmax_t) ST_BLKSIZE(statbuf), (uintmax_t) DEV_BSIZE); if (statbuf.st_size <= ST_NBYTES(statbuf)) { Log(LOG_LEVEL_DEBUG, "File is probably non-sparse"); return false; } else { /* We definitely know the file is sparse, since the allocated bytes * are less than the real size. */ Log(LOG_LEVEL_DEBUG, "File is definitely sparse"); return true; } } const char *srcfile = TEST_SRC_FILE; const char *dstfile = TEST_DST_FILE; static void test_sparse_files_1(void) { Log(LOG_LEVEL_VERBOSE, "No zeros in the file, the output file must be non-sparse"); char *buf = xmalloc(TESTFILE_SIZE); FillBufferWithGarbage(buf, TESTFILE_SIZE); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_false(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE); assert_true(data_ok); free(buf); test_has_run[1] = true; success [1] = true; } static void test_sparse_files_2(void) { Log(LOG_LEVEL_VERBOSE, "File starting with few zeroes, the output file must be non-sparse."); char *buf = xmalloc(TESTFILE_SIZE); FillBufferWithGarbage(buf, TESTFILE_SIZE); memset(buf, 0, SHORT_REGION); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_false(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE); assert_true(data_ok); free(buf); test_has_run[2] = true; success [2] = true; } static void test_sparse_files_3(void) { Log(LOG_LEVEL_VERBOSE, "File with few zeroes in the middle, the output file must be non-sparse"); char *buf = xmalloc(TESTFILE_SIZE); FillBufferWithGarbage(buf, TESTFILE_SIZE); memset(&buf[TESTFILE_SIZE / 2], 0, SHORT_REGION); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_false(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE); assert_true(data_ok); free(buf); test_has_run[3] = true; success [3] = true; } static void test_sparse_files_4(void) { Log(LOG_LEVEL_VERBOSE, "File ending with few zeroes, the output file must be non-sparse"); char *buf = xmalloc(TESTFILE_SIZE); FillBufferWithGarbage(buf, TESTFILE_SIZE); memset(&buf[TESTFILE_SIZE - SHORT_REGION], 0, SHORT_REGION); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_false(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE); assert_true(data_ok); free(buf); test_has_run[4] = true; success [4] = true; } static void test_sparse_files_5(void) { Log(LOG_LEVEL_VERBOSE, "File starting with many zeroes, the output file must be sparse"); char *buf = xmalloc(TESTFILE_SIZE); FillBufferWithGarbage(buf, TESTFILE_SIZE); memset(buf, 0, LONG_REGION); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_true(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE); assert_true(data_ok); free(buf); test_has_run[5] = true; success [5] = true; } static void test_sparse_files_6(void) { Log(LOG_LEVEL_VERBOSE, "Many zeroes in the middle of the file, the output file must be sparse"); char *buf = xmalloc(TESTFILE_SIZE); FillBufferWithGarbage(buf, TESTFILE_SIZE); memset(&buf[TESTFILE_SIZE / 2 - 7], 0, LONG_REGION); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_true(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE); assert_true(data_ok); free(buf); test_has_run[6] = true; success [6] = true; } static void test_sparse_files_7(void) { Log(LOG_LEVEL_VERBOSE, "File ending with many zeroes, the output file must be sparse"); char *buf = xmalloc(TESTFILE_SIZE); FillBufferWithGarbage(buf, TESTFILE_SIZE); memset(&buf[TESTFILE_SIZE - LONG_REGION], 0, LONG_REGION); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_true(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE); assert_true(data_ok); free(buf); test_has_run[7] = true; success [7] = true; } static void test_sparse_files_8(void) { Log(LOG_LEVEL_VERBOSE, "Special Case: File ending with few (DEV_BSIZE-1) zeroes," " at block size barrier; so the last bytes written are a hole and are seek()ed," " but the output file can't be sparse since the hole isn't block-sized"); char *buf = xmalloc(TESTFILE_SIZE + DEV_BSIZE - 1); FillBufferWithGarbage(buf, TESTFILE_SIZE); memset(&buf[TESTFILE_SIZE], 0, DEV_BSIZE - 1); WriteBufferToFile(srcfile, buf, TESTFILE_SIZE + DEV_BSIZE - 1); /* ACTUAL TEST */ bool ret = CopyRegularFileDisk(srcfile, dstfile); assert_true(ret); if (SPARSE_SUPPORT_OK) { bool is_sparse = FileIsSparse(dstfile); assert_false(is_sparse); } bool data_ok = CompareFileToBuffer(dstfile, buf, TESTFILE_SIZE + DEV_BSIZE - 1); assert_true(data_ok); free(buf); test_has_run[8] = true; success [8] = true; } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(init), unit_test(test_sparse_files_1), unit_test(test_sparse_files_2), unit_test(test_sparse_files_3), unit_test(test_sparse_files_4), unit_test(test_sparse_files_5), unit_test(test_sparse_files_6), unit_test(test_sparse_files_7), unit_test(test_sparse_files_8), unit_test(finalise), }; int ret = run_tests(tests); return ret; } cfengine-3.24.2/tests/unit/enterprise_extension_test.c0000644000000000000000000000432315010704253023155 0ustar00rootroot00000000000000#include #include #include #include ENTERPRISE_FUNC_2ARG_DECLARE(int64_t, extension_function, int32_t, short_int, int64_t, long_int); ENTERPRISE_FUNC_2ARG_DECLARE(int64_t, extension_function_broken, int32_t, short_int, int64_t, long_int); ENTERPRISE_FUNC_2ARG_DEFINE_STUB(int64_t, extension_function, int32_t, short_int, int64_t, long_int) { return short_int + long_int; } ENTERPRISE_FUNC_2ARG_DEFINE_STUB(int64_t, extension_function_broken, int32_t, short_int, int64_t, long_int) { return short_int + long_int; } static void test_extension_function_stub(void) { putenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR=nonexistingdir"); assert_int_equal(extension_function(2, 3), 5); unsetenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR"); } static void test_extension_function(void) { putenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR=.libs"); assert_int_equal(extension_function(2, 3), 6); unsetenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR"); } static void test_extension_function_broken(void) { putenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR=.libs"); // This one should call the stub, even if the extension is available, because the // function signature is different. assert_int_equal(extension_function_broken(2, 3), 5); unsetenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR"); } static void test_extension_function_version_mismatch() { putenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR=.libs"); putenv("CFENGINE_TEST_RETURN_VERSION=1.1.1"); // This one should call the stub, even if the extension is available, because the // version is different. assert_int_equal(extension_function(2, 3), 5); unsetenv("CFENGINE_TEST_RETURN_VERSION"); unsetenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR"); } int main() { putenv("CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DO_CLOSE=1"); PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_extension_function_stub), unit_test(test_extension_function), unit_test(test_extension_function_broken), unit_test(test_extension_function_version_mismatch), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/redirection_test_stub.c0000644000000000000000000000063615010704253022250 0ustar00rootroot00000000000000#include #include #include #include #include #include #include int main(int argc, char **argv) { if (argc < 2) return -1; char *text = argv[1]; int output = STDIN_FILENO; int result = 0; result = write(output, text, strlen(text)); if (result < 0) return -1; fsync(output); return 0; } cfengine-3.24.2/tests/unit/set_domainname_test.c0000644000000000000000000000413215010704253021662 0ustar00rootroot00000000000000#include #include #include #include #include #include #include static struct hostent h = { .h_name = "laptop.intra.cfengine.com" }; #ifdef SOLARIS int gethostname(char *name, ARG_UNUSED int len) #else int gethostname(char *name, ARG_UNUSED size_t len) #endif { strcpy(name, "laptop.intra"); return 0; } struct hostent *gethostbyname(const char *name) { assert_string_equal(name, "laptop.intra"); return &h; } typedef struct { const char *name; const char *value; bool found; } ExpectedVars; ExpectedVars expected_vars[] = { {"host", "laptop.intra"}, {"fqhost", "laptop.intra.cfengine.com"}, {"uqhost", "laptop.intra"}, {"domain", "cfengine.com"}, }; static void TestSysVar(EvalContext *ctx, const char *lval, const char *expected) { VarRef *ref = VarRefParseFromScope(lval, "sys"); assert_string_equal(expected, EvalContextVariableGet(ctx, ref, NULL)); VarRefDestroy(ref); assert_string_equal(expected, EvalContextVariableGetSpecial(ctx, SPECIAL_SCOPE_SYS, lval, NULL)); assert_string_equal(expected, EvalContextVariableGetSpecialString(ctx, SPECIAL_SCOPE_SYS, lval)); } static void test_set_names(void) { EvalContext *ctx = EvalContextNew(); DetectDomainName(ctx, "laptop.intra"); assert_true(!EvalContextClassGet(ctx, NULL, "laptop_intra_cfengine_com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "intra_cfengine_com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "cfengine_com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "com")->is_soft); assert_true(!EvalContextClassGet(ctx, NULL, "laptop_intra")->is_soft); TestSysVar(ctx, "host", "laptop.intra"); TestSysVar(ctx, "fqhost", "laptop.intra.cfengine.com"); TestSysVar(ctx, "uqhost", "laptop.intra"); TestSysVar(ctx, "domain", "cfengine.com"); EvalContextDestroy(ctx); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_set_names), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/tar_portability_test.sh0000755000000000000000000000026415010704253022304 0ustar00rootroot00000000000000#!/bin/sh if [ "$(uname)" != "Linux" ] then # Skip. exit 77 fi cd "$(dirname $0)/../.." tar --exclude="tests/acceptance/workdir" --format=ustar -cf /dev/null * exit $? cfengine-3.24.2/tests/unit/class_test.c0000644000000000000000000000676315010704253020020 0ustar00rootroot00000000000000#include #include static void test_class_ref(void) { { ClassRef ref = ClassRefParse("class"); assert_true(ref.ns == NULL); assert_string_equal("class", ref.name); char *expr = ClassRefToString(ref.ns, ref.name); assert_string_equal("class", expr); free(expr); ClassRefDestroy(ref); } { ClassRef ref = ClassRefParse("default:class"); assert_string_equal("default", ref.ns); assert_string_equal("class", ref.name); char *expr = ClassRefToString(ref.ns, ref.name); assert_string_equal("class", expr); free(expr); ClassRefDestroy(ref); } { ClassRef ref = ClassRefParse("ns:class"); assert_string_equal("ns", ref.ns); assert_string_equal("class", ref.name); char *expr = ClassRefToString(ref.ns, ref.name); assert_string_equal("ns:class", expr); free(expr); ClassRefDestroy(ref); } } static void test_ns(void) { { ClassTable *t = ClassTableNew(); assert_false(ClassTablePut(t, "foo", "127.0.0.1", true, CONTEXT_SCOPE_BUNDLE, NULL, NULL)); Class *cls = ClassTableGet(t, "foo", "127_0_0_1"); assert_string_equal("foo", cls->ns); assert_string_equal("127_0_0_1", cls->name); assert_true(cls->is_soft); cls = ClassTableMatch(t, "foo:127_0_.*"); assert_true(cls); cls = ClassTableMatch(t, "foo:127_1_.*"); assert_false(cls); cls = ClassTableMatch(t, "127_0_.*"); assert_false(cls); ClassTableDestroy(t); } } static void test_default_ns(void) { { ClassTable *t = ClassTableNew(); assert_false(ClassTablePut(t, NULL, "127.0.0.1", false, CONTEXT_SCOPE_NAMESPACE, NULL, NULL)); Class *cls = ClassTableGet(t, NULL, "127_0_0_1"); assert_true(cls != NULL); assert_true(cls->ns == NULL); cls = ClassTableGet(t, "default", "127_0_0_1"); assert_true(cls->ns == NULL); assert_string_equal("127_0_0_1", cls->name); assert_false(cls->is_soft); cls = ClassTableMatch(t, "127_0_.*"); assert_true(cls); cls = ClassTableMatch(t, "127_1_.*"); assert_false(cls); ClassTableDestroy(t); } { ClassTable *t = ClassTableNew(); assert_false(ClassTablePut(t, "default", "127.0.0.1", false, CONTEXT_SCOPE_NAMESPACE, NULL, NULL)); Class *cls = ClassTableGet(t, NULL, "127_0_0_1"); assert_true(cls->ns == NULL); cls = ClassTableGet(t, "default", "127_0_0_1"); assert_true(cls->ns == NULL); assert_string_equal("127_0_0_1", cls->name); assert_false(cls->is_soft); ClassTableDestroy(t); } } static void test_put_replace(void) { ClassTable *t = ClassTableNew(); assert_false(ClassTablePut(t, NULL, "test", false, CONTEXT_SCOPE_NAMESPACE, NULL, NULL)); Class *cls = ClassTableGet(t, NULL, "test"); assert_true(cls); assert_int_equal(CONTEXT_SCOPE_NAMESPACE, cls->scope); assert_true(ClassTablePut(t, NULL, "test", true, CONTEXT_SCOPE_BUNDLE, NULL, NULL)); cls = ClassTableGet(t, NULL, "test"); assert_true(cls); assert_int_equal(CONTEXT_SCOPE_BUNDLE, cls->scope); ClassTableDestroy(t); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_default_ns), unit_test(test_ns), unit_test(test_class_ref), unit_test(test_put_replace), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/string_expressions_test.c0000644000000000000000000000460215010704253022651 0ustar00rootroot00000000000000#include #include #include #include #include static char *ForbiddenVarRefEval(ARG_UNUSED const char *varname, ARG_UNUSED VarRefType type, ARG_UNUSED void *param) { fail(); } static char *IdentityVarRefEval(const char *varname, ARG_UNUSED VarRefType type, ARG_UNUSED void *param) { return xstrdup(varname); } static char *AppendAVarRefEval(const char *varname, ARG_UNUSED VarRefType type, ARG_UNUSED void *param) { return StringConcatenate(2, "a", varname); } static char *DiscriminateVarTypesVarRefEval(const char *varname, VarRefType type, ARG_UNUSED void *param) { if (type == VAR_REF_TYPE_SCALAR) { return StringConcatenate(3, "cozy(", varname, ")"); } else { return StringConcatenate(3, "ugly{", varname, "}"); } } static void CheckParse(const char *string_expression, const char *expected_output, VarRefEvaluator evaluator, void *param) { StringParseResult res = ParseStringExpression(string_expression, 0, strlen(string_expression)); assert_true(res.result); char *eval_result = EvalStringExpression(res.result, evaluator, param); assert_string_equal(expected_output, eval_result); free(eval_result); FreeStringExpression(res.result); } static void test_literal(void) { CheckParse("hello", "hello", ForbiddenVarRefEval, NULL); } static void test_var_naked(void) { CheckParse("$(foo)", "foo", IdentityVarRefEval, NULL); } static void test_var_naked_two_level(void) { CheckParse("$($(foo))", "aafoo", AppendAVarRefEval, NULL); } static void test_var_one_level(void) { CheckParse("$(foo)x$(bar)y$(baz)", "fooxbarybaz", IdentityVarRefEval, NULL); } static void test_different_var_types(void) { CheckParse("@{a$(b@(c)${d})@(e)}", "ugly{acozy(bugly{c}cozy(d))ugly{e}}", DiscriminateVarTypesVarRefEval, NULL); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_literal), unit_test(test_var_naked), unit_test(test_var_naked_two_level), unit_test(test_var_one_level), unit_test(test_different_var_types), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/data/0000755000000000000000000000000015010704253016405 5ustar00rootroot00000000000000cfengine-3.24.2/tests/unit/data/bundle_invalid_type.cf0000644000000000000000000000002715010704253022736 0ustar00rootroot00000000000000bundle invalid foo { } cfengine-3.24.2/tests/unit/data/body_control_no_arguments.cf0000644000000000000000000000007315010704253024175 0ustar00rootroot00000000000000body common control(arg) { bundlesequence => { test }; } cfengine-3.24.2/tests/unit/data/body_executor_control_agent_expireafter_only.cf0000644000000000000000000000007415010704253030150 0ustar00rootroot00000000000000body executor control { agent_expireafter => "121"; } cfengine-3.24.2/tests/unit/data/promise_duplicate_handle.cf0000644000000000000000000000020315010704253023735 0ustar00rootroot00000000000000bundle agent foo { reports: cfengine3:: "hello world" handle => "stuff"; "quux" handle => "stuff"; } cfengine-3.24.2/tests/unit/data/mustache_delimiters.json0000644000000000000000000000545015010704253023336 0ustar00rootroot00000000000000{ "tests": [ { "name": "Pair Behavior", "data": { "text": "Hey!" }, "expected": "(Hey!)", "template": "{{=<% %>=}}(<%text%>)", "desc": "The equals sign (used on both sides) should permit delimiter changes." }, { "name": "Special Characters", "data": { "text": "It worked!" }, "expected": "(It worked!)", "template": "({{=[ ]=}}[text])", "desc": "Characters with special meaning regexen should be valid delimiters." }, { "name": "Sections", "data": { "section": true, "data": "I got interpolated." }, "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", "template": "[\n{{#section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|#section|\n {{data}}\n |data|\n|/section|\n]\n", "desc": "Delimiters set outside sections should persist." }, { "name": "Inverted Sections", "data": { "section": false, "data": "I got interpolated." }, "expected": "[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n", "template": "[\n{{^section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|^section|\n {{data}}\n |data|\n|/section|\n]\n", "desc": "Delimiters set outside inverted sections should persist." }, { "name": "Surrounding Whitespace", "data": {}, "expected": "| |", "template": "| {{=@ @=}} |", "desc": "Surrounding whitespace should be left untouched." }, { "name": "Outlying Whitespace (Inline)", "data": {}, "expected": " | \n", "template": " | {{=@ @=}}\n", "desc": "Whitespace should be left untouched." }, { "name": "Standalone Tag", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n{{=@ @=}}\nEnd.\n", "desc": "Standalone lines should be removed from the template." }, { "name": "Indented Standalone Tag", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n {{=@ @=}}\nEnd.\n", "desc": "Indented standalone lines should be removed from the template." }, { "name": "Pair with Padding", "data": {}, "expected": "||", "template": "|{{= @ @ =}}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/tests/unit/data/mustache_comments.json0000644000000000000000000000636715010704253023032 0ustar00rootroot00000000000000{ "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", "overview": "Comment tags represent content that should never appear in the resulting\noutput.\n\nThe tag's content may contain any substring (including newlines) EXCEPT the\nclosing delimiter.\n\nComment tags SHOULD be treated as standalone when appropriate.\n", "tests": [ { "name": "Inline", "data": {}, "expected": "1234567890", "template": "12345{{! Comment Block! }}67890", "desc": "Comment blocks should be removed from the template." }, { "name": "Multiline", "data": {}, "expected": "1234567890\n", "template": "12345{{!\n This is a\n multi-line comment...\n}}67890\n", "desc": "Multiline comments should be permitted." }, { "name": "Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n{{! Comment Block! }}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Indented Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n {{! Indented Comment Block! }}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Standalone Line Endings", "data": {}, "expected": "|\r\n|", "template": "|\r\n{{! Standalone Comment }}\r\n|", "desc": "\"\\r\\n\" should be considered a newline for standalone tags." }, { "name": "Standalone Without Previous Line", "data": {}, "expected": "!", "template": " {{! I'm Still Standalone }}\n!", "desc": "Standalone tags should not require a newline to precede them." }, { "name": "Standalone Without Newline", "data": {}, "expected": "!\n", "template": "!\n {{! I'm Still Standalone }}", "desc": "Standalone tags should not require a newline to follow them." }, { "name": "Multiline Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n{{!\nSomething's going on here...\n}}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Indented Multiline Standalone", "data": {}, "expected": "Begin.\nEnd.\n", "template": "Begin.\n {{!\n Something's going on here...\n }}\nEnd.\n", "desc": "All standalone comment lines should be removed." }, { "name": "Indented Inline", "data": {}, "expected": " 12 \n", "template": " 12 {{! 34 }}\n", "desc": "Inline comments should not strip whitespace" }, { "name": "Surrounding Whitespace", "data": {}, "expected": "12345 67890", "template": "12345 {{! Comment Block! }} 67890", "desc": "Comment removal should preserve surrounding whitespace." } ] } cfengine-3.24.2/tests/unit/data/csv_file.csv0000644000000000000000000000011115010704253020705 0ustar00rootroot00000000000000field_1, field_2 field_1, "value1 value2 value3" field_1, "field,2" cfengine-3.24.2/tests/unit/data/bundle_body_forgot_semicolon.cf0000644000000000000000000000022115010704253024630 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "bas" string => "van der vlies", handle => "netherlands", comment => "lastname" } cfengine-3.24.2/tests/unit/data/rval_list_wrong_input_type.cf0000644000000000000000000000012415010704253024407 0ustar00rootroot00000000000000bundle agent my_commands { vars: "family" slist => { "andre", bas:: } ; } cfengine-3.24.2/tests/unit/data/no_bundle_or_body_keyword.cf0000644000000000000000000000011315010704253024140 0ustar00rootroot00000000000000bunndle agent foo { report: any:: "Hello World"; } cfengine-3.24.2/tests/unit/data/mustache_sections.json0000644000000000000000000002655515010704253023035 0ustar00rootroot00000000000000{ "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", "overview": "Section tags and End Section tags are used in combination to wrap a section\nof the template for iteration\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Section tag MUST be followed\nby an End Section tag with the same content within the same section.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nFor each element in the data list, the element MUST be pushed onto the\ncontext stack, the section MUST be rendered, and the element MUST be popped\noff the context stack.\n\nSection and End Section tags SHOULD be treated as standalone when\nappropriate.\n", "tests": [ { "name": "Truthy", "data": { "boolean": true }, "expected": "\"This should be rendered.\"", "template": "\"{{#boolean}}This should be rendered.{{/boolean}}\"", "desc": "Truthy sections should have their contents rendered." }, { "name": "Falsey", "data": { "boolean": false }, "expected": "\"\"", "template": "\"{{#boolean}}This should not be rendered.{{/boolean}}\"", "desc": "Falsey sections should have their contents omitted." }, { "name": "Context", "data": { "context": { "name": "Joe" } }, "expected": "\"Hi Joe.\"", "template": "\"{{#context}}Hi {{name}}.{{/context}}\"", "desc": "Objects and hashes should be pushed onto the context stack." }, { "name": "Deeply Nested Contexts", "data": { "a": { "one": 1 }, "b": { "two": 2 }, "c": { "three": 3 }, "d": { "four": 4 }, "e": { "five": 5 } }, "expected": "1\n121\n12321\n1234321\n123454321\n1234321\n12321\n121\n1\n", "template": "{{#a}}\n{{one}}\n{{#b}}\n{{one}}{{two}}{{one}}\n{{#c}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{#d}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{#e}}\n{{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}\n{{/e}}\n{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}\n{{/d}}\n{{one}}{{two}}{{three}}{{two}}{{one}}\n{{/c}}\n{{one}}{{two}}{{one}}\n{{/b}}\n{{one}}\n{{/a}}\n", "desc": "All elements on the context stack should be accessible." }, { "name": "List", "data": { "list": [ { "item": 1 }, { "item": 2 }, { "item": 3 } ] }, "expected": "\"123\"", "template": "\"{{#list}}{{item}}{{/list}}\"", "desc": "Lists should be iterated; list items should visit the context stack." }, { "name": "Empty List", "data": { "list": [] }, "expected": "\"\"", "template": "\"{{#list}}Yay lists!{{/list}}\"", "desc": "Empty lists should behave like falsey values." }, { "name": "Doubled", "data": { "two": "second", "bool": true }, "expected": "* first\n* second\n* third\n", "template": "{{#bool}}\n* first\n{{/bool}}\n* {{two}}\n{{#bool}}\n* third\n{{/bool}}\n", "desc": "Multiple sections per template should be permitted." }, { "name": "Nested (Truthy)", "data": { "bool": true }, "expected": "| A B C D E |", "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested truthy sections should have their contents rendered." }, { "name": "Nested (Falsey)", "data": { "bool": false }, "expected": "| A E |", "template": "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested falsey sections should be omitted." }, { "name": "Context Misses", "data": {}, "expected": "[]", "template": "[{{#missing}}Found key 'missing'!{{/missing}}]", "desc": "Failed context lookups should be considered falsey." }, { "name": "Implicit Iterator - String", "data": { "list": [ "a", "b", "c", "d", "e" ] }, "expected": "\"(a)(b)(c)(d)(e)\"", "template": "\"{{#list}}({{.}}){{/list}}\"", "desc": "Implicit iterators should directly interpolate strings." }, { "name": "Implicit Iterator - Integer", "data": { "list": [ 1, 2, 3, 4, 5 ] }, "expected": "\"(1)(2)(3)(4)(5)\"", "template": "\"{{#list}}({{.}}){{/list}}\"", "desc": "Implicit iterators should cast integers to strings and interpolate." }, { "name": "Implicit Iterator - Decimal", "data": { "list": [ 1.1, 2.2, 3.3, 4.4, 5.5 ] }, "expected": "\"(1.10)(2.20)(3.30)(4.40)(5.50)\"", "template": "\"{{#list}}({{.}}){{/list}}\"", "desc": "Implicit iterators should cast decimals to strings and interpolate." }, { "name": "Dotted Names - Truthy", "data": { "a": { "b": { "c": true } } }, "expected": "\"Here\" == \"Here\"", "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"Here\"", "desc": "Dotted names should be valid for Section tags." }, { "name": "Dotted Names - Falsey", "data": { "a": { "b": { "c": false } } }, "expected": "\"\" == \"\"", "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", "desc": "Dotted names should be valid for Section tags." }, { "name": "Dotted Names - Broken Chains", "data": { "a": {} }, "expected": "\"\" == \"\"", "template": "\"{{#a.b.c}}Here{{/a.b.c}}\" == \"\"", "desc": "Dotted names that cannot be resolved should be considered falsey." }, { "name": "Surrounding Whitespace", "data": { "boolean": true }, "expected": " | \t|\t | \n", "template": " | {{#boolean}}\t|\t{{/boolean}} | \n", "desc": "Sections should not alter surrounding whitespace." }, { "name": "Internal Whitespace", "data": { "boolean": true }, "expected": " | \n | \n", "template": " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", "desc": "Sections should not alter internal whitespace." }, { "name": "Indented Inline Sections", "data": { "boolean": true }, "expected": " YES\n GOOD\n", "template": " {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n", "desc": "Single-line sections should not alter surrounding whitespace." }, { "name": "Standalone Lines", "data": { "boolean": true }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n{{#boolean}}\n|\n{{/boolean}}\n| A Line\n", "desc": "Standalone lines should be removed from the template." }, { "name": "Indented Standalone Lines", "data": { "boolean": true }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n {{#boolean}}\n|\n {{/boolean}}\n| A Line\n", "desc": "Indented standalone lines should be removed from the template." }, { "name": "Standalone Line Endings", "data": { "boolean": true }, "expected": "|\r\n|", "template": "|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|", "desc": "\"\\r\\n\" should be considered a newline for standalone tags." }, { "name": "Standalone Without Previous Line", "data": { "boolean": true }, "expected": "#\n/", "template": " {{#boolean}}\n#{{/boolean}}\n/", "desc": "Standalone tags should not require a newline to precede them." }, { "name": "Standalone Without Newline", "data": { "boolean": true }, "expected": "#\n/\n", "template": "#{{#boolean}}\n/\n {{/boolean}}", "desc": "Standalone tags should not require a newline to follow them." }, { "name": "Padding", "data": { "boolean": true }, "expected": "|=|", "template": "|{{# boolean }}={{/ boolean }}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/tests/unit/data/rval_function_forgot_cp_semicolon.cf0000644000000000000000000000014315010704253025700 0ustar00rootroot00000000000000bundle agent my_commands { vars: any:: "env" string => getenv("PATH", "20" ; } cfengine-3.24.2/tests/unit/data/bundle_redefinition.cf0000644000000000000000000000021315010704253022723 0ustar00rootroot00000000000000bundle agent foo { reports: cfengine3:: "hello world"; } bundle agent foo { reports: cfengine3:: "other stuff"; } cfengine-3.24.2/tests/unit/data/mustache_inverted.json0000644000000000000000000002167115010704253023020 0ustar00rootroot00000000000000{ "__ATTN__": "Do not edit this file; changes belong in the appropriate YAML file.", "overview": "Inverted Section tags and End Section tags are used in combination to wrap a\nsection of the template.\n\nThese tags' content MUST be a non-whitespace character sequence NOT\ncontaining the current closing delimiter; each Inverted Section tag MUST be\nfollowed by an End Section tag with the same content within the same\nsection.\n\nThis tag's content names the data to replace the tag. Name resolution is as\nfollows:\n 1) Split the name on periods; the first part is the name to resolve, any\n remaining parts should be retained.\n 2) Walk the context stack from top to bottom, finding the first context\n that is a) a hash containing the name as a key OR b) an object responding\n to a method with the given name.\n 3) If the context is a hash, the data is the value associated with the\n name.\n 4) If the context is an object and the method with the given name has an\n arity of 1, the method SHOULD be called with a String containing the\n unprocessed contents of the sections; the data is the value returned.\n 5) Otherwise, the data is the value returned by calling the method with\n the given name.\n 6) If any name parts were retained in step 1, each should be resolved\n against a context stack containing only the result from the former\n resolution. If any part fails resolution, the result should be considered\n falsey, and should interpolate as the empty string.\nIf the data is not of a list type, it is coerced into a list as follows: if\nthe data is truthy (e.g. `!!data == true`), use a single-element list\ncontaining the data, otherwise use an empty list.\n\nThis section MUST NOT be rendered unless the data list is empty.\n\nInverted Section and End Section tags SHOULD be treated as standalone when\nappropriate.\n", "tests": [ { "name": "Falsey", "data": { "boolean": false }, "expected": "\"This should be rendered.\"", "template": "\"{{^boolean}}This should be rendered.{{/boolean}}\"", "desc": "Falsey sections should have their contents rendered." }, { "name": "Truthy", "data": { "boolean": true }, "expected": "\"\"", "template": "\"{{^boolean}}This should not be rendered.{{/boolean}}\"", "desc": "Truthy sections should have their contents omitted." }, { "name": "Context", "data": { "context": { "name": "Joe" } }, "expected": "\"\"", "template": "\"{{^context}}Hi {{name}}.{{/context}}\"", "desc": "Objects and hashes should behave like truthy values." }, { "name": "List", "data": { "list": [ { "n": 1 }, { "n": 2 }, { "n": 3 } ] }, "expected": "\"\"", "template": "\"{{^list}}{{n}}{{/list}}\"", "desc": "Lists should behave like truthy values." }, { "name": "Empty List", "data": { "list": [] }, "expected": "\"Yay lists!\"", "template": "\"{{^list}}Yay lists!{{/list}}\"", "desc": "Empty lists should behave like falsey values." }, { "name": "Doubled", "data": { "two": "second", "bool": false }, "expected": "* first\n* second\n* third\n", "template": "{{^bool}}\n* first\n{{/bool}}\n* {{two}}\n{{^bool}}\n* third\n{{/bool}}\n", "desc": "Multiple inverted sections per template should be permitted." }, { "name": "Nested (Falsey)", "data": { "bool": false }, "expected": "| A B C D E |", "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested falsey sections should have their contents rendered." }, { "name": "Nested (Truthy)", "data": { "bool": true }, "expected": "| A E |", "template": "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", "desc": "Nested truthy sections should be omitted." }, { "name": "Context Misses", "data": {}, "expected": "[Cannot find key 'missing'!]", "template": "[{{^missing}}Cannot find key 'missing'!{{/missing}}]", "desc": "Failed context lookups should be considered falsey." }, { "name": "Dotted Names - Truthy", "data": { "a": { "b": { "c": true } } }, "expected": "\"\" == \"\"", "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"\"", "desc": "Dotted names should be valid for Inverted Section tags." }, { "name": "Dotted Names - Falsey", "data": { "a": { "b": { "c": false } } }, "expected": "\"Not Here\" == \"Not Here\"", "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", "desc": "Dotted names should be valid for Inverted Section tags." }, { "name": "Dotted Names - Broken Chains", "data": { "a": {} }, "expected": "\"Not Here\" == \"Not Here\"", "template": "\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\"", "desc": "Dotted names that cannot be resolved should be considered falsey." }, { "name": "Surrounding Whitespace", "data": { "boolean": false }, "expected": " | \t|\t | \n", "template": " | {{^boolean}}\t|\t{{/boolean}} | \n", "desc": "Inverted sections should not alter surrounding whitespace." }, { "name": "Internal Whitespace", "data": { "boolean": false }, "expected": " | \n | \n", "template": " | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", "desc": "Inverted should not alter internal whitespace." }, { "name": "Indented Inline Sections", "data": { "boolean": false }, "expected": " NO\n WAY\n", "template": " {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n", "desc": "Single-line sections should not alter surrounding whitespace." }, { "name": "Standalone Lines", "data": { "boolean": false }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n{{^boolean}}\n|\n{{/boolean}}\n| A Line\n", "desc": "Standalone lines should be removed from the template." }, { "name": "Standalone Indented Lines", "data": { "boolean": false }, "expected": "| This Is\n|\n| A Line\n", "template": "| This Is\n {{^boolean}}\n|\n {{/boolean}}\n| A Line\n", "desc": "Standalone indented lines should be removed from the template." }, { "name": "Standalone Line Endings", "data": { "boolean": false }, "expected": "|\r\n|", "template": "|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|", "desc": "\"\\r\\n\" should be considered a newline for standalone tags." }, { "name": "Standalone Without Previous Line", "data": { "boolean": false }, "expected": "^\n/", "template": " {{^boolean}}\n^{{/boolean}}\n/", "desc": "Standalone tags should not require a newline to precede them." }, { "name": "Standalone Without Newline", "data": { "boolean": false }, "expected": "^\n/\n", "template": "^{{^boolean}}\n/\n {{/boolean}}", "desc": "Standalone tags should not require a newline to follow them." }, { "name": "Padding", "data": { "boolean": false }, "expected": "|=|", "template": "|{{^ boolean }}={{/ boolean }}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/tests/unit/data/bundle_body_forget_cb_body.cf0000644000000000000000000000027515010704253024240 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "bas" string => "van der vlies", comment => "lastname"; body classes repaired(x) { promise_repaired => { "$(x)_repaired" }; } cfengine-3.24.2/tests/unit/data/body_selection_forgot_semicolon.cf0000644000000000000000000000042315010704253025350 0ustar00rootroot00000000000000body classes surfsara_all_classes(x) { promise_repaired => { "$(x)_repaired" }; promise_kept => { "$(x)_kept" } repair_failed => { "$(x)_failed" }; repair_denied => { "$(x)_denied" }; repair_timeout => { "$(x)_timeout" }; } cfengine-3.24.2/tests/unit/data/rval_function_wrong_input_type.cf0000644000000000000000000000013715010704253025265 0ustar00rootroot00000000000000bundle agent my_commands { vars: any:: "env" string => getenv("PATH", "bas ); } cfengine-3.24.2/tests/unit/data/bundle_args_invalid_type.cf0000644000000000000000000000003515010704253023751 0ustar00rootroot00000000000000bundle agent foo(a, "b") { } cfengine-3.24.2/tests/unit/data/benchmark.cf0000644000000000000000000000130515010704253020650 0ustar00rootroot00000000000000# This file is intended to have as much feature variation as possible, # while still being correct. body common control { bundlesequence => { "main" }; } bundle agent main { reports: cfengine:: "Hello, CFEngine" friend_pattern => hash("abc", "md5"); any:: "Hello, world" friend_pattern => hash("abc", "md5"); files: "/tmp/stuff" -> { "stakeholder" } create => "true", perms => myperms; processes: "/bin/stuff" -> { "stakeholder" } process_count => any_count("stuff_running"); } body process_count any_count(cl) { match_range => "0,0"; out_of_range_define => { "$(cl)" }; } body perms myperms { mode => "555"; } cfengine-3.24.2/tests/unit/data/bundle_body_wrong_statement.cf0000644000000000000000000000007715010704253024511 0ustar00rootroot00000000000000bundle agent foo { vars: invalid string => "foo"; } cfengine-3.24.2/tests/unit/data/bundle_body_forget_cb_eof.cf0000644000000000000000000000016115010704253024046 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "bas" string => "van der vlies", comment => "lastname"; cfengine-3.24.2/tests/unit/data/constraint_comment_nonscalar.cf0000644000000000000000000000011015010704253024655 0ustar00rootroot00000000000000bundle agent foo { reports: "hello" comment => { "a" }; } cfengine-3.24.2/tests/unit/data/csv_file_edge_cases.csv0000644000000000000000000000015115010704253023053 0ustar00rootroot00000000000000Empty,Empty,One double quote,Two double quotes,LF,CRLF,CRLFCRLF,Empty "",,"""",""""""," "," "," ", cfengine-3.24.2/tests/unit/data/bundle_body_promiser_statement_missing_assign.cf0000644000000000000000000000014215010704253030303 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "foo" string > "bar", comment => "test"; } cfengine-3.24.2/tests/unit/data/rval_wrong_input_type.cf0000644000000000000000000000013415010704253023355 0ustar00rootroot00000000000000bundle agent my_commands { vars: any:: "lastname" string => 'vandervlies ; } cfengine-3.24.2/tests/unit/data/body_body_forget_cb_bundle.cf0000644000000000000000000000014015010704253024227 0ustar00rootroot00000000000000body classes repaired(x) { promise_repaired => { "$(x)_repaired" }; bundle agent foo { } cfengine-3.24.2/tests/unit/data/body_executor_control_empty.cf0000644000000000000000000000000115010704253024537 0ustar00rootroot00000000000000 cfengine-3.24.2/tests/unit/data/body_body_forget_cb_body.cf0000644000000000000000000000014015010704253023713 0ustar00rootroot00000000000000body classes repaired(x) { promise_repaired => { "$(x)_repaired" }; body classes foo { } cfengine-3.24.2/tests/unit/data/body_selection_wrong_token.cf0000644000000000000000000000042615010704253024337 0ustar00rootroot00000000000000body classes surfsara_all_classes(x) { "promise_repaired" => { "$(x)_repaired" }; promise_kept => { "$(x)_kept" }; repair_failed => { "$(x)_failed" }; repair_denied => { "$(x)_denied" }; repair_timeout => { "$(x)_timeout" }; } cfengine-3.24.2/tests/unit/data/bundle_args_forgot_cp.cf0000644000000000000000000000004315010704253023243 0ustar00rootroot00000000000000bundle agent foo(a { } cfengine-3.24.2/tests/unit/data/bundle_custom_promise_type.cf0000644000000000000000000000024715010704253024364 0ustar00rootroot00000000000000# This policy should be parseable since the promise type might be # defined in another policy file bundle agent foo { custom_promise_type: "var" string => "test"; } cfengine-3.24.2/tests/unit/data/bundle_body_promiser_wrong_constraint_token.cf0000644000000000000000000000012615010704253030004 0ustar00rootroot00000000000000bundle agent foo { vars: "a" string => "foo", "comment" => "bar"; } cfengine-3.24.2/tests/unit/data/promiser_empty_varref.cf0000644000000000000000000000005515010704253023342 0ustar00rootroot00000000000000bundle agent foo { reports: "$()"; } cfengine-3.24.2/tests/unit/data/body_edit_xml_common_constraints.cf0000644000000000000000000000012115010704253025532 0ustar00rootroot00000000000000bundle edit_xml test { build_xpath: "foo" select_xpath => "abc"; } cfengine-3.24.2/tests/unit/data/vars_multiple_types.cf0000644000000000000000000000012515010704253023027 0ustar00rootroot00000000000000bundle agent foo { vars: "bar" string => "snookie", int => 42; } cfengine-3.24.2/tests/unit/data/constraint_lval_invalid.cf0000644000000000000000000000020115010704253023620 0ustar00rootroot00000000000000bundle agent test { files: "$(G.testdir)/shouldnotexist" create => "true", nonexistent_attribute => "abc"; } cfengine-3.24.2/tests/unit/data/methods_invalid_arity.cf0000644000000000000000000000024215010704253023276 0ustar00rootroot00000000000000bundle agent foo(one, two) { reports: cfengine3:: "$(one), $(two)"; } bundle agent bar { methods: "any" usebundle => foo("snookie"); } cfengine-3.24.2/tests/unit/data/bundle_body_forget_cb_bundle.cf0000644000000000000000000000020615010704253024546 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "bas" string => "van der vlies", comment => "lastname"; bundle agent bar { } cfengine-3.24.2/tests/unit/data/bundle_body_promiser_forgot_colon.cf0000644000000000000000000000017115010704253025676 0ustar00rootroot00000000000000bundle agent foo { vars: "foo" string => "bar", handle => "foo" comment => "test"; } cfengine-3.24.2/tests/unit/data/mustache_extra.json0000644000000000000000000000446115010704253022321 0ustar00rootroot00000000000000{ "tests": [ { "name": "Demo", "data": { "header": "Colors", "items": [ {"name": "red", "first": true, "url": "#Red"}, {"name": "green", "link": true, "url": "#Green"}, {"name": "blue", "link": true, "url": "#Blue"} ], "empty": false }, "expected": "

    Colors

    \n\n
  • red
  • \n
  • green
  • \n
  • blue
  • \n\n", "template": "

    {{header}}

    \n{{#bug}}\n{{/bug}}\n\n{{#items}}\n {{#first}}\n
  • {{name}}
  • \n {{/first}}\n {{#link}}\n
  • {{name}}
  • \n {{/link}}\n{{/items}}\n\n{{#empty}}\n

    The list is empty.

    \n{{/empty}}\n" }, { "name": "Ted's Abusive Test 1", "data": { "x": 123 }, "template": "{{x}}", "expected": "123" }, { "name": "Ted's Abusive Test 2", "data": { "x": 123, "y": 456 }, "template": "{{x}} {{y}}", "expected": "123 456" }, { "name": "Ted's Abusive Test 3", "data": [ null ], "template": "{{null}}", "expected": "" }, { "name": "Ted's Abusive Test 4", "data": { "x": 123, "y": 456 }, "template": "{{}}", "expected": "{{}}" }, { "name": "Ted's Abusive Test 5", "data": { "boolean": true}, "template": "{{#boolean}}IT IS TRUE{{/boolean}}", "expected": "IT IS TRUE" }, { "name": "Ted's Abusive Test 6", "data": { "boolean": false}, "template": "{{^boolean}}IT IS FALSE{{/boolean}}", "expected": "IT IS FALSE" }, { "name": "Ted's Abusive Test 7", "data": { "list": [ { "k": 789, "v": 0 }, { "k": null, "v": true }, { "k": -1, "v": -2 } ] }, "template": "{{#list}}{{k}}={{v}}, {{/list}}", "expected": "789=0, =true, -1=-2, " }, ] } cfengine-3.24.2/tests/unit/data/body_edit_line_common_constraints.cf0000644000000000000000000000013215010704253025663 0ustar00rootroot00000000000000bundle edit_line test { delete_lines: "abc" select_region => test_select; } cfengine-3.24.2/tests/unit/data/rval_list_forgot_cb_semicolon.cf0000644000000000000000000000014415010704253025011 0ustar00rootroot00000000000000bundle agent my_commands { vars: any:: "family" slist => { "andre", "bas" ; } cfengine-3.24.2/tests/unit/data/body_executor_control_full.cf0000644000000000000000000000062415010704253024356 0ustar00rootroot00000000000000body executor control { splaytime => "1"; mailto => "cfengine_mail@example.org"; mailfrom => "cfengine@example.org"; mailsubject => "Test [localhost/127.0.0.1]"; smtpserver => "localhost"; mailmaxlines => "50"; schedule => { "Min00_05", "Min05_10" }; executorfacility => "LOG_LOCAL6"; agent_expireafter => "120"; exec_command => "/bin/echo"; } cfengine-3.24.2/tests/unit/data/bundle_body_forgot_ob.cf0000644000000000000000000000002715010704253023244 0ustar00rootroot00000000000000bundle agent foo(a) } cfengine-3.24.2/tests/unit/data/constraint_ifvarclass_invalid.cf0000644000000000000000000000007715010704253025032 0ustar00rootroot00000000000000bundle agent foo { reports: "hello" if => "*"; } cfengine-3.24.2/tests/unit/data/rval_list_forgot_cb_colon.cf0000644000000000000000000000020015010704253024124 0ustar00rootroot00000000000000bundle agent my_commands { vars: any:: "family" slist => { "andre", "bas" , comment => "brothers"; } cfengine-3.24.2/tests/unit/data/bundle_body_wrong_promise_type_token.cf0000644000000000000000000000004515010704253026417 0ustar00rootroot00000000000000bundle agent foo { invalid:: } cfengine-3.24.2/tests/unit/data/bundle_body_promiser_statement_contains_colon.cf0000644000000000000000000000014415010704253030300 0ustar00rootroot00000000000000bundle agent foo { reports: "This is a test", comment => "will report an error"; } cfengine-3.24.2/tests/unit/data/body_selection_unknown_selection_id.cf0000644000000000000000000000042315010704253026220 0ustar00rootroot00000000000000body classes surfsara_all_classes(x) { promise_repaired => { "$(x)_repaired" }; promise_kpt => { "$(x)_kept" }; repair_failed => { "$(x)_failed" }; repair_denied => { "$(x)_denied" }; repair_timeout => { "$(x)_timeout" }; } cfengine-3.24.2/tests/unit/data/bundle_body_promiser_unknown_constraint_id.cf0000644000000000000000000000014215010704253027621 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "foo" string => "bar", cmment => "test"; } cfengine-3.24.2/tests/unit/data/rval_list_forgot_colon.cf0000644000000000000000000000012215010704253023463 0ustar00rootroot00000000000000bundle agent my_commands { vars: "family" slist => { "andre" "bas" }; } cfengine-3.24.2/tests/unit/data/bundle_reserved_name.cf0000644000000000000000000000010515010704253023063 0ustar00rootroot00000000000000bundle agent sys { reports: cfengine3:: "hello world"; } cfengine-3.24.2/tests/unit/data/body_body_forget_cb_eof.cf0000644000000000000000000000011415010704253023530 0ustar00rootroot00000000000000body classes repaired(x) { promise_repaired => { "$(x)_repaired" }; cfengine-3.24.2/tests/unit/data/bundle_body_promise_missing_arrow.cf0000644000000000000000000000017015010704253025704 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "HvB" - { "@(stakeholders[$(service)])" } comment => "foobar"; } cfengine-3.24.2/tests/unit/data/promise_promiser_nonscalar.cf0000644000000000000000000000006615010704253024357 0ustar00rootroot00000000000000bundle agent foo { vars: a string => "bar"; } cfengine-3.24.2/tests/unit/data/rval_function_forgot_colon.cf0000644000000000000000000000013515010704253024341 0ustar00rootroot00000000000000bundle agent my_commands { vars: any:: "env" string => getenv("PATH" "20"); } cfengine-3.24.2/tests/unit/data/rval_function_forgot_cp_colon.cf0000644000000000000000000000017515010704253025027 0ustar00rootroot00000000000000bundle agent my_commands { vars: any:: "env" string => getenv("PATH", "20" , comment => 'get path"; } cfengine-3.24.2/tests/unit/data/body_redefinition.cf0000644000000000000000000000014215010704253022410 0ustar00rootroot00000000000000body agent control { ifelapsed => "60"; } body agent control { ifelapsed => "120"; } cfengine-3.24.2/tests/unit/data/bundle_body_promisee_no_colon_allowed.cf0000644000000000000000000000016315010704253026505 0ustar00rootroot00000000000000bundle agent foo { vars: debian:: "foo" -> "bar", handle => "foo" comment => "test"; } cfengine-3.24.2/tests/unit/data/mustache_interpolation.json0000644000000000000000000001431215010704253024061 0ustar00rootroot00000000000000{ "tests": [ { "name": "No Interpolation", "data": {}, "expected": "Hello from {Mustache}!\n", "template": "Hello from {Mustache}!\n", "desc": "Mustache-free templates should render as-is." }, { "name": "Basic Interpolation", "data": { "subject": "world" }, "expected": "Hello, world!\n", "template": "Hello, {{subject}}!\n", "desc": "Unadorned tags should interpolate content into the template." }, { "name": "HTML Escaping", "data": { "forbidden": "& \" < >" }, "expected": "These characters should be HTML escaped: & " < >\n", "template": "These characters should be HTML escaped: {{forbidden}}\n", "desc": "Basic interpolation should be HTML escaped." }, { "name": "Triple Mustache", "data": { "forbidden": "& \" < >" }, "expected": "These characters should not be HTML escaped: & \" < >\n", "template": "These characters should not be HTML escaped: {{{forbidden}}}\n", "desc": "Triple mustaches should interpolate without HTML escaping." }, { "name": "Ampersand", "data": { "forbidden": "& \" < >" }, "expected": "These characters should not be HTML escaped: & \" < >\n", "template": "These characters should not be HTML escaped: {{&forbidden}}\n", "desc": "Ampersand should interpolate without HTML escaping." }, { "name": "Basic Integer Interpolation", "data": { "mph": 85 }, "expected": "\"85 miles an hour!\"", "template": "\"{{mph}} miles an hour!\"", "desc": "Integers should interpolate seamlessly." }, { "name": "Triple Mustache Integer Interpolation", "data": { "mph": 85 }, "expected": "\"85 miles an hour!\"", "template": "\"{{{mph}}} miles an hour!\"", "desc": "Integers should interpolate seamlessly." }, { "name": "Ampersand Integer Interpolation", "data": { "mph": 85 }, "expected": "\"85 miles an hour!\"", "template": "\"{{&mph}} miles an hour!\"", "desc": "Integers should interpolate seamlessly." }, { "name": "Basic Decimal Interpolation", "data": { "power": 1.21 }, "expected": "\"1.21 jiggawatts!\"", "template": "\"{{power}} jiggawatts!\"", "desc": "Decimals should interpolate seamlessly with proper significance." }, { "name": "Triple Mustache Decimal Interpolation", "data": { "power": 1.21 }, "expected": "\"1.21 jiggawatts!\"", "template": "\"{{{power}}} jiggawatts!\"", "desc": "Decimals should interpolate seamlessly with proper significance." }, { "name": "Ampersand Decimal Interpolation", "data": { "power": 1.21 }, "expected": "\"1.21 jiggawatts!\"", "template": "\"{{&power}} jiggawatts!\"", "desc": "Decimals should interpolate seamlessly with proper significance." }, { "name": "Interpolation - Surrounding Whitespace", "data": { "string": "---" }, "expected": "| --- |", "template": "| {{string}} |", "desc": "Interpolation should not alter surrounding whitespace." }, { "name": "Triple Mustache - Surrounding Whitespace", "data": { "string": "---" }, "expected": "| --- |", "template": "| {{{string}}} |", "desc": "Interpolation should not alter surrounding whitespace." }, { "name": "Ampersand - Surrounding Whitespace", "data": { "string": "---" }, "expected": "| --- |", "template": "| {{&string}} |", "desc": "Interpolation should not alter surrounding whitespace." }, { "name": "Interpolation - Standalone", "data": { "string": "---" }, "expected": " ---\n", "template": " {{string}}\n", "desc": "Standalone interpolation should not alter surrounding whitespace." }, { "name": "Triple Mustache - Standalone", "data": { "string": "---" }, "expected": " ---\n", "template": " {{{string}}}\n", "desc": "Standalone interpolation should not alter surrounding whitespace." }, { "name": "Ampersand - Standalone", "data": { "string": "---" }, "expected": " ---\n", "template": " {{&string}}\n", "desc": "Standalone interpolation should not alter surrounding whitespace." }, { "name": "Interpolation With Padding", "data": { "string": "---" }, "expected": "|---|", "template": "|{{ string }}|", "desc": "Superfluous in-tag whitespace should be ignored." }, { "name": "Triple Mustache With Padding", "data": { "string": "---" }, "expected": "|---|", "template": "|{{{ string }}}|", "desc": "Superfluous in-tag whitespace should be ignored." }, { "name": "Ampersand With Padding", "data": { "string": "---" }, "expected": "|---|", "template": "|{{& string }}|", "desc": "Superfluous in-tag whitespace should be ignored." } ] } cfengine-3.24.2/tests/unit/data/benchmark.json0000644000000000000000000001642515010704253021242 0ustar00rootroot00000000000000{ "bundles": [ { "sourcePath": "tests/unit/data/benchmark.cf", "line": 9, "namespace": "default", "name": "main", "bundleType": "agent", "arguments": [], "promiseTypes": [ { "line": 11, "name": "reports", "contexts": [ { "name": "cfengine", "promises": [ { "line": 13, "promiser": "Hello, CFEngine", "attributes": [ { "line": 14, "lval": "friend_pattern", "rval": { "type": "functionCall", "name": "hash", "arguments": [ { "type": "string", "value": "abc" }, { "type": "string", "value": "md5" } ] } } ] } ] }, { "name": "any", "promises": [ { "line": 16, "promiser": "Hello, world", "attributes": [ { "line": 17, "lval": "friend_pattern", "rval": { "type": "functionCall", "name": "hash", "arguments": [ { "type": "string", "value": "abc" }, { "type": "string", "value": "md5" } ] } } ] } ] } ] }, { "line": 19, "name": "files", "contexts": [ { "name": "any", "promises": [ { "line": 20, "promiser": "/tmp/stuff", "promisee": [ "stakeholder" ], "attributes": [ { "line": 21, "lval": "create", "rval": { "type": "string", "value": "true" } }, { "line": 22, "lval": "perms", "rval": { "type": "symbol", "value": "myperms" } } ] } ] } ] }, { "line": 24, "name": "processes", "contexts": [ { "name": "any", "promises": [ { "line": 25, "promiser": "/bin/stuff", "promisee": [ "stakeholder" ], "attributes": [] } ] } ] } ] } ], "bodies": [ { "sourcePath": "tests/unit/data/benchmark.cf", "line": 4, "namespace": "default", "name": "control", "bodyType": "common", "arguments": [], "contexts": [ { "name": "any", "attributes": [ { "line": 6, "lval": "bundlesequence", "rval": { "type": "list", "value": [ { "type": "string", "value": "main" } ] } } ] } ] }, { "sourcePath": "tests/unit/data/benchmark.cf", "line": 28, "namespace": "default", "name": "myperms", "bodyType": "perms", "arguments": [], "contexts": [ { "name": "any", "attributes": [ { "line": 30, "lval": "mode", "rval": { "type": "string", "value": "555" } } ] } ] } ] } cfengine-3.24.2/tests/unit/verify_databases_test.c0000644000000000000000000000434015010704253022213 0ustar00rootroot00000000000000#include #include // Include .c file to test static functions void test_ValidateSQLTableName(void) { char db[CF_MAXVARSIZE]; char table[CF_MAXVARSIZE]; // Valid database table paths: assert_true(ValidateSQLTableName("cfsettings.users", db, sizeof(db), table, sizeof(table))); assert_string_equal(db, "cfsettings"); assert_string_equal(table, "users"); assert_true(ValidateSQLTableName("a.b", db, sizeof(db), table, sizeof(table))); assert_string_equal(db, "a"); assert_string_equal(table, "b"); assert_true(ValidateSQLTableName(".b", db, sizeof(db), table, sizeof(table))); assert_string_equal(db, ""); assert_string_equal(table, "b"); assert_true(ValidateSQLTableName("a.", db, sizeof(db), table, sizeof(table))); assert_string_equal(db, "a"); assert_string_equal(table, ""); // Invalid paths: char path[CF_MAXVARSIZE]; // ValidateSQLTableName will write to it :O strcpy(path, "nosep"); db[0] = table[0] = '\0'; assert_false(ValidateSQLTableName(path, db, sizeof(db), table, sizeof(table))); assert_string_equal(db, ""); assert_string_equal(table, ""); strcpy(path, "cfsettings\\users/users"); db[0] = table[0] = '\0'; assert_false(ValidateSQLTableName(path, db, sizeof(db), table, sizeof(table))); assert_string_equal(db, ""); assert_string_equal(table, ""); strcpy(path, "a.b/c"); db[0] = table[0] = '\0'; assert_false(ValidateSQLTableName(path, db, sizeof(db), table, sizeof(table))); assert_string_equal(db, ""); assert_string_equal(table, ""); // Seems like they should work, but they are invalid because of bugs: db[0] = table[0] = '\0'; strcpy(path, "a/b"); assert_false(ValidateSQLTableName(path, db, sizeof(db), table, sizeof(table))); assert_string_equal(db, ""); assert_string_equal(table, ""); db[0] = table[0] = '\0'; strcpy(path, "a\\b"); assert_false(ValidateSQLTableName(path, db, sizeof(db), table, sizeof(table))); assert_string_equal(db, ""); assert_string_equal(table, ""); } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_ValidateSQLTableName), }; return run_tests(tests); } cfengine-3.24.2/tests/unit/policy_test.c0000644000000000000000000003364715010704253020213 0ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include /* xsnprintf */ static Policy *TestParsePolicy(const char *filename) { char path[PATH_MAX]; xsnprintf(path, sizeof(path), "%s/%s", TESTDATADIR, filename); return ParserParseFile(AGENT_TYPE_COMMON, path, PARSER_WARNING_ALL, PARSER_WARNING_ALL); } static void DumpErrors(Seq *errs) { if (SeqLength(errs) > 0) { Writer *writer = FileWriter(stdout); for (size_t i = 0; i < errs->length; i++) { PolicyErrorWrite(writer, errs->data[i]); } FileWriterDetach(writer); } } static Seq *LoadAndCheck(const char *filename) { Policy *p = TestParsePolicy(filename); Seq *errs = SeqNew(10, PolicyErrorDestroy); PolicyCheckPartial(p, errs); DumpErrors(errs); PolicyDestroy(p); return errs; } static Seq *LoadAndCheckString(const char *policy_code) { char tmp[] = TESTDATADIR "/cfengine_test.XXXXXX"; mkstemp(tmp); { FILE *out = fopen(tmp, "w"); Writer *w = FileWriter(out); WriterWrite(w, policy_code); WriterClose(w); } Policy *p = ParserParseFile(AGENT_TYPE_COMMON, tmp, PARSER_WARNING_ALL, PARSER_WARNING_ALL); assert_true(p); Seq *errs = SeqNew(10, PolicyErrorDestroy); PolicyCheckPartial(p, errs); PolicyDestroy(p); unlink(tmp); return errs; } static void test_failsafe(void) { char tmp[] = TESTDATADIR "/cfengine_test.XXXXXX"; mkstemp(tmp); WriteBuiltinFailsafePolicyToPath(tmp); Policy *failsafe = ParserParseFile(AGENT_TYPE_COMMON, tmp, PARSER_WARNING_ALL, PARSER_WARNING_ALL); unlink(tmp); assert_true(failsafe); Seq *errs = SeqNew(10, PolicyErrorDestroy); PolicyCheckPartial(failsafe, errs); DumpErrors(errs); assert_int_equal(0, SeqLength(errs)); { EvalContext *ctx = EvalContextNew(); PolicyCheckRunnable(ctx, failsafe, errs); DumpErrors(errs); assert_int_equal(0, SeqLength(errs)); EvalContextDestroy(ctx); } assert_int_equal(0, (SeqLength(errs))); SeqDestroy(errs); PolicyDestroy(failsafe); } static void test_bundle_redefinition(void) { Seq *errs = LoadAndCheck("bundle_redefinition.cf"); assert_int_equal(2, errs->length); SeqDestroy(errs); } static void test_bundle_reserved_name(void) { Seq *errs = LoadAndCheck("bundle_reserved_name.cf"); assert_int_equal(1, errs->length); SeqDestroy(errs); } static void test_body_redefinition(void) { Seq *errs = LoadAndCheck("body_redefinition.cf"); assert_int_equal(2, errs->length); SeqDestroy(errs); } static void test_body_control_no_arguments(void) { Seq *errs = LoadAndCheck("body_control_no_arguments.cf"); assert_int_equal(1, errs->length); SeqDestroy(errs); } static void test_vars_multiple_types(void) { Seq *errs = LoadAndCheck("vars_multiple_types.cf"); assert_int_equal(1, errs->length); SeqDestroy(errs); } static void test_methods_invalid_arity(void) { Seq *errs = LoadAndCheck("methods_invalid_arity.cf"); assert_int_equal(1, errs->length); SeqDestroy(errs); } static void test_promise_duplicate_handle(void) { Seq *errs = LoadAndCheck("promise_duplicate_handle.cf"); assert_int_equal(1, errs->length); SeqDestroy(errs); } static void test_policy_json_to_from(void) { EvalContext *ctx = EvalContextNew(); Policy *policy = NULL; { Policy *original = TestParsePolicy("benchmark.cf"); JsonElement *json = PolicyToJson(original); PolicyDestroy(original); policy = PolicyFromJson(json); JsonDestroy(json); } assert_true(policy); assert_int_equal(1, SeqLength(policy->bundles)); assert_int_equal(3, SeqLength(policy->bodies)); { Bundle *main_bundle = PolicyGetBundle(policy, NULL, "agent", "main"); assert_true(main_bundle); { { const BundleSection *files = BundleGetSection(main_bundle, "files"); assert_true(files); assert_int_equal(1, SeqLength(files->promises)); for (size_t i = 0; i < SeqLength(files->promises); i++) { Promise *promise = SeqAt(files->promises, i); if (strcmp("/tmp/stuff", promise->promiser) == 0) { assert_string_equal("any", promise->classes); assert_int_equal(2, SeqLength(promise->conlist)); { Constraint *create = PromiseGetConstraint(promise, "create"); assert_true(create); assert_string_equal("create", create->lval); assert_string_equal("true", RvalScalarValue(create->rval)); } { Constraint *create = PromiseGetConstraint(promise, "perms"); assert_true(create); assert_string_equal("perms", create->lval); assert_string_equal("myperms", RvalScalarValue(create->rval)); } } else { fprintf(stderr, "Found unknown promise"); fail(); } } } { const char* reportOutput[2] = { "Hello, CFEngine", "Hello, world" }; const char* reportClass[2] = { "cfengine", "any" }; const BundleSection *reports = BundleGetSection(main_bundle, "reports"); assert_true(reports); assert_int_equal(2, SeqLength(reports->promises)); for (size_t i = 0; i < SeqLength(reports->promises); i++) { Promise *promise = SeqAt(reports->promises, i); if (strcmp(reportOutput[i], promise->promiser) == 0) { assert_string_equal(reportClass[i], promise->classes); assert_int_equal(1, SeqLength(promise->conlist)); { Constraint *friend_pattern = SeqAt(promise->conlist, 0); assert_true(friend_pattern); assert_string_equal("friend_pattern", friend_pattern->lval); assert_int_equal(RVAL_TYPE_FNCALL, friend_pattern->rval.type); FnCall *fn = RvalFnCallValue(friend_pattern->rval); assert_string_equal("hash", fn->name); assert_int_equal(2, RlistLen(fn->args)); } } else { fprintf(stderr, "Found unknown promise"); fail(); } } } } } { Body *myperms = PolicyGetBody(policy, NULL, "perms", "myperms"); assert_true(myperms); { Seq *mode_cps = BodyGetConstraint(myperms, "mode"); assert_int_equal(1, SeqLength(mode_cps)); Constraint *mode = SeqAt(mode_cps, 0); assert_string_equal("mode", mode->lval); assert_string_equal("555", RvalScalarValue(mode->rval)); SeqDestroy(mode_cps); } } PolicyDestroy(policy); EvalContextDestroy(ctx); } static void test_policy_json_offsets(void) { JsonElement *json = NULL; { Policy *original = TestParsePolicy("benchmark.cf"); json = PolicyToJson(original); PolicyDestroy(original); } assert_true(json); JsonElement *json_bundles = JsonObjectGetAsArray(json, "bundles"); { JsonElement *main_bundle = JsonArrayGetAsObject(json_bundles, 0); int line = JsonPrimitiveGetAsInteger(JsonObjectGet(main_bundle, "line")); assert_int_equal(9, line); JsonElement *json_promise_types = JsonObjectGetAsArray(main_bundle, "promiseTypes"); { JsonElement *json_reports_type = JsonArrayGetAsObject(json_promise_types, 0); line = JsonPrimitiveGetAsInteger(JsonObjectGet(json_reports_type, "line")); assert_int_equal(11, line); JsonElement *json_contexts = JsonObjectGetAsArray(json_reports_type, "contexts"); JsonElement *cf_context = JsonArrayGetAsObject(json_contexts, 0); JsonElement *cf_context_promises = JsonObjectGetAsArray(cf_context, "promises"); JsonElement *hello_cf_promise = JsonArrayGetAsObject(cf_context_promises, 0); line = JsonPrimitiveGetAsInteger(JsonObjectGet(hello_cf_promise, "line")); assert_int_equal(13, line); JsonElement *hello_cf_attribs = JsonObjectGetAsArray(hello_cf_promise, "attributes"); { JsonElement *friend_pattern_attrib = JsonArrayGetAsObject(hello_cf_attribs, 0); line = JsonPrimitiveGetAsInteger(JsonObjectGet(friend_pattern_attrib, "line")); assert_int_equal(14, line); } } } JsonElement *json_bodies = JsonObjectGetAsArray(json, "bodies"); { JsonElement *control_body = JsonArrayGetAsObject(json_bodies, 0); int line = JsonPrimitiveGetAsInteger(JsonObjectGet(control_body, "line")); assert_int_equal(4, line); JsonElement *myperms_body = JsonArrayGetAsObject(json_bodies, 1); line = JsonPrimitiveGetAsInteger(JsonObjectGet(myperms_body, "line")); assert_int_equal(29, line); JsonElement *myperms_contexts = JsonObjectGetAsArray(myperms_body, "contexts"); JsonElement *any_context = JsonArrayGetAsObject(myperms_contexts, 0); JsonElement *any_attribs = JsonObjectGetAsArray(any_context, "attributes"); { JsonElement *mode_attrib = JsonArrayGetAsObject(any_attribs, 0); line = JsonPrimitiveGetAsInteger(JsonObjectGet(mode_attrib, "line")); assert_int_equal(31, line); } } JsonDestroy(json); } static void test_util_bundle_qualified_name(void) { Bundle *b = xcalloc(1, sizeof(struct Bundle_)); assert_false(BundleQualifiedName(b)); b->name = "bar"; char *fqname = BundleQualifiedName(b); assert_string_equal("default:bar", fqname); free(fqname); b->ns = "foo"; fqname = BundleQualifiedName(b); assert_string_equal("foo:bar", fqname); free(fqname); free(b); } static void test_util_qualified_name_components(void) { { char *ns = QualifiedNameNamespaceComponent(":"); assert_string_equal("", ns); free(ns); char *sym = QualifiedNameScopeComponent(":"); assert_string_equal("", sym); free(sym); } { char *ns = QualifiedNameNamespaceComponent(""); assert_false(ns); free(ns); char *sym = QualifiedNameScopeComponent(""); assert_string_equal("", sym); free(sym); } { char *ns = QualifiedNameNamespaceComponent("foo"); assert_false(ns); free(ns); char *sym = QualifiedNameScopeComponent("foo"); assert_string_equal("foo", sym); free(sym); } { char *ns = QualifiedNameNamespaceComponent(":foo"); assert_string_equal("", ns); free(ns); char *sym = QualifiedNameScopeComponent(":foo"); assert_string_equal("foo", sym); free(sym); } { char *ns = QualifiedNameNamespaceComponent("foo:"); assert_string_equal("foo", ns); free(ns); char *sym = QualifiedNameScopeComponent("foo:"); assert_string_equal("", sym); free(sym); } { char *ns = QualifiedNameNamespaceComponent("foo:bar"); assert_string_equal("foo", ns); free(ns); char *sym = QualifiedNameScopeComponent("foo:bar"); assert_string_equal("bar", sym); free(sym); } } static void test_promiser_empty_varref(void) { Seq *errs = LoadAndCheck("promiser_empty_varref.cf"); assert_int_equal(1, errs->length); SeqDestroy(errs); } static void test_constraint_comment_nonscalar(void) { Seq *errs = LoadAndCheck("constraint_comment_nonscalar.cf"); assert_int_equal(1, errs->length); SeqDestroy(errs); } // TODO: consider moving this into a mod_common_test static void test_body_action_with_log_repaired_needs_log_string(void) { { Seq *errs = LoadAndCheckString("body action foo {" " log_repaired => '/tmp/abc';" "}"); assert_int_equal(1, errs->length); SeqDestroy(errs); } { Seq *errs = LoadAndCheckString("body action foo {" " log_repaired => '/tmp/abc';" " log_string => 'stuff';" "}"); assert_int_equal(0, errs->length); SeqDestroy(errs); } } int main() { PRINT_TEST_BANNER(); const UnitTest tests[] = { unit_test(test_failsafe), unit_test(test_bundle_redefinition), unit_test(test_bundle_reserved_name), unit_test(test_body_redefinition), unit_test(test_body_control_no_arguments), unit_test(test_vars_multiple_types), unit_test(test_methods_invalid_arity), unit_test(test_promise_duplicate_handle), unit_test(test_policy_json_to_from), unit_test(test_policy_json_offsets), unit_test(test_util_bundle_qualified_name), unit_test(test_util_qualified_name_components), unit_test(test_constraint_comment_nonscalar), unit_test(test_promiser_empty_varref), unit_test(test_body_action_with_log_repaired_needs_log_string), }; return run_tests(tests); } // STUBS cfengine-3.24.2/tests/unit/matching_test.c0000644000000000000000000000271015010704253020471 0ustar00rootroot00000000000000#include #include #include #include void test_has_regex_meta_chars(void) { assert_false(HasRegexMetaChars("string")); assert_false(HasRegexMetaChars("ala ma kota a kot ma ale")); assert_true(HasRegexMetaChars("^string")); assert_true(HasRegexMetaChars("^(string)")); assert_true(HasRegexMetaChars("string$")); assert_true(HasRegexMetaChars("(string)$")); assert_true(HasRegexMetaChars("string.*")); assert_true(HasRegexMetaChars("string*")); assert_true(HasRegexMetaChars("string.")); assert_true(HasRegexMetaChars("a?")); assert_true(HasRegexMetaChars("a*")); assert_true(HasRegexMetaChars("a+")); assert_true(HasRegexMetaChars("a{3}")); assert_true(HasRegexMetaChars("a{3,6}")); assert_true(HasRegexMetaChars("(a|b)")); assert_true(HasRegexMetaChars("a(bcd)*")); assert_true(HasRegexMetaChars("c.+t")); assert_true(HasRegexMetaChars("a(bcd)?e")); assert_true(HasRegexMetaChars("a(bcd){2,3}e")); assert_true(HasRegexMetaChars("(yes)|(no)")); assert_true(HasRegexMetaChars("pro(b|n|r|l)ate")); assert_true(HasRegexMetaChars("c[aeiou]t")); assert_true(HasRegexMetaChars("^[a-zA-Z0-9_]+$")); assert_true(HasRegexMetaChars("\\d{5}")); assert_true(HasRegexMetaChars("\\d")); } int main() { const UnitTest tests[] = { unit_test(test_has_regex_meta_chars), }; PRINT_TEST_BANNER(); return run_tests(tests); } cfengine-3.24.2/tests/valgrind-check/0000755000000000000000000000000015010704323017374 5ustar00rootroot00000000000000cfengine-3.24.2/tests/valgrind-check/Makefile.am0000644000000000000000000000210615010704253021431 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # DISTFILES = run_checks.sh run.sh valgrind.sh Makefile.in Makefile.am Containerfile cfengine-3.24.2/tests/valgrind-check/valgrind.sh0000644000000000000000000001444415010704253021547 0ustar00rootroot00000000000000#!/bin/bash function print_ps { set +e echo "CFEngine processes:" ps aux | grep [c]f- echo "Valgrind processes:" ps aux | grep [v]algrind set -e } function stop_daemons { echo "Stopping cfengine daemons" pkill -f cf-serverd || echo "Did not kill cf-serverd" pkill -f cf-execd || echo "Did not kill cf-execd" pkill -f cf-monitord || echo "Did not kill cf-monitord" } function no_errors { set +e grep -i "error" $1 grep -q -i "error" $1 && exit 1 set -e } function check_daemon_output { echo "Examining $1:" no_errors $1 } function check_valgrind_output { set -e if [ ! -f "$1" ]; then echo "$1 does not exists!" exit 1 fi echo "Looking for problems in $1:" grep -i "ERROR SUMMARY: 0 errors" "$1" cat $1 | sed -e "/ 0 errors/d" -e "/and suppressed error/d" -e "/a memory error detector/d" -e "/This database contains unknown binary data/d" > filtered.txt no_errors filtered.txt set +e grep -i "at 0x" filtered.txt grep -i -q "at 0x" filtered.txt && exit 1 grep -i "by 0x" filtered.txt grep -i -q "by 0x" filtered.txt && exit 1 grep -i "Failed to connect" filtered.txt grep -i -q "Failed to connect" filtered.txt && exit 1 set -e } function check_masterfiles_and_inputs { set -e echo "Comparing promises.cf from inputs and masterfiles:" diff -u /var/cfengine/inputs/promises.cf /var/cfengine/masterfiles/promises.cf } set -e set -x # In case things go wrong and this hangs, let's make sure things get properly # cleaned up from here rather than relying on the outer environment doing the # cleanup. In case this runs in a container, it could be a big # difference. Especially in a case of an SPC. { sleep 30m && kill -9 $$; } & auto_destruct_pid=$! trap "kill $auto_destruct_pid" EXIT # Assume we are in core directory if [ -f ./configure ] ; then ./configure -C --enable-debug else ./autogen.sh -C --enable-debug fi make -j -l $(getconf _NPROCESSORS_ONLN) make install cd ../masterfiles if [ -f ./configure ] ; then ./configure -C --enable-debug else ./autogen.sh -C --enable-debug fi make make install /var/cfengine/bin/cf-agent --version VG_OPTS="--leak-check=full --track-origins=yes --error-exitcode=1" BOOTSTRAP_IP="127.0.0.1" valgrind $VG_OPTS /var/cfengine/bin/cf-key 2>&1 | tee cf-key.txt check_valgrind_output cf-key.txt valgrind $VG_OPTS /var/cfengine/bin/cf-agent -B $BOOTSTRAP_IP 2>&1 | tee bootstrap.txt check_valgrind_output bootstrap.txt echo "Running cf-check diagnose --validate on all databases:" valgrind $VG_OPTS /var/cfengine/bin/cf-check diagnose --validate 2>&1 | tee cf_check_validate_all_1.txt check_valgrind_output cf_check_validate_all_1.txt check_masterfiles_and_inputs print_ps echo "Stopping before relaunch under valgrind" stop_daemons sleep 10 print_ps echo "Starting cf-serverd with valgrind in background:" valgrind $VG_OPTS --log-file=serverd.txt /var/cfengine/bin/cf-serverd --no-fork 2>&1 > serverd_output.txt & server_pid="$!" echo "Starting cf-execd with valgrind in background:" valgrind $VG_OPTS --log-file=execd.txt /var/cfengine/bin/cf-execd --no-fork 2>&1 > execd_output.txt & exec_pid="$!" print_ps # cf-serverd running under valgrind can be really slow to start, let's give it # some time before we move on and potentially hit the wall if it's actually # malfunctioning tries=12 # max 2 minutes while /var/cfengine/bin/cf-net -H $BOOTSTRAP_IP connect | grep Failed; do tries=$((tries - 1)) if [ $tries -le 0 ]; then break; fi sleep 10 done echo "Running cf-net:" valgrind $VG_OPTS /var/cfengine/bin/cf-net GET /var/cfengine/masterfiles/promises.cf 2>&1 | tee get.txt check_valgrind_output get.txt echo "Checking promises.cf diff (from cf-net GET):" diff -u ./promises.cf /var/cfengine/masterfiles/promises.cf echo "Running update.cf:" valgrind $VG_OPTS /var/cfengine/bin/cf-agent -K -f update.cf 2>&1 | tee update.txt check_valgrind_output update.txt check_masterfiles_and_inputs echo "Running update.cf without local copy:" valgrind $VG_OPTS /var/cfengine/bin/cf-agent -K -f update.cf -D mpf_skip_local_copy_optimization 2>&1 | tee update2.txt check_valgrind_output update2.txt check_masterfiles_and_inputs echo "Running promises.cf:" valgrind $VG_OPTS /var/cfengine/bin/cf-agent -K -f promises.cf 2>&1 | tee promises.txt check_valgrind_output promises.txt # Dump all databases, use grep to filter the JSON lines # (optional whitespace then double quote or curly brackets). # Some of the databases have strings containing "error" # which check_valgrind_output greps for. echo "Running cf-check dump:" valgrind $VG_OPTS /var/cfengine/bin/cf-check dump 2>&1 | grep -E '\s*[{}"]' --invert-match | tee cf_check_dump.txt check_valgrind_output cf_check_dump.txt echo "Running cf-check diagnose on all databases" valgrind $VG_OPTS /var/cfengine/bin/cf-check diagnose 2>&1 | tee cf_check_diagnose.txt check_valgrind_output cf_check_diagnose.txt echo "Running cf-check diagnose --validate on all databases:" valgrind $VG_OPTS /var/cfengine/bin/cf-check diagnose --validate 2>&1 | tee cf_check_validate_all_2.txt check_valgrind_output cf_check_validate_all_2.txt echo "Checking that bootstrap ID doesn't change" /var/cfengine/bin/cf-agent --show-evaluated-vars | grep bootstrap_id > id_a /var/cfengine/bin/cf-agent -K --show-evaluated-vars | grep bootstrap_id > id_b cat id_a diff id_a id_b echo "Checking that bootstrap ID has expected length" [ `cat id_a | awk '{print $2}' | wc -c` -eq 41 ] print_ps echo "cf-execd outputs:" tail execd_output.txt tail execd.txt echo "cf-serverd outputs:" tail serverd_output.txt tail serverd.txt echo "Checking that serverd and execd PIDs are still correct/alive:" ps -p $exec_pid ps -p $server_pid echo "Killing valgrind cf-execd" kill $exec_pid echo "Killing valgrind cf-serverd" kill $server_pid wait $exec_pid wait $server_pid echo "Output from cf-execd in valgrind:" cat execd.txt check_valgrind_output execd.txt check_daemon_output execd_output.txt echo "Output from cf-serverd in valgrind:" cat serverd.txt check_valgrind_output serverd.txt check_daemon_output serverd_output.txt stop_daemons echo "Done killing" sleep 10 print_ps echo "Check that bootstrap was successful" grep "This host assumes the role of policy server" bootstrap.txt grep "completed successfully!" bootstrap.txt echo "valgrind_health_check successful! (valgrind.sh)" cfengine-3.24.2/tests/valgrind-check/run_checks.sh0000755000000000000000000000033715010704253022064 0ustar00rootroot00000000000000#!/bin/bash set -x function check_with_valgrind() { bash tests/valgrind-check/valgrind.sh } cd "$(dirname $0)"/../../ failure=0 check_with_valgrind || { echo "FAIL: valgrind check failed"; failure=1; } exit $failure cfengine-3.24.2/tests/valgrind-check/Containerfile0000644000000000000000000000065715010704253022113 0ustar00rootroot00000000000000FROM ubuntu:22.04 AS build RUN DEBIAN_FRONTEND=noninteractive apt-get update -y RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libssl-dev libxml2-dev libpam0g-dev liblmdb-dev libacl1-dev libpcre2-dev RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3 git flex bison byacc automake make autoconf libtool valgrind COPY masterfiles masterfiles COPY core core WORKDIR core CMD bash tests/valgrind-check/run_checks.sh cfengine-3.24.2/tests/valgrind-check/Makefile.in0000644000000000000000000004145415010704301021445 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tests/valgrind-check ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ DISTFILES = run_checks.sh run.sh valgrind.sh Makefile.in Makefile.am Containerfile all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/valgrind-check/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/valgrind-check/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/valgrind-check/run.sh0000644000000000000000000000043215010704253020535 0ustar00rootroot00000000000000#!/bin/bash set -e trap "echo FAILURE" ERR set -x cd ../../../ if which podman ; then CLI="sudo podman --cgroup-manager=cgroupfs" else CLI="docker" fi $CLI build --tag ubuntu:mycfecontainer -f ./core/tests/valgrind-check/Containerfile . $CLI run --rm ubuntu:mycfecontainer cfengine-3.24.2/tests/acceptance/0000755000000000000000000000000015010704323016601 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/default.cf.sub0000644000000000000000000000232715010704253021335 0ustar00rootroot00000000000000######################################################################## # Acceptance test framework. # # See README for details about writing test cases. ######################################################################## bundle common D { vars: any:: "owndir" string => "$(this.promise_dirname)"; # If not testing the masterfiles policy framework we want to include the # plucked bodies and bundles so that we have conveniant access to commonly # used bundles and bodies. !testing_masterfiles_policy_framework:: "inputs" slist => { "$(D.owndir)$(const.dirsep)dcs.cf.sub", "$(D.owndir)$(const.dirsep)plucked.cf.sub", }; # If testing the masterfiles policy framework then load the stdlib by # default so it can be leveraged as expected. testing_masterfiles_policy_framework:: "inputs" slist => { "$(D.owndir)$(const.dirsep)dcs.cf.sub", "$(D.owndir)$(const.dirsep)..$(const.dirsep)..$(const.dirsep)lib$(const.dirsep)stdlib.cf" }; } body file control { # plucked.cf.sub comes from the stdlib with `make pluck` inputs => { @(D.inputs) }; } cfengine-3.24.2/tests/acceptance/02_classes/0000755000000000000000000000000015010704253020541 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/03_os/0000755000000000000000000000000015010704253021464 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/03_os/ubuntu.cf0000644000000000000000000000170215010704253023320 0ustar00rootroot00000000000000####################################################### # # Test ubuntu classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: ubuntu_18_04.ubuntu_18_4:: "not_ok"; ubuntu_16_04.ubuntu_16_4:: "not_ok"; ubuntu_14_04.ubuntu_14_4:: "not_ok"; ubuntu_12_04.ubuntu_12_4:: "not_ok"; any:: "ok" not => "not_ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/03_os/text.txt0000644000000000000000000000001215010704253023202 0ustar00rootroot00000000000000Succeeded cfengine-3.24.2/tests/acceptance/02_classes/03_os/powershell.cf0000644000000000000000000000343615010704253024170 0ustar00rootroot00000000000000####################################################### # # Test powershell class # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" and => { "!windows", "!powershell" }; # This relies on powershell being in the path, which it should be for a standard install. "detected_powershell" expression => regcmp(".*Succeeded.*", execresult("powershell Get-Content $(G.cwd)$(const.dirsep)text.txt", "useshell")); "ok" and => { "windows", "powershell", "detected_powershell" }; "ok" and => { "windows", "!powershell", "!detected_powershell" }; reports: DEBUG.windows.powershell.!detected_powershell:: "Powershell was detected by CFEngine, but not by the test."; DEBUG.windows.!powershell.detected_powershell:: "Powershell was detected by the test, but not by CFEngine."; DEBUG.windows.powershell.detected_powershell:: "Powershell was detected by CFEngine and the test."; DEBUG.windows.!powershell.!detected_powershell:: "Powershell was not detected by the test, nor by CFEngine."; DEBUG.!windows.powershell:: "Powershell was detected on a non-Windows system."; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/0000755000000000000000000000000015010704253023052 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/02_functions/001.cf0000644000000000000000000000226315010704253023667 0ustar00rootroot00000000000000####################################################### # # Test isgreaterthan() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" and => { isgreaterthan("1", "0"), isgreaterthan("2.7e3", "1"), isgreaterthan("2", "1.1"), isgreaterthan("2.7e3", "9e1"), isgreaterthan("3b", "2z"), isgreaterthan("beta", "alpha"), isgreaterthan("beta", ""), isgreaterthan("beta", "-75"), isgreaterthan("3", ""), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/isipinsubnet-valid-ip.cf0000644000000000000000000000313415010704253027604 0ustar00rootroot00000000000000####################################################### # # Test isipinsubnet() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3081" } string => "Test that isipinsubnet() validates IP addresses as valid especially within the 0.0.0.0/0 range"; "test_soft_fail" string => "any", meta => { "CFE-3081"}; vars: "variable_value_from_varible" string => "$(nosuch.variable)"; "candidates" slist => { "10.68.71.5", "10.168.171.5", "not-an-ip-address" }; "validIPv4[$(candidates)]" string => "$(candidates)", if => isipinsubnet( "0.0.0.0/0", "$(candidates)" ); "validIPv4_addresses" slist => getindices( validIPv4 ); } bundle agent check { vars: "reg_valid_ipv4" string => "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; classes: # We only pass if every one of the ip addresses within the subnet is actually a valid ipv4 string. "pass" expression => every( $(reg_valid_ipv4), @(test.validIPv4_addresses) ); reports: pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; (DEBUG|EXTRA).!pass:: "Not all ips found to be valid seem to match the regular expression for ipv4 address"; "validIPv4[$(test.candidates)] = $(test.candidates)"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/classesmatching.cf0000644000000000000000000000375715010704253026550 0ustar00rootroot00000000000000####################################################### # # Test classesmatching() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "known" slist => { "cfengine", "cfengine_3", "agent", "any", $(dow), $(dow) }; "known_str" string => join(" ", "known"); Monday:: "dow" string => "Monday"; Tuesday:: "dow" string => "Tuesday"; Wednesday:: "dow" string => "Wednesday"; Thursday:: "dow" string => "Thursday"; Friday:: "dow" string => "Friday"; Saturday:: "dow" string => "Saturday"; Sunday:: "dow" string => "Sunday"; } ####################################################### bundle agent test { vars: "matched" slist => { classesmatching("^cfengine$"), # static string # range of multiples classesmatching("^cfengine_[0-9]$"), # alternation/capture of single classesmatching("^a(g)ent$"), # range of single classesmatching("^a[n]y$"), # alternation of multiples classesmatching("^(Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day$"), # interpolation classesmatching("^$(init.dow)$"), }; "matched_str" string => join(" ", "matched"); } ####################################################### bundle agent check { classes: "ok" expression => strcmp($(init.known_str), $(test.matched_str)); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG.!ok:: "$(this.promise_filename) expected '$(init.known_str)', got '$(test.matched_str)'"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/016.cf0000644000000000000000000000266415010704253023702 0ustar00rootroot00000000000000####################################################### # # Test isvariable() on arrays # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "a[b]" string => "c"; "a[x][y]" string => "z"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "a[b]" string => "c"; "a[x][y]" string => "z"; classes: "should_fail" or => { isvariable("g.a"), isvariable("g.a[c]"), isvariable("g.a[x]"), isvariable("g.a[x][y][z]"), isvariable("a"), isvariable("a[c]"), isvariable("a[x]"), isvariable("a[x][y][z]"), }; "ok" and => { "!should_fail", isvariable("g.a[b]"), isvariable("g.a[x][y]"), isvariable("a[b]"), isvariable("a[x][y]"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { vars: "dummy" string => "dummy"; } empty_list_or_data_doesnt_return_true_for_filesexist.cf0000644000000000000000000000177015010704253036313 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/02_functionsbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2631" } string => "Test that empty lists or data containers do not return true with filesexist. There are no files provided to verify!"; vars: "emptylist" slist => {}; "emptydata" data => '{}'; classes: "files_in_empty_list_exist" expression => filesexist( @(emptylist) ); "files_in_empty_data_exist" expression => filesexist( @(emptydata) ); "pass" expression => "!(files_in_empty_list_exist|files_in_empty_data_exist)"; reports: DEBUG|EXTRA:: "CFEngine $(sys.cf_version)"; (DEBUG|EXTRA).files_in_empty_list_exist:: "files_in_empty_list_exist"; (DEBUG|EXTRA).files_in_empty_data_exist:: "files_in_empty_data_exist"; pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/008.cf0000644000000000000000000000162715010704253023701 0ustar00rootroot00000000000000####################################################### # # Test userexists() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { userexists("root"), userexists("xxxscrabbleroot"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/010.cf0000644000000000000000000000151115010704253023662 0ustar00rootroot00000000000000####################################################### # # Test isdir() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { isdir("/"), isdir("$(G.etc_passwd)"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/017.cf0000644000000000000000000000176415010704253023703 0ustar00rootroot00000000000000####################################################### # # Test classmatch() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" and => { classmatch("any"), classmatch("cfengine"), classmatch("cf.*"), classmatch("Hr.*"), classmatch("Yr.*"), classmatch("Min.*"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/012.cf0000644000000000000000000000141015010704253023662 0ustar00rootroot00000000000000####################################################### # # Test isdir() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" not => isdir("/xxgobbleroot"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/011.cf0000644000000000000000000000152615010704253023671 0ustar00rootroot00000000000000####################################################### # # Test isplain() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { isplain("$(G.etc_passwd)"), isplain("$(G.etc)"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/030.cf0000644000000000000000000000250215010704253023665 0ustar00rootroot00000000000000####################################################### # # Test concat() function # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "a" string => "a"; "b" string => "b"; "c" string => "c"; "str" string => "str"; "nil" string => ""; classes: "noarg" expression => strcmp(concat(), ""); "a" expression => strcmp(concat("$(a)"), "a"); "a_b" expression => strcmp(concat("$(a)", "$(b)"), "ab"); "a_b_c" expression => strcmp(concat("$(a)", "$(b)", "$(c)"), "abc"); "nil_nil" expression => strcmp(concat("$(nil)", "$(nil)"), ""); "str_str" expression => strcmp(concat("$(str)", "$(str)"), "strstr"); "ok" and => { "noarg", "a", "a_b", "a_b_c", "nil_nil", "str_str" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getindices_returns_positonal_indices_from_list.cf0000644000000000000000000000313315010704253035051 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/02_functionsbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-2930" } string => "Test that getindices() returns the positional indices from a list"; "test_soft_fail" string => "any", meta => { "CFE-2930" }; vars: "list" slist => { "beta", "alpha", "gamma" }; "getindices_list" slist => getindices( list ); } ####################################################### bundle agent check { vars: "expected_indices" slist => { 0, 1, 2 }; "diff_getindices_vs_expected" comment => "Expect to find no elements from getindices that differ from expected", slist => difference( "test.getindices_list", "expected_indices" ); "diff_expected_vs_getindices" comment => "Expect to find no elements from expected that differ from getindices", slist => difference( "expected_indices", "test.getindices_list" ); reports: "$(this.promise_filename) Pass" if => strcmp( join( ", ", sort( expected_indices, lex) ), join( ", ", sort( "test.getindices_list", lex) ) ); "$(this.promise_filename) FAIL" if => not( strcmp( join( ", ", sort( expected_indices, lex) ), join( ", ", sort( "test.getindices_list", lex) ) )); DEBUG|EXTRA:: "diff_getindices_vs_expected"; "$(diff_getindices_vs_expected)"; "diff_expected_vs_getindices"; "$(diff_expected_vs_getindices)"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/iprange.cf.expected.json0000644000000000000000000000020215010704253027553 0ustar00rootroot00000000000000{ "found": [ "just_locals", "local_range2", "local_range", "all_zeroes_some_interfaces", "all_zeroes" ] } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/silent_returnszero.cf.sub0000644000000000000000000000032615010704253030135 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "main" }; version => "1.0"; } bundle agent main { classes: "test" expression => returnszero("$(G.echo) Pass", "noshell"); } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/returnszero.cf0000644000000000000000000001503415010704253025771 0ustar00rootroot00000000000000####################################################### # # Test returnszero() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; meta: "test_suppress_fail" string => "windows", meta => { "redmine4687" }; } ####################################################### bundle agent check { vars: windows:: "zero_rel" string => "fc $(this.promise_filename) $(this.promise_filename)"; "one_rel" string => "fc $(this.promise_filename) $(this.promise_filename).doesnotexist"; "nxe_rel" string => "nosuchprogramexists"; "zero_abs" string => "c:\windows\system32\fc.exe $(this.promise_filename) $(this.promise_filename)"; "one_abs" string => "c:\windows\system32\fc.exe $(this.promise_filename) $(this.promise_filename).doesnotexist"; "nxe_abs" string => "c:\xbin\nosuchprogramexists"; "zero_powershell" string => "if (diff $(this.promise_filename) $(this.promise_filename)) { exit 1 } else { exit 0 }"; "one_powershell" string => "if (diff $(this.promise_filename) $(this.promise_filename).doesnotexit) { exit 1 } else { exit 0 }"; "nxe_powershell" string => "nosuchprogramexists"; !windows:: "zero_rel" string => "grep root $(G.etc_passwd)"; "one_rel" string => "grep gluequaggaunlikely $(G.etc_passwd)"; "nxe_rel" string => "nosuchprogramexists"; "zero_abs" string => "$(G.grep) root $(G.etc_passwd)"; "one_abs" string => "$(G.grep) gluequaggaunlikely $(G.etc_passwd)"; "nxe_abs" string => "/xbin/nosuchprogramexists"; classes: "rawshell_no_prefix" expression => returnszero("ls /", "useshell"); "rawnoshell_no_prefix" expression => returnszero("ls /", "noshell"); "zero_noshell_rel" expression => returnszero("$(zero_rel)", "noshell"); "zero_useshell_rel" expression => returnszero("$(zero_rel)", "useshell"); "zero_noshell_abs" expression => returnszero("$(zero_abs)", "noshell"); "zero_useshell_abs" expression => returnszero("$(zero_abs)", "useshell"); "one_noshell_rel" expression => returnszero("$(one_rel)", "noshell"); "one_useshell_rel" expression => returnszero("$(one_rel)", "useshell"); "one_noshell_abs" expression => returnszero("$(one_abs)", "noshell"); "one_useshell_abs" expression => returnszero("$(one_abs)", "useshell"); "nxe_noshell_rel" expression => returnszero("$(nxe_rel)", "noshell"); "nxe_useshell_rel" expression => returnszero("$(nxe_rel)", "useshell"); "nxe_noshell_abs" expression => returnszero("$(nxe_abs)", "noshell"); "nxe_useshell_abs" expression => returnszero("$(nxe_abs)", "useshell"); windows:: "zero_powershell" expression => returnszero("$(zero_powershell)", "powershell"); "one_powershell" expression => returnszero("$(one_powershell)", "powershell"); "nxe_powershell" expression => returnszero("$(nxe_powershell)", "powershell"); any:: "ok_common" and => { "!zero_noshell_rel", "zero_useshell_rel", "zero_noshell_abs", "zero_useshell_abs", "!one_noshell_rel", "!one_useshell_rel", "!one_noshell_abs", "!one_useshell_abs", "!nxe_noshell_rel", "!nxe_useshell_rel", "!nxe_noshell_abs", "!nxe_useshell_abs", }; windows:: "ok_windows" and => { "zero_powershell", "!one_powershell", "!nxe_powershell", }; "ok" and => { "ok_common", "ok_windows", }; !windows:: "ok" and => { "ok_common" }; reports: DEBUG.zero_noshell_rel:: "'$(zero_rel)' erroneously returns 0 with noshell"; DEBUG.!zero_noshell_rel:: "'$(zero_rel)' returns non-zero with noshell"; DEBUG.zero_useshell_rel:: "'$(zero_rel)' returns 0 with useshell"; DEBUG.!zero_useshell_rel:: "'$(zero_rel)' erroneously returns non-zero with useshell"; DEBUG.!one_noshell_rel:: "'$(one_rel)' returns non-zero with noshell"; DEBUG.one_noshell_rel:: "'$(one_rel)' erroneously returns 0 with noshell"; DEBUG.!one_useshell_rel:: "'$(one_rel)' returns non-zero with useshell"; DEBUG.one_useshell_rel:: "'$(one_rel)' erroneously returns 0 with useshell"; DEBUG.!nxe_noshell_rel:: "'$(nxe_rel)' returns non-zero with noshell"; DEBUG.nxe_noshell_rel:: "'$(nxe_rel)' erroneously returns 0 with noshell"; DEBUG.!nxe_useshell_rel:: "'$(nxe_rel)' returns non-zero with useshell"; DEBUG.nxe_useshell_rel:: "'$(nxe_rel)' erroneously returns 0 with useshell"; DEBUG.zero_noshell_abs:: "'$(zero_abs)' returns 0 with noshell"; DEBUG.!zero_noshell_abs:: "'$(zero_abs)' erroneously returns non-zero with noshell"; DEBUG.zero_useshell_abs:: "'$(zero_abs)' returns 0 with useshell"; DEBUG.!zero_useshell_abs:: "'$(zero_abs)' erroneously returns non-zero with useshell"; DEBUG.!one_noshell_abs:: "'$(one_abs)' returns non-zero with noshell"; DEBUG.one_noshell_abs:: "'$(one_abs)' erroneously returns 0 with noshell"; DEBUG.!one_useshell_abs:: "'$(one_abs)' returns non-zero with useshell"; DEBUG.one_useshell_abs:: "'$(one_abs)' erroneously returns 0 with useshell"; DEBUG.!nxe_noshell_abs:: "'$(nxe_abs)' returns non-zero with noshell"; DEBUG.nxe_noshell_abs:: "'$(nxe_abs)' erroneously returns 0 with noshell"; DEBUG.!nxe_useshell_abs:: "'$(nxe_abs)' returns non-zero with useshell"; DEBUG.nxe_useshell_abs:: "'$(nxe_abs)' erroneously returns 0 with useshell"; windows.DEBUG.!zero_powershell:: "'$(zero_powershell)' erroneously returns non-zero with powershell"; windows.DEBUG.zero_powershell:: "'$(zero_powershell)' returns 0 with powershell"; windows.DEBUG.!one_powershell:: "'$(one_powershell)' returns non-zero with powershell"; windows.DEBUG.one_powershell:: "'$(one_powershell)' erroneously returns 0 with powershell"; windows.DEBUG.!nxe_powershell:: "'$(nxe_powershell)' returns non-zero with powershell"; windows.DEBUG.nxe_powershell:: "'$(nxe_powershell)' erroneously returns 0 with powershell"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/usemodule.cf0000644000000000000000000000504615010704253025373 0ustar00rootroot00000000000000####################################################### # # Test usemodule() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "script_location" string => dirname("$(this.promise_filename)"); classes: "ok_to_run" not => regcmp("/var/cfengine|.*\.cf-agent", "$(sys.workdir)"); files: ok_to_run:: "$(sys.workdir)/modules/usemodule.cf.bat" create => "true", perms => usemodule_perms, edit_line => usemodule_lines; } bundle edit_line usemodule_lines { insert_lines: windows:: "@echo off"; "\"$(init.script_location)\usemodule.cf.bat\""; !windows:: "#!/bin/sh"; ". \"$(init.script_location)/usemodule.cf.bat\""; delete_lines: ".*"; } body perms usemodule_perms { mode => "755"; } ####################################################### bundle agent test { classes: "ok_to_run" not => regcmp("/var/cfengine|.*\.cf-agent", "$(sys.workdir)"); classes: ok_to_run:: # Should be undefined by the following script. "undefined_class" expression => "any"; "function_ok" expression => usemodule("usemodule.cf.bat", ""); "defined_variable" expression => strcmp("$(usemodule_cf_bat.defined_variable)", "yes"); "ok" and => { "function_ok", "defined_class", "!undefined_class", "defined_variable" }; vars: ok:: "ok" string => "yes"; reports: !ok_to_run:: "Must be run using testall script"; ok_to_run.DEBUG.!function_ok:: "usemodule did not execute correctly."; ok_to_run.DEBUG.!defined_class:: "defined_class was not set, but should be."; ok_to_run.DEBUG.undefined_class:: "undefined_class was set, but shouldn't be."; ok_to_run.DEBUG.!defined_variable:: "defined_variable was not set, but should be."; ok_to_run.DEBUG.function_ok:: "usemodule executed correctly."; ok_to_run.DEBUG.defined_class:: "defined_class was set."; ok_to_run.DEBUG.!undefined_class:: "undefined_class was not set."; ok_to_run.DEBUG.defined_variable:: "defined_variable was set."; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("$(test.ok)", "yes"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/003.cf0000644000000000000000000000204315010704253023665 0ustar00rootroot00000000000000####################################################### # # Test isvariable() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "present" int => "1"; classes: "should_fail" or => { isvariable("x"), isvariable("init.x") }; "should_pass" not => "should_fail"; "ok" and => { "should_pass", isvariable("present"), isvariable("init.dummy") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/021.cf0000644000000000000000000000250315010704253023666 0ustar00rootroot00000000000000####################################################### # # Test filesexist() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "f1" string => "$(G.etc_passwd)"; "f2" string => "$(G.etc_group)"; "f3" string => "/etc/NoFriggin'WayThisExi5ts"; "s1" slist => { "$(f1)", "$(f2)" }; "s2" slist => { "$(f1)", "$(f2)", "$(f3)" }; classes: "ok1" expression => filesexist("@(s1)"); "ok2" not => filesexist("@(s2)"); "ok" and => { "ok1", "ok2" }; reports: DEBUG.ok1:: "All files in list s1 $(s1) exist as expected"; DEBUG.!ok1:: "All files in list s1 $(s1) DO NOT exist (and should)"; DEBUG.ok2:: "All files in list s2 $(s2) do not exist as expected"; DEBUG.!ok2:: "All files in list s2 $(s2) DO exist (and shouldn't)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/004.cf0000644000000000000000000000223615010704253023672 0ustar00rootroot00000000000000####################################################### # # Test strcmp() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "null" string => ""; "one" int => "1"; classes: "should_fail" or => { strcmp("$(null)", "$(one)"), strcmp("01", "$(one)"), strcmp("init.x", "$(init.x)") }; "should_pass" not => "should_fail"; "ok" and => { "should_pass", strcmp("", "$(null)"), strcmp("1", "$(one)"), strcmp("dummy", "$(init.dummy)") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/005.cf0000644000000000000000000000431115010704253023667 0ustar00rootroot00000000000000####################################################### # # Test join() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "zeros" slist => { "solo" }; "zero" string => join("NOISE", "zeros"); "ones" slist => { "a", "bb", "ccc" }; "one" string => join(":", "ones"); "twos" slist => { "xx", "xx", "xx" }; "two" string => join("..", "twos"); "threes" slist => { "" }; "three" string => join("", "threes"); "fours" slist => { "1", "", "3" }; "four" string => join("", "fours"); "fives" slist => { "1", "", "3" }; "five" string => join(",", "fives"); "sixs" slist => { "one ", " two ", " three" }; "six" string => join(" and ", "sixs"); classes: "ok1" expression => strcmp("solo", "$(zero)"); "ok2" expression => strcmp("a:bb:ccc", "$(one)"); "ok3" expression => strcmp("xx..xx..xx", "$(two)"); "ok4" expression => strcmp("", "$(three)"); "ok5" expression => strcmp("13", "$(four)"); "ok6" expression => strcmp("1,,3", "$(five)"); "ok7" expression => strcmp("one and two and three", "$(six)"); "ok" and => { ok1, ok2, ok3, ok4, ok5, ok6, ok7 }; reports: DEBUG.ok1:: "ok1"; DEBUG.ok2:: "ok2"; DEBUG.ok3:: "ok3"; DEBUG.ok4:: "ok4"; DEBUG.ok5:: "ok5"; DEBUG.ok6:: "ok6"; DEBUG.ok7:: "ok7"; DEBUG:: 'strcmp("solo", "$(zero)")'; 'strcmp("a:bb:ccc", "$(one)")'; 'strcmp("xx..xx..xx", "$(two)")'; 'strcmp("", "$(three)")'; 'strcmp("13", "$(four)")'; 'strcmp("1,,3", "$(five)")'; 'strcmp("one and two and three", "$(six)")'; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/isipinsubnet.cf0000644000000000000000000000246415010704253026106 0ustar00rootroot00000000000000####################################################### # # Test isipinsubnet() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { classes: "zeroes_range_match" expression => isipinsubnet("0.0.0.0/0", "1.2.3.4"), meta => { "collect" }; "exact_ip_match" expression => isipinsubnet("1.2.3.4/32", "1.2.3.4"), meta => { "collect" }; "two_ips_match" expression => isipinsubnet("1.2.3.4/16", "4.5.6.7", "1.2.1.2"), meta => { "collect" }; "two_ips_nomatch" expression => isipinsubnet("1.2.3.4/16", "4.5.6.7", "3.4.1.2"), meta => { "collect" }; "garbage_nomatch" expression => isipinsubnet("1.2.3.4/16", "blah", "blue", "bleh"), meta => { "collect" }; vars: "found" slist => classesmatching(".*", "collect"); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/function_args_flattening.cf0000644000000000000000000000267015010704253030445 0ustar00rootroot00000000000000####################################################### # # This really tests that the list returned from splitstring() # gets flattened into the variadic function and() # # Test that and function can take a splitstring function call asa paramater # Redmine:4320 (https://cfengine.com/dev/issues/4320) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common init { classes: "one" expression => "any"; } ####################################################### bundle common test { classes: "fail_direct" expression => "any", if => and("one", "non_existing_class"); "fail_split" expression => "any", if => and(splitstring("one,non_existing_class", ",", "20")); "pass_direct" expression => "any", if => or("one", "non_existing_class"); "pass_split" expression => "any", if => or(splitstring("one,non_existing_class", ",", "20")); "pass_split1" expression => "any", if => not(splitstring("non_existing_class", ",", "20")); } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_expected("pass_direct,pass_split,pass_split1", "fail_direct,fail_split", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/015.cf0000644000000000000000000000340215010704253023670 0ustar00rootroot00000000000000####################################################### # # Test islink() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true"; "$(G.testfile).dir/." create => "true"; "$(G.testfile).link" link_from => test_link("$(G.testfile)"); } body link_from test_link(original) { source => "$(original)"; link_type => "symlink"; } ####################################################### bundle agent test { meta: "test_suppress_fail" string => "windows", meta => { "redmine4608" }; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "good" and => { islink("$(G.testfile).link"), }; "bad" or => { islink("$(G.testfile).dir"), islink("$(G.testfile).dir/"), islink("$(G.testfile)"), islink("$(G.testfile).does-not-exist"), }; "ok" expression => "good&!bad"; reports: DEBUG.good:: "As expected, $(G.testfile).link is a symlink to $(G.testfile)"; DEBUG.bad:: "One of these is detected as a symlink: $(G.testfile).dir, $(G.testfile), $(G.testfile).does-not-exist"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/classes_body_function_param.cf0000644000000000000000000000176115010704253031130 0ustar00rootroot00000000000000####################################################### # # Test that a classes body can take a function as a parameter # Redmine:4319 (https://cfengine.com/dev/issues/4319) ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "filename" string => "this is a filename"; methods: "test" usebundle => noop, classes => if_repaired(canonify("define_a_class_$(filename)")); } ####################################################### bundle agent noop { reports: !any:: "never"; } bundle agent check { classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/029.cf0000644000000000000000000000564515010704253023710 0ustar00rootroot00000000000000####################################################### # # Test logical functions in ifvarclass # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "and_yes_both" expression => "any", ifvarclass => and("any", "any"); "and_no_left" expression => "any", ifvarclass => and("any", "none"); "and_no_right" expression => "any", ifvarclass => and("none", "any"); "and_no_none" expression => "any", ifvarclass => and("none", "none"); "and_arg_fun" expression => "any", ifvarclass => and(isdir("/")); "and_no_arg_fun" expression => "any", ifvarclass => and(isdir("/bin/sh")); "and_two_args_fun" expression => "any", ifvarclass => and(isdir("/"), isdir("/")); "and_long" expression => "any", ifvarclass => and("any", "any", "any", "any", "any", "any", "any", "any"); "and_ok" and => { "and_yes_both", "!and_no_left", "!and_no_right", "!and_no_none", "and_arg_fun", "!and_no_arg_fun", "and_two_args_fun", "and_long" }; # "or_yes_both" expression => "any", ifvarclass => or("any", "any"); "or_yes_left" expression => "any", ifvarclass => or("any", "none"); "or_yes_right" expression => "any", ifvarclass => or("none", "any"); "or_no_none" expression => "any", ifvarclass => or("none", "none"); "or_arg_fun" expression => "any", ifvarclass => or(isdir("/")); "or_no_arg_fun" expression => "any", ifvarclass => or(isdir("/bin/sh")); "or_two_args_fun" expression => "any", ifvarclass => or(isdir("/"), isexecutable("/")); "or_long" expression => "any", ifvarclass => or("any", "any", "any", "any", "any", "any", "any", "any"); "or_ok" and => { "or_yes_both", "or_yes_left", "or_yes_right", "!or_no_none", "or_arg_fun", "!or_no_arg_fun", "or_two_args_fun", "or_long" }; # "not_yes_no" expression => "any", ifvarclass => not("none"); "not_no_yes" expression => "any", ifvarclass => not("any"); "not_arg_fun" expression => "any", ifvarclass => not(islink("/")); "not_ok" and => { "not_yes_no", "!not_no_yes", "not_arg_fun" }; "ok" and => { "and_ok", "or_ok", "not_ok" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/006.cf0000644000000000000000000000477315010704253023704 0ustar00rootroot00000000000000####################################################### # # Test grep() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "zeros" slist => { "", "a", "bb", "ccc", "dddd" }; "zeroz" slist => grep('\d.*', "zeros"); "zero" string => join(",", "zeroz"); "ones" slist => { "", "a", "bb", "ccc", "dddd" }; "onez" slist => grep("c.*", "ones"); "one" string => join(",", "onez"); "twos" slist => { "", "a", "bb", "ccc", "dddd" }; "twoz" slist => grep(".{1,2}", "twos"); "two" string => join(",", "twoz"); "threes" slist => { "", "a", "bb", "ccc", "dddd" }; "threez" slist => grep("ccc", "threes"); "three" string => join(",", "threez"); "fours" slist => { "", "a", "bb", "ccc", "dddd" }; "fourz" slist => grep(".+", "fours"); "four" string => join(",", "fourz"); "fives" slist => { "", "a", "bb", "ccc", "dddd" }; "fivez" slist => grep(".*", "fives"); "five" string => join(",", "fivez"); "sixs" slist => { "", "a", "bb", "ccc", "dddd", '' }; "sixz" slist => grep("^$", "sixs"); "six" string => join(",", "sixz"); classes: "ok1" expression => strcmp("", "$(zero)"); "ok2" expression => strcmp("ccc", "$(one)"); "ok3" expression => strcmp("a,bb", "$(two)"); "ok4" expression => strcmp("ccc", "$(three)"); "ok5" expression => strcmp("a,bb,ccc,dddd", "$(four)"); "ok6" expression => strcmp(",a,bb,ccc,dddd", "$(five)"); "ok7" expression => strcmp(",", "$(six)"); "ok" and => { ok1, ok2, ok3, ok4, ok5, ok6, ok7 }; reports: DEBUG.ok1:: "ok1"; DEBUG.ok2:: "ok2"; DEBUG.ok3:: "ok3"; DEBUG.ok4:: "ok4"; DEBUG.ok5:: "ok5"; DEBUG.ok6:: "ok6"; DEBUG.ok7:: "ok7"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { vars: "dummy" string => "dummy"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/009.cf0000644000000000000000000000163015010704253023674 0ustar00rootroot00000000000000####################################################### # # Test groupexists() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { groupexists("bin"), groupexists("xxxscrabblebin"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/iprange.cf0000644000000000000000000000365715010704253025024 0ustar00rootroot00000000000000####################################################### # # Test iprange() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { classes: "expected_missing" expression => iprange("8.8.8.8/31"), meta => { "collect" }; "expected_missing" expression => iprange("8.8.8.8/24"), meta => { "collect" }; "expected_missing" expression => iprange("8.8.8.8/31", $(sys.interfaces)), meta => { "collect" }; "expected_missing" expression => iprange("8.8.8.8/24", $(sys.interfaces)), meta => { "collect" }; "expected_missing" expression => iprange("0.0.0.0/0", "dummy"), meta => { "collect" }; "all_zeroes" expression => iprange("0.0.0.0/0"), meta => { "collect" }; "all_zeroes_some_interfaces" expression => iprange("0.0.0.0/0", $(sys.interfaces)), meta => { "collect" }; "local_range" expression => iprange("0.0.0.0/1"), meta => { "collect" }; "local_range" expression => iprange("128.0.0.0/1"), meta => { "collect" }; "local_range2" expression => iprange("0.0.0.0/1", $(sys.interfaces)), meta => { "collect" }; "local_range2" expression => iprange("128.0.0.0/1", $(sys.interfaces)), meta => { "collect" }; "just_locals" expression => iprange("$(sys.ip_addresses)/32"), meta => { "collect" }; vars: "found" slist => classesmatching(".*", "collect"); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/getindices_containers.cf0000644000000000000000000000165415010704253027735 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "obj" data => parsejson('{ "a": 1, "b": 2 }'); "arr" data => parsejson('["a", "b"]'); } ####################################################### bundle agent test { vars: "obj_i" slist => getindices("init.obj"); "arr_i" slist => getindices("init.arr"); reports: DEBUG:: "obj_i $(obj_i)"; "arr_i $(arr_i)"; } ####################################################### bundle agent check { classes: "ok" and => { strcmp("a,b", join(",", "test.obj_i")), strcmp("0,1", join(",", "test.arr_i")) }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/laterthan.cf0000644000000000000000000000761015010704253025352 0ustar00rootroot00000000000000####################################################### # # Test laterthan() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { classes: # On 32-bit systems, dates before 1901-12-13 aren't representable "after_year_1902" expression => laterthan(1902,1,1,0,0,0), scope => "namespace"; "after_year_1902_month" expression => laterthan(1902,12,1,0,0,0), scope => "namespace"; "after_year_1902_day" expression => laterthan(1902,12,31,0,0,0), scope => "namespace"; "after_year_1902_hour" expression => laterthan(1902,12,31,23,0,0), scope => "namespace"; "after_year_1902_minute" expression => laterthan(1902,12,31,23,59,0), scope => "namespace"; "after_year_1902_second" expression => laterthan(1902,12,31,23,59,59), scope => "namespace"; # On 32-bit systems, dates after 2038-01-18 aren't representable "after_year_2037" expression => laterthan(2037,1,1,0,0,0), scope => "namespace"; "after_year_2037_month" expression => laterthan(2037,12,1,0,0,0), scope => "namespace"; "after_year_2037_day" expression => laterthan(2037,12,31,0,0,0), scope => "namespace"; "after_year_2037_hour" expression => laterthan(2037,12,31,23,0,0), scope => "namespace"; "after_year_2037_minute" expression => laterthan(2037,12,31,23,59,0), scope => "namespace"; "after_year_2037_second" expression => laterthan(2037,12,31,23,59,59), scope => "namespace"; } ####################################################### bundle agent check { vars: DEBUG:: # The date and time now, in laterthan-compatible format: "present" string => execresult("$(G.date) +(%Y,%m,%d,%H,%M,%S)", "noshell"); # NB: shell would try to sub-shell on this (...), hence noshell. classes: "check_after_year_1902" and => { "after_year_1902", "after_year_1902_month", "after_year_1902_day", "after_year_1902_hour", "after_year_1902_minute", "after_year_1902_second" }; "check_after_year_2037" or => { "after_year_2037", "after_year_2037_month", "after_year_2037_day", "after_year_2037_hour", "after_year_2037_minute", "after_year_2037_second" }; "ok" expression => "check_after_year_1902.!check_after_year_2037"; reports: DEBUG.!after_year_1902:: "Failed laterthan(1902,1,1,0,0,0); year"; DEBUG.!after_year_1902_month:: "Failed laterthan(1902,12,1,0,0,0); month"; DEBUG.!after_year_1902_day:: "Failed laterthan(1902,12,31,0,0,0); day"; DEBUG.!after_year_1902_hour:: "Failed laterthan(1902,12,31,23,0,0); hour"; DEBUG.!after_year_1902_minute:: "Failed laterthan(1902,12,31,23,59,0); minute"; DEBUG.!after_year_1902_second:: "Failed laterthan(1902,12,31,23,59,59); second"; DEBUG.after_year_2037:: "Satisfied laterthan(2037,1,1,0,0,0); year"; DEBUG.after_year_2037_month:: "Satisfied laterthan(2037,12,1,0,0,0); month"; DEBUG.after_year_2037_day:: "Satisfied laterthan(2037,12,31,0,0,0); day"; DEBUG.after_year_2037_hour:: "Satisfied laterthan(2037,12,31,23,0,0); hour"; DEBUG.after_year_2037_minute:: "Satisfied laterthan(2037,12,31,23,59,0); minute"; DEBUG.after_year_2037_second:: "Satisfied laterthan(2037,12,31,23,59,59); second"; DEBUG.!ok:: "The time now is '$(present)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/usemodule.cf.bat0000755000000000000000000000025515010704253026140 0ustar00rootroot00000000000000@rem ' @echo off @rem Careful. Batch and shell script in the same file. @rem ' 1>/dev/null 2>/dev/null echo +defined_class echo -undefined_class echo =defined_variable=yes cfengine-3.24.2/tests/acceptance/02_classes/02_functions/014.cf0000644000000000000000000000146615010704253023677 0ustar00rootroot00000000000000####################################################### # # Test hostinnetgroup # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { classes: "ng_host" expression => hostinnetgroup("netgroup2"); } ####################################################### bundle agent check { classes: "ok" expression => "any"; # check not crashed reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/classesmatching_inherit.cf0000644000000000000000000000205215010704253030255 0ustar00rootroot00000000000000bundle agent __main__ { classes: "defined_in_parent" expression => "cfengine"; methods: "ENT-5850" usebundle => ENT_5850, inherit => "true"; } bundle agent ENT_5850 { vars: "c_matching" slist => classesmatching(".*"); "c_matching_defined_in_parent" slist => classesmatching("defined_in_parent"); classes: "defined_here" expression => "cfengine"; reports: "$(this.promise_filename) Pass" if => some( "defined_in_parent", c_matching); "$(this.promise_filename) FAIL $(this.promise_filename)$(const.n)Could not find class 'defined_in_parent' in classesmatching() but it's defined" if => and( not( some( "defined_in_parent", c_matching) ), defined_in_parent ); "Classes found by classesmatching() starting with 'defined' $(with)" with => join( ", ", classesmatching("defined.*") ); "'defined_here' is defined" if => "defined_here"; "'defined_in_parent' is defined" if => "defined_in_parent"; "Running CFEngine: $(sys.cf_version)"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/classesmatching_inherit_2.cf0000644000000000000000000000240715010704253030502 0ustar00rootroot00000000000000bundle agent common { vars: "logfile" string => "$(this.promise_dirname)$(const.dirsep)defined_classes.log"; } bundle agent __main__ { classes: "defined_in_main"; methods: "init"; "first" inherit => "true"; "check"; } bundle agent init { files: "$(common.logfile)" delete => tidy; } bundle agent first { classes: "defined_in_first"; methods: "second" inherit => "true"; } bundle agent second { classes: "defined_in_second"; methods: "third" inherit => "true"; } bundle agent third { vars: "defined_classes" slist => classesmatching("defined.*"); reports: "defined_classes: $(defined_classes)" report_to_file => "$(common.logfile)"; } bundle agent check { vars: "expected" string => concat("defined_classes: defined_in_main$(const.n)", "defined_classes: defined_in_first$(const.n)", "defined_classes: defined_in_second$(const.n)"); "actual" string => readfile("$(common.logfile)", inf); reports: "$(this.promise_filename) Pass" if => strcmp($(expected), $(actual)); "$(this.promise_filename) FAIL" if => not(strcmp($(expected), $(actual))); } body delete tidy { dirlinks => "delete"; rmdirs => "true"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/usemodule-returns-nonzero.cf0000644000000000000000000000566715010704253030574 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "foo_usemodule" string => "#!/bin/sh echo '=mystring=foo99' echo '+class_from_classes_usemodule' exit 1 "; "foo_commands_module" string => "#!/bin/sh echo '=mystring=foo99' echo '+class_from_commands_module' exit 1 "; files: "${sys.workdir}/modules/foo-usemodule" create => 'true', perms => m( 700 ), edit_defaults => empty, edit_line => append_if_no_line( ${foo_usemodule} ); "${sys.workdir}/modules/foo-commands_module" create => 'true', perms => m( 700 ), edit_defaults => empty, edit_line => append_if_no_line( ${foo_commands_module} ); } bundle agent test { meta: "description" -> { "CFE-942" } string => "Test that when a module executed by usemodule() returns nonzero, it's not interpreted as successful"; "test_soft_fail" string => "any", meta => { "CFE-942" }, comment => "usemodule seems to return true no matter if the module exists returning 0 or nonzero"; classes: # Since the module exits with non zero, we should not get this class "usemodule_expect_no_class_defined_because_return_nonzero" expression => usemodule( "foo-usemodule", "" ), scope => "namespace", if => isexecutable( "$(sys.workdir)/foo-usemodule" ); # Since the module exists non zero, we should get this class "usemodule_expect_class_defined_because_return_nonzero" not => usemodule( "foo-usemodule", "" ), scope => "namespace", if => isexecutable( "$(sys.workdir)/foo-usemodule" ); commands: "$(sys.workdir)/modules/foo-commands_module" module => "true", if => isexecutable( $(this.promiser) ); } bundle agent check { methods: usemodule_expect_no_class_defined_because_return_nonzero.!usemodule_expect_class_defined_because_return_nonzero:: "FAIL" usebundle => dcs_fail( $(this.promise_filename) ); !usemodule_expect_class_defined_because_return_nonzero.usemodule_expect_class_defined_because_return_nonzero:: "Pass" usebundle => dcs_pass( $(this.promise_filename) ); reports: DEBUG:: # Since the module exists nonzero, we don't expect that it communicated things back to the agent "The command execution executed as a module that did not return 0 defined a class (unexpectedly)" if => "class_from_commands_module"; "Did not expect that a class defined as the result of a classes promise usemodule would be defined if the module used returned nonzero" if => "usemodule_expect_no_class_defined_because_return_nonzero"; "expected class to be defined based on negative result from usemodule classes promise" if => "usemodule_expect_class_defined_because_return_nonzero"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/silent_returnszero.cf0000644000000000000000000000110315010704253027337 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { vars: "command" string => "$(sys.cf_agent) -KIf $(this.promise_filename).sub -DAUTO"; "silent_command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*Pass.*", "", $(command), $(this.promise_filename)); "check" usebundle => dcs_passif_output("", ".*Pass.*", $(silent_command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/makerule.cf0000644000000000000000000000440215010704253025171 0ustar00rootroot00000000000000####################################################### # # Test makerule() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "lold" slist => { "$(G.etc_passwd)", "$(G.etc_group)" }; "lnew" slist => { "$(G.etc_passwd)", "$(G.testfile)" }; "lnon" slist => { "$(G.etc_passwd)", "/etc/NoFriggin'WayThisExi5ts" }; files: "$(G.testfile)" create => "true"; "$(G.testfile).nosuchfile" delete => tidy; } ####################################################### bundle agent check { classes: # A new file does not need to be rebuilt from an older file (fails) "ok1" expression => makerule("$(G.testfile)", "$(G.etc_passwd)"); # An older file does need to be rebuilt from a newer file "ok2" expression => makerule("$(G.etc_passwd)", "$(G.testfile)"); # An older file cannot be rebuilt from a non existent file (fails) "ok3" expression => makerule("$(G.etc_passwd)", "$(G.testfile).nosuchfile"); # An non existent file does need to be rebuilt from a source file "ok4" expression => makerule("$(G.testfile).nosuchfile", "$(G.etc_passwd)"); # A new file does not need to be rebuilt from an older file (fails) "ok5" expression => makerule("$(G.testfile)", "test.lold"); # An old file does need to be rebuilt from an newer file in a list "ok6" expression => makerule("$(G.etc_passwd)", "test.lnew"); # An old file does not need to be rebuilt from sources with a missing file (fails) "ok7" expression => makerule("$(G.etc_passwd)", "test.lnon"); "ok" and => { "!ok1", "ok2", "!ok3", "ok4", "!ok5", "ok6", "!ok7" }; reports: DEBUG.ok1:: "1. pass"; DEBUG.ok2:: "2. pass"; DEBUG.ok3:: "3. pass"; DEBUG.ok4:: "4. pass"; DEBUG.ok5:: "5. pass"; DEBUG.ok6:: "6. pass"; DEBUG.ok7:: "7. pass"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/002.cf0000644000000000000000000000272315010704253023671 0ustar00rootroot00000000000000####################################################### # # Test islessthan() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok1" expression => islessthan("0", "1"); "ok2" expression => islessthan("1", "2.7e3"); "ok3" expression => islessthan("1.1", "2"); "ok4" expression => islessthan("2.7e3", "1e9"); "ok5" expression => islessthan("2z", "3b"); "ok6" expression => islessthan("alpha", "beta"); "ok7" expression => islessthan("", "beta"); "ok8" expression => islessthan("-75", "beta"); "ok9" expression => islessthan("", "3"); "ok" and => { ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8, ok9 }; reports: DEBUG.ok1:: "ok1"; DEBUG.ok2:: "ok2"; DEBUG.ok3:: "ok3"; DEBUG.ok4:: "ok4"; DEBUG.ok5:: "ok5"; DEBUG.ok6:: "ok6"; DEBUG.ok7:: "ok7"; DEBUG.ok8:: "ok8"; DEBUG.ok9:: "ok9"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/013.cf0000644000000000000000000000141415010704253023667 0ustar00rootroot00000000000000####################################################### # # Test isplain() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" not => isplain("/xxgobbleroot"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/isipinsubnet.cf.expected.json0000644000000000000000000000013115010704253030643 0ustar00rootroot00000000000000{ "found": [ "two_ips_match", "exact_ip_match", "zeroes_range_match" ] } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/splayclass_hourly.cf0000644000000000000000000000370315010704253027147 0ustar00rootroot00000000000000# Test that hourly splay class works as expected body common control { inputs => { "../../default.cf.sub" }; version => "1.0"; } bundle agent main { meta: "test_suppress_fail" string => "!any", meta => { "zendesk2548" }; vars: "hourly[Min00_05]" string => "1"; "hourly[Min05_10]" string => "2"; "hourly[Min10_15]" string => "3"; "hourly[Min15_20]" string => "14"; "hourly[Min20_25]" string => "23"; "hourly[Min25_30]" string => "4"; "hourly[Min30_35]" string => "12"; "hourly[Min35_40]" string => "13"; "hourly[Min40_45]" string => "6"; "hourly[Min45_50]" string => "7"; "hourly[Min50_55]" string => "10"; "hourly[Min55_00]" string => "24"; "hourly_idx" slist => getindices(hourly); "hourly_inputs" slist => getvalues(hourly); "splay_classes" slist => classesmatching("splayclass_hourly_.*"); classes: "splayclass_hourly_$(hourly_inputs)" expression => splayclass( $(hourly_inputs), hourly); "ok" and => { "$(hourly_idx)", "splayclass_hourly_$(hourly[$(hourly_idx)])"}; reports: DEBUG:: # Show the current time window "DEBUG $(this.bundle): Current time window '$(hourly_idx)'" if => "$(hourly_idx)"; # Show the currently defined splay class (found with classesmatching) "DEBUG $(this.bundle): Defined splay class '$(splay_classes)'"; # Show the class expression that is satisfied "DEBUG $(this.bundle): $(hourly_idx).splayclass_hourly_$(hourly[$(hourly_idx)])" if => and("$(hourly_idx)", "splayclass_hourly_$(hourly[$(hourly_idx)])"); # Show the time with the splay class defined "DEBUG $(this.bundle): $(sys.date) splayclass_hourly_$(hourly_inputs) defined" if => "splayclass_hourly_$(hourly_inputs)"; ok:: # We pass when the splay class is defined during the expected window "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/staging/0000755000000000000000000000000015010704253024506 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/02_functions/staging/017.cf0000644000000000000000000000265115010704253025333 0ustar00rootroot00000000000000####################################################### # # Test select_class - partial test only, hard to prove persistence # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "sel1" select_class => { "one" }; "sel2" select_class => { "alpha", "beta" }; "sel3" select_class => { "able", "baker", "charlie" }; "sel4" select_class => { "foo", "baz", "gar", "bletch" }; "ok2" xor => { "alpha", "beta" }; "ok3" xor => { "able", "baker", "charlie" }; "ok4" xor => { "foo", "baz", "gar", "bletch" }; "ok" and => { "sel1", "one", "sel2", "xor2", "sel3", "xor3", "sel4", "xor4", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { vars: "dummy" string => "dummy"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/staging/usemodule.cf0000644000000000000000000000644115010704253027027 0ustar00rootroot00000000000000####################################################### # # Test usemodule() # ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "script_location" string => dirname("$(this.promise_filename)"); classes: "ok_to_run" not => regcmp("/var/cfengine|.*\.cf-agent", "$(sys.workdir)"); files: ok_to_run:: "$(sys.workdir)/modules/usemodule.cf.bat" create => "true", perms => usemodule_perms, edit_line => usemodule_lines; "$(sys.workdir)/modules/usemodule-neg.cf.bat" create => "true", perms => usemodule_perms, edit_line => usemodule_lines_neg; } bundle edit_line usemodule_lines_neg { insert_lines: !windows:: "#!/bin/sh"; ". \"$(init.script_location)/usemodule.cf.bat\""; "exit 1"; delete_lines: ".*"; } bundle edit_line usemodule_lines { insert_lines: windows:: "@echo off"; "\"$(init.script_location)\usemodule.cf.bat\""; !windows:: "#!/bin/sh"; ". \"$(init.script_location)/usemodule.cf.bat\""; delete_lines: ".*"; } body perms usemodule_perms { mode => "755"; } ####################################################### bundle agent test { classes: "ok_to_run" not => regcmp("/var/cfengine|.*\.cf-agent", "$(sys.workdir)"); classes: ok_to_run:: # Should be undefined by the following script. "undefined_class" expression => "any"; "function_ok" expression => usemodule("usemodule.cf.bat", ""); "function_neg_ok" comment => "Negative test. Class set if module returns non-zero", not => usemodule("usemodule-neg.cf.bat", ""); "defined_variable" expression => strcmp("$(usemodule_cf_bat.defined_variable)", "yes"); "ok" and => { "function_neg_ok", "function_ok", "defined_class", "!undefined_class", "defined_variable" }; vars: ok:: "ok" string => "yes"; reports: !ok_to_run:: "Must be run using testall script"; ok_to_run.DEBUG.!function_ok:: "usemodule did not execute correctly."; ok_to_run.DEBUG.!function_neg_ok:: "usemodule returned non-zero, class function_neg_ok was not set, but should be set."; ok_to_run.DEBUG.!defined_class:: "defined_class was not set, but should be."; ok_to_run.DEBUG.undefined_class:: "undefined_class was set, but shouldn't be."; ok_to_run.DEBUG.!defined_variable:: "defined_variable was not set, but should be."; ok_to_run.DEBUG.function_ok:: "usemodule executed correctly."; ok_to_run.DEBUG.function_neg_ok:: "usemodule returned non-zero and class function_neg_ok was set."; ok_to_run.DEBUG.defined_class:: "defined_class was set."; ok_to_run.DEBUG.!undefined_class:: "undefined_class was not set."; ok_to_run.DEBUG.defined_variable:: "defined_variable was set."; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("$(test.ok)", "yes"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/02_functions/020.cf0000644000000000000000000000253515010704253023672 0ustar00rootroot00000000000000####################################################### # # Test fileexists() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "f1" string => "$(G.etc_passwd)"; "f2" string => "$(G.etc_group)"; "f3" string => "/etc/NoFriggin'WayThisExi5ts"; } ####################################################### bundle agent check { classes: "ok1" expression => fileexists("$(test.f1)"); "ok2" expression => fileexists("$(test.f2)"); "ok3" not => fileexists("$(test.f3)"); "ok" and => { "ok1", "ok2", "ok3" }; reports: DEBUG.ok1:: "File $(test.f1) exists as expected"; DEBUG.!ok1:: "File $(test.f1) DOES NOT exist (and should)"; DEBUG.ok2:: "File $(test.f2) exists as expected"; DEBUG.!ok2:: "File $(test.f2) DOES NOT exist (and should)"; DEBUG.ok3:: "File $(test.f3) does not exist as expected"; DEBUG.!ok3:: "File $(test.f3) DOES exist (and shouldn't)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/0000755000000000000000000000000015010704253022122 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basic/persistent_tags.cf.sub0000644000000000000000000000030715010704253026442 0ustar00rootroot00000000000000body common control { bundlesequence => { run }; } bundle common run { classes: "myclass" expression => "any", meta => { "specialtag" }, persistence => "120"; # 2 hours. } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/001.cf0000644000000000000000000000140315010704253022732 0ustar00rootroot00000000000000####################################################### # # Test not # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" not => "class_never_defined"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/invalid_function_in_list.cf0000644000000000000000000000063315010704253027512 0ustar00rootroot00000000000000# Testcase for Redmine 6569 body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { classes: "PASS" or => { "any", classify( "${never}" ) }; reports: PASS:: "$(this.promise_filename) Pass"; !PASS:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/depends_on_proper_ordering.cf0000644000000000000000000000201115010704253030024 0ustar00rootroot00000000000000# Redmine#5462 # Redmine#6484 body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "states" slist => { "actual", "expected" }; "expected_content" string => "second_line first_line"; files: "$(G.testfile).expected" create => "true", edit_line => test_insert("$(expected_content)"); "$(G.testfile).actual" create => "true", edit_line => test_insert("first_line"), depends_on => { "insert_second_line" }; "$(G.testfile).actual" create => "true", edit_line => test_insert("second_line"), handle => "insert_second_line"; } bundle edit_line test_insert(str) { insert_lines: "$(str)"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/026.cf0000644000000000000000000000160015010704253022740 0ustar00rootroot00000000000000####################################################### # # Check if with qualified variable # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { classes: "classtotest" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "foobar" string => "classtotest"; } ####################################################### bundle agent check { classes: "ok" expression => "any", if => "$(test.foobar)"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/019.cf0000644000000000000000000000153215010704253022746 0ustar00rootroot00000000000000####################################################### # # Test brackets on "xor" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { userexists("root") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/016.cf0000644000000000000000000000151015010704253022737 0ustar00rootroot00000000000000####################################################### # # Test xor # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { "any", "any", "any", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/ipaddr_classes.cf0000644000000000000000000000124515010704253025416 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { vars: "ipv6_classes" slist => classesmatching("ipv6_.*"); classes: "has_ipv6" expression => returnszero("ifconfig -a | grep 'inet6 [a-z0-9].*'", "useshell"); has_ipv6:: "ok" expression => some(".*", "ipv6_classes"); !has_ipv6:: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "ipv6_classes: $(ipv6_classes)"; DEBUG.has_ipv6:: "Has IPv6"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/022.x.cf0000644000000000000000000000146215010704253023210 0ustar00rootroot00000000000000####################################################### # # Test syntactically errorneous class expression # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: !.!:: "undererror" string => "undererror"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/119.x.cf0000644000000000000000000000144415010704253023217 0ustar00rootroot00000000000000####################################################### # # Test no brackets on "xor" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => userexists("root"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/classes_without_expression.cf0000644000000000000000000000144015010704253030132 0ustar00rootroot00000000000000####################################################### # # test that classes without expressions are defined # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { classes: "myclass1"; "myclass2" meta => { "good" }; "myclass3" persistence => "120"; "myclass4" meta => { "good" }, persistence => "120"; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_expected("myclass1,myclass2,myclass3,myclass4", "", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/common_bundle_select_class_single_class.cf0000644000000000000000000000124115010704253032525 0ustar00rootroot00000000000000# Test that select class is actuated when it has only a single class given body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { vars: any:: "common_classes" slist => { }; common_class_selected:: "class_selected" string => "$(common_classes)", if => "$(common_classes)"; classes: "common_class_selected" select_class => { "common_1" }; } bundle agent check { methods: "any" usebundle => dcs_passif("common_1", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/common_class_scope.cf0000644000000000000000000000233215010704253026302 0ustar00rootroot00000000000000####################################################### # # Check that we can use scope attributes to promise global classes # from common bundles # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "classes" slist => { "global_c", "local_c", "unglobal_c", "unlocal_c" }; } bundle common test { classes: "global_c" expression => "any"; "unglobal_c" expression => "!any"; "local_c" expression => "any", scope => "bundle"; "unlocal_c" expression => "!any", scope => "bundle"; reports: DEBUG:: "$(init.classes) defined from test" if => "${init.classes}"; "$(init.classes) not defined from test" if => "!${init.classes}"; } bundle agent check { classes: global_c.!local_c.!unglobal_c.!unlocal_c:: "ok" expression => "any"; reports: DEBUG:: "$(init.classes) defined from check" if => "${init.classes}"; "$(init.classes) not defined from check" if => "!${init.classes}"; ok:: "${this.promise_filename} Pass"; !ok:: "${this.promise_filename} FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/040.cf0000644000000000000000000000164315010704253022743 0ustar00rootroot00000000000000####################################################### # # Check that countclassesmatching() works # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "num" int => countclassesmatching("any"); classes: # One and only one match "ok" and => { isgreaterthan("$(num)", "0"), islessthan("$(num)", "2") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/008.cf0000644000000000000000000000155315010704253022747 0ustar00rootroot00000000000000####################################################### # # Test or # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "not_ok" or => { "this_was_not_defined", "neither_was_this", }; "ok" not => "ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/persistent_negate.cf0000644000000000000000000000244515010704253026164 0ustar00rootroot00000000000000####################################################### # # ENT-5886 -- -N/--negate should prevent persistent classes from being defined # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dflags" string => ifelse("EXTRA", "-DDEBUG,EXTRA", "-DDEBUG"); } bundle agent test { meta: "description" -> {"ENT-5886"} string => "-N/--negate should prevent persistent classes from being defined"; commands: "$(sys.cf_agent) -K $(init.dflags) -f $(this.promise_filename).sub" classes => test_always("done_persisting"); } body classes test_always(x) { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } bundle agent check { vars: done_persisting:: "subout" string => execresult("$(sys.cf_agent) -N test_class -K $(init.dflags) -f $(this.promise_filename).sub2", "noshell"); methods: "" usebundle => dcs_check_strcmp($(subout), "R: Pass", $(this.promise_filename), "no"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/persistent_negate.cf.sub0000644000000000000000000000026415010704253026751 0ustar00rootroot00000000000000body common control { bundlesequence => { run }; } bundle common run { classes: "test_class" expression => "any", persistence => "120"; # 2 hours. } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/hp_ux_major.cf0000644000000000000000000000174515010704253024756 0ustar00rootroot00000000000000body common control { bundlesequence => { "test", "check" }; } bundle agent test { meta: "description" -> { "CFE-3609" } string => "Make sure the class 'hpux_' is defined on HP-UX"; vars: DEBUG:: "defined_classes" string => join("$(const.n)", classesmatching(".*")); } bundle agent check { classes: # if 'hpux': make sure 'hpux_10' or 'hpux_11' is defined hpux:: "passed" expression => "hpux_10|hpux_11"; # if not 'hpux': make sure neither 'hpux_10' nor 'hpux_11' is defined !hpux:: "passed" expression => "!(hpux_10|hpux_11)"; reports: DEBUG&hpux&!passed:: "No class containing OS- name & version major is defined on HP-UX."; "Here is a list of defined classes:"; "$(test.defined_classes)"; DEBUG&!hpux&!passed:: "A class containing 'hpux_' was defined on a non HP-UX system"; passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/010.cf0000644000000000000000000000146015010704253022735 0ustar00rootroot00000000000000####################################################### # # Test or # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" or => { "cfengine_3", "any", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } common_bundle_select_class_single_class_as_variable.cf0000644000000000000000000000127415010704253035004 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basic# Test that select class is actuated when it has only a single class given as a # variable body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { vars: any:: "common_class" string => "common_1"; common_class_selected:: "class_selected" string => "$(common_classes)", if => "$(common_classes)"; classes: "common_class_selected" select_class => { $(common_class) }; } bundle agent check { methods: "any" usebundle => dcs_passif("common_1", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/030.cf.namespaced.sub0000644000000000000000000000067015010704253025630 0ustar00rootroot00000000000000body file control { namespace => "test_namespace"; } bundle agent classchecker { classes: "noedit_$(cindex[$(key)])" expression => strcmp("x","dontchange"); vars: "key" string => "1 2 3"; "cindex[$(key)]" string => canonify("$(key)"); # "var1" string => "data1", # ifvarclass => "noedit_$(cindex[$(key)])"; "var1" string => "data1", ifvarclass => "!noedit_$(cindex[$(key)])"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/classes_comments_emitted_in_show_classes.cf.sub0000644000000000000000000000024015010704253033540 0ustar00rootroot00000000000000bundle agent main { classes: "test_class" expression => "any", comment => "This is a comment about test_class", scope => "namespace"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/017.cf0000644000000000000000000000153315010704253022745 0ustar00rootroot00000000000000####################################################### # # Test brackets on "and" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" and => { userexists("root") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/012.cf0000644000000000000000000000151115010704253022734 0ustar00rootroot00000000000000####################################################### # # Test xor # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "not_ok" xor => { "this_was_not_defined", "neither_was_this", }; "ok" not => "not_ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/classes_comments_emitted_in_show_classes.cf0000644000000000000000000000140315010704253032752 0ustar00rootroot00000000000000# Test $(sys.inputdir), $(sys.masterdir), $(sys.libdir), $(sys.bindir), $(sys.failsafe_policy_path), $(sys.update_policy_path), $(sys.local_libdir) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent test { meta: "description" string => "Test that comments on classes are emitted in --show-evaluated-classes output."; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*test_class.*This is a comment about test_class.*", "", "$(sys.cf_agent) -Kf $(this.promise_filename).sub --show-evaluated-classes", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/simplistic_ipaddr_classes.cf0000644000000000000000000000174615010704253027664 0ustar00rootroot00000000000000############################################################################## # # Test that simplistic IP-address classes are set (e.g., 192_168_56_10) # ############################################################################## body common control { bundlesequence => { "test", "check" }; version => "1.0"; } ############################################################################## bundle agent test { meta: "description" -> { "ENT-2044" } string => "Test that simplistic IP classes are set"; vars: "ip_classes" slist => maplist(canonify("$(this)"), "@(sys.ip_addresses)"); } ############################################################################## bundle agent check { classes: "ok" and => { "@(test.ip_classes)" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "IP Classes: $(with)" with => join(", ", "test.ip_classes"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/109.cf.sub0000644000000000000000000000120715010704253023535 0ustar00rootroot00000000000000body file control { namespace => "ns109"; } bundle agent pass() { classes: "shred" expression => "default:shared_class"; vars: "shared_dependent" string => "works", ifvarclass => "default:shared_class"; shred:: "forced_dependent" string => "works"; reports: DEBUG:: "Does the shared class work in a variable? Is '$(shared_dependent)' == 'works'?"; "Does the shared class work explicitly? Is '$(forced_dependent)' == 'works'?"; "The shared class claims to work." ifvarclass => "$(class_needed)"; "The shared class does not work" ifvarclass => "!$(class_needed)"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/011.cf0000644000000000000000000000146215010704253022740 0ustar00rootroot00000000000000####################################################### # # Test xor # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "not_ok" xor => { "cfengine_3", "any", }; "ok" not => "not_ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/007.cf0000644000000000000000000000147715010704253022753 0ustar00rootroot00000000000000####################################################### # # Test or # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "not_ok" or => { "this_was_not_defined" }; "ok" not => "ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/031.cf0000644000000000000000000000246115010704253022742 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "031.cf.namespaced.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle common globalclasses { classes: "GLOBALCLASS" expression => "any"; } bundle agent test { methods: "globals" usebundle => globalclasses; "call" usebundle => test_namespace:classchecker; } ####################################################### bundle agent check { classes: "ok1" expression => strcmp("$(test_namespace:classchecker.var1)", "data1"); "ok2" expression => strcmp("$(test_namespace:classchecker.var2)", "data2"); "ok3" expression => strcmp("$(test_namespace:classchecker.var3)", "data3"); any:: "ok" and => { "ok1", "ok2", "ok3" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; !ok1||DEBUG:: "Expected data1, got $(test_namespace:classchecker.var1)"; !ok2||DEBUG:: "Expected data2, got $(test_namespace:classchecker.var2)"; !ok3||DEBUG:: "Expected data3, got $(test_namespace:classchecker.var3)"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/030.cf0000644000000000000000000000157315010704253022744 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "030.cf.namespaced.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; methods: "call" usebundle => test_namespace:classchecker; } ####################################################### bundle agent check { classes: "ok1" expression => strcmp("$(test_namespace:classchecker.var1)", "data1"); any:: "ok" and => { "ok1" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "Expected data1, got $(test_namespace:classchecker.var1)"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/020.x.cf0000644000000000000000000000141115010704253023200 0ustar00rootroot00000000000000####################################################### # # Test brackets on "expression" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" expression => { userexists("root"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/042.cf0000644000000000000000000000220315010704253022736 0ustar00rootroot00000000000000####################################################### # # Check that weekday classes make sense # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: # Only one of these should be set at a time "num" int => countclassesmatching("(Min00_05|Min05_10|Min10_15|Min15_20|Min20_25|Min25_30|Min30_35|Min35_40|Min40_45|Min45_50|Min50_55|Min55_00)"); classes: # One and only one match "ok" and => { isgreaterthan("$(num)", "0"), islessthan("$(num)", "2") }; reports: cfengine:: "Found $(num) matches when there should be 1"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/cancel_hardclass.cf0000644000000000000000000000156315010704253025712 0ustar00rootroot00000000000000############################################################################# # # Test that undefining hardclasses is not be permitted. # ############################################################################# body common control { bundlesequence => { "init", "test", "check" }; } bundle agent init { } body classes undefine(class) { cancel_kept => { "$(class)" }; cancel_repaired => { "$(class)" }; cancel_notkept => { "$(class)" }; } bundle agent test { meta: "description" -> { "ENT-7718" } string => "Test that undefining hardclasses is not be permitted."; commands: "/bin/true" classes => undefine("cfengine"); } bundle agent check { classes: "passed" expression => "cfengine"; reports: passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/rbtree_collisions-redmine7912.cf0000644000000000000000000000270515010704253030125 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "legumes" expression => "any"; "kumiss" expression => "any"; "range_class_prod_ltx1_seas_groupdiscussions_indexer_4_PRODUCTVERSION__0_1_86_" expression => "any"; "right_classes_set" expression => "legumes.kumiss.range_class_prod_ltx1_seas_groupdiscussions_indexer_4_PRODUCTVERSION__0_1_86_"; "wrong_classes_set" expression => "goosey|ungoverned|ipv4_10_132_60"; "ok" expression => "right_classes_set.!wrong_classes_set"; reports: DEBUG.legumes:: "Pass legumes"; DEBUG.goosey:: "FAIL goosey"; DEBUG.kumiss:: "Pass kumiss"; DEBUG.ungoverned:: "FAIL ungoverned"; DEBUG.range_class_prod_ltx1_seas_groupdiscussions_indexer_4_PRODUCTVERSION__0_1_86_:: "PASS range_class_prod_ltx1_seas_groupdiscussions_indexer_4_PRODUCTVERSION__0_1_86_"; DEBUG.ipv4_10_132_60:: "FAIL ipv4_10_132_60"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/025.cf0000644000000000000000000000163615010704253022750 0ustar00rootroot00000000000000####################################################### # # Check if with array # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { classes: "classtotest" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "foobar[0]" string => "classtotest"; classes: "ok" expression => "any", if => "$(foobar[0])"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/023.cf0000644000000000000000000000171415010704253022743 0ustar00rootroot00000000000000####################################################### # # Test complex expression (issue 487) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "class1" expression => "any"; "class2" expression => "any"; "class3" expression => "any"; "class4" expression => "any"; class1.(class2|(class3.class4)):: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/003.cf0000644000000000000000000000143015010704253022734 0ustar00rootroot00000000000000####################################################### # # Test and # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" and => { "cfengine_3" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/array_key_with_space_isvariable.cf0000644000000000000000000000174015010704253031033 0ustar00rootroot00000000000000# isvariable should be able to check array indexes that have spaces body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "array[one]" string => "1"; "array[twenty one]" string => "21"; classes: "have_one" expression => isvariable("array[one]"), scope => "namespace"; "have_twenty_one" expression => isvariable("array[twenty one]"), scope => "namespace"; reports: have_one.DEBUG:: "Have array key 'one' as expected containing value '$(array[one])'"; have_twenty_one.DEBUG:: "Have array key 'twenty one' as expected containing value '$(array[twenty one])'"; } bundle agent check { methods: have_one.have_twenty_one:: "result" usebundle => dcs_pass("$(this.promise_filename)"); !(have_one.have_twenty_one):: "result" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/from_json_booleans.cf.expected.json0000644000000000000000000000025215010704253031061 0ustar00rootroot00000000000000{ "collected": [ "canary", "from_true" ], "json": { "maybe": null, "no": false, "yes": true }, "var_false": "false", "var_true": "true" } classes_from_modules_available_to_subsequent_bundles_in_first_pass.cf0000644000000000000000000000153415010704253040207 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basic####################################################### # # Redmine#6689 - Should be able to use negative expression on class defined # from module protocol right away # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine#6689", "zendesk#1548" }; methods: "" usebundle => dcs_passif_output("should be set", "should not be set", "$(sys.cf_agent) -KI -f $(this.promise_filename).sub", $(this.promise_filename)); } if_resolving_classexpression_from_datacontainer.cf0000644000000000000000000000313115010704253034265 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basicbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3319" } string => "Test that if/ifvarclass can check class expressions from within a data container"; vars: "d" data => '{ "things": [ { "Title": "NOPE", "classexpr": "Something_that_wont_match" }, { "Title": "ExpectedPick", "classexpr": "$(sys.class)" }, { "Title": "AlsoNOPE", "classexpr": "AnotherSomething_that_wont_match" } ] }'; "di" slist => getindices( "d[things]" ); "selected" string => "$(d[things][$(di)][Title])", if => "$(d[things][$(di)][classexpr])"; "sanity_check" string => "You are sane", if => "$(sys.class)"; reports: EXTRA|DEBUG:: "See iteration/expansion: $(d[things][$(di)][Title]) has classexpr $(d[things][$(di)][classexpr])"; "See sanity_check: $(sanity_check) because $(sys.class) is a defined class"; "Picked: $(d[things][$(di)][Title]) has classexpr $(d[things][$(di)][classexpr])" if => "$(d[things][$(di)][classexpr])"; } ####################################################### bundle agent check { vars: "expected_selection" string => "ExpectedPick"; methods: "Pass/Fail" usebundle => dcs_check_strcmp($(expected_selection), $(test.selected), $(this.promise_filename), "no"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/004.cf0000644000000000000000000000146315010704253022743 0ustar00rootroot00000000000000####################################################### # # Test and # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" and => { "any", "cfengine_3" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/117.x.cf0000644000000000000000000000144415010704253023215 0ustar00rootroot00000000000000####################################################### # # Test no brackets on "and" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" and => userexists("root"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/005.cf0000644000000000000000000000151015010704253022735 0ustar00rootroot00000000000000####################################################### # # Test and # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "not_ok" and => { "any", "cfengine_3", "this_was_not_defined" }; "ok" not => "ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/041.cf0000644000000000000000000000212515010704253022740 0ustar00rootroot00000000000000####################################################### # # Check that weekday classes make sense # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: # Only one of these should be set at a time "num" int => countclassesmatching("(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)"); classes: # One and only one match "ok" and => { isgreaterthan("$(num)", "0"), islessthan("$(num)", "2") }; reports: cfengine:: "Found val $(num) matches when there should be 1"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/015.cf0000644000000000000000000000151215010704253022740 0ustar00rootroot00000000000000####################################################### # # Test xor # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { "!any", "!any", "any", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/classes_promises_with_classes_bodies.cf0000644000000000000000000000161715010704253032114 0ustar00rootroot00000000000000####################################################### # # Classes type promises should work with classes bodies # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine#7537" }; vars: "classes" slist => classesmatching("checked_for_file.*"); classes: "have_file" expression => isplain("$(this.promise_filename)"), classes => scoped_classes_generic("bundle", "checked_for_file"); methods: "pass or fail" usebundle => dcs_passif("checked_for_file_reached", $(this.promise_filename)); reports: DEBUG|EXTRA:: "Found class: $(classes)"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/031.cf.namespaced.sub0000644000000000000000000000071615010704253025632 0ustar00rootroot00000000000000body file control { namespace => "test_namespace"; } bundle agent classchecker { classes: "localclass1" and => { "default:GLOBALCLASS" }; "localclass2" or => { "default:GLOBALCLASS" }; "localclass3" and => { "default:$(classname)" }; vars: "classname" string => "GLOBALCLASS"; localclass1:: "var1" string => "data1"; localclass2:: "var2" string => "data2"; localclass3:: "var3" string => "data3"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/classes_comments_emitted_in_verbose.cf0000644000000000000000000000137015010704253031725 0ustar00rootroot00000000000000# Test $(sys.inputdir), $(sys.masterdir), $(sys.libdir), $(sys.bindir), $(sys.failsafe_policy_path), $(sys.update_policy_path), $(sys.local_libdir) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent test { meta: "description" string => "Test that comments on classes are emitted in verbose output.", meta => { "CFE-2443" }; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*This is a comment about test_class.*", "", "$(sys.cf_agent) -Kvf $(this.promise_filename).sub", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/006.cf0000644000000000000000000000145515010704253022746 0ustar00rootroot00000000000000####################################################### # # Test and # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "not_ok" and => { "this_was_not_defined" }; "ok" not => "ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/027.c0000644000000000000000000000247115010704253022602 0ustar00rootroot00000000000000#include #include #include #define SPLAY_PSEUDO_RANDOM_CONSTANT 8192 #define HOURLY 12 main() { char s[] = "a"; char c; int hash, box, minblocks; int period = HOURLY - 1; char *boxes[HOURLY]; for (c = 0; c < HOURLY; c++) { boxes[c] = 0; } for (c = 'a'; c <= 'z'; c++) { *s = c; // The block algorithm is copied from evalfunction.c hash = OatHash(s); box = (int) (0.5 + period * hash / (double) SPLAY_PSEUDO_RANDOM_CONSTANT); minblocks = box % HOURLY; // Back to original code if (!boxes[minblocks]) { boxes[minblocks] = strncpy((char *) malloc(2), s, 2); } } printf(" \"ok\" xor => {\n"); for (c = 0; c < HOURLY; c++) { printf("\tsplayclass(\"%s\",\"hourly\"), # Box %d\n", boxes[c], c); } printf("\t};\n"); } // This is copied from files_hashes.c int OatHash(char *key) { unsigned int hashtablesize = SPLAY_PSEUDO_RANDOM_CONSTANT; unsigned char *p = key; unsigned h = 0; int i, len = strlen(key); for (i = 0; i < len; i++) { h += p[i]; h += (h << 10); h ^= (h >> 6); } h += (h << 3); h ^= (h >> 11); h += (h << 15); return (h & (hashtablesize - 1)); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/009.cf0000644000000000000000000000155015010704253022745 0ustar00rootroot00000000000000####################################################### # # Test or # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" or => { "this_was_not_defined", "cfengine_3", "neither_was_this", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/avoid_reevaluation.cf0000644000000000000000000000135315010704253026316 0ustar00rootroot00000000000000####################################################### # # Redmine#5241: do not reevaluate classes if they are known already # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*", ".*loquacious quaalude.*|.*/etc/debian_version.*", "$(sys.cf_agent) -KI -f $(this.promise_filename).sub -Dloquacious", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/ifvarclass_common_bundles.cf0000644000000000000000000000217215010704253027657 0ustar00rootroot00000000000000####################################################### # # Check that we can use ifvarclass in common bundle class expressions # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common init { classes: "initclass" expression => "any"; } ####################################################### bundle common test { classes: "shouldset" expression => "any", ifvarclass => "initclass"; "shouldnot" expression => "any", ifvarclass => "notaclass"; } ####################################################### bundle agent check { vars: "classes" slist => { "shouldset", "shouldnot" }; classes: shouldset.!shouldnot:: "ok" expression => "any"; reports: DEBUG:: "$(classes) is set" ifvarclass => "$(classes)"; "$(classes) is not" ifvarclass => "!$(classes)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/024.cf0000644000000000000000000000171215010704253022742 0ustar00rootroot00000000000000####################################################### # # Test complex expression (issue 487) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "class1" expression => "any"; "class2" expression => "any"; "class3" expression => "any"; "class4" expression => "any"; class1.(class2|class3.class4):: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/from_json_booleans.cf0000644000000000000000000000230515010704253026312 0ustar00rootroot00000000000000########################################################### # # Test expansion of JSON booleans # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { classes: "canary" expression => "any", meta => { "collect" }; # just a baseline test "from_$(json)" expression => "$(json)", meta => { "collect" }; # iterates through non-nulls "from_null" expression => "$(json[maybe])", meta => { "collect" }; "from_missing" expression => "$(json[nonesuch])", meta => { "collect" }; vars: "json" data => '{ "yes": true, "no": false, "maybe": null }'; "var_$(json)" string => "$(json)"; "collected" slist => sort(classesmatching(".*", "collect")); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/persistent_tags.cf.sub20000644000000000000000000000252115010704253026524 0ustar00rootroot00000000000000body common control { bundlesequence => { run }; } bundle agent run { vars: "tagged" slist => classesmatching("myclass"); "unsorted_tags_$(tagged)" slist => getclassmetatags($(tagged)); "tags_$(tagged)" slist => sort("unsorted_tags_$(tagged)", "lex"); "tagged_str" string => format("%S", tagged); "tags_$(tagged)_str" string => format("%S", "tags_$(tagged)"); "expected_classes" string => '{ "myclass" }'; "expected_tags" string => '{ "source=persistent", "source=promise", "specialtag" }'; classes: "ok_class" expression => strcmp($(tagged_str), $(expected_classes)); "ok_tags" expression => strcmp($(tags_myclass_str), $(expected_tags)); "ok" and => { "ok_class", "ok_tags" }; reports: !ok_class.DEBUG:: "The list of tagged classes '$(tagged_str)' did NOT match the expected '$(expected_classes)'"; !ok_tags.DEBUG:: "The list of tags '$(tags_myclass_str)' did NOT match the expected '$(expected_tags)'"; ok_class.EXTRA:: "The list of tagged classes '$(tagged_str)' matched the expected '$(expected_classes)'"; ok_tags.EXTRA:: "The list of tags '$(tags_myclass_str)' matched the expected '$(expected_tags)'"; ok:: "${this.promise_dirname}/persistent_tags.cf Pass"; !ok:: "${this.promise_dirname}/persistent_tags.cf FAIL"; } classes_from_modules_available_to_subsequent_bundles_in_first_pass.cf.sub0000644000000000000000000000275015010704253041000 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basic#!/var/cfengine/bin/cf-agent -Kf body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "main"}; } bundle agent main { methods: "any" usebundle => module_stub; "any" usebundle => test_bundle; } bundle agent module_stub { commands: any:: "$(G.echo) +test_class" comment => "Setting test_class", module => "true" ; } bundle agent test_bundle { vars: # because this bundle runs after the module, I would expect both # of these class statements to be false (and the vars not set). # In practice, $(bogus_first) seems to somehow get set before # the module runs, and $(bogus_second) - which is forced to run # in the second pass of this bundle, is not set, which is correct. !test_class:: "bogus_first" string => "should not be set", comment => "because module_stub was activated and test_class was defined *BEFORE* $(this.bundle) was activated"; secondpass.!test_class:: "bogus_second" string => "should not be set", comment => "because even when its the second pass, test_class was already defined."; !secondpass.test_class:: "good_first" string => "should be set"; classes: "secondpass" expression => "any"; reports: # I would expect *neither* of these vars to be defined "Value of bogus_first is: $(bogus_first)"; "Value of bogus_second is: $(bogus_second)"; "Value of good_first is: $(good_first)"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/014.cf0000644000000000000000000000146515010704253022746 0ustar00rootroot00000000000000####################################################### # # Test xor # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { "cfengine_3", "!any", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/action_policy_warn_sets_classes.cf0000644000000000000000000000306415010704253031075 0ustar00rootroot00000000000000####################################################### # # Test not # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { files: "/tmp/dont_create_me" create => 'true', classes => classes_generic( "test_files" ), action => warnonly; commands: "$(G.echo) 'dont_print_me'" classes => classes_generic( "test_commands" ), action => warnonly; processes: "cf-agent-x" restart_class => "restart_cf_agent", classes => classes_generic( "test_processes" ), action => warnonly; reports: "Test output" classes => classes_generic("test_reports"), action => warnonly; } body action warnonly { action_policy => "warn"; } ####################################################### bundle agent check { vars: "classes" slist => classesmatching( "test_.*" ); classes: "ok" and => { "test_files_not_kept", "test_commands_not_kept", "test_processes_not_kept", "test_reports_not_kept" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; debug:: "$(classes)"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/032.cf0000644000000000000000000000217715010704253022747 0ustar00rootroot00000000000000# # Test whether classes defined by promises end up in right namespace # body common control { inputs => { "../../default.cf.sub", "031.cf.namespaced.sub", "032.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { methods: "call" usebundle => xxx:localclass; reports: cfengine:: "testing class 1" classes => xxx:always("another_class_global_from_command"); } ####################################################### bundle agent check { classes: "ok" and => { "xxx:a_class_global_from_command", "default:another_class_global_from_command" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "xxx:a_class_global_from_command is set" if => "xxx:a_class_global_from_command"; DEBUG.another_class_global_from_command:: "another_class_global_from_command is set"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/depends_on_respected.cf0000644000000000000000000000714115010704253026613 0ustar00rootroot00000000000000# Redmine#5462 # Redmine#6484 # respect depends_on restriction body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)_present_if_test_commands_false_considered_kept_or_repaired" delete => tidy; "$(G.testfile)_present_if_test_commands_echo_ran" delete => tidy; } bundle agent test { files: "$(G.testfile)_present_if_test_commands_false_considered_kept_or_repaired" create => "true", handle => "test_files", classes => scoped_classes_generic("namespace", "test_commands_files_testfile"), depends_on => { "test_commands_false", "test_commands_false2" }; commands: "$(G.false)" handle => "test_commands_false", classes => scoped_classes_generic("namespace", "test_commands_false"); "$(G.false)" handle => "test_commands_false2", classes => scoped_classes_generic("namespace", "test_commands_false2"); "$(G.true)" handle => "test_commands_true", classes => scoped_classes_generic("namespace", "test_commands_true"), depends_on => { "test_commands_false", "test_commands_false2" }; packages: "test_packages" package_method => mock, handle => "test_packages", classes => scoped_classes_generic("namespace", "test_packages"), depends_on => { "test_commands_false", "test_commands_false2" }; reports: "This promise '$(this.handle)' should have been skipped as the promise 'test_commands_false' should never be kept or repaired" handle => "test_reports", classes => scoped_classes_generic("namespace", "test_reports"), depends_on => { "test_commands_false", "test_commands_false2" }; } bundle agent check { vars: "fail_classes" slist => { "test_commands_true_reached", "test_files_reached", "test_reports_reached", "test_packages_reached", }; classes: "fail" or => { @(fail_classes) }; reports: DEBUG:: "'test_commands_false' was ok unexpectedly" if => "test_commands_false_ok"; "'test_commands_false' was kept unexpectedly" if => "test_commands_false_kept"; "'test_commands_false' was repaired unexpectedly" if => "test_commands_false_repaired"; "'test_commands_false' was not_ok as expected" if => "test_commands_false_not_ok"; "'test_commands_false2' was ok unexpectedly" if => "test_commands_false2_ok"; "'test_commands_false2' was kept unexpectedly" if => "test_commands_false2_kept"; "'test_commands_false2' was repaired unexpectedly" if => "test_commands_false2_repaired"; "'test_commands_false2' was not_ok as expected" if => "test_commands_false2_not_ok"; "'$(fail_classes)' erroneously thought 'test_commands_false' and or 'test_commands_false2' was ok aka (kept or repaired)." if => "$(fail_classes)"; fail:: "$(this.promise_filename) FAIL"; !fail:: "$(this.promise_filename) Pass"; } body package_method mock { package_changes => "individual"; package_list_command => "$(G.echo) --list-installed"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.echo) --add "; package_update_command => "$(G.echo) --update "; package_delete_command => "$(G.echo) --delete "; package_verify_command => "$(G.echo) --verify "; } common_bundle_select_class_variable_expands_empty_list.cf0000644000000000000000000000131115010704253035556 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basic# Test that select class is skipped when the list of classes is empty body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { vars: any:: "common_classes" slist => { }; common_class_selected:: "class_selected" string => "$(common_classes)", if => "$(common_classes)"; classes: "common_class_selected" select_class => { @(common_classes) }; } bundle agent check { methods: "any" usebundle => dcs_passif("any", "$(this.promise_filename)"), unless => "common_class_selected"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/021.x.cf0000644000000000000000000000137315010704253023210 0ustar00rootroot00000000000000####################################################### # # Test brackets on "not" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" not => { userexists("root"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/classes_comments_emitted_in_verbose.cf.sub0000644000000000000000000000020415010704253032510 0ustar00rootroot00000000000000bundle agent main { classes: "test_class" expression => "any", comment => "This is a comment about test_class"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/118.x.cf0000644000000000000000000000144215010704253023214 0ustar00rootroot00000000000000####################################################### # # Test no brackets on "or" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" or => userexists("root"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/agent_class_scope.cf0000644000000000000000000000233615010704253026114 0ustar00rootroot00000000000000####################################################### # # Check that we can use scope attributes to promise global classes # from agent bundles # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "classes" slist => { "global_c", "local_c", "unglobal_c", "unlocal_c" }; } bundle agent test { classes: "global_c" expression => "any", scope => "namespace"; "unglobal_c" expression => "!any", scope => "namespace"; "local_c" expression => "any"; "unlocal_c" expression => "!any"; reports: DEBUG:: "$(init.classes) defined from test" if => "${init.classes}"; "$(init.classes) not defined from test" if => "!${init.classes}"; } bundle agent check { classes: global_c.!local_c.!unglobal_c.!unlocal_c:: "ok" expression => "any"; reports: DEBUG:: "$(init.classes) defined from check" if => "${init.classes}"; "$(init.classes) not defined from check" if => "!${init.classes}"; ok:: "${this.promise_filename} Pass"; !ok:: "${this.promise_filename} FAIL"; } common_bundle_select_class_multiple_classes_as_scalar_variable.cf0000644000000000000000000000212315010704253037225 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basic# Test that select class is actuated when it has multiple classes given as a # variable body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { vars: any:: "common_classes" slist => { "common_1", "common_2" }; common_class_selected:: "class_selected" string => "$(common_classes)", if => "$(common_classes)"; classes: # When you iterate on a list using $() it should iterate in the order of # the list. So the first time this is actuated, the value of # $(common_classes) should be "common_1". "common_2" should never be # defined, because the promise will be skipped on subsequent passes since # the "common_class_selected" is already defined. "common_class_selected" select_class => { $(common_classes) }; } bundle agent check { methods: "any" usebundle => dcs_passif("common_1", "$(this.promise_filename)"), unless => "common_2"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/expected_os_classes.cf0000644000000000000000000000216115010704253026453 0ustar00rootroot00000000000000body common control { bundlesequence => { "test", "check" }; } bundle agent test { meta: "description" -> { "CFE-3608" } string => "Make sure at least one of the expected os hard classes are defined"; vars: DEBUG:: "defined_classes" string => join("$(const.n)", classesmatching(".*")); } bundle agent check { classes: "passed" or => { "debian", "ubuntu", "redhat", "centos", "fedora", "aix", "hpux", "suse", "opensuse", "archlinux", "windows", "freebsd", "macos", "solaris" }; reports: DEBUG&!passed:: "None of the expected classes were defined."; "Here is a list of defined classes:"; "$(test.defined_classes)"; passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/avoid_reevaluation.cf.sub0000644000000000000000000000054715010704253027112 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { run }; } bundle agent run { vars: "path" string => "/etc/debian_version"; classes: "loquacious" expression => returnszero("$(G.echo) loquacious quaalude", "noshell"); "$(path)" expression => returnszero("$(G.echo) redmine6561", "noshell"); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/common_bundle_select_class_empty_list.cf0000644000000000000000000000143515010704253032255 0ustar00rootroot00000000000000# Test that select_class is skipped when no classes are given body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { # meta: # "test_soft_fail" string => "any", # meta => { "redmine7482" }; vars: any:: "common_classes" slist => { "common_1", "common_2" }; common_class_selected:: "class_selected" string => "$(common_classes)", if => "$(common_classes)"; classes: "common_class_selected" select_class => { }; } bundle agent check { methods: "any" usebundle => dcs_passif("any", "$(this.promise_filename)"), unless => "common_class_selected"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/variable_class_expressions_with_if.cf0000644000000000000000000000501415010704253031561 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" string => "Test that variable class expressions and the if alias work together as expected.", meta => { "CFE-2615" }; vars: "x" string => "x"; classes: "DEBUG" expression => "any"; "one$(x)" expression => "any"; # These expressions are here purely for illustration. The classes two and # three are never set. "two" expression => "!any"; "three" expression => "!any"; # Here, after the variable class expression "one$(x)":: is where all of the # test cases are described. "one$(x)":: "FAIL_if" expression => "any", meta => { "failtest" }, if => "two|three", comment => "We expect the class 'onex' to be defined, but since neither 'two' nor 'three' are defined this class should not be set. This seems to have something to do with the combination of a variable class expression AND the use of the if attribute. Note, ifvarclass does not seem to be affected."; "FAIL_ifvarclass" expression => "any", meta => { "failtest" }, ifvarclass => "two|three"; "FAIL_if_or" expression => "any", meta => { "failtest" }, if => or("two", "three"); "FAIL_ifvarclass_or" expression => "any", meta => { "failtest" }, ifvarclass => or("two", "three"); "FAIL_unless" expression => "any", meta => { "failtest" }, unless => "!two.!three"; "FAIL_unless_not" expression => "any", meta => { "failtest" }, unless => not("two|three"); vars: "FAIL_classes" slist => classesmatching( ".*", "failtest" ); commands: "$(G.true)" handle => "delay", comment => "This is a benign promise that is used to delay detection of failure classes until after normal order begins."; classes: "no_FAIL_classes" expression => none(".*", FAIL_classes), depends_on => { "delay" }; "FAIL_classes" expression => some(".*", FAIL_classes); reports: DEBUG|EXTRA:: "CFEngine $(sys.cf_version)"; "Found class indicating failure '$(FAIL_classes)'"; FAIL_classes:: "$(this.promise_filename) FAIL"; no_FAIL_classes:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/002.cf0000644000000000000000000000142315010704253022735 0ustar00rootroot00000000000000####################################################### # # Test not # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "not_ok" not => "any"; "ok" not => "not_ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/109.cf0000644000000000000000000000146615010704253022754 0ustar00rootroot00000000000000# Test that classes in common bundles can be passed across bundles and namespaces body common control { inputs => { "../../default.cf.sub", "109.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle common shared { classes: "shared_class" expression => "any"; } bundle agent test { methods: "shared" usebundle => shared; "namespaced" usebundle => ns109:pass(); } bundle agent check { classes: "ok" expression => strcmp("works", "$(ns109:pass.shared_dependent)"); reports: DEBUG:: "The class expression in ns109:pass() was $(ns109:pass.class_needed)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/013.cf0000644000000000000000000000150515010704253022740 0ustar00rootroot00000000000000####################################################### # # Test xor # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" xor => { "cfengine_3", "this_was_not_defined", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/018.cf0000644000000000000000000000153115010704253022744 0ustar00rootroot00000000000000####################################################### # # Test brackets on "or" (Issue 234) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" or => { userexists("root") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/persistent_tags.cf0000644000000000000000000000227415010704253025657 0ustar00rootroot00000000000000####################################################### # # Redmine#5017: persistent classes should keep their tags # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dflags" string => ifelse("EXTRA", "-DDEBUG,EXTRA", "-DDEBUG"); commands: "$(G.echo)" classes => init_cancel_always; } body classes init_cancel_always { cancel_repaired => { "myclass" }; cancel_notkept => { "myclass" }; cancel_kept => { "myclass" }; } bundle agent test { commands: "$(sys.cf_agent) -K $(init.dflags) -f $(this.promise_filename).sub" classes => test_always("done_persisting"); } body classes test_always(x) { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } bundle agent check { vars: done_persisting:: "subout" string => execresult("$(sys.cf_agent) -K $(init.dflags) -f $(this.promise_filename).sub2", "noshell"); reports: "$(subout)"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/032.cf.sub0000644000000000000000000000132215010704253023526 0ustar00rootroot00000000000000body file control { namespace => "xxx"; } bundle agent localclass { reports: cfengine:: "testing class 2" classes => always("a_class_global_from_command"); a_class_global_from_command:: "Global class from 'classes' attribute, accessed in the same namespace"; default:a_class_global_from_command:: "Global class from 'classes' attribute, accessed in the default namespace"; } body classes always(x) # Define a class no matter what the outcome of the promise is { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; # persist_time => "1"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/staging/0000755000000000000000000000000015010704253023556 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/02_classes/01_basic/staging/028.c0000644000000000000000000000277115010704253024242 0ustar00rootroot00000000000000#include #include #include #include #define SPLAY_PSEUDO_RANDOM_CONSTANT 8192 #define DAILY 12 * 24 main() { char s[] = "xx"; char c, c2; int hash, box, minblocks; int period = DAILY - 1; char *boxes[DAILY]; for (box = 0; box < DAILY; box++) { boxes[box] = 0; } for (c = 'A'; c <= 'z'; c++) { for (c2 = 'A'; c2 <= 'z'; c2++) { if (!(isalnum(c) && isalnum(c2))) continue; s[0] = c; s[1] = c2; // The block algorithm is copied from evalfunction.c hash = OatHash(s); box = (int) (0.5 + period * hash / (double) SPLAY_PSEUDO_RANDOM_CONSTANT); // Back to original code if (!boxes[box]) { boxes[box] = strncpy((char *) malloc(3), s, 3); } } } printf(" \"ok\" xor => {\n"); for (box = 0; box < DAILY; box++) { printf("\tsplayclass(\"%s\",\"daily\"), # Box %d\n", boxes[box], box); } printf("\t};\n"); } // This is copied from files_hashes.c int OatHash(char *key) { unsigned int hashtablesize = SPLAY_PSEUDO_RANDOM_CONSTANT; unsigned char *p = key; unsigned h = 0; int i, len = strlen(key); for (i = 0; i < len; i++) { h += p[i]; h += (h << 10); h ^= (h >> 6); } h += (h << 3); h ^= (h >> 11); h += (h << 15); return (h & (hashtablesize - 1)); } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/staging/028.cf0000644000000000000000000003135315010704253024406 0ustar00rootroot00000000000000####################################################### # # Check splayclass - requires familiaity with internals # See associated C file to generate mutually exclusive classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { classes: "classtotest" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: # The program 028.c generates this list, and exactly 1 class will # be True at any time of day "ok" xor => { splayclass("AT","daily"), # Box 0 splayclass("AA","daily"), # Box 1 splayclass("AH","daily"), # Box 2 splayclass("AZ","daily"), # Box 3 splayclass("Cd","daily"), # Box 4 splayclass("CV","daily"), # Box 5 splayclass("Am","daily"), # Box 6 splayclass("EH","daily"), # Box 7 splayclass("Bh","daily"), # Box 8 splayclass("HF","daily"), # Box 9 splayclass("Bz","daily"), # Box 10 splayclass("CM","daily"), # Box 11 splayclass("OR","daily"), # Box 12 splayclass("FK","daily"), # Box 13 splayclass("Ay","daily"), # Box 14 splayclass("Cc","daily"), # Box 15 splayclass("IF","daily"), # Box 16 splayclass("IA","daily"), # Box 17 splayclass("HP","daily"), # Box 18 splayclass("Et","daily"), # Box 19 splayclass("Ga","daily"), # Box 20 splayclass("EF","daily"), # Box 21 splayclass("DS","daily"), # Box 22 splayclass("Ee","daily"), # Box 23 splayclass("BI","daily"), # Box 24 splayclass("CH","daily"), # Box 25 splayclass("AS","daily"), # Box 26 splayclass("Gd","daily"), # Box 27 splayclass("Dm","daily"), # Box 28 splayclass("CA","daily"), # Box 29 splayclass("FZ","daily"), # Box 30 splayclass("Gv","daily"), # Box 31 splayclass("ES","daily"), # Box 32 splayclass("Db","daily"), # Box 33 splayclass("BS","daily"), # Box 34 splayclass("KP","daily"), # Box 35 splayclass("EZ","daily"), # Box 36 splayclass("Ax","daily"), # Box 37 splayclass("An","daily"), # Box 38 splayclass("Mq","daily"), # Box 39 splayclass("Bw","daily"), # Box 40 splayclass("BL","daily"), # Box 41 splayclass("AI","daily"), # Box 42 splayclass("CN","daily"), # Box 43 splayclass("Aw","daily"), # Box 44 splayclass("Ce","daily"), # Box 45 splayclass("Mh","daily"), # Box 46 splayclass("Gs","daily"), # Box 47 splayclass("He","daily"), # Box 48 splayclass("Ex","daily"), # Box 49 splayclass("KJ","daily"), # Box 50 splayclass("GN","daily"), # Box 51 splayclass("Bm","daily"), # Box 52 splayclass("Iy","daily"), # Box 53 splayclass("JG","daily"), # Box 54 splayclass("Po","daily"), # Box 55 splayclass("CF","daily"), # Box 56 splayclass("Fg","daily"), # Box 57 splayclass("KQ","daily"), # Box 58 splayclass("AB","daily"), # Box 59 splayclass("Cq","daily"), # Box 60 splayclass("KX","daily"), # Box 61 splayclass("ER","daily"), # Box 62 splayclass("De","daily"), # Box 63 splayclass("Fn","daily"), # Box 64 splayclass("Bn","daily"), # Box 65 splayclass("DZ","daily"), # Box 66 splayclass("DA","daily"), # Box 67 splayclass("Ag","daily"), # Box 68 splayclass("Bi","daily"), # Box 69 splayclass("Ki","daily"), # Box 70 splayclass("Kw","daily"), # Box 71 splayclass("Ed","daily"), # Box 72 splayclass("In","daily"), # Box 73 splayclass("CC","daily"), # Box 74 splayclass("Dy","daily"), # Box 75 splayclass("OB","daily"), # Box 76 splayclass("DU","daily"), # Box 77 splayclass("Cj","daily"), # Box 78 splayclass("EC","daily"), # Box 79 splayclass("Gr","daily"), # Box 80 splayclass("AO","daily"), # Box 81 splayclass("Bf","daily"), # Box 82 splayclass("Gk","daily"), # Box 83 splayclass("AX","daily"), # Box 84 splayclass("Ar","daily"), # Box 85 splayclass("Hq","daily"), # Box 86 splayclass("Ac","daily"), # Box 87 splayclass("BG","daily"), # Box 88 splayclass("Dq","daily"), # Box 89 splayclass("AY","daily"), # Box 90 splayclass("BY","daily"), # Box 91 splayclass("Cn","daily"), # Box 92 splayclass("BJ","daily"), # Box 93 splayclass("Yu","daily"), # Box 94 splayclass("DC","daily"), # Box 95 splayclass("Dd","daily"), # Box 96 splayclass("Ca","daily"), # Box 97 splayclass("Kc","daily"), # Box 98 splayclass("Op","daily"), # Box 99 splayclass("PV","daily"), # Box 100 splayclass("MJ","daily"), # Box 101 splayclass("GE","daily"), # Box 102 splayclass("EJ","daily"), # Box 103 splayclass("Hh","daily"), # Box 104 splayclass("CJ","daily"), # Box 105 splayclass("Ev","daily"), # Box 106 splayclass("Cw","daily"), # Box 107 splayclass("Cb","daily"), # Box 108 splayclass("Eh","daily"), # Box 109 splayclass("Bt","daily"), # Box 110 splayclass("EB","daily"), # Box 111 splayclass("Fo","daily"), # Box 112 splayclass("Nb","daily"), # Box 113 splayclass("HG","daily"), # Box 114 splayclass("KD","daily"), # Box 115 splayclass("DW","daily"), # Box 116 splayclass("Ak","daily"), # Box 117 splayclass("Cp","daily"), # Box 118 splayclass("Ae","daily"), # Box 119 splayclass("Bg","daily"), # Box 120 splayclass("Qq","daily"), # Box 121 splayclass("PC","daily"), # Box 122 splayclass("CL","daily"), # Box 123 splayclass("HA","daily"), # Box 124 splayclass("Aq","daily"), # Box 125 splayclass("Ef","daily"), # Box 126 splayclass("PJ","daily"), # Box 127 splayclass("BA","daily"), # Box 128 splayclass("Dp","daily"), # Box 129 splayclass("DK","daily"), # Box 130 splayclass("Gq","daily"), # Box 131 splayclass("GW","daily"), # Box 132 splayclass("Hp","daily"), # Box 133 splayclass("BK","daily"), # Box 134 splayclass("NY","daily"), # Box 135 splayclass("NP","daily"), # Box 136 splayclass("CB","daily"), # Box 137 splayclass("CI","daily"), # Box 138 splayclass("AR","daily"), # Box 139 splayclass("Pb","daily"), # Box 140 splayclass("Co","daily"), # Box 141 splayclass("Ms","daily"), # Box 142 splayclass("Oq","daily"), # Box 143 splayclass("Pt","daily"), # Box 144 splayclass("RQ","daily"), # Box 145 splayclass("AF","daily"), # Box 146 splayclass("Fs","daily"), # Box 147 splayclass("DO","daily"), # Box 148 splayclass("Cu","daily"), # Box 149 splayclass("Ds","daily"), # Box 150 splayclass("Tv","daily"), # Box 151 splayclass("Ys","daily"), # Box 152 splayclass("BW","daily"), # Box 153 splayclass("BP","daily"), # Box 154 splayclass("cV","daily"), # Box 155 splayclass("DE","daily"), # Box 156 splayclass("Fz","daily"), # Box 157 splayclass("EM","daily"), # Box 158 splayclass("DL","daily"), # Box 159 splayclass("cM","daily"), # Box 160 splayclass("BD","daily"), # Box 161 splayclass("Bd","daily"), # Box 162 splayclass("GC","daily"), # Box 163 splayclass("AE","daily"), # Box 164 splayclass("Ho","daily"), # Box 165 splayclass("JE","daily"), # Box 166 splayclass("CZ","daily"), # Box 167 splayclass("RG","daily"), # Box 168 splayclass("As","daily"), # Box 169 splayclass("Ai","daily"), # Box 170 splayclass("IT","daily"), # Box 171 splayclass("Cg","daily"), # Box 172 splayclass("Cl","daily"), # Box 173 splayclass("JS","daily"), # Box 174 splayclass("FO","daily"), # Box 175 splayclass("HO","daily"), # Box 176 splayclass("Bq","daily"), # Box 177 splayclass("OH","daily"), # Box 178 splayclass("DN","daily"), # Box 179 splayclass("Hx","daily"), # Box 180 splayclass("CK","daily"), # Box 181 splayclass("NC","daily"), # Box 182 splayclass("PO","daily"), # Box 183 splayclass("Dz","daily"), # Box 184 splayclass("Eq","daily"), # Box 185 splayclass("AG","daily"), # Box 186 splayclass("Ke","daily"), # Box 187 splayclass("DT","daily"), # Box 188 splayclass("EY","daily"), # Box 189 splayclass("BE","daily"), # Box 190 splayclass("Br","daily"), # Box 191 splayclass("Qk","daily"), # Box 192 splayclass("Jw","daily"), # Box 193 splayclass("KM","daily"), # Box 194 splayclass("AP","daily"), # Box 195 splayclass("DY","daily"), # Box 196 splayclass("Jz","daily"), # Box 197 splayclass("Hi","daily"), # Box 198 splayclass("AM","daily"), # Box 199 splayclass("WQ","daily"), # Box 200 splayclass("Cv","daily"), # Box 201 splayclass("BQ","daily"), # Box 202 splayclass("Fu","daily"), # Box 203 splayclass("CR","daily"), # Box 204 splayclass("JQ","daily"), # Box 205 splayclass("FN","daily"), # Box 206 splayclass("QW","daily"), # Box 207 splayclass("Fb","daily"), # Box 208 splayclass("DB","daily"), # Box 209 splayclass("OI","daily"), # Box 210 splayclass("Ei","daily"), # Box 211 splayclass("FY","daily"), # Box 212 splayclass("Cm","daily"), # Box 213 splayclass("IE","daily"), # Box 214 splayclass("HM","daily"), # Box 215 splayclass("BN","daily"), # Box 216 splayclass("BT","daily"), # Box 217 splayclass("HD","daily"), # Box 218 splayclass("GK","daily"), # Box 219 splayclass("BB","daily"), # Box 220 splayclass("Bo","daily"), # Box 221 splayclass("EV","daily"), # Box 222 splayclass("Ht","daily"), # Box 223 splayclass("BM","daily"), # Box 224 splayclass("Lk","daily"), # Box 225 splayclass("Er","daily"), # Box 226 splayclass("AD","daily"), # Box 227 splayclass("GI","daily"), # Box 228 splayclass("SX","daily"), # Box 229 splayclass("JH","daily"), # Box 230 splayclass("IZ","daily"), # Box 231 splayclass("Cs","daily"), # Box 232 splayclass("Ym","daily"), # Box 233 splayclass("DI","daily"), # Box 234 splayclass("Oo","daily"), # Box 235 splayclass("LK","daily"), # Box 236 splayclass("DX","daily"), # Box 237 splayclass("HR","daily"), # Box 238 splayclass("Fj","daily"), # Box 239 splayclass("XC","daily"), # Box 240 splayclass("AV","daily"), # Box 241 splayclass("AC","daily"), # Box 242 splayclass("CW","daily"), # Box 243 splayclass("AJ","daily"), # Box 244 splayclass("Av","daily"), # Box 245 splayclass("CX","daily"), # Box 246 splayclass("ED","daily"), # Box 247 splayclass("HE","daily"), # Box 248 splayclass("Ao","daily"), # Box 249 splayclass("Gm","daily"), # Box 250 splayclass("BC","daily"), # Box 251 splayclass("EN","daily"), # Box 252 splayclass("EP","daily"), # Box 253 splayclass("FQ","daily"), # Box 254 splayclass("Dt","daily"), # Box 255 splayclass("RC","daily"), # Box 256 splayclass("Ib","daily"), # Box 257 splayclass("JI","daily"), # Box 258 splayclass("BU","daily"), # Box 259 splayclass("BV","daily"), # Box 260 splayclass("Xp","daily"), # Box 261 splayclass("GA","daily"), # Box 262 splayclass("NE","daily"), # Box 263 splayclass("Mo","daily"), # Box 264 splayclass("CE","daily"), # Box 265 splayclass("AL","daily"), # Box 266 splayclass("Es","daily"), # Box 267 splayclass("Py","daily"), # Box 268 splayclass("Hl","daily"), # Box 269 splayclass("IC","daily"), # Box 270 splayclass("Bp","daily"), # Box 271 splayclass("Iz","daily"), # Box 272 splayclass("HU","daily"), # Box 273 splayclass("DQ","daily"), # Box 274 splayclass("EI","daily"), # Box 275 splayclass("Cf","daily"), # Box 276 splayclass("GH","daily"), # Box 277 splayclass("Aa","daily"), # Box 278 splayclass("EG","daily"), # Box 279 splayclass("Ct","daily"), # Box 280 splayclass("Gl","daily"), # Box 281 splayclass("AW","daily"), # Box 282 splayclass("CP","daily"), # Box 283 splayclass("CO","daily"), # Box 284 splayclass("AK","daily"), # Box 285 splayclass("BZ","daily"), # Box 286 splayclass("Fk","daily"), # Box 287 }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/028.cf0000644000000000000000000000204615010704253022747 0ustar00rootroot00000000000000####################################################### # # Check that we can use || in class expressions # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: any||something:: "oklhs" expression => "any"; something||any:: "okrhs" expression => "any"; any||any:: "okboth" expression => "any"; something||something:: "okno" expression => "any"; any:: "ok" and => { "oklhs", "okrhs", "okboth", "!okno" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/027.cf0000644000000000000000000000145215010704253022746 0ustar00rootroot00000000000000####################################################### # # Check canonification in if # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { commands: "$(G.true)" classes => if_repaired("/test"); } ####################################################### bundle agent check { classes: "ok" expression => "_test"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/02_classes/01_basic/persistent_negate.cf.sub20000644000000000000000000000035315010704253027032 0ustar00rootroot00000000000000body common control { bundlesequence => { run }; } bundle agent run { classes: "ok" expression => "!test_class"; reports: ok:: "Pass"; !ok.DEBUG:: "test_class defined"; !ok:: "FAIL"; } cfengine-3.24.2/tests/acceptance/Makefile.am0000644000000000000000000000740215010704253020642 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # SUBDIRS = 25_cf-execd AM_CPPFLAGS = \ -I$(top_srcdir)/libntech/libutils \ -I$(top_srcdir)/libcfecompat \ -I$(top_srcdir)/libpromises \ -I$(top_srcdir)/libcfnet \ $(CORE_CPPFLAGS) $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = $(CORE_CFLAGS) AM_LDFLAGS = $(CORE_LDFLAGS) LIBS = $(CORE_LIBS) noinst_PROGRAMS = noinst_LTLIBRARIES = libmock_package_manager.la libmock_package_manager_la_SOURCES = mock_package_manager.c libmock_package_manager_la_LIBADD = ../../libpromises/libpromises.la if !WINDOWS noinst_PROGRAMS += mock_package_manager mock_package_manager_SOURCES = mock_package_manager_LDADD = libmock_package_manager.la noinst_PROGRAMS += no_fds no_fds_LDADD = ../../libntech/libutils/libutils.la noinst_PROGRAMS += custom_promise_binary custom_promise_binary_SOURCES = 30_custom_promise_types/custom_promise_binary.c endif # !WINDOWS if HAVE_LIBXML2 noinst_PROGRAMS += xml-c14nize xml_c14nize_CPPFLAGS = \ -I$(top_srcdir)/libpromises \ -I$(srcdir)/../../libntech/libutils \ $(LIBXML2_CPPFLAGS) xml_c14nize_CFLAGS = $(LIBXML2_CFLAGS) xml_c14nize_LDFLAGS = $(LIBXML2_LDFLAGS) xml_c14nize_LDADD = ../../libntech/libutils/libutils.la $(LIBXML2_LIBS) endif TESTS = TESTS_ENVIRONMENT = env \ AGENT=`pwd`/../../cf-agent/cf-agent \ CF_PROMISES=`pwd`/../../cf-promises/cf-promises \ CF_SERVERD=`pwd`/../../cf-serverd/cf-serverd \ CF_KEY=`pwd`/../../cf-key/cf-key \ CF_NET=`pwd`/../../cf-net/cf-net \ CF_CHECK=`pwd`/../../cf-check/cf-check \ RPMVERCMP=`pwd`/../../ext/rpmvercmp \ MOCK_PACKAGE_MANAGER=`pwd`/mock_package_manager if !HAVE_LIBXML2 TESTS_ENVIRONMENT += LIBXML2_TESTS=0 endif if !HAVE_LIBCURL TESTS_ENVIRONMENT += LIBCURL_TESTS=0 endif # Keep the '+' in front for the command, needed for the sub-make # to run in parallel; TODO fix "make -n" not working: check-local: + $(TESTS_ENVIRONMENT) MAKE=$(MAKE) $(srcdir)/testall EXTRA_DIST = default.cf.sub dcs.cf.sub plucked.cf.sub run_with_server.cf.sub \ testall dummy_etc write_args.sh \ root-MD5=617eb383deffef843ea856b129d0a423.pub \ root-MD5=617eb383deffef843ea856b129d0a423.priv # Recursively include all tests in the dist tarball and set proper permissions EXTRA_DIST += $(wildcard [0-9]*) dist-hook: chmod -R go-w $(distdir) CLEANFILES = *.gcno *.gcda Makefile.testall pluck: echo '### This is an auto-generated file, see Makefile.am and `make pluck` ###' > plucked.cf.sub ../../contrib/cf-locate/cf-locate -f -p '( if_|run_|warn_only|INI_section|kept_successful_command|edit_line|set_user_field|set_variable_values\(|edit_field|set_line_based|location|replace_with|_cp|_dcp|empty|shell|immediate|perms| m\b|recurse|tidy| all|classes_generic|results| start|always|^value|edit_field line|insert_lines|(link|copy)from| file_mustache| (file|dir)_(copy|tidy|sync|make|empty|link|hardlink))' ../../../masterfiles/lib/*.cf >> plucked.cf.sub cfengine-3.24.2/tests/acceptance/09_services/0000755000000000000000000000000015010704253020736 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/09_services/service_cannot_be_resolved.cf0000644000000000000000000000314615010704253026627 0ustar00rootroot00000000000000####################################################### # # catch "Service ... cannot be resolved" inform message # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle common test { meta: "test_soft_fail" string => "windows", meta => { "redmine4772,ENT-2161" }; classes: "resolution_warning" expression => returnszero("$(command) Service | $(G.grep) 'cannot be resolved' 2>&1", "useshell"); "myservice_found" expression => returnszero("$(command) 4441a73c9b58ff7f2285c018ee7449f35ec89712 2>&1", "useshell"); vars: "command" string => "$(sys.cf_agent) -KI -f $(this.promise_filename).sub | $(G.grep)"; } ####################################################### bundle agent check { classes: "ok" and => { "!resolution_warning", "myservice_found" }; reports: DEBUG.resolution_warning:: "failure: service bundle 'cannot be resolved' error WAS found"; DEBUG.!resolution_warning:: "success: service bundle 'cannot be resolved' error was not found"; DEBUG.myservice_found:: "success: myservice report 4441a73c9b58ff7f2285c018ee7449f35ec89712 was found"; DEBUG.!myservice_found:: "failure: myservice report 4441a73c9b58ff7f2285c018ee7449f35ec89712 was NOT found"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/09_services/restart.cf0000644000000000000000000000234115010704253022734 0ustar00rootroot00000000000000####################################################### # # Test services restart keyword # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "redmine4772,ENT-2161" }; services: "myservice" service_policy => "restart", service_method => service_test; } body service_method service_test { service_bundle => test_services("$(this.promiser)","$(this.service_policy)"); } bundle agent test_services(service, state) { vars: "service_state" string => "$(state)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("restart", "$(test_services.service_state)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 39 cfengine-3.24.2/tests/acceptance/09_services/enable.cf0000644000000000000000000000232215010704253022475 0ustar00rootroot00000000000000####################################################### # # Test services enable keyword # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "CFE-2402" }; services: "myservice" service_policy => "enable", service_method => service_test; } body service_method service_test { service_bundle => test_services("$(this.promiser)","$(this.service_policy)"); } bundle agent test_services(service, state) { vars: "service_state" string => "$(state)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("enable", "$(test_services.service_state)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 39 cfengine-3.24.2/tests/acceptance/09_services/outcomes.cf0000644000000000000000000000400415010704253023104 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-2161" }; vars: "services" slist => { "single" }; "policies" slist => { "enable", "disable", "start", "stop", "restart", "reload", "custom" }; services: "$(services)" service_policy => "$(policies)", classes => scoped_classes_generic("namespace", "$(services)_$(policies)"); } bundle agent standard_services(service, state) { reports: EXTRA:: "$(this.bundle): passthrough for $(service) -> $(state)"; } bundle agent check { vars: "s" slist => { @(test.services) }; "p" slist => { @(test.policies) }; methods: "collect" usebundle => dcs_all_classes_to_string("$(s)_$(p)"), inherit => "true", useresult => "$(s)_$(p)"; EXTRA:: "" usebundle => dcs_report_generic_classes("$(s)_$(p)"), inherit => "true"; any:: "report" usebundle => dcs_passif_expected('single_enable_kept,single_disable_kept,single_start_kept,single_stop_kept,single_restart_kept,single_reload_kept,single_custom_kept', 'single_enable_repaired,single_enable_failed,single_enable_denied,single_enable_timeout,single_disable_repaired,single_disable_failed,single_disable_denied,single_disable_timeout,single_start_repaired,single_start_failed,single_start_denied,single_start_timeout,single_stop_repaired,single_stop_failed,single_stop_denied,single_stop_timeout,single_restart_repaired,single_restart_failed,single_restart_denied,single_restart_timeout,single_reload_repaired,single_reload_failed,single_reload_denied,single_reload_timeout,single_custom_repaired,single_custom_failed,single_custom_denied,single_custom_timeout', $(this.promise_filename)); reports: EXTRA:: "Class strings for service $(s), policy $(p): $($(s)_$(p)[str])"; } cfengine-3.24.2/tests/acceptance/09_services/disable.cf0000644000000000000000000000232515010704253022655 0ustar00rootroot00000000000000####################################################### # # Test services disable keyword # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "CFE-2402" }; services: "myservice" service_policy => "disable", service_method => service_test; } body service_method service_test { service_bundle => test_services("$(this.promiser)","$(this.service_policy)"); } bundle agent test_services(service, state) { vars: "service_state" string => "$(state)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("disable", "$(test_services.service_state)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 39 cfengine-3.24.2/tests/acceptance/09_services/reload.cf0000644000000000000000000000233615010704253022522 0ustar00rootroot00000000000000####################################################### # # Test services reload keyword # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "redmine4772,ENT-2161" }; services: "myservice" service_policy => "reload", service_method => service_test; } body service_method service_test { service_bundle => test_services("$(this.promiser)","$(this.service_policy)"); } bundle agent test_services(service, state) { vars: "service_state" string => "$(state)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("reload", "$(test_services.service_state)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 39 cfengine-3.24.2/tests/acceptance/09_services/start.cf0000644000000000000000000000233315010704253022406 0ustar00rootroot00000000000000####################################################### # # Test services start keyword # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "redmine4772,ENT-2161" }; services: "myservice" service_policy => "start", service_method => service_test; } body service_method service_test { service_bundle => test_services("$(this.promiser)","$(this.service_policy)"); } bundle agent test_services(service, state) { vars: "service_state" string => "$(state)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("start", "$(test_services.service_state)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 39 cfengine-3.24.2/tests/acceptance/09_services/custom.cf0000644000000000000000000000232215010704253022561 0ustar00rootroot00000000000000####################################################### # # Test services custom keyword # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "CFE-2402" }; services: "myservice" service_policy => "custom", service_method => service_test; } body service_method service_test { service_bundle => test_services("$(this.promiser)","$(this.service_policy)"); } bundle agent test_services(service, state) { vars: "service_state" string => "$(state)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("custom", "$(test_services.service_state)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 39 cfengine-3.24.2/tests/acceptance/09_services/standard_services-from-non-default-namespace.cf0000644000000000000000000000245715010704253032070 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "ENT-5406" } string => "Test that standard_services can be used from non-default namespace"; "test_soft_fail" string => "windows", meta => { "ENT-2161" }; methods: "Test" usebundle => ENT_5406:ns_test; } bundle agent standard_services(service, state) # @brief Mock implementation of standard_services. # NOTE The stdlib in the MPF (masterfiles policy framework) contains a bundle of # the same name, this mock implementation is used becasue we don't really want # to test starting and stopping services, we only want to test that the correct # bundle is selected. { files: "$(G.testfile)" create => "true"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists( $(G.testfile) ); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body file control { namespace => "ENT_5406"; } bundle agent ns_test { services: "myservice" service_policy => "start"; } cfengine-3.24.2/tests/acceptance/09_services/stop.cf0000644000000000000000000000233015010704253022233 0ustar00rootroot00000000000000####################################################### # # Test services stop keyword # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "redmine4772,ENT-2161" }; services: "myservice" service_policy => "stop", service_method => service_test; } body service_method service_test { service_bundle => test_services("$(this.promiser)","$(this.service_policy)"); } bundle agent test_services(service, state) { vars: "service_state" string => "$(state)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("stop", "$(test_services.service_state)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 39 cfengine-3.24.2/tests/acceptance/09_services/service_cannot_be_resolved.cf.sub0000644000000000000000000000054515010704253027417 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { test }; } bundle agent test { services: "myservice" service_policy => "start"; } bundle agent standard_services(service, state) { reports: "$(this.bundle): bringing $(service) into desired state $(state) 4441a73c9b58ff7f2285c018ee7449f35ec89712"; } cfengine-3.24.2/tests/acceptance/08_commands/0000755000000000000000000000000015010704253020713 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/03_shells/0000755000000000000000000000000015010704253022507 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/03_shells/tryshell.cf.sub0000644000000000000000000000402015010704253025453 0ustar00rootroot00000000000000####################################################### # # Test command useshell parameters # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "init", "test" }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); } ####################################################### bundle agent test { classes: "shelltype_noshell" or => { "useshell_noshell", "useshell_false", "useshell_no", "useshell_off" }; "shelltype_useshell" or => { "useshell_useshell", "useshell_true", "useshell_yes", "useshell_on" }; "shelltype_powershell" or => { "useshell_powershell" }; vars: useshell_true:: "shelltype" string => "true"; useshell_false:: "shelltype" string => "false"; useshell_yes:: "shelltype" string => "yes"; useshell_no:: "shelltype" string => "no"; useshell_on:: "shelltype" string => "on"; useshell_off:: "shelltype" string => "off"; useshell_noshell:: "shelltype" string => "noshell"; useshell_useshell:: "shelltype" string => "useshell"; useshell_powershell:: "shelltype" string => "powershell"; shelltype_noshell.windows:: "shellcmd" string => "c:\windows\system32\cmd.exe /C type"; shelltype_noshell.!windows:: "shellcmd" string => "/bin/cat"; shelltype_useshell.windows:: "shellcmd" string => "type"; shelltype_useshell.!windows:: "shellcmd" string => "cat"; shelltype_powershell:: "shellcmd" string => "Get-Content"; classes: "shell_specified" or => { "shelltype_noshell", "shelltype_useshell", "shelltype_powershell" }; commands: shell_specified:: "$(shellcmd) $(init.origtestdir)$(const.dirsep)text.txt" contain => shelltype; reports: !shell_specified:: "No shell type specified!"; } body contain shelltype { useshell => "$(test.shelltype)"; } cfengine-3.24.2/tests/acceptance/08_commands/03_shells/shelltypes.cf0000644000000000000000000000347415010704253025225 0ustar00rootroot00000000000000####################################################### # # Test command useshell parameters # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); "shelltypes" slist => { "useshell_true", "useshell_false", "useshell_yes", "useshell_no", "useshell_on", "useshell_off", "useshell_noshell", "useshell_useshell", "useshell_powershell" }; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; classes: "$(init.shelltypes)" expression => regcmp(".*(Succeeded|Powershell is only supported on Windows).*", execresult("$(sys.cf_agent) -D $(init.shelltypes) -Kf $(init.origtestdir)$(const.dirsep)tryshell.cf.sub", "noshell")); "ok" and => { "@(init.shelltypes)" }; vars: ok:: "ok" string => "ok"; reports: DEBUG:: "$(init.shelltypes) test failed" if => "!$(init.shelltypes)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("$(test.ok)", "ok"); reports: DEBUG:: "Tests powershell in commands promises."; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL "; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/03_shells/text.txt0000644000000000000000000000001215010704253024225 0ustar00rootroot00000000000000Succeeded cfengine-3.24.2/tests/acceptance/08_commands/01_modules/0000755000000000000000000000000015010704253022663 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/01_modules/001.cf0000644000000000000000000000237315010704253023502 0ustar00rootroot00000000000000####################################################### # # Test command modules # ####################################################### body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "script_name" string => "$(this.promise_filename).txt"; } ####################################################### bundle agent test { vars: !windows:: "cat_prefix" string => "cat"; windows:: "cat_prefix" string => "cat_exe"; commands: "$(G.cat) $(init.script_name)" contain => in_shell, module => "true"; } ####################################################### bundle agent check { classes: CLASSTOBEDEFINED.!UNDEFINEDCLASS:: "classok" expression => "any"; any:: "varok" expression => strcmp("${$(test.cat_prefix).answer}", "42"); "ok" and => { "classok", "varok" }; reports: DEBUG:: "${$(test.cat_prefix).answer} =?= 42"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 vars-from-module-have-source-and-derived_from-tags.cf0000644000000000000000000000263115010704253034675 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/01_modulesbody common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "ENT-7725" } string => "Test that vars defined by modules without explicit tags still have automatic tags identifying the source"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }, comment => "The subtest policy uses /bin/echo"; commands: "/bin/echo" args => "=my_var_from_module= my val from module", module => "true"; } bundle agent check { vars: "my_var_from_module_tags" slist => getvariablemetatags( "echo.my_var_from_module" ); reports: # Every variable should have a source=SOMETHING tag "$(this.promise_filename) Pass" if => and( reglist( @(my_var_from_module_tags), "source=.*" ), reglist( @(my_var_from_module_tags), "derived_from=.*" ) ); "$(this.promise_filename) FAIL" unless => and( reglist( @(my_var_from_module_tags), "source=.*" ), reglist( @(my_var_from_module_tags), "derived_from=.*" ) ); EXTRA|DEBUG:: "my_var_from_module_tags == $(my_var_from_module_tags)"; "echo.my_var_from_module == $(echo.my_var_from_module)"; } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/set-tags.cf.txt0000644000000000000000000000044615010704253025546 0ustar00rootroot00000000000000^context=xyz ^meta=xyz,abc=def,,??what is this?? +myclass =myvar=hello there @mylist={"abc", "def", "ghi"} @myalist={"{{abc}}", " ' def}", "ghi'''"} ^meta=1,2,3 @myblist={'{{a,bc}}', ' " de,f}', 'gh,,i"""'} +mybclass ^meta=a,b,c @myclist={"{{a'bc',,}}", ' ",, d"ef}', "ghi,},'''"} +mycclass cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module_allows_trailing_comma.cf0000644000000000000000000000335615010704253031117 0ustar00rootroot00000000000000####################################################### # # Test that modules are allowed to define lists with trailing commas # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "any", meta => { "redmine7578" }; commands: "$(G.cat)" args => "$(this.promise_filename).txt", module => "true"; } ####################################################### bundle agent check { vars: "length_of_list_from_module" int => length("default:cat.list_from_module"); classes: "have_list_from_module" expression => isvariable("default:cat.list_from_module"), comment => "Modules should be able to define empty/null lists."; "list_from_module_length_1" expression => strcmp(1, $(length_of_list_from_module)); "ok" and => { "have_list_from_module", "list_from_module_length_1" }, comment => "OK since we can both define a list with a trailing comma, and its length is 1 as expected"; reports: DEBUG|DEBUG_check:: "DEBUG $(this.bundle): Module defined 'default:cat.list_from_module'" if => "have_list_from_module"; "DEBUG $(this.bundle): The list defined from the module had the expected length of 0" if => "list_from_module_length_1"; "DEBUG $(this.bundle): length of list from module '$(length_of_list_from_module)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/set-persistent-class.cf.sub0000644000000000000000000000060515010704253030062 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; } bundle agent main { commands: "$(G.echo) '^persistence=20$(const.n)+Cx4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP'" module => "true"; "$(G.echo) '^persistence=$(const.n)+Bx4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP'" module => "true"; "$(G.echo) '+Ax4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP'" module => "true"; } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/set-context.cf0000644000000000000000000000704715010704253025462 0ustar00rootroot00000000000000####################################################### # # Test command modules # Redmine#3991: support data containers # ####################################################### body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "script_name" string => "$(this.promise_filename).txt"; } ####################################################### bundle agent test { commands: "$(G.cat) $(init.script_name)" contain => in_shell, module => "true"; } ####################################################### bundle agent check { vars: "list0" slist => {"abc", "def", "ghi"}; "list1" slist => {"{{abc}}", " ' def}", "ghi'''"}; "list2" slist => {'{{a,bc}}', ' " de,f}', 'gh,,i"""'}; "list3" slist => {"{{a'bc',,}}", ' ",, d"ef}', "ghi,},'''"}; "actual0" string => join(":", "list0"); "actual1" string => join(":", "list1"); "actual2" string => join(":", "list2"); "actual3" string => join(":", "list3"); "joined0" string => join(":", "xyz_123___456.mylist"); "joined1" string => join(":", "xyz_123___456.myalist"); "joined2" string => join(":", "xyz_123___456.myblist"); "joined3" string => join(":", "xyz_123___456.myclist"); "c" slist => { "1", "2", "3", "4", "5", "6" }; "c$(c)" string => format("%S", "xyz_123___456.mycontainer$(c)"); "e1" string => '{"x":[456,789]}'; "e5" string => '["read","some","strings"]'; "e6" string => '{"mix":["match"],"nothing":null,"paddle":true,"ping":"pong"}'; "hello_contexts" slist => { "xyz_123___456", "_456", "456", "_", "a__456__", "__a__", }; classes: any:: "var0ok" expression => strcmp("${this.joined0}" , "${this.actual0}"); "var1ok" expression => strcmp("${this.joined1}" , "${this.actual1}"); "var2ok" expression => strcmp("${this.joined2}" , "${this.actual2}"); "var3ok" expression => strcmp("${this.joined3}" , "${this.actual3}"); "var4ok" expression => strcmp("hello there" , "${xyz_123___456.myvar}"); "hello_$(hello_contexts)_ok" expression => strcmp("hello there" , "${$(hello_contexts).myvar}"); "ok_c1" expression => strcmp($(e1) , $(c1)); "ok_c2" not => isvariable("c2"); "ok_c3" not => isvariable("c3"); "ok_c4" not => isvariable("c4"); "ok_c5" expression => strcmp($(e5) , $(c5)); "ok_c6" expression => strcmp($(e6) , $(c6)); "ok_injected_var" -> { "CFE-1915" } expression => strcmp($(test.myvar), "hello there"), comment => "This remote variable injection should work, BUT IS A DIRTY HACK!"; "ok" and => { "myclass", "var0ok", "var1ok", "var2ok", "var3ok", "var4ok", "hello_xyz_123___456_ok", "hello__456_ok", "hello_456_ok", "hello___ok", "hello_a__456___ok", "hello___a___ok", "ok_c1", "ok_c2", "ok_c3", "ok_c4", "ok_c5", "ok_c6", "ok_injected_var" }; reports: DEBUG:: "container $(c): $(e$(c)) != $(c$(c))" if => "!ok_c$(c)"; "context $(hello_contexts) failed" if => "!hello_$(hello_contexts)_ok"; "test.myvar = $(test.myvar)" if => "!ok_injected_var"; EXTRA:: "context $(hello_contexts) worked" if => "hello_$(hello_contexts)_ok"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module_allows_empty_lists.cf.txt0000644000000000000000000000002615010704253031313 0ustar00rootroot00000000000000@list_from_module={ } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module_file_test.cf0000644000000000000000000000164515010704253026526 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: any:: "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '{ "hello": "world" }'; } bundle agent test { meta: "description" string => "Test module file protocol"; "test_soft_fail" string => "windows", meta => { "ENT-10257" }; commands: any:: "$(G.echo) &data=$(G.testfile).json" module => "true"; reports: DEBUG:: "hello has value: $(echo.data[hello])"; } bundle agent check { classes: "pass" expression => strcmp("$(echo.data[hello])", "world"); reports: pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module_allows_empty_lists.cf0000644000000000000000000000404615010704253030503 0ustar00rootroot00000000000000####################################################### # # Test that modules are allowed to emit empty lists # Redmine: 7577 ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "any", meta => { "redmine7577" }; commands: "$(G.cat)" args => "$(this.promise_filename).txt", module => "true", comment => "Module output found in this file"; } ####################################################### bundle agent check { vars: "length_of_list_from_module" int => length("default:cat.list_from_module"); classes: "have_list_from_module" expression => isvariable("default:cat.list_from_module"), comment => "Modules should be able to define empty/null lists."; "list_from_module_length_0" expression => strcmp( 0, $(length_of_list_from_module) ); "ok" and => { "have_list_from_module", "list_from_module_length_0" }, comment => "OK since we can both define an empty list, and its length is 0"; reports: DEBUG|DEBUG_check:: "DEBUG $(this.bundle): Module defined 'default:cat.list_from_module'" if => "have_list_from_module"; "DEBUG $(this.bundle): Module did not define the expected list 'default:cat.list_from_module'" unless => "have_list_from_module"; "DEBUG $(this.bundle): The list defined from the module had the expected length of 0" if => "list_from_module_length_0"; "DEBUG $(this.bundle): The the list defined from the module did not have the expected length or was undefined" unless => "list_from_module_length_0"; "DEBUG $(this.bundle): length of list from module '$(length_of_list_from_module)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module-array-indexing.cf0000644000000000000000000000247715010704253027413 0ustar00rootroot00000000000000####################################################### # # Zendesk 1312 # Test command modules with given array indices # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { commands: "$(G.cat) $(this.promise_filename).txt" module => "true"; reports: EXTRA:: "Got foo_idx = $(arrays.foo_idx)"; "Got foo[$(arrays.foo_idx)] = $(arrays.foo[$(arrays.foo_idx)])"; } ####################################################### bundle agent check { vars: "foo_$(arrays.foo_idx)" string => "$(arrays.foo[$(arrays.foo_idx)])"; "merged_foo" data => mergedata("arrays.foo"); "sfoo" string => "foo_a=$(foo_a), foo_b=$(foo_b)"; "actual" string => format("foo = %S, foo_idx = %S, sfoo = %s", merged_foo, "arrays.foo_idx", $(sfoo)); "expected" string => 'foo = {"a":"a_foo","b":"b_foo"}, foo_idx = { "a", "b" }, sfoo = foo_a=a_foo, foo_b=b_foo'; methods: "" usebundle => dcs_check_strcmp($(expected), $(actual), $(this.promise_filename), "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/004.cf.txt0000644000000000000000000000026115010704253024315 0ustar00rootroot00000000000000@mylist={"abc", "def", "ghi"} @myalist={"{{abc}}", " ' def}", "ghi'''"} @myblist={'{{a,bc}}', ' " de,f}', 'gh,,i"""'} @myclist={"{{a'bc',,}}", ' ",, d"ef}', "ghi,},'''"} cfengine-3.24.2/tests/acceptance/08_commands/01_modules/set-context.cf.txt0000644000000000000000000000122015010704253026263 0ustar00rootroot00000000000000^context=xyz_123___456 +myclass =myvar=hello there @mylist={"abc", "def", "ghi"} @myalist={"{{abc}}", " ' def}", "ghi'''"} @myblist={'{{a,bc}}', ' " de,f}', 'gh,,i"""'} @myclist={"{{a'bc',,}}", ' ",, d"ef}', "ghi,},'''"} %mycontainer1={"x":[456,789]} %mycontainer2={"x":"y" %mycontainer3="long string here" %mycontainer4=null %mycontainer5=["read", "some", "strings"] %mycontainer6={"mix": ["match"], "ping": "pong", "paddle": true, "nothing": null} ^context=_456 =myvar=hello there ^context=456 =myvar=hello there ^context=_ =myvar=hello there ^context=a__456__ =myvar=hello there ^context=__a__ =myvar=hello there ^context=test =myvar=hello there cfengine-3.24.2/tests/acceptance/08_commands/01_modules/003.cf0000644000000000000000000000222215010704253023475 0ustar00rootroot00000000000000####################################################### # # Test command modules # ####################################################### body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "script_name" string => "$(this.promise_filename).txt"; } ####################################################### bundle agent test { vars: !windows:: "cat_prefix" string => "cat"; windows:: "cat_prefix" string => "cat_exe"; commands: "$(G.cat) $(init.script_name)" contain => in_shell, module => "true"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("$($(test.cat_prefix).myvar[dot.dash-test])", "42"); reports: DEBUG:: "${$(test.cat_prefix).myvar[dot.dash-test]} =?= 42"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL "; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/long-module-lines.cf0000644000000000000000000001570015010704253026532 0ustar00rootroot00000000000000####################################################### # # Test command modules with long lines # Redmine#4170: segfault on long lines # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "script_name" string => "$(G.cat) $(this.promise_filename).txt"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-1623" }; commands: "$(init.script_name)" module => "true"; } ####################################################### bundle agent check { vars: "scalars" slist => { "x4095", "x4094", "x4093" }; "lists" slist => { "zshort", "z4095" }; "bytes1024" string => "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; "bytes1000" string => "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567"; "expected[x4095]" string => concat($(bytes1024),$(bytes1024),$(bytes1024),$(bytes1000),"89abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789x4095"); "expected[x4094]" string => concat($(bytes1024),$(bytes1024),$(bytes1024),$(bytes1000),"89abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef012345678x4094"); "expected[x4093]" string => concat($(bytes1024),$(bytes1024),$(bytes1024),$(bytes1000),"89abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567x4093"); "longclass" string => "class678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"; "expected_length[zshort]" int => "227"; "expected_length[z4095]" int => "293"; "actual_length[$(lists)]" int => length("cat.$(lists)"); "longclass_length" int => string_length($(longclass)); "expected_length[$(scalars)]" int => string_length("$(expected[$(scalars)])"); "actual_length[$(scalars)]" int => string_length("$(cat.$(scalars))"); "tail[$(scalars)]" string => string_tail("$(cat.$(scalars))", 256); classes: "match_$(scalars)" expression => strcmp("$(expected[$(scalars)])", "$(cat.$(scalars))"); "match_length_$(scalars)" expression => strcmp("$(expected_length[$(scalars)])", "$(actual_length[$(scalars)])"); "match_length_$(lists)" expression => strcmp("$(expected_length[$(lists)])", "$(actual_length[$(lists)])"); "ok" and => { "$(longclass)", "match_x4095", "match_length_x4095", "match_x4094", "match_length_x4094", "match_x4093", "match_length_x4093", "match_length_zshort", "match_length_z4095", }; reports: DEBUG:: "tail(256) of $(scalars) = $(tail[$(scalars)])"; "Got the long class, $(longclass_length) bytes" if => "$(longclass)"; "Did NOT get the long class, $(longclass_length) bytes" if => "!$(longclass)"; "Got the length for list $(lists): $(actual_length[$(lists)])" if => "match_length_$(lists)"; "Did NOT get the length for list $(lists): actual $(actual_length[$(lists)]) vs expected $(expected_length[$(lists)])" if => "!match_length_$(lists)"; "Got the length for scalar $(scalars): $(actual_length[$(scalars)])" if => "match_length_$(scalars)"; "Did NOT get the length for scalar $(scalars): actual $(actual_length[$(scalars)]) vs expected $(expected_length[$(scalars)])" if => "!match_length_$(scalars)"; "Got the long $(scalars), actual $(actual_length[$(scalars)]) bytes, actual tail($(scalars), 256) = $(tail[$(scalars)])" if => "match_$(scalars)"; "Did NOT get the long $(scalars), actual $(actual_length[$(scalars)]) bytes, actual tail($(scalars), 256) = $(tail[$(scalars)])" if => "!match_$(scalars)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 vars-without-explicit-tags-do-not-segfault.cf.sub0000644000000000000000000000037315010704253034146 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/01_modulesbundle agent main { vars: "my_var_in_policy" string => "my value in policy"; "tagged" slist => variablesmatching(".*", "my_tag"); commands: "/bin/echo" args => "=my_var_from_module= my val from module", module => "true"; }cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module_with_no_output.cf0000644000000000000000000000246315010704253027636 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent init { methods: "init" usebundle => file_make("$(G.testdir)/module.output.txt", "=myvar=good_output_1"); "init" usebundle => file_make("$(G.testdir)/module.no_output.txt", "=myvar=bad_output"); "init" usebundle => file_make("$(G.testdir)/module.default.txt", "=myvar=bad_output"); "init" usebundle => file_make("$(G.testdir)/no_module.output.txt", "=myvar=good_output_2"); "init" usebundle => file_make("$(G.testdir)/no_module.no_output.txt", "=myvar=bad_output"); "init" usebundle => file_make("$(G.testdir)/no_module.default.txt", "=myvar=good_output_3"); } bundle agent check { methods: "check" usebundle => dcs_passif_output(".*good_output_1.*good_output_2.*good_output_3.*", ".*bad_output.*", "$(sys.cf_agent) -D AUTO -Kf $(this.promise_filename).sub", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/004.cf0000644000000000000000000000417315010704253023505 0ustar00rootroot00000000000000####################################################### # # Test command modules # ####################################################### body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "script_name" string => "$(this.promise_filename).txt"; } ####################################################### bundle agent test { vars: !windows:: "cat_prefix" string => "cat"; windows:: "cat_prefix" string => "cat_exe"; commands: "$(G.cat) $(init.script_name)" contain => in_shell, module => "true"; } ####################################################### bundle agent check { vars: "list0" slist => {"abc", "def", "ghi"}; "list1" slist => {"{{abc}}", " ' def}", "ghi'''"}; "list2" slist => {'{{a,bc}}', ' " de,f}', 'gh,,i"""'}; "list3" slist => {"{{a'bc',,}}", ' ",, d"ef}', "ghi,},'''"}; "actual0" string => join(":", "list0"); "actual1" string => join(":", "list1"); "actual2" string => join(":", "list2"); "actual3" string => join(":", "list3"); "joined0" string => join(":", "$(test.cat_prefix).mylist"); "joined1" string => join(":", "$(test.cat_prefix).myalist"); "joined2" string => join(":", "$(test.cat_prefix).myblist"); "joined3" string => join(":", "$(test.cat_prefix).myclist"); classes: any:: "var0ok" expression => strcmp("${this.joined0}" , "${this.actual0}"); "var1ok" expression => strcmp("${this.joined1}" , "${this.actual1}"); "var2ok" expression => strcmp("${this.joined2}" , "${this.actual2}"); "var3ok" expression => strcmp("${this.joined3}" , "${this.actual3}"); "ok" and => { "var0ok", "var1ok", "var2ok", "var3ok" }; reports: !DEBUG:: "joined3 = [${this.joined3}] vs actual3 = [${this.actual3}]"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module_with_no_output.cf.sub0000644000000000000000000000143015010704253030417 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent test { commands: "$(G.cat) $(G.testdir)/module.output.txt" module => "true", contain => test_contain("false"); "$(G.cat) $(G.testdir)/module.no_output.txt" module => "true", contain => test_contain("true"); "$(G.cat) $(G.testdir)/module.default.txt" module => "true"; "$(G.cat) $(G.testdir)/no_module.output.txt" contain => test_contain("false"); "$(G.cat) $(G.testdir)/no_module.no_output.txt" contain => test_contain("true"); "$(G.cat) $(G.testdir)/no_module.default.txt"; } body contain test_contain(no_output) { no_output => "$(no_output)"; } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module-array-allows-slash.cf0000644000000000000000000000352315010704253030210 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2768" } string => "Test that arrays defined by modules can contain slashes just like classic arrays."; "test_soft_fail" string => "windows", meta => { "ENT-10257" }; commands: # Define a simple classic array using the module protocol. "$(G.echo)" args => "=array[key]=array_key_value", module => "true"; # Define a classic array where the key contains a backslash using the module protocol. "$(G.echo)" args => "=array[/path/key]=array_path_key_value", module => "true"; vars: # Define a classic array where the key contains a backslash. "array[/path/key]" string => "another_array_path_key_value"; #Find all the array entries defined by the module commands. "v" slist => variablesmatching("default:echo\.*array.*"); reports: DEBUG:: "Found variable '$(v)'"; } ####################################################### bundle agent check { vars: # Construct strings from the array values for comparison and test pass/fail "expected" string => "array_key_value array_path_key_value another_array_path_key_value"; "actual" string => "$(echo.array[key]) $(echo.array[/path/key]) $(test.array[/path/key])"; methods: "" usebundle => dcs_check_strcmp($(expected), $(actual), $(this.promise_filename), "no"); reports: DEBUG:: "module array[key] = '$(echo.array[key])'"; "module array[/path/key] = '$(echo.array[/path/key])'"; "classic array[/path/key] = '$(test.array[/path/key])'"; } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/001.cf.txt0000644000000000000000000000005515010704253024313 0ustar00rootroot00000000000000+CLASSTOBEDEFINED -UNDEFINEDCLASS =answer=42 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/003.cf.txt0000644000000000000000000000003115010704253024307 0ustar00rootroot00000000000000=myvar[dot.dash-test]=42 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/002.cf.txt0000644000000000000000000000003715010704253024314 0ustar00rootroot00000000000000=answer[42]=Yes =answer[41]=No cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module-array-allows-at.cf0000644000000000000000000000343715010704253027506 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-3099" } string => "Test that arrays defined by modules can contain @ just like classic arrays."; "test_soft_fail" string => "windows", meta => { "ENT-10257" }; commands: # Define a simple classic array using the module protocol. "$(G.echo)" args => "=array[key]=array_key_value", module => "true"; # Define a classic array where the key contains an @ using the module protocol. "$(G.echo)" args => "=array[key@1]=array_path_key_value", module => "true"; vars: # Define a classic array where the key contains an @. "array[key@1]" string => "another_array_path_key_value"; #Find all the array entries defined by the module commands. "v" slist => variablesmatching("default:echo\.*array.*"); reports: DEBUG:: "Found variable '$(v)'"; } ####################################################### bundle agent check { vars: # Construct strings from the array values for comparison and test pass/fail "expected" string => "array_key_value array_path_key_value another_array_path_key_value"; "actual" string => "$(echo.array[key]) $(echo.array[key@1]) $(test.array[key@1])"; methods: "" usebundle => dcs_check_strcmp($(expected), $(actual), $(this.promise_filename), "no"); reports: DEBUG:: "module array[key] = '$(echo.array[key])'"; "module array[key@1] = '$(echo.array[key@1])'"; "classic array[key@1] = '$(test.array[key@1])'"; } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module-array-indexing.cf.txt0000644000000000000000000000011615010704253030215 0ustar00rootroot00000000000000^context=arrays =foo[a]=a_foo =foo[b]=b_foo @foo_idx={"a","b"} +arrays_loaded cfengine-3.24.2/tests/acceptance/08_commands/01_modules/set-tags.cf0000644000000000000000000000736115010704253024733 0ustar00rootroot00000000000000####################################################### # # Test the ^meta module protocol extension # ####################################################### body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common init { vars: "script_name" string => "$(this.promise_filename).txt"; } ####################################################### bundle agent test { meta: "test_flakey_fail" string => "windows", meta => { "ENT-10257" }; commands: "$(G.cat) $(init.script_name)" contain => in_shell, module => "true"; } ####################################################### bundle agent check { vars: "xyzvars" slist => variablesmatching("default:xyz.*"); "list0" slist => {"abc", "def", "ghi"}; "list1" slist => {"{{abc}}", " ' def}", "ghi'''"}; "list2" slist => {'{{a,bc}}', ' " de,f}', 'gh,,i"""'}; "list3" slist => {"{{a'bc',,}}", ' ",, d"ef}', "ghi,},'''"}; "actual0" string => join(":", "list0"); "actual1" string => join(":", "list1"); "actual2" string => join(":", "list2"); "actual3" string => join(":", "list3"); "joined0" string => join(":", "xyz.mylist"); "joined1" string => join(":", "xyz.myalist"); "joined2" string => join(":", "xyz.myblist"); "joined3" string => join(":", "xyz.myclist"); "tags0" slist => getvariablemetatags("xyz.mylist"); "tags1" slist => getvariablemetatags("xyz.myalist"); "tags2" slist => getvariablemetatags("xyz.myblist"); "tags3" slist => getclassmetatags("mycclass"); "jtags0" string => join(",", "tags0"); "jtags1" string => join(",", "tags1"); "jtags2" string => join(",", "tags2"); "jtags3" string => join(",", "tags3"); "etags0" string => "xyz,abc=def,,\?\?what is this\?\?,source=module,derived_from=.*"; "etags1" string => "xyz,abc=def,,\?\?what is this\?\?,source=module,derived_from=.*"; "etags2" string => "1,2,3,source=module,derived_from=.*"; "etags3" string => "a,b,c,source=module,derived_from=.*"; classes: any:: "var0ok" expression => strcmp("${this.joined0}" , "${this.actual0}"); "var1ok" expression => strcmp("${this.joined1}" , "${this.actual1}"); "var2ok" expression => strcmp("${this.joined2}" , "${this.actual2}"); "var3ok" expression => strcmp("${this.joined3}" , "${this.actual3}"); "var4ok" expression => strcmp("hello there" , "${xyz.myvar}"); "tags0ok" expression => regcmp($(etags0), $(jtags0)); "tags1ok" expression => regcmp($(etags1), $(jtags1)); "tags2ok" expression => regcmp($(etags2), $(jtags2)); "tags3ok" expression => regcmp($(etags3), $(jtags3)); "ok" and => { "myclass", "var0ok", "var1ok", "var2ok", "var3ok", "var4ok", "tags0ok", "tags1ok", "tags2ok", "tags3ok", }; reports: DEBUG:: "xyzvars = $(xyzvars)"; "tags0ok => regcmp('$(etags0)', '$(jtags0)')" if => "tags0ok"; "tags1ok => regcmp('$(etags1)', '$(jtags1)')" if => "tags1ok"; "tags2ok => regcmp('$(etags2)', '$(jtags2)')" if => "tags2ok"; "tags3ok => regcmp('$(etags3)', '$(jtags3)')" if => "tags3ok"; "tags0 NOT ok => regcmp('$(etags0)', '$(jtags0)')" if => "!tags0ok"; "tags1 NOT ok => regcmp('$(etags1)', '$(jtags1)')" if => "!tags1ok"; "tags2 NOT ok => regcmp('$(etags2)', '$(jtags2)')" if => "!tags2ok"; "tags3 NOT ok => regcmp('$(etags3)', '$(jtags3)')" if => "!tags3ok"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/long-module-lines.cf.txt0000644000000000000000000026671615010704253027367 0ustar00rootroot00000000000000+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234 +123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 +class678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 +123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 -12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 -1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234 -123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 -12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012 =x=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 =x=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234 =x4095=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789x4095 =x4094=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef012345678x4094 =x4093=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567x4093 @y={ "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" } @z={ "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890" } @zshort={ "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890" } @z4096={ "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "12" } @z4095={ "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "" } %json=[ "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890" ] cfengine-3.24.2/tests/acceptance/08_commands/01_modules/set-persistent-class.cf0000644000000000000000000000240415010704253027271 0ustar00rootroot00000000000000####################################################### # # Test command modules # Redmine#7302: support persistent classes # ####################################################### body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; } bundle agent check { vars: "command" string => "($(sys.cf_agent) -Kvf $(this.promise_filename).sub; $(sys.cf_promises) -v)| $(G.grep) 'x4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP'"; methods: # sample output # verbose: Module set persistent class 'Cx4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP' for 20 minutes # verbose: Adding persistent class 'Cx4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP' to heap # note we check that Ax4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP and Bx4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP are not set persistently! "check" usebundle => dcs_passif_output(".*Module set persistent class 'Cx4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP' for 20 minutes.*", ".*Module set persistent class '[AB]x4eXfWrHT0zsSbrAXh5jFnRnDLKqNsP'.*", $(command), $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/002.cf0000644000000000000000000000241215010704253023475 0ustar00rootroot00000000000000####################################################### # # Test setting associative array in module (Issue 714) # ####################################################### body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "script_name" string => "$(this.promise_filename).txt"; } ####################################################### bundle agent test { vars: !windows:: "cat_prefix" string => "cat"; windows:: "cat_prefix" string => "cat_exe"; commands: "$(G.cat) $(init.script_name)" contain => in_shell, module => "true"; } ####################################################### bundle agent check { vars: "generated_indices" slist => getindices("$(test.cat_prefix).answer"); classes: "ok" and => { strcmp("${$(test.cat_prefix).answer[42]}", "Yes"), strcmp("${$(test.cat_prefix).answer[41]}", "No") }; reports: DEBUG:: "${$(test.cat_prefix).answer[${generated_indices}]}"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/08_commands/01_modules/classes-automatically-canonified.cf0000644000000000000000000000217215010704253031577 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" string => "Test that classes defined via the module protocol are automatically canonified."; classes: "my-invalid-class" expression => "any", scope => "namespace"; commands: "$(G.echo) +invalid-class@module" module => "true"; reports: (EXTRA|DEBUG).invalid_class_module:: "Class defined from module automatically canonified as expected"; (EXTRA|DEBUG).!invalid_class_module:: "Class defined from module NOT automatically canonified"; (EXTRA|DEBUG).my_invalid_class:: "My class was automatically canonified as expected"; (EXTRA|DEBUG).!my_invalid_class:: "My class was NOT automatically canonified"; } bundle agent check { classes: "pass" and => { "my_invalid_class", "invalid_class_module" }; reports: pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/08_commands/01_modules/module_allows_trailing_comma.cf.txt0000644000000000000000000000007215010704253031725 0ustar00rootroot00000000000000@list_from_module={ "list_element_with_trailing_comma", } vars-without-explicit-tags-do-not-segfault.cf0000644000000000000000000000202115010704253033346 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/01_modulesbody common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "ENT-7724", "ENT-7678" } string => "Test that vars defined by modules without explicit tags does not crash the agent when there are vars defined by the module protocol that do not have explicit tags defined."; "test_skip_unsupported" string => "windows", comment => "The subtest policy uses /bin/echo"; commands: "$(sys.cf_agent) -Kvf $(this.promise_filename).sub" classes => results( "namespace", "sub_agent"); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_passif_expected( "sub_agent_repaired", "sub_agent_not_kept", "$(this.promise_filename)"); reports: EXTRA|DEBUG:: "sub_agent_.* classes: $(with)" with => join( ",", classesmatching( "sub_agent_.*" )); } cfengine-3.24.2/tests/acceptance/08_commands/arglist.cf0000644000000000000000000000305415010704253022674 0ustar00rootroot00000000000000############################################################################## # # CFE-2724: Test that arglist attribute preserves white-spaces # ############################################################################## body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ############################################################################## bundle agent init { files: "$(G.testfile).actual" delete => tidy; "$(G.testfile).sh" perms => mog("700", "root", "root"), content => '#!/bin/sh for arg in "$(const.dollar)$(const.at)" do echo "$(const.dollar)arg" >> $(G.testfile).actual done'; } ############################################################################## bundle agent test { meta: "description" -> { "CFE-2724" } string => "Test that arglist attribute preserves white-spaces"; "test_skip_unsupported" string => "windows", comment => "See ticket CFE-4294"; commands: "$(G.testfile).sh" args => "one two three", arglist => { "four", "five six", " seven$(const.t)" }; } ############################################################################## bundle agent check { vars: "actual" string => readfile("$(G.testfile).actual"); "expected" string => "one two three four five six seven$(const.t) "; methods: "any" usebundle => dcs_check_strcmp("$(actual)", "$(expected)", "$(this.promise_filename)", "no"); } cfengine-3.24.2/tests/acceptance/08_commands/staging/0000755000000000000000000000000015010704253022347 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/staging/default_failed_returncodes.cf0000644000000000000000000000274515010704253030236 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { commands: "/bin/false" classes => scoped_classes_generic("namespace", "default"), comment => "Test that by default non zero commands return promise failure"; "/bin/false" classes => scoped_classes_generic_kept_0("namespace", "specify_kept"), comment => "Test that when specifying kept returncodes that failures are still registered"; } bundle agent check { methods: "report" usebundle => dcs_passif_expected("default_not_kept,specify_kept_not_kept", "", "$(this.promise_filename)") inherit => "true"; } body classes scoped_classes_generic_kept_0(scope, x) { scope => "$(scope)"; promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" }; kept_returncodes => { "0" }; #repaired_returncodes => { "2" }; #failed_returncodes => { "1" }; } cfengine-3.24.2/tests/acceptance/08_commands/02_syntax/0000755000000000000000000000000015010704253022542 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/02_syntax/arglist.cf.expected.json0000644000000000000000000000006215010704253027267 0ustar00rootroot00000000000000{ "abc": "2'3\"4", "def": "567 =ghi=8'9\"a" } cfengine-3.24.2/tests/acceptance/08_commands/02_syntax/arglist.cf0000644000000000000000000000175215010704253024526 0ustar00rootroot00000000000000####################################################### # # Test that arglist works properly # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; commands: "$(G.echo)" arglist => { "=abc=2'3\"4" }, module => "true"; # this will generate the command `echo =def=567 =ghi=8'9"a` "$(G.echo)" args => "=def=567", arglist => { "=ghi=8'9\"a" }, module => "true"; } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(echo, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/08_commands/02_syntax/staging/0000755000000000000000000000000015010704253024176 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/08_commands/02_syntax/staging/001.cf0000644000000000000000000000353615010704253025017 0ustar00rootroot00000000000000####################################################### # # Test that backslashes are correctly passed to commands (Issue 471) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", edit_defaults => empty, edit_line => setup_lines; } body edit_defaults empty { empty_file_before_editing => "true"; } bundle edit_line setup_lines { insert_lines: "a test"; "a.test"; "nottest"; } ####################################################### bundle agent test { vars: "all_lines" string => execresult("$(G.egrep) -c '.' $(G.testfile)", "useshell"); "re_lines" string => execresult("$(G.egrep) -c 'a.test' $(G.testfile)", "useshell"); "lit_lines" string => execresult("$(G.egrep) -c 'a\.test' $(G.testfile)", "useshell"); "doubleslash_lit_lines" string => execresult("$(G.egrep) -c 'a\\.test' $(G.testfile)", "useshell"); } ####################################################### bundle agent check { classes: "ok" and => { strcmp("$(test.all_lines)", "3"), strcmp("$(test.re_lines)", "2"), strcmp("$(test.lit_lines)", "1"), strcmp("$(test.doubleslash_lit_lines)", "1") }; reports: DEBUG:: "all_lines: $(test.all_lines) =?= 3"; "re_lines: $(test.re_lines) =?= 2"; "lit_lines: $(test.lit_lines) =?= 1"; "doubleslash_lit_lines: $(test.doubleslash_lit_lines) =?= 1"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 26 cfengine-3.24.2/tests/acceptance/20_meta/0000755000000000000000000000000015010704253020032 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/20_meta/this_bundle_meta_expands.cf0000644000000000000000000000477615010704253025412 0ustar00rootroot00000000000000####################################################### # # Test basics of meta promises # ####################################################### bundle common test_meta { vars: "description" string => "Can dereference meta vars."; } body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine7803" }; "string" string => "value"; "list" slist => { "element1", "element2" }; classes: "can_deref_this_bundle_meta_string" expression => strcmp("$($(this.bundle)_meta.string)", "value"); "can_deref_direct_meta_list_element1" #expression => strcmp("$($(this.bundle)_meta.list)", "element1"); expression => strcmp("$(check_meta.list)", "element1"); "can_deref_direct_meta_list_element2" #expression => strcmp("$($(this.bundle)_meta.list)", "element2"); expression => strcmp("$(check_meta.list)", "element2"); "can_deref_this_bundle_meta_list_element1" expression => strcmp("$($(this.bundle)_meta.list)", "element1"); "can_deref_this_bundle_meta_list_element2" expression => strcmp("$($(this.bundle)_meta.list)", "element2"); "ok" and => { "can_deref_this_bundle_meta_string", "can_deref_direct_meta_list_element1", "can_deref_direct_meta_list_element2", "can_deref_this_bundle_meta_list_element1", "can_deref_this_bundle_meta_list_element2", }; reports: DEBUG:: "DEBUG $(this.bundle): meta var = '$($(this.bundle)_meta.string)'"; "DEBUG $(this.bundle): meta list direct = '$(check_meta.list)'"; "DEBUG $(this.bundle): meta list this.bundle = '$($(this.bundle)_meta.list)'"; "DEBUG $(this.bundle): Can't dereference meta string var with this.bundle" unless => "can_deref_this_bundle_meta_string"; "DEBUG $(this.bundle): Can't dereference meta list directly" unless => "can_deref_direct_meta_list_element1.can_deref_direct_meta_list_element2"; "DEBUG $(this.bundle): Can't dereference meta list with this.bundle" unless => "can_deref_this_bundle_meta_list_element1.can_deref_this_bundle_meta_list_element2"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/20_meta/basic.cf0000644000000000000000000000314115010704253021424 0ustar00rootroot00000000000000####################################################### # # Test basics of meta promises # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { meta: "s" string => "Wally Walleye"; "l" slist => { "Be", "Hg", "Pb" }; "c" data => parsejson(' { "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null } '); } bundle agent check { vars: "actual[s]" string => $(test_meta.s); "actual[l]" string => format("%S", "test_meta.l"); "actual[c]" string => format("%S", "test_meta.c"); "expected[s]" string => "Wally Walleye"; "expected[l]" string => '{ "Be", "Hg", "Pb" }'; "expected[c]" string => '{ "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null }'; "tests" slist => getindices(expected); classes: "ok_$(tests)" expression => strcmp("$(actual[$(tests)])", "$(expected[$(tests)])"); "ok_$(tests)" not => strcmp("$(actual[$(tests)])", "$(expected[$(tests)])"); "ok" and => { "ok_s", "ok_l", "ok_c" }; reports: DEBUG:: "OK: $(tests) got $(actual[$(tests)])" if => "ok_$(tests)"; "FAIL: $(tests) got $(actual[$(tests)]) != $(expected[$(tests)])" if => "not_ok_$(tests)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/xml-c14nize.c0000644000000000000000000000205415010704253021023 0ustar00rootroot00000000000000#include #include #include #include static bool xmlC14nizeFile(const char *filename) { xmlDocPtr doc = xmlParseFile(filename); if (doc == NULL) { fprintf(stderr, "Unable to open %s for canonicalization\n", filename); return false; } xmlOutputBufferPtr out = xmlOutputBufferCreateFile(stdout, NULL); if (out == NULL) { fprintf(stderr, "Unable to set up writer for stdout\n"); return false; } if (xmlC14NDocSaveTo(doc, NULL, XML_C14N_1_0, 0, true, out) < 0) { fprintf(stderr, "Unable to c14nize XML document\n"); return false; } if (xmlOutputBufferClose(out) < 0) { fprintf(stderr, "Unable to close writer for stdout\n"); return false; } xmlFreeDoc(doc); return true; } int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: xml-c14nize \n"); return 2; } return xmlC14nizeFile(argv[1]) ? 0 : 1; } cfengine-3.24.2/tests/acceptance/04_examples/0000755000000000000000000000000015010704253020724 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/04_examples/outputs/0000755000000000000000000000000015010704253022447 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/04_examples/outputs/check_outputs.cf0000644000000000000000000000447715010704253025655 0ustar00rootroot00000000000000####################################################### # # Check the example outputs # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { vars: "basedir" string => "$(G.cwd)/../../examples"; "checker" string => "$(basedir)/remake_outputs.pl"; "all_examples" slist => findfiles("$(basedir)/*.cf"); reports: DEBUG_LOTS:: "$(this.bundle): will consider example $(all_examples)"; } ####################################################### bundle agent test { meta: # It's unrealistic to keep this test perfectly stable on all non-Linux platforms. # It would require examples that quickly get very cluttered. "test_skip_unsupported" string => "!linux"; vars: "examples" slist => { @(init.all_examples) }; "canon[$(examples)]" string => canonify($(examples)); classes: "has_output_block_$(canon[$(examples)])" expression => regline(".*example_output.*", $(examples)); methods: "$(examples)" usebundle => test_example($(examples)), if => "has_output_block_$(canon[$(examples)])"; reports: DEBUG:: "$(this.bundle): found example with output $(examples)" if => "has_output_block_$(canon[$(examples)])"; } bundle agent test_example(file) { vars: "cfile" string => canonify($(file)); "checker" string => "$(G.perl) $(init.checker) --cfagent=$(sys.cf_agent) --workdir=$(G.testdir) -c"; classes: "failure_$(cfile)" not => returnszero("$(checker) $(file)", "noshell"), scope => "namespace"; methods: "with verbose" usebundle => verbose_output("$(checker) -v $(file)"), if => "failure_$(cfile)"; reports: "$(this.bundle): checker '$(checker) $(file)' returned error" if => "failure_$(cfile)"; DEBUG:: "$(this.bundle): ran checker '$(checker) $(file)'"; } bundle agent verbose_output(runme) { commands: "$(runme)"; } ####################################################### bundle agent check { classes: "ok" not => classmatch("failure.*"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/04_examples/mock_stdlib.cf0000644000000000000000000000506615010704253023537 0ustar00rootroot00000000000000# Mock version of stdlib.cf , paths.cf etc. from masterfiles. # This just defines some empty bodies and bundles which are necessary # for cf-promises to run on all the examples in core. There is currently no # way to make cf-promises validate the syntax of a single file, without # opening inputs. # # NOTE: Syntax doesn't allow empty body, but body with 1 class guard is OK # NOTE: It would be nice if this was auto-generated, but it isn't, # just add another body / bundle if you need to use it in an example. body package_method yum {} body package_method generic {} body classes enumerate(x) {} body perms p(user,mode) {} body changes tripwire {} body depth_search recurse(d) {} body delete tidy {} body file_select days_old(days) {} body edit_defaults empty {} body acl ntfs(acl) {} body action if_elapsed(x) {} body action warn_only {} body classes if_ok(x) {} body classes if_repaired(x) {} body contain setuid(owner) {} body copy_from local_cp(from) {} body copy_from remote_cp(from, server) {} body copy_from secure_cp(from,server) {} body depth_search include_base {} body package_method solaris(pkgname, spoolfile, adminfile) {} body package_method zypper {} body perms mo(mode, user) {} body perms mog(mode, user, group) {} body perms owner(user) {} body rename disable {} body rename rotate(level) {} body rename to(file) {} body replace_with value(x) {} body acl strict {} body changes detect_content {} body classes if_else (yes, no) {} body contain in_shell {} body copy_from remote_dcp(from,server) {} body package_method msi_explicit(repo) {} body package_method msi_implicit(repo) {} bundle edit_line insert_lines(lines) {} bundle edit_line append_if_no_line(lines) {} bundle edit_line prepend_if_no_line(string) {} bundle edit_line append_user_field(group,field,allusers) {} bundle edit_line set_user_field(user,field,val) {} bundle agent package_absent(package) {} bundle agent package_present(package) {} bundle agent package_latest(package) {} bundle agent package_specific_present(packageorfile, package_version, package_arch) {} bundle agent package_specific_latest(packageorfile, package_version, package_arch) {} bundle edit_xml xml_insert_tree_nopath(treestring) {} bundle edit_xml xml_set_value(value, xpath) {} bundle edit_xml xml_set_attribute(attr, value, xpath) {} bundle edit_line set_variable_values(v) {} bundle edit_line expand_template(templatefile) {} bundle edit_line create_solaris_admin_file {} bundle common paths {} # This "test" always passes, it is meant to be included from examples: bundle agent __main__ { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/04_examples/README.org0000644000000000000000000030344315010704253022401 0ustar00rootroot00000000000000#+Title: Testing Examples This is the place to have examples in =core/examples= tested. * Outputs Before running a test the optional commands found between =#+begin_src prep= and =#+end_src= are run to prepare the environment for the test. This is commonly used to prepare files for the example to operate on. The =outputs= test checks to see that the output generated by the test is correct as compared with the content between the =#+begin_src example_output= and =#+end_src= tags. *NOTE:* Agent output should be *identical* between a normal execution and a dry run. This means that some examples are poor candidates for automatic testing. =prep= sections can not handle /heredoc/, so don't try to use them to setup an environment, instead, use echo to build up a file. #+CAPTION: Example error showing issue with usage of heredoc in prep #+begin_example Q: "...r/bin/perl /hom": processing /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/execresult.cf: Running prep 'EOF'Can't exec "EOF": No such file or directory at /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl line 227. #+end_example So, don't do this: #+CAPTION: BAD: example using heredoc inside prep section #+begin_example ,#+begin_src prep #@ ``` #@ rm -rf /tmp/testhere #@ mkdir -p /tmp/testhere #@ touch /tmp/testhere/a #@ touch /tmp/testhere/b #@ touch /tmp/testhere/c #@ touch /tmp/testhere/d #@ touch /tmp/testhere/e #@ cat << EOF >/tmp/testhere/echo-stdout-and-stderr #@ #!/usr/bin/env sh #@ echo stderr >&2 #@ echo stdout #@ EOF #@ chmod +x /tmp/testhere/echo-stdout-and-stderr #@ ``` ,#+end_src #+end_example Instead, do this: #+CAPTION: GOOD example using echo instead of heredoc during setup #+begin_example ,#+begin_src prep #@ ``` #@ rm -rf /tmp/testhere #@ mkdir -p /tmp/testhere #@ touch /tmp/testhere/a #@ touch /tmp/testhere/b #@ touch /tmp/testhere/c #@ touch /tmp/testhere/d #@ touch /tmp/testhere/e #@ echo "#!/usr/bin/env sh" >/tmp/testhere/echo-stdout-and-stderr #@ echo "echo stderr >&2" >>/tmp/testhere/echo-stdout-and-stderr #@ echo "echo stdout" >>/tmp/testhere/echo-stdout-and-stderr #@ chmod +x /tmp/testhere/echo-stdout-and-stderr #@ ``` ,#+end_src #+end_example ** Troubleshooting Outputs Test Failures This section is primarily intended for CFEngine Staff as not all build output is publicly available. It is *very* important for the examples output to be consistent or it will result in a failed test. Example test failures are somewhat opaque and can be difficult to troubleshoot. A failure will look like this in the build system: #+BEGIN_EXAMPLE 00:13:23.974 ./04_examples/outputs/check_outputs.cf FAIL (UNEXPECTED FAILURE) #+END_EXAMPLE *Note:* The specific example that failed is not immediately apparent. You must wait for the job to finish and then drill into the test results. Where you might be looking for something like this: #+BEGIN_EXAMPLE error: Finished command related to promiser "/usr/bin/perl /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c -v /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/multiple_outcomes.cf" -- an error occurred, returned 1 notice: Q: "...r/bin/perl /hom": Test file: /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/multiple_outcomes.cf Q: "...r/bin/perl /hom": Command: "/home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" -D_cfe_output_testing -nKf /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine/multiple_outcomes.cf 2>&1 Q: "...r/bin/perl /hom": NEW OUTPUT: [[[ warning: Warning promised, need to create file "/tmp/repaired_and_not_kept.txt" Q: "...r/bin/perl /hom": R: My promise was not kept because the template failed to render. Q: "...r/bin/perl /hom": R: Found class: "outcome_failed" Q: "...r/bin/perl /hom": R: Found class: "outcome_not_kept" Q: "...r/bin/perl /hom": R: Found class: "outcome_error" Q: "...r/bin/perl /hom": R: Found class: "outcome_reached" Q: "...r/bin/perl /hom": ]]] Q: "...r/bin/perl /hom": --- /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine/multiple_outcomes.cf.a 2016-04-12 16:16:28.247136634 +0200 Q: "...r/bin/perl /hom": +++ /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine/multiple_outcomes.cf.b 2016-04-12 16:16:28.247136634 +0200 Q: "...r/bin/perl /hom": @@ -1,10 +1,6 @@ Q: "...r/bin/perl /hom": -error: Template file "$(this.promsie_filename).broken_mustache" could not be opened for reading Q: "...r/bin/perl /hom": -R: My promise was repaired because the file was created. Q: "...r/bin/perl /hom": +warning: Warning promised, need to create file "/tmp/repaired_and_not_kept.txt" Q: "...r/bin/perl /hom": R: My promise was not kept because the template failed to render. Q: "...r/bin/perl /hom": -R: My promise was kept because the permissions were as desired. Q: "...r/bin/perl /hom": R: Found class: "outcome_failed" Q: "...r/bin/perl /hom": -R: Found class: "outcome_repaired" Q: "...r/bin/perl /hom": -R: Found class: "outcome_error" Q: "...r/bin/perl /hom": R: Found class: "outcome_not_kept" Q: "...r/bin/perl /hom": +R: Found class: "outcome_error" Q: "...r/bin/perl /hom": R: Found class: "outcome_reached" Q: "...r/bin/perl /hom": -R: Found class: "outcome_kept" Q: "...r/bin/perl /hom": /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/multiple_outcomes.cf: output differs from original... error: Method "verbose_output" failed in some repairs R: test_example: checker "/usr/bin/perl /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/multiple_outcomes.cf" returned error R: test_example: ran checker "/usr/bin/perl /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/jenkins/workspace/testing-enterprise-pr_core/label/PACKAGES_x86_64_linux_redhat_6/core/tests/acceptance/../../examples/multiple_outcomes.cf" error: Method "test_example" failed in some repairs #+END_EXAMPLE Note how in the above the test failed because of differing output. In this specific case, the differences are due to some difference in output between a normal run and a dry-run where warnings are promised. #+Caption: Execute the example outputs tests with the system installed cfengine #+NAME: test_check_outputs #+BEGIN_SRC sh :dir ../ :results output :exports both ./testall --jobs=4 \ --printlog \ --bindir=/var/cfengine/bin/ \ ./04_examples/outputs/check_outputs.cf 2>&1 #+END_SRC #+NAME: Testing classfiltercsv() #+CALL: test_check_outputs() :DRAWER: #+RESULTS: Example Testing classfiltercsv() #+begin_example ====================================================================== Testsuite started at 2019-04-13 18:40:54 ---------------------------------------------------------------------- Total tests: 1 COMMON_TESTS: enabled TIMED_TESTS: enabled SLOW_TESTS: enabled ERROREXIT_TESTS: enabled SERIAL_TESTS: enabled NETWORK_TESTS: enabled LIBXML2_TESTS: enabled LIBCURL_TESTS: enabled UNSAFE_TESTS: disabled STAGING_TESTS: disabled Test run is PARALLEL with MAKEFLAGS= --jobs=4 ./04_examples/outputs/check_outputs.cf Pass ====================================================================== Testsuite finished at 2019-04-13 18:41:03 (9 seconds) Passed tests: 1 Failed tests: 0 Skipped tests: 0 Soft failures: 0 Total tests: 1 ====================================================================== Testsuite started at 2019-04-13 18:40:54 ---------------------------------------------------------------------- Total tests: 1 COMMON_TESTS: enabled TIMED_TESTS: enabled SLOW_TESTS: enabled ERROREXIT_TESTS: enabled SERIAL_TESTS: enabled NETWORK_TESTS: enabled LIBXML2_TESTS: enabled LIBCURL_TESTS: enabled UNSAFE_TESTS: disabled STAGING_TESTS: disabled Test run is PARALLEL with MAKEFLAGS= --jobs=4 ---------------------------------------------------------------------- ./04_examples/outputs/check_outputs.cf ---------------------------------------------------------------------- R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/file_hash.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filesize.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/lsdir.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_replace.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readrealarray.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_upcase.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_tail.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getvariablemetatags.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/classfiltercsv.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/with.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/parseintrealstringarray.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_multiline_json.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/ago.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/peers.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filter.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_reverse.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/kill_process_running_wrong_user.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getvalues.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/bundlesequence.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/classmatch.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/islessthan.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/data_regextract.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/maplist.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/bundlesmatching.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/appgroups.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readfile.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_classes.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_non_empty_list.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/diskfree.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/data_readstringarray.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getindices.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/returnszero.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/container_key_iteration.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/lastnode.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regarray.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/hash.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_downcase.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filestat.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/main_library.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_top.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/datastate.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getfields.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mergedata.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regline.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isnewerthan.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/augment.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readintarray.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/format.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getgid.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/strftime.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_split.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_expand_key.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/sublist.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/compare.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/variablesmatching_as_data.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/reverse.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readdata.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/intersection.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regex_replace.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/quoting.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/max-min-mean-variance.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/randomint.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/islink.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/ip2host.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/execresult.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/class-automatic-canonificiation.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readstringarray.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/main.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/canonify.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/join.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/every.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/escape.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/container_iteration.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getenv.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getusers.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/maparray.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/difference.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/classesmatching.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readenvfile.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regextract.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/dirname.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/data_expand.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/userexists.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_set_delimiters.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/splitstring.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/missing_ok.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/groupexists.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getclassmetatags.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_mustache.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_empty_list.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/peerleaders.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/peerleader.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_compact_json.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/none.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/bundlestate.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/length.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/countlinesmatching.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/multiple_outcomes.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/nth.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/product.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isplain.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/some.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/accessedbefore.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/select_region.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filesexist.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_inverted.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/variablesmatching.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mapdata.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/grep.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isdir.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/unique.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/parsestringarrayidx.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isgreaterthan.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/main_entry_point.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readcsv.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readintrealstringlist.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/hash_to_int.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/defaults.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getuid.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isvariable.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/countclassesmatching.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_head.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/fileexists.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/registryvalue.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/findfiles.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_non_false_value.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isipinsubnet.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_length.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_comments.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/translatepath.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/strcmp.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isexecutable.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/shuffle.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/sum.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/reglist.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_variables.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regcmp.cf' R: test_example: ran checker '/usr/bin/perl /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/remake_outputs.pl --cfagent="/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/bin/cf-agent" --workdir=/home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/workdir/__04_examples_outputs_check_outputs_cf/tmp/TESTDIR.cfengine -c /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/services_default_service_bundle.cf' R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/file_hash.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filesize.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/lsdir.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_replace.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readrealarray.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_upcase.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_tail.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getvariablemetatags.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/classfiltercsv.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/with.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/parseintrealstringarray.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_multiline_json.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/ago.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/peers.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filter.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_reverse.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/kill_process_running_wrong_user.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getvalues.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/bundlesequence.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/classmatch.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/islessthan.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/data_regextract.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/maplist.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/bundlesmatching.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/appgroups.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readfile.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_classes.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_non_empty_list.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/diskfree.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/data_readstringarray.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getindices.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/returnszero.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/container_key_iteration.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/lastnode.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regarray.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/hash.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_downcase.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filestat.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/main_library.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_top.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/datastate.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getfields.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mergedata.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regline.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isnewerthan.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/augment.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readintarray.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/format.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getgid.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/strftime.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_split.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_expand_key.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/sublist.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/compare.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/variablesmatching_as_data.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/reverse.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readdata.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/intersection.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regex_replace.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/quoting.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/max-min-mean-variance.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/randomint.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/islink.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/ip2host.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/execresult.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/class-automatic-canonificiation.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readstringarray.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/main.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/canonify.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/join.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/every.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/escape.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/container_iteration.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getenv.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getusers.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/maparray.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/difference.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/classesmatching.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readenvfile.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regextract.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/dirname.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/data_expand.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/userexists.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_set_delimiters.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/splitstring.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/missing_ok.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/groupexists.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getclassmetatags.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_mustache.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_empty_list.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/peerleaders.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/peerleader.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_extension_compact_json.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/none.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/bundlestate.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/length.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/countlinesmatching.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/multiple_outcomes.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/nth.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/product.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isplain.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/some.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/accessedbefore.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/select_region.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/filesexist.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_inverted.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/variablesmatching.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mapdata.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/grep.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isdir.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/unique.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/parsestringarrayidx.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isgreaterthan.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/main_entry_point.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readcsv.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/readintrealstringlist.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/hash_to_int.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/defaults.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/getuid.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isvariable.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/countclassesmatching.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_head.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/fileexists.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/registryvalue.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/findfiles.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_sections_non_false_value.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isipinsubnet.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/string_length.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_comments.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/translatepath.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/strcmp.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/isexecutable.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/shuffle.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/sum.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/reglist.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/mustache_variables.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/regcmp.cf R: test: found example with output /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/../../examples/services_default_service_bundle.cf R: /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/./04_examples/outputs/check_outputs.cf Pass Return code is 0. ==> Pass ====================================================================== Testsuite finished at 2019-04-13 18:41:03 (9 seconds) Passed tests: 1 Failed tests: 0 Skipped tests: 0 Soft failures: 0 Total tests: 1 #+end_example :END: cfengine-3.24.2/tests/acceptance/04_examples/syntax/0000755000000000000000000000000015010704253022252 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/04_examples/syntax/check_syntax.cf0000644000000000000000000001050015010704253025243 0ustar00rootroot00000000000000####################################################### # # Check the syntax of all examples in examples directory # # Is this test failing? If you added an example, make sure you add the # necessary bodies/bundles to mock_stdlib.cf # To find out which example is failing, run in tests/acceptance: # $ ./testall 04_examples/syntax/check_syntax.cf ; less test.log # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { vars: "basedir" string => "$(G.cwd)/../../examples"; "all_examples" slist => findfiles("$(basedir)/*.cf"); "stdlib" string => "$(G.testdir)/inputs/lib/stdlib.cf"; "mock" string => "$(this.promise_dirname)/../mock_stdlib.cf"; methods: "stdlib_symlink" usebundle => lib_maybe_symlink( "$(mock)", "$(G.testdir)/inputs/lib/stdlib.cf"); "paths_symlink" usebundle => lib_maybe_symlink( "$(mock)", "$(G.testdir)/inputs/lib/paths.cf"); "users_symlink" usebundle => lib_maybe_symlink( "$(mock)", "$(G.testdir)/inputs/lib/users.cf"); "services_symlink" usebundle => lib_maybe_symlink( "$(mock)", "$(G.testdir)/inputs/lib/services.cf"); "packages_symlink" usebundle => lib_maybe_symlink( "$(mock)", "$(G.testdir)/inputs/lib/packages.cf"); "commands_symlink" usebundle => lib_maybe_symlink( "$(mock)", "$(G.testdir)/inputs/lib/commands.cf"); "files_symlink" usebundle => lib_maybe_symlink( "$(mock)", "$(G.testdir)/inputs/lib/files.cf"); DEBUG_LOTS:: "$(this.bundle): will consider example $(all_examples)"; } bundle agent lib_maybe_symlink(src, dst) # Symlink a file, only if dst does not exist # If dst already exists, assume it's correct (testing with masterfiles) { classes: "file_missing" if => not(fileexists("$(dst)")); methods: file_missing:: "symlink" usebundle => symlink("$(src)", "$(dst)"); } bundle agent symlink(src, dst) { vars: "dir" string => dirname("$(dst)"); files: "$(dir)/." create => "true"; "$(dst)" link_from => ln_s("$(src)"); } body link_from ln_s(x) { link_type => "symlink"; source => "$(x)"; } ####################################################### bundle agent test { meta: # It's unrealistic to keep this test perfectly stable on all non-Linux platforms. # It would require examples that quickly get very cluttered. "test_skip_unsupported" string => "!linux"; "description" string => "Syntax check each policy (.cf) file in examples"; vars: "examples" slist => { @(init.all_examples) }; "canon[$(examples)]" string => canonify($(examples)); methods: "$(examples)" usebundle => test_example($(examples)); reports: DEBUG:: "$(this.bundle): found example with output $(examples)" if => "has_output_block_$(canon[$(examples)])"; } bundle agent test_example(file) { vars: "cfile" string => canonify($(file)); "checker" # -c option is omitted, because it enforces bundlesequence / main string => "$(sys.cf_promises) --workdir=$(G.testdir)"; classes: "failure_$(cfile)" not => returnszero("$(checker) $(file)", "noshell"), scope => "namespace"; reports: DEBUG:: "Syntax error in example: '$(file)'" if => "failure_$(cfile)", handle => "reported_error_$(cfile)"; methods: "verbose_$(cfile)" usebundle => run_with_output("$(checker) $(file)"), if => "failure_$(cfile)", depends_on => { "reported_error_$(cfile)" }; } bundle agent run_with_output(runme) # This bundle is only used in case of failure # It reruns a command, as a commands promise, which will show the output # from the failing cf-promises command. { vars: "c" string => canonify("$(runme)"); reports: "Running: $(runme)" handle => "printed_$(c)"; commands: "$(runme)" depends_on => { "printed_$(c)" }; } ####################################################### bundle agent check { classes: "ok" not => classmatch("failure_.*"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/29_simulate_mode/0000755000000000000000000000000015010704253021744 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/29_simulate_mode/simulate_safe_functions.cf.sub0000644000000000000000000000324715010704253027765 0ustar00rootroot00000000000000body common control { inputs => { "../plucked.cf.sub" }; } bundle agent test { vars: "unsafe_functions" slist => { "execresult", "execresult_as_data", "returnszero", "usemodule" }; "test_1" string => execresult("touch $(sys.statedir)$(const.dirsep)execresult_safe", useshell), meta => { "simulate_safe" }; "test_2" string => execresult("touch $(sys.statedir)$(const.dirsep)execresult_unsafe", useshell); "test_3" data => execresult_as_data("touch $(sys.statedir)$(const.dirsep)execresult_as_data_safe", useshell), meta => { "simulate_safe" }; "test_4" data => execresult_as_data("touch $(sys.statedir)$(const.dirsep)execresult_as_data_unsafe", useshell); classes: "test_5" expression => returnszero("touch $(sys.statedir)$(const.dirsep)returnszero_safe", useshell), meta => { "simulate_safe" }; "test_6" expression => returnszero("touch $(sys.statedir)$(const.dirsep)returnszero_unsafe", useshell); "test_7" expression => usemodule("usemodule_safe.sh", useshell), meta => { "simulate_safe" }; "test_8" expression => usemodule("usemodule_unsafe.sh", useshell); } bundle agent check { classes: "pass_$(test.unsafe_functions)" expression => not(fileexists("$(sys.statedir)$(const.dirsep)$(test.unsafe_functions)_unsafe")); "fail_$(test.unsafe_functions)" expression => fileexists("$(sys.statedir)$(const.dirsep)$(test.unsafe_functions)_unsafe"); reports: "$(this.promise_filename) FAIL" if => classmatch("fail_.*"); "$(this.promise_filename) Pass" if => strcmp(countclassesmatching("fail.*"), 0); } bundle agent __main__ { methods: "init"; "test"; "check"; } cfengine-3.24.2/tests/acceptance/29_simulate_mode/promises.cf.sub0000644000000000000000000000566015010704253024716 0ustar00rootroot00000000000000bundle common simulation_files_promises { vars: "inputs" slist => { "$(this.promise_dirname)/../default.cf.sub" }; } body common control { inputs => { "@(simulation_files_promises.inputs)" }; } bundle agent init { files: "$(G.testroot)$(const.dirsep)source-file" create => "true", content => "These are my source file contents."; } bundle agent test { methods: "hardlink" usebundle => file_hardlink("$(G.testroot)$(const.dirsep)already-created", "$(G.testroot)$(const.dirsep)hardlink"); "link" usebundle => file_link("$(G.testroot)$(const.dirsep)already-created", "$(G.testroot)$(const.dirsep)link"); files: "$(G.testroot)$(const.dirsep)already-created" create => "true"; "$(G.testroot)$(const.dirsep)create-true" create => "true"; "$(G.testroot)$(const.dirsep)insert-lines" create => "true", edit_line => insert_lines("foobar"); "$(G.testroot)$(const.dirsep)SUBDIR/." create => "true"; "$(G.testroot)$(const.dirsep)copy-from" copy_from => example("$(G.testroot)$(const.dirsep)source-file"); "$(G.testroot)$(const.dirsep)delete-me" delete => tidy; "$(G.testroot)$(const.dirsep)sub-dir/." delete => tidy, file_select => all, depth_search => recurse("inf"); "$(G.testroot)$(const.dirsep)set-colon-field" edit_line => set_colon_field("me","6","/my/new/shell"); "$(G.testroot)$(const.dirsep)delete-lines-matching" edit_line => delete_lines_matching("foo 1"); "$(G.testroot)$(const.dirsep)regex-replace" edit_line => regex_replace("foo","FOO!"); "$(G.testroot)$(const.dirsep)edit-template-string" template_method => "inline_mustache", edit_template_string => "{{{name}}} killed your father", template_data => '{ "name": "Darth Vader" }'; "$(G.testroot)$(const.dirsep)build-xpath" edit_xml => build_xpath("/Server/Service/Engine/Host"); "$(G.testroot)$(const.dirsep)xml-insert-tree" edit_xml => xml_insert_tree("y", "//Root"); "$(G.testroot)$(const.dirsep)perms" perms => m(000); "$(G.testroot)$(const.dirsep)rename-me" rename => newname("rename-newname"); "$(G.testroot)$(const.dirsep)transformer" transformer => "$(G.gzip) $(this.promiser)"; } # TODO list the contents of the chroot so we can see transformer.gz for example? #bundle agent check #{ # vars: # "result" string => execresult("$(G.ls) -laR $(sys.workdir)/state/", "noshell"), # meta => { "simulate_safe" }; # reports: # "chroot files: $(result)"; #} bundle agent main { methods: "init"; "test"; # "check"; } body copy_from example(from) { source => "$(from)"; compare => "digest"; preserve => "true"; } bundle edit_xml xml_insert_tree(treestring, xpath) { insert_tree: '$(treestring)' select_xpath => "$(xpath)"; } bundle edit_xml build_xpath(xpath) { build_xpath: "$(xpath)"; } body rename newname(name) { newname => "$(name)"; } cfengine-3.24.2/tests/acceptance/29_simulate_mode/prepare_files_for_simulate_tests.cf.sub0000644000000000000000000000251315010704253031662 0ustar00rootroot00000000000000bundle agent prepare_files_for_simulate_tests { files: "$(G.testroot)$(const.dirsep)already-created" create => "true"; "$(G.testroot)$(const.dirsep)delete-me" create => "true"; "$(G.testroot)$(const.dirsep)sub-dir/." create => "true"; "$(G.testroot)$(const.dirsep)sub-dir/sub-file" create => "true"; "$(G.testroot)$(const.dirsep)set-colon-field" create => "true", content => "me:x:1001:1001::/home/me:/bin/sh"; "$(G.testroot)$(const.dirsep)delete-lines-matching" create => "true", content => " foo 1 bar 2 baz 3 me:x:101:doo "; "$(G.testroot)$(const.dirsep)regex-replace" create => "true", content => "I dare you to change my policy foo"; "$(G.testroot)$(const.dirsep)edit-template-string" create => "true", content => "From a particular point of view"; "$(G.testroot)$(const.dirsep)xml-insert-tree" create => "true", edit_xml => xml_insert_tree_nopath(""); "$(G.testroot)$(const.dirsep)build-xpath" create => "true"; "$(G.testroot)$(const.dirsep)perms" create => "true"; "$(G.testroot)$(const.dirsep)rename-me" create => "true"; "$(G.testroot)$(const.dirsep)transformer" create => "true"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } cfengine-3.24.2/tests/acceptance/29_simulate_mode/manifest_mode.cf0000644000000000000000000000303515010704253025071 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub", "./prepare_files_for_simulate_tests.cf.sub", "./normalize_agent_output.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: "prepare_files_for_simulate_tests"; } bundle agent test { meta: "test_soft_fail" string => "(solaris|aix|hpux|windows)", meta => { "ENT-6540,ENT-10254" }; # ENT-6540 exotics fail to delete chroot # ENT-10254 tests fail on Windows due to CRLF "description" -> { "ENT-5301" } string => "Test that files promises in --simulate=manifest mode produce proper output and only make changes in chroot"; commands: # add --verbose here and look at the .actual log for debugging sub policy runs "$(sys.cf_agent) -Kf $(this.promise_dirname)$(const.dirsep)promises.cf.sub --simulate=manifest > $(this.promise_filename).temp 2>&1" contain => in_shell, comment => "Run sub policy in manifest mode and capture output to $(this.promise_filename).actual file."; } bundle agent check { methods: "normalize_agent_results" usebundle => normalize_agent_results("$(this.promise_filename).temp", "$(this.promise_filename).actual"); "check" usebundle => dcs_check_diff("$(this.promise_filename).actual", "$(this.promise_filename).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/29_simulate_mode/diff_mode.cf.expected0000644000000000000000000001034315010704253025773 0ustar00rootroot00000000000000 warning: All changes in files will be made in the 'WORKDIR/state/PID.changes' chroot =========================================================================== 'WORKDIR/tmp/rename-newname' is the new name of 'WORKDIR/tmp/rename-me' =========================================================================== 'WORKDIR/tmp/source-file' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: These are my source file contents. \no newline at the end of file =========================================================================== 'WORKDIR/tmp/create-true' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/insert-lines' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: foobar =========================================================================== 'WORKDIR/tmp/SUBDIR' is a directory Size: SIZE Access: (0700/rwx------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Directory contents: =========================================================================== 'WORKDIR/tmp/copy-from' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: These are my source file contents. \no newline at the end of file =========================================================================== 'WORKDIR/tmp/delete-me' no longer exists =========================================================================== 'WORKDIR/tmp/sub-dir/./sub-file' no longer exists =========================================================================== Only in WORKDIR/tmp/sub-dir/.: sub-file =========================================================================== --- original WORKDIR/tmp/set-colon-field +++ changed WORKDIR/tmp/set-colon-field @@ -1 +1 @@ -me:x:1001:1001::/home/me:/bin/sh \ No newline at end of file +me:x:1001:1001::/my/new/shell:/bin/sh =========================================================================== --- original WORKDIR/tmp/delete-lines-matching +++ changed WORKDIR/tmp/delete-lines-matching @@ -1,5 +1,4 @@ -foo 1 bar 2 baz 3 me:x:101:doo =========================================================================== --- original WORKDIR/tmp/regex-replace +++ changed WORKDIR/tmp/regex-replace @@ -1 +1 @@ -I dare you to change my policy foo \ No newline at end of file +I dare you to change my policy FOO! =========================================================================== --- original WORKDIR/tmp/edit-template-string +++ changed WORKDIR/tmp/edit-template-string @@ -1 +1 @@ -From a particular point of view \ No newline at end of file +Darth Vader killed your father \ No newline at end of file =========================================================================== --- original WORKDIR/tmp/build-xpath +++ changed WORKDIR/tmp/build-xpath @@ -0,0 +1,2 @@ + + =========================================================================== --- original WORKDIR/tmp/xml-insert-tree +++ changed WORKDIR/tmp/xml-insert-tree @@ -1,2 +1,2 @@ - +y =========================================================================== =========================================================================== 'WORKDIR/tmp/transformer' no longer exists =========================================================================== 'WORKDIR/tmp/hardlink' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/link' is a symbolic link Size: SIZE Access: (0777/rwxrwxrwx) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Target: 'WORKDIR/tmp/already-created' cfengine-3.24.2/tests/acceptance/29_simulate_mode/diff_mode.cf0000644000000000000000000000302515010704253024172 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub", "./prepare_files_for_simulate_tests.cf.sub", "./normalize_agent_output.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: "prepare_files_for_simulate_tests"; } bundle agent test { meta: "test_soft_fail" string => "(solaris|aix|hpux|windows)", meta => { "ENT-6540,ENT-10254" }; # ENT-6540 exotics fail to delete chroot # ENT-10254 tests fail on Windows due to CRLF "description" -> { "ENT-5302" } string => "Test that files promises in --simulate=diff mode produce proper output and only make changes in chroot"; commands: # add --verbose here and look at the .actual log for debugging sub policy runs "$(sys.cf_agent) -Kf $(this.promise_dirname)$(const.dirsep)promises.cf.sub --simulate=diff > $(this.promise_filename).temp 2>&1" contain => in_shell, comment => "Run sub policy in manifest mode and capture output to $(this.promise_filename).actual file."; } bundle agent check { methods: "normalize_agent_results" usebundle => normalize_agent_results("$(this.promise_filename).temp", "$(this.promise_filename).actual"); "check" usebundle => dcs_check_diff("$(this.promise_filename).actual", "$(this.promise_filename).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/29_simulate_mode/normalize_agent_output.cf.sub0000644000000000000000000000076215010704253027651 0ustar00rootroot00000000000000bundle agent normalize_agent_results(original, normalized) { commands: "$(G.sed)" args => " \ -e 's,$(sys.workdir),WORKDIR,g' \ -e 's/[0-9]*\.changes/PID.changes/' \ -e 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}[[:blank:]][0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}[[:blank:]][-+][0-9]\{4\}/TIMESTAMP/' \ -e 's/Size: [0-9]*/Size: SIZE/' \ $(original) > $(normalized)", contain => in_shell, comment => "Normalize pid, timestamp and file sizes so that we can compare to an expected output."; } cfengine-3.24.2/tests/acceptance/29_simulate_mode/simulate_safe_functions.cf0000644000000000000000000000272015010704253027170 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { vars: "usemodule_unsafe_module_path" string => "$(sys.workdir)$(const.dirsep)modules$(const.dirsep)usemodule_unsafe.sh"; "usemodule_safe_module_path" string => "$(sys.workdir)$(const.dirsep)modules$(const.dirsep)usemodule_safe.sh"; files: "$(sys.statedir)/*safe" delete => tidy; "$(usemodule_unsafe_module_path)" create => "true", perms => m(700), content => "#!/bin/bash touch $(sys.statedir)/usemodule_unsafe "; "$(usemodule_safe_module_path)" create => "true", perms => m(700), content => "#!/bin/bash touch $(sys.statedir)/usemodule_safe "; } bundle agent test { meta: "description" -> { "ENT-5299" } string => "Test that unsafe functions are only evaluated in --simulate mode when tagged as simulate_safe"; vars: "cf_agent" string => ifelse(isvariable("sys.cf_agent"), "$(sys.cf_agent)", "/var/cfengine/bin/cf-agent"); commands: "$(cf_agent) --timestamp --debug --simulate=manifest -Kf $(this.promise_filename).sub >$(sys.workdir)$(const.dirsep)state$(const.dirsep)agent.log" contain => in_shell; } bundle agent check { vars: "result" string => readfile("$(sys.workdir)$(const.dirsep)state$(const.dirsep)agent.log"); methods: "Pass/FAIL" usebundle => dcs_check_strcmp( "$(result)", "FAIL", $(this.promise_filename), "yes"); } cfengine-3.24.2/tests/acceptance/29_simulate_mode/manifest_full_mode.cf.expected0000644000000000000000000001223215010704253027712 0ustar00rootroot00000000000000 warning: All changes in files will be made in the 'WORKDIR/state/PID.changes' chroot =========================================================================== 'WORKDIR/tmp/rename-newname' is the new name of 'WORKDIR/tmp/rename-me' =========================================================================== 'WORKDIR/tmp/source-file' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: These are my source file contents. \no newline at the end of file =========================================================================== 'WORKDIR/tmp/create-true' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/insert-lines' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: foobar =========================================================================== 'WORKDIR/tmp/SUBDIR' is a directory Size: SIZE Access: (0700/rwx------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Directory contents: =========================================================================== 'WORKDIR/tmp/copy-from' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: These are my source file contents. \no newline at the end of file =========================================================================== 'WORKDIR/tmp/delete-me' no longer exists =========================================================================== 'WORKDIR/tmp/sub-dir/./sub-file' no longer exists =========================================================================== 'WORKDIR/tmp/sub-dir/.' is a directory Size: SIZE Access: (0700/rwx------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Directory contents: =========================================================================== 'WORKDIR/tmp/set-colon-field' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: me:x:1001:1001::/my/new/shell:/bin/sh =========================================================================== 'WORKDIR/tmp/delete-lines-matching' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: bar 2 baz 3 me:x:101:doo =========================================================================== 'WORKDIR/tmp/regex-replace' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: I dare you to change my policy FOO! =========================================================================== 'WORKDIR/tmp/edit-template-string' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: Darth Vader killed your father \no newline at the end of file =========================================================================== 'WORKDIR/tmp/build-xpath' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/xml-insert-tree' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: y =========================================================================== 'WORKDIR/tmp/perms' is a regular file Size: SIZE Access: (0000/---------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/transformer' no longer exists =========================================================================== 'WORKDIR/tmp/hardlink' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/link' is a symbolic link Size: SIZE Access: (0777/rwxrwxrwx) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Target: 'WORKDIR/tmp/already-created' =========================================================================== 'WORKDIR/tmp/already-created' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: cfengine-3.24.2/tests/acceptance/29_simulate_mode/manifest_mode.cf.expected0000644000000000000000000001161615010704253026675 0ustar00rootroot00000000000000 warning: All changes in files will be made in the 'WORKDIR/state/PID.changes' chroot =========================================================================== 'WORKDIR/tmp/rename-newname' is the new name of 'WORKDIR/tmp/rename-me' =========================================================================== 'WORKDIR/tmp/source-file' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: These are my source file contents. \no newline at the end of file =========================================================================== 'WORKDIR/tmp/create-true' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/insert-lines' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: foobar =========================================================================== 'WORKDIR/tmp/SUBDIR' is a directory Size: SIZE Access: (0700/rwx------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Directory contents: =========================================================================== 'WORKDIR/tmp/copy-from' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: These are my source file contents. \no newline at the end of file =========================================================================== 'WORKDIR/tmp/delete-me' no longer exists =========================================================================== 'WORKDIR/tmp/sub-dir/./sub-file' no longer exists =========================================================================== 'WORKDIR/tmp/sub-dir/.' is a directory Size: SIZE Access: (0700/rwx------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Directory contents: =========================================================================== 'WORKDIR/tmp/set-colon-field' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: me:x:1001:1001::/my/new/shell:/bin/sh =========================================================================== 'WORKDIR/tmp/delete-lines-matching' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: bar 2 baz 3 me:x:101:doo =========================================================================== 'WORKDIR/tmp/regex-replace' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: I dare you to change my policy FOO! =========================================================================== 'WORKDIR/tmp/edit-template-string' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: Darth Vader killed your father \no newline at the end of file =========================================================================== 'WORKDIR/tmp/build-xpath' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/xml-insert-tree' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: y =========================================================================== 'WORKDIR/tmp/perms' is a regular file Size: SIZE Access: (0000/---------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/transformer' no longer exists =========================================================================== 'WORKDIR/tmp/hardlink' is a regular file Size: SIZE Access: (0600/rw-------) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Contents of the file: =========================================================================== 'WORKDIR/tmp/link' is a symbolic link Size: SIZE Access: (0777/rwxrwxrwx) Uid: (0/root) Gid: (0/root) Access: TIMESTAMP Modify: TIMESTAMP Change: TIMESTAMP Target: 'WORKDIR/tmp/already-created' cfengine-3.24.2/tests/acceptance/29_simulate_mode/manifest_full_mode.cf0000644000000000000000000000304715010704253026116 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub", "./prepare_files_for_simulate_tests.cf.sub", "./normalize_agent_output.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: "prepare_files_for_simulate_tests"; } bundle agent test { meta: "test_soft_fail" string => "(solaris|aix|hpux|windows)", meta => { "ENT-6540,ENT-10254" }; # ENT-6540 exotics fail to delete chroot # ENT-10254 tests fail on Windows due to CRLF "description" -> { "ENT-5301" } string => "Test that files promises in --simulate=manifest-full mode produce proper output and only make changes in chroot"; commands: # add --verbose here and look at the .actual log for debugging sub policy runs "$(sys.cf_agent) -Kf $(this.promise_dirname)$(const.dirsep)promises.cf.sub --simulate=manifest-full > $(this.promise_filename).temp 2>&1" contain => in_shell, comment => "Run sub policy in manifest mode and capture output to $(this.promise_filename).actual file."; } bundle agent check { methods: "normalize_agent_results" usebundle => normalize_agent_results("$(this.promise_filename).temp", "$(this.promise_filename).actual"); "check" usebundle => dcs_check_diff("$(this.promise_filename).actual", "$(this.promise_filename).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/plucked.cf.sub0000644000000000000000000016107015010704253021341 0ustar00rootroot00000000000000### This is an auto-generated file, see Makefile.am and `make pluck` ### bundle agent run_ifdefined(namespace, mybundle) # @brief bundle to maybe run another bundle dynamically # @param namespace the namespace, usually `$(this.namespace)` # @param mybundle the bundle to maybe run # # This bundle simply is a way to run another bundle only if it's defined. # # **Example:** # # ```cf3 # bundle agent run # { # methods: # # does nothing if bundle "runthis" is not defined # "go" usebundle => run_ifdefined($(this.namespace), runthis); # } # ``` { vars: "bundlesfound" slist => bundlesmatching("^$(namespace):$(mybundle)$"); "count" int => length(bundlesfound); methods: "any" usebundle => $(bundlesfound), ifvarclass => strcmp(1, $(count)); reports: verbose_mode:: "$(this.bundle): found matching bundles $(bundlesfound) for namespace '$(namespace)' and bundle '$(mybundle)'"; } body contain in_dir_shell(dir) # @brief run command after switching to directory "dir" with full shell # @param dir directory to change into # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_dir_shell("/tmp"); # ``` { chdir => "$(dir)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible } body contain in_shell # @brief run command in shell # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_shell; # ``` { useshell => "true"; # canonical "useshell" but this is backwards-compatible } body contain in_shell_bg # @brief deprecated # This bundle previously had an invalid background attribute that was caught by # parser strictness enhancements. Backgrounding is handeled by the body action # background attribute. { useshell => "true"; # canonical "useshell" but this is backwards-compatible } body contain in_shell_and_silent # @brief run command in shell and suppress output # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_shell_and_silent, # comment => "Silently run command in shell"; # ``` { useshell => "true"; # canonical "useshell" but this is backwards-compatible no_output => "true"; } body contain in_dir_shell_and_silent(dir) # @brief run command in shell after switching to 'dir' and suppress output # @param dir directory to change into # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_dir_shell_and_silent("/tmp"), # comment => "Silently run command in shell"; # ``` { useshell => "true"; # canonical "useshell" but this is backwards-compatible no_output => "true"; chdir => "$(dir)"; } body action if_elapsed(x) # @brief Evaluate the promise every `x` minutes # @param x The time in minutes between promise evaluations { ifelapsed => "$(x)"; expireafter => "$(x)"; } body action if_elapsed_day # @brief Evalute the promise once every 24 hours { ifelapsed => "1440"; # 60 x 24 expireafter => "1400"; } body action warn_only # @brief Warn once an hour if the promise needs to be repaired # # The promise does not get repaired. { action_policy => "warn"; ifelapsed => "60"; } body action immediate # @brief Evaluate the promise at every `cf-agent` execution. { ifelapsed => "0"; } body classes if_repaired(x) # @brief Define class `x` if the promise has been repaired # @param x The name of the class { promise_repaired => { "$(x)" }; } body classes if_else(yes,no) # @brief Define the classes `yes` or `no` depending on promise outcome # @param yes The name of the class that should be defined if the promise is kept or repaired # @param no The name of the class that should be defined if the promise could not be repaired { promise_kept => { "$(yes)" }; promise_repaired => { "$(yes)" }; repair_failed => { "$(no)" }; repair_denied => { "$(no)" }; repair_timeout => { "$(no)" }; } body classes if_notkept(x) # @brief Define the class `x` if the promise is not kept and cannot be repaired. # @param x The name of the class that should be defined { repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } body classes if_ok(x) # @brief Define the class `x` if the promise is kept or could be repaired # @param x The name of the class that should be defined { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; } body classes if_ok_cancel(x) # @brief Cancel the class `x` if the promise ks kept or repaired # @param x The name of the class that should be cancelled { cancel_repaired => { "$(x)" }; cancel_kept => { "$(x)" }; } body classes classes_generic(x) # @brief Define `x` prefixed/suffixed with promise outcome # @param x The unique part of the classes to be defined { promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_reached" }; } body classes results(scope, class_prefix) # @brief Define classes prefixed with `class_prefix` and suffixed with # appropriate outcomes: _kept, _repaired, _not_kept, _error, _failed, # _denied, _timeout, _reached # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined # # This body can be applied to any promise and sets global # (`namespace`) or local (`bundle`) classes based on its outcome. For # instance, with `class_prefix` set to `abc`: # # * if the promise is to change a file's owner to `nick` and the file # was already owned by `nick`, the classes `abc_reached` and # `abc_kept` will be set. # # * if the promise is to change a file's owner to `nick` and the file # was owned by `adam` and the change succeeded, the classes # `abc_reached` and `abc_repaired` will be set. # # This body is a simpler, more consistent version of the body # `scoped_classes_generic`, which see. The key difference is that # fewer classes are defined, and only for outcomes that we can know. # For example this body does not define "OK/not OK" outcome classes, # since a promise can be both kept and failed at the same time. # # It's important to understand that promises may do multiple things, # so a promise is not simply "OK" or "not OK." The best way to # understand what will happen when your specific promises get this # body is to test it in all the possible combinations. # # **Suffix Notes:** # # * `_reached` indicates the promise was tried. Any outcome will result # in a class with this suffix being defined. # # * `_kept` indicates some aspect of the promise was kept # # * `_repaired` indicates some aspect of the promise was repaired # # * `_not_kept` indicates some aspect of the promise was not kept. # error, failed, denied and timeout outcomes will result in a class # with this suffix being defined # # * `_error` indicates the promise repair encountered an error # # * `_failed` indicates the promise failed # # * `_denied` indicates the promise repair was denied # # * `_timeout` indicates the promise timed out # # **Example:** # # ```cf3 # bundle agent example # { # commands: # "/bin/true" # classes => results("bundle", "my_class_prefix"); # # reports: # my_class_prefix_kept:: # "My promise was kept"; # # my_class_prefix_repaired:: # "My promise was repaired"; # } # ``` # # **See also:** `scope`, `scoped_classes_generic`, `classes_generic` { scope => "$(scope)"; promise_kept => { "$(class_prefix)_reached", "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_reached", "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_failed" }; repair_denied => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_denied" }; repair_timeout => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_timeout" }; } body classes scoped_classes_generic(scope, x) # @brief Define `x` prefixed/suffixed with promise outcome # **See also:** `scope` # # @param scope The scope in which the class should be defined # @param x The unique part of the classes to be defined { scope => "$(scope)"; promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_reached" }; } body classes always(x) # @brief Define class `x` no matter what the outcome of the promise is # @param x The name of the class to be defined { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } body classes kept_successful_command # @brief Set command to "kept" instead of "repaired" if it returns 0 { kept_returncodes => { "0" }; } bundle edit_line insert_before_if_no_line(before, string) # @brief Insert `string` before `before` if `string` is not found in the file # @param before The regular expression matching the line which `string` will be # inserted before # @param string The string to be prepended # { insert_lines: "$(string)" location => before($(before)), comment => "Prepend a line to the file if it doesn't already exist"; } bundle edit_line insert_lines(lines) # @brief Append `lines` if they don't exist in the file # @param lines The lines to be appended # # **See also:** [`insert_lines`][insert_lines] in # [`edit_line`][bundle edit_line] { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } bundle edit_line insert_file(templatefile) # @brief Reads the lines from `templatefile` and inserts those into the # file being edited. # @param templatefile The name of the file from which to import lines. { insert_lines: "$(templatefile)" comment => "Insert the template file into the file being edited", insert_type => "file"; } bundle edit_line comment_lines_matching(regex,comment) # @brief Comment lines in the file that matching an [anchored] regex # @param regex Anchored regex that the entire line needs to match # @param comment A string that is prepended to matching lines { replace_patterns: "^($(regex))$" replace_with => comment("$(comment)"), comment => "Search and replace string"; } bundle edit_line uncomment_lines_matching(regex,comment) # @brief Uncomment lines of the file where the regex matches # the entire text after the comment string # @param regex The regex that lines need to match after `comment` # @param comment The prefix of the line that is removed { replace_patterns: "^$(comment)\s?($(regex))$" replace_with => uncomment, comment => "Uncomment lines matching a regular expression"; } bundle edit_line comment_lines_containing(regex,comment) # @brief Comment lines of the file matching a regex # @param regex A regex that a part of the line needs to match # @param comment A string that is prepended to matching lines { replace_patterns: "^((?!$(comment)).*$(regex).*)$" replace_with => comment("$(comment)"), comment => "Comment out lines in a file"; } bundle edit_line uncomment_lines_containing(regex,comment) # @brief Uncomment lines of the file where the regex matches # parts of the text after the comment string # @param regex The regex that lines need to match after `comment` # @param comment The prefix of the line that is removed { replace_patterns: "^$(comment)\s?(.*$(regex).*)$" replace_with => uncomment, comment => "Uncomment a line containing a fragment"; } bundle edit_line delete_lines_matching(regex) # @brief Delete lines matching a regular expression # @param regex The regular expression that the lines need to match { delete_lines: "$(regex)" comment => "Delete lines matching regular expressions"; } bundle edit_line warn_lines_matching(regex) # @brief Warn about lines matching a regular expression # @param regex The regular expression that the lines need to match { delete_lines: "$(regex)" comment => "Warn about lines in a file", action => warn_only; } bundle edit_line prepend_if_no_line(string) # @brief Prepend `string` if it doesn't exist in the file # @param string The string to be prepended # # **See also:** [`insert_lines`][insert_lines] in # [`edit_line`][bundle edit_line] { insert_lines: "$(string)" location => start, comment => "Prepend a line to the file if it doesn't already exist"; } bundle edit_line append_if_no_line(str) # @ignore # This duplicates the insert_lines bundle { insert_lines: "$(str)" comment => "Append a line to the file if it doesn't already exist"; } bundle edit_line append_if_no_lines(list) # @ignore # This duplicates the insert_lines bundle { insert_lines: "$(list)" comment => "Append lines to the file if they don't already exist"; } bundle edit_line replace_line_end(start,end) # @brief Give lines starting with `start` the ending given in `end` # # Whitespaces will be left unmodified. For example, # `replace_line_end("ftp", "2121/tcp")` would replace # # `"ftp 21/tcp"` # # with # # `"ftp 2121/tcp"` # # @param start The string lines have to start with # @param end The string lines should end with { field_edits: "\s*$(start)\s.*" comment => "Replace lines with $(this.start) and $(this.end)", edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","set"); } bundle edit_line append_to_line_end(start,end) # @brief Append `end` to any lines beginning with `start` # # `end` will be appended to all lines starting with `start` and not # already ending with `end`. Whitespaces will be left unmodified. # # For example, `append_to_line_end("kernel", "vga=791")` would replace # `kernel /boot/vmlinuz root=/dev/sda7` # # with # # `kernel /boot/vmlinuz root=/dev/sda7 vga=791` # # **WARNING**: Be careful not to have multiple promises matching the same line, which would result in the line growing indefinitely. # # @param start pattern to match lines of interest # @param end string to append to matched lines # # **Example:** # # ```cf3 # files: # "/tmp/boot-options" edit_line => append_to_line_end("kernel", "vga=791"); # ``` # { field_edits: "\s*$(start)\s.*" comment => "Append lines with $(this.start) and $(this.end)", edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","append"); } bundle edit_line regex_replace(find,replace) # @brief Find exactly a regular expression and replace exactly the match with a string. # You can think of this like a PCRE powered sed. # @param find The regular expression # @param replace The replacement string { replace_patterns: "$(find)" replace_with => value("$(replace)"), comment => "Search and replace string"; } bundle edit_line resolvconf(search,list) # @brief Adds search domains and name servers to the system # resolver configuration. # # Use this bundle to modify `resolv.conf`. Existing entries for # `search` and `nameserver` are replaced. # # @param search The search domains with space # @param list An slist of nameserver addresses { delete_lines: "search.*" comment => "Reset search lines from resolver"; "nameserver.*" comment => "Reset nameservers in resolver"; insert_lines: "search $(search)" comment => "Add search domains to resolver"; "nameserver $(list)" comment => "Add name servers to resolver"; } bundle edit_line resolvconf_o(search,list,options) # @brief Adds search domains, name servers and options to the system # resolver configuration. # # Use this bundle to modify `resolv.conf`. Existing entries for # `search`, `nameserver` and `options` are replaced. # # @param search The search domains with space # @param list An slist of nameserver addresses # @param options is an slist of variables to modify the resolver { delete_lines: "search.*" comment => "Reset search lines from resolver"; "nameserver.*" comment => "Reset nameservers in resolver"; "options.*" comment => "Reset options in resolver"; insert_lines: "search $(search)" comment => "Add search domains to resolver"; "nameserver $(list)" comment => "Add name servers to resolver"; "options $(options)" comment => "Add options to resolver"; } bundle edit_line manage_variable_values_ini(tab, sectionName) # @brief Sets the RHS of configuration items in the file of the form # `LHS=RHS` # # If the line is commented out with `#`, it gets uncommented first. # Adds a new line if none exists. # Removes any variable value pairs not defined for the ini section. # # @param tab An associative array containing `tab[sectionName][LHS]="RHS"`. # The value is not changed when the `RHS` is "dontchange" # @param sectionName The section in the file within which values should be # modified # # **See also:** `set_variable_values_ini()` { vars: "index" slist => getindices("$(tab)[$(sectionName)]"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), comment => "Create conditions to make changes"; field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" select_region => INI_section(escape("$(sectionName)")), edit_field => col("=","1","$(index)","set"), ifvarclass => "edit_$(cindex[$(index)])"; # match a line starting like the key something "$(index)\s*=.*" edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), select_region => INI_section(escape("$(sectionName)")), classes => results("bundle", "manage_variable_values_ini_not_$(cindex[$(index)])"), ifvarclass => "edit_$(cindex[$(index)])"; delete_lines: ".*" select_region => INI_section(escape("$(sectionName)")), comment => "Remove all entries in the region so there are no extra entries"; insert_lines: "[$(sectionName)]" location => start, comment => "Insert lines"; "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section(escape("$(sectionName)")), ifvarclass => "!(manage_variable_values_ini_not_$(cindex[$(index)])_kept|manage_variable_values_ini_not_$(cindex[$(index)])_repaired).edit_$(cindex[$(index)])"; } bundle edit_line set_variable_values_ini(tab, sectionName) # @brief Sets the RHS of configuration items in the file of the form # `LHS=RHS` # # If the line is commented out with `#`, it gets uncommented first. # Adds a new line if none exists. # # @param tab An associative array containing `tab[sectionName][LHS]="RHS"`. # The value is not changed when the `RHS` is "dontchange" # @param sectionName The section in the file within which values should be # modified # # **See also:** `manage_variable_values_ini()` { vars: "index" slist => getindices("$(tab)[$(sectionName)]"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), comment => "Create conditions to make changes"; field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" select_region => INI_section("$(sectionName)"), edit_field => col("=","1","$(index)","set"), ifvarclass => "edit_$(cindex[$(index)])"; # match a line starting like the key something "$(index)\s*=.*" edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), select_region => INI_section("$(sectionName)"), classes => results("bundle", "set_variable_values_ini_not_$(cindex[$(index)])"), ifvarclass => "edit_$(cindex[$(index)])"; insert_lines: "[$(sectionName)]" location => start, comment => "Insert lines"; "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section("$(sectionName)"), ifvarclass => "!(set_variable_values_ini_not_$(cindex[$(index)])_kept|set_variable_values_ini_not_$(cindex[$(index)])_repaired).edit_$(cindex[$(index)])"; } bundle edit_line insert_ini_section(name, config) # @brief Inserts a INI section with content # # ``` # # given an array "barray" # files: # "myfile.ini" edit_line => insert_innit_section("foo", "barray"); # ``` # # Inserts a section in an INI file with the given configuration # key-values from the array `config`. # # @param name the name of the INI section # @param config The fully-qualified name of an associative array containing `v[LHS]="rhs"` { vars: "k" slist => getindices($(config)); insert_lines: "[$(name)]" location => start, comment => "Prepend a line to the file if it doesn't already exist"; "$(k)=$($(config)[$(k)])"; } bundle edit_line set_quoted_values(v) # @brief Sets the RHS of variables in shell-like files of the form: # # ``` # LHS="RHS" # ``` # # Adds a new line if no LHS exists, and replaces RHS values if one does exist. # If the line is commented out with #, it gets uncommented first. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` # # **Example:** # # ```cf3 # vars: # "stuff[lhs-1]" string => "rhs1"; # "stuff[lhs-2]" string => "rhs2"; # # files: # "myfile" # edit_line => set_quoted_values(stuff) # ``` # # **See also:** `set_variable_values()` { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" edit_field => col("=","1","$(index)","set"); # match a line starting like the key = something "\s*$(index)\s*=.*" edit_field => col("=","2",'"$($(v)[$(index)])"',"set"), classes => results("bundle", "$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: '$(index)="$($(v)[$(index)])"' comment => "Insert a variable definition", ifvarclass => "!($(cindex[$(index)])_in_file_kept|$(cindex[$(index)])_in_file_repaired)"; } bundle edit_line set_variable_values(v) # @brief Sets the RHS of variables in files of the form: # # ``` # LHS=RHS # ``` # # Adds a new line if no LHS exists, and replaces RHS values if one does exist. # If the line is commented out with #, it gets uncommented first. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` # # **Example:** # # ```cf3 # vars: # "stuff[lhs-1]" string => "rhs1"; # "stuff[lhs-2]" string => "rhs2"; # # files: # "myfile" # edit_line => set_variable_values(stuff) # ``` # # **See also:** `set_quoted_values()` { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); "cv" string => canonify("$(v)"); field_edits: # match a line starting like the key = something "\s*$(index)\s*=.*" edit_field => col("\s*$(index)\s*=","2","$($(v)[$(index)])","set"), classes => results("bundle", "$(cv)_$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: "$(index)=$($(v)[$(index)])" comment => "Insert a variable definition", ifvarclass => "!($(cv)_$(cindex[$(index)])_in_file_kept|$(cv)_$(cindex[$(index)])_in_file_repaired)"; } bundle edit_line set_config_values(v) # @brief Sets the RHS of configuration items in the file of the form: # # ``` # LHS RHS # ``` # # If the line is commented out with `#`, it gets uncommented first. # # Adds a new line if none exists. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); # Escape the value (had a problem with special characters and regex's) "ev[$(index)]" string => escape("$($(v)[$(index)])"); # Do we have more than one line commented out? "index_comment_matches_$(cindex[$(index)])" int => countlinesmatching("^\s*#\s*($(index)\s+.*|$(index))$","$(edit.filename)"); classes: # Check to see if this line exists "line_exists_$(cindex[$(index)])" expression => regline("^\s*($(index)\s.*|$(index))$","$(edit.filename)"), scope => "bundle"; # if there's more than one comment, just add new (don't know who to use) "multiple_comments_$(cindex[$(index)])" expression => isgreaterthan("$(index_comment_matches_$(cindex[$(index)]))","1"), scope => "bundle"; replace_patterns: # If the line is commented out, uncomment and replace with # the correct value "^\s*#\s*($(index)\s+.*|$(index))$" comment => "If we find a single commented entry we can uncomment it to keep the settings near any inline documentation. If there are multiple comments, then we don't try to replace them and instead will later append the new value after the first commented occurrence of $(index).", handle => "set_config_values_replace_commented_line", replace_with => value("$(index) $($(v)[$(index)])"), ifvarclass => "!line_exists_$(cindex[$(index)]).!replace_attempted_$(cindex[$(index)])_reached.!multiple_comments_$(cindex[$(index)])", classes => results("bundle", "uncommented_$(cindex[$(index)])"); # If the line is there with the wrong value, replace with # the correct value "^\s*($(index)\s+(?!$(ev[$(index)])$).*|$(index))$" comment => "Correct the value $(index)", replace_with => value("$(index) $($(v)[$(index)])"), classes => results("bundle", "replace_attempted_$(cindex[$(index)])"); insert_lines: # If the line doesn't exist, or there is more than one occurrence # of the LHS commented out, insert a new line and try to place it # after the commented LHS (keep new line with old comments) "$(index) $($(v)[$(index)])" comment => "Insert the value, marker exists $(index)", location => after("^\s*#\s*($(index)\s+.*|$(index))$"), ifvarclass => "replace_attempted_$(cindex[$(index)])_reached.multiple_comments_$(cindex[$(index)])"; # If the line doesn't exist and there are no occurrences # of the LHS commented out, insert a new line at the eof "$(index) $($(v)[$(index)])" comment => "Insert the value, marker doesn't exist $(index)", ifvarclass => "replace_attempted_$(cindex[$(index)])_reached.!multiple_comments_$(cindex[$(index)])"; } bundle edit_line set_line_based(v, sep, bp, kp, cp) # @brief Sets the RHS of configuration items in the file of the form: # # ``` # LHS$(sep)RHS # ``` # # Example usage for `x=y` lines (e.g. rsyncd.conf): # # ```cf3 # "myfile" # edit_line => set_line_based("test.config", "=", "\s*=\s*", ".*", "\s*#\s*"); # ``` # # Example usage for `x y` lines (e.g. sshd_config): # # ```cf3 # "myfile" # edit_line => set_line_based("test.config", " ", "\s+", ".*", "\s*#\s*"); # ``` # # If the line is commented out with `$(cp)`, it gets uncommented first. # # Adds a new line if none exists or if more than one commented-out # possible matches exist. # # Originally `set_config_values` by Ed King. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` # @param sep The separator to insert, e.g. ` ` for space-separated # @param bp The key-value separation regex, e.g. `\s+` for space-separated # @param kp The keys to select from v, use `.*` for all # @param cp The comment pattern from line-start, e.g. `\s*#\s*` { meta: "tags" slist => { "replaces=set_config_values", "replaces=set_config_values_matching", "replaces=set_variable_values", "replaces=set_quoted_values", "replaces=maintain_key_values", }; vars: "vkeys" slist => getindices("$(v)"); "i" slist => grep($(kp), vkeys); # Be careful if the index string contains funny chars "ci[$(i)]" string => canonify("$(i)"); # Escape the value (had a problem with special characters and regex's) "ev[$(i)]" string => escape("$($(v)[$(i)])"); # Do we have more than one line commented out? "comment_matches_$(ci[$(i)])" int => countlinesmatching("^$(cp)($(i)$(bp).*|$(i))$", $(edit.filename)); classes: # Check to see if this line exists "exists_$(ci[$(i)])" expression => regline("^\s*($(i)$(bp).*|$(i))$", $(edit.filename)); # if there's more than one comment, just add new (don't know who to use) "multiple_comments_$(ci[$(i)])" expression => isgreaterthan("$(comment_matches_$(ci[$(i)]))", "1"); replace_patterns: # If the line is commented out, uncomment and replace with # the correct value "^$(cp)($(i)$(bp).*|$(i))$" comment => "Uncommented the value '$(i)'", replace_with => value("$(i)$(sep)$($(v)[$(i)])"), ifvarclass => "!exists_$(ci[$(i)]).!replace_attempted_$(ci[$(i)])_reached.!multiple_comments_$(ci[$(i)])", classes => results("bundle", "uncommented_$(ci[$(i)])"); # If the line is there with the wrong value, replace with # the correct value "^\s*($(i)$(bp)(?!$(ev[$(i)])$).*|$(i))$" comment => "Correct the value '$(i)'", replace_with => value("$(i)$(sep)$($(v)[$(i)])"), classes => results("bundle", "replace_attempted_$(ci[$(i)])"); insert_lines: # If the line doesn't exist, or there is more than one occurrence # of the LHS commented out, insert a new line and try to place it # after the commented LHS (keep new line with old comments) "$(i)$(sep)$($(v)[$(i)])" comment => "Insert the value, marker '$(i)' exists", location => after("^$(cp)($(i)$(bp).*|$(i))$"), ifvarclass => "replace_attempted_$(ci[$(i)])_reached.multiple_comments_$(ci[$(i)])"; # If the line doesn't exist and there are no occurrences # of the LHS commented out, insert a new line at the eof "$(i)$(sep)$($(v)[$(i)])" comment => "Insert the value, marker '$(i)' doesn't exist", ifvarclass => "replace_attempted_$(ci[$(i)])_reached.!multiple_comments_$(ci[$(i)]).!exists_$(ci[$(i)])"; reports: verbose_mode|EXTRA:: "$(this.bundle): Line for '$(i)' exists" ifvarclass => "exists_$(ci[$(i)])"; "$(this.bundle): Line for '$(i)' does not exist" ifvarclass => "!exists_$(ci[$(i)])"; } bundle edit_line set_config_values_matching(v,pat) # @brief Sets the RHS of configuration items in the file of the form # # ``` # LHS RHS # ``` # # If the line is commented out with `#`, it gets uncommented first. # Adds a new line if none exists. # # @param v the fully-qualified name of an associative array containing v[LHS]="rhs" # @param pat Only elements of `v` that match the regex `pat` are use { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "allparams" slist => getindices("$(v)"); "index" slist => grep("$(pat)", "allparams"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); replace_patterns: # If the line is there, maybe commented out, uncomment and replace with # the correct value "^\s*($(index)\s+(?!$($(v)[$(index)])).*|# ?$(index)\s+.*)$" comment => "Correct the value", replace_with => value("$(index) $($(v)[$(index)])"), classes => results("bundle", "replace_attempted_$(cindex[$(index)])"); insert_lines: "$(index) $($(v)[$(index)])" ifvarclass => "replace_attempted_$(cindex[$(index)])_reached"; } bundle edit_line maintain_key_values(v,sep) # @ignore # @brief Sets the RHS of configuration items with an giving separator # # Contributed by David Lee { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); # Matching pattern for line (basically key-and-separator) "keypat[$(index)]" string => "\s*$(index)\s*$(sep)\s*"; # Values may contain regexps. Escape them for replace_pattern matching. "ve[$(index)]" string => escape("$($(v)[$(index)])"); classes: "$(cindex[$(index)])_key_in_file" comment => "Dynamic Class created if patterns matching", expression => regline("^$(keypat[$(index)]).*", "$(edit.filename)"); replace_patterns: # For convergence need to use negative lookahead on value: # "key sep (?!value).*" "^($(keypat[$(index)]))(?!$(ve[$(index)])$).*" comment => "Replace definition of $(index)", replace_with => value("$(match.1)$($(v)[$(index)])"); insert_lines: "$(index)$(sep)$($(v)[$(index)])" comment => "Insert definition of $(index)", ifvarclass => "!$(cindex[$(index)])_key_in_file"; } bundle edit_line append_users_starting(v) # @brief For adding to `/etc/passwd` or `etc/shadow` # @param v An array `v[username] string => "line..."` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => userexists("$(index)"), comment => "Class created if user does not exist"; insert_lines: "$($(v)[$(index)])" comment => "Append users into a password file format", ifvarclass => "add_$(index)"; } bundle edit_line append_groups_starting(v) # @brief For adding groups to `/etc/group` # @param v An array `v[groupname] string => "line..."` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => groupexists("$(index)"), comment => "Class created if group does not exist"; insert_lines: "$($(v)[$(index)])" comment => "Append users into a group file format", ifvarclass => "add_$(index)"; } bundle edit_line set_colon_field(key,field,val) # @brief Set the value of field number `field` of the line whose # first field is `key` to the value `val`, in a colon-separated file. # @param key The value the first field has to match # @param field The field to be modified # @param val The new value of `field` { field_edits: "$(key):.*" comment => "Edit a colon-separated file, using the first field as a key", edit_field => col(":","$(field)","$(val)","set"); } bundle edit_line set_user_field(user,field,val) # @brief Set the value of field number "field" in a `:-field` # formatted file like `/etc/passwd` # @param user The user to be modified # @param field The field that should be modified # @param val The value for `field` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { field_edits: "$(user):.*" comment => "Edit a user attribute in the password file", edit_field => col(":","$(field)","$(val)","set"); } bundle edit_line append_user_field(group,field,allusers) # @brief For adding users to to a file like `/etc/group` # at field position `field`, comma separated subfields # @param group The group to be modified # @param field The field where users should be added # @param allusers The list of users to add to `field` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { vars: "val" slist => { @(allusers) }; field_edits: "$(group):.*" comment => "Append users into a password file format", edit_field => col(":","$(field)","$(val)","alphanum"); } bundle edit_line expand_template(templatefile) # @brief Read in the named text file and expand `$(var)` inside the file # @param templatefile The name of the file { insert_lines: "$(templatefile)" insert_type => "file", comment => "Expand variables in the template file", expand_scalars => "true"; } bundle edit_line replace_or_add(pattern,line) # @brief Replace a pattern in a file with a single line. # # If the pattern is not found, add the line to the file. # # @param pattern The pattern that should be replaced # The pattern must match the whole line (it is automatically # anchored to the start and end of the line) to avoid # ambiguity. # @param line The line with which to replace matches of `pattern` { vars: "cline" string => canonify("$(line)"); "eline" string => escape("$(line)"); replace_patterns: "^(?!$(eline)$)$(pattern)$" comment => "Replace a pattern here", replace_with => value("$(line)"), classes => results("bundle", "replace_$(cline)"); insert_lines: "$(line)" ifvarclass => "replace_$(cline)_reached"; } bundle edit_line converge(marker, lines) # @brief Converge `lines` marked with `marker` # # Any content marked with `marker` is removed, then `lines` are # inserted. Every `line` should contain `marker`. # # @param marker The marker (not a regular expression; will be escaped) # @param lines The lines to insert; all must contain `marker` { vars: "regex" string => escape($(marker)); delete_lines: "$(regex)" comment => "Delete lines matching the marker"; insert_lines: "$(lines)" comment => "Insert the given lines"; } bundle edit_line fstab_option_editor(method, mount, option) # @brief Add or remove `/etc/fstab` options for a mount # # This bundle edits the options field of a mount. The `method` is a # `field_operation` which can be `append`, `prepend`, `set`, `delete`, # or `alphanum`. The option is OS-specific. # # @param method `field_operation` to apply # @param mount the mount point # @param option the option to add or remove # # **Example:** # # ```cf3 # files: # "/etc/fstab" edit_line => fstab_option_editor("delete", "/", "acl"); # "/etc/fstab" edit_line => fstab_option_editor("append", "/", "acl"); # ``` { field_edits: "(?!#)\S+\s+$(mount)\s.+" edit_field => fstab_options($(option), $(method)); } body edit_field fstab_options(newval, method) # @brief Edit the options field in a fstab format # @param newval the new option # @param method `field_operation` to apply # # This body edits the options field in the fstab file format. The # `method` is a `field_operation` which can be `append`, `prepend`, # `set`, `delete`, or `alphanum`. The `newval` option is OS-specific. # # **Example:** # # ```cf3 # # from the `fstab_options_editor` # field_edits: # "(?!#)\S+\s+$(mount)\s.+" # edit_field => fstab_options($(option), $(method)); # ``` { field_separator => "\s+"; select_field => "4"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; } body edit_field quoted_var(newval,method) # @brief Edit the quoted value of the matching line # @param newval The new value # @param method The method by which to edit the field { field_separator => "\""; select_field => "2"; value_separator => " "; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "false"; allow_blank_fields => "true"; } body edit_field col(split,col,newval,method) # @brief Edit tabluar data with comma-separated sub-values # @param split The separator that defines columns # @param col The (1-based) index of the value to change # @param newval The new value # @param method The method by which to edit the field { field_separator => "$(split)"; select_field => "$(col)"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } body edit_field line(split,col,newval,method) # @brief Edit tabular data with space-separated sub-values # @param split The separator that defines columns # @param col The (1-based) index of the value to change # @param newval The new value # @param method The method by which to edit the field { field_separator => "$(split)"; select_field => "$(col)"; value_separator => " "; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } body replace_with value(x) # @brief Replace matching lines # @param x The replacement string { replace_value => "$(x)"; occurrences => "all"; } body select_region INI_section(x) # @brief Restrict the `edit_line` promise to the lines in section `[x]` # @param x The name of the section in an INI-like configuration file { select_start => "\[$(x)\]\s*"; select_end => "\[.*\]\s*"; @if minimum_version(3.10) select_end_match_eof => "true"; @endif } body edit_defaults empty # @brief Empty the file before editing # # No backup is made { empty_file_before_editing => "true"; edit_backup => "false"; #max_file_size => "300000"; } body location start # @brief Editing occurs before the matched line { before_after => "before"; } body location after(str) # @brief Editing occurs after the line matching `str` # @param str Regular expression matching the file line location { before_after => "after"; select_line_matching => "$(str)"; } body location before(str) # @brief Editing occurs before the line matching `str` # @param str Regular expression matching the file line location { before_after => "before"; select_line_matching => "$(str)"; } body replace_with comment(c) # @brief Comment all lines matching the pattern by preprending `c` # @param c The prefix that comments out lines { replace_value => "$(c) $(match.1)"; occurrences => "all"; } body replace_with uncomment # @brief Uncomment all lines matching the pattern by removing # anything outside the matching string { replace_value => "$(match.1)"; occurrences => "all"; } body copy_from secure_cp(from,server) # @brief Download a file from a remote server over an encrypted channel # # Only copy the file if it is different from the local copy, and verify # that the copy is correct. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { source => "$(from)"; servers => { "$(server)" }; compare => "digest"; encrypt => "true"; verify => "true"; } body copy_from remote_cp(from,server) # @brief Download a file from a remote server. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(from)"; compare => "mtime"; } body copy_from remote_dcp(from,server) # @brief Download a file from a remote server if it is different from the local copy. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; } body copy_from local_cp(from) # @brief Copy a local file. # # @param from The path to the source file. { source => "$(from)"; } body copy_from local_dcp(from) # @brief Copy a local file if it is different from the existing copy. # # @param from The path to the source file. { source => "$(from)"; compare => "digest"; } body copy_from perms_cp(from) # @brief Copy a local file and preserve file permissions on the local copy. # # @param from The path to the source file. { source => "$(from)"; preserve => "true"; } body copy_from perms_dcp(from) # @brief Copy a local file if it is different from the existing copy and # preserve file permissions on the local copy. # # @param from The path to the source file. { source => "$(from)"; preserve => "true"; compare => "digest"; } body copy_from backup_local_cp(from) # @brief Copy a local file and keep a backup of old versions. # # @param from The path to the source file. { source => "$(from)"; copy_backup => "timestamp"; } body copy_from seed_cp(from) # @brief Copy a local file if the file does not already exist, i.e. seed the placement # # @param from The path to the source file. { source => "$(from)"; compare => "exists"; } body copy_from sync_cp(from,server) # @brief Download a file if the local copy does not already exist, i.e. seed the placement # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(from)"; purge => "true"; preserve => "true"; type_check => "false"; } body copy_from no_backup_cp(from) # @brief Copy a local file and don't make any backup of the previous version # # @param from The path to the source file. { source => "$(from)"; copy_backup => "false"; } body copy_from no_backup_dcp(from) # @brief Copy a local file if contents have changed, and don't make any backup # of the previous version # # @param from The path to the source file. { source => "$(from)"; copy_backup => "false"; compare => "digest"; } body link_from linkfrom(source, type) # @brief Make any kind of link to a file # @param source link to this # @param type the link's type (`symlink` or `hardlink`) { source => $(source); link_type => $(type); } body perms m(mode) # @brief Set the file mode # @param mode The new mode { mode => "$(mode)"; rxdirs => "true"; } body perms mo(mode,user) # @brief Set the file's mode and owners # @param mode The new mode # @param user The username of the new owner { owners => { "$(user)" }; mode => "$(mode)"; rxdirs => "true"; } body perms mog(mode,user,group) # @brief Set the file's mode, owner and group # @param mode The new mode # @param user The username of the new owner # @param group The group name { owners => { "$(user)" }; groups => { "$(group)" }; mode => "$(mode)"; rxdirs => "true"; } body perms og(u,g) # @brief Set the file's owner and group # @param u The username of the new owner # @param g The group name { owners => { "$(u)" }; groups => { "$(g)" }; } body perms owner(user) # @brief Set the file's owner # @param user The username of the new owner { owners => { "$(user)" }; } body perms system_owned(mode) # @brief Set the file owner and group to the system default # @param mode the access permission in octal format # # **Example:** # # ```cf3 # files: # "/etc/passwd" perms => system_owned("0644"); # ``` { mode => "$(mode)"; owners => { "root" }; groups => { "$(sys.user_data[gid])" }; rxdirs => "true"; } body depth_search recurse(d) # @brief Search files and direcories recursively, up to the specified depth # Directories on different devices are included. # # @param d The maximum search depth { depth => "$(d)"; xdev => "true"; } body depth_search recurse_ignore(d,list) # @brief Search files and directories recursively, # but don't recurse into the specified directories # # @param d The maximum search depth # @param list The list of directories to be excluded { depth => "$(d)"; exclude_dirs => { @(list) }; } body depth_search recurse_with_base(d) # @brief Search files and directories recursively up to the specified # depth, starting from the base directory and including directories on # other devices. # # @param d The maximum search depth { depth => "$(d)"; xdev => "true"; include_basedir => "true"; } body delete tidy # @brief Delete the file and remove empty directories # and links to directories { dirlinks => "delete"; rmdirs => "true"; } body file_select all # @brief Select all file system entries { leaf_name => { ".*" }; file_result => "leaf_name"; } body changes all_changes # @brief Detect all file changes using sha256 # and report the diff to CFEngine Enterprise { hash => "sha256"; report_changes => "all"; report_diffs => "true"; update_hashes => "yes"; } bundle agent file_mustache(mustache_file, json_file, target_file) # @brief Make a file from a Mustache template and a JSON file # @param mustache_file the file with the Mustache template # @param json_file a file with JSON data # @param target_file the target file to write # # **Example:** # # ```cf3 # methods: # "m" usebundle => file_mustache("x.mustache", "y.json", "z.txt"); # ``` { files: "$(target_file)" create => "true", edit_template => $(mustache_file), template_data => readjson($(json_file), "100k"), template_method => "mustache"; } bundle agent file_mustache_jsonstring(mustache_file, json_string, target_file) # @brief Make a file from a Mustache template and a JSON string # @param mustache_file the file with the Mustache template # @param json_string a string with JSON data # @param target_file the target file to write # # **Example:** # # ```cf3 # methods: # "m" usebundle => file_mustache_jsonstring("x.mustache", '{ "x": "y" }', "z.txt"); # ``` { files: "$(target_file)" create => "true", edit_template => $(mustache_file), template_data => parsejson($(json_string)), template_method => "mustache"; } bundle agent file_tidy(file) # @brief Remove a file # @param file to remove # # **Example:** # # ```cf3 # methods: # "" usebundle => file_tidy("/tmp/z.txt"); # ``` { files: "$(file)" delete => tidy; reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): deleting $(file) with delete => tidy"; } bundle agent dir_sync(from, to) # @brief Synchronize a directory entire, deleting unknown files # @param from source directory # @param to destination directory # # **Example:** # # ```cf3 # methods: # "" usebundle => dir_sync("/tmp", "/var/tmp"); # ``` { files: "$(to)/." create => "true", depth_search => recurse("inf"), copy_from => copyfrom_sync($(from)); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): copying directory $(from) to $(to)"; } bundle agent file_copy(from, to) # @brief Copy a file # @param from source file # @param to destination file # # **Example:** # # ```cf3 # methods: # "" usebundle => file_copy("/tmp/z.txt", "/var/tmp/y.txt"); # ``` { files: "$(to)" copy_from => copyfrom_sync($(from)); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): copying file $(from) to $(to)"; } body copy_from copyfrom_sync(f) # @brief Copy a directory or file with digest checksums, preserving attributes and purging leftovers # @param f the file or directory { source => "$(f)"; purge => "true"; preserve => "true"; type_check => "false"; compare => "digest"; } bundle agent file_make(file, str) # @brief Make a file from a string # @param file target # @param str the string data # # **Example:** # # ```cf3 # methods: # "" usebundle => file_make("/tmp/z.txt", "Some text # and some more text here"); # ``` { vars: "len" int => string_length($(str)); summarize:: "summary" string => format("%s...%s", string_head($(str), 18), string_tail($(str), 18)); classes: "summarize" expression => isgreaterthan($(len), 40); files: "$(file)" create => "true", edit_line => insert_lines($(str)), edit_defaults => empty; reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): creating $(file) with contents '$(str)'" ifvarclass => "!summarize"; "DEBUG $(this.bundle): creating $(file) with contents '$(summary)'" ifvarclass => "summarize"; } bundle agent file_make_mog(file, str, mode, owner, group) # @brief Make a file from a string with mode, owner, group # @param file target # @param str the string data # @param mode the file permissions in octal # @param owner the file owner as a name or UID # @param group the file group as a name or GID # # **Example:** # # ```cf3 # methods: # "" usebundle => file_make_mog("/tmp/z.txt", "Some text # and some more text here", "0644", "root", "root"); # ``` { vars: "len" int => string_length($(str)); summarize:: "summary" string => format("%s...%s", string_head($(str), 18), string_tail($(str), 18)); classes: "summarize" expression => isgreaterthan($(len), 40); files: "$(file)" create => "true", edit_line => insert_lines($(str)), perms => mog($(mode), $(owner), $(group)), edit_defaults => empty; reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): creating $(file) with contents '$(str)', mode '$(mode)', owner '$(owner)' and group '$(group)'" ifvarclass => "!summarize"; "DEBUG $(this.bundle): creating $(file) with contents '$(summary)', mode '$(mode)', owner '$(owner)' and group '$(group)'" ifvarclass => "summarize"; } bundle agent file_empty(file) # @brief Make an empty file # @param file target # # **Example:** # # ```cf3 # methods: # "" usebundle => file_empty("/tmp/z.txt"); # ``` { files: "$(file)" create => "true", edit_defaults => empty; reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): creating empty $(file) with 0 size"; } bundle agent file_hardlink(target, link) # @brief Make a hard link to a file # @param target of link # @param link the hard link's location # # **Example:** # # ```cf3 # methods: # "" usebundle => file_hardlink("/tmp/z.txt", "/tmp/z.link"); # ``` { files: "$(link)" move_obstructions => "true", link_from => linkfrom($(target), "hardlink"); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): $(link) will be a hard link to $(target)"; } bundle agent file_link(target, link) # @brief Make a symlink to a file # @param target of symlink # @param link the symlink's location # # **Example:** # # ```cf3 # methods: # "" usebundle => file_link("/tmp/z.txt", "/tmp/z.link"); # ``` { files: "$(link)" move_obstructions => "true", link_from => linkfrom($(target), "symlink"); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): $(link) will be a symlink to $(target)"; } bundle edit_line create_solaris_admin_file # @brief The following bundle is part of a package setup for solaris # # See unit examples. { insert_lines: "$(solaris_knowledge.admin_nocheck)" comment => "Insert contents of Solaris admin file (automatically install packages)"; } cfengine-3.24.2/tests/acceptance/21_methods/0000755000000000000000000000000015010704253020550 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/21_methods/method_outcomes.cf0000644000000000000000000000765015010704253024270 0ustar00rootroot00000000000000# Test method outcomes as expected # Worst promise outcome inside bundle results in that outcome for entire # bundle. body file control { inputs => { "../default.cf.sub" }; } bundle agent main { methods: "init" usebundle => init; "check" usebundle => check; } bundle agent init { classes: # "method_FORCE_UNEXPECTED_FAIL" expression => "any"; vars: "method_outcome_classes" slist => classesmatching("method_.*"); "sorted_method_outcome_classes" slist => sort(method_outcome_classes, lex); methods: "test kept bundle" usebundle => method_kept, classes => scoped_classes_generic("namespace", "method_kept_outcome"); "test repaired bundle" usebundle => method_repaired, classes => scoped_classes_generic("namespace", "method_repaired_outcome"); "test repaired bundle" usebundle => method_not_kept, classes => scoped_classes_generic("namespace", "method_not_kept_outcome"); "test repaired bundle" usebundle => method_worst, classes => scoped_classes_generic("namespace", "method_worst_outcome"); reports: "$(sorted_method_outcome_classes)"; } bundle agent check { vars: "expected_classes" slist => { "method_kept_outcome_kept", "method_kept_outcome_ok", "method_kept_outcome_reached", "method_not_kept_outcome_error", "method_not_kept_outcome_failed", "method_not_kept_outcome_not_kept", "method_not_kept_outcome_not_ok", "method_not_kept_outcome_reached", "method_repaired_outcome_ok", "method_repaired_outcome_reached", "method_repaired_outcome_repaired", "method_worst_outcome_error", "method_worst_outcome_failed", "method_worst_outcome_not_kept", "method_worst_outcome_not_ok", "method_worst_outcome_reached", #"method_FORCE_UNEXPECTED_FAILURE", }; # Find classes that we expect to find but do not "missing_expected_classes" slist => difference( "expected_classes", "init.method_outcome_classes"); # Find classes that we did not expect to find "unexpected_classes" slist => difference( "init.method_outcome_classes", "expected_classes" ); # Count up the number of missing and extra classes "num_missing" int => length("missing_expected_classes"); "num_unexpected" int => length("unexpected_classes"); classes: # Fail if the counts are not as expected "fail" expression => isgreaterthan( "$(num_missing)", "0"); "fail" expression => isgreaterthan( "$(num_unexpected)", "0"); # Pass if we found all expected classes and did not fail "ok" and => { @(expected_classes), "!fail" }; reports: ok:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; } bundle agent method_kept { reports: "$(this.bundle)" comment => "This promsie should have a kept outcome"; } bundle agent method_repaired { # This bundle runs a command that returns 0 and is by default considered # repaired, so the bundle will be considered repaired commands: "$(G.true)" comment => "This promsie should have a repaired outcome"; } bundle agent method_not_kept { commands: "$(G.false)" comment => "This promise should have a not_kept outcome"; } bundle agent method_worst # @brief This bundle activates a promise that is repaired (/bin/true), a promise that is not kept (/bin/false), and a promise that is kept (report) { commands: "$(G.true)" comment => "This promsie should have a repaired outcome"; "$(G.false)" comment => "This promise should have a not_kept outcome"; reports: "$(this.bundle)" comment => "This promsie should have a kept outcome"; } cfengine-3.24.2/tests/acceptance/21_methods/call_methods_using_array_expansion.cf.expected.txt0000644000000000000000000000005315010704253032623 0ustar00rootroot00000000000000Bundle b1 Bundle b2 param Bundle b2 param2 cfengine-3.24.2/tests/acceptance/21_methods/array_reset.cf0000644000000000000000000000166115010704253023406 0ustar00rootroot00000000000000####################################################### # # Redmine 6369 - make sure that arrays don't accumulate # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "key_value" slist => { 1, 2, 3 }; methods: "in" usebundle => test_method($(key_value), $(key_value)); } bundle agent test_method(key, value) { vars: "array[$(key)]" string => "$(value)"; } bundle agent check { vars: "indices" slist => getindices("test_method.array"); "dim" int => length("indices"); classes: "ok" expression => strcmp("$(dim)", "1"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG.!ok:: "test_method.array has $(dim) entries instead of 1"; } cfengine-3.24.2/tests/acceptance/21_methods/warn_only.cf0000644000000000000000000000174215010704253023076 0ustar00rootroot00000000000000####################################################### # # Redmine#4852: test kept methods reporting # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body action warnonly { action_policy => "warn"; } ####################################################### bundle agent test { methods: "verify" usebundle => test_method, action => warnonly, classes => if_else("method_kept", "method_notkept"); } bundle agent test_method { reports: "unwanted sideeffect!" classes => if_else("report_kept", "report_notkept"); } bundle agent check { classes: "ok" expression => "method_notkept.!report_kept.!report_notkept"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/21_methods/reachable/0000755000000000000000000000000015010704253022456 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_promiser_call_by_arg_undefined.x.cf0000644000000000000000000000120115010704253032760 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent baz { reports: "$(this.promise_filename) Pass"; } bundle agent bar(x) { methods: "$(x)"; # Tries to call bazz, doesn't exist, shouldn't work } bundle agent main { methods: "foo" usebundle => bar("bazz"); } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_usebundle_defined.cf0000644000000000000000000000102515010704253027763 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent bar { reports: "$(this.promise_filename) Pass"; } bundle agent main { methods: "foo" usebundle => bar; } bundle_reversed_usebundle_parameters_undefined.x.cf0000644000000000000000000000140215010704253034636 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/21_methods/reachable# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. # reversed tests are just to show it should behave the same # if the called bundle comes after instead of before bundle agent main { methods: "foo" usebundle => bar("baz"); # Should error because bar does not exist } bundle agent foo(x) { # foo exists, but it's not the bundle we are looking for reports: "$(x)"; "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_promiser_call_by_arg_defined.cf0000644000000000000000000000115715010704253032161 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent baz { reports: "$(this.promise_filename) Pass"; } bundle agent bar(x) { methods: "$(x)"; # Tries to call baz, exists, works } bundle agent main { methods: "foo" usebundle => bar("baz"); } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_promiser_undefined.x.cf0000644000000000000000000000074215010704253030453 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent main { methods: "foo"; # Should error because foo does not exist } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_usebundle_call_by_arg_defined.cf0000644000000000000000000000122015010704253032276 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent baz { reports: "$(this.promise_filename) Pass"; } bundle agent bar(x) { methods: "foo" usebundle => "$(x)"; # Will call baz, which exists, should work } bundle agent main { methods: "foo" usebundle => bar("baz"); } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_usebundle_parameters_undefined.x.cf0000644000000000000000000000122015010704253033014 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent foo(x) { # foo exists, but it's not the bundle we are looking for reports: "$(x)"; "$(this.promise_filename) Pass"; } bundle agent main { methods: "foo" usebundle => bar("baz"); # Should error because bar does not exist } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_usebundle_parameters_defined.cf0000644000000000000000000000115215010704253032207 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent bar(x) { # bar exists and it's the bundle we want, so this will pass: reports: "$(x)"; "$(this.promise_filename) Pass"; } bundle agent main { methods: "foo" usebundle => bar("baz"); } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_usebundle_undefined.x.cf0000644000000000000000000000111115010704253030570 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent foo { # foo exists but it's not the bundle we are looking for } bundle agent main { methods: "foo" usebundle => bar; # Should error because bar does not exist } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_usebundle_unreachable.cf0000644000000000000000000000115415010704253030641 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent baz { reports: "$(this.promise_filename) Pass"; } bundle agent main { methods: "foo" if => "out_of_context", usebundle => "bar"; # Should not error because it's unreachable "baz"; } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_promiser_defined.cf0000644000000000000000000000077615010704253027651 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent foo { reports: "$(this.promise_filename) Pass"; } bundle agent main { methods: "foo"; } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_promiser_unreachable.cf0000644000000000000000000000113015010704253030505 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent bar { reports: "$(this.promise_filename) Pass"; } bundle agent main { methods: out_of_context:: "foo"; # Should not error because it's unreachable any:: "bar"; } cfengine-3.24.2/tests/acceptance/21_methods/reachable/bundle_usebundle_call_by_arg_undefined.x.cf0000644000000000000000000000123215010704253033112 0ustar00rootroot00000000000000# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. bundle agent baz { reports: "$(this.promise_filename) Pass"; } bundle agent bar(x) { methods: "foo" usebundle => "$(x)"; # Tries to call bazz, doesn't exist, shouldn't work } bundle agent main { methods: "foo" usebundle => bar("bazz"); } bundle_reversed_usebundle_parameters_defined.cf0000644000000000000000000000133415010704253034031 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/21_methods/reachable# Reachable bundle tests verify that you are allowed have references # to undefined bundles, as long as they are not actually called. # These tests are left very simple on purpose, # they are not using the test framework. # They should be seen together, note that defined vs undefined variants are # almost identical, just replacing one detail to show what should work # and what should error. # reversed tests are just to show it should behave the same # if the called bundle comes after instead of before bundle agent main { methods: "foo" usebundle => bar("baz"); } bundle agent bar(x) { # bar exists and it's the bundle we want, so this will pass: reports: "$(x)"; "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/21_methods/reporting/0000755000000000000000000000000015010704253022561 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/21_methods/reporting/kept.cf0000644000000000000000000000220515010704253024035 0ustar00rootroot00000000000000####################################################### # # Redmine#4852: test kept methods reporting # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { methods: "create" usebundle => test_create_hello; } ####################################################### bundle agent test { methods: "verify" usebundle => test_create_hello, classes => test_verify_method; reports: OK:: "OK"; FAIL:: "FAIL"; } bundle agent test_create_hello { files: "$(G.testfile)" create => "true", perms => test_m("000"), action => test_immediate; } body perms test_m(mode) { mode => $(mode); } body action test_immediate { ifelapsed => 0; } body classes test_verify_method { promise_kept => {"ok"}; } bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/21_methods/callers/0000755000000000000000000000000015010704253022175 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/21_methods/callers/promisers_indirectly.cf0000644000000000000000000000372315010704253026765 0ustar00rootroot00000000000000####################################################### # # Test the variable this.callers_promisers with one bundle called twice # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle agent test { methods: "test" usebundle => "caller"; } bundle agent check { reports: success_first.success_second:: "$(this.promise_filename) Pass"; !(success_first.success_second):: "$(this.promise_filename) FAIL"; } bundle agent caller { methods: "first call" usebundle => dummy; "second call" usebundle => dummy_inter; } bundle agent dummy_inter { methods: "inter" usebundle => dummy; } bundle agent dummy { vars: # This bundle gets called twice, once directly, and once via dummy_inter "callers_promisers" slist => callstack_promisers(); "callers_promisers_expect_first" string => "any, any, test, first call"; "callers_promisers_expect_second" string => "any, any, test, second call, inter"; "callers_promisers_actual" string => join(", ", "callers_promisers"); classes: "success_first" expression => strcmp("${callers_promisers_expect_first}", "${callers_promisers_actual}"), scope => "namespace"; "success_second" expression => strcmp("${callers_promisers_expect_second}", "${callers_promisers_actual}"), scope => "namespace"; reports: DEBUG:: "EXPECT (first in ${this.bundle}): callers_promisers_string = ${callers_promisers_expect_first}"; "ACTUAL (first in ${this.bundle}): callers_promisers_string = ${callers_promisers_actual}"; "EXPECT (second in ${this.bundle}): callers_promisers_string = ${callers_promisers_expect_second}"; "ACTUAL (second in ${this.bundle}): callers_promisers_string = ${callers_promisers_actual}"; } cfengine-3.24.2/tests/acceptance/21_methods/callers/callers_directly.cf0000644000000000000000000000260015010704253026031 0ustar00rootroot00000000000000####################################################### # # Test the variable this.callers_promisers with one bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle agent test { methods: "test" usebundle => "caller"; } bundle agent check { vars: "callers_expect" string => "agent"; # Due to the 4K variable limit we cannot test the whole structure, so # just test one element within it. At least it's not completely broken # if we find it. "callers_actual" string => "$(dummy.callers[0][bundle][bundleType])"; classes: "success" expression => strcmp("${callers_expect}", "${callers_actual}"), scope => "namespace"; reports: success:: "$(this.promise_filename) Pass"; !success:: "$(this.promise_filename) FAIL"; methods: "any" usebundle => file_make($(G.testfile), $(callers_actual)); reports: DEBUG:: "EXPECT: callers_string = ${callers_expect}"; "ACTUAL: callers_string = $(callers_actual)"; } bundle agent caller { methods: "first call" usebundle => dummy; } bundle agent dummy { vars: "callers" data => callstack_callers(); } cfengine-3.24.2/tests/acceptance/21_methods/callers/promisers_directly.cf0000644000000000000000000000232715010704253026435 0ustar00rootroot00000000000000####################################################### # # Test the variable this.callers_promisers with one bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle agent test { methods: "test" usebundle => "caller"; } bundle agent check { reports: success:: "$(this.promise_filename) Pass"; !success:: "$(this.promise_filename) FAIL"; } bundle agent caller { methods: "first call" usebundle => dummy; } bundle agent dummy { vars: "callers_promisers" slist => callstack_promisers(); "callers_promisers_expect" string => "any, any, test, first call"; "callers_promisers_actual" string => join(", ", "callers_promisers"); classes: "success" expression => strcmp("${callers_promisers_expect}", "${callers_promisers_actual}"), scope => "namespace"; reports: DEBUG:: "EXPECT: callers_promisers_string = ${callers_promisers_expect}"; "ACTUAL: callers_promisers_string = ${callers_promisers_actual}"; } cfengine-3.24.2/tests/acceptance/21_methods/call_methods_using_array_expansion.cf0000644000000000000000000000267515010704253030221 0ustar00rootroot00000000000000####################################################### # # Redmine 6369 - make sure that arrays don't accumulate # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { commands: windows:: "$(G.dos2unix) $(this.promise_filename).expected.txt" -> { "ENT-10433" }; files: "$(G.testdir)/reports.txt" delete => tidy; } bundle agent test { meta: "description" -> { "CFE-636" } string => "Check that methods can be called by expanding classic arrays"; vars: "b1" string => "b1"; "b2" string => "b2"; "b[b2]" string => "b2"; methods: "${b1}" usebundle => ${b1}; "${b[b2]}" usebundle => ${b[b2]}("param"); "${b[b2]}" usebundle => ${b[${b2}]}("param2"); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_diff( "$(G.testdir)/reports.txt", "$(this.promise_filename).expected.txt", $(this.promise_filename)); } bundle agent b1{ reports: cfengine:: "Bundle b1" report_to_file => "$(G.testdir)/reports.txt"; } bundle agent b2(ref){ reports: cfengine:: "Bundle b2 ${ref}" report_to_file => "$(G.testdir)/reports.txt"; } cfengine-3.24.2/tests/acceptance/21_methods/usebundle_with_or_without.cf0000644000000000000000000000411615010704253026370 0ustar00rootroot00000000000000# Test that methods promises work correctly both with and without usebundle. body common control { inputs => { '../default.cf.sub' }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { vars: "test_var7" string => "7"; "test_var8" string => "8"; methods: "check1"; "check2" usebundle => check2; "bad_check3" usebundle => check3; #"checkN(4)"; # Not currently working. "checkN(5)" usebundle => checkN(5); "bad_checkN(6)" usebundle => checkN(6); "checkN(bad)" usebundle => checkN(good); "check$(test_var7)"; #"checkN($(test_var8))"; # Not currently working. } bundle agent check1 { classes: "ok_1" expression => "any", scope => "namespace"; } bundle agent check2 { classes: "ok_2" expression => "any", scope => "namespace"; } bundle agent check3 { classes: "ok_3" expression => "any", scope => "namespace"; } bundle agent bad_check3 { classes: "bad_3" expression => "any", scope => "namespace"; } bundle agent checkN(X) { classes: "ok_$(X)" expression => "any", scope => "namespace"; } bundle agent bad_checkN(X) { classes: "bad_$(X)" expression => "any", scope => "namespace"; } bundle agent check7 { classes: "ok_7" expression => "any", scope => "namespace"; } bundle agent check { vars: "cases" slist => { 1, 2, 3, 5, 6, 7, "good" }; "positive" slist => maplist("ok_$(this)", "cases"); "negative" slist => { maplist("bad_$(this)", "cases"), "ok_bad" }; classes: "positive_match" and => { @(positive) }; "negative_match" or => { @(negative) }; "ok" expression => "positive_match.!negative_match"; reports: DEBUG:: "Classes not set that should be: $(positive)" if => "!$(positive)"; "Classes set that should not be: $(negative)" if => "$(negative)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/root-MD5=617eb383deffef843ea856b129d0a423.pub0000644000000000000000000000065215010704253025350 0ustar00rootroot00000000000000-----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA56WwX+9IW9Hbw83iDf8uAdSciUgTgFQQG0ror5rxUXoTyetChNKW y2JlOqHO61dIbEkSAg9C1bp3N6/ukkjXwqEOMf4W0BLfkZaFTrZvy8ivbE/HconJ ZWzvJ/jNKI7z8SbEMCfAPuH+z+bwcLCi+Ut1/Byy4kZupIGM4DiJwjI7ldsHdEZG D6lplmPre9k/07pZl04o0NqiTheL3EWaGzFPOBBXSe9PaeuX/WSBYmc3Jc6SqlZO MmDm5mywHnD2uhCnZDeSOfaWhj4XhA41LL00h+g006JSLtWzrrkQHJkRvVEHWGu9 qAvAddXihFMwquFsOPNGrhaOK76q2kVf/QIDAQAB -----END RSA PUBLIC KEY----- cfengine-3.24.2/tests/acceptance/11_databases/0000755000000000000000000000000015010704253021033 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/11_databases/00_syntax/0000755000000000000000000000000015010704253022660 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/11_databases/00_syntax/missing_database_operation.cf0000644000000000000000000000140115010704253030543 0ustar00rootroot00000000000000# Test that missing database_operation does not segfault (Mantis #1046) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { databases: "foobar" database_type => "sql", database_server => myserver; } body database_server myserver { db_server_owner => "owner"; db_server_password => "password"; db_server_host => "localhost"; db_server_type => "postgres"; db_server_connection_db => "postgres"; } bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } ### PROJECT_ID: core ### CATEGORY_ID: 33 cfengine-3.24.2/tests/acceptance/dummy_etc/0000755000000000000000000000000015010704253020571 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/dummy_etc/null0000644000000000000000000000000015010704253021454 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/dummy_etc/motd0000644000000000000000000000004415010704253021455 0ustar00rootroot00000000000000Welcome to the CFEngine Test Suite! cfengine-3.24.2/tests/acceptance/dummy_etc/group0000644000000000000000000000146515010704253021656 0ustar00rootroot00000000000000root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20: fax:x:21: voice:x:22: cdrom:x:24: floppy:x:25: tape:x:26: sudo:x:27: audio:x:29:pulse dip:x:30: www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: src:x:40: gnats:x:41: shadow:x:42: utmp:x:43: video:x:44: sasl:x:45: plugdev:x:46: staff:x:50: games:x:60: users:x:100: nogroup:x:65534: libuuid:x:101: crontab:x:102: syslog:x:103: fuse:x:104: messagebus:x:105: bluetooth:x:106: scanner:x:107: colord:x:108: lpadmin:x:109: ssl-cert:x:110: lightdm:x:111: nopasswdlogin:x:112: netdev:x:113: whoopsie:x:114: mlocate:x:115: ssh:x:116: avahi-autoipd:x:117: avahi:x:118: pulse:x:119: pulse-access:x:120: utempter:x:121: rtkit:x:122: saned:x:123: sambashare:x:124: cfengine-3.24.2/tests/acceptance/dummy_etc/passwd0000644000000000000000000000311115010704253022011 0ustar00rootroot00000000000000root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh proxy:x:13:13:proxy:/bin:/bin/sh www-data:x:33:33:www-data:/var/www:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh list:x:38:38:Mailing List Manager:/var/list:/bin/sh irc:x:39:39:ircd:/var/run/ircd:/bin/sh gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh libuuid:x:100:101::/var/lib/libuuid:/bin/sh syslog:x:101:103::/home/syslog:/bin/false messagebus:x:102:105::/var/run/dbus:/bin/false colord:x:103:108:colord colour management daemon,,,:/var/lib/colord:/bin/false lightdm:x:104:111:Light Display Manager:/var/lib/lightdm:/bin/false whoopsie:x:105:114::/nonexistent:/bin/false avahi-autoipd:x:106:117:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/bin/false avahi:x:107:118:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false usbmux:x:108:46:usbmux daemon,,,:/home/usbmux:/bin/false kernoops:x:109:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false pulse:x:110:119:PulseAudio daemon,,,:/var/run/pulse:/bin/false rtkit:x:111:122:RealtimeKit,,,:/proc:/bin/false saned:x:112:123::/home/saned:/bin/false speech-dispatcher:x:113:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh hplip:x:114:7:HPLIP system user,,,:/var/run/hplip:/bin/false cfengine-3.24.2/tests/acceptance/dummy_etc/shadow0000644000000000000000000000162615010704253022006 0ustar00rootroot00000000000000root:!:15797:0:99999:7::: daemon:*:15797:0:99999:7::: bin:*:15797:0:99999:7::: sys:*:15797:0:99999:7::: sync:*:15797:0:99999:7::: games:*:15797:0:99999:7::: man:*:15797:0:99999:7::: lp:*:15797:0:99999:7::: mail:*:15797:0:99999:7::: news:*:15797:0:99999:7::: uucp:*:15797:0:99999:7::: proxy:*:15797:0:99999:7::: www-data:*:15797:0:99999:7::: backup:*:15797:0:99999:7::: list:*:15797:0:99999:7::: irc:*:15797:0:99999:7::: gnats:*:15797:0:99999:7::: nobody:*:15797:0:99999:7::: libuuid:!:15797:0:99999:7::: syslog:*:15797:0:99999:7::: messagebus:*:15797:0:99999:7::: colord:*:15797:0:99999:7::: lightdm:*:15797:0:99999:7::: whoopsie:*:15797:0:99999:7::: avahi-autoipd:*:15797:0:99999:7::: avahi:*:15797:0:99999:7::: usbmux:*:15797:0:99999:7::: kernoops:*:15797:0:99999:7::: pulse:*:15797:0:99999:7::: rtkit:*:15797:0:99999:7::: saned:*:15797:0:99999:7::: speech-dispatcher:!:15797:0:99999:7::: hplip:*:15797:0:99999:7::: cfengine-3.24.2/tests/acceptance/16_cf-serverd/0000755000000000000000000000000015010704253021151 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/0000755000000000000000000000000015010704253022430 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/001.cf0000644000000000000000000000154215010704253023244 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/allow_path1_then_deny_path2_b.cf0000644000000000000000000000273615010704253030621 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { create_directories, default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file - G.testdir is denied. "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/server1_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server1_latest"); "any" usebundle => dcs_fini("$(G.testdir)/server2_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server2_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_deny_one_directory.srv"); "any" usebundle => start_server("$(this.promise_dirname)/localhost_deny_one_directory_with_regex.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_deny_one_directory.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_deny_one_directory_with_regex.srv"); } # For the access rules in cf-serverd to work recursively, the paths must exist and be directories bundle agent create_directories { files: "$(G.testroot)/." create => "true"; "$(G.testdir)/." create => "true"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_closed_deny_hostnames.srv0000644000000000000000000000162015010704253031604 0ustar00rootroot00000000000000# In access_rules, deny "localhost" instead of "127.0.0.1" body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9887"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "0.0.0.0/0" }, # admit everyone but deny_hostnames => { "localhost", "localhost.localdomain" }; # deny is stronger than admit } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_inexistent_file_connection_closed.cf0000644000000000000000000000175115010704253033764 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => dcs_fini("$(G.testdir)/destfile2"); "any" usebundle => dcs_fini("$(G.testdir)/destfile3"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_expand_ip_directory.cf.sub0000644000000000000000000000407615010704253031651 0ustar00rootroot00000000000000####################################################### # # copy_from from within recursively admitted directory that does not # exist during daemon init time, e.g. /path/to/$(connection.ip) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: # Admitted in cf-serverd using trailing slash "$(G.testdir)/destination_file1" copy_from => copy_src_file("$(G.testdir)/127.0.0.1_DIR1/ADMIT_FILE"); # Admitted in cf-serverd using trailing slashdot "$(G.testdir)/destination_file2" copy_from => copy_src_file("$(G.testdir)/127.0.0.1_DIR2/ADMIT_FILE"); } ######################################################### body copy_from copy_src_file(file) { source => "$(file)"; # Special variable expansion only works with "latest" protocol. protocol_version => "latest"; servers => { "127.0.0.1" }; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected("$(G.testdir)/127.0.0.1_DIR1/ADMIT_FILE", "$(G.testdir)/destination_file1", "no", "same_file1", "differ_file1"); "any" usebundle => dcs_if_diff_expected("$(G.testdir)/127.0.0.1_DIR2/ADMIT_FILE", "$(G.testdir)/destination_file2", "no", "same_file2", "differ_file2"); reports: same_file1.same_file2:: "$(fn[1]) Pass"; !same_file1|!same_file2:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_ciphers_fail.cf0000644000000000000000000000204615010704253027451 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => dcs_fini("$(G.testdir)/destfile2"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/nondefault_ciphers_tlsversion.srv"); "any" usebundle => start_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/nondefault_ciphers_tlsversion.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_same_expand_shortcut.cf0000644000000000000000000000171615010704253032602 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source and Destination are identical"); # destination files "any" usebundle => file_make("$(G.testdir)/destfile_classic", "Source and Destination are identical"); "any" usebundle => file_make("$(G.testdir)/destfile_latest", "Source and Destination are identical"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_missing_ok.cf.sub0000644000000000000000000000333315010704253026730 0ustar00rootroot00000000000000####################################################### # # Tries to copy using TLS (which is default now), from two servers: one # with the default TLS ciphers list and another with a non-default very # restricted one. # # It should fail since we are setting "tls_ciphers" to a cipher missing # in both servers. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { } bundle agent test { files: "$(G.testdir)/out/missing_ok" classes => classes_generic("test"), copy_from => dcs_remote_cp_X("nodir/does_not_exist", "127.0.0.1", "true"); # try to copy a file after the previous was not found "$(G.testdir)/out/second_file_should_be_ok" classes => classes_generic("test2"), copy_from => dcs_remote_cp_X("source_file", "127.0.0.1", "false"); } bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: test_kept.test2_repaired:: "$(fn[1]) Pass"; test_failed|test_repaired|test2_failed:: "$(fn[1]) FAIL"; } body copy_from dcs_remote_cp_X(from,server, missing_ok) # @brief Download a file from a remote server. They server is always trusted. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(G.testdir)/$(from)"; compare => "mtime"; trustkey => "true"; missing_ok => "${missing_ok}"; portnumber => "9876"; # localhost_open } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_same.cf.sub0000644000000000000000000000270715010704253030101 0ustar00rootroot00000000000000####################################################### # # copy_from compare=>"digest" when file is already there - should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !copied_classic.!copied_latest:: "$(fn[1]) Pass"; copied_classic|copied_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_same_expand_ip.cf.sub0000644000000000000000000000245315010704253032126 0ustar00rootroot00000000000000####################################################### # # copy_from compare=>"digest" with server-side expansion of IP address # (TLS protocol only) when file is already there - should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destination_file" copy_from => copy_src_file, classes => if_repaired("repaired"); } ######################################################### body copy_from copy_src_file { source => "$(G.testdir)/127.0.0.1.txt"; protocol_version => "latest"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !repaired:: "$(fn[1]) Pass"; repaired:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_different_expand_ip.cf0000644000000000000000000000155315010704253032357 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: "any" usebundle => file_make("$(G.testdir)/127.0.0.1.txt", "Source and Destination are different_A"); "any" usebundle => file_make("$(G.testdir)/destination_file", "Source and Destination are different_B"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_expand_ip_directory.cf0000644000000000000000000000261015010704253031051 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/127.0.0.1_DIR1/." create => "true"; "$(G.testdir)/127.0.0.1_DIR2/." create => "true"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR1/ADMIT_FILE", "ADMIT_FILE A CONTENTS"); "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR1/DENY_FILE", "DENY_FILE A CONTENTS"); "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR2/ADMIT_FILE", "ADMIT_FILE B CONTENTS"); "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR2/DENY_FILE", "DENY_FILE B CONTENTS"); "any" usebundle => dcs_fini("$(G.testdir)/destination_file1"); "any" usebundle => dcs_fini("$(G.testdir)/destination_file2"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/008.cf0000644000000000000000000000164215010704253023254 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_reordered_ciphers_success.cf.sub0000644000000000000000000000226715010704253033036 0ustar00rootroot00000000000000####################################################### # # Tries to copy using TLS (which is default now), from two servers: one # with the default TLS ciphers list and another with a non-default very # restricted one. # # It should succeed in both cases since default client-side cipherlist # is OpenSSL's default, which is very broad. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; # Do not set this, just use the very broad OpenSSL default. # # tls_ciphers => ""; } bundle agent init { } bundle agent test { files: # Server with reordered default "allowciphers" "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9893"), classes => classes_generic("copy1"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); reports: copy1_repaired.exists1:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/010.cf0000644000000000000000000000164215010704253023245 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_deny_one_directory_with_regex.srv0000644000000000000000000000144715010704253033353 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9882"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testroot)/" admit => { "192.168.*", ".*", "10.*" }, deny => { "127.0*" }; # this matches nothing "$(G.testdir)/" deny => { ".*" }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_tls_1_3_fail.cf0000644000000000000000000000236415010704253027263 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_skip_unsupported" string => "!feature_tls_1_3"; "description" -> {"ENT-4617"} string => "Test that requiring TLS 1.3 works fine"; "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => dcs_fini("$(G.testdir)/destfile2"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/no_tls_1_3.srv"); "any" usebundle => start_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/no_tls_1_3.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/002.cf.sub0000644000000000000000000000301715010704253024034 0ustar00rootroot00000000000000####################################################### # # mtime, newer destination, localhost, should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; portnumber => "9876"; # localhost_open #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !copied_classic.!copied_latest:: "$(fn[1]) Pass"; copied_classic|copied_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_open.srv0000644000000000000000000000313115010704253026173 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9876"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; "$(G.testdir)/$(connection.ip).txt" admit_ips => { "$(connection.ip)" }, shortcut => "expand_ip_source"; # Directory existing only in connection time (not in daemon init # time), after special variables have been expanded. So we need to # specify recursive access by appending trailing slash or slashdot. # Trailing slash "$(G.testdir)/$(connection.ip)_DIR1/" admit_ips => { "$(connection.ip)" }; # Trailing slashdot, should be equivalent to trailing slash "$(G.testdir)/$(connection.ip)_DIR2/." admit_ips => { "$(connection.ip)" }; # Deny access to a file within a recursively admitted directory! "$(G.testdir)/$(connection.ip)_DIR1/DENY_FILE" deny_ips => { "$(connection.ip)" }; "$(G.testdir)/$(connection.ip)_DIR2/DENY_FILE" deny_ips => { "$(connection.ip)" }; } copy_from_expand_ip_admit_directory_deny_file.cf0000644000000000000000000000246215010704253034173 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/127.0.0.1_DIR1/." create => "true"; "$(G.testdir)/127.0.0.1_DIR2/." create => "true"; } bundle agent test { methods: "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR1/ADMIT_FILE", "ADMIT_FILE A CONTENTS"); "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR1/DENY_FILE", "DENY_FILE A CONTENTS"); "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR2/ADMIT_FILE", "ADMIT_FILE B CONTENTS"); "any" usebundle => file_make("$(G.testdir)/127.0.0.1_DIR2/DENY_FILE", "DENY_FILE B CONTENTS"); "any" usebundle => dcs_fini("$(G.testdir)/destination_file1"); "any" usebundle => dcs_fini("$(G.testdir)/destination_file2"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_tls_1_3_success.cf.sub0000644000000000000000000000241115010704253030601 0ustar00rootroot00000000000000####################################################### # # Tries to copy using TLS 1.3, from two servers: # - one with only TLS 1.3 enabled # - one with the defaults # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; # Require TLS 1.3 tls_min_version => "1.3"; } bundle agent init { } bundle agent test { files: # Server only allowing TLS 1.3 "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9894"), classes => classes_generic("copy1"); # Server with default "allowciphers" and "allowtlsversion" "$(G.testdir)/destfile2" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9889"), classes => classes_generic("copy2"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); "exists2" expression => fileexists("$(G.testdir)/destfile2"); reports: (copy1_repaired.copy2_repaired).(exists1.exists2):: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/tcp_port_listen_outside_range.x.cf0000644000000000000000000000060115010704253031325 0ustar00rootroot00000000000000# # Check the parser enforces standard TCP port ( 1 <= port <= 65535) for: # -cf-serverd listening port # body common control { bundlesequence => { default("$(this.promise_filename)") }; inputs => { "../../default.cf.sub" }; version => "1.0"; } body server control { port => "65536"; } bundle agent test { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/011.cf0000644000000000000000000000164215010704253023246 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/simple_copy_from_deny_localhost.cf.sub0000644000000000000000000000410315010704253032165 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises, mtime simple copy localhost # The source server has access_rules admit=>{"localhost"} # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: # localhost_closed_hostname "$(G.testdir)/server1_classic" copy_from => copy_file("9885", "classic"), classes => if_repaired("repaired1_classic"); "$(G.testdir)/server1_latest" copy_from => copy_file("9885", "latest"), classes => if_repaired("repaired1_latest"); # localhost_closed_deny_hostnames "$(G.testdir)/server2_classic" copy_from => copy_file("9887", "classic"), classes => if_repaired("repaired2_classic"); "$(G.testdir)/server2_latest" copy_from => copy_file("9887", "latest"), classes => if_repaired("repaired2_latest"); } ######################################################### body copy_from copy_file(port, protocol_version) { source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; portnumber => "$(port)"; protocol_version => "$(protocol_version)"; #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !repaired1_classic.!repaired1_latest.!repaired2_classic.!repaired2_latest:: "$(fn[1]) Pass"; repaired1_classic|repaired1_latest|repaired2_classic|repaired2_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/007.cf0000644000000000000000000000164215010704253023253 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } copy_from_expand_ip_admit_directory_deny_file.cf.sub0000644000000000000000000000317115010704253034761 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial####################################################### # # copy_from from within recursively admitted directory that does not # exist during daemon init time, e.g. /path/to/$(connection.ip), # but the file itself is in "deny" list! # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: # Directory admitted in cf-serverd using trailing slash "$(G.testdir)/destination_file1" copy_from => copy_src_file("$(G.testdir)/127.0.0.1_DIR1/DENY_FILE"), classes => if_repaired("repaired1"); # Directory admitted in cf-serverd using trailing slashdot "$(G.testdir)/destination_file2" copy_from => copy_src_file("$(G.testdir)/127.0.0.1_DIR2/DENY_FILE"), classes => if_repaired("repaired2"); } ######################################################### body copy_from copy_src_file(file) { source => "$(file)"; protocol_version => "latest"; servers => { "127.0.0.1" }; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !repaired1.!repaired2:: "$(fn[1]) Pass"; repaired1|repaired2:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_open_admit_hostnames.srv0000644000000000000000000000142515010704253031436 0ustar00rootroot00000000000000# In access_rules, admit "localhost" instead of "127.0.0.1" body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9886"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit_hostnames => { "localhost", "localhost.localdomain" }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/allowlegacyconnects_open.srv0000644000000000000000000000140115010704253030241 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9890"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # ADMIT CLASSIC PROTOCOL allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/reordered_default_ciphers_tlsversion.srv0000644000000000000000000000144315010704253032652 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9893"; # Use the defaults, but reordered: allowciphers => "TLS_AES_256_GCM_SHA384:AES256-GCM-SHA384:AES256-SHA"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/tcp_port_listen_within_range.cf0000644000000000000000000000055715010704253030717 0ustar00rootroot00000000000000# # Check the parser enforces standard TCP port ( 1 <= port <= 65535) for: # -cf-serverd listening port # body common control { bundlesequence => { default("$(this.promise_filename)") }; inputs => { "../../default.cf.sub" }; version => "1.0"; } body server control { port => "5308"; } bundle agent test { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/simple_copy_from_admit_localhost.cf.sub0000644000000000000000000000516315010704253032333 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises, mtime simple copy localhost # The source server has access_rules admit=>{"localhost"} # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: # localhost_open_hostname "$(G.testdir)/server1_classic" copy_from => copy_file("9884", "classic"); "$(G.testdir)/server1_latest" copy_from => copy_file("9884", "latest"); # localhost_open_admit_hostnames "$(G.testdir)/server2_classic" copy_from => copy_file("9886", "classic"); "$(G.testdir)/server2_latest" copy_from => copy_file("9886", "latest"); } ######################################################### body copy_from copy_file(port, protocol_version) { source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; portnumber => "$(port)"; protocol_version => "$(protocol_version)"; #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/server1_classic", "no", "same_classic1", "differ_classic1"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/server1_latest", "no", "same_latest1", "differ_latest1"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/server2_classic", "no", "same_classic2", "differ_classic2"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/server2_latest", "no", "same_latest2", "differ_latest2"); reports: same_classic1.same_latest1.same_classic2.same_latest2:: "$(fn[1]) Pass"; !same_classic1|!same_latest1|!same_classic2|!same_latest2:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_classic_protocol_success.cf.sub0000644000000000000000000000201315010704253032675 0ustar00rootroot00000000000000####################################################### # # Tries to copy using the "classic" protocol, from a server that has # "allowlegacyconnects" open. # # It should succeed. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; # FORCE CLASSIC PROTOCOL protocol_version => "classic"; } bundle agent init { } bundle agent test { files: # Copy from server with allowlegacyconnects open. "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9890"), classes => classes_generic("copy1"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); reports: copy1_repaired.exists1.!copy1_failed:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/006.cf.sub0000644000000000000000000000435015010704253024041 0ustar00rootroot00000000000000####################################################### # # mtime server copy, localhost, trustkey = false, should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: # WAZA! I can't enable both protocols to be tested because the second # will always succeed! Here is why: # cf-serverd and cf-agent are running in the same tree, so they have # the same ID! (same localhost.priv,pub) So when we (the agent) # contact the server 1st time, we drop the connection because we don't # trust him, but *his* trust is open and he stores the proper # MD5-xxx.pub file that identifies us. BUT THIS FILE IDENTIFIES THE # SERVER AS WELL. So on the second (latest protocol) connection # attempt, we (the agent) find that file and assume we have # established trust with the server. Thus this test fails... "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); # "$(G.testdir)/destfile_latest" # copy_from => copy_src_file("latest"), # classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; #trustkey => "true"; portnumber => "9876"; # localhost_open #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !copied_classic.!copied_latest:: "$(fn[1]) Pass"; copied_classic|copied_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_closed_hostname.srv0000644000000000000000000000157015010704253030406 0ustar00rootroot00000000000000# In access_rules, deny "localhost" instead of "127.0.0.1" body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9885"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "0.0.0.0/0" }, # admit everyone deny => { "localhost", "localhost.localdomain" }; # deny is stronger than admit } copy_from_digest_different_expand_shortcut.cf.sub0000644000000000000000000000375615010704253034342 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial####################################################### # # copy_from compare=>"digest" with server-side shortcut expansion # when file is there but differs - should copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; # server-side expansion of shortcut source => "simple_source"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected("$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected("$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } copy_from_inexistent_file_connection_closed-classic_protocol.cf.sub0000644000000000000000000000311015010704253040024 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial####################################################### # # CFE-2532: failure to get one file causes all subsequent copy_from # promises to also fail - classic protocol version # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; protocol_version => "classic"; } bundle agent init { } bundle agent test { files: # Copy 1st file successfully "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9876"), classes => classes_generic("copy1"); # Copy 2nd file, WILL FAIL "$(G.testdir)/destfile2" copy_from => dcs_remote_cp("DOES_NOT_EXIST", "127.0.0.1", "9876"), classes => classes_generic("copy2"); # Copy 3rd file, MUST SUCCEED DESPITE PREVIOUS FAILURE "$(G.testdir)/destfile3" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9876"), classes => classes_generic("copy3"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); "exists2" expression => fileexists("$(G.testdir)/destfile2"); "exists3" expression => fileexists("$(G.testdir)/destfile3"); reports: copy1_repaired.exists1.!copy1_failed.copy3_repaired.exists3.!copy3_failed.!copy2_repaired.!exists2.copy2_failed:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_deny_one_directory.srv0000644000000000000000000000134615010704253031124 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9881"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testroot)/" admit => { "127.0.0.1", "::1" }; "$(G.testdir)/" deny => { "127.0.0.1", "::1" }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/no_tls_1_3.srv0000644000000000000000000000151015010704253025121 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9895"; # Do not allow TLS 1.3 (no TLS 1.3 cipher suites listed below) allowciphers => "AES256-GCM-SHA384:AES256-SHA"; allowtlsversion => "1.1"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/003.cf0000644000000000000000000000153415010704253023247 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_deny_connect.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_deny_connect.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/simple_copy_from_admit_localhost.cf0000644000000000000000000000340415010704253031537 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_suppress_fail" string => "windows", meta => { "redmine6405", "ENT-2480"}; # Ubuntu 20 (at least our build machines) doesn't know how to resolve # 127.0.0.1/::1 to localhost, the reverse lookup fails and so # 'admit => { "localhost" };' and 'admit_hostnames => { "localhost" };' # are not enough to allow access for this test. # Test fails on SLES / OpenSUSE 15, pending investigation. "test_skip_unsupported" string => "(ubuntu_20|ubuntu_22|debian_12|sles_15|opensuse_leap_15)", meta => { "ENT-2480", "ENT-7362", "ENT-9055" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/server1_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server1_latest"); "any" usebundle => dcs_fini("$(G.testdir)/server2_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server2_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open_hostname.srv"); "any" usebundle => start_server("$(this.promise_dirname)/localhost_open_admit_hostnames.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open_hostname.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open_admit_hostnames.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_classic_protocol_fail.cf0000644000000000000000000000203715010704253031356 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile"); "any" usebundle => dcs_fini("$(G.testdir)/destfile2"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/allowlegacyconnects_closed.srv"); "any" usebundle => start_server("$(this.promise_dirname)/allowlegacyconnects_absent.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/allowlegacyconnects_closed.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/allowlegacyconnects_absent.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/nondefault_ciphers_tlsversion.srv0000644000000000000000000000151115010704253031326 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9888"; # Only this cipher is to be accepted allowciphers => "AES128-GCM-SHA256"; # Allow only TLSv1.1 or higher allowtlsversion => "1.1"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_different.cf.sub0000644000000000000000000000354615010704253031124 0ustar00rootroot00000000000000####################################################### # # copy_from compare=>"digest" when file is there but differs - should copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/allow_path1_then_deny_path2_a.cf0000644000000000000000000000307215010704253030612 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { create_directories, default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file - on purpose in G.testroot instead of G.testdir # since the former is admitted while the latter is denied. "any" usebundle => file_make("$(G.testroot)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/server1_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server1_latest"); "any" usebundle => dcs_fini("$(G.testdir)/server2_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server2_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_deny_one_directory.srv"); "any" usebundle => start_server("$(this.promise_dirname)/localhost_deny_one_directory_with_regex.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_deny_one_directory.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_deny_one_directory_with_regex.srv"); } # For the access rules in cf-serverd to work recursively, the paths must exist and be directories bundle agent create_directories { files: "$(G.testroot)/." create => "true"; "$(G.testdir)/." create => "true"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/005.cf0000644000000000000000000000152015010704253023244 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/lan_deny_connect.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/lan_deny_connect.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_classic_protocol_fail.cf.sub0000644000000000000000000000257015010704253032150 0ustar00rootroot00000000000000####################################################### # # Tries to copy using the "classic" protocol, to a server that has # "allowlegacyconnects" closed and to one that does not have the # setting at all. # # Both must fail. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; # FORCE CLASSIC PROTOCOL protocol_version => "classic"; } bundle agent init { } bundle agent test { files: # Copy from server with allowlegacyconnects closed. "$(G.testdir)/destfile" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9892"), classes => classes_generic("copy"); # Copy from server with allowlegacyconnects absent. "$(G.testdir)/destfile2" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9891"), classes => classes_generic("copy2"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists" expression => fileexists("$(G.testdir)/destfile"); "exists2" expression => fileexists("$(G.testdir)/destfile2"); reports: copy_failed.!copy_repaired.!exists.copy2_failed.!copy2_repaired.!exists2:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/011.cf.sub0000644000000000000000000000371215010704253024036 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises # # Tests copy_from digest verify (MD5) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; copy_backup => "false"; portnumber => "9876"; # localhost_open encrypt => "false"; compare => "digest"; verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_open_with_data_select.srv0000644000000000000000000000157315010704253031566 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9883"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }; "delta" resource_type => "query", report_data_select => test_report_filter; } body report_data_select test_report_filter { monitoring_include => { "lala.*", "lalala.*" }; monitoring_exclude => { "lala.*", "lalala.*" }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/007.cf.sub0000644000000000000000000000377215010704253024051 0ustar00rootroot00000000000000####################################################### # # digest server copy, localhost, newer destination, should copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; portnumber => "9876"; # localhost_open #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_tls_1_3_success.cf0000644000000000000000000000240615010704253030015 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_skip_unsupported" string => "!feature_tls_1_3"; "description" -> {"ENT-4617"} string => "Test that CFEngine connections over TLS 1.3 work fine"; "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => dcs_fini("$(G.testdir)/destfile2"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/tls_1_3_only.srv"); "any" usebundle => start_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/tls_1_3_only.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/009.cf.sub0000644000000000000000000000135715010704253024050 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises, mtime simple copy localhost # TODO: implement # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { reports: } ####################################################### bundle agent test { reports: } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/005.cf.sub0000644000000000000000000000323615010704253024042 0ustar00rootroot00000000000000####################################################### # # mtime server copy, for non-localhost, no connect access, should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; # localhost comes first but will be denied servers => { @(sys.ip_addresses) }; compare => "mtime"; copy_backup => "false"; portnumber => "9879"; # lan_deny_connect #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !copied_classic.!copied_latest:: "$(fn[1]) Pass"; copied_classic|copied_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/allow_path1_then_deny_path2_a.cf.sub0000644000000000000000000000454715010704253031412 0ustar00rootroot00000000000000####################################################### # # We request a path from allowed path, it should succeed # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } ####################################################### body copy_from copy_from_port(port, protocol_version) { portnumber => "$(port)"; protocol_version => "$(protocol_version)"; # testroot dir is admitted on the server, while G.testdir is denied source => "$(G.testroot)/source_file"; servers => { "127.0.0.1" }; trustkey => "true"; } bundle agent test { files: # localhost_deny_one_directory "$(G.testdir)/server1_classic" copy_from => copy_from_port("9881", "classic"); "$(G.testdir)/server1_latest" copy_from => copy_from_port("9881", "latest"); # localhost_deny_one_directory_with_regex "$(G.testdir)/server2_classic" copy_from => copy_from_port("9882", "classic"); "$(G.testdir)/server2_latest" copy_from => copy_from_port("9882", "latest"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testroot)/source_file", "$(G.testdir)/server1_classic", "no", "same_classic1", "differ_classic1"); "any" usebundle => dcs_if_diff_expected( "$(G.testroot)/source_file", "$(G.testdir)/server1_latest", "no", "same_latest1", "differ_latest1"); "any" usebundle => dcs_if_diff_expected( "$(G.testroot)/source_file", "$(G.testdir)/server2_classic", "no", "same_classic2", "differ_classic2"); "any" usebundle => dcs_if_diff_expected( "$(G.testroot)/source_file", "$(G.testdir)/server2_latest", "no", "same_latest2", "differ_latest2"); reports: same_classic1.same_latest1.same_classic2.same_latest2:: "$(fn[1]) Pass"; !same_classic1|!same_latest1|!same_classic2|!same_latest2:: "$(fn[1]) FAIL"; } copy_from_digest_different_expand_ip_and_shortcut.cf.sub0000644000000000000000000000331215010704253035640 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial####################################################### # # copy_from compare=>"digest" with server-side expansion of IP address # (TLS protocol only) *and* shortcut expansion when file is there but # differs - should copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destination_file" copy_from => copy_src_file, classes => if_repaired("repaired"); } ######################################################### body copy_from copy_src_file { # server-side shortcut expansion to "$(G.testdir)/$(connection.ip).txt" source => "expand_ip_source"; # Special variable expansion only works with "latest" protocol. protocol_version => "latest"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected("$(G.testdir)/127.0.0.1.txt", "$(G.testdir)/destination_file", "no", "same_file", "differ_file"); reports: same_file:: "$(fn[1]) Pass"; !same_file:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/006.cf0000644000000000000000000000151415010704253023250 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/009.cf0000644000000000000000000000141115010704253023247 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: "any" usebundle => dcs_fini("$(G.testdir)/destination_file"); "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open_with_data_select.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open_with_data_select.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/README0000644000000000000000000000077315010704253023317 0ustar00rootroot00000000000000001 - mtime simple copy, localhost 002 - mtime, newer destination, localhost, should not copy 003 - mtime server copy, localhost, explicit deny connect access, should not copy 004 - mtime server copy, for non-localhost, should copy 005 - mtime server copy, for non-localhost, no connect access, should not copy 006 - mtime server copy, localhost, no file access promise, should not copy 007 - digest server copy, localhost, newer destination, should copy 008 - mtime simple copy, localhost with encryption cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copied_files_can_be_sparse.cf0000644000000000000000000000325715010704253030242 0ustar00rootroot00000000000000# The agent writes sparse files when detecting chunks of zeros. Here we # verify that a NULL-filled file, is fully sparse when remotely copied. body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { meta: "description" string => "ENT-2769: Test that files written are sparse when possible"; # Various exotic filesystems don't support sparseness, see the unit # test "files_copy_test.c" for details. "test_skip_unsupported" string => "!linux"; files: "$(G.testdir)/source_file" delete => tidy, handle => "init_tidy_sparse"; commands: # Create a 10MB sparse file "/bin/dd" args => "if=/dev/zero of=$(G.testdir)/source_file seek=1024 bs=1024 count=0", if => not( fileexists( "$(G.testdir)/source_file" )), depends_on => { "init_tidy_sparse" }; } bundle agent test { methods: # source file is created in "init" bundle # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); # "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); # "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); # "any" usebundle => dcs_fini("$(G.testdir)/source_file"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/network/0000755000000000000000000000000015010704253024121 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/network/lan_open.srv0000644000000000000000000000166515010704253026460 0ustar00rootroot00000000000000# Deny localhost, admit other interface IPs body common control { bundlesequence => { "access_rules" }; inputs => { "../../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9878"; # DENY LOCALHOST! denyconnects => { "127.0.0.1" }; # "127.0.0.1" is in this variable, but deny has precedence. So # effectively we only admit non-localhost connections allowconnects => { @(sys.ip_addresses) }; allowallconnects => { @(sys.ip_addresses) }; trustkeysfrom => { @(sys.ip_addresses) }; allowlegacyconnects => { @(sys.ip_addresses) }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { @(sys.ip_addresses) }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/network/004.cf.sub0000644000000000000000000000404315010704253025527 0ustar00rootroot00000000000000####################################################### # # mtime server copy, for non-localhost, should copy # ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; # localhost comes first but will be denied servers => { @(sys.ip_addresses) }; compare => "mtime"; copy_backup => "false"; portnumber => "9878"; # lan_open #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/network/004.cf0000644000000000000000000000150515010704253024737 0ustar00rootroot00000000000000# body common control { inputs => { "../../../default.cf.sub", "../../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/lan_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/lan_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_md5_zero_length_file.cf.sub0000644000000000000000000000335415010704253031700 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises # # Tests copy_from digest verify (SMD5) zero-length file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; copy_backup => "false"; portnumber => "9876"; # localhost_open encrypt => "false"; compare => "digest"; verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "empty_classic" and => { strcmp(filesize("$(G.testdir)/destfile_classic"),"0") }; "empty_latest" and => { strcmp(filesize("$(G.testdir)/destfile_latest"),"0") }; reports: copied_classic.copied_latest.empty_classic.empty_latest:: "$(fn[1]) Pass"; !copied_classic|!copied_latest|!empty_classic|!empty_latest:: "$(fn[1]) FAIL"; } copy_from_encrypted_md5_zero_length_file.cf.sub0000644000000000000000000000336415010704253033677 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial####################################################### # # Test cf-serverd related promises # # Tests copy_from encrypted digest verify (SMD5) zero-length file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; copy_backup => "false"; portnumber => "9876"; # localhost_open encrypt => "true"; compare => "digest"; verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "empty_classic" and => { strcmp(filesize("$(G.testdir)/destfile_classic"),"0") }; "empty_latest" and => { strcmp(filesize("$(G.testdir)/destfile_latest"),"0") }; reports: copied_classic.copied_latest.empty_classic.empty_latest:: "$(fn[1]) Pass"; !copied_classic|!copied_latest|!empty_classic|!empty_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_reordered_ciphers_success.cf0000644000000000000000000000146615010704253032246 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/reordered_default_ciphers_tlsversion.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/reordered_default_ciphers_tlsversion.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_same_expand_ip.cf0000644000000000000000000000142315010704253031332 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: "any" usebundle => file_make("$(G.testdir)/127.0.0.1.txt", "Source and Destination are identical."); "any" usebundle => file_make("$(G.testdir)/destination_file", "Source and Destination are identical."); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/tcp_port_copy_from_within_range.cf0000644000000000000000000000062515010704253031412 0ustar00rootroot00000000000000# # Check the parser enforces standard TCP port ( 1 <= port <= 65535) for: # -copy_from bodies "portnumber" # body common control { bundlesequence => { default("$(this.promise_filename)") }; inputs => { "../../default.cf.sub" }; version => "1.0"; } bundle agent test { reports: "$(this.promise_filename) Pass"; } body copy_from dummy_copy_from { portnumber => "5308"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/allowlegacyconnects_absent.srv0000644000000000000000000000145215010704253030562 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9891"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Absence of this option *denies* access # to classic protocol connections #allowlegacyconnects => { ... }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_open_hostname.srv0000644000000000000000000000141315010704253030072 0ustar00rootroot00000000000000# In access_rules, admit "localhost" instead of "127.0.0.1" body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9884"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowlegacyconnects => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "localhost", "localhost.localdomain" }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_same_expand_shortcut.cf.sub0000644000000000000000000000304115010704253033363 0ustar00rootroot00000000000000####################################################### # # copy_from compare=>"digest" with server-side shortcut expansion (TLS # protocol only) when file is already there - should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; # server-side expansion of shortcut source => "simple_source"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !copied_classic.!copied_latest:: "$(fn[1]) Pass"; copied_classic|copied_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/tls_1_3_only.srv0000644000000000000000000000143015010704253025467 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9894"; # Allow TLS 1.3 only allowciphers => "TLS_AES_256_GCM_SHA384"; allowtlsversion => "1.3"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_different_expand_shortcut.cf0000644000000000000000000000205015010704253033613 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source and Destination are DIFFERENT_A"); # destination files "any" usebundle => file_make("$(G.testdir)/destfile_classic", "Source and Destination are DIFFERENT_B"); "any" usebundle => file_make("$(G.testdir)/destfile_latest", "Source and Destination are DIFFERENT_B"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_noaccess.srv0000644000000000000000000000112415010704253027030 0ustar00rootroot00000000000000 body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9880"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: # no access granted } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_ciphers_success.cf.sub0000644000000000000000000000274615010704253031005 0ustar00rootroot00000000000000####################################################### # # Tries to copy using TLS (which is default now), from two servers: one # with the default TLS ciphers list and another with a non-default very # restricted one. # # It should succeed in both cases since default client-side cipherlist # is OpenSSL's default, which is very broad. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; # Do not set this, just use the very broad OpenSSL default. # # tls_ciphers => ""; } bundle agent init { } bundle agent test { files: # Server with non-default, very restricted "allowciphers" "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9888"), classes => classes_generic("copy1"); # Server with default "allowciphers" "$(G.testdir)/destfile2" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9889"), classes => classes_generic("copy2"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); "exists2" expression => fileexists("$(G.testdir)/destfile2"); reports: (copy1_repaired.copy2_repaired).(exists1.exists2):: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/008.cf.sub0000644000000000000000000000400315010704253024036 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises, mtime simple copy localhost, should copy # # Tests secure copy (SGET) and secure stat (SSYNCH). # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; portnumber => "9876"; # localhost_open encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } copy_from_digest_same_expand_ip_and_shortcut.cf.sub0000644000000000000000000000247215010704253034625 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial####################################################### # # copy_from compare=>"digest" with server-side expansion of IP address # (TLS protocol only) and shortcut expansion when file is already there # - should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destination_file" copy_from => copy_src_file, classes => if_repaired("repaired"); } ######################################################### body copy_from copy_src_file { source => "expand_ip_source"; protocol_version => "latest"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !repaired:: "$(fn[1]) Pass"; repaired:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_same.cf0000644000000000000000000000172215010704253027305 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source files "any" usebundle => file_make("$(G.testdir)/source_file", "Source and Destination are identical."); # destination files "any" usebundle => file_make("$(G.testdir)/destfile_latest", "Source and Destination are identical."); "any" usebundle => file_make("$(G.testdir)/destfile_classic", "Source and Destination are identical."); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_classic_protocol_success.cf0000644000000000000000000000143615010704253032115 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/allowlegacyconnects_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/allowlegacyconnects_open.srv"); } copy_from_inexistent_file_connection_closed-classic_protocol.cf0000644000000000000000000000175115010704253037245 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => dcs_fini("$(G.testdir)/destfile2"); "any" usebundle => dcs_fini("$(G.testdir)/destfile3"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_ciphers_success.cf0000644000000000000000000000217415010704253030210 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/destfile1"); "any" usebundle => dcs_fini("$(G.testdir)/destfile2"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/nondefault_ciphers_tlsversion.srv"); "any" usebundle => start_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/nondefault_ciphers_tlsversion.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/default_ciphers_tlsversion.srv"); } copy_from_digest_different_expand_ip_and_shortcut.cf0000644000000000000000000000155315010704253035055 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: "any" usebundle => file_make("$(G.testdir)/127.0.0.1.txt", "Source and Destination are different_A"); "any" usebundle => file_make("$(G.testdir)/destination_file", "Source and Destination are different_B"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_md5_zero_length_file.cf0000644000000000000000000000150315010704253031102 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_empty("$(G.testdir)/source_file"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/lan_deny_connect.srv0000644000000000000000000000127215010704253026470 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9879"; denyconnects => { @(sys.ip_addresses) }; allowconnects => { @(sys.ip_addresses) }; allowallconnects => { @(sys.ip_addresses) }; trustkeysfrom => { @(sys.ip_addresses) }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { @(sys.ip_addresses) }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copied_files_can_be_sparse.cf.sub0000644000000000000000000000576615010704253031041 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises, mtime simple copy localhost # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; protocol_version => "$(protocol_version)"; portnumber => "9876"; # localhost_open #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { vars: # Real file size "size1" string => filestat( "$(G.testdir)/destfile_classic", size ), if => fileexists( "$(G.testdir)/destfile_classic"); "size2" string => filestat( "$(G.testdir)/destfile_latest", size ), if => fileexists( "$(G.testdir)/destfile_latest"); # Disk allocated space "alloc_size1" string => execresult( "expr `du -k $(G.testdir)/destfile_classic | cut -f1` '*' 1024", useshell), if => fileexists("$(G.testdir)/destfile_classic"); "alloc_size2" string => execresult( "expr `du -k $(G.testdir)/destfile_latest | cut -f1` '*' 1024", useshell), if => fileexists("$(G.testdir)/destfile_latest"); classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "is_sparse1" expression => islessthan( "$(alloc_size1)", "$(size1)" ); "is_sparse2" expression => islessthan( "$(alloc_size2)", "$(size2)" ); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: DEBUG.!is_sparse1:: "ERROR destfile_classic is NOT sparse; size1=$(size1) alloc_size1=$(alloc_size1)"; DEBUG.!is_sparse2:: "ERROR destfile_latest is NOT sparse; size2=$(size2) alloc_size2=$(alloc_size2)"; same_classic.same_latest.is_sparse1.is_sparse2:: "$(fn[1]) Pass"; !same_classic|!same_latest|!is_sparse1|!is_sparse2:: "$(fn[1]) FAIL"; } copy_from_digest_same_expand_ip_and_shortcut.cf0000644000000000000000000000142315010704253034030 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: "any" usebundle => file_make("$(G.testdir)/127.0.0.1.txt", "Source and Destination are identical."); "any" usebundle => file_make("$(G.testdir)/destination_file", "Source and Destination are identical."); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/002.cf0000644000000000000000000000214615010704253023246 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # We generate key in-between the two files on purpose, to # introduce latency and make sure that destination file is newer "any" usebundle => generate_key; "any" usebundle => file_make("$(G.testdir)/destfile_classic", "This is the source file to copy $(sys.date) - different!"); "any" usebundle => file_make("$(G.testdir)/destfile_latest", "This is the source file to copy $(sys.date) - different!"); "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_ciphers_fail.cf.sub0000644000000000000000000000301015010704253030231 0ustar00rootroot00000000000000####################################################### # # Tries to copy using TLS (which is default now), from two servers: one # with the default TLS ciphers list and another with a non-default very # restricted one. # # It should fail since we are setting "tls_ciphers" to a cipher missing # in both servers. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; # This cipher doesn't match neither of the two # servers "allowciphers" setting. tls_ciphers => "AES128-SHA"; } bundle agent init { } bundle agent test { files: # Server with non-default, very restricted "allowciphers" "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9888"), classes => classes_generic("copy1"); # Server with default "allowciphers" "$(G.testdir)/destfile2" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9889"), classes => classes_generic("copy2"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); "exists2" expression => fileexists("$(G.testdir)/destfile2"); reports: (copy1_failed.copy2_failed).(!copy1_repaired.!copy2_repaired).(!exists1.!exists2):: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_tls_1_3_fail.cf.sub0000644000000000000000000000240615010704253030050 0ustar00rootroot00000000000000####################################################### # # Tries to copy using TLS 1.3, from two servers: # - one not supporting TLS 1.3 # - one with the defaults # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; # Require TLS 1.3 tls_min_version => "1.3"; } bundle agent init { } bundle agent test { files: # Server not supporting TLS 1.3 "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9895"), classes => classes_generic("copy1"); # Server with default "allowciphers" and "allowtlsversion" "$(G.testdir)/destfile2" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9889"), classes => classes_generic("copy2"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); "exists2" expression => fileexists("$(G.testdir)/destfile2"); reports: (copy1_failed.copy2_repaired).(!exists1.exists2):: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_different.cf0000644000000000000000000000177215010704253030333 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: "any" usebundle => file_make("$(G.testdir)/source_file", "Source and Destination are DIFFERENT_A"); "any" usebundle => file_make("$(G.testdir)/destfile_latest", "Source and Destination are DIFFERENT_B"); "any" usebundle => file_make("$(G.testdir)/destfile_classic", "Source and Destination are DIFFERENT_C"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_missing_ok.cf0000644000000000000000000000213615010704253026140 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # ensure destination files are not there "any" usebundle => dcs_fini("$(G.testdir)/dir"); "any" usebundle => dcs_fini("$(G.testdir)/out"); "any" usebundle => dcs_fini("$(G.testdir)/nodir/does_not_exist"); # source file "any" usebundle => file_make("$(G.testdir)/source_file", "Source file to copy, always fresh, $(sys.date)"); "any" usebundle => file_make("$(G.testdir)/out/dummy", "dummy file to create output dir"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/003.cf.sub0000644000000000000000000000312515010704253024035 0ustar00rootroot00000000000000####################################################### # # mtime server copy, localhost, explicit deny connect access, should not copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; portnumber => "9877"; #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: !copied_classic.!copied_latest:: "$(fn[1]) Pass"; copied_classic|copied_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/localhost_deny_connect.srv0000644000000000000000000000127215010704253027706 0ustar00rootroot00000000000000 body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9877"; denyconnects => { "127.0.0.1" , "::1" }; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/001.cf.sub0000644000000000000000000000357415010704253024043 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises, mtime simple copy localhost # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; compare => "mtime"; copy_backup => "false"; protocol_version => "$(protocol_version)"; portnumber => "9876"; # localhost_open #encrypt => "true"; #verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_digest_different_expand_ip.cf.sub0000644000000000000000000000330715010704253033146 0ustar00rootroot00000000000000####################################################### # # copy_from compare=>"digest" with server-side expansion of IP address # (TLS protocol only) when file is there but differs - should copy # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testdir)/destination_file" copy_from => copy_src_file, classes => if_repaired("repaired"); } ######################################################### body copy_from copy_src_file { # server-side special variable expansion # of "127.0.0.1" to "$(connection.ip)" source => "$(G.testdir)/127.0.0.1.txt"; # Special variable expansion only works with "latest" protocol. protocol_version => "latest"; servers => { "127.0.0.1" }; compare => "digest"; copy_backup => "false"; trustkey => "true"; portnumber => "9876"; # localhost_open } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected("$(G.testdir)/127.0.0.1.txt", "$(G.testdir)/destination_file", "no", "same_file", "differ_file"); reports: same_file:: "$(fn[1]) Pass"; !same_file:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/010.cf.sub0000644000000000000000000000372415010704253024040 0ustar00rootroot00000000000000####################################################### # # Test cf-serverd related promises # # Tests copy_from encrypted digest verify (SMD5) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } bundle agent test { files: "$(G.testdir)/destfile_classic" copy_from => copy_src_file("classic"), classes => if_repaired("copied_classic"); "$(G.testdir)/destfile_latest" copy_from => copy_src_file("latest"), classes => if_repaired("copied_latest"); } ######################################################### body copy_from copy_src_file(protocol_version) { protocol_version => "$(protocol_version)"; source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; copy_backup => "false"; portnumber => "9876"; # localhost_open encrypt => "true"; compare => "digest"; verify => "true"; #purge => "false"; #type_check => "true"; #force_ipv4 => "true"; trustkey => "true"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); methods: "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_classic", "no", "same_classic", "differ_classic"); "any" usebundle => dcs_if_diff_expected( "$(G.testdir)/source_file", "$(G.testdir)/destfile_latest", "no", "same_latest", "differ_latest"); reports: same_classic.same_latest:: "$(fn[1]) Pass"; !same_classic|!same_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/simple_copy_from_deny_localhost.cf0000644000000000000000000000340715010704253031403 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_suppress_fail" string => "windows", meta => { "redmine6405", "ENT-2480"}; # Ubuntu 20 (at least our build machines) doesn't know how to resolve # 127.0.0.1/::1 to localhost, the reverse lookup fails and so # 'deny => { "localhost" };' and 'deny_hostnames => { "localhost" };' # are not enough to deny access for this test. # Test fails on SLES / OpenSUSE 15, pending investigation. "test_skip_unsupported" string => "(ubuntu_20|ubuntu_22|debian_12|sles_15|opensuse_leap_15)", meta => { "ENT-2480", "ENT-7362", "ENT-9055" }; methods: # source file "any" usebundle => file_make("$(G.testdir)/source_file", "This is the source file to copy $(sys.date) - always fresh"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/server1_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server1_latest"); "any" usebundle => dcs_fini("$(G.testdir)/server2_classic"); "any" usebundle => dcs_fini("$(G.testdir)/server2_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_closed_hostname.srv"); "any" usebundle => start_server("$(this.promise_dirname)/localhost_closed_deny_hostnames.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_closed_hostname.srv"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_closed_deny_hostnames.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/copy_from_encrypted_md5_zero_length_file.cf0000644000000000000000000000150315010704253033157 0ustar00rootroot00000000000000# body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10401" }; methods: # source file "any" usebundle => file_empty("$(G.testdir)/source_file"); # destination files "any" usebundle => dcs_fini("$(G.testdir)/destfile_classic"); "any" usebundle => dcs_fini("$(G.testdir)/destfile_latest"); "any" usebundle => generate_key; "any" usebundle => start_server("$(this.promise_dirname)/localhost_open.srv"); "any" usebundle => run_test("$(this.promise_filename).sub"); "any" usebundle => stop_server("$(this.promise_dirname)/localhost_open.srv"); } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/default_ciphers_tlsversion.srv0000644000000000000000000000150615010704253030617 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9889"; # Use the defaults, i.e. the following: # # allowciphers => "AES256-GCM-SHA384:AES256-SHA:TLS_AES_256_GCM_SHA384"; # allowtlsversion => "1.1"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } copy_from_inexistent_file_connection_closed.cf.sub0000644000000000000000000000301015010704253034463 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial####################################################### # # CFE-2532: failure to get one file causes all subsequent copy_from # promises to also fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { } bundle agent test { files: # Copy 1st file successfully "$(G.testdir)/destfile1" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9876"), classes => classes_generic("copy1"); # Copy 2nd file, WILL FAIL "$(G.testdir)/destfile2" copy_from => dcs_remote_cp("DOES_NOT_EXIST", "127.0.0.1", "9876"), classes => classes_generic("copy2"); # Copy 3rd file, MUST SUCCEED DESPITE PREVIOUS FAILURE "$(G.testdir)/destfile3" copy_from => dcs_remote_cp("simple_source", "127.0.0.1", "9876"), classes => classes_generic("copy3"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "exists1" expression => fileexists("$(G.testdir)/destfile1"); "exists2" expression => fileexists("$(G.testdir)/destfile2"); "exists3" expression => fileexists("$(G.testdir)/destfile3"); reports: copy1_repaired.exists1.!copy1_failed.copy3_repaired.exists3.!copy3_failed.!copy2_repaired.!exists2.copy2_failed:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/allow_path1_then_deny_path2_b.cf.sub0000644000000000000000000000346515010704253031411 0ustar00rootroot00000000000000####################################################### # # We request a path from disallowed path, it should fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } ####################################################### body copy_from copy_from_port(port, protocol_version) { portnumber => "$(port)"; protocol_version => "$(protocol_version)"; # testroot dir is admitted on the server, while G.testdir is denied source => "$(G.testdir)/source_file"; servers => { "127.0.0.1" }; trustkey => "true"; } bundle agent test { files: # localhost_deny_one_directory "$(G.testdir)/server1_classic" copy_from => copy_from_port("9881", "classic"), classes => if_repaired("copied1_classic"); "$(G.testdir)/server1_latest" copy_from => copy_from_port("9881", "latest"), classes => if_repaired("copied1_latest"); # localhost_deny_one_directory_with_regex "$(G.testdir)/server2_classic" copy_from => copy_from_port("9882", "classic"), classes => if_repaired("copied2_classic"); "$(G.testdir)/server2_latest" copy_from => copy_from_port("9882", "latest"), classes => if_repaired("copied2_latest"); } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: # All copies must fail !copied1_classic.!copied1_latest.!copied2_classic.!copied2_latest:: "$(fn[1]) Pass"; copied1_classic|copied1_latest|copied2_classic|copied2_latest:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/16_cf-serverd/serial/allowlegacyconnects_closed.srv0000644000000000000000000000136415010704253030561 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "9892"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # DO NOT ALLOW CLASSIC PROTOCOL allowlegacyconnects => { }; } ######################################################### bundle server access_rules() { access: "$(G.testdir)/source_file" admit => { "127.0.0.1", "::1" }, shortcut => "simple_source"; } cfengine-3.24.2/tests/acceptance/run_with_server.cf.sub0000644000000000000000000000602115010704253023131 0ustar00rootroot00000000000000body classes if_failed(x) { repair_failed => { "$(x)" }; } body contain run_under_shell { useshell => "useshell"; } body action in_background { background => "true"; } bundle agent start_server(server_config) { classes: "debug_server" expression => "debug_mode"; vars: "config_basename" string => filestat("$(server_config)", basename); "dlog" string => "$(sys.workdir)/server-debug.$(config_basename).log"; commands: !debug_server.!windows:: "$(sys.cf_serverd) -Kf $(server_config)" classes => if_failed("server_failed"); !debug_server.windows:: # Windows cannot daemonize and needs to start in background. "$(sys.cf_serverd) -Kf $(server_config)" action => in_background, classes => if_failed("server_failed"); debug_server:: "$(sys.cf_serverd) -Kldf $(server_config) > $(dlog) 2>&1" contain => run_under_shell, action => in_background, classes => if_failed("server_failed"); debug_server|windows:: # Sleep 3 seconds since cf-serverd takes some time to start in background # mode. We need to add a handle with $(server_config) in it so that the # promise is not skipped if this bundle is used for multiple configs. "$(G.sleep) 3" contain => run_under_shell, handle => "sleep_for_$(server_config)"; reports: debug_server:: "$(sys.cf_serverd) was run in debug mode, the logs will be in $(dlog)"; } bundle agent run_test(test_name) { classes: "debug_client" expression => "debug_mode"; vars: "dlog" string => "$(sys.workdir)/agent-debug.log"; commands: !debug_client:: "$(sys.cf_agent) -KIf $(test_name) -D DEBUG,AUTO 2>&1 | $(G.tee) $(dlog)" contain => run_under_shell; debug_client:: "$(sys.cf_agent) -Kldf $(test_name) -D DEBUG,EXTRA,AUTO 2>&1 | $(G.tee) $(dlog)" contain => run_under_shell; reports: debug_client:: "$(sys.cf_agent) was run in debug mode, the logs will be in $(dlog)"; } bundle agent run_runagent(runagent_params) { classes: "debug_client" expression => "debug_mode"; vars: "dlog" string => "$(sys.workdir)/runagent-debug.log"; commands: !debug_client:: "$(sys.cf_runagent) -I $(runagent_params) 2>&1 | $(G.tee) $(dlog)" contain => run_under_shell; debug_client:: "$(sys.cf_runagent) -d $(runagent_params) 2>&1 | $(G.tee) $(dlog)" contain => run_under_shell; reports: debug_client:: "$(sys.cf_runagent) was run in debug mode, the logs will be in $(dlog)"; } bundle agent stop_server(server_config) { # On some old platforms, "ps" truncates its output, which CFEngine depends on. This can lead to # the test servers not being killed. # On HP-UX you can set the DEFAULT_CMD_LINE_WIDTH inside /etc/default/ps to a higher value, which # controls the maximum line length of "ps". Unfortunately it is not overridable from the # environment. processes: "$(server_config)" signals => { "term", "kill" }; } cfengine-3.24.2/tests/acceptance/24_cmd_line_arguments/0000755000000000000000000000000015010704253022747 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/24_cmd_line_arguments/parsed_policy.cf.sub.sub0000644000000000000000000000010515010704253027472 0ustar00rootroot00000000000000bundle common extra { vars: "extra_var" string => "extra"; } cfengine-3.24.2/tests/acceptance/24_cmd_line_arguments/parsed_policy.cf.template0000644000000000000000000001602515010704253027734 0ustar00rootroot00000000000000bundle agent test() { vars: any:: "testvar" string => "string"; "testlist" slist => {"list"}; } body common control() { inputs => {"parsed_policy.cf.sub.sub"}; bundlesequence => {"test"}; } { "bodies": [ { "arguments": [], "bodyType": "common", "contexts": [ { "attributes": [ { "line": 3, "lval": "inputs", "rval": { "type": "list", "value": [ { "type": "string", "value": "parsed_policy.cf.sub.sub" } ] } }, { "line": 4, "lval": "bundlesequence", "rval": { "type": "list", "value": [ { "type": "string", "value": "test" } ] } } ], "name": "any" } ], "line": 1, "name": "control", "namespace": "default", "sourcePath": "{{testdir}}/parsed_policy.cf.sub" } ], "bundles": [ { "arguments": [], "bundleType": "agent", "line": 7, "name": "test", "namespace": "default", "promiseTypes": [ { "contexts": [ { "name": "any", "promises": [ { "attributes": [ { "line": 10, "lval": "string", "rval": { "type": "string", "value": "string" } } ], "line": 10, "promiser": "testvar" }, { "attributes": [ { "line": 11, "lval": "slist", "rval": { "type": "list", "value": [ { "type": "string", "value": "list" } ] } } ], "line": 11, "promiser": "testlist" } ] } ], "line": 9, "name": "vars" } ], "sourcePath": "{{testdir}}/parsed_policy.cf.sub" } ] }bundle agent test() { vars: any:: "testvar" string => "string"; "testlist" slist => {"list"}; } bundle common extra() { vars: any:: "extra_var" string => "extra"; } body common control() { inputs => {"parsed_policy.cf.sub.sub"}; bundlesequence => {"test"}; } { "bodies": [ { "arguments": [], "bodyType": "common", "contexts": [ { "attributes": [ { "line": 3, "lval": "inputs", "rval": { "type": "list", "value": [ { "type": "string", "value": "parsed_policy.cf.sub.sub" } ] } }, { "line": 4, "lval": "bundlesequence", "rval": { "type": "list", "value": [ { "type": "string", "value": "test" } ] } } ], "name": "any" } ], "line": 1, "name": "control", "namespace": "default", "sourcePath": "{{testdir}}/parsed_policy.cf.sub" } ], "bundles": [ { "arguments": [], "bundleType": "agent", "line": 7, "name": "test", "namespace": "default", "promiseTypes": [ { "contexts": [ { "name": "any", "promises": [ { "attributes": [ { "line": 10, "lval": "string", "rval": { "type": "string", "value": "string" } } ], "line": 10, "promiser": "testvar" }, { "attributes": [ { "line": 11, "lval": "slist", "rval": { "type": "list", "value": [ { "type": "string", "value": "list" } ] } } ], "line": 11, "promiser": "testlist" } ] } ], "line": 9, "name": "vars" } ], "sourcePath": "{{testdir}}/parsed_policy.cf.sub" }, { "arguments": [], "bundleType": "common", "line": 1, "name": "extra", "namespace": "default", "promiseTypes": [ { "contexts": [ { "name": "any", "promises": [ { "attributes": [ { "line": 4, "lval": "string", "rval": { "type": "string", "value": "extra" } } ], "line": 4, "promiser": "extra_var" } ] } ], "line": 3, "name": "vars" } ], "sourcePath": "{{testdir}}/parsed_policy.cf.sub.sub" } ] }cfengine-3.24.2/tests/acceptance/24_cmd_line_arguments/parsed_policy.cf0000644000000000000000000000207315010704253026120 0ustar00rootroot00000000000000# Tests that the '-p' option works properly in all its modes. body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent init { vars: "testdir" data => '{ testdir: "$(this.promise_dirname)" }'; files: "$(G.testdir)/output.expected" create => "true", edit_template => "$(this.promise_filename).template", template_method => "mustache", template_data => @(testdir); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10254" }; vars: "arg_list" slist => { "none", "cf", "json", "cf-full", "json-full" }; commands: "$(sys.cf_promises) -f $(this.promise_filename).sub -p $(arg_list) >> $(G.testdir)/output.actual" contain => in_shell; } bundle agent check { methods: "check" usebundle => dcs_check_diff("$(G.testdir)/output.actual", "$(G.testdir)/output.expected", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/24_cmd_line_arguments/parsed_policy.cf.sub0000644000000000000000000000032115010704253026702 0ustar00rootroot00000000000000body common control { inputs => { "parsed_policy.cf.sub.sub" }; bundlesequence => { "test" }; } bundle agent test { vars: "testvar" string => "string"; "testlist" slist => { "list" }; } cfengine-3.24.2/tests/acceptance/14_reports/0000755000000000000000000000000015010704253020605 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/14_reports/failed_reports_are_not_kept.cf0000644000000000000000000000271615010704253026661 0ustar00rootroot00000000000000# Check that reports are printed just once (Redmine#3446 https://cfengine.com/dev/issues/3446) body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" create => "true", handle => "init_testfile"; commands: "/usr/bin/chattr" args => "+i $(G.testfile)", comment => "The file needs to be immutable so that we can accurately test it."; } bundle agent test { meta: "description" string => "Test that we do not conisder failure to report to a file a kept outcome"; # this test should be skipped on platforms that do not have chattr! "test_soft_fail" string => "any", meta => { "redmine7833" }; reports: "Hello World" report_to_file => "$(G.testfile)", classes => scoped_classes_generic("namespace", "report_to_file"); } bundle agent check { classes: "ok" not => "report_to_file_kept"; commands: "/usr/bin/chattr" args => "-i $(G.testfile)", handle => "remove_immutable_bit", comment => "So that we don't mess up other tests lets be sure to clean up after ourselves"; files: "$(G.testfile)" depends_on => { "remove_immutable_bit" }, delete => tidy; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 2 cfengine-3.24.2/tests/acceptance/14_reports/00_output/0000755000000000000000000000000015010704253022444 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/14_reports/00_output/001.cf0000644000000000000000000000206115010704253023255 0ustar00rootroot00000000000000####################################################### # # Test that printfile honors number_of_lines constraint (Issue 686) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); } ####################################################### bundle agent check { classes: "firstline" expression => regcmp(".*firstline.*", "$(test.subout)"); "nosecondline" not => regcmp(".*secondline.*", "$(test.subout)"); "ok" and => { "firstline", "nosecondline" }; reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 2 cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_once.cf0000644000000000000000000000131515010704253025275 0ustar00rootroot00000000000000# Check that reports are printed just once (Redmine#3446 https://cfengine.com/dev/issues/3446) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); } bundle agent check { # If the output contains the string "ONCE" twice then we fail classes: "ok" not => regcmp(".*ONCE.*ONCE.*", "$(test.subout)"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 2 cfengine-3.24.2/tests/acceptance/14_reports/00_output/002.cf.sub0000644000000000000000000000061415010704253024050 0ustar00rootroot00000000000000############################################################################## # # Redmine #2936: Check that list variables under reserved scope expand # as they should in reports promises. # ############################################################################## body common control { bundlesequence => {"example"}; } bundle agent example { reports: "$(sys.hardware_addresses)"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/unresolved_vars.cf.sub0000644000000000000000000000077115010704253026774 0ustar00rootroot00000000000000bundle agent __main__ { vars: any:: "var1" string => "val1"; def_var2:: "var2" string => "val2"; def_var3:: "var3" string => "val3"; def_var4:: "var4" string => "val4"; classes: "def_var2" expression => isvariable("var1"); "def_var3" expression => isvariable("var2"); "def_var4" expression => isvariable("var3"); reports: "var1: $(var1)"; "var2: $(var2)"; "var3: $(var3)"; "var4: $(var4)"; "var5: $(var5)"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/unresolved_with.cf.sub0000644000000000000000000000016615010704253026772 0ustar00rootroot00000000000000bundle agent __main__ { vars: "y" slist => { @{x} }; reports: "y: $(with)" with => format("%S", y); } cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_nested_variable.cf0000644000000000000000000000164615010704253027507 0ustar00rootroot00000000000000# Check that nested variables are reported (Redmine: https://cfengine.com/dev/issues/4247) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "any", meta => { "redmine4247" }; vars: !FAKE_PASS:: "subout" string => execresult("$(sys.cf_agent) -b runme -Kf $(this.promise_filename).sub", "noshell"); FAKE_PASS:: "subout" string => execresult("$(sys.cf_agent) -b runme -Kf $(this.promise_filename).sub -DFAKE_PASS", "noshell"); } bundle agent check { classes: "ok" expression => regcmp(".*replaced-by=something_else.*", "$(test.subout)"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 2 cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_array.cf.sub0000644000000000000000000000066215010704253026263 0ustar00rootroot00000000000000body common control { bundlesequence => { set, run }; } bundle agent set { vars: "array[key_scalar]" string => "9b70d955f7e126bc082e4a99eb2b3d08e4ebc29a"; "array[key_slist]" slist => { "18a307169ff8a691607846c8a19c361a37695773", "79815eefd0b619c6b875edf68adc7ef0e00c1ad3" }; "keys" slist => getindices(array); } bundle agent run { reports: "key = $(set.keys), value = $(set.array[$(set.keys)])"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/001.cf.sub.in0000644000000000000000000000002515010704253024450 0ustar00rootroot00000000000000firstline secondline cfengine-3.24.2/tests/acceptance/14_reports/00_output/unresolved_vars.cf0000644000000000000000000000277215010704253026207 0ustar00rootroot00000000000000####################################################### # # Test that reports promises handle unresolved var refs in a sane way # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "expected_lines" slist => { "R: var1: val1", "R: var2: val2", "R: var3: val3", "R: var4: val4", "R: var5: $(const.dollar)(var5)" }; "expected_output" string => join("$(const.n)", expected_lines); files: "$(G.testfile).expected" content => "$(expected_output)$(const.n)"; } bundle agent test { meta: "description" -> { "CFE-3776" } string => "Test that reports with unresolved variables are only emitted during the last pass of evaluation"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; commands: "$(sys.cf_agent) -Kf $(this.promise_filename).sub > $(G.testfile).actual" contain => shell; } body contain shell { useshell => "true"; } bundle agent check { methods: "" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_printfile_from_top.cf.sub0000644000000000000000000000050415010704253031041 0ustar00rootroot00000000000000# Line 1 from top # Line 2 from top # Line 3 from top body common control { bundlesequence => { "example" }; } bundle agent example { reports: "First three:" printfile => first_three("$(this.promise_filename)"); } body printfile first_three(file) { file_to_print => "$(file)"; number_of_lines => "3"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_once.cf.sub0000644000000000000000000000024415010704253026065 0ustar00rootroot00000000000000body common control { bundlesequence => { run }; } bundle agent run { reports: "should be printed just ONCE"; "should be printed just ONCE"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_printfile_from_top.cf0000644000000000000000000000144715010704253030260 0ustar00rootroot00000000000000body common control { bundlesequence => { "test", "check" }; } bundle agent test { meta: "description" -> { "CFE-3558" } string => "Test reports printfile with number_of_lines as positive number"; vars: "actual" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); "expected" string => "R: First three: R: # Line 1 from top R: # Line 2 from top R: # Line 3 from top"; } bundle agent check { classes: "passed" expression => strcmp("$(test.expected)", "$(test.actual)"); reports: windows:: "$(this.promise_filename) SFAIL/ENT-10433"; DEBUG:: "Expected: '$(test.expected)'"; "Found: '$(test.actual)'"; passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/002.cf0000644000000000000000000000167215010704253023265 0ustar00rootroot00000000000000############################################################################## # # Redmine #2936: Check that list variables under reserved scope expand # as they should in reports promises. # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); } bundle agent check { # If the output contains the string "$(sys.hardware_addresses)" then we # failed to expand the variable! classes: "ok" not => regcmp(".*hardware_addresses.*", "$(test.subout)"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 2 cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_printfile_from_bot.cf0000644000000000000000000000144615010704253030241 0ustar00rootroot00000000000000body common control { bundlesequence => { "test", "check" }; } bundle agent test { meta: "description" -> { "CFE-3558" } string => "Test reports printfile with number_of_lines as negative number"; vars: "actual" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); "expected" string => "R: Last three: R: # Line 3 from bot R: # Line 2 from bot R: # Line 1 from bot"; } bundle agent check { classes: "passed" expression => strcmp("$(test.expected)", "$(test.actual)"); reports: windows:: "$(this.promise_filename) SFAIL/ENT-10433"; DEBUG:: "Expected: '$(test.expected)'"; "Found: '$(test.actual)'"; passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/staging/0000755000000000000000000000000015010704253024100 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/14_reports/00_output/staging/report_in_common_bundle.cf.sub0000644000000000000000000000020415010704253032100 0ustar00rootroot00000000000000bundle agent runme { } bundle common report { reports: "$(this.bundle): rhino_9d85a7796746fb3e2e2ac95f74e4b981564803de"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/staging/report_in_common_bundle.cf0000644000000000000000000000136315010704253031317 0ustar00rootroot00000000000000# Check that reports are printed from common bundles (Redmine#3848 https://cfengine.com/dev/issues/3848) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -b runme -Kf $(this.promise_filename).sub", "noshell"); } bundle agent check { classes: "ok" expression => regcmp(".*rhino_9d85a7796746fb3e2e2ac95f74e4b981564803de.*", "$(test.subout)"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 2 cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_nested_variable.cf.sub0000644000000000000000000000074515010704253030276 0ustar00rootroot00000000000000bundle agent old_bundle { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=something_else", }; } bundle agent runme { vars: "deprecated" slist => bundlesmatching(".*", "deprecated.*"); reports: !FAKE_PASS:: "$(deprecated): $($(deprecated)_meta.tags)"; FAKE_PASS:: "$(deprecated): $(old_bundle_meta.tags)"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_array.cf0000644000000000000000000000170215010704253025467 0ustar00rootroot00000000000000# Check that reports are printed just once (Redmine#3446 https://cfengine.com/dev/issues/3446) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); } bundle agent check { classes: "ok1" expression => regcmp(".*9b70d955f7e126bc082e4a99eb2b3d08e4ebc29a.*", "$(test.subout)"); "ok2" expression => regcmp(".*18a307169ff8a691607846c8a19c361a37695773.*", "$(test.subout)"); "ok3" expression => regcmp(".*79815eefd0b619c6b875edf68adc7ef0e00c1ad3.*", "$(test.subout)"); "ok" and => { "ok1", "ok2", "ok3" }; reports: DEBUG:: "Output from subtest: $(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 2 cfengine-3.24.2/tests/acceptance/14_reports/00_output/001.cf.sub0000644000000000000000000000045415010704253024051 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "test" }; version => "1.0"; } bundle agent test { reports: cfengine_3:: "doesnotmatter" printfile => p; } body printfile p { file_to_print => "$(this.promise_filename).in"; number_of_lines => "1"; } cfengine-3.24.2/tests/acceptance/14_reports/00_output/report_printfile_from_bot.cf.sub0000644000000000000000000000050215010704253031021 0ustar00rootroot00000000000000body common control { bundlesequence => { "example" }; } bundle agent example { reports: "Last three:" printfile => last_three("$(this.promise_filename)"); } body printfile last_three(file) { file_to_print => "$(file)"; number_of_lines => "-3"; } # Line 3 from bot # Line 2 from bot # Line 1 from bot cfengine-3.24.2/tests/acceptance/14_reports/00_output/unresolved_with.cf0000644000000000000000000000223515010704253026201 0ustar00rootroot00000000000000####################################################### # # Test that reports promises handle unresolved var refs in '$(with)' # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "expected_output" string => 'R: y: { "@{x}" }'; files: "$(G.testfile).expected" content => "$(expected_output)$(const.n)"; } bundle agent test { meta: "description" -> { "CFE-3776" } string => "Test that with reports its content during the last pass even when that content has unresolved variables "; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; commands: "$(sys.cf_agent) -Kf $(this.promise_filename).sub > $(G.testfile).actual" contain => shell; } body contain shell { useshell => "true"; } bundle agent check { methods: "" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/14_reports/reports_comments_emitted_in_verbose.cf.sub0000644000000000000000000000016615010704253031243 0ustar00rootroot00000000000000bundle agent main { reports: "This is an example report" comment => "This is a comment about a report"; } cfengine-3.24.2/tests/acceptance/14_reports/reports_comments_emitted_in_verbose.cf0000644000000000000000000000106615010704253030453 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent test { meta: "description" string => "Test that comments on reports are emitted in verbose output."; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*This is a comment about a report.*", "", "$(sys.cf_agent) -Kvf $(this.promise_filename).sub", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/14_reports/report_to_file_suppresses_report_to_stdout.cf0000644000000000000000000000213115010704253032123 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that report_to_file attribute suppresses report on stdout."; } bundle agent init { files: "$(G.testfile)" delete => tidy; } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO", "noshell"); } bundle agent check { classes: "not_found_report_in_agent_output" not => regcmp(".*This should not be reported to stdout.*", "$(test.subout)"); "sub_ok" expression => regcmp(".*Pass", "$(test.subout)"); "ok" and => { "sub_ok", "not_found_report_in_agent_output" }; reports: DEBUG:: "DEBUG: sub output $(const.n)$(test.subout)"; sub_ok.DEBUG:: "DEBUG: subtest passed"; not_found_report_in_agent_output.DEBUG:: "DEBUG: Did not find report in agent output as expected"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/14_reports/report_to_file_suppresses_report_to_stdout.cf.sub0000644000000000000000000000126015010704253032715 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { reports: "This should not be reported to stdout" report_to_file => "$(G.testfile)"; } bundle agent check { vars: "count_reports_in_file" int => countlinesmatching("This should not be reported to stdout", "$(G.testfile)"); classes: "ok" expression => isgreaterthan($(count_reports_in_file), 0); reports: DEBUG:: "DEBUG: Found '$(count_reports_in_file)' lines matching 'This should not be reported to stdout' in '$(G.testfile)'"; ok:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/27_cf-secret/0000755000000000000000000000000015010704253020766 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/27_cf-secret/testkey.pub0000644000000000000000000000065215010704253023171 0ustar00rootroot00000000000000-----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEAt96mvMUSXyJSr4jjcfrADkIm+8uqLGp0pHL4zrJLo8o/o8WnQyKl hK614sAA/XlQmOIZ1KZ8x5Nw3fd/EFxEJ9wugz2iMbQTyRNgyJ4y68wrlBumKDgL rtVDgb1ozIVh9Q5SEdGuV6MgHwNI7ubaLyuLetn+mlLcJXbzs6V75yWvCdfPfAt+ aVONUChFRi1HydH34KEmEOgEca8YQW3FxjRYOnzeU81B9C3UGv3aFs8UQtNBvvd5 15GQGnjimkZ3Ukpp0M/CrpcpoAU7X4AywvZLB3X5/JhZVw4wgFlprIdbbL4wd9ov Q+4KoG+3BaMf5Y6NKvLRshONh5e3j7V4kQIDAQAB -----END RSA PUBLIC KEY----- cfengine-3.24.2/tests/acceptance/27_cf-secret/testkey.priv0000644000000000000000000000331715010704253023364 0ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,C213C4387710A6A4 L1J7NLoZ0DogIHAQXb0MR62kSGyIqRkZX5mLDKAf76mP/ejKGo27s8gwV7wVioFC uTAY5j9066/XsUdRN2vjBmX+/VM9SPciRrXwsKFUxqd23swxEEG9FjTWmp8z5mKK VNUh3C1CcSMVYjigSKInQP3M4/iMZ5EvzXgCsPxgfLgIf0j2+lF3Qxsdy0uzBCxz t19IjgvG4LCn26Vd1tm8QomPBK5y1e6OEuxh7Ke8TcOh/93nACIpuo/hGw1FtJ6Z zQXNdrDklP96FwrzsUdaDd6tuHTTTiqHkviaF9jkEUbfkIZJkWzqAFGhcW0So+28 OiCzpfESTDTaj3aVagc9UovJ2/S+AnlbHxrf24VCo5tD0dQzk9h5Pjg8Ze5N5el8 tmGkPMcvSDwr1RkPm1Xqipa1FbPGnfnebRNxc95vRw1JIf0eF0PCvVS0f4XjncBG QhUVeM6XKsqxoq3GC6ab/6cC3ZiVZNQpcptzt6Qy9+cDz0Et21Y8RJPdOT8wR+Sr SQST/wKW+H/xNh4sld+gLF3v6MACq5Wk2trAZYS+MdmelVps7LSQBnHPD1oDOkkq cL21cdevScDMjvbRnL2oj2054320rGBXS2VkT4XI7Qw/JeqNfT0Ue/9n+TABx60u pbPKpCfJzxQIErE5XEQU27+2IVYu5fK+BVi6s7UYUU40NePRlWFTfLRCVskrm63u UnZ4o8nKz+5DLtCdtTlRGOZDCwYQYOFawCfwLN9wToHqQZxC1wzqRTsqXoTEVmby hp+Qji55e93dFgLpIKB54flj2v3Wdbk8FPx3mjzf9MCxRaaGhsuX0WHQyHzIDb9K raFWYcZJ1S8DUz5o7Q8otJaxj+nPGLCKTpBw/UyfXi1tXkGSRSIDo1dUtMaE2MpL J44u4BuokKSOZbOi/piJy5wR0GSN6FHiDJo3yNbz/ZFXCq8l4ZQsVFNtB+9BzKX1 ZkTSe8JX1guGLo3+MKsLOpriBzmjDJ2JvziXa1S4P9l3SziwCfreDqMM3dw5+N2z rmtruWDMCURiVQXyuUToKRvzxiroOWIUofHrBoCG23Ztz3R+qlpXtYNy93z9tcg1 R8CeFXymXq8q2TpUorhLrZGf7Q6fZxLV66tWfkYje4oicH4qo+SFqN8T1/T6kJd4 kVj28Vb1RB4Phz7dkOyjKNo7qYXcedUbygUiAepLfnFgk7L9NEldn5CR6e1TxJoZ fD0ib/naOuUKdesc2YF2EAoS0Un9O4/YgZMCBNBUI412MGteiqOWwn0K6MNgiIKr 0ToBtNRsEXM/7p5/q32NDBuWOfL1/82ptMShRIlCMemZAlswbibuJnA6KI6smUIi LD4fti2143FqLQg3pkvjc6PEuAHUFVxfUSx3Kn/8mhKNbZxJuU8V/OfTEnfPKo+3 DyesHX7fTvnea5K+XJZY4fZRMxuzXtCcbIfq2wc5D4XPUy32wGqfsV9fmiEGqG7/ ul1uquFUg4qfBhKqbFdIt7x7XSDiCSzdQsC0kQ9XI5OiIQBrPIctXEsQxfsvGzx5 tI9xJ40eiNbFZfOLNyPOZ9RS5E7SHe0YeOQGkcbb1/+yY8GjaxTTYg== -----END RSA PRIVATE KEY----- cfengine-3.24.2/tests/acceptance/27_cf-secret/encrypt.x.cf0000644000000000000000000000147715010704253023243 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" string => "Test that cf-secret encryption uses random padding"; commands: "$(sys.cf_secret)" args => "encrypt -k $(this.promise_dirname)/testkey.pub -o $(G.testfile) $(this.promise_dirname)/plaintext"; "$(sys.cf_secret)" args => "encrypt -k $(this.promise_dirname)/testkey.pub -o $(G.testfile).2 $(this.promise_dirname)/plaintext"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile)", "$(G.testfile).2", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/27_cf-secret/decrypt.cf0000644000000000000000000000146715010704253022762 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" string => "Test that cf-secret can still decrypt content encrypted at the time of initial implementation"; "test_soft_fail" string => "windows", meta => { "ENT-10405" }; commands: "$(sys.cf_secret)" args => "decrypt -k $(this.promise_dirname)/testkey.priv -o $(G.testfile) $(this.promise_dirname)/encrypted"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(this.promise_dirname)/plaintext", "$(G.testfile)", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/27_cf-secret/encrypt-decrypt.cf0000644000000000000000000000311415010704253024433 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile).plain"); "any" usebundle => dcs_fini("$(G.testfile).encrypted"); "any" usebundle => dcs_fini("$(G.testfile).decrypted"); "any" usebundle => generate_key; "any" usebundle => trust_key; } bundle agent test { meta: "description" string => "Test that cf-secret basic key based encryption and decryption work"; "test_soft_fail" string => "windows", meta => { "ENT-10405" }; vars: "text" string => "This secret sauce should be encrypted and decrypted."; files: "$(G.testfile).plain" create => "true", edit_defaults => empty, edit_line => insert_lines( "$(text)" ); commands: "$(sys.cf_secret)" args => "encrypt -k $(sys.workdir)/ppkeys/localhost.pub -o $(G.testfile).encrypted $(G.testfile).plain"; "$(sys.cf_secret)" args => "decrypt -k $(sys.workdir)/ppkeys/localhost.priv -o $(G.testfile).decrypted $(G.testfile).encrypted"; reports: "Binaries/folders:"; "$(sys.cf_secret)"; "$(sys.cf_agent)"; "$(sys.workdir)"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).plain", "$(G.testfile).decrypted", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/27_cf-secret/encrypt-no-key.cf0000644000000000000000000000334715010704253024173 0ustar00rootroot00000000000000############################################################################## # # Test that encrypting with no host- / key argument defaults to encrypting for # localhost. # ############################################################################## body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } bundle agent init { methods: "any" usebundle => generate_key; "any" usebundle => trust_key; files: # Create plain text file "$(G.testfile).plaintext" create => "true", content => "Hello World!"; # Delete encrypted file "$(G.testfile).encrypted" delete => init_delete; # Delete decrypted file "$(G.testfile).decrypted" delete => init_delete; } bundle agent test { meta: "description" -> { "CFE-3874" } string => "Test that encrypting with no host- / key argument defaults to encrypting for localhost."; "test_soft_fail" string => "windows", meta => { "ENT-10405" }; commands: # Encrypt test file "$(sys.cf_secret)" args => "encrypt -o $(G.testfile).encrypted $(G.testfile).plaintext", handle => "file-is-encrypted"; # Decrypt test file "$(sys.cf_secret)" args => "decrypt -o $(G.testfile).decrypted $(G.testfile).encrypted", depends_on => { "file-is-encrypted" }; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).plaintext", "$(G.testfile).decrypted", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/27_cf-secret/encrypted0000644000000000000000000000056215010704253022711 0ustar00rootroot00000000000000Version: 1.0 Encrypted-for: MD5=05a10a6f3ff63d9e88fb0d013085cb3c +--ŽIªQ}â¡3™›•ì"°ãÓ™eÇpm00¯„¸û®eGiè”ocj2'W0S o§»ÖDp*y²ˆ0©øÓàWGíàZT" ŠH«³Ùñ™Ø£ôïë»'¦MZÈEBhêD å£KoÎÌ<¦FÑxH›ˆ=¸Óp¡‡ìlT„]…6dœ÷ÍgtÑ3¨ `ø¦p2r3`ÐA߈RŠÈãÁ—Ÿ$õìð„Ìáíné ×¾1#‘lBºl‡@f­DmÑÄ û|¤2„o…*Ü`ò%^„Ûf[Íì¡î)l{'4Sìgì>Úóp;¢Tüœ³6îJLA @50ÎÔm,½žƒ÷QÝÂ-š9Zf”—Ë‘òÞäÞ9tŸbëœLN+`W홽t¬FíÒcfengine-3.24.2/tests/acceptance/27_cf-secret/plaintext0000644000000000000000000000003515010704253022717 0ustar00rootroot00000000000000Super secret message is here cfengine-3.24.2/tests/acceptance/27_cf-secret/encrypt-decrypt-args.cf0000644000000000000000000000275615010704253025400 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile).plain"); "any" usebundle => dcs_fini("$(G.testfile).encrypted"); "any" usebundle => dcs_fini("$(G.testfile).decrypted"); "any" usebundle => generate_key; "any" usebundle => trust_key; } bundle agent test { meta: "description" string => "Test cf-secret with different arguments/order"; vars: "text" string => "This secret sauce should be encrypted and decrypted."; files: "$(G.testfile).plain" create => "true", edit_defaults => empty, edit_line => insert_lines( "$(text)" ); commands: "$(sys.cf_secret)" args => "encrypt --key $(sys.workdir)/ppkeys/localhost.pub --output $(G.testfile).encrypted $(G.testfile).plain"; "$(sys.cf_secret)" args => "decrypt --key $(sys.workdir)/ppkeys/localhost.priv -o $(G.testfile).decrypted $(G.testfile).encrypted"; reports: "Binaries/folders:"; "$(sys.cf_secret)"; "$(sys.cf_agent)"; "$(sys.workdir)"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).plain", "$(G.testfile).decrypted", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/root-MD5=617eb383deffef843ea856b129d0a423.priv0000644000000000000000000000332715010704253025544 0ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,03888484F391EBEF Md6pmS3kdvXhvjxI07s7w42xLZsEboZBAP8xbLjaj2MTjbnBnBymeYK6TNk1G1WS ZAvwujdfgimXLi3uDmfWuhWE9yZtG4KMZuQAGm7ZQTmmxhj4KLFS0htoU1zTe56g xnQvIB/wH0YETukkBdKnApb7gGS34cPbq8rNHb9qK5qgNwJAnDPN7x7QYAXIslXM jlXAtzbavVa83KGsivibf4UxIQiEZ4LYNxh+qfAzthsCHDxsM8WSvIbyv0kE2xpF tWyIsHyCrd1jrbkwbd6ADpUvyuPoKEhXFe51Sc2ntgjYeTcVRt7B3ldW67IgvaOT VdjPhse8aevQwOeLAjYz9aohv3ndNrXydS4wUub4+zd5NlV4Nt7DrmiT/T0fZrtd cBlfwF7NHdTk2GU41Rkd4702YyqLomfQlCHtyk3X62qIFhXiYScqZLF/3++3kqnA cfsBVigDmcnr64hbxWty/AoeObvNKY/ACjU6NOMerxzrSvLCe+kZAZl4exh/SvK0 uO0hP+dOj6wJ0IAq2MbvSRlxqQB4nGeN3BrlRbFyAEul0r5ZWfTEUysMJFLde9ye 2dYeXSX1DRrPF5TRh+66Osh4eElc7N5NaFZmyNvT3OT1CxnVbncgA6nWaBD7RI+j pW1tQ35o/y/9JiC6Gfbe5DQdbKEWKItDL5eoz/l7k+92J+Cx7VP/6jH8cMSdoIl5 KntdwQtEE8XG8XIuid7o7bmySXNHW32mt8uqh6yX8J9QPmufALbth0fnVIOJYNs6 GYeaJWcaXe36hMfVdkkGkPkP5qa2iBBPI+DILEooa+0bLent0ki36wFwZ0Ynu2x5 WOzlpWUGcezM3hXssffEwIvgonrnrdRiLO9wcdkOhClZe1M65gMrbCARPvNpK5II 9qtC/JWM7rOHV5xAwUYq0PlQ7X/FZGM6tILM/2B03lhZUPsPfMWWUGQYtkVjtmJE ktEsKDmzg3E3HutnhhrbX18NAD7PlheZ5TCBSllZTESG6QaEYXVwRMzgkSAhH+4N 4twwYUpi4ONKc/rqw5oWmOigysOanCWOIbAGDsf5sdxV2N/Y1tfERD/4ze2c3KOr s7EXCzYvrpRX8sifnl9ahriEskzl3Vl9pk8XZefEvt2pCCei2HfCpzv6XLnyPNd3 8bUV3BhTGxQtzhLT8s5crO8o2dOcUkj+zd2rFeHF5k2YycqTtU8jqKsRhtbBkMdU 8pRBPD1DIcBWs4q8ljuzPwFY5vrpRzJZpsdlosvxa3SVkc6ND3EQDm58BVBMqqSm pfk8ht34bv6Hst3EqSCsh8JUNDlivE/eUW2AyPEEoqexgpTQjMjYXZy0BDlE9yZn nc7JyLVQax6GAF3o7nb8KANo6gs2nSBjwraTnFREdeqPk45kVZn9Z/i2y0JFNWxJ vis+ntFCTe1Z2WlA8aKG6pCQ9IqX9j6tGmy9YqqHJ7N0zDxgjRGnDEg1sAKxmTxp HES65jsAvuAmmEj2q99B2QHnODl4pUZ+Tc1UexLTQQvmla5yJzLsPqN57jaZSXqW cxB3DXv5JUKF6i7ZJog+/KVCX10cF/zNt4hu+3XKH2INCkBxOq2bVhCQkyztwOFQ -----END RSA PRIVATE KEY----- cfengine-3.24.2/tests/acceptance/Makefile.in0000644000000000000000000012041515010704301020645 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) @WINDOWS_FALSE@am__append_1 = mock_package_manager no_fds \ @WINDOWS_FALSE@ custom_promise_binary @HAVE_LIBXML2_TRUE@am__append_2 = xml-c14nize TESTS = @HAVE_LIBXML2_FALSE@am__append_3 = LIBXML2_TESTS=0 @HAVE_LIBCURL_FALSE@am__append_4 = LIBCURL_TESTS=0 subdir = tests/acceptance ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libmock_package_manager_la_DEPENDENCIES = \ ../../libpromises/libpromises.la am_libmock_package_manager_la_OBJECTS = mock_package_manager.lo libmock_package_manager_la_OBJECTS = \ $(am_libmock_package_manager_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = @WINDOWS_FALSE@am__EXEEXT_1 = mock_package_manager$(EXEEXT) \ @WINDOWS_FALSE@ no_fds$(EXEEXT) custom_promise_binary$(EXEEXT) @HAVE_LIBXML2_TRUE@am__EXEEXT_2 = xml-c14nize$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) am__custom_promise_binary_SOURCES_DIST = \ 30_custom_promise_types/custom_promise_binary.c @WINDOWS_FALSE@am_custom_promise_binary_OBJECTS = \ @WINDOWS_FALSE@ custom_promise_binary.$(OBJEXT) custom_promise_binary_OBJECTS = $(am_custom_promise_binary_OBJECTS) custom_promise_binary_LDADD = $(LDADD) am_mock_package_manager_OBJECTS = mock_package_manager_OBJECTS = $(am_mock_package_manager_OBJECTS) @WINDOWS_FALSE@mock_package_manager_DEPENDENCIES = \ @WINDOWS_FALSE@ libmock_package_manager.la no_fds_SOURCES = no_fds.c no_fds_OBJECTS = no_fds.$(OBJEXT) @WINDOWS_FALSE@no_fds_DEPENDENCIES = \ @WINDOWS_FALSE@ ../../libntech/libutils/libutils.la xml_c14nize_SOURCES = xml-c14nize.c xml_c14nize_OBJECTS = xml_c14nize-xml-c14nize.$(OBJEXT) am__DEPENDENCIES_1 = @HAVE_LIBXML2_TRUE@xml_c14nize_DEPENDENCIES = \ @HAVE_LIBXML2_TRUE@ ../../libntech/libutils/libutils.la \ @HAVE_LIBXML2_TRUE@ $(am__DEPENDENCIES_1) xml_c14nize_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(xml_c14nize_CFLAGS) \ $(CFLAGS) $(xml_c14nize_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libmock_package_manager_la_SOURCES) \ $(custom_promise_binary_SOURCES) \ $(mock_package_manager_SOURCES) no_fds.c xml-c14nize.c DIST_SOURCES = $(libmock_package_manager_la_SOURCES) \ $(am__custom_promise_binary_SOURCES_DIST) \ $(mock_package_manager_SOURCES) no_fds.c xml-c14nize.c RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = $(CORE_LIBS) LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ SUBDIRS = 25_cf-execd AM_CPPFLAGS = \ -I$(top_srcdir)/libntech/libutils \ -I$(top_srcdir)/libcfecompat \ -I$(top_srcdir)/libpromises \ -I$(top_srcdir)/libcfnet \ $(CORE_CPPFLAGS) $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = $(CORE_CFLAGS) AM_LDFLAGS = $(CORE_LDFLAGS) noinst_LTLIBRARIES = libmock_package_manager.la libmock_package_manager_la_SOURCES = mock_package_manager.c libmock_package_manager_la_LIBADD = ../../libpromises/libpromises.la @WINDOWS_FALSE@mock_package_manager_SOURCES = @WINDOWS_FALSE@mock_package_manager_LDADD = libmock_package_manager.la @WINDOWS_FALSE@no_fds_LDADD = ../../libntech/libutils/libutils.la @WINDOWS_FALSE@custom_promise_binary_SOURCES = 30_custom_promise_types/custom_promise_binary.c @HAVE_LIBXML2_TRUE@xml_c14nize_CPPFLAGS = \ @HAVE_LIBXML2_TRUE@ -I$(top_srcdir)/libpromises \ @HAVE_LIBXML2_TRUE@ -I$(srcdir)/../../libntech/libutils \ @HAVE_LIBXML2_TRUE@ $(LIBXML2_CPPFLAGS) @HAVE_LIBXML2_TRUE@xml_c14nize_CFLAGS = $(LIBXML2_CFLAGS) @HAVE_LIBXML2_TRUE@xml_c14nize_LDFLAGS = $(LIBXML2_LDFLAGS) @HAVE_LIBXML2_TRUE@xml_c14nize_LDADD = ../../libntech/libutils/libutils.la $(LIBXML2_LIBS) TESTS_ENVIRONMENT = env AGENT=`pwd`/../../cf-agent/cf-agent \ CF_PROMISES=`pwd`/../../cf-promises/cf-promises \ CF_SERVERD=`pwd`/../../cf-serverd/cf-serverd \ CF_KEY=`pwd`/../../cf-key/cf-key \ CF_NET=`pwd`/../../cf-net/cf-net \ CF_CHECK=`pwd`/../../cf-check/cf-check \ RPMVERCMP=`pwd`/../../ext/rpmvercmp \ MOCK_PACKAGE_MANAGER=`pwd`/mock_package_manager \ $(am__append_3) $(am__append_4) # Recursively include all tests in the dist tarball and set proper permissions EXTRA_DIST = default.cf.sub dcs.cf.sub plucked.cf.sub \ run_with_server.cf.sub testall dummy_etc write_args.sh \ root-MD5=617eb383deffef843ea856b129d0a423.pub \ root-MD5=617eb383deffef843ea856b129d0a423.priv $(wildcard \ [0-9]*) CLEANFILES = *.gcno *.gcda Makefile.testall all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/acceptance/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/acceptance/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libmock_package_manager.la: $(libmock_package_manager_la_OBJECTS) $(libmock_package_manager_la_DEPENDENCIES) $(EXTRA_libmock_package_manager_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libmock_package_manager_la_OBJECTS) $(libmock_package_manager_la_LIBADD) $(LIBS) clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list custom_promise_binary$(EXEEXT): $(custom_promise_binary_OBJECTS) $(custom_promise_binary_DEPENDENCIES) $(EXTRA_custom_promise_binary_DEPENDENCIES) @rm -f custom_promise_binary$(EXEEXT) $(AM_V_CCLD)$(LINK) $(custom_promise_binary_OBJECTS) $(custom_promise_binary_LDADD) $(LIBS) mock_package_manager$(EXEEXT): $(mock_package_manager_OBJECTS) $(mock_package_manager_DEPENDENCIES) $(EXTRA_mock_package_manager_DEPENDENCIES) @rm -f mock_package_manager$(EXEEXT) $(AM_V_CCLD)$(LINK) $(mock_package_manager_OBJECTS) $(mock_package_manager_LDADD) $(LIBS) no_fds$(EXEEXT): $(no_fds_OBJECTS) $(no_fds_DEPENDENCIES) $(EXTRA_no_fds_DEPENDENCIES) @rm -f no_fds$(EXEEXT) $(AM_V_CCLD)$(LINK) $(no_fds_OBJECTS) $(no_fds_LDADD) $(LIBS) xml-c14nize$(EXEEXT): $(xml_c14nize_OBJECTS) $(xml_c14nize_DEPENDENCIES) $(EXTRA_xml_c14nize_DEPENDENCIES) @rm -f xml-c14nize$(EXEEXT) $(AM_V_CCLD)$(xml_c14nize_LINK) $(xml_c14nize_OBJECTS) $(xml_c14nize_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/custom_promise_binary.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mock_package_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/no_fds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml_c14nize-xml-c14nize.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< custom_promise_binary.o: 30_custom_promise_types/custom_promise_binary.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT custom_promise_binary.o -MD -MP -MF $(DEPDIR)/custom_promise_binary.Tpo -c -o custom_promise_binary.o `test -f '30_custom_promise_types/custom_promise_binary.c' || echo '$(srcdir)/'`30_custom_promise_types/custom_promise_binary.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/custom_promise_binary.Tpo $(DEPDIR)/custom_promise_binary.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='30_custom_promise_types/custom_promise_binary.c' object='custom_promise_binary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o custom_promise_binary.o `test -f '30_custom_promise_types/custom_promise_binary.c' || echo '$(srcdir)/'`30_custom_promise_types/custom_promise_binary.c custom_promise_binary.obj: 30_custom_promise_types/custom_promise_binary.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT custom_promise_binary.obj -MD -MP -MF $(DEPDIR)/custom_promise_binary.Tpo -c -o custom_promise_binary.obj `if test -f '30_custom_promise_types/custom_promise_binary.c'; then $(CYGPATH_W) '30_custom_promise_types/custom_promise_binary.c'; else $(CYGPATH_W) '$(srcdir)/30_custom_promise_types/custom_promise_binary.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/custom_promise_binary.Tpo $(DEPDIR)/custom_promise_binary.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='30_custom_promise_types/custom_promise_binary.c' object='custom_promise_binary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o custom_promise_binary.obj `if test -f '30_custom_promise_types/custom_promise_binary.c'; then $(CYGPATH_W) '30_custom_promise_types/custom_promise_binary.c'; else $(CYGPATH_W) '$(srcdir)/30_custom_promise_types/custom_promise_binary.c'; fi` xml_c14nize-xml-c14nize.o: xml-c14nize.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_c14nize_CPPFLAGS) $(CPPFLAGS) $(xml_c14nize_CFLAGS) $(CFLAGS) -MT xml_c14nize-xml-c14nize.o -MD -MP -MF $(DEPDIR)/xml_c14nize-xml-c14nize.Tpo -c -o xml_c14nize-xml-c14nize.o `test -f 'xml-c14nize.c' || echo '$(srcdir)/'`xml-c14nize.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_c14nize-xml-c14nize.Tpo $(DEPDIR)/xml_c14nize-xml-c14nize.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xml-c14nize.c' object='xml_c14nize-xml-c14nize.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_c14nize_CPPFLAGS) $(CPPFLAGS) $(xml_c14nize_CFLAGS) $(CFLAGS) -c -o xml_c14nize-xml-c14nize.o `test -f 'xml-c14nize.c' || echo '$(srcdir)/'`xml-c14nize.c xml_c14nize-xml-c14nize.obj: xml-c14nize.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_c14nize_CPPFLAGS) $(CPPFLAGS) $(xml_c14nize_CFLAGS) $(CFLAGS) -MT xml_c14nize-xml-c14nize.obj -MD -MP -MF $(DEPDIR)/xml_c14nize-xml-c14nize.Tpo -c -o xml_c14nize-xml-c14nize.obj `if test -f 'xml-c14nize.c'; then $(CYGPATH_W) 'xml-c14nize.c'; else $(CYGPATH_W) '$(srcdir)/xml-c14nize.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xml_c14nize-xml-c14nize.Tpo $(DEPDIR)/xml_c14nize-xml-c14nize.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xml-c14nize.c' object='xml_c14nize-xml-c14nize.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xml_c14nize_CPPFLAGS) $(CPPFLAGS) $(xml_c14nize_CFLAGS) $(CFLAGS) -c -o xml_c14nize-xml-c14nize.obj `if test -f 'xml-c14nize.c'; then $(CYGPATH_W) 'xml-c14nize.c'; else $(CYGPATH_W) '$(srcdir)/xml-c14nize.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local check: check-recursive all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-TESTS check-am check-local clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ cscopelist-am ctags ctags-am dist-hook distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile # Keep the '+' in front for the command, needed for the sub-make # to run in parallel; TODO fix "make -n" not working: check-local: + $(TESTS_ENVIRONMENT) MAKE=$(MAKE) $(srcdir)/testall dist-hook: chmod -R go-w $(distdir) pluck: echo '### This is an auto-generated file, see Makefile.am and `make pluck` ###' > plucked.cf.sub ../../contrib/cf-locate/cf-locate -f -p '( if_|run_|warn_only|INI_section|kept_successful_command|edit_line|set_user_field|set_variable_values\(|edit_field|set_line_based|location|replace_with|_cp|_dcp|empty|shell|immediate|perms| m\b|recurse|tidy| all|classes_generic|results| start|always|^value|edit_field line|insert_lines|(link|copy)from| file_mustache| (file|dir)_(copy|tidy|sync|make|empty|link|hardlink))' ../../../masterfiles/lib/*.cf >> plucked.cf.sub # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/acceptance/no_fds.c0000644000000000000000000000517215010704253020224 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include static void usage(void) { printf("Runs the given command without inheriting any file descriptors.\n" "Usage: no_fds [options]\n" "Options:\n" " --no-std\n" " Even stdin/stdout/stderr will not be inherited.\n" " -h, --help\n" " This help screen.\n"); } static void close_on_exec(int fd) { #ifdef _WIN32 SetHandleInformation((HANDLE)_get_osfhandle(fd), HANDLE_FLAG_INHERIT, 0); #else long flags = fcntl(fd, F_GETFD); flags |= FD_CLOEXEC; fcntl(fd, F_SETFD, flags); #endif } int main(int argc, char **argv) { bool std = true; int startarg = 1; for (int arg = 1; arg < argc; arg++) { if (strcmp(argv[arg], "--no-std") == 0) { std = false; startarg++; } else if (strcmp(argv[arg], "-h") == 0 || strcmp(argv[arg], "--help") == 0) { usage(); return 0; } else if (argv[arg][0] == '-') { fprintf(stderr, "Unknown option: %s\n", argv[arg]); usage(); return 1; } else { break; } } closefrom(3); if (!std) { for (int fd = 0; fd < 3; fd++) { close_on_exec(fd); } } char *new_args[argc - startarg + 1]; for (int i = startarg; i < argc; i++) { new_args[i - startarg] = argv[i]; } new_args[argc - startarg] = NULL; execvp(new_args[0], new_args); fprintf(stderr, "Could not execute command '%s': %s\n", new_args[0], GetErrorStr()); return 1; } cfengine-3.24.2/tests/acceptance/README0000644000000000000000000003542315010704253017472 0ustar00rootroot00000000000000============================================================================== CFEngine acceptance testsuite ============================================================================== CFEngine has an extensive testsuite which covers lot of functionality which can be tested as a series of cf-agent runs. You are encouraged to run this testsuite on any new software/hardware configuration, in order to * verify that CFEngine functions correctly * provide developers with reproducible way to fix any problems encountered in new configurations / environment In case you find a bug you are encouraged to create tests in format of testsuite which demonstrate bug found, so the test could be added to this testsuite and checked for in the future. Note that the testall script generates JUnit style XML output for parsing by CI systems. https://llg.cubic.org/docs/junit/ ------------------------------------------------------------------------------ Preparing for running tests ------------------------------------------------------------------------------ * Compile CFEngine. - It is advised to use Tokyo Cabinet as it gives much better performance in test suite over Berkeley DB. * Install fakeroot(1). If this tool is not available for your operating system, you may use any other "fake root" environment or even sudo(1). Alternative tools are specified by --gainroot option of `testall' script. Note that if you use the --unsafe option (can damage your system), you may have to use --gainroot=sudo in order to get correct results. * If you want output in color, set CFENGINE_COLOR to 1. If you want diff output colorized, you also need to install the colordiff utility. * If you plan to use `git bisect` to hunt for a bug, try tests/acceptance/bisect-acceptance.pl, contributed by the indomitable Chris Dituri ------------------------------------------------------------------------------ Running testsuite ------------------------------------------------------------------------------ All tests ought only to create files and directories in /tmp, and ought not to modify other files. The exception to this rule are so called unsafe tests, which reside in a special directory. More on unsafe tests below. Run ./testall --agent=$workdir/bin/cf-agent e.g. ./testall --agent=/var/cfengine/bin/cf-agent Testing will start. For every test case the name and result (failed / passed) will be produced. At the end testing summary will be provided. Test runner creates the following log files: * test.log contains detailed information about each test case (name, standard output/error contents, return code, and test status). * summary.log contains summary information, like the one displayed during testsuite run. Also a directory .succeeded will be created, containing stamps for each passed test case, so test cases which passed before and failing in subsequent testsuite run will be additionally marked in output as "(UNEXPECTED FAILURE)". You might run a subset of tests by passing either filenames: ./testall --agent=$workdir/bin/cf-agent 01_vars/01_basic/sysvars.cf or directories to 'testall': ./testall --agent=$workdir/bin/cf-agent 01_vars ------------------------------------------------------------------------------ Creating/editing test cases ------------------------------------------------------------------------------ Each test should be 100% standalone. If you include "default.cf.sub" in inputs, then the bundlesequence is automatically defined, and your file must contain at least 1 of the main bundles: * init - setup, create initial and hoped-for final states * test - the actual test code * check - the comparison of expected and actual results * destroy - anything you want to do at the end like killing processes etc However if the test is really simple you might want to skip including "default.cf.sub" in inputs. Then you should define your own bundlesequence, e.g. {"test","check"}. It's recommended to avoid including "default.cf.sub" when not needed, since the test will run much faster. Look in default.cf for some standard check bundles (for example, to compare files when testing file edits, or for cleaning up temporary files). For a test named XYZ, if the test runner finds the file XYZ.def.json, that file will be copied to the input directory so it will be loaded on startup. That lets you set hard classes and def variables and add inputs before the test ever runs. Tests should be named with short names describing what they test, using lower- case letters and underscores only. If the test is expected to generate an error (that is, if they contan syntax errors or other faults), it should have an additional '.x' suffix before '.cf' (e.g. 'string_vars.x.cf'). A crash will still cause a failure. Tests which are not expected to pass yet (e.g. there is a bug in code which prevents tests from passing) should be placed in 'staging' subdirectory in the test directory where they belong. Such test cases will be only run if --staging argument to ./testall is passed. Tests which modify the system outside of /tmp are so called unsafe tests, and should be placed in the 'unsafe' subdirectory in the directory where they belong. Such test cases have the potential to damage the host system and will only be run if the --unsafe argument is given to ./testall. For the user's protection, this option is needed even if the test file name is specified directly on the command line. Tests which need network connectivity should be placed to 'network' subdirectories. Those tests may be disabled by passing --no-network option to 'testall'. Tests which cannot be run in parallel with other tests should be put in a 'serial' subdirectory. This is necessary if the test depends on for example a certain number of cf-agent processes running, or to open a network port that may be shared with other tests. Unsafe tests are always carried out serially, and do not need to be in a 'serial' subdirectory. You can also give individual tests a name that contains "serial" as a word. Serial tests enforce strictly sorted order when they are encountered, so you can use them to initialize some precondition for a set a of tests by sorting it lexicographically before the others and giving it a name containing "serial". The other tests can then be executed in parallel, unless they need to be serial for other reasons. For example, you can use two serial tests, one to set up a cf-serverd, and one to tear it down, and in between you put normal tests. Note that timed tests (see below) have one small exception: If a test that is both timed and serial is executed in the same "block" as other serial tests (that is, when one or more serials tests follow another), it will always be executed first. So put it in a timed directory as well, if you want to be absolutely sure. NOTE: Since the class 'ok' is used in most tests, never create a persistent class called 'ok' in any test. Persistent classes are cleaned up between test runs, but better safe than sorry. All tests should contain three bundles: init, test and check. In the "body common control" this file should be included, and bundlesequence should be set to default("$(this.promise_filename)"). Output "$(this.promise_filename) Pass" for passing and "$(this.promise_filename) FAIL" for failing. If you want to use tools like grep, diff, touch, etc, please use the $(G.grep) format so that the correct path to the tool is chosen by the test template. If a tool is missing you can add it to dcs.cf.sub. ------------------------------------------------------------------------------ Waiting in tests ------------------------------------------------------------------------------ If your test needs to wait for a significant amount of time, for example in order for locks to expire, you should use the wait functionality in the test suite. It requires three parts: 1. Your test needs to be put in a "timed" directory. 2. Whenever you want to wait, use the "dcs_wait($(this.promise_filename), )" method to wait the specified number of seconds. 3. Each test invocation will have a predefined class set, "test_pass_", where is the current pass number starting from one. This means you can wait several times. The test suite will keep track of time, and run other tests while your test is waiting. Some things to look out for though: - During the wait time, your test is no longer running, so you cannot for example do polling. - You cannot leave daemons running while waiting, because it may interfere with other tests. If you need that you will have to wait the traditional way, by introducing sleeps in the policy itself. - The timing is not guaranteed to be accurate to the second. The test will be resumed as soon as the current test has finished running, but if it takes a long time, this will add to the wait time. ------------------------------------------------------------------------------ Handling different platforms ------------------------------------------------------------------------------ For tests that need to be skipped on certain platforms, you can add special meta variables to the *test* bundle. These are the possible variable names: - test_skip_unsupported Skips a test because it makes no sense on that platform (e.g. symbolic links on Windows). - test_skip_needs_work Skips a test because the test itself is not adapted to the platform (even if the functionality exists). - test_soft_fail - test_suppress_fail - test_flakey_fail Runs the test, but will accept failure. Use this when there is a real failure, but it is acceptable for the time being. This variable requires a meta tag on the variable set to "redmine", where is a Redmine issue number. There is a subtle difference between the three. Soft failures will not be reported as a failure in the XML output, and is appropriate for test cases that document incoming bug reports. Suppressed failures will count as a failure, but it won't block the build, and is appropriate for regressions or bad test failures. Flakey failures count in a category by themselves and won't block the build. If any are present then a different exit code will be produced from the test run so that CI runners can react accordingly. Additionally, a *description* meta variable can be added to the test to describe its function. meta: "description" -> { "CFE-2971" } string => "Test that class expressions can be used to define classes via augments"; The rule of thumb is: * If you are writing an acceptance test for a (not yet fixed) bug in Redmine, use test_soft_fail. * If you need the build to work, but the bug you are suppressing cannot stay unfixed for long, use test_suppress_fail. In all cases, the variable is expected to be set to a class expression suitable for ifvarclass, where a positive match means that the test will be skipped. So the expression '"test_skip_needs_work" string => "hpux|aix";' will skip the test on HP-UX and AIX, and nowhere else. Example: bundle agent test { meta: # Indicate that this test should be skipped on hpux because the # functionality is unsupported on that platform. "test_skip_unsupported" string => "hpux"; } bundle agent test { meta: # Indicates that the test should be skipped on hpux because the # test needs to be adapted for the platform. "test_skip_needs_work" string => "hpux"; } bundle agent test { meta: # Indicate the test is expected to fail on hpux and aix, but # should not cause the build to change from green. This is # appropriate for test cases that document incoming bug reports. "test_soft_fail" string => "hpux|aix", meta => { "redmine1234" }; } bundle agent test { meta: # Indicate the test is expected to fail on hpux but will not # block the build. This is appropriate for regressions or very # bad bad test failures. "test_suppress_fail" string => "hpux", meta => { "redmine1234" }; } ------------------------------------------------------------------------------ Glossary ------------------------------------------------------------------------------ For purposes of testing, here is what our terms mean: Pass: the test did what we expected (whether that was setting a variable, editing a file, killing or starting a process, or correctly failing to do these actions in the light of existing conditions or attributes). Note that in the case of tests that end in an 'x', a Pass is generated when the test abnormally terminates and we wanted it to do that. FAIL: not doing what we wanted: either test finished and returned "FAIL" from check bundle, or something went wrong - cf-agent might have dropped core, cf-promises may have denied execution of the promises, etc. Soft fail: the test failed as expected by a "test_soft_fail" promise. Skipped: test is skipped due to be either explicitly disabled or being Nova-specific and being run on Community cf-agent. ------------------------------------------------------------------------------ Example Test Skeleton ------------------------------------------------------------------------------ body file control { # Feel free to avoid including "default.cf.sub" and define your # own bundlesequence for simple tests inputs => { "../default.cf.sub" }; } ####################################################### bundle agent init # Initialize the environment and prepare for test { } bundle agent test # Activate policy for behaviour you wish to inspect { meta: "description" -> { "CFE-1234" } string => "What does this test?"; "test_soft_fail" string => "Class_Expression|here", meta => { "CFE-1234" }; } bundle agent check # Check the result of the test { # Pass/Fail requires a specific format: # reports: "$(this.promise_filename) Pass"; # reports: "$(this.promise_filename) FAIL"; # Consider using one of the dcs bundles # methods: "Pass/Fail" usebundle => dcs_passif( "Namespace_Scoped_Class_Indicating_Test_Passed", $(this.promise_filename) ); } bundle agent __main__ # @brief The test entry # Note: The testall script runs the agent with the acceptance test as the entry point, ##+begin_src sh :results output :exports both :dir ~/CFEngine/core/tests/acceptance # pwd | sed 's/\/.*CFEngine\///' # find . -name "*.cf*" | xargs chmod 600 # cf-agent -Kf ./01_vars/02_functions/basename_1.cf --define AUTO ##+end_src sh # ##+RESULTS: #: core/tests/acceptance #: R: /home/nickanderson/Northern.Tech/CFEngine/core/tests/acceptance/./01_vars/02_functions/basename_1.cf Pass { methods: "Run the default test bundle sequence (init,test,check,cleanup) if defined" usebundle => default( $(this.promise_filename) ); } ------------------------------------------------------------------------------ cfengine-3.24.2/tests/acceptance/28_inform_testing/0000755000000000000000000000000015010704253022143 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/0000755000000000000000000000000015010704253025574 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml03.cf0000644000000000000000000000202715010704253030057 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { vars: "xml" string => "y"; files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath("$(xml)"), create => "true"; } bundle agent main { vars: "xml2" string => "text content"; files: "$(G.testfile)" edit_xml => xml_insert_tree("$(xml2)", "//x"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_tree(treestring, xpath) { insert_tree: '$(treestring)' select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/transformer.cf.expected0000644000000000000000000000025715010704253032254 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, transformer => "$(G.gzip) $(G.testfile)" info: Transformed '/tmp/TEST.cfengine' with '/bin/bzip /tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/touch.cf0000644000000000000000000000040415010704253027226 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent main { files: "$(G.testfile)" touch => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml09.cf0000644000000000000000000000170715010704253030071 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath("text content"), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_delete_tree("text content", "//b"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_delete_tree(subtree, xpath) { delete_tree: "$(subtree)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/rename_newname.cf.expected0000644000000000000000000000020615010704253032665 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, rename => newname info: Renamed file '/tmp/TEST.cfengine' to 'TEST.foobar' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml01.cf.expected0000644000000000000000000000032315010704253031652 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => build_xpath("/Server/Service/Engine/Host"); info: Built XPath '/Server/Service/Engine/Host' into an empty XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/touch.cf.expected0000644000000000000000000000022515010704253031027 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, touch => "true" info: Created and Touched (updated time stamps) file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/changes01.cf0000644000000000000000000000067215010704253027664 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" changes => example; } body changes example { hash => "best"; update_hashes => "true"; report_changes => "content"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line02.cf0000644000000000000000000000137315010704253030210 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => delete_lines_matching("foo 1"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml02.cf.expected0000644000000000000000000000031315010704253031652 0ustar00rootroot00000000000000 info: Inserted tree 'y' at XPath '//Root' in XML document'/tmp/TEST.cfengine' info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => xml_insert_tree("$(xml1)", "//Root") cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line04.cf0000644000000000000000000000136715010704253030215 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => regex_replace("bar","BAR"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/test_files/0000755000000000000000000000000015010704253027735 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/test_files/file-perms-6440000644000000000000000000000000015010704253032224 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/test_files/subdir/0000755000000000000000000000000015010704253031225 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/test_files/subdir/subdir-file0000644000000000000000000000000015010704253033343 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml08.cf0000644000000000000000000000163615010704253030071 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_insert_text("Tuesday", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_text(text, xpath) { insert_text: "$(text)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml05.cf0000644000000000000000000000174015010704253030062 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_set_attribute("my_attr", "my_value", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_set_attribute(attr, value, xpath) { set_attribute: "$(attr)" attribute_value => "$(value)", select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml02.cf0000644000000000000000000000202515010704253030054 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { vars: "xml1" string => "y"; "xml2" string => "text content"; files: "$(G.testfile)" edit_xml => xml_insert_tree("$(xml1)", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_tree(treestring, xpath) { insert_tree: '$(treestring)' select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml03.cf.expected0000644000000000000000000000031115010704253031651 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, xml_insert_tree("$(xml2)", "//x") info: Inserted tree 'text content' at XPath '//x' in XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/copy_from01.cf.expected0000644000000000000000000000055315010704253032047 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.destination' repaired, copy_from => example('/tmp/TEST.source'), depth_search => recurse("inf") info: Replaced file '/tmp/TEST.destination/subdir/subdir-file' from 'localhost:/tmp/TEST.source/subdir/subdir-file' info: Replaced file '/tmp/TEST.destination/file-perms-644' from 'localhost:/tmp/TEST.source/file-perms-644' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml07.cf0000644000000000000000000000174115010704253030065 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { vars: "xml" string => "text content"; files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath($(xml)), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_delete_text("text content", "//c"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_delete_text(match, xpath) { delete_text: "$(match)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/copy_from01.cf0000644000000000000000000000115515010704253030246 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testroot)/TEST.source" depth_search => recurse("inf"), copy_from => example("$(this.promise_dirname)/test_files"); } bundle agent main { files: "$(G.testroot)/TEST.destination" depth_search => recurse("inf"), copy_from => example("$(G.testroot)/TEST.source"); } body copy_from example(from) { source => "$(from)"; compare => "digest"; preserve => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line03.cf0000644000000000000000000000136515010704253030212 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => insert_lines("amazing!"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line03.cf.expected0000644000000000000000000000025215010704253032004 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_line => insert_lines("amazing!"); info: Inserted line 'amazing!' into '/tmp/TEST.cfengine' at end of file cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line01.cf0000644000000000000000000000140615010704253030204 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => set_colon_field("me","6","/my/new/shell"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/changes01.cf.expected0000644000000000000000000000035115010704253031456 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, changes => example info: Detected changes for '/tmp/TEST.cfengine', md5 hash 'MD5=d41d8cd98f00b204e9800998ecf8427e', sha1 hash 'SHA=da39a3ee5e6b4b0d3255bfef95601890afd80709' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/rename_newname.cf0000644000000000000000000000070515010704253031071 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; "$(G.testroot)/TEST.foobar" delete => init_delete; } bundle agent main { files: "$(G.testfile)" rename => newname; } body rename newname { newname => "TEST.foobar"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line01.cf.expected0000644000000000000000000000032315010704253032001 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_line => set_colon_field("me","6","/my/new/shell"); info: Set field 6 with separator ':' to value '/my/new/shell' on line 4 of '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/delete.cf.expected0000644000000000000000000000017115010704253031147 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, delete => init_delete info: Deleted file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/delete.cf0000644000000000000000000000052515010704253027352 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" delete => init_delete; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/copy_from02.cf0000644000000000000000000000136315010704253030250 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testroot)/TEST.source" depth_search => recurse("inf"), copy_from => example("$(this.promise_dirname)/test_files"); } bundle agent main { files: "$(G.testroot)/TEST.destination" depth_search => recurse("inf"), copy_from => example2("$(G.testroot)/TEST.source"); } body copy_from example(from) { source => "$(from)"; compare => "digest"; preserve => "true"; } body copy_from example2(from) { source => "$(from)"; compare => "mtime"; check_root => "true"; copy_backup => "timestamp"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml06.cf0000644000000000000000000000166315010704253030067 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_delete_attribute("foo", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_delete_attribute(attr, xpath) { delete_attribute: "$(attr)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/transformer.cf0000644000000000000000000000065315010704253030454 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true", edit_line => insert_lines(" zebra apple dog cat banana "); } bundle agent main { files: "$(G.testfile)" transformer => "$(G.gzip) $(G.testfile)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml09.cf.expected0000644000000000000000000000032215010704253031661 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => xml_delete_tree("text content", "//b") info: Deleted tree 'text content' at XPath '//b' in XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/changes02.cf0000644000000000000000000000054515010704253027664 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => insert_lines("foobar"); } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml08.cf.expected0000644000000000000000000000030515010704253031661 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => xml_insert_text("Tuesday", "//Root") info: Inserted text 'Tuesday' at XPath '//Root' in the XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/copy_from03.cf0000644000000000000000000000160615010704253030251 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testroot)/TEST.source" depth_search => recurse("inf"), copy_from => example("$(this.promise_dirname)/test_files"); } bundle agent main { files: "$(G.testroot)/TEST.destination/purgeme" create => "true", handle => "step_one"; "$(G.testroot)/TEST.destination" depends_on => { "step_one" }, depth_search => recurse("inf"), move_obstructions => "true", copy_from => example3("$(G.testroot)/TEST.source"); } body copy_from example(from) { source => "$(from)"; compare => "digest"; preserve => "true"; } body copy_from example3(from) { source => "$(from)"; linkcopy_patterns => { ".*644" }; purge => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line02.cf.expected0000644000000000000000000000024715010704253032007 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_line => delete_lines_matching("foo 1"); info: Deleted line 'foo 1' from '/tmp/TEST.cfengine' at line 1 cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml07.cf.expected0000644000000000000000000000031015010704253031654 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => xml_delete_text("text content", "//c") info: Deleted text 'text content' at XPath '//c' in the XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/perms.cf0000644000000000000000000000051715010704253027237 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" perms => m(000); } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml05.cf.expected0000644000000000000000000000035515010704253031663 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => xml_set_attribute("my_attr", "my_value", "//Root") info: Set attribute with name 'my_attr' to value 'my_value' at XPath '//Root' in XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/create.cf0000644000000000000000000000040515010704253027350 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent main { files: "$(G.testfile)" create => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/perms.cf.expected0000644000000000000000000000021715010704253031034 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, perms => m(000) info: Changed permissions of '/tmp/TEST.cfengine' from 0600 to 0000 cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line05.cf0000644000000000000000000000153215010704253030210 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" template_method => "inline_mustache", edit_template_string => "Hi {{{username}}}!", template_data => '{ "username": "agent" }'; } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line05.cf.expected0000644000000000000000000000042615010704253032011 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, template_method => "inline_mustache", edit_template_string => "Hi {{{username}}}!", template_data => '{ "username": "agent" }' info: Updated rendering of '/tmp/TEST.cfengine' from mustache template 'Hi {{{username}}}!' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml04.cf0000644000000000000000000000163215010704253030061 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_set_value("foobar", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_set_value(value, xpath) { set_text: "$(value)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/rename_rotate.cf0000644000000000000000000000057415010704253030741 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" rename => rotate; } body rename rotate { rotate => "4"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml06.cf.expected0000644000000000000000000000030615010704253031660 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => xml_delete_attribute("foo", "//Root") info: Deleted attribute 'foo' at XPath '//Root' in the XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/rename_rotate.cf.expected0000644000000000000000000000023015010704253032526 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, rename => rotate info: Rotated file '/tmp/TEST.cfengine' in 4 fifo to '/tmp/TEST.cfengine.1' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/create.cf.expected0000644000000000000000000000017715010704253031156 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, create => "true" info: Created file '/tmp/TEST.cfengine', mode 0600 cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml01.cf0000644000000000000000000000135415010704253030057 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => build_xpath("/Server/Service/Engine/Host"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml build_xpath(xpath) { build_xpath: "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/copy_from02.cf.expected0000644000000000000000000000056515010704253032053 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.destination' repaired, depth_search => recurse("inf"), copy_from => example2("$(G.testroot)/TEST.source") info: Replaced file '/tmp/TEST.destination/subdir/subdir-file' from 'localhost:/tmp/TEST.source/subdir/subdir-file' info: Replaced file '/tmp/TEST.destination/file-perms-644' from 'localhost:/tmp/TEST.source/file-perms-644' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_line04.cf.expected0000644000000000000000000000024315010704253032005 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_line => regex_replace("bar","BAR"); info: Replaced pattern 'bar' in '/tmp/TEST.cfengine' at line 2 cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/copy_from03.cf.expected0000644000000000000000000000077115010704253032053 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.destination/purgeme' repaired, create => "true", handle => "step_one" info: Created file '/tmp/TEST.destination/purgeme', mode 0600 info: files promise '/tmp/TEST.destination' repaired, depth_search => recurse("inf"), move_obstructions => "true", copy_from => example3("$(G.testroot)/TEST.source") info: Purged '/tmp/TEST.destination/purgeme' info: Replaced '/tmp/TEST.destination/subdir/subdir-file' from 'localhost:/tmp/TEST.source/subdir/subdir-file' cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/changes02.cf.expected0000644000000000000000000000024515010704253031461 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_line => insert_lines('foobar') info: Inserted line 'foobar' into '/tmp/TEST.cfengine' at end of file cfengine-3.24.2/tests/acceptance/28_inform_testing/02_soft_fail_files/edit_xml04.cf.expected0000644000000000000000000000027015010704253031656 0ustar00rootroot00000000000000 info: files promise '/tmp/TEST.cfengine' repaired, edit_xml => xml_set_value("foobar", "//Root") info: Set text 'foobar' at XPath '//Root' in XML document '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/0000755000000000000000000000000015010704253023545 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml03.cf0000644000000000000000000000201515010704253026025 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { vars: "xml" string => "y"; files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath("$(xml)"), create => "true"; } bundle agent main { vars: "xml2" string => "text content"; files: "$(G.testfile)" edit_xml => xml_insert_tree("$(xml2)", "//x"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_tree(treestring, xpath) { insert_tree: '$(treestring)' select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/transformer.cf.expected0000644000000000000000000000037715010704253030230 0ustar00rootroot00000000000000 info: Transforming '/tmp/TEST.cfengine' with '/bin/gzip /tmp/TEST.cfengine' info: Transformed '/tmp/TEST.cfengine' with '/bin/gzip /tmp/TEST.cfengine' info: Transformer '/tmp/TEST.cfengine' => '/bin/gzip /tmp/TEST.cfengine' seemed to work ok cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/touch.cf0000644000000000000000000000037215010704253025203 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent main { files: "$(G.testfile)" touch => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml09.cf0000644000000000000000000000167515010704253026046 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath("text content"), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_delete_tree("text content", "//b"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_delete_tree(subtree, xpath) { delete_tree: "$(subtree)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/rename_newname.cf.expected0000644000000000000000000000010215010704253030631 0ustar00rootroot00000000000000 info: Renamed file '/tmp/TEST.cfengine' to '/tmp/TEST.foobar' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml01.cf.expected0000644000000000000000000000033015010704253027621 0ustar00rootroot00000000000000 info: Built XPath '/Server/Service/Engine/Host' into an empty XML document '/tmp/TEST.cfengine' info: build_xpath promise '/Server/Service/Engine/Host' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/touch.cf.expected0000644000000000000000000000017515010704253027004 0ustar00rootroot00000000000000 info: Created file '/tmp/TEST.cfengine', mode 0600 info: Touched (updated time stamps) for path '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/changes01.cf0000644000000000000000000000066015010704253025632 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" changes => example; } body changes example { hash => "best"; update_hashes => "true"; report_changes => "content"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line02.cf0000644000000000000000000000136115010704253026156 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => delete_lines_matching("foo 1"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml02.cf.expected0000644000000000000000000000031715010704253027627 0ustar00rootroot00000000000000 info: Inserted tree 'y' at XPath '//Root' in XML document '/tmp/TEST.cfengine' info: insert_tree promise 'y' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line04.cf0000644000000000000000000000135515010704253026163 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => regex_replace("bar","BAR"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/test_files/0000755000000000000000000000000015010704253025706 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/test_files/file-perms-6440000644000000000000000000000000015010704253030175 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/test_files/subdir/0000755000000000000000000000000015010704253027176 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/test_files/subdir/subdir-file0000644000000000000000000000000015010704253031314 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml08.cf0000644000000000000000000000162415010704253026037 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_insert_text("Tuesday", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_text(text, xpath) { insert_text: "$(text)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml05.cf0000644000000000000000000000172615010704253026037 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_set_attribute("my_attr", "my_value", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_set_attribute(attr, value, xpath) { set_attribute: "$(attr)" attribute_value => "$(value)", select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/delete-dir.cf0000644000000000000000000000055115010704253026076 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testdir)/sub-directory/." create => "true"; } bundle agent main { files: "$(G.testdir)/sub-directory/." delete => init_delete; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml02.cf0000644000000000000000000000201315010704253026022 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { vars: "xml1" string => "y"; "xml2" string => "text content"; files: "$(G.testfile)" edit_xml => xml_insert_tree("$(xml1)", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_tree(treestring, xpath) { insert_tree: '$(treestring)' select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml03.cf.expected0000644000000000000000000000035215010704253027627 0ustar00rootroot00000000000000 info: Inserted tree 'text content' at XPath '//x' in XML document '/tmp/TEST.cfengine' info: insert_tree promise 'text content' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/copy_from01.cf.expected0000644000000000000000000000171215010704253030016 0ustar00rootroot00000000000000 info: Created directory '/tmp/TEST.destination/subdir/.', mode 0700 info: Copied file '/tmp/TEST.source/file-perms-644' to '/tmp/TEST.destination/file-perms-644.cfnew' (permissions preserved) info: Moved '/tmp/TEST.destination/file-perms-644.cfnew' to '/tmp/TEST.destination/file-perms-644' info: Regular file '/tmp/TEST.destination/file-perms-644' had permissions 0600, changed it to 0644 info: Updated file '/tmp/TEST.destination/file-perms-644' from 'localhost:/tmp/TEST.source/file-perms-644' info: Copied file '/tmp/TEST.source/subdir/subdir-file' to '/tmp/TEST.destination/subdir/subfile.cfnew' (permissions preserved) info: Moved '/tmp/TEST.destination/subdir/subfile.cfnew' to '/tmp/TEST.destination/subdir/subfile' info: Regular file '/tmp/TEST.destination/subdir/subfile' had permissions 0600, changed it to 0644 info: Updated file '/tmp/TEST.destination/subdir/subfile' from 'localhost:/tmp/TEST.source/subdir/subdir-file' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml07.cf0000644000000000000000000000172715010704253026042 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { vars: "xml" string => "text content"; files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath($(xml)), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_delete_text("text content", "//c"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_delete_text(match, xpath) { delete_text: "$(match)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/copy_from01.cf0000644000000000000000000000166415010704253026224 0ustar00rootroot00000000000000body file control { hpux.ia64:: inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; !(hpux.ia64):: inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testroot)/TEST.source" depth_search => recurse("inf"), perms => system_owned("0644"), copy_from => example("$(this.promise_dirname)/test_files"); } bundle agent main { files: "$(G.testroot)/TEST.destination/subdir/." create => "true"; "$(G.testroot)/TEST.destination/file-perms-644" copy_from => example("$(G.testroot)/TEST.source/file-perms-644"); "$(G.testroot)/TEST.destination/subdir/subfile" copy_from => example("$(G.testroot)/TEST.source/subdir/subdir-file"); } body copy_from example(from) { source => "$(from)"; compare => "digest"; preserve => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line03.cf0000644000000000000000000000135315010704253026160 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => insert_lines("amazing!"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line03.cf.expected0000644000000000000000000000026615010704253027762 0ustar00rootroot00000000000000 info: Inserted the promised line 'amazing!' into '/tmp/TEST.cfengine' after locator info: insert_lines promise 'amazing!' repaired info: Edited file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line01.cf0000644000000000000000000000137415010704253026161 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => set_colon_field("me","6","/my/new/shell"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/changes01.cf.expected0000644000000000000000000000027515010704253027434 0ustar00rootroot00000000000000 info: Stored md5 hash for '/tmp/TEST.cfengine' (MD5=d41d8cd98f00b204e9800998ecf8427e) info: Stored sha1 hash for '/tmp/TEST.cfengine' (SHA=da39a3ee5e6b4b0d3255bfef95601890afd80709) cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/insert_lines_noop.cf.expected0000644000000000000000000000000015010704253031376 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/rename_newname.cf0000644000000000000000000000067315010704253027046 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; "$(G.testroot)/TEST.foobar" delete => init_delete; } bundle agent main { files: "$(G.testfile)" rename => newname; } body rename newname { newname => "TEST.foobar"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line01.cf.expected0000644000000000000000000000024015010704253027750 0ustar00rootroot00000000000000 info: Set field sub-value '/my/new/shell' in '/tmp/TEST.cfengine' info: fields_edit promise 'me:.*' repaired info: Edited file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/delete.cf.expected0000644000000000000000000000005415010704253027120 0ustar00rootroot00000000000000 info: Deleted file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/delete.cf0000644000000000000000000000051315010704253025320 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" delete => init_delete; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/copy_from02.cf0000644000000000000000000000165015010704253026220 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testroot)/TEST.source" depth_search => recurse("inf"), copy_from => example("$(this.promise_dirname)/test_files"); } bundle agent main { files: "$(G.testroot)/TEST.destination/subdir/." create => "true"; "$(G.testroot)/TEST.destination/file-perms-644" copy_from => example2("$(G.testroot)/TEST.source/file-perms-644"); "$(G.testroot)/TEST.destination/subdir/subfile" copy_from => example2("$(G.testroot)/TEST.source/subdir/subdir-file"); } body copy_from example(from) { source => "$(from)"; compare => "digest"; preserve => "true"; } body copy_from example2(from) { source => "$(from)"; compare => "mtime"; check_root => "true"; copy_backup => "timestamp"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml06.cf0000644000000000000000000000165115010704253026035 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_delete_attribute("foo", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_delete_attribute(attr, xpath) { delete_attribute: "$(attr)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/transformer.cf0000644000000000000000000000064115010704253026422 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true", edit_line => insert_lines(" zebra apple dog cat banana "); } bundle agent main { files: "$(G.testfile)" transformer => "$(G.gzip) $(G.testfile)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/insert_lines_noop.cf0000644000000000000000000000163615010704253027616 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { meta: "description" -> { "CFE-3708" } string => "empty+insert should not cause any changes being logged because the file is already as expected"; vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines("this one line"), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => insert_lines("this one line"), create => "true", edit_defaults => empty; } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml09.cf.expected0000644000000000000000000000031515010704253027634 0ustar00rootroot00000000000000 info: Deleted tree 'text content' at XPath '//b' in XML document '/tmp/TEST.cfengine' info: delete_tree promise 'text content' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/changes02.cf0000644000000000000000000000053315010704253025632 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" edit_line => insert_lines("foobar"); } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml08.cf.expected0000644000000000000000000000027515010704253027640 0ustar00rootroot00000000000000 info: Inserted text 'Tuesday' at XPath '//Root' in the XML document '/tmp/TEST.cfengine' info: insert_text promise 'Tuesday' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/copy_from03.cf0000644000000000000000000000224415010704253026221 0ustar00rootroot00000000000000body file control { hpux.ia64:: inputs => { "$(sys.policy_entry_dirname)/../common_soft_fail.cf.sub" }; !(hpux.ia64):: inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testroot)/TEST.source" depth_search => recurse("inf"), perms => system_owned("0644"), copy_from => example("$(this.promise_dirname)/test_files"); } bundle agent main { files: "$(G.testroot)/TEST.destination/subdir/purgeme" create => "true", handle => "step_one"; "$(G.testroot)/TEST.destination/file-perms-644" copy_from => example("$(G.testroot)/TEST.source/file-perms-644"); "$(G.testroot)/TEST.destination/subdir/." depends_on => { "step_one" }, depth_search => recurse("inf"), move_obstructions => "true", copy_from => example3("$(G.testroot)/TEST.source/subdir/."); } body copy_from example(from) { source => "$(from)"; compare => "digest"; preserve => "true"; } body copy_from example3(from) { source => "$(from)"; linkcopy_patterns => { ".*644" }; purge => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line02.cf.expected0000644000000000000000000000024115010704253027752 0ustar00rootroot00000000000000 info: Deleted the promised line 1 'foo 1' from /tmp/TEST.cfengine info: delete_lines promise 'foo 1' repaired info: Edited file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml07.cf.expected0000644000000000000000000000030315010704253027627 0ustar00rootroot00000000000000 info: Deleted text 'text content' at XPath '//c' in the XML document '/tmp/TEST.cfengine' info: delete_text promise 'text content' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/perms.cf0000644000000000000000000000155515010704253025213 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } body link_from link_info(source) { source => "$(source)"; link_type => "symlink"; } bundle agent setup { files: "$(G.testdir)/foo" create => "true", comment => "A regular file"; "$(G.testdir)/bar" create => "true", comment => "A regular file symlink target"; "$(G.testdir)/baz" link_from => link_info("$(G.testdir)/bar"), comment => "A symbolic link to a regular file"; "$(G.testdir)/foobar/." create => "true", comment => "A directory"; } bundle agent main { files: "$(G.testdir)/foo" perms => m(777); "$(G.testdir)/baz" perms => m(777); "$(G.testdir)/foobar" perms => m(777); } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml05.cf.expected0000644000000000000000000000033115010704253027626 0ustar00rootroot00000000000000 info: Set attribute with name 'my_attr' to value 'my_value' at XPath '//Root' in XML document '/tmp/TEST.cfengine' info: set_attribute promise 'my_attr' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/create.cf0000644000000000000000000000037315010704253025325 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent main { files: "$(G.testfile)" create => "true"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/perms.cf.expected0000644000000000000000000000027015010704253027004 0ustar00rootroot00000000000000 info: Regular file '/tmp/TESTDIR.cfengine/foo' had permissions 0600, changed it to 0777 info: Directory '/tmp/TESTDIR.cfengine/foobar' had permissions 0700, changed it to 0777 cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line05.cf0000644000000000000000000000152015010704253026156 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_line => insert_lines(" foo 1 bar 2 baz 3 me:x:1001:1001::/home/me:/bin/sh "), create => "true"; } bundle agent main { files: "$(G.testfile)" template_method => "inline_mustache", edit_template_string => "Hi {{{username}}}!", template_data => '{ "username": "agent" }'; } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line05.cf.expected0000644000000000000000000000012415010704253027755 0ustar00rootroot00000000000000 info: Updated rendering of '/tmp/TEST.cfengine' from mustache template 'inline' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml04.cf0000644000000000000000000000162015010704253026027 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" edit_xml => xml_insert_tree_nopath(""), create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => xml_set_value("foobar", "//Root"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml xml_insert_tree_nopath(treestring) { insert_tree: '$(treestring)'; } bundle edit_xml xml_set_value(value, xpath) { set_text: "$(value)" select_xpath => "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/rename_rotate.cf0000644000000000000000000000056215010704253026707 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" rename => rotate; } body rename rotate { rotate => "4"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml06.cf.expected0000644000000000000000000000027615010704253027637 0ustar00rootroot00000000000000 info: Deleted attribute 'foo' at XPath '//Root' in the XML document '/tmp/TEST.cfengine' info: delete_attribute promise 'foo' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/rename_rotate.cf.expected0000644000000000000000000000015415010704253030504 0ustar00rootroot00000000000000 info: Rotated file '/tmp/TEST.cfengine' in 4 fifo info: Rotated file '/tmp/TEST.cfengine' in 4 fifo cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/create.cf.expected0000644000000000000000000000006715010704253027125 0ustar00rootroot00000000000000 info: Created file '/tmp/TEST.cfengine', mode 0600 cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml01.cf0000644000000000000000000000134215010704253026025 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } bundle agent setup { files: "$(G.testfile)" create => "true"; } bundle agent main { files: "$(G.testfile)" edit_xml => build_xpath("/Server/Service/Engine/Host"); } bundle agent teardown { reports: "Edited file has contents: " printfile => my_cat( $(G.testfile) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_xml build_xpath(xpath) { build_xpath: "$(xpath)"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/copy_from02.cf.expected0000644000000000000000000000134615010704253030022 0ustar00rootroot00000000000000 info: Created directory '/tmp/TEST.destination/subdir/.', mode 0700 info: Copied file '/tmp/TEST.source/file-perms-644' to '/tmp/TEST.destination/file-perms-644.cfnew' (mode '600') info: Moved '/tmp/TEST.destination/file-perms-644.cfnew' to '/tmp/TEST.destination/file-perms-644' info: Updated file '/tmp/TEST.destination/file-perms-644' from 'localhost:/tmp/TEST.source/file-perms-644' info: Copied file '/tmp/TEST.source/subdir/subdir-file' to '/tmp/TEST.destination/subdir/subfile.cfnew' (mode '600') info: Moved '/tmp/TEST.destination/subdir/subfile.cfnew' to '/tmp/TEST.destination/subdir/subfile' info: Updated file '/tmp/TEST.destination/subdir/subfile' from 'localhost:/tmp/TEST.source/subdir/subdir-file' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/delete-dir.cf.expected0000644000000000000000000000010215010704253027666 0ustar00rootroot00000000000000 info: Deleted directory '/tmp/TESTDIR.cfengine/sub-directory' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_line04.cf.expected0000644000000000000000000000022615010704253027757 0ustar00rootroot00000000000000 info: Replaced pattern 'bar' in '/tmp/TEST.cfengine' info: replace_patterns promise 'bar' repaired info: Edited file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/copy_from03.cf.expected0000644000000000000000000000201215010704253030012 0ustar00rootroot00000000000000 info: Created directory for '/tmp/TEST.destination/subdir/purgeme' info: Created file '/tmp/TEST.destination/subdir/purgeme', mode 0600 info: Copied file '/tmp/TEST.source/file-perms-644' to '/tmp/TEST.destination/file-perms-644.cfnew' (permissions preserved) info: Moved '/tmp/TEST.destination/file-perms-644.cfnew' to '/tmp/TEST.destination/file-perms-644' info: Regular file '/tmp/TEST.destination/file-perms-644' had permissions 0600, changed it to 0644 info: Updated file '/tmp/TEST.destination/file-perms-644' from 'localhost:/tmp/TEST.source/file-perms-644' info: Copied file '/tmp/TEST.source/subdir/./subdir-file' to '/tmp/TEST.destination/subdir/./subdir-file.cfnew' (mode '600') info: Moved '/tmp/TEST.destination/subdir/./subdir-file.cfnew' to '/tmp/TEST.destination/subdir/./subdir-file' info: Updated file '/tmp/TEST.destination/subdir/./subdir-file' from 'localhost:/tmp/TEST.source/subdir/./subdir-file' info: Purged '/tmp/TEST.destination/subdir/./purgeme' copy dest directory cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/changes02.cf.expected0000644000000000000000000000026215010704253027431 0ustar00rootroot00000000000000 info: Inserted the promised line 'foobar' into '/tmp/TEST.cfengine' after locator info: insert_lines promise 'foobar' repaired info: Edited file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/01_files/edit_xml04.cf.expected0000644000000000000000000000025715010704253027634 0ustar00rootroot00000000000000 info: Set text 'foobar' at XPath '//Root' in XML document '/tmp/TEST.cfengine' info: set_text promise 'foobar' repaired info: Edited xml file '/tmp/TEST.cfengine' cfengine-3.24.2/tests/acceptance/28_inform_testing/README.md0000644000000000000000000000227615010704253023431 0ustar00rootroot00000000000000==================== Inform Logging Tests ==================== These tests turn the model upside down a bit to make things easier. Two bits are needed at the top of each .cf test file: ```cf3 body file control { inputs => { "$(sys.policy_entry_dirname)/../common.cf.sub" }; } bundle common testcase { vars: "filename" string => "$(this.promise_filename)"; } ``` This is the boiler-plate to drive the tests. The framework automatically cleans up `$(G.testfile)` and `$(G.testdir)`. For the simplest case you can just include a `main` bundle to do the operation you want to perform. ```cf3 bundle agent main { files: "$(G.testfile)" create => "true"; } ``` And when the test is run it will generate a `.actual` and check it against a `.expected`. There are temporary files created during the test involving the results. If the test fails, these files will be kept, if the test passes, they will be removed. The little framework also supports a `setup` and `teardown` optional bundle for things you might need in that regard. Next to common.cf.sub there is a shell script called accept-actual.sh which will mv the .actual files to .expected and add them via `git`. cfengine-3.24.2/tests/acceptance/28_inform_testing/common_soft_fail.cf.sub0000644000000000000000000000457615010704253026577 0ustar00rootroot00000000000000bundle common inform_tests { vars: "inputs" slist => { "$(this.promise_dirname)/../default.cf.sub" }; } body common control { inputs => { "@(inform_tests.inputs)" }; version => "1.0"; # RUNDIRECT is used later to only run the actual test code with cf-agent !RUNDIRECT:: bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { classes: "expected_file_exists" expression => fileexists("$(testcase.filename).expected"), scope => "namespace"; "has_setup" expression => isgreaterthan(length(bundlesmatching("default:setup")), "0"), scope => "namespace"; "has_teardown" expression => isgreaterthan(length(bundlesmatching("default:teardown")), "0"), scope => "namespace"; files: "$(G.testfile)" delete => init_delete, handle => "file_deleted"; "$(G.testdir)" delete => init_delete, handle => "dir_deleted"; methods: has_setup:: "setup" depends_on => { "dir_deleted", "file_deleted" }; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "any", meta => { "ENT-3787" }; vars: "cf_agent" string => ifelse(isvariable("sys.cf_agent"), "$(sys.cf_agent)", "/var/cfengine/bin/cf-agent"); commands: # NOTE: easy debug, if you change `>` to `|tee` in all below then you can see results in the execution log "$(cf_agent) -D RUNDIRECT -KIf $(testcase.filename) > $(testcase.filename).log" contain => useshell; "$(G.sed) 's,$(G.testroot),/tmp,g' $(testcase.filename).log > $(testcase.filename).actual" contain => useshell; } body contain useshell { useshell => "useshell"; } ####################################################### bundle agent check { methods: has_teardown:: "teardown"; # optional tear down step contained in the test.cf file expected_file_exists:: "any" usebundle => dcs_if_diff("$(testcase.filename).actual", "$(testcase.filename).expected", "ok", "not_ok"); files: # delete if not ok, since we expect these tests to fail !ok:: "$(testcase.filename).(log|sorted|actual)" delete => tidy; reports: ok:: "$(testcase.filename) Pass"; !ok:: "$(testcase.filename) FAIL"; } cfengine-3.24.2/tests/acceptance/28_inform_testing/accept-actual.sh0000755000000000000000000000012515010704253025206 0ustar00rootroot00000000000000for f in *.actual; do mv $f $(basename $f .actual).expected; done git add *.expected cfengine-3.24.2/tests/acceptance/28_inform_testing/common.cf.sub0000644000000000000000000000514315010704253024540 0ustar00rootroot00000000000000bundle common inform_tests { vars: "inputs" slist => { "$(this.promise_dirname)/../default.cf.sub" }; } body common control { inputs => { "@(inform_tests.inputs)" }; version => "1.0"; # RUNDIRECT is used later to only run the actual test code with cf-agent !RUNDIRECT:: bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { classes: "expected_file_exists" expression => fileexists("$(testcase.filename).expected"), scope => "namespace"; "has_setup" expression => isgreaterthan(length(bundlesmatching("default:setup")), "0"), scope => "namespace"; "has_teardown" expression => isgreaterthan(length(bundlesmatching("default:teardown")), "0"), scope => "namespace"; files: "$(G.testfile)" delete => init_delete, handle => "file_deleted"; "$(G.testdir)" delete => init_delete, handle => "dir_deleted"; methods: has_setup:: "setup" depends_on => { "dir_deleted", "file_deleted" }; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10406" }, if => not( strcmp( "insert_lines_noop.cf", "$(sys.policy_entry_basename)" ) ); vars: "cf_agent" string => ifelse(isvariable("sys.cf_agent"), "$(sys.cf_agent)", "/var/cfengine/bin/cf-agent"); "filter_list" slist => { " -e '/filestat bailing/d' ", " -e s,$(G.testroot),/tmp,g ", " -e s,/usr/local/bin/gzip,/bin/gzip, "}; "filters" string => join("", filter_list); commands: # NOTE: easy debug, if you change `>` to `|tee` in all below then you can see results in the execution log "$(cf_agent) -D RUNDIRECT -KIf $(testcase.filename) > $(testcase.filename).log" contain => useshell; "$(G.sed) $(filters) $(testcase.filename).log > $(testcase.filename).actual" contain => useshell; } body contain useshell { useshell => "useshell"; } ####################################################### bundle agent check { methods: has_teardown:: "teardown"; # optional tear down step contained in the test.cf file expected_file_exists:: "any" usebundle => dcs_if_diff("$(testcase.filename).actual", "$(testcase.filename).expected", "ok", "not_ok"); files: ok:: "$(testcase.filename).(log|actual)" delete => tidy; reports: ok:: "$(testcase.filename) Pass"; !ok:: "$(testcase.filename) FAIL"; } cfengine-3.24.2/tests/acceptance/25_cf-execd/0000755000000000000000000000000015010704316020567 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/25_cf-execd/mail_include_filter.cf0000644000000000000000000000240615010704253025075 0ustar00rootroot00000000000000# Tests that include mail filter causes only matched lines to be mailed by # cf-execd. body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent init { vars: "reports" slist => { "CorrectString1", "CorrectString2", "WrongString1", "WrongString2", }; "includes" slist => { "R: CorrectString1", ".*CorrectString[2]" }; "excludes" slist => { }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { vars: "expected" slist => { "CorrectString1", "CorrectString2" }; "not_expected" slist => { "WrongString1", "WrongString2" }; methods: "any" usebundle => check_cf_execd_mail(@(expected), @(not_expected), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/mail_1st_run_empty_new_log.cf0000644000000000000000000000220515010704253026425 0ustar00rootroot00000000000000# Tests that no mail is sent by cf-execd on the first run (hence the old log # doesn't exist) and if the new log is empty. body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promiser_filename)) }; } bundle agent init { vars: "reports" slist => { }; # No mail is expected at all, since everything is filtered. "expected" slist => { }; "unexpected" slist => { ".+" }; "includes" slist => { }; "excludes" slist => { }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { methods: "any" usebundle => check_cf_execd_mail(@(init.expected), @(init.unexpected), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/Makefile.am0000644000000000000000000000273115010704253022626 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # AM_CPPFLAGS = \ $(OPENSSL_CPPFLAGS) \ -I$(srcdir)/../../../libpromises \ -I$(srcdir)/../../../libntech/libutils \ -I$(srcdir)/../../../libcfnet \ -I$(srcdir)/../../../libenv \ -I$(srcdir)/../../../cf-execd \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(PCRE2_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) if !NT noinst_PROGRAMS = cf-execd-test cf_execd_test_SOURCES = cf-execd-rpl-functions.c cf_execd_test_LDADD = ../../../cf-execd/libcf-execd-test.la endif cfengine-3.24.2/tests/acceptance/25_cf-execd/mailfilter_1st_run_everything_filtered.cf0000644000000000000000000000246515010704253031035 0ustar00rootroot00000000000000# Tests that no mail is sent by cf-execd if everything is filtered on the first # run (hence the old log doesn't exist). body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promiser_filename)) }; } bundle agent init { vars: "reports" slist => { "WrongString1", "WrongString2", "WrongString3", }; # No mail is expected at all, since everything is filtered. "expected" slist => { }; "unexpected" slist => { ".+" }; "includes" slist => { }; "excludes" slist => { ".*WrongString.*" }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { methods: "any" usebundle => check_cf_execd_mail(@(init.expected), @(init.unexpected), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/.deps/0000755000000000000000000000000015010704316021600 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/25_cf-execd/.deps/cf-execd-rpl-functions.Po0000644000000000000000000000001015010704316026346 0ustar00rootroot00000000000000# dummy cfengine-3.24.2/tests/acceptance/25_cf-execd/.gitignore0000644000000000000000000000001715010704253022555 0ustar00rootroot00000000000000/cf-execd-test cfengine-3.24.2/tests/acceptance/25_cf-execd/mailfilter_common.cf.sub0000644000000000000000000001216715010704253025400 0ustar00rootroot00000000000000# Common stuff for mailfilter tests. bundle agent prepare_mailfilter_test(reports, includes, excludes) { vars: "data_keys[reports]" slist => { @(reports) }; "data_keys[includes]" slist => { @(includes) }; "data_keys[excludes]" slist => { @(excludes) }; "data" data => mergedata("data_keys"); "data_print" string => format("%S", "data"); # promises.cf files: "$(sys.inputdir)/promises.cf" create => "true", edit_template => "$(this.promise_dirname)/mailfilter_promises_cf.template", template_method => "mustache", template_data => @(data); # cf-execd.cf files: "$(sys.inputdir)/controls/cf_execd.cf" create => "true", edit_template => "$(this.promise_dirname)/mailfilter_cf_execd_control.template", template_method => "mustache", template_data => @(data); # Keys. methods: "generate_key"; } bundle agent run_cf_execd(wanted, unwanted) { vars: "cmd" string => "$(this.promise_dirname)/cf-execd-test --once --with-runagent-socket no"; commands: "$(cmd) >> $(G.testfile).output" contain => in_shell; methods: "any" usebundle => store_expected_regex_from_run(@(wanted), @(unwanted)); } bundle agent store_expected_regex_from_run(wanted, unwanted) { classes: "wanted_not_empty" expression => some(".*", "wanted"); "unwanted_not_empty" expression => some(".*", "unwanted"); vars: !wanted_not_empty:: "wanted_regex" string => ""; wanted_not_empty:: # Notice that "Date" is optionally matched, due to it being ifdef'ed on # some platforms. "wanted_regex" string => concat( '220 test\.com\r HELO [^\r\n]+\r 250 Hello test\.com, pleased to meet you\r MAIL FROM: \r 250 from@test\.com\.\.\. Sender ok\r RCPT TO: \r 250 to@test\.com\.\.\. Recipient ok\r DATA\r 354 Enter mail, end with "\." on a line by itself\r Subject: \[[^]]+\]\r X-CFEngine: vfqhost="[^"]+";ip-addresses="[^"]+";policyhub="[^"]*";pkhash="MD5=617eb383deffef843ea856b129d0a423"\r (Date: [^\r\n]+\r )?From: from@test\.com\r To: to@test\.com\r \r R: ' , join( '\r R: ', "wanted"), '\r \.\r 250 Message accepted for delivery\r QUIT\r( 221 test\.com closing connection\r)*'); # ^ Note that this last string is optionally matched. The reason is that # cf-execd may finish everything and quit before the mock thread has time to # finish writing that string. It does not mean there's an error. # Moreover, sometimes it might be printed more than once, and since this # regexp is treated as ancored, we're prepared to face as many of repetitions # as necessary. unwanted_not_empty:: "unwanted_regex" string => concat(".*(", join("|", "unwanted"), ").*"); files: "$(G.testfile).wanted" create => "true"; wanted_not_empty:: "$(G.testfile).wanted" edit_line => append_regex($(wanted_regex)); any:: "$(G.testfile).unwanted" create => "true"; unwanted_not_empty:: "$(G.testfile).unwanted" edit_line => append_regex($(unwanted_regex)); } bundle edit_line append_regex(regex) { insert_lines: "$(regex)" insert_type => "preserve_all_lines"; } bundle agent compare_cf_execd_mail(test) { classes: "test_not_empty" expression => isvariable("test"); "unwanted_content" not => strcmp(filestat("$(G.testfile).unwanted", "size"), "0"); vars: test_not_empty:: "cmd" string => "$(G.cat) $(G.testfile).output"; "wanted_regex" string => readfile("$(G.testfile).wanted", 0); "unwanted_regex_list" slist => readstringlist("$(G.testfile).unwanted", "", "\n", "1000000", "1000000"); "unwanted_regex" string => join("|", "unwanted_regex_list"); "output" string => readfile("$(G.testfile).output", 0); classes: "wanted_ok" expression => regcmp($(wanted_regex), $(output)); "unwanted_ok" not => regcmp($(unwanted_regex), $(output)); "ok" and => { "wanted_ok", "unwanted_ok" }; reports: "unwanted_regex_list = $(unwanted_regex_list)"; "wanted_regex = '$(wanted_regex)'"; "unwanted_regex = '$(unwanted_regex)'"; "output = '$(output)'"; wanted_ok:: "wanted_ok is set"; !wanted_ok:: "wanted_ok is NOT set"; unwanted_ok:: "unwanted_ok is set"; !unwanted_ok:: "unwanted_ok is NOT set"; reports: ok:: "$(test) Pass"; !ok:: "$(test) FAIL"; } bundle agent check_cf_execd_mail(wanted_arg, unwanted_arg, test) { vars: # Workaround: The parser doesn't see bundle arguments as truly being in # the scope of the bundle, and therefore they can't be passed on into # other bundles. Therefore we make a copy. "wanted" slist => { @(wanted_arg) }; "unwanted" slist => { @(unwanted_arg) }; methods: "any" usebundle => run_cf_execd(@(wanted), @(unwanted)); "any" usebundle => compare_cf_execd_mail($(test)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/timed/0000755000000000000000000000000015010704253021671 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/25_cf-execd/timed/mailfilter_repeated_runs.cf0000644000000000000000000001056215010704253027257 0ustar00rootroot00000000000000# Tests that the correct content is sent by cf-execd after several consecutive # cf-agent runs. body common control { inputs => { "../../default.cf.sub", "../mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promiser_filename)) }; } bundle agent init { vars: # Positions of WrongString inside the report should not matter, since it # is filtered out. "reports1" slist => { "CorrectString1", "CorrectString2", "WrongString1", "WrongString2", "WrongString3", }; "expected1" slist => { "CorrectString1", "CorrectString2", }; "reports2" slist => { "WrongString1", "CorrectString1", "WrongString2", "CorrectString2", "WrongString3", }; "expected2" slist => { # Nothing expected, since it is identical to # previous run. }; "reports3" slist => { }; "expected3" slist => { # Nothing expected, because the log is empty. }; "reports4" slist => { "WrongString1", "WrongString2", "WrongString3", }; "expected4" slist => { # Nothing expected, because everything is filtered. }; "reports5" slist => { "WrongString2", "WrongString1", "CorrectString2", "CorrectString1", "WrongString3", }; "expected5" slist => { "CorrectString2", "CorrectString1", }; "unexpected" slist => { ".*WrongString.*" }; "includes" slist => { "R: CorrectString1", ".*CorrectString[2]", "R: WrongString1", ".*WrongString[2]" }; "excludes" slist => { "R: WrongString1", ".*WrongString[2]", # Tests anchoring. "orrectString1" }; methods: test_pass_1:: "any" usebundle => prepare_mailfilter_test(@(reports1), @(includes), @(excludes)); "any" usebundle => run_cf_execd(@(expected1), @(unexpected)); test_pass_2:: "any" usebundle => prepare_mailfilter_test(@(reports2), @(includes), @(excludes)); "any" usebundle => run_cf_execd(@(expected2), @(unexpected)); test_pass_3:: "any" usebundle => prepare_mailfilter_test(@(reports3), @(includes), @(excludes)); "any" usebundle => run_cf_execd(@(expected3), @(unexpected)); test_pass_4:: "any" usebundle => prepare_mailfilter_test(@(reports4), @(includes), @(excludes)); "any" usebundle => run_cf_execd(@(expected4), @(unexpected)); test_pass_5:: "any" usebundle => prepare_mailfilter_test(@(reports5), @(includes), @(excludes)); "any" usebundle => run_cf_execd(@(expected5), @(unexpected)); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { methods: test_pass_1|test_pass_2|test_pass_3|test_pass_4:: "any" usebundle => dcs_wait($(this.promise_filename), 1); test_pass_5:: "any" usebundle => compare_cf_execd_mail($(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/mail_empty_old_and_new_log.cf0000644000000000000000000000242515010704253026436 0ustar00rootroot00000000000000# Tests that no mail is sent by cf-execd if the old and new logs are empty. body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promiser_filename)) }; } bundle agent init { vars: "reports" slist => { }; # No mail is expected at all, since everything is filtered. "expected" slist => { }; "unexpected" slist => { ".+" }; "includes" slist => { }; "excludes" slist => { }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); files: "$(sys.workdir)/outputs/old.log" create => "true"; "$(sys.workdir)/outputs/previous" link_from => linkfrom("$(sys.workdir)/outputs/old.log", "symlink"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { methods: "any" usebundle => check_cf_execd_mail(@(init.expected), @(init.unexpected), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/slow/0000755000000000000000000000000015010704253021553 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/25_cf-execd/slow/dies_in_time.cf0000644000000000000000000000764315010704253024527 0ustar00rootroot00000000000000# ENT-3147, zd#3157 # Ensure that cf-execd dies within 3 seconds after being signalled. body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { vars: "exec_command_script" string => "#!/bin/sh -x sleep 10 CF_EXECD_PID=`cat $(sys.piddir)/cf-execd.pid` # Send TERM kill -15 $CF_EXECD_PID # Give the process 2 (plus 1 just to be sure) seconds to die gracefully sleep 3 # Is it dead? if kill -0 $CF_EXECD_PID then echo ALIVE > $(G.testdir)/cf_execd.status else echo DEAD > $(G.testdir)/cf_execd.status fi # Touch a file to trigger the policy to move on and check the cf_execd.status file touch $(G.testdir)/EXECUTOR_WAS_SIGNALLED # Keep this child running to test that cf-execd still dies instantly despite that sleep 10 # Clean up that useless executor if TERM failed # NOTE: using `ps` command fails under fakeroot! if kill -0 $CF_EXECD_PID then echo 'cf-execd is still alive, killing it with FIRE!!!' kill -9 $CF_EXECD_PID exit 1 fi # Verify that this shell script reaches completion # despite parent cf-execd being dead echo DONE > $(G.testdir)/exec_command.status "; files: "$(G.testdir)/exec_command.sh" create => "true", perms => m(777), edit_line => insert_lines("$(exec_command_script)"); methods: "any" usebundle => dcs_fini("$(sys.piddir)/cf-execd.pid"); "any" usebundle => dcs_fini("$(G.testdir)/EXECUTOR_WAS_SIGNALLED"); "any" usebundle => dcs_fini("$(G.testdir)/cf_execd.status"); "any" usebundle => dcs_fini("$(G.testdir)/exec_command.status"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; commands: "$(sys.cf_execd) -f $(this.promise_dirname)/kill_myself.execd.srv" classes => if_repaired("executor_started"); executor_started:: # Make sure it started fully "$(G.sleep) 5" classes => if_repaired("waited"); executor_started.waited:: # Ensure executor PID is up "kill -0 `cat $(sys.piddir)/cf-execd.pid`" contain => in_shell, classes => if_repaired("executor_started_ok"); executor_started_ok:: # Wait until cf-execd is signalled by its own child; # more than 60s which is CFPULSETIME " i=0 while [ $i -lt 120 ] do i=`expr $i + 1` echo $i sleep 1 if test -f $(G.testdir)/EXECUTOR_WAS_SIGNALLED then exit 0 fi done exit 1 # Executor was never signalled! " contain => in_shell, classes => if_repaired("executor_was_signalled"); executor_was_signalled:: # Wait again until executor runs the signal handler and exits gracefully "$(G.sleep) 3" classes => if_repaired("waited_for_cleanup"); waited_for_cleanup:: # and another 10s for exec_command.sh script to exit "$(G.sleep) 10" classes => if_repaired("script_should_have_exited"); classes: "test_bundle_done" expression => "script_should_have_exited", scope => "namespace"; reports: !executor_was_signalled:: "$(this.promise_filename) FAIL"; } # PASS only if cf_execd.status is DEAD and exec_command.status is DONE bundle agent check { classes: test_bundle_done:: "executor_is_dead" expression => returnszero("$(G.grep) DEAD $(G.testdir)/cf_execd.status", "useshell"); "exec_command_finished" expression => returnszero("$(G.grep) DONE $(G.testdir)/exec_command.status", "useshell"); methods: "" usebundle => dcs_passif_expected("executor_is_dead,exec_command_finished","", "$(this.promise_filename)"), inherit => "true"; reports: !executor_is_dead.DEBUG:: "FAIL: cf-execd did not die within 3s after TERM signal!"; } cfengine-3.24.2/tests/acceptance/25_cf-execd/slow/kill_myself.execd.srv0000644000000000000000000000066015010704253025712 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } body executor control { # Every 1 min schedule => { "any" }; # redirect all file descriptors so that the shell script # stays alive after cf-execd is killed exec_command => "$(G.testdir)/exec_command.sh > $(G.testdir)/exec_command.sh.log 2>&1 &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @NT_FALSE@noinst_PROGRAMS = cf-execd-test$(EXEEXT) subdir = tests/acceptance/25_cf-execd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am__cf_execd_test_SOURCES_DIST = cf-execd-rpl-functions.c @NT_FALSE@am_cf_execd_test_OBJECTS = cf-execd-rpl-functions.$(OBJEXT) cf_execd_test_OBJECTS = $(am_cf_execd_test_OBJECTS) @NT_FALSE@cf_execd_test_DEPENDENCIES = \ @NT_FALSE@ ../../../cf-execd/libcf-execd-test.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cf_execd_test_SOURCES) DIST_SOURCES = $(am__cf_execd_test_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ AM_CPPFLAGS = \ $(OPENSSL_CPPFLAGS) \ -I$(srcdir)/../../../libpromises \ -I$(srcdir)/../../../libntech/libutils \ -I$(srcdir)/../../../libcfnet \ -I$(srcdir)/../../../libenv \ -I$(srcdir)/../../../cf-execd \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(PCRE2_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) @NT_FALSE@cf_execd_test_SOURCES = cf-execd-rpl-functions.c @NT_FALSE@cf_execd_test_LDADD = ../../../cf-execd/libcf-execd-test.la all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/acceptance/25_cf-execd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/acceptance/25_cf-execd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-execd-test$(EXEEXT): $(cf_execd_test_OBJECTS) $(cf_execd_test_DEPENDENCIES) $(EXTRA_cf_execd_test_DEPENDENCIES) @rm -f cf-execd-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_execd_test_OBJECTS) $(cf_execd_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-execd-rpl-functions.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/acceptance/25_cf-execd/mailfilter_cf_execd_control.template0000644000000000000000000000060015010704253030030 0ustar00rootroot00000000000000body executor control { mailto => "to@test.com"; mailfrom => "from@test.com"; smtpserver => "dummy"; mailfilter_include => { {{#includes}} "{{.}}", {{/includes}} }; mailfilter_exclude => { {{#excludes}} "{{.}}", {{/excludes}} }; exec_command => "$(sys.cf_agent) -K"; } cfengine-3.24.2/tests/acceptance/25_cf-execd/mail_no_filter.cf0000644000000000000000000000202015010704253024056 0ustar00rootroot00000000000000# Tests that without mail filters, everything is mailed by cf-execd. body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent init { vars: "reports" slist => { "CorrectString1", "CorrectString2", }; "includes" slist => { }; "excludes" slist => { }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { vars: "empty_list" slist => { }; methods: "any" usebundle => check_cf_execd_mail(@(init.reports), @(empty_list), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/Makefile0000644000000000000000000005334015010704315022233 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # tests/acceptance/25_cf-execd/Makefile. Generated from Makefile.in by configure. # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/cfengine pkgincludedir = $(includedir)/cfengine pkglibdir = $(libdir)/cfengine pkglibexecdir = $(libexecdir)/cfengine am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = x86_64-pc-linux-gnu host_triplet = x86_64-pc-linux-gnu target_triplet = x86_64-pc-linux-gnu noinst_PROGRAMS = cf-execd-test$(EXEEXT) subdir = tests/acceptance/25_cf-execd ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am__cf_execd_test_SOURCES_DIST = cf-execd-rpl-functions.c am_cf_execd_test_OBJECTS = cf-execd-rpl-functions.$(OBJEXT) cf_execd_test_OBJECTS = $(am_cf_execd_test_OBJECTS) cf_execd_test_DEPENDENCIES = \ ../../../cf-execd/libcf-execd-test.la AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_$(V)) am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_$(V)) am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I. -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_$(V)) am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_$(V)) am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(cf_execd_test_SOURCES) DIST_SOURCES = $(am__cf_execd_test_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = ${SHELL} /home/jenkins/workspace/bootstrap-pr/core/missing aclocal-1.15 AMTAR = $${TAR-tar} AM_DEFAULT_VERBOSITY = 0 AR = ar AUTOCONF = ${SHELL} /home/jenkins/workspace/bootstrap-pr/core/missing autoconf AUTOHEADER = ${SHELL} /home/jenkins/workspace/bootstrap-pr/core/missing autoheader AUTOMAKE = ${SHELL} /home/jenkins/workspace/bootstrap-pr/core/missing automake-1.15 AWK = mawk CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -pthread -g -O2 -g -Wall -Wno-pointer-sign -Werror=implicit-function-declaration -Wunused-parameter -O2 -DNDEBUG CORE_CFLAGS = -pthread -g -O2 -g -Wall -Wno-pointer-sign -Werror=implicit-function-declaration -Wunused-parameter -O2 -DNDEBUG CORE_CPPFLAGS = -Icheck/include/libxml2 -std=gnu99 -I./libcfecompat CORE_LDFLAGS = -R/lib -L/var/cfengine/lib -Wl,-R/var/cfengine/lib CORE_LIBS = -llmdb -lpcre2-8 -lssl -lcrypto -ldl -lrt -lm CPP = gcc -E CPPFLAGS = -std=gnu99 CYGPATH_W = echo DEFS = -DHAVE_CONFIG_H DEPDIR = .deps DLLTOOL = false DSYMUTIL = DUMPBIN = ECHO_C = ECHO_N = -n ECHO_T = EGREP = /bin/grep -E EXEEXT = FGREP = /bin/grep -F GETCONF = /usr/bin/getconf GETLOADAVG_LIBS = GREP = /bin/grep HOSTNAME = /bin/hostname INIT_D_PATH = INSTALL = /usr/bin/install -c INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} INSTALL_SCRIPT = ${INSTALL} INSTALL_STRIP_PROGRAM = $(install_sh) -c -s KMEM_GROUP = LCOV = LCOV_GENHTML = LD = /usr/bin/ld -m elf_x86_64 LDFLAGS = -L/var/cfengine/lib -Wl,-R/var/cfengine/lib LEX = flex LEXLIB = -lfl LEX_OUTPUT_ROOT = lex.yy LIBACL_CFLAGS = LIBACL_CPPFLAGS = LIBACL_LDFLAGS = LIBACL_LIBS = LIBACL_PATH = default path LIBCURL_CFLAGS = LIBCURL_CPPFLAGS = LIBCURL_LDFLAGS = LIBCURL_LIBS = LIBCURL_PATH = default path LIBOBJS = LIBS = -ldl -lrt -lm LIBTOOL = $(SHELL) $(top_builddir)/libtool LIBVIRT_CFLAGS = LIBVIRT_CPPFLAGS = LIBVIRT_LDFLAGS = LIBVIRT_LIBS = LIBVIRT_PATH = default path LIBXML2_CFLAGS = LIBXML2_CPPFLAGS = -Icheck/include/libxml2 LIBXML2_LDFLAGS = LIBXML2_LIBS = LIBXML2_PATH = default path LIBYAML_CFLAGS = LIBYAML_CPPFLAGS = LIBYAML_LDFLAGS = LIBYAML_LIBS = LIBYAML_PATH = default path LIPO = LMDB_CFLAGS = LMDB_CPPFLAGS = LMDB_LDFLAGS = -R/lib LMDB_LIBS = -llmdb LMDB_PATH = default path LN_S = ln -s LTLIBOBJS = LT_SYS_LIBRARY_PATH = MAINT = MAKEINFO = MANIFEST_TOOL = : MKDIR_P = /bin/mkdir -p MYSQL_CFLAGS = MYSQL_CPPFLAGS = MYSQL_LDFLAGS = MYSQL_LIBS = MYSQL_PATH = default path NEED_SETGID = false NM = /usr/bin/nm -B NMEDIT = OBJDUMP = objdump OBJEXT = o OPENSSL_CFLAGS = OPENSSL_CPPFLAGS = OPENSSL_LDFLAGS = OPENSSL_LIBS = -lssl -lcrypto OPENSSL_PATH = default path OS_ENVIRONMENT_PATH = /etc/default OTOOL = OTOOL64 = PACKAGE = cfengine PACKAGE_BUGREPORT = PACKAGE_NAME = cfengine PACKAGE_STRING = cfengine 3.24.2 PACKAGE_TARNAME = cfengine PACKAGE_URL = PACKAGE_VERSION = 3.24.2 PAM_CFLAGS = PAM_CPPFLAGS = PAM_LDFLAGS = -R/lib PAM_LIBS = -lpam -ldl -lrt -lm PAM_PATH = default path PATH_SEPARATOR = : PCRE2_CFLAGS = PCRE2_CPPFLAGS = PCRE2_LDFLAGS = PCRE2_LIBS = -lpcre2-8 PCRE2_PATH = default path PERL = /usr/bin/perl PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = PLATFORM_SELINUX_POLICIES = POSTGRESQL_CFLAGS = POSTGRESQL_CPPFLAGS = POSTGRESQL_LDFLAGS = POSTGRESQL_LIBS = POSTGRESQL_PATH = default path PTHREAD_CC = gcc PTHREAD_CFLAGS = -pthread PTHREAD_LIBS = QDBM_CFLAGS = QDBM_CPPFLAGS = QDBM_LDFLAGS = QDBM_LIBS = QDBM_PATH = RANLIB = ranlib SED = /bin/sed SET_MAKE = SHELL = /bin/bash STRIP = strip SYSTEMD_SERVICE_PATH = /usr/lib/systemd/system SYSTEMD_SOCKET_CFLAGS = SYSTEMD_SOCKET_CPPFLAGS = SYSTEMD_SOCKET_LDFLAGS = SYSTEMD_SOCKET_LIBS = -ldl -lrt -lm SYSTEMD_SOCKET_PATH = default path TOKYOCABINET_CFLAGS = TOKYOCABINET_CPPFLAGS = TOKYOCABINET_LDFLAGS = TOKYOCABINET_LIBS = TOKYOCABINET_PATH = VERSION = 3.24.2 XML2_CONFIG = YACC = bison -y YFLAGS = abs_builddir = /home/jenkins/workspace/bootstrap-pr/core/tests/acceptance/25_cf-execd abs_srcdir = /home/jenkins/workspace/bootstrap-pr/core/tests/acceptance/25_cf-execd abs_top_builddir = /home/jenkins/workspace/bootstrap-pr/core abs_top_srcdir = /home/jenkins/workspace/bootstrap-pr/core ac_ct_AR = ar ac_ct_CC = gcc ac_ct_DUMPBIN = acx_pthread_config = am__include = include am__leading_dot = . am__quote = am__tar = tar --format=ustar --hard-dereference -chf - "$$tardir" am__untar = tar -xf - bindir = /var/cfengine/bin build = x86_64-pc-linux-gnu build_alias = build_cpu = x86_64 build_os = linux-gnu build_vendor = pc builddir = . datadir = default datarootdir = ${prefix}/share docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} dvidir = ${docdir} enable_builtin_extensions = no exec_prefix = ${prefix} host = x86_64-pc-linux-gnu host_alias = host_cpu = x86_64 host_os = linux-gnu host_vendor = pc htmldir = ${docdir} hw_cv_func_ctime_proper = no hw_cv_func_mkdir_proper = yes hw_cv_func_rename_proper = yes hw_cv_func_stat_proper = yes includedir = ${prefix}/include infodir = ${datarootdir}/info inputdir = default install_sh = ${SHELL} /home/jenkins/workspace/bootstrap-pr/core/install-sh libdir = ${exec_prefix}/lib libexecdir = ${exec_prefix}/libexec localedir = ${datarootdir}/locale localstatedir = ${prefix}/var logdir = /var/cfengine mandir = ${datarootdir}/man masterdir = default mkdir_p = $(MKDIR_P) oldincludedir = /usr/include pdfdir = ${docdir} piddir = /var/cfengine prefix = /var/cfengine program_transform_name = s,x,x, projlibdir = ${libdir} psdir = ${docdir} runstatedir = ${localstatedir}/run sbindir = ${exec_prefix}/sbin sharedstatedir = ${prefix}/com srcdir = . statedir = default subdirs = libntech sysconfdir = ${prefix}/etc systemctl = /bin/systemctl target = x86_64-pc-linux-gnu target_alias = target_cpu = x86_64 target_os = linux-gnu target_vendor = pc top_build_prefix = ../../../ top_builddir = ../../.. top_srcdir = ../../.. workdir = /var/cfengine AM_CPPFLAGS = \ $(OPENSSL_CPPFLAGS) \ -I$(srcdir)/../../../libpromises \ -I$(srcdir)/../../../libntech/libutils \ -I$(srcdir)/../../../libcfnet \ -I$(srcdir)/../../../libenv \ -I$(srcdir)/../../../cf-execd \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = \ $(PCRE2_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) cf_execd_test_SOURCES = cf-execd-rpl-functions.c cf_execd_test_LDADD = ../../../cf-execd/libcf-execd-test.la all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/acceptance/25_cf-execd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/acceptance/25_cf-execd/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-execd-test$(EXEEXT): $(cf_execd_test_OBJECTS) $(cf_execd_test_DEPENDENCIES) $(EXTRA_cf_execd_test_DEPENDENCIES) @rm -f cf-execd-test$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_execd_test_OBJECTS) $(cf_execd_test_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c include ./$(DEPDIR)/cf-execd-rpl-functions.Po .c.o: $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po # $(AM_V_CC)source='$<' object='$@' libtool=no \ # DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ # $(AM_V_CC_no)$(COMPILE) -c -o $@ $< .c.obj: $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po # $(AM_V_CC)source='$<' object='$@' libtool=no \ # DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ # $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo # $(AM_V_CC)source='$<' object='$@' libtool=yes \ # DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ # $(AM_V_CC_no)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/acceptance/25_cf-execd/mailfilter_promises_cf.template0000644000000000000000000000027315010704253027047 0ustar00rootroot00000000000000body common control { inputs => { "controls/cf_execd.cf" }; bundlesequence => { "test" }; } bundle agent test { reports: {{#reports}} "{{.}}"; {{/reports}} } cfengine-3.24.2/tests/acceptance/25_cf-execd/mailfilter_empty_old_log_everything_filtered.cf0000644000000000000000000000273215010704253032274 0ustar00rootroot00000000000000# Tests that no mail is sent by cf-execd if everything is filtered and the old # log is empty. body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promiser_filename)) }; } bundle agent init { vars: "reports" slist => { "WrongString1", "WrongString2", "WrongString3", }; # No mail is expected at all, since everything is filtered. "expected" slist => { }; "unexpected" slist => { ".+" }; "includes" slist => { }; "excludes" slist => { ".*WrongString.*" }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); files: "$(sys.workdir)/outputs/old.log" create => "true"; "$(sys.workdir)/outputs/previous" link_from => linkfrom("$(sys.workdir)/outputs/old.log", "symlink"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { methods: "any" usebundle => check_cf_execd_mail(@(init.expected), @(init.unexpected), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/mail_exclude_filter.cf0000644000000000000000000000240215010704253025077 0ustar00rootroot00000000000000# Tests that exclude mail filter causes excluded lines not to be mailed by # cf-execd. body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent init { vars: "reports" slist => { "CorrectString1", "CorrectString2", "WrongString1", "WrongString2", }; "includes" slist => { }; "excludes" slist => { "R: WrongString1", ".*WrongString[2]" }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { vars: "expected" slist => { "CorrectString1", "CorrectString2" }; "not_expected" slist => { "WrongString1", "WrongString2" }; methods: "any" usebundle => check_cf_execd_mail(@(expected), @(not_expected), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/mail_include_and_exclude_filters.cf0000644000000000000000000000343515010704253027616 0ustar00rootroot00000000000000# Tests that combining include and exclude mail filters works, IOW only lines # matching the include filter should be printed, unless they also match the # exclude filter. body common control { inputs => { "../default.cf.sub", "mailfilter_common.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent init { vars: "reports" slist => { "CorrectString1", "CorrectString2", "WrongString1", "WrongString2", "WrongString3", }; "includes" slist => { "R: CorrectString1", ".*CorrectString[2]", "R: WrongString1", ".*WrongString[2]" }; "excludes" slist => { "R: WrongString1", ".*WrongString[2]", # Tests anchoring. This is only a part of the string # and should not match. "orrectString1" }; methods: "any" usebundle => prepare_mailfilter_test(@(reports), @(includes), @(excludes)); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; } bundle agent check { vars: "expected" slist => { "CorrectString1", "CorrectString2" }; "not_expected" slist => { "WrongString1", "WrongString2", "WrongString3" }; methods: "any" usebundle => check_cf_execd_mail(@(expected), @(not_expected), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/25_cf-execd/cf-execd-rpl-functions.c0000644000000000000000000000654415010704253025223 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * A test source file with alternative implementations of some functions. Those * that are affected are generally ifdef'ed out in the original source file by * TEST_CF_EXECD macro. */ #include #include static void *FeedSmtpDirectives(void *data) { int socket = *(int *)data; #define COND_SEND(X) if (send(socket, X, strlen(X), 0) == -1) \ { \ Log(LOG_LEVEL_ERR, "Failed to write SMTP directive in %s:%i", __FILE__, __LINE__); \ return NULL; \ } \ else \ { \ fwrite(X, strlen(X), 1, stdout); \ } #define COND_RECV(X) if ((rcvd = recv(socket, X, sizeof(X), 0)) == -1) \ { \ Log(LOG_LEVEL_ERR, "Failed to read SMTP response in %s:%i", __FILE__, __LINE__); \ return NULL; \ } \ else \ { \ fwrite(X, rcvd, 1, stdout); \ } char recvbuf[CF_BUFSIZE]; int rcvd; COND_SEND("220 test.com\r\n"); COND_RECV(recvbuf); COND_SEND("250 Hello test.com, pleased to meet you\r\n"); COND_RECV(recvbuf); COND_SEND("250 from@test.com... Sender ok\r\n"); COND_RECV(recvbuf); COND_SEND("250 to@test.com... Recipient ok\r\n"); COND_RECV(recvbuf); COND_SEND("354 Enter mail, end with \".\" on a line by itself\r\n"); while (true) { COND_RECV(recvbuf); if ((rcvd == 3 && memcmp(recvbuf + rcvd - 3, ".\r\n", 3) == 0) || (rcvd > 3 && memcmp(recvbuf + rcvd - 4, "\n.\r\n", 4) == 0)) { break; } } COND_SEND("250 Message accepted for delivery\r\n"); COND_RECV(recvbuf); COND_SEND("221 test.com closing connection\r\n"); #undef COND_SEND #undef COND_RECV cf_closesocket(socket); free(data); return NULL; } int ConnectToSmtpSocket(ARG_UNUSED const ExecConfig *config) { int sockets[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { return -1; } int *thread_socket = xmalloc(sizeof(int)); *thread_socket = sockets[1]; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t thread; int ret = pthread_create(&thread, &attr, &FeedSmtpDirectives, thread_socket); pthread_attr_destroy(&attr); if (ret != 0) { free(thread_socket); cf_closesocket(sockets[0]); cf_closesocket(sockets[1]); return -1; } return sockets[0]; } cfengine-3.24.2/tests/acceptance/05_processes/0000755000000000000000000000000015010704253021115 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/05_processes/process_stop.cf0000644000000000000000000001141115010704253024150 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "ENT-4988" } string => "Test some basic expectations when using process_stop in processes type promises"; "test_soft_fail" string => "windows", meta => { "ENT-10257" }; processes: # The policy file itself is not expected to be executable, this promise is # expected to fail and be notkept. "." process_stop => "$(this.promise_filename)", handle => "process_stop_not_executable_expect_failed", classes => explicit_results( "namespace", "$(this.handle)_is" ); # G.true is expected to return true, and the promise is expected to be # repaired. Note: At the time of authorship there is no validation that # the selected pids were killed by process_stop. We are only using the # return code. "." process_stop => "$(G.true)", handle => "process_stop_return_zero_expect_repaired", classes => explicit_results( "namespace", "$(this.handle)_is" ); # G.false is expected to return false, and the promise is expected to be # repaired. Note: At the time of authorship there is no validation that # the selected pids were killed by process_stop. We are only using the # return code. "." process_stop => "$(G.false)", handle => "process_stop_return_nonzero_expect_failed", classes => explicit_results( "namespace", "$(this.handle)_is" ); # G.echo is expected to return true, and the promise is expected to be # repaired. Note: At the time of authorship there is no validation that # the selected pids were killed by process_stop. We are only using the # return code. "." process_stop => "$(G.echo) pretend stop servicename", handle => "process_stop_with_args_return_nonzero_expect_repaired", classes => explicit_results( "namespace", "$(this.handle)_is" ); } bundle agent check { vars: "expected_classes" slist => { "process_stop_with_args_return_nonzero_expect_repaired_is_repaired", "process_stop_return_nonzero_expect_failed_is_failed", "process_stop_return_zero_expect_repaired_is_repaired", "process_stop_not_executable_expect_failed_is_failed", }; DEBUG:: "found_classes" slist => classesmatching( "process_stop_.*"); "difference" slist => difference( found_classes, expected_classes ); classes: "ok" and => { @(expected_classes) }; reports: DEBUG:: "Found unexpected class: $(difference)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes explicit_results(scope, class_prefix) # @brief Define classes prefixed with `class_prefix` and suffixed with # appropriate outcomes: _kept, _repaired, _failed, _denied, _timeout # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined # # This body can be applied to any promise and sets global # (`namespace`) or local (`bundle`) classes based on its outcome. For # instance, with `class_prefix` set to `abc`: # # This body is a simpler, more consistent version of the body `results`. The key # difference is that fewer classes are defined, and only for explicit outcomes # that we can know. For example this body does not define "OK/not OK" outcome # classes, since a promise can be both kept and failed at the same time. # # It's important to understand that promises may do multiple things, # so a promise is not simply "OK" or "not OK." The best way to # understand what will happen when your specific promises get this # body is to test it in all the possible combinations. # # **Suffix Notes:** # # * `_kept` indicates some aspect of the promise was kept # # * `_repaired` indicates some aspect of the promise was repaired # # * `_failed` indicates the promise failed # # * `_denied` indicates the promise repair was denied # # * `_timeout` indicates the promise timed out # # **Example:** # # ```cf3 # bundle agent example # { # commands: # "/bin/true" # classes => results("bundle", "my_class_prefix"); # # reports: # my_class_prefix_kept:: # "My promise was kept"; # # my_class_prefix_repaired:: # "My promise was repaired"; # } # ``` # # **See also:** `scope`, `scoped_classes_generic`, `classes_generic` { scope => "$(scope)"; promise_kept => { "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_failed" }; repair_denied => { "$(class_prefix)_denied" }; repair_timeout => { "$(class_prefix)_timeout" }; } cfengine-3.24.2/tests/acceptance/05_processes/02_functions/0000755000000000000000000000000015010704253023426 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/05_processes/02_functions/processexists.cf0000644000000000000000000000133415010704253026657 0ustar00rootroot00000000000000########################################################### # # Test processexists() # # Note: On HP-UX this depends on the # 00_hpux_ps_setup_serial.cf setup test having run first. # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle common test { classes: "descartes" expression => processexists(".+agent.+"); } ########################################################### bundle agent check { methods: "" usebundle => dcs_passif_expected("descartes", "", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/05_processes/02_functions/findprocesses.cf0000644000000000000000000000206015010704253026605 0ustar00rootroot00000000000000########################################################### # # Test findprocesses() # # Note: On HP-UX this depends on the # 00_hpux_ps_setup_serial.cf setup test having run first. # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle common test { classes: # this will be set only if we find our own exact PID "descartes" expression => strcmp($(found_pids), $(this.promiser_pid)); vars: # find our own PID, using \b to make sure we match whole words "found" data => findprocesses("\bfindprocesses\.cf\b"); # pluck the "pid" field out into a list "found_pids" data => mapdata("none", "$(found[$(this.k)][pid])", found); } ########################################################### bundle agent check { methods: "" usebundle => dcs_passif_expected("descartes", "", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/05_processes/01_matching/0000755000000000000000000000000015010704253023207 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/05_processes/01_matching/process_count_found.cf0000644000000000000000000000201015010704253027573 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does exist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: "\bcf-agent\b" process_count => test_no_such; } body process_count test_no_such { in_range_define => { "found" }; out_of_range_define => { "not_found" }; match_range => irange(1,"inf"); } ####################################################### bundle agent check { classes: "ok" expression => "found.!not_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/promiser_match_is_correct.cf0000644000000000000000000000533115010704253030753 0ustar00rootroot00000000000000# Test that process promise only matches the promiser against the command line # not the full ps line output. Also verify that a command line longer than 80 # characters can be matched using the promiser. Created for Redmine #7627. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "debug_info", default("$(this.promise_filename)") }; } bundle common userinfo { vars: "cmd" string => "id | sed -e 's/.*uid=\([0-9][0-9]*\).*/\1/'"; any:: "current_user" string => execresult($(cmd), "useshell"); classes: "root_user" expression => strcmp("$(current_user)", "0"); } bundle agent debug_info { reports: !root_user:: "Need to be root user to run this. Detected user: $(userinfo.current_user)"; } bundle agent init { meta: # Using background commands, this won't work correctly on Windows. # Also, we need to be root user to test this correctly, since we need to # match against the user in the ps output. # And we can't use no_fds under fakeroot. "test_skip_needs_work" string => "windows|!root_user|using_fakeroot"; commands: "$(G.no_fds) --no-std $(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_underscore_marks_the_81st_character_of_this_string___STRINGBEYOND80CHARS &" contain => in_shell; # give the process a chance to actually start "$(G.sleep) 1"; } body process_count at_least_one(class) { match_range => irange("1", "1000"); in_range_define => { "$(class)" }; } bundle agent test { processes: "$(this.promise_filename).sub" process_count => at_least_one("cf_agent"); "STRINGBEYOND80CHARS" process_count => at_least_one("string"); # This is intended to look for a username in the process matching, which # is wrong, we only want it to match the command string. However, "root" # might be in the home path of the executing user, which is valid, so # avoid that match. "root[^/].*$(this.promise_filename).sub" process_count => at_least_one("root"); } bundle agent check { vars: "expected_classes" slist => { "cf_agent", "string", "!root", }; classes: "ok" and => { @(expected_classes) }; commands: # Just sleep a little to make sure our background command has finished. "$(G.sleep) 6"; reports: DEBUG:: "expected_classes = $(expected_classes)"; "Expression evaluated to false, should be true: $(expected_classes)" unless => "$(expected_classes)"; !root_user|!ok:: "$(this.promise_filename) FAIL"; root_user.ok:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/05_processes/01_matching/process_count_inverse_not_found.cf0000644000000000000000000000202015010704253032207 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does exist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: "\bcf-agent\b" process_count => test_no_such; } body process_count test_no_such { in_range_define => { "none_found" }; out_of_range_define => { "some_found" }; match_range => irange(0,0); } ####################################################### bundle agent check { classes: "ok" expression => "!none_found.some_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/tty.cf0000644000000000000000000000561415010704253024347 0ustar00rootroot00000000000000####################################################### # # Basic checking of 'tty' selector. # # The name pattern of ttys varies across operating systems. # While the example in the documentation (e.g. "pts/[0-9]+") # is typical and illustrative, this basic-level test needs to be # reliably portable. # # The possible meta "test_skip_needs_work" would allow graceful handling # of platforms that have not yet been tested. But aim to minimise # any reliance on this. # # It assumes that the host on which the test is being run will have at least # one tty connection active. This is clearly the case if it is being run # by a human from their command line. But it might not be true in a # CI/CD environment; in such a case the meta/skip may be useful. # # Tests: # # 1. Negative: using a highly unlikely name. # # 2. Positive: using a known-good name pattern; allow to differ across OSes. # # David Lee, 2019 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_needs_work" -> {"CFE-3025"} string => "!linux.!hpux", comment => "TTY-based process filtering doesn't work well on other platforms"; vars: # Maintenance note: Aim to cover as many OSes as possible # and mimimise the ".+" catch-all. linux:: "dev_pattern" string => "(pts/[0-9]+)|(ttyS?[0-9]+)"; !linux:: "dev_pattern" string => ".+"; processes: ### Expect zero processes on a tty with a highly unlikely name. ".*" handle => "expect_none", process_select => test_select_tty("No-Such-Major/No-Such-Minor"), process_count => test_range("0", "0", "pass_bad_dev", "fail_bad_dev"); ### Expect to find one or more processes on these ttys. ".*" handle => "expect_some", process_select => test_select_tty("$(dev_pattern)"), process_count => test_range("1", "inf", "pass_good_dev", "fail_good_dev"); } body process_count test_range(min, max, class_good, class_bad) { match_range => irange("$(min)", "$(max)"); in_range_define => { "$(class_good)" }; out_of_range_define => { "$(class_bad)" }; } body process_select test_select_tty(tty_pattern) { tty => "$(tty_pattern)"; process_result => "tty"; } ####################################################### bundle agent check { classes: "ok" and => { "pass_good_dev", "pass_bad_dev", "!fail_good_dev", "!fail_bad_dev", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/inverse_ttime_inverse_found.cf0000644000000000000000000000314315010704253031325 0ustar00rootroot00000000000000####################################################### # # Set a class if a process with !any time does not exist, and # we wanted not to (irange(0,0)) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_flakey_fail" string => "aix_7_1", meta => { "CFE-3313" }; processes: ".*" process_count => test_range, process_select => test_select_high_users; } body process_count test_range { in_range_define => { "none_found" }; out_of_range_define => { "some_found" }; aix:: # Allow one process with CPU time not between 0 seconds and 99 years on # AIX because a process with TIME '-' sometimes appears there. match_range => irange(0, 1); !aix:: match_range => irange(0, 0); } body process_select test_select_high_users { ttime_range => irange(0, accumulated(99,0,0,0,0,0)); # Anything process_result => "!ttime"; # Nothing } ####################################################### bundle agent check { classes: "ok" expression => "none_found.!some_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/restart_class.cf0000644000000000000000000000155315010704253026376 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does not exist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { processes: "There-is-NoPrOCess-with-this-name" restart_class => "ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/promiser_match_is_correct.cf.sub0000644000000000000000000000027215010704253031542 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { commands: "$(G.sleep) 3"; } cfengine-3.24.2/tests/acceptance/05_processes/01_matching/timed/0000755000000000000000000000000015010704253024311 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/05_processes/01_matching/timed/stime.cf0000644000000000000000000000334115010704253025745 0ustar00rootroot00000000000000# Test that using process cmd line matching works in a process promise. body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { meta: # Adding the test case revealed that these platforms do not work, but we # don't know why. "test_skip_needs_work" string => "solaris|hpux"; "test_soft_fail" string => "windows", meta => { "ENT-10257" }; vars: # Random, but unique string for this test case. "unique" string => "Ni8Goobi"; commands: test_pass_1.!windows:: "$(G.no_fds) --no-std $(G.sh) $(this.promise_filename).bat $(unique) &" contain => in_shell; test_pass_1.windows:: "$(this.promise_dirname)/../../../elevate.exe $(this.promise_filename).bat $(unique)" contain => in_shell; } bundle agent test { vars: "escaped_process" string => escape("$(this.promise_filename).bat"); processes: ".*$(init.unique).*" process_count => test_range; } body process_count test_range { in_range_define => { "found" }; out_of_range_define => { "not_found" }; match_range => irange(1,100); } bundle agent check { methods: test_pass_1:: "any" usebundle => dcs_wait("$(this.promise_filename)", 1); test_pass_2.(!found|not_found):: "any" usebundle => dcs_fail("$(this.promise_filename)"); test_pass_2.found.!not_found:: "any" usebundle => dcs_wait("$(this.promise_filename)", 65); test_pass_3.(found|!not_found):: "any" usebundle => dcs_fail("$(this.promise_filename)"); test_pass_3.!found.not_found:: "any" usebundle => dcs_pass("$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/timed/stime.cf.bat0000644000000000000000000000001115010704253026501 0ustar00rootroot00000000000000sleep 60 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/stime_range.cf0000644000000000000000000002127715010704253026027 0ustar00rootroot00000000000000####################################################### # # Acceptance test for RedMine 4094 # # Where ps reports a date (or even a year) as "start time", selecting # processes by how old they are can get wrong answers due to the # imprecision implicit in these start times. (Our code, from the # commit that adds this test, deals with this by using elapsed time to # infer a start time, when appropriate.) The test below looks for # processes whose start times look more like dates than times; it uses # the elapsed time of such processes to find out how long they've # actually been running and separates them into "early" and "late" # groups, based on whether their start-times in their respective start # dates are before or after the present time within today. If we now # search for processes started within the number of days that their # start date is ago, the late ones should appear within that interval # while the early ones appear outside it. # # On platforms where start time doesn't fall back to a date, or on # hosts which don't have any old processes running, this test finds no # matching "early" or "late" processes and silently passes. If we # have a platform on which this test fails, this may lead to the test # not always failing (due to the host lacking relevant processes by # which to notice the failure). # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "now_raw" string => execresult("$(G.ps) -o stime $$", "useshell"); got_ps.got_now:: # Get pid and parsed etime for processes whose stime isn't # actually a time; use sed to munge ps's output into a csv # format for ease of ingestion: "ps_list" string => execresult("$(G.ps) -eo pid,stime,etime | sed -n -e 's/[ \t]*\([0-9][0-9]*\)[ \t][ \t]*[A-Z][a-z0-9]*[ \t][ \t]*\(\([0-9][0-9]*\)-\)\?\([0-9][0-9]*\):\([0-9][0-9]*\):\([0-9][0-9]*\)/\1,\3,\4,\5,\6/p'", "useshell"); # Ingest the results, save in procs[i][j]: "count" int => parsestringarrayidx("procs", "$(ps_list)", "no comment", ",", "1000", "100000"); # procs[i][j] for each i describe one process; # for j = 0, ..., 4, entries are a pid and its age in days, hrs, mins, secs "pndx" slist => getindices("procs"); # Now flatten h:m:s to total seconds, for each proc-index: "hrassec[$(pndx)]" ilist => { "$(procs[$(pndx)][2])", "3600" }; "min2sec[$(pndx)]" ilist => { "$(procs[$(pndx)][3])", "60" }; "hms[$(pndx)]" rlist => { product("hrassec[$(pndx)]"), product("min2sec[$(pndx)]"), "$(procs[$(pndx)][4])" }; # Map pids to seconds before a whole number of days ago: "when[$(procs[$(pndx)][0])]" string => format("%.0f", sum("hms[$(pndx)]")); # Likewise reduce "now" to a number of seconds into today: "hrassec[now]" ilist => { "$(now[1])", "3600" }; "min2sec[now]" ilist => { "$(now[2])", "60" }; "hms[now]" rlist => { product("hrassec[now]"), product("min2sec[now]") }; "present" string => format("%.0f", sum("hms[now]")); # Allow for up to 10s delay between when we asked for now_raw # and when bundle agent test runs: "pausing" rlist => { @(hms[now]), "10" }; "paused" string => format("%.0f", sum("pausing")); # Naturally, this doesn't work so well if the interval between # present and paused straddles midnight; see bad_timing, below. # How many days back is each pid ? "past[$(pndx)]" slist => { # Number of days from elapsed time, 0 if none specified: ifelse("got_day_$(pndx)", "$(proc_day[$(pndx)][0])", "0"), # Plus one for those started late in their days: ifelse("late_$(procs[$(pndx)][0])", "1", "0") }; "days[$(procs[$(pndx)][0])]" string => format("%.0f", sum("past[$(pndx)]")); "pid" slist => getindices("days"); classes: # Give up on test unless these are set: "got_now" expression => regextract("^(\d+):(\d+)$", "$(now_raw)", "now"); "got_ps" expression => isexecutable("$(G.ps)"); got_ps.got_now:: "got_data" expression => isgreaterthan(length("pndx"), 0); # Filtering processes got_data:: # Are we too close to midnight ? "bad_timing" expression => isgreaterthan("$(paused)", 86400); # 24*60*60 # Which procs[$(pndx)] have non-empty days, procs[$(pndx)][1] ? "got_day_$(pndx)" expression => regextract("(\d+)", "$(procs[$(pndx)][1])", "proc_day[$(pndx)]"); # A process started late in its day if less than $(present) # seconds before a whole number of days ago: "late_$(procs[$(pndx)][0])" expression => isgreaterthan("$(present)", "$(when[$(procs[$(pndx)][0])])"), scope => "namespace"; # ... and early in its day if more than $(paused) seconds before # a whole number of days ago: "early_$(procs[$(pndx)][0])" and => { isgreaterthan("$(when[$(procs[$(pndx)][0])])", "$(paused)"), "got_day_$(pndx)" }, scope => "namespace"; "got_early" or => { classmatch("early_\d+") }, scope => "namespace"; "got_late" or => { classmatch("late_\d+") }, scope => "namespace"; # So now a search for pid=$(pid) within the last $(days[$(pid)]) # days should fail if early_$(pid) is set and succeed if # late_$(pid) is set; if neither is set, it may go either way. # reports: # DEBUG.got_early:: # "Early: $(pid) from $(days[$(pid)]) days ago" if => "early_$(pid)"; # DEBUG.got_late:: # "Late: $(pid) from $(days[$(pid)]) days ago" if => "late_$(pid)"; } ####################################################### bundle agent test { vars: "pid" ilist => { @(init.pid) }; processes: "" process_select => pid_is_newer_than($(pid), "$(init.days[$(pid)])"), process_count => any_procs("early_$(pid)"), if => "early_$(pid)"; "" process_select => pid_is_newer_than($(pid), "$(init.days[$(pid)])"), process_count => any_procs("late_$(pid)"), if => "late_$(pid)"; } body process_select pid_is_newer_than(pid, days) { pid => irange($(pid), $(pid)); stime_range => irange(ago(0, 0, $(days), 0, 0, 0), now()); process_result => "pid.stime"; } body process_count any_procs(prefix) { match_range => "1,1"; in_range_define => { "$(prefix)_in" }; out_of_range_define => { "$(prefix)_out" }; } ####################################################### bundle agent check { vars: "pid" ilist => { @(init.pid) }; classes: "bad_$(pid)_in" and => { "early_$(pid)", "early_$(pid)_in" }; "good_$(pid)_out" and => { "early_$(pid)", "early_$(pid)_out" }; "good_$(pid)_in" and => { "late_$(pid)", "late_$(pid)_in" }; "bad_$(pid)_out" and => { "late_$(pid)", "late_$(pid)_out" }; "early_in" or => { classmatch("bad_\d+_in") }; "early_out" or => { classmatch("good_\d+_out") }; "late_in" or => { classmatch("good_\d+_in") }; "late_out" or => { classmatch("bad_\d+_out") }; "early_ok" or => { "!got_early", "!early_in.early_out" }; "late_ok" or => { "!got_late", "late_in.!late_out" }; "pass" and => { "late_ok", "early_ok" }; "ok" or => { "pass", "bad_timing" }; reports: bad_timing:: "Ran too close to midnight to get meaningful answers; 'passing' by default."; DEBUG.!got_early:: "Found no processes, early in past days, to test"; DEBUG.!got_late:: "Found no processes, late in past days, to test"; DEBUG.got_early.early_in:: "Early processes reported as in range"; "Process $(pid), reported within $(init.days[$(pid)]) days, is older" if => "bad_$(pid)_in"; DEBUG.got_early.!early_out:: "Early processes not reported as out of range"; "Process $(pid), not reported outside $(init.days[$(pid)]) days, is so old" if => "early_$(pid).!early_$(pid)_out"; DEBUG.got_late.!late_in:: "Late processes not reported as in range"; "Process $(pid), not reported within $(init.days[$(pid)]) days, is so new" if => "late_$(pid).!late_$(pid)_in"; DEBUG.got_late.late_out:: "Late processes reported as out of range"; "Process $(pid), reported outside $(init.days[$(pid)]) days, is newer" if => "bad_$(pid)_out"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/ttime_classes_body_params.cf0000644000000000000000000000242215010704253030740 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does exist, more complex matches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: ".*" process_select => test_select_high_users, classes => test_set_class("found", "not_found"); } body classes test_set_class(t,f) { promise_kept => { "$(t)" }; promise_repaired => { "$(t)" }; repair_failed => { "$(f)" }; } body process_select test_select_high_users { ttime_range => irange(0, accumulated(9,0,0,0,0,0)); # Anything process_result => "ttime"; # Everything } ####################################################### bundle agent check { classes: "ok" expression => "found.!not_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/partial_name_inverse_found.cf0000644000000000000000000000176215010704253031111 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does exist, # but partial match name fails # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: "cf-agen$" process_count => test_no_such; } body process_count test_no_such { in_range_define => { "none_found" }; out_of_range_define => { "some_found" }; match_range => irange(0,0); } ####################################################### bundle agent check { classes: "ok" expression => "none_found.!some_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/process_count_inverse_found.cf0000644000000000000000000000203515010704253031335 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does not exist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: "There-is-NoPrOCess-with-this-name" process_count => test_no_such; } body process_count test_no_such { in_range_define => { "found" }; out_of_range_define => { "not_found" }; match_range => irange(0,0); } ####################################################### bundle agent check { classes: "ok" expression => "found.!not_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/partial_name_inverse_not_found.cf0000644000000000000000000000212515010704253031763 0ustar00rootroot00000000000000####################################################### # # Set a negative match class if a process does exist, # and partial name match succeeds but we wanted zero found # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: "-agent" process_count => test_no_such; } body process_count test_no_such { in_range_define => { "none_found" }; out_of_range_define => { "some_found" }; match_range => irange(0,0); } ####################################################### bundle agent check { classes: "ok" expression => "!none_found.some_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/process_select_fncalls.cf0000644000000000000000000000540515010704253030244 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-1968" } string => "Test that process_select body can have (failing) function calls"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "canonified_uid" string => canonify(getuid("nosuchuser")); processes: any:: "cf-agent" process_select => by_owner_no_fncall("nosuchuser", "$(canonified_uid)"), process_count => proc_found_one_or_more("nosuchuser_no_fncall"); "cf-agent" process_select => by_owner("nosuchuser"), process_count => proc_found_one_or_more("nosuchuser"); "nosuchproc" process_count => proc_found_one_or_more("nosuchproc"); "cf-agent" process_count => proc_found_one_or_more("agent"); ".*" process_select => by_owner("root"), process_count => proc_found_one_or_more("root"); } body process_count proc_found_one_or_more(prefix) # defines _found / _not_found if there are 1 or more / 0 matches, respectively { in_range_define => { "$(prefix)_found" }; out_of_range_define => { "$(prefix)_not_found" }; match_range => irange(1,"inf"); } body process_select by_owner(u) # @brief Select processes owned by user `u` # @param u The name of the user # # Matches processes against the given username and the given username's uid # in case only uid is visible in process list. # # @note: if getuid fails (because there is no user) the canonify call will # not resolve, and that part of the list will be skipped. { process_owner => { "$(u)", canonify(getuid("$(u)")) }; process_result => "process_owner"; } body process_select by_owner_no_fncall(u, cgu) # Compare behavior to this backwards compatible body { process_owner => { "$(u)", "$(cgu)" }; process_result => "process_owner"; } ####################################################### bundle agent check { classes: "ok" and => { "!nosuchuser_no_fncall_found", "nosuchuser_no_fncall_not_found", "!nosuchuser_found", "nosuchuser_not_found", "!nosuchproc_found", "nosuchproc_not_found", "agent_found", "!agent_not_found", "root_found", "!root_not_found" }; reports: DEBUG.agent_found:: "ok - found agent"; DEBUG.nosuchproc_found:: "not ok - found nosuchproc"; DEBUG.nosuchuser_found:: "not ok - found nosuchuser"; DEBUG.root_found:: "ok - found root!"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/05_processes/01_matching/ttime_inverse_found.cf0000644000000000000000000000246715010704253027602 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does exist but # we wanted not to (irange(0,0)), more complex matches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: ".*" process_count => test_range, process_select => test_select_high_users; } body process_count test_range { in_range_define => { "none_found" }; out_of_range_define => { "some_found" }; match_range => irange(0,0); } body process_select test_select_high_users { ttime_range => irange(0, accumulated(9,0,0,0,0,0)); # Anything process_result => "ttime"; # Everything } ####################################################### bundle agent check { classes: "ok" expression => "!none_found.some_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/inverse_ttime_classes_body_params.cf0000644000000000000000000000246115010704253032476 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does exist, more complex matches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: ".*" process_select => test_select_high_users, classes => test_set_class("found", "not_found"); } body classes test_set_class(t,f) { promise_kept => { "$(t)" }; promise_repaired => { "$(t)" }; repair_failed => { "$(f)" }; } body process_select test_select_high_users { ttime_range => irange(0, accumulated(9,0,0,0,0,0)); # Anything process_result => "!ttime"; # Nothing } ####################################################### bundle agent check { classes: "ok" expression => "found.!not_found"; # Nothing found is "kept" reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/negative_restart_class.cf0000644000000000000000000000157215010704253030261 0ustar00rootroot00000000000000####################################################### # # Set a class if a process exists # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { processes: "\bcf-agent\b" restart_class => "not_ok"; classes: "ok" not => "not_ok"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/process_count_fncalls.cf0000644000000000000000000000126315010704253030113 0ustar00rootroot00000000000000bundle agent main { meta: "description" -> { "CFE-2067" } string => "Test that process_count body can have (failing) function calls"; processes: # Test that this doesn't cause a crash / abort: "cf-execd" process_count => process_count_one("$(nosuchvar)"); # Error will be printed since variable won't expand, expected behavior reports: # Nothing to check, running without crashing is good enough "$(this.promise_filename) Pass"; } body process_count process_count_one(suffix) { match_range => irange("1", "1"); in_range_define => { canonify("one_$(suffix)") }; out_of_range_define => { canonify("not_one_$(suffix)") }; } cfengine-3.24.2/tests/acceptance/05_processes/01_matching/process_count_not_found.cf0000644000000000000000000000204115010704253030457 0ustar00rootroot00000000000000####################################################### # # Set a class if a process does not exist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: "There-is-NoPrOCess-with-this-name" process_count => test_no_such; } body process_count test_no_such { in_range_define => { "found" }; out_of_range_define => { "not_found" }; match_range => irange(1,"inf"); } ####################################################### bundle agent check { classes: "ok" expression => "!found.not_found"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/01_matching/owner.cf0000644000000000000000000000445015010704253024656 0ustar00rootroot00000000000000####################################################### # # Run multiple similar tests for 'process_owner'. # We test both expected success and expected failure. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "ok_list" slist => { "pass_root_1", "pass_root_2", "pass_nouser_3", "pass_nouser_4", "!fail_root_1", "!fail_root_2", "!fail_nouser_3", "!fail_nouser_4" }; processes: ### 'root' processes: # finding many processes is good ".*" process_select => test_select_owners("root"), process_count => test_range("2", "inf", "pass_root_1", "fail_root_1"); # looking for a tiny number should fail ".*" process_select => test_select_owners("root"), process_count => test_range("0", "1", "fail_root_2", "pass_root_2"); ### A hopefully non-existent user: # finding zero processes is good ".*" process_select => test_select_owners("NoSuchUserWeHope"), process_count => test_range("0", "0", "pass_nouser_3", "fail_nouser_3"); # looking for one or more should fail ".*" process_select => test_select_owners("NoSuchUserWeHope"), process_count => test_range("1", "inf", "fail_nouser_4", "pass_nouser_4"); } body process_count test_range(min, max, class_good, class_bad) { match_range => irange("$(min)", "$(max)"); in_range_define => { "$(class_good)" }; out_of_range_define => { "$(class_bad)" }; } body process_select test_select_owners(owner) { process_owner => { "$(owner)" }; process_result => "process_owner"; } ####################################################### bundle agent check { classes: "ok" and => { @(test.ok_list) }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 30 cfengine-3.24.2/tests/acceptance/05_processes/00_hpux_ps_setup_serial.cf0000644000000000000000000000213115010704253026170 0ustar00rootroot00000000000000# Simply makes sure that /etc/default/ps has the correct setting on HPUX. If # DEFAULT_CMD_LINE_WIDTH is too low ps output may be truncated, leading to test # failures. We adjust it here if we are running in unsafe mode, else we simply # check that it is correct and fail if it isn't. body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "test_skip_unsupported" string => "!hpux"; classes: "unsafe_mode" expression => strcmp(getenv("UNSAFE_TESTS", "10"), "1"), scope => "namespace"; files: unsafe_mode:: "/etc/default/ps" edit_line => ps_edit; } bundle edit_line ps_edit { delete_lines: "\s*DEFAULT_CMD_LINE_WIDTH\s*=\s*[0-9]+\s*"; insert_lines: "DEFAULT_CMD_LINE_WIDTH=1024"; } bundle agent check { classes: "ok" expression => regline("DEFAULT_CMD_LINE_WIDTH=1024", "/etc/default/ps"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/0000755000000000000000000000000015010704253021317 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/0000755000000000000000000000000015010704253022576 5ustar00rootroot00000000000000runagent_-D_ns1_role2_-B_ns2_bundle2_denied.cf0000644000000000000000000000230715010704253033105 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serialbody common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 -D ns1:role2 --remote-bundles ns2:bundle2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundles_all_allowed_roles_disallowed_denied.cf0000644000000000000000000000225115010704253033747 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serialbody common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_all_allowed.22010.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22010 is bundles_all_allowed.22010.srv run_runagent("-H 127.0.0.1:22010 --remote-bundles bundle1 -D role $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_all_allowed.22010.srv"); } runagent_-D_ns1_role2_-B_ns2_bundle2_admitted.cf0000644000000000000000000000277715010704253033463 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serialbody common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D ns1:role2 --bundlesequence ns2:bundle2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/ns2_bundle2_ns1_role2_only_allowed.22015.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22015 is ns2:bundle2_ns1:role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22015 -D ns1:role2 --remote-bundles ns2:bundle2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/ns2_bundle2_ns1_role2_only_allowed.22015.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role2_role1_denied_1.cf0000644000000000000000000000230715010704253031212 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22009 is allroles_nonroot_role2_root_allowed.22009.srv run_runagent("-H 127.0.0.1:22009 -D role2,role1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_role2_admitted_1.cf0000644000000000000000000000264215010704253031557 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role1,role2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/allroles_root_allowed.22006.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22006 is allroles_root_allowed.22006.srv run_runagent("-H 127.0.0.1:22006 -D role1,role2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/allroles_root_allowed.22006.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_open.22000.srv0000644000000000000000000000164715010704253027501 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22000"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to activate all classes # roles: # ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/role12_root_allowed.22007.srv0000644000000000000000000000165715010704253027672 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22007"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to only activate class "role12" roles: "role12" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_bundle1_admitted_1.cf0000644000000000000000000000266015010704253030762 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "--bundlesequence bundle1"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_all_allowed.22010.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22010 is bundles_all_allowed.22010.srv run_runagent("-H 127.0.0.1:22010 --remote-bundles bundle1 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_all_allowed.22010.srv"); } bundles_all_allowed_regex_disallowed_admitted.cf0000644000000000000000000000274115010704253034304 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serialbody common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "--bundlesequence bundle"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_all_allowed_regex_disallowed.22013.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22013 is bundles_all_allowed_regex_disallowed.22013.srv run_runagent("-H 127.0.0.1:22013 --remote-bundles bundle $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_all_allowed_regex_disallowed.22013.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role2_admitted_1.cf0000644000000000000000000000263715010704253030461 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22008 is role1_role2_root_allowed.22008.srv run_runagent("-H 127.0.0.1:22008 -D role2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/bundles_all_allowed.22010.srv0000644000000000000000000000163615010704253027776 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22010"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; ".*" admit_ips => { "127.0.0.1", "::1" }, resource_type => "bundle"; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_ns1_role2_-B_bundle2_denied.cf0000644000000000000000000000233315010704253032401 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/ns2_bundle2_ns1_role2_only_allowed.22015.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22015 is ns2_bundle2_ns1_role2_only_allowed.22015.srv run_runagent("-H 127.0.0.1:22015 -D ns1:role2 --remote-bundles bundle2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/ns2_bundle2_ns1_role2_only_allowed.22015.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_bundle2_bundle1_denied.cf0000644000000000000000000000227615010704253031615 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 --remote-bundles bundle2,bundle1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_no_access.22003.srv0000644000000000000000000000170115010704253030467 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22003"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: # ACCESS IS DENIED to 127.0.0.1 "$(G.write_args_sh)" admit_ips => { "1.2.3.4" }; # Authorize "root" users to activate all classes # roles: # ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_no_access.22002.srv0000644000000000000000000000170115010704253030466 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22002"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: # ACCESS IS DENIED # "$(G.write_args_sh)" # admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to activate all classes # roles: # ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_specialchars_denied.cf0000644000000000000000000000224315010704253031305 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_roles_all_allowed.22011.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22011 is bundles_roles_all_allowed.22011.srv run_runagent("-H 127.0.0.1:22011 -D role@ $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_roles_all_allowed.22011.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_deny_root.cf0000644000000000000000000000213015010704253027642 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_deny_root.22001.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => run_runagent("-H 127.0.0.1:22001 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_deny_root.22001.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_deny_root.22001.srv0000644000000000000000000000151515010704253030535 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22001"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Allow user "blah", disallow "root" user to execute cfruncommand allowusers => { "blah" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; } runagent_-D_ns2_role2_-B_ns2_bundle2_denied.cf0000644000000000000000000000233715010704253033111 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serialbody common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/ns2_bundle2_ns1_role2_only_allowed.22015.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22015 is ns2_bundle2_ns1_role2_only_allowed.22015.srv run_runagent("-H 127.0.0.1:22015 -D ns2:role2 --remote-bundles ns2:bundle2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/ns2_bundle2_ns1_role2_only_allowed.22015.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_no_access_1.cf0000644000000000000000000000233415010704253030023 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_no_access.22002.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22002 is cfruncommand_no_access.22002.srv run_runagent("-H 127.0.0.1:22002 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there, since cfruncommand # invocation from cf-serverd should have been denied. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_no_access.22002.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_admitted_3.cf0000644000000000000000000000263715010704253030462 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role1"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22008 is role1_role2_root_allowed.22008.srv run_runagent("-H 127.0.0.1:22008 -D role1 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-o_deprecated.cf0000644000000000000000000000222315010704253027505 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22000 is cfruncommand_open.22000.srv run_runagent("-H 127.0.0.1:22000 -o custom_option $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_bundle1_bundle2_admitted_1.cf0000644000000000000000000000270015010704253032370 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "--bundlesequence bundle1,bundle2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_all_allowed.22010.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22010 is bundles_all_allowed.22010.srv run_runagent("-H 127.0.0.1:22010 --remote-bundles bundle1,bundle2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_all_allowed.22010.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_admitted_2.cf0000644000000000000000000000262615010704253030457 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role1"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/allroles_root_allowed.22006.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22006 is allroles_root_allowed.22006.srv run_runagent("-H 127.0.0.1:22006 -D role1 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/allroles_root_allowed.22006.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_denied_1.cf0000644000000000000000000000221315010704253030103 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22000 is cfruncommand_open.22000.srv run_runagent("-H 127.0.0.1:22000 -D role1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } bundles_all_allowed_regex_disallowed.22013.srv0000644000000000000000000000177115010704253033323 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serialbody common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22013"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; ".*" admit_ips => { "127.0.0.1", "::1" }, resource_type => "bundle"; "bundle[12]" deny_ips => { "0.0.0.0/0" }, resource_type => "bundle"; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/bundle2_role2_only_allowed.22012.srv0000644000000000000000000000201315010704253031201 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22012"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; "bundle2" admit_ips => { "127.0.0.1", "::1" }, resource_type => "bundle"; # Authorize "root" user to activate only "role2" class roles: "role2" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role12_denied_1.cf0000644000000000000000000000231015010704253030163 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22005 is role1_root_allowed.22005.srv # It allows "role1" but should disallow "role12" run_runagent("-H 127.0.0.1:22005 -D role12 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role2_denied_1.cf0000644000000000000000000000230615010704253030107 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22005 is role1_root_allowed.22005.srv # It allows "role1" but should disallow "role2" run_runagent("-H 127.0.0.1:22005 -D role2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_denied_3.cf0000644000000000000000000000241215010704253030106 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22009 is allroles_nonroot_role2_root_allowed.22009.srv # It allows "role1" but only to user "nonroot" so it should fail run_runagent("-H 127.0.0.1:22009 -D role1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role2_-B_bundle2_admitted.cf0000644000000000000000000000272715010704253032172 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role2 --bundlesequence bundle2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 -D role2 --remote-bundles bundle2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_bundle_denied.cf0000644000000000000000000000226515010704253030117 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 --remote-bundles bundle $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_bundle1_bundle2_denied.cf0000644000000000000000000000227615010704253031615 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 --remote-bundles bundle1,bundle2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundles_all_allowed_regex_disallowed_denied.cf0000644000000000000000000000232415010704253033736 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/22_cf-runagent/serialbody common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_all_allowed_regex_disallowed.22013.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22013 is bundles_all_allowed_regex_disallowed.22013.srv run_runagent("-H 127.0.0.1:22013 --remote-bundles bundle1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_all_allowed_regex_disallowed.22013.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_bundle1_denied_1.cf0000644000000000000000000000223315010704253030413 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22000 is cfruncommand_open.22000.srv run_runagent("-H 127.0.0.1:22000 --remote-bundles bundle1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_role2_denied_3.cf0000644000000000000000000000230715010704253031214 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22009 is allroles_nonroot_role2_root_allowed.22009.srv run_runagent("-H 127.0.0.1:22009 -D role1,role2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_role2_admitted_2.cf0000644000000000000000000000265315010704253031562 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role1,role2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22008 is role1_role2_root_allowed.22008.srv run_runagent("-H 127.0.0.1:22008 -D role1,role2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role2_admitted_2.cf0000644000000000000000000000270015010704253030451 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22009 is allroles_nonroot_role2_root_allowed.22009.srv run_runagent("-H 127.0.0.1:22009 -D role2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/allroles_nonroot_role2_root_allowed.22009.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_no_access.22004.srv0000644000000000000000000000167015010704253030475 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22004"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: # ACCESS IS DENIED "$(G.write_args_sh)" deny => { "127.0.0.1", "::1" }; # Authorize "root" users to activate all classes # roles: # ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/ns2_bundle2_ns1_role2_only_allowed.22015.srv0000644000000000000000000000202315010704253032550 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22015"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; "ns2:bundle2" admit_ips => { "127.0.0.1", "::1" }, resource_type => "bundle"; # Authorize "root" user to activate only "role2" class roles: "ns1:role2" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_denied_2.cf0000644000000000000000000000231215010704253030104 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role12_root_allowed.22007.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22007 is role12_root_allowed.22007.srv # It allows "role12" but should disallow "role1" run_runagent("-H 127.0.0.1:22007 -D role1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role12_root_allowed.22007.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_bundle2_admitted.cf0000644000000000000000000000270515010704253030543 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "--bundlesequence bundle2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 --remote-bundles bundle2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_argv0_quoted.22014.srv0000644000000000000000000000176715010704253031150 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22014"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; # Make sure that if argv0 is quoted, it still is executed properly. cfruncommand => "\"$(G.write_args_sh)\" $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to activate all classes # roles: # ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_admitted_1.cf0000644000000000000000000000261515010704253030454 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role1"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22005 is role1_root_allowed.22005.srv run_runagent("-H 127.0.0.1:22005 -D role1 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_no_access_2.cf0000644000000000000000000000233415010704253030024 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_no_access.22003.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22003 is cfruncommand_no_access.22003.srv run_runagent("-H 127.0.0.1:22003 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there, since cfruncommand # invocation from cf-serverd should have been denied. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_no_access.22003.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_role2_denied_1.cf0000644000000000000000000000231415010704253031210 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22005 is role1_root_allowed.22005.srv # It allows "role1" but should disallow "role2" run_runagent("-H 127.0.0.1:22005 -D role1,role2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_root_allowed.22005.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-B_specialchars_denied.cf0000644000000000000000000000226315010704253031305 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_roles_all_allowed.22011.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22011 is bundles_roles_all_allowed.22011.srv run_runagent("-H 127.0.0.1:22011 --remote-bundles bundle@ $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_roles_all_allowed.22011.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_argv0_quoted.cf0000644000000000000000000000262115010704253030245 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", ""); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_argv0_quoted.22014.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22014 is cfruncommand_argv0_quoted.22014.srv run_runagent("-H 127.0.0.1:22014 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_argv0_quoted.22014.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/role1_root_allowed.22005.srv0000644000000000000000000000165515010704253027604 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22005"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to only activate class "role1" roles: "role1" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/empty_config.runagent.cf.sub0000644000000000000000000000061715010704253030211 0ustar00rootroot00000000000000# # Uncomment if you want to test the classic protocol. The code paths for # EXEC on cf-serverd have been unified so it should not make any # difference. # #body common control #{ # protocol_version => "classic"; #} body runagent control { # A list of hosts to contact when using cf-runagent. # In the acceptance tests we give the list of hosts on the command line. hosts => { }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_no_access_3.cf0000644000000000000000000000233415010704253030025 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_no_access.22004.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22004 is cfruncommand_no_access.22004.srv run_runagent("-H 127.0.0.1:22004 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there, since cfruncommand # invocation from cf-serverd should have been denied. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_no_access.22004.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_role2_denied_2.cf0000644000000000000000000000234115010704253031211 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role12_root_allowed.22007.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22007 is role12_root_allowed.22007.srv # It allows "role12" but should disallow both "role1" and "role2" run_runagent("-H 127.0.0.1:22007 -D role1,role2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role12_root_allowed.22007.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1-B_bundle1_admitted_1.cf0000644000000000000000000000272415010704253032246 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role1 --bundlesequence bundle1"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundles_roles_all_allowed.22011.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22010 is bundles_roles_all_allowed.22011.srv run_runagent("-H 127.0.0.1:22011 -D role1 --remote-bundles bundle1 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundles_roles_all_allowed.22011.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_-D_role2_admitted.cf0000644000000000000000000000265615010704253031664 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", "-D role1,role2"); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22008 is role1_role2_root_allowed.22008.srv run_runagent("-H 127.0.0.1:22008 -D role1 -D role2 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/role1_role2_root_allowed.22008.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_relative_paths_disallowed.srv0000644000000000000000000000162115010704253033307 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22001"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "root" }; cfruncommand => "../../../../../../../../../bin/echo blah"; } ######################################################### bundle server access_rules() { access: "/bin/echo" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to activate all classes # roles: # ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/allroles_root_allowed.22006.srv0000644000000000000000000000164315010704253030375 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22006"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to activate all classes roles: ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role2_-B_bundle1_denied.cf0000644000000000000000000000227715010704253031626 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 -D role2 --remote-bundles bundle1 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/role1_role2_root_allowed.22008.srv0000644000000000000000000000174015010704253030705 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22008"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to only activate classes "role1" and "role2" roles: "role1" authorize => { "root" }; "role2" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/cfruncommand_open.cf0000644000000000000000000000257115010704253026612 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Expected output in the exec_args.txt file "any" usebundle => file_make("$(G.testdir)/expected_args.txt", ""); # Ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10404" }; vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22000 is cfruncommand_open.22000.srv run_runagent("-H 127.0.0.1:22000 $(runagent_cf)"); } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testdir)/expected_args.txt", "$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/cfruncommand_open.22000.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/bundles_roles_all_allowed.22011.srv0000644000000000000000000000177515010704253031207 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22011"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; ".*" admit_ips => { "127.0.0.1", "::1" }, resource_type => "bundle"; # Authorize "root" users to activate all classes roles: ".*" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/runagent_-D_role1_-B_bundle2_denied.cf0000644000000000000000000000227715010704253031626 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # ensure execution output file is not there "any" usebundle => dcs_fini("$(G.testdir)/exec_args.txt"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } bundle agent test { vars: "runagent_cf" string => "$(this.promise_dirname)/empty_config.runagent.cf.sub"; methods: "any" usebundle => # Port 22012 is bundle2_role2_only_allowed.22012.srv run_runagent("-H 127.0.0.1:22012 -D role1 --remote-bundles bundle2 $(runagent_cf)"); } bundle agent check { # Execution output file should still not be there. methods: "any" usebundle => dcs_passif_file_absent("$(G.testdir)/exec_args.txt", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/bundle2_role2_only_allowed.22012.srv"); } cfengine-3.24.2/tests/acceptance/22_cf-runagent/serial/allroles_nonroot_role2_root_allowed.22009.srv0000644000000000000000000000174015010704253033257 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "22009"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # Authorize "root" users to execute cfruncommand allowusers => { "blah", "root" }; cfruncommand => "$(G.write_args_sh) $(G.testdir)/exec_args.txt"; } ######################################################### bundle server access_rules() { access: "$(G.write_args_sh)" admit_ips => { "127.0.0.1", "::1" }; # Authorize "root" users to only activate classes "role1" and "role2" roles: ".*" authorize => { "nonroot" }; "role2" authorize => { "root" }; } cfengine-3.24.2/tests/acceptance/23_failsafe/0000755000000000000000000000000015010704253020661 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/23_failsafe/preexisting_failsafe_preserved.failsafe.cf.sub0000644000000000000000000000041415010704253032005 0ustar00rootroot00000000000000# My custom minimal failsafe, only touches a file in $(sys.inputdir) body common control { bundlesequence => { "main" }; } bundle agent main { vars: "outfile" string => "$(sys.inputdir)/failsafe_output.txt"; files: "$(outfile)" create => true; } cfengine-3.24.2/tests/acceptance/23_failsafe/invalid_syntax.cf.sub0000644000000000000000000000025415010704253025020 0ustar00rootroot00000000000000#INVALID POLICY SYNTAX! body common control { bundlesequence => { "test" }; } bundle agent test { my_non_existing_promise_type: "non_existing" => "not_there"; } cfengine-3.24.2/tests/acceptance/23_failsafe/preexisting_failsafe_preserved.cf0000644000000000000000000000171115010704253027445 0ustar00rootroot00000000000000# Test that failsafe.cf is not created when it exists body common control { inputs => { "../default.cf.sub", "../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Remove the custom failsafe output file "any" usebundle => dcs_fini("$(sys.inputdir)/failsafe_output.txt"); files: "$(sys.inputdir)/failsafe.cf" create => "true", perms => m("600"), copy_from => dcs_sync("$(this.promise_dirname)/preexisting_failsafe_preserved.failsafe.cf.sub"); } bundle agent test { commands: "$(sys.cf_agent) -f $(this.promise_dirname)/invalid_syntax.cf.sub"; } bundle agent check { methods: "any" usebundle => # Verify that the custom failsafe.cf did run and created the # file that we removed earlier. dcs_passif_fileexists("$(sys.inputdir)/failsafe_output.txt", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/23_failsafe/failsafe_created_on_parse_error.cf0000644000000000000000000000203415010704253027532 0ustar00rootroot00000000000000# Test that failsafe.cf is created when dosn't exist body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: # Remove any failsafe.cf "any" usebundle => dcs_fini("$(sys.inputdir)/failsafe.cf"); classes: "failsafe_before_test_not_exists" not => fileexists("$(sys.inputdir)/failsafe.cf"), scope => "namespace"; } bundle agent test { commands: "$(sys.cf_agent) -f $(this.promise_dirname)/invalid_syntax.cf.sub"; # TODO this sub-agent fails to run invalid_syntax.cf and writes # failsafe.cf, which then executes. The execute bit is # redundant, can we avoid it? } bundle agent check { classes: "failsafe_after_test_exists" expression => fileexists("$(sys.inputdir)/failsafe.cf"); "ok" expression => "failsafe_after_test_exists.failsafe_before_test_not_exists"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/07_packages/0000755000000000000000000000000015010704253020667 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/list-architecture.cf0000644000000000000000000000430215010704253024633 0ustar00rootroot00000000000000# # Test matching packages with no explicit default architecture set, but with # architecture reported by the list of installed packages. # # List of installed packages contains a single package with explicit architecture set. # body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: # # Test that package with explicit architecture is matched by promise with no # package_architectures constraint, as no constraint means "any architecture". # "foobar" package_version => "1", package_policy => "addupdate", package_method => mock, classes => kept("ok_1"); # # Test that specifying architecture explicitly matches. # "foobar" package_version => "1", package_architectures => { "besm6" }, package_policy => "addupdate", package_method => mock, classes => kept("ok_2"); # # Test that specifying wrong architecture does not match. # "foobar" package_version => "1", package_architectures => { "aldan" }, package_policy => "addupdate", package_method => mock, classes => fail("ok_3"); } body package_method mock { package_changes => "individual"; package_list_command => "$(G.printf) 'foobar-1-besm6'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-([\S]+)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body classes kept(classname) { promise_kept => { "$(classname)" }; } body classes fail(classname) { repair_failed => { "$(classname)" }; } bundle agent check { classes: "ok" and => { "ok_1", "ok_2", "ok_3" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/001.cf0000644000000000000000000000476715010704253021517 0ustar00rootroot00000000000000####################################################### # # Test add a package # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "G", "g", default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } bundle common g { classes: "mpm_declared" not => strcmp(getenv("MOCK_PACKAGE_MANAGER", "65535"), ""); vars: mpm_declared:: "pm" string => getenv("MOCK_PACKAGE_MANAGER", "65535"); !mpm_declared:: "pm" string => "$(G.mock_package_manager)"; } ####################################################### bundle agent init { commands: "$(g.pm) --clear-installed"; "$(g.pm) --clear-available"; "$(g.pm) --populate-available imagisoft:1.0i:teapot"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "name" string => "imagisoft"; "version" string => "1.0i"; "arch" string => "teapot"; packages: "$(name):$(version):$(arch)" package_policy => "add", package_method => mock, classes => test_set_class("pass","fail"); } body package_method mock { package_changes => "individual"; package_list_command => "$(g.pm) --list-installed"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(g.pm) --add "; package_update_command => "$(g.pm) --update "; package_delete_command => "$(g.pm) --delete "; package_verify_command => "$(g.pm) --verify "; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { vars: "pkgs" string => execresult("$(g.pm) --list-installed", "noshell"); classes: "has_pkg" expression => regcmp("imagisoft:1\.0i:teapot", "$(pkgs)"); "ok" expression => "pass.!fail.has_pkg"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes successfully_executed(class) { kept_returncodes => { "0" }; promise_kept => { "$(class)" }; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/800.cf0000644000000000000000000000264615010704253021520 0ustar00rootroot00000000000000####################################################### # Test that classes are set on individual installation (Mantis #829) ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: "a:b:c" package_policy => "add", package_method => mock, if => "!a", classes => ok("a"); "d:e:f" package_policy => "add", package_method => mock, if => "!d", classes => ok("d"); } body package_method mock { package_changes => "individual"; package_list_command => "$(G.true)"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes ok(classname) { promise_repaired => { "$(classname)" }; promise_kept => { "$(classname)" }; } bundle agent check { reports: a.d:: "$(this.promise_filename) Pass"; !a|!d:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/default-list-architectures-same.cf0000644000000000000000000000451615010704253027372 0ustar00rootroot00000000000000# # Test matching packages with explicit default architecture set and the same # architecture in list of installed packages. Should work similar to the case # there are no architectures at all. # # List of installed packages contains a single package with the default # architecture specified. # body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: # # Test that package is matched by a promise with no package_architectures # constraint, as it means "any architecture" # "foobar" package_version => "1", package_policy => "addupdate", package_method => mock, classes => kept("ok_1"); # # Test that specifying proper architecture explicitly matches the package. # "foobar" package_version => "1", package_architectures => { "setun" }, package_policy => "addupdate", package_method => mock, classes => kept("ok_2"); # # Test that specifying wrong architecture explicitly does not match the package. # "foobar" package_version => "1", package_architectures => { "aldan" }, package_policy => "addupdate", package_method => mock, classes => fail("ok_3"); } body package_method mock { package_changes => "individual"; package_default_arch_command => "$(G.printf) 'setun'"; package_list_command => "$(G.printf) 'foobar-1-setun'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-([\S]+)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body classes kept(classname) { promise_kept => { "$(classname)" }; } body classes fail(classname) { repair_failed => { "$(classname)" }; } bundle agent check { classes: "ok" and => { "ok_1", "ok_2", "ok_3" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/dependency-checks-package_verify_command.cf0000644000000000000000000000642415010704253031236 0ustar00rootroot00000000000000####################################################### # Test for presence of "main" attribute, given the presence of "dependent" # attributes, which do not make sense without the "main" attribute. # # main attribute: package_verify_command # dependent attributes: # package_noverify_regex # package_noverify_returncode ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "bash-1.0-amd64" package_policy => "add", package_method => mock_no_verify_command_noverify_regex, classes => test_set_class("no_verify_command_noverify_regex_succ", "no_verify_command_noverify_regex_fail"); "bash-1.0-i386" package_policy => "add", package_method => mock_no_verify_command_noverify_returncode, classes => test_set_class("no_verify_command_noverify_returncode_succ", "no_verify_command_noverify_returncode_fail"); } body package_method mock_no_verify_command_noverify_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; # package_verify_command => "$(G.true)"; package_noverify_regex => "."; } body package_method mock_no_verify_command_noverify_returncode { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; # package_verify_command => "$(G.true)"; package_noverify_returncode => "-1"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "!no_verify_command_noverify_regex_succ", "no_verify_command_noverify_regex_fail", "!no_verify_command_noverify_returncode_succ", "no_verify_command_noverify_returncode_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/903.cf0000644000000000000000000000316715010704253021523 0ustar00rootroot00000000000000####################################################### # # Test missing package listing fails # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_unsupported" string => "windows"; packages: "a:b:c" package_policy => "add", package_method => mock, classes => test_set_class("fail","ok"); } body package_method mock { package_changes => "individual"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { reports: ok.!fail:: "$(this.promise_filename) Pass"; !ok|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/dependency-checks-package_patch_command.cf0000644000000000000000000001036015010704253031023 0ustar00rootroot00000000000000####################################################### # Test for presence of "main" attribute, given the presence of "dependent" # attributes, which do not make sense without the "main" attribute. # # main attribute: package_patch_command # dependent attributes: # package_patch_arch_regex # package_patch_name_regex # package_patch_version_regex ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: "bash-1.0-amd64" package_policy => "add", package_method => mock_no_patch_command_patch_arch_regex, classes => test_set_class("no_patch_command_patch_arch_regex_succ", "no_patch_command_patch_arch_regex_fail"); "bash-1.0-i386" package_policy => "add", package_method => mock_no_patch_command_patch_name_regex, classes => test_set_class("no_patch_command_patch_name_regex_succ", "no_patch_command_patch_name_regex_fail"); "bash-1.0-sparc" package_policy => "add", package_method => mock_no_patch_command_patch_version_regex, classes => test_set_class("no_patch_command_patch_version_regex_succ", "no_patch_command_patch_version_regex_fail"); } body package_method mock_no_patch_command_patch_arch_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; package_patch_arch_regex => ""; } body package_method mock_no_patch_command_patch_name_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; package_patch_name_regex => ""; } body package_method mock_no_patch_command_patch_version_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; package_patch_version_regex => ""; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "!no_patch_command_patch_arch_regex_succ", "no_patch_command_patch_arch_regex_fail", "!no_patch_command_patch_name_regex_succ", "no_patch_command_patch_name_regex_fail", "!no_patch_command_patch_version_regex_succ", "no_patch_command_patch_version_regex_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/warn-package-delete.cf.sub0000644000000000000000000000203015010704253025564 0ustar00rootroot00000000000000####################################################### # # Test delete a package # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "test_warn_delete_pkg" }; version => "1.0"; } ####################################################### bundle agent test_warn_delete_pkg { packages: "bash" package_policy => "delete", package_method => mock_warn_delete_pkg, package_select => ">=", package_version => "4.2.8", package_architectures => {"x86_64"}; } body package_method mock_warn_delete_pkg { package_changes => "individual"; package_list_command => "$(G.printf) 'bash-4.2.8-x86_64'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.false)"; } cfengine-3.24.2/tests/acceptance/07_packages/dry-run-install.cf.sub0000644000000000000000000000170715010704253025042 0ustar00rootroot00000000000000# Test that if the action => 'warn' is specified, no packages are installed. body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "test" }; version => "1.0"; } bundle agent test { packages: "bash" package_policy => "add", package_method => mock_do_not_install_pkg, package_select => ">=", package_version => "1.0", action => dryrun; } body action dryrun { action_policy => "warn"; } body package_method mock_do_not_install_pkg { package_changes => "individual"; package_list_command => "$(G.true)"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_installed_regex => ".*"; package_add_command => "/bin/should-not-be-called"; package_update_command => "/bin/should-not-be-called"; package_delete_command => "/bin/should-not-be-called"; package_verify_command => "/bin/should-not-be-called"; } cfengine-3.24.2/tests/acceptance/07_packages/900.cf0000644000000000000000000000233615010704253021515 0ustar00rootroot00000000000000####################################################### # # Test no-op works # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "a:b:c" package_policy => "add", package_method => mock; } body package_method mock { package_changes => "individual"; package_list_command => "$(G.true)"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } ####################################################### bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/upgrade-package.cf0000644000000000000000000000245215010704253024224 0ustar00rootroot00000000000000# Tests that package upgrade works properly body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_needs_work" string => "windows"; vars: "dummy" string => "dummy"; } body package_method yum_rpm { package_changes => "individual"; package_list_command => "$(G.printf) 'which 1 i386'"; package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.false)"; } bundle agent test { packages: "which" package_policy => "addupdate", package_select => "==", package_version => "2", package_method => yum_rpm, classes => if_repaired("whichrepaired"); } bundle agent check { reports: whichrepaired:: "$(this.promise_filename) Pass"; !whichrepaired:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/default-list-architectures-different.cf0000644000000000000000000000515515010704253030413 0ustar00rootroot00000000000000# # Test matching packages with explicit default architecture set and the same # architecture in list of installed packages. Should work similar to the case # there are no architectures at all. # # List of installed packages contains a single package with the default # architecture specified. # body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: # # Test that package is matched by a promise with no package_architectures # constraint, as it means "any architecture" # "foobar" package_version => "1", package_policy => "addupdate", package_method => mock, classes => kept("ok_1"); # # Test that specifying default architecture does not match the # "foobar" package_version => "1", package_architectures => { "setun" }, package_policy => "addupdate", package_method => mock, classes => fail("ok_2"); # # Test that specifying proper architecture explicitly matches the package. # "foobar" package_version => "1", package_architectures => { "besm6" }, package_policy => "addupdate", package_method => mock, classes => kept("ok_3"); # # Test that specifying wrong architecture explicitly does not match the package. # "foobar" package_version => "1", package_architectures => { "aldan" }, package_policy => "addupdate", package_method => mock, classes => fail("ok_4"); } body package_method mock { package_changes => "individual"; package_default_arch_command => "$(G.printf) 'setun'"; package_list_command => "$(G.printf) 'foobar-1-besm6'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-([\S]+)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body classes kept(classname) { promise_kept => { "$(classname)" }; } body classes fail(classname) { repair_failed => { "$(classname)" }; } bundle agent check { classes: "ok" and => { "ok_1", "ok_2", "ok_3", "ok_4"}; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/dry-run-install.cf0000644000000000000000000000136515010704253024252 0ustar00rootroot00000000000000# Test that if the action => 'warn' is specified, no packages are installed. body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kv -f $(this.promise_filename).sub | $(G.grep) should-not-be-called", "useshell"); } bundle agent check { classes: "ok" not => regcmp(".*should-not-be-called.*", "$(test.subout)"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/no-architectures.cf0000644000000000000000000000352215010704253024462 0ustar00rootroot00000000000000# # Test matching packages with no explicit default architecture set and no # architectures in list of installed packages. # # List of installed packages contains a single package with no architecture # specified. # body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: # # Test that package is matched by a promise with no package_architectures # constraint. # "foobar" package_version => "1", package_policy => "addupdate", package_method => mock, classes => kept("ok_1"); # # Test that specifying architecture explicitly does not match the package with # default architecture. # "foobar" package_version => "1", package_architectures => { "aldan" }, package_policy => "addupdate", package_method => mock, classes => fail("ok_2"); } body package_method mock { package_changes => "individual"; package_list_command => "$(G.printf) 'foobar-1'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([\S+])"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body classes kept(classname) { promise_kept => { "$(classname)" }; } body classes fail(classname) { repair_failed => { "$(classname)" }; } bundle agent check { classes: "ok" and => { "ok_1", "ok_2" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/repositories.cf.sub0000644000000000000000000002306615010704253024527 0ustar00rootroot00000000000000# Tests that package upgrade works properly body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "init", "test" }; version => "1.0"; } bundle agent init { methods: "make filerepo" usebundle => file_make($(G.testfile), ""); } body package_method test_method_filerepo(currentdir) { package_changes => "individual"; package_list_command => "$(G.cat) $(currentdir)/test_repository/installed.txt | $(G.grep) 'i '"; package_installed_regex => "i .*"; package_list_name_regex => "^[ia] (\S+?)\s\S+?\s\S+$"; package_list_version_regex => "^[ia] \S+?\s(\S+?)\s\S+$"; package_list_arch_regex => "^[ia] \S+?\s\S+?\s(\S+)$"; # Normally one would use $(G.echo), but it messes up redirection when you have arguments # following the redirected filename on Windows, so use the stock "echo" in this case. package_add_command => "echo >>$(G.testfile) filerepo ADD"; package_update_command => "echo >>$(G.testfile) filerepo UPDATE"; package_delete_command => "echo >>$(G.testfile) filerepo DELETE"; package_file_repositories => { translatepath("$(currentdir)/test_repository") }; package_name_convention => "$(name)-$(version).$(arch).rpm"; } bundle agent test { vars: "currentdir" string => translatepath("$(this.promise_dirname)"); packages: "install-exact-version" package_policy => "addupdate", package_select => "==", package_version => "2.2.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "update-to-exact-version" package_policy => "addupdate", package_select => "==", package_version => "2.2.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "delete-exact-version" package_policy => "delete", package_select => "==", package_version => "2.2.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "install-lessorequal-version" package_policy => "addupdate", package_select => "<=", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "update-to-lessorequal-version" package_policy => "addupdate", package_select => "<=", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "install-lessthan-version" package_policy => "addupdate", package_select => "<", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "update-to-lessthan-version" package_policy => "addupdate", package_select => "<", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "install-greaterorequal-version" package_policy => "addupdate", package_select => ">=", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "update-to-greaterorequal-version" package_policy => "addupdate", package_select => ">=", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "update-to-greaterorequal-version-already-greater-installed" package_policy => "addupdate", package_select => ">=", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "install-greaterthan-version" package_policy => "addupdate", package_select => ">", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "update-to-greaterthan-version" package_policy => "addupdate", package_select => ">", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "update-to-greaterthan-version-already-greater-installed" package_policy => "addupdate", package_select => ">", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-install-exact-version" package_policy => "addupdate", package_select => "==", package_version => "2.1.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-update-to-exact-version" package_policy => "addupdate", package_select => "==", package_version => "2.1.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-delete-exact-version" package_policy => "delete", package_select => "==", package_version => "2.1.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-install-lessorequal-version" package_policy => "addupdate", package_select => "<=", package_version => "2.1.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-update-to-lessorequal-version" package_policy => "addupdate", package_select => "<=", package_version => "2.1.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-install-lessthan-version" package_policy => "addupdate", package_select => "<", package_version => "2.1.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-update-to-lessthan-version" package_policy => "addupdate", package_select => "<", package_version => "2.1.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-install-greaterorequal-version" package_policy => "addupdate", package_select => ">=", package_version => "2.4.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-update-to-greaterorequal-version" package_policy => "addupdate", package_select => ">=", package_version => "2.4.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-install-greaterthan-version" package_policy => "addupdate", package_select => ">", package_version => "2.4.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "mismatch-update-to-greaterthan-version" package_policy => "addupdate", package_select => ">", package_version => "2.4.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-install-exact-version" package_policy => "addupdate", package_select => "==", package_version => "2.2.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-update-to-exact-version" package_policy => "addupdate", package_select => "==", package_version => "2.2.3", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-install-lessorequal-version" package_policy => "addupdate", package_select => "<=", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-update-to-lessorequal-version" package_policy => "addupdate", package_select => "<=", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-install-lessthan-version" package_policy => "addupdate", package_select => "<", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-update-to-lessthan-version" package_policy => "addupdate", package_select => "<", package_version => "2.4.5", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-install-greaterorequal-version" package_policy => "addupdate", package_select => ">=", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-update-to-greaterorequal-version" package_policy => "addupdate", package_select => ">=", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-install-greaterthan-version" package_policy => "addupdate", package_select => ">", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); "missing-update-to-greaterthan-version" package_policy => "addupdate", package_select => ">", package_version => "2.0.1", package_architectures => { "i386" }, package_method => test_method_filerepo($(currentdir)); } cfengine-3.24.2/tests/acceptance/07_packages/904.cf0000644000000000000000000000274315010704253021523 0ustar00rootroot00000000000000####################################################### # # Test missing basic package commands # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "a:b:c" package_policy => "add", package_method => mock, classes => test_set_class("fail","ok"); } body package_method mock { package_changes => "individual"; package_list_command => "$(G.true)"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { reports: ok.!fail:: "$(this.promise_filename) Pass"; !ok|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/default_package_module.cf.expected0000644000000000000000000000014115010704253027441 0ustar00rootroot00000000000000Name=first_pkg Version=1.0 Architecture=generic Name=second_pkg Version=1.0 Architecture=generic cfengine-3.24.2/tests/acceptance/07_packages/custom-version-compare.cf0000644000000000000000000000632115010704253025624 0ustar00rootroot00000000000000####################################################### # Test custom version comparator ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_needs_work" string => "windows"; packages: # Test that overriding 'equal' works. Installed is 01, requested is 1. Overridden eq compares numeric values. "bash-1-amd64" package_policy => "addupdate", package_method => mock_zeroone_installed, classes => test_set_class("custom_eq_succ", "custom_eq_fail"); "bash-2-amd64" package_policy => "addupdate", package_method => mock_zeroone_installed_can_install, classes => test_set_class("custom_eq_2_succ", "custom_eq_2_fail"); } body package_method mock_zeroone_installed { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-01-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; package_version_less_command => "test $(v1) -lt $(v2)"; package_version_equal_command => "test $(v1) -eq $(v2)"; } body package_method mock_zeroone_installed_can_install { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-01-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; package_version_less_command => "test $(v1) -lt $(v2)"; package_version_equal_command => "test $(v1) -eq $(v2)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "custom_eq_succ", "!custom_eq_fail", "custom_eq_2_succ", "!custom_eq_2_fail" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/902.cf0000644000000000000000000000316215010704253021515 0ustar00rootroot00000000000000####################################################### # # Test missing name regex fails # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_unsupported" string => "windows"; packages: "a:b:c" package_policy => "add", package_method => mock, classes => test_set_class("fail","ok"); } body package_method mock { package_changes => "individual"; package_list_command => "$(G.true)"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { reports: ok.!fail:: "$(this.promise_filename) Pass"; !ok|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/905.cf0000644000000000000000000000273515010704253021525 0ustar00rootroot00000000000000####################################################### # # Test missing "installed" regex # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "a:b:c" package_policy => "add", package_method => mock, classes => test_set_class("fail","ok"); } body package_method mock { package_changes => "individual"; package_list_command => "$(G.true)"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { reports: ok.!fail:: "$(this.promise_filename) Pass"; !ok|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/package_module_interpreter.cf.expected0000644000000000000000000000014115010704253030360 0ustar00rootroot00000000000000Name=first_pkg Version=1.0 Architecture=generic Name=second_pkg Version=1.0 Architecture=generic cfengine-3.24.2/tests/acceptance/07_packages/dependency-checks-package_list_command.cf0000644000000000000000000001336615010704253030710 0ustar00rootroot00000000000000####################################################### # Test for presence of "main" attribute, given the presence of "dependent" # attributes, which do not make sense without the "main" attribute. # # main attribute: package_list_command # dependent attributes: # package_installed_regex # package_list_arch_regex # package_list_name_regex # package_list_version_regex # package_multiline_start ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_unsupported" string => "windows"; packages: "bash-1.0-amd64" package_policy => "add", package_method => mock_no_list_command_package_installed_regex, classes => test_set_class("no_list_command_package_installed_regex_succ", "no_list_command_package_installed_regex_fail"); "bash-2.0-amd64" package_policy => "add", package_method => mock_no_list_command_package_arch_regex, classes => test_set_class("no_list_command_package_arch_regex_succ", "no_list_command_package_arch_regex_fail"); "bash-1.0-i386" package_policy => "add", package_method => mock_no_list_command_package_name_regex, classes => test_set_class("no_list_command_package_name_regex_succ", "no_list_command_package_name_regex_fail"); "bash-1.0-sparc" package_policy => "add", package_method => mock_no_list_command_package_version_regex, classes => test_set_class("no_list_command_package_version_regex_succ", "no_list_command_package_version_regex_fail"); } body package_method mock_no_list_command_package_version_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_file_repositories => { "/package/repos1", "package/repos2" }; # but no package_list_command! # package_installed_regex => ".*"; # package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; # package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; # package_multiline_start => package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock_no_list_command_package_name_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_file_repositories => { "/package/repos1", "package/repos2" }; # but no package_list_command! # package_installed_regex => ".*"; # package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_name_regex => "^([^-]+)"; # package_list_version_regex => "^[^-]+-([^-]+)"; # package_multiline_start => package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock_no_list_command_package_arch_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_file_repositories => { "/package/repos1", "package/repos2" }; # but no package_list_command! # package_installed_regex => ".*"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; # package_list_name_regex => "^([^-]+)"; # package_list_version_regex => "^[^-]+-([^-]+)"; # package_multiline_start => package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock_no_list_command_package_installed_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_file_repositories => { "/package/repos1", "package/repos2" }; # but no package_list_command! package_installed_regex => ".*"; # package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; # package_list_name_regex => "^([^-]+)"; # package_list_version_regex => "^[^-]+-([^-]+)"; # package_multiline_start => package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "!no_list_command_package_installed_regex_succ", "no_list_command_package_installed_regex_fail", "!no_list_command_package_arch_regex_succ", "no_list_command_package_arch_regex_fail", "!no_list_command_package_name_regex_succ", "no_list_command_package_name_regex_fail", "!no_list_command_package_version_regex_succ", "no_list_command_package_version_regex_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/has-default-no-list-architectures.cf0000644000000000000000000000440015010704253027622 0ustar00rootroot00000000000000# # Test matching packages with explicit default architecture set and no # architecture in list of installed packages. Should work similar to the case # there are no architectures at all. # # List of installed packages contains a single package with no architecture # specified. # body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: # # Test that package is matched by a promise with no package_architectures # constraint, as it means "any architecture" # "foobar" package_version => "1", package_policy => "addupdate", package_method => mock, classes => kept("ok_1"); # # Test that specifying proper architecture explicitly matches the package. # "foobar" package_version => "1", package_architectures => { "setun" }, package_policy => "addupdate", package_method => mock, classes => kept("ok_2"); # # Test that specifying wrong architecture explicitly does not match the package. # "foobar" package_version => "1", package_architectures => { "aldan" }, package_policy => "addupdate", package_method => mock, classes => fail("ok_3"); } body package_method mock { package_changes => "individual"; package_default_arch_command => "$(G.printf) 'setun'"; package_list_command => "$(G.printf) 'foobar-1'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([\S+])"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body classes kept(classname) { promise_kept => { "$(classname)" }; } body classes fail(classname) { repair_failed => { "$(classname)" }; } bundle agent check { classes: "ok" and => { "ok_1", "ok_2", "ok_3" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/003.cf0000644000000000000000000000477715010704253021522 0ustar00rootroot00000000000000####################################################### # # Test adding a package using separate package_version attribute # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "G", "g", default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } bundle common g { classes: "mpm_declared" not => strcmp(getenv("MOCK_PACKAGE_MANAGER", "65535"), ""); vars: mpm_declared:: "pm" string => getenv("MOCK_PACKAGE_MANAGER", "65535"); !mpm_declared:: "pm" string => "$(G.mock_package_manager)"; } ####################################################### bundle agent init { commands: "$(g.pm) --clear-installed"; "$(g.pm) --clear-available"; "$(g.pm) --populate-available imagisoft:1.0i:x666"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "name" string => "imagisoft"; packages: "$(name)" package_policy => "add", package_method => mock, package_version => "1.0i", classes => test_set_class("pass","fail"); } body package_method mock { package_changes => "individual"; package_list_command => "$(g.pm) --list-installed"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_installed_regex => "^[^:]*"; package_add_command => "$(g.pm) --add "; package_update_command => "$(g.pm) --update "; package_delete_command => "$(g.pm) --delete "; package_verify_command => "$(g.pm) --verify "; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { vars: "pkgs" string => execresult("$(g.pm) --list-installed", "noshell"); classes: "has_pkg" expression => regcmp("imagisoft:1\.0i:x666", "$(pkgs)"); "ok" expression => "pass.!fail.has_pkg"; reports: DEBUG.pass:: "pass"; DEBUG.has_pkg:: "has_pkg"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes successfully_executed(class) { kept_returncodes => { "0" }; promise_kept => { "$(class)" }; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/004.cf0000644000000000000000000000507415010704253021512 0ustar00rootroot00000000000000####################################################### # # Test adding *second* package # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "G", "g", default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } bundle common g { classes: "mpm_declared" not => strcmp(getenv("MOCK_PACKAGE_MANAGER", "65535"), ""); vars: mpm_declared:: "pm" string => getenv("MOCK_PACKAGE_MANAGER", "65535"); !mpm_declared:: "pm" string => "$(G.mock_package_manager)"; } ####################################################### bundle agent init { commands: "$(g.pm) --clear-installed"; "$(g.pm) --clear-available"; "$(g.pm) --populate-available imagisoft:1.0i:x666"; "$(g.pm) --populate-available bluesky:3.1:x666"; "$(g.pm) --add bluesky:*:*"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "name" string => "imagisoft"; packages: "$(name)" package_policy => "add", package_method => mock, package_version => "1.0i", classes => test_set_class("pass","fail"); } body package_method mock { package_changes => "individual"; package_list_command => "$(g.pm) --list-installed"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_installed_regex => "^[^:]*"; package_add_command => "$(g.pm) --add "; package_update_command => "$(g.pm) --update "; package_delete_command => "$(g.pm) --delete "; package_verify_command => "$(g.pm) --verify "; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { vars: "pkgs" string => execresult("$(g.pm) --list-installed", "noshell"); classes: "has_pkg" expression => regcmp(".*imagisoft:1\.0i:x666.*", "$(pkgs)"); "ok" expression => "pass.!fail.has_pkg"; reports: DEBUG.pass:: "pass"; DEBUG.has_pkg:: "has_pkg"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes successfully_executed(class) { kept_returncodes => { "0" }; promise_kept => { "$(class)" }; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/907.cf0000644000000000000000000000240315010704253021517 0ustar00rootroot00000000000000####################################################### # # Test no-op with with "package_repositories" works # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "a:b:c" package_policy => "add", package_method => mock; } body package_method mock { package_changes => "individual"; package_file_repositories => { "/tmp" }; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } ####################################################### bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/default_package_module.cf.module0000644000000000000000000000272415010704253027136 0ustar00rootroot00000000000000#!/bin/sh set -e remove_prefix() { echo "$1" | sed "s/$2//" } case "$1" in supports-api-version) echo 1 ;; get-package-data) while read line; do case "$line" in File=*) echo PackageType=repo echo Name=`remove_prefix "${line}" "File="` ;; *) true ;; esac done ;; list-installed) while read line; do case "$line" in options=*) OUTPUT=`remove_prefix "${line}" "options="` ;; *) exit 1 ;; esac done if [ -f "$OUTPUT" ]; then cat "$OUTPUT" fi ;; list-*) # Drain input. cat > /dev/null ;; repo-install) while read line; do case "$line" in options=*) OUTPUT=`remove_prefix "${line}" "options="` ;; Name=*) NAME=`remove_prefix "${line}" "Name="` ;; *) exit 1 ;; esac done echo "Name=$NAME" >> "$OUTPUT" echo "Version=1.0" >> "$OUTPUT" echo "Architecture=generic" >> "$OUTPUT" ;; *) exit 1 ;; esac exit 0 cfengine-3.24.2/tests/acceptance/07_packages/005.cf0000644000000000000000000000522315010704253021507 0ustar00rootroot00000000000000####################################################### # # Test trying to actually specify versions of packages # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "G", "g", default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } bundle common g { classes: "mpm_declared" not => strcmp(getenv("MOCK_PACKAGE_MANAGER", "65535"), ""); vars: mpm_declared:: "pm" string => getenv("MOCK_PACKAGE_MANAGER", "65535"); !mpm_declared:: "pm" string => "$(G.mock_package_manager)"; } ####################################################### bundle agent init { commands: "$(g.pm) --clear-installed"; "$(g.pm) --clear-available"; "$(g.pm) --populate-available imagisoft:1.0i:x666"; "$(g.pm) --populate-available bluesky:3.1:x666"; "$(g.pm) --add bluesky:*:*"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "name" string => "imagisoft"; packages: "$(name)" package_policy => "add", package_method => mock, package_version => "1.0i", classes => test_set_class("pass","fail"); } body package_method mock { package_changes => "individual"; package_list_command => "$(g.pm) --list-installed"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_installed_regex => "^[^:]*"; package_add_command => "$(g.pm) --add "; package_update_command => "$(g.pm) --update "; package_delete_command => "$(g.pm) --delete "; package_verify_command => "$(g.pm) --verify "; package_name_convention => "$(name):$(version):$(arch)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { vars: "pkgs" string => execresult("$(g.pm) --list-installed", "noshell"); classes: "has_pkg" expression => regcmp(".*imagisoft:1\.0i:x666.*", "$(pkgs)"); "ok" expression => "pass.!fail.has_pkg"; reports: DEBUG.pass:: "pass"; DEBUG.has_pkg:: "has_pkg"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes successfully_executed(class) { kept_returncodes => { "0" }; promise_kept => { "$(class)" }; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/006.cf0000644000000000000000000000520415010704253021507 0ustar00rootroot00000000000000####################################################### # # Test trying to avoid parsing promiser # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "G", "g", default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } bundle common g { classes: "mpm_declared" not => strcmp(getenv("MOCK_PACKAGE_MANAGER", "65535"), ""); vars: mpm_declared:: "pm" string => getenv("MOCK_PACKAGE_MANAGER", "65535"); !mpm_declared:: "pm" string => "$(G.mock_package_manager)"; } ####################################################### bundle agent init { commands: "$(g.pm) --clear-installed"; "$(g.pm) --clear-available"; "$(g.pm) --populate-available imagisoft:1.0i:x666"; "$(g.pm) --populate-available bluesky:3.1:x666"; "$(g.pm) --add bluesky:*:*"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "name" string => "imagisoft"; packages: "$(name)" package_policy => "add", package_method => mock, package_version => "1.0i", classes => test_set_class("pass","fail"); } body package_method mock { package_changes => "individual"; package_list_command => "$(g.pm) --list-installed"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_installed_regex => "^[^:]*"; package_add_command => "$(g.pm) --add "; package_update_command => "$(g.pm) --update "; package_delete_command => "$(g.pm) --delete "; package_verify_command => "$(g.pm) --verify "; package_name_convention => "$(name):$(version):$(arch)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { vars: "pkgs" string => execresult("$(g.pm) --list-installed", "noshell"); classes: "has_pkg" expression => regcmp(".*imagisoft:1\.0i:x666.*", "$(pkgs)"); "ok" expression => "pass.!fail.has_pkg"; reports: DEBUG.pass:: "pass"; DEBUG.has_pkg:: "has_pkg"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes successfully_executed(class) { kept_returncodes => { "0" }; promise_kept => { "$(class)" }; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/dependency-checks-package_patch_list_command.cf0000644000000000000000000000421415010704253032057 0ustar00rootroot00000000000000####################################################### # Test for presence of "main" attribute, given the presence of "dependent" # attributes, which do not make sense without the "main" attribute. # # main attribute: package_patch_list_command # dependent attributes: # package_patch_installed_regex ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: "bash-1.0-amd64" package_policy => "add", package_method => mock_no_patch_list_command_patch_installed_regex, classes => test_set_class("no_patch_list_command_patch_installed_regex_succ", "no_patch_list_command_patch_installed_regex_fail"); } body package_method mock_no_patch_list_command_patch_installed_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; package_patch_installed_regex => ""; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "!no_patch_list_command_patch_installed_regex_succ", "no_patch_list_command_patch_installed_regex_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/package_module_path.cf.expected0000644000000000000000000000014115010704253026751 0ustar00rootroot00000000000000Name=first_pkg Version=1.0 Architecture=generic Name=second_pkg Version=1.0 Architecture=generic cfengine-3.24.2/tests/acceptance/07_packages/upgrade-package-version.cf0000644000000000000000000000250215010704253025703 0ustar00rootroot00000000000000# Tests that package upgrade works properly with "more than" version body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_needs_work" string => "windows"; vars: "dummy" string => "dummy"; } body package_method yum_rpm { package_changes => "individual"; package_list_command => "$(G.printf) 'which 1 i386'"; package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.false)"; } bundle agent test { packages: "which" package_policy => "addupdate", package_select => ">", package_version => "2", package_method => yum_rpm, classes => if_repaired("whichrepaired"); } bundle agent check { reports: whichrepaired:: "$(this.promise_filename) Pass"; !whichrepaired:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/package_module_path.cf.module0000644000000000000000000000272415010704253026446 0ustar00rootroot00000000000000#!/bin/sh set -e remove_prefix() { echo "$1" | sed "s/$2//" } case "$1" in supports-api-version) echo 1 ;; get-package-data) while read line; do case "$line" in File=*) echo PackageType=repo echo Name=`remove_prefix "${line}" "File="` ;; *) true ;; esac done ;; list-installed) while read line; do case "$line" in options=*) OUTPUT=`remove_prefix "${line}" "options="` ;; *) exit 1 ;; esac done if [ -f "$OUTPUT" ]; then cat "$OUTPUT" fi ;; list-*) # Drain input. cat > /dev/null ;; repo-install) while read line; do case "$line" in options=*) OUTPUT=`remove_prefix "${line}" "options="` ;; Name=*) NAME=`remove_prefix "${line}" "Name="` ;; *) exit 1 ;; esac done echo "Name=$NAME" >> "$OUTPUT" echo "Version=1.0" >> "$OUTPUT" echo "Architecture=generic" >> "$OUTPUT" ;; *) exit 1 ;; esac exit 0 cfengine-3.24.2/tests/acceptance/07_packages/repositories.cf0000644000000000000000000000466215010704253023740 0ustar00rootroot00000000000000# Tests that package upgrade works properly body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "d" string => "$(const.dirsep)"; # Due to shell rules, windows includes certain characters on certain commands, # while Unix does not. windows:: "q" string => '"'; "s" string => ' '; !windows:: "q" string => ''; "s" string => ''; methods: "make" usebundle => file_make("$(G.testfile).expected", " $(s)filerepo DELETE delete-exact-version-2.2.3.i386.rpm $(s)filerepo ADD $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)install-greaterthan-version-2.2.3.i386.rpm$(q) $(s)filerepo ADD $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)install-greaterorequal-version-2.2.3.i386.rpm$(q) $(s)filerepo ADD $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)install-lessthan-version-2.2.3.i386.rpm$(q) $(s)filerepo ADD $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)install-lessorequal-version-2.2.3.i386.rpm$(q) $(s)filerepo ADD $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)install-exact-version-2.2.3.i386.rpm$(q) $(s)filerepo UPDATE $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)update-to-greaterthan-version-already-greater-installed-2.2.3.i386.rpm$(q) $(s)filerepo UPDATE $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)update-to-greaterthan-version-2.2.3.i386.rpm$(q) $(s)filerepo UPDATE $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)update-to-greaterorequal-version-already-greater-installed-2.2.3.i386.rpm$(q) $(s)filerepo UPDATE $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)update-to-greaterorequal-version-2.2.3.i386.rpm$(q) $(s)filerepo UPDATE $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)update-to-lessthan-version-2.2.3.i386.rpm$(q) $(s)filerepo UPDATE $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)update-to-lessorequal-version-2.2.3.i386.rpm$(q) $(s)filerepo UPDATE $(q)$(G.cwd)$(d).$(d)07_packages$(d)test_repository$(d)update-to-exact-version-2.2.3.i386.rpm$(q)"); } bundle agent test { methods: "run" usebundle => dcs_runagent("$(this.promise_filename).sub"); } bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile)", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/default_package_module.cf0000644000000000000000000000241615010704253025650 0ustar00rootroot00000000000000# Based on 07_package/package_module_path.cf body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; package_module => test_module; # important! part of this specific test } bundle agent init { files: "$(sys.workdir)/modules/packages/." create => "true"; "$(sys.workdir)/modules/packages/test_module_script.sh" copy_from => local_cp("$(this.promise_filename).module"), perms => m("ugo+x"); } body package_module test_module { query_installed_ifelapsed => "60"; query_updates_ifelapsed => "14400"; default_options => { "$(G.testfile)" }; module_path => "$(sys.workdir)/modules/packages/test_module_script.sh"; } bundle agent test { meta: "description" string => "Test that a package with no attributes uses a configured common control package_module", meta => { "CFE-4408" }; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; packages: "first_pkg"; "second_pkg"; } bundle agent check { methods: "any" usebundle => dcs_check_diff($(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/07_packages/contradicting-bodies-and-promises.cf0000644000000000000000000001130415010704253027672 0ustar00rootroot00000000000000####################################################### # Test that specifying two incompatible ways to get package version is detected # and reported ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "bash-1.0-amd64" package_policy => "add", package_method => mock, package_version => "2.0", package_architectures => { "amd64" }, classes => test_set_class("overlapping_version_arch_regex_succ", "overlapping_version_arch_regex_fail"); "bash-1.0-i386" package_policy => "add", package_method => mock_no_name_regex_but_version_regex, classes => test_set_class("no_name_regex_version_succ", "no_name_regex_version_fail"); "bash-1.0-i386" package_policy => "add", package_method => mock_no_name_regex_but_arch_regex, classes => test_set_class("no_name_regex_arch_succ", "no_name_regex_arch_fail"); "bash-1.0-sparc" package_policy => "add", package_method => mock_overlapping_version_regex, package_version => "2.0", classes => test_set_class("overlapping_version_regex_succ", "overlapping_version_regex_fail"); } body package_method mock_overlapping_version_regex { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.true) $(this.name)-$(this.version):$(this.arch)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body package_method mock_no_name_regex_but_arch_regex { package_changes => "individual"; package_arch_regex => ".*"; # but no package_name_regex! package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock_no_name_regex_but_version_regex { package_changes => "individual"; package_version_regex => ".*"; # but no package_name_regex! package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "!no_name_regex_version_succ", "no_name_regex_version_fail", "!no_name_regex_arch_succ", "no_name_regex_arch_fail", "!overlapping_version_arch_regex_succ", "overlapping_version_arch_regex_fail", "!overlapping_version_regex_succ", "overlapping_version_regex_fail"}; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/901.cf0000644000000000000000000000315215010704253021513 0ustar00rootroot00000000000000####################################################### # # Test missing version regex fails # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_unsupported" string => "windows"; packages: "a:b:c" package_policy => "add", package_method => mock, classes => test_set_class("fail","ok"); } body package_method mock { package_changes => "individual"; package_list_command => "$(G.true)"; package_list_name_regex => "^[^:]*"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { reports: ok.!fail:: "$(this.promise_filename) Pass"; !ok|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/test_repository/0000755000000000000000000000000015010704253024145 5ustar00rootroot00000000000000mismatch-update-to-lessorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253035451 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorymismatch-install-exact-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253033762 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorymismatch-install-lessthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253034477 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryupdate-to-greaterorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253034331 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorymismatch-install-greaterthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253035162 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryupdate-to-greaterthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253033613 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorycfengine-3.24.2/tests/acceptance/07_packages/test_repository/install-lessthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253032753 0ustar00rootroot00000000000000update-to-lessthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253033130 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryinstall-greaterthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253033357 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryupdate-to-lessorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253033646 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorymismatch-update-to-greaterorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253036134 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorymismatch-install-greaterorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253035700 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorycfengine-3.24.2/tests/acceptance/07_packages/test_repository/install-exact-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253032236 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repository/installed.txt0000644000000000000000000000402115010704253026662 0ustar00rootroot00000000000000i update-to-exact-version 1.4.3 i386 i update-to-lessorequal-version 1.4.3 i386 i update-to-lessthan-version 1.4.3 i386 i update-to-greaterorequal-version 1.4.3 i386 i update-to-greaterthan-version 1.4.3 i386 i update-to-greaterorequal-version-already-greater-installed 2.2.2 i386 i update-to-greaterthan-version-already-greater-installed 2.2.2 i386 i mismatch-update-to-exact-version 1.4.3 i386 i mismatch-update-to-lessorequal-version 1.4.3 i386 i mismatch-update-to-lessthan-version 1.4.3 i386 i mismatch-update-to-greaterorequal-version 1.4.3 i386 i mismatch-update-to-greaterthan-version 1.4.3 i386 i missing-update-to-exact-version 1.4.3 i386 i missing-update-to-lessorequal-version 1.4.3 i386 i missing-update-to-lessthan-version 1.4.3 i386 i missing-update-to-greaterorequal-version 1.4.3 i386 i missing-update-to-greaterthan-version 1.4.3 i386 i delete-exact-version 2.2.3 i386 i mismatch-delete-exact-version 2.2.3 i386 a install-exact-version-2.2.3.i386.rpm a install-greaterorequal-version-2.2.3.i386.rpm a install-greaterthan-version-2.2.3.i386.rpm a install-lessorequal-version-2.2.3.i386.rpm a install-lessthan-version-2.2.3.i386.rpm a mismatch-install-exact-version-2.2.3.i386.rpm a mismatch-install-greaterorequal-version-2.2.3.i386.rpm a mismatch-install-greaterthan-version-2.2.3.i386.rpm a mismatch-install-lessorequal-version-2.2.3.i386.rpm a mismatch-install-lessthan-version-2.2.3.i386.rpm a mismatch-update-to-exact-version-2.2.3.i386.rpm a mismatch-update-to-greaterorequal-version-2.2.3.i386.rpm a mismatch-update-to-greaterthan-version-2.2.3.i386.rpm a mismatch-update-to-lessorequal-version-2.2.3.i386.rpm a mismatch-update-to-lessthan-version-2.2.3.i386.rpm a update-to-exact-version-2.2.3.i386.rpm a update-to-greaterorequal-version-2.2.3.i386.rpm a update-to-greaterorequal-version-already-greater-installed-2.2.3.i386.rpm a update-to-greaterthan-version-2.2.3.i386.rpm a update-to-greaterthan-version-already-greater-installed-2.2.3.i386.rpm a update-to-lessorequal-version-2.2.3.i386.rpm a update-to-lessthan-version-2.2.3.i386.rpm mismatch-update-to-greaterthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253035416 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryinstall-greaterorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253034075 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorymismatch-update-to-lessthan-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253034733 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorymismatch-install-lessorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253035215 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryupdate-to-greaterorequal-version-already-greater-installed-2.2.3.i386.rpm0000644000000000000000000000000015010704253041354 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorycfengine-3.24.2/tests/acceptance/07_packages/test_repository/update-to-exact-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253032472 0ustar00rootroot00000000000000mismatch-update-to-exact-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253034216 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryupdate-to-greaterthan-version-already-greater-installed-2.2.3.i386.rpm0000644000000000000000000000000015010704253040636 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositoryinstall-lessorequal-version-2.2.3.i386.rpm0000644000000000000000000000000015010704253033412 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/07_packages/test_repositorycfengine-3.24.2/tests/acceptance/07_packages/002.cf0000644000000000000000000000477615010704253021520 0ustar00rootroot00000000000000####################################################### # # Test add a package using a "default" architecture # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { "G", "g", default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } bundle common g { classes: "mpm_declared" not => strcmp(getenv("MOCK_PACKAGE_MANAGER", "65535"), ""); vars: mpm_declared:: "pm" string => getenv("MOCK_PACKAGE_MANAGER", "65535"); !mpm_declared:: "pm" string => "$(G.mock_package_manager)"; } ####################################################### bundle agent init { commands: "$(g.pm) --clear-installed"; "$(g.pm) --clear-available"; "$(g.pm) --populate-available imagisoft:1.0i:x666"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "name" string => "imagisoft"; "version" string => "1.0i"; packages: "$(name):$(version)" package_policy => "add", package_method => mock, classes => test_set_class("pass","fail"); } body package_method mock { package_changes => "individual"; package_list_command => "$(g.pm) --list-installed"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_installed_regex => "^[^:]*"; package_add_command => "$(g.pm) --add "; package_update_command => "$(g.pm) --update "; package_delete_command => "$(g.pm) --delete "; package_verify_command => "$(g.pm) --verify "; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { vars: "pkgs" string => execresult("$(g.pm) --list-installed", "noshell"); classes: "has_pkg" expression => regcmp("imagisoft:1\.0i:x666", "$(pkgs)"); "ok" expression => "pass.!fail.has_pkg"; reports: DEBUG.pass:: "pass"; DEBUG.has_pkg:: "has_pkg"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes successfully_executed(class) { kept_returncodes => { "0" }; promise_kept => { "$(class)" }; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/warn-package-delete-non-existing.cf0000644000000000000000000000317615010704253027430 0ustar00rootroot00000000000000####################################################### # # Test delete a package that does not exist # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "nosuchpackageinstalled" package_method => mock_warn_delete_pkg, package_policy => "delete", classes => kept_repaired_notkept("kept", "repaired", "notkept"); } body package_method mock_warn_delete_pkg { package_changes => "individual"; package_list_command => "$(G.printf) 'bash-4.2.8-x86_64'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.false)"; } body classes kept_repaired_notkept(kept, repaired, notkept) { promise_kept => { "$(kept)" }; promise_repaired => { "$(repaired)" }; repair_failed => { "$(notkept)" }; } ####################################################### bundle agent check { reports: kept:: "$(this.promise_filename) Pass"; !kept:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/dependency-checks-package_delete_command.cf0000644000000000000000000000414115010704253031166 0ustar00rootroot00000000000000####################################################### # Test for presence of "main" attribute, given the presence of "dependent" # attributes, which do not make sense without the "main" attribute. # # main attribute: package_delete_command # dependent attributes: # package_delete_convention ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { packages: "bash-1.0-amd64" package_policy => "add", package_method => mock_no_delete_command_delete_convention, classes => test_set_class("no_delete_command_delete_convention_succ", "no_delete_command_delete_convention_fail"); } body package_method mock_no_delete_command_delete_convention { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "$(G.printf) 'bash-1.0-amd64'"; package_installed_regex => ".*"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-(.*)"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; # package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; package_delete_convention => "$(name)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "!no_delete_command_delete_convention_succ", "no_delete_command_delete_convention_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/package_commands_useshell.cf0000644000000000000000000000744715010704253026375 0ustar00rootroot00000000000000####################################################### # # Test package_commands_useshell works # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: # Windows has its own mechanism to list packages, and doesn't use the package body. "test_skip_needs_work" string => "windows"; vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "bash-1.0-amd64" package_policy => "add", package_method => mock_useshell_true, classes => test_set_class("useshell_true_succ", "useshell_true_fail"); "bash-1.0-i386" package_policy => "add", package_method => mock_useshell_false, classes => test_set_class("useshell_false_succ", "useshell_false_fail"); "bash-1.0-spark" package_policy => "add", package_method => mock_useshell_unset, classes => test_set_class("useshell_unset_succ", "useshell_unset_fail"); } body package_method mock_useshell_true { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "if true; then true; else false; fi"; package_list_name_regex => ".*"; package_list_version_regex => ".*"; package_list_arch_regex => ".*"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; package_commands_useshell => "true"; } body package_method mock_useshell_false { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "if true; then true; else false; fi"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; package_commands_useshell => "false"; } body package_method mock_useshell_unset { package_changes => "individual"; package_name_regex => "^([^-]+)"; package_version_regex => "^[^-]+-([^-]+)"; package_arch_regex => "^[^-]+-[^-]+-(.*)"; package_list_command => "echo 'a:b:c\n'"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" and => { "useshell_true_succ", "!useshell_true_fail", "!useshell_false_succ", "useshell_false_fail", "useshell_unset_succ", "!useshell_unset_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/908.cf0000644000000000000000000000300515010704253021517 0ustar00rootroot00000000000000####################################################### # # Test broken list_command # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "a:b:c" package_policy => "add", package_method => mock, classes => test_set_class("fail","ok"); } body package_method mock { package_changes => "individual"; package_list_command => "/nonexisting"; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { reports: ok.!fail:: "$(this.promise_filename) Pass"; !ok|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/package_module_interpreter.cf.module0000644000000000000000000000271115010704253030051 0ustar00rootroot00000000000000set -e remove_prefix() { echo "$1" | sed "s/$2//" } case "$1" in supports-api-version) echo 1 ;; get-package-data) while read line; do case "$line" in File=*) echo PackageType=repo echo Name=`remove_prefix "${line}" "File="` ;; *) true ;; esac done ;; list-installed) while read line; do case "$line" in options=*) OUTPUT=`remove_prefix "${line}" "options="` ;; *) exit 1 ;; esac done if [ -f "$OUTPUT" ]; then cat "$OUTPUT" fi ;; list-*) # Drain input. cat > /dev/null ;; repo-install) while read line; do case "$line" in options=*) OUTPUT=`remove_prefix "${line}" "options="` ;; Name=*) NAME=`remove_prefix "${line}" "Name="` ;; *) exit 1 ;; esac done echo "Name=$NAME" >> "$OUTPUT" echo "Version=1.0" >> "$OUTPUT" echo "Architecture=generic" >> "$OUTPUT" ;; *) exit 1 ;; esac exit 0 cfengine-3.24.2/tests/acceptance/07_packages/warn-package-delete.cf0000644000000000000000000000172415010704253025005 0ustar00rootroot00000000000000####################################################### # # Test delete a package # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -KI -f $(this.promise_filename).sub --dry-run", "useshell"); } ####################################################### bundle agent check { classes: "ok" expression => regcmp(".*Deleting.*", "$(test.subout)"); reports: # DEBUG:: # "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/07_packages/package_module_path.cf0000644000000000000000000000251515010704253025160 0ustar00rootroot00000000000000# Based on 00_basics/ifelapsed_and_expireafter/timed/package_lock.cf body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { files: "$(sys.workdir)/modules/packages/." create => "true"; "$(sys.workdir)/modules/packages/test_module_script.sh" copy_from => local_cp("$(this.promise_filename).module"), perms => m("ugo+x"); } body package_module test_module { query_installed_ifelapsed => "60"; query_updates_ifelapsed => "14400"; default_options => { "$(G.testfile)" }; module_path => "$(sys.workdir)/modules/packages/test_module_script.sh"; } bundle agent test { meta: "description" string => "Test that the interpreter for the package module script can be set", meta => { "CFE-2880" }; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; packages: "first_pkg" policy => "present", package_module => test_module; "second_pkg" policy => "present", package_module => test_module; } bundle agent check { methods: "any" usebundle => dcs_check_diff($(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/07_packages/package_module_interpreter.cf0000644000000000000000000000246115010704253026567 0ustar00rootroot00000000000000# Based on 00_basics/ifelapsed_and_expireafter/timed/package_lock.cf body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { files: "$(sys.workdir)/modules/packages/." create => "true"; "$(sys.workdir)/modules/packages/test_module" copy_from => local_cp("$(this.promise_filename).module"); } body package_module test_module { query_installed_ifelapsed => "60"; query_updates_ifelapsed => "14400"; default_options => { "$(G.testfile)" }; interpreter => "$(G.sh)"; # /bin/sh; NOTE: no hashbang in the test_module script } bundle agent test { meta: "description" string => "Test that the interpreter for the package module script can be set", meta => { "CFE-2880" }; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; packages: "first_pkg" policy => "present", package_module => test_module; "second_pkg" policy => "present", package_module => test_module; } bundle agent check { methods: "any" usebundle => dcs_check_diff($(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/07_packages/906.cf0000644000000000000000000000503015010704253021515 0ustar00rootroot00000000000000####################################################### # # Test too long repository directory # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "a:b:c" package_policy => "add", package_method => mock, classes => test_set_class("fail","ok"); } body package_method mock { package_changes => "individual"; package_file_repositories => { "/tmp", "/fuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu/" }; package_list_name_regex => "^[^:]*"; package_list_version_regex => ":(?<=:).*(?=:)"; package_list_arch_regex => "[^:]\w+$"; package_installed_regex => "^[^:]*"; package_add_command => "$(G.true)"; package_update_command => "$(G.true)"; package_delete_command => "$(G.true)"; package_verify_command => "$(G.true)"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { reports: ok.!fail:: "$(this.promise_filename) Pass"; !ok|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 29 cfengine-3.24.2/tests/acceptance/10_files/0000755000000000000000000000000015010704253020205 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_dryryn_option.cf.sub.mustache0000644000000000000000000000002215010704253031631 0ustar00rootroot00000000000000SHOULD NOT RENDER agent_control_files_single_copy_does_not_apply_to_nonmatching_files_1.cf0000644000000000000000000000272715010704253036653 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body agent control { # (?!) should always fail to match. It is the zero-width negative # look-ahead. If what is in the parentheses matches then the whole # match fails. Given that it has nothing in it, it will fail the # match for anything (including nothing). files_single_copy => { "(?!)" }; } bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy does not prevent file patterns that do not match from being copied multiple times."; "test_soft_fail" string => "any", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/two", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/purge_reports_as_repaired.cf0000644000000000000000000000202115010704253025750 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that purging a directory in a target propagates promise as repaired"; } ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dirs" slist => { "$(G.testdir)/source/.", "$(G.testdir)/target/.", "$(G.testdir)/target/subdir/." }; files: "$(dirs)" create => "true"; } bundle agent test { files: "$(G.testdir)/target/" copy_from => copyfrom_sync("$(G.testdir)/source/."), depth_search => recurse("inf"), classes => if_repaired("purge_propagated"); } ####################################################### bundle agent check { reports: purge_propagated:: "$(this.promise_filename) Pass"; !purge_propagated:: "$(this.promise_filename) FAIL"; } agent_control_files_single_copy_prevents_subsequent_copy_on_regular_expression_match.cf0000644000000000000000000000247615010704253042172 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body agent control { # Here we cast a wide net (any file) to make sure regular expression # matching works. files_single_copy => { ".*" }; } bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy prevents subsequnt copy of a file when there is a matching regular expression."; "test_skip_needs_work" string => "windows", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/one", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/templating/0000755000000000000000000000000015010704253022351 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templating/demo.datastate.mustache0000644000000000000000000000123515010704253027002 0ustar00rootroot00000000000000

    {{vars.test.header}}

    {{#vars.test.items}} {{.}} {{/vars.test.items}} {{#classes.empty}}

    The list is empty.

    {{/classes.empty}} {{#vars.test.d}} key "{{@}}" value "{{.}}" {{/vars.test.d}} {{#vars.test.h}} key "{{@}}" value "{{.}}" {{/vars.test.h}} {{#vars.test.h_under_q}} key "{{@}}" value "{{%.}}" {{/vars.test.h_under_q}} {{#vars.test.h_in_array}} key "{{@}}" value "{{%.}}" {{/vars.test.h_in_array}} {{#vars.test.h2_in_array}} key "{{@}}" value "{{%.}}" {{/vars.test.h2_in_array}} {{#vars.test.h2_in_array}} {{#vars.test.h_under_q}} nested key should be "q": "{{@}}" value "{{%.}}" {{/vars.test.h_under_q}} {{/vars.test.h2_in_array}} cfengine-3.24.2/tests/acceptance/10_files/templating/basic_classes.cf0000644000000000000000000000336615010704253025471 0ustar00rootroot00000000000000####################################################### # # Test basic classes for CFEngine templates. # Redmine #2928 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_defaults => init_empty, edit_line => init_expect; "$(G.testfile).template" create => "true", edit_line => template, edit_defaults => init_empty; } ####################################################### bundle agent test { classes: "two" expression => "any"; "three" expression => "any"; files: "$(G.testfile).actual" create => "true", edit_defaults => init_empty, edit_template => "$(G.testfile).template"; } ####################################################### bundle edit_line template { insert_lines: "[%CFEngine BEGIN %] one [%CFEngine END %] [%CFEngine two:: %] two [%CFEngine default:three:: %] three " insert_type => "preserve_block"; } ####################################################### bundle edit_line init_expect { insert_lines: "one two three " insert_type => "preserve_block"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 mustache_no_fallback_to_datastate_with_undefined_direct_data.cf0000644000000000000000000000505115010704253037064 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that a mustache template does not fall back to datastate when its given an invalid container directly"; } bundle agent init { # First we make sure to start of with am emty target files: "$(G.testfile)" handle => "init_testfile_absent", delete => tidy; "$(G.testfile)" handle => "init_testfile_present", create => "true", depends_on => { "init_testfile_absent" }, comment => "We first remove the file, and then re-create it so that we know that it is empty to start with."; } bundle agent test { # Second we promise to render template passing data that does not exist via template_data vars: "classes" slist => classesmatching("template_render_with_non_existing_data_container.*"); files: "$(G.testfile)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => @(missing_ns:missing_bundle.missing_data), classes => scoped_classes_generic("bundle", "template_render_with_non_existing_data_container"); reports: DEBUG:: "$(this.bundle): Found class '$(classes)'"; } bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine7699" }; # Finally we look to see what classes were defined, and look at the target file to see if it has changed. vars: "expected" string => ""; "actual" string => readfile($(G.testfile), inf); classes: # I assume here that the promise should not even be actuated when invalid # data is provided thus we should have found 0 classes "fail_classes" expression => isgreaterthan(length("test.classes"), 0); # Another failure condition is if the rendered file is not empty as # expected "fail_content" not => strcmp($(expected), $(actual)); "fail" or => { "fail_classes", "fail_content" }; "exception" and => { "fail", "ok" }; reports: DEBUG:: "DEBUG $(this.bundle): Found '$(test.classes)' that should not have been found" if => "fail_classes"; "DEBUG $(this.bundle): Found the content of $(G.testfile) was not as expected" if => "fail_content"; fail:: "$(this.promise_filename) FAIL"; !fail|exception:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } cfengine-3.24.2/tests/acceptance/10_files/templating/demo.json0000644000000000000000000000033715010704253024173 0ustar00rootroot00000000000000{ "header": "Colors", "items": [ {"name": "red", "first": true, "url": "#Red"}, {"name": "green", "link": true, "url": "#Green"}, {"name": "blue", "link": true, "url": "#Blue"} ], "empty": false } mustache_no_fallback_to_datastate_with_undefined_parsejson_storejson.cf0000644000000000000000000000514415010704253040736 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that a mustache template does not try to render when its given an invalid container via parsejson(storejson())"; } bundle agent init { # First we make sure to start with an empty target file. files: "$(G.testfile)" handle => "init_testfile_absent", delete => tidy; "$(G.testfile)" handle => "init_testfile_present", create => "true", depends_on => { "init_testfile_absent" }, comment => "We first remove the file, and then re-create it so that we know that it is empty to start with."; } bundle agent test { # Second we try to render the template while passing in an non existing data container to template_data via parsejson(storejson vars: "classes" slist => classesmatching("template_render_with_non_existing_data_container.*"); files: "$(G.testfile)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => parsejson(storejson('missing_ns:missing_bundle.missing_data')), classes => scoped_classes_generic("bundle", "template_render_with_non_existing_data_container"); reports: DEBUG:: "$(this.bundle): Found class '$(classes)'"; } bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine7699" }; # Finally we check to see what classes were defined, and inspect the target file for change vars: "expected" string => ""; "actual" string => readfile($(G.testfile), inf); classes: # I assume here that the promise should not even be actuated when invalid # data is provided thus we should have found 0 classes "fail_classes" expression => isgreaterthan(length("test.classes"), 0); # Another failure condition is if the rendered file is not empty as # expected "fail_content" not => strcmp($(expected), $(actual)); "fail" or => { "fail_classes", "fail_content" }; "exception" and => { "fail", "ok" }; reports: DEBUG:: "DEBUG $(this.bundle): Found '$(test.classes)' that should not have been found" if => "fail_classes"; "DEBUG $(this.bundle): Found the content of $(G.testfile) was not as expected" if => "fail_content"; fail:: "$(this.promise_filename) FAIL"; !fail|exception:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } cfengine-3.24.2/tests/acceptance/10_files/templating/missing_file.cf0000644000000000000000000000324115010704253025333 0ustar00rootroot00000000000000############################################################################## # # Redmine #3573: establish message for missing target file with a template # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: any:: # Run subtests. Need to be in verbose mode to see the output. # The full verbose output is too big for variable assignment here. # So extract (grep) only potentially interesting lines. "subout" string => execresult("$(sys.cf_agent) -KIv -b run -f $(this.promise_filename).sub 2>&1 | $(G.grep) '/no/such/file'", "useshell"); } ####################################################### bundle agent check { vars: "must_have" string => ".*Cannot render file '/no/such/file': file does not exist.*"; "cant_have" string => ".*no longer access file.*"; classes: "ok_1" not => regcmp($(cant_have), "$(test.subout)"); "ok_2" expression => regcmp($(must_have), "$(test.subout)"); reports: DEBUG:: "Attempted subtest '$(this.promise_filename).sub'"; "Significant output was '$(test.subout)'."; DEBUG.!ok_1:: "failing: can't have pattern '$(cant_have)' in subtest"; DEBUG.!ok_2:: "failing: must have pattern '$(must_have)' in subtest"; ok_1.ok_2:: "$(this.promise_filename) Pass"; !(ok_1.ok_2):: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/templating/cftemplate.cf.template0000644000000000000000000000006615010704253026623 0ustar00rootroot00000000000000[%CFEngine any:: %] 1 2 [%CFEngine cfengine:: %] 3 4 5cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_datastate_demo.cf0000644000000000000000000000463115010704253027536 0ustar00rootroot00000000000000####################################################### # # Demo of Mustache templates with no external JSON data # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { classes: "empty" expression => "any"; vars: "template_file" string => "$(init.origtestdir)/demo.datastate.mustache"; "header" string => "Colors"; "items" slist => { "red", "green", "blue" }; "d" data => parsejson('[4,5,6]'); "h" data => parsejson('{ "a": "x", "b": "y"}'); "h_under_q" data => mergedata('{ "q": h }'); # wrap h in a map "h_in_array" data => mergedata('[ h ]'); # wrap h in an array "h2_in_array" data => mergedata(h_in_array, h_in_array); # more arrays! files: "$(G.testfile)" create => "true", edit_template => "$(template_file)", template_method => "mustache"; reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile)"; } ####################################################### bundle agent check { vars: "expect" string => '

    Colors

    red green blue

    The list is empty.

    key "0" value "4" key "1" value "5" key "2" value "6" key "a" value "x" key "b" value "y" key "q" value "{ "a": "x", "b": "y" }" key "0" value "{ "a": "x", "b": "y" }" key "0" value "{ "a": "x", "b": "y" }" key "1" value "{ "a": "x", "b": "y" }" nested key should be "q": "q" value "{ "a": "x", "b": "y" }" nested key should be "q": "q" value "{ "a": "x", "b": "y" }" '; "actual" string => readfile("$(G.testfile)", inf); classes: "ok" expression => strcmp($(expect), $(actual)); reports: DEBUG:: "'$(expect)' != '$(actual)'" if => "!ok"; "'$(expect)' == '$(actual)'" if => "ok"; "expect: '$(expect)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/templating/empty_template_empty_file.cf.template0000644000000000000000000000010715010704253031741 0ustar00rootroot00000000000000[%CFEngine no_such_class:: %] Redmine#3870: text will not be inserted cfengine-3.24.2/tests/acceptance/10_files/templating/large_template_blocks.cf.template0000644000000000000000000002025215010704253031020 0ustar00rootroot00000000000000This first block, smaller than 4096 characters is rendered: [%CFEngine BEGIN %] 00-1234567890123456789012345678901234567890123456789012345678901234567890 01-1234567890123456789012345678901234567890123456789012345678901234567890 02-1234567890123456789012345678901234567890123456789012345678901234567890 03-1234567890123456789012345678901234567890123456789012345678901234567890 04-1234567890123456789012345678901234567890123456789012345678901234567890 05-1234567890123456789012345678901234567890123456789012345678901234567890 06-1234567890123456789012345678901234567890123456789012345678901234567890 07-1234567890123456789012345678901234567890123456789012345678901234567890 08-1234567890123456789012345678901234567890123456789012345678901234567890 09-1234567890123456789012345678901234567890123456789012345678901234567890 [%CFEngine END %] The second block, which is larger than 4096 characters, is not rendered in CFE3.5.x: [%CFEngine BEGIN %] 00-1234567890123456789012345678901234567890123456789012345678901234567890 01-1234567890123456789012345678901234567890123456789012345678901234567890 02-1234567890123456789012345678901234567890123456789012345678901234567890 03-1234567890123456789012345678901234567890123456789012345678901234567890 04-1234567890123456789012345678901234567890123456789012345678901234567890 05-1234567890123456789012345678901234567890123456789012345678901234567890 06-1234567890123456789012345678901234567890123456789012345678901234567890 07-1234567890123456789012345678901234567890123456789012345678901234567890 08-1234567890123456789012345678901234567890123456789012345678901234567890 09-1234567890123456789012345678901234567890123456789012345678901234567890 10-1234567890123456789012345678901234567890123456789012345678901234567890 11-1234567890123456789012345678901234567890123456789012345678901234567890 12-1234567890123456789012345678901234567890123456789012345678901234567890 13-1234567890123456789012345678901234567890123456789012345678901234567890 14-1234567890123456789012345678901234567890123456789012345678901234567890 15-1234567890123456789012345678901234567890123456789012345678901234567890 16-1234567890123456789012345678901234567890123456789012345678901234567890 17-1234567890123456789012345678901234567890123456789012345678901234567890 18-1234567890123456789012345678901234567890123456789012345678901234567890 19-1234567890123456789012345678901234567890123456789012345678901234567890 20-1234567890123456789012345678901234567890123456789012345678901234567890 21-1234567890123456789012345678901234567890123456789012345678901234567890 22-1234567890123456789012345678901234567890123456789012345678901234567890 23-1234567890123456789012345678901234567890123456789012345678901234567890 24-1234567890123456789012345678901234567890123456789012345678901234567890 25-1234567890123456789012345678901234567890123456789012345678901234567890 26-1234567890123456789012345678901234567890123456789012345678901234567890 27-1234567890123456789012345678901234567890123456789012345678901234567890 28-1234567890123456789012345678901234567890123456789012345678901234567890 29-1234567890123456789012345678901234567890123456789012345678901234567890 30-1234567890123456789012345678901234567890123456789012345678901234567890 31-1234567890123456789012345678901234567890123456789012345678901234567890 32-1234567890123456789012345678901234567890123456789012345678901234567890 33-1234567890123456789012345678901234567890123456789012345678901234567890 34-1234567890123456789012345678901234567890123456789012345678901234567890 35-1234567890123456789012345678901234567890123456789012345678901234567890 36-1234567890123456789012345678901234567890123456789012345678901234567890 37-1234567890123456789012345678901234567890123456789012345678901234567890 38-1234567890123456789012345678901234567890123456789012345678901234567890 39-1234567890123456789012345678901234567890123456789012345678901234567890 40-1234567890123456789012345678901234567890123456789012345678901234567890 41-1234567890123456789012345678901234567890123456789012345678901234567890 42-1234567890123456789012345678901234567890123456789012345678901234567890 43-1234567890123456789012345678901234567890123456789012345678901234567890 44-1234567890123456789012345678901234567890123456789012345678901234567890 45-1234567890123456789012345678901234567890123456789012345678901234567890 46-1234567890123456789012345678901234567890123456789012345678901234567890 47-1234567890123456789012345678901234567890123456789012345678901234567890 48-1234567890123456789012345678901234567890123456789012345678901234567890 49-1234567890123456789012345678901234567890123456789012345678901234567890 50-1234567890123456789012345678901234567890123456789012345678901234567890 51-1234567890123456789012345678901234567890123456789012345678901234567890 52-1234567890123456789012345678901234567890123456789012345678901234567890 53-1234567890123456789012345678901234567890123456789012345678901234567890 54-1234567890123456789012345678901234567890123456789012345678901234567890 55-1234567890123456789012345678901234567890123456789012345678901234567890 56-1234567890123456789012345678901234567890123456789012345678901234567890 57-1234567890123456789012345678901234567890123456789012345678901234567890 58-1234567890123456789012345678901234567890123456789012345678901234567890 59-1234567890123456789012345678901234567890123456789012345678901234567890 60-1234567890123456789012345678901234567890123456789012345678901234567890 61-1234567890123456789012345678901234567890123456789012345678901234567890 62-1234567890123456789012345678901234567890123456789012345678901234567890 63-1234567890123456789012345678901234567890123456789012345678901234567890 64-1234567890123456789012345678901234567890123456789012345678901234567890 65-1234567890123456789012345678901234567890123456789012345678901234567890 66-1234567890123456789012345678901234567890123456789012345678901234567890 67-1234567890123456789012345678901234567890123456789012345678901234567890 68-1234567890123456789012345678901234567890123456789012345678901234567890 69-1234567890123456789012345678901234567890123456789012345678901234567890 70-1234567890123456789012345678901234567890123456789012345678901234567890 71-1234567890123456789012345678901234567890123456789012345678901234567890 72-1234567890123456789012345678901234567890123456789012345678901234567890 73-1234567890123456789012345678901234567890123456789012345678901234567890 74-1234567890123456789012345678901234567890123456789012345678901234567890 75-1234567890123456789012345678901234567890123456789012345678901234567890 76-1234567890123456789012345678901234567890123456789012345678901234567890 77-1234567890123456789012345678901234567890123456789012345678901234567890 78-1234567890123456789012345678901234567890123456789012345678901234567890 79-1234567890123456789012345678901234567890123456789012345678901234567890 80-1234567890123456789012345678901234567890123456789012345678901234567890 81-1234567890123456789012345678901234567890123456789012345678901234567890 82-1234567890123456789012345678901234567890123456789012345678901234567890 83-1234567890123456789012345678901234567890123456789012345678901234567890 84-1234567890123456789012345678901234567890123456789012345678901234567890 85-1234567890123456789012345678901234567890123456789012345678901234567890 86-1234567890123456789012345678901234567890123456789012345678901234567890 87-1234567890123456789012345678901234567890123456789012345678901234567890 88-1234567890123456789012345678901234567890123456789012345678901234567890 89-1234567890123456789012345678901234567890123456789012345678901234567890 90-1234567890123456789012345678901234567890123456789012345678901234567890 91-1234567890123456789012345678901234567890123456789012345678901234567890 92-1234567890123456789012345678901234567890123456789012345678901234567890 93-1234567890123456789012345678901234567890123456789012345678901234567890 94-1234567890123456789012345678901234567890123456789012345678901234567890 95-1234567890123456789012345678901234567890123456789012345678901234567890 96-1234567890123456789012345678901234567890123456789012345678901234567890 97-1234567890123456789012345678901234567890123456789012345678901234567890 98-1234567890123456789012345678901234567890123456789012345678901234567890 99-1234567890123456789012345678901234567890123456789012345678901234567890 [%CFEngine END %] mustache_no_render_with_undefined_parsejson_storejson.cf0000644000000000000000000000514415010704253035722 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that a mustache template does not try to render when its given an invalid container via parsejson(storejson())"; } bundle agent init { # First we make sure to start with an empty target file. files: "$(G.testfile)" handle => "init_testfile_absent", delete => tidy; "$(G.testfile)" handle => "init_testfile_present", create => "true", depends_on => { "init_testfile_absent" }, comment => "We first remove the file, and then re-create it so that we know that it is empty to start with."; } bundle agent test { # Second we try to render the template while passing in an non existing data container to template_data via parsejson(storejson vars: "classes" slist => classesmatching("template_render_with_non_existing_data_container.*"); files: "$(G.testfile)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => parsejson(storejson('missing_ns:missing_bundle.missing_data')), classes => scoped_classes_generic("bundle", "template_render_with_non_existing_data_container"); reports: DEBUG:: "$(this.bundle): Found class '$(classes)'"; } bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine7699" }; # Finally we check to see what classes were defined, and inspect the target file for change vars: "expected" string => ""; "actual" string => readfile($(G.testfile), inf); classes: # I assume here that the promise should not even be actuated when invalid # data is provided thus we should have found 0 classes "fail_classes" expression => isgreaterthan(length("test.classes"), 0); # Another failure condition is if the rendered file is not empty as # expected "fail_content" not => strcmp($(expected), $(actual)); "fail" or => { "fail_classes", "fail_content" }; "exception" and => { "fail", "ok" }; reports: DEBUG:: "DEBUG $(this.bundle): Found '$(test.classes)' that should not have been found" if => "fail_classes"; "DEBUG $(this.bundle): Found the content of $(G.testfile) was not as expected" if => "fail_content"; fail:: "$(this.promise_filename) FAIL"; !fail|exception:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_demo.cf0000644000000000000000000000305515010704253025503 0ustar00rootroot00000000000000####################################################### # # Demo from mustache.github.io # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "template_file" string => "$(init.origtestdir)/demo.mustache"; files: "$(G.testfile)" create => "true", edit_template => "$(template_file)", template_method => "mustache", template_data => readjson("$(init.origtestdir)/demo.json", 10000); reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile)"; } ####################################################### bundle agent check { vars: "expect" string => readfile("$(init.origtestdir)/demo.expected", 10000); "actual" string => readfile("$(G.testfile)", 10000); classes: "ok" expression => regcmp("$(expect)", "$(actual)"); reports: DEBUG:: "expect: '$(expect)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_expect_list_find_string.cf0000644000000000000000000001325315010704253031471 0ustar00rootroot00000000000000####################################################### # # Test that mustache DTRT when encountering string when expects list. Also # check that after mustache template is applied you have a different filestat # (indicating you wrote to a different file and moved into place) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { methods: "empty good" usebundle => file_empty("$(G.testfile).good"); "empty bad" usebundle => file_empty("$(G.testfile).bad"); "first filestat good" usebundle => init_filestat("good1", "$(G.testfile).good"); "first filestat bad" usebundle => init_filestat("bad1", "$(G.testfile).bad"); "Remove good" usebundle => dcs_fini("$(G.testfile).good"); "Remove bad" usebundle => dcs_fini("$(G.testfile).bad"); "ready good" usebundle => file_make("$(G.testfile).good", "# Set good"); "ready bad" usebundle => file_make("$(G.testfile).bad", "# Set bad"); "link good" usebundle => file_hardlink("$(G.testfile).good", "$(G.testfile).goodlink"); "link bad" usebundle => file_hardlink("$(G.testfile).bad", "$(G.testfile).badlink"); "second filestat good" usebundle => init_filestat("good2", "$(G.testfile).good"); "second filestat bad" usebundle => init_filestat("bad2", "$(G.testfile).bad"); } bundle agent init_filestat(n, f) { vars: "filestat_$(n)" string => format("%s,%s", filestat($(f), "basename"), filestat($(f), "nlink")); } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; methods: "mustache good" usebundle => file_mustache_jsonstring($(template), '{"mykeys": ["template expects list of strings"]}', "$(G.testfile).good"); "mustache bad" usebundle => file_mustache_jsonstring($(template), '{"mykeys": "string but template expects list of strings"}', "$(G.testfile).bad"); "third filestat good" usebundle => init_filestat("good3", "$(G.testfile).good"); "third filestat bad" usebundle => init_filestat("bad3", "$(G.testfile).bad"); vars: "template" string => "$(this.promise_filename).mustache"; "actual_good" string => readfile("$(G.testfile).good", 4096); "actual_bad" string => readfile("$(G.testfile).bad", 4096); } ####################################################### bundle agent check { vars: "expected_good" string => "#DO NOT EDIT - MANAGED FILE template expects list of strings "; "expected_bad" string => "# Set bad"; "filestats_good" slist => { "$(init_filestat.filestat_good1)", "$(init_filestat.filestat_good2)", "$(init_filestat.filestat_good3)" }; "filestats_bad" slist => { "$(init_filestat.filestat_bad1)", "$(init_filestat.filestat_bad2)", "$(init_filestat.filestat_bad3)" }; "filestats_good_str" string => format("%S", filestats_good); "filestats_bad_str" string => format("%S", filestats_bad); classes: "ok_filestats_good_1_2" not => strcmp("$(init_filestat.filestat_good1)", "$(init_filestat.filestat_good2)"); "ok_filestats_good_2_3" not => strcmp("$(init_filestat.filestat_good2)", "$(init_filestat.filestat_good3)"); "ok_filestats_bad_1_2" not => strcmp("$(init_filestat.filestat_bad1)", "$(init_filestat.filestat_bad2)"); "ok_filestats_bad_2_3" expression => strcmp("$(init_filestat.filestat_bad2)", "$(init_filestat.filestat_bad3)"); "ok_content_good" expression => strcmp($(expected_good), $(test.actual_good)); "ok_content_bad" expression => strcmp($(expected_bad), $(test.actual_bad)); methods: "" usebundle => dcs_passif_expected("ok_filestats_good_1_2,ok_filestats_good_2_3,ok_filestats_bad_1_2,ok_filestats_bad_2_3,ok_content_good,ok_content_bad", "", $(this.promise_filename)), inherit => "true"; reports: EXTRA:: "OK: As expected good '$(expected_good)'" if => "ok_content_good"; "OK: As expected bad '$(expected_bad)'" if => "ok_content_bad"; "OK: good filestats $(filestats_good_str) change from step 1 to step 2" if => "ok_filestats_good_1_2"; "OK: good filestats $(filestats_good_str) change from step 2 to step 3" if => "ok_filestats_good_2_3"; "OK: bad filestats $(filestats_bad_str) change from step 1 to step 2" if => "ok_filestats_bad_1_2"; "OK: bad filestats $(filestats_bad_str) don't change from step 2 to step 3" if => "ok_filestats_bad_2_3"; DEBUG:: "FAIL: Expected '$(expected_good)' <> '$(test.actual_good)'" if => "!ok_content_good"; "FAIL: Expected '$(expected_bad)' <> '$(test.actual_bad)'" if => "!ok_content_bad"; "FAIL: good filestats $(filestats_good_str) don't change enough from step 1 to step 2" if => "!ok_filestats_good_1_2"; "FAIL: good filestats $(filestats_good_str) don't change enough from step 2 to step 3" if => "!ok_filestats_good_2_3"; "FAIL: bad filestats $(filestats_bad_str) don't change enough from step 1 to step 2" if => "!ok_filestats_bad_1_2"; "FAIL: bad filestats $(filestats_bad_str) change from step 2 to step 3" if => "!ok_filestats_bad_2_3"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_html_escape.cf0000644000000000000000000000330715010704253027043 0ustar00rootroot00000000000000####################################################### # # Test that characters are NOT escaped outside of variables # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_suppress_fail" string => "!any", meta => { "redmine7620" }; vars: "template_file" string => "$(this.promise_filename).mustache"; files: "$(G.testfile)" create => "true", edit_template => "$(template_file)", template_method => "mustache", template_data => readjson("$(this.promise_filename).json", 10000); reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile) using $(this.promise_filename).json"; } ####################################################### bundle agent check { vars: "expect" string => readfile("$(this.promise_filename).expected", 10000); "actual" string => readfile("$(G.testfile)", 10000); classes: "ok" expression => strcmp("$(expect)", "$(actual)"); reports: DEBUG:: "expect: '$(expect)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_from_json_or_classic_array.cf0000644000000000000000000001365615010704253032162 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: any:: "json_data"; "array_data"; } bundle agent json_data { vars: any:: "key_values" data => ' { "one" : "1", "two": "2", "three": "3", }'; } bundle agent array_data { vars: any:: "key_values[one]" string => "1"; "key_values[two]" string => "2"; "key_values[three]" string => "3"; } bundle agent test { meta: "description" -> { "CFE-3124" } string => "Test that rendering mustache from classic arrays works like rendering from JSON data"; "test_soft_fail" string => "any", meta => { "CFE-3124" }; vars: "cases" slist => { "from_json_with_explicit_data", "from_array_with_explicit_data", "from_json_with_implicit_datastate", "from_array_with_implicit_datastate", "from_json_with_bundlestate", "from_array_with_bundlestate", "from_json_with_explicit_datastate", "from_array_with_explicit_datastate", }; files: any:: "$(G.testdir)/$(this.handle)" create => "true", handle => "from_json_with_explicit_data", template_method => "inline_mustache", template_data => @(json_data.key_values), edit_template_string => "TEMPLATE=RENDERED {{#-top-}} {{@}}={{.}} {{/-top-}}"; "$(G.testdir)/$(this.handle)" create => "true", handle => "from_array_with_explicit_data", template_method => "inline_mustache", template_data => @(array_data.key_values), edit_template_string => "TEMPLATE=RENDERED {{#-top-}} {{@}}={{.}} {{/-top-}}"; "$(G.testdir)/$(this.handle)" create => "true", handle => "from_json_with_implicit_datastate", template_method => "inline_mustache", edit_template_string => "TEMPLATE=RENDERED {{#vars.json_data.key_values}} {{@}}={{.}} {{/vars.json_data.key_values}}"; "$(G.testdir)/$(this.handle)" create => "true", handle => "from_array_with_implicit_datastate", template_method => "inline_mustache", edit_template_string => "TEMPLATE=RENDERED {{#vars.array_data.key_values}} {{@}}={{.}} {{/vars.array_data.key_values}}"; "$(G.testdir)/$(this.handle)" create => "true", handle => "from_json_with_bundlestate", template_method => "inline_mustache", template_data => bundlestate( "json_data" ), edit_template_string => "TEMPLATE=RENDERED {{#key_values}} {{@}}={{.}} {{/key_values}}"; "$(G.testdir)/$(this.handle)" create => "true", handle => "from_array_with_bundlestate", template_method => "inline_mustache", template_data => bundlestate( "array_data" ), edit_template_string => "TEMPLATE=RENDERED {{#key_values}} {{@}}={{.}} {{/key_values}}"; "$(G.testdir)/$(this.handle)" create => "true", handle => "from_json_with_explicit_datastate", template_method => "inline_mustache", template_data => datastate(), edit_template_string => "TEMPLATE=RENDERED {{#vars.json_data.key_values}} {{@}}={{.}} {{/vars.json_data.key_values}}"; "$(G.testdir)/$(this.handle)" create => "true", handle => "from_array_with_explicit_datastate", template_method => "inline_mustache", template_data => datastate(), edit_template_string => "TEMPLATE=RENDERED {{#vars.array_data.key_values}} {{@}}={{.}} {{/vars.array_data.key_values}}"; # "datastate()$(const.n)$(with)" # with => string_mustache("{{%-top-}}", datastate() ); } bundle agent check { vars: # Here we read in the data file create by each test case so that we can # check if it was rendered as expected. Reading in the data as an env file # we can ignore ordering which classic arrays do not promise. "env_$(test.cases)" data => readenvfile( "$(G.testdir)/$(test.cases)" ); "passed_tests" slist => classesmatching( ".*", "class_for_passing_case" ); "implicitly_failed_tests" slist => classesmatching( ".*", "class_for_failing_case" ); "expected_passing" slist => maplist( "passed_$(this)", @(test.cases) ); classes: "passed_$(test.cases)" and => { strcmp( "1", "$(env_$(test.cases)[one])" ), strcmp( "2", "$(env_$(test.cases)[two])" ), strcmp( "3", "$(env_$(test.cases)[three])" ), strcmp( "TEMPLATE", "RENDERED" ), }, meta => { "class_for_passing_case" }, comment => "We pass a test case if each expected key value pair is found in the rendered data"; "implicitly_failed_$(test.cases)" not => "passed_$(test.cases)", meta => { "class_for_failing_case" }, comment => "With no passing class for the test case, we must have failed"; "ok" and => { @(expected_passing) }; "fail" expression => isgreaterthan( length( "$(this.bundle).implicitly_failed_tests" ), 0 ); reports: ok:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; DEBUG|EXTRA:: "test cases passed: $(with)" with => join(", ", passed_tests ); "test cases that failed implicitly: $(with)" with => join(", ", implicitly_failed_tests ); "Output from each test case:"; "$(G.testdir)/$(test.cases)" printfile => my_cat( $(this.promiser) ); } body printfile my_cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle agent __main__ { methods: any:: "init"; "test"; "check"; } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_container_serialization.cf.mustache0000644000000000000000000000006315010704253033302 0ustar00rootroot00000000000000{{name}}{{$data}}{{name}} {{name}}{{%data}}{{name}}cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_render_quote.cf.mustache0000644000000000000000000000055315010704253031063 0ustar00rootroot00000000000000# Escaped variable references by default: {{vars.init.variable_containing_double_quote}} {{vars.init.variable_containing_single_quote}} # Unescaped variable references: {{&vars.init.variable_containing_double_quote}} {{&vars.init.variable_containing_single_quote}} {{{vars.init.variable_containing_double_quote}}} {{{vars.init.variable_containing_single_quote}}} cfengine-3.24.2/tests/acceptance/10_files/templating/edit_template_string/0000755000000000000000000000000015010704253026557 5ustar00rootroot00000000000000mustache_edit_template_string_vs_edit_template.cf0000644000000000000000000000510715010704253040524 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templating/edit_template_stringbody common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/pghba.conf-from-edit_template" delete => tidy; "$(G.testdir)/pghba.conf-from-edit_template_string" delete => tidy; } bundle agent test { meta: "description" -> { "CFE-2910" } string => "Test that there is no difference when rendering the same mustache template with edit_template and edit_template_string"; vars: "pghbadirectives" data => '[ { "type": "local", "database": "all", "user": "all", "address": "", "method": "trust" }, { "type": "host", "database": "replication", "user": "all", "address": "primary-replication", "method": "trust" }, { "type": "host", "database": "replication", "user": "all", "address": "secondary-replication", "method": "trust" } ]'; # Reparent the config so that we have a named key to iterate over. "conf" data => mergedata( '{ "pghba": pghbadirectives }' ); files: "$(G.testdir)/pghba.conf-from-edit_template" create => "true", template_method => "mustache", template_data => @(conf), edit_template => '$(this.promise_dirname)/pghba.conf.mustache'; "$(G.testdir)/pghba.conf-from-edit_template_string" create => "true", template_method => "inline_mustache", template_data => @(conf), edit_template_string => readfile( '$(this.promise_dirname)/pghba.conf.mustache' ); reports: DEBUG|EXTRA:: "$(G.testdir)/pghba.conf-from-edit_template" printfile => cat( "$(G.testdir)/pghba.conf-from-edit_template"); "$(G.testdir)/pghba.conf-from-edit_template_string" printfile => cat( "$(G.testdir)/pghba.conf-from-edit_template_string"); } bundle agent check { methods: "Pass/FAIL" usebundle => dcs_check_diff_expected("$(G.testdir)/pghba.conf-from-edit_template", "$(G.testdir)/pghba.conf-from-edit_template_string", "$(this.promise_filename)", "no"); } body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } cfengine-3.24.2/tests/acceptance/10_files/templating/edit_template_string/pghba.conf.mustache0000644000000000000000000000014215010704253032314 0ustar00rootroot00000000000000{{#pghba}} {{{type}}} {{{database}}} {{{user}}} {{{address}}} {{{method}}} {{/pghba}} mustache_edit_template_string_vs_string_mustache.cf0000644000000000000000000000705315010704253041105 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templating/edit_template_stringbody common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/pghba.conf-from-edit_template_string" delete => tidy; "$(G.testdir)/pghba.conf-from-string_mustache" delete => tidy; } bundle agent test { meta: "description" -> { "CFE-2910" } string => "Test that there is no difference when rendering the same mustache template with edit_template and edit_template_string"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; vars: "pghbadirectives" data => '[ { "type": "local", "database": "all", "user": "all", "address": "", "method": "trust" }, { "type": "host", "database": "replication", "user": "all", "address": "primary-replication", "method": "trust" }, { "type": "host", "database": "replication", "user": "all", "address": "secondary-replication", "method": "trust" } ]'; # Reparent the config so that we have a named key to iterate over. "conf" data => mergedata( '{ "pghba": pghbadirectives }' ); files: "$(G.testdir)/pghba.conf-from-edit_template_string" create => "true", template_method => "inline_mustache", template_data => @(conf), edit_template_string => readfile( '$(this.promise_dirname)/pghba.conf.mustache' ); "$(G.testdir)/pghba.conf-from-edit_template_string" comment => "We need to append a blank line in order to match up with report_to_file from string_mustache", edit_line => lines_present( "" ); reports: # This is how we get a file from string_mustache "$(with)" with => string_mustache( readfile('$(this.promise_dirname)/pghba.conf.mustache'), @(conf) ), report_to_file => "$(G.testdir)/pghba.conf-from-string_mustache", if => not( fileexists( "$(G.testdir)/pghba.conf-from-string_mustache" )); DEBUG|EXTRA:: "$(G.testdir)/pghba.conf-from-edit_template_string" printfile => cat( "$(G.testdir)/pghba.conf-from-edit_template_string"); "$(G.testdir)/pghba.conf-from-string_mustache" printfile => cat( "$(G.testdir)/pghba.conf-from-string_mustache" ); } bundle agent check { methods: "Pass/FAIL" usebundle => dcs_check_diff_expected("$(G.testdir)/pghba.conf-from-string_mustache", "$(G.testdir)/pghba.conf-from-edit_template_string", "$(this.promise_filename)", "no"); } body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle edit_line lines_present(lines) # @brief Ensure `lines` are present in the file. Lines that do not exist are appended to the file # @param List or string that should be present in the file # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "nameservers" slist => { "8.8.8.8", "8.8.4.4" }; # # files: # "/etc/resolv.conf" edit_line => lines_present( @(nameservers) ); # "/etc/ssh/sshd_config" edit_line => lines_present( "PermitRootLogin no" ); # } # ``` { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_html_escape.cf.expected0000644000000000000000000000002215010704253030632 0ustar00rootroot00000000000000& == & & ~= & mustache_no_fallback_to_datastate_with_undefined_parsejson_storejson.cf.mustache0000644000000000000000000000005615010704253042543 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingVar from datastate: {{{vars.sys.cf_version}}} cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_top_level_iteration.cf0000644000000000000000000000172615010704253030631 0ustar00rootroot00000000000000####################################################### # # Demo of Mustache templates with top-level iteration # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "mydata1" data => '{ "a": 100 }'; "mydata2" data => '[ "p", "q" ]'; "actual1" string => string_mustache("{{#-top-}}key {{@}} value {{.}} {{/-top-}}", mydata1); "actual2" string => string_mustache("{{#-top-}}value {{.}} {{/-top-}}", mydata2); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/templating/demo.mustache0000644000000000000000000000036515010704253025034 0ustar00rootroot00000000000000

    {{header}}

    {{#bug}} {{/bug}} {{#items}} {{#first}}
  • {{name}}
  • {{/first}} {{#link}}
  • {{name}}
  • {{/link}} {{/items}} {{#empty}}

    The list is empty.

    {{/empty}} cfengine-3.24.2/tests/acceptance/10_files/templating/timed/0000755000000000000000000000000015010704253023453 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templating/timed/expired_edit_line_locks.cf0000644000000000000000000000262515010704253030641 0ustar00rootroot00000000000000# Check whether file promises have a shorter expiry time than edit_line promises # resulting from templates. This will create an empty file because the file is # opened for editing, but all the edit_line promises have expired. body common control { inputs => { "../../../dcs.cf.sub", "../../../plucked.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent test { commands: # Note, no -K, we are testing locks. "$(sys.cf_agent) -v -D AUTO,DEBUG -f $(this.promise_filename).sub" contain => in_shell; } bundle agent check { methods: test_pass_1:: "any" usebundle => dcs_wait($(this.promise_filename), 70); vars: test_pass_2:: "content_edit_line" string => readfile("$(G.testfile).edit_line", 10000); "content_cftemplate" string => readfile("$(G.testfile).cftemplate", 10000); "content_mustache" string => readfile("$(G.testfile).mustache", 10000); classes: test_pass_2:: "ok_edit_line" expression => strcmp($(content_edit_line), "text"), scope => "namespace"; "ok_cftemplate" expression => strcmp($(content_cftemplate), "text"), scope => "namespace"; "ok_mustache" expression => strcmp($(content_mustache), "text"), scope => "namespace"; methods: test_pass_2:: "any" usebundle => dcs_passif("ok_edit_line.ok_cftemplate.ok_mustache", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/templating/timed/expired_edit_line_locks.cf.sub0000644000000000000000000000132215010704253031422 0ustar00rootroot00000000000000body common control { inputs => { "../../../dcs.cf.sub", "../../../plucked.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent init { methods: "any" usebundle => file_make("$(G.testfile).template", "text"); } bundle agent test { files: "$(G.testfile).edit_line" create => "true", edit_line => insert_lines("text"), edit_defaults => empty; "$(G.testfile).cftemplate" create => "true", edit_template => "$(G.testfile).template", template_method => "cfengine"; "$(G.testfile).mustache" create => "true", edit_template => "$(G.testfile).template", template_method => "mustache"; } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_render_quote.cf.expected0000644000000000000000000000042515010704253031051 0ustar00rootroot00000000000000# Escaped variable references by default: Something "special" with quotes Something 'special' with quotes # Unescaped variable references: Something "special" with quotes Something 'special' with quotes Something "special" with quotes Something 'special' with quotes mustache_no_render_with_undefined_direct_data.cf0000644000000000000000000000504015010704253034046 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that a mustache template does not try to render when its given an invalid container directly"; } bundle agent init { # First we make sure to start of with am emty target files: "$(G.testfile)" handle => "init_testfile_absent", delete => tidy; "$(G.testfile)" handle => "init_testfile_present", create => "true", depends_on => { "init_testfile_absent" }, comment => "We first remove the file, and then re-create it so that we know that it is empty to start with."; } bundle agent test { # Second we promise to render template passing data that does not exist via template_data vars: "classes" slist => classesmatching("template_render_with_non_existing_data_container.*"); files: "$(G.testfile)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => @(missing_ns:missing_bundle.missing_data), classes => scoped_classes_generic("bundle", "template_render_with_non_existing_data_container"); reports: DEBUG:: "$(this.bundle): Found class '$(classes)'"; } bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine7699" }; # Finally we look to see what classes were defined, and look at the target file to see if it has changed. vars: "expected" string => ""; "actual" string => readfile($(G.testfile), inf); classes: # I assume here that the promise should not even be actuated when invalid # data is provided thus we should have found 0 classes "fail_classes" expression => isgreaterthan(length("test.classes"), 0); # Another failure condition is if the rendered file is not empty as # expected "fail_content" not => strcmp($(expected), $(actual)); "fail" or => { "fail_classes", "fail_content" }; "exception" and => { "fail", "ok" }; reports: DEBUG:: "DEBUG $(this.bundle): Found '$(test.classes)' that should not have been found" if => "fail_classes"; "DEBUG $(this.bundle): Found the content of $(G.testfile) was not as expected" if => "fail_content"; fail:: "$(this.promise_filename) FAIL"; !fail|exception:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } mustache_no_render_with_undefined_direct_data.cf.mustache0000644000000000000000000000001115010704253035647 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingHi there mustache_no_render_with_undefined_mergedata.cf.mustache0000644000000000000000000000001115010704253035335 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingHi there cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_invalid_template_data.cf0000644000000000000000000000401715010704253031070 0ustar00rootroot00000000000000####################################################### # # Test that invalid mustache template data is not replaced by datastate(). # CFE-2194 ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "template_content" string => ' template_data: {{%-top-}} '; files: "$(G.testfile).template" create => "true", edit_line => insert_lines($(template_content)), edit_defaults => empty; "$(G.testfile).output" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "template_file" string => "$(G.testfile).template"; "invalid_data" data => parsejson('{ "port": 3508, "protocol": 2, "filepath": "$(no_such_variable)", "encryption-level": 256, "loglevel": 1, "users": [ {"user": "thomas", "level": "admin"}, {"user": "malin", "level": "guest"} ] }'); files: "$(G.testfile).output" create => "true", edit_template => "$(template_file)", template_method => "mustache", template_data => @(invalid_data); classes: "invalid_data_exists" expression => isvariable("invalid_data"); reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile).output"; "invalid_data defined!" if => "invalid_data_exists"; } ####################################################### bundle agent check { classes: "ok" -> {"CFE-2194"} not => fileexists("$(G.testfile).output"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } mustache_no_fallback_to_datastate_with_undefined_direct_data.cf.mustache0000644000000000000000000000005615010704253040674 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingVar from datastate: {{{vars.sys.cf_version}}} mustache_no_fallback_to_datastate_with_undefined_mergedata.cf.mustache0000644000000000000000000000005615010704253040362 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingVar from datastate: {{{vars.sys.cf_version}}} cfengine-3.24.2/tests/acceptance/10_files/templating/empty_template_empty_file.cf0000644000000000000000000000315215010704253030132 0ustar00rootroot00000000000000####################################################### # # Redmine#3870: Test that an empty CFEngine template will empty the file. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" edit_defaults => init_empty, create => "true", edit_line => init_insert_lines("TEXT NOT GOOD"); } bundle edit_line init_insert_lines(lines) { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } body edit_defaults init_empty { empty_file_before_editing => "true"; edit_backup => "false"; #max_file_size => "300000"; } ####################################################### bundle agent test { vars: "template_file" string => "$(this.promise_filename).template"; files: "$(G.testfile)" edit_template => "$(template_file)"; reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile)"; } ####################################################### bundle agent check { vars: "expect" string => ""; "actual" string => readfile("$(G.testfile)", 1000); classes: "ok" expression => regcmp("$(expect)", "$(actual)"); reports: DEBUG:: "expect: '$(expect)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_expect_list_find_string.cf.mustache0000644000000000000000000000007115010704253033273 0ustar00rootroot00000000000000#DO NOT EDIT - MANAGED FILE {{#mykeys}}{{.}} {{/mykeys}} cfengine-3.24.2/tests/acceptance/10_files/templating/demo.expected0000644000000000000000000000020215010704253025012 0ustar00rootroot00000000000000

    Colors

  • red
  • green
  • blue
  • cfengine-3.24.2/tests/acceptance/10_files/templating/basic_classes.template0000644000000000000000000000014715010704253026706 0ustar00rootroot00000000000000[%CFEngine BEGIN %] one [%CFEngine END %] [%CFEngine two:: %] two [%CFEngine default:three:: %] threecfengine-3.24.2/tests/acceptance/10_files/templating/mustache_invalid_template.cf0000644000000000000000000000307715010704253030104 0ustar00rootroot00000000000000####################################################### # # Test that invalid mustache template does not cause a segfault # Redmine:4702 (https://cfengine.com/dev/issues/4702) ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "template_content" string => ' {{#vars.sys.interfaces}}{{.}} {{#vars.sys.interface_flags[{{.}}]}} {{/vars.sys.interfaces}}'; files: "$(G.testfile).template" create => "true", edit_line => insert_lines($(template_content)), edit_defaults => empty; "$(G.testfile).output" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "template_file" string => "$(G.testfile).template"; files: "$(G.testfile).output" create => "true", edit_template => "$(template_file)", template_method => "mustache"; reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile).output"; } ####################################################### bundle agent check { classes: "ok" expression => "any", comment => "If we made it to here we didn't segfault"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_section.cf0000644000000000000000000000167515010704253026231 0ustar00rootroot00000000000000####################################################### # # Check that we warn about Mustache sections over non-iterables/non-booleans # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { methods: "" usebundle => dcs_fini($(G.testfile)); } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output1(".*Mustache sections can only take a boolean or a container.+value, but section 'x' isn't getting one of those.*", "$(sys.cf_agent) -KI -f $(this.promise_filename).sub | grep Mustache", $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/inline_demo.expected0000644000000000000000000000002215010704253026350 0ustar00rootroot00000000000000This is a test: 1 mustache_no_fallback_to_datastate_with_undefined_mergedata.cf0000644000000000000000000000506615010704253036560 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that a mustache template does not fallback to datastate when its given an invalid container via mergedata"; } bundle agent init { # First we make sure to start with an empty target file files: "$(G.testfile)" handle => "init_testfile_absent", delete => tidy; "$(G.testfile)" handle => "init_testfile_present", create => "true", depends_on => { "init_testfile_absent" }, comment => "We first remove the file, and then re-create it so that we know that it is empty to start with."; } bundle agent test { # Second we try to render the template using the result of mergedata with a non existing container vars: "classes" slist => classesmatching("template_render_with_non_existing_data_container.*"); files: "$(G.testfile)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => mergedata("missing_ns:missing_bundle.missing_data"), classes => scoped_classes_generic("bundle", "template_render_with_non_existing_data_container"); reports: DEBUG:: "$(this.bundle): Found class '$(classes)'"; } bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine7699" }; # Finally we check to see what classes were defined, and inspect the target file for changes. vars: "expected" string => ""; "actual" string => readfile($(G.testfile), inf); classes: # I assume here that the promise should not even be actuated when invalid # data is provided thus we should have found 0 classes "fail_classes" expression => isgreaterthan(length("test.classes"), 0); # Another failure condition is if the rendered file is not empty as # expected "fail_content" not => strcmp($(expected), $(actual)); "fail" or => { "fail_classes", "fail_content" }; "exception" and => { "fail", "ok" }; reports: DEBUG:: "DEBUG $(this.bundle): Found '$(test.classes)' that should not have been found" if => "fail_classes"; "DEBUG $(this.bundle): Found the content of $(G.testfile) was not as expected" if => "fail_content"; fail:: "$(this.promise_filename) FAIL"; !fail|exception:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } cfengine-3.24.2/tests/acceptance/10_files/templating/large_template_blocks.cf0000644000000000000000000000271415010704253027211 0ustar00rootroot00000000000000####################################################### # # Test instatiation of template blocks larger than 4096 characters. # Redmine #3852 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "template_file" string => "$(this.promise_filename).template"; classes: files: "$(G.testfile)" create => "true", edit_template => "$(template_file)"; reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile)"; } ####################################################### bundle agent check { vars: "expected" int => "110"; "actual" int => countlinesmatching(".*0123456789.*", "$(G.testfile)"); classes: "ok" expression => strcmp("$(expected)", "$(actual)"); reports: DEBUG:: "expected: '$(expected)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_container_serialization.cf0000644000000000000000000000404215010704253031473 0ustar00rootroot00000000000000####################################################### # # Demo of Mustache templates with no external JSON data # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "a" string => "[]"; "b" string => "{}"; "c" string => '{"a":100,"b":200}'; "d" string => '[{"a":100,"b":200},null,true,false,"abcde"]'; "test" slist => { "a", "b", "c", "d" }; methods: "" usebundle => file_mustache_jsonstring("$(this.promise_filename).mustache", '{ "name": "$(test)", "data": $($(test)) }', "$(G.testdir)/$(test)"); "" usebundle => test2; } bundle agent test2 { files: "$(G.testfile).expected" create => "true", edit_line => insertthem; "$(G.testfile).actual" create => "true", edit_line => readthem; } bundle edit_line insertthem { vars: "test" slist => { @(test.test) }; "parsed_$(test)" data => parsejson("$(test.$(test))"); "fulldump_$(test)" string => storejson("parsed_$(test)"); insert_lines: "$(test)$(test.$(test))$(test) $(test)$(fulldump_$(test))$(test)" insert_type => "preserve_block"; reports: EXTRA:: "Full dump of $(test) is $(fulldump_$(test))"; } bundle edit_line readthem { vars: "test" slist => { @(test.test) }; "read_$(test)" string => readfile("$(G.testdir)/$(test)", 1k); insert_lines: "$(read_$(test))"; reports: EXTRA:: "For $(test) we got '$(read_$(test))'"; } ####################################################### bundle agent check { vars: "test" slist => { @(test.test) }; methods: "" usebundle => dcs_check_diff("$(G.testfile).expected", "$(G.testfile).actual", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_section.cf.sub0000644000000000000000000000060715010704253027013 0ustar00rootroot00000000000000body common control { inputs => { "../../plucked.cf.sub" }; bundlesequence => { test }; version => "1.0"; } bundle agent test { methods: "m" usebundle => file_mustache_jsonstring("$(this.promise_filename).mustache", '{ "x": "y" }', "$(sys.workdir)/state/out.txt"); } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_top_level_iteration.cf.expected.json0000644000000000000000000000021315010704253033367 0ustar00rootroot00000000000000{ "actual1": "key a value 100 ", "actual2": "value p value q ", "mydata1": { "a": 100 }, "mydata2": [ "p", "q" ] } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_abuse.cf0000644000000000000000000000543015010704253025655 0ustar00rootroot00000000000000####################################################### # # Abusive Mustache relationship # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "tests" slist => { "0", "1", "2", "3", "4", "5", "6" }; "templates" data => parsejson(' [ "{{x}}", "{{x}} {{y}}", "{{null}}", "{{}}", "{{#boolean}}IT IS TRUE{{/boolean}}", "{{^boolean}}IT IS FALSE{{/boolean}}", "{{#list}}{{k}}={{v}}, {{/list}}" ]'); files: "$(G.testfile).$(tests).tmpl" create => "true", edit_defaults => test_empty, edit_line => init_insert_lines("$(templates[$(tests)])"); } bundle edit_line init_insert_lines(lines) { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } ####################################################### bundle agent test { vars: "tdata" data => parsejson(' [ "{ \\\"x\\\": 123 }", "{ \\\"x\\\": 123, \\\"y\\\": 456 }", "[ null ]", "{ \\\"x\\\": 123, \\\"y\\\": 456 }", "{\\\"boolean\\\": true}", "{\\\"boolean\\\": false}", "{ \\\"list\\\": [ { \\\"k\\\": 789, \\\"v\\\": 0 }, { \\\"k\\\": null, \\\"v\\\": true }, { \\\"k\\\": -1, \\\"v\\\": -2 } ] }", ]'); files: "$(G.testfile).$(init.tests)" create => "true", edit_defaults => test_empty, edit_template => "$(G.testfile).$(init.tests).tmpl", template_method => "mustache", template_data => parsejson("$(tdata[$(init.tests)])"); reports: DEBUG:: "Rendering template file $(G.testfile).$(init.tests).tmpl to $(G.testfile).$(init.tests)"; } body edit_defaults test_empty { empty_file_before_editing => "true"; edit_backup => "false"; } ####################################################### bundle agent check { vars: "expected" data => parsejson(' [ "123", "123 456", "", "{{}}", "IT IS TRUE" "IT IS FALSE", "789=0, =true, -1=-2, " ]'); "actual_$(init.tests)" string => readfile("$(G.testfile).$(init.tests)", 10000); classes: "ok_$(init.tests)" expression => regcmp("$(expected[$(init.tests)])", "$(actual_$(init.tests))"); "ok" and => { ok_0, ok_1, ok_2, ok_3, ok_4, ok_5 }; reports: DEBUG:: "OK $(init.tests): Expected '$(expected[$(init.tests)])' == '$(actual_$(init.tests))'" if => "ok_$(init.tests)"; "FAIL $(init.tests): Expected '$(expected[$(init.tests)])' <> '$(actual_$(init.tests))'" if => "!ok_$(init.tests)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_no_render_with_undefined_mergedata.cf0000644000000000000000000000505615010704253033622 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that a mustache template does not try to render when its given an invalid container via mergedata"; } bundle agent init { # First we make sure to start with an empty target file files: "$(G.testfile)" handle => "init_testfile_absent", delete => tidy; "$(G.testfile)" handle => "init_testfile_present", create => "true", depends_on => { "init_testfile_absent" }, comment => "We first remove the file, and then re-create it so that we know that it is empty to start with."; } bundle agent test { # Second we try to render the template using the result of mergedata with a non existing container vars: "classes" slist => classesmatching("template_render_with_non_existing_data_container.*"); files: "$(G.testfile)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => mergedata("missing_ns:missing_bundle.missing_data"), classes => scoped_classes_generic("bundle", "template_render_with_non_existing_data_container"); reports: DEBUG:: "$(this.bundle): Found class '$(classes)'"; } bundle agent check { meta: "test_soft_fail" string => "any", meta => { "redmine7699" }; # Finally we check to see what classes were defined, and inspect the target file for changes. vars: "expected" string => ""; "actual" string => readfile($(G.testfile), inf); classes: # I assume here that the promise should not even be actuated when invalid # data is provided thus we should have found 0 classes "fail_classes" expression => isgreaterthan(length("test.classes"), 0); # Another failure condition is if the rendered file is not empty as # expected "fail_content" not => strcmp($(expected), $(actual)); "fail" or => { "fail_classes", "fail_content" }; "exception" and => { "fail", "ok" }; reports: DEBUG:: "DEBUG $(this.bundle): Found '$(test.classes)' that should not have been found" if => "fail_classes"; "DEBUG $(this.bundle): Found the content of $(G.testfile) was not as expected" if => "fail_content"; fail:: "$(this.promise_filename) FAIL"; !fail|exception:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } classic_template_wont_render_cf_null_with_empty_datacontainer.cf.tpl0000644000000000000000000000033015010704253040167 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingThis is a test file $(template_file.data_container[$(template_file.index)][bogus]) $(template_file.data_container[$(template_file.index)][foo]) $(template_file.data_container[$(template_file.index)][bar]) more stuff cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_html_escape.cf.mustache0000644000000000000000000000006015010704253030644 0ustar00rootroot00000000000000{{{vars.test.amp}}} == & {{vars.test.amp}} ~= & cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_render_quote.cf0000644000000000000000000000325715010704253027257 0ustar00rootroot00000000000000####################################################### # # Acceptance test to ensure that mustache renders quotes in variables # correctly. # # Redmine: https://dev.cfengine.com/issues/6516 ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "variable_containing_double_quote" string => 'Something "special" with quotes'; "variable_containing_single_quote" string => "Something 'special' with quotes"; files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "template_file" string => "$(this.promise_filename).mustache"; files: "$(G.testfile)" create => "true", edit_template => "$(template_file)", template_method => "mustache"; reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile)"; } ####################################################### bundle agent check { vars: "expect" string => readfile("$(this.promise_filename).expected", 4000); "actual" string => readfile("$(G.testfile)", 4000); classes: "ok" expression => regcmp("$(expect)", "$(actual)"); reports: DEBUG:: "expect: '$(expect)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_section.cf.sub.mustache0000644000000000000000000000002115010704253030611 0ustar00rootroot00000000000000{{#x}}{{.}}{{/x}}cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_inline_demo.cf0000644000000000000000000000307315010704253027041 0ustar00rootroot00000000000000####################################################### # # Demo from mustache.github.io # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "template_str" string => "This is a test: {{a}}"; "d" data => parsejson('{ "a": "1" }'); files: "$(G.testfile)" create => "true", edit_template_string => "$(template_str)", template_method => "inline_mustache", template_data => "@(test.d)"; reports: DEBUG:: "Rendering template file $(template_str) to $(G.testfile)"; } ####################################################### bundle agent check { vars: "expect" string => readfile("$(init.origtestdir)/inline_demo.expected", 10000); "actual" string => readfile("$(G.testfile)", 10000); classes: "ok" expression => regcmp("$(expect)", "$(actual)"); reports: DEBUG:: "expect: '$(expect)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/templating/cftemplate.cf0000644000000000000000000000276715010704253025023 0ustar00rootroot00000000000000####################################################### # # Test a complete CFEngine template, including trailing newlines. # Redmine #1900 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### ####################################################### bundle agent test { meta: "description" -> { "CFE-270" } string => "Test that classic templating does not insert extra newlines"; "test_soft_fail" -> { "CFE-270" } string => "any", meta => { "CFE-270" }; files: "$(G.testfile).expected" copy_from => my_local_cp("$(this.promise_filename).expected"); "$(G.testfile).actual" create => "true", edit_defaults => my_init_empty, edit_template => "$(this.promise_filename).template"; } ####################################################### body copy_from my_local_cp(from) { source => "$(from)"; } body edit_defaults my_init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 classic_template_wont_render_cf_null_with_empty_datacontainer.cf0000644000000000000000000000460015010704253037375 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingbody common control { # ignore_missing_bundles => "true"; inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" string => "Test that classic templates will not render cf_null when dereferencing an absent data container."; "test_soft_fail" string => "cfengine_3_7|cfengine_3_8|cfengine_3_9", meta => { "CFE-2422" }; vars: # No vars are expected to be found here "matching_vars" slist => variablesmatching(".*", "nomatch"); methods: "any" usebundle => cmerge( "absent_container", @(matching_vars) ); "any" usebundle => template_file( $(G.testfile), "$(this.promise_filename).tpl", @(cmerge.absent_container)); } bundle agent check { classes: "some_content" expression => regline( "This is a test file", $(G.testfile) ); "cf_null_in_rendered_file" expression => regline( ".*cf_null.*", $(G.testfile) ); # The test should pass if the file is rendered without cf_null in the file "ok" expression => "some_content.!cf_null_in_rendered_file"; # The test should fail if the expected contnet is not rendered or if # cf_null is found in the rendered file. "fail" expression => "!some_content|cf_null_in_rendered_file"; methods: ok:: "" usebundle => dcs_pass( $(this.promise_filename) ); fail:: "" usebundle => dcs_fail( $(this.promise_filename) ); reports: DEBUG:: "Found some correct content in rendered file" if => "some_content"; "Found cf_null in rendered file but should not have" if => "cf_null_in_rendered_file"; } bundle agent template_file(file, template, data_container) { # Note: the classic template looks inside this bundle to dereference various # values from data_container. vars: "index" slist => getindices("data_container"); files: "$(file)" create => "true", edit_template => "$(template)"; reports: "$(this.bundle)"; } ### Picked from the STDLIB ### bundle agent cmerge(name, varlist) { vars: "$(name)" data => parsejson('[]'), policy => "free"; "$(name)" data => mergedata($(name), $(varlist)), policy => "free"; # iterates! "$(name)_str" string => format("%S", $(name)), policy => "free"; } cfengine-3.24.2/tests/acceptance/10_files/templating/missing_template_file.cf0000644000000000000000000000273015010704253027230 0ustar00rootroot00000000000000############################################################################## # # Redmine #4241: set correct classes if template is missing # ############################################################################## body common control { inputs => { "../../default.cf.sub", "../../plucked.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", edit_template => "$(this.promise_filename).nonexistent", classes => scoped_classes_generic("namespace", "test_file_template"); methods: DEBUG:: "report" usebundle => dcs_report_generic_classes("test_file_template"); } ####################################################### bundle agent check { classes: "ok" and => { "!test_file_template_kept", "test_file_template_repaired", # create => "true" "test_file_template_failed", # edit_template "!test_file_template_denied", "!test_file_template_timeout" }; reports: DEBUG.created:: "Correctly created the test file $(G.testfile)"; DEBUG.!created:: "Erroneously did not create the test file $(G.testfile)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/templating/cftemplate.cf.expected0000644000000000000000000000001115010704253026577 0ustar00rootroot000000000000001 2 3 4 5cfengine-3.24.2/tests/acceptance/10_files/templating/staging/0000755000000000000000000000000015010704253024005 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templating/staging/array_expansion.cf0000644000000000000000000000315715010704253027527 0ustar00rootroot00000000000000####################################################### # # Test array expansion for CFEngine templates. # Redmine #3442 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data[user-a][home]" string => "/tmp/test/user-a"; methods: "" usebundle => file_make("$(G.testfile).expected", "CASE1: passed var /tmp/test/user-a .foo .bar CASE2: local var /tmp/test/user-a .foo .bar"); "" usebundle => file_make("$(G.testfile).template", "CASE1: passed var $(const.dollar)($(const.dollar)(test2.info)[user-a][home]) .foo .bar CASE2: local var $(const.dollar)($(const.dollar)(test2.local_info)[user-a][home]) .foo .bar"); } ####################################################### bundle agent test { methods: "" usebundle => test2("init.data"); } bundle agent test2(info) { vars: "local_info" string => "init.data"; files: "$(G.testfile).actual" create => "true", edit_defaults => empty, edit_template => "$(G.testfile).template"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 mustache_no_render_with_undefined_parsejson_storejson.cf.mustache0000644000000000000000000000001115010704253037516 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/templatingHi there cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_html_escape.cf.json0000644000000000000000000000007315010704253030010 0ustar00rootroot00000000000000{ "vars": { "test": { "amp": "&" } } } cfengine-3.24.2/tests/acceptance/10_files/templating/missing_file.cf.sub0000644000000000000000000000074615010704253026132 0ustar00rootroot00000000000000############################################################################## # # Redmine #3573: establish message for missing target file with a template # ############################################################################## bundle agent run { files: "/no/such/file" create => "false", edit_defaults => init_empty, edit_template => "$(this.promise_filename)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_no_end.error.cf0000644000000000000000000000030315010704253027142 0ustar00rootroot00000000000000# This previously caused a crash (segfault), now we are testing that # it prints error and exits with 0. bundle agent main { reports: "With: $(with)" with => string_mustache("{{"); } cfengine-3.24.2/tests/acceptance/10_files/templating/mustache_repair_existing.cf0000644000000000000000000000334415010704253027754 0ustar00rootroot00000000000000####################################################### # # Test that _repaired classes are defined on template repair # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "origtestdir" string => dirname("$(this.promise_filename)"); files: "$(G.testfile)" create => "true", comment => "Need to see if we define repair when file exists"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "template_file" string => "$(init.origtestdir)/demo.mustache"; files: "$(G.testfile)" edit_template => "$(template_file)", template_method => "mustache", classes => classes_generic("templated_file"), template_data => readjson("$(init.origtestdir)/demo.json", 4096); reports: DEBUG:: "Rendering template file $(template_file) to $(G.testfile)"; } bundle agent check { vars: "expect" string => readfile("$(init.origtestdir)/demo.expected", 4096); "actual" string => readfile("$(G.testfile)", 4096); classes: "content_ok" expression => regcmp("$(expect)", "$(actual)"); "repair_ok" expression => "templated_file_repaired"; "ok" and => { "content_ok", "repair_ok" }; reports: DEBUG:: "expect: '$(expect)'"; "actual: '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_warn_only.cf0000644000000000000000000000260415010704253026332 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that body action_policy warn restricts mustache template rendering"; "story_id" string => "5535"; "covers" string => "dryrun_repaired"; } # Ref: https://dev.cfengine.com/issues/6739 ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } bundle agent test { vars: "template_target" string => "$(init.template_target)"; files: # The template should not be rendered because dryrun is set "$(template_target)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", action => warn_only, classes => classes_generic("mustache_warn"); } ####################################################### bundle agent check { classes: "fail" expression => regline("SHOULD NOT RENDER", $(test.template_target) ); "defined_class" expression => "mustache_warn_failed"; reports: !fail.defined_class:: "$(this.promise_filename) Pass"; fail|!defined_class:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/replace_patterns/0000755000000000000000000000000015010704253023540 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/replace_patterns/basic_replace.cf0000644000000000000000000000272215010704253026631 0ustar00rootroot00000000000000####################################################### # # Replace a pattern and use match.0 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN END"; "expected" string => "BEGIN_REPLACED END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ###################################################### # bundle agent test { files: "$(G.testfile).actual" edit_line => test_replace("$(init.parameters)"); } bundle edit_line test_replace(parameters) { replace_patterns: "^BEGIN$" replace_with => value("BEGIN_REPLACED"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/replace_patterns/noop_replace.cf0000644000000000000000000000343615010704253026526 0ustar00rootroot00000000000000####################################################### # # Replace a pattern and use match.0 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN kernel /vmlinuz-2.6.18-348.el5 ro noapic nolapic apci=off time process_timing=everything root=LABEL=/foo kernel /vmlinuz-2.6.18-348.el5 ro root=LABEL=/1 END"; "expected" string => "BEGIN kernel /vmlinuz-2.6.18-348.el5 ro noapic nolapic apci=off time process_timing=everything root=LABEL=/foo kernel /vmlinuz-2.6.18-348.el5 ro root=LABEL=/1 END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ###################################################### # bundle agent test { files: "$(G.testfile).actual" edit_line => test_replace("$(init.parameters)"); } bundle edit_line test_replace(parameters) { replace_patterns: # should not change anything "^.+$" replace_with => value("$(match.0)"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/replace_patterns/staging/0000755000000000000000000000000015010704253025174 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/replace_patterns/staging/advanced_replace.cf0000644000000000000000000000457215010704253030756 0ustar00rootroot00000000000000####################################################### # # Replace a pattern and use match.0 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN kernel /vmlinuz-2.6.18-348.el5 ro noapic nolapic apci=off time process_timing=everything root=LABEL=/foo kernel /vmlinuz-2.6.18-348.el5 ro root=LABEL=/1 END"; "parameters" string => "noapic nolapic apci=off time process_timing=everything"; "expected" string => "BEGIN kernel /vmlinuz-2.6.18-348.el5 ro root=LABEL=/1 noapic nolapic apci=off time process_timing=everything kernel /vmlinuz-2.6.18-348.el5 ro root=LABEL=/foo noapic nolapic apci=off time process_timing=everything END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ###################################################### # bundle agent test { files: "$(G.testfile).actual" edit_line => test_replace("$(init.parameters)"); } bundle edit_line test_replace(parameters) { replace_patterns: # replace the parameters with an empty string "$(parameters)" handle => "test_replace_parameters", replace_with => value(""); # should append $(parameters) to any line that begins with "kernel" "^\s*(kernel.+)$" depends_on => { "test_replace_parameters" }, replace_with => value("$(match.1) $(parameters)"); # should not change anything "^\s*(kernel.+)$" replace_with => value("$(match.0)"); } body replace_with value(x) { replace_value => "$(x)"; occurrences => "all"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/mustache_propagates_failure.cf.mustache0000644000000000000000000000000715010704253030071 0ustar00rootroot00000000000000foobar cfengine-3.24.2/tests/acceptance/10_files/this_promiser.cf0000644000000000000000000001356715010704253023422 0ustar00rootroot00000000000000####################################################### # # Test this.promiser on files promises # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body classes promiser0_generic { promise_repaired => { "$(this.promiser)_repaired", "$(this.promiser)_0_ok" }; promise_kept => { "$(this.promiser)_kept", "$(this.promiser)_0_ok" }; } body classes promiser1_generic { promise_repaired => { "$(this.promiser)_repaired", "$(this.promiser)_1_ok" }; promise_kept => { "$(this.promiser)_kept", "$(this.promiser)_1_ok" }; } body classes promiser2_generic { promise_repaired => { "$(this.promiser)_repaired", "$(this.promiser)_2_ok" }; promise_kept => { "$(this.promiser)_kept", "$(this.promiser)_2_ok" }; } body classes promiser3_generic { promise_repaired => { "$(this.promiser)_repaired", "$(this.promiser)_3_ok" }; promise_kept => { "$(this.promiser)_kept", "$(this.promiser)_3_ok" }; } body classes promiser4_generic { promise_repaired => { "$(this.promiser)_repaired", "$(this.promiser)_4_ok" }; promise_kept => { "$(this.promiser)_kept", "$(this.promiser)_4_ok" }; } bundle agent init { vars: "files" slist => { "aa", "ab", "ac", "ba", "bb", "bc" }; files: "$(G.testdir)/copy_me_source" create => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; commands: "$(G.true)" classes => promiser0_generic; files: # 6 promisers "$(G.testdir)/$(init.files)" create => "true", classes => promiser1_generic; # 3 promisers "$(G.testdir)/a.*" perms => m("666"), classes => promiser2_generic; # 2 promisers - 1 file inside the directory and the directory itself (as the # real promiser) "$(G.testdir)" file_select => by_exec_cmd, perms => m("666"), classes => promiser2_generic, depth_search => test_recurse; # 6 promisers - 6 files inside the directory and the directory itself (as the # real promiser) "$(G.testdir)" file_select => test_plain, depth_search => test_recurse, delete => tidyfiles, classes => promiser3_generic; "$(G.testdir)/copy_me" copy_from => local_cp("$(this.promiser)_source"); methods: "template_test" usebundle => template_test; } bundle agent template_test { vars: "testdir" string => "$(G.testdir)/template_test"; "cfe_files" slist => { "cfe_file1", "cfe_file2" }; "mustache_files" slist => { "mustache_file1", "mustache_file2" }; files: # create empty files so that we can test pattern and file_select cases "$(testdir)/." create => "true"; "$(testdir)/$(cfe_files)" create => "true"; "$(testdir)/$(mustache_files)" create => "true"; "$(testdir)/$(cfe_files).cf-template" create => "true", edit_line => insert_lines("Just a cfengine line for $(this.promiser)."); "$(testdir)/$(mustache_files).mustache" create => "true", edit_line => insert_lines("Just a mustache line for $(this.promiser)."); "$(testdir)/cfe_file[1,2]" perms => m("666"), template_method => "cfengine", edit_template => "$(this.promiser).cf-template", classes => promiser4_generic; "$(testdir)/mustache_.*" file_select => mustache_files, perms => m("666"), template_method => "mustache", edit_template => "$(this.promiser).mustache", classes => promiser4_generic; } body file_select mustache_files { leaf_name => { "@(template_test.mustache_files)" }; file_result => "leaf_name"; } body delete tidyfiles { dirlinks => "delete"; rmdirs => "true"; } body file_select test_plain { leaf_name => { "[a,b][a,b,c]" }; file_types => { "plain" }; file_result => "file_types.leaf_name"; } body file_select by_exec_cmd # Redmine #3530 { leaf_name => {"ba"}; exec_program => "$(G.ls) $(this.promiser)"; file_result => "leaf_name.exec_program"; } body depth_search test_recurse { depth => "inf"; } ####################################################### bundle agent check { vars: "ok_promisers" slist => classesmatching(".*_ok"); "ok_0_count" int => countclassesmatching(".*_0_ok"); "ok_1_count" int => countclassesmatching(".*_1_ok"); "ok_2_count" int => countclassesmatching(".*_2_ok"); "ok_3_count" int => countclassesmatching(".*_3_ok"); "ok_4_count" int => countclassesmatching(".*_4_ok"); "ok_pattern_promiser_count" int => countclassesmatching(".*__[01234]_ok"), comment => "the patterns should be cannonified and classes for them should be defined"; classes: "ok_expand" expression => none("__this_promiser_[0,1,2,3]_ok", ok_promisers); "ok0" expression => strcmp("$(ok_0_count)", 1); "ok1" expression => strcmp("$(ok_1_count)", 6); "ok2" expression => strcmp("$(ok_2_count)", 6); "ok3" expression => strcmp("$(ok_3_count)", 7); "ok4" expression => strcmp("$(ok_4_count)", 6); "ok5" expression => fileexists("$(G.testdir)/copy_me"); "ok_pattern" expression => strcmp("$(ok_pattern_promiser_count)", 3); "ok" and => { "ok_expand", "ok0", "ok1", "ok2", "ok3", "ok4", "ok5", "ok_pattern" }; reports: DEBUG:: "$(ok_promisers)"; "0: $(ok_0_count) (expected 1)"; "1: $(ok_1_count) (expected 6)"; "2: $(ok_2_count) (expected 6)"; "3: $(ok_3_count) (expected 7)"; "4: $(ok_4_count) (expected 6)"; "pattern promiser classes: $(ok_pattern_promiser_count) (expected 3)"; DEBUG.!ok5:: "5: file not copied"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 agent_control_files_single_copy_does_not_apply_to_nonmatching_files_5.cf0000644000000000000000000000254215010704253036652 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### # Body agent control is not defined, so files_single_copy should not match any files. #body agent control #{ # files_single_copy => { @(def.control_agent_files_single_copy) }; #} bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy does not prevent file patterns that do not match from being copied multiple times."; "test_skip_needs_work" string => "windows", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/two", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/zendesk_1779/0000755000000000000000000000000015010704253022337 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/zendesk_1779/zendesk_1779.cf.sub0000644000000000000000000000445015010704253025576 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init # Ensure there is a directory structure created with both plain files and # symlinks to a plain file. { files: "$(G.testdir)/." create => "true"; "$(G.testdir)/plainfile_0" create => "true", edit_line => insert_lines("Just some content"); "$(G.testdir)/file_select/." create => "true"; "$(G.testdir)/file_select/plainfile_1" copy_from => local_cp("/$(G.testdir)/plainfile_0"); "$(G.testdir)/file_select/plainfile_2" copy_from => local_cp("/$(G.testdir)/plainfile_0"); "$(G.testdir)/file_select/symlink_1" link_from => ln_s("/$(G.testdir)/plainfile_0"); "$(G.testdir)/file_select/symlink_2" link_from => ln_s("/$(G.testdir)/plainfile_0"); } bundle agent test { files: "$(G.testdir)/file_select/." delete => tidy, depth_search => recurse("inf"), file_select => no_file_should_be_executed; } bundle agent check { vars: "files" slist => lsdir("$(G.testdir)/file_select/", ".*", "false"); "dir_count" int => length(files); classes: # Since we can't test ourself for stdout, we just make sure that the number # of files is correct. A separate policy runs this one and inspects its # output. It needs something to check for passing condition. And failing # condition is the errors its looking for "have_expected_number_of_files" expression => strcmp("$(dir_count)", "6"); "ok" expression => "have_expected_number_of_files"; reports: ok:: "Pass $(this.promise_filename)"; } body file_select no_file_should_be_executed # Since no files match both leaf_name and file_types, there is no chance that # file_result will succeed and no executions should be performed. { leaf_name => { "plainfile.*" }; file_types => { "symlink" }; exec_program => "/bin/echo executed command for $(this.promiser)"; file_result => "leaf_name.file_types.exec_program"; } body link_from ln_s(x) # @brief Create a symbolink link to `x` # The link is created even if the source of the link does not exist. # @param x The source of the link { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } cfengine-3.24.2/tests/acceptance/10_files/zendesk_1779/zendesk_1779.cf0000644000000000000000000000176515010704253025014 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test file_selection attributes are only checked as necessary"; "story_id" string => ""; "covers" string => ""; } # Ref: https://dev.cfengine.com/issues/6997 ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { meta: "test_soft_fail" string => "!windows", meta => { "redmine6997" }; "test_skip_unsupported" string => "windows", comment => "The test deals with symlinks which are not supported on windows"; vars: "command" string => "$(sys.cf_agent) -KIf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*Pass.*", ".*executed command for.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/locally_copied_sparse_file_preserves_sparseness.cf0000644000000000000000000000465415010704253032432 0ustar00rootroot00000000000000# Test that locally copied files keep their sparsness body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(test.file[sparse])" delete => tidy, handle => "init_tidy_sparse"; "$(test.file[copy])" delete => tidy, handle => "init_tidy_copy"; commands: "/bin/dd" args => "if=/dev/zero of=$(test.file[sparse]) seek=1024 bs=1024 count=0", if => not( fileexists( "$(test.file[sparse])" )), depends_on => { "init_tidy_sparse", "init_tidy_copy" }; } bundle agent test { meta: "description" string => "ENT-2769: Test that when a sparse file is copied locally the sparseness is preserved"; # Various exotic filesystems don't support sparseness, see the unit # test "files_copy_test.c" for details. "test_skip_unsupported" string => "!linux"; vars: "file[sparse]" string => "$(G.testdir)/sparse"; "file[copy]" string => "$(G.testdir)/copy"; files: "$(file[copy])" copy_from => local_dcp( "$(file[sparse])" ); } bundle agent check { vars: "size[sparse]" string => filestat( "$(test.file[sparse])", size ), if => fileexists( "$(test.file[sparse])" ); "size[copy]" string => filestat( "$(test.file[copy])", size ), if => fileexists( "$(test.file[copy])" ); "du[sparse]" string => execresult( "expr `du -k $(test.file[sparse]) | cut -f1` '*' 1024", useshell), if => fileexists( "$(test.file[sparse])" ); "du[copy]" string => execresult( "expr `du -k $(test.file[copy]) | cut -f1` '*' 1024", useshell), if => fileexists( "$(test.file[copy])" ); classes: "size_match" expression => strcmp( "$(size[sparse])", "$(size[copy])" ); "du_less" expression => islessthan( "$(du[copy])", "$(size[copy])" ); "OK" and => { "size_match", "du_less" }; reports: OK:: "$(this.promise_filename) Pass"; !OK:: "$(this.promise_filename) FAIL"; DEBUG:: "Sparse filestat.size: $(size[sparse])"; "Sparse du -k: '$(du[sparse])'"; "Copy filestat.size: $(size[copy])"; "Copy du -k: '$(du[copy])'"; DEBUG.size_match:: "Sparse file and copy match in apparent size."; DEBUG.du_less:: "Copy of sparse file is using more bytes on disk than the real size of the file, in bytes, so it's probably non-sparse!"; } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/0000755000000000000000000000000015010704253023213 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/001.cf0000644000000000000000000000317415010704253024032 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Four END"; "expected" string => "BEGIN One potato Two potato Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "BEGIN$(const.n)$(str)$(const.n)END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/218.cf0000644000000000000000000000375215010704253024046 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/203.cf0000644000000000000000000000374115010704253024036 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_trailing works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/same_text_in_two_regions.cf0000644000000000000000000000206615010704253030627 0ustar00rootroot00000000000000# Tests whether you can insert the same text into two regions. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => file_make("$(G.testfile)", "block1 block2 block3 block4"); "any" usebundle => file_make("$(G.testfile).expected", "block1 test1 block2 block3 test1 block4"); } bundle agent test { files: "$(G.testfile)" edit_line => insert_in_two_regions; } bundle edit_line insert_in_two_regions { insert_lines: "test1" select_region => sel1; "test1" select_region => sel2; } body select_region sel1 { select_start => "block1"; select_end => "block2"; } body select_region sel2 { select_start => "block3"; select_end => "block4"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile)", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/302.cf0000644000000000000000000000331315010704253024031 0ustar00rootroot00000000000000####################################################### # # Test non matching end selector in region. # This will cause content won't be added to file. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "actual" string => "[quux] bar "; "expected" string => "[quux] bar "; "files" slist => { "actual", "expected" }; files: "$(G.testfile).$(files)" create => "true", edit_line => init_insert("$(init.$(files))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => example_edit_line; } bundle edit_line example_edit_line { insert_lines: "foo" select_region => example_select, location => example_location; } body select_region example_select { select_start => "\[quux\]"; select_end => "\[.*\]"; } body location example_location { select_line_matching => "bar"; before_after => "after"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/019.cf0000644000000000000000000000371415010704253024043 0ustar00rootroot00000000000000####################################################### # # Files read in as templates, check class handling # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_expected, edit_defaults => init_empty; files: "$(G.testfile).template" create => "true", edit_line => init_template, edit_defaults => init_empty; } ####### bundle edit_line init_template { insert_lines: "[%CFEngine BEGIN %] WARNING No unauthorized logins. All logins are recorded. Property of Example.com [%CFEngine END %] [%CFEngine nosuchclass:: %] manager: Mr. White phone: 555-555-5555 [%CFEngine fishy:: %] manager: Mr. Black phone: 555-555-4444 [%CFEngine any:: %] AAAAAAAA " insert_type => "preserve_all_lines"; } ####### bundle edit_line init_expected { insert_lines: "WARNING No unauthorized logins. All logins are recorded. Property of Example.com manager: Mr. Black phone: 555-555-4444 AAAAAAAA " insert_type => "preserve_block"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { classes: "fishy" expression => "any"; files: "$(G.testfile).actual" create => "true", edit_template => "$(G.testfile).template"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).expected", "$(G.testfile).actual", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/016.cf0000644000000000000000000000360415010704253024036 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines before the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "insert" string => " One potato Two potato Three potatoe Spuds spuds spuds Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Four END Spuds spuds spuds"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", insert_select => test_insert_exclude(".*Three.*"); } body insert_select test_insert_exclude(r) { insert_if_not_match_from_list => { "$(r)" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/insert_line_end_match_eof.cf0000644000000000000000000000341215010704253030673 0ustar00rootroot00000000000000####################################################### # # Test matching EOF in file where end selector in region don't matches # anything but select_end_match_eof is true. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "actual" string => "[quux] bar "; "expected" string => "[quux] bar foo "; "files" slist => { "actual", "expected" }; files: "$(G.testfile).$(files)" create => "true", edit_line => init_insert("$(init.$(files))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => example_edit_line; } bundle edit_line example_edit_line { insert_lines: "foo" select_region => example_select, location => example_location; } body select_region example_select { select_start => "\[quux\]"; select_end => "\[.*\]"; select_end_match_eof => "true"; } body location example_location { select_line_matching => "bar"; before_after => "after"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf-in-edit_line.cf0000644000000000000000000000536215010704253027017 0ustar00rootroot00000000000000############################################################################## # Test that CRLF is handled correctly on Windows. ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: "test_skip_unsupported" string => "!windows"; vars: "datadir" string => "$(this.promise_dirname)/crlf_data"; "filelist" slist => { "file-with-lf.txt", "file-with-crlf.txt", "file-with-mixed-eol.txt" }; files: "$(G.testdir)/." create => "yes"; "$(G.testdir)/$(filelist)" copy_from => copy_file("$(filelist)"); } body copy_from copy_file(file) { source => "$(datadir)/$(file)"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; files: "$(G.testdir)/$(init.filelist)" edit_line => insert_line; } bundle edit_line insert_line { insert_lines: "Inserted line" select_region => second_line; "Inserted block Block line 1 Block line 2" select_region => third_line; } body select_region second_line { select_start => "alpha"; select_end => "beta"; } body select_region third_line { select_start => "beta"; select_end => "charlie"; } ####################################################### bundle agent check { vars: "ok_classes" slist => { "diff_ok_file_with_lf_txt", "diff_ok_file_with_crlf_txt", "diff_ok_file_with_mixed_eol_txt", "size_ok_file_with_lf_txt", "size_ok_file_with_crlf_txt", "size_ok_file_with_mixed_eol_txt" }; "classes_set" slist => classesmatching("(diff|size)_ok.*"); classes: "diff_ok_$(init.filelist)" expression => returnszero( "$(G.diff) $(G.testdir)/$(init.filelist) $(init.datadir)/$(init.filelist).expected >$(G.dev_null) 2>&1", "useshell"); "size_ok_$(init.filelist)" expression => strcmp(filestat("$(G.testdir)/$(init.filelist)", "size"), filestat("$(init.datadir)/$(init.filelist).expected", "size")); "ok" and => { @(ok_classes) }; reports: DEBUG.!ok:: "Classes expected: $(ok_classes)"; "Classes actually set: $(classes_set)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/222.cf0000644000000000000000000000374615010704253024044 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_embedded works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/insert_line_end_match_eof_control_body.cf0000644000000000000000000000346115010704253033454 0ustar00rootroot00000000000000####################################################### # # Test matching EOF in file where end selector in region don't matches # anything and control body 'select_end_match_eof' is true. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { select_end_match_eof => "true"; } ####################################################### bundle agent init { vars: "actual" string => "[quux] bar "; "expected" string => "[quux] bar foo "; "files" slist => { "actual", "expected" }; files: "$(G.testfile).$(files)" create => "true", edit_line => init_insert("$(init.$(files))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => example_edit_line; } bundle edit_line example_edit_line { insert_lines: "foo" select_region => example_select, location => example_location; } body select_region example_select { select_start => "\[quux\]"; select_end => "\[.*\]"; } body location example_location { select_line_matching => "bar"; before_after => "after"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/119.cf0000644000000000000000000000364215010704253024044 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_embedded", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/multi-files-dirs.cf0000644000000000000000000000420415010704253026716 0ustar00rootroot00000000000000####################################################### # # Insert a line into variously named files, in various directories (Issue 888) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "expected", "$(results)" }; "testdirs" slist => { "dirA/", "dirB/", "dirC/" }; "testfiles" slist => { "dirA/testfa", "dirB/testfb", "dirC/testfc" }; files: "$(G.testdir)/$(testdirs)" comment => "Create directory: $(testdirs)."; "$(G.testdir)/$(testfiles)" comment => "Create target file: $(testfiles).", create => "true"; } ####################################################### bundle agent test { meta: "test_suppress_fail" string => "windows", meta => { "redmine4853" }; files: any:: "$(G.testdir)/.*/testf.*" create => "true", edit_line => myedit; } bundle edit_line myedit { insert_lines: any:: "one two three test"; } ####################################################### bundle agent check { vars: "expect" string => "one two three test"; "results" slist => { "resultA", "resultB", "resultC" }; "resultA" string => readfile( "$(G.testdir)/dirA/testfa", "33"); "resultB" string => readfile( "$(G.testdir)/dirB/testfb", "33"); "resultC" string => readfile( "$(G.testdir)/dirC/testfc", "33"); classes: "ok_A" expression => strcmp("$(expect)", "$(resultA)"); "ok_B" expression => strcmp("$(expect)", "$(resultB)"); "ok_C" expression => strcmp("$(expect)", "$(resultC)"); "ok" and => { "ok_A", "ok_B", "ok_C" }; reports: DEBUG:: "expected: '$(expect)'"; "results:"; "resultA: '$(resultA)'"; "resultB: '$(resultB)'"; "resultC: '$(resultC)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/122.cf0000644000000000000000000000366715010704253024045 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_embedded works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/104.cf0000644000000000000000000000370415010704253024035 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_trailing works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ###################################################### # bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/008.cf0000644000000000000000000000355115010704253024040 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines before the first instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "expected" string => "BEGIN Three potatoe One potato Two potato Two potatoes Four END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" location => test_before_first(".*potato.*"); } body location test_before_first(line) { before_after => "before"; first_last => "first"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/102.cf0000644000000000000000000000361215010704253024031 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that exact match works when given a # not-exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/010.cf0000644000000000000000000000354515010704253024034 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines after the first instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "expected" string => "BEGIN One potato Three potatoe Two potato Two potatoes Four END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" location => test_after_first(".*potato.*"); } body location test_after_first(line) { before_after => "after"; first_last => "first"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/121.cf0000644000000000000000000000360715010704253024036 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy ignore_embedded # works when given a close-enough exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/217.cf0000644000000000000000000000373415010704253024045 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/107.cf0000644000000000000000000000361415010704253024040 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_trailing", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/insert-large-lines.cf.txt0000644000000000000000000004006015010704253030047 0ustar00rootroot00000000000000........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... ........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... ........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... ........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/101.cf0000644000000000000000000000354515010704253024035 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that exact match works when given an # exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/017.cf0000644000000000000000000000166515010704253024044 0ustar00rootroot00000000000000####################################################### # # Try to insert lines from a file that is really a directory. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => insert_dir, create => "true"; } bundle edit_line insert_dir { insert_lines: "$(G.testroot)" insert_type => "file", classes => if_notkept("ok"); } ####################################################### bundle agent check { reports: DEBUG:: "This should only pass if inserting lines from a directory fails"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/012.cf0000644000000000000000000000366215010704253024036 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines before the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "insert" string => " One potato Two potato Three potatoe Spuds spuds spuds Four"; "expected" string => "BEGIN One potato Two potato Three potatoe Spuds spuds spuds Two potatoes Four END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" insert_type => "file", location => test_before_last(".*potato.*"); } body location test_before_last(line) { before_after => "before"; first_last => "last"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 edit_line_bundle_called_from_namespace.cf.sub0000644000000000000000000000054015010704253034065 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/09_insert_linesbody file control { namespace => "testing_namespace"; } bundle agent namespaced_test(file) { files: "$(file)" create => "true", edit_defaults => default:init_empty, classes => default:scoped_classes_generic("bundle", "edit"), edit_line => default:simple_insert("Hello"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/212.cf0000644000000000000000000000374015010704253024035 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_trailing works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/011.cf0000644000000000000000000000354515010704253024035 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines before the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "expected" string => "BEGIN One potato Two potato Three potatoe Two potatoes Four END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" location => test_before_last(".*potato.*"); } body location test_before_last(line) { before_after => "before"; first_last => "last"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/007.cf0000644000000000000000000000414715010704253024041 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines at the end of a fully bounded # region, before the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " big potatoes BEGIN One potato Two potato Two potatoes Four END small potatoes"; "expected" string => " big potatoes BEGIN One potato Two potato Three potatoe Two potatoes Four END small potatoes"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" select_region => test_region, location => test_before_last(".*potato.*"); } body select_region test_region { select_start => "BEGIN"; select_end => "END"; } body location test_before_last(line) { before_after => "before"; first_last => "last"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/105.cf0000644000000000000000000000361315010704253024035 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/112.cf0000644000000000000000000000366115010704253024036 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_trailing works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/115.cf0000644000000000000000000000365515010704253024044 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy ignore_trailing # works when given a close-enough exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/221.cf0000644000000000000000000000366615010704253024044 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy ignore_embedded # works when given a close-enough exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/204.cf0000644000000000000000000000376315010704253024043 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_trailing works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/118.cf0000644000000000000000000000367315010704253024047 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/113.cf0000644000000000000000000000367015010704253024037 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_embedded works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/preserve_block_blank_lines.cf0000644000000000000000000000245015010704253031074 0ustar00rootroot00000000000000# https://dev.cfengine.com/issues/7094 # body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body edit_defaults test_empty { empty_file_before_editing => "true"; edit_backup => "false"; } bundle agent init { vars: "test_file" string => "$(G.testfile).test"; files: "$(test_file)" create => "true", edit_defaults => test_empty; } bundle agent test { files: "$(init.test_file)" edit_line => add_bad(); "$(init.test_file)" edit_line => add_bad2(); } bundle agent check { vars: "expected" string => "Bad 1 Bad 2 Bad 3 "; "actual" string => readfile("$(init.test_file)", "inf"); classes: "ok" expression => strcmp("$(expected)", "$(actual)"); reports: DEBUG:: "OK: Expected '$(expected)' == '$(actual)'" if => "ok"; "FAIL: Expected '$(expected)' <> '$(actual)'" if => "!ok"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } bundle edit_line add_bad() { insert_lines: "Bad 1 Bad 2 Bad 3" insert_type => "preserve_block"; } bundle edit_line add_bad2() { insert_lines: " Bad 2 Bad 3" insert_type => "preserve_block"; } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/0000755000000000000000000000000015010704253025132 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-mixed-eol.txt.expected0000644000000000000000000000012115010704253033236 0ustar00rootroot00000000000000alpha Inserted line beta Inserted block Block line 1 Block line 2 charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-crlf.txt0000644000000000000000000000002615010704253030505 0ustar00rootroot00000000000000alpha beta charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-lf.txt.mustache0000644000000000000000000000015415010704253031772 0ustar00rootroot00000000000000alpha Inserted line beta {{#classes.any}} Inserted block Block line 1 Block line 2 {{/classes.any}} charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-lf.txt.cftemplate0000644000000000000000000000016015010704253032302 0ustar00rootroot00000000000000alpha Inserted line beta [%CFEngine BEGIN %] Inserted block Block line 1 Block line 2 [%CFEngine END %] charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/.gitattributes0000644000000000000000000000001015010704253030014 0ustar00rootroot00000000000000* -text cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/insert_file.txt0000644000000000000000000000005215010704253030173 0ustar00rootroot00000000000000Inserted block Block line 1 Block line 2 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-crlf.txt.mustache0000644000000000000000000000016515010704253032321 0ustar00rootroot00000000000000alpha Inserted line beta {{#classes.any}} Inserted block Block line 1 Block line 2 {{/classes.any}} charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-lf.txt.expected0000644000000000000000000000011215010704253031754 0ustar00rootroot00000000000000alpha Inserted line beta Inserted block Block line 1 Block line 2 charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-crlf.txt.cftemplate0000644000000000000000000000017115010704253032631 0ustar00rootroot00000000000000alpha Inserted line beta [%CFEngine BEGIN %] Inserted block Block line 1 Block line 2 [%CFEngine END %] charlie file-with-mixed-eol.txt.cftemplate0000644000000000000000000000016015010704253033505 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_dataalpha Inserted line beta [%CFEngine BEGIN %] Inserted block Block line 1 Block line 2 [%CFEngine END %] charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-crlf.txt.expected0000644000000000000000000000012115010704253032301 0ustar00rootroot00000000000000alpha Inserted line beta Inserted block Block line 1 Block line 2 charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-mixed-eol.txt0000644000000000000000000000002415010704253031440 0ustar00rootroot00000000000000alpha beta charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-lf.txt0000644000000000000000000000002315010704253030155 0ustar00rootroot00000000000000alpha beta charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf_data/file-with-mixed-eol.txt.mustache0000644000000000000000000000015415010704253033254 0ustar00rootroot00000000000000alpha Inserted line beta {{#classes.any}} Inserted block Block line 1 Block line 2 {{/classes.any}} charlie cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/insert-large-lines.cf0000644000000000000000000000141515010704253027232 0ustar00rootroot00000000000000 body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "data" string => readfile("$(this.promise_filename).txt", "16431"); files: "$(G.testfile).actual" create => "true", edit_defaults => init_empty, edit_line => test_insert("$(data)"); } bundle edit_line test_insert(data) { insert_lines: "$(data)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(this.promise_filename).txt", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf-in-mustache.cf0000644000000000000000000000470615010704253026675 0ustar00rootroot00000000000000############################################################################## # Test that CRLF is handled correctly on Windows. ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: "test_skip_unsupported" string => "!windows"; vars: "datadir" string => "$(this.promise_dirname)/crlf_data"; "filelist" slist => { "file-with-lf.txt", "file-with-crlf.txt", "file-with-mixed-eol.txt" }; files: "$(G.testdir)/." create => "yes"; "$(G.testdir)/$(filelist)" copy_from => copy_file("$(filelist)"); } body copy_from copy_file(file) { source => "$(datadir)/$(file)"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; files: "$(G.testdir)/$(init.filelist)" edit_template => "$(init.datadir)/$(init.filelist).mustache", template_method => "mustache"; } ####################################################### bundle agent check { vars: "ok_classes" slist => { "diff_ok_file_with_lf_txt", "diff_ok_file_with_crlf_txt", "diff_ok_file_with_mixed_eol_txt", "size_ok_file_with_lf_txt", "size_ok_file_with_crlf_txt", "size_ok_file_with_mixed_eol_txt" }; "classes_set" slist => classesmatching("(diff|size)_ok.*"); classes: "diff_ok_$(init.filelist)" expression => returnszero( "$(G.diff) $(G.testdir)/$(init.filelist) $(init.datadir)/$(init.filelist).expected >$(G.dev_null) 2>&1", "useshell"); "size_ok_$(init.filelist)" expression => strcmp(filestat("$(G.testdir)/$(init.filelist)", "size"), filestat("$(init.datadir)/$(init.filelist).expected", "size")); "ok" and => { @(ok_classes) }; reports: DEBUG.!ok:: "Classes expected: $(ok_classes)"; "Classes actually set: $(classes_set)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/103.cf0000644000000000000000000000366215010704253024037 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_trailing works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/003.cf0000644000000000000000000000335715010704253024037 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines at the end of a partially bounded region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Four END"; "expected" string => "BEGIN One potato Two potato Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" select_region => test_region; } body select_region test_region { select_start => "BEGIN"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/215.cf0000644000000000000000000000366715010704253024050 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy ignore_trailing # works when given a close-enough exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/selectlinematching.cf.sub_10000644000000000000000000000373415010704253030406 0ustar00rootroot00000000000000####################################################### # # Redmine #2778 # This subtest should be identical to "009.cf" with the exception of # these comment lines. # ####################################################### # # Insert a number of lines after the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "expected" string => "BEGIN One potato Two potato Two potatoes Three potatoe Four END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" location => test_after_last(".*potato.*"); } body location test_after_last(line) { before_after => "after"; first_last => "last"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf-in-cftemplate.cf0000644000000000000000000000471015010704253027203 0ustar00rootroot00000000000000############################################################################## # Test that CRLF is handled correctly on Windows. ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: "test_skip_unsupported" string => "!windows"; vars: "datadir" string => "$(this.promise_dirname)/crlf_data"; "filelist" slist => { "file-with-lf.txt", "file-with-crlf.txt", "file-with-mixed-eol.txt" }; files: "$(G.testdir)/." create => "yes"; "$(G.testdir)/$(filelist)" copy_from => copy_file("$(filelist)"); } body copy_from copy_file(file) { source => "$(datadir)/$(file)"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; files: "$(G.testdir)/$(init.filelist)" edit_template => "$(init.datadir)/$(init.filelist).cftemplate", template_method => "cfengine"; } ####################################################### bundle agent check { vars: "ok_classes" slist => { "diff_ok_file_with_lf_txt", "diff_ok_file_with_crlf_txt", "diff_ok_file_with_mixed_eol_txt", "size_ok_file_with_lf_txt", "size_ok_file_with_crlf_txt", "size_ok_file_with_mixed_eol_txt" }; "classes_set" slist => classesmatching("(diff|size)_ok.*"); classes: "diff_ok_$(init.filelist)" expression => returnszero( "$(G.diff) $(G.testdir)/$(init.filelist) $(init.datadir)/$(init.filelist).expected >$(G.dev_null) 2>&1", "useshell"); "size_ok_$(init.filelist)" expression => strcmp(filestat("$(G.testdir)/$(init.filelist)", "size"), filestat("$(init.datadir)/$(init.filelist).expected", "size")); "ok" and => { @(ok_classes) }; reports: DEBUG.!ok:: "Classes expected: $(ok_classes)"; "Classes actually set: $(classes_set)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/021.cf0000644000000000000000000000310715010704253024030 0ustar00rootroot00000000000000####################################################### # # Test idempotency of preserve_block # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_expected, edit_defaults => init_empty; files: "$(G.testfile).actual" create => "true", edit_line => init_file, edit_defaults => init_empty; } ####### bundle edit_line init_file { insert_lines: "auto eth0.1190 iface eth0.1190 inet manual up ifconfig eth0.1190 up" insert_type => "preserve_block"; } ####### bundle edit_line init_expected { insert_lines: "auto eth0.1190 iface eth0.1190 inet manual up ifconfig eth0.1190 up" insert_type => "preserve_block"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: # Do the same again to test idempotency of preserve_block "$(G.testfile).actual" edit_line => init_expected; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).expected", "$(G.testfile).actual", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/004.cf0000644000000000000000000000415315010704253024033 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines at the end of a fully bounded # region, before the first instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " big potatoes BEGIN One potato Two potato Two potatoes Four END small potatoes"; "expected" string => " big potatoes BEGIN Three potatoe One potato Two potato Two potatoes Four END small potatoes"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" select_region => test_region, location => test_before_first(".*potato.*"); } body select_region test_region { select_start => "BEGIN"; select_end => "END"; } body location test_before_first(line) { before_after => "before"; first_last => "first"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/117.cf0000644000000000000000000000361715010704253024044 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/005.cf0000644000000000000000000000414315010704253024033 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines at the end of a fully bounded # region, after the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " big potatoes BEGIN One potato Two potato Two potatoes Four END small potatoes"; "expected" string => " big potatoes BEGIN One potato Two potato Two potatoes Three potatoe Four END small potatoes"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" select_region => test_region, location => test_after_last(".*potato.*"); } body select_region test_region { select_start => "BEGIN"; select_end => "END"; } body location test_after_last(line) { before_after => "after"; first_last => "last"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/114.cf0000644000000000000000000000371215010704253024035 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_embedded works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/namespaced_edit_line_bundle.cf.sub0000644000000000000000000000025215010704253031761 0ustar00rootroot00000000000000body file control { namespace => "testing_namespace"; } bundle edit_line simple_insert { insert_lines: "Hello"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/201.cf0000644000000000000000000000362415010704253024034 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that exact match works when given an # exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/015.cf0000644000000000000000000000362215010704253024035 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines before the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "insert" string => " One potato Two potato Three potatoe Spuds spuds spuds Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Four END Three potatoe Spuds spuds spuds"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", insert_select => test_insert_exclude("Three"); } body insert_select test_insert_exclude(r) { insert_if_not_match_from_list => { "$(r)" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/106.cf0000644000000000000000000000361315010704253024036 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/300.cf0000644000000000000000000000737515010704253024043 0ustar00rootroot00000000000000####################################################### # # Test insertion of newlines (Issue 555) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "template", "expected" }; "template" string => "## # Sendmail Alias File # @(#)B11.23_LRaliases $Revision: 1.1.212.1 $ $Date: 99/09/13 15:13:16 $ # # Mail to an alias in this file will be sent to the users, programs, or # files designated following the colon. # Aliases defined in this file will NOT be expanded in headers from # mailx(1), but WILL be visible over networks and in headers from # rmail(1). # # >>>>>>>>>> The program \"/usr/sbin/newaliases\" must be run after # >> NOTE >> this file is updated, or else any changes will not be # >>>>>>>>>> visible to sendmail. ## # Alias for mailer daemon MAILER-DAEMON : root # RFC 822 requires that every host have a mail address \"postmaster\" postmaster : root # Aliases to handle mail to msgs and news nobody : /dev/null # System Admistration aliases operator : root uucp : root daemon : root # Ftp maintainer. ftp-bugs : root # Local aliases root : dcpds.sysadmin@dcpds.cpms.osd.mil,:include:/etc/mail/aliases.root oracle : dcpds.dba@dcpds.cpms.osd.mil exinfac : dcpds.exits@dcpds.cpms.osd.mil applmgr : dcpds.dba@dcpds.cpms.osd.mil"; "expected" string => "## # Sendmail Alias File # @(#)B11.23_LRaliases $Revision: 1.1.212.1 $ $Date: 99/09/13 15:13:16 $ # # Mail to an alias in this file will be sent to the users, programs, or # files designated following the colon. # Aliases defined in this file will NOT be expanded in headers from # mailx(1), but WILL be visible over networks and in headers from # rmail(1). # # >>>>>>>>>> The program \"/usr/sbin/newaliases\" must be run after # >> NOTE >> this file is updated, or else any changes will not be # >>>>>>>>>> visible to sendmail. ## # Alias for mailer daemon MAILER-DAEMON : root # RFC 822 requires that every host have a mail address \"postmaster\" postmaster : root # Aliases to handle mail to msgs and news nobody : /dev/null # System Admistration aliases operator : root uucp : root daemon : root # Ftp maintainer. ftp-bugs : root # Local aliases root : dcpds.sysadmin@dcpds.cpms.osd.mil,:include:/etc/mail/aliases.root oracle : dcpds.dba@dcpds.cpms.osd.mil exinfac : dcpds.exits@dcpds.cpms.osd.mil applmgr : dcpds.dba@dcpds.cpms.osd.mil stgmgmt : :include:/etc/mail/aliases.stgmgmt"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "MailAliases" slist => { "stgmgmt : :include:/etc/mail/aliases.stgmgmt" }; files: "$(G.testfile).actual" edit_line => copy_and_append_lines("$(G.testfile).template", "@(this.MailAliases)"), edit_defaults => empty, create => "true"; } bundle edit_line copy_and_append_lines(file,lines) { insert_lines: "$(file)" insert_type => "file"; "$(lines)" insert_type => "string"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/006.cf0000644000000000000000000000414715010704253024040 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines at the end of a fully bounded # region, after the first instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " big potatoes BEGIN One potato Two potato Two potatoes Four END small potatoes"; "expected" string => " big potatoes BEGIN One potato Three potatoe Two potato Two potatoes Four END small potatoes"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" select_region => test_region, location => test_after_first(".*potato.*"); } body select_region test_region { select_start => "BEGIN"; select_end => "END"; } body location test_after_first(line) { before_after => "after"; first_last => "first"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/crlf-in-edit_line-insert-file.cf0000644000000000000000000000541015010704253031230 0ustar00rootroot00000000000000############################################################################## # Test that CRLF is handled correctly on Windows. ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: "test_skip_unsupported" string => "!windows"; vars: "datadir" string => "$(this.promise_dirname)/crlf_data"; "filelist" slist => { "file-with-lf.txt", "file-with-crlf.txt", "file-with-mixed-eol.txt" }; files: "$(G.testdir)/." create => "yes"; "$(G.testdir)/$(filelist)" copy_from => copy_file("$(filelist)"); } body copy_from copy_file(file) { source => "$(datadir)/$(file)"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; files: "$(G.testdir)/$(init.filelist)" edit_line => insert_line; } bundle edit_line insert_line { insert_lines: "Inserted line" select_region => second_line; "$(init.datadir)/insert_file.txt" insert_type => "file", select_region => third_line; } body select_region second_line { select_start => "alpha"; select_end => "beta"; } body select_region third_line { select_start => "beta"; select_end => "charlie"; } ####################################################### bundle agent check { vars: "ok_classes" slist => { "diff_ok_file_with_lf_txt", "diff_ok_file_with_crlf_txt", "diff_ok_file_with_mixed_eol_txt", "size_ok_file_with_lf_txt", "size_ok_file_with_crlf_txt", "size_ok_file_with_mixed_eol_txt" }; "classes_set" slist => classesmatching("(diff|size)_ok.*"); classes: "diff_ok_$(init.filelist)" expression => returnszero( "$(G.diff) $(G.testdir)/$(init.filelist) $(init.datadir)/$(init.filelist).expected >$(G.dev_null) 2>&1", "useshell"); "size_ok_$(init.filelist)" expression => strcmp(filestat("$(G.testdir)/$(init.filelist)", "size"), filestat("$(init.datadir)/$(init.filelist).expected", "size")); "ok" and => { @(ok_classes) }; reports: DEBUG.!ok:: "Classes expected: $(ok_classes)"; "Classes actually set: $(classes_set)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/009.cf0000644000000000000000000000354115010704253024040 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines after the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "expected" string => "BEGIN One potato Two potato Two potatoes Three potatoe Four END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" location => test_after_last(".*potato.*"); } body location test_after_last(line) { before_after => "after"; first_last => "last"; select_line_matching => "$(line)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/205.cf0000644000000000000000000000367215010704253024043 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/208.cf0000644000000000000000000000364615010704253024047 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading", "ignore_trailing", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/202.cf0000644000000000000000000000367115010704253024037 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that exact match works when given a # not-exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/207.cf0000644000000000000000000000367315010704253024046 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_trailing", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/301.cf0000644000000000000000000000261115010704253024030 0ustar00rootroot00000000000000####################################################### # # Test that specifying whitespace_policy escapes meta-characters (Issue 644) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "expected" string => "*foobar*"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert("$(init.expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => set_value_rev, create => "true"; } bundle edit_line set_value_rev { insert_lines: "*foobar*" whitespace_policy => { "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/insertion-order-reversal.cf0000644000000000000000000000342415010704253030474 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines, insuring they are not printed in reverse order (Issue 809) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Three potatoes Four END"; "insert" string => "BEGIN Five potato Six potato Seven potatoe More! END"; "expected" string => "BEGIN Five potato Six potato Seven potatoe More! END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(str) { delete_lines: ".*"; insert_lines: "$(str)" insert_type => "preserve_block", location => start; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/nothing_to_repeat_error.cf0000644000000000000000000000142115010704253030444 0ustar00rootroot00000000000000####################################################### # # catch "nothing to repeat" error in file editing # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*info: Inserted the promised line.*", ".*nothing to repeat.*", "$(sys.cf_agent) -KI -f $(this.promise_filename).sub | $(G.grep) nofile", $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/selectlinematching.cf0000644000000000000000000000614415010704253027374 0ustar00rootroot00000000000000############################################################################## # # Redmine #2778 # 3.5.x: incorrect output of: # "insert_lines promise uses the same select_line_matching anchor [...]" # # This test is loosely modelled on "execresult_multiples.cf" (post-3.5.x). # # The original Redmine 2778 report concerned editing a "sendmail.mc" file. # But in developing this acceptance test, I discovered that some existing # tests in this area also exhibit this behaviour, such as "009.cf". # # This test has two subtests: # o a copy of "009.cf"; # o the "sendmail.mc" edit from the original report. # # The subtests functionally pass but exhibit the incorrect output. # # Our intention is to fail if any of: # o incorrect output is seen (our prime concern) # o subtest itself functionally fails (its problem, not ours) # # David Lee # December 2013 # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: any:: # Run subtests. Need to be in verbose mode to see the output. # The full verbose output is too big for variable assignment here. # So extract (grep) only potentially interesting lines. "subout_1" string => execresult("$(sys.cf_agent) -Kv -f $(this.promise_filename).sub_1 2>&1 | $(G.egrep) -i 'select_line_matching'", "useshell"); "subout_2" string => execresult("$(sys.cf_agent) -Kv -f $(this.promise_filename).sub_2 2>&1 | $(G.egrep) -i 'select_line_matching'", "useshell"); reports: DEBUG:: "bundle test: this.promise_filename: $(this.promise_filename)"; "bundle test: subtest_1: $(this.promise_filename).sub_1"; "bundle test: subout_1: $(subout_1)"; "bundle test: subtest_2: $(this.promise_filename).sub_2"; "bundle test: subout_2: $(subout_2)"; } ####################################################### bundle agent check { vars: any:: # These patterns spell trouble. "pattern_fail" string => ".*select_line_matching anchor.*"; # Examine output from 'test' to decide whether good or bad. classes: any:: "ok_pattern_1" not => regcmp("$(pattern_fail)", "$(test.subout_1)"); "ok_pattern_2" not => regcmp("$(pattern_fail)", "$(test.subout_2)"); reports: DEBUG:: "Attempted subtest '$(this.promise_filename).sub_1' in verbose mode."; "Significant output of sub_1 was '$(test.subout_1)'."; "Attempted subtest '$(this.promise_filename).sub_2' in verbose mode."; "Significant output of sub_2 was '$(test.subout_2)'."; DEBUG.!ok_pattern_1:: "failing: pattern '$(pattern_fail)' in subtest_1"; DEBUG.!ok_pattern_2:: "failing: pattern '$(pattern_fail)' in subtest_2"; ok_pattern_1.ok_pattern_2:: "$(this.promise_filename) Pass"; !(ok_pattern_1.ok_pattern_2):: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/014.cf0000644000000000000000000000361015010704253024031 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines before the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "insert" string => " One potato Two potato Three potatoe Spuds spuds spuds Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Four END Three potatoe Spuds spuds spuds"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" insert_type => "file", insert_select => test_insert_exclude("Xhree"); } body insert_select test_insert_exclude(r) { insert_if_not_match_from_list => { "$(r)" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/303.cf0000644000000000000000000000454215010704253024037 0ustar00rootroot00000000000000######################################################## # # ISSUE 1023 # ######################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ######################################################## bundle agent init { vars: "actual1qaz" string => ""; "actual2qaz" string => ""; "actual3qaz" string => ""; "expected1qaz" string => "AAAA"; "expected2qaz" string => "AAAA"; "expected3qaz" string => "AAAA"; "files" slist => { "actual1qaz", "expected1qaz", "actual2qaz", "expected2qaz", "actual3qaz", "expected3qaz" }; files: "$(G.testfile).actual1qaz" touch => "true"; "$(G.testfile).actual2qaz" touch => "true"; "$(G.testfile).actual3qaz" touch => "true"; "$(G.testfile).expected1qaz" touch => "true", edit_line => init_insert("$(expected1qaz)"); "$(G.testfile).expected2qaz" touch => "true", edit_line => init_insert("$(expected1qaz)"); "$(G.testfile).expected3qaz" touch => "true", edit_line => init_insert("$(expected1qaz)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle agent test { meta: "test_suppress_fail" string => "windows", meta => { "redmine5120" }; files: "$(G.testfile).(actual)?\dq.*" pathtype => "regex", edit_line => example_edit_line; } bundle edit_line example_edit_line { insert_lines: "AAAA"; } bundle agent check { methods: "first" usebundle => dcs_check_diff("$(G.testfile).actual1qaz", "$(G.testfile).expected1qaz", "$(this.promise_filename)"); "second" usebundle => dcs_check_diff("$(G.testfile).actual2qaz", "$(G.testfile).expected2qaz", "$(this.promise_filename)"); "third" usebundle => dcs_check_diff("$(G.testfile).actual3qaz", "$(G.testfile).expected3qaz", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/116.cf0000644000000000000000000000360715010704253024042 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy ignore_leading # works when given a close-enough exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/block_insert_order.cf0000644000000000000000000000263115010704253027400 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy ignore_trailing # works when given a close-enough exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert, edit_defaults => init_empty; } bundle edit_line init_insert { insert_lines: "line1 line2"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { delete_lines: ".*"; insert_lines: "line1 line2" insert_type => "preserve_block", location => start; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/insert_line_end_match_eof_default.cf0000644000000000000000000000325315010704253032402 0ustar00rootroot00000000000000####################################################### # # Test matching EOF default value for select region. # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "actual" string => "[quux] bar foo "; "expected" string => "[quux] bar foo "; "files" slist => { "actual", "expected" }; files: "$(G.testfile).$(files)" create => "true", edit_line => init_insert("$(init.$(files))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => example_edit_line; } bundle edit_line example_edit_line { insert_lines: "foo" select_region => example_select, location => example_location; } body select_region example_select { select_start => "\[quux\]"; select_end => "\[.*\]"; } body location example_location { select_line_matching => "bar"; before_after => "after"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/213.cf0000644000000000000000000000374715010704253024045 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_embedded works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/block_insert_duplicate.cf0000644000000000000000000000353315010704253030241 0ustar00rootroot00000000000000####################################################### # # Insert lines at the top of file a multi-line header, # verify that insertion is convergent - Redmine #1525 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "header" string => "############### ### This file is managed by CFEngine ### Do not update it manually, oh no ### do not ###############"; files: "$(G.testfile).expected" create => "true", edit_line => insert_header; commands: !windows:: "$(G.echo)" args => "\"${init.header}\" > \"$(G.testfile).actual\"", contain => in_shell; windows:: # newlines in shell are not handled properly on Windows... "$(G.printf)" args => '"###############\n### This file is managed by CFEngine\n### Do not update it manually, oh no\n### do not\n###############\n" > "$(G.testfile).actual"', contain => in_shell; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10254" }; files: "$(G.testfile).actual" create => "true", edit_line => insert_header; } bundle edit_line insert_header { insert_lines: "${init.header}" location => start, insert_type => "preserve_block"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/108.cf0000644000000000000000000000356715010704253024050 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "ignore_leading", "ignore_trailing", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/edit_line_bundle_called_from_namespace.cf0000644000000000000000000000244015010704253033355 0ustar00rootroot00000000000000####################################################### # # Call an edit_line bundle from another namespace # ####################################################### body common control { inputs => { "../../default.cf.sub", "edit_line_bundle_called_from_namespace.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert, edit_defaults => init_empty; } bundle edit_line init_insert { insert_lines: "Hello"; } bundle edit_line simple_insert(line) { insert_lines: "$(line)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { methods: "jump" usebundle => testing_namespace:namespaced_test("$(G.testfile).actual"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/216.cf0000644000000000000000000000366615010704253024050 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy ignore_leading # works when given a close-enough exact match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/400.cf0000644000000000000000000000130515010704253024027 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { files: "$(G.testfile)" file_type => "fifo", edit_line => init_insert("foo"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle agent check { classes: "exists" expression => fileexists("$(G.testfile)"); "ok" not => "exists"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } insert_line_end_do_not_match_eof_control_body.cf0000644000000000000000000000361215010704253034735 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines####################################################### # # Test matching EOF in file where end selector in region don't matches # anything and local edit_line 'select_end_match_eof' option is # overriding global body common control. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { select_end_match_eof => "true"; } ####################################################### bundle agent init { vars: "actual" string => "[quux] bar foo "; "expected" string => "[quux] bar foo "; "files" slist => { "actual", "expected" }; files: "$(G.testfile).$(files)" create => "true", edit_line => init_insert("$(init.$(files))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => example_edit_line; } bundle edit_line example_edit_line { insert_lines: "foo" select_region => example_select, location => example_location; } body select_region example_select { select_start => "\[quux\]"; select_end => "\[.*\]"; select_end_match_eof => "false"; } body location example_location { select_line_matching => "bar"; before_after => "after"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/002.cf0000644000000000000000000000340615010704253024031 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines at the end of a fully bounded region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Four END"; "expected" string => "BEGIN One potato Two potato Four Three potatoe END"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " One potato Two potato Three potatoe Four"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(test.tstr)"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" select_region => test_region; } body select_region test_region { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/109.cf0000644000000000000000000000416315010704253024042 0ustar00rootroot00000000000000####################################################### # # Insert lines with preserve_block "after" and check convergence # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "START"; "expected" string => "START 1 x2x xx3xx x4x 5 x6x xx7xx xxx8xxx xxxx9xxxx xxxxx10xxxx xxxxxx11xxxxx xxxxxxx12xxxxxx xxxxxxxx13xxxxxxx xxxxxxxxx14xxxxxxxx xxxxxxxxx15xxxxxxxxx xxx16xx xxx17xx xxx18xx xxx19xx xxx20xx xxxxxxxxx21xxxxxxx"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: " 1 x2x xx3xx x4x 5 x6x xx7xx xxx8xxx xxxx9xxxx xxxxx10xxxx xxxxxx11xxxxx xxxxxxx12xxxxxx xxxxxxxx13xxxxxxx xxxxxxxxx14xxxxxxxx xxxxxxxxx15xxxxxxxxx xxx16xx xxx17xx xxx18xx xxx19xx xxx20xx xxxxxxxxx21xxxxxxx" location => prepend, insert_type => "preserve_block"; } body location prepend { before_after => "after"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/219.cf0000644000000000000000000000411015010704253024034 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_embedded", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff_expected("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "yes"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/selectlinematching.cf.sub_20000644000000000000000000000362015010704253030401 0ustar00rootroot00000000000000####################################################### # # Redmine 2778: # # A reduced form of the generating case. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "dnl # dnl define(`SMART_HOST', `smtp.your.provider')dnl dnl #"; "expected" string => "dnl # dnl define(`SMART_HOST', `smtp.your.provider')dnl define(`SMART_HOST', `mail1.$m')dnl define(`MAIL_HUB', `mail1.$m')dnl dnl #"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "hostname" string => "mail1.$m"; files: "$(G.testfile).actual" create => "true", edit_line => test_insert("$(hostname)"); } bundle edit_line test_insert(h) { insert_lines: # These sendmail "define" lines comprise a cfengine multi-line string. "define(`SMART_HOST', `$(h)')dnl define(`MAIL_HUB', `$(h)')dnl" location => location_sendmail_mc; } body location location_sendmail_mc { select_line_matching => "^dnl.*SMART_HOST.*"; before_after => "after"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/013.cf0000644000000000000000000000336115010704253024033 0ustar00rootroot00000000000000####################################################### # # Insert a number of lines before the last instance of a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Four END"; "insert" string => " One potato Two potato Three potatoe Spuds spuds spuds Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Four END Three potatoe Spuds spuds spuds"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(str) { insert_lines: "$(str)" insert_type => "file"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/214.cf0000644000000000000000000000377115010704253024043 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_embedded works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/namespaced_edit_line_bundle.cf0000644000000000000000000000241415010704253031173 0ustar00rootroot00000000000000####################################################### # # Call an edit_line bundle from another namespace # ####################################################### body common control { inputs => { "../../default.cf.sub", "namespaced_edit_line_bundle.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert, edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "Hello"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_defaults => init_empty, edit_line => testing_namespace:simple_insert; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/staging/0000755000000000000000000000000015010704253024647 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/staging/120.x.cf0000644000000000000000000000355415010704253025740 0ustar00rootroot00000000000000####################################################### # # Insert lines from a variable, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(init.insert)"); } bundle edit_line test_insert(lines) { insert_lines: "$(lines)" whitespace_policy => { "exact_match", "ignore_embedded", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/staging/304.cf0000644000000000000000000000224315010704253025470 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "304.cf.namespaced.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ######################################################## bundle agent init { vars: "expected" slist => { "var1=value1" }; "files" slist => { "actual", "expected" }; files: "$(G.testfile).actual" touch => "true"; "$(G.testfile).expected" touch => "true", edit_defaults => init_empty, edit_line => init_insert("$(expected)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle agent test { methods: "call" usebundle => cfdc_yumclient:config("$(G.testfile).actual", "2"); "call" usebundle => cfdc_yumclient:config("$(G.testfile).actual", "1"); } bundle agent check { methods: "first" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/staging/304.cf.namespaced.sub0000644000000000000000000000050315010704253030354 0ustar00rootroot00000000000000body file control { namespace => "cfdc_yumclient"; } bundle agent config(file, i) { vars: "data[var$(i)]" string => "value$(i)"; files: "$(file)" handle => "ensure_present", edit_defaults => default:init_empty, edit_line => default:set_variable_values("cfdc_yumclient:config.data"); } cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/staging/220.x.cf0000644000000000000000000000361115010704253025733 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that whitespace_policy other than # ignore_leading works when given a not-close-enough match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Leading embedded and trailing spaces "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "exact_match", "ignore_embedded", "ignore_trailing" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/206.cf0000644000000000000000000000367215010704253024044 0ustar00rootroot00000000000000####################################################### # # Insert lines from a file, verify that pairs of whitespace_policy work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected", "insert" }; "actual" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END"; "insert" string => " One potato Two potato Three potatoe Leading embedded and trailing spaces Four"; "expected" string => "BEGIN One potato Two potato Two potatoes Leading embedded and trailing spaces Four END Three potatoe Leading embedded and trailing spaces"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert("$(G.testfile).insert"); } bundle edit_line test_insert(filename) { insert_lines: "$(filename)" insert_type => "file", whitespace_policy => { "ignore_leading", "ignore_embedded" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/020.cf0000644000000000000000000000356115010704253024033 0ustar00rootroot00000000000000####################################################### # # Files read in as templates, check variable expansion # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_expected, edit_defaults => init_empty; files: "$(G.testfile).template" create => "true", edit_line => init_template, edit_defaults => init_empty; } ####### bundle edit_line init_template { insert_lines: "BEGIN $(const.dollar)(test.scalar) CCCCCCCC CCCCCCCC CCCCCCCC DDDDDDDD [%CFEngine BEGIN %] $(const.dollar)(test.list) [%CFEngine END %] " insert_type => "preserve_all_lines"; } ####### bundle edit_line init_expected { insert_lines: "BEGIN One upon a time... CCCCCCCC CCCCCCCC CCCCCCCC DDDDDDDD Many times Upon a star " insert_type => "preserve_all_lines"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "scalar" string => "One upon a time..."; "list" slist => { "Many times", "Upon a star" }; classes: "fishy" expression => "any"; files: "$(G.testfile).actual" create => "true", edit_template => "$(G.testfile).template"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).expected", "$(G.testfile).actual", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/09_insert_lines/nothing_to_repeat_error.cf.sub0000644000000000000000000000125315010704253031237 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { build_linux_limits_conf }; } bundle agent build_linux_limits_conf { vars: "limits[glob-dash-nofile]" string => "* - nofile 30000", policy => "free"; "limits[app-soft-nproc]" string => "app soft nproc 16357", policy => "free"; "values" slist => getvalues("limits"); files: "$(G.testfile)" create => "true", edit_line => insert("@(build_linux_limits_conf.values)"), edit_defaults => empty; } bundle edit_line insert(str) { insert_lines: "$(str)"; } cfengine-3.24.2/tests/acceptance/10_files/04_match/0000755000000000000000000000000015010704253021604 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/04_match/001.cf0000644000000000000000000000173715010704253022426 0ustar00rootroot00000000000000####################################################### # # Create a file and delete it - hoping that it matches (issue 365) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" delete => test_delete; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/008.cf0000644000000000000000000000234315010704253022427 0ustar00rootroot00000000000000####################################################### # # Delete a file in a nonexistent directory. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "1"; } ####################################################### bundle agent test { vars: "agent" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO 2>&1", "useshell"); } ####################################################### bundle agent check { classes: "chdir" expression => regcmp(".*chdir.*", $(test.agent)); "checkpoint" expression => regcmp(".*CHECKPOINT.*", $(test.agent)); "ok" and => { "!chdir", "checkpoint" }; reports: DEBUG:: "This should only pass if $(this.promise_filename).sub does not output anything about failing to chdir"; "Output from $(this.promise_filename).sub: $(test.agent)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/not_selected_dirs_are_skipped.cf0000644000000000000000000000461615010704253030164 0ustar00rootroot00000000000000######################################################################## # # Make sure that a directory is skipped when body_select does not match # it, even when depth_search is off. # ######################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body perms perms1 { mode => "732"; } body depth_search recurse_nobasedir(x) { depth => "$(x)"; include_basedir => "false"; } body delete del { rmdirs => "true"; } body file_select by_name(names) { leaf_name => { @(names) }; file_result => "leaf_name"; } bundle agent init { files: # Create a directory and some files in there "$(G.testroot)/srcdir/." create => "true"; "$(G.testroot)/srcdir/testfile1" create => "true"; "$(G.testroot)/srcdir/testfile2" create => "true"; # The destination should already exist and have specific # permissions, so that it's excluded by the body files_select later "$(G.testroot)/destdir/." perms => perms1, create => "true"; # Make sure all of its contents are cleaned up "$(G.testroot)/destdir" depth_search => recurse_nobasedir("inf"), file_select => by_name(".*"), delete => del; } ####################################################### body file_select test_select { # Select will fail because the dir is mode 732 search_mode => { "444" }; file_result => "mode"; } body link_from ln_s_children(x) { link_type => "symlink"; link_children => "true"; source => "$(x)"; } bundle agent test { # We promise that if destdir has specific permissions, then it must # contain links to all children from srcdir. files: "$(G.testroot)/destdir" file_select => test_select, link_from => ln_s_children("$(G.testroot)/srcdir"); } ####################################################### bundle agent check { # Since body select fails, the files in target directory should *not* # be created classes: "files_created" and => { fileexists("$(G.testroot)/destdir/testfile1"), fileexists("$(G.testroot)/destdir/testfile2") }; reports: !files_created:: "$(this.promise_filename) Pass"; files_created:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/04_match/directory_can_not_readlink.cf0000644000000000000000000000305215010704253027474 0ustar00rootroot00000000000000####################################################### # # Delete a file in a nonexistent directory. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } ####################################################### bundle agent init { vars: "checkdir" string => "$(G.testdir)/should-not-show-up-in-output"; files: "$(checkdir)/." create => "true"; } ####################################################### bundle agent test { vars: "agent" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO 2>&1", "useshell"); } ####################################################### bundle agent check { classes: "checkpoint_fail" not => regcmp(".*CHECKPOINT.*", $(test.agent)); "fail" or => { checkpoint_fail, regcmp(".*Unable to read link.*", $(test.agent)), regcmp(".*$(init.checkdir).*", $(test.agent)) }; reports: DEBUG:: "This should only pass if $(this.promise_filename).sub does not output anything about failing to readlink"; "Output from $(this.promise_filename).sub: $(test.agent)"; DEBUG.checkpoint_fail:: "The secondary policy in $(this.promise_filename).sub did not checkpoint correctly"; !fail:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/004.cf0000644000000000000000000000306615010704253022426 0ustar00rootroot00000000000000####################################################### # # Test exec_program on file_select (issue 294) - test negative match on existing file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "find_this" string => "bibbetygargle"; files: "$(G.testfile)" create => "true", edit_line => init_data; } bundle edit_line init_data { insert_lines: "Gabba gabba hey!"; "yibbity $(find_this) bletch"; "torchecol bum adder"; } ####################################################### bundle agent test { vars: linux:: "prefix" string => ""; freebsd:: "prefix" string => "/usr"; !(linux|freebsd):: "prefix" string => "FIX ME"; files: "$(G.testroot)" file_select => test_hunt("$(prefix)"), delete => test_delete; } body file_select test_hunt(prefix) { exec_program => "$(G.grep) XX$(init.find_this)XX $(this.promiser)"; file_result => "exec_program"; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/directory_can_not_readlink.cf.sub0000644000000000000000000000173615010704253030273 0ustar00rootroot00000000000000####################################################### # # Find a directory when expecting a symlink # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { symlinks }; version => "1.0"; } ####################################################### bundle agent symlinks { vars: "checkdir" string => "$(G.testdir)/should-not-show-up-in-output"; classes: "checkdir_exists" expression => fileexists($(checkdir)); files: "$(checkdir)" handle => "delete_checkdir_link", comment => "Delete checkdir symlink", file_select => select_link("/home"), delete => nodir, pathtype => "literal"; reports: checkdir_exists:: "CHECKPOINT"; } body file_select select_link(name) { file_types => { "symlink" }; issymlinkto => { "$(name)$" }; file_result => "issymlinkto"; } body delete nodir { rmdirs => "false"; } cfengine-3.24.2/tests/acceptance/10_files/04_match/008.cf.sub0000644000000000000000000000074315010704253023221 0ustar00rootroot00000000000000####################################################### # # Delete a file in a nonexistent directory. # ####################################################### body common control { bundlesequence => { "delete" }; version => "1.0"; } ####################################################### bundle agent delete { files: "/abc/nofile" delete => test_delete; reports: "CHECKPOINT"; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } cfengine-3.24.2/tests/acceptance/10_files/04_match/match_scope.cf0000644000000000000000000000246415010704253024411 0ustar00rootroot00000000000000####################################################### # # Check that $(match.1) works # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "testfile" string => concat("$(G.testdir)", "/dummy_file"); files: "$(testfile)" create => "true"; reports: DEBUG:: "Creating file $(testfile)"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; vars: "foo" string => "foo"; files: "$(G.testdir)/([^_]*)_(.*)" delete => test_delete, classes => test_classes; } body classes test_classes { promise_repaired => { "$(match.1)", "$(match.2)" }; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" and => { "dummy", "file" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/staging/0000755000000000000000000000000015010704253023240 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/04_match/staging/007.cf0000644000000000000000000000257415010704253024070 0ustar00rootroot00000000000000####################################################### # # Test exec_program on file_select (issue 294) - test negative match on existing file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "find_this" string => "bibbetygargle"; files: "$(G.testfile)" create => "true", edit_line => init_data; } bundle edit_line init_data { insert_lines: "Gabba gabba hey!"; "yibbity $(find_this) bletch"; "torchecol bum adder"; } ####################################################### bundle agent test { files: "/tmp" file_select => test_hunt, delete => test_delete; } body file_select test_hunt { exec_regex => "$(test.find_this)"; # Partial regex shouldn't match exec_program => "/bin/cat $(this.promiser)"; file_result => "exec_program.exec_regex"; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/staging/003.cf0000644000000000000000000000275315010704253024063 0ustar00rootroot00000000000000####################################################### # # Test exec_program on file_select (issue 294) - test positive match on existing file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "find_this" string => "bibbetygargle"; files: "$(G.testfile)" create => "true", edit_line => init_data; } bundle edit_line init_data { insert_lines: "Gabba gabba hey!"; "yibbity $(find_this) bletch"; "torchecol bum adder"; } ####################################################### bundle agent test { vars: linux:: "prefix" string => ""; freebsd:: "prefix" string => "/usr"; !(linux|freebsd):: "prefix" string => "FIX ME"; files: "/tmp" file_select => test_hunt("$(prefix)"), delete => test_delete; } body file_select test_hunt(prefix) { exec_program => "$(G.grep) $(init.find_this) $(this.promiser)"; file_result => "exec_program"; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/staging/005.cf0000644000000000000000000000254015010704253024057 0ustar00rootroot00000000000000####################################################### # # Test exec_program on file_select (issue 294) - test positive match on existing file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "find_this" string => "bibbetygargle"; files: "$(G.testfile)" create => "true", edit_line => init_data; } bundle edit_line init_data { insert_lines: "Gabba gabba hey!"; "yibbity $(find_this) bletch"; "torchecol bum adder"; } ####################################################### bundle agent test { files: "/tmp" file_select => test_hunt, delete => test_delete; } body file_select test_hunt { exec_regex => ".*$(test.find_this).*"; exec_program => "/bin/cat $(this.promiser)"; file_result => "exec_program.exec_regex"; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/staging/006.cf0000644000000000000000000000254415010704253024064 0ustar00rootroot00000000000000####################################################### # # Test exec_program on file_select (issue 294) - test negative match on existing file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "find_this" string => "bibbetygargle"; files: "$(G.testfile)" create => "true", edit_line => init_data; } bundle edit_line init_data { insert_lines: "Gabba gabba hey!"; "yibbity $(find_this) bletch"; "torchecol bum adder"; } ####################################################### bundle agent test { files: "/tmp" file_select => test_hunt, delete => test_delete; } body file_select test_hunt { exec_regex => ".*XX$(test.find_this)XX.*"; exec_program => "/bin/cat $(this.promiser)"; file_result => "exec_program.exec_regex"; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/staging/002.cf0000644000000000000000000000165615010704253024063 0ustar00rootroot00000000000000####################################################### # # Create a file and delete it - hoping that it matches (issue 365) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" create => "true"; } ####################################################### bundle agent test { files: "/tmp/TEST\.cfengine" delete => test_delete; } body delete test_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/04_match/kept_promise.cf0000644000000000000000000000337515010704253024627 0ustar00rootroot00000000000000####################################################### # # Check that already inserted lines trigger promise # kept. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { vars: "array[1]" string => "one"; "array[2]" string => "two"; "array[3]" string => "three"; files: "$(G.testfile)" create => "true", edit_line => init_edit; } bundle agent test { files: "$(G.testfile)" create => "true", edit_line => test_edit; } bundle edit_line init_edit { vars: "index" slist => getindices("init.array"); insert_lines: "${init.array[${index}]}"; } bundle edit_line test_edit { vars: "index" slist => getindices("init.array"); insert_lines: "${init.array[${index}]}" classes => kept_if_else("line_${index}_kept", "line_${index}_added", "line_${index}_failed"); } bundle agent check { classes: "ok" and => { "line_1_kept", "line_2_kept", "line_3_kept" }; reports: DEBUG.!line_1_kept:: "Line 1 promise should have been kept, but was not."; DEBUG.!line_2_kept:: "Line 2 promise should have been kept, but was not."; DEBUG.!line_3_kept:: "Line 3 promise should have been kept, but was not."; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body classes kept_if_else(kept, yes, no) { promise_kept => { "${kept}" }; promise_repaired => { "${yes}" }; repair_failed => { "${no}" }; repair_denied => { "${no}" }; repair_timeout => { "${no}" }; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/12_acl/0000755000000000000000000000000015010704253021246 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/12_acl/acl.cf0000644000000000000000000000444615010704253022327 0ustar00rootroot00000000000000###################################################### # # ACL tests # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { classes: "cfengine_internal_getfacl" expression => fileexists("/var/cfengine/bin/getfacl"); "system_getfacl" expression => fileexists("/usr/bin/getfacl"); vars: linux.cfengine_internal_getfacl:: "cmd" string => "/var/cfengine/bin/getfacl"; linux.!cfengine_internal_getfacl.system_getfacl:: "cmd" string => "/usr/bin/getfacl"; files: "$(G.testdir)$(const.dirsep)file" create => "true", acl => acl_sanity_check; } body acl acl_sanity_check { acl_method => "append"; aces => { "all:=rwx:allow" }; } ####################################################### bundle agent test { meta: "test_skip_needs_work" string => "windows"; vars: linux:: "sanity_perms" string => execresult("$(init.cmd) $(G.testdir)$(const.dirsep)file 2>&1 | $(G.grep) -v 'Removing leading'", "noshell"); classes: linux:: # Some filesystems don't have ACL capability, so we do this sanity check. "linux_go_ahead" expression => regcmp(".*other::rwx.*", "$(sanity_perms)"); vars: linux_go_ahead|windows:: "result" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); !linux_go_ahead.!windows:: "result" string => ""; reports: DEBUG.!linux_go_ahead.!windows:: "ACL support not detected. Try remounting the filesystem with -o acl."; } ####################################################### bundle agent check { classes: "ok" not => regcmp(".*(error|failed).*", "$(test.result)"); reports: DEBUG:: "Tests various ACL features"; DEBUG.!ok:: "Subtest(s) failing: $(test.result)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; files: "$(G.testdir)$(const.dirsep)file" acl => acl_sanity_check_reset; } body acl acl_sanity_check_reset { acl_method => "append"; aces => { "all:-rwx:allow" }; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/12_acl/file_copy_acl.cf0000644000000000000000000001037015010704253024351 0ustar00rootroot00000000000000###################################################### # # ACL tests for file copying. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { classes: "cfengine_internal_getfacl" expression => fileexists("/var/cfengine/bin/getfacl"); "system_getfacl" expression => fileexists("/usr/bin/getfacl"); vars: linux.cfengine_internal_getfacl:: "cmd" string => "/var/cfengine/bin/getfacl"; linux.!cfengine_internal_getfacl.system_getfacl:: "cmd" string => "/usr/bin/getfacl"; windows:: "cmd" string => "C:\windows\system32\cmd.exe /C cacls"; files: "$(G.testdir)/source_plain" create => "true"; "$(G.testdir)/source_ext" create => "true", acl => testacl; } body acl testacl { !windows:: acl_method => "append"; aces => { "user:root:wx" }; windows:: acl_method => "overwrite"; aces => { "user:Administrator:r" }; acl_inherit => "false"; } bundle agent test { meta: "test_skip_needs_work" string => "windows"; files: "$(G.testdir)/destination_plain" copy_from => source_plain; "$(G.testdir)/destination_ext_preserve" copy_from => source_ext_preserve; "$(G.testdir)/destination_ext_no_preserve" copy_from => source_ext_no_preserve; } body copy_from source_plain { source => "$(G.testdir)/source_plain"; } body copy_from source_ext_preserve { source => "$(G.testdir)/source_ext"; preserve => "yes"; } body copy_from source_ext_no_preserve { source => "$(G.testdir)/source_ext"; preserve => "no"; } bundle agent check { vars: "destination_ext_preserve_output" string => execresult("$(init.cmd) $(G.testdir)$(const.dirsep)destination_ext_preserve", "noshell"); "destination_ext_no_preserve_output" string => execresult("$(init.cmd) $(G.testdir)$(const.dirsep)destination_ext_no_preserve", "noshell"); !windows:: "destination_plain_output" string => execresult("/bin/ls -lZ $(G.testdir)$(const.dirsep)destination_plain", "noshell"); "source_ext_output" string => execresult("$(init.cmd) $(G.testdir)$(const.dirsep)source_ext", "noshell"); classes: !windows:: "destination_plain_ok" not => regcmp(".*[-rwx]{10}\+.*", "$(destination_plain_output)"); "source_ext_ok" expression => regcmp(".*user:root:-wx.*", "$(source_ext_output)"); "destination_ext_preserve_ok" expression => regcmp(".*user:root:-wx.*", "$(destination_ext_preserve_output)"); "destination_ext_no_preserve_ok" not => regcmp(".*user:root:-wx.*", "$(destination_ext_no_preserve_output)"); "targets_ok" and => { "destination_plain_ok", "destination_ext_preserve_ok", "destination_ext_no_preserve_ok" }; # The !source_ext_ok test is in case the underlying file system does not support ACLs. "ok" or => { "!source_ext_ok", "targets_ok" }; windows:: "destination_ext_preserve_ok" expression => regcmp(".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_READ_DATA.*FILE_READ_EA.*FILE_READ_ATTRIBUTES.*", "$(destination_ext_preserve_output)"); "destination_ext_no_preserve_ok" not => regcmp(".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_READ_DATA.*FILE_READ_EA.*FILE_READ_ATTRIBUTES.*", "$(destination_ext_no_preserve_output)"); "ok" and => { "destination_ext_preserve_ok", "destination_ext_no_preserve_ok" }; reports: DEBUG.!windows:: "Destination file permissions (should not contain a '+'): $(destination_plain_output)"; "Destination file permissions (should contain \"user:root:-wx\"): $(destination_ext_preserve_output)"; "Destination file permissions (should not contain \"user:root:-wx\"): $(destination_ext_no_preserve_output)"; DEBUG.windows:: "Destination file permissions (should contain read attributes): $(destination_ext_preserve_output)"; "Destination file permissions (should not contain read attributes): $(destination_ext_no_preserve_output)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/12_acl/acl.cf.sub0000644000000000000000000003536615010704253023124 0ustar00rootroot00000000000000###################################################### # # ACL tests # This test is not convergent, since it tests the # same file over and over. But it saves us a lot # of test code. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "init", "test" }; version => "1.0"; } ####################################################### bundle agent init { classes: "cfengine_internal_getfacl" expression => fileexists("/var/cfengine/bin/getfacl"); "system_getfacl" expression => fileexists("/usr/bin/getfacl"); vars: linux.cfengine_internal_getfacl:: "cmd" string => "/var/cfengine/bin/getfacl"; linux.!cfengine_internal_getfacl.system_getfacl:: "cmd" string => "/usr/bin/getfacl"; windows:: "cmd" string => "C:\windows\system32\cmd.exe /C cacls"; vars: windows:: "rootuser" string => "Administrator"; !windows:: "rootuser" string => "root"; vars: # ACLs may work on many Unixes, but only Linux has the tool we use to check the permissions. linux:: # Ordering is important here, in the case of append. "acl_method[regular_posix]" string => "overwrite"; "aces[regular_posix]" slist => { "user:*:=rw:allow", "group:*:=rw:allow", "all:=r:allow" }; "regcmp[regular_posix]" string => ".*user::rw-.*group::rw-.*other::r--.*"; "acl_method[regular_posix2]" string => "overwrite"; "aces[regular_posix2]" slist => { "user:*:=x:allow", "group:*:=x:allow", "all:=w:allow" }; "regcmp[regular_posix2]" string => ".*user::--x.*group::--x.*other::-w-.*"; "acl_method[specific_user]" string => "overwrite"; "aces[specific_user]" slist => { "user:*:=r:allow", "group:*:=r:allow", "all:=r:allow", "user:root:=rwx:allow" }; "regcmp[specific_user]" string => ".*user::r--.*user:root:rwx.*group::r--.*other::r--.*"; "notregcmp[specific_user]" string => ".*group:root:.*"; "acl_method[specific_group_append]" string => "append"; "aces[specific_group_append]" slist => { "group:root:=rw:allow" }; "regcmp[specific_group_append]" string => ".*user::r--.*user:root:rwx.*group::r--.*group:root:rw-.*other::r--.*"; "acl_method[no_mask]" string => "overwrite"; "aces[no_mask]" slist => { "user:*:=r:allow", "group:*:=r:allow", "all:=r:allow", "user:root:=rx:allow" }; "regcmp[no_mask]" string => ".*user::r--.*user:root:r-x.*group::r--.*mask::r-x.*other::r--.*"; "acl_type[specific_mask]" string => "posix"; "acl_method[specific_mask]" string => "overwrite"; "aces[specific_mask]" slist => { "user:*:=r:allow", "group:*:=r:allow", "mask:=r:allow", "all:=r:allow", "user:root:=rw:allow" }; "regcmp[specific_mask]" string => ".*user::r--.*user:root:rw-.*group::r--.*mask::r--.*other::r--.*"; "notregcmp[specific_mask]" string => ".*group:root:.*"; "acl_method[mask_and_append_group]" string => "append"; "aces[mask_and_append_group]" slist => { "group:root:=rx:allow" }; "regcmp[mask_and_append_group]" string => ".*user::r--.*user:root:rw-.*group::r--.*group:root:r-x.*mask::rwx.*other::r--.*"; "acl_method[no_perm_group]" string => "append"; "aces[no_perm_group]" slist => { "group:root:=:allow" }; "regcmp[no_perm_group]" string => ".*user::r--.*user:root:rw-.*group::r--.*group:root:---.*mask::rw-.*other::r--.*"; "acl_method[add_perm]" string => "append"; "aces[add_perm]" slist => { "user:*:+x:allow" }; "regcmp[add_perm]" string => ".*user::r-x.*user:root:rw-.*group::r--.*group:root:---.*mask::rw-.*other::r--.*"; "acl_method[add_perm_user]" string => "append"; "aces[add_perm_user]" slist => { "user:root:+x:allow" }; "regcmp[add_perm_user]" string => ".*user::r-x.*user:root:rwx.*group::r--.*group:root:---.*mask::rwx.*other::r--.*"; "acl_method[rm_perm]" string => "append"; "aces[rm_perm]" slist => { "all:-r:allow", "user:root:-rw:allow" }; "regcmp[rm_perm]" string => ".*user::r-x.*user:root:--x.*group::r--.*group:root:---.*mask::r-x.*other::---.*"; "acl_method[overwrite_add_remove]" string => "overwrite"; # Overwrite starts with blank permissions. "aces[overwrite_add_remove]" slist => { "all:+r:allow", "user:*:-x:allow", "group:*:+x:allow" }; "regcmp[overwrite_add_remove]" string => ".*user::---.*group::--x.*other::r--.*"; "notregcmp[overwrite_add_remove]" string => ".*user:root:.*|.*group:root:.*"; # This test oscillates between pass and fail. Check out "other::r--" vs "other::r-x" "acl_method[default]" string => "overwrite"; "aces[default]" slist => { "all:r:allow", "user:*:rwx:allow", "group:*:rw:allow" }; "acl_default[default]" string => "access"; "use_dir[default]" string => "true"; "regcmp[default]" string => ".*user::rwx.*group::rw-.*other::r--.*default:user::rwx.*default:group::rw-.*default:other::r--.*"; # Fails but should pass. "acl_method[default_specify]" string => "overwrite"; "aces[default_specify]" slist => { "user:*:r:allow", "group:*:r:allow", "all:r:allow" }; "acl_default[default_specify]" string => "specify"; "specify_default_aces[default_specify]" slist => { "user:*:rwx:allow", "group:*:rw:allow", "all:rw:allow", "user:root:x:allow" }; "use_dir[default_specify]" string => "true"; "regcmp[default_specify]" string => ".*user::r--.*group::r--.*other::r--.*default:user::rwx.*default:user:root:--x.*default:group::rw-.*default:other::rw-.*"; "tests" slist => { "regular_posix", "regular_posix2", "specific_user", "specific_group_append", "no_mask", "specific_mask", "mask_and_append_group", "no_perm_group", "add_perm", "add_perm_user", "rm_perm", "overwrite_add_remove", "default", "default_specify", } ; windows:: "acl_method[read]" string => "overwrite"; "aces[read]" slist => { "user:Administrator:r:allow" }; "acl_inherit[read]" string => "false"; "regcmp[read]" string => ".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_READ_DATA.*FILE_READ_EA.*FILE_READ_ATTRIBUTES.*"; "notregcmp[read]" string => ".*\(ID\).*"; "acl_method[write]" string => "overwrite"; "aces[write]" slist => { "user:Administrator:w:allow" }; "regcmp[write]" string => ".*Administrator:.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_WRITE_EA.*FILE_WRITE_ATTRIBUTES.*"; "notregcmp[write]" string => ".*\(ID\).*"; "acl_method[append_read]" string => "append"; "aces[append_read]" slist => { "user:Administrator:r:allow" }; "regcmp[append_read]" string => ".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_READ_DATA.*FILE_READ_EA.*FILE_READ_ATTRIBUTES.*"; "notregcmp[append_read]" string => ".*(Administrator:.*(FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES)|\(ID\)).*"; "acl_method[add_write]" string => "append"; "aces[add_write]" slist => { "user:Administrator:+w:allow" }; "regcmp[add_write]" string => ".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*"; "notregcmp[add_write]" string => ".*\(ID\).*"; "acl_method[rm_write]" string => "append"; "aces[rm_write]" slist => { "user:Administrator:-w:allow" }; "regcmp[rm_write]" string => ".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_READ_DATA.*FILE_READ_EA.*FILE_READ_ATTRIBUTES.*"; "notregcmp[rm_write]" string => ".*\(ID\).*"; "acl_method[no_default]" string => "overwrite"; "aces[no_default]" slist => { "user:Administrator:rwx:allow" }; "acl_default[no_default]" string => "clear"; "use_dir[no_default]" string => "true"; "regcmp[no_default]" string => ".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_EXECUTE.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*"; "notregcmp[no_default]" string => ".*(\(OI\)|\(CI\)).*"; "acl_method[default]" string => "overwrite"; "aces[default]" slist => { "user:Administrator:rwx:allow" }; "acl_default[default]" string => "access"; "use_dir[default]" string => "true"; "regcmp[default]" string => ".*Administrator:\(OI\)\(CI\).*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_EXECUTE.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*"; "acl_method[inherit]" string => "overwrite"; "aces[inherit]" slist => { "group:Everyone:r:allow" }; "acl_inherit[inherit]" string => "true"; "regcmp[inherit]" string => ".*Everyone:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_READ_DATA.*FILE_READ_EA.*FILE_READ_ATTRIBUTES.*Administrator:\(ID\).*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*"; "acl_method[inherit_nochange]" string => "append"; "aces[inherit_nochange]" slist => { "group:Everyone:+w:allow" }; "acl_inherit[inherit_nochange]" string => "nochange"; "regcmp[inherit_nochange]" string => ".*Everyone:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*Administrator:\(ID\).*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*"; "acl_method[empty]" string => "append"; "aces[empty]" slist => { "group:Everyone:-rw:allow" }; "acl_inherit[empty]" string => "nochange"; "regcmp[empty]" string => ".*Administrator:\(ID\).*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*"; "notregcmp[empty]" string => ".*Everyone.*"; "acl_method[no_inherit]" string => "append"; "aces[no_inherit]" slist => { "group:Everyone:+rw:allow" }; "acl_inherit[no_inherit]" string => "false"; "regcmp[no_inherit]" string => ".*Everyone:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_GENERIC_WRITE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_WRITE_EA.*FILE_READ_ATTRIBUTES.*FILE_WRITE_ATTRIBUTES.*"; "notregcmp[no_inherit]" string => ".*\(ID\).*"; "acl_type[ext_attr_delete]" string => "ntfs"; "acl_method[ext_attr_delete]" string => "overwrite"; "aces[ext_attr_delete]" slist => { "user:Administrator:(d):allow" }; "regcmp[ext_attr_delete]" string => ".*Administrator:.*DELETE.*"; "notregcmp[ext_attr_delete]" string => ".*(\(ID\)|READ|WRITE).*"; "acl_type[ext_attr_half1]" string => "ntfs"; "acl_method[ext_attr_half1]" string => "append"; "aces[ext_attr_half1]" slist => { "user:Administrator:+(rtxTwa):allow" }; "regcmp[ext_attr_half1]" string => ".*Administrator:.*DELETE.*FILE_READ_DATA.*FILE_WRITE_DATA.*FILE_APPEND_DATA.*FILE_READ_EA.*FILE_EXECUTE.*FILE_READ_ATTRIBUTES.*"; "notregcmp[ext_attr_half1]" string => ".*\(ID\).*"; "acl_type[ext_attr_half2]" string => "ntfs"; "acl_method[ext_attr_half2]" string => "append"; "aces[ext_attr_half2]" slist => { "user:Administrator:-(drtxTwa),+(bBpcoD):allow" }; "regcmp[ext_attr_half2]" string => ".*Administrator:.*READ_CONTROL.*WRITE_DAC.*WRITE_OWNER.*FILE_WRITE_EA.*FILE_DELETE_CHILD.*FILE_WRITE_ATTRIBUTES.*"; "notregcmp[ext_attr_half2]" string => ".*(\(ID\)|[^_]DELETE|FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_READ_EA|FILE_EXECUTE|FILE_READ_ATTRIBUTES).*"; "tests" slist => { "read", "write", "append_read", "add_write", "rm_write", "no_default", "default", "inherit", "inherit_nochange", "empty", "no_inherit", "ext_attr_delete", "ext_attr_half1", "ext_attr_half2", }; files: "$(G.testdir)$(const.dirsep)file" create => "true"; } ####################################################### bundle agent test { methods: linux|windows:: "any" usebundle => test_and_check("$(init.tests)"); } bundle agent test_and_check(testname) { classes: "use_dir" expression => isvariable("init.use_dir[$(testname)]"); methods: use_dir:: "any" usebundle => test_exec("$(testname)", "$(G.testdir)"); "any" usebundle => test_check("$(testname)", "$(G.testdir)"); !use_dir:: "any" usebundle => test_exec("$(testname)", "$(G.testdir)$(const.dirsep)file"); "any" usebundle => test_check("$(testname)", "$(G.testdir)$(const.dirsep)file"); } bundle agent test_exec(testname, file) { classes: "acl_type" expression => isvariable("init.acl_type[$(testname)]"); "acl_default" expression => isvariable("init.acl_default[$(testname)]"); acl_default:: "specify_default_aces" expression => strcmp("init.acl_default[$(testname)]", "specify"); files: "$(file)" acl => acldef("$(testname)", "$(file)"); } body acl acldef(testname, file) { acl_method => "$(init.acl_method[$(testname)])"; acl_inherit => "$(init.acl_inherit[$(testname)])"; aces => { "@(init.aces[$(testname)])" }; acl_type:: acl_type => "$(init.acl_type[$(testname)])"; !acl_type:: acl_type => "generic"; acl_default:: acl_default => "$(init.acl_default[$(testname)])"; specify_default_aces:: specify_default_aces => { "@(init.specify_default_aces[$(testname)])" }; } bundle agent test_check(testname, file) { vars: "output" string => execresult("$(init.cmd) $(file)", "noshell"); classes: "regcmp_matched" expression => regcmp("$(init.regcmp[$(testname)])", "$(output)"); "notregcmp_exists" expression => isvariable("init.notregcmp[$(testname)]"); notregcmp_exists:: "notregcmp_matched" expression => regcmp("$(init.notregcmp[$(testname)])", "$(output)"); reports: !regcmp_matched|notregcmp_matched:: "Test \"$(testname)\" failed: Got \"$(output)\""; "Should contain \"$(init.regcmp[$(testname)])\""; (!regcmp_matched|notregcmp_matched)¬regcmp_exists:: "Should NOT contain \"$(init.notregcmp[$(testname)])\""; } cfengine-3.24.2/tests/acceptance/10_files/12_acl/file_edit_acl.cf0000644000000000000000000000577215010704253024336 0ustar00rootroot00000000000000###################################################### # # ACL tests for file editing. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { classes: "cfengine_internal_getfacl" expression => fileexists("/var/cfengine/bin/getfacl"); "system_getfacl" expression => fileexists("/usr/bin/getfacl"); vars: linux.cfengine_internal_getfacl:: "cmd" string => "/var/cfengine/bin/getfacl"; linux.!cfengine_internal_getfacl.system_getfacl:: "cmd" string => "/usr/bin/getfacl"; windows:: "cmd" string => "C:\windows\system32\cmd.exe /C cacls"; files: "$(G.testdir)/file_plain" create => "true"; "$(G.testdir)/basetest_ext" create => "true", acl => testacl; "$(G.testdir)/file_ext" create => "true", acl => testacl; } body acl testacl { !windows:: acl_method => "append"; aces => { "user:root:wx" }; windows:: acl_method => "overwrite"; aces => { "user:Administrator:r" }; acl_inherit => "false"; } bundle agent test { meta: "test_skip_needs_work" string => "windows"; files: "$(G.testdir)/file_plain" edit_line => file_edit; files: "$(G.testdir)/file_ext" edit_line => file_edit; } bundle edit_line file_edit { insert_lines: "New line!"; } bundle agent check { vars: "file_ext_output" string => execresult("$(init.cmd) $(G.testdir)$(const.dirsep)file_ext", "noshell"); !windows:: "file_plain_output" string => execresult("/bin/ls -lZ $(G.testdir)$(const.dirsep)file_plain", "noshell"); "basetest_ext_output" string => execresult("$(init.cmd) $(G.testdir)$(const.dirsep)basetest_ext", "noshell"); classes: !windows:: "file_plain_ok" not => regcmp(".*[-rwx]{10}\+.*", "$(file_plain_output)"); "basetest_ext_ok" expression => regcmp(".*user:root:-wx.*", "$(basetest_ext_output)"); "file_ext_ok" expression => regcmp(".*user:root:-wx.*", "$(file_ext_output)"); # The !basetest_ext_ok test is in case the underlying file system does not support ACLs. "ext_ok" or => { "!basetest_ext_ok", "file_ext_ok" }; "ok" and => { "file_plain_ok", "ext_ok" }; windows:: "ok" expression => regcmp(".*Administrator:.*READ_CONTROL.*FILE_GENERIC_READ.*FILE_READ_DATA.*FILE_READ_EA.*FILE_READ_ATTRIBUTES.*", "$(file_ext_output)"); reports: DEBUG.!windows:: "Destination file permissions (should not contain a '+'): $(file_plain_output)"; "Destination file permissions (should contain \"user:root:-wx\"): $(file_ext_output)"; DEBUG.windows:: "Destination file permissions (should contain read attributes): $(file_ext_output)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 no_error_archiving_previous_backup_using_copy_from_without_create_true.cf.sub0000644000000000000000000000553515010704253040027 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_filesbody common control { inputs => { "../default.cf.sub" }; version => "1.0"; } bundle agent init { vars: # body agent control default_repository uses this 'bck' string => '$(G.testdir)/backups'; files: '$(init.bck)/.' create => 'true'; } bundle agent __main__ { methods: "init"; "test"; } bundle agent test { meta: "description" -> { "CFE-3640" } string => "Test that automatically created backup copies of files promised via copy_from do not produce errors."; vars: 'file' string => "$(G.testfile)"; files: # Let's have a file '$(file)' create => "true", classes => outcomes('create'); # Let's have the file be a copy of this policy, this should create the first backup file '$(file)' copy_from => path('$(this.promise_filename)'), handle => 'copy_1', classes => outcomes('copy_1'); # Let's make sure the file differs from this policy file, so that we have reason to copy the file again '$(file)' edit_line => lines_present( 'edit after first copy' ), handle => 'edit_1', classes => outcomes('edit_1'); # Let's have the file be a copy of this policy, this should create the second backup file # This promise triggered an error on AIX, see CFE-3640. '$(file)' copy_from => path('$(this.promise_filename)'), handle => 'copy_2', classes => outcomes('copy_2'); # Let's make sure the file differs from this policy file, so that we have reason to copy the file again '$(file)' edit_line => lines_present( 'edit after second copy' ), handle => 'edit_2', classes => outcomes('edit_2'); # Let's have the file be a copy of this policy, this should create the second backup file '$(file)' copy_from => path('$(this.promise_filename)'), handle => 'copy_3', classes => outcomes('copy_3'); reports: DEBUG|EXTRA:: 'CFEngine $(sys.cf_version) (running on $(sys.flavour))'; 'Results: $(with)' with => join(' ', classesmatching('_.*')); } body copy_from path(path) { source => translatepath($(path)); } body agent control { default_repository => '$(init.bck)'; } body classes outcomes(p) { promise_kept => { '$(p)_kept', '$(p)_reached' }; promise_repaired => { '$(p)_repaired', '$(p)_reached' }; repair_failed => { '$(p)_failed', '$(p)_reached', '$(p)_error' }; repair_denied => { '$(p)_denied', '$(p)_reached', '$(p)_error' }; repair_timeout => { '$(p)_timeout', '$(p)_reached', '$(p)_error' }; scope => 'bundle'; } bundle edit_line lines_present(lines) { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/0000755000000000000000000000000015010704253022767 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/001.cf0000644000000000000000000000365215010704253023607 0ustar00rootroot00000000000000####################################################### # # Replace fields, simple case # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "2"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/019.cf0000644000000000000000000000404215010704253023612 0ustar00rootroot00000000000000####################################################### # # Append field, testing blank values (spaces, not completely blank) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe: , ::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo,XXX apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe: , ,XXX::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/016.cf0000644000000000000000000000375315010704253023617 0ustar00rootroot00000000000000####################################################### # # Prepend field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX+baker,booker,banker:charlie:delta:echo apple:XXX+banana:carrot:dogfood aardvark:XXX+baboon:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "prepend"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/set_empty_field_erroneous_message.cf0000644000000000000000000000146615010704253032271 0ustar00rootroot00000000000000####################################################### # # catch spurious editing messages in field editing # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { methods: "" usebundle => file_make($(G.testfile), "root:sikrt:16104::::::"); "" usebundle => dcs_passif_output("", ".*(Edited|Setting).*", "$(sys.cf_agent) -KI -f $(this.promise_filename).sub | $(G.grep) field", $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/010.cf0000644000000000000000000000400415010704253023577 0ustar00rootroot00000000000000####################################################### # # Append field, different value_separator # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker+XXX:charlie:delta:echo apple:banana+XXX:carrot:dogfood aardvark:baboon+XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/file_content.error.cf0000644000000000000000000000420515010704253027103 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { # Create a blank file to compare files: "$(G.testfile).expected.blank" create => "true", edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).error.edit_line" create => "true", content => "whatever", edit_line => whatever_line; "$(G.testfile).error.edit_xml" create => "true", content => "whatever", edit_xml => whatever_xml; "$(G.testfile).error.edit_template" create => "true", content => "whatever", edit_template => "/path/to/whatever"; "$(G.testfile).error.edit_template_string" create => "true", content => "whatever", edit_template_string => "whatever"; } bundle edit_line whatever_line { } bundle edit_xml whatever_xml { } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff("$(G.testfile).error.edit_line", "$(G.testfile).expected.blank", "$(this.promise_filename)"); "" usebundle => dcs_check_diff("$(G.testfile).error.edit_xml", "$(G.testfile).expected.blank", "$(this.promise_filename)"); "" usebundle => dcs_check_diff("$(G.testfile).error.edit_template", "$(G.testfile).expected.blank", "$(this.promise_filename)"); "" usebundle => dcs_check_diff("$(G.testfile).error.edit_template_string", "$(G.testfile).expected.blank", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/017.cf0000644000000000000000000000361615010704253023616 0ustar00rootroot00000000000000####################################################### # # Append field, testing blank values # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo+XXX apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:,+XXX::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/set_empty_field_erroneous_message.cf.sub0000644000000000000000000000065615010704253033061 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { editor }; } bundle agent editor { vars: "null_shadow_entries" ilist => {4, 5, 6, 7, 8}; files: "$(G.testfile)" handle => "null_root_user_account_expiration_shadow_entries", edit_line => set_user_field("root", $(null_shadow_entries), ""), classes => if_repaired("root_password_modified"); } cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/036.cf0000644000000000000000000000367315010704253023622 0ustar00rootroot00000000000000####################################################### # # Append field, testing blank values (default field_operation) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo+XXX apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:,+XXX::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; # field_operation => "append"; # Default value field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/031.cf0000644000000000000000000000361215010704253023606 0ustar00rootroot00000000000000####################################################### # # Set field, not allowing blanks (test needs to be double-checked for accuracy) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo:XXX apple:banana:carrot:dogfood::XXX aardvark:baboon:colugo:dingo:fox:XXX ampallang: :dydoe:,::XXX :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "false"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "6"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/030.cf0000644000000000000000000000373615010704253023614 0ustar00rootroot00000000000000####################################################### # # Set field, after end of some lists without extend_fields # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::XXX ampallang:: :dydoe:,:XXX:::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "false"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "6"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/004.x.cf0000644000000000000000000000377515010704253024066 0ustar00rootroot00000000000000####################################################### # # Replace fields, broken start_fields_from_zero # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false "; # Illegal value value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/006.x.cf0000644000000000000000000000377515010704253024070 0ustar00rootroot00000000000000####################################################### # # Replace fields, illegal select_field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "-1"; # Must be greater than 1 start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/023.cf0000644000000000000000000000375515010704253023617 0ustar00rootroot00000000000000####################################################### # # Alphanum field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX,baker,banker,booker:charlie:delta:echo apple:XXX,banana:carrot:dogfood aardvark:XXX,baboon:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/set_classes_in_warn_only.cf0000644000000000000000000000600115010704253030364 0ustar00rootroot00000000000000####################################################### # #Tries to edit a file in warn_only, and must have a kept class defined # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "filename_kept" string => "shadow.kept"; "filename_failed" string => "shadow.failed"; "content" string => "nicolas:$1$NoSH4e.u$U4uEzaOuC0tmQThtI3hj00:16988:0:99999:7:::"; "name" string => "nicolas"; "field_kept" string => "$1$NoSH4e.u$U4uEzaOuC0tmQThtI3hj00"; "field_failed" string => "bad"; files: "$(G.testfile).$(init.filename_kept)" create => "true", edit_line => init_insert("$(init.content)"), edit_defaults => init_empty; "$(G.testfile).$(init.filename_failed)" create => "true", edit_line => init_insert("$(init.content)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).$(init.filename_kept)" create => "false", edit_line => test_set_user_field("${init.name}", 2, "${init.field_kept}"), action => test_warn_only, classes => test_classes_generic("test_result_kept"); "$(G.testfile).$(init.filename_failed)" create => "false", edit_line => test_set_user_field("${init.name}", 2, "${init.field_failed}"), action => test_warn_only, classes => test_classes_generic("test_result_failed"); } bundle edit_line test_set_user_field(user,field,val) { field_edits: "$(user):.*" comment => "Edit a user attribute in the password file", edit_field => test_col(":","$(field)","$(val)","set"); } body edit_field test_col(split,col,newval,method) { field_separator => "$(split)"; select_field => "$(col)"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } body action test_warn_only { action_policy => "warn"; ifelapsed => "60"; } body classes test_classes_generic(x) { promise_repaired => { "$(x)_repaired" }; repair_failed => { "$(x)_failed" }; repair_denied => { "$(x)_denied" }; repair_timeout => { "$(x)_timeout" }; promise_kept => { "$(x)_ok" }; } ####################################################### bundle agent check { reports: test_result_kept_ok.test_result_failed_failed:: "$(this.promise_filename) Pass"; !(test_result_kept_ok.test_result_failed_failed):: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/003.cf0000644000000000000000000000376615010704253023617 0ustar00rootroot00000000000000####################################################### # # Replace fields, simple case index 1 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/file_content.cf0000644000000000000000000000343215010704253025754 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "expected.singleline" string => "content in file"; "expected.multiline" string => "multiline content in file"; # Create the expected files using insert_lines files: "$(G.testfile).expected.singleline" create => "true", edit_line => init_insert("$(expected.singleline)"), edit_defaults => init_empty; "$(G.testfile).expected.multiline" create => "true", edit_line => init_insert("$(expected.multiline)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10254" }; files: "$(G.testfile).actual.singleline" create => "true", content => "content in file "; "$(G.testfile).actual.multiline" create => "true", content => "multiline content in file "; } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff("$(G.testfile).actual.singleline", "$(G.testfile).expected.singleline", "$(this.promise_filename)"); "" usebundle => dcs_check_diff("$(G.testfile).actual.multiline", "$(G.testfile).expected.multiline", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/005.cf0000644000000000000000000000365115010704253023612 0ustar00rootroot00000000000000####################################################### # # Replace fields, illegal select_field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "0"; # Must be greater than 1 to be legal start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/015.cf0000644000000000000000000000375315010704253023616 0ustar00rootroot00000000000000####################################################### # # Prepend field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX,baker,booker,banker:charlie:delta:echo apple:XXX,banana:carrot:dogfood aardvark:XXX,baboon:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "prepend"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/029.cf0000644000000000000000000000377015010704253023622 0ustar00rootroot00000000000000####################################################### # # Alphanum field, lowercase # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,banker,booker,xxx:charlie:delta:echo apple:banana,xxx:carrot:dogfood aardvark:baboon,xxx:colugo:dingo::fox ampallang:xxx: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "xxx"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/009.cf0000644000000000000000000000375115010704253023617 0ustar00rootroot00000000000000####################################################### # # Append field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker,XXX:charlie:delta:echo apple:banana,XXX:carrot:dogfood aardvark:baboon,XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/024.cf0000644000000000000000000000375515010704253023620 0ustar00rootroot00000000000000####################################################### # # Alphanum field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,bo0ker,bonker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX+baker,bo0ker,bonker:charlie:delta:echo apple:XXX+banana:carrot:dogfood aardvark:XXX+baboon:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/007.x.cf0000644000000000000000000000376715010704253024072 0ustar00rootroot00000000000000####################################################### # # Replace fields, illegal select_field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "xyz"; # Must be numeric start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/033.cf0000644000000000000000000000404415010704253023610 0ustar00rootroot00000000000000####################################################### # # Append field (default field_operation) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker,XXX:charlie:delta:echo apple:banana,XXX:carrot:dogfood aardvark:baboon,XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; # field_operation => "append"; # Default value field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/032.cf0000644000000000000000000000362415010704253023612 0ustar00rootroot00000000000000####################################################### # # Delete fields, simple case # Bug, tracked on https://cfengine.com/dev/issues/3506 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,XXX,banker:charlie:delta:echo apple:XXX,banana:carrot:dogfood aardvark:baboon,XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "delete"; field_separator => ":"; field_value => "XXX"; select_field => "2"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/002.cf0000644000000000000000000000373315010704253023610 0ustar00rootroot00000000000000####################################################### # # Replace fields, simple case, index 0 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "1"; start_fields_from_zero => "true"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/018.cf0000644000000000000000000000362015010704253023612 0ustar00rootroot00000000000000####################################################### # # Prepend field, testing blank values # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:XXX+echo apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:XXX+,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "prepend"; field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/0000755000000000000000000000000015010704253024423 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/026.cf0000644000000000000000000000366515010704253025256 0ustar00rootroot00000000000000####################################################### # # Alphanum field, testing blank values (spaces, not completely blank) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe: , ::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:XXX,echo apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:XXX, , ::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/022.x.cf0000644000000000000000000000365615010704253025520 0ustar00rootroot00000000000000####################################################### # # Alphanum field, field_separator same as value_separator # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ":"; # Shouldn't be the same as field_separator } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/034.x.cf0000644000000000000000000000372215010704253025515 0ustar00rootroot00000000000000####################################################### # # Append field, field_separator the same as value_separator (default field_operation) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker+XXX:charlie:delta:echo apple:banana+XXX:carrot:dogfood aardvark:baboon+XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; # field_operation => "append"; # Default value field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ":"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/043.x.cf0000644000000000000000000000353715010704253025521 0ustar00rootroot00000000000000####################################################### # # Replace fields, missing field_value # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; # field_value => "XXX"; # useless without this! select_field => "2"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/040.cf0000644000000000000000000000365315010704253025247 0ustar00rootroot00000000000000####################################################### # # Replace fields, regex separator value_separator not included in it # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:XXX:delta:echo apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:XXX,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => "[:,]"; field_value => "XXX"; select_field => "5"; value_separator => "/"; # This is not included in the field_separator } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/014.x.cf0000644000000000000000000000360115010704253025507 0ustar00rootroot00000000000000####################################################### # # Prepend field, field_separator same as value_separator # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "prepend"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ":"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/035.x.cf0000644000000000000000000000375415010704253025523 0ustar00rootroot00000000000000####################################################### # # Append field, field_separator missing (default field_operation) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker?XXX:charlie:delta:echo apple:banana?XXX:carrot:dogfood aardvark:baboon?XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; # field_value => "XXX"; # Default value select_field => "2"; start_fields_from_zero => "false"; # value_separator => ","; # How can you append if you don't have sep? } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/041.x.cf0000644000000000000000000000365015010704253025513 0ustar00rootroot00000000000000####################################################### # # Replace fields, regex separator with value_separator included in it # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:XXX:delta:echo apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:XXX,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => "[:,]"; field_value => "XXX"; select_field => "5"; value_separator => ","; # This is included in the field_separator } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/012.x.cf0000644000000000000000000000367715010704253025522 0ustar00rootroot00000000000000####################################################### # # Append field, field_separator missing # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker?XXX:charlie:delta:echo apple:banana?XXX:carrot:dogfood aardvark:baboon?XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; # value_separator => ","; # How can you append if you don't have sep? } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/025.cf0000644000000000000000000000362215010704253025246 0ustar00rootroot00000000000000####################################################### # # Alphanum field, testing blank values # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:XXX,echo apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:XXX,,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/042.x.cf0000644000000000000000000000354115010704253025513 0ustar00rootroot00000000000000####################################################### # # Replace fields, missing field_value # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; # field_value => "XXX"; # useless without this! select_field => "2"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/011.x.cf0000644000000000000000000000364515010704253025514 0ustar00rootroot00000000000000####################################################### # # Append field, field_separator the same as value_separator # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker+XXX:charlie:delta:echo apple:banana+XXX:carrot:dogfood aardvark:baboon+XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "append"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; value_separator => ":"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/044.x.cf0000644000000000000000000000354015010704253025514 0ustar00rootroot00000000000000####################################################### # # Replace fields, missing field_value # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "prepend"; field_separator => ":"; # field_value => "XXX"; # useless without this! select_field => "2"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/046.x.cf0000644000000000000000000000354115010704253025517 0ustar00rootroot00000000000000####################################################### # # Replace fields, missing field_value # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; # field_value => "XXX"; # useless without this! select_field => "2"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/021.x.cf0000644000000000000000000000364315010704253025513 0ustar00rootroot00000000000000####################################################### # # Alphanum field, field_separator missing # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; # value_separator => ","; # How can you alphanum if you don't have sep? } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/013.x.cf0000644000000000000000000000364015010704253025511 0ustar00rootroot00000000000000####################################################### # # Prepend field, field_separator missing # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "prepend"; field_separator => ":"; field_value => "XXX"; select_field => "2"; start_fields_from_zero => "false"; # value_separator => ","; # How can you prepend if you don't have sep? } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/045.x.cf0000644000000000000000000000353715010704253025523 0ustar00rootroot00000000000000####################################################### # # Replace fields, missing field_value # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "delete"; field_separator => ":"; # field_value => "XXX"; # useless without this! select_field => "2"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/staging/039.cf0000644000000000000000000000347315010704253025257 0ustar00rootroot00000000000000####################################################### # # Replace fields, regex separator # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:XXX:delta:echo apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:XXX,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => "[:,]"; field_value => "XXX"; select_field => "5"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/037.cf0000644000000000000000000000373615010704253023623 0ustar00rootroot00000000000000####################################################### # # Append field, testing blank values (spaces, not completely blank) (default field_operation) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe: , ::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo+XXX apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe: , +XXX::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; # field_operation => "append"; # Default value field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/038.x.cf0000644000000000000000000000366715010704253024075 0ustar00rootroot00000000000000####################################################### # # Replace fields, illegal value_separator # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "2"; value_separator => ",+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/028.cf0000644000000000000000000000377015010704253023621 0ustar00rootroot00000000000000####################################################### # # Alphanum field, lowercase # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker+xxx:charlie:delta:echo apple:banana+xxx:carrot:dogfood aardvark:baboon+xxx:colugo:dingo::fox ampallang:xxx: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "alphanum"; field_separator => ":"; field_value => "xxx"; select_field => "2"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/027.cf0000644000000000000000000000372015010704253023613 0ustar00rootroot00000000000000####################################################### # # Set field, after end of some lists # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:echo:XXX apple:banana:carrot:dogfood::XXX aardvark:baboon:colugo:dingo::XXX ampallang:: :dydoe:,:XXX:::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "6"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/008.x.cf0000644000000000000000000000377515010704253024072 0ustar00rootroot00000000000000####################################################### # # Replace fields, illegal select_field # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:XXX:charlie:delta:echo apple:XXX:carrot:dogfood aardvark:XXX:colugo:dingo::fox ampallang:XXX: :dydoe:,::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "XXX"; select_field => "-1"; # Must be greater than 1 start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/set_value_line_long.cf0000644000000000000000000003153215010704253027322 0ustar00rootroot00000000000000####################################################### # # Test setting a field in a line longer than 4k # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "a:a:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaend"; "expected" string => "a:b:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaend"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "set"; field_separator => ":"; field_value => "b"; select_field => "2"; start_fields_from_zero => "false"; value_separator => "+"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/08_field_edits/020.cf0000644000000000000000000000404415010704253023604 0ustar00rootroot00000000000000####################################################### # # Prepend field, testing blank values (spaces, not completely blank) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "able:baker,booker,banker:charlie:delta:echo apple:banana:carrot:dogfood aardvark:baboon:colugo:dingo::fox ampallang:: :dydoe: , ::::: :blowfish:conger:dogfish:eel:flounder"; "expected" string => "able:baker,booker,banker:charlie:delta:XXX,echo apple:banana:carrot:dogfood:XXX aardvark:baboon:colugo:dingo:XXX:fox ampallang:: :dydoe:XXX, , ::::: :blowfish:conger:dogfish:eel:flounder"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_edit; } bundle edit_line test_edit { field_edits: "a.*" edit_field => test_col; } body edit_field test_col { allow_blank_fields => "true"; extend_fields => "true"; field_operation => "prepend"; field_separator => ":"; field_value => "XXX"; select_field => "5"; start_fields_from_zero => "false"; value_separator => ","; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_dryryn_option.cf.sub0000644000000000000000000000145715010704253030036 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "template_target" string => "$(G.testfile)"; files: # The template should not be rendered because dryrun is set "$(template_target)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache"; } ####################################################### bundle agent check { classes: "fail" expression => regline("SHOULD NOT RENDER", $(test.template_target) ); reports: !fail:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 no_error_archiving_previous_backup_using_copy_from_without_create_true.cf0000644000000000000000000000221515010704253037227 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_filesbody common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-3640" } string => "Test that automatically created backup copies of files promised via copy_from do not produce errors."; vars: "agent_log_path" string => "$(sys.workdir)$(const.dirsep)state$(const.dirsep)agent.log"; "cf_agent" string => ifelse(isvariable("sys.cf_agent"), "$(sys.cf_agent)", "/var/cfengine/bin/cf-agent"); commands: "$(cf_agent) -Kf $(this.promise_filename).sub >$(test.agent_log_path) 2>&1" contain => in_shell; } bundle agent check { vars: "result" string => readfile($(test.agent_log_path)), if => fileexists( $(test.agent_log_path) ); methods: "Pass/FAIL" usebundle => dcs_check_regcmp(".*(error|Failed to clean backup).*", $(result), $(this.promise_filename), "true"); # We do not expect to find an error in the agent output } mustache_missing_variable_is_empty_string_by_default.cf.mustache.expected0000644000000000000000000000004415010704253036752 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_fileskey1 = value1 key2 = key3 = value3 cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_dryryn.cf.sub0000644000000000000000000000153315010704253026441 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { dryrun => "true"; } ####################################################### bundle agent test { vars: "template_target" string => "$(G.testfile)"; files: # The template should not be rendered because dryrun is set "$(template_target)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache"; } ####################################################### bundle agent check { classes: "fail" expression => regline("SHOULD NOT RENDER", $(test.template_target) ); reports: !fail:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 agent_control_files_single_copy_does_not_apply_to_nonmatching_files_3.cf0000644000000000000000000000253315010704253036650 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body agent control { # Here we test a sane filename pattern against a file we definitely # aren't copying. files_single_copy => { "/var/cfengine/state/WORKAROUND-CFE-2459" }; } bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy does not prevent file patterns that do not match from being copied multiple times."; "test_soft_fail" string => "any", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/two", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/mustache_render_multiline_template_data.cf.mustache0000644000000000000000000000001315010704253032437 0ustar00rootroot00000000000000{{%-top-}} cfengine-3.24.2/tests/acceptance/10_files/files_with_spaces.cf0000644000000000000000000000361315010704253024215 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { meta: "description" string => "ensure clean starting point before test"; files: "$(G.testdir)/$(test.file[$(test.idx)])" delete => tidy; } bundle agent test { meta: "description" string => "Test that file paths with spaces can be created without special treatment"; vars: "file[1]" string => "file with space.txt"; "file[2]" string => "path with/a space.txt"; "idx" slist => getindices( file ); files: "$(G.testdir)/$(file[$(idx)])" classes => scoped_classes_generic("namespace", "file_$(idx)"), create => "true"; } bundle agent check { vars: "expected_classes" slist => maplist( "file_$(this)_repaired", "test.idx" ); # NOT WORKING -- variable not expanded "/tmp/TESTDIR.cfengine/$(test#file[2])" "expected_files" slist => maplist( "$(G.testdir)/$(test.file[$(this)])", "test.idx"); # NOT WORKING -- Only the first file is actually tested # "expected_files" slist => { "$(G.testdir)/$(test.file[@(test.idx)])" }; # NOT WORKING -- only the second file is created # "expected_files" slist => { "$(G.testdir)/$(test.file[$(test.idx)])" }; "classes" slist => classesmatching("file_.*"); classes: "have_expected_classes" and => { @(expected_classes) }; "have_expected_files" expression => filesexist( @(expected_files) ); methods: "Report Test Result" usebundle => dcs_passif_expected("have_expected_classes,have_expected_files", "FAIL", $(this.promise_filename) ), inherit => "true"; reports: DEBUG:: "Expecting class: '$(expected_classes)'"; "Expecting file: '$(expected_files)'"; "Have expected classes" if => "have_expected_classes"; "Have expected files" if => "have_expected_files"; } cfengine-3.24.2/tests/acceptance/10_files/copy_local_file3.cf.expected0000644000000000000000000000000615010704253025521 0ustar00rootroot00000000000000EXPECTcfengine-3.24.2/tests/acceptance/10_files/FIM/0000755000000000000000000000000015010704253020620 5ustar00rootroot00000000000000monitoring_symlinks_does_not_constantly_report_change.cf0000644000000000000000000000312015010704253034235 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/FIMbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" link_from => ln_s( $(this.promise_filename) ); } bundle agent test { meta: "description" string => "Test that monitoring a symlink does not constantly report changes"; "test_skip_unsupported" string => "windows", comment => "Windows does not support symlinks, so it makes no sense to test there"; "test_soft_fail" string => "!windows", meta => { "redmine7692" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; commands: "$(command)" handle => "first_agent_run", comment => "We must run the agent at least once so that the file can be added to the FIM database. The second run we scan for output.", classes => scoped_classes_generic("bundle", "first_agent_run"); methods: first_agent_run_reached:: # We fail if we see Permissions, inode or mtime changes "Check second run" usebundle => dcs_passif_output(".*fim_kept.*", ".*(Permissions for|inode for|Last modified time for).*$(G.testfile).*changed.*", $(command), $(this.promise_filename)); } body link_from ln_s(x) # @brief Create a symbolink link to `x` # The link is created even if the source of the link does not exist. # @param x The source of the link { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } monitoring_symlinks_does_not_constantly_report_change.cf.sub0000644000000000000000000000100215010704253035022 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/FIMbody common control { inputs => { "../../default.cf.sub" }; version => "1.0"; } bundle agent main { files: "$(G.testfile)" changes => detect_all_change; vars: "classes" slist => classesmatching("fim_.*"); reports: "$(classes)"; } body changes detect_all_change # @brief Detect all file changes using the best hash method # # This is fierce, and will cost disk cycles # { hash => "best"; report_changes => "all"; update_hashes => "yes"; } cfengine-3.24.2/tests/acceptance/10_files/copy_local_file3.cf0000644000000000000000000000131715010704253023727 0ustar00rootroot00000000000000####################################################### # # Test local_cp # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { files: "$(G.testfile).expected" copy_from => local_cp("$(this.promise_filename).expected"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(this.promise_filename).expected", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/copy_from_preserve_false.cf0000644000000000000000000000427315010704253025607 0ustar00rootroot00000000000000body file control { inputs => { "../default.cf.sub" }; } bundle agent main { methods: "Test" usebundle => default("$(this.promise_filename)") ; } bundle agent init { files: # We set the permissions of our source file so that we can be sure they # are not the permissions of the target file at the end. "$(this.promise_filename).src" perms => m( "$(check.expect[src])" ); # We make sure the target file exists and has permissions different from # the source file. "$(this.promise_filename).target" delete => tidy; "$(this.promise_filename).target" create => "true", perms => m( "$(check.expect[target])" ); } bundle agent test { meta: "description" string => "Test that preserve false in body copy_from doesn't modify permissions of the promised file"; "test_soft_fail" string => "windows", meta => { "ENT-10257" }; files: # We promise that the target is a copy of the source file Since preserve # is set to false, we expect the original permissions on the target file # to remain unchanged. "$(this.promise_filename).target" copy_from => local_cp_digest_preserve_false( "$(this.promise_filename).src" ); } bundle agent check { vars: "expect[src]" string => "500"; "expect[target]" string => "600"; "observe[src]" string => filestat( "$(this.promise_filename).src", permoct); "observe[target]" string => filestat( "$(this.promise_filename).target", permoct); methods: "Test Result" usebundle => dcs_check_strcmp( "$(expect[target])", "$(observe[target])", $(this.promise_filename), "false"); reports: DEBUG|EXTRA:: ".src Expect $(expect[src]), observe $(observe[target])"; ".target Expect $(expect[target]), observe $(observe[target])"; } body copy_from local_cp_digest_preserve_false (from) { source => "$(from)"; preserve => "false"; compare => "digest"; copy_backup => "false"; } cfengine-3.24.2/tests/acceptance/10_files/zendesk_1776/0000755000000000000000000000000015010704253022334 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/zendesk_1776/zendesk_1776.cf.sub0000644000000000000000000000502415010704253025566 0ustar00rootroot00000000000000######################################################################## # # Test that selecting symlinks does not generate unnecessary errors # Ref: https://dev.cfengine.com/issues/6996 ######################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init # Ensure there is a directory structure created with both plain files and # symlinks to a plain file. { files: "$(G.testdir)/." create => "true"; "$(G.testdir)/plainfile_0" create => "true", edit_line => insert_lines("Just some content"); "$(G.testdir)/file_select/." create => "true"; "$(G.testdir)/file_select/plainfile_1" copy_from => local_cp("/$(G.testdir)/plainfile_0"); "$(G.testdir)/file_select/plainfile_2" copy_from => local_cp("/$(G.testdir)/plainfile_0"); "$(G.testdir)/file_select/symlink_1" link_from => ln_s("/$(G.testdir)/plainfile_0"); "$(G.testdir)/file_select/symlink_2" link_from => ln_s("/$(G.testdir)/plainfile_0"); } bundle agent test { files: "$(G.testdir)/file_select/." delete => tidy, depth_search => recurse("inf"), file_select => select_symlink_pointing_to_usr, comment => "This does not select and delete non symlink files, but did result in undesirable errors for Unable to read link in filter. (readlink: Invalid argument)"; } bundle agent check { vars: "files" slist => lsdir("$(G.testdir)/file_select/", ".*", "false"); "dir_count" int => length(files); classes: # Since we can't test ourself for stdout, we just make sure that the number # of files is correct. A separate policy runs this one and inspects its # output. It needs something to check for passing condition. And failing # condition is the errors its looking for "have_expected_number_of_files" expression => strcmp("$(dir_count)", "6"); "ok" expression => "have_expected_number_of_files"; reports: ok:: "Pass $(this.promise_filename)"; } body file_select select_symlink_pointing_to_usr { file_types => { "symlink" }; issymlinkto => { "/usr/.*" }; file_result => "file_types.issymlinkto"; } body link_from ln_s(x) # @brief Create a symbolink link to `x` # The link is created even if the source of the link does not exist. # @param x The source of the link { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } cfengine-3.24.2/tests/acceptance/10_files/zendesk_1776/zendesk_1776.cf0000644000000000000000000000166515010704253025005 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that seleting files based on symlink do not generate undesired errors"; "story_id" string => ""; "covers" string => ""; } # Ref: https://dev.cfengine.com/issues/6996 ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { meta: "test_skip_unsupported" string => "windows", comment => "The test deals with symlinks which are not supported on windows"; vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*Pass.*", ".*readlink: Invalid argument.*", $(command), $(this.promise_filename)); } mustache_missing_variable_is_empty_string_by_default.cf.mustache0000644000000000000000000000006615010704253035156 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_fileskey1 = {{{key1}}} key2 = {{{key2}}} key3 = {{{key3}}} cfengine-3.24.2/tests/acceptance/10_files/mustache_propagates_failure.cf0000644000000000000000000000204115010704253026261 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that Mustache templates propagate classes to calling bundle"; } ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } bundle agent render_mustache { files: "$(init.template_target)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache"; } bundle agent test { methods: "any" usebundle => render_mustache, classes => if_repaired("mustache_propagated"); } ####################################################### bundle agent check { reports: mustache_propagated:: "$(this.promise_filename) Pass"; !mustache_propagated:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/mustache_render_multiline_template_data.cf0000644000000000000000000000175415010704253030644 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that data passed to edit_template can be rendered as multiline JSON."; } body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "template_target" string => "$(G.testfile)"; "data" data => parsejson('{ "key": "value", "key2": [ "list", "elements" ], "key3": { "complex": { "data": "structure", "with": [ "deep", "data" ] } } }'); files: "$(template_target)" create => "true"; "$(template_target)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => mergedata(data); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_diff( $(test.template_target), "$(this.promise_filename).expected", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/0000755000000000000000000000000015010704253022476 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/insert_text_002.cf0000644000000000000000000000402115010704253025736 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " Marlin"; "expected" string => " MarlinNemo"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "text" string => "Nemo"; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.text)"); } bundle edit_xml test_insert(str) { insert_text: "$(str)" build_xpath => "/Server/Service/Engine/OneFish/TwoFish[@type=\'clownfish\']/RedFish/BlueFish", select_xpath => "/Server/Service/Engine/OneFish/TwoFish[@type=\'clownfish\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/set_text_002.cf0000644000000000000000000000375515010704253025242 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " Marlin"; "expected" string => " Nemo"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "text" string => "Nemo"; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.text)"); } bundle edit_xml test_insert(str) { set_text: "$(str)" build_xpath => "/Server/Service/Engine/OneFish[@type=\'clownfish\']/TwoFish/RedFish/BlueFish", select_xpath => "/Server/Service/Engine/OneFish[@type=\'clownfish\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/delete_text_002.cf0000644000000000000000000000375215010704253025706 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " Nemo"; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "text" string => "Nemo"; files: "$(G.testfile).actual" create => "true", edit_xml => test_delete("$(test.text)"); } bundle edit_xml test_delete(str) { delete_text: "$(str)" build_xpath => "/Server/Service/Engine/OneFish[@type=\'clownfish\']/TwoFish/RedFish/BlueFish", select_xpath => "/Server/Service/Engine/OneFish[@type=\'clownfish\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/delete_text_001.cf0000644000000000000000000000377415010704253025711 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " Hot Potatoes!!! "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "text" string => "Hot Potatoes!!!"; files: "$(G.testfile).actual" create => "true", edit_xml => test_delete("$(test.text)"); } bundle edit_xml test_delete(str) { delete_text: "$(str)" select_xpath => "/Potatoes/Potato[@name=\'OnePotato\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/set_text_001.cf0000644000000000000000000000377415010704253025242 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " Hot Potatoes!!! "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "text" string => "Hot Potatoes!!!"; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.text)"); } bundle edit_xml test_insert(str) { set_text: "$(str)" select_xpath => "/Potatoes/Potato[@name=\'OnePotato\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/build_xpath_003.cf0000644000000000000000000000374215010704253025703 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - example for building an XPath in a node in a non-empty file # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " cfe_alias"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "xpath" string => "/Server/Service/Engine/OneFish/TwoFish/RedFish/BlueFish/Host[ Alias = cfe_alias | @name=\"cfe_host\" ]"; files: "$(G.testfile).actual" create => "true", edit_xml => test_build("$(test.xpath)"); } bundle edit_xml test_build(str) { build_xpath: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/insert_host_example.cf0000644000000000000000000001103215010704253027061 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - example for inserting a host into a Tomcat configuration file # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " cfe_alias "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "host" string => " cfe_alias "; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.host)"); } bundle edit_xml test_insert(str) { insert_tree: "$(str)" select_xpath => "/Server/Service/Engine"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/delete_tree_002.cf0000644000000000000000000000504515010704253025656 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " cfe_alias "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "tree" string => " cfe_alias "; files: "$(G.testfile).actual" create => "true", edit_xml => test_delete("$(test.tree)"); } bundle edit_xml test_delete(str) { delete_tree: "$(str)" build_xpath => "/Server/Service/Engine/OneFish/TwoFish/RedFish/BlueFish", select_xpath => "/Server/Service/Engine"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/insert_tree_001.cf0000644000000000000000000000474615010704253025726 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "tree" string => " "; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.tree)"); } bundle edit_xml test_insert(str) { insert_tree: "$(str)" select_xpath => "/Potatoes/Potato[@name=\'OnePotato\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/insert_text_001.cf0000644000000000000000000000400215010704253025734 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " Hot Potatoes!!! "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "text" string => "Hot Potatoes!!!"; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.text)"); } bundle edit_xml test_insert(str) { insert_text: "$(str)" select_xpath => "/Potatoes/Potato[@name=\'OnePotato\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/CFE-3806.cf0000644000000000000000000000360215010704253024004 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "starting_xml" string => ' Public For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted. '; files: "$(G.testfile)-1.xml" content => "$(starting_xml)"; "$(G.testfile)-2.xml" content => "$(starting_xml)"; } bundle agent test { meta: "description" -> { "CFE-3806" } string => "Test that trailing newline on insert_tree promisers do not remove ending tag for select_xpath"; files: "$(G.testfile)-1.xml" edit_xml => insert_tree_with_trailing_newline("1.1.1.1", "tcp", "9443"); "$(G.testfile)-2.xml" edit_xml => insert_tree_without_trailing_newline("1.1.1.1", "tcp", "9443"); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_strcmp( readfile( "$(G.testfile)-1.xml"), readfile( "$(G.testfile)-2.xml"), $(this.promise_filename), "no" ); } bundle edit_xml insert_tree_with_trailing_newline(source, protocol, port) { build_xpath: "/zone"; insert_tree: ' ' select_xpath => "/zone"; } bundle edit_xml insert_tree_without_trailing_newline(source, protocol, port) { build_xpath: "/zone"; insert_tree: ' ' select_xpath => "/zone"; } cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/set_attribute_002.cf0000644000000000000000000000372215010704253026253 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "attribute_name" string => "type"; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.attribute_name)"); } bundle edit_xml test_insert(str) { set_attribute: "$(str)" build_xpath => "/Server/Service/Engine/OneFish/TwoFish/RedFish/BlueFish", select_xpath => "/Server/Service/Engine/OneFish", attribute_value => "clownfish"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/insert_tree_003.cf0000644000000000000000000000516615010704253025725 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - Inserting a tree into a non-empty file, using build_xpath body attribute # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " cfe_alias "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "content" string => " cfe_alias "; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.content)"); } bundle edit_xml test_insert(str) { insert_tree: "$(str)" build_xpath => "/Server/Service/Engine/OneFish/TwoFish/RedFish/BlueFish", select_xpath => "/Server/Service/Engine"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/set_attribute_001.cf0000644000000000000000000000407315010704253026252 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "attribute_name" string => "topping"; files: "$(G.testfile).actual" create => "true", edit_xml => test_insert("$(test.attribute_name)"); } bundle edit_xml test_insert(str) { set_attribute: "$(str)" select_xpath => "/Potatoes/Potato[@name=\'OnePotato\']", attribute_value => "brocolli"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/delete_attribute_002.cf0000644000000000000000000000371215010704253026721 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " Nemo"; "expected" string => " Nemo"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "attribute_name" string => "type"; files: "$(G.testfile).actual" create => "true", edit_xml => test_delete("$(test.attribute_name)"); } bundle edit_xml test_delete(str) { delete_attribute: "$(str)" build_xpath => "/Server/Service/Engine/OneFish/TwoFish/RedFish/BlueFish", select_xpath => "/Server/Service/Engine/OneFish"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/build_xpath_002.cf0000644000000000000000000000356315010704253025703 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - example for building an XPath in a node in a non-empty file # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " cfe_alias"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "xpath" string => "/Server/Service/Engine/Host[ Alias = cfe_alias | @name=\"cfe_host\" ]"; files: "$(G.testfile).actual" create => "true", edit_xml => test_build("$(test.xpath)"); } bundle edit_xml test_build(str) { build_xpath: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/set_attribute_003.cf0000644000000000000000000000417415010704253026256 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - test changing an existing attribute of a node # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "attribute_name" string => "topping"; files: "$(G.testfile).actual" create => "true", edit_xml => test_set("$(test.attribute_name)"); } bundle edit_xml test_set(str) { set_attribute: "$(str)" select_xpath => "/Potatoes/Potato[@name=\'OnePotato\']", attribute_value => "sourcream"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/build_xpath_001.cf0000644000000000000000000000351515010704253025677 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - example for building an XPath in an empty file # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "expected" string => " cfe_alias"; files: "$(G.testfile).actual" create => "true", edit_defaults => init_empty; "$(G.testfile).expected" create => "true", edit_line => init_insert("$(init.expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "xpath" string => "/Server/Service/Engine/Host[ @name=\"cfe_host\" | Alias = cfe_alias ]"; files: "$(G.testfile).actual" create => "true", edit_xml => test_build("$(test.xpath)"); } bundle edit_xml test_build(str) { build_xpath: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/staging/0000755000000000000000000000000015010704253024132 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/staging/insert_tree_004.cf0000644000000000000000000000516215010704253027356 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - Inserting a tree into an initially empty file, using build_xpath body attribute # Note that selext_xpath must still be specified, as file will no longer be empty after build_xpath is verified. # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "expected" string => " cfe_alias "; files: "$(G.testfile).actual" create => "true", edit_defaults => init_empty; "$(G.testfile).expected" create => "true", edit_line => init_insert("$(init.expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "content" string => " cfe_alias "; files: "$(G.testfile).actual" create => "true", edit_xml => test_create("$(test.content)"); } bundle edit_xml test_create(str) { insert_tree: "$(str)" build_xpath => "/Server/Service/Engine/OneFish/TwoFish/RedFish/BlueFish", select_xpath => "/Server/Service/Engine"; } ####################################################### bundle agent check { methods: "any" usebundle => check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/staging/insert_tree_002.cf0000644000000000000000000000435115010704253027353 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml - Inserting a tree into an empty file # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "expected" string => " cfe_alias "; files: "$(G.testfile).actual" create => "true", edit_defaults => init_empty; "$(G.testfile).expected" create => "true", edit_line => init_insert("$(init.expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "content" string => " cfe_alias "; files: "$(G.testfile).actual" create => "true", edit_xml => test_create("$(test.content)"); } bundle edit_xml test_create(str) { insert_tree: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/delete_attribute_001.cf0000644000000000000000000000405715010704253026723 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "attribute_name" string => "topping"; files: "$(G.testfile).actual" create => "true", edit_xml => test_delete_attribute("$(test.attribute_name)"); } bundle edit_xml test_delete_attribute(str) { delete_attribute: "$(str)" select_xpath => "/Potatoes/Potato[@topping=\'brocolli\']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/11_xml_edits/delete_tree_001.cf0000644000000000000000000000474315010704253025661 0ustar00rootroot00000000000000###################################################################### # # File editing edit_xml # ###################################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => " "; "expected" string => " "; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10215" }; vars: "tree" string => " "; files: "$(G.testfile).actual" create => "true", edit_xml => test_delete("$(test.tree)"); } bundle edit_xml test_delete(str) { delete_tree: "$(str)" select_xpath => "/Potatoes/Potato[@name='OnePotato']"; } ####################################################### bundle agent check { methods: "any" usebundle => xml_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)", "no"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/03_transform/0000755000000000000000000000000015010704253022522 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/03_transform/001.cf0000644000000000000000000000335115010704253023336 0ustar00rootroot00000000000000####################################################### # # Ensure that the transformer runs for every file in a recursive tree # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: any:: "files" slist => { "1", "2", "3" }; files: "$(G.testdir)/." create => "true"; "$(G.testdir)/$(files)" copy_from => init_copy("$(G.etc_group)"); } body copy_from init_copy(file) { source => "$(file)"; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testdir)" transformer => "$(G.gzip) $(this.promiser)", file_select => test_plain, depth_search => test_recurse; } body file_select test_plain { file_types => { "plain" }; file_result => "file_types"; } body depth_search test_recurse { depth => "inf"; } ####################################################### bundle agent check { vars: "files" slist => { @{init.files} }; classes: "ok$(files)" expression => fileexists("$(G.testdir)/$(files).gz"); "ok" and => { "ok1", "ok2", "ok3" }; reports: DEBUG:: "$(G.testdir)/$(files).gz exists as expected" if => "ok$(files)"; "$(G.testdir)/$(files).gz was not created!" if => "!ok$(files)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/03_transform/003.cf0000644000000000000000000000415215010704253023340 0ustar00rootroot00000000000000####################################################### # # Ensure that the transformer runs only once for every file in a recursive tree # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "off"; # for execresult in check bundle } ####################################################### bundle agent init { vars: "files" slist => { "1", "2", "3" }; files: "$(G.testdir)/files/." create => "true"; "$(G.testdir)/files/$(files)" copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { vars: "counter" string => "$(G.testdir)/counter"; files: windows:: "$(G.testdir)/files" transformer => "$(G.echo) $(this.promiser) >> $(counter)", file_select => test_plain, depth_search => test_recurse; !windows:: "$(G.testdir)/files" transformer => "/bin/sh -c 'echo $(this.promiser) >> $(counter)'", file_select => test_plain, depth_search => test_recurse; } body file_select test_plain { file_types => { "plain" }; file_result => "file_types"; } body depth_search test_recurse { depth => "inf"; } ####################################################### bundle agent check { vars: "count" string => execresult("$(G.wc) -l $(test.counter)", "noshell"); DEBUG:: "list" string => execresult("$(G.ls) -1 $(G.testdir)/files", "noshell"); classes: "ok" expression => regcmp("^\s*3\s.*", "$(count)"); reports: DEBUG.!ok:: "3 transformations expected, saw (wc): '$(count)'"; "3 copies of $(G.etc_group) expected, saw (ls): '$(list)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/03_transform/002.cf0000644000000000000000000000432215010704253023336 0ustar00rootroot00000000000000####################################################### # # Ensure that the transformer does not run when --dry-run is used # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: any:: "files" slist => { "1", "2", "3" }; files: "$(G.testdir)/." create => "true"; "$(G.testdir)/$(files)" copy_from => init_copy("$(G.etc_group)"); } body copy_from init_copy(file) { source => "$(file)"; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { commands: "$(sys.cf_agent) -f $(this.promise_filename) -D AUTO -K -b init,test_dry_run --dry-run" contain => start_from_cwd; } body contain start_from_cwd { chdir => "$(G.cwd)"; } bundle agent test_dry_run { files: "$(G.testdir)" transformer => "$(G.gzip) $(this.promiser)", file_select => test_plain, depth_search => test_recurse; reports: !opt_dry_run:: "$(this.promise_filename) --dry-run FAIL"; } body file_select test_plain { file_types => { "plain" }; file_result => "file_types"; } body depth_search test_recurse { depth => "inf"; } ####################################################### bundle agent check { vars: "files" slist => { @{init.files} }; classes: "ok$(files)" expression => fileexists("$(G.testdir)/$(files)"); "no$(files)" expression => fileexists("$(G.testdir)/$(files).gz"); "ok" and => { "ok1", "ok2", "ok3", "!no1", "!no2", "!no3", }; reports: DEBUG:: "$(G.testdir)/$(files) exists with no $(G.testdir)/$(files).gz" if => "ok$(files).!no$(files)"; "$(G.testdir)/$(files).gz was created during --dry-run!" if => "no$(files)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_warn_only.cf.mustache0000644000000000000000000000002215010704253030132 0ustar00rootroot00000000000000SHOULD NOT RENDER cfengine-3.24.2/tests/acceptance/10_files/file_select_attrs_consistent_behavior/0000755000000000000000000000000015010704253030030 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/file_select_attrs_consistent_behavior/rules.json0000644000000000000000000000031215010704253032051 0ustar00rootroot00000000000000[ { "location": "/tmp/logs/tidy" "context": "any", "action": "TIDY", "frequency": "10", "type": "plain", "filter": ".*.log", "retention": "2", "depth": "2", "size": "ANY", "reason": "Tidy all logs" } ] cfengine-3.24.2/tests/acceptance/10_files/file_select_attrs_consistent_behavior/main.cf0000644000000000000000000002013215010704253031264 0ustar00rootroot00000000000000####################################################### # # Redmine#6584: file_select mtime consistency # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "datafile" string => "$(this.promise_dirname)/rules.json"; } bundle agent init { vars: "files" slist => { "file1.log", "file2.log", "file3.log" }, comment => "These are the files we will try to delete"; "tests" slist => { "test_delete_with_spec_from_data", "test_delete_with_spec_from_policy", }, comment => "We have two tests combined here because they should be kept in sync."; "data" data => readjson($(g.datafile), 1M); "idx" slist => getindices("data"); files: "$(G.testdir)/$(tests)/$(data[$(idx)][location])/." create => "true", comment => "Make sure our directories exist so that files can be created"; "$(G.testdir)/$(tests)/$(data[$(idx)][location])/$(files)" create => "true", comment => "Make sure the files exist so they can be deleted"; commands: "$(G.touch)" args => "-a -m -t 200901181205.09 $(G.testdir)/$(tests)/$(data[$(idx)][location])/$(files)", comment => "Make sure the files are 'old' so they will be selected for deletion"; } bundle agent test { meta: "test_soft_fail" string => "any", meta => { "redmine#6584", "zendesk#1466" }; methods: "Test delete with spec from policy" usebundle => test_delete_with_spec_from_policy; "Test delete with spec from data" usebundle => test_delete_with_spec_from_data($(g.datafile)); } bundle agent test_delete_with_spec_from_policy { files: # This promise should be an effictive mirror of the promise with handle 'test_delete_with_spec_from_data' "$(G.testdir)/$(this.bundle)/tmp/logs/tidy" delete => tidy, file_select => select_file_with_extension_retention_mtime(".*.log", # == 'filter' key in JSON "plain", # == 'type' key in JSON "2", # == 'retention' key in JSON "$(G.testdir)/$(this.bundle)/tmp/logs/tidy"), # == 'location' key in JSON depth_search => recurse("2"), # == 'depth' key in JSON action => if_elapsed_inform("10"), # == 'frequency' key in JSON if => "any"; # == 'context' key in JSON reports: DEBUG:: "'$(G.testdir)/$(this.bundle)/tmp/logs/tidy'"; } bundle agent test_delete_with_spec_from_data(ref) { vars: "input_cleanup" comment => "Read json file into container", data => readjson("${ref}", 1024); "i" comment => "Get index of json for iteration", slist => getindices("input_cleanup"); methods: "do_cleanup" usebundle => do_cleanup("${input_cleanup[${i}][location]}", "${input_cleanup[${i}][context]}", "${input_cleanup[${i}][action]}", "${input_cleanup[${i}][frequency]}", "${input_cleanup[${i}][type]}", "${input_cleanup[${i}][filter]}", "${input_cleanup[${i}][retention]}", "${input_cleanup[${i}][depth]}", "${input_cleanup[${i}][size]}", "${input_cleanup[${i}][reason]}"); reports: DEBUG:: " # Spec from json data file '$(ref)'# location => ${input_cleanup[${i}][location]} context => ${input_cleanup[${i}][context]} action => ${input_cleanup[${i}][action]} frequency => ${input_cleanup[${i}][frequency]} type => ${input_cleanup[${i}][type]} filter => ${input_cleanup[${i}][filter]} retention => ${input_cleanup[${i}][retention]} depth => ${input_cleanup[${i}][depth]} size => ${input_cleanup[${i}][size]} reason => ${input_cleanup[${i}][reason]} "; } bundle agent do_cleanup(location, context, action, frequency, type, filter, retention, depth, size, reason) { classes: #"action_tidy" expression => strcmp("$(action)", "TIDY"); #"action_rotate" expression => strcmp("$(action)", "ROTATE"); #"requested_size" expression => regcmp("[0-9]*", "$(size)"); files: #action_tidy:: "$(G.testdir)/test_delete_with_spec_from_data/$(location)" handle => "test_delete_with_spec_from_data", delete => tidy, file_select => select_file_with_extension_retention_mtime("$(filter)", "$(type)", "$(retention)", "$(G.testdir)/test_delete_with_spec_from_data/$(location)"), depth_search => recurse("$(depth)"), action => if_elapsed_inform("$(frequency)"), if => "$(context)"; reports: DEBUG:: "Filter=$(filter) Type=$(type) Retension=$(retention) Location=$(G.testdir)/test_delete_with_spec_from_data/$(location).* Depth=$(depth) Freq=$(frequency) Context=$(context)"; } bundle agent check { vars: "files[test_delete_with_spec_from_data]" slist => lsdir("$(G.testdir)/test_delete_with_spec_from_data/tmp/logs/tidy", ".*.log", "false"); "files[test_delete_with_spec_from_policy]" slist => lsdir("$(G.testdir)/test_delete_with_spec_from_policy/tmp/logs/tidy", ".*.log", "false"); "count_files[test_delete_with_spec_from_data]" int => length("files[test_delete_with_spec_from_data]") ; "count_files[test_delete_with_spec_from_policy]" int => length("files[test_delete_with_spec_from_policy]"); "files_in_tidy_dir_count_$(init.tests)" int => length("files_in_tidy_dir[$(init.tests)]"); "OK_tests" slist => maplist("OK_$(this)", @(init.tests)); classes: "OK_$(init.tests)" not => isgreaterthan("$(count_files[$(init.tests)])", 0), comment => "Define a class for each test that has an empty directory as desired"; "OK" and => { @(OK_tests) }, comment => "Pass if all tests are OK"; reports: DEBUG:: "files[test_delete_with_spec_from_data] = $(files[test_delete_with_spec_from_data])"; "files[test_delete_with_spec_from_policy] = $(files[test_delete_with_spec_from_policy])"; "count_files[test_delete_with_spec_from_data] = $(count_files[test_delete_with_spec_from_data])"; "count_files[test_delete_with_spec_from_policy] = $(count_files[test_delete_with_spec_from_policy])"; "$(init.tests) pass" if => "OK_$(init.tests)"; "$(init.tests) fail" if => "!OK_$(init.tests)"; OK:: "$(this.promise_filename) Pass"; !OK:: "$(this.promise_filename) FAIL"; } body file_select select_file_with_extension_retention_mtime(filter, type, days_old, location) { mtime => irange(0, ago(0, 0, $(days_old), 0, 0, 0)); path_name => { "$(location)/.*" }; leaf_name => { "$(filter)" }; file_types => { "$(type)" }; # The intention is to select files older than x days (mtime between now and x days ago should be retained) I believe the second file_result is correct. # file_result => "mtime.path_name.leaf_name.file_types"; # Oddly this works for test_delete_with_spec_from_policy, but not with test_delete_with_spec_from_data file_result => "!mtime.path_name.leaf_name.file_types"; # Oddly this works for test_delete_with_spec_from_data, but not with test_delete_with_spec_from_policy } body action if_elapsed_inform(x) { report_level => "inform"; ifelapsed => "$(x)"; expireafter => "$(x)"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/0000755000000000000000000000000015010704253022306 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/02_maintain/001.cf0000644000000000000000000000335315010704253023124 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with default compare to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_group)"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/203.cf0000644000000000000000000000555215010704253023133 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size, owner, group (different ordering of groups) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: any:: "mode" int => "01751"; linux:: "owner" string => "sys"; "group" string => "sys"; freebsd:: "owner" string => "bin"; "group" string => "sys"; !(linux|freebsd):: "owner" string => "undefined-please-fix"; "group" string => "undefined-please-fix"; pass2.!windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms("$(init.mode)", "$(init.owner)", "$(init.group)"); } body perms test_perms(m, o, g) { mode => "$(m)"; owners => { "root", "$(o)" }; linux:: groups => { "root", "$(g)" }; freebsd:: groups => { "wheel", "$(g)" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "ok" expression => strcmp("$(init.result)", "$(result)"); "not_ok" not => regcmp("$(init.result[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(init.result[$(fields)])'"; "got: $(fields) = '$(check.result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/019.cf0000644000000000000000000000262715010704253023140 0ustar00rootroot00000000000000####################################################### # # Test that disable_mode => "333" in body rename works (Issue 688) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testfile)" rename => disable_file; } body rename disable_file { disable_mode => "333"; disable => "true"; } ####################################################### bundle agent check { vars: "expect[permoct]" string => "333"; "expect[nlink]" string => "1"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile).cfdisabled", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/touch.cf0000644000000000000000000000230315010704253023740 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for touch # Redmine 3172 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" create => "true"; } bundle agent test { files: "$(G.testfile)" touch => "true", action => warn_only, classes => if_repaired("wrong_class_set"); "$(G.testfile)_not_there" touch => "true", action => warn_only; "$(G.testfile)_there" touch => "true"; } bundle agent check { vars: "wrong_classes" slist => classesmatching("wrong_.*"); classes: "wrong_file_there" expression => fileexists("$(G.testfile)_not_there"); "right_file_there" expression => fileexists("$(G.testfile)_there"); "ok" and => { "right_file_there", "!wrong_file_there", "!wrong_class_set" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG.!ok:: "Unwanted class: $(wrong_classes)"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/016.cf0000644000000000000000000000272315010704253023132 0ustar00rootroot00000000000000####################################################### # # Test that timestamped copying adds .cfsaved suffix (Issue 666) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testdir)/afile" create => "true"; # We can't use files promise here as it will remember we have created the file # and will not generate backup file which we are trying to get. commands: "$(G.echo) LimpBizkit > $(G.testdir)/destfile" contain => shell; } body contain shell { useshell => "true"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; files: "$(G.testdir)/destfile" copy_from => cp_2_file("$(G.testdir)/afile"); } body copy_from cp_2_file(x) { source => "$(x)"; copy_backup => "timestamp"; compare => "digest"; } ####################################################### bundle agent check { files: "$(G.testdir)/destfile.*\.cfsaved" touch => "true", classes => if_repaired("ok"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/check_file_changes_log.cf.sub0000644000000000000000000000341215010704253030015 0ustar00rootroot00000000000000# Checks whether the given content matches the content in # /var/cfengine/state/file_changes.log, but removes "unstable" # fields first (timestamp, promise ID, absolute path). # # The checks argument is a comma separated list of the following # options to check. # # - check_mtime # - sorted # # If the "check_*" flags are not given, those fields are filtered out # before comparing, since they are typically unstable. # # The "sorted" flag is to sort the log before comparing. This is # necessary for tests that depend on file system order, but the test # won't be as accurate. body file control { inputs => { "../../plucked.cf.sub" }; } bundle agent check_file_changes_log(file, pass_class, fail_class, checks) { vars: "classes_to_define" slist => splitstring($(checks), ",", 10); classes: "$(classes_to_define)" expression => "any"; "actual_exists" expression => fileexists("$(file).actual"); files: !actual_exists:: "$(file).actual" copy_from => local_cp("$(sys.workdir)/state/file_changes.log"); any:: "$(file).actual" edit_line => remove_unstable_fields($(file)); methods: sorted:: "any" usebundle => dcs_sort("$(file).actual", "$(file).actual.sort"); "any" usebundle => dcs_if_diff("$(file).actual.sort", "$(file)", "$(pass_class)", "$(fail_class)"); !sorted:: "any" usebundle => dcs_if_diff("$(file).actual", "$(file)", "$(pass_class)", "$(fail_class)"); } bundle edit_line remove_unstable_fields(file) { replace_patterns: # Get rid of timestamp, promise ID and absolute path. "^[0-9]+,[^,]*,[^,]+/" replace_with => value(""); delete_lines: !check_mtime:: ".*,S,Modified time:.*"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/413.cf.sub0000644000000000000000000000155215010704253023722 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 1 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "test" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => append_nonsense, edit_defaults => rotate; } body edit_defaults rotate { edit_backup => "rotate"; rotate => "4"; max_file_size => "300000"; } bundle edit_line append_nonsense { vars: useless0:: "contents" string => "0"; useless1:: "contents" string => "1"; useless2:: "contents" string => "2"; useless3:: "contents" string => "3"; useless4:: "contents" string => "4"; insert_lines: any:: "$(contents)"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/406.x.cf0000644000000000000000000000260415010704253023401 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(g.repofile).*" delete => init_delete; "$(G.testfile).*" delete => init_delete; "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" repository => "non-absolute-path", # Intentionally wrong move_obstructions => "true", copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_motd)"; compare => "digest"; } ####################################################### bundle agent check { classes: "test" not => fileexists("$(G.testfile).cfsaved"); "repo" expression => fileexists("$(g.repofile).cfsaved"); "ok" and => { "test", "repo" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/changes_promise_status.cf0000644000000000000000000000531715010704253027377 0ustar00rootroot00000000000000# Test that monitoring file status gives the right promise status body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { files: "$(G.testdir)/existingfile" create => "true", changes => test_changes; } bundle agent test { files: "$(G.testdir)/nosuchfile" changes => test_changes, classes => kept_repaired_notkept("nosuchfile_kept", "nosuchfile_repaired", "nosuchfile_notkept"); "$(G.testdir)/newfile" create => "true", changes => test_changes, classes => kept_repaired_notkept("newfile_kept", "newfile_repaired", "newfile_notkept"); "$(G.testdir)/existingfile" changes => test_changes, classes => kept_repaired_notkept("existingfile_kept", "existingfile_repaired", "existingfile_notkept"); } body changes test_changes { hash => "sha256"; report_changes => "all"; update_hashes => "yes"; } body classes kept_repaired_notkept(kept, repaired, notkept) { promise_kept => { "$(kept)" }; promise_repaired => { "$(repaired)" }; repair_failed => { "$(notkept)" }; repair_denied => { "$(notkept)" }; repair_timeout => { "$(notkept)" }; } bundle agent check { classes: "ok" and => { "!nosuchfile_kept", "!nosuchfile_repaired", "nosuchfile_notkept", # Kept state can be either set or unset depending on number of passes. # Let's not depend on either. #"!newfile_kept", "newfile_repaired", "!newfile_notkept", "existingfile_kept", "!existingfile_repaired", "!existingfile_notkept", }; reports: DEBUG.nosuchfile_kept:: "nosuchfile_kept is set, but shouldn't be."; DEBUG.nosuchfile_repaired:: "nosuchfile_repaired is set, but shouldn't be."; DEBUG.!nosuchfile_notkept:: "nosuchfile_notkept is not set, but should be."; DEBUG.newfile_kept:: "newfile_kept is set, but shouldn't be. (tolerated, for now)"; DEBUG.!newfile_repaired:: "newfile_repaired is not set, but should be."; DEBUG.newfile_notkept:: "newfile_notkept is set, but shouldn't be."; DEBUG.!existingfile_kept:: "existingfile_kept is not set, but should be."; DEBUG.existingfile_repaired:: "existingfile_repaired is set, but shouldn't be."; DEBUG.existingfile_notkept:: "existingfile_notkept is set, but shouldn't be."; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/104.cf0000644000000000000000000000345315010704253023131 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous relative symbolic link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "relative"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: "expect[permoct]" string => "$(test.mode)"; "expect[nlink]" string => "1"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/008.cf0000644000000000000000000000340615010704253023132 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with exists compare to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_group)"; compare => "exists"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/absolute_link_and_move_obstructions.cf0000644000000000000000000000371115010704253032143 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous link with absolute and move_obstructions # to succeed # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "inode" string => filestat("$(G.etc_group)", "ino"); files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "absolute"; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); "Lresult" string => filestat("$(G.testfile)", "ino"); # This tells us where the link points "link_target" string => filestat("$(G.testfile)", "linktarget"); classes: "okL" not => strcmp("$(test.inode)", "$(Lresult)"); "ok" and => { "okL", strcmp("$(test.inode)", "$(result)"), # Might be slightly different from link_target because of redundant '../../'. regcmp("/.*/group", "$(link_target)") }; reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(Lresult)' => '$(result)'"; "got this too: '$(G.etc_group)' => '$(link_target)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/102.cf0000644000000000000000000000337315010704253023130 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous hard link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "hardlink"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/copy_linkpattern_from_contains_dots.cf0000644000000000000000000000471215010704253032163 0ustar00rootroot00000000000000####################################################### # # Test copylink_pattern can handle source symlink that contains '/../' # CFE-2960 ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testdir)/linkdir/" comment => "Create a directory."; "$(G.testdir)/linkdir/another/" comment => "Create another directory."; "$(G.testdir)/linkdir/another/target" comment => "A target file.", create => "true"; "$(G.testdir)/linkdir/link" comment => "Create a relative link to the target.", link_from => ln_s("$(G.testdir)/linkdir/another/target"); } ####################################################### bundle agent test { meta: "description" string => "Test copylink_pattern can handle source symlink that contains'/../'", meta => { "CFE-2960" }; vars: "mode" int => "0600"; "from" string => "$(G.testdir)/linkdir/../linkdir/link"; files: "$(G.testdir)/copy_file" comment => "Copy the file behind the link.", perms => test_perms($(mode)), copy_from => cp_2_file("$(from)"); } body link_from ln_s(x) { link_type => "relative"; source => "$(x)"; when_no_source => "nop"; } body copy_from cp_2_file(x) { source => "$(x)"; compare => "binary"; copy_backup => "false"; copylink_patterns => { ".*" }; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "\d+$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)$(const.dirsep)copy_file", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/010.cf0000644000000000000000000000341115010704253023117 0ustar00rootroot00000000000000####################################################### # # Test that symlinks are set aside while copying trees of directories (Issue 569) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testdir)/srcdir/foo" create => "true"; "$(G.testdir)/realdestdir/" create => "true"; "$(G.testdir)/destdir" comment => "Create a relative link to the target.", link_from => ln_s("$(G.testdir)/realdestdir"); } body link_from ln_s(x) { link_type => "relative"; source => "$(x)"; when_no_source => "nop"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testdir)/destdir/" copy_from => test_sync_cp("$(G.testdir)/srcdir"), depth_search => recurse("inf"), move_obstructions => "true", action => if_elapsed(0); } body copy_from test_sync_cp(from) { source => "$(from)"; purge => "true"; preserve => "true"; type_check => "true"; } ####################################################### bundle agent check { vars: "expect" string => "directory"; "result" string => filestat("$(G.testdir)/destdir", "type"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/copy_from_depth_search.cf0000644000000000000000000000345315010704253027333 0ustar00rootroot00000000000000####################################################### # # Copy a directory structure, mixing create and depth_search # Redmine 6027 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "source_dirs" slist => { ".", "a.dir/.", "a.dir/b.dir/." }; "source_files" slist => { "a.file", "a.dir/b.file" }; files: "$(G.testdir)_source/$(source_dirs)" create => "true"; "$(G.testdir)_source/$(source_files)" create => "true"; } bundle agent test { files: "$(G.testdir)_destination" create => "true", copy_from => local_cp("$(G.testdir)_source"), depth_search => recurse("inf"); "$(G.testdir)_destination_dir/." create => "true", copy_from => local_cp("$(G.testdir)_source"), depth_search => recurse("inf"); } bundle agent check { # test that selected destination file system entries exist with the correct type classes: "files_ok" and => { strcmp(filestat("$(G.testdir)_destination/a.dir/b.file", "type"), "regular file"), strcmp(filestat("$(G.testdir)_destination_dir/a.dir/b.file", "type"), "regular file") }; "dirs_ok" and => { strcmp(filestat("$(G.testdir)_destination", "type"), "directory"), strcmp(filestat("$(G.testdir)_destination/a.dir/b.dir", "type"), "directory"), strcmp(filestat("$(G.testdir)_destination_dir/a.dir/b.dir", "type"), "directory") }; "ok" and => { "files_ok", "dirs_ok" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/changes_depth_search.cf.sub0000644000000000000000000000645215010704253027540 0ustar00rootroot00000000000000body common control { inputs => { "../../dcs.cf.sub", "../../plucked.cf.sub", }; bundlesequence => { "init", "test" }; } bundle agent init { files: "$(G.testdir)" depth_search => recurse("inf"), file_select => all, delete => tidy; methods: "any" usebundle => setup_files; "any" usebundle => init_monitoring; } bundle agent setup_files { methods: "any" usebundle => file_make("$(G.testdir)/file.same", "same"); "any" usebundle => file_make("$(G.testdir)/file.removed", "removed"); #"any" usebundle => file_make("$(G.testdir)/file.created", "created"); "any" usebundle => file_make("$(G.testdir)/file.content", "old content"); "any" usebundle => file_make("$(G.testdir)/file.always-ignored.same", "same"); "any" usebundle => file_make("$(G.testdir)/file.always-ignored.removed", "removed"); #"any" usebundle => file_make("$(G.testdir)/file.always-ignored.created", "created"); "any" usebundle => file_make("$(G.testdir)/file.always-ignored.content", "old content"); "any" usebundle => file_make("$(G.testdir)/file.new-ignored.same", "same"); "any" usebundle => file_make("$(G.testdir)/file.new-ignored.removed", "removed"); #"any" usebundle => file_make("$(G.testdir)/file.new-ignored.created", "created"); "any" usebundle => file_make("$(G.testdir)/file.new-ignored.content", "old content"); "any" usebundle => file_make("$(G.testdir)/subdir/subfile.same", "same"); #"any" usebundle => file_make("$(G.testdir)/subdir/subfile.created", "subfile created"); "any" usebundle => file_make("$(G.testdir)/subdir/subfile.removed", "subfile removed"); "any" usebundle => file_make("$(G.testdir)/subdir/subfile.content", "subfile old content"); } bundle agent init_monitoring { files: "$(G.testdir)" depth_search => recurse("inf"), file_select => init_select, changes => changes_body; } body file_select init_select { leaf_name => { ".*always-ignored.*" }; file_result => "!leaf_name"; } body changes changes_body { report_changes => "all"; update_hashes => "true"; } bundle agent test { vars: "remove" slist => { "file.removed", "file.always-ignored.removed", "file.new-ignored.removed", "subdir/subfile.removed", }; "create" slist => { "file.created", "file.always-ignored.created", "file.new-ignored.created", "subdir/subfile.created", }; "modify" slist => { "file.content", "file.always-ignored.content", "file.new-ignored.content", "subdir/subfile.content", }; files: "$(G.testdir)/$(remove)" delete => tidy; "$(G.testdir)/$(create)" create => "true"; "$(G.testdir)/$(modify)" edit_line => insert_lines("extra content"); files: "$(G.testdir)" depth_search => recurse("inf"), file_select => test_select, changes => changes_body; } body file_select test_select { leaf_name => { ".*ignored.*" }; file_result => "!leaf_name"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/101.cf0000644000000000000000000000333715010704253023127 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous default link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/111.x.cf0000644000000000000000000000312715010704253023373 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous none no-filename link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", link_from => test_link; } body link_from test_link { link_type => "none"; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/017.cf0000644000000000000000000000163615010704253023135 0ustar00rootroot00000000000000####################################################### # # Test that copy_from body with source does not crash (Issue 687) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { files: "$(G.testdir)/." create => "true", move_obstructions => "true", copy_from => update_nobackup; } body copy_from update_nobackup() { copy_backup => "false"; } ####################################################### bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/changes_depth_search_last_file.cf.sub0000644000000000000000000000107415010704253031555 0ustar00rootroot00000000000000body common control { inputs => { "../../dcs.cf.sub", "../../plucked.cf.sub", }; bundlesequence => { "init", "test" }; } bundle agent init { methods: pass1|pass3:: "any" usebundle => file_make("$(G.testdir)/file", "content"); files: pass2|pass4:: "$(G.testdir)/file" delete => tidy; } body changes changes_body { report_changes => "all"; update_hashes => "true"; } bundle agent test { files: "$(G.testdir)" depth_search => recurse("inf"), changes => changes_body; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/012.cf0000644000000000000000000000343015010704253023122 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testdir)/srcdir/" create => "true"; "$(G.testdir)/srcdir/intermediate/" create => "true"; "$(G.testdir)/srcdir/intermediate/intermediate2/" create => "true"; "$(G.testdir)/srcdir/intermediate/intermediate2/foo" create => "true"; "$(G.testdir)/realdestdir/" create => "true"; "$(G.testdir)/destdir" comment => "Create a relative link to the target.", link_from => ln_s("$(G.testdir)/realdestdir"); } body link_from ln_s(x) { link_type => "relative"; source => "$(x)"; when_no_source => "nop"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testdir)/destdir/intermediate/intermediate2/foo" copy_from => test_sync_cp("$(G.testdir)/srcdir/intermediate/intermediate2/foo"); } body copy_from test_sync_cp(from) { source => "$(from)"; } ####################################################### bundle agent check { vars: "expect" string => "symlink"; "result" string => filestat("$(G.testdir)/destdir", "type"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/copy-relative-link-existing.cf0000644000000000000000000000237215010704253030172 0ustar00rootroot00000000000000# Assume the following file-structure: # dest # link -> dest # link-currdir -> ./dest # # When verifying "link-currdir" is copy of "link", it is ok # to correct it (to be link-currdir -> dest), but after this, the promise must be kept. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { commands: "$(G.mkdir) -p $(G.testdir)"; "$(G.touch) $(G.testdir)/dest"; "$(G.ln) -s dest link" contain => in_dir("$(G.testdir)"); "$(G.ln) -s ./dest link-currdir" contain => in_dir("$(G.testdir)"); } bundle agent test { files: "$(G.testdir)/link-currdir" copy_from => local_cp("$(G.testdir)/link"), move_obstructions => "true"; "$(G.testdir)/link-currdir" copy_from => local_cp("$(G.testdir)/link"), classes => if_kept("copy_link_kept"); } bundle agent check { classes: "ok" or => { "copy_link_kept" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body contain in_dir(s) { chdir => "$(s)"; } body classes if_kept(x) { promise_kept => { "$(x)" }; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/011.cf0000644000000000000000000000324015010704253023120 0ustar00rootroot00000000000000####################################################### # # Test that symlinks outside of copying root are NOT set aside while copying trees of directorise (Issue 585) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testdir)/srcdir/" create => "true"; "$(G.testdir)/srcdir/foo" create => "true"; "$(G.testdir)/realdestdir/" create => "true"; "$(G.testdir)/destdir" comment => "Create a relative link to the target.", link_from => ln_s("$(G.testdir)/realdestdir"); } body link_from ln_s(x) { link_type => "relative"; source => "$(x)"; when_no_source => "nop"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testdir)/destdir/foo" copy_from => test_sync_cp("$(G.testdir)/srcdir/foo"); } body copy_from test_sync_cp(from) { source => "$(from)"; } ####################################################### bundle agent check { vars: "expect" string => "symlink"; "result" string => filestat("$(G.testdir)/destdir", "type"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/relative_link_and_no_move_obstructions.cf0000644000000000000000000000416415010704253032637 0ustar00rootroot00000000000000####################################################### # # Create an absolute link to a file, expect relative link promise to want # to change it to an relative link (but fail to) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => init_link; } body link_from init_link { source => "$(G.etc_group)"; link_type => "absolute"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "inode" string => filestat("$(G.etc_group)", "ino"); files: "$(G.testfile)" classes => init_if_failed("test_ok"), link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "relative"; } body classes init_if_failed(c) { repair_failed => { "$(c)" }; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); "Lresult" string => filestat("$(G.testfile)", "ino"); # This tells us where the link points "link_target" string => filestat("$(G.testfile)", "linktarget"); classes: "okL" not => strcmp("$(test.inode)", "$(Lresult)"); "ok" and => { "test_ok", "okL", strcmp("$(test.inode)", "$(result)"), # Might be slightly different from link_target because of redundant '../../'. regcmp("/.*/group", "$(link_target)") }; reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(Lresult)' => '$(result)'"; "got this too: '$(G.etc_group)' => '$(link_target)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/007.cf0000644000000000000000000000356415010704253023136 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with binary compare to succeed # but not change owner/group # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testdir)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" string => filestat("$(G.etc_group)", "modeoct"); files: "$(G.testfile)" create => "true", perms => test_og, copy_from => test_copy; } body perms test_og { owners => { "3" }; groups => { "3" }; } body copy_from test_copy { source => "$(G.etc_group)"; compare => "binary"; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "$(test.mode)"; "expect[uid]" string => "3"; "expect[gid]" string => "3"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testdir)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/classes_on_delete.cf0000644000000000000000000000430615010704253026276 0ustar00rootroot00000000000000####################################################### # # Redmine#6509: repairs from delete bodies should not be seen as kept # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/redmine_6509_1/." create => "true"; "$(G.testdir)/redmine_6509_2" delete => tidy; } bundle agent test { files: "$(G.testdir)/redmine_6509_1" classes => mygeneric("dir1_absent"), delete => tidy; "$(G.testdir)/redmine_6509_2" classes => mygeneric("dir2_absent"), delete => tidy; } bundle agent check { vars: "expected_ok" slist => { "dir1_absent_ok", "dir1_absent_repaired", "dir1_absent_reached", "dir2_absent_ok", "dir2_absent_kept", "dir2_absent_reached", }; "seen_fail" slist => { "dir1_absent_error", "dir1_absent_repair_failed", "dir1_absent_repair_denied", "dir1_absent_repair_timeout", "dir1_absent_kept", }; classes: "ok" and => { @(expected_ok) }; "fail" or => { @(seen_fail) }; reports: DEBUG.fail:: "Found $(expected_ok) defined as expected" if => "$(expected_ok)"; "Found $(seen_fail) which is not expected and causes the test to fail" if => "$(seen_fail)"; "Missing $(expected_ok) which is expected and not being defined causes the test to fail" if => "!$(expected_ok)"; !fail.ok:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; } body classes mygeneric(x) { promise_kept => { "$(x)_ok", "$(x)_kept", "$(x)_reached" }; promise_repaired => { "$(x)_ok", "$(x)_repaired", "$(x)_reached" }; repair_failed => { "$(x)_error", "$(x)_repair_failed", "$(x)_reached" }; repair_denied => { "$(x)_error", "$(x)_repair_denied", "$(x)_reached" }; repair_timeout => { "$(x)_error", "$(x)_repair_timeout", "$(x)_reached" }; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/105.cf0000644000000000000000000000355415010704253023134 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous absolute symbolic link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile).SOURCE" create => "true"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(test.mode)), link_from => test_link; } body link_from test_link { link_type => "absolute"; source => "$(G.testfile).SOURCE"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: "expect[permoct]" string => "$(test.mode)"; "expect[nlink]" string => "1"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/relative_link_and_move_obstructions.cf0000644000000000000000000000414715010704253032144 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous link with relative and move_obstructions # to succeed # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; "test_suppress_fail" string => "freebsd", meta => { "redmine5261" }; vars: "inode" string => filestat("$(G.etc_group)", "ino"); files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "relative"; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); "Lresult" string => filestat("$(G.testfile)", "ino"); # This tells us where the link points, but don't follow it "link_target" string => filestat("$(G.testfile)", "linktarget_shallow"); classes: "okL" not => strcmp("$(test.inode)", "$(Lresult)"); "okT" not => strcmp("$(link_target)", "$(G.etc_group)"); "ok" and => { "okL", "okT", strcmp("$(test.inode)", "$(result)"), # Test that the symlink target starts with dot regcmp("\..*", "$(link_target)") }; reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(Lresult)' => '$(result)'"; "got this too: '$(G.etc_group)' => '$(link_target)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/409.cf0000644000000000000000000000237615010704253023144 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename => disable (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_null)"; compare => "digest"; } ####################################################### bundle agent test { files: "$(G.testfile)" rename => disable, action => warn_only; } body rename disable { disable => "true"; } ####################################################### bundle agent check { classes: "filestillthere" expression => fileexists("$(G.testfile)"); "fileisnotdisabled" not => fileexists("$(G.testfile).cfdisabled"); "ok" and => { "filestillthere", "fileisnotdisabled" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/112.cf0000644000000000000000000000266015010704253023127 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous link with default and move_obstructions # to succeed # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "inode" string => filestat("$(G.etc_group)", "ino"); files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); classes: "ok" expression => strcmp("$(test.inode)", "$(result)"); reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/204.cf0000644000000000000000000000530315010704253023126 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size or change owner/group (different ordering of groups) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: any:: "mode" int => "01751"; linux:: "owner" string => "sys"; "group" string => "sys"; freebsd:: "owner" string => "bin"; "group" string => "sys"; !(linux|freebsd):: "owner" string => "undefined-please-fix"; "group" string => "undefined-please-fix"; pass2.!windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms("$(init.mode)"); } body perms test_perms(m) { mode => "$(m)"; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "ok" expression => strcmp("$(init.result)", "$(result)"); "not_ok" not => regcmp("$(init.result[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(init.result[$(fields)])'"; "got: $(fields) = '$(check.result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/113.cf0000644000000000000000000000275215010704253023132 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous link with hardlink and move_obstructions # to succeed # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile).SOURCE" create => "true"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => test_link; } body link_from test_link { source => "$(G.testfile).SOURCE"; link_type => "hardlink"; } ####################################################### bundle agent check { vars: "expect" string => filestat("$(G.testfile).SOURCE", "ino"); "result" string => filestat("$(G.testfile)", "ino"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/412.cf.sub0000644000000000000000000000132415010704253023716 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 1 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "test" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => append_nonsense, edit_defaults => rotate; } body edit_defaults rotate { edit_backup => "rotate"; rotate => "4"; max_file_size => "300000"; } bundle edit_line append_nonsense { vars: "ns" string => execresult("$(G.date) +%N", "noshell"); insert_lines: "$(ns)"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/413.cf0000644000000000000000000000246615010704253023137 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 1 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { commands: "$(G.touch) $(G.testfile)"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; commands: "$(cmd) -D useless0"; "$(cmd) -D useless1"; "$(cmd) -D useless2"; "$(cmd) -D useless3"; "$(cmd) -D useless4"; } ####################################################### bundle agent check { classes: "filestillthere" expression => fileexists("$(G.testfile)"); "fileisrotated" expression => fileexists("$(G.testfile).cf-before-edit.4"); "nooverflow" not => fileexists("$(G.testfile).cf-before-edit.5"); "ok" and => { "filestillthere", "fileisrotated", "nooverflow" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/fifos.cf0000644000000000000000000000130415010704253023724 0ustar00rootroot00000000000000# https://dev.cfengine.com/issues/7030 # body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "test_fifo" string => "$(G.testfile).fifo"; commands: "$(G.mkfifo) $(test_fifo)"; } bundle agent test { meta: "test_skip_unsupported" string => "!has_mkfifo|windows"; files: "$(init.test_fifo)" create => "false", perms => m("0700"); } bundle agent check { classes: "ok" expression => isexecutable("$(init.test_fifo)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/410.cf0000644000000000000000000000236215010704253023127 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 1 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_null)"; compare => "digest"; } ####################################################### bundle agent test { files: "$(G.testfile)" rename => rotate, action => warn_only; } body rename rotate { rotate => "1"; } ####################################################### bundle agent check { classes: "filestillthere" expression => fileexists("$(G.testfile)"); "fileisnotrotated" not => fileexists("$(G.testfile).1"); "ok" and => { "filestillthere", "fileisnotrotated" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/414.cf.sub0000644000000000000000000000127515010704253023725 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 1 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "test" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => append_nonsense, edit_defaults => rotate; } body edit_defaults rotate { edit_backup => "rotate"; max_file_size => "300000"; } bundle edit_line append_nonsense { vars: "ns" string => execresult("$(G.date) +%N", "noshell"); insert_lines: "$(ns)"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/changes_depth_search_last_file.cf0000644000000000000000000000263715010704253030773 0ustar00rootroot00000000000000# Checks whether a whole directory is monitored correctly with # a file changes promise even when all files are removed. body common control { inputs => { "../../dcs.cf.sub", "../../plucked.cf.sub", "check_file_changes_log.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => setup_files; } bundle agent setup_files { methods: "any" usebundle => file_make("$(G.testfile).expected", "file,N,New file found file,R,File removed file,N,New file found file,R,File removed"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10254" }; commands: "$(sys.cf_agent) -Dpass1 -Kf $(this.promise_filename).sub"; "$(sys.cf_agent) -Dpass2 -Kf $(this.promise_filename).sub"; "$(sys.cf_agent) -Dpass3 -Kf $(this.promise_filename).sub"; "$(sys.cf_agent) -Dpass4 -Kf $(this.promise_filename).sub"; } bundle agent check { methods: "any" usebundle => check_file_changes_log("$(G.testfile).expected", "test_changes_log_ok", "test_changes_log_fail", ""); classes: "ok" and => { "test_changes_log_ok", "!test_changes_log_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/103.cf0000644000000000000000000000344115010704253023125 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous symbolic link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "symlink"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: "expect[permoct]" string => "$(test.mode)"; "expect[nlink]" string => "1"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/003.cf0000644000000000000000000000340415010704253023123 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with ctime compare to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_group)"; compare => "ctime"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/perms_recurse.cf0000644000000000000000000000522015010704253025475 0ustar00rootroot00000000000000# https://dev.cfengine.com/issues/7808 # body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { meta: # Permissions test doesn't work with fakeroot. # It also doesn't work on non-Linux due to the use of GNU specific find # options. "test_skip_needs_work" string => "using_fakeroot|!linux"; vars: "directory" string => "$(G.testdir)"; "mode" string => "750"; "owner" string => "bin"; "group" string => "bin"; files: "$(directory)/." perms => mog("000", "root", "0"), create => "true"; "$(directory)/dir1/." perms => mog("000", "root", "0"), create => "true"; "$(directory)/dir2/." perms => mog("000", "root", "0"), create => "true"; } bundle agent test { files: "$(init.directory)" create => "false", perms => mog("${init.mode}", "${init.owner}", "${init.group}"), depth_search => recurse_with_base("inf"), file_select => dirs; } body file_select dirs # @brief Select directories { file_types => { "dir" }; file_result => "file_types"; } bundle agent check { vars: "permissions_test_mode" string => "/usr/bin/test \"`/usr/bin/find ${init.directory} -perm ${init.mode} | wc -l`\" = \"3\""; "permissions_test_owner" string => "/usr/bin/test \"`/usr/bin/find ${init.directory} -user ${init.owner} | wc -l`\" = \"3\""; "permissions_test_group" string => "/usr/bin/test \"`/usr/bin/find ${init.directory} -group ${init.group} | wc -l`\" = \"3\""; commands: "${permissions_test_mode}" contain => in_shell, classes => ok("permissions_test_mode_ok"); "${permissions_test_owner}" contain => in_shell, classes => ok("permissions_test_owner_ok"); "${permissions_test_group}" contain => in_shell, classes => ok("permissions_test_group_ok"); reports: DEBUG.!permissions_test_mode_ok:: "Didn't find 3 files with mode ${init.mode}"; DEBUG.!permissions_test_owner_ok:: "Didn't find 3 files with owner${init.owner}"; DEBUG.!permissions_test_group_ok:: "Didn't find 3 files with group ${init.group}"; permissions_test_mode_ok.permissions_test_owner_ok.permissions_test_group_ok:: "$(this.promise_filename) Pass"; !(permissions_test_mode_ok.permissions_test_owner_ok.permissions_test_group_ok):: "$(this.promise_filename) FAIL"; } body classes ok(classname) { promise_repaired => { "$(classname)" }; promise_kept => { "$(classname)" }; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/004.cf0000644000000000000000000000352715010704253023132 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with atime compare to succeed # but not change owner/group # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" string => filestat("$(G.etc_group)", "modeoct"); files: "$(G.testfile)" create => "true", perms => test_og, copy_from => test_copy; } body perms test_og { owners => { "3" }; groups => { "3" }; } body copy_from test_copy { preserve => "true"; source => "$(G.etc_group)"; compare => "atime"; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "$(test.mode)"; "expect[uid]" string => "3"; "expect[gid]" string => "3"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/005.cf0000644000000000000000000000343415010704253023130 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with hash compare to succeed # but not change owner/group # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" string => filestat("$(G.etc_group)", "modeoct"); files: "$(G.testfile)" create => "true", perms => test_og, copy_from => test_copy; } body perms test_og { owners => { "3" }; groups => { "3" }; } body copy_from test_copy { preserve => "true"; source => "$(G.etc_group)"; compare => "hash"; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "$(test.mode)"; "expect[uid]" string => "3"; "expect[gid]" string => "3"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/copy_from_translatepath.cf0000644000000000000000000000203315010704253027545 0ustar00rootroot00000000000000####################################################### # # Test that copying a file with double directory # separators work # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "regex" string => escape("$(const.dirsep)"); "orig_path" string => translatepath("$(this.promise_filename)"); "path_list" slist => splitstring("$(orig_path)", "$(regex)", 100); "path" string => join("$(const.dirsep)$(const.dirsep)", "path_list"); files: "$(G.testfile)" copy_from => copy_body("$(path)"); } body copy_from copy_body(file) { source => "$(file)"; } bundle agent check { reports: DEBUG:: "Tested pathname: '$(test.path)'"; methods: "check" usebundle => dcs_check_diff("$(this.promise_filename)", "$(G.testfile)", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/114.cf0000644000000000000000000000313015010704253023122 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous link with symlink and move_obstructions # to succeed # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "inode" string => filestat("$(G.etc_group)", "ino"); files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "symlink"; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); "Lresult" string => filestat("$(G.testfile)", "ino"); classes: "okL" not => strcmp("$(test.inode)", "$(Lresult)"); "ok" and => { "okL", strcmp("$(test.inode)", "$(result)") }; reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(Lresult)' => '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/201.cf0000644000000000000000000000445315010704253023130 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: any:: "mode" int => "01751"; pass2.!windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; } body perms init_perms(m) { mode => "$(m)"; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms("$(init.mode)"); } body perms test_perms(m) { mode => "$(m)"; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "ok" expression => strcmp("$(init.result)", "$(result)"); "not_ok" not => regcmp("$(init.result[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(init.result[$(fields)])'"; "got: $(fields) = '$(check.result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/015.cf0000644000000000000000000000167115010704253023132 0ustar00rootroot00000000000000####################################################### # # Test that we can supply relative filename to link_from # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { files: "$(G.testdir)/destdir" link_from => sync_cp("./srcdirrr"); } body link_from sync_cp(from) { source => "$(from)"; } ####################################################### bundle agent check { classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/line_truncation_at_4096_chars.cf0000644000000000000000000000451215010704253030345 0ustar00rootroot00000000000000####################################################### # # Check if the lines in a file get truncated after 4096 # chars during file editing. # # Ticket: https://cfengine.com/dev/issues/3882 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("${this.promise_filename}") }; version => "1.0"; cache_system_functions => "off"; } ####################################################### bundle agent init { vars: any:: "file_mode" int => "0644"; "char_number" int => "6144"; "line_to_add" string => "This is a nice short line."; files: "${G.testfile}" create => "true", perms => m("${file_mode}"); # Using system command instead of CFEngine itself to # prevent the bug to be here at file creation too. # It would create a false negative. commands: "${G.perl}" args => "-e 'print \"#\" x ${char_number}; print \"ENDMARK\n\"' > ${G.testfile}", contain => in_shell; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "${G.testfile}" create => "false", edit_line => insert_lines("${init.line_to_add}"); } ####################################################### bundle agent check { classes: !solaris:: # ok is defined if the file still contains ENDMARK, meaning the end of the sample very # long line did not get truncated during file editing "ok" expression => returnszero("${G.grep} ENDMARK ${G.testfile}", "noshell"); solaris:: # Bug in xpg4 version of Solaris. grep internally has a limit of 4096 chars per line, # which is the very thing we're testing. Use /bin/grep. "ok" expression => returnszero("/bin/grep ENDMARK ${G.testfile}", "noshell"); reports: DEBUG.!ok:: "${this.promise_filename} FAILed as the generated file got at least a line truncated to 4096 characters"; ok:: "${this.promise_filename} Pass"; !ok:: "${this.promise_filename} FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("${G.testfile}"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/412.cf0000644000000000000000000000234115010704253023126 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 1 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { commands: "$(G.touch) $(G.testfile)"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; commands: "$(cmd)"; "$(cmd) -D superfluous"; } ####################################################### bundle agent check { classes: "filestillthere" expression => fileexists("$(G.testfile)"); "fileisrotated" expression => fileexists("$(G.testfile).cf-before-edit.1"); "nounnamedbackup" not => fileexists("$(G.testfile).cf-before-edit"); "ok" and => { "filestillthere", "fileisrotated", "nounnamedbackup" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/006.cf0000644000000000000000000000353115010704253023127 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with digest compare to succeed # but not change owner/group # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" string => filestat("$(G.etc_group)", "modeoct"); files: "$(G.testfile)" create => "true", perms => test_og, copy_from => test_copy; } body perms test_og { owners => { "3" }; groups => { "3" }; } body copy_from test_copy { preserve => "true"; source => "$(G.etc_group)"; compare => "digest"; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "$(test.mode)"; "expect[uid]" string => "3"; "expect[gid]" string => "3"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/009.cf0000644000000000000000000000442315010704253023133 0ustar00rootroot00000000000000####################################################### # # Test that copying file by relative symlink works # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testdir)/linkdir/" comment => "Create a directory."; "$(G.testdir)/linkdir/another/" comment => "Create another directory."; "$(G.testdir)/linkdir/another/target" comment => "A target file.", create => "true"; "$(G.testdir)/linkdir/link" comment => "Create a relative link to the target.", link_from => ln_s("$(G.testdir)/linkdir/another/target"); } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testdir)/copy_file" comment => "Copy the file behind the link.", perms => test_perms($(mode)), copy_from => cp_2_file("$(G.testdir)/linkdir/link"); } body link_from ln_s(x) { link_type => "relative"; source => "$(x)"; when_no_source => "nop"; } body copy_from cp_2_file(x) { source => "$(x)"; compare => "binary"; copy_backup => "false"; copylink_patterns => { ".*" }; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "\d+$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)$(const.dirsep)copy_file", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/205.cf0000644000000000000000000000620415010704253023130 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size, but DOES change owner, group (symbolic IDs) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } ####################################################### bundle agent init { vars: freebsd|solaris:: "mode" int => "04751"; !freebsd.!solaris:: "mode" int => "01751"; linux:: "owner" string => "sys"; "group" string => "sys"; freebsd:: "owner" string => "bin"; "group" string => "sys"; !(linux|freebsd):: "owner" string => "undefined-please-fix"; "group" string => "undefined-please-fix"; pass2.(freebsd|solaris):: "expect[modeoct]" string => "104755"; pass2.!(freebsd|solaris|windows):: "expect[modeoct]" string => "101755"; pass2.!windows:: "expect[uid]" string => "0"; "expect[gid]" string => "0"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms("a+r"); } body perms test_perms(m) { mode => "$(m)"; owners => { "root" }; linux|hpux|solaris|qnx:: groups => { "root" }; freebsd|netbsd|openbsd|darwin|dragonfly:: groups => { "wheel" }; aix:: groups => { "system" }; cray:: groups => { "sys" }; # Still need unix_sv, sco, vmware } ####################################################### bundle agent check { vars: freebsd|solaris:: "expect[modeoct]" string => "104755"; !freebsd.!solaris.!windows:: "expect[modeoct]" string => "101755"; !windows:: "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "result: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/208.cf0000644000000000000000000000542015010704253023132 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size, group but DOES change owner, because # we start with a non-registered user/group name. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } ####################################################### bundle agent init { vars: freebsd|solaris:: "mode" int => "04751"; !freebsd.!solaris:: "mode" int => "01751"; any:: "owner" string => "786756"; "group" string => "786756"; pass2.!windows:: "expect[modeoct]" string => "\d+$(init.mode)"; "expect[uid]" string => "$(init.owner)"; "expect[gid]" string => "$(init.group)"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; compare => "mtime"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { # Mode is unspecified - should not change anything owners => { "12349", "none" }; # Should change to 12349 # Group is unspecified - should not change anything } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "\d+$(init.mode)"; "expect[uid]" string => "12349"; "expect[gid]" string => "$(init.group)"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "result: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/202.cf0000644000000000000000000000551315010704253023127 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size, owner, group # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: any:: "mode" int => "01751"; linux:: "owner" string => "sys"; "group" string => "sys"; freebsd:: "owner" string => "bin"; "group" string => "sys"; !(linux|freebsd):: "owner" string => "undefined-please-fix"; "group" string => "undefined-please-fix"; pass2.!windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms("$(init.mode)", "$(init.owner)", "$(init.group)"); } body perms test_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)", "root" }; linux:: groups => { "$(g)", "root" }; freebsd:: groups => { "$(g)", "wheel" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "ok" expression => strcmp("$(init.result)", "$(result)"); "not_ok" not => regcmp("$(init.result[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(init.result[$(fields)])'"; "got: $(fields) = '$(check.result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/207.cf0000644000000000000000000000565315010704253023141 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size, but DOES change owner, group (numeric IDs) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } ####################################################### bundle agent init { vars: freebsd|solaris:: "mode" int => "04751"; !freebsd.!solaris:: "mode" int => "01751"; linux:: "owner" string => "sys"; "group" string => "sys"; freebsd:: "owner" string => "bin"; "group" string => "sys"; !(linux|freebsd):: "owner" string => "undefined-please-fix"; "group" string => "undefined-please-fix"; pass2.(freebsd|solaris):: "expect[modeoct]" string => "104755"; pass2.!(freebsd|solaris|windows):: "expect[modeoct]" string => "101755"; pass2.!windows:: "expect[uid]" string => "333"; "expect[gid]" string => "444"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms("a+r"); } body perms test_perms(m) { mode => "$(m)"; owners => { "333" }; groups => { "444" }; } ####################################################### bundle agent check { vars: freebsd|solaris:: "expect[modeoct]" string => "104755"; !freebsd.!solaris.!windows:: "expect[modeoct]" string => "101755"; !windows:: "expect[uid]" string => "333"; "expect[gid]" string => "444"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "result: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/backup_repository.cf0000644000000000000000000000201315010704253026360 0ustar00rootroot00000000000000# Test that repository contains backup of file after updating it. body common control { bundlesequence => { default("$(this.promise_filename)") }; inputs => { "../../default.cf.sub" }; } body agent control { default_repository => $(init.repodir); } bundle agent init { vars: "repodir" string => "$(sys.workdir)/repository"; methods: "" usebundle => dcs_fini($(repodir)); "" usebundle => file_make("$(G.testfile).orig", "Original content"); "" usebundle => file_make("$(G.testfile).new", "Updated content"); "" usebundle => file_make("$(G.testfile).copy", "Original content"); } bundle agent test { methods: "" usebundle => file_copy("$(G.testfile).new", "$(G.testfile).copy"); } bundle agent check { vars: "backups" slist => findfiles("$(init.repodir)/*cfsaved"); methods: "any" usebundle => dcs_check_diff("$(G.testfile).orig", $(backups), "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/301.cf0000644000000000000000000000455115010704253023130 0ustar00rootroot00000000000000####################################################### # # Create a file using copy, expect second copy to have "promise_kept" # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { classes: "cxl_succ" expression => "any"; "cxl_fail" expression => "any"; } ####################################################### bundle agent init { files: "$(G.testfile)" perms => init_mog, copy_from => init_copy("$(G.etc_group)"); } body perms init_mog { mode => "751"; owners => { "0" }; groups => { "0" }; } body copy_from init_copy(fn) { source => "$(fn)"; compare => "digest"; } ####################################################### bundle agent test { files: "$(G.testfile)" perms => init_mog, copy_from => init_copy("$(G.etc_group)"), classes => test_classes("success", "failure", "failure", "failure", "cxl_succ", "cxl_fail", "cxl_fail"); } body classes test_classes(kep, rep, fai, xxx, cxl_kep, cxl_rep, cxl_nkp) { promise_kept => { "$(kep)" }; promise_repaired => { "$(rep)" }; repair_failed => { "$(fai)" }; repair_denied => { "$(fai)" }; repair_timeout => { "$(fai)" }; cancel_kept => { "$(cxl_kep)" }; cancel_repaired => { "$(cxl_rep)" }; cancel_notkept => { "$(cxl_nkp)" }; } ####################################################### bundle agent check { classes: "ok" and => { "success", "!cxl_succ", "!failure", "cxl_fail" }; reports: DEBUG.success:: "class 'success' was set (should be)"; DEBUG.!success:: "class 'success' was not set (should be)"; DEBUG.cxl_succ:: "class 'cxl_succ' was still set (should not be)"; DEBUG.!cxl_succ:: "class 'cxl_succ' was not still set (should not be)"; DEBUG.failure:: "class 'failure' was set (should not be)"; DEBUG.!failure:: "class 'failure' was not set (should not be)"; DEBUG.cxl_fail:: "class 'cxl_fail' was still set (should be)"; DEBUG.!cxl_fail:: "class 'cxl_fail' was not still set (should not be)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/RM5411.cf0000644000000000000000000000114515010704253023452 0ustar00rootroot00000000000000# RedMine 5411: segfaults. -*- Mode: cfengine -*- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/src" create => "true"; } bundle agent test { files: "$(G.testdir)/dst" copy_from => chained("$(G.testdir)/src"); } body copy_from chained(sourcedir) { source => "$(sourcedir)"; servers => { "x", "localhost" }; } bundle agent check { reports: # If we made it this far, we didn't segfault. "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/407.x.cf0000644000000000000000000000330415010704253023400 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; "repofile" string => "/var/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(g.repofile).*" delete => init_delete; "$(G.testfile).*" delete => init_delete; "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" repository => "tmp", # Intentionally wrong move_obstructions => "true", copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_motd)"; compare => "digest"; } ####################################################### bundle agent check { classes: "test" not => fileexists("$(G.testfile).cfsaved"); "repo" expression => fileexists("$(g.repofile).cfsaved"); "ok" and => { "test", "repo" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(g.repofile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/symlink_link_and_no_move_obstructions.cf0000644000000000000000000000441715010704253032513 0ustar00rootroot00000000000000####################################################### # # Create an relative link to a file, expect subsequent symlink promise to # be unhappy with that (symlink is supposed to be synonymous with absolute) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => init_link; } body link_from init_link { source => "$(G.etc_group)"; link_type => "relative"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; "test_suppress_fail" string => "freebsd", meta => { "redmine5261" }; vars: "inode" string => filestat("$(G.etc_group)", "ino"); files: "$(G.testfile)" classes => test_if_ok("test_ok"), link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "symlink"; } body classes test_if_ok(c) { repair_failed => { "$(c)" }; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); "Lresult" string => filestat("$(G.testfile)", "ino"); # This tells us where the link points "link_target" string => filestat("$(G.testfile)", "linktarget_shallow"); classes: "okL" not => strcmp("$(test.inode)", "$(Lresult)"); "okT" not => strcmp("$(link_target)", "$(G.etc_group)"); "ok" and => { "test_ok", "okL", "okT", strcmp("$(test.inode)", "$(result)"), # Test that the symlink target starts with dot regcmp("\..*", "$(link_target)") }; reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(Lresult)' => '$(result)'"; "got this too: '$(G.etc_group)' => '$(link_target)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/403.x.cf0000644000000000000000000000264415010704253023402 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { default_repository => "non-absolute-path"; # Intentionally wrong } bundle agent init { files: "$(g.repofile).*" delete => init_delete; "$(G.testfile).*" delete => init_delete; "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_motd)"; compare => "digest"; } ####################################################### bundle agent check { classes: "test" not => fileexists("$(G.testfile).cfsaved"); "repo" expression => fileexists("$(g.repofile).cfsaved"); "ok" and => { "test", "repo" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/106.x.cf0000644000000000000000000000317115010704253023376 0ustar00rootroot00000000000000####################################################### # # Test wrong type of link_type. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "none"; } ####################################################### bundle agent check { vars: "expect[permoct]" string => "$(test.mode)"; "expect[nlink]" string => "1"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/copy-relative-link.cf0000644000000000000000000000200215010704253026330 0ustar00rootroot00000000000000# Test that copying relative link does not mangle it (Mantis #1117) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { commands: "$(G.mkdir) -p $(G.testdir)/a"; "$(G.touch) $(G.testdir)/a/dest"; "$(G.ln) -s dest $(G.testdir)/a/link"; } bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testdir)/b" copy_from => local_cp("$(G.testdir)/a"), depth_search => recurse("inf"); } bundle agent check { vars: "expect" string => "dest"; "result" string => filestat("$(G.testdir)/b/link", "linktarget_shallow"); classes: "ok" expression => strcmp("$(result)", "$(expect)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/symlink_link_kept.cf0000644000000000000000000000413615010704253026352 0ustar00rootroot00000000000000####################################################### # # Create an absolute link to a file, expect subsequent symlink promise to # be happy with that # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).linked_to" create => "true"; "$(G.testfile)" create => "true", move_obstructions => "true", link_from => init_link; } body link_from init_link { source => "$(G.testfile).linked_to"; link_type => "absolute"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "inode" string => filestat("$(G.testfile).linked_to", "ino"); files: "$(G.testfile)" classes => test_if_ok("test_ok"), link_from => test_link; } body link_from test_link { source => "$(G.testfile).linked_to"; link_type => "symlink"; } body classes test_if_ok(c) { promise_kept => { "$(c)" }; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); "Lresult" string => filestat("$(G.testfile)", "ino"); # This tells us where the link points "link_target" string => filestat("$(G.testfile)", "linktarget"); classes: "okL" not => strcmp("$(test.inode)", "$(Lresult)"); "ok" and => { "test_ok", "okL", strcmp("$(test.inode)", "$(result)"), strcmp("$(link_target)", "$(G.testfile).linked_to") }; reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(Lresult)' => '$(result)'"; "got this too: '$(G.testfile).linked_to' => '$(link_target)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/209.cf0000644000000000000000000000533515010704253023140 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size, but DOES change owner, group, because # we start with a non-registered user/group name. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } ####################################################### bundle agent init { vars: freebsd|solaris:: "mode" int => "04751"; !freebsd.!solaris:: "mode" int => "01751"; any:: "owner" string => "786756"; "group" string => "786756"; pass2.!windows:: "expect[modeoct]" string => "\d+$(init.mode)"; "expect[uid]" string => "$(init.owner)"; "expect[gid]" string => "$(init.group)"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; compare => "mtime"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { # Mode, owner is unspecified - should not change anything groups => { "23459", "none" }; # Should change to 23459 } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "\d+$(init.mode)"; "expect[uid]" string => "$(init.owner)"; "expect[gid]" string => "23459"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "result: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/404.x.cf0000644000000000000000000000326315010704253023401 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { default_repository => "tmp"; # Intentionally wrong } bundle common g { vars: "repofile" string => "/var/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(g.repofile).*" delete => init_delete; "$(G.testfile).*" delete => init_delete; "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_motd)"; compare => "digest"; } ####################################################### bundle agent check { classes: "test" not => fileexists("$(G.testfile).cfsaved"); "repo" expression => fileexists("$(g.repofile).cfsaved"); "ok" and => { "test", "repo" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(g.repofile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/changes_update_hashes.cf0000644000000000000000000001775015010704253027137 0ustar00rootroot00000000000000# Test that monitoring file status of an updated file gives right promises # status. body common control { inputs => { "../../default.cf.sub", "check_file_changes_log.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { files: # Not in database. "$(G.testfile).update.new" create => "true"; # Should be in database. "$(G.testfile).update.same" create => "true", changes => test_changes_update; "$(G.testfile).update.updated" create => "true", changes => test_changes_update; # Not in database. "$(G.testfile).noupdate.new" create => "true"; # Should be in database. "$(G.testfile).noupdate.same" create => "true", changes => test_changes_nohasheupdate_report_changes_all; "$(G.testfile).noupdate.updated" create => "true", changes => test_changes_nohasheupdate_report_changes_all; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10254" }; files: "$(G.testfile).update.updated" edit_line => insert_text; "$(G.testfile).noupdate.updated" edit_line => insert_text; methods: # Update each file twice. We cannot reuse the bundles because CFEngine # will skip bundles it has done before. "test_update_new" usebundle => test_update_new; "test_update_same" usebundle => test_update_same; "test_update_updated" usebundle => test_update_updated; "test_update_new_again" usebundle => test_update_new_again; "test_update_same_again" usebundle => test_update_same_again; "test_update_updated_again" usebundle => test_update_updated_again; "test_noupdate_new" usebundle => test_noupdate_new; "test_noupdate_same" usebundle => test_noupdate_same; "test_noupdate_updated" usebundle => test_noupdate_updated; "test_noupdate_new_again" usebundle => test_noupdate_new_again; "test_noupdate_same_again" usebundle => test_noupdate_same_again; "test_noupdate_updated_again" usebundle => test_noupdate_updated_again; } bundle edit_line insert_text { insert_lines: "Text"; } bundle agent test_update_new { files: "$(G.testfile).update.new" changes => test_changes_update, classes => kept_repaired_notkept("test_update_new_kept", "test_update_new_repaired", "test_update_new_notkept"); } bundle agent test_update_same { files: "$(G.testfile).update.same" changes => test_changes_update, classes => kept_repaired_notkept("test_update_same_kept", "test_update_same_repaired", "test_update_same_notkept"); } bundle agent test_update_updated { files: "$(G.testfile).update.updated" changes => test_changes_update, classes => kept_repaired_notkept("test_update_updated_kept", "test_update_updated_repaired", "test_update_updated_notkept"); } bundle agent test_update_new_again { files: "$(G.testfile).update.new" changes => test_changes_update, classes => kept_repaired_notkept("test_update_new_kept", "test_update_new_repaired", "test_update_new_notkept"); } bundle agent test_update_same_again { files: "$(G.testfile).update.same" changes => test_changes_update, classes => kept_repaired_notkept("test_update_same_kept", "test_update_same_repaired", "test_update_same_notkept"); } bundle agent test_update_updated_again { files: "$(G.testfile).update.updated" changes => test_changes_update, classes => kept_repaired_notkept("test_update_updated_kept", "test_update_updated_repaired", "test_update_updated_notkept"); } bundle agent test_noupdate_new { files: "$(G.testfile).noupdate.new" changes => test_changes_nohasheupdate_report_changes_all, classes => kept_repaired_notkept("test_noupdate_new_kept", "test_noupdate_new_repaired", "test_noupdate_new_notkept"); } bundle agent test_noupdate_same { files: "$(G.testfile).noupdate.same" changes => test_changes_nohasheupdate_report_changes_all, classes => kept_repaired_notkept("test_noupdate_same_kept", "test_noupdate_same_repaired", "test_noupdate_same_notkept"); } bundle agent test_noupdate_updated { files: "$(G.testfile).noupdate.updated" changes => test_changes_nohasheupdate_report_changes_all, classes => kept_repaired_notkept("test_noupdate_updated_kept", "test_noupdate_updated_repaired", "test_noupdate_updated_notkept"); } bundle agent test_noupdate_new_again { files: "$(G.testfile).noupdate.new" changes => test_changes_nohasheupdate_report_changes_all, classes => kept_repaired_notkept("test_noupdate_new_kept", "test_noupdate_new_repaired", "test_noupdate_new_notkept"); } bundle agent test_noupdate_same_again { files: "$(G.testfile).noupdate.same" changes => test_changes_nohasheupdate_report_changes_all, classes => kept_repaired_notkept("test_noupdate_same_kept", "test_noupdate_same_repaired", "test_noupdate_same_notkept"); } bundle agent test_noupdate_updated_again { files: "$(G.testfile).noupdate.updated" changes => test_changes_nohasheupdate_report_changes_all, classes => kept_repaired_notkept("test_noupdate_updated_kept", "test_noupdate_updated_repaired", "test_noupdate_updated_notkept"); } body changes test_changes_update { hash => "sha256"; report_changes => "all"; update_hashes => "yes"; } body changes test_changes_nohasheupdate_report_changes_all { hash => "sha256"; report_changes => "all"; update_hashes => "no"; } body classes kept_repaired_notkept(kept, repaired, notkept) { promise_kept => { "$(kept)" }; promise_repaired => { "$(repaired)" }; repair_failed => { "$(notkept)" }; repair_denied => { "$(notkept)" }; repair_timeout => { "$(notkept)" }; } bundle agent check { vars: "classes_set" slist => classesmatching("test_.*"); methods: # Seems like CFEngine does two passes over files where we don't update # hash, so the last four entries should really be two entries. # If the number of "Content changed" lines is wrong, this is the first # place to look. "any" usebundle => file_make("$(G.testfile).file_changes_log", "TEST.cfengine.update.updated,C,Content changed TEST.cfengine.noupdate.updated,C,Content changed TEST.cfengine.noupdate.updated,C,Content changed TEST.cfengine.noupdate.updated,C,Content changed TEST.cfengine.noupdate.updated,C,Content changed"); "any" usebundle => check_file_changes_log("$(G.testfile).file_changes_log", "test_changes_log_ok", "test_changes_log_fail", ""); classes: "ok" and => { "checksum_alerts", "test_update_new_repaired", "!test_update_new_notkept", "!test_update_same_repaired", "test_update_same_kept", "!test_update_same_notkept", "test_update_updated_repaired", "!test_update_updated_notkept", "test_noupdate_new_repaired", "!test_noupdate_new_notkept", "!test_noupdate_same_repaired", "test_noupdate_same_kept", "!test_noupdate_same_notkept", "test_noupdate_updated_repaired", # because changes are recorded in the changes log "test_noupdate_updated_notkept", # because hashes are not updated "test_changes_log_ok", "!test_changes_log_fail", }; reports: DEBUG:: "Set classes: $(classes_set)"; !checksum_alerts.DEBUG:: "The checksum_alerts class was NOT set as expected."; checksum_alerts.EXTRA:: "The checksum_alerts class was set as expected."; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/414.cf0000644000000000000000000000245215010704253023133 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 1 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { commands: "$(G.touch) $(G.testfile)"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; commands: "$(cmd)"; "$(cmd) -D useless1"; "$(cmd) -D useless2"; "$(cmd) -D useless3"; "$(cmd) -D useless4"; } ####################################################### bundle agent check { classes: "filestillthere" expression => fileexists("$(G.testfile)"); "fileisrotated" expression => fileexists("$(G.testfile).cf-before-edit.1"); "nooverflow" not => fileexists("$(G.testfile).cf-before-edit.2"); "ok" and => { "filestillthere", "fileisrotated", "nooverflow" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/absolute_link_and_no_move_obstructions.cf0000644000000000000000000000441515010704253032641 0ustar00rootroot00000000000000####################################################### # # Create an relative link to a file, expect absolute link promise to want # to change it to an absolute link (but fail to) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", move_obstructions => "true", link_from => init_link; } body link_from init_link { source => "$(G.etc_group)"; link_type => "relative"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; "test_suppress_fail" string => "freebsd", meta => { "redmine5261" }; vars: "inode" string => filestat("$(G.etc_group)", "ino"); files: "$(G.testfile)" classes => init_if_failed("test_ok"), link_from => test_link; } body link_from test_link { source => "$(G.etc_group)"; link_type => "absolute"; } body classes init_if_failed(c) { repair_failed => { "$(c)" }; } ####################################################### bundle agent check { vars: "result" string => filestat(filestat("$(G.testfile)", "linktarget"), "ino"); "Lresult" string => filestat("$(G.testfile)", "ino"); # Tell us where the link points, but don't follow it "link_target" string => filestat("$(G.testfile)", "linktarget_shallow"); classes: "okL" not => strcmp("$(test.inode)", "$(Lresult)"); "okT" not => strcmp("$(link_target)", "$(G.etc_group)"); "ok" and => { "test_ok", "okL", "okT", strcmp("$(test.inode)", "$(result)"), # Test that the symlink target starts with dot regcmp("\..*", "$(link_target)") }; reports: DEBUG:: "expected: '$(test.inode)'"; "got: '$(Lresult)' => '$(result)'"; "got this too: '$(G.etc_group)' => '$(link_target)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/002.cf0000644000000000000000000000340415010704253023122 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous copy with mtime compare to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)), copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_group)"; compare => "mtime"; } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; "expect[uid]" string => "0"; "expect[gid]" string => "0"; any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/411.cf0000644000000000000000000000263115010704253023127 0ustar00rootroot00000000000000####################################################### # # Test that action => "warn" works correctly for rename { rotate => 0 } (Issue 841) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "someline"; "expected" string => "someline"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" rename => rotate, action => warn_only; } body rename rotate { rotate => "0"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/013.cf0000644000000000000000000000347215010704253023131 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testdir)/srcdir/" create => "true"; "$(G.testdir)/srcdir/intermediate/" create => "true"; "$(G.testdir)/srcdir/intermediate/intermediate2/" create => "true"; "$(G.testdir)/srcdir/intermediate/intermediate2/foo" create => "true"; "$(G.testdir)/realdestdir/" create => "true"; "$(G.testdir)/destdir" comment => "Create a relative link to the target.", link_from => ln_s("$(G.testdir)/realdestdir"); } body link_from ln_s(x) { link_type => "relative"; source => "$(x)"; when_no_source => "nop"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testdir)/destdir" copy_from => test_sync_cp("$(G.testdir)/srcdir"), depth_search => recurse("inf"); } body copy_from test_sync_cp(from) { source => "$(from)"; purge => "true"; preserve => "true"; } ####################################################### bundle agent check { vars: "expect" string => "symlink"; "result" string => filestat("$(G.testdir)/destdir", "type"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/018.cf0000644000000000000000000000262415010704253023134 0ustar00rootroot00000000000000####################################################### # # Test that disable_mode => "000" in body rename works (Issue 688) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testfile)" rename => disable_file; } body rename disable_file { disable_mode => "000"; disable => "true"; } ####################################################### bundle agent check { vars: "expect[permoct]" string => "0"; "expect[nlink]" string => "1"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile).cfdisabled", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ## PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/0000755000000000000000000000000015010704253023742 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/302.cf0000644000000000000000000000512115010704253024557 0ustar00rootroot00000000000000####################################################### # # Create a file using copy, expect second copy of different file to # have "promise_repaired" # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; classes: "cxl_succ" expression => "any"; "cxl_fail" expression => "any"; } ####################################################### bundle agent init { files: "$(G.testfile)" perms => init_mog, copy_from => init_copy("$(G.etc_group)"); } body perms init_mog { mode => "751"; owners => { "bin" }; groups => { "bin" }; } body copy_from init_copy(fn) { source => "$(fn)"; compare => "digest"; } ####################################################### bundle agent test { files: "$(G.testfile)" perms => init_mog, copy_from => init_copy("$(G.etc_passwd)"), classes => test_classes("failure", "success", "failure", "failure", "cxl_fail", "cxl_succ", "cxl_fail"); } body classes test_classes(kep, rep, fai, xxx, cxl_kep, cxl_rep, cxl_nkp) { promise_kept => { "$(kep)" }; promise_repaired => { "$(rep)" }; repair_failed => { "$(fai)" }; repair_denied => { "$(fai)" }; repair_timeout => { "$(fai)" }; cancel_kept => { "$(cxl_kep)" }; cancel_repaired => { "$(cxl_rep)" }; cancel_notkept => { "$(cxl_nkp)" }; } ####################################################### bundle agent check { classes: "ok" and => { "success", "!cxl_succ", "!failure", "cxl_fail" }; reports: DEBUG.success:: "class 'success' was set (should be)"; DEBUG.!success:: "class 'success' was not set (should be)"; DEBUG.cxl_succ:: "class 'cxl_succ' was still set (should not be)"; DEBUG.!cxl_succ:: "class 'cxl_succ' was not still set (should not be)"; DEBUG.failure:: "class 'failure' was set (should not be)"; DEBUG.!failure:: "class 'failure' was not set (should not be)"; DEBUG.cxl_fail:: "class 'cxl_fail' was still set (should be)"; DEBUG.!cxl_fail:: "class 'cxl_fail' was not still set (should not be)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/405.cf0000644000000000000000000000361415010704253024570 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; "repofile" string => "_tmp_TEST.cfengine"; "repo" string => "/var/tmp"; } ####################################################### bundle agent init { files: "$(g.repo)/$(g.repofile).*" delete => init_delete; "$(G.testfile).*" delete => init_delete; "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", repository => "$(g.repo)", copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_motd)"; compare => "digest"; } ####################################################### bundle agent check { classes: "test" not => fileexists("$(G.testfile).cfsaved"); "repo" expression => fileexists("$(g.repo)/$(g.repofile).cfsaved"); "ok" and => { "test", "repo" }; reports: DEBUG:: "testfile = $(G.testfile)"; "repo = $(g.repo)"; "repofile = $(g.repofile)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); "any" usebundle => dcs_fini("$(g.repo)/$(g.repofile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/110.x.cf0000644000000000000000000000336115010704253025026 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous absolute symbolic no-filename link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; # This extracts the octal mode, and decimal nlink, uid, gid, size "command" string => 'printf "%o" . " %d" x 4, (stat("$(G.testfile)"))[2]&07777, (stat(_))[3..5,7]'; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", link_from => test_link; } body link_from test_link { link_type => "absolute"; } ####################################################### bundle agent check { vars: "expect" string => "$(test.mode) 1 0 0 0"; "result" string => execresult( "$(G.perl) -le '$(g.command)'", "noshell"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/copy-select-link-dereference.cf0000644000000000000000000000354415010704253031711 0ustar00rootroot00000000000000# Assume the following file-structure: # dir1/file1 # dir2/file2 # link -> dir1 # # We want to copy only what link points to, without explicitly specifying the link name. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { commands: "$(G.mkdir) -p $(G.testdir)/from/dir1"; "$(G.mkdir) -p $(G.testdir)/from/dir2"; "$(G.echo) 'indir1' > $(G.testdir)/from/dir1/file1" contain => in_shell; "$(G.echo) 'indir2' > $(G.testdir)/from/dir2/file2" contain => in_shell; "$(G.ln) -s dir1 link", contain => in_dir("$(G.testdir)/from"); } bundle agent test { vars: "regular_dirs" slist => { ".*dir1",".*dir2" }; files: "$(G.testdir)/to" copy_from => dereference_all("$(G.testdir)/from"), depth_search => recurse("inf"), file_select => links_to( "@(regular_dirs)" ); } bundle agent check { vars: "file1_contents" string => readfile("$(G.testdir)/to/dir1/file1", 100); classes: "file1_contents_correct" expression => strcmp("$(file1_contents)", "indir1"); "file2_exists" expression => fileexists("$(G.testdir)/to/dir2/file2"); "ok" expression => "file1_contents_correct.(!file2_exists)"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body contain in_dir(s) { chdir => "$(s)"; } body contain in_shell { useshell => "true"; } body copy_from dereference_all(from) { source => "$(from)"; copylink_patterns => { ".*" }; } body file_select links_to(list) { issymlinkto => { @(list) }; file_result => "issymlinkto"; } body depth_search recurse(d) { depth => "$(d)"; xdev => "true"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/line_truncation_at_4096_chars.cf0000644000000000000000000000437115010704253032004 0ustar00rootroot00000000000000####################################################### # # Check if the lines in a file get truncated after 4096 # chars during file editing. # # Ticket: https://cfengine.com/dev/issues/3882 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("${this.promise_filename}") }; version => "1.0"; } ####################################################### bundle agent init { vars: any:: "file_mode" int => "0644"; "char_number" int => "6144"; "line_to_add" string => "This is a nice short line."; files: "${G.testfile}" create => "true", perms => m("${file_mode}"); # Using system command instead of CFEngine itself to # prevent the bug to be here at file creation too. # It would create a false negative. commands: "${G.perl}" args => "-e 'print \"#\" x ${char_number}; print \"ENDMARK\n\"' > ${G.testfile}" contain => in_shell; } body perms m(mode) { mode => "${mode}"; } body contain in_shell { useshell => "true"; # canonical "useshell" but this is backwards-compatible } ####################################################### bundle agent test { files: "${G.testfile}" create => "false", edit_line => insert_lines("${init.line_to_add}"); } bundle edit_line insert_lines(lines) { insert_lines: "${lines}" comment => "Append lines if they don't exist"; } ####################################################### bundle agent check { classes: # ok is defined if the file still contains ENDMARK, meaning the end of the sample very # long line did not get truncated during file editing "ok" expression => returnszero("${G.grep} -q ENDMARK ${G.testfile}", "noshell"); reports: DEBUG.!ok:: "${this.promise_filename} FAILed as the generated file got at least a line truncated to 4096 characters" ok:: "${this.promise_filename} Pass"; !ok:: "${this.promise_filename} FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("${G.testfile}"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/edit_immutable.cf0000644000000000000000000000524715010704253027250 0ustar00rootroot00000000000000####################################################### # # Redmine#3184: Test editing of an immutable file # Redmine#2100: Test chmod of an immutable file # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common chattr { vars: "chattr" string => "/usr/bin/chattr"; classes: "have_chattr" expression => fileexists($(chattr)); } bundle agent init { files: "$(G.testfile)" create => "true"; } bundle agent test { methods: "1" usebundle => test_setup($(G.testfile)); "2" usebundle => test_edit($(G.testfile)); "2" usebundle => test_chmod($(G.testfile)); "3" usebundle => test_teardown($(G.testfile)); } bundle agent test_setup(file) { commands: have_chattr:: "$(chattr.chattr)" args => "+i $(file)", classes => scoped_classes_generic("namespace", "chattr"); } bundle agent test_edit(file) { files: have_chattr:: "$(file)" edit_line => test_edit_line(), classes => scoped_classes_generic("namespace", "test"); } bundle agent test_chmod(file) { files: have_chattr:: "$(file)" perms => m("755"), classes => scoped_classes_generic("namespace", "chmod"); } body perms m(mode) { mode => "$(mode)"; } bundle agent test_teardown(file) { commands: have_chattr:: "$(chattr.chattr)" args => "-i $(file)", classes => scoped_classes_generic("namespace", "chattr"); } bundle edit_line test_edit_line() { insert_lines: "blah"; } ####################################################### bundle agent check { classes: # we're OK if: # - we don't have chattr # - chattr failed to DTRT (e.g. we're not root) # - the test failed to edit # - the test denied the chmod (TODO: should it be "denied" or "failed"? "ok" expression => "!have_chattr|chattr_failed|(test_failed.!test_kept.!test_denied.!test_timeout.!test_repaired.!chmod_failed.!chmod_kept.chmod_denied.!chmod_timeout.!chmod_repaired)"; methods: "report" usebundle => dcs_report_generic_classes("test"); "report" usebundle => dcs_report_generic_classes("chmod"); "report" usebundle => dcs_report_generic_classes("chattr"); reports: DEBUG.!have_chattr:: "Without $(chattr.chattr), the test will always pass"; DEBUG.chattr_failed:: "Since you can't run $(chattr.chattr) to set attributes, the test will always pass"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/107.x.cf0000644000000000000000000000334415010704253025035 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous hard no-filename link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; # This extracts the octal mode, and decimal nlink, uid, gid, size "command" string => 'printf "%o" . " %d" x 4, (stat("$(G.testfile)"))[2]&07777, (stat(_))[3..5,7]'; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", link_from => test_link; } body link_from test_link { link_type => "hardlink"; } ####################################################### bundle agent check { vars: "expect" string => "$(test.mode) 1 0 0 0"; "result" string => execresult( "$(G.perl) -le '$(g.command)'", "noshell"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/108.x.cf0000644000000000000000000000333515010704253025036 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous symbolic no-filename link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; # This extracts the octal mode, and decimal nlink, uid, gid, size "command" string => 'printf "%o" . " %d" x 4, (stat("$(G.testfile)"))[2]&07777, (stat(_))[3..5,7]'; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" link_from => test_link("$(baz)"); } body link_from test_link(foo) { link_type => "$(foo)"; } ####################################################### bundle agent check { vars: "expect" string => "$(test.mode) 1 0 0 0"; "result" string => execresult( "$(G.perl) -le '$(g.command)'", "noshell"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/401.cf0000644000000000000000000000270515010704253024564 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(G.testfile).*" delete => init_delete; "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_motd)"; compare => "digest"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile).cfsaved"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/109.x.cf0000644000000000000000000000336115010704253025036 0ustar00rootroot00000000000000####################################################### # # Create a file, expect simultaneous relative symbolic no-filename link to fail # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; # This extracts the octal mode, and decimal nlink, uid, gid, size "command" string => 'printf "%o" . " %d" x 4, (stat("$(G.testfile)"))[2]&07777, (stat(_))[3..5,7]'; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0600"; files: "$(G.testfile)" create => "true", link_from => test_link; } body link_from test_link { link_type => "relative"; } ####################################################### bundle agent check { vars: "expect" string => "$(test.mode) 1 0 0 0"; "result" string => execresult( "$(G.perl) -le '$(g.command)'", "noshell"); classes: "ok" expression => strcmp("$(expect)", "$(result)"); reports: DEBUG:: "expected: '$(expect)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/staging/402.cf0000644000000000000000000000332415010704253024563 0ustar00rootroot00000000000000####################################################### # # # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { default_repository => "/var/tmp"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; "repofile" string => "_tmp_TEST.cfengine"; "repo" string => "/var/tmp"; } ####################################################### bundle agent init { files: "$(g.repofile).*" delete => init_delete; "$(G.testfile).*" delete => init_delete; "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", copy_from => test_copy; } body copy_from test_copy { source => "$(G.etc_motd)"; compare => "digest"; } ####################################################### bundle agent check { classes: "test" not => fileexists("$(G.testfile).cfsaved"); "repo" expression => fileexists("$(g.repo)/$(g.repofile).cfsaved"); "ok" and => { "test", "repo" }; reports: DEBUG:: "testfile = $(G.testfile)"; "repo = $(g.repo)"; "repofile = $(g.repofile)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/408.cf0000644000000000000000000000301415010704253023131 0ustar00rootroot00000000000000####################################################### # # Copy symlink over file, test that file is correctly saved aside. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "srcfile" string => "$(G.testfile).source"; } ####################################################### bundle agent init { files: "$(G.testfile)" move_obstructions => "true", copy_from => init_copy; "$(g.srcfile)" move_obstructions => "true", link_from => init_link; } body copy_from init_copy { source => "$(G.etc_group)"; compare => "digest"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } body link_from init_link { source => "$(G.true)"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testfile)" move_obstructions => "true", copy_from => test_copy; } body copy_from test_copy { source => "$(g.srcfile)"; compare => "digest"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile).cfsaved"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/206.cf0000644000000000000000000000565415010704253023141 0ustar00rootroot00000000000000####################################################### # # Copy a file, then ensure that subsequent create=true doesn't # overwrite mode, size, but DOES change owner, group - numeric UID/GID # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; cache_system_functions => "false"; } ####################################################### bundle agent init { vars: freebsd|solaris:: "mode" int => "04751"; !freebsd.!solaris:: "mode" int => "01751"; linux:: "owner" string => "sys"; "group" string => "sys"; freebsd:: "owner" string => "bin"; "group" string => "sys"; !(linux|freebsd):: "owner" string => "undefined-please-fix"; "group" string => "undefined-please-fix"; pass2.(freebsd|solaris):: "expect[modeoct]" string => "104755"; pass2.!(freebsd|solaris|windows):: "expect[modeoct]" string => "101755"; pass2.!windows:: "expect[uid]" string => "0"; "expect[gid]" string => "0"; pass2.any:: "expect[nlink]" string => "1"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); files: "$(G.testfile)" copy_from => init_copy("$(G.etc_group)"), perms => init_perms("$(mode)", "$(owner)", "$(group)"), classes => init_set_class("pass2"); } body copy_from init_copy(file) { source => "$(file)"; } body perms init_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } body classes init_set_class(class) { promise_kept => { "$(class)" }; promise_repaired => { "$(class)" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", perms => test_perms("a+r"); } body perms test_perms(m) { mode => "$(m)"; owners => { "456" }; groups => { "567" }; } ####################################################### bundle agent check { vars: freebsd|solaris:: "expect[modeoct]" string => "104755"; !freebsd.!solaris.!windows:: "expect[modeoct]" string => "101755"; !windows:: "expect[uid]" string => "456"; "expect[gid]" string => "567"; any:: "expect[nlink]" string => "1"; "expect[size]" string => filestat("$(G.etc_group)", "size"); "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "result: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/02_maintain/changes_depth_search.cf0000644000000000000000000000711715010704253026747 0ustar00rootroot00000000000000# Checks whether a whole directory is monitored correctly with # a file changes promise. body common control { inputs => { "../../dcs.cf.sub", "../../plucked.cf.sub", "check_file_changes_log.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => setup_files; } bundle agent setup_files { methods: # Note: sorted, not in actual order, due to file system order sensitivity. "any" usebundle => file_make("$(G.testfile).expected", "file.content,C,Content changed file.content,C,Content changed file.content,C,Content changed file.content,C,Content changed file.content,C,Content changed file.content,N,New file found file.content.cf-before-edit,N,New file found file.content.cf-before-edit,N,New file found file.content.cf-before-edit,N,New file found file.content.cf-before-edit,R,File removed file.content.cf-before-edit,R,File removed file.created,N,New file found file.created,N,New file found file.created,N,New file found file.created,R,File removed file.created,R,File removed file.new-ignored.content,N,New file found file.new-ignored.content,N,New file found file.new-ignored.content,N,New file found file.new-ignored.content,R,File removed file.new-ignored.content,R,File removed file.new-ignored.content,R,File removed file.new-ignored.removed,N,New file found file.new-ignored.removed,N,New file found file.new-ignored.removed,N,New file found file.new-ignored.removed,R,File removed file.new-ignored.removed,R,File removed file.new-ignored.removed,R,File removed file.new-ignored.same,N,New file found file.new-ignored.same,N,New file found file.new-ignored.same,N,New file found file.new-ignored.same,R,File removed file.new-ignored.same,R,File removed file.new-ignored.same,R,File removed file.removed,N,New file found file.removed,N,New file found file.removed,N,New file found file.removed,R,File removed file.removed,R,File removed file.removed,R,File removed file.same,N,New file found subdir,N,New file found subfile.content,C,Content changed subfile.content,C,Content changed subfile.content,C,Content changed subfile.content,C,Content changed subfile.content,C,Content changed subfile.content,N,New file found subfile.content.cf-before-edit,N,New file found subfile.content.cf-before-edit,N,New file found subfile.content.cf-before-edit,N,New file found subfile.content.cf-before-edit,R,File removed subfile.content.cf-before-edit,R,File removed subfile.created,N,New file found subfile.created,N,New file found subfile.created,N,New file found subfile.created,R,File removed subfile.created,R,File removed subfile.removed,N,New file found subfile.removed,N,New file found subfile.removed,N,New file found subfile.removed,R,File removed subfile.removed,R,File removed subfile.removed,R,File removed subfile.same,N,New file found"); } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10254" }; commands: "$(sys.cf_agent) -Dpass1 -Kf $(this.promise_filename).sub"; "$(sys.cf_agent) -Dpass2 -Kf $(this.promise_filename).sub"; "$(sys.cf_agent) -Dpass3 -Kf $(this.promise_filename).sub"; } bundle agent check { methods: "any" usebundle => check_file_changes_log("$(G.testfile).expected", "test_changes_log_ok", "test_changes_log_fail", "sorted"); classes: "ok" and => { "test_changes_log_ok", "!test_changes_log_fail", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/rename/0000755000000000000000000000000015010704253021454 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/rename/main.cf0000644000000000000000000000512715010704253022717 0ustar00rootroot00000000000000body file control { inputs => { "../../default.cf.sub" }; } bundle agent main { methods: "init,test,check,cleanup" usebundle => default("$(this.promise_filename)") ; } bundle agent init { files: # First we initialize some directories to iterate over and some files that # will be renamed during the test "$(G.testdir)/test/$(check.dirs)/incoming/$(check.files)" create => "true"; } bundle agent test { meta: "description" string => "Test that files can be renamed using regular expression matches from the promiser"; "test_soft_fail" string => "any", meta => { "CFE-2879" }; files: # We promise that the target is a copy of the source file Since preserve # is set to false, we expect the original permissions on the target file # to remain unchanged. "$(G.testdir)/test/$(check.dirs)/incoming/((?!.*renamed)[a-z]*)" rename => to( "$(G.testdir)/test/$(check.dirs)/incoming/$(match.1)_renamed" ); } body rename to(file) { newname => "$(file)"; } bundle agent check { vars: "dirs" slist => { "knuth", "lamport", "turing" }; "files" slist => { "one", "two", "three" }; # Append _renamed to each of the files "expected_files" slist => maplist( "$(this)_renamed", files ); "expected_paths" slist => { "$(G.testdir)/test/knuth/incoming/one_renamed", "$(G.testdir)/test/knuth/incoming/two_renamed", "$(G.testdir)/test/knuth/incoming/three_renamed", "$(G.testdir)/test/lamport/incoming/one_renamed", "$(G.testdir)/test/lamport/incoming/two_renamed", "$(G.testdir)/test/lamport/incoming/three_renamed", "$(G.testdir)/test/turing/incoming/one_renamed", "$(G.testdir)/test/turing/incoming/two_renamed", "$(G.testdir)/test/turing/incoming/three_renamed", }; classes: "all_expected_files_exist" expression => filesexist( @(expected_paths) ); methods: "Pass or Fail" usebundle => dcs_passif( "all_expected_files_exist", $(this.promise_filename)); reports: DEBUG|EXTRA:: "Expected path exists '$(expected_paths)'" if => fileexists( $(expected_paths) ); "Expected path MISSING '$(expected_paths)'" unless => fileexists( $(expected_paths) ); } cfengine-3.24.2/tests/acceptance/10_files/01_create/0000755000000000000000000000000015010704253021750 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/01_create/001.cf0000644000000000000000000000274215010704253022567 0ustar00rootroot00000000000000####################################################### # # Create a file, check defaults # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true"; } ####################################################### bundle agent check { vars: # We want default 0600, 1 link, zero size !windows:: "expect[permoct]" string => "600"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/008.cf0000644000000000000000000000326515010704253022577 0ustar00rootroot00000000000000####################################################### # # Create a file, check owners/mode, different order - assumption, this is run # by root (see notes below) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0644"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)); } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/010.cf0000644000000000000000000000317215010704253022565 0ustar00rootroot00000000000000####################################################### # # Create a file, check owner/group (single choice) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0644"; files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; owners => { "3" }; groups => { "3" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/mustache_create_by_default.cf0000644000000000000000000001153215010704253027616 0ustar00rootroot00000000000000############################################################################## # # template_method mustache and inline_mustache should create files if they are # absent by default. But file should not be created in the cases where promise # is not kept. # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ############################################################################## bundle agent init { vars: "range" slist => { expandrange("[1-8]", 1) }; files: "$(G.testfile).test_$(range)" delete => tidy; "$(G.testfile).valid_template" content => "Hello {{{name}}}"; "$(G.testfile).invalid_template" content => "Hello {{{name"; } ############################################################################## bundle agent test { meta: "description" -> { "ENT-4792" } string => "mustache and inline_mustache creates promiser by default"; vars: "d" data => '{ "name": "Lars" }'; files: # File should be created by default "$(G.testfile).test_1" template_method => "mustache", edit_template => "$(G.testfile).valid_template", if => fileexists("$(G.testfile).valid_template"), template_data => @(d); # File should not be created due to invalid template "$(G.testfile).test_2" template_method => "mustache", edit_template => "$(G.testfile).invalid_template", if => fileexists("$(G.testfile).invalid_template"), template_data => @(d); # File should be created even though template is invalid "$(G.testfile).test_3" create => "true", template_method => "mustache", edit_template => "$(G.testfile).invalid_template", if => fileexists("$(G.testfile).invalid_template"), template_data => @(d); # File should not be created even though template is valid "$(G.testfile).test_4" create => "false", template_method => "mustache", edit_template => "$(G.testfile).valid_template", if => fileexists("$(G.testfile).valid_template"), template_data => @(d); # File should be created by default "$(G.testfile).test_5" template_method => "inline_mustache", edit_template_string => readfile("$(G.testfile).valid_template"), if => fileexists("$(G.testfile).valid_template"), template_data => @(d); # File should not be created due to invalid template "$(G.testfile).test_6" template_method => "inline_mustache", edit_template_string => readfile("$(G.testfile).invalid_template"), if => fileexists("$(G.testfile).invalid_template"), template_data => @(d); # File should be created even though template is invalid "$(G.testfile).test_7" create => "true", template_method => "inline_mustache", edit_template_string => readfile("$(G.testfile).invalid_template"), if => fileexists("$(G.testfile).invalid_template"), template_data => @(d); # File should not be created even though template is valid "$(G.testfile).test_8" create => "false", template_method => "inline_mustache", edit_template_string => readfile("$(G.testfile).valid_template"), if => fileexists("$(G.testfile).valid_template"), template_data => @(d); } ############################################################################## bundle agent check { vars: # Get lists of successful / failed checks so we can report them "checks" slist => { expandrange("check_[1-8]", 1) }; "successful_checks" slist => sort(classesmatching("check_[1-8]"), "lex"); "failed_checks" slist => sort(difference("checks", "successful_checks"), "lex"); classes: "check_1" expression => fileexists("$(G.testfile).test_1"); "check_2" expression => not(fileexists("$(G.testfile).test_2")); "check_3" expression => fileexists("$(G.testfile).test_3"); "check_4" expression => not(fileexists("$(G.testfile).test_4")); "check_5" expression => fileexists("$(G.testfile).test_5"); "check_6" expression => not(fileexists("$(G.testfile).test_6")); "check_7" expression => fileexists("$(G.testfile).test_7"); "check_8" expression => not(fileexists("$(G.testfile).test_8")); "ok" expression => and("check_1", "check_2", "check_3", "check_4", "check_5", "check_6", "check_7", "check_8"); reports: DEBUG:: "'$(successful_checks)' succeded!"; "'$(failed_checks)' failed!"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/01_create/perms-mode.cf0000644000000000000000000000612415010704253024335 0ustar00rootroot00000000000000####################################################### # # Redmine #4791: body perms mode # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; vars: freebsd|solaris:: "modes" slist => { "1", "333", "100", "200", "777", "o=x", "ugo=wx", "u=x", "u=w", "ugo=rwx" }; !freebsd.!solaris:: "modes" slist => { "1", "333", "100", "200", "777", "1111", "1010", "13400", "22222", "o=x", "ugo=wx", "u=x", "u=w", "ugo=rwx" }; files: "$(G.testdir)/$(modes)" create => "true", perms => test_mode($(modes)); } body perms test_mode(m) { mode => "$(m)"; } bundle agent check { vars: "modes" slist => { @(test.modes) }; windows:: "win_r" string => "100444"; "win_w" string => "100666"; "expected" data => parsejson(' { "1": "$(win_r)", "333": "$(win_w)", "100": "$(win_r)", "200": "$(win_w)", "777": "$(win_w)", "1111": "$(win_r)", "1010": "$(win_r)", "13400": "$(win_r)", "22222": "$(win_r)", "o=x": "$(win_r)", "ugo=wx": "$(win_w)", "u=x": "$(win_r)", "u=w": "$(win_w)", "ugo=rwx": "$(win_w)", }'); freebsd|solaris:: "expected" data => parsejson(' { "1": "100001", "333": "100333", "100": "100100", "200": "100200", "777": "100777", "o=x": "100001", "ugo=wx": "100333", "u=x": "100100", "u=w": "100200", "ugo=rwx": "100777", }'); !freebsd.!solaris.!windows:: "expected" data => parsejson(' { "1": "100001", "333": "100333", "100": "100100", "200": "100200", "777": "100777", "1111": "101111", "1010": "101010", "13400": "103400", "22222": "102222", "o=x": "100001", "ugo=wx": "100333", "u=x": "100100", "u=w": "100200", "ugo=rwx": "100777", }'); any:: "actual[$(modes)]" string => filestat("$(G.testdir)/$(modes)", "modeoct"); "canonified[$(modes)]" string => canonify("$(modes)"); classes: "ok_$(canonified[$(modes)])" expression => strcmp("$(expected[$(modes)])", "$(actual[$(modes)])"); freebsd|solaris:: "ok" and => { "ok_1", "ok_333", "ok_100", "ok_200", "ok_777", classify("ok_o=x"), classify("ok_ugo=wx"), classify("ok_u=x"), classify("ok_u=w"), classify("ok_ugo=rwx") }; !freebsd.!solaris:: "ok" and => { "ok_1", "ok_333", "ok_100", "ok_200", "ok_777", "ok_1111", "ok_1010", "ok_13400", "ok_22222", classify("ok_o=x"), classify("ok_ugo=wx"), classify("ok_u=x"), classify("ok_u=w"), classify("ok_ugo=rwx") }; reports: DEBUG:: "Permission $(modes) worked, got $(expected[$(modes)])" if => "ok_$(canonified[$(modes)])"; "Permission $(modes) failed, expected $(expected[$(modes)]) != actual $(actual[$(modes)])" if => "!ok_$(canonified[$(modes)])"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/copy_and_purge.cf0000644000000000000000000000426215010704253025264 0ustar00rootroot00000000000000####################################################### # # Redmine #3429: copy and purge files and directories should purge empty directories too # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { } ####################################################### bundle agent init { methods: "1" usebundle => init1; "2" usebundle => init2; } bundle agent init1 { files: "$(G.testfile)" delete => init_delete; } bundle agent init2 { files: "$(G.testfile)/source/1/2/3/." create => "true"; "$(G.testfile)/dest/1/2/should-be-removed/3/." create => "true"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)/dest/." create => "true", depth_search => test_recurse("inf"), action => test_immediate, copy_from => test_sync("$(G.testfile)/source"); } body depth_search test_recurse(d) { depth => "$(d)"; xdev => "true"; } body action test_immediate { ifelapsed => "0"; } body copy_from test_sync(from) { source => "$(from)"; purge => "true"; preserve => "false"; type_check => "false"; compare => "digest"; } ####################################################### bundle agent check { classes: "ok_copy" expression => fileexists("$(G.testfile)/dest/1/2/3"); "ok_purge" not => fileexists("$(G.testfile)/dest/1/2/should-be-removed"); "bad_copy" not => fileexists("$(G.testfile)/dest/1/2/3"); "bad_purge" expression => fileexists("$(G.testfile)/dest/1/2/should-be-removed"); "ok" and => { ok_copy, ok_purge }; reports: DEBUG:: "The copy worked" if => "ok_copy"; "The purge worked" if => "ok_purge"; "The copy failed" if => "bad_copy"; "The purge failed" if => "bad_purge"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/content_create_by_default.cf0000644000000000000000000000612715010704253027463 0ustar00rootroot00000000000000############################################################################## # # content files promises shall create files by default unless `create => # "false"` is specified. # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ############################################################################## bundle agent init { vars: "delete_range" slist => { expandrange("[1-3]", 1) }; "create_range" slist => { expandrange("[4-6]", 1) }; files: "$(G.testfile)_$(delete_range)" delete => tidy; "$(G.testfile)_$(create_range)" create => "true"; } ############################################################################## bundle agent test { meta: "description" -> { "CFE-3916" } string => "files with content attribute shall create promiser by default"; files: # File should be created by default "$(G.testfile)_1" content => "Hello World!"; "$(G.testfile)_2" create => "true", content => "Hello World!"; "$(G.testfile)_3" create => "false", content => "Hello World!"; "$(G.testfile)_4" content => "Hello World!"; "$(G.testfile)_5" create => "true", content => "Hello World!"; "$(G.testfile)_6" create => "false", content => "Hello World!"; } ############################################################################## bundle agent check { vars: # Get lists of successful / failed checks so we can report them "checks" slist => { expandrange("check_[1-6]", 1) }; "successful_checks" slist => sort(classesmatching("check_[1-6]"), "lex"); "failed_checks" slist => sort(difference("checks", "successful_checks"), "lex"); classes: "check_1" expression => strcmp(readfile("$(G.testfile)_1"), "Hello World!"), if => fileexists("$(G.testfile)_1"); "check_2" expression => strcmp(readfile("$(G.testfile)_2"), "Hello World!"), if => fileexists("$(G.testfile)_2"); "check_3" expression => not(fileexists("$(G.testfile)_3")); "check_4" expression => strcmp(readfile("$(G.testfile)_4"), "Hello World!"), if => fileexists("$(G.testfile)_4"); "check_5" expression => strcmp(readfile("$(G.testfile)_5"), "Hello World!"), if => fileexists("$(G.testfile)_5"); "check_6" expression => strcmp(readfile("$(G.testfile)_6"), "Hello World!"), if => fileexists("$(G.testfile)_6"); "ok" expression => and("check_1", "check_2", "check_3", "check_4", "check_5", "check_6"); methods: "Pass/Fail" usebundle => dcs_passif("ok", $(this.promise_filename)), inherit => "true"; # We want dcs_passif to inhert bundle scoped classes from our check bundle reports: DEBUG:: "'$(successful_checks)' succeded!"; "'$(failed_checks)' failed!"; } cfengine-3.24.2/tests/acceptance/10_files/01_create/012.cf0000644000000000000000000000265315010704253022572 0ustar00rootroot00000000000000####################################################### # # Create a file, change perms # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } bundle agent test { vars: "mode" int => "0644"; files: "$(G.testfile)" create => "true", file_type => "fifo", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; owners => { "3" }; groups => { "3" }; } bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/01_create/011.cf0000644000000000000000000000243615010704253022570 0ustar00rootroot00000000000000####################################################### # # Create a fifo, check defaults # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } bundle agent test { vars: "mode" int => "0644"; files: "$(G.testfile)" create => "true", file_type => "fifo"; } bundle agent check { vars: !windows:: "expect[permoct]" string => "600"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/01_create/007.cf0000644000000000000000000000315615010704253022575 0ustar00rootroot00000000000000####################################################### # # Create a file, check owners/mode # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0644"; files: "$(G.testfile)" create => "true", perms => test_perms($(mode)); } body perms test_perms(m) { mode => "$(m)"; owners => { "0" }; groups => { "0" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/003.cf0000644000000000000000000000311315010704253022562 0ustar00rootroot00000000000000####################################################### # # Create a file, check initial permissions (odd mode) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0146"; files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/004.cf0000644000000000000000000000342015010704253022564 0ustar00rootroot00000000000000####################################################### # # Create a file, check initial permissions (strange mode) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "01010"; files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; } ####################################################### bundle agent check { vars: !freebsd.!solaris.!windows:: "expect[modeoct]" string => "[0-9]+$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); # # OS X refuses to open(2) file you have no permissions for (which is required for safe_chmod), # so this test is temporarily disabled there. # reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok|darwin:: "$(this.promise_filename) Pass"; not_ok&!darwin:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/005.cf0000644000000000000000000000340515010704253022570 0ustar00rootroot00000000000000####################################################### # # Create a file, check initial permissions (strange setgid mode) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "02001"; files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "[0-9]+$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); # # OS X refuses to open(2) file you have no permissions for (which is required for safe_chmod), # so this test is temporarily disabled there. # reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok|darwin:: "$(this.promise_filename) Pass"; not_ok&!darwin:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/cfengine_create_by_default.cf0000644000000000000000000000761315010704253027570 0ustar00rootroot00000000000000############################################################################## # # template_method cfengine should create files by default, unless # `create => "false"` is specified. # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ############################################################################## bundle agent init { vars: "range" slist => { expandrange("[1-4]", 1) }; files: "$(G.testfile).test_$(range)" delete => tidy; "$(G.testfile).test_5" create => "true"; "$(G.testfile).valid_template" content => "[%CFEngine BEGIN %] I have $(const.dollar)(sys.cpus) CPU's! [%CFEngine END %] "; "$(G.testfile).invalid_template" content => "[%CFEngine BEGIN %] I have $(const.dollar)(sys.cpus) CPU's! [%CFEngine END %) "; } ############################################################################## bundle agent test { meta: "description" -> { "CFE-3955" } string => "template_method cfengine creates promiser by default"; "test_soft_fail" string => "windows", meta => { "ENT-10257" }; files: # File should be created by default and rendered with content "$(G.testfile).test_1" template_method => "cfengine", edit_template => "$(G.testfile).valid_template", if => fileexists("$(G.testfile).valid_template"); # File should not be created due to invalid template "$(G.testfile).test_2" template_method => "cfengine", edit_template => "$(G.testfile).invalid_template", if => fileexists("$(G.testfile).invalid_template"); # File should be created even though template is invalid "$(G.testfile).test_3" create => "true", template_method => "cfengine", edit_template => "$(G.testfile).invalid_template", if => fileexists("$(G.testfile).invalid_template"); # File should not be created even though template is valid "$(G.testfile).test_4" create => "false", template_method => "cfengine", edit_template => "$(G.testfile).valid_template", if => fileexists("$(G.testfile).valid_template"); # File should be rendered with content, since it already exists "$(G.testfile).test_5" create => "false", template_method => "cfengine", edit_template => "$(G.testfile).valid_template", if => fileexists("$(G.testfile).valid_template"); } ############################################################################## bundle agent check { vars: # Get lists of successful / failed checks so we can report them "checks" slist => { expandrange("check_[1-5]", 1) }; "successful_checks" slist => sort(classesmatching("check_[1-5]"), "lex"); "failed_checks" slist => sort(difference("checks", "successful_checks"), "lex"); classes: "check_1" expression => regcmp("I have [0-9]+ CPU's!", readfile("$(G.testfile).test_1")), if => fileexists("$(G.testfile).test_1"); "check_2" expression => not(fileexists("$(G.testfile).test_2")); "check_3" expression => fileexists("$(G.testfile).test_3"); "check_4" expression => not(fileexists("$(G.testfile).test_4")); "check_5" expression => regcmp("I have [0-9]+ CPU's!", readfile("$(G.testfile).test_5")), if => fileexists("$(G.testfile).test_5"); "ok" expression => and("check_1", "check_2", "check_3", "check_4", "check_5"); reports: DEBUG:: "'$(successful_checks)' succeded!"; "'$(failed_checks)' failed!"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/01_create/006.cf0000644000000000000000000000313515010704253022571 0ustar00rootroot00000000000000####################################################### # # Create a file, check initial permissions (strange setuid mode) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "04777"; files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; } ####################################################### bundle agent check { vars: !windows:: "expect[modeoct]" string => "[0-9]+$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/009.cf0000644000000000000000000000371115010704253022574 0ustar00rootroot00000000000000####################################################### # # Create a file, check owners/mode, different order - assumption, this is run # by root (see notes below) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0644"; files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; # In the POSIX model, one cannot create a file for another user, one can only # create a file as you, and then change owners. This test file will be created # by root, but then changed to sys - and thus the promise to be owned by sys # is kept. owners => { "3", "1" }; groups => { "3", "1" }; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/002.cf0000644000000000000000000000312315010704253022562 0ustar00rootroot00000000000000####################################################### # # Create a file, check initial permissions (predictable mode) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "mode" int => "0641"; files: "$(G.testfile)" create => "true", perms => test_perms; } body perms test_perms { mode => "$(test.mode)"; } ####################################################### bundle agent check { vars: !windows:: "expect[permoct]" string => "$(test.mode)"; any:: "expect[nlink]" string => "1"; "expect[uid]" string => "\d+"; "expect[gid]" string => "\d+"; "expect[size]" string => "0"; "fields" slist => getindices("expect"); "result[$(fields)]" string => filestat("$(G.testfile)", "$(fields)"); classes: "not_ok" not => regcmp("$(expect[$(fields)])", "$(result[$(fields)])"); reports: DEBUG:: "expected: $(fields) = '$(expect[$(fields)])'"; "got: $(fields) = '$(result[$(fields)])'"; !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/01_create/directory_with_trailing_slash.cf0000644000000000000000000000312015010704253030400 0ustar00rootroot00000000000000####################################################### # # Redmine#3905: Create a directory, set permissions using a trailing slash # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; vars: "mode" string => "751"; methods: "1" usebundle => test1; # create the directory "1" usebundle => test2($(mode)); # promise the directory with a trailing slash } bundle agent test1 { files: "$(G.testfile)/." create => "true", perms => test_perms("700"); } bundle agent test2(mode) { files: "$(G.testfile)/" perms => test_perms($(mode)); } body perms test_perms(m) { mode => "$(m)"; } ####################################################### bundle agent check { vars: "result" string => filestat($(G.testfile), "permoct"); classes: "ok" expression => strcmp($(test.mode), "$(result)"); reports: DEBUG:: "expected: '$(test.mode)'"; "got: '$(result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/copy_from_this_promiser.cf0000755000000000000000000000460615010704253025474 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "ROOT" string => "/tmp/CFE-2489"; "SOURCE" string => "$(ROOT)/SOURCE"; "use_bundles" slist => { "bundle_uses_copy_from_without_param", "bundle_uses_copy_from_with_param" }; files: "$(init.ROOT)/$(use_bundles)/." create => "true"; # Setup source files to copy_from "$(init.ROOT)/SOURCE/$(init.ROOT)/$(use_bundles)/file.txt" create => "true"; } bundle agent test { meta: "description" -> { "CFE-2489" } string => "Test that this.promiser holds the correct value in a copy_from body that uses parameters"; "test_soft_fail" string => "any", meta => { "CFE-2489" }; methods: "XXX" usebundle => $(init.use_bundles); } bundle agent bundle_uses_copy_from_without_param { files: # As expected, when a copy_from promise uses a non-parameterized body the # this.promiser context is as expected (points to the promised file). "$(init.ROOT)/$(this.bundle)/file.txt" copy_from => my_copy_without_param(); } body copy_from my_copy_without_param() { source => "$(init.ROOT)/SOURCE/$(this.promiser)"; compare => "digest"; } bundle agent bundle_uses_copy_from_with_param { files: # Oddly, when a copy_from promise uses a parameterized body, the # this.promiser context does not contain the promised file, instead, it # seems to contain the parents promiser. So, in this case, it wrongly gets # XXX from the 'test' bundle. "$(init.ROOT)/$(this.bundle)/file.txt" copy_from => my_copy_with_param( "use_of_paramater_should_not_change_this_promiser" ); } body copy_from my_copy_with_param(root) { source => "$(init.ROOT)/SOURCE/$(this.promiser)"; compare => "digest"; } bundle agent check { classes: "pass" expression => filesexist( '[ "$(init.ROOT)/bundle_uses_copy_from_with_param/file.txt", "$(init.ROOT)/bundle_uses_copy_from_without_param/file.txt" ]' ); reports: "$(this.promise_filename) $(with)" with => ifelse( "pass", "Pass", "FAIL"); } bundle agent __main__ { methods: "init"; "test"; "check"; } cfengine-3.24.2/tests/acceptance/10_files/unsafe/0000755000000000000000000000000015010704253021466 5ustar00rootroot00000000000000multiple-owner-candidates-first-found-user-perms-if-no-listed-candidate-matches.cf0000644000000000000000000000277015010704253041171 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/unsafebody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: # Username lengths up to 8 chars because of AIX and HP-UX limitations "absent_users" slist => { "abs_us_1", "abs_us_2" }; "present_users" slist => { "pr_us_1", "pr_us_2" }; "users" slist => { @(absent_users), @(present_users), }; users: "$(absent_users)" policy => "absent"; "$(present_users)" policy => "present"; files: "$(G.testfile)" create => "true", perms => o("root"); } bundle agent test { meta: "description" string => "When a list of perms owners is provided if the perms do not match at least one of the owners then the perms are set to the first present owner."; files: "$(G.testfile)" perms => o( @(init.users) ); } bundle agent check { vars: "observed_uid" string => filestat($(G.testfile), uid); "desired_uid" int => getuid("pr_us_1"); reports: "$(this.promise_filename) Pass" if => strcmp( $(observed_uid), $(desired_uid) ); "$(this.promise_filename) FAIL" if => not( strcmp( $(observed_uid), $(desired_uid) ) ); } bundle agent cleanup { users: "$(init.users)" policy => "absent"; } body perms o(u) # @brief Set the file's owner # @param u The username of the new owner { owners => { "$(u)" }; } multiple-group-candidates-first-found-group-perms-if-no-listed-candidate-matches.cf0000644000000000000000000000441415010704253041346 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/unsafebody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent _group_state(group, state) { meta: # no groupadd on windows "test_skip_unsupported" string => "windows"; vars: !aix:: "groupadd" string => "/usr/sbin/groupadd"; "groupdel" string => "/usr/sbin/groupdel"; aix:: "groupadd" string => "/usr/bin/mkgroup"; "groupdel" string => "/usr/sbin/rmgroup"; classes: "_have_group" expression => groupexists( $(group) ); "_want_$(state)" expression => "any"; commands: !_have_group._want_present:: "$(groupadd)" args => "$(group)"; _have_group._want_absent:: "$(groupdel)" args => "$(group)"; } bundle agent init { vars: # Group lengths up to 8 chars because of AIX and HP-UX limitations "absent_groups" slist => { "abs_gr_1", "abs_gr_2" }; "present_groups" slist => { "pr_gr_1", "pr_gr_2" }; "groups" slist => { @(absent_groups), @(present_groups), }; methods: "Ensure Groups Absent" usebundle => _group_state( $(absent_groups), "absent" ); "Ensure Groups Present" usebundle => _group_state( $(present_groups), "present" ); files: "$(G.testfile)" create => "true", perms => g("root"); } bundle agent test { meta: "description" string => "When a list of perms owners is provided if the perms do not match at least one of the owners then the perms are set to the first present owner."; files: "$(G.testfile)" perms => g( @(init.groups) ); } bundle agent check { vars: "observed_gid" string => filestat($(G.testfile), gid); "desired_gid" int => getgid("pr_gr_1"); reports: "$(this.promise_filename) Pass" if => strcmp( $(observed_gid), $(desired_gid) ); "$(this.promise_filename) FAIL" if => not( strcmp( $(observed_gid), $(desired_gid) ) ); } bundle agent cleanup { methods: "Ensure Groups Absent" usebundle => _group_state( $(init.groups), "absent" ); } body perms g(g) # @brief Set the file's group to the first presnet group # @param g A list of candidate groups for the file { groups => { "$(g)" }; } cfengine-3.24.2/tests/acceptance/10_files/unsafe/can_set_sticky_bits_with_nonroot_owner_and_group.cf0000644000000000000000000000540015010704253034103 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "users" slist => { "user01", "user02" }; "modes" slist => { "2700", "2750", "2755", "2770", "2771", "2775", "2751", }; users: "$(users)" policy => "present"; } bundle agent cleanup { users: "$(init.users)" policy => "absent", comment => "Purge the users we created to test with"; } ####################################################### bundle agent test { meta: "description" string => "Test that sgid can be set when ownership is non root"; "test_skip_unsupported" string => "windows"; "test_skip_needs_work" string => "!has_stat", meta => { "redmine7989", "zendesk2797" }; files: "$(G.testdir)/test_sgid/$(init.modes)/." create => "true", perms => test_perms( $(init.modes), "user01", "user02"), classes => scoped_classes_generic("namespace", "file_$(init.modes)"), comment => "Make sure a directory named for each desired mode we want to test exists."; } body perms test_perms(m, o, g) { mode => "$(m)"; owners => { "$(o)" }; groups => { "$(g)" }; } ####################################################### bundle agent check { vars: # We expect to find an ok_ prefixed class for each of the modes defined in # init. "expected_classes" slist => maplist("ok_$(this)", @(init.modes)); # Get the octal mode for each of the files "result_permoct_$(init.modes)" string => execresult('$(G.stat) -c %a $(G.testdir)/test_sgid/$(init.modes)', "useshell"), if => "file_$(init.modes)_reached"; DEBUG|DEBUG_check:: # We collect up the classes that match our expected pattern for debug # reports "classes" slist => classesmatching("ok_.*"); classes: # Define an ok_ prefixed class for each of the modes defined in init if it # matches what we observed with stat. "ok_$(init.modes)" expression => strcmp("$(init.modes)", "$(result_permoct_$(init.modes))"); # And here we define the class to pass or fail the test. "ok" and => { @(expected_classes) }; "not_ok" not => "ok"; reports: DEBUG|DEBUG_check:: "Found '$(G.testdir)/test_sgid/$(init.modes)' = '$(result_permoct_$(init.modes))' expected '$(init.modes)'"; "Found class: '$(classes)')"; ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } agent_control_files_single_copy_does_not_apply_to_nonmatching_files.cf0000644000000000000000000000247415010704253036432 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body agent control { files_single_copy => { @(def.control_agent_files_single_copy) }; } # NOTE that def.control_agent_files_single_copy DOES NOT EXIST bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy does not prevent file patterns that do not match from being copied multiple times."; "test_soft_fail" string => "any", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/two", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/0000755000000000000000000000000015010704253023147 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/001.cf0000644000000000000000000000311415010704253023760 0ustar00rootroot00000000000000####################################################### # # Delete a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/619.cf0000644000000000000000000000370415010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns (different order than original) # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/615.cf0000644000000000000000000000370615010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines (different order than in original) # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: " Three potatoe" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/138.cf0000644000000000000000000000377515010704253024010 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/345.cf0000644000000000000000000000343315010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "true", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/218.cf0000644000000000000000000000356515010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way (different order than original) # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "BEGIN", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/203.cf0000644000000000000000000000340515010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a group of three lines at once # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "header header BEGIN trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/623.cf0000644000000000000000000000402015010704253023767 0ustar00rootroot00000000000000####################################################### # # Don't delete a line, set a class # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body classes test_class(a) { promise_kept => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/224.cf0000644000000000000000000000373515010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/540.cf0000644000000000000000000000373315010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "eade", "EGI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/026.cf0000644000000000000000000000346115010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "header", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/302.cf0000644000000000000000000000353615010704253023774 0ustar00rootroot00000000000000####################################################### # # Don't delete a line # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/428.cf0000644000000000000000000000367415010704253024010 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/019.cf0000644000000000000000000000323215010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns (different order than original) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/415.cf0000644000000000000000000000354415010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines (different order than in original) # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: " Three potatoe" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/225.cf0000644000000000000000000000411515010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: # Note - regex doesn't qualify for "starts_with"! "tstr" slist => { " Three potatoe", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/439.cf0000644000000000000000000000370315010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three", "GI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/245.cf0000644000000000000000000000345515010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "true", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/016.cf0000644000000000000000000000314715010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes (different order than in original) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "\s+Three.*"; "BEGIN"; "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/438.cf0000644000000000000000000000363415010704253024005 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/604.cf0000644000000000000000000000362615010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a group of lines at once, different way # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n) Four" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/625.cf0000644000000000000000000000410415010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", " Five", " Two", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/035.cf0000644000000000000000000000340215010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/632.cf0000644000000000000000000000406015010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*GI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/222.cf0000644000000000000000000000347615010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line, set a class # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body classes test_class(a) { promise_repaired => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/405.cf0000644000000000000000000000330315010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "BEGIN", " Three potatoe", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/126.cf0000644000000000000000000000411015010704253023765 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "header", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/119.cf0000644000000000000000000000371015010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns (different order than original) # Region editing, include_start_delimiter and include_end_delimiter # Second edit destroys the region and therefore the third edit will not be possible. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; delete_lines: # Second edit destroys the region "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/122.cf0000644000000000000000000000355315010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a line, set a class # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body classes test_class(a) { promise_repaired => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/539.cf0000644000000000000000000000371215010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three", "GI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/538.cf0000644000000000000000000000364315010704253024006 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/229.cf0000644000000000000000000000377015010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/509.cf0000644000000000000000000000343415010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { "BEGIN", " Three potatoe", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/329.cf0000644000000000000000000000375015010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/331.cf0000644000000000000000000000370115010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/104.cf0000644000000000000000000000350715010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a group of lines at once, different way # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "header header trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "BEGIN$(const.n)$(str)$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/040.cf0000644000000000000000000000343615010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "eade", "EGI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/008.cf0000644000000000000000000000314615010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { "BEGIN", " Three potatoe", "END" }; delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/602.cf0000644000000000000000000000401415010704253023767 0ustar00rootroot00000000000000####################################################### # # Don't delete a line # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/102.cf0000644000000000000000000000363315010704253023770 0ustar00rootroot00000000000000####################################################### # # Don't delete a line # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/433.cf0000644000000000000000000000373315010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*eade.*", ".*EGI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/010.cf0000644000000000000000000000317215010704253023764 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/646.cf0000644000000000000000000000347015010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/337.cf0000644000000000000000000000376015010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/323.cf0000644000000000000000000000354215010704253023774 0ustar00rootroot00000000000000####################################################### # # Don't delete a line, set a class # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body classes test_class(a) { promise_kept => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/407.cf0000644000000000000000000000351115010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "\s+Three.*" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/241.cf0000644000000000000000000000370715010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/136.cf0000644000000000000000000000403715010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*C.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/217.cf0000644000000000000000000000370515010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way (different order than in original) # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/107.cf0000644000000000000000000000400415010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes # Region editing, include_start_delimiter and include_end_delimiter # Region is destroyed by first edit # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: # Region is destroyed by first edit "BEGIN" select_region => test_select; "\s+Three.*" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/332.cf0000644000000000000000000000375615010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*GI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/419.cf0000644000000000000000000000353115010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns (different order than original) # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/342.cf0000644000000000000000000000373315010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/235.cf0000644000000000000000000000375415010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/239.cf0000644000000000000000000000376715010704253024013 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three", "GI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/440.cf0000644000000000000000000000372415010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "eade", "EGI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/308.cf0000644000000000000000000000347315010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way # select_region, only include_start_delimiter # This will only work for the first match, the same reason # as 306 and 307. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/446.cf0000644000000000000000000000332715010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/101.cf0000644000000000000000000000354215010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a line # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/518.cf0000644000000000000000000000347415010704253024006 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way (different order than original) # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "BEGIN", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/417.cf0000644000000000000000000000362515010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way (different order than in original) # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/507.cf0000644000000000000000000000350015010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "\s+Three.*" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/636.cf0000644000000000000000000000417015010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Two regions - Only the first region is going to be selected # select_region, doesn't include header or trailer # Notice that the list is expanded in one step, not iterated # over. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*C.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/243.cf0000644000000000000000000000375515010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "C" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/339.cf0000644000000000000000000000374715010704253024012 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three", "GI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/017.cf0000644000000000000000000000322015010704253023765 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way (different order than in original) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "^\s+Three.*$"; # Anchors should make no difference "BEGIN"; "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/528.cf0000644000000000000000000000370315010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/012.cf0000644000000000000000000000310215010704253023757 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => "BEGIN Three potatoe END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/611.cf0000644000000000000000000000366415010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/127.cf0000644000000000000000000000377515010704253024006 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/307.cf0000644000000000000000000000343415010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes # select_region, only include_start_delimiter # As with 306, this will not work since only the first line # will be selected. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "\s+Three.*" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/212.cf0000644000000000000000000000345315010704253023772 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe BEGIN END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/534.cf0000644000000000000000000000363715010704253024005 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/441.cf0000644000000000000000000000362315010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/426.cf0000644000000000000000000000374715010704253024007 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "header", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/530.cf0000644000000000000000000000372715010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/011.cf0000644000000000000000000000321215010704253023760 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/637.cf0000644000000000000000000000423615010704253024005 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/139.cf0000644000000000000000000000404415010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three", "GI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/700.cf0000644000000000000000000000115415010704253023770 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { files: "$(G.testfile)" create => "true", file_type => "fifo", edit_line => init_delete("foo"); } bundle edit_line init_delete(str) { delete_lines: "$(str)"; } bundle agent check { classes: "exists" expression => fileexists("$(G.testfile)"); "ok" not => "exists"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/437.cf0000644000000000000000000000371415010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/007.cf0000644000000000000000000000310415010704253023765 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN"; "\s+Three.*"; "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/616.cf0000644000000000000000000000371615010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes (different order than in original) # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "\s+Three.*" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/334.cf0000644000000000000000000000367415010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/537.cf0000644000000000000000000000372315010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/045.cf0000644000000000000000000000303715010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => " One potato Two potato Three potatoe"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/609.cf0000644000000000000000000000361615010704253024005 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { "BEGIN", " Three potatoe", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/105.cf0000644000000000000000000000367115010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist # Region editing, include_start_delimiter and include_end_delimiter # Notice that this is a misinterpretation of our language, once the # start_delimiter is deleted, the region will not be matched again. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "BEGIN", " Three potatoe", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/036.cf0000644000000000000000000000341015010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*C.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/347.cf0000644000000000000000000000371315010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@{test.tstr}"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/504.cf0000644000000000000000000000335515010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a group of lines at once, different way # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN Three potatoe END trailer END trailer"; "expected" string => "header BEGIN header trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "BEGIN$(const.n)$(str)$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/409.cf0000644000000000000000000000344515010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { "BEGIN", " Three potatoe", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/031.cf0000644000000000000000000000334715010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/312.cf0000644000000000000000000000343315010704253023771 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe BEGIN END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/112.cf0000644000000000000000000000353015010704253023765 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe BEGIN END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/640.cf0000644000000000000000000000424615010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "eade", "EGI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/030.cf0000644000000000000000000000343215010704253023765 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/115.cf0000644000000000000000000000401115010704253023763 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines (different order than in original) # Region editing, include_start_delimiter and include_end_delimiter # Second edit destroys the region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: # Second edit destroys the region " Three potatoe" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/443.cf0000644000000000000000000000367115010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "C" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/444.cf0000644000000000000000000000370715010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/238.cf0000644000000000000000000000372015010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/635.cf0000644000000000000000000000403715010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/641.cf0000644000000000000000000000377215010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/204.cf0000644000000000000000000000342115010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a group of lines at once, different way # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "header header BEGIN trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/436.cf0000644000000000000000000000367615010704253024011 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*C.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/325.cf0000644000000000000000000000407515010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: # Note - regex doesn't qualify for "starts_with"! "tstr" slist => { " Three potatoe", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/326.cf0000644000000000000000000000401315010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "header", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/118.cf0000644000000000000000000000375215010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way (different order than original) # Region editing, include_start_delimiter and include_end_delimiter # Second edit destroys the region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "BEGIN", "END" }; delete_lines: # Second edit destroys the region "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/310.cf0000644000000000000000000000350015010704253023762 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns # select_region, only include_start_delimiter # As with 309.cf "END" will not be deleted because is not part of the # selected region. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/628.cf0000644000000000000000000000404515010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/501.cf0000644000000000000000000000341015010704253023764 0ustar00rootroot00000000000000####################################################### # # Delete a line # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/626.cf0000644000000000000000000000427115010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "header", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/135.cf0000644000000000000000000000403115010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/113.cf0000644000000000000000000000355215010704253023772 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n)BEGIN$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/445.cf0000644000000000000000000000337515010704253024005 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "true", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/447.cf0000644000000000000000000000364715010704253024011 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@{test.tstr}"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/327.cf0000644000000000000000000000370015010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/413.cf0000644000000000000000000000341115010704253023767 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n)BEGIN$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/335.cf0000644000000000000000000000373415010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/320.cf0000644000000000000000000000360615010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns (different order than original) # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/042.cf0000644000000000000000000000340115010704253023764 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/432.cf0000644000000000000000000000371215010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*GI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/140.cf0000644000000000000000000000406515010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "eade", "EGI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/546.cf0000644000000000000000000000333615010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/526.cf0000644000000000000000000000364015010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Double (nested) header/trailer # No line will be removed. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "header", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/418.cf0000644000000000000000000000350515010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way (different order than original) # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "BEGIN", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/246.cf0000644000000000000000000000341315010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/522.cf0000644000000000000000000000342115010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a line, set a class # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body classes test_class(a) { promise_repaired => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/410.cf0000644000000000000000000000347115010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/511.cf0000644000000000000000000000350015010704253023765 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/047.cf0000644000000000000000000000336215010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@{test.tstr}"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), not_matching => "false"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/025.cf0000644000000000000000000000354315010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: # Note - regex doesn't qualify for "starts_with"! "tstr" slist => { " Three potatoe", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/305.cf0000644000000000000000000000356515010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist # select_region, only include_start_delimiter # Notice that after the first iteration the region will never # be matched again because the start marker does not exist anymore. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "BEGIN", " Three potatoe", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/618.cf0000644000000000000000000000366015010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way (different order than original) # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "BEGIN", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/613.cf0000644000000000000000000000373515010704253024002 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # Two matching regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe break Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe break Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n) Four" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/023.cf0000644000000000000000000000321015010704253023761 0ustar00rootroot00000000000000####################################################### # # Don't delete a line, set a class # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"); } body classes test_class(a) { promise_kept => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/103.cf0000644000000000000000000000346515010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a contiguous group of three lines # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "header header trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => "BEGIN Three potatoe END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/003.cf0000644000000000000000000000303715010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a contiguous group of three lines # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "header header trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => "BEGIN Three potatoe END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/125.cf0000644000000000000000000000417215010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: # Note - regex doesn't qualify for "starts_with"! "tstr" slist => { " Three potatoe", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/215.cf0000644000000000000000000000362415010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines (different order than in original) # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: " Three potatoe" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/435.cf0000644000000000000000000000367015010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/403.cf0000644000000000000000000000332215010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a group of three lines at once, should do nothing because # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => "BEGIN Three potatoe END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/319.cf0000644000000000000000000000356715010704253024010 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns (different order than original) # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/510.cf0000644000000000000000000000346015010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/306.cf0000644000000000000000000000343315010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines # select_region, only include_start_delimiter # This way of selecting lines does not work. Only the # first line will be considered. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: " Three potatoe" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/038.cf0000644000000000000000000000334615010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/129.cf0000644000000000000000000000404515010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/select_end_match_eof_true.cf0000644000000000000000000000327515010704253030641 0ustar00rootroot00000000000000####################################################### # # Try to delete a region where select_end does not match # end region and 'select_end_match_eof' is set to false. # CFE-2263 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN One potato Two potato Three potatoe Four END trailer"; "expected" string => "header BEGIN"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; # anchored regex doesn't match due to whitespace, but # 'select_end_match_eof' is true. select_end_match_eof => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/341.cf0000644000000000000000000000366715010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/524.cf0000644000000000000000000000366015010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/004.cf0000644000000000000000000000307215010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a contiguous group of three lines, different way # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "header header trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "BEGIN$(const.n)$(str)$(const.n)END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/425.cf0000644000000000000000000000374115010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/131.cf0000644000000000000000000000377615010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/427.cf0000644000000000000000000000363415010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/117.cf0000644000000000000000000000407215010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way (different order than in original) # Region editing, include_start_delimiter and include_end_delimiter # Second edit destroys the region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: # Second edit destroys the region "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/536.cf0000644000000000000000000000370515010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*C.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/005.cf0000644000000000000000000000300415010704253023762 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "BEGIN", " Three potatoe", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/041.cf0000644000000000000000000000333515010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/232.cf0000644000000000000000000000377615010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*GI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/330.cf0000644000000000000000000000376415010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/114.cf0000644000000000000000000000361315010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist (different order than in original) # Region editing, include_start_delimiter and include_end_delimiter # Second edit destroys the region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: # Second edit destroys the region "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/527.cf0000644000000000000000000000364315010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/210.cf0000644000000000000000000000355115010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/141.cf0000644000000000000000000000376415010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/420.cf0000644000000000000000000000355015010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns (different order than original) # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/230.cf0000644000000000000000000000400415010704253023763 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/201.cf0000644000000000000000000000346515010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a line # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/015.cf0000644000000000000000000000313715010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines (different order than in original) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: " Three potatoe"; "BEGIN"; "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/532.cf0000644000000000000000000000372115010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*GI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/111.cf0000644000000000000000000000400415010704253023761 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns # Region editing, include_start_delimiter and include_end_delimiter # Region is destroyed by first edit # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: # Region is destroyed by first edit "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/106.cf0000644000000000000000000000377415010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines # Region editing, include_start_delimiter and include_end_delimiter # Region is destroyed by first edit # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: # Region is destroyed by first edit "BEGIN" select_region => test_select; " Three potatoe" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/416.cf0000644000000000000000000000355415010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes (different order than in original) # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "\s+Three.*" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/431.cf0000644000000000000000000000363515010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/404.cf0000644000000000000000000000335515010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a group of lines at once, different way, should do nothing because # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "BEGIN$(const.n)$(str)$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/529.cf0000644000000000000000000000371315010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/029.cf0000644000000000000000000000341615010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/237.cf0000644000000000000000000000400015010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/311.cf0000644000000000000000000000345115010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns # select_region, only include_start_delimiter # Same as with 310 and 309, "END" is not deleted. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/338.cf0000644000000000000000000000370015010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/545.cf0000644000000000000000000000335515010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header One potato Two potato Three potatoe trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "true", select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/044.cf0000644000000000000000000000342115010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/505.cf0000644000000000000000000000327215010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "BEGIN", " Three potatoe", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/046.cf0000644000000000000000000000304115010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "false"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/142.cf0000644000000000000000000000403015010704253023764 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/240.cf0000644000000000000000000000401015010704253023761 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "eade", "EGI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/412.cf0000644000000000000000000000336715010704253024000 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe BEGIN END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/535.cf0000644000000000000000000000367715010704253024012 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/006.cf0000644000000000000000000000307415010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN"; " Three potatoe"; "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/134.cf0000644000000000000000000000377115010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/009.cf0000644000000000000000000000314615010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { "BEGIN", " Three potatoe", "END" }; delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/205.cf0000644000000000000000000000335215010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/208.cf0000644000000000000000000000364215010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/223.cf0000644000000000000000000000356215010704253023775 0ustar00rootroot00000000000000####################################################### # # Don't delete a line, set a class # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body classes test_class(a) { promise_kept => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/525.cf0000644000000000000000000000404015010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: # Note - regex doesn't qualify for "starts_with"! "tstr" slist => { " Three potatoe", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/601.cf0000644000000000000000000000356215010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line # Two regions - Only the first region will be selected. # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/643.cf0000644000000000000000000000415215010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Two regions - Only one region is selected # select_region, doesn't include header or trailer # Notice that the list is evaluated in one step, not in # several iterations. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "C" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/516.cf0000644000000000000000000000354315010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes (different order than in original) # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "\s+Three.*" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/034.cf0000644000000000000000000000334215010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/617.cf0000644000000000000000000000376015010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way (different order than in original) # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/429.cf0000644000000000000000000000370415010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/124.cf0000644000000000000000000000401215010704253023764 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/424.cf0000644000000000000000000000365115010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/515.cf0000644000000000000000000000353315010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines (different order than in original) # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: " Three potatoe" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/202.cf0000644000000000000000000000355615010704253023775 0ustar00rootroot00000000000000####################################################### # # Don't delete a line # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/442.cf0000644000000000000000000000366715010704253024006 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/207.cf0000644000000000000000000000357115010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "\s+Three.*" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/512.cf0000644000000000000000000000336415010704253023776 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe BEGIN END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/304.cf0000644000000000000000000000336615010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a group of lines at once, different way # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "BEGIN$(const.n)$(str)$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/633.cf0000644000000000000000000000425515010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*eade.*", ".*EGI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/024.cf0000644000000000000000000000336315010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/645.cf0000644000000000000000000000353615010704253024006 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "true", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/346.cf0000644000000000000000000000337315010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/644.cf0000644000000000000000000000423115010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/244.cf0000644000000000000000000000377315010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/301.cf0000644000000000000000000000344515010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a line # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/514.cf0000644000000000000000000000333515010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist (different order than in original) # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/622.cf0000644000000000000000000000371215010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line, set a class # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body classes test_class(a) { promise_repaired => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/033.cf0000644000000000000000000000344515010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*eade.*", ".*EGI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/322.cf0000644000000000000000000000345615010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line, set a class # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body classes test_class(a) { promise_repaired => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/220.cf0000644000000000000000000000363015010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns (different order than original) # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/430.cf0000644000000000000000000000372015010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/324.cf0000644000000000000000000000371515010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/627.cf0000644000000000000000000000400215010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/123.cf0000644000000000000000000000363715010704253023777 0ustar00rootroot00000000000000####################################################### # # Don't delete a line, set a class # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body classes test_class(a) { promise_kept => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/605.cf0000644000000000000000000000401715010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist # Two regions - Only first region is selected # select_region, doesn't include header or trailer # Notice that neither "BEGIN" nor "END" are included in # the selected region, therefore only "Three potatoe" is # deleted. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "BEGIN", " Three potatoe", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/014.cf0000644000000000000000000000304715010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist (different order than in original) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/303.cf0000644000000000000000000000333315010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a group of three lines at once # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN Three potatoe END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => "BEGIN Three potatoe END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/638.cf0000644000000000000000000000400515010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/314.cf0000644000000000000000000000362515010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist (different order than in original) # select_region, only include_start_delimiter # "END" is not going to be deleted, this time because "BEGIN" is deleted # before, therefore the region will not be selected when "END" is used. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/519.cf0000644000000000000000000000352015010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns (different order than original) # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/116.cf0000644000000000000000000000402115010704253023765 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes (different order than in original) # Region editing, include_start_delimiter and include_end_delimiter # Second edit destroys the region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: # Second edit destroys the region "\s+Three.*" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/145.cf0000644000000000000000000000352415010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "true", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/502.cf0000644000000000000000000000350115010704253023766 0ustar00rootroot00000000000000####################################################### # # Don't delete a line # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/234.cf0000644000000000000000000000371415010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/032.cf0000644000000000000000000000342415010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*GI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/110.cf0000644000000000000000000000376415010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns # Region editing, include_start_delimiter and include_end_delimiter # Region is destroyed by first edit # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; delete_lines: # Region is destroyed by first edit "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/213.cf0000644000000000000000000000347515010704253023777 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n)BEGIN$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/227.cf0000644000000000000000000000372015010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/226.cf0000644000000000000000000000403315010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "header", " Two.*", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/401.cf0000644000000000000000000000340115010704253023763 0ustar00rootroot00000000000000####################################################### # # Delete a line # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/108.cf0000644000000000000000000000405515010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way # Region editing, include_start_delimiter and include_end_delimiter # Region is destroyed by first edit # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: # Region is destroyed by first edit "BEGIN" select_region => test_select; "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/506.cf0000644000000000000000000000347015010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; " Three potatoe" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/531.cf0000644000000000000000000000364415010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/612.cf0000644000000000000000000000372715010704253024002 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # Two matching regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe break Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe break Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe Four"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/209.cf0000644000000000000000000000352515010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { "BEGIN", " Three potatoe", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/642.cf0000644000000000000000000000403615010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/543.cf0000644000000000000000000000370015010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "C" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/520.cf0000644000000000000000000000353715010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns (different order than original) # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/216.cf0000644000000000000000000000363415010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes (different order than in original) # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "\s+Three.*" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/414.cf0000644000000000000000000000334615010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist (different order than in original) # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/147.cf0000644000000000000000000000401015010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@{test.tstr}"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/340.cf0000644000000000000000000000377015010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "eade", "EGI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/647.cf0000644000000000000000000000401015010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@{test.tstr}"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/542.cf0000644000000000000000000000367615010704253024007 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/639.cf0000644000000000000000000000405015010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "hre", "GI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/620.cf0000644000000000000000000000372015010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns (different order than original) # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/002.cf0000644000000000000000000000320515010704253023762 0ustar00rootroot00000000000000####################################################### # # Don't delete a line # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/544.cf0000644000000000000000000000371615010704253024004 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/608.cf0000644000000000000000000000372015010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/109.cf0000644000000000000000000000374015010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # Region editing, include_start_delimiter and include_end_delimiter # Region is destroyed by first edit # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { "BEGIN", " Three potatoe", "END" }; delete_lines: # Region is destroyed by first edit "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/231.cf0000644000000000000000000000372115010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/219.cf0000644000000000000000000000361115010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns (different order than original) # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/317.cf0000644000000000000000000000366315010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way (different order than in original) # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/132.cf0000644000000000000000000000405315010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*GI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/336.cf0000644000000000000000000000374215010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*C.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/411.cf0000644000000000000000000000351115010704253023766 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/547.cf0000644000000000000000000000365615010704253024012 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@{test.tstr}"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/318.cf0000644000000000000000000000354315010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way (different order than original) # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "BEGIN", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/013.cf0000644000000000000000000000312415010704253023764 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "BEGIN$(const.n)$(str)$(const.n)END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/631.cf0000644000000000000000000000400315010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/629.cf0000644000000000000000000000407115010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four potatoe END middle middle BEGIN One potato Two potato Three potatoe Four potatoe END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe END middle middle BEGIN One potato Two potato Three potatoe Four potatoe END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/523.cf0000644000000000000000000000350515010704253023775 0ustar00rootroot00000000000000####################################################### # # Don't delete a line, set a class # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body classes test_class(a) { promise_kept => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/328.cf0000644000000000000000000000374015010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/316.cf0000644000000000000000000000361215010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes (different order than in original) # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "\s+Three.*" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/211.cf0000644000000000000000000000357115010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/315.cf0000644000000000000000000000360215010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines (different order than in original) # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: " Three potatoe" select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/610.cf0000644000000000000000000000364415010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way, different patterns # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { ".*BEGIN.*", ".*Three.*", ".*END.*" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/128.cf0000644000000000000000000000403515010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/214.cf0000644000000000000000000000342615010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist (different order than in original) # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/606.cf0000644000000000000000000000364615010704253024005 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; " Three potatoe" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/018.cf0000644000000000000000000000320615010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way (different order than original) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "BEGIN", "END" }; delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/423.cf0000644000000000000000000000347615010704253024003 0ustar00rootroot00000000000000####################################################### # # Don't delete a line, set a class # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body classes test_class(a) { promise_kept => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/120.cf0000644000000000000000000000401515010704253023763 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns (different order than original) # Region editing, include_start_delimiter and include_end_delimiter # Second edit destroys the region # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: # Second edit destroys the region "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/634.cf0000644000000000000000000000377615010704253024012 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/422.cf0000644000000000000000000000341215010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a line, set a class # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body classes test_class(a) { promise_repaired => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/146.cf0000644000000000000000000000347015010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/no_matching_end.cf0000644000000000000000000000314515010704253026600 0ustar00rootroot00000000000000####################################################### # # Try to delete a region where select_end never matches # Redmine #6589 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN One potato Two potato Three potatoe Four END trailer"; "expected" string => "header BEGIN One potato Two potato Three potatoe Four END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete(".*"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; # anchored regex doesn't match due to whitespace } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/513.cf0000644000000000000000000000340615010704253023774 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n)BEGIN$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/313.cf0000644000000000000000000000345515010704253023776 0ustar00rootroot00000000000000####################################################### # # Don't delete multiple lines if they are not in the exact order # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "$(actual)"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)$(const.n)BEGIN$(const.n)END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/408.cf0000644000000000000000000000356215010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/607.cf0000644000000000000000000000365615010704253024007 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines, using regexes # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "\s+Three.*" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/603.cf0000644000000000000000000000361215010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a group of three lines at once # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe Four"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/037.cf0000644000000000000000000000342615010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/028.cf0000644000000000000000000000340615010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/344.cf0000644000000000000000000000375315010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/333.cf0000644000000000000000000000377715010704253024007 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*eade.*", ".*EGI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/517.cf0000644000000000000000000000361415010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way (different order than in original) # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "BEGIN" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/541.cf0000644000000000000000000000363215010704253023776 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/434.cf0000644000000000000000000000363015010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/027.cf0000644000000000000000000000334615010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/343.cf0000644000000000000000000000373515010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, only include_start_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "C" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/130.cf0000644000000000000000000000406115010704253023765 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/228.cf0000644000000000000000000000376015010704253024002 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/402.cf0000644000000000000000000000347215010704253023774 0ustar00rootroot00000000000000####################################################### # # Don't delete a line # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe "; # NOTE, DOES NOT MATCH! files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/624.cf0000644000000000000000000000402115010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # Two regions - Only the first one is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/137.cf0000644000000000000000000000405515010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*O.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/236.cf0000644000000000000000000000376215010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*T.*", ".*C.*" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/614.cf0000644000000000000000000000367215010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist (different order than in original) # Two regions - Only the first region is selected # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " Three potatoe", "BEGIN", "END" }; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/206.cf0000644000000000000000000000356115010704253023775 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; " Three potatoe" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/039.cf0000644000000000000000000000341515010704253023777 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which don't match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "Three", "GI", "ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/508.cf0000644000000000000000000000355115010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines, using regexes different way # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header header One potato Two potato Four trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; "^\s+Three.*$" # Anchors should make no difference select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/133.cf0000644000000000000000000000407415010704253023774 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*eade.*", ".*EGI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/242.cf0000644000000000000000000000375315010704253024000 0ustar00rootroot00000000000000####################################################### # # Delete a line using a singleton list which matches # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/144.cf0000644000000000000000000000405015010704253023770 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/309.cf0000644000000000000000000000347115010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, different way # select_region, only include_start_delimiter # Notice that deleting "END" will fail because the end # delimiter is not included in the region. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { vars: "str" slist => { " Three potatoe", "END" }; delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/143.cf0000644000000000000000000000403215010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # Region editing, include_start_delimiter and include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "C" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_start_delimiter => "true"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/020.cf0000644000000000000000000000325115010704253023763 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines via an slist, original way, different patterns (different order than original) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header One potato Two potato Four trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*Three.*", ".*BEGIN.*", ".*END.*" }; files: "$(G.testfile).actual" edit_line => test_delete("$(tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/247.cf0000644000000000000000000000373315010704253024003 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@{test.tstr}"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), not_matching => "false", select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/406.cf0000644000000000000000000000350115010704253023771 0ustar00rootroot00000000000000####################################################### # # Delete a number of lines as separate lines # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_delete; } bundle edit_line test_delete { delete_lines: "BEGIN" select_region => test_select; " Three potatoe" select_region => test_select; "END" select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/630.cf0000644000000000000000000000424215010704253023773 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which match # Two regions - expect changes to occur in both # select_region, doesn't include header or trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END middle middle BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { " T", " O" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; } body delete_select test_match(m) { delete_if_not_startwith_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/503.cf0000644000000000000000000000333015010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a group of three lines at once # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN Three potatoe END trailer END trailer"; "expected" string => "header BEGIN header trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => "BEGIN Three potatoe END"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/533.cf0000644000000000000000000000374215010704253024001 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # Double (nested) header/trailer # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; "expected" string => "header BEGIN header BEGIN One potato Two potato Three potatoe Four END trailer END trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*eade.*", ".*EGI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "header"; select_end => "trailer"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/233.cf0000644000000000000000000000401715010704253023772 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, all of which don't match # select_region, include_start_delimiter, include_end_delimiter # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { ".*eade.*", ".*EGI.*", ".*ND" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}), select_region => test_select; } body select_region test_select { select_start => "BEGIN"; select_end => "END"; include_end_delimiter => "true"; } body delete_select test_match(m) { delete_if_match_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/043.cf0000644000000000000000000000340315010704253023767 0ustar00rootroot00000000000000####################################################### # # Delete a line using a list, some of which match # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN Two potato Three potatoe Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" slist => { "T", "C" }; files: "$(G.testfile).actual" edit_line => test_delete(".*potat.*", "@(test.tstr)"); } bundle edit_line test_delete(str, match) { delete_lines: "$(str)" delete_select => test_match(@{match}); } body delete_select test_match(m) { delete_if_not_contains_from_list => { @{m} }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/07_delete_lines/022.cf0000644000000000000000000000312415010704253023764 0ustar00rootroot00000000000000####################################################### # # Delete a line, set a class # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "header header BEGIN One potato Two potato Three potatoe Four END trailer trailer"; "expected" string => "header header BEGIN One potato Two potato Four END trailer trailer"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => " Three potatoe"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => test_class("ok"); } body classes test_class(a) { promise_repaired => { "$(a)" }; } ####################################################### bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_dryryn.cf0000644000000000000000000000163015010704253025647 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that body agent control dryrun restricts mustache template rendering"; "story_id" string => "5535"; "covers" string => "dryrun_repaired"; } # Ref: https://dev.cfengine.com/issues/6739 ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -KIf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*Pass.*", ".*FAIL.*", $(command), $(this.promise_filename)); } agent_control_files_single_copy_does_not_apply_to_nonmatching_files_4.cf0000644000000000000000000000263115010704253036650 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body agent control { # Here we test a sane filename pattern against a file we definitely # aren't copying. But this time we are using a variable witin the # pattern. files_single_copy => { "$(sys.workdir)/state/WORKAROUND-CFE-2459" }; } bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy does not prevent file patterns that do not match from being copied multiple times."; "test_soft_fail" string => "any", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/two", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/mustache_render_multiline_template_data.cf.expected0000644000000000000000000000027315010704253032437 0ustar00rootroot00000000000000{ "key": "value", "key2": [ "list", "elements" ], "key3": { "complex": { "data": "structure", "with": [ "deep", "data" ] } } } cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_dryryn_option.cf0000644000000000000000000000162215010704253027240 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that --dry-run restricts mustache template rendering"; "story_id" string => "5535"; "covers" string => "dryrun_repaired"; } # Ref: https://dev.cfengine.com/issues/6739 ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) --dry-run -KIf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*Pass.*", ".*FAIL.*", $(command), $(this.promise_filename)); } agent_control_files_single_copy_prevents_subsequent_copy_on_exact_match.cf0000644000000000000000000000241015010704253037342 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body agent control { # Here we explicitly target the testfile. files_single_copy => { $(G.testfile) }; } bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy prevents subsequnt copy of a file when there is an exact match."; "test_skip_needs_work" string => "windows", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/one", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/copy_local_file.cf0000644000000000000000000000203715010704253023644 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that copying a file locally works"; "story_id" string => "5576"; "covers" string => "operational_repaired"; } # Ref: https://dev.cfengine.com/issues/5576 ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "target" string => "$(G.testdir)/target"; files: "$(target)" create => "true", edit_line => insert_lines("Initial Content"); } bundle agent test { files: # Ensure the target file is exactly the same as this file "$(init.target)" copy_from => local_dcp($(this.promise_filename)); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(init.target), $(this.promise_filename), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/10_files/mustache_respects_dryryn.cf.sub.mustache0000644000000000000000000000002215010704253030241 0ustar00rootroot00000000000000SHOULD NOT RENDER cfengine-3.24.2/tests/acceptance/10_files/move_obstruction_respects_warn_only.cf0000644000000000000000000000161215010704253030120 0ustar00rootroot00000000000000####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "target" string => "$(G.testfile)"; files: "$(target)/." create => "true"; } body link_from ln_s(x) { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } bundle agent test { files: "$(init.target)" move_obstructions => "true", link_from => ln_s("/tmp"), action => warn_only; } ####################################################### bundle agent check { classes: "ok" expression => isdir("$(init.target)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/13_file_dir/0000755000000000000000000000000015010704253022265 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/13_file_dir/001.cf0000644000000000000000000000410615010704253023100 0ustar00rootroot00000000000000####################################################### # # Acceptance test for issue #4070 # Ensure that cfengine creates a # file that has the same name as a pre-existing # directory without consuming 100% cpu and crashing # This test does what it says in 4070 - it creates # a directory e.g. /tmp/backup/my_dir # It then causes cfengine to create a file with an # identical name i.e. /tmp/backup/my_dir # The names above are simplified so as not to cause # confusion. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { ####################################### #Clean up test directory before testing ####################################### files: "$(G.testdir)/." depth_search => recurse("inf"), delete => tidy, file_select => all, classes => if_ok("dir_purged"); commands: dir_purged:: "$(G.mkdir) -p" args => "$(G.testdir)/backup/_tmp_TEST_cfengine_test"; } bundle edit_line test_insert(str) { insert_lines: "$(sys.date)"; } ####################################################### bundle agent test { files: agent_ran:: "$(G.testdir)/test" edit_line => test_insert("inserted text"), classes => if_ok("file_edited"); commands: "$(sys.cf_agent)" args => "-f $(this.promise_filename).sub -K", classes => if_ok("agent_ran"); file_edited:: "$(sys.cf_agent)" args => "-f $(this.promise_filename).sub -K -D SECOND_RUN", classes => classes_generic("agent_ran_test"), contain => test_timeout; } body contain test_timeout { exec_timeout => "30"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testdir)/SECOND_RUN"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/10_files/13_file_dir/never_delete_parent_dir.cf0000644000000000000000000000313315010704253027447 0ustar00rootroot00000000000000####################################################### # # Test rmdirs => true never deletes parent directory, i.e. the promiser. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { # Create a bunch of subdirectories and files. All will be deleted later. vars: "dir" string => "$(G.testdir)/dir"; "subdir1" string => "$(dir)/subdir1/."; "subdir2" string => "$(dir)/subdir2/."; files: "$(dir)/." create => "true"; "$(subdir1)" create => "true"; "$(subdir2)" create => "true"; "$(subdir2)/blah" create => "true"; } ####################################################### bundle agent test { # Delete everything under "dir", but the promiser itself should never # be removed. files: "$(init.dir)" depth_search => recurse_include_basedir("inf"), file_select => all, delete => tidy, # success should be set after removing all subdirs classes => if_ok("success"); } ####################################################### bundle agent check { classes: "dir_exists" expression => isdir($(init.dir)); "ok" expression => "success.dir_exists"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body depth_search recurse_include_basedir(d) { depth => "$(d)"; include_basedir => "true"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/13_file_dir/never_delete_nonempty_dir.cf0000644000000000000000000000370715010704253030036 0ustar00rootroot00000000000000####################################################### # # Test rmdirs => true never deletes non empty directories # but returns promise kept/repaired, even if dir not empty. # Ref: https://dev.cfengine.com/issues/6331 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dir" string => "$(G.testdir)/dir/."; "subdir1" string => "$(dir)/subdir1/."; "subdir2" string => "$(dir)/subdir2/."; files: "$(dir)" create => "true"; "$(subdir1)" create => "true"; "$(subdir2)" create => "true"; "$(subdir2)/blah" create => "true"; } ####################################################### bundle agent test { # When trying to recursively delete "dir", it will be unable to delete # "dir/subdir2" because it's not empty, but it should be skipped # silently, and the whole promise will be success. files: "$(init.dir)" depth_search => recurse_include_basedir("inf"), file_select => not_blah, delete => tidy, # success is being set despite skipping non-empty dir classes => if_ok("success"); } ####################################################### bundle agent check { classes: "dir_exists" expression => isdir($(init.dir)); "subdir1_deleted" not => isdir($(init.subdir1)); "subdir2_exists" expression => isdir($(init.subdir2)); "ok" expression => "success.dir_exists.subdir1_deleted.subdir2_exists"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body depth_search recurse_include_basedir(d) { depth => "$(d)"; include_basedir => "true"; } body file_select not_blah { leaf_name => { "blah" }; file_result => "!leaf_name"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/13_file_dir/001.cf.sub0000644000000000000000000000204015010704253023663 0ustar00rootroot00000000000000body common control { bundlesequence => { "create_test_file" }; inputs => { "../../default.cf.sub" }; } body agent control { default_repository => "$(G.testdir)/backup"; } bundle agent create_test_file { files: "$(G.testdir)/test" create => "true", edit_line => append_if_no_line("username:x:1:3:gcos:/home/dir:/bin/false"); "$(G.testdir)/test" changes => diff; SECOND_RUN:: "$(G.testdir)/SECOND_RUN" create => "true"; } body changes diff { hash => "sha256"; report_changes => "content"; report_diffs => "true"; update_hashes => "yes"; } cfengine-3.24.2/tests/acceptance/10_files/can_set_sticky_bits_without_root_owning_directory.cf0000644000000000000000000000326215010704253033040 0ustar00rootroot00000000000000####################################################### # # Acceptance test for Zendesk issue #2745 # Ensure that cfengine creates a # directory not owned by root and the setgid # is set on the directory # ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" string => "Test that the agent can set the sticky bit on a directory that root does not own."; "test_skip_unsupported" string => "windows"; "test_skip_needs_work" string => "!has_stat"; vars: !windows:: #"test_dir" string => "/tmp/test_setgid"; "mode" int => "2700"; "owner" string => "daemon"; "group" string => "daemon"; files: !windows:: "$(G.testdir)/test_sgid/." create => "true", perms => mog( $(mode), $(owner), $(group) ), classes => scoped_classes_generic("namespace", "test_sgid_dir"); } ####################################################### bundle agent check { vars: test_sgid_dir_reached:: "expect_permoct" string => "$(test.mode)"; "result_permoct" string => execresult('$(G.stat) -c %a $(G.testdir)/test_sgid', "useshell"); methods: "Compare Results" usebundle => dcs_check_strcmp( "$(expect_permoct)", "$(result_permoct)", $(this.promise_filename), "false"); reports: DEBUG:: "expected: permoct = '$(check.expect_permoct)'"; "got: permoct = '$(check.result_permoct)'"; } cfengine-3.24.2/tests/acceptance/10_files/mustache_missing_variable_is_empty_string_by_default.cf0000644000000000000000000000271015010704253033423 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" -> { "Mustache Specification" } string => "Missed variables should be empty strings by default in rendered mustache templates as described in the Mustache Manual.", comment => "https://mustache.github.io/mustache.5.html"; } ####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; "template_data" data => '{ "key1": "value1", "key3": "value3" }'; files: "$(template_target)" create => "true"; } ####################################################### bundle agent test { files: "$(init.template_target)" edit_template => "$(this.promise_filename).mustache", template_method => "mustache", template_data => @(init.template_data); } bundle agent check { vars: "command" string => "$(sys.cf_agent) -KIf $(this.promise_filename).sub -DAUTO"; "actual" string => "$(init.template_target)"; "expected" string => "$(this.promise_filename).mustache.expected"; "test" string => "$(this.promise_filename)"; methods: "check" usebundle => dcs_check_diff( $(actual), $(expected), $(test) ); reports: DEBUG:: "Comparing render of '$(actual)' with expected output '$(expected)'"; } cfengine-3.24.2/tests/acceptance/10_files/copy_from_preserve_false.cf.src0000755000000000000000000000012315010704253026366 0ustar00rootroot00000000000000This file is used as part of a test. Its hashed and compared against another file. cfengine-3.24.2/tests/acceptance/10_files/05_classes/0000755000000000000000000000000015010704253022146 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/05_classes/001.cf0000644000000000000000000000354315010704253022765 0ustar00rootroot00000000000000####################################################### # # Delete a line, ensure that a promise_repaired class gets set # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "keep this and this but delete one line keep this too"; "expected" string => "keep this and this keep this too"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => ".*delete.*"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => full_set; } body classes full_set { promise_kept => { "fail" }; promise_repaired => { "pass" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { methods: pass.!fail:: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); reports: !pass|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/102.cf0000644000000000000000000000666015010704253022772 0ustar00rootroot00000000000000####################################################### # # Test multiple promise_repaired and cancel_repaired (contrived example) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_repaired => { "promise_repaired", "p2_repaired" }; cancel_repaired => { "cancel_repaired", "cancel_kept", "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[p2_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "p2_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/004.cf0000644000000000000000000000372215010704253022767 0ustar00rootroot00000000000000####################################################### # # Delete a line that isn't there, action_policy=>"warn", ensure that a promise_kept class gets set # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "keep this and this keep this too"; "expected" string => "keep this and this keep this too"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => ".*delete.*"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" action => test_warn_only, classes => full_set; } body action test_warn_only { action_policy => "warn"; } body classes full_set { promise_kept => { "pass" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { methods: pass.!fail:: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); reports: !pass|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/006.cf0000644000000000000000000000372015010704253022767 0ustar00rootroot00000000000000####################################################### # # Delete a line that isn't there, action_policy=>"nop", ensure that a promise_kept class gets set # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "keep this and this keep this too"; "expected" string => "keep this and this keep this too"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => ".*delete.*"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" action => test_warn_only, classes => full_set; } body action test_warn_only { action_policy => "nop"; } body classes full_set { promise_kept => { "pass" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { methods: pass.!fail:: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); reports: !pass|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/002.cf0000644000000000000000000000353415010704253022766 0ustar00rootroot00000000000000####################################################### # # Delete a line that isn't there, ensure that a promise_kept class gets set # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "keep this and this keep this too"; "expected" string => "keep this and this keep this too"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => ".*delete.*"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => full_set; } body classes full_set { promise_kept => { "pass" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { methods: pass.!fail:: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); reports: !pass|fail:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/0000755000000000000000000000000015010704253023602 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/104.cf0000644000000000000000000000711315010704253024422 0ustar00rootroot00000000000000####################################################### # # Test promise_kept and cancel_kept # Insert lines to a file, then verify that insert promise is kept # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => init_insert("$(init.body)"), edit_defaults => init_empty, classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/107.cf0000644000000000000000000001020515010704253024421 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (still incorrectly done!) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; "body2" string => "BEGIN One potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", edit_line => test_insert, edit_defaults => init_empty; } bundle edit_line test_insert { insert_lines: "$(init.body2)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/101.cf0000644000000000000000000000705415010704253024423 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/007.cf0000644000000000000000000000426415010704253024430 0ustar00rootroot00000000000000####################################################### # # Delete a line that isn't there, action_policy=>"nop", ensure that a promise_kept class gets set # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", perms => test_mode("0644"); "$(G.testfile).link" link_from => init_link("$(G.testfile)"); } body link_from init_link(src) { source => "$(src)"; } ####################################################### bundle agent test { files: "$(G.testfile).link" perms => test_mode("0600"), classes => fail_check; "$(G.testfile)" perms => test_mode("0644"), classes => kept_check; } body perms test_mode(m) { mode => "$(m)"; } body classes fail_check { promise_kept => { "fail1" }; promise_repaired => { "fail1" }; repair_failed => { "pass1" }; # Cannot chmod a sylink! repair_denied => { "fail1" }; repair_timeout => { "fail1" }; } body classes kept_check { promise_kept => { "pass2" }; # Original mode should not have changed promise_repaired => { "fail2" }; repair_failed => { "fail2" }; repair_denied => { "fail2" }; repair_timeout => { "fail2" }; } ####################################################### bundle agent check { classes: "ok" and => { "pass1", "pass2", "!fail1", "!fail2" }; reports: DEBUG.!pass1:: "Trying to chmod a symlink did not fail like it should"; DEBUG.fail1:: "Trying to chmod a symlink gave a return other than repair_failed"; DEBUG.!pass2:: "Something was funky with the target of a symlink"; DEBUG.fail2:: "Doing a chmod on a symlink changed the target file instead!"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/105.cf0000644000000000000000000000750715010704253024432 0ustar00rootroot00000000000000####################################################### # # Test promise_kept+repaired and cancel_kept+repaired (broken multiple promises set classes, see comments) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => init_insert("$(init.body)"), edit_defaults => init_empty; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and test, it is only executed ONCE, so it only # sets the repaired promises. "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/112.cf0000644000000000000000000000710115010704253024416 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" # create => "true", # file will not exist! edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/113.cf0000644000000000000000000000722615010704253024427 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept (different location and results) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" # create => "true", # file will not exist! edit_line => init_insert("$(body)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)", # Promise never executed, so classes not set! classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/103.cf0000644000000000000000000000711515010704253024423 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired (different location in edit_line) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/003.cf0000644000000000000000000000423115010704253024416 0ustar00rootroot00000000000000####################################################### # # Try to delete a line, action_policy=>"warn", ensure that a repair_denied class gets set (issue 441) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "keep this and this but delete one line keep this too"; "expected" string => "keep this and this but delete one line keep this too"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => ".*delete.*"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" classes => full_set; } body classes full_set { promise_kept => { "fail" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "pass" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { classes: "no_difference" expression => returnszero( "$(G.diff) -q $(G.testfile).actual $(G.testfile).expected", "noshell"); "ok" and => { "pass", "!fail", "no_difference" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/005.cf0000644000000000000000000000436015010704253024423 0ustar00rootroot00000000000000####################################################### # # Attempt to delete a line, action_policy=>"nop", ensure that a repair_denied class gets set (issue 441) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => "keep this and this but delete one line keep this too"; "expected" string => "keep this and this but delete one line keep this too"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "tstr" string => ".*delete.*"; files: "$(G.testfile).actual" edit_line => test_delete("$(test.tstr)"); } bundle edit_line test_delete(str) { delete_lines: "$(str)" action => warn_only, classes => full_set; } body action warn_only { action_policy => "nop"; } body classes full_set { promise_kept => { "fail" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "pass" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { classes: "no_difference" expression => returnszero( "$(G.diff) -q $(G.testfile).actual $(G.testfile).expected", "noshell"); "ok" and => { "pass", "!fail", "no_difference" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/114.cf0000644000000000000000000000676115010704253024433 0ustar00rootroot00000000000000####################################################### # # Test setting two classes in one promise # Copy file with one mode, then copy again with different mode # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile)" copy_from => local("$(G.etc_group)"), perms => mode("666"); } body copy_from local(f) { source => "$(f)"; } body perms mode(m) { mode => "$(m)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" copy_from => local("$(G.etc_group)"), # Same file perms => mode("644"), # Different mode classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/111.cf0000644000000000000000000001021415010704253024414 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (second promise is not kept because files are different) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; "body2" string => "BEGIN One potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => test_insert, edit_defaults => init_empty; } bundle edit_line test_insert { insert_lines: "$(init.body2)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/106.cf0000644000000000000000000001010115010704253024413 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (incorrect test, see comments) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", edit_line => test_insert("$(init.body)"), edit_defaults => init_empty; } bundle edit_line test_insert(str) { insert_lines: "$(str)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/110.cf0000644000000000000000000001010215010704253024407 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (correctly done!) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; "body2" string => "BEGIN One potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(init.body2)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/108.cf0000644000000000000000000001021415010704253024422 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (second promise is not kept because files are different) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; "body2" string => "BEGIN One potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => test_insert, edit_defaults => init_empty; } bundle edit_line test_insert { insert_lines: "$(init.body2)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/05_classes/staging/109.cf0000644000000000000000000001023215010704253024423 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (correctly done!) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; "body2" string => "BEGIN One potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(init.body2)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/10_links/0000755000000000000000000000000015010704253021625 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files/10_links/001.cf0000644000000000000000000000222315010704253022436 0ustar00rootroot00000000000000####################################################### # # Subdirectories shall not be created when action is # warn. Related to bug #926. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: } ####################################################### bundle agent test { files: "$(G.testdir)/subdir/mylink" link_from => ln_s("$(G.testdir)/sourcefile"), action => test_warn_only; } body action test_warn_only { action_policy => "warn"; } body link_from ln_s(x) { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } ####################################################### bundle agent check { classes: "subdir_created" expression => fileexists("$(G.testdir)/subdir"); reports: !subdir_created:: "$(this.promise_filename) Pass"; subdir_created:: "$(this.promise_filename) Fail"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/10_links/002-namespaced_links.cf.sub0000644000000000000000000000033415010704253026526 0ustar00rootroot00000000000000body file control { namespace => "testing_links"; } bundle agent namespaced_test { files: "$(G.testdir)/subdir/mylink" link_from => default:ln_s("$(G.testdir)/sourcefile"), action => default:warn_only; } cfengine-3.24.2/tests/acceptance/10_files/10_links/select_file_by_type.cf0000644000000000000000000000300315010704253026144 0ustar00rootroot00000000000000####################################################### # # Select files based on type # # Ref: https://dev.cfengine.com/issues/6878 ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "symlink" string => "$(G.testdir)/symlink_to_tmp_target"; "target" string => "$(G.testdir)/target"; files: "$(target)/." create => "true"; "$(symlink)" delete => tidy; "$(symlink)" link_from => linkfrom("$(target)", "symlink"), classes => scoped_classes_generic("namespace", "init_symlink"); } ####################################################### bundle agent test { files: "$(init.symlink)" file_select => select_type("symlink"), delete => nodir, pathtype => "literal", classes => scoped_classes_generic("namespace", "test_symlink"); } ####################################################### bundle agent check { classes: "OK" not => fileexists("$(init.symlink)"); reports: OK:: "$(this.promise_filename) Pass"; !OK:: "$(this.promise_filename) Fail"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 body delete nodir { rmdirs => "false"; } body file_select select_type(type) { file_types => { "$(type)" }; file_result => "file_types"; } cfengine-3.24.2/tests/acceptance/10_files/10_links/owner-mismatch-link-and-target.cf0000755000000000000000000000454215010704253030063 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: # The symlink is initially created with uid 0, the uid we expect in the end. # This tests that promising the uid of a symlink is not confused by the symlink target having a different uid # - We do not expect to see any REPAIR related to the UID of the symlink "/tmp/symlink-target" create => "true", perms => uid(2); "/tmp/symlink" link_from => ln_s( "/tmp/symlink-target" ), perms => uid(0); } bundle agent test { meta: "description" -> { "CFE-3116" } string => "Test that promising ownership of symlinks is not confused by target"; "test_skip_unsupported" string => "windows"; files: "/tmp/symlink" handle => "link_1", classes => results( "namespace", "link_1_uid" ), perms => uid(0); "/tmp/symlink" handle => "link_2", classes => results( "namespace", "link_2_uid" ), perms => uid(0); } bundle agent check { classes: "symlink_owner_ok" expression => strcmp( "0", filestat( "/tmp/symlink", "uid" ) ); "pass" and => { "symlink_owner_ok" }; "fail" or => { "link_1_uid_repaired", "link_2_uid_repaired" }; reports: link_1_uid_repaired:: "We think we repaired the UID of the symlink for promise with handle link_1"; link_2_uid_repaired:: "We think we repaired the UID of the symlink for promise with handle link_2"; link_1_uid_repaired.link_2_uid_repaired:: "We think we repaired the UID of the symlink multiple times"; symlink_owner_ok:: "The symlink is owned by uid 0 as expected"; !symlink_owner_ok:: "The symlink is NOT owned by uid 0 unexpectedly"; pass.!fail:: "$(this.promise_filename) Pass"; !pass|fail:: "$(this.promise_filename) FAIL"; } body perms uid( uid ) { owners => { "$(uid)" }; } body link_from ln_s(x) # @brief Create a symbolink link to `x` # The link is created even if the source of the link does not exist. # @param x The source of the link { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } bundle agent __main__ { methods: "init"; "test"; "check"; } cfengine-3.24.2/tests/acceptance/10_files/10_links/select_file_by_symlink_target.cf0000644000000000000000000000316715010704253030232 0ustar00rootroot00000000000000####################################################### # # Select files based on symlink target # Ref: https://dev.cfengine.com/issues/6878 # ######################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "symlink" string => "$(G.testdir)/symlink_to_tmp_target"; "target" string => "$(G.testdir)/target"; files: "$(target)/." create => "true"; "$(symlink)" link_from => linkfrom("$(target)", "symlink"), classes => scoped_classes_generic("namespace", "init_symlink"); } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; # Delete the file only if it is a symlink pointing to the expected target files: "$(init.symlink)" file_select => symlinked_to("$(init.target)"), delete => nodir, pathtype => "literal", classes => scoped_classes_generic("namespace", "test_symlink"); } ####################################################### bundle agent check { classes: "OK" not => fileexists("$(init.symlink)"); reports: OK:: "$(this.promise_filename) Pass"; !OK:: "$(this.promise_filename) Fail"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 body file_select symlinked_to(name) { file_types => { "symlink" }; issymlinkto => { "$(name)" }; file_result => "issymlinkto"; } body delete nodir { rmdirs => "false"; } cfengine-3.24.2/tests/acceptance/10_files/10_links/edit_linked_file.cf0000644000000000000000000000316415010704253025415 0ustar00rootroot00000000000000# Test that editing a symlink does not mangle it body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/file_dir/file" create => "true", edit_line => edit_init; "$(G.testdir)/link_dir/." create => "true"; "$(G.testdir)/link_dir/link" link_from => link_init; } bundle edit_line edit_init { insert_lines: "Initial line"; } body link_from link_init { link_type => "symlink"; source => "../file_dir/file"; } bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: "$(G.testdir)/link_dir/link" edit_line => edit_test; } bundle edit_line edit_test { insert_lines: "Added line"; } bundle agent check { classes: "link_ok" expression => islink("$(G.testdir)/link_dir/link"); "file_ok" not => islink("$(G.testdir)/file_dir/file"); "link_line_one_ok" expression => regline("Initial line", "$(G.testdir)/link_dir/link"); "file_line_one_ok" expression => regline("Initial line", "$(G.testdir)/file_dir/file"); "link_line_two_ok" expression => regline("Added line", "$(G.testdir)/link_dir/link"); "file_line_two_ok" expression => regline("Added line", "$(G.testdir)/file_dir/file"); "ok" and => { "link_ok", "file_ok", "link_line_one_ok", "file_line_one_ok", "link_line_two_ok", "file_line_two_ok" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/10_links/002.cf0000644000000000000000000000210415010704253022435 0ustar00rootroot00000000000000####################################################### # # Check that action and link_from bodies are accessible from outside # the current namespace. # ####################################################### body common control { inputs => { "../../default.cf.sub", "002-namespaced_links.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: } ####################################################### bundle agent test { methods: "run" usebundle => testing_links:namespaced_test(); } body link_from ln_s(x) { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } ####################################################### bundle agent check { classes: "subdir_created" expression => fileexists("$(G.testdir)/subdir"); reports: !subdir_created:: "$(this.promise_filename) Pass"; subdir_created:: "$(this.promise_filename) Fail"; } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/10_files/10_links/delete_dangling_symlink.cf0000644000000000000000000000170215010704253027012 0ustar00rootroot00000000000000####################################################### # # Delete dangling symlinks # https://dev.cfengine.com/issues/6582 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { files: "$(G.testdir)/mylink" link_from => ln_s("$(G.testdir)/sourcefile"); "$(G.testdir)/mylink" delete => tidy; } body link_from ln_s(x) { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } ####################################################### bundle agent check { classes: "link_absent" not => fileexists("$(G.testdir)/mylink"); reports: link_absent:: "$(this.promise_filename) Pass"; !link_absent:: "$(this.promise_filename) Fail"; } agent_control_files_single_copy_does_not_apply_to_nonmatching_files_2.cf0000644000000000000000000000253115010704253036645 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/10_files####################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body agent control { # $^ should match an empty string which should never be a way to # reference a file so this should never match any file. files_single_copy => { "$^" }; } bundle agent init { vars: "copy_files" slist => { "one", "two" }; files: "$(G.testdir)/$(copy_files)" create => "true", edit_line => insert_lines("$(copy_files)"); } bundle agent test { meta: "description" string => "Test that files_single_copy does not prevent file patterns that do not match from being copied multiple times."; "test_soft_fail" string => "any", meta => { "CFE-2459" }; files: # Here we iterate over each copy_file to promise the content # of the testfile. We expect that with files_single_copy in # effect only the first file should be copied. "$(G.testfile)" copy_from => local_dcp( "$(G.testdir)/$(init.copy_files)" ); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_diff($(G.testfile), "$(G.testdir)/two", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/17_users/0000755000000000000000000000000015010704253020253 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/17_users/unsafe/0000755000000000000000000000000015010704253021534 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_with_password_hpux_trusted.cf0000644000000000000000000000401515010704253032467 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { data => "$(init.hash)"; !windows:: format => "hash"; windows:: format => "plaintext"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "plaintext"; data => "New0P4SSW0RD"; } ####################################################### bundle agent check { methods: !windows:: # Make sure it is *not* the same as before. "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "failure", "success"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "New0P4SSW0RD", "success", "failure"), classes => always("methods_run"); any:: "any" usebundle => user_does_not_need_password_update("johndoe", "no_pw_update_ok", "no_pw_update_fail"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure", "no_pw_update_ok", "!no_pw_update_fail" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user.cf0000644000000000000000000000215315010704253024135 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe" policy => "present"; } ####################################################### bundle agent check { methods: "any" usebundle => user_exists("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_remove_user.cf0000644000000000000000000000206515010704253024704 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets removed"; "story_id" string => "5526"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" policy => "absent"; } ####################################################### bundle agent check { methods: "any" usebundle => user_exists("johndoe", "failure", "success"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_with_many_attributes.cf0000644000000000000000000001116015010704253031217 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets several attributes changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Start out with other attributes. users: "johndoe" policy => "present", password => init_password, uid => "8765", group_primary => "$(user_tests.gid2)", groups_secondary => { "$(user_tests.group1)" }, home_dir => "/home/johndoe", shell => "/bin/bash", description => "Wrong!"; } body password init_password { format => "plaintext"; data => "Wrong0P4SSW0RD"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; "desc_string" string => "This description should make the CFEngine test pass"; users: "johndoe" policy => "present", password => test_password, uid => "9876", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, home_dir => "/home/user-johndoe", shell => "/bin/csh", description => "$(desc_string)"; } body password test_password { !windows:: format => "hash"; data => "$(test.hash)"; windows:: format => "plaintext"; data => "New0P4SSW0RD"; } ####################################################### bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: "any" usebundle => user_has_uid("johndoe", "9876", "uid_success", "uid_failure"), classes => always("uid_methods_run"); "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group1)", "pgroup_success", "pgroup_failure"), classes => always("pgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group2)", "sgroup_success", "sgroup_failure"), classes => always("sgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "not_sgroup_failure", "not_sgroup_success"), classes => always("not_sgroup_methods_run"); "any" usebundle => user_has_home_dir("johndoe", "/home/user-johndoe", "home_success", "home_failure"), classes => always("home_methods_run"); "any" usebundle => user_has_shell("johndoe", "/bin/csh", "shell_success", "shell_failure"), classes => always("shell_methods_run"); "any" usebundle => user_has_description("johndoe", "$(test.desc_string)", "desc_success", "desc_failure"), classes => always("desc_methods_run"); !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "hash_success", "hash_failure"), classes => always("hash_methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "New0P4SSW0RD", "hash_success", "hash_failure"), classes => always("hash_methods_run"); classes: "ready" and => { "uid_methods_run", "pgroup_methods_run", "sgroup_methods_run", "not_sgroup_methods_run", "home_methods_run", "shell_methods_run", "desc_methods_run", "hash_methods_run" }; !windows:: # Note the secondary group classes here. Windows treats primary and secondary groups the same, # and hence that test is invalid there. "unix_ok" and => { "uid_success", "!uid_failure", "shell_success", "!shell_failure", "not_sgroup_success", "!not_sgroup_failure", }; windows:: "unix_ok" expression => "any"; sles_11:: "ok" -> "CFE-3386" and => { "pgroup_success", "!pgroup_failure", "!sgroup_success", "sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; !sles_11:: "ok" and => { "pgroup_success", "!pgroup_failure", "sgroup_success", "!sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_password_hash_is_not_cached.cf0000644000000000000000000000624515010704253030064 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that cached password hashes do not cause problems"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### # If the platform is using /etc/passwd to store hashes, then the hash will be # cached in the passwd_info structure in the C code. This may cause problems # if one part of the code (password update) tries to modify the hash, and # another one (locking) also does it. The latter may use the cached value from # before it was modified, but should use the updated value. ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: # Password hashes are not supported on Windows. "test_skip_unsupported" string => "(hpux_trusted_mode_test.!hpux)|windows"; vars: # "j0hnd0e" "hash" string => "dTloMVpjYt1w2"; methods: "any" usebundle => init_firstpass; "any" usebundle => init_secondpass; } bundle agent init_firstpass { users: "user1" policy => "absent"; "user2" policy => "absent"; } bundle agent init_secondpass { users: "user1" policy => "present", password => init_password; "user2" policy => "present", password => init_password; } body password init_password { format => "hash"; data => "$(init.hash)"; } ####################################################### bundle agent test { vars: # "N4wP4ssw" "hash" string => "aapgPBZAGeZf6"; methods: "any" usebundle => test_firstpass; "any" usebundle => test_secondpass; } bundle agent test_firstpass { users: "user1" policy => "locked"; "user2" policy => "locked"; } bundle agent test_secondpass { users: "user1" policy => "present", password => test_hash; "user2" policy => "present", password => test_passwd; } body password test_hash { format => "hash"; data => "$(test.hash)"; } body password test_passwd { format => "plaintext"; data => "N4wP4ssw"; } ####################################################### bundle agent check { methods: "any" usebundle => user_has_password_hash("user1", "$(test.hash)", "user1_success", "user1_failure"), classes => always("user1_methods_run"); "any" usebundle => user_has_password_hash("user2", "$(init.hash)", "user2_failure", "user2_success"), classes => always("user2_methods_run"); classes: "ready" and => { "user1_methods_run", "user2_methods_run" }; "ok" and => { "user1_success", "!user1_failure", "user2_success", "!user2_failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_home_bundle_when_removing_user.cf0000644000000000000000000000226415010704253030620 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user removed does not get the home bundle run"; "story_id" string => "5526"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" policy => "absent", home_bundle => home_bundle("/home/johndoe"); } bundle agent home_bundle(x) { files: "$(G.testfile)" create => "true", edit_line => home_edit("$(x)"); } bundle edit_line home_edit(x) { insert_lines: "$(x)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("0", countlinesmatching("/home/johndoe", "$(G.testfile)")); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_many_attributes.cf0000644000000000000000000000616015010704253030464 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with several attributes"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "desc_string" string => "This description should make the CFEngine test pass"; aix:: # AIX only allows certain shells. "shell" string => "/bin/csh"; !aix:: "shell" string => "$(G.echo)"; users: "johndoe" policy => "present", uid => "9876", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, home_dir => "/home/user-johndoe", shell => "$(shell)", description => "$(desc_string)"; } ####################################################### bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: "any" usebundle => user_has_uid("johndoe", "9876", "uid_success", "uid_failure"), classes => always("uid_methods_run"); "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group1)", "pgroup_success", "pgroup_failure"), classes => always("pgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group2)", "sgroup_success", "sgroup_failure"), classes => always("sgroup_methods_run"); "any" usebundle => user_has_home_dir("johndoe", "/home/user-johndoe", "home_success", "home_failure"), classes => always("home_methods_run"); "any" usebundle => user_has_shell("johndoe", "$(test.shell)", "shell_success", "shell_failure"), classes => always("shell_methods_run"); "any" usebundle => user_has_description("johndoe", "$(test.desc_string)", "desc_success", "desc_failure"), classes => always("desc_methods_run"); classes: "ready" and => { "uid_methods_run", "pgroup_methods_run", "sgroup_methods_run", "home_methods_run", "shell_methods_run", "desc_methods_run" }; !windows:: "unix_ok" and => { "uid_success", "!uid_failure", "shell_success", "!shell_failure", }; windows:: "unix_ok" expression => "any"; any:: "ok" and => { "pgroup_success", "!pgroup_failure", "sgroup_success", "!sgroup_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/aix_get_shadow_field.pl0000755000000000000000000000107315010704253026225 0ustar00rootroot00000000000000#!/usr/bin/perl -w # Takes two arguments, the field to get, and the user to get it from. open(PASSWD, "< /etc/security/passwd") or die("Could not open password file"); my $in_user_section = 0; my $hash = ""; while () { if (!$in_user_section) { if (/^$ARGV[1]:/) { $in_user_section = 1; } } else { if (/^\S/) { $in_user_section = 0; } elsif (/$ARGV[0] *= *(\S+)/) { $hash = $1; } } } print("$hash\n") if ($hash); close(PASSWD); cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_description.cf0000644000000000000000000000243715010704253027600 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with description"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "desc_string" string => "This description should make the CFEngine test pass"; users: "johndoe" policy => "present", description => "$(desc_string)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_has_description("johndoe", "$(test.desc_string)", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_lock_with_password_hpux_trusted.cf0000644000000000000000000000272615010704253033506 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets locked and the password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "locked", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_add_user_locked_with_password_hpux_trusted.cf0000644000000000000000000000272415010704253033256 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added locked with password"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "locked", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_locked_with_password.cf0000644000000000000000000000272415010704253030437 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added locked with password"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "locked", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_shell.cf0000644000000000000000000000340315010704253026356 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with a shell"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub", "disable_sudo_tty_requirement.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; cache_system_functions => "no"; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; methods: "any" usebundle => disable_sudo_tty_requirement; } ####################################################### bundle agent test { vars: aix:: # AIX only allows certain shells. "shell" string => "/bin/csh"; !aix:: "shell" string => "$(G.cat)"; users: "johndoe" policy => "present", shell => "$(shell)"; } ####################################################### bundle agent check { vars: "currentdir" string => dirname("$(this.promise_filename)"); classes: !windows.!aix:: "ok" expression => regcmp(".*Succeeded.*", execresult("sudo su johndoe $(currentdir)$(const.dirsep)add_user_with_shell.txt", "useshell")); methods: aix:: "any" usebundle => user_has_shell("johndoe", "$(test.shell)", "shell_success", "shell_failure"), classes => always("shell_methods_run"); classes: aix:: "ok" and => { "shell_success", "!shell_failure" }; reports: ok|windows:: "$(this.promise_filename) Pass"; !ok.!windows:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_promise_outcomes_hpux_trusted.cf0000644000000000000000000001601115010704253030560 0ustar00rootroot00000000000000####################################################### # # Test that promise outcomes are set correctly. # ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Something in the Solaris chroot test environment makes it impossible # to test matching passwords, the pam module always returns error. # This should not happen in a production system though. # Since the error is not on our part, and likely unsolvable, we set # Redmine to zero. However, it would be nice to know if the problem ever # goes away, so using soft_fail. "test_soft_fail" string => "!hpux_trusted_mode_test.(solaris.!sunos_5_9)", meta => { "redmine0" }; # On Solaris 9 PAM just crashes inside chroot. "test_skip_needs_work" string => "!hpux_trusted_mode_test.sunos_5_9"; # AIX doesn't like long names (> 8 chars), so keep them short. # a = absent # p = present # t = attributes # w = password # l = locked # r = repair users: "akeep" policy => "absent"; "arepair" policy => "present"; "pkeep" policy => "present"; "prepair" policy => "absent"; "tkeep" policy => "present", uid => "9878", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, shell => "/bin/csh", description => "Description"; "trepair" policy => "present", uid => "9877", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, shell => "/bin/csh", description => "Description"; "wkeep" policy => "present", password => init_password; "wrepair" policy => "present", password => init_password; "lkeep" policy => "locked"; "lr_byadd" policy => "absent"; "lr_bymod" policy => "present"; } body password init_password { format => "plaintext"; data => "Init0P4SSW0RD"; } ####################################################### bundle agent test { users: !ok:: "akeep" classes => set_classes_kept_repaired("absent_keep", "not_absent_keep"), policy => "absent"; "arepair" classes => set_classes_kept_repaired("not_absent_repair", "absent_repair"), policy => "absent"; "pkeep" classes => set_classes_kept_repaired("present_keep", "not_present_keep"), policy => "present"; "prepair" classes => set_classes_kept_repaired("not_present_repair", "present_repair"), policy => "present"; "tkeep" classes => set_classes_kept_repaired("attributes_keep", "not_attributes_keep"), policy => "present", uid => "9878", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, shell => "/bin/csh", description => "Description"; "trepair" classes => set_classes_kept_repaired("not_attributes_repair", "attributes_repair"), policy => "present", uid => "9877", group_primary => "$(user_tests.group1)", groups_secondary => { }, shell => "/bin/ksh", description => "Description"; "wkeep" classes => set_classes_kept_repaired("password_keep", "not_password_keep"), policy => "present", password => init_password; "wrepair" classes => set_classes_kept_repaired("not_password_repair", "password_repair"), policy => "present", password => test_password; "lkeep" classes => set_classes_kept_repaired("locked_keep", "not_locked_keep"), policy => "locked"; "lr_byadd" classes => set_classes_kept_repaired("not_locked_repair_by_add", "locked_repair_by_add"), policy => "locked"; "lr_bymod" classes => set_classes_kept_repaired("not_locked_repair_by_mod", "locked_repair_by_mod"), policy => "locked"; classes: "and_ok" and => { "absent_keep", "absent_repair", "present_keep", "present_repair", "attributes_keep", "attributes_repair", "password_keep", "password_repair", "locked_keep", "locked_repair_by_add", "locked_repair_by_mod" }; "not_ok" or => { "not_absent_keep", "not_absent_repair", "not_present_keep", "not_present_repair", "not_attributes_keep", "not_attributes_repair", "not_password_keep", "not_password_repair", "not_locked_keep", "not_locked_repair_by_add", "not_locked_repair_by_mod" }; "ok" and => { "and_ok", "!not_ok" }; "fail" or => { "!and_ok", "not_ok" }; reports: !absent_keep.DEBUG:: "absent_keep is NOT set, but should be"; !absent_repair.DEBUG:: "absent_repair is NOT set, but should be"; !present_keep.DEBUG:: "present_keep is NOT set, but should be"; !present_repair.DEBUG:: "present_repair is NOT set, but should be"; !attributes_keep.DEBUG:: "attributes_keep is NOT set, but should be"; !attributes_repair.DEBUG:: "attributes_repair is NOT set, but should be"; !password_keep.DEBUG:: "password_keep is NOT set, but should be"; !password_repair.DEBUG:: "password_repair is NOT set, but should be"; !locked_keep.DEBUG:: "locked_keep is NOT set, but should be"; !locked_repair_by_add.DEBUG:: "locked_repair_by_add is NOT set, but should be"; !locked_repair_by_mod.DEBUG:: "locked_repair_by_mod is NOT set, but should be"; not_absent_keep.DEBUG:: "not_absent_keep is SET, but shouldn't be"; not_absent_repair.DEBUG:: "not_absent_repair is SET, but shouldn't be"; not_present_keep.DEBUG:: "not_present_keep is SET, but shouldn't be"; not_present_repair.DEBUG:: "not_present_repair is SET, but shouldn't be"; not_attributes_keep.DEBUG:: "not_attributes_keep is SET, but shouldn't be"; not_attributes_repair.DEBUG:: "not_attributes_repair is SET, but shouldn't be"; not_password_keep.DEBUG:: "not_password_keep is SET, but shouldn't be"; not_password_repair.DEBUG:: "not_password_repair is SET, but shouldn't be"; not_locked_keep.DEBUG:: "not_locked_keep is SET, but shouldn't be"; not_locked_repair_by_add.DEBUG:: "not_locked_repair_by_add is SET, but shouldn't be"; not_locked_repair_by_mod.DEBUG:: "not_locked_repair_by_mod is SET, but shouldn't be"; ok:: "$(this.promise_filename) Pass"; fail|!ok:: "$(this.promise_filename) FAIL"; } body password test_password { format => "plaintext"; data => "Test0P4SSW0RD"; } body classes set_classes_kept_repaired(x, y) { promise_kept => { "$(x)" }; promise_repaired => { "$(y)" }; } ####################################################### bundle agent check { } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_password_hash_is_not_cached_hpux_trusted.cf0000644000000000000000000000624515010704253032703 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "Test that cached password hashes do not cause problems"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### # If the platform is using /etc/passwd to store hashes, then the hash will be # cached in the passwd_info structure in the C code. This may cause problems # if one part of the code (password update) tries to modify the hash, and # another one (locking) also does it. The latter may use the cached value from # before it was modified, but should use the updated value. ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: # Password hashes are not supported on Windows. "test_skip_unsupported" string => "(hpux_trusted_mode_test.!hpux)|windows"; vars: # "j0hnd0e" "hash" string => "dTloMVpjYt1w2"; methods: "any" usebundle => init_firstpass; "any" usebundle => init_secondpass; } bundle agent init_firstpass { users: "user1" policy => "absent"; "user2" policy => "absent"; } bundle agent init_secondpass { users: "user1" policy => "present", password => init_password; "user2" policy => "present", password => init_password; } body password init_password { format => "hash"; data => "$(init.hash)"; } ####################################################### bundle agent test { vars: # "N4wP4ssw" "hash" string => "aapgPBZAGeZf6"; methods: "any" usebundle => test_firstpass; "any" usebundle => test_secondpass; } bundle agent test_firstpass { users: "user1" policy => "locked"; "user2" policy => "locked"; } bundle agent test_secondpass { users: "user1" policy => "present", password => test_hash; "user2" policy => "present", password => test_passwd; } body password test_hash { format => "hash"; data => "$(test.hash)"; } body password test_passwd { format => "plaintext"; data => "N4wP4ssw"; } ####################################################### bundle agent check { methods: "any" usebundle => user_has_password_hash("user1", "$(test.hash)", "user1_success", "user1_failure"), classes => always("user1_methods_run"); "any" usebundle => user_has_password_hash("user2", "$(init.hash)", "user2_failure", "user2_success"), classes => always("user2_methods_run"); classes: "ready" and => { "user1_methods_run", "user2_methods_run" }; "ok" and => { "user1_success", "!user1_failure", "user2_success", "!user2_failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_unlock_with_password_hpux_trusted.cf0000644000000000000000000000374115010704253034047 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets enabled and the password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "locked"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => test_password; } body password test_password { !windows:: format => "hash"; data => "$(test.hash)"; windows:: format => "plaintext"; data => "Unlocked0P4SSW0RD"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_unlocked("johndoe", "unlock_success", "unlock_failure"), classes => always("unlock_methods_run"); !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "hash_success", "hash_failure"), classes => always("hash_methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Unlocked0P4SSW0RD", "hash_success", "hash_failure"), classes => always("hash_methods_run"); classes: "ready" and => { "unlock_methods_run", "hash_methods_run" }; "ok" and => { "unlock_success", "!unlock_failure", "hash_success", "!hash_failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/15_hpux_set_trusted_mode.cf0000644000000000000000000000117615010704253026775 0ustar00rootroot00000000000000# Not a test, but just setting up trusted mode on HPUX. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { meta: "test_skip_unsupported" string => "!hpux"; classes: "trusted_mode" expression => fileexists("/etc/shadow"), scope => "namespace"; commands: !trusted_mode:: "$(G.echo) yes | /usr/sbin/pwconv" contain => in_shell; } bundle agent check { reports: trusted_mode:: "$(this.promise_filename) Pass"; !trusted_mode:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_add_user_with_password_hpux_trusted.cf0000644000000000000000000000374715010704253031743 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with password"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "plaintext"; data => "J0hnd0eX"; } ####################################################### bundle agent check { methods: !windows:: "any" usebundle => user_get_password_hash("johndoe"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "J0hnd0eX", "pw_ok", "pw_fail"), classes => always("methods_run"); any:: "any" usebundle => user_does_not_need_password_update("johndoe", "no_pw_update_ok", "no_pw_update_fail"); classes: "ready" expression => "methods_run"; !windows:: # Make sure the password field has grown to more than a few characters. "pw_ok" expression => regcmp("^[^:][^:][^:][^:][^:][^:][^:][^:][^:][^:].*", "$(user_get_password_hash.hash)"); any:: "ok" and => { "pw_ok", "!pw_fail", "no_pw_update_ok", "!no_pw_update_fail" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_promise_outcomes.cf0000644000000000000000000001601115010704253025741 0ustar00rootroot00000000000000####################################################### # # Test that promise outcomes are set correctly. # ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Something in the Solaris chroot test environment makes it impossible # to test matching passwords, the pam module always returns error. # This should not happen in a production system though. # Since the error is not on our part, and likely unsolvable, we set # Redmine to zero. However, it would be nice to know if the problem ever # goes away, so using soft_fail. "test_soft_fail" string => "!hpux_trusted_mode_test.(solaris.!sunos_5_9)", meta => { "redmine0" }; # On Solaris 9 PAM just crashes inside chroot. "test_skip_needs_work" string => "!hpux_trusted_mode_test.sunos_5_9"; # AIX doesn't like long names (> 8 chars), so keep them short. # a = absent # p = present # t = attributes # w = password # l = locked # r = repair users: "akeep" policy => "absent"; "arepair" policy => "present"; "pkeep" policy => "present"; "prepair" policy => "absent"; "tkeep" policy => "present", uid => "9878", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, shell => "/bin/csh", description => "Description"; "trepair" policy => "present", uid => "9877", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, shell => "/bin/csh", description => "Description"; "wkeep" policy => "present", password => init_password; "wrepair" policy => "present", password => init_password; "lkeep" policy => "locked"; "lr_byadd" policy => "absent"; "lr_bymod" policy => "present"; } body password init_password { format => "plaintext"; data => "Init0P4SSW0RD"; } ####################################################### bundle agent test { users: !ok:: "akeep" classes => set_classes_kept_repaired("absent_keep", "not_absent_keep"), policy => "absent"; "arepair" classes => set_classes_kept_repaired("not_absent_repair", "absent_repair"), policy => "absent"; "pkeep" classes => set_classes_kept_repaired("present_keep", "not_present_keep"), policy => "present"; "prepair" classes => set_classes_kept_repaired("not_present_repair", "present_repair"), policy => "present"; "tkeep" classes => set_classes_kept_repaired("attributes_keep", "not_attributes_keep"), policy => "present", uid => "9878", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, shell => "/bin/csh", description => "Description"; "trepair" classes => set_classes_kept_repaired("not_attributes_repair", "attributes_repair"), policy => "present", uid => "9877", group_primary => "$(user_tests.group1)", groups_secondary => { }, shell => "/bin/ksh", description => "Description"; "wkeep" classes => set_classes_kept_repaired("password_keep", "not_password_keep"), policy => "present", password => init_password; "wrepair" classes => set_classes_kept_repaired("not_password_repair", "password_repair"), policy => "present", password => test_password; "lkeep" classes => set_classes_kept_repaired("locked_keep", "not_locked_keep"), policy => "locked"; "lr_byadd" classes => set_classes_kept_repaired("not_locked_repair_by_add", "locked_repair_by_add"), policy => "locked"; "lr_bymod" classes => set_classes_kept_repaired("not_locked_repair_by_mod", "locked_repair_by_mod"), policy => "locked"; classes: "and_ok" and => { "absent_keep", "absent_repair", "present_keep", "present_repair", "attributes_keep", "attributes_repair", "password_keep", "password_repair", "locked_keep", "locked_repair_by_add", "locked_repair_by_mod" }; "not_ok" or => { "not_absent_keep", "not_absent_repair", "not_present_keep", "not_present_repair", "not_attributes_keep", "not_attributes_repair", "not_password_keep", "not_password_repair", "not_locked_keep", "not_locked_repair_by_add", "not_locked_repair_by_mod" }; "ok" and => { "and_ok", "!not_ok" }; "fail" or => { "!and_ok", "not_ok" }; reports: !absent_keep.DEBUG:: "absent_keep is NOT set, but should be"; !absent_repair.DEBUG:: "absent_repair is NOT set, but should be"; !present_keep.DEBUG:: "present_keep is NOT set, but should be"; !present_repair.DEBUG:: "present_repair is NOT set, but should be"; !attributes_keep.DEBUG:: "attributes_keep is NOT set, but should be"; !attributes_repair.DEBUG:: "attributes_repair is NOT set, but should be"; !password_keep.DEBUG:: "password_keep is NOT set, but should be"; !password_repair.DEBUG:: "password_repair is NOT set, but should be"; !locked_keep.DEBUG:: "locked_keep is NOT set, but should be"; !locked_repair_by_add.DEBUG:: "locked_repair_by_add is NOT set, but should be"; !locked_repair_by_mod.DEBUG:: "locked_repair_by_mod is NOT set, but should be"; not_absent_keep.DEBUG:: "not_absent_keep is SET, but shouldn't be"; not_absent_repair.DEBUG:: "not_absent_repair is SET, but shouldn't be"; not_present_keep.DEBUG:: "not_present_keep is SET, but shouldn't be"; not_present_repair.DEBUG:: "not_present_repair is SET, but shouldn't be"; not_attributes_keep.DEBUG:: "not_attributes_keep is SET, but shouldn't be"; not_attributes_repair.DEBUG:: "not_attributes_repair is SET, but shouldn't be"; not_password_keep.DEBUG:: "not_password_keep is SET, but shouldn't be"; not_password_repair.DEBUG:: "not_password_repair is SET, but shouldn't be"; not_locked_keep.DEBUG:: "not_locked_keep is SET, but shouldn't be"; not_locked_repair_by_add.DEBUG:: "not_locked_repair_by_add is SET, but shouldn't be"; not_locked_repair_by_mod.DEBUG:: "not_locked_repair_by_mod is SET, but shouldn't be"; ok:: "$(this.promise_filename) Pass"; fail|!ok:: "$(this.promise_filename) FAIL"; } body password test_password { format => "plaintext"; data => "Test0P4SSW0RD"; } body classes set_classes_kept_repaired(x, y) { promise_kept => { "$(x)" }; promise_repaired => { "$(y)" }; } ####################################################### bundle agent check { } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_many_empty_attributes.cf0000644000000000000000000000346715010704253031711 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with several empty attributes"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", group_primary => "", groups_secondary => { }, description => "", classes => if_ok("promise_ok"); } ####################################################### bundle agent check { methods: aix:: # AIX forcibly puts a user in the staff group, even if no group is specified. "any" usebundle => user_is_in_secondary_group("johndoe", "staff", "sgroup_success", "sgroup_failure"), classes => always("sgroup_methods_run"); !aix:: "any" usebundle => user_is_in_any_secondary_group("johndoe", "sgroup_failure", "sgroup_success"), classes => always("sgroup_methods_run"); any:: "any" usebundle => user_has_description("johndoe", "", "desc_success", "desc_failure"), classes => always("desc_methods_run"); classes: "ready" and => { "sgroup_methods_run", "desc_methods_run" }; "ok" and => { "sgroup_success", "!sgroup_failure", "desc_success", "!desc_failure", "promise_ok" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/05_hpux_set_non_trusted_mode.cf0000644000000000000000000000114115010704253027636 0ustar00rootroot00000000000000# Not a test, but just setting up non-trusted mode on HPUX. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { meta: "test_skip_unsupported" string => "!hpux"; classes: "non_trusted_mode" not => fileexists("/etc/shadow"), scope => "namespace"; commands: !not_trusted_mode:: "/usr/sbin/pwunconv"; } bundle agent check { reports: non_trusted_mode:: "$(this.promise_filename) Pass"; !non_trusted_mode:: "$(this.promise_filename) FAIL"; } 20_add_user_with_many_attributes_warn_hpux_trusted.cf0000644000000000000000000000352115010704253034251 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/17_users/unsafebundle common test_meta { vars: "description" string => "A user not present gets added with multiple attributes (dry run only)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "desc_string" string => "This description should make the CFEngine test pass"; users: "johndoe" action => test_action, policy => "present", uid => "9876", group_primary => "$(user_tests.gid1)", groups_secondary => { "$(user_tests.group2)" }, password => test_password, shell => "/bin/csh", description => "$(desc_string)"; } body action test_action { action_policy => "warn"; } body password test_password { format => "hash"; data => "dTloMVpjYt1w2"; } ####################################################### bundle agent check { methods: "any" usebundle => user_exists("johndoe", "failure", "success"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/user_queries.cf.sub0000644000000000000000000002723115010704253025356 0ustar00rootroot00000000000000bundle common user_tests { vars: !windows:: "group1" string => "bin"; "group2" string => "sys"; "gid2" string => "3"; redhat|suse.!suse_15:: "gid1" string => "1"; !redhat.(!suse|suse_15).!windows:: "gid1" string => "2"; windows:: "group1" string => "Users"; "group2" string => "Administrators"; freebsd:: "pw_path" string => "/usr/sbin/pw"; "sudo_path" string => "/usr/local/bin/sudo"; !freebsd:: "pw_path" string => ""; "sudo_path" string => "/usr/bin/sudo"; classes: # On HPUX we use a sudo hack, which doesn't support '-u'. !windows.!hpux:: "sudo_works" expression => "any"; hpux:: "passwords_in_shadow" expression => fileexists("/etc/shadow"); "passwords_in_passwd" not => fileexists("/etc/shadow"); freebsd:: "passwords_in_shadow" expression => "!any"; "passwords_in_passwd" expression => "!any"; "passwords_in_master_passwd" expression => "any"; windows|aix:: "passwords_in_shadow" expression => "!any"; "passwords_in_passwd" expression => "!any"; !hpux.!windows.!aix.!freebsd:: "passwords_in_shadow" expression => "any"; "passwords_in_passwd" expression => "!any"; windows|aix:: "passwords_in_passwd_format" expression => "!any"; !windows.!aix:: "passwords_in_passwd_format" expression => "any"; } bundle agent remove_stale_groups { # When we create a user and change its primary GID afterwards, its original # group may linger and cause problems later. commands: aix:: "rmgroup johndoe" contain => in_shell; !aix:: "$(user_tests.pw_path) groupdel johndoe" contain => in_shell; } bundle agent user_exists(user, true_class, false_class) { commands: !windows:: "$(G.grep) '^$(user):' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); vars: windows:: "output" string => execresult("net user $(user)", "useshell"); "reg" string => escape("$(user)"); classes: windows:: "$(true_class)" expression => regcmp(".*$(reg).*", "$(output)"), scope => "namespace"; "$(false_class)" not => regcmp(".*$(reg).*", "$(output)"), scope => "namespace"; } bundle agent user_has_uid(user, uid, true_class, false_class) { commands: !windows:: "$(G.grep) '^$(user):[^:]*:$(uid):' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); reports: windows:: "Cannot check uid on Windows!"; } bundle agent user_is_in_primary_group(user, group, true_class, false_class) { vars: !windows:: "no" int => getfields("$(group):.*", "/etc/group", ":", "gid_number"); commands: !windows:: "$(G.grep) '^$(user):[^:]*:[^:]*:$(gid_number[3]):' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); methods: windows:: "redirect" usebundle => user_is_in_secondary_group("$(user)", "$(group)", "$(true_class)", "$(false_class)"); } bundle agent user_is_in_secondary_group(user, group, true_class, false_class) { commands: !windows:: "$(G.egrep) '^$(group):[^:]*:[^:]*:[^:]*,?$(user)(,|$)' /etc/group" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); vars: windows:: "output" string => execresult("net user $(user)", "useshell"); "reg" string => escape("$(group)"); classes: windows:: "$(true_class)" expression => regcmp(".*Local Group Memberships *(\*[a-zA-Z0-9]* *)* *$(reg).*", "$(output)"), scope => "namespace"; "$(false_class)" not => regcmp(".*Local Group Memberships *(\*[a-zA-Z0-9]* *)* *$(reg).*", "$(output)"), scope => "namespace"; } bundle agent user_is_in_any_secondary_group(user, true_class, false_class) { commands: !windows:: "$(G.egrep) '^[^:]*:[^:]*:[^:]*:[^:]*,?$(user)(,|$)' /etc/group" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); vars: windows:: "output" string => execresult("net user $(user)", "useshell"); classes: windows:: "$(true_class)" expression => regcmp(".*Local Group Memberships *\*None.*", "$(output)"), scope => "namespace"; "$(false_class)" not => regcmp(".*Local Group Memberships *\*None.*", "$(output)"), scope => "namespace"; } bundle agent user_has_home_dir(user, home_dir, true_class, false_class) { commands: !windows:: "$(G.grep) '^$(user):[^:]*:[^:]*:[^:]*:[^:]*:$(home_dir):' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); vars: windows:: "output" string => execresult("net user $(user)", "useshell"); "reg" string => escape("$(home_dir)"); classes: windows:: "$(true_class)" expression => regcmp(".*Home directory *$(reg).*", "$(output)"), scope => "namespace"; "$(false_class)" not => regcmp(".*Home directory *$(reg).*", "$(output)"), scope => "namespace"; } bundle agent user_has_shell(user, shell, true_class, false_class) { commands: !windows:: "$(G.grep) '^$(user):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:$(shell)$' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); reports: windows:: "Cannot check shell on Windows!"; } bundle agent user_has_description(user, description, true_class, false_class) { commands: !windows:: "$(G.grep) '^$(user):[^:]*:[^:]*:[^:]*:$(description):' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); vars: windows:: "output" string => execresult("net user $(user)", "useshell"); classes: windows:: "$(true_class)" expression => regcmp(".*Full Name *$(description).*", "$(output)"), scope => "namespace"; "$(false_class)" not => regcmp(".*Full Name *$(description).*", "$(output)"), scope => "namespace"; } bundle agent user_has_password(user, password, true_class, false_class) { reports: !windows:: "Cannot test password on Unix!"; classes: windows.has_psexec:: "$(true_class)" expression => returnszero("$(G.psexec) -u $(user) -p $(password) $(sys.cf_agent) -h", "noshell"), scope => "namespace"; "$(false_class)" not => returnszero("$(G.psexec) -u $(user) -p $(password) $(sys.cf_agent) -h", "noshell"), scope => "namespace"; reports: windows.!has_psexec:: "Need PsExec.exe tool from PSTools to test password!"; } bundle agent user_has_password_hash(user, hash, true_class, false_class) { vars: !aix:: "escaped_hash" string => escape("$(hash)"); aix:: "user_hash" string => execresult("$(this.promise_dirname)/aix_get_shadow_field.pl password $(user)", "useshell"); passwords_in_passwd:: "passwd_file" string => "/etc/passwd"; passwords_in_shadow:: "passwd_file" string => "/etc/shadow"; passwords_in_master_passwd:: "passwd_file" string => "/etc/master.passwd"; classes: aix:: "$(true_class)" expression => strcmp($(hash), $(user_hash)), scope => "namespace"; "$(false_class)" not => strcmp($(hash), $(user_hash)), scope => "namespace"; commands: passwords_in_passwd_format:: "$(G.grep) '^$(user):$(escaped_hash):' $(passwd_file)" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); reports: windows:: "Cannot test password hash on Windows!"; } bundle agent user_get_password_hash(user) { vars: passwords_in_passwd:: "passwd_file" string => "/etc/passwd"; passwords_in_shadow:: "passwd_file" string => "/etc/shadow"; passwords_in_passwd_format:: "hash" string => execresult("$(G.grep) '^$(user):' $(passwd_file) | $(G.sed) -e 's/[^:]*:\([^:]*\):.*/\1/'", "useshell"); aix:: "hash" string => execresult("$(this.promise_dirname)/aix_get_shadow_field.pl password $(user)", "useshell"); reports: windows:: "Cannot get password hash on Windows!"; } bundle agent user_is_locked(user, true_class, false_class) { vars: solaris:: # Solaris doesn't support expiry date properly (see users promise code). "expiry_date" string => ""; !solaris:: # Expiry date should be something non-empty. "expiry_date" string => "[^:]"; aix:: "user_hash" string => execresult("$(this.promise_dirname)/aix_get_shadow_field.pl password $(user)", "useshell"); classes: aix:: "$(true_class)" expression => regcmp("!.*", $(user_hash)), scope => "namespace"; "$(false_class)" not => regcmp("!.*", $(user_hash)), scope => "namespace"; commands: passwords_in_shadow:: # Notice the [^:] without * at the end. That field (expiry) should be *something*. "$(G.grep) '^$(user):![^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:$(expiry_date)[^:]*:' /etc/shadow" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); passwords_in_passwd:: "$(G.grep) '^$(user):![^:]*:' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); vars: windows:: "output" string => execresult("net user $(user)", "useshell"); classes: windows:: "$(true_class)" expression => regcmp(".*Account active *No.*", "$(output)"), scope => "namespace"; "$(false_class)" not => regcmp(".*Account active *No.*", "$(output)"), scope => "namespace"; } bundle agent user_is_unlocked(user, true_class, false_class) { vars: aix:: "user_hash" string => execresult("$(this.promise_dirname)/aix_get_shadow_field.pl password $(user)", "useshell"); classes: aix:: "$(true_class)" not => regcmp("!.*", $(user_hash)), scope => "namespace"; "$(false_class)" expression => regcmp("!.*", $(user_hash)), scope => "namespace"; commands: passwords_in_shadow:: # Notice the field at the end. That field (expiry) should be gone or zero. "$(G.egrep) '^$(user):[^:!]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:(:|0:)' /etc/shadow" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); passwords_in_passwd:: "$(G.grep) '^$(user):[^:!]*:' /etc/passwd" contain => no_output_shell, classes => on_success("$(true_class)", "$(false_class)"); vars: windows:: "output" string => execresult("net user $(user)", "useshell"); classes: windows:: "$(true_class)" expression => regcmp(".*Account active *Yes.*", "$(output)"), scope => "namespace"; "$(false_class)" not => regcmp(".*Account active *Yes.*", "$(output)"), scope => "namespace"; } # Some platforms add a flag that forces the user to change the password. bundle agent user_does_not_need_password_update(user, true_class, false_class) { vars: aix:: "flags" string => execresult("$(this.promise_dirname)/aix_get_shadow_field.pl flags $(user)", "useshell"); classes: aix:: "$(true_class)" not => regcmp(".*ADMCHG.*", "$(flags)"), scope => "namespace"; "$(false_class)" expression => regcmp(".*ADMCHG.*", "$(flags)"), scope => "namespace"; !aix:: "$(true_class)" expression => "any", scope => "namespace"; } body classes on_success(true_class, false_class) { promise_repaired => { "$(true_class)" }; repair_failed => { "$(false_class)" }; cancel_notkept => { "$(true_class)" }; cancel_repaired => { "$(false_class)" }; } body contain no_output_shell { no_output => "true"; useshell => "useshell"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_with_hashed_password.cf0000644000000000000000000000352315010704253031167 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the hashed password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present", password => init_password; } body password init_password { format => "plaintext"; data => "Bad0P4SSW0RD"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "success", "failure"), classes => always("methods_run"); windows:: # Hash not supported on Windows. Make sure it is the same as before. "any" usebundle => user_has_password("johndoe", "Bad0P4SSW0RD", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_secondary_groups.cf0000644000000000000000000000345615010704253030352 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { commands: "$(G.sudo) $(user_tests.pw_path) $(G.userdel) testu"; "$(G.sudo) $(user_tests.pw_path) $(G.groupdel) testu"; "$(G.sudo) $(user_tests.pw_path) $(G.groupdel) testg1"; "$(G.sudo) $(user_tests.pw_path) $(G.groupdel) testg2"; "$(G.sudo) $(user_tests.pw_path) $(G.groupadd) testg1"; "$(G.sudo) $(user_tests.pw_path) $(G.useradd) testu"; freebsd:: "$(G.sudo) $(user_tests.pw_path) $(G.usermod) testu -G testg1"; !freebsd:: "$(G.sudo) $(user_tests.pw_path) $(G.usermod) -G testg1 testu"; } bundle agent test { meta: "description" -> { "ENT-3710" } string => "Adding a secondary group which doesn't exist should not remove existing secondary groups"; users: "testu" groups_secondary => { "testg1", "testg2" }, policy => "present"; } bundle agent check { methods: "any" usebundle => user_is_in_secondary_group("testu", "testg1", "testg1_success", "testg1_failure"), classes => always("testg1_method_run"); "any" usebundle => user_is_in_secondary_group("testu", "testg2", "testg2_success", "testg2_failure"), classes => always("testg2_method_run"); "any" usebundle => user_exists("testu", "testu_success", "testu_failure"), classes => always("testu_method_run"); classes: "ready" and => { "testg1_method_run", "testg2_method_run", "testu_method_run" }; "ok" and => { "testg1_success", "!testg1_failure", "!testg2_success", "testg2_failure", "testu_success", "!testu_failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_remove_user_warn.cf0000644000000000000000000000221715010704253025732 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets removed (dry run)"; "story_id" string => "5526"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" action => test_action, policy => "absent"; } body action test_action { action_policy => "warn"; } ####################################################### bundle agent check { methods: "any" usebundle => user_exists("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } 10_newly_created_account_should_not_count_as_locked.cf0000644000000000000000000000361315010704253034305 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/17_users/unsafebundle common test_meta { vars: "description" string => "A user present gets locked"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### # # Test that a newly created account does not confuse # our locking detection. This may happen because # "useradd" initially sets the password to '!'. # ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Delete user, then create. vars: "users[n1]" string => "johndoe"; "users[n2]" string => "johndoe"; "policies[n1]" string => "absent"; "policies[n2]" string => "present"; "iter" slist => { "n1", "n2" }; users: "$(users[$(iter)])" policy => "$(policies[$(iter)])"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "locked", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_with_many_attributes_hpux_trusted.cf0000644000000000000000000001116015010704253034036 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets several attributes changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Start out with other attributes. users: "johndoe" policy => "present", password => init_password, uid => "8765", group_primary => "$(user_tests.gid2)", groups_secondary => { "$(user_tests.group1)" }, home_dir => "/home/johndoe", shell => "/bin/bash", description => "Wrong!"; } body password init_password { format => "plaintext"; data => "Wrong0P4SSW0RD"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; "desc_string" string => "This description should make the CFEngine test pass"; users: "johndoe" policy => "present", password => test_password, uid => "9876", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, home_dir => "/home/user-johndoe", shell => "/bin/csh", description => "$(desc_string)"; } body password test_password { !windows:: format => "hash"; data => "$(test.hash)"; windows:: format => "plaintext"; data => "New0P4SSW0RD"; } ####################################################### bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: "any" usebundle => user_has_uid("johndoe", "9876", "uid_success", "uid_failure"), classes => always("uid_methods_run"); "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group1)", "pgroup_success", "pgroup_failure"), classes => always("pgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group2)", "sgroup_success", "sgroup_failure"), classes => always("sgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "not_sgroup_failure", "not_sgroup_success"), classes => always("not_sgroup_methods_run"); "any" usebundle => user_has_home_dir("johndoe", "/home/user-johndoe", "home_success", "home_failure"), classes => always("home_methods_run"); "any" usebundle => user_has_shell("johndoe", "/bin/csh", "shell_success", "shell_failure"), classes => always("shell_methods_run"); "any" usebundle => user_has_description("johndoe", "$(test.desc_string)", "desc_success", "desc_failure"), classes => always("desc_methods_run"); !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "hash_success", "hash_failure"), classes => always("hash_methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "New0P4SSW0RD", "hash_success", "hash_failure"), classes => always("hash_methods_run"); classes: "ready" and => { "uid_methods_run", "pgroup_methods_run", "sgroup_methods_run", "not_sgroup_methods_run", "home_methods_run", "shell_methods_run", "desc_methods_run", "hash_methods_run" }; !windows:: # Note the secondary group classes here. Windows treats primary and secondary groups the same, # and hence that test is invalid there. "unix_ok" and => { "uid_success", "!uid_failure", "shell_success", "!shell_failure", "not_sgroup_success", "!not_sgroup_failure", }; windows:: "unix_ok" expression => "any"; sles_11:: "ok" -> "CFE-3386" and => { "pgroup_success", "!pgroup_failure", "!sgroup_success", "sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; !sles_11:: "ok" and => { "pgroup_success", "!pgroup_failure", "sgroup_success", "!sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_home_bundle_with_new_user_and_inherit.cf0000644000000000000000000000267015010704253032142 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user added gets the home bundle run (2)"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { classes: "should_prevent_edits" expression => "any"; users: "johndoe" policy => "present", home_bundle => home_bundle("/home/johndoe"), home_bundle_inherit => "true"; } bundle agent home_bundle(x) { files: # Class selector should prevent edits since we're supposed to inherit classes. !should_prevent_edits:: "$(G.testfile)" create => "true", edit_line => home_edit("$(x)"); } bundle edit_line home_edit(x) { insert_lines: "$(x)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("0", countlinesmatching("/home/johndoe", "$(G.testfile)")); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_missing_secondary_group.cf0000644000000000000000000000346115010704253031714 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { commands: "$(G.sudo) $(user_tests.pw_path) $(G.userdel) testu"; "$(G.sudo) $(user_tests.pw_path) $(G.groupdel) testu"; "$(G.sudo) $(user_tests.pw_path) $(G.groupdel) testg1"; "$(G.sudo) $(user_tests.pw_path) $(G.groupdel) testg2"; "$(G.sudo) $(user_tests.pw_path) $(G.groupadd) testg1"; "$(G.sudo) $(user_tests.pw_path) $(G.useradd) testu"; freebsd:: "$(G.sudo) $(user_tests.pw_path) $(G.usermod) testu -G testg1"; !freebsd:: "$(G.sudo) $(user_tests.pw_path) $(G.usermod) -G testg1 testu"; } bundle agent test { meta: "description" -> { "ENT-3710" } string => "Managing a user without specifying any secondary groups attribute should result in no changes to existing secondary groups."; users: "testu" policy => "present"; } bundle agent check { methods: "any" usebundle => user_is_in_secondary_group("testu", "testg1", "testg1_success", "testg1_failure"), classes => always("testg1_method_run"); "any" usebundle => user_is_in_secondary_group("testu", "testg2", "testg2_success", "testg2_failure"), classes => always("testg2_method_run"); "any" usebundle => user_exists("testu", "testu_success", "testu_failure"), classes => always("testu_method_run"); classes: "ready" and => { "testg1_method_run", "testg2_method_run", "testu_method_run" }; "ok" and => { "testg1_success", "!testg1_failure", "!testg2_success", "testg2_failure", "testu_success", "!testu_failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_missing_policy.cf0000644000000000000000000000207715010704253025404 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added when there is no policy attribute"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe"; } ####################################################### bundle agent check { methods: "any" usebundle => user_exists("johndoe", "failure", "success"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_unlock_hpux_trusted.cf0000644000000000000000000000244115010704253031066 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets enabled"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "locked"; } ####################################################### bundle agent test { users: "johndoe" policy => "present"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_unlocked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_with_many_empty_attributes.cf0000644000000000000000000000466415010704253032450 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets multiple empty attributes changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Create him first with some unwanted attributes users: "johndoe" policy => "present", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, description => "Description"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", group_primary => "", groups_secondary => { }, description => ""; } ####################################################### bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: windows:: "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group1)", "pgroup_failure", "pgroup_success"), classes => always("pgroup_methods_run"); # Unix hosts cannot remove the primary group. !windows:: "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group1)", "pgroup_success", "pgroup_failure"), classes => always("pgroup_methods_run"); aix:: # AIX forcibly puts a user in the primary group, even if no group is specified. "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "sgroup_success", "sgroup_failure"), classes => always("sgroup_methods_run"); !aix:: "any" usebundle => user_is_in_any_secondary_group("johndoe", "sgroup_failure", "sgroup_success"), classes => always("sgroup_methods_run"); any:: "any" usebundle => user_has_description("johndoe", "", "desc_success", "desc_failure"), classes => always("desc_methods_run"); classes: "ready" and => { "pgroup_methods_run", "sgroup_methods_run", "desc_methods_run" }; "ok" and => { "pgroup_success", "!pgroup_failure", "sgroup_success", "!sgroup_failure", "desc_success", "!desc_failure", }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_primary_gid.cf0000644000000000000000000000425415010704253027562 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with primary group id"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub", "disable_sudo_tty_requirement.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { meta: # No GIDs on Windows. "test_skip_unsupported" string => "windows"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; files: "$(G.testfile)" delete => init_delete; methods: "any" usebundle => disable_sudo_tty_requirement; } body delete init_delete { rmdirs => "false"; } ####################################################### body contain test_contain_body { useshell => "useshell"; } bundle agent test { users: "johndoe" policy => "present", group_primary => "$(user_tests.gid1)"; commands: sudo_works:: "sudo -u johndoe $(G.touch) $(G.testfile)" contain => test_contain_body; } ####################################################### body perms check_perms_body { groups => { "$(user_tests.gid1)" }; } body classes check_classes_body { promise_repaired => { "perms_not_ok" }; promise_kept => { "perms_ok" }; } bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group1)", "success", "failure"), classes => always("methods_run"); files: "$(G.testfile)" perms => check_perms_body, classes => check_classes_body; classes: "ready" expression => "methods_run"; sudo_works:: "ok" and => { "success", "!failure", "perms_ok", "!perms_not_ok" }; !sudo_works:: "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_with_same_password_hpux_trusted.cf0000644000000000000000000000520715010704253033500 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the password set to the same as before"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Something in the Solaris chroot test environment makes it impossible # to test matching passwords, the pam module always returns error. # This should not happen in a production system though. # Since the error is not on our part, and likely unsolvable, we set # Redmine to zero. However, it would be nice to know if the problem ever # goes away, so using soft_fail. "test_soft_fail" string => "!hpux_trusted_mode_test.(solaris.!sunos_5_9)", meta => { "redmine0" }; # On Solaris 9 PAM just crashes inside chroot. "test_skip_needs_work" string => "!hpux_trusted_mode_test.sunos_5_9"; vars: # This is the same password as the plaintext one further down. "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "J0hnd0eX"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password, classes => if_repaired("kept_failed"); } body password test_password { format => "plaintext"; data => "J0hnd0eX"; } ####################################################### bundle agent check { methods: # Make sure it is the same as before. !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "success", "failure"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "J0hnd0eX", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure", "!kept_failed" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_several_secondary_groups.cf0000644000000000000000000000515715010704253032366 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with several secondary groups"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub", "disable_sudo_tty_requirement.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### body perms init_perms_body_bin { groups => { "$(user_tests.group1)" }; mode => "664"; } body perms init_perms_body_sys { groups => { "$(user_tests.group2)" }; mode => "664"; } bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; files: "$(G.testfile)" create => "true", perms => init_perms_body_bin; "$(G.testfile).2" create => "true", perms => init_perms_body_sys; methods: "any" usebundle => disable_sudo_tty_requirement; } ####################################################### body contain test_contain_body { useshell => "useshell"; } bundle agent test { users: "johndoe" policy => "present", groups_secondary => { "$(user_tests.group1)", "$(user_tests.group2)" }; commands: sudo_works:: "sudo -u johndoe /bin/sh -c '$(G.echo) Succeeded > $(G.testfile)'" contain => test_contain_body; "sudo -u johndoe /bin/sh -c '$(G.echo) Succeeded > $(G.testfile).2'" contain => test_contain_body; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "bin_success", "bin_failure"), classes => always("bin_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group2)", "sys_success", "sys_failure"), classes => always("sys_methods_run"); classes: !windows:: "1_ok" not => strcmp("0", countlinesmatching("Succeeded", "$(G.testfile)")); "2_ok" not => strcmp("0", countlinesmatching("Succeeded", "$(G.testfile).2")); classes: "ready" and => { "bin_methods_run", "sys_methods_run" }; sudo_works:: "ok" and => { "bin_success", "!bin_failure", "sys_success", "!sys_failure", "1_ok", "2_ok" }; !sudo_works:: "ok" and => { "bin_success", "!bin_failure", "sys_success", "!sys_failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_with_hashed_password_hpux_trusted.cf0000644000000000000000000000352315010704253034006 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the hashed password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present", password => init_password; } body password init_password { format => "plaintext"; data => "Bad0P4SSW0RD"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "success", "failure"), classes => always("methods_run"); windows:: # Hash not supported on Windows. Make sure it is the same as before. "any" usebundle => user_has_password("johndoe", "Bad0P4SSW0RD", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_warn.cf0000644000000000000000000000231215010704253025161 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added (dry run only)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe" action => test_action, policy => "present"; } body action test_action { action_policy => "warn"; } ####################################################### bundle agent check { methods: "any" usebundle => user_exists("johndoe", "failure", "success"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_password_with_no_format_hpux_trusted.cf0000644000000000000000000000362715010704253032136 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present has the password unchanged when password format is unspecified"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: # "j0hnd0e" "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "Old0P4SSW0RD"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { data => "New0P4SSW0RD"; } ####################################################### bundle agent check { methods: # Make sure it is the same as before. !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "success", "failure"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Old0P4SSW0RD", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_hashed_password.cf0000644000000000000000000000313315010704253030425 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with password"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: # Password hash unsupported on Windows. (ok.ready)|windows:: "$(this.promise_filename) Pass"; (!ok.ready).!windows:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_with_same_password.cf0000644000000000000000000000520715010704253030661 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the password set to the same as before"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Something in the Solaris chroot test environment makes it impossible # to test matching passwords, the pam module always returns error. # This should not happen in a production system though. # Since the error is not on our part, and likely unsolvable, we set # Redmine to zero. However, it would be nice to know if the problem ever # goes away, so using soft_fail. "test_soft_fail" string => "!hpux_trusted_mode_test.(solaris.!sunos_5_9)", meta => { "redmine0" }; # On Solaris 9 PAM just crashes inside chroot. "test_skip_needs_work" string => "!hpux_trusted_mode_test.sunos_5_9"; vars: # This is the same password as the plaintext one further down. "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "J0hnd0eX"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password, classes => if_repaired("kept_failed"); } body password test_password { format => "plaintext"; data => "J0hnd0eX"; } ####################################################### bundle agent check { methods: # Make sure it is the same as before. !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "success", "failure"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "J0hnd0eX", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure", "!kept_failed" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_with_password.cf0000644000000000000000000000401515010704253027650 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { data => "$(init.hash)"; !windows:: format => "hash"; windows:: format => "plaintext"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "plaintext"; data => "New0P4SSW0RD"; } ####################################################### bundle agent check { methods: !windows:: # Make sure it is *not* the same as before. "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "failure", "success"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "New0P4SSW0RD", "success", "failure"), classes => always("methods_run"); any:: "any" usebundle => user_does_not_need_password_update("johndoe", "no_pw_update_ok", "no_pw_update_fail"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure", "no_pw_update_ok", "!no_pw_update_fail" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/add_user_with_shell.txt0000644000000000000000000000003315010704253026301 0ustar00rootroot00000000000000#!/bin/sh exit 0 Succeeded cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_unlock_with_password.cf0000644000000000000000000000374115010704253031230 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets enabled and the password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "locked"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => test_password; } body password test_password { !windows:: format => "hash"; data => "$(test.hash)"; windows:: format => "plaintext"; data => "Unlocked0P4SSW0RD"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_unlocked("johndoe", "unlock_success", "unlock_failure"), classes => always("unlock_methods_run"); !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "hash_success", "hash_failure"), classes => always("hash_methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Unlocked0P4SSW0RD", "hash_success", "hash_failure"), classes => always("hash_methods_run"); classes: "ready" and => { "unlock_methods_run", "hash_methods_run" }; "ok" and => { "unlock_success", "!unlock_failure", "hash_success", "!hash_failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_uid.cf0000644000000000000000000000270415010704253026033 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with uid"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; files: "$(G.testfile)" delete => init_delete; } body delete init_delete { rmdirs => "false"; } ####################################################### body perms test_perms_body { owners => { "johndoe" }; } bundle agent test { users: "johndoe" policy => "present", uid => "9999"; files: "$(G.testfile)" create => "true", perms => test_perms_body; } ####################################################### body perms check_perms_body { owners => { "9999" }; } body classes check_classes_body { promise_repaired => { "not_ok" }; promise_kept => { "ok" }; } bundle agent check { files: "$(G.testfile)" perms => check_perms_body, classes => check_classes_body; reports: (ok.!not_ok)|windows:: "$(this.promise_filename) Pass"; (!ok|not_ok).!windows:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_password.cf0000644000000000000000000000374715010704253027124 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with password"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "plaintext"; data => "J0hnd0eX"; } ####################################################### bundle agent check { methods: !windows:: "any" usebundle => user_get_password_hash("johndoe"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "J0hnd0eX", "pw_ok", "pw_fail"), classes => always("methods_run"); any:: "any" usebundle => user_does_not_need_password_update("johndoe", "no_pw_update_ok", "no_pw_update_fail"); classes: "ready" expression => "methods_run"; !windows:: # Make sure the password field has grown to more than a few characters. "pw_ok" expression => regcmp("^[^:][^:][^:][^:][^:][^:][^:][^:][^:][^:].*", "$(user_get_password_hash.hash)"); any:: "ok" and => { "pw_ok", "!pw_fail", "no_pw_update_ok", "!no_pw_update_fail" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_add_user_locked_hpux_trusted.cf0000644000000000000000000000253315010704253030277 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added locked"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe" policy => "locked"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_unlock_warn_hpux_trusted.cf0000644000000000000000000000262215010704253032116 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets enabled and the password changed (dry run)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "locked"; } ####################################################### bundle agent test { users: "johndoe" action => test_action, policy => "present"; } body action test_action { action_policy => "warn"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } 20_newly_created_account_should_not_count_as_locked_hpux_trusted.cf0000644000000000000000000000361315010704253037124 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/17_users/unsafebundle common test_meta { vars: "description" string => "A user present gets locked"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### # # Test that a newly created account does not confuse # our locking detection. This may happen because # "useradd" initially sets the password to '!'. # ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Delete user, then create. vars: "users[n1]" string => "johndoe"; "users[n2]" string => "johndoe"; "policies[n1]" string => "absent"; "policies[n2]" string => "present"; "iter" slist => { "n1", "n2" }; users: "$(users[$(iter)])" policy => "$(policies[$(iter)])"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "locked", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_with_many_attributes_warn.cf0000644000000000000000000001131715010704253032252 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets many attributes changed (dry run)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: "hash" string => "dTloMVpjYt1w2"; # Start out with other attributes. users: "johndoe" policy => "present", password => init_password, uid => "8765", group_primary => "$(user_tests.group2)", groups_secondary => { "$(user_tests.group1)" }, home_dir => "/johns_old_home_dir", shell => "/bin/csh", description => "Good user"; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "Old0P4SSW0RD"; } ####################################################### bundle agent test { vars: "desc_string" string => "This description should make the CFEngine test fail"; users: "johndoe" action => test_action, policy => "present", password => test_password, uid => "9876", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, home_dir => "/johns_home_dir", shell => "/bin/sh", description => "$(desc_string)"; } body action test_action { action_policy => "warn"; } body password test_password { format => "plaintext"; data => "Wrong0P4SSW0RD"; } ####################################################### bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: "any" usebundle => user_has_uid("johndoe", "8765", "uid_success", "uid_failure"), classes => always("uid_methods_run"); "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group2)", "pgroup_success", "pgroup_failure"), classes => always("pgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "sgroup_success", "sgroup_failure"), classes => always("sgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group2)", "not_sgroup_failure", "not_sgroup_success"), classes => always("not_sgroup_methods_run"); "any" usebundle => user_has_home_dir("johndoe", "/johns_old_home_dir", "home_success", "home_failure"), classes => always("home_methods_run"); "any" usebundle => user_has_shell("johndoe", "/bin/csh", "shell_success", "shell_failure"), classes => always("shell_methods_run"); "any" usebundle => user_has_description("johndoe", "Good user", "desc_success", "desc_failure"), classes => always("desc_methods_run"); !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "hash_success", "hash_failure"), classes => always("hash_methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Wrong0P4SSW0RD", "hash_failure", "hash_success"), classes => always("hash_methods_run"); classes: "ready" and => { "uid_methods_run", "pgroup_methods_run", "sgroup_methods_run", "not_sgroup_methods_run", "home_methods_run", "shell_methods_run", "desc_methods_run", "hash_methods_run" }; !windows:: # Note the secondary group classes here. Windows treats primary and secondary groups the same, # and hence that test is invalid there. "unix_ok" and => { "uid_success", "!uid_failure", "shell_success", "!shell_failure", "not_sgroup_success", "!not_sgroup_failure", }; windows:: "unix_ok" expression => "any"; sles_11:: "ok" -> "CFE-3386" and => { "pgroup_success", "!pgroup_failure", "!sgroup_success", "sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; !sles_11:: "ok" and => { "pgroup_success", "!pgroup_failure", "sgroup_success", "!sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_lock_with_password.cf0000644000000000000000000000272615010704253030667 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets locked and the password changed"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "locked", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_lock_warn_hpux_trusted.cf0000644000000000000000000000257215010704253031557 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets locked (dry run)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" action => test_action, policy => "locked"; } body action test_action { action_policy => "warn"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_unlocked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_unlock_warn.cf0000644000000000000000000000262215010704253027277 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets enabled and the password changed (dry run)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "locked"; } ####################################################### bundle agent test { users: "johndoe" action => test_action, policy => "present"; } body action test_action { action_policy => "warn"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_password_with_no_data_hpux_trusted.cf0000644000000000000000000000361215010704253031551 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the password unchanged when it is unspecified"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: # "j0hnd0e" "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "Old0P4SSW0RD"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "plaintext"; } ####################################################### bundle agent check { methods: # Make sure it is the same as before. !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "success", "failure"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Old0P4SSW0RD", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_secondary_group.cf0000644000000000000000000000371115010704253030454 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with secondary group"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub", "disable_sudo_tty_requirement.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### body perms init_perms_body { groups => { "$(user_tests.group1)" }; mode => "664"; } bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; files: "$(G.testfile)" create => "true", perms => init_perms_body; methods: "any" usebundle => disable_sudo_tty_requirement; } ####################################################### body contain test_contain_body { useshell => "useshell"; } bundle agent test { users: "johndoe" policy => "present", groups_secondary => { "$(user_tests.group1)" }; commands: sudo_works:: "sudo -u johndoe /bin/sh -c '$(G.echo) Succeeded > $(G.testfile)'" contain => test_contain_body; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "success", "failure"), classes => always("methods_run"); classes: sudo_works:: "content_ok" not => strcmp("0", countlinesmatching("Succeeded", "$(G.testfile)")); classes: "ready" expression => "methods_run"; sudo_works:: "ok" and => { "success", "!failure", "content_ok" }; !sudo_works:: "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_add_user_with_hashed_password_hpux_trusted.cf0000644000000000000000000000313315010704253033244 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with password"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "hash"; data => "$(test.hash)"; } ####################################################### bundle agent check { methods: "any" usebundle => user_has_password_hash("johndoe", "$(test.hash)", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: # Password hash unsupported on Windows. (ok.ready)|windows:: "$(this.promise_filename) Pass"; (!ok.ready).!windows:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_primary_group.cf0000644000000000000000000000415415010704253030152 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with primary group"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub", "disable_sudo_tty_requirement.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; files: "$(G.testfile)" delete => init_delete; methods: "any" usebundle => disable_sudo_tty_requirement; } body delete init_delete { rmdirs => "false"; } ####################################################### body contain test_contain_body { useshell => "useshell"; } bundle agent test { users: "johndoe" policy => "present", group_primary => "$(user_tests.group1)"; commands: sudo_works:: "sudo -u johndoe $(G.touch) $(G.testfile)" contain => test_contain_body; } ####################################################### body perms check_perms_body { groups => { "$(user_tests.group1)" }; } body classes check_classes_body { promise_repaired => { "perms_not_ok" }; promise_kept => { "perms_ok" }; } bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group1)", "success", "failure"), classes => always("methods_run"); files: sudo_works:: "$(G.testfile)" perms => check_perms_body, classes => check_classes_body; classes: "ready" expression => "methods_run"; sudo_works:: "ok" and => { "success", "!failure", "perms_ok", "!perms_not_ok" }; !sudo_works:: "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_home_bundle_with_existing_user.cf0000644000000000000000000000226515010704253030637 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present does not get the home bundle run"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", home_bundle => home_bundle("/home/johndoe"); } bundle agent home_bundle(x) { files: "$(G.testfile)" create => "true", edit_line => home_edit("$(x)"); } bundle edit_line home_edit(x) { insert_lines: "$(x)"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("0", countlinesmatching("/home/johndoe", "$(G.testfile)")); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_password_with_no_format.cf0000644000000000000000000000362715010704253027317 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present has the password unchanged when password format is unspecified"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: # "j0hnd0e" "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "Old0P4SSW0RD"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { data => "New0P4SSW0RD"; } ####################################################### bundle agent check { methods: # Make sure it is the same as before. !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "success", "failure"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Old0P4SSW0RD", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/20_modify_user_lock_hpux_trusted.cf0000644000000000000000000000244515010704253030527 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets set to locked"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" policy => "locked"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_locked.cf0000644000000000000000000000253315010704253025460 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added locked"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { users: "johndoe" policy => "locked"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_home_bundle_with_new_user_and_default_inherit.cf0000644000000000000000000000262515010704253033646 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user added gets the home bundle run"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { classes: "should_not_prevent_edits" expression => "any"; users: "johndoe" policy => "present", home_bundle => home_bundle("/home/johndoe"); } bundle agent home_bundle(x) { files: # Class selector should have no effect since we're not supposed to inherit classes. !should_not_prevent_edits:: "$(G.testfile)" create => "true", edit_line => home_edit("$(x)"); } bundle edit_line home_edit(x) { insert_lines: "$(x)"; } ####################################################### bundle agent check { classes: "ok" not => strcmp("0", countlinesmatching("/home/johndoe", "$(G.testfile)")); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_many_attributes_warn.cf0000644000000000000000000000352115010704253031511 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with multiple attributes (dry run only)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { vars: "desc_string" string => "This description should make the CFEngine test pass"; users: "johndoe" action => test_action, policy => "present", uid => "9876", group_primary => "$(user_tests.gid1)", groups_secondary => { "$(user_tests.group2)" }, password => test_password, shell => "/bin/csh", description => "$(desc_string)"; } body action test_action { action_policy => "warn"; } body password test_password { format => "hash"; data => "dTloMVpjYt1w2"; } ####################################################### bundle agent check { methods: "any" usebundle => user_exists("johndoe", "failure", "success"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_password_with_no_data.cf0000644000000000000000000000361215010704253026732 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets the password unchanged when it is unspecified"; "story_id" string => "5525"; "covers" string => "operational_kept"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: # "j0hnd0e" "hash" string => "dTloMVpjYt1w2"; users: "johndoe" policy => "present", password => init_password; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "Old0P4SSW0RD"; } ####################################################### bundle agent test { users: "johndoe" policy => "present", password => test_password; } body password test_password { format => "plaintext"; } ####################################################### bundle agent check { methods: # Make sure it is the same as before. !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "success", "failure"), classes => always("methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Old0P4SSW0RD", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_add_user_with_secondary_gid.cf0000644000000000000000000000424415010704253030065 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user not present gets added with secondary group id"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub", "disable_sudo_tty_requirement.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### body perms init_perms_body { groups => { "$(user_tests.gid1)" }; mode => "664"; } bundle agent init { # AIX useradd/usermod commands do not support numerical group arguments. meta: "test_soft_fail" string => "aix", meta => { "redmine6285" }; # No GIDs on Windows. "test_skip_unsupported" string => "windows"; # Remove him first, should he already be present. users: "johndoe" policy => "absent"; files: "$(G.testfile)" create => "true", perms => init_perms_body; methods: "any" usebundle => disable_sudo_tty_requirement; } ####################################################### body contain test_contain_body { useshell => "useshell"; } bundle agent test { users: "johndoe" policy => "present", groups_secondary => { "$(user_tests.gid1)" }; commands: sudo_works:: "sudo -u johndoe /bin/sh -c '$(G.echo) Succeeded > $(G.testfile)'" contain => test_contain_body; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "success", "failure"), classes => always("methods_run"); classes: "content_ok" not => strcmp("0", countlinesmatching("Succeeded", "$(G.testfile)")); classes: "ready" expression => "methods_run"; sudo_works:: "ok" and => { "success", "!failure", "content_ok" }; !sudo_works:: "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_lock.cf0000644000000000000000000000244515010704253025710 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets set to locked"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" policy => "locked"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_locked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } 20_modify_user_with_many_attributes_warn_hpux_trusted.cf0000644000000000000000000001131715010704253035012 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/17_users/unsafebundle common test_meta { vars: "description" string => "A user present gets many attributes changed (dry run)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; vars: "hash" string => "dTloMVpjYt1w2"; # Start out with other attributes. users: "johndoe" policy => "present", password => init_password, uid => "8765", group_primary => "$(user_tests.group2)", groups_secondary => { "$(user_tests.group1)" }, home_dir => "/johns_old_home_dir", shell => "/bin/csh", description => "Good user"; } body password init_password { !windows:: format => "hash"; data => "$(init.hash)"; windows:: format => "plaintext"; data => "Old0P4SSW0RD"; } ####################################################### bundle agent test { vars: "desc_string" string => "This description should make the CFEngine test fail"; users: "johndoe" action => test_action, policy => "present", password => test_password, uid => "9876", group_primary => "$(user_tests.group1)", groups_secondary => { "$(user_tests.group2)" }, home_dir => "/johns_home_dir", shell => "/bin/sh", description => "$(desc_string)"; } body action test_action { action_policy => "warn"; } body password test_password { format => "plaintext"; data => "Wrong0P4SSW0RD"; } ####################################################### bundle agent check { methods: "any" usebundle => remove_stale_groups; methods: "any" usebundle => user_has_uid("johndoe", "8765", "uid_success", "uid_failure"), classes => always("uid_methods_run"); "any" usebundle => user_is_in_primary_group("johndoe", "$(user_tests.group2)", "pgroup_success", "pgroup_failure"), classes => always("pgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group1)", "sgroup_success", "sgroup_failure"), classes => always("sgroup_methods_run"); "any" usebundle => user_is_in_secondary_group("johndoe", "$(user_tests.group2)", "not_sgroup_failure", "not_sgroup_success"), classes => always("not_sgroup_methods_run"); "any" usebundle => user_has_home_dir("johndoe", "/johns_old_home_dir", "home_success", "home_failure"), classes => always("home_methods_run"); "any" usebundle => user_has_shell("johndoe", "/bin/csh", "shell_success", "shell_failure"), classes => always("shell_methods_run"); "any" usebundle => user_has_description("johndoe", "Good user", "desc_success", "desc_failure"), classes => always("desc_methods_run"); !windows:: "any" usebundle => user_has_password_hash("johndoe", "$(init.hash)", "hash_success", "hash_failure"), classes => always("hash_methods_run"); windows:: "any" usebundle => user_has_password("johndoe", "Wrong0P4SSW0RD", "hash_failure", "hash_success"), classes => always("hash_methods_run"); classes: "ready" and => { "uid_methods_run", "pgroup_methods_run", "sgroup_methods_run", "not_sgroup_methods_run", "home_methods_run", "shell_methods_run", "desc_methods_run", "hash_methods_run" }; !windows:: # Note the secondary group classes here. Windows treats primary and secondary groups the same, # and hence that test is invalid there. "unix_ok" and => { "uid_success", "!uid_failure", "shell_success", "!shell_failure", "not_sgroup_success", "!not_sgroup_failure", }; windows:: "unix_ok" expression => "any"; sles_11:: "ok" -> "CFE-3386" and => { "pgroup_success", "!pgroup_failure", "!sgroup_success", "sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; !sles_11:: "ok" and => { "pgroup_success", "!pgroup_failure", "sgroup_success", "!sgroup_failure", "hash_success", "!hash_failure", "home_success", "!home_failure", "desc_success", "!desc_failure", "unix_ok" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/disable_sudo_tty_requirement.cf.sub0000644000000000000000000000057315010704253030620 0ustar00rootroot00000000000000# Disable the requiretty setting in /etc/sudoers. body file control { inputs => { "../../plucked.cf.sub" }; } bundle agent disable_sudo_tty_requirement { files: "/etc/sudoers" edit_line => comment_requiretty; } bundle edit_line comment_requiretty { replace_patterns: "^Defaults *requiretty" replace_with => value("#Defaults requiretty"); } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_lock_warn.cf0000644000000000000000000000257215010704253026740 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets locked (dry run)"; "story_id" string => "5525"; "covers" string => "dryrun_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "present"; } ####################################################### bundle agent test { users: "johndoe" action => test_action, policy => "locked"; } body action test_action { action_policy => "warn"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_unlocked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_modify_user_unlock.cf0000644000000000000000000000244115010704253026247 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user present gets enabled"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle common hpux_trusted { classes: "hpux_trusted_mode_test" expression => regcmp(".*hpux_trusted.*", $(this.promise_filename)); } bundle agent init { meta: "test_skip_unsupported" string => "hpux_trusted_mode_test.!hpux"; users: "johndoe" policy => "locked"; } ####################################################### bundle agent test { users: "johndoe" policy => "present"; } ####################################################### bundle agent check { methods: "any" usebundle => user_is_unlocked("johndoe", "success", "failure"), classes => always("methods_run"); classes: "ready" expression => "methods_run"; "ok" and => { "success", "!failure" }; reports: ok.ready:: "$(this.promise_filename) Pass"; !ok.ready:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/17_users/unsafe/10_home_bundle_with_new_user_and_no_inherit.cf0000644000000000000000000000267715010704253032645 0ustar00rootroot00000000000000bundle common test_meta { vars: "description" string => "A user added gets the home bundle run (3)"; "story_id" string => "5525"; "covers" string => "operational_repaired"; } ####################################################### body common control { inputs => { "../../default.cf.sub", "user_queries.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { # Remove him first, should he already be present. users: "johndoe" policy => "absent"; } ####################################################### bundle agent test { classes: "should_not_prevent_edits" expression => "any"; users: "johndoe" policy => "present", home_bundle => home_bundle("/home/johndoe"), home_bundle_inherit => "false"; } bundle agent home_bundle(x) { files: # Class selector should have no effect since we're not supposed to inherit classes. !should_not_prevent_edits:: "$(G.testfile)" create => "true", edit_line => home_edit("$(x)"); } bundle edit_line home_edit(x) { insert_lines: "$(x)"; } ####################################################### bundle agent check { classes: "ok" not => strcmp("0", countlinesmatching("/home/johndoe", "$(G.testfile)")); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/26_cf-net/0000755000000000000000000000000015010704253020266 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/26_cf-net/serial/0000755000000000000000000000000015010704253021545 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_get.cf0000644000000000000000000000256015010704253024075 0ustar00rootroot00000000000000body contain myshell { !windows:: useshell => "useshell"; windows:: useshell => "powershell"; } body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile)"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); } bundle agent test { commands: "$(sys.cf_net)" args => " -H 127.0.0.1:15000 get -o $(G.testfile) $(this.promise_filename)", contain => myshell; meta: "description" string => "STAT+GET policy file from cf-serverd"; "test_skip_needs_work" string => "windows", comment => "for some reason, softfailing this test is not enough", meta => { "ENT-10254" }; } bundle agent check { methods: "check" usebundle => dcs_check_diff("$(G.testfile)", "$(this.promise_filename)", "$(this.promise_filename)"); } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); } cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_stat.cf0000644000000000000000000000344415010704253024273 0ustar00rootroot00000000000000body contain myshell { !windows:: useshell => "useshell"; windows:: useshell => "powershell"; } body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile)"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); commands: "echo" args => " \"127.0.0.1:15000:'$(this.promise_dirname)/cf-net_stat.cf' is a regular file\" > $(G.testfile).expected", contain => myshell; } bundle agent test { commands: "$(sys.cf_net)" args => " -H 127.0.0.1:15000 stat $(this.promise_dirname)/cf-net_stat.cf > $(G.testfile) 2>&1", contain => myshell; meta: "description" string => "Stat a regular file (this policy file)"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; } bundle agent check { methods: "check" usebundle => dcs_check_diff("$(G.testfile)", "$(G.testfile).expected", "$(this.promise_filename)"); vars: DEBUG|EXTRA:: "actual_output" string => readfile("$(G.testfile)"); "expected_output" string => readfile("$(G.testfile).expected"); reports: DEBUG|EXTRA:: "expected_output: $(expected_output)"; "actual_output: $(actual_output)"; } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); } cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_connect.cf.expected0000644000000000000000000000007415010704253026545 0ustar00rootroot00000000000000Connected & authenticated successfully to '127.0.0.1:15000' cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_connect.cf0000644000000000000000000000315015010704253024743 0ustar00rootroot00000000000000body contain myshell { !windows:: useshell => "useshell"; windows:: useshell => "powershell"; } body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile)"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); } bundle agent test { commands: "$(sys.cf_net)" args => " -H 127.0.0.1:15000 connect > $(G.testfile) 2>&1", contain => myshell; meta: "description" string => "Connect and authenticate with cf-serverd"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; } bundle agent check { methods: "check" usebundle => dcs_check_diff("$(G.testfile)", "$(this.promise_filename).expected", "$(this.promise_filename)"); vars: DEBUG|EXTRA:: "actual_output" string => readfile("$(G.testfile)"); "expected_output" string => readfile("$(this.promise_filename).expected"); reports: DEBUG|EXTRA:: "expected_output: $(expected_output)"; "actual_output: $(actual_output)"; } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); } cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_help.cf0000644000000000000000000000166115010704253024247 0ustar00rootroot00000000000000body contain myshell { !windows:: useshell => "useshell"; windows:: useshell => "powershell"; } body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile)"); } bundle agent test { commands: # Run "cf-net help help" "$(sys.cf_net)" args => " help help > $(G.testfile) 2>&1", contain => myshell; meta: "description" string => "Argument parsing and help output"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; } bundle agent check { methods: "check" usebundle => dcs_check_diff("$(G.testfile)", "$(this.promise_filename).expected", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/26_cf-net/serial/serverd_admit_localhost_15000.cf.srv0000644000000000000000000000151715010704253030321 0ustar00rootroot00000000000000body common control { bundlesequence => { "access_rules" }; inputs => { "../../default.cf.sub" }; } ######################################################### # Server config ######################################################### body server control { port => "15000"; allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "$(this.promise_dirname)/cf-net_stat.cf" admit_ips => { "127.0.0.1", "::1" }; "$(this.promise_dirname)/cf-net_get.cf" admit_ips => { "127.0.0.1", "::1" }; "$(G.testdir)" admit_ips => { "127.0.0.1", "::1" }; } cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_stat_deny.cf0000644000000000000000000000345115010704253025310 0ustar00rootroot00000000000000body contain myshell { !windows:: useshell => "useshell"; windows:: useshell => "powershell"; } body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile)"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); commands: "echo" args => "\"Could not stat: '$(this.promise_dirname)/cf-net_connect.cf'\" > $(G.testfile).expected", contain => myshell; } bundle agent test { commands: "$(sys.cf_net)" args => "--log-level ERROR -H 127.0.0.1:15000 stat $(this.promise_dirname)/cf-net_connect.cf > $(G.testfile) 2>&1", contain => myshell; meta: "description" string => "Attempt to stat file without permission"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; } bundle agent check { methods: "check" usebundle => dcs_check_diff("$(G.testfile)", "$(G.testfile).expected", "$(this.promise_filename)"); vars: DEBUG|EXTRA:: "actual_output" string => readfile("$(G.testfile)"); "expected_output" string => readfile("$(G.testfile).expected"); reports: DEBUG|EXTRA:: "expected_output: $(expected_output)"; "actual_output: $(actual_output)"; } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); } cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_help.cf.expected0000644000000000000000000000021315010704253026037 0ustar00rootroot00000000000000Command: help Usage: cf-net help [command] Description: Prints general help or per topic You did it, you used the help command! cfengine-3.24.2/tests/acceptance/26_cf-net/serial/cf-net_stat_dir.cf0000644000000000000000000000332715010704253025131 0ustar00rootroot00000000000000body contain myshell { !windows:: useshell => "useshell"; windows:: useshell => "powershell"; } body common control { inputs => { "../../default.cf.sub", "../../run_with_server.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { methods: "any" usebundle => dcs_fini("$(G.testfile)"); "any" usebundle => generate_key; "any" usebundle => trust_key; "any" usebundle => start_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); commands: "echo" args => " \"127.0.0.1:15000:'$(G.testdir)' is a directory\" > $(G.testfile).expected", contain => myshell; } bundle agent test { commands: "$(sys.cf_net)" args => " -H 127.0.0.1:15000 stat $(G.testdir) > $(G.testfile) 2>&1", contain => myshell; meta: "description" string => "Stat a directory"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; } bundle agent check { methods: "check" usebundle => dcs_check_diff("$(G.testfile)", "$(G.testfile).expected", "$(this.promise_filename)"); vars: DEBUG|EXTRA:: "actual_output" string => readfile("$(G.testfile)"); "expected_output" string => readfile("$(G.testfile).expected"); reports: DEBUG|EXTRA:: "expected_output: $(expected_output)"; "actual_output: $(actual_output)"; } bundle agent destroy { methods: "any" usebundle => stop_server("$(this.promise_dirname)/serverd_admit_localhost_15000.cf.srv"); } cfengine-3.24.2/tests/acceptance/00_basics/0000755000000000000000000000000015010704253020346 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/namespaces_can_not_contain_funny_characters.cf0000644000000000000000000000214415010704253031632 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" string => "Test that namespaces cannot be defined with characters that are invalid in bundle names."; vars: "command" string => "$(sys.cf_agent) -KI --define AUTO,DEBUG $(this.promise_filename).sub"; methods: # We check the output of a sub policy that we expect to be syntatically # invalid. So we pass if the subtest output says syntax error. We fail the # test if the output of the subtest includes FAIL. We never expect that # report to print, because the policy should not be syntatically valid and # should never run. "check" usebundle => dcs_passif_output(".*syntax error.*", ".*FAIL", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/0000755000000000000000000000000015010704253024466 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/11-augments-no-override.cf.json0000644000000000000000000000031615010704253032241 0ustar00rootroot00000000000000{ "variables" : { "ns1:scope1.test_variable": { "value" : "4hfcattz2607yfksllzpf73eg7nmqprl", "comment" : "comment1", "tags" : ["test_tag"] } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/05-variables-tag-comment.cf0000644000000000000000000000250415010704253031404 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'variables' object with a tag and a comment body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; "empty_promises_cf" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf | $(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output("data:variables.test_variable\s+4hfcattz2607yfksllzpf73eg7nmqprl\s+test_tag,source=cmdb\s+comment1", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/06-classes-tag-comment.cf.json0000644000000000000000000000043315010704253032041 0ustar00rootroot00000000000000{ "classes" : { "ns1:test_class": { "class_expressions" : [], "tags": ["test_tag"], "comment" : "comment1" }, "ns2:test_class2": { "tags": ["test_tag2"], "comment" : "comment2" } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/03-variables-value.cf0000644000000000000000000000334215010704253030304 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'variables' object with the 'value' field body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; } ####################################################### bundle agent test { vars: "result" data => execresult_as_data("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell", "both"), depends_on => { "prepare_host_specific_data" }; # ensure the sub-agent execution doesn't happen too early } ####################################################### bundle agent check { classes: "exit_code_ok" expression => strcmp("$(test.result[exit_code])", "0"); "output_ok" expression => strcmp("$(test.result[output])", 'R: 4hfcattz2607yfksllzpf73eg7nmqprl R: { "496btq4wxqs6rf07anbx95cj74ftdyhy" } R: {"key":"tiyl4z5nybvlp8npd2faso4ctxhknpvk"}'); "ok" and => {"exit_code_ok", "output_ok"}; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; !ok.DEBUG:: "exit code: $(test.result[exit_code])"; "output: $(test.result[output])"; } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/11-augments-no-override.cf0000644000000000000000000000314715010704253031276 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'variables' object with a tag and a comment body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; "def_json" usebundle => file_copy("$(this.promise_filename).def.json", "$(sys.inputdir)/def.json"); "empty_promises_cf" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --verbose --show-vars -f $(sys.inputdir)/promises.cf | $(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output(concat(".*Cannot set variable ns1:scope1.test_variable from augments, already defined from host-specific data", ".*ns1:scope1.test_variable\s+4hfcattz2607yfksllzpf73eg7nmqprl\s+test_tag,source=cmdb\s+comment1.*"), "override_value", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/01-vars.cf.json0000644000000000000000000000035715010704253027146 0ustar00rootroot00000000000000{ "vars" : { "test_variable": "4hfcattz2607yfksllzpf73eg7nmqprl", "scope1.test_variable": ["496btq4wxqs6rf07anbx95cj74ftdyhy"], "ns1:scope1.test_variable": { "key" : "tiyl4z5nybvlp8npd2faso4ctxhknpvk" } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/02-variables.cf0000644000000000000000000000323515010704253027172 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'variables' object body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; } ####################################################### bundle agent test { vars: "result" data => execresult_as_data("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell", "both"), depends_on => { "prepare_host_specific_data" }; # ensure the sub-agent execution doesn't happen too early } ####################################################### bundle agent check { classes: "exit_code_ok" expression => strcmp("$(test.result[exit_code])", "0"); "output_ok" expression => strcmp("$(test.result[output])", 'R: 4hfcattz2607yfksllzpf73eg7nmqprl R: { "496btq4wxqs6rf07anbx95cj74ftdyhy" }'); "ok" and => {"exit_code_ok", "output_ok"}; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; !ok.DEBUG:: "exit code: $(test.result[exit_code])"; "output: $(test.result[output])"; } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/11-augments-no-override.cf.def.json0000644000000000000000000000027515010704253033002 0ustar00rootroot00000000000000{ "variables" : { "ns1:scope1.test_variable": { "value" : "override_value", "comment" : "comment2", "tags" : ["test_tag2"] } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/09-class-reg-expression.cf0000644000000000000000000000245115010704253031305 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'classes' object with a tag and a comment body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; "empty_promises_cf" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf"; methods: "" usebundle => dcs_passif_output("\s*error: Invalid regular expression rules for class 'ns1:test_class1'.*\s+ns2:test_class2\s+.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/04-classes.cf.json0000644000000000000000000000062115010704253027625 0ustar00rootroot00000000000000{ "classes" : { "test_class1": "any::", "test_class2": ["any::"], "ns1:test_class3": "any::", "ns2:test_class4" : { "class_expressions": ["any::"] }, "ns2:test_class5" : { "regular_expressions": ["any"] }, "ns3:test_class6" : { "class_expressions": [] }, "ns3:test_class7" : { "regular_expressions": [] }, "test_class8" : {} } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/01-vars.cf0000644000000000000000000000330615010704253026173 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'vars' object body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; } ####################################################### bundle agent test { vars: "result" data => execresult_as_data("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell", "both"), depends_on => { "prepare_host_specific_data" }; # ensure the sub-agent execution doesn't happen too early } ####################################################### bundle agent check { classes: "exit_code_ok" expression => strcmp("$(test.result[exit_code])", "0"); "output_ok" expression => strcmp("$(test.result[output])", 'R: 4hfcattz2607yfksllzpf73eg7nmqprl R: { "496btq4wxqs6rf07anbx95cj74ftdyhy" } R: {"key":"tiyl4z5nybvlp8npd2faso4ctxhknpvk"}'); "ok" and => {"exit_code_ok", "output_ok"}; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; !ok.DEBUG:: "exit code: $(test.result[exit_code])"; "output: $(test.result[output])"; } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/10-variable-references.cf0000644000000000000000000000240215010704253031120 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'classes' object with a tag and a comment body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; "empty_promises_cf" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf"; methods: "" usebundle => dcs_passif_output("\s*error: Invalid 'variables' CMDB data.*", "test_variable2?", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/03-variables-value.cf.json0000644000000000000000000000043315010704253031252 0ustar00rootroot00000000000000{ "variables" : { "test_variable": { "value": "4hfcattz2607yfksllzpf73eg7nmqprl" }, "scope1.test_variable": { "value": ["496btq4wxqs6rf07anbx95cj74ftdyhy"] }, "ns1:scope1.test_variable": { "value": { "key" : "tiyl4z5nybvlp8npd2faso4ctxhknpvk" } } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/07-invalid-data.cf0000644000000000000000000000240115010704253027556 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'classes' object with a tag and a comment body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; "empty_promises_cf" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf"; methods: "" usebundle => dcs_passif_output("\s*warning: Invalid key 'clses'.*\s+ns1:test_class\s+.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/01-vars.cf.sub0000644000000000000000000000032315010704253026757 0ustar00rootroot00000000000000bundle agent __main__ { reports: "$(data:variables.test_variable)"; "$(with)" with => format("%S", "data:scope1.test_variable"); "$(with)" with => format("%S", "ns1:scope1.test_variable"); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/09-class-reg-expression.cf.json0000644000000000000000000000051315010704253032252 0ustar00rootroot00000000000000{ "classes" : { "ns1:test_class1": { "regular_expressions" : ["cfengine"], "tags": ["test_tag"], "comment" : "comment1" }, "ns2:test_class2": { "class_expressions" : [], "tags": ["test_tag"], "comment" : "comment1" } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/07-invalid-data.cf.json0000644000000000000000000000052515010704253030533 0ustar00rootroot00000000000000{ "clses" : { "ns1:test_class": { "class_expressions" : [], "tags": ["test_tag"], "comment" : "comment1" } }, "classes" : { "ns1:test_class": { "class_expressions" : [], "tags": ["test_tag"], "comment" : "comment1" } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/08-class-expression.cf.json0000644000000000000000000000051115010704253031474 0ustar00rootroot00000000000000{ "classes" : { "ns1:test_class1": { "class_expressions" : ["cfengine"], "tags": ["test_tag"], "comment" : "comment1" }, "ns2:test_class2": { "class_expressions" : [], "tags": ["test_tag"], "comment" : "comment1" } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/04-classes.cf0000644000000000000000000000354515010704253026665 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'classes' object body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; } ####################################################### bundle agent test { vars: "result" data => execresult_as_data("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell", "both"), depends_on => { "prepare_host_specific_data" }; # ensure the sub-agent execution doesn't happen too early } ####################################################### bundle agent check { classes: "exit_code_ok" expression => strcmp("$(test.result[exit_code])", "0"); "output_ok" expression => strcmp("$(test.result[output])", 'R: test_class1 defined as expected R: test_class2 defined as expected R: test_class3 defined as expected R: test_class4 defined as expected R: test_class5 defined as expected R: test_class6 defined as expected R: test_class7 defined as expected R: test_class8 defined as expected'); "ok" and => {"exit_code_ok", "output_ok"}; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; !ok.DEBUG:: "exit code: $(test.result[exit_code])"; "output: $(test.result[output])"; } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/03-variables-value.cf.sub0000644000000000000000000000032315010704253031070 0ustar00rootroot00000000000000bundle agent __main__ { reports: "$(data:variables.test_variable)"; "$(with)" with => format("%S", "data:scope1.test_variable"); "$(with)" with => format("%S", "ns1:scope1.test_variable"); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/05-variables-tag-comment.cf.json0000644000000000000000000000030315010704253032347 0ustar00rootroot00000000000000{ "variables" : { "test_variable": { "value" : "4hfcattz2607yfksllzpf73eg7nmqprl", "comment" : "comment1", "tags" : ["test_tag"] } } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/04-classes.cf.sub0000644000000000000000000000104015010704253027441 0ustar00rootroot00000000000000bundle agent __main__ { reports: data:test_class1:: "test_class1 defined as expected"; data:test_class2:: "test_class2 defined as expected"; ns1:test_class3:: "test_class3 defined as expected"; ns2:test_class4:: "test_class4 defined as expected"; ns2:test_class5:: "test_class5 defined as expected"; ns3:test_class6:: "test_class6 defined as expected"; ns3:test_class7:: "test_class7 defined as expected"; data:test_class8:: "test_class8 defined as expected"; } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/02-variables.cf.sub0000644000000000000000000000022115010704253027752 0ustar00rootroot00000000000000bundle agent __main__ { reports: "$(data:variables.test_variable)"; "$(with)" with => format("%S", "data:scope1.test_variable"); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/02-variables.cf.json0000644000000000000000000000024015010704253030133 0ustar00rootroot00000000000000{ "variables" : { "test_variable": "4hfcattz2607yfksllzpf73eg7nmqprl", "scope1.test_variable": ["496btq4wxqs6rf07anbx95cj74ftdyhy"] } } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/08-class-expression.cf0000644000000000000000000000244715010704253030536 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'classes' object with a tag and a comment body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; "empty_promises_cf" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf"; methods: "" usebundle => dcs_passif_output("\s*error: Invalid class expression rules for class 'ns1:test_class1'.*\s+ns2:test_class2\s+.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/06-classes-tag-comment.cf0000644000000000000000000000250315010704253031071 0ustar00rootroot00000000000000# basic test of the host_specific.json functionality: 'classes' object with a tag and a comment body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(sys.workdir)$(const.dirsep)data$(const.dirsep)." create => "true", perms => mog("0700", "$(sys.user_data[username])", "$(sys.user_data[username])"); methods: "prepare_host_specific_data" usebundle => file_copy("$(this.promise_filename).json", "$(sys.workdir)$(const.dirsep)data$(const.dirsep)host_specific.json"), handle => "prepare_host_specific_data"; "empty_promises_cf" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("ns1:test_class\s+test_tag,source=cmdb\s+comment1.*ns2:test_class2\s+test_tag2,source=cmdb\s+comment2", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/06_host_specific_data/10-variable-references.cf.json0000644000000000000000000000053015010704253032070 0ustar00rootroot00000000000000{ "variables" : { "test_variable": { "value" : "$(sys.uptime)", "comment" : "comment1", "tags" : ["test_tag"] }, "test_variable2": { "value" : "4hfcattz2607yfksllzpf73eg7nmqprl", "comment" : "comment2", "tags" : ["test_tag2"] } } } cfengine-3.24.2/tests/acceptance/00_basics/namespaces_can_not_contain_funny_characters.cf.sub0000644000000000000000000000121615010704253032421 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { reports: # This should NEVER be reported because we have a body file control that # contains illegal characters. "$(this.promise_filename) FAIL"; } body file control { # Variable dereferences should work namespace => "{}()$:[]"; } cfengine-3.24.2/tests/acceptance/00_basics/05_licenses/0000755000000000000000000000000015010704253022457 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/05_licenses/001.cf0000644000000000000000000000220115010704253023264 0ustar00rootroot00000000000000####################################################### # # Test that we do not complain about license. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "agent" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO 2>&1", "useshell"); } ####################################################### bundle agent check { classes: "fail" expression => regcmp(".*Your configuration promises no host_licenses_paid in common control.*", $(test.agent)); reports: DEBUG:: "This should only pass if $(this.promise_filename).sub does not output anything about license"; "Output from $(this.promise_filename).sub: $(test.agent)"; !fail:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/05_licenses/001.cf.sub0000644000000000000000000000127115010704253024062 0ustar00rootroot00000000000000####################################################### # # Test that we do not complain about license. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; host_licenses_paid => "0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/0000755000000000000000000000000015010704253022305 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/passing-vars.cf0000644000000000000000000000402715010704253025237 0ustar00rootroot00000000000000# Test that variables can be passed across bundles and namespaces body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "x" string => "datax"; "y" slist => { "datay1", "datay2" }; "z" data => parsejson('{ "hello": "there" }'); meta: "test_skip_needs_work" string => "windows"; methods: "x" usebundle => see_scalar($(x)); "y" usebundle => see_slist(@(test.y)); "z" usebundle => see_data(@(z)); } bundle agent see_scalar(svar) { classes: "saw_scalar" scope => "namespace", expression => strcmp($(svar), "datax"); reports: DEBUG:: "The passed-in string was $(svar)"; } bundle agent see_slist(lvar) { vars: "concat" string => join(",", lvar); classes: "saw_slist" scope => "namespace", expression => strcmp($(concat), "datay1,datay2"); reports: DEBUG:: "The passed-in slist was $(lvar)"; } bundle agent see_data(cvar_passed) { vars: "concat_passed" string => storejson(cvar_passed); "cvar_local" data => parsejson('{ "hello": "there" }'); "concat_local" string => storejson(cvar_local); # generates a warning about "can't find container named cvar_passed" "dummy" data => mergedata(cvar_local, cvar_passed); classes: "saw_data" scope => "namespace", expression => strcmp($(concat_passed), '{ "hello": "there" }'); reports: DEBUG:: "The passed-in container as string was $(concat_passed)"; "The local container as string was $(concat_local)"; } bundle agent check { classes: "ok" and => { "saw_scalar", "saw_slist", "saw_data" }; reports: DEBUG.!saw_scalar:: "The scalar passing didn't work"; DEBUG.!saw_slist:: "The slist passing didn't work"; DEBUG.!saw_data:: "The data passing didn't work"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/wrong-bundle-type.cf.sub0000644000000000000000000000017315010704253026772 0ustar00rootroot00000000000000body common control { bundlesequence => { "test" }; } bundle wrongwrongwrong test { vars: "dummy" string => "dummy"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/namespaced.cf.sub0000644000000000000000000000201115010704253025501 0ustar00rootroot00000000000000body file control { namespace => "ns1"; } bundle agent mytest(a) { classes: "ns1global" expression => "any", scope => "namespace"; "ns1global_from_ppkeys" expression => "ns1ppkeys", scope => "namespace"; # should be defined "ns1global_from_ppkeys_explicit" expression => "ns1:ns1ppkeys", scope => "namespace"; # prefix should not be necessary vars: cfengine_3:: "ns1string" string => $(this.promise_dirname); files: "$(sys.workdir)/ppkeys/." create => "true", classes => default:always("ns1ppkeys"); reports: EXTRA:: "$(this.bundle): ns1string = '$(ns1string)'"; } body file control { namespace => "ns2"; } bundle agent mytest(a,b) { classes: "ns2global" expression => "cfengine_3", scope => "namespace"; vars: "ns2string" string => $(sys.fqhost); "ns2string2" string => $(const.t); files: "$(sys.workdir)/ppkeys/." create => "true"; reports: EXTRA:: "$(this.bundle): ns2string = '$(ns2string)'"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/unless.cf0000644000000000000000000002077115010704253024137 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent test { meta: "description" -> { "CFE-2698" } string => "This test ensures changes to unless are compatible with previous behavior"; vars: any:: # Simple expressions - unless is equivalent to if not: "defined_variable_unless" string => "value", unless => "!any"; "defined_variable_if_not" string => "value", if => not("!any"); "skipped_variable_unless" string => "value", unless => "any"; "skipped_variable_if_not" string => "value", if => not("any"); # Function calls: "defined_variable_function_call_unless" string => "value", unless => strcmp("a", "b"); "defined_variable_function_call_if_not" string => "value", if => not(strcmp("a", "b")); "skipped_variable_function_call_unless" string => "value", unless => strcmp("a", "a"); "skipped_variable_function_call_if_not" string => "value", if => not(strcmp("a", "a")); # If and unless precedence (skipping takes precedence): "skipped_variable_precedence_if" string => "value", if => "!any", # Causes the promise to be skipped unless => "!any"; "skipped_variable_precedence_unless" string => "value", if => "any", unless => "any"; # Causes the promise to be skipped "skipped_variable_precedence_unexpanded_variable_if" string => "value", if => "$(undefined_var)", # Causes the promise to be skipped unless => "$(undefined_var)"; "skipped_variable_precedence_unresolved_function_call_if" string => "value", if => not("$(undefined_var)"), # Causes the promise to be skipped unless => not("$(undefined_var)"); # Edge case - unresolved function calls: "skipped_variable_unresolved_function_call_if" string => "value", if => strcmp("$(no_such_var)", "$(no_such_var)"); "defined_variable_unresolved_function_call_unless" string => "value", unless => strcmp("$(no_such_var)", "$(no_such_var)"); # Edge case - this shows the difference between unless and if not: "defined_variable_unresolved_variable_unless" string => "value", unless => "$(no_such_var)"; "skipped_variable_unresolved_variable_if_not" string => "value", if => not("$(no_such_var)"); no_such_class:: # Let's just test that unless doesn't bypass class guards: "skipped_variable_class_guard_unless" string => "value", unless => "!any"; "skipped_variable_class_guard_if_not" string => "value", if => not("!any"); classes: any:: # Simple expressions - unless is equivalent to if not: "defined_class_unless" expression => "any", scope => "namespace", unless => "!any"; "defined_class_if_not" expression => "any", scope => "namespace", if => not("!any"); "skipped_class_unless" expression => "any", scope => "namespace", unless => "any"; "skipped_class_if_not" expression => "any", scope => "namespace", if => not("any"); # Function calls: "defined_class_function_call_unless" expression => "any", scope => "namespace", unless => strcmp("a", "b"); "defined_class_function_call_if_not" expression => "any", scope => "namespace", if => not(strcmp("a", "b")); "skipped_class_function_call_unless" expression => "any", scope => "namespace", unless => strcmp("a", "a"); "skipped_class_function_call_if_not" expression => "any", scope => "namespace", if => not(strcmp("a", "a")); # If and unless precedence (skipping takes precedence): "skipped_class_precedence_if" expression => "any", scope => "namespace", if => "!any", # Causes the promise to be skipped unless => "!any"; "skipped_class_precedence_unless" expression => "any", scope => "namespace", if => "any", unless => "any"; # Causes the promise to be skipped "skipped_class_precedence_unexpanded_variable_if" expression => "any", scope => "namespace", if => "$(undefined_var)", # Causes the promise to be skipped unless => "$(undefined_var)"; "skipped_class_precedence_unresolved_function_call_if" expression => "any", scope => "namespace", if => not("$(undefined_var)"), # Causes the promise to be skipped unless => not("$(undefined_var)"); # Edge case - unresolved function calls: "skipped_class_unresolved_function_call_if" expression => "any", scope => "namespace", if => strcmp("$(no_such_var)", "$(no_such_var)"); "defined_class_unresolved_function_call_unless" expression => "any", scope => "namespace", unless => strcmp("$(no_such_var)", "$(no_such_var)"); # Edge case - this shows the difference between unless and if not: "defined_class_unresolved_variable_unless" expression => "any", scope => "namespace", unless => "$(no_such_var)"; "skipped_class_unresolved_variable_if_not" expression => "any", scope => "namespace", if => not("$(no_such_var)"); no_such_class:: # Let's just test that if/unless doesn't bypass class guards: "skipped_class_class_guard_unless" expression => "any", scope => "namespace", unless => "!any"; "skipped_class_class_guard_if_not" expression => "any", scope => "namespace", if => not("!any"); } bundle agent check { classes: any:: "positives" # Fail if any of these are not defined: and => { isvariable("test.defined_variable_unless"), isvariable("test.defined_variable_if_not"), isvariable("test.defined_variable_function_call_unless"), isvariable("test.defined_variable_function_call_if_not"), isvariable("test.defined_variable_unresolved_function_call_unless"), isvariable("test.defined_variable_unresolved_variable_unless"), "defined_class_unless", "defined_class_if_not", "defined_class_function_call_unless", "defined_class_function_call_if_not", "defined_class_unresolved_function_call_unless", "defined_class_unresolved_variable_unless", }; "negatives" # Fail if any of these are defined: or => { isvariable("test.skipped_variable_unless"), isvariable("test.skipped_variable_if_not"), isvariable("test.skipped_variable_function_call_unless"), isvariable("test.skipped_variable_function_call_if_not"), isvariable("test.skipped_variable_precedence_if"), isvariable("test.skipped_variable_precedence_unless"), isvariable("test.skipped_variable_precedence_unexpanded_variable_if"), isvariable("test.skipped_variable_precedence_unresolved_function_call_if"), isvariable("test.skipped_variable_unresolved_function_call_if"), isvariable("test.skipped_variable_unresolved_variable_if_not"), isvariable("test.skipped_variable_class_guard_unless"), isvariable("test.skipped_variable_class_guard_if_not"), "skipped_class_unless", "skipped_class_if_not", "skipped_class_function_call_unless", "skipped_class_function_call_if_not", "skipped_class_precedence_if", "skipped_class_precedence_unless", "skipped_class_precedence_unexpanded_variable_if", "skipped_class_precedence_unresolved_function_call_if", "skipped_class_unresolved_function_call_if", "skipped_class_unresolved_variable_if_not", "skipped_class_class_guard_unless", "skipped_class_class_guard_if_not", }; reports: !positives:: "Some classes/vars were unexpectedly skipped"; negatives:: "Some classes/vars were unexpectedly evaluated"; positives.!negatives:: "$(this.promise_filename) Pass"; !positives|negatives:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/non_default_def.cf0000644000000000000000000000127515010704253025740 0ustar00rootroot00000000000000# Test that 'def' bundle in a non-default namespace works body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } body file control { namespace => "my_ns"; } bundle common def { vars: "some_var" string => "some value"; } body file control { namespace => "default"; } bundle agent init { } bundle agent test { } bundle agent check { classes: "ok" expression => strcmp("$(my_ns:def.some_var)", "some value"); reports: ok:: "$(this.promise_filename) Pass"; !ok.DEBUG:: "my_ns:def.some_var: $(my_ns:def.some_var)"; !ok:: "$(this.promise_filename) FAIL"; } agent-bundle-class-bundle-scope-namespace-perspective.cf0000755000000000000000000000421615010704253035055 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body file control { namespace => "test"; } bundle agent example { classes: "TRIGGERED" expression => "any", scope => "bundle"; # Namespace scoped classes are visible from other bundles } bundle agent check { classes: # Expectation, default:TRIGGERED is NOT defined "default_TRIGGERED_OK" expression => "!default:TRIGGERED"; # Expectation, test:TRIGGERED is NOT defined (not visable since it's a bundle scoped class) "namespaced_TRIGGERED_OK" expression => "!test:TRIGGERED"; # Expectation, TRIGGERED is NOT defined, we are now in the test namespace where the TRIGGERED class was defined, but it was bundle scoped, so not visable from another bundle "TRIGGERED_OK" expression => "!TRIGGERED"; "pass" and => { "default_TRIGGERED_OK", "namespaced_TRIGGERED_OK", "TRIGGERED_OK", }; reports: pass:: "Pass $(this.promise_filename)"; !pass:: "FAIL $(this.promise_filename)"; !default_TRIGGERED_OK:: "Expected 'default:TRIGGERED' to not be seen as defined, but expression '!default:TRIGGERED' resulted in true"; !namespaced_TRIGGERED_OK:: "Expected 'test:TRIGGERED' to NOT be seen as defined, but expression '!test:TRIGGERED' resulted in false"; !TRIGGERED_OK:: "Expected 'TRIGGERED' to NOT be seen as defined, but expression '!TRIGGERED' resulted in false"; } body file control { namespace => "default"; } bundle agent test { meta: "description" -> {"ENT-4681" } string => "Test that bundle scoped classes defined from namespaced agent bundles are properly scoped. Specifically from the perspective of the non-default namespace itself."; "test_soft_fail" string => "any", meta => { "ENT-4681" }; methods: "test:example"; } bundle agent check { methods: "test:check"; } bundle agent __main__ { methods: "test"; "check"; } empty_list_or_datacontainer_should_not_error_bundlesequence/0000755000000000000000000000000015010704253036544 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundlesabsent_data_container_or_list_in_bundlesequence_triggers_error.x.cf0000644000000000000000000000070115010704253054253 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/empty_list_or_datacontainer_should_not_error_bundlesequencebody common control { bundlesequence => { def, test, check, @(def.bundlesequnece_end) }; } bundle common def { vars: "v" slist => variablesmatching("default\:def.*"); reports: DEBUG:: "Def Varaiable: $(v)"; } bundle agent test { meta: "description" string => "Test that a non existing data container or list triggers an undefined bundle error"; } bundle agent check { reports: "$(this.promise_filename) Pass"; } bundlesequence_iterate_over_data_container.cf0000644000000000000000000000272515010704253047671 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/empty_list_or_datacontainer_should_not_error_bundlesequencebody common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { collect_stories_metadata, test_precheck, def, test, @(def.container), check }; } bundle common def { vars: "v" slist => variablesmatching("default\:def.*"); "m" data => mergedata( "def.missing" ); "values" slist => getvalues(m); "indices" slist => getindices(m); "container" data => parsejson('[ "one", "two" ]'); # "list" slist => { "one", "two" }; # "container" data => mergedata(list); reports: DEBUG:: "Def Varaiable: $(v)"; "container: $(container)"; } bundle agent one { classes: # We check for this class in bundle agent check "actuated_bundle_agent_$(this.bundle)" expression => "any", scope => "namespace"; reports: "one"; } bundle agent two { classes: # We check for this class in bundle agent check "actuated_bundle_agent_$(this.bundle)" expression => "any", scope => "namespace"; reports: "two"; } bundle agent test { meta: "description" string => "Test that bundlesequence in body common control can iterate over a data container."; # This was working in 3.7.4 but has regressed. "test_soft_fail" string => "!cfengine_3_7", meta => { "CFE-2460"}; } bundle agent check { reports: actuated_bundle_agent_one.actuated_bundle_agent_two:: "$(this.promise_filename) Pass"; !(actuated_bundle_agent_one.actuated_bundle_agent_two):: "$(this.promise_filename) FAIL"; } empty_list_does_not_trigger_undefined_bundle.cf0000644000000000000000000000072715010704253050244 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/empty_list_or_datacontainer_should_not_error_bundlesequencebody common control { bundlesequence => { def, test, check, @(def.bundlesequnece_end) }; } bundle common def { vars: "v" slist => variablesmatching("default\:def.*"); "bundlesequnece_end" slist => { }; reports: DEBUG:: "Def Varaiable: $(v)"; } bundle agent test { meta: "description" string => "Test that an empty list does not trigger an undefined bundle error"; } bundle agent check { reports: "$(this.promise_filename) Pass"; } empty_data_container_does_not_trigger_undefined_bundle.cf0000644000000000000000000000075515010704253052245 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/empty_list_or_datacontainer_should_not_error_bundlesequencebody common control { bundlesequence => { def, test, check, @(def.bundlesequnece_end) }; } bundle common def { vars: "v" slist => variablesmatching("default\:def.*"); "bundlesequnece_end" data => parsejson('{}'); reports: DEBUG:: "Def Varaiable: $(v)"; } bundle agent test { meta: "description" string => "Test that an empty data container does not trigger an undefined bundle error"; } bundle agent check { reports: "$(this.promise_filename) Pass"; } call_namespaced_bundle_from_namespace_without_specifying_namespace.cf0000644000000000000000000000226315010704253040245 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles# Test that namespaced bundles that call other namespaced bundles can do so # without specifying their own namespace # Redmine:4289 (https://cfengine.com/dev/issues/4289) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "agent_output" string => execresult("$(sys.cf_agent) -KIf $(this.promise_filename).sub -b testing:one", "noshell"); } bundle agent check { classes: "OK_non_specified_namespace" expression => regcmp(".*OKI DOKI.*", $(test.agent_output)); "OK_specified_namespace" expression => regcmp(".*artichokie.*", $(test.agent_output)); "ok" and => { "OK_non_specified_namespace", "OK_specified_namespace", }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "agent output: =============================================================================== $(test.agent_output) ==============================================================================="; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/main_duplicate_1.x.cf0000644000000000000000000000032515010704253026263 0ustar00rootroot00000000000000bundle agent main { reports: "This should fail because __main__ will be renamed to main"; } bundle agent __main__ { reports: "This should fail because __main__ will be renamed to main"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/namespaced.cf0000644000000000000000000000352315010704253024722 0ustar00rootroot00000000000000# Redmine#4025 body common control { inputs => { "../../default.cf.sub", "namespaced.cf.sub" }; bundlesequence => { ns1:mytest("x"), ns2:mytest("x", "y"), default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; } bundle agent check { vars: "checks" slist => { "ns1:ns1global", "ns2:ns2global", "ns1:ns1global_from_ppkeys", "ns1:ns1global_from_ppkeys_explicit", "ns1global", "ns2global", "ok_ns1string", "ok_ns2string", "ok_ns2string2", }; classes: "ok_ns1string" expression => strcmp($(ns1:mytest.ns1string), $(this.promise_dirname)); "ok_ns2string" expression => strcmp($(ns2:mytest.ns2string), $(sys.fqhost)); "ok_ns2string2" expression => strcmp($(ns2:mytest.ns2string2), $(const.t)); "ok" and => { "ns1:ns1global", "ns2:ns2global", "ns1:ns1global_from_ppkeys", "ns1:ns1ppkeys", "!ns1global", "!ns2global", "ok_ns1string", "ok_ns2string", "ok_ns2string2", }; reports: EXTRA:: "class $(checks) is ON" if => $(checks); EXTRA:: "class $(checks) is OFF" if => "!$(checks)"; DEBUG.ns1:ns1global_from_ppkeys:: "ns1:ns1global_from_ppkeys is on as expected"; DEBUG.ns1:ns1global_from_ppkeys_explicit:: "ns1:ns1global_from_ppkeys_explicit is on as expected"; DEBUG.!ns1:ns1global_from_ppkeys:: "ns1:ns1global_from_ppkeys is NOT on as expected"; DEBUG.!ns1:ns1global_from_ppkeys_explicit:: "ns1:ns1global_from_ppkeys_explicit is NOT on as expected"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/unless_vars_order.cf0000644000000000000000000000145315010704253026361 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; } bundle agent test { meta: any:: "description" -> { "CFE-2698" } string => "Order of vars promises shouldn't matter"; vars: any:: "target_variable" string => "value"; "vars_promise_which_should_be_skipped" string => "value", unless => isvariable( $(variable_defined_later) ); "variable_defined_later" string => "target_variable"; } bundle agent check { classes: any:: "not_ok" or => { isvariable("test.vars_promise_which_should_be_skipped"), }; reports: !not_ok:: "$(this.promise_filename) Pass"; not_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/main_entry_point.cf.sub0000644000000000000000000000033115010704253026762 0ustar00rootroot00000000000000bundle agent __main__ { reports: "$(this.promise_filename) FAIL"; # This shouldn't run } bundle agent imported { reports: "This file can be imported and the __main__ above will be ignored"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/main_rename.cf0000644000000000000000000000021315010704253025066 0ustar00rootroot00000000000000body common control { bundlesequence => { "main" }; } bundle agent __main__ { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/unsupported_promise_types_in_common.x.cf0000644000000000000000000000074615010704253032504 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common test { meta: "description" -> { "CFE-3672" } string => "Test that cf-promises errors for incompatible promise types in common bundle and doesnt crash."; methods: "some_report" usebundle => reporter("123"); files: "some_file"; } bundle agent reporter(x) { reports: "${x}"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/duplicate_promise_handles.cf0000644000000000000000000000202515010704253030024 0ustar00rootroot00000000000000# Test that we don't get errors about duplicate handles when using variables in # handle name that do not expand identically # Redmine:4682 (https://cfengine.com/dev/issues/4682) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "duplicate" handle => "$(this.handle)_$(this.promiser)", string => "foo"; } bundle agent test { vars: "duplicate" handle => "$(this.handle)_$(this.promiser)", string => "bar"; # Two promises with equal handle but different classes is allowed reports: debian:: "this is debian" handle => "os_handle"; redhat:: "this is redhat" handle => "os_handle"; } bundle agent check { classes: "ok" and => { "any" }, comment => "Policy validation failing will cause us to never reach this if the test fails"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/main_entry_point.cf0000644000000000000000000000031715010704253026176 0ustar00rootroot00000000000000body file control { inputs => { "main_entry_point.cf.sub" }; } bundle agent __main__ { methods: "imported" usebundle => imported(); reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/namespaced.cf.subx0000644000000000000000000000021215010704253025672 0ustar00rootroot00000000000000body file control { namespace => "ns1"; } bundle agent mytest { files: "$(sys.workdir)/ppkeys/." create => "true"; } agent-bundle-namespaced-class-namespace-perspective.cf0000755000000000000000000000424115010704253034573 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body file control { namespace => "test"; } bundle agent example { classes: "TRIGGERED" expression => "any", scope => "namespace"; # Namespace scoped classes are visible from other bundles } bundle agent check { classes: # Expectation, default:TRIGGERED is NOT defined "default_TRIGGERED_OK" expression => "!default:TRIGGERED"; # Expectation, test:TRIGGERED is defined (visable since it's a namespace scoped class) "namespaced_TRIGGERED_OK" expression => "test:TRIGGERED"; # Expectation, TRIGGERED is defined, we are now in the test namespace where the TRIGGERED class was defined. We should be able to reference classes defined in our current namespace without being explicit "TRIGGERED_OK" expression => "TRIGGERED"; "pass" and => { "default_TRIGGERED_OK", "namespaced_TRIGGERED_OK", "TRIGGERED_OK", }; reports: pass:: "Pass $(this.promise_filename)"; !pass:: "FAIL $(this.promise_filename)"; !default_TRIGGERED_OK:: "Expected 'default:TRIGGERED' to not be seen as defined, but expression '!default:TRIGGERED' resulted in true"; !namespaced_TRIGGERED_OK:: "Expected 'test:TRIGGERED' to be seen as defined, but expression 'test:TRIGGERED' resulted in false"; !TRIGGERED_OK:: "Expected 'TRIGGERED' to be seen as defined, but expression 'TRIGGERED' resulted in false"; } body file control { namespace => "default"; } bundle agent test { meta: "description" -> {"ENT-4681" } string => "Test that namespace scoped classes defined from namespaced agent bundles are properly scoped. Specifically from the perspective of the non-default namespace itself."; "test_soft_fail" string => "any", meta => { "ENT-4681" }; methods: "test:example"; } bundle agent check { methods: "test:check"; } bundle agent __main__ { methods: "test"; "check"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/namespaced.x.cf0000644000000000000000000000071515010704253025170 0ustar00rootroot00000000000000# Redmine#4025: should fail body common control { inputs => { "../../default.cf.sub", "namespaced.cf.subx" }; bundlesequence => { mytest, default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { } bundle agent check { classes: "ok" and => { "any" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } agent-bundle-class-bundle-scope-default-perspective.cf0000755000000000000000000000412315010704253034542 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body file control { namespace => "test"; } bundle agent example { classes: "TRIGGERED" expression => "any", scope => "bundle"; # Bundle scoped classes are NOT visible from other bundles } body file control { namespace => "default"; } bundle agent test { meta: "description" -> {"ENT-4681" } string => "Test that bundle scoped classes defined from namespaced agent bundles are properly scoped. Specifically from the default namespace."; "test_soft_fail" string => "any", meta => { "ENT-4681" }; methods: "test:example"; } bundle agent check { classes: # Expectation, default:TRIGGERED is NOT defined "default_TRIGGERED_OK" expression => "!default:TRIGGERED"; # Expectation, test:TRIGGERED is NOT defined (not visable since it's a bundle scoped class) "namespaced_TRIGGERED_OK" expression => "!test:TRIGGERED"; # Expectation, TRIGGERED is NOT defined, we are now in the default namespace, the TRIGGERED class was defined in the test namespace with a bundle scope "TRIGGERED_OK" expression => "!TRIGGERED"; "pass" and => { "default_TRIGGERED_OK", "namespaced_TRIGGERED_OK", "TRIGGERED_OK", }; reports: pass:: "Pass $(this.promise_filename)"; !pass:: "FAIL $(this.promise_filename)"; !default_TRIGGERED_OK:: "Expected 'default:TRIGGERED' to not be seen as defined, but expression '!default:TRIGGERED' resulted in true"; !namespaced_TRIGGERED_OK:: "Expected 'test:TRIGGERED' to NOT be seen as defined, but expression '!test:TRIGGERED' resulted in false"; !TRIGGERED_OK:: "Expected 'TRIGGERED' to NOT be seen as defined, but expression 'TRIGGERED' resulted in true even without specify the test namespace"; } bundle agent __main__ { methods: "test:example"; "check"; } call_namespaced_bundle_from_namespace_without_specifying_namespace.cf.sub0000644000000000000000000000054215010704253041033 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundlesbody file control { namespace => "testing"; } bundle agent one { methods: "call namespaced bundle from namespace" usebundle => two; "call namespaced bundle from namespace and specify the namespace" usebundle => testing:three; } bundle agent two { reports: "OKI DOKI"; } bundle agent three { reports: "artichokie"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/getindices-vars-need-secondpass.cf0000644000000000000000000000203715010704253030761 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "x" slist => { "PARAM1", "PARAM2" }; "conf[internal1]" string => "internalvalue1"; "conf[internal2]" string => "internalvalue2"; "conf[$(x)]" string => "$(x)"; "keys_unsorted" slist => getindices("conf"); "keys" slist => sort(keys_unsorted, "lex"); "keys_str" string => format("%S", keys); reports: DEBUG:: "conf[$(keys_unsorted)] = $(conf[$(keys_unsorted)])"; } bundle agent check { vars: "expected" string => '{ "PARAM1", "PARAM2", "internal1", "internal2" }'; classes: "ok" expression => strcmp($(test.keys_str), $(expected)); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG.!ok:: "Expected $(expected), actual $(test.keys_str)"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/0000755000000000000000000000000015010704253027013 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/inputs/0000755000000000000000000000000015010704253030335 5ustar00rootroot00000000000000read_classes.cf.sub0000644000000000000000000000062315010704253034011 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/inputsbundle common read_classes { vars: linux:: "local_classes" slist => lsdir("$(this.promise_dirname)/../classes","\w.*","false"); classes: "$(local_classes)" expression => "any"; "PASS_READ_CLASSES1" expression => "enable_test_bundle"; reports: PASS_READ_CLASSES1:: "PASS $(this.bundle) $(sys.cf_version)"; !PASS_READ_CLASSES1:: "FAIL $(this.bundle) $(sys.cf_version) Module Failed"; } test_bundle_common.cf.sub0000644000000000000000000000103415010704253035236 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/inputsbundle common test_bundle_common { classes: "test_bundle_disabled_class" or => { "disable_test_bundle" }; "test_bundle_supported_platform" or => { "linux.enable_test_bundle" }; "test_bundle_supported_class" or => { "enable_test_bundle" }; "test_bundle_enabled_class" and => { "test_bundle_supported_class", "test_bundle_supported_platform", "!test_bundle_disabled_class" }; reports: debug:: "$(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/app_based_inputs.cf.sub0000644000000000000000000000365015010704253033441 0ustar00rootroot00000000000000# Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Bundle list built from array # Bundles policy defined in separate file # include only app files neaded based on list built from array # Lexicly sorted bundles activated with methods promise body common control # { bundlesequence => { "classify", "map_role_bundles", "go" }; } bundle common classify # { vars: "variable" string => "vmware"; classes: "group_one" expression => strcmp("vmware", "vmware"), comment => "Highest level classification, other classes depend on this."; } bundle common map_role_bundles # { vars: # Define bundles any:: "role[app00_zero]" string => "$(this.promise_dirname)/apps/app00_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; "role[app_zero]" string => "$(this.promise_dirname)/apps/app_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_one:: "role[app_one]" string => "$(this.promise_dirname)/apps/app_one.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_none:: "role[app_two]" string => "$(this.promise_dirname)/apps/app_two.cf.sub"; any:: "inputs" slist => getvalues(role); "bundles" slist => getindices(role); } bundle agent go # { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); methods: "$(sorted_bundles)" usebundle => $(sorted_bundles); reports: DEBUG:: "Should include '$(map_role_bundles.inputs)'"; } body file control { inputs => { @(map_role_bundles.inputs) }; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/read_inputs.cf.sub0000644000000000000000000000071315010704253032433 0ustar00rootroot00000000000000bundle common prep_read_inputs { vars: linux.use_lsdir:: "inputs" slist => lsdir("inputs","\w.*","true"); linux.use_lsdir_relative:: "inputs" slist => lsdir("$(this.promise_dirname)/inputs","\w.*","true"); linux.no_use_lsdir:: "inputs" slist => { "inputs/read_classes.cf.sub", "inputs/test_bundle_common.cf.sub" }; } bundle common read_inputs { vars: linux:: "inputs" slist => { @(prep_read_inputs.inputs) }; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/simple.cf0000644000000000000000000000176715010704253030631 0ustar00rootroot00000000000000####################################################### # # Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Bundle list built from array # Lexicly sorted bundles activated with methods promise ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output( ".*R: HEY I activated app00_zero R: HEY I activated app_one R: HEY I activated app_zero.*", ".*FAIL.*", $(command), $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 classification_bundles_not_in_sequence3.cf.sub0000644000000000000000000000362615010704253040075 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence# Test a simple dynamic bundlesequnece pattern # Classification Bundles NOT listed in bundlesequence # Classificaiton bundles defined in order used # Classify bundle uses a variable on the RHS when defining a class # Bundle list built from array # Lexicly sorted bundles activated with methods promise body common control # { bundlesequence => { "go", @(go.sorted_bundles) }; } bundle agent go # { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); } bundle agent app_one # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_two # { reports: "HEY I activated $(this.bundle)"; } bundle agent app00_zero # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_zero # { reports: "HEY I activated $(this.bundle)"; } bundle common classify # { vars: "variable" string => "vmware"; classes: "group_one" expression => strcmp("$(variable)", "vmware"), comment => "Highest level classification, other classes depend on this."; } bundle common map_role_bundles # { vars: # Define bundles any:: "role[app00_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; "role[app_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_one:: "role[app_one]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_none:: "role[app_two]" string => "/path/to_policy_file.cf"; any:: "bundles" slist => getindices(role); } dynamic_inputs_based_on_list_variable_dependent_on_class.cf.sub0000644000000000000000000000024515010704253043526 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequencebundle agent good { classes: "dummy" expression => regextract("(.*)\.sub", "$(this.promise_filename)", "fn"); reports: "$(fn[1]) Pass"; } classification_bundles_not_in_sequence.cf.sub0000644000000000000000000000360015010704253040002 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence# Test a simple dynamic bundlesequnece pattern # Classification Bundles NOT listed in bundlesequence # Classificaiton bundles defined in order used # Bundle list built from array # Lexicly sorted bundles activated with methods promise body common control # { bundlesequence => { "go" }; } bundle agent go # { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); methods: "$(sorted_bundles)" usebundle => $(sorted_bundles); } bundle agent app_one # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_two # { reports: "HEY I activated $(this.bundle)"; } bundle agent app00_zero # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_zero # { reports: "HEY I activated $(this.bundle)"; } bundle common classify # { vars: "variable" string => "vmware"; classes: "group_one" expression => strcmp("$(variable)", "vmware"), comment => "Highest level classification, other classes depend on this."; } bundle common map_role_bundles # { vars: # Define bundles any:: "role[app00_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; "role[app_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_one:: "role[app_one]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_none:: "role[app_two]" string => "/path/to_policy_file.cf"; any:: "bundles" slist => getindices(role); } classification_bundles_not_in_sequence.cf0000644000000000000000000000205215010704253037212 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence####################################################### # # Test a simple dynamic bundlesequnece pattern # Classification Bundles NOT listed in bundlesequence # Classificaiton bundles defined in order used # Bundle list built from array # Lexicly sorted bundles activated with methods promise ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output( ".*R: HEY I activated app00_zero R: HEY I activated app_one R: HEY I activated app_zero.*", ".*FAIL.*", $(command), $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 dynamic_inputs_based_on_class_set_using_variable_file_control_extends_inputs.cf0000644000000000000000000000224715010704253047140 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence####################################################### # # Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Bundle list built from array # Bundles policy defined in separate file # include only app files neaded based on list built from array # Lexicly sorted bundles activated with methods promise ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { meta: "tags" slist => { "redmine#6867", "zendesk#1600" }; vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output( ".*R: HEY I activated app00_zero R: HEY I activated app_one R: HEY I activated app_zero.*", ".*FAIL.*", $(command), $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/classes/0000755000000000000000000000000015010704253030450 5ustar00rootroot00000000000000enable_test_bundle0000644000000000000000000000000015010704253034120 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/classesdynamic_inputs_based_on_class_set_using_variable_file_control_extends_inputs.cf.sub0000644000000000000000000000352615010704253047731 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence# Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Bundle list built from array # Bundles policy defined in separate file # include only app files neaded based on list built from array # Lexicly sorted bundles activated with methods promise body common control { bundlesequence => { "classify", "map_role_bundles", "go" }; } bundle common classify { vars: "variable" string => "vmware"; classes: "group_one" expression => strcmp($(variable), "vmware"), comment => "Highest level classification, other classes depend on this."; } bundle common map_role_bundles { vars: # Define bundles any:: "role[app00_zero]" string => "$(this.promise_dirname)/apps/app00_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; "role[app_zero]" string => "$(this.promise_dirname)/apps/app_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_one:: "role[app_one]" string => "$(this.promise_dirname)/apps/app_one.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_none:: "role[app_two]" string => "$(this.promise_dirname)/apps/app_two.cf.sub"; any:: "inputs" slist => getvalues(role); "bundles" slist => getindices(role); } bundle agent go { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); methods: "$(sorted_bundles)" usebundle => $(sorted_bundles); } body file control { inputs => { @(map_role_bundles.inputs) }; } classification_bundles_not_in_sequence3.cf0000644000000000000000000000205115010704253037274 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence####################################################### # # Test a simple dynamic bundlesequnece pattern # Classification Bundles NOT listed in bundlesequence # Classificaiton bundles defined in order used # Bundle list built from array # Lexicly sorted bundles activated from bundlesequence ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output( ".*R: HEY I activated app00_zero R: HEY I activated app_one R: HEY I activated app_zero.*", ".*FAIL.*", $(command), $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/simple.cf.sub0000644000000000000000000000355415010704253031415 0ustar00rootroot00000000000000# Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Bundle list built from array # Lexicly sorted bundles activated with methods promise body common control # { bundlesequence => { "classify", "map_role_bundles", "go" }; } bundle common classify # { vars: "variable" string => "vmware"; classes: "group_one" expression => strcmp("$(variable)", "vmware"), comment => "Highest level classification, other classes depend on this."; } bundle common map_role_bundles # { vars: # Define bundles any:: "role[app00_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; "role[app_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_one:: "role[app_one]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_none:: "role[app_two]" string => "/path/to_policy_file.cf"; any:: "bundles" slist => getindices(role); } bundle agent go # { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); methods: "$(sorted_bundles)" usebundle => $(sorted_bundles); } bundle agent app_one # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_two # { reports: "HEY I activated $(this.bundle)"; } bundle agent app00_zero # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_zero # { reports: "HEY I activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/apps/0000755000000000000000000000000015010704253027756 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/apps/app_two.cf.sub0000644000000000000000000000011715010704253032530 0ustar00rootroot00000000000000bundle agent app_two # { reports: "HEY I activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/apps/app_one.cf.sub0000644000000000000000000000011715010704253032500 0ustar00rootroot00000000000000bundle agent app_one # { reports: "HEY I activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/apps/app00_zero.cf.sub0000644000000000000000000000012215010704253033032 0ustar00rootroot00000000000000bundle agent app00_zero # { reports: "HEY I activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/apps/app_zero.cf.sub0000644000000000000000000000012015010704253032670 0ustar00rootroot00000000000000bundle agent app_zero # { reports: "HEY I activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence/app_based_inputs.cf0000644000000000000000000000214015010704253032642 0ustar00rootroot00000000000000####################################################### # # Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Bundle list built from array # Bundles policy defined in separate file # include only app files neaded based on list built from array # Lexicly sorted bundles activated with methods promise ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output( ".*R: HEY I activated app00_zero R: HEY I activated app_one R: HEY I activated app_zero.*", ".*FAIL.*", $(command), $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 classification_bundles_not_in_sequence2.cf.sub0000644000000000000000000000366015010704253040072 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence# Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Map role bundles (which uses the classify bundle) is defined BEFORE the classify bundle (linerally). # Bundle list built from array # Lexicly sorted bundles activated with methods promise body common control # { bundlesequence => { "go" }; } bundle agent go # { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); methods: "$(sorted_bundles)" usebundle => $(sorted_bundles); } bundle agent app_one # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_two # { reports: "HEY I activated $(this.bundle)"; } bundle agent app00_zero # { reports: "HEY I activated $(this.bundle)"; } bundle agent app_zero # { reports: "HEY I activated $(this.bundle)"; } bundle common map_role_bundles # { vars: # Define bundles any:: "role[app00_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; "role[app_zero]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_one:: "role[app_one]" string => "/path/to/policy_file.cf", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_none:: "role[app_two]" string => "/path/to_policy_file.cf"; any:: "bundles" slist => getindices(role); } bundle common classify # { vars: "variable" string => "vmware"; classes: "group_one" expression => strcmp("vmware", "vmware"), comment => "Highest level classification, other classes depend on this."; } dynamic_inputs_based_on_list_variable_dependent_on_class.cf0000644000000000000000000000122515010704253042735 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequencebody common control { inputs => { @(inventory.inputs) }; bundlesequence => { @(inventory.bundles) }; } bundle common inventory { classes: "this_is_true" expression => "any"; vars: !this_is_true:: "inputs" slist => { }; "bundles" slist => { "bad" }; this_is_true.!windows:: "inputs" slist => { "$(this.promise_filename).sub" }; "bundles" slist => { "good" }; windows:: "bundles" slist => { "skip" }; } bundle agent bad { reports: "$(this.promise_filename) FAIL"; } bundle agent skip { reports: "$(this.promise_filename) Skip/unsupported"; } classification_bundles_not_in_sequence2.cf0000644000000000000000000000176715010704253037310 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/dynamic_bundlesequence####################################################### # # Test a simple dynamic bundlesequnece pattern # Classification Bundles listed in bundlesequence # Bundle list built from array # Lexicly sorted bundles activated with methods promise ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template_target" string => "$(G.testfile)"; files: "$(template_target)" create => "true"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output( ".*R: HEY I activated app00_zero R: HEY I activated app_one R: HEY I activated app_zero.*", ".*FAIL.*", $(command), $(this.promise_filename)); } ### PROJECT_ID: core ### CATEGORY_ID: 27 agent-bundle-namespaced-class-default-perspective.cf0000755000000000000000000000465715010704253034276 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/04_bundles#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body file control { namespace => "test"; } bundle agent example { classes: "TRIGGERED" expression => "any", scope => "namespace"; # Namespace scoped classes are visible from other bundles reports: TRIGGERED:: "TRIGGERED is defined within $(this.namespace).$(this.bundle)"; default:TRIGGERED:: "default:TRIGGERED is defined within $(this.namespace).$(this.bundle)"; test:TRIGGERED:: "$(this.namespace):TRIGGERED is defined within $(this.namespace).$(this.bundle)"; } body file control { namespace => "default"; } bundle agent test { meta: "description" -> {"ENT-4681" } string => "Test that namespace scoped classes defined from namespaced agent bundles are properly scoped. Specifically from the default namespace."; "test_soft_fail" string => "any", meta => { "ENT-4681" }; methods: "test:example"; } bundle agent check { classes: # Expectation, default:TRIGGERED is NOT defined "default_TRIGGERED_OK" expression => "!default:TRIGGERED"; # Expectation, test:TRIGGERED is defined (visable since it's a namespace scoped class) "namespaced_TRIGGERED_OK" expression => "test:TRIGGERED"; # Expectation, TRIGGERED is NOT defined, we are now in the default namespace, the TRIGGERED class was defined in the test namespace and should not be seen without explicitly using it's namespace "TRIGGERED_OK" expression => "!TRIGGERED"; "pass" and => { "default_TRIGGERED_OK", "namespaced_TRIGGERED_OK", "TRIGGERED_OK", }; reports: pass:: "Pass $(this.promise_filename)"; !pass:: "FAIL $(this.promise_filename)"; !default_TRIGGERED_OK:: "Expected 'default:TRIGGERED' to not be seen as defined, but expression '!default:TRIGGERED' resulted in true"; !namespaced_TRIGGERED_OK:: "Expected 'test:TRIGGERED' to be seen as defined, but expression 'test:TRIGGERED' resulted in false"; !TRIGGERED_OK:: "Expected 'TRIGGERED' to NOT be seen as defined, but expression 'TRIGGERED' resulted in true even without specify the test namespace"; } bundle agent __main__ { methods: "test:example"; "check"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/wrong-bundle-type.cf0000644000000000000000000000123715010704253026204 0ustar00rootroot00000000000000# Test that wrong bundle type is detected (Redmine #XXXX) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { vars: "subout" string => execresult("${sys.cf_agent} -Kf ${this.promise_filename}.sub", "noshell"); } bundle agent check { classes: "ok" expression => regcmp(".*Unknown bundle type.*", "${test.subout}"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/bundle-iteration.cf0000644000000000000000000000150115010704253026061 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "bundles" slist => { "a", "b" }; "values" slist => { "x", "y" }; methods: "b" usebundle => $(bundles)("z"); # runs 2x "bv" usebundle => $(bundles)($(values)); # runs 4x } bundle agent a(var) { classes: "a_$(var)" expression => "any", scope => "namespace"; } bundle agent b(var) { classes: "b_$(var)" expression => "any", scope => "namespace"; } bundle agent check { classes: "ok" and => { "a_x", "b_x", "a_y", "b_y", "a_z", "b_z" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/main_duplicate_2.x.cf0000644000000000000000000000033115010704253026261 0ustar00rootroot00000000000000bundle agent __main__ { reports: "This should fail because duplicate bundles aren't allowed"; } bundle agent __main__ { reports: "This should fail because duplicate bundles aren't allowed"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/main_rename.x.cf0000644000000000000000000000025315010704253025340 0ustar00rootroot00000000000000body common control { bundlesequence => { "__main__" }; } bundle agent __main__ { reports: "This should fail because __main__ will be renamed to main"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/common-bundle-normal-ordering.cf0000644000000000000000000000155715010704253030463 0ustar00rootroot00000000000000# Tests that normal ordering (classes before vars) is adhered to in commmon # bundles, leading to correct resolution regardless of policy order. # This check tests that # 1. Common bundles are converged before other bundles. # 2. Common bundles promises follow normal ordering body common control { bundlesequence => { check }; version => "1.0"; } bundle agent check { reports: any:: # this was the only way I found to trigger the issue. Classifying # on join seems to resolve the variable. "$(this.promise_filename) $(g_stuff.two)"; } # It is critical that the common bundle is declared after the agent bundles bundle common g_stuff { # promise type ordering here is critical vars: trigger:: "one" string => "Pas"; any:: "two" slist => { "$(one)s" }; classes: "trigger" expression => "any"; } cfengine-3.24.2/tests/acceptance/00_basics/04_bundles/main_duplicate_3.x.cf0000644000000000000000000000032115010704253026261 0ustar00rootroot00000000000000bundle agent main { reports: "This should fail because duplicate bundles aren't allowed"; } bundle agent main { reports: "This should fail because duplicate bundles aren't allowed"; } cfengine-3.24.2/tests/acceptance/00_basics/environment/0000755000000000000000000000000015010704253022712 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/environment/proc-net.cf.sub0000644000000000000000000000231215010704253025541 0ustar00rootroot00000000000000# you can run this test directly with # CFENGINE_TEST_OVERRIDE_PROCDIR=`pwd`/00_basics/environment/proc-net.cf.proc testall 00_basics/environment/proc-net.cf.sub body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } bundle agent test { vars: "todo" slist => { "inet", "inet6", "interfaces_data" }; "$(todo)" data => mergedata("sys.$(todo)"); # make sure deep lookups work "docker" string => "$(sys.inet6[addresses][docker0][address])"; "default_gateway" string => "$(sys.inet[default_gateway])"; } bundle agent check { vars: "testname" string => regex_replace($(this.promise_filename), "\\.sub$", "", ""); methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(testname)); test_debug:: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/environment/hpux.cf0000644000000000000000000000262015010704253024210 0ustar00rootroot00000000000000############################################################################## # # Redmine #3842: ensure correct sys.flavor, sys.arch on HP-UX # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { } bundle agent check { vars: "expected[flavor]" string => ifelse("hpux", "hp-ux_.+", "unknown"); "expected[arch]" string => ifelse("hpux", "ia64", "unknown"); "checks" slist => getindices("expected"); # If the output contains the string, we fail classes: "ok_$(checks)" expression => regcmp("$(expected[$(checks)])", "$(sys.$(checks))"); "unknown_$(checks)" expression => strcmp("$(expected[$(checks)])", "unknown"); "ok" and => { "ok_flavor", "ok_arch" }; "skipped" and => { "unknown_flavor", "unknown_arch" }; reports: DEBUG:: "check $(checks) was OK" if => "ok_$(checks)"; "check $(checks) was not OK" if => "!ok_$(checks).!unknown_$(checks)"; "check $(checks) was unknown (skipped)" if => "unknown_$(checks)"; ok||skipped:: "$(this.promise_filename) Pass"; !ok.!skipped:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/environment/workdir_correct_after_files_promise.cf0000644000000000000000000000162715010704253032535 0ustar00rootroot00000000000000############################################################################## # # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { meta: # This test should be skipped on non linux hosts when its fixed (or # improved to do something similar on platforms that don't have /bin/pwd "test_soft_fail" string => "any", meta => { "redmine7569" }; vars: # When the agent runs the test, pwd should not return /tmp "fail_string" string => 'Q: ".*/bin/pwd": /tmp'; "command" string => "$(sys.cf-agent) -KIf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*", escape($(fail_string)), $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/environment/proc-net.cf0000644000000000000000000000066515010704253024762 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { meta: "test_skip_unsupported" string => "!linux"; commands: "$(G.env) CFENGINE_TEST_OVERRIDE_PROCDIR=$(this.promise_dirname)/proc $(sys.cf_agent) -DAUTO -f $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/environment/proc-net-functions.cf.sub0000644000000000000000000000165315010704253027556 0ustar00rootroot00000000000000# you can run this test directly with # CFENGINE_TEST_OVERRIDE_PROCDIR=`pwd`/00_basics/environment/proc testall 00_basics/environment/proc-net-functions.cf.sub body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } bundle agent test { vars: "connections" data => network_connections(); } bundle agent check { vars: "testname" string => regex_replace($(this.promise_filename), "\\.sub$", "", ""); methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(testname)); test_debug:: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/environment/proc-net-functions.cf0000644000000000000000000000066515010704253026770 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { meta: "test_skip_unsupported" string => "!linux"; commands: "$(G.env) CFENGINE_TEST_OVERRIDE_PROCDIR=$(this.promise_dirname)/proc $(sys.cf_agent) -DAUTO -f $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/0000755000000000000000000000000015010704253023655 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/0000755000000000000000000000000015010704253024620 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/0000755000000000000000000000000015010704253025406 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/udp60000644000000000000000000000123015010704253026203 0ustar00rootroot00000000000000 sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops 4029: 00000000000000000000000000000000:14E9 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 107 0 13195 2 0000000000000000 0 13690: 00000000000000000000000000000000:BAA6 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 107 0 13197 2 0000000000000000 0 15087: 00000000000000000000000000000000:401B 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 15931 2 0000000000000000 0 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/snmp60000644000000000000000000000625215010704253026401 0ustar00rootroot00000000000000Ip6InReceives 492189 Ip6InHdrErrors 0 Ip6InTooBigErrors 0 Ip6InNoRoutes 0 Ip6InAddrErrors 0 Ip6InUnknownProtos 0 Ip6InTruncatedPkts 0 Ip6InDiscards 0 Ip6InDelivers 490145 Ip6OutForwDatagrams 0 Ip6OutRequests 12145 Ip6OutDiscards 6 Ip6OutNoRoutes 249070 Ip6ReasmTimeout 0 Ip6ReasmReqds 0 Ip6ReasmOKs 0 Ip6ReasmFails 0 Ip6FragOKs 0 Ip6FragFails 0 Ip6FragCreates 0 Ip6InMcastPkts 488766 Ip6OutMcastPkts 10304 Ip6InOctets 132343220 Ip6OutOctets 1522724 Ip6InMcastOctets 131896014 Ip6OutMcastOctets 1076616 Ip6InBcastOctets 0 Ip6OutBcastOctets 0 Ip6InNoECTPkts 492196 Ip6InECT1Pkts 0 Ip6InECT0Pkts 0 Ip6InCEPkts 0 Icmp6InMsgs 275 Icmp6InErrors 0 Icmp6OutMsgs 1815 Icmp6OutErrors 0 Icmp6InCsumErrors 0 Icmp6InDestUnreachs 0 Icmp6InPktTooBigs 0 Icmp6InTimeExcds 0 Icmp6InParmProblems 0 Icmp6InEchos 0 Icmp6InEchoReplies 0 Icmp6InGroupMembQueries 0 Icmp6InGroupMembResponses 1 Icmp6InGroupMembReductions 1 Icmp6InRouterSolicits 0 Icmp6InRouterAdvertisements 0 Icmp6InNeighborSolicits 5 Icmp6InNeighborAdvertisements 268 Icmp6InRedirects 0 Icmp6InMLDv2Reports 0 Icmp6OutDestUnreachs 0 Icmp6OutPktTooBigs 0 Icmp6OutTimeExcds 0 Icmp6OutParmProblems 0 Icmp6OutEchos 0 Icmp6OutEchoReplies 0 Icmp6OutGroupMembQueries 0 Icmp6OutGroupMembResponses 0 Icmp6OutGroupMembReductions 0 Icmp6OutRouterSolicits 396 Icmp6OutRouterAdvertisements 0 Icmp6OutNeighborSolicits 206 Icmp6OutNeighborAdvertisements 5 Icmp6OutRedirects 0 Icmp6OutMLDv2Reports 1208 Icmp6InType131 1 Icmp6InType132 1 Icmp6InType135 5 Icmp6InType136 268 Icmp6OutType133 396 Icmp6OutType135 206 Icmp6OutType136 5 Icmp6OutType143 1208 Udp6InDatagrams 486201 Udp6NoPorts 0 Udp6InErrors 0 Udp6OutDatagrams 7273 Udp6RcvbufErrors 0 Udp6SndbufErrors 0 Udp6InCsumErrors 0 Udp6IgnoredMulti 0 UdpLite6InDatagrams 0 UdpLite6NoPorts 0 UdpLite6InErrors 0 UdpLite6OutDatagrams 0 UdpLite6RcvbufErrors 0 UdpLite6SndbufErrors 0 UdpLite6InCsumErrors 0 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/dev0000644000000000000000000000111315010704253026103 0ustar00rootroot00000000000000Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed enp4s0: 446377831179 492136556 0 0 0 0 0 0 428200856331 499195545 0 0 0 0 0 0 lo: 1210580426 1049790 0 0 0 0 0 0 1210580426 1049790 0 0 0 0 0 0 wlp3s0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/netstat0000644000000000000000000000524315010704253027017 0ustar00rootroot00000000000000TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPLossProbes TCPLossProbeRecovery TCPRenoRecoveryFail TCPSackRecoveryFail TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPRetransFail TCPRcvCoalesce TCPOFOQueue TCPOFODrop TCPOFOMerge TCPChallengeACK TCPSYNChallenge TCPFastOpenActive TCPFastOpenActiveFail TCPFastOpenPassive TCPFastOpenPassiveFail TCPFastOpenListenOverflow TCPFastOpenCookieReqd TCPSpuriousRtxHostQueues BusyPollRxPackets TCPAutoCorking TCPFromZeroWindowAdv TCPToZeroWindowAdv TCPWantZeroWindowAdv TCPSynRetrans TCPOrigDataSent TCPHystartTrainDetect TCPHystartTrainCwnd TCPHystartDelayDetect TCPHystartDelayCwnd TCPACKSkippedSynRecv TCPACKSkippedPAWS TCPACKSkippedSeq TCPACKSkippedFinWait2 TCPACKSkippedTimeWait TCPACKSkippedChallenge TCPWinProbe TCPKeepAlive TcpExt: 0 0 0 19896 7 0 0 9 0 0 560727 0 0 0 0 3575 2049614 302 313016 0 0 17283401 130554 186252521 0 126381259 21978 34307113 42386136 481 386568 7 175 316 11 822 2028 483 20959 148926 16709 267 271328 38869 512579 72057 281202 375133 561590 150370 23 59420 0 106 391776 9062 174837 4389 211213 13931 0 14556 0 0 0 585 594 65103 100117 0 0 0 0 2199955 0 0 0 0 0 0 0 15 36402752 5236349 0 7020 7132 4057 0 0 0 0 0 0 70 0 17925237 24 30 71 693624 275201738 33 992 2253 49843 136 484 21848 0 25 218 10478 503111 IpExt: InNoRoutes InTruncatedPkts InMcastPkts OutMcastPkts InBcastPkts OutBcastPkts InOctets OutOctets InMcastOctets OutMcastOctets InBcastOctets OutBcastOctets InCsumErrors InNoECTPkts InECT1Pkts InECT0Pkts InCEPkts IpExt: 0 0 1304886 130589 3784495 6 437612883789 422416538003 334973818 8189234 817859007 284 1 487495405 18258 4804476 543340 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/if_inet60000644000000000000000000000024215010704253027032 0ustar00rootroot0000000000000000000000000000000000000000000001 01 80 10 80 lo fe80000000000000004249fffebdd7b4 04 40 20 80 docker0 fe80000000000000c27cd1fffe3eada6 02 40 20 80 enp4s0 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/tcp0000644000000000000000000364116215010704253026134 0ustar00rootroot00000000000000 sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 0: 00000000:BCEF 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828769 1 0000000000000000 100 0 0 10 0 1: 0101007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 11263 1 0000000000000000 100 0 0 10 0 2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23651 1 0000000000000000 100 0 0 10 0 3: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827515 1 0000000000000000 100 0 0 10 0 4: 0100007F:22B8 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 12828786 1 0000000000000000 100 0 0 10 0 5: 00000000:E27F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016062 1 0000000000000000 100 0 0 10 0 6: 0100007F:1F40 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939376 1 0000000000000000 100 0 0 10 0 7: 00000000:60E0 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 16124 1 0000000000000000 100 0 0 10 0 8: 3202A8C0:895C 2E7BC2AD:01BB 06 00000000:00000000 03:00001463 00000000 0 0 0 3 0000000000000000 9: 3202A8C0:D9DE 43E27D4A:01BB 06 00000000:00000000 03:00000E9A 00000000 0 0 0 3 0000000000000000 10: 3202A8C0:B892 BC167D4A:146C 01 00000000:00000000 02:00000600 00000000 1000 0 10728629 2 0000000000000000 23 4 0 10 -1 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/ipv6_route0000644000000000000000000000160415010704253027434 0ustar00rootroot00000000000000fe800000000000000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000001 00000004 00000001 enp4s0 00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 0007e26c 00200200 lo 00000000000000000000000000000001 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000009 0000020b 80200001 lo fe80000000000000c27cd1fffe3eada6 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000002 00000004 80200001 lo ff000000000000000000000000000000 08 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000008 0003ffc5 00000001 enp4s0 00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 0007e26c 00200200 lo cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/udp0000644000000000000000000000100015010704253026110 0ustar00rootroot00000000000000 sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops 576: 00000000:076C 00000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 12828775 2 0000000000000000 0 12537: 3202A8C0:B625 0102A8C0:14E7 01 00000000:00000000 00:00000000 00000000 1000 0 1020761 2 0000000000000000 0 15113: 0101007F:0035 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 11262 2 0000000000000000 0 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/route0000644000000000000000000000100015010704253026456 0ustar00rootroot00000000000000Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT enp4s0 00000000 0102A8C0 0003 0 0 100 00000000 0 0 0 enp4s0 0000FEA9 00000000 0001 0 0 1000 0000FFFF 0 0 0 enp4s0 0002A8C0 00000000 0001 0 0 100 00FFFFFF 0 0 0 cfengine-3.24.2/tests/acceptance/00_basics/environment/proc/proc/net/tcp60000644000000000000000000000230415010704253026204 0ustar00rootroot00000000000000 sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 0: 00000000000000000000000000000000:0016 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 23653 1 0000000000000000 100 0 0 10 0 1: 00000000000000000000000001000000:0277 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 12827514 1 0000000000000000 100 0 0 10 0 2: 00000000000000000000000000000000:E27F 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 1016064 1 0000000000000000 100 0 0 10 0 3: 00000000000000000000000001000000:1F40 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 11939375 1 0000000000000000 100 0 0 10 0 4: 00000000000000000000000001000000:B1DA 00000000000000000000000001000000:0277 08 00000000:00000001 00:00000000 00000000 0 0 14023 1 0000000000000000 20 4 24 10 -1 5: 00000000000000000000000001000000:B3F6 00000000000000000000000001000000:0277 08 00000000:00000001 00:00000000 00000000 0 0 12522538 1 0000000000000000 20 4 24 10 -1 cfengine-3.24.2/tests/acceptance/00_basics/environment/workdir_correct_after_files_promise.cf.sub0000644000000000000000000000156715010704253033330 0ustar00rootroot00000000000000############################################################################## # # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test_exec(id, cmd) { commands: "$(cmd)" handle => "$(id)"; reports: DEBUG|DEBUG_test_exec:: "DEBUG $(this.bundle): $(id) $(cmd)"; } bundle agent test_touch(file) { files: "$(file)" create => "true", touch => "true"; reports: DEBUG|DEBUG_test_touch:: "DEBUG $(this.bundle): touch '$(file)'"; } bundle agent test { methods: "pwd_1" usebundle => test_exec("pwd_1", "/bin/pwd"); "touch_1" usebundle => test_touch("$(G.testfile)"); "pwd_2" usebundle => test_exec("pwd_2", "/bin/pwd"); } cfengine-3.24.2/tests/acceptance/00_basics/environment/proc-net-functions.cf.sub.expected.json0000644000000000000000000550636315010704253032343 0ustar00rootroot00000000000000{ "connections": { "tcp": [ { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" }, { "local": { "address": "0.0.0.0", "port": "48367" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "22" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "631" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8888" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "57983" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "127.0.0.1", "port": "8000" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0.0.0.0", "port": "24800" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "192.168.2.50", "port": "35164" }, "remote": { "address": "173.194.123.46", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "55774" }, "remote": { "address": "74.125.226.67", "port": "443" }, "state": "TIME_WAIT" }, { "local": { "address": "192.168.2.50", "port": "47250" }, "remote": { "address": "74.125.22.188", "port": "5228" }, "state": "ESTABLISHED" } ], "tcp6": [ { "local": { "address": "0:0:0:0:0:0:0:0", "port": "22" }, "remote": { "address": "0:0:0:0:0:0:0:0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0:0:0:0:0:0:100:0", "port": "631" }, "remote": { "address": "0:0:0:0:0:0:0:0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0:0:0:0:0:0:0:0", "port": "57983" }, "remote": { "address": "0:0:0:0:0:0:0:0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0:0:0:0:0:0:100:0", "port": "8000" }, "remote": { "address": "0:0:0:0:0:0:0:0", "port": "0" }, "state": "UNKNOWN" }, { "local": { "address": "0:0:0:0:0:0:100:0", "port": "45530" }, "remote": { "address": "0:0:0:0:0:0:100:0", "port": "631" }, "state": "CLOSE_WAIT" }, { "local": { "address": "0:0:0:0:0:0:100:0", "port": "46070" }, "remote": { "address": "0:0:0:0:0:0:100:0", "port": "631" }, "state": "CLOSE_WAIT" } ], "udp": [ { "local": { "address": "0.0.0.0", "port": "1900" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "CLOSE" }, { "local": { "address": "192.168.2.50", "port": "46629" }, "remote": { "address": "192.168.2.1", "port": "5351" }, "state": "ESTABLISHED" }, { "local": { "address": "127.0.1.1", "port": "53" }, "remote": { "address": "0.0.0.0", "port": "0" }, "state": "CLOSE" } ], "udp6": [ { "local": { "address": "0:0:0:0:0:0:0:0", "port": "5353" }, "remote": { "address": "0:0:0:0:0:0:0:0", "port": "0" }, "state": "CLOSE" }, { "local": { "address": "0:0:0:0:0:0:0:0", "port": "47782" }, "remote": { "address": "0:0:0:0:0:0:0:0", "port": "0" }, "state": "CLOSE" }, { "local": { "address": "0:0:0:0:0:0:0:0", "port": "16411" }, "remote": { "address": "0:0:0:0:0:0:0:0", "port": "0" }, "state": "CLOSE" } ] } } cfengine-3.24.2/tests/acceptance/00_basics/environment/proc-net.cf.sub.expected.json0000644000000000000000000002765315010704253030330 0ustar00rootroot00000000000000{ "default_gateway": "192.168.2.1", "docker": "fe80:0:0:0:42:49ff:febd:d7b4", "inet": { "default_gateway": "192.168.2.1", "default_route": { "active_default_gateway": true, "dest": "0.0.0.0", "flags": [ "up", "net", "default", "gateway" ], "gateway": "192.168.2.1", "interface": "enp4s0", "irtt": 0, "mask": "0.0.0.0", "metric": 100, "mtu": 0, "refcnt": 0, "use": 0, "window": 0 }, "routes": [ { "active_default_gateway": true, "dest": "0.0.0.0", "flags": [ "up", "net", "default", "gateway" ], "gateway": "192.168.2.1", "interface": "enp4s0", "irtt": 0, "mask": "0.0.0.0", "metric": 100, "mtu": 0, "refcnt": 0, "use": 0, "window": 0 }, { "active_default_gateway": false, "dest": "169.254.0.0", "flags": [ "up", "net", "not_default", "local" ], "gateway": "0.0.0.0", "interface": "enp4s0", "irtt": 0, "mask": "255.255.0.0", "metric": 1000, "mtu": 0, "refcnt": 0, "use": 0, "window": 0 }, { "active_default_gateway": false, "dest": "192.168.2.0", "flags": [ "up", "net", "not_default", "local" ], "gateway": "0.0.0.0", "interface": "enp4s0", "irtt": 0, "mask": "255.255.255.0", "metric": 100, "mtu": 0, "refcnt": 0, "use": 0, "window": 0 } ], "stats": { "IpExt": { "InBcastOctets": "817859007", "InBcastPkts": "3784495", "InCEPkts": "543340", "InCsumErrors": "1", "InECT0Pkts": "4804476", "InECT1Pkts": "18258", "InMcastOctets": "334973818", "InMcastPkts": "1304886", "InNoECTPkts": "487495405", "InNoRoutes": "0", "InOctets": "437612883789", "InTruncatedPkts": "0", "OutBcastOctets": "284", "OutBcastPkts": "6", "OutMcastOctets": "8189234", "OutMcastPkts": "130589", "OutOctets": "422416538003" }, "TcpExt": { "ArpFilter": "0", "BusyPollRxPackets": "0", "DelayedACKLocked": "302", "DelayedACKLost": "313016", "DelayedACKs": "2049614", "EmbryonicRsts": "19896", "IPReversePathFilter": "0", "ListenDrops": "0", "ListenOverflows": "0", "LockDroppedIcmps": "0", "OfoPruned": "0", "OutOfWindowIcmps": "9", "PAWSActive": "0", "PAWSEstab": "3575", "PAWSPassive": "0", "PruneCalled": "7", "RcvPruned": "0", "SyncookiesFailed": "0", "SyncookiesRecv": "0", "SyncookiesSent": "0", "TCPACKSkippedChallenge": "218", "TCPACKSkippedFinWait2": "0", "TCPACKSkippedPAWS": "484", "TCPACKSkippedSeq": "21848", "TCPACKSkippedSynRecv": "136", "TCPACKSkippedTimeWait": "25", "TCPAbortFailed": "0", "TCPAbortOnClose": "13931", "TCPAbortOnData": "211213", "TCPAbortOnLinger": "0", "TCPAbortOnMemory": "0", "TCPAbortOnTimeout": "14556", "TCPAutoCorking": "17925237", "TCPBacklogDrop": "0", "TCPChallengeACK": "7132", "TCPDSACKIgnoredNoUndo": "65103", "TCPDSACKIgnoredOld": "594", "TCPDSACKOfoRecv": "4389", "TCPDSACKOfoSent": "9062", "TCPDSACKOldSent": "391776", "TCPDSACKRecv": "174837", "TCPDSACKUndo": "20959", "TCPDeferAcceptDrop": "0", "TCPDirectCopyFromBacklog": "130554", "TCPDirectCopyFromPrequeue": "186252521", "TCPFACKReorder": "175", "TCPFastOpenActive": "0", "TCPFastOpenActiveFail": "0", "TCPFastOpenCookieReqd": "0", "TCPFastOpenListenOverflow": "0", "TCPFastOpenPassive": "0", "TCPFastOpenPassiveFail": "0", "TCPFastRetrans": "512579", "TCPForwardRetrans": "72057", "TCPFromZeroWindowAdv": "24", "TCPFullUndo": "2028", "TCPHPAcks": "42386136", "TCPHPHits": "126381259", "TCPHPHitsToUser": "21978", "TCPHystartDelayCwnd": "49843", "TCPHystartDelayDetect": "2253", "TCPHystartTrainCwnd": "992", "TCPHystartTrainDetect": "33", "TCPKeepAlive": "503111", "TCPLossFailures": "38869", "TCPLossProbeRecovery": "150370", "TCPLossProbes": "561590", "TCPLossUndo": "148926", "TCPLostRetransmit": "16709", "TCPMD5NotFound": "0", "TCPMD5Unexpected": "0", "TCPMemoryPressures": "0", "TCPMinTTLDrop": "0", "TCPOFODrop": "0", "TCPOFOMerge": "7020", "TCPOFOQueue": "5236349", "TCPOrigDataSent": "275201738", "TCPPartialUndo": "483", "TCPPrequeueDropped": "0", "TCPPrequeued": "17283401", "TCPPureAcks": "34307113", "TCPRcvCoalesce": "36402752", "TCPRcvCollapsed": "106", "TCPRenoFailures": "267", "TCPRenoRecovery": "481", "TCPRenoRecoveryFail": "23", "TCPRenoReorder": "11", "TCPReqQFullDoCookies": "0", "TCPReqQFullDrop": "0", "TCPRetransFail": "15", "TCPSACKDiscard": "585", "TCPSACKReneging": "7", "TCPSACKReorder": "316", "TCPSYNChallenge": "4057", "TCPSackFailures": "271328", "TCPSackMerged": "0", "TCPSackRecovery": "386568", "TCPSackRecoveryFail": "59420", "TCPSackShiftFallback": "2199955", "TCPSackShifted": "0", "TCPSchedulerFailed": "0", "TCPSlowStartRetrans": "281202", "TCPSpuriousRTOs": "100117", "TCPSpuriousRtxHostQueues": "70", "TCPSynRetrans": "693624", "TCPTSReorder": "822", "TCPTimeWaitOverflow": "0", "TCPTimeouts": "375133", "TCPToZeroWindowAdv": "30", "TCPWantZeroWindowAdv": "71", "TCPWinProbe": "10478", "TW": "560727", "TWKilled": "0", "TWRecycled": "0" } } }, "inet6": { "addresses": { "docker0": { "address": "fe80:0:0:0:42:49ff:febd:d7b4", "device_number": 4, "interface": "docker0", "prefix_length": 64, "raw_flags": "80", "scope": 32 }, "enp4s0": { "address": "fe80:0:0:0:c27c:d1ff:fe3e:ada6", "device_number": 2, "interface": "enp4s0", "prefix_length": 64, "raw_flags": "80", "scope": 32 }, "lo": { "address": "0:0:0:0:0:0:0:1", "device_number": 1, "interface": "lo", "prefix_length": 128, "raw_flags": "80", "scope": 16 } }, "routes": [ { "dest": "0:0:0:0:0:0:0:0", "dest_prefix": "40", "flags": [ "up", "net", "local" ], "interface": "enp4s0", "metric": 256, "next_hop": "0:0:0:0:0:0:0:0", "refcnt": 1, "source_prefix": "00", "use": 4 }, { "dest": "0:0:0:0:0:0:0:0", "dest_prefix": "80", "flags": [ "up", "net", "local" ], "interface": "lo", "metric": 0, "next_hop": "0:0:0:0:0:0:0:0", "refcnt": 2, "source_prefix": "00", "use": 4 } ], "stats": { "Icmp6InCsumErrors": 0, "Icmp6InDestUnreachs": 0, "Icmp6InEchoReplies": 0, "Icmp6InEchos": 0, "Icmp6InErrors": 0, "Icmp6InGroupMembQueries": 0, "Icmp6InGroupMembReductions": 1, "Icmp6InGroupMembResponses": 1, "Icmp6InMLDv2Reports": 0, "Icmp6InMsgs": 275, "Icmp6InNeighborAdvertisements": 268, "Icmp6InNeighborSolicits": 5, "Icmp6InParmProblems": 0, "Icmp6InPktTooBigs": 0, "Icmp6InRedirects": 0, "Icmp6InRouterAdvertisements": 0, "Icmp6InRouterSolicits": 0, "Icmp6InTimeExcds": 0, "Icmp6InType131": 1, "Icmp6InType132": 1, "Icmp6InType135": 5, "Icmp6InType136": 268, "Icmp6OutDestUnreachs": 0, "Icmp6OutEchoReplies": 0, "Icmp6OutEchos": 0, "Icmp6OutErrors": 0, "Icmp6OutGroupMembQueries": 0, "Icmp6OutGroupMembReductions": 0, "Icmp6OutGroupMembResponses": 0, "Icmp6OutMLDv2Reports": 1208, "Icmp6OutMsgs": 1815, "Icmp6OutNeighborAdvertisements": 5, "Icmp6OutNeighborSolicits": 206, "Icmp6OutParmProblems": 0, "Icmp6OutPktTooBigs": 0, "Icmp6OutRedirects": 0, "Icmp6OutRouterAdvertisements": 0, "Icmp6OutRouterSolicits": 396, "Icmp6OutTimeExcds": 0, "Icmp6OutType133": 396, "Icmp6OutType135": 206, "Icmp6OutType136": 5, "Icmp6OutType143": 1208, "Ip6FragCreates": 0, "Ip6FragFails": 0, "Ip6FragOKs": 0, "Ip6InAddrErrors": 0, "Ip6InBcastOctets": 0, "Ip6InCEPkts": 0, "Ip6InDelivers": 490145, "Ip6InDiscards": 0, "Ip6InECT0Pkts": 0, "Ip6InECT1Pkts": 0, "Ip6InHdrErrors": 0, "Ip6InMcastOctets": 131896014, "Ip6InMcastPkts": 488766, "Ip6InNoECTPkts": 492196, "Ip6InNoRoutes": 0, "Ip6InOctets": 132343220, "Ip6InReceives": 492189, "Ip6InTooBigErrors": 0, "Ip6InTruncatedPkts": 0, "Ip6InUnknownProtos": 0, "Ip6OutBcastOctets": 0, "Ip6OutDiscards": 6, "Ip6OutForwDatagrams": 0, "Ip6OutMcastOctets": 1076616, "Ip6OutMcastPkts": 10304, "Ip6OutNoRoutes": 249070, "Ip6OutOctets": 1522724, "Ip6OutRequests": 12145, "Ip6ReasmFails": 0, "Ip6ReasmOKs": 0, "Ip6ReasmReqds": 0, "Ip6ReasmTimeout": 0, "Udp6IgnoredMulti": 0, "Udp6InCsumErrors": 0, "Udp6InDatagrams": 486201, "Udp6InErrors": 0, "Udp6NoPorts": 0, "Udp6OutDatagrams": 7273, "Udp6RcvbufErrors": 0, "Udp6SndbufErrors": 0, "UdpLite6InCsumErrors": 0, "UdpLite6InDatagrams": 0, "UdpLite6InErrors": 0, "UdpLite6NoPorts": 0, "UdpLite6OutDatagrams": 0, "UdpLite6RcvbufErrors": 0, "UdpLite6SndbufErrors": 0 } }, "interfaces_data": { "enp4s0": { "device": "enp4s0", "receive_bytes": "446377831179", "receive_compressed": "0", "receive_drop": "0", "receive_errors": "0", "receive_fifo": "0", "receive_frame": "0", "receive_multicast": "0", "receive_packets": "492136556", "transmit_bytes": "428200856331", "transmit_compressed": "0", "transmit_drop": "0", "transmit_errors": "0", "transmit_fifo": "0", "transmit_frame": "0", "transmit_multicast": "0", "transmit_packets": "499195545" }, "lo": { "device": "lo", "receive_bytes": "1210580426", "receive_compressed": "0", "receive_drop": "0", "receive_errors": "0", "receive_fifo": "0", "receive_frame": "0", "receive_multicast": "0", "receive_packets": "1049790", "transmit_bytes": "1210580426", "transmit_compressed": "0", "transmit_drop": "0", "transmit_errors": "0", "transmit_fifo": "0", "transmit_frame": "0", "transmit_multicast": "0", "transmit_packets": "1049790" }, "wlp3s0": { "device": "wlp3s0", "receive_bytes": "0", "receive_compressed": "0", "receive_drop": "0", "receive_errors": "0", "receive_fifo": "0", "receive_frame": "0", "receive_multicast": "0", "receive_packets": "0", "transmit_bytes": "0", "transmit_compressed": "0", "transmit_drop": "0", "transmit_errors": "0", "transmit_fifo": "0", "transmit_frame": "0", "transmit_multicast": "0", "transmit_packets": "0" } }, "todo": [ "inet", "inet6", "interfaces_data" ] } cfengine-3.24.2/tests/acceptance/00_basics/macros/0000755000000000000000000000000015010704253021632 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/macros/if_ignore.cf0000644000000000000000000000116715010704253024112 0ustar00rootroot00000000000000###################################################### # # Test that @if works for greater versions # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if minimum_version(300.600) Some new function here... more text... @endif } bundle agent check { methods: "" usebundle => dcs_passif_expected("cfengine", "", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/macros/if_eof_without_endif2.x.cf0000644000000000000000000000103615010704253026653 0ustar00rootroot00000000000000###################################################### # # Test that @if works # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { methods: "" usebundle => dcs_passif_expected("any", "", $(this.promise_filename)); } @if minimum_version(1.1) # just testing for EOF cfengine-3.24.2/tests/acceptance/00_basics/macros/if_feature_nested.x.cf0000644000000000000000000000170015010704253026063 0ustar00rootroot00000000000000###################################################### # # Test that nested @if with features fails # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if minimum_version(3.7) @if feature(xml) classes: "expected" expression => "any"; @endif @endif @if feature(xml) @if minimum_version(3.7) classes: "expected2" expression => "any"; @endif @endif @if minimum_version(300.700) classes: "not_expected" expression => "any"; @endif } bundle agent check { methods: "" usebundle => dcs_passif_expected("expected,expected2", "not_expected", $(this.promise_filename)); } @if minimum_version(300.600) This text should never be seen, it's completely ignored @endif cfengine-3.24.2/tests/acceptance/00_basics/macros/if_mismatched.x.cf0000644000000000000000000000172015010704253025206 0ustar00rootroot00000000000000###################################################### # # Test that @if works # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if minimum_version(3.7) @if minimum_version(3.6) classes: "expected" expression => "any"; @endif @endif @endif @endif @endif @if minimum_version(3.6) classes: "expected2" expression => "any"; @endif @if minimum_version(300.700) @if minimum_version(3.6) classes: "not_expected" expression => "any"; @endif @endif } bundle agent check { methods: "" usebundle => dcs_passif_expected("expected,expected2", "not_expected", $(this.promise_filename)); } @if minimum_version(300.600) This text should never be seen, it's completely ignored @endif cfengine-3.24.2/tests/acceptance/00_basics/macros/if_multiple_endif.x.cf0000644000000000000000000000160215010704253026067 0ustar00rootroot00000000000000###################################################### # # Test that @if works # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if minimum_version(3.7) classes: "expected" expression => "any"; @endif @endif @if minimum_version(3.6) classes: "expected2" expression => "any"; @endif @if minimum_version(300.700) classes: "not_expected" expression => "any"; @endif } bundle agent check { methods: "" usebundle => dcs_passif_expected("expected,expected2", "not_expected", $(this.promise_filename)); } @if minimum_version(300.600) This text should never be seen, it's completely ignored @endif cfengine-3.24.2/tests/acceptance/00_basics/macros/if_on_first_line.cf0000644000000000000000000000105415010704253025454 0ustar00rootroot00000000000000@if minimum_version(300.700) ###################################################### # # Test that @if works on the first line in a file # ##################################################### @endif body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { methods: "" usebundle => dcs_passif_expected("any", "", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/macros/if_triple.cf.sub.template0000644000000000000000000000163215010704253026525 0ustar00rootroot00000000000000###################################################### # # Test that @if works with patch level # ##################################################### body common control { bundlesequence => { check }; } bundle common test { @if minimum_version(3.7.100) classes: "expected" expression => "any"; @endif @if minimum_version({{vars.sys.cf_version_major}}.{{vars.sys.cf_version_minor}}.0) classes: "expected2" expression => "any"; @endif @if minimum_version(2.100.0) classes: "expected_2_100" expression => "any"; @endif @if minimum_version({{vars.sys.cf_version_major}}.{{vars.sys.cf_version_minor}}.300) classes: "not_expected" expression => "any"; @endif } bundle agent check { classes: "ok" expression => "expected.expected2.expected_2_100.!not_expected"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/macros/if_eof_without_endif.x.cf0000644000000000000000000000110315010704253026564 0ustar00rootroot00000000000000###################################################### # # Test that @if works # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { methods: "" usebundle => dcs_passif_expected("any", "", $(this.promise_filename)); } @if minimum_version(300.100) This text should never be seen, it's completely ignored cfengine-3.24.2/tests/acceptance/00_basics/macros/if.cf0000644000000000000000000001003115010704253022535 0ustar00rootroot00000000000000###################################################### # # Test that @if works # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if minimum_version(3) classes: "expected_3"; @else classes: "not_expected_3"; @endif @if minimum_version(3.7) classes: "expected_3_7"; @else classes: "not_expected_3_7"; @endif @if minimum_version(3.6) classes: "expected_3_6"; @else classes: "not_expected_3_6"; @endif @if minimum_version(2.100) classes: "expected_2_100"; @else classes: "not_xpected_2_100"; @endif @if minimum_version(300.700) classes: "not_expected_300_700"; @else classes: "expected_300_700"; @endif @if maximum_version(3.0) classes: "not_expected_3_0"; @else classes: "expected_3_0"; @endif @if maximum_version(4) classes: "expected_4"; @else classes: "not_expected_4"; @endif @if maximum_version(4.0.0) classes: "expected_4_0_0"; @else classes: "not_expected_4_0_0"; @endif @if between_versions(3.15.0, 4.0.0) classes: "expected_3_15_0_4_0_0"; @else classes: "not_expected_3_15_0_4_0_0"; @endif @if between_versions(3.11, 3.12) classes: "not_expected_3_11_3_12"; @else classes: "expected_3_11_3_12"; @endif @if before_version(4) classes: "expected_before_version_4"; @else classes: "not_expected_before_version_4"; @endif @if before_version(3) classes: "not_expected_before_version_3"; @else classes: "expected_before_version_3"; @endif @if at_version(3) classes: "expected_at_version_3"; @else classes: "not_expected_at_version_3"; @endif @if at_version(2) classes: "not_expected_at_version_2"; @else classes: "expected_at_version_2"; @endif @if after_version(2) classes: "expected_after_version_2"; @else classes: "not_expected_after_version_2"; @endif @if after_version(3) classes: "not_expected_after_version_3"; @else classes: "expected_after_version_3"; @endif } bundle agent check { vars: "expected_classes" slist => classesmatching("expected.*"); "not_expected_classes" slist => classesmatching("not_expected.*"); "expected_length" int => length("expected_classes"); "not_expected_length" int => length("not_expected_classes"); classes: "pass_expected" if => strcmp("$(expected_length)", "16"); "pass_not_expected" if => strcmp("$(not_expected_length)", "0"); "ok" and => { "pass_expected", "pass_not_expected" }; methods: ok:: "" usebundle => dcs_pass($(this.promise_filename)); reports: DEBUG:: "Expected classes: $(expected_classes)"; "Not expected classes: $(not_expected_classes)"; "Expected length: $(expected_length)"; "Not expected length: $(not_expected_length)"; DEBUG.pass_expected:: "pass_expected"; DEBUG.pass_not_expected:: "pass_not_expected"; } @if minimum_version(3.12) @else some invalid syntax here body {} {}{}{{}} @endif @if minimum_version(3) @else some invalid syntax here body {} {}{}{{}} @endif @if minimum_version(300.600) This text should never be seen, it's completely ignored @endif @if minimum_version(300.600) Nor should this @endif @if minimum_version(300.600) Nor this Not this either @endif @if minimum_version(300.600) Nothing should be seen here really Who knows, perhaps this text doesn't exist..? @endif @if maximum_version(3.6.0) body files control { {} } @endif @if between_versions(2.0, 3.0) more invalid syntax body body body body {{}};;:: @endif @if between_versions(1, 3.6) more invalid syntax body body body body {{}};;:: @endif @if at_version(2) body invalid syntax {{{reports:}}};;;::: @endif @if before_version(3) body invalid syntax {{{reports:}}};;;::: @endif @if after_version(3) body invalid syntax {{{reports:}}};;;::: @endif cfengine-3.24.2/tests/acceptance/00_basics/macros/if_ignore_with_addsign.cf0000644000000000000000000000125715010704253026636 0ustar00rootroot00000000000000###################################################### # # Test that @if works for greater versions # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if minimum_version(300.600) Some new function here... @should_pass bundle agent netgroup(@netgroup_list) more text... @endif } bundle agent check { methods: "" usebundle => dcs_passif_expected("cfengine", "", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/macros/if_feature.cf0000644000000000000000000000245615010704253024264 0ustar00rootroot00000000000000###################################################### # # Test that @if feature() works # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if feature(xml) classes: "xml" expression => "any"; @endif @if feature(yaml) classes: "yaml" expression => "any"; @endif @if feature(unknown_123) classes: "not_expected" expression => "any"; @endif } bundle agent check { vars: !feature_yaml.!feature_xml:: "result" string => ""; feature_yaml.!feature_xml:: "result" string => "yaml"; !feature_yaml.feature_xml:: "result" string => "xml"; feature_yaml.feature_xml:: "result" string => "yaml,xml"; methods: "" usebundle => dcs_passif_expected("$(result)", "not_expected", $(this.promise_filename)); } @if feature(ABCD) This text should never be seen, it's completely ignored @endif @if feature(ABCD) Nor should this @endif @if feature(ABCD) Nor this Not this either @endif @if feature(ABCD) Nothing should be seen here really Who knows, perhaps this text doesn't exist..? @endif cfengine-3.24.2/tests/acceptance/00_basics/macros/if_triple.cf0000644000000000000000000000272215010704253024124 0ustar00rootroot00000000000000###################################################### # # Test that @if works with patch level ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { files: "$(G.testdir)$(const.dirsep)test.cf" create => "true", edit_template => "$(this.promise_filename).sub.template", template_method => "mustache"; } bundle agent test { meta: "test_skip_needs_work" string => "windows"; } bundle agent check { methods: # Note: dcs_passif_output expects first argument to be regexp. # To convert Windows-style path (with backslashes) to a regex which will match this path, # we need to convert all backslashes to double-backslashes. # In the command below, each backslash is escaped twice: # once for regex, and once for CFEngine string parser. "check" usebundle => dcs_passif_output(regex_replace(".*$(G.testdir)$(const.dirsep)test.cf Pass.*", "\\\\", "\\\\\\\\", "g"), ".*FAIL.*", "$(sys.cf_agent) -D AUTO -Kf $(G.testdir)$(const.dirsep)test.cf", $(this.promise_filename)); } @if minimum_version(300.600.0) This text should never be seen, it's completely ignored @endif cfengine-3.24.2/tests/acceptance/00_basics/macros/if_nested.x.cf0000644000000000000000000000164215010704253024355 0ustar00rootroot00000000000000###################################################### # # Test that nested @if fails # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { @if minimum_version(3.7) @if minimum_version(3.6) classes: "expected" expression => "any"; @endif @endif @if minimum_version(3.6) classes: "expected2" expression => "any"; @endif @if minimum_version(300.700) classes: "not_expected" expression => "any"; @endif } bundle agent check { methods: "" usebundle => dcs_passif_expected("expected,expected2", "not_expected", $(this.promise_filename)); } @if minimum_version(300.600) This text should never be seen, it's completely ignored @endif cfengine-3.24.2/tests/acceptance/00_basics/validation/0000755000000000000000000000000015010704253022500 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/validation/validation_tagging_directory.cf0000644000000000000000000002264415010704253030740 0ustar00rootroot00000000000000# Test that cf-promises -T tags a directory correctly body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { meta: "test_skip_needs_work" string => "windows"; vars: "options" string => ifelse("verbose_mode", " -v ", ""); "dirs" slist => { $(G.testdir), $(sys.masterdir), $(sys.inputdir) }; "hubfile" slist => { "$(sys.workdir)/policy_server.dat", "$(sys.workdir)/state/am_policy_hub" }; methods: "rm hub" usebundle => dcs_fini($(hubfile)); "run" usebundle => test_dorun("testdir", $(G.testdir), "$(sys.cf_promises) -T $(G.testdir) $(options)"); "run" usebundle => test_dorun("inputdir", $(sys.inputdir), "$(sys.cf_agent) -K $(options)"); # make this machine a hub "mk hub" usebundle => file_make($(hubfile), "$(sys.host)"); "run" usebundle => test_dorun("masterdir", $(sys.masterdir), "$(sys.cf_agent) -K $(options)"); } bundle agent test_dorun(name, dir, tagopt) { vars: "simulated_validated_ok" string => ' { "timestamp": 1234, } '; "simulated_validated_bad" string => ' { "timestamp": 1234, } '; methods: vars: "masters" slist => { "promises.cf", "x.cf", "y.cf" }; methods: "rsync" usebundle => dir_sync("$(this.promise_dirname)/testdir", $(dir)); "master2cf" usebundle => file_copy("$(dir)/$(masters).master", "$(dir)/$(masters)"); "make ignored file 1" usebundle => file_make("$(dir)/ignoreme", "fnord $(sys.date)"); "make ignored file 2" usebundle => file_make("$(dir)/ignoredir/2", "fnord $(sys.date)"); "tag1" usebundle => test_tag("1", $(name), $(tagopt), "make new cf_promises_validated and cf_promises_release_id in $(dir)"); "read1" usebundle => test_read("1", $(name), $(dir)); "rm r_id" usebundle => dcs_fini($(test_read.rf)); "tag2" usebundle => test_tag("2", $(name), $(tagopt), "recreate cf_promises_release_id even if cf_promises_validated is OK"); "read2" usebundle => test_read("2", $(name), $(dir)); "make good validated file" usebundle => file_make("$(dir)/cf_promises_validated", $(simulated_validated_ok)); "tag3" usebundle => test_tag("3", $(name), $(tagopt), "rewrite good cf_promises_validated and leave cf_promises_release_id alone"); "read3" usebundle => test_read("3", $(name), $(dir)); "make bad validated file" usebundle => file_make("$(dir)/cf_promises_validated", $(simulated_validated_bad)); "tag4" usebundle => test_tag("4", $(name), $(tagopt), "overwrite bad cf_promises_validated"); "read4" usebundle => test_read("4", $(name), $(dir)); reports: "$(this.bundle): $(name) $(dir) '$(tagopt)'"; } bundle agent test_tag(vary, topname, tagopt, desc) { vars: "uid" string => "$(topname)_$(vary)"; classes: "tagged_$(uid)" expression => returnszero("$(tagopt) -D$(uid)", "noshell"), scope => "namespace"; reports: "Case $(uid): $(desc)"; DEBUG:: "Case $(uid): failed to $(tagopt)" if => "!tagged_$(uid)"; "Case $(uid): tagged $(tagopt)" if => "tagged_$(uid)"; } bundle agent test_read(suffix, topname, dir) { vars: "vf" string => "$(dir)/cf_promises_validated"; "rf" string => "$(dir)/cf_promises_release_id"; "uid" string => "$(topname)_$(suffix)"; "v_$(uid)" data => readjson($(vf), 4k), if => "have_vf_$(uid)"; "v_$(uid)_str" string => format("%S", "v_$(uid)"), handle => "v_$(uid)_str", if => "have_vf_$(uid)"; "r_$(uid)" data => readjson($(rf), 4k), if => "have_rf_$(uid)"; "r_$(uid)_str" string => format("%S", "r_$(uid)"), handle => "r_$(uid)_str", if => "have_rf_$(uid)"; classes: "have_vf_$(uid)" expression => fileexists($(vf)), scope => "namespace"; "have_rf_$(uid)" expression => fileexists($(rf)), scope => "namespace"; reports: DEBUG:: "Case $(uid): $(vf) = $(v_$(uid)_str)" depends_on => { "v_$(uid)_str" }, if => "have_vf_$(uid)"; "Case $(uid): Missing validation file $(vf)" if => "!have_vf_$(uid)"; "Case $(uid): $(rf) = $(r_$(uid)_str)" depends_on => { "r_$(uid)_str" }, if => "have_rf_$(uid)"; "Case $(uid): Missing release ID file $(rf)" if => "!have_rf_$(uid)"; } bundle agent check { vars: "expected_checksum" string => "4b974a13b5473cfbf60edfb66b201a364d38960f"; "tops" slist => { "testdir", "masterdir", "inputdir" }; "tests" slist => { "1", "2", "3", "4" }; classes: # exceptions # the release ID is not recreated in a normal agent run if the # promises validated file is OK, even on the hub "correct_release_masterdir_2" expression => "any"; # the release ID is not generated when running on a non-hub "correct_release_inputdir_$(tests)" expression => "any"; # normal testing "correct_timestamp_$(tops)_1" expression => "any"; "correct_release_$(tops)_1" expression => strcmp("$(test_read.r_$(tops)_1[releaseId])", $(expected_checksum)); "correct_timestamp_$(tops)_2" expression => "any"; "correct_release_$(tops)_2" expression => strcmp("$(test_read.r_$(tops)_2[releaseId])", $(expected_checksum)); # we expect the bad timestamp "correct_timestamp_inputdir_3" expression => strcmp("$(test_read.v_inputdir_3[timestamp])", "1234"); # anything except the bad timestamp is OK "correct_timestamp_masterdir_3" not => strcmp("$(test_read.v_masterdir_3[timestamp])", "1234"); "correct_timestamp_testdir_3" not => strcmp("$(test_read.v_testdir_3[timestamp])", "1234"); "correct_release_$(tops)_3" expression => strcmp("$(test_read.r_$(tops)_3[releaseId])", $(expected_checksum)); # we expect the bad timestamp "correct_timestamp_inputdir_4" expression => strcmp("$(test_read.v_inputdir_4[timestamp])", "1234"); # anything except the bad timestamp is OK "correct_timestamp_masterdir_4" not => strcmp("$(test_read.v_masterdir_4[timestamp])", "1234"); "correct_timestamp_testdir_4" not => strcmp("$(test_read.v_testdir_4[timestamp])", "1234"); "correct_release_$(tops)_4" expression => strcmp("$(test_read.r_$(tops)_4[releaseId])", $(expected_checksum)); "ok" and => { "tagged_testdir_1", "correct_timestamp_testdir_1", "correct_release_testdir_1", "tagged_testdir_2", "correct_timestamp_testdir_2", "correct_release_testdir_2", "tagged_testdir_3", "correct_timestamp_testdir_3", "correct_release_testdir_3", "tagged_testdir_4", "correct_timestamp_testdir_4", "correct_release_testdir_4", "tagged_masterdir_1", "correct_timestamp_masterdir_1", "correct_release_masterdir_1", "tagged_masterdir_2", "correct_timestamp_masterdir_2", "correct_release_masterdir_2", "tagged_masterdir_3", "correct_timestamp_masterdir_3", "correct_release_masterdir_3", "tagged_masterdir_4", "correct_timestamp_masterdir_4", "correct_release_masterdir_4", "tagged_inputdir_1", "correct_timestamp_inputdir_1", "correct_release_inputdir_1", "tagged_inputdir_2", "correct_timestamp_inputdir_2", "correct_release_inputdir_2", "tagged_inputdir_3", "correct_timestamp_inputdir_3", "correct_release_inputdir_3", "tagged_inputdir_4", "correct_timestamp_inputdir_4", "correct_release_inputdir_4", }; reports: DEBUG:: "Case $(tops)_$(tests): the timestamp was correct or ignored" if => "correct_timestamp_$(tops)_$(tests)"; "Case $(tops)_$(tests): the timestamp was incorrect, actual $(test_read.v_$(tops)_$(tests)[timestamp])" if => "!correct_timestamp_$(tops)_$(tests)"; "Case $(tops)_$(tests): the release ID was correct ($(expected_checksum)) or ignored" if => "correct_release_$(tops)_$(tests)"; "Case $(tops)_$(tests): the release ID was incorrect, expected $(expected_checksum) vs. actual $(test_read.r_$(tops)_$(tests)[releaseId])" if => "!correct_release_$(tops)_$(tests)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/0000755000000000000000000000000015010704253024156 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/promises.dat0000644000000000000000000000013615010704253026511 0ustar00rootroot00000000000000body common control { inputs => { "x.cf", "y.cf" }; bundlesequence => { x, y }; } cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/x.cf.master0000644000000000000000000000007115010704253026227 0ustar00rootroot00000000000000bundle agent x { reports: "$(this.bundle): x"; } cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/.gitattributes0000644000000000000000000000001115010704253027041 0ustar00rootroot00000000000000* eol=lf cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/promises.txt0000644000000000000000000000013615010704253026560 0ustar00rootroot00000000000000body common control { inputs => { "x.cf", "y.cf" }; bundlesequence => { x, y }; } cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/promises.cf.master0000644000000000000000000000013615010704253027623 0ustar00rootroot00000000000000body common control { inputs => { "x.cf", "y.cf" }; bundlesequence => { x, y }; } cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/promises.conf0000644000000000000000000000013615010704253026666 0ustar00rootroot00000000000000body common control { inputs => { "x.cf", "y.cf" }; bundlesequence => { x, y }; } cfengine-3.24.2/tests/acceptance/00_basics/validation/testdir/y.cf.master0000644000000000000000000000007115010704253026230 0ustar00rootroot00000000000000bundle agent y { reports: "$(this.bundle): y"; } cfengine-3.24.2/tests/acceptance/00_basics/CFE-1886.cf0000644000000000000000000005016515010704253021670 0ustar00rootroot00000000000000###################################################### # # Test that we don't error parsing long lines # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-1886" } string => "Test that we don't error because of long lines in policy."; } bundle agent check { reports: "$(this.promise_filename) Pass"; #"IP16lvcMb19Rg2BNQW1USktx7RzBZbyyGsZCgixY5TL0ynV4u0Cm1xKfta8n3ZQgovDEoPJp6FpbVhnhkJB4ILV3ubrnIKCKUlan7Msg4EN2o2qA6tYRDIBjQtlhXUqpnYznHHuvWeIVXhHTBo8uVoZEiWJuQkscjr74tOBcEhfXBMOc7dGNqsWjZIVV7hSwWWIb27DitY69KIYHGp9EsRS9ZIrL0xF48HMeFL83vZGnbm41PwQSzjLSZDd7CqmyERVfE0rQsneVjtSjZiQngMIRejfvWeWMU8aVjJeyIEg0YSYQAxBbxDxi4o537QbH8sDxArS0RL9Un69Ki3bvwtX3BA8piOIOwF6PZmEIeaydUP1I2w1PswQXdmb3wWIRrQhTqq46W0ZrfYsLKcT6UbWi8IAuxBVodrMxuoEM9KtUYzwbYHa1WwTEhs5GXgo8Jq47cuwleboqUOc8wjhOIb5ZL5DWfI65kJavC8gWXN3FAM3e7UhMUYolhXN9zxkYczfUiJEUUz3W7KJkB4bSBmZtUyL15cdO9efBsPXG4WqqCgWTZ6DUHIBKIu0SfBKIj9Vm6qffMK6eYN1RCmiHsEvbqSnAobZGGdby1amoyPC9crw8ocANLOm8gg1FGlmsEwaKvF3BH6AMQUr7d2YGfOc2BouiFW31nh1qizqHt0qcVOAUtQU83bLecp78GvNqW7HlaqT79gUk5dNQu6iUsMIkJi2DsvxTrS6D5NScwtvi48arYtLledM0iAuKLfJnG4mCEz9L2s7V40KlcvfQkfk1hYkzdYytjdXi1kx903k8R2rXQjpzdm1JwaAlQGaYIUdTjEcHw7unVPPwpQsoLErSVcgiw86KAPIi6KNzSBDfFSzl9Fi4mvucJF7ahkFxrII7HizOpM6h47cSopjfglw07e3hFacMbh2f7CMS3JBokYSLVHb2TDUL86FMbvfiFOWrTcdlSZJ9oWbzNQ3YY43Gx4YYXSFGQ8MZnMgV6Y2zubKVncbSWu9OPEKdwQ6D51g5086uCh5gxe20sSKGuHDjCBSks6KeBUix0J0dIvJGHGeNBSAxkYK3xgvo5OKDs9aWp367sxTM2YjCvCeaGIW3jM2fsVP7TPYNGCMu3zH3AUnOC8NfjXtS3a9kW1FjkO60OT05yMDgoFT4Xxou7Wn449YxEd6V2I6kdVCkngvHBxcboykuU1rIdONqKP1OifHngU1JXK5cRP4TwB7nmZ5PiB44MpaOL21JCkAUwh0sydaAEeFpGFDgSZjWwNaVYlUjquLV8YoyvZPnNAbWoH3sZrJuT0gqtPLpFVQ637K5XGrs0ezW58YeuN2JvxCrLzG6w1sc9sGeY6ITOVUKZw2KiPPdvj9p5QSFjtxkhzyuWQkhcBkURY6O2pv59ssG4LHrwM9z0hMoWkHQa4u9HxySJiJh6z5p7QIJQAiQ4ytn43p0BpJCiiWtmvy1CvD5tcDPvlASVywdENF1WqR0ycJWGIkw08HmLXPuBHsSl1mYLeJymTBMfbMfVxcrCuH0ETzTtE2HALpgwAfnjMd6g1Tq7rXPGIDaeHjOFoIzauNy098bChJuZQW53EE0EtxHeJNlr9rJMBHWcKBOILF6tBOgwAMa4pYNSQvTQC2JotKOnui6W9DztOrsmYF8WPuIdFq8AQSf0uT1Um90uFsW6aVLBTACbrp2Dt0ekmX8eVdIDSjXpeJHRLhtpz85kuoV5Tc3YHlBL8sjqBkcE22MEQCddjJz687RfV9punkS6ObuPeD7D86ifFBxLPjQUs9Q4LdB2j6PV2W4Rz2hAN7wVz2F76vmFQ2Ge5HT4JQI2MLSMIXIMuAe5ehnXQjsdSj90lSlos5ekR2sLyIExl8kTTFwfGMKt4bq1gEMsFqxPGscgm0k8mKNiWEnZMDrnbyTOsYmAUBHeoin19igAl5wqkctlpNVXPGVqTKl83qiipuPNkOvtEx4glLfeObkRWm8JqdG8zLI5glS3FKXbZrXieBGPw8gW2hJ9QasSpsrkCi9X4hPW83qMP31I7ypu6ZYASNrQc99RP4GURD7TyPEFKUzyjVYqjuyt8qNy6jCq4O2wogIhPaGpChuBsnTOErLlBpbfs8hNnXdxY46Mt6MjZtiwDWcQ0iwuO9xYmMuxv2MYfTIphAFaIdRMtS7NPUy2AIUNwlnWZVrYQY5BiKUdLpo1br6hjEWdqeBWduRCLJZS1OG2i8OwXrIONLox0T8gtPin1slEmcGEapOnxd6Ho1v09mA6fU7ChmPigxjICly7pmbaA6uJb1Hv5vyr7wHGBqWhfx8STJpoPfMjdB5GKwg4SOciLBFMGtuq7GC7sCBkV5XyWBTHgZahZdJZtS18aw6bLmW87s2nxqCgcdFRnVy9t7aOrlFWgHRzRDSEMp17N1MTySg3nBvTOAQBbMaKl7MhkTKKhqJk4t2HpBWO4RCqZtvFrw5ebuCguemSnH3oJ6Hvwsp1uqwfCTsq3Q1zIxJmEszNsZI7oeWXAUwRWwAKt3jagSMNgWiER1CzJBs8UwJXUrqQrk28FIPxvonXPsWaYslf3xtKuIPQ6xK6byote1JHuNs7d2n7Xaa0AhsokR07aM6LqUocSyuLTJ5PipXfwbhFDZ3tTBawUV2sY17e9qEqXDDmT2Yvu3Qe6kuwQ7Go0WsolEND4RJGrpWGJrKKgPAfVsmKboyd8ppCHLBB2PFvQ6uBYqtR9PUtXivYJ8cTzK8uYCoDqNhqJmUtKT8aKvdyBo3cOeNn55MHDIT83zKIB8JudLWdVy2jWqX6p5NxwOetqIvGK3pZrwuFvH6G37sZnhvDwhg8dcXzaI3s2mLaNeb3bwE16BLOpDzVunv4BrmZpbOlOSoAUtkwWboCLbCf9Xxd6ck4slHmOpouFDuDSjU1j38a2OEHxgas02wI5SgagxHfOaUIZvbxQCxuEEWEdQNi46b8K2P6XPt2BwpIAQL16ufy8PgkZQkeMZqyxqcjTr8tNMH2k7u9hq3uksOVP7B8T7IArs9GjeKVEmFABZOdy6Ems400oI7siewhW7Mt1yZX0YAjzKv1h0ybgAFAy2gLdasDQA3zWCjoScqXhfCbdyO4w1EVjb00LYRLRzcKzjj0ekOkATfmeZ30FwhFWCwgEadceC7t5X4noYQ1GTvimc1ZHPWTMZPE7JgQ0IL6W0TINhwWnKTplUmAClyr0AwSwMyyxH2i34OXehGdPdOfae71kqgCGNkcu80boPzGbInrWJ8Zlz0J0z0bss6okRGX3SvVImRwRC7oXfKsWQEVeoF8o7hS3UaSFSsQ70hpXTHGInQ8EI9c6mJZWNi5MA7ArBZydkOqQXI6iGPTDoNNx3wzd8nCAEThiYV4iLpNIqSUlG1pAO71siIPsSkZ8WTq0scMKkF0WhGDo7Lxk4b29CAwKOyp3pGlh7xWAZryeWvfbECWEkMSqfEgYBfkGFMQlUjWumOzMLEZZICwBxtaPhuepasEQmuPTOfB4Hr106aMAFasPjozsYwTcxYUqvew0Ddpt8DGTlyTtnrY0jsF6NkubSVV4hAQFJpBvO4KAlrUWCSrRcQOY3mJXMFWg6E5ckzjrIf9smIn3XpW3IABA96vRT22Bs9FYbEvAX4xlOPjCbU28oHySMcr0iCjGH1Vq0fX6lF0aej2nGcPwvFzmgqy65Glvcnff8mBNui5gSWfxUk6SdheBhqMVKmsq2ZshTK8dUuMzibEQsvAKAuRCGAOzjGNUozTmfOWZ2Ucz6Fp6yXUFbPDBGUAXR9htYSJShCG7hvcudvjJduBvc7AcxDJclrudYUfsOYMBfUWIG9puwDdySbzWu5HIRdV7MnBmPgJ5FLD2ix6UMHYq4yof3nKTplJcCJXtoRVg7JFSkykRUTazEVS4znZcTfneCIfsoN5Sx8YROztsPqtdBqnJlYVOTZYg4jW13f5BnTHzUqDC6pTrjcfuaR9sPf9c0NdAufhPQtgGh4eeflZUbbVWxZFbul6Xm8NtWOhrd5cxh2KhHSn6kzJAyVuxiOVHef7wcpZRdIzMdXXklvu0qvjjWS2KqOhdAxhhIqDSqwnh77w16KFT8Eva2vINUb1qp5qzKNWBGNS7TcvBcgkffcSH5PbnZYh1FOAouOptljDyLJu8YvJeUmue4jvy8kG8W2kesk3nUPjaKS7upfbLzYARtVCsMuuhJauSHvOZqpaVp8DMS3IaoIIMjiRdaQIHmtPvblOQkSnztKehsKkR3oUFUHlRI2HsE9lr5Usbta0NmYrT00wtR2AzzChCNi7QfzwhVvNlmZj6fiAY8pdVdYSPkqAoMG8v5yex6davoexsnVvgEs8hQW6tfxm6rOukcPdoZtMCS9s2Ft8xkg4VxVA2hs5u84vvzgl1vvjaaylwh1iyx04uxAiSiGRaqz6e7knDsmyVnHRxlsUh6OEzi3JQtmM8GR9xnT5DaBNODcWHQVBhI1vVarNsf5f88lMaY7EIZldODkWOKwf94sEOrqdY0gw7EA2Nth01d3j6D0o6Pe3RGptn5BpQbOYLDLL4CMZYQRfOqbs5RaI7WBGWtgmd3ZOAD3reSXVGwx8fgi7HfWEs8hjByFu3hclJszsmQGhUAZ92qlSeEh3K7BdDkuRoXAI4KZZbMw4PEHpQ5tVQ1hk6QIAyXmLSUH3wpcBfBXsM3aAHckQefP5zeOANQ1qE40y5eSqIZ8hzmEjNULwEhQddPIqvK8TTVwDhLghoN9UHIfUbPMgcYknQXzLqz6gK2LSWZXcr6TTV3QqxsOdCdKoW3dc33qmSJJLSGzPIiEjEjqQ67gNmAt2yCUYu8Tne0jxWOzyW8qtuF1LabTrnCcnGOGirs87JgvgOQNzY5HJKFKSUJcmDgLNxycdP8D0kCQeS7q0HvCM9sgLgx3fiEGxUPMXXqyPm7QVldAfm8LSrCjyJWWDb5gKSmOyHs98Bp2iwUwil1zh5FxAzIbm5Ev17O6XBVlPPvc6pIVZyNpcr4QsiDMERS7r56JWWNKwEF3PFHJ2Y6yoqPpohp8WiW3nZKta7FZDwE1iaR7DFY8vFxzCZhtMVL8oOQBPfxXvKwa2fN5S0tN7q22jAGsKOECJkQn3VZeQLGwHaXjIZ0r6XeA39BfZQiUSj5c9VFoBeROCohbwzH0CDda8g7WhieD68wxw7zFc3f5W6jFxyCBW8Z8vVxE9THtIFgwqrHMsohJhD1cu61hR5Qg2Th2GgAHfAcEDfMToilhxKKVyZwbg9lGyJzLaweeSD2e2K7nROabKh2D36iO0N3hWEvsfhvTrFO2UClLzfagEDUUDSZlqJeB60S9QPSXgSY40aYe78ZBff3nLHXvF8aUpgxwMDrU3zkSa2luYCVcgMEPGcP4JO1tbfobHlmSvTlodTFN5kuAvur6p46zK6r9Vg98poNN325sX66jHKHFrdu435MWoC6ac4GZ6AbqddUwLuBxMloXL33ig6WQOshXrHdB1RQzlExWzQJy58U9EVgZOyNrac2pUcG2rzgD98W4MbXmlPeYxH8a0drts1FET2WfQCEctgnud97qnEr57KM0L7SRw2wS1RArQd3nkuyMlXVCMRj82c8J3g31cSvBvvO3GKtSNc6WGYJxorRrOeMz5HgqmVxTbub6yBiRdenzVeHe1KGWd6wX297glKWfVy3i1C2xd72BpXep0prCiKps7XaZAf9yWUi3VwTTTpDQSN4DlswMI6LgYdiKMLBRdWrSbKvG0MKVZldNZnxmehPRRnZNh5lDf8Vx53DcfESCVQV6ad6Kk62l8SDQtNBgK4qFz8faq3h45FbDzWcBQT5PI98LWyAul4kKma8lTlDrFsqPPSLrsCY6qltFJlPZn26GXwvQWi3NthmOL2cUrMPlkS52AKNFGy6VNl8eZacEoU9fgH5bRQAcwJnpe59nvCdueBpJOwVtwRnCo35dZJxqhRn9MbWN4Mk6Rv2CCWjU6JCpSUWjfC176N3kcVDqPWMOM63s1ckgAOFbbKTTQU71elkfrvh8Depa3bGfXe1NrcOnN68hL9jFGwtzl1O5KwxBeO8dY2KPwRGmvWM251ecrVLUEd2PruzKOgycfclvaaU5PXxSoHtYqm6Rl2o27XDijIgEOgXM5v18QepNKej3cd3WdWvxwa3ezkbRayx0iDbeBBh9wLVydb7hG43gBteAWfLDK4sXobszdrRH5YDp2O8YjpSllvuHyIkv6NF9G83PkWsQ3EMHSP5sPrngT9cZ1NMeMkLZyX8NQm3esqPpY1h9zQMCxZnd0BTzCzShFd40z3jjSQfuSgcgowlkmueysZJSoTFObhoDGR96XTxFIyTSPTI9d86ojIzAGZnD6mkwYiN22DjEcGLNWvtpwnYAfUwB7x2Pi1rC1yKTjYSD0Risley6r0DcYbTITPtRH4lxzuMriCt2ZLlqYcHSI7w9CkDd8Jsmm30sOpKIg7euVfhuMHbAoS9JqaNIwZoOVSInlMFUPVlrFZselcxuUQkmyedz3EgtPEYnMJpr9mBeHanxjFxVcxkAOwxa1Ra5c0TINUlm8QANMRvq6yleZcyBdmsDmjJeEEzvtg27mIO3EcZgg2nrRqumZzyFrpClO3PmyQmIUfS3dXamGmNoY00PT8RpN2cAN7Hl5XpHS1JOSY3JHTaQ1I8fUqFlJpAYcWhP9zMcCFdRUD0AvmJx3iFyjEmLOAl9npbcqqiVTc1aTPfF52WAtFMqByUU98L9FNhTKmVbvsgJe4XNsQKju1w6ExLz1FSfAoSN5eFOno4UNTkaCJXfua15LIwiVKf1WNj0YHgL1TVHeU3750D5YX7GvVrInvTaFgCNVFkhKi4HyhBg0EthXoH49Q1FRhfZ3VgFt1xdtc762lPTMWtmDRmO5LwiATPhjKCFJjD1jEexxavorT0YiAVd833R8PrLpB7KKcvgCsf1fx8mOUZr0qKCdL7TMWCCIdlmFKMREZ41hIqdZkN8j4RzfAVvatxFpz5VCNY94SafJsw8M9xxViE1BGWbJ8BNqL5EYsFP0PM37J82BPSIFdmCtQI6M8yljDtZ3kf7aUADZiIMGjH5lP6BwQ3GLPxhcOe1Bf5BzX1wtbGa98OgnqI73diYK0yXcobC67YoEvqs6So9gbrWqc24WyTfDgCdAebUXb98VQuwhfGBNEDsPbPZDKique0lnI3j55pIgttlSTiNnvbQXRt4db5PU2pSOVdCnS6cE56H66R8vAPAjPTUwGsDmD8HFyi9sj8iQGzrxmduCfZ31k7Mgo7a4ln12biI2og5voU44sgrHxRCDcb1XmRhAympcItfQtjgDi8UggaBMYy3T5MF75kLzskeyEGb4Xd81wKoMSi8VmR8eFMwXOqhYSpmjrdf4gq9fLXlzWQi8RDcMqo2vxuCb3A1v1xn8Ksjl3CG9O3T6n1SK2kxf2k0pE4FHsLKqr441hHThLpIRwblFzOxovjCwaRwZEJzkHhHzwX5jljTvhEh0bjsBRnSoCvcMECoqn6waoLICRh4RTeO0NcyFLXlb2PXCR1rw1xs5srCkIjQqa4NnARsMgePn2d6LA9LG8b4ujFmPI4TqKqKtxb4EATL8QdD9DP1qUM7UMxwUtqC2uJl0zbkfcZaHUVMANsRzxVxT01qH6d3YWvbxfBHlX5WrYfQyveanS3dEJ4BN8PcdkCjFty0LCg7DMdl2HPEzT4eQNka8eAiyah4bkytvvigBxyW1AvHmSXIw8Z3PP981FP6nb3Tdp2pElK82wnNjQB4ea2HSzIgSe8fHoObnqwlPruvXsEkstYWElFeARgVFn0YgeycgIgbJtLGj3LABDMs9SplWoPv8CUS7oxgffpKQ0S5nO0w1Ymch6wTsEF5sCZL0cOF3KlmSYlgfArlZ1oGDLUl22DVPMuK0aBeSePEEmHfN8sS4oW5ggJdnYz2mhTu1dsB7UFFTWl4aNaBg4bfCger2strh1tPOrzzyhn6KXsUuFMc3zIzgcONilYT52A0caGKpDcPImhavV3NMSR7zLCBTzD00lGw4k9zY8yFlcJVmMfxiRrNXms9Zd90ZZPLxDvJIS3N8M19k3fddM1WDvaguZtBTTXi0hVz9aYUTeeAg151qOH5tXfDMqNqZMTk4KzStjst6Ilrv6GKpv3ynEbksWWD0dAYFLcwWjCJhzu7SXD22egw6hPPj2fennW2SfUDKPumc39biIdAUrkZ3LnYfAmePFXWItj14kh6KGRaEjXl6iWeIHau6rcoYRb9Z5L5MmRbicSEJsrUg9UifFobqKUHHv7WaP8ihg9yinwu9lTvJATiGdSbHis2uhVVYbsd9OBNA32yzMv76CfE9rBxxHgdSQkz0nNRTZJZKyTOq8K8DWoxWLUJOAQYKIcJqwd20VOho1JWsrCS45ecLDzAqP8LTQQs9ffgQW2wIeE1pTK2haOVUM1KxseDaD7xGgaPTluK1Tox84rtX77XBWXLYpYfiSFmZ28tqhJLyubgJwRh2QgLVtc2gZJhgQG7b1koPbvL2TYyCaH4oXU8kKKmo7m4jVFPaxz6LM6rgcD7heGAZykw2hleI8Q8eGn6gF2umX1RkRs7z4WmfaLijQsUefqOotHDSxOgMC4OqebTaqPJHbfwDuL2k8cyuOUNNdM5BR2UolCShqtssPNHAIXuKLlQZ35CEgzOdaliQcjH5leW6eQDKlAQAOMDsVe5u4LyaRyE9XyStjYENBLWBKNeHkgKJVK5Bez3FY91zueOFOQA5C0uQBVDRQoJEwSr8rywo8JqypxEc7WKfGMYluXbKIOd2CpHpI9u9zzqDQiNyWZiqgBn0znlm0H0ADLag8PX69Sndw3X6cghUDgm6UNbX1EczhFPzSxuTqKNrE8tYf0sflTIg3L9YGgktj2OjVE38suwmSmGju8a8v2hOuO5g5PgXquGPx25owEC90CcxYlrudSVSTxC1iyopBduh48ZNqdkOPkU6oCs1Mkk5VrwsfL0nrG4CoqKyFJYqlnJooJnsZlR9dQ9DwUhOZZXnbSTWuVoLSBTqzfyE8eQ86YdZofIS1on8YoOPrLtHZxdroULBhB1ZsryypL2qsTEQSMbr2EPR1Xk0qkFJ0GwPfbqCPBlbdOUc3usFjnHHKvsI7dZPGMQQ4zSZ2NCFuVxz0VnUYPajyNwWqTxtvVRB6waUIopH45NntyFBuB2woRiatB2MrDZGrlXFqjKiB1WT0XtqBZlvALfus8KTICMNvS66RD032hh0wJUAKPpYaMRqqoeWyHWpsAEXm5E1bMeDCcpjWVd1camrrS4RhUe0Zfv4kfwQQsiLjhiZLuxJ5IFgI6okGD6wXxE7sHBYId17WAJEVtUzGLjBsPfAd5dids6hsd6mQSiMuequwQY69rVqoWu7hIVxsTXdDyA9vjCtGVXoSTFeybz2VsS1CgID8sqcwOg152AOcjUw221slXQnRb8m4CuWdodrpxDaXDDIUt6i2Rq2PGmpqkXWEijc528Vc8XTvPTnDSVwVFRFqnOJtZq4nS5LxY72cuF4vNZPkP1QjZwwOzqMBJ90qOCGldYqPzw0gxXqqR74drZAdGjFxB4pQHp1sZYryRva7chyMcARs45qowRt246N3RKHQkY2QQim4SmSkiRUTtO16FpcSNyAaQU9kdCo6e6nDwhvORDSKZzq0LNsFbbqqCTPYVEvCUkqrCEnxajenGazy0L7NaoM9lNJxaO8m19iJEaEQbseVSml9Ni3vAkS4PKEuz2DYL7IXgRHZ1ejucxrSIvkmwNrTHsQFYUhAfRagZPoHUt22q6CNIv8iYPPT0j4cfy3jkR9MUiOqs0v83Zj29bEwXZUzhzFrozrkKPJrMxHksr8NvTPcDn4JC4s5WJgIG4rxofeofRBLKryZ1sZk5izFobtBGYLiqMtnYsKJnxnvNEk0Yhb4N6RmqC0mpYPXis3PDOWwh8j0IE4z3hCjvO3u1IxV8n8kLht0TOEjfnZyNpcr4QsiDMERS7r56JWWNKwEF3PFHJ2Y6yoqPpohp8WiW3nZKta7FZDwE1iaR7DFY8vFxzCZhtMVL8oOQBPfxXvKwa2fN5S0tN7q22jAGsKOECJkQn3VZeQLGwHaXjIZ0r6XeA39BfZQiUSj5c9VFoBeROCohbwzH0CDda8g7WhieD68wxw7zFc3f5W6jFxyCBW8Z8vVxE9THtIFgwqrHMsohJhD1cu61hR5Qg2Th2GgAHfAcEDfMToilhxKKVyZwbg9lGyJzLaweeSD2e2K7nROabKh2D36iO0N3hWEvsfhvTrFO2UClLzfagEDUUDSZlqJeB60S9QPSXgSY40aYe78ZBff3nLHXvF8aUpgxwMDrU3zkSa2luYCVcgMEPGcP4JO1tbfobHlmSvTlodTFN5kuAvur6p46zK6r9Vg98poNN325sX66jHKHFrdu435MWoC6ac4GZ6AbqddUwLuBxMloXL33ig6WQOshXrHdB1RQzlExWzQJy58U9EVgZOyNrac2pUcG2rzgD98W4MbXmlPeYxH8a0drts1FET2WfQCEctgnud97qnEr57KM0L7SRw2wS1RArQd3nkuyMlXVCMRj82c8J3g31cSvBvvO3GKtSNc6WGYJxorRrOeMz5HgqmVxTbub6yBiRdenzVeHe1KGWd6wX297glKWfVy3i1C2xd72BpXep0prCiKps7XaZAf9yWUi3VwTTTpDQSN4DlswMI6LgYdiKMLBRdWrSbKvG0MKVZldNZnxmehPRRnZNh5lDf8Vx53DcfESCVQV6ad6Kk62l8SDQtNBgK4qFz8faq3h45FbDzWcBQT5PI98LWyAul4kKma8lTlDrFsqPPSLrsCY6qltFJlPZn26GXwvQWi3NthmOL2cUrMPlkS52AKNFGy6VNl8eZacEoU9fgH5bRQAcwJnpe59nvCdueBpJOwVtwRnCo35dZJxqhRn9MbWN4Mk6Rv2CCWjU6JCpSUWjfC176N3kcVDqPWMOM63s1ckgAOFbbKTTQU71elkfrvh8Depa3bGfXe1NrcOnN68hL9jFGwtzl1O5KwxBeO8dY2KPwRGmvWM251ecrVLUEd2PruzKOgycfclvaaU5PXxSoHtYqm6Rl2o27XDijIgEOgXM5v18QepNKej3cd3WdWvxwa3ezkbRayx0iDbeBBh9wLVydb7hG43gBteAWfLDK4sXobszdrRH5YDp2O8YjpSllvuHyIkv6NF9G83PkWsQ3EMHSP5sPrngT9cZ1NMeMkLZyX8NQm3esqPpY1h9zQMCxZnd0BTzCzShFd40z3jjSQfuSgcgowlkmueysZJSoTFObhoDGR96XTxFIyTSPTI9d86ojIzAGZnD6mkwYiN22DjEcGLNWvtpwnYAfUwB7x2Pi1rC1yKTjYSD0Risley6r0DcYbTITPtRH4lxzuMriCt2ZLlqYcHSI7w9CkDd8Jsmm30sOpKIg7euVfhuMHbAoS9JqaNIwZoOVSInlMFUPVlrFZselcxuUQkmyedz3EgtPEYnMJpr9mBeHanxjFxVcxkAOwxa1Ra5c0TINUlm8QANMRvq6yleZcyBdmsDmjJeEEzvtg27mIO3EcZgg2nrRqumZzyFrpClO3PmyQmIUfS3dXamGmNoY00PT8RpN2cAN7Hl5XpHS1JOSY3JHTaQ1I8fUqFlJpAYcWhP9zMcCFdRUD0AvmJx3iFyjEmLOAl9npbcqqiVTc1aTPfF52WAtFMqByUU98L9FNhTKmVbvsgJe4XNsQKju1w6ExLz1FSfAoSN5eFOno4UNTkaCJXfua15LIwiVKf1WNj0YHgL1TVHeU3750D5YX7GvVrInvTaFgCNVFkhKi4HyhBg0EthXoH49Q1FRhfZ3VgFt1xdtc762lPTMWtmDRmO5LwiATPhjKCFJjD1jEexxavorT0YiAVd833R8PrLpB7KKcvgCsf1fx8mOUZr0qKCdL7TMWCCIdlmFKMREZ41hIqdZkN8j4RzfAVvatxFpz5VCNY94SafJsw8M9xxViE1BGWbJ8BNqL5EYsFP0PM37J82BPSIFdmCtQI6M8yljDtZ3kf7aUADZiIMGjH5lP6BwQ3GLPxhcOe1Bf5BzX1wtbGa98OgnqI73diYK0yXcobC67YoEvqs6So9gbrWqc24WyTfDgCdAebUXb98VQuwhfGBNEDsPbPZDKique0lnI3j55pIgttlSTiNnvbQXRt4db5PU2pSOVdCnS6cE56H66R8vAPAjPTUwGsDmD8HFyi9sj8iQGzrxmduCfZ31k7Mgo7a4ln12biI2og5voU44sgrHxRCDcb1XmRhAympcItfQtjgDi8UggaBMYy3T5MF75kLzskeyEGb4Xd81wKoMSi8VmR8eFMwXOqhYSpmjrdf4gq9fLXlzWQi8RDcMqo2vxuCb3A1v1xn8Ksjl3CG9O3T6n1SK2kxf2k0pE4FHsLKqr441hHThLpIRwblFzOxovjCwaRwZEJzkHhHzwX5jljTvhEh0bjsBRnSoCvcMECoqn6waoLICRh4RTeO0NcyFLXlb2PXCR1rw1xs5srCkIjQqa4NnARsMgePn2d6LA9LG8b4ujFmPI4TqKqKtxb4EATL8QdD9DP1qUM7UMxwUtqC2uJl0zbkfcZaHUVMANsRzxVxT01qH6d3YWvbxfBHlX5WrYfQyveanS3dEJ4BN8PcdkCjFty0LCg7DMdl2HPEzT4eQNka8eAiyah4bkytvvigBxyW1AvHmSXIw8Z3PP981FP6nb3Tdp2pElK82wnNjQB4ea2HSzIgSe8fHoObnqwlPruvXsEkstYWElFeARgVFn0YgeycgIgbJtLGj3LABDMs9SplWoPv8CUS7oxgffpKQ0S5nO0w1Ymch6wTsEF5sCZL0cOF3KlmSYlgfArlZ1oGDLUl22DVPMuK0aBeSePEEmHfN8sS4oW5ggJdnYz2mhTu1dsB7UFFTWl4aNaBg4bfCger2strh1tPOrzzyhn6KXsUuFMc3zIzgcONilYT52A0caGKpDcPImhavV3NMSR7zLCBTzD00lGw4k9zY8yFlcJVmMfxiRrNXms9Zd90ZZPLxDvJIS3N8M19k3fddM1WDvaguZtBTTXi0hVz9aYUTeeAg151qOH5tXfDMqNqZMTk4KzStjst6Ilrv6GKpv3ynEbksWWD0dAYFLcwWjCJhzu7SXD22egw6hPPj2fennW2SfUDKPumc39biIdAUrkZ3LnYfAmePFXWItj14kh6KGRaEjXl6iWeIHau6rcoYRb9Z5L5MmRbicSEJsrUg9UifFobqKUHHv7WaP8ihg9yinwu9lTvJATiGdSbHis2uhVVYbsd9OBNA32yzMv76CfE9rBxxHgdSQkz0nNRTZJZKyTOq8K8DWoxWLUJOAQYKIcJqwd20VOho1JWsrCS45ecLDzAqP8LTQQs9ffgQW2wIeE1pTK2haOVUM1KxseDaD7xGgaPTluK1Tox84rtX77XBWXLYpYfiSFmZ28tqhJLyubgJwRh2QgLVtc2gZJhgQG7b1koPbvL2TYyCaH4oXU8kKKmo7m4jVFPaxz6LM6rgcD7heGAZykw2hleI8Q8eGn6gF2umX1RkRs7z4WmfaLijQsUefqOotHDSxOgMC4OqebTaqPJHbfwDuL2k8cyuOUNNdM5BR2UolCShqtssPNHAIXuKLlQZ35CEgzOdaliQcjH5leW6eQDKlAQAOMDsVe5u4LyaRyE9XyStjYENBLWBKNeHkgKJVK5Bez3FY91zueOFOQA5C0uQBVDRQoJEwSr8rywo8JqypxEc7WKfGMYluXbKIOd2CpHpI9u9zzqDQiNyWZiqgBn0znlm0H0ADLag8PX69Sndw3X6cghUDgm6UNbX1EczhFPzSxuTqKNrE8tYf0sflTIg3L9YGgktj2OjVE38suwmSmGju8a8v2hOuO5g5PgXquGPx25owEC90CcxYlrudSVSTxC1iyopBduh48ZNqdkOPkU6oCs1Mkk5VrwsfL0nrG4CoqKyFJYqlnJooJnsZlR9dQ9DwUhOZZXnbSTWuVoLSBTqzfyE8eQ86YdZofIS1on8YoOPrLtHZxdroULBhB1ZsryypL2qsTEQSMbr2EPR1Xk0qkFJ0GwPfbqCPBlbdOUc3usFjnHHKvsI7dZPGMQQ4zSZ2NCFuVxz0VnUYPajyNwWqTxtvVRB6waUIopH45NntyFBuB2woRiatB2MrDZGrlXFqjKiB1WT0XtqBZlvALfus8KTICMNvS66RD032hh0wJUAKPpYaMRqqoeWyHWpsAEXm5E1bMeDCcpjWVd1camrrS4RhUe0Zfv4kfwQQsiLjhiZLuxJ5IFgI6okGD6wXxE7sHBYId17WAJEVtUzGLjBsPfAd5dids6hsd6mQSiMuequwQY69rVqoWu7hIVxsTXdDyA9vjCtGVXoSTFeybz2VsS1CgID8sqcwOg152AOcjUw221slXQnRb8m4CuWdodrpxDaXDDIUt6i2Rq2PGmpqkXWEijc528Vc8XTvPTnDSVwVFRFqnOJtZq4nS5LxY72cuF4vNZPkP1QjZwwOzqMBJ90qOCGldYqPzw0gxXqqR74drZAdGjFxB4pQHp1sZYryRva7chyMcARs45qowRt246N3RKHQkY2QQim4SmSkiRUTtO16FpcSNyAaQU9kdCo6e6nDwhvORDSKZzq0LNsFbbqqCTPYVEvCUkqrCEnxajenGazy0L7NaoM9lNJxaO8m19iJEaEQbseVSml9Ni3vAkS4PKEuz2DYL7IXgRHZ1ejucxrSIvkmwNrTHsQFYUhAfRagZPoHUt22q6CNIv8iYPPT0j4cfy3jkR9MUiOqs0v83Zj29bEwXZUzhzFrozrkKPJrMxHksr8NvTPcDn4JC4s5WJgIG4rxofeofRBLKryZ1sZk5izFobtBGYLiqMtnYsKJnxnvNEk0Yhb4N6RmqC0mpYPXis3PDOWwh8j0IE4z3hCjvO3u1IxV8n8kLht0TOEjfnZyNpcr4QsiDMERS7r56JWWNKwEF3PFHJ2Y6yoqPpohp8WiW3nZKta7FZDwE1iaR7DFY8vFxzCZhtMVL8oOQBPfxXvKwa2fN5S0tN7q22jAGsKOECJkQn3VZeQLGwHaXjIZ0r6XeA39BfZQiUSj5c9VFoBeROCohbwzH0CDda8g7WhieD68wxw7zFc3f5W6jFxyCBW8Z8vVxE9THtIFgwqrHMsohJhD1cu61hR5Qg2Th2GgAHfAcEDfMToilhxKKVyZwbg9lGyJzLaweeSD2e2K7nROabKh2D36iO0N3hWEvsfhvTrFO2UClLzfagEDUUDSZlqJeB60S9QPSXgSY40aYe78ZBff3nLHXvF8aUpgxwMDrU3zkSa2luYCVcgMEPGcP4JO1tbfobHlmSvTlodTFN5kuAvur6p46zK6r9Vg98poNN325sX66jHKHFrdu435MWoC6ac4GZ6AbqddUwLuBxMloXL33ig6WQOshXrHdB1RQzlExWzQJy58U9EVgZOyNrac2pUcG2rzgD98W4MbXmlPeYxH8a0drts1FET2WfQCEctgnud97qnEr57KM0L7SRw2wS1RArQd3nkuyMlXVCMRj82c8J3g31cSvBvvO3GKtSNc6WGYJxorRrOeMz5HgqmVxTbub6yBiRdenzVeHe1KGWd6wX297glKWfVy3i1C2xd72BpXep0prCiKps7XaZAf9yWUi3VwTTTpDQSN4DlswMI6LgYdiKMLBRdWrSbKvG0MKVZldNZnxmehPRRnZNh5lDf8Vx53DcfESCVQV6ad6Kk62l8SDQtNBgK4qFz8faq3h45FbDzWcBQT5PI98LWyAul4kKma8lTlDrFsqPPSLrsCY6qltFJlPZn26GXwvQWi3NthmOL2cUrMPlkS52AKNFGy6VNl8eZacEoU9fgH5bRQAcwJnpe59nvCdueBpJOwVtwRnCo35dZJxqhRn9MbWN4Mk6Rv2CCWjU6JCpSUWjfC176N3kcVDqPWMOM63s1ckgAOFbbKTTQU71elkfrvh8Depa3bGfXe1NrcOnN68hL9jFGwtzl1O5KwxBeO8dY2KPwRGmvWM251ecrVLUEd2PruzKOgycfclvaaU5PXxSoHtYqm6Rl2o27XDijIgEOgXM5v18QepNKej3cd3WdWvxwa3ezkbRayx0iDbeBBh9wLVydb7hG43gBteAWfLDK4sXobszdrRH5YDp2O8YjpSllvuHyIkv6NF9G83PkWsQ3EMHSP5sPrngT9cZ1NMeMkLZyX8NQm3esqPpY1h9zQMCxZnd0BTzCzShFd40z3jjSQfuSgcgowlkmueysZJSoTFObhoDGR96XTxFIyTSPTI9d86ojIzAGZnD6mkwYiN22DjEcGLNWvtpwnYAfUwB7x2Pi1rC1yKTjYSD0Risley6r0DcYbTITPtRH4lxzuMriCt2ZLlqYcHSI7w9CkDd8Jsmm30sOpKIg7euVfhuMHbAoS9JqaNIwZoOVSInlMFUPVlrFZselcxuUQkmyedz3EgtPEYnMJpr9mBeHanxjFxVcxkAOwxa1Ra5c0TINUlm8QANMRvq6yleZcyBdmsDmjJeEEzvtg27mIO3EcZgg2nrRqumZzyFrpClO3PmyQmIUfS3dXamGmNoY00PT8RpN2cAN7Hl5XpHS1JOSY3JHTaQ1I8fUqFlJpAYcWhP9zMcCFdRUD0AvmJx3iFyjEmLOAl9npbcqqiVTc1aTPfF52WAtFMqByUU98L9FNhTKmVbvsgJe4XNsQKju1w6ExLz1FSfAoSN5eFOno4UNTkaCJXfua15LIwiVKf1WNj0YHgL1TVHeU3750D5YX7GvVrInvTaFgCNVFkhKi4HyhBg0EthXoH49Q1FRhfZ3VgFt1xdtc762lPTMWtmDRmO5LwiATPhjKCFJjD1jEexxavorT0YiAVd833R8PrLpB7KKcvgCsf1fx8mOUZr0qKCdL7TMWCCIdlmFKMREZ41hIqdZkN8j4RzfAVvatxFpz5VCNY94SafJsw8M9xxViE1BGWbJ8BNqL5EYsFP0PM37J82BPSIFdmCtQI6M8yljDtZ3kf7aUADZiIMGjH5lP6BwQ3GLPxhcOe1Bf5BzX1wtbGa98OgnqI73diYK0yXcobC67YoEvqs6So9gbrWqc24WyTfDgCdAebUXb98VQuwhfGBNEDsPbPZDKique0lnI3j55pIgttlSTiNnvbQXRt4db5PU2pSOVdCnS6cE56H66R8vAPAjPTUwGsDmD8HFyi9sj8iQGzrxmduCfZ31k7Mgo7a4ln12biI2og5voU44sgrHxRCDcb1XmRhAympcItfQtjgDi8UggaBMYy3T5MF75kLzskeyEGb4Xd81wKoMSi8VmR8eFMwXOqhYSpmjrdf4gq9fLXlzWQi8RDcMqo2vxuCb3A1v1xn8Ksjl3CG9O3T6n1SK2kxf2k0pE4FHsLKqr441hHThLpIRwblFzOxovjCwaRwZEJzkHhHzwX5jljTvhEh0bjsBRnSoCvcMECoqn6waoLICRh4RTeO0NcyFLXlb2PXCR1rw1xs5srCkIjQqa4NnARsMgePn2d6LA9LG8b4ujFmPI4TqKqKtxb4EATL8QdD9DP1qUM7UMxwUtqC2uJl0zbkfcZaHUVMANsRzxVxT01qH6d3YWvbxfBHlX5WrYfQyveanS3dEJ4BN8PcdkCjFty0LCg7DMdl2HPEzT4eQNka8eAiyah4bkytvvigBxyW1AvHmSXIw8Z3PP981FP6nb3Tdp2pElK82wnNjQB4ea2HSzIgSe8fHoObnqwlPruvXsEkstYWElFeARgVFn0YgeycgIgbJtLGj3LABDMs9SplWoPv8CUS7oxgffpKQ0S5nO0w1Ymch6wTsEF5sCZL0cOF3KlmSYlgfArlZ1oGDLUl22DVPMuK0aBeSePEEmHfN8sS4oW5ggJdnYz2mhTu1dsB7UFFTWl4aNaBg4bfCger2strh1tPOrzzyhn6KXsUuFMc3zIzgcONilYT52A0caGKpDcPImhavV3NMSR7zLCBTzD00lGw4k9zY8yFlcJVmMfxiRrNXms9Zd90ZZPLxDvJIS3N8M19k3fddM1WDvaguZtBTTXi0hVz9aYUTeeAg151qOH5tXfDMqNqZMTk4KzStjst6Ilrv6GKpv3ynEbksWWD0dAYFLcwWjCJhzu7SXD22egw6hPPj2fennW2SfUDKPumc39biIdAUrkZ3LnYfAmePFXWItj14kh6KGRaEjXl6iWeIHau6rcoYRb9Z5L5MmRbicSEJsrUg9UifFobqKUHHv7WaP8ihg9yinwu9lTvJATiGdSbHis2uhVVYbsd9OBNA32yzMv76CfE9rBxxHgdSQkz0nNRTZJZKyTOq8K8DWoxWLUJOAQYKIcJqwd20VOho1JWsrCS45ecLDzAqP8LTQQs9ffgQW2wIeE1pTK2haOVUM1KxseDaD7xGgaPTluK1Tox84rtX77XBWXLYpYfiSFmZ28tqhJLyubgJwRh2QgLVtc2gZJhgQG7b1koPbvL2TYyCaH4oXU8kKKmo7m4jVFPaxz6LM6rgcD7heGAZykw2hleI8Q8eGn6gF2umX1RkRs7z4WmfaLijQsUefqOotHDSxOgMC4OqebTaqPJHbfwDuL2k8cyuOUNNdM5BR2UolCShqtssPNHAIXuKLlQZ35CEgzOdaliQcjH5leW6eQDKlAQAOMDsVe5u4LyaRyE9XyStjYENBLWBKNeHkgKJVK5Bez3FY91zueOFOQA5C0uQBVDRQoJEwSr8rywo8JqypxEc7WKfGMYluXbKIOd2CpHpI9u9zzqDQiNyWZiqgBn0znlm0H0ADLag8PX69Sndw3X6cghUDgm6UNbX1EczhFPzSxuTqKNrE8tYf0sflTIg3L9YGgktj2OjVE38suwmSmGju8a8v2hOuO5g5PgXquGPx25owEC90CcxYlrudSVSTxC1iyopBduh48ZNqdkOPkU6oCs1Mkk5VrwsfL0nrG4CoqKyFJYqlnJooJnsZlR9dQ9DwUhOZZXnbSTWuVoLSBTqzfyE8eQ86YdZofIS1on8YoOPrLtHZxdroULBhB1ZsryypL2qsTEQSMbr2EPR1Xk0qkFJ0GwPfbqCPBlbdOUc3usFjnHHKvsI7dZPGMQQ4zSZ2NCFuVxz0VnUYPajyNwWqTxtvVRB6waUIopH45NntyFBuB2woRiatB2MrDZGrlXFqjKiB1WT0XtqBZlvALfus8KTICMNvS66RD032hh0wJUAKPpYaMRqqoeWyHWpsAEXm5E1bMeDCcpjWVd1camrrS4RhUe0Zfv4kfwQQsiLjhiZLuxJ5IFgI6okGD6wXxE7sHBYId17WAJEVtUzGLjBsPfAd5dids6hsd6mQSiMuequwQY69rVqoWu7hIVxsTXdDyA9vjCtGVXoSTFeybz2VsS1CgID8sqcwOg152AOcjUw221slXQnRb8m4CuWdodrpxDaXDDIUt6i2Rq2PGmpqkXWEijc528Vc8XTvPTnDSVwVFRFqnOJtZq4nS5LxY72cuF4vNZPkP1QjZwwOzqMBJ90qOCGldYqPzw0gxXqqR74drZAdGjFxB4pQHp1sZYryRva7chyMcARs45qowRt246N3RKHQkY2QQim4SmSkiRUTtO16FpcSNyAaQU9kdCo6e6nDwhvORDSKZzq0LNsFbbqqCTPYVEvCUkqrCEnxajenGazy0L7NaoM9lNJxaO8m19iJEaEQbseVSml9Ni3vAkS4PKEuz2DYL7IXgRHZ1ejucxrSIvkmwNrTHsQFYUhAfRagZPoHUt22q6CNIv8iYPPT0j4cfy3jkR9MUiOqs0v83Zj29bEwXZUzhzFrozrkKPJrMxHksr8NvTPcDn4JC4s5WJgIG4rxofeofRBLKryZ1sZk5izFobtBGYLiqMtnYsKJnxnvNEk0Yhb4N6RmqC0mpYPXis3PDOWwh8j0IE4z3hCjvO3u1IxV8n8kLht0TOEjfn"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/0000755000000000000000000000000015010704253022500 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/02_switches/001.cf0000644000000000000000000000105715010704253023315 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,ok"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/dry_run_perms_doesnt_lie.cf0000644000000000000000000000235515010704253030114 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/." create => "true"; "$(G.testdir)/redmine_7082" create => "true", perms => m("777"), comment => "We first ensure a file exists with specific permissions so that we can test if we get unexpected output when later running with dry-run."; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) -Knf $(this.promise_filename).sub -I -b test"; methods: # Since the agent is run with dry-run (-n) there should be no statement of permissions changing. # In fact, permissions are not changed, the agent only says they are, so it is only the false statement that needs to be checked. "test_agent_output" usebundle => dcs_passif_output(".*Should change permissions of .* from 0777 to 0700.*", ".*had permissions 0777, changed it to 0700.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/show-evaluated-vars.cf0000644000000000000000000000212515010704253026713 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "ENT-7724", "ENT-7678" } string => "Test --show-evaluated-vars does not crash the agent when there are vars defined by the module protocol that do not have explicit tags defined."; "test_skip_unsupported" string => "windows", comment => "The subtest policy uses /bin/echo"; commands: "$(sys.cf_agent) -Kf $(this.promise_filename).sub --show-evaluated-vars" classes => results( "namespace", "sub_agent" ); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_passif_expected( "sub_agent_repaired", "sub_agent_not_kept", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/show-evaluated-vars.cf.sub0000644000000000000000000000066515010704253027512 0ustar00rootroot00000000000000# Here we execute echo as a module to define some variables that do not have /explicit/ tags. # As noted in ENT-7724, this can cause a segfault when the agent is run with --show-evaluated-vars bundle agent main { commands: `/bin/echo '=string_from_module= value of string from module @list_from_module= { "one", "two", "three" } %data1_from_module=[1,2,3] %data2_from_module={ "my_stuff": [1,2,3] }'` module => "true"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/008.cf0000644000000000000000000000117315010704253023323 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,MAIN -N ok,foo"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/010.cf0000644000000000000000000000144715010704253023320 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd1" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub1 -D AUTO -N bingo"; "cmd2" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub2 -D AUTO"; commands: "$(cmd1)"; "$(cmd2)"; reports: DEBUG:: "Running: $(cmd1)"; "Running: $(cmd2)"; "Setup comes from $(this.promise_filename).sub1, results come from $(this.promise_filename).sub2"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/002.cf.sub0000644000000000000000000000163015010704253024103 0ustar00rootroot00000000000000####################################################### # # Test class creation with -D # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: DEBUG:: "This should only pass if you run it with: -D ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) Pass"; !ok:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/004.cf.sub0000644000000000000000000000163715010704253024114 0ustar00rootroot00000000000000####################################################### # # Test class creation with -D # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: DEBUG:: "This should only pass if you do not run it with: -D ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) FAIL"; !ok:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/006.cf.sub0000644000000000000000000000153515010704253024113 0ustar00rootroot00000000000000####################################################### # # Test initial class negation with -N # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" expression => "any"; "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: DEBUG:: "This should pass even if you run it with: -N ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) Pass"; !ok:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/003.cf0000644000000000000000000000115515010704253023316 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,ok_"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/dry_run_perms_doesnt_lie.cf.sub0000644000000000000000000000041615010704253030700 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { files: "$(G.testdir)/redmine_7082" create => "true", perms => m("go-rwx"); } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/004.cf0000644000000000000000000000115515010704253023317 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,ok."; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/005.cf0000644000000000000000000000115715010704253023322 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO -N ok"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/005.cf.sub0000644000000000000000000000163315010704253024111 0ustar00rootroot00000000000000####################################################### # # Test initial class negation with -N # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: DEBUG:: "This should pass if you run it with: -N ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) FAIL"; !ok:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/006.cf0000644000000000000000000000116715010704253023324 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,MAIN -N ok"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/README0000644000000000000000000000042515010704253023361 0ustar00rootroot00000000000000There are tests in this directory that consist of two files. The first file is the nnn.cf file, which is called by the test runner. The second file is the nnn.cf.sub file, which is called by the nnn.cf file. In each case we are testing the effects of various runtime flags. cfengine-3.24.2/tests/acceptance/00_basics/02_switches/008.cf.sub0000644000000000000000000000153515010704253024115 0ustar00rootroot00000000000000####################################################### # # Test initial class negation with -N # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" expression => "any"; "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: DEBUG:: "This should pass even if you run it with: -N ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) Pass"; !ok:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/002.cf0000644000000000000000000000115515010704253023315 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,ok,"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/003.cf.sub0000644000000000000000000000163715010704253024113 0ustar00rootroot00000000000000####################################################### # # Test class creation with -D # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: DEBUG:: "This should only pass if you do not run it with: -D ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) FAIL"; !ok:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/staging/0000755000000000000000000000000015010704253024134 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/02_switches/staging/negate_hard_class.cf0000644000000000000000000000145615010704253030102 0ustar00rootroot00000000000000####################################################### # # Test hard class negation with -N # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle common test { classes: "rejected" not => returnszero("$(sys.cf_agent) -Kf $(this.promise_filename).sub -Ncfengine", "noshell"); } ####################################################### bundle agent check { classes: "ok" and => { "rejected" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/staging/007.cf0000644000000000000000000000116715010704253024761 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,MAIN -N ok"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/staging/negate_hard_class.cf.sub0000644000000000000000000000024215010704253030662 0ustar00rootroot00000000000000body common control { bundlesequence => { run }; } bundle agent run { reports: DEBUG:: "$(this.bundle): running from $(this.promise_filename)"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/staging/007.cf.sub0000644000000000000000000000173515010704253025552 0ustar00rootroot00000000000000####################################################### # # Test initial class negation with -N # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { files: "$(g.testfile)" create => "true", classes => set_bingo; } body classes set_bingo { promise_kept => { "bingo" }; promise_repaired => { "bingo" }; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "ok" expression => "bingo"; reports: DEBUG:: "This should pass even if you run it with: -N ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) Pass"; !ok:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/staging/009.cf.sub0000644000000000000000000000173515010704253025554 0ustar00rootroot00000000000000####################################################### # # Test initial class negation with -N # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { files: "$(g.testfile)" create => "true", classes => set_bingo; } body classes set_bingo { promise_kept => { "bingo" }; promise_repaired => { "bingo" }; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); "ok" expression => "bingo"; reports: DEBUG:: "This should pass even if you run it with: -N ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) Pass"; !ok:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/staging/009.cf0000644000000000000000000000117315010704253024760 0ustar00rootroot00000000000000####################################################### # # This is a special test - it exercises runtime switches # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test }; version => "1.0"; } ####################################################### bundle agent test { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -D AUTO,MAIN -N ok,foo"; commands: "$(cmd)"; reports: DEBUG:: "Running: $(cmd)"; "Test results come from $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/010.cf.sub10000644000000000000000000000215115010704253024162 0ustar00rootroot00000000000000####################################################### # # Test initial class negation with -N # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", classes => set_bingo; } body classes set_bingo { promise_kept => { "bingo" }; promise_repaired => { "bingo" }; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub\d", $(this.promise_filename), "fn"); "ok" expression => "bingo"; reports: DEBUG:: "This is $(this.promise_filename), the setup stage of the test only"; DEBUG.bingo:: "bingo is set in $(this.promise_filename)"; DEBUG.!bingo:: "bingo is not set in $(this.promise_filename)"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/001.cf.sub0000644000000000000000000000163015010704253024102 0ustar00rootroot00000000000000####################################################### # # Test class creation with -D # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub", $(this.promise_filename), "fn"); reports: DEBUG:: "This should only pass if you run it with: -D ok"; "Look at $(fn[1]) to see which flags are passed in"; ok:: "$(fn[1]) Pass"; !ok:: "$(fn[1]) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/02_switches/010.cf.sub20000644000000000000000000000202515010704253024163 0ustar00rootroot00000000000000####################################################### # # Test class creation with -D # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "dummy" expression => regextract("(.*)\.sub\d", $(this.promise_filename), "fn"); reports: DEBUG:: "This is $(this.promise_filename)"; "This should only pass if you run it with the 'bingo' class defined"; "The main tester does NOT set it, but it is created in the 'setup'"; "config file, $(fn[1]).sub1"; bingo:: "$(fn[1]) FAIL"; !bingo:: "$(fn[1]) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/0000755000000000000000000000000015010704253022115 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/001.cf0000644000000000000000000000107015010704253022725 0ustar00rootroot00000000000000# Test that log_failed without log_kept does not segfault (Mantis #1107) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { files: "$(G.testdir)/foo.txt" create => "true", action => log; } body action log { log_failed => "stdout"; log_string => ""; } bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/119.cf0000644000000000000000000001027115010704253022742 0ustar00rootroot00000000000000####################################################### # # Test no classes set with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "1" }; repaired_returncodes => { "2" }; failed_returncodes => { "3" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/104.cf0000644000000000000000000001017215010704253022734 0ustar00rootroot00000000000000####################################################### # # Test promise_kept and cancel_kept # Insert lines to a file, then verify that insert promise is kept # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => init_insert("$(init.body)"), edit_defaults => init_empty, classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/log_file_permissions.cf0000644000000000000000000000176415010704253026652 0ustar00rootroot00000000000000# Test that log_failed and log_kept set to the same value do not cause stack overflow (Redmine #2317) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { meta: "test_skip_unsupported" string => "windows"; commands: "$(G.true)" action => log; } body action log { log_repaired => "$(G.testfile).action.log"; log_failed => "$(G.testfile).action.log"; log_kept => "$(G.testfile).action.log"; log_string => "ignore me"; } bundle agent check { vars: "perms" string => filestat("$(G.testfile).action.log", "permoct"); classes: "ok" expression => strcmp("600", $(perms)); reports: DEBUG:: "Log file $(G.testfile).action.log had permissions $(perms)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/102.cf0000644000000000000000000000774615010704253022747 0ustar00rootroot00000000000000####################################################### # # Test multiple promise_repaired and cancel_repaired (contrived example) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_repaired => { "promise_repaired", "p2_repaired" }; cancel_repaired => { "cancel_repaired", "cancel_kept", "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[p2_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "p2_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/evaluation-should-respect-ifvarclass.cf0000644000000000000000000000376115010704253031677 0ustar00rootroot00000000000000############################################################################## # # Redmine #3577: evaluation should respect ifvarclass # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: "rm" usebundle => dcs_fini("$(G.testfile).z"); "rm" usebundle => dcs_fini("$(G.testfile).z2"); } bundle agent test { classes: "zclass" expression => returnszero("$(G.echo) xyz > $(G.testfile).z", "useshell"), ifvarclass => not("any"); "zclass" expression => returnszero("$(G.echo) xyz > $(G.testfile).z", "useshell"), depends_on => { "this_handle_does_not_exist" }; !any:: "z2class" expression => returnszero("$(G.echo) xyz > $(G.testfile).z2", "useshell"); vars: "x" string => concat("a", "b"), ifvarclass => "!any"; "x_not" string => concat("a", "b"), ifvarclass => not("any"); !any:: "y" string => concat("c", "d"); } bundle agent check { # If the output contains the string, we fail classes: "eval_x" expression => strcmp("ab", "$(test.x)"); "eval_x_not" expression => strcmp("ab", "$(test.x_not)"); "eval_y" expression => strcmp("cd", "$(test.y)"); "eval_z" expression => "zclass"; "zfile_created" expression => fileexists("$(G.testfile).z"); "z2file_created" expression => fileexists("$(G.testfile).z2"); methods: "" usebundle => dcs_passif_expected("", "eval_x,eval_x_not,eval_y,zclass,zfile_created,z2file_created", $(this.promise_filename)), inherit => "true"; reports: DEBUG:: "x $(test.x)"; "x_not $(test.x_not)"; "y $(test.y)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/121.cf0000644000000000000000000001034215010704253022732 0ustar00rootroot00000000000000####################################################### # # Test overlapping codes (with no match) with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "10", "11" }; repaired_returncodes => { "11" }; failed_returncodes => { "11", "12" }; } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/101.cf0000644000000000000000000000764715010704253022746 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "G", "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/0000755000000000000000000000000015010704253023107 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-common-control-inputs/0000755000000000000000000000000015010704253030330 5ustar00rootroot00000000000000app_two.cf.sub0000644000000000000000000000007415010704253033025 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-common-control-inputsbundle agent app_two { reports: "$(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-common-control-inputs/test.cf.sub0000644000000000000000000000336415010704253032417 0ustar00rootroot00000000000000body file control { inputs => { @(map_role_bundles.inputs) }; } bundle agent main # { methods: "classify"; "map_role_bundles"; "go"; } bundle common classify # { vars: "variable" string => "any"; classes: "group_class_from_variable" expression => strcmp("$(variable)", "any"), comment => "Highest level classification, other classes depend on this."; "group_class_from_string" expression => strcmp("any", "any"), comment => "Highest level classification, other classes depend on this."; } bundle common map_role_bundles # { vars: # Define bundles any:: "role[app00_zero]" string => "$(this.promise_dirname)/app00_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; !any:: "role[app_zero]" string => "$(this.promise_dirname)/app_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_class_from_variable:: "role[app_one]" string => "$(this.promise_dirname)/app_one.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_class_from_string:: "role[app_two]" string => "$(this.promise_dirname)/app_two.cf.sub"; any:: "bundles" slist => getindices(role); "inputs" slist => getvalues(role); } bundle agent go # { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); methods: "$(sorted_bundles)" usebundle => $(sorted_bundles); } app_one.cf.sub0000644000000000000000000000007415010704253032775 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-common-control-inputsbundle agent app_one { reports: "$(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-common-control-inputs/test.cf0000644000000000000000000000162515010704253031625 0ustar00rootroot00000000000000####################################################### # # Redmine#3315: Test dynamic inputs and bundlesequence # ####################################################### body common control { inputs => { "../../../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-1780" } string => "Test that dynamic inputs from classic array structures can be loaded and used via body file control."; } bundle agent check { methods: "Check Agent Output" usebundle => dcs_passif_output1(".*R: app00_zero R: app_one R: app_two.*", "$(sys.cf_agent) -Kf $(this.promise_filename).sub", $(this.promise_filename)); } app00_zero.cf.sub0000644000000000000000000000007715010704253033336 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-common-control-inputsbundle agent app00_zero { reports: "$(this.bundle)"; } app_zero.cf.sub0000644000000000000000000000011715010704253033171 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-common-control-inputsbundle agent app_zero # { reports: "HEY I activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-file-control-inputs/0000755000000000000000000000000015010704253027757 5ustar00rootroot00000000000000app_two.cf.sub0000644000000000000000000000007415010704253032454 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-file-control-inputsbundle agent app_two { reports: "$(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-file-control-inputs/test.cf.sub0000644000000000000000000000337215010704253032045 0ustar00rootroot00000000000000body common control # { bundlesequence => { "classify", "map_role_bundles", "go" }; inputs => { @(map_role_bundles.inputs) }; } bundle common classify # { vars: "variable" string => "any"; classes: "group_class_from_variable" expression => strcmp("$(variable)", "any"), comment => "Highest level classification, other classes depend on this."; "group_class_from_string" expression => strcmp("any", "any"), comment => "Highest level classification, other classes depend on this."; } bundle common map_role_bundles # { vars: # Define bundles any:: "role[app00_zero]" string => "$(this.promise_dirname)/app00_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; !any:: "role[app_zero]" string => "$(this.promise_dirname)/app_zero.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_class_from_variable:: "role[app_one]" string => "$(this.promise_dirname)/app_one.cf.sub", comment => "Roles are based on groups. Roles map to bundles. Bundles are defined in a specific file."; group_class_from_string:: "role[app_two]" string => "$(this.promise_dirname)/app_two.cf.sub"; any:: "bundles" slist => getindices(role); "inputs" slist => getvalues(role); } bundle agent go # { vars: "bundles" slist => { @(map_role_bundles.bundles) }; "sorted_bundles" slist => sort(bundles, "lex"); methods: "$(sorted_bundles)" usebundle => $(sorted_bundles); } app_one.cf.sub0000644000000000000000000000007415010704253032424 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-file-control-inputsbundle agent app_one { reports: "$(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-file-control-inputs/test.cf0000644000000000000000000000157715010704253031262 0ustar00rootroot00000000000000####################################################### # # Redmine#3315: Test dynamic inputs and bundlesequence # ####################################################### body common control { inputs => { "../../../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-1780" } string => "Test that dynamic inputs from classic array structures can be loaded and used."; } bundle agent check { methods: "Check Agent Output" usebundle => dcs_passif_output1(".*R: app00_zero R: app_one R: app_two.*", "$(sys.cf_agent) -Kf $(this.promise_filename).sub", $(this.promise_filename)); } app00_zero.cf.sub0000644000000000000000000000007715010704253032765 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-file-control-inputsbundle agent app00_zero { reports: "$(this.bundle)"; } app_zero.cf.sub0000644000000000000000000000011715010704253032620 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/CFE-1780/body-file-control-inputsbundle agent app_zero # { reports: "HEY I activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/112.cf0000644000000000000000000001016015010704253022730 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" # create => "true", # file will not exist! edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/115.cf0000644000000000000000000001014315010704253022734 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired with command and no *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/cf_null_in_bundlesequence.cf0000644000000000000000000000064015010704253027621 0ustar00rootroot00000000000000# cf_null now is just another string, bundles names as such should be # executed like every other bundle body common control { bundlesequence => { "cf_null", "test" }; } bundle agent cf_null { classes: "ok" expression => "any", scope => "namespace"; } bundle agent test { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/118.cf0000644000000000000000000001032315010704253022737 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "0" }; repaired_returncodes => { "1" }; failed_returncodes => { "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile).missing" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/dynamic_inputs_maplist.cf0000644000000000000000000000204315010704253027205 0ustar00rootroot00000000000000####################################################### # # Redmine#3315: Test dynamic inputs and bundlesequence using maplist # ####################################################### body common control { inputs => { "../../default.cf.sub", @(dynamic.inputs), }; bundlesequence => { dynamic, default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent dynamic { vars: "todo" slist => bundlesmatching(".*included"); "dynamic_input_names" slist => {"$(this.promise_filename).sub"}; "inputs" slist => maplist("$(this)", "dynamic_input_names"); methods: "run" usebundle => $(todo); reports: DEBUG:: "Found dynamic bundle: $(todo)"; } bundle agent init { } bundle agent test { } bundle agent check { classes: "ok" expression => "class_defined_from_included_bundle"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/inherit_from_noargs.x.cf0000644000000000000000000000126315010704253026735 0ustar00rootroot00000000000000############################################################################## # # Redmine #4309: body inheritance with inherit_from # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { reports: "test_inherit" classes => classes_generic_broken_inherit("test_inherit"); } body classes classes_generic_broken_inherit(x) { inherit_from => classes_generic; # should break } bundle agent check { methods: "any" usebundle => dcs_pass("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/401.x.cf0000644000000000000000000000151515010704253023203 0ustar00rootroot00000000000000####################################################### # # Test handling of duplicate handles # Should error, was crashing in Issue 2267 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { vars: "firstvar" handle => "dupehandle", string => "Some item with a handle"; "secondvar" handle => "dupehandle", string => "Another variable with an intentionally duplicated handle"; } bundle agent check { reports: DEBUG:: "Expected to return an error"; !ok:: "$(this.promise_filename) Pass"; ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/control-body-fncall.cf0000644000000000000000000000123015010704253026273 0ustar00rootroot00000000000000# Test that functions may be called from control bodies body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { # this is just to trigger the desired behavior. here ifelse is evaluated # without any caller promise. If it was a non-control body, the caller # would have been the promise inlining the body. here there is no caller. default_repository => ifelse("x", "false", "y", "false", "false"); } bundle agent init { } bundle agent test { } bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/113.cf0000644000000000000000000001030415010704253022731 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept (different location and results) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" # create => "true", # file will not exist! edit_line => init_insert("$(body)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)" # Promise never executed, so classes not set! classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/inherit_from_parameters.cf0000644000000000000000000000253215010704253027341 0ustar00rootroot00000000000000############################################################################## # # Redmine #4309: parameterized body inheritance with inherit_from # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle common test { reports: "test_inherit1" classes => scoped_classes_generic_inherit("namespace", "test_inherit"); "test_inherit2" classes => scoped_classes_generic_some_inherit("test_inherit_some"); "test_inherit3" classes => scoped_classes_generic_none_inherit; } body classes scoped_classes_generic_inherit(myscope, myx) { inherit_from => scoped_classes_generic($(myscope), $(myx)); } body classes scoped_classes_generic_some_inherit(somex) { inherit_from => scoped_classes_generic("namespace", $(somex)); } body classes scoped_classes_generic_none_inherit { inherit_from => scoped_classes_generic("namespace", "test_inherit_none"); } bundle agent check { methods: "" usebundle => dcs_passif_expected("test_inherit_ok,test_inherit_some_ok,test_inherit_none_ok", "", $(this.promise_filename)), inherit => "true"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/inherit_from_mismatched_args.x.cf0000644000000000000000000000130115010704253030567 0ustar00rootroot00000000000000############################################################################## # # Redmine #4309: body inheritance with inherit_from # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test { reports: "test_inherit" classes => classes_generic_broken_inherit("test_inherit"); } body classes classes_generic_broken_inherit(x) { inherit_from => classes_generic("one", "two"); # should break } bundle agent check { methods: "any" usebundle => dcs_pass("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/inherit_from.cf0000644000000000000000000000432315010704253025116 0ustar00rootroot00000000000000############################################################################## # # Redmine #4309: body inheritance with inherit_from # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle common test { reports: "test_inherit" classes => classes_generic_inherit("test_inherit"); "test_nonesuch" classes => classes_generic_nonesuch("test_nonesuch"); "test_overwrite" classes => classes_generic_overwrite("test_overwrite"); } body classes classes_generic_inherit(x) { inherit_from => classes_generic($(x)); } body classes classes_generic_nonesuch(x) { inherit_from => classes_generic_missing_body; } # the parent uses $(x) so this tests that inheritance goes from parent to child body classes classes_generic_overwrite(overwrite_x) { inherit_from => classes_generic($(overwrite_x)); promise_repaired => { "promise_repaired_$(overwrite_x)", "$(overwrite_x)_repaired", "$(overwrite_x)_ok", "$(overwrite_x)_reached" }; repair_failed => { "repair_failed_$(overwrite_x)", "$(overwrite_x)_failed", "$(overwrite_x)_not_ok", "$(overwrite_x)_error", "$(overwrite_x)_not_kept", "$(overwrite_x)_not_repaired", "$(overwrite_x)_reached" }; repair_denied => { "repair_denied_$(overwrite_x)", "$(overwrite_x)_denied", "$(overwrite_x)_not_ok", "$(overwrite_x)_error", "$(overwrite_x)_not_kept", "$(overwrite_x)_not_repaired", "$(overwrite_x)_reached" }; repair_timeout => { "repair_timeout_$(overwrite_x)", "$(overwrite_x)_timeout", "$(overwrite_x)_not_ok", "$(overwrite_x)_error", "$(overwrite_x)_not_kept", "$(overwrite_x)_not_repaired", "$(overwrite_x)_reached" }; promise_kept => { "promise_kept_$(overwrite_x)", "$(overwrite_x)_kept", "$(overwrite_x)_ok", "$(overwrite_x)_not_repaired", "$(overwrite_x)_reached" }; } bundle agent check { methods: "" usebundle => dcs_passif_expected("test_inherit_ok,test_overwrite_ok", "test_nonesuch_ok", $(this.promise_filename)), inherit => "true"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/103.cf0000644000000000000000000001017415010704253022735 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired (different location in edit_line) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/003.cf0000644000000000000000000000124715010704253022735 0ustar00rootroot00000000000000# Test that log_failed and log_kept set to the same value do not cause stack overflow (Redmine #2317) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { commands: "$(G.true)" action => log; } body action log { log_repaired => "$(G.testfile).action.log"; log_failed => "$(G.testfile).action.log"; log_kept => "$(G.testfile).action.log"; log_string => ""; } bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/125.cf0000644000000000000000000000156515010704253022745 0ustar00rootroot00000000000000# Test a context defined in body classes with scope => bundle, # cancelling a namespace class using a bundle class body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; processes: any:: "$(G.true)" classes => set_cancel_this; } bundle agent test { processes: any:: "$(G.true)" classes => bundle_class; } body classes set_cancel_this { promise_kept => { "cancel_this" }; } body classes bundle_class { scope => "bundle"; promise_kept => { "bundle_class" }; cancel_kept => { "cancel_this" }; } bundle agent check { reports: !cancel_this:: "$(this.promise_filename) Pass"; cancel_this|bundle_class:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/default_files_action.cf0000644000000000000000000000267015010704253026577 0ustar00rootroot00000000000000####################################################### # # Test default body action and overriding with specific action # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body file control { namespace => "bodydefault"; } body action files_action { action_policy => "warn"; } body file control { namespace => "default"; } body action specific { action_policy => "fix"; } ####################################################### bundle agent test_specified_action { files: "$(G.testdir)/specified" create => "true", action => specific; } bundle agent test_default_action { files: "$(G.testdir)/default" create => "true"; } ####################################################### bundle agent test { methods: "specified" usebundle => test_specified_action; "default" usebundle => test_default_action; } bundle agent check { classes: "default_created" expression => fileexists("$(G.testdir)/default"); "specified_created" expression => fileexists("$(G.testdir)/specified"); "ok" expression => "specified_created.!default_created"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/dynamic_inputs_findfiles.cf.sub0000644000000000000000000000027315010704253030272 0ustar00rootroot00000000000000bundle agent dynamic_included { meta: "tags" string => "included"; classes: "class_defined_from_included_bundle" expression => "any", scope => "namespace"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/117.cf0000644000000000000000000001032615010704253022741 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "0" }; repaired_returncodes => { "1" }; failed_returncodes => { "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/114.cf0000644000000000000000000001016015010704253022732 0ustar00rootroot00000000000000####################################################### # # Test setting two classes in one promise # Copy file with one mode, then copy again with different mode # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile)" copy_from => local("$(G.etc_group)"), perms => mode("666"); } body copy_from local(f) { source => "$(f)"; } body perms mode(m) { mode => "$(m)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { meta: "test_skip_needs_work" string => "windows"; files: "$(G.testfile)" copy_from => local("$(G.etc_group)"), # Same file perms => mode("644"), # Different mode classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/report_error_when_body_missing.cf0000644000000000000000000000112115010704253030735 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" string => "Test that a sensible error message is emitted when a body is undefined."; } bundle agent check { classes: "ok" expression => "class_defined_from_included_bundle"; methods: "" usebundle => dcs_passif_output(".*Undefined body my_undefined_body.*", "", "$(sys.cf_agent) -Kf $(this.promise_filename).sub", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/dynamic_inputs_maplist.cf.sub0000644000000000000000000000041615010704253027777 0ustar00rootroot00000000000000bundle agent dynamic_included { meta: "tags" string => "included"; classes: "class_defined_from_included_bundle" expression => "any", scope => "namespace"; reports: DEBUG:: "$(this.promise_filename) activated $(this.bundle)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/122.x.cf0000644000000000000000000001040215010704253023176 0ustar00rootroot00000000000000####################################################### # # Test illegal codes (string) with command and *_returncodes (issue 751) # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "1", "3" }; repaired_returncodes => { "fred", "7" }; # Must be an integer failed_returncodes => { "1", "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/README0000644000000000000000000000030515010704253022773 0ustar00rootroot00000000000000The files in this directory are tests of bodies that occur "anywhere": 0xx.cf body action 1xx.cf body classes 2xx.cf body comments 3xx.cf body depends_on 4xx.cf body handle 5xx.cf body ifvarclass cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/124.cf0000644000000000000000000000216015010704253022734 0ustar00rootroot00000000000000# Test a context defined in body classes with scope => bundle, # check that the bundle context goes away after the bundle is done body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { methods: !pass_one:: "whatever" usebundle => set_context("yes"); pass_one:: "whatever2" usebundle => set_context("no"); } bundle agent set_context(doit) { classes: "set_bundle_class" expression => strcmp(${doit}, "yes"); processes: set_bundle_class:: "$(G.true)" classes => bundle_class; "$(G.true)" classes => namespace_class; } body classes namespace_class { scope => "namespace"; promise_kept => { "pass_one" }; } body classes bundle_class { scope => "bundle"; promise_kept => { "bundle_context" }; } bundle agent check { reports: !bundle_context:: "$(this.promise_filename) Pass"; bundle_context:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/if-unless.cf0000644000000000000000000000233215010704253024334 0ustar00rootroot00000000000000############################################################################## # # Redmine #6179: if and unless # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { classes: "check1" expression => "any", scope => "namespace"; "check2" expression => "any", scope => "namespace"; } bundle agent test { methods: "" usebundle => file_make("$(G.testfile).present", ""), if => "check1"; "" usebundle => file_make("$(G.testfile).absent", ""), unless => "check2"; "" usebundle => file_make("$(G.testfile).absent", ""), if => "check1", unless => "check2"; } bundle agent check { # If the output contains the string, we fail classes: "if_ok" expression => fileexists("$(G.testfile).present"); "unless_ok" not => fileexists("$(G.testfile).absent"); methods: "" usebundle => dcs_passif_expected("if_ok,unless_ok", "", $(this.promise_filename)), inherit => "true"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/report_error_when_body_missing.cf.sub0000644000000000000000000000015015010704253031526 0ustar00rootroot00000000000000bundle agent main { commands: "/bin/echo 123" action => my_undefined_body("echo_repaired"); } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/123.cf0000644000000000000000000000151615010704253022737 0ustar00rootroot00000000000000# Test a context defined in body classes with scope => bundle body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { processes: any:: "$(G.true)" classes => bundle_class; bundle_context:: "$(G.true)" classes => namespace_class; } body classes namespace_class { # default to namespace scoping promise_kept => { "namespace_context" }; } body classes bundle_class { scope => "bundle"; promise_kept => { "bundle_context" }; } bundle agent check { reports: namespace_context.!bundle_context:: "$(this.promise_filename) Pass"; bundle_context:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/116.cf0000644000000000000000000001030715010704253022737 0ustar00rootroot00000000000000####################################################### # # Test promise_kept and cancel_kept with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "0" }; repaired_returncodes => { "1" }; failed_returncodes => { "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/inherit_from_self.x.cf0000644000000000000000000000130615010704253026373 0ustar00rootroot00000000000000############################################################################## # # Redmine #4309: body inheritance with inherit_from # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle common test { reports: "foo" classes => classes_generic_nonesuch; } body classes classes_generic_nonesuch { inherit_from => classes_generic_nonesuch; } bundle agent check { methods: "" usebundle => dcs_passif_expected("any", "", $(this.promise_filename)), inherit => "true"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/inherit_from_with_global_var.cf0000644000000000000000000000216315010704253030341 0ustar00rootroot00000000000000####################################################### # # Test that bodies can inherit attributes containing global variables # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "class" string => "_pass"; } ####################################################### body classes parent(p) { promise_kept => { "${init.class}" }; } body classes static(p) { inherit_from => parent(p); } bundle agent test { meta: "description" -> { "CFE-4254" } string => "Test that bodies can inherit attributes containing global variables"; vars: "test" string => "test", classes => static("placeholder"); } ####################################################### bundle agent check { methods: _pass:: "pass" usebundle => dcs_pass("$(this.promise_filename)"); !_pass:: "pass" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/dynamic_inputs_findfiles.cf0000644000000000000000000000172415010704253027504 0ustar00rootroot00000000000000####################################################### # # Redmine#3315: Test dynamic inputs and bundlesequence # ####################################################### body common control { inputs => { "../../default.cf.sub", @(dynamic.inputs), }; bundlesequence => { dynamic, default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent dynamic { vars: "todo" slist => bundlesmatching(".*included"); "inputs" slist => findfiles("$(this.promise_filename).[s][u][b]"); methods: "run" usebundle => $(todo); reports: DEBUG:: "Found dynamic bundle: $(todo)"; } bundle agent init { } bundle agent test { } bundle agent check { classes: "ok" expression => "class_defined_from_included_bundle"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/002.cf0000644000000000000000000000150515010704253022731 0ustar00rootroot00000000000000# Test that log_failed and log_kept set to the same value do not cause stack overflow (Redmine #2317) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile).src" create => "yes"; "$(G.testfile).dest" create => "yes"; } bundle agent test { files: "$(G.testfile).dest" link_from => hard("$(G.testfile).src"), action => log; } body action log { log_failed => "$(G.testfile).action.log"; log_kept => "$(G.testfile).action.log"; log_string => ""; } body link_from hard(from) { source => "$(from)"; link_type => "hardlink"; } bundle agent check { reports: cfengine_3:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/109.cf0000644000000000000000000001131115010704253022735 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (correctly done!) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; "body2" string => "BEGIN One potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(init.body2)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/120.cf0000644000000000000000000001031515010704253022731 0ustar00rootroot00000000000000####################################################### # # Test overlapping codes with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "0", "1" }; repaired_returncodes => { "1" }; failed_returncodes => { "1", "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/0000755000000000000000000000000015010704253023551 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/218.cf0000644000000000000000000000717315010704253024405 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "0" }; repaired_returncodes => { "1" }; failed_returncodes => { "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile).missing" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/203.cf0000644000000000000000000000705415010704253024375 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired (different location in edit_line) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/225.cf0000644000000000000000000001042315010704253024373 0ustar00rootroot00000000000000####################################################### # # Test illegal codes (space in num) with command and *_returncodes (issue 751) # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "11", "13" }; repaired_returncodes => { "12" }; failed_returncodes => { " 1", "12" }; # Spaces in number should be ok } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/224.x.cf0000644000000000000000000001037715010704253024650 0ustar00rootroot00000000000000####################################################### # # Test illegal codes (> 255) with command and *_returncodes (issue 751) # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "11", "13" }; repaired_returncodes => { "12" }; failed_returncodes => { "1111", "12" }; # Must be <= 255 } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/217.cf0000644000000000000000000000720715010704253024402 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "0" }; repaired_returncodes => { "1" }; failed_returncodes => { "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/223.x.cf0000644000000000000000000001040515010704253024637 0ustar00rootroot00000000000000####################################################### # # Test illegal codes (negative num) with command and *_returncodes (issue 751) # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "cancel_kept" expression => "any"; "cancel_repaired" expression => "any"; "cancel_notkept" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "-1", "3" }; # Must be positive repaired_returncodes => { "12" }; failed_returncodes => { "11", "12" }; } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; MAIN.ok:: "$(this.promise_filename) Pass" report_to_file => "$(G.logfile)"; !ok:: "$(this.promise_filename) FAIL"; MAIN.!ok:: "$(this.promise_filename) FAIL" report_to_file => "$(G.logfile)"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/212.cf0000644000000000000000000000704015010704253024370 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" # create => "true", # file will not exist! edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => "ON"; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => ""; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/221.cf0000644000000000000000000000721215010704253024371 0ustar00rootroot00000000000000####################################################### # # Test overlapping codes (with no match) with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "10", "11" }; repaired_returncodes => { "11" }; failed_returncodes => { "11", "12" }; } ####################################################### bundle agent test { commands: "$(G.grep) linenotfound $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/204.cf0000644000000000000000000000705215010704253024374 0ustar00rootroot00000000000000####################################################### # # Test promise_kept and cancel_kept # Insert lines to a file, then verify that insert promise is kept # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" edit_line => init_insert("$(init.body)"), edit_defaults => init_empty, classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/215.cf0000644000000000000000000000702315010704253024374 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired with command and no *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/201.cf0000644000000000000000000000701315010704253024366 0ustar00rootroot00000000000000####################################################### # # Test promise_repaired and cancel_repaired # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty, classes => all_classes; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/213.cf0000644000000000000000000000716515010704253024401 0ustar00rootroot00000000000000####################################################### # # Test repair_failed and cancel_notkept (different location and results) # Insert lines to a file, verify that insert promise is repaired # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" # create => "true", # file will not exist! edit_line => init_insert("$(body)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)", # Promise never executed, so classes not set! classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/209.cf0000644000000000000000000001017115010704253024375 0ustar00rootroot00000000000000####################################################### # # Same as 105.cf, but two separate edit_line promises (correctly done!) # Test promise_kept+repaired and cancel_kept+repaired (multiple promises set classes) # Insert lines to a file (setting/clearing classes), verify that insert # promise is kept (which sets/clears more classes) # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "body" string => "BEGIN One potato Two potato Three potatoes Four END"; "body2" string => "BEGIN One potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"); } bundle edit_line init_insert(str) { insert_lines: "$(str)" classes => all_classes; } body edit_defaults init_empty { empty_file_before_editing => "true"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(init.body2)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: # NOTE: bundle edit_line init_insert(str) is CACHED, so even though it # is mentioned in init and we call test_insert from test, the promises are # the same, and are only executed ONCE, so it only sets the repaired # promises. "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/216.cf0000644000000000000000000000716715010704253024406 0ustar00rootroot00000000000000####################################################### # # Test promise_kept and cancel_kept with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "0" }; repaired_returncodes => { "1" }; failed_returncodes => { "2" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/219.cf0000644000000000000000000000714115010704253024401 0ustar00rootroot00000000000000####################################################### # # Test no classes set with command and *_returncodes # Insert lines to a file, the grep for a line which is there # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; "body" string => "BEGIN One potato Two potato Three potatoes Four END"; files: "$(G.testfile)" create => "true", edit_line => init_insert("$(body)"), edit_defaults => init_empty; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; kept_returncodes => { "1" }; repaired_returncodes => { "2" }; failed_returncodes => { "3" }; } ####################################################### bundle agent test { commands: "$(G.grep) BEGIN $(G.testfile)" classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => ""; "expect[promise_repaired]" string => ""; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => "ON"; "expect[cancel_repaired]" string => "ON"; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/staging/214.cf0000644000000000000000000000701115010704253024370 0ustar00rootroot00000000000000####################################################### # # Test setting two classes in one promise # Copy file with one mode, then copy again with different mode # # Present in both 00_basics/03_bodies and 10_files/05_classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile)" copy_from => local("$(G.etc_group)"), perms => mode("666"); } body copy_from local(f) { source => "$(f)"; } body perms mode(m) { mode => "$(m)"; } # These set/clear global classes, so they can be tested in another bundle body classes all_classes { promise_kept => { "promise_kept" }; promise_repaired => { "promise_repaired" }; repair_failed => { "repair_failed" }; repair_denied => { "repair_denied" }; repair_timeout => { "repair_timeout" }; cancel_kept => { "cancel_kept" }; cancel_repaired => { "cancel_repaired" }; cancel_notkept => { "cancel_notkept" }; } ####################################################### bundle agent test { files: "$(G.testfile)" copy_from => local("$(G.etc_group)"), # Same file perms => mode("644"), # Different mode classes => all_classes; } ####################################################### bundle agent check { # These variables determine the conditions being tested vars: "expect[promise_kept]" string => "ON"; "expect[promise_repaired]" string => "ON"; "expect[repair_failed]" string => ""; "expect[repair_denied]" string => ""; "expect[repair_timeout]" string => ""; "expect[cancel_kept]" string => ""; "expect[cancel_repaired]" string => ""; "expect[cancel_notkept]" string => "ON"; # Everything from here down is "boilerplate" to these 1xx.cf tests "lookfor" slist => { "promise_kept", "promise_repaired", "repair_failed", "repair_denied", "repair_timeout", "cancel_kept", "cancel_repaired", "cancel_notkept", }; classes: "p1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "$(lookfor)", }; "p2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "!$(lookfor)", }; "pass_$(lookfor)" xor => { "p1_$(lookfor)", "p2_$(lookfor)" }; "f1_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", "ON"), "!$(lookfor)", }; "f2_$(lookfor)" and => { strcmp("$(expect[$(lookfor)])", ""), "$(lookfor)", }; "f3_$(lookfor)" not => isvariable("expect[$(lookfor)]"); "fail_$(lookfor)" or => {"f1_$(lookfor)", "f2_$(lookfor)", "f3_$(lookfor)"}; "oops" expression => classmatch("fail.*"); "ok" and => { classmatch("pass.*"), "!oops" }; reports: DEBUG:: "ok: class '$(lookfor)' was set (should be)" if => "p1_$(lookfor)"; "ok: class '$(lookfor)' was not set (should not be)" if => "p2_$(lookfor)"; "ERROR: class '$(lookfor)' WAS NOT set (should be)" if => "f1_$(lookfor)"; "ERROR: class '$(lookfor)' was set (should NOT be)" if => "f2_$(lookfor)"; "ERROR: missing variable expect['$(lookfor)']" if => "f3_$(lookfor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/multilevel_inherit_from_parameters.cf0000644000000000000000000000176515010704253031612 0ustar00rootroot00000000000000############################################################################## # # Redmine #4309: parameterized 2-level body inheritance with inherit_from # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle common test { reports: "test_inherit" classes => scoped_classes_generic_none2_inherit(); } body classes scoped_classes_generic_none_inherit { inherit_from => scoped_classes_generic("namespace", "test_inherit_none"); } body classes scoped_classes_generic_none2_inherit { inherit_from => scoped_classes_generic_none_inherit; } bundle agent check { methods: "" usebundle => dcs_passif_expected("test_inherit_none_ok", "", $(this.promise_filename)), inherit => "true"; } cfengine-3.24.2/tests/acceptance/00_basics/03_bodies/ifvarclass-with-function.cf0000644000000000000000000000256315010704253027366 0ustar00rootroot00000000000000# Verify that functions returns are interpreted correctly in ifvarclass # Redmine 6327 body common control { AUTO:: inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; !AUTO:: bundlesequence => { "init", "check" }; } bundle agent init { vars: "always" string => "any"; "never" string => "!any"; } bundle agent check { classes: # yes "variable_with_set_class" expression => "any", ifvarclass => canonify("$(init.always)"); # no "variable_with_unset_class" expression => "any", ifvarclass => canonify("$(init.never)"); "just_a_class" expression => "any", ifvarclass => not("any"); "undefined_variable" expression => "any", ifvarclass => canonify("$(init.unknown)"); "undefined_bundle" expression => "any", ifvarclass => canonify("$(never.never)"); "invalid_function" expression => "any", ifvarclass => now(); "fail" expression => "variable_with_unset_class|just_a_class|undefined_variable|undefined_bundle|invalid_function"; "ok" and => { "variable_with_set_class", "!fail" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG.just_a_class:: "just_a_class"; DEBUG.undefined_variable:: "undefined_variable"; DEBUG.undefined_bundle:: "undefined_bundle"; DEBUG.invalid_function:: "invalid_function"; } cfengine-3.24.2/tests/acceptance/00_basics/linesep.cf0000644000000000000000000000104115010704253022313 0ustar00rootroot00000000000000body common control { bundlesequence => { "test", "check" }; version => "1.0"; } bundle agent test { meta: "description" -> { "ENT-10432" } string => "Test platform-agnostic linesep constant"; } bundle agent check { classes: windows:: "ok" expression => strcmp("$(const.linesep)", "$(const.r)$(const.n)"); !windows:: "ok" expression => strcmp("$(const.linesep)", "$(const.n)"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/0000755000000000000000000000000015010704253022460 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/001.cf0000644000000000000000000000244415010704253023276 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile).SOURCE" create => "true"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", link_from => test_link; meta: "test_suppress_fail" string => "windows", meta => { "redmine4608" }; } body link_from test_link { source => "$(G.testfile).SOURCE"; link_type => "hardlink"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/800.cf0000644000000000000000000000210315010704253023275 0ustar00rootroot00000000000000####################################################### # # Test whether parsing of /etc/issue works on Debian # (Acceptance test for redmine #2988) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } ####################################################### bundle agent test { vars: debian:: "myflavor" string => execresult("/bin/grep Debian.*GNU /etc/issue | /usr/bin/cut -d' ' -f3 | cut -d. -f1 | cut -d/ -f1", "useshell"); } ####################################################### bundle agent check { classes: debian.!ubuntu:: "ok" expression => strcmp("$(sys.flavor)", "debian_$(test.myflavor)"); ubuntu:: "ok" expression => "any"; !debian:: "ok" expression => "any"; reports: DEBUG:: "Compared $(sys.flavor) to debian_$(test.myflavor)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/019.cf0000644000000000000000000000222015010704253023277 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { action_policy => "warn"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; "This test should not create $(G.testfile)"; ok:: "$(this.promise_filename) FAIL"; !ok:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/string_contexts_rval.cf0000644000000000000000000000064615010704253027261 0ustar00rootroot00000000000000# fixes https://dev.cfengine.com/issues/2504 using variables in string # contexts when a promise has a previous if *with a FnCall* body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { } bundle agent check { reports: "any":: "$(this.promise_filename) Pass" if => and("any"); } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/034.x.cf0000644000000000000000000000171615010704253023553 0ustar00rootroot00000000000000###################################################### # # Issue 375 (duplicate, to preserve pattern of 5) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "banana"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/104.cf0000644000000000000000000000062215010704253023276 0ustar00rootroot00000000000000# Check that it's OK to have an empty list in inputs body common control { inputs => { @(g.inputs) }; bundlesequence => { check }; version => "1.0"; } bundle common g { vars: "inputs" slist => { }; } bundle agent check { reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; any:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/710.x.cf0000644000000000000000000000170415010704253023551 0ustar00rootroot00000000000000####################################################### # # Related to bug introduced in core r1900 - allowed any body constraint name # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { files: "$(G.testdir)/shouldnotexist" create => "true", nonexistent_attribute => "abc"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testdir)/shouldnotexist"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/depends_on_canonify.cf0000644000000000000000000000117315010704253027000 0ustar00rootroot00000000000000# Test depends_on with a canonify() function call body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { classes: # this works "foo1" expression => "any", depends_on => { canonify($(G.testfile)) }; methods: "" usebundle => test2($(G.testfile)); } bundle agent test2(file) { classes: # this fails "foo2" expression => "any", depends_on => { canonify($(file)) }; } bundle agent check { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/101.cf0000644000000000000000000000160215010704253023272 0ustar00rootroot00000000000000###################################################### # # Test that \ expands correctly by eating newline (Issue 696) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "mystring" string => "some\ thing"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("$(test.mystring)", "something"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "$(test.subout)"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/cf-promises-common-bundles-only.cf0000644000000000000000000000162315010704253031122 0ustar00rootroot00000000000000############################################################################## # # Redmine #3576: cf-promises should not run agent bundles # NOTE: changed to if --eval-functions=no # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_promises) --eval-functions=no -v -f $(this.promise_filename).sub | $(G.grep) PURPLE", "useshell"); } bundle agent check { # If the output contains the string, we fail classes: "ok1" not => regcmp(".*PURPLE_DINOSAUR.*", "$(test.subout)"); "ok" and => { "ok1" }; reports: DEBUG:: "PURPLE TEST: $(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/with_iteration.cf.expected.json0000644000000000000000000000132715010704253030576 0ustar00rootroot00000000000000{ "Apromiser_addition": "promiser addition = promiser_addition", "Bclean": "clean = clean", "Cmy_name_is_canonified": "my name is = my_name_is_canonified", "D11": "iter1 = 1", "D12": "iter1 = 2", "D13": "iter1 = 3", "D21": "iter2 = 1", "D22": "iter2 = 2", "D23": "iter2 = 3", "E0": "probe = 0", "Fiter_canon_1": "iter = iter_canon_1", "Fiter_canon_2": "iter = iter_canon_2", "Fiter_canon_3": "iter = iter_canon_3", "G1iter_canon_1": "iter = iter_canon_1", "G1iter_canon_2": "iter = iter_canon_2", "G1iter_canon_3": "iter = iter_canon_3", "G21": "iter = 1", "G22": "iter = 2", "G23": "iter = 3", "H": "{ \"1\", \"2\", \"3\" }", "iter": [ "1", "2", "3" ], "probe": "0" } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/014.x.cf0000644000000000000000000000200015010704253023534 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { log_priority => "banana"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/007.cf0000644000000000000000000000213415010704253023300 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { log_level => "verbose"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/with_iteration.cf0000644000000000000000000000304615010704253026026 0ustar00rootroot00000000000000########################################################### # # Test the "with" promise attribute # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: "probe" string => "0"; "iter" slist => { "1", "2", "3" }; "A$(with)" string => "promiser addition = $(with)", with => canonify(concat("promiser ", canonify("addition"))); "B$(with)" string => "clean = $(with)", with => canonify("clean"); "C$(with)" string => "my name is = $(with)", with => canonify("my name is canonified"); "D1$(with)" string => "iter1 = $(with)", with => $(iter); "D2$(with)" string => "iter2 = $(with)", with => $(iter); "E$(with)" string => "probe = $(with)", with => $(probe); "F$(with)" string => "iter = $(with)", with => concat("iter_canon_", canonify($(iter))); "G1$(with)" string => "iter = $(with)", with => concat("iter_canon_", canonify($(iter))); "G2$(with)" string => "iter = $(with)", with => canonify($(iter)); "H" string => "$(with)", with => format("%S", iter); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/105.cf0000644000000000000000000000050615010704253023300 0ustar00rootroot00000000000000# Check that empty bundles work (Redmine #2411) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { } bundle agent check { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/003.x.cf0000644000000000000000000000212515010704253023542 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "type" string => "banana"; files: "$(G.testfile)" move_obstructions => "true", link_from => test_link; } body link_from test_link { source => "$(G.etc_motd)"; link_type => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/031.cf0000644000000000000000000000200415010704253023271 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/cf-promises-json-long-strings.cf0000644000000000000000000000135715010704253030622 0ustar00rootroot00000000000000# Test that cf-promises doesn't fail if ppkeys are missing body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "2.0"; } bundle agent test { meta: "description" -> { "CFE-2383", "CFE-2310" } string => "Test that json representation of policy is not truncated."; vars: "output" string => execresult( "$(sys.cf_promises) -p json -f $(this.promise_filename).sub", "noshell" ); } bundle agent check { classes: "validated_ok" expression => regcmp( ".*endflag.*", $(test.output) ); reports: validated_ok:: "$(this.promise_filename) Pass"; !validated_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/004.x.cf0000644000000000000000000000207415010704253023546 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", link_from => test_link("banana"); } body link_from test_link(type) { source => "$(G.etc_motd)"; link_type => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/no_error_when_key_contains_space.cf0000644000000000000000000000320615010704253031562 0ustar00rootroot00000000000000# This test should be renamed from .x.cf to .cf when the bug is fixed. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3320" } string => "Test that data container keys can contain spaces"; vars: "d" data => '{ "thing s": [ { "Title": "ExpectedPick", "classexpr": "$(sys.class)" } ] }'; "selected" string => "$(d[thing s][0][Title])", if => "$(d[thing s][0][classexpr])"; # Note: wrapping with concat or classify prevents the error # if => concat("$(d[thing s][$(di)][classexpr])"); # if => classify("$(d[thing s][$(di)][classexpr])"); "sanity_check" string => "You are sane", if => "$(sys.class)"; reports: EXTRA|DEBUG:: "See iteration/expansion: $(d[thing s][ExpectedPick][Title]) has classexpr $(d[thing s][ExpectedPick][classexpr])"; "See sanity_check: $(sanity_check) because $(sys.class) is a defined class"; "Picked: $(d[thing s][ExpectedPick][Title]) has classexpr $(d[thing s][ExpectedPick][classexpr])" if => "$(d[thing s][ExpectedPick][classexpr])"; } ####################################################### bundle agent check { vars: "expected_selection" string => "ExpectedPick"; methods: "Pass/Fail" usebundle => dcs_check_strcmp($(expected_selection), $(test.selected), $(this.promise_filename), "no"); } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/trailing_comma_arglist.cf0000644000000000000000000000034715010704253027510 0ustar00rootroot00000000000000body common control { bundlesequence => { "test" }; } bundle agent test { methods: "check" usebundle => check("a", "b", "c"); } bundle agent check(a, b, c,) { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/020.x.cf0000644000000000000000000000200115010704253023532 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { action_policy => "banana"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/041.x.cf0000644000000000000000000000213315010704253023543 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { promise_repaired => { "ok" }; persist_time => "$(type)"; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/100.cf.sub0000644000000000000000000000021115010704253024054 0ustar00rootroot00000000000000body common control { bundlesequence => { 'test' }; } bundle agent test { files: "/tmp/foobar" comment => "${this.promiser}"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/100.cf0000644000000000000000000000215215010704253023272 0ustar00rootroot00000000000000###################################################### # # Test that ${this.promiser} is expanded in comments (Issue 691) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kvf $(this.promise_filename).sub | grep Comment", "useshell"); meta: "test_skip_needs_work" string => "windows"; } ####################################################### bundle agent check { classes: "ok1" not => regcmp(".*this\.promiser.*", "$(test.subout)"); "ok2" expression => regcmp(".*foobar.*", "$(test.subout)"); "ok" and => { "ok1", "ok2" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "$(test.subout)"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/032.x.cf0000644000000000000000000000165015010704253023546 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "banana"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/025.cf0000644000000000000000000000213715010704253023303 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { report_level => "verbose"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/040.x.cf0000644000000000000000000000170315010704253023544 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action("banana"); } body action test_action(type) { promise_repaired => { "ok" }; persist_time => "$(type)"; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/103.cf0000644000000000000000000000060115010704253023272 0ustar00rootroot00000000000000# Check that empty input lists work body common control { inputs => { @(g.inputs) }; bundlesequence => { check }; version => "1.0"; } bundle common g { vars: "inputs" slist => { }; } bundle agent check { reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; any:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/042.x.cf0000644000000000000000000000225015010704253023544 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { promise_repaired => { "ok" }; persist_time => "$(type)"; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/cf-promises-99999999999.cf0000644000000000000000000000341215010704253026461 0ustar00rootroot00000000000000####################################################### # # Related to redmine #6531 # # In short, on 32-bit platforms the maximum number that cf-agent # understands is LONG_MAX. However the number "99999999999" (eleven # nines) has been historically used in many places, so this test makes # sure that it's still being accepted, even though on 32-bit platforms # it will be truncated to LONG_MAX. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### # With this body we're making sure cf-promises won't bail out on # this. This is exactly the body that cf-promises was rejecting before # the fix. body classes u_always_forever(theclass) { persist_time => 99999999999; } ####################################################### bundle agent init { vars: # truncation will happen on 32-bit architectures "x" int => "99999999999"; "y" int => "-99999999999"; } bundle agent test { classes: "x_ok" or => { strcmp("$(init.x)", "99999999999"), # 64-bit arch strcmp("$(init.x)", "2147483647") # 32-bit arch }, scope => "namespace"; "y_ok" or => { strcmp("$(init.y)", "-99999999999"), # 64-bit arch strcmp("$(init.y)", "-2147483648") # 32-bit arch }, scope => "namespace"; } bundle agent check { reports: DEBUG:: "x is $(init.x), should be 99999999999 or LONG_MAX"; "y is $(init.y), should be -99999999999 or LONG_MIN"; x_ok.y_ok:: "$(this.promise_filename) Pass"; !x_ok|!y_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/044.x.cf0000644000000000000000000000171615010704253023554 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { guest_environments: "host1" environment_host => "...com._", classes => whatever("ok"); } body classes whatever(c) { promise_kept => { "$(c)" }; promise_repaired => { "$(c)" }; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/033.x.cf0000644000000000000000000000172315010704253023550 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "type" string => "banana"; files: "$(G.testfile)" create => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/classes_without_constraints.cf0000644000000000000000000000107015010704253030637 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2000" } string => "Test that classes can be defined without any constraints/attributes"; classes: "supercalifragilisticexpialidocious"; reports: supercalifragilisticexpialidocious:: "$(this.promise_filename) Pass"; !supercalifragilisticexpialidocious:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/README0000644000000000000000000000100115010704253023330 0ustar00rootroot000000000000000*.cf: This suite of tests is essentially 5 different tests repeated for various attributes. 1) prove that the test case works 2) show that it fails as expected with an illegal value 3) attempt to show failure when that illegal value is a parameter to the body 4) attempt to show failure when that illegal value is a parameter to the bundle 5) attempt to show failure when that illegal value is a parameter to a method 7*.cf: These tests are slightly different, but also address issues in constraint checking cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/double_comma_arglist.x.cf0000644000000000000000000000034715010704253027417 0ustar00rootroot00000000000000body common control { bundlesequence => { "test" }; } bundle agent test { methods: "check" usebundle => check("a", "b", "c"); } bundle agent check(a, b,, c) { reports: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/string_contexts.cf.expected.json0000644000000000000000000000137415010704253031004 0ustar00rootroot00000000000000{ "iterated_a": "iteration class a", "iterated_b": "iteration class b", "iterated_c": "iteration class c", "myclass": "any", "mylist": [ "a", "b", "c" ], "myvar": "me", "s1": "hello, this is me", "s2": "any hello", "s3": "string hello", "s4": "variable context hello!!!", "s4_2": "variable context hello!!!", "s5": "compound variable context hello!!!", "s6": "6", "s7": "augmented variable context hello!!!", "s8": "8", "whitespace1": "whitespace1: quoted with spaces", "whitespace2": "whitespace2: unquoted with spaces, starts with valid class", "whitespace4": "whitespace4: unquoted with spaces, starts with missing class but is true", "whitespace5": "whitespace5: remove spaces and tabs from an expression" } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/leading_comma_arglist.x.cf0000644000000000000000000000035015010704253027542 0ustar00rootroot00000000000000body common control { bundlesequence => { "test" }; } bundle agent test { methods: "check" usebundle => check("a", "b", "c"); } bundle agent check(, a, b, c) { reports: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/cf-promises-json-long-strings.cf.sub0000644000000000000000000000420215010704253031402 0ustar00rootroot00000000000000bundle agent main { vars: "content" string => "flag This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan This is a file template containing variables to expan endflag"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/704.x.cf0000644000000000000000000000217115010704253023553 0ustar00rootroot00000000000000####################################################### # # Related to Issue 377 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { processes: ".*" process_select => test_plain, signals => { "child" }; } body process_select test_plain { command => "should-never-find-this"; process_result => "command|bfd.pms.wtf!"; # Illegal test names } ####################################################### bundle agent check { vars: "count" string => execresult("$(G.wc) $(test.counter)", "noshell"); classes: "ok" expression => regcmp("\s*3\s.*", "$(count)"); reports: DEBUG:: "Expected to crash - illegal test names"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/cf-promises-common-bundles-only.cf.sub0000644000000000000000000000023715010704253031712 0ustar00rootroot00000000000000body common control { bundlesequence => { runme }; } bundle agent runme { vars: "x" string => execresult("/bin/echo PURPLE_DINOSAUR", "noshell"); } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/string_contexts.x.cf0000644000000000000000000000116515010704253026500 0ustar00rootroot00000000000000# fixes https://dev.cfengine.com/issues/2504 # using variables in string contexts # should fail: class names in string contexts must be separated by operators body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { reports: cf e ngine:: "hello"; cf engine:: "hello"; } ####################################################### bundle agent check { methods: "check" usebundle => dcs_pass($(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/200.x.cf0000644000000000000000000002117015010704253023542 0ustar00rootroot00000000000000# # Test that overlong identifier fails # body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } # 8192 symbols bundle agent xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/026.x.cf0000644000000000000000000000200015010704253023537 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { report_level => "banana"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/002.x.cf0000644000000000000000000000205215010704253023540 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" move_obstructions => "true", link_from => test_link; } body link_from test_link { source => "$(G.etc_motd)"; link_type => "banana"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/013.cf0000644000000000000000000000213515010704253023276 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { log_priority => "alert"; } ####################################################### bundle agent check { classes: "ok" expression => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/0000755000000000000000000000000015010704253024114 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/022.x.cf0000644000000000000000000000173315010704253025203 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action("banana"); } body action test_action(type) { action_policy => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/701.x.cf0000644000000000000000000000267715010704253025217 0ustar00rootroot00000000000000####################################################### # # Issue 377 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "files" slist => { "1", "2", "3" }; files: "$(G.testdir)/." create => "true"; "$(G.testdir)/$(files)" copy_from => init_copy("$(G.etc_group)"); } body copy_from init_copy(file) { source => "$(file)"; } ####################################################### bundle agent test { vars: "counter" string => "$(G.testdir)/counter"; files: "$(G.testdir)" transformer => "/bin/sh -c 'echo $(this.promiser) >> $(counter)'", file_select => test_plain, depth_search => test_recurse; } body file_select test_plain { file_types => { "plain" }; file_result => "file_types|bfd.pms.wtf!"; # Illegal test names } body depth_search test_recurse { depth => "inf"; } ####################################################### bundle agent check { vars: "count" string => execresult("$(G.wc) $(test.counter)", "noshell"); classes: "ok" expression => regcmp("\s*3\s.*", "$(count)"); reports: DEBUG:: "3 transformations expected, saw '$(count)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/036.x.cf0000644000000000000000000000212615010704253025205 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { files: "$(G.testfile)" create => "$(val)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/027.x.cf0000644000000000000000000000176415010704253025214 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "type" string => "banana"; files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { report_level => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/029.x.cf0000644000000000000000000000216215010704253025207 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { report_level => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/035.x.cf0000644000000000000000000000201115010704253025175 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { files: "$(G.testfile)" create => "$(val)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/702.x.cf0000644000000000000000000000142615010704253025207 0ustar00rootroot00000000000000####################################################### # # Issue 378 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; syslog_host => "...com..._"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" expression => "any"; reports: DEBUG:: "This is expected to crash"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/047.x.cf0000644000000000000000000000214615010704253025211 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("...com._"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { guest_environments: "host1" environment_host => "$(val)", classes => whatever("ok"); } body classes whatever(c) { promise_kept => { "$(c)" }; promise_repaired => { "$(c)" }; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/006.x.cf0000644000000000000000000000235215010704253025203 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { files: "$(G.testfile)" move_obstructions => "true", link_from => test_link("$(val)"); } body link_from test_link(type) { source => "$(G.etc_motd)"; link_type => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/012.x.cf0000644000000000000000000000227415010704253025203 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { log_level => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/011.x.cf0000644000000000000000000000215715010704253025202 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { log_level => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/703.x.cf0000644000000000000000000000146215010704253025210 0ustar00rootroot00000000000000####################################################### # # Issue 378 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { bindtointerface => "...com..._"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: "ok" expression => "any"; reports: DEBUG:: "This is expected to crash"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/048.x.cf0000644000000000000000000000226315010704253025212 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("...com._"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { guest_environments: "host1" environment_host => "$(val)", classes => whatever("ok"); } body classes whatever(c) { promise_kept => { "$(c)" }; promise_repaired => { "$(c)" }; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/028.x.cf0000644000000000000000000000173215010704253025210 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action("banana"); } body action test_action(type) { report_level => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/024.x.cf0000644000000000000000000000230015010704253025174 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { action_policy => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/016.x.cf0000644000000000000000000000173215010704253025205 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action("banana"); } body action test_action(type) { log_priority => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/030.x.cf0000644000000000000000000000227715010704253025206 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { report_level => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/009.x.cf0000644000000000000000000000176315010704253025213 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "type" string => "banana"; files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { log_level => "$(g.type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/023.x.cf0000644000000000000000000000216315010704253025202 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { action_policy => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/046.x.cf0000644000000000000000000000176015010704253025211 0ustar00rootroot00000000000000###################################################### # # Issue 375 (duplicate, to with pattern of 6) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { guest_environments: "host1" environment_host => "...com._", classes => whatever("ok"); } body classes whatever(c) { promise_kept => { "$(c)" }; promise_repaired => { "$(c)" }; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/021.x.cf0000644000000000000000000000176515010704253025207 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "type" string => "banana"; files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { action_policy => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/018.x.cf0000644000000000000000000000227715010704253025214 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(v) { methods: "any" usebundle => do_test(v); } bundle agent do_test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { log_priority => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/017.x.cf0000644000000000000000000000216215010704253025204 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { files: "$(G.testfile)" create => "true", action => test_action("$(val)"); } body action test_action(type) { log_priority => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/010.x.cf0000644000000000000000000000172715010704253025203 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action("banana"); } body action test_action(type) { log_level => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/039.x.cf0000644000000000000000000000214615010704253025212 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("...com._"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { guest_environments: "host1" environment_host => "$(val)", classes => whatever("ok"); } body classes whatever(c) { promise_kept => { "$(c)" }; promise_repaired => { "$(c)" }; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/005.x.cf0000644000000000000000000000223515010704253025202 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### # This test falls out of the usual test-syntax, because 1) It is designed to # fail and 2) Two of the set of tests requires a non-standard bundlesequence body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { init, test("banana"), check }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test(val) { files: "$(G.testfile)" move_obstructions => "true", link_from => test_link("$(val)"); } body link_from test_link(type) { source => "$(G.etc_motd)"; link_type => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/015.x.cf0000644000000000000000000000176415010704253025211 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "type" string => "banana"; files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { log_priority => "$(type)"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/staging/043.cf0000644000000000000000000000204215010704253024732 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { guest_environments: "host1" environment_host => "test", classes => whatever("ok"); } body classes whatever(c) { promise_kept => { "$(c)" }; promise_repaired => { "$(c)" }; } ####################################################### bundle agent check { reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/102.x.cf0000644000000000000000000000055615010704253023550 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { reports: cfengine_3:: "$()"; } bundle agent check { cfengine_3:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/037.cf0000644000000000000000000000207615010704253023310 0ustar00rootroot00000000000000###################################################### # # Issue 375 setup (precursor to actual tickle of bug) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", classes => test_action; } body classes test_action { promise_repaired => { "ok" }; persist_time => "10"; } ####################################################### bundle agent check { reports: DEBUG:: "This test should pass as a precursor to a bunch of related failures"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/038.x.cf0000644000000000000000000000175115010704253023556 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { promise_repaired => { "ok" }; persist_time => "banana"; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/string_contexts.cf0000644000000000000000000000516515010704253026236 0ustar00rootroot00000000000000# fixes https://dev.cfengine.com/issues/2504 # using variables in string contexts body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { defaults: "s1" string => "1"; "s2" string => "2"; "s3" string => "3"; "s4" string => "4"; "s5" string => "5"; "s6" string => "6"; "s7" string => "7"; "s8" string => "8"; classes: "$(mylist)" expression => "any"; vars: "mylist" slist => { "a", "b", "c" }; "myvar" string => "me"; "myclass" string => "any"; "s1" string => "hello, this is $(myvar)", if => "$(myclass)"; any:: "s2" string => "any hello"; 'any':: "s3" string => "string hello"; "$(myclass)":: "s4" string => "variable context hello!!!"; "s4_2" string => "variable context hello!!!"; "$(myclass).any":: "s5" string => "compound variable context hello!!!"; "not$(myclass)":: "s6" string => "BAD variable context hello!!!"; "$(myclass)":: "s7" string => "augmented variable context hello!!!", if => "any"; "$(myclass)":: "s8" string => "BAD augmented variable context hello!!!", if => "nonesuch"; "$(mylist).cfengine":: "iterated_$(mylist)" string => "iteration class $(mylist)"; "myclass . cfengine | any":: "whitespace1" string => "$(this.promiser): quoted with spaces"; myclass . cfengine | any:: "whitespace2" string => "$(this.promiser): unquoted with spaces, starts with valid class"; nosuchclass . any:: "whitespace3" string => "$(this.promiser): unquoted with spaces, should be missing"; nosuchclass | any:: "whitespace4" string => "$(this.promiser): unquoted with spaces, starts with missing class but is true"; any | ( cfengine | linux ):: "whitespace5" string => "$(this.promiser): remove spaces and tabs from an expression"; any . ( nosuchclass . any ):: "whitespace6" string => "$(this.promiser): remove spaces and tabs from an expression that is false in the end, should be missing"; "cf engine":: "whitespace7" string => "$(this.promiser): quoted with spaces but no operators, should be missing with an error"; } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/008.x.cf0000644000000000000000000000177515010704253023561 0ustar00rootroot00000000000000###################################################### # # Issue 375 # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { files: "$(G.testfile)" create => "true", action => test_action; } body action test_action { log_level => "banana"; } ####################################################### bundle agent check { classes: "ok" not => fileexists("$(G.testfile)"); reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/045.x.cf0000644000000000000000000000176015010704253023554 0ustar00rootroot00000000000000###################################################### # # Issue 375 (duplicate, to with pattern of 6) # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { guest_environments: "host1" environment_host => "...com._", classes => whatever("ok"); } body classes whatever(c) { promise_kept => { "$(c)" }; promise_repaired => { "$(c)" }; } ####################################################### bundle agent check { reports: DEBUG:: "This test should fail"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/cf-promises-without-ppkeys.cf0000644000000000000000000000117115010704253030233 0ustar00rootroot00000000000000# Test that cf-promises doesn't fail if ppkeys are missing body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { methods: "clear ppkeys" usebundle => dcs_fini("$(sys.workdir)/ppkeys"); } bundle agent test { commands: "$(sys.cf_promises) -f $(this.promise_filename)" classes => scoped_classes_generic("namespace", "validated"); } bundle agent check { reports: validated_ok:: "$(this.promise_filename) Pass"; validated_not_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/01_compiler/depends_on.cf0000644000000000000000000000333715010704253025116 0ustar00rootroot00000000000000# Test depends_on body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "expandit" slist => { "hc2" }; methods: "zebra" usebundle => zebra:zebra; classes: "c1" expression => "any", scope => "namespace", handle => "hc1", depends_on => { }; "c2" expression => "any", scope => "namespace", handle => "hc2", depends_on => { "hc1", "me2" }; "c3" expression => "any", scope => "namespace", handle => "hc3", depends_on => { "$(expandit)" }; "c4" expression => "any", scope => "namespace", handle => "hc4", depends_on => { "nosuchhandle" }; "c5" expression => "any", scope => "namespace", handle => "hc5", depends_on => { "zebra.zebra" }; "c6" expression => "any", scope => "namespace", handle => "hc6", depends_on => { "zebra:zebra" }; reports: "me too" handle => "me2"; } bundle agent check { classes: "ok" and => { "c1", "c2", "c3", "!c4", "!c5", "!c6", }; reports: DEBUG.!c1:: "bad: c1 was NOT defined"; DEBUG.!c2:: "bad: c2 was NOT defined"; DEBUG.!c3:: "bad: c3 was NOT defined"; DEBUG.c4:: "bad: c4 WAS defined"; DEBUG.c5:: "bad: c5 WAS defined"; DEBUG.c6:: "bad: c6 WAS defined"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } body file control { namespace => "zebra"; } bundle agent zebra { classes: "zebra" expression => "any", scope => "namespace", handle => "zebra"; } cfengine-3.24.2/tests/acceptance/00_basics/def.json/0000755000000000000000000000000015010704253022054 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_with_bundle.cf.json0000644000000000000000000000023115010704253027666 0ustar00rootroot00000000000000{ "variables": { "config.test_variable": { "value": "37bff81c825bd57a613ff4770b7a0679ff147bdf", "tags": ["test_tag"] } } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/classes_with_ns_tags.cf0000644000000000000000000000207115010704253026574 0ustar00rootroot00000000000000# basic test of the def.json facility: classes with namespace specification and tags body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9\s+test_tag,source=augments_file\s+comment1.+my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9_2\s+test_tag,source=augments_file\s+comment2", "my_ns2:test_class_cfengine_and_cfengine_version\s+test_tag2,source=augments_file", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_bare_array.cf.json0000644000000000000000000000011415010704253027471 0ustar00rootroot00000000000000{ "variables": { "bare_test_array": ["bare_test_array_element"] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/state.cf0000644000000000000000000000123215010704253023504 0ustar00rootroot00000000000000# full test of the def.json facility body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(def, "$(this.promise_filename).expected.json", $(this.promise_filename)); reports: "augments policy = $(this.promise_filename)"; "domain = $(def.domain)"; } cfengine-3.24.2/tests/acceptance/00_basics/def.json/show_vars_JSON.cf0000644000000000000000000000154015010704253025232 0ustar00rootroot00000000000000# basic test of the def.json facility: classes body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -w $(sys.workdir)|$(G.grep) test_var"; methods: "" usebundle => dcs_passif_output('default:def.test_var\\s+\\{"387c108886725091c6fe2433a9fcafa0820dd61f":\\["8e92eeab70dbef876aeac9d97a74cfdde6f53e86"\\]\\}.*', "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/policy_server_classes.cf0000644000000000000000000000170015010704253026766 0ustar00rootroot00000000000000# basic test of the def.json facility: classes body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_make("$(sys.statedir)/am_policy_hub", ''); "" usebundle => file_make("$(sys.workdir)/policy_server.dat", 'fake-server'); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("test_class_policy_server\s+source=augments_file", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/classes_with_ns.cf0000644000000000000000000000177615010704253025571 0ustar00rootroot00000000000000# basic test of the def.json facility: classes with namespace specification body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9\s+source=augments_file.+my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9_2\s+source=augments_file", "my_ns2:test_class_cfengine_and_cfengine_version\s+source=augments_file", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments.cf0000644000000000000000000000223615010704253024214 0ustar00rootroot00000000000000# basic test of the def.json facility: augments body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ' body common control { inputs => { "@(def.inputs)" }; } '); "" usebundle => file_make("$(sys.inputdir)/secondary.cf", ' bundle common x { classes: "test_class_f03ab8289d0775ca821b39a724c6f6f08ef8fb17" expression => "any"; } '); "" usebundle => file_copy("$(this.promise_filename).augmenter.json", "$(sys.inputdir)/augmenter.json"); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("test_class_f03ab8289d0775ca821b39a724c6f6f08ef8fb17\s+source=promise", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/vars_with_ns.cf0000644000000000000000000000157015010704253025077 0ustar00rootroot00000000000000# basic test of the def.json facility: vars with namespace and bundle specification body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf|$(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output("my_ns:config.test_variable\s+37bff81c825bd57a613ff4770b7a0679ff147bdf\s+source=augments_file", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/class_from_classexpression.cf0000644000000000000000000000345415010704253030031 0ustar00rootroot00000000000000# basic test of the def.json facility: augments body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-2971" } string => "Test that class expressions can be used to define classes via augments"; methods: "Test all expected classes defined from augments" usebundle => file_make("$(sys.inputdir)/promises.cf", ' bundle agent main { classes: "pass" and => { "augments_class_from_regex", "augments_class_from_single_class_as_regex", "augments_class_from_single_class_as_expression", "augments_class_from_classexpression_and", "augments_class_from_classexpression_not", "augments_class_from_classexpression_or", "augments_class_from_classexpression_complex", }; reports: pass:: "PASS: All expected classes found"; !pass:: "FAIL: Not all expected classes found"; } '); "Place Augments for test" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) --show-evaluated-classes=augments_classes_from_ -f $(sys.inputdir)/promises.cf|$(G.grep) PASS"; methods: "PASS/FAIL" usebundle => dcs_passif_output(".*PASS.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments_classes/0000755000000000000000000000000015010704253025414 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments_classes/augments_classes.cf0000644000000000000000000000261715010704253031274 0ustar00rootroot00000000000000# basic test of the def.json facility: augments body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-2956" } string => "Test that negative lookahead works as expected, when what is being looked for is defined from augments earlier."; "test_soft_fail" string => "any", meta => { "CFE-2956" }; vars: "expect_defined" slist => { "MY_ALWAYS", "BECAUSE_MY_ALWAYS", "BECAUSE_MISSING_ABSENT" }; "expect_undefined" slist => { "BECAUSE_MY_ALWAYS_ABSENT" }; classes: # When all expect_defined are found and none of the expect_undefined are found. "pass" expression => concat( "(", join( ".", expect_defined ), ").!(", join( "|", expect_undefined), ")" ); reports: "$(this.promise_filename) $(with)" with => ifelse( "pass", "Pass", "FAIL" ); DEBUG|EXTRA:: "Expected $(expect_defined) to be defined, but was not." unless => "$(expect_defined)"; "Found $(expect_defined) to be defined, as expected." if => "$(expect_defined)"; "Expected $(expect_undefined) to not be defined, but was." if => "$(expect_undefined)"; "Found $(expect_undefined) to not be defined, as expected." unless => "$(expect_undefined)"; } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments_classes/def.json0000644000000000000000000000032715010704253027047 0ustar00rootroot00000000000000{ "classes": { "MY_ALWAYS": [ "cfengine" ], "BECAUSE_MY_ALWAYS": [ "MY_ALWAYS" ], "BECAUSE_MISSING_ABSENT": [ "^(?!MISSING).*" ], "BECAUSE_MY_ALWAYS_ABSENT": [ "^(?!MY_ALWAYS).*" ] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/def_preferred.json/0000755000000000000000000000000015010704253025620 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/def_preferred.json/def_preferred.json0000644000000000000000000000005415010704253031306 0ustar00rootroot00000000000000{ "vars": { "good_var": "foo" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/def_preferred.json/def_preferred.cf0000644000000000000000000000204415010704253030726 0ustar00rootroot00000000000000body common control { # Feel free to avoid including "default.cf.sub" and define your # own bundlesequence for simple tests inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init # Initialize the environment and prepare for test { } bundle agent test # Activate policy for behaviour you wish to inspect { meta: "description" -> { "CFE-3656" } string => "def_preferred.json is preferred over def.json if it exists."; classes: "ok" if => and( strcmp(length(variablesmatching(".*\.good_var")), "1"), strcmp(length(variablesmatching(".*\.bad_var")), "0"), fileexists("$(this.promise_dirname)/def.json"), fileexists("$(this.promise_dirname)/def_preferred.json")), scope => "namespace"; } bundle agent check # Check the result of the test { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/def.json/def_preferred.json/def.json0000644000000000000000000000005315010704253027247 0ustar00rootroot00000000000000{ "vars": { "bad_var": "foo" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_bare_array.cf0000644000000000000000000000146015010704253026526 0ustar00rootroot00000000000000# basic test of the def.json facility: variables body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf | $(G.grep) bare_test"; methods: "" usebundle => dcs_passif_output("default:def.bare_test_array\s+.*bare_test_array_element.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/concurrent-vars-and-variables-keys/0000755000000000000000000000000015010704253030666 5ustar00rootroot00000000000000both-can-define-vars.cf0000644000000000000000000000237515010704253035024 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/concurrent-vars-and-variables-keysbody common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3975" } string => "Both 'vars' and 'variables' in Augments are able to define variables concurrently."; # The variables key was introduced in 3.18.0, so 3.17 and prior should # skip this test since the functionality is unsupported. # Note: This before_version macro was introduced in 3.16.0, 3.15.1, 3.12.4. @if before_version(3.18.0) "test_skip_unsupported" string => "any"; @endif } bundle agent check { vars: "expected_value" string => concat( "Only in vars", "Only in variables"); "actual_value" string => concat( "$(default:def.in_vars)", "$(default:def.in_variables)"); "expected_difference" string=> "no"; "test" string => "$(this.promise_filename)"; methods: "Pass/Fail" usebundle => dcs_check_strcmp($(expected_value), $(actual_value), $(test), $(expected_difference)); } variables-wins-variables-listed-first/0000755000000000000000000000000015010704253040112 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/concurrent-vars-and-variables-keysdef.json0000644000000000000000000000033315010704253041542 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/concurrent-vars-and-variables-keys/variables-wins-variables-listed-first{ "variables": { "default:def.my_var": "Set by variables key", "in_variables": "Only in variables" }, "vars": { "my_var": "Set by vars key", "in_vars": "Only in vars" } } variables-wins.cf0000644000000000000000000000237715010704253043363 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/concurrent-vars-and-variables-keys/variables-wins-variables-listed-firstbody common control { inputs => { "../../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3975" } string => "'variables' in def.json should win if both 'vars' and 'variables' keys define the same variable, even when variables is listed first in augments."; # The variables key was introduced in 3.18.0, so 3.17 and prior should # skip this test since the functionality is unsupported. # Note: This before_version macro was introduced in 3.16.0, 3.15.1, 3.12.4. @if before_version(3.18.0) "test_skip_unsupported" string => "any"; @endif } bundle agent check { vars: "expected_value" string => "Set by variables key"; "actual_value" string => "$(default:def.my_var)"; "expected_difference" string=> "no"; "test" string => "$(this.promise_filename)"; methods: "Pass/Fail" usebundle => dcs_check_strcmp($(expected_value), $(actual_value), $(test), $(expected_difference)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/concurrent-vars-and-variables-keys/def.json0000644000000000000000000000033315010704253032316 0ustar00rootroot00000000000000{ "vars": { "my_var": "Set by vars key", "in_vars": "Only in vars" }, "variables": { "default:def.my_var": "Set by variables key", "in_variables": "Only in variables" } } variables-wins.cf0000644000000000000000000000231315010704253034046 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/def.json/concurrent-vars-and-variables-keysbody common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3975" } string => "'variables' in def.json should win if both 'vars' and 'variables' keys define the same variable."; # The variables key was introduced in 3.18.0, so 3.17 and prior should # skip this test since the functionality is unsupported. # Note: This before_version macro was introduced in 3.16.0, 3.15.1, 3.12.4. @if before_version(3.18.0) "test_skip_unsupported" string => "any"; @endif } bundle agent check { vars: "expected_value" string => "Set by variables key"; "actual_value" string => "$(default:def.my_var)"; "expected_difference" string=> "no"; "test" string => "$(this.promise_filename)"; methods: "Pass/Fail" usebundle => dcs_check_strcmp($(expected_value), $(actual_value), $(test), $(expected_difference)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/class_from_classexpression.cf.json0000644000000000000000000000105015010704253030767 0ustar00rootroot00000000000000{ "classes": { "augments_class_from_regex": [ "cfengine_\\d+" ], "augments_class_from_single_class_as_regex": [ "cfengine" ], "augments_class_from_single_class_as_expression": [ "cfengine::" ], "augments_class_from_classexpression_and": [ "cfengine.cfengine_3::" ], "augments_class_from_classexpression_not": [ "!MISSING::" ], "augments_class_from_classexpression_or": [ "cfengine|cfengine_3::" ], "augments_class_from_classexpression_complex": [ "(cfengine|cfengine_3).!MISSING::" ] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/json-inputs-not-array.cf0000644000000000000000000000167615010704253026603 0ustar00rootroot00000000000000# Test that a def.json inputs section that doesn't contain an array produces an # error message. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ' body common control { inputs => { @(def.augments_inputs) }; } '); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) -f $(sys.inputdir)/promises.cf"; methods: "" usebundle => dcs_passif_output(".*Trying to augment inputs in [^\n]* but the value was not a list of string.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/vars.cf.json0000644000000000000000000000033715010704253024314 0ustar00rootroot00000000000000{ "classes": { "class_to_define_if": [ "one", "of", "these", "matches_classmatch" ], "my_other_example": [ "server[34]", "debian.*" ] }, "vars": { "test_variable": "37bff81c825bd57a613ff4770b7a0679ff147bdf" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_with_bundle.cf0000644000000000000000000000157215010704253026727 0ustar00rootroot00000000000000# basic test of the def.json facility: variables with bundle specification body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf|$(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output("default:config.test_variable\s+37bff81c825bd57a613ff4770b7a0679ff147bdf\s+test_tag,source=augments_file", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/inputs.cf0000644000000000000000000000206215010704253023710 0ustar00rootroot00000000000000# basic test of the def.json facility: inputs body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ' body common control { inputs => { @(def.augments_inputs) }; } '); "" usebundle => file_make("$(sys.inputdir)/secondary.cf", ' bundle common x { classes: "test_class_9f606e44752ce34ef39ee7d4754c5c84890d2b14" expression => "any"; } '); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("test_class_9f606e44752ce34ef39ee7d4754c5c84890d2b14\s+source=promise", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/inputs.cf.json0000644000000000000000000000006215010704253024656 0ustar00rootroot00000000000000{ "inputs": [ "$(sys.inputdir)/secondary.cf" ] } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments_order.cf.json0000644000000000000000000000016515010704253026356 0ustar00rootroot00000000000000{ "augments": [ "$(sys.inputdir)/augmenter.json" ], "vars": { "test_var" : "defined in vars" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_with_ns.cf.json0000644000000000000000000000023715010704253027043 0ustar00rootroot00000000000000{ "variables": { "my_ns:config.test_variable": { "value": "37bff81c825bd57a613ff4770b7a0679ff147bdf", "tags": ["test_tag"] } } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/classes.cf.json0000644000000000000000000000051515010704253024774 0ustar00rootroot00000000000000{ "classes": { "test_class_29665402e2b4331f10b8d767b512cd916eeb5db9": [ "one", "of", "these", "matches_classmatch", "any" ], "test_class_29665402e2b4331f10b8d767b512cd916eeb5db9_2": [ "cfengine" ], "test_class_cfengine_and_cfengine_version": [ "cfengine.cfengine_3" ], "my_other_example": [ "server[34]", "debian.*" ] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/json-inputs-not-auto-applied.cf.json0000644000000000000000000000006215010704253031005 0ustar00rootroot00000000000000{ "inputs": [ "$(sys.inputdir)/secondary.cf" ] } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments_order.cf.augmenter.json0000644000000000000000000000011415010704253030336 0ustar00rootroot00000000000000{ "vars" : { "test_var": [ "defined in augments.vars" ] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/state.cf.expected.json0000644000000000000000000000067715010704253026270 0ustar00rootroot00000000000000{ "acl": [ ".*$(def.domain) note this will remain unexpanded!!!" ], "domain": "mydomain", "input_name_patterns": [ ".*\\.cf", ".*\\.dat", ".*\\.txt", ".*\\.conf", ".*\\.mustache", ".*\\.sh", ".*\\.pl", ".*\\.py", ".*\\.rb", "cf_promises_release_id", ".*\\.json", ".*\\.yaml", ".*\\.js" ], "jq": "jq --compact-output --monochrome-output --ascii-output --unbuffered --sort-keys" } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_with_ns.cf0000644000000000000000000000160615010704253026074 0ustar00rootroot00000000000000# basic test of the def.json facility: variables with namespace and bundle specification body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf|$(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output("my_ns:config.test_variable\s+37bff81c825bd57a613ff4770b7a0679ff147bdf\s+test_tag,source=augments_file", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/vars_with_bundle.cf.json0000644000000000000000000000012715010704253026675 0ustar00rootroot00000000000000{ "vars": { "config.test_variable": "37bff81c825bd57a613ff4770b7a0679ff147bdf" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables.cf.json0000644000000000000000000000026215010704253025306 0ustar00rootroot00000000000000{ "variables": { "test_variable": { "value": "37bff81c825bd57a613ff4770b7a0679ff147bdf", "tags": ["test_tag"], "comment": "comment1" } } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/bad-json.cf0000644000000000000000000000150115010704253024060 0ustar00rootroot00000000000000# test of the def.json facility: complain if a bad JSON file is found body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; methods: "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)$(const.dirsep)def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) -v|$(G.grep) JSON"; methods: "" usebundle => dcs_passif_output(".*Could not parse JSON file $(sys.inputdir)$(const.dirsep)def.json.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments.cf.augmenter.json0000644000000000000000000000011615010704253027145 0ustar00rootroot00000000000000{ "vars" : { "inputs": [ "$(sys.inputdir)/secondary.cf" ] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/vars_with_ns.cf.json0000644000000000000000000000035415010704253026046 0ustar00rootroot00000000000000{ "classes": { "class_to_define_if": [ "one", "of", "these", "matches_classmatch" ], "my_other_example": [ "server[34]", "debian.*" ] }, "vars": { "my_ns:config.test_variable": "37bff81c825bd57a613ff4770b7a0679ff147bdf" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/classes_with_ns.cf.json0000644000000000000000000000054715010704253026534 0ustar00rootroot00000000000000{ "classes": { "my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9": [ "one", "of", "these", "matches_classmatch", "any" ], "my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9_2": [ "cfengine" ], "my_ns2:test_class_cfengine_and_cfengine_version": [ "cfengine.cfengine_3" ], "my_ns2:my_other_example": [ "server[34]", "debian.*" ] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/vars.cf0000644000000000000000000000151715010704253023345 0ustar00rootroot00000000000000# basic test of the def.json facility: vars body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf|$(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output("default:def.test_variable\s+37bff81c825bd57a613ff4770b7a0679ff147bdf\s+source=augments_file", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/classes_with_ns_tags.cf.json0000644000000000000000000000142415010704253027545 0ustar00rootroot00000000000000{ "classes": { "my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9": { "class_expressions": [ "one", "of", "these", "matches_classmatch", "any" ], "tags": ["test_tag"], "comment": "comment1" }, "my_ns:test_class_29665402e2b4331f10b8d767b512cd916eeb5db9_2": { "regular_expressions": [ "cfengine" ], "tags": ["test_tag"], "comment": "comment2" }, "my_ns2:test_class_cfengine_and_cfengine_version": { "class_expressions": [ "cfengine.cfengine_3" ], "tags": ["test_tag2"] }, "my_ns2:my_other_example": { "regular_expressions": [ "server[34]", "debian.*" ], "tags": ["test_tag2"] } } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments_order.cf0000644000000000000000000000222415010704253025404 0ustar00rootroot00000000000000# test that 'augments' in def.json are applied last body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-2844" } string => "'augments' in def.json should be applied last and thus override values of variables from 'vars'"; methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ' body common control { inputs => { "@(def.inputs)" }; } '); "" usebundle => file_copy("$(this.promise_filename).augmenter.json", "$(sys.inputdir)/augmenter.json"); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf|$(G.grep) test_var"; methods: "" usebundle => dcs_passif_output("default:def.test_var\s+\{\"defined in augments.vars\"\}\s+source=augments_file", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/vars_with_bundle.cf0000644000000000000000000000155415010704253025732 0ustar00rootroot00000000000000# basic test of the def.json facility: vars with bundle specification body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf|$(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output("default:config.test_variable\s+37bff81c825bd57a613ff4770b7a0679ff147bdf\s+source=augments_file", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_bare_string.cf.json0000644000000000000000000000011215010704253027657 0ustar00rootroot00000000000000{ "variables": { "bare_test_string": "bare_test_string_value" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables_bare_string.cf0000644000000000000000000000146015010704253026716 0ustar00rootroot00000000000000# basic test of the def.json facility: variables body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf | $(G.grep) bare_test"; methods: "" usebundle => dcs_passif_output("default:def.bare_test_string\s+bare_test_string_value\s.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/json-inputs-not-array.cf.json0000644000000000000000000000010315010704253027533 0ustar00rootroot00000000000000{ "inputs": { "there-should-not-be-a-key-here": "nor-a-value" } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/def.json0000644000000000000000000000055315010704253023510 0ustar00rootroot00000000000000{ "vars": { "domain": "mydomain", "acl": [ ".*$(def.domain) note this will remain unexpanded!!!" ], "input_name_patterns": [ ".*\\.cf",".*\\.dat",".*\\.txt", ".*\\.conf", ".*\\.mustache", ".*\\.sh", ".*\\.pl", ".*\\.py", ".*\\.rb", "cf_promises_release_id", ".*\\.json", ".*\\.yaml", ".*\\.js" ] } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/augments.cf.json0000644000000000000000000000006615010704253025163 0ustar00rootroot00000000000000{ "augments": [ "$(sys.inputdir)/augmenter.json" ] } cfengine-3.24.2/tests/acceptance/00_basics/def.json/json-inputs-not-auto-applied.cf0000644000000000000000000000202115010704253030032 0ustar00rootroot00000000000000# Test that def.json:inputs is not auto loaded. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ' body common control { inputs => { }; } '); "" usebundle => file_make("$(sys.inputdir)/secondary.cf", ' bundle common x { classes: "test_class_8f606e44752ce34ef39ee7d4754c5c84890d2b14" expression => "any"; } '); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("", ".*test_class_8f606e44752ce34ef39ee7d4754c5c84890d2b14.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/bad-json.cf.json0000644000000000000000000000001615010704253025030 0ustar00rootroot00000000000000bad JSON data cfengine-3.24.2/tests/acceptance/00_basics/def.json/show_vars_JSON.cf.json0000644000000000000000000000020015010704253026172 0ustar00rootroot00000000000000{ "vars": { "test_var": { "387c108886725091c6fe2433a9fcafa0820dd61f": [ "8e92eeab70dbef876aeac9d97a74cfdde6f53e86" ] } } } cfengine-3.24.2/tests/acceptance/00_basics/def.json/variables.cf0000644000000000000000000000155015010704253024337 0ustar00rootroot00000000000000# basic test of the def.json facility: variables body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-vars -f $(sys.inputdir)/promises.cf|$(G.grep) test_variable"; methods: "" usebundle => dcs_passif_output("default:def.test_variable\s+37bff81c825bd57a613ff4770b7a0679ff147bdf\s+test_tag,source=augments_file\s+comment1", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/classes.cf0000644000000000000000000000171615010704253024030 0ustar00rootroot00000000000000# basic test of the def.json facility: classes body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "" usebundle => file_make("$(sys.inputdir)/promises.cf", ''); "" usebundle => file_copy("$(this.promise_filename).json", "$(sys.inputdir)/def.json"); } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_promises) --show-classes -f $(sys.inputdir)/promises.cf|$(G.grep) test_class"; methods: "" usebundle => dcs_passif_output("test_class_29665402e2b4331f10b8d767b512cd916eeb5db9\s+source=augments_file.+test_class_29665402e2b4331f10b8d767b512cd916eeb5db9_2\s+source=augments_file", "test_class_cfengine_and_cfengine_version\s+source=augments_file", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/def.json/policy_server_classes.cf.json0000644000000000000000000000011115010704253027731 0ustar00rootroot00000000000000{ "classes": { "test_class_policy_server": [ "am_policy_hub" ], } } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/0000755000000000000000000000000015010704253025522 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/redmine_6334.cf.sub0000644000000000000000000000260415010704253030730 0ustar00rootroot00000000000000# Test that locking works and that locks are clear upon abort # Called twice from main.cf body agent control { abortclasses => { "abort_agent_run" }; } bundle agent example { methods: "test" usebundle => test, action => now; } bundle agent test { vars: first:: "count" string => "first"; second:: "count" string => "second"; methods: # should print "Called from test" for both runs "Report" usebundle => report_now($(this.bundle)), action => now; # should print "Called from call_report_now" for both runs "Nested Report" usebundle => call_report_now, action => now; # should print "Called from only_first" only for the first run "Only first" usebundle => report_now("only_first"); # should never print anything, but abort the execution "Nested Abort" usebundle => abort_now, action => now; } bundle agent call_report_now { methods: "Call Report" usebundle => report_now($(this.bundle)), action => now; } bundle agent report_now(caller) { reports: "Called from $(caller) ($(test.count))" action => now; } bundle agent abort_now { classes: "abort_agent_run" expression => "any"; reports: "Called from abort_now ($(test.count))" action => now; } body action now { ifelapsed => "0"; } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/redmine_6334.cf0000644000000000000000000000450715010704253030144 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_flakey_fail" string => "sunos_5_11.sparc", meta => { "ENT-7068" }; vars: "first" string => execresult("$(sys.cf_agent) -KIf $(this.promise_filename).sub -b example -Dfirst", "noshell"), comment => "Ignore locks in this first run - it will still write the locks!"; "second" string => execresult("$(sys.cf_agent) -If $(this.promise_filename).sub -b example -Dsecond", "noshell"), comment => "Don't ignore locks here so for pass_only_first_test_second case"; } bundle agent check { vars: "pass_strings" slist => { "test", "call_report_now", "only_first", "abort_now" }; "activations" slist => { "test.first", "test.second" }; # we want to see all of those in either "test.first" or "test.second" "pass_classes" slist => { "pass_test_test_first", "pass_call_report_now_test_first", "pass_test_test_second", "pass_call_report_now_test_second", "pass_only_first_test_first", }; # we don't want to any of those in neither "test.first" nor "test.second" "fail_classes" slist => { "pass_only_first_test_second", "pass_abort_now_test_first", "pass_abort_now_test_second" }; classes: "pass_$(pass_strings)_$(activations)" expression => regcmp(".*R: Called from $(pass_strings).*", "$($(activations))"); "ok_pass" and => { @(pass_classes) }; "fail_pass" or => { @(fail_classes) }; "ok" expression => "ok_pass.!fail_pass"; reports: DEBUG.!ok:: "Failed activation $(activations): '$($(activations))'"; DEBUG:: "expected : $(pass_classes)" if => not("$(pass_classes)"); "unexpected: $(fail_classes)" if => "$(fail_classes)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/timed/0000755000000000000000000000000015010704253026624 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/timed/package_lock.cf.expected0000644000000000000000000000030215010704253033334 0ustar00rootroot00000000000000Name=first_pkg Version=1.0 Architecture=generic Name=second_pkg Version=1.0 Architecture=generic Name=third_pkg Version=1.0 Architecture=generic Name=fourth_pkg Version=1.0 Architecture=generic cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/timed/package_lock.cf.module0000644000000000000000000000252215010704253033026 0ustar00rootroot00000000000000#!/bin/sh set -e case "$1" in supports-api-version) echo 1 ;; get-package-data) while read line; do case "$line" in File=*) echo PackageType=repo echo Name=${line#File=} ;; *) true ;; esac done ;; list-installed) while read line; do case "$line" in options=*) OUTPUT=${line#options=} ;; *) exit 1 ;; esac done if [ -f "$OUTPUT" ]; then cat "$OUTPUT" fi ;; list-*) # Drain input. cat > /dev/null ;; repo-install) while read line; do case "$line" in options=*) OUTPUT=${line#options=} ;; Name=*) NAME=${line#Name=} ;; *) exit 1 ;; esac done echo "Name=$NAME" >> "$OUTPUT" echo "Version=1.0" >> "$OUTPUT" echo "Architecture=generic" >> "$OUTPUT" ;; *) exit 1 ;; esac exit 0 cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/timed/defaults.cf.sub0000644000000000000000000000227015010704253031536 0ustar00rootroot00000000000000body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { "test" }; } bundle agent test { commands: # Use "has_run" class to avoid reexecution. This may happen because of the # sleep making the promise last for two minutes. Default ifelapsed time is # 1 minute. !has_run.expireafter:: "$(G.echo) one promise execution >> $(G.testfile).expireafter ; $(G.sleep) 120" contain => in_shell, classes => always("has_run"); !has_run.short_expireafter:: "$(G.echo) one promise execution >> $(G.testfile).short_expireafter ; $(G.sleep) 120" contain => in_shell, action => set_expireafter(1), classes => always("has_run"); !has_run.ifelapsed:: "$(G.echo) one promise execution >> $(G.testfile).ifelapsed" contain => in_shell, classes => always("has_run"); !has_run.long_ifelapsed:: "$(G.echo) one promise execution >> $(G.testfile).long_ifelapsed" contain => in_shell, action => set_ifelapsed(5), classes => always("has_run"); } body action set_ifelapsed(x) { ifelapsed => "$(x)"; } body action set_expireafter(x) { expireafter => "$(x)"; } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/timed/package_lock.cf0000644000000000000000000000367215010704253031551 0ustar00rootroot00000000000000# Test whether successive package locks can be grabbed, both immediately # following each other and after a time delay. (Redmine #7933). body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { meta: # "no_fds" won't work correctly on Windows. # Also Solaris 9 and 10 don't seem to handle the backgrounding used in # this test. But it seems unrelated to the actual fix. "test_skip_needs_work" string => "windows|sunos_5_9|sunos_5_10"; # The backgrounding doesn't work well under fakeroot. "test_skip_unsupported" string => "using_fakeroot"; files: test_pass_1:: "$(sys.workdir)/modules/packages/." create => "true"; "$(sys.workdir)/modules/packages/test_module" copy_from => local_cp("$(this.promise_filename).module"), perms => m("ugo+x"); } bundle agent test { commands: test_pass_1:: # Note: No -K. We need locks. # Also get rid of file descriptor ties to the parent with no_fds. # Note that we need to redirect descriptors 0, 1 and 2, since there is # apparently some unrelated bug in the output if we close them (otherwise # we would have used --no-std argument to no_fds). "$(G.no_fds) $(sys.cf_agent) -f $(this.promise_filename).sub < /dev/null > /dev/null 2>&1 &" contain => in_shell; } bundle agent check { methods: test_pass_1:: # We wait 61 seconds in the sub invocation, but in practice test platforms # experience all sorts of timing delays, let's give it plenty of time to # make sure it finishes. 300 seconds = 5 minutes. "any" usebundle => dcs_wait($(this.promise_filename), 300); test_pass_2:: "any" usebundle => dcs_check_diff($(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/timed/defaults.cf0000644000000000000000000001001615010704253030743 0ustar00rootroot00000000000000# Tests that the defaults to ifelapsed and expireafter are correct, # and that changing them has an effect. # We repeatedly run four promises, all adding a line of text to a file. What we # test is how many times the line gets added to the file, depending on the # value of ifelapsed and expireafter. The promise is carried out three times, # once at 0 seconds, once at 20 seconds, and once at 75 seconds. # # Seconds 0----------------20----------------75 No. lines # LR + DE Add Noop Noop 1 # LR + SE Add Noop Add 2 # SR + DI Add Noop Add 2 # SR + LI Add Noop Noop 1 # # LR = Long Running promise # SR = Short Running promise # DE = Default Expireafter # SE = Short Expireafter # DI = Default Ifelapsed # LI = Long Ifelapsed body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default($(this.promiser_filename)) }; } bundle agent init { meta: # Backgrounding doesn't work properly on Windows or with fakeroot. # In addition, RHEL4 seems to have some problem killing the test # afterwards, and HP-UX is too slow for timing to be accurate. Also, # this test was disabled on all platforms in ENT-6939 "test_skip_needs_work" string => "any"; methods: test_pass_1:: "any" usebundle => file_make("$(G.testfile).expireafter.expected", "one promise execution"); "any" usebundle => file_make("$(G.testfile).short_expireafter.expected", "one promise execution one promise execution"); "any" usebundle => file_make("$(G.testfile).ifelapsed.expected", "one promise execution one promise execution"); "any" usebundle => file_make("$(G.testfile).long_ifelapsed.expected", "one promise execution"); } bundle agent test { vars: "cases" slist => { "expireafter", "short_expireafter", "ifelapsed", "long_ifelapsed", }; commands: !DEBUG:: "$(G.no_fds) $(sys.cf_agent) -Il -D $(cases) -f $(this.promise_filename).sub 1>>$(G.testfile).$(cases).output.log 2>&1 &" contain => in_shell; DEBUG.test_pass_1:: "$(G.no_fds) $(sys.cf_agent) -l --debug -D $(cases) -f $(this.promise_filename).sub 1>>$(G.testfile).$(cases).1.output.log 2>&1 & echo $!" contain => in_shell; DEBUG.test_pass_2:: "$(G.no_fds) $(sys.cf_agent) -l --debug -D $(cases) -f $(this.promise_filename).sub 1>>$(G.testfile).$(cases).2.output.log 2>&1 & echo $!" contain => in_shell; DEBUG.test_pass_3:: "$(G.no_fds) $(sys.cf_agent) -l --debug -D $(cases) -f $(this.promise_filename).sub 1>>$(G.testfile).$(cases).3.output.log 2>&1 & echo $!" contain => in_shell; } bundle agent check { methods: test_pass_1:: "any" usebundle => dcs_wait($(this.promise_filename), 20); test_pass_2:: "any" usebundle => dcs_wait($(this.promise_filename), 55); test_pass_3:: # Final delay is just to make sure all background echos have happened, and # all sub agents have exited. Failure to do so can make the sub agents try # to look for locks inside the workdir, which by that point may have been # deleted. "any" usebundle => dcs_wait($(this.promise_filename), 140); vars: test_pass_4:: "pass_classes" slist => maplist("$(this)_pass", "test.cases"); "pass_expr" string => join(".", "pass_classes"); "fail_classes" slist => maplist("!$(this)_fail", "test.cases"); "fail_expr" string => join(".", "fail_classes"); methods: test_pass_4:: "any" usebundle => dcs_if_diff("$(G.testfile).$(test.cases)", "$(G.testfile).$(test.cases).expected", "$(test.cases)_pass", "$(test.cases)_fail"); "any" usebundle => dcs_passif("$(pass_expr).$(fail_expr)", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/timed/package_lock.cf.sub0000644000000000000000000000242015010704253032327 0ustar00rootroot00000000000000body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { "test" }; } bundle agent test { methods: debug_package_lock:: # Normally done by parent test. "debug_init"; any:: "test1"; "test2"; "test3"; } body package_module test_module { query_installed_ifelapsed => "60"; query_updates_ifelapsed => "14400"; default_options => { "$(G.testfile)" }; } bundle agent debug_init { files: "$(sys.workdir)/modules/packages/." create => "true"; "$(sys.workdir)/modules/packages/test_module" copy_from => local_cp("$(this.promise_dirname)/package_lock.cf.module"), perms => m("ugo+x"); } bundle agent test1 { packages: "first_pkg" policy => "present", package_module => test_module, action => immediate; "second_pkg" policy => "present", package_module => test_module, action => immediate; } bundle agent test2 { commands: "$(G.sleep) 61"; } bundle agent test3 { packages: "third_pkg" policy => "present", package_module => test_module, action => immediate; "fourth_pkg" policy => "present", package_module => test_module, action => immediate; } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/locks.cf0000644000000000000000000000430315010704253027147 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_flakey_fail" string => "sunos_5_11.sparc", meta => { "ENT-7068" }; vars: "first" string => execresult("$(sys.cf_agent) -KIf $(this.promise_filename).sub -b example -Dfirst", "noshell"), comment => "Ignore locks in this first run - it will still write the locks!"; "second" string => execresult("$(sys.cf_agent) -If $(this.promise_filename).sub -b example -Dsecond", "noshell"), comment => "Don't ignore locks here so for pass_only_first_test_second case"; } bundle agent check { vars: "pass_strings" slist => { "test", "call_report_now", "only_first" }; "activations" slist => { "test.first", "test.second" }; # we want to see all of those in either "test.first" or "test.second" "pass_classes" slist => { "pass_test_test_first", "pass_call_report_now_test_first", "pass_test_test_second", "pass_call_report_now_test_second", "pass_only_first_test_first", }; # we don't want to any of those in neither "test.first" nor "test.second" "fail_classes" slist => { "pass_only_first_test_second" }; classes: "pass_$(pass_strings)_$(activations)" expression => regcmp(".*R: Called from $(pass_strings).*", "$($(activations))"); "ok_pass" and => { @(pass_classes) }; "fail_pass" or => { @(fail_classes) }; "ok" expression => "ok_pass.!fail_pass"; reports: DEBUG.!ok:: "Failed activation $(activations): '$($(activations))'"; DEBUG:: "expected : $(pass_classes)" if => not("$(pass_classes)"); "unexpected: $(fail_classes)" if => "$(fail_classes)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/expireafter.cf0000644000000000000000000000347415010704253030362 0ustar00rootroot00000000000000############################################################################## # # Test that expireafter works with commands promise type # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ############################################################################## bundle agent init { meta: # Solaris 9 & 10 don't seem to handle the backgrounding "test_skip_needs_work" string => "windows|sunos_5_9|sunos_5_10"; files: "$(G.testfile)" delete => tidy; } ############################################################################## body action background { background => "true"; } bundle agent test { meta: "description" -> { "CFE-1188" } string => "Test that expireafter works with commands promise type"; commands: "$(sys.cf_agent) --inform --file $(this.promise_filename).sub --" action => background, comment => "I will get killed by the second agent"; "$(G.sleep) 90" comment => "I will wait for the first agent to expire"; "$(sys.cf_agent) --inform --file $(this.promise_filename).sub" comment => "I will kill the first agent"; } ############################################################################## bundle agent check { vars: "expected" string => "Hello CFEngine"; "actual" string => readfile("$(G.testfile)"), if => fileexists("$(G.testfile)"); classes: "ok" expression => strcmp("$(expected)", "$(actual)"); reports: DEBUG:: "Expected '$(expected)', found '$(actual)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/expireafter.cf.sub0000644000000000000000000000153315010704253031144 0ustar00rootroot00000000000000############################################################################## # # Test that expireafter works with commands promise type # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "hang" }; version => "1.0"; } ############################################################################## body action timeout { expireafter => "1"; ifelapsed => "0"; } bundle agent hang { vars: "content" string => ifelse(fileexists("$(G.testfile)"), "Hello CFEngine", "Bye CFEngine"); commands: "$(G.sleep) 120" action => timeout, handle => "done"; files: "$(G.testfile)" content => "$(content)", depends_on => { "done" }; } cfengine-3.24.2/tests/acceptance/00_basics/ifelapsed_and_expireafter/locks.cf.sub0000644000000000000000000000177215010704253027746 0ustar00rootroot00000000000000# Test that locking works # Called twice from main.cf bundle agent example { methods: "test" usebundle => test, action => now; } bundle agent test { vars: first:: "count" string => "first"; second:: "count" string => "second"; methods: # should print "Called from test" for both runs "Report" usebundle => report_now($(this.bundle)), action => now; # should print "Called from call_report_now" for both runs "Nested Report" usebundle => call_report_now, action => now; # should print "Called from only_first" only for the first run "Only first" usebundle => report_now("only_first"); } bundle agent call_report_now { methods: "Call Report" usebundle => report_now($(this.bundle)), action => now; } bundle agent report_now(caller) { reports: "Called from $(caller) ($(test.count))" action => now; } body action now { ifelapsed => "0"; } cfengine-3.24.2/tests/acceptance/15_control/0000755000000000000000000000000015010704253020570 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/15_control/02_agent/0000755000000000000000000000000015010704253022167 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/15_control/02_agent/001.cf0000644000000000000000000000162015010704253023000 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - control case 1, no abort # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit", "quit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_nomatchclassexpression.cf.sub0000644000000000000000000000154015010704253032451 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will not abort when a class expression used in # abortbundleclass does not match. ########################################################################## body agent control { abortbundleclasses => { "abort_bundle.something_else" }; } body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { classes: "abort_bundle" expression => "!any"; "something_else" expression => "any"; reports: "PASS" comment => "This report should happen as abort_bundle.something_else is not valid and the bundle should not abort."; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_nomatchclassexpression.cf0000644000000000000000000000132715010704253031664 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will not abort when a class expression used in # abortbundleclass does not match. ########################################################################## body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*PASS.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_classes.cf.sub0000644000000000000000000000177115010704253027315 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will abort when an abortbundleclass is found to match # exactly. Only the one bundle should be aborted, not the entire agent # execution. # ########################################################################## body agent control { abortbundleclasses => { "abort_bundle" }; } body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { classes: "abort_bundle" expression => "any"; reports: "Should Never Reach" comment => "This report should not happen since the bundle should abort first"; } bundle agent check { reports: "PASS" comment => "This should be reported, as only the previous bundle was aborted not the whole agent execution"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/003.x.cf0000644000000000000000000000167615010704253023263 0ustar00rootroot00000000000000####################################################### # # Test abortclasses regexp - should abort in same agent bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; "quitquit" expression => "any"; reports: ok:: "$(this.promise_filename) FAIL"; !ok:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/031.cf0000644000000000000000000000161515010704253023007 0ustar00rootroot00000000000000####################################################### # # Test addclasses # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { addclasses => { "ok" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; # Prevent reports from running reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/004.x.cf0000644000000000000000000000177315010704253023262 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - should abort in common bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortclasses_even_without_classes.x.cf0000644000000000000000000000123615010704253031753 0ustar00rootroot00000000000000body common control { bundlesequence => { init, test }; } body agent control { abortclasses => { "foo", "bar", "foobar" }; } bundle agent init { reports: "Defining class indirectly foo" classes => always("foo"); "Defining class indirectly bar" classes => always("bar"); "Defining class indirectly foobar" classes => always("foobar"); } bundle agent test { reports: foo:: "Aborting class defined"; } body classes always(x) { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/006.x.cf0000644000000000000000000000171015010704253023253 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - should abort in preliminary agent bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortclasses_from_common_bundle.x.cf0000644000000000000000000000165115010704253031363 0ustar00rootroot00000000000000####################################################### # # Test abortclasses regexp - should abort in preliminary common bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle common test { classes: "quitquit" expression => "any"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) FAIL"; !ok:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/023.cf0000644000000000000000000000204515010704253023006 0ustar00rootroot00000000000000####################################################### # # Test abortbundleclasses - control case 3, no abort # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortbundleclasses => { "quit" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; # Validate no submatch, reverse } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/003.cf0000644000000000000000000000203115010704253022777 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - control case 3, no abort # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quit" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; # Validate no submatch, reverse } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/021.cf0000644000000000000000000000164015010704253023004 0ustar00rootroot00000000000000####################################################### # # Test abortbundleclasses - control case 1, no abort # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortbundleclasses => { "quitquit", "quitquit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_regex.cf.sub0000644000000000000000000000202015010704253026756 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will abort when an abortbundleclass is found to match # a regular expression. Only the one bundle should be aborted, not the entire # agent execution. # ########################################################################## body agent control { abortbundleclasses => { "abort_bundle.*" }; } body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { classes: "abort_bundle_please" expression => "any"; reports: "Should Never Reach" comment => "This report should not happen since the bundle should abort first"; } bundle agent check { reports: "PASS" comment => "This should be reported, as only the previous bundle was aborted not the whole agent execution"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_classexpression.cf0000644000000000000000000000162315010704253030311 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will abort when a class expression is used with # abortbundleclass and found to match . Only the one bundle should be aborted, # not the entire agent execution. # ########################################################################## body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*Setting abort for 'abort_bundle.something_else' when setting class 'something_else'.*PASS.*", ".*Should Never Reach.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/15_control/02_agent/007.x.cf0000644000000000000000000000171515010704253023261 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - should abort in preliminary agent bundle, regex # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/009.x.cf0000644000000000000000000000036115010704253023257 0ustar00rootroot00000000000000body common control { bundlesequence => { test }; } bundle common g { classes: "foo" and => { "any" }; } body agent control { abortclasses => { "foo" }; } bundle agent test { reports: foo:: "Aborting class defined"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_regex.cf0000644000000000000000000000154415010704253026200 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will abort when an abortbundleclass is found to match # a regular expression. Only the one bundle should be aborted, not the entire # agent execution. # ########################################################################## body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*aborted on defined class 'abort_bundle_please'.*PASS.*", ".*Should Never Reach.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/15_control/02_agent/109.x.cf0000644000000000000000000000167215010704253023266 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - should abort in same agent bundle, regex # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; "quitquit" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_classes.cf0000644000000000000000000000151715010704253026523 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will abort when an abortbundleclass is found to match # exactly. Only the one bundle should be aborted, not the entire agent # execution. # ########################################################################## body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO"; methods: "check" usebundle => dcs_passif_output(".*aborted on defined class 'abort_bundle'.*PASS.*", ".*Should Never Reach.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/15_control/02_agent/002.cf0000644000000000000000000000203615010704253023003 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - control case 2, no abort # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit", "quitquit.*" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "quit" expression => "any"; # Validate no submatch } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/002.x.cf0000644000000000000000000000172115010704253023251 0ustar00rootroot00000000000000####################################################### # # Test abortclasses regexp - should abort in preliminary agent bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) FAIL"; !ok:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/abortbundle_classexpression.cf.sub0000644000000000000000000000212315010704253031075 0ustar00rootroot00000000000000########################################################################## # # Test that bundles will abort when a class expression is used with # abortbundleclass and found to match . Only the one bundle should be aborted, # not the entire agent execution. # ########################################################################## body agent control { abortbundleclasses => { "abort_bundle.something_else" }; } body common control { inputs => { "../../default.cf.sub", }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { classes: "abort_bundle" expression => "any"; "something_else" expression => "abort_bundle"; reports: "Should Never Reach" comment => "This report should not happen since the bundle should abort first"; } bundle agent check { reports: "PASS" comment => "This should be reported, as only the previous bundle was aborted not the whole agent execution"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/staging/0000755000000000000000000000000015010704253023623 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/15_control/02_agent/staging/027.x.cf0000644000000000000000000000210215010704253024706 0ustar00rootroot00000000000000####################################################### # # Test abortbundleclasses - expect failure, ok should not be defined # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortbundleclasses => { "quitquit" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; # Should abort bundle "ok" expression => "any"; # Should not be defined } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/staging/025.x.cf0000644000000000000000000000214315010704253024711 0ustar00rootroot00000000000000####################################################### # # Test abortbundleclasses - expect failure, report doesn't execute # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortbundleclasses => { "quitquit" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; # Globally set, but should still fail } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; # Prevent reports from running reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/staging/024.x.cf0000644000000000000000000000210615010704253024707 0ustar00rootroot00000000000000####################################################### # # Test abortbundleclasses - expect failure regex, ok should not be defined # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortbundleclasses => { "quit.*" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; # Should abort bundle "ok" expression => "any"; # Should not be defined } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/staging/026.x.cf0000644000000000000000000000215015010704253024710 0ustar00rootroot00000000000000####################################################### # # Test abortbundleclasses - expect failure, regex, report doesn't execute # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortbundleclasses => { "quit.*" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; # Globally set, but should still fail } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; # Prevent reports from running reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/008.x.cf0000644000000000000000000000166515010704253023266 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - should abort in same agent bundle # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quitquit" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; "quitquit" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/005.x.cf0000644000000000000000000000200015010704253023243 0ustar00rootroot00000000000000####################################################### # # Test abortclasses - should abort in common bundle, regex # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "quit.*" }; } bundle common g { vars: "dummy" string => "dummy"; classes: "quitquit" expression => "any"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/02_agent/022.cf0000644000000000000000000000174015010704253023006 0ustar00rootroot00000000000000####################################################### # # Test abortbundleclasses - control case 2, no abort # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortbundleclasses => { "quitquit", "quitquit.*" }; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; "quit" expression => "any"; # Validate no submatch reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/0000755000000000000000000000000015010704253022360 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/15_control/01_common/missing_inputs_directory.x.cf0000644000000000000000000000161615010704253030303 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_inputs with a directory - explicit failure expected # ####################################################### body common control { inputs => { "../../default.cf.sub", "/" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; ignore_missing_inputs => "off"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/inputs_from_readstringlist.cf.sub0000644000000000000000000000013215010704253031141 0ustar00rootroot00000000000000bundle common info { classes: "included_info_global_class" expression => "any"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/default_bundlesequence_namespace.x.cf0000644000000000000000000000042015010704253031656 0ustar00rootroot00000000000000# Redmine#4993: default bundlesequence calls main() body common control { inputs => { "../../default.cf.sub" }; } body file control { namespace => "abc"; } bundle agent main { methods: "" usebundle => default:dcs_pass("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/15_control/01_common/dynamic.sub0000644000000000000000000000002715010704253024516 0ustar00rootroot00000000000000bundle agent dummy { } cfengine-3.24.2/tests/acceptance/15_control/01_common/007.cf0000644000000000000000000000160215010704253023177 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_bundles, expect to pass, methods # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; ignore_missing_bundles => "on"; } ####################################################### # # bundle agent init # { # vars: # "dummy" string => "dummy"; # } # ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/012.x.cf0000644000000000000000000000160315010704253023442 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_inputs - explicit failure expected # ####################################################### body common control { inputs => { "../../default.cf.sub", "missing" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; ignore_missing_inputs => "off"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/003.cf0000644000000000000000000000157115010704253023200 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_bundles, expect to pass # ####################################################### body common control { ignore_missing_bundles => "on"; inputs => { "../../default.cf.sub" }; bundlesequence => { "missing", default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/011.x.cf0000644000000000000000000000152015010704253023437 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_inputs - control case # ####################################################### body common control { inputs => { "../../default.cf.sub", "missing" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/021.cf0000644000000000000000000000152415010704253023176 0ustar00rootroot00000000000000####################################################### # # Test domain # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; domain => "puppetlabs.com"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "puppetlabs_com"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/004.cf0000644000000000000000000000165515010704253023204 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_bundles, expect to pass, order independent # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "missing", default("$(this.promise_filename)") }; version => "1.0"; ignore_missing_bundles => "on"; # Order should not matter! } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/inputs_from_readstringlist.cf.txt0000644000000000000000000000004215010704253031167 0ustar00rootroot00000000000000inputs_from_readstringlist.cf.sub cfengine-3.24.2/tests/acceptance/15_control/01_common/001.x.cf0000644000000000000000000000152115010704253023437 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_bundles - control case # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "missing", default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/014.cf0000644000000000000000000000165315010704253023203 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_inputs, expect to pass, order independent # ####################################################### body common control { inputs => { "../../default.cf.sub", "missing" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; ignore_missing_inputs => "on"; # Order should not matter! } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/inputs_from_json.cf0000644000000000000000000000105715010704253026273 0ustar00rootroot00000000000000# Redmine#4683: dynamic inputs should work from a data container body common control { #ignore_missing_inputs => "true"; inputs => { "../../default.cf.sub", "$(config.myfile)" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common config { vars: "c" data => parsejson('{ "file": "dynamic.sub" }'); "myfile" string => "$(c[file])"; reports: DEBUG:: "myfile $(myfile)"; } bundle agent init { } bundle agent test { } bundle agent check { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/inputs_from_readstringlist.cf0000644000000000000000000000266115010704253030362 0ustar00rootroot00000000000000# Redmine#4683: dynamic inputs should work from readstringlist body common control { inputs => { "../../default.cf.sub", @(runlist.inputs) }; bundlesequence => { prep_runlist, runlist, default("$(this.promise_filename)") }; } # workaround: reading the data has to be separate from... bundle common prep_runlist { vars: "generated_inputs" string => "$(this.promise_filename).txt"; "inputs_pre" slist => readstringlist($(generated_inputs), "\s*#[^\n]*", "\n", 99999, 9999999); reports: EXTRA:: "$(this.bundle) reading inputs from file $(generated_inputs)"; } # ...the usage of the data bundle common runlist { vars: "inputs" slist => maplist("$(this.promise_dirname)/$(this)", "prep_runlist.inputs_pre"); reports: EXTRA:: "$(this.bundle) got inputs '$(inputs)'"; } bundle agent init { } bundle agent test { } bundle agent check { classes: "ok" and => { "included_info_global_class" }; reports: DEBUG.!included_info_global_class:: "BAD: The global class from the included file was not defined"; EXTRA.included_info_global_class:: "Good: The global class from the included file was defined"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/default_bundlesequence.cf0000644000000000000000000000046515010704253027405 0ustar00rootroot00000000000000# Redmine#4993: default bundlesequence calls main() body common control { inputs => { "../../default.cf.sub" }; } bundle agent main { methods: "" usebundle => default("$(this.promise_filename)"); } bundle agent check { methods: "" usebundle => dcs_pass("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/15_control/01_common/inputs_directory.cf0000644000000000000000000000063115010704253026300 0ustar00rootroot00000000000000# Redmine#4683: ensure directories and missing files don't abort when # ignore_missing_inputs is set body common control { ignore_missing_inputs => "true"; inputs => { "/x.cf", "/", "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { } bundle agent test { } bundle agent check { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/002.x.cf0000644000000000000000000000160515010704253023443 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_bundles - explicit failure expected # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "missing", default("$(this.promise_filename)") }; version => "1.0"; ignore_missing_bundles => "off"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/013.cf0000644000000000000000000000156715010704253023206 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_inputs, expect to pass # ####################################################### body common control { ignore_missing_inputs => "on"; inputs => { "../../default.cf.sub", "missing" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/staging/0000755000000000000000000000000015010704253024014 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/15_control/01_common/staging/006.x.cf0000644000000000000000000000161715010704253025106 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_bundles - explicit failure expected, methods # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; ignore_missing_bundles => "off"; } ####################################################### # # bundle agent init # { # vars: # "dummy" string => "dummy"; # } # ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/staging/005.x.cf0000644000000000000000000000153315010704253025102 0ustar00rootroot00000000000000####################################################### # # Test ignore_missing_bundles - control case, methods # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### # # bundle agent init # { # vars: # "dummy" string => "dummy"; # } # ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/01_common/022.cf0000644000000000000000000000173415010704253023202 0ustar00rootroot00000000000000####################################################### # # Test domain - expect it to set the $(sys.domain) variable # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; domain => "puppetlabs.com"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "dummy" string => "dummy"; classes: "ok" expression => strcmp("$(sys.domain)", "puppetlabs.com"); reports: DEBUG:: "Expected $(sys.domain) to be puppetlabs.com"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/15_control/file/0000755000000000000000000000000015010704253021507 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/15_control/file/file_inputs.sub10000644000000000000000000000046515010704253024631 0ustar00rootroot00000000000000bundle common sub1 { vars: # this is the same file twice, which should be OK with hash checks "inputs" slist => { "$(this.promise_dirname)/file_inputs.sub2", "$(this.promise_dirname)/./file_inputs.sub2" }; } body file control { inputs => { @(sub1.inputs) }; } cfengine-3.24.2/tests/acceptance/15_control/file/file_inputs.sub20000644000000000000000000000007015010704253024622 0ustar00rootroot00000000000000bundle agent check { reports: "$(init.file) Pass"; } cfengine-3.24.2/tests/acceptance/15_control/file/file_inputs.cf0000644000000000000000000000053615010704253024346 0ustar00rootroot00000000000000body common control { ignore_missing_bundles => "yes"; inputs => { "../../default.cf.sub" }; bundlesequence => { "missing", default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "file" string => "$(this.promise_filename)"; } bundle agent test { } body file control { inputs => { "file_inputs.sub1" }; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/0000755000000000000000000000000015010704253023401 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/bad_import.py0000644000000000000000000000002415010704253026067 0ustar00rootroot00000000000000import non_existing cfengine-3.24.2/tests/acceptance/30_custom_promise_types/05_meta_attr.cf0000644000000000000000000000455715010704253026212 0ustar00rootroot00000000000000###################################################### # # Basic test of custom promise types / promise modules checking that using a # 'meta' attribute in combination with a custom promise works (i.e. doesn't # crash). # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } body classes example { promise_repaired => { "example_promise_repaired" }; } bundle agent test { meta: "description" -> { "CFE-3440" } string => "Test that you can use a meta attribute with a custom promise"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "test_string" string => "hello, modules"; example: cfengine:: "$(G.testfile)" message => "$(test_string)", classes => example, meta => { "tag1", "tag2" }; classes: "file_created" expression => canonify("$(G.testfile)_created"), scope => "namespace"; "file_updated" expression => canonify("$(G.testfile)_content_updated"), scope => "namespace"; "file_update_failed" expression => canonify("$(G.testfile)_content_update_failed"), scope => "namespace"; } ####################################################### bundle agent check { classes: "file_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)")), if => fileexists("$(G.testfile)"); "ok" expression => "file_ok.file_created.file_updated.(!file_update_failed).example_promise_repaired"; reports: DEBUG.file_ok:: "file_ok"; DEBUG.file_created:: "file_created"; DEBUG.file_updated:: "file_updated"; DEBUG.file_update_failed:: "file_update_failed"; DEBUG.example_promise_repaired:: "example_promise_repaired"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/0000755000000000000000000000000015010704253026541 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/dryrun_unsupported.cf0000644000000000000000000000175115010704253033052 0ustar00rootroot00000000000000###################################################### # # Test of a custom promise with '--dry-run' and a module that # doesn't implement action_policy handling. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3433" } string => "Test that --dry-run produces errors when used with custom promise modules not supporting it"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) --dry-run -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*error: Not making changes.*", ".*CRITICAL:.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/simulate_supported.cf.sub0000644000000000000000000000127515010704253033600 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module_with_action_policy.sh"; } bundle agent test { vars: "test_string" string => "hello, modules"; example: "$(G.testfile)" message => "$(test_string)", action => policy("warn"); } body action policy(pol) { action_policy => "${pol}"; } example_module_with_fake_action_policy.sh0000644000000000000000000001150115010704253036751 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policylog() { if [ "$#" != 2 ] ; then echo "log_critical=Error in promise module (log must be used with 2 arguments, level and message)" exit 1 fi level="$1" message="$2" echo "log_$level=$message" } reset_state() { # Set global variables before we begin another request # Variables parsed directly from request: request_operation="" request_log_level="" request_promise_type="" request_promiser="" request_attribute_message="" action_policy="" # Variables to put into response: response_result="" # Other state: saw_unknown_key="no" saw_unknown_attribute="no" } handle_input_line() { # Split the line of input on the first '=' into 2 - key and value IFS='=' read -r key value <<< "$1" case "$key" in operation) request_operation="$value" ;; log_level) request_log_level="$value" ;; promise_type) request_promise_type="$value" ;; promiser) request_promiser="$value" ;; attribute_message) request_attribute_message="$value" ;; attribute_action_policy) action_policy="$value" ;; attribute_*) attribute_name=${key#"attribute_"} log error "Unknown attribute: '$attribute_name'" saw_unknown_attribute="yes" ;; *) saw_unknown_key="yes" ;; esac } receive_request() { # Read lines from input until empty line # Call handle_input_line for each non-empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then break fi handle_input_line "$line" # Parses a key=value pair done } write_response() { echo "operation=$request_operation" echo "result=$response_result" echo "" } operation_terminate() { response_result="success" write_response exit 0 } operation_validate() { response_result="valid" if [ "$saw_unknown_attribute" != "no" ] ; then response_result="invalid" fi if [ "$request_promiser" = "" ] ; then log error "Promiser must be non-empty" response_result="invalid" fi if [ "$request_attribute_message" = "" ] ; then log error "Attribute 'message' is missing or empty" response_result="invalid" fi write_response } operation_evaluate() { local safe_promiser="$(echo "$request_promiser" | sed 's/,/_/g')" local classes="" local existed_before=0 if [ -f "$request_promiser" ]; then existed_before=1 fi if grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="kept" classes="${safe_promiser}_content_as_promised" # elif [ x"$action_policy" = x"warn" ]; then # printf "log_warning=Should update file '%s' with content '%s', but only warning promised\n" "$request_promiser" "$request_attribute_message" # response_result="not_kept" else response_result="repaired" echo "$request_attribute_message" > "$request_promiser" && { printf "log_info=Updated file '%s' with content '%s'\n" "$request_promiser" "$request_attribute_message" if [ $existed_before = 0 ]; then classes="${safe_promiser}_created,${safe_promiser}_content_updated" else classes="${safe_promiser}_content_updated" fi } || response_result="not_kept" if ! grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="not_kept" if [ -z "$classes" ]; then classes="${safe_promiser}_content_update_failed" else classes="${classes},${safe_promiser}_content_update_failed" fi fi fi if [ -n "$classes" ]; then echo "result_classes=$classes" fi write_response } operation_unknown() { response_result="error" log error "Promise module received unexpected operation: $request_operation" write_response } perform_operation() { case "$request_operation" in validate_promise) operation_validate ;; evaluate_promise) operation_evaluate ;; terminate) operation_terminate ;; *) operation_unknown ;; esac } handle_request() { reset_state # 1. Reset global variables receive_request # 2. Receive / parse an operation from agent perform_operation # 3. Perform operation (validate, evaluate, terminate) } skip_header() { # Skip until (and including) the first empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then return; fi done } # Skip the protocol header given by agent: skip_header # Write our header to request line based protocol: echo "example_promises 0.0.1 v1 line_based action_policy" echo "" # Loop indefinitely, handling requests: while true; do handle_request done # Should never get here. explicit_warn_unsupported.cf.sub0000644000000000000000000000130015010704253035076 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policybody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module_without_action_policy.sh"; } bundle agent test { vars: "test_string" string => "hello, modules"; example: "$(G.testfile)" message => "$(test_string)", action => policy("warn"); } body action policy(pol) { action_policy => "${pol}"; } explicit_warn_unsupported.cf0000644000000000000000000000176115010704253034321 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy###################################################### # # Test of a custom promise with 'action_policy => "warn"' and a module that # doesn't implement action_policy handling. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3433" } string => "Test that action_policy produces errors when used with custom promise modules not supporting it"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*error: Not making changes.*", ".*CRITICAL:.*", $(command), $(this.promise_filename)); } explicit_warn_fake_supported.cf.sub0000644000000000000000000000130215010704253035523 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policybody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module_with_fake_action_policy.sh"; } bundle agent test { vars: "test_string" string => "hello, modules"; example: "$(G.testfile)" message => "$(test_string)", action => policy("warn"); } body action policy(pol) { action_policy => "${pol}"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/dryrun_supported.cf.sub0000644000000000000000000000127515010704253033300 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module_with_action_policy.sh"; } bundle agent test { vars: "test_string" string => "hello, modules"; example: "$(G.testfile)" message => "$(test_string)", action => policy("warn"); } body action policy(pol) { action_policy => "${pol}"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/explicit_warn_supported.cf0000644000000000000000000000171615010704253034035 0ustar00rootroot00000000000000###################################################### # # Test of a custom promise with 'action_policy => "warn"' and a module that # implements action_policy handling. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3433" } string => "Test that action_policy can be used with custom promise modules supporting it"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*warning: Should.*", ".*CRITICAL:.*", $(command), $(this.promise_filename)); } explicit_warn_fake_supported.cf0000644000000000000000000000203415010704253034736 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy###################################################### # # Test of a custom promise with 'action_policy => "warn"' and a module that # doesn't implement action_policy handling, but advertises it as supported. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3433" } string => "Test that a bug in a module is reported if it advertises action_policy feature, but doesn't properly implement it"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*CRITICAL: Bug in promise module.*", "", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/dryrun_supported.cf0000644000000000000000000000170415010704253032505 0ustar00rootroot00000000000000###################################################### # # Test of a custom promise with '--dry-run' and a module that # implements action_policy handling. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3433" } string => "Test that dry-run can be used with custom promise modules supporting it"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) --dry-run -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*warning: Should.*", ".*CRITICAL:.*", $(command), $(this.promise_filename)); } example_module_without_action_policy.sh0000644000000000000000000001037515010704253036523 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policyreset_state() { # Set global variables before we begin another request # Variables parsed directly from request: request_operation="" request_log_level="" request_promise_type="" request_promiser="" request_attribute_message="" # Variables to put into response: response_result="" # Other state: saw_unknown_key="no" saw_unknown_attribute="no" } handle_input_line() { # Split the line of input on the first '=' into 2 - key and value IFS='=' read -r key value <<< "$1" case "$key" in operation) request_operation="$value" ;; log_level) request_log_level="$value" ;; promise_type) request_promise_type="$value" ;; promiser) request_promiser="$value" ;; attribute_message) request_attribute_message="$value" ;; attribute_*) attribute_name=${key#"attribute_"} log error "Unknown attribute: '$attribute_name'" saw_unknown_attribute="yes" ;; *) saw_unknown_key="yes" ;; esac } receive_request() { # Read lines from input until empty line # Call handle_input_line for each non-empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then break fi handle_input_line "$line" # Parses a key=value pair done } write_response() { echo "operation=$request_operation" echo "result=$response_result" echo "" } operation_terminate() { response_result="success" write_response exit 0 } operation_validate() { response_result="valid" if [ "$saw_unknown_attribute" != "no" ] ; then response_result="invalid" fi if [ "$request_promiser" = "" ] ; then log error "Promiser must be non-empty" response_result="invalid" fi if [ "$request_attribute_message" = "" ] ; then log error "Attribute 'message' is missing or empty" response_result="invalid" fi write_response } operation_evaluate() { local safe_promiser="$(echo "$request_promiser" | sed 's/,/_/g')" local classes="" local existed_before=0 if [ -f "$request_promiser" ]; then existed_before=1 fi if grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="kept" classes="${safe_promiser}_content_as_promised" else response_result="repaired" echo "$request_attribute_message" > "$request_promiser" && { printf "log_info=Updated file '%s' with content '%s'\n" "$request_promiser" "$request_attribute_message" if [ $existed_before = 0 ]; then classes="${safe_promiser}_created,${safe_promiser}_content_updated" else classes="${safe_promiser}_content_updated" fi } || response_result="not_kept" fi if ! grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="not_kept" if [ -z "$classes" ]; then classes="${safe_promiser}_content_update_failed" else classes="${classes},${safe_promiser}_content_update_failed" fi fi if [ -n "$classes" ]; then echo "result_classes=$classes" fi write_response } operation_unknown() { response_result="error" log error "Promise module received unexpected operation: $request_operation" write_response } perform_operation() { case "$request_operation" in validate_promise) operation_validate ;; evaluate_promise) operation_evaluate ;; terminate) operation_terminate ;; *) operation_unknown ;; esac } handle_request() { reset_state # 1. Reset global variables receive_request # 2. Receive / parse an operation from agent perform_operation # 3. Perform operation (validate, evaluate, terminate) } skip_header() { # Skip until (and including) the first empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then return; fi done } # Skip the protocol header given by agent: skip_header # Write our header to request line based protocol: echo "example_promises 0.0.1 v1 line_based" echo "" # Loop indefinitely, handling requests: while true; do handle_request done # Should never get here. cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/simulate_supported.cf0000644000000000000000000000172215010704253033005 0ustar00rootroot00000000000000###################################################### # # Test of a custom promise with '--simulate' and a module that # implements action_policy handling. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3433" } string => "Test that --simulate can be used with custom promise modules supporting it"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) --simulate manifest -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*warning: Should.*", ".*CRITICAL:.*", $(command), $(this.promise_filename)); } explicit_warn_supported.cf.sub0000644000000000000000000000127515010704253034546 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policybody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module_with_action_policy.sh"; } bundle agent test { vars: "test_string" string => "hello, modules"; example: "$(G.testfile)" message => "$(test_string)", action => policy("warn"); } body action policy(pol) { action_policy => "${pol}"; } example_module_with_action_policy.sh0000644000000000000000000001147315010704253035773 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policylog() { if [ "$#" != 2 ] ; then echo "log_critical=Error in promise module (log must be used with 2 arguments, level and message)" exit 1 fi level="$1" message="$2" echo "log_$level=$message" } reset_state() { # Set global variables before we begin another request # Variables parsed directly from request: request_operation="" request_log_level="" request_promise_type="" request_promiser="" request_attribute_message="" action_policy="" # Variables to put into response: response_result="" # Other state: saw_unknown_key="no" saw_unknown_attribute="no" } handle_input_line() { # Split the line of input on the first '=' into 2 - key and value IFS='=' read -r key value <<< "$1" case "$key" in operation) request_operation="$value" ;; log_level) request_log_level="$value" ;; promise_type) request_promise_type="$value" ;; promiser) request_promiser="$value" ;; attribute_message) request_attribute_message="$value" ;; attribute_action_policy) action_policy="$value" ;; attribute_*) attribute_name=${key#"attribute_"} log error "Unknown attribute: '$attribute_name'" saw_unknown_attribute="yes" ;; *) saw_unknown_key="yes" ;; esac } receive_request() { # Read lines from input until empty line # Call handle_input_line for each non-empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then break fi handle_input_line "$line" # Parses a key=value pair done } write_response() { echo "operation=$request_operation" echo "result=$response_result" echo "" } operation_terminate() { response_result="success" write_response exit 0 } operation_validate() { response_result="valid" if [ "$saw_unknown_attribute" != "no" ] ; then response_result="invalid" fi if [ "$request_promiser" = "" ] ; then log error "Promiser must be non-empty" response_result="invalid" fi if [ "$request_attribute_message" = "" ] ; then log error "Attribute 'message' is missing or empty" response_result="invalid" fi write_response } operation_evaluate() { local safe_promiser="$(echo "$request_promiser" | sed 's/,/_/g')" local classes="" local existed_before=0 if [ -f "$request_promiser" ]; then existed_before=1 fi if grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="kept" classes="${safe_promiser}_content_as_promised" elif [ x"$action_policy" = x"warn" ]; then printf "log_warning=Should update file '%s' with content '%s', but only warning promised\n" "$request_promiser" "$request_attribute_message" response_result="not_kept" else response_result="repaired" echo "$request_attribute_message" > "$request_promiser" && { printf "log_info=Updated file '%s' with content '%s'\n" "$request_promiser" "$request_attribute_message" if [ $existed_before = 0 ]; then classes="${safe_promiser}_created,${safe_promiser}_content_updated" else classes="${safe_promiser}_content_updated" fi } || response_result="not_kept" if ! grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="not_kept" if [ -z "$classes" ]; then classes="${safe_promiser}_content_update_failed" else classes="${classes},${safe_promiser}_content_update_failed" fi fi fi if [ -n "$classes" ]; then echo "result_classes=$classes" fi write_response } operation_unknown() { response_result="error" log error "Promise module received unexpected operation: $request_operation" write_response } perform_operation() { case "$request_operation" in validate_promise) operation_validate ;; evaluate_promise) operation_evaluate ;; terminate) operation_terminate ;; *) operation_unknown ;; esac } handle_request() { reset_state # 1. Reset global variables receive_request # 2. Receive / parse an operation from agent perform_operation # 3. Perform operation (validate, evaluate, terminate) } skip_header() { # Skip until (and including) the first empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then return; fi done } # Skip the protocol header given by agent: skip_header # Write our header to request line based protocol: echo "example_promises 0.0.1 v1 line_based action_policy" echo "" # Loop indefinitely, handling requests: while true; do handle_request done # Should never get here. cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/dryrun_unsupported.cf.sub0000644000000000000000000000130015010704253033630 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module_without_action_policy.sh"; } bundle agent test { vars: "test_string" string => "hello, modules"; example: "$(G.testfile)" message => "$(test_string)", action => policy("warn"); } body action policy(pol) { action_policy => "${pol}"; } simulate_unsupported.cf.sub0000644000000000000000000000130015010704253034051 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policybody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module_without_action_policy.sh"; } bundle agent test { vars: "test_string" string => "hello, modules"; example: "$(G.testfile)" message => "$(test_string)", action => policy("warn"); } body action policy(pol) { action_policy => "${pol}"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/23_action_policy/simulate_unsupported.cf0000644000000000000000000000176515010704253033357 0ustar00rootroot00000000000000###################################################### # # Test of a custom promise with '--simulate' and a module that # doesn't implement action_policy handling. # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3433" } string => "Test that --simulate produces errors when used with custom promise modules not supporting it"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; } bundle agent check { vars: "command" string => "$(sys.cf_agent) --simulate manifest -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*error: Not making changes.*", ".*CRITICAL:.*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/04_unknown_promise_type.error.cf0000644000000000000000000000006015010704253031640 0ustar00rootroot00000000000000bundle agent main { unknown: "promise"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/22_what_module_gets.cf0000644000000000000000000000246115010704253027553 0ustar00rootroot00000000000000###################################################### # # Test which checks what custom module gets from the agent # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "/tmp/module.log" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/cat_module.sh"; } bundle agent test { meta: "description" -> { "CFE-3723" } string => "Test that input from cf-agent to promise module matches expected data"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; example: cfengine:: "Promiser" attributeName => "attributeValue"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("/tmp/module.log", "$(this.promise_filename).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/cat_module.sh0000644000000000000000000000433015010704253026051 0ustar00rootroot00000000000000log() { echo "$1" >>/tmp/module.log } reset_operation() { # reset operation name to default value request_operation="" } handle_input_line() { # Split the line of input on the first '=' into 2 - key and value IFS='=' read -r key value <<< "$1" # save operation name, if that's what the line is about if [ "$key" = operation ]; then request_operation="$value" fi } receive_request() { # Read lines from input until empty line # Call handle_input_line for each non-empty line while IFS='$\n' read -r line; do # Different CIs (Travis and Jenkins) run cf-agent with different verbosity settings. # This test accepts two verbosity settings, replacing one of them with another. log "`echo "$line" | sed 's/^log_level=notice$/log_level=info/'`" if [ "x$line" = "x" ] ; then break fi handle_input_line "$line" # Parses a key=value pair done } write_response() { echo "operation=$request_operation" echo "result=$response_result" echo "" } perform_operation() { case "$request_operation" in validate_promise) response_result="valid" ;; evaluate_promise) response_result="kept" ;; terminate) response_result="success" write_response exit 0 ;; *) response_result="error" ;; esac write_response } handle_request() { reset_state # 1. Reset global variables receive_request # 2. Receive / parse an operation from agent perform_operation # 3. Perform operation (validate, evaluate, terminate) } skip_header() { # Skip until (and including) the first empty line while IFS='$\n' read -r line; do # save header to the log, stripping CFEngine version log "`echo "$line" | sed 's/ 3\.[0-9][0-9]\.[0-9][^ ]* / xxx /'`" if [ "x$line" = "x" ] ; then return; fi done } # Skip the protocol header given by agent: skip_header # Write our header to request line based protocol: echo "example_promises 0.0.1 v1 line_based" echo "" # Loop indefinitely, handling requests: while true; do handle_request done # Should never get here. cfengine-3.24.2/tests/acceptance/30_custom_promise_types/03_ifvarclass.x.cf0000644000000000000000000000115115010704253026616 0ustar00rootroot00000000000000###################################################### # # Test that ifvarclass causes syntax / validation error # ##################################################### # This policy is as minimal as possible to reduce # the chance of something else causing an error promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } bundle agent main { meta: "description" -> { "CFE-3391" } string => "Test that ifvarclass causes syntax / validation error"; example: "/some/absolute/path" message => "x", ifvarclass => "any"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/12_multiple_promises.cf0000644000000000000000000000666415010704253030005 0ustar00rootroot00000000000000###################################################### # # Basic test of custom promise types / promise modules with multiple custom # promises of the same type # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)2" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } body classes example { promise_repaired => { "example_promise_repaired" }; } body classes example2 { promise_repaired => { "example2_promise_repaired" }; } bundle agent test { meta: "description" -> { "CFE-3443" } string => "Test that you can evaluate multiple custom promises of the same type"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "test_string" string => "hello, modules"; example: cfengine:: "$(G.testfile)" message => "$(test_string)", classes => example; "$(G.testfile)2" message => "$(test_string)", classes => example2; classes: "file_created" expression => canonify("$(G.testfile)_created"), scope => "namespace"; "file_updated" expression => canonify("$(G.testfile)_content_updated"), scope => "namespace"; "file_update_failed" expression => canonify("$(G.testfile)_content_update_failed"), scope => "namespace"; "file2_created" expression => canonify("$(G.testfile)2_created"), scope => "namespace"; "file2_updated" expression => canonify("$(G.testfile)2_content_updated"), scope => "namespace"; "file2_update_failed" expression => canonify("$(G.testfile)2_content_update_failed"), scope => "namespace"; } ####################################################### bundle agent check { classes: "file_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)")), if => fileexists("$(G.testfile)"); "file2_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)2")), if => fileexists("$(G.testfile)2"); "example_ok" expression => "file_ok.file_created.file_updated.(!file_update_failed).example_promise_repaired"; "example2_ok" expression => "file2_ok.file2_created.file2_updated.(!file2_update_failed).example2_promise_repaired"; "ok" expression => "example_ok.example2_ok"; reports: DEBUG.file_ok:: "file_ok"; DEBUG.file_created:: "file_created"; DEBUG.file_updated:: "file_updated"; DEBUG.file_update_failed:: "file_update_failed"; DEBUG.example_promise_repaired:: "example_promise_repaired"; DEBUG.file2_ok:: "file2_ok"; DEBUG.file2_created:: "file2_created"; DEBUG.file2_updated:: "file2_updated"; DEBUG.file2_update_failed:: "file2_update_failed"; DEBUG.example2_promise_repaired:: "example_promise_repaired"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/custom_promise_binary.c0000644000000000000000000000101215010704253030153 0ustar00rootroot00000000000000#include static inline void eatline(FILE *stream) { int c; while ((c = getc(stream)) != EOF && c != '\n') ; } int main() { printf("binary 0.0.1 v1 line_based\n"); printf("\n"); eatline(stdin); printf("operation=validate_promise\n"); printf("promiser=foobar\n"); printf("result=valid\n"); printf("\n"); eatline(stdin); printf("operation=evaluate_promise\n"); printf("promiser=foobar\n"); printf("result=kept\n"); printf("\n"); return 0; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/17_early_module_failure.cf.sub0000644000000000000000000000071015010704253031200 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } promise agent bad { interpreter => "/usr/bin/python3"; path => "$(this.promise_dirname)/bad_import.py"; } bundle agent test { meta: "description" -> { "CFE-3651" } string => "Test that an early-failing custom module is hanled properly"; bad: "doesn't matter what I put here"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/22_what_module_gets.cf.expected0000644000000000000000000000062515010704253031353 0ustar00rootroot00000000000000cf-agent xxx v1 operation=validate_promise log_level=info promise_type=example promiser=Promiser line_number=46 filename=./30_custom_promise_types/22_what_module_gets.cf attribute_attributeName=attributeValue operation=evaluate_promise log_level=info promise_type=example promiser=Promiser line_number=46 filename=./30_custom_promise_types/22_what_module_gets.cf attribute_attributeName=attributeValue cfengine-3.24.2/tests/acceptance/30_custom_promise_types/02_if.cf0000644000000000000000000000706415010704253024621 0ustar00rootroot00000000000000###################################################### # # Test that custom promises can use if attribute # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)-0" delete => init_delete; "$(G.testfile)-1" delete => init_delete; "$(G.testfile)-2" delete => init_delete; "$(G.testfile)-3" delete => init_delete; "$(G.testfile)-4" delete => init_delete; "$(G.testfile)-5" delete => init_delete; "$(G.testfile)-6" delete => init_delete; "$(G.testfile)-7" delete => init_delete; "$(G.testfile)-8" delete => init_delete; "$(G.testfile)-9" delete => init_delete; "$(G.testfile)-10" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } bundle agent test { meta: "description" -> { "CFE-3391" } string => "Test that custom promises work with if attribute"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "false_variable" string => "cfengine.(!cfengine)"; "true_variable" string => "cfengine|(!cfengine)"; example: cfengine:: "$(G.testfile)-0" # Created - no condition message => "x"; "$(G.testfile)-1" # Created - true condition message => "x", if => "cfengine"; "$(G.testfile)-2" # Created - true condition from variable message => "x", if => "$(true_variable)"; "$(G.testfile)-3" # Created - true condition (inverted false variable) message => "x", if => "!($(false_variable))"; "$(G.testfile)-4" # Created - not function call of something false message => "x", if => not("$(false_variable)"); "$(G.testfile)-5" # Not created - false condition message => "x", if => "!cfengine"; "$(G.testfile)-6" # Not created - false condition from variable message => "x", if => "$(false_variable)"; "$(G.testfile)-7" # Not created - false condition (inverted true variable) message => "x", if => "!($(true_variable))"; "$(G.testfile)-8" # Not created - not function call of something true message => "x", if => not("$(true_variable)"); "$(G.testfile)-9" # Not created - undefined variable in if message => "x", if => "$(undefined_variable)"; "$(G.testfile)-10" # Not created - unresolved function call in if message => "x", if => not("$(undefined_variable)"); } ####################################################### bundle agent check { classes: "ok" and => { fileexists("$(G.testfile)-0"), fileexists("$(G.testfile)-1"), fileexists("$(G.testfile)-2"), fileexists("$(G.testfile)-3"), fileexists("$(G.testfile)-4"), not(fileexists("$(G.testfile)-5")), not(fileexists("$(G.testfile)-6")), not(fileexists("$(G.testfile)-7")), not(fileexists("$(G.testfile)-8")), not(fileexists("$(G.testfile)-9")), not(fileexists("$(G.testfile)-10")), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/15_conflicting_interpreters.cf0000644000000000000000000000722315010704253031331 0ustar00rootroot00000000000000###################################################### # # Basic test of custom promise types / promise modules with a custom promise # module used for two promise types with conflicting interpreter # specifications. # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)2" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } promise agent example_two { interpreter => "/bin/bash_noexist"; path => "$(this.promise_dirname)/example_module.sh"; } body classes example { promise_repaired => { "example_promise_repaired" }; } body classes example2 { promise_repaired => { "example2_promise_repaired" }; } bundle agent test { meta: "description" -> { "CFE-3443" } string => "Test that you cannot use a promise module with two different interpreters"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "test_string" string => "hello, modules"; example: cfengine:: "$(G.testfile)" message => "$(test_string)", classes => example; example_two: cfengine:: "$(G.testfile)2" message => "$(test_string)", classes => example2; classes: "file_created" expression => canonify("$(G.testfile)_created"), scope => "namespace"; "file_updated" expression => canonify("$(G.testfile)_content_updated"), scope => "namespace"; "file_update_failed" expression => canonify("$(G.testfile)_content_update_failed"), scope => "namespace"; "file2_created" expression => canonify("$(G.testfile)2_created"), scope => "namespace"; "file2_updated" expression => canonify("$(G.testfile)2_content_updated"), scope => "namespace"; "file2_update_failed" expression => canonify("$(G.testfile)2_content_update_failed"), scope => "namespace"; } ####################################################### bundle agent check { classes: "file_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)")), if => fileexists("$(G.testfile)"); "file2_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)2")), if => fileexists("$(G.testfile)2"); "example_ok" expression => "file_ok.file_created.file_updated.(!file_update_failed).example_promise_repaired"; "example2_ok" expression => "!file2_ok.!file2_created.!file2_updated.!file2_update_failed.!example2_promise_repaired"; "ok" expression => "example_ok.example2_ok"; reports: DEBUG.file_ok:: "file_ok"; DEBUG.file_created:: "file_created"; DEBUG.file_updated:: "file_updated"; DEBUG.file_update_failed:: "file_update_failed"; DEBUG.example_promise_repaired:: "example_promise_repaired"; DEBUG.file2_ok:: "file2_ok"; DEBUG.file2_created:: "file2_created"; DEBUG.file2_updated:: "file2_updated"; DEBUG.file2_update_failed:: "file2_update_failed"; DEBUG.example2_promise_repaired:: "example_promise_repaired"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/17_early_module_failure.cf0000644000000000000000000000123015010704253030406 0ustar00rootroot00000000000000###################################################### # # Test of a module which fails early # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { vars: "command" string => "$(sys.cf_agent) -D AUTO -KIf $(this.promise_filename).sub"; methods: "check" usebundle => dcs_passif_output(".*error:.*", ".*(Assertion.*failed|fault).*", $(command), $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/11_unless.cf0000644000000000000000000000712215010704253025527 0ustar00rootroot00000000000000###################################################### # # Test that custom promises can use unless attribute # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)-0" delete => init_delete; "$(G.testfile)-1" delete => init_delete; "$(G.testfile)-2" delete => init_delete; "$(G.testfile)-3" delete => init_delete; "$(G.testfile)-4" delete => init_delete; "$(G.testfile)-5" delete => init_delete; "$(G.testfile)-6" delete => init_delete; "$(G.testfile)-7" delete => init_delete; "$(G.testfile)-8" delete => init_delete; "$(G.testfile)-9" delete => init_delete; "$(G.testfile)-10" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } bundle agent test { meta: "description" -> { "CFE-3431" } string => "Test that custom promises work with unless attribute"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "false_variable" string => "cfengine.(!cfengine)"; "true_variable" string => "cfengine|(!cfengine)"; example: cfengine:: "$(G.testfile)-0" # Created - no condition message => "x"; "$(G.testfile)-1" # Not created - true condition message => "x", unless => "cfengine"; "$(G.testfile)-2" # Not created - true condition from variable message => "x", unless => "$(true_variable)"; "$(G.testfile)-3" # Not created - true condition (inverted false variable) message => "x", unless => "!($(false_variable))"; "$(G.testfile)-4" # NOT - not function call of something false message => "x", unless => not("$(false_variable)"); "$(G.testfile)-5" # Created - false condition message => "x", unless => "!cfengine"; "$(G.testfile)-6" # Created - false condition from variable message => "x", unless => "$(false_variable)"; "$(G.testfile)-7" # Created - false condition (inverted true variable) message => "x", unless => "!($(true_variable))"; "$(G.testfile)-8" # Created - not function call of something true message => "x", unless => not("$(true_variable)"); "$(G.testfile)-9" # Created - undefined variable in unless message => "x", unless => "$(undefined_variable)"; "$(G.testfile)-10" # Created - unresolved function call in unless message => "x", unless => not("$(undefined_variable)"); } ####################################################### bundle agent check { classes: "ok" and => { fileexists("$(G.testfile)-0"), not(fileexists("$(G.testfile)-1")), not(fileexists("$(G.testfile)-2")), not(fileexists("$(G.testfile)-3")), not(fileexists("$(G.testfile)-4")), fileexists("$(G.testfile)-5"), fileexists("$(G.testfile)-6"), fileexists("$(G.testfile)-7"), fileexists("$(G.testfile)-8"), fileexists("$(G.testfile)-9"), fileexists("$(G.testfile)-10"), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/13_binary_path.cf0000644000000000000000000000102115010704253026510 0ustar00rootroot00000000000000body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } promise agent binary { path => "$(G.cwd)/custom_promise_binary"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10217" }; binary: "foobar" classes => if_ok("binary_ok"); } bundle agent check { reports: binary_ok:: "$(this.promise_filename) Pass"; !binary_ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/01_basic_module.cf0000644000000000000000000000434615010704253026650 0ustar00rootroot00000000000000###################################################### # # Basic test of custom promise types / promise modules # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } body classes example { promise_repaired => { "example_promise_repaired" }; } bundle agent test { meta: "description" -> { "CFE-3443" } string => "Test that you can add a promise module and evaluate a custom promise"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "test_string" string => "hello, modules"; example: cfengine:: "$(G.testfile)" message => "$(test_string)", classes => example; classes: "file_created" expression => canonify("$(G.testfile)_created"), scope => "namespace"; "file_updated" expression => canonify("$(G.testfile)_content_updated"), scope => "namespace"; "file_update_failed" expression => canonify("$(G.testfile)_content_update_failed"), scope => "namespace"; } ####################################################### bundle agent check { classes: "file_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)")), if => fileexists("$(G.testfile)"); "ok" expression => "file_ok.file_created.file_updated.(!file_update_failed).example_promise_repaired"; reports: DEBUG.file_ok:: "file_ok"; DEBUG.file_created:: "file_created"; DEBUG.file_updated:: "file_updated"; DEBUG.file_update_failed:: "file_update_failed"; DEBUG.example_promise_repaired:: "example_promise_repaired"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/14_multiple_promise_types_same_module.cf0000644000000000000000000000712315010704253033411 0ustar00rootroot00000000000000###################################################### # # Basic test of custom promise types / promise modules with a custom promise # module used for two promise types. # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)2" delete => init_delete; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### promise agent example { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } promise agent example_two { interpreter => "/bin/bash"; path => "$(this.promise_dirname)/example_module.sh"; } body classes example { promise_repaired => { "example_promise_repaired" }; } body classes example2 { promise_repaired => { "example2_promise_repaired" }; } bundle agent test { meta: "description" -> { "CFE-3443" } string => "Test that you can use the same custom module for two promise types"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "test_string" string => "hello, modules"; example: cfengine:: "$(G.testfile)" message => "$(test_string)", classes => example; example_two: cfengine:: "$(G.testfile)2" message => "$(test_string)", classes => example2; classes: "file_created" expression => canonify("$(G.testfile)_created"), scope => "namespace"; "file_updated" expression => canonify("$(G.testfile)_content_updated"), scope => "namespace"; "file_update_failed" expression => canonify("$(G.testfile)_content_update_failed"), scope => "namespace"; "file2_created" expression => canonify("$(G.testfile)2_created"), scope => "namespace"; "file2_updated" expression => canonify("$(G.testfile)2_content_updated"), scope => "namespace"; "file2_update_failed" expression => canonify("$(G.testfile)2_content_update_failed"), scope => "namespace"; } ####################################################### bundle agent check { classes: "file_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)")), if => fileexists("$(G.testfile)"); "file2_ok" expression => strcmp("$(test.test_string)", readfile("$(G.testfile)2")), if => fileexists("$(G.testfile)2"); "example_ok" expression => "file_ok.file_created.file_updated.(!file_update_failed).example_promise_repaired"; "example2_ok" expression => "file2_ok.file2_created.file2_updated.(!file2_update_failed).example2_promise_repaired"; "ok" expression => "example_ok.example2_ok"; reports: DEBUG.file_ok:: "file_ok"; DEBUG.file_created:: "file_created"; DEBUG.file_updated:: "file_updated"; DEBUG.file_update_failed:: "file_update_failed"; DEBUG.example_promise_repaired:: "example_promise_repaired"; DEBUG.file2_ok:: "file2_ok"; DEBUG.file2_created:: "file2_created"; DEBUG.file2_updated:: "file2_updated"; DEBUG.file2_update_failed:: "file2_update_failed"; DEBUG.example2_promise_repaired:: "example_promise_repaired"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/30_custom_promise_types/example_module.sh0000644000000000000000000001037515010704253026743 0ustar00rootroot00000000000000reset_state() { # Set global variables before we begin another request # Variables parsed directly from request: request_operation="" request_log_level="" request_promise_type="" request_promiser="" request_attribute_message="" # Variables to put into response: response_result="" # Other state: saw_unknown_key="no" saw_unknown_attribute="no" } handle_input_line() { # Split the line of input on the first '=' into 2 - key and value IFS='=' read -r key value <<< "$1" case "$key" in operation) request_operation="$value" ;; log_level) request_log_level="$value" ;; promise_type) request_promise_type="$value" ;; promiser) request_promiser="$value" ;; attribute_message) request_attribute_message="$value" ;; attribute_*) attribute_name=${key#"attribute_"} log error "Unknown attribute: '$attribute_name'" saw_unknown_attribute="yes" ;; *) saw_unknown_key="yes" ;; esac } receive_request() { # Read lines from input until empty line # Call handle_input_line for each non-empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then break fi handle_input_line "$line" # Parses a key=value pair done } write_response() { echo "operation=$request_operation" echo "result=$response_result" echo "" } operation_terminate() { response_result="success" write_response exit 0 } operation_validate() { response_result="valid" if [ "$saw_unknown_attribute" != "no" ] ; then response_result="invalid" fi if [ "$request_promiser" = "" ] ; then log error "Promiser must be non-empty" response_result="invalid" fi if [ "$request_attribute_message" = "" ] ; then log error "Attribute 'message' is missing or empty" response_result="invalid" fi write_response } operation_evaluate() { local safe_promiser="$(echo "$request_promiser" | sed 's/,/_/g')" local classes="" local existed_before=0 if [ -f "$request_promiser" ]; then existed_before=1 fi if grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="kept" classes="${safe_promiser}_content_as_promised" else response_result="repaired" echo "$request_attribute_message" > "$request_promiser" && { printf "log_info=Updated file '%s' with content '%s'\n" "$request_promiser" "$request_attribute_message" if [ $existed_before = 0 ]; then classes="${safe_promiser}_created,${safe_promiser}_content_updated" else classes="${safe_promiser}_content_updated" fi } || response_result="not_kept" fi if ! grep -q "$request_attribute_message" "$request_promiser" 2>/dev/null ; then response_result="not_kept" if [ -z "$classes" ]; then classes="${safe_promiser}_content_update_failed" else classes="${classes},${safe_promiser}_content_update_failed" fi fi if [ -n "$classes" ]; then echo "result_classes=$classes" fi write_response } operation_unknown() { response_result="error" log error "Promise module received unexpected operation: $request_operation" write_response } perform_operation() { case "$request_operation" in validate_promise) operation_validate ;; evaluate_promise) operation_evaluate ;; terminate) operation_terminate ;; *) operation_unknown ;; esac } handle_request() { reset_state # 1. Reset global variables receive_request # 2. Receive / parse an operation from agent perform_operation # 3. Perform operation (validate, evaluate, terminate) } skip_header() { # Skip until (and including) the first empty line while IFS='$\n' read -r line; do if [ "x$line" = "x" ] ; then return; fi done } # Skip the protocol header given by agent: skip_header # Write our header to request line based protocol: echo "example_promises 0.0.1 v1 line_based" echo "" # Loop indefinitely, handling requests: while true; do handle_request done # Should never get here. cfengine-3.24.2/tests/acceptance/30_custom_promise_types/18_early_module_failure_classes.cf0000644000000000000000000000206315010704253032131 0ustar00rootroot00000000000000###################################################### # # Test of classes being set for a promise using a module which fails early # ##################################################### body common control { inputs => { "../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### promise agent bad { interpreter => "/usr/bin/python3"; path => "$(this.promise_dirname)/bad_import.py"; } bundle agent test { meta: "description" -> { "CFE-3645" } string => "Test that a promise using an early-failing custom module still sets result classes"; bad: "doesn't matter what I put here" classes => test; } body classes test { promise_repaired => { "test_promise_repaired" }; repair_failed => { "test_promise_failed" }; } bundle agent check { classes: "ok" expression => "test_promise_failed"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/testall0000755000000000000000000014113715010704253020210 0ustar00rootroot00000000000000#!/bin/sh # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # # Detect and replace non-POSIX shell # try_exec() { type "$1" > /dev/null 2>&1 && exec "$@" } broken_posix_shell() { unset foo local foo=1 test "$foo" != "1" } if broken_posix_shell >/dev/null 2>&1 then try_exec /usr/xpg4/bin/sh "$0" "$@" echo "No compatible shell script interpreter found." echo "Please find a POSIX shell for your system." exit 42 fi # # Explicitly use POSIX tools if needed # if [ -f /usr/xpg4/bin/grep ] then PATH=/usr/xpg4/bin:$PATH export PATH fi # # Unset environment variables which might break runinng acceptance tests # GREP_OPTIONS= export GREP_OPTIONS # # Defaults (overridden by command-line arguments) # LOG=test.log INOTIFYWATCH_LOG=inotifywatch.log INOTIFYWAIT_LOG=inotifywait.log INOTIFYWATCH_OPTS="-r -e modify -e attrib -e moved_to -e create -e delete -e delete_self" INOTIFYWAIT_OPTS="-r -m -e modify -e attrib -e moved_to -e create -e delete -e delete_self" SUMMARY=summary.log XML=test.xml WHOAMI=/c/Windows/System32/whoami.exe BASE_WORKDIR=${BASE_WORKDIR:-$(pwd)/workdir} QUIET= # Default test types to run if --tests= is not passed # DEFAULT ON COMMON_TESTS=${COMMON_TESTS:-1} ; export COMMON_TESTS TIMED_TESTS=${TIMED_TESTS:-1} ; export TIMED_TESTS SLOW_TESTS=${SLOW_TESTS:-1} ; export SLOW_TESTS ERROREXIT_TESTS=${ERROREXIT_TESTS:-1} ; export ERROREXIT_TESTS ERRORLOG_TESTS=${ERRORLOG_TESTS:-1} ; export ERRORLOG_TESTS SERIAL_TESTS=${SERIAL_TESTS:-1} ; export SERIAL_TESTS NETWORK_TESTS=${NETWORK_TESTS:-1} ; export NETWORK_TESTS LIBXML2_TESTS=${LIBXML2_TESTS:-1} ; export LIBXML2_TESTS LIBCURL_TESTS=${LIBCURL_TESTS:-1} ; export LIBCURL_TESTS # DEFAULT OFF UNSAFE_TESTS=${UNSAFE_TESTS:-0} ; export UNSAFE_TESTS STAGING_TESTS=${STAGING_TESTS:-0} ; export STAGING_TESTS BINDIR=${BINDIR:-} ; export BINDIR NO_CLEAN=${NO_CLEAN:-0} ; export NO_CLEAN BASECLASSES=${BASECLASSES:-AUTO} ; export BASECLASSES EXTRACLASSES=${EXTRACLASSES:-DEBUG} ; export EXTRACLASSES AGENT=${AGENT:-} ; export AGENT CF_PROMISES=${CF_PROMISES:-} ; export CF_PROMISES CF_SERVERD=${CF_SERVERD:-} ; export CF_SERVERD CF_EXECD=${CF_EXECD:-} ; export CF_EXECD CF_KEY=${CF_KEY:-} ; export CF_KEY CF_SECRET=${CF_SECRET:-} ; export CF_SECRET CF_NET=${CF_NET:-} ; export CF_NET CF_CHECK=${CF_CHECK:-} ; export CF_CHECK CF_RUNAGENT=${CF_RUNAGENT:-} ; export CF_RUNAGENT RPMVERCMP=${RPMVERCMP:-} ; export RPMVERCMP DIFF=${DIFF:-} ; export DIFF LIBTOOL=${LIBTOOL:-} ; export LIBTOOL INCLUDE_IN_WORKDIR=${INCLUDE_IN_WORKDIR:-} ; export INCLUDE_IN_WORKDIR VALGRIND_OPTS="${VALGRIND_OPTS:---leak-check=full --show-reachable=yes --suppressions=valgrind-suppressions}" export VALGRIND_OPTS export MAKEFLAGS export GAINROOT # Use TEST_INDEX for indexing a poor man's array. Basically the subscript is # just appended to the variable name. TEST_INDEX=0 TEST_TIMED_INDEX=0 #TESTS_TIMED_=0 #TESTS_TIMEOUT_=0 #TESTS_PASSES_=0 TESTS_COUNT=0 TESTS_NORMAL_COUNT=0 TESTS_TIMED_COUNT=0 TESTS_TIMED_REMAINING=0 case "$OSTYPE" in msys) if "$WHOAMI" -priv | grep SeTakeOwnershipPrivilege > /dev/null then # Don't use elevate if we already have the privileges. It is slower and # pops up a flashing window for every single test. DEFAULT_GAINROOT= else DEFAULT_GAINROOT="`dirname $0`/tool_wrappers/elevate.sh" fi # Use hardlinks on Windows. Using symbolic links will work, but Msys creates a # real copy, which eats disk space very quickly when you multiply with the number # of tests. LN_CMD="ln -f" ;; *) DEFAULT_GAINROOT=fakeroot LN_CMD="ln -sf" ;; esac GAINROOT=${GAINROOT:-$DEFAULT_GAINROOT} PASSED_TESTS=0 FAILED_TESTS=0 SUPPRESSED_FAILURES=0 SOFT_FAILURES=0 SKIPPED_TESTS=0 FLAKEY_FAILURES=0 # # Many older platforms don't support date +%s, so check for compatibility # and find Perl for the unix_seconds() routine below. (Mantis #1254) # HAVE_DATE_PCT_S= date +%s | grep %s >/dev/null 2>&1 if [ $? -ne 0 ] then HAVE_DATE_PCT_S=1 fi PERL=`which perl 2>/dev/null` # color! if [ "${CFENGINE_COLOR}" = "1" ] then COLOR_SUCCESS="\\033[1;32m" COLOR_FAILURE="\\033[1;31m" COLOR_WARNING="\\033[1;33m" COLOR_NORMAL="\\033[0;39m" else COLOR_SUCCESS= COLOR_FAILURE= COLOR_WARNING= COLOR_NORMAL= fi # # Obtain UNIX time(), using date +%s, Perl, or POSIX-compatible approach. # unix_seconds() { if [ "$HAVE_DATE_PCT_S" ] then date +%s return 0 fi if [ "$PERL" ] then $PERL -e 'print time() . "\n"' 2>/dev/null if [ $? -eq 0 ] then return 0 fi fi # Last resort if Perl fails - the extended cpio interchange format has # the file modification timestamp in columns 48-59, in octal. : > $BASE_WORKDIR/x echo "ibase=8;$(pax -wx cpio $BASE_WORKDIR/$$.seconds | cut -c 48-59)" | bc 2>/dev/null rm $BASE_WORKDIR/x } usage() { echo "testall [-h|--help] [-q|--quiet] [--gainroot=] [--agent=] [--cfpromises=] [--cfserverd=] [--cfexecd=] [--cfkey=] [--cfkeycrypt=] [--cfnet=] [--cfcheck=] [--bindir=] [--tests=...] [--gdb] [--printlog] [ ...]" echo echo "If no test is given, all standard tests are run:" echo " Tests with names of form .cf are expected to run successfully" echo " Tests with names of form .x.cf are expected to exit with error" echo "Set ${COLOR_SUCCESS}CFENGINE_COLOR=1${COLOR_NORMAL} to get ANSI color markers where appropriate." echo echo "If arguments are given, those are executed as tests" echo echo " -h" echo " --help prints usage" echo " -q" echo " --quiet makes script much quieter" echo " --gainroot= forces use of command to gain root privileges," echo " otherwise fakeroot is used. Use --gainroot=env to make this" echo " option a no-op (e.g. you're running inside fakeroot already)" echo " --agent provides a way to specify non-default cf-agent location," echo " and defaults to $DEFAGENT." echo " --baseclasses provides a way to override the default cf-agent classes," echo " and defaults to ${BASECLASSES}. Also can use --bc" echo " --extraclasses provides a way to append to the default cf-agent classes," echo " and defaults to ${EXTRACLASSES}. Also can use --ec" echo " --cfpromises provides a way to specify non-default cf-promises location," echo " and defaults to $DEFCF_PROMISES." echo " --cfserverd provides a way to specify non-default cf-serverd location," echo " and defaults to $DEFCF_SERVERD." echo " --cfexecd provides a way to specify non-default cf-execd location," echo " and defaults to $DEFCF_EXECD." echo " --cfkey provides a way to specify non-default cf-key location," echo " and defaults to $DEFCF_KEY." echo " --cfkeycrypt provides a way to specify non-default cf-secret location," echo " and defaults to $DEFCF_SECRET." echo " --cfnet provides a way to specify non-default cf-net location," echo " and defaults to $DEFCF_NET." echo " --cfcheck provides a way to specify non-default cf-check location," echo " and defaults to $DEFCF_CHECK." echo " --cfrunagent provides a way to specify non-default cf-runagent location," echo " and defaults to $DEFCF_RUNAGENT." echo " --rpmvercmp provides a way to specify non-default rpmvercmp location," echo " and defaults to $DEFRPMVERCMP." echo " --bindir specifies the directory containing all the binaries." echo " Mutually exclusive with --agent and --cf* arguments." echo " --libtool specify non-default libtool location (only needed for --gdb)." echo " defaults to $DEFLIBTOOL." echo " --include Include the file or directory given in the workdir before the test" echo " starts. This option may be given several times." echo " --tests=common,network,serial,timed,slow,errorexit,errorlog,libxml2,libcurl" echo " This is the default value, you can also add from the following:" echo " unsafe,staging" echo " NOTE: 'staging' tests are not expected to pass" echo " WARN: 'unsafe' tests modify the system they are running on and can cause DAMAGE!" echo " If you use this option you should also use --gainroot=sudo." echo " --printlog print the full test.log output immediately. Override with $PRINTLOG" echo " --gdb Run test under GDB" echo " --valgrind Run test under Valgrind" echo " --callgrind Run test under valgrind --tool=callgrind" echo " --inotifywatch Run tests and log filesystem statistics" echo " --inotifywait Run tests and log filesystem events" echo " --no-clean does not clean workdir after test finishes" echo " (by default it gets cleaned only if test passed)." echo " --base-workdir Specify a local directory for all working files" echo " -j[n]" echo " -jobs=[n] Run tests in parallel, works like make -j option. Note that some" echo " tests will always run one by one." echo " --verbose Run tests with verbose logging" echo " --debug Run tests with debug logging" } workdir() { echo "$BASE_WORKDIR/$(echo "$1" | sed 's,[./],_,g')" } # Example: fgrepvar 'word' VARNAME # Silent fgrep for variables: search for "word" in $VARNAME fgrepvar() { eval echo \$$2 | fgrep "$1" > /dev/null } # Same but instead of word search for a regex grepvar() { eval echo \$$2 | grep "$1" > /dev/null } # Takes the following arguments: # 1. Agent - The agent to execute. # 2. Test - The test to execute. # 3. Pass number - [Optional] The current pass number. Used by timed tests. # 4. Timeout variable - [Optional] The name of the variable to put the next # timeout into. Used by timed tests. runtest() { # Clear/Reset local variables unset AGENT TEST TEST_TYPE EXTRATEXT SKIP SKIPREASON RESULT RESULT_MSG TEST_START_TIME FLATNAME WORKDIR OUTFILE TEST_DESCRIPTION TEST_STORY TEST_COVERS AGENT="$1" TEST="$2" PASS_NUM="$3" NEXT_TIMEOUT_VAR="$4" # With STAY_IN_WORKDIR we may be running alongside others, and need to print everything at once # on one line, so that we don't risk mixing lines together. if [ -z "$QUIET" -a -z "$STAY_IN_WORKDIR" ] then printf "$TEST " fi case "$TEST" in *.x.cf) TEST_TYPE=errorexit && EXTRATEXT='(should exit with non-zero, but not crash)' ;; *.error.cf) TEST_TYPE=errorlog && EXTRATEXT='(should log error(s), but exit with 0)' ;; */staging/*) TEST_TYPE=staging ;; */unsafe/*) TEST_TYPE=unsafe ;; */network/*) TEST_TYPE=network ;; */timed/*) TEST_TYPE=timed ;; */slow/*) TEST_TYPE=slow ;; *[/_]serial[/_.]*) TEST_TYPE=serial ;; */11_xml_edits/*) TEST_TYPE=libxml2 ;; */01_vars/02_functions/network/url_get.cf) TEST_TYPE=libcurl ;; *) TEST_TYPE=common ;; esac SKIP=0 # by default the test is not skipped SKIPREASON= if [ $ERROREXIT_TESTS = 0 -a $TEST_TYPE = errorexit ] then SKIP=1 SKIPREASON="${COLOR_WARNING}'errorexit' tests are disabled${COLOR_NORMAL}" elif [ $ERRORLOG_TESTS = 0 -a $TEST_TYPE = errorlog ] then SKIP=1 SKIPREASON="${COLOR_WARNING}'errorlog' tests are disabled${COLOR_NORMAL}" elif [ $STAGING_TESTS = 0 -a $TEST_TYPE = staging ] then SKIP=1 SKIPREASON="${COLOR_WARNING}Staging tests are disabled${COLOR_NORMAL}" elif [ $UNSAFE_TESTS = 0 -a $TEST_TYPE = unsafe ] then SKIP=1 SKIPREASON="${COLOR_WARNING}Unsafe tests are disabled${COLOR_NORMAL}" elif [ $NETWORK_TESTS = 0 -a $TEST_TYPE = network ] then SKIP=1 SKIPREASON="${COLOR_WARNING}Network-dependent tests are disabled${COLOR_NORMAL}" elif [ $TIMED_TESTS = 0 -a $TEST_TYPE = timed ] then SKIP=1 SKIPREASON="${COLOR_WARNING}Timed tests are disabled${COLOR_NORMAL}" elif [ $SLOW_TESTS = 0 -a $TEST_TYPE = slow ] then SKIP=1 SKIPREASON="${COLOR_WARNING}Slow tests are disabled${COLOR_NORMAL}" elif [ $SERIAL_TESTS = 0 -a $TEST_TYPE = serial ] then SKIP=1 SKIPREASON="${COLOR_WARNING}Serial tests are disabled${COLOR_NORMAL}" elif [ $LIBXML2_TESTS = 0 -a $TEST_TYPE = libxml2 ] then SKIP=1 SKIPREASON="${COLOR_WARNING}XML file editing tests are disabled${COLOR_NORMAL}" elif [ $LIBCURL_TESTS = 0 -a $TEST_TYPE = libcurl ] then SKIP=1 SKIPREASON="${COLOR_WARNING}libcurl tests are disabled${COLOR_NORMAL}" elif [ $COMMON_TESTS = 0 -a $TEST_TYPE = common ] then SKIP=1 SKIPREASON="${COLOR_WARNING}Common tests are disabled${COLOR_NORMAL}" fi TEST_START_TIME=$(unix_seconds) # Create workdir WORKDIR="$(workdir "$TEST")" OUTFILE="$WORKDIR/output.log" if [ -z "$PASS_NUM" ] || [ "$PASS_NUM" -eq 1 ] then # Don't reset workdir if this is a subsequent pass. $GAINROOT rm -rf "$WORKDIR" mkdir -p "$WORKDIR/bin" "$WORKDIR/tmp" chmod ugo+rwxt "$WORKDIR/tmp" fi # For unknown reason on the second pass, this file is root-owned, so we need GAINROOT here $GAINROOT rm -f "$OUTFILE" # Make sure these files are owned by the script, for some reason # each agent execution or each pass, messes this up. $GAINROOT touch "$OUTFILE" "$WORKDIR/$LOG" "$WORKDIR/$SUMMARY" "$WORKDIR/$XML" $GAINROOT chown $USER "$OUTFILE" "$WORKDIR/$LOG" "$WORKDIR/$SUMMARY" "$WORKDIR/$XML" if [ -n "$NEXT_TIMEOUT_VAR" ] then eval $NEXT_TIMEOUT_VAR= fi if [ "$SKIP" = 1 ] # Skip then TEST_END_TIME=$TEST_START_TIME RESULT=Skip RESULT_MSG="${COLOR_WARNING}Skipped ($SKIPREASON)${COLOR_NORMAL}" else # Do not skip # Prepare workdir # Don't copy into workdir if this is a subsequent pass. if [ -z "$PASS_NUM" ] || [ "$PASS_NUM" -eq 1 ] then if [ -n "$BINDIR" ] then # Copy everything, because Windows depends on DLLs. $LN_CMD "$BINDIR"/* "$WORKDIR/bin" else $LN_CMD "$AGENT" "$WORKDIR/bin" $LN_CMD "$CF_PROMISES" "$WORKDIR/bin" $LN_CMD "$CF_SERVERD" "$WORKDIR/bin" $LN_CMD "$CF_EXECD" "$WORKDIR/bin" $LN_CMD "$CF_KEY" "$WORKDIR/bin" $LN_CMD "$CF_SECRET" "$WORKDIR/bin" $LN_CMD "$CF_NET" "$WORKDIR/bin" $LN_CMD "$CF_CHECK" "$WORKDIR/bin" $LN_CMD "$CF_RUNAGENT" "$WORKDIR/bin" if [ "$NEED_RPMVERCMP" = "yes" ] then $LN_CMD "$RPMVERCMP" "$WORKDIR/bin" fi $LN_CMD "$DIFF" "$WORKDIR/bin" fi for inc in $INCLUDE_IN_WORKDIR do ( # Copy directory structure, but make links inside. This allows tests to # add additional files to the directory. base=$(basename $inc) mkdir -p "$WORKDIR/$base" cd $inc || exit 2 for dir in $(find . -type d) do mkdir -p "$WORKDIR/$base/$dir" done for file in $(find . \! -type d) do $LN_CMD "$inc/$file" "$WORKDIR/$base/$file" done ) done fi if uname | grep MINGW > /dev/null then PLATFORM_WORKDIR="$(echo $WORKDIR | sed -e 's%^/\([a-zA-Z]\)/%\1:/%' | sed -e 's%/%\\%g')" DS="\\" else PLATFORM_WORKDIR="$WORKDIR" DS="/" fi ( echo ---------------------------------------------------------------------- echo "$TEST" "$EXTRATEXT" echo ---------------------------------------------------------------------- ) >> "$WORKDIR/$LOG" echo "#!/bin/sh CFENGINE_TEST_OVERRIDE_WORKDIR=\"$PLATFORM_WORKDIR\" TEMP=\"$PLATFORM_WORKDIR${DS}tmp\" CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR=\"$CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR\" export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBRARY_DIR " > "$WORKDIR/runtest" if [ "$GDB" = 1 ] then if grep libtool < "$AGENT" > /dev/null then printf "\"$LIBTOOL\" --mode=execute " >> "$WORKDIR/runtest" fi printf "gdb --args " >> "$WORKDIR/runtest" fi if [ -n "$USE_VALGRIND" -a $TEST_TYPE = errorexit ] then if grep libtool < "$AGENT" > /dev/null then printf "\"$LIBTOOL\" --mode=execute " >> "$WORKDIR/runtest" fi printf "valgrind ${VALGRIND_OPTS} \"$AGENT\" $VERBOSE $DEBUG -Klf \"$TEST\" -D ${PASS_NUM:+test_pass_$PASS_NUM,}${BASECLASSES},${EXTRACLASSES} 2>&1\n" >> "$WORKDIR/runtest" elif [ x"$PRELOAD_ASAN" != x ] then printf "LD_PRELOAD=$PRELOAD_ASAN \"$AGENT\" $VERBOSE $DEBUG -Klf \"$TEST\" -D ${PASS_NUM:+test_pass_$PASS_NUM,}${BASECLASSES},${EXTRACLASSES}\n" >> "$WORKDIR/runtest" else printf "\"$AGENT\" $VERBOSE $DEBUG -Klf \"$TEST\" -D ${PASS_NUM:+test_pass_$PASS_NUM,}${BASECLASSES},${EXTRACLASSES}\n" >> "$WORKDIR/runtest" fi chmod +x "$WORKDIR/runtest" if [ "$GDB" = 1 ] then $GAINROOT "$WORKDIR/runtest" else eval $GAINROOT "$WORKDIR/runtest" >>$OUTFILE 2>&1 fi RETVAL=$? TEST_END_TIME=$(unix_seconds) cat $OUTFILE >> "$WORKDIR/$LOG" echo >> "$WORKDIR/$LOG" echo "Return code is $RETVAL." >> "$WORKDIR/$LOG" # Try to collect test metadata if any if egrep "R: test description: " $OUTFILE > /dev/null then TEST_DESCRIPTION="$(egrep "R: test description" $OUTFILE | sed -e "s,.*test description: \([A-Za-z0-9_]*\),\1,")" fi if egrep -e "R: test story_id: " $OUTFILE > /dev/null then TEST_STORY="$(egrep "R: test story_id" $OUTFILE | sed -e "s,.*test story_id: \([0-9][0-9]*\),\1,")" fi if egrep -e "R: test covers: " $OUTFILE > /dev/null then TEST_COVERS="$(egrep "R: test covers" $OUTFILE | sed -e "s,.*test covers: \([A-Za-z0-9_]*\),\1,")" fi if [ $TEST_TYPE = errorexit ] then if [ $RETVAL -gt 0 ] && [ $RETVAL -lt 128 ] && egrep "error:|aborted on defined class" $OUTFILE > /dev/null then RESULT=Pass RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}" elif [ $RETVAL -ge 128 ] then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (CRASH!!! THIS IS A BUG!)${COLOR_NORMAL}" else RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (Failed to exit with error!)${COLOR_NORMAL}" fi elif [ $TEST_TYPE = errorlog ] then if [ $RETVAL != 0 ] then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (NON-ZERO EXIT CODE!)${COLOR_NORMAL}" elif fgrep 'error: ' "$OUTFILE" > /dev/null then RESULT=Pass RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}" else RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (No errors printed)${COLOR_NORMAL}" fi else # TEST_TYPE is not errorlog or errorexit # We need to be careful when matching test outcomes. Because of convergence # passes, a test may output FAIL before it outputs Pass; in this case the # latter trumps the former. Also be careful when matching an [XS]FAIL; the # test should not be allowed to output any other outcome in the same run, # except for FAIL. # Some states are output by dcs.cf.sub, therefore check for both TEST # prefix and dcs.cf.sub prefix. ESCAPED_TEST="$(echo "($TEST|dcs.cf.sub)" | sed -e 's/\./\\./g')" if egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE > /dev/null && ! egrep "R: .*$ESCAPED_TEST Wait/" $OUTFILE > /dev/null then # Check for passed outcome, which should not happen. if egrep "R: .*$ESCAPED_TEST " $OUTFILE | egrep "R: .*$ESCAPED_TEST Pass" > /dev/null then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (The test Passed, but failure was expected)${COLOR_NORMAL}" elif egrep "R: .*$ESCAPED_TEST " $OUTFILE | egrep -v "R: .*$ESCAPED_TEST [XS]?FAIL" > /dev/null then # Other test case outcomes than fail. Should not happen. RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (Failure was expected, but the test had an unexpected test outcome, check test output, Pass/FAIL need to match exactly)${COLOR_NORMAL}" else TICKET="$(egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*[XS]FAIL/\(.*\),\1,")" RESULT="$(egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*\([XS]FAIL\).*,\1,")" if [ "$RESULT" = "XFAIL" ] then RESULT_MSG="${COLOR_WARNING}FAIL (Suppressed, $TICKET)${COLOR_NORMAL}" else RESULT_MSG="${COLOR_WARNING}Soft fail ($TICKET)${COLOR_NORMAL}" fi fi elif [ $RETVAL -ne 0 ] then RESULT=FAIL elif egrep "R: .*$ESCAPED_TEST FAIL/no_ticket_number" $OUTFILE > /dev/null then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (Tried to suppress failure, but no issue number is provided)${COLOR_NORMAL}" elif egrep "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE > /dev/null then if [ -z "$NEXT_TIMEOUT_VAR" ] then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (Test tried to wait but is not in \"timed\" directory)${COLOR_NORMAL}" else WAIT_TIME=$(egrep "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE | sed -e 's,.*Wait/\([0-9][0-9]*\).*,\1,') eval $NEXT_TIMEOUT_VAR=$(($TEST_END_TIME+$WAIT_TIME)) RESULT=Wait RESULT_MSG="Awaiting ($WAIT_TIME seconds)..." fi elif egrep "R: .*$ESCAPED_TEST Pass" $OUTFILE > /dev/null then RESULT=Pass RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}" elif egrep "R: .*$ESCAPED_TEST Skip/unsupported" $OUTFILE > /dev/null then RESULT=Skip RESULT_MSG="${COLOR_WARNING}Skipped (No platform support)${COLOR_NORMAL}" elif egrep "R: .*$ESCAPED_TEST Skip/needs_work" $OUTFILE > /dev/null then RESULT=Skip RESULT_MSG="${COLOR_WARNING}Skipped (Test needs work)${COLOR_NORMAL}" elif egrep "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE > /dev/null then RESULT=FLAKEY TICKET="$(egrep "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE | sed -e "s,.*FLAKEY/\(.*\),\1,")" RESULT_MSG="${COLOR_WARNING}Flakey fail ($TICKET)${COLOR_NORMAL}" else RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL${COLOR_NORMAL}" fi fi if [ "x$RESULT_MSG" = "x" ] then RESULT_MSG=$RESULT fi if [ "$RESULT" = "FAIL" ] && [ -e .succeeded/"$FLATNAME" ] then RESULT_MSG="${COLOR_FAILURE}$RESULT_MSG (UNEXPECTED FAILURE)${COLOR_NORMAL}" fi fi if [ "$RESULT" = "XFAIL" -o "$RESULT" = "SFAIL" ] then echo " " elif [ "$RESULT" != Wait ] then echo " " fi >> "$WORKDIR/$XML" # Fill test metadata if any if [ ! -z "$TEST_DESCRIPTION" ] || [ ! -z "$TEST_STORY" ] || [ ! -z "$TEST_COVERS" ] then if [ ! -z "$TEST_DESCRIPTION" ] then TEST_DESCRIPTION_METATAG="name=\"$TEST_DESCRIPTION\"" fi if [ ! -z "$TEST_STORY" ] then TEST_STORY_METATAG="story_id=\"$TEST_STORY\"" fi if [ ! -z "$TEST_COVERS" ] then TEST_COVERS_METATAG="covers=\"$TEST_COVERS\"" fi echo " $TEST_DESCRIPTION_METATAG $TEST_STORY_METATAG $TEST_COVERS_METATAG" fi >> "$WORKDIR/$XML" echo $RESULT $TEST >> "$WORKDIR/$SUMMARY" case "$RESULT" in Pass) PASSED_TESTS=$(($PASSED_TESTS + 1)) mkdir -p '.succeeded' touch .succeeded/"$FLATNAME" ;; FAIL|XFAIL) ( echo " " cat $OUTFILE | sed -e "s/&/\&/g; s//\>/g; s/'/\"/g" echo " " ) >> "$WORKDIR/$XML" FAILED_TESTS=$(($FAILED_TESTS + 1)) if [ "$RESULT" = "XFAIL" ] then SUPPRESSED_FAILURES=$(($SUPPRESSED_FAILURES + 1)) fi ;; SFAIL) ( echo " " echo " message=\"$RESULT_MSG $TEST\">" cat $OUTFILE | sed -e "s/&/\&/g; s//\>/g; s/'/\"/g" echo " " ) >> "$WORKDIR/$XML" SOFT_FAILURES=$(($SOFT_FAILURES + 1)) ;; Skip) ( echo " " echo " " ) >> "$WORKDIR/$XML" SKIPPED_TESTS=$(($SKIPPED_TESTS + 1)) ;; esac if [ "$RESULT" != Wait ] then echo " " >> "$WORKDIR/$XML" fi if [ -e "$WORKDIR" -a "$RESULT" != "FAIL" -a "$RESULT" != "Wait" -a "$NO_CLEAN" = "0" ] then # Delete everything except the logs from the workdir. ls -1 "$WORKDIR" | while read s do case "$s" in "$LOG"|"$SUMMARY"|"$XML") ;; *) $GAINROOT rm -fr "$WORKDIR/$s" ;; esac done if [ "$GITHUB_ACTIONS" = "true" ] && [ "$RUNNER_OS" = "Windows" ] then # on Github Actions Windows runners, `rm -rf` moves files into /d/d/ directory. # To clean this "Recycle bin", we delete this directory. # Otherwise, runner promptly run out of disk space. rm -rf /d/d/ fi fi if [ -z "$QUIET" ] then if [ -n "$STAY_IN_WORKDIR" ] then # See comment about STAY_IN_WORKDIR near start of runtest. echo "$TEST $RESULT_MSG" else echo $RESULT_MSG fi else if [ "$RESULT" = Pass ] then printf '.' elif [ "$RESULT" = Skip ] then printf '-' elif [ "$RESULT" = FAIL ] then if [ $TEST_TYPE = errorexit ] then printf '!' else printf 'x' fi fi fi ( echo echo ' ==>' "$RESULT_MSG" echo ) >> "$WORKDIR/$LOG" } ORIG_ARGS= while true do case "$1" in -h|--help) usage exit;; -q|--quiet) QUIET=1;; --gainroot=*) GAINROOT=${1#--gainroot=};; --valgrind) USE_VALGRIND=1;; --callgrind) USE_VALGRIND=1 VALGRIND_OPTS="--suppressions=valgrind-suppressions --tool=callgrind";; --inotifywatch) USE_INOTIFYWATCH=1;; --inotifywait) USE_INOTIFYWAIT=1;; --tests=*) # Deselect all test types, in order to have only the ones # given as arguments COMMON_TESTS=0 TIMED_TESTS=0 SLOW_TESTS=0 ERROREXIT_TESTS=0 ERRORLOG_TESTS=0 SERIAL_TESTS=0 NETWORK_TESTS=0 LIBXML2_TESTS=0 LIBCURL_TESTS=0 UNSAFE_TESTS=0 STAGING_TESTS=0 TESTS_SELECTED=${1#--tests=} for testtype in `echo $TESTS_SELECTED | tr , ' '` do case "$testtype" in common) COMMON_TESTS=1;; timed) TIMED_TESTS=1;; slow) SLOW_TESTS=1;; errorexit) ERROREXIT_TESTS=1;; errorlog) ERRORLOG_TESTS=1;; serial) SERIAL_TESTS=1;; network) NETWORK_TESTS=1;; libxml2) LIBXML2_TESTS=1;; libcurl) LIBCURL_TESTS=1;; unsafe) UNSAFE_TESTS=1;; staging) STAGING_TESTS=1;; esac done ;; --agent=*) AGENT=${1#--agent=};; --baseclasses=*) BASECLASSES=${1#--baseclasses=};; --bc=*) BASECLASSES=${1#--bc=};; --extraclasses=*) EXTRACLASSES=${1#--extraclasses=};; --ec=*) EXTRACLASSES=${1#--ec=};; --cfpromises=*) CF_PROMISES=${1#--cfpromises=};; --cfserverd=*) CF_SERVERD=${1#--cfserverd=};; --cfexecd=*) CF_EXECD=${1#--cfexecd=};; --cfkey=*) CF_KEY=${1#--cfkey=};; --cfkeycrypt=*) CF_SECRET=${1#--cfkeycrypt=};; --cfnet=*) CF_NET=${1#--cfnet=};; --cfcheck=*) CF_CHECK=${1#--cfcheck=};; --cfrunagent=*) CF_RUNAGENT=${1#--cfrunagent=};; --rpmvercmp=*) RPMVERCMP=${1#--rpmvercmp=};; --bindir=*) BINDIR=${1#--bindir=};; --libtool=*) LIBTOOL=${1#--libtool=};; --include=*) INCLUDE_IN_WORKDIR="$INCLUDE_IN_WORKDIR${INCLUDE_IN_WORKDIR:+ }${1#--include=}";; -j*|--jobs*) MAKEFLAGS="$MAKEFLAGS $1";; --printlog) PRINTLOG=1;; --gdb) GDB=1;; --no-clean) NO_CLEAN=1;; --verbose) VERBOSE="-v";; --debug) DEBUG="--debug";; --stay-in-workdir) # Internal option. Meant to keep sub invocations from interfering by # writing files only into the workdir. STAY_IN_WORKDIR=1;; --base-workdir=*) BASE_WORKDIR="${1#--base-workdir=}";; -*) echo "Unknown option: $1" exit 1;; *) break;; esac # Make sure spaces are preserved by escaping them. ORIG_ARGS="$ORIG_ARGS $(echo "$1" | sed -e 's/ /\\ /g')" shift done # # Close stdin file descriptor to avoid tty_interactive check in cf-agent being success. # Do this iff GDB AND Valgrind are not in use. # if [ "$GDB" != 1 ] && [ "$USE_VALGRIND" != 1 ] then exec /dev/null then # On Windows we run the entire test run under GAINROOT, because doing it for # each test is horribly slow. echo "export GAINROOT=" > runtests.sh echo "export TESTALL_DO_NOT_RECURSE=1" >> runtests.sh echo "export DEBUG='$DEBUG'" >> runtests.sh echo "export VERBOSE='$VERBOSE'" >> runtests.sh echo "$0 $ORIG_ARGS $@ &" >> runtests.sh # Note quote change. We want to keep below variables unexpanded. echo 'trap "kill $!" INT' >> runtests.sh echo 'trap "kill $!" TERM' >> runtests.sh # Traps do not fire during commands, but *do* fire during wait. echo 'wait $!' >> runtests.sh $GAINROOT "./runtests.sh" exit $? fi # Check last -j flag, and check if it is -j1. for arg in $MAKEFLAGS do case "$arg" in -j|--jobs) PARALLEL=1 ;; -j*) if [ 1 -eq "${arg#-j}" ] then PARALLEL= else PARALLEL=1 fi ;; --jobs=*) if [ 1 -eq "${arg#--jobs=}" ] then PARALLEL= else PARALLEL=1 fi ;; esac done # check if rpm is used on this host, sometimes it can be installed but not used say on Ubuntu if [ -n "$(command -v rpm)" ] && [ "$(rpm -qa | wc -l)" != "0" ] then NEED_RPMVERCMP="yes" else NEED_RPMVERCMP="no" fi if [ -n "$AGENT" -o -n "$CF_PROMISES" -o -n "$CF_SERVERD" -o -n "$CF_EXECD" -o -n "$CF_KEY" -o -n "$CF_SECRET" -o -n "$CF_NET" -o -n "$CF_CHECK" -o -n "$CF_RUNAGENT" -o \( "$NEED_RPMVERCMP" = "yes" -a -n "$RPMVERCMP" \) -o -n "$DIFF" ] then if [ -n "$BINDIR" ] then echo "--bindir is mutually exclusive with specifying individual binaries." exit 2 fi fi # We assume we're running this script from one of the following # $objdir # $objdir/tests/acceptance # /var/cfengine/tests/acceptance or from # $core_objdir/../{enterprise,masterfiles}/tests/acceptance find_default_binary() { [ -x "`pwd`/../../../core/$2/$2" ] && eval $1=\""`pwd`/../../../core/$2/$2"\" [ -x "`pwd`/../../../core/ext/$2" ] && eval $1=\""`pwd`/../../../core/ext/$2"\" [ -x "`pwd`/../../ext/$2" ] && eval $1=\""`pwd`/../../ext/$2"\" [ -x "`pwd`/../../bin/$2" ] && eval $1=\""`pwd`/../../bin/$2"\" [ -x "`pwd`/../../$2/$2" ] && eval $1=\""`pwd`/../../$2/$2"\" [ -x "`pwd`/$2/$2" ] && eval $1=\""`pwd`/$2/$2"\" [ -n "$BINDIR" -a -x "$BINDIR/$2" ] && eval $1=\""$BINDIR/$2"\" [ $2 = "diff" ] && eval $1=\""`command -v diff`"\" } find_default_binary DEFAGENT cf-agent find_default_binary DEFCF_PROMISES cf-promises find_default_binary DEFCF_SERVERD cf-serverd find_default_binary DEFCF_EXECD cf-execd find_default_binary DEFCF_KEY cf-key find_default_binary DEFCF_SECRET cf-secret find_default_binary DEFCF_NET cf-net find_default_binary DEFCF_CHECK cf-check find_default_binary DEFCF_RUNAGENT cf-runagent if [ "$NEED_RPMVERCMP" = "yes" ] then find_default_binary DEFRPMVERCMP rpmvercmp fi find_default_binary DIFF diff [ -x "`pwd`/libtool" ] && DEFLIBTOOL="`pwd`/libtool" [ -x "`pwd`/../../libtool" ] && DEFLIBTOOL="`pwd`/../../libtool" AGENT=${AGENT:-${DEFAGENT}} CF_PROMISES=${CF_PROMISES:-${DEFCF_PROMISES}} CF_SERVERD=${CF_SERVERD:-${DEFCF_SERVERD}} CF_EXECD=${CF_EXECD:-${DEFCF_EXECD}} CF_KEY=${CF_KEY:-${DEFCF_KEY}} CF_SECRET=${CF_SECRET:-${DEFCF_SECRET}} CF_NET=${CF_NET:-${DEFCF_NET}} CF_CHECK=${CF_CHECK:-${DEFCF_CHECK}} CF_RUNAGENT=${CF_RUNAGENT:-${DEFCF_RUNAGENT}} RPMVERCMP=${RPMVERCMP:-${DEFRPMVERCMP}} LIBTOOL=${LIBTOOL:-${DEFLIBTOOL}} if [ ! -x "$AGENT" -o ! -x "$CF_PROMISES" -o ! -x "$CF_SERVERD" -o ! -x "$CF_EXECD" -o ! -x "$CF_KEY" -o ! -x "$CF_SECRET" -o ! -x "$CF_NET" -o ! -x "$CF_CHECK" -o ! -x "$CF_RUNAGENT" -o \( "$NEED_RPMVERCMP" = "yes" -a ! -x "$RPMVERCMP" \) ] then echo "ERROR: can't find cf-agent or other binary;" \ " Are you sure you're running this from OBJDIR" \ " or {core,masterfiles,enterprise}_OBJDIR/tests/acceptance ?" echo '$AGENT =' "$AGENT" echo '$CF_PROMISES =' "$CF_PROMISES" echo '$CF_SERVERD =' "$CF_SERVERD" echo '$CF_EXECD =' "$CF_EXECD" echo '$CF_KEY =' "$CF_KEY" echo '$CF_SECRET =' "$CF_SECRET" echo '$CF_RUNAGENT =' "$CF_RUNAGENT" echo '$CF_NET =' "$CF_NET" echo '$CF_CHECK =' "$CF_CHECK" echo '$RPMVERCMP =' "$RPMVERCMP" exit 1 fi if [ "$UNSAFE_TESTS" = "1" ] then if [ "$GAINROOT" = "fakeroot" ] then echo "Unsafe tests do not play well together with fakeroot. Please use a different" echo "--gainroot (like \"sudo\"), or you will get incorrect results." exit 1 fi # Make sure test dir is accessible to everyone, because unsafe tests may # switch user during the test (users promises do this). DIR="$(cd "$(dirname "$0")"; pwd)" while [ "$DIR" != "/" -a "$DIR" != "" ] do $GAINROOT chmod go+rx "$DIR" DIR="$(dirname "$DIR")" done fi if [ $# -gt 0 ] then # We run all specified tests according to the defaults (no unsafe ones). for test in "$@" do if ! expr "$test" : '[/.]' >/dev/null then test="./$test" fi if [ -f $test ] then ALL_TESTS="$ALL_TESTS${ALL_TESTS:+ }$test" elif [ -d $test ] then ALL_TESTS="$ALL_TESTS${ALL_TESTS:+ }$(find "$test" -name workdir -prune -o -name '*.cf' -print | sort)" else echo "Unable to open test file/directory: $test" fi done else ALL_TESTS="$ALL_TESTS${ALL_TESTS:+ }$(find . \( -name selftest -o -name workdir \) -prune -o -name '*.cf' -print | sort)" fi for addtest in $ALL_TESTS do if echo "$addtest" | fgrep "/timed/" > /dev/null then if [ "$TIMED_TESTS" = 1 ] then eval TESTS_TIMED_$TEST_TIMED_INDEX="$addtest" eval TESTS_TIMEOUT_$TEST_TIMED_INDEX=0 eval TESTS_PASSES_$TEST_TIMED_INDEX=0 TEST_TIMED_INDEX=$(($TEST_TIMED_INDEX+1)) fi else eval TESTS_$TEST_INDEX="$addtest" TEST_INDEX=$(($TEST_INDEX+1)) fi done TESTS_NORMAL_COUNT=$TEST_INDEX TESTS_TIMED_COUNT=$TEST_TIMED_INDEX TESTS_COUNT=$(($TESTS_NORMAL_COUNT + $TESTS_TIMED_COUNT)) TESTS_TIMED_REMAINING=$TEST_TIMED_INDEX # # fd 7 is a /dev/null for quiet execution and stdout for default one # if [ -z "$QUIET" ] then exec 7>&1 else exec 7>/dev/null fi print_header() { ( echo ====================================================================== echo Testsuite started at $(date "+%Y-%m-%d %T") echo ---------------------------------------------------------------------- echo Total tests: $TESTS_COUNT echo for feature in COMMON_TESTS TIMED_TESTS SLOW_TESTS ERROREXIT_TESTS SERIAL_TESTS NETWORK_TESTS LIBXML2_TESTS LIBCURL_TESTS UNSAFE_TESTS STAGING_TESTS do if eval "[ \${$feature} != 0 ]" then printf '%20s: %s\n' $feature enabled else printf '%20s: %s\n' $feature disabled fi done echo if [ x$PARALLEL = x1 ] then echo "Test run is PARALLEL with MAKEFLAGS=$MAKEFLAGS" else echo "Test run is not parallel ${MAKEFLAGS:+(MAKEFLAGS=$MAKEFLAGS)}" fi echo ) | tee "$LOG" | tee "$SUMMARY" >&7 } print_footer() { # Recalculate results since sub invocations may not have been recorded. PASSED_TESTS=`egrep '^Pass ' $SUMMARY | wc -l | tr -d ' '` FAILED_TESTS=`egrep '^(FAIL|XFAIL) ' $SUMMARY | wc -l | tr -d ' '` SUPPRESSED_FAILURES=`egrep '^XFAIL ' $SUMMARY | wc -l | tr -d ' '` SOFT_FAILURES=`egrep '^SFAIL ' $SUMMARY | wc -l | tr -d ' '` FLAKEY_FAILURES=`egrep '^FLAKEY ' $SUMMARY | wc -l | tr -d ' '` SKIPPED_TESTS=`egrep '^Skip ' $SUMMARY | wc -l | tr -d ' '` ( echo echo ====================================================================== echo "Testsuite finished at $(date "+%F %T") ($(($END_TIME - $START_TIME)) seconds)" ) | tee -a "$LOG" | tee -a "$SUMMARY" >&7 ( echo echo "Passed tests: $PASSED_TESTS" printf "Failed tests: $FAILED_TESTS" if [ $SUPPRESSED_FAILURES -gt 0 ] then echo " ($SUPPRESSED_FAILURES are known and suppressed)" else echo fi echo "Skipped tests: $SKIPPED_TESTS" echo "Soft failures: $SOFT_FAILURES" echo "Flakey failures: $FLAKEY_FAILURES" echo "Total tests: $TESTS_COUNT" ) | tee -a "$LOG" | tee -a "$SUMMARY" if [ -n "$PRINTLOG" ] then cat "$LOG" fi } finish_xml() { mv "$XML" xml.tmp ( cat < EOF cat xml.tmp cat < EOF ) > "$XML" rm -f xml.tmp } collect_results() { if [ -n "$STAY_IN_WORKDIR" ] then return 0 fi WORKDIR="$(workdir "$1")" for file in "$LOG" "$SUMMARY" "$XML" do if [ -e "$WORKDIR/$file" ] then cat "$WORKDIR/$file" >> "$file" if [ "$NO_CLEAN" = "0" ] then # For unknown reason after the second pass, these file are root-owned, so we need GAINROOT here $GAINROOT rm -f "$WORKDIR/$file" fi fi done rmdir "$WORKDIR" >/dev/null 2>&1 || true } check_and_run_timed_tests() { TEST_TIMED_INDEX=0 time=$(unix_seconds) # Run timed tests if any deadlines have expired. while [ $TEST_TIMED_INDEX -lt $TESTS_TIMED_COUNT ] do eval test=\$TESTS_TIMED_$TEST_TIMED_INDEX eval timeout=\$TESTS_TIMEOUT_$TEST_TIMED_INDEX if [ -n "$timeout" ] && [ "$time" -ge "$timeout" ] then eval TESTS_PASSES_$TEST_TIMED_INDEX="\$((\$TESTS_PASSES_$TEST_TIMED_INDEX+1))" eval pass=\$TESTS_PASSES_$TEST_TIMED_INDEX runtest "$AGENT" "$test" "$pass" "TESTS_TIMEOUT_$TEST_TIMED_INDEX" collect_results "$test" eval timeout=\$TESTS_TIMEOUT_$TEST_TIMED_INDEX if [ -z "$timeout" ] then TESTS_TIMED_REMAINING=$(($TESTS_TIMED_REMAINING - 1)) fi fi TEST_TIMED_INDEX=$(($TEST_TIMED_INDEX+1)) done } run_all_tests() { TEST_INDEX=0 while [ $TEST_INDEX -lt $TESTS_NORMAL_COUNT -o $TESTS_TIMED_REMAINING -gt 0 ] do check_and_run_timed_tests # Run normal test. if [ $TEST_INDEX -lt $TESTS_NORMAL_COUNT ] then eval test=\$TESTS_$TEST_INDEX runtest "$AGENT" "$test" collect_results "$test" TEST_INDEX=$(($TEST_INDEX+1)) elif [ $TESTS_TIMED_REMAINING -gt 0 ] then sleep 1 fi done } # TODO this function is currently creating a Makefile with all possible # tests, either they will run or be skipped. The proper way is to # do all the checks that now are in runtest(), and add the test # here only if it will run. This should be done higher up, where # ALL_TESTS is populated. # # When this is done, there won't be a need to pass --tests=... down # the makefile subexecutions. run_all_tests_using_make() { MAKEFILE=Makefile.testall TEST_BLOCKS=1 LAST_WAS_SERIAL=0 for curr_test in $ALL_TESTS do # Keep serial tests after preceding tests and before following tests. case "$curr_test" in */serial_*|*_serial_*|*_serial.*|*/serial/*|*/unsafe/*) if [ $LAST_WAS_SERIAL = 0 ] then TEST_BLOCKS=$(($TEST_BLOCKS + 1)) LAST_WAS_SERIAL=1 fi ;; *) if [ $LAST_WAS_SERIAL = 1 ] then TEST_BLOCKS=$(($TEST_BLOCKS + 1)) LAST_WAS_SERIAL=0 fi ;; esac case "$curr_test" in */serial_*|*_serial_*|*_serial.*|*/serial/*|*/unsafe/*|*/timed/*|*/slow/*) eval MAKE_RECIPE_LIST$TEST_BLOCKS='$MAKE_RECIPE_LIST'$TEST_BLOCKS'${MAKE_RECIPE_LIST'$TEST_BLOCKS':+ }$curr_test' ;; *) # Separate make target list (notice the "_rule"), because we do not want the target to be a # file name, since make will skip it if it exists (which of course it does). eval MAKE_TARGET_LIST$TEST_BLOCKS='$MAKE_TARGET_LIST'$TEST_BLOCKS'${MAKE_TARGET_LIST'$TEST_BLOCKS':+ }${curr_test}_rule' ;; esac done # Redirect to makefile all at once. ( printf "tests:\n\n" printf "parallel_block0:\n\n" printf "serial_block0:\n\n" printf "tests: serial_block0 parallel_block0\n\n" i=1 while [ $i -le $TEST_BLOCKS ] do if eval test -n '"$MAKE_RECIPE_LIST'$i'"' then eval printf '"serial_block$i:\n\t@-$0 --stay-in-workdir -j1 ${TESTS_SELECTED:+--tests=$TESTS_SELECTED} $MAKE_RECIPE_LIST'$i'\n\n"' fi printf "serial_block$i: serial_block$(($i-1)) parallel_block$(($i-1))\n\n" eval printf '"parallel_block$i: $MAKE_TARGET_LIST'$i'\n\n"' if eval test -n '"$MAKE_TARGET_LIST'$i'"' then eval printf '"$MAKE_TARGET_LIST'$i': serial_block$(($i-1)) parallel_block$(($i-1))\n\n"' fi printf "tests: serial_block$i parallel_block$i\n\n" i=$(($i + 1)) done printf "%%_rule: %%\n\t@-$0 --stay-in-workdir -j1 ${TESTS_SELECTED:+--tests=$TESTS_SELECTED} \$<\n\n" ) > $MAKEFILE ${MAKE:-make} -k -f $MAKEFILE for curr_test in $ALL_TESTS do collect_results "$curr_test" done } # # ========== RUN THE TESTS ========== # # isEnabled? USE_INOTIFYWATCH if [ -n "$USE_INOTIFYWATCH" ] then if which inotifywatch 2>&1 > /dev/null then mkdir -p "$BASE_WORKDIR" 2> /dev/null inotifywatch ${INOTIFYWATCH_OPTS} $BASE_WORKDIR < /dev/null 2>&1 > ${INOTIFYWATCH_LOG} & INOTIFYWATCH_PID=$! else echo "info: inotifywatch not detected." exit 0 fi fi # isEnabled? USE_INOTIFYWAIT if [ -n "$USE_INOTIFYWAIT" ] then if which inotifywait 2>&1 > /dev/null then mkdir -p "$BASE_WORKDIR" 2> /dev/null inotifywait ${INOTIFYWAIT_OPTS} $BASE_WORKDIR < /dev/null 2>&1 > ${INOTIFYWAIT_LOG} & INOTIFYWAIT_PID=$! else echo "info: inotifywait not detected." exit 0 fi fi trap_handler() { [ -n "$INOTIFYWATCH_PID" ] && kill -9 ${INOTIFYWATCH_PID} 2>&1 > /dev/null [ -n "$INOTIFYWAIT_PID" ] && kill -9 ${INOTIFYWAIT_PID} 2>&1 > /dev/null exit 0 } if [ -n "$USE_INOTIFYWATCH" -o -n "$USE_INOTIFYWAIT" ] then trap trap_handler EXIT INT TERM fi START_TIME=$(unix_seconds) if [ -z "$STAY_IN_WORKDIR" ] then # This is top level invocation. print_header rm -f "$XML" fi if [ -z "$PARALLEL" -o "$TESTS_COUNT" -eq 1 ] then run_all_tests else run_all_tests_using_make fi END_TIME=$(unix_seconds) if [ -z "$STAY_IN_WORKDIR" ] then # This is top level invocation. print_footer finish_xml fi if [ $(($PASSED_TESTS+$FAILED_TESTS+$SOFT_FAILURES+$SKIPPED_TESTS+$FLAKEY_FAILURES)) -ne $TESTS_COUNT ] then echo "WARNING: Number of test results does not match number of tests!" echo "Did something go wrong during execution?" exit 2 fi if [ "$FAILED_TESTS" -gt "$SUPPRESSED_FAILURES" ] then exit 1 elif [ "$FLAKEY_FAILURES" -gt "0" ] && [ -n "$FLAKEY_IS_FAIL" ] then exit 4 else exit 0 fi cfengine-3.24.2/tests/acceptance/write_args.sh0000755000000000000000000000054315010704253021312 0ustar00rootroot00000000000000#!/bin/sh # WARNING keep this /bin/sh compatible! # Outputs to file $1 all the rest of the arguments if [ $# = 0 ] then echo "ERROR: At least one argument OUTPUT_FILE expected!" exit 1 fi OUTFILE="$1" if [ -f "$OUTFILE" ] then echo "ERROR: already exists, I refuse to overwrite file: $OUTFILE" exit 1 fi shift echo "$*" > "$OUTFILE" cfengine-3.24.2/tests/acceptance/mock_package_manager.c0000644000000000000000000003102315010704253023044 0ustar00rootroot00000000000000#include #include #include #include // Syntax() #include static char AVAILABLE_PACKAGES_FILE_NAME[PATH_MAX]; static char INSTALLED_PACKAGES_FILE_NAME[PATH_MAX]; static const int MAX_PACKAGE_ENTRY_LENGTH = 256; #define DEFAULT_ARCHITECTURE "x666" #define Error(msg) fprintf(stderr, "%s:%d: %s", __FILE__, __LINE__, msg) static const Component COMPONENT = { .name = "mock-package-manager - pretend that you are managing packages!", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"clear-installed", no_argument, 0, 'c'}, {"clear-available", no_argument, 0, 'C'}, {"list-installed", no_argument, 0, 'l'}, {"list-available", no_argument, 0, 'L'}, {"populate-available", required_argument, 0, 'P'}, {"add", required_argument, 0, 'a'}, {"delete", required_argument, 0, 'd'}, {"reinstall", required_argument, 0, 'r'}, {"update", required_argument, 0, 'u'}, {"addupdate", required_argument, 0, 'U'}, {"verify", required_argument, 0, 'v'}, {NULL, 0, 0, '\0'} }; static const char *HINTS[] = { "Clear all installed imaginary packages", "Clear all available imaginary packages", "List installed imarginary packages", "List imaginary packages available to be installed", "Add an imaginary package to list of available", "Add an imaginary package", "Delete a previously imagined package", "Reinstall an imaginary package", "Update a previously imagined package", "Add or update an imaginary package", "Verify a previously imagined package", NULL }; typedef struct { char *name; char *version; char *arch; } Package; typedef struct { char *name; char *version; char *arch; } PackagePattern; /******************************************************************************/ static char *SerializePackage(Package *package) { char *s; xasprintf(&s, "%s:%s:%s", package->name, package->version, package->arch); return s; } /******************************************************************************/ static char *SerializePackagePattern(PackagePattern *pattern) { char *s; xasprintf(&s, "%s:%s:%s", pattern->name ? pattern->name : "*", pattern->version ? pattern->version : "*", pattern->arch ? pattern->arch : "*"); return s; } /******************************************************************************/ static Package *DeserializePackage(const char *entry) { Package *package = xcalloc(1, sizeof(Package)); char *entry_copy = xstrdup(entry); package->name = strtok(entry_copy, ":"); package->version = strtok(NULL, ":"); package->arch = strtok(NULL, ":"); if (package->name == NULL || strcmp(package->name, "*") == 0 || package->version == NULL || strcmp(package->version, "*") == 0 || package->arch == NULL || strcmp(package->arch, "*") == 0) { fprintf(stderr, "Incomplete package specification: %s:%s:%s\n", package->name, package->version, package->arch); exit(255); } return package; } /******************************************************************************/ static bool IsWildcard(const char *str) { return str && (strcmp(str, "*") == 0 || strcmp(str, "") == 0); } /******************************************************************************/ static void CheckWellformedness(const char *str) { if (str && strchr(str, '*') != NULL) { fprintf(stderr, "* is encountered in pattern not as wildcard: '%s'\n", str); exit(255); } } /******************************************************************************/ static PackagePattern *NewPackagePattern(const char *name, const char *version, const char *arch) { PackagePattern *pattern = xcalloc(1, sizeof(PackagePattern)); pattern->name = name ? xstrdup(name) : NULL; pattern->version = version ? xstrdup(version) : NULL; pattern->arch = arch ? xstrdup(arch) : NULL; return pattern; } /******************************************************************************/ static PackagePattern *DeserializePackagePattern(const char *entry) { //PackagePattern *pattern = xcalloc(1, sizeof(PackagePattern)); char *entry_copy = xstrdup(entry); char *name = strtok(entry_copy, ":"); if (IsWildcard(name)) { name = NULL; } CheckWellformedness(name); char *version = strtok(NULL, ":"); if (IsWildcard(version)) { version = NULL; } CheckWellformedness(version); char *arch = strtok(NULL, ":"); if (arch == NULL) { arch = DEFAULT_ARCHITECTURE; } else if (IsWildcard(arch)) { arch = NULL; } CheckWellformedness(arch); if (strtok(NULL, ":") != NULL) { fprintf(stderr, "Too many delimiters are encountered in pattern: %s\n", entry); exit(255); } return NewPackagePattern(name, version, arch); } /******************************************************************************/ static Seq *ReadPackageEntries(const char *database_filename) { FILE *packages_file = fopen(database_filename, "r"); Seq *packages = SeqNew(1000, NULL); if (packages_file != NULL) { char serialized_package[MAX_PACKAGE_ENTRY_LENGTH]; while (fscanf(packages_file, "%s\n", serialized_package) != EOF) { Package *package = DeserializePackage(serialized_package); SeqAppend(packages, package); } fclose(packages_file); } return packages; } /******************************************************************************/ static void SavePackages(const char *database_filename, Seq *package_entries) { FILE *packages_file = fopen(database_filename, "w"); for (size_t i = 0; i < SeqLength(package_entries); i++) { fprintf(packages_file, "%s\n", SerializePackage(SeqAt(package_entries, i))); } fclose(packages_file); } /******************************************************************************/ static PackagePattern *MatchAllVersions(const Package *p) { return NewPackagePattern(p->name, NULL, p->arch); } /******************************************************************************/ static PackagePattern *MatchSame(const Package *p) { return NewPackagePattern(p->name, p->version, p->arch); } /******************************************************************************/ static bool MatchPackage(PackagePattern *a, Package *b) { return (a->name == NULL || strcmp(a->name, b->name) == 0) && (a->version == NULL || strcmp(a->version, b->version) == 0) && (a->arch == NULL || strcmp(a->arch, b->arch) == 0); } /******************************************************************************/ static Seq *FindPackages(const char *database_filename, PackagePattern *pattern) { Seq *db = ReadPackageEntries(database_filename); Seq *matching = SeqNew(1000, NULL); for (size_t i = 0; i < SeqLength(db); i++) { Package *package = SeqAt(db, i); if (MatchPackage(pattern, package)) { SeqAppend(matching, package); } } return matching; } /******************************************************************************/ static void ShowPackages(FILE *out, Seq *package_entries) { for (size_t i = 0; i < SeqLength(package_entries); i++) { fprintf(out, "%s\n", SerializePackage(SeqAt(package_entries, i))); } } /******************************************************************************/ static void ClearPackageList(const char *db_file_name) { FILE *packages_file = fopen(db_file_name, "w"); if (packages_file == NULL) { fprintf(stderr, "fopen(%s): %s", INSTALLED_PACKAGES_FILE_NAME, strerror(errno)); exit(255); } fclose(packages_file); } /******************************************************************************/ static void ClearInstalledPackages(void) { ClearPackageList(INSTALLED_PACKAGES_FILE_NAME); } /******************************************************************************/ static void ClearAvailablePackages(void) { ClearPackageList(AVAILABLE_PACKAGES_FILE_NAME); } /******************************************************************************/ static void AddPackage(PackagePattern *pattern) { fprintf(stderr, "Trying to install all packages matching pattern %s\n", SerializePackagePattern(pattern)); Seq *matching_available = FindPackages(AVAILABLE_PACKAGES_FILE_NAME, pattern); if (SeqLength(matching_available) == 0) { fprintf(stderr, "Unable to find any package matching %s\n", SerializePackagePattern(pattern)); exit(EXIT_FAILURE); } for (size_t i = 0; i < SeqLength(matching_available); i++) { Package *p = SeqAt(matching_available, i); PackagePattern *pat = MatchAllVersions(p); if (SeqLength(FindPackages(INSTALLED_PACKAGES_FILE_NAME, pat)) > 0) { fprintf(stderr, "Package %s is already installed.\n", SerializePackage(p)); exit(EXIT_FAILURE); } } Seq *installed_packages = ReadPackageEntries(INSTALLED_PACKAGES_FILE_NAME); for (size_t i = 0; i < SeqLength(matching_available); i++) { Package *p = SeqAt(matching_available, i); SeqAppend(installed_packages, p); fprintf(stderr, "Successfully installed package %s\n", SerializePackage(p)); } SavePackages(INSTALLED_PACKAGES_FILE_NAME, installed_packages); exit(EXIT_SUCCESS); } /******************************************************************************/ static void PopulateAvailable(const char *arg) { Package *p = DeserializePackage(arg); PackagePattern *pattern = MatchSame(p); if (SeqLength(FindPackages(AVAILABLE_PACKAGES_FILE_NAME, pattern)) > 0) { fprintf(stderr, "Skipping already available package %s\n", SerializePackage(p)); return; } Seq *available_packages = ReadPackageEntries(AVAILABLE_PACKAGES_FILE_NAME); SeqAppend(available_packages, p); SavePackages(AVAILABLE_PACKAGES_FILE_NAME, available_packages); } /******************************************************************************/ int main(int argc, char *argv[]) { extern char *optarg; int option_index = 0; int c; #ifdef __MINGW32__ InitializeWindows(); #endif char *workdir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR"); char *tempdir = getenv("TEMP"); if (!workdir && !tempdir) { fprintf(stderr, "Please set either CFENGINE_TEST_OVERRIDE_WORKDIR or TEMP environment variables\n" "to a valid directory.\n"); return 2; } xsnprintf(AVAILABLE_PACKAGES_FILE_NAME, 256, "%s/cfengine-mock-package-manager-available", workdir ? workdir : tempdir); xsnprintf(INSTALLED_PACKAGES_FILE_NAME, 256, "%s/cfengine-mock-package-manager-installed", workdir ? workdir : tempdir); while ((c = getopt_long(argc, argv, "", OPTIONS, &option_index)) != EOF) { PackagePattern *pattern = NULL; switch (c) { case 'c': ClearInstalledPackages(); break; case 'C': ClearAvailablePackages(); break; case 'l': { Seq *installed_packages = ReadPackageEntries(INSTALLED_PACKAGES_FILE_NAME); ShowPackages(stdout, installed_packages); } break; case 'L': { Seq *available_packages = ReadPackageEntries(AVAILABLE_PACKAGES_FILE_NAME); ShowPackages(stdout, available_packages); } break; case 'a': pattern = DeserializePackagePattern(optarg); AddPackage(pattern); break; case 'P': PopulateAvailable(optarg); break; /* case 'd': */ /* DeletePackage(pattern); */ /* break; */ /* case 'r': */ /* ReinstallPackage(pattern); */ /* break; */ /* case 'u': */ /* UpdatePackage(pattern); */ /* break; */ /* case 'U': */ /* AddUpdatePackage(pattern); */ /* break; */ /* case 'v': */ /* VerifyPackage(pattern); */ /* break; */ default: { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, false); FileWriterDetach(w); } exit(EXIT_FAILURE); } } return 0; } cfengine-3.24.2/tests/acceptance/31_tickets/0000755000000000000000000000000015010704253020554 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3988/0000755000000000000000000000000015010704253021562 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3988/1/0000755000000000000000000000000015010704253021722 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3988/1/test.cf0000644000000000000000000000435215010704253023217 0ustar00rootroot00000000000000body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent init { files: # Seed the file we will exercise the test on "$(G.testfile)" copy_from => local_dcp( "$(this.promise_dirname)/before_test.xml.txt" ); } bundle agent test { meta: "description" string => "edit_line should insert after the last matched line when selecting a region where the end delimiter is included", meta => { "CFE-3988" }; "test_soft_fail" string => "any", meta => { "CFE-3988" }; vars: "seed_file" string => "$(this.promise_dirname)/before_test.xml.txt"; "test_file" string => "$(G.testfile)"; files: "$(test_file)" edit_line => CFE_3988; } bundle agent check { methods: # We expect to find lines that look something like this: # THIS MUST BE THE LAST FILTER IN THE DEFINED CHAIN # ===================================================== --> #INSERT ME "Pass/FAIL" usebundle => dcs_check_regcmp( ".*\s+THIS MUST BE THE LAST FILTER IN THE DEFINED CHAIN\R\s+=+\s+-->\RINSERT\sME.*", readfile( "$(test.test_file)" ), $(this.promise_filename), "no" ); } bundle edit_line CFE_3988 { insert_lines: "INSERT ME" select_region => my_comment_last_filter, location => my_location_after_comment_last_filter; } body location my_location_after_comment_last_filter # @brief Editing occurs after the last line in the selected region { before_after => "after"; first_last => "last"; select_line_matching => ".*"; } body select_region my_comment_last_filter { select_start => "\s+THIS MUST BE THE LAST FILTER IN THE DEFINED CHAIN"; select_end => "\s+=+\s+-->"; include_start_delimiter => "true"; include_end_delimiter => "true"; select_end_match_eof => "false"; } cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3988/1/before_test.xml.txt0000644000000000000000000000371415010704253025570 0ustar00rootroot00000000000000 Atlassian JIRA Web Application The Atlassian JIRA web application - see http://www.atlassian.com/software/jira for more information JiraImportProgressFilter com.atlassian.jira.web.filters.JiraImportProgressFilter JiraFirstFilter com.atlassian.jira.web.filters.JiraFirstFilter JiraLastFilter com.atlassian.jira.web.filters.JiraLastFilter cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/0000755000000000000000000000000015010704253021616 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/2/0000755000000000000000000000000015010704253021757 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/2/start.xml.txt0000644000000000000000000001472015010704253024460 0ustar00rootroot00000000000000 Atlassian JIRA Web Application The Atlassian JIRA web application - see http://www.atlassian.com/software/jira for more information JiraImportProgressFilter com.atlassian.jira.web.filters.JiraImportProgressFilter SetupProgressFilter com.atlassian.jira.web.filters.SetupProgressFilter StartupProgressFilter com.atlassian.jira.web.filters.StartupProgressFilter JiraFirstFilter com.atlassian.jira.web.filters.JiraFirstFilter MetricsCollectorFilter com.atlassian.jira.servermetrics.MetricsCollectorFilter MultipartBoundaryCheckFilter com.atlassian.jira.web.filters.MultipartBoundaryCheckFilter filter-plugin-dispatcher-before-dispatch-include com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher INCLUDE filter-plugin-dispatcher-before-dispatch-error com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher ERROR JiraLastFilter com.atlassian.jira.web.filters.JiraLastFilter JiraImportProgressFilter /importprogress com.atlassian.jira.web.ServletContextProviderListener appstatus com.atlassian.jira.servlet.ApplicationStatusServlet jsp.func.service.service_002dexecutor_jsp /func/service/service-executor.jsp 600 wsdl text/xml default.jsp index.html 401 /display-error webwork /WEB-INF/tld/webwork.tld sitemesh-page /WEB-INF/tld/sitemesh-page.tld sitemesh-decorator /WEB-INF/tld/sitemesh-decorator.tld jiratags /WEB-INF/tld/atlassian-jira-tags.tld cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/2/desired-result.xml.txt0000644000000000000000000001552715010704253026264 0ustar00rootroot00000000000000 Atlassian JIRA Web Application The Atlassian JIRA web application - see http://www.atlassian.com/software/jira for more information JiraImportProgressFilter com.atlassian.jira.web.filters.JiraImportProgressFilter SetupProgressFilter com.atlassian.jira.web.filters.SetupProgressFilter StartupProgressFilter com.atlassian.jira.web.filters.StartupProgressFilter JiraFirstFilter com.atlassian.jira.web.filters.JiraFirstFilter MetricsCollectorFilter com.atlassian.jira.servermetrics.MetricsCollectorFilter MultipartBoundaryCheckFilter com.atlassian.jira.web.filters.MultipartBoundaryCheckFilter filter-plugin-dispatcher-before-dispatch-include com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher INCLUDE filter-plugin-dispatcher-before-dispatch-error com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher ERROR MyLoginFilter com.atlassian.jira.authenticator.my.MyLoginFilter MyLoginFilter /* REQUEST FORWARD JiraLastFilter com.atlassian.jira.web.filters.JiraLastFilter JiraImportProgressFilter /importprogress com.atlassian.jira.web.ServletContextProviderListener appstatus com.atlassian.jira.servlet.ApplicationStatusServlet jsp.func.service.service_002dexecutor_jsp /func/service/service-executor.jsp 600 wsdl text/xml default.jsp index.html 401 /display-error webwork /WEB-INF/tld/webwork.tld sitemesh-page /WEB-INF/tld/sitemesh-page.tld sitemesh-decorator /WEB-INF/tld/sitemesh-decorator.tld jiratags /WEB-INF/tld/atlassian-jira-tags.tld cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/2/main.cf0000644000000000000000000000506415010704253023222 0ustar00rootroot00000000000000body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent init { vars: "original_file" string => "$(this.promise_dirname)/start.xml.txt"; "test_file" string => "$(sys.workdir)/start.xml.test"; files: "$(test_file)" copy_from => local_cp("${original_file}"); } bundle agent test { meta: "description" string => "Inserting content that does not contain blank lines with file_preserve_block before select_line_matching works as expected", meta => { "ENT-8788" }; vars: "new_content_file" string => "$(this.promise_dirname)/newcontent.xml.txt"; files: "$(init.test_file)" create => "false", edit_defaults => size("500k"), edit_line => insert_file_as_block_relative_to_first_or_last_line( "$(new_content_file)", # File with content to insert if not found "before", # Relative position to insert content (before|after) "last", # which line match will we insert based on? "\s+" # Regex to match the line we want to insert relative to ); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_diff($(init.test_file), "$(this.promise_dirname)/desired-result.xml.txt", $(this.promise_filename)); } bundle edit_line insert_file_as_block_relative_to_first_or_last_line(templatefile, relative_location, first_or_last, location_line_regex) { insert_lines: "$(templatefile)" comment => "Insert the template file into the file being edited", insert_type => "file_preserve_block", location => location_before_after_first_or_last_line( $(relative_location), $(first_or_last), $(location_line_regex) ); } body location location_before_after_first_or_last_line(relative_position, first_or_last, regex_matching_line) { before_after => "$(relative_position)"; first_last => "$(first_or_last)"; select_line_matching => "$(regex_matching_line)"; } body edit_defaults size(bigenough) { max_file_size => "$(bigenough)"; } cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/2/newcontent.xml.txt0000644000000000000000000000060715010704253025506 0ustar00rootroot00000000000000 MyLoginFilter com.atlassian.jira.authenticator.my.MyLoginFilter MyLoginFilter /* REQUEST FORWARD cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/1/0000755000000000000000000000000015010704253021756 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/1/start.xml.txt0000644000000000000000000001472015010704253024457 0ustar00rootroot00000000000000 Atlassian JIRA Web Application The Atlassian JIRA web application - see http://www.atlassian.com/software/jira for more information JiraImportProgressFilter com.atlassian.jira.web.filters.JiraImportProgressFilter SetupProgressFilter com.atlassian.jira.web.filters.SetupProgressFilter StartupProgressFilter com.atlassian.jira.web.filters.StartupProgressFilter JiraFirstFilter com.atlassian.jira.web.filters.JiraFirstFilter MetricsCollectorFilter com.atlassian.jira.servermetrics.MetricsCollectorFilter MultipartBoundaryCheckFilter com.atlassian.jira.web.filters.MultipartBoundaryCheckFilter filter-plugin-dispatcher-before-dispatch-include com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher INCLUDE filter-plugin-dispatcher-before-dispatch-error com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher ERROR JiraLastFilter com.atlassian.jira.web.filters.JiraLastFilter JiraImportProgressFilter /importprogress com.atlassian.jira.web.ServletContextProviderListener appstatus com.atlassian.jira.servlet.ApplicationStatusServlet jsp.func.service.service_002dexecutor_jsp /func/service/service-executor.jsp 600 wsdl text/xml default.jsp index.html 401 /display-error webwork /WEB-INF/tld/webwork.tld sitemesh-page /WEB-INF/tld/sitemesh-page.tld sitemesh-decorator /WEB-INF/tld/sitemesh-decorator.tld jiratags /WEB-INF/tld/atlassian-jira-tags.tld cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/1/desired-result.xml.txt0000644000000000000000000001553115010704253026256 0ustar00rootroot00000000000000 Atlassian JIRA Web Application The Atlassian JIRA web application - see http://www.atlassian.com/software/jira for more information JiraImportProgressFilter com.atlassian.jira.web.filters.JiraImportProgressFilter SetupProgressFilter com.atlassian.jira.web.filters.SetupProgressFilter StartupProgressFilter com.atlassian.jira.web.filters.StartupProgressFilter JiraFirstFilter com.atlassian.jira.web.filters.JiraFirstFilter MetricsCollectorFilter com.atlassian.jira.servermetrics.MetricsCollectorFilter MultipartBoundaryCheckFilter com.atlassian.jira.web.filters.MultipartBoundaryCheckFilter filter-plugin-dispatcher-before-dispatch-include com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher INCLUDE filter-plugin-dispatcher-before-dispatch-error com.atlassian.plugin.servlet.filter.ServletFilterModuleContainerFilter location before-dispatch dispatcher ERROR MyLoginFilter com.atlassian.jira.authenticator.my.MyLoginFilter MyLoginFilter /* REQUEST FORWARD JiraLastFilter com.atlassian.jira.web.filters.JiraLastFilter JiraImportProgressFilter /importprogress com.atlassian.jira.web.ServletContextProviderListener appstatus com.atlassian.jira.servlet.ApplicationStatusServlet jsp.func.service.service_002dexecutor_jsp /func/service/service-executor.jsp 600 wsdl text/xml default.jsp index.html 401 /display-error webwork /WEB-INF/tld/webwork.tld sitemesh-page /WEB-INF/tld/sitemesh-page.tld sitemesh-decorator /WEB-INF/tld/sitemesh-decorator.tld jiratags /WEB-INF/tld/atlassian-jira-tags.tld cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/1/main.cf0000644000000000000000000000514015010704253023214 0ustar00rootroot00000000000000body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent init { vars: "original_file" string => "$(this.promise_dirname)/start.xml.txt"; "test_file" string => "$(sys.workdir)/start.xml.test"; files: "$(test_file)" copy_from => local_cp("${original_file}"); } bundle agent test { meta: "description" string => "Inserting content that contains blank lines with file_preserve_block before select_line_matching does not split inserted content before and after select_line_matching", meta => { "ENT-8788" }; vars: "new_content_file" string => "$(this.promise_dirname)/newcontent.xml.txt"; files: "$(init.test_file)" create => "false", edit_defaults => size("500k"), edit_line => insert_file_as_block_relative_to_first_or_last_line( "$(new_content_file)", # File with content to insert if not found "before", # Relative position to insert content (before|after) "last", # which line match will we insert based on? "\s+" # Regex to match the line we want to insert relative to ); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_diff($(init.test_file), "$(this.promise_dirname)/desired-result.xml.txt", $(this.promise_filename)); } bundle edit_line insert_file_as_block_relative_to_first_or_last_line(templatefile, relative_location, first_or_last, location_line_regex) { insert_lines: "$(templatefile)" comment => "Insert the template file into the file being edited", insert_type => "file_preserve_block", location => location_before_after_first_or_last_line( $(relative_location), $(first_or_last), $(location_line_regex) ); } body location location_before_after_first_or_last_line(relative_position, first_or_last, regex_matching_line) { before_after => "$(relative_position)"; first_last => "$(first_or_last)"; select_line_matching => "$(regex_matching_line)"; } body edit_defaults size(bigenough) { max_file_size => "$(bigenough)"; } cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8788/1/newcontent.xml.txt0000644000000000000000000000061115010704253025500 0ustar00rootroot00000000000000 MyLoginFilter com.atlassian.jira.authenticator.my.MyLoginFilter MyLoginFilter /* REQUEST FORWARD cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8818/0000755000000000000000000000000015010704253021610 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8818/1/0000755000000000000000000000000015010704253021750 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8818/1/README.org0000644000000000000000000000071415010704253023420 0ustar00rootroot00000000000000#+title: ENT-8818 This test reproduces a crash (assert). Our test system does not support suppression of crashing tests, instead they must live in staging directories and be moved back out when they are fixed. This is unfortunate as it gives us little ability to run crahsing tests contunually and spot cases when they stop crashing un-expectedly. So, when a fix for this is ready, move staging/main.cf up to the level of this readme and delete this readme. cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8818/1/staging/0000755000000000000000000000000015010704253023404 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/ENT-8818/1/staging/main.cf0000644000000000000000000000170615010704253024646 0ustar00rootroot00000000000000# NOTE: This test file must have it's be renamed from .x.cf to .cf when the bug is fixed. body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent test { meta: "description" -> { "ENT-8818" } string => "Referencing variables in a namespace that does not exist should not cause the agent to crash"; reports: # NOTE: Here in the last variable I misspelled default as defult which is how I originally found this bug. "In $(this.namespace):$(this.bundle) $(const.dollar)(default:sys.cf_version_major) == $(defult:sys.cf_version_major)"; } bundle agent check { methods: # If we make ti this far we pass. "Pass" usebundle => dcs_pass( $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3987/0000755000000000000000000000000015010704253021561 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3987/2/0000755000000000000000000000000015010704253021722 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3987/2/test.cf0000644000000000000000000000402015010704253023207 0ustar00rootroot00000000000000body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent init { files: # Seed the file we will exercise the test on "$(G.testfile)" copy_from => local_dcp( "$(this.promise_dirname)/before_test.xml.txt" ); } bundle agent test { meta: "description" string => "Workaround for bug where edit_line doesn't insert text immediately before a selected region if a location body only explicitly sets before_after => 'before'", meta => { "CFE-3987" }; vars: "seed_file" string => "$(this.promise_dirname)/before_test.xml.txt"; "test_file" string => "$(G.testfile)"; files: "$(test_file)" edit_line => CFE_3987; } bundle agent check { methods: "Pass/FAIL" usebundle => dcs_check_regcmp( ".*INSERT\sME\R\s+ Atlassian JIRA Web Application The Atlassian JIRA web application - see http://www.atlassian.com/software/jira for more information JiraImportProgressFilter com.atlassian.jira.web.filters.JiraImportProgressFilter JiraFirstFilter com.atlassian.jira.web.filters.JiraFirstFilter JiraLastFilter com.atlassian.jira.web.filters.JiraLastFilter cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3987/1/0000755000000000000000000000000015010704253021721 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-3987/1/test.cf0000644000000000000000000000367215010704253023222 0ustar00rootroot00000000000000body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent init { files: # Seed the file we will exercise the test on "$(G.testfile)" copy_from => local_dcp( "$(this.promise_dirname)/before_test.xml.txt" ); } bundle agent test { meta: "description" string => "edit_line doesn't insert text immediately before a selected region if a location body only explicitly sets before_after => 'before'", meta => { "CFE-3987" }; "test_soft_fail" string => "any", meta => { "CFE-3987" }; vars: "seed_file" string => "$(this.promise_dirname)/before_test.xml.txt"; "test_file" string => "$(G.testfile)"; files: "$(test_file)" edit_line => CFE_3987; } bundle agent check { methods: "Pass/FAIL" usebundle => dcs_check_regcmp( ".*INSERT\sME\R\s+ Atlassian JIRA Web Application The Atlassian JIRA web application - see http://www.atlassian.com/software/jira for more information JiraImportProgressFilter com.atlassian.jira.web.filters.JiraImportProgressFilter JiraFirstFilter com.atlassian.jira.web.filters.JiraFirstFilter JiraLastFilter com.atlassian.jira.web.filters.JiraLastFilter cfengine-3.24.2/tests/acceptance/31_tickets/CFE-2367/0000755000000000000000000000000015010704253021550 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-2367/2/0000755000000000000000000000000015010704253021711 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-2367/2/test.cf0000644000000000000000000000267115010704253023210 0ustar00rootroot00000000000000body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent test { meta: "description" -> { "CFE-2367" } string => "cf-agent should not fatally error when fileexists() is given an undefined variable as a parameter"; files: "$(G.testfile)" content => "CFE-2367", unless => and( fileexists( $(testfile) ) ); # testfile is not defined, # in the original ticket # filed this caused a fatal # error and the workaround # was to wrap the function # call with and(), so we # simply test that as in the # original case, there is no # fatal error. } bundle agent check { methods: # Since this was testing for the absence of a fatal error, if we get to # this point, we pass. "Pass" usebundle => dcs_pass("$(this.promise_filename)" ); } cfengine-3.24.2/tests/acceptance/31_tickets/CFE-2367/1/0000755000000000000000000000000015010704253021710 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/31_tickets/CFE-2367/1/test.cf0000644000000000000000000000173215010704253023204 0ustar00rootroot00000000000000body file control { inputs => { "../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent test { meta: "description" -> { "CFE-2367" } string => "cf-agent should not fatally error when fileexists() is given an undefined variable as a parameter"; files: "$(G.testfile)" content => "CFE-2367", unless => fileexists( $(testfile) ); # testfile is not defined, in the # original ticket filed this caused # a fatal error } bundle agent check { methods: # Since this was testing for the absence of a fatal error, if we get to # this point, we pass. "Pass" usebundle => dcs_pass("$(this.promise_filename)" ); } cfengine-3.24.2/tests/acceptance/19_security/0000755000000000000000000000000015010704253020763 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/19_security/other_writeable/0000755000000000000000000000000015010704253024142 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/19_security/other_writeable/other_write.cf0000644000000000000000000000277115010704253027016 0ustar00rootroot00000000000000####################################################### # # Create a file, check defaults # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: # This extracts the octal mode, and decimal nlink, uid, gid, size "policy_file" string => ' body common control { bundlesequence => { "test" }; } bundle agent test { reports: "We\'re not in KS anymore toto."; }'; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", edit_defaults => empty, edit_line => insert_lines("$(g.policy_file)"), perms => m("602"); } ####################################################### bundle agent test { vars: "agent_output" string => execresult("$(sys.cf_agent) -f $(G.testfile)", "noshell"), if => fileexists("$(G.testfile)"); classes: "security_exception" expression => regcmp(".*is writable by others (security exception).*", "$(agent_output)"), comment => "It's a security risk to evaluate policy that is writeable by users other than the owner"; } ####################################################### bundle agent check { classes: "ok" expression => "!security_exception"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/19_security/other_writeable/group_write.cf0000644000000000000000000000315115010704253027022 0ustar00rootroot00000000000000####################################################### # # Create a file, check defaults # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: # This extracts the octal mode, and decimal nlink, uid, gid, size "policy_file" string => ' body common control { bundlesequence => { "test" }; } bundle agent test { reports: "Dorothy: How do you talk if you don\'t have a brain?"; "Scarecrow: Well, some people without brains do an awful lot of talking don\'t they?"; }'; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", edit_defaults => empty, edit_line => insert_lines("$(g.policy_file)"), perms => m("620"); } ####################################################### bundle agent test { vars: "agent_output" string => execresult("$(sys.cf_agent) -f $(G.testfile)", "noshell"), if => fileexists("$(G.testfile)"); classes: "security_exception" expression => regcmp(".*is writable by others (security exception).*", "$(agent_output)"), comment => "It's a security risk to evaluate policy that is writeable by users other than the owner"; } ####################################################### bundle agent check { classes: "ok" expression => "!security_exception"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/0000755000000000000000000000000015010704253020056 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/03_lists/0000755000000000000000000000000015010704253021516 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/03_lists/001.cf0000644000000000000000000000442615010704253022336 0ustar00rootroot00000000000000####################################################### # # Nested iterations of slists (the ordering is not guaranteed, so we sort) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => " a x a y a z b x b y b z c x c y c z a cf_null b cf_null c cf_null cf_null blah"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle edit_line test_insert { vars: "one" slist => { "a", "b", "c" }; "two" slist => { "x", "y", "z" }; "empty" slist => {}; "null" slist => { "cf_null" }; "nulls" slist => { "cf_null", "cf_null", "cf_null" }; "not_an_array" string => "blah"; "no_values" slist => getvalues("not_an_array"); insert_lines: "$(one) $(two)"; # cf_null is no longer treated specially, they are regular list elements "$(one) $(nulls)"; "$(null)"; "$(nulls)"; # the following should do nothing "$(one) $(two) $(empty)"; "$(empty) $(one) $(null) $(two)"; "$(null) $(empty)"; "$(no_values)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/016.cf0000644000000000000000000000221615010704253022337 0ustar00rootroot00000000000000############################################################################## # # Redmine #2936: Check that list variables under reserved scope expand # as they should. The initial bug report was for reports promises only, # but here we check it for files promises. # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { # TODO delete the testfile } bundle agent test { files: "$(G.testfile).actual" create => "true", edit_defaults => init_empty, edit_line => test_insert_macs; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line test_insert_macs { insert_lines: "$(sys.hardware_addresses)"; } bundle agent check { # If the file contains the string "sys.hardware_addresses" then we # failed to expand the variable! classes: "ok" not => regline(".*sys\.hardware_addresses.*", "$(G.testfile).actual"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaced_list_including_list_expanded.cf.sub0000644000000000000000000000117315010704253032714 0ustar00rootroot00000000000000body common control { bundlesequence => { "go" }; version => "1.0"; } bundle agent go { methods: "if you like then you better put a namespace on it" usebundle => test:namespace_check; } body file control { namespace => "test"; } bundle agent namespace_check { classes: "server" expression => "any"; vars: "packages" slist => { "mysql-client", "mysql-common" }, policy => "free"; "server_packages" slist => { "mysql-server", "mysql-server-core" }, policy => "free"; "all_packages" slist => { @(packages), @(server_packages) }, policy => "free"; reports: "$(all_packages)"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/extend_list.cf0000644000000000000000000000463515010704253024362 0ustar00rootroot00000000000000####################################################### # # Test that slists can be extended (redefined using its own previous value) # Redmine:4335 and 6541 ####################################################### body common control { version => "1.0"; bundlesequence => { "init", "test", "check" }; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "x" slist => { "xyz" }, policy => "free"; "x" slist => { @(x), "extended" }, policy => "free"; "x" slist => { @(x), "more" }, policy => "free"; "x1" slist => { @(x), @(undefined1), @(undefined2) }, policy => "ifdefined"; "x2" slist => { @(undefined1), @(x), @(undefined2) }, policy => "ifdefined"; "x3" slist => { @(undefined1), @(undefined2), @(x) }, policy => "ifdefined"; "x4" slist => { @(x), @(undefined1), @(undefined2), @(x) }, policy => "ifdefined"; "x5" slist => { @(undefined1), "entry", @(undefined2) }, policy => "ifdefined"; } ####################################################### bundle agent check { vars: "expected" string => "xyz,extended,more"; "joined_test_x" string => join(",", "test.x"); "joined_test_x1" string => join(",", "test.x1"); "joined_test_x2" string => join(",", "test.x2"); "joined_test_x3" string => join(",", "test.x3"); "joined_test_x4" string => join(",", "test.x4"); "joined_test_x5" string => join(",", "test.x5"); classes: "ok0" expression => strcmp($(expected), $(joined_test_x)); "ok1" expression => strcmp($(expected), $(joined_test_x1)); "ok2" expression => strcmp($(expected), $(joined_test_x2)); "ok3" expression => strcmp($(expected), $(joined_test_x3)); "ok4" expression => strcmp("$(expected),$(expected)", $(joined_test_x4)); "ok5" expression => strcmp("entry", $(joined_test_x5)); "ok" and => { "ok0", "ok1", "ok2", "ok3", "ok4", "ok5" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG.!ok0:: "x: $(joined_test_x)"; DEBUG.!ok1:: "expected x1: $(expected)"; " x1: $(joined_test_x1)"; DEBUG.!ok2:: "x2: $(joined_test_x2)"; DEBUG.!ok3:: "x3: $(joined_test_x3)"; DEBUG.!ok4:: "x4: $(joined_test_x4)"; DEBUG.!ok5:: "x5: $(joined_test_x5)"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/008.cf0000644000000000000000000000303415010704253022337 0ustar00rootroot00000000000000####################################################### # # Test list iteration over cf_null special blank character, start of list # # NOTE: tests conditions have been reversed! cf_null is no longer # treated specially! ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "expected" string => "cf_null 1 2 3"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert("$(expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_list_null, edit_defaults => init_empty; } bundle edit_line test_list_null { vars: "lines" slist => { "cf_null", "1", "2", "3" }; insert_lines: "$(lines)" whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/010.cf0000644000000000000000000000303215010704253022326 0ustar00rootroot00000000000000####################################################### # # Test list iteration over cf_null special blank character, end of list # # NOTE: tests conditions have been reversed! cf_null is no longer # treated specially! ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "expected" string => "1 2 3 cf_null"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert("$(expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_list_null, edit_defaults => init_empty; } bundle edit_line test_list_null { vars: "lines" slist => { "1", "2", "3", "cf_null" }; insert_lines: "$(lines)" whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/usebundle_naked.cf0000644000000000000000000000142715010704253025164 0ustar00rootroot00000000000000# Test usebundle passing a naked list from local scope body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "expected" string => "1,2,3"; } bundle agent test { vars: "testlist" slist => {"1","2","3"}; methods: "call sub" usebundle => sub(@{testlist}); } bundle agent sub(sublist) { vars: "joined" string => join(",", "sublist"); reports: DEBUG:: "sub joined $(joined)"; } bundle agent check { methods: "check results" usebundle => dcs_check_strcmp("$(init.expected)", "$(sub.joined)", "$(this.promise_filename)", "no"); reports: DEBUG:: "comparing '$(init.expected)' with '$(sub.joined)'"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/012.cf0000644000000000000000000000351215010704253022333 0ustar00rootroot00000000000000####################################################### # # Iterations of non-local slists inside non-local (sclar) array # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => " XX XXX XXXX"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle agent otherbundle { vars: "array[one]" string => "XX"; "array[two]" string => "XXX"; "array[three]" string => "XXXX"; "list" slist => { "one", "two", "three" }; } bundle edit_line test_insert { insert_lines: "$(otherbundle.array[$(otherbundle.list)])"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/011.cf0000644000000000000000000000275615010704253022343 0ustar00rootroot00000000000000####################################################### # # Test list iteration over cf_null special blank characters, all blank # # NOTE: tests conditions have been reversed! cf_null is no longer # treated specially! ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: files: "$(G.testfile).expected" create => "true", edit_defaults => init_empty, edit_line => init_insert("cf_null"); } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_list_null, edit_defaults => init_empty; } bundle edit_line test_list_null { vars: "lines" slist => { "cf_null", "cf_null", "cf_null" }; insert_lines: "$(lines)" whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/007.cf0000644000000000000000000000147415010704253022344 0ustar00rootroot00000000000000# Test that cf_null lists can be joined # NOTE: tests conditions have been reversed! cf_null is no longer # treated specially! body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => ""; } bundle agent test { vars: "dummy" string => ""; } bundle agent check { vars: "emptylist" slist => { "cf_null" }; "joined" string => join(":", "emptylist"); classes: "ok1" expression => strcmp($(joined), ""); "ok" not => "ok1"; # the list should contain cf_null reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; DEBUG:: "Expected cf_null string, got $(joined)!"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/nested_lists.cf0000644000000000000000000000534315010704253024535 0ustar00rootroot00000000000000####################################################### # # Nested iterations of slists (the ordering is not guaranteed, so we sort) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => " Nesting: 1 Nesting: 2 Nothing: Unknown: $(unknown) A list: @(lists) Other empty: 5 Other empty: 6 Parameter nesting: 7 Parameter nesting: 8 Sub nesting: 7 Sub nesting: 8"; files: "$(G.testfile).$(states)" create => "true", edit_line => insert_line("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line insert_line(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent otherbundle { vars: "list_a" slist => { }; "list_b" slist => { "5", "6" }; "lists" slist => { "a", "b" }; } bundle edit_line test_insert { vars: "list_a" slist => { "1", "2" }; "list_b" slist => {}; "lists" slist => { "a", "b" }; "nothing" string => ""; insert_lines: "Nesting: $(list_$(lists))"; "Expanded: $(lists) $(list_a) $(list_b)"; "$(nothing)" insert_type => "preserve_all_lines"; # ignore existing newline "Nothing: $(nothing)"; "Unknown: $(unknown)"; "A list: @(lists)"; "Other empty: $(otherbundle.list_$(otherbundle.lists))"; } bundle agent sub(text) { files: "$(G.testfile).actual" edit_line => insert_line("Sub nesting: $(text)"); } bundle agent test { vars: "list_a" slist => { }; "list_b" slist => { "7", "8" }; "lists" slist => { "a", "b" }; files: "$(G.testfile).actual" edit_line => test_insert; "$(G.testfile).actual" edit_line => insert_line("Parameter nesting: $(list_$(lists))"); methods: "nesting" usebundle => sub("$(list_$(lists))"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/003.cf0000644000000000000000000000313615010704253022335 0ustar00rootroot00000000000000####################################################### # # Iteration on slist of size 1 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => " a"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle edit_line test_insert { vars: "one" slist => { "a" }; insert_lines: "$(one)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/004.cf0000644000000000000000000000331015010704253022330 0ustar00rootroot00000000000000####################################################### # # Iterations of non-local slists # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => " a b c"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle agent otherbundle { vars: "one" slist => { "a", "b", "c" }; } bundle edit_line test_insert { vars: "one" slist => { "c", "b", "a" }; insert_lines: "$(otherbundle.one)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/interpolation_order.cf0000644000000000000000000000160515010704253026114 0ustar00rootroot00000000000000# Redmine#3122: ensure lists are interpolated in the correct order body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "first_list" slist => { "item1", "item2", "item3", "item4", "item5" }; } bundle agent test { vars: "local" slist => { @(second_list) }; "second_list" slist => { @(init.first_list), "item6" }; } bundle agent check { vars: "expected" string => '{ "item1", "item2", "item3", "item4", "item5", "item6" }'; "joined" string => format("%S", "test.local"); methods: "check" usebundle => dcs_check_strcmp($(expected), $(joined), "$(this.promise_filename)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/005.cf0000644000000000000000000000353115010704253022336 0ustar00rootroot00000000000000####################################################### # # Iterations of non-local slists # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => " XX XXX XXXX"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle agent otherbundle { vars: "list" slist => { "one", "two", "three" }; } bundle edit_line test_insert { vars: "array[one]" string => "XX"; "array[two]" string => "XXX"; "array[three]" string => "XXXX"; "list" slist => { "three", "two", "one" }; insert_lines: "$(array[$(otherbundle.list)])"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/double_expand_remote_list.cf0000644000000000000000000000141015010704253027243 0ustar00rootroot00000000000000# Redmine#6866 # Test that varibles are fully expanded body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check { meta: # "tags" # slist => { "redmine#6866" }; "test_soft_fail" meta => { "redmine#6866" }, string => "any"; vars: "command" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; "expected" string => "R: Direct: 1 R: Direct: 2 R: Direct: 3 R: Indirect: 1 R: Indirect: 2 R: Indirect: 3"; methods: "check" usebundle => dcs_passif_output(".*$(expected).*", "", $(command), $(this.promise_filename)); reports: DEBUG:: "=== Expected === '$(expected)' ================"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/015.cf0000644000000000000000000000312215010704253022333 0ustar00rootroot00000000000000####################################################### # # Iteration on slist of size 1 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => ""; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle edit_line test_insert { vars: "one" slist => { }; insert_lines: "$(one)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/006.cf0000644000000000000000000000124315010704253022335 0ustar00rootroot00000000000000# Test that reglist() does not match cf_null values # NOTE: tests conditions have been reversed! cf_null is no longer # treated specially! body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => ""; } bundle agent test { vars: "dummy" string => ""; } bundle agent check { vars: "emptylist" slist => { "cf_null" }; classes: "ok" expression => reglist("@(emptylist)", ".+"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/009.cf0000644000000000000000000000302715010704253022342 0ustar00rootroot00000000000000####################################################### # # Test list iteration over cf_null special blank character, mid list # # NOTE: tests conditions have been reversed! cf_null is no longer # treated specially! ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "expected" string => "1 cf_null 2 3"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert("$(expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_list_null, edit_defaults => init_empty; } bundle edit_line test_list_null { vars: "lines" slist => { "1", "cf_null", "2", "3" }; insert_lines: "$(lines)" whitespace_policy => { "exact_match" }; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/014.cf0000644000000000000000000000326515010704253022342 0ustar00rootroot00000000000000####################################################### # # Iteration on non-local empty slist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => ""; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle agent otherbundle { vars: "list" slist => { }; } bundle edit_line test_insert { vars: "list" slist => { "a", "b", "c" }; insert_lines: "$(otherbundle.list)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/double_expand_remote_list.cf.sub0000644000000000000000000000113515010704253030037 0ustar00rootroot00000000000000# Redmine#6866 # Test that nested expansion of arrays works body common control { bundlesequence => { "init", "test", "report" }; version => "1.0"; } bundle agent init { vars: "list" slist => { "1", "2", "3" }; "list2" slist => { "a", "b", "c" }; } bundle agent test { vars: "other_list" string => "init.list"; "list_of_lists" slist => { "init.list", "init.list2" }; } bundle agent report { reports: "Direct: $(init.list)"; "Indirect: $($(test.other_list))"; #TODO "Indirect lists: $($(test.list_of_lists))"; # Expected different lines of: 1 2 3 a b c } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaces/0000755000000000000000000000000015010704253023635 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaces/passing_slists3.cf0000644000000000000000000000166315010704253027305 0ustar00rootroot00000000000000# Redmine#4494 # the agent should not try to process files promises on the unexpanded # version of a passed list # here, the error manifests as "Failed to chdir into @(given_watch)" # but it also generates a NOTKEPT compliance entry body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "output" string => execresult("$(sys.cf_agent) -K -f $(this.promise_filename).sub | $(G.grep) 'Failed to chdir' 2>&1", "useshell"); } bundle agent check { methods: "pass" usebundle => dcs_check_regcmp(".*Failed to chdir into '@.given_watch.'.*", $(test.output), $(this.promise_filename), "true"); reports: EXTRA:: "Output = $(test.output)"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaces/passing_slists.cf.sub0000644000000000000000000000165715010704253030015 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle agent test_in_namespace(passed_list) { vars: "mylist" slist => { @(passed_list) }; "joined" string => join(",", "mylist"); classes: "mylist_$(mylist)" expression => "any"; reports: default:DEBUG:: "BUG: mylist___mylist_ was defined!" ifvarclass => "mylist___mylist_"; "BUG: mylist_1 not defined" ifvarclass => "!mylist_1"; "GOOD: mylist_1 was defined" ifvarclass => "mylist_1"; "mylist = $(b:test_in_namespace.mylist)"; "mylist without namespace = $(test_in_namespace.mylist)"; "mylist without qualifiers = $(mylist)"; "Set joined to $(joined)"; } bundle agent check_in_namespace(target,test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.joined)", "$(target)", "$(test)", "no"); reports: default:DEBUG:: "comparing '$(b:test_in_namespace.joined)' and '$(target)'"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaces/passing_slists.cf0000644000000000000000000000116415010704253027216 0ustar00rootroot00000000000000body common control { inputs => { "../../../default.cf.sub", "passing_slists.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { abortclasses => { "mylist___mylist_" }; } bundle common g { vars: "slist_pass" slist => { "1", "2", "3" }; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace(@(g.slist_pass)); } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace(join(",", "g.slist_pass"), "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaces/passing_slists3.cf.sub0000644000000000000000000000241515010704253030071 0ustar00rootroot00000000000000# Redmine#4494 # - passing a slist to a non-namespaced agent bundle (works) # - passing a slist to a namespaced agent bundle with no "classes" promises (works) # - passing a slist to a namespaced agent bundle with a "classes" promises (emits spurious "Failed to chdir..." message) body common control { bundlesequence => { test }; } bundle agent test { vars: "watch" slist => { "/" }; methods: "watch" usebundle => watch(@(test.watch)); "nswatch" usebundle => ns:watch(@(test.watch)); "ns2watch" usebundle => ns2:watch(@(test.watch)); } bundle agent watch(given_watch) { classes: vars: "watch" slist => { @(given_watch) }; files: "$(watch)"; reports: "$(this.namespace):$(this.bundle): got local watch = $(watch)"; } body file control { namespace => "ns"; } bundle agent watch(given_watch) { classes: vars: "watch" slist => { @(given_watch) }; files: "$(watch)"; reports: "$(this.namespace):$(this.bundle): got local watch = $(watch)"; } body file control { namespace => "ns2"; } bundle agent watch(given_watch) { vars: "watch" slist => { @(given_watch) }; files: "$(watch)"; reports: "$(this.namespace):$(this.bundle): got local watch = $(watch)"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaces/passing_slists2.cf0000644000000000000000000000110615010704253027274 0ustar00rootroot00000000000000# Redmine#4494 # the agent should not abort when a bundle is passed a qualified slist # name that doesn't actually exist body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { methods: "watch" usebundle => watch(@(run.watch)); } bundle agent check { methods: "pass" usebundle => dcs_passif("any", $(this.promise_filename)); } bundle agent watch(given_watch) { vars: "watch" slist => { @(given_watch) }; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/002.cf0000644000000000000000000000314415010704253022333 0ustar00rootroot00000000000000####################################################### # # Iterations of slists # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "actual" string => ""; "expected" string => " a b c"; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$(init.$(states))"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle edit_line test_insert { vars: "one" slist => { "a", "b", "c" }; insert_lines: "$(one)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_sort("$(G.testfile).actual", "$(G.testfile).actual.sorted"); "any" usebundle => dcs_sort("$(G.testfile).expected", "$(G.testfile).expected.sorted"); "any" usebundle => dcs_check_diff("$(G.testfile).actual.sorted", "$(G.testfile).expected.sorted", "$(this.promise_filename)"); } body contain check_in_shell { useshell => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/013.cf0000644000000000000000000000257515010704253022344 0ustar00rootroot00000000000000# Test expansion of remote arrays containing lists body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; nova_edition:: host_licenses_paid => "5"; } bundle agent init { vars: "array[one]" string => "1"; "array[two]" string => "2"; "array[list]" slist => { "first", "second", "last" }; "keys" slist => { "one", "two", "list" }; "expected" string => " 1 2 first second last"; "actual" string => ""; "states" slist => { "expected", "actual" }; files: "$(G.testfile).$(states)" create => "true", edit_line => init_insert("$($(states))"), edit_defaults => init_empty; } bundle agent test { files: "$(G.testfile).actual" edit_line => test_insert; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } bundle edit_line test_insert { insert_lines: "$(init.array[$(init.keys)])"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); reports: DEBUG:: "can expand $(init.array[$(init.keys)])"; } cfengine-3.24.2/tests/acceptance/01_vars/03_lists/namespaced_list_including_list_expanded.cf0000644000000000000000000000233615010704253032126 0ustar00rootroot00000000000000# Redmine#4445: Ensure that namespaced lists that include other lists are fully expanded body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "agent_output" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "noshell"); } bundle agent check { classes: "unexpanded_list" expression => regcmp(".*packages.*", $(test.agent_output)), comment => "check to see if an included list is unexpanded"; "found_from_packages" expression => regcmp(".*mysql-client.*", $(test.agent_output)), comment => "found something good from one list"; "found_from_server_packages" expression => regcmp(".*mysql-server.*", $(test.agent_output)), comment => "found something good from one list"; "found_expected_output" and => { "found_from_packages", "found_from_server_packages" }, comment => "Found something good from both included lists"; "ok" expression => "!unexpanded_list.found_expected_output"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/0000755000000000000000000000000015010704253022367 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/execresult_action_immediate.cf0000644000000000000000000000312215010704253030435 0ustar00rootroot00000000000000# Test that execresult is called multiple times with the same command if # 'ifelapsed => "0"' is used. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent check_date(x) { vars: "reports_file" string => "$(G.testdir)/execresult_action_immediate_report"; "date" string => execresult("date; sleep 1", "useshell"), action => immediate; reports: "Date for ${x}: ${date}" report_to_file => "$(reports_file)"; } bundle agent test { meta: "description" -> {"ENT-7478"} string => "If 'ifelapsed => 0' is used, execresult() should run the given command every time"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; methods: "foo" usebundle => check_date("foo"); "bar" usebundle => check_date("bar"); } bundle agent check { vars: "content" slist => readstringlist( "$(check_date.reports_file)", "", '$(const.n)', inf, inf); "count" int => length( content ); reports: DEBUG|EXTRA:: "$(check_date.reports_file) contents:"; "$(content)"; any:: # Pass if there are 6 lines, 3 for each check_date bundle actuation, # indicating that execresult is being called once for each pass. "$(this.promise_filename) Pass" if => strcmp( $(count), 6 ); "$(this.promise_filename) FAIL" unless => strcmp( $(count), 6 ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/001.cf0000644000000000000000000000406215010704253023203 0ustar00rootroot00000000000000####################################################### # # Test getuid() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_needs_work" string => "windows"; vars: any:: "uid_root" int => getuid("root"); "uid_daemon" int => getuid("daemon"); !darwin:: "uid_bin" int => getuid("bin"); (linux.!archlinux.!SuSE.!redhat.!gentoo)|solaris|hpux|aix:: "num_root" int => "0"; "num_daemon" int => "1"; "num_bin" int => "2"; archlinux|SuSE|redhat|gentoo:: "num_root" int => "0"; "num_daemon" int => "2"; "num_bin" int => "1"; freebsd|openbsd:: "num_root" int => "0"; "num_daemon" int => "1"; "num_bin" int => "3"; darwin:: "num_root" int => "0"; "num_daemon" int => "1"; !linux.!solaris.!hpux.!aix.!freebsd.!openbsd.!darwin:: "num_root" string => "fixme"; "num_daemon" string => "fixme"; "num_bin" string => "fixme"; } ####################################################### bundle agent check { classes: darwin:: "ok_bin" expression => "any"; !darwin:: "ok_bin" expression => strcmp("$(test.uid_bin)", "$(test.num_bin)"); any:: "ok" and => { strcmp("$(test.uid_root)", "$(test.num_root)"), strcmp("$(test.uid_daemon)", "$(test.num_daemon)"), "ok_bin" }; reports: DEBUG:: "root is UID $(test.uid_root), expected $(test.num_root)"; "daemon is UID $(test.uid_daemon), expected $(test.num_daemon)"; "bin is UID $(test.uid_bin), expected $(test.num_bin)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mustache_section_nonfalse_inverted.cf0000644000000000000000000000262315010704253032026 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template" string => "{{#network_interfaces}} interface {{interface}} {{#gateway}} gateway {{.}} {{/gateway}} {{^gateway}} #no gateway {{/gateway}} {{/network_interfaces}}"; "data" data => '{ "network_interfaces": [ { "interface":"eth1", "family":"inet6", "config_mode":"dhcp" }, { "interface":"vlan10", "device":"eth0", "role":"Management", "family":"inet", "config_mode":"static", "ip_address":"192.168.1.2", "prefix":"24", "gateway":"192.168.1.1" } ] }'; } bundle agent test { meta: "description" -> { "CFE-1565" } string => "Test that inversion of non-false values works as expected with mustache. (CFE-1565)"; "test_soft_fail" string => "any", meta => { "CFE-1565" }; vars: "got" string => string_mustache( $(init.template), @(init.data) ); } bundle agent check { vars: "expected" string => "interface eth1 #no gateway interface vlan10 gateway 192.168.1.1 "; methods: "check" usebundle => dcs_check_strcmp( $(test.got), $(check.expected), $(this.promise_filename), "no" ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/format_edge_case.cf0000644000000000000000000001176515010704253026162 0ustar00rootroot00000000000000# Test bug fix # Former bug truncates strings greater than 4096 bytes # There is no reason for format() to truncate strings body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ########################################################## bundle agent test { vars: "str" string => format('%s', 'Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else.'); "list" slist => { $(str) }; "list_str" string => format('%S', "list"); "container" data => parsejson(' ["$(str)"] '); "container_str" string => format('%S', "container"); } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sublist.cf0000644000000000000000000000257715010704253024401 0ustar00rootroot00000000000000####################################################### # # Test sublist() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "one", "two", "three", }; "test_head9999" slist => sublist("test", "head", 9999); "test_head1" slist => sublist("test", "head", 1); "test_head0" slist => sublist("test", "head", 0); "test_tail9999" slist => sublist("test", "tail", 9999); "test_tail10" slist => sublist("test", "tail", 10); "test_tail2" slist => sublist("test", "tail", 2); "test_tail1" slist => sublist("test", "tail", 1); "test_tail0" slist => sublist("test", "tail", 0); "test_inline" slist => sublist('[1,2,3,4,5,6,7]', "tail", 3); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/array_subkey_collision.cf0000644000000000000000000000242415010704253027456 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2536" } string => "Converting arrays with colliding definitions for subkeys should work, somehow."; vars: "array[key1][subkey1]" string => "hey"; "array[key1]" string => "hou"; "array_values" slist => getvalues("array"); "array_values_str" string => format("%S", array_values); "array_data" data => mergedata(array); "array_data_str" string => format("%S", array_data); } bundle agent check { classes: # the "more structured structure" should win when converting to JSON "get_values_ok" expression => strcmp("$(test.array_values_str)", '{ "hey" }'); "array_data_ok" expression => strcmp("$(test.array_data_str)", '{"key1":{"subkey1":"hey"}}'); "ok" and => { "get_values_ok", "array_data_ok" }; reports: "DEBUG":: "array_values_str: $(test.array_values_str)" if => "!get_values_ok"; "array_data_str: $(test.array_data_str)" if => "!array_data_ok"; "ok":: "$(this.promise_filename) Pass"; "!ok":: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/203.cf0000644000000000000000000000254115010704253023207 0ustar00rootroot00000000000000####################################################### # # Test getindices(), size 2 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "alpha"; "beta"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "array[beta]" string => "two"; "keys" slist => getindices("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(keys)"; } bundle edit_line test_insert { vars: "keys" slist => { @{test.keys} }; insert_lines: "$(keys)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/shuffle-exact.cf.expected.json0000644000000000000000000000127615010704253030215 0ustar00rootroot00000000000000{ "lists": [ "a", "b" ], "seeds": [ "skruf", "cormorant", "dollhouse" ], "shuffle_a_cormorant": [ "d", "b", "c", "f", "e", "a", "g" ], "shuffle_a_dollhouse": [ "b", "f", "a", "e", "g", "c", "d" ], "shuffle_a_skruf": [ "f", "d", "b", "e", "c", "g", "a" ], "shuffle_b_cormorant": [], "shuffle_b_dollhouse": [], "shuffle_b_skruf": [], "shuffle_inline_cormorant": [ "farmer", "b", "a", "delta" ], "shuffle_inline_dollhouse": [ "delta", "farmer", "a", "b" ], "shuffle_inline_skruf": [ "b", "a", "delta", "farmer" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/224.cf0000644000000000000000000000256715010704253023222 0ustar00rootroot00000000000000####################################################### # # Test grep(), size 2, global array # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "Two"; "Three"; } ####################################################### bundle agent test { vars: "array" slist => { "One", "Two", "Three", "Four", "Five" }; "vals" slist => grep("T.*","test.array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/026.cf0000644000000000000000000000264715010704253023221 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/064.x.cf0000644000000000000000000000171315010704253023462 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(1001,1000,1000,1000,1000,40000); } ####################################################### bundle agent check { vars: "time" int => "2682100000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_regextract-2.cf0000644000000000000000000000416115010704253026203 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-3171" } string => "test that data_regextract uses a multiline regex"; vars: "file" string => "$(this.promise_filename).readfile"; # Note the newline at the end of the file was included in the backreference. # Per http://www.pcre.org/current/doc/html/pcre2syntax.html#SEC4 that means the regex is being run in “dotall†mode. # Dotall mode doesn’t necessarily imply multiline mode, but a “$†matching before an internal newline does (per http://www.pcre.org/current/doc/html/pcre2syntax.html#SEC10) "instance_guid_until_eof" data => data_regextract( "^guid\s+=\s+(?.*)$", readfile ( $(file), inf )); "instance_guid" data => data_regextract( "^guid\s+=\s+(?[^\n]*)", readfile( $(file), inf )); "instance_port" data => data_regextract( "^port\s?+=\s?+(?[^\n]*)", readfile( $(file), inf )); } bundle agent check { classes: "pass" and => { strcmp( "$(test.instance_guid[value])", "9CB197F0-4569-446A-A987-1DDEC1205F6B"), strcmp( "$(test.instance_port[value])", "5308"), strcmp( "$(test.instance_guid_until_eof[value])", "9CB197F0-4569-446A-A987-1DDEC1205F6B$(const.n)port=5308"), }; reports: DEBUG:: "expect test.instance_guid[value] '$(test.instance_guid[value])' == '9CB197F0-4569-446A-A987-1DDEC1205F6B'"; "expect test.instance_port[value] '$(test.instance_port[value])' == '5308'"; "expect test.instance_guid_until_eof[value] '$(test.instance_guid_until_eof[value])' == '9CB197F0-4569-446A-A987-1DDEC1205F6B$(const.n)port=5308'"; methods: "Result" usebundle => dcs_passif( "pass", $(this.promise_filename) ), inherit => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/missing_functions.cf.sub0000644000000000000000000000112315010704253027227 0ustar00rootroot00000000000000############################################################################## # # Redmine #3907: supposedly missing functions (in this case, a classes body with parameters) aren't # ############################################################################## body common control { bundlesequence => {"example"}; } bundle agent example { vars: "testme" string => "me?!?!?!", classes => 9fdee2550bec1030e22addb0dc9d7218b9174c70("1"); } body classes 9fdee2550bec1030e22addb0dc9d7218b9174c70(x) { promise_repaired => { "9fdee2550bec1030e22addb0dc9d7218b9174c70" }; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classesmatching.cf0000644000000000000000000000364415010704253026060 0ustar00rootroot00000000000000# Test that classesmatching and countclassesmatching work correctly body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { classes: "test_fbeae67f3e347b5e0032302200141131" expression => "any", meta => { "x" }; "test_fbeae67f3e347b5e0032302200141131_1" expression => "any", meta => { "x" }; "test_fbeae67f3e347b5e0032302200141131_2" expression => "any", meta => { "y" }; } bundle common test { vars: "classes" slist => classesmatching("test_fbeae67f3e347b5e0032302200141131.*"); "x_classes" slist => classesmatching("test_fbeae67f3e347b5e0032302200141131.*", "x"); "z_classes" slist => classesmatching("test_fbeae67f3e347b5e0032302200141131.*", "z"); "ccm_classes" int => countclassesmatching("test_fbeae67f3e347b5e0032302200141131.*"); "ccm_x_classes" int => countclassesmatching("test_fbeae67f3e347b5e0032302200141131.*", "x"); "ccm_z_classes" int => countclassesmatching("test_fbeae67f3e347b5e0032302200141131.*", "z"); "count" int => length(classes); "x_count" int => length(x_classes); "z_count" int => length(z_classes); classes: "have_count_classes" expression => strcmp($(count), 3); "have_count_x_classes" expression => strcmp($(x_count), 2); "have_count_z_classes" expression => strcmp($(z_count), 0); "have_ccm_classes" expression => strcmp($(ccm_classes), 3); "have_ccm_x_classes" expression => strcmp($(ccm_x_classes), 2); "have_ccm_z_classes" expression => strcmp($(ccm_z_classes), 0); } bundle agent check { methods: "" usebundle => dcs_passif_expected("have_count_classes,have_count_x_classes,have_count_z_classes,have_ccm_classes,have_ccm_x_classes,have_ccm_z_classes", "", $(this.promise_filename)), inherit => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/019.cf0000644000000000000000000000270015010704253023211 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","X",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123.456", "$(nums)"); "ok" and => { "ok_list", "ok123", islessthan("$(test.sum)", "123.457"), isgreaterthan("$(test.sum)", "123.455") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata.cf.expected.json0000644000000000000000000000535115010704253027222 0ustar00rootroot00000000000000{ "explicit_csv": [ [ "a", "b", "c" ], [ "d", "e", "f" ], [ "g,h,i" ] ], "explicit_env": { "A": "B", "ANSI_COLOR": "37;4;65", "BACKSLASH": "\\", "BACKSLASH2": "\\", "BUG_REPORT_URL": "https://northerntech.atlassian.net/projects/CFE/issues", "BUILD_ID": "2017-02-14-2245", "C": "D", "DOUBLE_QUOTE1": "\"", "DOUBLE_QUOTE2": "\"", "DOUBLE_QUOTE3": "\"", "E": "F\"G", "EMPTY": "", "HOME_URL": "https://cfengine.com/", "ID": "cfengineos", "INDENT": "hello", "INDENT1": "world", "INDENT12": "!", "INDENT123": "!", "MESSAGE_TO_NICK": "Single quotes are \"fine\"!", "NAME": "Test Linux by CFEngine", "OVERRIDE": "new", "PRETTY_NAME": "Test Linux by CFEngine 1234.5.0 (Leafant)", "QUOTE_IN_TEXT": "text \"quote\" text", "SINGLE_QUOTE1": "'", "SINGLE_QUOTE2": "'", "SINGLE_QUOTE3": "'", "SPACE": " ", "UNFINISHED_QUOTE1": "OOPS", "UNFINISHED_QUOTE2": "WOOPS", "VERSION": "1234.5.0", "X_COMMENT": "Outisde content not included", "Y_COMMENT": "Comment #included", "x": "y" }, "explicit_json": { "x": [ 1, 2, 3 ], "y": "more data here", "z": { "300": 400 } }, "extension_csv": [ [ "a", "b", "c" ], [ "d", "e", "f" ], [ "g,h,i" ] ], "extension_env": { "A": "B", "ANSI_COLOR": "37;4;65", "BACKSLASH": "\\", "BACKSLASH2": "\\", "BUG_REPORT_URL": "https://northerntech.atlassian.net/projects/CFE/issues", "BUILD_ID": "2017-02-14-2245", "C": "D", "DOUBLE_QUOTE1": "\"", "DOUBLE_QUOTE2": "\"", "DOUBLE_QUOTE3": "\"", "E": "F\"G", "EMPTY": "", "HOME_URL": "https://cfengine.com/", "ID": "cfengineos", "INDENT": "hello", "INDENT1": "world", "INDENT12": "!", "INDENT123": "!", "MESSAGE_TO_NICK": "Single quotes are \"fine\"!", "NAME": "Test Linux by CFEngine", "OVERRIDE": "new", "PRETTY_NAME": "Test Linux by CFEngine 1234.5.0 (Leafant)", "QUOTE_IN_TEXT": "text \"quote\" text", "SINGLE_QUOTE1": "'", "SINGLE_QUOTE2": "'", "SINGLE_QUOTE3": "'", "SPACE": " ", "UNFINISHED_QUOTE1": "OOPS", "UNFINISHED_QUOTE2": "WOOPS", "VERSION": "1234.5.0", "X_COMMENT": "Outisde content not included", "Y_COMMENT": "Comment #included", "x": "y" }, "extension_json": { "x": [ 1, 2, 3 ], "y": "more data here", "z": { "300": 400 } }, "failed_explicit_csv": [], "failed_explicit_env": { }, "guess_json": { "x": [ 1, 2, 3 ], "y": "more data here", "z": { "300": 400 } } } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/225.cf0000644000000000000000000000254715010704253023221 0ustar00rootroot00000000000000####################################################### # # Test grep(), size 1, last element # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "Five"; } ####################################################### bundle agent test { vars: "array" slist => { "One", "Two", "Three", "Four", "Five" }; "vals" slist => grep(".*v.*", "array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/016.cf0000644000000000000000000000310715010704253023210 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456"; "789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/filter.cf.expected.json0000644000000000000000000000417715010704253026747 0ustar00rootroot00000000000000{ "d1": [ 1, 2, 3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three" ], "d1_exact1": [ "one", "one" ], "d1_exactdot": [], "d1_fgrep09": [ "1", "2", "3" ], "d1_grep09": [ "1", "2", "3" ], "d1_invert": [ "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three" ], "d1_max0": [], "d1_max2": [ "1", "2" ], "d1_regexdot": [ "1", "2", "3" ], "d2": { "a": "b", "one": 1, "p": "q", "three": 3, "two": 2, "x": "y" }, "d2_exact1": [], "d2_exactdot": [], "d2_fgrep09": [ "1", "2", "3" ], "d2_grep09": [ "1", "2", "3" ], "d2_invert": [ "y", "b", "q" ], "d2_max0": [], "d2_max2": [ "1", "2" ], "d2_regexdot": [ "1", "2", "3", "y", "b", "q" ], "dempty": [], "dempty_exact1": [], "dempty_exactdot": [], "dempty_fgrep09": [], "dempty_grep09": [], "dempty_invert": [], "dempty_max0": [], "dempty_max2": [], "dempty_regexdot": [], "inline_exact1": [], "inline_exactdot": [], "inline_fgrep09": [ "1", "2", "3" ], "inline_grep09": [ "1", "2", "3" ], "inline_invert": [], "inline_max0": [], "inline_max2": [ "1", "2" ], "inline_regexdot": [ "1", "2", "3" ], "lists": [ "s1", "d1", "d2", "dempty" ], "s1": [ "1", "2", "3", "one", "two", "three", "long string", "one", "two", "three" ], "s1_exact1": [ "one", "one" ], "s1_exactdot": [], "s1_fgrep09": [ "1", "2", "3" ], "s1_grep09": [ "1", "2", "3" ], "s1_invert": [ "one", "two", "three", "long string", "one", "two", "three" ], "s1_max0": [], "s1_max2": [ "1", "2" ], "s1_regexdot": [ "1", "2", "3" ], "tests": [ "fgrep09", "exact1", "exactdot", "regexdot", "invert", "max2", "max0", "grep09" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/read-file-endless-loop.cf0000644000000000000000000000104415010704253027132 0ustar00rootroot00000000000000# Test that regline, getfields and countlinesmatching do not loop endlessly if # supplied with a directory (Redmine #2453) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { } bundle agent test { classes: "foo" expression => regline("foo", "/"); vars: "bar" int => getfields(".*", "/", ":", "foo"); "baz" int => countlinesmatching(".*", "/"); } bundle agent check { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/bundlestate.cf0000644000000000000000000000352015010704253025213 0ustar00rootroot00000000000000# Test that the bundlestate() function gives good data body common control { inputs => { "../../default.cf.sub", "bundlestate.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "s" string => "Hello!"; "d" data => parsejson('[4,5,6]'); "list" slist => { "element1", "element2" }; "h" data => parsejson('{ "a": "x", "b": "y"}'); methods: "" usebundle => external:init; "" usebundle => external:dump; } bundle agent test { vars: "holder" data => bundlestate("init"); "holder2" data => bundlestate("$(this.namespace):init"); "holder3" data => bundlestate("nosuchnamespace:init"); "holder4" data => bundlestate("external:init"); "holder_s" string => format("%S", holder); "holder2_defined" string => ifelse(isvariable(holder2), "we have holder 2 and we shouldn't", ""); "holder3_defined" string => ifelse(isvariable("holder3"), "we have holder 3 and we shouldn't", ""); "holder4_s" string => format("%S", holder4); "s_s" string => format("%S", "holder[s]"); "s_d" string => format("%S", "holder[d]"); "s_list" string => format("%S", "holder[list]"); "s_h" string => format("%S", "holder[h]"); } bundle agent check { methods: "check" usebundle => dcs_check_strcmp("$(test.s_s) $(test.s_d) $(test.s_list) $(test.s_h) $(test.holder4_s) $(external:dump.external_holder_s) $(external:dump.external_holder2_s) $(test.holder2_defined) $(test.holder3_defined)", '"Hello!" [4,5,6] ["element1","element2"] {"a":"x","b":"y"} {"external_s":"External Hello!"} $(test.holder_s) {"external_s":"External Hello!"} ', $(this.promise_filename), "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/nth_datacontainer.cf.expected0000644000000000000000000000162115010704253030166 0ustar00rootroot00000000000000jsonstring = {"boolean":true,"boolean_2":false,"integer":20130111,"integer_2":987654321,"list":["chris","dituri","was","here"],"null":null,"object":{"a":true,"b":[1,2,3],"c":"cat","d":108},"string":"Figaro. Figaro. Figaro, Figaro, Figaro... Figaro!","string_2":"Othello? Where art thou now?"} keys:json = boolean keys:json = boolean_2 keys:json = integer keys:json = integer_2 keys:json = list keys:json = null keys:json = object keys:json = string keys:json = string_2 primitive:json[boolean] = true primitive:json[boolean_2] = false primitive:json[integer] = 20130111 primitive:json[integer_2] = 987654321 primitive:json[null] = null primitive:json[string] = Figaro. Figaro. Figaro, Figaro, Figaro... Figaro! primitive:json[string_2] = Othello? Where art thou now? list:json[0] = chris list:json[1] = dituri list:json[2] = was list:json[3] = here object:json[a] = true object:json[c] = cat object:json[d] = 108 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/execresult_4k.cf0000644000000000000000000000142615010704253025465 0ustar00rootroot00000000000000####################################################### # # Test returnszero() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: any:: "cwd" string => dirname("$(this.promise_filename)"); "cat_4k" string => "$(G.cat) $(cwd)$(const.dirsep)text_xform.cf.txt"; "result" string => execresult("$(cat_4k)", "useshell"); classes: any:: "ok" expression => regcmp(".*3456789abcdefghij$", "$(result)"); reports: DEBUG:: "$(result)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/and.cf0000644000000000000000000001602415010704253023446 0ustar00rootroot00000000000000###################################################### # # Test that and() behaves as expected # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3470" } string => "Test that and() behaves as expected"; vars: "f" # false string => "(cfengine.(!cfengine))"; "T" # true, uppercase to be more different visually string => "(cfengine|(!cfengine))"; "f_name" string => "f"; "T_name" string => "T"; "f_name_name" string => "f_name"; "T_name_name" string => "T_name"; "many_true" slist => { "any", "$(T)", concat(not(and("$(f)"))), "(any.cfengine)", concat(and()), concat(and(and())), }; "many_false" slist => { "(!any)", "$(f)", concat(and(not("$(T)"))), "(any.!cfengine)", concat(not("any")), concat(not(and())), }; "many_both" slist => { @(many_true), @(many_false) }; classes: # All elements should be true, fail if one is false: "ok" scope => "namespace", and => { # Sanity check: "any", "cfengine", # and() with 0 arguments should default to true: and(), # and() with 1 static string: and("any"), and("cfengine"), and("!(!cfengine)"), # and() with 1 string with variable expansion(s): and("$(T)"), and("!$(f)"), and("$(T).any"), and("$(T).!(!any)"), and("any.$(T)"), and("!(!any).$(T)"), and("any|$(f)"), and("!(!any)|$(f)"), and("$(T)|$(f)"), and("$(f)|$(T)"), # and() with slist: # Careful, if there are expressions in list (using | operator) # they should be parenthesized for this to work: and(join(".", many_true)), and(join("|", many_true)), and(join("|", many_both)), and(not(join(".", many_false))), and(not(join("|", many_false))), and(not(join(".", many_both))), # and() with 1 function call as argument: and(and("any")), and(and("cfengine")), and(not("!cfengine")), and(not(not("cfengine"))), and(not("$(f)")), and(not(not("$(T)"))), and(strcmp("cfengine", "cfengine")), and(strcmp("any", not("$(f)"))), # and() with 2 arguments: and("any", "cfengine"), and("!(!any)", "!(!cfengine)"), and("$(T)", "$(T)"), and("$(T)", "!$(f)"), and("$(T)", not("$(f)")), and(not("$(f)"), not("$(f)")), # and() with 3+ arguments (strings): and("any", "any", "any"), and("any", "any", "any", "any"), and("any", "any", "any", "any", "any"), and("any", "any", "any", "any", "any", "any"), and("$(T)", "$(T)", "$(T)"), and("$(T)", "$(T)", "$(T)", "$(T)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), # and() with 3+ function calls: and(not("!any"), not("!any"), not("!any")), and(not("!any"), not("!any"), not("!any"), not("!any")), and(not("!any"), not("!any"), not("!any"), not("!any"), not("!any")), and(not("!any"), not("!any"), not("!any"), not("!any"), not("!any"), not("!any")), and(not("$(f)"), not("$(f)"), not("$(f)")), and(not("$(f)"), not("$(f)"), not("$(f)"), not("$(f)")), and(not("$(f)"), not("$(f)"), not("$(f)"), not("$(f)"), not("$(f)")), and(not("$(f)"), not("$(f)"), not("$(f)"), not("$(f)"), not("$(f)"), not("$(f)")), # and() with deep nesting: and(and()), and(and(and())), and(and(and(and()))), and(and(and(and(and())))), and(and(and(and(and(and()))))), and(and(and(and(and(and("any")))))), and(and(and(and(and(and("any", "cfengine")))))), # Double expansion: and("$($(T_name))"), and("$($(T_name))", "$($(T_name))"), and("$($(T_name))", "$($(T_name))", "$($(T_name))"), and("!$($(f_name))", "!$($(f_name))"), and("!$($(f_name))", "!$($(f_name))", "!$($(f_name))"), and(not("$($(f_name))"), not("$($(f_name))")), # Triple expansion: and("$($($(T_name_name)))"), and("$($($(T_name_name)))", "$($($(T_name_name)))"), and("$($($(T_name_name)))", "$($($(T_name_name)))", "$($($(T_name_name)))"), and("!$($(f_name_name))", "!$($(f_name_name))"), and("!$($(f_name_name))", "!$($(f_name_name))", "!$($(f_name_name))"), and(not("$($(f_name_name))"), not("$($(f_name_name))")), # and() should always return any or !any, # this is important for backwards compatibility: strcmp(and("any"), "any"), strcmp(and("!any"), "!any"), strcmp(and("!cfengine"), "!any"), strcmp(and("!(cfengine.!cfengine)"), "any"), strcmp(and("$(T)"), "any"), strcmp(and("$(f)"), "!any"), strcmp(and("$(T)", "$(T)"), "any"), strcmp(and("$(T)", "$(f)"), "!any"), strcmp(and("$(f)", "$(T)"), "!any"), strcmp(and("$(f)", "$(f)"), "!any"), }; # Cases where and() should return false (fail if one is true): "fail_false" or => { and("$(f)"), and("$(T)", "$(f)"), and("$(T)", "$(T)", "$(f)"), and("$(T)", "$(T)", "$(T)", "$(f)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(f)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(f)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(f)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(f)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(f)", "$(T)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(f)", "$(T)", "$(T)"), and("$(T)", "$(T)", "$(T)", "$(T)", "$(f)", "$(T)", "$(T)", "$(T)"), and("$(T)", "$(T)", "$(T)", "$(f)", "$(T)", "$(T)", "$(T)", "$(T)"), and("$(T)", "$(T)", "$(f)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), and("$(T)", "$(f)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), and("$(f)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), }; # Should be skipped because of unresolved variable: "fail_unresolved" and => { "any", and("$(unresolved_var)"), }; # Check that it's really skipped because of unresolved, # and not that it accidentally becomes false: "fail_not_of_unresolved" and => { "any", and(not("$(unresolved_var)")), }; "fail" scope => "namespace", expression => "fail_false|fail_unresolved|fail_not_of_unresolved"; } ####################################################### bundle agent check { reports: ok.(!fail):: "$(this.promise_filename) Pass"; (!ok)|fail:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_expand.cf.json0000644000000000000000000000013215010704253026115 0ustar00rootroot00000000000000{ "plain data": "nothing", "$(x)": "nothing again", "$(y)": "$(nosuchvar)", } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/222.cf0000644000000000000000000000217115010704253023207 0ustar00rootroot00000000000000####################################################### # # Test grep(), size 0, global array # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true"; } ####################################################### bundle agent test { vars: "array" slist => { "One", "Two", "Three", "Four", "Five" }; "vals" slist => grep("Z.*", "test.array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/ifelse_undefined.cf0000644000000000000000000000217415010704253026175 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "ENT-4653" } string => "Test that ifelse works with undefined variables in the second or third arguments"; vars: "test_one" string => ifelse( "no_such_class", "$(no_such_var)", "test_one_expected_value" ); "test_two" string => ifelse( "any", "test_two_expected_value", "$(no_such_var)" ); } bundle agent check { reports: '$(this.promise_filename) Pass' if => and( strcmp( "test_one_expected_value", $(test.test_one) ), strcmp( "test_two_expected_value", $(test.test_two) ) ); '$(this.promise_filename) FAIL' if => or( not( isvariable( "test.test_one" ) ), not( isvariable( "test.test_two" ) ) ); '$(this.propmise_filename) FAIL' if => or( not(strcmp( "test_one_expected_value", $(test.test_one) ) ), not(strcmp( "test_two_expected_value", $(test.test_two) ) ) ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/long_string_from_text_file.cf0000644000000000000000000000651215010704253030320 0ustar00rootroot00000000000000####################################################### # # Test that we don't crash when reading in large strings from a file # Redmine:3957 (https://cfengine.com/dev/issues/3957) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).data" create => "true", edit_defaults => empty, edit_line => seed_data; } ####################################################### bundle agent test { vars: "keyfile" string => "$(G.testfile).data"; "keys" slist => readstringlist("$(keyfile)", "#[^\n]*", "\n", 10, 3072); } ####################################################### bundle agent check { classes: "ok" expression => "any", comment => "If we made it to here, we didn't crash"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } bundle edit_line seed_data { insert_lines: "ssh-dss YavBsyK3sHDac4Gj4nDbVH9E7OfRPi16DADNOWGKEjWiBB0cCe0UY6xxEgcYuwOOl8HUGqqzLOByvUbo1hENDQldKFt8N7WIb2E9gXFtGm0Sf0NlYARALj1nhLju9hodpGxkr4vKioW1fZQBmBqsI7Ky8ZhzU5p4CAm4uCbxAZuiIhDTAcxj7RlDy3fe9WBw7v0cSIbu8E3zEbPn0VQjTduLCJtFOb5LvUxpxUsHMhHu0xS8DvXIwf7l83cQ0XZtwyIgbF3ZxjIZaPyYhKZRAV1qCze4BlcOerJeVYOiKjpXJlOoBprxy2SfEYVS4Khun0efkmsmBAfllKUUNCqsK9j6oWo7BvNbXqzkl2ULJd6h0LNy9jW8IXnnrfWknLGa7lksVmL3afSAufDAb7yRESaUP5KmcD3ghP3Nvu7fy9hz7nIAPgj2dQOwnFRbkv9Svoi9YmCtvBWYAcwIUVNJBmwXe5j5xJyt5vOyRSI2ooJ9mk69UOCsIM8PEnEXwtHcsg9fDjfu9ChFY2HWZPWeNXH05SATnSyLgclQsZcazhQXPoxZbcqR80mfuRX9ymEzNwZJ1jJUERnj9PZkSInu6mFVRjTaQjg8yvqMGRxWknP8aURCDh5rr4Na23jULVVI66heWOi7nzLqBg5U8GsbLsocM8zBam8bhXfU0KvpBo5wlUtHnDWHoMlS3ktr25ldrp3zLuywhHe5vGUbg2E0gr4xB3oPAyaDa3MGQiVXPfngu5CJhwIXmeN5JtIBA0S46ihg7lQ6IU8kAaRHwhWh3TokoNFOYE8R5i24gpYNF8dgCRGqSZIT5V7wuR3qG1Wau963ILuX8EFOSu7xDc5qnGTem3FwICTpSdnZNqpzRt4Ipqsn4Pa2tFFpHlzDwKFRPS7r8v4QX7acqdTSCUOuZ68GwDRlvHIz5mHUf1XLY3FH2InuWFsonJAZwmEbX5evWXFgyJHFlplQcGJvyNdL0T6oBmbG3ssSMoRnqnsk8XjGWtUyvYoQmOY8HWlMhf4V3v78C4k4TnCbN4LmnDYaDcnXMejrUMYDk6QwW3fdTF5ZyjJMy4ANu2fJfKysZMc1Cc== root@host1"; "ssh-dss a58AZSxQlmcq33EBCW1GuhpkYCgUfr7o5A1arQZ2dr8I4kldCF76mpl6o2CFthZs4YUU8LewbIDDPqjhS2WwafTXeMEvPMtmLufk6E5njNy2WQtAnmGc9R21qIteTgikY9ubRCM3hlhzJ1wGSKCsE5oBHDQC0thk1ljJGHzsEl0AuVClkUq3yz4eWAsiRdbD9QY7ddD6zA61aHomuczKU5F0VvyO8gRQmWV7b6lysoUFcMgCPVf3UaDdg7L7vvBVkQN2vGCh9CCJz5OkBShlZVNaAXd5TkKJNmsTuBDscPyxeCBAk8sai69f1NNtTeAyWTtSu1KiqTDvD9aal93MhpZnPdOZzNr7etK4C7HuPD0uFjdvKZy1H55rpwNHnJ4GojqiNG1VvN5bGLa3sSLiKOngtMBCokdtHpZn2eHD7oLUROTIG3ZXqFGGvfKEP5zlpvJz3392n4PDQ7EKuNFPhyNQpVXEIAQEDcmeWMopVTGezLoFJG01hKMPxs5QWF7qetVLi1pCjmlUpqgE8c81WGxvMe7ooMtQbeVNulX3qBC3rZhYKtk0R5AA8JxmxHSLYlLFbtnR1PA97hnRvnvlfk92i7WL1hjJsMl29LOrubi554Dr9N2uVUrCFcPZMK45PY0TiRH82AKFmkM8mbM0rndJxoJobZsqRAGHVIkcS53hxMT69liRxlCyubwcxgDaqmeQnJU2Ug0YyFs1uxt4NT9laJ0CO2IxhkbmGeDGw1FJqKyc8Haov263cFMcB97I3gyNHccsAynQnxpMS1ltTFXalghuochdue4unbq0Ty2PfS4jPMkavBlMYN8UZdnyZHuUhycwBJri1Grv5kf2SP00P6NQhuB8kwjqoTG8ay5fKWvhDrVetd7tPuj4dMouHuDeaLJInc7Cz0S5tQOuMfRhpPqk1E8A0YnuNCyPDNuW75rkXZkxP9cYSVWeDa1wgOyNLZDTzYts82qiu9kxLbZ184jowJ8rru4UB20JRtoehnD2nGU1NfegD1qOBgQHtDuB18xggfvOgvUNXBrQpICSz0JqszpftAgV5TJq1FjOdjUo1kOCFuqqi6C4S0Siho== root@host2"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/059.x.cf0000644000000000000000000000171015010704253023463 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,1001,1000,1000,1000,40000); } ####################################################### bundle agent check { vars: "time" int => "2682100000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/findfiles_up.cf0000755000000000000000000001575515010704253025370 0ustar00rootroot00000000000000body common control { bundlesequence => { "init", "test", "check" }; version => "1.0"; } bundle common G { vars: "testdir" string => concat( getenv("TEMP", "65535"), "$(const.dirsep)TESTDIR.cfengine" ); } bundle agent init { vars: "files" slist => { "core/.gitignore", "core/.git/config", "core/libpromises/cf3parse.y", "core/libpromises/cf3lex.l", "core/libntech/.gitignore", "core/libntech/.git/config", "core/libntech/libutils/string.h", "core/libntech/libutils/string.c" }; files: "$(G.testdir)/$(files)" create => "true"; reports: DEBUG:: "Created $(G.testdir)/$(files)"; } bundle agent test { meta: "description" -> { "CFE-3577" } string => "Test for expected results from policy function findfiles_up"; vars: "t1" data => findfiles_up("$(G.testdir)/core/libntech/libutils/", ".gitignore", "inf"); "t2" data => findfiles_up("$(G.testdir)/core/libntech/libutils/", "string.?"); "t3" data => findfiles_up("$(G.testdir)/core/libntech/libutils/", ".git/"); "t4" data => findfiles_up("$(G.testdir)/core/libntech/libutils/", ".git/", "1"); "t5" data => findfiles_up("$(G.testdir)/core/libntech/libutils/", ".git/config"); "t6" data => findfiles_up("$(G.testdir)/core/libntech/libutils/", "*/cf?{lex,parse}.[ly]"); } bundle agent check { classes: windows:: "c1" expression => and( strcmp("$(G.testdir)\\core\\libntech\\.gitignore", "$(test.t1[0])"), strcmp("$(G.testdir)\\core\\.gitignore", "$(test.t1[1])") ); "c2" expression => and( strcmp("$(G.testdir)\\core\\libntech\\libutils\\string.c", "$(test.t2[0])"), strcmp("$(G.testdir)\\core\\libntech\\libutils\\string.h", "$(test.t2[1])") ); "c3" expression => and( strcmp("$(G.testdir)\\core\\libntech\\.git", "$(test.t3[0])"), strcmp("$(G.testdir)\\core\\.git", "$(test.t3[1])") ); "c4" expression => and( strcmp("$(G.testdir)\\core\\libntech\\.git", "$(test.t4[0])"), not(isvariable("test.t4[1]")) ); "c5" expression => and( strcmp("$(G.testdir)\\core\\libntech\\.git\\config", "$(test.t5[0])"), strcmp("$(G.testdir)\\core\\.git\\config", "$(test.t5[1])") ); "c6" expression => and( strcmp("$(G.testdir)\\core\\libpromises\\cf3lex.l", "$(test.t6[0])"), strcmp("$(G.testdir)\\core\\libpromises\\cf3parse.y", "$(test.t6[1])") ); !windows:: "c1" expression => and( strcmp("$(G.testdir)/core/libntech/.gitignore", "$(test.t1[0])"), strcmp("$(G.testdir)/core/.gitignore", "$(test.t1[1])") ); "c2" expression => and( strcmp("$(G.testdir)/core/libntech/libutils/string.c", "$(test.t2[0])"), strcmp("$(G.testdir)/core/libntech/libutils/string.h", "$(test.t2[1])") ); "c3" expression => and( strcmp("$(G.testdir)/core/libntech/.git", "$(test.t3[0])"), strcmp("$(G.testdir)/core/.git", "$(test.t3[1])") ); "c4" expression => and( strcmp("$(G.testdir)/core/libntech/.git", "$(test.t4[0])"), not(isvariable("test.t4[1]")) ); "c5" expression => and( strcmp("$(G.testdir)/core/libntech/.git/config", "$(test.t5[0])"), strcmp("$(G.testdir)/core/.git/config", "$(test.t5[1])") ); "c6" expression => and( strcmp("$(G.testdir)/core/libpromises/cf3lex.l", "$(test.t6[0])"), strcmp("$(G.testdir)/core/libpromises/cf3parse.y", "$(test.t6[1])") ); any:: "ok" expression => and("c1", "c2", "c3", "c4", "c5", "c6"); reports: DEBUG.windows.!c1:: "$(const.dollar)(test.t1[0]): Expected '$(G.testdir)\\core\\libntech\\.gitignore', found '$(test.t1[0])'"; "$(const.dollar)(test.t1[1]): Expected '$(G.testdir)\\core\\.gitignore', found '$(test.t1[1])'"; DEBUG.windows.!c2:: "$(const.dollar)(test.t2[0]): Expected '$(G.testdir)\\core\\libntech\\libutils\\string.c', found '$(test.t2[0])'"; "$(const.dollar)(test.t2[1]): Expected '$(G.testdir)\\core\\libntech\\libutils\\string.h', found '$(test.t2[1])'"; DEBUG.windows.!c3:: "$(const.dollar)(test.t3[0]): Expected '$(G.testdir)\\core\\libntech\\.git', found '$(test.t3[0])'"; "$(const.dollar)(test.t3[1]): Expected '$(G.testdir)\\core\\.git', found '$(test.t3[1])'"; DEBUG.windows.!c4:: "$(const.dollar)(test.t4[0]): Expected '$(G.testdir)\\core\\libntech\\.git', found '$(test.t4[0])'"; "$(const.dollar)(test.t4[1]): Should not exist, $(with). Expanded value: '$(test.t4[1])'" with => ifelse(isvariable("test.t4[1]"), "but does exist", "and does not exist"); DEBUG.windows.!c5:: "$(const.dollar)(test.t5[0]): Expected '$(G.testdir)\\core\\libntech\\.git\\config', found '$(test.t5[0])'"; "$(const.dollar)(test.t5[1]): Expected '$(G.testdir)\\core\\.git\\config', found '$(test.t5[1])'"; DEBUG.windows.!c6:: "$(const.dollar)(test.t6[0]): Expected '$(G.testdir)\\core\\libpromises\\cf3lex.l', found '$(test.t6[0])'"; "$(const.dollar)(test.t6[1]): Expected '$(G.testdir)\\core\\libpromises\\cf3parse.y', found '$(test.t6[1])'"; DEBUG.!windows.!c1:: "$(const.dollar)(test.t1[0]): Expected '$(G.testdir)/core/libntech/.gitignore', found '$(test.t1[0])'"; "$(const.dollar)(test.t1[1]): Expected '$(G.testdir)/core/.gitignore', found '$(test.t1[1])'"; DEBUG.!windows.!c2:: "$(const.dollar)(test.t2[0]): Expected '$(G.testdir)/core/libntech/libutils/string.c', found '$(test.t2[0])'"; "$(const.dollar)(test.t2[1]): Expected '$(G.testdir)/core/libntech/libutils/string.h', found '$(test.t2[1])'"; DEBUG.!windows.!c3:: "$(const.dollar)(test.t3[0]): Expected '$(G.testdir)/core/libntech/.git', found '$(test.t3[0])'"; "$(const.dollar)(test.t3[1]): Expected '$(G.testdir)/core/.git', found '$(test.t3[1])'"; DEBUG.!windows.!c4:: "$(const.dollar)(test.t4[0]): Expected '$(G.testdir)/core/libntech/.git', found '$(test.t4[0])'"; "$(const.dollar)(test.t4[1]): Should not exist, $(with). Expanded value: '$(test.t4[1])'" with => ifelse(isvariable("test.t4[1]"), "but does exist", "and does not exist"); DEBUG.!windows.!c5:: "$(const.dollar)(test.t5[0]): Expected '$(G.testdir)/core/libntech/.git/config', found '$(test.t5[0])'"; "$(const.dollar)(test.t5[1]): Expected '$(G.testdir)/core/.git/config', found '$(test.t5[1])'"; DEBUG.!windows.!c6:: "$(const.dollar)(test.t6[0]): Expected '$(G.testdir)/core/libpromises/cf3lex.l', found '$(test.t6[0])'"; "$(const.dollar)(test.t6[1]): Expected '$(G.testdir)/core/libpromises/cf3parse.y', found '$(test.t6[1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/bundlesmatching_dynamicsequence.cf0000644000000000000000000000155715010704253031315 0ustar00rootroot00000000000000# Test that bundlesmatching works correctly for dynamic sequences body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { } bundle agent test { vars: "runs" slist => bundlesmatching("default:run.*"); methods: "run them" usebundle => $(runs); } bundle agent check { classes: "ok" and => { ok1, ok2, ok3 }; reports: DEBUG:: "Found bundles $(test.runs)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } bundle agent run_123_456 { classes: "ok1" expression => "any", scope => "namespace"; } bundle agent run_789_0ab { classes: "ok2" expression => "any", scope => "namespace"; } bundle agent run_cde_fgh { classes: "ok3" expression => "any", scope => "namespace"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getfields.cf0000644000000000000000000000261415010704253024652 0ustar00rootroot00000000000000####################################################### # # Test getfields() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", edit_line => init_fill_in; reports: DEBUG:: "Created $(G.testfile)"; } bundle edit_line init_fill_in { insert_lines: "one:data1"; "two:data2"; "three:data3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "num_matching" int => getfields("t.*", "$(G.testfile)", ":", "fields"); } ####################################################### bundle agent check { classes: any:: "ok" and => { strcmp("$(test.fields[1])", "two"), strcmp("$(test.fields[2])", "data2"), strcmp("$(test.num_matching)", "2") }; reports: DEBUG:: "got field $(test.fields[1])"; "got field $(test.fields[2])"; "num_matching is $(test.num_matching)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sort.cf.expected.json0000644000000000000000000002351615010704253026447 0ustar00rootroot00000000000000{ "IP_sorted_a": [ "a", "b", "c" ], "IP_sorted_b": [ "10", "100", "9" ], "IP_sorted_c": [], "IP_sorted_d": [ "", "", "a", "b" ], "IP_sorted_e": [ "1", "a", "b" ], "IP_sorted_f": [ "0", "0.1", "100.0", "3.2" ], "IP_sorted_g": [ "", "-2.1", "0.88", "00.88", "b" ], "IP_sorted_ip": [ "", "-1", "9", "9.7", "9.7.5", "where are the IP addresses?", "1.2.3.4", "9.7.5.1", "100.200.100.0" ], "IP_sorted_ipv6": [ "-1", "2001:0000:4136:e378:", "2001:DB8:0:0:1::1", "8000:63bf:3fff:fdd2", "8000:63bf:3fff:fdd2", "::ffff:192.0.2.47", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "FE80::0202:B3FF:FE1E:8329", "where are the IP addresses?", "::1", "2001:0002:6c::430", "2001:10:240:ab::a", "2001:db8:0000:0:1::1", "2001:db8:0:0:1::1", "2001:0db8::1:0:0:1", "2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1", "2001:0db8:0:0:1:0:0:1", "2001:db8:0:0:1:0:0:1", "2001:db8:8:4::2", "2002:cb0a:3cdd:1::1", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "ff01:0:0:0:0:0:0:2" ], "IP_sorted_mac": [ "-1", "00:014:BF:0F7:23:01D", "00:014:BF:0F7:23:01D", "00:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "01:14:BF:F7:23:1D", "01:14:BF:F7:23:2D", "0:14:BF:F7:23:1D", "0:14:BF:F7:23:1D", "1:14:BF:F7:23:1D", "1:14:BF:F7:23:2D", ":14:BF:F7:23:1D", ":14:BF:F7:23:1D", "where are the MAC addresses?" ], "MAC_sorted_a": [ "a", "b", "c" ], "MAC_sorted_b": [ "10", "100", "9" ], "MAC_sorted_c": [], "MAC_sorted_d": [ "", "", "a", "b" ], "MAC_sorted_e": [ "1", "a", "b" ], "MAC_sorted_f": [ "0", "0.1", "100.0", "3.2" ], "MAC_sorted_g": [ "", "-2.1", "0.88", "00.88", "b" ], "MAC_sorted_ip": [ "", "-1", "1.2.3.4", "100.200.100.0", "9", "9.7", "9.7.5", "9.7.5.1", "where are the IP addresses?" ], "MAC_sorted_ipv6": [ "-1", "2001:0000:4136:e378:", "2001:0002:6c::430", "2001:0db8::1:0:0:1", "2001:10:240:ab::a", "2001:DB8:0:0:1::1", "2001:db8:0000:0:1::1", "2001:db8:0:0:1::1", "2001:db8:8:4::2", "2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1", "2002:cb0a:3cdd:1::1", "8000:63bf:3fff:fdd2", "8000:63bf:3fff:fdd2", "::1", "::ffff:192.0.2.47", "FE80::0202:B3FF:FE1E:8329", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "where are the IP addresses?", "ff01:0:0:0:0:0:0:2", "2001:0db8:0:0:1:0:0:1", "2001:db8:0:0:1:0:0:1", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329" ], "MAC_sorted_mac": [ "-1", ":14:BF:F7:23:1D", ":14:BF:F7:23:1D", "where are the MAC addresses?", "00:014:BF:0F7:23:01D", "0:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "00:014:BF:0F7:23:01D", "0:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "1:14:BF:F7:23:1D", "01:14:BF:F7:23:1D", "1:14:BF:F7:23:2D", "01:14:BF:F7:23:2D" ], "inline_IP_sorted": [ "10", "100", "9", "a", "b", "c" ], "inline_MAC_sorted": [ "10", "100", "9", "a", "b", "c" ], "inline_int_sorted": [ "a", "b", "c", "9", "10", "100" ], "inline_lex_sorted": [ "10", "100", "9", "a", "b", "c" ], "inline_real_sorted": [ "a", "b", "c", "9", "10", "100" ], "int_sorted_a": [ "a", "b", "c" ], "int_sorted_b": [ "9", "10", "100" ], "int_sorted_c": [], "int_sorted_d": [ "", "", "a", "b" ], "int_sorted_e": [ "a", "b", "1" ], "int_sorted_f": [ "0.1", "0", "3.2", "100.0" ], "int_sorted_g": [ "", "b", "-2.1", "00.88", "0.88" ], "int_sorted_ip": [ "", "where are the IP addresses?", "-1", "1.2.3.4", "9.7.5", "9.7", "9", "9.7.5.1", "100.200.100.0" ], "int_sorted_ipv6": [ "::1", "::ffff:192.0.2.47", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "FE80::0202:B3FF:FE1E:8329", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "ff01:0:0:0:0:0:0:2", "where are the IP addresses?", "-1", "2001:db8:8:4::2", "2001:10:240:ab::a", "2001:0002:6c::430", "2001:0000:4136:e378:", "2001:DB8:0:0:1::1", "2001:db8:0000:0:1::1", "2001:db8:0:0:1::1", "2001:0db8::1:0:0:1", "2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1", "2001:0db8:0:0:1:0:0:1", "2001:db8:0:0:1:0:0:1", "2002:cb0a:3cdd:1::1", "8000:63bf:3fff:fdd2", "8000:63bf:3fff:fdd2" ], "int_sorted_mac": [ ":14:BF:F7:23:1D", ":14:BF:F7:23:1D", "where are the MAC addresses?", "-1", "00:014:BF:0F7:23:01D", "0:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "00:014:BF:0F7:23:01D", "0:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "1:14:BF:F7:23:2D", "01:14:BF:F7:23:2D", "1:14:BF:F7:23:1D", "01:14:BF:F7:23:1D" ], "lex_sorted_a": [ "a", "b", "c" ], "lex_sorted_b": [ "10", "100", "9" ], "lex_sorted_c": [], "lex_sorted_d": [ "", "", "a", "b" ], "lex_sorted_e": [ "1", "a", "b" ], "lex_sorted_f": [ "0", "0.1", "100.0", "3.2" ], "lex_sorted_g": [ "", "-2.1", "0.88", "00.88", "b" ], "lex_sorted_ip": [ "", "-1", "1.2.3.4", "100.200.100.0", "9", "9.7", "9.7.5", "9.7.5.1", "where are the IP addresses?" ], "lex_sorted_ipv6": [ "-1", "2001:0000:4136:e378:", "2001:0002:6c::430", "2001:0db8:0:0:1:0:0:1", "2001:0db8::1:0:0:1", "2001:10:240:ab::a", "2001:DB8:0:0:1::1", "2001:db8:0000:0:1::1", "2001:db8:0:0:1:0:0:1", "2001:db8:0:0:1::1", "2001:db8:8:4::2", "2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1", "2002:cb0a:3cdd:1::1", "8000:63bf:3fff:fdd2", "8000:63bf:3fff:fdd2", "::1", "::ffff:192.0.2.47", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "FE80::0202:B3FF:FE1E:8329", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "ff01:0:0:0:0:0:0:2", "where are the IP addresses?" ], "lex_sorted_mac": [ "-1", "00:014:BF:0F7:23:01D", "00:014:BF:0F7:23:01D", "00:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "01:14:BF:F7:23:1D", "01:14:BF:F7:23:2D", "0:14:BF:F7:23:1D", "0:14:BF:F7:23:1D", "1:14:BF:F7:23:1D", "1:14:BF:F7:23:2D", ":14:BF:F7:23:1D", ":14:BF:F7:23:1D", "where are the MAC addresses?" ], "real_sorted_a": [ "a", "b", "c" ], "real_sorted_b": [ "9", "10", "100" ], "real_sorted_c": [], "real_sorted_d": [ "", "", "a", "b" ], "real_sorted_e": [ "a", "b", "1" ], "real_sorted_f": [ "0", "0.1", "3.2", "100.0" ], "real_sorted_g": [ "", "b", "-2.1", "00.88", "0.88" ], "real_sorted_ip": [ "", "where are the IP addresses?", "-1", "1.2.3.4", "9", "9.7.5", "9.7", "9.7.5.1", "100.200.100.0" ], "real_sorted_ipv6": [ "::1", "::ffff:192.0.2.47", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "FE80::0202:B3FF:FE1E:8329", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "ff01:0:0:0:0:0:0:2", "where are the IP addresses?", "-1", "2001:db8:8:4::2", "2001:10:240:ab::a", "2001:0002:6c::430", "2001:0000:4136:e378:", "2001:DB8:0:0:1::1", "2001:db8:0000:0:1::1", "2001:db8:0:0:1::1", "2001:0db8::1:0:0:1", "2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1", "2001:0db8:0:0:1:0:0:1", "2001:db8:0:0:1:0:0:1", "2002:cb0a:3cdd:1::1", "8000:63bf:3fff:fdd2", "8000:63bf:3fff:fdd2" ], "real_sorted_mac": [ ":14:BF:F7:23:1D", ":14:BF:F7:23:1D", "where are the MAC addresses?", "-1", "00:014:BF:0F7:23:01D", "0:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "00:014:BF:0F7:23:01D", "0:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "1:14:BF:F7:23:2D", "01:14:BF:F7:23:2D", "1:14:BF:F7:23:1D", "01:14:BF:F7:23:1D" ], "sort": [ "lex", "int", "real", "IP", "MAC" ], "sorted_a": [ "a", "b", "c" ], "sorted_b": [ "10", "100", "9" ], "sorted_c": [], "sorted_d": [ "", "", "a", "b" ], "sorted_e": [ "1", "a", "b" ], "sorted_f": [ "0", "0.1", "100.0", "3.2" ], "sorted_g": [ "", "-2.1", "0.88", "00.88", "b" ], "sorted_ip": [ "", "-1", "1.2.3.4", "100.200.100.0", "9", "9.7", "9.7.5", "9.7.5.1", "where are the IP addresses?" ], "sorted_ipv6": [ "-1", "2001:0000:4136:e378:", "2001:0002:6c::430", "2001:0db8:0:0:1:0:0:1", "2001:0db8::1:0:0:1", "2001:10:240:ab::a", "2001:DB8:0:0:1::1", "2001:db8:0000:0:1::1", "2001:db8:0:0:1:0:0:1", "2001:db8:0:0:1::1", "2001:db8:8:4::2", "2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1", "2002:cb0a:3cdd:1::1", "8000:63bf:3fff:fdd2", "8000:63bf:3fff:fdd2", "::1", "::ffff:192.0.2.47", "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "FE80::0202:B3FF:FE1E:8329", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "ff01:0:0:0:0:0:0:2", "where are the IP addresses?" ], "sorted_mac": [ "-1", "00:014:BF:0F7:23:01D", "00:014:BF:0F7:23:01D", "00:14:BF:F7:23:1D", "00:14:BF:F7:23:1D", "01:14:BF:F7:23:1D", "01:14:BF:F7:23:2D", "0:14:BF:F7:23:1D", "0:14:BF:F7:23:1D", "1:14:BF:F7:23:1D", "1:14:BF:F7:23:2D", ":14:BF:F7:23:1D", ":14:BF:F7:23:1D", "where are the MAC addresses?" ], "test": [ "a", "b", "c", "d", "e", "f", "g", "ip", "ipv6", "mac" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/strftime_GMT.cf0000644000000000000000000000321515010704253025246 0ustar00rootroot00000000000000####################################################### # # Test strftime() against some GMT classes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: # These classes don't depend on the locale # we require two digits to filter out GMT_Hr0 through 9 # (note that %k has a leading space, so we can't use it below) "results" slist => classesmatching("^GMT_(Hr|Min|Yr)\d\d+$"); files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "$(init.results)"; } ####################################################### bundle agent test { vars: "vals" slist => { # note that %k has a leading space, don't use it strftime('gmtime', 'GMT_Hr%H', now()), strftime('gmtime', 'GMT_Min%M', now()), strftime('gmtime', 'GMT_Yr%Y', now()), }; files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/peers.cf0000644000000000000000000001661115010704253024024 0ustar00rootroot00000000000000####################################################### # # Test peers() # Ref:Redmine:4848 (https://cfengine.com/dev/issues/4848) ####################################################### ### TODO this test is failing, because for example the variable ### default:this.test#actual_peers_nohosts_2 ### is never VariableTablePut ### regex:VariableTablePut\([^)]*actual_peers_nohosts_2 ### ### TODO figure out why actual_peers_nohosts_2 is never Put() body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { methods: "nohosts" usebundle => file_empty("$(G.testfile).nohosts"), comment => "Test the behavior when there are no entries in the file."; "nopeers" usebundle => file_mustache_jsonstring ( "$(this.promise_filename).mustache", '{ "peers": [ "a", "b", "c" ] }', "$(G.testfile).nopeers" ), comment => "Test the behaviour when there are no peers (some hosts, but when the executing host is not found in the list)"; "somepeers" usebundle => file_mustache_jsonstring ( "$(this.promise_filename).mustache", '{ "peers": [ "a", "b", "c", "$(sys.fqhost)" ] }', "$(G.testfile).somepeers" ), comment => "Test the behaviour when there are some peers."; "allpeers" usebundle => file_mustache_jsonstring ( "$(this.promise_filename).mustache", '{ "peers": [ "$(sys.fqhost)", "$(sys.fqhost)", "$(sys.fqhost)", "$(sys.fqhost)" ] }', "$(G.testfile).allpeers" ); } bundle agent test { vars: "tests" slist => { "nohosts", "nopeers", "somepeers", "allpeers" }; "subtests" ilist => { "0", "1", "2", "3", "4", "5" }; "peers_$(tests)_$(subtests)" slist => peers("$(G.testfile).$(tests)", "#.*", $(subtests)); "peerleaders_$(tests)_$(subtests)" slist => peerleaders("$(G.testfile).$(tests)", "#.*", $(subtests)); "actual_peers_$(tests)_$(subtests)" string => format("%S", "peers_$(tests)_$(subtests)"); "actual_peerleaders_$(tests)_$(subtests)" string => format("%S", "peerleaders_$(tests)_$(subtests)"); "actual_peerleader_$(tests)_$(subtests)" string => peerleader("$(G.testfile).$(tests)", "#.*", $(subtests)); } ####################################################### bundle agent check { vars: "f" slist => { "peers", "peerleader", "peerleaders" }; "tests" slist => { @(test.tests) }; "subtests" ilist => { @(test.subtests) }; "good_cases" slist => { "peers_nohosts_2", "peers_nohosts_3", "peers_nohosts_4", "peers_nohosts_5", "peers_nopeers_2", "peers_nopeers_3", "peers_nopeers_4", "peers_nopeers_5", "peers_somepeers_2", "peers_somepeers_3", "peers_somepeers_4", "peers_somepeers_5", "peers_allpeers_2", "peers_allpeers_3", "peers_allpeers_4", "peers_allpeers_5", "peers_somepeers_2", "peers_somepeers_4", "peers_somepeers_5", "peerleader_somepeers_2", "peerleader_somepeers_3", "peerleader_somepeers_4", "peerleader_somepeers_5", "peerleader_allpeers_2", "peerleader_allpeers_3", "peerleader_allpeers_4", "peerleader_allpeers_5", "peerleaders_nohosts_2", "peerleaders_nohosts_3", "peerleaders_nohosts_4", "peerleaders_nohosts_5", "peerleaders_nopeers_2", "peerleaders_nopeers_3", "peerleaders_nopeers_4", "peerleaders_nopeers_5", "peerleaders_somepeers_2", "peerleaders_somepeers_3", "peerleaders_somepeers_4", "peerleaders_somepeers_5", "peerleaders_allpeers_2", "peerleaders_allpeers_3", "peerleaders_allpeers_4", "peerleaders_allpeers_5", }; "bad_cases" slist => { "peers_nohosts_0", "peers_nohosts_1", "peers_nopeers_0", "peers_nopeers_1", "peers_somepeers_0", "peers_somepeers_1", "peers_allpeers_0", "peers_allpeers_1", "peerleader_nohosts_0", "peerleader_nohosts_1", "peerleader_nohosts_2", "peerleader_nohosts_3", "peerleader_nohosts_4", "peerleader_nohosts_5", "peerleader_nopeers_0", "peerleader_nopeers_1", "peerleader_nopeers_2", "peerleader_nopeers_3", "peerleader_nopeers_4", "peerleader_nopeers_5", "peerleader_somepeers_0", "peerleader_somepeers_1", "peerleader_allpeers_0", "peerleader_allpeers_1", "peerleaders_nohosts_0", "peerleaders_nohosts_1", "peerleaders_nopeers_0", "peerleaders_nopeers_1", "peerleaders_somepeers_0", "peerleaders_somepeers_1", "peerleaders_allpeers_0", "peerleaders_allpeers_1", }; "expected_peers_allpeers_$(subtests)" string => '{ }'; "expected_peers_nopeers_$(subtests)" string => '{ }'; "expected_peers_nohosts_$(subtests)" string => '{ }'; "expected_peers_allpeers_$(subtests)" string => '{ }'; "expected_peers_nopeers_$(subtests)" string => '{ }'; "expected_peers_nohosts_$(subtests)" string => '{ }'; "expected_peers_somepeers_2" string => '{ "c" }'; "expected_peers_somepeers_3" string => '{ }'; "expected_peers_somepeers_4" string => '{ "a", "b", "c" }'; "expected_peers_somepeers_5" string => '{ "a", "b", "c" }'; "expected_peerleader_allpeers_$(subtests)" string => 'localhost'; "expected_peerleader_somepeers_2" string => 'c'; "expected_peerleader_somepeers_3" string => 'localhost'; "expected_peerleader_somepeers_4" string => 'a'; "expected_peerleader_somepeers_5" string => 'a'; "expected_peerleaders_nohosts_$(subtests)" string => '{ }'; "expected_peerleaders_nopeers_2" string => '{ "a", "c" }'; "expected_peerleaders_nopeers_3" string => '{ "a" }'; "expected_peerleaders_nopeers_4" string => '{ "a" }'; "expected_peerleaders_nopeers_5" string => '{ "a" }'; "expected_peerleaders_somepeers_2" string => '{ "a", "c" }'; "expected_peerleaders_somepeers_3" string => '{ "a", "localhost" }'; "expected_peerleaders_somepeers_4" string => '{ "a" }'; "expected_peerleaders_somepeers_5" string => '{ "a" }'; "expected_peerleaders_allpeers_2" string => '{ "localhost", "localhost" }'; "expected_peerleaders_allpeers_3" string => '{ "localhost", "localhost" }'; "expected_peerleaders_allpeers_4" string => '{ "localhost" }'; "expected_peerleaders_allpeers_5" string => '{ "localhost" }'; "c[$(f)_$(tests)_$(subtests)]" string => "ok_$(f)_$(tests)_$(subtests)"; "cases" slist => getvalues(c); "cs" string => join(",", cases); classes: "ok_$(bad_cases)" not => isvariable("test.actual_$(bad_cases)"); "ok_$(good_cases)" expression => strcmp("$(expected_$(good_cases))", "$(test.actual_$(good_cases))"); methods: "" usebundle => dcs_passif_expected($(cs), "", $(this.promise_filename)), inherit => "true"; reports: EXTRA:: "$(good_cases): as expected, '$(expected_$(good_cases))'" if => "ok_$(good_cases)"; "$(bad_cases): as expected, no variable" if => "ok_$(bad_cases)"; #"test.actual_$(good_cases) = '$(test.actual_$(good_cases))'"; DEBUG:: "$(good_cases): NOT as expected, '$(expected_$(good_cases))' != '$(test.actual_$(good_cases))'" if => "!ok_$(good_cases)"; "$(bad_cases): NOT as expected, has variable '$(test.actual_$(bad_cases))'" if => "!ok_$(bad_cases)"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata.cf.csv.guess0000644000000000000000000000003115010704253026357 0ustar00rootroot00000000000000a,b,c d,"e",f "g,h,i" cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata_yaml.cf.yaml0000644000000000000000000000010115010704253026421 0ustar00rootroot00000000000000--- x: 100 y: - 1 - 2 - a - b - c: 200 300 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/051.cf0000644000000000000000000000162715010704253023214 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,0,0,0,0,100); } ####################################################### bundle agent check { vars: "time" int => "100"; classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/length.cf.expected.json0000644000000000000000000000046415010704253026736 0ustar00rootroot00000000000000{ "empty_list": [], "empty_list_len": "0", "empty_object": { }, "empty_object_len": "0", "inline_array_len": "4", "inline_object_len": "2", "normal_list": [ "b", "c", "a" ], "normal_list_len": "3", "normal_object": { "a": 1, "b": 2 }, "normal_object_len": "2" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/shuffle-exact.cf0000644000000000000000000000267215010704253025446 0ustar00rootroot00000000000000####################################################### # # Test shuffle() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: "test_soft_fail" string => "!linux", meta => { "redmine7950" }; vars: "a" slist => { "a", "b", "c", "d", "e", "f", "g" }; "b" slist => { }; } ####################################################### bundle agent test { meta: # for some reason, shuffle() produces different results on 64bit RHEL 4 # and Debian 4 than everywhere else "test_soft_fail" string => "((centos_4|centos_5|debian_4).64_bit)|windows", meta => { "CFE-2301,ENT-10254" }; vars: "lists" slist => { "a", "b" }; "seeds" slist => { "skruf", "cormorant", "dollhouse" }; "shuffle_$(lists)_$(seeds)" slist => shuffle("init.$(lists)", $(seeds)); "shuffle_inline_$(seeds)" slist => shuffle('["a", "b", "delta", "farmer"]', $(seeds)); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/040.cf0000644000000000000000000000265015010704253023207 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\.",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/wrap_container_fncalls.cf.expected.json0000644000000000000000000000324115010704253032166 0ustar00rootroot00000000000000{ "base_data": { "x": 100, "y": "z" }, "base_list": [ "a", "b", "c", "aaa", "bbb", "ccc" ], "concat_sort_mapdata_mergedata_data": "<<< x=100 >>><<< y=z >>>", "concat_sort_mapdata_mergedata_inline_json": "<<< 0=1 >>><<< 1=2 >>><<< 2=3 >>>", "concat_sort_mapdata_mergedata_slist": "<<< 0=a >>><<< 1=b >>><<< 2=c >>><<< 3=aaa >>><<< 4=bbb >>><<< 5=ccc >>>", "mapdata_spec": "<<< $(this.k)=$(this.v) >>>", "nth_data": "100", "nth_inline_json": "88888888", "nth_list": "aaa", "nth_mapdata_mergedata_slist": "<<< 1=b >>>", "nth_sort_mapdata_mergedata_inline_json": "<<< 0=1 >>>", "reverse_sort_slist": [ "ccc", "c", "bbb", "b", "aaa", "a" ], "sort_mapdata_data": [ "<<< x=100 >>>", "<<< y=z >>>" ], "sort_mapdata_inline_json": [ "<<< 0=1 >>>", "<<< 1=2 >>>", "<<< 2=3 >>>" ], "sort_mapdata_mergedata_data": [ "<<< x=100 >>>", "<<< y=z >>>" ], "sort_mapdata_mergedata_inline_json": [ "<<< 0=1 >>>", "<<< 1=2 >>>", "<<< 2=3 >>>" ], "sort_mapdata_mergedata_slist": [ "<<< 0=a >>>", "<<< 1=b >>>", "<<< 2=c >>>", "<<< 3=aaa >>>", "<<< 4=bbb >>>", "<<< 5=ccc >>>" ], "sort_mapdata_mergedata_sort_slist": [ "<<< 0=a >>>", "<<< 1=aaa >>>", "<<< 2=b >>>", "<<< 3=bbb >>>", "<<< 4=c >>>", "<<< 5=ccc >>>" ], "sort_mapdata_slist": [ "<<< 0=a >>>", "<<< 1=b >>>", "<<< 2=c >>>", "<<< 3=aaa >>>", "<<< 4=bbb >>>", "<<< 5=ccc >>>" ], "sort_mapdata_sort_slist": [ "<<< 0=a >>>", "<<< 1=aaa >>>", "<<< 2=b >>>", "<<< 3=bbb >>>", "<<< 4=c >>>", "<<< 5=ccc >>>" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/008.cf0000644000000000000000000000547015010704253023216 0ustar00rootroot00000000000000# splitstring() body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { vars: # Basic stuff "test1" slist => splitstring("abcXdefXghiXjkl", "X", "100"); "test1_result" string => join(":", "test1"); "test1_expected" string => "abc:def:ghi:jkl"; # Empty last item "test2" slist => splitstring("abcX", "X", "100"); "test2_result" string => join(":", "test2"); "test2_expected" string => "abc:"; # Empty first item "test3" slist => splitstring("Xabc", "X", "100"); "test3_result" string => join(":", "test3"); "test3_expected" string => ":abc"; # Regex "test4" slist => splitstring("abc0123def", "[0-9]", "100"); "test4_result" string => join(":", "test4"); "test4_expected" string => "abc::::def"; # No matches "test5" slist => splitstring("abcYdef", "X", "100"); "test5_result" string => join(":", "test5"); "test5_expected" string => "abcYdef"; # Empty string "test6" slist => splitstring("", "X", "100"); "test6_result" string => join(":", "test6"); "test6_expected" string => "$(const.dollar)(test.test6_result)"; # Limit "test7" slist => splitstring("abcXdefXghiXjklXmno", "X", 3); "test7_result" string => join(":", "test7"); "test7_expected" string => "abc:def:ghi"; } bundle agent check { classes: "ok1" expression => strcmp("$(test.test1_result)", "$(test.test1_expected)"); "ok2" expression => strcmp("$(test.test2_result)", "$(test.test2_expected)"); "ok3" expression => strcmp("$(test.test3_result)", "$(test.test3_expected)"); "ok4" expression => strcmp("$(test.test4_result)", "$(test.test4_expected)"); "ok5" expression => strcmp("$(test.test5_result)", "$(test.test5_expected)"); "ok6" expression => strcmp("$(test.test6_result)", "$(test.test6_expected)"); "ok7" expression => strcmp("$(test.test7_result)", "$(test.test7_expected)"); "ok" and => { "ok1", "ok2", "ok3", "ok4", "ok5", "ok6", "ok7" }; reports: DEBUG.!ok1:: "$(test.test1_result) != $(test.test1_expected)"; DEBUG.!ok2:: "$(test.test2_result) != $(test.test2_expected)"; DEBUG.!ok3:: "$(test.test3_result) != $(test.test3_expected)"; DEBUG.!ok4:: "$(test.test4_result) != $(test.test4_expected)"; DEBUG.!ok5:: "$(test.test5_result) != $(test.test5_expected)"; DEBUG.!ok6:: "$(test.test6_result) != $(test.test6_expected)"; DEBUG.!ok7:: "$(test.test7_result) != $(test.test7_expected)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/read_long_file.cf0000644000000000000000000000165615010704253025642 0ustar00rootroot00000000000000# Test that long file is successfully read by readstringlist() function body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "value" slist => readstringlist("$(this.promise_filename).txt", "", "\n", 100000, 1000000); } bundle agent check { vars: "length" int => length("test.value"); "last" string => nth("test.value", 599); classes: "ok1" expression => strcmp("$(length)", "600"); "ok2" expression => strcmp("$(last)", "line600"); "ok" and => { "ok1", "ok2" }; reports: DEBUG.ok1:: "passed1"; DEBUG.ok2:: "passed2"; DEBUG.!ok1:: "failed1 $(length) != 600"; DEBUG.!ok2:: "failed2 $(last) != line600"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/not.cf0000644000000000000000000000515715010704253023511 0ustar00rootroot00000000000000###################################################### # # Test that not() behaves as expected # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3470" } string => "Test that not() behaves as expected"; classes: "ok" scope => "namespace", and => { # Simple case: "any", not("!any"), "cfengine", not("!cfengine"), # Variable expansion: "$(true_variable)", not("$(false_variable)"), not(not("$(true_variable)")), not(not(not("$(false_variable)"))), # Double expand: not(not("$($(true_variable_name))")), not(not(not("$($(false_variable_name))"))), # Triple expand: not(not("$($($(true_variable_name_name)))")), not(not(not("$($($(false_variable_name_name)))"))), # not() should always return any or !any, # this is important for backwards compatibility: strcmp(not("any"), "!any"), strcmp(not("!any"), "any"), strcmp(not("!cfengine"), "any"), strcmp(not("!(cfengine.!cfengine)"), "!any"), strcmp(not("$(true_variable)"), "!any"), strcmp(not("$(false_variable)"), "any"), }; # In both of these cases we expect the function call (and promise) # to be skipped because of the unresolved variable: # This tests function/promise skipping because of unresolved variables, # but also that there is no syntax / type error, when the unresolved # function call stays in the and list forever (Never resolved). "fail_one" and => { "any", not("$(unresolved_var)"), }; "fail_two" and => { "any", not(not("$(unresolved_var)")), }; "fail" scope => "namespace", expression => "fail_one|fail_two"; vars: "false_variable" string => "cfengine.(!cfengine)"; "true_variable" string => "cfengine|(!cfengine)"; "false_variable_name" string => "false_variable"; "true_variable_name" string => "true_variable"; "false_variable_name_name" string => "false_variable_name"; "true_variable_name_name" string => "true_variable_name"; } ####################################################### bundle agent check { reports: ok.(!fail):: "$(this.promise_filename) Pass"; (!ok)|fail:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_array_slist.cf0000644000000000000000000000202515010704253027313 0ustar00rootroot00000000000000####################################################### # # Test getvalues() # ####################################################### # If we run getvalues on a classic array index that contains an slist we should # end up with a copy of that slist. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "array[slist]" slist => { "scrumdiddlyumptious" }; "values" slist => getvalues("array[slist]"); } ####################################################### bundle agent check { vars: "expected" slist => { "scrumdiddlyumptious" }; "diff" slist => difference( expected, "test.values" ); classes: "_pass" expression => strcmp( length( diff ), 0 ); methods: _pass:: "pass" usebundle => dcs_pass("$(this.promise_filename)"); !_pass:: "pass" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/shuffle.cf0000644000000000000000000000264715010704253024346 0ustar00rootroot00000000000000####################################################### # # Test shuffle() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "a" slist => { "a", "b", "c", "d", "e", "f", "g" }; "b" slist => { }; } ####################################################### bundle agent test { vars: "sa" slist => shuffle("init.a", "skruf"); "sb" slist => shuffle("init.b", "skruf"); } ####################################################### bundle agent check { vars: "asorted" slist => sort("test.sa", "lex"); "jaorig" string => join(",", "init.a"); "jasorted" string => join(",", "asorted"); "ja" string => join(",", "test.sa"); "jb" string => join(",", "test.sb"); classes: "a_not_changed" expression => strcmp($(jaorig), $(ja)); "a_is_permutation" expression => strcmp($(jasorted), $(jaorig)); "ok_a" and => { "!a_not_changed", "a_is_permutation" }; "ok_b" expression => strcmp("", $(jb)); "ok" and => { "ok_a", "ok_b" }; reports: DEBUG:: "a '$(jaorig)' <> sort('$(ja)')"; "b '$(jb)' <> ''"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/variablesmatching.cf.expected.json0000644000000000000000000000202215010704253031130 0ustar00rootroot00000000000000{ "fullvars": { "default:init.test_b37ce1b03955522848f0a82d0b2b2e21_1": [ "a", "b" ], "default:init.test_b37ce1b03955522848f0a82d0b2b2e21_2": { "a": "b" }, "default:init.test_b37ce1b03955522848f0a82d0b2b2e21_3": "mydata" }, "tag_match": [ "default:init.test_variable_with_weird_tag" ], "tag_match_data": { "default:init.test_variable_with_weird_tag": "some_data" }, "tag_no_match": [], "tag_no_match_data": { }, "vars": [ "default:init.test_fbeae67f3e347b5e0032302200141131_1", "default:init.test_fbeae67f3e347b5e0032302200141131_2", "default:init.test_fbeae67f3e347b5e0032302200141131" ], "x_fullvars": { "default:init.test_b37ce1b03955522848f0a82d0b2b2e21_1": [ "a", "b" ], "default:init.test_b37ce1b03955522848f0a82d0b2b2e21_2": { "a": "b" } }, "x_vars": [ "default:init.test_fbeae67f3e347b5e0032302200141131_1", "default:init.test_fbeae67f3e347b5e0032302200141131" ], "z_fullvars": { }, "z_vars": [] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/010.cf0000644000000000000000000000164115010704253023203 0ustar00rootroot00000000000000####################################################### # # Test hostsseen() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "hosts" slist => hostsseen("inf", "lastseen", "name"); } ####################################################### bundle agent check { vars: "hosts" slist => { @{test.hosts} }; classes: "ok" expression => "any"; # XXX # I don't know how to test hostsseen! reports: DEBUG:: "$(hosts)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/regline.cf0000644000000000000000000000301115010704253024321 0ustar00rootroot00000000000000####################################################### # # Test filter() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "results" slist => { "five trailing spaces ", "no trailing spaces", }; files: "$(G.testfile)" create => "true", edit_defaults => init_empty, edit_line => init_insert; } body edit_defaults init_empty { empty_file_before_editing => "true"; edit_backup => "false"; } bundle edit_line init_insert { insert_lines: "$(init.results)"; } bundle agent test { classes: "matched1" expression => regline("five trailing spaces ", $(G.testfile)), scope => "namespace"; "matched2" expression => regline("five trailing spaces ", $(G.testfile)), scope => "namespace"; reports: DEBUG.matched1:: "Line matched1 matched"; DEBUG.!matched1:: "Line matched1 did not match"; DEBUG.matched2:: "Line matched2 matched"; DEBUG.!matched2:: "Line matched2 did not match"; } bundle agent check { classes: "ok" expression => "matched1.!matched2"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_flattens-list-elements.cf0000644000000000000000000000304615010704253031366 0ustar00rootroot00000000000000####################################################### # # Test getvalues(), to be sure that If the array contains list elements on the # right hand side then all of the list elements are flattened into a single list # to make the return value a list. (Bug #1271) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "results" slist => { "one", "two", "red", "blue" }; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "$(init.results)"; } ####################################################### bundle agent test { vars: "sea[fish]" slist => { "one", "two" }; "sea[shark]" slist => { "red", "blue" }; secondpass:: "vals" slist => getvalues("sea"); classes: "secondpass" expression => "any"; files: secondpass:: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/long_string_from_module.cf0000644000000000000000000000650615010704253027625 0ustar00rootroot00000000000000####################################################### # # Test that we don't crash when reading in large strings from a module # Redmine:3957 (https://cfengine.com/dev/issues/3957) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).module" create => "true", perms => m("700"), edit_defaults => empty, edit_line => seed_module; } ####################################################### bundle agent test { commands: "$(G.testfile).module" module => "true"; } ####################################################### bundle agent check { classes: "ok" expression => "any", comment => "If we made it to here, we didn't crash"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } bundle edit_line seed_module { insert_lines: "#!/bin/bash"; "echo '@keys= { \"ssh-dss YavBsyK3sHDac4Gj4nDbVH9E7OfRPi16DADNOWGKEjWiBB0cCe0UY6xxEgcYuwOOl8HUGqqzLOByvUbo1hENDQldKFt8N7WIb2E9gXFtGm0Sf0NlYARALj1nhLju9hodpGxkr4vKioW1fZQBmBqsI7Ky8ZhzU5p4CAm4uCbxAZuiIhDTAcxj7RlDy3fe9WBw7v0cSIbu8E3zEbPn0VQjTduLCJtFOb5LvUxpxUsHMhHu0xS8DvXIwf7l83cQ0XZtwyIgbF3ZxjIZaPyYhKZRAV1qCze4BlcOerJeVYOiKjpXJlOoBprxy2SfEYVS4Khun0efkmsmBAfllKUUNCqsK9j6oWo7BvNbXqzkl2ULJd6h0LNy9jW8IXnnrfWknLGa7lksVmL3afSAufDAb7yRESaUP5KmcD3ghP3Nvu7fy9hz7nIAPgj2dQOwnFRbkv9Svoi9YmCtvBWYAcwIUVNJBmwXe5j5xJyt5vOyRSI2ooJ9mk69UOCsIM8PEnEXwtHcsg9fDjfu9ChFY2HWZPWeNXH05SATnSyLgclQsZcazhQXPoxZbcqR80mfuRX9ymEzNwZJ1jJUERnj9PZkSInu6mFVRjTaQjg8yvqMGRxWknP8aURCDh5rr4Na23jULVVI66heWOi7nzLqBg5U8GsbLsocM8zBam8bhXfU0KvpBo5wlUtHnDWHoMlS3ktr25ldrp3zLuywhHe5vGUbg2E0gr4xB3oPAyaDa3MGQiVXPfngu5CJhwIXmeN5JtIBA0S46ihg7lQ6IU8kAaRHwhWh3TokoNFOYE8R5i24gpYNF8dgCRGqSZIT5V7wuR3qG1Wau963ILuX8EFOSu7xDc5qnGTem3FwICTpSdnZNqpzRt4Ipqsn4Pa2tFFpHlzDwKFRPS7r8v4QX7acqdTSCUOuZ68GwDRlvHIz5mHUf1XLY3FH2InuWFsonJAZwmEbX5evWXFgyJHFlplQcGJvyNdL0T6oBmbG3ssSMoRnqnsk8XjGWtUyvYoQmOY8HWlMhf4V3v78C4k4TnCbN4LmnDYaDcnXMejrUMYDk6QwW3fdTF5ZyjJMy4ANu2fJfKysZMc1Cc== root@host1\", \"ssh-dss a58AZSxQlmcq33EBCW1GuhpkYCgUfr7o5A1arQZ2dr8I4kldCF76mpl6o2CFthZs4YUU8LewbIDDPqjhS2WwafTXeMEvPMtmLufk6E5njNy2WQtAnmGc9R21qIteTgikY9ubRCM3hlhzJ1wGSKCsE5oBHDQC0thk1ljJGHzsEl0AuVClkUq3yz4eWAsiRdbD9QY7ddD6zA61aHomuczKU5F0VvyO8gRQmWV7b6lysoUFcMgCPVf3UaDdg7L7vvBVkQN2vGCh9CCJz5OkBShlZVNaAXd5TkKJNmsTuBDscPyxeCBAk8sai69f1NNtTeAyWTtSu1KiqTDvD9aal93MhpZnPdOZzNr7etK4C7HuPD0uFjdvKZy1H55rpwNHnJ4GojqiNG1VvN5bGLa3sSLiKOngtMBCokdtHpZn2eHD7oLUROTIG3ZXqFGGvfKEP5zlpvJz3392n4PDQ7EKuNFPhyNQpVXEIAQEDcmeWMopVTGezLoFJG01hKMPxs5QWF7qetVLi1pCjmlUpqgE8c81WGxvMe7ooMtQbeVNulX3qBC3rZhYKtk0R5AA8JxmxHSLYlLFbtnR1PA97hnRvnvlfk92i7WL1hjJsMl29LOrubi554Dr9N2uVUrCFcPZMK45PY0TiRH82AKFmkM8mbM0rndJxoJobZsqRAGHVIkcS53hxMT69liRxlCyubwcxgDaqmeQnJU2Ug0YyFs1uxt4NT9laJ0CO2IxhkbmGeDGw1FJqKyc8Haov263cFMcB97I3gyNHccsAynQnxpMS1ltTFXalghuochdue4unbq0Ty2PfS4jPMkavBlMYN8UZdnyZHuUhycwBJri1Grv5kf2SP00P6NQhuB8kwjqoTG8ay5fKWvhDrVetd7tPuj4dMouHuDeaLJInc7Cz0S5tQOuMfRhpPqk1E8A0YnuNCyPDNuW75rkXZkxP9cYSVWeDa1wgOyNLZDTzYts82qiu9kxLbZ184jowJ8rru4UB20JRtoehnD2nGU1NfegD1qOBgQHtDuB18xggfvOgvUNXBrQpICSz0JqszpftAgV5TJq1FjOdjUo1kOCFuqqi6C4S0Siho== root@host2\" }'"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/ifelse_isvariable.cf.expected.json0000644000000000000000000000012215010704253031114 0ustar00rootroot00000000000000{ "use_passwd_file": "/tmp/custom_passwd", "use_shadow_file": "/etc/shadow" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.tail20.txt0000644000000000000000000000002515010704253027005 0ustar00rootroot000000000000000123456789abcdefghij cfengine-3.24.2/tests/acceptance/01_vars/02_functions/dirname.cf0000644000000000000000000001272315010704253024325 0ustar00rootroot00000000000000####################################################### # # Test dirname() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: # The tests starting with template will be tested with both types of # directory separators on Windows. "template_input[root]" string => "/"; "template_expected[root]" string => "/"; "template_input[simple]" string => "/foo/bar"; "template_expected[simple]" string => "/foo"; "template_input[slash]" string => "/foo/bar/"; "template_expected[slash]" string => "/foo"; "template_input[sub]" string => "/foo"; "template_expected[sub]" string => "/"; "template_input[subslash]" string => "/foo/"; "template_expected[subslash]" string => "/"; "template_input[dot]" string => "/foo/."; "template_expected[dot]" string => "/foo"; "template_input[dot_subslash]" string => "/foo/./"; "template_expected[dot_subslash]" string => "/foo"; "template_input[multi]" string => "/foo/bar/baz"; "template_expected[multi]" string => "/foo/bar"; "template_input[multislash]" string => "/foo/bar/baz/"; "template_expected[multislash]" string => "/foo/bar"; "template_input[more]" string => "/a/b/c/d/e/f/g/h/i"; "template_expected[more]" string => "/a/b/c/d/e/f/g/h"; "template_input[multislash]" string => "/a///b////c///"; "template_expected[multislash]" string => "/a/b"; # Note: no template, because backslashes will be interpreted as UNC path on Windows. "input[multislash_start]" string => "//a///b////c///"; "expected[multislash_start]" string => "/a/b"; "template_input[rel_one]" string => "foo"; "template_expected[rel_one]" string => "."; "template_input[rel_more]" string => "foo/bar"; "template_expected[rel_more]" string => "foo"; "template_input[rel_one_subslash]" string => "foo/"; "template_expected[rel_one_subslash]" string => "."; "template_input[rel_more_subslash]" string => "foo/bar/"; "template_expected[rel_more_subslash]" string => "foo"; "template_input[rel_dot]" string => "foo/."; "template_expected[rel_dot]" string => "foo"; "template_input[rel_only_dot]" string => "./"; "template_expected[rel_only_dot]" string => "."; "template_input[rel_multislash]" string => "a///b////c///"; "template_expected[rel_multislash]" string => "a/b"; "template_input[noop]" string => ""; "template_expected[noop]" string => ""; "template_keys" slist => getindices("template_input"); windows:: "template_input[full_root]" string => "C:/"; "template_expected[full_root]" string => "C:/"; "template_input[full_root_file]" string => "C:/foo"; "template_expected[full_root_file]" string => "C:/"; "template_input[full_root_file_subslash]" string => "C:/foo/"; "template_expected[full_root_file_subslash]" string => "C:/"; "template_input[full_file]" string => "C:/foo/bar"; "template_expected[full_file]" string => "C:/foo"; "template_input[full_file_subslash]" string => "C:/foo/bar/"; "template_expected[full_file_subslash]" string => "C:/foo"; "template_input[dir]" string => "C:foo"; "template_expected[dir]" string => "C:."; "template_input[two_dirs]" string => "C:foo/bar"; "template_expected[two_dirs]" string => "C:foo"; "template_input[dir_subslash]" string => "C:foo/"; "template_expected[dir_subslash]" string => "C:."; "template_input[two_dirs_subslash]" string => "C:foo/bar/"; "template_expected[two_dirs_subslash]" string => "C:foo"; # UNC paths don't have forward slash equivalents. "input[native_unc_one]" string => "\\\\foo"; "expected[native_unc_one]" string => "\\\\"; "input[native_unc_two]" string => "\\\\foo\\bar"; "expected[native_unc_two]" string => "\\\\foo"; "input[native_unc_three]" string => "\\\\foo\\bar\\charlie\\"; "expected[native_unc_three]" string => "\\\\foo\\bar"; "input[unix_$(template_keys)]" string => "$(template_input[$(template_keys)])"; "input[native_$(template_keys)]" string => translatepath("$(template_input[$(template_keys)])"); "expected[unix_$(template_keys)]" string => "$(template_expected[$(template_keys)])"; "expected[native_$(template_keys)]" string => translatepath("$(template_expected[$(template_keys)])"); !windows:: "input[native_$(template_keys)]" string => "$(template_input[$(template_keys)])"; "expected[native_$(template_keys)]" string => "$(template_expected[$(template_keys)])"; any:: "keys" slist => getindices("input"); "actual[$(keys)]" string => dirname("$(input[$(keys)])"); } ####################################################### bundle agent check { vars: "keys" slist => { @(test.keys) }; classes: "failed_cmp_$(keys)" not => strcmp(dirname("$(test.input[$(keys)])"), "$(test.expected[$(keys)])"); "ok" not => classmatch("failed_cmp_.*"); reports: DEBUG:: "'dirname($(test.input[$(keys)]))' = '$(test.actual[$(keys)])' != '$(test.expected[$(keys)])'" if => "failed_cmp_$(keys)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/cache_name.cf0000644000000000000000000000220215010704253024740 0ustar00rootroot00000000000000####################################################### # # Test that the function result cache checks function name # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "agent_regex" string => ".*cf-agent.*"; } ####################################################### bundle common test { meta: "description" -> { "CFE-4244" } string => "Test that the function result cache checks function name"; vars: "res1" data => findprocesses("${init.agent_regex}"); classes: # must not reuse result from previous line # is reused, produces a type error "_pass" expression => processexists("${init.agent_regex}"); } ####################################################### bundle agent check { methods: _pass:: "pass" usebundle => dcs_pass("$(this.promise_filename)"); !_pass:: "pass" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.expected.json0000644000000000000000000075730015010704253027664 0ustar00rootroot00000000000000{ "data[q1]": "this is the Question", "data[q1_string_downcase]": "this is the question", "data[q1_string_head_-10240]": "", "data[q1_string_head_-10]": "this is th", "data[q1_string_head_-1]": "this is the Questio", "data[q1_string_head_-20]": "", "data[q1_string_head_-26]": "", "data[q1_string_head_-27]": "", "data[q1_string_head_-28]": "", "data[q1_string_head_-2]": "this is the Questi", "data[q1_string_head_-5]": "this is the Que", "data[q1_string_head_0]": "", "data[q1_string_head_10240]": "this is the Question", "data[q1_string_head_10]": "this is th", "data[q1_string_head_1]": "t", "data[q1_string_head_20]": "this is the Question", "data[q1_string_head_26]": "this is the Question", "data[q1_string_head_27]": "this is the Question", "data[q1_string_head_28]": "this is the Question", "data[q1_string_head_2]": "th", "data[q1_string_head_5]": "this ", "data[q1_string_head_inline_neg]": "this is the Quest", "data[q1_string_head_inline_pos]": "thi", "data[q1_string_length]": "20", "data[q1_string_reverse]": "noitseuQ eht si siht", "data[q1_string_tail_-10240]": "", "data[q1_string_tail_-10]": "e Question", "data[q1_string_tail_-1]": "his is the Question", "data[q1_string_tail_-20]": "", "data[q1_string_tail_-26]": "", "data[q1_string_tail_-27]": "", "data[q1_string_tail_-28]": "", "data[q1_string_tail_-2]": "is is the Question", "data[q1_string_tail_-5]": "is the Question", "data[q1_string_tail_0]": "", "data[q1_string_tail_10240]": "this is the Question", "data[q1_string_tail_10]": "e Question", "data[q1_string_tail_1]": "n", "data[q1_string_tail_20]": "this is the Question", "data[q1_string_tail_26]": "this is the Question", "data[q1_string_tail_27]": "this is the Question", "data[q1_string_tail_28]": "this is the Question", "data[q1_string_tail_2]": "on", "data[q1_string_tail_5]": "stion", "data[q1_string_tail_inline_neg]": "s is the Question", "data[q1_string_tail_inline_pos]": "ion", "data[q1_string_upcase]": "THIS IS THE QUESTION", "data[q2]": "", "data[q2_string_downcase]": "", "data[q2_string_head_-10240]": "", "data[q2_string_head_-10]": "", "data[q2_string_head_-1]": "", "data[q2_string_head_-20]": "", "data[q2_string_head_-26]": "", "data[q2_string_head_-27]": "", "data[q2_string_head_-28]": "", "data[q2_string_head_-2]": "", "data[q2_string_head_-5]": "", "data[q2_string_head_0]": "", "data[q2_string_head_10240]": "", "data[q2_string_head_10]": "", "data[q2_string_head_1]": "", "data[q2_string_head_20]": "", "data[q2_string_head_26]": "", "data[q2_string_head_27]": "", "data[q2_string_head_28]": "", "data[q2_string_head_2]": "", "data[q2_string_head_5]": "", "data[q2_string_head_inline_neg]": "", "data[q2_string_head_inline_pos]": "", "data[q2_string_length]": "0", "data[q2_string_reverse]": "", "data[q2_string_tail_-10240]": "", "data[q2_string_tail_-10]": "", "data[q2_string_tail_-1]": "", "data[q2_string_tail_-20]": "", "data[q2_string_tail_-26]": "", "data[q2_string_tail_-27]": "", "data[q2_string_tail_-28]": "", "data[q2_string_tail_-2]": "", "data[q2_string_tail_-5]": "", "data[q2_string_tail_0]": "", "data[q2_string_tail_10240]": "", "data[q2_string_tail_10]": "", "data[q2_string_tail_1]": "", "data[q2_string_tail_20]": "", "data[q2_string_tail_26]": "", "data[q2_string_tail_27]": "", "data[q2_string_tail_28]": "", "data[q2_string_tail_2]": "", "data[q2_string_tail_5]": "", "data[q2_string_tail_inline_neg]": "", "data[q2_string_tail_inline_pos]": "", "data[q2_string_upcase]": "", "data[q3]": "some text is not \t simple\n\n", "data[q3_string_downcase]": "some text is not \t simple\n\n", "data[q3_string_head_-10240]": "", "data[q3_string_head_-10]": "some text is not ", "data[q3_string_head_-1]": "some text is not \t simple\n", "data[q3_string_head_-20]": "some te", "data[q3_string_head_-26]": "s", "data[q3_string_head_-27]": "", "data[q3_string_head_-28]": "", "data[q3_string_head_-2]": "some text is not \t simple", "data[q3_string_head_-5]": "some text is not \t sim", "data[q3_string_head_0]": "", "data[q3_string_head_10240]": "some text is not \t simple\n\n", "data[q3_string_head_10]": "some text ", "data[q3_string_head_1]": "s", "data[q3_string_head_20]": "some text is not \t s", "data[q3_string_head_26]": "some text is not \t simple\n", "data[q3_string_head_27]": "some text is not \t simple\n\n", "data[q3_string_head_28]": "some text is not \t simple\n\n", "data[q3_string_head_2]": "so", "data[q3_string_head_5]": "some ", "data[q3_string_head_inline_neg]": "some text is not \t simpl", "data[q3_string_head_inline_pos]": "som", "data[q3_string_length]": "27", "data[q3_string_reverse]": "\n\nelpmis \t ton si txet emos", "data[q3_string_tail_-10240]": "", "data[q3_string_tail_-10]": "is not \t simple\n\n", "data[q3_string_tail_-1]": "ome text is not \t simple\n\n", "data[q3_string_tail_-20]": "imple\n\n", "data[q3_string_tail_-26]": "\n", "data[q3_string_tail_-27]": "", "data[q3_string_tail_-28]": "", "data[q3_string_tail_-2]": "me text is not \t simple\n\n", "data[q3_string_tail_-5]": "text is not \t simple\n\n", "data[q3_string_tail_0]": "", "data[q3_string_tail_10240]": "some text is not \t simple\n\n", "data[q3_string_tail_10]": "\t simple\n\n", "data[q3_string_tail_1]": "\n", "data[q3_string_tail_20]": "xt is not \t simple\n\n", "data[q3_string_tail_26]": "ome text is not \t simple\n\n", "data[q3_string_tail_27]": "some text is not \t simple\n\n", "data[q3_string_tail_28]": "some text is not \t simple\n\n", "data[q3_string_tail_2]": "\n\n", "data[q3_string_tail_5]": "ple\n\n", "data[q3_string_tail_inline_neg]": "e text is not \t simple\n\n", "data[q3_string_tail_inline_pos]": "e\n\n", "data[q3_string_upcase]": "SOME TEXT IS NOT \t SIMPLE\n\n", "data[q4]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_downcase]": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghij", "data[q4_string_head_-10240]": "", "data[q4_string_head_-10]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", "data[q4_string_head_-1]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghi", "data[q4_string_head_-20]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "data[q4_string_head_-26]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST", "data[q4_string_head_-27]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS", "data[q4_string_head_-28]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR", "data[q4_string_head_-2]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefgh", "data[q4_string_head_-5]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcde", "data[q4_string_head_0]": "", "data[q4_string_head_10240]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_head_10]": "abcdefghij", "data[q4_string_head_1]": "a", "data[q4_string_head_20]": "abcdefghijklmnopqrst", "data[q4_string_head_26]": "abcdefghijklmnopqrstuvwxyz", "data[q4_string_head_27]": "abcdefghijklmnopqrstuvwxyzA", "data[q4_string_head_28]": "abcdefghijklmnopqrstuvwxyzAB", "data[q4_string_head_2]": "ab", "data[q4_string_head_5]": "abcde", "data[q4_string_head_inline_neg]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefg", "data[q4_string_head_inline_pos]": "abc", "data[q4_string_length]": "10240", "data[q4_string_reverse]": "jihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba", "data[q4_string_tail_-10240]": "", "data[q4_string_tail_-10]": "klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_-1]": "bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_-20]": "uvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_-26]": "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_-27]": "BCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_-28]": "CDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_-2]": "cdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_-5]": "fghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_0]": "", "data[q4_string_tail_10240]": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_10]": "abcdefghij", "data[q4_string_tail_1]": "j", "data[q4_string_tail_20]": "0123456789abcdefghij", "data[q4_string_tail_26]": "UVWXYZ0123456789abcdefghij", "data[q4_string_tail_27]": "TUVWXYZ0123456789abcdefghij", "data[q4_string_tail_28]": "STUVWXYZ0123456789abcdefghij", "data[q4_string_tail_2]": "ij", "data[q4_string_tail_5]": "fghij", "data[q4_string_tail_inline_neg]": "defghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij", "data[q4_string_tail_inline_pos]": "hij", "data[q4_string_upcase]": "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJ", "fn1": [ "string_head", "string_tail" ], "offsets": [ "-1", "-2", "-5", "-10", "-20", "-26", "-27", "-28", "-10240", "0", "1", "2", "5", "10", "20", "26", "27", "28", "10240" ], "tests": [ "q1", "q2", "q3", "q4" ] } getindices_returns_expected_list_from_datacontainer.cf.expected.json0000644000000000000000000000006015010704253040121 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions{ "values_data": [ "one", "two" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/datastate.cf0000644000000000000000000000411415010704253024653 0ustar00rootroot00000000000000# Test that the datastate() function gives good data body common control { inputs => { "../../default.cf.sub", "datastate.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { classes: "a" expression => "any", scope => "namespace"; "b" expression => "any"; "c" expression => "!any"; vars: "x" string => "1"; "y" data => parsejson('{"ykey":["yvalue1", "yvalue2"]}'); "z" slist => { "z1", "z2", "z3" }; } bundle agent test { vars: "state" data => datastate(); } bundle agent check { vars: "init_state_str" string => format("%S", "test.state[vars][init]"); "ns_state_str" string => format("%S", "test.state[vars][visible_namespace:included]"); "known_classes" slist => getindices("test.state[classes]"); "printed_classes" string => format("%S", known_classes); "init_expected" string => '{"x":"1","y":{"ykey":["yvalue1","yvalue2"]},"z":["z1","z2","z3"]}'; "ns_expected" string => '{"i":"1","j":"two","k":["k2","everest"],"l":[1,"l","|"]}'; classes: "init_ok" expression => strcmp($(init_state_str), $(init_expected)); "ns_ok" expression => strcmp($(ns_state_str), $(ns_expected)); "classes_ok" and => { some("cfengine_3", known_classes), some("a", known_classes), some("visible_namespace:foo", known_classes) }; "ok" and => { "init_ok", "ns_ok", "classes_ok" }; reports: DEBUG.!ns_ok:: "visible_namespace:included data state is $(ns_state_str)"; "expected visible_namespace:included state is $(ns_expected)"; "expected state != visible_namespace:included data state"; DEBUG.!init_ok:: "init data state is $(init_state_str)"; "expected init state is $(init_expected)"; "expected init state != init data state"; DEBUG.!classes_ok:: "expected classes a, visible_namespace:foo, and cfengine_3 were not in $(printed_classes)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/split.cf0000644000000000000000000000241415010704253024035 0ustar00rootroot00000000000000####################################################### # # Test string_split() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ############################################### bundle agent init { vars: "states" slist => { "actual", "expected" }; "expected" string => "one two:three"; files: "$(G.testfile).expected" create => "true", edit_line => ensure_lines("$(init.expected)"), edit_defaults => empty; } ####################################################### bundle agent test { vars: "result" slist => string_split("one:two:three", ":", "2"); files: "$(G.testfile).actual" create => "true", edit_defaults => empty, edit_line => ensure_lines(@(result)); } ####################################################### bundle edit_line ensure_lines(list) { insert_lines: "$(list)"; } bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } variable_references_from_function_that_never_succeeds.cf0000644000000000000000000000261115010704253035635 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test that FnFailure results in unresolved references # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle common test { classes: "resolved_found" expression => returnszero("$(command) resolved_a557d39e04d666075754b8f78ea17fbc175925d5 2>&1", "useshell"); "unresolved_found" expression => returnszero("$(command) unresolved_76201d0eaac49a884308358aa487147b4db70e8a 2>&1", "useshell"); vars: "command" string => "$(sys.cf_agent) -K -f $(this.promise_filename).sub | $(G.grep) MARKER | $(G.grep)"; } ####################################################### bundle agent check { classes: "ok" and => { "!resolved_found", "unresolved_found" }; reports: DEBUG.!resolved_found:: "Resolved variable not found"; DEBUG.resolved_found:: "Resolved variable found?!?!"; DEBUG.unresolved_found:: "Unresolved variable found"; DEBUG.!unresolved_found:: "Unresolved variable not found?!?!"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getindices_returns_empty_list_if_array_index_has_no_key_values.cf0000644000000000000000000000326315010704253037620 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test that getindices() returns an empty list if used on # an array index that has no key values. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data[foo]" slist => { "alpha", "bravo" }; "data[bar]" string => "zulu"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "!any", meta => { "redmine7116" }; vars: "values_data" slist => getindices("init.data[bar]"); } ####################################################### bundle agent check { vars: "expected_elements" slist => { }; "diff1" slist => difference( "test.values_data", expected_elements ); "diff2" slist => difference( expected_elements, "test.values_data"); "len_values_data" int => length( "test.values_data" ); "len_diff1" int => length(diff1); "len_diff2" int => length(diff2); classes: "ok" expression => strcmp( $(len_diff1), $(len_diff2) ); reports: DEBUG:: "DEBUG: data value: '$(test.values_data)'"; "DEBUG: expected value: '$(expected_elements)'"; "DEBUG: length of test.values_data: '$(len_values_data)'"; "DEBUG: found '$(diff1)' in test.values_data, but not in expected_elements"; "DEBUG: found '$(diff2)' in expected_elements, but not in test.values_data"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mapdata.cf.expected.json0000644000000000000000000002643015010704253027065 0ustar00rootroot00000000000000{ "X": [ "1", "2", "3", "4", "5", "6" ], "Y": [ "1", "2", "3", "4" ], "jsonspec1": "{ \"key\": \"$(this.k)\", \"value\": \"$(this.v)\"", "jsonspec2": "{ \"key\": \"$(this.k)\", \"value\": \"$(this.v)\" }", "jsonspec3": "[ \"$(this.k)\", \"$(this.v)\" ]", "jsonspec4": "{ \"key\": \"$(this.k)\", \"key2\": \"$(this.k[1])\", \"value\": \"$(this.v)\" }", "justastring": "me", "load1": [ 1, 2, 3 ], "load2": [ "eleme\"nt1", "element2", "element3" ], "load3": { "x"x": "y\"y" }, "load4": [], "load5[anotherkey]": "anothervalue", "load5[lastkey!]": [ "o\"ne", "two", "three" ], "load5[mykey]": [ "myvalue" ], "load6": { "a": { "b": "c" } }, "mapdata_canonify_1_1": [ "key___0", "key___1", "key___2" ], "mapdata_canonify_1_2": [ "key___0__value___1", "key___1__value___2", "key___2__value___3" ], "mapdata_canonify_1_3": [ "key___0__key2_____this_k_1____value___1", "key___1__key2_____this_k_1____value___2", "key___2__key2_____this_k_1____value___3" ], "mapdata_canonify_1_4": [ "xvalue_should_be_0value", "xvalue_should_be_1value", "xvalue_should_be_2value" ], "mapdata_canonify_2_1": [ "key___0", "key___1", "key___2" ], "mapdata_canonify_2_2": [ "key___0__value___eleme_nt1", "key___1__value___element2", "key___2__value___element3" ], "mapdata_canonify_2_3": [ "key___0__key2_____this_k_1____value___eleme_nt1", "key___1__key2_____this_k_1____value___element2", "key___2__key2_____this_k_1____value___element3" ], "mapdata_canonify_2_4": [ "xvalue_should_be_0value", "xvalue_should_be_1value", "xvalue_should_be_2value" ], "mapdata_canonify_3_1": [ "key___x_x" ], "mapdata_canonify_3_2": [ "key___x_x__value___y_y" ], "mapdata_canonify_3_3": [ "key___x_x__key2_____this_k_1____value___y_y" ], "mapdata_canonify_3_4": [ "xvalue_should_be_xxvalue" ], "mapdata_canonify_4_1": [], "mapdata_canonify_4_2": [], "mapdata_canonify_4_3": [], "mapdata_canonify_4_4": [], "mapdata_canonify_5_1": [ "key___anotherkey", "key___lastkey_", "key___mykey" ], "mapdata_canonify_5_2": [ "key___anotherkey__value___anothervalue", "key___lastkey___value___o_ne", "key___lastkey___value___two", "key___lastkey___value___three", "key___mykey__value___myvalue" ], "mapdata_canonify_5_3": [ "key___anotherkey__key2_____this_k_1____value___anothervalue", "key___lastkey___key2_____this_k_1____value___o_ne", "key___lastkey___key2_____this_k_1____value___two", "key___lastkey___key2_____this_k_1____value___three", "key___mykey__key2_____this_k_1____value___myvalue" ], "mapdata_canonify_5_4": [ "xvalue_should_be_anothervalue", "xvalue_should_be_lastvalue", "xvalue_should_be_myvalue" ], "mapdata_canonify_6_1": [ "key___a" ], "mapdata_canonify_6_2": [ "key___a__value___c" ], "mapdata_canonify_6_3": [ "key___a__key2___b__value___c" ], "mapdata_canonify_6_4": [ "xvalue_should_be_avalue" ], "mapdata_canonify_eval_1_1": [ "key___0", "key___1", "key___2" ], "mapdata_canonify_eval_1_2": [ "key___0__value___1", "key___1__value___2", "key___2__value___3" ], "mapdata_canonify_eval_1_3": [ "key___0__key2_____this_k_1____value___1", "key___1__key2_____this_k_1____value___2", "key___2__key2_____this_k_1____value___3" ], "mapdata_canonify_eval_1_4": [ "xvalue_should_be_0value", "xvalue_should_be_1value", "xvalue_should_be_2value" ], "mapdata_canonify_eval_2_1": [ "key___0", "key___1", "key___2" ], "mapdata_canonify_eval_2_2": [ "key___0__value___eleme_nt1", "key___1__value___element2", "key___2__value___element3" ], "mapdata_canonify_eval_2_3": [ "key___0__key2_____this_k_1____value___eleme_nt1", "key___1__key2_____this_k_1____value___element2", "key___2__key2_____this_k_1____value___element3" ], "mapdata_canonify_eval_2_4": [ "xvalue_should_be_0value", "xvalue_should_be_1value", "xvalue_should_be_2value" ], "mapdata_canonify_eval_3_1": [ "key___x_x" ], "mapdata_canonify_eval_3_2": [ "key___x_x__value___y_y" ], "mapdata_canonify_eval_3_3": [ "key___x_x__key2_____this_k_1____value___y_y" ], "mapdata_canonify_eval_3_4": [ "xvalue_should_be_xxvalue" ], "mapdata_canonify_eval_4_1": [], "mapdata_canonify_eval_4_2": [], "mapdata_canonify_eval_4_3": [], "mapdata_canonify_eval_4_4": [], "mapdata_canonify_eval_5_1": [ "key___anotherkey", "key___lastkey_", "key___mykey" ], "mapdata_canonify_eval_5_2": [ "key___anotherkey__value___anothervalue", "key___lastkey___value___o_ne", "key___lastkey___value___two", "key___lastkey___value___three", "key___mykey__value___myvalue" ], "mapdata_canonify_eval_5_3": [ "key___anotherkey__key2_____this_k_1____value___anothervalue", "key___lastkey___key2_____this_k_1____value___o_ne", "key___lastkey___key2_____this_k_1____value___two", "key___lastkey___key2_____this_k_1____value___three", "key___mykey__key2_____this_k_1____value___myvalue" ], "mapdata_canonify_eval_5_4": [ "xvalue_should_be_anothervalue", "xvalue_should_be_lastvalue", "xvalue_should_be_myvalue" ], "mapdata_canonify_eval_6_1": [ "key___a" ], "mapdata_canonify_eval_6_2": [ "key___a__value___c" ], "mapdata_canonify_eval_6_3": [ "key___a__key2___b__value___c" ], "mapdata_canonify_eval_6_4": [ "xvalue_should_be_avalue" ], "mapdata_json_1_1": [], "mapdata_json_1_2": [ { "key": "0", "value": "1" }, { "key": "1", "value": "2" }, { "key": "2", "value": "3" } ], "mapdata_json_1_3": [ [ "0", "1" ], [ "1", "2" ], [ "2", "3" ] ], "mapdata_json_1_4": [ { "key": "0", "key2": "$(this.k[1])", "value": "1" }, { "key": "1", "key2": "$(this.k[1])", "value": "2" }, { "key": "2", "key2": "$(this.k[1])", "value": "3" } ], "mapdata_json_2_1": [], "mapdata_json_2_2": [ { "key": "0", "value": "eleme\"nt1" }, { "key": "1", "value": "element2" }, { "key": "2", "value": "element3" } ], "mapdata_json_2_3": [ [ "0", "eleme\"nt1" ], [ "1", "element2" ], [ "2", "element3" ] ], "mapdata_json_2_4": [ { "key": "0", "key2": "$(this.k[1])", "value": "eleme\"nt1" }, { "key": "1", "key2": "$(this.k[1])", "value": "element2" }, { "key": "2", "key2": "$(this.k[1])", "value": "element3" } ], "mapdata_json_3_1": [], "mapdata_json_3_2": [ { "key": "x\"x", "value": "y\"y" } ], "mapdata_json_3_3": [ [ "x\"x", "y\"y" ] ], "mapdata_json_3_4": [ { "key": "x\"x", "key2": "$(this.k[1])", "value": "y\"y" } ], "mapdata_json_4_1": [], "mapdata_json_4_2": [], "mapdata_json_4_3": [], "mapdata_json_4_4": [], "mapdata_json_5_1": [], "mapdata_json_5_2": [ { "key": "anotherkey", "value": "anothervalue" }, { "key": "lastkey!", "value": "o\"ne" }, { "key": "lastkey!", "value": "two" }, { "key": "lastkey!", "value": "three" }, { "key": "mykey", "value": "myvalue" } ], "mapdata_json_5_3": [ [ "anotherkey", "anothervalue" ], [ "lastkey!", "o\"ne" ], [ "lastkey!", "two" ], [ "lastkey!", "three" ], [ "mykey", "myvalue" ] ], "mapdata_json_5_4": [ { "key": "anotherkey", "key2": "$(this.k[1])", "value": "anothervalue" }, { "key": "lastkey!", "key2": "$(this.k[1])", "value": "o\"ne" }, { "key": "lastkey!", "key2": "$(this.k[1])", "value": "two" }, { "key": "lastkey!", "key2": "$(this.k[1])", "value": "three" }, { "key": "mykey", "key2": "$(this.k[1])", "value": "myvalue" } ], "mapdata_json_6_1": [], "mapdata_json_6_2": [ { "key": "a", "value": "c" } ], "mapdata_json_6_3": [ [ "a", "c" ] ], "mapdata_json_6_4": [ { "key": "a", "key2": "b", "value": "c" } ], "mapdata_none_1_1": [ "key = 0", "key = 1", "key = 2" ], "mapdata_none_1_2": [ "key = 0, value = 1", "key = 1, value = 2", "key = 2, value = 3" ], "mapdata_none_1_3": [ "key = 0, key2 = $(this.k[1]), value = 1", "key = 1, key2 = $(this.k[1]), value = 2", "key = 2, key2 = $(this.k[1]), value = 3" ], "mapdata_none_1_4": [ "xvalue should be 0value", "xvalue should be 1value", "xvalue should be 2value" ], "mapdata_none_2_1": [ "key = 0", "key = 1", "key = 2" ], "mapdata_none_2_2": [ "key = 0, value = eleme\"nt1", "key = 1, value = element2", "key = 2, value = element3" ], "mapdata_none_2_3": [ "key = 0, key2 = $(this.k[1]), value = eleme\"nt1", "key = 1, key2 = $(this.k[1]), value = element2", "key = 2, key2 = $(this.k[1]), value = element3" ], "mapdata_none_2_4": [ "xvalue should be 0value", "xvalue should be 1value", "xvalue should be 2value" ], "mapdata_none_3_1": [ "key = x\"x" ], "mapdata_none_3_2": [ "key = x\"x, value = y\"y" ], "mapdata_none_3_3": [ "key = x\"x, key2 = $(this.k[1]), value = y\"y" ], "mapdata_none_3_4": [ "xvalue should be xxvalue" ], "mapdata_none_4_1": [], "mapdata_none_4_2": [], "mapdata_none_4_3": [], "mapdata_none_4_4": [], "mapdata_none_5_1": [ "key = anotherkey", "key = lastkey!", "key = mykey" ], "mapdata_none_5_2": [ "key = anotherkey, value = anothervalue", "key = lastkey!, value = o\"ne", "key = lastkey!, value = two", "key = lastkey!, value = three", "key = mykey, value = myvalue" ], "mapdata_none_5_3": [ "key = anotherkey, key2 = $(this.k[1]), value = anothervalue", "key = lastkey!, key2 = $(this.k[1]), value = o\"ne", "key = lastkey!, key2 = $(this.k[1]), value = two", "key = lastkey!, key2 = $(this.k[1]), value = three", "key = mykey, key2 = $(this.k[1]), value = myvalue" ], "mapdata_none_5_4": [ "xvalue should be anothervalue", "xvalue should be lastvalue", "xvalue should be myvalue" ], "mapdata_none_6_1": [ "key = a" ], "mapdata_none_6_2": [ "key = a, value = c" ], "mapdata_none_6_3": [ "key = a, key2 = b, value = c" ], "mapdata_none_6_4": [ "xvalue should be avalue" ], "spec1": "key = $(this.k)", "spec2": "key = $(this.k), value = ${this.v}", "spec3": "key = $(this.k), key2 = $(this.k[1]), value = ${this.v}", "spec4": "xvalue should be $(static[$(this.k)])", "static[0]": "0value", "static[1]": "1value", "static[2]": "2value", "static[a]": "avalue", "static[anotherkey]": "anothervalue", "static[lastkey!]": "lastvalue", "static[mykey]": "myvalue", "static[x"x]": "xxvalue", "static[x]": "xvalue" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getuserinfo.cf0000644000000000000000000000151115010704253025231 0ustar00rootroot00000000000000####################################################### # # Test 'getuserinfo' function # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: # this is pretty much all we can test across platforms "info_root" string => nth(getuserinfo("root"), "username"); "info_0" string => nth(getuserinfo(0), "uid"); } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_3.cf.csv0000644000000000000000000000043715010704253026750 0ustar00rootroot00000000000000ClassExpr,SORT,Token,Value any,1,net.ipv4.ip_forward,ANYVALUE-sort1 any,a,net.ipv4.ip_forward,ANYVALUE-sorta any,A,net.ipv4.ip_forward,ANYVALUE-sortA supercalifragilisticexpialidociousNOTDEFINED,0,net.ipv4.ip_forward,SHOULD_BE_FILTERED_OUT any,0,net.ipv4.ip_forward,ANYVALUE-sort0 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sort.cf0000644000000000000000000000656615010704253023705 0ustar00rootroot00000000000000########################################################### # # Test sort() # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent init { vars: "a" slist => { "b", "c", "a" }; "b" slist => { "100", "9", "10" }; "c" slist => { }; "d" slist => { "", "a", "", "b" }; "e" slist => { "a", "1", "b" }; "f" slist => { "0", "100.0", "0.1", "3.2" }; "g" slist => { "", "-2.1", "0.88", "b", "00.88" }; "ip" slist => { "100.200.100.0", "1.2.3.4", "9.7.5.1", "9", "9.7", "9.7.5", "", "-1", "where are the IP addresses?" }; "ipv6" slist => { "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "FE80::0202:B3FF:FE1E:8329", "::1", # the following should all be parsed as the same address and sorted together "2001:db8:0:0:1:0:0:1", "2001:0db8:0:0:1:0:0:1", "2001:db8::1:0:0:1", "2001:db8::0:1:0:0:1", "2001:0db8::1:0:0:1", "2001:db8:0:0:1::1", "2001:db8:0000:0:1::1", "2001:DB8:0:0:1::1", # note uppercase IPv6 addresses are invalid # examples from https://www.ripe.net/lir-services/new-lir/ipv6_reference_card.pdf "8000:63bf:3fff:fdd2", "::ffff:192.0.2.47", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "2001:0000:4136:e378:", "8000:63bf:3fff:fdd2", "2001:0002:6c::430", "2001:10:240:ab::a", "2002:cb0a:3cdd:1::1", "2001:db8:8:4::2", "ff01:0:0:0:0:0:0:2", "-1", "where are the IP addresses?" }; "mac" slist => { "00:14:BF:F7:23:1D", "0:14:BF:F7:23:1D", ":14:BF:F7:23:1D", "00:014:BF:0F7:23:01D", "00:14:BF:F7:23:1D", "0:14:BF:F7:23:1D", ":14:BF:F7:23:1D", "00:014:BF:0F7:23:01D", "01:14:BF:F7:23:1D", "1:14:BF:F7:23:1D", "01:14:BF:F7:23:2D", "1:14:BF:F7:23:2D", "-1", "where are the MAC addresses?" }; } bundle agent test { meta: "test_soft_fail" string => "hpux|sunos_5_9", meta => { "redmine4934", "redmine5107" }; "test_flakey_fail" string => "windows", meta => { "ENT-10254" }; vars: "test" slist => { "a", "b", "c", "d", "e", "f", "g", "ip", "ipv6", "mac" }; "sort" slist => { "lex", "int", "real", "IP", "MAC" }; "$(sort)_sorted_$(test)" slist => sort("init.$(test)", $(sort)); "inline_$(sort)_sorted" slist => sort('["b", "c", "a", "100", "9", "10"]', $(sort)); "sorted_$(test)" slist => sort("init.$(test)"); # implicit "lex" } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maparray_mixed.cf0000644000000000000000000000523415010704253025707 0ustar00rootroot00000000000000####################################################### # # Test maparray() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" string => "Test that maparray can expand variables with this and without this at the same time."; "test_soft_fail" string => "any", meta => { "CFE-2590" }; vars: "ntp_servers" string => ifelse( "cfengine", ' { "kali01": { "address" : "172.27.82.22", "key" : "232", "trustedkey" : [ "232", "242", "252" ], "serverkey" : "213" }, "kali02": { "address" : "172.27.82.23", "key" : "232", "trustedkey" : [ "232", "242", "252" ], "serverkey" : "213" }, "kali03": { "address" : "172.27.82.24", "key" : "232", "trustedkey" : [ "232", "242", "252" ], "serverkey" : "213" } }', "EOP", ' { "nexus": { "address" : "134.152.192.11", "key" : "", "trustedkey" : [ "" ], "serverkey" : "" } }', "undefined"); "ntp" data => parsejson($(ntp_servers)); "i" slist => getindices("ntp"); "key[$(i)]" string => ifelse(isgreaterthan( string_length("$(ntp[$(i)][key])"), "0" ), "key", " "); # In 3.9.2 $(key[$(i)]) is expanded in the maparray used below. In 3.10 it # is not expanded and the literal is left in each entry of the resulting # slist. "commands" slist => maparray("server $(ntp[$(this.k)][address]) iburst $(key[$(i)]) $(ntp[$(this.k)][key]) # $(this.k)", "ntp"); files: "$(G.testfile).actual" create => "true", edit_template => "$(this.promise_dirname)/multiline_json.mustache", template_method => "mustache", template_data => bundlestate("test"); reports: DEBUG:: "$(commands)"; } bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(this.promise_filename).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/execresult.cf0000644000000000000000000002246615010704253025076 0ustar00rootroot00000000000000####################################################### # # Test returnszero() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { vars: "cwd" string => dirname("$(this.promise_filename)"); windows:: "zero_rel" string => "type $(cwd)$(const.dirsep)text.txt"; "one_rel" string => "type $(cwd)$(const.dirsep)text.txt.doesnotexist"; "nxe_rel" string => "nosuchprogramexists"; "zero_abs" string => "c:\windows\system32\cmd.exe /C type $(cwd)$(const.dirsep)text.txt"; "one_abs" string => "c:\windows\system32\cmd.exe /C type $(cwd)$(const.dirsep)text.txt.doesnotexist"; "nxe_abs" string => "c:\xbin\nosuchprogramexists"; "zero_powershell" string => "Get-Content $(cwd)$(const.dirsep)text.txt"; "one_powershell" string => "Get-Content $(cwd)$(const.dirsep)text.txt.doesnotexist"; "nxe_powershell" string => "nosuchprogramexists"; !windows:: "zero_rel" string => "cat $(cwd)$(const.dirsep)text.txt"; "one_rel" string => "cat $(cwd)$(const.dirsep)text.txt.doesnotexist"; "nxe_rel" string => "nosuchprogramexists"; "zero_abs" string => "/bin/cat $(cwd)$(const.dirsep)text.txt"; "one_abs" string => "/bin/cat $(cwd)$(const.dirsep)text.txt.doesnotexist"; "nxe_abs" string => "/xbin/nosuchprogramexists"; classes: # Test whether we extracted the expected string. "zero_noshell_rel" expression => regcmp(".*Succeeded.*", execresult("$(zero_rel)", "noshell")); "zero_useshell_rel" expression => regcmp(".*Succeeded.*", execresult("$(zero_rel)", "useshell")); "zero_noshell_abs" expression => regcmp(".*Succeeded.*", execresult("$(zero_abs)", "noshell")); "zero_useshell_abs" expression => regcmp(".*Succeeded.*", execresult("$(zero_abs)", "useshell")); "one_noshell_rel" expression => regcmp(".*Succeeded.*", execresult("$(one_rel)", "noshell")); "one_useshell_rel" expression => regcmp(".*Succeeded.*", execresult("$(one_rel)", "useshell")); "one_noshell_abs" expression => regcmp(".*Succeeded.*", execresult("$(one_abs)", "noshell")); "one_useshell_abs" expression => regcmp(".*Succeeded.*", execresult("$(one_abs)", "useshell")); "nxe_noshell_rel" expression => regcmp(".*Succeeded.*", execresult("$(nxe_rel)", "noshell")); "nxe_useshell_rel" expression => regcmp(".*Succeeded.*", execresult("$(nxe_rel)", "useshell")); "nxe_noshell_abs" expression => regcmp(".*Succeeded.*", execresult("$(nxe_abs)", "noshell")); "nxe_useshell_abs" expression => regcmp(".*Succeeded.*", execresult("$(nxe_abs)", "useshell")); # Test whether any assignment happens at all. "does_assign_zero_noshell_rel" expression => regcmp(".*", execresult("$(zero_rel)", "noshell")); "does_assign_zero_useshell_rel" expression => regcmp(".*", execresult("$(zero_rel)", "useshell")); "does_assign_zero_noshell_abs" expression => regcmp(".*", execresult("$(zero_abs)", "noshell")); "does_assign_zero_useshell_abs" expression => regcmp(".*", execresult("$(zero_abs)", "useshell")); "does_assign_one_noshell_rel" expression => regcmp(".*", execresult("$(one_rel)", "noshell")); "does_assign_one_useshell_rel" expression => regcmp(".*", execresult("$(one_rel)", "useshell")); "does_assign_one_noshell_abs" expression => regcmp(".*", execresult("$(one_abs)", "noshell")); "does_assign_one_useshell_abs" expression => regcmp(".*", execresult("$(one_abs)", "useshell")); "does_assign_nxe_noshell_rel" expression => regcmp(".*", execresult("$(nxe_rel)", "noshell")); "does_assign_nxe_useshell_rel" expression => regcmp(".*", execresult("$(nxe_rel)", "useshell")); "does_assign_nxe_noshell_abs" expression => regcmp(".*", execresult("$(nxe_abs)", "noshell")); "does_assign_nxe_useshell_abs" expression => regcmp(".*", execresult("$(nxe_abs)", "useshell")); windows:: # Test whether we extracted the expected string. "zero_powershell" expression => regcmp(".*Succeeded.*", execresult("$(zero_powershell)", "powershell")); "one_powershell" expression => regcmp(".*Succeeded.*", execresult("$(one_powershell)", "powershell")); "nxe_powershell" expression => regcmp(".*Succeeded.*", execresult("$(nxe_powershell)", "powershell")); # Test whether any assignment happens at all. "does_assign_zero_powershell" expression => regcmp(".*", execresult("$(zero_powershell)", "powershell")); "does_assign_one_powershell" expression => regcmp(".*", execresult("$(one_powershell)", "powershell")); "does_assign_nxe_powershell" expression => regcmp(".*", execresult("$(nxe_powershell)", "powershell")); any:: "ok_common" and => { "!zero_noshell_rel", "zero_useshell_rel", "zero_noshell_abs", "zero_useshell_abs", "!one_noshell_rel", "!one_useshell_rel", "!one_noshell_abs", "!one_useshell_abs", "!nxe_noshell_rel", "!nxe_useshell_rel", "!nxe_noshell_abs", "!nxe_useshell_abs", "!does_assign_zero_noshell_rel", "does_assign_zero_useshell_rel", "does_assign_zero_noshell_abs", "does_assign_zero_useshell_abs", "!does_assign_one_noshell_rel", "does_assign_one_useshell_rel", "does_assign_one_noshell_abs", "does_assign_one_useshell_abs", "!does_assign_nxe_noshell_rel", "does_assign_nxe_useshell_rel", "!does_assign_nxe_noshell_abs", "!does_assign_nxe_useshell_abs", }; windows:: "ok_windows" and => { "zero_powershell", "!one_powershell", "!nxe_powershell", "does_assign_zero_powershell", "does_assign_one_powershell", "does_assign_nxe_powershell", }; "ok" and => { "ok_common", "ok_windows", }; !windows:: "ok" and => { "ok_common" }; reports: DEBUG.zero_noshell_rel:: "'$(zero_rel)' executes command successfully with noshell"; DEBUG.!zero_useshell_rel:: "'$(zero_rel)' executes command unsuccessfully with useshell"; DEBUG.one_noshell_rel:: "'$(one_rel)' executes command successfully with noshell"; DEBUG.one_useshell_rel:: "'$(one_rel)' executes command successfully with useshell"; DEBUG.nxe_noshell_rel:: "'$(nxe_rel)' executes command successfully with noshell"; DEBUG.nxe_useshell_rel:: "'$(nxe_rel)' executes command successfully with useshell"; DEBUG.!zero_noshell_abs:: "'$(zero_abs)' executes command unsuccessfully with noshell"; DEBUG.!zero_useshell_abs:: "'$(zero_abs)' executes command unsuccessfully with useshell"; DEBUG.one_noshell_abs:: "'$(one_abs)' executes command successfully with noshell"; DEBUG.one_useshell_abs:: "'$(one_abs)' executes command successfully with useshell"; DEBUG.nxe_noshell_abs:: "'$(nxe_abs)' executes command successfully with noshell"; DEBUG.nxe_useshell_abs:: "'$(nxe_abs)' executes command successfully with useshell"; DEBUG.does_assign_zero_noshell_rel:: "'$(zero_rel)' executes command with noshell"; DEBUG.!does_assign_zero_useshell_rel:: "'$(zero_rel)' does not execute command with useshell"; DEBUG.does_assign_one_noshell_rel:: "'$(one_rel)' executes command with noshell"; DEBUG.!does_assign_one_useshell_rel:: "'$(one_rel)' does not execute command with useshell"; DEBUG.does_assign_nxe_noshell_rel:: "'$(nxe_rel)' executes command with noshell"; DEBUG.!does_assign_nxe_useshell_rel:: "'$(nxe_rel)' does not execute command with useshell"; DEBUG.!does_assign_zero_noshell_abs:: "'$(zero_abs)' does not execute command with noshell"; DEBUG.!does_assign_zero_useshell_abs:: "'$(zero_abs)' does not execute command with useshell"; DEBUG.!does_assign_one_noshell_abs:: "'$(one_abs)' does not execute command with noshell"; DEBUG.!does_assign_one_useshell_abs:: "'$(one_abs)' does not execute command with useshell"; DEBUG.does_assign_nxe_noshell_abs:: "'$(nxe_abs)' executes command with noshell"; DEBUG.does_assign_nxe_useshell_abs:: "'$(nxe_abs)' executes command with useshell"; windows.DEBUG.!zero_powershell:: "'$(zero_powershell)' executes command unsuccessfully with powershell"; windows.DEBUG.one_powershell:: "'$(one_powershell)' executes command successfully with powershell"; windows.DEBUG.nxe_powershell:: "'$(nxe_powershell)' executes command successfully with powershell"; windows.DEBUG.!does_assign_zero_powershell:: "'$(zero_powershell)' does not execute command with powershell"; windows.DEBUG.!does_assign_one_powershell:: "'$(one_powershell)' does not execute command with powershell"; windows.DEBUG.!does_assign_nxe_powershell:: "'$(nxe_powershell)' does not execute command with powershell"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_expand.cf.expected.json0000644000000000000000000000037515010704253027726 0ustar00rootroot00000000000000{ "load_expanded": { "200": "$(nosuchvar)", "foo": "nothing again", "plain data": "nothing" }, "load_unexpanded": { "$(x)": "nothing again", "$(y)": "$(nosuchvar)", "plain data": "nothing" }, "x": "foo", "y": "200" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/440.cf0000644000000000000000000000533615010704253023217 0ustar00rootroot00000000000000####################################################### # # Test readstringarrayidx(), simple # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "this"), strcmp("$(test.ary[1][1])", "is"), strcmp("$(test.ary[1][2])", "a"), strcmp("$(test.ary[1][3])", "test"), strcmp("$(test.ary[2][0])", "1"), strcmp("$(test.ary[2][1])", "2"), strcmp("$(test.ary[2][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][4]"), isvariable("test.ary[2][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = 'this', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = 'is', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = 'a', saw '$(test.ary[1][2])'"; "expected test.ary[1][3] = 'test', saw '$(test.ary[1][3])'"; "expected test.ary[2][0] = '1', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = '2', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = '3', saw '$(test.ary[2][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/parsearray_maxlen.cf0000644000000000000000000000432515010704253026422 0ustar00rootroot00000000000000# Test the parse\w+array(idx)? functions honour their maxlen parameter. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { vars: "float" string => " 1.0 4.0 2.0 1.0 3.0 1e1 # 36 bytes up to 1e1 4.0 2.0 5.0 16.0 6.0 3.0"; "whole" string => " 1 4 2 1 3 10 # 30 bytes up to 10 4 2 5 16 6 3"; "words" string => " one four two one three ten # 37 bytes up to ten four two five sixteen six three"; } bundle agent test { vars: "flen" int => parserealarray("float", "$(init.float)", "\s*#[^\n]*", "\s+", 1000, 36); "ilen" int => parseintarray("whole", "$(init.whole)", "\s*#[^\n]*", "\s+", 1000, 30); "slen" int => parsestringarray("words", "$(init.words)", "\s*#[^\n]*", "\s+", 1000, 37); "tlen" int => parsestringarrayidx("texts", "$(init.words)", "\s*#[^\n]*", "\s+", 1000, 37); } bundle agent check { vars: "arrays" slist => { "float", "whole", "words", "texts" }; "key_$(arrays)" slist => getindices("test.$(arrays)"); "sub_$(key_$(arrays))" slist => getindices("test.$(arrays)[$(key_$(arrays))]"); classes: "okf" expression => strcmp("$(test.flen)", "3"); "oki" expression => strcmp("$(test.ilen)", "3"); "oks" expression => strcmp("$(test.slen)", "3"); "okt" expression => strcmp("$(test.tlen)", "3"); "ok" and => { "okf", "oki", "oks", "okt" }; reports: DEBUG.!okf:: "float: '$(test.flen)'"; "float[$(key_float)][$(sub_$(key_float))] = $(test.float[$(key_float)][$(sub_$(key_float))])"; DEBUG.!oki:: "whole: '$(test.ilen)'"; "whole[$(key_whole)][$(sub_$(key_whole))] = $(test.whole[$(key_whole)][$(sub_$(key_whole))])"; DEBUG.!oks:: "words: '$(test.slen)'"; "words[$(key_words)][$(sub_$(key_words))] = $(test.words[$(key_words)][$(sub_$(key_words))])"; DEBUG.!okt:: "texts: '$(test.tlen)'"; "texts[$(key_texts)][$(sub_$(key_texts))] = $(test.texts[$(key_texts)][$(sub_$(key_texts))])"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/version_compare.cf.expected.json0000644000000000000000000000144315010704253030646 0ustar00rootroot00000000000000{ "false_a": "!any", "false_b": "!any", "false_c": "!any", "false_d": "!any", "false_e": "!any", "false_f": "!any", "false_g": "!any", "false_h": "!any", "false_i": "!any", "false_j": "!any", "false_k": "!any", "false_l": "!any", "false_m": "!any", "false_n": "!any", "false_o": "!any", "false_p": "!any", "false_q": "!any", "false_r": "!any", "false_s": "!any", "false_t": "!any", "true_a": "any", "true_b": "any", "true_c": "any", "true_d": "any", "true_e": "any", "true_f": "any", "true_g": "any", "true_h": "any", "true_i": "any", "true_j": "any", "true_k": "any", "true_l": "any", "true_m": "any", "true_n": "any", "true_o": "any", "true_p": "any", "true_q": "any", "true_r": "any", "true_s": "any", "true_t": "any" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/eval_class.cf0000644000000000000000000000637415010704253025027 0ustar00rootroot00000000000000####################################################### # # Test eval() in class context mode # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "values[0]" string => "x"; "values[1]" string => "+ 200"; "values[2]" string => "200 + 100"; "values[3]" string => "200 - 100"; "values[4]" string => "- - -"; "values[5]" string => "2 - (3 - 1)"; "values[6]" string => ""; "values[7]" string => "3 / 0"; "values[8]" string => "3^3"; "values[9]" string => "(-1)^2"; "values[10]" string => "sin(20)"; "values[11]" string => "cos(20)"; "values[12]" string => "asin(0.2)"; "values[13]" string => "acos(0.2)"; "values[14]" string => "tan(20)"; "values[15]" string => "atan(0.2)"; "values[16]" string => "log(0.2)"; "values[17]" string => "ln2"; "values[18]" string => "ln10"; "values[19]" string => "20 % 3"; "values[20]" string => "sqrt(0.2)"; "values[21]" string => "ceil(3.5)"; "values[22]" string => "floor(3.4)"; "values[23]" string => "abs(-3.4)"; "values[24]" string => "-3.4 -3.4"; "values[25]" string => "-3.400000 -3.400001"; "values[26]" string => "pi"; "values[27]" string => "e"; "values[28]" string => "10 == 10"; "values[29]" string => "10 == 11"; "values[30]" string => "3**0"; "values[31]" string => "step(10)"; "values[32]" string => "step(-10)"; "values[33]" string => "100k"; "values[34]" string => "(200m - 100k) / (2t + 2t)"; "values[35]" string => "10 > 10"; "values[36]" string => "10 > 11"; "values[37]" string => "10 >= 10"; "values[38]" string => "10 >= 11"; "values[39]" string => "10 < 10"; "values[40]" string => "10 < 11"; "values[41]" string => "10 <= 10"; "values[42]" string => "10 <= 11"; } ####################################################### bundle agent test { classes: "context_eval_$(indices)" expression => eval("$(init.values[$(indices)])", "class"), scope => "namespace"; vars: "indices" slist => getindices("init.values"); } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_expected("context_eval_2,context_eval_3,context_eval_7,context_eval_8,context_eval_9,context_eval_10,context_eval_11,context_eval_12,context_eval_13,context_eval_14,context_eval_15,context_eval_16,context_eval_17,context_eval_18,context_eval_19,context_eval_20,context_eval_21,context_eval_22,context_eval_23,context_eval_24,context_eval_25,context_eval_26,context_eval_27,context_eval_28,context_eval_30,context_eval_31,context_eval_33,context_eval_34,context_eval_37,context_eval_40,context_eval_41,context_eval_42", "context_eval_0,context_eval_1,context_eval_4,context_eval_5,context_eval_6,context_eval_29,context_eval_32,context_eval_35,context_eval_36,context_eval_38,context_eval_39", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_containers.cf0000644000000000000000000000123115010704253027122 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "arr" data => '["a", [], { "x": 1 }, 2, 5.30, true]'; } bundle agent test { vars: "arr_v" slist => getvalues("init.arr"); reports: DEBUG:: "arr_v $(arr_v)"; } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/regex_replace.cf.expected.json0000644000000000000000000000116715010704253030263 0ustar00rootroot00000000000000{ "allofitwithTEST": "TEST", "cap123": "[cap=abc][cap=def][cap=ghi]j", "cap123_backslash": "[cap=abc][cap=def][cap=ghi]j", "cap123_backslash2": "[cap=abc][cap=def][cap=ghi]j", "cap123_backslashes1to9havesome": "[cap=abc][cap=def][cap=ghi]j", "cap123_backslashes1to9missing": "[cap=][cap=][cap=]j", "dots_everywhere": "-DOT--DOT--DOT--DOT--DOT--DOT--DOT--DOT--DOT--DOT-", "empty1": "", "empty2": "", "nomatch": "abcdefghij", "nomatch2": "abcdefghij", "simple": "ABCdefghij", "simple_nocase": "ABCdefghij", "test": "abcdefghij", "void": "abcdefghij", "void1": "", "void2": "xaxbxcxdxexfxgxhxixjx" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/065.cf0000644000000000000000000000166715010704253023225 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => now(); } ####################################################### bundle agent check { vars: "time" int => "1289601605"; # About when this test was created classes: "ok" expression => islessthan("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_5.cf0000644000000000000000000000326515010704253026162 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2768" } string => "Test that classfiltercsv() works: - column headings - simple filtering (no duplicates after filter) - no sorting - empty rows"; } bundle agent check { vars: "data_file" string => "$(this.promise_filename).csv"; "d" data => classfiltercsv( $(data_file), "true", # Data file contains column headings 0); # Column containing class expression to filter with classes: # Check if Token has the value we expect "Token_OK" expression => strcmp( "$(d[0][Token])", "net.ipv4.ip_forward" ); # Check if Value has the value we expect "Value_OK" expression => strcmp( "$(d[0][Value])", "ANYVALUE" ); # Check if the result contains the number of records we expect. "Length_OK" expression => strcmp( length( d ), 1 ); methods: "Pass/FAIL" usebundle => dcs_passif_expected( 'Token_OK,Value_OK,Length_OK', '', $(this.promise_filename) ), inherit => "true"; reports: DEBUG|EXTRA:: "Function returned:$(with)" with => string_mustache( "{{%-top-}}", d ); "supercalifragilisticexpialidociousNOTDEFINED is actually defined." if => "supercalifragilisticexpialidociousNOTDEFINED"; "supercalifragilisticexpialidociousNOTDEFINED is not defined (as expected)" unless => "supercalifragilisticexpialidociousNOTDEFINED"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/regextract2.cf0000644000000000000000000000217415010704253025137 0ustar00rootroot00000000000000####################################################### # # Test regextract # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: parsed:: "part1_as_int" int => "$(part[1])"; "part2_as_int" int => "$(part[2])"; "part1_as_str" string => "$(part[1])"; "part2_as_str" string => "$(part[2])"; classes: "parsed" expression => regextract("^node-(\d+)-0*(\d+)", "node-8-01", "part"); } ####################################################### bundle agent check { classes: "ok1" expression => strcmp("$(test.part1_as_int)", "$(test.part1_as_str)"); "ok2" expression => strcmp("$(test.part2_as_int)", "$(test.part2_as_str)"); "ok" and => { "ok1", "ok2" }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/017.cf0000644000000000000000000000301615010704253023210 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; "789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123.456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok789", islessthan("$(test.sum)", "912.457"), isgreaterthan("$(test.sum)", "912.455") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getvalues_returns_slist_for_datacontainer_scalar.cf0000644000000000000000000000276515010704253034722 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test getvalues() returns an slist for a datacontainer # scalar # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data" data => parsejson('{"foo": "bar"}'); } ####################################################### bundle agent test { meta: "test_soft_fail" string => "!any", meta => { "redmine7116" }; vars: "values_data" slist => getvalues("init.data"); } ####################################################### bundle agent check { vars: "expected_elements" slist => { "bar" }; "diff1" slist => difference( "test.values_data", expected_elements ); "diff2" slist => difference( expected_elements, "test.values_data"); "len_diff1" int => length(diff1); "len_diff2" int => length(diff2); classes: "ok" expression => strcmp( $(len_diff1), $(len_diff2) ); reports: DEBUG:: "DEBUG: data value: '$(test.values_data)'"; "DEBUG: expected value: '$(expected_elements)'"; "DEBUG: found '$(diff1)' in test.values_data, but not in expected_elements"; "DEBUG: found '$(diff2)' in expected_elements, but not in test.values_data"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/012.cf0000644000000000000000000000300215010704253023176 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123"; "456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/canonifyuniquely.cf0000644000000000000000000000643015010704253026306 0ustar00rootroot00000000000000####################################################### # # Test canonifyuniquely() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "in1" string => "h?llo"; "expect1" string => "h_llo_ad3f6fcf7063483c9d23b4b83c0b65df72e9f5cc"; "out1" string => canonifyuniquely("$(in1)"); "in2" string => "h/llo"; "expect2" string => "h_llo_5d049ef5eaa0c5b4622eac3eee899132731bc034"; "out2" string => canonifyuniquely("$(in2)"); "in3" string => "/etc/passwd"; "expect3" string => "_etc_passwd_b5cc3f676d00dd320d85ef41a5209fa0a99891ea"; "out3" string => canonifyuniquely("$(in3)"); "in4" string => "hello@mumble.com"; "expect4" string => "hello_mumble_com_5050b0473d3e79adccfb885b8cbe3f44ed706987"; "out4" string => canonifyuniquely("$(in4)"); "in5" string => "!@#$%^&*()_-+={}[]\:;<>,?"; "expect5" string => "__________________________55a3d62a602f37917827cbe044fcbb5da58f8df5"; "out5" string => canonifyuniquely("$(in5)"); "in6" string => "Eystein MÃ¥løy Stenberg"; "expect6" string => "Eystein_M__l__y_Stenberg_f1d661c705209075cd873226cb131d2e27374357"; "out6" string => canonifyuniquely("$(in6)"); "in7" string => "$(in1) $(in1)"; "expect7" string => "h_llo_h_llo_53750186dbccd2f8a512345c4a92ccc34d75267d"; "out7" string => canonifyuniquely("$(in1) $(in1)"); "in8" string => "'\"hello\"'"; "expect8" string => "__hello___b2a2a0459a623c8e1cae32e88673ba4067106dc9"; "out8" string => canonifyuniquely("$(in8)"); } ####################################################### bundle agent check { classes: "ok" and => { strcmp("$(test.expect1)", "$(test.out1)"), strcmp("$(test.expect2)", "$(test.out2)"), strcmp("$(test.expect3)", "$(test.out3)"), strcmp("$(test.expect4)", "$(test.out4)"), strcmp("$(test.expect5)", "$(test.out5)"), strcmp("$(test.expect6)", "$(test.out6)"), strcmp("$(test.expect7)", "$(test.out7)"), strcmp("$(test.expect8)", "$(test.out8)"), }; reports: DEBUG:: "Expected canonifyuniquely('$(test.in1)') => $(test.out1) == $(test.expect1)"; "Expected canonifyuniquely('$(test.in2)') => $(test.out2) == $(test.expect2)"; "Expected canonifyuniquely('$(test.in3)') => $(test.out3) == $(test.expect3)"; "Expected canonifyuniquely('$(test.in4)') => $(test.out4) == $(test.expect4)"; "Expected canonifyuniquely('$(test.in5)') => $(test.out5) == $(test.expect5)"; "Expected canonifyuniquely('$(test.in6)') => $(test.out6) == $(test.expect6)"; "Expected canonifyuniquely('$(test.in7)') => $(test.out7) == $(test.expect7)"; "Expected canonifyuniquely('$(test.in8)') => $(test.out8) == $(test.expect8)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/format_edge_case.cf.expected.json0000644000000000000000000005164615010704253030734 0ustar00rootroot00000000000000{ "container": [ "Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else." ], "container_str": "[\"Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else.\"]", "list": [ "Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else." ], "list_str": "{ \"Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else.\" }", "str": "Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else." } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maparray_multi_index.cf.expected.json0000644000000000000000000000331515010704253031670 0ustar00rootroot00000000000000{ "bundles[onelevel1]": [ "onelevel1_avalue", "onelevel1_bvalue" ], "bundles[onelevel2]": "onelevel2value", "bundles[services][afs]": [ "afs.cf", "afsadm.cf" ], "bundles[services][base]": [ "base.cf", "base2.cf" ], "bundles[x][y][z1]": "xyz1", "bundles[x][y][z23]": [ "xyz2", "xyz3" ], "bundles[zcuinventory][inventory_fibrechannel]": [ "inv_fibrechannel.cf" ], "bundles[zcuinventory][inventory_virtualization]": [ "inv_virtualization.cf" ], "bundles[zcuinventory][zcuinventory]": [ "inv_zcuinventory.cf" ], "bundles[zculib][mypaths]": [ "pathsa.cf", "pathsb.cf" ], "bundles[zculib][myservices]": [ "myservices.cf" ], "inputs": [ "zculib/pathsa.cf", "zculib/pathsb.cf", "zculib/myservices.cf" ], "merged_bundles": { "onelevel1": [ "onelevel1_avalue", "onelevel1_bvalue" ], "onelevel2": "onelevel2value", "services": { "afs": [ "afs.cf", "afsadm.cf" ], "base": [ "base.cf", "base2.cf" ] }, "x": { "y": { "z1": "xyz1", "z23": [ "xyz2", "xyz3" ] } }, "zcuinventory": { "inventory_fibrechannel": [ "inv_fibrechannel.cf" ], "inventory_virtualization": [ "inv_virtualization.cf" ], "zcuinventory": [ "inv_zcuinventory.cf" ] }, "zculib": { "mypaths": [ "pathsa.cf", "pathsb.cf" ], "myservices": [ "myservices.cf" ] } }, "merged_zculib": { "mypaths": [ "pathsa.cf", "pathsb.cf" ], "myservices": [ "myservices.cf" ] } } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/080.cf0000644000000000000000000000274615010704253023221 0ustar00rootroot00000000000000####################################################### # # Test getuid() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: # NOTE: We need to make this test work on Windows by finding a good # registry value to use (and we always expect it to fail on non-Windows # # Always execute this - the return value depends on the OS used, but # we always expect registryvalue() to not crash "regval" string => registryvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Currentversion", "ProgramFilesDir"); } ####################################################### bundle agent check { classes: windows:: "ok" and => { strcmp("$(test.regval)", "C:\Program Files"), }; !windows:: "ok" not => isvariable("test.regval"); reports: DEBUG:: "Registry value is $(test.regval)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { vars: "dummy" string => "dummy"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues.cf0000644000000000000000000000237315010704253024705 0ustar00rootroot00000000000000####################################################### # # Test getvalues() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "user[name]" string => "zamboni"; "user[fullname][first]" string => "Diego"; "user[fullname][last]" string => "Zamboni"; "user[dirs]" slist => { "/home/zamboni", "/tmp/zamboni", "/export/home/zamboni" }; "values" slist => getvalues("user"); "uservalues" slist => getvalues("user[fullname]"); "inline_values_map" slist => getvalues('{ "foo": 1, "bar": 2 }'); "inline_values_array" slist => getvalues('[ "foo", 1, "bar", 2 ]'); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sum_and_product.cf0000644000000000000000000000335715010704253026077 0ustar00rootroot00000000000000####################################################### # # Test 'sum' and 'product' functions # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "normal_list" slist => { "1", "2", "3" }; "empty_list" slist => { }; "normal_object" data => parsejson('{ "a": 1, "b": 2 }'); "empty_object" data => parsejson('{}'); "normal_list_sum" real => sum(normal_list); # 6 "empty_list_sum" real => sum(empty_list); # 0 "normal_object_sum" real => sum(normal_object); # 3 "empty_object_sum" real => sum(empty_object); # 0 "inline_object_sum" real => sum('{ "a": 1, "b": 2 }'); # 3 "inline_array_sum" real => sum('[ "a", 1, "b", 2 ]'); # 3 "normal_list_product" real => product(normal_list); # 6 "empty_list_product" real => product(empty_list); # 1 "normal_object_product" real => product(normal_object); # 2 "empty_object_product" real => product(empty_object); # 1 "inline_object_product" real => product('{ "a": 1, "b": 2 }'); # 2 "inline_array_product" real => product('[ "a", 1, "b", 2 ]'); # 0 } ####################################################### ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/filestat_linktarget_relative_symlink.cf0000644000000000000000000000410715010704253032403 0ustar00rootroot00000000000000####################################################### # # Test filestat(linktarget) follows relative symlinks - redmine#7404 # Also filestat(linktarget_shallow) should output the first relative symlink itself # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { # Create chain of links first_link -> second_link -> final_target commands: "$(G.touch) $(G.testdir)/final_target"; "$(G.ln) -s final_target $(G.testdir)/second_link"; "$(G.ln) -s second_link $(G.testdir)/first_link"; reports: DEBUG:: "Init: created chain of links first_link -> second_link -> final_target"; } ####################################################### bundle agent test { meta: # windows don't support symlinks "test_skip_unsupported" string => "windows"; vars: "fields" slist => splitstring("linktarget,linktarget_shallow", ",", 999); "stat[$(fields)]" string => filestat("$(G.testdir)/first_link", $(fields)); } ####################################################### bundle agent check { vars: "expected[linktarget_shallow]" string => "second_link"; "expected[linktarget]" string => "$(G.testdir)/final_target"; classes: "test1_ok" expression => strcmp("$(test.stat[linktarget])", "$(expected[linktarget])"); "test2_ok" expression => strcmp("$(test.stat[linktarget_shallow])", "$(expected[linktarget_shallow])"); "ok" expression => "test1_ok.test2_ok"; reports: DEBUG:: "linktarget : expected '$(expected[linktarget])' returned '$(test.stat[linktarget])'"; "linktarget_shallow: expected '$(expected[linktarget_shallow])' returned '$(test.stat[linktarget_shallow])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mapdata_json_pipe.cat_consume_input.sh0000755000000000000000000000022215010704253032115 0ustar00rootroot00000000000000#!/bin/sh # Works like "cat ", except that it will consume everything on stdin # before outputting the file. cat > /dev/null cat "$@" cfengine-3.24.2/tests/acceptance/01_vars/02_functions/212.cf0000644000000000000000000000245315010704253023211 0ustar00rootroot00000000000000####################################################### # # Test getvalues(), size 1 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "zero"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "vals" slist => getvalues("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/join_mapped_list.cf0000644000000000000000000000172115010704253026222 0ustar00rootroot00000000000000####################################################### # # Redmine #2614: join should iterate over all elements of a mapped list # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "elements" slist => { "a", "b", "c" }; "expected" string => "a_x:b_x:c_x"; } ####################################################### bundle agent test { vars: "map" slist => maplist("$(this)_x", "init.elements"); "join" string => join(":","map"); } ####################################################### bundle agent check { classes: "ok" expression => strcmp($(init.expected), $(test.join)); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/441.cf0000644000000000000000000000470115010704253023213 0ustar00rootroot00000000000000####################################################### # # Test readstringarrayidx(), introduce a singleton with no other fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 singleton 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "singleton"), strcmp("$(test.ary[2][0])", "1"), strcmp("$(test.ary[2][1])", "2"), strcmp("$(test.ary[2][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][1]"), isvariable("test.ary[2][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = 'singleton', saw '$(test.ary[1][0])'"; "expected test.ary[2][0] = '1', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = '2', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = '3', saw '$(test.ary[2][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/011.cf0000644000000000000000000000265515010704253023212 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok" and => { "ok_list", islessthan("$(test.sum)", "123.1"), isgreaterthan("$(test.sum)", "122.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/validdata.cf.expected.json0000644000000000000000000000011215010704253027374 0ustar00rootroot00000000000000{ "valid_json": "should appear", "valid_validjson": "should appear" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/iterating_variablesmatching_results.cf0000644000000000000000000000111015010704253032204 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2593" } string => "Test that the agent won't crash trying to iterate over variablesmatching() results"; } bundle agent check { vars: "some_var" string => "some value"; "make_cfe_crash" slist => variablesmatching("$(this.namespace):$(this.bundle)\..*"); reports: "DEBUG: '$(make_cfe_crash)' = '$($(make_cfe_crash))'"; "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sysctl.cf.sub.expected.json0000644000000000000000000000043215010704253027561 0ustar00rootroot00000000000000{ "sysctl": { "net.ipv4.tcp_mem": "383133\t510845\t766266", "net.unix.max_dgram_qlen": "512" }, "tested": [ "net.ipv4.tcp_mem", "net.unix.max_dgram_qlen" ], "values[net.ipv4.tcp_mem]": "383133\t510845\t766266", "values[net.unix.max_dgram_qlen]": "512" } setop_unique_difference_intersection.cf.expected.json0000644000000000000000000000773615010704253035067 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions{ "difference_a_a": [], "difference_a_b": [ "x", "y", "z" ], "difference_a_c": [ "x", "y", "z" ], "difference_a_d": [ "x", "y", "z" ], "difference_a_e": [ "y", "z" ], "difference_a_f": [ "x", "y", "z" ], "difference_b_a": [ "100", "9", "10" ], "difference_b_b": [], "difference_b_c": [ "100", "9", "10" ], "difference_b_d": [ "100", "9", "10" ], "difference_b_e": [ "100", "9", "10" ], "difference_b_f": [ "100", "9", "10" ], "difference_c_a": [], "difference_c_b": [], "difference_c_c": [], "difference_c_d": [], "difference_c_e": [], "difference_c_f": [], "difference_d_a": [ "" ], "difference_d_b": [ "" ], "difference_d_c": [ "" ], "difference_d_d": [], "difference_d_e": [ "" ], "difference_d_f": [ "" ], "difference_e_a": [], "difference_e_b": [ "x" ], "difference_e_c": [ "x" ], "difference_e_d": [ "x" ], "difference_e_e": [], "difference_e_f": [ "x" ], "difference_f_a": [ "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six" ], "difference_f_b": [ "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six" ], "difference_f_c": [ "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six" ], "difference_f_d": [ "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six" ], "difference_f_e": [ "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six" ], "difference_f_f": [], "difference_inline_a": [ "b", "q" ], "difference_inline_b": [ "b", "q" ], "difference_inline_c": [ "b", "q" ], "difference_inline_d": [ "b", "q" ], "difference_inline_e": [ "b", "q" ], "difference_inline_f": [ "b", "q" ], "intersection_a_a": [ "x", "y", "z" ], "intersection_a_b": [], "intersection_a_c": [], "intersection_a_d": [], "intersection_a_e": [ "x" ], "intersection_a_f": [], "intersection_a_inline": [], "intersection_b_a": [], "intersection_b_b": [ "100", "9", "10" ], "intersection_b_c": [], "intersection_b_d": [], "intersection_b_e": [], "intersection_b_f": [], "intersection_b_inline": [], "intersection_c_a": [], "intersection_c_b": [], "intersection_c_c": [], "intersection_c_d": [], "intersection_c_e": [], "intersection_c_f": [], "intersection_c_inline": [], "intersection_d_a": [], "intersection_d_b": [], "intersection_d_c": [], "intersection_d_d": [ "" ], "intersection_d_e": [], "intersection_d_f": [], "intersection_d_inline": [], "intersection_e_a": [ "x" ], "intersection_e_b": [], "intersection_e_c": [], "intersection_e_d": [], "intersection_e_e": [ "x" ], "intersection_e_f": [], "intersection_e_inline": [], "intersection_f_a": [], "intersection_f_b": [], "intersection_f_c": [], "intersection_f_d": [], "intersection_f_e": [], "intersection_f_f": [ "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six" ], "intersection_f_inline": [ "one" ], "list1": [ "a", "b", "c", "d", "e", "f" ], "list2": [ "a", "b", "c", "d", "e", "f" ], "unique_a": [ "x", "y", "z" ], "unique_b": [ "100", "9", "10" ], "unique_c": [], "unique_d": [ "" ], "unique_e": [ "x" ], "unique_f": [ "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six" ], "unique_inline_array": [ "one", "b", "q" ], "unique_inline_object": [ "b", "q", "one" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/700.cf0000644000000000000000000000145015010704253023207 0ustar00rootroot00000000000000# Test that long bundle names are not cut off (Mantis #975) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent long_long_long_long_long_long_long_long_long_name { vars: "foo[ok]" string => "abc"; "bar" slist => getindices("foo"); } bundle agent test { methods: "l" usebundle => "long_long_long_long_long_long_long_long_long_name"; } bundle agent check { vars: "res" string => join("", "long_long_long_long_long_long_long_long_long_name.bar"); classes: "ok" expression => strcmp("${res}", "ok"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/findfiles-GLOB_BRACE.cf0000644000000000000000000000407115010704253026263 0ustar00rootroot00000000000000####################################################### # # Test GLOB_BRACE with findfiles() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common findfiles { vars: "names" slist => { "a", "bc", "d/e/f", "g/h/i/j", "klm/nop/qrs" }; } ####################################################### bundle agent init { files: "$(G.testdir)/$(findfiles.names)" create => "true"; reports: DEBUG:: "Created $(G.testdir)/$(findfiles.names)"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3292" } string => "Test that findfiles() works as expected."; vars: "patterns[GLOB_BRACE]" string => "$(G.testdir)/{a,bc}"; "pnames" slist => getindices("patterns"); "found[$(pnames)]" slist => findfiles("$(patterns[$(pnames)])"); "found_string[$(pnames)]" string => join(",", "found[$(pnames)]"); reports: DEBUG:: "findfiles pattern $(pnames) '$(patterns[$(pnames)])' => '$(found_string[$(pnames)])'"; } ####################################################### bundle agent check { vars: "expected[GLOB_BRACE]" string => "$(G.testdir)$(const.dirsep)a,$(G.testdir)$(const.dirsep)bc"; "expects" slist => getindices("expected"); "fstring" slist => getindices("test.found_string"); "joint_condition" string => join(".", "expects"); classes: "$(expects)" expression => strcmp("$(test.found_string[$(expects)])", "$(expected[$(expects)])"); "ok" expression => "$(joint_condition)"; reports: DEBUG:: "pattern $(expects) matches as expected: '$(expected[$(expects)])'" if => "$(expects)"; "pattern $(expects) does NOT match expected: '$(test.found_string[$(expects)])' != '$(expected[$(expects)])'" if => "!$(expects)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata_yaml.cf.yml0000644000000000000000000000010115010704253026260 0ustar00rootroot00000000000000--- x: 100 y: - 1 - 2 - a - b - c: 200 300 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/007.cf0000644000000000000000000000552515010704253023216 0ustar00rootroot00000000000000####################################################### # # Test canonify() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "in1" string => "hello"; "expect1" string => "hello"; "out1" string => canonify("$(in1)"); "in2" string => "hello there"; "expect2" string => "hello_there"; "out2" string => canonify("$(in2)"); "in3" string => "/etc/passwd"; "expect3" string => "_etc_passwd"; "out3" string => canonify("$(in3)"); "in4" string => "hello@mumble.com"; "expect4" string => "hello_mumble_com"; "out4" string => canonify("$(in4)"); "in5" string => "!@#$%^&*()_-+={}[]\:;<>,?"; "expect5" string => "_________________________"; "out5" string => canonify("$(in5)"); "in6" string => "Eystein MÃ¥løy Stenberg"; "expect6" string => "Eystein_M__l__y_Stenberg"; "out6" string => canonify("$(in6)"); "in7" string => "$(in1) $(in1)"; "expect7" string => "$(in1)_$(in1)"; "out7" string => canonify("$(in1) $(in1)"); "in8" string => "'\"hello\"'"; "expect8" string => "__hello__"; "out8" string => canonify("$(in8)"); } ####################################################### bundle agent check { classes: "ok" and => { strcmp("$(test.expect1)", "$(test.out1)"), strcmp("$(test.expect2)", "$(test.out2)"), strcmp("$(test.expect3)", "$(test.out3)"), strcmp("$(test.expect4)", "$(test.out4)"), strcmp("$(test.expect5)", "$(test.out5)"), strcmp("$(test.expect6)", "$(test.out6)"), strcmp("$(test.expect7)", "$(test.out7)"), strcmp("$(test.expect8)", "$(test.out8)"), }; reports: DEBUG:: "Expected canonify('$(test.in1)') => $(test.out1) == $(test.expect1)"; "Expected canonify('$(test.in2)') => $(test.out2) == $(test.expect2)"; "Expected canonify('$(test.in3)') => $(test.out3) == $(test.expect3)"; "Expected canonify('$(test.in4)') => $(test.out4) == $(test.expect4)"; "Expected canonify('$(test.in5)') => $(test.out5) == $(test.expect5)"; "Expected canonify('$(test.in6)') => $(test.out6) == $(test.expect6)"; "Expected canonify('$(test.in7)') => $(test.out7) == $(test.expect7)"; "Expected canonify('$(test.in8)') => $(test.out8) == $(test.expect8)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata.cf.json.guess0000644000000000000000000000011515010704253026540 0ustar00rootroot00000000000000{ "x": [ 1, 2, 3 ], "y": "more data here", "z": { "300": 400 } } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/053.cf0000644000000000000000000000163115010704253023211 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,0,1,1,2,100); } ####################################################### bundle agent check { vars: "time" int => "90220"; classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/function_with_skipped_promise.cf0000644000000000000000000000157315010704253031044 0ustar00rootroot00000000000000# Make sure function is (not) evaluated in a promise (not) skipped via if # Redmine 6577 body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testdir)/." create => "true"; } bundle agent test { vars: "files" slist => { "want_file", "dont_want_file" }; classes: "want_file" expression => "any"; "test" expression => returnszero("$(G.touch) $(G.testdir)/$(files)", "noshell"), if => "$(files)"; } bundle agent check { classes: "$(test.files)_exists" expression => fileexists("$(G.testdir)/$(test.files)"); "ok" expression => "want_file_exists.!dont_want_file_exists"; reports: DEBUG.!ok:: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/045.cf0000644000000000000000000000256015010704253023214 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","X",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123.456", "$(nums)"); "ok" and => { "ok_list", "ok123", islessthan("$(test.sum)", "123.457"), isgreaterthan("$(test.sum)", "123.455") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/validdata.cf.json0000644000000000000000000000010515010704253025576 0ustar00rootroot00000000000000{ "test": [1,2,3,4], "test2": { "test3": 1 }, "test3": "Yes" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/062.x.cf0000644000000000000000000000171015010704253023455 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,1000,1000,1000,1001,40000); } ####################################################### bundle agent check { vars: "time" int => "2682100000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata-CFE-2551-2.cf0000644000000000000000000000415315010704253025761 0ustar00rootroot00000000000000# Test that merged data does not inherit variables from calling bundle body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2551" } string => "Test that merged data does not include variables from calling bundle."; vars: "a" string => "string a"; "b" string => "string b"; "vars1[a]" string => "$(a)"; "vars1[b]" string => "$(b)"; methods: # Call bundle that will define and merge it's own vars1 data structure. "Call another bundle" usebundle => called_by_bundle_test; } bundle agent called_by_bundle_test { vars: "c" string => "string c"; "vars1[c]" string => "$(c)"; # Create a new data structure NOT including data from calling bundle # This variant is expected to not work, because the data structure (this # bundles var1) cannot be referenced "bare" as the colon (:) makes the # data look like JSON. So the mergedata fails, and the merged_data_vars # isn't defined. "merged_data_vars" data => mergedata('{ "vars1": $(this.namespace):$(this.bundle).vars1 }'); DEBUG|EXTRA:: # We only care to stringify this if we need the debug reports "merged_data_vars_string" string => storejson( merged_data_vars ); reports: DEBUG|EXTRA:: "Got:$(const.n)$(merged_data_vars_string)"; "Expect merged_data_vars to be undefined."; } bundle agent check { classes: # We pass if the variable indicies found in bundle test are NOT found in # the bundle it called, and we find the index defined in the bundle it # called that we expect. "pass" not => isvariable("called_by_bundle_test.merged_data_vars"); # We fail if the variable indicies found in bundle test are also found in # the bundle it called. "fail" expression => isvariable( "called_by_bundle_test.merged_data_vars" ); reports: fail:: "$(this.promise_filename) FAIL"; pass:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/bundlesmatching.cf0000644000000000000000000000540615010704253026055 0ustar00rootroot00000000000000# Test that bundlesmatching works correctly body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { } bundle agent test { vars: "bundle_runs" slist => bundlesmatching("default:bundle_run.*"); "bundle_run_123s" slist => bundlesmatching("default:bundle_run_123.*"); "bundle_123" string => nth(bundle_run_123s, 0); "bundle_run_meta_deprecated_unsorted" slist => bundlesmatching("default:bundle_run_meta.*", "deprecated"); "bundle_run_meta_deprecated" slist => sort(bundle_run_meta_deprecated_unsorted, "lex"); "bundle_deprecated" string => nth(bundle_run_meta_deprecated, 0); "bundle_run_meta_obsoleted_unsorted" slist => bundlesmatching("default:bundle_run_meta.*", "obs.*", "deprecated"); "bundle_run_meta_obsoleted" slist => sort(bundle_run_meta_obsoleted_unsorted, "lex"); "bundle_obsoleted" string => nth(bundle_run_meta_obsoleted, 0); "count" int => length(bundle_runs); "123_count" int => length(bundle_run_123s); "deprecated_count" int => length(bundle_run_meta_deprecated); "obsoleted_count" int => length(bundle_run_meta_obsoleted); } bundle agent check { classes: "ok" and => { strcmp("$(test.count)", "6"), strcmp("$(test.123_count)", "1"), strcmp("$(test.deprecated_count)", "2"), strcmp("$(test.bundle_deprecated)", "default:bundle_run_meta_deprecated"), strcmp("$(test.obsoleted_count)", "1"), strcmp("$(test.bundle_obsoleted)", "default:bundle_run_meta_deprecated"), strcmp("$(test.bundle_123)", "default:bundle_run_123_456") }; reports: DEBUG:: "Bundle runs count $(test.count)"; "123 count $(test.123_count)"; "Deprecated count $(test.deprecated_count)"; "'obs.*' && deprecated count $(test.obsoleted_count)"; "Found bundles $(test.bundle_runs)"; "Found 123 bundles $(test.bundle_run_123s)"; "First 123 bundle is $(test.bundle_123)"; "Found deprecated bundles $(test.bundle_run_meta_deprecated)"; "First deprecated bundle is $(test.bundle_deprecated)"; "Found obsoleted bundles $(test.bundle_run_meta_obsoleted)"; "First obsoleted bundle is $(test.bundle_obsoleted)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } bundle agent bundle_run_123_456 { } bundle agent bundle_run_789_0ab { } bundle agent bundle_run_cde_fgh { } bundle agent bundle_run_meta_deprecated { meta: "tags" slist => { "deprecated", "obsoleted" }; } bundle agent bundle_run_meta_string_tags { meta: "tags" string => "deprecated"; } bundle agent bundle_run_meta_missing_tags { } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maparray.cf.expected.json0000644000000000000000000000661115010704253027271 0ustar00rootroot00000000000000{ "X": [ "1", "2", "3", "4", "5", "6" ], "Y": [ "1", "2", "3", "4" ], "jsonspec1": "{ \"key\": \"$(this.k)\", \"value\": \"$(this.v)\"", "jsonspec2": "{ \"key\": \"$(this.k)\", \"value\": \"$(this.v)\" }", "jsonspec3": "[ \"$(this.k)\", \"$(this.v)\" ]", "jsonspec4": "{ \"key\": \"$(this.k)\", \"key2\": \"$(this.k[1])\", \"value\": \"$(this.v)\" }", "justastring": "me", "load1": [ 1, 2, 3 ], "load2": [ "eleme\"nt1", "element2", "element3" ], "load3": { "x"x": "y\"y" }, "load4": [], "load5[anotherkey]": "anothervalue", "load5[lastkey!]": [ "o\"ne", "two", "three" ], "load5[mykey]": [ "myvalue" ], "load6": { "a": { "b": "c" } }, "maparray_1_1": [ "key = 0", "key = 1", "key = 2" ], "maparray_1_2": [ "key = 0, value = 1", "key = 1, value = 2", "key = 2, value = 3" ], "maparray_1_3": [ "key = 0, key2 = $(this.k[1]), value = 1", "key = 1, key2 = $(this.k[1]), value = 2", "key = 2, key2 = $(this.k[1]), value = 3" ], "maparray_1_4": [ "xvalue should be 0value", "xvalue should be 1value", "xvalue should be 2value" ], "maparray_2_1": [ "key = 0", "key = 1", "key = 2" ], "maparray_2_2": [ "key = 0, value = eleme\"nt1", "key = 1, value = element2", "key = 2, value = element3" ], "maparray_2_3": [ "key = 0, key2 = $(this.k[1]), value = eleme\"nt1", "key = 1, key2 = $(this.k[1]), value = element2", "key = 2, key2 = $(this.k[1]), value = element3" ], "maparray_2_4": [ "xvalue should be 0value", "xvalue should be 1value", "xvalue should be 2value" ], "maparray_3_1": [ "key = x\"x" ], "maparray_3_2": [ "key = x\"x, value = y\"y" ], "maparray_3_3": [ "key = x\"x, key2 = $(this.k[1]), value = y\"y" ], "maparray_3_4": [ "xvalue should be xxvalue" ], "maparray_4_1": [], "maparray_4_2": [], "maparray_4_3": [], "maparray_4_4": [], "maparray_5_1": [ "key = anotherkey", "key = lastkey!", "key = mykey" ], "maparray_5_2": [ "key = anotherkey, value = anothervalue", "key = lastkey!, value = o\"ne", "key = lastkey!, value = three", "key = lastkey!, value = two", "key = mykey, value = myvalue" ], "maparray_5_3": [ "key = anotherkey, key2 = $(this.k[1]), value = anothervalue", "key = lastkey!, key2 = $(this.k[1]), value = o\"ne", "key = lastkey!, key2 = $(this.k[1]), value = three", "key = lastkey!, key2 = $(this.k[1]), value = two", "key = mykey, key2 = $(this.k[1]), value = myvalue" ], "maparray_5_4": [ "xvalue should be anothervalue", "xvalue should be lastvalue", "xvalue should be myvalue" ], "maparray_6_1": [ "key = a" ], "maparray_6_2": [ "key = a, value = c" ], "maparray_6_3": [ "key = a, key2 = b, value = c" ], "maparray_6_4": [ "xvalue should be avalue" ], "spec1": "key = $(this.k)", "spec2": "key = $(this.k), value = ${this.v}", "spec3": "key = $(this.k), key2 = $(this.k[1]), value = ${this.v}", "spec4": "xvalue should be $(static[$(this.k)])", "static[0]": "0value", "static[1]": "1value", "static[2]": "2value", "static[a]": "avalue", "static[anotherkey]": "anothervalue", "static[lastkey!]": "lastvalue", "static[mykey]": "myvalue", "static[x"x]": "xxvalue", "static[x]": "xvalue" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/031.cf0000644000000000000000000000275415010704253023214 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456 789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/312.cf0000644000000000000000000000213215010704253023204 0ustar00rootroot00000000000000# # Test escape() - issue 689 # body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { vars: "t1" string => escape("1,2"); "e1" string => "1,2"; "t2" string => escape("{1,2}"); "e2" string => "{1,2}"; } bundle agent check { classes: "ok1" expression => regcmp("$(test.t1)", "$(test.e1)"); "ok2" expression => regcmp("$(test.t2)", "$(test.e2)"); "ok" and => { "ok1", "ok2" }; reports: DEBUG:: "Comparing actual vs. expected:"; DEBUG.ok1:: "'$(test.t1)' is the same as '$(test.e1)'"; DEBUG.!ok1:: "'$(test.t1)' is NOT the same as '$(test.e1)'"; DEBUG.ok2:: "'$(test.t2)' is the same as '$(test.e2)'"; DEBUG.!ok2:: "'$(test.t2)' is NOT the same as '$(test.e2)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string_mustache.cf0000644000000000000000000000221015010704253026073 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "desert" string => "Sahara"; "state2" data => parsejson('{"x": 1, "y": [{"item": 2}, {"item": 3}, {"item": 4}]}'); } bundle agent test { vars: "out11" string => string_mustache("desert = {{vars.init.desert}}"); "out21" string => string_mustache("desert = {{vars.init.desert}}", "init.state2"); "out22" string => string_mustache("x = {{x}}", "init.state2"); "out23" string => string_mustache("{{#y}}{{item}} {{/y}}", "init.state2"); "inline" string => string_mustache("{{#y}}{{item}} {{/y}}", '{ "y": [{"item": 2}, {"item": 3}, {"item": 4}]}'); "badref" string => string_mustache("desert = {{vars.init.desert}}", nosuch); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_readstringarray.cf0000644000000000000000000000273315010704253027100 0ustar00rootroot00000000000000# Redmine#2926: test long lines with readstringarrayidx() body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "params" data => data_readstringarray("$(this.promise_filename).txt", "\s*#[^\n]*", ";", 9999, 99999); "params_str" string => format("%S", params); "pk" slist => getindices(params); reports: DEBUG:: "params: $(params_str)"; } bundle agent check { vars: "dim" int => length("test.params"); "length" int => length("test.pk"); "last" string => nth("test.value", 599); classes: "ok1" expression => strcmp($(dim), "3"); "ok2" expression => strcmp($(dim), $(length)); "ok3" expression => strcmp("$(test.params[not_working_app_config][0])", "9123"); "ok" and => { "ok1", "ok2", "ok3" }; reports: DEBUG.ok1:: "passed1"; DEBUG.ok2:: "passed2"; DEBUG.ok3:: "passed3"; DEBUG.!ok1:: "failed1 $(dim) != 3"; DEBUG.!ok2:: "failed2 $(dim) != $(length)"; DEBUG.!ok3:: "failed3 $(test.params[not_working_app_config][0]) != 9123"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/030.cf0000644000000000000000000000266215010704253023211 0ustar00rootroot00000000000000####################################################### # # Test readintlist() with reals # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; "789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok1" not => strcmp("123.456", "$(nums)"); "ok2" not => strcmp("123", "$(nums)"); # One failure and the readintlist aborts parsing the rest "ok3" not => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok1", "ok2", "ok3" }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readstringarrayidx_order.cf0000644000000000000000000000775615010704253030021 0ustar00rootroot00000000000000####################################################### # # Acceptance test for RedMine 6466. # # Order and duplication in data should be preserved. # Based on an initial test by Neil Watson. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: # Note: order is deliberately one unlikely to happen # automatically; and there are duplicates. "file" slist => { "1 ;; other field 1", "2 ;; other field 2", "4 ;; other field 4", "8 ;; other field 8", "16 ;; other field 16", "2 ;; other field 2", "3 ;; other field 3", "6 ;; other field 6", "12 ;; other field 12", "9 ;; other field 9", "18 ;; other field 18", "3 ;; other field 3", "5 ;; other field 5", "10 ;; other field 10", "15 ;; other field 15", "5 ;; other field 5", "7 ;; other field 7", "14 ;; other field 14", "7 ;; other field 7", "0 ;; other field 0" }; files: "$(G.testfile).orig.txt" create => 'true', edit_defaults => empty, edit_line => insert_all_lines( "@{file}" ); } ####################################################### # Insert lines, preserving duplicates: bundle edit_line insert_all_lines(lines) { vars: "whole" string => join(" ", "lines"); insert_lines: "$(whole)" insert_type => "preserve_block"; } ####################################################### bundle agent test { vars: "num" int => readstringarrayidx("mylines", "$(G.testfile).orig.txt", "\s*#[^\n]*", "\s*;;\s*", 50, 9999); "file" slist => { "${mylines[0][0]} ;; ${mylines[0][1]}", "${mylines[1][0]} ;; ${mylines[1][1]}", "${mylines[2][0]} ;; ${mylines[2][1]}", "${mylines[3][0]} ;; ${mylines[3][1]}", "${mylines[4][0]} ;; ${mylines[4][1]}", "${mylines[5][0]} ;; ${mylines[5][1]}", "${mylines[6][0]} ;; ${mylines[6][1]}", "${mylines[7][0]} ;; ${mylines[7][1]}", "${mylines[8][0]} ;; ${mylines[8][1]}", "${mylines[9][0]} ;; ${mylines[9][1]}", "${mylines[10][0]} ;; ${mylines[10][1]}", "${mylines[11][0]} ;; ${mylines[11][1]}", "${mylines[12][0]} ;; ${mylines[12][1]}", "${mylines[13][0]} ;; ${mylines[13][1]}", "${mylines[14][0]} ;; ${mylines[14][1]}", "${mylines[15][0]} ;; ${mylines[15][1]}", "${mylines[16][0]} ;; ${mylines[16][1]}", "${mylines[17][0]} ;; ${mylines[17][1]}", "${mylines[18][0]} ;; ${mylines[18][1]}", "${mylines[19][0]} ;; ${mylines[19][1]}" }; files: "$(G.testfile).copy.txt" create => 'true', edit_defaults => empty, edit_line => insert_all_lines( "@{file}" ); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).copy.txt", "$(G.testfile).orig.txt", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/443.cf0000644000000000000000000000603315010704253023215 0ustar00rootroot00000000000000####################################################### # # Test readstringarrayidx(), introduce a non-parsed comment # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 # Not parsed as a comment this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "4"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "# Not parsed as a comment"), strcmp("$(test.ary[2][0])", "this"), strcmp("$(test.ary[2][1])", "is"), strcmp("$(test.ary[2][2])", "a"), strcmp("$(test.ary[2][3])", "test"), strcmp("$(test.ary[3][0])", "1"), strcmp("$(test.ary[3][1])", "2"), strcmp("$(test.ary[3][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][1]"), isvariable("test.ary[2][4]"), isvariable("test.ary[3][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/444.cf0000644000000000000000000001153615010704253023222 0ustar00rootroot00000000000000####################################################### # # Test readstringarrayidx(), add some weird indices (including a duplicate) # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "9"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "# A duplicate follows"), strcmp("$(test.ary[6][1])", " this line is not always a comment"), strcmp("$(test.ary[7][0])", "this"), strcmp("$(test.ary[7][1])", "also"), strcmp("$(test.ary[8][0])", "last"), strcmp("$(test.ary[8][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = '# A duplicate follows', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ' this line is not always a comment', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'this', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'also', saw '$(test.ary[7][1])'"; "expected test.ary[8][0] = 'last', saw '$(test.ary[8][0])'"; "expected test.ary[8][1] = 'one', saw '$(test.ary[8][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.uppercase.txt0000644000000000000000000002400115010704253027701 0ustar00rootroot00000000000000ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJ cfengine-3.24.2/tests/acceptance/01_vars/02_functions/221.cf0000644000000000000000000000216315010704253023207 0ustar00rootroot00000000000000####################################################### # # Test grep(), size 0, local slist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true"; } ####################################################### bundle agent test { vars: "array" slist => { "One", "Two", "Three", "Four", "Five" }; "vals" slist => grep("Z.*", "array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/setop_unique_difference_intersection.cf0000644000000000000000000000416115010704253032363 0ustar00rootroot00000000000000####################################################### # # Test unique(), difference() and intersection() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "a" slist => { "x", "y", "z" }; "b" slist => { "100", "9", "10" }; "c" slist => { }; "d" slist => { "" }; "e" slist => { "x" }; "f" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; } ####################################################### bundle agent test { vars: "list1" slist => { "a", "b", "c", "d", "e", "f" }; "list2" slist => { "a", "b", "c", "d", "e", "f" }; "unique_$(list1)" slist => unique("init.$(list1)"); "difference_$(list1)_$(list2)" slist => difference("init.$(list1)", "init.$(list2)"); "intersection_$(list1)_$(list2)" slist => intersection("init.$(list1)", "init.$(list2)"); "unique_inline_array" slist => unique('[ "one", "b", "one", "q" ]'); "unique_inline_object" slist => unique('{ "one": "b", "c": "q", "d": "one" }'); "difference_inline_$(list1)" slist => difference('[ "one", "b", "one", "q" ]', "init.$(list2)"); "intersection_$(list1)_inline" slist => intersection("init.$(list1)", '[ "one", "b", "one", "q" ]'); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } parsestringarray_dontread_comment_duplicate_lastline2.cf0000644000000000000000000001055415010704253035640 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test parsestringarray(), don't read comment, duplicate key or last line # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","NoComment",":",6,1000); "num" int => "6"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "bad" or => { isvariable("test.ary[6][0]"), isvariable("test.ary[6][1]"), isvariable("test.ary[7][0]"), isvariable("test.ary[7][1]"), isvariable("test.ary[8][0]"), isvariable("test.ary[8][1]"), }; "ok" and => { "!bad", strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/filesexist-is-collecting.cf0000644000000000000000000000416115010704253027614 0ustar00rootroot00000000000000####################################################### # # Test that filesexist() can check for presence of files containing hashes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "test_files" slist => { "example4567", "example123" }; files: "$(G.testdir)/$(test_files)" create => "true"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-2744" } string => "Test that filesexist works as a collecting function"; classes: "filesexist_slist_identifier_ok" expression => filesexist( "init.test_files" ), scope => "namespace"; "filesexist_slist_ref_ok" expression => filesexist( @(init.test_files) ), scope => "namespace"; "filesexist_findfiles_ok" expression => filesexist( findfiles( "$(G.testdir)/example*" ) ), scope => "namespace"; "filesexist_json_array_ok" expression => filesexist( '[ "example4567", "example123" ]' ), scope => "namespace"; } ####################################################### bundle agent check { classes: "ok" and => { "filesexist_slist_identifier_ok", "filesexist_slist_ref_ok", "filesexist_findfiles_ok", "filesexist_json_array_ok" }; reports: DEBUG|EXTRA:: "Test files: $(init.test_files)"; "filesexist() doesn't work with an slist identifier" if => not( "filesexist_slist_identifier_ok" ); "filesexist() doesn't work with an slist reference" if => not( "filesexist_slist_ref_ok" ); "filesexist() doesn't work properly with a nested findfiles() call" if => not( "filesexist_findfiles_ok" ); "filesexist() doesn't work with a JSON array" if => not( "filesexist_json_array_ok" ); ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/204.cf0000644000000000000000000000305415010704253023210 0ustar00rootroot00000000000000####################################################### # # Test getindices(), size 5 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "alpha"; "beta"; "gamma's"; "delta-delta:delta"; "last"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "array[beta]" string => "two"; "array[gamma's]" string => "three's"; "array[delta-delta:delta]" string => "four-fore:quatre"; "array[last]" string => "last"; "keys" slist => getindices("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(keys)"; } bundle edit_line test_insert { vars: "keys" slist => { @{test.keys} }; insert_lines: "$(keys)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maplist.cf.expected.json0000644000000000000000000000106115010704253027120 0ustar00rootroot00000000000000{ "empty": [], "mapped_empty": [], "mapped_function1": [ " zero", " two", " three's", "four-fore:", " last" ], "mapped_function2": [ "a_or_b", "b_and_c", "c_d", "e" ], "mapped_function_empty": [], "mapped_inline": [ "value=a", "value=b", "value=c" ], "mapped_testlist": [ "value=zero", "value=two", "value=three's", "value=four-fore:quatre", "value=last" ], "testlist": [ "zero", "two", "three's", "four-fore:quatre", "last" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string_replace.cf.expected.json0000644000000000000000000000060515010704253030453 0ustar00rootroot00000000000000{ "empty": "", "empty2": "", "match_none": "abdc", "match_none2": "abcdefghij\\t\\n", "match_once": "ABCd", "match_twice": "hellohello", "overlap": "yesa", "replace": "abcdefghij\\r\\n", "replace2": "abcdeftEsT\\n", "replace3": "no", "special": "1{}[].*?", "special2": "()\\1[].*?", "special3": "(){}[]\\2", "test": "abcdefghij\\t\\n", "test2": "(){}[].*?" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/regex_replace.cf0000644000000000000000000000520315010704253025506 0ustar00rootroot00000000000000####################################################### # # Test regex_replace function # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "test" string => "abcdefghij"; # replace the empty string with empty string, globally "void" string => regex_replace($(test), "", "", "g"); # replace any character with empty string, globally "void1" string => regex_replace($(test), ".", "", "g"); # replace the empty string with 'x', globally (matches on character boundaries) "void2" string => regex_replace($(test), "", "x", "g"); # replace the whole string "allofitwithTEST" string => regex_replace($(test), ".*", "TEST", ""); # no matches, original intact "nomatch" string => regex_replace($(test), "nonesuch", "TEST", "g"); "nomatch2" string => regex_replace($(test), "nonesuch", "TEST\1\2\3\4\5\6\7\8\9", "g"); # replace any character with -DOT- "dots_everywhere" string => regex_replace($(test), ".", "-DOT-", "g"); # capture any three characters and replace with a backreference "cap123" string => regex_replace($(test), "(...)", "[cap=$1]", "g"); # capture any three characters and replace with a backreference "cap123_backslash" string => regex_replace($(test), "(...)", "[cap=\1]", "g"); # note that this is the same as above because the CFE parser tries to be clever in this case, converting \\1 to \1 "cap123_backslash2" string => regex_replace($(test), "(...)", "[cap=\\1]", "g"); "cap123_backslashes1to9missing" string => regex_replace($(test), "...", "[cap=\1\2\3\4\5\6\7\8\9]", "g"); "cap123_backslashes1to9havesome" string => regex_replace($(test), "(.)(.)(.)", "[cap=\1\2\3\4\5\6\7\8\9]", "g"); # match ABC case-insensitive and replace with ABC "simple_nocase" string => regex_replace($(test), "ABC", "ABC", "gi"); # case-insensitive # match abc and replace with ABC "simple" string => regex_replace($(test), "abc", "ABC", "g"); # empty cases "empty1" string => regex_replace("", "abc", "ABC", "g"); "empty2" string => regex_replace("", "abc", "", "g"); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata-CFE-2551-1.cf0000644000000000000000000000456715010704253025771 0ustar00rootroot00000000000000# Test that merged data does not inherit variables from calling bundle body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2551" } string => "Test that merged data does not include variables from calling bundle. Variant specifying bundle qualified variable"; vars: "a" string => "string a"; "b" string => "string b"; "vars1[a]" string => "$(a)"; "vars1[b]" string => "$(b)"; methods: # Call bundle that will define and merge it's own vars1 data structure. "Call another bundle" usebundle => called_by_bundle_test; } bundle agent called_by_bundle_test { vars: "c" string => "string c"; "vars1[c]" string => "$(c)"; # Create a new data structure NOT including data from calling bundle # NOTE: This is what differs from the base test "merged_data_vars" data => mergedata('{ "vars1": $(this.bundle).vars1 }'); DEBUG|EXTRA:: # We only care to stringify this if we need the debug reports "merged_data_vars_string" string => storejson( merged_data_vars ); reports: DEBUG|EXTRA:: "Got:$(const.n)$(merged_data_vars_string)"; 'Expect: { "vars1": { "c": "string c" } }'; } bundle agent check { classes: # We pass if the variable indicies found in bundle test are NOT found in # the bundle it called, and we find the index defined in the bundle it # called that we expect. "pass" expression => and( and( not( isvariable("called_by_bundle_test.merged_data_vars[vars1][a]")), not( isvariable("called_by_bundle_test.merged_data_vars[vars1][b]")) ), isvariable("called_by_bundle_test.merged_data_vars[vars1][c]") ); # We fail if the variable indicies found in bundle test are also found in # the bundle it called. "fail" or => { isvariable( "called_by_bundle_test.merged_data_vars[vars1][a]" ), isvariable( "called_by_bundle_test.merged_data_vars[vars1][b]" ), }; reports: fail:: "$(this.promise_filename) FAIL"; pass:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/310.cf0000644000000000000000000000317715010704253023214 0ustar00rootroot00000000000000####################################################### # # Test escape() - basic tests # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "t1" string => escape("foo"); "e1" string => "foo"; "t2" string => escape("foo.baz"); "e2" string => "foo.baz"; "t3" string => escape("foo[baz]"); "e3" string => "foo[baz]"; "t4" string => escape("(fo?o|baz)+x{3}y*"); "e4" string => "(fo?o|baz)+x{3}y*"; "t5" string => escape("~`!@#%&_=\"';:,/<>"); "e5" string => "~`!@#%&_=\"';:,/<>"; } ####################################################### bundle agent check { classes: "ok" and => { regcmp("$(test.t1)", "$(test.e1)"), regcmp("$(test.t2)", "$(test.e2)"), regcmp("$(test.t3)", "$(test.e3)"), regcmp("$(test.t4)", "$(test.e4)"), regcmp("$(test.t5)", "$(test.e5)"), }; reports: DEBUG:: "Comparing actual vs. expected:"; "'$(test.t1)' vs. '$(test.e1)'"; "'$(test.t2)' vs. '$(test.e2)'"; "'$(test.t3)' vs. '$(test.e3)'"; "'$(test.t4)' vs. '$(test.e4)'"; "'$(test.t5)' vs. '$(test.e5)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/reverse.cf.expected.json0000644000000000000000000000014515010704253027124 0ustar00rootroot00000000000000{ "inline": [ "r", "p", "q" ], "sa": [ "a", "b", "c" ], "sb": [] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string_split_2k_variable.cf0000644000000000000000000000600115010704253027660 0ustar00rootroot00000000000000bundle agent main { vars: any:: "test_str" string => "147.228.4.62#443:www.afs2010.civ.zcu.cz www.agt.zcu.cz www.ah2015.zcu.cz www.ait.fdu.zcu.cz www.akv.zcu.cz www.albumjuristarum.zcu.cz www.amp.zcu.cz www.quiz.zcu.cz www.app.fdu.zcu.cz www.arnica.zcu.cz www.aud.zcu.cz www.audio.zcu.cz www.bedekr.fdu.zcu.cz www.beeronomics2019.zcu.cz www.beyondai.zcu.cz www.caduv.cz www.camop.zcu.cz www.canut.zcu.cz www.careercentre.zcu.cz www.cars.fdu.zcu.cz www.centem.zcu.cz www.chat2014.zcu.cz www.cidam.zcu.cz www.cvts.zcu.cz www.daah.zcu.cz www.dask.zcu.cz www.db-webz.zcu.cz www.dceryasynovenilu.zcu.cz www.dd-uwb-esiee.zcu.cz www.deti.zcu.cz www.diagnostika.zcu.cz www.didap.zcu.cz www.digipod.zcu.cz www.direct.zcu.cz www.disco.zcu.cz www.dispecink.zcu.cz www.dode.fek.zcu.cz www.eb-vyztymdp.zcu.cz www.economics.zcu.cz www.edom.zcu.cz www.eduproeu.zcu.cz www.edutest.zcu.cz www.ehotrod.zcu.cz www.elektromotorsport.zcu.cz www.elmon.fel.zcu.cz www.eltech.fel.zcu.cz www.envirogis.fpe.zcu.cz www.esecc.zcu.cz www.esf.kfi.zcu.cz www.esn.zcu.cz www.fel-utef.zcu.cz www.flab.zcu.cz www.florbal.zcu.cz www.frodja.zcu.cz www.futsal.zcu.cz www.gapps.zcu.cz www.gcindy.zcu.cz www.ha30.zcu.cz www.hb2014.ntc.zcu.cz www.hcenat.zcu.cz www.historie.zcu.cz www.hss.zcu.cz www.hsvv.zcu.cz www.icmd2016.zcu.cz www.inem.fek.zcu.cz www.info-studium.zcu.cz www.infoplatforma.zcu.cz www.informace.zcu.cz www.integrita.zcu.cz www.interdisciplinarita.zcu.cz www.ish2015.zcu.cz www.iso690.zcu.cz www.kee.zcu.cz www.kev.zcu.cz www.kohout.zcu.cz www.konstruktiv.zcu.cz www.kvk2.zcu.cz www.kvnt.zcu.cz www.kvpr.kks.zcu.cz www.lego.zcu.cz www.logickehry.zcu.cz www.lsfek.zcu.cz www.lsipc.zcu.cz www.masekjan.zcu.cz www.mobility.fpe.zcu.cz www.mobility.fpr.zcu.cz www.mojefavka.zcu.cz www.mojepc.zcu.cz www.multilab.fdu.zcu.cz www.mupic.eu www.nacelnik.civ.zcu.cz www.ocv.fzs.zcu.cz www.pc.fpe.zcu.cz www.pes.zcu.cz www.pf.zcu.cz www.pgs.zcu.cz www.pilinterreg.zcu.cz www.pilsencube.zcu.cz www.pir.fel.zcu.cz www.pldsdev.zcu.cz www.pohybovapruprava.zcu.cz www.poplatky.zcu.cz www.ppa2017.zcu.cz www.pracesdaty.zcu.cz www.profilzadavatele.zcu.cz www.projekt-minos.zcu.cz www.prvakoviny.zcu.cz www.radio.zcu.cz www.rcths.zcu.cz www.robotipk.zcu.cz www.ropovportal.zcu.cz www.rozvrhy.fpe.zcu.cz www.ruskecentrum.zcu.cz www.sauron6.zcu.cz www.scicom.zcu.cz www.ska.zcu.cz www.speedtest.zcu.cz www.stf2013.zcu.cz www.strojarna.zcu.cz www.studentskeotazniky.zcu.cz www.studykom.zcu.cz www.summon.zcu.cz www.sutnarka.zcu.cz www.svoc.fel.zcu.cz www.svoc.zcu.cz www.talent.zcu.cz www.technicka-ekologie.zcu.cz www.tfz.zcu.cz www.tvp.zcu.cz www.unipranet.zcu.cz www.usa.fek.zcu.cz www.usk.zcu.cz www.uspoint.zcu.cz www.veletrh.zcu.cz www.virtualbody.zcu.cz www.westernstars.zcu.cz www.wittgenstein.zcu.cz www.zkusebna.zcu.cz$(const.n)147.228.4.60#443:www.pit-plzen.zcu.cz"; "test_list" -> { "CFE-3047" } # Promise to ticket that we don't crash slist => string_split("$(test_str)", "\n", "5" ); # Segment 1 is truncated reports: any:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/501.cf0000644000000000000000000000462715010704253023217 0ustar00rootroot00000000000000####################################################### # # Test readintarray(), introduce 777 12345 with no other fields # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 12345 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readintarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[12345][0])", "12345"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[12345][1]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[12345][0] = '12345', saw '$(test.ary[12345][0])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/on.cf0000644000000000000000000000135615010704253023322 0ustar00rootroot00000000000000####################################################### # # Test on(), especially integer out of bounds on some Unices # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "unix_timestamp" int => on(2014, 7 , 21 , 23 , 13 ,0); } ####################################################### bundle agent check { classes: "ok" expression => isvariable("test.unix_timestamp"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sum_and_product.cf.expected.json0000644000000000000000000000110115010704253030630 0ustar00rootroot00000000000000{ "empty_list": [], "empty_list_product": "1.000000", "empty_list_sum": "0.000000", "empty_object": { }, "empty_object_product": "1.000000", "empty_object_sum": "0.000000", "inline_array_product": "0.000000", "inline_array_sum": "3.000000", "inline_object_product": "2.000000", "inline_object_sum": "3.000000", "normal_list": [ "1", "2", "3" ], "normal_list_product": "6.000000", "normal_list_sum": "6.000000", "normal_object": { "a": 1, "b": 2 }, "normal_object_product": "2.000000", "normal_object_sum": "3.000000" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/445.cf0000644000000000000000000001153715010704253023224 0ustar00rootroot00000000000000####################################################### # # Test parsestringarray(), weird indices, duplicate and trailing newlines # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one "; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "9"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "# A duplicate follows"), strcmp("$(test.ary[6][1])", " this line is not always a comment"), strcmp("$(test.ary[7][0])", "this"), strcmp("$(test.ary[7][1])", "also"), strcmp("$(test.ary[8][0])", "last"), strcmp("$(test.ary[8][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = '# A duplicate follows', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ' this line is not always a comment', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'this', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'also', saw '$(test.ary[7][1])'"; "expected test.ary[8][0] = 'last', saw '$(test.ary[8][0])'"; "expected test.ary[8][1] = 'one', saw '$(test.ary[8][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/447.cf0000644000000000000000000001151215010704253023217 0ustar00rootroot00000000000000####################################################### # # Test parsestringarray(), weird indices, change comment parsing # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","",":",10,1000); "num" int => "9"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "# A duplicate follows"), strcmp("$(test.ary[6][1])", " this line is not always a comment"), strcmp("$(test.ary[7][0])", "this"), strcmp("$(test.ary[7][1])", "also"), strcmp("$(test.ary[8][0])", "last"), strcmp("$(test.ary[8][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = '# A duplicate follows', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ' this line is not always a comment', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'this', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'also', saw '$(test.ary[7][1])'"; "expected test.ary[8][0] = 'last', saw '$(test.ary[8][0])'"; "expected test.ary[8][1] = 'one', saw '$(test.ary[8][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/version_compare.cf0000644000000000000000000000666015010704253026104 0ustar00rootroot00000000000000########################################################### # # Test version_compare function # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: "true_a" string => version_compare("1.0.0", "=", "1.0.0"); "true_b" string => version_compare("0.1.0", "=", "0.1.0"); "true_c" string => version_compare("0.0.1", "=", "0.0.1"); "true_d" string => version_compare("1.0.1", "!=", "1.0.0"); "true_e" string => version_compare("0.0.0", "==", "0.0.0"); "true_f" string => version_compare("1.2.3", ">", "1.1.999"); "true_g" string => version_compare("1.2.3", ">", "1.1.999"); "true_h" string => version_compare("1.2.3", "!=", "1.1.999"); "true_i" string => version_compare("0.0.0", "<", "0.0.1"); "true_j" string => version_compare("0.0.0", "<=", "0.0.1"); "true_k" string => version_compare("0.0.0", "!=", "0.0.1"); "true_l" string => version_compare("0.0.0", "<=", "0.0.1"); "true_m" string => version_compare("7.7.7", "==", "7.7.7-1"); "true_n" string => version_compare("7.7.7-1", "==", "7.7.7-2"); "true_o" string => version_compare("7.7.7a", "==", "7.7.7"); "true_p" string => version_compare("7.7.7a", ">=", "7.7.7"); "true_q" string => version_compare("7.7.7a", "<=", "7.7.7"); "true_r" string => version_compare("3.2.1", "==", "3.2"); "true_s" string => version_compare("3", "=", "3.2.1"); "true_t" string => version_compare("3.2", "<=", "3"); "false_a" string => version_compare("1.0.0", "!=", "1.0.0"); "false_b" string => version_compare("0.1.0", "!=", "0.1.0"); "false_c" string => version_compare("0.0.1", "!=", "0.0.1"); "false_d" string => version_compare("1.0.1", "=", "1.0.0"); "false_e" string => version_compare("0.0.0", "!=", "0.0.0"); "false_f" string => version_compare("1.2.3", "<=", "1.1.999"); "false_g" string => version_compare("1.2.3", "<=", "1.1.999"); "false_h" string => version_compare("1.2.3", "=", "1.1.999"); "false_i" string => version_compare("0.0.0", ">=", "0.0.1"); "false_j" string => version_compare("0.0.0", ">", "0.0.1"); "false_k" string => version_compare("0.0.0", "==", "0.0.1"); "false_l" string => version_compare("0.0.0", ">", "0.0.1"); "false_m" string => version_compare("7.7.7", "!=", "7.7.7-1"); "false_n" string => version_compare("7.7.7-1", "!=", "7.7.7-2"); "false_o" string => version_compare("7.7.7a", "!=", "7.7.7"); "false_p" string => version_compare("7.7.7a", "<", "7.7.7"); "false_q" string => version_compare("7.7.7a", ">", "7.7.7"); "false_r" string => version_compare("3.2.1", "!=", "3.2"); "false_s" string => version_compare("3", "!=", "3.2.1"); "false_t" string => version_compare("3.2", ">", "3"); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/regextract.cf0000644000000000000000000000277215010704253025061 0ustar00rootroot00000000000000####################################################### # # Test regextract # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "text" string => "node-01-10.0"; classes: "parsed_text" expression => regextract("^\w+-(\d+)-(\d+\.\d+)", "$(text)", "pair"); reports: DEBUG.!parsed_text:: "Failed to parse $(text)"; } ####################################################### bundle agent test { vars: "lefts" string => "$(init.pair[1])"; "lefti" int => "$(init.pair[1])"; "rights" string => "$(init.pair[2])"; "rightr" real => "$(init.pair[2])"; } ####################################################### bundle agent check { classes: "sok" expression => strcmp("$(test.lefts):$(test.rights)", "01:10.0"); "iok" expression => strcmp("$(test.lefti)", "1"); "rok" expression => strcmp("$(test.rightr)", "10.000000"); "ok" and => { "sok", "iok", "rok" }; reports: DEBUG.!iok:: "Parsed integer '$(test.lefti)' isn't 1"; DEBUG.!rok:: "Parsed real '$(test.rightr)' isn't 10.000000"; DEBUG.!sok:: "Parsed numbers '$(test.lefts)' and '$(test.rights)' aren't '01' and '10.0'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/701.cf0000644000000000000000000000131115010704253023204 0ustar00rootroot00000000000000# Test that countclassesmatching works correctly (Mantis #975) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { classes: "test_fbeae67f3e347b5e0032302200141131" expression => "any"; "test_fbeae67f3e347b5e0032302200141131_1" expression => "any"; } bundle agent test { vars: "num" int => countclassesmatching("test_fbeae67f3e347b5e0032302200141131.*"); } bundle agent check { classes: "ok" expression => strcmp("$(test.num)", "2"); reports: DEBUG:: "$(test.num)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getvalues_returns_all_values_for_given_datacontainer_index_merging_strings.cf0000644000000000000000000000240415010704253042214 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test getvalues() returns all values for a given # datacontainer index merging strings. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data" data => ' { "foo": [ "alpha", "bravo" ], "bar": "zulu" }'; "data2" data => ' { "foo": [ null, "bravo" ], "zed": { "quu": "something else" }, "bar": null, "bar2": 1233333 }'; "data3" data => '[ "foo", null, "bravo", { "bar": "barista" } ]'; } ####################################################### bundle agent test { vars: "values_data" slist => getvalues("init.data"); "values_data2" slist => getvalues("init.data2"); "values_data3" slist => getvalues("init.data3"); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readtcp_connection_fail.cf.sub0000644000000000000000000000023215010704253030322 0ustar00rootroot00000000000000body common control { bundlesequence => { "tcpread" }; } bundle agent tcpread { vars: 'trace_output' string => readtcp('127.0.0.1', '1', '', 1); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues.cf.expected.json0000644000000000000000000000075415010704253027456 0ustar00rootroot00000000000000{ "inline_values_array": [ "foo", "1", "bar", "2" ], "inline_values_map": [ "1", "2" ], "user[dirs]": [ "/home/zamboni", "/tmp/zamboni", "/export/home/zamboni" ], "user[fullname][first]": "Diego", "user[fullname][last]": "Zamboni", "user[name]": "zamboni", "uservalues": [ "Diego", "Zamboni" ], "values": [ "Diego", "Zamboni", "/home/zamboni", "/tmp/zamboni", "/export/home/zamboni", "zamboni" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/042.cf0000644000000000000000000000276715010704253023222 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456"; "789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.tail27.txt0000644000000000000000000000003415010704253027014 0ustar00rootroot00000000000000TUVWXYZ0123456789abcdefghij cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getindices.cf0000644000000000000000000000437615010704253025031 0ustar00rootroot00000000000000####################################################### # # Test that getindices on an array variable will resolve to 2 levels # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### # Do not change the name of this bundle or of variables inside this bundle. The # original bug CFE-2397 depended on a certain order in the variable table which # was triggered by these names. bundle common b { vars: "d[k]" string => "val1"; "d[f][f1]" string => "val2"; "d[s][s1]" string => "val3"; "d_keys" slist => getindices("d"); "d_keys_f" slist => getindices("d[f]"); "d_keys_s" slist => getindices("d[s]"); "c[$(d_keys)]" string => "$(d[$(d_keys)])"; "c[f][$(d_keys_f)]" string => "$(d[f][$(d_keys_f)])"; "c[s][$(d_keys_s)]" string => "$(d[s][$(d_keys_s)])"; "c_keys" slist => getindices("c"); "c_keys_f" slist => getindices("c[f]"); "c_keys_s" slist => getindices("c[s]"); } bundle agent test { vars: "user[name]" string => "zamboni"; "user[fullname][first]" string => "Diego"; "user[fullname][last]" string => "Zamboni"; "user[dirs]" slist => { "/home/zamboni", "/tmp/zamboni", "/export/home/zamboni" }; "fields" slist => getindices("user"); "userfields" slist => getindices("user[fullname]"); "inline_fields" slist => getindices('{ "foo": 1, "bar": 2 }'); "inline_numfields" slist => getindices('[ "foo", 1, "bar", 2 ]'); "inline_function" slist => getindices(parsejson('{ "a": "b", "c": "d" }')); "c_keys" slist => { @(b.c_keys) }; "c_keys_f" slist => { @(b.c_keys_f) }; "c_keys_s" slist => { @(b.c_keys_s) }; } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/validdata.cf.inv.json0000644000000000000000000000007215010704253026374 0ustar00rootroot00000000000000{ "test" : [1,2,3,4], "test2" : { }, "test3" : { } { cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_regextract.cf0000644000000000000000000000366515010704253026054 0ustar00rootroot00000000000000# data_regextract() test body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { vars: "patterns" data => parsejson('["^(?...)(...)(..)-(?...)-(..).*", "", ".*", "(?...)"]'); "plength" int => length(patterns); "pi" slist => expandrange("[0-$(plength)]", 1); # this is one more than the valid indices "strings" data => parsejson('[ "abcdef12-345-67andsoon", "", "!!!", "one two three"]'); "slength" int => length(strings); "si" slist => expandrange("[0-$(slength)]", 1); # this is one more than the valid indices "parsed_$(pi)_$(si)" data => data_regextract(nth(patterns, $(pi)), nth(strings, $(si))); "parsed_$(pi)_$(si)_str" string => format("%S", "parsed_$(pi)_$(si)"); reports: EXTRA:: "$(this.bundle): $(pi) $(si) '$(patterns[$(pi)])' matching '$(strings[$(si)])' => $(parsed_$(pi)_$(si)_str)"; } bundle agent check { vars: "actual" string => " 0 0 $(test.parsed_0_0_str) 1 0 $(test.parsed_1_0_str) 1 1 $(test.parsed_1_1_str) 1 2 $(test.parsed_1_2_str) 1 3 $(test.parsed_1_3_str) 2 0 $(test.parsed_2_0_str) 2 1 $(test.parsed_2_1_str) 2 2 $(test.parsed_2_2_str) 2 3 $(test.parsed_2_3_str) 3 0 $(test.parsed_3_0_str) 3 2 $(test.parsed_3_2_str) 3 3 $(test.parsed_3_3_str) "; "expected" string => ' 0 0 {"0":"abcdef12-345-67andsoon","2":"def","3":"12","5":"67","name1":"abc","name2":"345"} 1 0 {"0":""} 1 1 {"0":""} 1 2 {"0":""} 1 3 {"0":""} 2 0 {"0":"abcdef12-345-67andsoon"} 2 1 {"0":""} 2 2 {"0":"!!!"} 2 3 {"0":"one two three"} 3 0 {"0":"abc","myword":"abc"} 3 2 {"0":"!!!","myword":"!!!"} 3 3 {"0":"one","myword":"one"} '; methods: "" usebundle => dcs_check_strcmp($(actual), $(expected), $(this.promise_filename), "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getindices_with_multi_index_arrays.cf0000644000000000000000000000363315010704253032041 0ustar00rootroot00000000000000########################################################### # # Test that multiple getindices only get the specified keys # Redmine#6779 # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ########################################################### bundle agent init { } ########################################################### bundle agent test { vars: "bundle_config[dir][dir_test1]" string => "dir_test1"; "bundle_config[dir][dir_test2]" string => "dir_test2"; "bundle_config[lnk][lnk_test1]" string => "lnk_test1"; "bundle_config[lnk][lnk_test2]" string => "lnk_test2"; "dir_keys" slist => getindices("bundle_config[dir]"); "lnk_keys" slist => getindices("bundle_config[lnk]"); "dir_keys_sorted" slist => sort("dir_keys", "lex"); "lnk_keys_sorted" slist => sort("lnk_keys", "lex"); "dir_keys_str" string => join(",", "dir_keys_sorted"); "lnk_keys_str" string => join(",", "lnk_keys_sorted"); } ########################################################### bundle agent check { vars: "expected_dir_keys" string => "dir_test1,dir_test2"; "expected_lnk_keys" string => "lnk_test1,lnk_test2"; classes: "ok_dir_keys" expression => strcmp($(expected_dir_keys), $(test.dir_keys_str)); "ok_lnk_keys" expression => strcmp($(expected_lnk_keys), $(test.lnk_keys_str)); "ok" and => { "ok_dir_keys", "ok_lnk_keys" }; reports: DEBUG:: "dir_keys = '$(test.dir_keys_str)', expected = '$(expected_dir_keys)'"; "lnk_keys = '$(test.lnk_keys_str)', expected = '$(expected_lnk_keys)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maparray.cf0000644000000000000000000000460415010704253024521 0ustar00rootroot00000000000000####################################################### # # Test maparray() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "load1" data => parsejson('[ 1, 2, 3]'); "load2" slist => { "eleme\"nt1", "element2", "element3" }; "load3" data => parsejson('{ "x\\"x": "y\\"y" }'); "load4" data => parsejson('[]'); "load5[mykey]" slist => { "myvalue" }; "load5[anotherkey]" string => "anothervalue"; "load5[lastkey!]" slist => { "o\"ne", "two", "three" }; "load6" data => parsejson('{ "a": { "b": "c" } }'); "static[x]" string => "xvalue"; "static[x\"x]" string => "xxvalue"; "static[0]" string => "0value"; "static[1]" string => "1value"; "static[2]" string => "2value"; "static[lastkey!]" string => "lastvalue"; "static[anotherkey]" string => "anothervalue"; "static[mykey]" string => "myvalue"; "static[a]" string => "avalue"; "spec1" string => "key = $(this.k)"; "spec2" string => "key = $(this.k), value = ${this.v}"; "spec3" string => "key = $(this.k), key2 = $(this.k[1]), value = ${this.v}"; "spec4" string => "xvalue should be $(static[$(this.k)])"; "jsonspec1" string => '{ "key": "$(this.k)", "value": "$(this.v)"'; "jsonspec2" string => '{ "key": "$(this.k)", "value": "$(this.v)" }'; "jsonspec3" string => '[ "$(this.k)", "$(this.v)" ]'; "jsonspec4" string => '{ "key": "$(this.k)", "key2": "$(this.k[1])", "value": "$(this.v)" }'; "X" slist => { "1", "2", "3", "4", "5", "6" }; "Y" slist => { "1", "2", "3", "4" }; "maparray_$(X)_$(Y)" slist => sort(maparray("$(spec$(Y))", "load$(X)")); "bad2" slist => maparray("", missingvar); "justastring" string => "me"; "bad4" slist => maparray("", justastring); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/702.cf0000644000000000000000000000136315010704253023214 0ustar00rootroot00000000000000# Test maplist expansion with ${this} syntax (Mantis #1249) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { vars: "s" slist => { "suffix" }; } bundle agent test { vars: "list1" slist => maplist("prefix${this}", "init.s"); "list2" slist => maplist("prefix$(this)", "init.s"); } bundle agent check { classes: "ok" and => { reglist("@(test.list1)", "prefixsuffix"), reglist("@(test.list2)", "prefixsuffix") }; reports: DEBUG:: "list1 => $(test.list1)"; "list2 => $(test.list2)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/countlinesmatching_errors_on_absent_file.cf0000644000000000000000000000255615010704253033232 0ustar00rootroot00000000000000####################################################### # # Test countlinesmatching() errors when file is absent # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### ####################################################### bundle agent test { meta: "description" -> { "CFE-3234" } string => "Test that the agent emits error output when countlinesmatching() is used on a file that is inaccessible."; "test_skip_needs_work" string => "windows", meta => { "CFE-3234" }; vars: "subout" string => execresult("$(sys.cf_agent) -Kv --define AUTO -f $(this.promise_dirname)/countlinesmatching_returns_0_on_inaccessable_file.cf 2>&1 | $(G.grep) countlinesmatching", "useshell"); } ####################################################### bundle agent check { vars: "expression" string => ".* error: File '/asd/fgh/qwertyio0p' could not be read in countlinesmatching.*"; classes: "__pass" expression => regcmp( $(expression), $(test.subout) ); methods: __pass:: "Pass" usebundle => dcs_pass( $(this.promise_filename) ); !__pass:: "FAIL" usebundle => dcs_pass( $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/410.cf0000644000000000000000000000501015010704253023201 0ustar00rootroot00000000000000####################################################### # # Test readstringarray(), add some weird indices, real comments, character limit # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","^#.*",":+",10,14); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "bad" or => { isvariable("test.ary[he][1]"), isvariable("test.ary[blank][0]"), }; "ok" and => { "!bad", strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[he][0])", "he"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "saw 'bad'-class things"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[he][0] = 'he', saw '$(test.ary[he][0])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/047.cf0000644000000000000000000000301115010704253023206 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123,,,456,789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata-CFE-2551-0.cf0000644000000000000000000000452515010704253025762 0ustar00rootroot00000000000000# Test that merged data does not inherit variables from calling bundle body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2551" } string => "Test that merged data does not include variables from calling bundle."; "test_soft_fail" string => "any", meta => { "CFE-2551"}; vars: "a" string => "string a"; "b" string => "string b"; "vars1[a]" string => "$(a)"; "vars1[b]" string => "$(b)"; methods: # Call bundle that will define and merge it's own vars1 data structure. "Call another bundle" usebundle => called_by_bundle_test; } bundle agent called_by_bundle_test { vars: "c" string => "string c"; "vars1[c]" string => "$(c)"; # Create a new data structure NOT including data from calling bundle "merged_data_vars" data => mergedata('{ "vars1": vars1 }'); DEBUG|EXTRA:: # We only care to stringify this if we need the debug reports "merged_data_vars_string" string => storejson( merged_data_vars ); reports: DEBUG|EXTRA:: "Got:$(const.n)$(merged_data_vars_string)"; 'Expect: { "vars1": { "c": "string c" } }'; } bundle agent check { classes: # We pass if the variable indicies found in bundle test are NOT found in # the bundle it called, and we find the index defined in the bundle it # called that we expect. "pass" expression => and( and( not( isvariable("called_by_bundle_test.merged_data_vars[vars1][a]")), not( isvariable("called_by_bundle_test.merged_data_vars[vars1][b]")) ), isvariable("called_by_bundle_test.merged_data_vars[vars1][c]") ); # We fail if the variable indicies found in bundle test are also found in # the bundle it called. "fail" or => { isvariable( "called_by_bundle_test.merged_data_vars[vars1][a]" ), isvariable( "called_by_bundle_test.merged_data_vars[vars1][b]" ), }; reports: fail:: "$(this.promise_filename) FAIL"; pass:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/inline_json.cf0000644000000000000000000000356715010704253025223 0ustar00rootroot00000000000000########################################################### # # Test inline JSON expansion # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: "z" string => "100"; "foo" string => "bar"; # test mergedata() as well "var" data => mergedata('[]', '["x"]'); # test mapdata() as well "var2" data => mapdata("none", '$(this.v)', '["x"]'); # the basic building block "var3" data => data_expand('["linux"]'); # variable references with a bundle "var4" data => data_expand('[test.var3]'); "var5" data => data_expand('[test.var3,]'); # make sure bareword keys are not expanded "var6" data => data_expand('[foo]'); "var7" data => data_expand('{foo:var3}'); # variable references without a bundle "var8" data => data_expand('[var3]'); "var9" data => data_expand('{ "x": var3 }'); # regular lookup with bundle name into a map value "varA" data => data_expand('{ "fullx": test.var3 }'); # try to trigger off-by-one errors "varB" data => data_expand('[z]'); # intentionally broken to try to trigger off-by-one errors "varC" data => data_expand('[z'); # inline array lookup "varD" data => data_expand('[var3[0]]'); "varE" data => data_expand('[varA[fullx]]'); "varF" data => data_expand('[var9[x]]'); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/format.cf0000644000000000000000000000744515010704253024203 0ustar00rootroot00000000000000####################################################### # # Test formatint(), formatreal(), and formatstring() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_defaults => empty, edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "key='c32' value='(unhandled format)'"; "key='c107' value='(unhandled format)'"; "key='int100' value='100'"; "key='string100' value='100'"; "key='int0100' value='0100'"; "key='string0100' value='0100'"; "key='real200' value='200.0'"; "key='string200' value='200.0'"; "key='real0200_00' value='0200.00'"; "key='string0200_00' value='0200.00'"; "key='stringabc' value='abc'"; "key='string6abc' value=' abc'"; "key='string-6abc' value='abc '"; "key='2strings-6abc-6def' value='abc def '"; "key='S_empty_list' value='{ }'"; "key='badend' value='ends badly '"; "key='escape' value='% should be a single percent'"; "key='S_123_list' value='{ \"one\", \"two\", \"\\\"three\\\"\" }'"; "key='S_container_1' value='[null]'"; "key='S_container_2' value='[{\"x\":123},\"yz\"]'"; } ####################################################### bundle agent test { vars: "array[c32]" string => format("%c", 32); "array[c107]" string => format("%c", 107); "array[int100]" string => format("%d", 100); "array[string100]" string => format("%d", "100"); "array[int0100]" string => format("%04d", 100); "array[string0100]" string => format("%04d", "100"); "array[real200]" string => format("%.1f", 200); "array[string200]" string => format("%.1f", "200.00"); "array[real0200_00]" string => format("%07.2f", 200); "array[string0200_00]" string => format("%07.2f", "200.00"); "array[stringabc]" string => format("%s", "abc"); "array[string6abc]" string => format("%6s", "abc"); "array[string-6abc]" string => format("%-6s", "abc"); "array[2strings-6abc-6def]" string => format("%-6s%-6s", "abc", "def"); "array[badend]" string => format("ends badly %"); "array[escape]" string => format("%% should be a single percent"); # %S specifier "mydata" string => 'simplest data'; "emptylist" slist => {}; "list123" slist => { "one", "two", '"three"'}; "mycontainer1" data => parsejson("[ null ]"); "mycontainer2" data => parsejson('[ { "x": 123 }, "yz" ]'); "array[S_string]" string => format("prefix %S suffix", "simple data"); "array[S_var]" string => format("%S", $(mydata)); "array[S_empty_list]" string => format("%S", emptylist); "array[S_123_list]" string => format("%S", list123); "array[S_container_1]" string => format("%S", mycontainer1); "array[S_container_2]" string => format("%S", mycontainer2); "formatted" slist => maparray("key='$(this.k)' value='$(this.v)'", "array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(formatted)"; } bundle edit_line test_insert { vars: "formatted" slist => { @{test.formatted} }; insert_lines: "$(formatted)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/025.cf0000644000000000000000000000266015010704253023213 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123"; "456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string_trim.cf0000644000000000000000000000221315010704253025240 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "abcd1" string => string_trim("abcd"); "abcd2" string => string_trim(" abcd"); "abcd3" string => string_trim("abcd "); "abcd4" string => string_trim(" abcd "); "abcd5" string => string_trim("abcd "); "abcd6" string => string_trim(" abcd"); "abcd7" string => string_trim(" abcd "); "abcd_abcd" string => string_trim(" abcd abcd "); # empty cases "empty1" string => string_trim(""); "empty2" string => string_trim(" "); "empty3" string => string_trim(" "); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/read_empty_file.cf0000644000000000000000000000207315010704253026033 0ustar00rootroot00000000000000# Test that empty file is successfully read by readfile() function body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" create => "true"; } bundle agent test { vars: "value1" string => readfile("$(G.testfile)", 10000); "value2" string => readfile("$(G.testfile)", 0); } bundle agent check { classes: "ok1" expression => strcmp("$(test.value1)", ""); "ok2" expression => strcmp("$(test.value2)", ""); "not_ok1" not => strcmp("$(test.value1)", ""); "not_ok2" not => strcmp("$(test.value2)", ""); "ok" and => { "ok1", "ok2" }; reports: DEBUG.ok1:: "passed1: '$(test.value1)' == ''"; DEBUG.ok2:: "passed2: '$(test.value1)' == ''"; DEBUG.not_ok1:: "failed1: '$(test.value1)' != ''"; DEBUG.not_ok2:: "failed2: '$(test.value2)' != ''"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getindices_returns_empty_list_if_datacontainer_index_has_no_key_values.cf0000644000000000000000000000333215010704253041313 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test that getindices() returns an empy list if used # on a datacontainer index that has no key values. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data" data => parsejson('{ "foo": [ "alpha", "bravo" ], "bar": "zulu" }'); } ####################################################### bundle agent test { meta: "test_soft_fail" string => "!any", meta => { "redmine7116" }; vars: "values_data" slist => getindices("init.data[bar]"); } ####################################################### bundle agent check { vars: "expected_elements" slist => { }; "diff1" slist => difference( "test.values_data", expected_elements ); "diff2" slist => difference( expected_elements, "test.values_data"); "len_values_data" int => length( "test.values_data" ); "len_diff1" int => length(diff1); "len_diff2" int => length(diff2); classes: "ok" expression => strcmp( $(len_diff1), $(len_diff2) ); reports: DEBUG:: "DEBUG: data value: '$(test.values_data)'"; "DEBUG: expected value: '$(expected_elements)'"; "DEBUG: length of test.values_data: '$(len_values_data)'"; "DEBUG: found '$(diff1)' in test.values_data, but not in expected_elements"; "DEBUG: found '$(diff2)' in expected_elements, but not in test.values_data"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_readstringarrayidx.cf0000644000000000000000000000364015010704253027603 0ustar00rootroot00000000000000# Redmine#2926: test long lines with readstringarrayidx() body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "params" data => data_readstringarrayidx("$(this.promise_filename).txt", "\s*#[^\n]*", ";", 9999, 99999); "params_str" string => format("%S", params); "pk" slist => getindices(params); reports: DEBUG:: "params: $(params_str)"; } bundle agent check { vars: "dim" int => length("test.params"); "length" int => length("test.pk"); "last" string => nth("test.value", 599); "pluck_23" data => mergedata("test.params[22]"); "pluck_24" data => mergedata("test.params[23]"); classes: "ok1" expression => strcmp($(dim), "24"); "ok2" expression => strcmp($(dim), $(length)); "ok3" expression => strcmp("$(test.params[2][0])", "not_working_app_config"); "ok4" expression => strcmp("$(pluck_24[0])", "LAST"); "ok5" expression => strcmp("$(pluck_23[0])", "NEXT-TO-LAST"); "ok" and => { "ok1", "ok2", "ok3", "ok4", "ok5" }; reports: DEBUG.ok1:: "passed1"; DEBUG.ok2:: "passed2"; DEBUG.ok3:: "passed3"; DEBUG.ok4:: "passed4"; DEBUG.ok5:: "passed5"; DEBUG.!ok1:: "failed1 $(dim) != 24"; DEBUG.!ok2:: "failed2 $(dim) != $(length)"; DEBUG.!ok3:: "failed3 $(test.params[2][0]) != not_working_app_config"; DEBUG.!ok4:: "failed4 $(pluck_24[0]) != LAST"; DEBUG.!ok5:: "failed5 $(pluck_23[0]) != NEXT-TO-LAST"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/hash.cf0000644000000000000000000001632615010704253023634 0ustar00rootroot00000000000000####################################################### # # Test hash() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "base_null" string => ""; "base_easy" string => "test"; "base_hard" string => 'This is a test of the hash function!";'; "strings" slist => { "null", "easy", "hard" }; "$(strings)" string => "$(base_$(strings)) "; methods: "make $(strings)" usebundle => file_make("$(G.testfile).$(strings).txt", "$(base_$(strings))"); } ####################################################### bundle agent test { meta: "test_skip_needs_work" string => "windows"; vars: "algos" slist => { "md5", "sha1", "sha256", "sha384", "sha512" }; # XXX # What do we do about testing the crypt hash-type? # "null_$(algos)" string => hash("$(init.null)", $(algos)); # Cfengine does not expand most \ characters, so use Perl :-) "easy_$(algos)" string => hash("$(init.easy)", $(algos)); "hard_$(algos)" string => hash("$(init.hard)", $(algos)); } ####################################################### bundle agent check { vars: "null_md5" string => "68b329da9893e34099c7d8ad5cb9c940"; "null_sha1" string => "adc83b19e793491b1c6ea0fd8b46cd9f32e592fc"; "null_sha256" string => "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b"; "null_sha384" string => "ec664e889ed6c1b2763cacf7899d95b7f347373eb982e523419feea3aa362d891b3bf025f292267a5854049091789c3e"; "null_sha512" string => "be688838ca8686e5c90689bf2ab585cef1137c999b48c70b92f67a5c34dc15697b5d11c982ed6d71be1e1e7f7b4e0733884aa97c3f7a339a8ed03577cf74be09"; "easy_md5" string => "d8e8fca2dc0f896fd7cb4cb0031ba249"; "easy_sha1" string => "4e1243bd22c66e76c2ba9eddc1f91394e57f9f83"; "easy_sha256" string => "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2"; "easy_sha384" string => "109bb6b5b6d5547c1ce03c7a8bd7d8f80c1cb0957f50c4f7fda04692079917e4f9cad52b878f3d8234e1a170b154b72d"; "easy_sha512" string => "0e3e75234abc68f4378a86b3f4b32a198ba301845b0cd6e50106e874345700cc6663a86c1ea125dc5e92be17c98f9a0f85ca9d5f595db2012f7cc3571945c123"; "hard_md5" string => "e80a705b338f8bd4e2525a2cec846233"; "hard_sha1" string => "305636f0563c179c71955612bff716648d2aa9bf"; "hard_sha256" string => "fbfa93af3ddc81df9f812a6d2eff1a40d53160692c81f9f8cfffa9b4562a1749"; "hard_sha384" string => "712843c71d5ca0b6a2b663251b8b5d08abe5fb55adc4445e6fdf759e5429a98f2c762a0f82612d4e42c4703474b58eb5"; "hard_sha512" string => "c9d45d2669a941d4e5014ac291fd0cac0c7717604476416cad118898f238a2887057269e70ac5cad972cf5b8cbb0673e985285b0cc69810d4fee507b8b89067c"; "algos" slist => { @(test.algos) }; "strings" slist => { @(init.strings) }; classes: "ok_$(strings)_$(algos)" expression => strcmp("$(test.$(strings)_$(algos))", "$($(strings)_$(algos))"); "not_ok_$(strings)_$(algos)" not => strcmp("$(test.$(strings)_$(algos))", "$($(strings)_$(algos))"); "ok_hmatch_$(strings)_$(algos)" expression => hashmatch("$(G.testfile).$(strings).txt", $(algos), "$($(strings)_$(algos))"); "not_ok_hmatch_$(strings)_$(algos)" not => hashmatch("$(G.testfile).$(strings).txt", $(algos), "$($(strings)_$(algos))"); "ok_filehash_$(strings)_$(algos)" expression => strcmp(file_hash("$(G.testfile).$(strings).txt", $(algos)), "$($(strings)_$(algos))"); "not_ok_filehash_$(strings)_$(algos)" not => strcmp(file_hash("$(G.testfile).$(strings).txt", $(algos)), "$($(strings)_$(algos))"); "ok_null" and => { "ok_null_md5", "ok_null_sha1", "ok_null_sha256", "ok_null_sha384", "ok_null_sha512", }; "ok_easy" and => { "ok_easy_md5", "ok_easy_sha1", "ok_easy_sha256", "ok_easy_sha384", "ok_easy_sha512", }; "ok_hard" and => { "ok_hard_md5", "ok_hard_sha1", "ok_hard_sha256", "ok_hard_sha384", "ok_hard_sha512", }; "ok_hmatch_null" and => { "ok_hmatch_null_md5", "ok_hmatch_null_sha1", "ok_hmatch_null_sha256", "ok_hmatch_null_sha384", "ok_hmatch_null_sha512", }; "ok_hmatch_easy" and => { "ok_hmatch_easy_md5", "ok_hmatch_easy_sha1", "ok_hmatch_easy_sha256", "ok_hmatch_easy_sha384", "ok_hmatch_easy_sha512", }; "ok_hmatch_hard" and => { "ok_hmatch_hard_md5", "ok_hmatch_hard_sha1", "ok_hmatch_hard_sha256", "ok_hmatch_hard_sha384", "ok_hmatch_hard_sha512", }; "ok_filehash_null" and => { "ok_filehash_null_md5", "ok_filehash_null_sha1", "ok_filehash_null_sha256", "ok_filehash_null_sha384", "ok_filehash_null_sha512", }; "ok_filehash_easy" and => { "ok_filehash_easy_md5", "ok_filehash_easy_sha1", "ok_filehash_easy_sha256", "ok_filehash_easy_sha384", "ok_filehash_easy_sha512", }; "ok_filehash_hard" and => { "ok_filehash_hard_md5", "ok_filehash_hard_sha1", "ok_filehash_hard_sha256", "ok_filehash_hard_sha384", "ok_filehash_hard_sha512", }; methods: "" usebundle => dcs_passif_expected("ok_null,ok_easy,ok_hard,ok_filehash_null,ok_filehash_easy,ok_filehash_hard,ok_hmatch_null,ok_hmatch_easy,ok_hmatch_hard", "", $(this.promise_filename)), inherit => "true"; reports: DEBUG:: "$(strings) / $(algos) failed, $(test.$(strings)_$(algos)) != $($(strings)_$(algos)) (original = $(init.$(strings)))" if => "not_ok_$(strings)_$(algos)"; "$(strings) / $(algos) hashmatch failed $($(strings)_$(algos)) against $(G.testfile).$(strings).txt" if => "not_ok_hmatch_$(strings)_$(algos)"; "$(strings) / $(algos) file_hash failed $($(strings)_$(algos)) against $(G.testfile).$(strings).txt" if => "not_ok_filehash_$(strings)_$(algos)"; EXTRA:: "$(strings) / $(algos) is OK" if => "ok_$(strings)_$(algos)"; "$(strings) / $(algos) hashmatch is OK" if => "ok_hmatch_$(strings)_$(algos)"; "$(strings) / $(algos) file_hash is OK" if => "ok_filehash_$(strings)_$(algos)"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_expand.cf0000644000000000000000000000155715010704253025161 0ustar00rootroot00000000000000########################################################### # # Test data_expand() # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: "x" string => "foo"; "y" int => "200"; "load_unexpanded" data => readjson("$(this.promise_filename).json", inf); "load_expanded" data => data_expand(load_unexpanded); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/003.cf0000644000000000000000000000273715010704253023214 0ustar00rootroot00000000000000####################################################### # # Test countlinesmatching() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "zero_regex" string => "impossible line"; "one_regex" string => "root:.*"; "positive_regex" string => ".*:\d+:.*"; "zero" int => countlinesmatching("$(zero_regex)", "$(G.etc_passwd)"); "one" int => countlinesmatching("$(one_regex)", "$(G.etc_passwd)"); "positive" int => countlinesmatching("$(positive_regex)", "$(G.etc_passwd)"); } ####################################################### bundle agent check { classes: "ok" and => { strcmp("$(test.zero)", "0"), strcmp("$(test.one)", "1"), isgreaterthan("$(test.positive)", "1"), }; reports: DEBUG:: "Expected 0 matches to '$(test.zero_regex)', found $(test.zero)"; "Expected 1 matches to '$(test.one_regex)', found $(test.one)"; "Expected >1 matches to '$(test.positive_regex)', found $(test.positive)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata-json-strings.cf.expected0000644000000000000000000000003615010704253031067 0ustar00rootroot00000000000000{ "one": "1", "two": "2" }cfengine-3.24.2/tests/acceptance/01_vars/02_functions/063.x.cf0000644000000000000000000000171015010704253023456 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,1000,1000,1000,1000,40001); } ####################################################### bundle agent check { vars: "time" int => "2682100000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/execresult_multiples.cf.sub0000644000000000000000000000073015010704253027752 0ustar00rootroot00000000000000############################################################################## # # Redmine #2981: execresult and returnszero should not be run so much # ############################################################################## body common control { bundlesequence => {"example"}; } bundle agent example { classes: "y" expression => returnszero("/bin/echo CLASSONCE", "noshell"); vars: "x" string => execresult("/bin/echo RETONCE", "noshell"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata_yaml.cf0000644000000000000000000000236415010704253025475 0ustar00rootroot00000000000000########################################################### # # Test readdata() with YAML # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: feature_yaml:: "explicit_yaml" data => readdata("$(this.promise_filename).yaml", "YAML"); "extension_yaml" data => readdata("$(this.promise_filename).yaml", "auto"); "extension_yml" data => readdata("$(this.promise_filename).yml", "auto"); "guess_yaml" data => readdata("$(this.promise_filename).yaml.guess", "auto"); # should be empty (JSON is attempted) "failed_explicit_yaml" data => readdata($(this.promise_filename), "YAML"); } ########################################################### bundle agent check { methods: feature_yaml:: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); !feature_yaml:: "check" usebundle => dcs_pass($(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/nth.cf0000644000000000000000000000600215010704253023470 0ustar00rootroot00000000000000####################################################### # # Test nth() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "results" slist => { "starting list = 1", "starting list = 2", "starting list = 3", "starting list = one", "starting list = two", "starting list = three", "starting list = long string", "starting list = four", "starting list = fix", "starting list = six", "starting list = one", "starting list = two", "starting list = three", "element #0 of the test list: 1", "element #1 of the test list: 2", "element #10 of the test list: one", "element #11 of the test list: two", "element #2 of the test list: 3", "element #6 of the test list: long string", "element #-1 of the test list: three", "element #-13 of the test list: 1", "element #-6 of the test list: four", }; files: "$(G.testfile).expected" create => "true", edit_defaults => init_empty, edit_line => init_insert; } body edit_defaults init_empty { empty_file_before_editing => "true"; edit_backup => "false"; } bundle edit_line init_insert { insert_lines: "$(init.results)"; } ####################################################### bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "nth" slist => { 1, 2, 6, 10, 11, 1000, "-1", "-13", "-6", "-1000" }; "test[$(nth)]" string => nth("test", $(nth)); "test[0]" string => nth("test", 0); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "starting list = $(test.test)"; "element #$(test.nth) of the test list: $(test.test[$(test.nth)])"; "element #0 of the test list: $(test.test[0])"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/storejson.cf0000644000000000000000000000150215010704253024725 0ustar00rootroot00000000000000# Test that the storejson() function will convert a data container back to JSON body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "mylist" slist => { "x", "y" }; "data" data => parsejson('{ "x": [ 1, 2, 3 ] }'); "datas" string => storejson(data); "data_from_slist" string => storejson(mylist); "data_from_inline" string => storejson('{ "a": "b" }'); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata_yaml.cf.yaml.guess0000644000000000000000000000010115010704253027546 0ustar00rootroot00000000000000--- x: 100 y: - 1 - 2 - a - b - c: 200 300 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/inline_json.cf.expected.json0000644000000000000000000000105715010704253027763 0ustar00rootroot00000000000000{ "foo": "bar", "var": [ "x" ], "var2": [ "x" ], "var3": [ "linux" ], "var4": [ [ "linux" ] ], "var5": [ [ "linux" ] ], "var6": [ "bar" ], "var7": { "foo": [ "linux" ] }, "var8": [ [ "linux" ] ], "var9": { "x": [ "linux" ] }, "varA": { "fullx": [ "linux" ] }, "varB": [ "100" ], "varD": [ "linux" ], "varE": [ [ "linux" ] ], "varF": [ [ "linux" ] ], "z": "100" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/read_sys_file.cf0000644000000000000000000000407015010704253025512 0ustar00rootroot00000000000000# Redmine#1032: Test that /sys and /proc files with 0 length are successfully read by readfile() function body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { classes: "have_sys" expression => fileexists("/sys/kernel/vmcoreinfo"); "have_proc0" expression => fileexists("/proc/meminfo"); "have_proc1" expression => fileexists("/proc/kallsyms"); vars: have_sys:: "sys_info" string => readfile("/sys/kernel/vmcoreinfo", 0); !have_sys:: "sys_info" string => "42"; have_proc0:: "proc0_info" string => readfile("/proc/meminfo", 0); !have_proc0:: "proc0_info" string => "42"; have_proc1:: "proc1_info" string => readfile("/proc/kallsyms", 0); !have_proc1:: "proc1_info" string => "42"; } bundle agent check { classes: "ok_proc0" expression => regcmp(".*\d+.*", $(test.proc0_info)); "ok_proc1" expression => regcmp(".*\d+.*", $(test.proc1_info)); "not_ok_proc0" not => regcmp(".*\d+.*", $(test.proc0_info)); "not_ok_proc1" not => regcmp(".*\d+.*", $(test.proc1_info)); "ok_sys" expression => regcmp(".*\d+.*", $(test.sys_info)); "not_ok_sys" not => regcmp(".*\d+.*", $(test.sys_info)); "ok" not => classmatch("not_ok_.+"); reports: DEBUG:: "/proc0 test OK" if => "ok_proc0"; "/proc1 test OK" if => "ok_proc1"; "/sys test OK" if => "ok_sys"; "/proc0 test NOT OK: data '$(test.proc0_info)' did not contain digits" if => "not_ok_proc0"; "/proc1 test NOT OK: data '$(test.proc1_info)' did not contain digits" if => "not_ok_proc1"; "/sys test NOT OK: data '$(test.sys_info)' did not contain digits" if => "not_ok_sys"; DEBUG.inform_mode:: "/proc0 test got data '$(test.proc0_info)'"; "/proc1 test got data '$(test.proc1_info)'"; "/sys test got data '$(test.sys_info)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mustach_doesnt_render_null.cf0000644000000000000000000000174715010704253030323 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" string => "Test that mustache doesn't render nulls that don't exist (CFE-2077)"; vars: "jsondata" data => parsejson('{ "key" : ["one", "two", "three"]}'); "noninstersecting_list" slist => { "four" }; "list" slist => getvalues("jsondata[key]"); "diff_list" slist => difference("list", "noninstersecting_list"); "diff_string" string => join(" ", diff_list); "mustache_string" string => string_mustache("{{#vars.test.diff_list}}{{{.}}} {{/vars.test.diff_list}}"); } bundle agent check { methods: "check" usebundle => dcs_check_regcmp("one two three ", $(test.mustache_string), $(this.promise_filename), "no"); reports: DEBUG|EXTRA:: "Diff string: $(test.diff_string)"; "Mustache string: $(test.mustache_string)"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/038.cf0000644000000000000000000000266215010704253023221 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123"; "456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maparray_mixed.cf.expected0000644000000000000000000000313115010704253027501 0ustar00rootroot00000000000000{ "commands": [ "server 172.27.82.22 iburst key 232 # kali01", "server 172.27.82.23 iburst key 232 # kali02", "server 172.27.82.24 iburst key 232 # kali03" ], "i": [ "kali01", "kali02", "kali03" ], "key[kali01]": "key", "key[kali02]": "key", "key[kali03]": "key", "ntp": { "kali01": { "address": "172.27.82.22", "key": "232", "serverkey": "213", "trustedkey": [ "232", "242", "252" ] }, "kali02": { "address": "172.27.82.23", "key": "232", "serverkey": "213", "trustedkey": [ "232", "242", "252" ] }, "kali03": { "address": "172.27.82.24", "key": "232", "serverkey": "213", "trustedkey": [ "232", "242", "252" ] } }, "ntp_servers": "\n { \"kali01\":\n { \"address\" : \"172.27.82.22\",\n \"key\" : \"232\",\n \"trustedkey\" : [ \"232\", \"242\", \"252\" ],\n \"serverkey\" : \"213\"\n },\n \"kali02\":\n { \"address\" : \"172.27.82.23\",\n \"key\" : \"232\",\n \"trustedkey\" : [ \"232\", \"242\", \"252\" ],\n \"serverkey\" : \"213\"\n },\n \"kali03\":\n { \"address\" : \"172.27.82.24\",\n \"key\" : \"232\",\n \"trustedkey\" : [ \"232\", \"242\", \"252\" ],\n \"serverkey\" : \"213\"\n }\n }" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/050.cf0000644000000000000000000000303015010704253023201 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456.789"; # Is is a real or a set of ints? } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\.",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/basename_1.cf0000644000000000000000000001202515010704253024674 0ustar00rootroot00000000000000####################################################### # # Test basename() without suffix # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: # The tests starting with template will be tested with both types of # directory separators on Windows. "template_input[root]" string => "/"; "template_expected[root]" string => "/"; "template_input[simple]" string => "/foo/bar"; "template_expected[simple]" string => "bar"; "template_input[slash]" string => "/foo/bar/"; "template_expected[slash]" string => "bar"; "template_input[sub]" string => "/foo"; "template_expected[sub]" string => "foo"; "template_input[subslash]" string => "/foo/"; "template_expected[subslash]" string => "foo"; "template_input[dot]" string => "/foo/."; "template_expected[dot]" string => "."; "template_input[dot_subslash]" string => "/foo/./"; "template_expected[dot_subslash]" string => "."; "template_input[multi]" string => "/foo/bar/baz"; "template_expected[multi]" string => "baz"; "template_input[multislash]" string => "/foo/bar/baz/"; "template_expected[multislash]" string => "baz"; "template_input[more]" string => "/a/b/c/d/e/f/g/h/i"; "template_expected[more]" string => "i"; "template_input[multislash]" string => "/a///b////c///"; "template_expected[multislash]" string => "c"; # Note: no template, because backslashes will be interpreted as UNC path on Windows. "input[multislash_start]" string => "//a///b////c///"; "expected[multislash_start]" string => "c"; "template_input[rel_one]" string => "foo"; "template_expected[rel_one]" string => "foo"; "template_input[rel_more]" string => "foo/bar"; "template_expected[rel_more]" string => "bar"; "template_input[rel_one_subslash]" string => "foo/"; "template_expected[rel_one_subslash]" string => "foo"; "template_input[rel_more_subslash]" string => "foo/bar/"; "template_expected[rel_more_subslash]" string => "bar"; "template_input[rel_dot]" string => "foo/."; "template_expected[rel_dot]" string => "."; "template_input[rel_only_dot]" string => "./"; "template_expected[rel_only_dot]" string => "."; "template_input[rel_multislash]" string => "a///b////c///"; "template_expected[rel_multislash]" string => "c"; "template_input[noop]" string => ""; "template_expected[noop]" string => ""; "template_keys" slist => getindices("template_input"); windows:: "template_input[full_root]" string => "C:/"; "template_expected[full_root]" string => "/"; "template_input[full_root_file]" string => "C:/foo"; "template_expected[full_root_file]" string => "foo"; "template_input[full_root_file_subslash]" string => "C:/foo/"; "template_expected[full_root_file_subslash]" string => "foo"; "template_input[full_file]" string => "C:/foo/bar"; "template_expected[full_file]" string => "bar"; "template_input[full_file_subslash]" string => "C:/foo/bar/"; "template_expected[full_file_subslash]" string => "bar"; "template_input[dir]" string => "C:foo"; "template_expected[dir]" string => "foo"; "template_input[two_dirs]" string => "C:foo/bar"; "template_expected[two_dirs]" string => "bar"; "template_input[dir_subslash]" string => "C:foo/"; "template_expected[dir_subslash]" string => "foo"; "template_input[two_dirs_subslash]" string => "C:foo/bar/"; "template_expected[two_dirs_subslash]" string => "bar"; # UNC paths don't have forward slash equivalents. "input[native_unc_one]" string => "\\\\foo"; "expected[native_unc_one]" string => "foo"; "input[native_unc_two]" string => "\\\\foo\\bar"; "expected[native_unc_two]" string => "bar"; "input[native_unc_three]" string => "\\\\foo\\bar\\charlie\\"; "expected[native_unc_three]" string => "charlie"; any:: "input[native_$(template_keys)]" string => "$(template_input[$(template_keys)])"; "expected[native_$(template_keys)]" string => "$(template_expected[$(template_keys)])"; "keys" slist => getindices("input"); "actual[$(keys)]" string => basename("$(input[$(keys)])"); } ####################################################### bundle agent check { vars: "keys" slist => { @(test.keys) }; classes: "failed_cmp_$(keys)" not => strcmp(basename("$(test.input[$(keys)])"), "$(test.expected[$(keys)])"); "ok" not => classmatch("failed_cmp_.*"); reports: DEBUG:: "'basename($(test.input[$(keys)]))' = '$(test.actual[$(keys)])' != '$(test.expected[$(keys)])'" if => "failed_cmp_$(keys)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/021.cf0000644000000000000000000000314015010704253023201 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123,,,456,789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/004.cf0000644000000000000000000000463115010704253023210 0ustar00rootroot00000000000000####################################################### # # Test sum() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "six" ilist => { "1", "2", "3" }; "sum_six" real => sum("six"); "minus_six" ilist => { "-1", "-2", "-3" }; "sum_minus_six" real => sum("minus_six"); "zero" ilist => { "-1", "-2", "3" }; "sum_zero" real => sum("zero"); "sixpoint" rlist => { "1.", "2", "3e0" }; "sum_sixpoint" real => sum("sixpoint"); "minus_sixpoint" rlist => { "-1.", "-2", "-3e0" }; "sum_minus_sixpoint" real => sum("minus_sixpoint"); "zeropoint" rlist => { "-1.", "-2", "3e0" }; "sum_zeropoint" real => sum("zeropoint"); } ####################################################### bundle agent check { classes: "ok" and => { isgreaterthan("$(test.sum_six)", "5.9999999"), islessthan("$(test.sum_six)", "6.0000001"), islessthan("$(test.sum_minus_six)", "-5.9999999"), isgreaterthan("$(test.sum_minus_six)", "-6.0000001"), isgreaterthan("$(test.sum_zero)", "-.0000001"), islessthan("$(test.sum_zero)", ".0000001"), isgreaterthan("$(test.sum_sixpoint)", "5.9999999"), islessthan("$(test.sum_sixpoint)", "6.0000001"), islessthan("$(test.sum_minus_sixpoint)", "-5.9999999"), isgreaterthan("$(test.sum_minus_sixpoint)", "-6.0000001"), isgreaterthan("$(test.sum_zeropoint)", "-.0000001"), islessthan("$(test.sum_zeropoint)", ".0000001"), }; reports: DEBUG:: "test.sum_six = $(test.sum_six)"; "test.sum_minus_six = $(test.sum_minus_six)"; "test.sum_zero = $(test.sum_zero)"; "test.sum_sixpoint = $(test.sum_sixpoint)"; "test.sum_minus_sixpoint = $(test.sum_minus_sixpoint)"; "test.sum_zeropoint = $(test.sum_zeropoint)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/validjson_trailing_bogus_data.cf0000644000000000000000000000306315010704253030755 0ustar00rootroot00000000000000############################################################################## # # Test validjson() evaluates to !any:: when there is trailing bogus data after # termination for JSON object. # ############################################################################## body common control { bundlesequence => { "test", "check" }; version => "1.0"; } ############################################################################## bundle agent test { meta: "description" -> { "CFE-4080" } string => "Test validjson() with trailing bogus data"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; } ############################################################################## bundle agent check { classes: "ok" and => { not(validjson('""a')), validjson('""'), not(validjson('{}b')), validjson('{}'), not(validjson('[]c')), not(validjson('{}}')), not(validjson('{"d": "e"}}')), not(validjson('[]]')), not(validjson('[[]]]')), not(validjson('[[[]]]]')), not(validjson(' []]')), not(validjson('"some": [ "json" ] }')), not(validjson('{ "some": [ "json" ] } [')), not(validjson('["some", "json"]!')), not(validjson(' ["some", "json"]a')), not(validjson('["some", "json"] {"foo": "var"} ')), validjson('{"test": [1, 2, 3]}'), }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata_yaml.cf.expected.json0000644000000000000000000000061215010704253030237 0ustar00rootroot00000000000000{ "explicit_yaml": { "x": 100, "y": [ 1, 2, "a", "b", { "c": 200 } ] }, "extension_yaml": { "x": 100, "y": [ 1, 2, "a", "b", { "c": 200 } ] }, "extension_yml": { "x": 100, "y": [ 1, 2, "a", "b", { "c": 200 } ] } } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mapdata.cf0000644000000000000000000007327415010704253024325 0ustar00rootroot00000000000000####################################################### # # Test mapdata() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "load1" data => parsejson('[ 1, 2, 3]'); "load2" slist => { "eleme\"nt1", "element2", "element3" }; "load3" data => parsejson('{ "x\\"x": "y\\"y" }'); "load4" data => parsejson('[]'); "load5[mykey]" slist => { "myvalue" }; "load5[anotherkey]" string => "anothervalue"; "load5[lastkey!]" slist => { "o\"ne", "two", "three" }; "load6" data => parsejson('{ "a": { "b": "c" } }'); "static[x]" string => "xvalue"; "static[x\"x]" string => "xxvalue"; "static[0]" string => "0value"; "static[1]" string => "1value"; "static[2]" string => "2value"; "static[lastkey!]" string => "lastvalue"; "static[anotherkey]" string => "anothervalue"; "static[mykey]" string => "myvalue"; "static[a]" string => "avalue"; "spec1" string => "key = $(this.k)"; "spec2" string => "key = $(this.k), value = ${this.v}"; "spec3" string => "key = $(this.k), key2 = $(this.k[1]), value = ${this.v}"; "spec4" string => "xvalue should be $(static[$(this.k)])"; "jsonspec1" string => '{ "key": "$(this.k)", "value": "$(this.v)"'; "jsonspec2" string => '{ "key": "$(this.k)", "value": "$(this.v)" }'; "jsonspec3" string => '[ "$(this.k)", "$(this.v)" ]'; "jsonspec4" string => '{ "key": "$(this.k)", "key2": "$(this.k[1])", "value": "$(this.v)" }'; "X" slist => { "1", "2", "3", "4", "5", "6" }; "Y" slist => { "1", "2", "3", "4" }; "mapdata_none_$(X)_$(Y)" data => mapdata("none", "$(spec$(Y))", "load$(X)"); "mapdata_none_str_$(X)_$(Y)" string => format("%S", "mapdata_none_$(X)_$(Y)"); "mapdata_canonify_$(X)_$(Y)" data => mapdata("canonify", "$(spec$(Y))", "load$(X)"); "mapdata_canonify_str_$(X)_$(Y)" string => format("%S", "mapdata_canonify_$(X)_$(Y)"); "mapdata_canonify_eval_$(X)_$(Y)" data => mapdata("canonify", concat("$(spec$(Y))"), "load$(X)"); "mapdata_canonify_eval_str_$(X)_$(Y)" string => format("%S", "mapdata_canonify_eval_$(X)_$(Y)"); "mapdata_json_$(X)_$(Y)" data => mapdata("json", "$(jsonspec$(Y))", "load$(X)"); "mapdata_json_str_$(X)_$(Y)" string => format("%S", "mapdata_json_$(X)_$(Y)"); "bad1" data => mapdata("json", "", missingvar); "justastring" string => "me"; "bad3" data => mapdata("json", "", justastring); classes: 'mapdata_none_1_1_ok' and => { regcmp('.*"key = 0".*', '$(mapdata_none_str_1_1)'), regcmp('.*"key = 1".*', '$(mapdata_none_str_1_1)'), regcmp('.*"key = 2".*', '$(mapdata_none_str_1_1)') }; 'mapdata_none_1_2_ok' and => { regcmp('.*"key = 0, value = 1".*', '$(mapdata_none_str_1_2)'), regcmp('.*"key = 1, value = 2".*', '$(mapdata_none_str_1_2)'), regcmp('.*"key = 2, value = 3".*', '$(mapdata_none_str_1_2)') }; 'mapdata_none_1_3_ok' and => { regcmp('.*"key = 0, key2 = \$\(this.k\[1\]\), value = 1".*', '$(mapdata_none_str_1_3)'), regcmp('.*"key = 1, key2 = \$\(this.k\[1\]\), value = 2".*', '$(mapdata_none_str_1_3)'), regcmp('.*"key = 2, key2 = \$\(this.k\[1\]\), value = 3".*', '$(mapdata_none_str_1_3)') }; 'mapdata_none_1_4_ok' and => { regcmp('.*"xvalue should be 0value".*', '$(mapdata_none_str_1_4)'), regcmp('.*"xvalue should be 1value".*', '$(mapdata_none_str_1_4)'), regcmp('.*"xvalue should be 2value".*', '$(mapdata_none_str_1_4)') }; 'mapdata_none_2_1_ok' and => { regcmp('.*"key = 0".*', '$(mapdata_none_str_2_1)'), regcmp('.*"key = 1".*', '$(mapdata_none_str_2_1)'), regcmp('.*"key = 2".*', '$(mapdata_none_str_2_1)') }; 'mapdata_none_2_2_ok' and => { regcmp('.*"key = 0, value = eleme\\\\"nt1".*', '$(mapdata_none_str_2_2)'), regcmp('.*"key = 1, value = element2".*', '$(mapdata_none_str_2_2)'), regcmp('.*"key = 2, value = element3".*', '$(mapdata_none_str_2_2)') }; 'mapdata_none_2_3_ok' and => { regcmp('.*"key = 0, key2 = \$\(this.k\[1\]\), value = eleme\\\\"nt1".*', '$(mapdata_none_str_2_3)'), regcmp('.*"key = 1, key2 = \$\(this.k\[1\]\), value = element2".*', '$(mapdata_none_str_2_3)'), regcmp('.*"key = 2, key2 = \$\(this.k\[1\]\), value = element3".*', '$(mapdata_none_str_2_3)') }; 'mapdata_none_2_4_ok' and => { regcmp('.*"xvalue should be 0value".*', '$(mapdata_none_str_2_4)'), regcmp('.*"xvalue should be 1value".*', '$(mapdata_none_str_2_4)'), regcmp('.*"xvalue should be 2value".*', '$(mapdata_none_str_2_4)') }; 'mapdata_none_3_1_ok' and => { regcmp('.*"key = x\\\\"x".*', '$(mapdata_none_str_3_1)') }; 'mapdata_none_3_2_ok' and => { regcmp('.*"key = x\\\\"x, value = y\\\\"y".*', '$(mapdata_none_str_3_2)') }; 'mapdata_none_3_3_ok' and => { regcmp('.*"key = x\\\\"x, key2 = \$\(this.k\[1\]\), value = y\\\\"y".*', '$(mapdata_none_str_3_3)') }; 'mapdata_none_3_4_ok' and => { regcmp('.*"xvalue should be xxvalue".*', '$(mapdata_none_str_3_4)') }; 'mapdata_none_4_1_ok' expression => strcmp('$(mapdata_none_str_4_1)', '[]'); 'mapdata_none_4_2_ok' expression => strcmp('$(mapdata_none_str_4_1)', '[]'); 'mapdata_none_4_3_ok' expression => strcmp('$(mapdata_none_str_4_1)', '[]'); 'mapdata_none_4_4_ok' expression => strcmp('$(mapdata_none_str_4_1)', '[]'); 'mapdata_none_5_1_ok' and => { regcmp('.*"key = mykey".*', '$(mapdata_none_str_5_1)'), regcmp('.*"key = anotherkey".*', '$(mapdata_none_str_5_1)'), regcmp('.*"key = lastkey!".*', '$(mapdata_none_str_5_1)') }; 'mapdata_none_5_2_ok' and => { regcmp('.*"key = mykey, value = myvalue".*', '$(mapdata_none_str_5_2)'), regcmp('.*"key = anotherkey, value = anothervalue".*', '$(mapdata_none_str_5_2)'), regcmp('.*"key = lastkey!, value = o\\\\"ne".*', '$(mapdata_none_str_5_2)'), regcmp('.*"key = lastkey!, value = two".*', '$(mapdata_none_str_5_2)'), regcmp('.*"key = lastkey!, value = three".*', '$(mapdata_none_str_5_2)') }; 'mapdata_none_5_3_ok' and => { regcmp('.*"key = mykey, key2 = \$\(this.k\[1\]\), value = myvalue".*', '$(mapdata_none_str_5_3)'), regcmp('.*"key = anotherkey, key2 = \$\(this.k\[1\]\), value = anothervalue".*', '$(mapdata_none_str_5_3)'), regcmp('.*"key = lastkey!, key2 = \$\(this.k\[1\]\), value = o\\\\"ne".*', '$(mapdata_none_str_5_3)'), regcmp('.*"key = lastkey!, key2 = \$\(this.k\[1\]\), value = two".*', '$(mapdata_none_str_5_3)'), regcmp('.*"key = lastkey!, key2 = \$\(this.k\[1\]\), value = three".*', '$(mapdata_none_str_5_3)') }; 'mapdata_none_5_4_ok' and => { regcmp('.*"xvalue should be myvalue".*', '$(mapdata_none_str_5_4)'), regcmp('.*"xvalue should be anothervalue".*', '$(mapdata_none_str_5_4)'), regcmp('.*"xvalue should be lastvalue".*', '$(mapdata_none_str_5_4)') }; 'mapdata_none_6_1_ok' and => { regcmp('.*"key = a".*', '$(mapdata_none_str_6_1)') }; 'mapdata_none_6_2_ok' and => { regcmp('.*"key = a, value = c".*', '$(mapdata_none_str_6_2)') }; 'mapdata_none_6_3_ok' and => { regcmp('.*"key = a, key2 = b, value = c".*', '$(mapdata_none_str_6_3)') }; 'mapdata_none_6_4_ok' and => { regcmp('.*"xvalue should be avalue".*', '$(mapdata_none_str_6_4)') }; 'mapdata_canonify_1_1_ok' and => { regcmp('.*"key___0".*', '$(mapdata_canonify_str_1_1)'), regcmp('.*"key___1".*', '$(mapdata_canonify_str_1_1)'), regcmp('.*"key___2".*', '$(mapdata_canonify_str_1_1)') }; 'mapdata_canonify_1_2_ok' and => { regcmp('.*"key___0__value___1".*', '$(mapdata_canonify_str_1_2)'), regcmp('.*"key___1__value___2".*', '$(mapdata_canonify_str_1_2)'), regcmp('.*"key___2__value___3".*', '$(mapdata_canonify_str_1_2)') }; 'mapdata_canonify_1_3_ok' and => { regcmp('.*"key___0__key2_____this_k_1____value___1".*', '$(mapdata_canonify_str_1_3)'), regcmp('.*"key___1__key2_____this_k_1____value___2".*', '$(mapdata_canonify_str_1_3)'), regcmp('.*"key___2__key2_____this_k_1____value___3".*', '$(mapdata_canonify_str_1_3)') }; 'mapdata_canonify_1_4_ok' and => { regcmp('.*"xvalue_should_be_0value".*', '$(mapdata_canonify_str_1_4)'), regcmp('.*"xvalue_should_be_1value".*', '$(mapdata_canonify_str_1_4)'), regcmp('.*"xvalue_should_be_2value".*', '$(mapdata_canonify_str_1_4)') }; 'mapdata_canonify_2_1_ok' and => { regcmp('.*"key___0".*', '$(mapdata_canonify_str_2_1)'), regcmp('.*"key___1".*', '$(mapdata_canonify_str_2_1)'), regcmp('.*"key___2".*', '$(mapdata_canonify_str_2_1)') }; 'mapdata_canonify_2_2_ok' and => { regcmp('.*"key___0__value___eleme_nt1".*', '$(mapdata_canonify_str_2_2)'), regcmp('.*"key___1__value___element2".*', '$(mapdata_canonify_str_2_2)'), regcmp('.*"key___2__value___element3".*', '$(mapdata_canonify_str_2_2)') }; 'mapdata_canonify_2_3_ok' and => { regcmp('.*"key___0__key2_____this_k_1____value___eleme_nt1".*', '$(mapdata_canonify_str_2_3)'), regcmp('.*"key___1__key2_____this_k_1____value___element2".*', '$(mapdata_canonify_str_2_3)'), regcmp('.*"key___2__key2_____this_k_1____value___element3".*', '$(mapdata_canonify_str_2_3)') }; 'mapdata_canonify_2_4_ok' and => { regcmp('.*"xvalue_should_be_0value".*', '$(mapdata_canonify_str_2_4)'), regcmp('.*"xvalue_should_be_1value".*', '$(mapdata_canonify_str_2_4)'), regcmp('.*"xvalue_should_be_2value".*', '$(mapdata_canonify_str_2_4)') }; 'mapdata_canonify_3_1_ok' and => { regcmp('.*"key___x_x".*', '$(mapdata_canonify_str_3_1)') }; 'mapdata_canonify_3_2_ok' and => { regcmp('.*"key___x_x__value___y_y".*', '$(mapdata_canonify_str_3_2)') }; 'mapdata_canonify_3_3_ok' and => { regcmp('.*"key___x_x__key2_____this_k_1____value___y_y".*', '$(mapdata_canonify_str_3_3)') }; 'mapdata_canonify_3_4_ok' and => { regcmp('.*"xvalue_should_be_xxvalue".*', '$(mapdata_canonify_str_3_4)') }; 'mapdata_canonify_4_1_ok' expression => strcmp('$(mapdata_canonify_str_4_1)', '[]'); 'mapdata_canonify_4_2_ok' expression => strcmp('$(mapdata_canonify_str_4_1)', '[]'); 'mapdata_canonify_4_3_ok' expression => strcmp('$(mapdata_canonify_str_4_1)', '[]'); 'mapdata_canonify_4_4_ok' expression => strcmp('$(mapdata_canonify_str_4_1)', '[]'); 'mapdata_canonify_5_1_ok' and => { regcmp('.*"key___mykey".*', '$(mapdata_canonify_str_5_1)'), regcmp('.*"key___anotherkey".*', '$(mapdata_canonify_str_5_1)'), regcmp('.*"key___lastkey_".*', '$(mapdata_canonify_str_5_1)') }; 'mapdata_canonify_5_2_ok' and => { regcmp('.*"key___mykey__value___myvalue".*', '$(mapdata_canonify_str_5_2)'), regcmp('.*"key___anotherkey__value___anothervalue".*', '$(mapdata_canonify_str_5_2)'), regcmp('.*"key___lastkey___value___o_ne".*', '$(mapdata_canonify_str_5_2)'), regcmp('.*"key___lastkey___value___two".*', '$(mapdata_canonify_str_5_2)'), regcmp('.*"key___lastkey___value___three".*', '$(mapdata_canonify_str_5_2)') }; 'mapdata_canonify_5_3_ok' and => { regcmp('.*"key___mykey__key2_____this_k_1____value___myvalue".*', '$(mapdata_canonify_str_5_3)'), regcmp('.*"key___anotherkey__key2_____this_k_1____value___anothervalue".*', '$(mapdata_canonify_str_5_3)'), regcmp('.*"key___lastkey___key2_____this_k_1____value___o_ne".*', '$(mapdata_canonify_str_5_3)'), regcmp('.*"key___lastkey___key2_____this_k_1____value___two".*', '$(mapdata_canonify_str_5_3)'), regcmp('.*"key___lastkey___key2_____this_k_1____value___three".*', '$(mapdata_canonify_str_5_3)') }; 'mapdata_canonify_5_4_ok' and => { regcmp('.*"xvalue_should_be_myvalue".*', '$(mapdata_canonify_str_5_4)'), regcmp('.*"xvalue_should_be_anothervalue".*', '$(mapdata_canonify_str_5_4)'), regcmp('.*"xvalue_should_be_lastvalue".*', '$(mapdata_canonify_str_5_4)') }; 'mapdata_canonify_6_1_ok' and => { regcmp('.*"key___a".*', '$(mapdata_canonify_str_6_1)') }; 'mapdata_canonify_6_2_ok' and => { regcmp('.*"key___a__value___c".*', '$(mapdata_canonify_str_6_2)') }; 'mapdata_canonify_6_3_ok' and => { regcmp('.*"key___a__key2___b__value___c".*', '$(mapdata_canonify_str_6_3)') }; 'mapdata_canonify_6_4_ok' and => { regcmp('.*"xvalue_should_be_avalue".*', '$(mapdata_canonify_str_6_4)') }; 'mapdata_canonify_eval_1_1_ok' and => { regcmp('.*"key___0".*', '$(mapdata_canonify_eval_str_1_1)'), regcmp('.*"key___1".*', '$(mapdata_canonify_eval_str_1_1)'), regcmp('.*"key___2".*', '$(mapdata_canonify_eval_str_1_1)') }; 'mapdata_canonify_eval_1_2_ok' and => { regcmp('.*"key___0__value___1".*', '$(mapdata_canonify_eval_str_1_2)'), regcmp('.*"key___1__value___2".*', '$(mapdata_canonify_eval_str_1_2)'), regcmp('.*"key___2__value___3".*', '$(mapdata_canonify_eval_str_1_2)') }; 'mapdata_canonify_eval_1_3_ok' and => { regcmp('.*"key___0__key2_____this_k_1____value___1".*', '$(mapdata_canonify_eval_str_1_3)'), regcmp('.*"key___1__key2_____this_k_1____value___2".*', '$(mapdata_canonify_eval_str_1_3)'), regcmp('.*"key___2__key2_____this_k_1____value___3".*', '$(mapdata_canonify_eval_str_1_3)') }; 'mapdata_canonify_eval_1_4_ok' and => { regcmp('.*"xvalue_should_be_0value".*', '$(mapdata_canonify_eval_str_1_4)'), regcmp('.*"xvalue_should_be_1value".*', '$(mapdata_canonify_eval_str_1_4)'), regcmp('.*"xvalue_should_be_2value".*', '$(mapdata_canonify_eval_str_1_4)') }; 'mapdata_canonify_eval_2_1_ok' and => { regcmp('.*"key___0".*', '$(mapdata_canonify_eval_str_2_1)'), regcmp('.*"key___1".*', '$(mapdata_canonify_eval_str_2_1)'), regcmp('.*"key___2".*', '$(mapdata_canonify_eval_str_2_1)') }; 'mapdata_canonify_eval_2_2_ok' and => { regcmp('.*"key___0__value___eleme_nt1".*', '$(mapdata_canonify_eval_str_2_2)'), regcmp('.*"key___1__value___element2".*', '$(mapdata_canonify_eval_str_2_2)'), regcmp('.*"key___2__value___element3".*', '$(mapdata_canonify_eval_str_2_2)') }; 'mapdata_canonify_eval_2_3_ok' and => { regcmp('.*"key___0__key2_____this_k_1____value___eleme_nt1".*', '$(mapdata_canonify_eval_str_2_3)'), regcmp('.*"key___1__key2_____this_k_1____value___element2".*', '$(mapdata_canonify_eval_str_2_3)'), regcmp('.*"key___2__key2_____this_k_1____value___element3".*', '$(mapdata_canonify_eval_str_2_3)') }; 'mapdata_canonify_eval_2_4_ok' and => { regcmp('.*"xvalue_should_be_0value".*', '$(mapdata_canonify_eval_str_2_4)'), regcmp('.*"xvalue_should_be_1value".*', '$(mapdata_canonify_eval_str_2_4)'), regcmp('.*"xvalue_should_be_2value".*', '$(mapdata_canonify_eval_str_2_4)') }; 'mapdata_canonify_eval_3_1_ok' and => { regcmp('.*"key___x_x".*', '$(mapdata_canonify_eval_str_3_1)') }; 'mapdata_canonify_eval_3_2_ok' and => { regcmp('.*"key___x_x__value___y_y".*', '$(mapdata_canonify_eval_str_3_2)') }; 'mapdata_canonify_eval_3_3_ok' and => { regcmp('.*"key___x_x__key2_____this_k_1____value___y_y".*', '$(mapdata_canonify_eval_str_3_3)') }; 'mapdata_canonify_eval_3_4_ok' and => { regcmp('.*"xvalue_should_be_xxvalue".*', '$(mapdata_canonify_eval_str_3_4)') }; 'mapdata_canonify_eval_4_1_ok' expression => strcmp('$(mapdata_canonify_eval_str_4_1)', '[]'); 'mapdata_canonify_eval_4_2_ok' expression => strcmp('$(mapdata_canonify_eval_str_4_1)', '[]'); 'mapdata_canonify_eval_4_3_ok' expression => strcmp('$(mapdata_canonify_eval_str_4_1)', '[]'); 'mapdata_canonify_eval_4_4_ok' expression => strcmp('$(mapdata_canonify_eval_str_4_1)', '[]'); 'mapdata_canonify_eval_5_1_ok' and => { regcmp('.*"key___mykey".*', '$(mapdata_canonify_eval_str_5_1)'), regcmp('.*"key___anotherkey".*', '$(mapdata_canonify_eval_str_5_1)'), regcmp('.*"key___lastkey_".*', '$(mapdata_canonify_eval_str_5_1)') }; 'mapdata_canonify_eval_5_2_ok' and => { regcmp('.*"key___mykey__value___myvalue".*', '$(mapdata_canonify_eval_str_5_2)'), regcmp('.*"key___anotherkey__value___anothervalue".*', '$(mapdata_canonify_eval_str_5_2)'), regcmp('.*"key___lastkey___value___o_ne".*', '$(mapdata_canonify_eval_str_5_2)'), regcmp('.*"key___lastkey___value___two".*', '$(mapdata_canonify_eval_str_5_2)'), regcmp('.*"key___lastkey___value___three".*', '$(mapdata_canonify_eval_str_5_2)') }; 'mapdata_canonify_eval_5_3_ok' and => { regcmp('.*"key___mykey__key2_____this_k_1____value___myvalue".*', '$(mapdata_canonify_eval_str_5_3)'), regcmp('.*"key___anotherkey__key2_____this_k_1____value___anothervalue".*', '$(mapdata_canonify_eval_str_5_3)'), regcmp('.*"key___lastkey___key2_____this_k_1____value___o_ne".*', '$(mapdata_canonify_eval_str_5_3)'), regcmp('.*"key___lastkey___key2_____this_k_1____value___two".*', '$(mapdata_canonify_eval_str_5_3)'), regcmp('.*"key___lastkey___key2_____this_k_1____value___three".*', '$(mapdata_canonify_eval_str_5_3)') }; 'mapdata_canonify_eval_5_4_ok' and => { regcmp('.*"xvalue_should_be_myvalue".*', '$(mapdata_canonify_eval_str_5_4)'), regcmp('.*"xvalue_should_be_anothervalue".*', '$(mapdata_canonify_eval_str_5_4)'), regcmp('.*"xvalue_should_be_lastvalue".*', '$(mapdata_canonify_eval_str_5_4)') }; 'mapdata_canonify_eval_6_1_ok' and => { regcmp('.*"key___a".*', '$(mapdata_canonify_eval_str_6_1)') }; 'mapdata_canonify_eval_6_2_ok' and => { regcmp('.*"key___a__value___c".*', '$(mapdata_canonify_eval_str_6_2)') }; 'mapdata_canonify_eval_6_3_ok' and => { regcmp('.*"key___a__key2___b__value___c".*', '$(mapdata_canonify_eval_str_6_3)') }; 'mapdata_canonify_eval_6_4_ok' and => { regcmp('.*"xvalue_should_be_avalue".*', '$(mapdata_canonify_eval_str_6_4)') }; 'mapdata_json_1_1_ok' expression => strcmp('$(mapdata_json_str_1_1)', '[]'); 'mapdata_json_1_2_ok' and => { regcmp('.*\{"key":"0","value":"1"\}.*', '$(mapdata_json_str_1_2)'), regcmp('.*\{"key":"1","value":"2"\}.*', '$(mapdata_json_str_1_2)'), regcmp('.*\{"key":"2","value":"3"\}.*', '$(mapdata_json_str_1_2)') }; 'mapdata_json_1_3_ok' and => { regcmp('.*\["0","1"\].*', '$(mapdata_json_str_1_3)'), regcmp('.*\["1","2"\].*', '$(mapdata_json_str_1_3)'), regcmp('.*\["2","3"\].*', '$(mapdata_json_str_1_3)') }; 'mapdata_json_1_4_ok' and => { regcmp('.*\{"key":"0","key2":"\$\(this.k\[1\]\)","value":"1"\}.*', '$(mapdata_json_str_1_4)'), regcmp('.*\{"key":"1","key2":"\$\(this.k\[1\]\)","value":"2"\}.*', '$(mapdata_json_str_1_4)'), regcmp('.*\{"key":"2","key2":"\$\(this.k\[1\]\)","value":"3"\}.*', '$(mapdata_json_str_1_4)') }; 'mapdata_json_2_1_ok' expression => strcmp('$(mapdata_json_str_2_1)', '[]'); 'mapdata_json_2_2_ok' and => { regcmp('.*\{"key":"0","value":"eleme\\\\"nt1"\}.*', '$(mapdata_json_str_2_2)'), regcmp('.*\{"key":"1","value":"element2"\}.*', '$(mapdata_json_str_2_2)'), regcmp('.*\{"key":"2","value":"element3"\}.*', '$(mapdata_json_str_2_2)') }; 'mapdata_json_2_3_ok' and => { regcmp('.*\["0","eleme\\\\"nt1"\].*', '$(mapdata_json_str_2_3)'), regcmp('.*\["1","element2"\].*', '$(mapdata_json_str_2_3)'), regcmp('.*\["2","element3"\].*', '$(mapdata_json_str_2_3)') }; 'mapdata_json_2_4_ok' and => { regcmp('.*\{"key":"0","key2":"\$\(this.k\[1\]\)","value":"eleme\\\\"nt1"\}.*', '$(mapdata_json_str_2_4)'), regcmp('.*\{"key":"1","key2":"\$\(this.k\[1\]\)","value":"element2"\}.*', '$(mapdata_json_str_2_4)'), regcmp('.*\{"key":"2","key2":"\$\(this.k\[1\]\)","value":"element3"\}.*', '$(mapdata_json_str_2_4)') }; 'mapdata_json_3_1_ok' expression => strcmp('$(mapdata_json_str_3_1)', '[]'); 'mapdata_json_3_2_ok' and => { regcmp('.*\{"key":"x\\\\"x","value":"y\\\\"y"\}.*', '$(mapdata_json_str_3_2)') }; 'mapdata_json_3_3_ok' and => { regcmp('.*\["x\\\\"x","y\\\\"y"\].*', '$(mapdata_json_str_3_3)') }; 'mapdata_json_3_4_ok' and => { regcmp('.*\{"key":"x\\\\"x","key2":"\$\(this.k\[1\]\)","value":"y\\\\"y"\}.*', '$(mapdata_json_str_3_4)') }; 'mapdata_json_4_1_ok' expression => strcmp('$(mapdata_json_str_4_1)', '[]'); 'mapdata_json_4_2_ok' expression => strcmp('$(mapdata_json_str_4_1)', '[]'); 'mapdata_json_4_3_ok' expression => strcmp('$(mapdata_json_str_4_1)', '[]'); 'mapdata_json_4_4_ok' expression => strcmp('$(mapdata_json_str_4_1)', '[]'); 'mapdata_json_5_1_ok' expression => strcmp('$(mapdata_json_str_5_1)', '[]'); 'mapdata_json_5_2_ok' and => { regcmp('.*\{"key":"mykey","value":"myvalue"\}.*', '$(mapdata_json_str_5_2)'), regcmp('.*\{"key":"anotherkey","value":"anothervalue"\}.*', '$(mapdata_json_str_5_2)'), regcmp('.*\{"key":"lastkey!","value":"o\\\\"ne"\}.*', '$(mapdata_json_str_5_2)'), regcmp('.*\{"key":"lastkey!","value":"two"\}.*', '$(mapdata_json_str_5_2)'), regcmp('.*\{"key":"lastkey!","value":"three"\}.*', '$(mapdata_json_str_5_2)') }; 'mapdata_json_5_3_ok' and => { regcmp('.*\["mykey","myvalue"\].*', '$(mapdata_json_str_5_3)'), regcmp('.*\["anotherkey","anothervalue"\].*', '$(mapdata_json_str_5_3)'), regcmp('.*\["lastkey!","o\\\\"ne"\].*', '$(mapdata_json_str_5_3)'), regcmp('.*\["lastkey!","two"\].*', '$(mapdata_json_str_5_3)'), regcmp('.*\["lastkey!","three"\].*', '$(mapdata_json_str_5_3)') }; 'mapdata_json_5_4_ok' and => { regcmp('.*\{"key":"mykey","key2":"\$\(this.k\[1\]\)","value":"myvalue"\}.*', '$(mapdata_json_str_5_4)'), regcmp('.*\{"key":"anotherkey","key2":"\$\(this.k\[1\]\)","value":"anothervalue"\}.*', '$(mapdata_json_str_5_4)'), regcmp('.*\{"key":"lastkey!","key2":"\$\(this.k\[1\]\)","value":"o\\\\"ne"\}.*', '$(mapdata_json_str_5_4)'), regcmp('.*\{"key":"lastkey!","key2":"\$\(this.k\[1\]\)","value":"two"\}.*', '$(mapdata_json_str_5_4)'), regcmp('.*\{"key":"lastkey!","key2":"\$\(this.k\[1\]\)","value":"three"\}.*', '$(mapdata_json_str_5_4)') }; 'mapdata_json_6_1_ok' expression => strcmp('$(mapdata_json_str_6_1)', '[]'); 'mapdata_json_6_2_ok' and => { regcmp('.*\{"key":"a","value":"c"\}.*', '$(mapdata_json_str_6_2)') }; 'mapdata_json_6_3_ok' and => { regcmp('.*\["a","c"\].*', '$(mapdata_json_str_6_3)') }; 'mapdata_json_6_4_ok' and => { regcmp('.*\{"key":"a","key2":"b","value":"c"\}.*', '$(mapdata_json_str_6_4)') }; "mapdata_none_ok" and => { "mapdata_none_1_1_ok", "mapdata_none_1_2_ok", "mapdata_none_1_3_ok", "mapdata_none_1_4_ok", "mapdata_none_2_1_ok", "mapdata_none_2_2_ok", "mapdata_none_2_3_ok", "mapdata_none_2_4_ok", "mapdata_none_3_1_ok", "mapdata_none_3_2_ok", "mapdata_none_3_3_ok", "mapdata_none_3_4_ok", "mapdata_none_4_1_ok", "mapdata_none_4_2_ok", "mapdata_none_4_3_ok", "mapdata_none_4_4_ok", "mapdata_none_5_1_ok", "mapdata_none_5_2_ok", "mapdata_none_5_3_ok", "mapdata_none_5_4_ok", "mapdata_none_6_1_ok", "mapdata_none_6_2_ok", "mapdata_none_6_3_ok", "mapdata_none_6_4_ok" }; "mapdata_canonify_ok" and => { "mapdata_canonify_1_1_ok", "mapdata_canonify_1_2_ok", "mapdata_canonify_1_3_ok", "mapdata_canonify_1_4_ok", "mapdata_canonify_2_1_ok", "mapdata_canonify_2_2_ok", "mapdata_canonify_2_3_ok", "mapdata_canonify_2_4_ok", "mapdata_canonify_3_1_ok", "mapdata_canonify_3_2_ok", "mapdata_canonify_3_3_ok", "mapdata_canonify_3_4_ok", "mapdata_canonify_4_1_ok", "mapdata_canonify_4_2_ok", "mapdata_canonify_4_3_ok", "mapdata_canonify_4_4_ok", "mapdata_canonify_5_1_ok", "mapdata_canonify_5_2_ok", "mapdata_canonify_5_3_ok", "mapdata_canonify_5_4_ok", "mapdata_canonify_6_1_ok", "mapdata_canonify_6_2_ok", "mapdata_canonify_6_3_ok", "mapdata_canonify_6_4_ok" }; "mapdata_canonify_eval_ok" and => { "mapdata_canonify_eval_1_1_ok", "mapdata_canonify_eval_1_2_ok", "mapdata_canonify_eval_1_3_ok", "mapdata_canonify_eval_1_4_ok", "mapdata_canonify_eval_2_1_ok", "mapdata_canonify_eval_2_2_ok", "mapdata_canonify_eval_2_3_ok", "mapdata_canonify_eval_2_4_ok", "mapdata_canonify_eval_3_1_ok", "mapdata_canonify_eval_3_2_ok", "mapdata_canonify_eval_3_3_ok", "mapdata_canonify_eval_3_4_ok", "mapdata_canonify_eval_4_1_ok", "mapdata_canonify_eval_4_2_ok", "mapdata_canonify_eval_4_3_ok", "mapdata_canonify_eval_4_4_ok", "mapdata_canonify_eval_5_1_ok", "mapdata_canonify_eval_5_2_ok", "mapdata_canonify_eval_5_3_ok", "mapdata_canonify_eval_5_4_ok", "mapdata_canonify_eval_6_1_ok", "mapdata_canonify_eval_6_2_ok", "mapdata_canonify_eval_6_3_ok", "mapdata_canonify_eval_6_4_ok" }; "mapdata_json_ok" and => { "mapdata_json_1_1_ok", "mapdata_json_1_2_ok", "mapdata_json_1_3_ok", "mapdata_json_1_4_ok", "mapdata_json_2_1_ok", "mapdata_json_2_2_ok", "mapdata_json_2_3_ok", "mapdata_json_2_4_ok", "mapdata_json_3_1_ok", "mapdata_json_3_2_ok", "mapdata_json_3_3_ok", "mapdata_json_3_4_ok", "mapdata_json_4_1_ok", "mapdata_json_4_2_ok", "mapdata_json_4_3_ok", "mapdata_json_4_4_ok", "mapdata_json_5_1_ok", "mapdata_json_5_2_ok", "mapdata_json_5_3_ok", "mapdata_json_5_4_ok", "mapdata_json_6_1_ok", "mapdata_json_6_2_ok", "mapdata_json_6_3_ok", "mapdata_json_6_4_ok" }; "ok" and => { "mapdata_none_ok", "mapdata_canonify_ok", "mapdata_canonify_eval_ok", "mapdata_json_ok" }, scope => "namespace"; } ####################################################### bundle agent check { reports: DEBUG:: "mapdata_none*:"; "mapdata_none_str_$(test.X)_$(test.Y): '$(test.mapdata_none_str_$(test.X)_$(test.Y))'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parseyaml_with_unquoted_values_starting_with_digits.cf0000644000000000000000000000144715010704253035474 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functionsbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2033" } string => "Make sure parsing YAML values starting with numbers works"; vars: "class" string => "1003_efl_test"; "d" data => parseyaml( "- class: ${class}" ); classes: "PASS" expression => strcmp( ${d[0][class]}, "${class}" ); "FAIL" not => strcmp( ${d[0][class]}, "${class}" ); reports: PASS:: "$(this.promise_filename) Pass"; FAIL:: "$(this.promise_filename) FAIL"; PASS.FAIL:: "$(this.promise_filename) EXCEPTION"; DEBUG:: "version => ${sys.cf_version}"; "class => ${d[0][class]}"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/eval.cf0000644000000000000000000001265715010704253023643 0ustar00rootroot00000000000000####################################################### # # Test eval() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "values[0]" string => "x"; "values[1]" string => "+ 200"; "values[2]" string => "200 + 100"; "values[3]" string => "200 - 100"; "values[4]" string => "- - -"; "values[5]" string => "2 - (3 - 1)"; "values[6]" string => ""; "values[7]" string => "3 / 0"; "values[8]" string => "3^3"; "values[9]" string => "(-1)^2"; "values[10]" string => "sin(20)"; "values[11]" string => "cos(20)"; "values[12]" string => "asin(0.2)"; "values[13]" string => "acos(0.2)"; "values[14]" string => "tan(20)"; "values[15]" string => "atan(0.2)"; "values[16]" string => "log(0.2)"; "values[17]" string => "ln2"; "values[18]" string => "ln10"; "values[19]" string => "20 % 3"; "values[20]" string => "sqrt(0.2)"; "values[21]" string => "ceil(3.5)"; "values[22]" string => "floor(3.4)"; "values[23]" string => "abs(-3.4)"; "values[24]" string => "-3.4 -3.4"; "values[25]" string => "-3.400000 -3.400001"; "values[26]" string => "pi"; "values[27]" string => "e"; "values[28]" string => "10 == 10"; "values[29]" string => "10 == 11"; "values[30]" string => "3**0"; "values[31]" string => "step(10)"; "values[32]" string => "step(-10)"; "values[33]" string => "100k"; "values[34]" string => "(200m - 100k) / (2t + 2t)"; "values[35]" string => "10 > 10"; "values[36]" string => "10 > 11"; "values[37]" string => "10 >= 10"; "values[38]" string => "10 >= 11"; "values[39]" string => "10 < 10"; "values[40]" string => "10 < 11"; "values[41]" string => "10 <= 10"; "values[42]" string => "10 <= 11"; "values[43]" -> { "CFE-2762" } string => "1 * .75"; } ####################################################### bundle agent test { vars: "indices" slist => getindices("init.values"); # convert the result to lowercase because some platforms use 'inf' # and others 'Inf' and others... you don't wanna know "eval[$(indices)]" string => string_downcase(eval("$(init.values[$(indices)])")); } ####################################################### bundle agent check { vars: # note this test will be MUCH more accurate when we have sprintf and rounding "verify[0]" string => ''; "verify[1]" string => ''; "verify[2]" string => '300.000000'; "verify[3]" string => '100.000000'; "verify[4]" string => ''; "verify[5]" string => '0.000000'; "verify[6]" string => '0.000000'; "verify[7]" string => 'inf'; "verify[8]" string => '27.000000'; "verify[9]" string => '1.000000'; "verify[10]" string => '0.912945'; "verify[11]" string => '0.408082'; "verify[12]" string => '0.201358'; "verify[13]" string => '1.369438'; "verify[14]" string => '2.237161'; "verify[15]" string => '0.197396'; "verify[16]" string => '-1.609438'; "verify[17]" string => '0.693147'; "verify[18]" string => '2.302585'; "verify[19]" string => '2.000000'; "verify[20]" string => '0.447214'; "verify[21]" string => '4.000000'; "verify[22]" string => '3.000000'; "verify[23]" string => '3.400000'; "verify[24]" string => '-6.800000'; "verify[25]" string => '-6.800001'; "verify[26]" string => '3.141593'; "verify[27]" string => '2.718282'; "verify[28]" string => '1.000000'; "verify[29]" string => '0.000000'; "verify[30]" string => '1.000000'; "verify[31]" string => '1.000000'; "verify[32]" string => '0.000000'; "verify[33]" string => '100000.000000'; "verify[34]" string => '0.000050'; "verify[35]" string => '0.000000'; "verify[36]" string => '0.000000'; "verify[37]" string => '1.000000'; "verify[38]" string => '0.000000'; "verify[39]" string => '0.000000'; "verify[40]" string => '1.000000'; "verify[41]" string => '1.000000'; "verify[42]" string => '1.000000'; "verify[43]" -> { "CFE-2762" } string => '0.750000'; "indices" slist => getindices("verify"); classes: "ok_$(indices)" expression => strcmp("$(test.eval[$(indices)])", "$(verify[$(indices)])"); "not_ok_$(indices)" not => strcmp("$(test.eval[$(indices)])", "$(verify[$(indices)])"); "ok" and => { ok_0, ok_1, ok_3, ok_4, ok_5, ok_6, ok_7, ok_8, ok_9, ok_10, ok_11, ok_13, ok_14, ok_15, ok_16, ok_17, ok_18, ok_19, ok_20, ok_21, ok_23, ok_24, ok_25, ok_26, ok_27, ok_28, ok_29, ok_30, ok_31, ok_32, ok_33, ok_34, ok_35, ok_36, ok_37, ok_38, ok_39, ok_40, ok_41, ok_42, ok_43 }; reports: DEBUG:: "OK math $(indices) eval('$(init.values[$(indices)])') = '$(test.eval[$(indices)])'" if => "ok_$(indices)"; "FAIL math $(indices) eval('$(init.values[$(indices)])') = '$(test.eval[$(indices)])' (expected '$(verify[$(indices)])')" if => "not_ok_$(indices)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/005.cf0000644000000000000000000000504515010704253023211 0ustar00rootroot00000000000000####################################################### # # Test product() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "six" ilist => { "1", "2", "3" }; "product_six" real => product("six"); "minus_six" ilist => { "-1", "-2", "-3" }; "product_minus_six" real => product("minus_six"); "zero" ilist => { "-1", "0", "3" }; "product_zero" real => product("zero"); "sixpoint" rlist => { "1.", "2", "3" }; "product_sixpoint" real => product("sixpoint"); "minus_sixpoint" rlist => { "-1.", "-2", "-3" }; "product_minus_sixpoint" real => product("minus_sixpoint"); "zeropoint" rlist => { "-1.", "0", "3" }; "product_zeropoint" real => product("zeropoint"); } ####################################################### bundle agent check { classes: "ok" and => { isgreaterthan("$(test.product_six)", "5.9999999"), islessthan("$(test.product_six)", "6.0000001"), islessthan("$(test.product_minus_six)", "-5.9999999"), isgreaterthan("$(test.product_minus_six)", "-6.0000001"), isgreaterthan("$(test.product_zero)", "-.0000001"), islessthan("$(test.product_zero)", ".0000001"), isgreaterthan("$(test.product_sixpoint)", "5.9999999"), islessthan("$(test.product_sixpoint)", "6.0000001"), islessthan("$(test.product_minus_sixpoint)", "-5.9999999"), isgreaterthan("$(test.product_minus_sixpoint)", "-6.0000001"), isgreaterthan("$(test.product_zeropoint)", "-.0000001"), islessthan("$(test.product_zeropoint)", ".0000001"), }; reports: DEBUG:: "test.product_six = $(test.product_six)"; "test.product_minus_six = $(test.product_minus_six)"; "test.product_zero = $(test.product_zero)"; "test.product_sixpoint = $(test.product_sixpoint)"; "test.product_minus_sixpoint = $(test.product_minus_sixpoint)"; "test.product_zeropoint = $(test.product_zeropoint)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_4.cf0000644000000000000000000000341215010704253026153 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2768" } string => "Test that classfiltercsv() works: - column headings - simple filtering (no duplicates after filter) - no sorting - 2 invalid rows, one that would be included, and one that would be filtered out are both ignored"; } bundle agent check { vars: "data_file" string => "$(this.promise_filename).csv"; "d" data => classfiltercsv( $(data_file), "true", # Data file contains column headings 0); # Column containing class expression to filter with classes: # Check if Token has the value we expect "Token_OK" expression => strcmp( "$(d[0][Token])", "net.ipv4.ip_forward" ); # Check if Value has the value we expect "Value_OK" expression => strcmp( "$(d[0][Value])", "ANYVALUE" ); # Check if the result contains the number of records we expect. "Length_OK" expression => strcmp( length( d ), 1 ); methods: "Pass/FAIL" usebundle => dcs_passif_expected( 'Token_OK,Value_OK,Length_OK', '', $(this.promise_filename) ), inherit => "true"; reports: DEBUG|EXTRA:: "Function returned:$(with)" with => string_mustache( "{{%-top-}}", d ); "supercalifragilisticexpialidociousNOTDEFINED is actually defined." if => "supercalifragilisticexpialidociousNOTDEFINED"; "supercalifragilisticexpialidociousNOTDEFINED is not defined (as expected)" unless => "supercalifragilisticexpialidociousNOTDEFINED"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/041.cf0000644000000000000000000000256215010704253023212 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123.456", "$(nums)"); "ok" and => { "ok_list", "ok123", islessthan("$(test.sum)", "123.457"), isgreaterthan("$(test.sum)", "123.455") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata_with_list_iteration.cf0000644000000000000000000000362615010704253031005 0ustar00rootroot00000000000000####################################################### # # Test that mergedata works with list iteration # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { test_1, test_2, default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test_1 { vars: "hosts" meta => { "hosts" }, data => parsejson('{"10.100.250.11": [ "slot2" ], "10.100.250.10": [ "slot1" ], "111": 222 }'); } bundle agent test_2 { vars: "hosts" meta => { "hosts" }, data => parsejson('{"10.100.250.11": [ "cflin111" ], "10.100.250.10": [ "cflin110" ]}'); } # this bundle is not in the bundlesequence but will be evaluated bundle agent test_3 { vars: "hosts" meta => { "hosts" }, data => parsejson('{"10.100.250.12": [ "cflin111" ], "10.100.250.13": [ "cflin110" ]}'); } bundle common test { vars: "variables" slist => variablesmatching(".*", "hosts"); "sorted_vars" slist => sort("variables", "lex"); "merged" data => parsejson('{}'), policy => "free"; "merged" data => mergedata(merged, $(sorted_vars)), policy => "free"; "result" string => format("%S", "merged"), policy => "free"; } ####################################################### bundle agent check { vars: "expected" string => '{"10.100.250.10":["cflin110"],"10.100.250.11":["cflin111"],"10.100.250.12":["cflin111"],"10.100.250.13":["cflin110"],"111":222}'; classes: "ok" expression => strcmp($(test.result), $(check.expected)); reports: DEBUG.inform_mode:: "Expected: '$(check.expected)'"; "Result: '$(test.result)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/every_some_none.cf0000644000000000000000000000677115010704253026110 0ustar00rootroot00000000000000####################################################### # # Test every(), some(), and none() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { methods: "pretest"; "collect"; } bundle common pretest { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "empty" slist => { }; "d1" data => parsejson(' [1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three"]'); "d2" data => parsejson(' { "one": 1, "two": 2, "three": 3, "x": "y", "a": "b", "p": "q" }'); "dempty" data => parsejson('[]'); "collected" slist => classesmatching(".*", "collect"); "collected_sorted" slist => sort(collected, "lex"); classes: "every1" meta => { "collect" }, expression => every(".*", "test"); "every2" meta => { "collect" }, expression => every(".", "test"); "some1" meta => { "collect" }, expression => some("long string", "test"); "some2" meta => { "collect" }, expression => some("none", "test"); "none1" meta => { "collect" }, expression => none("jebadiah", "test"); "none2" meta => { "collect" }, expression => none("2", "test"); "every_empty" meta => { "collect" }, expression => every(".*", "empty"); "some_empty" meta => { "collect" }, expression => some(".*", "empty"); "none_empty" meta => { "collect" }, expression => none(".*", "empty"); "everyd11" meta => { "collect" }, expression => every(".*", d1); "everyd12" meta => { "collect" }, expression => every(".", d1); "somed11" meta => { "collect" }, expression => some("long string", d1); "somed12" meta => { "collect" }, expression => some("none", d1); "noned11" meta => { "collect" }, expression => none("jebadiah", d1); "noned12" meta => { "collect" }, expression => none("2", d1); "everyd21" meta => { "collect" }, expression => every(".*", d2); "everyd22" meta => { "collect" }, expression => every(".", d2); "somed21" meta => { "collect" }, expression => some("long string", d2); "somed22" meta => { "collect" }, expression => some("none", d2); "noned21" meta => { "collect" }, expression => none("jebadiah", d2); "noned22" meta => { "collect" }, expression => none("2", d2); "every_dempty" meta => { "collect" }, expression => every(".*", dempty); "some_dempty" meta => { "collect" }, expression => some(".*", dempty); "none_dempty" meta => { "collect" }, expression => none(".*", dempty); # with inline JSON "inline_every_empty" meta => { "collect" }, expression => every(".*", '[]'); "inline_some_data" meta => { "collect" }, expression => every(".*", '[ "foo", "bar" ]'); "inline_none_data" meta => { "collect" }, expression => none("jebadiah", '[ "foo", "bar" ]'); } bundle common collect { vars: "collected" slist => { @(pretest.collected_sorted) }; } bundle agent check { methods: "check" usebundle => dcs_check_state(collect, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/ifelse_isvariable-ENT-4653.cf0000644000000000000000000000154115010704253027375 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "ENT-4653" } string => "Test that ifelse can use the result of isvariable with 3 arguments even when they contain variables that don't resolve"; vars: "lookup" string => "THIS_IS_NOT_A_DEFINED_VARIABLE"; "test" string => ifelse( isvariable( "$(lookup)" ), "$($(lookup))", "FALLBACK"); } bundle agent check { reports: '$(this.promise_filename) Pass' if => strcmp( "FALLBACK", $(test.test) ) ; '$(this.promise_filename) FAIL' if => not( isvariable( "test.test" ) ); '$(this.promise_filename) FAIL' if => not( strcmp( "FALLBACK", $(test.test) ) ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readstringlist-many-comments.cf.list.txt0000644000000000000000000000035715010704253032321 0ustar00rootroot00000000000000# comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment # comment jay dave cfengine-3.24.2/tests/acceptance/01_vars/02_functions/420.cf0000644000000000000000000000565715010704253023223 0ustar00rootroot00000000000000####################################################### # # Test parsestringarray(), simple # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","NoComment",":",10,1000); # ensure that bare words are OK "ignore" int => parsestringarray("ary", "mydata","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "is"), strcmp("$(test.ary[this][2])", "a"), strcmp("$(test.ary[this][3])", "test"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[this][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mapdata_json_pipe.cf.input.json0000644000000000000000000000012215010704253030457 0ustar00rootroot00000000000000{ "a": 100, "b": true } { "a": 100, "b": true } { "a": 100, "b": true } {} cfengine-3.24.2/tests/acceptance/01_vars/02_functions/lsdir.cf0000644000000000000000000000475515010704253024031 0ustar00rootroot00000000000000####################################################### # # Test lsdir() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common files { vars: # * in filenames not allowed on win windows:: "names" slist => { "a", "bc", "d/e/f", "g/h/i/j", "klm/nop/qrs" }; !windows:: "names" slist => { "a", "bc", "d/e/f", "g/h/i/j", "klm/nop/qrs", "tu/*" }; } ####################################################### bundle agent init { files: "$(G.testdir)/$(files.names)" create => "true"; reports: DEBUG:: "Created $(G.testdir)/$(files.names)"; } ####################################################### bundle agent test { vars: "patterns[a]" string => "$(G.testdir)"; "patterns[b]" string => "$(G.testdir)/b"; # no such directory "pnames" slist => getindices("patterns"); "found_unsorted[$(pnames)]" slist => lsdir("$(patterns[$(pnames)])", "[^.].*", "true"); "found[$(pnames)]" slist => sort("found_unsorted[$(pnames)]", "lex"); "found_string[$(pnames)]" string => join(",", "found[$(pnames)]"); reports: DEBUG:: "found pattern $(pnames) '$(patterns[$(pnames)])' => '$(found_string[$(pnames)])'"; } ####################################################### bundle agent check { vars: windows:: "expected[a]" string => "$(G.testdir)$(const.dirsep)a,$(G.testdir)$(const.dirsep)bc,$(G.testdir)$(const.dirsep)d,$(G.testdir)$(const.dirsep)g,$(G.testdir)$(const.dirsep)klm"; !windows:: "expected[a]" string => "$(G.testdir)/a,$(G.testdir)/bc,$(G.testdir)/d,$(G.testdir)/g,$(G.testdir)/klm,$(G.testdir)/tu"; any:: "expected[b]" string => ""; "expects" slist => getindices("expected"); "fstring" slist => getindices("test.found_string"); "joint_condition" string => join(".", "expects"); classes: "$(expects)" expression => strcmp("$(test.found_string[$(expects)])", "$(expected[$(expects)])"); "ok" expression => "$(joint_condition)"; reports: DEBUG:: "pattern $(expects) matches as expected: '$(expected[$(expects)])'" if => "$(expects)"; "pattern $(expects) does NOT match expected: '$(test.found_string[$(expects)])' != '$(expected[$(expects)])'" if => "!$(expects)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/060.x.cf0000644000000000000000000000171315010704253023456 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(1001,1000,1000,1000,1000,40000); } ####################################################### bundle agent check { vars: "time" int => "2682100000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_array_returns_first_index_values.cf0000644000000000000000000000223615010704253033640 0ustar00rootroot00000000000000####################################################### # # Test getvalues() # ####################################################### # If we run getvalues on a classic array index that contains a string # we should end up with a list made up of that single value body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "array[string]" string => "scrumdiddlyumptious"; "array[slist]" slist => { "1", "2" }; "array[idx][2]" slist => { "3", "4" }; # DO not expect to get these values "values" slist => getvalues("array"); } ####################################################### bundle agent check { vars: "expected" slist => { "scrumdiddlyumptious", 1, 2 }; "diff" slist => difference( expected, "test.values" ); classes: "_pass" expression => strcmp( length( diff ), 0 ); methods: _pass:: "pass" usebundle => dcs_pass("$(this.promise_filename)"); !_pass:: "pass" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/201.cf0000644000000000000000000000234315010704253023205 0ustar00rootroot00000000000000####################################################### # # Test getindices(), size 0 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true"; } ####################################################### bundle agent test { vars: "array" string => "zero"; # Intentionally not an array "keys" slist => getindices("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(keys)"; } bundle edit_line test_insert { vars: "keys" slist => { @{test.keys} }; insert_lines: "$(keys)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/015.cf0000644000000000000000000000270215010704253023207 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123.456", "$(nums)"); "ok" and => { "ok_list", "ok123", islessthan("$(test.sum)", "123.457"), isgreaterthan("$(test.sum)", "123.455") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readfile.cf.txt0000644000000000000000000002400115010704253025267 0ustar00rootroot000000000000001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/CFE-954.cf0000644000000000000000000000700615010704253023620 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent init { files: "$(G.testdir)/prod/." create => "true"; "$(G.testdir)/test/." create => "true"; "$(G.testdir)/test/FR1234.gz" create => "true"; } bundle agent test { meta: "description" -> { "CFE-954" } string => "Test that using lsdir on a list where nothing matches does not mess up later iterations"; vars: "directories" slist => {"prod","test"}; "files_regex_1_$(directories)" slist => lsdir( "$(G.testdir)/$(directories)", ".*", "false"), if => isdir( "$(G.testdir)/$(directories)" ); # Suppress errors about missing directory during pre-eval # Expect files_regex_1_prod contains . and .. # Expect files_regex_1_test contains . .. and FR1234.gz "files_regex_2_$(directories)" slist => lsdir( "$(G.testdir)/$(directories)", "FR.*\.gz", "false"), if => isdir( "$(G.testdir)/$(directories)" ); # Suppress errors about missing directory during pre-eval # Expect files_regex_2_prod contains nothing # Expect files_regex_2_test contains FR1234.gz reports: DEBUG|EXTRA:: "files_regex_1_$(directories) is defined" if => isvariable( "files_regex_1_$(directories)" ); "files_regex_1_$(directories) is not defined" unless => isvariable( "files_regex_1_$(directories)" ); "files_regex_2_$(directories) is defined" if => isvariable( "files_regex_2_$(directories)" ); "files_regex_2_$(directories) is not defined" unless => isvariable( "files_regex_2_$(directories)" ); "Expect files_regex_1_prod contains . and .."; "files_regex_1_prod contains $(files_regex_1_prod)"; "Expect files_regex_1_test contains . .. and FR1234.gz"; "files_regex_1_test contains $(files_regex_1_test)"; "Expect files_regex_2_prod contains nothing"; "Expect files_regex_2_test contains FR1234.gz"; "files_regex_2_$(directories) contains $(files_regex_2_$(directories))"; } bundle agent check { vars: "expect_files_regex_1_prod" slist => { ".", ".." }; "expect_files_regex_1_test" slist => { ".", "..", "FR1234.gz" }; "expect_files_regex_2_prod" slist => { }; "expect_files_regex_2_test" slist => { "FR1234.gz" }; "d_1_prod" slist => difference( "check.expect_files_regex_1_prod", "test.files_regex_1_prod" ); "d_1_test" slist => difference( "check.expect_files_regex_1_test", "test.files_regex_1_test" ); "d_2_prod" slist => difference( "check.expect_files_regex_2_prod", "test.files_regex_2_prod" ); "d_2_test" slist => difference( "check.expect_files_regex_2_test", "test.files_regex_2_test" ); classes: "pass" and => { strcmp( "0", length( d_1_prod ) ), strcmp( "0", length( d_1_test ) ), strcmp( "0", length( d_2_prod ) ), strcmp( "0", length( d_2_test ) ) }; reports: DEBUG|EXTRA:: "test.expect_files_regex_2_prod is NOT defined" if => not(isvariable( "test.expect_files_regex_2_prod" )); "test.expect_files_regex_2_prod is defined" if => isvariable( "test.expect_files_regex_2_prod" ); "Difference regex 1 prod: $(d_1_prod)"; "Difference regex 1 test: $(d_1_test)"; "Difference regex 2 prod: $(d_2_prod)"; "Difference regex 2 test: $(d_2_test)"; pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/300.cf0000644000000000000000000000151715010704253023207 0ustar00rootroot00000000000000####################################################### # # Test multiline regcmp # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "haystack" string => "foo bar"; "needle" string => ".*"; } ####################################################### bundle agent check { classes: "ok" and => { regcmp("$(test.needle)", "$(test.haystack)") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/cf_version.cf.expected.json0000644000000000000000000000033215010704253027604 0ustar00rootroot00000000000000{ "after_newer": "yes", "after_newer_major": "yes", "at_major": "yes", "at_same": "yes", "before_older": "yes", "before_older_major": "yes", "between": "yes", "max_older": "yes", "min_newer": "yes" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/isreadable.cf0000644000000000000000000000733615010704253025005 0ustar00rootroot00000000000000############################################################################## # # Test policy function isreadable # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ############################################################################## bundle agent init { files: # Has content "$(G.testfile)_1" content => "Hello CFEngine!"; # No content "$(G.testfile)_2" content => ""; # Does not exists "$(G.testfile)_3" delete => tidy; # Not a regular file "$(G.testfile)_4/." create => "true"; } ############################################################################## bundle agent test { meta: "description" -> { "ENT-9380" } string => "Test policy function filereadable"; "test_soft_fail" -> { "ENT-9930" } string => "hpux|aix", meta => { "ENT-9930" }; } ############################################################################## bundle agent check { classes: # Possibly block for 3 seconds (default) "test_1" # Has content expression => isreadable("$(G.testfile)_1"); "test_2" # No content expression => isreadable("$(G.testfile)_2"); "test_3" # Does not exist expression => not(isreadable("$(G.testfile)_3")); "test_4" # Not a regular file expression => not(isreadable("$(G.testfile)_4")); # Possibly block forever "test_5" # Has content expression => isreadable("$(G.testfile)_1", 0); "test_6" # No content expression => isreadable("$(G.testfile)_2", 0); "test_7" # Does not exist expression => not(isreadable("$(G.testfile)_3", 0)); "test_8" # Not a regular file expression => not(isreadable("$(G.testfile)_4", 0)); # Possibly block for 5 seconds "test_9" # Has content expression => isreadable("$(G.testfile)_1", 5); "test_10" # No content expression => isreadable("$(G.testfile)_2", 5); "test_11" # Does not exists expression => not(isreadable("$(G.testfile)_3", 5)); "test_12" # Not a regular file expression => not(isreadable("$(G.testfile)_4", 5)); "ok" expression => and("test_1", "test_2", "test_3", "test_4", "test_5", "test_6", "test_7", "test_8", "test_9", "test_10", "test_11", "test_12"); reports: DEBUG.!test_1:: "Expected 'test_1' to be defined, but 'test_1' was not defined"; DEBUG.!test_2:: "Expected 'test_2' to be defined, but 'test_2' was not defined"; DEBUG.!test_3:: "Expected 'test_3' to be defined, but 'test_3' was not defined"; DEBUG.!test_4:: "Expected 'test_4' to be defined, but 'test_4' was not defined"; DEBUG.!test_5:: "Expected 'test_5' to be defined, but 'test_5' was not defined"; DEBUG.!test_6:: "Expected 'test_6' to be defined, but 'test_6' was not defined"; DEBUG.!test_7:: "Expected 'test_7' to be defined, but 'test_7' was not defined"; DEBUG.!test_8:: "Expected 'test_8' to be defined, but 'test_8' was not defined"; DEBUG.!test_9:: "Expected 'test_9' to be defined, but 'test_9' was not defined"; DEBUG.!test_10:: "Expected 'test_10' to be defined, but 'test_10' was not defined"; DEBUG.!test_11:: "Expected 'test_11' to be defined, but 'test_11' was not defined"; DEBUG.!test_12:: "Expected 'test_12' to be defined, but 'test_12' was not defined"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/findfiles_glob_bracket.cf0000644000000000000000000000567615010704253027360 0ustar00rootroot00000000000000####################################################### # # Test that square bracket works in glob patterns # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "init", "test", "check" }; version => "1.0"; } ####################################################### bundle agent init { vars: "filenames" slist => { "foo", "bar", "baz" }; files: "$(G.testdir)/$(filenames)" create => "true"; reports: DEBUG:: "Created $(G.testdir)/$(filenames)"; } ####################################################### bundle agent test { meta: "description" string => "Test that square bracket works in glob patterns."; vars: "patterns[a]" string => "$(G.testdir)/[f]oo"; "patterns[b]" string => "$(G.testdir)/b[a]r"; "patterns[c]" string => "$(G.testdir)/ba[z]"; "patterns[d]" string => "$(G.testdir)/[a-z][a-z][a-z]"; "patterns[e]" string => "$(G.testdir)/ba[rz]"; "patterns[f]" string => "$(G.testdir)/[fb][oa][orz]"; "pnames" slist => getindices("patterns"); "found[$(pnames)]" slist => findfiles("$(patterns[$(pnames)])"); "found_string[$(pnames)]" string => join(",", "found[$(pnames)]"); reports: DEBUG:: "findfiles pattern $(pnames) '$(patterns[$(pnames)])' => '$(found_string[$(pnames)])'"; } ####################################################### bundle agent check { meta: "test_skip_needs_work" string => "windows", meta => { "ENT-11176" }; vars: "expected[a]" string => "$(G.testdir)$(const.dirsep)foo"; "expected[b]" string => "$(G.testdir)$(const.dirsep)bar"; "expected[c]" string => "$(G.testdir)$(const.dirsep)baz"; "expected[d]" string => "$(G.testdir)$(const.dirsep)bar,$(G.testdir)$(const.dirsep)baz,$(G.testdir)$(const.dirsep)foo"; "expected[e]" string => "$(G.testdir)$(const.dirsep)bar,$(G.testdir)$(const.dirsep)baz"; "expected[f]" string => "$(G.testdir)$(const.dirsep)bar,$(G.testdir)$(const.dirsep)baz,$(G.testdir)$(const.dirsep)foo"; "expects" slist => getindices("expected"); "fstring" slist => getindices("test.found_string"); "joint_condition" string => join(".", "expects"); classes: "$(expects)" expression => strcmp("$(test.found_string[$(expects)])", "$(expected[$(expects)])"); "ok" expression => "$(joint_condition)"; reports: DEBUG:: "pattern $(expects) matches as expected: '$(expected[$(expects)])'" if => "$(expects)"; "pattern $(expects) does NOT match expected: '$(test.found_string[$(expects)])' != '$(expected[$(expects)])'" if => "!$(expects)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } mustache_iterating_object_should_use_context_for_single_block_render.cf0000644000000000000000000000375615010704253040760 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functionsbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template" string => "# Test1 {{#testcase.test1}} {{#data}} Data = {{.}} {{/data}} {{/testcase.test1}} # Test2 {{#testcase.test2}} {{#data}} Data = {{.}} {{/data}} {{#otherdata}} Other data = {{.}} {{/otherdata}} {{/testcase.test2}}"; "data" data => '{ "testcase": { "test1": { "data": [ "v1", "v2" ] }, "test2": { "data": [ "v1", "v2" ], "otherdata": [ "v3", "v4" ] } } }'; } bundle agent test { meta: # https://mustache.github.io/#demo Try the template and data from above in # the demo site. The issue we see in cfengine is that while iterating over # testcase.test2 the rendering happens for each sub structure iterated # duplicating the data. # So we get Instead of # # Test2 | # Test2 # Data = v1 | Data = v1 # Data = v2 | Data = v2 # Other data = v3 | Other data = v3 # Other data = v4 | Other data = v4 # Data = v1 | # Data = v2 | # Other data = v3 | # Other data = v4 | "description" -> { "CFE-2125" } string => "Test that iterating over object results in single block with correct context (CFE-2125)."; vars: "got" string => string_mustache( $(init.template), @(init.data) ); } bundle agent check { reports: DEBUG:: "got output: $(test.got)"; vars: "expected" string => "# Test1 Data = v1 Data = v2 # Test2 Data = v1 Data = v2 Other data = v3 Other data = v4 "; methods: "check" usebundle => dcs_check_strcmp( $(test.got), $(check.expected), $(this.promise_filename), "no" ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/029.cf0000644000000000000000000000276515010704253023225 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456"; "789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/311.cf0000644000000000000000000000231615010704253023207 0ustar00rootroot00000000000000####################################################### # # Test escape() - basic tests inside an slist # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "s1" slist => { "bstr", escape("foo"), escape("foo.baz"), escape("foo[baz]"), "estr", }; "t1" string => join(",","s1"); "e1" string => "bstr,foo,foo.baz,foo[baz],estr"; } ####################################################### bundle agent check { classes: "ok" and => { regcmp("$(test.t1)", "$(test.e1)"), }; reports: DEBUG:: "'$(test.t1)' comprises $(s1)"; "Comparing actual vs. expected:"; "'$(test.t1)' vs. '$(test.e1)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readfile_absent_does_not_error_in_pre_eval.cf0000644000000000000000000000173415010704253033463 0ustar00rootroot00000000000000body common control { # If you want to see this work on 3.6.x comment out # inputs and bundlesequence, and inline the following # bundles from dcs.cf.sub # - dcs_passif_output # - dcs_passif_expected # - dcs_passif inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; # bundlesequence => { "test", "check" }; version => "1.0"; } ########################################################### bundle agent test { meta: "description" string => "Test that readfile() does not throw an error during pre-eval if the file does not exist."; } ########################################################### bundle agent check { methods: "check" usebundle => dcs_passif_output(".*Hello World.*", ".*failed to read file.*", "$(sys.cf_agent) -Kf $(this.promise_filename).sub", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readcsv.cf.csv0000644000000000000000000000113315010704253025120 0ustar00rootroot00000000000000emptydata,99,xyz,/default/default/methods/'any'[0],p,[],[],default,ny,default.cf.sub emptydata,99,def,/default/default/methods/'any'/default/test_run/methods/'any'[0],q,[],[],default,ny,default.cf.sub emptydata,99,abc,/default/default/methods/'any'/default/test_run/methods/'any'[0],r,[],[],default,ny,default.cf.sub emptydata,99,pqr,/default/default/methods/'any'/default/test_run/methods/'any'[0],s,[],[],default,ny,default.cf.sub emptydata,110,???,"[""Proposed executable file '/TEST.cfengine.willfail' doesn't exist"",""'/TEST.cfengine.willfail' promises to be executable but isn't""]",default cfengine-3.24.2/tests/acceptance/01_vars/02_functions/gettags.cf0000644000000000000000000000333215010704253024340 0ustar00rootroot00000000000000# Test that getvariabletags and getclasstags work correctly body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { classes: "myclass" expression => "any", meta => { "mytag1" }; "myotherclass" expression => "any", meta => { "mytag5", "mytag51" }; "myplainclass" expression => "any"; "keyclass" expression => "any", meta => { "foo=1", "mytag51", "foo", "foo=2" }; "keyclass2" expression => "any", meta => { "foo" }; vars: "tests" slist => { "1", "2", "3", "4", "5" }; "myvar" string => "123", meta => { "mytag3" }; "myothervar" string => "123"; "keyvar" int => "1", meta => { "foo=1", "mytag51", "foo", "foo=2" }; "keyvar2" real => "20", meta => { "foo" }; } bundle agent test { vars: "tags1" slist => getclassmetatags("myclass"); "tags2" slist => getclassmetatags("myplainclass"); "tags3" slist => getvariablemetatags("init.myvar"); "tags4" slist => getvariablemetatags("init.myothervar"); "tags5" slist => getclassmetatags("myotherclass"); "tags6" slist => getclassmetatags("nosuchclass"); "tags7" slist => getvariablemetatags("nosuchvariable"); "tags8" slist => getclassmetatags("keyclass", "foo"); "tags9" slist => getclassmetatags("keyclass2", "foo"); "tagsa" slist => getvariablemetatags("init.keyvar", "foo"); "tagsb" slist => getvariablemetatags("init.keyvar2", "foo"); } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/044.cf0000644000000000000000000000275615010704253023222 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456 789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/url_get_local.cf.expected.json0000644000000000000000000000047215010704253030267 0ustar00rootroot00000000000000{ "kept": { "res4": "###########################################################\n#\n# Test url_get() locally\n#\n###########################################################\n\nbody common control\n{\n inputs => { \"../../defau", "res4/rc": 0, "res4/returncode": 0, "res4/success": true } } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/missing_functions.cf0000644000000000000000000000212115010704253026436 0ustar00rootroot00000000000000############################################################################## # # Redmine #3907: supposedly missing functions (in this case, a classes body with parameters) aren't # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -KI -f $(this.promise_filename).sub | $(G.grep) 'FnCall'", "useshell"); } bundle agent check { # If the output contains the FnCall warning about 9fdee2550bec1030e22addb0dc9d7218b9174c70, we fail classes: "ok" not => regcmp(".*9fdee2550bec1030e22addb0dc9d7218b9174c70.*", "$(test.subout)"); reports: DEBUG:: "agent output: $(test.subout)"; ok:: "The FnCall bogus warning didn't happen"; !ok:: "The FnCall bogus warning happened"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.tail28.txt0000644000000000000000000000003515010704253027016 0ustar00rootroot00000000000000STUVWXYZ0123456789abcdefghij cfengine-3.24.2/tests/acceptance/01_vars/02_functions/046.cf0000644000000000000000000000301215010704253023206 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456 789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_2.cf0000644000000000000000000000322215010704253026150 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2768" } string => "Test that classfiltercsv() works: - no column headings - simple filtering (no duplicates after filter) - no sorting"; } bundle agent check { vars: "data_file" string => "$(this.promise_filename).csv"; "d" data => classfiltercsv( $(data_file), "false", # Data file contains column headings 0); # Column containing class expression to filter with classes: # Check if Token has the value we expect "Token_OK" expression => strcmp( "$(d[0][0])", "net.ipv4.ip_forward" ); # Check if Value has the value we expect "Value_OK" expression => strcmp( "$(d[0][1])", "ANYVALUE" ); # Check if the result contains the number of records we expect. "Length_OK" expression => strcmp( length( d ), 1 ); methods: "Pass/FAIL" usebundle => dcs_passif_expected( 'Token_OK,Value_OK,Length_OK', '', $(this.promise_filename) ), inherit => "true"; reports: DEBUG|EXTRA:: "Function returned:$(with)" with => string_mustache( "{{%-top-}}", d ); "supercalifragilisticexpialidociousNOTDEFINED is actually defined." if => "supercalifragilisticexpialidociousNOTDEFINED"; "supercalifragilisticexpialidociousNOTDEFINED is not defined (as expected)" unless => "supercalifragilisticexpialidociousNOTDEFINED"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata.cf.json0000644000000000000000000000011515010704253025413 0ustar00rootroot00000000000000{ "x": [ 1, 2, 3 ], "y": "more data here", "z": { "300": 400 } } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/filestat_linktarget.cf0000644000000000000000000000350215010704253026740 0ustar00rootroot00000000000000####################################################### # # Test filestat() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { commands: "$(G.ln) -fs $(G.testfile) $(G.testfile)"; reports: DEBUG:: "Created $(G.testfile) linked to itself"; } ####################################################### bundle agent test { meta: "test_suppress_fail" string => "windows", meta => { "redmine4608" }; vars: "fields" slist => splitstring("linktarget,linktarget_shallow", ",", 999); "stat[$(fields)]" string => filestat($(G.testfile), $(fields)); } ####################################################### bundle agent check { vars: # Note that on W32 the link target is the file itself "expected[linktarget]" string => $(G.testfile); "expected[linktarget_shallow]" string => $(G.testfile); "expects" slist => getindices("expected"); "fields" slist => getindices("test.stat"); "joint_condition" string => join(".", "expects"); classes: "$(expects)" expression => strcmp("$(test.stat[$(expects)])", "$(expected[$(expects)])"); "ok" expression => "$(joint_condition)"; reports: DEBUG:: "got $(G.testfile) field $(fields)=$(test.stat[$(fields)])"; "got $(G.testfile) field $(expects)=$(test.stat[$(expects)]) matches expected" if => "$(expects)"; "got $(G.testfile) field $(expects)=$(test.stat[$(expects)]) did NOT match expected $(expected[$(expects)])" if => "!$(expects)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.reverse.txt0000644000000000000000000002400115010704253027365 0ustar00rootroot00000000000000jihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba cfengine-3.24.2/tests/acceptance/01_vars/02_functions/006.cf0000644000000000000000000000270015010704253023205 0ustar00rootroot00000000000000####################################################### # # Test diskfree() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "positive_disk" string => "$(G.etc)"; "p_disk" string => "$(G.etc_passwd)"; "zero_disk" string => "/lkjqeroiu"; "positive" int => diskfree("$(positive_disk)"); "p" int => diskfree("$(p_disk)"); "zero" int => diskfree("$(zero_disk)"); meta: "test_suppress_fail" string => "windows", meta => { "redmine4686" }; } ####################################################### bundle agent check { classes: "ok" and => { strcmp("$(test.zero)", "0"), isgreaterthan("$(test.p)", "0"), isgreaterthan("$(test.positive)", "0"), }; reports: DEBUG:: "Expected 0 size on $(test.zero_disk), found $(test.zero)"; "Expected >1 size on $(test.p_disk), found $(test.p)"; "Expected >1 size on $(test.positive_disk), found $(test.positive)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/CFE-2704-0.cf0000644000000000000000000000100315010704253024017 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2704" } string => "Test that attempting to merge incompatible data does not segfault."; vars: "data" data => "{\"env\":\"test\"}"; "node" data => mergedata("[]", "data[env]"); } bundle agent check { methods: "Pass if we made it this far" usebundle => dcs_pass( $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/randomint.cf0000644000000000000000000000177315010704253024704 0ustar00rootroot00000000000000####################################################### # # Test randomint() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "nine_a" int => randomint(9,10); "nine_b" int => randomint(9,9); "nine_c" int => randomint(10,9); } ####################################################### bundle agent check { classes: "ok_a" expression => strcmp("$(test.nine_a)", "9"); "ok_b" expression => strcmp("$(test.nine_b)", "9"); "ok_c" expression => strcmp("$(test.nine_c)", "9"); "ok" and => {ok_a, ok_b, ok_c}; reports: DEBUG:: "nine_a: $(test.nine_a)"; "nine_b: $(test.nine_b)"; "nine_c: $(test.nine_c)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/205.cf0000644000000000000000000000322415010704253023210 0ustar00rootroot00000000000000####################################################### # # getindices should not truncate keys # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "longstring" string => "abcdefghijklmnopqrstuvwxyz1234abcdefghijklmnopqrstuvwxyz1234abcdefghijklmnopqrstuvwxyz1234abcdefghijklmnopqrstuvwxyz1234abcdefghijklmnopqrstuvwxyz1234abcdefghijklmnopqrstuvwxyz1234AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQRSTUVWXYZ"; "table[$(longstring)]" string => "0050"; "member" slist => getindices("table"); } ####################################################### bundle agent test { } ####################################################### bundle agent check { classes: "ok" expression => strcmp($(init.member), $(init.longstring)); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sysctl.cf0000644000000000000000000000066515010704253024231 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { meta: "test_skip_unsupported" string => "!linux"; commands: "$(G.env) CFENGINE_TEST_OVERRIDE_PROCDIR=$(this.promise_dirname)/proc $(sys.cf_agent) -DAUTO -f $(this.promise_filename).sub"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/223.cf0000644000000000000000000000256115010704253023213 0ustar00rootroot00000000000000####################################################### # # Test grep(), size 2 local array # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "Two"; "Three"; } ####################################################### bundle agent test { vars: "array" slist => { "One", "Two", "Three", "Four", "Five" }; "vals" slist => grep("T.*", "array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/601.cf0000644000000000000000000000463215010704253023214 0ustar00rootroot00000000000000####################################################### # # Test readrealarray(), introduce 777 12345 with no other fields # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 12345 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readrealarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[12345][0])", "12345"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[12345][1]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[12345][0] = '12345', saw '$(test.ary[12345][0])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/034.cf0000644000000000000000000000300715010704253023207 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123,,,456,789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/067.cf0000644000000000000000000000307415010704253023221 0ustar00rootroot00000000000000####################################################### # # Test getusers() arg1 only # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: # All users except root, bin, and daemon freebsd|openbsd:: "users" slist => getusers("","0,1,3"); !freebsd.!openbsd:: "users" slist => getusers("","0,1,2"); files: "$(G.testfile)" delete => init_delete; reports: cfengine_3:: "$(users)" report_to_file => "$(G.testfile)"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: # Try to delete the lines that shouldn't be there anyway "$(G.testfile)" edit_line => test_delete, classes => full_set; } bundle edit_line test_delete { delete_lines: "root"; "daemon"; "bin"; } body classes full_set { promise_kept => { "pass" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { classes: "ok" expression => "pass&!fail"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/ifelse.cf.expected.json0000644000000000000000000000043015010704253026715 0ustar00rootroot00000000000000{ "empty": "", "empty2": "hardclass expected", "expression": "bundle class OK", "five": "5 parameters OK", "hardclass": "hardclass OK", "one": "1", "single": "single string parameter", "unresolved1": "expected fallback 1", "unresolved2": "expected fallback 2" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_4.cf.csv0000644000000000000000000000045015010704253026744 0ustar00rootroot00000000000000ClassExpr,Token,Value any,net.ipv4.ip_forward,ANYVALUE supercalifragilisticexpialidociousNOTDEFINED,net.ipv4.ip_forward,SHOULD_BE_FILTERED_OUT supercalifragilisticexpialidociousNOTDEFINED,net.ipv4.ip_forward,SHOULD,BE,FILTERED,OUT cfengine,net.ipv4.ip_forward,INVALID,SHOULD,BE,FILTERED,OUT cfengine-3.24.2/tests/acceptance/01_vars/02_functions/202.cf0000644000000000000000000000245615010704253023213 0ustar00rootroot00000000000000####################################################### # # Test getindices(), size 1 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "alpha"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "keys" slist => getindices("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(keys)"; } bundle edit_line test_insert { vars: "keys" slist => { @{test.keys} }; insert_lines: "$(keys)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/442.cf0000644000000000000000000000577615010704253023231 0ustar00rootroot00000000000000####################################################### # # Test readstringarrayidx(), introduce a duplicate key # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test this:too 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "4"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "this"), strcmp("$(test.ary[1][1])", "is"), strcmp("$(test.ary[1][2])", "a"), strcmp("$(test.ary[1][3])", "test"), strcmp("$(test.ary[2][0])", "this"), strcmp("$(test.ary[2][1])", "too"), strcmp("$(test.ary[3][0])", "1"), strcmp("$(test.ary[3][1])", "2"), strcmp("$(test.ary[3][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][4]"), isvariable("test.ary[2][2]"), isvariable("test.ary[3][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = 'this', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = 'is', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = 'a', saw '$(test.ary[1][2])'"; "expected test.ary[1][3] = 'test', saw '$(test.ary[1][3])'"; "expected test.ary[2][0] = 'this', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'too', saw '$(test.ary[2][1])'"; "expected test.ary[3][0] = '1', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = '2', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '3', saw '$(test.ary[3][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/storejson_edge_case.cf0000644000000000000000000001143115010704253026706 0ustar00rootroot00000000000000# Test fix for previous bug that truncates JSON data greater than 4096 bytes body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ########################################################## bundle agent test { vars: "data" string => storejson('{ "A very long text": "Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else."}'); } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata.cf0000644000000000000000000001405315010704253024635 0ustar00rootroot00000000000000####################################################### # # Test mergedata() # This test is unstable until we have canonical JSON output # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "load1" data => parsejson('[ 1, 2, 3]'); "load2" slist => { "element1", "element2", "element3" }; "load3" data => parsejson('{ "x": "y" }'); "load4" slist => { }; "load5[mykey]" slist => { "myvalue" }; "load5[anotherkey]" string => "anothervalue"; "load5[lastkey!]" slist => {}; "X" slist => { "1", "2", "3", "4", "5" }; "Y" slist => { @(X) }; "load_$(X)" data => mergedata("load$(X)"); "load_$(X)_$(Y)" data => mergedata("load$(X)", "load$(Y)"); "wrap_key_$(X)" data => mergedata('{ "wrapkey": load$(X) }'); "wrap_array_$(X)" data => mergedata('[ load$(X) ]'); "bad1" data => mergedata(missingvar); "bad2" data => mergedata(load1, missingvar); "justastring" string => "me"; "bad3" data => mergedata(justastring); "bad4" data => mergedata(load1, justastring); } ####################################################### bundle agent check { vars: "X" slist => { @(test.X) }; "Y" slist => { @(test.X) }; "expected_1" string => '[1,2,3]'; "expected_2" string => '["element1","element2","element3"]'; "expected_3" string => '{"x":"y"}'; "expected_4" string => '[]'; "expected_5" string => '{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_1_1" string => '[1,2,3,1,2,3]'; "expected_1_2" string => '[1,2,3,"element1","element2","element3"]'; "expected_1_3" string => '{"0":1,"1":2,"2":3,"x":"y"}'; "expected_1_4" string => '[1,2,3]'; "expected_1_5" string => '{"0":1,"1":2,"2":3,"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_2_1" string => '["element1","element2","element3",1,2,3]'; "expected_2_2" string => '["element1","element2","element3","element1","element2","element3"]'; "expected_2_3" string => '{"0":"element1","1":"element2","2":"element3","x":"y"}'; "expected_2_4" string => '["element1","element2","element3"]'; "expected_2_5" string => '{"0":"element1","1":"element2","2":"element3","anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_3_1" string => '{"0":1,"1":2,"2":3,"x":"y"}'; "expected_3_2" string => '{"0":"element1","1":"element2","2":"element3","x":"y"}'; "expected_3_3" string => '{"x":"y"}'; "expected_3_4" string => '{"x":"y"}'; "expected_3_5" string => '{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"],"x":"y"}'; "expected_4_1" string => '[1,2,3]'; "expected_4_2" string => '["element1","element2","element3"]'; "expected_4_3" string => '{"x":"y"}'; "expected_4_4" string => '[]'; "expected_4_5" string => '{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_5_1" string => '{"0":1,"1":2,"2":3,"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_5_2" string => '{"0":"element1","1":"element2","2":"element3","anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_5_3" string => '{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"],"x":"y"}'; "expected_5_4" string => '{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_5_5" string => '{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}'; "expected_wrapped_key_1" string => '{"wrapkey":[1,2,3]}'; "expected_wrapped_key_2" string => '{"wrapkey":["element1","element2","element3"]}'; "expected_wrapped_key_3" string => '{"wrapkey":{"x":"y"}}'; "expected_wrapped_key_4" string => '{"wrapkey":[]}'; "expected_wrapped_key_5" string => '{"wrapkey":{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}}'; "expected_wrapped_array_1" string => '[[1,2,3]]'; "expected_wrapped_array_2" string => '[["element1","element2","element3"]]'; "expected_wrapped_array_3" string => '[{"x":"y"}]'; "expected_wrapped_array_4" string => '[[]]'; "expected_wrapped_array_5" string => '[{"anotherkey":"anothervalue","lastkey!":[],"mykey":["myvalue"]}]'; "actual_$(X)_$(Y)" string => format("%S", "test.load_$(X)_$(Y)"); "actual_$(X)" string => format("%S", "test.load_$(X)"); "actual_wrapped_key_$(X)" string => format("%S", "test.wrap_key_$(X)"); "actual_wrapped_array_$(X)" string => format("%S", "test.wrap_array_$(X)"); classes: "ok_$(X)_$(Y)" expression => strcmp("$(actual_$(X)_$(Y))", "$(expected_$(X)_$(Y))"); "ok_$(X)" expression => strcmp("$(actual_$(X))", "$(expected_$(X))"); "not_ok_wrapped_key_$(X)" not => strcmp("$(actual_wrapped_key_$(X))", "$(expected_wrapped_key_$(X))"); "not_ok_wrapped_array_$(X)" not => strcmp("$(actual_wrapped_array_$(X))", "$(expected_wrapped_array_$(X))"); "ok" not => classmatch("not_ok_.*"); reports: DEBUG:: "$(X): actual $(actual_$(X)) != $(X) expected $(expected_$(X))" if => "!ok_$(X)"; "$(X): actual wrap key $(actual_wrapped_key_$(X)) != $(X) expected wrapped key $(expected_wrapped_key_$(X))" if => "not_ok_wrapped_key_$(X)"; "$(X): actual wrap array $(actual_wrapped_array_$(X)) != $(X) expected wrapped array $(expected_wrapped_array_$(X))" if => "not_ok_wrapped_array_$(X)"; "$(X)+$(Y): actual $(actual_$(X)_$(Y)) != $(X)+$(Y) expected $(expected_$(X)_$(Y))" if => "!ok_$(X)_$(Y)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata_CFE-2551-0.cf0000644000000000000000000000312315010704253026035 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent main { methods: "test"; "check"; } bundle agent test { meta: "description" -> { "CFE-2551" } string => "Test that variables defined in other bundles with the same name are not included in a merged result"; "test_soft_fail" string => "any", meta => { "CFE-2551" }; vars: "a" string => "string a"; "b" string => "string b"; "vars1[a]" string => "$(a)"; "vars1[b]" string => "$(b)"; methods: "run_low_test_merged" usebundle => test_merged_low; } bundle agent test_merged_low { vars: "c" string => "string c"; "vars1[c]" string => "$(c)"; # We expect that only the values from the classic array vars1 in this # bundle will be merged together. And thus, we should only end up with ={ "vars1" : { "c": "string c" } }= "merged_data_vars" data => mergedata('{ "vars1": vars1 }'); "merged_data_vars_str" string => format( "%S", merged_data_vars ); reports: DEBUG|EXTRA:: "$(this.bundle) : merged_data_vars_str : $(merged_data_vars_str)"; } bundle agent check { vars: "expected" string => '{"vars1":{"c":"string c"}}'; classes: "pass" expression => strcmp( $(expected), $(test_merged_low.merged_data_vars_str) ); reports: pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; "expected: '$(expected)'"; "got: '$(test_merged_low.merged_data_vars_str)'"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/regarray.cf0000644000000000000000000000166115010704253024521 0ustar00rootroot00000000000000####################################################### # # Test regarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "myarray[0]" string => "bla1"; "myarray[1]" string => "bla2"; "myarray[3]" string => "bla"; "myarray" string => "345"; "not" string => "345"; } ####################################################### bundle agent check { classes: "ok" expression => regarray("test.myarray","b.*2"); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/join.cf.expected.json0000644000000000000000000000126415010704253026413 0ustar00rootroot00000000000000{ "join_a": "b:c:a", "join_b": "100:9:10", "join_c": "", "join_d": ":a::b", "join_e": "a:1:b", "join_f": "100:200:300", "join_g": "1.11:-2.22:-3.33", "join_h": "-10:0:200", "join_i": "1:2::3000:", "join_j": "1:2:true:false", "join_k": "", "join_l": "100:200", "join_m": "cf_null", "join_n": "a:b:c:cf_null", "join_o": "b:c:a", "join_p": "cf_null", "join_q": ":::", "join_r": ":", "join_s": "::cf_null", "join_t": "a:b:c:cf_null:cf_null:a:b:c:cf_null::", "lists": [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/reverse.cf0000644000000000000000000000170015010704253024352 0ustar00rootroot00000000000000####################################################### # # Test reverse() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "a" slist => { "c", "b", "a" }; "b" slist => { }; } ####################################################### bundle agent test { vars: "sa" slist => reverse("init.a"); "sb" slist => reverse("init.b"); "inline" slist => reverse('[ "q", "p", "r" ]'); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/024.cf0000644000000000000000000000253315010704253023211 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok" and => { "ok_list", islessthan("$(test.sum)", "123.1"), isgreaterthan("$(test.sum)", "122.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readstringlist-many-comments.cf0000755000000000000000000000242415010704253030531 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "descripton" -> { "ENT-5042" } string => "Test that readstringlist correctly ignores many comment lines"; # https://regex101.com/r/OZUgku/1/ vars: "my_list_of_strings" slist => readstringlist( "$(this.promise_filename).list.txt", # File to read "\s*#[^\n]*", # Exclude hash comment lines "\s", # Split on whitespace inf, # Maximum number of entries inf); # Maximum number of bytes to read } bundle agent check { vars: "expected" slist => { "jay", "dave" }; methods: "Pass/FAIL" usebundle => dcs_check_diff_elements( @(test.my_list_of_strings), # First set of elements @(expected), # Second set of elements $(this.promise_filename), # Full path to test policy file "no"); # Expected difference in elements } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/network/0000755000000000000000000000000015010704253024060 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/network/008.cf0000644000000000000000000000274415010704253024710 0ustar00rootroot00000000000000####################################################### # # Test host2ip() # ####################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: # Neither of these are likely to change... "localhost" string => host2ip("localhost"); "a" string => host2ip("a.root-servers.net"); } ####################################################### bundle agent check { vars: "localhost" string => "127.0.0.1"; "localhost_6" string => "::1"; "a" string => "198.41.0.4"; "a_6" string => "2001:503:ba3e::2:30"; classes: "ok_a" or => { strcmp("$(test.a)", "$(a)"), strcmp("$(test.a)", "$(a_6)"), }; "ok_localhost" or => { strcmp("$(test.localhost)", "$(localhost)"), strcmp("$(test.localhost)", "$(localhost_6)"), }; "ok" and => { "ok_a", "ok_localhost", }; reports: DEBUG:: "Expected $(test.localhost) == $(localhost)"; "Expected $(test.a) == ( $(a) or $(a_6) )"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/network/selectservers.cf0000644000000000000000000000305415010704253027265 0ustar00rootroot00000000000000# Test that failure to connect to remote host does not result in "Could not # close socket" error messages. body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } body agent control { # 5 seconds timeout for selectservers for non-connecting host 8.8.8.8 default_timeout => "5"; } bundle agent init { } bundle agent test { vars: # The first two hosts listen to port 80, the third does not listen # to port 80, the fourth does not even resolve "hosts" slist => { "cfengine.com", "www.duckduckgo.com", "smtp.mail.yahoo.com", "inexistent-server" }; "retval" int => selectservers("@(hosts)","80","","","100","alive_servers"); } bundle agent check { classes: "up2servers" expression => strcmp("$(test.retval)", "2"); "first_is_ok" expression => isvariable("test.alive_servers[0]"); "second_is_ok" expression => isvariable("test.alive_servers[1]"); "third_is_bad" not => isvariable("test.alive_servers[2]"); "fourth_is_bad" not => isvariable("test.alive_servers[3]"); methods: # All above classes must be set for test to pass "" usebundle => dcs_passif_expected("up2servers,first_is_ok,second_is_ok,third_is_bad,fourth_is_bad", "", $(this.promise_filename)), inherit => "true"; reports: DEBUG:: "retval: $(test.retval)"; "alive_servers: $(test.alive_servers[0]) $(test.alive_servers[1]) $(test.alive_servers[2])"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/network/url_get.cf.expected.json0000644000000000000000000000101715010704253030602 0ustar00rootroot00000000000000{ "kept": { "res1/rc": 0, "res1/returncode": 200, "res1/success": true, "res2": "", "res2/error_message": "Couldn't resolve host name", "res2/rc": 6, "res2/returncode": 0, "res2/success": false, "res3": "/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */\n!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a)", "res3/rc": 0, "res3/returncode": 200, "res3/success": true } } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/network/url_get.cf0000644000000000000000000000416615010704253026042 0ustar00rootroot00000000000000########################################################### # # Test url_get() # ########################################################### body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent init { vars: "options_limit" data => ' { "url.max_content": 200, "nosuchoption": 100, "url.verbose": 0, "url.headers": [ "Foo: bar" ] }'; "options_clean" data => '{}'; "res1" data => url_get("http://acme.com", options_clean); "res2" data => url_get("http://nosuchcfenginehost.com", options_clean); # static content, we hope won't change much "res3" data => url_get("http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js", options_limit); } bundle agent test { meta: "test_skip_unsupported" string => "!feature_curl"; vars: "kept" data => mergedata( '{ "res1/returncode": init.res1[returncode] }', '{ "res1/rc": init.res1[rc] }', '{ "res1/success": init.res1[success] }', '{ "res2": init.res2[content] }', '{ "res2/returncode": init.res2[returncode] }', '{ "res2/rc": init.res2[rc] }', '{ "res2/error_message": init.res2[error_message] }', '{ "res2/success": init.res2[success] }', '{ "res3": init.res3[content] }', '{ "res3/returncode": init.res3[returncode] }', '{ "res3/rc": init.res3[rc] }', '{ "res3/success": init.res3[success] }' ); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_2.cf.csv0000644000000000000000000000017315010704253026744 0ustar00rootroot00000000000000any,net.ipv4.ip_forward,ANYVALUE supercalifragilisticexpialidociousNOTDEFINED,net.ipv4.ip_forward,SHOULD_BE_FILTERED_OUT cfengine-3.24.2/tests/acceptance/01_vars/02_functions/findfiles_up.cf.expected.json0000755000000000000000000000077715010704253030136 0ustar00rootroot00000000000000{ "test[0]": "/a, /file_1.png, /file_1.txt", "test[1]": "/a/b/c/d/e/f/., /a/b/c/d/e/., /a/b/c/d/., /a/b/c/., /a/b/., /a/., /.", "test[2]": "/file_1.txt", "test[3]": "/a/file_2.txt", "test[4]": "/a/b/c/d/e/f/file_3.txt", "test[5]": "/a/b/c/d/e/f/file_3.txt, /a/b/c/d/file_3.txt", "test[6]": "/file_1.png, /file_1.txt", "test[7]": "/a/b/c/d/e/f/file_3.txt, /a/b/c/d/file_3.txt, /a/b/file_3.txt, /a/file_2.txt, /file_1.txt", "test[8]": "/a/b/c/d/file_3.txt", "test[9]": "/a/b/c/d/file_3.txt" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readtcp_connection_fail.cf0000644000000000000000000000150115010704253027532 0ustar00rootroot00000000000000# Test that failure to connect to remote host does not result in "Could not # close socket" error messages. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "useshell"); } bundle agent check { classes: "ok_output" not => regcmp(".*Bad file descriptor.*", "$(test.subout)"); "ok_no_crash" expression => isvariable("test.subout"); "ok" and => { "ok_output", "ok_no_crash" }; reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readstringarrayidx.cf0000644000000000000000000000270415010704253026612 0ustar00rootroot00000000000000# Redmine#2926: test long lines with readstringarrayidx() body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "dim" int => readstringarrayidx("parms", "$(this.promise_filename).txt", "\s*#[^\n]*", ";", 9999, 99999); "pk" slist => getindices("parms"); reports: DEBUG:: "$(parms[$(pk)]): $(parms[$(pk)][0]) $(parms[$(pk)][16])"; } bundle agent check { vars: "length" int => length("test.pk"); "last" string => nth("test.value", 599); classes: "ok1" expression => strcmp("$(test.dim)", "3"); "ok2" expression => strcmp("$(test.dim)", "$(length)"); "ok3" expression => strcmp("$(test.parms[2][0])", "not_working_app_config"); "ok" and => { "ok1", "ok2", "ok3" }; reports: DEBUG.ok1:: "passed1"; DEBUG.ok2:: "passed2"; DEBUG.ok3:: "passed3"; DEBUG.!ok1:: "failed1 $(test.dim) != 3"; DEBUG.!ok2:: "failed2 $(test.dim) != $(length)"; DEBUG.!ok3:: "failed3 $(test.parms[2][0]) != not_working_app_config"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata.cf.csv0000644000000000000000000000003115010704253025232 0ustar00rootroot00000000000000a,b,c d,"e",f "g,h,i" cfengine-3.24.2/tests/acceptance/01_vars/02_functions/filter.cf0000644000000000000000000000475715010704253024203 0ustar00rootroot00000000000000####################################################### # # Test filter() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: "tests" slist => { "fgrep09", "exact1", "exactdot", "regexdot", "invert", "max2", "max0", "grep09" }; "lists" slist => { "s1", "d1", "d2", "dempty" }; "s1" slist => { 1,2,3, "one", "two", "three", "long string", "one", "two", "three", }; "d1" data => parsejson(' [1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three"]'); "d2" data => parsejson(' { "one": 1, "two": 2, "three": 3, "x": "y", "a": "b", "p": "q" }'); "dempty" data => parsejson('[]'); "$(lists)_fgrep09" slist => filter("[0-9]", $(lists), "true", "false", 999); "$(lists)_exact1" slist => filter("one", $(lists), "false", "false", 999); "$(lists)_exactdot" slist => filter(".", $(lists), "false", "false", 999); "$(lists)_regexdot" slist => filter(".", $(lists), "true", "false", 999); "$(lists)_invert" slist => filter("[0-9]", $(lists), "true", "true", 999); "$(lists)_max2" slist => filter(".*", $(lists), "true", "false", 2); "$(lists)_max0" slist => filter(".*", $(lists), "true", "false", 0); "$(lists)_grep09" slist => grep("[0-9]", $(lists)); # with inline JSON "inline_fgrep09" slist => filter("[0-9]", '[1,2,3]', "true", "false", 999); "inline_exact1" slist => filter("one", '[1,2,3]', "false", "false", 999); "inline_exactdot" slist => filter(".", '[1,2,3]', "false", "false", 999); "inline_regexdot" slist => filter(".", '[1,2,3]', "true", "false", 999); "inline_invert" slist => filter("[0-9]", '[1,2,3]', "true", "true", 999); "inline_max2" slist => filter(".*", '[1,2,3]', "true", "false", 2); "inline_max0" slist => filter(".*", '[1,2,3]', "true", "false", 0); "inline_grep09" slist => grep("[0-9]", '[1,2,3]'); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readcsv.cf0000644000000000000000000000247515010704253024340 0ustar00rootroot00000000000000# test readcsv() body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "c" data => readcsv("$(this.promise_filename).csv"); "cs" string => format("%S", c); } bundle agent check { vars: "expected" string => '[["emptydata","99","xyz","/default/default/methods/\'any\'[0]","p","[]","[]","default","ny","default.cf.sub"],["emptydata","99","def","/default/default/methods/\'any\'/default/test_run/methods/\'any\'[0]","q","[]","[]","default","ny","default.cf.sub"],["emptydata","99","abc","/default/default/methods/\'any\'/default/test_run/methods/\'any\'[0]","r","[]","[]","default","ny","default.cf.sub"],["emptydata","99","pqr","/default/default/methods/\'any\'/default/test_run/methods/\'any\'[0]","s","[]","[]","default","ny","default.cf.sub"],["emptydata","110","???","[\\"Proposed executable file \'/TEST.cfengine.willfail\' doesn\'t exist\\",\\"\'/TEST.cfengine.willfail\' promises to be executable but isn\'t\\"]","default"]]'; methods: "check" usebundle => dcs_check_strcmp("$(test.cs)", $(expected), "$(this.promise_filename)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/033.cf0000644000000000000000000000301015010704253023200 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456 789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getindices_size2_with_expansion.cf0000644000000000000000000000325015010704253031252 0ustar00rootroot00000000000000####################################################### # # Test getindices(), size 2 with variable expansion # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "the fini$end"; "the end$(const.dollar)fini"; "XXX dummy XXX"; "YYY $(init.dummy) YYY"; } ####################################################### bundle agent test { vars: "array[the fini$end]" string => "additional line again"; "array[the end$(const.dollar)fini]" string => "one$(const.n)extra line"; "array[XXX dummy XXX]" string => "XXX dummy XXX"; "array[YYY $(init.dummy) YYY]" string => "YYY $(init.dummy) YYY"; "keys" slist => getindices("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(keys)"; } bundle edit_line test_insert { vars: "keys" slist => { @{test.keys} }; insert_lines: "$(keys)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/ifelse.cf0000644000000000000000000000337615010704253024161 0ustar00rootroot00000000000000####################################################### # # Test ifelse() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common init { classes: "myclass" expression => "any"; } ####################################################### bundle agent test { classes: "myclass2" expression => "any"; vars: "one" string => ifelse(1); "single" string => ifelse("single string parameter"); "hardclass" string => ifelse("cfengine", "hardclass OK", "hardclass broken"); "empty" string => ifelse("cfengine", "", "hardclass broken"); "empty2" string => ifelse("!cfengine", "", "hardclass expected"); "five" string => ifelse("this is not true", "5 parameters broken", "this is also not true", "5 parameters broken 2", "5 parameters OK"); "unresolved1" string => ifelse( isvariable( "missing" ), "$(missing)", "expected fallback 1"); "unresolved2" string => ifelse( isvariable( "missing" ), "$($(missing))", "expected fallback 2"); any:: "mystring" string => ifelse("any","pass","!any","$(foo)","bar"); myclass2:: "expression" string => ifelse("myclass.myclass2", "bundle class OK", "bundle class broken"); reports: "ifelse result: $(mystring)"; } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/054.cf0000644000000000000000000000166715010704253023223 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,1,0,0,0,100); } ####################################################### bundle agent check { vars: "time" int => "2592100"; # 1 month == 30 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.txt0000644000000000000000000002400115010704253025713 0ustar00rootroot00000000000000abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghij cfengine-3.24.2/tests/acceptance/01_vars/02_functions/500.cf0000644000000000000000000000531715010704253023213 0ustar00rootroot00000000000000####################################################### # # Test readintarray(), simple # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999:888:777:666 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readintarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999][0])", "999"), strcmp("$(test.ary[999][1])", "888"), strcmp("$(test.ary[999][2])", "777"), strcmp("$(test.ary[999][3])", "666"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999][0] = '999', saw '$(test.ary[999][0])'"; "expected test.ary[999][1] = '888', saw '$(test.ary[999][1])'"; "expected test.ary[999][2] = '777', saw '$(test.ary[999][2])'"; "expected test.ary[999][3] = '666', saw '$(test.ary[999][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/wrap_container_fncalls.cf0000644000000000000000000000526015010704253027421 0ustar00rootroot00000000000000####################################################### # # Test wrapped fncalls that return data containers # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common init { classes: "predefined" expression => "any"; } bundle agent test { vars: "base_list" slist => { "a", "b", "c", "aaa", "bbb", "ccc" }; "base_data" data => '{ "x": 100, "y": "z" }'; "mapdata_spec" string => "<<< $(this.k)=$(this.v) >>>"; "sort_mapdata_inline_json" slist => sort(mapdata('none', $(mapdata_spec), '[1,2,3]'), lex); "sort_mapdata_slist" slist => sort(mapdata('none', $(mapdata_spec), base_list), lex); "sort_mapdata_data" slist => sort(mapdata('none', $(mapdata_spec), base_data), lex); "sort_mapdata_mergedata_inline_json" slist => sort(mapdata('none', $(mapdata_spec), '[1,2,3]'), lex); "sort_mapdata_mergedata_slist" slist => sort(mapdata('none', $(mapdata_spec), mergedata(base_list)), lex); "sort_mapdata_mergedata_data" slist => sort(mapdata('none', $(mapdata_spec), mergedata(base_data)), lex); # we can nest functions that return slists too! "sort_mapdata_sort_slist" slist => sort(mapdata('none', $(mapdata_spec), sort(base_list, int)), lex); "sort_mapdata_mergedata_sort_slist" slist => sort(mapdata('none', $(mapdata_spec), mergedata(sort(base_list, int))), lex); "reverse_sort_slist" slist => reverse(sort(base_list, int)); "concat_sort_mapdata_mergedata_inline_json" string => concat(sort(mapdata('none', $(mapdata_spec), '[1,2,3]'), lex)); "concat_sort_mapdata_mergedata_slist" string => concat(sort(mapdata('none', $(mapdata_spec), mergedata(base_list)), lex)); "concat_sort_mapdata_mergedata_data" string => concat(sort(mapdata('none', $(mapdata_spec), mergedata(base_data)), lex)); "nth_sort_mapdata_mergedata_inline_json" string => nth(sort(mapdata('none', $(mapdata_spec), '[1,2,3]'), lex), 0); "nth_mapdata_mergedata_slist" string => nth(mapdata('none', $(mapdata_spec), mergedata(base_list)), 1); "nth_inline_json" string => nth('{ "x": "88888888" }', "x"); "nth_missing_inline_json" string => nth('{ "x": "88888888" }', "y"); "nth_data" string => nth(base_data, "x"); "nth_list" string => nth(base_list, 3); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/findfiles.cf0000644000000000000000000001045715010704253024653 0ustar00rootroot00000000000000####################################################### # # Test findfiles() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common findfiles { vars: # * in filenames not allowed on win windows:: "names" slist => { "a", "bc", "d/e/f", "g/h/i/j", "klm/nop/qrs" }; !windows:: "names" slist => { "a", "bc", "d/e/f", "g/h/i/j", "klm/nop/qrs", "tu/*" }; } ####################################################### bundle agent init { files: "$(G.testdir)/$(findfiles.names)" create => "true"; reports: DEBUG:: "Created $(G.testdir)/$(findfiles.names)"; } ####################################################### bundle agent test { vars: "patterns[a]" string => "$(G.testdir)/?"; "patterns[b]" string => "$(G.testdir)/*"; "patterns[c]" string => "$(G.testdir)/?/*"; "patterns[d]" string => "$(G.testdir)/[ab]*"; "patterns[e]" string => "$(G.testdir)/nosuch/*"; "patterns[relative_path_1]" string => "./*"; "patterns[relative_path_2]" string => "**"; "patterns[relative_path_3]" string => "../**"; !windows:: # First of all '*' is an illegal filename on Windows. Also you cannot # escape wildcards with backslash when it is a file separator. "patterns[f]" string => "$(G.testdir)/tu/\\*"; any:: "patterns[g]" string => "$(G.testdir)/*/**"; "patterns[h]" string => "$(G.testdir)/**/j"; "pnames" slist => getindices("patterns"); "found[$(pnames)]" slist => findfiles("$(patterns[$(pnames)])"); "found_string[$(pnames)]" string => join(",", "found[$(pnames)]"); reports: DEBUG:: "findfiles pattern $(pnames) '$(patterns[$(pnames)])' => '$(found_string[$(pnames)])'"; } ####################################################### bundle agent check { vars: !windows:: "expected[a]" string => "$(G.testdir)/a,$(G.testdir)/d,$(G.testdir)/g"; "expected[b]" string => "$(G.testdir)/a,$(G.testdir)/bc,$(G.testdir)/d,$(G.testdir)/g,$(G.testdir)/klm,$(G.testdir)/tu"; "expected[c]" string => "$(G.testdir)/d/e,$(G.testdir)/g/h"; "expected[d]" string => "$(G.testdir)/a,$(G.testdir)/bc"; "expected[e]" string => ""; "expected[f]" string => "$(G.testdir)/tu/*"; "expected[g]" string => "$(G.testdir)/a,$(G.testdir)/bc,$(G.testdir)/d,$(G.testdir)/g,$(G.testdir)/klm,$(G.testdir)/tu,$(G.testdir)/d/e,$(G.testdir)/g/h,$(G.testdir)/klm/nop,$(G.testdir)/tu/*,$(G.testdir)/d/e/f,$(G.testdir)/g/h/i,$(G.testdir)/klm/nop/qrs,$(G.testdir)/g/h/i/j"; "expected[h]" string => "$(G.testdir)/g/h/i/j"; windows:: "expected[a]" string => "$(G.testdir)\\a,$(G.testdir)\\d,$(G.testdir)\\g"; "expected[b]" string => "$(G.testdir)\\a,$(G.testdir)\\bc,$(G.testdir)\\d,$(G.testdir)\\g,$(G.testdir)\\klm"; "expected[c]" string => "$(G.testdir)\\d\\e,$(G.testdir)\\g\\h"; "expected[d]" string => "$(G.testdir)\\a,$(G.testdir)\\bc"; "expected[e]" string => ""; "expected[g]" string => "$(G.testdir)\\a,$(G.testdir)\\bc,$(G.testdir)\\d,$(G.testdir)\\g,$(G.testdir)\\klm,$(G.testdir)\\d\\e,$(G.testdir)\\g\\h,$(G.testdir)\\klm\\nop,$(G.testdir)\\d\\e\\f,$(G.testdir)\\g\\h\\i,$(G.testdir)\\klm\\nop\\qrs,$(G.testdir)\\g\\h\\i\\j"; "expected[h]" string => "$(G.testdir)\\g\\h\\i\\j"; any:: # relative paths are skipped, thus return empty list "expected[relative_path_1]" string => ""; "expected[relative_path_2]" string => ""; "expected[relative_path_3]" string => ""; "expects" slist => getindices("expected"); "fstring" slist => getindices("test.found_string"); "joint_condition" string => join(".", "expects"); classes: "$(expects)" expression => strcmp("$(test.found_string[$(expects)])", "$(expected[$(expects)])"); "ok" expression => "$(joint_condition)"; reports: DEBUG:: "pattern $(expects) matches as expected: '$(expected[$(expects)])'" if => "$(expects)"; "pattern $(expects) does NOT match expected: '$(test.found_string[$(expects)])' != '$(expected[$(expects)])'" if => "!$(expects)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readfile_absent_does_not_error_in_pre_eval.cf.sub0000644000000000000000000000065015010704253034170 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functionsbody common control { bundlesequence =>{ main }; } ########################################################### bundle agent pre_evaluated { vars: "none" string => readfile("/tmp/supercalifragilisticexpialidocious", 33); } bundle agent main { meta: "description" string => "Test that readfile() does not throw an error during pre-eval if the file does not exist."; reports: "Hello World!"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/storejson_edge_case.cf.expected.json0000644000000000000000000001032515010704253031457 0ustar00rootroot00000000000000{ "data": "{\n \"A very long text\": \"Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else.\"\n}" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/basename_2.cf0000644000000000000000000000504015010704253024674 0ustar00rootroot00000000000000####################################################### # # Test basename() with suffix removal # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: # The tests starting with template will be tested with both types of # directory separators on Windows. "template_input[root]" string => "/"; "template_suffix[root]" string => ""; "template_expected[root]" string => "/"; "template_input[simple]" string => "/foo/bar.c"; "template_suffix[simple]" string => ".c"; "template_expected[simple]" string => "bar"; "template_input[rel_suffif]" string => "foo.xyz"; "template_suffix[rel_suffif]" string => ".xyz"; "template_expected[rel_suffif]" string => "foo"; "template_input[no_matching_suffix]" string => "/foo/bar"; "template_suffix[no_matching_suffix]" string => "baz"; "template_expected[no_matching_suffix]" string => "bar"; "template_input[same_suffix]" string => "foo"; "template_suffix[same_suffix]" string => "foo"; "template_expected[same_suffix]" string => "foo"; "template_input[sub_same_suffix]" string => "foo/bar"; "template_suffix[sub_same_suffix]" string => "bar"; "template_expected[sub_same_suffix]" string => "bar"; "template_keys" slist => getindices("template_input"); any:: "input[native_$(template_keys)]" string => "$(template_input[$(template_keys)])"; "expected[native_$(template_keys)]" string => "$(template_expected[$(template_keys)])"; "suffix[native_$(template_keys)]" string => "$(template_suffix[$(template_keys)])"; "keys" slist => getindices("input"); "actual[$(keys)]" string => basename("$(input[$(keys)])", "$(suffix[$suffix])"); } ####################################################### bundle agent check { vars: "keys" slist => { @(test.keys) }; classes: "failed_cmp_$(keys)" not => strcmp(basename("$(test.input[$(keys)])", "$(test.suffix[$(keys)])"), "$(test.expected[$(keys)])"); "ok" not => classmatch("failed_cmp_.*"); reports: DEBUG:: "'basename($(test.input[$(keys)]), $(test.suffix[$(keys)]))' = '$(test.actual[$(keys)])' != '$(test.expected[$(keys)])'" if => "failed_cmp_$(keys)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_real_comments_noemptyfields2.cf0000644000000000000000000000510115010704253037043 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test parsestringarray(), add some weird indices, real comments, no empty fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","^#.*",":+",10,14); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "bad" or => { isvariable("test.ary[he][1]"), isvariable("test.ary[blank][0]"), }; "ok" and => { "!bad", strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[he][0])", "he"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "saw 'bad'-class things"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[he][0] = 'he', saw '$(test.ary[he][0])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/014.cf0000644000000000000000000000277015010704253023213 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\.",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/071.cf0000644000000000000000000000317115010704253023212 0ustar00rootroot00000000000000####################################################### # # Test filesize(), simple # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "known_val" int => filesize("$(G.testfile)"); "known_zero" int => filesize("$(G.etc_null)"); "unknown" int => filesize("/There/Is/nosuch/Name/as-this"); } ####################################################### bundle agent check { vars: windows:: "testfilesize" int => "30"; !windows:: "testfilesize" int => "27"; classes: "var" expression => isvariable("test.unknown"); "ok" and => { "!var", strcmp("$(test.known_val)", "$(testfilesize)"), strcmp("$(test.known_zero)", "0"), }; reports: DEBUG:: "expected filesize($(G.testfile)) to be XXX, saw $(test.known_val)"; "expected filesize($(G.etc_null)) to be 0, saw $(test.known_zero)"; "expected filesize('UnknownFile') to be undefined, saw $(test.unknown)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_returns_slist_for_array_scalar.cf0000644000000000000000000000277115010704253033300 0ustar00rootroot00000000000000####################################################### # # Test getvalues() returns an slist when used against # an array that has a scalar. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data[foo]" string => "bar"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "!any", meta => { "redmine7116" }; vars: "values_data" slist => getvalues("init.data"); } ####################################################### bundle agent check { vars: "expected_elements" slist => { "bar" }; "diff1" slist => difference( "test.values_data", expected_elements ); "diff2" slist => difference( expected_elements, "test.values_data"); "len_diff1" int => length(diff1); "len_diff2" int => length(diff2); classes: "ok" expression => strcmp( $(len_diff1), $(len_diff2) ); reports: DEBUG:: "DEBUG: data value: '$(test.values_data)'"; "DEBUG: expected value: '$(expected_elements)'"; "DEBUG: found '$(diff1)' in test.values_data, but not in expected_elements"; "DEBUG: found '$(diff2)' in expected_elements, but not in test.values_data"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/068.cf0000644000000000000000000000276415010704253023227 0ustar00rootroot00000000000000####################################################### # # Test getusers() arg0 and arg1 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: # All users except root, bin, and daemon "users" slist => getusers("root,bin,daemon","0,1,2"); files: "$(G.testfile)" delete => init_delete; reports: cfengine_3:: "$(users)" report_to_file => "$(G.testfile)"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: # Try to delete the lines that shouldn't be there anyway "$(G.testfile)" edit_line => test_delete, classes => full_set; } bundle edit_line test_delete { delete_lines: "root"; "daemon"; "bin"; } body classes full_set { promise_kept => { "pass" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { classes: "ok" expression => "pass&!fail"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/421.cf0000644000000000000000000000502415010704253023210 0ustar00rootroot00000000000000####################################################### # # Test parsestringarray(), introduce a singleton with no other fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 singleton 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[singleton][0])", "singleton"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[singleton][1]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[singleton][0] = 'singleton', saw '$(test.ary[singleton][0])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getindices.cf.expected.json0000644000000000000000000000106015010704253027564 0ustar00rootroot00000000000000{ "c_keys": [ "s", "f", "k" ], "c_keys_f": [ "f1" ], "c_keys_s": [ "s1" ], "fields": [ "fullname", "dirs", "name" ], "inline_fields": [ "foo", "bar" ], "inline_function": [ "a", "c" ], "inline_numfields": [ "0", "1", "2", "3" ], "user[dirs]": [ "/home/zamboni", "/tmp/zamboni", "/export/home/zamboni" ], "user[fullname][first]": "Diego", "user[fullname][last]": "Zamboni", "user[name]": "zamboni", "userfields": [ "first", "last" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/packagesmatching.cf0000644000000000000000000000715215010704253026177 0ustar00rootroot00000000000000####################################################### # # Test packagesmatching() and that the env prefix is stripped # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { packages: "cfe-no-such-package" package_policy => "add", package_method => mock1; "cfe-no-such-package" package_policy => "add", package_method => mock2; # the parsing of env X="y z" fails # "cfe-no-such-package" # package_policy => "add", # package_method => mock3; "cfe-no-such-package" package_policy => "add", package_method => mock4; } body package_method mock1 { package_changes => "individual"; package_list_command => "$(G.printf) 'bfoobar-1-besm6'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-([\S]+)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock2 { package_changes => "individual"; package_list_command => "/usr/bin/env $(G.printf) 'bfoobar-1-besm6'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-([\S]+)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock3 { package_changes => "individual"; package_list_command => '/usr/bin/env X="y z" $(G.printf) "bfoobar-1-besm6"'; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-([\S]+)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } body package_method mock4 { package_changes => "individual"; package_list_command => "/usr/bin/env X=Y $(G.printf) 'bfoobar-1-besm6'"; package_list_name_regex => "^([^-]+)"; package_list_version_regex => "^[^-]+-([^-]+)"; package_list_arch_regex => "^[^-]+-[^-]+-([\S]+)"; package_installed_regex => ".*"; package_add_command => "$(G.false)"; package_update_command => "$(G.false)"; package_delete_command => "$(G.false)"; package_verify_command => "$(G.false)"; } ####################################################### bundle agent test { meta: "test_suppress_fail" string => "windows", meta => { "redmine4741", "ENT-10422" }; vars: "all_packages" data => packagesmatching(".*", ".*", ".*", ".*"); "all_string" string => format("packages = %S", all_packages); } ####################################################### bundle agent check { vars: "e" string => '{"arch":"besm6","method":"printf","name":"bfoobar","version":"1"}'; methods: "" usebundle => dcs_check_strcmp($(test.all_string), 'packages = [$(e)]', $(this.promise_filename), "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readfile.cf0000644000000000000000000000362615010704253024463 0ustar00rootroot00000000000000# test readfile() body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "sizes" ilist => { "0", "1", "4094", "4095", "4096", "4097", "99999999" }; "read_$(sizes)" string => readfile("$(this.promise_filename).txt", $(sizes)); "length_$(sizes)" int => string_length("$(read_$(sizes))"); "read_no_size" string => readfile("$(this.promise_filename).txt"); "length_no_size" int => string_length("$(read_no_size)"); } bundle agent check { vars: "sizes" ilist => { @(test.sizes) }; "expected[0]" int => "10240"; "expected[1]" int => "1"; "expected[4094]" int => "4094"; "expected[4095]" int => "4095"; "expected[4096]" int => "4096"; "expected[4097]" int => "4097"; "expected[99999999]" int => "10240"; "expected_no_size" int => "10240"; classes: "ok_$(sizes)" expression => strcmp("$(test.length_$(sizes))", "$(expected[$(sizes)])"); "ok_no_size" expression => strcmp("$(test.length_no_size)", "$(expected_no_size)"); "ok" and => { "ok_0", "ok_1", "ok_4094", "ok_4095", "ok_4096", "ok_4097", "ok_99999999", "ok_no_size", }; reports: DEBUG:: "Got expected size for read of $(sizes): $(test.length_$(sizes))" if => "ok_$(sizes)"; "Did NOT get expected size for read of $(sizes): $(test.length_$(sizes)) != expected $(expected[$(sizes)])" if => "!ok_$(sizes)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/ifelse_isvariable.cf0000644000000000000000000000216215010704253026352 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "passwd_file" string => "/tmp/custom_passwd"; } bundle agent test { meta: "description" string => "Test that ifelse can use the result of isvariable as a class identifer"; vars: # Since init.passwd_file is defined, I expect the value to be # the value of init.passwd_file "use_passwd_file" string => ifelse( isvariable("init.passwd_file"), $(init.passwd_file), "/etc/passwd"); # Since init.shadow_file is not defined, I expect that the value # will be "/etc/shadow" "use_shadow_file" string => ifelse( isvariable("init.shadow_file"), $(init.shadow_file), "/etc/shadow"); } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/or.cf0000644000000000000000000001715315010704253023330 0ustar00rootroot00000000000000###################################################### # # Test that or() behaves as expected # ##################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3470" } string => "Test that or() behaves as expected"; vars: "f" # false string => "(cfengine.(!cfengine))"; "T" # true, uppercase to be more different visually string => "(cfengine|(!cfengine))"; "f_name" string => "f"; "T_name" string => "T"; "f_name_name" string => "f_name"; "T_name_name" string => "T_name"; "many_true" slist => { "any", "$(T)", concat(not(or("$(f)"))), "(any.cfengine)", concat(not(or())), concat(not(or(or()))), }; "many_false" slist => { "(!any)", "$(f)", concat(or(not("$(T)"))), "(any.!cfengine)", concat(not("any")), concat(or()), }; "many_both" slist => { @(many_true), @(many_false) }; classes: # All elements should be true, fail if one is false: "ok" scope => "namespace", and => { # Sanity check: "any", "cfengine", # or() with 0 arguments should default to false: not(or()), # or() with 1 static string: or("any"), or("cfengine"), or("!(!cfengine)"), # or() with 1 string with variable expansion(s): or("$(T)"), or("!$(f)"), or("$(T).any"), or("$(T).!(!any)"), or("any.$(T)"), or("!(!any).$(T)"), or("any|$(f)"), or("!(!any)|$(f)"), or("$(T)|$(f)"), or("$(f)|$(T)"), # or() with slist: # Careful, if there are expressions in list (using | operator) # they should be parenthesized for this to work: or(join(".", many_true)), or(join("|", many_true)), or(join("|", many_both)), or(not(join(".", many_false))), or(not(join("|", many_false))), or(not(join(".", many_both))), # or() with 1 function call as argument: or(or("any")), or(or("cfengine")), or(not("!cfengine")), or(not(not("cfengine"))), or(not("$(f)")), or(not(not("$(T)"))), or(strcmp("cfengine", "cfengine")), or(strcmp("any", not("$(f)"))), # or() with 2 arguments: or("any", "cfengine"), or("any", "!any"), or("!any", "any"), or("!(!any)", "!(!cfengine)"), or("$(T)", "$(T)"), or("$(T)", "$(f)"), or("$(T)", "!$(f)"), or("$(T)", not("$(f)")), or(not("$(f)"), not("$(f)")), # or() with 3+ arguments (strings): or("any", "any", "any"), or("any", "any", "any", "any"), or("any", "any", "any", "any", "any"), or("any", "any", "any", "any", "any", "any"), or("any", "any", "any", "any", "any", "!any"), or("any", "any", "any", "any", "!any", "!any"), or("any", "any", "any", "!any", "!any", "!any"), or("any", "any", "!any", "!any", "!any", "!any"), or("any", "!any", "!any", "!any", "!any", "!any"), or("!any", "!any", "!any", "!any", "!any", "any"), or("!any", "!any", "!any", "!any", "any", "any"), or("!any", "!any", "!any", "any", "any", "any"), or("!any", "!any", "any", "any", "any", "any"), or("!any", "any", "any", "any", "any", "any"), or("$(T)", "$(T)", "$(T)"), or("$(T)", "$(T)", "$(T)", "$(T)"), or("$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), or("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), or("$(T)", "$(T)", "$(T)", "$(T)", "$(T)", "$(f)"), or("$(T)", "$(T)", "$(T)", "$(T)", "$(f)", "$(f)"), or("$(T)", "$(T)", "$(T)", "$(f)", "$(f)", "$(f)"), or("$(T)", "$(T)", "$(f)", "$(f)", "$(f)", "$(f)"), or("$(T)", "$(f)", "$(f)", "$(f)", "$(f)", "$(f)"), or("$(f)", "$(f)", "$(f)", "$(f)", "$(f)", "$(T)"), or("$(f)", "$(f)", "$(f)", "$(f)", "$(T)", "$(T)"), or("$(f)", "$(f)", "$(f)", "$(T)", "$(T)", "$(T)"), or("$(f)", "$(f)", "$(T)", "$(T)", "$(T)", "$(T)"), or("$(f)", "$(T)", "$(T)", "$(T)", "$(T)", "$(T)"), # or() with 3+ function calls: or(not("any"), not("any"), not("!any")), or(not("any"), not("any"), not("any"), not("!any")), or(not("any"), not("any"), not("any"), not("any"), not("!any")), or(not("any"), not("any"), not("any"), not("any"), not("any"), not("!any")), or(not("$(T)"), not("$(T)"), not("$(f)")), or(not("$(T)"), not("$(T)"), not("$(T)"), not("$(f)")), or(not("$(T)"), not("$(T)"), not("$(T)"), not("$(T)"), not("$(f)")), or(not("$(T)"), not("$(T)"), not("$(T)"), not("$(T)"), not("$(T)"), not("$(f)")), # or() with deep nesting: not(or(or())), not(or(or(or()))), not(or(or(or(or())))), not(or(or(or(or(or()))))), not(or(or(or(or(or(or())))))), or(or(or(or(or(or("any")))))), or(or(or(or(or(or("any", "cfengine")))))), # Double expansion: or("$($(T_name))"), or("$($(f_name))", "$($(T_name))"), or("$($(f_name))", "$($(f_name))", "$($(T_name))"), or("!$($(T_name))", "!$($(f_name))"), or("!$($(T_name))", "!$($(T_name))", "!$($(f_name))"), or(not("$($(T_name))"), not("$($(f_name))")), # Triple expansion: or("$($($(T_name_name)))"), or("$($($(f_name_name)))", "$($($(T_name_name)))"), or("$($($(f_name_name)))", "$($($(f_name_name)))", "$($($(T_name_name)))"), or("!$($(T_name_name))", "!$($(f_name_name))"), or("!$($(T_name_name))", "!$($(T_name_name))", "!$($(f_name_name))"), or(not("$($(T_name_name))"), not("$($(f_name_name))")), # or() should always return any or !any, # this is important for backwards compatibility: strcmp(or("any"), "any"), strcmp(or("!any"), "!any"), strcmp(or("!cfengine"), "!any"), strcmp(or("!(cfengine|!cfengine)"), "!any"), strcmp(or("$(T)"), "any"), strcmp(or("$(f)"), "!any"), strcmp(or("$(T)", "$(T)"), "any"), strcmp(or("$(T)", "$(f)"), "any"), strcmp(or("$(f)", "$(T)"), "any"), strcmp(or("$(f)", "$(f)"), "!any"), }; # Cases where or() should return false (fail if one is true): "fail_false" or => { or("$(f)"), or("$(f)", "$(f)"), or("$(f)", "$(f)", "$(f)"), or("$(f)", "$(f)", "$(f)", "$(f)"), or("$(f)", "$(f)", "$(f)", "$(f)", "$(f)"), or("$(f)", "$(f)", "$(f)", "$(f)", "$(f)", "$(f)"), or("$(f)", "$(f)", "$(f)", "$(f)", "$(f)", "$(f)", "$(f)"), or("$(f)", "$(f)", "$(f)", "$(f)", "$(f)", "$(f)", "$(f)", "$(f)"), }; # Should be skipped because of unresolved variable: "fail_unresolved" and => { "any", or("$(unresolved_var)"), }; # Check that it's really skipped because of unresolved, # and not that it accidentally becomes false: "fail_not_of_unresolved" and => { "any", or(not("$(unresolved_var)")), }; "fail" scope => "namespace", expression => "fail_false|fail_unresolved|fail_not_of_unresolved"; } ####################################################### bundle agent check { reports: ok.(!fail):: "$(this.promise_filename) Pass"; (!ok)|fail:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/int.cf0000644000000000000000000000343515010704253023500 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { vars: "expect" data => '{ "pos_int": { "in": "12", "out": "12" }, "pos_int_k": { "in": "21k", "out": "21000" }, "neg_int": { "in": "-34", "out": "-34" }, "neg_int_k": { "in": "-42k", "out": "-42000" }, "pos_real": { "in": "56.789", "out": "56" }, "pos_real_k": { "in": "65.987k", "out": "65987" }, "neg_real": { "in": "-78.789", "out": "-78" }, "neg_real_k": { "in": "-87.987k", "out": "-87987" }, }'; "cases" slist => getindices( @{expect} ); "all_ok_classes" slist => maplist( "ok_${this}", @{cases} ); } bundle common test { meta: "description" -> { "CFE-3616" } string => "Test whether the int() policy function properly returns integer from string"; classes: "ok_${init.cases}" expression => strcmp( int( "${init.expect[${init.cases}][in]}" ), "${init.expect[${init.cases}][out]}" ); } bundle agent check { vars: "difference" slist => difference( @{init.all_ok_classes}, classesmatching( "ok_.*" ) ); classes: "ok" expression => strcmp( "0", length( @{difference} ) ); methods: "Pass/FAIL" usebundle => dcs_passif( "ok", ${this.promise_filename} ), inherit => "true"; reports: !ok.DEBUG:: "Ok classes not matching: ${with}" with => join(", ", @{difference}); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.lowercase.txt0000644000000000000000000002400115010704253027676 0ustar00rootroot00000000000000abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789abcdefghij cfengine-3.24.2/tests/acceptance/01_vars/02_functions/032.cf0000644000000000000000000000245615010704253023214 0ustar00rootroot00000000000000####################################################### # # Test readintlist() with reals # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","X",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok1" not => strcmp("123.456", "$(nums)"); "ok2" not => strcmp("123", "$(nums)"); "ok" and => { "ok_list", "ok1", "ok2" }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getvalues_returns_all_values_for_given_array_index_merging_strings.cf0000644000000000000000000000306215010704253040517 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test getvalues() returns all values for a given array # merging strings # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data[foo]" slist => { "alpha", "bravo" }; "data[bar]" string => "zulu"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "!any", meta => { "redmine7116" }; vars: "values_data" slist => getvalues("init.data"); } ####################################################### bundle agent check { vars: "expected_elements" slist => { "alpha", "bravo", "zulu" }; "diff1" slist => difference( "test.values_data", expected_elements ); "diff2" slist => difference( expected_elements, "test.values_data"); "len_diff1" int => length(diff1); "len_diff2" int => length(diff2); classes: "ok" expression => strcmp( $(len_diff1), $(len_diff2) ); reports: DEBUG:: "DEBUG: data value: '$(test.values_data)'"; "DEBUG: expected value: '$(expected_elements)'"; "DEBUG: found '$(diff1)' in test.values_data, but not in expected_elements"; "DEBUG: found '$(diff2)' in expected_elements, but not in test.values_data"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string.cf0000644000000000000000000000505015010704253024207 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default( "$(this.promise_filename)" ) }; } bundle agent init { classes: "ExistingClass"; vars: "a_int" int => "1k"; "a_real" real => "6.066"; "a_string" string => "Really interesting string"; "a_data_container_1" data => '{"foo": "bar"}'; "a_data_container_2" data => '[1, 2, 3]'; "a_data_container_3" data => '{"list": [1, 2, 3, 4], "obj": {"key": ["b", "a", "r"]}}'; "string_of_int" string => string("$(a_int)"); "string_of_real" string => string("$(a_real)"); "string_of_string" string => string("$(a_string)"); "string_of_bool_true" string => string(and("ExistingClass")); "string_of_bool_false" string => string(and("NonExistingClass")); "string_of_data_container_1" string => string(a_data_container_1); # Strings not interpretted as references "string_of_data_container_2" string => string("a_data_container_2"); # Strings not interpretted as references "string_of_data_container_3" string => string(@(a_data_container_3)); # "test_args" string => string(); # This is caught by the parser } bundle agent check { meta: "description" -> { "CFE-3476" } string => "Test whether string() properly converts argument to string or string-serialises JSON *only* when explicitely passed as a '@()' reference"; classes: "ok_int" expression => strcmp("1000", "$(init.string_of_int)"); "ok_real" expression => strcmp("6.066000", "$(init.string_of_real)"); "ok_string" expression => strcmp("Really interesting string", "$(init.string_of_string)"); "ok_bool_true" expression => strcmp("any", "$(init.string_of_bool_true)"); "ok_bool_false" expression => strcmp("!any", "$(init.string_of_bool_false)"); "ok_data_container_1" expression => strcmp("a_data_container_1", "$(init.string_of_data_container_1)"); "ok_data_container_2" expression => strcmp("a_data_container_2", "$(init.string_of_data_container_2)"); "ok_data_container_3" expression => strcmp('{"list":[1,2,3,4],"obj":{"key":["b","a","r"]}}', "$(init.string_of_data_container_3)"); "ok" expression => and("ok_int", "ok_real", "ok_string", "ok_bool_true", "ok_bool_false", "ok_data_container_1", "ok_data_container_2", "ok_data_container_3"); methods: "Pass/Fail" usebundle => dcs_passif( "ok", "$(this.promise_filename)" ), inherit => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/nth_datacontainer.cf.json0000644000000000000000000000052015010704253027333 0ustar00rootroot00000000000000{ "boolean": true, "string": "Figaro. Figaro. Figaro, Figaro, Figaro... Figaro!", "integer": 20130111, "list": [ "chris", "dituri", "was", "here" ], "object": { "a": true, "b": [ 1, 2, 3 ], "c": "cat", "d": 108 }, "integer_2": 987654321, "string_2": "Othello? Where art thou now?", "boolean_2": false, "null": null, } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/variablesmatching.cf0000644000000000000000000000374415010704253026374 0ustar00rootroot00000000000000# Test that variablesmatching works correctly body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { vars: "test_fbeae67f3e347b5e0032302200141131" string => "abc", meta => { "x" }; "test_fbeae67f3e347b5e0032302200141131_1" string => "def", meta => { "x" }; "test_fbeae67f3e347b5e0032302200141131_2" string => "ghi", meta => { "y" }; "test_b37ce1b03955522848f0a82d0b2b2e21_1" slist => { "a", "b" }, meta => { "x" }; "test_b37ce1b03955522848f0a82d0b2b2e21_2" data => '{ "a": "b" }', meta => { "x" }; "test_b37ce1b03955522848f0a82d0b2b2e21_3" string => 'mydata', meta => { "y" }; "test_variable_with_weird_tag" string => 'some_data', meta => { "weird[tag]" }; } bundle agent test { vars: "vars" slist => variablesmatching("default:init.test_fbeae67f3e347b5e0032302200141131.*"); "x_vars" slist => variablesmatching("default:init.test_fbeae67f3e347b5e0032302200141131.*", "x"); "z_vars" slist => variablesmatching("default:init.test_fbeae67f3e347b5e0032302200141131.*", "z"); "fullvars" data => variablesmatching_as_data("default:init.test_b37ce1b03955522848f0a82d0b2b2e21.*"); "x_fullvars" data => variablesmatching_as_data("default:init.test_b37ce1b03955522848f0a82d0b2b2e21.*", "x"); "z_fullvars" data => variablesmatching_as_data("default:init.test_b37ce1b03955522848f0a82d0b2b2e21.*", "z"); "tag_match" slist => variablesmatching(".*", "weird\[tag\]"); "tag_no_match" slist => variablesmatching(".*", "weird[tag]"); "tag_match_data" data => variablesmatching_as_data(".*", "weird\[tag\]"); "tag_no_match_data" data => variablesmatching_as_data(".*", "weird[tag]"); } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } getindices_returns_expected_list_from_array.cf.expected.json0000644000000000000000000000022115010704253036422 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions{ "values_data_1": [ "two", "one" ], "values_data_2": [ "first", "second" ], "values_data_3": [ "a", "b" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_readstringarrayidx.cf.txt0000644000000000000000000004233715010704253030427 0ustar00rootroot00000000000000# app_name;instance;mmax;mmin;mperm;zone;tomcat_version;env;setenv;app_properties;newrelic;newrelic_name;newrelic_version;context_static;checks;action;context some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server NEXT-TO-LAST;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server LAST;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server cfengine-3.24.2/tests/acceptance/01_vars/02_functions/CFE-2704-1.cf0000644000000000000000000000101215010704253024020 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" -> { "CFE-2704" } string => "Test that attempting to merge incompatible data does not segfault. Variant 1."; vars: "data" data => '{"env":"test"}'; "node" data => mergedata("[]", "data[env]"); } bundle agent check { methods: "Pass if we made it this far" usebundle => dcs_pass( $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/227.cf0000644000000000000000000000246315010704253023220 0ustar00rootroot00000000000000####################################################### # # Test grep(), size 0, empty pattern should match nothing # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "zero" string => "zero"; "one" string => "one"; files: "$(G.testfile).expected" create => "true"; } ####################################################### bundle agent test { vars: "array" slist => { "One", "Two", "Three", "Four", "Five" }; "vals" slist => grep("", "array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_5.cf.csv0000644000000000000000000000023215010704253026743 0ustar00rootroot00000000000000ClassExpr,Token,Value any,net.ipv4.ip_forward,ANYVALUE supercalifragilisticexpialidociousNOTDEFINED,net.ipv4.ip_forward,SHOULD_BE_FILTERED_OUT cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/0000755000000000000000000000000015010704253023332 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/proc/0000755000000000000000000000000015010704253024275 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/proc/sys/0000755000000000000000000000000015010704253025113 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/proc/sys/net/0000755000000000000000000000000015010704253025701 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/proc/sys/net/unix/0000755000000000000000000000000015010704253026664 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/proc/sys/net/unix/max_dgram_qlen0000644000000000000000000000000415010704253031557 0ustar00rootroot00000000000000512 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/proc/sys/net/ipv4/0000755000000000000000000000000015010704253026563 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/proc/proc/sys/net/ipv4/tcp_mem0000644000000000000000000000002515010704253030127 0ustar00rootroot00000000000000383133 510845 766266 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_plain_string.cf0000644000000000000000000000177415010704253027462 0ustar00rootroot00000000000000####################################################### # # Test getvalues() # ####################################################### # If we run getvalues on a plan string, we should end up with a list of one # element being that string value. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "string" string => "scrumdiddlyumptious"; "values" slist => getvalues("string"); } ####################################################### bundle agent check { vars: "expected" slist => { "scrumdiddlyumptious" }; "diff" slist => difference( expected, "test.values" ); classes: "_pass" expression => strcmp( length( diff ), 0 ); methods: _pass:: "pass" usebundle => dcs_pass("$(this.promise_filename)"); !_pass:: "pass" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/bundlestate.cf.sub0000644000000000000000000000064015010704253026003 0ustar00rootroot00000000000000body file control { namespace => "external"; } bundle agent init { vars: "external_s" string => "External Hello!"; } bundle agent dump { vars: "external_holder" data => bundlestate("init"); "external_holder2" data => bundlestate("external:init"); "external_holder_s" string => format("%S", external_holder); "external_holder2_s" string => format("%S", external_holder2); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_3.cf0000644000000000000000000000337615010704253026163 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2768" } string => "Test that classfiltercsv() works: - column headings - simple filtering (no duplicates after filter) - sorting"; } bundle agent check { vars: "data_file" string => "$(this.promise_filename).csv"; "d" data => classfiltercsv( $(data_file), "true", # Data file contains column headings 0, # Column containing class expression to filter with 1); # Column to sort by (NOT IMPLEMENTED AT TIME OF TEST) classes: # Check if Token has the value we expect "Token_OK" expression => strcmp( "$(d[0][Token])", "net.ipv4.ip_forward" ); # Check if Value has the value we expect "Value_OK" expression => strcmp( "$(d[0][Value])", "ANYVALUE-sort0" ); # Check if the result contains the number of records we expect. "Length_OK" expression => isgreaterthan( length( d ), 0); methods: "Pass/FAIL" usebundle => dcs_passif_expected( 'Token_OK,Value_OK,Length_OK', '', $(this.promise_filename) ), inherit => "true"; reports: DEBUG|EXTRA:: "Function returned:$(with)" with => string_mustache( "{{%-top-}}", d ); "supercalifragilisticexpialidociousNOTDEFINED is actually defined." if => "supercalifragilisticexpialidociousNOTDEFINED"; "supercalifragilisticexpialidociousNOTDEFINED is not defined (as expected)" unless => "supercalifragilisticexpialidociousNOTDEFINED"; } getindices_returns_expected_list_from_datacontainer.cf0000644000000000000000000000202215010704253035351 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test that getindices() returns the expected list from # a data container # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data" data => parsejson('{ "foo": [ "alpha", "bravo" ], "bar": { "one": "1" "two": "2" } }'); } ####################################################### bundle agent test { vars: # expected: one, two "values_data" slist => getindices("init.data[bar]"); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sysctl.cf.sub0000644000000000000000000000203715010704253025014 0ustar00rootroot00000000000000# you can run this test directly with # CFENGINE_TEST_OVERRIDE_PROCDIR=`pwd`/01_vars/02_functions/proc ./testall 01_vars/02_functions/sysctl.cf.sub body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } bundle agent test { vars: "sysctl" data => data_sysctlvalues(); "tested" slist => { "net.ipv4.tcp_mem", "net.unix.max_dgram_qlen" }; "values[$(tested)]" string => sysctlvalue($(tested)); } bundle agent check { vars: "testname" string => regex_replace($(this.promise_filename), "\\.sub$", "", ""); methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(testname)); test_debug:: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/0000755000000000000000000000000015010704253024506 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/001.cf0000644000000000000000000000135215010704253025321 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 001: getindices() with parameter variable in its argument, from a non-default namespace to the default namespace body common control { inputs => { "../../../default.cf.sub", "001_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace("default:g.array", "b:variables.array2"); } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/203.cf0000644000000000000000000000140415010704253025323 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 003: getindices() with parameter variable argument, from non-default namespace to the same namespace, but with getindices() inside braces. body common control { inputs => { "../../../default.cf.sub", "203_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace("default:g.array", "b:variables.array2"); } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/001_namespaced_getindices.cf.sub0000644000000000000000000000063315010704253032470 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace(array_name, array_name2) { vars: "repo_ids1" slist => getindices("$(array_name)"); } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids1)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/101.cf0000644000000000000000000000136115010704253025322 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 101: getindices() with local variable in its argument, from a non-default namespace to the default namespace # same as 001.cf but without using a parameter body common control { inputs => { "../../../default.cf.sub", "101_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace; } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/003_namespaced_getindices.cf.sub0000644000000000000000000000063515010704253032474 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace(array_name, array_name2) { vars: "repo_ids3" slist => getindices("$(array_name2)"); } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids3)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/103.cf0000644000000000000000000000134515010704253025326 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 103: getindices() with local variable argument, from non-default namespace to the same namespace # same as 003.cf but without using a parameter body common control { inputs => { "../../../default.cf.sub", "103_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace; } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/003.cf0000644000000000000000000000133615010704253025325 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 003: getindices() with parameter variable argument, from non-default namespace to the same namespace body common control { inputs => { "../../../default.cf.sub", "003_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace("default:g.array", "b:variables.array2"); } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/004.cf0000644000000000000000000000132515010704253025324 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 004: getindices() with constant argument, from non-default namespace to the same namespace. body common control { inputs => { "../../../default.cf.sub", "004_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace("default:g.array", "b:variables.array2"); } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/005.cf0000644000000000000000000000143615010704253025330 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 004: getindices() with constant argument, from non-default namespace to the same namespace. body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "any" usebundle => test_default_namespace("g.array"); } bundle agent test_default_namespace(array_name) { vars: "repo_ids5" slist => getindices("$(array_name)"); } bundle agent check { methods: "check" usebundle => dcs_check_strcmp("$(test_default_namespace.repo_ids5)", "key", "$(this.promise_filename)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/201.cf0000644000000000000000000000142015010704253025317 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 201: getindices() with parameter variable in its argument, from a non-default namespace to the default namespace, but with getindices() inside braces. body common control { inputs => { "../../../default.cf.sub", "201_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace("default:g.array", "b:variables.array2"); } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/201_namespaced_getindices.cf.sub0000644000000000000000000000063715010704253032476 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace(array_name, array_name2) { vars: "repo_ids1" slist => { getindices("$(array_name)") }; } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids1)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/006.cf0000644000000000000000000000140115010704253025321 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 004: getindices() with constant argument, from non-default namespace to the same namespace. body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "any" usebundle => test_default_namespace; } bundle agent test_default_namespace { vars: "repo_ids6" slist => getindices("g.array"); } bundle agent check { methods: "check" usebundle => dcs_check_strcmp("$(test_default_namespace.repo_ids6)", "key", "$(this.promise_filename)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/101_namespaced_getindices.cf.sub0000644000000000000000000000066215010704253032473 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace { vars: "array_name" string => "default:g.array"; "repo_ids1" slist => getindices("$(array_name)"); } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids1)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/004_namespaced_getindices.cf.sub0000644000000000000000000000064115010704253032472 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace(array_name, array_name2) { vars: "repo_ids4" slist => getindices("b:variables.array2"); } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids4)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/103_namespaced_getindices.cf.sub0000644000000000000000000000067015010704253032474 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace { vars: "array_name2" string => "b:variables.array2"; "repo_ids3" slist => getindices("$(array_name2)"); } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids3)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/002_namespaced_getindices.cf.sub0000644000000000000000000000063615010704253032474 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace(array_name, array_name2) { vars: "repo_ids2" slist => getindices("default:g.array"); } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids2)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/002.cf0000644000000000000000000000132515010704253025322 0ustar00rootroot00000000000000# Check that getindices() works correctly within and across namespaces # 002: getindices() with constant argument, from a non-default namespace to default namespace body common control { inputs => { "../../../default.cf.sub", "002_namespaced_getindices.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "array[key]" string => "string"; } bundle agent init { vars: } bundle agent test { methods: "test_in_namespace" usebundle => b:test_in_namespace("default:g.array", "b:variables.array2"); } bundle agent check { methods: "check_in_namespace" usebundle => b:check_in_namespace("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/namespaces/203_namespaced_getindices.cf.sub0000644000000000000000000000064115010704253032473 0ustar00rootroot00000000000000body file control { namespace => "b"; } bundle common variables { vars: "array2[key]" string => "string2"; } bundle agent test_in_namespace(array_name, array_name2) { vars: "repo_ids3" slist => { getindices("$(array_name2)") }; } bundle agent check_in_namespace(test) { methods: "any" usebundle => default:dcs_check_strcmp("$(b:test_in_namespace.repo_ids3)", "key", "$(test)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/hash_to_int.cf0000644000000000000000000000365315010704253025207 0ustar00rootroot00000000000000####################################################### # # Test hash_to_int() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "a_9" int => hash_to_int(9,10,"string"); "b_9" int => hash_to_int(9,9,"doesn't"); "c_9" int => hash_to_int(10,9,"matter"); "empty_27" int => hash_to_int(0,100,""); "empty_5327" int => hash_to_int(100,10000,""); "empty_n2" int => hash_to_int("-2","-1",""); "short_9872" int => hash_to_int("-10000","10001","shortstring"); "long_n893" int => hash_to_int("-1000","1001", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\!\"#$%&/()=?.:,;-_"); } ####################################################### bundle agent check { classes: "ok_a" expression => strcmp("$(test.a_9)", "9"); "ok_b" expression => strcmp("$(test.b_9)", "9"); "ok_c" expression => strcmp("$(test.c_9)", "9"); "ok_d" expression => strcmp("$(test.empty_27)", "27"); "ok_e" expression => strcmp("$(test.empty_5327)", "5327"); "ok_f" expression => strcmp("$(test.empty_n2)", "-2"); "ok_g" expression => strcmp("$(test.long_n893)", "-893"); "ok_h" expression => strcmp("$(test.short_9872)", "9872"); "ok" and => {ok_a, ok_b, ok_c, ok_d, ok_e, ok_f, ok_g, ok_h}; reports: DEBUG:: "a_9: $(test.a_9)"; "b_9: $(test.b_9)"; "c_9: $(test.c_9)"; "empty_27: $(test.empty_27)"; "empty_5327: $(test.empty_5327)"; "empty_n2: $(test.empty_n2)"; "long_n893: $(test.long_n893)"; "short_9872: $(test.short_9872)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mapdata_json_pipe.cf.expected.json0000644000000000000000000000106115010704253031124 0ustar00rootroot00000000000000{ "items": { "titles": [ "JQ Primer", "More JQ" ], "user": "stedolan" }, "items_input": [ { "a": 100, "b": true }, { "a": 100, "b": true }, { "a": 100, "b": true }, { } ], "items_jqinput": [ { "title": "JQ Primer", "user": "stedolan" }, { "title": "More JQ", "user": "stedolan" } ], "items_passthrough": [ { "titles": [ "JQ Primer", "More JQ" ], "user": "stedolan" } ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/226.cf0000644000000000000000000000247215010704253023217 0ustar00rootroot00000000000000####################################################### # # Test grep(), size 0, ".*v" matches nothing (anchored regex) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "zero" string => "zero"; "one" string => "one"; files: "$(G.testfile).expected" create => "true"; } ####################################################### bundle agent test { vars: "array" slist => { "One", "Two", "Three", "Four", "Five" }; "vals" slist => grep(".*v", "array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_1.cf0000644000000000000000000000322515010704253026152 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { meta: "description" -> { "CFE-2768" } string => "Test that classfiltercsv() works: - column headings - simple filtering (no duplicates after filter) - no sorting"; } bundle agent check { vars: "data_file" string => "$(this.promise_filename).csv"; "d" data => classfiltercsv( $(data_file), "true", # Data file contains column headings 0); # Column containing class expression to filter with classes: # Check if Token has the value we expect "Token_OK" expression => strcmp( "$(d[0][Token])", "net.ipv4.ip_forward" ); # Check if Value has the value we expect "Value_OK" expression => strcmp( "$(d[0][Value])", "ANYVALUE" ); # Check if the result contains the number of records we expect. "Length_OK" expression => strcmp( length( d ), 1 ); methods: "Pass/FAIL" usebundle => dcs_passif_expected( 'Token_OK,Value_OK,Length_OK', '', $(this.promise_filename) ), inherit => "true"; reports: DEBUG|EXTRA:: "Function returned:$(with)" with => string_mustache( "{{%-top-}}", d ); "supercalifragilisticexpialidociousNOTDEFINED is actually defined." if => "supercalifragilisticexpialidociousNOTDEFINED"; "supercalifragilisticexpialidociousNOTDEFINED is not defined (as expected)" unless => "supercalifragilisticexpialidociousNOTDEFINED"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/execresult_multiples.cf0000644000000000000000000000217215010704253027164 0ustar00rootroot00000000000000############################################################################## # # Redmine #2981: execresult and returnszero should not be run so much # ############################################################################## body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kv -f $(this.promise_filename).sub | $(G.egrep) 'execresult|returnszero'", "useshell"); } bundle agent check { # If the output contains CLASSONCE or RETONCE more than once, we fail classes: "ok1" not => regcmp(".*ran.*CLASSONCE.*ran.*CLASSONCE.*", "$(test.subout)"); "ok2" not => regcmp(".*ran.*RETONCE.*ran.*RETONCE.*", "$(test.subout)"); "ok" and => { "ok1", "ok2" }; reports: DEBUG:: "agent output: $(test.subout)"; ok1.ok2:: "The duplicate output in cf-agent didn't happen"; !(ok1.ok2):: "The duplicate output in cf-agent happened"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/056.x.cf0000644000000000000000000000166515010704253023471 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated("-1",0,0,0,0,100); } ####################################################### bundle agent check { vars: "time" int => "31536100"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "nums: $(time)"; "sum: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string_mustache.cf.expected.json0000644000000000000000000000017015010704253030646 0ustar00rootroot00000000000000{ "inline": "2 3 4 ", "out11": "desert = Sahara", "out21": "desert = ", "out22": "x = 1", "out23": "2 3 4 " } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/url_get_local.cf0000644000000000000000000000271715010704253025523 0ustar00rootroot00000000000000########################################################### # # Test url_get() locally # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent init { vars: "options_limit" data => ' { "url.max_content": 200, "nosuchoption": 100, "url.verbose": 0, "url.headers": [ "Foo: bar" ] }'; "options_clean" data => '{}'; # local file: does it work on Windows? "res4" data => url_get("file://$(this.promise_filename)", options_limit); } bundle agent test { meta: "test_skip_unsupported" string => "!feature_curl"; "test_soft_fail" string => "windows", meta => { "ENT-10254" }; vars: "kept" data => mergedata( '{ "res4": init.res4[content] }', '{ "res4/returncode": init.res4[returncode] }', '{ "res4/rc": init.res4[rc] }', '{ "res4/success": init.res4[success] }' ); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/filestat.cf0000644000000000000000000000571215010704253024521 0ustar00rootroot00000000000000####################################################### # # Test filestat() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" create => "true", perms => init_m(600), edit_defaults => init_empty, edit_line => init_fill_in; reports: DEBUG:: "Created $(G.testfile)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; edit_backup => "false"; } body perms init_m(mode) { mode => "$(mode)"; } bundle edit_line init_fill_in { insert_lines: "012345789"; "112345789"; "212345789"; "312345789"; "4"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "fields" slist => splitstring("size,gid,uid,ino,nlink,ctime,atime,mtime,mode,modeoct,permstr,permoct,type,devno,dev_minor,dev_major,basename,dirname,linktarget,linktarget_shallow", ",", 999); "stat[$(fields)]" string => filestat($(G.testfile), $(fields)); } ####################################################### bundle agent check { vars: "expected[type]" string => "regular file"; "expected[nlink]" string => "1"; "expected[dirname]" string => dirname($(G.testfile)); "expected[basename]" string => lastnode($(G.testfile), escape("$(const.dirsep)")); "expected[linktarget]" string => $(G.testfile); "expected[linktarget_shallow]" string => $(G.testfile); windows:: "expected[size]" string => "47"; "expected[mode]" string => "33206"; # 100666 "expected[permoct]" string => "666"; "expected[modeoct]" string => "100666"; "expected[permstr]" string => "-rw-rw-rw-"; !windows:: "expected[size]" string => "42"; "expected[mode]" string => "33152"; # 100600 "expected[permoct]" string => "600"; "expected[modeoct]" string => "100600"; "expected[permstr]" string => "-rw-------"; any:: "expects" slist => getindices("expected"); "fields" slist => getindices("test.stat"); "joint_condition" string => join(".", "expects"); classes: "$(expects)" expression => strcmp("$(test.stat[$(expects)])", "$(expected[$(expects)])"); "ok" expression => "$(joint_condition)"; reports: DEBUG:: "got $(G.testfile) field $(fields)=$(test.stat[$(fields)])"; "got $(G.testfile) field $(expects)=$(test.stat[$(expects)]) matches expected" if => "$(expects)"; "got $(G.testfile) field $(expects)=$(test.stat[$(expects)]) did NOT match expected $(expected[$(expects)])" if => "!$(expects)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/storejson.cf.expected.json0000644000000000000000000000037415010704253027503 0ustar00rootroot00000000000000{ "data": { "x": [ 1, 2, 3 ] }, "data_from_inline": "{\n \"a\": \"b\"\n}", "data_from_slist": "[\n \"x\",\n \"y\"\n]", "datas": "{\n \"x\": [\n 1,\n 2,\n 3\n ]\n}", "mylist": [ "x", "y" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/401.cf0000644000000000000000000000473315010704253023214 0ustar00rootroot00000000000000####################################################### # # Test readstringarray(), introduce a singleton with no other fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 singleton 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[singleton][0])", "singleton"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[singleton][1]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[singleton][0] = 'singleton', saw '$(test.ary[singleton][0])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/execresult_select.cf0000644000000000000000000000302415010704253026422 0ustar00rootroot00000000000000####################################################### # # Test that you can select stderr/stdout in execresult # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3108" } string => "Test that you can select stderr/stdout in execresult"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "result_with_stdout_stderr" string => execresult("$(G.echo) stdout; $(G.echo) stderr >&2", "useshell", "both"); "result_with_stdout" string => execresult("$(G.echo) stdout; $(G.echo) stderr >&2", "useshell", "stdout"); "result_with_stderr" string => execresult("$(G.echo) stdout; $(G.echo) stderr >&2", "useshell", "stderr"); classes: "pass_stdout_stderr" scope => "namespace", expression => strcmp( "stdout$(const.n)stderr", $(result_with_stdout_stderr) ); "pass_stdout" scope => "namespace", expression => strcmp( "stdout", $(result_with_stdout) ); "pass_stderr" scope => "namespace", expression => strcmp( "stderr", $(result_with_stderr) ); methods: "Pass/Fail" usebundle => dcs_passif("pass_stdout_stderr.pass_stdout.pass_stderr", $(this.promise_filename)); } bundle agent __main__ { methods: "test"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/gettags.cf.expected.json0000644000000000000000000000054315010704253027111 0ustar00rootroot00000000000000{ "tags1": [ "source=promise", "mytag1" ], "tags2": [ "source=promise" ], "tags3": [ "source=promise", "mytag3" ], "tags4": [ "source=promise" ], "tags5": [ "source=promise", "mytag5", "mytag51" ], "tags8": [ "1", "2" ], "tags9": [], "tagsa": [ "1", "2" ], "tagsb": [] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_readstringarray.cf.txt0000644000000000000000000000445215010704253027716 0ustar00rootroot00000000000000# app_name;instance;mmax;mmin;mperm;zone;tomcat_version;env;setenv;app_properties;newrelic;newrelic_name;newrelic_version;context_static;checks;action;context some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server cfengine-3.24.2/tests/acceptance/01_vars/02_functions/validdata.cf0000644000000000000000000000230415010704253024631 0ustar00rootroot00000000000000########################################################### # # Test validdata() with valid and invalid data files # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: "valid_json" string => "should appear", if => validdata(readfile("$(this.promise_filename).json", inf), "JSON"); "invalid_json" string => "should not appear", if => validdata(readfile("$(this.promise_filename).inv.json", inf), "JSON"); "valid_validjson" string => "should appear", if => validjson(readfile("$(this.promise_filename).json", inf)); "invalid_validjson" string => "should not appear", if => validjson(readfile("$(this.promise_filename).inv.json", inf)); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/052.cf0000644000000000000000000000162715010704253023215 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,0,0,0,2,100); } ####################################################### bundle agent check { vars: "time" int => "220"; classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readstringarrayidx.cf.txt0000644000000000000000000000445215010704253027432 0ustar00rootroot00000000000000# app_name;instance;mmax;mmin;mperm;zone;tomcat_version;env;setenv;app_properties;newrelic;newrelic_name;newrelic_version;context_static;checks;action;context some_app_config;9123;8192;512;192;europe;tomcat7;live;;this string is short and no problem at all;true;blah;2.0.3;false;true;fix;app_server working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789.;true;blah;2.0.3;false;true;fix;app_server not_working_app_config;9123;8192;512;192;europe;tomcat7;live;;.23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..23456789..;true;blah;2.0.3;false;true;fix;app_server cfengine-3.24.2/tests/acceptance/01_vars/02_functions/fold.cf0000644000000000000000000002250415010704253023630 0ustar00rootroot00000000000000####################################################### # # Test folding functions: length(), max(), min(), mean(), range(), and variance() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "a" slist => { "b", "c", "a" }; "b" slist => { "100", "9", "10" }; "c" slist => { }; "d" slist => { "", "a", "", "b" }; "e" slist => { "a", "1", "b" }; "f" rlist => { "100", "200", "300" }; "g" rlist => { "1.11", "-2.22", "-3.33" }; "h" ilist => { "-10", "0", "200" }; "i" data => parsejson('[ 1, 2, 3000 ]'); "j" data => parsejson('[ 1, 2, [ 3, 4, 5 ], null, true, false ]'); "k" data => parsejson('{}'); "l" data => parsejson('{ "a": 100, "b": 200, "c": null}'); "lists" slist => { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" }; "bad_lists" slist => { "c", "k" }; "good_lists" slist => difference("lists", "bad_lists"); "joined_$(lists)" string => format("%S", $(lists)); "length_$(lists)" int => length($(lists)); "lexmin_$(lists)" string => min($(lists), "lex"); "realmin_$(lists)" string => min($(lists), "real"); "lexmax_$(lists)" string => max($(lists), "lex"); "realmax_$(lists)" string => max($(lists), "real"); "variance_$(lists)" string => format("%.2f", variance($(lists))); "stddev_$(lists)" string => format("%.2f", eval("sqrt($(variance_$(lists)))", "math", "infix")); "mean_$(lists)" string => format("%.2f", mean($(lists))); reports: DEBUG:: "List $(lists): $(joined_$(lists)) had length $(length_$(lists))"; "List $(lists): $(joined_$(lists)) had variance $(variance_$(lists))"; "List $(lists): $(joined_$(lists)) had standard deviation $(stddev_$(lists))"; "List $(lists): $(joined_$(lists)) had mean $(mean_$(lists))"; "List $(lists): $(joined_$(lists)) had lex min $(lexmin_$(lists))"; "List $(lists): $(joined_$(lists)) had lex max $(lexmax_$(lists))"; "List $(lists): $(joined_$(lists)) had real min $(realmin_$(lists))"; "List $(lists): $(joined_$(lists)) had real max $(realmax_$(lists))"; } ####################################################### bundle agent check { vars: "lists" slist => { @(test.lists) }; "good_lists" slist => { @(test.good_lists) }; "methods" slist => { @(test.methods) }; "measurements" slist => { "length", "mean", "variance", "stddev", "lexmin", "lexmax", "realmin", "realmax" }; "expected[a][length]" int => "3"; "expected[b][length]" int => "3"; "expected[c][length]" int => "0"; "expected[d][length]" int => "4"; "expected[e][length]" int => "3"; "expected[f][length]" int => "3"; "expected[g][length]" int => "3"; "expected[h][length]" int => "3"; "expected[i][length]" int => "3"; "expected[j][length]" int => "6"; "expected[k][length]" int => "0"; "expected[l][length]" int => "3"; "expected[a][variance]" string => "0.00"; "expected[b][variance]" string => "2730.33"; "expected[c][variance]" string => "-1"; "expected[d][variance]" string => "0.00"; "expected[e][variance]" string => "0.33"; "expected[f][variance]" string => "10000.00"; "expected[g][variance]" string => "5.34"; "expected[h][variance]" string => "14033.33"; "expected[i][variance]" string => "2997001.00"; "expected[j][variance]" string => "0.92"; "expected[k][variance]" string => "0"; "expected[l][variance]" string => "5000.00"; "expected[a][stddev]" string => "0.00"; "expected[b][stddev]" string => "52.25"; "expected[c][stddev]" string => "-1"; "expected[d][stddev]" string => "0.00"; "expected[e][stddev]" string => "0.57"; "expected[f][stddev]" string => "100.00"; "expected[g][stddev]" string => "2.31"; "expected[h][stddev]" string => "118.46"; "expected[i][stddev]" string => "1731.18"; "expected[j][stddev]" string => "0.96"; "expected[k][stddev]" string => "0"; "expected[l][stddev]" string => "70.71"; "expected[a][mean]" string => "0.00"; "expected[b][mean]" string => "39.67"; "expected[c][mean]" string => "-1"; "expected[d][mean]" string => "0.00"; "expected[e][mean]" string => "0.33"; "expected[f][mean]" string => "200.00"; "expected[g][mean]" string => "-1.48"; "expected[h][mean]" string => "63.33"; "expected[i][mean]" string => "1001.00"; "expected[j][mean]" string => "0.75"; "expected[k][mean]" string => "0"; "expected[l][mean]" string => "150.00"; "expected[a][lexmin]" string => "a"; "expected[b][lexmin]" string => "10"; "expected[c][lexmin]" string => "-1"; "expected[d][lexmin]" string => ""; "expected[e][lexmin]" string => "1"; "expected[f][lexmin]" string => "100"; "expected[g][lexmin]" string => "-2.22"; "expected[h][lexmin]" string => "-10"; "expected[i][lexmin]" string => "1"; "expected[j][lexmin]" string => "1"; "expected[k][lexmin]" string => ""; "expected[l][lexmin]" string => "100"; "expected[a][realmin]" string => "a"; "expected[b][realmin]" string => "9"; "expected[c][realmin]" string => "-1"; "expected[d][realmin]" string => ""; "expected[e][realmin]" string => "a"; "expected[f][realmin]" string => "100"; "expected[g][realmin]" string => "-3.33"; "expected[h][realmin]" string => "-10"; "expected[i][realmin]" string => "1"; "expected[j][realmin]" string => "false"; "expected[k][realmin]" string => ""; "expected[l][realmin]" string => "100"; "expected[a][lexmax]" string => "c"; "expected[b][lexmax]" string => "9"; "expected[c][lexmax]" string => "-1"; "expected[d][lexmax]" string => "b"; "expected[e][lexmax]" string => "b"; "expected[f][lexmax]" string => "300"; "expected[g][lexmax]" string => "1.11"; "expected[h][lexmax]" string => "200"; "expected[i][lexmax]" string => "3000"; "expected[j][lexmax]" string => "true"; "expected[k][lexmax]" string => ""; "expected[l][lexmax]" string => "200"; "expected[a][realmax]" string => "c"; "expected[b][realmax]" string => "100"; "expected[c][realmax]" string => "-1"; "expected[d][realmax]" string => "b"; "expected[e][realmax]" string => "1"; "expected[f][realmax]" string => "300"; "expected[g][realmax]" string => "1.11"; "expected[h][realmax]" string => "200"; "expected[i][realmax]" string => "3000"; "expected[j][realmax]" string => "2"; "expected[k][realmax]" string => ""; "expected[l][realmax]" string => "200"; classes: "ok_$(measurements)_$(lists)" expression => strcmp("$(expected[$(lists)][$(measurements)])", "$(test.$(measurements)_$(lists))"); "no_$(measurements)_$(lists)" not => isvariable("test.$(measurements)_$(lists)"); "ok" and => { "ok_length_a", "ok_length_b", "ok_length_c", "ok_length_d", "ok_length_e", "ok_length_f", "ok_length_g", "ok_length_h", "ok_length_i", "ok_length_j", "ok_length_k", "ok_length_l", "ok_mean_a", "ok_mean_b", "no_mean_c", "ok_mean_d", "ok_mean_e", "ok_mean_f", "ok_mean_g", "ok_mean_h", "ok_mean_i", "ok_mean_j", "no_mean_k", "ok_mean_l", "ok_variance_a", "ok_variance_b", "no_variance_c", "ok_variance_d", "ok_variance_e", "ok_variance_f", "ok_variance_g", "ok_variance_h", "ok_variance_i", "ok_variance_j", "no_variance_k", "ok_variance_l", "ok_stddev_a", "ok_stddev_b", "no_stddev_c", "ok_stddev_d", "ok_stddev_e", "ok_stddev_f", "ok_stddev_g", "ok_stddev_h", "ok_stddev_i", "ok_stddev_j", "no_stddev_k", "ok_stddev_l", "ok_realmax_a", "ok_realmax_b", "no_realmax_c", "ok_realmax_d", "ok_realmax_e", "ok_realmax_f", "ok_realmax_g", "ok_realmax_h", "ok_realmax_i", "ok_realmax_j", "no_realmax_k", "ok_realmax_l", "ok_realmin_a", "ok_realmin_b", "no_realmin_c", "ok_realmin_d", "ok_realmin_e", "ok_realmin_f", "ok_realmin_g", "ok_realmin_h", "ok_realmin_i", "ok_realmin_j", "no_realmin_k", "ok_realmin_l", "ok_lexmax_a", "ok_lexmax_b", "no_lexmax_c", "ok_lexmax_d", "ok_lexmax_e", "ok_lexmax_f", "ok_lexmax_g", "ok_lexmax_h", "ok_lexmax_i", "ok_lexmax_j", "no_lexmax_k", "ok_lexmax_l", "ok_lexmin_a", "ok_lexmin_b", "no_lexmin_c", "ok_lexmin_d", "ok_lexmin_e", "ok_lexmin_f", "ok_lexmin_g", "ok_lexmin_h", "ok_lexmin_i", "ok_lexmin_j", "no_lexmin_k", "ok_lexmin_l", }; reports: DEBUG:: "$(good_lists) $(measurements) check expected '$(expected[$(good_lists)][$(measurements)])' <> actual '$(test.$(measurements)_$(good_lists))'" if => "!ok_$(measurements)_$(good_lists)"; "good list $(good_lists) had no $(measurements): '$(test.$(measurements)_$(good_lists))' was not expanded" if => "no_$(measurements)_$(good_lists)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/read_long_file.cf.txt0000644000000000000000000001112415010704253026447 0ustar00rootroot00000000000000line1 line2 line3 line4 line5 line6 line7 line8 line9 line10 line11 line12 line13 line14 line15 line16 line17 line18 line19 line20 line21 line22 line23 line24 line25 line26 line27 line28 line29 line30 line31 line32 line33 line34 line35 line36 line37 line38 line39 line40 line41 line42 line43 line44 line45 line46 line47 line48 line49 line50 line51 line52 line53 line54 line55 line56 line57 line58 line59 line60 line61 line62 line63 line64 line65 line66 line67 line68 line69 line70 line71 line72 line73 line74 line75 line76 line77 line78 line79 line80 line81 line82 line83 line84 line85 line86 line87 line88 line89 line90 line91 line92 line93 line94 line95 line96 line97 line98 line99 line100 line101 line102 line103 line104 line105 line106 line107 line108 line109 line110 line111 line112 line113 line114 line115 line116 line117 line118 line119 line120 line121 line122 line123 line124 line125 line126 line127 line128 line129 line130 line131 line132 line133 line134 line135 line136 line137 line138 line139 line140 line141 line142 line143 line144 line145 line146 line147 line148 line149 line150 line151 line152 line153 line154 line155 line156 line157 line158 line159 line160 line161 line162 line163 line164 line165 line166 line167 line168 line169 line170 line171 line172 line173 line174 line175 line176 line177 line178 line179 line180 line181 line182 line183 line184 line185 line186 line187 line188 line189 line190 line191 line192 line193 line194 line195 line196 line197 line198 line199 line200 line201 line202 line203 line204 line205 line206 line207 line208 line209 line210 line211 line212 line213 line214 line215 line216 line217 line218 line219 line220 line221 line222 line223 line224 line225 line226 line227 line228 line229 line230 line231 line232 line233 line234 line235 line236 line237 line238 line239 line240 line241 line242 line243 line244 line245 line246 line247 line248 line249 line250 line251 line252 line253 line254 line255 line256 line257 line258 line259 line260 line261 line262 line263 line264 line265 line266 line267 line268 line269 line270 line271 line272 line273 line274 line275 line276 line277 line278 line279 line280 line281 line282 line283 line284 line285 line286 line287 line288 line289 line290 line291 line292 line293 line294 line295 line296 line297 line298 line299 line300 line301 line302 line303 line304 line305 line306 line307 line308 line309 line310 line311 line312 line313 line314 line315 line316 line317 line318 line319 line320 line321 line322 line323 line324 line325 line326 line327 line328 line329 line330 line331 line332 line333 line334 line335 line336 line337 line338 line339 line340 line341 line342 line343 line344 line345 line346 line347 line348 line349 line350 line351 line352 line353 line354 line355 line356 line357 line358 line359 line360 line361 line362 line363 line364 line365 line366 line367 line368 line369 line370 line371 line372 line373 line374 line375 line376 line377 line378 line379 line380 line381 line382 line383 line384 line385 line386 line387 line388 line389 line390 line391 line392 line393 line394 line395 line396 line397 line398 line399 line400 line401 line402 line403 line404 line405 line406 line407 line408 line409 line410 line411 line412 line413 line414 line415 line416 line417 line418 line419 line420 line421 line422 line423 line424 line425 line426 line427 line428 line429 line430 line431 line432 line433 line434 line435 line436 line437 line438 line439 line440 line441 line442 line443 line444 line445 line446 line447 line448 line449 line450 line451 line452 line453 line454 line455 line456 line457 line458 line459 line460 line461 line462 line463 line464 line465 line466 line467 line468 line469 line470 line471 line472 line473 line474 line475 line476 line477 line478 line479 line480 line481 line482 line483 line484 line485 line486 line487 line488 line489 line490 line491 line492 line493 line494 line495 line496 line497 line498 line499 line500 line501 line502 line503 line504 line505 line506 line507 line508 line509 line510 line511 line512 line513 line514 line515 line516 line517 line518 line519 line520 line521 line522 line523 line524 line525 line526 line527 line528 line529 line530 line531 line532 line533 line534 line535 line536 line537 line538 line539 line540 line541 line542 line543 line544 line545 line546 line547 line548 line549 line550 line551 line552 line553 line554 line555 line556 line557 line558 line559 line560 line561 line562 line563 line564 line565 line566 line567 line568 line569 line570 line571 line572 line573 line574 line575 line576 line577 line578 line579 line580 line581 line582 line583 line584 line585 line586 line587 line588 line589 line590 line591 line592 line593 line594 line595 line596 line597 line598 line599 line600 cfengine-3.24.2/tests/acceptance/01_vars/02_functions/520.cf0000644000000000000000000000541015010704253023207 0ustar00rootroot00000000000000####################################################### # # Test parseintarray(), simple # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999:888:777:666 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parseintarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999][0])", "999"), strcmp("$(test.ary[999][1])", "888"), strcmp("$(test.ary[999][2])", "777"), strcmp("$(test.ary[999][3])", "666"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999][0] = '999', saw '$(test.ary[999][0])'"; "expected test.ary[999][1] = '888', saw '$(test.ary[999][1])'"; "expected test.ary[999][2] = '777', saw '$(test.ary[999][2])'"; "expected test.ary[999][3] = '999', saw '$(test.ary[999][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classfiltercsv_1.cf.csv0000644000000000000000000000022215010704253026736 0ustar00rootroot00000000000000ClassExpr,Token,Value any,net.ipv4.ip_forward,ANYVALUE supercalifragilisticexpialidociousNOTDEFINED,net.ipv4.ip_forward,SHOULD_BE_FILTERED_OUT cfengine-3.24.2/tests/acceptance/01_vars/02_functions/400.cf0000644000000000000000000000537715010704253023220 0ustar00rootroot00000000000000####################################################### # # Test readstringarray(), simple # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "is"), strcmp("$(test.ary[this][2])", "a"), strcmp("$(test.ary[this][3])", "test"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[this][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getindices_returns_expected_list_from_array.cf0000644000000000000000000000302115010704253033732 0ustar00rootroot00000000000000####################################################### # # Test that getindices() returns the expected list from # an array # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "data[foo]" slist => { "alpha", "bravo" }; "data[bar]" string => "zulu"; "data[bar][one]" string => "1"; "data[bar][two]" string => "2"; "data[zebra][gazelle]" slist => { "alpha", "bravo" }; "data[zebra][lion]" string => "zulu"; "data[zebra][lion][first]" string => "1st"; "data[zebra][lion][second]" string => "2nd"; "data[one][two][zero]" slist => { "alpha", "bravo" }; "data[one][two][three]" string => "zulu"; "data[one][two][three][a]" string => "c"; "data[one][two][three][b]" string => "d"; } ####################################################### bundle agent test { vars: "values_data_1" slist => getindices("init.data[bar]"); "values_data_2" slist => getindices("init.data[zebra][lion]"); "values_data_3" slist => getindices("init.data[one][two][three]"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/peers.cf.mustache0000644000000000000000000000003215010704253025622 0ustar00rootroot00000000000000{{#peers}}{{.}} {{/peers}}cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata_CFE-2551-1.cf0000644000000000000000000000302215010704253026034 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent main { methods: "test"; "check"; } bundle agent test { meta: "description" -> { "CFE-2551" } string => "Test that variables defined in other bundles with the same name are not included in a merged result"; vars: "a" string => "string a"; "b" string => "string b"; "vars1[a]" string => "$(a)"; "vars1[b]" string => "$(b)"; methods: "run_low_test_merged" usebundle => test_merged_low; } bundle agent test_merged_low { vars: "c" string => "string c"; "vars1[c]" string => "$(c)"; # We expect that only the values from the classic array vars1 in this # bundle will be merged together. And thus, we should only end up with ={ "vars1" : { "c": "string c" } }= "merged_data_vars" data => mergedata('{ "vars1": test_merged_low.vars1 }'); "merged_data_vars_str" string => format( "%S", merged_data_vars ); reports: DEBUG|EXTRA:: "$(this.bundle) : merged_data_vars_str : $(merged_data_vars_str)"; } bundle agent check { vars: "expected" string => '{"vars1":{"c":"string c"}}'; classes: "pass" expression => strcmp( $(expected), $(test_merged_low.merged_data_vars_str) ); reports: pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; "expected: '$(expected)'"; "got: '$(test_merged_low.merged_data_vars_str)'"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/sublist.cf.expected.json0000644000000000000000000000136615010704253027144 0ustar00rootroot00000000000000{ "test": [ "1", "2", "3", "one", "two", "three", "long string", "one", "two", "three" ], "test_head0": [], "test_head1": [ "1" ], "test_head9999": [ "1", "2", "3", "one", "two", "three", "long string", "one", "two", "three" ], "test_inline": [ "5", "6", "7" ], "test_tail0": [], "test_tail1": [ "three" ], "test_tail10": [ "1", "2", "3", "one", "two", "three", "long string", "one", "two", "three" ], "test_tail2": [ "two", "three" ], "test_tail9999": [ "1", "2", "3", "one", "two", "three", "long string", "one", "two", "three" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/datastate.cf.sub0000644000000000000000000000054215010704253025444 0ustar00rootroot00000000000000body file control { namespace => "visible_namespace"; } bundle common included { classes: "foo" expression => "any"; "bar" expression => "any", scope => "bundle"; vars: "i" int => "1"; "j" string => "two"; "k" slist => { "k2", "everest" }; "l" data => parsejson('[1, "l", "|"]'); # Night of the Bad Font } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/066.cf0000644000000000000000000000275415010704253023224 0ustar00rootroot00000000000000####################################################### # # Test getusers(), arg0 only # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: # All users except root, bin, and daemon "users" slist => getusers("root,daemon,bin",""); files: "$(G.testfile)" delete => init_delete; reports: cfengine_3:: "$(users)" report_to_file => "$(G.testfile)"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: # Try to delete the lines that shouldn't be there anyway "$(G.testfile)" edit_line => test_delete, classes => full_set; } bundle edit_line test_delete { delete_lines: "root"; "daemon"; "bin"; } body classes full_set { promise_kept => { "pass" }; promise_repaired => { "fail" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { classes: "ok" expression => "pass&!fail"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text.txt0000644000000000000000000000001215010704253024105 0ustar00rootroot00000000000000Succeeded cfengine-3.24.2/tests/acceptance/01_vars/02_functions/055.cf0000644000000000000000000000167015010704253023216 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(1,0,0,0,0,100); } ####################################################### bundle agent check { vars: "time" int => "31536100"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf0000644000000000000000000000356715010704253025113 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "tests" slist => { "q1", "q2", "q3", "q4" }; "offsets" ilist => { "-1", "-2", "-5", "-10", "-20", "-26", "-27", "-28", "-10240", "0", "1", "2", "5", "10", "20", "26", "27", "28", "10240" }; "fn1" slist => { "string_head", "string_tail" }; "data[q1]" string => "this is the Question"; "data[q2]" string => ""; "data[q3]" string => "some text is not $(const.t) simple "; "data[q4]" string => readfile("$(this.promise_filename).txt", "inf"); "data[$(tests)_string_reverse]" string => string_reverse("$(data[$(tests)])"); "data[$(tests)_string_length]" int => string_length("$(data[$(tests)])"); "data[$(tests)_string_upcase]" string => string_upcase("$(data[$(tests)])"); "data[$(tests)_string_downcase]" string => string_downcase("$(data[$(tests)])"); "data[$(tests)_string_head_$(offsets)]" string => string_head("$(data[$(tests)])", $(offsets)); "data[$(tests)_string_tail_$(offsets)]" string => string_tail("$(data[$(tests)])", $(offsets)); "data[$(tests)_string_head_inline_pos]" string => string_head("$(data[$(tests)])", 3); "data[$(tests)_string_tail_inline_pos]" string => string_tail("$(data[$(tests)])", 3); "data[$(tests)_string_head_inline_neg]" string => string_head("$(data[$(tests)])", "-3"); "data[$(tests)_string_tail_inline_neg]" string => string_tail("$(data[$(tests)])", "-3"); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mapdata_json_pipe.cf.jqinput.json0000644000000000000000000000014015010704253031012 0ustar00rootroot00000000000000{ "user": "stedolan", "title": "JQ Primer" } { "user": "stedolan", "title": "More JQ" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/countlinesmatching.cf0000644000000000000000000000253115010704253026600 0ustar00rootroot00000000000000# Test that countlinesmatching works correctly body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { } bundle agent test { vars: # meta comment 1 # meta comment 2 # meta comment 3 # meta comment 4 "metagrep" int => countlinesmatching(".*# meta comment.*", $(this.promise_filename)); "exactgrep" int => countlinesmatching("bundle agent test", $(this.promise_filename)); "nullgrep" int => countlinesmatching("blue hippo, purple elephant, yellow submarine", $(this.promise_filename)); } bundle agent check { classes: "ok" and => { strcmp("$(test.metagrep)", "5"), # the 4 comments plus the pattern! strcmp("$(test.exactgrep)", "1"), strcmp("$(test.nullgrep)", "0") }; reports: DEBUG:: "Grepping for 'meta comment' found $(test.metagrep) matches, expected 5"; "Grepping for exactly 'bundle agent test' found $(test.exactgrep) matches, expected 1"; "Grepping for children's rhyme found $(test.nullgrep) matches, expected 0"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maplist.cf0000644000000000000000000000234615010704253024357 0ustar00rootroot00000000000000####################################################### # # Test maplist() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "testlist" slist => { "zero", "two", "three's", "four-fore:quatre", "last" }; "empty" slist => { }; "mapped_testlist" slist => maplist("value=$(this)", "testlist"); "mapped_empty" slist => maplist("value=$(this)", empty); "mapped_inline" slist => maplist("value=$(this)", '["a", "b", "c"]'); "mapped_function_empty" slist => maplist(canonify($(this)), empty); "mapped_function1" slist => maplist(format("%10.10s", $(this)), testlist); "mapped_function2" slist => maplist(canonify($(this)), '["a or b", "b and c", "c+d", "e"]'); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/maparray_multi_index.cf0000644000000000000000000000346615010704253027127 0ustar00rootroot00000000000000########################################################### # # Test maparray for multi-index arrays # Redmine#6033 # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ########################################################### bundle agent init { } ########################################################### bundle agent test { vars: "bundles[x][y][z1]" string => "xyz1"; "bundles[x][y][z23]" slist => { "xyz2", "xyz3" }; "bundles[zculib][mypaths]" slist => { "pathsa.cf", "pathsb.cf" }; "bundles[zculib][myservices]" slist => { "myservices.cf" }; #make sure that below variables will be not mapped "bundles[zcuinventory][zcuinventory]" slist => { "inv_zcuinventory.cf" }; "bundles[zcuinventory][inventory_fibrechannel]" slist => { "inv_fibrechannel.cf" }; "bundles[zcuinventory][inventory_virtualization]" slist => { "inv_virtualization.cf" }; "bundles[services][afs]" slist => { "afs.cf", "afsadm.cf" }; "bundles[services][base]" slist => { "base.cf", "base2.cf" }; "bundles[onelevel1]" slist => { "onelevel1_avalue", "onelevel1_bvalue" }; "bundles[onelevel2]" string => "onelevel2value"; "inputs" slist => maparray("zculib/$(this.v)","bundles[zculib]"); "merged_bundles" data => mergedata(bundles); "merged_zculib" data => mergedata("bundles[zculib]"); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/620.cf0000644000000000000000000000546115010704253023216 0ustar00rootroot00000000000000####################################################### # # Test parserealarray(), simple # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999.9:888:777:666.6 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parserealarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999.9][0])", "999.9"), strcmp("$(test.ary[999.9][1])", "888"), strcmp("$(test.ary[999.9][2])", "777"), strcmp("$(test.ary[999.9][3])", "666.6"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999.9][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999.9][0] = '999.9', saw '$(test.ary[999.9][0])'"; "expected test.ary[999.9][1] = '888', saw '$(test.ary[999.9][1])'"; "expected test.ary[999.9][2] = '777', saw '$(test.ary[999.9][2])'"; "expected test.ary[999.9][3] = '999.9', saw '$(test.ary[999.9][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/002.cf0000644000000000000000000000465515010704253023214 0ustar00rootroot00000000000000####################################################### # # Test getgid() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_skip_needs_work" string => "windows"; vars: linux|freebsd|solaris|openbsd|hpux:: "gid_daemon" int => getgid("daemon"); "gid_sys" int => getgid("sys"); darwin:: "gid_daemon" int => getgid("daemon"); aix:: "gid_sys" int => getgid("sys"); !linux.!freebsd.!solaris.!darwin.!openbsd.!hpux.!aix:: "gid_daemon" string => "fixme"; "gid_sys" string => "fixme"; linux|solaris|hpux:: "gid_0" int => getgid("root"); freebsd|darwin|openbsd:: "gid_0" int => getgid("wheel"); aix:: "gid_0" int => getgid("system"); !linux.!freebsd.!solaris.!darwin.!openbsd.!hpux.!aix:: "gid_0" string => "fixme"; archlinux|SuSE|redhat|gentoo:: "num_daemon" int => "2"; (linux.!archlinux.!SuSE.!redhat.!gentoo)|freebsd|darwin|openbsd:: "num_daemon" int => "1"; solaris:: "num_daemon" int => "12"; hpux:: "num_daemon" int => "5"; !linux.!freebsd.!solaris.!darwin.!openbsd.!hpux.!aix:: "num_daemon" string => "fixme"; linux|freebsd|solaris|openbsd|hpux|aix:: "num_sys" int => "3"; !linux.!freebsd.!solaris.!darwin.!openbsd.!hpux.!aix:: "num_sys" string => "fixme"; } ####################################################### bundle agent check { classes: darwin:: "ok_sys" expression => "any"; !darwin:: "ok_sys" expression => strcmp("$(test.gid_sys)", "$(test.num_sys)"); aix:: "ok_daemon" expression => "any"; !aix:: "ok_daemon" expression => strcmp("$(test.gid_daemon)", "$(test.num_daemon)"); any:: "ok" and => { strcmp("$(test.gid_0)", "0"), "ok_sys", "ok_daemon" }; reports: DEBUG:: "root/wheel is GID $(test.gid_0), expected 0"; "daemon is GID $(test.gid_daemon), expected $(test.num_daemon)"; "sys is GID $(test.gid_sys), expected $(test.num_sys)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata_CFE-2551-2.cf0000644000000000000000000000302115010704253026034 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent main { methods: "test"; "check"; } bundle agent test { meta: "description" -> { "CFE-2551" } string => "Test that variables defined in other bundles with the same name are not included in a merged result"; vars: "a" string => "string a"; "b" string => "string b"; "vars1[a]" string => "$(a)"; "vars1[b]" string => "$(b)"; methods: "run_low_test_merged" usebundle => test_merged_low; } bundle agent test_merged_low { vars: "c" string => "string c"; "vars1[c]" string => "$(c)"; # We expect that only the values from the classic array vars1 in this # bundle will be merged together. And thus, we should only end up with ={ "vars1" : { "c": "string c" } }= "merged_data_vars" data => mergedata('{ "vars1": $(this.bundle).vars1 }'); "merged_data_vars_str" string => format( "%S", merged_data_vars ); reports: DEBUG|EXTRA:: "$(this.bundle) : merged_data_vars_str : $(merged_data_vars_str)"; } bundle agent check { vars: "expected" string => '{"vars1":{"c":"string c"}}'; classes: "pass" expression => strcmp( $(expected), $(test_merged_low.merged_data_vars_str) ); reports: pass:: "$(this.promise_filename) Pass"; !pass:: "$(this.promise_filename) FAIL"; "expected: '$(expected)'"; "got: '$(test_merged_low.merged_data_vars_str)'"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/nth_datacontainer.cf0000644000000000000000000000474015010704253026373 0ustar00rootroot00000000000000####################################################### # # Test nth() with data container input # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" copy_from => local_cp("$(this.promise_filename).expected"); } ####################################################### bundle common test_common { vars: "data" data => readjson("$(this.promise_filename).json", "100k"); "datastr" string => format("%S", data); "numbers" ilist => { "-100", "-1", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1000 }; "keys" slist => getindices(data); "object_keys" slist => getindices("data[object]"); "list_keys" slist => getindices("data[list]"); "all_keys" slist => { @(object_keys), @(list_keys), "foo", "bar", "", $(numbers), $(keys) }; "primitives[$(keys)]" string => nth(data, $(keys)); "list[$(all_keys)]" string => nth("data[list]", $(all_keys)); "object[$(all_keys)]" string => nth("data[object]", $(all_keys)); classes: "hasprimitive_$(keys)" expression => isvariable("primitives[$(keys)]"); "haslist_$(all_keys)" expression => isvariable("list[$(all_keys)]"); "hasobject_$(all_keys)" expression => isvariable("object[$(all_keys)]"); } bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "jsonstring = $(test_common.datastr)"; "keys:json = $(test_common.keys)"; "primitive:json[$(test_common.keys)] = $(test_common.primitives[$(test_common.keys)])" if => "hasprimitive_$(test_common.keys)"; "list:json[$(test_common.all_keys)] = $(test_common.list[$(test_common.all_keys)])" if => "haslist_$(test_common.all_keys)"; "object:json[$(test_common.all_keys)] = $(test_common.object[$(test_common.all_keys)])" if => "hasobject_$(test_common.all_keys)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mapdata_json_pipe.cf0000644000000000000000000000240215010704253026354 0ustar00rootroot00000000000000####################################################### # # Test mapdata('json_pipe') # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: # Skip on Windows because we use shell script below. "test_skip_needs_work" string => "windows"; vars: "items" data => '{"user":"stedolan","titles":["JQ Primer", "More JQ"]}'; "items_passthrough" data => mapdata("json_pipe", "$(G.cat)", items); "items_jqinput" data => mapdata("json_pipe", "$(this.promise_dirname)/mapdata_json_pipe.cat_consume_input.sh $(this.promise_filename).jqinput.json", items); "items_input" data => mapdata("json_pipe", "$(this.promise_dirname)/mapdata_json_pipe.cat_consume_input.sh $(this.promise_filename).input.json", items); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/every_some_none.cf.expected.json0000644000000000000000000000036215010704253030646 0ustar00rootroot00000000000000{ "collected": [ "every1", "everyd11", "everyd21", "everyd22", "inline_none_data", "inline_some_data", "none1", "none_dempty", "none_empty", "noned11", "noned21", "some1", "somed11" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/execresult_stderr.cf0000644000000000000000000000271115010704253026450 0ustar00rootroot00000000000000####################################################### # # Test execresult() captures stdout and stderr # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-3103" } string => "Test that execresult captures both stdout and stderr"; "test_soft_fail" string => "windows", meta => { "ENT-10217" }; vars: "result_with_stdout_stderr" string => execresult("$(G.echo) stdout; $(G.echo) stderr >&2", "useshell"); "result_with_stdout" string => execresult("$(G.echo) stdout", "useshell"); "result_with_stderr" string => execresult("$(G.echo) stderr >&2", "useshell"); classes: "pass_stdout_stderr" scope => "namespace", expression => strcmp( "stdout$(const.n)stderr", $(result_with_stdout_stderr) ); "pass_stdout" scope => "namespace", expression => strcmp( "stdout", $(result_with_stdout) ); "pass_stderr" scope => "namespace", expression => strcmp( "stderr", $(result_with_stderr) ); methods: "Pass/Fail" usebundle => dcs_passif("pass_stdout_stderr.pass_stdout.pass_stderr", $(this.promise_filename)); } bundle agent __main__ { methods: "test"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/013.cf0000644000000000000000000000277115010704253023213 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readstringarray_dontread_comment_duplicatekey_lastline.cf0000644000000000000000000001104015010704253036057 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test readstringarray(), don't read comment, duplicate key or last line # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","NoComment",":",6,1000); "num" int => "6"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "is"), strcmp("$(test.ary[this][2])", "a"), strcmp("$(test.ary[this][3])", "test"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/classmatch.cf0000644000000000000000000000226515010704253025030 0ustar00rootroot00000000000000# Test that classmatch works correctly body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle common init { classes: "test_fbeae67f3e347b5e0032302200141131" expression => "any", meta => { "x" }; "test_fbeae67f3e347b5e0032302200141131_1" expression => "any", meta => { "x" }; "test_fbeae67f3e347b5e0032302200141131_2" expression => "any", meta => { "y" }; } bundle common test { classes: "have_classes" expression => classmatch("test_fbeae67f3e347b5e0032302200141131"); "have_x_classes" expression => classmatch("test_fbeae67f3e347b5e0032302200141131_1.*", "x"); "have_z_classes" expression => classmatch("nosuchclass"); "have_z_classes" expression => classmatch("test_fbeae67f3e347b5e0032302200141131_2", "z"); "have_z_classes" expression => classmatch("test_fbeae67f3e347b5e0032302200141131_2.*", "z"); } bundle agent check { methods: "" usebundle => dcs_passif_expected("have_classes,have_x_classes", "have_z_classes", $(this.promise_filename)), inherit => "true"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/211.cf0000644000000000000000000000301715010704253023205 0ustar00rootroot00000000000000####################################################### # # Test getvalues(string), should return the string itself # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; "expected" string => "blah"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert("$(init.expected)"), edit_defaults => init_empty; } bundle edit_line init_insert(str) { insert_lines: "$(str)"; } body edit_defaults init_empty { empty_file_before_editing => "true"; } ####################################################### bundle agent test { vars: "array" string => "blah"; # Intentionally not an array "vals" slist => getvalues("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mustache_iteration_with_nonfalse_values.cf0000644000000000000000000000160315010704253033067 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "test_soft_fail" string => "any", meta => { "CFE-2535" }; } bundle agent check { vars: "json" data => '{"test":[ {"a?":{"val":"a1"}}, {"b?":{"val":"b2"}}, {"a?":{"val":"a3"}} ]}'; "json_str" string => format("%S", 'json'); "result" string => string_mustache('{{#test}} --- A:{{#a?}}{{val}}{{/a?}}, B:{{#b?}}{{val}}{{/b?}} {{/test}}', json); "expected" string => "--- A:a1, B: --- A:, B:b2 --- A:a3,B: "; reports: "$(this.promise_filename) Pass" if => strcmp( $(result), $(expected) ); "$(this.promise_filename) FAIL" unless => strcmp( $(result), $(expected) ); EXTRA:: "$(sys.cf_version)"; "Result: $(result)"; "Should be: $(expected)"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/join.cf0000644000000000000000000000523415010704253023644 0ustar00rootroot00000000000000####################################################### # # test join() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "a" slist => { "b", "c", "a" }; "b" slist => { "100", "9", "10" }; "c" slist => { }; "d" slist => { "", "a", "", "b" }; "e" slist => { "a", "1", "b" }; "f" rlist => { "100", "200", "300" }; "g" rlist => { "1.11", "-2.22", "-3.33" }; "h" ilist => { "-10", "0", "200" }; "i" data => parsejson('[ 1, 2, "", 3000, "" ]'); "j" data => parsejson('[ 1, 2, [ 3, 4, 5 ], null, true, false ]'); "k" data => parsejson('{}'); "l" data => parsejson('{ "a": 100, "b": 200, "c": null}'); "m" slist => { "cf_null" }; "n" slist => { "a", "b", "c", "cf_null" }; "o" slist => { @(a), @(c) }; "p" slist => { @(c), @(m) }; "q" slist => { ":", ":" }; "r" slist => { ":", @(c) }; "s" slist => { ":", @(c), @(m) }; "t" slist => { @(n), @(m), @(n), ":" }; "lists" slist => { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t" }; } ####################################################### bundle agent test { # "expected_a" string => "b:c:a"; # "expected_b" string => "100:9:10"; # "expected_c" string => ""; # "expected_d" string => ":a::b"; # "expected_e" string => "a:1:b"; # "expected_f" string => "100:200:300"; # "expected_g" string => "1.11:-2.22:-3.33"; # "expected_h" string => "-10:0:200"; # "expected_i" string => "1:2::3000:"; # "expected_j" string => "1:2:true:false"; # "expected_k" string => ""; # "expected_l" string => "100:200"; # "expected_m" string => "cf_null"; # "expected_n" string => "a:b:c:cf_null"; # "expected_o" string => "b:c:a"; # "expected_p" string => "cf_null"; # "expected_q" string => ":::"; # "expected_r" string => ":"; # "expected_s" string => "::cf_null"; # "expected_t" string => "a:b:c:cf_null:cf_null:a:b:c:cf_null::"; vars: "lists" slist => { @(init.lists) }; "join_$(lists)" string => join(":", "init.$(lists)"); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/type.cf.expected.json0000644000000000000000000000142515010704253026434 0ustar00rootroot00000000000000{ "test_00": "data", "test_01": "data object", "test_02": "data", "test_03": "data string", "test_04": "data", "test_05": "data int", "test_06": "data", "test_07": "data real", "test_08": "data", "test_09": "data boolean", "test_10": "data", "test_11": "data boolean", "test_12": "data", "test_13": "data object", "test_14": "data", "test_15": "data array", "test_16": "data", "test_17": "data null", "test_18": "string", "test_19": "policy string", "test_20": "int", "test_21": "policy int", "test_22": "real", "test_23": "policy real", "test_24": "slist", "test_25": "policy slist", "test_26": "ilist", "test_27": "policy ilist", "test_28": "rlist", "test_29": "policy rlist", "test_30": "none", "test_31": "policy none" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/018.cf0000644000000000000000000000307615010704253023217 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456 789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata.cf.env0000644000000000000000000000167715010704253025250 0ustar00rootroot00000000000000# Example env file used for acceptance test readdata.cf # We can't test for all weird possibilites, # but this should serve most use cases A=B C="D" E="F\"G" x=y EMPTY= SPACE=" " BACKSLASH=\\ BACKSLASH2="\\" DOUBLE_QUOTE1=\" DOUBLE_QUOTE2="\"" DOUBLE_QUOTE3='\"' SINGLE_QUOTE1=\' SINGLE_QUOTE2='\'' SINGLE_QUOTE3="\'" QUOTE_IN_TEXT="text \"quote\" text" INDENT = "hello" INDENT1 = "world" INDENT12 = "!" INDENT123= "!" # override OVERRIDE=old OVERRIDE=new MESSAGE_TO_NICK='Single quotes are "fine"!' UNFINISHED_QUOTE1='OOPS UNFINISHED_QUOTE2="WOOPS NAME="Test Linux by CFEngine" ID=cfengineos VERSION=1234.5.0 BUILD_ID=2017-02-14-2245 PRETTY_NAME="Test Linux by CFEngine 1234.5.0 (Leafant)" ANSI_COLOR="37;4;65" HOME_URL="https://cfengine.com/" BUG_REPORT_URL="https://northerntech.atlassian.net/projects/CFE/issues" # Quote closing X_COMMENT="Outisde content not included" This part shouldn't be included Y_COMMENT="Comment #included" cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/0000755000000000000000000000000015010704253024023 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readintarray_non_integers3.cf0000644000000000000000000000544215010704253031664 0ustar00rootroot00000000000000####################################################### # # Test readintarray(), introduce non-integers (issue 313 and 368) # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999::bogus:666 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parseintarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999][0])", "999"), strcmp("$(test.ary[999][1])", "0"), strcmp("$(test.ary[999][2])", "0"), strcmp("$(test.ary[999][3])", "666"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999][0] = '999', saw '$(test.ary[999][0])'"; "expected test.ary[999][1] = '0', saw '$(test.ary[999][1])'"; "expected test.ary[999][2] = '0', saw '$(test.ary[999][2])'"; "expected test.ary[999][3] = '999', saw '$(test.ary[999][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readstringarray_introduce_nonparsed_comment.cf0000644000000000000000000000634615010704253035337 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test readstringarray(), introduce a non-parsed comment # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 # Not parsed as a comment this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "4"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[# Not parsed as a comment][0])", "# Not parsed as a comment"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "is"), strcmp("$(test.ary[this][2])", "a"), strcmp("$(test.ary[this][3])", "test"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[# Not parsed as a comment][1]"), isvariable("test.ary[this][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[# Not parsed as a comment][0] = '# Not parsed as a comment', saw 'expected $(test.ary[# Not parsed as a comment][0])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_duplicates_trailing_newlines2.cf0000644000000000000000000001162415010704253040646 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, duplicate and trailing newlines # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one "; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "9"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "# A duplicate follows"), strcmp("$(test.ary[6][1])", " this line is not always a comment"), strcmp("$(test.ary[7][0])", "this"), strcmp("$(test.ary[7][1])", "also"), strcmp("$(test.ary[8][0])", "last"), strcmp("$(test.ary[8][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = '# A duplicate follows', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ' this line is not always a comment', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'this', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'also', saw '$(test.ary[7][1])'"; "expected test.ary[8][0] = 'last', saw '$(test.ary[8][0])'"; "expected test.ary[8][1] = 'one', saw '$(test.ary[8][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/format_empty_lists.cf0000644000000000000000000000157215010704253030266 0ustar00rootroot00000000000000# ensure interpolated empty lists don't drag in cf_null body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "list" slist => { "item1", "item2", "item3", "item4", "item5" }; } bundle agent test { vars: "local" slist => { }; # should *not* bring in cf_null "splice" slist => { @(init.list), @(local) }; } bundle agent check { vars: "expected" string => '{ "item1", "item2", "item3", "item4", "item5" }'; "joined" string => format("%S", "test.splice"); methods: "check" usebundle => dcs_check_strcmp($(expected), $(joined), "$(this.promise_filename)", "no"); } parsestringarray_weird_indices_real_comments_noemptyfields3.cf0000644000000000000000000001035115010704253040503 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, real comments, no empty fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","^#.*",":+",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", "in here"), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "this"), strcmp("$(test.ary[6][1])", "also"), strcmp("$(test.ary[7][0])", "last"), strcmp("$(test.ary[7][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = 'in here', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = 'this', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = 'also', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'last', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'one', saw '$(test.ary[7][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readintlist2.cf0000644000000000000000000000302015010704253026734 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123,broken,456,789"; # non-numeric fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_change_comment_parsing.cf0000644000000000000000000001213515010704253037322 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, change comment parsing # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[# A duplicate follows][0])", "# A duplicate follows"), strcmp("$(test.ary[# A duplicate follows][1])", "this line is not always a comment"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readstringarray_weird_indices_trailing_newlines.cf0000644000000000000000000001207115010704253036145 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test readstringarray(), weird indices, duplicate and trailing newlines # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one "; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[# A duplicate follows][0])", "# A duplicate follows"), strcmp("$(test.ary[# A duplicate follows][1])", "this line is not always a comment"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readstringarray_weird_indices_real_comments_noemptyfields.cf0000644000000000000000000001067415010704253040231 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test readstringarray(), weird indices, real comments, no empty fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","^#.*",":+",10,1000); "num" int => "7"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", "in here"), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = 'in here', saw '$(test.ary[blank][2])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/execresult_large.cf0000644000000000000000000000263515010704253027700 0ustar00rootroot00000000000000####################################################### # # Test execresult() of large files # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { } ####################################################### bundle agent check { vars: "testlengths" ilist => { "1024", "4096", "100000", "500000" }; "result_$(testlengths)" string => execresult("$(G.perl) -e 'my $x = qw/x/ x $(testlengths); print $x;'", "useshell"); "length_$(testlengths)" int => strlen("$(result_$(testlengths))"); classes: "ok_$(testlengths)" expression => strcmp("$(length_$(testlengths))", $(testlengths)); "ok" and => { "ok_1024", "ok_4096", "ok_100000", "ok_500000", }; reports: DEBUG:: "the read of $(testlengths) bytes gave $(length_$(testlengths)) bytes"; "the read of $(testlengths) bytes failed to match the expected $(testlengths) bytes, actual = $(length_$(testlengths))" if => "!ok_$(testlengths)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/datatype.cf0000644000000000000000000002054715010704253026160 0ustar00rootroot00000000000000####################################################### # # Test datatype() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "results" string => 'jsonstring = { "person": { "first": "miyamoto", "last": "musashi" }, "birth": null, "death": 16450613, "go rin no sho": { "1": "ground", "2": "water", "3": "fire", "4": "wind", "5": "void" }, "dokkÅdÅ": [ "accept everything just the way it is.", "do not seek pleasure for its own sake.", "do not, under any circumstances, depend on a partial feeling.", "think lightly of yourself and deeply of the world.", "be detached from desire your whole life.", "do not regret what you have done.", "never be jealous.", "never let yourself be saddened by a separation.", "resentment and complaint are appropriate neither for oneself nor others.", "do not let yourself be guided by the feeling of lust or love.", "In all things, have no preferences.", "be indifferent to where you live.", "do not pursue the taste of good food.", "do not hold on to possessions you no longer need.", "do not act following customary beliefs.", "do not collect weapons or practice with weapons beyond what is useful.", "do not fear death.", "do not seek to possess either goods or fiefs for your old age.", "respect buddha and the gods without counting on their help.", "you may abandon your own body but you must preserve your honor.", "never stray from the way." ], "styles": [ "two heavens as one", "two swords as one" ], "decidable": false, "dituri was here": 3.1416 }'; "results2" string => '--------------------- toplevel:key = person toplevel:key = birth toplevel:key = death toplevel:key = go rin no sho toplevel:key = dokkÅdÅ toplevel:key = styles toplevel:key = decidable toplevel:key = dituri was here toplevel[person]:type = json_object toplevel[birth]:type = json_null toplevel[death]:type = json_integer toplevel[go rin no sho]:type = json_object toplevel[dokkÅdÅ]:type = json_array toplevel[styles]:type = json_array toplevel[decidable]:type = json_bool toplevel[dituri was here]:type = json_real ------------------------------------------ toplevel[person]:key= first toplevel[go rin no sho]:key= 1 toplevel[dokkÅdÅ]:key= 0 toplevel[styles]:key= 0 toplevel[person]:key= last toplevel[go rin no sho]:key= 2 toplevel[go rin no sho]:key= 3 toplevel[go rin no sho]:key= 4 toplevel[go rin no sho]:key= 5 toplevel[dokkÅdÅ]:key= 1 toplevel[dokkÅdÅ]:key= 2 toplevel[dokkÅdÅ]:key= 3 toplevel[dokkÅdÅ]:key= 4 toplevel[dokkÅdÅ]:key= 5 toplevel[dokkÅdÅ]:key= 6 toplevel[dokkÅdÅ]:key= 7 toplevel[dokkÅdÅ]:key= 8 toplevel[dokkÅdÅ]:key= 9 toplevel[dokkÅdÅ]:key= 10 toplevel[dokkÅdÅ]:key= 11 toplevel[dokkÅdÅ]:key= 12 toplevel[dokkÅdÅ]:key= 13 toplevel[dokkÅdÅ]:key= 14 toplevel[dokkÅdÅ]:key= 15 toplevel[dokkÅdÅ]:key= 16 toplevel[dokkÅdÅ]:key= 17 toplevel[dokkÅdÅ]:key= 18 toplevel[dokkÅdÅ]:key= 19 toplevel[dokkÅdÅ]:key= 20 toplevel[styles]:key= 1'; "results3" string => 'toplevel[person][first]:type = json_string toplevel[go rin no sho][1]:type = json_string toplevel[dokkÅdÅ][0]:type = json_string toplevel[styles][0]:type = json_string toplevel[person][last]:type = json_string toplevel[go rin no sho][2]:type = json_string toplevel[go rin no sho][3]:type = json_string toplevel[go rin no sho][4]:type = json_string toplevel[go rin no sho][5]:type = json_string toplevel[dokkÅdÅ][1]:type = json_string toplevel[dokkÅdÅ][2]:type = json_string toplevel[dokkÅdÅ][3]:type = json_string toplevel[dokkÅdÅ][4]:type = json_string toplevel[dokkÅdÅ][5]:type = json_string toplevel[dokkÅdÅ][6]:type = json_string toplevel[dokkÅdÅ][7]:type = json_string toplevel[dokkÅdÅ][8]:type = json_string toplevel[dokkÅdÅ][9]:type = json_string toplevel[dokkÅdÅ][10]:type = json_string toplevel[dokkÅdÅ][11]:type = json_string toplevel[dokkÅdÅ][12]:type = json_string toplevel[dokkÅdÅ][13]:type = json_string toplevel[dokkÅdÅ][14]:type = json_string toplevel[dokkÅdÅ][15]:type = json_string toplevel[dokkÅdÅ][16]:type = json_string toplevel[dokkÅdÅ][17]:type = json_string toplevel[dokkÅdÅ][18]:type = json_string toplevel[dokkÅdÅ][19]:type = json_string toplevel[dokkÅdÅ][20]:type = json_string toplevel[styles][1]:type = json_string ok: datatype(datastr) failed properly'; files: "$(G.testfile).expected" create => "true", edit_defaults => init_empty, edit_line => init_insert; } body edit_defaults init_empty { empty_file_before_editing => "true"; edit_backup => "false"; } bundle edit_line init_insert { insert_lines: "$(init.results)"; "$(init.results2)"; "$(init.results3)"; } ####################################################### bundle common test_common { vars: "datastr" string => storejson("data"); "data" data => parsejson(' { "person": { "first": "miyamoto", "last": "musashi" }, "birth": null, "death": 16450613, "go rin no sho": { "1": "ground", "2": "water", "3": "fire", "4": "wind", "5": "void" }, "dokkÅdÅ": [ "accept everything just the way it is.", "do not seek pleasure for its own sake.", "do not, under any circumstances, depend on a partial feeling.", "think lightly of yourself and deeply of the world.", "be detached from desire your whole life.", "do not regret what you have done.", "never be jealous.", "never let yourself be saddened by a separation.", "resentment and complaint are appropriate neither for oneself nor others.", "do not let yourself be guided by the feeling of lust or love.", "In all things, have no preferences.", "be indifferent to where you live.", "do not pursue the taste of good food.", "do not hold on to possessions you no longer need.", "do not act following customary beliefs.", "do not collect weapons or practice with weapons beyond what is useful.", "do not fear death.", "do not seek to possess either goods or fiefs for your old age.", "respect buddha and the gods without counting on their help.", "you may abandon your own body but you must preserve your honor.", "never stray from the way." ], "styles": ["two heavens as one","two swords as one"], "decidable": false "dituri was here": 3.14159265 } '); "typenames" slist => { "person", "go rin no sho", "dokkÅdÅ", "styles" }; "keys[top]" slist => getindices("data"); "types[top][$(keys[top])]" string => datatype("data[$(keys[top])]"); "keys[$(typenames)]" slist => getindices("data[$(typenames)]"); "types[$(typenames)][$(keys[$(typenames)])]" string => datatype("data[$(typenames)][$(keys[$(typenames)])]"); "bad_type_test" string => datatype("datastr"); classes: "ok_invalid_test_failed" not => isvariable("bad_type_test"); } bundle agent test { files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: cfengine:: "jsonstring = $(test_common.datastr)"; "---------------------"; "toplevel:key = $(test_common.keys[top])"; "toplevel[$(test_common.keys[top])]:type = $(test_common.types[top][$(test_common.keys[top])])"; "------------------------------------------"; "toplevel[$(test_common.typenames)]:key= $(test_common.keys[$(test_common.typenames)])"; "toplevel[$(test_common.typenames)][$(test_common.keys[$(test_common.typenames)])]:type = $(test_common.types[$(test_common.typenames)][$(test_common.keys[$(test_common.typenames)])])"; ok_invalid_test_failed:: "------------------------------------------"; "ok: datatype(datastr) failed properly"; !ok_invalid_test_failed:: "------------------------------------------"; "NOT_OK: datatype(datastr) was supposed to fail"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } parsestringarrayidx_weird_indices_real_comments_noemptyfields.cf0000644000000000000000000000510515010704253041126 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarrayidx(), add some weird indices, real comments, no empty fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)","^#.*",":+"14); "cnt" int => parsestringarrayidx("ary", "$(teststr)","^#.*",":+",10,14); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "bad" or => { isvariable("test.ary[2][1]"), isvariable("test.ary[3][0]"), }; "ok" and => { "!bad", strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "he"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "saw 'bad'-class things"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'he', saw '$(test.ary[2][0])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/getindices_size5_namespaces.cf.sub0000644000000000000000000000076615010704253032572 0ustar00rootroot00000000000000body file control { namespace => "testing_arrays"; } bundle agent namespaced_test(file, arrayname) { vars: "keys" slist => getindices("$(arrayname)"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Working in namespace; array name $(arrayname)"; "Inserting line: $(keys)"; } bundle edit_line test_insert { vars: "keys" slist => { @{namespaced_test.keys} }; insert_lines: "$(keys)"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readrealarray_non_integers2.cf0000644000000000000000000000551315010704253032013 0ustar00rootroot00000000000000####################################################### # # Test readrealarray(), introduce non-integers (issue 313 and 368) # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999.9::bogus:666.6 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parserealarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999.9][0])", "999.9"), strcmp("$(test.ary[999.9][1])", "0"), strcmp("$(test.ary[999.9][2])", "0"), strcmp("$(test.ary[999.9][3])", "666.6"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999.9][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999.9][0] = '999.9', saw '$(test.ary[999.9][0])'"; "expected test.ary[999.9][1] = '0', saw '$(test.ary[999.9][1])'"; "expected test.ary[999.9][2] = '0', saw '$(test.ary[999.9][2])'"; "expected test.ary[999.9][3] = '666.6', saw '$(test.ary[999.9][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/accumulated2.cf0000644000000000000000000000171015010704253026705 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,1000,1000,1000,1000,40000); } ####################################################### bundle agent check { vars: "time" int => "2682100000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_real_comments_noemptyfields4.cf0000644000000000000000000001045115010704253040505 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, real comments, no empty fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)","^#.*",":+"1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","^#.*",":+",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", "in here"), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "this"), strcmp("$(test.ary[6][1])", "also"), strcmp("$(test.ary[7][0])", "last"), strcmp("$(test.ary[7][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = 'in here', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = 'this', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = 'also', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'last', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'one', saw '$(test.ary[7][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/getvalues_size2_with_expansion.cf0000644000000000000000000000324715010704253032575 0ustar00rootroot00000000000000####################################################### # # Test getvalues(), size 2 with variable expansion # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "one extra line" "the end$(const.dollar)fini"; "XXX dummy XXX"; "YYY $(init.dummy) YYY"; } ####################################################### bundle agent test { vars: "array[the fini$end]" string => "additional line again"; "array[the end$(const.dollar)fini]" string => "one$(const.n)extra line"; "array[XXX dummy XXX]" string => "XXX dummy XXX"; "array[YYY $(init.dummy) YYY]" string => "YYY $(init.dummy) YYY"; "vals" slist => getvalues("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } parsestringarray_introduce_duplicate_key.cf0000644000000000000000000000527615010704253034646 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), introduce a duplicate key # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test this:too 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; # 4 lines, but 3 unique keys } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), # The second value should overwrite the first strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "too"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[this][2]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'too', saw '$(test.ary[this][1])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readstringarray_weird_indices.cf0000644000000000000000000001206615010704253032433 0ustar00rootroot00000000000000####################################################### # # Test readstringarray(), add some weird indices (including a duplicate) # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[# A duplicate follows][0])", "# A duplicate follows"), strcmp("$(test.ary[# A duplicate follows][1])", "this line is not always a comment"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_change_comment_parsing2.cf0000644000000000000000000001160515010704253037405 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, change comment parsing # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)","",":"1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","",":",10,1000); "num" int => "9"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "# A duplicate follows"), strcmp("$(test.ary[6][1])", " this line is not always a comment"), strcmp("$(test.ary[7][0])", "this"), strcmp("$(test.ary[7][1])", "also"), strcmp("$(test.ary[8][0])", "last"), strcmp("$(test.ary[8][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = '# A duplicate follows', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ' this line is not always a comment', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'this', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'also', saw '$(test.ary[7][1])'"; "expected test.ary[8][0] = 'last', saw '$(test.ary[8][0])'"; "expected test.ary[8][1] = 'one', saw '$(test.ary[8][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readrealarray_non_integers.cf0000644000000000000000000000542315010704253031731 0ustar00rootroot00000000000000####################################################### # # Test readrealarray(), introduce non-integers (issue 313 and 368) # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999.9::bogus:666.6 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readrealarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999.9][0])", "999.9"), strcmp("$(test.ary[999.9][1])", "0"), strcmp("$(test.ary[999.9][2])", "0"), strcmp("$(test.ary[999.9][3])", "666.6"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999.9][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999.9][0] = '999.9', saw '$(test.ary[999.9][0])'"; "expected test.ary[999.9][1] = '0', saw '$(test.ary[999.9][1])'"; "expected test.ary[999.9][2] = '0', saw '$(test.ary[999.9][2])'"; "expected test.ary[999.9][3] = '666.6', saw '$(test.ary[999.9][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getvalues_size5_with_duplicate_triplicate.cf0000644000000000000000000000306415010704253034704 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test getvalues(), size 5 with a duplicate and a triplicate # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "zero" string => "zero"; "one" string => "one"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "zero"; "one"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "array[beta]" string => "$(zero)"; "array[gamma's]" string => "one"; "array[delta-delta:delta]" string => "$(one)"; "array[last]" string => "one"; "vals" slist => getvalues("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readintlist.cf0000644000000000000000000000300715010704253026657 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123, ,456,789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/parserealarray_duplicate_key.cf0000644000000000000000000000525015010704253032256 0ustar00rootroot00000000000000####################################################### # # Test parserealarray(), introduce 777 duplicate key # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999.9:888:777:666.6 999.9:000 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parserealarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; # 4 lines, but 3 unique keys } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), # The second value should overwrite the first strcmp("$(test.ary[999.9][0])", "999.9"), strcmp("$(test.ary[999.9][1])", "0"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999.9][2]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999.9][0] = '999.9', saw '$(test.ary[999.9][0])'"; "expected test.ary[999.9][1] = '0', saw '$(test.ary[999.9][1])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_real_comments.cf0000644000000000000000000001165315010704253035464 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, real comments # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","^#.*",":",10,1000); "num" int => "7"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][0])", "fields"), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[blank][0])", "in here"), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = 'fields', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = 'in here', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/parsestringarrayinx_simple.cf0000644000000000000000000000542415010704253032032 0ustar00rootroot00000000000000####################################################### # # Test parsestringarrayidx(), simple # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "this"), strcmp("$(test.ary[1][1])", "is"), strcmp("$(test.ary[1][2])", "a"), strcmp("$(test.ary[1][3])", "test"), strcmp("$(test.ary[2][0])", "1"), strcmp("$(test.ary[2][1])", "2"), strcmp("$(test.ary[2][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][4]"), isvariable("test.ary[2][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = 'this', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = 'is', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = 'a', saw '$(test.ary[1][2])'"; "expected test.ary[1][3] = 'test', saw '$(test.ary[1][3])'"; "expected test.ary[2][0] = '1', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = '2', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = '3', saw '$(test.ary[2][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readstringlist.cf0000644000000000000000000000301515010704253027372 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123, ,456,789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_with_duplicate.cf0000644000000000000000000001215715010704253035641 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), add some weird indices (including a duplicate) # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[# A duplicate follows][0])", "# A duplicate follows"), strcmp("$(test.ary[# A duplicate follows][1])", "this line is not always a comment"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readrealarray_duplicate_key.cf0000644000000000000000000000515715010704253032065 0ustar00rootroot00000000000000####################################################### # # Test readrealarray(), introduce 777 duplicate key # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999.9:888:777:666.6 999.9:000 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readrealarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; # 4 lines, but 3 unique keys } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), # The second value should overwrite the first strcmp("$(test.ary[999.9][0])", "999.9"), strcmp("$(test.ary[999.9][1])", "0"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999.9][2]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999.9][0] = '999.9', saw '$(test.ary[999.9][0])'"; "expected test.ary[999.9][1] = '0', saw '$(test.ary[999.9][1])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_change_separator_to_s.cf0000644000000000000000000000715415010704253034276 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), change separator to 's' # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","^#.*","s+",10,1000); "num" int => "7"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0:1:2][0])", "0:1:2"), strcmp("$(test.ary[1:2:3][0])", "1:2:3"), strcmp("$(test.ary[here i][0])", "here i"), strcmp("$(test.ary[here i][1])", ":a line: with space"), strcmp("$(test.ary[here i][2])", " : in it"), strcmp("$(test.ary[blank field][0])", "blank field"), strcmp("$(test.ary[blank field][2])", "::: in here::"), strcmp("$(test.ary[:leading blank field][0])", "leading blank field"), strcmp("$(test.ary[thi][0])", "thi"), strcmp("$(test.ary[thi][1])", ":also"), strcmp("$(test.ary[thi][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[thi][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[la][0])", "la"), strcmp("$(test.ary[la][1])", "t:one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0:1:2][0] = '0:1:2', saw '$(test.ary[0:1:2][0])'"; "expected test.ary[1:2:3][0] = '1:2:3', saw '$(test.ary[1:2:3][0])'"; "expected test.ary[here i][0] = 'here i', saw '$(test.ary[here i][0])'"; "expected test.ary[here i][1] = ':a line: with space', saw '$(test.ary[here i][1])'"; "expected test.ary[here i][2] = ' : in it', saw '$(test.ary[here i][2])'"; "expected test.ary[blank field][0] = 'blank field', saw '$(test.ary[blank field][0])'"; "expected test.ary[blank field][2] = '::: in here::', saw '$(test.ary[blank field][2])'"; "expected test.ary[:leading blank field][0] = 'leading blank field', saw '$(test.ary[:leading blank field][0])'"; "expected test.ary[thi][0] = 'thi', saw '$(test.ary[thi][0])'"; "expected test.ary[thi][1]) = ':also', saw '$(test.ary[thi][1]))'"; "expected test.ary[thi][2]) = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[thi][2]))'"; "expected test.ary[thi][3]) = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[thi][3]))'"; "expected test.ary[la][0]) = 'la', saw '$(test.ary[la][0]))'"; "expected test.ary[la][1]) = 't:one', saw '$(test.ary[la][1]))'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_real_comments3.cf0000644000000000000000000001111015010704253035533 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, real comments # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)","^#.*",":"1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","^#.*",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "this"), strcmp("$(test.ary[6][1])", "also"), strcmp("$(test.ary[7][0])", "last"), strcmp("$(test.ary[7][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = 'this', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = 'also', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'last', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'one', saw '$(test.ary[7][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readintarray_duplicate_key.cf0000644000000000000000000000512415010704253031726 0ustar00rootroot00000000000000####################################################### # # Test readintarray(), introduce 777 duplicate key # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999:888:777:666 999:000 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readintarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; # 4 lines, but 3 unique keys } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), # The second value should overwrite the first strcmp("$(test.ary[999][0])", "999"), strcmp("$(test.ary[999][1])", "0"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999][2]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999][0] = '999', saw '$(test.ary[999][0])'"; "expected test.ary[999][1] = '0', saw '$(test.ary[999][1])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/getindices_size5_namespaces.cf0000644000000000000000000000271415010704253031775 0ustar00rootroot00000000000000####################################################### # # Test getindices() across namespaces, size 5 # ####################################################### body common control { inputs => { "../../../default.cf.sub", "206-namespaced.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "alpha"; "beta"; "gamma's"; "delta-delta:delta"; "last"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "array[beta]" string => "two"; "array[gamma's]" string => "three's"; "array[delta-delta:delta]" string => "four-fore:quatre"; "array[last]" string => "last"; methods: "run" usebundle => testing_arrays:namespaced_test("$(G.testfile).actual", "default:test.array"); } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } readstringarrayidx_change_separator_to_s.cf0000644000000000000000000000720315010704253034577 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test readstringarrayidx(), change separator to 's' # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","^#.*","s+",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0:1:2"), strcmp("$(test.ary[1][0])", "1:2:3"), strcmp("$(test.ary[2][0])", "here i"), strcmp("$(test.ary[2][1])", ":a line: with "), strcmp("$(test.ary[2][2])", "pace"), strcmp("$(test.ary[2][3])", " : in it"), strcmp("$(test.ary[3][0])", "blank:field"), strcmp("$(test.ary[3][1])", ":::in here::"), strcmp("$(test.ary[4][0])", ":leading blank field"), strcmp("$(test.ary[5][0])", "thi"), strcmp("$(test.ary[5][1])", ":i"), strcmp("$(test.ary[5][2])", ":a:te"), strcmp("$(test.ary[5][3])", "t"), strcmp("$(test.ary[6][0])", "thi"), strcmp("$(test.ary[6][1])", ":al"), strcmp("$(test.ary[6][2])", "o"), strcmp("$(test.ary[7][0])", "la"), strcmp("$(test.ary[7][1])", "t:one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0:1:2', saw '$(test.ary[0][0])'"; "expected test.ary[1][0] = '1:2:3', saw '$(test.ary[1][0])'"; "expected test.ary[2][0] = 'here i', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = ':a line: with ', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = 'pace', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' : in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank:field', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = ':::in here::', saw '$(test.ary[3][1])'"; "expected test.ary[4][0] = ':leading blank field', saw '$(test.ary[4][0])'"; "expected test.ary[5][0] = 'thi', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = ':i', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = ':a:te', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 't', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = 'thi', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ':al', saw '$(test.ary[6][1])'"; "expected test.ary[6][2] = 'o', saw '$(test.ary[6][2])'"; "expected test.ary[7][0] = 'la', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 't:one', saw '$(test.ary[7][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_introduce_nonparsed_comment.cf0000644000000000000000000000643715010704253035537 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), introduce a non-parsed comment # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 # Not parsed as a comment this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "4"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "is"), strcmp("$(test.ary[this][2])", "a"), strcmp("$(test.ary[this][3])", "test"), strcmp("$(test.ary[# Not parsed as a comment][0])", "# Not parsed as a comment"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[# Not parsed as a comment][1]"), isvariable("test.ary[this][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[# Not parsed as a comment][0] = '# Not parsed as a comment', saw 'expected $(test.ary[# Not parsed as a comment][0])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/host2ip.cf0000644000000000000000000000324615010704253025732 0ustar00rootroot00000000000000####################################################### # # Test host2ip() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: # Neither of these are likely to change... "localhost" string => ip2host("127.0.0.1"); "localhost_6" string => ip2host("::1"); "a" string => ip2host("198.41.0.4"); "a_6" string => ip2host("2001:503:ba3e::2:30"); } ####################################################### bundle agent check { vars: "localhost" string => "localhost"; "a" string => "a.root-servers.net"; classes: "ok_a" and => { strcmp("$(test.a)", "$(a)"), strcmp("$(test.a_6)", "$(a)"), }; "ok_localhost" and => { strcmp("$(test.localhost)", "$(localhost)"), strcmp("$(test.localhost_6)", "$(localhost)"), }; "ok" and => { "ok_a", "ok_localhost", }; reports: DEBUG:: "Expected ($(test.localhost) and $(test.localhost_6)) == $(localhost)"; "Expected ($(test.a) and $(test.a_6)) == $(a)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ####################################################### bundle agent fini { vars: "dummy" string => "dummy"; } parsestringarray_weird_indices_duplicates_trailing_newlines.cf0000644000000000000000000001216715010704253040567 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, duplicate and trailing newlines # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one "; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)", strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[# A duplicate follows][0])", "# A duplicate follows"), strcmp("$(test.ary[# A duplicate follows][1])", "this line is not always a comment"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarrayidx_weird_indices_duplicate.cf0000644000000000000000000001162415010704253035311 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarrayidx(), add some weird indices (including a duplicate) # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "9"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "# A duplicate follows"), strcmp("$(test.ary[6][1])", " this line is not always a comment"), strcmp("$(test.ary[7][0])", "this"), strcmp("$(test.ary[7][1])", "also"), strcmp("$(test.ary[8][0])", "last"), strcmp("$(test.ary[8][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = '# A duplicate follows', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ' this line is not always a comment', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'this', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'also', saw '$(test.ary[7][1])'"; "expected test.ary[8][0] = 'last', saw '$(test.ary[8][0])'"; "expected test.ary[8][1] = 'one', saw '$(test.ary[8][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_real_comments_noemptyfields.cf0000644000000000000000000001076515010704253040431 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, real comments, no empty fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(teststr)","^#.*",":+",10,1000); "num" int => "7"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", "in here"), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = 'in here', saw '$(test.ary[blank][2])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/parsestringarrayidx_duplicate_key.cf0000644000000000000000000000606415010704253033352 0ustar00rootroot00000000000000####################################################### # # Test parsestringarrayidx(), introduce a duplicate key # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test this:too 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "4"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "this"), strcmp("$(test.ary[1][1])", "is"), strcmp("$(test.ary[1][2])", "a"), strcmp("$(test.ary[1][3])", "test"), strcmp("$(test.ary[2][0])", "this"), strcmp("$(test.ary[2][1])", "too"), strcmp("$(test.ary[3][0])", "1"), strcmp("$(test.ary[3][1])", "2"), strcmp("$(test.ary[3][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][4]"), isvariable("test.ary[2][2]"), isvariable("test.ary[3][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = 'this', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = 'is', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = 'a', saw '$(test.ary[1][2])'"; "expected test.ary[1][3] = 'test', saw '$(test.ary[1][3])'"; "expected test.ary[2][0] = 'this', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'too', saw '$(test.ary[2][1])'"; "expected test.ary[3][0] = '1', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = '2', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '3', saw '$(test.ary[3][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_dontread_comment_duplicate_lastline.cf0000644000000000000000000001113215010704253037203 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), don't read comment, duplicate key or last line # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parsestringarray("ary", "$(testfile)","NoComment",":",6,1000); "num" int => "6"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "is"), strcmp("$(test.ary[this][2])", "a"), strcmp("$(test.ary[this][3])", "test"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readstringarray_introduce_duplicate.cf0000644000000000000000000000520515010704253033646 0ustar00rootroot00000000000000####################################################### # # Test readstringarray(), introduce a duplicate key # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 this:is:a:test this:too 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; # 4 lines, but 3 unique keys } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), # The second value should overwrite the first strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "too"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[this][2]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'too', saw '$(test.ary[this][1])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readreallist2.cf0000644000000000000000000000302215010704253027067 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123,broken,456,789"; # non-numeric fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/getvalues_size5.cf0000644000000000000000000000307315010704253027456 0ustar00rootroot00000000000000####################################################### # # Test getvalues(), size 5 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "zero"; "one"; "three's"; "four-fore:quatre"; "last"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "array[beta]" string => "two"; "array[gamma's]" string => "three's"; "array[delta-delta:delta]" string => "four-fore:quatre"; "array[last]" string => "last"; "vals" slist => getvalues("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/functions_and_nulls.cf0000644000000000000000000000426415010704253030412 0ustar00rootroot00000000000000####################################################### # # Test hash() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: # The nulls terminate the string here "test1" string => execresult("$(G.perl) -e 'print \"Test of \0\1\2\n nulls in a string\";'", "noshell"); # Write the same string to a file and read it in again, they are converted "test2" string => execresult("$(G.perl) -e 'print \"Test of \0\1\2\n nulls in a string\";' > $(G.testfile)", "useshell"); "test3" string => readfile("$(G.testfile)","100"); # They are converted here, too, so the split fails "test4a" slist => readstringlist("$(G.testfile)","#no comments", "\0", "2", "100"); # And simply quoting the backslash doesn't work, because I think the # regex is also converted "test4b" slist => readstringlist("$(G.testfile)","#no comments", "\\0", "2", "100"); # So this doubly incorrect split succeeds because of the two conversions "test4c" slist => readstringlist("$(G.testfile)","#no comments", "\\\0", "2", "100"); # readstringarray() (or perhaps getindices) simply breaks "i" int => readstringarray("test5", "$(G.testfile)","#no comments", "no split", "2", "100"); "test5_idx" slist => getindices("test5"); # readstringarrayidx() converts the results (same split issues as test4) "j" int => readstringarrayidx("test6", "$(G.testfile)","#no comments", "no split", "2", "100"); "test6_idx" slist => getindices("test6"); # This shows that the nulls are really there in the file "od_file" string => execresult("$(G.od) -c $(G.testfile)", "noshell"); reports: cfengine_3:: "test1: $(test1)"; "test2: $(test2) (<== we expect nothing here)"; "test3: $(test3)"; "test4a: $(test4a)"; "test4b: $(test4b)"; "test4c: $(test4c)"; "test5, $(i) entries: $(test5[$(test5_idx)])"; "test5_idx: $(test5_idx)"; "test6, $(j) entries: $(test6[$(test6_idx)][0])"; "od_file: $(od_file)"; } bundlesmatching_dynamicbundlesequence.cf0000644000000000000000000000151215010704253034053 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging# Test that bundlesmatching works correctly for dynamic sequences body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)"), @(init.runs) }; } bundle common init { vars: "runs" slist => bundlesmatching("default:run.*"); } bundle agent test { } bundle agent check { classes: "ok" and => { ok1, ok2, ok3 }; reports: DEBUG:: "Found bundles $(test.runs)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } bundle agent run_123_456 { classes: "ok1" expression => "any", scope => "namespace"; } bundle agent run_789_0ab { classes: "ok2" expression => "any", scope => "namespace"; } bundle agent run_cde_fgh { classes: "ok3" expression => "any", scope => "namespace"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readreallist.cf0000644000000000000000000000301115010704253027003 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123, ,456,789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readintarray_non_integers.cf0000644000000000000000000000521515010704253031577 0ustar00rootroot00000000000000####################################################### # # Test parseintarray(), introduce 777 duplicate key # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999:888:777:666 999:000 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parseintarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; # 4 lines, but 3 unique keys } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), # The second value should overwrite the first strcmp("$(test.ary[999][0])", "999"), strcmp("$(test.ary[999][1])", "0"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999][2]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999][0] = '999', saw '$(test.ary[999][0])'"; "expected test.ary[999][1] = '0', saw '$(test.ary[999][1])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/accumulated.cf0000644000000000000000000000167215010704253026632 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(315,0,0,0,0,0); } ####################################################### bundle agent check { vars: "time" int => "9933840000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readstringlist2.cf0000644000000000000000000000302615010704253027456 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123,broken,456,789"; # non-numeric fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment",",",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/getvalues_size2.cf0000644000000000000000000000256115010704253027454 0ustar00rootroot00000000000000####################################################### # # Test getvalues(), size 2 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "zero"; "one"; } ####################################################### bundle agent test { vars: "array[alpha]" string => "zero"; "array[beta]" string => "two"; "vals" slist => getvalues("array"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; reports: DEBUG:: "Inserting line: $(vals)"; } bundle edit_line test_insert { vars: "vals" slist => { @{test.vals} }; insert_lines: "$(vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } ####################################################### bundle agent fini { methods: "any" usebundle => dcs_fini("$(G.testfile).*"); } parsestringarrayidx_change_separator_to_s.cf0000644000000000000000000000730015010704253034774 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarrayidx(), change separator to 's' # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)","^#.*",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","^#.*","s+",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0:1:2"), strcmp("$(test.ary[1][0])", "1:2:3"), strcmp("$(test.ary[2][0])", "here i"), strcmp("$(test.ary[2][1])", ":a line: with "), strcmp("$(test.ary[2][2])", "pace"), strcmp("$(test.ary[2][3])", " : in it"), strcmp("$(test.ary[3][0])", "blank:field"), strcmp("$(test.ary[3][1])", ":::in here::"), strcmp("$(test.ary[4][0])", ":leading blank field"), strcmp("$(test.ary[5][0])", "thi"), strcmp("$(test.ary[5][1])", ":i"), strcmp("$(test.ary[5][2])", ":a:te"), strcmp("$(test.ary[5][3])", "t"), strcmp("$(test.ary[6][0])", "thi"), strcmp("$(test.ary[6][1])", ":al"), strcmp("$(test.ary[6][2])", "o"), strcmp("$(test.ary[7][0])", "la"), strcmp("$(test.ary[7][1])", "t:one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0:1:2', saw '$(test.ary[0][0])'"; "expected test.ary[1][0] = '1:2:3', saw '$(test.ary[1][0])'"; "expected test.ary[2][0] = 'here i', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = ':a line: with ', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = 'pace', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' : in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank:field', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = ':::in here::', saw '$(test.ary[3][1])'"; "expected test.ary[4][0] = ':leading blank field', saw '$(test.ary[4][0])'"; "expected test.ary[5][0] = 'thi', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = ':i', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = ':a:te', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 't', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = 'thi', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = ':al', saw '$(test.ary[6][1])'"; "expected test.ary[6][2] = 'o', saw '$(test.ary[6][2])'"; "expected test.ary[7][0] = 'la', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 't:one', saw '$(test.ary[7][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarrayidx_nonparsed_comment.cf0000644000000000000000000000612115010704253034156 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarrayidx(), introduce a non-parsed comment # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "g", default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "testfile" string => "/tmp/TEST.cfengine"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 # Not parsed as a comment this:is:a:test 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "4"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "# Not parsed as a comment"), strcmp("$(test.ary[2][0])", "this"), strcmp("$(test.ary[2][1])", "is"), strcmp("$(test.ary[2][2])", "a"), strcmp("$(test.ary[2][3])", "test"), strcmp("$(test.ary[3][0])", "1"), strcmp("$(test.ary[3][1])", "2"), strcmp("$(test.ary[3][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][1]"), isvariable("test.ary[2][4]"), isvariable("test.ary[3][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'is', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = 'a', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = 'test', saw '$(test.ary[this][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging/readintarray_non_integers2.cf0000644000000000000000000000535215010704253031663 0ustar00rootroot00000000000000####################################################### # # Test readintarray(), introduce non-integers (issue 313 and 368) # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999::bogus:666 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readintarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999][0])", "999"), strcmp("$(test.ary[999][1])", "0"), strcmp("$(test.ary[999][2])", "0"), strcmp("$(test.ary[999][3])", "666"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999][0] = '999', saw '$(test.ary[999][0])'"; "expected test.ary[999][1] = '0', saw '$(test.ary[999][1])'"; "expected test.ary[999][2] = '0', saw '$(test.ary[999][2])'"; "expected test.ary[999][3] = '999', saw '$(test.ary[999][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readstringarray_change_separator_to_s.cf0000644000000000000000000000706315010704253034076 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test readstringarray(), change separator to 's' # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","^#.*","s+",10,1000); "num" int => "7"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0:1:2][0])", "0:1:2"), strcmp("$(test.ary[1:2:3][0])", "1:2:3"), strcmp("$(test.ary[here i][0])", "here i"), strcmp("$(test.ary[here i][1])", ":a line: with space"), strcmp("$(test.ary[here i][2])", " : in it"), strcmp("$(test.ary[blank field][0])", "blank field"), strcmp("$(test.ary[blank field][2])", "::: in here::"), strcmp("$(test.ary[:leading blank field][0])", "leading blank field"), strcmp("$(test.ary[thi][0])", "thi"), strcmp("$(test.ary[thi][1])", ":also"), strcmp("$(test.ary[thi][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[thi][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[la][0])", "la"), strcmp("$(test.ary[la][1])", "t:one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0:1:2][0] = '0:1:2', saw '$(test.ary[0:1:2][0])'"; "expected test.ary[1:2:3][0] = '1:2:3', saw '$(test.ary[1:2:3][0])'"; "expected test.ary[here i][0] = 'here i', saw '$(test.ary[here i][0])'"; "expected test.ary[here i][1] = ':a line: with space', saw '$(test.ary[here i][1])'"; "expected test.ary[here i][2] = ' : in it', saw '$(test.ary[here i][2])'"; "expected test.ary[blank field][0] = 'blank field', saw '$(test.ary[blank field][0])'"; "expected test.ary[blank field][2] = '::: in here::', saw '$(test.ary[blank field][2])'"; "expected test.ary[:leading blank field][0] = 'leading blank field', saw '$(test.ary[:leading blank field][0])'"; "expected test.ary[thi][0] = 'thi', saw '$(test.ary[thi][0])'"; "expected test.ary[thi][1]) = ':also', saw '$(test.ary[thi][1]))'"; "expected test.ary[thi][2]) = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[thi][2]))'"; "expected test.ary[thi][3]) = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[thi][3]))'"; "expected test.ary[la][0]) = 'la', saw '$(test.ary[la][0]))'"; "expected test.ary[la][1]) = 't:one', saw '$(test.ary[la][1]))'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readstringarray_weird_indices_real_comments.cf0000644000000000000000000001156215010704253035264 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test readstringarray(), weird indices, real comments # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","^#.*",":",10,1000); "num" int => "7"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][0])", "fields"), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[blank][0])", "in here"), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[blank][0])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = 'fields', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = 'in here', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][0] = '', saw '$(test.ary[blank][0])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarrayinx_singleton_nootherfields.cf0000644000000000000000000000476715010704253035422 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarrayidx(), introduce a singleton with no other fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 singleton 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "singleton"), strcmp("$(test.ary[2][0])", "1"), strcmp("$(test.ary[2][1])", "2"), strcmp("$(test.ary[2][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[1][1]"), isvariable("test.ary[2][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = 'singleton', saw '$(test.ary[1][0])'"; "expected test.ary[2][0] = '1', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = '2', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = '3', saw '$(test.ary[2][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_weird_indices_real_comments2.cf0000644000000000000000000001101115010704253035532 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), weird indices, real comments # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","^#.*",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), strcmp("$(test.ary[6][0])", "this"), strcmp("$(test.ary[6][1])", "also"), strcmp("$(test.ary[7][0])", "last"), strcmp("$(test.ary[7][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; "expected test.ary[6][0] = 'this', saw '$(test.ary[6][0])'"; "expected test.ary[6][1] = 'also', saw '$(test.ary[6][1])'"; "expected test.ary[7][0] = 'last', saw '$(test.ary[7][0])'"; "expected test.ary[7][1] = 'one', saw '$(test.ary[7][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } readstringarray_weird_indices_change_comment_parsing.cf0000644000000000000000000001204415010704253037122 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test readstringarray(), weird indices, change comment parsing # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarray("ary", "$(G.testfile)","",":",10,1000); "num" int => "8"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "ok" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[here is][0])", "here is"), strcmp("$(test.ary[here is][1])", "a line"), strcmp("$(test.ary[here is][2])", " with spaces "), strcmp("$(test.ary[here is][3])", " in it"), strcmp("$(test.ary[blank][0])", "blank"), strcmp("$(test.ary[blank][1])", "fields"), strcmp("$(test.ary[blank][2])", ""), strcmp("$(test.ary[blank][3])", ""), strcmp("$(test.ary[blank][4])", "in here"), strcmp("$(test.ary[blank][5])", ""), strcmp("$(test.ary[blank][6])", ""), strcmp("$(test.ary[][0])", ""), strcmp("$(test.ary[][1])", "leading blank field"), strcmp("$(test.ary[# A duplicate follows][0])", "# A duplicate follows"), strcmp("$(test.ary[# A duplicate follows][1])", "this line is not always a comment"), strcmp("$(test.ary[this][0])", "this"), strcmp("$(test.ary[this][1])", "also"), strcmp("$(test.ary[this][2])", "$(const.dollar)test.ary[this][2]"), strcmp("$(test.ary[this][3])", "$(const.dollar)test.ary[this][3]"), strcmp("$(test.ary[last][0])", "last"), strcmp("$(test.ary[last][1])", "one"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[here is][0] = 'here is', saw '$(test.ary[here is][0])'"; "expected test.ary[here is][1] = 'a line', saw '$(test.ary[here is][1])'"; "expected test.ary[here is][2] = ' with spaces ', saw '$(test.ary[here is][2])'"; "expected test.ary[here is][3] = ' in it', saw '$(test.ary[here is][3])'"; "expected test.ary[blank][0] = 'blank', saw '$(test.ary[blank][0])'"; "expected test.ary[blank][1] = 'fields', saw '$(test.ary[blank][1])'"; "expected test.ary[blank][2] = '', saw '$(test.ary[blank][2])'"; "expected test.ary[blank][3] = '', saw '$(test.ary[blank][3])'"; "expected test.ary[blank][4] = 'in here', saw '$(test.ary[blank][4])'"; "expected test.ary[blank][5] = '', saw '$(test.ary[blank][5])'"; "expected test.ary[blank][6] = '', saw '$(test.ary[blank][6])'"; "expected test.ary[][0] = '', saw '$(test.ary[][0])'"; "expected test.ary[][1] = 'leading blank field', saw '$(test.ary[][1])'"; "expected test.ary[# A duplicate follows][0] = '# A duplicate follows', saw '$(test.ary[# A duplicate follows][0])'"; "expected test.ary[# A duplicate follows][1] = 'this line is not always a comment', saw '$(test.ary[# A duplicate follows][1])'"; "expected test.ary[this][0] = 'this', saw '$(test.ary[this][0])'"; "expected test.ary[this][1] = 'also', saw '$(test.ary[this][1])'"; "expected test.ary[this][2] = '$(const.dollar)test.ary[this][2]', saw '$(test.ary[this][2])'"; "expected test.ary[this][3] = '$(const.dollar)test.ary[this][3]', saw '$(test.ary[this][3])'"; "expected test.ary[last][0] = 'last', saw '$(test.ary[last][0])'"; "expected test.ary[last][1] = 'one', saw '$(test.ary[last][1])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } parsestringarray_dontread_comment_duplicate_lastline3.cf0000644000000000000000000001064115010704253037272 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions/staging####################################################### # # Test parsestringarray(), don't read comment, duplicate key or last line # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" str => readfile("$(G.testfile)",1000); "cnt" int => parsestringarrayidx("ary", "$(teststr)","NoComment",":",6,1000); "num" int => "6"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "bad" or => { isvariable("test.ary[6][0]"), isvariable("test.ary[6][1]"), isvariable("test.ary[7][0]"), isvariable("test.ary[7][1]"), isvariable("test.ary[8][0]"), isvariable("test.ary[8][1]"), }; "ok" and => { "!bad", strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "here is"), strcmp("$(test.ary[2][1])", "a line"), strcmp("$(test.ary[2][2])", " with spaces "), strcmp("$(test.ary[2][3])", " in it"), strcmp("$(test.ary[3][0])", "blank"), strcmp("$(test.ary[3][1])", "fields"), strcmp("$(test.ary[3][2])", ""), strcmp("$(test.ary[3][3])", ""), strcmp("$(test.ary[3][4])", "in here"), strcmp("$(test.ary[3][5])", ""), strcmp("$(test.ary[3][6])", ""), strcmp("$(test.ary[4][0])", ""), strcmp("$(test.ary[4][1])", "leading blank field"), strcmp("$(test.ary[5][0])", "this"), strcmp("$(test.ary[5][1])", "is"), strcmp("$(test.ary[5][2])", "a"), strcmp("$(test.ary[5][3])", "test"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'here is', saw '$(test.ary[2][0])'"; "expected test.ary[2][1] = 'a line', saw '$(test.ary[2][1])'"; "expected test.ary[2][2] = ' with spaces ', saw '$(test.ary[2][2])'"; "expected test.ary[2][3] = ' in it', saw '$(test.ary[2][3])'"; "expected test.ary[3][0] = 'blank', saw '$(test.ary[3][0])'"; "expected test.ary[3][1] = 'fields', saw '$(test.ary[3][1])'"; "expected test.ary[3][2] = '', saw '$(test.ary[3][2])'"; "expected test.ary[3][3] = '', saw '$(test.ary[3][3])'"; "expected test.ary[3][4] = 'in here', saw '$(test.ary[3][4])'"; "expected test.ary[3][5] = '', saw '$(test.ary[3][5])'"; "expected test.ary[3][6] = '', saw '$(test.ary[3][6])'"; "expected test.ary[4][0] = '', saw '$(test.ary[4][0])'"; "expected test.ary[4][1] = 'leading blank field', saw '$(test.ary[4][1])'"; "expected test.ary[5][0] = 'this', saw '$(test.ary[5][0])'"; "expected test.ary[5][1] = 'is', saw '$(test.ary[5][1])'"; "expected test.ary[5][2] = 'a', saw '$(test.ary[5][2])'"; "expected test.ary[5][3] = 'test', saw '$(test.ary[5][3])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/621.cf0000644000000000000000000000472315010704253023217 0ustar00rootroot00000000000000####################################################### # # Test parserealarray(), introduce 777 12345 with no other fields # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 12345 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parserealarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[12345][0])", "12345"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[12345][1]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[12345][0] = '12345', saw '$(test.ary[12345][0])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/wrap_invalid_container_fncalls.x.cf0000644000000000000000000000125315010704253031373 0ustar00rootroot00000000000000####################################################### # # Test wrapped fncalls with mismatched data types # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { vars: "base_list" slist => { "a", "b", "c", "aaa", "bbb", "ccc" }; # this should be a function call failure "canonify" string => canonify(reverse(base_list)); } ####################################################### bundle agent check { methods: "check" usebundle => dcs_pass($(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/cf_version.cf0000644000000000000000000000362015010704253025037 0ustar00rootroot00000000000000########################################################### # # Test cf_version convenience functions # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { vars: "after_newer" string => "yes", if => cf_version_after("1.0.0"); "after_newer_major" string => "yes", if => cf_version_after("3.12"); "after_older" string => "no", if => cf_version_after("999.999.999"); "at_same" string => "yes", if => cf_version_at("$(sys.cf_version)"); "at_major" string => "yes", if => cf_version_at("3"); "at_not_same" string => "no", if => cf_version_at("999.999.999"); "before_newer" string => "no", if => cf_version_before("1.0.0"); "before_older" string => "yes", if => cf_version_before("999.999.999"); "before_older_major" string => "yes", if => cf_version_before("999"); "between" string => "yes", if => cf_version_between("1.0", "999.999"); "not_between" string => "no", if => cf_version_between("999", "999"); "also_not_between" string => "no", if => cf_version_between("1", "1"); "max_newer" string => "no", if => cf_version_maximum("1.0.0"); "max_older" string => "yes", if => cf_version_maximum("999.999.999"); "min_newer" string => "yes", if => cf_version_minimum("1.0.0"); "min_older" string => "no", if => cf_version_minimum("999.999.999"); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/filestat_xattr.cf0000644000000000000000000000226715010704253025745 0ustar00rootroot00000000000000####################################################### # # Redmine#4079: Test filestat() with xattr # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common xattr_support { vars: "xattr" string => "/usr/bin/xattr"; classes: "has_xattr" and => { fileexists($(xattr)) }; } ####################################################### bundle agent init { meta: "test_skip_unsupported" string => "!has_xattr"; methods: "" usebundle => file_make($(G.testfile), ""); } ####################################################### bundle agent test { commands: "$(init.xattr) -w foo bar $(G.testfile)"; } ####################################################### bundle agent check { vars: "attributes" string => filestat($(G.testfile), "xattr"); methods: "" usebundle => dcs_check_strcmp($(attributes), "foo=bar", $(this.promise_filename), "no"); } countlinesmatching_returns_0_on_inaccessable_file.cf0000644000000000000000000000225215010704253034711 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test countlinesmatching() with some kind of failure expected # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "description" -> { "Mantis 320", "CFE-3234" } string => "Test that countlinesmatching() returns 0 when the file is inaccessible."; vars: "zero_regex" string => "impossible line"; "fail" int => countlinesmatching("$(zero_regex)", "/asd/fgh/qwertyio0p"); } ####################################################### bundle agent check { classes: "ok" and => { strcmp("$(test.fail)", "0"), }; reports: DEBUG:: "Expected 0 matches to '$(test.zero_regex)', found $(test.fail)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/313.cf0000644000000000000000000000200415010704253023203 0ustar00rootroot00000000000000####################################################### # # Test escape() - strings that end with \, issue 690 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common g { vars: "dummy" string => "dummy"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "t1" string => escape("\\"); "e1" string => "\\"; } ####################################################### bundle agent check { classes: "ok" and => { regcmp("$(test.t1)", "$(test.e1)"), }; reports: DEBUG:: "Comparing actual vs. expected:"; "'$(test.t1)' vs. '$(test.e1)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/strftime.cf0000644000000000000000000000346415010704253024545 0ustar00rootroot00000000000000####################################################### # # Test strftime() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: # we don't use locale-sensitive formats! "results" slist => { "1973-03-03 09:46:40", "124 1 18 200000000", $(dow) }; Monday:: "dow" string => "1"; Tuesday:: "dow" string => "2"; Wednesday:: "dow" string => "3"; Thursday:: "dow" string => "4"; Friday:: "dow" string => "5"; Saturday:: "dow" string => "6"; Sunday:: "dow" string => "0"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert; } bundle edit_line init_insert { insert_lines: "$(init.results)"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10253" }; vars: "vals" slist => { strftime('gmtime', '%F %T', 100000000), strftime('localtime', '%j %w %W %s', 200000000), strftime('localtime', '%w', now()), }; files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.vals)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_plain_slist.cf0000644000000000000000000000174715010704253027312 0ustar00rootroot00000000000000####################################################### # # Test getvalues() # ####################################################### # If we run getvalues on a plan slist, we should end up with a copy of that # list. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "slist" slist => { "scrumdiddlyumptious" }; "values" slist => getvalues("slist"); } ####################################################### bundle agent check { vars: "expected" slist => { "scrumdiddlyumptious" }; "diff" slist => difference( expected, "test.values" ); classes: "_pass" expression => strcmp( length( diff ), 0 ); methods: _pass:: "pass" usebundle => dcs_pass("$(this.promise_filename)"); !_pass:: "pass" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/521.cf0000644000000000000000000000472015010704253023213 0ustar00rootroot00000000000000####################################################### # # Test parseintarray(), introduce 777 12345 with no other fields # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readintarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 12345 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "teststr" string => readfile("$(G.testfile)",1000); "cnt" int => parseintarray("ary", "$(teststr)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[12345][0])", "12345"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[12345][1]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[12345][0] = '12345', saw '$(test.ary[12345][0])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } getvalues_returns_all_values_for_given_datacontainer_index_merging_strings.cf.expected.json0000644000000000000000000000031115010704253044757 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions{ "values_data": [ "alpha", "bravo", "zulu" ], "values_data2": [ "bravo", "something else", "1233333" ], "values_data3": [ "foo", "bravo", "barista" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata_multilevel_array.cf0000644000000000000000000000155015010704253030273 0ustar00rootroot00000000000000# Test that merging a multi level classic array works # Ref: https://dev.cfengine.com/issues/4566 body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent check { vars: "a[0][class]" string => "any"; "a[0][command]" string => "/bin/true"; "a[1][class]" string => "linux"; "a[1][command]" string => "/bin/false"; "m" data => mergedata( a ); "i" slist => getindices( m ); classes: "PASS" expression => strcmp( "any", "$(m[0][class])" ); reports: PASS:: "$(this.promise_filename) Pass"; !PASS:: "$(this.promise_filename) FAIL"; DEBUG:: "i => [$(i)]"; "class => $(m[$(i)][class])"; "command => $(m[$(i)][command])"; "version => $(sys.cf_version)"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/061.x.cf0000644000000000000000000000171015010704253023454 0ustar00rootroot00000000000000####################################################### # # Test accumulated() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "time" int => accumulated(0,1000,1000,1001,1000,40000); } ####################################################### bundle agent check { vars: "time" int => "2682100000"; # 1 year == 365 days classes: "ok" expression => strcmp("$(time)", "$(test.time)"); reports: DEBUG:: "time: $(time)"; "test.time: $(test.time)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } variable_references_from_function_that_never_succeeds.cf.sub0000644000000000000000000000112215010704253036421 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Subtest that FnFailure results in unresolved references # ####################################################### body common control { bundlesequence => { test }; } bundle agent test { vars: "unresolved_76201d0eaac49a884308358aa487147b4db70e8a" slist => { canonify($(missing)) }; "resolved_a557d39e04d666075754b8f78ea17fbc175925d5" slist => { "a", "b" }; reports: "MARKER$(unresolved_76201d0eaac49a884308358aa487147b4db70e8a)MARKER MARKER$(resolved_a557d39e04d666075754b8f78ea17fbc175925d5)MARKER"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/037.cf0000644000000000000000000000253515010704253023217 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok" and => { "ok_list", islessthan("$(test.sum)", "123.1"), isgreaterthan("$(test.sum)", "122.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/028.cf0000644000000000000000000000246215010704253023216 0ustar00rootroot00000000000000####################################################### # # Test readintlist() with reals # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok1" not => strcmp("123.456", "$(nums)"); "ok2" not => strcmp("123", "$(nums)"); "ok" and => { "ok_list", "ok1", "ok2" }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string_trim.cf.expected.json0000644000000000000000000000032715010704253030014 0ustar00rootroot00000000000000{ "abcd1": "abcd", "abcd2": "abcd", "abcd3": "abcd", "abcd4": "abcd", "abcd5": "abcd", "abcd6": "abcd", "abcd7": "abcd", "abcd_abcd": "abcd abcd", "empty1": "", "empty2": "", "empty3": "" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/027.cf0000644000000000000000000000264615010704253023221 0ustar00rootroot00000000000000####################################################### # # Test readintlist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" ilist => readintlist("$(G.testfile)","NoComment","\.",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" ilist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/readdata.cf0000644000000000000000000000337415010704253024455 0ustar00rootroot00000000000000########################################################### # # Test readdata() with YAML # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10252" }; vars: "explicit_csv" data => readdata("$(this.promise_filename).csv", "CSV"); "explicit_env" data => readdata("$(this.promise_filename).env", "ENV"); "explicit_json" data => readdata("$(this.promise_filename).json", "JSON"); "extension_csv" data => readdata("$(this.promise_filename).csv", "auto"); "extension_env" data => readdata("$(this.promise_filename).env", "auto"); "extension_json" data => readdata("$(this.promise_filename).json", "auto"); "guess_csv" data => readdata("$(this.promise_filename).csv.guess", "auto"); # should be empty (JSON is attempted) "guess_json" data => readdata("$(this.promise_filename).json.guess", "auto"); "failed_explicit_csv" data => readdata($(this.promise_filename), "CSV"); "failed_explicit_env" data => readdata("$(this.promise_filename).csv", "ENV"); "failed_explicit_json" data => readdata($(this.promise_filename), "JSON"); "failed_guess" data => readdata($(this.promise_filename), "auto"); } ########################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/450.cf0000644000000000000000000000500615010704253023212 0ustar00rootroot00000000000000####################################################### # # Test readstringarrayidx(), add some weird indices, real comments, no empty fields # # The 4xx tests are all related, and 400-419 are the readstringarray tests, # 420-439 the same for readstringarrayidx, 440-459 parsestringarray, and # 460-479 parsestringarrayidx # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 1:2:3 here is:a line: with spaces : in it blank:fields:::in here:: :leading blank field this:is:a:test # A duplicate follows: this line is not always a comment this:also last:one"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readstringarrayidx("ary", "$(G.testfile)","^#.*",":+",10,14); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "bad" or => { isvariable("test.ary[2][1]"), isvariable("test.ary[3][0]"), }; "ok" and => { "!bad", strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), strcmp("$(test.ary[2][0])", "he"), }; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "saw 'bad'-class things"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; "expected test.ary[2][0] = 'he', saw '$(test.ary[2][0])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/text_xform.cf.tail26.txt0000644000000000000000000000003315010704253027012 0ustar00rootroot00000000000000UVWXYZ0123456789abcdefghij cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mustache_iterating_object_workaround.cf0000644000000000000000000000326615010704253032370 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "template" string => "# Test1 {{#testcase.test1}} {{#data}} Data = {{.}} {{/data}} {{/testcase.test1}} # Test2 {{#testcase.test2.data}} Data = {{.}} {{/testcase.test2.data}} {{#testcase.test2.otherdata}} Other data = {{.}} {{/testcase.test2.otherdata}}"; "data" data => '{ "testcase": { "test1": { "data": [ "v1", "v2" ] }, "test2": { "data": [ "v1", "v2" ], "otherdata": [ "v3", "v4" ] } } }'; } bundle agent test { meta: # The issue we see in cfengine is that if a {{#testcase.test2}} section is # used the corresponding JSON object is iterated over and the rendering # happens for each sub structure (property) iterated duplicating the # data. The workaround is to not use a separate section corresponding to # the testcase.test2 JSON object with multiple properties. "description" -> { "CFE-2125" } string => "Test a workaround for iterating over object to get a single block with correct context (CFE-2125)."; vars: "got" string => string_mustache( $(init.template), @(init.data) ); } bundle agent check { reports: DEBUG:: "got output: $(test.got)"; vars: "expected" string => "# Test1 Data = v1 Data = v2 # Test2 Data = v1 Data = v2 Other data = v3 Other data = v4 "; methods: "check" usebundle => dcs_check_strcmp( $(test.got), $(check.expected), $(this.promise_filename), "no" ); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/069.cf0000644000000000000000000000302015010704253023212 0ustar00rootroot00000000000000####################################################### # # Test getusers() arg0 and arg1, but expect a failure # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: # All users except r.*t [illegal!], bin, and daemon "users" slist => getusers("r.*t,bin","1,5,6,7"); files: "$(G.testfile)" delete => init_delete; reports: cfengine_3:: "$(users)" report_to_file => "$(G.testfile)"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { meta: "test_skip_unsupported" string => "windows"; files: # Try to delete the lines that shouldn't be there anyway "$(G.testfile)" edit_line => test_delete, classes => full_set; } bundle edit_line test_delete { delete_lines: "root"; "daemon"; "bin"; } body classes full_set { promise_kept => { "fail" }; promise_repaired => { "pass" }; repair_failed => { "fail" }; repair_denied => { "fail" }; repair_timeout => { "fail" }; } ####################################################### bundle agent check { classes: "ok" expression => "pass&!fail"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } filesexist-can-detect-files-containing-hash-character.cf0000644000000000000000000000303315010704253035107 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functions####################################################### # # Test that filesexist() can check for presence of files containing hashes # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "test_files" slist => { "example##4567", "example##123" }; files: "$(G.testdir)/$(test_files)" create => "true"; } ####################################################### bundle agent test { meta: "description" -> { "CFE-2744" } string => "Test that filesexist can verify files containing hashes exist"; vars: "found_files" slist => findfiles( "$(G.testdir)/example##*"); classes: # This should always be true. # We check that the files that we found exist. "found_expected_files_with_filesexist" expression => filesexist( "@(found_files)" ), scope => "namespace"; } ####################################################### bundle agent check { classes: "ok" expression => "found_expected_files_with_filesexist"; reports: DEBUG|EXTRA:: "Test files: $(init.test_files)"; "Found files: $(test.found_files)"; "filesexist() cannot validate files containing '#', not working as expected" if => not( "ok" ); ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/length.cf0000644000000000000000000000254015010704253024163 0ustar00rootroot00000000000000####################################################### # # Test 'length' function # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "normal_list" slist => { "b", "c", "a" }; # 3 "empty_list" slist => { }; # 0 "normal_object" data => parsejson('{ "a": 1, "b": 2 }'); # 2 "empty_object" data => parsejson('{}'); # 0 "normal_list_len" int => length(normal_list); "empty_list_len" int => length(empty_list); "normal_object_len" int => length(normal_object); "empty_object_len" int => length(empty_object); "inline_object_len" int => length('{ "a": 1, "b": 2 }'); # 2 "inline_array_len" int => length('[ "a", 1, "b", 2 ]'); # 4 } ####################################################### ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/600.cf0000644000000000000000000000537015010704253023213 0ustar00rootroot00000000000000####################################################### # # Test readrealarray(), simple # # The 5xx tests look at the same thing as their corresponding 4xx tests # 500-519 are readrealarray, 520-539 test the same things for parseintarray # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "0:1:2 999.9:888:777:666.6 1:2:3"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "cnt" int => readrealarray("ary", "$(G.testfile)","NoComment",":",10,1000); "num" int => "3"; } ####################################################### bundle agent check { vars: "idx" slist => getindices("test.ary"); classes: "good" and => { strcmp("$(test.num)", "$(test.cnt)"), strcmp("$(test.ary[0][0])", "0"), strcmp("$(test.ary[0][1])", "1"), strcmp("$(test.ary[0][2])", "2"), strcmp("$(test.ary[999.9][0])", "999.9"), strcmp("$(test.ary[999.9][1])", "888"), strcmp("$(test.ary[999.9][2])", "777"), strcmp("$(test.ary[999.9][3])", "666.6"), strcmp("$(test.ary[1][0])", "1"), strcmp("$(test.ary[1][1])", "2"), strcmp("$(test.ary[1][2])", "3"), }; # Make sure there are no trailing elements "bad" or => { isvariable("test.ary[0][3]"), isvariable("test.ary[999.9][4]"), isvariable("test.ary[1][3]"), }; "ok" expression => "good&!bad"; reports: DEBUG:: "expected $(test.num) entries, saw $(test.cnt)"; "saw array indices '$(idx)'"; "expected test.ary[0][0] = '0', saw '$(test.ary[0][0])'"; "expected test.ary[0][1] = '1', saw '$(test.ary[0][1])'"; "expected test.ary[0][2] = '2', saw '$(test.ary[0][2])'"; "expected test.ary[999.9][0] = '999.9', saw '$(test.ary[999.9][0])'"; "expected test.ary[999.9][1] = '888', saw '$(test.ary[999.9][1])'"; "expected test.ary[999.9][2] = '777', saw '$(test.ary[999.9][2])'"; "expected test.ary[999.9][3] = '666.6', saw '$(test.ary[999.9][3])'"; "expected test.ary[1][0] = '1', saw '$(test.ary[1][0])'"; "expected test.ary[1][1] = '2', saw '$(test.ary[1][1])'"; "expected test.ary[1][2] = '3', saw '$(test.ary[1][2])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/039.cf0000644000000000000000000000265115010704253023220 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", islessthan("$(test.sum)", "579.1"), isgreaterthan("$(test.sum)", "578.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/020.cf0000644000000000000000000000314115010704253023201 0ustar00rootroot00000000000000####################################################### # # Test readstringlist() issue 364, also 366 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123 456 789"; # "empty" fields } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" slist => readstringlist("$(G.testfile)","NoComment","\s",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" slist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123", "$(nums)"); "ok456" expression => strcmp("456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok456", "ok789", islessthan("$(test.sum)", "1368.1"), isgreaterthan("$(test.sum)", "1367.9") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/mergedata-json-strings.cf0000644000000000000000000000147015010704253027272 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -f- body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" string => "Test that plain json strings can be merged"; vars: "merged" data => mergedata( '[]', '{ "one": "1" }', '{ "two":"2"}' ); files: "$(G.testfile)" create => "true", edit_template_string => "{{%-top-}}", template_method => "inline_mustache", template_data => @(merged); } bundle agent check { methods: "PASS/FAIL" usebundle => dcs_check_diff("$(G.testfile)", "$(this.promise_filename).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getuserinfo.cf.expected.json0000644000000000000000000000005315010704253030001 0ustar00rootroot00000000000000{ "info_0": "0", "info_root": "root" } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_containers.cf.expected.json0000644000000000000000000000010715010704253031673 0ustar00rootroot00000000000000{ "arr_v": [ "a", "1", "2", "5.30", "true" ] } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/043.cf0000644000000000000000000000267615010704253023222 0ustar00rootroot00000000000000####################################################### # # Test readreallist() issue 364 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => init_delete; "$(G.testfile)" create => "true", edit_line => init_fill_in; } bundle edit_line init_fill_in { insert_lines: "123.456"; "789"; } body delete init_delete { dirlinks => "delete"; rmdirs => "true"; } ####################################################### bundle agent test { vars: "nums" rlist => readreallist("$(G.testfile)","NoComment","\s+",5,100); "sum" real => sum("nums"); } ####################################################### bundle agent check { vars: "nums" rlist => { @{test.nums} }; classes: "ok_list" not => strcmp("won't match", "$(nums)"); "ok123" expression => strcmp("123.456", "$(nums)"); "ok789" expression => strcmp("789", "$(nums)"); "ok" and => { "ok_list", "ok123", "ok789", islessthan("$(test.sum)", "912.457"), isgreaterthan("$(test.sum)", "912.455") }; reports: DEBUG:: "nums: $(nums)"; "sum: $(test.sum)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/data_regextract-2.cf.readfile0000644000000000000000000000007715010704253027757 0ustar00rootroot00000000000000[general] guid = 9CB197F0-4569-446A-A987-1DDEC1205F6B port=5308getindices_and_getvalues_return_same_with_empty_datacontainer.cf0000644000000000000000000000233215010704253037412 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/02_functionsbody common control { bundlesequence => { "test" }; } bundle agent test { meta: "description" string => "Test that getindices() and getvalues() return the same data when run against an empty data container"; "test_soft_fail" string => "cfengine_3_9_1", meta => { "CFE-2479" }, comment => "This regression was found in 3.9.1 from 3.7.4. Soft failing for already released version where tests will fail."; vars: # Because def.does_not_exist does in fact not exist, we expect this will # produce an empty data container. "data" data => mergedata("def.does_not_exist"); "a" slist => getindices(data); "b" slist => getvalues(data); reports: DEBUG:: "a is variable" if => isvariable(a); "b is variable" if => isvariable(b); "getindices and getvalues do not behave the same when run against an empty data container." if => not(and(isvariable(a), isvariable(b))); any:: "CFEngine version: $(sys.cf_version)"; "$(this.promise_filename) Pass" if => and(isvariable(a), isvariable(b)); "$(this.promise_filename) FAIL" if => not(and(isvariable(a), isvariable(b))); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/string_replace.cf0000644000000000000000000000325715010704253025711 0ustar00rootroot00000000000000 ####################################################### # # Test string_replace function # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "test" string => "abcdefghij\t\n"; "test2" string => "(){}[].*?"; # normal tests "match_once" string => string_replace("abcd", "abc", "ABC"); "match_twice" string => string_replace("abcdabcd", "abcd", "hello"); "match_none" string => string_replace("abdc", "abcd", "nope"); "match_none2" string => string_replace($(test), "nonesuch", "TEST"); "overlap" string => string_replace("aaaa", "aaa", "yes"); "replace" string => string_replace($(test), "\t", "\r"); "replace2" string => string_replace($(test), "ghij\t", "tEsT"); "replace3" string => string_replace($(test), "abcdefghij\t\n", "no"); # tests for regex special characters "special" string => string_replace($(test2), "()", "1"); "special2" string => string_replace($(test2), "{}", "\1"); "special3" string => string_replace($(test2), ".*?", "\2"); # empty cases "empty" string => string_replace("", "abc", "ABC"); "empty2" string => string_replace("", "abc", ""); } ####################################################### bundle agent check { methods: "" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/getvalues_array_string.cf0000644000000000000000000000203515010704253027464 0ustar00rootroot00000000000000####################################################### # # Test getvalues() # ####################################################### # If we run getvalues on a classic array index that contains a string # we should end up with a list made up of that single value body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "array[string]" string => "scrumdiddlyumptious"; "values" slist => getvalues("array[string]"); } ####################################################### bundle agent check { vars: "expected" slist => { "scrumdiddlyumptious" }; "diff" slist => difference( expected, "test.values" ); classes: "_pass" expression => strcmp( length( diff ), 0 ); methods: _pass:: "pass" usebundle => dcs_pass("$(this.promise_filename)"); !_pass:: "pass" usebundle => dcs_fail("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/02_functions/type.cf0000644000000000000000000000543715010704253023673 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "_data" data => ' { "_string": "abc", "_int": 123, "_real": 123.4, "_true": true, "_false": false, "_object": { "abc": 123 }, "_array": [ 1, 2, 3 ], "_null": null }'; "_string" string => "abc"; "_int" int => "123"; "_real" real => "123.4"; "_slist" slist => { "a", "b", "c" }; "_ilist" ilist => { "1", "2", "3" }; "_rlist" rlist => { "1.2", "3.4", "5.6" }; } bundle agent test { meta: "description" -> { "CFE-2240" } string => "Test for expected results from policy function type"; vars: "test_00" string => type("init._data"); "test_01" string => type("init._data", "true"); "test_02" string => type("init._data[_string]"); "test_03" string => type("init._data[_string]", "true"); "test_04" string => type("init._data[_int]"); "test_05" string => type("init._data[_int]", "true"); "test_06" string => type("init._data[_real]"); "test_07" string => type("init._data[_real]", "true"); "test_08" string => type("init._data[_true]"); "test_09" string => type("init._data[_true]", "true"); "test_10" string => type("init._data[_false]"); "test_11" string => type("init._data[_false]", "true"); "test_12" string => type("init._data[_object]"); "test_13" string => type("init._data[_object]", "true"); "test_14" string => type("init._data[_array]"); "test_15" string => type("init._data[_array]", "true"); "test_16" string => type("init._data[_null]"); "test_17" string => type("init._data[_null]", "true"); "test_18" string => type("init._string"); "test_19" string => type("init._string", "true"); "test_20" string => type("init._int"); "test_21" string => type("init._int", "true"); "test_22" string => type("init._real"); "test_23" string => type("init._real", "true"); "test_24" string => type("init._slist", "false"); "test_25" string => type("init._slist", "true"); "test_26" string => type("init._ilist", "no"); "test_27" string => type("init._ilist", "yes"); "test_28" string => type("init._rlist", "off"); "test_29" string => type("init._rlist", "on"); "test_30" string => type("undefined"); "test_31" string => type("undefined", "true"); } bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/deep_delayed_expansion/0000755000000000000000000000000015010704253024546 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/deep_delayed_expansion/my_globals.cf.sub0000644000000000000000000000012715010704253030000 0ustar00rootroot00000000000000bundle common my_globals { vars: "policy_root" string => "$(def.policy_root)"; } cfengine-3.24.2/tests/acceptance/01_vars/deep_delayed_expansion/main.cf0000644000000000000000000000132415010704253026004 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub", @(def.augments_inputs) }; bundlesequence => { default("$(this.promise_filename)") }; } bundle agent test { meta: "description" string => "Test that variables containing other variales are de-referenced"; "test_soft_fail" string => "windows", meta => { "ENT-10256" }; } bundle agent check { reports: "$(this.promise_filename) Pass" if => strcmp( $(this.promise_dirname), $(my_globals.policy_root) ); "$(this.promise_filename) FAIL" unless => strcmp( $(this.promise_dirname), $(my_globals.policy_root) ); EXTRA:: "my_globals.policy_root = $(my_globals.policy_root)"; "def.policy_root = $(def.policy_root)"; } cfengine-3.24.2/tests/acceptance/01_vars/deep_delayed_expansion/def.json0000644000000000000000000000013715010704253026200 0ustar00rootroot00000000000000{ "vars": { "policy_root": "$(this.promise_dirname)" }, "inputs": ["my_globals.cf.sub"] } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/0000755000000000000000000000000015010704253022526 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containers/pass_variable_container_index.cf.expected0000644000000000000000000000171415010704253032707 0ustar00rootroot00000000000000[any:any:test_data:run_list:executor] a [any:any:test_data:run_list:executor] b [any:any:test_data:run_list:executor] c [any:any:test_data:run_list:executor] x [any:any:test_data:run_list:executor] y [any:any:test_data:run_list:executor] z [any:any:test_array:run_list:executor] x [any:any:test_array:run_list:executor] y [any:any:test_array:run_list:executor] z [any:any:test_array:run_list:executor] a [any:any:test_array:run_list:executor] b [any:any:test_array:run_list:executor] c [any:any:test_executor_data:executor] a [any:any:test_executor_data:executor] b [any:any:test_executor_data:executor] c [any:any:test_executor_data:executor] x [any:any:test_executor_data:executor] y [any:any:test_executor_data:executor] z [any:any:test_executor_array:executor] x [any:any:test_executor_array:executor] y [any:any:test_executor_array:executor] z [any:any:test_executor_array:executor] a [any:any:test_executor_array:executor] b [any:any:test_executor_array:executor] c cfengine-3.24.2/tests/acceptance/01_vars/04_containers/multiple_cmerge_variable_dynamic.cf0000644000000000000000000001130515010704253031566 0ustar00rootroot00000000000000# This policy is synthetic, but represents a real life pattern where data is # published from multiple bundles and then merged before use. # Note: The multiple_cmerge_variable_static.cf test is nearly identical. It simply uses hard coded variables instead of variable variables. #@@ -97,7 +102,7 @@ # # vars: # "cron" #- data => readjson( "$(this.promise_filename).policy_1.cron.json"), #+ data => readjson( "$(this.promise_filename).$(this.bundle).$(this.promiser).json"), # meta => { "cron_rules" }; # # "s" string => format( "%S", cron ); #@@ -120,7 +125,7 @@ # # # For example: Cron entries # "cron" # #- data => readjson( "$(this.promise_filename).policy_2.cron.json"), #+ data => readjson( "$(this.promise_filename).$(this.bundle).$(this.promiser).json"), # meta => { "cron_rules" }; body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "autorun" slist => bundlesmatching(".*", "autorun"); commands: windows:: "$(G.dos2unix) $(this.promise_filename).expected" -> { "ENT-10433" }; files: "$(G.testfile)" edit_line => empty; methods: "$(autorun)" comment => "Bundles tagged with 'autorun' expect to be automatically actuated. Some of the policies publish data by tagging it for other policies to use later in the bundlesequence. This allows for the implementation of automatic cleanup when a service stops publishing specifc data."; } bundle agent test { meta: "description" string => "Test that this real life pattern for loading data based on a bundle name and merging it for later use works."; methods: "cron" comment => "Manage /etc/crontab using published cron rules"; } bundle agent check { methods: "" usebundle => dcs_check_diff( $(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename) ); } bundle agent cron { vars: "published_rules" slist => variablesmatching( ".*", "cron_rules" ), comment => "We find all variables tagged with cron_rules so that we can merge them together and manage /etc/crontab from a single policy. Allowing other polices to easily subscribe to the service."; "sorted" slist => sort( published_rules, "lex" ); # It is possible to perform some data validation at this point. filtering # or restricting what areas of policy are allowed to subscribe to the # cron implementation. methods: # We use the cmerge bundle from the standard library to merge all of the # data containers into a single container that will be used to render # /etc/crontab "" usebundle => cmerge("merged_cron_rules", @(sorted) ); "" usebundle => cron_entries( @(cmerge.merged_cron_rules) ); } bundle agent cron_entries(rules) { vars: "s" string => format("%S", rules ); reports: "$(this.bundle): '$(s)'" report_to_file => "$(G.testfile)"; } bundle edit_line empty { delete_lines: ".*"; } bundle agent policy_1 # This represents a bundle for some service. It might be some custom in house # written application. They publish information about some cron jobs they wish # to have run. That data originates in this case from a plain text file. { meta: "tags" slist => { "autorun" }; vars: "cron" data => readjson( "$(this.promise_filename).$(this.bundle).$(this.promiser).json"), meta => { "cron_rules" }; "s" string => format( "%S", cron ); reports: "$(this.bundle): cron = '$(s)'" report_to_file => "$(G.testfile)"; } bundle agent policy_2 # This represents a bundle for some service. It might be some custom in house # written application. They publish information about some cron jobs they wish # to have run. That data originates in this case from a plain text file. { meta: "tags" slist => { "autorun" }; vars: # # For example: Cron entries "cron" data => readjson( "$(this.promise_filename).$(this.bundle).$(this.promiser).json"), meta => { "cron_rules" }; "s" string => format( "%S", cron ); reports: "$(this.bundle): cron = '$(s)'" report_to_file => "$(G.testfile)"; } bundle agent cmerge(name, varlist) { vars: "$(name)" data => parsejson('[]'), policy => "free"; "$(name)" data => mergedata($(name), $(varlist)), policy => "free"; # iterates! "$(name)_str" string => format("%S", $(name)), policy => "free"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/parsejson_unicode.cf.sub0000644000000000000000000000045215010704253027343 0ustar00rootroot00000000000000body common control { bundlesequence => { "redmine_6549" }; } bundle agent redmine_6549 { vars: "response" data => parsejson('{ "unicode": "Linux kernel \u03c0 = 3,14" }'); "response_idx" slist => getindices("response"); reports: "response index: $(response_idx)"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/inline_yaml.cf0000644000000000000000000000173615010704253025347 0ustar00rootroot00000000000000####################################################### # # Test inline JSON and YAML data # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: feature_yaml:: "included" string => "( included text )"; "options2" data => '--- a: b c: d e: - 1 - 2 '; "options4" data => '--- a: $(included) c: d e: - 1 - 2 '; } ####################################################### bundle agent check { methods: feature_yaml:: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); !feature_yaml:: "check" usebundle => dcs_pass($(this.promise_filename)); } parsejson_with_unresolved_varibales_does_not_define_datacontainer.cf0000644000000000000000000000164715010704253040426 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containersbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that data containers defined with parsejson that conatains unexpanded variables does NOT define a new datacontainer"; } bundle agent check { vars: "data" data => parsejson('{ "key1": "$(sys.fqhost)", "key2" : "$(undefined_namespace:undefined_bundle.undefined_variable)" }'); classes: "fail" expression => isvariable("data"); "ok" not => isvariable("data"); "exception" and => { "fail", "ok" }; reports: fail:: "$(this.promise_filename) FAIL"; ok.!fail:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/iterate_over_data_array.cf0000644000000000000000000000164215010704253027722 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" delete => tidy; } bundle agent test { meta: "description" -> { "zendesk:3437" } string => "Test that we can iterate over an array inside of a data container without first extracting it. And that the order of iteration is preserved."; vars: "data3" data => '{ "iteration_order":[ "b", "c", "a" ], "b":{ "key": "bkeyval" }, "c":{"key":"ckeyval"}, "a":{"key":"akeyval"}}'; files: "$(G.testfile)" create => "true", edit_line => append_if_no_line("$(data3[$(data3[iteration_order])][key])"); } bundle agent check { methods: "Check" usebundle => dcs_check_diff( $(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/iterate_over_data_array.cf.expected0000644000000000000000000000003015010704253031510 0ustar00rootroot00000000000000bkeyval ckeyval akeyval cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson_subindex_quoted.cf0000644000000000000000000000304015010704253030124 0ustar00rootroot00000000000000####################################################### # # Test subreferencing with quoted keys of datas loaded through readjson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '{ "first": 1, "seconds": 2, "third key! can? almost be anything& but no dollar or bracket yet": [ "a", "b", "c" ]}'; } bundle edit_line init_insert_lines { insert_lines: 'a'; 'b'; 'c'; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json", 1024); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: '$(test.load[third key! can? almost be anything& but no dollar or bracket yet])'; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/multiple_cmerge_variable_static.cf0000644000000000000000000000771115010704253031437 0ustar00rootroot00000000000000# This policy is synthetic, but represents a real life pattern where data is # published from multiple bundles and then merged before use. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "autorun" slist => bundlesmatching(".*", "autorun"); commands: windows:: "$(G.dos2unix) $(this.promise_filename).expected" -> { "ENT-10433" }; files: "$(G.testfile)" edit_line => empty; methods: "$(autorun)" comment => "Bundles tagged with 'autorun' expect to be automatically actuated. Some of the policies publish data by tagging it for other policies to use later in the bundlesequence. This allows for the implementation of automatic cleanup when a service stops publishing specifc data."; } bundle agent test { meta: "description" string => "Test that this real life pattern for loading data based on a bundle name and merging it for later use works."; methods: "cron" comment => "Manage /etc/crontab using published cron rules"; } bundle agent check { methods: "" usebundle => dcs_check_diff( $(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename) ); } bundle agent cron { vars: "published_rules" slist => variablesmatching( ".*", "cron_rules" ), comment => "We find all variables tagged with cron_rules so that we can merge them together and manage /etc/crontab from a single policy. Allowing other polices to easily subscribe to the service."; "sorted" slist => sort( published_rules, "lex" ); # It is possible to perform some data validation at this point. filtering # or restricting what areas of policy are allowed to subscribe to the # cron implementation. methods: # We use the cmerge bundle from the standard library to merge all of the # data containers into a single container that will be used to render # /etc/crontab "" usebundle => cmerge("merged_cron_rules", @(sorted) ); "" usebundle => cron_entries( @(cmerge.merged_cron_rules) ); } bundle agent cron_entries(rules) { vars: "s" string => format("%S", rules ); reports: "$(this.bundle): '$(s)'" report_to_file => "$(G.testfile)"; } bundle edit_line empty { delete_lines: ".*"; } bundle agent policy_1 # This represents a bundle for some service. It might be some custom in house # written application. They publish information about some cron jobs they wish # to have run. That data originates in this case from a plain text file. { meta: "tags" slist => { "autorun" }; vars: "cron" data => readjson( "$(this.promise_filename).policy_1.cron.json"), meta => { "cron_rules" }; "s" string => format( "%S", cron ); reports: "$(this.bundle): cron = '$(s)'" report_to_file => "$(G.testfile)"; } bundle agent policy_2 # This represents a bundle for some service. It might be some custom in house # written application. They publish information about some cron jobs they wish # to have run. That data originates in this case from a plain text file. { meta: "tags" slist => { "autorun" }; vars: # # For example: Cron entries "cron" data => readjson( "$(this.promise_filename).policy_2.cron.json"), meta => { "cron_rules" }; "s" string => format( "%S", cron ); reports: "$(this.bundle): cron = '$(s)'" report_to_file => "$(G.testfile)"; } bundle agent cmerge(name, varlist) { vars: "$(name)" data => parsejson('[]'), policy => "free"; "$(name)" data => mergedata($(name), $(varlist)), policy => "free"; # iterates! "$(name)_str" string => format("%S", $(name)), policy => "free"; } multiple_cmerge_variable_static.cf.policy_1.cron.json0000644000000000000000000000032015010704253034773 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containers[ { "hour": "1", "minute": "1", "day": "1", "month": "1", "comment": "a backup job that runs", "command": "/bin/echo 'back me up!'" } ] cfengine-3.24.2/tests/acceptance/01_vars/04_containers/extraction.cf0000644000000000000000000000236515010704253025226 0ustar00rootroot00000000000000####################################################### # # Redmine#4301: "Couldn't find extracted variable" # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "config" data => parsejson('{"*.alert": "root"}'); files: "$(G.testfile).actual" create => "true", edit_line => test_set_line_based("test.config", " ", "\s+", ".*", "\s*#\s*"); } # this is the stdlib set_line_based cut down bundle edit_line test_set_line_based(v, sep, bp, kp, cp) { vars: # even though it's not used in the iteration, the vkeys variable # is required for the test to fail "vkeys" slist => getindices("$(v)"); "i" slist => grep($(kp), vkeys); # Escape the value (had a problem with special characters and regex's) "ev[$(i)]" string => escape("$($(v)[$(i)])"); } ####################################################### bundle agent check { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/test_json_with_and_without_nulls.cf.mustache0000644000000000000000000000002515010704253033532 0ustar00rootroot00000000000000{{%vars.test.state}} cfengine-3.24.2/tests/acceptance/01_vars/04_containers/inline_yaml.cf.expected.json0000644000000000000000000000033415010704253030110 0ustar00rootroot00000000000000{ "included": "( included text )", "options2": { "a": "b", "c": "d", "e": [ 1, 2 ] }, "options4": { "a": "( included text )", "c": "d", "e": [ 1, 2 ] } } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson_objects.cf0000644000000000000000000000261715010704253026364 0ustar00rootroot00000000000000####################################################### # # Test nested datas iteration through readjson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '{ "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null}'; } bundle edit_line init_insert_lines { insert_lines: '1'; '2'; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json", 1024); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } multiple_cmerge_variable_dynamic.cf.policy_1.cron.json0000644000000000000000000000032015010704253035130 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containers[ { "hour": "1", "minute": "1", "day": "1", "month": "1", "comment": "a backup job that runs", "command": "/bin/echo 'back me up!'" } ] cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readyaml.cf0000644000000000000000000000360615010704253024643 0ustar00rootroot00000000000000####################################################### # # Test datas creation through readyaml() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common yaml_check { classes: "no_yaml_support" not => regline(" *# *define *HAVE_LIBYAML.*", "$(this.promise_dirname)/../../../../libutils/config.h"); } bundle agent init { meta: "test_skip_unsupported" string => "no_yaml_support"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).yaml" create => "true", edit_line => init_insert_yaml; } bundle edit_line init_insert_yaml { insert_lines: "- hello - there - where: 1 - where_else: 1.0023E2 - nowhere: true boolean_spears: yes string_spears: \"yes\" bows: maybe"; } bundle edit_line init_insert_lines { insert_lines: '[ "hello", "there", { "where": 1 }, { "where_else": 100.2300 }, { "boolean_spears": true, "bows": "maybe", "nowhere": true, "string_spears": "yes" } ]'; } ####################################################### bundle agent test { vars: "load" data => readyaml("$(G.testfile).yaml", 1024); "load_s" string => storejson(load); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load_s)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/test_json_with_and_without_nulls.cf0000644000000000000000000000732015010704253031727 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" create => "true"; } bundle agent test { meta: "description" string => "Test that null keys, and mixed datatypes in json data are handeled appropriately."; "test_soft_fail" string => "any", meta => { "redmine7821" }; methods: "ec2" comment => "We activate the bundle so that we can grab its state"; } bundle agent check { methods: "check" usebundle => dcs_check_state("ec2", "$(this.promise_filename).expected.json", $(this.promise_filename)); } bundle agent ec2 { vars: # This data has nulls in it, and consists of a single data type for # values (strings) "data" data => '{ "instanceId" : "i-f444554e", "billingProducts" : null, "instanceType" : "m3.large", "accountId" : "444444444444", "pendingTime" : "2015-12-02T19:47:57Z", "imageId" : "ami-44444444", "kernelId" : "aki-44444444", "ramdiskId" : null, "architecture" : "x86_64", "region" : "eu-west-1", "version" : "2010-08-31", "availabilityZone" : "eu-west-1c", "privateIp" : "10.44.44.4", "devpayProductCodes" : null }'; "keys" slist => getindices("data"); "data_$(keys)" string => "$(data[$(keys)])"; # This data has no nulls in it and consists of a single type for values # (strings) "data2" data => '{ "instanceId" : "i-f444554e", "instanceType" : "m3.large", "accountId" : "444444444444", "pendingTime" : "2015-12-02T19:47:57Z", "imageId" : "ami-44444444", "kernelId" : "aki-44444444", "architecture" : "x86_64", "region" : "eu-west-1", "version" : "2010-08-31", "availabilityZone" : "eu-west-1c", "privateIp" : "10.44.44.4", }'; "keys2" slist => getindices("data2"); "data2_$(keys2)" string => "$(data2[$(keys2)])"; # The values in this data contain nulls and are of mixed types # (strings, lists) "data3" data => '{ "a": [], "b": ["one", "two"], "c": null, "d": "should be here" }'; "keys3" slist => getindices("data3"); # I expect that data3_a will not be defined # - because the list is empty and there is nothing to iterate over # - potentially it would make sense to be cf_null (thats what # iterating over empty slist does) or null # I expect that data3_b will contain 'two' # - because the list will be iterated over and two is the last # element. # I expect data3_c to not be defined # - potentially cf_null or null would make sense as with data3_a # I expect data3_d to be 'should be here' "data3_$(keys3)" string => "$(data3[$(keys3)])"; reports: DEBUG:: "Key from 'data': $(keys)"; "key from 'data2': $(keys2)"; "key from 'data3': $(keys3)"; "Value from 'data': $(data_$(keys)) = $(data[$(keys)])"; "Value from 'data2': $(data_$(keys2)) = $(data2[$(keys2)])"; "Value from 'data3': $(data_$(keys3)) = $(data3[$(keys3)])"; } multiple_cmerge_variable_dynamic.cf.policy_2.cron.json0000644000000000000000000000035715010704253035143 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containers[ { "hour": "*", "minute": "*", "day": "*", "month": "*", "comment": "This job is a failsafe to keep cfengine services running", "command": "/bin/echo 'Hi there'" } ] cfengine-3.24.2/tests/acceptance/01_vars/04_containers/pass_variable_container_index.cf0000644000000000000000000000667315010704253031120 0ustar00rootroot00000000000000####################################################### # # Test datacontainers can be passed with a variable name. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: "tags" slist => { "find" }; commands: windows:: "$(G.dos2unix) $(this.promise_filename).expected" -> { "ENT-10433" }; } bundle agent test { meta: "description" -> { "CFE-3299" } string => "Test that lists and data containers with variable index can be passed."; vars: "data" data => parsejson('{ "key1" : { "list" : [ "a", "b", "c" ], "scalar" : "value1" }, "key2" : { "list" : [ "x", "y", "z" ], "scalar" : "value2" } }') ; "array[key1][list]" slist => { "a", "b", "c" } ; "array[key1][scalar]" string => "value1" ; "array[key2][list]" slist => { "x", "y", "z" } ; "array[key2][scalar]" string => "value2" ; "datakey" slist => getindices("data") ; "arraykey" slist => getindices("array") ; methods: "test_data" usebundle => launcher_data("test.data[${datakey}][list]") ; "test_array" usebundle => launcher_array("test.array[${arraykey}][list]") ; "test_executor_data" usebundle => executor("@{test.data[${datakey}][list]}") ; "test_executor_array" usebundle => executor("@{test.data[${arraykey}][list]}") ; } bundle agent check { methods: "" usebundle => dcs_check_diff( $(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename)); } bundle agent launcher_data(list_name) { vars: any:: "expanded_list" slist => getvalues("${list_name}") ; "callers" string => join(":", callstack_promisers()) ; methods: any:: # If we don't add something variable in the following promise, and the promise is kept, # CFEngine will think that the promise is already kept and refuse to keep it more than # once. Inserting a variable handle will make CFEngine understand that it's not the # same promise we are asking it to keep over and over again, and execute it again every # time we pass it a different list. "run_list" usebundle => executor(@{launcher_data.expanded_list}), handle => "run_list_${list_name}" ; } bundle agent launcher_array(list_name) { vars: any:: "expanded_list" slist => { "@{${list_name}}"} ; "callers" string => join(":", callstack_promisers()) ; methods: any:: # If we don't add something variable in the following promise, and the promise is kept, # CFEngine will think that the promise is already kept and refuse to keep it more than # once. Inserting a variable handle will make CFEngine understand that it's not the # same promise we are asking it to keep over and over again, and execute it again every # time we pass it a different list. "run_list" usebundle => executor(@{launcher_array.expanded_list}), handle => "run_list_${list_name}" ; } bundle agent executor(list) { vars: "callers" string => join(":", callstack_promisers()) ; reports: "[${callers}:${this.bundle}] ${list}" report_to_file => "$(G.testfile)"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/multiple_cmerge_variable_dynamic.cf.expected0000644000000000000000000000112615010704253033366 0ustar00rootroot00000000000000policy_2: cron = '[{"command":"/bin/echo 'Hi there'","comment":"This job is a failsafe to keep cfengine services running","day":"*","hour":"*","minute":"*","month":"*"}]' policy_1: cron = '[{"command":"/bin/echo 'back me up!'","comment":"a backup job that runs","day":"1","hour":"1","minute":"1","month":"1"}]' cron_entries: '[{"command":"/bin/echo 'back me up!'","comment":"a backup job that runs","day":"1","hour":"1","minute":"1","month":"1"},{"command":"/bin/echo 'Hi there'","comment":"This job is a failsafe to keep cfengine services running","day":"*","hour":"*","minute":"*","month":"*"}]' cfengine-3.24.2/tests/acceptance/01_vars/04_containers/parsejson.cf0000644000000000000000000000222315010704253025043 0ustar00rootroot00000000000000####################################################### # # Test parsejson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; } bundle edit_line init_insert_lines { insert_lines: 'a'; 'b'; 'c'; } ####################################################### bundle agent test { vars: "load" data => parsejson('["a", "b", "c"]'); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/mergecontainer_arrays.cf0000644000000000000000000000240015010704253027417 0ustar00rootroot00000000000000####################################################### # # Test mergejson() with two JSON arrays # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; } bundle edit_line init_insert_lines { insert_lines: 'a'; 'b'; 'c'; } ####################################################### bundle agent test { vars: "load1" data => parsejson('["a", "b"]'); "load2" data => parsejson('["c"]'); "load" data => mergedata("load1", "load2"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/mergecontainer.cf0000644000000000000000000000251315010704253026043 0ustar00rootroot00000000000000####################################################### # # Test mergedata() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; } bundle edit_line init_insert_lines { insert_lines: 'a'; 'b'; 'c'; } ####################################################### bundle agent test { vars: "load1" data => parsejson('{"x": "y", "third": 123}'); "load2" data => parsejson(' { "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null } '); "load" data => mergedata("load1", "load2"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load[third])"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readyaml_new.cf0000644000000000000000000000361715010704253025516 0ustar00rootroot00000000000000####################################################### # # Test data creation through readyaml() with just 1 arg # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common yaml_check { classes: "no_yaml_support" not => regline(" *# *define *HAVE_LIBYAML.*", "$(this.promise_dirname)/../../../../libutils/config.h"); } bundle agent init { meta: "test_skip_unsupported" string => "no_yaml_support"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).yaml" create => "true", edit_line => init_insert_yaml; } bundle edit_line init_insert_yaml { insert_lines: "- hello - there - where: 1 - where_else: 1.0023E2 - nowhere: true boolean_spears: yes string_spears: \"yes\" bows: maybe"; } bundle edit_line init_insert_lines { insert_lines: '[ "hello", "there", { "where": 1 }, { "where_else": 100.2300 }, { "boolean_spears": true, "bows": "maybe", "nowhere": true, "string_spears": "yes" } ]'; } ####################################################### bundle agent test { vars: "load" data => readyaml("$(G.testfile).yaml"); "load_s" string => storejson(load); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load_s)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } multiple_cmerge_variable_static.cf.policy_2.cron.json0000644000000000000000000000035715010704253035006 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containers[ { "hour": "*", "minute": "*", "day": "*", "month": "*", "comment": "This job is a failsafe to keep cfengine services running", "command": "/bin/echo 'Hi there'" } ] cfengine-3.24.2/tests/acceptance/01_vars/04_containers/inline_json.cf0000644000000000000000000000212315010704253025345 0ustar00rootroot00000000000000####################################################### # # Test inline JSON and YAML data # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "included" string => "( included text )"; "options1" data => ' { "max_content": 512, "verbose": 0, "headers": [ "Foo: bar" ] }'; "options3" data => ' { "max_content": 512, "verbose": "$(included)", "headers": [ "Foo: bar" ] }'; # same as options3 but with bareword keys "options4" data => ' { max_content: 512, verbose: "$(included)", headers: [ "Foo: bar" ] }'; } ####################################################### bundle agent check { methods: "check" usebundle => dcs_check_state(test, "$(this.promise_filename).expected.json", $(this.promise_filename)); } mergedata_with_unresolved_variables_does_not_define_datacontainer.cf0000644000000000000000000000140715010704253040345 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containersbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that data containers are NOT defined when mergedata is used with a non-existing data container"; } bundle agent check { vars: "data" data => mergedata("missing_ns:missing_bundle.missing_var"); classes: "fail" expression => isvariable("data"); "ok" not => isvariable("data"); "exception" and => { "fail", "ok" }; reports: fail:: "$(this.promise_filename) FAIL"; ok.!fail:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/multiple_cmerge_variable_static.cf.expected0000644000000000000000000000112615010704253033231 0ustar00rootroot00000000000000policy_2: cron = '[{"command":"/bin/echo 'Hi there'","comment":"This job is a failsafe to keep cfengine services running","day":"*","hour":"*","minute":"*","month":"*"}]' policy_1: cron = '[{"command":"/bin/echo 'back me up!'","comment":"a backup job that runs","day":"1","hour":"1","minute":"1","month":"1"}]' cron_entries: '[{"command":"/bin/echo 'back me up!'","comment":"a backup job that runs","day":"1","hour":"1","minute":"1","month":"1"},{"command":"/bin/echo 'Hi there'","comment":"This job is a failsafe to keep cfengine services running","day":"*","hour":"*","minute":"*","month":"*"}]' cfengine-3.24.2/tests/acceptance/01_vars/04_containers/canonical_json.cf0000644000000000000000000000156415010704253026026 0ustar00rootroot00000000000000####################################################### # # Test canonical JSON output # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "c" data => parsejson('{ "q": 100, "a": 200, "c": [1,2,3,4] }'); } bundle agent test { vars: "actual" string => format("%S", "init.c"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_strcmp($(test.actual), '{"a":200,"c":[1,2,3,4],"q":100}', $(this.promise_filename), "no"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/inline_json.cf.expected.json0000644000000000000000000000057715010704253030130 0ustar00rootroot00000000000000{ "included": "( included text )", "options1": { "headers": [ "Foo: bar" ], "max_content": 512, "verbose": 0 }, "options3": { "headers": [ "Foo: bar" ], "max_content": 512, "verbose": "( included text )" }, "options4": { "headers": [ "Foo: bar" ], "max_content": 512, "verbose": "( included text )" } } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/parsejson_unicode.cf0000644000000000000000000000125015010704253026550 0ustar00rootroot00000000000000####################################################### # # Test that we don't barf on unicode escapes in JSON # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*R: response index: unicode\b.*", ".*Error parsing JSON.*", "$(sys.cf_agent) -KIf $(this.promise_filename).sub", $(this.promise_filename)); } test_json_with_and_without_nulls.cf.expected.json0000644000000000000000000000444115010704253034421 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containers{ "data": { "accountId": "444444444444", "architecture": "x86_64", "availabilityZone": "eu-west-1c", "billingProducts": null, "devpayProductCodes": null, "imageId": "ami-44444444", "instanceId": "i-f444554e", "instanceType": "m3.large", "kernelId": "aki-44444444", "pendingTime": "2015-12-02T19:47:57Z", "privateIp": "10.44.44.4", "ramdiskId": null, "region": "eu-west-1", "version": "2010-08-31" }, "data2": { "accountId": "444444444444", "architecture": "x86_64", "availabilityZone": "eu-west-1c", "imageId": "ami-44444444", "instanceId": "i-f444554e", "instanceType": "m3.large", "kernelId": "aki-44444444", "pendingTime": "2015-12-02T19:47:57Z", "privateIp": "10.44.44.4", "region": "eu-west-1", "version": "2010-08-31" }, "data_accountId": "444444444444", "data_architecture": "x86_64", "data_availabilityZone": "eu-west-1c", "data_imageId": "ami-44444444", "data_instanceId": "i-f444554e", "data_instanceType": "m3.large", "data_kernelId": "aki-44444444", "data_pendingTime": "2015-12-02T19:47:57Z", "data_privateIp": "10.44.44.4", "data_region": "eu-west-1", "data_version": "2010-08-31", "data2_accountId": "444444444444", "data2_architecture": "x86_64", "data2_availabilityZone": "eu-west-1c", "data2_imageId": "ami-44444444", "data2_instanceId": "i-f444554e", "data2_instanceType": "m3.large", "data2_kernelId": "aki-44444444", "data2_pendingTime": "2015-12-02T19:47:57Z", "data2_privateIp": "10.44.44.4", "data2_region": "eu-west-1", "data2_version": "2010-08-31", "data3": { "a": [], "b": [ "one", "two" ], "c": null, "d": "should be here" }, "data3_b": "two", "data3_d": "should be here", "keys": [ "instanceId", "billingProducts", "instanceType", "accountId", "pendingTime", "imageId", "kernelId", "ramdiskId", "architecture", "region", "version", "availabilityZone", "privateIp", "devpayProductCodes" ], "keys2": [ "instanceId", "instanceType", "accountId", "pendingTime", "imageId", "kernelId", "architecture", "region", "version", "availabilityZone", "privateIp" ], "keys3": [ "a", "b", "c", "d" ] } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/parsejson_indexed.cf0000644000000000000000000000233115010704253026543 0ustar00rootroot00000000000000####################################################### # # Test parsejson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; } bundle edit_line init_insert_lines { insert_lines: 'a'; 'b'; 'c'; } ####################################################### bundle agent test { vars: "load" data => parsejson(' { "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null } '); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load[third])"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson.cf0000644000000000000000000000253415010704253024651 0ustar00rootroot00000000000000####################################################### # # Test datas creation through readjson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '[ "hello", "there" ]'; } bundle edit_line init_insert_lines { insert_lines: "hello"; "there"; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json", 1024); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson_subindex.cf0000644000000000000000000000265115010704253026552 0ustar00rootroot00000000000000####################################################### # # Test subreferencing of datas loaded through readjson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '{ "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null}'; } bundle edit_line init_insert_lines { insert_lines: 'a'; 'b'; 'c'; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json", 1024); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load[third])"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } parsejson_storejson_with_missing_container_does_not_create_new_container.cf0000644000000000000000000000175515010704253042061 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containersbody common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle common test_meta { vars: "description" string => "Test that a data container defined by using parsejson(storejson()) against a non existing data container will not define a new data container."; } bundle agent init { vars: "data" data => parsejson(storejson("missing_ns:missing_bundle.missing_var")); "serialized_data" string => format("%S", data); reports: DEBUG:: "DEBUG $(this.bundle): serialized_data: '$(serialized_data)'"; } bundle agent check { classes: "fail" expression => isvariable("init.data"); "ok" not => isvariable("init.data"); "exception" and => { "fail", "ok" }; reports: fail:: "$(this.promise_filename) FAIL"; ok.!fail:: "$(this.promise_filename) Pass"; exception:: "$(this.promise_filename) EXCEPTION"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/mergecontainer_conflict.cf0000644000000000000000000000257715010704253027736 0ustar00rootroot00000000000000####################################################### # # Test mergejson() with mismatched datas # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; } bundle edit_line init_insert_lines { insert_lines: "$(const.dollar)(test.load[third])"; } ####################################################### bundle agent test { vars: "load1" data => parsejson('["x": "y", "third"]'); "load2" data => parsejson(' { "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null } '); # this should fail "load" data => mergedata("load1", "load2"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load[third])"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } iterate_over_data_container_with_nulls.cf.expected0000644000000000000000000000150515010704253034555 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/04_containerswith nulls: instanceId = i-f444554e with nulls: instanceType = m3.large with nulls: accountId = 444444444444 with nulls: pendingTime = 2015-12-02T19:47:57Z with nulls: imageId = ami-44444444 with nulls: kernelId = aki-44444444 with nulls: architecture = x86_64 with nulls: region = eu-west-1 with nulls: version = 2010-08-31 with nulls: availabilityZone = eu-west-1c with nulls: privateIp = 10.44.44.4 without nulls: instanceId = i-f444554e without nulls: instanceType = m3.large without nulls: accountId = 444444444444 without nulls: pendingTime = 2015-12-02T19:47:57Z without nulls: imageId = ami-44444444 without nulls: kernelId = aki-44444444 without nulls: architecture = x86_64 without nulls: region = eu-west-1 without nulls: version = 2010-08-31 without nulls: availabilityZone = eu-west-1c without nulls: privateIp = 10.44.44.4 cfengine-3.24.2/tests/acceptance/01_vars/04_containers/parseyaml.cf0000644000000000000000000000443315010704253025041 0ustar00rootroot00000000000000####################################################### # # Test parseyaml() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle common yaml_check { classes: "no_yaml_support" not => regline(" *# *define *HAVE_LIBYAML.*", "$(this.promise_dirname)/../../../../libutils/config.h"); } bundle agent init { meta: "test_skip_unsupported" string => "no_yaml_support"; files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; } bundle edit_line init_insert_lines { insert_lines: '{ "a": "b", "c": "d", "e": [ { "where": 1 }, { "where_else": 100.2300 }, { "boolean_spears": true, "bows": "maybe", "nowhere": true, "string_spears": "yes" } ], "f": [ { "hostname": "prd-web", "packages": [ "apache", "memcache" ], "users": [ "root", "mike" ] }, { "hostname": "prd-db", "packages": [ "postgresql" ], "users": [ "root", "john", "debbie" ] } ] }'; } ####################################################### bundle agent test { vars: "load" data => parseyaml('a: b c: d e: - where: 1 - where_else: 1.0023E2 - nowhere: true boolean_spears: yes string_spears: "yes" bows: maybe f: - hostname: prd-web packages: - apache - memcache users: - root - mike - hostname: prd-db packages: - postgresql users: - root - john - debbie '); "load_s" string => storejson(load); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load_s)"; } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson_new.cf0000644000000000000000000000254515010704253025524 0ustar00rootroot00000000000000####################################################### # # Test data creation through readjson() with just 1 arg # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '[ "hello", "there" ]'; } bundle edit_line init_insert_lines { insert_lines: "hello"; "there"; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json"); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson_null.cf0000644000000000000000000000253615010704253025705 0ustar00rootroot00000000000000####################################################### # # Test datas creation from a null through readjson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: 'null'; } bundle edit_line init_insert_lines { insert_lines: "$(const.dollar)(test.load)"; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json", 1024); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/parseyaml_abuse.cf0000644000000000000000000000170615010704253026220 0ustar00rootroot00000000000000####################################################### # # Abuse parseyaml() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "strings" data => parsejson(' [ "- valid", "xyzzz", "- xyzzz", "[xyzzz]", "- { xyzzz: }", "xyzzz: { p: 100 }", "- p class=\\"some class\\" id=\\"some-id\\": abusing the free naming of properties in YAML.", ]'); "n" slist => getindices(strings); "load_$(n)" data => parseyaml("$(strings[$(n)])"); "load_s_$(n)" string => format("%S", "load_$(n)"); reports: EXTRA:: "parsing $(n) = $(strings[$(n)])"; "convert $(n) = $(load_s_$(n))"; } bundle agent check { methods: "any" usebundle => dcs_pass("$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/pass_variable_container.cf.expected0000644000000000000000000000116615010704253031521 0ustar00rootroot00000000000000Pass by name: hosts=/etc/hosts Pass by name: auto_master=/etc/auto.master Pass by namespace:name: hosts=/etc/hosts Pass by namespace:name: auto_master=/etc/auto.master Pass by variable name: hosts=/etc/hosts Pass by variable name: auto_master=/etc/auto.master Pass by variable name including namespace: hosts=/etc/hosts Pass by variable name including namespace: auto_master=/etc/auto.master Pass by variable name with prefix: hosts=/etc/hosts Pass by variable name with prefix: auto_master=/etc/auto.master Pass by variable name with namespace: hosts=/etc/hosts Pass by variable name with namespace: auto_master=/etc/auto.master cfengine-3.24.2/tests/acceptance/01_vars/04_containers/passing_containers.cf0000644000000000000000000000234615010704253026736 0ustar00rootroot00000000000000####################################################### # # Test passing of datas with @(ref) notation # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; } bundle edit_line init_insert_lines { insert_lines: '1'; '2'; } ####################################################### bundle agent test { vars: "load" data => parsejson(' { "first": 1, "seconds": 2, "third": [ "a", "b", "c" ], "fourth": null} '); files: "$(G.testfile).actual" create => "true", edit_line => test_insert(@(load)); } bundle edit_line test_insert(data) { insert_lines: "$(data)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/execresult_and_as_data.cf0000644000000000000000000000202215010704253027515 0ustar00rootroot00000000000000####################################################### # # Test the ability to call the same command with execresult and execresult_as_data # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: !windows:: "res1" string => execresult("echo test", "useshell"); "res2" data => execresult_as_data("echo test", "useshell", "stdout"); windows:: "res1" string => execresult("echo test", "powershell"); "res2" data => execresult_as_data("echo test", "powershell", "stdout"); } ####################################################### bundle agent check { methods: "any" usebundle => dcs_check_strcmp("${test.res1}", "${test.res2[output]}", "$(this.promise_filename)", "no"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson_scalar.cf0000644000000000000000000000254215010704253026175 0ustar00rootroot00000000000000####################################################### # # Test datas creation from a scalar through readjson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '123456'; } bundle edit_line init_insert_lines { insert_lines: "$(const.dollar)(test.load)"; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json", 1024); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/readjson_arrays.cf0000644000000000000000000000262415010704253026232 0ustar00rootroot00000000000000####################################################### # # Test nested datas iteration through readjson() # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).expected" create => "true", edit_line => init_insert_lines; "$(G.testfile).json" create => "true", edit_line => init_insert_json; } bundle edit_line init_insert_json { insert_lines: '[ 1, 2, 3, [ "a", "b", "c" ], "d", 5, null]'; } bundle edit_line init_insert_lines { insert_lines: '1'; '2'; '3'; 'd'; '5'; } ####################################################### bundle agent test { vars: "load" data => readjson("$(G.testfile).json", 1024); files: "$(G.testfile).actual" create => "true", edit_line => test_insert; } bundle edit_line test_insert { insert_lines: "$(test.load)"; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).actual", "$(G.testfile).expected", "$(this.promise_filename)"); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/iterate_over_data_container_with_nulls.cf0000644000000000000000000000401615010704253033034 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { commands: windows:: "$(G.dos2unix) $(this.promise_filename).expected" -> { "ENT-10433" }; files: "$(G.testdir)/actual.txt" delete => tidy; } bundle agent test { meta: "description" -> { "CFE-2230" } string => "Test that iteration over the getindices() of a data container is not interrupted by nulls."; vars: "data" data => '{ "instanceId": "i-f444554e", "billingProducts": null, "instanceType": "m3.large", "accountId": "444444444444", "pendingTime": "2015-12-02T19:47:57Z", "imageId": "ami-44444444", "kernelId": "aki-44444444", "ramdiskId": null, "architecture": "x86_64", "region": "eu-west-1", "version": "2010-08-31", "availabilityZone": "eu-west-1c", "privateIp": "10.44.44.4", "devpayProductCodes": null }'; "data2" data => '{ "instanceId" : "i-f444554e", "instanceType" : "m3.large", "accountId" : "444444444444", "pendingTime" : "2015-12-02T19:47:57Z", "imageId" : "ami-44444444", "kernelId" : "aki-44444444", "architecture" : "x86_64", "region" : "eu-west-1", "version" : "2010-08-31", "availabilityZone" : "eu-west-1c", "privateIp" : "10.44.44.4", }'; "keys" slist => getindices("data"); "$(keys)" string => "$(data[$(keys)])"; "keys2" slist => getindices("data2"); "$(keys2)" string => "$(data2[$(keys2)])"; reports: "with nulls: $(keys) = $(data[$(keys)])" report_to_file => "$(G.testdir)/actual.txt"; "without nulls: $(keys2) = $(data2[$(keys2)])" report_to_file => "$(G.testdir)/actual.txt"; } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_diff( "$(G.testdir)/actual.txt", "$(this.promise_filename).expected", $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/pass_variable_container.cf0000644000000000000000000000446415010704253027725 0ustar00rootroot00000000000000####################################################### # # Test datacontainers can be passed with a variable name. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { meta: "tags" slist => { "find" }; commands: windows:: "$(G.dos2unix) $(this.promise_filename).expected" -> { "ENT-10433" }; vars: # We want to be sure we can reference this data subsequently "d" data => parsejson( '{ "hosts": { "path": "/etc/hosts" }, "auto_master" { "path": "/etc/auto.master" } }'); } bundle agent test { meta: "description" -> { "CFE-2434" } string => "Test that variable data containers can be passed."; vars: "found" slist => bundlesmatching(".*", "find"); # "ns_bundle" string => "default:init"; # This is the same content as the # "found" variable, so we just use that instead. "bundle_name" string => "init"; "bundle_name_suffix" string => "it"; methods: "" usebundle => report_data("Pass by name:", @(init.d)); "" usebundle => report_data("Pass by namespace:name:", @(default:init.d)); "" usebundle => report_data("Pass by variable name:", "@($(bundle_name).d)"); "" usebundle => report_data("Pass by variable name including namespace:", "@($(found).d)"); "" usebundle => report_data("Pass by variable name with prefix:", "@(in$(bundle_name_suffix).d)"); "" usebundle => report_data("Pass by variable name with namespace:", "@(default:$(bundle_name).d)"); } bundle agent check { methods: "" usebundle => dcs_check_diff( $(G.testfile), "$(this.promise_filename).expected", $(this.promise_filename)); } bundle agent report_data(id, datacontainer) { vars: "keys" slist => getindices("datacontainer"); classes: "some_keys" expression => some(".*", keys); reports: DEBUG:: "$(id) found keys in data container" if => "some_keys"; "$(id) did *not* find keys in data container" unless => "some_keys"; any:: "$(id) $(keys)=$(datacontainer[$(keys)][path])" report_to_file => "$(G.testfile)"; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/inline_json_parse.cf.sub0000644000000000000000000000016615010704253027334 0ustar00rootroot00000000000000bundle agent mytest { vars: "inline" data => '{ "key": "special value e8hoeAM1UJC5xmqwCx9iJARKZ9qGk8GU" }'; } cfengine-3.24.2/tests/acceptance/01_vars/04_containers/inline_json_parse.cf0000644000000000000000000000130715010704253026542 0ustar00rootroot00000000000000####################################################### # # Test inline JSON and YAML data # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent check { methods: "check" usebundle => dcs_passif_output(".*e8hoeAM1UJC5xmqwCx9iJARKZ9qGk8GU.*", "", "$(sys.cf_promises) -p json $(this.promise_filename).sub", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/0000755000000000000000000000000015010704253021437 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/vars_in_arrays.cf0000644000000000000000000000252215010704253024774 0ustar00rootroot00000000000000 # # Parsing paramaterized arrays # body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { "init", "check" }; version => "1.0"; } ####################################################### bundle agent init { files: "$(G.testfile).actual" create => "true", edit_line => write, edit_defaults => empty; "$(G.testfile).expected" create => "true", edit_line => write_control, edit_defaults => empty; } ####################################################### bundle agent check { methods: "any" usebundle => sorted_check_diff("$(G.testfile).expected", "$(G.testfile).actual", "$(this.promise_filename)"); } ####################################################### bundle edit_line write_control { insert_lines: "1 3 2 one two three four"; } bundle edit_line write { vars: "a[1]" string => "a"; "a[2]" string => "b"; "a[3]" string => "c"; "alias" string => "a"; "list" slist => getindices($(alias)); "one[$(sys.uqhost)]" slist => { "one", "two" }; "two" slist => { "three", "four" }; "oneandtwo" slist => { @(one[$(sys.uqhost)]), @(two) }; insert_lines: "$(list)"; "$(oneandtwo)"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/001.cf0000644000000000000000000000211615010704253022251 0ustar00rootroot00000000000000####################################################### # # Test simple variables # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" int => "10"; "ten[ten]" int => "11"; "nine" string => "hello", policy => "free"; "nine" int => "9", policy => "free"; } ####################################################### bundle agent check { classes: "ok_10" not => strcmp("$(test.ten)", "$(test.ten[ten])"); "ok" and => { "ok_10", strcmp("$(test.nine)", "9") }; reports: DEBUG:: "ten == $(test.ten)"; "ten[ten] == $(test.ten[ten])"; "nine == $(test.nine)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/parse_number_3572.cf0000644000000000000000000000264215010704253025117 0ustar00rootroot00000000000000####################################################### # # Regression test for RedMine #3572. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "digits" string => "42"; } ####################################################### bundle agent test { vars: "number" int => "$(init.digits)"; "floaty" real => "$(init.digits)"; # RedMine #3572: this stanza should make no difference, but actually # caused the numbers to be unexpanded, hence not "42" but literally # "$(init.digits)", which doesn't parse as a number ! classes: "ignored" not => "any"; # (In fact, even an empty classes stanza provoked the bug - but is # that even valid ?) } ####################################################### bundle agent check { classes: "iok" expression => strcmp("$(test.number)", "$(init.digits)"); "rok" expression => strcmp("$(test.floaty)", "42.000000"); "ok" and => { "iok", "rok" }; reports: DEBUG.!iok:: "Read $(init.digits) as int $(test.number)"; DEBUG.!rok:: "Read $(init.digits) as real $(test.floaty)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/this_variables.cf.finish0000644000000000000000000000002615010704253026225 0ustar00rootroot00000000000000[test] testline [end] cfengine-3.24.2/tests/acceptance/01_vars/01_basic/sys_flavor_on_aix_no_dots.cf0000644000000000000000000000166015010704253027225 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { classes: "etc_os_release_present" expression => fileexists( '/etc/os-release'); meta: "description" -> { "ENT-3970" } string => "Test that sys.flavor on aix is in the form aix_digit"; "test_skip_needs_work" string => "!(aix|etc_os_release_present)", meta => { "ENT-3970"}; methods: # Probably the common case for this would be $(sys.os)_MAJOR or $(sys.os)_\d+ aix:: "Pass/Fail" usebundle => dcs_check_regcmp( "aix_\d+", $(sys.flavor), $(this.promise_filename), "no" ); etc_os_release_present:: "Pass/Fail" usebundle => dcs_check_regcmp( "$(sys.os_release[ID])_\d+", $(sys.flavor), $(this.promise_filename), "no" ), if => fileexists( "/etc/os-release" ); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/106.cf.sub0000644000000000000000000000036015010704253023046 0ustar00rootroot00000000000000body common control { bundlesequence => { "test" }; } bundle agent test { vars: "index" slist => { "index" }; "array[$(index)]" string => "value"; "indices" slist => getindices("array"); "values" slist => getvalues("array"); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/010.cf0000644000000000000000000000231315010704253022250 0ustar00rootroot00000000000000####################################################### # # Test nested functions # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "oct2" string => '20'; "oct4" slist => { '11', '12' }; "separator" string => ","; "prefix" string => "10.${oct2}.20"; "temp_namelist" slist => { " ", @(oct4) }; "foo" slist => splitstring ( join("${separator}${prefix}", "temp_namelist"), "$(separator)", "999999999" ); "nameserv" slist => grep ("^[^\s]+$", join(escape("${separator}${prefix}"), "temp_namelist") ); } ####################################################### bundle agent check { classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/vars_comments_emitted_in_verbose.cf.sub0000644000000000000000000000020415010704253031343 0ustar00rootroot00000000000000bundle agent main { vars: "test_var" string => "test_var value", comment => "This is a comment about test_var"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/107.cf0000644000000000000000000000133515010704253022262 0ustar00rootroot00000000000000# Test that function call with computed if does not lead to incorrect # use of values (Mantis #864) (Mantis #1084) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "useshell"); } bundle agent check { classes: "ok" not => regcmp(".*Unable to parse class expression.*", "$(test.subout)"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/uptime_systime_and_sysday.cf0000644000000000000000000000250115010704253027245 0ustar00rootroot00000000000000# Test $(sys.uptime), $(sys.systime) and $(sys.sysday) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { vars: # Quite crude testing, only test that it is a number, and not zero. "regexp" string => "^[0-9]+$"; "notregexp" string => "^0$"; } ####################################################### bundle agent check { classes: "uptime_ok" expression => regcmp("$(init.regexp)", "$(sys.uptime)"); "systime_ok" expression => regcmp("$(init.regexp)", "$(sys.systime)"); "sysday_ok" expression => regcmp("$(init.regexp)", "$(sys.sysday)"); "uptime_ok_zero" not => regcmp("$(init.notregexp)", "$(sys.uptime)"); "systime_ok_zero" not => regcmp("$(init.notregexp)", "$(sys.systime)"); "sysday_ok_zero" not => regcmp("$(init.notregexp)", "$(sys.sysday)"); "ok" and => { "uptime_ok", "systime_ok", "sysday_ok", "uptime_ok_zero", "systime_ok_zero", "sysday_ok_zero" }; reports: DEBUG:: "sys.uptime: $(sys.uptime)"; "sys.systime: $(sys.systime)"; "sys.sysday: $(sys.sysday)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/double_expansion_list.cf0000755000000000000000000000405415010704253026350 0ustar00rootroot00000000000000############################################################################## # # Test double expansion of list from remote bundle (ENT-9491) # ############################################################################## body common control { bundlesequence => { "check" }; } bundle agent test(parent_bundle) { meta: "description" -> { "ENT-9491", "CFE-1644" } string => "Test double expansion of list from remote bundle"; reports: "$($(parent_bundle).str)" comment => "Double expansion of remote string works prior to fix", bundle_return_value_index => "foo"; "$($(parent_bundle).lst)" comment => "But double expansion of remote list does not work prior to fix", bundle_return_value_index => "bar"; "$(check.lst)" comment => "Single expansion of remote list works prior to fix", bundle_return_value_index => "baz"; "$($(parent_bundle)#lst)" comment => "We force mangle the variable, it works, but should this be possible?", bundle_return_value_index => "qux"; } bundle agent check { vars: "str" string => "EXPANDED"; "lst" slist => { "EXPANDED" }; methods: "holder" usebundle => test("$(this.bundle)"), useresult => "ret"; reports: "$(this.promise_filename) Pass" if => and(strcmp("$(ret[foo])", "EXPANDED"), strcmp("$(ret[bar])", "EXPANDED"), strcmp("$(ret[baz])", "EXPANDED"), strcmp("$(ret[qux])", "EXPANDED")); "$(this.promise_filename) FAIL" unless => and(strcmp("$(ret[foo])", "EXPANDED"), strcmp("$(ret[bar])", "EXPANDED"), strcmp("$(ret[qux])", "EXPANDED"), strcmp("$(ret[baz])", "EXPANDED")); DEBUG:: "$(const.dollar)($(const.dollar)(parent_bundle).str) => $(ret[foo])"; "$(const.dollar)($(const.dollar)(parent_bundle).lst) => $(ret[bar])"; "$(const.dollar)(check.lst) => $(ret[baz])"; "$(const.dollar)($(const.dollar)(parent_bundle)#lst) => $(ret[qux])"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/012.cf0000644000000000000000000000161215010704253022253 0ustar00rootroot00000000000000####################################################### # # Compilation test of strings that end with a \ - issue 690 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "foo" string => "simple"; "baz" string => "s\imple"; "gar" string => "s\\imple"; "goo" string => "s\\"; "boo" string => "\\e"; "zoo" string => "\\"; } bundle agent check { classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/this_variables.cf0000644000000000000000000000256415010704253024757 0ustar00rootroot00000000000000# This was created because of a bug while working on purging variable table # copying for CFE-2524. The issue was that variables were not found when # looked up deep inside the INI_SECTION body. body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile).expected" copy_from => local_cp("$(this.promise_filename).finish"); } bundle agent test { vars: "var" slist => { "var in test" }; "var_test" slist => { "var_test in test" }; files: "$(G.testfile).actual" create => "true", edit_line => test_edit_line("testline"); } bundle edit_line test_edit_line(line) { vars: "sectionName" string => "test"; insert_lines: "[$(sectionName)] [end]" location => start; "${line}" select_region => INI_section(escape("$(sectionName)")); } bundle agent check { methods: "check" usebundle => dcs_if_diff( "$(G.testfile).actual", "$(G.testfile).expected", "pass", "_fail"); # Fail the test if any of the files fail. "fail" usebundle => dcs_fail( $(this.promise_filename) ), if => "_fail"; pass:: "pass" usebundle => dcs_pass( $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/can_not_define_variables_in_remote_bundles.cf0000644000000000000000000000407415010704253032516 0ustar00rootroot00000000000000####################################################### # # Test that it is invalid to define variables in remote bundles # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { vars: "check.variable" string => "is defined from bundle $(this.bundle)", comment => "This should not be allowed, perhaps the first part of the variable should be canonified, or it should be a parser error"; "prefix.variable" string => "value-ok", comment => "This should be allowed because there is no such bundle called 'prefix'"; "array[with.a.dot]" string => "value", comment => "dots should be allowed in array keys"; } ####################################################### bundle agent check { meta: "description" -> {"CFE-1915"} string => "Test that it is invalid to define variables in remote bundles"; classes: "variable_defined" expression => isvariable("variable"); "variable_has_content" expression => regcmp(".*", "$(variable)"); "prefixed_var_fail" expression => not(strcmp("$(prefix.variable)", "value-ok")); "array_with_a_dot_fail" expression => not(strcmp("$(test.array[with.a.dot])", "value")); "fail" expression => "(variable_defined|variable_has_content|prefixed_var_fail|array_with_a_dot_fail)"; reports: DEBUG:: "'variable' in bundle '$(this.bundle)' is defined" if => "variable_defined"; "'variable' in bundle '$(this.bundle)' = '$(variable)'" if => "variable_has_content"; "'prefix.variable' = $(prefix.variable)" if => "prefixed_var_fail"; "array[with.a.dot] has the value '$(test.array[with.a.dot])'" if => "array_with_a_dot_fail"; !fail:: "$(this.promise_filename) Pass"; fail:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/109.cf.sub0000644000000000000000000000041515010704253023052 0ustar00rootroot00000000000000body file control { namespace => "ns109"; } bundle agent pass(given_dummy) { vars: "passed_dummy" string => "$(given_dummy)"; reports: DEBUG:: "ns109:pass: given_dummy = '$(given_dummy)'"; "ns109:pass: passed_dummy = '$(passed_dummy)'"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/access_classic_array_key_value_using_with.cf0000644000000000000000000000303215010704253032413 0ustar00rootroot00000000000000########################################################### # # Test the "with" promise attribute # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { meta: "description" -> { "CFE-3223" } string => "Test that with can be used in the index of a classic array to access the value"; "test_soft_fail" string => "any", meta => { "CFE-3223" }; vars: "interfaces" slist => { "eth0", "wlan0", "wlan0.1" }; "ip[eth0]" string => "1.1.1.1"; "ip[wlan0]" string => "2.1.1.1"; "ip[wlan0_1]" string => "3.1.1.1"; "with[$(interfaces)]" string => "$(ip[$(with)])", with => canonify( $(interfaces) ), comment => "This is a bug. This classic array is not generated when I try to dereference an array value using with."; } ########################################################### bundle agent check { classes: "_pass" and => { isvariable( "test.with[eth0]" ), isvariable( "test.with[wlan0]" ), isvariable( "test.with[wlan0.1]" )}; methods: "Pass/Fail" usebundle => dcs_passif("_pass", $(this.promise_filename) ); reports: !_pass:: 'One or more of "test.with[eth0]", "test.with[wlan0]", or "test.with[wlan0.1]" is not defined'; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/CFE-628.cf.sub0000644000000000000000000000053015010704253023451 0ustar00rootroot00000000000000bundle agent main { classes: "found_the_file" expression => fileexists( $(this.promise_filename) ); vars: found_the_file:: "myvar" string => execresult("/bin/echo found_the_file", "noshell"); !found_the_file:: "myvar" string => execresult("/bin/echo didnt_find_the_file", "noshell"); reports: "$(myvar)"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/vars_comments_emitted_in_show_vars.cf0000644000000000000000000000141315010704253031124 0ustar00rootroot00000000000000# Test $(sys.inputdir), $(sys.masterdir), $(sys.libdir), $(sys.bindir), $(sys.failsafe_policy_path), $(sys.update_policy_path), $(sys.local_libdir) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent test { meta: "description" string => "Test that comments on variables are emitted in --show-evaluated-vars output."; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*test_var.*test_var value.*This is a comment about test_var.*", "", "$(sys.cf_agent) -Kf $(this.promise_filename).sub --show-evaluated-vars", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/multi_index_arrays_variable_lookup.cf0000644000000000000000000000216415010704253031114 0ustar00rootroot00000000000000####################################################### # # Conflation of multi-index entries in arrays # Redmine#6674: Conflation of multi-index entries in arrays # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "file[22][0]" string => "something"; "file[2][20]" string => "anything"; "a[10]" string => "a"; "a1[0]" string => "b"; } ####################################################### bundle agent check { classes: "fail_1" expression => strcmp("${test.file[22][0]}", "${test.file[2][20]}"); "fail_2" expression => strcmp("${test.a[10]}", "${test.a1[0]}"); "failure" or => { "fail_1", "fail_2" }; reports: failure:: "$(this.promise_filename) FAIL"; !failure:: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/parse_number.cf0000644000000000000000000000644215010704253024441 0ustar00rootroot00000000000000####################################################### # # Test basic interpretation of digits as numbers. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "digits" string => "42"; "zero" string => "00000"; "negate" string => "-137"; "spacey" string => "17 "; # Spaces ignored after number "kilo" string => "42k"; "kibi" string => "42K"; "mega" string => "42m"; "mibi" string => "42M"; # NB: 42g fails on 32-bit - many places go via int, which overflows (Redmine 4404). "giga" string => "1g"; "gibi" string => "1G"; "pi" string => "3.141592653589793238462643383279502884197169399375105820974"; "nowt" string => "-000.0000e137"; "nogiga" string => "0e0G "; # quantifier and spaces "me2pi" string => "-.5354916555247646e-3M"; # minus exp(two pi) "whole" slist => { "digits", "zero", "negate", "spacey", "kilo", "kibi", "mega", "mibi", "giga", "gibi" }; "float" slist => { "pi", "nowt", "nogiga", "me2pi" }; # Expected answers: "round[digits]" string => "$(digits)"; "round[zero]" string => "0"; "round[negate]" string => "$(negate)"; "round[spacey]" string => "17"; "round[kilo]" string => "42000"; "round[kibi]" string => "43008"; "round[mega]" string => "42000000"; "round[mibi]" string => "44040192"; "round[giga]" string => "1000000000"; "round[gibi]" string => "1073741824"; "ratio[$(whole)]" string => "$(round[$(whole)]).000000"; "ratio[pi]" string => "3.14159265"; "ratio[nowt]" string => "$(ratio[zero])"; "ratio[nogiga]" string => "$(ratio[zero])"; "ratio[me2pi]" string => "535.491656"; } ####################################################### bundle agent test { vars: "round[$(init.whole)]" int => "$(init.$(init.whole))"; "ratio[$(init.whole)]" real => "$(init.$(init.whole))"; "ratio[$(init.float)]" real => "$(init.$(init.float))"; } ####################################################### bundle agent check { vars: "float" slist => { @(init.whole), @(init.float) }; classes: "whole_$(init.whole)" expression => strcmp("$(test.round[$(init.whole)])", "$(init.round[$(init.whole)])"); "float_$(float)" expression => strcmp("$(test.ratio[$(float)])", "$(init.ratio[$(float)])"); "$(init.whole)" and => { "whole_$(init.whole)", "float_$(init.whole)" }; "$(init.float)" and => { "float_$(init.whole)" }; "iok" and => { @(init.whole) }; "rok" and => { @(init.float) }; "ok" and => { "iok", "rok" }; reports: DEBUG.!iok:: "Read $(init.$(init.whole)) as int $(test.round[$(init.whole)]), expected $(init.round[$(init.whole)])"; DEBUG.!rok:: "Read $(init.$(float)) as real $(test.ratio[$(float)]), expected $(init.ratio[$(float)])"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/105.cf0000644000000000000000000000243415010704253022261 0ustar00rootroot00000000000000####################################################### # # Test Scoping of "this" variables (issue 349) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "dummy" string => "dummy"; } ####################################################### bundle agent check { classes: # $(this.promiser) is not available in this context "not_valid" not => strcmp("xyzzy", "$(this.promiser)"); "valid" expression => strcmp("xyzzy", "$(this.promiser)"); "any_promiser" and => { "not_valid", "valid" }; "ok" not => "any_promiser"; reports: DEBUG.not_valid:: "not_valid IS set (and should not be)"; DEBUG.!not_valid:: "not_valid is not set (and should not be)"; DEBUG.valid:: "valid IS set (and should not be)"; DEBUG.!valid:: "valid is not set (and should not be)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/004.x.cf0000644000000000000000000000140315010704253022520 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" real => "1.2.3"; # Not a float } ####################################################### bundle agent check { reports: DEBUG:: "The real variable assignment should fail"; cfengine_3:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/006.x.cf0000644000000000000000000000137715010704253022534 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" real => "."; # Not a float } ####################################################### bundle agent check { reports: DEBUG:: "The real variable assignment should fail"; cfengine_3:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/empty-splice-does-not-segfault.cf0000644000000000000000000000044215010704253027722 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { reports: "empty @{}"; } bundle agent check { reports: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/107.cf.sub0000644000000000000000000000037315010704253023053 0ustar00rootroot00000000000000body common control { bundlesequence => { "main" }; } bundle agent main { methods: "TEST" usebundle => test("any"); } bundle common test(var) { vars: "something" string => and("any", "any"), ifvarclass => canonify("${var}"); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/parse_long_slists.cf0000644000000000000000000044367515010704253025526 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { # Parser used to abort here with message # "error: memory exhausted", see Redmine#6672 vars: "list" ilist => { 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, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547, 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583, 2584, 2585, 2586, 2587, 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627, 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635, 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643, 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746, 2747, 2748, 2749, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773, 2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2942, 2943, 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963, 2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078, 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182, 3183, 3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237, 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309, 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325, 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341, 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358, 3359, 3360, 3361, 3362, 3363, 3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381, 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397, 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429, 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437, 3438, 3439, 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3448, 3449, 3450, 3451, 3452, 3453, 3454, 3455, 3456, 3457, 3458, 3459, 3460, 3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470, 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, 3533, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549, 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557, 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631, 3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681, 3682, 3683, 3684, 3685, 3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3706, 3707, 3708, 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716, 3717, 3718, 3719, 3720, 3721, 3722, 3723, 3724, 3725, 3726, 3727, 3728, 3729, 3730, 3731, 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747, 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 3803, 3804, 3805, 3806, 3807, 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815, 3816, 3817, 3818, 3819, 3820, 3821, 3822, 3823, 3824, 3825, 3826, 3827, 3828, 3829, 3830, 3831, 3832, 3833, 3834, 3835, 3836, 3837, 3838, 3839, 3840, 3841, 3842, 3843, 3844, 3845, 3846, 3847, 3848, 3849, 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857, 3858, 3859, 3860, 3861, 3862, 3863, 3864, 3865, 3866, 3867, 3868, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898, 3899, 3900, 3901, 3902, 3903, 3904, 3905, 3906, 3907, 3908, 3909, 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917, 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925, 3926, 3927, 3928, 3929, 3930, 3931, 3932, 3933, 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941, 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949, 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 3970, 3971, 3972, 3973, 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981, 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989, 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997, 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016, 4017, 4018, 4019, 4020, 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099, 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4175, 4176, 4177, 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, 4186, 4187, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4217, 4218, 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226, 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291, 4292, 4293, 4294, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4371, 4372, 4373, 4374, 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4401, 4402, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4418, 4419, 4420, 4421, 4422, 4423, 4424, 4425, 4426, 4427, 4428, 4429, 4430, 4431, 4432, 4433, 4434, 4435, 4436, 4437, 4438, 4439, 4440, 4441, 4442, 4443, 4444, 4445, 4446, 4447, 4448, 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460, 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, 4470, 4471, 4472, 4473, 4474, 4475, 4476, 4477, 4478, 4479, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4493, 4494, 4495, 4496, 4497, 4498, 4499, 4500, 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4519, 4520, 4521, 4522, 4523, 4524, 4525, 4526, 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534, 4535, 4536, 4537, 4538, 4539, 4540, 4541, 4542, 4543, 4544, 4545, 4546, 4547, 4548, 4549, 4550, 4551, 4552, 4553, 4554, 4555, 4556, 4557, 4558, 4559, 4560, 4561, 4562, 4563, 4564, 4565, 4566, 4567, 4568, 4569, 4570, 4571, 4572, 4573, 4574, 4575, 4576, 4577, 4578, 4579, 4580, 4581, 4582, 4583, 4584, 4585, 4586, 4587, 4588, 4589, 4590, 4591, 4592, 4593, 4594, 4595, 4596, 4597, 4598, 4599, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4624, 4625, 4626, 4627, 4628, 4629, 4630, 4631, 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639, 4640, 4641, 4642, 4643, 4644, 4645, 4646, 4647, 4648, 4649, 4650, 4651, 4652, 4653, 4654, 4655, 4656, 4657, 4658, 4659, 4660, 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679, 4680, 4681, 4682, 4683, 4684, 4685, 4686, 4687, 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695, 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4717, 4718, 4719, 4720, 4721, 4722, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4731, 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739, 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747, 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755, 4756, 4757, 4758, 4759, 4760, 4761, 4762, 4763, 4764, 4765, 4766, 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4774, 4775, 4776, 4777, 4778, 4779, 4780, 4781, 4782, 4783, 4784, 4785, 4786, 4787, 4788, 4789, 4790, 4791, 4792, 4793, 4794, 4795, 4796, 4797, 4798, 4799, 4800, 4801, 4802, 4803, 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811, 4812, 4813, 4814, 4815, 4816, 4817, 4818, 4819, 4820, 4821, 4822, 4823, 4824, 4825, 4826, 4827, 4828, 4829, 4830, 4831, 4832, 4833, 4834, 4835, 4836, 4837, 4838, 4839, 4840, 4841, 4842, 4843, 4844, 4845, 4846, 4847, 4848, 4849, 4850, 4851, 4852, 4853, 4854, 4855, 4856, 4857, 4858, 4859, 4860, 4861, 4862, 4863, 4864, 4865, 4866, 4867, 4868, 4869, 4870, 4871, 4872, 4873, 4874, 4875, 4876, 4877, 4878, 4879, 4880, 4881, 4882, 4883, 4884, 4885, 4886, 4887, 4888, 4889, 4890, 4891, 4892, 4893, 4894, 4895, 4896, 4897, 4898, 4899, 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, 4925, 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985, 4986, 4987, 4988, 4989, 4990, 4991, 4992, 4993, 4994, 4995, }; } bundle agent test { vars: "list_len" int => length("init.list"); } bundle agent check { classes: "ok" expression => strcmp("4995", "$(test.list_len)"); reports: DEBUG:: "List length should be 4995, and is computed to be $(test.list_len)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/nested_parens_var_ref.cf0000644000000000000000000000170515010704253026312 0ustar00rootroot00000000000000########################################################### # # Test that a variable reference with nested parentheses works # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { meta: "description" -> { "CFE-3242" } string => "Test that a variable reference with nested parentheses works"; vars: "my_array[key(1)]" string => "value"; "value" string => "$(my_array[key(1)])"; } ########################################################### bundle agent check { classes: "ok" and => { isvariable( "test.value" ), strcmp( "$(test.value)", "value") }; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/fncall-invalid-type.x.cf0000644000000000000000000000027515010704253026065 0ustar00rootroot00000000000000body common control { bundlesequence => { test }; } bundle agent test { vars: "mylist" slist => { "a", "b" }; "canonified_$(mylist)" slist => canonify("$(mylist)"); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/unresolved_variables.cf.sub0000644000000000000000000000400615010704253026757 0ustar00rootroot00000000000000# # Unresolved variables end up in reports and files prommises # body common control { bundlesequence => { run, dmi, etc_nologin }; } bundle agent run { classes: "dim_found" expression => regcmp("^[1-9][0-9]*$", $(dim)); vars: "data" string => "PURPLE_DINOSAUR: Ubuntu"; "dim" int => parsestringarray( "lsb", $(data), "\s*#[^\n]*", "\s*:\s+", "15", "4095" ); dim_found:: "PURPLE_DINOSAUR" string => canonify("$(lsb[PURPLE_DINOSAUR][1])"); files: "$(PURPLE_DINOSAUR)" create => "true"; "$(sys.workdir)/state/anotherfile" create => $(PURPLE_DINOSAUR); reports: dim_found:: "$(this.bundle): value = $(PURPLE_DINOSAUR)"; } # inventory DMI decoder, simplified for this test bundle agent dmi { vars: "dmivars" slist => { "PURPLE_DINOSAUR" }; secondpass:: "dmi[$(dmivars)]" string => execresult("echo Not A Dinosaur", "useshell"); classes: "secondpass" expression => "any"; reports: "$(this.bundle): Obtained qualified '$(dmi.dmi[$(dmivars)])'"; # fails "$(this.bundle): Obtained unqualified '$(dmi[$(dmivars)])'"; # fails } # the System::nologin sketch, simplified for this test bundle agent etc_nologin() { vars: secondpass:: "PURPLE_DINOSAUR" string => "$(sys.workdir)/state", policy => "free"; classes: "secondpass" expression => "any"; vars: "etc_nologin" string => "$(PURPLE_DINOSAUR)/etc/nologin"; files: "$(etc_nologin)" create => "true"; reports: "$(etc_nologin)"; } # THIS LAST BUNDLE IS FAILING! # TODO implement skipping of promises that have unresolved variables; ways: # a. scan for dollar-paren and skip if found # -- this will make it impossible to have any dollar-paren strings # b. check if the dollar-paren variable is in any vars promise ... cfengine-3.24.2/tests/acceptance/01_vars/01_basic/this_promiser_ifvarclass.cf0000644000000000000000000000165415010704253027063 0ustar00rootroot00000000000000# Test that this.promiser works in ifvarclass # CFE-2262 (https://northerntech.atlassian.net/browse/CFE-2262) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { files: "$(G.testfile)" create => "true"; } bundle agent test { meta: "description" -> { "redmine#7880", "CFE-2262" } string => "Test that it is possible to use this.promiser in ifvarclass.", meta => { "redmine#7880", "CFE-2262" }; files: # I should be able to use this.promiser to check if the file is a plain # file "$(G.testfile)" delete => tidy, ifvarclass => isplain( "$(this.promiser)" ); } bundle agent check { classes: "ok" not => fileexists( "$(G.testfile)" ); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/os_version_major.cf0000644000000000000000000000450315010704253025331 0ustar00rootroot00000000000000############################################################## # # Test reworked in CFE-3644 to be more dynamic # ############################################################## body common control { bundlesequence => { "test", "check" }; } bundle agent test { meta: any:: "decription" -> { "CFE-3569" } string => "Test for expected values of variable sys.os_version_major"; vars: # Platforms to test any:: "platforms" slist => { "debian", "ubuntu", "redhat", "rhel", "centos", "fedora", "aix", "hpux", "suse", "opensuse", "opensuse_leap", "sles", "solaris", "sunos", "windows", "freebsd", "macos" }; # Regex matching current platforms OS-class with version numbers !solaris&!sunos:: "class_regex" string => format("^(%s)_[0-9]+$", join("|", "platforms")); solaris|sunos:: "class_regex" string => format("^(%s)_[0-9]+_[0-9]+$", join("|", "platforms")); # Regex to extract major version number from OS-class # Edge cases: # - On Solaris/SunOS major version comes second # E.g. Solaris 11 has class "solaris_5_11" any:: "extract_regex" string => ifelse("solaris|sunos", "^[a-z]+_[0-9]+_([0-9]+$)", "opensuse_leap", "^[a-z_]+_([0-9]+)$", "^[a-z]+_([0-9]+)$"); # Find OS-class with version numbers using regex any:: "os_class" string => nth(classesmatching("$(class_regex)"), "0"); # Get extracted major version number any:: "expected" string => nth("version_number", "1"); classes: any:: "regextract_success" expression => regextract("$(extract_regex)", "$(os_class)", "version_number"); } bundle agent check { vars: any:: "defined_classes" slist => classesmatching(".*"); classes: any:: "passed" expression => strcmp("$(test.expected)", "$(sys.os_version_major)"); reports: DEBUG:: "Version number extracted from class: $(test.os_class)"; "Defined classes: $(defined_classes)"; "$(this.promise_filename) Expected: $(test.expected)"; "$(this.promise_filename) Found: $(sys.os_version_major)"; passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/this_promiser_with_readjson.cf0000644000000000000000000000211515010704253027557 0ustar00rootroot00000000000000# Test that this.promiser can be used in a call with readjson # Redmine:4680 (https://cfengine.com/dev/issues/4680) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "cf_promises_validated_mock_data" string => '{ "timestamp": 1393095384 }'; files: "$(G.testfile).cf_promises_validated" create => "true", edit_defaults => empty, edit_line => insert_lines($(cf_promises_validated_mock_data)), comment => "we need example data to parse"; } bundle agent test { vars: "cf_promises_validated" data => readjson("$(G.testfile).$(this.promiser)", 1K); "printable" string => format("%S", "cf_promises_validated"); reports: DEBUG:: "$(printable)"; } bundle agent check { classes: "ok" expression => strcmp("1393095384", $(test.cf_promises_validated[timestamp])); reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/111.cf0000644000000000000000000000240315010704253022252 0ustar00rootroot00000000000000####################################################### # # Check that similar command promises are not skipped # (cf redmine #2182) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### body classes if_touched(x) { visited:: promise_repaired => { "revisited" }; !visited:: promise_repaired => { "visited" }; } ####################################################### bundle agent init { } ####################################################### bundle agent test { commands: "$(G.echo) restart" classes => if_touched("called"); methods: "any" usebundle => call; } bundle agent call { commands: "$(G.echo) restart" classes => if_touched("called"); } ####################################################### bundle agent check { classes: any:: "ok" and => { "visited", "revisited" }; reports: DEBUG.visited:: "visited defined"; DEBUG.revisited:: "revisited defined"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/106.cf0000644000000000000000000000165515010704253022266 0ustar00rootroot00000000000000####################################################### # # Test arrays with list-specified indices (issue 692) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub", "useshell"); } ####################################################### bundle agent check { classes: "ok" not => regcmp(".*Redefinition.*", "$(test.subout)"); reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/qualified_array_with_spaced_index.cf0000644000000000000000000000162515010704253030657 0ustar00rootroot00000000000000####################################################### # # Test that an array variable will resolve when fully # qualified and the index contains spaces # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "array[one two three]" string => "snookie"; } ####################################################### bundle agent check { classes: "ok" expression => strcmp("snookie", "$(test.array[one two three])"); reports: DEBUG:: "array: $(test.array[one two])"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/long_string_from_embedded.cf0000644000000000000000000000613515010704253027137 0ustar00rootroot00000000000000####################################################### # # Test that we don't crash when slist has very long elements # Redmine:3957 (https://cfengine.com/dev/issues/3957) # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { } ####################################################### bundle agent test { vars: "keys" slist => { "ssh-dss YavBsyK3sHDac4Gj4nDbVH9E7OfRPi16DADNOWGKEjWiBB0cCe0UY6xxEgcYuwOOl8HUGqqzLOByvUbo1hENDQldKFt8N7WIb2E9gXFtGm0Sf0NlYARALj1nhLju9hodpGxkr4vKioW1fZQBmBqsI7Ky8ZhzU5p4CAm4uCbxAZuiIhDTAcxj7RlDy3fe9WBw7v0cSIbu8E3zEbPn0VQjTduLCJtFOb5LvUxpxUsHMhHu0xS8DvXIwf7l83cQ0XZtwyIgbF3ZxjIZaPyYhKZRAV1qCze4BlcOerJeVYOiKjpXJlOoBprxy2SfEYVS4Khun0efkmsmBAfllKUUNCqsK9j6oWo7BvNbXqzkl2ULJd6h0LNy9jW8IXnnrfWknLGa7lksVmL3afSAufDAb7yRESaUP5KmcD3ghP3Nvu7fy9hz7nIAPgj2dQOwnFRbkv9Svoi9YmCtvBWYAcwIUVNJBmwXe5j5xJyt5vOyRSI2ooJ9mk69UOCsIM8PEnEXwtHcsg9fDjfu9ChFY2HWZPWeNXH05SATnSyLgclQsZcazhQXPoxZbcqR80mfuRX9ymEzNwZJ1jJUERnj9PZkSInu6mFVRjTaQjg8yvqMGRxWknP8aURCDh5rr4Na23jULVVI66heWOi7nzLqBg5U8GsbLsocM8zBam8bhXfU0KvpBo5wlUtHnDWHoMlS3ktr25ldrp3zLuywhHe5vGUbg2E0gr4xB3oPAyaDa3MGQiVXPfngu5CJhwIXmeN5JtIBA0S46ihg7lQ6IU8kAaRHwhWh3TokoNFOYE8R5i24gpYNF8dgCRGqSZIT5V7wuR3qG1Wau963ILuX8EFOSu7xDc5qnGTem3FwICTpSdnZNqpzRt4Ipqsn4Pa2tFFpHlzDwKFRPS7r8v4QX7acqdTSCUOuZ68GwDRlvHIz5mHUf1XLY3FH2InuWFsonJAZwmEbX5evWXFgyJHFlplQcGJvyNdL0T6oBmbG3ssSMoRnqnsk8XjGWtUyvYoQmOY8HWlMhf4V3v78C4k4TnCbN4LmnDYaDcnXMejrUMYDk6QwW3fdTF5ZyjJMy4ANu2fJfKysZMc1Cc== root@host1", "ssh-dss a58AZSxQlmcq33EBCW1GuhpkYCgUfr7o5A1arQZ2dr8I4kldCF76mpl6o2CFthZs4YUU8LewbIDDPqjhS2WwafTXeMEvPMtmLufk6E5njNy2WQtAnmGc9R21qIteTgikY9ubRCM3hlhzJ1wGSKCsE5oBHDQC0thk1ljJGHzsEl0AuVClkUq3yz4eWAsiRdbD9QY7ddD6zA61aHomuczKU5F0VvyO8gRQmWV7b6lysoUFcMgCPVf3UaDdg7L7vvBVkQN2vGCh9CCJz5OkBShlZVNaAXd5TkKJNmsTuBDscPyxeCBAk8sai69f1NNtTeAyWTtSu1KiqTDvD9aal93MhpZnPdOZzNr7etK4C7HuPD0uFjdvKZy1H55rpwNHnJ4GojqiNG1VvN5bGLa3sSLiKOngtMBCokdtHpZn2eHD7oLUROTIG3ZXqFGGvfKEP5zlpvJz3392n4PDQ7EKuNFPhyNQpVXEIAQEDcmeWMopVTGezLoFJG01hKMPxs5QWF7qetVLi1pCjmlUpqgE8c81WGxvMe7ooMtQbeVNulX3qBC3rZhYKtk0R5AA8JxmxHSLYlLFbtnR1PA97hnRvnvlfk92i7WL1hjJsMl29LOrubi554Dr9N2uVUrCFcPZMK45PY0TiRH82AKFmkM8mbM0rndJxoJobZsqRAGHVIkcS53hxMT69liRxlCyubwcxgDaqmeQnJU2Ug0YyFs1uxt4NT9laJ0CO2IxhkbmGeDGw1FJqKyc8Haov263cFMcB97I3gyNHccsAynQnxpMS1ltTFXalghuochdue4unbq0Ty2PfS4jPMkavBlMYN8UZdnyZHuUhycwBJri1Grv5kf2SP00P6NQhuB8kwjqoTG8ay5fKWvhDrVetd7tPuj4dMouHuDeaLJInc7Cz0S5tQOuMfRhpPqk1E8A0YnuNCyPDNuW75rkXZkxP9cYSVWeDa1wgOyNLZDTzYts82qiu9kxLbZ184jowJ8rru4UB20JRtoehnD2nGU1NfegD1qOBgQHtDuB18xggfvOgvUNXBrQpICSz0JqszpftAgV5TJq1FjOdjUo1kOCFuqqi6C4S0Siho== root@host2",}; } ####################################################### bundle agent check { classes: "ok" expression => "any", comment => "If we made it to here, we didn't crash"; reports: DEBUG:: "$(this.bundle): Got key $(test.keys)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/CFE-2191.cf0000644000000000000000000000177615010704253022753 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent init { vars: "suffix" string => "devel"; } bundle agent test { meta: "description" -> { "CFE-2191" } string => "Test that expansion of a nested variable in another bundle expands to the expected value"; } ########################################################### bundle agent check { vars: "expected" string => "___.___"; "var_devel" string => "___"; methods: "Pass/Fail" # First, init.suffix is expanded (to devel) # Then, $(var_devel) is expanded (to ___) usebundle => dcs_check_strcmp( "$(expected)", "$(var_$(init.suffix)).___", $(this.promise_filename), "no"); reports: DEBUG|EXTRA:: "Expect '$(expected)', got '$(var_$(test.suffix)).___'"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/009.cf0000644000000000000000000000226615010704253022267 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "zero_p" real => "0e2345678"; # Exponent too big, but still zero "zero_n" real => "0e-2345678"; # Exponent too big, but still zero } ####################################################### bundle agent check { classes: "ok" and => { isgreaterthan("$(test.zero_p)", "-0.1"), islessthan("$(test.zero_p)", "0.1"), isgreaterthan("$(test.zero_n)", "-0.1"), islessthan("$(test.zero_n)", "0.1"), }; reports: DEBUG:: "zero_p == $(test.zero_p)"; "zero_n == $(test.zero_n)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/promise_dirname.cf0000644000000000000000000000142215010704253025125 0ustar00rootroot00000000000000# Test $(this.promise_dirname) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { vars: "expected" string => dirname($(this.promise_filename)); } ####################################################### bundle agent test { } ####################################################### bundle agent check { classes: "ok" expression => strcmp($(init.expected), $(this.promise_dirname)); reports: DEBUG:: "$(this.promise_filename) expected dirname $(init.expected), actual $(this.promise_dirname)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/007.x.cf0000644000000000000000000000140015010704253022520 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" real => "e2"; # Not a float } ####################################################### bundle agent check { reports: DEBUG:: "The real variable assignment should fail"; cfengine_3:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/CFE-628.cf0000644000000000000000000000216615010704253022670 0ustar00rootroot00000000000000########################################################### # # Test evaluation order expectations # ########################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default($(this.promise_filename)) }; version => "1.0"; } ########################################################### bundle agent test { meta: "description" -> { "CFE-628" } string => "Test that the output is as expected"; "test_skip_needs_work" -> { "CFE-628" } string => "windows", meta => { "CFE-628" }; } ########################################################### bundle agent check { vars: "cmd" string => "$(sys.cf_agent) -Kf $(this.promise_filename).sub"; methods: "Pass/Fail" usebundle => dcs_passif_output( ".*found_the_file.*", # wanted, ".*didnt_find_the_file.*", # unwanted, "$(cmd)", # command, $(this.promise_filename) ); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/110.cf.sub0000644000000000000000000000052315010704253023042 0ustar00rootroot00000000000000body file control { namespace => "ns110"; } bundle agent pass(given_dummy) { vars: "returned_dummy" string => "$(given_dummy)"; reports: "$(returned_dummy)" bundle_return_value_index => "dummy"; DEBUG:: "ns110:pass: given_dummy = '$(given_dummy)'"; "ns110:pass: returned_dummy = '$(returned_dummy)'"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/os_name_human_not_unknown.cf0000644000000000000000000000166615010704253027232 0ustar00rootroot00000000000000body common control { bundlesequence => { "test", "check" }; } bundle agent test { meta: "description" -> { "CFE-3569" } string => "Make sure sys.os_name_human does not resolve to 'Unknown'"; } bundle agent check { classes: # Check that sys.os_name_human does not resolve to 'Unknown' "check1" expression => not(strcmp("Unknown", "$(sys.os_name_human)")); # Check that sys.os_name_human does not resolve to an empty string "check2" expression => not(strcmp("", "$(sys.os_name_human)")); # Check that sys.os_name_human does not contain 'os_name_human' "check3" expression => not(regcmp("os_name_human", "$(sys.os_name_human)")); "passed" and => { "check1", "check2", "check3" }; reports: DEBUG:: "sys.os_name_human resolved to '$(sys.os_name_human)'"; passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/sysvars.cf0000644000000000000000000000474615010704253023476 0ustar00rootroot00000000000000# Test $(sys.inputdir), $(sys.masterdir), $(sys.libdir), $(sys.bindir), $(sys.failsafe_policy_path), $(sys.update_policy_path), $(sys.local_libdir) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent init { vars: "expected[bindir]" string => "$(sys.workdir)$(const.dirsep)bin"; "expected[default_policy_path]" string => "$(sys.workdir)$(const.dirsep)inputs$(const.dirsep)promises.cf"; "expected[failsafe_policy_path]" string => "$(sys.workdir)$(const.dirsep)inputs$(const.dirsep)failsafe.cf"; "expected[inputdir]" string => "$(sys.workdir)$(const.dirsep)inputs"; "expected[libdir]" string => "$(sys.workdir)$(const.dirsep)inputs$(const.dirsep)lib"; "expected[local_libdir]" string => "lib"; "expected[masterdir]" string => "$(sys.workdir)$(const.dirsep)masterfiles"; "expected[update_policy_path]" string => "$(sys.workdir)$(const.dirsep)inputs$(const.dirsep)update.cf"; # sys.policy_entry variables are the same as this.promise variables in case the cf-agent is with '-f THIS_POLICY_FILENAME' # except that "/./" can appear in some places in this.promise variables "expected[policy_entry_dirname]" string => regex_replace("$(this.promise_dirname)", "/\./", "/", ""); "expected[policy_entry_filename]" string => regex_replace("$(this.promise_filename)", "/\./", "/", ""); "expected[policy_entry_basename]" string => regex_replace("$(this.promise_filename)", ".*/", "", ""); "sysvars" slist => getindices("expected"); } ####################################################### bundle agent test { meta: "test_soft_fail" string => "windows", meta => { "ENT-10257" }; } ####################################################### bundle agent check { classes: "$(init.sysvars)_ok" expression => strcmp("$(sys.$(init.sysvars))", "$(init.expected[$(init.sysvars)])"); "ok" and => { "inputdir_ok", "masterdir_ok", "libdir_ok", "bindir_ok", "default_policy_path_ok", "failsafe_policy_path_ok", "update_policy_path_ok", "local_libdir_ok", "policy_entry_dirname_ok", "policy_entry_filename_ok", "policy_entry_basename_ok" }; reports: DEBUG:: "$(init.sysvars) actual='$(sys.$(init.sysvars))', expected '$(init.expected[$(init.sysvars)])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/110.cf0000644000000000000000000000136015010704253022252 0ustar00rootroot00000000000000# Test that variables can be passed across bundles and namespaces body common control { inputs => { "../../default.cf.sub", "110.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { methods: "namespaced" usebundle => ns110:pass($(init.dummy)), useresult => "nsresult"; } bundle agent check { classes: "ok" expression => strcmp("$(init.dummy)", "$(test.nsresult[dummy])"); reports: DEBUG:: "We passed '$(init.dummy)' to ns110:pass() and it returned '$(test.nsresult[dummy])'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/var_meta_tags_overridden_correctly.cf0000644000000000000000000000271015010704253031074 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { meta: "description" -> { "CFE-2601" } string => "Test that meta tags are correct when a variable is re-defined with new meta tags."; vars: "myvar" string => "first definition tagged with first", meta => { "first" }; # We expect the last definition to win. "myvar" string => "second definition tagged with second", meta => { "second" }; } bundle agent check { vars: "vars_tagged_first" slist => variablesmatching(".*", "first"); "vars_tagged_second" slist => variablesmatching(".*", "second"); reports: DEBUG|EXTRA:: "Running CFEngine $(sys.cf_version)"; "Tagged with first: $(vars_tagged_first)"; "Tagged with second: $(vars_tagged_second)"; "default:init.myvar is NOT tagged with first" if => none("default:init.myvar", vars_tagged_first); "default:init.myvar is only var tagged with second" if => every("default:init.myvar", vars_tagged_second); any:: "$(this.promise_filename) Pass" if => and(none("default:init.myvar", vars_tagged_first), every("default:init.myvar", vars_tagged_second)); "$(this.promise_filename) FAIL" if => not(and(none("default:init.myvar", vars_tagged_first), every("default:init.myvar", vars_tagged_second))); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/fqhost_domain.cf0000644000000000000000000000130615010704253024604 0ustar00rootroot00000000000000############################################################## # # Test default:sys.fqhost with domain CFE-4053 # ############################################################## body common control { domain => "cfengine.com"; bundlesequence => { "check" }; } bundle agent __main__ { methods: "check"; } ############################################################## bundle agent check { reports: DEBUG:: "$(sys.fqhost), $(sys.uqhost).cfengine.com"; any:: "$(this.promise_filename) Pass" if => strcmp( "$(sys.fqhost)", "$(sys.uqhost).cfengine.com" ); "$(this.promise_filename) FAIL" unless => strcmp( "$(sys.fqhost)", "$(sys.uqhost).cfengine.com" ); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/unresolved_variables.cf0000644000000000000000000000136215010704253026171 0ustar00rootroot00000000000000# Redmine#4889: avoid unresolved variables in promiser or attributes body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { } bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -Kf $(this.promise_filename).sub -DAUTO,DEBUG 2>&1 | $(G.grep) PURPLE_DINOSAUR", "useshell"); } bundle agent check { classes: "ok" not => regcmp("PURPLE_DINOSAUR", $(test.subout)); reports: ok.EXTRA:: "The output was OK: $(test.subout)"; !ok.DEBUG:: "The output was NOT OK: $(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/0000755000000000000000000000000015010704253023556 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/namespaced-bundles.cf.sub20000644000000000000000000000036215010704253030475 0ustar00rootroot00000000000000body file control { namespace => "namespaced_bundles_2"; } bundle agent unique { reports: DEBUG:: "$(this.bundle): run"; } bundle agent unique2(justone) { reports: DEBUG:: "$(this.bundle): run($(justone))"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/namespaced-bundles.cf.sub10000644000000000000000000000035515010704253030476 0ustar00rootroot00000000000000body file control { namespace => "namespaced_bundles_1"; } bundle agent unique { reports: DEBUG:: "$(this.bundle): run"; } bundle agent unique2(x,y) { reports: DEBUG:: "$(this.bundle): run($(x), $(y))"; } nested_expansion_namespaced_variables.cf0000644000000000000000000000145015010704253033567 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces# Test that nested variables including namespaces are expanded correctly body common control { inputs => { "../../../default.cf.sub",}; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { meta: "tags" slist => { "redmine6349" }; vars: "dummy" string => "dummy"; } bundle agent check { methods: "Check" usebundle => check2("default:init"); } bundle agent check2(data_bundle) { classes: "ok" expression => strcmp("$($(data_bundle).dummy)", "dummy"); reports: DEBUG:: "Nested: '$(data_bundle).dummy' = $($(data_bundle).dummy)"; "Not Nested: '$(data_bundle).dummy' = $(default:init.dummy)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/nested-expansion-including-namespace.cf0000644000000000000000000000135015010704253033257 0ustar00rootroot00000000000000body common control { inputs => { "../../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { meta: "description" -> { "CFE-1583" } string => "Check that nested expansion with namespaces works"; } bundle agent check { vars: "data_bundle" string => "default:init"; methods: "Pass/FAIL" usebundle => dcs_check_strcmp( "$($(data_bundle).dummy)","dummy", $(this.promise_filename), "no"); reports: "Nested expansion: '$(data_bundle).dummy' = $($(data_bundle).dummy)"; "Not nested expansion: '$(data_bundle).dummy' = $(default:init.dummy)"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/0000755000000000000000000000000015010704253030071 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/2/0000755000000000000000000000000015010704253030232 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/2/main.cf0000644000000000000000000000321415010704253031470 0ustar00rootroot00000000000000# NOTE: This test is nearly identical to ../1/main.cf, the only difference is a # single variable definition body file control { inputs => { "../../../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent init { commands: windows:: "$(G.dos2unix) $(this.promise_dirname)/expected_output.txt" -> { "ENT-10433" }; } bundle agent test { meta: "description" -> { "ENT-8817" } string => "Bundle qualified variables should target the promisers namespace. This shows the case where a variable is set in a bundle of the same name in the default namespace."; vars: "color" string => "#052569"; # THIS IS THE ONLY DIFFERENCE BETWEEN ../1/main.cf methods: "Test Reporting Namespaced Variables" usebundle => example_space:test( $(G.testfile) ); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_diff( "$(this.promise_dirname)/expected_output.txt", $(G.testfile), $(this.promise_filename)); } body file control { namespace => "example_space"; } bundle agent test(file) { vars: "color" string => "#f5821f"; reports: "Unqualified: The color is $(color)" report_to_file => "$(file)"; "Bundle-qualified: The color is $(test.color)" report_to_file => "$(file)"; "Fully-qualified: The color is $(example_space:test.color)" report_to_file => "$(file)"; } expected_output.txt0000644000000000000000000000015715010704253034140 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/2Unqualified: The color is #f5821f Bundle-qualified: The color is #f5821f Fully-qualified: The color is #f5821f cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/3/0000755000000000000000000000000015010704253030233 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/3/main.cf0000644000000000000000000000363615010704253031501 0ustar00rootroot00000000000000# NOTE: This test is nearly identical to ../1/main.cf, the only difference is a # single variable definition body file control { inputs => { "../../../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent my_bundle { vars: "My_Variable" string => "WRONG VARIABLE VALUE"; } bundle agent test { meta: "description" -> { "ENT-10397" } string => concat( "The with attribute should be namespace aware.", "This shows the case where a variable is set in a bundle of a", "different name." ); "test_soft_fail" string => "any", meta => { "ENT-10397" }; methods: "Test Reporting Namespaced Variables" usebundle => example_space:test( $(G.testfile) ); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_diff( "$(this.promise_dirname)/expected_output.txt", $(G.testfile), $(this.promise_filename)); } body file control { namespace => "example_space"; } bundle agent my_bundle { vars: "My_Variable" string => "GOOD VARIABLE VALUE"; } bundle agent test(file) { methods: "My Bundle" usebundle => my_bundle; "write output" usebundle => write_output( $(file) ); } bundle agent write_output(file) { reports: "Bundle-qualified another bundle: The value of my_bundle.My_Variable is $(with)" report_to_file => "$(file)", with => "$(my_bundle.My_Variable)"; "Fully-qualified another bundle: The value of example_space:my_bundle.My_Variable $(with)" report_to_file => "$(file)", with => "$(example_space:my_bundle.My_Variable)"; } expected_output.txt0000644000000000000000000000030015010704253034127 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/3Bundle-qualified another bundle: The value of my_bundle.My_Variable is GOOD VARIABLE VALUE Fully-qualified another bundle: The value of example_space:my_bundle.My_Variable GOOD VARIABLE VALUE cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/1/0000755000000000000000000000000015010704253030231 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/1/main.cf0000644000000000000000000000314015010704253031465 0ustar00rootroot00000000000000# NOTE: This test is nearly identical to ../2/main.cf, the only difference is a # single variable definition body file control { inputs => { "../../../../../default.cf.sub", }; } bundle agent __main__ # If this is the policy entry (cf-agent --file) then this bundle will be run by default. { methods: "bundlesequence" usebundle => default("$(this.promise_filename)"); } bundle agent init { commands: windows:: "$(G.dos2unix) $(this.promise_dirname)/expected_output.txt" -> { "ENT-10433" }; } bundle agent test { meta: "description" -> { "ENT-8817" } string => "Bundle qualified variables should target the promisers namespace. This shows the case where a variable is NOT set in a bundle of the same name in the default namespace."; # NOTE THE ABSENCE OF A VARIABLE DEFINITION HERE methods: "Test Reporting Namespaced Variables" usebundle => example_space:test( $(G.testfile) ); } bundle agent check { methods: "Pass/Fail" usebundle => dcs_check_diff("$(this.promise_dirname)/expected_output.txt", $(G.testfile), $(this.promise_filename)); } body file control { namespace => "example_space"; } bundle agent test(file) { vars: "color" string => "#f5821f"; reports: "Unqualified: The color is $(color)" report_to_file => "$(file)"; "Bundle-qualified: The color is $(test.color)" report_to_file => "$(file)"; "Fully-qualified: The color is $(example_space:test.color)" report_to_file => "$(file)"; } expected_output.txt0000644000000000000000000000015715010704253034137 0ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/bundle_qualified_refs/1Unqualified: The color is #f5821f Bundle-qualified: The color is #f5821f Fully-qualified: The color is #f5821f cfengine-3.24.2/tests/acceptance/01_vars/01_basic/namespaces/namespaced-bundles.cf0000644000000000000000000000143215010704253027622 0ustar00rootroot00000000000000# Test that variables can be passed across bundles and namespaces body common control { inputs => { "../../../default.cf.sub", "namespaced-bundles.cf.sub1", "namespaced-bundles.cf.sub2" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { methods: "1" usebundle => namespaced_bundles_1:unique; "2" usebundle => namespaced_bundles_2:unique; "3" usebundle => namespaced_bundles_1:unique2("a", "b"); "4" usebundle => namespaced_bundles_2:unique2("one value"); } bundle agent check { classes: "ok" expression => "any"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/108.cf0000644000000000000000000000132715010704253022264 0ustar00rootroot00000000000000# Test that variables can be passed across bundles and namespaces body common control { inputs => { "../../default.cf.sub", "108.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { methods: "namespaced" usebundle => ns108:pass($(init.dummy)); } bundle agent check { classes: "ok" expression => strcmp("$(init.dummy)", "$(ns108:pass.passed_dummy)"); reports: DEBUG:: "We passed '$(init.dummy)' to ns108:pass() and it recorded '$(ns108:pass.passed_dummy)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/109.cf0000644000000000000000000000132715010704253022265 0ustar00rootroot00000000000000# Test that variables can be passed across bundles and namespaces body common control { inputs => { "../../default.cf.sub", "109.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } bundle agent test { methods: "namespaced" usebundle => ns109:pass($(init.dummy)); } bundle agent check { classes: "ok" expression => strcmp("$(init.dummy)", "$(ns109:pass.passed_dummy)"); reports: DEBUG:: "We passed '$(init.dummy)' to ns109:pass() and it recorded '$(ns109:pass.passed_dummy)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/002.x.cf0000644000000000000000000000145315010704253022523 0ustar00rootroot00000000000000####################################################### # # Test that a variable cannot be defined twice in the # same promise. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "twice" string => "plus ca change..", int => 42; } ####################################################### bundle agent check { reports: DEBUG:: "Assignment should fail"; cfengine_3: "$(this.promise_filename) Pass"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/013.cf0000644000000000000000000000264215010704253022260 0ustar00rootroot00000000000000####################################################### # # Test that 'classes' body works on 'vars' promises # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "foo" string => execresult("/nonexisting", "noshell"), classes => setclasses("nonexisting_t", "nonexisting_f"); "bar" string => execresult("$(G.true)", "noshell"), classes => setclasses("true_t", "true_f"); } body classes setclasses(t,f) { promise_repaired => { "$(t)" }; promise_kept => { "$(t)" }; repair_failed => { "$(f)" }; repair_denied => { "$(f)" }; repair_timeout => { "$(f)" }; } ####################################################### bundle agent check { classes: "ok" expression => "!nonexisting_f.!nonexisting_t.true_t.!true_f"; reports: DEBUG.nonexisting_t:: "nonexisting_t"; DEBUG.nonexisting_f:: "nonexisting_f"; DEBUG.true_t:: "true_t"; DEBUG.true_f:: "true_f"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/vars_comments_emitted_in_show_vars.cf.sub0000644000000000000000000000020415010704253031711 0ustar00rootroot00000000000000bundle agent main { vars: "test_var" string => "test_var value", comment => "This is a comment about test_var"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/108.cf.sub0000644000000000000000000000041515010704253023051 0ustar00rootroot00000000000000body file control { namespace => "ns108"; } bundle agent pass(given_dummy) { vars: "passed_dummy" string => "$(given_dummy)"; reports: DEBUG:: "ns108:pass: given_dummy = '$(given_dummy)'"; "ns108:pass: passed_dummy = '$(passed_dummy)'"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/0000755000000000000000000000000015010704253023073 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/026.cf0000644000000000000000000000611715010704253023721 0ustar00rootroot00000000000000####################################################### # # Test rrange # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: # Normal order "r1" string => rrange(10,20); "r2" string => rrange("10.1","20.2"); "r3" string => rrange("1.1k","2.2K"); "r4" string => rrange("1.1m","2.2M"); "r5" string => rrange("1.1g","2.2G"); "r6" string => rrange("-20.2",10); "r7" string => rrange("10.1%","20.2%"); # Reverse order "x1" string => rrange(20,10); "x2" string => rrange("20.2","10.1"); "x3" string => rrange("2.2K","1.1k"); "x4" string => rrange("2.2M","1.1m"); "x5" string => rrange("2.2G","1.1g"); "x6" string => rrange("20.2",10); "x7" string => rrange("20.2%","10.1%"); # String equivalent "s1" string => "10.000000,20.000000"; "s2" string => "10.100000,20.200000"; "s3" string => "1100.000000,2252.800000"; "s4" string => "1100000.000000,2306867.200000"; "s5" string => "1100000000.000000,2362232012.800000"; "s6" string => "-20.200000,10.000000"; # Unsure that this is correct behavior... and it do this now anyway "s7" string => "20.200000,10.100000"; } ####################################################### bundle agent check { classes: "ok1" and => { strcmp("$(test.r1)", "$(test.x1)"), strcmp("$(test.r1)", "$(test.s1)"), }; "ok2" and => { strcmp("$(test.r2)", "$(test.x2)"), strcmp("$(test.r2)", "$(test.s2)"), }; "ok3" and => { strcmp("$(test.r3)", "$(test.x3)"), strcmp("$(test.r3)", "$(test.s3)"), }; "ok4" and => { strcmp("$(test.r4)", "$(test.x4)"), strcmp("$(test.r4)", "$(test.s4)"), }; "ok5" and => { strcmp("$(test.r5)", "$(test.x5)"), strcmp("$(test.r5)", "$(test.s5)"), }; "ok6" and => { strcmp("$(test.r6)", "$(test.x6)"), strcmp("$(test.r6)", "$(test.s6)"), }; "ok7" and => { strcmp("$(test.r7)", "$(test.x7)"), strcmp("$(test.r7)", "$(test.s7)"), }; "ok" and => { "ok1", "ok2", "ok3", "ok4", "ok5", "ok6", "ok7" }; reports: DEBUG.!ok1:: "Mismatch 1: '$(test.r1)' '$(test.x1)' '$(test.s1)'"; DEBUG.!ok2:: "Mismatch 2: '$(test.r2)' '$(test.x2)' '$(test.s2)'"; DEBUG.!ok3:: "Mismatch 3: '$(test.r3)' '$(test.x3)' '$(test.s3)'"; DEBUG.!ok4:: "Mismatch 4: '$(test.r4)' '$(test.x4)' '$(test.s4)'"; DEBUG.!ok5:: "Mismatch 5: '$(test.r5)' '$(test.x5)' '$(test.s5)'"; DEBUG.!ok6:: "Mismatch 6: '$(test.r6)' '$(test.x6)' '$(test.s6)'"; DEBUG.!ok7:: "Mismatch 7: '$(test.r7)' '$(test.x7)' '$(test.s7)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/107.cf0000644000000000000000000000205415010704253023715 0ustar00rootroot00000000000000####################################################### # # Test $(this.promise_filename) in body referenced from bundle called from # another file. # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "subout" string => execresult("$(sys.cf_agent) -vKf $(this.promise_filename).sub -DAUTO | grep Q:", "useshell"); } ####################################################### bundle agent check { classes: "default" expression => regcmp(".*default\\.cf.*", "$(test.subout)"); "itself" expression => regcmp(".*107\\.cf.*", "$(test.subout)"); "ok" and => { "!default", "itself" }; reports: DEBUG:: "$(test.subout)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/011.cf0000644000000000000000000000546015010704253023713 0ustar00rootroot00000000000000####################################################### # # Test missing variable expansion consistency # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "foo" int => "42"; "baz[a]" string => "alpha"; "gar" string => "$(missing)"; "bletch" string => "$(gar)"; classes: # Known values should test easily "s_foo" expression => strcmp("$(foo)", "42"); "s_baz_a" expression => strcmp("$(baz[a])", "alpha"); # Missing variable names expand to $(varname) in reports and should # expand to the same value in strcmp... "s_missing" expression => strcmp("$(missing)", "$(const.dollar)(missing)"); "s_baz_b" expression => strcmp("$(baz[b])", "$(const.dollar)(baz[b])"); # We test the rest two ways because we assigned a missing variable to # another variable - first the literal assigned value and then the # expanded version testing for missing vars "s_gar" expression => strcmp("$(gar)", "$(missing)"); "s_gar2" expression => strcmp("$(gar)", "$(const.dollar)(missing)"); "s_bletch" expression => strcmp("$(bletch)", "$(missing)"); "s_bletch2" expression => strcmp("$(bletch)", "$(const.dollar)(missing)"); "good" and => { "s_foo", "s_baz_a", "s_gar", "s_gar2", "s_bletch", "s_bletch2", }; "v_missing" expression => isvariable("missing"); "v_baz" expression => isvariable("baz"); "v_baz_b" expression => isvariable("baz[b]"); "bad" or => { "v_missing", "v_baz", "v_baz_b", "v_baz_x", }; "ok" expression => "good&!bad"; reports: DEBUG.ok:: "Saw exactly what we expected"; DEBUG.!ok:: "Saw unexpected results!!"; DEBUG.v_missing:: "$(const.dollar)missing is a variable, and shouldn't be!"; DEBUG.v_baz:: "$(const.dollar)baz is a variable, and shouldn't be!"; DEBUG.v_baz_b:: "$(const.dollar)baz[b] is a variable, and shouldn't be!"; DEBUG.!s_foo:: "expected $(const.dollar)foo = '42', saw '$(foo)'"; DEBUG.!s_baz_a:: "expected $(const.dollar)baz[a] = 'alpha', saw '$(baz[a])'"; DEBUG.!(s_gar.s_gar2):: "expected $(const.dollar)gar = '$(const.dollar)(missing)', saw '$(gar)'"; DEBUG.!(s_bletch.s_bletch2):: "expected $(const.dollar)bletch = '$(const.dollar)(missing)', saw '$(bletch)'"; } bundle agent check { reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/003.x.cf0000644000000000000000000000142415010704253024156 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" int => "12345678901234567890"; # Integer too big } ####################################################### bundle agent check { reports: DEBUG:: "The int variable assignment should fail"; cfengine_3:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/this_promises_in_command_args.cf0000644000000000000000000000134115010704253031474 0ustar00rootroot00000000000000####################################################### # # Redmine#5959 # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent test { commands: # should expand to "touch testfile touch testfile.2" "$(G.touch) $(G.testfile)" args => "$(this.promiser).2"; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_fileexists("$(G.testfile).2", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/025.cf0000644000000000000000000000507615010704253023723 0ustar00rootroot00000000000000####################################################### # # Test irange # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: # Normal order "r1" string => irange(10,20); "r2" string => irange("10","20"); "r3" string => irange("1k","2K"); "r4" string => irange("1m","2M"); "r5" string => irange("1g","2G"); "r6" string => irange("-20",10); # Reverse order "x1" string => irange(20,10); "x2" string => irange("20","10"); "x3" string => irange("2K","1k"); "x4" string => irange("2M","1m"); "x5" string => irange("2G","1g"); "x6" string => irange(10,"-20"); # String equivalent "s1" string => "10,20"; "s2" string => "10,20"; "s3" string => "1000,2048"; "s4" string => "1000000,2097152"; "s5" string => "1000000000,2147483648"; "s6" string => "-20,10"; } ####################################################### bundle agent check { classes: "ok1" and => { strcmp("$(test.r1)", "$(test.x1)"), strcmp("$(test.r1)", "$(test.s1)"), }; "ok2" and => { strcmp("$(test.r2)", "$(test.x2)"), strcmp("$(test.r2)", "$(test.s2)"), }; "ok3" and => { strcmp("$(test.r3)", "$(test.x3)"), strcmp("$(test.r3)", "$(test.s3)"), }; "ok4" and => { strcmp("$(test.r4)", "$(test.x4)"), strcmp("$(test.r4)", "$(test.s4)"), }; "ok5" and => { strcmp("$(test.r5)", "$(test.x5)"), strcmp("$(test.r5)", "$(test.s5)"), }; "ok6" and => { strcmp("$(test.r6)", "$(test.x6)"), strcmp("$(test.r6)", "$(test.s6)"), }; "ok" and => { "ok1", "ok2", "ok3", "ok4", "ok5", "ok6" }; reports: DEBUG.!ok1:: "Mismatch 1: '$(test.r1)' '$(test.x1)' '$(test.s1)'"; DEBUG.!ok2:: "Mismatch 2: '$(test.r2)' '$(test.x2)' '$(test.s2)'"; DEBUG.!ok3:: "Mismatch 3: '$(test.r3)' '$(test.x3)' '$(test.s3)'"; DEBUG.!ok4:: "Mismatch 4: '$(test.r4)' '$(test.x4)' '$(test.s4)'"; DEBUG.!ok5:: "Mismatch 5: '$(test.r5)' '$(test.x5)' '$(test.s5)'"; DEBUG.!ok6:: "Mismatch 6: '$(test.r6)' '$(test.x6)' '$(test.s6)'"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/107.cf.sub0000644000000000000000000000106615010704253024507 0ustar00rootroot00000000000000# # Test reading single-line list of packages # body common control { inputs => { "../../default.cf", "107.cf.ext" }; bundlesequence => { "g", default("$(this.promise_filename)") }; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { packages: "p" package_version => "", package_architectures => { "" }, package_method => simplepkg("abug"), package_policy => "add", package_select => "=="; } bundle agent check { vars: "dummy" string => "dummy"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/107.cf.ext0000644000000000000000000000071115010704253024512 0ustar00rootroot00000000000000body package_method simplepkg(abug) { package_list_command => "/bin/sh -c 'echo $(this.promise_filename)'"; package_list_update_command => "/bin/sh -c 'echo $(this.promise_filename)'"; package_list_update_ifelapsed => "0"; package_installed_regex => ".*"; package_list_name_regex => ".*"; package_list_version_regex => ".*"; package_list_arch_regex => ".*"; package_add_command => "$(G.false)"; package_delete_command => "$(G.false)"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/staging/002.x.cf0000644000000000000000000000140315010704253024152 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" int => "10.0"; # Not an integer } ####################################################### bundle agent check { reports: DEBUG:: "The int variable assignment should fail"; cfengine_3:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/double_expansion_list_namespace.cf0000755000000000000000000000372515010704253030370 0ustar00rootroot00000000000000############################################################################## # # Test double expansion of list from remote bundle with namespace (ENT-11923) # ############################################################################## body common control { bundlesequence => { "bogus:check" }; } bundle agent test(parent_namespace, parent_bundle) { meta: "description" -> { "ENT-11923" } string => "Test double expansion of list from remote bundle with namespace"; reports: "$($(parent_namespace):$(parent_bundle).str)" comment => "Double expansion of remote string works prior to fix", bundle_return_value_index => "foo"; "$($(parent_namespace):$(parent_bundle).lst)" comment => "But double expansion of remote list does not work prior to fix", bundle_return_value_index => "bar"; "$(bogus:check.lst)" comment => "Single expansion of remote list works prior to fix", bundle_return_value_index => "baz"; } body file control { namespace => "bogus"; } bundle agent check { vars: "str" string => "EXPANDED"; "lst" slist => { "EXPANDED" }; methods: "holder" usebundle => default:test("$(this.namespace)", "$(this.bundle)"), useresult => "ret"; reports: "$(this.promise_filename) Pass" if => and(strcmp("$(ret[foo])", "EXPANDED"), strcmp("$(ret[bar])", "EXPANDED"), strcmp("$(ret[baz])", "EXPANDED")); "$(this.promise_filename) FAIL" unless => and(strcmp("$(ret[foo])", "EXPANDED"), strcmp("$(ret[bar])", "EXPANDED"), strcmp("$(ret[baz])", "EXPANDED")); default:DEBUG:: "$(const.dollar)($(const.dollar)(parent_namespace):$(const.dollar)(parent_bundle).str) => $(ret[foo])"; "$(const.dollar)($(const.dollar)(parent_namespace):$(const.dollar)(parent_bundle).lst) => $(ret[bar])"; "$(const.dollar)(default:check.lst) => $(ret[baz])"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/008.x.cf0000644000000000000000000000141415010704253022526 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" real => "1e2345678"; # Exponent too big } ####################################################### bundle agent check { reports: DEBUG:: "The real variable assignment should fail"; cfengine_3:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/os_name_human.cf0000755000000000000000000000311115010704253024561 0ustar00rootroot00000000000000body common control { bundlesequence => { "test", "check" }; } bundle agent test { meta: "description" -> { "CFE-3569" } string => "Test for expected values of variable sys.os_name_human"; # # Note: # # Order is important, the last variable assignment wins. # E.g. prefer Ubuntu over Debian. # # This test should also succeed if none of the os-classes are defined. # This should be covered in another test. # vars: any:: "actual" string => "$(sys.os_name_human)"; "expected" string => "Unknown"; debian:: "expected" string => "Debian"; ubuntu:: "expected" string => "Ubuntu"; redhat:: "expected" string => "RHEL"; centos:: "expected" string => "CentOS"; fedora:: "expected" string => "Fedora"; aix:: "expected" string => "AIX"; hpux:: "expected" string => "HP-UX"; suse:: "expected" string => "SUSE"; opensuse:: "expected" string => "OpenSUSE"; windows:: "expected" string => "Windows"; freebsd:: "expected" string => "FreeBSD"; macos:: "expected" string => "macOS"; solaris:: "expected" string => "Solaris"; amazon_linux:: "expected" string => "Amazon"; } bundle agent check { classes: "passed" expression => strcmp("$(test.actual)", "$(test.expected)"); reports: DEBUG:: "$(this.promise_filename) Expected: $(test.expected)"; "$(this.promise_filename) Found: $(test.actual)"; passed:: "$(this.promise_filename) Pass"; !passed:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/duplicate_bundles.cf0000644000000000000000000000147115010704253025442 0ustar00rootroot00000000000000body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent test { methods: "one" usebundle => gvar( "x", "one" ); !FAIL:: "two" usebundle => gvar( "y", "two" ); } bundle agent gvar ( name, value ) { vars: "${name}" string => "${value}"; } bundle agent check { classes: "pass_x" expression => strcmp( "one", "${gvar.x}" ); "pass_y" expression => strcmp( "two", "${gvar.y}" ); methods: "" usebundle => dcs_passif_expected("pass_x,pass_y", "", $(this.promise_filename)), inherit => "true"; reports: EXTRA:: "gvar.x => ${gvar.x}"; "gvar.y => ${gvar.y}"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/vars_comments_emitted_in_verbose.cf0000644000000000000000000000137015010704253030560 0ustar00rootroot00000000000000# Test $(sys.inputdir), $(sys.masterdir), $(sys.libdir), $(sys.bindir), $(sys.failsafe_policy_path), $(sys.update_policy_path), $(sys.local_libdir) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; } ####################################################### bundle agent test { meta: "description" string => "Test that comments on variables are emitted in verbose output.", meta => { "CFE-2442" }; } ####################################################### bundle agent check { methods: "" usebundle => dcs_passif_output(".*This is a comment about test_var.*", "", "$(sys.cf_agent) -Kvf $(this.promise_filename).sub", $(this.promise_filename)); } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/005.x.cf0000644000000000000000000000140415010704253022522 0ustar00rootroot00000000000000####################################################### # # Test simple variables failures # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { vars: "ten" real => "1.2e.3"; # Not a float } ####################################################### bundle agent check { reports: DEBUG:: "The real variable assignment should fail"; cfengine_3:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/01_basic/var_expansion_in_meta.cf0000644000000000000000000000222615010704253026323 0ustar00rootroot00000000000000# Test that variables in meta tags are expanded # Redmine:4885 (https://cfengine.com/dev/issues/4885) body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "variables" slist => { "item1", "item2" }; "variable_tag" string => "mytag"; classes: "$(variables)_class" expression => "any", scope => "namespace", meta => { "$(variable_tag)" }; } bundle agent test { vars: "found_classes" slist => classesmatching(".*", $(init.variable_tag)); "joined_found_classes" string => join(",", found_classes); } bundle agent check { vars: "expected_joined_found_classes" string => "item1_class,item2_class"; classes: "ok" expression => strcmp($(expected_joined_found_classes), $(test.joined_found_classes)); reports: DEBUG:: "$(this.promise_filename) Expected: $(expected_joined_found_classes)"; "$(this.promise_filename) Found: $(test.joined_found_classes)"; ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } cfengine-3.24.2/tests/acceptance/01_vars/05_defaults/0000755000000000000000000000000015010704253022171 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/01_vars/05_defaults/basics.cf0000644000000000000000000000210715010704253023747 0ustar00rootroot00000000000000body common control { bundlesequence => { "main" }; } bundle agent main { methods: "example" usebundle => class_default, useresult => "value"; "example" usebundle => no_class_default, useresult => "value"; classes: "fail1" expression => strcmp("$(value[1])", "one"); "fail2" expression => strcmp("$(value[2])", "two"); "fail" or => { "fail1", "fail2" }; "ok" and => { strcmp("$(value[1])", "default"), strcmp("$(value[2])", "default") }; reports: fail1.!ok:: "value 1: $(value[1])"; fail2.!ok:: "value 2: $(value[2])"; !fail.ok:: "$(this.promise_filename) Pass"; fail.!ok:: "$(this.promise_filename) FAIL"; } bundle agent class_default { vars: "a" string => "one"; defaults: "a" string => "default", if_match_regex => "one"; classes: "test" expression => "any"; reports: "${a}" bundle_return_value_index => "1"; } bundle agent no_class_default { vars: "b" string => "two"; defaults: "b" string => "default", if_match_regex => "two"; reports: "${b}" bundle_return_value_index => "2"; } cfengine-3.24.2/tests/acceptance/dcs.cf.sub0000644000000000000000000010372315010704253020464 0ustar00rootroot00000000000000######################################################################## # Acceptance test framework. # # See README for details about writing test cases. ######################################################################## bundle common G { vars: windows:: "cwd" string => execresult("C:\windows\system32\cmd.exe /C cd", "noshell"), meta => { "simulate_safe" }; # Use for redirection, not as a real file. "dev_null" string => "nul"; "exeext" slist => { ".exe", ".bat" }; !windows:: "cwd" string => execresult("/bin/pwd 2>/dev/null || /usr/bin/pwd", "useshell"), meta => { "simulate_safe" }; # Use for redirection, not as a real file. "dev_null" string => "/dev/null"; "exeext" string => ""; any:: # General commands. "cmds" slist => { "date", "dd", "dos2unix", "diff", "cat", "colordiff", "cp", "echo", "egrep", "env", "false", "grep", "gsed", # will override sed on solaris hosts "gzip", "hexdump", "ln", "ls", "mkdir", "mkfifo", "mkgroup", # AIX equivalent of groupadd "mock_package_manager", "mv", "no_fds", "od", "perl", "printf", "ps", "psexec", "pwd", "rm", "sed", "seq", "sh", "sleep", "sort", "stat", "sudo", "tee", "touch", "true", "yes", "wc", }; # Special cases. "make_cmds" slist => { "gmake", "make" }; # rmgroup is AIX equivalent of groupdel "sbin_cmds" slist => { "rmgroup", "groupadd", "groupdel", "useradd", "userdel", "usermod" }; any:: "paths[tests]" string => "$(this.promise_dirname)"; solaris:: "paths[usr_xpg4_bin]" string => "/usr/xpg4/bin"; "paths[usr_ucb_sparcv7]" string => "/usr/ucb/sparcv7"; "paths[opt_csw_bin]" string => "/opt/csw/bin"; "paths[usr_sfw_bin]" string => "/usr/sfw/bin"; !windows:: "paths[bin]" string => "/bin"; "paths[usr_bin]" string => "/usr/bin"; "paths[usr_sbin]" string => "/usr/sbin"; "paths[usr_local_bin]" string => "/usr/local/bin"; "paths[usr_contrib_bin]" string => "/usr/contrib/bin"; windows:: "paths[msys64_usr_bin]" string => "c:\\msys64\\usr\\bin"; "paths[temp_msys64_usr_bin]" string => "d:\\a\\_temp\\msys64\\usr\\bin"; "paths[tool_wrappers]" string => "$(this.promise_dirname)\\tool_wrappers"; any:: "paths_indices" slist => getindices("paths"); # dereferenced path of the executable "deref_paths[$(paths[$(paths_indices)])][$(cmds)$(exeext)]" string => filestat("$(paths[$(paths_indices)])$(const.dirsep)$(cmds)$(exeext)", "linktarget"); classes: # General commands. "$(paths_indices)_$(cmds)$(exeext)" expression => fileexists("$(deref_paths[$(paths[$(paths_indices)])][$(cmds)$(exeext)])"); "has_$(cmds)" expression => fileexists("$(deref_paths[$(paths[$(paths_indices)])][$(cmds)$(exeext)])"), scope => "namespace"; # Special cases. "$(paths_indices)_$(sbin_cmds)$(exeext)" expression => fileexists("$(paths[$(paths_indices)])$(const.dirsep)$(sbin_cmds)$(exeext)"); "$(paths_indices)_$(make_cmds)$(exeext)" expression => fileexists("$(paths[$(paths_indices)])$(const.dirsep)$(make_cmds)$(exeext)"); "has_make" expression => fileexists("$(paths[$(paths_indices)])$(const.dirsep)$(make_cmds)$(exeext)"), scope => "namespace"; "want_color" expression => strcmp(getenv("CFENGINE_COLOR", 4k), "1"); "have_colordiff" expression => fileexists($(colordiff)); vars: # General commands. "$(cmds)" string => "$(paths[$(paths_indices)])$(const.dirsep)$(cmds)$(exeext)", ifvarclass => canonify("$(paths_indices)_$(cmds)$(exeext)"); # Special cases. "$(sbin_cmds)" string => "$(paths[$(paths_indices)])$(const.dirsep)$(sbin_cmds)$(exeext)", ifvarclass => canonify("$(paths_indices)_$(sbin_cmds)$(exeext)"); # gmake has higher priority, so should come last. "make" string => "$(paths[$(paths_indices)])$(const.dirsep)make$(exeext)", ifvarclass => canonify("$(paths_indices)_make$(exeext)"); "make" string => "$(paths[$(paths_indices)])$(const.dirsep)gmake$(exeext)", ifvarclass => canonify("$(paths_indices)_gmake$(exeext)"); # on solaris, gsed works more like GNU sed, such as having `-i` option solaris:: "sed" string => "$(G.gsed)"; # on AIX groupdel is rmgroup and groupadd is mkgroup aix:: "groupdel" string => "$(G.rmgroup)"; "groupadd" string => "$(G.mkgroup)"; want_color.have_colordiff:: "diff_maybecolor" string => $(colordiff); !want_color|!have_colordiff:: "diff_maybecolor" string => $(diff); classes: "temp_declared" not => strcmp(getenv("TEMP", "65536"), ""); vars: "etc" string => "$(this.promise_dirname)$(const.dirsep)dummy_etc"; "etc_motd" string => "$(this.promise_dirname)$(const.dirsep)dummy_etc$(const.dirsep)motd"; "etc_passwd" string => "$(this.promise_dirname)$(const.dirsep)dummy_etc$(const.dirsep)passwd"; "etc_shadow" string => "$(this.promise_dirname)$(const.dirsep)dummy_etc$(const.dirsep)shadow"; "etc_group" string => "$(this.promise_dirname)$(const.dirsep)dummy_etc$(const.dirsep)group"; # Use instead of /dev/null when you need a real empty file to open. "etc_null" string => "$(this.promise_dirname)$(const.dirsep)dummy_etc$(const.dirsep)null"; "write_args_sh" string => "$(this.promise_dirname)/write_args.sh"; temp_declared:: "testroot" string => getenv("TEMP", "65535"); "testdir" string => concat(getenv("TEMP", "65535"), "$(const.dirsep)TESTDIR.cfengine"); "testfile" string => concat(getenv("TEMP", "65535"), "$(const.dirsep)TEST.cfengine"); !temp_declared:: "testroot" string => "$(const.dirsep)tmp"; "testdir" string => "$(const.dirsep)tmp$(const.dirsep)TESTDIR.cfengine"; "testfile" string => "$(const.dirsep)tmp$(const.dirsep)TEST.cfengine"; classes: "using_fakeroot" expression => regcmp(".+", getenv("FAKEROOTKEY", "10")); } bundle common dcs_strings { vars: "multiline_potatoes" string => "BEGIN One potato Two potato Three potatoes Four END"; "multiline_potatoes_lesser" string => "BEGIN One potato Three potatoes Four END"; } bundle agent paths_init(filename) { classes: "filename_absolute" expression => regcmp("/.*", "$(filename)"); } bundle agent paths_absolute(filename) { vars: filename_absolute:: "input_file" string => "$(filename)"; !filename_absolute:: "input_file" string => "$(G.cwd)/$(filename)"; } bundle agent default(filename) { classes: "have_test_run_$(bundles)" expression => "any"; vars: "tests" slist => { "default:init", "default:test", "default:check", "default:destroy" }; "bundles" slist => bundlesmatching("default:(init|test|check|destroy)"); files: "$(G.testdir)/." create => "true"; methods: "any" usebundle => collect_stories_metadata; "any" usebundle => test_precheck; proceed_with_test:: "any" usebundle => test_run("$(filename)"), inherit => "true"; reports: EXTRA.verbose_mode:: "$(this.bundle): found runnable bundle $(bundles)"; } bundle agent test_run(filename) { vars: methods: "any" usebundle => paths_init("$(filename)"); "any" usebundle => paths_absolute("$(filename)"); AUTO:: "any" usebundle => "$(default.tests)", ifvarclass => canonify("have_test_run_$(default.tests)"); reports: !AUTO:: "# You must either specify '-D AUTO' or run the following commands:"; "cf-agent -f .$(const.dirsep)$(filename) -b $(tests)"; } bundle agent collect_stories_metadata { vars: "test_meta_vars" slist => { "description", "story_id", "covers" }; classes: "have_$(test_meta_vars)" expression => isvariable("test_meta.$(test_meta_vars)"); reports: have_description:: "test description: $(test_meta.description)"; have_story_id:: "test story_id: $(test_meta.story_id)"; have_covers:: "test covers: $(test_meta.covers)"; } bundle agent test_precheck { vars: "fail_types" slist => { "suppress", "soft", "flakey" }; "test_skip_unsupported" slist => variablesmatching(".*_meta\.test_skip_unsupported"); "test_skip_needs_work" slist => variablesmatching(".*_meta\.test_skip_needs_work"); "test_$(fail_types)_fail" slist => variablesmatching(".*_meta\.test_$(fail_types)_fail"); "test_$(fail_types)_fail_metatags" slist => getvariablemetatags("$(test_$(fail_types)_fail)"); "test_$(fail_types)_fail_ticket" slist => filter("(redmine|CFE-|ENT-|ARCHIVE-|QA-).*", "test_$(fail_types)_fail_metatags", "true", "false", 1); classes: "test_skip_unsupported_set" expression => some(".*", "test_skip_unsupported"); "test_skip_needs_work_set" expression => some(".*", "test_skip_needs_work"); "test_$(fail_types)_fail_set" expression => some(".*", "test_$(fail_types)_fail"); "test_$(fail_types)_fail_ticket_set" expression => some(".*", "test_$(fail_types)_fail_ticket"); "test_skip_unsupported_match" and => { "test_skip_unsupported_set", "$($(test_skip_unsupported))" }; "test_skip_needs_work_match" and => { "test_skip_needs_work_set", "$($(test_skip_needs_work))" }; "test_$(fail_types)_fail_match" and => { "test_$(fail_types)_fail_set", "$($(test_$(fail_types)_fail))" }; "proceed_with_test" and => { "!test_skip_unsupported_match", "!test_skip_needs_work_match" }, scope => "namespace"; reports: test_skip_unsupported_match:: "$(this.promise_filename) Skip/unsupported"; test_skip_needs_work_match:: "$(this.promise_filename) Skip/needs_work"; test_suppress_fail_match.test_suppress_fail_ticket_set:: "$(this.promise_filename) XFAIL/$(test_suppress_fail_ticket)"; test_suppress_fail_match.!test_suppress_fail_ticket_set:: "$(this.promise_filename) FAIL/no_ticket_number"; test_soft_fail_match.test_soft_fail_ticket_set:: "$(this.promise_filename) SFAIL/$(test_soft_fail_ticket)"; test_soft_fail_match.!test_soft_fail_ticket_set:: "$(this.promise_filename) FAIL/no_ticket_number"; test_flakey_fail_match.test_flakey_fail_ticket_set:: "$(this.promise_filename) FLAKEY/$(test_flakey_fail_ticket)"; test_flakey_fail_match.!test_flakey_fail_ticket_set:: "$(this.promise_filename) FAIL/no_ticket_number"; } ####################################################### bundle agent dcs_sort(infile, outfile) { commands: # Enforce byte sort order with LC_ALL. "$(G.env) LC_ALL=C $(G.sort) $(infile) > $(outfile)" contain => in_shell; } bundle agent dcs_check_state(bundlename, expected_file, test) { vars: "state" data => bundlestate($(bundlename)); methods: "" usebundle => file_make("$(G.testdir)/template", "{{%state}}"); "" usebundle => file_make("$(G.testdir)/actual", ""); "any" usebundle => dcs_check_state_prep(@(state)); "any" usebundle => dcs_check_diff_expected("$(G.testdir)/actual", $(expected_file), $(test), "no"); } bundle agent dcs_check_state_prep(state_container) { files: "$(G.testdir)/actual" create => "true", edit_template => "$(G.testdir)/template", template_data => mergedata('{ "state": state_container }'), template_method => "mustache"; } bundle agent dcs_check_diff(file1, file2, test) # @brief Pass if two files do not differ. { methods: "any" usebundle => dcs_check_diff_expected($(file1), $(file2), $(test), "no"); } bundle agent dcs_if_diff(file1, file2, pass_class, fail_class) { methods: "any" usebundle => dcs_if_diff_expected($(file1), $(file2), "no", $(pass_class), $(fail_class)); } bundle agent sorted_check_diff(file1, file2, test) { methods: "any" usebundle => dcs_sort("$(file1)", "$(file1).sort"); "any" usebundle => dcs_sort("$(file2)", "$(file2).sort"); "any" usebundle => dcs_check_diff_expected("$(file1).sort", "$(file2).sort", $(test), "no"); } bundle agent xml_check_diff(file1, file2, test, expected_difference) { vars: DEBUG.check_ready.!no_difference:: "file1r" string => execresult("$(G.cwd)/xml-c14nize $(file1)", "noshell"), meta => { "simulate_safe" }; "file2r" string => execresult("$(G.cwd)/xml-c14nize $(file2)", "noshell"), meta => { "simulate_safe" }; DEBUG.check_ready.!no_difference.has_hexdump:: "file1h" string => execresult("$(G.hexdump) -C $(file1)", "useshell"), meta => { "simulate_safe" }; "file2h" string => execresult("$(G.hexdump) -C $(file2)", "useshell"), meta => { "simulate_safe" }; DEBUG.check_ready.!no_difference.!has_hexdump:: "file1h" string => execresult("$(G.od) -c $(file1)", "useshell"), meta => { "simulate_safe" }; "file2h" string => execresult("$(G.od) -c $(file2)", "useshell"), meta => { "simulate_safe" }; DEBUG.check_ready.!no_difference.has_unified_diff:: "diffu" string => execresult("$(G.diff_maybecolor) -u $(file2) $(file1) 2>$(G.dev_null)", "useshell"), meta => { "simulate_safe" }; DEBUG.check_ready.!no_difference.!has_unified_diff:: "diffu" string => execresult("$(G.diff_maybecolor) -c $(file2) $(file1) 2>$(G.dev_null)", "useshell"), meta => { "simulate_safe" }; classes: "has_unified_diff" expression => returnszero( "$(G.diff_maybecolor) -u $(G.etc_null) $(G.etc_null) >$(G.dev_null) 2>&1", "useshell"), meta => { "simulate_safe" }; c14n_files_created:: "no_difference" expression => returnszero( "$(G.diff_maybecolor) $(G.testfile).default-xml-check-diff-1 $(G.testfile).default-xml-check-diff-2 >$(G.dev_null) 2>&1", "useshell"), meta => { "simulate_safe" }; "expected_difference" expression => strcmp("$(expected_difference)", "yes"); "check_ready" expression => "any"; commands: "$(G.cwd)/xml-c14nize $(file1) > $(G.testfile).default-xml-check-diff-1" contain => in_shell; "$(G.cwd)/xml-c14nize $(file2) > $(G.testfile).default-xml-check-diff-2" contain => in_shell, classes => if_ok("c14n_files_created"); reports: check_ready.no_difference.!expected_difference:: "$(test) Pass"; check_ready.!no_difference.expected_difference:: "$(test) Pass"; check_ready.!no_difference.!expected_difference:: "$(test) FAIL"; check_ready.no_difference.expected_difference:: "$(test) FAIL"; DEBUG.check_ready.!no_difference.!expected_difference:: "$(file1) and $(file2) differ:"; "$(file1): <$(file1r)>"; "$(file2): <$(file2r)>"; "dump $(file1): $(file1h)"; "dump $(file2): $(file2h)"; "$(diffu)"; DEBUG.check_ready.no_difference.expected_difference:: "Contents of $(file1) and $(file) is the same."; } bundle agent dcs_report_generic_classes(x) { vars: "choices" slist => { "repaired", "failed", "denied", "timeout", "kept" }; reports: DEBUG:: "class '$(x)_$(choices)' was defined" ifvarclass => '$(x)_$(choices)'; "class '$(x)_$(choices)' was NOT defined" ifvarclass => '!$(x)_$(choices)'; } bundle agent dcs_generic_classes_to_string(x) { vars: "choices" slist => { "repaired", "failed", "denied", "timeout", "kept" }; "s[$(choices)]" string => "$(x)_$(choices)", ifvarclass => '$(x)_$(choices)'; "found_unsorted" slist => getvalues(s); "found" slist => sort(found_unsorted, "lex"); "found_str" string => format("%S", found); reports: "$(found_str)" bundle_return_value_index => "str"; } # These set/clear global classes, so they can be tested in another bundle body classes dcs_all_classes(prefix) { promise_kept => { "$(prefix)_promise_kept" }; promise_repaired => { "$(prefix)_promise_repaired" }; repair_failed => { "$(prefix)_repair_failed" }; repair_denied => { "$(prefix)_repair_denied" }; repair_timeout => { "$(prefix)_repair_timeout" }; cancel_kept => { "$(prefix)_cancel_kept" }; cancel_repaired => { "$(prefix)_cancel_repaired" }; cancel_notkept => { "$(prefix)_cancel_notkept" }; } bundle agent dcs_all_negative_classes(prefix) { # These must be global classes so they can be tested in another bundle # We set them here, so they can be (possibly) cleared later classes: "$(prefix)_cancel_kept" expression => "any", scope => "namespace"; "$(prefix)_cancel_repaired" expression => "any", scope => "namespace"; "$(prefix)_cancel_notkept" expression => "any", scope => "namespace"; } bundle agent dcs_all_classes_to_string(prefix) { vars: "classes_all" slist => classesmatching("$(prefix)_.*(kept|notkept|failed|denied|repaired|timeout)"); "classes" slist => sort(classes_all, "lex"); "found_str" string => format("%S", classes); reports: "$(found_str)" bundle_return_value_index => "str"; } bundle agent dcs_check_diff_expected(file1, file2, test, expected_difference) { methods: "any" usebundle => dcs_if_diff_expected($(file1), $(file2), $(expected_difference), "dcs_check_diff_expected_pass_class", "dcs_check_diff_expected_fail_class"); reports: dcs_check_diff_expected_pass_class:: "$(test) Pass"; dcs_check_diff_expected_fail_class:: "$(test) FAIL"; } bundle agent dcs_if_diff_expected(file1, file2, expected_difference, pass_class, fail_class) { vars: DEBUG.check_ready.!no_difference:: "file1r" string => readfile("$(file1)", "4096"); "file2r" string => readfile("$(file2)", "4096"); (EXTRA|DEBUG_HEXDUMP).check_ready.!no_difference.has_hexdump:: "file1h" string => execresult("$(G.hexdump) -C $(file1)", "useshell"), meta => { "simulate_safe" }; "file2h" string => execresult("$(G.hexdump) -C $(file2)", "useshell"), meta => { "simulate_safe" }; (EXTRA|DEBUG_HEXDUMP).check_ready.!no_difference.!has_hexdump:: "file1h" string => execresult("$(G.od) -c $(file1)", "useshell"), meta => { "simulate_safe" }; "file2h" string => execresult("$(G.od) -c $(file2)", "useshell"), meta => { "simulate_safe" }; DEBUG.check_ready.!no_difference.has_unified_diff:: "diffu" string => execresult("$(G.diff_maybecolor) -u $(file2) $(file1) 2>$(G.dev_null)", "useshell"), meta => { "simulate_safe" }; DEBUG.check_ready.!no_difference.!has_unified_diff:: "diffu" string => execresult("$(G.diff_maybecolor) -c $(file2) $(file1) 2>$(G.dev_null)", "useshell"), meta => { "simulate_safe" }; classes: "has_unified_diff" expression => returnszero( "$(G.diff_maybecolor) -u $(G.etc_null) $(G.etc_null) >$(G.dev_null) 2>&1", "useshell"), meta => { "simulate_safe" }; "no_difference" expression => returnszero( "$(G.diff_maybecolor) $(file1) $(file2) >$(G.dev_null) 2>&1", "useshell"), meta => { "simulate_safe" }; "expected_difference" expression => strcmp("$(expected_difference)", "yes"); "check_ready" expression => "any"; check_ready.no_difference.!expected_difference:: "$(pass_class)" expression => "any", scope => "namespace"; check_ready.!no_difference.expected_difference:: "$(pass_class)" expression => "any", scope => "namespace"; check_ready.!no_difference.!expected_difference:: "$(fail_class)" expression => "any", scope => "namespace"; check_ready.no_difference.expected_difference:: "$(fail_class)" expression => "any", scope => "namespace"; reports: DEBUG.check_ready.!no_difference.!expected_difference:: "FILES DIFFER BUT SHOULD BE THE SAME"; "CONTENTS OF $(file1): $(file1r)"; "CONTENTS OF $(file2): $(file2r)"; "$(diffu)"; (DEBUG_HEXDUMP|EXTRA).check_ready.!no_difference.!expected_difference:: "hexdump $(file1): $(file1h)"; "hexdump $(file2): $(file2h)"; DEBUG.check_ready.no_difference.expected_difference:: "Contents of $(file1) and $(file) are the same but should differ."; EXTRA:: "Diff command: $(G.diff_maybecolor) -u $(file2) $(file1) 2>$(G.dev_null)"; } bundle agent dcs_sleep(t) { commands: "$(G.perl) -e 'sleep $(t)'"; reports: EXTRA:: "Sleeping $(t) seconds"; } ####################################################### # Uses rm -rf instead of selecting and deleting files to avoid side-effects in # tests due to problems in file deleletion promises. bundle agent dcs_fini(file) { commands: "$(G.rm) -rf $(file)*" contain => dcs_useshell; "$(G.rm) -rf $(sys.statedir)/cf_state.*" contain => dcs_useshell; reports: EXTRA:: "$(this.bundle): deleting $(file) with $(G.rm) -rf"; } bundle agent dcs_copyfile(from, to) { files: "$(to)" create => "true", copy_from => dcs_sync($(from)); reports: EXTRA:: "$(this.bundle): copying file $(from) to $(to)"; } body copy_from dcs_sync(f) { source => "$(f)"; purge => "true"; preserve => "false"; type_check => "false"; compare => "digest"; } body contain dcs_useshell { useshell => "true"; chdir => "/"; } bundle agent dcs_runagent(args) { commands: debug_mode:: "$(sys.cf_agent) -Kdf $(args)"; verbose_mode:: "$(sys.cf_agent) -Kvf $(args)"; inform_mode:: "$(sys.cf_agent) -KIf $(args)"; !debug_mode.!verbose_mode.!inform_mode:: "$(sys.cf_agent) -Kf $(args)"; } ####################################################### # Test based on whether two strings are the same bundle agent dcs_check_strcmp(strA, strB, test, expected_difference) { classes: "equal" expression => strcmp($(strA), $(strB)); "expected_difference" or => { strcmp($(expected_difference), "yes"), strcmp($(expected_difference), "true") }; "__passif" xor => { "equal", "expected_difference" }; reports: EXTRA|!__passif:: "$(this.bundle): STRING A: '$(strA)'"; "$(this.bundle): STRING B: '$(strB)'"; __passif:: "$(test) Pass"; !__passif:: "$(test) FAIL"; } bundle agent dcs_check_diff_elements( setA, setB, test, expected_difference) # @brief Test that there is or is not a difference between two lists or data containers elements (order elements does not matter) # # **Example:** # ``` # vars: # "l1" slist => { "A", "three" }; # "l2" slist => { "three", "A" }; # "d1" data => '[ "three", "three" ]'; # # methods: # "Pass/FAIL" # usebundle => dcs_check_diff_elements( @(l1), # First set of elements # @(l2), # Second set of elements # $(this.promise_filename), # Full path to test policy file # "no"); # Expected difference in elements # "Pass/FAIL" # usebundle => dcs_check_diff_elements( @(l1), # First set of elements # @(d1), # Second set of elements # $(this.promise_filename), # Full path to test policy file # "yes"); # Expected difference in elements # ``` { vars: "length_A" int => length( setA ); "length_B" int => length( setB ); "difference_A_B" slist => difference( setA, setB ); "difference_B_A" slist => difference( setB, setA ); classes: "_pass_same_length" expression => eval( "$(length_A) == $(length_B)", class, infix ); "_pass_no_elements_in_setA_that_are_not_in_setB" expression => islessthan( length( difference_A_B ), 1 ); "_pass_no_elements_in_setB_that_are_not_in_setA" expression => islessthan( length( difference_B_A ), 1 ); "__passif" and => { "_pass_same_length", "_pass_no_elements_in_setA_that_are_not_in_setB", "_pass_no_elements_in_setB_that_are_not_in_setA"}; reports: DEBUG|EXTRA:: # We print each element of the list out individually on versions that didn't # have the with attribute. No great way to specify a version less than a # cfengine version. "setA: $(setA)" if => eval( "$(sys.cf_version_minor) < 11", class, infix ); "setB: $(setB)" if => eval( "$(sys.cf_version_minor) < 11", class, infix ); @if minimum_version(3.11) "setA: $(with)" with => join( ", ", setA ); "setB: $(with)" with => join( ", ", setB ); @endif "setA and setB have the same number of elements" if => "_pass_same_length"; "setA and setB do not have the same number of elements" if => not("_pass_same_length"); "setA has $(length_A) elements and setB has $(length_B) ements" if => not("_pass_same_length"); "There are no elements in setA that are not in setB" if => "_pass_no_elements_in_setA_that_are_not_in_setB"; "Element in setA that is not in setB: $(difference_A_B)" if => not( "_pass_no_elements_in_setA_that_are_not_in_setB" ); "There are no elements in setB that are not in setA" if => "_pass_no_elements_in_setB_that_are_not_in_setA"; "Element in setB that is not in setA: $(difference_B_A)" if => not( "_pass_no_elements_in_setB_that_are_not_in_setA" ); __passif:: "$(test) Pass"; !__passif:: "$(test) FAIL"; } ####################################################### # Test based on whether a string matches a regular expression bundle agent dcs_check_regcmp(regex, thestring, test, expected_mismatch) # @brief Check if `regex` matches `thestring` Pass if they match, unless `expected_mismatch` is `true|yes`, in which case, FAIL # @param regex The regular expression to check `thestring` against # @param thestring The string to test with `regex` # @param test The path to the test being run # @param expected_mismatch When `yes|true` the test will Pass if `regex` does not match `thestring` { classes: "matched" expression => regcmp($(regex), $(thestring)); "expected_mismatch" or => { strcmp($(expected_mismatch), "yes"), strcmp($(expected_mismatch), "true") }; "__passif" xor => { "matched", "expected_mismatch" }; reports: EXTRA|!__passif:: "$(this.bundle): REGEX: '$(regex)'"; "$(this.bundle): STRING TO MATCH: '$(thestring)'"; __passif:: "$(test) Pass"; !__passif:: "$(test) FAIL"; } ####################################################### # Pass the test if class bundle agent dcs_passif(classname, test) { reports: "$(test) Pass" ifvarclass => $(classname); "$(test) FAIL" ifvarclass => not($(classname)); EXTRA:: "$(this.bundle): passing based on class '$(classname)'" ifvarclass => $(classname); DEBUG:: "$(this.bundle): failing based on class '$(classname)'" ifvarclass => not($(classname)); } bundle agent dcs_pass(test) { reports: "$(test) Pass"; EXTRA:: "$(this.bundle): Explicitly passing..."; } bundle agent dcs_fail(test) { reports: "$(test) FAIL"; EXTRA:: "$(this.bundle): Explicitly failing..."; } bundle agent dcs_wait(test, seconds) { reports: "$(test) Wait/$(seconds)"; EXTRA:: "$(this.bundle): Explicitly waiting $(seconds) seconds..."; } bundle agent dcs_passif_fileexists(file, test) { classes: "__passif" expression => fileexists($(file)); methods: "" usebundle => dcs_passif("__passif", $(test)), inherit => "true"; reports: DEBUG.!__passif:: "$(this.bundle): $(file) did not exist!"; EXTRA.__passif:: "$(this.bundle): $(file) exists."; } bundle agent dcs_passif_file_absent(file, test) { classes: "__passif" not => fileexists($(file)); methods: "" usebundle => dcs_passif("__passif", $(test)), inherit => "true"; reports: DEBUG.__passif:: "$(this.bundle): $(file) did not exist."; EXTRA.!__passif:: "$(this.bundle): $(file) exists!"; } bundle agent dcs_passif_expected(expected, not_expected, test) { vars: "ex" slist => splitstring($(expected), ",", 1000); "notex" slist => splitstring($(not_expected), ",", 1000); "e[$(ex)]" string => $(ex); "e[$(notex)]" string => "!$(notex)"; "classes" slist => getvalues(e); classes: "__passif" and => { @(classes) }; methods: "" usebundle => dcs_passif("__passif", $(test)), inherit => "true"; reports: DEBUG:: "$(this.bundle): bad: $(ex) was NOT defined" ifvarclass => "!$(ex)"; "$(this.bundle): bad: $(notex) WAS defined" ifvarclass => "$(notex)"; EXTRA:: "$(this.bundle): good: $(ex) WAS defined" ifvarclass => "$(ex)"; "$(this.bundle): good: $(notex) was NOT defined" ifvarclass => "!$(notex)"; } ####################################################### bundle agent dcs_passif_output(wanted, unwanted, command, test) { vars: "subout" string => execresult($(command), "useshell"), meta => { "simulate_safe" }; classes: "__passif_output_unwanted" expression => regcmp($(unwanted), $(subout)); "__passif_output_wanted" expression => regcmp($(wanted), $(subout)); methods: "" usebundle => dcs_passif_expected("__passif_output_wanted", # expected "__passif_output_unwanted", # not expected $(test)), inherit => "true"; reports: DEBUG:: "$(this.bundle): bad: '$(wanted)' was NOT found in the output of '$(command)'" ifvarclass => "!__passif_output_wanted"; "$(this.bundle): bad: '$(unwanted)' WAS found in the output of '$(command)'" ifvarclass => "__passif_output_unwanted"; EXTRA:: "$(this.bundle): good: '$(wanted)' WAS found in the output of '$(command)'" ifvarclass => "__passif_output_wanted"; "$(this.bundle): good: '$(unwanted)' was NOT found in the output of '$(command)'" ifvarclass => "!__passif_output_unwanted"; DEBUG:: "$(this.bundle): the output of command '$(command)' was: '$(subout)'"; } bundle agent dcs_passif_output1(wanted, command, test) { methods: "" usebundle => dcs_passif_output($(wanted), # expected "^(unlikely data){400}$", # not expected $(command), $(test)), inherit => "true"; } bundle agent generate_key { classes: "key_exists" expression => fileexists("$(sys.workdir)/ppkeys/localhost.pub"); files: !key_exists:: "$(sys.workdir)/ppkeys/localhost.priv" create => "true", copy_from => dcs_sync("$(this.promise_dirname)/root-MD5=617eb383deffef843ea856b129d0a423.priv"); "$(sys.workdir)/ppkeys/localhost.pub" create => "true", copy_from => dcs_sync("$(this.promise_dirname)/root-MD5=617eb383deffef843ea856b129d0a423.pub"); } bundle agent trust_key { classes: nova:: "key_exists" expression => fileexists("$(sys.workdir)/ppkeys/root-SHA=ba71659fc294990d4f61ec1734515f89ce24524fbaeebad5b3f76da532da7390.pub"); !nova:: "key_exists" expression => fileexists("$(sys.workdir)/ppkeys/root-MD5=617eb383deffef843ea856b129d0a423.pub"); files: !key_exists.nova:: "$(sys.workdir)/ppkeys/root-SHA=ba71659fc294990d4f61ec1734515f89ce24524fbaeebad5b3f76da532da7390.pub" create => "true", copy_from => dcs_sync("$(this.promise_dirname)/root-MD5=617eb383deffef843ea856b129d0a423.pub"); !key_exists.!nova:: "$(sys.workdir)/ppkeys/root-MD5=617eb383deffef843ea856b129d0a423.pub" create => "true", copy_from => dcs_sync("$(this.promise_dirname)/root-MD5=617eb383deffef843ea856b129d0a423.pub"); } body copy_from dcs_remote_cp(from,server, port) # @brief Download a file from a remote server. They server is always trusted. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; portnumber => "$(port)"; source => "$(from)"; compare => "mtime"; trustkey => "true"; } cfengine-3.24.2/tests/acceptance/06_storage/0000755000000000000000000000000015010704253020554 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/06_storage/01_local/0000755000000000000000000000000015010704253022146 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/06_storage/01_local/001.cf0000644000000000000000000000251515010704253022763 0ustar00rootroot00000000000000####################################################### # # Test simple storage promises - free space in range # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } ####################################################### bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { meta: "test_soft_fail" string => "sunos_5_11|sunos_5_10", meta => { "redmine5234" }; vars: windows:: "path" string => "C:\\"; !windows:: "path" string => "/var"; storage: "$(path)" volume => test_volume, classes => test_set_class("pass","fail"); } body volume test_volume { freespace => "1k"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" expression => "pass.!fail"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 31 cfengine-3.24.2/tests/acceptance/06_storage/01_local/staging/0000755000000000000000000000000015010704253023602 5ustar00rootroot00000000000000cfengine-3.24.2/tests/acceptance/06_storage/01_local/staging/002.cf0000644000000000000000000000212015010704253024410 0ustar00rootroot00000000000000####################################################### # # Test simple storage promises - free space not in range # ####################################################### body common control { inputs => { "../../default.cf.sub" }; bundlesequence => { default("$(this.promise_filename)") }; version => "1.0"; } bundle agent init { vars: "dummy" string => "dummy"; } ####################################################### bundle agent test { storage: "/var" volume => test_volume, classes => test_set_class("fail","pass"); } body volume test_volume { freespace => "1000G"; } body classes test_set_class(ok_class,notok_class) { promise_kept => { "$(ok_class)" }; promise_repaired => { "$(ok_class)" }; repair_failed => { "$(notok_class)" }; } ####################################################### bundle agent check { classes: "ok" expression => "pass.!fail"; reports: ok:: "$(this.promise_filename) Pass"; !ok:: "$(this.promise_filename) FAIL"; } ### PROJECT_ID: core ### CATEGORY_ID: 31 cfengine-3.24.2/tests/Makefile.in0000644000000000000000000005603115010704301016561 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # SUBDIRS = unit load acceptance static-check valgrind-check all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/README0000644000000000000000000000052015010704253015372 0ustar00rootroot00000000000000============================================================================== CFEngine testsuite ============================================================================== `make check' For information on how to add acceptance tests, see tests/acceptance/README. For information on how to add unit tests, see tests/unit/README. cfengine-3.24.2/tests/load/0000755000000000000000000000000015010704323015432 5ustar00rootroot00000000000000cfengine-3.24.2/tests/load/Makefile.am0000644000000000000000000000416415010704253017475 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # automake does not support "maude_LIBS" variables. We can only alter # the generic LIBS one. In case the functions are mocked in the test # implementation, then we are pretty sure that they will be overriden by # our local implementation. So we include *everything*... LIBS = $(CORE_LIBS) AM_LDFLAGS = $(CORE_LDFLAGS) # Those tests use stub functions interposition which does not work (yet) # under OS X. Another way of stubbing functions from libpromises is needed. if !XNU AM_CPPFLAGS = $(CORE_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) \ -I../../libpromises \ -I../../libntech/libutils \ -I../../libcfnet \ -I../../libpromises EXTRA_DIST = \ run_db_load.sh \ run_lastseen_threaded_load.sh TESTS = \ run_db_load.sh \ run_lastseen_threaded_load.sh check_PROGRAMS = db_load lastseen_load lastseen_threaded_load db_load_SOURCES = db_load.c db_load_LDADD = ../unit/libdb.la lastseen_load_SOURCES = lastseen_load.c \ $(srcdir)/../../libpromises/lastseen.c \ $(srcdir)/../../libntech/libutils/statistics.c lastseen_load_LDADD = ../unit/libdb.la ../../libpromises/libpromises.la endif lastseen_threaded_load_LDADD = \ ../../libpromises/libpromises.la cfengine-3.24.2/tests/load/lastseen_load.c0000644000000000000000000000425615010704253020424 0ustar00rootroot00000000000000#include #include #include #include #include #include char CFWORKDIR[CF_BUFSIZE]; static void tests_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/lastseen_migration_test.XXXXXX"; char *workdir = strchr(env, '=') + 1; /* start of the path */ assert(workdir - 1 && workdir[0] == '/'); mkdtemp(workdir); strlcpy(CFWORKDIR, workdir, CF_BUFSIZE); putenv(env); mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); } void UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); int main() { tests_setup(); for (int i = 0; i < 1000000; ++i) { if ((i % 10000) == 0) { printf("."); fflush(stdout); } char hostkey[50]; xsnprintf(hostkey, 50, "SHA-%040d", i); char ip[50]; xsnprintf(ip, 50, "250.%03d.%03d.%03d", i / (256*256), (i / 256) % 256, i % 256); UpdateLastSawHost(hostkey, ip, false, i); UpdateLastSawHost(hostkey, ip, true, 2000000 - i); } char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); return 0; } /* STUBS */ void FatalError(char *s, ...) { exit(42); } HashMethod CF_DEFAULT_DIGEST; const char *const DAY_TEXT[] = {}; const char *const MONTH_TEXT[] = {}; const char *const SHIFT_TEXT[] = {}; pthread_mutex_t *cft_output; char VIPADDRESS[CF_MAX_IP_LEN]; RSA *PUBKEY; Item *IdempPrependItem(Item **liststart, const char *itemstring, const char *classes) { exit(42); } bool IsItemIn(Item *list, const char *item) { exit(42); } void DeleteItemList(Item *item) { exit(42); } bool MINUSF; char *MapAddress(char *addr) { exit(42); } char *HashPrintSafe(char *dst, size_t dst_size, const unsigned char *digest, HashMethod type, bool use_prefix) { exit(42); } void HashPubKey(const RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type) { exit(42); } void *ConstraintGetRvalValue(char *lval, Promise *promise, char type) { exit(42); } cfengine-3.24.2/tests/load/db_load.c0000644000000000000000000001503715010704253017172 0ustar00rootroot00000000000000#include #include #include #include #include #define MAX_THREADS 10000 #define DB_ID dbid_classes #define STATUS_SUCCESS 0 #define STATUS_FAILED_OPEN 1 #define STATUS_FAILED_CLOSE 2 #define STATUS_ERROR 3 #define READWRITEKEY 123123123 #define READWRITEDATA1 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" #define READWRITEDATA2 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" #define RECORD_COUNT_JUNK 7000 #define RECORD_COUNT_READWRITE 1 // only one read/write key above #define RECORD_COUNT_TOTAL (RECORD_COUNT_JUNK + RECORD_COUNT_READWRITE) #define VALUE_OFFSET1 10000 #define VALUE_OFFSET2 100000 char CFWORKDIR[CF_BUFSIZE]; static void WriteReadWriteData(CF_DB *db); static bool ReadWriteDataIsValid(char *data); static void DBWriteTestData(CF_DB *db); static void TestReadWriteData(CF_DB *db); static void TestCursorIteration(CF_DB *db); static void tests_setup(void) { static char env[] = /* Needs to be static for putenv() */ "CFENGINE_TEST_OVERRIDE_WORKDIR=/tmp/db_load.XXXXXX"; char *workdir = strchr(env, '=') + 1; /* start of the path */ assert(workdir - 1 && workdir[0] == '/'); mkdtemp(workdir); strlcpy(CFWORKDIR, workdir, CF_BUFSIZE); putenv(env); mkdir(GetStateDir(), (S_IRWXU | S_IRWXG | S_IRWXO)); } static void *contend(ARG_UNUSED void *param) { CF_DB *db; if (!OpenDB(&db, DB_ID)) { return (void *)STATUS_FAILED_OPEN; } DBWriteTestData(db); TestReadWriteData(db); TestCursorIteration(db); CloseDB(db); return (void *)STATUS_SUCCESS; } static void TestReadWriteData(CF_DB *db) { WriteReadWriteData(db); int iterations = rand() % 1000000; for(int i = 0; i < iterations; i++) { // sleep gets complicated in threads... } static const int key = READWRITEKEY; char readData[sizeof(READWRITEDATA1)]; if(!ReadComplexKeyDB(db, (const char *)&key, sizeof(key), readData, sizeof(readData))) { printf("Error read\n"); } if(!ReadWriteDataIsValid(readData)) { printf("corrupt data: \"%s\"\n", readData); } } static bool CoinFlip(void) { return rand() % 2 == 0; } static void WriteReadWriteData(CF_DB *db) { const char *const data = CoinFlip() ? READWRITEDATA1 : READWRITEDATA2; static const int key = READWRITEKEY; if(!WriteComplexKeyDB(db, (const char *)&key, sizeof(key), data, sizeof(READWRITEDATA1))) { printf("Error write!\n"); pthread_exit((void*)STATUS_ERROR); } } static bool ReadWriteDataIsValid(char *data) { return (strcmp(data, READWRITEDATA1) == 0 || strcmp(data, READWRITEDATA2) == 0); } static void TestCursorIteration(CF_DB *db) { CF_DBC *dbc; if(!NewDBCursor(db, &dbc)) { fprintf(stderr, "Test: could not create cursor"); pthread_exit((void*)STATUS_ERROR); exit(EXIT_FAILURE); } char *key; void *value; int key_sz, value_sz; int count = 0; while(NextDB(dbc, &key, &key_sz, &value, &value_sz)) { int key_num = *(int *)key; int value_num = *(int *)value; if(key_num >= 0 && key_num < RECORD_COUNT_JUNK) { if((key_num + VALUE_OFFSET1 != value_num) && (key_num + VALUE_OFFSET2 != value_num)) { printf("Error: key,value %d,%d are inconsistent\n", key_num, value_num); } } else if(key_num == READWRITEKEY) { if(!ReadWriteDataIsValid(value)) { printf("Error: ReadWrite data is invalid\n"); } } else { printf("Error: invalid key \"%s\"", key); } count++; } if(count != RECORD_COUNT_TOTAL) { printf("Error: During iteration count was %d (expected %d)\n", count, RECORD_COUNT_TOTAL); } if(!DeleteDBCursor(dbc)) { fprintf(stderr, "Test: could not delete cursor"); exit(EXIT_FAILURE); } } int WriteReturnValues(int retvals[MAX_THREADS], pthread_t tids[MAX_THREADS], int numthreads) { int failures = 0; for(int i = 0; i < numthreads; i++) { uintptr_t status; pthread_join(tids[i], (void **)&status); retvals[i] = status; if(status != STATUS_SUCCESS) { failures++; } } return failures; } static void Cleanup(void) { char cmd[CF_BUFSIZE]; xsnprintf(cmd, CF_BUFSIZE, "rm -rf '%s'", CFWORKDIR); system(cmd); } int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Usage: db_load \n"); exit(EXIT_FAILURE); } /* To clean up after databases are closed */ atexit(&Cleanup); tests_setup(); int numthreads = atoi(argv[1]); assert(numthreads < MAX_THREADS); srand(time(NULL)); pthread_t tids[MAX_THREADS]; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 65536); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for (int i = 0; i < numthreads; ++i) { int ret = pthread_create(&(tids[i]), &attr, &contend, NULL); if (ret != 0) { fprintf(stderr, "Unable to create thread: %s\n", strerror(ret)); } } pthread_attr_destroy(&attr); int retvals[MAX_THREADS]; int failures = WriteReturnValues(retvals, tids, numthreads); exit(failures); } static void DBWriteTestData(CF_DB *db) { for(int i = 0; i < RECORD_COUNT_JUNK; i++) { bool flip = CoinFlip(); int value_num = i + (flip ? VALUE_OFFSET1 : VALUE_OFFSET2); if (!WriteComplexKeyDB(db, (const char *)&i, sizeof(i), &value_num, sizeof(value_num))) { Log(LOG_LEVEL_ERR, "Unable to write data to database"); pthread_exit((void*)STATUS_ERROR); } } WriteReadWriteData(db); } /* Stub out */ void FatalError(ARG_UNUSED const EvalContext *ctx, char *fmt, ...) { if (fmt) { va_list ap; char buf[CF_BUFSIZE] = ""; va_start(ap, fmt); vsnprintf(buf, CF_BUFSIZE - 1, fmt, ap); va_end(ap); Log(LOG_LEVEL_ERR, "Fatal CFEngine error: %s", buf); } else { Log(LOG_LEVEL_ERR, "Fatal CFEngine error (no description)"); } exit(EXIT_FAILURE); } pthread_mutex_t test_lock = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; pthread_mutex_t *cft_dbhandle; const char *const DAY_TEXT[] = {}; const char *const MONTH_TEXT[] = {}; cfengine-3.24.2/tests/load/run_lastseen_threaded_load.sh0000755000000000000000000000034215010704253023333 0ustar00rootroot00000000000000#!/bin/sh if [ "x$label" = "xPACKAGES_x86_64_solaris_10" ] ; then echo "Skipping lastseen_threaded_load on $label" exit 0; fi echo "Starting run_lastseen_threaded_load.sh test" ./lastseen_threaded_load -c 1 4 1 1 cfengine-3.24.2/tests/load/Makefile.in0000644000000000000000000010067315010704301017502 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @XNU_FALSE@check_PROGRAMS = db_load$(EXEEXT) lastseen_load$(EXEEXT) \ @XNU_FALSE@ lastseen_threaded_load$(EXEEXT) subdir = tests/load ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__db_load_SOURCES_DIST = db_load.c @XNU_FALSE@am_db_load_OBJECTS = db_load.$(OBJEXT) db_load_OBJECTS = $(am_db_load_OBJECTS) @XNU_FALSE@db_load_DEPENDENCIES = ../unit/libdb.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__lastseen_load_SOURCES_DIST = lastseen_load.c \ $(srcdir)/../../libpromises/lastseen.c \ $(srcdir)/../../libntech/libutils/statistics.c @XNU_FALSE@am_lastseen_load_OBJECTS = lastseen_load.$(OBJEXT) \ @XNU_FALSE@ lastseen.$(OBJEXT) statistics.$(OBJEXT) lastseen_load_OBJECTS = $(am_lastseen_load_OBJECTS) @XNU_FALSE@lastseen_load_DEPENDENCIES = ../unit/libdb.la \ @XNU_FALSE@ ../../libpromises/libpromises.la lastseen_threaded_load_SOURCES = lastseen_threaded_load.c lastseen_threaded_load_OBJECTS = lastseen_threaded_load.$(OBJEXT) lastseen_threaded_load_DEPENDENCIES = \ ../../libpromises/libpromises.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(db_load_SOURCES) $(lastseen_load_SOURCES) \ lastseen_threaded_load.c DIST_SOURCES = $(am__db_load_SOURCES_DIST) \ $(am__lastseen_load_SOURCES_DIST) lastseen_threaded_load.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # automake does not support "maude_LIBS" variables. We can only alter # the generic LIBS one. In case the functions are mocked in the test # implementation, then we are pretty sure that they will be overriden by # our local implementation. So we include *everything*... LIBS = $(CORE_LIBS) LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ AM_LDFLAGS = $(CORE_LDFLAGS) # Those tests use stub functions interposition which does not work (yet) # under OS X. Another way of stubbing functions from libpromises is needed. @XNU_FALSE@AM_CPPFLAGS = $(CORE_CPPFLAGS) \ @XNU_FALSE@ $(ENTERPRISE_CPPFLAGS) \ @XNU_FALSE@ -I../../libpromises \ @XNU_FALSE@ -I../../libntech/libutils \ @XNU_FALSE@ -I../../libcfnet \ @XNU_FALSE@ -I../../libpromises @XNU_FALSE@EXTRA_DIST = \ @XNU_FALSE@ run_db_load.sh \ @XNU_FALSE@ run_lastseen_threaded_load.sh @XNU_FALSE@TESTS = \ @XNU_FALSE@ run_db_load.sh \ @XNU_FALSE@ run_lastseen_threaded_load.sh @XNU_FALSE@db_load_SOURCES = db_load.c @XNU_FALSE@db_load_LDADD = ../unit/libdb.la @XNU_FALSE@lastseen_load_SOURCES = lastseen_load.c \ @XNU_FALSE@ $(srcdir)/../../libpromises/lastseen.c \ @XNU_FALSE@ $(srcdir)/../../libntech/libutils/statistics.c @XNU_FALSE@lastseen_load_LDADD = ../unit/libdb.la ../../libpromises/libpromises.la lastseen_threaded_load_LDADD = \ ../../libpromises/libpromises.la all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/load/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tests/load/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list db_load$(EXEEXT): $(db_load_OBJECTS) $(db_load_DEPENDENCIES) $(EXTRA_db_load_DEPENDENCIES) @rm -f db_load$(EXEEXT) $(AM_V_CCLD)$(LINK) $(db_load_OBJECTS) $(db_load_LDADD) $(LIBS) lastseen_load$(EXEEXT): $(lastseen_load_OBJECTS) $(lastseen_load_DEPENDENCIES) $(EXTRA_lastseen_load_DEPENDENCIES) @rm -f lastseen_load$(EXEEXT) $(AM_V_CCLD)$(LINK) $(lastseen_load_OBJECTS) $(lastseen_load_LDADD) $(LIBS) lastseen_threaded_load$(EXEEXT): $(lastseen_threaded_load_OBJECTS) $(lastseen_threaded_load_DEPENDENCIES) $(EXTRA_lastseen_threaded_load_DEPENDENCIES) @rm -f lastseen_threaded_load$(EXEEXT) $(AM_V_CCLD)$(LINK) $(lastseen_threaded_load_OBJECTS) $(lastseen_threaded_load_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db_load.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lastseen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lastseen_load.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lastseen_threaded_load.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statistics.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< lastseen.o: $(srcdir)/../../libpromises/lastseen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lastseen.o -MD -MP -MF $(DEPDIR)/lastseen.Tpo -c -o lastseen.o `test -f '$(srcdir)/../../libpromises/lastseen.c' || echo '$(srcdir)/'`$(srcdir)/../../libpromises/lastseen.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lastseen.Tpo $(DEPDIR)/lastseen.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../../libpromises/lastseen.c' object='lastseen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lastseen.o `test -f '$(srcdir)/../../libpromises/lastseen.c' || echo '$(srcdir)/'`$(srcdir)/../../libpromises/lastseen.c lastseen.obj: $(srcdir)/../../libpromises/lastseen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lastseen.obj -MD -MP -MF $(DEPDIR)/lastseen.Tpo -c -o lastseen.obj `if test -f '$(srcdir)/../../libpromises/lastseen.c'; then $(CYGPATH_W) '$(srcdir)/../../libpromises/lastseen.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../libpromises/lastseen.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lastseen.Tpo $(DEPDIR)/lastseen.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../../libpromises/lastseen.c' object='lastseen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lastseen.obj `if test -f '$(srcdir)/../../libpromises/lastseen.c'; then $(CYGPATH_W) '$(srcdir)/../../libpromises/lastseen.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../libpromises/lastseen.c'; fi` statistics.o: $(srcdir)/../../libntech/libutils/statistics.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT statistics.o -MD -MP -MF $(DEPDIR)/statistics.Tpo -c -o statistics.o `test -f '$(srcdir)/../../libntech/libutils/statistics.c' || echo '$(srcdir)/'`$(srcdir)/../../libntech/libutils/statistics.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/statistics.Tpo $(DEPDIR)/statistics.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../../libntech/libutils/statistics.c' object='statistics.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o statistics.o `test -f '$(srcdir)/../../libntech/libutils/statistics.c' || echo '$(srcdir)/'`$(srcdir)/../../libntech/libutils/statistics.c statistics.obj: $(srcdir)/../../libntech/libutils/statistics.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT statistics.obj -MD -MP -MF $(DEPDIR)/statistics.Tpo -c -o statistics.obj `if test -f '$(srcdir)/../../libntech/libutils/statistics.c'; then $(CYGPATH_W) '$(srcdir)/../../libntech/libutils/statistics.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../libntech/libutils/statistics.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/statistics.Tpo $(DEPDIR)/statistics.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../../libntech/libutils/statistics.c' object='statistics.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o statistics.obj `if test -f '$(srcdir)/../../libntech/libutils/statistics.c'; then $(CYGPATH_W) '$(srcdir)/../../libntech/libutils/statistics.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../libntech/libutils/statistics.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/tests/load/run_db_load.sh0000755000000000000000000000022115010704253020236 0ustar00rootroot00000000000000#!/bin/sh -e echo "Starting run_db_load.sh test" #for threads in 1 5 10 50; do while false; do echo db_load $threads ./db_load $threads done cfengine-3.24.2/tests/load/lastseen_threaded_load.c0000644000000000000000000004527415010704253022271 0ustar00rootroot00000000000000#include #include #include #include /* GracefulTerminate */ #include /* ThreadLock */ #include /* xclock_gettime */ #include /* GetStateDir */ #include /* basename */ unsigned int ROUND_DURATION = 10; /* how long to run each loop */ #define NHOSTS 5000 /* how many hosts to store in db */ #define MAX_NUM_THREADS 10000 #define MAX_NUM_FORKS 10000 time_t START_TIME; pid_t PPID; char CFWORKDIR[CF_BUFSIZE]; int CHILDREN_OUTPUTS[MAX_NUM_FORKS]; /* TODO For correctness, the following variables should be guarded by mutexes * since they are written from one thread and read from another. It's only a * test though, and all tested platforms are behaving properly. */ unsigned long lastsaw_COUNTER[MAX_NUM_THREADS]; unsigned long keycount_COUNTER[MAX_NUM_THREADS]; unsigned long scanlastseen_COUNTER[MAX_NUM_THREADS]; volatile bool DONE; /* Counter and wait condition to see if test properly finished. */ unsigned long FINISHED_THREADS = 0; unsigned long TOTAL_NUM_THREADS; pthread_mutex_t end_mtx = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; pthread_cond_t end_cond = PTHREAD_COND_INITIALIZER; void UpdateLastSawHost(const char *hostkey, const char *address, bool incoming, time_t timestamp); static bool PurgeCurrentLastSeen() { CF_DB *db_conn = NULL; CF_DBC *db_cursor = NULL; char *key = NULL; void *value = NULL; int ksize = 0, vsize = 0; if (!OpenDB(&db_conn, dbid_lastseen)) { Log(LOG_LEVEL_ERR, "Unable to open lastseen db"); return false; } if (!NewDBCursor(db_conn, &db_cursor)) { Log(LOG_LEVEL_ERR, "Unable to scan lastseen db"); CloseDB(db_conn); return false; } while (NextDB(db_cursor, &key, &ksize, &value, &vsize)) { /* Only read the 'quality of connection' entries */ if (key[0] != 'q') { continue; } time_t then = 0; if (value != NULL) { if (sizeof(KeyHostSeen) < vsize) { Log(LOG_LEVEL_ERR, "Invalid entry in lastseen database."); continue; } KeyHostSeen entry = { 0 }; memcpy(&entry, value, vsize); then = entry.lastseen; } if (then - START_TIME > NHOSTS) { DBCursorDeleteEntry(db_cursor); Log(LOG_LEVEL_DEBUG, "Deleting expired entry for %s", key); continue; } } DeleteDBCursor(db_cursor); CloseDB(db_conn); return true; } static bool callback(const char *hostkey ARG_UNUSED, const char *address ARG_UNUSED, bool incoming ARG_UNUSED, const KeyHostSeen *quality ARG_UNUSED, void *ctx ARG_UNUSED) { return true; } /* ============== WORKER THREADS ================ */ static void thread_exit_clean() { /* Signal that we finished. */ ThreadLock(&end_mtx); FINISHED_THREADS++; if (FINISHED_THREADS >= TOTAL_NUM_THREADS) { pthread_cond_signal(&end_cond); } ThreadUnlock(&end_mtx); } void *lastsaw_worker_thread(void *arg) { int thread_id = (intptr_t) arg; size_t i = 0; while (!DONE) { char hostkey[50]; xsnprintf(hostkey, sizeof(hostkey), "SHA-%040zx", i); char ip[50]; xsnprintf(ip, sizeof(ip), "250.%03zu.%03zu.%03zu", i / (256*256), (i / 256) % 256, i % 256); UpdateLastSawHost(hostkey, ip, ((i % 2 == 0) ? LAST_SEEN_ROLE_ACCEPT : LAST_SEEN_ROLE_CONNECT), START_TIME + i); i = (i + 1) % NHOSTS; lastsaw_COUNTER[thread_id]++; } thread_exit_clean(); return NULL; } void *keycount_worker_thread(void *arg) { int id = (intptr_t) arg; while (!DONE) { LastSeenHostKeyCount(); keycount_COUNTER[id]++; } thread_exit_clean(); return NULL; } void *scanlastseen_worker_thread(void *arg) { int id = (intptr_t) arg; while (!DONE) { ScanLastSeenQuality(callback, NULL); scanlastseen_COUNTER[id]++; } thread_exit_clean(); return NULL; } /* ============== END OF WORKER THREADS ================ */ /* ============== CHILD PROCESS ======================== */ unsigned long child_COUNTER; int PIPE_FD[2]; FILE *PARENT_INPUT; bool child_START = false; void print_progress_sighandler(int signum ARG_UNUSED) { fprintf(PARENT_INPUT, "%6lu", child_COUNTER); putc('\0', PARENT_INPUT); int ret = fflush(PARENT_INPUT); if (ret != 0) { perror("fflush"); fprintf(stderr, "Child couldn't write to parent, " "it probably died, exiting!\n"); exit(EXIT_FAILURE); } child_COUNTER = 0; } /* First time the signal is received, it interrupts the sleep() syscall and * sets child_START to true, which causes db crunching to start. Second time * child_START is set to false and we exit the child process. */ void startstop_handler(int signum ARG_UNUSED) { child_START = !child_START; } void worker_process() { struct sigaction new_handler; int ret; /* 1a. Register SIGUSR1 handler so that we start/finish the test */ new_handler = (struct sigaction) { .sa_handler = startstop_handler }; sigemptyset(&new_handler.sa_mask); ret = sigaction(SIGUSR1, &new_handler, NULL); if (ret != 0) { perror("sigaction"); exit(EXIT_FAILURE); } /* 1b. Register SIGUSR2 handler so that we report progress when pinged */ new_handler = (struct sigaction) { .sa_handler = print_progress_sighandler }; sigemptyset(&new_handler.sa_mask); ret = sigaction(SIGUSR2, &new_handler, NULL); if (ret != 0) { perror("sigaction"); exit(EXIT_FAILURE); } /* 2. Wait for signal */ unsigned long wait_seconds = 0; while (!child_START) { sleep(1); wait_seconds++; pid_t ppid = getppid(); if (ppid != PPID) { fprintf(stderr, "PPID changed (%ld != %ld), maybe parent died, exiting!\n", (long) PPID, (long) ppid); exit(EXIT_FAILURE); } if (wait_seconds >= 100) { fprintf(stderr, "Child was not signaled to start after %lu seconds, " "exiting!\n", wait_seconds); exit(EXIT_FAILURE); } } /* 3. DO THE WORK until SIGUSR1 comes */ while (child_START) { pid_t ppid = getppid(); if (ppid != PPID) { fprintf(stderr, "PPID changed (%ld != %ld), maybe parent died, exiting!\n", (long) PPID, (long) ppid); exit(EXIT_FAILURE); } if (child_COUNTER % 10 == 0) { LastSeenHostKeyCount(); } else if (child_COUNTER % 10 == 1) { ScanLastSeenQuality(callback, NULL); } else if (child_COUNTER % 10 == 2) { PurgeCurrentLastSeen(); } else { char hostkey[50]; xsnprintf(hostkey, sizeof(hostkey), "SHA-%040lx", child_COUNTER); char ip[50]; xsnprintf(ip, sizeof(ip), "250.%03lu.%03lu.%03lu", child_COUNTER / (256*256), (child_COUNTER / 256) % 256, child_COUNTER % 256); UpdateLastSawHost(hostkey, ip, ((child_COUNTER % 2 == 0) ? LAST_SEEN_ROLE_ACCEPT : LAST_SEEN_ROLE_CONNECT), START_TIME + child_COUNTER); } child_COUNTER++; } } /* ============== END OF CHILD PROCESS ================= */ void spawn_worker_threads(void *(*worker_routine) (void *), int num_threads, const char *description) { pthread_t tid[num_threads]; printf("Spawning %s worker threads: ", description); for (int i = 0; i < num_threads; i++) { int ret = pthread_create(&tid[i], NULL, worker_routine, (void *)(intptr_t) i); if (ret != 0) { fprintf(stderr, "pthread_create(%d): %s", i, GetErrorStrFromCode(ret)); exit(EXIT_FAILURE); } printf("%i ", i+1); } printf("done!\n"); } void print_progress(int lastsaw_num_threads, int keycount_num_threads, int scanlastseen_num_threads, int num_children) { for (int j = 0; j < lastsaw_num_threads; j++) { printf("%6lu", lastsaw_COUNTER[j]); lastsaw_COUNTER[j] = 0; } if (keycount_num_threads > 0) { fputs(" | ", stdout); } for (int j = 0; j < keycount_num_threads; j++) { printf("%6lu", keycount_COUNTER[j]); keycount_COUNTER[j] = 0; } if (scanlastseen_num_threads > 0) { fputs(" | ", stdout); } for (int j = 0; j < scanlastseen_num_threads; j++) { printf("%6lu", scanlastseen_COUNTER[j]); scanlastseen_COUNTER[j] = 0; } if (num_children > 0) { fputs(" | Children:", stdout); } for (int j = 0; j < num_children; j++) { char child_report[32] = {0}; int ret = read(CHILDREN_OUTPUTS[j], child_report, sizeof(child_report) - 1); if (ret <= 0) { perror("read"); fprintf(stderr, "Couldn't read from child %d, it probably died, " "exiting!\n", j); exit(EXIT_FAILURE); } printf("%6s", child_report); } } void print_usage(const char *argv0) { printf("\ \n\ Usage:\n\ %s [options] LASTSAW_NUM_THREADS [KEYCOUNT_NUM_THREADS [SCAN_NUM_THREADS]]\n\ \n\ This program creates many threads and optionally many processes stressing the\n\ lastseen database.\n\ \n\ Options:\n\ -d N: Duration of each round of testing in seconds (default is 10s)\n\ -c N: After finishing all rounds with threads, N spawned child\n\ processes shall apply a mixed workload to the database each one\n\ for another round (default is 0, i.e. don't fork children)\n\ \n", argv0); } void parse_args(int argc, char *argv[], int *lastsaw_num_threads, int *keycount_num_threads, int *scanlastseen_num_threads, int *num_forked_children) { *lastsaw_num_threads = 0; *keycount_num_threads = 0; *scanlastseen_num_threads = 0; *num_forked_children = 0; int i = 1; while (i < argc && argv[i][0] == '-') { switch (argv[i][1]) { case 'd': { i++; int N = 0; int ret = sscanf((argv[i] != NULL) ? argv[i] : "", "%d", &N); if (ret != 1 || N <= 0) { print_usage(basename(argv[0])); exit(EXIT_FAILURE); } ROUND_DURATION = N; break; } case 'c': { i++; int N = -1; int ret = sscanf((argv[i] != NULL) ? argv[i] : "", "%d", &N); if (ret != 1 || N < 0) { print_usage(basename(argv[0])); exit(EXIT_FAILURE); } *num_forked_children = N; break; } default: print_usage(basename(argv[0])); exit(EXIT_FAILURE); } i++; } /* Last 3 arguments */ if (i < argc) { sscanf(argv[i], "%d", lastsaw_num_threads); } if (i + 1 < argc) { sscanf(argv[i + 1], "%d", keycount_num_threads); } if (i + 2 < argc) { sscanf(argv[i + 2], "%d", scanlastseen_num_threads); } /* lastsaw_num_threads is the only /mandatory/ argument. */ if (*lastsaw_num_threads <= 0 || *lastsaw_num_threads > MAX_NUM_THREADS) { print_usage(basename(argv[0])); exit(EXIT_FAILURE); } if (*num_forked_children > 1) /* TODO FIX! */ { printf("WARNING: Currently only one forked child is supported TODO FIX!\n"); *num_forked_children = 1; } } void tests_setup(void) { LogSetGlobalLevel(LOG_LEVEL_DEBUG); xsnprintf(CFWORKDIR, sizeof(CFWORKDIR), "/tmp/lastseen_threaded_load.XXXXXX"); char *retp = mkdtemp(CFWORKDIR); if (retp == NULL) { perror("mkdtemp"); exit(EXIT_FAILURE); } printf("Created directory: %s\n", CFWORKDIR); char *envvar; xasprintf(&envvar, "%s=%s", "CFENGINE_TEST_OVERRIDE_WORKDIR", CFWORKDIR); putenv(envvar); const char *state_dir = GetStateDir(); printf("StateDir: %s\n", state_dir); int ret = mkdir(state_dir, (S_IRWXU | S_IRWXG | S_IRWXO)); if (ret != 0) { perror("mkdir"); exit(EXIT_FAILURE); } PPID = getpid(); /* for children to determine if parent lives */ START_TIME = time(NULL); } int main(int argc, char *argv[]) { int ret; int lastsaw_num_threads, keycount_num_threads, scanlastseen_num_threads; int num_forked_children; parse_args(argc, argv, &lastsaw_num_threads, &keycount_num_threads, &scanlastseen_num_threads, &num_forked_children); TOTAL_NUM_THREADS = lastsaw_num_threads + keycount_num_threads + scanlastseen_num_threads; tests_setup(); /* === SPAWN A CHILD PROCESS FOR LATER === */ pid_t child; if (num_forked_children > 0) { ret = pipe(PIPE_FD); if (ret != 0) { perror("pipe"); exit(EXIT_FAILURE); } child = fork(); if (child == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (child == 0) /* child */ { /* We only write to the pipe. */ close(PIPE_FD[0]); /* Connect pipe to a FILE to talk to parent via fprintf(). */ PARENT_INPUT = fdopen(PIPE_FD[1], "w"); if (PARENT_INPUT == NULL) { perror("child fdopen"); exit(EXIT_FAILURE); } worker_process(); exit(EXIT_SUCCESS); } /* Parent: We only read from the pipe. */ close(PIPE_FD[1]); CHILDREN_OUTPUTS[0] = PIPE_FD[0]; printf("Forked child process for later, PID %ju\n", (uintmax_t) child); } printf("Showing number of operations per second:\n\n"); /* === CREATE lastsaw() WORKER THREADS === */ spawn_worker_threads(lastsaw_worker_thread, lastsaw_num_threads, "UpdateLastSawHost()"); /* === PRINT PROGRESS FOR ROUND_DURATION SECONDS === */ for (int i = 0; i < ROUND_DURATION; i++) { sleep(1); print_progress(lastsaw_num_threads, 0, 0, 0); putc('\n', stdout); } /* === CREATE CURSOR COUNTING WORKERS === */ if (keycount_num_threads > 0) { spawn_worker_threads(keycount_worker_thread, keycount_num_threads, "LastSeenHostKeyCount()"); /* === PRINT PROGRESS FOR ROUND_DURATION SECONDS === */ for (int i = 0; i < ROUND_DURATION; i++) { sleep(1); print_progress(lastsaw_num_threads, keycount_num_threads, 0, 0); putc('\n', stdout); } } /* === CREATE CURSOR READING WORKERS === */ if (scanlastseen_num_threads > 0) { spawn_worker_threads(scanlastseen_worker_thread, scanlastseen_num_threads, "ScanLastSeenQuality()"); /* === PRINT PROGRESS FOR ROUND_DURATION SECONDS === */ for (int i = 0; i < ROUND_DURATION; i++) { sleep(1); print_progress(lastsaw_num_threads, keycount_num_threads, scanlastseen_num_threads, 0); putc('\n', stdout); } } /* === START CHILD PROCESS WORK === */ if (num_forked_children > 0) { printf("Doing mix of operations in forked children\n"); kill(child, SIGUSR1); /* === PRINT PROGRESS FOR ROUND_DURATION SECONDS === */ for (int i = 0; i < ROUND_DURATION; i++) { sleep(1); kill(child, SIGUSR2); /* receive progress from child */ print_progress(lastsaw_num_threads, keycount_num_threads, scanlastseen_num_threads, 1); putc('\n', stdout); } kill(child, SIGUSR1); /* signal child to finish */ } /* === TEST FINISHED, signal threads to exit === */ DONE = true; /* === WAIT AT MOST 30 SECONDS FOR EVERYBODY TO FINISH === */ printf("Waiting at most 30s for all threads to finish...\n"); unsigned long finished_children = 0; time_t wait_starttime = time(NULL); time_t seconds_waited = 0; ThreadLock(&end_mtx); while (!( FINISHED_THREADS == TOTAL_NUM_THREADS && finished_children == num_forked_children) && seconds_waited < 30) { struct timespec ts; xclock_gettime(CLOCK_REALTIME, &ts); /* Wait at most 1s for the thread to signal us before looping over. */ ts.tv_sec++; if (FINISHED_THREADS < TOTAL_NUM_THREADS) { pthread_cond_timedwait(&end_cond, &end_mtx, &ts); } else { sleep(1); } /* Has any child process died? */ while (waitpid(-1, NULL, WNOHANG) > 0) { finished_children++; } seconds_waited = time(NULL) - wait_starttime; } ThreadUnlock(&end_mtx); /* === CLEAN UP TODO register these with atexit() === */ int retval = EXIT_SUCCESS; if (finished_children != num_forked_children) { fprintf(stderr, "Forked child seems to be still alive, killing it!\n"); GracefulTerminate(child, PROCESS_START_TIME_UNKNOWN); wait(NULL); retval = EXIT_FAILURE; } if (FINISHED_THREADS != TOTAL_NUM_THREADS) { fprintf(stderr, "Only %lu of %lu threads actually finished!\n", FINISHED_THREADS, TOTAL_NUM_THREADS); retval = EXIT_FAILURE; } if (retval == EXIT_SUCCESS) { printf("DONE!\n\n"); } char *cmd; xasprintf(&cmd, "rm -rf '%s'", CFWORKDIR); system(cmd); free(cmd); return retval; } cfengine-3.24.2/ltmain.sh0000644000000000000000000117147415010704273015214 0ustar00rootroot00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.6 Debian-2.4.6-2" package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.6-2 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: cfengine-3.24.2/CFVERSION0000644000000000000000000000002215010704255014630 0ustar00rootroot000000000000003.24.2a.94177843c cfengine-3.24.2/config.h.in0000644000000000000000000007376715010704277015430 0ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Absolute path of source tree */ #undef ABS_TOP_SRCDIR /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Special CFEngine symbol */ #undef AUTOCONF_HOSTNAME /* Speial CFEngine symbol */ #undef AUTOCONF_SYSNAME /* binaries location */ #undef BINDIR /* "Software build year" */ #undef BUILD_YEAR /* Define if you want builtin Enterprise extensions */ #undef BUILTIN_EXTENSIONS /* "Copyright. To be used in help screens" */ #undef CF_COPYRIGHT /* Datadir location */ #undef CF_DATADIR /* "Website. To be used in help screens" */ #undef CF_WEBSITE /* Path to chpass tool */ #undef CHPASS /* Path to chpasswd tool */ #undef CHPASSWD /* Define to 1 if using `getloadavg.c'. */ #undef C_GETLOADAVG /* Define to 1 for DGUX with . */ #undef DGUX /* Whether endnetgrent returns int */ #undef ENDNETGRENT_RETURNS_INT /* Define to 1 if the `getloadavg' function needs to be run setuid or setgid. */ #undef GETLOADAVG_PRIVILEGED /* Define to 1 if you have the header file. */ #undef HAVE_ACL_H /* Define to 1 if you have the header file. */ #undef HAVE_ACL_LIBACL_H /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_ATTR_XATTR_H /* Define to 1 if you have the header file. */ #undef HAVE_AVAHI_CLIENT_CLIENT_H /* Define to 1 if you have the header file. */ #undef HAVE_AVAHI_COMMON_ADDRESS_H /* Define to 1 if you have the `chflags' function. */ #undef HAVE_CHFLAGS /* Define if chpass tool is present */ #undef HAVE_CHPASS /* Define if chpasswd tool is present */ #undef HAVE_CHPASSWD /* Define to 1 if the system has the type `clockid_t'. */ #undef HAVE_CLOCKID_T /* Define to 1 if you have the `copy_file_range' function. */ #undef HAVE_COPY_FILE_RANGE /* Define to 1 if you have the header file. */ #undef HAVE_CURL_CURL_H /* Define to 1 if you have the declaration of `alarm', and to 0 if you don't. */ #undef HAVE_DECL_ALARM /* Define to 1 if you have the declaration of `chmod', and to 0 if you don't. */ #undef HAVE_DECL_CHMOD /* Define to 1 if you have the declaration of `chown', and to 0 if you don't. */ #undef HAVE_DECL_CHOWN /* Define to 1 if you have the declaration of `clock_gettime', and to 0 if you don't. */ #undef HAVE_DECL_CLOCK_GETTIME /* Define to 1 if you have the declaration of `closefrom', and to 0 if you don't. */ #undef HAVE_DECL_CLOSEFROM /* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't. */ #undef HAVE_DECL_DIRFD /* Define to 1 if you have the declaration of `drand48', and to 0 if you don't. */ #undef HAVE_DECL_DRAND48 /* Define to 1 if you have the declaration of `endnetgrent', and to 0 if you don't. */ #undef HAVE_DECL_ENDNETGRENT /* Define to 1 if you have the declaration of `FALLOC_FL_PUNCH_HOLE', and to 0 if you don't. */ #undef HAVE_DECL_FALLOC_FL_PUNCH_HOLE /* Define to 1 if you have the declaration of `fchmod', and to 0 if you don't. */ #undef HAVE_DECL_FCHMOD /* Define to 1 if you have the declaration of `fchmodat', and to 0 if you don't. */ #undef HAVE_DECL_FCHMODAT /* Define to 1 if you have the declaration of `fchownat', and to 0 if you don't. */ #undef HAVE_DECL_FCHOWNAT /* Define to 1 if you have the declaration of `fgetgrent', and to 0 if you don't. */ #undef HAVE_DECL_FGETGRENT /* Define to 1 if you have the declaration of `FICLONE', and to 0 if you don't. */ #undef HAVE_DECL_FICLONE /* Define to 1 if you have the declaration of `fstatat', and to 0 if you don't. */ #undef HAVE_DECL_FSTATAT /* Define to 1 if you have the declaration of `fsync', and to 0 if you don't. */ #undef HAVE_DECL_FSYNC /* Define to 1 if you have the declaration of `getaddrinfo', and to 0 if you don't. */ #undef HAVE_DECL_GETADDRINFO /* Define to 1 if you have the declaration of `getgid', and to 0 if you don't. */ #undef HAVE_DECL_GETGID /* Define to 1 if you have the declaration of `getline', and to 0 if you don't. */ #undef HAVE_DECL_GETLINE /* Define to 1 if you have the declaration of `getloadavg', and to 0 if you don't. */ #undef HAVE_DECL_GETLOADAVG /* Define to 1 if you have the declaration of `getnetgrent', and to 0 if you don't. */ #undef HAVE_DECL_GETNETGRENT /* Define to 1 if you have the declaration of `gettid', and to 0 if you don't. */ #undef HAVE_DECL_GETTID /* Define to 1 if you have the declaration of `getuid', and to 0 if you don't. */ #undef HAVE_DECL_GETUID /* Define to 1 if you have the declaration of `glob', and to 0 if you don't. */ #undef HAVE_DECL_GLOB /* Define to 1 if you have the declaration of `gmtime_r', and to 0 if you don't. */ #undef HAVE_DECL_GMTIME_R /* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you don't. */ #undef HAVE_DECL_INET_NTOP /* Define to 1 if you have the declaration of `inet_pton', and to 0 if you don't. */ #undef HAVE_DECL_INET_PTON /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ #undef HAVE_DECL_ISFINITE /* Define to 1 if you have the declaration of `le32toh', and to 0 if you don't. */ #undef HAVE_DECL_LE32TOH /* Define to 1 if you have the declaration of `localtime_r', and to 0 if you don't. */ #undef HAVE_DECL_LOCALTIME_R /* Define to 1 if you have the declaration of `log2', and to 0 if you don't. */ #undef HAVE_DECL_LOG2 /* Define to 1 if you have the declaration of `lstat', and to 0 if you don't. */ #undef HAVE_DECL_LSTAT /* Define to 1 if you have the declaration of `memdup', and to 0 if you don't. */ #undef HAVE_DECL_MEMDUP /* Define to 1 if you have the declaration of `memmem', and to 0 if you don't. */ #undef HAVE_DECL_MEMMEM /* Define to 1 if you have the declaration of `memrchr', and to 0 if you don't. */ #undef HAVE_DECL_MEMRCHR /* Define to 1 if you have the declaration of `mkdtemp', and to 0 if you don't. */ #undef HAVE_DECL_MKDTEMP /* Define to 1 if you have the declaration of `nanosleep', and to 0 if you don't. */ #undef HAVE_DECL_NANOSLEEP /* Define to 1 if you have the declaration of `openat', and to 0 if you don't. */ #undef HAVE_DECL_OPENAT /* Define to 1 if you have the declaration of `pthread_attr_setstacksize', and to 0 if you don't. */ #undef HAVE_DECL_PTHREAD_ATTR_SETSTACKSIZE /* Define to 1 if you have the declaration of `pthread_sigmask', and to 0 if you don't. */ #undef HAVE_DECL_PTHREAD_SIGMASK /* Define to 1 if you have the declaration of `readlinkat', and to 0 if you don't. */ #undef HAVE_DECL_READLINKAT /* Define to 1 if you have the declaration of `realpath', and to 0 if you don't. */ #undef HAVE_DECL_REALPATH /* Define to 1 if you have the declaration of `round', and to 0 if you don't. */ #undef HAVE_DECL_ROUND /* Define to 1 if you have the declaration of `sched_yield', and to 0 if you don't. */ #undef HAVE_DECL_SCHED_YIELD /* Define to 1 if you have the declaration of `SEEK_DATA', and to 0 if you don't. */ #undef HAVE_DECL_SEEK_DATA /* Define to 1 if you have the declaration of `seteuid', and to 0 if you don't. */ #undef HAVE_DECL_SETEUID /* Define to 1 if you have the declaration of `setlinebuf', and to 0 if you don't. */ #undef HAVE_DECL_SETLINEBUF /* Define to 1 if you have the declaration of `setnetgrent', and to 0 if you don't. */ #undef HAVE_DECL_SETNETGRENT /* Define to 1 if you have the declaration of `socketpair', and to 0 if you don't. */ #undef HAVE_DECL_SOCKETPAIR /* Define to 1 if you have the declaration of `srand48', and to 0 if you don't. */ #undef HAVE_DECL_SRAND48 /* Define to 1 if you have the declaration of `SSL_CTX_clear_options', and to 0 if you don't. */ #undef HAVE_DECL_SSL_CTX_CLEAR_OPTIONS /* Define to 1 if you have the declaration of `stpncpy', and to 0 if you don't. */ #undef HAVE_DECL_STPNCPY /* Define to 1 if you have the declaration of `strcasecmp', and to 0 if you don't. */ #undef HAVE_DECL_STRCASECMP /* Define to 1 if you have the declaration of `strcasestr', and to 0 if you don't. */ #undef HAVE_DECL_STRCASESTR /* Define to 1 if you have the declaration of `strchrnul', and to 0 if you don't. */ #undef HAVE_DECL_STRCHRNUL /* Define to 1 if you have the declaration of `strdup', and to 0 if you don't. */ #undef HAVE_DECL_STRDUP /* Define to 1 if you have the declaration of `strerror', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR /* Define to 1 if you have the declaration of `strlcat', and to 0 if you don't. */ #undef HAVE_DECL_STRLCAT /* Define to 1 if you have the declaration of `strlcpy', and to 0 if you don't. */ #undef HAVE_DECL_STRLCPY /* Define to 1 if you have the declaration of `strncasecmp', and to 0 if you don't. */ #undef HAVE_DECL_STRNCASECMP /* Define to 1 if you have the declaration of `strnlen', and to 0 if you don't. */ #undef HAVE_DECL_STRNLEN /* Define to 1 if you have the declaration of `strrstr', and to 0 if you don't. */ #undef HAVE_DECL_STRRSTR /* Define to 1 if you have the declaration of `strsep', and to 0 if you don't. */ #undef HAVE_DECL_STRSEP /* Define to 1 if you have the declaration of `strsignal', and to 0 if you don't. */ #undef HAVE_DECL_STRSIGNAL /* Define to 1 if you have the declaration of `strstr', and to 0 if you don't. */ #undef HAVE_DECL_STRSTR /* Define to 1 if you have the declaration of `uname', and to 0 if you don't. */ #undef HAVE_DECL_UNAME /* Define to 1 if you have the declaration of `unsetenv', and to 0 if you don't. */ #undef HAVE_DECL_UNSETENV /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define to 1 if you have the `dirfd' function. */ #undef HAVE_DIRFD /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `door' function. */ #undef HAVE_DOOR /* Define to 1 if you have the header file. */ #undef HAVE_DUSTAT_H /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H /* Define to 1 if you have the `endnetgrent' function. */ #undef HAVE_ENDNETGRENT /* Define to 1 if you have the `endpwent' function. */ #undef HAVE_ENDPWENT /* Define to 1 if you have the `fchmod' function. */ #undef HAVE_FCHMOD /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Whether to use fexecve(3) to execute a new process */ #undef HAVE_FEXECVE /* Define to 1 if you have the `fgetgrent' function. */ #undef HAVE_FGETGRENT /* Define to 1 if you have the `fgetpwent' function. */ #undef HAVE_FGETPWENT /* Define if fgetpwent and fgetgrent functions are present */ #undef HAVE_FGETPWENT_FGETGRENT /* Define if fgetspent is available */ #undef HAVE_FGETSPENT /* Define to 1 if you have the `fpathconf' function. */ #undef HAVE_FPATHCONF /* Define to 1 if you have the `gethostent' function. */ #undef HAVE_GETHOSTENT /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* Define to 1 if you have the `getifaddrs' function. */ #undef HAVE_GETIFADDRS /* Define to 1 if you have the `getloadavg' function. */ #undef HAVE_GETLOADAVG /* Define to 1 if you have the `getnetgrent' function. */ #undef HAVE_GETNETGRENT /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `getprocs64' function. */ #undef HAVE_GETPROCS64 /* Define to 1 if you have the `getpwent' function. */ #undef HAVE_GETPWENT /* Define to 1 if you have the `getzoneid' function. */ #undef HAVE_GETZONEID /* Define to 1 if you have the `getzonenamebyid' function. */ #undef HAVE_GETZONENAMEBYID /* Define to 1 if you have the header file. */ #undef HAVE_IEEEFP_H /* Define to 1 if the system has the type `intmax_t'. */ #undef HAVE_INTMAX_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `jail_get' function. */ #undef HAVE_JAIL_GET /* Define to 1 if you have the header file. */ #undef HAVE_KSTAT_H /* Whether to use lchown(3) to change ownerships */ #undef HAVE_LCHOWN /* Define to 1 if you have the `lckpwdf' function. */ #undef HAVE_LCKPWDF /* Define to 1 if you have the `acl' library (-lacl). */ #undef HAVE_LIBACL /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Define to 1 if you have the `curl' library (-lcurl). */ #undef HAVE_LIBCURL /* Define to 1 if you have the `dgc' library (-ldgc). */ #undef HAVE_LIBDGC /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the `kstat' library (-lkstat). */ #undef HAVE_LIBKSTAT /* Define to 1 if you have the `lmdb' library (-llmdb). */ #undef HAVE_LIBLMDB /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `mysqlclient' library (-lmysqlclient). */ #undef HAVE_LIBMYSQLCLIENT /* Define to 1 if you have the `nss_nis' library (-lnss_nis). */ #undef HAVE_LIBNSS_NIS /* Define to 1 if you have the `pam' library (-lpam). */ #undef HAVE_LIBPAM /* Define to 1 if you have the `pcre2-8' library (-lpcre2-8). */ #undef HAVE_LIBPCRE2_8 /* Define to 1 if you have the `pq' library (-lpq). */ #undef HAVE_LIBPQ /* Define to 1 if you have the header file. */ #undef HAVE_LIBPQ_FE_H /* Define to 1 if you have the `qdbm' library (-lqdbm). */ #undef HAVE_LIBQDBM /* Define to 1 if you have the `rt' library (-lrt). */ #undef HAVE_LIBRT /* Define if -lsec is available */ #undef HAVE_LIBSEC /* Define to 1 if you have the `ssl' library (-lssl). */ #undef HAVE_LIBSSL /* Define to 1 if you have the `systemd' library (-lsystemd). */ #undef HAVE_LIBSYSTEMD /* Define to 1 if you have the `tokyocabinet' library (-ltokyocabinet). */ #undef HAVE_LIBTOKYOCABINET /* Define to 1 if you have the `virt' library (-lvirt). */ #undef HAVE_LIBVIRT /* Define to 1 if you have the header file. */ #undef HAVE_LIBVIRT_LIBVIRT_H /* Define to 1 if you have the `xml2' library (-lxml2). */ #undef HAVE_LIBXML2 /* Define to 1 if you have the header file. */ #undef HAVE_LIBXML_XMLWRITER_H /* Define to 1 if you have the `yaml' library (-lyaml). */ #undef HAVE_LIBYAML /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_FS_H /* Define to 1 if you have the `llistxattr' function. */ #undef HAVE_LLISTXATTR /* Define to 1 if you have the header file. */ #undef HAVE_LMDB_H /* Define to 1 if you have the `localeconv' function. */ #undef HAVE_LOCALECONV /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if the system has the type `long double'. */ #undef HAVE_LONG_DOUBLE /* Define to 1 if the system has the type `long long int'. */ #undef HAVE_LONG_LONG_INT /* Define to 1 if you have the header file. */ #undef HAVE_MACH_MACH_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mkfifo' function. */ #undef HAVE_MKFIFO /* Define to 1 if BSD .msg_accrights supported */ #undef HAVE_MSGHDR_ACCRIGHTS /* Define to 1 if SCM_RIGHTS supported */ #undef HAVE_MSGHDR_MSG_CONTROL /* Define to 1 if you have the header file. */ #undef HAVE_MYSQL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_ARP_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_DL_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_ROUTE_H /* Define to 1 if you have the header file. */ #undef HAVE_NLIST_H /* Define to 1 if no BSD .msg_accrights support */ #undef HAVE_NO_MSGHDR_ACCRIGHTS /* Define to 1 if SCM_RIGHTS support */ #undef HAVE_NO_MSGHDR_MSG_CONTROL /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_OPENSSLV_H /* The old route entry structure in newer BSDs */ #undef HAVE_ORTENTRY /* Define to 1 if you have the header file. */ #undef HAVE_PCRE2_H /* Define to 1 if you have the `pstat_getdynamic' function. */ #undef HAVE_PSTAT_GETDYNAMIC /* Define to 1 if you have the `pstat_getfile2' function. */ #undef HAVE_PSTAT_GETFILE2 /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Define to 1 if the system has the type `ptrdiff_t'. */ #undef HAVE_PTRDIFF_T /* Define if pw tool is present */ #undef HAVE_PW /* Define if pwdadm tool is present */ #undef HAVE_PWDADM /* Define to 1 if you have the header file. */ #undef HAVE_QDBM_DEPOT_H /* Do we have any route entry structure? */ #undef HAVE_RTENTRY /* Define to 1 if you have the `sched_yield' function. */ #undef HAVE_SCHED_YIELD /* sd_notify_barrier on recent systemd */ #undef HAVE_SD_NOTIFY_BARRIER /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_APPL_H /* Define to 1 if you have the `sendfile' function. */ #undef HAVE_SENDFILE /* Define to 1 if you have the `sendto' function. */ #undef HAVE_SENDTO /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID /* Define to 1 if you have the `seteuid' function. */ #undef HAVE_SETEUID /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the `setnetgrent' function. */ #undef HAVE_SETNETGRENT /* Define to 1 if you have the `setpwent' function. */ #undef HAVE_SETPWENT /* Define to 1 if you have the `setregid' function. */ #undef HAVE_SETREGID /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `setsockopt' function. */ #undef HAVE_SETSOCKOPT /* Define to 1 if you have the header file. */ #undef HAVE_SHADOW_H /* Define to 1 if you have the `sleep' function. */ #undef HAVE_SLEEP /* Define to 1 if you have a C99 compliant `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* Define to 1 if the system has the type `socklen_t'. */ #undef HAVE_SOCKLEN_T /* Define to 1 if you have the `statfs' function. */ #undef HAVE_STATFS /* Define to 1 if you have the `statvfs' function. */ #undef HAVE_STATVFS /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if `ifr_hwaddr' is a member of `struct ifreq'. */ #undef HAVE_STRUCT_IFREQ_IFR_HWADDR /* Define to 1 if `decimal_point' is a member of `struct lconv'. */ #undef HAVE_STRUCT_LCONV_DECIMAL_POINT /* Define to 1 if `thousands_sep' is a member of `struct lconv'. */ #undef HAVE_STRUCT_LCONV_THOUSANDS_SEP /* Define to 1 if `n_un.n_name' is a member of `struct nlist'. */ #undef HAVE_STRUCT_NLIST_N_UN_N_NAME /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ #undef HAVE_STRUCT_SOCKADDR_SA_LEN /* Define to 1 if the system has the type `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE /* Define to 1 if `st_blocks' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLOCKS /* Define to 1 if `st_mtim' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_MTIM /* Define to 1 if `st_mtimespec' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_MTIMESPEC /* Define to 1 if `uptime' is a member of `struct sysinfo'. */ #undef HAVE_STRUCT_SYSINFO_UPTIME /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define to 1 if you have the `sysinfo' function. */ #undef HAVE_SYSINFO /* Define to 1 if you have the header file. */ #undef HAVE_SYSTEMD_SD_DAEMON_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ACL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILESYS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_JAIL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LOADAVG_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MOUNT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MPCTL_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PSTAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SENDFILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATVFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSMACROS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSTEMINFO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_VFS_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_XATTR_H /* Define to 1 if you have the header file. */ #undef HAVE_TCHDB_H /* Define to 1 if you have the header file. */ #undef HAVE_TCUTIL_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define if TLS 1.1 is supported by OpenSSL */ #undef HAVE_TLS_1_1 /* Define if TLS 1.2 is supported by OpenSSL */ #undef HAVE_TLS_1_2 /* Define if TLS 1.3 is supported by OpenSSL */ #undef HAVE_TLS_1_3 /* Define to 1 if the system has the type `uintmax_t'. */ #undef HAVE_UINTMAX_T /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T /* Define to 1 if you have the `ulckpwdf' function. */ #undef HAVE_ULCKPWDF /* Define to 1 if you have the `uname' function. */ #undef HAVE_UNAME /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if the system has the type `unsigned long long int'. */ #undef HAVE_UNSIGNED_LONG_LONG_INT /* Define if useradd tool is present */ #undef HAVE_USERADD /* Define if userdel tool is present */ #undef HAVE_USERDEL /* Define if usermod tool is present */ #undef HAVE_USERMOD /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMPX_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMP_H /* Define to 1 if you have the header file. */ #undef HAVE_VARARGS_H /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF /* Define to 1 if you have the `va_copy' function or macro. */ #undef HAVE_VA_COPY /* Define to 1 if you have the header file. */ #undef HAVE_VFS_H /* Define to 1 if you have a C99 compliant `vsnprintf' function. */ #undef HAVE_VSNPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_WINSOCK2_H /* Define to 1 if you have the header file. */ #undef HAVE_WS2TCPIP_H /* Define to 1 if you have the header file. */ #undef HAVE_YAML_H /* Define to 1 if you have the header file. */ #undef HAVE_ZONE_H /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to 1 if you have the `__va_copy' function or macro. */ #undef HAVE___VA_COPY /* Define to 1 if you have properly defined `ctime' function */ #undef HAVE_ctime_PROPER /* Define to 1 if you have properly defined `mkdir' function */ #undef HAVE_mkdir_PROPER /* Define to 1 if you have properly defined `rename' function */ #undef HAVE_rename_PROPER /* Define to 1 if you have properly defined `stat' function */ #undef HAVE_stat_PROPER /* Inputs directory location */ #undef INPUTDIR /* Define if Lightning MDB is available */ #undef LMDB /* Logdir location */ #undef LOGDIR /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Masterfiles directory location */ #undef MASTERDIR /* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend on `HAVE_STRUCT_NLIST_N_UN_N_NAME */ #undef NLIST_NAME_UNION /* Suppress deprecation warnings from OpenSSL 3 */ #undef OPENSSL_SUPPRESS_DEPRECATED /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* piddir location */ #undef PIDDIR /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* Path to pw tool */ #undef PW /* Path to pwdadm tool */ #undef PWDADM /* Define if QDBM is available */ #undef QDB /* Release number */ #undef RELEASE /* Whether sendto does not returns ssize_t */ #undef SENDTO_RETURNS_SSIZE_T /* Whether setnetgrent returns int */ #undef SETNETGRENT_RETURNS_INT /* Path to the POSIX-compatible shell */ #undef SHELL_PATH /* State directory location */ #undef STATEDIR /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 on System V Release 4. */ #undef SVR4 /* Define if Tokyo Cabinet is available. */ #undef TCDB /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 for Encore UMAX. */ #undef UMAX /* Define to 1 for Encore UMAX 4.3 that has instead of . */ #undef UMAX4_3 /* Path to useradd tool */ #undef USERADD /* Path to userdel tool */ #undef USERDEL /* Path to usermod tool */ #undef USERMOD /* Version number of package */ #undef VERSION /* Define if PCRE2 is being used */ #undef WITH_PCRE2 /* Define if you have a libc that supports extended attributes */ #undef WITH_XATTR /* Define if your xattr implementation has extra arguments */ #undef WITH_XATTR_EXTRA_ARGS /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Workdir location */ #undef WORKDIR /* Define if XEN cpuid-based HVM detection is available. */ #undef XEN_CPUID_SUPPORT /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE # define _DARWIN_USE_64_BIT_INODE 1 #endif /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Enable wide data structures everywhere */ #undef _PSTAT64 /* SUSv3 */ #undef _XOPEN_SOURCE /* Extended UNIX 98 interfaces */ #undef __EXTENSIONS__ /* Define to rpl_asprintf if the replacement function should be used. */ #undef asprintf /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to rpl_fprintf if the replacement function should be used. */ #undef fprintf /* Define to `int' if doesn't define. */ #undef gid_t /* Define to the widest signed integer type if and do not define. */ #undef intmax_t /* Define to `int' if does not define. */ #undef mode_t /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define to rpl_printf if the replacement function should be used. */ #undef printf /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to rpl_snprintf if the replacement function should be used. */ #undef snprintf /* Define to `int' if doesn't define. */ #undef uid_t /* Define to the widest unsigned integer type if and do not define. */ #undef uintmax_t /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t /* Define to rpl_vasprintf if the replacement function should be used. */ #undef vasprintf /* Define to rpl_vfprintf if the replacement function should be used. */ #undef vfprintf /* Define to rpl_vprintf if the replacement function should be used. */ #undef vprintf /* Define to rpl_vsnprintf if the replacement function should be used. */ #undef vsnprintf cfengine-3.24.2/cf-secret/0000755000000000000000000000000015010704323015224 5ustar00rootroot00000000000000cfengine-3.24.2/cf-secret/Makefile.am0000644000000000000000000000307515010704253017267 0ustar00rootroot00000000000000# # Copyright (C) CFEngine AS # # This file is part of CFEngine 3 - written and maintained by CFEngine AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-secret.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_secret_la_LIBADD = ../libpromises/libpromises.la libcf_secret_la_SOURCES = cf-secret.c if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-secret cf_secret_LDADD = libcf-secret.la cf_secret_SOURCES = endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-secret/cf-secret.c0000644000000000000000000010117215010704253017247 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* cf-secret.c Copyright (C) 2017 cfengineers.net Written and maintained by Jon Henrik Bjornstad Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include #include #include #include #include /* GenericAgentSetDefaultDigest */ #include #include #include #include #include #include #include #include #include #include #include /* DoCleanupAndExit(), CallCleanupFunctions() */ #include #define BUFSIZE 1024 #define MAX_HEADER_LEN 256 /* "Key[126]: Value[128]" */ #define MAX_HEADER_KEY_LEN 126 #define MAX_HEADER_VAL_LEN 128 typedef enum { HOST_RSA_KEY_PRIVATE, HOST_RSA_KEY_PUBLIC, } HostRSAKeyType; /* see README.md for details about the format */ typedef enum { CF_SECRET_FORMAT_V_1_0, } CFKeyCryptFormatVersion; static const char passphrase[] = "Cfengine passphrase"; //******************************************************************* // DOCUMENTATION / GETOPT CONSTS: //******************************************************************* static const char *const CF_SECRET_SHORT_DESCRIPTION = "cf-secret: Use CFEngine cryptographic keys to encrypt and decrypt files"; static const char *const CF_SECRET_MANPAGE_LONG_DESCRIPTION = "cf-secret offers a simple way to encrypt or decrypt files using keys " "generated by cf-key. CFEngine uses asymmetric cryptography, and " "cf-secret allows you to encrypt a file using a public key file. " "The encrypted file can only be decrypted on the host with the " "corresponding private key. Original author: Jon Henrik Bjornstad " ""; static const Component COMPONENT = { .name = "cf-secrets", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"help", no_argument, 0, 'h'}, {"manpage", no_argument, 0, 'M'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"log-level", required_argument, 0, 'g'}, {"inform", no_argument, 0, 'I'}, {"key", required_argument, 0, 'k'}, {"host", required_argument, 0, 'H'}, {"output", required_argument, 0, 'o'}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Print the man page", "Enable debugging output", "Enable verbose output", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Enable basic information output", "Comma-separated list of key files to use (one of -k/-H options is required for encryption)", "Comma-separated list of hosts to encrypt/decrypt for (defaults to 'localhost' for decryption)", "Output file (required)", NULL }; static const Description COMMANDS[] = { {"encrypt", "Encrypt data for one or more hosts/keys", "cf-secret encrypt -k/-H KEY/HOST -o OUTPUT INPUT"}, {"decrypt", "Decrypt data", "cf-secret decrypt [-k/-H KEY/HOST] -o OUTPUT INPUT"}, {"print-headers", "Print headers from an encrypted file", "cf-secret print-headers ENCRYPTED_FILE"}, {NULL, NULL, NULL} }; static inline void *GetIPAddress(struct sockaddr *sa) { assert(sa != NULL); if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } /** * Get path of the RSA key for the given host. */ static char *GetHostRSAKey(const char *host, HostRSAKeyType type) { const char *key_ext = NULL; if (type == HOST_RSA_KEY_PRIVATE) { key_ext = ".priv"; } else { key_ext = ".pub"; } struct addrinfo *result; int error = getaddrinfo(host, NULL, NULL, &result); if (error != 0) { Log(LOG_LEVEL_ERR, "Failed to get IP from host (getaddrinfo: %s)", gai_strerror(error)); return NULL; } char *buffer = malloc(PATH_MAX); char hash[CF_HOSTKEY_STRING_SIZE]; char ipaddress[64]; bool found = false; for (struct addrinfo *res = result; !found && (res != NULL); res = res->ai_next) { inet_ntop(res->ai_family, GetIPAddress((struct sockaddr *) res->ai_addr), ipaddress, sizeof(ipaddress)); if (StringIsLocalHostIP(ipaddress)) { Log(LOG_LEVEL_VERBOSE, "Using localhost%s key", key_ext); found = true; int ret = snprintf(buffer, PATH_MAX, "%s/ppkeys/localhost%s", GetWorkDir(), key_ext); if (ret < 0 || ret >= PATH_MAX) { Log(LOG_LEVEL_ERR, "Path to RSA key is too long (%d > %d)", ret, PATH_MAX - 1); freeaddrinfo(result); return NULL; } freeaddrinfo(result); return buffer; } found = Address2Hostkey(hash, sizeof(hash), ipaddress); } if (found) { Log(LOG_LEVEL_DEBUG, "Found host '%s' for address '%s'", hash, ipaddress); int ret = snprintf(buffer, PATH_MAX, "%s/ppkeys/root-%s%s", GetWorkDir(), hash, key_ext); if (ret < 0 || ret >= PATH_MAX) { Log(LOG_LEVEL_ERR, "Path to RSA key is too long (%d > %d)", ret, PATH_MAX - 1); freeaddrinfo(result); return NULL; } freeaddrinfo(result); return buffer; } else { Log(LOG_LEVEL_DEBUG, "Searching key by IP"); for (struct addrinfo *res = result; res != NULL; res = res->ai_next) { inet_ntop(res->ai_family, GetIPAddress((struct sockaddr *) res->ai_addr), ipaddress, sizeof(ipaddress)); int ret = snprintf(buffer, BUFSIZE, "%s/ppkeys/root-%s%s", GetWorkDir(), ipaddress, key_ext); if (ret < 0 || ret >= PATH_MAX) { Log(LOG_LEVEL_ERR, "Path to RSA key is too long (%d > %d)", ret, PATH_MAX - 1); freeaddrinfo(result); return NULL; } if (access(buffer, F_OK) == 0) { Log(LOG_LEVEL_DEBUG, "Found matching key: '%s'", buffer); freeaddrinfo(result); return buffer; } } } freeaddrinfo(result); return NULL; } static RSA *ReadPrivateKey(const char *privkey_path) { FILE *fp = safe_fopen(privkey_path,"r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Could not open private key '%s'", privkey_path); return NULL; } RSA *privkey = PEM_read_RSAPrivateKey(fp, (RSA **) NULL, NULL, (void *) passphrase); if (privkey == NULL) { unsigned long err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Could not read private key '%s': %s", privkey_path, ERR_reason_error_string(err)); } fclose(fp); return privkey; } static RSA *ReadPublicKey(const char *pubkey_path) { FILE *fp = safe_fopen(pubkey_path, "r"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Could not open public key '%s'", pubkey_path); return NULL; } RSA *pubkey = PEM_read_RSAPublicKey(fp, NULL, NULL, (void *) passphrase); if (pubkey == NULL) { unsigned long err = ERR_get_error(); Log(LOG_LEVEL_ERR, "Could not read public key '%s': %s", pubkey_path, ERR_reason_error_string(err)); } fclose(fp); return pubkey; } static FILE *OpenInputOutput(const char *path, const char *mode) { assert(path != NULL); assert(mode != NULL); if (StringEqual(path, "-")) { if (*mode == 'r') { return stdin; } else { return stdout; } } return safe_fopen(path, mode); } static bool RSAEncrypt(Seq *rsa_keys, const char *input_path, const char *output_path) { assert((rsa_keys != NULL) && (SeqLength(rsa_keys) > 0)); FILE *input_file = OpenInputOutput(input_path, "r"); if (input_file == NULL) { Log(LOG_LEVEL_ERR, "Could not open input file '%s'", input_path); return false; } FILE *output_file = OpenInputOutput(output_path, "w"); if (output_file == NULL) { Log(LOG_LEVEL_ERR, "Could not create or open output file '%s'", output_path); fclose(input_file); return false; } const size_t n_keys = SeqLength(rsa_keys); Seq *evp_keys = SeqNew(n_keys, EVP_PKEY_free); for (size_t i = 0; i < n_keys; i++) { RSA *rsa_key = SeqAt(rsa_keys, i); EVP_PKEY *evp_key = EVP_PKEY_new(); if (EVP_PKEY_set1_RSA(evp_key, rsa_key) == 0) { Log(LOG_LEVEL_ERR, "Failed to initialize encryption context"); SeqDestroy(evp_keys); fclose(input_file); fclose(output_file); return false; } SeqAppend(evp_keys, evp_key); } bool success = true; const EVP_CIPHER *cipher = EVP_aes_256_cbc(); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); const int key_size = EVP_PKEY_size((EVP_PKEY*) SeqAt(evp_keys, 0)); /* This sequence and the 'enc_key_sizes' array are both populated by the * EVP_SealInit() call below. */ Seq *enc_keys = SeqNew(n_keys, free); for (size_t i = 0; i < n_keys; i++) { SeqAppend(enc_keys, xmalloc(key_size)); } int enc_key_sizes[n_keys]; const int iv_size = EVP_CIPHER_iv_length(cipher); unsigned char iv[iv_size]; const int block_size = EVP_CIPHER_block_size(cipher); char plaintext[block_size], ciphertext[2 * block_size]; int ct_len; int ret = EVP_SealInit(ctx, cipher, (unsigned char**) SeqGetData(enc_keys), enc_key_sizes, iv, (EVP_PKEY**) SeqGetData(evp_keys), n_keys); if (ret == 0) { Log(LOG_LEVEL_ERR, "Failed to initialize encryption context"); success = false; goto cleanup; } /* newline and NUL-byte => +2 */ Log(LOG_LEVEL_VERBOSE, "Writing headers"); char header[MAX_HEADER_LEN + 2] = "Version: 1.0\n"; size_t header_len = strlen(header); ssize_t n_written = FullWrite(fileno(output_file), header, header_len); if (n_written < 0 || (size_t) n_written != header_len) { Log(LOG_LEVEL_ERR, "Failed to write header to the output file '%s'", output_path); success = false; goto cleanup; } Log(LOG_LEVEL_VERBOSE, "Writing Encrypted-for headers"); for (size_t i = 0; i < n_keys; i++) { char *key_digest = GetPubkeyDigest(SeqAt(rsa_keys, i)); header_len = snprintf(header, MAX_HEADER_LEN + 2, "Encrypted-for: %s\n", key_digest); free(key_digest); assert(header_len <= (MAX_HEADER_LEN + 2)); n_written = FullWrite(fileno(output_file), header, header_len); if ((size_t) n_written != header_len) { Log(LOG_LEVEL_ERR, "Failed to write header to the output file '%s'", output_path); success = false; goto cleanup; } } n_written = FullWrite(fileno(output_file), "\n", 1); if (n_written != 1) { Log(LOG_LEVEL_ERR, "Failed to write header to the output file '%s'", output_path); success = false; goto cleanup; } Log(LOG_LEVEL_VERBOSE, "Writing IV"); n_written = FullWrite(fileno(output_file), iv, iv_size); if (n_written != iv_size) { Log(LOG_LEVEL_ERR, "Failed to write IV to the output file '%s'", output_path); success = false; goto cleanup; } Log(LOG_LEVEL_VERBOSE, "Writing keys"); for (size_t i = 0; i < n_keys; i++) { const char *enc_key = SeqAt(enc_keys, i); n_written = FullWrite(fileno(output_file), enc_key, enc_key_sizes[i]); if (n_written != enc_key_sizes[i]) { Log(LOG_LEVEL_ERR, "Failed to write key to the output file '%s'", output_path); success = false; goto cleanup; } } size_t processed = 0; while (success && !feof(input_file)) { ssize_t n_read = ReadFileStreamToBuffer(input_file, block_size, plaintext); if (n_read == FILE_ERROR_READ) { Log(LOG_LEVEL_ERR, "Could not read file '%s'", input_path); success = false; break; } ret = EVP_SealUpdate(ctx, ciphertext, &ct_len, plaintext, n_read); if (ret == 0) { Log(LOG_LEVEL_ERR, "Failed to encrypt data: %s", ERR_error_string(ERR_get_error(), NULL)); success = false; break; } n_written = FullWrite(fileno(output_file), ciphertext, ct_len); if (n_written < 0) { Log(LOG_LEVEL_ERR, "Could not write file '%s'", output_path); success = false; break; } processed += n_read; Log(LOG_LEVEL_VERBOSE, "%zu bytes processed", processed); } Log(LOG_LEVEL_VERBOSE, "Finalizing"); ret = EVP_SealFinal(ctx, ciphertext, &ct_len); if (ret == 0) { Log(LOG_LEVEL_ERR, "Failed to encrypt data: %s", ERR_error_string(ERR_get_error(), NULL)); success = false; } if (ct_len > 0) { n_written = FullWrite(fileno(output_file), ciphertext, ct_len); if (n_written < 0) { Log(LOG_LEVEL_ERR, "Could not write file '%s'", output_path); success = false; } } OPENSSL_cleanse(plaintext, block_size); cleanup: fclose(input_file); fclose(output_file); SeqDestroy(evp_keys); SeqDestroy(enc_keys); EVP_CIPHER_CTX_free(ctx); return success; } static inline bool CheckHeader(const char *key, const char *value) { if (StringEqual(key, "Version")) { if (!StringEqual(value, "1.0")) { Log(LOG_LEVEL_ERR, "Unsupported file format version: '%s'", value); return false; } else { return true; } } else if (StringEqual(key, "Encrypted-for")) { /* TODO: do some verification that 'value' is valid hash digest? */ return true; } else { Log(LOG_LEVEL_ERR, "Unsupported header: '%s'", key); return false; } } /** * Read from #input_file into #buffer at most #max_chars or until #delimiter is * encountered. If #stop_on_space, also stop when ' ' is read. #buffer is * NUL-terminated when this function returns. * * @warning #buffer has to be at least #max_chars+1 big to accommodate for the * terminating NUL byte. */ static inline bool ReadUntilDelim(FILE *input_file, char *buffer, size_t max_chars, char delimiter, bool stop_on_space) { bool done = false; size_t i = 0; int c = fgetc(input_file); while (!done && (i < max_chars)) { if (c == EOF) { done = true; } else if (c == delimiter) { done = true; ungetc(c, input_file); } else if (stop_on_space && (c == ' ')) { done = true; ungetc(c, input_file); } else { buffer[i] = (char) c; i++; if (i < max_chars) { c = fgetc(input_file); } } } buffer[i] = '\0'; bool ran_out = ((i > max_chars) || (c == EOF)); return !ran_out; } static inline void SkipSpaces(FILE *input_file) { int c = ' '; while (!feof(input_file) && (c == ' ')) { c = fgetc(input_file); } if (c != ' ') { ungetc(c, input_file); } } static inline bool ParseHeader(FILE *input_file, char *key, char *value) { bool ok = ReadUntilDelim(input_file, key, MAX_HEADER_KEY_LEN, ':', true); if (ok) { SkipSpaces(input_file); ok = (fgetc(input_file) == ':'); SkipSpaces(input_file); ok = ReadUntilDelim(input_file, value, MAX_HEADER_VAL_LEN, '\n', false); } ok = (fgetc(input_file) == '\n'); return ok; } static bool ParseHeaders(FILE *input_file, RSA *privkey, size_t *enc_key_pos, size_t *n_enc_keys) { assert(enc_key_pos != NULL); assert(n_enc_keys != NULL); /* Make sure these are always set by this function. */ *enc_key_pos = 0; *n_enc_keys = 0; /* Actually works for a private RSA key too because it contains the public * key. */ char *key_digest = GetPubkeyDigest(privkey); bool version_specified = false; bool found_matching_digest = false; size_t n_enc_for_headers = 0; char key[MAX_HEADER_KEY_LEN + 1]; char value[MAX_HEADER_VAL_LEN + 1]; while (ParseHeader(input_file, key, value)) { Log(LOG_LEVEL_DEBUG, "Parsed header '%s: %s'", key, value); if (!CheckHeader(key, value)) { free(key_digest); return false; } if (StringEqual(key, "Version")) { version_specified = true; } else if (StringEqual(key, "Encrypted-for")) { Log(LOG_LEVEL_DEBUG, "Encrypted for '%s'", value); if (StringEqual(value, key_digest)) { found_matching_digest = true; *enc_key_pos = n_enc_for_headers; } n_enc_for_headers++; } /* headers are supposed to be terminated by a blank line */ int next = fgetc(input_file); if (next == '\n') { if (!version_specified) { Log(LOG_LEVEL_ERR, "File format version not specified"); } if (!found_matching_digest) { Log(LOG_LEVEL_ERR, "File not encrypted for host '%s'", key_digest); } *n_enc_keys = n_enc_for_headers; free(key_digest); return (version_specified && found_matching_digest); } else if (next == EOF) { Log(LOG_LEVEL_ERR, "Failed to parse headers from"); free(key_digest); return false; } else { /* keep trying */ ungetc(next, input_file); } } Log(LOG_LEVEL_ERR, "Failed to parse headers"); free(key_digest); return false; } static bool RSADecrypt(RSA *privkey, const char *input_path, const char *output_path) { FILE *input_file = OpenInputOutput(input_path, "r"); if (input_file == NULL) { Log(LOG_LEVEL_ERR, "Cannot open input file '%s'", input_path); return false; } FILE *output_file = OpenInputOutput(output_path, "w"); if (output_file == NULL) { Log(LOG_LEVEL_ERR, "Cannot open output file '%s'", output_path); fclose(input_file); return false; } EVP_PKEY *evp_key = EVP_PKEY_new(); if (EVP_PKEY_set1_RSA(evp_key, privkey) == 0) { Log(LOG_LEVEL_ERR, "Failed to initialize decryption context"); fclose(input_file); fclose(output_file); return false; } bool success = true; Log(LOG_LEVEL_VERBOSE, "Parsing headers"); size_t our_key_pos; size_t n_enc_keys; if (!ParseHeaders(input_file, privkey, &our_key_pos, &n_enc_keys)) { fclose(input_file); fclose(output_file); return false; } Log(LOG_LEVEL_DEBUG, "Parsed %zu keys", n_enc_keys); const EVP_CIPHER *cipher = EVP_aes_256_cbc(); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); const int iv_size = EVP_CIPHER_iv_length(cipher); unsigned char iv[iv_size]; const int key_size = EVP_PKEY_size(evp_key); unsigned char ek[key_size]; unsigned char dev_null[key_size]; const int block_size = EVP_CIPHER_block_size(cipher); char plaintext[block_size], ciphertext[2 * block_size]; int pt_len; ssize_t n_read = ReadFileStreamToBuffer(input_file, iv_size, iv); if (n_read != iv_size) { Log(LOG_LEVEL_ERR, "Failed to read the IV from '%s'", input_path); goto cleanup; } /* just skip the keys that are not ours */ size_t nth_key = 0; for (; nth_key < our_key_pos; nth_key++) { n_read = ReadFileStreamToBuffer(input_file, key_size, dev_null); if (n_read != key_size) { Log(LOG_LEVEL_ERR, "Failed to read the key from '%s'", input_path); goto cleanup; } Log(LOG_LEVEL_DEBUG, "Skipping key"); } /* read our key */ Log(LOG_LEVEL_DEBUG, "Reading key"); n_read = ReadFileStreamToBuffer(input_file, key_size, ek); if (n_read != key_size) { Log(LOG_LEVEL_ERR, "Failed to read the key from '%s'", input_path); goto cleanup; } nth_key++; /* skip the remaining keys */ for (; nth_key < n_enc_keys; nth_key++) { n_read = ReadFileStreamToBuffer(input_file, key_size, dev_null); if (n_read != key_size) { Log(LOG_LEVEL_ERR, "Failed to read the key from '%s'", input_path); goto cleanup; } Log(LOG_LEVEL_DEBUG, "Skipping key"); } int ret = EVP_OpenInit(ctx, cipher, ek, key_size, iv, evp_key); if (ret == 0) { char *key_digest = GetPubkeyDigest(privkey); Log(LOG_LEVEL_ERR, "Failed to decrypt contents using key '%s'", key_digest); free(key_digest); success = false; goto cleanup; } Log(LOG_LEVEL_VERBOSE, "Decrypting data"); size_t processed = 0; ssize_t n_written; while (success && !feof(input_file)) { n_read = ReadFileStreamToBuffer(input_file, block_size, ciphertext); if (n_read == FILE_ERROR_READ) { Log(LOG_LEVEL_ERR, "Could not read file '%s'", input_path); success = false; break; } ret = EVP_OpenUpdate(ctx, plaintext, &pt_len, ciphertext, n_read); if (ret == 0) { Log(LOG_LEVEL_ERR, "Failed to decrypt data: %s", ERR_error_string(ERR_get_error(), NULL)); success = false; break; } n_written = FullWrite(fileno(output_file), plaintext, pt_len); if (n_written < 0) { Log(LOG_LEVEL_ERR, "Could not write file '%s'", output_path); success = false; break; } processed += n_read; Log(LOG_LEVEL_VERBOSE, "%zu bytes processed", processed); } Log(LOG_LEVEL_VERBOSE, "Finalizing"); ret = EVP_OpenFinal(ctx, plaintext, &pt_len); if (ret == 0) { Log(LOG_LEVEL_ERR, "Failed to decrypt data: %s", ERR_error_string(ERR_get_error(), NULL)); success = false; } if (pt_len > 0) { n_written = FullWrite(fileno(output_file), plaintext, pt_len); if (n_written < 0) { Log(LOG_LEVEL_ERR, "Could not write file '%s'", output_path); success = false; } } OPENSSL_cleanse(plaintext, block_size); cleanup: fclose(input_file); fclose(output_file); EVP_PKEY_free(evp_key); EVP_CIPHER_CTX_free(ctx); return success; } static Seq *LoadPublicKeys(Seq *key_paths) { const size_t n_keys = SeqLength(key_paths); Seq *pub_keys = SeqNew(n_keys, RSA_free); for (size_t i = 0; i < n_keys; i++) { const char *key_path = SeqAt(key_paths, i); Log(LOG_LEVEL_VERBOSE, "Reading key '%s'", key_path); RSA *pubkey = ReadPublicKey(key_path); if (pubkey == NULL) { SeqDestroy(pub_keys); return NULL; } SeqAppend(pub_keys, pubkey); } return pub_keys; } static void CFKeyCryptHelp() { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, COMMANDS, true, true); FileWriterDetach(w); } void CFKeyCryptMan() { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-secret", time(NULL), CF_SECRET_SHORT_DESCRIPTION, CF_SECRET_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, COMMANDS, true, true); FileWriterDetach(out); } int main(int argc, char *argv[]) { if (argc < 2) { CFKeyCryptHelp(); DoCleanupAndExit(EXIT_FAILURE); } opterr = 0; char *key_path_arg = NULL; char *input_path = NULL; char *output_path = NULL; char *host_arg = NULL; bool encrypt = false; bool decrypt = false; bool print_headers = false; size_t offset = 0; if (StringEqual(argv[1], "encrypt")) { encrypt = true; offset++; } else if (StringEqual(argv[1], "decrypt")) { offset++; decrypt = true; } else if (StringEqual(argv[1], "print-headers")) { print_headers = true; offset++; } int c = 0; while ((c = getopt_long(argc - offset, argv + offset, "hMedk:o:H:", OPTIONS, NULL)) != -1) { switch (c) { case 'h': CFKeyCryptHelp(); DoCleanupAndExit(EXIT_SUCCESS); break; case 'M': CFKeyCryptMan(); DoCleanupAndExit(EXIT_SUCCESS); break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); Log(LOG_LEVEL_DEBUG, "Debug log level enabled"); break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); Log(LOG_LEVEL_VERBOSE, "Verbose log level enabled"); break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); Log(LOG_LEVEL_INFO, "Inform log level enabled"); break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'k': key_path_arg = optarg; break; case 'o': output_path = optarg; break; case 'H': host_arg = optarg; break; default: Log(LOG_LEVEL_ERR, "Unknown option '-%c'", optopt); CFKeyCryptHelp(); DoCleanupAndExit(EXIT_FAILURE); } } if (!(decrypt || encrypt || print_headers)) { printf("Command required. Specify either 'encrypt', 'decrypt' or 'print-headers'\n"); CFKeyCryptHelp(); DoCleanupAndExit(EXIT_FAILURE); } /* Increment 'optind' because of command being argv[0]. */ optind++; input_path = argv[optind]; /* Some more unexpected arguments? */ if ((size_t) argc > (optind + offset)) { Log(LOG_LEVEL_ERR, "Unexpected non-option argument: '%s'", argv[optind + 1]); DoCleanupAndExit(EXIT_FAILURE); } if (print_headers) { FILE *input_file = OpenInputOutput(input_path, "r"); char key[MAX_HEADER_KEY_LEN + 1]; char value[MAX_HEADER_VAL_LEN + 1]; bool done = false; while (!done && ParseHeader(input_file, key, value)) { Log(LOG_LEVEL_DEBUG, "Parsed header '%s: %s'", key, value); if (!CheckHeader(key, value)) { fclose(input_file); DoCleanupAndExit(EXIT_FAILURE); } printf("%s: %s\n", key, value); /* headers are supposed to be terminated by a blank line */ int next = fgetc(input_file); if (next == '\n') { done = true; } else { ungetc(next, input_file); } } fclose(input_file); DoCleanupAndExit(EXIT_SUCCESS); } if (decrypt && (host_arg == NULL) && (key_path_arg == NULL)) { /* Decryption requires a private key which is usually only available for * the local host. Let's just default to localhost if no other specific * host/key is given for decryption. */ Log(LOG_LEVEL_VERBOSE, "Using the localhost private key for decryption"); host_arg = "localhost"; } if ((host_arg != NULL) && (key_path_arg != NULL)) { Log(LOG_LEVEL_ERR, "--host/-H is used to specify a public key and cannot be used with --key/-k"); DoCleanupAndExit(EXIT_FAILURE); } if (input_path == NULL) { Log(LOG_LEVEL_ERR, "No input file specified (Use -h for help)"); DoCleanupAndExit(EXIT_FAILURE); } if (output_path == NULL) { Log(LOG_LEVEL_ERR, "No output file specified (Use -h for help)"); DoCleanupAndExit(EXIT_FAILURE); } CryptoInitialize(); GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN); Seq *key_paths; if (key_path_arg != NULL) { Log(LOG_LEVEL_DEBUG, "-k/--key given: '%s'", key_path_arg); key_paths = SeqStringFromString(key_path_arg, ','); } else { key_paths = SeqNew(16, free); } // Default to localhost on encryption char *localhost = "127.0.0.1"; if (encrypt && key_path_arg == NULL && host_arg == NULL) { host_arg = localhost; } if (host_arg != NULL) { Log(LOG_LEVEL_DEBUG, "-H/--host given: '%s'", host_arg); Seq *hosts = SeqStringFromString(host_arg, ','); const size_t n_hosts = SeqLength(hosts); for (size_t i = 0; i < n_hosts; i++) { HostRSAKeyType key_type = encrypt ? HOST_RSA_KEY_PUBLIC : HOST_RSA_KEY_PRIVATE; char *host = SeqAt(hosts, i); char *host_key_path = GetHostRSAKey(host, key_type); if (!host_key_path) { Log(LOG_LEVEL_ERR, "Unable to locate key for host '%s'", host); SeqDestroy(hosts); SeqDestroy(key_paths); DoCleanupAndExit(EXIT_FAILURE); } SeqAppend(key_paths, host_key_path); } SeqDestroy(hosts); } assert ((key_paths != NULL) && (SeqLength(key_paths) > 0)); // Encrypt or decrypt bool success; if (encrypt) { Log(LOG_LEVEL_DEBUG, "Encrypting"); Seq *pub_keys = LoadPublicKeys(key_paths); SeqDestroy(key_paths); if (pub_keys == NULL) { Log(LOG_LEVEL_ERR, "Failed to load public key(s)"); DoCleanupAndExit(EXIT_FAILURE); } success = RSAEncrypt(pub_keys, input_path, output_path); SeqDestroy(pub_keys); if (!success) { Log(LOG_LEVEL_ERR, "Encryption failed"); DoCleanupAndExit(EXIT_FAILURE); } } else if (decrypt) { Log(LOG_LEVEL_DEBUG, "Decrypting"); const size_t n_keys = SeqLength(key_paths); if (n_keys > 1) { Log(LOG_LEVEL_ERR, "--decrypt requires only one key/host to be specified"); SeqDestroy(key_paths); DoCleanupAndExit(EXIT_FAILURE); } RSA *private_key = ReadPrivateKey((char *) SeqAt(key_paths, 0)); SeqDestroy(key_paths); success = RSADecrypt(private_key, input_path, output_path); RSA_free(private_key); if (!success) { Log(LOG_LEVEL_ERR, "Decryption failed"); DoCleanupAndExit(EXIT_FAILURE); } } else { ProgrammingError("Unexpected error in cf-secret"); DoCleanupAndExit(EXIT_FAILURE); } CallCleanupFunctions(); return 0; } cfengine-3.24.2/cf-secret/Makefile.in0000644000000000000000000006264715010704300017303 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-secret$(EXEEXT) subdir = cf-secret ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_secret_la_DEPENDENCIES = ../libpromises/libpromises.la am_libcf_secret_la_OBJECTS = cf-secret.lo libcf_secret_la_OBJECTS = $(am_libcf_secret_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_cf_secret_OBJECTS = cf_secret_OBJECTS = $(am_cf_secret_OBJECTS) @BUILTIN_EXTENSIONS_FALSE@cf_secret_DEPENDENCIES = libcf-secret.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_secret_la_SOURCES) $(cf_secret_SOURCES) DIST_SOURCES = $(libcf_secret_la_SOURCES) $(cf_secret_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright (C) CFEngine AS # # This file is part of CFEngine 3 - written and maintained by CFEngine AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-secret.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_secret_la_LIBADD = ../libpromises/libpromises.la libcf_secret_la_SOURCES = cf-secret.c @BUILTIN_EXTENSIONS_FALSE@cf_secret_LDADD = libcf-secret.la @BUILTIN_EXTENSIONS_FALSE@cf_secret_SOURCES = CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-secret/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-secret/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-secret.la: $(libcf_secret_la_OBJECTS) $(libcf_secret_la_DEPENDENCIES) $(EXTRA_libcf_secret_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_secret_la_OBJECTS) $(libcf_secret_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-secret$(EXEEXT): $(cf_secret_OBJECTS) $(cf_secret_DEPENDENCIES) $(EXTRA_cf_secret_DEPENDENCIES) @rm -f cf-secret$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_secret_OBJECTS) $(cf_secret_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-secret.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/examples/0000755000000000000000000000000015010704323015167 5ustar00rootroot00000000000000cfengine-3.24.2/examples/zenoss.cf0000644000000000000000000000436215010704253017031 0ustar00rootroot00000000000000 ###################################################################### # # Zenoss integration template example # ###################################################################### body common control { bundlesequence => { "zenoss_host", "zenoss_client" }; syslog_host => "zenoss_syslog.example.org"; syslog_port => "514"; inputs => { "$(sys.libdir)/stdlib.cf" }; } ######################################################## bundle agent zenoss_host { vars: "cf_server_hosts" string => "cfengine_policy.example.org"; "cf_doc_root" string => "/srv/www/html"; "zCfengineComplianceFile" string => "/home/zenoss/compliance.zen"; files: # Assume Cfengine is running on the zenoss server to collect data zenoss_syslog_example_org:: "$(zCfengineComplianceFile)" comment => "Collect data from the Cfengine policy server", perms => mo("644","zenoss"), copy_from => secure_cp("$(cf_doc_root)/reports/summary.z","$(cf_server_host)"); } ######################################################## bundle agent zenoss_client { processes: # On clients, we just pass any messages to the zenoss server # for logging... "bad_process" comment => "Make sure that process X is not running, tell zenoss if it was", signals => { "term", "kill" }, action => tell_zenoss_repaired("bad_process was killed"); files: "/etc/passwd" comment => "Check passwd security, tell zenoss if permissions were wrong", perms => mog("644","root","root"), action => tell_zenoss_repaired("passwd file had incorrect permissions"); commands: "/my/important/script -xyz" comment => "Run my mission critical batch process", action => tell_zenoss_failed("myscript failed to execute or returned error"); } # # Library stuff # body action tell_zenoss_repaired(x) { log_repaired => "udp_syslog"; log_string => "zenoss_cfengine_integration $(x) promise repaired"; ifelapsed => "10"; # Every 10 mins } body action tell_zenoss_failed(x) { log_failed => "udp_syslog"; log_string => "zenoss_cfengine_integration $(x) persistent problem"; ifelapsed => "10"; # Every 10 mins } cfengine-3.24.2/examples/namespace_classes.cf0000644000000000000000000000700415010704253021155 0ustar00rootroot00000000000000bundle agent __main__ { methods: "mynamespace:my_bundle"; reports: a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'a_bundle_scoped_class_in_my_namespaced_bundle::'"; !a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I do not see 'a_bundle_scoped_class_in_my_namespaced_bundle::'"; a_namespace_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'a_namespace_scoped_class_in_my_namespaced_bundle::'"; !a_namespace_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I do not see 'a_namespace_scoped_class_in_my_namespaced_bundle::'"; mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle::'"; !mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I do not see 'mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle::'"; mynamespace:a_namespace_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'mynamespace:a_namespace_scoped_class_in_my_namespaced_bundle::'"; } body file control { namespace => "mynamespace"; } bundle agent my_bundle { classes: "a_bundle_scoped_class_in_my_namespaced_bundle"; "a_namespace_scoped_class_in_my_namespaced_bundle" scope => "namespace"; reports: a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'a_bundle_scoped_class_in_my_namespaced_bundle::'"; !a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I do not see 'a_bundle_scoped_class_in_my_namespaced_bundle::'"; a_namespace_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'a_namespace_scoped_class_in_my_namespaced_bundle::'"; !a_namespace_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I do not see 'a_namespace_scoped_class_in_my_namespaced_bundle::'"; mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle::'"; !mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I do not see 'mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle::'"; mynamespace:a_namespace_scoped_class_in_my_namespaced_bundle:: "In $(this.namespace):$(this.bundle) I see 'mynamespace:a_namespace_scoped_class_in_my_namespaced_bundle::'"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: In mynamespace:my_bundle I see 'a_bundle_scoped_class_in_my_namespaced_bundle::' #@ R: In mynamespace:my_bundle I see 'a_namespace_scoped_class_in_my_namespaced_bundle::' #@ R: In mynamespace:my_bundle I see 'mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle::' #@ R: In mynamespace:my_bundle I see 'mynamespace:a_namespace_scoped_class_in_my_namespaced_bundle::' #@ R: In default:main I do not see 'a_bundle_scoped_class_in_my_namespaced_bundle::' #@ R: In default:main I do not see 'a_namespace_scoped_class_in_my_namespaced_bundle::' #@ R: In default:main I do not see 'mynamespace:a_bundle_scoped_class_in_my_namespaced_bundle::' #@ R: In default:main I see 'mynamespace:a_namespace_scoped_class_in_my_namespaced_bundle::' #@ ``` #+end_src cfengine-3.24.2/examples/server_copy_remote.cf0000644000000000000000000000666315010704253021431 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test copy from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-v] (on remote-host.example.org) # cf-agent -f runtest_2.cf (on host 1.2.3.4) # # Notice that the same file configures all parts of cfengine # even though different parts are read by different hosts and agents ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/tmp/testcopy" perms => system, copy_from => mycopy("/src/document","remote-host.example.org"), depth_search => recurse("inf"); } ######################################################## body perms system { mode => "0444"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } ######################################################### body copy_from mycopy(from,server) { source => "$(from)"; #portnumber => "6789"; servers => { "$(server)" , "failover1" }; copy_backup => "true"; #/false/timestamp stealth => "true"; #/on/false/off preserve => "true"; linkcopy_patterns => { ".*fish.*" }; copylink_patterns => { "non-local.*"}; compare => "mtime"; # ctime/mtime/checksum/sum/byte/binary/any link_type => "absolute"; # /symbolic/relative/hard etc type_check => "true"; force_update => "false"; force_ipv4 => "false"; copy_size => irange("0","50000"); trustkey => "true"; encrypt => "true"; verify => "true"; purge => "false"; findertype => "MacOSX"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "1.2.3.4" , "::1" }; allowallconnects => { "1.2.3.4" , "::1" }; trustkeysfrom => { "1.2.3.4" , "::1" }; # allowusers } ######################################################### bundle server access_rules() { access: # Grant access to the remote client to access the source docs "/src" admit => { "1.2.3.4" }; } cfengine-3.24.2/examples/cf_version_between.cf0000644000000000000000000000076315010704253021357 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This will be skipped on versions outside this inclusive range" if => cf_version_between("3.15", "4"); "This will be skipped if version is within this inclusive range" unless => cf_version_between("3.15", "4"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This will be skipped on versions outside this inclusive range #@ ``` #+end_src cfengine-3.24.2/examples/edit_deletenotmatch.cf0000644000000000000000000000315015010704253021507 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test editfile # ######################################################## # # This assumes a file format like: # # [section 1] # # lines.... # # [section 2] # # lines... etc body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/tmp/passwd_excerpt" create => "true", edit_line => MarkNRoot; } ######################################################## bundle edit_line MarkNRoot { delete_lines: "mark.*|root.*" not_matching => "true"; } cfengine-3.24.2/examples/rxdirs.cf0000644000000000000000000000565315010704253017027 0ustar00rootroot00000000000000############################################################################### #+begin_src cfengine3 bundle agent __main__ # @brief Illustrating the behavior of rxdirs in perms bodies. { vars: "example_dirs" slist => { "/tmp/rxdirs_example/rxdirs=default(false)-r", "/tmp/rxdirs_example/rxdirs=default(false)-rx", "/tmp/rxdirs_example/rxdirs=true-r", "/tmp/rxdirs_example/rxdirs=true-rx", }; files: "$(example_dirs)/." create => "true"; "/tmp/rxdirs_example/rxdirs=default(false)-r" perms => example:m( 600 ); "/tmp/rxdirs_example/rxdirs=default(false)-rx" perms => example:m( 700 ); "/tmp/rxdirs_example/rxdirs=true-r" perms => example:m_rxdirs_on( 600 ); "/tmp/rxdirs_example/rxdirs=true-rx" perms => example:m_rxdirs_on( 700 ); reports: "$(example_dirs) modeoct='$(with)'" with => filestat( $(example_dirs), modeoct ); } body file control{ namespace => "example"; } body perms m(mode) # @brief Set the file mode # @param mode The new mode { mode => "$(mode)"; } body perms m_rxdirs_on(mode) # @brief Set the file mode and set +x on directory when +r is desired # @param mode The new mode { inherit_from => m( $(mode) ); rxdirs => "true"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitly #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitly #@ R: /tmp/rxdirs_example/rxdirs=default(false)-r modeoct='40600' #@ R: /tmp/rxdirs_example/rxdirs=default(false)-rx modeoct='40600' #@ R: /tmp/rxdirs_example/rxdirs=true-r modeoct='40700' #@ R: /tmp/rxdirs_example/rxdirs=true-rx modeoct='40700' #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitly #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly #@ warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitly #@ ``` #+end_example cfengine-3.24.2/examples/complicated_cpu_bound_benchmark.cf0000644000000000000000000007523615010704253024054 0ustar00rootroot00000000000000body common control { bundlesequence => { "benchmark" }; } bundle agent benchmark { vars: # Determines how many times each example is run "n" int => "10"; # Range: 1, 2, 3, ..., n "i" slist => { expandrange("[1-$(n)]", "1") }; methods: "accumulated" usebundle => accumulated_bench("$(i)"); "ago" usebundle => ago_bench("$(i)"); "and" usebundle => and_bench("$(i)"); "basename" usebundle => basename_bench("$(i)"); "bundlesmatching" usebundle => bundlesmatching_bench("$(i)"); "bundlestate" usebundle => bundlestate_bench("$(i)"); "callstack_callers" usebundle => callstack_callers_bench("$(i)"); "callstack_promisers" usebundle => callstack_promisers_bench("$(i)"); "canonify" usebundle => canonify_bench("$(i)"); "canonifyuniquely" usebundle => canonifyuniquely_bench("$(i)"); "cf_version_after" usebundle => cf_version_after_bench("$(i)"); "cf_version_at" usebundle => cf_version_at_bench("$(i)"); "cf_version_before" usebundle => cf_version_before_bench("$(i)"); "cf_version_between" usebundle => cf_version_between_bench("$(i)"); "cf_version_maximum" usebundle => cf_version_maximum_bench("$(i)"); "cf_version_minimum" usebundle => cf_version_minimum_bench("$(i)"); "classesmatching" usebundle => classesmatching_bench("$(i)"); "classify" usebundle => classify_bench("$(i)"); "classmatch" usebundle => classmatch_bench("$(i)"); "concat" usebundle => concat_bench("$(i)"); "countclassesmatching" usebundle => countclassesmatching_bench("$(i)"); "data_expand" usebundle => data_expand_bench("$(i)"); "data_regextract" usebundle => data_regextract_bench("$(i)"); "difference" usebundle => difference_bench("$(i)"); "dirname" usebundle => dirname_bench("$(i)"); "escape" usebundle => escape_bench("$(i)"); "eval" usebundle => eval_bench("$(i)"); "every" usebundle => every_bench("$(i)"); "expandrange" usebundle => expandrange_bench("$(i)"); "filter" usebundle => filter_bench("$(i)"); "format" usebundle => format_bench("$(i)"); "getclassmetatags" usebundle => getclassmetatags_bench("$(i)"); "getindices" usebundle => getindices_bench("$(i)"); "getvalues" usebundle => getvalues_bench("$(i)"); "getvariablemetatags" usebundle => getvariablemetatags_bench("$(i)"); "grep" usebundle => grep_bench("$(i)"); "hash" usebundle => hash_bench("$(i)"); "hash_to_int" usebundle => hash_to_int_bench("$(i)"); "ifelse" usebundle => ifelse_bench("$(i)"); "intersection" usebundle => intersection_bench("$(i)"); "isgreaterthan" usebundle => isgreaterthan_bench("$(i)"); "islessthan" usebundle => islessthan_bench("$(i)"); "isvariable" usebundle => isvariable_bench("$(i)"); "join" usebundle => join_bench("$(i)"); "laterthan" usebundle => laterthan_bench("$(i)"); "length" usebundle => length_bench("$(i)"); "maparray" usebundle => maparray_bench("$(i)"); "mapdata" usebundle => mapdata_bench("$(i)"); "maplist" usebundle => maplist_bench("$(i)"); "max" usebundle => max_bench("$(i)"); "mean" usebundle => mean_bench("$(i)"); "mergedata" usebundle => mergedata_bench("$(i)"); "min" usebundle => min_bench("$(i)"); "none" usebundle => none_bench("$(i)"); "not" usebundle => not_bench("$(i)"); "now" usebundle => now_bench("$(i)"); "nth" usebundle => nth_bench("$(i)"); "on" usebundle => on_bench("$(i)"); "or" usebundle => or_bench("$(i)"); "parseintarray" usebundle => parseintarray_bench("$(i)"); "parsejson" usebundle => parsejson_bench("$(i)"); "parserealarray" usebundle => parserealarray_bench("$(i)"); "parsestringarray" usebundle => parsestringarray_bench("$(i)"); "parsestringarrayidx" usebundle => parsestringarrayidx_bench("$(i)"); "product" usebundle => product_bench("$(i)"); "random" usebundle => randomint_bench("$(i)"); "regarray" usebundle => regarray_bench("$(i)"); "regcmp" usebundle => regcmp_bench("$(i)"); "regex_replace" usebundle => regex_replace_bench("$(i)"); "regextract" usebundle => regextract_bench("$(i)"); "reglist" usebundle => reglist_bench("$(i)"); "reverse" usebundle => reverse_bench("$(i)"); "shuffle" usebundle => shuffle_bench("$(i)"); "some" usebundle => some_bench("$(i)"); "sort" usebundle => sort_bench("$(i)"); "splitstring" usebundle => splitstring_bench("$(i)"); "storejson" usebundle => storejson_bench("$(i)"); "strcmp" usebundle => strcmp_bench("$(i)"); "strftime" usebundle => strftime_bench("$(i)"); "string_downcase" usebundle => string_downcase_bench("$(i)"); "string_head" usebundle => string_head_bench("$(i)"); "string_length" usebundle => string_length_bench("$(i)"); "string_mustache" usebundle => string_mustache_bench("$(i)"); "string_replace" usebundle => string_replace_bench("$(i)"); "string_reverse" usebundle => string_reverse_bench("$(i)"); "string_split" usebundle => string_split_bench("$(i)"); "string_tail" usebundle => string_tail_bench("$(i)"); "string_upcase" usebundle => string_upcase_bench("$(i)"); "sublist" usebundle => sublist_bench("$(i)"); "sum" usebundle => sum_bench("$(i)"); "translatepath" usebundle => translatepath_bench("$(i)"); "unique" usebundle => unique_bench("$(i)"); "validdata" usebundle => validdata_bench("$(i)"); "validjson" usebundle => validjson_bench("$(i)"); "variablesmatching" usebundle => variablesmatching_bench("$(i)"); "variablesmatching_as_data" usebundle => variablesmatching_as_data_bench("$(i)"); "variance" usebundle => variance_bench("$(i)"); "done" usebundle => print_benchmark_done_msg(); } bundle agent accumulated_bench(i) { vars: "test" int => accumulated("$(i)", "$(i)", "$(i)", "$(i)", "$(i)", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent ago_bench(i) { vars: "test" int => ago("$(i)", "$(i)", "$(i)", "$(i)", "$(i)", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent and_bench(i) { classes: "test_1" expression => and("any_$(i)", "any_$(i)"); "test_2" expression => and("any_$(i)", "!any_$(i)"); "test_3" expression => and("!any_$(i)", "any_$(i)"); "test_4" expression => and("!any_$(i)", "!any_$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent basename_bench(i) { vars: "test_1" string => basename("/tmp/test_$(i).txt"); "test_2" string => basename("/tmp/test_$(i).txt", ".txt"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent bundlesmatching_bench(i) { vars: "test" slist => bundlesmatching(".*"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent bundlestate_bench(i) { vars: "test" data => bundlestate("benchmark"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent callstack_callers_bench(i) { vars: "test" data => callstack_callers(); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent callstack_promisers_bench(i) { vars: "test" slist => callstack_promisers(); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent canonify_bench(i) { vars: "test" string => canonify("/home/root/test-$(i).txt"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent canonifyuniquely_bench(i) { vars: "test" string => canonifyuniquely("/home/root/test-$(i).txt"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent cf_version_after_bench(i) { classes: "test" expression => cf_version_after("3.$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent cf_version_at_bench(i) { classes: "test" expression => cf_version_at("3.$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent cf_version_before_bench(i) { classes: "test" expression => cf_version_before("3.$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent cf_version_between_bench(i) { classes: "test" expression => cf_version_between("3.$(i)", "4"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent cf_version_maximum_bench(i) { classes: "test" expression => cf_version_maximum("3.$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent cf_version_minimum_bench(i) { classes: "test" expression => cf_version_minimum("3.$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent classesmatching_bench(i) { vars: "test" slist => classesmatching(".*$(i).*"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent classify_bench(i) { classes: "test" expression => classify("/home/root/test-$(i).txt"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent classmatch_bench(i) { classes: "test" expression => classmatch(".*$(i).*", "hardclass"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent concat_bench(i) { vars: "test" string => concat("file", "_$(i)", ".txt"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent countclassesmatching_bench(i) { vars: "test" int => countclassesmatching(".*$(i).*"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent data_expand_bench(i) { vars: "json" data => '{ "i": $(i) }'; "expanded" data => data_expand("json"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent data_regextract_bench(i) { vars: "parsed" data => data_regextract("^(?...)(...)(..)-(?...)-(..).*", "abcdef12-345-$(i)andsoon"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent difference_bench(i) { vars: "a" slist => { "a", "b", "c", "d", "e", "f", "$(i)" }; "b" slist => { "a", "c", "e", "g", "i", "k" }; "diff" slist => difference(a, b); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent dirname_bench(i) { vars: "dir" string => dirname("/dir/dir_$(i)/file"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent escape_bench(i) { vars: "node" string => format("%d", eval("($(i) - 1) % 256")); "ip" string => "192.168.1.$(node)"; "escaped" string => escape("$(ip)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent eval_bench(i) { vars: "hyp" string => eval("sqrt( ( ($(i) * $(i)) + ($(i) * $(i)) ) )", "math", "infix"); "same" string => eval("$(i) == sqrt($(i) * $(i))", "class", "infix"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent every_bench(i) { vars: "test" slist => { "/var/cfengine/bin/cf-agent", "/var/cfengine/bin/cf-execd", "/var/cfengine/bin/rpmvercmp", "/var/cfengine/bin/cf-$(i)" }; classes: "yes" expression => every("/var/cfengine/bin/.*", test); "no" expression => every("/var/cfengine/bin/cf-.*", test); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent expandrange_bench(i) { vars: "range" slist=> { expandrange("[0-$(i)]", "1") }; reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent filter_bench(i) { vars: "natural" slist => { expandrange("[0-$(i)]", "1") }; "odd" slist => filter("[0-9]*[02468]", natural, "true", "false", "inf"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent format_bench(i) { vars: "formatted" string => format("num: %s", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent getclassmetatags_bench(i) { classes: "myclass" expression => "any", meta => { "tag_$(i)" }; vars: "metatags" slist => getclassmetatags("myclass"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent getindices_bench(i) { vars: "test[i$(i)]" string => "v$(i)"; "indices" slist => getindices(test); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent getvalues_bench(i) { vars: "test[i$(i)]" string => "v$(i)"; "values" slist => getvalues(test); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent getvariablemetatags_bench(i) { vars: "myvar" string => "hello", meta => { "tag_$(i)" }; "metatags" slist => getvariablemetatags(myvar); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent grep_bench(i) { vars: "mylist" slist => { "One", "Two", "Three", "Four", "Five", "T$(i)" }; "tlist" slist => grep("T.*", mylist); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent hash_bench(i) { vars: "md5" string => hash("Cfengine $(i) is not cryptic","md5"); "sha256" string => hash("Cfengine $(i) is not cryptic","sha256"); "sha384" string => hash("Cfengine $(i) is not cryptic","sha384"); "sha512" string => hash("Cfengine $(i) is not cryptic","sha512"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent hash_to_int_bench(i) { vars: "a" int => hash_to_int(0, "$(i)", "hello"); "b" int => hash_to_int(0, "$(i)", "world"); "c" int => hash_to_int(0, "$(i)", "$(sys.key_digest)"); "d" int => hash_to_int(0, "$(i)", "$(sys.policy_hub)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent ifelse_bench(i) { vars: "outcome" string => ifelse(regcmp("[0-9]*[02468]", "$(i)"), "is odd", regcmp("[0-9]", "$(i)"), "is less than 10", "is even"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent intersection_bench(i) { vars: "a" slist => { "a", "b", "c", "d", "e", "f", "$(i)" }; "b" slist => { "a", "c", "e", "g", "i", "k", "$(i)" }; "inter" slist => intersection(a, b); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent isgreaterthan_bench(i) { classes: "indeed" expression => isgreaterthan("5", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent islessthan_bench(i) { classes: "indeed" expression => islessthan("5", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent isvariable_bench(i) { vars: "defined_$(i)" string => "this var is defined"; classes: "test_1" expression => isvariable("defined_$(i)"); "test_2" expression => isvariable("undefined_$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent join_bench(i) { vars: "list" slist => { "a", "b", "c", "d", "e", "$(i)" }; "joined_list" string => join(", ", list); "dat" data => '[ "a", "b", "c", "d", "e", "$(i)" ]'; "joined_data" string => join("->", dat); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent laterthan_bench(i) { classes: "test" expression => laterthan("$(i)", "$(i)", "$(i)", "$(i)", "$(i)", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent length_bench(i) { vars: "list" slist => { expandrange("[0-$(i)]", "1") }; "len" int => length(list); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent maparray_bench(i) { vars: "arr[0]" string => "a"; "arr[1]" string => "b"; "arr[2]" string => "c"; "arr[3]" string => "d"; "arr[4]" string => "e"; "arr[5]" string => "$(i)"; "mapped" slist => maparray("key=$(this.k), val=$(this.v)", arr); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent mapdata_bench(i) { vars: "dat" data => '{ "name": "alice", "age": $(i) }'; "map_json" data => mapdata("json", '{ "key": "$(this.k)", "value": "$(this.v)" }', dat); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent maplist_bench(i) { vars: "list" slist => { "a", "b", "c", "d", "e", "$(i)" }; "mapped" slist => maplist("Element: $(this)", list); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent max_bench(i) { vars: "alpha" slist => { "a", "c", "b", "d", "f", "$(i)" }; "numer" ilist => { 1, 3, 2, 4, 6, "$(i)" }; "alpha_max" string => max(alpha, "lex"); "numer_max" string => max(numer, "int"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent mean_bench(i) { vars: "list" slist => { "a", "1", "b", "2", "f", "$(i)" }; "mean" real => mean(list); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent mergedata_bench(i) { vars: "d1" data => '{ "name": "alice" }'; "d2" data => '{ "age": $(i) }'; "data" data => mergedata(d1, d2); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent min_bench(i) { vars: "alpha" slist => { "a", "c", "b", "d", "f", "$(i)" }; "numer" ilist => { 1, 3, 2, 4, 6, "$(i)" }; "alpha_min" string => min(alpha, "lex"); "numer_min" string => min(numer, "int"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent none_bench(i) { vars: "list" slist => { "a", "b", "c", "$(i)" }; classes: "test_2" expression => none("[0-9]", list); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent not_bench(i) { classes: "myclass_$(i)" expression => "any"; "yes" expression => not("!myclass_$(i)"); "no" expression => not("myclass_$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent now_bench(i) { vars: "epoch" int => now(); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent nth_bench(i) { vars: "list" slist => { "a", "b", "c", "d", "e", "$(i)" }; "first" string => nth(list, "0"); "second" string => nth(list, "1"); "third" string => nth(list, "2"); "forth" string => nth(list, "3"); "fifth" string => nth(list, "4"); "sixth" string => nth(list, "5"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent on_bench(i) { vars: "epoch" int => on("$(i)", "$(i)", "$(i)", "$(i)", "$(i)", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent or_bench(i) { classes: "myclass_$(i)" expression => "any"; "test_1" expression => or("myclass_$(i)", "myclass_$(i)"); "test_2" expression => or("myclass_$(i)", "!myclass_$(i)"); "test_3" expression => or("!myclass_$(i)", "myclass_$(i)"); "test_3" expression => or("!myclass_$(i)", "!myclass_$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent parseintarray_bench(i) { vars: # Define data inline for convenience "table" string => "1:2 3:4 $(i):6"; "dim" int => parseintarray("items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent parsejson_bench(i) { vars: "json" string => '{ "name": "alice", "age": $(i) }'; "data" data => parsejson("$(json)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent parserealarray_bench(i) { vars: "table" string => "1.1:2.2 3.3:4.4 $(i).5:6.6"; "dim" int => parserealarray("items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent parsestringarray_bench(i) { vars: "table" string => "a:b c:d $(i):f"; "dim" int => parsestringarray("items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent parsestringarrayidx_bench(i) { vars: "table" string => "one: a two: b $(i): c"; "dim" int => parsestringarrayidx("items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent product_bench(i) { vars: "series" rlist => { "1.1", "1.2", "2.3", "3.$(i)" }; "prod" real => product(series); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent randomint_bench(i) { vars: "rand" int => randomint("0", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent regarray_bench(i) { vars: "array[0]" string => "a1"; "array[1]" string => "a2"; "array[2]" string => "b$(i)"; classes: "yes" expression => regarray(array, "[ab][123]"); "no" expression => regarray(array, "[cd][456]"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent regcmp_bench(i) { classes: "odd" expression => regcmp("[0-9]*[02468]", "$(i)"); "par" expression => regcmp("[0-9]*[13579]", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent regex_replace_bench(i) { vars: "str" string => regex_replace("$(i)", "[0-9]*[02468]", "odd", "i"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent regextract_bench(i) { classes: "ok" expression => regextract("abc([0-9]+)def", "abc$(i)def", "arr"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent reglist_bench(i) { vars: "test" slist => { "a", "$(i)", "c" }; classes: "yes" expression => reglist("@(test)", "[0-9]*[02468]"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent reverse_bench(i) { vars: "test" slist => { "a", "b", "c", "1", "2", "$(i)" }; "reversed" slist => reverse(test); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent shuffle_bench(i) { vars: "test" slist => { "a", "b", "c", "1", "2", "3" }; "shuffled" slist => shuffle(test, "seed_$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent some_bench(i) { vars: "test" slist => { "a", "b", "c", "1", "$(i)", "3" }; classes: "yes" expression => some("[0-9]*[02468]", test); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent sort_bench(i) { vars: "test" slist => { "1", "2", "3", "4", "5", "$(i)" }; "shuffled" slist => shuffle(test, "seed_$(i)"); "lex" slist => sort(shuffled, "lex"); "int" slist => sort(shuffled, "int"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent splitstring_bench(i) { vars: "test" string => "1.5;2.3;$(i).0"; "split" slist => splitstring("$(test)", ";", "inf"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent storejson_bench(i) { vars: "dat" data => '{ "name": "alice", "age": $(i) }'; "json" string => storejson(dat); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent strcmp_bench(i) { classes: "same" expression => strcmp("test$(i)", "test$(i)"); "diff" expression => strcmp("$(i)test", "test$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent strftime_bench(i) { vars: "at_time" string => strftime("localtime", "%Y-%m-%d %T", "$(i)"); "gmt_at_time" string => strftime("gmtime", "%Y-%m-%d %T", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_downcase_bench(i) { vars: "downcase" string => string_downcase("AbC dEf_$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_head_bench(i) { vars: "str" string => "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, 1, 2, 3, 4, 5, 6, 7, 8, 9"; "head" string => string_head("$(str)", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_length_bench(i) { vars: "len" int => string_length("Hello world $(i)!"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_mustache_bench(i) { vars: "deserts" data => parsejson('{"deserts":{"Africa":"Sahara","Asia":"Gobi"}}'); "data" string => string_mustache("from container $(i): deserts = {{%deserts}}from container: {{#deserts}}The desert {{.}} is in {{@}}. {{/deserts}}", deserts); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_replace_bench(i) { vars: "str" string => string_replace("This is a string $(i)", "string", "thing"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_reverse_bench(i) { vars: "str" string => string_reverse("abcdefghijklmnopqrstuvwxyz$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_split_bench(i) { vars: "split" slist => string_split("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z", ",", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_tail_bench(i) { vars: "tail" string => string_tail("a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent string_upcase_bench(i) { vars: "upcase" string => string_upcase("AbC dEf_$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent sublist_bench(i) { vars: "list" slist => { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "x", "y", "z" }; "sub_head" slist => sublist(list, "head", "$(i)"); "sub_tail" slist => sublist(list, "tail", "$(i)"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent sum_bench(i) { vars: "nums" ilist => { "1", "2", "3", "4", "5", "$(i)" }; "num_sum" real => sum(nums); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent translatepath_bench(i) { vars: "path" string => translatepath("/a/b/c/file_$(i).txt"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent unique_bench(i) { vars: "uni" slist => { "one", "two", "three", "1", "2", "3", "one", "$(i)", "two" }; reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent validdata_bench(i) { classes: "is_valid" expression => validdata('{ "name": "alice", "age": $(i) }', "JSON"); "not_valid" expression => validdata('{ "name": "alice", "age": $(i) ]', "JSON"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent validjson_bench(i) { classes: "is_valid" expression => validjson('{ "name": "alice", "age": $(i) }'); "not_valid" expression => validjson('{ "name": "alice", "age": $(i) ]'); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent variablesmatching_bench(i) { vars: "matches" slist => variablesmatching(".*$(i).*", "source=agent"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent variablesmatching_as_data_bench(i) { vars: "matches" data => variablesmatching_as_data(".*$(i).*", "source=agent"); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent variance_bench(i) { vars: "nums" ilist => { "1", "2", "3", "$(i) " }; "vari" real => variance(nums); reports: "Benching '$(this.bundle)' ($(i)/$(benchmark.n)) ..."; } bundle agent print_benchmark_done_msg() { reports: "********** BENCHMARK DONE **********"; } cfengine-3.24.2/examples/env.cf0000644000000000000000000000031015010704253016265 0ustar00rootroot00000000000000 body common control { bundlesequence => { "one" }; } body agent control { environment => { "A=123", "B=456", "PGK_PATH=/tmp"}; } bundle agent one { commands: "/usr/bin/env"; } cfengine-3.24.2/examples/orchestrate_dominoes2.cf0000644000000000000000000000540115010704253022005 0ustar00rootroot00000000000000############################################################ # # Dominoes # # This method works with either Community of Enterprise # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # ############################################################ body common control { bundlesequence => { "dominoes_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################################ bundle agent dominoes_symphony { methods: # We have to seed the beginning by creating the dominoes # /tmp/dominoes_localhost host1:: "dominoes" usebundle => hand_over("localhost","host1","overture"); host2:: "dominoes" usebundle => hand_over("host1","host2","first_movement"); host3:: "dominoes" usebundle => hand_over("host2","host3","second_movement"); host4:: "dominoes" usebundle => hand_over("host3","host4","final_movement"), classes => if_ok("finale"); reports: finale:: "The visitors book of the Dominoes method" printfile => visitors_book("/tmp/dominoes_host4"); } ############################################################ bundle agent hand_over(predecessor,myalias,method) { # This is a wrapper for the orchestration files: "/tmp/tip_the_dominoes" comment => "Wait for our cue or relay/conductor baton", copy_from => secure_cp("/tmp/dominoes_$(predecessor)","$(predecessor)"), classes => if_repaired("cue_action"); methods: cue_action:: "the music happens" comment => "One off activity", usebundle => $(method), classes => if_ok("pass_the_stick"); files: pass_the_stick:: "/tmp/tip_the_dominoes" comment => "Add our signature to the dominoes's tail", edit_line => append_if_no_line("Knocked over $(myalias) and did: $(method)"); "/tmp/dominoes_$(myalias)" comment => "Dominoes in position to be beamed up by next agent", copy_from => local_cp("/tmp/tip_the_dominoes"); } ############################################################ bundle agent overture { reports: "Singing the overture..."; } bundle agent first_movement { reports: "Singing the first adagio..."; } bundle agent second_movement { reports: "Singing second allegro..."; } bundle agent final_movement { reports: "Trumpets for the finale"; } ############################################################ bundle server access_rules() { access: "/tmp" admit => { "127.0.0.1" }; "did.*" resource_type => "context", admit => { "127.0.0.1" }; } body printfile visitors_book(file) { file_to_print => "$(file)"; number_of_lines => "10"; } cfengine-3.24.2/examples/sublist.cf0000644000000000000000000001013515010704253017170 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", }; "test_head9999" slist => sublist("test", "head", 9999); "test_head1" slist => sublist("test", "head", 1); "test_head0" slist => sublist("test", "head", 0); "test_tail9999" slist => sublist("test", "tail", 9999); "test_tail10" slist => sublist("test", "tail", 10); "test_tail2" slist => sublist("test", "tail", 2); "test_tail1" slist => sublist("test", "tail", 1); "test_tail0" slist => sublist("test", "tail", 0); reports: "The test list is $(test)"; "This line should not appear: $(test_head0)"; "The head(1) of the test list is $(test_head1)"; "The head(9999) of the test list is $(test_head9999)"; "This line should not appear: $(test_tail0)"; "The tail(1) of the test list is $(test_tail1)"; "The tail(10) of the test list is $(test_tail10)"; "The tail(2) of the test list is $(test_tail2)"; "The tail(9999) of the test list is $(test_tail9999)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The test list is 1 #@ R: The test list is 2 #@ R: The test list is 3 #@ R: The test list is one #@ R: The test list is two #@ R: The test list is three #@ R: The test list is long string #@ R: The test list is four #@ R: The test list is fix #@ R: The test list is six #@ R: The head(1) of the test list is 1 #@ R: The head(9999) of the test list is 1 #@ R: The head(9999) of the test list is 2 #@ R: The head(9999) of the test list is 3 #@ R: The head(9999) of the test list is one #@ R: The head(9999) of the test list is two #@ R: The head(9999) of the test list is three #@ R: The head(9999) of the test list is long string #@ R: The head(9999) of the test list is four #@ R: The head(9999) of the test list is fix #@ R: The head(9999) of the test list is six #@ R: The tail(1) of the test list is six #@ R: The tail(10) of the test list is 1 #@ R: The tail(10) of the test list is 2 #@ R: The tail(10) of the test list is 3 #@ R: The tail(10) of the test list is one #@ R: The tail(10) of the test list is two #@ R: The tail(10) of the test list is three #@ R: The tail(10) of the test list is long string #@ R: The tail(10) of the test list is four #@ R: The tail(10) of the test list is fix #@ R: The tail(10) of the test list is six #@ R: The tail(2) of the test list is fix #@ R: The tail(2) of the test list is six #@ R: The tail(9999) of the test list is 1 #@ R: The tail(9999) of the test list is 2 #@ R: The tail(9999) of the test list is 3 #@ R: The tail(9999) of the test list is one #@ R: The tail(9999) of the test list is two #@ R: The tail(9999) of the test list is three #@ R: The tail(9999) of the test list is long string #@ R: The tail(9999) of the test list is four #@ R: The tail(9999) of the test list is fix #@ R: The tail(9999) of the test list is six #@ ``` #+end_src cfengine-3.24.2/examples/user_edit_method.cf0000644000000000000000000000366315010704253021036 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # body common control { bundlesequence => { "users" }; } body agent control { abortbundleclasses => { "ldap_fail" }; } #################################################################################### bundle agent users { vars: "users" slist => { "mark", "nakarin", "three" }; methods: "all" usebundle => fix_user("$(users)"); } ################################################################################### bundle agent fix_user(x) { classes: "ldap_fail" not => ldaparray("dat","ldap://eternity.iu.hio.no","dc=cfengine,dc=com","(uid=$(x))","subtree","none"); files: "/tmp/passwd" create => "true", edit_line => fix_passwd("$(x)"); reports: !ldap_fail:: "Editing user $(x)"; } #################################################################################### bundle edit_line fix_passwd(x) { insert_lines: "Hello $(x),$(fix_user.dat[uid]),$(fix_user.dat[gecos])"; } cfengine-3.24.2/examples/main_library.cf0000644000000000000000000000140515010704253020153 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -KIf- # Example showing how bundle __main__ works # This file can be used as the main entry (`cf-agent -KIf ./main_library.cf`) # This file can also be included from another policy file containing __main__ bundle agent libprint(message) # @brief report `message` { reports: "Library: $(message)."; } bundle agent __main__ # @brief Run this bundle (a testsuite) if this file is the entry # This bundle is special. It is ignored unless it is the policy entry file { methods: "test" usebundle => libprint( "ok 1 - libprint works" ); } #@ The policy promises to call libprint to report that it works when the policy file is the main entry. #+begin_src example_output #@ ``` #@ R: Library: ok 1 - libprint works #@ ``` #+end_src cfengine-3.24.2/examples/copy_edit.cf0000644000000000000000000000526615010704253017473 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Copy and edit convergently # ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { vars: "source" string => "/tmp"; "dest" string => "/tmp"; files: "/$(dest)/staging-file" comment => "Copy from source to buffer", copy_from => cp("$(source)/source-template"), classes => satisfied("copy_ok"); copy_ok:: "/$(dest)/final-file" comment => "Build a file template and expand keys", edit_line => myedits("/$(dest)/staging-file"), edit_defaults => empty; } ######################################################### body copy_from cp(from) { source => "$(from)"; compare => "mtime"; type_check => "true"; } ######################################################## bundle edit_line myedits(f) { insert_lines: "$(f)" comment => "Populate empty file", insert_type => "file"; replace_patterns: "TEMPLATE_HOST_KEY" comment => "Replace a place-marker with the name of this host", replace_with => rp("$(sys.host)"); } ######################################################## body replace_with rp(x) { replace_value => "$(x)"; occurrences => "all"; } ######################################################### body classes satisfied(x) { promise_repaired => { "$(x)" }; persist_time => "0"; } ####################################################### body edit_defaults empty { empty_file_before_editing => "true"; } cfengine-3.24.2/examples/compare.cf0000644000000000000000000000271415010704253017135 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Testing some variable/class definitions - note scope # # Use browser -f promise_output_agent.html to view # body common control { bundlesequence => { "test" }; } ########################################################### bundle agent test { classes: "ok" expression => isgreaterthan("1","0"); reports: ok:: "Assertion is true"; !ok:: "Assertion is false"; } #+begin_src example_output #@ ``` #@ R: Assertion is true #@ ``` #+end_src cfengine-3.24.2/examples/classesmatching.cf0000644000000000000000000000410015010704253020646 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent main { classes: "example_one"; "example_two" meta => { "plus", "defined_from=$(this.bundle)" }; "example_three" meta => { "plus", "defined_from=$(this.bundle)" }; vars: "cfengine_classes" slist => sort( classesmatching("cfengine"), lex); "example_with_plus" slist => sort( classesmatching("example.*", "plus"), lex); reports: # you may find this list of all classes interesting but it # produces different output every time, so it's commented out here # "All classes = '$(all)'"; "Classes matching 'cfengine' = '$(cfengine_classes)'"; # this should produce no output "Classes matching 'example.*' with the 'plus' tag = $(example_with_plus)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Classes matching 'cfengine' = 'cfengine' #@ R: Classes matching 'example.*' with the 'plus' tag = example_three #@ R: Classes matching 'example.*' with the 'plus' tag = example_two #@ ``` #+end_src cfengine-3.24.2/examples/warnifline.cf0000644000000000000000000000322715010704253017645 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Warn if line matched # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/var/cfengine/inputs/.*" edit_line => DeleteLinesMatching(".*cfenvd.*"), action => WarnOnly; } ######################################################## bundle edit_line DeleteLinesMatching(regex) { delete_lines: "$(regex)" action => WarnOnly; } ######################################################## body action WarnOnly { action_policy => "warn"; } cfengine-3.24.2/examples/chdir.cf0000644000000000000000000000241415010704253016575 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### body contain cd(dir) { chdir => "${dir}"; useshell => "useshell"; } bundle agent example { commands: "/bin/pwd" contain => cd("/tmp"); } cfengine-3.24.2/examples/module_exec.cf0000644000000000000000000000247515010704253020004 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Test module execution as class function # body common control { bundlesequence => { "example" }; } ################################################################### bundle agent example { classes: "done" or => { usemodule("module:getusers","") }; commands: "/bin/echo promiser text" args => "test $(user)"; } cfengine-3.24.2/examples/pattern_and_edit.cf0000644000000000000000000000277315010704253021020 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => {"test"}; } ######################################################## bundle agent example { files: "/home/(.*)/testfile" create => "true", edit_line => AppendIfNoLine("key_$(match.1)"); } ######################################################## bundle edit_line AppendIfNoLine(x) { insert_lines: "Line $(x)" location => append; } ######################################################## body location append { before_after => "before"; } cfengine-3.24.2/examples/hashuncomment.cf0000644000000000000000000000354015010704253020356 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # Uncomment lines # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "example" }; } # try this on some test data like # one # two # mark one #mark two ######################################################## bundle agent example { files: "/home/mark/tmp/comment_test" create => "true", edit_line => uncomment_lines_matching("\s*mark.*","#"); } ######################################################## bundle edit_line uncomment_lines_matching(regex,comment) { replace_patterns: "#($(regex))$" replace_with => uncomment; } ######################################################## body replace_with uncomment { replace_value => "$(match.1)"; occurrences => "all"; } cfengine-3.24.2/examples/services_concept.cf0000644000000000000000000000620715010704253021046 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ##################################################################### # # Concept of standard services promises # ##################################################################### body common control { bundlesequence => { "example" }; } # bundle agent example { vars: "mail" slist => { "milter", "spamassassin", "postfix" }; services: "www" service_policy => "start", service_method => service_test; "$(mail)" service_policy => "stop", service_method => service_test; } #################################################################### body service_method service_test { service_bundle => non_standard_services("$(this.promiser)","$(this.service_policy)"); } #################################################################### bundle agent standard_services(service,state) { # DATA, vars: suse|redhat:: "startcommand[www]" string => "/etc/init.d/apache2 start"; "stopcommand[www]" string => "/etc/init.d/apache2 stop"; debian|ubuntu:: "startcommand[www]" string => "/etc/init.d/httpd start"; "stopcommand[www]" string => "/etc/init.d/httpd stop"; linux:: "startcommand[postfix]" string => "/etc/init.d/postfix start"; "stopcommand[postfix]" string => "/etc/init.d/postfix stop"; # METHODS classes: "start" expression => strcmp("start","$(state)"); "stop" expression => strcmp("stop","$(state)"); processes: start:: ".*$(service).*" comment => "Verify that the service appears in the process table", restart_class => "restart_$(service)"; stop:: ".*$(service).*" comment => "Verify that the service does not appear in the process", process_stop => "$(stopcommand[$(service)])", signals => { "term", "kill"}; commands: "$(startcommand[$(service)])" comment => "Execute command to restart the $(service) service", if => "restart_$(service)"; } ###################################################################### bundle agent non_standard_services(service,state) { reports: !done:: "Test service promise for \"$(service)\" -> $(state)"; } cfengine-3.24.2/examples/changedbefore.cf0000644000000000000000000000241515010704253020261 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { classes: "do_it" and => { changedbefore("/tmp/earlier","/tmp/later") }; reports: do_it:: "Earlier than later!"; } cfengine-3.24.2/examples/inform.cf0000644000000000000000000000120415010704253016772 0ustar00rootroot00000000000000# The inform constraint can be used to select which commands promises # generate output in INFO log level. INFO log level, is intendeted for # events which alter the state of the system, such as editing files, users, # etc. Since commands promises CAN modify the system, they create INFO # messages by default. However, not all commands promises do change the # system, so we let the policy writer customize this. bundle agent main { commands: "/bin/touch /tmp/module_cache" inform => "true"; # Default "/bin/cat /tmp/module_cache" inform => "false", # Read-only promise, no INFO logging wanted module => "true"; } cfengine-3.24.2/examples/style_snake_case.cf0000644000000000000000000000157515010704253021027 0ustar00rootroot00000000000000bundle agent __main__ { methods: "ssh"; } bundle agent ssh { vars: "service_name" string => "ssh"; "config_file" string => "/etc/ssh/sshd_config"; "conf[Port]" string => "22"; files: "$(config_file)" edit_line => default:set_line_based("$(this.bundle).conf", " ", "\s+", ".*", "\s*#\s*"), classes => default:results( "bundle", "$(config_file)"); services: _etc_ssh_sshd_config_repaired:: "$(service_name)" service_policy => "restart", classes => default:results( "bundle", "$(service_name)_restart"); reports: ssh_restart_repaired._etc_ssh_sshd_config_repaired:: "We restarted ssh because the config file was repaired"; } cfengine-3.24.2/examples/namespace_bodies.cf0000644000000000000000000000314715010704253020771 0ustar00rootroot00000000000000bundle agent __main__ { methods: "example_space:main"; } body file control { namespace => "example_space"; } bundle agent main { reports: # Use the 'first_line' printfile body from the current namespace "Specifying a body without explict namespace assumes the same namespace.$(const.n)Show me the first 1 line of this file" printfile => first_line( $(this.promise_filename) ); # Use the 'first_two_lines' printfile body from the 'default' namespace "Forgetting to prefix bodies with 'default:' is a common mistake when using the standard library.$(const.n)Show me the first 2 line of this file" printfile => default:first_two_lines( $(this.promise_filename) ); } body printfile first_line(file) # @brief Report the first 1 lines of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "1"; } body file control { namespace => "default"; } body printfile first_two_lines(file) # @brief Report the first 2 lines of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "2"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: Specifying a body without explict namespace assumes the same namespace. #@ Show me the first 1 line of this file #@ R: bundle agent __main__ #@ R: Forgetting to prefix bodies with 'default:' is a common mistake when using the standard library. #@ Show me the first 2 line of this file #@ R: bundle agent __main__ #@ R: { #@ ``` #+end_src cfengine-3.24.2/examples/bundlestate.cf0000644000000000000000000000343715010704253020024 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { holder, test }; } bundle common holder { classes: "holderclass" expression => "any"; # will be global vars: "s" string => "Hello!"; "d" data => parsejson('[4,5,6]'); "list" slist => { "element1", "element2" }; } bundle agent test { vars: "bundle_state" data => bundlestate("holder"); # all the variables in bundle "holder" defined as of the execution of bundlestate() will be here "holderstate" string => format("%S", "bundle_state"); reports: "holder vars = $(holderstate)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: holder vars = {"d":[4,5,6],"list":["element1","element2"],"s":"Hello!"} #@ ``` #+end_src cfengine-3.24.2/examples/inherit_from_classes.cf0000644000000000000000000000431015010704253021703 0ustar00rootroot00000000000000# This example illustrates the use of inherit_from to inherit body attribute # values from another body. ############################################################################### #+begin_src cfengine3 bundle agent __main__ { commands: "/bin/true" handle => "some meaningful string", classes => my_set_some_extra_fancy_classes( "$(this.promiser)", "$(this.handle)", "some_class_to_handle_dependencies" ); "/bin/false" handle => "some meaningless string", classes => my_set_some_extra_fancy_classes( "$(this.promiser)", "$(this.handle)", "some_class_to_handle_dependencies" ); reports: "Defined classes:$(const.n)$(with)" with => join( "$(const.n)", sort( classesmatching( "some_.*"), "lex" )); } body classes my_set_some_extra_fancy_classes(x, y, z) # @brief In addition to the classes set by `set_some_fancy_classes` define `z` when the promise is repaired { inherit_from => set_some_fancy_classes( $(x), $(y) ); promise_repaired => { "some_fancy_class_${x}_${y}_repaired", $(z) }; } body classes set_some_fancy_classes(x, y) # @brief Define a class prefixed with `some_fancy_class_` followed by expansion # of `x`_`y` and suffixed with the promise outcome for each promise outcome. { promise_kept => { "some_fancy_class_${x}_${y}_kept" }; promise_repaired => { "some_fancy_class_${x}_${y}_repaired" }; repair_failed => { "some_fancy_class_${x}_${y}_notkept" }; repair_denied => { "some_fancy_class_${x}_${y}_notkept" }; repair_timeout => { "some_fancy_class_${x}_${y}_notkept" }; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ error: Finished command related to promiser '/bin/false' -- an error occurred, returned 1 #@ R: Defined classes: #@ some_class_to_handle_dependencies #@ some_fancy_class__bin_false_some_meaningless_string_notkept #@ some_fancy_class__bin_true_some_meaningful_string_repaired #@ ``` #+end_src cfengine-3.24.2/examples/filesexist.cf0000644000000000000000000000274315010704253017670 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "mylist" slist => { "/tmp/a", "/tmp/b", "/tmp/c" }; classes: "exists" expression => filesexist("@(mylist)"); reports: exists:: "All files exist"; !exists:: "Not all files exist"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Not all files exist #@ ``` #+end_src cfengine-3.24.2/examples/escape.cf0000644000000000000000000000263115010704253016745 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "ip" string => "10.123.321.250"; "escaped" string => escape($(ip)); reports: "escaped $(ip) = $(escaped)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: escaped 10.123.321.250 = 10\.123\.321\.250 #@ ``` #+end_src cfengine-3.24.2/examples/Makefile.am0000644000000000000000000000303515010704253017226 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # examplesdir = $(docdir)/examples dist_examples_DATA = $(srcdir)/*.cf dist_examples_SCRIPTS = remake_outputs.pl FAKE_WORKDIR=/tmp/fake-cfengine-workdir MAINTAINERCLEANFILES = Makefile.in mdate-sh # only re-run the outputs for examples that already have an example_output block remake: perl ./remake_outputs.pl $(shell grep -l example_output $(dist_examples_DATA)) recheck: perl ./remake_outputs.pl -c $(shell grep -l example_output $(dist_examples_DATA)) recheck_verbose: perl ./remake_outputs.pl -v -c $(shell grep -l example_output $(dist_examples_DATA)) cfengine-3.24.2/examples/orchestrate_chain1.cf0000644000000000000000000000502715010704253021255 0ustar00rootroot00000000000000############################################################ # # The self-healing tower: Anti-Dominoes # # This method works with Enterprise # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # ############################################################ body common control { bundlesequence => { "weak_dependency_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } body server control { allowconnects => { "127.0.0.1" , "::1", @(def.acl) }; allowallconnects => { "127.0.0.1" , "::1", @(def.acl) }; } ############################################################ bundle agent weak_dependency_symphony { methods: # We have to seed the beginning by creating the tower # /tmp/tower_localhost host1:: "tower" usebundle => tier1, classes => publish_ok("ok_O"); host2:: "tower" usebundle => tier2, classes => publish_ok("ok_1"); host3:: "tower" usebundle => tier3, classes => publish_ok("ok_2"); host4:: "tower" usebundle => tier4, classes => publish_ok("ok_f"); classes: ok_O:: # Wait for the methods, report on host1 only "check1" expression => remoteclassesmatching("ok.*","host2","yes","a"); "check2" expression => remoteclassesmatching("ok.*","host3","yes","a"); "check3" expression => remoteclassesmatching("ok.*","host4","yes","a"); reports: ok_O:: "tier 1 is ok"; a_ok_1:: "tier 2 is ok"; a_ok_2:: "tier 3 is ok"; a_ok_f:: "tier 4 is ok"; ok_O&a_ok_1&a_ok_2&a_ok_f:: "The Tower is standing"; !(ok_O&a_ok_1&a_ok_2&a_ok_f):: "The Tower is down"; } ############################################################ bundle agent tier1 { files: "/tmp/something_to_do_1" create => "true"; } bundle agent tier2 { files: "/tmp/something_to_do_2" create => "true"; } bundle agent tier3 { files: "/tmp/something_to_do_3" create => "true"; } bundle agent tier4 { files: "/tmp/something_to_do_4" create => "true"; } ############################################################ bundle server access_rules() { access: "ok.*" resource_type => "context", admit => { "127.0.0.1" }; } ############################################################ body classes publish_ok(x) { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; cancel_notkept => { "$(x)" }; persist_time => "2"; } cfengine-3.24.2/examples/remake_outputs.pl0000755000000000000000000001341415010704253020603 0ustar00rootroot00000000000000#!/usr/bin/perl use warnings; use strict; use Data::Dumper; use Getopt::Long; use File::Basename; use Sys::Hostname; $|=1; # autoflush my %options = ( check => 0, verbose => 0, veryverbose => 0, help => 0, cfagent => "../cf-agent/cf-agent", workdir => "/tmp", ); die ("Unknown options") unless GetOptions(\%options, "help|h!", "check|c!", "cfagent=s", "workdir=s", "verbose|v!", "veryverbose!", ); if ($options{help}) { print <; close $fh; my $copy = $data; if ($data =~ m/#\+begin_src cfengine3\n(.+?)\n#\+end_src/s) { my $example = $1; my $prep; if ($data =~ m/#\+begin_src prep\n(.+?)\n#\+end_src/s) { $prep = [split "\n", $1]; } $data =~ s/(#\+begin_src example_output( no_check)?\n)(.*?)(#\+end_src)/$1 . rewrite_output($file, $prep, $example, $3) . $4/es; if (!defined($2) && $data ne $copy) { print "$file: output differs from original..."; if ($options{check}) { $rc = 1; print "\n"; next; } open my $fh, '>', $file or warn "Could not open $file: $!"; print $fh $data; close $fh; print "new output written!\n"; } } else { warn "No example to run was found in $file, skipping"; } } exit $rc; sub rewrite_output { my $file = shift @_; my $prep = shift @_; my $example = shift @_; my $old_output = shift @_; my $new_output = run_example($file, $prep, $example); if (equal_outputs($old_output, $new_output, $file)) { return $old_output; } if (defined $new_output && length $new_output > 0) { $new_output =~ s/^/#@ /mg; $new_output = "#@ ```\n$new_output#@ ```\n"; } return $new_output; } sub equal_outputs { # strip out date, e.g. '2013-12-16T20:48:24+0200' my $x = shift @_; my $y = shift @_; my $file = shift @_; my ($tempfile, $base) = get_tempfile($file); $x =~ s/^#@ ```\s+//mg; $y =~ s/^#@ ```\s+//mg; $x =~ s/^(#@ )//mg; $x =~ s/^[-0-9T:+]+\s+//mg; $y =~ s/^(#@ )//mg; $y =~ s/^[-0-9T:+]+\s+//mg; $x =~ s/.*RANDOM.*//mg; $y =~ s/.*RANDOM.*//mg; # strip leading blanks, for example from " error:" $x =~ s/^ *//mg; $y =~ s/^ *//mg; if ($x ne $y) { open my $fha, '>', "$tempfile.a" or die "Could not write to diff output $tempfile.a: $!"; print $fha $x; close $fha; open my $fhb, '>', "$tempfile.b" or die "Could not write to diff output $tempfile.b: $!"; print $fhb $y; close $fhb; system("diff -u $tempfile.a $tempfile.b") if $options{verbose}; return 0; } return 1; } sub get_tempfile { my $file = shift @_; my $base = basename($file); my $tempfile = "$options{workdir}/$base"; mkdir $options{workdir} unless -e $options{workdir}; return ($tempfile, $base); } sub run_example { my $file = shift @_; my $prep = shift @_ || []; my $example = shift @_; my ($tempfile, $base) = get_tempfile($file); open my $fh, '>', $tempfile or die "Could not write to $tempfile: $!"; print $fh $example; close $fh; chmod 0600, $tempfile; foreach (@$prep) { s/^#@ //; # skip Markdown markup like ``` next unless m/^\w/; s/FILE/$tempfile/g; s/\$HOSTNAME/hostname()/ge; print "processing $file: Running prep '$_'" if $options{verbose}; system($_); } $ENV{EXAMPLE} = $base; $ENV{CFENGINE_COLOR} = 0; my $cmd = "$options{cfagent} -D_cfe_output_testing -Kf $tempfile 2>&1"; open my $ofh, '-|', $cmd; my $output = join '', <$ofh>; close $ofh; print "Test file: $file\nCommand: $cmd\n\nNEW OUTPUT: [[[$output]]]\n\n\n" if $options{verbose}; return $output; } cfengine-3.24.2/examples/canonify.cf0000644000000000000000000000270715010704253017317 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "component" string => "/var/cfengine/bin/cf-serverd"; "canon" string => canonify("$(component)"); reports: "canonified component == $(canon)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: canonified component == _var_cfengine_bin_cf_serverd #@ ``` #+end_src cfengine-3.24.2/examples/switchcase.cf0000644000000000000000000000217515010704253017645 0ustar00rootroot00000000000000 body common control { bundlesequence => { "test1", "test2" }; } ################################################## bundle agent test1 { classes: "default" expression => "any"; reports: linux:: "This is a linux box" classes => exclusive; solaris:: "This is a solaris box" classes => exclusive; default:: "This is something not worth mentioning specifically" classes => reset_default; } ################################################## bundle agent test2 { classes: "default" expression => "any"; reports: linux:: "This is another linux box" classes => exclusive; solaris:: "This is another solaris box" classes => exclusive; default:: "This is something else not worth mentioning specifically" classes => reset_default; } ########################################################## body classes exclusive { cancel_kept => { "default" }; cancel_notkept => { "default" }; cancel_repaired => { "default" }; } body classes reset_default { promise_kept => { "default" }; } cfengine-3.24.2/examples/variablesmatching_as_data.cf0000644000000000000000000000312215010704253022640 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { run }; } bundle agent run { vars: "all" data => variablesmatching_as_data(".*"); # this is huge "v" data => variablesmatching_as_data("default:sys.cf_version_major.*"); "v_dump" string => format("%S", v); reports: "Variables matching 'default:sys.cf_version.*' = $(v_dump)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Variables matching 'default:sys.cf_version.*' = {"default:sys.cf_version_major":"3"} #@ ``` #+end_src cfengine-3.24.2/examples/files-content.cf0000644000000000000000000000064515010704253020262 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ test -e /tmp/hello && rm -f /tmp/hello #@ ``` #+end_src #+begin_src cfengine3 body agent control { inform => "true"; } bundle agent __main__ { files: "/tmp/hello" content => "Hello, CFEngine"; } #+end_src #+begin_src example_output #@ ``` #@ info: Created file '/tmp/hello', mode 0600 #@ info: Updated file '/tmp/hello' with content 'Hello, CFEngine' #@ ``` #+end_src cfengine-3.24.2/examples/remoteclasses.cf0000644000000000000000000000756715010704253020373 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Remote classes from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-d2] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { job_chain("Hr16|Hr17") }; version => "1.2.3"; } ######################################################## bundle common g { vars: # Signals are in scope of promiser and promisee "signal" string => "pack_a_name"; } ######################################################## bundle agent job_chain(time) { vars: "client" string => "localhost"; "server" string => "localhost"; "margin" string => "5"; # mins deadtime classes: "client_primed" expression => classmatch(canonify("$(client)")), if => "$(time)"; "server_primed" expression => classmatch(canonify("$(server)")), if => "$(time)"; client_primed:: "succeeded" expression => remoteclassesmatching("$(g.signal)","$(server)","yes","myprefix"); # # Now the job itself # methods: client_primed:: "downstream" usebundle => do_job("Starting local follow-up job"), action => if_elapsed("$(margin)"), if => "myprefix_$(g.signal)"; server_primed:: "upstream" usebundle => do_job("Starting remote job"), action => if_elapsed("$(margin)"), classes => signal_repaired("$(g.signal)"); reports: !succeeded:: "Server communication failed" if => "$(time)"; "Job completed on the server..." if => "$(g.signal)"; } ######################################################### bundle agent do_job(job) { commands: # do whatever... "/bin/echo $(job)"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowusers => { "mark" }; } ######################################################### bundle server access_rules() { vars: "localvar" string => "literal string"; access: "$(g.signal)" handle => "test_class_signal", resource_type => "context", admit => { "127.0.0.1" }; } ######################################################### # Standard library ######################################################### body action if_elapsed(x) { ifelapsed => "$(x)"; } ######################################################### body classes signal_repaired(x) { promise_repaired => { "$(x)" }; persist_time => "10"; } cfengine-3.24.2/examples/orchestrate_dragon_load_balancer.cf0000644000000000000000000001575015010704253024216 0ustar00rootroot00000000000000############################################################ # # Chinese Dragon Dancing on a Star # # This method works with either Community or Enterprise. # and uses named signals # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # # Start a switch file /tmp/switch_file with # host1 ON # host2 ON # host3 ON etc ############################################################ body common control { bundlesequence => { "dragon_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################################ bundle agent dragon_symphony { methods: # We have to seed the beginning by creating the dragon # /tmp/dragon_localhost "dragon" usebundle => upgrade_host("localhost","host1","chapter1"); "dragon" usebundle => upgrade_host("host1","host2","chapter2"); "dragon" usebundle => upgrade_host("host2","host3","chapter3"); "dragon" usebundle => upgrade_host("host3","host4","chapter4"), classes => if_ok("finale"); finale:: "dragon" usebundle => restore_final("host4"), comment => "Restore all the deactivated satellites"; reports: finale:: "The dragon is slain!!!" printfile => visitors_book("/tmp/shoo_dragon_host4"); "And the switch state is..." printfile => visitors_book("/tmp/switch_file"); } ############################################################ # Define the ############################################################ bundle agent chapter1(x) { # Do something significant here reports: host1:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter2(x) { # Do something significant here reports: host2:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter3(x) { # Do something significant here reports: host3:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter4(x) { # Do something significant here reports: host4:: " ----> Breathing fire on $(x)"; } ############################################################ # Orchestration wrappers ############################################################ bundle agent upgrade_host(predecessor,satellite,method) { # This is a wrapper for the orchestration will be acted on # first by the dragon's lair and then by the satellite vars: "dragons_lair" string => "host0"; files: # We start in the dragon's lair .. "/tmp/unleash_dragon" comment => "Unleash the dragon", rename => to("/tmp/enter_the_dragon"), classes => if_repaired("dispatch_dragon_$(satellite)"), if => "$(dragons_lair)"; # if we are the dragon's lair, welcome the dragon back, shooed from the satellite "/tmp/enter_the_dragon" comment => "Returning from a visit to a satellite", copy_from => secure_cp("/tmp/shoo_dragon_$(predecessor)","$(predecessor)"), classes => if_repaired("dispatch_dragon_$(satellite)"), if => "$(dragons_lair)"; # If we are a satellite, receive the dragon from its lair "/tmp/enter_the_dragon" comment => "Wait for our cue or relay/conductor baton", copy_from => secure_cp("/tmp/dragon_$(satellite)","$(dragons_lair)"), classes => if_repaired("cue_action_on_$(satellite)"), if => "$(satellite)"; methods: "check in at home" comment => "Edit the load balancer?", usebundle => next_host("$(satellite)","$(predecessor)"), classes => if_repaired("send_the_dragon_to_$(satellite)"), if => "dispatch_dragon_$(satellite)"; "dragon visits" comment => "One off activity that the nodes carry out while the dragon visits", usebundle => $(method)("$(satellite)"), classes => if_repaired("send_the_dragon_back_from_$(satellite)"), if => "cue_action_on_$(satellite)"; files: # hub/lair hub signs the book too and schedules the dragon for next satellite "/tmp/dragon_$(satellite)" create => "true", comment => "Add our signature to the dragon's tail", edit_line => sign_visitor_book("Dragon returned from $(predecessor)"), if => "send_the_dragon_to_$(satellite)"; # Satellite signs the book and shoos dragon for hub to collect "/tmp/shoo_dragon_$(satellite)" create => "true", comment => "Add our signature to the dragon's tail", edit_line => sign_visitor_book("Dragon visited $(satellite) and did: $(method)"), if => "send_the_dragon_back_from_$(satellite)"; reports: "Done $(satellite)" if => "$(satellite)"; } ############################################################ bundle agent next_host(name,pred) { files: "/tmp/enter_the_dragon" comment => "Add our signature to the dragon's tail", edit_line => append_if_no_line("Switch new dragon's target $(name)"); # Edit the switch file "/tmp/switch_file" comment => "Restore whatever is missing and comment out", edit_line => restore_and_comment("$(name)","$(pred)"), classes => if_repaired("reload_switch_$(name)"); reports: !problem:: "Returned from $(pred), heading out to $(name)"; " X Restoring $(pred) and switching new dragon's target $(name)" if => "reload_switch_$(name)"; } ############################################################ bundle agent restore_final(name) { files: host0:: "/tmp/switch_file" comment => "Restore whatever is missing and comment out", edit_line => restore_and_comment("NONE","$(name)"), classes => if_repaired("reload_switch"); reports: reload_switch:: " X Restoring $(name) to tidy up loose ends"; } ############################################################ bundle edit_line sign_visitor_book(s) { insert_lines: "/tmp/enter_the_dragon" comment => "Import the current visitor's book", insert_type => "file"; "$(s)" comment => "Append this string to the visitor's book"; } # bundle edit_line restore_and_comment(name,pred) { replace_patterns: "$(name) ON" replace_with => value("$(name) OFF"), comment => "Uncomment the predecessor to reactivate"; "$(pred) OFF" replace_with => value("$(pred) ON"), comment => "Comment out the new host", classes => if_repaired("show_switch_$(name)"); reports: !problem:: "The state of the switch was:" printfile => visitors_book("/tmp/switch_file"), if => "show_switch_$(name)"; } ############################################################ bundle server access_rules() { access: "/tmp" admit => { "127.0.0.1" }; "did.*" resource_type => "context", admit => { "127.0.0.1" }; } ############################################################ body printfile visitors_book(file) { file_to_print => "$(file)"; number_of_lines => "100"; } cfengine-3.24.2/examples/mustache_sections_non_false_value.cf0000644000000000000000000000066015010704253024445 0ustar00rootroot00000000000000# Example showing how sections are rendered for non-false #+begin_src cfengine3 bundle agent main { vars: "data" data => parsejson('{ "classes": { "example": true } }'); reports: "$(with)" with => string_mustache("{{#classes.example}}This is an example.{{/classes.example}}", data); } #+end_src #+begin_src example_output #@ ``` #@ R: This is an example. #@ ``` #+end_src cfengine-3.24.2/examples/mustache_sections_empty_list.cf0000644000000000000000000000060015010704253023470 0ustar00rootroot00000000000000# Example showing how variables are rendered for empty lists. #+begin_src cfengine3 bundle agent main { vars: "data" data => '{ "list": [ ] }'; reports: "The list contains $(with)." with => string_mustache("{{#list}} {{{.}}}{{/list}}", data); } #+end_src #+begin_src example_output #@ ``` #@ R: The list contains . #@ ``` #+end_src cfengine-3.24.2/examples/insert_users.cf0000644000000000000000000000603415010704253020233 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Insert users into the passwd file of a system by # extracting named users from a master file - repeat # for /etc/shadow # ######################################################## body common control { bundlesequence => { "updateusers" }; } ######################################################## bundle agent updateusers { vars: # Set $(testing) to "" for production "testing" string => "/home/mark/tmp"; "tmp" string => "$(testing)/etc/passwd_tmp"; "extract_users" slist => { "mark", "root", "at", "www-run" }; files: # # Take the passwed entries from source and add them to real_passwd # "$(tmp)" create => "true", edit_line => SelectUsers("$(testing)/masterfiles/passwd","@(this.extract_users)"); # # Intermediate file - should be secure - not in /tmp # "$(testing)/etc/passwd" edit_line => ReplaceUsers("$(tmp)","@(this.extract_users)"); # "$(testing)/home/$(extract_users)/." create => "true", perms => userdir("$(extract_users)"); } ######################################################## # Library stuff ######################################################## body perms userdir(u) { mode => "755"; owners => { "$(u)" }; groups => { "users" }; } ######################################################## bundle edit_line SelectUsers(f,l) { insert_lines: "$(f)" insert_type => "file", insert_select => keep("@(l)"); } ######################################################## bundle edit_line ReplaceUsers(f,l) { delete_lines: "$(f)" delete_select => discard("@(l)"); insert_lines: "$(f)" insert_type => "file"; } ######################################################## body insert_select keep(s) { insert_if_startwith_from_list => { @(s) }; } ######################################################## body delete_select discard(s) { delete_if_not_startwith_from_list => { @(s) }; } cfengine-3.24.2/examples/meta.cf0000644000000000000000000000315715010704253016437 0ustar00rootroot00000000000000 # Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Default values for variables and parameters, introduced 3.4.0 # body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { meta: "bundle_version" string => "1.2.3"; "works_with_cfengine" string => "3.4.0"; vars: "testvar" string => "x"; reports: "Not a local variable: $(bundle_version)"; "Not a local variable: $(other_bundle.something)"; "Meta data (variable): $(example_meta.bundle_version)"; } bundle agent other_bundle { vars: "something" string => "I am defined in another bundle"; } cfengine-3.24.2/examples/definitions.cf0000644000000000000000000000543115010704253020021 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Testing some variable/class definitions - note scope # # Use browser -f promise_output_agent.html to view # body common control { bundlesequence => { "mycommon", "assign" }; } ########################################################### bundle common mycommon { classes: "global_class" expression => "any"; "another_global" xor => { "any", "linux", "solaris"}; } ########################################################### bundle agent assign { vars: "scalar" int => "16k"; # "xxx" string => readfile( "/home/mark/tmp/testfile" , "33" ); "ran" int => randomint(4,88); # "yyy" slist => { readstringlist("/home/mark/tmp/testlist","#[a-zA-Z0-9 ]*","[^a-zA-Z0-9]",15,4000) }; # "zzz" slist => { readstringlist("/home/mark/tmp/testlist2","#[^\n]*",",",5,4000) }; # "aaa" ilist => { readintlist("/home/mark/tmp/testilist","#[a-zA-Z0-9 ]*",",",10,4000) }; "dim_array" int => readstringarray("array_name","/etc/passwd","#[^\n]*",":",10,4000); classes: # Standard aliasing "myclass" or => { "solaris", "linux" }; # got_array is a class that says whether the read was successful # array_name[] is the lval # Create a distribution "my_dist" dist => { "10", "20", "30", "40" }; # # Now like "alerts" in cf2 # reports: "Dimension of passwd array $(dim_array)"; "Read item from list: $(yyy)"; # Any kind of rule can define classes on exit "Read this file: [$(xxx)] ..." classes => persist("alertclass","20"); } ###################################################################### body classes persist(class,time) { promise_repaired => { "$(class)" }; persist_time => "$(time)"; timer_policy => "absolute"; } cfengine-3.24.2/examples/findfiles_up.cf0000644000000000000000000000213715010704253020155 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ mkdir -p /tmp/repo/.git/ #@ touch /tmp/repo/.git/config #@ mkdir -p /tmp/repo/submodule/.git/ #@ touch /tmp/repo/submodule/.git/config #@ mkdir -p /tmp/repo/submodule/some/place/deep/within/my/repo/ #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent __main__ { vars: "path" # path to search up from string => "/tmp/repo/submodule/some/place/deep/within/my/repo/"; "glob" # glob pattern matching filename string => ".git/config"; "level" # how far to search int => "inf"; "configs" data => findfiles_up("$(path)", "$(glob)", "$(level)"); reports: "Submodules '$(glob)' is located in '$(configs[0])'"; "Parents '$(glob)' is located in '$(configs[1])'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Submodules '.git/config' is located in '/tmp/repo/submodule/.git/config' #@ R: Parents '.git/config' is located in '/tmp/repo/.git/config' #@ ``` #+end_src cfengine-3.24.2/examples/app_baseline.cf0000644000000000000000000000450115010704253020125 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################################### # # app_baseline.cf - Verify Existence of Applications # # NOTE: Sometimes applications are not correctly installed even # though the native package manager reports them to be. # Cfengine can check for application-specific configuration # and act upon or report any anomalies. # ######################################################################### bundle agent app_baseline { methods: windows:: "any" usebundle => detect_adobereader; } ### bundle agent detect_adobereader { vars: windows:: "value1" string => registryvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\Acrobat Reader\9.0\Installer", "ENU_GUID"); "value2" string => registryvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\Acrobat Reader\9.0\Installer", "VersionMax"); "value3" string => registryvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\Acrobat Reader\9.0\Installer", "VersionMin"); classes: windows:: "is_correct" and => { strcmp("$(value1)", "{AC76BA86-7AD7-1033-7B44-A93000000001}"), strcmp("$(value2)", "90003"), islessthan("$(value3)", "10001" ) }; reports: windows.!is_correct:: "Adobe Reader is not correctly deployed - got \"$(value1)\", \"$(value2)\", \"$(value3)\""; } cfengine-3.24.2/examples/file_hash.cf0000644000000000000000000000432415010704253017430 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo 1 > /tmp/1 #@ echo 2 > /tmp/2 #@ echo 3 > /tmp/3 #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "md5" string => file_hash("/tmp/1","md5"); "sha256" string => file_hash("/tmp/2","sha256"); "sha384" string => hash("/tmp/3","sha384"); "sha512" string => hash("/tmp/3","sha512"); reports: "'1\n' hashed to: md5 $(md5)"; "'2\n' hashed to: sha256 $(sha256)"; "'3\n' hashed to: sha384 $(sha384)"; "'3\n' hashed to: sha512 $(sha512)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: '1\n' hashed to: md5 b026324c6904b2a9cb4b88d6d61c81d1 #@ R: '2\n' hashed to: sha256 53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3 #@ R: '3\n' hashed to: sha384 54f7379844b41bf513c0557a7195ca96a8ac90d0f8cc87d3607ef7ab593a7c61732759387afaabaf72ca2c0bd599373e #@ R: '3\n' hashed to: sha512 48b3c46b24db82059b5c87603066cf8d2165837d66e268286feb384644c808c06edf99aeaca0d879f4ee6ec70ebfaa0b98d5b77c12f7c0a68de3f7302dec6e21 #@ ``` #+end_src cfengine-3.24.2/examples/getfields.cf0000644000000000000000000000355215010704253017456 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "no" int => getfields("root:.*","/etc/passwd",":","userdata"); reports: "Found $(no) lines matching"; "root's handle = $(userdata[1])"; "root's passwd = ... forget it!"; "root's uid = $(userdata[3])"; # uncomment this if you want to see the HOMEDIR field #"root's homedir = $(userdata[6])"; # uncomment this if you want to see the GID field #"root's gid = $(userdata[4])"; # uncomment this if you want to see the GECOS field #"root's name = $(userdata[5])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found 1 lines matching #@ R: root's handle = root #@ R: root's passwd = ... forget it! #@ R: root's uid = 0 #@ ``` #+end_src cfengine-3.24.2/examples/defaults2.cf0000644000000000000000000000332415010704253017376 0ustar00rootroot00000000000000 # Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Default values for variables and parameters, introduced 3.4.0 # body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "Y" slist => { "I am list item 1", "I am list item 2" }; methods: # More useful, defaults if parameters are passed to a param bundle "example" usebundle => mymethod(@(example.Y)); } ########################################################### bundle agent mymethod(list) { defaults: "list" slist => { "1", "2", "3"}, if_match_regex => ".*list item.*"; # "list" string => "1" , if_match_regex => ".*list item.*"; reports: "The value of list is $(list)"; } cfengine-3.24.2/examples/copylinks.cf0000644000000000000000000000405515010704253017522 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test copy with link/copy exceptions # ######################################################## ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { files: "/home/mark/tmp/test_to" copy_from => mycopy("/home/mark/tmp/test_from"), perms => system, move_obstructions => "true", depth_search => recurse("inf"); } ######################################################### body perms system { mode => "0644"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } ######################################################### body copy_from mycopy(from) { source => "$(from)"; #copylink_patterns => { ".*" }; # copy all links linkcopy_patterns => { ".*" }; # copy all links #copy_backup => "timestamp"; } cfengine-3.24.2/examples/peers.cf0000644000000000000000000000606715010704253016632 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo alpha > /tmp/cfe_hostlist #@ echo beta >> /tmp/cfe_hostlist #@ echo gamma >> /tmp/cfe_hostlist #@ echo "Set HOSTNAME appropriately beforehand" #@ touch $CFENGINE_TEST_OVERRIDE_WORKDIR/inputs/promises.cf # to enable cf-promises to run #@ bash -c "${CF_PROMISES} --show-vars=sys.fqhost | grep fqhost | awk '{print \$2}' | tr 'A-Z' 'a-z' 2>&1 >> /tmp/cfe_hostlist" #@ echo "Delta Delta Delta may I help ya help ya help ya" #@ echo delta1 >> /tmp/cfe_hostlist #@ echo delta2 >> /tmp/cfe_hostlist #@ echo delta3 >> /tmp/cfe_hostlist #@ echo may1.I.help.ya >> /tmp/cfe_hostlist #@ echo may2.I.help.ya >> /tmp/cfe_hostlist #@ echo may3.I.help.ya >> /tmp/cfe_hostlist #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "peers" }; } bundle agent peers { vars: "mygroup" slist => peers("/tmp/cfe_hostlist","#.*",4); "myleader" string => peerleader("/tmp/cfe_hostlist","#.*",4); "all_leaders" slist => peerleaders("/tmp/cfe_hostlist","#.*",4); reports: # note that the current host name is fourth in the host list, so # its peer group is the first 4-host group, minus the host itself. "/tmp/cfe_hostlist mypeer $(mygroup)"; # note that the current host name is fourth in the host list, so # the peer leader is "alpha" "/tmp/cfe_hostlist myleader $(myleader)"; "/tmp/cfe_hostlist another leader $(all_leaders)"; "Unable to find my fully qualified hostname $(sys.fqhost) in /tmp/cfe_hostlist. Can't determine peers." if => not( regline( $(sys.fqhost), "/tmp/cfe_hostlist" ) ); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /tmp/cfe_hostlist mypeer alpha #@ R: /tmp/cfe_hostlist mypeer beta #@ R: /tmp/cfe_hostlist mypeer gamma #@ R: /tmp/cfe_hostlist myleader alpha #@ R: /tmp/cfe_hostlist another leader alpha #@ R: /tmp/cfe_hostlist another leader delta1 #@ R: /tmp/cfe_hostlist another leader may2.I.help.ya #@ ``` #+end_src cfengine-3.24.2/examples/epimenides.cf0000644000000000000000000000225615010704253017632 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "g" }; } bundle common g { vars: "head" string => "Swallow my ${tail}"; "tail" string => "behind my "; reports: "Go $(head)"; } cfengine-3.24.2/examples/hostsseen.cf0000644000000000000000000000227715010704253017526 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } bundle agent example { vars: "myhosts" slist => { hostsseen("inf","lastseen","address") }; reports: "Found client/peer: $(myhosts)"; } cfengine-3.24.2/examples/literal_server.cf0000644000000000000000000000577415010704253020542 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Remote value from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-d2] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { vars: "encrypt" string => "yes"; "x" string => "scalar2"; "remote1" string => remotescalar("test_scalar1","127.0.0.1","$(encrypt)"); "remote2" string => remotescalar("test_scalar2","127.0.0.1","$(encrypt)"); "remote3" string => remotescalar("test_scalar3","127.0.0.1","$(encrypt)"); "remote_error" string => remotescalar("test_$(x)","127.0.0.2","$(encrypt)"); reports: "Receive value $(remote1), $(remote2), $(remote3)"; "And an error gives: $(remote_error)"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowusers => { "mark" }; } ######################################################### bundle server access_rules() { vars: "localvar" string => "literal string"; access: "Embed a $(localvar) for remote access" handle => "test_scalar1", resource_type => "literal", admit => { "127.0.0.1" }; "Mary had a little lamb whose fleece was white as snow and everywhere that Mary went she wore it lovingly" handle => "test_scalar2", resource_type => "literal", admit => { "127.0.0.1" }; "/etc/passwd" handle => "test_scalar3", admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/reporttofile.cf0000644000000000000000000000223115010704253020217 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } # bundle agent example { reports: "$(sys.date),This is a report" report_to_file => "/tmp/test_log"; } cfengine-3.24.2/examples/copydir_copbl.cf0000644000000000000000000000262215010704253020335 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "my_recursive_copy" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent my_recursive_copy { files: "/home/mark/tmp/test_dir" copy_from => local_cp("$(sys.workdir)/bin/."), depth_search => recurse("inf"); "/home/mark/tmp/test_dir" copy_from => secure_cp("$(sys.workdir)/bin","serverhost"), depth_search => recurse("inf"); } cfengine-3.24.2/examples/template2.cf0000644000000000000000000000214015010704253017375 0ustar00rootroot00000000000000 body common control { bundlesequence => { "example" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent example { methods: "any" usebundle => get_template("/tmp/sudoers","400"); "any" usebundle => get_template("/tmp/hosts","644"); } ############################################################# bundle agent get_template(final_destination,mode) { vars: # This needs to ne preconfigured to your site "masterfiles" string => "/home/mark/tmp"; "this_template" string => lastnode("$(final_destination)","/"); files: "$(final_destination).staging" comment => "Get template and expand variables for this host", perms => mo("400","root"), copy_from => remote_cp("$(masterfiles)/templates/$(this_template)","$(policy_server)"), action => if_elapsed("60"); "$(final_destination)" comment => "Expand the template", create => "true", edit_line => expand_template("$(final_destination).staging"), edit_defaults => empty, perms => mo("$(mode)","root"), action => if_elapsed("60"); } cfengine-3.24.2/examples/mustache_extension_compact_json.cf0000644000000000000000000000103615010704253024147 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent main { vars: "msg" string => "Hello World"; "report" string => string_mustache("{{$-top-}}", bundlestate( $(this.bundle) ) ), unless => isvariable( $(this.promiser) ); # Careful to not include # ourselves so we only grab the # state of the first pass. reports: "$(report)"; } #+end_src #+begin_src example_output #@ ``` #@ R: {"msg":"Hello World"} #@ ``` #+end_src cfengine-3.24.2/examples/edit_xml.cf0000644000000000000000000000520415010704253017311 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ############################################################################### #+begin_src cfengine3 # for more info: http://cfengine.com/docs/master/reference-promise-types-edit_xml.html body common control { bundlesequence => { run }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent run { vars: "file" string => "$(this.promise_filename).txt"; methods: "rm" usebundle => rmxml; "make" usebundle => makexml; "use" usebundle => maintainxml; "report" usebundle => reportxml; } bundle agent rmxml { files: "$(run.file)" delete => tidy; } bundle agent makexml { files: "$(run.file)" comment => "Create xml file", create => "true", edit_defaults => empty, edit_xml => xml_insert_tree_nopath('cfe_alias'); } bundle agent reportxml { vars: "data" string => readfile($(run.file), 4k); reports: "Final XML is $(data)"; # R: Final XML is # newhosttextnewalias } bundle agent maintainxml { files: "$(run.file)" comment => "Maintain xml file: set the Alias node", create => "false", edit_xml => xml_set_value("newalias","/Host/Alias"); "$(run.file)" comment => "Maintain xml file: replace a Host node with a name attribute = cfe_host", create => "false", edit_xml => xml_set_value("newhosttext","/Host[@name='cfe_host']"); "$(run.file)" comment => "Maintain xml file: replace a Host node's name attribute", create => "false", edit_xml => xml_set_attribute("name", "newhostname", "/Host"); } #+end_src cfengine-3.24.2/examples/activedirectory_listusers.cf0000644000000000000000000000303115010704253023015 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # List users from Active Directory through LDAP # Note: Anonymous LDAP binding must be allowed, and the Anonymous user # must have read access to CN=Users bundle agent ldap { vars: "userlist" slist => ldaplist( "ldap://cf-win2003", "CN=Users,DC=domain,DC=cf-win2003", "(objectClass=user)", "sAMAccountName", "subtree", "none"); reports: "Username: \"$(userlist)\""; } cfengine-3.24.2/examples/orchestrate_dragon.cf0000644000000000000000000001255615010704253021371 0ustar00rootroot00000000000000############################################################ # # Chinese Dragon Dancing on a Star # # This method works with either Community or Enterprise. # and uses named signals # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # ############################################################ body common control { bundlesequence => { "dragon_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################################ bundle agent dragon_symphony { methods: # We have to seed the beginning by creating the dragon # /tmp/dragon_localhost "dragon" usebundle => visit("localhost","host1","chapter1"); "dragon" usebundle => visit("host1","host2","chapter2"); "dragon" usebundle => visit("host2","host3","chapter3"); "dragon" usebundle => visit("host3","host4","chapter4"), classes => if_ok("finale"); reports: finale:: "The dragon is slain:" printfile => visitors_book("/tmp/shoo_dragon_host4"); } ############################################################ # Define the ############################################################ bundle agent chapter1(x) { # Do something significant here reports: host1:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter2(x) { # Do something significant here reports: host2:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter3(x) { # Do something significant here reports: host3:: " ----> Breathing fire on $(x)"; } ################################ bundle agent chapter4(x) { # Do something significant here reports: host4:: " ----> Breathing fire on $(x)"; } ############################################################ # Orchestration wrappers ############################################################ bundle agent visit(predecessor,satellite,method) { # This is a wrapper for the orchestration will be acted on # first by the dragon's lair and then by the satellite vars: "dragons_lair" string => "host0"; files: # We start in the dragon's lair .. "/tmp/unleash_dragon" comment => "Unleash the dragon", rename => to("/tmp/enter_the_dragon"), classes => if_repaired("dispatch_dragon_$(satellite)"), if => "$(dragons_lair)"; # if we are the dragon's lair, welcome the dragon back, shooed from the satellite "/tmp/enter_the_dragon" comment => "Returning from a visit to a satellite", copy_from => secure_cp("/tmp/shoo_dragon_$(predecessor)","$(predecessor)"), classes => if_repaired("dispatch_dragon_$(satellite)"), if => "$(dragons_lair)"; # If we are a satellite, receive the dragon from its lair "/tmp/enter_the_dragon" comment => "Wait for our cue or relay/conductor baton", copy_from => secure_cp("/tmp/dragon_$(satellite)","$(dragons_lair)"), classes => if_repaired("cue_action_on_$(satellite)"), if => "$(satellite)"; methods: "check in at home" comment => "Edit the load balancer?", usebundle => switch_satellite(" -> Send dragon to $(satellite)"), classes => if_repaired("send_the_dragon_to_$(satellite)"), if => "dispatch_dragon_$(satellite)"; "dragon visits" comment => "One off activity that the nodes carry out while the dragon visits", usebundle => $(method)("$(satellite)"), classes => if_repaired("send_the_dragon_back_from_$(satellite)"), if => "cue_action_on_$(satellite)"; files: # hub/lair hub signs the book too and schedules the dragon for next satellite "/tmp/dragon_$(satellite)" create => "true", comment => "Add our signature to the dragon's tail", edit_line => sign_visitor_book("Dragon returned from $(predecessor)"), if => "send_the_dragon_to_$(satellite)"; # Satellite signs the book and shoos dragon for hub to collect "/tmp/shoo_dragon_$(satellite)" create => "true", comment => "Add our signature to the dragon's tail", edit_line => sign_visitor_book("Dragon visited $(satellite) and did: $(method)"), if => "send_the_dragon_back_from_$(satellite)"; reports: "Done $(satellite)"; } ############################################################ bundle agent switch_satellite(name) { files: "/tmp/enter_the_dragon" comment => "Add our signature to the dragon's tail", edit_line => append_if_no_line("Switch new dragon's target $(name)"); reports: " X Switching new dragon's target $(name)"; } ############################################################ bundle edit_line sign_visitor_book(s) { insert_lines: "/tmp/enter_the_dragon" comment => "Import the current visitor's book", insert_type => "file"; "$(s)" comment => "Append this string to the visitor's book"; } ############################################################ bundle server access_rules() { access: "/tmp" admit => { "127.0.0.1" }; "did.*" resource_type => "context", admit => { "127.0.0.1" }; } ############################################################ body printfile visitors_book(file) { file_to_print => "$(file)"; number_of_lines => "100"; } cfengine-3.24.2/examples/shuffle.cf0000644000000000000000000000324615010704253017144 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "mylist" slist => { "b", "c", "a" }; "seeds" slist => { "xx", "yy", "zz" }; "shuffled_$(seeds)" slist => shuffle(mylist, $(seeds)); "joined_$(seeds)" string => join(",", "shuffled_$(seeds)"); reports: "shuffled RANDOMLY by $(seeds) = '$(joined_$(seeds))'"; } #+end_src ############################################################################### # Not checked because shuffle is random. #+begin_src example_output #@ ``` #@ R: shuffled RANDOMLY by xx = 'b,a,c' #@ R: shuffled RANDOMLY by yy = 'a,c,b' #@ R: shuffled RANDOMLY by zz = 'c,b,a' #@ ``` #+end_src cfengine-3.24.2/examples/report_custom.cf0000644000000000000000000000327615010704253020420 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } bundle agent example { vars: "software" slist => { "gpg", "zip", "rsync" }; classes: "noreport" expression => fileexists("/tmp/report.html"); "have_$(software)" expression => fileexists("/usr/bin/$(software)"); reports: no_report:: " Name of this host is: $(sys.host)
    Type of this host is: $(sys.os)
    " report_to_file => "/tmp/report.html"; # " Host has software $(software)
    " if => "have_$(software)", report_to_file => "/tmp/report.html"; # " " report_to_file => "/tmp/report.html"; } cfengine-3.24.2/examples/edit_sectioned_file.cf0000644000000000000000000000535215010704253021471 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test editfile # ######################################################## # # This assumes a file format like: # # [section 1] # # lines.... # # [section 2] # # lines... etc body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { vars: "v1" string => "numerical backreference"; files: "/home/mark/tmp/cf3_test" create => "true", edit_line => AppendIfNoLine("cfengine tcp 5308","second"); } ######################################################## bundle edit_line AppendIfNoLine(parameter,two) { vars: "list" slist => { "1", "2", "3" }; insert_lines: "$(parameter) and $(two)-$(list)" location => append; "NEW Special-insert!!!" select_region => MySection("New section"); "set variable = value" select_region => MySection("New section"); "/home/mark/tmp/insert" insert_type => "file", expand_scalars => "true", select_region => MySection("New section"); delete_lines: # "l.*"; # "NEW.*" select_region => MySection("New section"); # Delete LinesStarting in file } ######################################################## body location append { # If not line to match, applies to whole text body before_after => "after"; } ######################################################## body location after(x) { # If not line to match, applies to whole text body #select_line_matching => "$(x)"; before_after => "after"; } ######################################################## body select_region MySection(x) { select_start => "\[$(x)\]"; select_end => "\[.*\]"; } cfengine-3.24.2/examples/irange.cf0000644000000000000000000000311215010704253016745 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "cleanup" }; } bundle agent cleanup { files: # This will not delete the parent "/home/mark/tmp/testcopy" delete => tidyfiles, file_select => changed_within_1_year, depth_search => recurse; #Now delete the parent. "/home/mark/tmp/testcopy" delete => tidyfiles; } body delete tidyfiles { dirlinks => "delete"; rmdirs => "true"; } body file_select changed_within_1_year { mtime => irange(ago(1,0,0,0,0,0),now); file_result => "mtime"; } body depth_search recurse { depth => "inf"; } cfengine-3.24.2/examples/orchestrate_dominoes1.cf0000644000000000000000000000471015010704253022006 0ustar00rootroot00000000000000############################################################ # # Dominoes # # This method works with either Community of Enterprise # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # ############################################################ body common control { bundlesequence => { "dominoes_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################################ bundle agent dominoes_symphony { methods: # We have to seed the beginning by creating the dominoes # /tmp/dominoes_localhost host1:: "dominoes" usebundle => hand_over("localhost","host1","overture"); host2:: "dominoes" usebundle => hand_over("host1","host2","first movement"); host3:: "dominoes" usebundle => hand_over("host2","host3","second movement"); host4:: "dominoes" usebundle => hand_over("host3","host4","final movement"), classes => if_ok("finale"); reports: finale:: "The visitors book of the Dominoes method" printfile => visitors_book("/tmp/dominoes_host4"); } ############################################################ bundle agent hand_over(predecessor,myalias,method) { # This is a wrapper for the orchestration files: "/tmp/tip_the_dominoes" comment => "Wait for our cue or relay/conductor baton", copy_from => secure_cp("/tmp/dominoes_$(predecessor)","$(predecessor)"), classes => if_repaired("cue_action"); cue_action:: "/tmp/outcome_of_part" comment => "One off activity", create => "true", edit_line => append_if_no_line("Do something meaningful by calling $(method)"), classes => if_ok("pass_the_stick"); pass_the_stick:: "/tmp/tip_the_dominoes" comment => "Add our signature to the dominoes's tail", edit_line => append_if_no_line("Knocked over $(myalias) and did: $(method)"); "/tmp/dominoes_$(myalias)" comment => "Dominoes in position to be beamed up by next agent", copy_from => local_cp("/tmp/tip_the_dominoes"); } ############################################################ bundle server access_rules() { access: "/tmp" admit => { "127.0.0.1" }; "did.*" resource_type => "context", admit => { "127.0.0.1" }; } body printfile visitors_book(file) { file_to_print => "$(file)"; number_of_lines => "10"; } cfengine-3.24.2/examples/classes_global.cf0000644000000000000000000000303315010704253020457 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "g","tryclasses_1", "tryclasses_2" }; } ################################# bundle common g { classes: "one" expression => "any"; "client_network" expression => iprange("128.39.89.0/24"); } ################################# bundle agent tryclasses_1 { classes: "two" expression => "any"; } ################################# bundle agent tryclasses_2 { classes: "three" expression => "any"; reports: one.three.!two:: "Success"; } ################################# cfengine-3.24.2/examples/parserealarray.cf0000644000000000000000000000332515010704253020523 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent __main__ { vars: # Define data inline for convenience "table" string => "1.0:2.718 3:4.6692 5.0:6.82"; "dim" int => parserealarray( "items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000" ); "keys" slist => sort(getindices("items")); reports: "$(keys) - $(items[$(keys)][1])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: 1.0 - 2.718 #@ R: 3 - 4.6692 #@ R: 5.0 - 6.82 #@ ``` #+end_src cfengine-3.24.2/examples/hashmatch.cf0000644000000000000000000000245715010704253017453 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { classes: "matches" expression => hashmatch("/etc/passwd","md5","c5068b7c2b1707f8939b283a2758a691"); reports: matches:: "File has correct version"; } cfengine-3.24.2/examples/user_edit.cf0000644000000000000000000000341015010704253017464 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # body common control { bundlesequence => { "users" }; } body agent control { abortbundleclasses => { "ldap_fail" }; } ################################################################################ bundle agent users { vars: "users" slist => { "mark", "nakarin", "jonhenrik" }; files: "/tmp/passwd2" create => "true", edit_line => fix_passwd("$(users)"); reports: !ldap_fail:: "Editing user $(users)"; } ################################################################################################### bundle edit_line fix_passwd(x) { classes: "ldap_fail" not => ldaparray("dat","ldap://eternity.iu.hio.no","dc=cfengine,dc=com","(uid=$(x))","subtree","none"); insert_lines: "Hello $(x),$(dat[uid]),$(dat[gecos])"; } cfengine-3.24.2/examples/kill_process_running_wrong_user.cf0000644000000000000000000000364215010704253024213 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent main { processes: # Any /usr/local/web/tomcat-logviewer processes not # running as buildsrv should be killed on sight. "/usr/local/web/tomcat-logviewer" -> { "security" } process_select => not_running_as("buildsrv"), signals => { "kill" }, comment => "It is against the security policy for this service to run under the wrong user id."; } body process_select not_running_as(owner) # @brief select processes that are not running as the expected owner # @param owner { process_owner => { $(owner) }; process_result => "!process_owner"; } #+end_src ############################################################################### #+begin_src static_example_output #@ ``` #@ info: Signalled 'kill' (9) to process 7211 (root 7211 7199 7211 0.0 0.1 100908 0 596 1 15:26 00:06 00:00:00 /usr/local/web/tomcat-logviewer 500) #@ ``` #+end_src cfengine-3.24.2/examples/regline.cf0000644000000000000000000000411115010704253017125 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # Function regline(regex,file) ###################################################################### #+begin_src cfengine3 bundle agent main # @brief An example showing how to use regline to see if a pattern exists within # a file. { vars: linux:: "file" string => "/proc/sys/net/ipv4/ip_forward"; "reg_enabled" string => "^1$"; "reg_disabled" string => "^0$"; classes: linux:: "ipv4_forwarding_enabled" -> { "SecOps" } expression => regline( $(reg_enabled) , $(file) ), comment => "We want to know if ip forwarding is enabled because it is a potential security issue."; "ipv4_forwarding_disabled" -> { "SecOps" } expression => regline( $(reg_disabled) , $(file) ); reports: ipv4_forwarding_enabled:: "I found that IPv4 forwarding is enabled!"; ipv4_forwarding_disabled:: "I found that IPv4 forwarding is disabled."; } #+end_src #+begin_src random_example_output #@ ``` #@ R: I found that IPv4 forwarding is disabled. #@ ``` #+end_src cfengine-3.24.2/examples/ordering.cf0000644000000000000000000000353615010704253017323 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ################################################################## # # cfengine 3 - ordering promises into dependent chains # ## # # cf-agent -f ./cftest.cf -K # ################################################################## body common control { bundlesequence => { "order" }; } ################################################################## bundle agent order { vars: "list" slist => { "three", "four" }; commands: ok_later:: "/bin/echo five"; otherthing:: "/bin/echo six"; any:: "/bin/echo one" classes => d("ok_later","otherthing"); "/bin/echo two"; "/bin/echo $(list)"; preserved_class:: "/bin/echo seven"; } ############################################ body classes d(if,else) { promise_repaired => { "$(if)" }; repair_failed => { "$(else)" }; persist_time => "0"; } cfengine-3.24.2/examples/intarray.cf0000644000000000000000000000236215010704253017337 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "dim_array" int => readstringarray("array_name","/tmp/array","#[^\n]*",":",10,4000); } cfengine-3.24.2/examples/dirname.cf0000644000000000000000000000260115010704253017121 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "apache_dir" string => dirname("/etc/apache2/httpd.conf"); reports: "apache conf dir = $(apache_dir)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: apache conf dir = /etc/apache2 #@ ``` #+end_src cfengine-3.24.2/examples/package_apt.cf0000644000000000000000000000525015010704253017744 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # to see list of packages type "apt-cache pkgnames" # to see list of installed packages type "dpkg --get-selections" # # Package management # body common control { bundlesequence => { "packages" }; } body agent control { environment => { "DEBIAN_FRONTEND=noninteractive" }; } ############################################# bundle agent packages { vars: # Test the simplest case -- leave everything to the yum smart manager "match_package" slist => { "apache2" # "apache2-mod_php5", # "apache2-prefork", # "php5" }; packages: "$(match_package)" package_policy => "add", package_method => apt; } ############################################# body package_method apt { any:: # ii acpi 0.09-3ubuntu1 package_changes => "bulk"; package_list_command => "/usr/bin/dpkg -l"; package_list_name_regex => "ii\s+([^\s]+).*"; package_list_version_regex => "ii\s+[^\s]+\s+([^\s]+).*"; # package_list_arch_regex => "none"; package_installed_regex => ".*"; # all reported are installed #package_name_convention => "$(name)_$(version)_$(arch)"; package_name_convention => "$(name)"; # Use these only if not using a separate version/arch string # package_version_regex => ""; # package_name_regex => ""; # package_arch_regex => ""; package_add_command => "/usr/bin/apt-get --yes install"; package_delete_command => "/usr/bin/apt-get --yes remove"; package_update_command => "/usr/bin/apt-get --yes dist-upgrade"; #package_verify_command => "/bin/rpm -V"; } cfengine-3.24.2/examples/varclass.cf0000644000000000000000000000240415010704253017321 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { commands: "/bin/echo This is linux" if => "linux"; "/bin/echo This is solaris" if => "solaris"; } cfengine-3.24.2/examples/isdir.cf0000644000000000000000000000254315010704253016621 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "isdir" expression => isdir("/"); reports: isdir:: "Directory exists.."; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Directory exists.. #@ ``` #+end_src cfengine-3.24.2/examples/cf-secret.cf0000644000000000000000000000510015010704253017352 0ustar00rootroot00000000000000# Copyright (C) Cfengine AS # This file is part of CFEngine 3 - written and maintained by Cfengine AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ############################################################################### #+begin_src cfengine3 bundle agent main { vars: "private_key" comment => "The decryption key", string => "$(this.promise_filename).priv"; "encrypted_file" string => "$(this.promise_filename).cfcrypt"; "secret" comment => "We decrypt the encrypted file directly into a variable.", string => execresult("$(sys.cf_secret) -d $(private_key) -i $(encrypted_file) -o -", noshell); reports: "Encrypted file content:" printfile => cat( $(encrypted_file) ); "Decrypted content:$(const.n)$(secret)"; } body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } #+end_src ############################################################################### #+begin_src static_example_output #@ ``` #@ R: Encrypted file content: #@ R: Version: 1.0 #@ R: #@ R: ���V�cv�#�P��, ��-O�8æ—¼[i����pò¢¢¦ï¿½Q� #@ R: Φ&l�x'�#j���qQ����[�F�1����v�Q��ˮ�J'�թ�|^HG%)�`&�����~k�$wd]"�%4X\(Q�~�O����s�A~���/��:�" gi�Rn&Ù�E^���߬3��M�ə�%2s�SB��b3���K4wm����o�B�:P��O�#��1�t8��`�@��j/��+����j��g஡����Z�D�iJ��͞j��8ĉ�ag�9vz?+�暢��So��.Org]�"+�S����_HÑ¢=_O% #@ R: Decrypted content: #@ Super secret message is here #@ ``` #+end_src cfengine-3.24.2/examples/datastate.cf0000644000000000000000000000410715010704253017457 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { holder, test }; } bundle common holder { classes: "holderclass" expression => "any"; # will be global vars: "s" string => "Hello!"; "d" data => parsejson('[4,5,6]'); "list" slist => { "element1", "element2" }; } bundle agent test { vars: "state" data => datastate(); # all the variables in bundle "holder" defined as of the execution of datastate() will be here "holderstate" string => format("%S", "state[vars][holder]"); # all the classes defined as of the execution of datastate() will be here "allclasses" slist => getindices("state[classes]"); classes: "have_holderclass" expression => some("holderclass", allclasses); reports: "holder vars = $(holderstate)"; have_holderclass:: "I have the holder class"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: holder vars = {"d":[4,5,6],"list":["element1","element2"],"s":"Hello!"} #@ R: I have the holder class #@ ``` #+end_src cfengine-3.24.2/examples/change_detect.cf0000644000000000000000000000330015010704253020254 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Change detect # ######################################################## #[%+%] body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/tmp/web" # Directory to monitor for changes. changes => detect_all_change, depth_search => recurse("inf"); } ######################################################### body changes detect_all_change { report_changes => "all"; update_hashes => "true"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } cfengine-3.24.2/examples/locate_files_and_compress.cf0000644000000000000000000000324615010704253022676 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Compressing files # ####################################################### body common control { bundlesequence => { "example" }; } ############################################ bundle agent example { files: "/home/mark/tmp/testcopy" file_select => pdf_files, transformer => "/usr/bin/gzip $(this.promiser)", depth_search => recurse("inf"); } ############################################ body file_select pdf_files { leaf_name => { ".*.pdf" , ".*.fdf" }; file_result => "leaf_name"; } ############################################ body depth_search recurse(d) { depth => "$(d)"; } cfengine-3.24.2/examples/cf_version_at.cf0000644000000000000000000000065215010704253020327 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This will be skipped if version is not the same" if => cf_version_at("3"); "This will be skipped if version is the same" unless => cf_version_at("3"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This will be skipped if version is not the same #@ ``` #+end_src cfengine-3.24.2/examples/isgreaterthan.cf0000644000000000000000000000261715010704253020351 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "ok" expression => isgreaterthan("1","0"); reports: ok:: "Assertion is true"; !ok:: "Assertion is false"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Assertion is true #@ ``` #+end_src cfengine-3.24.2/examples/getuserinfo.cf0000644000000000000000000000321715010704253020040 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: # note the results here will vary depending on your platform "me" data => getuserinfo(); # the current user's info "root" data => getuserinfo("root"); # the "root" user's info (usually UID 0) "uid0" data => getuserinfo(0); # lookup user info for UID 0 (usually "root") # sys.user_data has the information for the user that started the agent "out" string => format("I am '%s', root shell is '%s', and the agent was started by %S", "$(me[description])", "$(root[shell])", "sys.user_data"); reports: "$(out)"; } #+end_src cfengine-3.24.2/examples/rename.cf0000644000000000000000000000225715010704253016760 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => {"test"}; } bundle agent example { files: "/tmp/foo" rename => moveit; } body rename moveit { newname => "/tmp/foo_moved"; } cfengine-3.24.2/examples/sort.cf0000644000000000000000000000743215010704253016500 0ustar00rootroot00000000000000#+begin_src cfengine3 body common control { bundlesequence => { test }; } bundle agent test { vars: "a" slist => { "b", "c", "a" }; "b" slist => { "100", "9", "10", "8.23" }; "c" slist => { }; "d" slist => { "", "a", "", "b" }; "e" slist => { "a", "1", "b" }; "ips" slist => { "100.200.100.0", "1.2.3.4", "9.7.5.1", "9", "9.7", "9.7.5", "", "-1", "where are the IP addresses?" }; "ipv6" slist => { "FE80:0000:0000:0000:0202:B3FF:FE1E:8329", "FE80::0202:B3FF:FE1E:8329", "::1", # the following should all be parsed as the same address and sorted together "2001:db8:0:0:1:0:0:1", "2001:0db8:0:0:1:0:0:1", "2001:db8::1:0:0:1", "2001:db8::0:1:0:0:1", "2001:0db8::1:0:0:1", "2001:db8:0:0:1::1", "2001:db8:0000:0:1::1", "2001:DB8:0:0:1::1", # note uppercase IPv6 addresses are invalid # examples from https://www.ripe.net/lir-services/new-lir/ipv6_reference_card.pdf "8000:63bf:3fff:fdd2", "::ffff:192.0.2.47", "fdf8:f53b:82e4::53", "fe80::200:5aee:feaa:20a2", "2001:0000:4136:e378:", "8000:63bf:3fff:fdd2", "2001:0002:6c::430", "2001:10:240:ab::a", "2002:cb0a:3cdd:1::1", "2001:db8:8:4::2", "ff01:0:0:0:0:0:0:2", "-1", "where are the IP addresses?" }; "macs" slist => { "00:14:BF:F7:23:1D", "0:14:BF:F7:23:1D", ":14:BF:F7:23:1D", "00:014:BF:0F7:23:01D", "00:14:BF:F7:23:1D", "0:14:BF:F7:23:1D", ":14:BF:F7:23:1D", "00:014:BF:0F7:23:01D", "01:14:BF:F7:23:1D", "1:14:BF:F7:23:1D", "01:14:BF:F7:23:2D", "1:14:BF:F7:23:2D", "-1", "where are the MAC addresses?" }; "ja" string => join(",", "a"); "jb" string => join(",", "b"); "jc" string => join(",", "c"); "jd" string => join(",", "d"); "je" string => join(",", "e"); "jips" string => join(",", "ips"); "jipv6" string => join(",", "ipv6"); "jmacs" string => join(",", "macs"); "sa" slist => sort("a", "lex"); "sb" slist => sort("b", "lex"); "sc" slist => sort("c", "lex"); "sd" slist => sort("d", "lex"); "se" slist => sort("e", "lex"); "sb_int" slist => sort("b", "int"); "sb_real" slist => sort("b", "real"); "sips" slist => sort("ips", "ip"); "sipv6" slist => sort("ipv6", "ip"); "smacs" slist => sort("macs", "mac"); "jsa" string => join(",", "sa"); "jsb" string => join(",", "sb"); "jsc" string => join(",", "sc"); "jsd" string => join(",", "sd"); "jse" string => join(",", "se"); "jsb_int" string => join(",", "sb_int"); "jsb_real" string => join(",", "sb_real"); "jsips" string => join(",", "sips"); "jsipv6" string => join(",", "sipv6"); "jsmacs" string => join(",", "smacs"); reports: "sorted lexicographically '$(ja)' => '$(jsa)'"; "sorted lexicographically '$(jb)' => '$(jsb)'"; "sorted lexicographically '$(jc)' => '$(jsc)'"; "sorted lexicographically '$(jd)' => '$(jsd)'"; "sorted lexicographically '$(je)' => '$(jse)'"; "sorted integers '$(jb)' => '$(jsb_int)'"; "sorted reals '$(jb)' => '$(jsb_real)'"; "sorted IPs '$(jips)' => '$(jsips)'"; "sorted IPv6s '$(jipv6)' => '$(jsipv6)'"; "sorted MACs '$(jmacs)' => '$(jsmacs)'"; } #+end_src cfengine-3.24.2/examples/execresult.cf0000644000000000000000000000526715010704253017700 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ rm -rf /tmp/testhere #@ mkdir -p /tmp/testhere #@ touch /tmp/testhere/a #@ touch /tmp/testhere/b #@ touch /tmp/testhere/c #@ touch /tmp/testhere/d #@ touch /tmp/testhere/e #@ echo "#!/usr/bin/env sh" >/tmp/testhere/echo-stdout-and-stderr #@ echo "echo stderr >&2" >>/tmp/testhere/echo-stdout-and-stderr #@ echo "echo stdout" >>/tmp/testhere/echo-stdout-and-stderr #@ chmod +x /tmp/testhere/echo-stdout-and-stderr #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "my_result" string => execresult("/bin/ls /tmp/testhere", noshell); "my_result_with_stdout_and_stderr" string => execresult("/tmp/testhere/echo-stdout-and-stderr", noshell); "my_result_with_stdout" string => execresult("/tmp/testhere/echo-stdout-and-stderr 2>/dev/null", useshell); "my_result_with_stderr" string => execresult("/tmp/testhere/echo-stdout-and-stderr 1>/dev/null", useshell); reports: "/bin/ls /tmp/testhere returned '$(my_result)'"; "my_result_with_stdout_and_stderr == '$(my_result_with_stdout_and_stderr)'"; "my_result_with_stdout == '$(my_result_with_stdout)'"; "my_result_with_stderr == '$(my_result_with_stderr)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /bin/ls /tmp/testhere returned 'a #@ b #@ c #@ d #@ e #@ echo-stdout-and-stderr' #@ R: my_result_with_stdout_and_stderr == 'stderr #@ stdout' #@ R: my_result_with_stdout == 'stdout' #@ R: my_result_with_stderr == 'stderr' #@ ``` #+end_src cfengine-3.24.2/examples/win_dns_client.cf0000644000000000000000000000164515010704253020510 0ustar00rootroot00000000000000# Ensures correct DNS settings for Windows DNS clients # Tested on: Windows Server 2003 32-bit, Windows Server 2008 R2 64-bit body common control { bundlesequence => { "windows_dns" }; } bundle agent windows_dns { vars: "dns_servers" string => "192.168.1.3 192.168.1.4"; "keys" string => execresult("$(sys.winsysdir)\reg.exe query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces", "noshell"); "key_list" slist => splitstring("$(keys)", "\r\n", 50); databases: "$(key_list)" comment => "Ensure DNS client configuration is correct", handle => canonify("windows_dns_$(dns_servers)"), database_operation => "create", database_rows => { "NameServer,REG_SZ,$(dns_servers)" }, database_type => "ms_registry", if => not( strcmp("$(key_list)", "" )); } cfengine-3.24.2/examples/select_region.cf0000644000000000000000000000567315010704253020340 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo "MATCHING before region" > /tmp/example_select_region.txt #@ echo "BEGIN" >> /tmp/example_select_region.txt #@ echo "MATCHING inside region" >> /tmp/example_select_region.txt #@ echo "END" >> /tmp/example_select_region.txt #@ echo "MATCHING after region" >> /tmp/example_select_region.txt #@ ``` #+end_src #+begin_src cfengine3 bundle agent main # @brief Demonstrate how edit_line can operate within a region of a file { vars: "file" string => "/tmp/example_select_region.txt"; files: "$(file)" comment => "We want to delete any lines that begin with the string MATCHING inside the region described by regular expressions matching the beginning and end of the region.", create => "true", edit_line => delete_inside_region("^MATCHING.*", "^BEGIN.*", "^END.*"); reports: "$(file)" printfile => cat( $(this.promiser) ); } ######################################################## bundle edit_line delete_inside_region(line_reg, begin_reg, end_reg) # @brief Delete lines matching `line_reg` when found within the expected region starting with `begin_reg` and `end_reg` { delete_lines: "$(line_reg)" select_region => between( $(begin_reg), $(end_reg) ); } body select_region between(start, end) # @brief Select a region exclusively between regular expressions `start` and `end`. { select_start => "$(start)"; select_end => "$(end)"; @if minimum_version(3.10) select_end_match_eof => "false"; @endif } body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } #+end_src #+begin_src example_output #@ ``` #@ R: /tmp/example_select_region.txt #@ R: MATCHING before region #@ R: BEGIN #@ R: END #@ R: MATCHING after region #@ ``` #+end_src cfengine-3.24.2/examples/measurements.cf0000644000000000000000000000754415010704253020225 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #cop measurements,example ####################################################### # # Test file: # # First line # Blonk blonk bnklkygsuilnm # ####################################################### body common control { bundlesequence => { "report" }; } ####################################################### body monitor control { forgetrate => "0.7"; histograms => "true"; } ####################################################### bundle agent report { reports: " Free memory read at $(mon.av_free_memory_watch) cf_monitord read $(mon.value_monitor_self_watch) "; } ####################################################### bundle monitor watch { measurements: # Test 1 - extract string matching "/home/mark/tmp/testmeasure" handle => "blonk_watch", stream_type => "file", data_type => "string", history_type => "weekly", units => "blonks", match_value => find_blonks, action => sample_min("10"); # Test 2 - follow a special process over time # using cfengine's process cache to avoid resampling "/var/cfengine/state/cf_rootprocs" handle => "monitor_self_watch", stream_type => "file", data_type => "int", history_type => "static", units => "kB", match_value => proc_value(".*cf-monitord.*", "root\s+[0-9.]+\s+[0-9.]+\s+[0-9.]+\s+[0-9.]+\s+([0-9]+).*"); # Test 3, discover disk device information "/bin/df" handle => "free_disk_watch", stream_type => "pipe", data_type => "slist", history_type => "static", units => "device", match_value => file_system; # Update this as often as possible # Test 4 "/tmp/file" handle => "line_counter", stream_type => "file", data_type => "counter", match_value => scanlines("MYLINE.*"), history_type => "log"; } ########################################################## body match_value scanlines(x) { select_line_matching => "^$(x)$"; } ########################################################## body action sample_min(x) { ifelapsed => "$(x)"; expireafter => "$(x)"; } ########################################################## body match_value find_blonks { select_line_number => "2"; extraction_regex => "Blonk blonk ([blonk]+).*"; } ########################################################## body match_value free_memory # not willy! { select_line_matching => "MemFree:.*"; extraction_regex => "MemFree:\s+([0-9]+).*"; } ########################################################## body match_value proc_value(x,y) { select_line_matching => "$(x)"; extraction_regex => "$(y)"; } ########################################################## body match_value file_system { select_line_matching => "/.*"; extraction_regex => "(.*)"; } cfengine-3.24.2/examples/module_exec_2.cf0000644000000000000000000000333615010704253020222 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Test module execution as class function # body common control { bundlesequence => { "def", "example" }; } ################################################################### bundle agent def { commands: "$(sys.workdir)/modules/module_name" module => "true"; reports: # # Each module forms a private context with its name as id # module_class:: "Module set variable $(module_name.myscalar)"; } ################################################################### bundle agent example { vars: "mylist" slist => { @(module_name.mylist) }; reports: # # Each module forms a private context with its name as id # module_class:: "Module set variable $(mylist)"; } cfengine-3.24.2/examples/printfile.cf0000644000000000000000000000237315010704253017504 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ echo 'Line 1' > /tmp/example_file.txt #@ echo 'Line 2' >> /tmp/example_file.txt #@ echo 'Line 3' >> /tmp/example_file.txt #@ echo 'Line 4' >> /tmp/example_file.txt #@ echo 'Line 5' >> /tmp/example_file.txt #@ echo 'Line 6' >> /tmp/example_file.txt #@ echo 'Line 7' >> /tmp/example_file.txt #@ echo 'Line 8' >> /tmp/example_file.txt #@ echo 'Line 9' >> /tmp/example_file.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "example_file" string => "/tmp/example_file.txt"; reports: "First three:" printfile => first_three("$(example_file)"); "Last three:" printfile => last_three("$(example_file)"); } body printfile first_three(file) { file_to_print => "$(file)"; number_of_lines => "3"; } body printfile last_three(file) { file_to_print => "$(file)"; number_of_lines => "-3"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: First three: #@ R: Line 1 #@ R: Line 2 #@ R: Line 3 #@ R: Last three: #@ R: Line 7 #@ R: Line 8 #@ R: Line 9 #@ ``` #+end_src cfengine-3.24.2/examples/service_catalogue_separate.cf0000644000000000000000000000117415010704253023056 0ustar00rootroot00000000000000body common control { bundlesequence => { "service_catalogue_separate" }; } bundle agent service_catalogue_separate { services: "foo" service_policy => "start", service_method => service_bundle_separate; "bar" service_policy => "stop", service_method => service_bundle_separate; } body service_method service_bundle_separate { service_bundle => $(this.promiser)("$(this.service_policy)"); } bundle agent foo(service_policy) { reports: "we need to ensure $(service_policy) of foo"; } bundle agent bar(service_policy) { reports: "we need to ensure $(service_policy) of bar"; } cfengine-3.24.2/examples/string_split.cf0000644000000000000000000000335415010704253020231 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "split1" slist => string_split("one:two:three", ":", "10"); "split2" slist => string_split("one:two:three", ":", "1"); "split3" slist => string_split("alpha:xyz:beta", "xyz", "10"); reports: "split1: $(split1)"; # will list "one", "two", and "three" "split2: $(split2)"; # will list "one:two:three" "split3: $(split3)"; # will list "alpha:" and ":beta" } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: split1: one #@ R: split1: two #@ R: split1: three #@ R: split2: one:two:three #@ R: split3: alpha: #@ R: split3: :beta #@ ``` #+end_src cfengine-3.24.2/examples/namespace_hard_classes.cf0000644000000000000000000000247215010704253022157 0ustar00rootroot00000000000000bundle agent __main__ { methods: "example:my_bundle"; reports: cfengine:: "From the '$(this.namespace)' namespace the class expression 'cfengine::' evaluates true"; default:cfengine:: "From the '$(this.namespace)' namespace the class expression 'default:cfengine::' evaluates true"; "The class 'cfengine' has tags: $(with)" with => join( ", ", getclassmetatags( "cfengine" ) ); } body file control { namespace => "example"; } bundle agent my_bundle { reports: cfengine:: "From the '$(this.namespace)' namespace the class expression 'cfengine::' evaluates true"; default:cfengine:: "From the '$(this.namespace)' namespace the class expression 'default:cfengine::' evaluates true"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: From the 'example' namespace the class expression 'cfengine::' evaluates true #@ R: From the 'example' namespace the class expression 'default:cfengine::' evaluates true #@ R: From the 'default' namespace the class expression 'cfengine::' evaluates true #@ R: From the 'default' namespace the class expression 'default:cfengine::' evaluates true #@ R: The class 'cfengine' has tags: inventory, attribute_name=none, source=agent, hardclass #@ ``` #+end_src cfengine-3.24.2/examples/storage.cf0000644000000000000000000000271515010704253017154 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # cfengine 3 # # cf-agent -f ./cftest.cf -K # body common control { bundlesequence => { "storage" }; } # bundle agent storage { storage: "/usr" volume => mycheck("11G"); "/" volume => mycheck("60%"); } ###################################################################### body volume mycheck(free) # reusable template { check_foreign => "false"; freespace => "$(free)"; sensible_size => "10000"; sensible_count => "2"; } cfengine-3.24.2/examples/file_change_detection.cf0000644000000000000000000000406215010704253021767 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple backgrounding # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## body agent control { agentaccess => { "mark", "root" }; } ######################################################## bundle agent example { files: "/home/mark/tmp" -> "me" changes => tripwire, depth_search => recurse("inf"), action => background; "/home/mark/LapTop/words" -> "you" changes => tripwire, depth_search => recurse("inf"); } ######################################################### body changes tripwire { hash => "md5"; report_changes => "content"; update_hashes => "true"; } ######################################################### body action background { background => "true"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } cfengine-3.24.2/examples/helloworld.cf0000644000000000000000000000214615010704253017661 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. bundle agent main { files: "/tmp/hello_world" create => "true", content => "Hello, CFEngine!$(const.n)"; } cfengine-3.24.2/examples/method_validate.cf0000644000000000000000000000326515010704253020642 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; version => "1.2.3"; } ########################################### body agent control { abortbundleclasses => { "invalid" }; } ########################################### bundle agent example { vars: "userlist" slist => { "xyz", "mark", "jeang", "jonhenrik", "thomas", "eben" }; methods: "any" usebundle => subtest("$(userlist)"); } ########################################### bundle agent subtest(user) { classes: "invalid" not => regcmp("[a-z][a-z][a-z][a-z]","$(user)"); reports: !invalid:: "User name $(user) is valid at 4 letters"; invalid:: "User name $(user) is invalid"; } cfengine-3.24.2/examples/software_update_version_yum.cf0000644000000000000000000000351015010704253023335 0ustar00rootroot00000000000000# # Schedule software update for yum-based distributions (e.g. RedHat, CentOS) # Will only update to the given package_version assumed to be found in the yum repository. # If installed version is the same as package_version or newer, no action is taken. # body common control { bundlesequence => { "system_software" }; } bundle agent system_software { classes: "update_hosts" expression => "host1|host2"; "update_schedule" expression => "Day27.Hr02.Min00_05"; packages: update_hosts.update_schedule:: "bash" comment => "Make sure bash package is updated to right version", handle => "package_bash_update", package_version => "3.2-32.el5", package_architectures => { "x86_64" }, package_policy => "addupdate", package_select => ">=", package_method => yum_version; } body package_method yum_version { package_changes => "bulk"; package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; package_patch_list_command => "/usr/bin/yum check-update"; package_list_name_regex => "^(\S+?)\s\S+?\s\S+$"; package_list_version_regex => "^\S+?\s(\S+?)\s\S+$"; package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$"; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version).$(arch)"; package_patch_installed_regex => "^\s.*"; package_patch_name_regex => "([^.]+).*"; package_patch_version_regex => "[^\s]\s+([^\s]+).*"; package_patch_arch_regex => "[^.]+\.([^\s]+).*"; package_add_command => "/usr/bin/yum -y install"; package_update_command => "/usr/bin/yum -y update"; package_delete_command => "/bin/rpm -e --nodeps --allmatches"; package_verify_command => "/bin/rpm -V"; } cfengine-3.24.2/examples/cf_version_after.cf0000644000000000000000000000066115010704253021024 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This will be skipped on older or equal versions" if => cf_version_after("3.15"); "This will be skipped on newer versions" unless => cf_version_after("3.15"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This will be skipped on older or equal versions #@ ``` #+end_src cfengine-3.24.2/examples/getmacaddress.cf0000644000000000000000000000272115010704253020313 0ustar00rootroot00000000000000 body common control { bundlesequence => { "get_mac_adr" }; } ############################################################## bundle agent get_mac_adr { vars: linux:: "interface" string => execresult("/sbin/ifconfig eth0","noshell"); solaris:: "interface" string => execresult("/usr/sbin/ifconfig bge0","noshell"); freebsd:: "interface" string => execresult("/sbin/ifconfig le0","noshell"); darwin:: "interface" string => execresult("/sbin/ifconfig en0","noshell"); classes: linux:: "ok" expression => regextract( ".*HWaddr ([^\s]+).*(\n.*)*", "$(interface)", "mac" ); solaris:: "ok" expression => regextract( ".*ether ([^\s]+).*(\n.*)*", "$(interface)", "mac" ); freebsd:: "ok" expression => regextract( ".*ether ([^\s]+).*(\n.*)*", "$(interface)", "mac" ); darwin:: "ok" expression => regextract( "(?s).*ether ([^\s]+).*(\n.*)*", "$(interface)", "mac" ); reports: ok:: "MAC address is $(mac[1])"; } cfengine-3.24.2/examples/namespace_special_var_exception.cf0000644000000000000000000000163615010704253024073 0ustar00rootroot00000000000000bundle agent __main__ { methods: "special_variables_example:demo"; } body file control { namespace => "special_variables_example"; } bundle agent demo { reports: "Special Variables live in the default namespace but don't have to be fully qualified when referenced ..."; "In $(this.namespace):$(this.bundle) $(const.dollar)(sys.cf_version_major) == $(sys.cf_version_major)"; "In $(this.namespace):$(this.bundle) $(default:const.dollar)(default:sys.cf_version_major) == $(default:sys.cf_version_major)"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: Special Variables live in the default namespace but don't have to be fully qualified when referenced ... #@ R: In special_variables_example:demo $(sys.cf_version_major) == 3 #@ R: In special_variables_example:demo $(default:sys.cf_version_major) == 3 #@ ``` #+end_src cfengine-3.24.2/examples/accessedbefore.cf0000644000000000000000000000325415010704253020444 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ touch -a -t '200102031234.56' /tmp/earlier #@ touch -a -t '200202031234.56' /tmp/later #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "do_it" expression => accessedbefore("/tmp/earlier","/tmp/later"); reports: do_it:: "The secret changes have been accessed after the reference time"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The secret changes have been accessed after the reference time #@ ``` #+end_src cfengine-3.24.2/examples/getuid.cf0000644000000000000000000000251315010704253016765 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "uid" int => getuid("root"); reports: "root's uid is $(uid)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: root's uid is 0 #@ ``` #+end_src cfengine-3.24.2/examples/getvalues.cf0000644000000000000000000000371615010704253017511 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "v[index_1]" string => "value_1"; "v[index_2]" string => "value_2"; "values" slist => getvalues("v"); "values_sorted" slist => sort(values, lex); # works with data containers too "d" data => parsejson('{ "k": [ 1, 2, 3, "a", "b", "c" ] }'); "cvalues" slist => getvalues("d[k]"); "cvalues_sorted" slist => sort(cvalues, lex); reports: "Found values: $(values_sorted)"; "Found container values: $(cvalues_sorted)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found values: value_1 #@ R: Found values: value_2 #@ R: Found container values: 1 #@ R: Found container values: 2 #@ R: Found container values: 3 #@ R: Found container values: a #@ R: Found container values: b #@ R: Found container values: c #@ ``` #+end_src cfengine-3.24.2/examples/getregistry.cf0000644000000000000000000000234715010704253020061 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "reg" }; } bundle agent reg { vars: windows:: "value" string => registryvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\Cfengine","value3"); reports: "Value extracted: $(value)"; } cfengine-3.24.2/examples/package_msi_version.cf0000644000000000000000000000370015010704253021513 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # MSI package management using version criteria # body common control { bundlesequence => { "packages" }; } ############################################# bundle agent packages { vars: "match_package" slist => { "7zip" }; packages: "$(match_package)" package_policy => "update", package_select => ">=", package_architectures => { "x86_64" }, package_version => "3.00", package_method => msi_vmatch; } ############################################# body package_method msi_vmatch { package_changes => "individual"; package_file_repositories => { "$(sys.workdir)\software_updates\windows", "s:\su" }; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version)-$(arch).msi"; package_add_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; package_update_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; package_delete_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /x"; } cfengine-3.24.2/examples/select_mode.cf0000644000000000000000000000325115010704253017767 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Searching for permissions # ####################################################### body common control { bundlesequence => { "example" }; } ############################################ bundle agent example { files: "/home/mark/tmp/test_from" file_select => by_modes, transformer => "/bin/echo DETECTED $(this.promiser)", depth_search => recurse("inf"); } ############################################ body file_select by_modes { search_mode => { "711" , "666" }; file_result => "mode"; } ############################################ body depth_search recurse(d) { depth => "$(d)"; } cfengine-3.24.2/examples/missing_ok.cf0000644000000000000000000000672115010704253017653 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # This example shows how to use the missing_ok attribute in copy from bodies. If # the source file is missing, the promise will be seen to be a promise kept # instead of a failure. The exception is that a remote copy that fails to make a # connection to the remote server will still be seen as a promise failure. #+begin_src cfengine3 bundle agent main { files: "/tmp/copied_from_missing_ok" copy_from => missing_ok( "/var/cfengine/masterfiles/missing" ), classes => results("bundle", "copy_from_missing_ok"); reports: "$(with)" with => string_mustache( "{{%-top-}}", sort( classesmatching( "copy_from_.*" ), lex)); } body copy_from missing_ok( file_path ) { source => "$(file_path)"; missing_ok => "true"; # Run with these classes to try remote copies remote_copy_self:: servers => { "127.0.0.1" }; remote_copy_policy_hub:: servers => { $(sys.policy_hub) }; } body classes results(scope, class_prefix) { scope => "$(scope)"; promise_kept => { "$(class_prefix)_reached", "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_reached", "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_failed" }; repair_denied => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_denied" }; repair_timeout => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_timeout" }; } #+end_src #@ In the above example `/tmp/copied_from_missing_ok` promises to be a copy of the local file #@ `/var/cfengine/masterfiles/missing`. In the `missing_ok` `copy_from` body #@ `missing_ok` is set to true. This causes the promise to be considered kept if #@ the source file is missing. The `results` classes body is used to define bundle #@ scoped classes prefixed with `copy_from_missing_ok`. The `reports` promise #@ outputs a sorted list of the classes defined starting with `copy_from_`. #+begin_src example_output #@ ``` #@ R: [ #@ "copy_from_missing_ok_kept", #@ "copy_from_missing_ok_reached" #@ ] #@ ``` #+end_src #@ We can see in the output that the class defined for copying a local file that #@ does not exist is seen to be a promise kept. cfengine-3.24.2/examples/defaults3.cf0000644000000000000000000000100015010704253017364 0ustar00rootroot00000000000000 body common control { bundlesequence => { "main" }; } bundle agent main { methods: "example" usebundle => test("one","x","","$(four)"); } bundle agent test(a,b,c,d) { defaults: "a" string => "default a", if_match_regex => ""; "b" string => "default b", if_match_regex => "x"; "c" string => "default c", if_match_regex => ""; "d" string => "default d", if_match_regex => "\$\([a-zA-Z0-9_.]+\)"; reports: "a = '$(a)', b = '$(b)', c = '$(c)' d = '$(d)'"; } cfengine-3.24.2/examples/every.cf0000644000000000000000000000765415010704253016651 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { classes: "every_dot_star" expression => every(".*", test); "every_dot" expression => every(".", test); "every_number" expression => every("[0-9]", test); "every2_dot_star" expression => every(".*", test2); "every2_dot" expression => every(".", test2); "every2_number" expression => every("[0-9]", test2); vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "test2" data => parsejson('[1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three",]'); reports: "The test list is $(test)"; every_dot_star:: "every() test passed: every element matches '.*'"; !every_dot_star:: "every() test failed: not every element matches '.*'"; every_number:: "every() test failed: every element matches '[0-9]'"; !every_number:: "every() test passed: not every element matches '[0-9]'"; every_dot:: "every() test failed: every element matches '.'"; !every_dot:: "every() test passed: not every element matches '.'"; "The test2 list is $(test2)"; every2_dot_star:: "every() test2 passed: every element matches '.*'"; !every2_dot_star:: "every() test2 failed: not every element matches '.*'"; every2_number:: "every() test2 failed: every element matches '[0-9]'"; !every2_number:: "every() test2 passed: not every element matches '[0-9]'"; every2_dot:: "every() test2 failed: every element matches '.'"; !every2_dot:: "every() test2 passed: not every element matches '.'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The test list is 1 #@ R: The test list is 2 #@ R: The test list is 3 #@ R: The test list is one #@ R: The test list is two #@ R: The test list is three #@ R: The test list is long string #@ R: The test list is four #@ R: The test list is fix #@ R: The test list is six #@ R: every() test passed: every element matches '.*' #@ R: every() test passed: not every element matches '[0-9]' #@ R: every() test passed: not every element matches '.' #@ R: The test2 list is 1 #@ R: The test2 list is 2 #@ R: The test2 list is 3 #@ R: The test2 list is one #@ R: The test2 list is two #@ R: The test2 list is three #@ R: The test2 list is long string #@ R: The test2 list is four #@ R: The test2 list is fix #@ R: The test2 list is six #@ R: every() test2 passed: every element matches '.*' #@ R: every() test2 passed: not every element matches '[0-9]' #@ R: every() test2 passed: not every element matches '.' #@ ``` #+end_src cfengine-3.24.2/examples/namespace_var_meta2.cf0000644000000000000000000000054615010704253021404 0ustar00rootroot00000000000000 body file control { namespace => "fred"; } bundle agent example { vars: "bundle_version" string => "4.5.6"; meta: "bundle_version" string => "1.2.3"; "works_with_cfengine" string => "3.4.0"; reports: "Not a local variable: $(bundle_version)"; "Meta data (variable): $(example_meta.bundle_version)"; } cfengine-3.24.2/examples/getindices_and_values.cf0000644000000000000000000000265015010704253022025 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ####################################################### bundle agent example { vars: "v[index_1]" string => "value_1"; "v[index_2]" string => "value_2"; "x" slist => getindices("v"); "y" slist => getvalues("v"); reports: "All indices:"; " Found index: $(x) with value \"$(v[$(x)])\""; "All values:"; " Found value: $(y)"; } cfengine-3.24.2/examples/readintarray.cf0000644000000000000000000000502315010704253020170 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo 1: 5:7:21:13 > /tmp/readintarray.txt #@ echo 2:19:8:14:14 >> /tmp/readintarray.txt #@ echo 3:45:1:78:22 >> /tmp/readintarray.txt #@ echo 4:64:2:98:99 >> /tmp/readintarray.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main { vars: "lines" int => readintarray("array_name", "/tmp/readintarray.txt", "#[^\n]*", ":", 10, 4000); reports: "array_name contains $(lines) keys$(const.n)$(with)" with => string_mustache("{{%-top-}}", "array_name"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: array_name contains 4 keys #@ { #@ "1": { #@ "0": "1", #@ "1": "5", #@ "2": "7", #@ "3": "21", #@ "4": "13" #@ }, #@ "2": { #@ "0": "2", #@ "1": "19", #@ "2": "8", #@ "3": "14", #@ "4": "14" #@ }, #@ "3": { #@ "0": "3", #@ "1": "45", #@ "2": "1", #@ "3": "78", #@ "4": "22" #@ }, #@ "4": { #@ "0": "4", #@ "1": "64", #@ "2": "2", #@ "3": "98", #@ "4": "99" #@ } #@ } #@ ``` #+end_src cfengine-3.24.2/examples/ldap.cf0000644000000000000000000000501015010704253016417 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # body common control { bundlesequence => { "ldap" , "followup"}; } ################################################################################################### # NOTE!! relying on LDAP or other network data without validation is EXTREMELY dangerous. # You could destroy a system by assuming that the service will respond with a # sensible result. Cfengine does not recommend reliance on network services in configuration. ################################################################################################### bundle agent ldap { vars: # Get the first matching value for "uid" "value" string => ldapvalue("ldap://eternity.iu.hio.no","dc=cfengine,dc=com","(sn=User)","uid","subtree","none"); # Geta all matching values for "uid" - should be a single record match "list" slist => ldaplist("ldap://eternity.iu.hio.no","dc=cfengine,dc=com","(sn=User)","uid","subtree","none"); classes: "gotdata" expression => ldaparray("myarray","ldap://eternity.iu.hio.no","dc=cfengine,dc=com","(uid=mark)","subtree","none"); "found" expression => regldap("ldap://eternity.iu.hio.no","dc=cfengine,dc=com","(sn=User)","uid","subtree","jon.*","none"); reports: "LDAP VALUE $(value) found"; "LDAP LIST VALUE $(list)"; gotdata:: "Found specific entry data ...$(ldap.myarray[uid]),$(ldap.myarray[gecos]), etc"; found:: "Matched regex"; } bundle agent followup { reports: "Different bundle ...$(ldap.myarray[uid]),$(ldap.myarray[gecos]), etc"; } cfengine-3.24.2/examples/edit_insert_lines.cf0000644000000000000000000000364715010704253021220 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Insert a number of lines # ####################################################### body common control { any:: bundlesequence => { "insert" }; } ####################################################### bundle agent insert { vars: "v" string => " One potato Two potato Three potatoe Four "; files: "/tmp/test_insert" create => "true", edit_line => Insert("$(insert.v)"), edit_defaults => empty; } ####################################################### # For the library ####################################################### bundle edit_line Insert(name) { insert_lines: "Begin$(const.n)$(name)$(const.n)End"; } ####################################################### body edit_defaults empty { empty_file_before_editing => "false"; } cfengine-3.24.2/examples/hostrange.cf0000644000000000000000000000545115010704253017502 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent main { vars: "range" string => "1-32"; "hostname_f" string => execresult( "hostname -f", useshell); "hostname_s" string => execresult( "hostname -s", useshell); "hostname" string => execresult( "hostname", useshell); classes: "hostgroup_alpha_no_leading_zeros" expression => hostrange("host", $(range) ); "hostgroup_alpha_leading_zeros" expression => hostrange("host", "00$(range)" ); "hostgroup_alpha_UPPERCASE_prefix" expression => hostrange("HOST", "0$(range)" ); reports: "sys.fqhost = '$(sys.fqhost)'"; "sys.uqhost = '$(sys.uqhost)'"; "hostname -f = '$(hostname_f)'"; "hostname -s = '$(hostname_s)'"; "hostname = '$(hostname)'"; hostgroup_alpha_no_leading_zeros:: "This host is within the alpha host group range (host$(range))"; hostgroup_alpha_leading_zeros:: "This host is within the alpha host group range (host00$(range)) (NOTE: Leading zeros and prefix capitalization is insignificant)"; hostgroup_alpha_UPPERCASE_prefix:: "This host is within the alpha host group range (HOST0$(range)) (NOTE: Leading zeros and prefix capitalization is insignificant)"; } #+end_src ############################################################################### #+begin_src static_example_output #@ ``` #@ R: sys.fqhost = 'host001.example.com' #@ R: sys.uqhost = 'host001' #@ R: hostname -f = 'HOST001.example.com' #@ R: hostname -s = 'HOST001' #@ R: hostname = 'HOST001' #@ R: This host is within the alpha host group range (host1-32) #@ R: This host is within the alpha host group range (host001-32) (NOTE: Leading zeros and prefix capitalization is insignificant) #@ R: This host is within the alpha host group range (HOST01-32) (NOTE: Leading zeros and prefix capitalization is insignificant) #@ ``` #+end_src cfengine-3.24.2/examples/server_callback.cf0000644000000000000000000000514715010704253020634 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test copy from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-v] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { vars: } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; call_collect_interval => "5"; } ######################################################### bundle server access_rules() { access: # On the policy hub am_policy_hub:: "collect_calls" comment => "Enable call-collect report collection for the specific client", resource_type => "query", admit => { "1.2.3.4" }; # On the isolated clients in the field any:: "delta" comment => "Grant access to cfengine hub to collect report deltas", resource_type => "query", admit => { "$(sys.policy_hub)" }; "full" comment => "Grant access to cfengine hub to collect full report dump", resource_type => "query", admit => { "$(sys.policy_hub)" }; } cfengine-3.24.2/examples/edit.empty_before_use.cf0000644000000000000000000000373015010704253021766 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { files: "/tmp/example-edit.empty_before_use.one" create => "true"; "/tmp/example-edit.empty_before_use.two" create => "true"; "/tmp/example-edit.empty_before_use.one" edit_line => show_edit_empty_before_use, edit_defaults => my_empty_file_before_editing; "/tmp/example-edit.empty_before_use.two" edit_line => show_edit_empty_before_use; } bundle edit_line show_edit_empty_before_use { reports: "$(with)" with => concat( "The promise to edit '$(edit.filename)' was ", "instructed to ignore any pre-existing content." ), if => strcmp( "true", "$(edit.empty_before_use)"); "$(with)" with => concat( "The promise to edit '$(edit.filename)' was ", "not instructed to ignore any pre-existing content."), if => strcmp( "false", "$(edit.empty_before_use)"); "$(with)" with => concat ( "This version of CFEngine does not know if the", "edit operation is expected to ignore pre-existing ", "content the variable 'edit.empty_before_use' does ", "not exist"), unless => isvariable ( "edit.empty_before_use" ); } body edit_defaults my_empty_file_before_editing { empty_file_before_editing => "true"; # The variable # edit.empty_before_use allows this # to be known from within an # edit_line bundle. } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The promise to edit '/tmp/example-edit.empty_before_use.one' was instructed to ignore any pre-existing content. #@ R: The promise to edit '/tmp/example-edit.empty_before_use.two' was not instructed to ignore any pre-existing content. #@ ``` #+end_src cfengine-3.24.2/examples/getusers.cf0000644000000000000000000000443315010704253017350 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: # The getusers function takes two filtering arguments: exclude_names and # exclude_ids, both a comma separated list of usernames and user IDs # respectively. # To get users with a uid 1000 and greater we generate a list of uids from # 0 to 999 and convert it into a comma separated string used to filter the # list of users. "users_with_uid_gt_999" slist => getusers( "", join( ",", expandrange( "[0-999]", 1 ) ) ); # Here we get a list of users except usernames nfsnobody and vagrant as # well as any users with uid 8 or 9 "users_except_nfsnobody_and_vagrant_and_uid_8_and_9" slist => getusers( "nfsnobody,vagrant", "8,9" ); # Here we get a list of all users by not filtering any "allusers" slist => getusers("",""); "root_list" slist => { "root" }; # this will get just the root users out of the full user list "justroot" slist => intersection(allusers, root_list); reports: "Found just the root user: $(justroot)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found just the root user: root #@ ``` #+end_src cfengine-3.24.2/examples/update.cf0000644000000000000000000000624415010704253016773 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #cop update,example #cop What should a failsafe and update file contain?,example # Minimum failsafe body common control { bundlesequence => { "update" }; } bundle agent update { vars: "master_location" string => "$(sys.workdir)/masterfiles"; "policy_server" string => readfile("$(sys.workdir)/policy_server.dat",40), comment => "IP address to locate your policy host."; classes: "policy_host" or => { classmatch(canonify("ipv4_$(policy_server)")), classmatch(canonify("$(policy_server)")) }, comment => "Define the ip identity of the policy source host"; "have_ppkeys" expression => fileexists("$(sys.workdir)/ppkeys/localhost.pub"); "nofile" expression => fileexists("$(sys.workdir)/policy_server.dat"); commands: !have_ppkeys:: "/var/cfengine/bin/cf-key"; files: "/var/cfengine/inputs" handle => "update_policy", perms => u_p("600"), copy_from => u_scp("$(master_location)"), depth_search => u_recurse("inf"), action => immediate; processes: any:: "cf-execd" restart_class => "start_exec"; policy_host:: "cf-serverd" restart_class => "start_server"; commands: start_exec:: "$(sys.workdir)/bin/cf-execd" action => logme("executor"); start_server:: "$(sys.workdir)/bin/cf-serverd" action => logme("server"); reports: bootstrap_mode.policy_host:: "I am the policy host - i.e. with ipv4 address $(policy_server)"; } ############################################ body action logme(x) { log_repaired => "stdout"; log_string => " -> Started the $(x) (success)"; } ############################################ body perms u_p(p) { mode => "$(p)"; } ############################################# body copy_from u_scp(from) { source => "$(from)"; compare => "digest"; trustkey => "true"; !policy_host:: servers => { "$(policy_server)" }; } ######################################################### body action immediate { ifelapsed => "1"; } ############################################ body depth_search u_recurse(d) { depth => "$(d)"; } cfengine-3.24.2/examples/remove_deadlinks.cf0000644000000000000000000000333015010704253021015 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Test dead link removal # ####################################################### body common control { bundlesequence => { "example" }; } ############################################ bundle agent example { files: "/home/mark/tmp/test_to" -> "someone" depth_search => recurse("inf"), perms => modestuff, action => tell_me; } ############################################ body depth_search recurse(d) { rmdeadlinks => "true"; depth => "$(d)"; } ############################################ body perms modestuff { mode => "o-w"; } ############################################ body action tell_me { report_level => "inform"; } cfengine-3.24.2/examples/package_yum.cf0000644000000000000000000000275415010704253020000 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Package management # body common control { bundlesequence => { "packages" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################# bundle agent packages { vars: # Test the simplest case -- leave everything to the yum smart manager "match_package" slist => { "apache2", "apache2-mod_php5", "apache2-prefork", "php5" }; packages: "$(match_package)" package_policy => "add", package_method => yum; } cfengine-3.24.2/examples/bundle_return_values.cf0000644000000000000000000000100315010704253021724 0ustar00rootroot00000000000000 body common control { bundlesequence => { "example" }; } bundle agent example { methods: "any" usebundle => child, useresult => "my_return_var"; reports: "My return was: \"$(my_return_var[1])\" and \"$(my_return_var[2])\""; } bundle agent child { reports: # Map these indices into the useresult namespace "this is a return value" bundle_return_value_index => "1"; "this is another return value" bundle_return_value_index => "2"; } cfengine-3.24.2/examples/exec_in_sequence.cf0000644000000000000000000000371215010704253021010 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test execution # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { vars: "size" int => "46k"; "rand" int => randomint("33","$(size)"); commands: "/bin/echo" args => "Hello world - $(size)/$(rand)", contain => standard, classes => cdefine("followup","alert"); followup:: "/bin/ls" contain => standard; reports: alert:: "What happened?"; } ###################################################################### body contain standard { exec_owner => "mark"; useshell => "useshell"; } ###################################################################### body classes cdefine(class,alert) { promise_repaired => { "$(class)" }; repair_failed => { "$(alert)" }; } cfengine-3.24.2/examples/failedcommand.cf0000644000000000000000000000101515010704253020263 0ustar00rootroot00000000000000body common control { bundlesequence => { "cmdtest" }; } bundle agent cmdtest { files: "/tmp/test" copy_from => copy("/etc/passwd"); "/tmp/test" classes => example, transformer => "/bin/grep -q lkajfo999999 $(this.promiser)"; reports: hasfailed:: "The files-promise failed!"; } body classes example { failed_returncodes => { "1" }; repair_failed => { "hasfailed" }; } body copy_from copy(file) { source => "$(file)"; } cfengine-3.24.2/examples/bundlesmatching.cf0000644000000000000000000000462415010704253020660 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { mefirst }; } bundle common g { vars: # Here we find all bundles in the default namespace whos name starts with # run. "todo" slist => bundlesmatching("default:run.*"); } bundle agent mefirst { methods: # Here, we actuate each of the bundles that were found using # bundlesmatching in bundle common g. "" usebundle => $(g.todo); } bundle agent run_deprecated { meta: # This bundle is tagged with deprecated "tags" slist => { "deprecated" }; } bundle agent run_123_456 { vars: # Here we find all bundles in our policy. "bundles" slist => bundlesmatching(".*"); # Here we find all the bundles that are tagged as deprecated. "deprecated_bundles" slist => bundlesmatching(".*", "deprecated"); # Here we find all bundles that match 891 (none will). "no_bundles" slist => bundlesmatching("891"); reports: # Here we report on our findings: "bundles = $(bundles)"; "deprecated bundles = $(deprecated_bundles)"; "no bundles = $(no_bundles)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: bundles = default:run_123_456 #@ R: bundles = default:run_deprecated #@ R: bundles = default:mefirst #@ R: bundles = default:g #@ R: deprecated bundles = default:run_deprecated #@ ``` #+end_src cfengine-3.24.2/examples/service_disable.cf0000644000000000000000000000247215010704253020633 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "winservice" }; } ########################################################### bundle agent winservice { vars: "bad_services" slist => { "Alerter", "ClipSrv" }; services: windows:: "$(bad_services)" service_policy => "disable", comment => "Disable services that create security issues"; } cfengine-3.24.2/examples/acl.cf0000644000000000000000000000343115010704253016243 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "acls" }; } ######################################### bundle agent acls { files: "/media/flash/acl/test_dir" depth_search => include_base, acl => template; } ######################################### body acl template { acl_method => "overwrite"; acl_type => "posix"; acl_default => "access"; aces => { "user:*:r(wwx),-r:allow", "group:*:+rw:allow", "mask:x:allow", "all:r"}; } ######################################### body acl win { acl_method => "overwrite"; acl_type => "ntfs"; acl_default => "nochange"; aces => { "user:Administrator:rw", "group:Bad:rwx(Dpo):deny" }; } ######################################### body depth_search include_base { include_basedir => "true"; } cfengine-3.24.2/examples/abort.cf0000644000000000000000000000327215010704253016616 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #[%+%] body common control { bundlesequence => { "example" }; } body agent control { abortbundleclasses => { "invalid" }; } #[%-%] ########################################### #[%+%] bundle agent example { vars: #"userlist" slist => { "mark", "john" }; # contains all valid entries "userlist" slist => { "mark", "john", "thomas" }; # contains one invalid entry classes: "invalid" not => regcmp("[a-z][a-z][a-z][a-z]","$(userlist)"); # The class 'invalid' is set if the user name does not # contain exactly four un-capitalized letters (bundle # execution will be aborted if set) reports: !invalid:: "User name $(userlist) is valid at 4 letters"; } cfengine-3.24.2/examples/server_flatcopy_localhost.cf0000644000000000000000000000651715010704253022773 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test copy from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-d2] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { files: "/home/mark/tmp/testflatcopy" comment => "test copy promise", copy_from => mycopy("/home/mark/LapTop/words","127.0.0.1"), perms => system, depth_search => recurse("inf"), classes => satisfied("copy_ok"); "/home/mark/tmp/testcopy/single_file" comment => "test copy promise", copy_from => mycopy("/home/mark/LapTop/Cfengine3/trunk/README","127.0.0.1"), perms => system; reports: copy_ok:: "Files were copied.."; } ######################################################### body perms system { mode => "0644"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } ######################################################### body copy_from mycopy(from,server) { source => "$(from)"; servers => { "$(server)" }; compare => "digest"; verify => "true"; copy_backup => "true"; #/false/timestamp purge => "false"; type_check => "true"; force_ipv4 => "true"; trustkey => "true"; collapse_destination_dir => "true"; } ######################################################### body classes satisfied(x) { promise_repaired => { "$(x)" }; persist_time => "0"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "/home/mark/LapTop" admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/hostswithclass.cf0000644000000000000000000000056015010704253020566 0ustar00rootroot00000000000000body common control { bundlesequence => { "example" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent example { vars: am_policy_hub:: "host_list" slist => hostswithclass( "debian", "name" ); files: am_policy_hub:: "/tmp/master_config.cfg" edit_line => insert_lines("host=$(host_list)"), create => "true"; } cfengine-3.24.2/examples/string_length.cf0000644000000000000000000000257315010704253020361 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "length" int => string_length("abc"); # will contain "3" reports: "length of string abc = $(length)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: length of string abc = 3 #@ ``` #+end_src cfengine-3.24.2/examples/files-content-with.cf0000644000000000000000000000076315010704253021234 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ test -e /tmp/hello && rm /tmp/hello #@ ``` #+end_src #+begin_src cfengine3 body agent control { inform => "true"; } bundle agent __main__ { files: "/tmp/hello" content => "Output from stat: $(with)", with => execresult( 'stat -c "%U" /', "useshell" ); } #+end_src #+begin_src example_output #@ ``` #@ info: Created file '/tmp/hello', mode 0600 #@ info: Updated file '/tmp/hello' with content 'Output from stat: root' #@ ``` #+end_src cfengine-3.24.2/examples/win_registry.cf0000644000000000000000000000503215010704253020230 0ustar00rootroot00000000000000######################################################################### # # win_registry.cf - Windows Registry Management # ######################################################################### bundle agent win_registry { vars: "cache_keys" slist => { "HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS" }; "reg_create" slist => { "value1,REG_SZ,this is the first value...", "value2,REG_SZ,...and this is the second!" }; "reg_delete" slist => { "value1" }; methods: # 1) Cfengine can cache and restore any part of the registry # "any" usebundle => registry_cache("@(win_registry.cache_keys)"); # "any" usebundle => registry_restore("@(win_registry.cache_keys)"); # 2) Registry settings may also be explicitly defined/deleted in policy # "any" usebundle => registry_define("HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\Cfengine", "@(win_registry.reg_create)"); # "any" usebundle => registry_delete("HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\Cfengine", "@(win_registry.reg_delete)"); } ######################################################################### bundle agent registry_cache(keys) { databases: windows:: "$(keys)" database_operation => "cache", database_type => "ms_registry", comment => "Save correct registry settings"; } ######################################################################### bundle agent registry_restore(keys) { databases: windows:: "$(keys)" database_operation => "restore", database_type => "ms_registry", comment => "Make sure correct registry settings are set, according to cached version"; } ######################################################################### bundle agent registry_define(key, contents) { databases: windows:: "$(key)" database_operation => "create", database_rows => { "$(contents)" } , database_type => "ms_registry", comment => "Explicitly define important registry settings"; } ######################################################################### bundle agent registry_delete(key, values) { databases: windows:: "$(key)" database_operation => "delete", database_columns => { "@(values)" } , database_type => "ms_registry", comment => "Remove unwanted registry values"; } cfengine-3.24.2/examples/readlist.cf0000644000000000000000000000241115010704253017310 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "mylist" ilist => { readintlist("/tmp/listofint","#.*","[\n]",10,400) }; reports: "List entry: $(mylist)"; } cfengine-3.24.2/examples/disable_and_rotate_files.cf0000644000000000000000000000324515010704253022474 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Disabling / rotating files # ####################################################### body common control { bundlesequence => { "example" }; } ############################################ bundle agent example { files: "/home/mark/tmp/test_create" comment => "this rule does something", rename => disable; "/home/mark/tmp/rotateme" rename => rotate("4"); } ############################################ body rename disable { disable => "true"; disable_suffix => "_blownaway"; } ############################################ body rename rotate(level) { rotate => "$(level)"; } cfengine-3.24.2/examples/peerleader.cf0000644000000000000000000000606715010704253017624 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo alpha > /tmp/cfe_hostlist #@ echo beta >> /tmp/cfe_hostlist #@ echo gamma >> /tmp/cfe_hostlist #@ echo "Set HOSTNAME appropriately beforehand" #@ touch $CFENGINE_TEST_OVERRIDE_WORKDIR/inputs/promises.cf # to enable cf-promises to run #@ bash -c "${CF_PROMISES} --show-vars=sys.fqhost | grep fqhost | awk '{print \$2}' | tr 'A-Z' 'a-z' 2>&1 >> /tmp/cfe_hostlist" #@ echo "Delta Delta Delta may I help ya help ya help ya" #@ echo delta1 >> /tmp/cfe_hostlist #@ echo delta2 >> /tmp/cfe_hostlist #@ echo delta3 >> /tmp/cfe_hostlist #@ echo may1.I.help.ya >> /tmp/cfe_hostlist #@ echo may2.I.help.ya >> /tmp/cfe_hostlist #@ echo may3.I.help.ya >> /tmp/cfe_hostlist #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "peers" }; } bundle agent peers { vars: "mygroup" slist => peers("/tmp/cfe_hostlist","#.*",4); "myleader" string => peerleader("/tmp/cfe_hostlist","#.*",4); "all_leaders" slist => peerleaders("/tmp/cfe_hostlist","#.*",4); reports: # note that the current host name is fourth in the host list, so # its peer group is the first 4-host group, minus the host itself. "/tmp/cfe_hostlist mypeer $(mygroup)"; # note that the current host name is fourth in the host list, so # the peer leader is "alpha" "/tmp/cfe_hostlist myleader $(myleader)"; "/tmp/cfe_hostlist another leader $(all_leaders)"; "Unable to find my fully qualified hostname $(sys.fqhost) in /tmp/cfe_hostlist. Can't determine peers." if => not( regline( $(sys.fqhost), "/tmp/cfe_hostlist" ) ); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /tmp/cfe_hostlist mypeer alpha #@ R: /tmp/cfe_hostlist mypeer beta #@ R: /tmp/cfe_hostlist mypeer gamma #@ R: /tmp/cfe_hostlist myleader alpha #@ R: /tmp/cfe_hostlist another leader alpha #@ R: /tmp/cfe_hostlist another leader delta1 #@ R: /tmp/cfe_hostlist another leader may2.I.help.ya #@ ``` #+end_src cfengine-3.24.2/examples/readintlist.cf0000644000000000000000000000201115010704253020017 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ printf "one\ntwo\nthree\n" > /tmp/list.txt #@ printf "1\n2\n3\n" >> /tmp/list.txt #@ printf "1.0\n2.0\n3.0" >> /tmp/list.txt #@ ``` #+end_src #+begin_src cfengine3 bundle agent example_readintlist # @brief Example showing function return types { vars: "my_list_of_integers" ilist => readintlist( "/tmp/list.txt", # File to read "^(\D+)|(\d+[^\n]+)", # Ignore any lines that are not integers "\n", # Split on newlines inf, # Maximum number of entries inf); # Maximum number of bytes to read reports: "my_list_of_integers includes '$(my_list_of_integers)'"; } bundle agent __main__ { methods: "example_readintlist"; } #+end_src #+begin_src example_output #@ ``` #@ R: my_list_of_integers includes '1' #@ R: my_list_of_integers includes '2' #@ R: my_list_of_integers includes '3' #@ ``` #+end_src cfengine-3.24.2/examples/mustache_sections_inverted.cf0000644000000000000000000000065615010704253023132 0ustar00rootroot00000000000000# Example showing how inverted sections are rendered #+begin_src cfengine3 bundle agent main { reports: "CFEngine $(with)" with => string_mustache("{{^classes.enterprise_edition}}Community{{/classes.enterprise_edition}}{{#classes.enterprise_edition}}Enterprise{{/classes.example}}", datastate()); } #+end_src #+begin_src example_output #@ ``` #@ R: CFEngine Community #@ ``` #+end_src cfengine-3.24.2/examples/edit_insert_lines_silly.cf0000644000000000000000000000364515010704253022432 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Insert a number of lines # ####################################################### body common control { any:: bundlesequence => { "insert" }; } ####################################################### bundle agent insert { vars: "v" slist => { "One potato", "Two potato", "Three potatoe", "Four" }; files: "/tmp/test_insert" create => "true", edit_line => Insert("@(insert.v)"); # edit_defaults => empty; } ####################################################### # For the library ####################################################### bundle edit_line Insert(name) { insert_lines: "$(name)"; } ####################################################### body edit_defaults empty { empty_file_before_editing => "true"; } cfengine-3.24.2/examples/acl_ntfs.cf0000644000000000000000000000115215010704253017273 0ustar00rootroot00000000000000body common control { inputs => { "$(sys.libdir)/stdlib.cf" }; bundlesequence => { "example" }; } ### bundle agent example { vars: "acl_secret_dir" slist => { "user:Administrator:rwx:allow", "group:Administrators:rx:allow" }; "acl_secret_file" slist => { "user:Administrator:rw:allow" }; files: windows:: "C:\Secret" acl => ntfs( "@(acl_secret_dir)" ), depth_search => include_base, perms => owner( "Administrator" ); "C:\Secret\file.txt" acl => ntfs( "@(acl_secret_file)" ), perms => owner( "Administrator" ); } cfengine-3.24.2/examples/files_auto_define.cf0000644000000000000000000000360015010704253021146 0ustar00rootroot00000000000000# Example illustrating how body agent control files_auto_define works. #+begin_src prep #@ ``` #@ # Ensure that the files used in the example do not exist before running the example #@ rm -f /tmp/example_files_auto_define.txt #@ rm -f /tmp/source_file.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body agent control { inform => "true"; # So that we can easily see class definition files_auto_define => { ".*" }; # Trigger for any copied file } bundle agent main { files: "/tmp/source_file.txt" content => "Hello World!"; "/tmp/example_files_auto_define.txt" copy_from => local_dcp( "/tmp/source_file.txt" ); reports: "Defined '$(with)', the canonified form of 'auto_/tmp/example_files_auto_define.txt'" with => canonify( "auto_/tmp/example_files_auto_define.txt"), if => canonify( "auto_/tmp/example_files_auto_define.txt"); } # Copied from the standard library to make self-contained. body copy_from local_dcp(from) { source => "$(from)"; compare => "digest"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ info: Created file '/tmp/source_file.txt', mode 0600 #@ info: Updated file '/tmp/source_file.txt' with content 'Hello World!' #@ info: Copied file '/tmp/source_file.txt' to '/tmp/example_files_auto_define.txt.cfnew' (mode '600') #@ info: Moved '/tmp/example_files_auto_define.txt.cfnew' to '/tmp/example_files_auto_define.txt' #@ info: Updated file '/tmp/example_files_auto_define.txt' from 'localhost:/tmp/source_file.txt' #@ info: Auto defining class 'auto__tmp_example_files_auto_define_txt' #@ R: Defined 'auto__tmp_example_files_auto_define_txt', the canonified form of 'auto_/tmp/example_files_auto_define.txt' #@ ``` #+end_src cfengine-3.24.2/examples/string_mustache.cf0000644000000000000000000000473315010704253020711 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "config", "example" }; } bundle agent config { vars: "deserts" data => parsejson('{ "deserts": { "Africa": "Sahara", "Asia": "Gobi" } }'); } bundle agent example { vars: # {{@}} is the current key during an iteration in 3.7 with Mustache "with_data_container" string => string_mustache("from container: deserts = {{%deserts}} from container: {{#deserts}}The desert {{.}} is in {{@}}. {{/deserts}}", "config.deserts"); # you can dump an entire data structure with {{%myvar}} in 3.7 with Mustache "with_system_state" string => string_mustache("from datastate(): deserts = {{%vars.config.deserts.deserts}} from datastate(): {{#vars.config.deserts.deserts}}The desert {{.}} is in {{@}}. {{/vars.config.deserts.deserts}}"); # will use datastate() reports: "With an explicit data container: $(with_data_container)"; "With the system datastate(): $(with_system_state)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: With an explicit data container: from container: deserts = { #@ "Africa": "Sahara", #@ "Asia": "Gobi" #@ } #@ from container: The desert Sahara is in Africa. The desert Gobi is in Asia. #@ R: With the system datastate(): from datastate(): deserts = { #@ "Africa": "Sahara", #@ "Asia": "Gobi" #@ } #@ from datastate(): The desert Sahara is in Africa. The desert Gobi is in Asia. #@ ``` #+end_src cfengine-3.24.2/examples/data_readstringarray.cf0000644000000000000000000000500215010704253021672 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo a,b,c > /tmp/cfe_array #@ echo "# This is a comment" >> /tmp/cfe_array #@ echo d,e,f >> /tmp/cfe_array #@ echo g,h,i >> /tmp/cfe_array #@ echo "# This is another comment" >> /tmp/cfe_array #@ echo j,k,l >> /tmp/cfe_array #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: # The comment regex warrents an explination: # # matches the character # literally # [^\n]* match a single character not including the newline character # between zero and unlimited times, as many times as possible "bykey" data => data_readstringarray("/tmp/cfe_array","#[^\n]*",",",10,400); "byint" data => data_readstringarrayidx("/tmp/cfe_array","#[^\n]*",",",10,400); "bykey_str" string => format("%S", bykey); "byint_str" string => format("%S", byint); reports: "By key: $(bykey_str)"; "specific element by key a, offset 0: '$(bykey[a][0])'"; "By int offset: $(byint_str)"; "specific element by int offset 2, 0: '$(byint[2][0])'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: By key: {"a":["b","c"],"d":["e","f"],"g":["h","i"],"j":["k","l"]} #@ R: specific element by key a, offset 0: 'b' #@ R: By int offset: [["a","b","c"],["d","e","f"],["g","h","i"],["j","k","l"]] #@ R: specific element by int offset 2, 0: 'g' #@ ``` #+end_src cfengine-3.24.2/examples/registryvalue.cf0000644000000000000000000000302115010704253020404 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "reg" }; } bundle agent reg { vars: windows:: "value" string => registryvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\CFEngine","value3"); !windows:: "value" string => "Sorry, no registry data is available"; reports: "Value extracted: $(value)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Value extracted: Sorry, no registry data is available #@ ``` #+end_src cfengine-3.24.2/examples/syslog.cf0000644000000000000000000000226515010704253017030 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "one" }; } bundle agent one { files: "/tmp/xyz" create => "true", action => log; } body action log { log_level => "inform"; } cfengine-3.24.2/examples/filesize.cf0000644000000000000000000000307115010704253017316 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { example }; } bundle agent example { vars: # my own size! "exists" int => filesize("$(this.promise_filename)"); "nexists" int => filesize("/etc/passwdx"); reports: "File size $(exists)"; "Does not exist: $(nexists)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: File size 301 #@ R: Does not exist: $(nexists) #@ ``` #+end_src cfengine-3.24.2/examples/disable.cf0000644000000000000000000000240515010704253017107 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "my_disable" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent my_disable { files: "/home/mark/tmp/test_create" rename => disable; "/home/mark/tmp/rotate_my_log" rename => rotate("4"); } cfengine-3.24.2/examples/neighbourhood_watch.cf0000644000000000000000000000515315010704253021531 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Change detect # ######################################################## body common control { bundlesequence => { "neighbourhood_watch" }; } ######################################################## bundle agent neighbourhood_watch { vars: "neighbours" slist => peers("/var/cfengine/inputs/hostlist","#.*",4); files: # Redundant cross monitoring ....................................... "$(sys.workdir)/nw/$(neighbours)_checksum_digests.db" comment => "Watch our peers remote hash tables and keep a local copy", copy_from => rcp("$(sys.workdir)/checksum_digests.db",$(neighbours)), depends_on => { "grant_hash_tables" }; # Define the actual children to watch over ......................... "/usr/bin" comment => "Watch over the system binaries - changes are mostly updates", changes => lay_trip_wire, depth_search => recurse("inf"), action => measure; } ######################################################### body changes lay_trip_wire { hash => "best"; report_changes => "content"; update_hashes => "yes"; } ######################################################### body copy_from rcp(from,server) { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; encrypt => "false"; } ########################################################## body depth_search recurse(d) { depth => "$(d)"; } body action measure { measurement_class => "$(this.promiser) long job scan of /usr"; } cfengine-3.24.2/examples/reference_values_inside_data.cf0000755000000000000000000000132415010704253023347 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -f- #+begin_src cfengine3 bundle agent example_reference_values_inside_data { vars: "data" data => '{ "Key1": "Value1", "Key2": "Value2", "Key3": [ "Value3", "Value4" ] }'; reports: "Key1 contains '$(data[Key1])'"; "Key2 contains '$(data[Key2])'"; "Key3 iterates and contains '$(data[Key3])'"; } bundle agent __main__ { methods: "example_reference_values_inside_data"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Key1 contains 'Value1' #@ R: Key2 contains 'Value2' #@ R: Key3 iterates and contains 'Value3' #@ R: Key3 iterates and contains 'Value4' #@ ``` #+end_src cfengine-3.24.2/examples/unpack_method_calls.cf0000644000000000000000000000136615010704253021510 0ustar00rootroot00000000000000#+begin_src cfengine3 body common control { bundlesequence => { run }; } bundle agent run { vars: "todo" slist => { "call_1,a,b", "call_2,x,y", "call_2,p,q" }; methods: "call" usebundle => unpack($(todo)); } bundle agent unpack(list) { vars: "split" slist => splitstring($(list), ",", "100"); "method" string => nth("split", "0"); "param1" string => nth("split", "1"); "param2" string => nth("split", "2"); methods: "relay" usebundle => $(method)($(param1), $(param2)); } bundle agent call_1(p1, p2) { reports: "$(this.bundle): called with parameters $(p1) and $(p2)"; } bundle agent call_2(p1, p2) { reports: "$(this.bundle): called with parameters $(p1) and $(p2)"; } #+end_src cfengine-3.24.2/examples/data_sysctlvalues.cf0000644000000000000000000012046515010704253021245 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent inventory_sysctl # @brief Inventory each sysctl variable { vars: # Get the complete set of sysctl variables and values as a data structure "_sysctl_d" data => data_sysctlvalues(), unless => isvariable( _sysctl_d ); # Get the sysctl variable names "_sysctl_i" slist => getindices( "_sysctl_d" ); # Define a variable tagged for inventory for each sysctl variable "sysctl[$(_sysctl_i)]" string => "$(_sysctl_d[$(_sysctl_i)])", meta => { "inventory", "attribute_name=Kernel Tunable $(_sysctl_i)" }; reports: # Show what data_sysctlvalues() returned. "data_sysctlvalues() returned:$(with)" with => storejson( @(_sysctl_d) ); } bundle agent __main__ { methods: "inventory_sysctl"; } #+end_src ############################################################################### #+begin_src mock_example_output #@ ``` #@ R: data_sysctlvalues() returned:{ #@ "abi.vsyscall32": "1", #@ "crypto.fips_enabled": "0", #@ "debug.exception-trace": "1", #@ "debug.kprobes-optimization": "1", #@ "debug.panic_on_rcu_stall": "0", #@ "dev.hpet.max-user-freq": "64", #@ "dev.mac_hid.mouse_button2_keycode": "97", #@ "dev.mac_hid.mouse_button3_keycode": "100", #@ "dev.mac_hid.mouse_button_emulation": "0", #@ "dev.parport.default.spintime": "500", #@ "dev.parport.default.timeslice": "200", #@ "dev.raid.speed_limit_max": "200000", #@ "dev.raid.speed_limit_min": "1000", #@ "dev.scsi.logging_level": "0", #@ "fs.aio-max-nr": "65536", #@ "fs.aio-nr": "0", #@ "fs.binfmt_misc.status": "enabled", #@ "fs.dentry-state": "43676\t27378\t45\t0\t479\t0", #@ "fs.dir-notify-enable": "1", #@ "fs.epoll.max_user_watches": "99020", #@ "fs.file-max": "47380", #@ "fs.file-nr": "1472\t0\t47380", #@ "fs.inode-nr": "47116\t21990", #@ "fs.inode-state": "47116\t21990\t0\t0\t0\t0\t0", #@ "fs.inotify.max_queued_events": "16384", #@ "fs.inotify.max_user_instances": "128", #@ "fs.inotify.max_user_watches": "8192", #@ "fs.lease-break-time": "45", #@ "fs.leases-enable": "1", #@ "fs.may_detach_mounts": "0", #@ "fs.mount-max": "100000", #@ "fs.mqueue.msg_default": "10", #@ "fs.mqueue.msg_max": "10", #@ "fs.mqueue.msgsize_default": "8192", #@ "fs.mqueue.msgsize_max": "8192", #@ "fs.mqueue.queues_max": "256", #@ "fs.negative-dentry-limit": "0", #@ "fs.nr_open": "1048576", #@ "fs.overflowgid": "65534", #@ "fs.overflowuid": "65534", #@ "fs.pipe-max-size": "1048576", #@ "fs.pipe-user-pages-hard": "0", #@ "fs.pipe-user-pages-soft": "16384", #@ "fs.protected_hardlinks": "1", #@ "fs.protected_symlinks": "1", #@ "fs.quota.allocated_dquots": "0", #@ "fs.quota.cache_hits": "0", #@ "fs.quota.drops": "0", #@ "fs.quota.free_dquots": "0", #@ "fs.quota.lookups": "0", #@ "fs.quota.reads": "0", #@ "fs.quota.syncs": "0", #@ "fs.quota.warnings": "1", #@ "fs.quota.writes": "0", #@ "fs.suid_dumpable": "0", #@ "fs.xfs.age_buffer_centisecs": "1500", #@ "fs.xfs.error_level": "3", #@ "fs.xfs.filestream_centisecs": "3000", #@ "fs.xfs.inherit_noatime": "1", #@ "fs.xfs.inherit_nodefrag": "1", #@ "fs.xfs.inherit_nodump": "1", #@ "fs.xfs.inherit_nosymlinks": "0", #@ "fs.xfs.inherit_sync": "1", #@ "fs.xfs.irix_sgid_inherit": "0", #@ "fs.xfs.irix_symlink_mode": "0", #@ "fs.xfs.panic_mask": "0", #@ "fs.xfs.rotorstep": "1", #@ "fs.xfs.speculative_prealloc_lifetime": "300", #@ "fs.xfs.stats_clear": "0", #@ "fs.xfs.xfsbufd_centisecs": "100", #@ "fs.xfs.xfssyncd_centisecs": "3000", #@ "kernel.acct": "4\t2\t30", #@ "kernel.acpi_video_flags": "0", #@ "kernel.auto_msgmni": "0", #@ "kernel.bootloader_type": "114", #@ "kernel.bootloader_version": "2", #@ "kernel.cad_pid": "1", #@ "kernel.cap_last_cap": "36", #@ "kernel.compat-log": "1", #@ "kernel.core_pattern": "core", #@ "kernel.core_pipe_limit": "0", #@ "kernel.core_uses_pid": "1", #@ "kernel.ctrl-alt-del": "0", #@ "kernel.dmesg_restrict": "0", #@ "kernel.domainname": "(none)", #@ "kernel.ftrace_dump_on_oops": "0", #@ "kernel.ftrace_enabled": "1", #@ "kernel.hardlockup_all_cpu_backtrace": "0", #@ "kernel.hardlockup_panic": "1", #@ "kernel.hostname": "hub.example.com", #@ "kernel.hotplug": "", #@ "kernel.hung_task_check_count": "4194304", #@ "kernel.hung_task_panic": "0", #@ "kernel.hung_task_timeout_secs": "120", #@ "kernel.hung_task_warnings": "10", #@ "kernel.io_delay_type": "0", #@ "kernel.kexec_load_disabled": "0", #@ "kernel.keys.gc_delay": "300", #@ "kernel.keys.maxbytes": "20000", #@ "kernel.keys.maxkeys": "200", #@ "kernel.keys.persistent_keyring_expiry": "259200", #@ "kernel.keys.root_maxbytes": "25000000", #@ "kernel.keys.root_maxkeys": "1000000", #@ "kernel.kptr_restrict": "0", #@ "kernel.max_lock_depth": "1024", #@ "kernel.modprobe": "/sbin/modprobe", #@ "kernel.modules_disabled": "0", #@ "kernel.msg_next_id": "-1", #@ "kernel.msgmax": "8192", #@ "kernel.msgmnb": "16384", #@ "kernel.msgmni": "32000", #@ "kernel.ngroups_max": "65536", #@ "kernel.nmi_watchdog": "1", #@ "kernel.ns_last_pid": "3240", #@ "kernel.numa_balancing": "0", #@ "kernel.numa_balancing_scan_delay_ms": "1000", #@ "kernel.numa_balancing_scan_period_max_ms": "60000", #@ "kernel.numa_balancing_scan_period_min_ms": "1000", #@ "kernel.numa_balancing_scan_size_mb": "256", #@ "kernel.numa_balancing_settle_count": "4", #@ "kernel.osrelease": "3.10.0-1127.el7.x86_64", #@ "kernel.ostype": "Linux", #@ "kernel.overflowgid": "65534", #@ "kernel.overflowuid": "65534", #@ "kernel.panic": "0", #@ "kernel.panic_on_io_nmi": "0", #@ "kernel.panic_on_oops": "1", #@ "kernel.panic_on_stackoverflow": "0", #@ "kernel.panic_on_unrecovered_nmi": "0", #@ "kernel.panic_on_warn": "0", #@ "kernel.perf_cpu_time_max_percent": "25", #@ "kernel.perf_event_max_sample_rate": "100000", #@ "kernel.perf_event_mlock_kb": "516", #@ "kernel.perf_event_paranoid": "2", #@ "kernel.pid_max": "32768", #@ "kernel.poweroff_cmd": "/sbin/poweroff", #@ "kernel.print-fatal-signals": "0", #@ "kernel.printk": "7\t4\t1\t7", #@ "kernel.printk_delay": "0", #@ "kernel.printk_ratelimit": "5", #@ "kernel.printk_ratelimit_burst": "10", #@ "kernel.pty.max": "4096", #@ "kernel.pty.nr": "1", #@ "kernel.pty.reserve": "1024", #@ "kernel.random.boot_id": "422886c9-8219-4749-9610-981bdeb5e509", #@ "kernel.random.entropy_avail": "3071", #@ "kernel.random.poolsize": "4096", #@ "kernel.random.read_wakeup_threshold": "64", #@ "kernel.random.urandom_min_reseed_secs": "60", #@ "kernel.random.uuid": "f9544436-b0a1-43b7-a36b-3b8da50e066a", #@ "kernel.random.write_wakeup_threshold": "896", #@ "kernel.randomize_va_space": "2", #@ "kernel.real-root-dev": "0", #@ "kernel.sched_autogroup_enabled": "0", #@ "kernel.sched_cfs_bandwidth_slice_us": "5000", #@ "kernel.sched_child_runs_first": "0", #@ "kernel.sched_domain.cpu0.domain0.busy_factor": "32", #@ "kernel.sched_domain.cpu0.domain0.busy_idx": "2", #@ "kernel.sched_domain.cpu0.domain0.cache_nice_tries": "1", #@ "kernel.sched_domain.cpu0.domain0.flags": "559", #@ "kernel.sched_domain.cpu0.domain0.forkexec_idx": "0", #@ "kernel.sched_domain.cpu0.domain0.idle_idx": "0", #@ "kernel.sched_domain.cpu0.domain0.imbalance_pct": "117", #@ "kernel.sched_domain.cpu0.domain0.max_interval": "4", #@ "kernel.sched_domain.cpu0.domain0.max_newidle_lb_cost": "37143", #@ "kernel.sched_domain.cpu0.domain0.min_interval": "2", #@ "kernel.sched_domain.cpu0.domain0.name": "MC", #@ "kernel.sched_domain.cpu0.domain0.newidle_idx": "0", #@ "kernel.sched_domain.cpu0.domain0.wake_idx": "0", #@ "kernel.sched_domain.cpu1.domain0.busy_factor": "32", #@ "kernel.sched_domain.cpu1.domain0.busy_idx": "2", #@ "kernel.sched_domain.cpu1.domain0.cache_nice_tries": "1", #@ "kernel.sched_domain.cpu1.domain0.flags": "559", #@ "kernel.sched_domain.cpu1.domain0.forkexec_idx": "0", #@ "kernel.sched_domain.cpu1.domain0.idle_idx": "0", #@ "kernel.sched_domain.cpu1.domain0.imbalance_pct": "117", #@ "kernel.sched_domain.cpu1.domain0.max_interval": "4", #@ "kernel.sched_domain.cpu1.domain0.max_newidle_lb_cost": "16770", #@ "kernel.sched_domain.cpu1.domain0.min_interval": "2", #@ "kernel.sched_domain.cpu1.domain0.name": "MC", #@ "kernel.sched_domain.cpu1.domain0.newidle_idx": "0", #@ "kernel.sched_domain.cpu1.domain0.wake_idx": "0", #@ "kernel.sched_latency_ns": "12000000", #@ "kernel.sched_migration_cost_ns": "500000", #@ "kernel.sched_min_granularity_ns": "10000000", #@ "kernel.sched_nr_migrate": "32", #@ "kernel.sched_rr_timeslice_ms": "100", #@ "kernel.sched_rt_period_us": "1000000", #@ "kernel.sched_rt_runtime_us": "950000", #@ "kernel.sched_schedstats": "0", #@ "kernel.sched_shares_window_ns": "10000000", #@ "kernel.sched_time_avg_ms": "1000", #@ "kernel.sched_tunable_scaling": "1", #@ "kernel.sched_wakeup_granularity_ns": "15000000", #@ "kernel.seccomp.actions_avail": "kill trap errno trace allow", #@ "kernel.seccomp.actions_logged": "kill trap errno trace", #@ "kernel.sem": "250\t32000\t32\t128", #@ "kernel.sem_next_id": "-1", #@ "kernel.shm_next_id": "-1", #@ "kernel.shm_rmid_forced": "0", #@ "kernel.shmall": "18446744073692774399", #@ "kernel.shmmax": "18446744073692774399", #@ "kernel.shmmni": "4096", #@ "kernel.softlockup_all_cpu_backtrace": "0", #@ "kernel.softlockup_panic": "0", #@ "kernel.stack_tracer_enabled": "0", #@ "kernel.sysctl_writes_strict": "1", #@ "kernel.sysrq": "16", #@ "kernel.tainted": "0", #@ "kernel.threads-max": "3777", #@ "kernel.timer_migration": "1", #@ "kernel.traceoff_on_warning": "0", #@ "kernel.unknown_nmi_panic": "0", #@ "kernel.usermodehelper.bset": "4294967295\t31", #@ "kernel.usermodehelper.inheritable": "4294967295\t31", #@ "kernel.version": "#1 SMP Tue Mar 31 23:36:51 UTC 2020", #@ "kernel.watchdog": "1", #@ "kernel.watchdog_cpumask": "0-1", #@ "kernel.watchdog_thresh": "10", #@ "kernel.yama.ptrace_scope": "0", #@ "net.core.bpf_jit_enable": "1", #@ "net.core.bpf_jit_harden": "1", #@ "net.core.bpf_jit_kallsyms": "0", #@ "net.core.busy_poll": "0", #@ "net.core.busy_read": "0", #@ "net.core.default_qdisc": "pfifo_fast", #@ "net.core.dev_weight": "64", #@ "net.core.dev_weight_rx_bias": "1", #@ "net.core.dev_weight_tx_bias": "1", #@ "net.core.message_burst": "10", #@ "net.core.message_cost": "5", #@ "net.core.netdev_budget": "300", #@ "net.core.netdev_max_backlog": "1000", #@ "net.core.netdev_rss_key": "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", #@ "net.core.netdev_tstamp_prequeue": "1", #@ "net.core.optmem_max": "20480", #@ "net.core.rmem_default": "212992", #@ "net.core.rmem_max": "212992", #@ "net.core.rps_sock_flow_entries": "0", #@ "net.core.somaxconn": "128", #@ "net.core.warnings": "1", #@ "net.core.wmem_default": "212992", #@ "net.core.wmem_max": "212992", #@ "net.core.xfrm_acq_expires": "30", #@ "net.core.xfrm_aevent_etime": "10", #@ "net.core.xfrm_aevent_rseqth": "2", #@ "net.core.xfrm_larval_drop": "1", #@ "net.ipv4.cipso_cache_bucket_size": "10", #@ "net.ipv4.cipso_cache_enable": "1", #@ "net.ipv4.cipso_rbm_optfmt": "0", #@ "net.ipv4.cipso_rbm_strictvalid": "1", #@ "net.ipv4.conf.all.accept_local": "0", #@ "net.ipv4.conf.all.accept_redirects": "1", #@ "net.ipv4.conf.all.accept_source_route": "0", #@ "net.ipv4.conf.all.arp_accept": "0", #@ "net.ipv4.conf.all.arp_announce": "0", #@ "net.ipv4.conf.all.arp_filter": "0", #@ "net.ipv4.conf.all.arp_ignore": "0", #@ "net.ipv4.conf.all.arp_notify": "0", #@ "net.ipv4.conf.all.bootp_relay": "0", #@ "net.ipv4.conf.all.disable_policy": "0", #@ "net.ipv4.conf.all.disable_xfrm": "0", #@ "net.ipv4.conf.all.force_igmp_version": "0", #@ "net.ipv4.conf.all.forwarding": "0", #@ "net.ipv4.conf.all.igmpv2_unsolicited_report_interval": "10000", #@ "net.ipv4.conf.all.igmpv3_unsolicited_report_interval": "1000", #@ "net.ipv4.conf.all.log_martians": "0", #@ "net.ipv4.conf.all.mc_forwarding": "0", #@ "net.ipv4.conf.all.medium_id": "0", #@ "net.ipv4.conf.all.promote_secondaries": "1", #@ "net.ipv4.conf.all.proxy_arp": "0", #@ "net.ipv4.conf.all.proxy_arp_pvlan": "0", #@ "net.ipv4.conf.all.route_localnet": "0", #@ "net.ipv4.conf.all.rp_filter": "1", #@ "net.ipv4.conf.all.secure_redirects": "1", #@ "net.ipv4.conf.all.send_redirects": "1", #@ "net.ipv4.conf.all.shared_media": "1", #@ "net.ipv4.conf.all.src_valid_mark": "0", #@ "net.ipv4.conf.all.tag": "0", #@ "net.ipv4.conf.default.accept_local": "0", #@ "net.ipv4.conf.default.accept_redirects": "1", #@ "net.ipv4.conf.default.accept_source_route": "0", #@ "net.ipv4.conf.default.arp_accept": "0", #@ "net.ipv4.conf.default.arp_announce": "0", #@ "net.ipv4.conf.default.arp_filter": "0", #@ "net.ipv4.conf.default.arp_ignore": "0", #@ "net.ipv4.conf.default.arp_notify": "0", #@ "net.ipv4.conf.default.bootp_relay": "0", #@ "net.ipv4.conf.default.disable_policy": "0", #@ "net.ipv4.conf.default.disable_xfrm": "0", #@ "net.ipv4.conf.default.force_igmp_version": "0", #@ "net.ipv4.conf.default.forwarding": "0", #@ "net.ipv4.conf.default.igmpv2_unsolicited_report_interval": "10000", #@ "net.ipv4.conf.default.igmpv3_unsolicited_report_interval": "1000", #@ "net.ipv4.conf.default.log_martians": "0", #@ "net.ipv4.conf.default.mc_forwarding": "0", #@ "net.ipv4.conf.default.medium_id": "0", #@ "net.ipv4.conf.default.promote_secondaries": "1", #@ "net.ipv4.conf.default.proxy_arp": "0", #@ "net.ipv4.conf.default.proxy_arp_pvlan": "0", #@ "net.ipv4.conf.default.route_localnet": "0", #@ "net.ipv4.conf.default.rp_filter": "1", #@ "net.ipv4.conf.default.secure_redirects": "1", #@ "net.ipv4.conf.default.send_redirects": "1", #@ "net.ipv4.conf.default.shared_media": "1", #@ "net.ipv4.conf.default.src_valid_mark": "0", #@ "net.ipv4.conf.default.tag": "0", #@ "net.ipv4.conf.eth0.accept_local": "0", #@ "net.ipv4.conf.eth0.accept_redirects": "1", #@ "net.ipv4.conf.eth0.accept_source_route": "0", #@ "net.ipv4.conf.eth0.arp_accept": "0", #@ "net.ipv4.conf.eth0.arp_announce": "0", #@ "net.ipv4.conf.eth0.arp_filter": "0", #@ "net.ipv4.conf.eth0.arp_ignore": "0", #@ "net.ipv4.conf.eth0.arp_notify": "0", #@ "net.ipv4.conf.eth0.bootp_relay": "0", #@ "net.ipv4.conf.eth0.disable_policy": "0", #@ "net.ipv4.conf.eth0.disable_xfrm": "0", #@ "net.ipv4.conf.eth0.force_igmp_version": "0", #@ "net.ipv4.conf.eth0.forwarding": "0", #@ "net.ipv4.conf.eth0.igmpv2_unsolicited_report_interval": "10000", #@ "net.ipv4.conf.eth0.igmpv3_unsolicited_report_interval": "1000", #@ "net.ipv4.conf.eth0.log_martians": "0", #@ "net.ipv4.conf.eth0.mc_forwarding": "0", #@ "net.ipv4.conf.eth0.medium_id": "0", #@ "net.ipv4.conf.eth0.promote_secondaries": "1", #@ "net.ipv4.conf.eth0.proxy_arp": "0", #@ "net.ipv4.conf.eth0.proxy_arp_pvlan": "0", #@ "net.ipv4.conf.eth0.route_localnet": "0", #@ "net.ipv4.conf.eth0.rp_filter": "1", #@ "net.ipv4.conf.eth0.secure_redirects": "1", #@ "net.ipv4.conf.eth0.send_redirects": "1", #@ "net.ipv4.conf.eth0.shared_media": "1", #@ "net.ipv4.conf.eth0.src_valid_mark": "0", #@ "net.ipv4.conf.eth0.tag": "0", #@ "net.ipv4.conf.eth1.accept_local": "0", #@ "net.ipv4.conf.eth1.accept_redirects": "1", #@ "net.ipv4.conf.eth1.accept_source_route": "0", #@ "net.ipv4.conf.eth1.arp_accept": "0", #@ "net.ipv4.conf.eth1.arp_announce": "0", #@ "net.ipv4.conf.eth1.arp_filter": "0", #@ "net.ipv4.conf.eth1.arp_ignore": "0", #@ "net.ipv4.conf.eth1.arp_notify": "0", #@ "net.ipv4.conf.eth1.bootp_relay": "0", #@ "net.ipv4.conf.eth1.disable_policy": "0", #@ "net.ipv4.conf.eth1.disable_xfrm": "0", #@ "net.ipv4.conf.eth1.force_igmp_version": "0", #@ "net.ipv4.conf.eth1.forwarding": "0", #@ "net.ipv4.conf.eth1.igmpv2_unsolicited_report_interval": "10000", #@ "net.ipv4.conf.eth1.igmpv3_unsolicited_report_interval": "1000", #@ "net.ipv4.conf.eth1.log_martians": "0", #@ "net.ipv4.conf.eth1.mc_forwarding": "0", #@ "net.ipv4.conf.eth1.medium_id": "0", #@ "net.ipv4.conf.eth1.promote_secondaries": "1", #@ "net.ipv4.conf.eth1.proxy_arp": "0", #@ "net.ipv4.conf.eth1.proxy_arp_pvlan": "0", #@ "net.ipv4.conf.eth1.route_localnet": "0", #@ "net.ipv4.conf.eth1.rp_filter": "1", #@ "net.ipv4.conf.eth1.secure_redirects": "1", #@ "net.ipv4.conf.eth1.send_redirects": "1", #@ "net.ipv4.conf.eth1.shared_media": "1", #@ "net.ipv4.conf.eth1.src_valid_mark": "0", #@ "net.ipv4.conf.eth1.tag": "0", #@ "net.ipv4.conf.lo.accept_local": "0", #@ "net.ipv4.conf.lo.accept_redirects": "1", #@ "net.ipv4.conf.lo.accept_source_route": "1", #@ "net.ipv4.conf.lo.arp_accept": "0", #@ "net.ipv4.conf.lo.arp_announce": "0", #@ "net.ipv4.conf.lo.arp_filter": "0", #@ "net.ipv4.conf.lo.arp_ignore": "0", #@ "net.ipv4.conf.lo.arp_notify": "0", #@ "net.ipv4.conf.lo.bootp_relay": "0", #@ "net.ipv4.conf.lo.disable_policy": "1", #@ "net.ipv4.conf.lo.disable_xfrm": "1", #@ "net.ipv4.conf.lo.force_igmp_version": "0", #@ "net.ipv4.conf.lo.forwarding": "0", #@ "net.ipv4.conf.lo.igmpv2_unsolicited_report_interval": "10000", #@ "net.ipv4.conf.lo.igmpv3_unsolicited_report_interval": "1000", #@ "net.ipv4.conf.lo.log_martians": "0", #@ "net.ipv4.conf.lo.mc_forwarding": "0", #@ "net.ipv4.conf.lo.medium_id": "0", #@ "net.ipv4.conf.lo.promote_secondaries": "0", #@ "net.ipv4.conf.lo.proxy_arp": "0", #@ "net.ipv4.conf.lo.proxy_arp_pvlan": "0", #@ "net.ipv4.conf.lo.route_localnet": "0", #@ "net.ipv4.conf.lo.rp_filter": "0", #@ "net.ipv4.conf.lo.secure_redirects": "1", #@ "net.ipv4.conf.lo.send_redirects": "1", #@ "net.ipv4.conf.lo.shared_media": "1", #@ "net.ipv4.conf.lo.src_valid_mark": "0", #@ "net.ipv4.conf.lo.tag": "0", #@ "net.ipv4.fib_multipath_hash_policy": "0", #@ "net.ipv4.fwmark_reflect": "0", #@ "net.ipv4.icmp_echo_ignore_all": "0", #@ "net.ipv4.icmp_echo_ignore_broadcasts": "1", #@ "net.ipv4.icmp_errors_use_inbound_ifaddr": "0", #@ "net.ipv4.icmp_ignore_bogus_error_responses": "1", #@ "net.ipv4.icmp_msgs_burst": "50", #@ "net.ipv4.icmp_msgs_per_sec": "1000", #@ "net.ipv4.icmp_ratelimit": "1000", #@ "net.ipv4.icmp_ratemask": "6168", #@ "net.ipv4.igmp_max_memberships": "20", #@ "net.ipv4.igmp_max_msf": "10", #@ "net.ipv4.igmp_qrv": "2", #@ "net.ipv4.inet_peer_maxttl": "600", #@ "net.ipv4.inet_peer_minttl": "120", #@ "net.ipv4.inet_peer_threshold": "65664", #@ "net.ipv4.ip_default_ttl": "64", #@ "net.ipv4.ip_dynaddr": "0", #@ "net.ipv4.ip_early_demux": "1", #@ "net.ipv4.ip_forward": "0", #@ "net.ipv4.ip_forward_use_pmtu": "0", #@ "net.ipv4.ip_local_port_range": "32768\t60999", #@ "net.ipv4.ip_local_reserved_ports": "", #@ "net.ipv4.ip_no_pmtu_disc": "0", #@ "net.ipv4.ip_nonlocal_bind": "0", #@ "net.ipv4.ipfrag_high_thresh": "4194304", #@ "net.ipv4.ipfrag_low_thresh": "3145728", #@ "net.ipv4.ipfrag_max_dist": "64", #@ "net.ipv4.ipfrag_secret_interval": "600", #@ "net.ipv4.ipfrag_time": "30", #@ "net.ipv4.neigh.default.anycast_delay": "100", #@ "net.ipv4.neigh.default.app_solicit": "0", #@ "net.ipv4.neigh.default.base_reachable_time": "30", #@ "net.ipv4.neigh.default.base_reachable_time_ms": "30000", #@ "net.ipv4.neigh.default.delay_first_probe_time": "5", #@ "net.ipv4.neigh.default.gc_interval": "30", #@ "net.ipv4.neigh.default.gc_stale_time": "60", #@ "net.ipv4.neigh.default.gc_thresh1": "128", #@ "net.ipv4.neigh.default.gc_thresh2": "512", #@ "net.ipv4.neigh.default.gc_thresh3": "1024", #@ "net.ipv4.neigh.default.locktime": "100", #@ "net.ipv4.neigh.default.mcast_solicit": "3", #@ "net.ipv4.neigh.default.proxy_delay": "80", #@ "net.ipv4.neigh.default.proxy_qlen": "64", #@ "net.ipv4.neigh.default.retrans_time": "100", #@ "net.ipv4.neigh.default.retrans_time_ms": "1000", #@ "net.ipv4.neigh.default.ucast_solicit": "3", #@ "net.ipv4.neigh.default.unres_qlen": "31", #@ "net.ipv4.neigh.default.unres_qlen_bytes": "65536", #@ "net.ipv4.neigh.eth0.anycast_delay": "100", #@ "net.ipv4.neigh.eth0.app_solicit": "0", #@ "net.ipv4.neigh.eth0.base_reachable_time": "30", #@ "net.ipv4.neigh.eth0.base_reachable_time_ms": "30000", #@ "net.ipv4.neigh.eth0.delay_first_probe_time": "5", #@ "net.ipv4.neigh.eth0.gc_stale_time": "60", #@ "net.ipv4.neigh.eth0.locktime": "100", #@ "net.ipv4.neigh.eth0.mcast_solicit": "3", #@ "net.ipv4.neigh.eth0.proxy_delay": "80", #@ "net.ipv4.neigh.eth0.proxy_qlen": "64", #@ "net.ipv4.neigh.eth0.retrans_time": "100", #@ "net.ipv4.neigh.eth0.retrans_time_ms": "1000", #@ "net.ipv4.neigh.eth0.ucast_solicit": "3", #@ "net.ipv4.neigh.eth0.unres_qlen": "31", #@ "net.ipv4.neigh.eth0.unres_qlen_bytes": "65536", #@ "net.ipv4.neigh.eth1.anycast_delay": "100", #@ "net.ipv4.neigh.eth1.app_solicit": "0", #@ "net.ipv4.neigh.eth1.base_reachable_time": "30", #@ "net.ipv4.neigh.eth1.base_reachable_time_ms": "30000", #@ "net.ipv4.neigh.eth1.delay_first_probe_time": "5", #@ "net.ipv4.neigh.eth1.gc_stale_time": "60", #@ "net.ipv4.neigh.eth1.locktime": "100", #@ "net.ipv4.neigh.eth1.mcast_solicit": "3", #@ "net.ipv4.neigh.eth1.proxy_delay": "80", #@ "net.ipv4.neigh.eth1.proxy_qlen": "64", #@ "net.ipv4.neigh.eth1.retrans_time": "100", #@ "net.ipv4.neigh.eth1.retrans_time_ms": "1000", #@ "net.ipv4.neigh.eth1.ucast_solicit": "3", #@ "net.ipv4.neigh.eth1.unres_qlen": "31", #@ "net.ipv4.neigh.eth1.unres_qlen_bytes": "65536", #@ "net.ipv4.neigh.lo.anycast_delay": "100", #@ "net.ipv4.neigh.lo.app_solicit": "0", #@ "net.ipv4.neigh.lo.base_reachable_time": "30", #@ "net.ipv4.neigh.lo.base_reachable_time_ms": "30000", #@ "net.ipv4.neigh.lo.delay_first_probe_time": "5", #@ "net.ipv4.neigh.lo.gc_stale_time": "60", #@ "net.ipv4.neigh.lo.locktime": "100", #@ "net.ipv4.neigh.lo.mcast_solicit": "3", #@ "net.ipv4.neigh.lo.proxy_delay": "80", #@ "net.ipv4.neigh.lo.proxy_qlen": "64", #@ "net.ipv4.neigh.lo.retrans_time": "100", #@ "net.ipv4.neigh.lo.retrans_time_ms": "1000", #@ "net.ipv4.neigh.lo.ucast_solicit": "3", #@ "net.ipv4.neigh.lo.unres_qlen": "31", #@ "net.ipv4.neigh.lo.unres_qlen_bytes": "65536", #@ "net.ipv4.ping_group_range": "1\t0", #@ "net.ipv4.route.error_burst": "5000", #@ "net.ipv4.route.error_cost": "1000", #@ "net.ipv4.route.gc_elasticity": "8", #@ "net.ipv4.route.gc_interval": "60", #@ "net.ipv4.route.gc_min_interval": "0", #@ "net.ipv4.route.gc_min_interval_ms": "500", #@ "net.ipv4.route.gc_thresh": "-1", #@ "net.ipv4.route.gc_timeout": "300", #@ "net.ipv4.route.max_size": "2147483647", #@ "net.ipv4.route.min_adv_mss": "256", #@ "net.ipv4.route.min_pmtu": "552", #@ "net.ipv4.route.mtu_expires": "600", #@ "net.ipv4.route.redirect_load": "20", #@ "net.ipv4.route.redirect_number": "9", #@ "net.ipv4.route.redirect_silence": "20480", #@ "net.ipv4.tcp_abort_on_overflow": "0", #@ "net.ipv4.tcp_adv_win_scale": "1", #@ "net.ipv4.tcp_allowed_congestion_control": "cubic reno", #@ "net.ipv4.tcp_app_win": "31", #@ "net.ipv4.tcp_autocorking": "1", #@ "net.ipv4.tcp_available_congestion_control": "cubic reno", #@ "net.ipv4.tcp_base_mss": "512", #@ "net.ipv4.tcp_challenge_ack_limit": "1000", #@ "net.ipv4.tcp_congestion_control": "cubic", #@ "net.ipv4.tcp_dsack": "1", #@ "net.ipv4.tcp_early_retrans": "3", #@ "net.ipv4.tcp_ecn": "2", #@ "net.ipv4.tcp_fack": "1", #@ "net.ipv4.tcp_fastopen": "0", #@ "net.ipv4.tcp_fastopen_key": "00000000-00000000-00000000-00000000", #@ "net.ipv4.tcp_fin_timeout": "60", #@ "net.ipv4.tcp_frto": "2", #@ "net.ipv4.tcp_invalid_ratelimit": "500", #@ "net.ipv4.tcp_keepalive_intvl": "75", #@ "net.ipv4.tcp_keepalive_probes": "9", #@ "net.ipv4.tcp_keepalive_time": "7200", #@ "net.ipv4.tcp_limit_output_bytes": "262144", #@ "net.ipv4.tcp_low_latency": "0", #@ "net.ipv4.tcp_max_orphans": "2048", #@ "net.ipv4.tcp_max_ssthresh": "0", #@ "net.ipv4.tcp_max_syn_backlog": "128", #@ "net.ipv4.tcp_max_tw_buckets": "2048", #@ "net.ipv4.tcp_mem": "11517\t15356\t23034", #@ "net.ipv4.tcp_min_snd_mss": "48", #@ "net.ipv4.tcp_min_tso_segs": "2", #@ "net.ipv4.tcp_moderate_rcvbuf": "1", #@ "net.ipv4.tcp_mtu_probing": "0", #@ "net.ipv4.tcp_no_metrics_save": "0", #@ "net.ipv4.tcp_notsent_lowat": "-1", #@ "net.ipv4.tcp_orphan_retries": "0", #@ "net.ipv4.tcp_reordering": "3", #@ "net.ipv4.tcp_retrans_collapse": "1", #@ "net.ipv4.tcp_retries1": "3", #@ "net.ipv4.tcp_retries2": "15", #@ "net.ipv4.tcp_rfc1337": "0", #@ "net.ipv4.tcp_rmem": "4096\t87380\t3868000", #@ "net.ipv4.tcp_sack": "1", #@ "net.ipv4.tcp_slow_start_after_idle": "1", #@ "net.ipv4.tcp_stdurg": "0", #@ "net.ipv4.tcp_syn_retries": "6", #@ "net.ipv4.tcp_synack_retries": "5", #@ "net.ipv4.tcp_syncookies": "1", #@ "net.ipv4.tcp_thin_dupack": "0", #@ "net.ipv4.tcp_thin_linear_timeouts": "0", #@ "net.ipv4.tcp_timestamps": "1", #@ "net.ipv4.tcp_tso_win_divisor": "3", #@ "net.ipv4.tcp_tw_recycle": "0", #@ "net.ipv4.tcp_tw_reuse": "0", #@ "net.ipv4.tcp_window_scaling": "1", #@ "net.ipv4.tcp_wmem": "4096\t16384\t3868000", #@ "net.ipv4.tcp_workaround_signed_windows": "0", #@ "net.ipv4.udp_mem": "11331\t15109\t22662", #@ "net.ipv4.udp_rmem_min": "4096", #@ "net.ipv4.udp_wmem_min": "4096", #@ "net.ipv4.xfrm4_gc_thresh": "32768", #@ "net.ipv6.anycast_src_echo_reply": "0", #@ "net.ipv6.bindv6only": "0", #@ "net.ipv6.conf.all.accept_dad": "0", #@ "net.ipv6.conf.all.accept_ra": "1", #@ "net.ipv6.conf.all.accept_ra_defrtr": "1", #@ "net.ipv6.conf.all.accept_ra_pinfo": "1", #@ "net.ipv6.conf.all.accept_ra_rt_info_max_plen": "0", #@ "net.ipv6.conf.all.accept_ra_rtr_pref": "1", #@ "net.ipv6.conf.all.accept_redirects": "1", #@ "net.ipv6.conf.all.accept_source_route": "0", #@ "net.ipv6.conf.all.autoconf": "1", #@ "net.ipv6.conf.all.dad_transmits": "1", #@ "net.ipv6.conf.all.disable_ipv6": "0", #@ "net.ipv6.conf.all.enhanced_dad": "1", #@ "net.ipv6.conf.all.force_mld_version": "0", #@ "net.ipv6.conf.all.force_tllao": "0", #@ "net.ipv6.conf.all.forwarding": "0", #@ "net.ipv6.conf.all.hop_limit": "64", #@ "net.ipv6.conf.all.keep_addr_on_down": "0", #@ "net.ipv6.conf.all.max_addresses": "16", #@ "net.ipv6.conf.all.max_desync_factor": "600", #@ "net.ipv6.conf.all.mc_forwarding": "0", #@ "net.ipv6.conf.all.mldv1_unsolicited_report_interval": "10000", #@ "net.ipv6.conf.all.mldv2_unsolicited_report_interval": "1000", #@ "net.ipv6.conf.all.mtu": "1280", #@ "net.ipv6.conf.all.ndisc_notify": "0", #@ "net.ipv6.conf.all.optimistic_dad": "0", #@ "net.ipv6.conf.all.proxy_ndp": "0", #@ "net.ipv6.conf.all.regen_max_retry": "3", #@ "net.ipv6.conf.all.router_probe_interval": "60", #@ "net.ipv6.conf.all.router_solicitation_delay": "1", #@ "net.ipv6.conf.all.router_solicitation_interval": "4", #@ "net.ipv6.conf.all.router_solicitations": "3", #@ "net.ipv6.conf.all.temp_prefered_lft": "86400", #@ "net.ipv6.conf.all.temp_valid_lft": "604800", #@ "net.ipv6.conf.all.use_optimistic": "0", #@ "net.ipv6.conf.all.use_tempaddr": "0", #@ "net.ipv6.conf.default.accept_dad": "1", #@ "net.ipv6.conf.default.accept_ra": "1", #@ "net.ipv6.conf.default.accept_ra_defrtr": "1", #@ "net.ipv6.conf.default.accept_ra_pinfo": "1", #@ "net.ipv6.conf.default.accept_ra_rt_info_max_plen": "0", #@ "net.ipv6.conf.default.accept_ra_rtr_pref": "1", #@ "net.ipv6.conf.default.accept_redirects": "1", #@ "net.ipv6.conf.default.accept_source_route": "0", #@ "net.ipv6.conf.default.autoconf": "1", #@ "net.ipv6.conf.default.dad_transmits": "1", #@ "net.ipv6.conf.default.disable_ipv6": "0", #@ "net.ipv6.conf.default.enhanced_dad": "1", #@ "net.ipv6.conf.default.force_mld_version": "0", #@ "net.ipv6.conf.default.force_tllao": "0", #@ "net.ipv6.conf.default.forwarding": "0", #@ "net.ipv6.conf.default.hop_limit": "64", #@ "net.ipv6.conf.default.keep_addr_on_down": "0", #@ "net.ipv6.conf.default.max_addresses": "16", #@ "net.ipv6.conf.default.max_desync_factor": "600", #@ "net.ipv6.conf.default.mc_forwarding": "0", #@ "net.ipv6.conf.default.mldv1_unsolicited_report_interval": "10000", #@ "net.ipv6.conf.default.mldv2_unsolicited_report_interval": "1000", #@ "net.ipv6.conf.default.mtu": "1280", #@ "net.ipv6.conf.default.ndisc_notify": "0", #@ "net.ipv6.conf.default.optimistic_dad": "0", #@ "net.ipv6.conf.default.proxy_ndp": "0", #@ "net.ipv6.conf.default.regen_max_retry": "3", #@ "net.ipv6.conf.default.router_probe_interval": "60", #@ "net.ipv6.conf.default.router_solicitation_delay": "1", #@ "net.ipv6.conf.default.router_solicitation_interval": "4", #@ "net.ipv6.conf.default.router_solicitations": "3", #@ "net.ipv6.conf.default.temp_prefered_lft": "86400", #@ "net.ipv6.conf.default.temp_valid_lft": "604800", #@ "net.ipv6.conf.default.use_optimistic": "0", #@ "net.ipv6.conf.default.use_tempaddr": "0", #@ "net.ipv6.conf.eth0.accept_dad": "1", #@ "net.ipv6.conf.eth0.accept_ra": "1", #@ "net.ipv6.conf.eth0.accept_ra_defrtr": "1", #@ "net.ipv6.conf.eth0.accept_ra_pinfo": "1", #@ "net.ipv6.conf.eth0.accept_ra_rt_info_max_plen": "0", #@ "net.ipv6.conf.eth0.accept_ra_rtr_pref": "1", #@ "net.ipv6.conf.eth0.accept_redirects": "1", #@ "net.ipv6.conf.eth0.accept_source_route": "0", #@ "net.ipv6.conf.eth0.autoconf": "1", #@ "net.ipv6.conf.eth0.dad_transmits": "1", #@ "net.ipv6.conf.eth0.disable_ipv6": "0", #@ "net.ipv6.conf.eth0.enhanced_dad": "1", #@ "net.ipv6.conf.eth0.force_mld_version": "0", #@ "net.ipv6.conf.eth0.force_tllao": "0", #@ "net.ipv6.conf.eth0.forwarding": "0", #@ "net.ipv6.conf.eth0.hop_limit": "64", #@ "net.ipv6.conf.eth0.keep_addr_on_down": "0", #@ "net.ipv6.conf.eth0.max_addresses": "16", #@ "net.ipv6.conf.eth0.max_desync_factor": "600", #@ "net.ipv6.conf.eth0.mc_forwarding": "0", #@ "net.ipv6.conf.eth0.mldv1_unsolicited_report_interval": "10000", #@ "net.ipv6.conf.eth0.mldv2_unsolicited_report_interval": "1000", #@ "net.ipv6.conf.eth0.mtu": "1500", #@ "net.ipv6.conf.eth0.ndisc_notify": "0", #@ "net.ipv6.conf.eth0.optimistic_dad": "0", #@ "net.ipv6.conf.eth0.proxy_ndp": "0", #@ "net.ipv6.conf.eth0.regen_max_retry": "3", #@ "net.ipv6.conf.eth0.router_probe_interval": "60", #@ "net.ipv6.conf.eth0.router_solicitation_delay": "1", #@ "net.ipv6.conf.eth0.router_solicitation_interval": "4", #@ "net.ipv6.conf.eth0.router_solicitations": "3", #@ "net.ipv6.conf.eth0.temp_prefered_lft": "86400", #@ "net.ipv6.conf.eth0.temp_valid_lft": "604800", #@ "net.ipv6.conf.eth0.use_optimistic": "0", #@ "net.ipv6.conf.eth0.use_tempaddr": "0", #@ "net.ipv6.conf.eth1.accept_dad": "1", #@ "net.ipv6.conf.eth1.accept_ra": "0", #@ "net.ipv6.conf.eth1.accept_ra_defrtr": "0", #@ "net.ipv6.conf.eth1.accept_ra_pinfo": "0", #@ "net.ipv6.conf.eth1.accept_ra_rt_info_max_plen": "0", #@ "net.ipv6.conf.eth1.accept_ra_rtr_pref": "0", #@ "net.ipv6.conf.eth1.accept_redirects": "1", #@ "net.ipv6.conf.eth1.accept_source_route": "0", #@ "net.ipv6.conf.eth1.autoconf": "1", #@ "net.ipv6.conf.eth1.dad_transmits": "1", #@ "net.ipv6.conf.eth1.disable_ipv6": "0", #@ "net.ipv6.conf.eth1.enhanced_dad": "1", #@ "net.ipv6.conf.eth1.force_mld_version": "0", #@ "net.ipv6.conf.eth1.force_tllao": "0", #@ "net.ipv6.conf.eth1.forwarding": "0", #@ "net.ipv6.conf.eth1.hop_limit": "64", #@ "net.ipv6.conf.eth1.keep_addr_on_down": "0", #@ "net.ipv6.conf.eth1.max_addresses": "16", #@ "net.ipv6.conf.eth1.max_desync_factor": "600", #@ "net.ipv6.conf.eth1.mc_forwarding": "0", #@ "net.ipv6.conf.eth1.mldv1_unsolicited_report_interval": "10000", #@ "net.ipv6.conf.eth1.mldv2_unsolicited_report_interval": "1000", #@ "net.ipv6.conf.eth1.mtu": "1500", #@ "net.ipv6.conf.eth1.ndisc_notify": "0", #@ "net.ipv6.conf.eth1.optimistic_dad": "0", #@ "net.ipv6.conf.eth1.proxy_ndp": "0", #@ "net.ipv6.conf.eth1.regen_max_retry": "3", #@ "net.ipv6.conf.eth1.router_probe_interval": "60", #@ "net.ipv6.conf.eth1.router_solicitation_delay": "1", #@ "net.ipv6.conf.eth1.router_solicitation_interval": "4", #@ "net.ipv6.conf.eth1.router_solicitations": "3", #@ "net.ipv6.conf.eth1.temp_prefered_lft": "86400", #@ "net.ipv6.conf.eth1.temp_valid_lft": "604800", #@ "net.ipv6.conf.eth1.use_optimistic": "0", #@ "net.ipv6.conf.eth1.use_tempaddr": "0", #@ "net.ipv6.conf.lo.accept_dad": "-1", #@ "net.ipv6.conf.lo.accept_ra": "1", #@ "net.ipv6.conf.lo.accept_ra_defrtr": "1", #@ "net.ipv6.conf.lo.accept_ra_pinfo": "1", #@ "net.ipv6.conf.lo.accept_ra_rt_info_max_plen": "0", #@ "net.ipv6.conf.lo.accept_ra_rtr_pref": "1", #@ "net.ipv6.conf.lo.accept_redirects": "1", #@ "net.ipv6.conf.lo.accept_source_route": "0", #@ "net.ipv6.conf.lo.autoconf": "1", #@ "net.ipv6.conf.lo.dad_transmits": "1", #@ "net.ipv6.conf.lo.disable_ipv6": "0", #@ "net.ipv6.conf.lo.enhanced_dad": "1", #@ "net.ipv6.conf.lo.force_mld_version": "0", #@ "net.ipv6.conf.lo.force_tllao": "0", #@ "net.ipv6.conf.lo.forwarding": "0", #@ "net.ipv6.conf.lo.hop_limit": "64", #@ "net.ipv6.conf.lo.keep_addr_on_down": "0", #@ "net.ipv6.conf.lo.max_addresses": "16", #@ "net.ipv6.conf.lo.max_desync_factor": "600", #@ "net.ipv6.conf.lo.mc_forwarding": "0", #@ "net.ipv6.conf.lo.mldv1_unsolicited_report_interval": "10000", #@ "net.ipv6.conf.lo.mldv2_unsolicited_report_interval": "1000", #@ "net.ipv6.conf.lo.mtu": "65536", #@ "net.ipv6.conf.lo.ndisc_notify": "0", #@ "net.ipv6.conf.lo.optimistic_dad": "0", #@ "net.ipv6.conf.lo.proxy_ndp": "0", #@ "net.ipv6.conf.lo.regen_max_retry": "3", #@ "net.ipv6.conf.lo.router_probe_interval": "60", #@ "net.ipv6.conf.lo.router_solicitation_delay": "1", #@ "net.ipv6.conf.lo.router_solicitation_interval": "4", #@ "net.ipv6.conf.lo.router_solicitations": "3", #@ "net.ipv6.conf.lo.temp_prefered_lft": "86400", #@ "net.ipv6.conf.lo.temp_valid_lft": "604800", #@ "net.ipv6.conf.lo.use_optimistic": "0", #@ "net.ipv6.conf.lo.use_tempaddr": "-1", #@ "net.ipv6.fwmark_reflect": "0", #@ "net.ipv6.icmp.ratelimit": "1000", #@ "net.ipv6.idgen_delay": "1", #@ "net.ipv6.idgen_retries": "3", #@ "net.ipv6.ip6frag_high_thresh": "4194304", #@ "net.ipv6.ip6frag_low_thresh": "3145728", #@ "net.ipv6.ip6frag_secret_interval": "600", #@ "net.ipv6.ip6frag_time": "60", #@ "net.ipv6.ip_nonlocal_bind": "0", #@ "net.ipv6.mld_max_msf": "64", #@ "net.ipv6.mld_qrv": "2", #@ "net.ipv6.neigh.default.anycast_delay": "100", #@ "net.ipv6.neigh.default.app_solicit": "0", #@ "net.ipv6.neigh.default.base_reachable_time": "30", #@ "net.ipv6.neigh.default.base_reachable_time_ms": "30000", #@ "net.ipv6.neigh.default.delay_first_probe_time": "5", #@ "net.ipv6.neigh.default.gc_interval": "30", #@ "net.ipv6.neigh.default.gc_stale_time": "60", #@ "net.ipv6.neigh.default.gc_thresh1": "128", #@ "net.ipv6.neigh.default.gc_thresh2": "512", #@ "net.ipv6.neigh.default.gc_thresh3": "1024", #@ "net.ipv6.neigh.default.locktime": "0", #@ "net.ipv6.neigh.default.mcast_solicit": "3", #@ "net.ipv6.neigh.default.proxy_delay": "80", #@ "net.ipv6.neigh.default.proxy_qlen": "64", #@ "net.ipv6.neigh.default.retrans_time": "1000", #@ "net.ipv6.neigh.default.retrans_time_ms": "1000", #@ "net.ipv6.neigh.default.ucast_solicit": "3", #@ "net.ipv6.neigh.default.unres_qlen": "31", #@ "net.ipv6.neigh.default.unres_qlen_bytes": "65536", #@ "net.ipv6.neigh.eth0.anycast_delay": "100", #@ "net.ipv6.neigh.eth0.app_solicit": "0", #@ "net.ipv6.neigh.eth0.base_reachable_time": "30", #@ "net.ipv6.neigh.eth0.base_reachable_time_ms": "30000", #@ "net.ipv6.neigh.eth0.delay_first_probe_time": "5", #@ "net.ipv6.neigh.eth0.gc_stale_time": "60", #@ "net.ipv6.neigh.eth0.locktime": "0", #@ "net.ipv6.neigh.eth0.mcast_solicit": "3", #@ "net.ipv6.neigh.eth0.proxy_delay": "80", #@ "net.ipv6.neigh.eth0.proxy_qlen": "64", #@ "net.ipv6.neigh.eth0.retrans_time": "1000", #@ "net.ipv6.neigh.eth0.retrans_time_ms": "1000", #@ "net.ipv6.neigh.eth0.ucast_solicit": "3", #@ "net.ipv6.neigh.eth0.unres_qlen": "31", #@ "net.ipv6.neigh.eth0.unres_qlen_bytes": "65536", #@ "net.ipv6.neigh.eth1.anycast_delay": "100", #@ "net.ipv6.neigh.eth1.app_solicit": "0", #@ "net.ipv6.neigh.eth1.base_reachable_time": "30", #@ "net.ipv6.neigh.eth1.base_reachable_time_ms": "30000", #@ "net.ipv6.neigh.eth1.delay_first_probe_time": "5", #@ "net.ipv6.neigh.eth1.gc_stale_time": "60", #@ "net.ipv6.neigh.eth1.locktime": "0", #@ "net.ipv6.neigh.eth1.mcast_solicit": "3", #@ "net.ipv6.neigh.eth1.proxy_delay": "80", #@ "net.ipv6.neigh.eth1.proxy_qlen": "64", #@ "net.ipv6.neigh.eth1.retrans_time": "1000", #@ "net.ipv6.neigh.eth1.retrans_time_ms": "1000", #@ "net.ipv6.neigh.eth1.ucast_solicit": "3", #@ "net.ipv6.neigh.eth1.unres_qlen": "31", #@ "net.ipv6.neigh.eth1.unres_qlen_bytes": "65536", #@ "net.ipv6.neigh.lo.anycast_delay": "100", #@ "net.ipv6.neigh.lo.app_solicit": "0", #@ "net.ipv6.neigh.lo.base_reachable_time": "30", #@ "net.ipv6.neigh.lo.base_reachable_time_ms": "30000", #@ "net.ipv6.neigh.lo.delay_first_probe_time": "5", #@ "net.ipv6.neigh.lo.gc_stale_time": "60", #@ "net.ipv6.neigh.lo.locktime": "0", #@ "net.ipv6.neigh.lo.mcast_solicit": "3", #@ "net.ipv6.neigh.lo.proxy_delay": "80", #@ "net.ipv6.neigh.lo.proxy_qlen": "64", #@ "net.ipv6.neigh.lo.retrans_time": "1000", #@ "net.ipv6.neigh.lo.retrans_time_ms": "1000", #@ "net.ipv6.neigh.lo.ucast_solicit": "3", #@ "net.ipv6.neigh.lo.unres_qlen": "31", #@ "net.ipv6.neigh.lo.unres_qlen_bytes": "65536", #@ "net.ipv6.route.gc_elasticity": "9", #@ "net.ipv6.route.gc_interval": "30", #@ "net.ipv6.route.gc_min_interval": "0", #@ "net.ipv6.route.gc_min_interval_ms": "500", #@ "net.ipv6.route.gc_thresh": "1024", #@ "net.ipv6.route.gc_timeout": "60", #@ "net.ipv6.route.max_size": "16384", #@ "net.ipv6.route.min_adv_mss": "1220", #@ "net.ipv6.route.mtu_expires": "600", #@ "net.ipv6.xfrm6_gc_thresh": "32768", #@ "net.netfilter.nf_log.0": "NONE", #@ "net.netfilter.nf_log.1": "NONE", #@ "net.netfilter.nf_log.10": "NONE", #@ "net.netfilter.nf_log.11": "NONE", #@ "net.netfilter.nf_log.12": "NONE", #@ "net.netfilter.nf_log.2": "NONE", #@ "net.netfilter.nf_log.3": "NONE", #@ "net.netfilter.nf_log.4": "NONE", #@ "net.netfilter.nf_log.5": "NONE", #@ "net.netfilter.nf_log.6": "NONE", #@ "net.netfilter.nf_log.7": "NONE", #@ "net.netfilter.nf_log.8": "NONE", #@ "net.netfilter.nf_log.9": "NONE", #@ "net.netfilter.nf_log_all_netns": "0", #@ "net.unix.max_dgram_qlen": "512", #@ "sunrpc.max_resvport": "1023", #@ "sunrpc.min_resvport": "665", #@ "sunrpc.nfs_debug": "0x0000", #@ "sunrpc.nfsd_debug": "0x0000", #@ "sunrpc.nlm_debug": "0x0000", #@ "sunrpc.rpc_debug": "0x0000", #@ "sunrpc.tcp_fin_timeout": "15", #@ "sunrpc.tcp_max_slot_table_entries": "65536", #@ "sunrpc.tcp_slot_table_entries": "2", #@ "sunrpc.transports": "tcp 1048576\nudp 32768", #@ "sunrpc.udp_slot_table_entries": "16", #@ "user.max_ipc_namespaces": "1888", #@ "user.max_mnt_namespaces": "1888", #@ "user.max_net_namespaces": "1888", #@ "user.max_pid_namespaces": "1888", #@ "user.max_user_namespaces": "0", #@ "user.max_uts_namespaces": "1888", #@ "vm.admin_reserve_kbytes": "8192", #@ "vm.block_dump": "0", #@ "vm.dirty_background_bytes": "0", #@ "vm.dirty_background_ratio": "10", #@ "vm.dirty_bytes": "0", #@ "vm.dirty_expire_centisecs": "3000", #@ "vm.dirty_ratio": "30", #@ "vm.dirty_writeback_centisecs": "500", #@ "vm.drop_caches": "0", #@ "vm.extfrag_threshold": "500", #@ "vm.hugepages_treat_as_movable": "0", #@ "vm.hugetlb_shm_group": "0", #@ "vm.laptop_mode": "0", #@ "vm.legacy_va_layout": "0", #@ "vm.lowmem_reserve_ratio": "256\t256\t32", #@ "vm.max_map_count": "65530", #@ "vm.memory_failure_early_kill": "0", #@ "vm.memory_failure_recovery": "1", #@ "vm.min_free_kbytes": "2816", #@ "vm.min_slab_ratio": "5", #@ "vm.min_unmapped_ratio": "1", #@ "vm.mmap_min_addr": "4096", #@ "vm.mmap_rnd_bits": "28", #@ "vm.mmap_rnd_compat_bits": "8", #@ "vm.nr_hugepages": "0", #@ "vm.nr_hugepages_mempolicy": "0", #@ "vm.nr_overcommit_hugepages": "0", #@ "vm.nr_pdflush_threads": "0", #@ "vm.numa_zonelist_order": "default", #@ "vm.oom_dump_tasks": "1", #@ "vm.oom_kill_allocating_task": "0", #@ "vm.overcommit_kbytes": "0", #@ "vm.overcommit_memory": "0", #@ "vm.overcommit_ratio": "50", #@ "vm.page-cluster": "3", #@ "vm.panic_on_oom": "0", #@ "vm.percpu_pagelist_fraction": "0", #@ "vm.stat_interval": "1", #@ "vm.swappiness": "30", #@ "vm.user_reserve_kbytes": "14160", #@ "vm.vfs_cache_pressure": "100", #@ "vm.zone_reclaim_mode": "0" #@ } #@ ``` #+end_src cfengine-3.24.2/examples/global_list_expansion_2.cf0000644000000000000000000000303115010704253022300 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Show access of external lists. # body common control { bundlesequence => { hardening }; } ######################################################### bundle common va { vars: "tmpdirs" slist => { "/tmp", "/var/tmp", "/usr/tmp" }; } ########################################################## bundle agent hardening { classes: "ok" expression => "any"; vars: "other" slist => { "/tmp", "/var/tmp" }; "x" slist => { @(va.tmpdirs) }; reports: ok:: "Do $(x)"; "Other: $(other)"; } cfengine-3.24.2/examples/string_upcase.cf0000644000000000000000000000255515010704253020360 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "upcase" string => string_upcase("abc"); # will contain "ABC" reports: "upcased abc: $(upcase)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: upcased abc: ABC #@ ``` #+end_src cfengine-3.24.2/examples/mustache_template_motd.cf0000644000000000000000000001043115010704253022231 0ustar00rootroot00000000000000bundle agent env_classification # @brief Classify environment { vars: # We use presence of key files to know the hosts environment "environment_semaphores" slist => { "/etc/prod", "/etc/staging" }; "environment" string => ifelse( filesexist( @(environment_semaphores) ), "incoherent", fileexists("/etc/prod"), "production", fileexists("/etc/staging"), "staging", "unknown" ); "env_issue_msg" string => ifelse( strcmp( "incoherent", $(environment) ), "WARNING: Environment incoherent (multiple environment semaphores)", strcmp( "unknown", $(environment) ), "WARNING: Environment unknown (missing environment semaphores)", "Host environment classified as $(environment)"); # This is to extract the cfengine role ( hub or client ) "cf_role" string => ifelse( "policy_server", "Policy Server", "Policy Client"); classes: # We define a class for the selected environment. It's useful for making # decisions in other policies "env_$(environment)" expression => "any", scope => "namespace"; } bundle agent env_info # @brief Relevant environment information { vars: ## Based on the environment we define different contacts. "admin_contact" slist => { "admin@acme.com", "oncall@acme.com" }, if => strcmp( $(env_classification.environment), "production" ); "admin_contact" slist => { "dev@acme.com" }, if => strcmp( $(env_classification.environment), "staging" ); "admin_contact" slist => { "root@localhost" }, if => strcmp( $(env_classification.environment), "unknown" ); ## This is to extract the available package updates status "updates_available" data => packageupdatesmatching(".*", ".*", ".*", ".*"); "count_updates" int => length("updates_available"); classes: # We define a class indicating there are updates available, it might be # useful for various different policies. "have_updates_available" expression => isgreaterthan( $(count_updates), 0), scope => "namespace"; } bundle agent motd { vars: "motd_path" string => "/etc/motd"; # It's considered best practice to prepare a data container holding the # information you need to render the template instead of relying on # current datastate() # First we extract currently defined classes from datastate(), then we # construct the template data. "_state" data => datastate(), if => not( isvariable ( $(this.promiser) ) ); # Limit recursive growth # and multiple calls to # datastate() over # multiple passes. "template_data" data => mergedata('{ "fqhost": "$(sys.fqhost)", "primary_ip": "$(sys.ipv4)", "cf_version": "$(sys.cf_version)", "issue_msg": "$(env_classification.env_issue_msg)", "cf_role": "$(env_classification.cf_role)", "count_updates": "$(env_info.count_updates)", "contacts": env_info.admin_contact, "classes": _state[classes] }'); files: "$(motd_path)" create => "true", template_method => "inline_mustache", template_data => @(template_data), edit_template_string => '# Managed by CFEngine {{{issue_msg}}} *** *** Welcome to {{{fqhost}}} *** * *** * CFEngine Role: {{{cf_role}}} * *** * CFEngine Version:{{{cf_version}}} * *** * * * Host IP: {{{primary_ip}}} *** {{#classes.have_updates_available}}{{{count_updates}}} package updates available.{{/classes.have_updates_available}}{{^classes.have_updates_available}}No package updates available or status unknown.{{/classes.have_updates_available}} * * * * * * For support contact:{{#contacts}} - {{{.}}}{{/contacts}}$(const.n)'; } bundle agent __main__ { methods: "env_classification"; "env_info"; "motd"; } cfengine-3.24.2/examples/backreferences_files.cf0000644000000000000000000000360415010704253021632 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # File editing - back reference # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "example" }; } ######################################################## bundle agent example { files: # The back reference in a path only applies to the last link # of the pathname, so the (tmp) gets ignored "/tmp/(cf3)_(.*)" edit_line => myedit("second $(match.2)"); # but ... # "/tmp/cf3_test" # create => "true", # edit_line => myedit("second $(match.1)"); } ######################################################## bundle edit_line myedit(parameter) { vars: "edit_variable" string => "private edit variable is $(parameter)"; insert_lines: "$(edit_variable)"; } cfengine-3.24.2/examples/orchestrate_n_of_m.cf0000644000000000000000000000256515010704253021353 0ustar00rootroot00000000000000############################################################ # # Keep a special promise only if at least n or m hosts # keep a specific promise # # This method works with Enterprise CFEngine # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # ############################################################ body common control { bundlesequence => { "n_of_m_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################################ bundle agent n_of_m_symphony { vars: "count_compliant_hosts" string => hubknowledge("running_myprocess"); classes: "reboot" expression => isgreaterthan("$(count_compliant_hosts)","20"); processes: "myprocess" comment => "Count this host if a job is matched", classes => enumerate("running_myprocess"); commands: reboot:: "/bin/shutdown now"; } ####################################################### bundle server access_rules() { access: "value of my test_scalar, can expand variables here - $(sys.host)" handle => "test_scalar", comment => "Grant access to contents of test_scalar VAR", resource_type => "literal", admit => { "127.0.0.1" }; "running_myprocess" resource_type => "variable", admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/regex_replace.cf0000644000000000000000000000432115010704253020310 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent main { vars: # global regex replace A with B "AB" string => regex_replace("This has AAA rating", "A", "B", "g"); # global regex replace [Aa] with B (case insensitive) "AaB" string => regex_replace("This has AAA rating", "A", "B", "gi"); # global replace every three characters with [cap=thecharacters] using $1 "cap123" string => regex_replace("abcdefghijklmn", "(...)", "[cap=$1]", "g"); # multiple captures using \1 \2 (just like $1 $2 but can only go up to \9) "path_breakdown" string => regex_replace("/a/b/c/example.txt", "(.+)/(.+)", "dirname = \1 file basename = \2", ""); reports: # in order, the above... "AB replacement = '$(AB)'"; "AaB replacement = '$(AaB)'"; "cap123 replacement = '$(cap123)'"; "path_breakdown replacement = '$(path_breakdown)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: AB replacement = 'This has BBB rating' #@ R: AaB replacement = 'This hBs BBB rBting' #@ R: cap123 replacement = '[cap=abc][cap=def][cap=ghi][cap=jkl]mn' #@ R: path_breakdown replacement = 'dirname = /a/b/c file basename = example.txt' #@ ``` #+end_src cfengine-3.24.2/examples/string_tail.cf0000644000000000000000000000254715010704253020032 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "end" string => string_tail("abc", "1"); # will contain "c" reports: "end of abc = $(end)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: end of abc = c #@ ``` #+end_src cfengine-3.24.2/examples/product.cf0000644000000000000000000000272115010704253017165 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "series" rlist => { "1.1", "2.2", "3.3", "5.5", "7.7" }; "prod" real => product("series"); "sum" real => sum("series"); reports: "Product result: $(prod) > $(sum)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Product result: 338.207100 > 19.800000 #@ ``` #+end_src cfengine-3.24.2/examples/arrays.cf0000644000000000000000000000176515010704253017015 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle common g { vars: "array[key1]" string => "one"; "array[key2]" string => "two"; } bundle agent __main__ { vars: "thing[1][color]" string => "red"; "thing[1][name]" string => "one"; "thing[2][color]" string => "blue"; "thing[2][name]" string => "two"; "_thing_idx" slist => sort( getindices( thing ), lex ); reports: "Keys in default:g.array = $(with)" with => join( ", ", sort( getindices( "default:g.array" ), lex)); "Keys of default:main.thing[1] = $(with)" with => join( ", ", sort( getindices( "default:main.thing[1]" ), lex)); "Thing $(thing[$(_thing_idx)][name]) is $(thing[$(_thing_idx)][color])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Keys in default:g.array = key1, key2 #@ R: Keys of default:main.thing[1] = color, name #@ R: Thing one is red #@ R: Thing two is blue #@ ``` #+end_src cfengine-3.24.2/examples/users_type.cf0000644000000000000000000000174115010704253017710 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.libdir)/stdlib.cf" }; } ### Users main BEGIN ### bundle agent main { vars: "users" slist => { "jack", "john" }; "skel" string => "/etc/skel"; users: !windows:: "$(users)" policy => "present", home_dir => "/home/$(users)", home_bundle => home_skel($(users), $(skel)); } ### Users main END ### ### Home Bundle BEGIN ### bundle agent home_skel(user, skel) # @brief Initialize a user's home directory with the contents of skel # @param user The user's home directory to create # @param skel The directory to seed the user's home with { files: "/home/$(user)/." create => "true", copy_from => seed_cp($(skel)), depth_search => recurse("inf"); } ### Home Bundle END ### ### Locked User BEGIN ### bundle agent service_accounts { vars: "users" slist => { "apache", "libuuid" }; users: !windows:: "$(users)" policy => "locked"; } ### Locked User END ### cfengine-3.24.2/examples/package_windows_feature.cf0000644000000000000000000000235715010704253022372 0ustar00rootroot00000000000000body common control { bundlesequence => { "example" }; } bundle agent example { packages: Windows_Server_2008_R2:: "Telnet-Client" comment => "Install the telnet client", package_policy => "add", package_method => windows_feature; } body package_method windows_feature # NOTE: Windows feature names are case-sensitive { package_changes => "individual"; package_name_convention => "$(name)"; package_delete_convention => "$(name)"; package_installed_regex => ".*"; package_list_name_regex => "(.*)"; package_list_version_regex => "(.*)"; # FIXME: the listing does not give version, so takes name for version too now package_add_command => "$(sys.winsysdir)\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"Import-Module ServerManager; Add-WindowsFeature -Name\""; package_delete_command => "$(sys.winsysdir)\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"Import-Module ServerManager; Remove-WindowsFeature -confirm:$false -Name\""; package_list_command => "$(sys.winsysdir)\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"Import-Module ServerManager; Get-WindowsFeature | where {$_.installed -eq $True} |foreach {$_.Name}\""; } cfengine-3.24.2/examples/intersection.cf0000644000000000000000000000367315010704253020222 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "a" slist => { 1,2,3,"x" }; "b" slist => { "x" }; "mylist1" slist => { "a", "b" }; "mylist2" slist => { "a", "b" }; "$(mylist1)_str" string => join(",", $(mylist1)); "int_$(mylist1)_$(mylist2)" slist => intersection($(mylist1), $(mylist2)); "int_$(mylist1)_$(mylist2)_str" string => join(",", "int_$(mylist1)_$(mylist2)"); reports: "The intersection of list '$($(mylist1)_str)' with '$($(mylist2)_str)' is '$(int_$(mylist1)_$(mylist2)_str)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The intersection of list '1,2,3,x' with '1,2,3,x' is '1,2,3,x' #@ R: The intersection of list '1,2,3,x' with 'x' is 'x' #@ R: The intersection of list 'x' with '1,2,3,x' is 'x' #@ R: The intersection of list 'x' with 'x' is 'x' #@ ``` #+end_src cfengine-3.24.2/examples/win_emergency.cf0000644000000000000000000000370015010704253020336 0ustar00rootroot00000000000000######################################################################### # # win_emergency.cf - Emergency Policy To Close Potential Security Holes # # NOTE: The class "emergency" may be set automatically by Cfengine # based on some criteria, or it may be explicitly set by a remote # execution of cf-agent through cf-runagent (if this is allowed # by the server control policy). # ######################################################################### body common control { bundlesequence => { "win_emergency" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent win_emergency { vars: "disable_services" slist => { "RemoteRegistry" # Windows Remote Management }; "secure_files" slist => { "C:\Secret", "$(sys.workdir)\secret.txt" }; "close_ports" slist => { "6510", "9300" }; commands: emergency:: "\"$(sys.winsysdir)\netsh.exe\"" args => "firewall add portopening ALL $(close_ports) \"Port $(close_ports)\" DISABLE", comment => "Close firewall ports on emergency"; databases: emergency:: "HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\Cfengine" database_operation => "create", database_rows => { "emergency,REG_SZ,This is an emergency!" } , database_type => "ms_registry", comment => "Create emergency policy registry settings"; files: emergency:: "$(secure_files)" acl => strict, comment => "Secure important file access on emergency"; services: emergency:: "$(disable_services)" service_policy => "disable", comment => "Disable security-relevant services on emergency"; } cfengine-3.24.2/examples/mustache_variables.cf0000644000000000000000000000100115010704253021334 0ustar00rootroot00000000000000# Example showing how sections are rendered. #+begin_src cfengine3 bundle agent main { vars: "data" data => '{ "key": "Hello World & 3>2!" }'; reports: "$(with)" with => string_mustache( "{{key}} {{{key}}} {{&key}} Missing '{{missing}}' varibles render empty strings.", data); } #+end_src #+begin_src example_output #@ ``` #@ R: Hello World & 3>2! #@ Hello World & 3>2! #@ Hello World & 3>2! #@ Missing '' varibles render empty strings. #@ ``` #+end_src cfengine-3.24.2/examples/package_bundles.cf0000644000000000000000000000570215010704253020616 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # #+begin_src cfengine3 body common control { inputs => { "$(sys.libdir)/packages.cf" }; bundlesequence => { "runme" }; } bundle agent runme { methods: "nozip" usebundle => package_absent("zip"); # delete "pleasezip" usebundle => package_present("zip"); # add "latestzip" usebundle => package_latest("zip"); # add/update # add a package from a file with a specific selection method, # version, and architecture "addfilezip" usebundle => package_specific_present("/mydir/zip.deb-or-rpm", "3.0-7", ifelse("debian", "amd64", "x86_64")); # add a package with a specific selection method, version, and # architecture "addzip" usebundle => package_specific_present("zip", ifelse("redhat", "3.0-7", "2.99"), ifelse("debian", "amd64", "x86_64")); # add or update a package from a file with a specific selection # method, version, and architecture "upgradefilezip" usebundle => package_specific_latest("/mydir/zip.deb-or-rpm", "3.0-7", ifelse("debian", "amd64", "x86_64")); # add or update a package with a specific selection method, # version, and architecture "upgradezip" usebundle => package_specific_latest("zip", "3.0-7", ifelse("debian", "amd64", "x86_64")); } #+end_src cfengine-3.24.2/examples/sql_table_structure.cf0000644000000000000000000000201715010704253021571 0ustar00rootroot00000000000000# # Database promises are introduced in CFEngine Community edition 3.3.0 # body common control { bundlesequence => { "databases" }; } bundle agent databases { databases: "cfengine_db/users" database_operation => "create", database_type => "sql", database_columns => { "username,varchar,50", "password,varchar,80", "email,varchar,20", }, database_server => local_mysql("root", ""); } body database_server local_mysql(username, password) { db_server_owner => "$(username)"; db_server_password => "$(password)"; db_server_host => "localhost"; db_server_type => "mysql"; db_server_connection_db => "mysql"; } body database_server local_postgresql(username, password) { db_server_owner => "$(username)"; db_server_password => "$(password)"; db_server_host => "localhost"; db_server_type => "postgres"; db_server_connection_db => "postgres"; } cfengine-3.24.2/examples/returnszero.cf0000644000000000000000000000314015010704253020103 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "my_result" expression => returnszero("/usr/local/bin/mycommand","noshell"); reports: !my_result:: "Command failed"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ 2014-08-18T14:13:28+0100 error: Proposed executable file '/usr/local/bin/mycommand' doesn't exist #@ 2014-08-18T14:13:28+0100 error: returnszero '/usr/local/bin/mycommand' is assumed to be executable but isn't #@ R: Command failed #@ ``` #+end_src cfengine-3.24.2/examples/edit_triggerclass.cf0000644000000000000000000000431215010704253021201 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Insert a number of lines and trigger a followup if edited # ####################################################### body common control { any:: bundlesequence => { "insert" }; } ####################################################### bundle agent insert { vars: "v" string => " One potato Two potato Three potahto Four "; files: "/tmp/test_insert" edit_line => Insert("$(insert.v)"), edit_defaults => empty, classes => trigger("edited"); commands: edited:: "/bin/echo make bananas"; reports: edited:: "The potatoes are bananas"; } ####################################################### # For the library ####################################################### bundle edit_line Insert(name) { insert_lines: "Begin$(const.n) $(name)$(const.n)End"; } ####################################################### body edit_defaults empty { empty_file_before_editing => "true"; } ####################################################### body classes trigger(x) { promise_repaired => { "$(x)" }; } cfengine-3.24.2/examples/version_compare.cf0000644000000000000000000000077515010704253020707 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This will be skipped because the version comparison is false" if => version_compare("3.21.0", "<", "3.20.99"); "This will be printed because the version comparison is true" if => version_compare("3.24.1", ">=", "3.24.1"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This will be printed because the version comparison is true #@ ``` #+end_src cfengine-3.24.2/examples/regextract.cf0000644000000000000000000000327415010704253017661 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: # Extract regex backreferences and put them in an array "ok" expression => regextract( "xx ([^\s]+) ([^\s]+).* xx", "xx one two three four xx", "myarray" ); reports: ok:: "ok - \"$(myarray[0])\" = xx + \"$(myarray[1])\" + \"$(myarray[2])\" + .. + xx"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: ok - "xx one two three four xx" = xx + "one" + "two" + .. + xx #@ ``` #+end_src cfengine-3.24.2/examples/package_solaris.cf0000644000000000000000000000333615010704253020637 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Package management # body common control { bundlesequence => { "packages" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################# bundle agent packages { vars: "solaris_packages[SMCzlib]" string => "zlib-1.2.3-sol10-sparc-local"; "admin_file" string => "cfengine_admin_file"; "package_names" slist => getindices("solaris_packages"); files: "/tmp/$(admin_file)" create => "true", edit_defaults => empty, edit_line => create_solaris_admin_file; packages: "$(package_names)" package_policy => "add", package_method => solaris("$(package_names)", "$(solaris_packages[$(package_names)])", "$(admin_file)"); } cfengine-3.24.2/examples/edit_passwd_file_basic.cf0000644000000000000000000000257715010704253022164 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "edit_passwd" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent edit_passwd { vars: "userset" slist => { "user1", "user2", "user3" }; files: "/etc/passwd" edit_line => set_user_field("mark","7","/set/this/shell"); "/etc/group" edit_line => append_user_field("root","4","@(main.userset)"); } cfengine-3.24.2/examples/create_filedir.cf0000644000000000000000000000373715010704253020456 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test create files # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/tmp/test_plain" #@ The promiser specifies the path and name of the file. perms => system, create => "true"; #@ The `perms` attribute sets the file permissions as defined in the `system` #@ body below. The `create` attribute makes sure that the files exists. If it #@ doesn't, CFEngine will create it. "/home/mark/tmp/test_dir/." perms => system, create => "true"; #@ The trailing `/.` in the filename tells CFEngine that the promiser is a #@ directory. } ######################################################### body perms system { mode => "0640"; } #@ This body sets permissions to "0640" ######################################################### cfengine-3.24.2/examples/control_expand.cf0000644000000000000000000000362615010704253020531 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. bundle common g { classes: "softclass" expression => "any"; vars: "bundle" slist => { "bundle1", "bundle2", @(g.extra) }; any:: # default extra "extra" slist => { "bundle3" }, policy => "overridable"; softclass:: "extra" slist => { "bundle3", "bundle4" }, policy => "overridable"; } ############################################################## body common control { bundlesequence => { @(g.bundle) }; } ############################################################## bundle agent bundle1 { vars: "var1" string => "anything"; "bundle" slist => { @(g.bundle) }; reports: "$(bundle)"; } bundle agent bundle2 { classes: "ok" expression => isvariable("bundle1.var1"); reports: ok:: "Success"; } bundle agent bundle3 { reports: "Success extra..."; } bundle agent bundle4 { reports: "Success extra more..."; } cfengine-3.24.2/examples/process_matching2.cf0000644000000000000000000000312415010704253021115 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test processes # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { processes: "sleep" process_count => up("sleep"); reports: sleep_out_of_control:: "Out of control"; } ######################################################## body process_count up(s) { match_range => "5,10"; # or irange("1","10"); out_of_range_define => { "$(s)_out_of_control" }; } cfengine-3.24.2/examples/pathtype.cf0000644000000000000000000000350115010704253017340 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple backgrounding # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/tmp" -> "me" changes => tripwire, pathtype => "literal", depth_search => recurse("inf"); } ######################################################### body changes tripwire { hash => "md5"; report_changes => "all"; update_hashes => "true"; } ######################################################### body action background { background => "true"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } cfengine-3.24.2/examples/mergedata-last-key-wins.cf0000644000000000000000000000134615010704253022145 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent mergedata_last_key_wins # @brief Example illustrating how the last key wins when merging data containers with conflicting keys { vars: "one" data => '{ "color": "red", "stuff": [ "one", "two" ], "thing": "one" }'; "two" data => '{ "color": "blue", "stuff": [ "three" ] }'; reports: "$(with)" with => storejson( mergedata( one, two ) ); } bundle agent __main__ { methods: "mergedata_last_key_wins"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: { #@ "color": "blue", #@ "stuff": [ #@ "three" #@ ], #@ "thing": "one" #@ } #@ ``` #+end_src cfengine-3.24.2/examples/fileperms.cf0000644000000000000000000000251415010704253017473 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "main" }; } ######################################################### bundle agent main { files: "/tmp/foo" perms => p("at","0750"); } ######################################################### body perms p(user,mode) { owners => { "$(user)" }; mode => "$(mode)"; } cfengine-3.24.2/examples/global_list_expansion.cf0000644000000000000000000000310015010704253022054 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Show access of external lists. # # - to pass lists globally, use a parameter to dereference them # body common control { bundlesequence => { hardening(@(va.tmpdirs)) }; } ######################################################### bundle common va { vars: "tmpdirs" slist => { "/tmp", "/var/tmp", "/usr/tmp" }; } ########################################################## bundle agent hardening(x) { classes: "ok" expression => "any"; vars: "other" slist => { "/tmp", "/var/tmp" }; reports: ok:: "Do $(x)"; "Other: $(other)"; } cfengine-3.24.2/examples/method_polymorph.cf0000644000000000000000000000106615010704253021077 0ustar00rootroot00000000000000# # Demonstrates the use of polymorphism to call bundles. # body common control { bundlesequence => { "example" }; } ########################################### bundle agent example { methods: "Patch Group" comment => "Apply OS specific patches and modifications", usebundle => "$(sys.class)_fix"; } ########################################### bundle agent linux_fix { reports: "Fixes for linux"; } ########################################### bundle agent solaris_android { reports: "Fixes for android"; } cfengine-3.24.2/examples/processes_define_class_based_on_process_runtime.cf0000644000000000000000000000366215010704253027352 0ustar00rootroot00000000000000######################################################## # # Simple process example # # Define a class if a process has been running for more # than one day # # For 3.6- run with cf-agent -KIf ./processes_define_class_based_on_process_runtime.cf -b main # For 3.7+ run with cf-agent -KIf ./processes_define_class_based_on_process_runtime.cf # - main is the default bundle executed if no bundlesequence is defined in # 3.7+ ######################################################## bundle agent main { processes: "init" process_count => any_count("booted_over_1_day_ago"), process_select => days_older_than(1), comment => "Define a class indicating we found an init process running for more than 1 day."; reports: booted_over_1_day_ago:: "This system was booted over 1 days ago since there is an init process that is older than 1 day."; !booted_over_1_day_ago:: "This system has been rebooted recently as the init process has been running for less than a day"; } ######################################################## ######################################################## # NOTE: These bundles were copied from the stdlib in # order to make this a standalone policy that requires # no external files. Because the standard library is # constantly evolving their definition may change ######################################################## body process_count any_count(cl) # @brief Define class `cl` if one or more process is running # @param cl Name of the class to be defined { match_range => "0,0"; out_of_range_define => { "$(cl)" }; } ######################################################## body process_select days_older_than(d) # @brief Select all processes that are older than `d` days # @param d Days that processes need to be old to be selected { stime_range => irange(ago(0,0,"$(d)",0,0,0),now); process_result => "!stime"; } cfengine-3.24.2/examples/varnet.cf0000644000000000000000000000046215010704253017004 0ustar00rootroot00000000000000 body common control { bundlesequence => { "example" }; } bundle agent example { reports: "My default interface and ip4 address is $(sys.interface) and $(sys.ipv4)"; "Can also extract $(sys.ipv4[Local_Area_Connection_3]), $(sys.ipv4_2[Wireless_Network_Connection])"; } cfengine-3.24.2/examples/main.cf0000644000000000000000000000054715010704253016435 0ustar00rootroot00000000000000# Example showing how the default bundlesequence runs bundle agent main bundle agent main # @brief main is the default bundlesequence { reports: "Hello, $(this.bundle) bundle."; } #@ The policy promises to report the name of the current bundle, and produces this output: #+begin_src example_output #@ ``` #@ R: Hello, main bundle. #@ ``` #+end_src cfengine-3.24.2/examples/getvariablemetatags.cf0000644000000000000000000000334315010704253021521 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "v" string => "myvalue", meta => { "mytag", "other=once", "other=twice" }; "vtags" slist => getvariablemetatags("example.v"); "othertag_values" slist => getvariablemetatags("example.v", "other"); reports: "Found tags: $(vtags)"; "Found tags for key 'other': $(othertag_values)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found tags: source=promise #@ R: Found tags: mytag #@ R: Found tags: other=once #@ R: Found tags: other=twice #@ R: Found tags for key 'other': once #@ R: Found tags for key 'other': twice #@ ``` #+end_src cfengine-3.24.2/examples/string_downcase.cf0000644000000000000000000000257115010704253020701 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "downcase" string => string_downcase("ABC"); # will contain "abc" reports: "downcased ABC = $(downcase)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: downcased ABC = abc #@ ``` #+end_src cfengine-3.24.2/examples/container_iteration.cf0000644000000000000000000000333115010704253021543 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { run }; } bundle agent run { vars: "x" data => parsejson('[ { "one": "a" }, { "two": "b" }, { "three": "c" } ]'); # get the numeric indices of x: 0, 1, 2 "xi" slist => getindices(x); # for each xi, make a variable xpiece_$(xi) so we'll have # xpiece_0, xpiece_1, xpiece_2. Each xpiece will have that # particular element of the list x. "xpiece_$(xi)" string => format("%S", "x[$(xi)]"); reports: "$(xi): $(xpiece_$(xi))"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: 0: {"one":"a"} #@ R: 1: {"two":"b"} #@ R: 2: {"three":"c"} #@ ``` #+end_src cfengine-3.24.2/examples/none.cf0000644000000000000000000000576615010704253016460 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "none11" expression => none("jebadiah", test1); "none12" expression => none("2", test1); "none21" expression => none("jebadiah", test2); "none22" expression => none("2", test2); vars: "test1" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "test2" data => parsejson('[1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three",]'); reports: "The test1 list is $(test1)"; none11:: "none() test1 1 passed"; !none11:: "none() test1 1 failed"; none12:: "none() test1 2 failed"; !none12:: "none() test1 2 passed"; "The test2 list is $(test2)"; none21:: "none() test2 1 passed"; !none21:: "none() test2 1 failed"; none22:: "none() test2 2 failed"; !none22:: "none() test2 2 passed"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The test1 list is 1 #@ R: The test1 list is 2 #@ R: The test1 list is 3 #@ R: The test1 list is one #@ R: The test1 list is two #@ R: The test1 list is three #@ R: The test1 list is long string #@ R: The test1 list is four #@ R: The test1 list is fix #@ R: The test1 list is six #@ R: none() test1 1 passed #@ R: none() test1 2 passed #@ R: The test2 list is 1 #@ R: The test2 list is 2 #@ R: The test2 list is 3 #@ R: The test2 list is one #@ R: The test2 list is two #@ R: The test2 list is three #@ R: The test2 list is long string #@ R: The test2 list is four #@ R: The test2 list is fix #@ R: The test2 list is six #@ R: none() test2 1 passed #@ R: none() test2 2 passed #@ ``` #+end_src cfengine-3.24.2/examples/diskfree.cf0000644000000000000000000000276615010704253017312 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "has_space" expression => isgreaterthan($(free), 0); vars: "free" int => diskfree("/tmp"); reports: has_space:: "The filesystem has free space"; !has_space:: "The filesystem has NO free space"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The filesystem has free space #@ ``` #+end_src cfengine-3.24.2/examples/getindices.cf0000644000000000000000000000436015010704253017624 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "ps[relayhost]" string => "[mymailrelay]:587"; "ps[mydomain]" string => "iu.hio.no"; "ps[smtp_sasl_auth_enable]" string => "yes"; "ps[smtp_sasl_password_maps]" string => "hash:/etc/postfix/sasl-passwd"; "ps[smtp_sasl_security_options]" string => ""; "ps[smtp_use_tls]" string => "yes"; "ps[default_privs]" string => "mailman"; "ps[inet_protocols]" string => "all"; "ps[inet_interfaces]" string => "127.0.0.1"; "parameter_name" slist => getindices("ps"); "parameter_name_sorted" slist => sort(parameter_name, lex); reports: "Found key $(parameter_name_sorted)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found key default_privs #@ R: Found key inet_interfaces #@ R: Found key inet_protocols #@ R: Found key mydomain #@ R: Found key relayhost #@ R: Found key smtp_sasl_auth_enable #@ R: Found key smtp_sasl_password_maps #@ R: Found key smtp_sasl_security_options #@ R: Found key smtp_use_tls #@ ``` #+end_src cfengine-3.24.2/examples/data_regextract.cf0000644000000000000000000000657315010704253020657 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ##+begin_src prep #@ ``` #@ printf "[general]\n" > /tmp/instance.cfg #@ printf "guid = 9CB197F0-4569-446A-A987-1DDEC1205F6B\n" >> /tmp/instance.cfg #@ printf "port=5308" >> /tmp/instance.cfg #@ ``` #+end_src ############################################################################## #+begin_src cfengine3 bundle agent main { vars: # the returned data container is a key-value map: # the whole matched string is put in key "0" # the first three characters are put in key "name1" # the next three characters go into key "2" (the capture has no name) # the next two characters go into key "3" (the capture has no name) # then the dash is ignored # then three characters are put in key "name2" # then another dash is ignored # the next three characters go into key "5" (the capture has no name) # anything else is ignored "parsed" data => data_regextract("^(?...)(...)(..)-(?...)-(..).*", "abcdef12-345-67andsoon"); "parsed_str" string => format("%S", parsed); # Illustrating multiline regular expression "instance_guid_until_end_of_string" data => data_regextract( "^guid\s?+=\s?+(?.*)$", readfile( "/tmp/instance.cfg", 200)); "instance_guid" data => data_regextract( "^guid\s+=\s+(?[^\n]*)", readfile( "/tmp/instance.cfg", 200)); "instance_port" data => data_regextract( "^port\s?+=\s?+(?[^\n]*)", readfile( "/tmp/instance.cfg", 200)); reports: "$(this.bundle): parsed[0] '$(parsed[0])' parses into: $(parsed_str)"; "$(this.bundle): instance_guid_until_end_of_string[value] '$(instance_guid_until_end_of_string[value])'"; "$(this.bundle): instance_guid[value] '$(instance_guid[value])'"; "$(this.bundle): instance_port[value] '$(instance_port[value])'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: main: parsed[0] 'abcdef12-345-67andsoon' parses into: {"0":"abcdef12-345-67andsoon","2":"def","3":"12","5":"67","name1":"abc","name2":"345"} #@ R: main: instance_guid_until_end_of_string[value] '9CB197F0-4569-446A-A987-1DDEC1205F6B #@ port=5308' #@ R: main: instance_guid[value] '9CB197F0-4569-446A-A987-1DDEC1205F6B' #@ R: main: instance_port[value] '5308' #@ ``` #+end_src cfengine-3.24.2/examples/inline-yaml.cf0000644000000000000000000000250015010704253017716 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent example_inline_yaml # @brief Example illustrating inline yaml { vars: # YAML requires "---" header (followed by newline) # NOTE \n is not interpreted as a newline, instead use $(const.n) "yaml_multi_line" data => '--- - "CFEngine Champions": - Name: "Aleksey Tsalolikhin" Year: 2011 - Name: "Ted Zlatanov" Year : 2013'; "yaml_single_line" data => '---$(const.n)- key1: value1$(const.n)- key2: value2'; reports: "Data container defined from yaml_multi_line: $(with)" with => storejson( @(yaml_multi_line) ); "Data container defined from yaml_single_line: $(with)" with => storejson( @(yaml_single_line) ); } bundle agent __main__ { methods: "example_inline_yaml"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Data container defined from yaml_multi_line: [ #@ { #@ "CFEngine Champions": [ #@ { #@ "Name": "Aleksey Tsalolikhin", #@ "Year": 2011 #@ }, #@ { #@ "Name": "Ted Zlatanov", #@ "Year": 2013 #@ } #@ ] #@ } #@ ] #@ R: Data container defined from yaml_single_line: [ #@ { #@ "key1": "value1" #@ }, #@ { #@ "key2": "value2" #@ } #@ ] #@ ``` #+end_src cfengine-3.24.2/examples/mustache_extension_expand_key.cf0000644000000000000000000000054115010704253023617 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent main { reports: "$(with)" with => string_mustache("datastate() provides {{#-top-}} {{{@}}}{{/-top-}}", datastate() ); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: datastate() provides classes vars #@ ``` #+end_src cfengine-3.24.2/examples/maparray.cf0000644000000000000000000000500515010704253017317 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "run" }; } bundle agent run { vars: "static[2]" string => "lookup 2"; "static[two]" string => "lookup two"; "static[big]" string => "lookup big"; "static[small]" string => "lookup small"; "todo[1]" string => "2"; "todo[one]" string => "two"; "todo[3999]" slist => { "big", "small" }; "map" slist => maparray("key='$(this.k)', static lookup = '$(static[$(this.v)])', value='$(this.v)'", todo); "map_sorted" slist => sort(map, lex); "mycontainer" data => parsejson(' { "top": { "x": 2, "y": "big" } }'); "mapc" slist => maparray("key='$(this.k)', key2='$(this.k[1])', static lookup = '$(static[$(this.v)])', value='$(this.v)'", mycontainer); "mapc_str" string => format("%S", mapc); reports: "mapped array: $(map_sorted)"; "mapped container: $(mapc_str)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: mapped array: key='1', static lookup = 'lookup 2', value='2' #@ R: mapped array: key='3999', static lookup = 'lookup big', value='big' #@ R: mapped array: key='3999', static lookup = 'lookup small', value='small' #@ R: mapped array: key='one', static lookup = 'lookup two', value='two' #@ R: mapped container: { "key='top', key2='x', static lookup = 'lookup 2', value='2'", "key='top', key2='y', static lookup = 'lookup big', value='big'" } #@ ``` #+end_src cfengine-3.24.2/examples/multiple_outcomes.cf0000644000000000000000000000605615010704253021263 0ustar00rootroot00000000000000# Note: This is NOT an automatically tested example. The difference between # dry-run and normal run output makes it problematic to do so. #+begin_src cfengine3 bundle agent main { meta: "description" string => " Illustrate how a promise can have multiple outcomes"; vars: !windows:: "repaired_and_kept" string => "/tmp/repaired_and_not_kept.txt"; files: # We make sure our test file is absent so that we # can show consistent outcomes. "$(repaired_and_kept)" handle => "testfile_absent", delete => tidy; "$(repaired_and_kept)" handle => "test_outcomes", depends_on => { "testfile_absent" }, create => "true", edit_template => "$(this.promsie_filename).broken_mustache", template_method => "mustache", classes => results("bundle", "outcome"); vars: "result_classes" slist => classesmatching("outcome_.*"); "s_result_classes" slist => sort( result_classes, "lex"); reports: outcome_repaired:: "My promise was repaired because the file was created."; outcome_not_kept:: "My promise was not kept because the template failed to render."; outcome_reached:: "My promise was reached because it was actuated. Any o"; DEBUG:: "Found class: '$(s_result_classes)'"; } body delete tidy # @brief This body was inlined from the standard # library in the masterfiles policy framework # repository at commit # 6244c16e6934546d069052f953e597c4b95747df { dirlinks => "delete"; rmdirs => "true"; } body classes results(scope, class_prefix) # @brief This body was inlined from the standard # library in the masterfiles policy framework # repository at commit # 206a8b2e6bf277c3df9b57bf5c535b0b6dba963a { scope => "$(scope)"; promise_kept => { "$(class_prefix)_reached", "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_reached", "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_failed" }; repair_denied => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_denied" }; repair_timeout => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_timeout" }; } #+end_src ######################### #+begin_src do_not_test_example_output #@ ``` #@ error: Template file '$(this.promsie_filename).broken_mustache' could not be opened for reading #@ R: My promise was repaired because the file was created. #@ R: My promise was not kept because the template failed to render. #@ R: Found class: 'outcome_error' #@ R: Found class: 'outcome_failed' #@ R: Found class: 'outcome_not_kept' #@ R: Found class: 'outcome_reached' #@ R: Found class: 'outcome_repaired' #@ ``` #+end_src cfengine-3.24.2/examples/services_default_service_bundle.cf0000644000000000000000000000107115010704253024102 0ustar00rootroot00000000000000bundle agent main # @brief Example showing how service_bundle is defaulted. { services: "my-custom-service" service_method => my_custom_service, service_policy => "stop"; } body service_method my_custom_service { service_type => "generic"; } bundle agent service_my_custom_service(service, state) { reports: "$(service) should have state $(state)"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: my-custom-service should have state stop #@ ``` #+end_src cfengine-3.24.2/examples/test_environment.cf0000644000000000000000000000544015010704253021111 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Guest environments # ####################################################### body common control { bundlesequence => { "my_vm_cloud" }; } ####################################################### bundle agent my_vm_cloud { guest_environments: scope||any:: # These should probably be in class "any" to ensure uniqueness "test2" environment_resources => my_environment, environment_interface => vnet("eth0,192.168.1.100/24"), environment_type => "test", environment_state => "create", environment_host => "atlas"; "test2" environment_resources => my_environment, environment_interface => vnet("eth0,192.168.1.101/24"), environment_type => "test", environment_state => "delete", environment_host => "atlas"; "test4" environment_resources => my_environment, environment_interface => vnet("eth0,192.168.1.102/24"), environment_type => "test", environment_state => "create", environment_host => "atlas"; "network1" environment_type => "test_net", environment_state => "create", environment_host => "atlas"; # default environment_state => "create" on host, and "suspended elsewhere" } ####################################################### body environment_resources my_environment { env_cpus => "2"; env_memory => "512"; # in KB env_disk => "1024"; # in MB } ####################################################### body environment_interface vnet(primary) { env_name => "$(this.promiser)"; env_addresses => { "$(primary)" }; host1:: env_network => "default_vnet1"; host2:: env_network => "default_vnet2"; } cfengine-3.24.2/examples/readstringlist.cf0000644000000000000000000000274615010704253020552 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ printf "one\ntwo\nthree\n" > /tmp/list.txt #@ printf " # commented line\n" >> /tmp/list.txt #@ printf "1\n2\n3\n" >> /tmp/list.txt #@ printf "# another commented line\n" >> /tmp/list.txt #@ printf "Not a commented # line\n" >> /tmp/list.txt #@ printf "1.0\n2.0\n3.0" >> /tmp/list.txt #@ ``` #+end_src #+begin_src cfengine3 bundle agent example_readstringlist # @brief Example showing readstringlist() { vars: "my_list_of_strings" slist => readstringlist( "/tmp/list.txt", # File to read "^\s*#[^\n]*", # Exclude hash comment lines lines "\n", # Split on newlines inf, # Maximum number of entries inf); # Maximum number of bytes to read reports: "my_list_of_strings includes '$(my_list_of_strings)'"; } bundle agent __main__ { methods: "example_readstringlist"; } #+end_src #+begin_src example_output #@ ``` #@ R: my_list_of_strings includes 'one' #@ R: my_list_of_strings includes 'two' #@ R: my_list_of_strings includes 'three' #@ R: my_list_of_strings includes '1' #@ R: my_list_of_strings includes '2' #@ R: my_list_of_strings includes '3' #@ R: my_list_of_strings includes 'Not a commented # line' #@ R: my_list_of_strings includes '1.0' #@ R: my_list_of_strings includes '2.0' #@ R: my_list_of_strings includes '3.0' #@ ``` #+end_src cfengine-3.24.2/examples/package_rpm.cf0000644000000000000000000000466115010704253017763 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Package management # body common control { bundlesequence => { "packages" }; } ############################################# bundle agent packages { vars: "exact_package" slist => { "apache2", "kernel-default" }; "version[OpenOffice_org-hyphen]" string => "1.2.3"; "version[kernel-default]" string => "2.6.27.7-9.1"; packages: "$(exact_package)" package_policy => "verify", package_method => rpm, package_select => ">=", package_architectures => { "x86_64" }, package_version => "$(version[$(exact_package)])"; } ############################################# body package_method rpm { any:: package_changes => "individual"; package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; # Remember to escape special characters like | package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s|]+).*"; package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s|]+).*"; package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; package_installed_regex => "i.*"; package_name_convention => "$(name).$(arch)"; package_add_command => "/bin echo /bin/rpm -i "; package_delete_command => "/bin/rpm -e --nodeps"; package_verify_command => "/bin/rpm -V"; package_noverify_regex => ".*[^\s].*"; #package_noverify_returncode => "-1"; } cfengine-3.24.2/examples/format.cf0000644000000000000000000000450715010704253017001 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "run" }; } bundle agent run { vars: "v" string => "2.5.6"; "vlist" slist => splitstring($(v), "\.", 3); "padded" string => format("%04d%04d%04d", nth("vlist", 0), nth("vlist", 1), nth("vlist", 2)); "a" string => format("%10.10s", "x"); "b" string => format("%-10.10s", "x"); "c" string => format("%04d", 1); "d" string => format("%07.2f", 1); "e" string => format("hello my name is %s %s", "Inigo", "Montoya"); "container" data => parsejson('{ "x": "y", "z": true }'); "packed" string => format("slist = %S, container = %S", vlist, container); reports: "version $(v) => padded $(padded)"; "%10.10s on 'x' => '$(a)'"; "%-10.10s on 'x' => '$(b)'"; "%04d on '1' => '$(c)'"; "%07.2f on '1' => '$(d)'"; "you killed my father... => '$(e)'"; "$(packed)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: version 2.5.6 => padded 000200050006 #@ R: %10.10s on 'x' => ' x' #@ R: %-10.10s on 'x' => 'x ' #@ R: %04d on '1' => '0001' #@ R: %07.2f on '1' => '0001.00' #@ R: you killed my father... => 'hello my name is Inigo Montoya' #@ R: slist = { "2", "5", "6" }, container = {"x":"y","z":true} #@ ``` #+end_src cfengine-3.24.2/examples/ensure_line_present_prepend_append.cf0000644000000000000000000000173015010704253024620 0ustar00rootroot00000000000000# Note that this example assumes that the masterfiles policy framework is installed # in inputs in your user's working directory (e.g. /var/cfengine/inputs for root). #+begin_src cfengine3 body common control { bundlesequence => { "line_prepend", "line_append" , "output" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent line_prepend { files: "/tmp/test_line_prepend" edit_line => prepend_if_no_line("I am the first line"), create => "true"; } bundle agent line_append { files: "/tmp/test_line_append" edit_line => append_if_no_line("I am the last line"), create => "true"; } bundle agent output { vars: "prepend_file" string => readfile("/tmp/test_line_prepend", 1000); "append_file" string => readfile("/tmp/test_line_append", 1000); reports: "Contents of /tmp/test_line_prepend:"; "$(prepend_file)"; "Contents of /tmp/test_line_append:"; "$(append_file)"; } #+end_src cfengine-3.24.2/examples/string_trim.cf0000644000000000000000000000120615010704253020043 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent example_trim # @brief Example showing string_trim { vars: "my_string_one" string => string_trim( " Trim spaces please "); "my_string_two" string => string_trim( " Trim newlines also please "); reports: "my_string_one: '$(my_string_one)'"; "my_string_two: '$(my_string_two)'"; } bundle agent __main__ { methods: "example_trim"; } ############################################################################### #+end_src #+begin_src example_output #@ ``` #@ R: my_string_one: 'Trim spaces please' #@ R: my_string_two: 'Trim newlines also please' #@ ``` #+end_src cfengine-3.24.2/examples/acl_generic.cf0000644000000000000000000000272515010704253017744 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "acls" }; } ######################################### bundle agent acls { files: "/media/flash/acl/test_dir" depth_search => include_base, acl => test; } ######################################### body acl test { acl_type => "generic"; aces => {"user:bob:rwx", "group:staff:rx", "all:r"}; } ######################################### body depth_search include_base { include_basedir => "true"; } cfengine-3.24.2/examples/with.cf0000644000000000000000000000457115010704253016465 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent main { vars: "todo" slist => { "a 1", "b 2", "c 3" }; # Here, `with` is the canonified version of $(todo), letting us avoid an # intermediate canonification array. "$(with)" string => "$(todo)", with => canonify($(todo)); "complex" data => ' { "x": 200, "y": [ 1, 2, null, true, false ] } '; reports: "For iterable '$(todo)' we created variable '$(with)' and its value is '$(todo)'" with => canonify($(todo)); "We can print a data container compactly without creating a temporary variable: $(with)" with => format("%S", complex); "We can print a data container fully without creating a temporary variable: $(with)" with => storejson(complex); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: For iterable 'a 1' we created variable 'a_1' and its value is 'a 1' #@ R: For iterable 'b 2' we created variable 'b_2' and its value is 'b 2' #@ R: For iterable 'c 3' we created variable 'c_3' and its value is 'c 3' #@ R: We can print a data container compactly without creating a temporary variable: {"x":200,"y":[1,2,null,true,false]} #@ R: We can print a data container fully without creating a temporary variable: { #@ "x": 200, #@ "y": [ #@ 1, #@ 2, #@ null, #@ true, #@ false #@ ] #@ } #@ ``` #+end_src cfengine-3.24.2/examples/copy_copbl.cf0000644000000000000000000000326715010704253017644 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "mycopy" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent mycopy { files: "/tmp/test_plain" #@ Path and name of the file we wish to copy to comment => "/tmp/test_plain promises to be an up-to-date copy of /bin/echo to demonstrate copying a local file", copy_from => local_cp("$(sys.workdir)/bin/file"); #@ Copy locally from path/filename "/tmp/test_remote_plain" comment => "/tmp/test_plain_remote promises to be a copy of cfengine://serverhost.example.org/repo/config-files/motd", copy_from => secure_cp("/repo/config-files/motd", "serverhost.example.org"); } #@ Copy remotely from path/filename and specified host cfengine-3.24.2/examples/hash.cf0000644000000000000000000000405415010704253016431 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "md5" string => hash("Cfengine is not cryptic","md5"); "sha256" string => hash("Cfengine is not cryptic","sha256"); "sha384" string => hash("Cfengine is not cryptic","sha384"); "sha512" string => hash("Cfengine is not cryptic","sha512"); reports: "Hashed to: md5 $(md5)"; "Hashed to: sha256 $(sha256)"; "Hashed to: sha384 $(sha384)"; "Hashed to: sha512 $(sha512)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Hashed to: md5 2036af0ee58d6d9dffcc6507af92664f #@ R: Hashed to: sha256 e2fb1927976bfe1ea3987c1a731c75e8ac1453d22a21811dc352db5e62d3f73c #@ R: Hashed to: sha384 b348c0b83ccd9ee12673f5daaba3ee5f49c42906540936bb16cf9d2001ed502b8c56f6e36b8389ab596febb529aab17f #@ R: Hashed to: sha512 29ce0883afbe7740bb2a016735499ae5a0a9b067539018ce6bb2c309a7e885c2d7da64744956e9f151bc72ec8dc19f85efd85eb0a73cbf1e829a15ac9ac35358 #@ ``` #+end_src cfengine-3.24.2/examples/process_signalling.cf0000644000000000000000000000334615010704253021376 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test process restart # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { processes: "cfservd" process_count => up("cfservd"); cfservd_out_of_control:: "cfservd" signals => { "stop" , "term" }, restart_class => "start_cfserv"; commands: start_cfserv:: "/usr/local/bin/cfservd"; } ######################################################## body process_count up(s) { match_range => "1,10"; # or irange("1","10"); out_of_range_define => { "$(s)_out_of_control" }; } cfengine-3.24.2/examples/inherit_from.cf0000644000000000000000000000244215010704253020172 0ustar00rootroot00000000000000# This example illustrates the use of inherit_from to inherit body attribute # values from another body. ############################################################################### #+begin_src cfengine3 bundle agent __main__ { files: "$(this.promise_filename).txt" content => "Hello World$(const.n)2$(const.n)3$(const.n)4$(const.n)half-way 6$(const.n)7$(const.n)8$(const.n)9$(const.n)Byeeeeeee", create => "true"; reports: "The first 3 lines of this file are:" printfile => head_n( "$(this.promise_filename).txt", "3" ); "The whole file contains:" printfile => cat( "$(this.promise_filename).txt" ); } body printfile head_n(file, lines) { # Sets file_to_print the same as cat inherit_from => cat( $(file) ); # Overrides number_of_lines from cat number_of_lines => "$(lines)"; } body printfile cat(file) { file_to_print => "$(file)"; number_of_lines => "inf"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: The first 3 lines of this file are: #@ R: Hello World #@ R: 2 #@ R: 3 #@ R: The whole file contains: #@ R: Hello World #@ R: 2 #@ R: 3 #@ R: 4 #@ R: half-way #@ R: 6 #@ R: 7 #@ R: 8 #@ R: 9 #@ R: Byeeeeeee #@ ``` #+end_src cfengine-3.24.2/examples/data_expand.cf0000644000000000000000000000335315010704253017757 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo '{ "$(main.x)": "$(main.y)" }' > /tmp/expand.json #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main { vars: "x" string => "the expanded x"; "y" string => "the expanded y"; "read" data => readjson("/tmp/expand.json", inf); "expanded" data => data_expand(read); "expanded_str" string => format("%S", expanded); reports: "$(this.bundle): the x and y references expanded to $(expanded_str)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: main: the x and y references expanded to {"the expanded x":"the expanded y"} #@ ``` #+end_src cfengine-3.24.2/examples/const.cf0000644000000000000000000000426415010704253016637 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ # @brief Example illustrating cosnt vars { vars: "example_file" string => "/tmp/const-vars.txt"; files: "$(example_file)" create => "true", content => concat("CFEngine const vars$(const.n)", "before const.at $(const.at) after const.at$(const.n)", "before const.dollar $(const.dollar) after const.dollar$(const.n)", "before const.dirsep $(const.dirsep) after const.dirsep$(const.n)", "before const.linesep $(const.linesep) after const.linesep$(const.n)", "before const.endl$(const.endl) after const.endl$(const.n)", "before const.n$(const.n) after const.n$(const.n)", "before const.r $(const.r) after const.r$(const.n)", "before const.t $(const.t) after const.t$(const.n)"); reports: "const vars available: $(with)" with => storejson( variablesmatching_as_data( "default:const\..*" ) ); "$(example_file):" printfile => cat( "$(example_file)" ); } body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: const vars available: { #@ "default:const.at": "@", #@ "default:const.dirsep": "/", #@ "default:const.dollar": "$", #@ "default:const.endl": "\n", #@ "default:const.linesep": "\n", #@ "default:const.n": "\n", #@ "default:const.r": "\r", #@ "default:const.t": "\t" #@ } #@ R: /tmp/const-vars.txt: #@ R: CFEngine const vars #@ R: before const.at @ after const.at #@ R: before const.dollar $ after const.dollar #@ R: before const.dirsep / after const.dirsep #@ R: before const.linesep #@ R: after const.linesep #@ R: before const.endl #@ R: after const.endl #@ R: before const.n #@ R: after const.n #@ R: before const.r after const.r #@ R: before const.t after const.t #@ ``` #+end_src cfengine-3.24.2/examples/file_owner_list_template.cf0000644000000000000000000000310215010704253022556 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # List substitution in bodies # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { vars: "usernames" slist => { "one", "two", "three" }; files: "/home/mark/tmp/test_plain" perms => users("@(usernames)"), create => "true"; } ######################################################### body perms users(x) { mode => "0640"; owners => { @(x) }; } cfengine-3.24.2/examples/read_module_protocol.cf0000644000000000000000000000175415010704253021713 0ustar00rootroot00000000000000bundle agent cache_maintenance # Creates a module protocol cache, refreshes it if minute is 30-35 { vars: "file" string => "$(this.promise_dirname)/cached_module"; classes: "cache_refresh" if => not(fileexists("$(file)")); Min30_35:: "cache_refresh"; files: cache_refresh:: "$(file)" create => "true", edit_template_string => "=my_variable=$(sys.date)", template_data => "{}", template_method => "inline_mustache"; } bundle agent demo # Demonstrates read_module_protocol function, prints a variable from it { classes: "cache_was_read" if => read_module_protocol("$(cache_maintenance.file)"); reports: cache_was_read:: "Module cache was read!"; "cached_module.my_variable = $(cached_module.my_variable)"; } bundle agent __main__ { methods: "cache_maintenance" handle => "cache_maintenance_done"; "demo" depends_on => { "cache_maintenance_done" }; } cfengine-3.24.2/examples/hashcomment.cf0000644000000000000000000000355515010704253020021 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # Comment lines # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/tmp/comment_test" create => "true", edit_line => comment_lines_matching; } ######################################################## bundle edit_line comment_lines_matching { vars: "regexes" slist => { "one.*", "two.*", "four.*" }; replace_patterns: "^($(regexes))$" replace_with => comment("# "); } ######################################## # Bodies ######################################## body replace_with comment(c) { replace_value => "$(c) $(match.1)"; occurrences => "all"; } cfengine-3.24.2/examples/select_class.cf0000644000000000000000000000244615010704253020155 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "g" }; } ################################# bundle common g { classes: "selection" select_class => { "one", "two" }; reports: one:: "One was selected"; two:: "Two was selected"; selection:: "A selection was made"; } cfengine-3.24.2/examples/edit_insert_fuzzylines.cf0000644000000000000000000000353215010704253022321 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Insert a number of lines with vague whitespace # ####################################################### body common control { any:: bundlesequence => { "insert" }; } ####################################################### bundle agent insert { vars: "v" string => " One potato"; files: "/tmp/test_insert" create => "true", edit_line => Insert("$(insert.v)"); } ####################################################### # For the library ####################################################### bundle edit_line Insert(name) { insert_lines: " $(name)" whitespace_policy => { "ignore_leading", "ignore_embedded" }; } ####################################################### body edit_defaults empty { empty_file_before_editing => "true"; } cfengine-3.24.2/examples/mustache_extension_multiline_json.cf0000644000000000000000000000056615010704253024532 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent main { reports: "$(with)" with => string_mustache( "{{%mykey}}", '{ "mykey": { "msg": "Hello World" } }' ); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: { #@ "msg": "Hello World" #@ } #@ ``` #+end_src cfengine-3.24.2/examples/strcmp.cf0000644000000000000000000000262615010704253017021 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "same" expression => strcmp("test","test"); reports: same:: "Strings are equal"; !same:: "Strings are not equal"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Strings are equal #@ ``` #+end_src cfengine-3.24.2/examples/accessed_before.cf0000644000000000000000000000257215010704253020605 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Show the definition of classes by comparing timestamps # body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { classes: "do_it" and => { accessedbefore("/tmp/earlier","/tmp/later") }; reports: do_it:: "The earlier file has been accessed before the later"; } cfengine-3.24.2/examples/nth.cf0000644000000000000000000000712615010704253016302 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "test_str" string => format("%S", test); "test2" data => parsejson("[1, 2, 3, null]"); "test2_str" string => format("%S", test2); "test3" data => parsejson('{ "x": true, "y": "z" }'); "test3_str" string => format("%S", test3); "nth" slist => { 1, 2, 6, 10, 11, 1000 }; "nth2" slist => getindices(test2); "nth3" slist => getindices(test3); "access[$(nth)]" string => nth(test, $(nth)); "access[0]" string => nth(test, 0); "access2[$(nth2)]" string => nth(test2, $(nth2)); "access3[$(nth3)]" string => nth(test3, $(nth3)); "nth_neg1" string => nth(test, "-1"); "nth_neg100" string => nth(test, "-100"); # invalid index position requested reports: "The test list is $(test_str)"; "element #$(nth) of the test list: $(access[$(nth)])"; "element #0 of the test list: $(access[0])"; "The test2 data container is $(test2_str)"; "element #$(nth2) of the test2 data container: $(access2[$(nth2)])"; "The test3 data container is $(test3_str)"; "element #$(nth3) of the test3 data container: $(access3[$(nth3)])"; "The last element of test is $(nth_neg1)"; "nth_neg100 is not defined, because an invalid index was requested" if => not( isvariable( nth_neg100 )); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The test list is { "1", "2", "3", "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three" } #@ R: element #1 of the test list: 2 #@ R: element #2 of the test list: 3 #@ R: element #6 of the test list: long string #@ R: element #10 of the test list: one #@ R: element #11 of the test list: two #@ R: element #0 of the test list: 1 #@ R: The test2 data container is [1,2,3,null] #@ R: element #0 of the test2 data container: 1 #@ R: element #1 of the test2 data container: 2 #@ R: element #2 of the test2 data container: 3 #@ R: element #3 of the test2 data container: null #@ R: The test3 data container is {"x":true,"y":"z"} #@ R: element #x of the test3 data container: true #@ R: element #y of the test3 data container: z #@ R: The last element of test is three #@ R: nth_neg100 is not defined, because an invalid index was requested #@ ``` #+end_src cfengine-3.24.2/examples/storejson.cf0000644000000000000000000000407115010704253017533 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle common globals { vars: "example_data" data => '{ "msg": "Hello from $(this.bundle)" }'; } bundle agent example_storejson # @brief Example showing storejson { vars: "example_data" data => '{ "msg": "Hello from $(this.bundle)" }'; # Using storejson with data from remote bundle # "json_string_zero" -> { "CFEngine 3.16.0"} # string => storejson( globals.example_data ) # comment => "Unquoted with . (dot) present will cause the parser to error"; "json_string_one" string => storejson( @(globals.example_data) ); "json_string_two" string => storejson( "globals.example_data" ); # Using storejson with data from this bundle "json_string_three" string => storejson( @(example_storejson.example_data) ); "json_string_four" string => storejson( "example_storejson.example_data"); "json_string_five" string => storejson( example_data ); "json_string_six" string => storejson( "$(this.bundle).example_data"); "json_string_seven" string => storejson( @(example_data) ); reports: "json_string_one and json_string_two are identical:$(const.n)$(json_string_one)" if => strcmp( $(json_string_one), $(json_string_two) ); "json_string_{one,two,three,four,five,six,seven} are identical:$(const.n)$(json_string_three)" if => and( strcmp( $(json_string_three), $(json_string_four) ), strcmp( $(json_string_four), $(json_string_five) ), strcmp( $(json_string_five), $(json_string_six) ), strcmp( $(json_string_six), $(json_string_seven) ) ); } bundle agent __main__ { methods: "example_storejson"; } ############################################################################### #+end_src #+begin_src example_output #@ ``` #@ R: json_string_one and json_string_two are identical: #@ { #@ "msg": "Hello from globals" #@ } #@ R: json_string_{one,two,three,four,five,six,seven} are identical: #@ { #@ "msg": "Hello from example_storejson" #@ } #@ ``` #+end_src cfengine-3.24.2/examples/cf2_integration.cf0000644000000000000000000000317215010704253020563 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Cfagent 2 can be run as a command within cfengine 3 # so that cfagent 2 AND cfagent 3 can coexist # # It does not matter which versions of the daemons are run # but you must choose version 2 XOR version 3 # body common control { # Reads default # /var/cfengine/inputs/promises.cf # /var/cfengine/inputs/failsafe.cf bundlesequence => { "cfengine3", "cfengine2" }; } ########################################### bundle agent cfengine2 { commands: "/var/cfengine/bin/cfagent"; } ########################################### bundle agent cfengine3 { # Stuff commands: "/var/cfengine/bin/cf-agent"; } cfengine-3.24.2/examples/countclassesmatching.cf0000644000000000000000000000276115010704253021732 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: # this is anchored, so you need .* to match multiple things "num" int => countclassesmatching("cfengine"); "hardcount" int => countclassesmatching(".*", "hardclass"); reports: "Found $(num) classes matching"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found 1 classes matching #@ ``` #+end_src cfengine-3.24.2/examples/deletelines.cf0000644000000000000000000000412615010704253020003 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } bundle agent example { files: "/tmp/resolv.conf" # test on "/tmp/resolv.conf" # create => "true", edit_line => resolver, edit_defaults => def; } ####################################################### # For the library ####################################################### bundle edit_line resolver { vars: "search" slist => { "search iu.hio.no cfengine.com", "nameserver 128.39.89.10" }; delete_lines: "search.*"; insert_lines: "$(search)" location => end; } ####################################################### body edit_defaults def { empty_file_before_editing => "false"; edit_backup => "false"; max_file_size => "100000"; } ######################################################## body location start { # If not line to match, applies to whole text body before_after => "before"; } ######################################################## body location end { # If not line to match, applies to whole text body before_after => "after"; } cfengine-3.24.2/examples/local_users_absent.cf0000644000000000000000000000021215010704253021345 0ustar00rootroot00000000000000bundle agent main { vars: "users" slist => { "jack", "jill" }; users: linux:: "$(users)" policy => "absent"; } cfengine-3.24.2/examples/service_start.cf0000644000000000000000000000111615010704253020357 0ustar00rootroot00000000000000body common control { bundlesequence => { "example" }; } ############################################# bundle agent example { services: "Themes" service_policy => "start", service_dependencies => { "Alerter" }, service_method => exmethod; } ############################################# body service_method exmethod { service_type => "windows"; service_args => "-f \"the file with spaces.cf\" --some-args"; service_autostart_policy => "boot_time"; service_dependence_chain => "start_parent_services"; } cfengine-3.24.2/examples/dollar.cf0000644000000000000000000000250715010704253016764 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { classes: "some" expression => "any"; reports: some:: "The value of $(const.dollar)(const.dollar) is $(const.dollar)"; "But the value of \$(dollar) is \$(dollar)"; } cfengine-3.24.2/examples/registry_cache.cf0000644000000000000000000000325215010704253020500 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { # "registry_cache" # "registry_restore" }; } ######################################### bundle agent registry_cache { databases: windows:: "HKEY_LOCAL_MACHINE\SOFTWARE\Adobe" database_operation => "cache", database_type => "ms_registry", comment => "Save correct registry settings for Adobe products"; } ######################################### bundle agent registry_restore { databases: windows:: "HKEY_LOCAL_MACHINE\SOFTWARE\Adobe" database_operation => "restore", database_type => "ms_registry", comment => "Make sure Adobe products have correct registry settings"; } cfengine-3.24.2/examples/classvar_convergence.cf0000644000000000000000000000272515010704253021705 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "tryclasses_1" }; } ################################# bundle agent tryclasses_1 { vars: "x" string => "one"; "y" slist => { "linux", "Friday" }; classes: "three" and => { "$(x)", "two" }; "four" or => { @(y) }; "one" expression => "any"; "two" expression => "any"; reports: three:: "Evaluated true"; four:: "List substitution works"; } ################################# cfengine-3.24.2/examples/ago.cf0000644000000000000000000000335715010704253016261 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "testbundle" }; } bundle agent testbundle { processes: ".*" process_count => anyprocs, process_select => proc_finder; reports: any_procs:: "Found processes out of range"; } body process_select proc_finder { # Processes started between 100 years + 5.5 hours and 1 minute ago stime_range => irange(ago(100,0,0,5,30,0),ago(0,0,0,0,1,0)); process_result => "stime"; } body process_count anyprocs { match_range => "0,0"; out_of_range_define => { "any_procs" }; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found processes out of range #@ ``` #+end_src cfengine-3.24.2/examples/execd.cf0000644000000000000000000000244615010704253016601 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { }; } body executor control { mailto => "MARK@iu.hio.no"; mailfrom => "cfengine@domain.tld"; smtpserver => "MAIL-out.hio.no"; mailmaxlines => "50"; schedule => { "Min00_05", "Min30_35" }; exec_command => "/var/cfengine/bin/cf-agent"; } cfengine-3.24.2/examples/main_entry_point.cf0000644000000000000000000000101315010704253021054 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -KIf- # Example showing how bundle __main__ works # This file can be used as the main entry (`cf-agent -KIf ./main_entry_point.cf`) # This file can also be included from another policy file containing __main__ body file control { inputs => { "$(sys.policy_entry_dirname)/main_library.cf" }; } bundle agent __main__ { methods: "a" usebundle => libprint("Hello from $(sys.policy_entry_basename)"); } #+begin_src example_output #@ ``` #@ R: Hello from policy.cf #@ ``` #+end_src cfengine-3.24.2/examples/parallel_exec.cf0000644000000000000000000000325415010704253020307 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple backgrounding - try this with background = true and false # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## body agent control { agentaccess => { "mark", "root" }; } ######################################################## bundle agent example { commands: "/bin/sleep 10" action => background; "/bin/sleep" args => "20", action => background; } ######################################################### body action background { background => "true"; } cfengine-3.24.2/examples/createdb.cf0000644000000000000000000000374015010704253017260 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "databases" }; } bundle agent databases { databases: "knowledge_bank/topics" database_operation => "create", database_type => "sql", database_columns => { "demo_name,varchar,256", "demo_comment,varchar,1024", "demo_id,varchar,256", "demo_type,varchar,256", "demo_extra,varchar,26" }, database_server => myserver; } ################################################ body database_server myserver { none:: db_server_owner => "postgres"; db_server_password => ""; db_server_host => "localhost"; db_server_type => "postgres"; db_server_connection_db => "postgres"; any:: db_server_owner => "root"; db_server_password => ""; db_server_host => "localhost"; db_server_type => "mysql"; db_server_connection_db => "mysql"; } cfengine-3.24.2/examples/style_PascaleCase.cf0000644000000000000000000000156715010704253021100 0ustar00rootroot00000000000000bundle agent __main__ { methods: "Ssh"; } bundle agent Ssh { vars: "ServiceName" string => "ssh"; "ConfigFile" string => "/etc/ssh/sshd_config"; "Conf[Port]" string => "22"; files: "$(ConfigFile)" edit_line => default:set_line_based("$(this.bundle).Conf", " ", "\s+", ".*", "\s*#\s*"), classes => default:results( "bundle", "$(ConfigFile)"); services: _etc_ssh_sshd_config_repaired:: "$(ServiceName)" service_policy => "restart", classes => default:results( "bundle", "$(ServiceName)_restart"); reports: ssh_restart_repaired._etc_ssh_sshd_config_repaired:: "We restarted ssh because the config file was repaired"; } cfengine-3.24.2/examples/mapdata.cf0000644000000000000000000000722115010704253017114 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "run" }; } bundle agent run { vars: "myarray[lookup][big]" string => "lookup big"; "myarray[lookup][small]" string => "lookup small"; # every item must parse as valid JSON when the interpretation is `json` "mapa_json" data => mapdata("json", '{ "key": "$(this.k)", "key2": "$(this.k[1])", "value": "$(this.v)" }', myarray); "mapa_json_str" string => format("%S", mapa_json); # every item is just a string when the interpretation is `none` "mapa_none" data => mapdata("none", 'key=$(this.k), level 2 key = $(this.k[1]), value=$(this.v)', myarray); "mapa_none_str" string => format("%S", mapa_none); "mycontainer" data => parsejson(' { "top": { "x": 100, "y": 200 } }'); # every item must parse as valid JSON when the interpretation is `json` "mapc_json" data => mapdata("json", '{ "key": "$(this.k)", "key2": "$(this.k[1])", "value": "$(this.v)" }', mycontainer); "mapc_json_str" string => format("%S", mapc_json); # every item is just a string when the interpretation is `none` "mapc_none" data => mapdata("none", 'key=$(this.k), level 2 key = $(this.k[1]), value=$(this.v)', mycontainer); "mapc_none_str" string => format("%S", mapc_none); reports: show_example:: "mapdata/json on classic CFEngine array result: $(mapa_json_str)"; "mapdata/none on classic CFEngine array result: $(mapa_none_str)"; "mapdata/json on data container result: $(mapc_json_str)"; "mapdata/none on data container result: $(mapc_none_str)"; any:: "Note that the output of the above reports is not deterministic,"; "because the order of the keys returned by mapdata() is not guaranteed."; } #+end_src ############################################################################### #+begin_src show_example_example_output #@ ``` #@ R: mapdata/json on classic CFEngine array result: [{"key":"lookup","key2":"big","value":"lookup big"},{"key":"lookup","key2":"small","value":"lookup small"}] #@ R: mapdata/none on classic CFEngine array result: ["key=lookup, level 2 key = big, value=lookup big","key=lookup, level 2 key = small, value=lookup small"] #@ R: mapdata/json on data container result: [{"key":"top","key2":"x","value":"100"},{"key":"top","key2":"y","value":"200"}] #@ R: mapdata/none on data container result: ["key=top, level 2 key = x, value=100","key=top, level 2 key = y, value=200"] #@ ``` #+end_src #+begin_src show_example_example_output #@ ``` #@ R: "Note that the output of the above reports is not deterministic," #@ R: "because the order of the keys returned by mapdata() is not guaranteed." #@ ``` #+end_src cfengine-3.24.2/examples/files-create-class-expression.cf0000644000000000000000000000053715010704253023353 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ test -e /tmp/linux && rm /tmp/linux #@ ``` #+end_src #+begin_src cfengine3 body agent control { inform => "true"; } bundle agent __main__ { files: linux:: "/tmp/linux" create => "true"; } #+end_src #+begin_src example_output #@ ``` #@ info: Created file '/tmp/linux', mode 0600 #@ ``` #+end_src cfengine-3.24.2/examples/edit_comment_lines.cf0000644000000000000000000000432715010704253021352 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # File editing # # Normal ordering: # - delete # - replace | column_edit # - insert # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/tmp/cf3_test" create => "true", edit_line => myedit("second"); } ######################################################## bundle edit_line myedit(parameter) { vars: "edit_variable" string => "private edit variable is $(parameter)"; replace_patterns: # replace shell comments with C comments "#(.*)" replace_with => C_comment, select_region => MySection("New section"); } ######################################## # Bodies ######################################## body replace_with C_comment { replace_value => "/* $(match.1) */"; # backreference 0 occurrences => "all"; # first, last all } ######################################################## body select_region MySection(x) { select_start => "\[$(x)\]"; select_end => "\[.*\]"; } cfengine-3.24.2/examples/method_var2.cf0000644000000000000000000000135415010704253017720 0ustar00rootroot00000000000000# # Demonstrates the use of polymorphism to call bundles. # body common control { bundlesequence => { "example" }; } ########################################### bundle agent example { vars: "m" slist => { "login", "ssh_keys", "environment" }; "user" slist => { "diego", "mark", "neil" }; methods: "set of $(m)" usebundle => $(m)("$(user)"); } ########################################### bundle agent login(x) { reports: "Setup login for $(x)"; } ########################################### bundle agent ssh_keys(x) { reports: "Setup ssh keys for $(x)"; } ########################################### bundle agent environment(x) { reports: "Setup login environment for $(x)"; } cfengine-3.24.2/examples/eval.cf0000644000000000000000000000616415010704253016441 0ustar00rootroot00000000000000#+begin_src cfengine3 body common control { bundlesequence => { run }; } body agent control { inform => "true"; } bundle agent run { vars: "values[0]" string => "x"; # bad "values[1]" string => "+ 200"; # bad "values[2]" string => "200 + 100"; "values[3]" string => "200 - 100"; "values[4]" string => "- - -"; # bad "values[5]" string => "2 + 3 - 1"; "values[6]" string => ""; # 0 "values[7]" string => "3 / 0"; # inf but not an error "values[8]" string => "3^3"; # "values[9]" string => "-1^2.1"; # 'nan' or '-nan' (on some platforms) "values[10]" string => "sin(20)"; "values[11]" string => "cos(20)"; "values[19]" string => "20 % 3"; # remainder "values[20]" string => "sqrt(0.2)"; "values[21]" string => "ceil(3.5)"; "values[22]" string => "floor(3.4)"; "values[23]" string => "abs(-3.4)"; "values[24]" string => "-3.4 == -3.4"; "values[25]" string => "-3.400000 == -3.400001"; "values[26]" string => "e"; "values[27]" string => "pi"; "values[28]" string => "100m"; # 100 million "values[29]" string => "100k"; # 100 thousand "indices" slist => sort( getindices("values"), int); "eval[$(indices)]" string => eval("$(values[$(indices)])", "math", "infix"); reports: "math/infix eval('$(values[$(indices)])') = '$(eval[$(indices)])'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ info: eval error: expression could not be parsed (input 'x') #@ info: eval error: expression could not be parsed (input '+ 200') #@ info: eval error: expression could not be parsed (input '- - -') #@ R: math/infix eval('x') = '' #@ R: math/infix eval('+ 200') = '' #@ R: math/infix eval('200 + 100') = '300.000000' #@ R: math/infix eval('200 - 100') = '100.000000' #@ R: math/infix eval('- - -') = '' #@ R: math/infix eval('2 + 3 - 1') = '4.000000' #@ R: math/infix eval('') = '0.000000' #@ R: math/infix eval('3 / 0') = 'inf' #@ R: math/infix eval('3^3') = '27.000000' #@ R: math/infix eval('sin(20)') = '0.912945' #@ R: math/infix eval('cos(20)') = '0.408082' #@ R: math/infix eval('20 % 3') = '2.000000' #@ R: math/infix eval('sqrt(0.2)') = '0.447214' #@ R: math/infix eval('ceil(3.5)') = '4.000000' #@ R: math/infix eval('floor(3.4)') = '3.000000' #@ R: math/infix eval('abs(-3.4)') = '3.400000' #@ R: math/infix eval('-3.4 == -3.4') = '1.000000' #@ R: math/infix eval('-3.400000 == -3.400001') = '0.000000' #@ R: math/infix eval('e') = '2.718282' #@ R: math/infix eval('pi') = '3.141593' #@ R: math/infix eval('100m') = '100000000.000000' #@ R: math/infix eval('100k') = '100000.000000' #@ info: eval error: expression could not be parsed (input 'x') #@ info: eval error: expression could not be parsed (input '+ 200') #@ info: eval error: expression could not be parsed (input '- - -') #@ info: eval error: expression could not be parsed (input 'x') #@ info: eval error: expression could not be parsed (input '+ 200') #@ info: eval error: expression could not be parsed (input '- - -') #@ ``` #+end_src cfengine-3.24.2/examples/edit_replace_string.cf0000644000000000000000000000415315010704253021514 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # File editing # # Normal ordering: # - delete # - replace | column_edit # - insert # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/tmp/replacestring" create => "true", edit_line => myedit("second"); } ######################################################## bundle edit_line myedit(parameter) { vars: "edit_variable" string => "private edit variable is $(parameter)"; replace_patterns: # replace shell comments with C comments "puppet" replace_with => With("cfengine 3"); } ######################################## # Bodies ######################################## body replace_with With(x) { replace_value => "$(x)"; occurrences => "first"; } ######################################## body select_region MySection(x) { select_start => "\[$(x)\]"; select_end => "\[.*\]"; } cfengine-3.24.2/examples/getclassmetatags.cf0000644000000000000000000000333115010704253021036 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "c" expression => "any", meta => { "mytag", "other=once", "other=twice" }; vars: "ctags" slist => getclassmetatags("c"); "othertag_values" slist => getclassmetatags("c", "other"); reports: "Found tags: $(ctags)"; "Found tags for key 'other': $(othertag_values)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found tags: source=promise #@ R: Found tags: mytag #@ R: Found tags: other=once #@ R: Found tags: other=twice #@ R: Found tags for key 'other': once #@ R: Found tags for key 'other': twice #@ ``` #+end_src cfengine-3.24.2/examples/isipinsubnet.cf0000644000000000000000000000324015010704253020216 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ############################################################################### #+begin_src cfengine3 bundle agent main { classes: "in_192" expression => isipinsubnet("192.0.0.0/8", "192.1.2.3"); "in_192_2_2_2" expression => isipinsubnet("192.2.2.0/24", "192.1.2.3"); reports: in_192:: "The address 192.1.2.3 is in the 192/8 subnet"; !in_192_2_2_2:: "The address 192.1.2.3 is not in the 192.2.2/24 subnet"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The address 192.1.2.3 is in the 192/8 subnet #@ R: The address 192.1.2.3 is not in the 192.2.2/24 subnet #@ ``` #+end_src cfengine-3.24.2/examples/template.cf0000644000000000000000000000325115010704253017317 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test editfile - template expansion # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/tmp/file_based_on_template" create => "true", edit_line => ExpandMeFrom("/tmp/source_template"); } ######################################################## bundle edit_line ExpandMeFrom(template) { vars: "myvar" string => "[sub string]"; insert_lines: "$(template)" insert_type => "file", expand_scalars => "true"; } cfengine-3.24.2/examples/edit_column_files.cf0000644000000000000000000000523615010704253021175 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # File editing # # Normal ordering: # - delete # - replace | column_edit # - insert # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "bun" }; } ######################################################## bundle agent bun { vars: "userset" slist => { "one", "two", "three" }; files: # Make a copy of the password file "/home/mark/tmp/passwd" create => "true", edit_line => set_user_field("mark","6","/home/dir"); "/home/mark/tmp/group" create => "true", edit_line => append_user_field("wheel","4","@(bun.userset)"); } ######################################################## bundle edit_line set_user_field(user,field,val) { field_edits: "$(user).*" # Set field of the file to parameter edit_field => col(":","$(field)","$(val)","set"); } ######################################################## bundle edit_line append_user_field(user,field,allusers) { vars: "val" slist => { @(allusers) }; field_edits: "$(user).*" # Set field of the file to parameter edit_field => col(":","$(field)","$(val)","alphanum"); } ######################################## # Bodies ######################################## body edit_field col(split,col,newval,method) { field_separator => "$(split)"; select_field => "$(col)"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } cfengine-3.24.2/examples/stringarray.cf0000644000000000000000000000263615010704253020057 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "dim_array" int => readstringarray("array_name","/etc/passwd","#[^\n]*",":",10,4000); "idx" slist => getindices("array_name"); reports: "Index $(idx): [1]=$(array_name[$(idx)][1]),[2]=$(array_name[$(idx)][2])...[7]=$(array_name[$(idx)][6])"; } cfengine-3.24.2/examples/cf_version_before.cf0000644000000000000000000000065215010704253021165 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This will be skipped on newer or equal versions" if => cf_version_before("3.15"); "This will be skipped on older versions" unless => cf_version_before("3.15"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This will be skipped on older versions #@ ``` #+end_src cfengine-3.24.2/examples/package_latest.cf0000644000000000000000000000072115010704253020452 0ustar00rootroot00000000000000# # Makes sure a package is installed at latest version. # Does not take any action if the package has already # reached the version given in package_version. # body common control { inputs => { "$(sys.libdir)/stdlib.cf" }; bundlesequence => { "example" }; } bundle agent example { packages: "apache2" package_method => generic, package_version => "2.2.00", package_select => ">=", package_policy => "addupdate"; } cfengine-3.24.2/examples/lsdir.cf0000644000000000000000000000274115010704253016624 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "listfiles" slist => lsdir("/etc", "(p.sswd|gr[ou]+p)", "true"); "sorted_listfiles" slist => sort(listfiles, "lex"); reports: "files in list: $(sorted_listfiles)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: files in list: /etc/group #@ R: files in list: /etc/passwd #@ ``` #+end_src cfengine-3.24.2/examples/win_schedule.cf0000644000000000000000000000433315010704253020157 0ustar00rootroot00000000000000######################################################################### # # scheduling.cf - Command Execution Scheduling # # NOTE: Commands can be executed based on any class expression. # Examples include execution of other commands (sequencing), # time, OS, hostname or the outcome of another promise. # If a shell wrapper is not needed, removing it will increase # security and performance. # ######################################################################### body common control { bundlesequence => { "system_scheduling" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent system_scheduling { vars: # Command definitions are given in cmd[index]. # The dependencies of the commands are dep_cmd[index], as boolean class expressions. # Comments are given as comment_cmd[index] "cmd[1]" string => "$(sys.cf_key)"; "dep_cmd[1]" string => "cmd2_success"; "comment_cmd[1]" string => "Check that a Cfengine key is generated if command 2 has run (dummy)"; windows:: "cmd[2]" string => "\"$(sys.winsysdir)\shutdown.exe\" /r /c \"Cfengine automatic restart\" /t 120"; "dep_cmd[2]" string => "Monday.Hr05.Min00_05"; "comment_cmd[2]" string => "Restart windows every week"; "cmd[3]" string => "$(sys.winsysdir)\cscript.exe \"$(sys.workdir)\script1.vbs\" //Nologo > \"$(sys.workdir)\script1_out.txt\""; "dep_cmd[3]" string => "Hr05.Min05_10"; "comment_cmd[3]" string => "Run a script and save its output for later reference (needs to be run in shell)"; !windows:: "cmd[2]" string => "/bin/echo Hello World!"; "dep_cmd[2]" string => "Hr12.Min00_05"; "comment_cmd[2]" string => "Print a message (dummy)"; any:: "cmd_index" slist => getindices("cmd"); commands: # Runs a command if its dependencies are satisfied "$(cmd[$(cmd_index)])" classes => if_repaired("cmd$(cmd_index)_success"), if => "$(dep_cmd[$(cmd_index)])", contain => in_shell, comment => "$(comment_cmd[$(cmd_index)])"; } cfengine-3.24.2/examples/linking.cf0000644000000000000000000000425415010704253017143 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # File editing # # Normal ordering: # - delete # - replace | column_edit # - insert # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "example" }; } ######################################################## bundle agent example { files: # Make a copy of the password file "/home/mark/tmp/passwd" link_from => linkdetails("/etc/passwd"), move_obstructions => "true"; "/home/mark/tmp/linktest" link_from => linkchildren("/usr/local/sbin"); #child links } ######################################################### body link_from linkdetails(tofile) { source => "$(tofile)"; link_type => "symlink"; when_no_source => "force"; # kill } ######################################################### body link_from linkchildren(tofile) { source => "$(tofile)"; link_type => "symlink"; when_no_source => "force"; # kill link_children => "true"; when_linking_children => "if_no_such_file"; # "override_file"; } cfengine-3.24.2/examples/namespace_methods-usebundle.cf0000644000000000000000000000241215010704253023145 0ustar00rootroot00000000000000bundle agent __main__ { methods: # Call the bundle named main within the example_space namespace. "example_space:main"; } body file control { namespace => "example_space"; } bundle agent main { methods: # Call the bundle 'my_bundle' within the current namespace "When not specified, we assume you are refering to a bundle or body within the same namespace" usebundle => my_bundle( "Called 'my_bundle' from $(this.namespace):$(this.bundle) (the same namespace)."); # Call the bundle 'my_bundle' from the 'example_space' namespace "When explicitly specified, the policy reader has less congnitive burden" usebundle => example_space:my_bundle( "Called 'example_space:my_bundle' $(this.namespace):$(this.bundle) (the same namespace)."); } bundle agent my_bundle(string) { reports: "In $(this.namespace):$(this.bundle)" handle => "$(string)"; "$(string)"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: In example_space:my_bundle #@ R: Called 'my_bundle' from example_space:main (the same namespace). #@ R: In example_space:my_bundle #@ R: Called 'example_space:my_bundle' example_space:main (the same namespace). #@ ``` #+end_src cfengine-3.24.2/examples/registry.cf0000644000000000000000000000442115010704253017354 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "databases" }; } bundle agent databases { databases: windows:: # Regsitry has (value,data) pairs in "keys" which are directories # "HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS" # database_operation => "create", # database_type => "ms_registry"; # "HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\Cfengine" # database_operation => "create", # database_rows => { "value1,REG_SZ,new value 1", "value2,REG_SZ,new val 2"} , # database_type => "ms_registry"; "HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\Cfengine" database_operation => "delete", database_columns => { "value1", "value2" } , database_type => "ms_registry"; # "HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS\Cfengine" # database_operation => "cache", # cache,restore # registry_exclude => { ".*Windows.*CurrentVersion.*", ".*Touchpad.*", ".*Capabilities.FileAssociations.*", ".*Rfc1766.*" , ".*Synaptics.SynTP.*", ".*SupportedDevices.*8086", ".*Microsoft.*ErrorThresholds" }, # database_type => "ms_registry"; "HKEY_LOCAL_MACHINE\SOFTWARE\Northern.tech AS" database_operation => "restore", database_type => "ms_registry"; } cfengine-3.24.2/examples/webserver.cf0000644000000000000000000000602215010704253017507 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Apache 2 reconfig - modelled on SuSE # ####################################################### body common control { any:: bundlesequence => { apache }; } ####################################################### bundle agent apache { files: "/home/mark/tmp/apache2" # "/etc/sysconfig/apache2" edit_line => fixapache; } ####################################################### # For the library ####################################################### bundle edit_line fixapache { # Values have the form NAME = "quoted space separated list" vars: "add_modules" slist => { "dav", "dav_fs", "ssl", "php5", "dav_svn", "xyz", "superduper" }; "del_modules" slist => { "php3", "jk", "userdir", "imagemap", "alias" }; insert_lines: "APACHE_CONF_INCLUDE_FILES=\"/site/masterfiles/local-http.conf\""; field_edits: ##################################################################### # APACHE_MODULES="authz_host actions alias auth_basic dav dav_fs imagemap ssl php5 dav_svn authz_default jk" ##################################################################### "APACHE_MODULES=.*" # Insert module "columns" between the quoted RHS # using space separators edit_field => quotedvar("$(add_modules)","append"); "APACHE_MODULES=.*" # Delte module "columns" between the quoted RHS # using space separators edit_field => quotedvar("$(del_modules)","delete"); # if this line already exists, edit it } ######################################## # Bodies ######################################## body edit_field quotedvar(newval,method) { field_separator => "\""; select_field => "2"; value_separator => " "; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "false"; allow_blank_fields => "true"; } cfengine-3.24.2/examples/null_config.cf0000644000000000000000000000250715010704253020006 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # The starting point for every configuration # ####################################################### body common control { bundlesequence => { "example" }; } ####################################################### bundle agent example { reports: "This is a test bundle"; } cfengine-3.24.2/examples/select_size.cf0000644000000000000000000000275615010704253020026 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } # bundle agent example { files: # Show files in range "/home/mark/tmp" file_select => name_and_sizes(".*cf","100","300"), depth_search => recurse("1"), transformer => "/bin/ls -l $(this.promiser)"; } # body file_select name_and_sizes(n,x,y) { leaf_name => { "$(n)" }; search_size => irange("$(x)", "$(y)"); file_result => "leaf_name&size"; } body depth_search recurse(x) { depth => "$(x)"; } cfengine-3.24.2/examples/guest_environment_kvm.cf0000644000000000000000000000364715010704253022145 0ustar00rootroot00000000000000# # Management of KVM/QEMU virtual machines # Assumes you already have a disk image (with an OS installed) for the machine on creation # body common control { bundlesequence => { "kvm_create" }; } bundle agent kvm_create { guest_environments: "my_host_machine" environment_resources => mykvm("my_host_machine", "x86_64", "1", "1048576", "/var/lib/libvirt/images/ubuntu104-64-clone.img"), environment_type => "kvm", environment_state => "create", environment_host => "ubuntu"; } bundle agent kvm_suspend { guest_environments: "my_host_machine" environment_type => "kvm", environment_state => "suspended", environment_host => "ubuntu"; } bundle agent kvm_run { guest_environments: "my_host_machine" environment_type => "kvm", environment_state => "running", environment_host => "ubuntu"; } bundle agent kvm_delete { guest_environments: "my_host_machine" environment_type => "kvm", environment_state => "delete", environment_host => "ubuntu"; } body environment_resources mykvm(name, arch, cpu_count, mem_kb, disk_file) { env_spec => " $(name) $(mem_kb) $(mem_kb) $(cpu_count) hvm destroy restart restart /usr/bin/kvm "; } cfengine-3.24.2/examples/syslog2.cf0000644000000000000000000000100215010704253017076 0ustar00rootroot00000000000000# # With Nova, log directly to a central server -- careful of scalability (UDP) # body common control { bundlesequence => { "example" }; syslog_host => "loghost.example.org"; } # bundle agent example { vars: "software" slist => { "/root/xyz", "/tmp/xyz" }; files: "$(software)" create => "true", action => logme("$(software)"); } # body action logme(x) { log_repaired => "udp_syslog"; log_string => "cfengine repaired promise $(this.handle) - $(x)"; } cfengine-3.24.2/examples/host2ip.cf0000644000000000000000000000254515010704253017101 0ustar00rootroot00000000000000 # Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # host2ip function # ####################################################### body common control { bundlesequence => { "example" }; } ####################################################### bundle agent example { vars: "ip" string => host2ip("www.google.com"); reports: "IP address $(ip)"; } cfengine-3.24.2/examples/readrealarray.cf0000644000000000000000000000506015010704253020322 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo "1: 5.0:7:21:13" > /tmp/readrealarray.txt #@ echo "2:19:8.1:14:14" >> /tmp/readrealarray.txt #@ echo "3:45:1:78.2:22" >> /tmp/readrealarray.txt #@ echo "4:64:2:98:99.3" >> /tmp/readrealarray.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main { vars: "lines" int => readrealarray("array_name", "/tmp/readrealarray.txt", "#[^\n]*", ":", 10, 4000); reports: "array_name contains $(lines) keys$(const.n)$(with)" with => string_mustache("{{%-top-}}", "array_name"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: array_name contains 4 keys #@ { #@ "1": { #@ "0": "1", #@ "1": " 5.0", #@ "2": "7", #@ "3": "21", #@ "4": "13" #@ }, #@ "2": { #@ "0": "2", #@ "1": "19", #@ "2": "8.1", #@ "3": "14", #@ "4": "14" #@ }, #@ "3": { #@ "0": "3", #@ "1": "45", #@ "2": "1", #@ "3": "78.2", #@ "4": "22" #@ }, #@ "4": { #@ "0": "4", #@ "1": "64", #@ "2": "2", #@ "3": "98", #@ "4": "99.3" #@ } #@ } #@ ``` #+end_src cfengine-3.24.2/examples/isreadable.cf0000644000000000000000000000111515010704253017574 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ echo "Hello CFEngine!" > /tmp/foo.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent __main__ { vars: "filename" string => "/tmp/foo.txt"; "timeout" int => "3"; reports: "File '$(filename)' is readable" if => isreadable("$(filename)", "$(timeout)"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: File '/tmp/foo.txt' is readable #@ ``` #+end_src cfengine-3.24.2/examples/server_copy_localhost.cf0000644000000000000000000000646615010704253022127 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test copy from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-v] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; #fips_mode => "true"; } ######################################################## bundle agent example { files: "/tmp/testcopy" comment => "test copy promise", copy_from => mycopy("/tmp/test-src","127.0.0.1"), perms => system, depth_search => recurse("inf"), classes => satisfied("copy_ok"); "/tmp/testcopy/single_file" comment => "test copy promise", copy_from => mycopy("/tmp/test-src/README","127.0.0.1"), perms => system; reports: copy_ok:: "Files were copied.."; } ######################################################### body perms system { mode => "0644"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } ######################################################### body copy_from mycopy(from,server) { source => "$(from)"; servers => { "$(server)" }; compare => "digest"; encrypt => "true"; verify => "true"; copy_backup => "true"; #/false/timestamp purge => "false"; type_check => "true"; force_ipv4 => "true"; trustkey => "true"; } ######################################################### body classes satisfied(x) { promise_repaired => { "$(x)" }; persist_time => "0"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; # allowusers } ######################################################### bundle server access_rules() { access: "/tmp/test-src" admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/validjson.cf0000644000000000000000000000067515010704253017504 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent main { vars: "json_string" string => '{"test": [1, 2, 3]}'; reports: "This JSON string is valid!" if => validjson("$(json_string)"); "This JSON string is not valid." unless => validjson("$(json_string)"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This JSON string is valid! #@ ``` #+end_src cfengine-3.24.2/examples/log_private.cf0000644000000000000000000000267715010704253020032 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } bundle agent example { vars: "software" slist => { "/root/xyz", "/tmp/xyz" }; files: "$(software)" create => "true", action => logme("$(software)"); } # body action logme(x) { log_kept => "/tmp/private_keptlog.log"; log_failed => "/tmp/private_faillog.log"; log_repaired => "/tmp/private_replog.log"; log_string => "$(sys.date) $(x) promise status"; } cfengine-3.24.2/examples/cf_version_minimum.cf0000644000000000000000000000065415010704253021400 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This will be skipped on older versions" if => cf_version_minimum("3.15"); "This will be skipped on newer or equal versions" unless => cf_version_minimum("3.15"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This will be skipped on older versions #@ ``` #+end_src cfengine-3.24.2/examples/unique.cf0000644000000000000000000000360115010704253017011 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "test_str" string => join(",", "test"); "test_unique" slist => unique("test"); "unique_str" string => join(",", "test_unique"); reports: "The test list is $(test_str)"; "The unique elements of the test list: $(unique_str)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The test list is 1,2,3,one,two,three,long string,four,fix,six,one,two,three #@ R: The unique elements of the test list: 1,2,3,one,two,three,long string,four,fix,six #@ ``` #+end_src cfengine-3.24.2/examples/mustache_sections_non_empty_list.cf0000644000000000000000000000056215010704253024351 0ustar00rootroot00000000000000# Example showing how variables are rendered for non empty lists. #+begin_src cfengine3 bundle agent main { vars: "data" data => '{ "list": [ "1", "2", "3" ] }'; reports: "$(with)" with => string_mustache("{{#list}} {{{.}}}{{/list}}", data); } #+end_src #+begin_src example_output #@ ``` #@ R: 1 2 3 #@ ``` #+end_src cfengine-3.24.2/examples/menu.cf0000644000000000000000000000417015010704253016451 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test copy from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-d2] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } # cf-runagent -q bundle agent example { files: } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowusers => { "mark", "root" }; } ######################################################### bundle server access_rules() { access: "delta" resource_type => "query", admit => { "127.0.0.1" }; "full" resource_type => "query", admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/ip2host.cf0000644000000000000000000000313315010704253017073 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "reverse_lookup" }; } bundle agent reverse_lookup { vars: "local4" string => ip2host("127.0.0.1"); # this will be localhost on some systems, ip6-localhost on others... "local6" string => ip2host("::1"); reports: _cfe_output_testing:: "we got local4" if => isvariable("local4"); !_cfe_output_testing:: "local4 is $(local4)"; "local6 is $(local6)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: we got local4 #@ ``` #+end_src cfengine-3.24.2/examples/local_users_present.cf0000644000000000000000000000133615010704253021561 0ustar00rootroot00000000000000body file control { # This policy uses parts of the standard library. inputs => { "$(sys.libdir)/files.cf" }; } bundle agent main { vars: "users" slist => { "jack", "jill" }; "skel" string => "/etc/skel"; users: linux:: "$(users)" home_dir => "/home/$(users)", policy => "present", home_bundle => home_skel( $(users), $(skel) ); } bundle agent home_skel(user, skel) # @brief Initialize a user's home directory with the contents of skel # @param user The user's home directory to create # @param skel The directory to seed the user's home with { files: "/home/$(user)/." create => "true", copy_from => seed_cp( $(skel) ), depth_search => recurse( "inf" ); } cfengine-3.24.2/examples/peerleaders.cf0000644000000000000000000000606715010704253020007 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo alpha > /tmp/cfe_hostlist #@ echo beta >> /tmp/cfe_hostlist #@ echo gamma >> /tmp/cfe_hostlist #@ echo "Set HOSTNAME appropriately beforehand" #@ touch $CFENGINE_TEST_OVERRIDE_WORKDIR/inputs/promises.cf # to enable cf-promises to run #@ bash -c "${CF_PROMISES} --show-vars=sys.fqhost | grep fqhost | awk '{print \$2}' | tr 'A-Z' 'a-z' 2>&1 >> /tmp/cfe_hostlist" #@ echo "Delta Delta Delta may I help ya help ya help ya" #@ echo delta1 >> /tmp/cfe_hostlist #@ echo delta2 >> /tmp/cfe_hostlist #@ echo delta3 >> /tmp/cfe_hostlist #@ echo may1.I.help.ya >> /tmp/cfe_hostlist #@ echo may2.I.help.ya >> /tmp/cfe_hostlist #@ echo may3.I.help.ya >> /tmp/cfe_hostlist #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "peers" }; } bundle agent peers { vars: "mygroup" slist => peers("/tmp/cfe_hostlist","#.*",4); "myleader" string => peerleader("/tmp/cfe_hostlist","#.*",4); "all_leaders" slist => peerleaders("/tmp/cfe_hostlist","#.*",4); reports: # note that the current host name is fourth in the host list, so # its peer group is the first 4-host group, minus the host itself. "/tmp/cfe_hostlist mypeer $(mygroup)"; # note that the current host name is fourth in the host list, so # the peer leader is "alpha" "/tmp/cfe_hostlist myleader $(myleader)"; "/tmp/cfe_hostlist another leader $(all_leaders)"; "Unable to find my fully qualified hostname $(sys.fqhost) in /tmp/cfe_hostlist. Can't determine peers." if => not( regline( $(sys.fqhost), "/tmp/cfe_hostlist" ) ); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /tmp/cfe_hostlist mypeer alpha #@ R: /tmp/cfe_hostlist mypeer beta #@ R: /tmp/cfe_hostlist mypeer gamma #@ R: /tmp/cfe_hostlist myleader alpha #@ R: /tmp/cfe_hostlist another leader alpha #@ R: /tmp/cfe_hostlist another leader delta1 #@ R: /tmp/cfe_hostlist another leader may2.I.help.ya #@ ``` #+end_src cfengine-3.24.2/examples/postfix.cf0000644000000000000000000000622615010704253017205 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Postfix # ####################################################### body common control { any:: bundlesequence => { postfix }; } ####################################################### bundle agent postfix { vars: "prefix" string => "/home/mark/tmp"; "smtpserver" string => "mailx.domain.tld"; "mailrelay" string => "mailx.domain.tld"; files: "$(prefix)/main.cf" edit_line => prefix_postfix; "$(prefix)/sasl-passwd" create => "true", perms => system("0600","root"), edit_line => AppendIfNSL("$(smtpserver) _$(fqhost):chmsxrcynz4etzefabj9frejizhs22"); } ####################################################### # For the library ####################################################### bundle edit_line prefix_postfix { # # Value have the form NAME = "quoted space separated list" # vars: "ps[relayhost]" string => "[$(postfix.mailrelay)]:587"; "ps[mydomain]" string => "iu.hio.no"; "ps[smtp_sasl_auth_enable]" string => "yes"; "ps[smtp_sasl_password_maps]" string => "hash:/etc/postfix/sasl-passwd"; "ps[smtp_sasl_security_options]" string => ""; "ps[smtp_use_tls]" string => "yes"; "ps[default_privs]" string => "mailman"; "ps[inet_protocols]" string => "all"; "ps[inet_interfaces]" string => "127.0.0.1"; "parameter_name" slist => getindices("ps"); delete_lines: "$(parameter_name).*"; insert_lines: "$(parameter_name) = $(ps[$(parameter_name)])"; } ######################################################## bundle edit_line AppendIfNSL(parameter) { insert_lines: "$(parameter)"; # This is default } ######################################## # Library Bodies ######################################## body replace_with All(x) { replace_value => "$(x)"; occurrences => "all"; } ######################################################### body perms system(x,owner) { mode => "0640"; owners => { "$(owner)", "root" }; } cfengine-3.24.2/examples/software_dist.cf0000644000000000000000000001501415010704253020361 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################################### # # software_local.cf - Application Deployment From Directory Repository # # NOTE: Windows needs to support WMI queries about installed msi files # in order for Cfengine to detect them. On Windows 2003, # go to Control Panel -> Add/Remove Programs -> # Windows Components -> Mgmnt and Monitoring Tools and check # WMI Windows Installer Provider. # # NOTE: Naming conventions are important when updating packages. # By default, Cfengine expects "name-version-arch.msi" # on Windows, where name is lowercase, and arch is # i686 or x86_64. No spaces should be included in the filename. # The Caption and Version fields inside the msi package # are important. They must correspond to the file name as # follows: name = lowercase(spacetodash(Caption)), # version = Version. For any msi-file, use InstEd # (www.instedit.com) to check/modify the # Caption and Version fields # (Tables->Property->ProductName/ProductVersion). # # For example, ProductName "CFEngine Nova" with ProductVersion # "1.1.2" for 32-bit Windows will correspond to the filename # "cfengine-nova-1.1.2-i686.msi". # ######################################################################### body common control { inputs => { "$(sys.libdir)/stdlib.cf" }; bundlesequence => { "check_software" }; } bundle agent check_software { vars: # software to install if not installed "include_software" slist => { "7-zip-4.50-$(sys.arch).msi" }; # this software gets updated if it is installed "autoupdate_software" slist => { "7-zip" }; # software to uninstall if it is installed "exclude_software" slist => { "7-zip-4.65-$(sys.arch).msi" }; methods: # TODO: Fix the following bundles, msi_implicit is giving errors: # "any" usebundle => add_software( "@(check_software.include_software)", "$(sys.policy_hub)" ); # "any" usebundle => update_software( "@(check_software.autoupdate_software)", "$(sys.policy_hub)" ); # "any" usebundle => remove_software( "@(check_software.exclude_software)", "$(sys.policy_hub)" ); } ######################################################################### bundle agent add_software(pkg_name, srv) { vars: # dir to install from locally - can also check multiple directories "local_software_dir" string => "C:\Program Files\Cfengine\software\add"; files: "$(local_software_dir)" copy_from => remote_cp("/var/cfengine/master_software_updates/$(sys.flavour)_$(sys.arch)/add", "$(srv)"), depth_search => recurse("1"), classes => if_repaired("got_newpkg"), comment => "Copy software from remote repository"; packages: # When to check if the package is installed ? got_newpkg|any:: "$(pkg_name)" package_policy => "add", package_method => msi_implicit( "$(local_software_dir)" ), classes => if_else("add_success", "add_fail" ), comment => "Install new software, if not already present"; reports: add_fail:: "Failed to install one or more packages"; } ######################################################################### bundle agent update_software(sw_names, srv) { vars: # dir to install from locally - can also check multiple directories "local_software_dir" string => "C:\Program Files\Cfengine\software\update"; files: "$(local_software_dir)" copy_from => remote_cp("/var/cfengine/master_software_updates/$(sys.flavour)_$(sys.arch)/update", "$(srv)"), depth_search => recurse("1"), classes => if_repaired("got_newpkg"), comment => "Copy software updates from remote repository"; packages: # When to check if the package is updated ? got_newpkg|any:: "$(sw_names)" package_policy => "update", package_select => ">=", # picks the newest update available package_architectures => { "$(sys.arch)" }, # install 32 or 64 bit package ? package_version => "1.0", # at least version 1.0 package_method => msi_explicit( "$(local_software_dir)" ), classes => if_else("update_success", "update_fail"); reports: update_fail:: "Failed to update one or more packages"; } ######################################################################### bundle agent remove_software(pkg_name, srv) { vars: # dir to install from locally - can also check multiple directories "local_software_dir" string => "C:\Program Files\Cfengine\software\remove"; files: "$(local_software_dir)" copy_from => remote_cp("/var/cfengine/master_software_updates/$(sys.flavour)_$(sys.arch)/remove", "$(srv)"), depth_search => recurse("1"), classes => if_repaired("got_newpkg"), comment => "Copy removable software from remote repository"; packages: got_newpkg:: "$(pkg_name)" package_policy => "delete", package_method => msi_implicit( "$(local_software_dir)" ), classes => if_else("remove_success", "remove_fail" ), comment => "Remove software, if present"; reports: remove_fail:: "Failed to remove one or more packages"; } cfengine-3.24.2/examples/Makefile.in0000644000000000000000000005256615010704300017245 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_examples_SCRIPTS) \ $(dist_examples_DATA) $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(examplesdir)" \ "$(DESTDIR)$(examplesdir)" SCRIPTS = $(dist_examples_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(dist_examples_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # examplesdir = $(docdir)/examples dist_examples_DATA = $(srcdir)/*.cf dist_examples_SCRIPTS = remake_outputs.pl FAKE_WORKDIR = /tmp/fake-cfengine-workdir MAINTAINERCLEANFILES = Makefile.in mdate-sh all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-dist_examplesSCRIPTS: $(dist_examples_SCRIPTS) @$(NORMAL_INSTALL) @list='$(dist_examples_SCRIPTS)'; test -n "$(examplesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(examplesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(examplesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(examplesdir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(examplesdir)$$dir" || exit $$?; \ } \ ; done uninstall-dist_examplesSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(dist_examples_SCRIPTS)'; test -n "$(examplesdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(examplesdir)'; $(am__uninstall_files_from_dir) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_examplesDATA: $(dist_examples_DATA) @$(NORMAL_INSTALL) @list='$(dist_examples_DATA)'; test -n "$(examplesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(examplesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(examplesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(examplesdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(examplesdir)" || exit $$?; \ done uninstall-dist_examplesDATA: @$(NORMAL_UNINSTALL) @list='$(dist_examples_DATA)'; test -n "$(examplesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(examplesdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) $(DATA) installdirs: for dir in "$(DESTDIR)$(examplesdir)" "$(DESTDIR)$(examplesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_examplesDATA \ install-dist_examplesSCRIPTS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_examplesDATA \ uninstall-dist_examplesSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_examplesDATA install-dist_examplesSCRIPTS \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags-am uninstall uninstall-am \ uninstall-dist_examplesDATA uninstall-dist_examplesSCRIPTS .PRECIOUS: Makefile # only re-run the outputs for examples that already have an example_output block remake: perl ./remake_outputs.pl $(shell grep -l example_output $(dist_examples_DATA)) recheck: perl ./remake_outputs.pl -c $(shell grep -l example_output $(dist_examples_DATA)) recheck_verbose: perl ./remake_outputs.pl -v -c $(shell grep -l example_output $(dist_examples_DATA)) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/examples/selectservers.cf0000644000000000000000000000372115010704253020377 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Testing some variable/class definitions - note scope # # Use browser -f promise_output_agent.html to view # body common control { bundlesequence => { "test" }; } ########################################################### bundle agent example { vars: "hosts" slist => { "slogans.iu.hio.no", "eternity.iu.hio.no", "nexus.iu.hio.no" }; # selectservers(hostlist,port,sendstr,regex_on_reply,maxbytesread_reply,array_name "up_servers" int => selectservers("@(hosts)","80","","","100","alive_servers"); classes: "someone_alive" expression => isgreaterthan("$(up_servers)","0"); "i_am_a_server" expression => regarray("up_servers","$(host)|$(fqhost)"); reports: someone_alive:: "Number of active servers $(up_servers)" action => always; "First server $(alive_servers[0]) fails over to $(alive_servers[1])"; } ############################################################# body action always { ifelapsed => "0"; } cfengine-3.24.2/examples/reg_multiline.cf0000644000000000000000000000135515010704253020346 0ustar00rootroot00000000000000############################################# # Matching multiple lines in regexp (PCRE) ############################################## body common control { bundlesequence => { "example" }; } bundle agent example { vars: "data" string => "Something boring is written up here. This is the interesting part: KWYDK (know what you don't know)"; classes: # note the (?s) at the beginning of the pattern - this ensures newlines are matched by . "matched" expression => regextract("(?s).*: (.*)", "$(data)", "interesting"); reports: matched:: "This is interesting: \"$(interesting[1])\""; !matched:: "Nothing was interesting!"; } cfengine-3.24.2/examples/customize_by_named_list.cf0000644000000000000000000000472415010704253022425 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test - copy from a single directory of spec files # generating multiple directories and special # edits. # ######################################################## body common control { bundlesequence => { "virtualhosts" }; version => "1.2.3"; } ######################################################## bundle agent virtualhosts { vars: "vmbase" string => "/home/mark/tmp/vm"; "source_files" string => "/home/mark/tmp/src"; # list of hosts to create "hostlist" slist => { "host1", "host2", "host3", "host4", "host5", "host6", "host7", "host8", "host9" }; ################### or just a new file to the dir ################ # # "hostlist" slist => { SelectFilesIn("$(source_files)",".*") } # ################################################################## files: "$(vmbase)/$(hostlist)/config_for_$(hostlist).vm" copy_from => buildvm("$(source_files)/template_$(hostlist)"); # # Now edit config .e.g. edit in $(ipadr[$(hostlist)]) for each # } ######################################################### # library template ######################################################### body copy_from buildvm(from) { source => "$(from)"; copy_backup => "true"; #/false/timestamp } cfengine-3.24.2/examples/process_matching3.cf0000644000000000000000000000340315010704253021116 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test processes # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { processes: ".*" process_select => proc_finder("a.*"), process_count => up("cfservd"); } ######################################################## body process_count up(s) { match_range => "1,10"; # or irange("1","10"); out_of_range_define => { "$(s)_out_of_control" }; } ######################################################## body process_select proc_finder(p) { stime_range => irange(ago("0","0","0","2","0","0"),now); process_result => "stime"; } cfengine-3.24.2/examples/files_transformer.cf0000644000000000000000000000510115010704253021224 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ # Make sure that none of the example files exist to begin with #@ rm -f /tmp/example-files-transformer.txt #@ rm -f /tmp/example-files-transformer.txt.gz #@ rm -f /tmp/this-file-does-not-exist-to-be-transformed.txt #@ rm -f /tmp/this-file-does-not-exist-to-be-transformed.txt.gz #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main { vars: "gzip_path" string => ifelse( isexecutable("/bin/gzip"), "/bin/gzip", "/usr/bin/gzip" ); files: linux:: "/tmp/example-files-transformer.txt" content => "Hello World"; "/tmp/example-files-transformer.txt" transformer => "$(gzip_path) $(this.promiser)"; # The transformer in the following promise results in the promised file # being absent on completion. Note: It is the expectation and # responsibility of the transformer itself that the transformation results # in the promised file no longer existing. "/tmp/example-files-transformer.txt" transformer => "$(gzip_path) $(this.promiser)"; # Since this file does not exist, the transformer will not be triggered # and neither the text file nor a gzip file will exist "/tmp/this-file-does-not-exist-to-be-transformed.txt" transformer => "$(gzip_path) $(this.promiser)"; reports: "/tmp/example-files-transformer.txt $(with)" with => ifelse( fileexists( "/tmp/example-files-transformer.txt"), "exists", "does not exist"); "/tmp/example-files-transformer.txt.gz $(with)" with => ifelse( fileexists( "/tmp/example-files-transformer.txt.gz"), "exists", "does not exist"); "/tmp/this-file-does-not-exist-to-be-transformed.txt $(with)" with => ifelse( fileexists( "/tmp/this-file-does-not-exist-to-be-transformed.txt"), "exists", "does not exist"); "/tmp/this-file-does-not-exist-to-be-transformed.txt.gz $(with)" with => ifelse( fileexists( "/tmp/this-file-does-not-exist-to-be-transformed.txt.gz"), "exists", "does not exist"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /tmp/example-files-transformer.txt does not exist #@ R: /tmp/example-files-transformer.txt.gz exists #@ R: /tmp/this-file-does-not-exist-to-be-transformed.txt does not exist #@ R: /tmp/this-file-does-not-exist-to-be-transformed.txt.gz does not exist #@ ``` #+end_src cfengine-3.24.2/examples/userexists.cf0000644000000000000000000000257715010704253017734 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "ok" expression => userexists("root"); reports: ok:: "Root exists"; !ok:: "Root does not exist"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Root exists #@ ``` #+end_src cfengine-3.24.2/examples/symlink_children.cf0000644000000000000000000000316115010704253021042 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## #+begin_src cfengine3 body file control { inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent main { files: # This will make symlinks to each file in /var/cfengine/bin # for example: # '/usr/local/bin/cf-agent' -> '/var/cfengine/bin/cf-agent' # '/usr/local/bin/cf-serverd' -> '/var/cfengine/bin/cf-serverd' "/usr/local/bin" link_from => linkchildren("/var/cfengine/bin"), comment => "We like for cfengine binaries to be available inside of the common $PATH"; } #+end_src ######################################################## cfengine-3.24.2/examples/active_directory.cf0000644000000000000000000000524015010704253021043 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################################### # active_directory.cf - Extract Data From Windows Domain Controllers # # NOTE: Since we don't supply any credentials in this policy file, # the Domain Controller must allow anonymous bind. Also, # the user "NT AUTHORITY\ANONYMOUS LOGON" must be granted access # to the resources we want to read. # ######################################################################### bundle agent active_directory { vars: # NOTE: Edit this to your domain, e.g. "corp", may also need more DC's after it "domain_name" string => "cftesting"; "user_name" string => "Guest"; # NOTE: We can also extract data from remote Domain Controllers dummy.DomainController:: "domain_controller" string => "localhost"; "userlist" slist => ldaplist( "ldap://$(domain_controller)", "CN=Users,DC=$(domain_name),DC=com", "(objectClass=user)", "sAMAccountName", "subtree", "none"); classes: dummy.DomainController:: "gotuser" expression => ldaparray( "userinfo", "ldap://$(domain_controller)", "CN=$(user_name),CN=Users,DC=$(domain_name),DC=com", "(name=*)", "subtree", "none"); reports: dummy.DomainController:: "Username is \"$(userlist)\""; dummy.gotuser:: "Got user data; $(userinfo[name]) has logged on $(userinfo[logonCount]) times"; } cfengine-3.24.2/examples/randomint.cf0000644000000000000000000000332715010704253017503 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent main { vars: "low" string => "4"; "high" string => "60"; "random" int => randomint($(low), $(high)); classes: "isabove" expression => isgreaterthan($(random), 3); reports: isabove:: "The generated random number was above 3"; show_random:: "Randomly generated '$(random)'"; } #+end_src ############################################################################### #+begin_src show_random_example_output #@ ``` #@ R: The generated random number was above 3 #@ R: Randomly generated '9' #@ R: Randomly generated '52' #@ R: Randomly generated '26' #@ ``` #+end_src #+begin_src example_output #@ ``` #@ R: The generated random number was above 3 #@ ``` #+end_src cfengine-3.24.2/examples/getenv.cf0000644000000000000000000000305415010704253016775 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "myvar" string => getenv("EXAMPLE","2048"); classes: "isdefined" not => strcmp("$(myvar)",""); reports: isdefined:: "The EXAMPLE environment variable is $(myvar)"; !isdefined:: "The environment variable EXAMPLE does not exist"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The EXAMPLE environment variable is getenv.cf #@ ``` #+end_src cfengine-3.24.2/examples/edit.filename.cf0000644000000000000000000000330415010704253020207 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { files: "/tmp/example-edit.filename.txt" content => "Hello World!"; "/tmp/example-edit.filename.txt" edit_line => show_edit_filename; } bundle edit_line show_edit_filename { reports: "$(with)" with => concat( "I found the string 'World' in the file being ", "edited ('$(edit.filename)')"), if => strcmp( "false", "$(edit.empty_before_use)"); # It's probably # useless to probe # the content of the # file if you are # ignoring # pre-existing # content. "$(with)" with => concat( "It's probably not very useful to inspect content", "that is being thrown away." ), if => strcmp( "true", "$(edit.empty_before_use)"); "$(with)" with => concat ( "This version of CFEngine does not know if the", "edit operation is expected to ignore pre-existing ", "content the variable 'edit.empty_before_use' does ", "not exist"), unless => isvariable ( "edit.empty_before_use" ); } body edit_defaults my_empty_file_before_editing { empty_file_before_editing => "true"; # The variable # edit.empty_before_use allows this # to be known from within an # edit_line bundle. } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: I found the string 'World' in the file being edited ('/tmp/example-edit.filename.txt') #@ ``` #+end_src cfengine-3.24.2/examples/local_group_present.cf0000644000000000000000000000051515010704253021552 0ustar00rootroot00000000000000body file control { # This policy uses parts of the standard library. inputs => { "$(sys.libdir)/paths.cf" }; } bundle agent main { classes: "group_cfengineers_absent" not => groupexists("cfengineers"); commands: linux.group_cfengineers_absent:: "$(paths.groupadd)" args => "cfengineers"; } cfengine-3.24.2/examples/method.cf0000644000000000000000000000272015010704253016764 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; version => "1.2.3"; } ########################################### bundle agent example { vars: "userlist" slist => { "mark", "jeang", "jonhenrik", "thomas", "eben" }; methods: "any" usebundle => subtest("$(userlist)"); } ########################################### bundle agent subtest(user) { commands: "/bin/echo Fix $(user)"; reports: "Finished doing stuff for $(user)"; } cfengine-3.24.2/examples/iprange.cf0000644000000000000000000000257515010704253017141 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { classes: "adhoc_group_1" expression => iprange("192.168.1.50-140"); "adhoc_group_2" expression => iprange("192.168.1.0/24"); reports: adhoc_group_1:: "Some numerology"; adhoc_group_2:: "The masked warriors"; } cfengine-3.24.2/examples/function-return-types.cf0000644000000000000000000000662015010704253022013 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ printf "one\ntwo\nthree\n" > /tmp/list.txt #@ printf "1\n2\n3\n" >> /tmp/list.txt #@ printf "1.0\n2.0\n3.0" >> /tmp/list.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent example_function_return_types # @brief Example showing function return types { classes: "this_file_exists" expression => fileexists( $(this.promise_filename) ); vars: "my_string" string => concat( "Promises you cannot keep", " are no better than lies"); "my_list_of_strings" slist => readstringlist( "/tmp/list.txt", # File to read "", # Don't ignore any lines "\n", # Split on newlines inf, # Extract as many entries as possible inf); # Read in as much data as possible "my_list_of_integers" ilist => readintlist( "/tmp/list.txt", # File to read "^(\D+)|(\d+[^\n]+)", # Ignore any lines that are not integers "\n", # Split on newlines inf, # Maximum number of entries inf); # Maximum number of bytes to read "my_list_of_reals" rlist => readreallist( "/tmp/list.txt", # File to read "^(\D+)", # Ignore any lines that are not digits "\n", # Split on newlines inf, # Maximum number of entries inf); # Maximum number of bytes to read "my_integer" int => string_length( $(my_string) ); "my_real" real => sum( my_list_of_integers ); "my_data" data => mergedata( '{ "Hello": "world!" }' ); reports: "my_string: '$(my_string)'"; "my_list_of_strings includes '$(my_list_of_strings)'"; "my_list_of_integers includes '$(my_list_of_integers)'"; "my_list_of_reals includes '$(my_list_of_reals)'"; "my_integer: '$(my_integer)'"; "my_real: '$(my_real)'"; "my_data: '$(with)'" with => string_mustache( "{{%-top-}}", my_data ); this_file_exists:: "This file exists."; } bundle agent __main__ { methods: "example_function_return_types"; } #+end_src #+begin_src example_output #@ ``` #@ R: my_string: 'Promises you cannot keep are no better than lies' #@ R: my_list_of_strings includes 'one' #@ R: my_list_of_strings includes 'two' #@ R: my_list_of_strings includes 'three' #@ R: my_list_of_strings includes '1' #@ R: my_list_of_strings includes '2' #@ R: my_list_of_strings includes '3' #@ R: my_list_of_strings includes '1.0' #@ R: my_list_of_strings includes '2.0' #@ R: my_list_of_strings includes '3.0' #@ R: my_list_of_integers includes '1' #@ R: my_list_of_integers includes '2' #@ R: my_list_of_integers includes '3' #@ R: my_list_of_reals includes '1' #@ R: my_list_of_reals includes '2' #@ R: my_list_of_reals includes '3' #@ R: my_list_of_reals includes '1.0' #@ R: my_list_of_reals includes '2.0' #@ R: my_list_of_reals includes '3.0' #@ R: my_integer: '48' #@ R: my_real: '6.000000' #@ R: my_data: '{ #@ "Hello": "world!" #@ }' #@ R: This file exists. #@ ``` #+end_src cfengine-3.24.2/examples/varexpansion.cf0000644000000000000000000000267215010704253020227 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "scalar1" string => "SCALAR 1"; "list1" slist => { "LIST1_1", "LIST1_2" } ; "array[1]" string => "ARRAY 1"; "array[2]" string => "ARRAY 2"; "i" slist => getindices("array"); reports: "Scalar $(scalar1)"; "LIst $(list1)"; "Array $(array[$(i)])"; } cfengine-3.24.2/examples/mustache_classes.cf0000644000000000000000000000361615010704253021037 0ustar00rootroot00000000000000# Example showing how sections are rendered using cfengine classes # Being a logicless templating system, mustache is not able to leverage # CFEngine's powerful class expression logic. Only singular classes can be used # to conditionally render a block in mustache. This example shows how you can # define a singular cfengine class based on a complex expression, and then use # that singular class for conditional rendering in a template. #+begin_src cfengine3 bundle agent main { classes: "known_day_of_week" expression => "(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)"; vars: "rendered" string => string_mustache( "{{#classes.known_day_of_week}}I recognize the day of the week.{{/classes.known_day_of_week}} {{^classes.class_you_are_looking_for}} The class you are looking for is not defined. {{/classes.class_you_are_looking_for}}", datastate()); reports: "$(rendered)"; } #+end_src #+begin_src policy_description #@ Here we define the class `known_day_of_week` as long as there is a class #@ representing a known day. Then we render the value of the string variable #@ "rendered" using `string_mustache()` with a template that includes a section #@ that is conditional when `classes.known_day_of_week` is `true` and another section #@ when `classes.class_you_are_looking_for` is not defined based on the data #@ provided from `datastate()` which is the default set of data to use for mustache #@ templates when explicit data is not provided. Finally we report the variable to #@ see the rendered template. #+end_src #+begin_src example_output #@ ``` #@ R: I recognize the day of the week. #@ The class you are looking for is not defined. #@ #@ ``` #+end_src #+begin_src output_description #@ We can see in the output that the conditional text was rendered as expected. #@ Try adjusting the template or the class expression. #+end_src cfengine-3.24.2/examples/appgroups.cf0000644000000000000000000001177415010704253017535 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { run }; } bundle agent run { vars: # you can also readjson() from a file "groups" data => parsejson('{ "ByGroup": { "App1": [ "GrpA", "GrpB", "GrpC" ], "App2": [ "GrpX", "GrpY", "GrpZ" ] }, "ByApp": { "App1": [ "Host1", "Host2", "Host3" ], "App2": [ "Host1", "Host3" ] } }'); methods: # use the first one on the client #"go" usebundle => appgroups($(sys.uqhost), @(groups)); "go" usebundle => appgroups("Host1", @(groups)); "go" usebundle => appgroups("Host2", @(groups)); } bundle agent appgroups(name, g) { classes: # stage (3) now for each APP, define have_app_APP if the host is in APP's host list "have_app_$(apps)" expression => strcmp($(name), "$(hosts_$(apps))"); # stage (4) define the class have_group_GROUP for every GROUP belonging to APP "have_group_$(groups_$(apps))" expression => "have_app_$(apps)"; # stage (5) define the class have_group if we found any groups "have_group" not => strcmp("0", length("$(cname)_list")); vars: # stage (1) start here: we get the apps from the list of "by app" keys "apps" slist => getindices("g[ByApp]"); "apps_str" string => format("%S", "apps"); # stage (2) now for each app, we collect the hosts assigned to it "hosts_$(apps)" slist => getvalues("g[ByApp][$(apps)]"); "hosts_$(apps)_str" string => format("%S", "hosts_$(apps)"); # stage (2) now for each app, we collect the groups assigned to it "groups_$(apps)" slist => getvalues("g[ByGroup][$(apps)]"); "groups_$(apps)_str" string => format("%S", "groups_$(apps)"); # stage (5) collect the space-separated group names from an intermediate array "cname" string => canonify($(name)); "$(cname)_grouplist[$(groups_$(apps))]" string => "1", if => "have_app_$(apps)"; "$(cname)_grouplist_slist" slist => getvalues("$(cname)_grouplist"); # get the keys of the array and sort them, then join with spaces "$(cname)_list" slist => getindices("$(cname)_grouplist"); "$(cname)_list_sorted" slist => sort("$(cname)_list", "lex"); "$(cname)_list_spaces" string => join(" ", "$(cname)_list_sorted"); reports: # stage (1) "$(this.bundle): looking for $(name)"; "$(this.bundle): apps: $(apps_str)"; # stage (2) "$(this.bundle): hosts for $(apps): $(hosts_$(apps)_str)"; "$(this.bundle): groups for $(apps): $(groups_$(apps)_str)"; # stage (3) "$(this.bundle): $(name) is assigned $(apps)" if => "have_app_$(apps)"; # stage (4) "$(this.bundle): all groups for $(name) = $(groups_$(apps))" if => "have_group_$(groups_$(apps))"; # stage (5) have_group:: "$(this.bundle): space-separated groups for $(name) = $($(cname)_list_spaces)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: appgroups: looking for Host1 #@ R: appgroups: apps: { "App1", "App2" } #@ R: appgroups: hosts for App1: { "Host1", "Host2", "Host3" } #@ R: appgroups: hosts for App2: { "Host1", "Host3" } #@ R: appgroups: groups for App1: { "GrpA", "GrpB", "GrpC" } #@ R: appgroups: groups for App2: { "GrpX", "GrpY", "GrpZ" } #@ R: appgroups: Host1 is assigned App1 #@ R: appgroups: Host1 is assigned App2 #@ R: appgroups: all groups for Host1 = GrpA #@ R: appgroups: all groups for Host1 = GrpB #@ R: appgroups: all groups for Host1 = GrpC #@ R: appgroups: all groups for Host1 = GrpX #@ R: appgroups: all groups for Host1 = GrpY #@ R: appgroups: all groups for Host1 = GrpZ #@ R: appgroups: space-separated groups for Host1 = GrpA GrpB GrpC GrpX GrpY GrpZ #@ R: appgroups: looking for Host2 #@ R: appgroups: Host2 is assigned App1 #@ R: appgroups: all groups for Host2 = GrpA #@ R: appgroups: all groups for Host2 = GrpB #@ R: appgroups: all groups for Host2 = GrpC #@ R: appgroups: space-separated groups for Host2 = GrpA GrpB GrpC #@ ``` #+end_src cfengine-3.24.2/examples/edit_template.cf0000644000000000000000000000050215010704253020320 0ustar00rootroot00000000000000 body common control { bundlesequence => { "main" }; } bundle agent main { vars: "here" string => "/home/a10004/LapTop/cfengine/core/examples"; "list" slist => { "one", "two", "three" }; files: "/tmp/output" create => "true", edit_template => "$(here)/input.edittemplate"; } cfengine-3.24.2/examples/mergedata.cf0000644000000000000000000001230015010704253017430 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test", "test2", "test3" }; } bundle agent test { vars: "d1" data => parsejson('{ "a": [1,2,3], "b": [] }'); "d2" data => parsejson('{ "b": [4,5,6] }'); "d3" data => parsejson('[4,5,6]'); "list1" slist => { "element1", "element2" }; "array1[mykey]" slist => { "array_element1", "array_element2" }; "array2[otherkey]" string => "hello"; "merged_d1_d2" data => mergedata("d1", "d2"); "merged_d1_d3" data => mergedata("d1", "d3"); "merged_d3_list1" data => mergedata("d3", "list1"); "merged_d1_array1" data => mergedata("d1", "array1"); "merged_d2_array2" data => mergedata("d2", "array2"); "merged_d1_wrap_array_d2" data => mergedata("d1", "[ d2 ]"); "merged_d1_wrap_map_d2" data => mergedata("d1", '{ "newkey": d2 }'); "merged_d1_d2_str" string => format("merging %S with %S produced %S", d1, d2, merged_d1_d2); "merged_d1_wrap_array_d2_str" string => format("merging %S with wrapped [ %S ] produced %S", d1, d2, merged_d1_wrap_array_d2); "merged_d1_wrap_map_d2_str" string => format('merging %S with wrapped { "newkey": %S produced %S', d1, d2, merged_d1_wrap_map_d2); "merged_d1_d3_str" string => format("merging %S with %S produced %S", d1, d3, merged_d1_d3); "merged_d3_list1_str" string => format("merging %S with %S produced %S", d3, list1, merged_d3_list1); "merged_d1_array1_str" string => format("merging %S with %s produced %S", d1, array1, merged_d1_array1); "merged_d2_array2_str" string => format("merging %S with %s produced %S", d2, array2, merged_d2_array2); reports: "$(merged_d1_d2_str)"; "$(merged_d1_wrap_array_d2_str)"; "$(merged_d1_wrap_map_d2_str)"; "$(merged_d1_d3_str)"; "$(merged_d3_list1_str)"; "$(merged_d1_array1_str)"; "$(merged_d2_array2_str)"; } bundle agent test2 { vars: "a" data => parsejson('{ "a": "1" }'), meta => { "mymerge" }; "b" data => parsejson('{ "b": "2" }'), meta => { "mymerge" }; "c" data => parsejson('{ "c": "3" }'), meta => { "mymerge" }; "d" data => parsejson('{ "d": "4" }'), meta => { "mymerge" }; "todo" slist => variablesmatching(".*", "mymerge"); methods: "go" usebundle => cmerge(@(todo)); # a, b, c, d reports: "$(this.bundle): merged containers with cmerge = $(cmerge.all_str)"; } # note this bundle is in the standard library, in lib/3.6/bundles.cf bundle agent cmerge(varlist) { vars: "all" data => parsejson('[]'), policy => "free"; "all" data => mergedata(all, $(varlist)), policy => "free"; "all_str" string => format("%S", all), policy => "free"; } bundle agent test3 { vars: "dest_files" slist => { "/tmp/default.json", "/tmp/epel.json" }; "template_file" string => "repository.mustache"; "process_templates" data => mergedata('{ "$(template_file)" : dest_files }'); "process__templates_str" string => format("%S", "process_templates"); reports: "$(this.bundle) $(process__templates_str)"; "$(this.bundle) $(process_templates[$(template_file)])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: merging {"a":[1,2,3],"b":[]} with {"b":[4,5,6]} produced {"a":[1,2,3],"b":[4,5,6]} #@ R: merging {"a":[1,2,3],"b":[]} with wrapped [ {"b":[4,5,6]} ] produced {"0":{"b":[4,5,6]},"a":[1,2,3],"b":[]} #@ R: merging {"a":[1,2,3],"b":[]} with wrapped { "newkey": {"b":[4,5,6]} produced {"a":[1,2,3],"b":[],"newkey":{"b":[4,5,6]}} #@ R: merging {"a":[1,2,3],"b":[]} with [4,5,6] produced {"0":4,"1":5,"2":6,"a":[1,2,3],"b":[]} #@ R: merging [4,5,6] with { "element1", "element2" } produced [4,5,6,"element1","element2"] #@ R: merging {"a":[1,2,3],"b":[]} with array1 produced {"a":[1,2,3],"b":[],"mykey":["array_element1","array_element2"]} #@ R: merging {"b":[4,5,6]} with array2 produced {"b":[4,5,6],"otherkey":"hello"} #@ R: test2: merged containers with cmerge = {"a":"1","b":"2","c":"3","d":"4"} #@ R: test3 {"repository.mustache":["/tmp/default.json","/tmp/epel.json"]} #@ R: test3 /tmp/default.json #@ R: test3 /tmp/epel.json #@ ``` #+end_src cfengine-3.24.2/examples/id.cf0000644000000000000000000000505315010704253016102 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test of promise references # ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { vars: classes: files: "/home/mark/tmp/testcopy" copy_from => mycopy("/home/mark/LapTop/words","127.0.0.1"), perms => system, depth_search => recurse("inf"); } ######################################################### body perms system { mode => "0644"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } ######################################################### body copy_from mycopy(from,server) { source => "$(from)"; servers => { "$(server)" }; copy_backup => "true"; #/false/timestamp purge => "false"; type_check => "true"; force_ipv4 => "true"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "/home/mark/LapTop" handle => "update_rule", admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/style_hungarian.cf0000644000000000000000000000266215010704253020705 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { vars: "s_one" string => "one"; "ITwo" int => "2"; "rThree" real => "3.0"; "lMyList" slist => { "$(s_one)", "$(ITwo)", "$(rThree)" }; methods: "Iteration inside (bundle called once)" usebundle => dollar_vs_at( @(lMyList) ); "Iteration outside (bundle called length(lMyList) times)" usebundle => dollar_vs_at( $(lMyList) ); } bundle agent dollar_vs_at( myParam ) { vars: "myParamType" string => type( myParam ); classes: "myParamType_slist" expression => strcmp( $(myParamType), "slist" ); "myParamType_string" expression => strcmp( $(myParamType), "string" ); reports: "Bundle promised by '$(with)'" with => nth( reverse( callstack_promisers() ), 0 ); myParamType_slist:: "myParam is of type '$(myParamType)' with value $(with)" with => join( ", ", @(myParam) ); myParamType_string:: "myParam is of type '$(myParamType)' with value $(myParam)"; } #+end_src cfengine3 #+begin_src example_output #@ ``` #@ R: Bundle promised by 'Iteration inside (bundle called once)' #@ R: myParam is of type 'slist' with value one, 2, 3.000000 #@ R: Bundle promised by 'Iteration outside (bundle called length(lMyList) times)' #@ R: myParam is of type 'string' with value one #@ R: myParam is of type 'string' with value 2 #@ R: myParam is of type 'string' with value 3.000000 #@ ``` #+end_src cfengine-3.24.2/examples/mustache_extension_top.cf0000644000000000000000000000105515010704253022273 0ustar00rootroot00000000000000# Example showing how -top- gives access to the entire data provided to a mustache template. #+begin_src cfengine3 bundle agent main { vars: "data" data => '{ "key": "value", "list": [ "1", "2" ] }'; reports: "-top- contains$(const.n)$(with)" with => string_mustache("{{%-top-}}", data ); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: -top- contains #@ { #@ "key": "value", #@ "list": [ #@ "1", #@ "2" #@ ] #@ } #@ ``` #+end_src cfengine-3.24.2/examples/regarray.cf0000644000000000000000000000300215010704253017312 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "myarray[0]" string => "bla1"; "myarray[1]" string => "bla2"; "myarray[3]" string => "bla"; classes: "ok" expression => regarray("myarray","b.*2"); reports: ok:: "Found in list"; !ok:: "Not found in list"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found in list #@ ``` #+end_src cfengine-3.24.2/examples/max-min-mean-variance.cf0000644000000000000000000000501615010704253021557 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: # the behavior will be the same whether you use a data container or a list # "mylist" slist => { "foo", "1", "2", "3000", "bar", "10.20.30.40" }; "mylist" data => parsejson('["foo", "1", "2", "3000", "bar", "10.20.30.40"]'); "mylist_str" string => format("%S", mylist); "max_int" string => max(mylist, "int"); "max_lex" string => max(mylist, "lex"); "max_ip" string => max(mylist, "ip"); "min_int" string => min(mylist, "int"); "min_lex" string => min(mylist, "lex"); "min_ip" string => min(mylist, "ip"); "mean" real => mean(mylist); "variance" real => variance(mylist); reports: "my list is $(mylist_str)"; "mean is $(mean)"; "variance is $(variance) (use eval() to get the standard deviation)"; "max int is $(max_int)"; "max IP is $(max_ip)"; "max lexicographically is $(max_lex)"; "min int is $(min_int)"; "min IP is $(min_ip)"; "min lexicographically is $(min_lex)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: my list is ["foo","1","2","3000","bar","10.20.30.40"] #@ R: mean is 502.200000 #@ R: variance is 1497376.000000 (use eval() to get the standard deviation) #@ R: max int is 3000 #@ R: max IP is 10.20.30.40 #@ R: max lexicographically is foo #@ R: min int is bar #@ R: min IP is 1 #@ R: min lexicographically is 1 #@ ``` #+end_src cfengine-3.24.2/examples/reverse.cf0000644000000000000000000000371015010704253017157 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "one", "two", "three", }; "reversed" slist => reverse("test"); reports: "Original list is $(test)"; "The reversed list is $(reversed)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Original list is 1 #@ R: Original list is 2 #@ R: Original list is 3 #@ R: Original list is one #@ R: Original list is two #@ R: Original list is three #@ R: Original list is long string #@ R: The reversed list is three #@ R: The reversed list is two #@ R: The reversed list is one #@ R: The reversed list is long string #@ R: The reversed list is 3 #@ R: The reversed list is 2 #@ R: The reversed list is 1 #@ ``` #+end_src cfengine-3.24.2/examples/parseintarray.cf0000644000000000000000000000335215010704253020372 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test(f) { vars: # Define data inline for convenience "table" string => "1:2 3:4 5:6"; "dim" int => parseintarray( "items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000" ); "keys" slist => sort(getindices("items")); reports: "$(keys)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: 1 #@ R: 3 #@ R: 5 #@ ``` #+end_src cfengine-3.24.2/examples/getgid.cf0000644000000000000000000000272315010704253016752 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: linux|solaris|hpux:: "gid" int => getgid("root"); freebsd|darwin|openbsd:: "gid" int => getgid("wheel"); aix:: "gid" int => getgid("system"); reports: "root's gid is $(gid)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: root's gid is 0 #@ ``` #+end_src cfengine-3.24.2/examples/package_zypper.cf0000644000000000000000000000276215010704253020516 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Package management # body common control { bundlesequence => { "packages" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ############################################# bundle agent packages { vars: # Test the simplest case -- leave everything to the zypper smart manager "match_package" slist => { "apache2", "apache2-mod_php5", "apache2-prefork", "php5" }; packages: "$(match_package)" package_policy => "add", package_method => zypper; } cfengine-3.24.2/examples/style_camelCase.cf0000644000000000000000000000156715010704253020611 0ustar00rootroot00000000000000bundle agent __main__ { methods: "Ssh"; } bundle agent ssh { vars: "serviceName" string => "ssh"; "configFile" string => "/etc/ssh/sshd_config"; "conf[Port]" string => "22"; files: "$(configFile)" edit_line => default:set_line_based("$(this.bundle).conf", " ", "\s+", ".*", "\s*#\s*"), classes => default:results( "bundle", "$(configFile)"); services: _etc_ssh_sshd_config_repaired:: "$(serviceName)" service_policy => "restart", classes => default:results( "bundle", "$(serviceName)_restart"); reports: ssh_restart_repaired._etc_ssh_sshd_config_repaired:: "We restarted ssh because the config file was repaired"; } cfengine-3.24.2/examples/storage-cifs.cf0000644000000000000000000000130115010704253020064 0ustar00rootroot00000000000000bundle agent main # @brief Example illustrating CIFS/Samba storage type promise mount { vars: redhat|centos:: "cifs" data => '{ "server": "192.168.42.251", "path": "/Audio" }'; packages: redhat|centos:: "cifs-utils" policy => "present"; "samba-client" policy => "present"; files: redhat|centos:: "/mnt/CIFS/." create => "true"; storage: redhat|centos:: "/mnt/CIFS" mount => cifs_guest( $(cifs[server]) , $(cifs[path]) ); } body mount cifs_guest(server,source) { mount_type => "cifs"; mount_source => "$(source)"; mount_server => "$(server)"; mount_options => { "guest" }; edit_fstab => "false"; } cfengine-3.24.2/examples/filenames.cf0000644000000000000000000000234115010704253017446 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # filenames # body common control { bundlesequence => { "example" }; } bundle agent example { files: "/etc/passwd" create => "true"; "C:\etc\passwd" create => "true"; "etc/passwd" create => "true"; } cfengine-3.24.2/examples/inline-json.cf0000644000000000000000000000232615010704253017733 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent example_inline_json # @brief Example illustrating inline json { vars: "json_multi_line" data => '{ "CFEngine Champions": [ { "Name": "Aleksey Tsalolikhin", "Year": "2011" }, { "Name": "Ted Zlatanov", "Year": "2013" } ] }'; "json_single_line" data => '[{"key1":"value1"},{"key2":"value2"}]'; reports: "Data container defined from json_multi_line: $(with)" with => storejson( @(json_multi_line) ); "Data container defined from json_single_line: $(with)" with => storejson( @(json_single_line) ); } bundle agent __main__ { methods: "example_inline_json"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Data container defined from json_multi_line: { #@ "CFEngine Champions": [ #@ { #@ "Name": "Aleksey Tsalolikhin", #@ "Year": "2011" #@ }, #@ { #@ "Name": "Ted Zlatanov", #@ "Year": "2013" #@ } #@ ] #@ } #@ R: Data container defined from json_single_line: [ #@ { #@ "key1": "value1" #@ }, #@ { #@ "key2": "value2" #@ } #@ ] #@ ``` #+end_src cfengine-3.24.2/examples/tidy_all_files.cf0000644000000000000000000000415515010704253020473 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Deleting files, like cf2 tidy age=0 r=inf # ####################################################### body common control { any:: bundlesequence => { "example" }; } ############################################ bundle agent example { files: "/home/mark/tmp/test_to" delete => tidyfiles, file_select => zero_age, depth_search => recurse("inf"); # Now delete the parent. "/home/mark/tmp/testcopy" delete => tidyfiles; } ######################################################### body depth_search recurse(d) { #include_basedir => "true"; depth => "$(d)"; } ######################################################### body delete tidyfiles { dirlinks => "delete"; rmdirs => "true"; } ######################################################### body file_select zero_age # # we can build old "include", "exclude", and "ignore" # from these as standard patterns - these bodies can # form a library of standard patterns # { mtime => irange(ago(1,0,0,0,0,0),now); file_result => "mtime"; } cfengine-3.24.2/examples/regcmp.cf0000644000000000000000000000275315010704253016767 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { subtest("mark") }; } bundle agent subtest(user) { classes: "invalid" not => regcmp("[a-z]{4}","$(user)"); reports: !invalid:: "User name $(user) is valid at exactly 4 letters"; invalid:: "User name $(user) is invalid"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: User name mark is valid at exactly 4 letters #@ ``` #+end_src cfengine-3.24.2/examples/filter.cf0000644000000000000000000001164215010704253016774 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "one", "two", "three", }; "test2" data => parsejson('[1,2,3, "ab", "c"]'); "test_filtergrep" slist => filter("[0-9]", test, "true", "false", 999); "test_exact1" slist => filter("one", test, "false", "false", 999); "test_exact2" slist => filter(".", test, "false", "false", 999); "test_invert" slist => filter("[0-9]", test, "true", "true", 999); "test_max2" slist => filter(".*", test, "true", "false", 2); "test_max0" slist => filter(".*", test, "true", "false", 0); "test_grep" slist => grep("[0-9]", test); "test2_filtergrep" slist => filter("[0-9]", test2, "true", "false", 999); "test2_exact1" slist => filter("one", test2, "false", "false", 999); "test2_exact2" slist => filter(".", test2, "false", "false", 999); "test2_invert" slist => filter("[0-9]", test2, "true", "true", 999); "test2_max2" slist => filter(".*", test2, "true", "false", 2); "test2_max0" slist => filter(".*", test2, "true", "false", 0); "test2_grep" slist => grep("[0-9]", test2); "todo" slist => { "test", "test2", "test_filtergrep", "test_exact1", "test_exact2", "test_invert", "test_max2", "test_max0", "test_grep", "test2_filtergrep", "test2_exact1", "test2_exact2", "test2_invert", "test2_max2", "test2_max0", "test2_grep"}; "$(todo)_str" string => format("%S", $(todo)); "tests" slist => { "test", "test2" }; reports: "The $(tests) list is $($(tests)_str)"; "The grepped list (only single digits from $(tests)) is $($(tests)_grep_str)"; "The filter-grepped list (only single digits from $(tests)) is $($(tests)_grep_str)"; "The filter-exact list, looking for only 'one' in $(tests), is $($(tests)_exact1_str)"; "This list should be empty, the '.' is not literally in the list $(tests): $($(tests)_exact2_str)"; "The filter-invert list, looking for non-digits in $(tests), is $($(tests)_invert_str)"; "The filter-bound list, matching at most 2 items from the whole list $(tests), is $($(tests)_max2_str)"; "This list should be empty because 0 elements of $(tests) were requested: $($(tests)_max0_str)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The test list is { "1", "2", "3", "one", "two", "three", "long string", "one", "two", "three" } #@ R: The test2 list is [1,2,3,"ab","c"] #@ R: The grepped list (only single digits from test) is { "1", "2", "3" } #@ R: The grepped list (only single digits from test2) is { "1", "2", "3" } #@ R: The filter-grepped list (only single digits from test) is { "1", "2", "3" } #@ R: The filter-grepped list (only single digits from test2) is { "1", "2", "3" } #@ R: The filter-exact list, looking for only 'one' in test, is { "one", "one" } #@ R: The filter-exact list, looking for only 'one' in test2, is { } #@ R: This list should be empty, the '.' is not literally in the list test: { } #@ R: This list should be empty, the '.' is not literally in the list test2: { } #@ R: The filter-invert list, looking for non-digits in test, is { "one", "two", "three", "long string", "one", "two", "three" } #@ R: The filter-invert list, looking for non-digits in test2, is { "ab", "c" } #@ R: The filter-bound list, matching at most 2 items from the whole list test, is { "1", "2" } #@ R: The filter-bound list, matching at most 2 items from the whole list test2, is { "1", "2" } #@ R: This list should be empty because 0 elements of test were requested: { } #@ R: This list should be empty because 0 elements of test2 were requested: { } #@ ``` #+end_src cfengine-3.24.2/examples/readcsv.cf0000644000000000000000000000322115010704253017130 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo -n 1,2,3 > /tmp/csv #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main { vars: # note that the CSV file has to have ^M (DOS) EOL terminators # thus the prep step uses `echo -n` and just one line, so it will work on Unix "csv" data => readcsv("/tmp/csv"); "csv_str" string => format("%S", csv); reports: "From /tmp/csv, got data $(csv_str)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: From /tmp/csv, got data [["1","2","3"]] #@ ``` #+end_src cfengine-3.24.2/examples/symlink.cf0000644000000000000000000000305715010704253017176 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## body file control { inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent main { files: # We use move_obstructions because we want the symlink to replace a # regular file if necessary. "/etc/apache2/sites-enabled/www.cfengine.com" -> { "webmaster@cfengine.com" } link_from => ln_s( "/etc/apache2/sites-available/www.cfengine.com" ), move_obstructions => "true", comment => "We always want our website to be enabled."; } ######################################################### cfengine-3.24.2/examples/activedirectory_showuser.cf0000644000000000000000000000273415010704253022650 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # List users from Active Directory through LDAP # Note: Anonymous LDAP binding must be allowed, and the Anonymous user # must have read access to CN=Users and CN=theusername # Run the agent in verbose mode to see the data bundle agent ldap { classes: "gotdata" expression => ldaparray( "myarray", "ldap://cf-win2003", "CN=Test Pilot,CN=Users,DC=domain,DC=cf-win2003", "(name=*)", "subtree", "none"); reports: gotdata:: "Got user data"; !gotdata:: "Did not get user data"; } cfengine-3.24.2/examples/basename.cf0000644000000000000000000000134115010704253017255 0ustar00rootroot00000000000000############################################################################### #+begin_src cfengine3 bundle agent main # @brief Example illustrating the behavior of basename() { vars: "basename" -> { "CFE-3196" } string => basename( $(this.promise_filename) ); "basename_wo_extension" -> { "CFE-3196" } string => basename( $(this.promise_filename), ".cf" ); reports: "basename = '$(basename)'"; "basename without '.cf' extension = '$(basename_wo_extension)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: basename = 'basename.cf' #@ R: basename without '.cf' extension = 'basename' #@ ``` #+end_example cfengine-3.24.2/examples/reports.cf0000644000000000000000000000276115010704253017207 0ustar00rootroot00000000000000# Example policy showing features of reports type promises bundle agent main { reports: "It's recommended that you always guard reports" comment => "Remember by default output from cf-agent when run from cf-execd will be emailed"; DEBUG|DEBUG_main:: "Run with --define DEBUG or --define DEBUG_main to display this report"; methods: "Actuate bundle that reports with a return value" usebundle => bundle_with_return_value, useresult => "return_array", comment => "Reports can be used to return data into a parent bundle. This is useful in some re-usable bundle patterns."; reports: "I got '$(return_array[key])' returned from bundle_with_return_value"; "Reports can be redirected and appended to files" report_to_file => "$(sys.workdir)/report_output.txt", comment => "It's important to note that this will suppress the report from stdout."; "Report content of a file:$(const.n)$(const.n)------------------------" printfile => cat( $(this.promise_filename) ); } bundle agent bundle_with_return_value { reports: "value from bundle_with_return_value" bundle_return_value_index => "key"; } body printfile cat(file) { file_to_print => "$(file)"; number_of_lines => "inf"; } @if minimum_version(3.8) body printfile head(file) { inherit_from => "cat"; # GNU head defaults to 10 number_of_lines => "10"; } @endif cfengine-3.24.2/examples/findfiles.cf0000644000000000000000000000300415010704253017443 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { run }; } bundle agent run { vars: "findtmp" slist => findfiles("/[tT][mM][pP]"); # or find all .txt files under /tmp, up to 6 levels deep... # "findtmp" slist => findfiles("/tmp/**/*.txt"); reports: "All files that match '/[tT][mM][pP]' = $(findtmp)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: All files that match '/[tT][mM][pP]' = /tmp #@ ``` #+end_src cfengine-3.24.2/examples/edit_setvar.cf0000644000000000000000000000355015010704253020017 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Edit variable = value in a text file # ####################################################### body common control { bundlesequence => { "example" }; } ####################################################### bundle agent example { vars: "v[variable_1]" string => "value_1"; "v[variable_2]" string => "value_2"; files: "/tmp/test_setvar" edit_line => setvars_v1("testsetvar.v"); } ####################################################### # For the library ####################################################### bundle edit_line setvars_v1(contexted_array_name) { vars: "parameter_name" slist => getindices("$(contexted_array_name)"); delete_lines: "$(parameter_name).*"; insert_lines: "$(parameter_name) = $($(contexted_array_name)[$(parameter_name)])"; } cfengine-3.24.2/examples/files-content-if-fileexists.cf0000644000000000000000000000063015010704253023025 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ rm -f /tmp/hello && touch /tmp/hello #@ ``` #+end_src #+begin_src cfengine3 body agent control { inform => "true"; } bundle agent __main__ { files: "/tmp/hello" content => "Hello, CFEngine", if => fileexists("/tmp/hello"); } #+end_src #+begin_src example_output #@ ``` #@ info: Updated file '/tmp/hello' with content 'Hello, CFEngine' #@ ``` #+end_src cfengine-3.24.2/examples/vars.cf0000644000000000000000000000226415010704253016462 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => {"yes"}; } bundle agent yes { vars: "var" string => "/one/two/last1", comment => "This is a comment"; reports: "Test = $(var)"; } cfengine-3.24.2/examples/measure_log.cf0000644000000000000000000000146515010704253020013 0ustar00rootroot00000000000000#cop measurements,example ####################################################### # # Test file: log scanner # ####################################################### # # Look for a file in $STATEDIR/line_counter_measure.log # # $STATEDIR = $WORKDIR/state unless overridden at compile time. # bundle monitor watch { measurements: "/home/mark/tmp/file" handle => "line_counter", stream_type => "file", data_type => "counter", match_value => scan_log("MYLINE.*"), history_type => "log", action => sample_rate("0"); } ########################################################## body match_value scan_log(x) { select_line_matching => "^$(x)$"; track_growing_file => "true"; } body action sample_rate(x) { ifelapsed => "$(x)"; expireafter => "10"; } cfengine-3.24.2/examples/namespace_declaration.cf0000644000000000000000000000251115010704253022003 0ustar00rootroot00000000000000# By default we are in the default namespace bundle agent __main__ { methods: "Main in my_namespace namespace" usebundle => my_namespace:main; "Main in your_namespace namespace" usebundle => your_namespace:main; "my_bundle in default namespace" usebundle => my_bundle; reports: "Inside $(this.namespace):$(this.bundle)"; } body file control # From here until the next namespace declaration all bundles and bodies are # defined in my_namespace. { namespace => "my_namespace"; } bundle agent main { reports: "Inside $(this.namespace):$(this.bundle)"; } body file control # From here until the next namespace declaration all bundles and bodies are # defined in your_namespace. { namespace => "your_namespace"; } bundle agent main { reports: "Inside $(this.namespace):$(this.bundle)"; } body file control # From here until the next namespace declaration we return to the default namespace. { namespace => "default"; } bundle agent my_bundle { reports: "Inside $(this.namespace):$(this.bundle)"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: Inside my_namespace:main #@ R: Inside your_namespace:main #@ R: Inside default:my_bundle #@ R: Inside default:main #@ ``` #+end_src cfengine-3.24.2/examples/parsestringarray.cf0000644000000000000000000000174415010704253021111 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { vars: ####################################### # Define data inline for convenience ####################################### "table" string => "Eulers Number:2.718 A Feigenbaum constant:4.6692 Tau (2pi):6.28"; ####################################### "dim" int => parsestringarray( "items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000" ); "keys" slist => sort(getindices("items")); reports: "$(keys) - $(items[$(keys)][1])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: A Feigenbaum constant - 4.6692 #@ R: Eulers Number - 2.718 #@ R: Tau (2pi) - 6.28 #@ ``` #+end_src cfengine-3.24.2/examples/exec_args.cf0000644000000000000000000000255315010704253017450 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Test the symmetry between using / not using args => # Locks should prevent these from being run twice, all else being equal. # body common control { bundlesequence => { "main" }; } bundle agent main { vars: "testlist" slist => { "apple", "banana", "carrot" }; commands: "/bin/echo test1 $(testlist)"; "/bin/echo test1" args => "$(testlist)"; } cfengine-3.24.2/examples/lastnode.cf0000644000000000000000000000377115010704253017324 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "yes" }; } bundle agent yes { vars: "path1" string => "/one/two/last1"; "path2" string => "one:two:last2"; "path4" string => "/one/two/"; "last1" string => lastnode("$(path1)","/"); "last2" string => lastnode("$(path2)",":"); "last3" string => lastnode("$(path2)","/"); "last4" string => lastnode("$(path4)","/"); reports: "Last / node in / path '$(path1)' = '$(last1)'"; "Last : node in : path '$(path2)' = '$(last2)'"; "Last / node in : path '$(path2)' = '$(last3)'"; "Last / node in /-terminated path '$(path4)' = '$(last4)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Last / node in / path '/one/two/last1' = 'last1' #@ R: Last : node in : path 'one:two:last2' = 'last2' #@ R: Last / node in : path 'one:two:last2' = 'one:two:last2' #@ R: Last / node in /-terminated path '/one/two/' = '' #@ ``` #+end_src cfengine-3.24.2/examples/readtcp.cf0000644000000000000000000000272515010704253017133 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "my80" string => readtcp("myserver.com","80","GET /index.html HTTP/1.1$(const.r)$(const.n)Host: myserver.com$(const.r)$(const.n)$(const.r)$(const.n)",20); classes: "server_ok" expression => regcmp("[^\n]*200 OK.*\n.*","$(my80)"); reports: server_ok:: "Server is alive"; !server_ok:: "Server is not responding - got $(my80)"; } #+end_src cfengine-3.24.2/examples/packagesmatching.cf0000644000000000000000000000424215010704253020776 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #[%-%] body common control { bundlesequence => { "missing_packages" }; } #[%-%] ########################################### #[%+%] bundle agent missing_packages { vars: # List of desired packages "desired" slist => { "mypackage1", "mypackage2" }; # Get info on all installed packages "installed" data => packagesmatching(".*",".*",".*",".*"); "installed_indices" slist => getindices(installed); # Build a simple array of the package names so that we can use # getvalues to pull a unified list of package names that are installed. "installed_name[$(installed_indices)]" string => "$(installed[$(installed_indices)][name])"; # Get unified list of installed packages "installed_names" slist => getvalues("installed_name"); # Determine packages that are missing my differencing the list of # desired packages, against the list of installed packages "missing_list" slist => difference(desired,installed_names); reports: # Report on packages that are missing, installed # and what we were looking for "Missing packages = $(missing_list)"; "Installed packages = $(installed_names)"; "Desired packages = $(desired)"; } #[%+%] cfengine-3.24.2/examples/splitstring.cf0000644000000000000000000000336115010704253020070 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "split1" slist => splitstring("one:two:three",":","10"); "split2" slist => splitstring("one:two:three",":","1"); "split3" slist => splitstring("alpha:xyz:beta","xyz","10"); reports: "split1: $(split1)"; # will list "one", "two", and "three" "split2: $(split2)"; # will list "one", "two:three" will be thrown away. "split3: $(split3)"; # will list "alpha:" and ":beta" } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: split1: one #@ R: split1: two #@ R: split1: three #@ R: split2: one #@ R: split3: alpha: #@ R: split3: :beta #@ ``` #+end_src cfengine-3.24.2/examples/filesexist2.cf0000644000000000000000000000272015010704253017745 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "mylist" slist => { "/tmp/a", "/tmp/b", "/tmp/c" }; methods: "any" usebundle => crystal_meth(@(example.mylist)); } bundle agent crystal_meth(x) { classes: "exists" expression => filesexist("@(x)"); reports: exists:: "File does exist"; !exists:: "Does not yet exist"; } cfengine-3.24.2/examples/reglist.cf0000644000000000000000000000337515010704253017164 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "nameservers" slist => { "128.39.89.10", "128.39.74.16", "192.168.1.103", "10.132.51.66" }; classes: "am_name_server" expression => reglist(@(nameservers), "127\.0\.0\.1"); reports: am_name_server:: "127.0.0.1 is currently set as a nameserver"; !am_name_server:: "127.0.0.1 is NOT currently set as a nameserver"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: 127.0.0.1 is NOT currently set as a nameserver #@ ``` #+end_src cfengine-3.24.2/examples/readfile.cf0000644000000000000000000000320415010704253017255 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo alpha > /tmp/cfe_hostlist #@ echo beta >> /tmp/cfe_hostlist #@ echo gamma >> /tmp/cfe_hostlist #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "xxx" string => readfile( "/tmp/cfe_hostlist" , "5" ); reports: "first 5 characters of /tmp/cfe_hostlist: $(xxx)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: first 5 characters of /tmp/cfe_hostlist: alpha #@ ``` #+end_src cfengine-3.24.2/examples/readreallist.cf0000644000000000000000000000210515010704253020154 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ printf "one\ntwo\nthree\n" > /tmp/list.txt #@ printf "1\n2\n3\n" >> /tmp/list.txt #@ printf "1.0\n2.0\n3.0" >> /tmp/list.txt #@ ``` #+end_src #+begin_src cfengine3 bundle agent example_readreallist # @brief Example showing function return types { vars: "my_list_of_reals" rlist => readreallist( "/tmp/list.txt", # File to read "^(\D+)", # Ignore any non-digits "\n", # Split on newlines inf, # Maximum number of entries inf ); # Maximum number of bytes to read reports: "my_list_of_reals includes '$(my_list_of_reals)'"; } bundle agent __main__ { methods: "example_readreallist"; } #+end_src #+begin_src example_output #@ ``` #@ R: my_list_of_reals includes '1' #@ R: my_list_of_reals includes '2' #@ R: my_list_of_reals includes '3' #@ R: my_list_of_reals includes '1.0' #@ R: my_list_of_reals includes '2.0' #@ R: my_list_of_reals includes '3.0' #@ ``` #+end_src cfengine-3.24.2/examples/local_users_locked.cf0000644000000000000000000000021215010704253021332 0ustar00rootroot00000000000000bundle agent main { vars: "users" slist => { "jack", "jill" }; users: linux:: "$(users)" policy => "locked"; } cfengine-3.24.2/examples/hub.cf0000644000000000000000000000432515010704253016265 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Remote value from hub # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-d2] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { vars: "remote_value" string => hubknowledge("monitoring"); reports: "Global knowledge: $(remote_value)"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; allowusers => { "mark" }; } ######################################################### bundle server access_rules() { access: "discovered value" handle => "monitoring", resource_type => "literal", admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/int.cf0000644000000000000000000000100615010704253016272 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent main { vars: "data" data => '{"acft_name": "A320neo", "engine_num": "2", "price_in_USD": "123.456789k"}'; "engines" int => int("$(data[engine_num])"); "ballpark_price" int => int("$(data[price_in_USD])"); reports: "A320neo has $(engines) engines and costs about $(ballpark_price) USD."; } #+end_src #+begin_src example_output #@ ``` #@ R: A320neo has 2 engines and costs about 123456 USD. #@ ``` #+end_src cfengine-3.24.2/examples/report_state.cf0000644000000000000000000000270315010704253020220 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "report" }; } ########################################################### bundle agent report { reports: "/etc/passwd except $(const.n)" printfile => pr("/etc/passwd","5"), showstate => { "otherprocs", "rootprocs" }; } ###################################################################### body printfile pr(file,lines) { file_to_print => "$(file)"; number_of_lines => "$(lines)"; } cfengine-3.24.2/examples/string.cf0000644000000000000000000000064515010704253017016 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent main { classes: "classA"; "classB"; vars: "some_string" string => "cba"; "class_expressions" slist => {"classA.classB", string(and("classA", strcmp("$(some_string)", "abc"))) }; reports: "$(class_expressions)"; } #+end_src #+begin_src example_output #@ ``` #@ R: classA.classB #@ R: !any #@ ``` #+end_src cfengine-3.24.2/examples/variablesmatching.cf0000644000000000000000000000355515010704253021176 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { run }; } bundle agent run { vars: "all" slist => variablesmatching(".*"); "v" slist => variablesmatching("default:sys.cf_version.*"); "v_sorted" slist => sort(v, lex); reports: "Variables matching 'default:sys.cf_version.*' = $(v_sorted)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Variables matching 'default:sys.cf_version.*' = default:sys.cf_version #@ R: Variables matching 'default:sys.cf_version.*' = default:sys.cf_version_major #@ R: Variables matching 'default:sys.cf_version.*' = default:sys.cf_version_minor #@ R: Variables matching 'default:sys.cf_version.*' = default:sys.cf_version_patch #@ R: Variables matching 'default:sys.cf_version.*' = default:sys.cf_version_release #@ ``` #+end_src cfengine-3.24.2/examples/multipassvars.cf0000644000000000000000000000227315010704253020424 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } bundle agent example { vars: any:: "tempdir" string => execresult("/bin/mktemp -d", "noshell"); reports: "tempdir: ${tempdir}"; } cfengine-3.24.2/examples/local_user_secondary_group_member.cf0000644000000000000000000000020415010704253024441 0ustar00rootroot00000000000000bundle agent main { users: linux:: "jill" policy => "present", groups_secondary => { "cfengineers" }; } cfengine-3.24.2/examples/accumulated_time.cf0000644000000000000000000000344615010704253021017 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test processes # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { processes: ".*" process_count => anyprocs, process_select => proc_finder; reports: any_procs:: "Found processes in range"; } ######################################################## body process_select proc_finder { ttime_range => irange(accumulated(0,0,0,0,2,0),accumulated(0,0,0,0,20,0)); process_result => "ttime"; } ######################################################## body process_count anyprocs { match_range => "0,0"; out_of_range_define => { "any_procs" }; } cfengine-3.24.2/examples/regex_win.cf0000644000000000000000000000111415010704253017467 0ustar00rootroot00000000000000###################################################################### # Using path regular expressions on Windows (always forward slash) ###################################################################### body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "c:/test/.*.xml" edit_line => add_information(); } ######################################################## bundle edit_line add_information() { insert_lines: "a line" comment => "adding line"; } cfengine-3.24.2/examples/augment.cf0000644000000000000000000000257115010704253017150 0ustar00rootroot00000000000000bundle common def { vars: # Only define this variable if it is not yet defined. "example_augment_string_override" unless => isvariable("example_augment_string_override"); # Define this variable regardless if it has been set in def.json "example_augment_list_override" slist => { "defined", "in", "bundle", "common", "def" }; } bundle agent main { vars: "def_vars" slist => variablesmatching("default\:def\..*"); reports: "Def var: '$(def_vars)'"; "def.example_augment_string_override = '$(def.example_augment_string_override)'"; "def.example_augment_list_override = '$(def.example_augment_list_override)'"; "def.example_augment_structured_override[key1] = '$(def.example_augment_structured_override[key1])'"; } #+begin_src example_output #@ ``` #@ R: Def var: 'default:def.example_augment_structured_override' #@ R: Def var: 'default:def.example_augment_string_override' #@ R: Def var: 'default:def.example_augment_list_override' #@ R: def.example_augment_string_override = 'defined in def.json' #@ R: def.example_augment_list_override = 'defined' #@ R: def.example_augment_list_override = 'in' #@ R: def.example_augment_list_override = 'bundle' #@ R: def.example_augment_list_override = 'common' #@ R: def.example_augment_list_override = 'def' #@ R: def.example_augment_structured_override[key1] = 'defined in def.json' #@ ``` #+end_src cfengine-3.24.2/examples/local_user_password.cf0000644000000000000000000000077215010704253021563 0ustar00rootroot00000000000000body file control { # This policy uses parts of the standard library. inputs => { "$(sys.libdir)/users.cf" }; } bundle agent main { vars: # This is the hashed password for 'vagrant' debian_8:: "root_hash" string => "$6$1nRTeNoE$DpBSe.eDsuZaME0EydXBEf.DAwuzpSoIJhkhiIAPgRqVKlmI55EONfvjZorkxNQvK2VFfMm9txx93r2bma/4h/"; users: linux:: "root" policy => "present", password => hashed_password( $(root_hash) ), if => isvariable("root_hash"); } cfengine-3.24.2/examples/service_catalogue.cf0000644000000000000000000000250615010704253021172 0ustar00rootroot00000000000000body common control { bundlesequence => { "service_catalogue" }; } bundle agent service_catalogue { services: "syslog" service_policy => "start"; "www" service_policy => "stop"; } bundle agent standard_services(service, state) { vars: debian:: "startcommand[www]" string => "/etc/init.d/apache2 start"; "stopcommand[www]" string => "/etc/init.d/apache2 stop"; "processname[www]" string => "apache2"; "startcommand[syslog]" string => "/etc/init.d/rsyslog start"; "stopcommand[syslog]" string => "/etc/init.d/rsyslog stop"; "processname[syslog]" string => "rsyslogd"; classes: "start" expression => strcmp("start","$(state)"); "stop" expression => strcmp("stop","$(state)"); processes: start:: ".*$(processname[$(service)]).*" comment => "Verify that the service appears in the process table", restart_class => "restart_$(service)"; stop:: ".*$(processname[$(service)]).*" comment => "Verify that the service does not appear in the process table", process_stop => "$(stopcommand[$(service)])", signals => { "term", "kill"}; commands: "$(startcommand[$(service)])" comment => "Execute command to restart the $(service) service", if => "restart_$(service)"; } cfengine-3.24.2/examples/hash_to_int.cf0000644000000000000000000000332315010704253020003 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "hello" int => hash_to_int(0, 1000, "hello"); "world" int => hash_to_int(0, 1000, "world"); # Hash can vary on hostkey or policy hub: "hour" int => hash_to_int(0, 24, "$(sys.key_digest)"); "minute" int => hash_to_int(0, 60, "$(sys.policy_hub)"); reports: "'hello' hashed to: $(hello)"; "'world' hashed to: $(world)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: 'hello' hashed to: 172 #@ R: 'world' hashed to: 760 #@ ``` #+end_src cfengine-3.24.2/examples/sum.cf0000644000000000000000000000276515010704253016321 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "adds_to_six" ilist => { "1", "2", "3" }; "six" real => sum("adds_to_six"); "adds_to_zero" rlist => { "1.0", "2", "-3e0" }; "zero" real => sum("adds_to_zero"); reports: "six is $(six), zero is $(zero)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: six is 6.000000, zero is 0.000000 #@ ``` #+end_src cfengine-3.24.2/examples/bsdflags.cf0000644000000000000000000000236415010704253017275 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } bundle agent example { files: freebsd:: "/tmp/newfile" create => "true", perms => setbsd; } body perms setbsd { bsdflags => { "+uappnd","+uchg", "+uunlnk", "-nodump" }; } cfengine-3.24.2/examples/acl_secret.cf0000644000000000000000000000274415010704253017616 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "acls" }; } ######################################### bundle agent acls { files: windows:: "c:\Secret" acl => win, depth_search => include_base, comment => "Secure the secret directory from unauthorized access"; } ######################################### body acl win { acl_method => "overwrite"; aces => { "user:Administrator:rwx" }; } ######################################### body depth_search include_base { include_basedir => "true"; } cfengine-3.24.2/examples/loops.cf0000644000000000000000000000270615010704253016644 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "component" slist => { "cf-monitord", "cf-serverd", "cf-execd" }; "array[cf-monitord]" string => "The monitor"; "array[cf-serverd]" string => "The server"; "array[cf-execd]" string => "The executor, not executioner"; reports: "/bin/echo $(component) is $(array[$(component)])"; } cfengine-3.24.2/examples/filestat.cf0000644000000000000000000000550415010704253017322 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo 1234567890 > FILE.txt #@ chmod 0755 FILE.txt #@ chown 0 FILE.txt #@ chgrp 0 FILE.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "file" string => "$(this.promise_filename).txt"; methods: "fileinfo" usebundle => fileinfo("$(file)"); } bundle agent fileinfo(f) { vars: # use the full list if you want to see all the attributes! # "fields" slist => splitstring("size,gid,uid,ino,nlink,ctime,atime,mtime,mode,modeoct,permstr,permoct,type,devno,dev_minor,dev_major,basename,dirname,linktarget,linktarget_shallow", ",", 999); # ino (inode number), ctime (creation time), # devno/dev_minor/dev_major (device numbers) were omitted but # they are all integers "fields" slist => splitstring("size,gid,uid,nlink,mode,modeoct,permstr,permoct,type,basename", ",", 999); "stat[$(f)][$(fields)]" string => filestat($(f), $(fields)); reports: "$(this.bundle): file $(stat[$(f)][basename]) has $(fields) = $(stat[$(f)][$(fields)])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: fileinfo: file filestat.cf.txt has size = 11 #@ R: fileinfo: file filestat.cf.txt has gid = 0 #@ R: fileinfo: file filestat.cf.txt has uid = 0 #@ R: fileinfo: file filestat.cf.txt has nlink = 1 #@ R: fileinfo: file filestat.cf.txt has mode = 33261 #@ R: fileinfo: file filestat.cf.txt has modeoct = 100755 #@ R: fileinfo: file filestat.cf.txt has permstr = -rwxr-xr-x #@ R: fileinfo: file filestat.cf.txt has permoct = 755 #@ R: fileinfo: file filestat.cf.txt has type = regular file #@ R: fileinfo: file filestat.cf.txt has basename = filestat.cf.txt #@ ``` #+end_src cfengine-3.24.2/examples/readenvfile.cf0000644000000000000000000000556115010704253017776 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo 'PRETTY_NAME="Ubuntu 14.04.5 LTS"' > /tmp/os-release #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 # Definitions (from standard library): body edit_defaults empty { empty_file_before_editing => "true"; edit_backup => "false"; } bundle edit_line insert_lines(lines) { insert_lines: "$(lines)"; } body printfile cat(file) { file_to_print => "$(file)"; number_of_lines => "inf"; } # empty, insert_lines() and cat() are part of the standard library # To import the standard library, remove them and uncomment this line: # body file control { inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent main { classes: "file_found" expression => fileexists("/tmp/os-release"); # Use readenvfile() to load /tmp/os-release, then convert to json: vars: file_found:: "envdata" data => readenvfile("/tmp/os-release"); "jsonstring" string => storejson(envdata); # Print input(os-release) and output(json) files: reports: file_found:: "/tmp/os-release :" printfile => cat("/tmp/os-release"); "/tmp/os-release converted to json:"; "$(jsonstring)"; "(The data for this system is available in sys.os_release)"; !file_found:: "/tmp/os-release doesn't exist, run this command:"; "echo 'PRETTY_NAME=\"Ubuntu 14.04.5 LTS\"' > /tmp/os-release"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /tmp/os-release : #@ R: PRETTY_NAME="Ubuntu 14.04.5 LTS" #@ R: /tmp/os-release converted to json: #@ R: { #@ "PRETTY_NAME": "Ubuntu 14.04.5 LTS" #@ } #@ R: (The data for this system is available in sys.os_release) #@ ``` #+end_src cfengine-3.24.2/examples/package_freebsd.cf0000644000000000000000000000434215010704253020573 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Package management # body common control { bundlesequence => { "packages" }; } ############################################# body agent control { environment => { "PACKAGESITE=ftp://freebsd-src.es.net/pub/FreeBSD/ports/i386/packages-7.2-release/All/" }; } ############################################# bundle agent packages { vars: # Test the simplest case -- leave everything to the yum smart manager "match_package" slist => { "wget-1.11.4" }; packages: "$(match_package)" package_policy => "add", package_method => freebsd; } ############################################# body package_method freebsd { any:: package_changes => "individual"; # Could use rpm for this package_list_command => "/usr/sbin/pkg_info"; # Remember to escape special characters like | package_list_name_regex => "([^-]+).*"; package_list_version_regex => "[^-]+-([^\s]+).*"; package_name_regex => "([^-]+).*"; package_version_regex => "[^-]+-([^\s]+).*"; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version)"; package_add_command => "/usr/sbin/pkg_add -r"; package_delete_command => "/usr/sbin/pkg_delete"; } cfengine-3.24.2/examples/remoteclasses2.cf0000644000000000000000000000224615010704253020442 0ustar00rootroot00000000000000# body common control { bundlesequence => { "overture" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ####################################################### bundle agent overture { classes: "extended_context" expression => remoteclassesmatching(".*did.*","127.0.0.1","yes","got"); files: "/etc/passwd" create => "true", classes => set_outcome_classes; reports: got_did_task_one:: "task 1 complete"; extended_context.got_did_task_two:: "task 2 complete"; extended_context.got_did_task_three:: "task 3 complete"; } body classes set_outcome_classes { promise_kept => { "did_task_one","did_task_two", "did_task_three" }; promise_repaired => { "did_task_one","did_task_two", "did_task_three" }; #cancel_kept => { "did_task_one" }; persist_time => "10"; } body server control { allowconnects => { "127.0.0.1" , "::1",}; allowallconnects => { "127.0.0.1" , "::1", }; trustkeysfrom => { "127.0.0.1" , "::1",}; } bundle server access_rules() { access: "did.*" resource_type => "context", admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/process_kill.cf0000644000000000000000000000221315010704253020172 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "kill_process" }; } bundle agent kill_process { processes: "sleep" signals => { "term", "kill" }; } cfengine-3.24.2/examples/root_passwd.cf0000644000000000000000000000651115010704253020052 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # Root password distribution # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "SetRootPassword" }; } ######################################################## bundle common g { vars: "secret_keys_dir" string => "/tmp"; } ######################################################## bundle agent SetRootPassword { files: "/var/cfengine/ppkeys/rootpw.txt" copy_from => scp("$(fqhost)-root.txt","master_host.example.org"); # or $(pw_class)-root.txt # Test this on a copy "/tmp/shadow" edit_line => SetPasswd("root"); } ######################################################## bundle edit_line SetPasswd(user) { vars: # Assume this file contains a single string of the form :passwdhash: # with : delimiters to avoid end of line/file problems "gotpw" int => readstringarray("pw","$(sys.workdir)/ppkeys/root-pw.txt","#[^\n]*",":","3","200"); field_edits: "$(user).*" # Set field of the file to parameter # File has format root:HASH: or user:HASH: edit_field => col(":","2","$(pw[root][1])","set"); } ######################################################## bundle server passwords { vars: # Read a file of format # # classname: host1,host2,host4,IP-address,regex.*,etc # "pw_classes" int => readstringarray("acl","$(g.secret_keys_dir)/classes.txt","#[^\n]*",":","100","4000"); "each_pw_class" slist => getindices("acl"); access: "/secret/keys/$(each_pw_class)-root.txt" admit => splitstring("$(acl[$(each_pw_class)][1])" , ":" , "100"), ifencrypted => "true"; } ######################################## # Bodies ######################################## body edit_field col(split,col,newval,method) { field_separator => "$(split)"; select_field => "$(col)"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } ######################################## body copy_from scp(from,server) { source => "$(from)"; compare => "digest"; encrypt => "true"; verify => "true"; } cfengine-3.24.2/examples/validdata.cf0000644000000000000000000000071515010704253017437 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent main { vars: "json_string" string => '{"test": [1, 2, 3]}'; reports: "This JSON string is valid!" if => validdata("$(json_string)", "JSON"); "This JSON string is not valid." unless => validdata("$(json_string)", "JSON"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This JSON string is valid! #@ ``` #+end_src cfengine-3.24.2/examples/bundlesequence.cf0000644000000000000000000000063515010704253020511 0ustar00rootroot00000000000000# Example showing how to override the default bundlesequence body common control { bundlesequence => { "hello" }; } bundle agent hello # @brief say hello and report my bundle name { reports: "Hello, $(this.bundle) bundle."; } #@ The policy promises to report the name of the current bundle, and produces this output: #+begin_src example_output #@ ``` #@ R: Hello, hello bundle. #@ ``` #+end_src cfengine-3.24.2/examples/orchestrate_delay_trigger.cf0000644000000000000000000000275215010704253022735 0ustar00rootroot00000000000000# # Time based orchestration # body common control { bundlesequence => { "example" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } ########################################### bundle common orchestrate { vars: # Must have delay < reset_time "reset_time" int => "2"; "delay" int => "1"; } ########################################### bundle agent example { methods: "immediate" usebundle => one, classes => if_repaired_persist("countdown", "$(orchestrate.delay)"), if => "!one"; "delayed" usebundle => two, if => "one.!countdown"; reports: countdown:: "Counting down ... $(sys.date)"; } ########################################### bundle agent one { reports: "One = $(this.bundle) at $(sys.date)" classes => if_repaired_persist("$(this.bundle)", "$(orchestrate.reset_time)"), action => if_elapsed("0"); "Set class $(this.bundle)" if => "$(this.bundle)"; } ########################################## bundle agent two { reports: "Two = $(this.bundle) at $(sys.date)" classes => if_repaired_persist("$(this.bundle)", "$(orchestrate.reset_time)"), action => if_elapsed("0"); "Set class $(this.bundle)" if => "$(this.bundle)"; } ########################################### body classes if_repaired_persist(x,t) { promise_repaired => { "$(x)" }; persist_time => "$(t)"; } body classes cancel_persist(x) { cancel_repaired => { "$(x)" }; } cfengine-3.24.2/examples/inherit.cf0000644000000000000000000000377715010704253017163 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # Inheritance of classes # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "parent" }; } ######################################################## bundle agent parent { classes: "parent_private" expression => "any"; methods: "any" usebundle => child, inherit => "true"; files: "/tmp/bla" create => "true", edit_line => edit_child, edit_defaults => inherit_all; } ######################################################## bundle agent child { reports: parent_private:: "Parent class is inherited"; !parent_private:: "Parent class is not inherited"; } # bundle edit_line edit_child { reports: parent_private:: "Parent editclass is inherited"; !parent_private:: "Parent editclass is not inherited"; } # body edit_defaults inherit_all { inherit => "true"; } cfengine-3.24.2/examples/orchestrate_chain2.cf0000644000000000000000000000464215010704253021260 0ustar00rootroot00000000000000############################################################ # # The self-healing tower: Anti-Dominoes # # This method works with either Community of Enterprise # # If you want to test this on localhost, just edit /etc/hosts # to add host1 host2 host3 host4 as aliases to localhost # ############################################################ body common control { bundlesequence => { "weak_dependency_symphony" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } body server control { allowconnects => { "127.0.0.1" , "::1", @(def.acl) }; allowallconnects => { "127.0.0.1" , "::1", @(def.acl) }; } ############################################################ bundle agent weak_dependency_symphony { methods: # We have to seed the beginning by creating the tower # /tmp/tower_localhost host1:: "tower" usebundle => tier1, classes => publish_ok("ok_O"); host2:: "tower" usebundle => tier2, classes => publish_ok("ok_1"); host3:: "tower" usebundle => tier3, classes => publish_ok("ok_2"); host4:: "tower" usebundle => tier4, classes => publish_ok("ok_f"); classes: ok_O:: # Wait for the methods, report on host1 only "check1" expression => remoteclassesmatching("ok.*","host2","yes","a"); "check2" expression => remoteclassesmatching("ok.*","host3","yes","a"); "check3" expression => remoteclassesmatching("ok.*","host4","yes","a"); reports: ok_O&a_ok_1&a_ok_2&a_ok_f:: "The Tower is standing"; !(ok_O&a_ok_1&a_ok_2&a_ok_f):: "The Tower is down"; } ############################################################ bundle agent tier1 { files: "/tmp/something_to_do_1" create => "true"; } bundle agent tier2 { files: "/tmp/something_to_do_2" create => "true"; } bundle agent tier3 { files: "/tmp/something_to_do_3" create => "true"; } bundle agent tier4 { files: "/tmp/something_to_do_4" create => "true"; } ############################################################ bundle server access_rules() { access: "ok.*" resource_type => "context", admit => { "127.0.0.1" }; } ############################################################ body classes publish_ok(x) { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; cancel_notkept => { "$(x)" }; persist_time => "5"; } cfengine-3.24.2/examples/sys_interfaces_ip_addresses_ipv4.cf0000644000000000000000000000407715010704253024223 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent example_sys_interfaces # @brief Illustrate iterating over interfaces and addresses { reports: "Address: $(sys.ip_addresses)"; "Interface: $(sys.interfaces)"; "Address of '$(sys.interfaces)' is '$(sys.ipv4[$(sys.interfaces)])'"; } bundle agent __main__ { methods: "example_sys_interfaces"; } #+end_src ############################################################################### #+begin_src static_example_output #@ ``` #@ R: Address: 127.0.0.1 #@ R: Address: 192.168.42.189 #@ R: Address: 192.168.122.1 #@ R: Address: 172.17.0.1 #@ R: Address: 192.168.33.1 #@ R: Address: 172.27.224.211 #@ R: Address: 192.168.69.1 #@ R: Interface: wlan0 #@ R: Interface: virbr0 #@ R: Interface: docker0 #@ R: Interface: vboxnet3 #@ R: Interface: tun0 #@ R: Interface: vboxnet13 #@ R: Address of 'wlan0' is '192.168.42.189' #@ R: Address of 'virbr0' is '192.168.122.1' #@ R: Address of 'docker0' is '172.17.0.1' #@ R: Address of 'vboxnet3' is '192.168.33.1' #@ R: Address of 'tun0' is '172.27.224.211' #@ R: Address of 'vboxnet13' is '192.168.69.1' #@ ``` #+end_src cfengine-3.24.2/examples/copy_classes.cf0000644000000000000000000000507715010704253020203 0ustar00rootroot00000000000000body common control { bundlesequence => { "copy_file"}; inputs => { "$(sys.libdir)/stdlib.cf" }; } ###################################################### bundle agent copy_file() { files: "/tmp/non_existent" copy_from => local_cp_compare("/non_existent"), # perms => m("777"), action => warn_only, classes => check_promises("NE_NE"); "/tmp/non_existent" copy_from => local_cp_compare("/tmp/existent_file"), # perms => m("777"), action => warn_only, classes => check_promises("NE_E"); "/tmp/existent_file" copy_from => local_cp_compare("/tmp/existent_file"), # perms => m("777"), action => warn_only, classes => check_promises("E_E"); "/tmp/existent_file" copy_from => local_cp_compare("/tmp/different_file"), # perms => m("777"), action => warn_only, classes => check_promises("D_E"); "/tmp/existent_file" copy_from => local_cp_compare("/non_existent"), # perms => m("777"), action => warn_only, classes => check_promises("E_NE"); reports: NE_NE_kept:: "NE_NE_kept"; NE_NE_repaired:: "NE_NE_repaired"; NE_NE_failed:: "NE_NE_failed"; NE_NE_denied:: "NE_NE_denied"; NE_NE_timeout:: "NE_NE_timeout"; NE_E_kept:: "NE_E_kept"; NE_E_repaired:: "NE_E_repaired"; NE_E_failed:: "NE_E_failed"; NE_E_denied:: "NE_E_denied"; NE_E_timeout:: "NE_E_timeout"; E_E_kept:: "E_E_kept"; E_E_repaired:: "E_E_repaired"; E_E_failed:: "E_E_failed"; E_E_denied:: "E_E_denied"; E_E_timeout:: "E_E_timeout"; D_E_kept:: "D_E_kept"; D_E_repaired:: "D_E_repaired"; D_E_failed:: "D_E_failed"; D_E_denied:: "D_E_denied"; D_E_timeout:: "D_E_timeout"; E_NE_kept:: "E_NE_kept"; E_NE_repaired:: "E_NE_repaired"; E_NE_failed:: "E_NE_failed"; E_NE_denied:: "E_NE_denied"; E_NE_timeout:: "E_NE_timeout"; } ###################################################### body classes check_promises(prom) { promise_kept => { "$(prom)_kept" }; promise_repaired => { "$(prom)_repaired" }; repair_failed => { "$(prom)_failed" }; repair_denied => { "$(prom)_denied" }; repair_timeout => { "$(prom)_timeout" }; } ###################################################### body copy_from local_cp_compare(from) { source => "$(from)"; verify => "true"; compare => "hash"; } cfengine-3.24.2/examples/isplain.cf0000644000000000000000000000276315010704253017152 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "fileisplain" expression => isplain("/etc/passwd"); "dirisnotplain" not => isplain("/"); reports: fileisplain:: "/etc/passwd is plain.."; dirisnotplain:: "/ is not plain.."; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /etc/passwd is plain.. #@ R: / is not plain.. #@ ``` #+end_src cfengine-3.24.2/examples/depends_on2.cf0000644000000000000000000000116215010704253017703 0ustar00rootroot00000000000000 body common control { bundlesequence => { "main" }; } bundle agent main { methods: "any" usebundle => one; "any" usebundle => mars:two; } bundle agent one { reports: "two" depends_on => { "handle_one" }; "one" handle => "handle_one"; } body file control { namespace => "mars"; } bundle agent two { reports: "marstwo" handle => "mars_two", depends_on => { "handle_one" }; # Currently bugged -> CFE-3206 # "marsone" # handle => "handle_one"; "marsthree" depends_on => { "default.handle_one", "mars_two" }; } cfengine-3.24.2/examples/islink.cf0000644000000000000000000000300515010704253016772 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ ln -fs /tmp/cfe_testhere.txt /tmp/link #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "islink" expression => islink("/tmp/link"); reports: islink:: "It's a link."; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: It's a link. #@ ``` #+end_src cfengine-3.24.2/examples/resolveconf.cf0000644000000000000000000000545615010704253020042 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # Resolve conf # ####################################################### bundle common g # globals { vars: "searchlist" slist => { "search iu.hio.no", "search cfengine.com" }; "nameservers" slist => { "128.39.89.10", "128.39.74.16", "192.168.1.103" }; classes: "am_name_server" expression => reglist("@(nameservers)","$(sys.ipv4[eth1])"); } ####################################################### body common control { any:: bundlesequence => { "g", resolver(@(g.searchlist),@(g.nameservers)) }; domain => "iu.hio.no"; } ####################################################### bundle agent resolver(s,n) { files: # When passing parameters down, we have to refer to # a source context "$(sys.resolv)" # test on "/tmp/resolv.conf" # create => "true", edit_line => doresolv("@(this.s)","@(this.n)"), edit_defaults => reconstruct; # or edit_defaults => modify } ####################################################### # For the library ####################################################### bundle edit_line doresolv(s,n) { vars: "line" slist => { @(s), @(n) }; insert_lines: "$(line)"; } ####################################################### body edit_defaults reconstruct { empty_file_before_editing => "true"; edit_backup => "false"; max_file_size => "100000"; } ####################################################### body edit_defaults modify { empty_file_before_editing => "false"; edit_backup => "false"; max_file_size => "100000"; } cfengine-3.24.2/examples/files_depth_search_include_basedir.cf0000644000000000000000000001310515010704253024512 0ustar00rootroot00000000000000#+begin_src prep #@ ``` #@ rm -rf /tmp/CFE-3217 #@ mkdir -p /tmp/CFE-3217/test-delete-nobasedir/one/two/three #@ mkdir -p /tmp/CFE-3217/test-delete/one/two/three #@ mkdir -p /tmp/CFE-3217/test-perms/one/two/three #@ mkdir -p /tmp/CFE-3217/test-perms-nobasedir/one/two/three #@ touch /tmp/CFE-3217/test-delete-nobasedir/one/two/three/file #@ touch /tmp/CFE-3217/test-delete/one/two/three/file #@ touch /tmp/CFE-3217/test-perms/one/two/three/file #@ touch /tmp/CFE-3217/test-perms-nobasedir/one/two/three/file #@ touch /tmp/CFE-3217/test-delete-nobasedir/file #@ touch /tmp/CFE-3217/test-delete/file #@ touch /tmp/CFE-3217/test-perms/file #@ touch /tmp/CFE-3217/test-perms-nobasedir/file #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main # @brief Example showing how to promise permissions recursively and promise a directory tree is empty. It illustrates the behavior of `include_basedir` in `depth_search` bodies and that the delete ignores `include_basedir`. { files: "/tmp/CFE-3217/test-delete/." -> { "CFE-3217", "CFE-3218" } depth_search => aggressive("true"), file_select => all, delete => tidy, comment => "include_basedir => 'true' will not result in thd promised directory being removed."; "/tmp/CFE-3217/test-delete-nobasedir/." depth_search => aggressive("false"), file_select => all, delete => tidy, comment => "include_basedir => 'false' will not result in thd promised directory being removed."; "/tmp/CFE-3217/test-perms/." perms => m(555), depth_search => aggressive("true"), file_select => all, comment => "include_basedir => 'true' results in thd promised directory having permissions managed as well."; "/tmp/CFE-3217/test-perms-nobasedir/." -> { "CFE-3217" } perms => m(555), depth_search => aggressive("false"), file_select => all, comment => "include_basedir => 'false' results in thd promised directory not having permissions managed."; reports: "delete => tidy"; "/tmp/CFE-3217/test-delete present despite include_basedir => 'true'" if => isdir("/tmp/CFE-3217/test-delete"); "/tmp/CFE-3217/test-delete-nobasedir present as expected with include_basedir => 'false'" if => isdir("/tmp/CFE-3217/test-delete-nobasedir"); "/tmp/CFE-3217/test-delete absent, unexpectedly" unless => isdir("/tmp/CFE-3217/test-delete"); "/tmp/CFE-3217/test-delete-nobasedir absent, unexpectedly" unless => isdir("/tmp/CFE-3217/test-delete-nobasedir"); "perms => m(555)"; "/tmp/CFE-3217/test-perms $(with), as expected with include_basedir => 'true'" with => filestat( "/tmp/CFE-3217/test-perms", modeoct ), if => strcmp( filestat( "/tmp/CFE-3217/test-perms", modeoct ), "40555" ); "/tmp/CFE-3217/test-perms-nobasedir $(with), not 555, as expected with include_basedir => 'false'" with => filestat( "/tmp/CFE-3217/test-perms-nobasedir", modeoct ), unless => strcmp( filestat( "/tmp/CFE-3217/test-perms-nobasedir", modeoct ), "40555" ); } body depth_search aggressive(include_basedir) # @brief Search for files recursively from promiser traversing synmlinks and filesystem boundaries. { depth => "inf"; # exclude_dirs => { @(exclude_dirs) }; include_basedir => "$(include_basedir)"; # include_dirs => { @(include_dirs) }; # inherit_from => "$(inherit_from)"; # meta => "$(meta)"; meta attribute inside the depth_search body? It's not documented. TODO!? rmdeadlinks => "false"; # Depth search removes dead links, this seems like something that should be in delete body. TODO!? traverse_links => "true"; xdev => "true"; } #@ Inlined bodies from the stdlib in the Masterfiles Policy Framework body file_select all # @brief Select all file system entries { leaf_name => { ".*" }; file_result => "leaf_name"; } body delete tidy # @brief Delete the file and remove empty directories # and links to directories { dirlinks => "delete"; rmdirs => "true"; } body perms m(mode) # @brief Set the file mode # @param mode The new mode { mode => "$(mode)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ info: Deleted file '/tmp/CFE-3217/test-delete/./one/two/three/file' #@ info: Deleted directory '/tmp/CFE-3217/test-delete/./one/two/three' #@ info: Deleted directory '/tmp/CFE-3217/test-delete/./one/two' #@ info: Deleted directory '/tmp/CFE-3217/test-delete/./one' #@ info: Deleted file '/tmp/CFE-3217/test-delete/./file' #@ info: Deleted file '/tmp/CFE-3217/test-delete-nobasedir/./one/two/three/file' #@ info: Deleted directory '/tmp/CFE-3217/test-delete-nobasedir/./one/two/three' #@ info: Deleted directory '/tmp/CFE-3217/test-delete-nobasedir/./one/two' #@ info: Deleted directory '/tmp/CFE-3217/test-delete-nobasedir/./one' #@ info: Deleted file '/tmp/CFE-3217/test-delete-nobasedir/./file' #@ info: Object '/tmp/CFE-3217/test-perms-nobasedir/./file' had permission 0664, changed it to 0555 #@ R: delete => tidy #@ R: /tmp/CFE-3217/test-delete present despite include_basedir => 'true' #@ R: /tmp/CFE-3217/test-delete-nobasedir present as expected with include_basedir => 'false' #@ R: perms => m(555) #@ R: /tmp/CFE-3217/test-perms 40555, as expected with include_basedir => 'true' #@ R: /tmp/CFE-3217/test-perms-nobasedir 40775, not 555, as expected with include_basedir => 'false' #@ ``` #+end_example cfengine-3.24.2/examples/islessthan.cf0000644000000000000000000000260615010704253017664 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { classes: "ok" expression => islessthan("0","1"); reports: ok:: "Assertion is true"; !ok:: "Assertion is false"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Assertion is true #@ ``` #+end_src cfengine-3.24.2/examples/countlinesmatching.cf0000644000000000000000000000264115010704253021404 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: # typically there is only one root user "no" int => countlinesmatching("root:.*","/etc/passwd"); reports: "Found $(no) lines matching"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Found 1 lines matching #@ ``` #+end_src cfengine-3.24.2/examples/maplist.cf0000644000000000000000000000344115010704253017156 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle common g { vars: "otherlist" slist => { "x", "y", "z" }; } ####################################################### bundle agent example { vars: "oldlist" slist => { "a", "b", "c" }; "newlist1" slist => maplist("Element ($(this))","@(g.otherlist)"); "newlist2" slist => maplist("Element ($(this))",@(oldlist)); reports: "Transform: $(newlist1)"; "Transform: $(newlist2)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Transform: Element (x) #@ R: Transform: Element (y) #@ R: Transform: Element (z) #@ R: Transform: Element (a) #@ R: Transform: Element (b) #@ R: Transform: Element (c) #@ ``` #+end_src cfengine-3.24.2/examples/string_reverse.cf0000644000000000000000000000257515010704253020555 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "reversed" string => string_reverse("abc"); # will contain "cba" reports: "reversed abs = $(reversed)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: reversed abs = cba #@ ``` #+end_src cfengine-3.24.2/examples/template_method-inline_mustache.cf0000644000000000000000000000454015010704253024026 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of Cfengine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ############################################################################### #+begin_src cfengine3 bundle agent example_using_template_method_inline_mustache { vars: # Here we construct a data container that will be passed to the mustache # templating engine "d" data => '{ "host": "docs.cfengine.com" }'; # Here we specify a string that will be used as an inline mustache template "mustache_template_string" string => "Welcome to host '{{{host}}}'"; files: # Here we render the file using the data container and inline template specification "/tmp/example.txt" create => "true", template_method => "inline_mustache", edit_template_string => "$(mustache_template_string)", template_data => @(d); reports: "/tmp/example.txt" printfile => cat( $(this.promiser) ); } # Copied from stdlib, lib/reports.cf body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle agent __main__ { methods: "example_using_template_method_inline_mustache"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /tmp/example.txt #@ R: Welcome to host 'docs.cfengine.com' #@ ``` #+end_src cfengine-3.24.2/examples/copy.cf0000644000000000000000000000247515010704253016465 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "copy" }; } bundle agent copy { files: "/tmp/testfile1-cop" copy_from => mycopy("/tmp/testfile1", "gudea"); "/tmp/testfile2-cop" copy_from => mycopy("/tmp/testfile2", "gudea"); } body copy_from mycopy(from,server) { source => "$(from)"; #servers => { "$(server)" }; } cfengine-3.24.2/examples/mustache_set_delimiters.cf0000644000000000000000000000060515010704253022411 0ustar00rootroot00000000000000# Example showing how delimeters can be customized #+begin_src cfengine3 bundle agent main { vars: "data" data => '{ "key": "value of key in data" }'; reports: "$(with)" with => string_mustache("{{=<% %>=}}key has <% key %>", data); } #+end_src #+begin_src example_output #@ ``` #@ R: key has value of key in data #@ ``` #+end_src cfengine-3.24.2/examples/inventory_cpu.cf0000644000000000000000000000132215010704253020405 0ustar00rootroot00000000000000# Demo on how to extract the first "model name" field from /proc/cpuinfo # into a variable. # Can be used for inventory information in CFEngine Nova and above. body common control { bundlesequence => { "inventory" }; } ### bundle common inventory { vars: "cpuinfo" string => execresult("/bin/grep \"model name\" /proc/cpuinfo", "noshell"); got_model_name:: "cpu" string => "$(myarray[1])"; classes: "got_model_name" expression => regextract( "model\s+name\s+:\s+([^\n]*)\n?.*", "$(cpuinfo)", "myarray" ); reports: got_model_name:: "model name is \"$(myarray[1])\""; !got_model_name:: "Did not match CPU model name"; } cfengine-3.24.2/examples/quoting.cf0000644000000000000000000000153715010704253017177 0ustar00rootroot00000000000000bundle agent main # @brief Example showing various ways of quoting in CFEngine. { vars: 'single' string => 'single quotes'; `backtick` string => `backtick quotes`; "double" string => "double"; 'single_escape' string => 'You can \'escape\' single quotes'; "double_escape" string => "You can \"escape\" double quotes"; `backtick_escape` string => `Note: You can't escape backtick quotes`; reports: "$(single)"; `$(backtick)`; `$(double)`; '$(single_escape)'; "$(double_escape)"; `$(backtick_escape)`; } ############################################################################### #+begin_src example_output #@ ``` #@ R: single quotes #@ R: backtick quotes #@ R: double #@ R: You can 'escape' single quotes #@ R: You can "escape" double quotes #@ R: Note: You can't escape backtick quotes #@ ``` #+end_src cfengine-3.24.2/examples/remotescalar.cf0000644000000000000000000000475215010704253020174 0ustar00rootroot00000000000000 # Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################################## # # Testing comms for remote orchestration # ######################################################################## body common control { bundlesequence => { "overture" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } body server control { allowconnects => { "127.0.0.1" , "::1",}; allowallconnects => { "127.0.0.1" , "::1", }; trustkeysfrom => { "127.0.0.1" , "::1",}; } ####################################################### bundle agent overture { vars: "remote" string => remotescalar("test_scalar","127.0.0.1","yes"); "know" string => hubknowledge("test_scalar"); "count_getty" string => hubknowledge("count_getty"); processes: # Use the enumerated library body to count hosts running getty "getty" comment => "Count this host if a job is matched", classes => enumerate("count_getty"); reports: "GOT remote scalar $(remote)"; "GOT knowedge scalar $(know)"; "GOT persistent scalar $(xyz)"; } ####################################################### bundle server access_rules() { access: "value of my test_scalar, can expand variables here - $(sys.host)" handle => "test_scalar", comment => "Grant access to contents of test_scalar VAR", resource_type => "literal", admit => { "127.0.0.1" }; "XYZ" resource_type => "variable", handle => "XYZ", admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/mount_fs.cf0000644000000000000000000000273315010704253017342 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # cfengine 3 # # cf-agent -f ./cftest.cf -K # body common control { bundlesequence => { "mounts" }; } # bundle agent mounts { storage: "/mnt" mount => nfs("slogans.iu.hio.no","/home"); } ###################################################################### body mount nfs(server,source) { mount_type => "nfs"; mount_source => "$(source)"; mount_server => "$(server)"; #mount_options => { "rw" }; edit_fstab => "true"; unmount => "true"; } cfengine-3.24.2/examples/classmatch.cf0000644000000000000000000000305215010704253017625 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "do_it" and => { classmatch("cfengine_3.*"), "any" }; "have_hardclass_nonesuch" expression => classmatch("nonesuchclass_sodonttryit", hardclass); reports: do_it:: "Host matches pattern"; have_hardclass_nonesuch:: "Host has that really weird hardclass"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Host matches pattern #@ ``` #+end_src cfengine-3.24.2/examples/promises.cf0000644000000000000000000000404615010704253017350 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ####################################################### # # The starting point for every configuration # ####################################################### body common control { inputs => { "$(sys.libdir)/stdlib.cf" }; bundlesequence => { "main", "cfengine2" }; } ####################################################### bundle agent main { # do something vars: "sys_files" slist => { "/etc/passwd", "/etc/services" }; files: "$(sys_files)" perms => mo("0644", "root"), changes => detect_content; "/etc/shadow" perms => mo("0600", "root"), changes => detect_content; "/usr" changes => detect_content, depth_search => recurse("inf"); "/tmp" delete => tidy, file_select => days_old("2"), depth_search => recurse("inf"); } ####################################################### bundle agent cfengine2 { commands: "/var/cfengine/bin/cfagent"; } cfengine-3.24.2/examples/isnewerthan.cf0000644000000000000000000000317415010704253020037 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ touch -t '200102031234.56' /tmp/earlier #@ touch -t '200202031234.56' /tmp/later #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "do_it" and => { isnewerthan("/tmp/later","/tmp/earlier"), "cfengine" }; reports: do_it:: "/tmp/later is older than /tmp/earlier"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /tmp/later is older than /tmp/earlier #@ ``` #+end_src cfengine-3.24.2/examples/iteration.cf0000644000000000000000000000241315010704253017501 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Nested iteration # body common control { bundlesequence => {"x"}; } bundle agent x { vars: "list1" slist => { "a", "b", "c" }; "list2" slist => { "1", "2", "3", "4" }; "list3" slist => { "x", "y", "z" }; reports: "Hello $(list1) $(list2) $(list3)"; } cfengine-3.24.2/examples/join.cf0000644000000000000000000000411515010704253016443 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "mylist" slist => { "one", "two", "three", "four", "five" }; "datalist" data => parsejson('[1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three",]'); "mylist_str" string => format("%S", mylist); "datalist_str" string => format("%S", datalist); "myscalar" string => join("->", mylist); "datascalar" string => join("->", datalist); reports: "Concatenated $(mylist_str): $(myscalar)"; "Concatenated $(datalist_str): $(datascalar)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Concatenated { "one", "two", "three", "four", "five" }: one->two->three->four->five #@ R: Concatenated [1,2,3,"one","two","three","long string","four","fix","six","one","two","three"]: 1->2->3->one->two->three->long string->four->fix->six->one->two->three #@ ``` #+end_src cfengine-3.24.2/examples/setvar.cf0000644000000000000000000000336615010704253017017 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "setvars" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent setvars { vars: # want to set these values by the names of their array keys "rhs[lhs1]" string => " Mary had a little pig"; "rhs[lhs2]" string => "Whose Fleece was white as snow"; "rhs[lhs3]" string => "And everywhere that Mary went"; "rhs[net/ipv4/tcp_syncookies]" string => "1"; "rhs[net/ipv4/icmp_echo_ignore_broadcasts]" string => "1"; "rhs[net/ipv4/ip_forward]" string => "0"; # oops, now change pig -> lamb files: "/tmp/system" comment => "Create a file of variable assignments and manage this file", create => "true", edit_line => set_variable_values("setvars.rhs"); } cfengine-3.24.2/examples/monitord.cf0000644000000000000000000000247515010704253017346 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################### body monitor control { #version => "1.2.3.4"; forgetrate => "0.7"; histograms => "true"; tcpdump => "false"; tcpdumpcommand => "/usr/sbin/tcpdump -i eth1 -n -t -v"; # on linux linux:: # sensor => readfile("/proc/cpu/temperature"); } cfengine-3.24.2/examples/expand.cf0000644000000000000000000000263015010704253016763 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { vars: "component" slist => { "cf-monitord", "cf-serverd", "cf-execd" }; processes: "$(component)" restart_class => canonify("start_$(component)"); commands: "/bin/echo /var/cfengine/bin/$(component)" if => canonify("start_$(component)"); } cfengine-3.24.2/examples/setuidlog.cf0000644000000000000000000000304015010704253017477 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/tmp" -> "me" changes => tripwire, depth_search => recurse("1"); } ######################################################### body changes tripwire { hash => "md5"; report_changes => "content"; update_hashes => "true"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } cfengine-3.24.2/examples/string_head.cf0000644000000000000000000000255715010704253020003 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "start" string => string_head("abc", "1"); # will contain "a" reports: "start of abc = $(start)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: start of abc = a #@ ``` #+end_src cfengine-3.24.2/examples/fix_names.cf0000644000000000000000000000352315010704253017457 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ###################################################################### # # File editing # # Normal ordering: # - delete # - replace | column_edit # - insert # ###################################################################### body common control { version => "1.2.3"; bundlesequence => { "example" }; } ######################################################## bundle agent example { files: "/home/mark/LapTop/Cfengine3/trunk/src/.*\.[ch]" edit_line => change_name; } ######################################################## bundle edit_line change_name { replace_patterns: "Verbose\(" replace_with => With("CfOut(cf_verbose,\"\","); } ######################################## # Bodies ######################################## body replace_with With(x) { replace_value => "$(x)"; occurrences => "all"; } cfengine-3.24.2/examples/mapdata_jsonpipe.cf0000644000000000000000000000627115010704253021027 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "run" }; } bundle agent run { vars: "tester" data => '{ "x": 100, "y": [ true, "a", "b" ] }'; # "jq ." returns the same thing that was passed in "pipe_passthrough" data => mapdata("json_pipe", '$(def.jq) .', tester); "pipe_passthrough_str" string => format("%S", pipe_passthrough); # "jq .x" returns what was under x wrapped in an array: [100] "pipe_justx" data => mapdata("json_pipe", '$(def.jq) .x', tester); "pipe_justx_str" string => format("%S", pipe_justx); # "jq .y" returns what was under y wrapped in an array: [[true,"a","b"]] "pipe_justy" data => mapdata("json_pipe", '$(def.jq) .y', tester); "pipe_justy_str" string => format("%S", pipe_justy); # "jq .y[]" returns each entry under y *separately*: [true,"a","b"] "pipe_yarray" data => mapdata("json_pipe", '$(def.jq) .y[]', tester); "pipe_yarray_str" string => format("%S", pipe_yarray); # "jq .z" returns null because the key "z" is missing: [null] "pipe_justz" data => mapdata("json_pipe", '$(def.jq) .z', tester); "pipe_justz_str" string => format("%S", pipe_justz); # "jq" can do math too! and much more! "pipe_jqmath" data => mapdata("json_pipe", '$(def.jq) 1+2+3', tester); "pipe_jqmath_str" string => format("%S", pipe_jqmath); reports: "mapdata/json_pipe passthrough result: $(pipe_passthrough_str)"; "mapdata/json_pipe just x result: $(pipe_justx_str)"; "mapdata/json_pipe just y result: $(pipe_justy_str)"; "mapdata/json_pipe array under y result: $(pipe_yarray_str)"; "mapdata/json_pipe just z result: $(pipe_justz_str)"; "mapdata/json_pipe math expression result: $(pipe_jqmath_str)"; } #+end_src ############################################################################### #+begin_src output #@ ``` #@ R: mapdata/json_pipe passthrough result: [{"x":100,"y":[true,"a","b"]}] #@ R: mapdata/json_pipe just x result: [100] #@ R: mapdata/json_pipe just y result: [[true,"a","b"]] #@ R: mapdata/json_pipe array under y result: [true,"a","b"] #@ R: mapdata/json_pipe just z result: [null] #@ R: mapdata/json_pipe math expression result: [6] #@ ``` #+end_src cfengine-3.24.2/examples/namespace_variable_references.cf0000644000000000000000000000107515010704253023510 0ustar00rootroot00000000000000bundle agent __main__ { methods: "example:demo"; } body file control { namespace => "example"; } bundle agent demo { vars: "color" string => "#f5821f"; reports: "Unqualified: The color is $(color)"; # ENT-8817 "Bundle-qualified: The color is $(demo.color)"; "Fully-qualified: The color is $(example:demo.color)"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: Unqualified: The color is #f5821f #@ R: Fully-qualified: The color is #f5821f #@ ``` #+end_src cfengine-3.24.2/examples/process_restart_basic.cf0000644000000000000000000000240515010704253022067 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "process_restart" }; } ######################################################### bundle agent process_restart { processes: "/usr/bin/daemon" restart_class => "launch"; commands: launch:: "/usr/bin/daemon"; } cfengine-3.24.2/examples/strftime.cf0000644000000000000000000003147315010704253017350 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 #@ The templates used here are from the documentation of the standard strftime #@ implementation in the [glibc manual](http://www.gnu.org/software/libc/manual/html_node/Formatting-Calendar-Time.html#Formatting-Calendar-Time). body agent control { environment => { "LC_ALL=en_US.UTF-8", "TZ=GMT" }; } bundle agent main { vars: "time" int => "1234567890"; "template[%a]" string => "The abbreviated weekday name according to the current locale."; "template[%A]" string => "The full weekday name according to the current locale."; "template[%b]" string => "The abbreviated month name according to the current locale."; "template[%B]" string => "The full month name according to the current locale."; "template[%c]" string => "The preferred calendar time representation for the current locale."; "template[%C]" string => "The century of the year. This is equivalent to the greatest integer not greater than the year divided by 100."; "template[%d]" string => "The day of the month as a decimal number (range 01 through 31)."; "template[%D]" string => "The date using the format %m/$d/%y."; "template[%e]" string => "The day of the month like with %d, but padded with blank (range 1 through 31)."; "template[%F]" string => "The date using the format %Y-%m-%d. This is the form specified in the ISO 8601 standard and is the preferred form for all uses."; "template[%g]" string => "The year corresponding to the ISO week number, but without the century (range 00 through 99). This has the same format and value as %y, except that if the ISO week number (see %V) belongs to the previous or next year, that year is used instead."; "template[%G]" string => "The year corresponding to the ISO week number. This has the same format and value as %Y, except that if the ISO week number (see %V) belongs to the previous or next year, that year is used instead."; "template[%h]" string => "The abbreviated month name according to the current locale. The action is the same as for %b."; "template[%H]" string => "The hour as a decimal number, using a 24-hour clock (range 00 through 23)."; "template[%I]" string => "The hour as a decimal number, using a 12-hour clock (range 01 through 12)."; "template[%j]" string => "The day of the year as a decimal number (range 001 through 366)."; "template[%k]" string => "The hour as a decimal number, using a 24-hour clock like %H, but padded with blank (range 0 through 23)."; "template[%l]" string => "The hour as a decimal number, using a 12-hour clock like %I, but padded with blank (range 1 through 12)."; "template[%m]" string => "The month as a decimal number (range 01 through 12)."; "template[%M]" string => "The minute as a decimal number (range 00 through 59)."; "template[%n]" string => "A single \n (newline) character."; "template[%p]" string => "Either AM or PM, according to the given time value; or the corresponding strings for the current locale. Noon is treated as PM and midnight as AM. In most locales AM/PM format is not supported, in such cases %p yields an empty string."; "template[%P]" string => "Either am or pm, according to the given time value; or the corresponding strings for the current locale, printed in lowercase characters. Noon is treated as pm and midnight as am. In most locales AM/PM format is not supported, in such cases %P yields an empty string."; "template[%r]" string => "The complete calendar time using the AM/PM format of the current locale."; "template[%R]" string => "The hour and minute in decimal numbers using the format %H:%M."; "template[%S]" string => "The seconds as a decimal number (range 00 through 60)."; "template[%t]" string => "A single \t (tabulator) character."; "template[%T]" string => "The time of day using decimal numbers using the format %H:%M:%S."; "template[%u]" string => "The day of the week as a decimal number (range 1 through 7), Monday being 1."; "template[%U]" string => "The week number of the current year as a decimal number (range 00 through 53), starting with the first Sunday as the first day of the first week. Days preceding the first Sunday in the year are considered to be in week 00."; "template[%V]" string => "The *ISO 8601:1988* week number as a decimal number (range 01 through 53). ISO weeks start with Monday and end with Sunday. Week 01 of a year is the first week which has the majority of its days in that year; this is equivalent to the week containing the year's first Thursday, and it is also equivalent to the week containing January 4. Week 01 of a year can contain days from the previous year. The week before week 01 of a year is the last week (52 or 53) of the previous year even if it contains days from the new year."; "template[%w]" string => "The day of the week as a decimal number (range 0 through 6), Sunday being 0."; "template[%w]" string => "The day of the week as a decimal number (range 0 through 6), Sunday being 0."; "template[%x]" string => "The preferred date representation for the current locale."; "template[%X]" string => "The preferred time of day representation for the current locale."; "template[%y]" string => "The year without a century as a decimal number (range 00 through 99). This is equivalent to the year modulo 100."; "template[%Y]" string => "The year as a decimal number, using the Gregorian calendar. Years before the year 1 are numbered 0, -1, and so on."; "template[%z]" string => "*RFC 822*/*ISO 8601:1988* style numeric time zone (e.g., -0600 or +0100), or nothing if no time zone is determinable."; "template[%Z]" string => "The time zone abbreviation (empty if the time zone can't be determined)."; "template[%%]" string => "A literal % character."; # Since %s is ever changing resulting in unstable output, causing a test failure in CI # it's not used unless show_seconds_since_epoch is defined "template[%s]" string => "The number of seconds since the epoch, i.e., since 1970-01-01 00:00:00 UTC. Leap seconds are not counted unless leap second support is available.", if => "show_seconds_since_epoch"; "_i" slist => sort(getindices(template), lex); reports: "$(_i) :: $(template[$(_i)])$(const.n)$(const.t)For example: '$(with)'" with => strftime(gmtime, $(_i), $(time)); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: %% :: A literal % character. #@ For example: '%' #@ R: %A :: The full weekday name according to the current locale. #@ For example: 'Friday' #@ R: %B :: The full month name according to the current locale. #@ For example: 'February' #@ R: %C :: The century of the year. This is equivalent to the greatest integer not greater than the year divided by 100. #@ For example: '20' #@ R: %D :: The date using the format %m/$d/%y. #@ For example: '02/13/09' #@ R: %F :: The date using the format %Y-%m-%d. This is the form specified in the ISO 8601 standard and is the preferred form for all uses. #@ For example: '2009-02-13' #@ R: %G :: The year corresponding to the ISO week number. This has the same format and value as %Y, except that if the ISO week number (see %V) belongs to the previous or next year, that year is used instead. #@ For example: '2009' #@ R: %H :: The hour as a decimal number, using a 24-hour clock (range 00 through 23). #@ For example: '23' #@ R: %I :: The hour as a decimal number, using a 12-hour clock (range 01 through 12). #@ For example: '11' #@ R: %M :: The minute as a decimal number (range 00 through 59). #@ For example: '31' #@ R: %P :: Either am or pm, according to the given time value; or the corresponding strings for the current locale, printed in lowercase characters. Noon is treated as pm and midnight as am. In most locales AM/PM format is not supported, in such cases %P yields an empty string. #@ For example: 'pm' #@ R: %R :: The hour and minute in decimal numbers using the format %H:%M. #@ For example: '23:31' #@ R: %S :: The seconds as a decimal number (range 00 through 60). #@ For example: '30' #@ R: %T :: The time of day using decimal numbers using the format %H:%M:%S. #@ For example: '23:31:30' #@ R: %U :: The week number of the current year as a decimal number (range 00 through 53), starting with the first Sunday as the first day of the first week. Days preceding the first Sunday in the year are considered to be in week 00. #@ For example: '06' #@ R: %V :: The *ISO 8601:1988* week number as a decimal number (range 01 through 53). ISO weeks start with Monday and end with Sunday. Week 01 of a year is the first week which has the majority of its days in that year; this is equivalent to the week containing the year's first Thursday, and it is also equivalent to the week containing January 4. Week 01 of a year can contain days from the previous year. The week before week 01 of a year is the last week (52 or 53) of the previous year even if it contains days from the new year. #@ For example: '07' #@ R: %X :: The preferred time of day representation for the current locale. #@ For example: '23:31:30' #@ R: %Y :: The year as a decimal number, using the Gregorian calendar. Years before the year 1 are numbered 0, -1, and so on. #@ For example: '2009' #@ R: %Z :: The time zone abbreviation (empty if the time zone can't be determined). #@ For example: 'GMT' #@ R: %a :: The abbreviated weekday name according to the current locale. #@ For example: 'Fri' #@ R: %b :: The abbreviated month name according to the current locale. #@ For example: 'Feb' #@ R: %c :: The preferred calendar time representation for the current locale. #@ For example: 'Fri Feb 13 23:31:30 2009' #@ R: %d :: The day of the month as a decimal number (range 01 through 31). #@ For example: '13' #@ R: %e :: The day of the month like with %d, but padded with blank (range 1 through 31). #@ For example: '13' #@ R: %g :: The year corresponding to the ISO week number, but without the century (range 00 through 99). This has the same format and value as %y, except that if the ISO week number (see %V) belongs to the previous or next year, that year is used instead. #@ For example: '09' #@ R: %h :: The abbreviated month name according to the current locale. The action is the same as for %b. #@ For example: 'Feb' #@ R: %j :: The day of the year as a decimal number (range 001 through 366). #@ For example: '044' #@ R: %k :: The hour as a decimal number, using a 24-hour clock like %H, but padded with blank (range 0 through 23). #@ For example: '23' #@ R: %l :: The hour as a decimal number, using a 12-hour clock like %I, but padded with blank (range 1 through 12). #@ For example: '11' #@ R: %m :: The month as a decimal number (range 01 through 12). #@ For example: '02' #@ R: %n :: A single \n (newline) character. #@ For example: ' #@ ' #@ R: %p :: Either AM or PM, according to the given time value; or the corresponding strings for the current locale. Noon is treated as PM and midnight as AM. In most locales AM/PM format is not supported, in such cases %p yields an empty string. #@ For example: 'PM' #@ R: %r :: The complete calendar time using the AM/PM format of the current locale. #@ For example: '11:31:30 PM' #@ R: %t :: A single \t (tabulator) character. #@ For example: ' ' #@ R: %u :: The day of the week as a decimal number (range 1 through 7), Monday being 1. #@ For example: '5' #@ R: %w :: The day of the week as a decimal number (range 0 through 6), Sunday being 0. #@ For example: '5' #@ R: %x :: The preferred date representation for the current locale. #@ For example: '02/13/09' #@ R: %y :: The year without a century as a decimal number (range 00 through 99). This is equivalent to the year modulo 100. #@ For example: '09' #@ R: %z :: *RFC 822*/*ISO 8601:1988* style numeric time zone (e.g., -0600 or +0100), or nothing if no time zone is determinable. #@ For example: '+0000' #@ ``` #+end_src cfengine-3.24.2/examples/execresult_as_data.cf0000644000000000000000000000117315010704253021344 0ustar00rootroot00000000000000############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "my_data" data => execresult_as_data("echo 'hello'", "useshell", "both"); "my_json_string" string => storejson(my_data); reports: "echo 'hello' returned '$(my_json_string)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: echo 'hello' returned '{ #@ "exit_code": 0, #@ "output": "hello" #@ }' #@ ``` #+end_src cfengine-3.24.2/examples/class-automatic-canonificiation.cf0000644000000000000000000000346715010704253023741 0ustar00rootroot00000000000000# This example shows how classes are automatically canonified when they are # defined and that you must explicitly canonify when verifying classes. #+begin_src cfengine3 bundle agent main { classes: "my-illegal-class"; reports: # We search to see what class was defined: "$(with)" with => join( " ", classesmatching( "my.illegal.class" ) ); # We see that the illegal class is explicitly not defined. "my-illegal-class is NOT defined (as expected, its invalid)" unless => "my-illegal-class"; # We see the canonified form of the illegal class is defined. "my_illegal_class is defined" if => canonify("my-illegal-class"); # Note, if takes expressisons, you couldn't do that if it were # automatically canonified. Here I canonify the string using with, and use # it as part of the expression which contains an invalid classcharacter, but # its desireable for constructing expressions. "Slice and dice using `with`" with => canonify( "my-illegal-class" ), if => "linux|$(with)"; } #+end_src #+begin_src policy_description #@ First we promise to define `my-illegal-class`. When the promise is actuated #@ it is automatically canonified and defined. This automatic canonification is #@ logged in verbose logs (`verbose: Class identifier 'my-illegal-class' contains illegal characters - canonifying`). #@ Next several reports prove which form of the class was defined. The last #@ report shows how `if` takes a class expression, and if you are checking a class #@ that contains invalid characters you must canonify it. #+end_src #+begin_src example_output #@ ``` #@ R: my_illegal_class #@ R: my-illegal-class is NOT defined (as expected, its invalid) #@ R: my_illegal_class is defined #@ R: Slice and dice using `with` #@ ``` #+end_src cfengine-3.24.2/examples/namespace_var_meta.cf0000644000000000000000000000047515010704253021323 0ustar00rootroot00000000000000 body common control { bundlesequence => { "main" }; version => "0.1"; inputs => { "namespace_var_meta2.cf"}; } bundle agent main { classes: "abc" expression => "any"; methods: "bla" usebundle => fred:example; reports: "remote var: $(fred:example.bundle_version)"; } cfengine-3.24.2/examples/services_win.cf0000644000000000000000000000264415010704253020211 0ustar00rootroot00000000000000######################################################################### # # win_services.cf - Windows Service Management # ######################################################################### body file control { inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent win_services { vars: # NOTE: Use "Service Name" (not "Display Name"); # Administrative Tools -> Services -> Double Click on one to see its name "bad_services" slist => { "RemoteRegistry" }; Windows_Server_2003_R2:: "autostart_services" slist => { "Alerter", "W32Time" # Windows Time }; Windows_Server_2008:: "autostart_services" slist => { "MpsSvc", # Windows Firewall "W32Time" # Windows Time }; services: "$(bad_services)" service_policy => "disable", service_method => force_deps, comment => "Disable services that create security issues"; Windows_Server_2003_R2|Windows_Server_2008:: "$(autostart_services)" service_policy => "start", service_method => bootstart, comment => "Make sure important services are running and set to start at boot time"; } cfengine-3.24.2/examples/orchestration_hostlist.cf0000644000000000000000000000333715010704253022326 0ustar00rootroot00000000000000# # Make list of hosts available to all clients, and use it on clients # in order to configure a sample monitoring application that checks # health of all clients. # # Sample application configuration file contents below, put this in # /var/cfengine/masterfiles/template_monitoring on the hub. # # --- # #monitor_hosts = $(orchestration_hostlist_use.host_string) # # --- # # Note that your copy_from statement in failsafe.cf or update.cf must # copy this file also (e.g. not only copy *.cf files in any file_select) body common control { inputs => { "$(sys.libdir)/stdlib.cf" }; bundlesequence => { "orchestration_hostlist_update", "orchestration_hostlist_use"}; } bundle agent orchestration_hostlist_update { vars: am_policy_hub:: "host_list" slist => hostsseen("inf", "lastseen", "address"); files: am_policy_hub:: "$(sys.workdir)/masterfiles/host_list" comment => "Write the addresses of all hosts to a file", handle => "orchestration_hostlit_update_files_host_list_write", edit_line => insert_lines( "@(orchestration_hostlist_update.host_list)" ), create => "true", edit_defaults => empty; } bundle agent orchestration_hostlist_use { vars: "host_list" slist => readstringlist("$(sys.workdir)/inputs/host_list", "#.*", "\n", 1000, 40000); "host_string" string => join(", ", "host_list"); files: "/tmp/monitoring" comment => "Update application configuration to reflect all hosts on this hub", handle => "orchestration_read_files_host_list_configuration", edit_line => expand_template("$(sys.workdir)/inputs/template_monitoring"), create => "true", edit_defaults => empty; } cfengine-3.24.2/examples/package_msi_file.cf0000644000000000000000000000407115010704253020747 0ustar00rootroot00000000000000# This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # MSI package management using file name # body common control { bundlesequence => { "packages" }; } ############################################# bundle agent packages { vars: "match_package" slist => { "7zip-4.65-x86_64.msi" }; packages: "$(match_package)" package_policy => "add", package_method => msi_fmatch; } ############################################# body package_method msi_fmatch { package_changes => "individual"; package_file_repositories => { "$(sys.workdir)\software_updates\windows", "s:\su" }; package_installed_regex => ".*"; package_name_regex => "^(\S+)-(\d+\.?)+"; package_version_regex => "^\S+-((\d+\.?)+)"; package_arch_regex => "^\S+-(\d+\.?)+(^.+)"; package_name_convention => "$(name)-$(version)-$(arch).msi"; package_add_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; package_update_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; package_delete_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /x"; } cfengine-3.24.2/examples/groupexists.cf0000644000000000000000000000302715010704253020101 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } ########################################################### bundle agent example { classes: "gname" expression => groupexists("sys"); "gid" expression => groupexists("0"); reports: gname:: "Group exists by name"; gid:: "Group exists by id"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Group exists by name #@ R: Group exists by id #@ ``` #+end_src cfengine-3.24.2/examples/isexecutable.cf0000644000000000000000000000257615010704253020172 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: "yes" expression => isexecutable("/bin/ls"); reports: yes:: "/bin/ls is an executable file"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: /bin/ls is an executable file #@ ``` #+end_src cfengine-3.24.2/examples/readdata.cf0000644000000000000000000000445115010704253017254 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo -n 1,2,3 > /tmp/file.csv #@ echo -n '{ "x": 200 }' > /tmp/file.json #@ echo '- a' > /tmp/file.yaml #@ echo '- b' >> /tmp/file.yaml #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main { vars: "csv" data => readdata("/tmp/file.csv", "auto"); # or file type "CSV" "json" data => readdata("/tmp/file.json", "auto"); # or file type "JSON" "csv_str" string => format("%S", csv); "json_str" string => format("%S", json); feature_yaml:: # we can only test YAML data if libyaml is compiled in "yaml" data => readdata("/tmp/file.yaml", "auto"); # or file type "YAML" "yaml_str" string => format("%S", yaml); reports: "From /tmp/file.csv, got data $(csv_str)"; "From /tmp/file.json, got data $(json_str)"; feature_yaml:: "From /tmp/file.yaml, we would get data $(yaml_str)"; !feature_yaml:: # show the output anyway 'From /tmp/file.yaml, we would get data ["a","b"]'; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: From /tmp/file.csv, got data [["1","2","3"]] #@ R: From /tmp/file.json, got data {"x":200} #@ R: From /tmp/file.yaml, we would get data ["a","b"] #@ ``` #+end_src cfengine-3.24.2/examples/container_key_iteration.cf0000644000000000000000000000557515010704253022427 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { run }; } bundle agent run { vars: "animals" data => parsejson(' { "dog": { "legs": 4, "tail": true, "names": [ "Fido", "Cooper", "Sandy" ] }, "cat": { "legs": 4, "tail": true, "names": [ "Fluffy", "Snowball", "Tabby" ] }, "dolphin": { "legs": 0, "tail": true, "names": [ "Flipper", "Duffy" ] }, "hamster": { "legs": 4, "tail": true, "names": [ "Skullcrusher", "Kimmy", "Fluffadoo" ] }, }'); "keys_unsorted" slist => getindices("animals"); "keys" slist => sort(keys_unsorted, "lex"); "animals_$(keys)" data => mergedata("animals[$(keys)]"); methods: # pass the container and a key inside it "any" usebundle => analyze(@(animals), $(keys)); } bundle agent analyze(animals, a) { vars: "names" slist => getvalues("animals[$(a)][names]"); "names_str" string => format("%S", names); reports: "$(this.bundle): possible names for animal '$(a)': $(names_str)"; "$(this.bundle): describe animal '$(a)' => name = $(a), legs = $(animals[$(a)][legs]), tail = $(animals[$(a)][tail])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: analyze: possible names for animal 'cat': { "Fluffy", "Snowball", "Tabby" } #@ R: analyze: describe animal 'cat' => name = cat, legs = 4, tail = true #@ R: analyze: possible names for animal 'dog': { "Fido", "Cooper", "Sandy" } #@ R: analyze: describe animal 'dog' => name = dog, legs = 4, tail = true #@ R: analyze: possible names for animal 'dolphin': { "Flipper", "Duffy" } #@ R: analyze: describe animal 'dolphin' => name = dolphin, legs = 0, tail = true #@ R: analyze: possible names for animal 'hamster': { "Skullcrusher", "Kimmy", "Fluffadoo" } #@ R: analyze: describe animal 'hamster' => name = hamster, legs = 4, tail = true #@ ``` #+end_src cfengine-3.24.2/examples/defaults.cf0000644000000000000000000000477215010704253017324 0ustar00rootroot00000000000000 # Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # # Default values for variables and parameters, introduced 3.4.0 # ########################################################### bundle agent main { defaults: # We can have default values even if variables are not defined at all. # This is equivalent to a variable definition, so not particularly useful. "X" string => "I am a default value"; "Y" slist => { "I am a default list item 1", "I am a default list item 2" }; methods: # More useful, defaults if parameters are passed to a param bundle "example" usebundle => mymethod("","bbb"); reports: "The default value of X is $(X)"; "The default value of Y is $(Y)"; } ########################################################### bundle agent mymethod(a,b) { vars: "no_return" string => "ok"; # readfile("/dont/exist","123"); defaults: "a" string => "AAAAAAAAA", if_match_regex => ""; "b" string => "BBBBBBBBB", if_match_regex => ""; "no_return" string => "no such file"; reports: "The value of a is $(a)"; "The value of b is $(b)"; "The value of no_return is $(no_return)"; } ############################################################################### #+begin_src example_output #@ ``` #@ R: The value of a is AAAAAAAAA #@ R: The value of b is bbb #@ R: The value of no_return is ok #@ R: The default value of X is I am a default value #@ R: The default value of Y is I am a default list item 1 #@ R: The default value of Y is I am a default list item 2 #@ ``` #+end_src cfengine-3.24.2/examples/process_matching.cf0000644000000000000000000000355515010704253021043 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test processes # ######################################################## body common control { bundlesequence => { "example" }; } ######################################################## bundle agent example { processes: ".*" process_select => proc_finder("a.*"), process_count => up("cfservd"); } ######################################################## body process_count up(s) { match_range => "1,10"; # or irange("1","10"); out_of_range_define => { "$(s)_out_of_control" }; } ######################################################## body process_select proc_finder(p) { process_owner => { "avahi", "bin" }; command => "$(p)"; pid => "100,199"; vsize => "0,1000"; process_result => "command.(process_owner|vsize)"; } cfengine-3.24.2/examples/server_copy_purge.cf0000644000000000000000000000612215010704253021246 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ######################################################## # # Simple test copy from server connection to cfServer # ######################################################## # # run this as follows: # # cf-serverd -f runtest_1.cf [-d2] # cf-agent -f runtest_2.cf # # Notice that the same file configures all parts of cfengine ######################################################## body common control { bundlesequence => { "example" }; version => "1.2.3"; } ######################################################## bundle agent example { files: "/home/mark/tmp/test_to" comment => "test copy promise", copy_from => mycopy("/home/mark/tmp/test_from","127.0.0.1"), perms => system, depth_search => recurse("inf"), classes => satisfied("copy_ok"); reports: copy_ok:: "Files were copied.."; } ######################################################### body perms system { mode => "0644"; } ######################################################### body depth_search recurse(d) { depth => "$(d)"; } ######################################################### body copy_from mycopy(from,server) { source => "$(from)"; servers => { "$(server)" }; compare => "digest"; verify => "true"; copy_backup => "true"; #/false/timestamp purge => "true"; type_check => "true"; force_ipv4 => "true"; trustkey => "true"; } ######################################################### body classes satisfied(x) { promise_repaired => { "$(x)" }; persist_time => "0"; } ######################################################### # Server config ######################################################### body server control { allowconnects => { "127.0.0.1" , "::1" }; allowallconnects => { "127.0.0.1" , "::1" }; trustkeysfrom => { "127.0.0.1" , "::1" }; } ######################################################### bundle server access_rules() { access: "/home/mark/tmp" admit => { "127.0.0.1" }; } cfengine-3.24.2/examples/mustache_comments.cf0000644000000000000000000000046415010704253021225 0ustar00rootroot00000000000000# Example showing how comments are not rendered #+begin_src cfengine3 bundle agent main { reports: "$(with)" with => string_mustache("Render this.{{! But not this}}", datastate()); } #+end_src #+begin_src example_output #@ ``` #@ R: Render this. #@ ``` #+end_src cfengine-3.24.2/examples/translatepath.cf0000644000000000000000000000272115010704253020357 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "inputs_dir" string => translatepath("/a/b/c/inputs"); reports: windows:: "The path has backslashes: $(inputs_dir)"; !windows:: "The path has slashes: $(inputs_dir)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The path has slashes: /a/b/c/inputs #@ ``` #+end_src cfengine-3.24.2/examples/isvariable.cf0000644000000000000000000000265015010704253017627 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "bla" string => "xyz.."; classes: "exists" expression => isvariable("bla"); reports: exists:: "Variable exists: \"$(bla)\".."; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: Variable exists: "xyz..".. #@ ``` #+end_src cfengine-3.24.2/examples/process_restart.cf0000644000000000000000000000266615010704253020737 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "process_restart" }; } ######################################################### bundle agent process_restart { vars: "component" slist => { "cf-monitord", "cf-serverd", "cf-execd" }; processes: "$(component)" restart_class => canonify("start_$(component)"); commands: "/var/cfengine/bin/$(component)" if => canonify("start_$(component)"); } cfengine-3.24.2/examples/length.cf0000644000000000000000000000340015010704253016761 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "test" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "length" int => length("test"); "test_str" string => join(",", "test"); reports: "The test list is $(test_str)"; "The test list has $(length) elements"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The test list is 1,2,3,one,two,three,long string,four,fix,six,one,two,three #@ R: The test list has 13 elements #@ ``` #+end_src cfengine-3.24.2/examples/simple_ssh_key_distribution.cf0000644000000000000000000000543415010704253023326 0ustar00rootroot00000000000000body common control { bundlesequence => { "autorun_ssh_key_distribution" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle common ssh_key_info { meta: "description" string => "This bundle defines common ssh key information, like which directory and server keys should be sourced from."; vars: "key_server" string => "$(sys.policy_hub)"; # We set the path to the repo in a common bundle so that we can reference # the same path when defining access rules and when copying files. # This directory is expected to contain one file for each users authorized # keys, named for the username. For example: /srv/ssh_authorized_keys/kelly "repo_path" string => "/srv/ssh_authorized_keys"; } bundle agent autorun_ssh_key_distribution { meta: # Here we simply tag the bundle for use with the `services_autorun` # feature. "tags" slist => { "autorun" }; vars: "users" slist => { "bob", "frank", "kelly" }; methods: "Distribute SSH Keys" usebundle => ssh_key_distribution( $(users) ), if => userexists( $(users) ), comment => "It's important that we make sure each of these users ssh_authorized_keys file has the correct content and permissions so that they can successfully log in, if the user exists on the executing agents host."; } bundle agent ssh_key_distribution(users) { meta: "description" string => "Ensure that specified users are able to log in using their ssh keys"; vars: # We get the users UID so that we can set permission appropriately "uid[$(users)]" int => getuid( $(users) ); files: "/home/$(users)/.ssh/." create => "true", perms => mo( 700, "$(uid[$(users)])"), comment => "It is important to set the proper restrictive permissions and ownership so that the ssh authorized_keys feature works correctly."; "/home/$(users)/.ssh/authorized_keys" perms => mo( 600, "$(uid[$(users)])" ), copy_from => remote_dcp( "$(ssh_key_info.repo_path)/$(users)", $(ssh_key_info.key_server) ), comment => "We centrally manage and users authorized keys. We source each users complete authorized_keys file from the central server."; } bundle server ssh_key_access_rules { meta: "description" string => "This bundle handles sharing the directory where ssh keys are distributed from."; access: # Only hosts with class `policy_server` should share the path to ssh # authorized_keys policy_server:: "$(ssh_key_info.repo_path)" admit => { @(def.acl) }, comment => "We share the ssh authorized keys with all authorized hosts."; } cfengine-3.24.2/examples/services.cf0000644000000000000000000000350615010704253017332 0ustar00rootroot00000000000000body file control { inputs => { "$(sys.libdir)/services.cf", "$(sys.libdir)/commands.cf" }; } bundle agent main # @brief Example showing services promises to manage standard operating system # services { vars: linux:: "enable[ssh]" string => ifelse( "debian|ubuntu", "ssh", "sshd"), comment => "The name of the ssh service varies on different platforms. Here we set the name of the service based on existing classes and defaulting to `sshd`"; "disable[apache]" string => ifelse( "debian|ubuntu", "apache2", "httpd" ), comment => "The name of the apache web service varies on different platforms. Here we set the name of the service based on existing classes and defaulting to `httpd`"; "enable[cron]" string => ifelse( "debian|ubuntu", "cron", "crond" ), comment => "The name of the cron service varies on different platforms. Here we set the name of the service based on existing classes and defaulting to `crond`"; "disable[cups]" string => "cups", comment => "Printing services are not needed on most hosts."; "enabled" slist => getvalues( enable ); "disabled" slist => getvalues( disable ); services: linux:: "$(enabled)" -> { "SysOps" } service_policy => "start", comment => "These services should be running because x, y or z."; "$(disabled)" -> { "SysOps" } service_policy => "stop", comment => "These services should not be running because x, y or z."; systemd:: "sysstat" service_policy => "stop", comment => "Standard service handling for sysstat only works with systemd. Other inits need cron entries managed."; } cfengine-3.24.2/examples/difference.cf0000644000000000000000000000472615010704253017606 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "a" slist => { 1,2,3,"x" }; "b" slist => { "x" }; # normal usage "diff_between_a_and_b" slist => difference(a, b); "diff_between_a_and_b_str" string => join(",", diff_between_a_and_b); # NOTE: advanced usage! "mylist1" slist => { "a", "b" }; "mylist2" slist => { "a", "b" }; "$(mylist1)_str" string => join(",", $(mylist1)); # Here we're going to really call difference(a,a) then difference(a,b) then difference(b,a) then difference(b,b) # We create a new variable for each difference!!! "diff_$(mylist1)_$(mylist2)" slist => difference($(mylist1), $(mylist2)); "diff_$(mylist1)_$(mylist2)_str" string => join(",", "diff_$(mylist1)_$(mylist2)"); reports: # normal usage "The difference between lists a and b is '$(diff_between_a_and_b_str)'"; # NOTE: advanced usage results! "The difference of list '$($(mylist1)_str)' with '$($(mylist2)_str)' is '$(diff_$(mylist1)_$(mylist2)_str)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: The difference between lists a and b is '1,2,3' #@ R: The difference of list '1,2,3,x' with '1,2,3,x' is '' #@ R: The difference of list '1,2,3,x' with 'x' is '1,2,3' #@ R: The difference of list 'x' with '1,2,3,x' is '' #@ R: The difference of list 'x' with 'x' is '' #@ ``` #+end_src cfengine-3.24.2/examples/some.cf0000644000000000000000000000702015010704253016445 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { classes: # This is an easy way to check if a list is empty, better than # expression => strcmp(length(x), "0") # Note that if you use length() or none() or every() they will # go through all the elements!!! some() returns as soon as any # element matches. "empty_x" not => some(".*", x); "empty_y" not => some(".*", y); "some11" expression => some("long string", test1); "some12" expression => some("none", test1); "some21" expression => some("long string", test2); "some22" expression => some("none", test2); vars: "x" slist => { "a", "b" }; "y" slist => { }; "test1" slist => { 1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three", }; "test2" data => parsejson('[1,2,3, "one", "two", "three", "long string", "four", "fix", "six", "one", "two", "three",]'); reports: empty_x:: "x has no elements"; empty_y:: "y has no elements"; any:: "The test1 list is $(test1)"; some11:: "some() test1 1 passed"; !some11:: "some() test1 1 failed"; some12:: "some() test1 2 failed"; !some12:: "some() test1 2 passed"; "The test2 list is $(test2)"; some21:: "some() test2 1 passed"; !some21:: "some() test2 1 failed"; some22:: "some() test2 2 failed"; !some22:: "some() test2 2 passed"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: y has no elements #@ R: The test1 list is 1 #@ R: The test1 list is 2 #@ R: The test1 list is 3 #@ R: The test1 list is one #@ R: The test1 list is two #@ R: The test1 list is three #@ R: The test1 list is long string #@ R: The test1 list is four #@ R: The test1 list is fix #@ R: The test1 list is six #@ R: some() test1 1 passed #@ R: some() test1 2 passed #@ R: The test2 list is 1 #@ R: The test2 list is 2 #@ R: The test2 list is 3 #@ R: The test2 list is one #@ R: The test2 list is two #@ R: The test2 list is three #@ R: The test2 list is long string #@ R: The test2 list is four #@ R: The test2 list is fix #@ R: The test2 list is six #@ R: some() test2 1 passed #@ R: some() test2 2 passed #@ ``` #+end_src cfengine-3.24.2/examples/classes_context_applies_multiple_promises.cf0000644000000000000000000000201515010704253026253 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This promise is not restricted."; any:: "Neither is this promise restricted, 'any' is always defined."; linux:: "This promise is restricted to hosts that have the class 'linux' defined."; "This promise is also restricted to hosts that have the class 'linux' defined."; linux.cfengine_4:: "This promise is restricted to hosts that have both the 'linux' class AND the 'cfengine_4' class."; !any:: "This promise will never be actuated."; vars: "Message" string => "Hello World!"; reports: "And this promise is again unrestricted"; } #+end_src #+begin_src example_output #@ ``` #@ R: This promise is not restricted. #@ R: Neither is this promise restricted, 'any' is always defined. #@ R: This promise is restricted to hosts that have the class 'linux' defined. #@ R: This promise is also restricted to hosts that have the class 'linux' defined. #@ R: And this promise is again unrestricted #@ ``` #+end_src cfengine-3.24.2/examples/method_var.cf0000644000000000000000000000142515010704253017635 0ustar00rootroot00000000000000# # Demonstrates the use of variables to call bundles. # We can then filter variables on classes, for example. # body common control { bundlesequence => { "example" }; } ########################################### bundle agent test { vars: "run_bundles" slist => { "test_one", "test_two" }; "run_a_bundle" string => "test_three"; methods: "any" usebundle => "$(run_bundles)"; "any" usebundle => "$(run_a_bundle)"; } ########################################### bundle agent test_one { reports: "in test_one"; } ########################################### bundle agent test_two { reports: "in test_two"; } ########################################### bundle agent test_three { reports: "in test_three"; } cfengine-3.24.2/examples/grep.cf0000644000000000000000000000371115010704253016442 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test { vars: "mylist" slist => { "One", "Two", "Three", "Four", "Five" }; "Tlist" slist => grep("T.*","mylist"); "empty_list" slist => grep("ive","mylist"); "datalist" data => parsejson('[1,2,3, "Tab", "chive"]'); "data_Tlist" slist => grep("T.*","datalist"); "data_empty_list" slist => grep("ive","datalist"); "todo" slist => { "mylist", "Tlist", "empty_list", "datalist", "data_Tlist", "data_empty_list" }; "$(todo)_str" string => format("%S", $(todo)); reports: "$(todo): $($(todo)_str)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: mylist: { "One", "Two", "Three", "Four", "Five" } #@ R: Tlist: { "Two", "Three" } #@ R: empty_list: { } #@ R: datalist: [1,2,3,"Tab","chive"] #@ R: data_Tlist: { "Tab" } #@ R: data_empty_list: { } #@ ``` #+end_src cfengine-3.24.2/examples/parsestringarrayidx.cf0000644000000000000000000000372615010704253021620 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "test" }; } bundle agent test(f) { vars: # Define data inline for convenience "table" string => "one: a two: b three: c"; ####################################### "dim" int => parsestringarrayidx( "items", "$(table)", "\s*#[^\n]*", ":", "1000", "200000" ); "keys" slist => getindices("items"); "sorted_keys" slist => sort(keys, "int"); reports: "item $(sorted_keys) has column 0 = $(items[$(sorted_keys)][0]) and column 1 = $(items[$(sorted_keys)][1])"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: item 0 has column 0 = one and column 1 = a #@ R: item 1 has column 0 = two and column 1 = b #@ R: item 2 has column 0 = three and column 1 = c #@ ``` #+end_src cfengine-3.24.2/examples/depends_on.cf0000644000000000000000000000027615010704253017626 0ustar00rootroot00000000000000 body common control { bundlesequence => { "one" }; } bundle agent one { reports: "two" depends_on => { "handle_one" }; "one" handle => "handle_one"; } cfengine-3.24.2/examples/classfiltercsv.cf0000644000000000000000000000532215010704253020534 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo 'ClassExpr,Sort,Token,Value' > /tmp/classfiltercsv.csv #@ echo '# This is a comment' >> /tmp/classfiltercsv.csv #@ echo 'any,A,net.ipv4.ip_forward,ANYVALUE' >> /tmp/classfiltercsv.csv #@ echo 'example_class1,z,net.ipv4.ip_forward,ANYVALUE' >> /tmp/classfiltercsv.csv #@ echo 'example_class2,a,net.ipv4.ip_forward,127.0.0.3' >> /tmp/classfiltercsv.csv #@ echo 'not_defined,Z,net.ipv4.ip_forward,NOT_DEFINED' >> /tmp/classfiltercsv.csv #@ echo 'example_class3,1,net.ipv4.ip_forward,127.0.0.4' >> /tmp/classfiltercsv.csv #@ echo 'also_undefined,0,net.ipv4.ip_forward,NOT_DEFINED' >> /tmp/classfiltercsv.csv #@ sed -i 's/$/\r/' /tmp/classfiltercsv.csv #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent example_classfiltercsv { classes: "example_class1"; "example_class2"; "example_class3"; vars: "data_file" string => "/tmp/classfiltercsv.csv"; "d" data => classfiltercsv($(data_file), "true", 0, 1); reports: "Filtered data: $(with)" with => string_mustache("{{%-top-}}", d); } bundle agent __main__ { methods: "example_classfiltercsv"; } #+end_src #+begin_src example_output #@ ``` #@ R: Filtered data: [ #@ { #@ "Sort": "1", #@ "Token": "net.ipv4.ip_forward", #@ "Value": "127.0.0.4" #@ }, #@ { #@ "Sort": "A", #@ "Token": "net.ipv4.ip_forward", #@ "Value": "ANYVALUE" #@ }, #@ { #@ "Sort": "a", #@ "Token": "net.ipv4.ip_forward", #@ "Value": "127.0.0.3" #@ }, #@ { #@ "Sort": "z", #@ "Token": "net.ipv4.ip_forward", #@ "Value": "ANYVALUE" #@ } #@ ] #@ ``` #+end_src cfengine-3.24.2/examples/cf_version_maximum.cf0000644000000000000000000000066515010704253021404 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent __main__ { reports: "This will be skipped on newer versions" if => cf_version_maximum("3.15"); "This will be skipped on older or equal versions" unless => cf_version_maximum("3.15"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: This will be skipped on older or equal versions #@ ``` #+end_src cfengine-3.24.2/examples/files_content.cf0000644000000000000000000000173515010704253020345 0ustar00rootroot00000000000000#+begin_src cfengine3 bundle agent example_file_content # @brief Example showing files content { vars: "my_content" string => "Hello from var!"; files: "/tmp/hello_string" create => "true", content => "Hello from string!"; "/tmp/hello_var" create => "true", content => "$(my_content)"; reports: "/tmp/hello_string" printfile => cat( $(this.promiser) ); "/tmp/hello_var" printfile => cat( $(this.promiser) ); } body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } bundle agent __main__ { methods: "example_file_content"; } ############################################################################### #+end_src #+begin_src example_output #@ ``` #@ R: /tmp/hello_string #@ R: Hello from string! #@ R: /tmp/hello_var #@ R: Hello from var! #@ ``` #+end_src cfengine-3.24.2/examples/readintrealstringlist.cf0000644000000000000000000000531615010704253022125 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo 1 > /tmp/cfe_list_ints #@ echo # Comment >> /tmp/cfe_list_ints #@ echo 2 >> /tmp/cfe_list_ints #@ echo # Another Comment >> /tmp/cfe_list_ints #@ echo 3 >> /tmp/cfe_list_ints #@ echo 1.1 > /tmp/cfe_list_reals #@ echo # Comment >> /tmp/cfe_list_reals #@ echo 2.2 >> /tmp/cfe_list_reals #@ echo # Another Comment >> /tmp/cfe_list_reals #@ echo 3 >> /tmp/cfe_list_reals #@ echo alpha > /tmp/cfe_list_strings #@ echo # Comment >> /tmp/cfe_list_strings #@ echo beta >> /tmp/cfe_list_strings #@ echo # Another Comment >> /tmp/cfe_list_strings #@ echo gamma >> /tmp/cfe_list_strings #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "integers" ilist => readintlist("/tmp/cfe_list_ints","#[^\n]*","[\n]",10,400); "strings" slist => readstringlist("/tmp/cfe_list_strings", "#[^\n]*", "\s", 10, 400); "reals" rlist => readreallist("/tmp/cfe_list_reals","#[^\n]*","[\n]",10,400); reports: "integers in /tmp/cfe_list_ints: $(integers)"; "strings in /tmp/cfe_list_strings: $(strings)"; "reals in /tmp/cfe_list_reals: $(reals)"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: integers in /tmp/cfe_list_ints: 1 #@ R: integers in /tmp/cfe_list_ints: 2 #@ R: integers in /tmp/cfe_list_ints: 3 #@ R: strings in /tmp/cfe_list_strings: alpha #@ R: strings in /tmp/cfe_list_strings: beta #@ R: strings in /tmp/cfe_list_strings: gamma #@ R: reals in /tmp/cfe_list_reals: 1.1 #@ R: reals in /tmp/cfe_list_reals: 2.2 #@ R: reals in /tmp/cfe_list_reals: 3 #@ ``` #+end_src cfengine-3.24.2/examples/commands.cf0000644000000000000000000000241515010704253017306 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "my_commands" }; inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent my_commands { commands: Sunday.Hr04.Min05_10.myhost:: "/usr/bin/update_db"; any:: "/etc/mysql/start" contain => setuid("mysql"); } cfengine-3.24.2/examples/edit_passwd_file.cf0000644000000000000000000000424615010704253021016 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. body common control { bundlesequence => { "addpasswd" }; } bundle agent addpasswd { vars: # want to set these values by the names of their array keys "pwd[mark]" string => "mark:x:1000:100:Mark Burgess:/home/mark:/bin/bash"; "pwd[fred]" string => "fred:x:1001:100:Right Said:/home/fred:/bin/bash"; "pwd[jane]" string => "jane:x:1002:100:Jane Doe:/home/jane:/bin/bash"; files: "/tmp/passwd" create => "true", edit_line => append_users_starting("addpasswd.pwd"); } ############################################################ # Library stuff ############################################################ bundle edit_line append_users_starting(v) { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => userexists("$(index)"); insert_lines: "$($(v)[$(index)])" if => "add_$(index)"; } ############################################################ bundle edit_line append_groups_starting(v) { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => groupexists("$(index)"); insert_lines: "$($(v)[$(index)])" if => "add_$(index)"; } cfengine-3.24.2/examples/string_replace.cf0000644000000000000000000000373215010704253020511 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 bundle agent main { vars: # replace one occurence "replace_once" string => string_replace("This is a string", "string", "thing"); # replace several occurences "replace_several" string => string_replace("This is a string", "i", "o"); # replace nothing "replace_none" string => string_replace("This is a string", "boat", "no"); # replace ambiguous order "replace_ambiguous" string => string_replace("aaaaa", "aaa", "b"); reports: # in order, the above... "replace_once = '$(replace_once)'"; "replace_several = '$(replace_several)'"; "replace_none = '$(replace_none)'"; "replace_ambiguous = '$(replace_ambiguous)'"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: replace_once = 'This is a thing' #@ R: replace_several = 'Thos os a strong' #@ R: replace_none = 'This is a string' #@ R: replace_ambiguous = 'baa' #@ ``` #+end_src cfengine-3.24.2/examples/repairedcommand.cf0000644000000000000000000000055115010704253020636 0ustar00rootroot00000000000000body common control { bundlesequence => { "cmdtest" }; } bundle agent cmdtest { commands: "/bin/false" classes => example; reports: wasrepaired:: "The command-promise got repaired!"; } body classes example { repaired_returncodes => { "0", "1" }; promise_repaired => { "wasrepaired" }; } cfengine-3.24.2/examples/readstringarray.cf0000644000000000000000000000716215010704253020712 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src prep #@ ``` #@ echo "at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash" > /tmp/readstringarray.txt #@ echo "avahi:x:103:105:User for Avahi:/var/run/avahi-daemon:/bin/false # Disallow login" >> /tmp/readstringarray.txt #@ echo "beagleindex:x:104:106:User for Beagle indexing:/var/cache/beagle:/bin/bash" >> /tmp/readstringarray.txt #@ echo "bin:x:1:1:bin:/bin:/bin/bash" >> /tmp/readstringarray.txt #@ echo "# Daemon has the default shell" >> /tmp/readstringarray.txt #@ echo "daemon:x:2:2:Daemon:/sbin:" >> /tmp/readstringarray.txt #@ ``` #+end_src ############################################################################### #+begin_src cfengine3 bundle agent main { vars: "lines" int => readstringarray("array_name", "/tmp/readstringarray.txt", "#[^\n]*", ":", 10, 4000); reports: "array_name contains $(lines) keys$(const.n)$(with)" with => string_mustache("{{%-top-}}", "array_name"); } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: array_name contains 5 keys #@ { #@ "at": { #@ "0": "at", #@ "1": "x", #@ "2": "25", #@ "3": "25", #@ "4": "Batch jobs daemon", #@ "5": "/var/spool/atjobs", #@ "6": "/bin/bash" #@ }, #@ "avahi": { #@ "0": "avahi", #@ "1": "x", #@ "2": "103", #@ "3": "105", #@ "4": "User for Avahi", #@ "5": "/var/run/avahi-daemon", #@ "6": "/bin/false " #@ }, #@ "beagleindex": { #@ "0": "beagleindex", #@ "1": "x", #@ "2": "104", #@ "3": "106", #@ "4": "User for Beagle indexing", #@ "5": "/var/cache/beagle", #@ "6": "/bin/bash" #@ }, #@ "bin": { #@ "0": "bin", #@ "1": "x", #@ "2": "1", #@ "3": "1", #@ "4": "bin", #@ "5": "/bin", #@ "6": "/bin/bash" #@ }, #@ "daemon": { #@ "0": "daemon", #@ "1": "x", #@ "2": "2", #@ "3": "2", #@ "4": "Daemon", #@ "5": "/sbin", #@ "6": "" #@ } #@ } #@ ``` #+end_src cfengine-3.24.2/examples/type.cf0000644000000000000000000000235215010704253016466 0ustar00rootroot00000000000000#+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { vars: "foo" data => '{ "bar": true, "baz": [1, 2, 3] }'; "_foo" string => type("foo", "true"); "_foobar" string => type("foo[bar]", "false"); "_foobaz" string => type("foo[baz]", "true"); "a" string => "hello"; "b" int => "123"; "c" rlist => { "1.1", "2.2", "3.3" }; "_a" string => type("a"); "_b" string => type("b", "true"); "_c" string => type("c", "false"); reports: "'foo' is of type '$(_foo)' (detail)"; "'foo[bar]' is of type '$(_foobar)' (no detail)"; "'foo[baz]' is of type '$(_foobaz)' (detail)"; "'a' is of type '$(_a)' (no detail)"; "'b' is of type '$(_b)' (detail)"; "'c' is of type '$(_c)' (no detail)"; } #+end_src ############################################################################# #+begin_src example_output #@ ``` #@ R: 'foo' is of type 'data object' (detail) #@ R: 'foo[bar]' is of type 'data' (no detail) #@ R: 'foo[baz]' is of type 'data array' (detail) #@ R: 'a' is of type 'string' (no detail) #@ R: 'b' is of type 'policy int' (detail) #@ R: 'c' is of type 'rlist' (no detail) #@ ``` #+end_src cfengine-3.24.2/examples/action_policy.cf0000755000000000000000000001110015010704253020333 0ustar00rootroot00000000000000#!/var/cfengine/bin/cf-agent -f- # Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body file control { # Include the stdlib for local_dcp, policy, delete_lines inputs => { "$(sys.libdir)/stdlib.cf" }; } bundle agent example_action_policy # @brief Example illustrating how action_policy in action bodies control promise actuation and outcomes { files: # We make sure there is some files to operate on, so we simply make a copy # of ourselves "$(this.promise_filename).nop" copy_from => local_dcp( $(this.promise_filename) ); "$(this.promise_filename).warn" copy_from => local_dcp( $(this.promise_filename) ); "$(this.promise_filename).fix" copy_from => local_dcp( $(this.promise_filename) ); # We exercise each valid value of action_policy (nop, fix, warn) defining # classes named for the action_policy "$(this.promise_filename).nop" handle => "delete_lines_action_nop", edit_line => delete_lines_matching ( ".*" ), action => policy( "nop" ), classes => results( "namespace", "MY_files_promise_nop" ); "$(this.promise_filename).warn" handle => "delete_lines_action_warn", edit_line => delete_lines_matching ( ".*" ), action => policy( "warn" ), classes => results( "namespace", "MY_files_promise_warn" ); "$(this.promise_filename).fix" handle => "delete_lines_action_fix", edit_line => delete_lines_matching ( ".*" ), action => policy( "fix" ), classes => results( "namespace", "MY_files_promise_fix" ); commands: "/bin/echo Running Command nop" handle => "command_nop", action => policy( "nop" ), classes => results( "namespace", "MY_commands_promise_nop" ); "/bin/echo Running Command warn" handle => "command_warn", action => policy( "warn" ), classes => results( "namespace", "MY_commands_promise_warn" ); "/bin/echo Running Command fix" handle => "command_fix", action => policy( "fix" ), classes => results( "namespace", "MY_commands_promise_fix" ); reports: "MY classes:$(const.n)$(const.t)$(with)" with => join( "$(const.n)$(const.t)", sort( classesmatching( "MY_.*" ), "lex" )); } bundle agent __main__ { methods: "example_action_policy"; } #+end_src ############################################################################### #+begin_src mock_example_output #@ ``` #@ warning: Should edit file '/tmp/action_policy.cf.nop' but only a warning promised #@ warning: Should edit file '/tmp/action_policy.cf.warn' but only a warning promised #@ warning: Command '/bin/echo Running Command nop' needs to be executed, but only warning was promised #@ warning: Command '/bin/echo Running Command warn' needs to be executed, but only warning was promised #@ R: MY classes: #@ MY_commands_promise_fix_reached #@ MY_commands_promise_fix_repaired #@ MY_commands_promise_nop_error #@ MY_commands_promise_nop_failed #@ MY_commands_promise_nop_not_kept #@ MY_commands_promise_nop_reached #@ MY_commands_promise_warn_error #@ MY_commands_promise_warn_failed #@ MY_commands_promise_warn_not_kept #@ MY_commands_promise_warn_reached #@ MY_files_promise_fix_reached #@ MY_files_promise_fix_repaired #@ MY_files_promise_nop_error #@ MY_files_promise_nop_failed #@ MY_files_promise_nop_not_kept #@ MY_files_promise_nop_reached #@ MY_files_promise_warn_error #@ MY_files_promise_warn_failed #@ MY_files_promise_warn_not_kept #@ MY_files_promise_warn_reached #@ warning: Method 'example_action_policy' invoked repairs, but only warnings promised #@ ``` #+end_src cfengine-3.24.2/examples/fileexists.cf0000644000000000000000000000306415010704253017665 0ustar00rootroot00000000000000# Copyright 2021 Northern.tech AS # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # To the extent this program is licensed as part of the Enterprise # versions of Cfengine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. #+begin_src cfengine3 body common control { bundlesequence => { "example" }; } bundle agent example { classes: # this.promise_filename has the currently-executed file, so it # better exist! "exists" expression => fileexists($(this.promise_filename)); "exists_etc_passwd" expression => fileexists("/etc/passwd"); reports: exists:: "I exist! I mean, file exists!"; } #+end_src ############################################################################### #+begin_src example_output #@ ``` #@ R: I exist! I mean, file exists! #@ ``` #+end_src cfengine-3.24.2/cf-agent/0000755000000000000000000000000015010704322015034 5ustar00rootroot00000000000000cfengine-3.24.2/cf-agent/package_module.h0000644000000000000000000000551015010704253020151 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef PACKAGE_MODULE_H #define PACKAGE_MODULE_H #include //TODO: use promise expireafter instead #define PACKAGE_PROMISE_SCRIPT_TIMEOUT_SEC 4 * 3600 /* 4 hours timeout */ #define PACKAGE_PROMISE_TERMINATION_CHECK_SEC 1 #define GLOBAL_PACKAGE_PROMISE_LOCK_NAME "new_packages_promise_lock" typedef enum { PACKAGE_TYPE_NONE, PACKAGE_TYPE_REPO, PACKAGE_TYPE_FILE } PackageType; typedef struct { char *name; char *version; char *arch; PackageType type; } PackageInfo; typedef struct { char *type; char *message; } PackageError; typedef struct { char *name; char *path; char *script_path; char *script_path_quoted; char *script_exec_opts; PackageModuleBody *package_module; int supported_api_version; } PackageModuleWrapper; typedef struct { CfLock g_lock; EvalContext *lock_ctx; } PackagePromiseGlobalLock; typedef enum { UPDATE_TYPE_INSTALLED, UPDATE_TYPE_UPDATES, UPDATE_TYPE_LOCAL_UPDATES, } UpdateType; PromiseResult HandlePresentPromiseAction(EvalContext *ctx, const Promise *pp, const Attributes *attr, const PackageModuleWrapper *wrapper); PromiseResult HandleAbsentPromiseAction(EvalContext *ctx, const Promise *pp, const Attributes *attr, const PackageModuleWrapper *wrapper); void UpdatePackagesCache(EvalContext *ctx, bool force_update); PackageModuleWrapper *NewPackageModuleWrapper(PackageModuleBody *package_module); void DeletePackageModuleWrapper(PackageModuleWrapper *wrapper); PackagePromiseGlobalLock AcquireGlobalPackagePromiseLock(EvalContext *ctx); void YieldGlobalPackagePromiseLock(PackagePromiseGlobalLock lock); #endif cfengine-3.24.2/cf-agent/verify_methods.c0000644000000000000000000002220015010704253020226 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include // FatalError() #include #include #include #include #include #include #include #include #include // HashVariables #include #include #include #include static void GetReturnValue(EvalContext *ctx, const Bundle *callee, const Promise *caller); /*****************************************************************************/ /* * This function should only be called from the evaluator so that methods promises * never report REPAIRED compliance (the promises inside will do that already). * * Promise types that delegate to bundles (services and users) should call VerifyMethod, * which maintains the REPAIRED compliance so that it bubbles up correctly to the parent * promise type. */ PromiseResult VerifyMethodsPromise(EvalContext *ctx, const Promise *pp) { Attributes a = GetMethodAttributes(ctx, pp); const Constraint *cp; Rval method_name; bool destroy_name; if ((cp = PromiseGetConstraint(pp, "usebundle"))) { method_name = cp->rval; destroy_name = false; } else { method_name = RvalNew(pp->promiser, RVAL_TYPE_SCALAR); destroy_name = true; } PromiseResult result = VerifyMethod(ctx, method_name, &a, pp); if (destroy_name) { RvalDestroy(method_name); } return result; } /*****************************************************************************/ PromiseResult VerifyMethod(EvalContext *ctx, const Rval call, const Attributes *a, const Promise *pp) { const Rlist *args = NULL; Buffer *method_name = BufferNew(); switch (call.type) { case RVAL_TYPE_FNCALL: { const FnCall *fp = RvalFnCallValue(call); ExpandScalar(ctx, PromiseGetBundle(pp)->ns, PromiseGetBundle(pp)->name, fp->name, method_name); args = fp->args; while (args) { args = args->next; } args = fp->args; } break; case RVAL_TYPE_SCALAR: { ExpandScalar(ctx, PromiseGetBundle(pp)->ns, PromiseGetBundle(pp)->name, RvalScalarValue(call), method_name); args = NULL; } break; default: BufferDestroy(method_name); return PROMISE_RESULT_NOOP; } char lockname[CF_BUFSIZE]; GetLockName(lockname, "method", pp->promiser, args); CfLock thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a->transaction.ifelapsed, a->transaction.expireafter, pp, false); if (thislock.lock == NULL) { BufferDestroy(method_name); return PROMISE_RESULT_SKIPPED; } PromiseBanner(ctx, pp); const Bundle *bp = EvalContextResolveBundleExpression(ctx, PromiseGetPolicy(pp), BufferData(method_name), "agent"); if (!bp) { bp = EvalContextResolveBundleExpression(ctx, PromiseGetPolicy(pp), BufferData(method_name), "common"); } PromiseResult result = PROMISE_RESULT_NOOP; if (bp) { if (a->transaction.action == cfa_warn) // don't skip for dry-runs (ie ignore DONTDO) { result = PROMISE_RESULT_WARN; cfPS(ctx, LOG_LEVEL_WARNING, result, pp, a, "Bundle '%s' should be invoked, but only a warning was promised!", BufferData(method_name)); } else { BundleBanner(bp, args); EvalContextSetBundleArgs(ctx, args); EvalContextStackPushBundleFrame(ctx, bp, args, a->inherit); /* Clear all array-variables that are already set in the sub-bundle. Otherwise, array-data accumulates between multiple bundle evaluations. Note: for bundles invoked multiple times via bundlesequence, array data *does* accumulate. */ VariableTableIterator *iter = EvalContextVariableTableIteratorNew(ctx, bp->ns, bp->name, NULL); Variable *var; while ((var = VariableTableIteratorNext(iter))) { const VarRef *var_ref = VariableGetRef(var); if (!var_ref->num_indices) { continue; } EvalContextVariableRemove(ctx, var_ref); } VariableTableIteratorDestroy(iter); BundleResolve(ctx, bp); result = ScheduleAgentOperations(ctx, bp); GetReturnValue(ctx, bp, pp); EvalContextStackPopFrame(ctx); EvalContextSetBundleArgs(ctx, NULL); switch (result) { case PROMISE_RESULT_SKIPPED: // if a bundle returns 'skipped', meaning that all promises were locked in the bundle, // we explicitly consider the method 'kept' result = PROMISE_RESULT_NOOP; // intentional fallthru case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Method '%s' verified", bp->name); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Method '%s' invoked repairs, but only warnings promised", bp->name); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Method '%s' invoked repairs", bp->name); break; case PROMISE_RESULT_FAIL: case PROMISE_RESULT_DENIED: cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Method '%s' failed in some repairs", bp->name); break; default: // PROMISE_RESULT_INTERRUPTED, TIMEOUT cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_FAIL, pp, a, "Method '%s' aborted in some repairs", bp->name); break; } } for (const Rlist *rp = bp->args; rp; rp = rp->next) { const char *lval = RlistScalarValue(rp); VarRef *ref = VarRefParseFromBundle(lval, bp); EvalContextVariableRemove(ctx, ref); VarRefDestroy(ref); } } else { if (IsCf3VarString(BufferData(method_name))) { Log(LOG_LEVEL_ERR, "A variable seems to have been used for the name of the method. In this case, the promiser also needs to contain the unique name of the method"); } cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "A method attempted to use a bundle '%s' that was apparently not defined", BufferData(method_name)); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); if (!EvalContextGetConfig(ctx)->ignore_missing_bundles) { FatalError(ctx, "Aborting due to missing bundle '%s'", BufferData(method_name)); } } YieldCurrentLock(thislock); BufferDestroy(method_name); EndBundleBanner(bp); return result; } /***********************************************************************/ static void GetReturnValue(EvalContext *ctx, const Bundle *callee, const Promise *caller) { char *result = PromiseGetConstraintAsRval(caller, "useresult", RVAL_TYPE_SCALAR); if (result) { VarRef *ref = VarRefParseFromBundle("last-result", callee); VariableTableIterator *iter = EvalContextVariableTableIteratorNew(ctx, ref->ns, ref->scope, ref->lval); Variable *result_var = NULL; while ((result_var = VariableTableIteratorNext(iter))) { const VarRef *result_var_ref = VariableGetRef(result_var); assert(result_var_ref->num_indices == 1); if (result_var_ref->num_indices != 1) { continue; } VarRef *new_ref = VarRefParseFromBundle(result, PromiseGetBundle(caller)); VarRefAddIndex(new_ref, result_var_ref->indices[0]); Rval result_var_rval = VariableGetRval(result_var, true); EvalContextVariablePut(ctx, new_ref, result_var_rval.item, VariableGetType(result_var), "source=bundle"); VarRefDestroy(new_ref); } VarRefDestroy(ref); VariableTableIteratorDestroy(iter); } } cfengine-3.24.2/cf-agent/findhub.c0000644000000000000000000001563315010704253016632 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include List *hublist = NULL; static void CleanupDlClose(void); static int CompareHosts(const void *a, const void *b); void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void *userdata) { assert(c); if (state == AVAHI_CLIENT_FAILURE) { Log(LOG_LEVEL_ERR, "Server connection failure '%s'", avahi_strerror_ptr(avahi_client_errno_ptr(c))); avahi_simple_poll_quit_ptr(spoll); } } void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void *userdata) { AvahiClient *c = userdata; assert(b); switch(event) { case AVAHI_BROWSER_FAILURE: Log(LOG_LEVEL_ERR, "Avahi browser error '%s'", avahi_strerror_ptr(avahi_client_errno_ptr(avahi_service_browser_get_client_ptr(b)))); avahi_simple_poll_quit_ptr(spoll); return; case AVAHI_BROWSER_NEW: if ( !(avahi_service_resolver_new_ptr(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, (AvahiServiceResolverCallback) resolve_callback, c)) ) { Log(LOG_LEVEL_ERR, "Failed to resolve service '%s', error '%s'", name, avahi_strerror_ptr(avahi_client_errno_ptr(c))); } break; case AVAHI_BROWSER_REMOVE: break; case AVAHI_BROWSER_ALL_FOR_NOW: avahi_simple_poll_quit_ptr(spoll); break; case AVAHI_BROWSER_CACHE_EXHAUSTED: break; } } void resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AVAHI_GCC_UNUSED AvahiStringList *txt, AVAHI_GCC_UNUSED AvahiLookupFlags flags, AVAHI_GCC_UNUSED void* userdata) { HostProperties *hostprop = xcalloc(1, sizeof(HostProperties)); assert(r); char a[AVAHI_ADDRESS_STR_MAX]; switch(event) { case AVAHI_RESOLVER_FAILURE: Log(LOG_LEVEL_ERR, "In Avahi resolver, failed to resolve service '%s' of type '%s' in domain '%s' (error: '%s')", name, type, domain, avahi_strerror_ptr(avahi_client_errno_ptr(avahi_service_resolver_get_client_ptr(r)))); break; case AVAHI_RESOLVER_FOUND: avahi_address_snprint_ptr(a, sizeof(a), address); strlcpy(hostprop->Hostname, host_name, 4096); strlcpy(hostprop->IPAddress, a, AVAHI_ADDRESS_STR_MAX); hostprop->Port = port; ListAppend(hublist, hostprop); break; } avahi_service_resolver_free_ptr(r); } void PrintList(List *list) { ListIterator *i = NULL; i = ListIteratorGet(list); if (!i) { ProgrammingError("Unable to get iterator for hub list"); return; } do { HostProperties *hostprop = (HostProperties *)ListIteratorData(i); Log(LOG_LEVEL_NOTICE, "CFEngine Policy Server: hostname '%s', IP address '%s', port %d", hostprop->Hostname, hostprop->IPAddress, hostprop->Port); } while (ListIteratorNext(i) != -1); ListIteratorDestroy(&i); } int ListHubs(List **list) { AvahiClient *client = NULL; AvahiServiceBrowser *sb = NULL; int error; hublist = ListNew(&CompareHosts, NULL, &free); if (!hublist) { return -1; } spoll = NULL; avahi_handle = NULL; RegisterCleanupFunction(&CleanupDlClose); if (loadavahi() == -1) { Log(LOG_LEVEL_ERR, "Avahi was not found"); return -1; } if (!(spoll = avahi_simple_poll_new_ptr())) { Log(LOG_LEVEL_ERR, "Failed to create simple poll object."); if (spoll) { avahi_simple_poll_free_ptr(spoll); } return -1; } client = avahi_client_new_ptr(avahi_simple_poll_get_ptr(spoll), 0, client_callback, NULL, &error); if (!client) { Log(LOG_LEVEL_ERR, "Failed to create client '%s'", avahi_strerror_ptr(error)); if (client) { avahi_client_free_ptr(client); } if (spoll) { avahi_simple_poll_free_ptr(spoll); } return -1; } if (!(sb = avahi_service_browser_new_ptr(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_cfenginehub._tcp", NULL, 0, browse_callback, client))) { Log(LOG_LEVEL_ERR, "Failed to create service browser '%s'", avahi_strerror_ptr(avahi_client_errno_ptr(client))); if (spoll) { avahi_simple_poll_free_ptr(spoll); } if (client) { avahi_client_free_ptr(client); } if (sb) { avahi_service_browser_free_ptr(sb); } return -1; } avahi_simple_poll_loop_ptr(spoll); if (sb) avahi_service_browser_free_ptr(sb); if (client) avahi_client_free_ptr(client); if (spoll) avahi_simple_poll_free_ptr(spoll); *list = hublist; return ListCount(*list); } static void CleanupDlClose(void) { if (avahi_handle != NULL) { dlclose(avahi_handle); } } static int CompareHosts(const void *a, const void *b) { return StringSafeCompare(((HostProperties*)a)->Hostname, ((HostProperties*)b)->Hostname); } cfengine-3.24.2/cf-agent/verify_users.h0000644000000000000000000000251315010704253017736 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_USERS_H #define CFENGINE_VERIFY_USERS_H #include PromiseResult VerifyUsersPromise(EvalContext *ctx, const Promise *pp); void VerifyOneUsersPromise (const char *puser, const User *u, PromiseResult *result, enum cfopaction action, EvalContext *ctx, const Attributes *a, const Promise *pp); #endif cfengine-3.24.2/cf-agent/files_editxml.c0000644000000000000000000027763215010704253020054 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* StringMatch() */ enum editxmltypesequence { elx_vars, elx_classes, elx_delete, elx_insert, elx_none }; static const char *const EDITXMLTYPESEQUENCE[] = { "vars", "classes", "build_xpath", "delete_tree", "insert_tree", "delete_attribute", "set_attribute", "delete_text", "set_text", "insert_text", "reports", NULL }; static PromiseResult KeepEditXmlPromise(EvalContext *ctx, const Promise *pp, void *param); #ifdef HAVE_LIBXML2 static bool VerifyXPathBuild(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext, PromiseResult *result); static PromiseResult VerifyTreeDeletions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyTreeInsertions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyAttributeDeletions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyAttributeSet(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyTextDeletions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyTextSet(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyTextInsertions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext); static bool XmlSelectNode(EvalContext *ctx, char *xpath, xmlDocPtr doc, xmlNodePtr *docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool BuildXPathInFile(EvalContext *ctx, char xpath[CF_BUFSIZE], xmlDocPtr doc, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool BuildXPathInNode(EvalContext *ctx, char xpath[CF_BUFSIZE], xmlDocPtr doc, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool DeleteTreeInNode(EvalContext *ctx, char *tree, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool InsertTreeInFile(EvalContext *ctx, char *root, xmlDocPtr doc, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool InsertTreeInNode(EvalContext *ctx, char *tree, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool DeleteAttributeInNode(EvalContext *ctx, char *attrname, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool SetAttributeInNode(EvalContext *ctx, char *attrname, char *attrvalue, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool DeleteTextInNode(EvalContext *ctx, char *tree, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool SetTextInNode(EvalContext *ctx, char *tree, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool InsertTextInNode(EvalContext *ctx, char *tree, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool SanityCheckXPathBuild(EvalContext *ctx, const Attributes *a, const Promise *pp, PromiseResult *result); static bool SanityCheckTreeDeletions(const Attributes *a); static bool SanityCheckTreeInsertions(const Attributes *a, EditContext *edcontext); static bool SanityCheckAttributeDeletions(const Attributes *a); static bool SanityCheckAttributeSet(const Attributes *a); static bool SanityCheckTextDeletions(const Attributes *a); static bool SanityCheckTextSet(const Attributes *a); static bool SanityCheckTextInsertions(const Attributes *a); static bool XmlDocsEqualMem(xmlDocPtr doc1, xmlDocPtr doc2); static bool XmlNodesCompare(xmlNodePtr node1, xmlNodePtr node2, const Attributes *a, const Promise *pp); static bool XmlNodesCompareAttributes(xmlNodePtr node1, xmlNodePtr node2); static bool XmlNodesCompareNodes(xmlNodePtr node1, xmlNodePtr node2, const Attributes *a, const Promise *pp); static bool XmlNodesCompareTags(const xmlNodePtr node1, const xmlNodePtr node2); static bool XmlNodesCompareText(xmlNodePtr node1, xmlNodePtr node2); static bool XmlNodesSubset(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp); static bool XmlNodesSubsetOfAttributes(const xmlNodePtr node1, const xmlNodePtr node2); static bool XmlNodesSubsetOfNodes(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp); static bool XmlNodesSubstringOfText(const xmlNodePtr node1, const xmlNodePtr node2); static xmlAttrPtr XmlVerifyAttributeInNode(const xmlChar *attrname, xmlChar *attrvalue, xmlNodePtr node); static bool XmlVerifyTextInNodeExact(const xmlChar *text, const xmlNodePtr node); static bool XmlVerifyTextInNodeSubstring(const xmlChar *text, xmlNodePtr node); static bool XmlVerifyNodeInNodeExact(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp); static xmlNodePtr XmlVerifyNodeInNodeSubset(xmlNodePtr node1, xmlNodePtr node2, const Attributes *a, const Promise *pp); //xpath build functionality static xmlNodePtr PredicateExtractNode(char predicate[CF_BUFSIZE]); static bool PredicateRemoveHead(char xpath[CF_BUFSIZE]); static xmlNodePtr XPathHeadExtractNode(EvalContext *ctx, char xpath[CF_BUFSIZE], const Attributes *a, const Promise *pp, PromiseResult *result); static xmlNodePtr XPathTailExtractNode(EvalContext *ctx, char xpath[CF_BUFSIZE], const Attributes *a, const Promise *pp, PromiseResult *result); static xmlNodePtr XPathSegmentExtractNode(char segment[CF_BUFSIZE]); static char* XPathGetTail(char xpath[CF_BUFSIZE]); static bool XPathRemoveHead(char xpath[CF_BUFSIZE]); static bool XPathRemoveTail(char xpath[CF_BUFSIZE]); //verification using PCRE - ContainsRegex static bool PredicateHasTail(char *predicate); static bool PredicateHeadContainsAttribute(char *predicate); static bool PredicateHeadContainsNode(char *predicate); static bool XPathHasTail(char *head); static bool XPathHeadContainsNode(char *head); static bool XPathHeadContainsPredicate(char *head); static bool XPathVerifyBuildSyntax(EvalContext *ctx, const char* xpath, const Attributes *a, const Promise *pp, PromiseResult *result); static bool XPathVerifyConvergence(const char* xpath); //helper functions static xmlChar *CharToXmlChar(char c[CF_BUFSIZE]); static bool ContainsRegex(const char* rawstring, const char* regex); static int XmlAttributeCount(const xmlNodePtr node); #endif /*****************************************************************************/ /* Level */ /*****************************************************************************/ bool ScheduleEditXmlOperations(EvalContext *ctx, const Bundle *bp, const Attributes *a, const Promise *parentp, EditContext *edcontext) { assert(a != NULL); enum editxmltypesequence type; char lockname[CF_BUFSIZE]; CfLock thislock; int pass; snprintf(lockname, CF_BUFSIZE - 1, "masterfilelock-%s", edcontext->filename); const int ifelapsed = a->transaction.ifelapsed; const int expireafter = a->transaction.expireafter; thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, ifelapsed, expireafter, parentp, true); if (thislock.lock == NULL) { return false; } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_EDIT, "filename", edcontext->filename, CF_DATA_TYPE_STRING, "source=promise"); for (pass = 1; pass < CF_DONEPASSES; pass++) { for (type = 0; EDITXMLTYPESEQUENCE[type] != NULL; type++) { const BundleSection *sp = BundleGetSection(bp, EDITXMLTYPESEQUENCE[type]); if (!sp) { continue; } EvalContextStackPushBundleSectionFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepEditXmlPromise, edcontext); if (BundleAbort(ctx)) { YieldCurrentLock(thislock); EvalContextStackPopFrame(ctx); return false; } } EvalContextStackPopFrame(ctx); } } YieldCurrentLock(thislock); return true; } /***************************************************************************/ /* Level */ /***************************************************************************/ static PromiseResult KeepEditXmlPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { PromiseBanner(ctx, pp); if (strcmp("classes", PromiseGetPromiseType(pp)) == 0) { return VerifyClassPromise(ctx, pp, NULL); } else if (strcmp("build_xpath", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetInsertionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = PROMISE_RESULT_NOOP; VerifyXPathBuild(ctx, &a, pp, edcontext, &result); switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the build_xpath promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "build_xpath promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating build_xpath promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating build_xpath promise '%s'", pp->promiser); break; } return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2."); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("delete_tree", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetDeletionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = VerifyTreeDeletions(ctx, &a, pp, edcontext); return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2"); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("insert_tree", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetInsertionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = VerifyTreeInsertions(ctx, &a, pp, edcontext); return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2"); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("delete_attribute", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetDeletionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = VerifyAttributeDeletions(ctx, &a, pp, edcontext); return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2"); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("set_attribute", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetInsertionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = VerifyAttributeSet(ctx, &a, pp, edcontext); return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2"); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("delete_text", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetDeletionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = VerifyTextDeletions(ctx, &a, pp, edcontext); return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2"); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("set_text", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetInsertionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = VerifyTextSet(ctx, &a, pp, edcontext); return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2"); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("insert_text", PromiseGetPromiseType(pp)) == 0) { Attributes a = GetInsertionAttributes(ctx, pp); #ifdef HAVE_LIBXML2 EditContext *edcontext = param; PromiseResult result = VerifyTextInsertions(ctx, &a, pp, edcontext); return result; #else cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Cannot edit XML files without LIBXML2"); return PROMISE_RESULT_FAIL; #endif } else if (strcmp("reports", PromiseGetPromiseType(pp)) == 0) { return VerifyReportPromise(ctx, pp); } return PROMISE_RESULT_NOOP; } /***************************************************************************/ #ifdef HAVE_LIBXML2 /***************************************************************************/ static bool VerifyXPathBuild(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; CfLock thislock; char lockname[CF_BUFSIZE], rawxpath[CF_BUFSIZE] = { 0 }; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; if (a.xml.havebuildxpath) { strcpy(rawxpath, a.xml.build_xpath); } else { strcpy(rawxpath, pp->promiser); } if (!SanityCheckXPathBuild(ctx, &a, pp, result)) { RecordFailure(ctx, pp, &a, "The promised XPath build '%s' breaks its own promises", rawxpath); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if ((doc = edcontext->xmldoc) == NULL) { RecordFailure(ctx, pp, &a, "Unable to load XML document '%s'", edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } snprintf(lockname, CF_BUFSIZE - 1, "buildxpath-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return false; } //build XPath in an empty file if (!xmlDocGetRootElement(doc)) { if (BuildXPathInFile(ctx, rawxpath, doc, &a, pp, edcontext, result)) { (edcontext->num_edits)++; } } //build XPath in a nonempty file else if (BuildXPathInNode(ctx, rawxpath, doc, &a, pp, edcontext, result)) { (edcontext->num_edits)++; } YieldCurrentLock(thislock); return true; } /***************************************************************************/ static PromiseResult VerifyTreeDeletions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; xmlNodePtr docnode = NULL; CfLock thislock; char lockname[CF_BUFSIZE]; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; if (!SanityCheckTreeDeletions(&a)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "The promised tree deletion '%s' is inconsistent", pp->promiser); return PROMISE_RESULT_FAIL; } PromiseResult result = PROMISE_RESULT_NOOP; if (a.xml.havebuildxpath && !VerifyXPathBuild(ctx, &a, pp, edcontext, &result)) { return result; } if ((doc = edcontext->xmldoc) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Unable to load XML document"); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (!XmlSelectNode(ctx, a.xml.select_xpath, doc, &docnode, &a, pp, edcontext, &result)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "The promised XPath pattern '%s', was NOT successful when selecting an edit node, in XML document '%s)", a.xml.select_xpath, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } snprintf(lockname, CF_BUFSIZE - 1, "deletetree-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return result; } if (DeleteTreeInNode(ctx, pp->promiser, doc, docnode, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the delete_tree promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "delete_tree promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating delete_tree promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating delete_tree promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyTreeInsertions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; xmlNodePtr docnode = NULL; CfLock thislock; char lockname[CF_BUFSIZE]; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; PromiseResult result = PROMISE_RESULT_NOOP; if (!SanityCheckTreeInsertions(&a, edcontext)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "The promised tree insertion '%s' breaks its own promises", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (a.xml.havebuildxpath && !VerifyXPathBuild(ctx, &a, pp, edcontext, &result)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Failed to build XPath for tree insertion '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if ((doc = edcontext->xmldoc) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Unable to load XML document '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } //if file is not empty: select an edit node, for tree insertion if (a.xml.haveselectxpath && !XmlSelectNode(ctx, a.xml.select_xpath, doc, &docnode, &a, pp, edcontext, &result)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Failed to select edit node in the XML document '%s' using the XPath '%s'", edcontext->filename, a.xml.select_xpath); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } snprintf(lockname, CF_BUFSIZE - 1, "inserttree-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return result; } //insert tree into empty file or selected node if (!a.xml.haveselectxpath) { if (InsertTreeInFile(ctx, pp->promiser, doc, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } } else if (InsertTreeInNode(ctx, pp->promiser, doc, docnode, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the insert_tree promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "insert_tree promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating insert_tree promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating insert_tree promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyAttributeDeletions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; xmlNodePtr docnode = NULL; CfLock thislock; char lockname[CF_BUFSIZE]; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; PromiseResult result = PROMISE_RESULT_NOOP; if (!SanityCheckAttributeDeletions(&a)) { RecordFailure(ctx, pp, &a, "The promised attribute deletion '%s', is inconsistent", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (a.xml.havebuildxpath && !VerifyXPathBuild(ctx, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "Failed to build XPath for attribute deletion '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if ((doc = edcontext->xmldoc) == NULL) { RecordFailure(ctx, pp, &a, "Unable to load XML document '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (!XmlSelectNode(ctx, a.xml.select_xpath, doc, &docnode, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "The promised XPath pattern '%s', was NOT successful when selecting an edit node, in XML document '%s'", a.xml.select_xpath, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } snprintf(lockname, CF_BUFSIZE - 1, "deleteattribute-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return result; } if (DeleteAttributeInNode(ctx, pp->promiser, docnode, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the delete_attribute promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "delete_attribute promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating delete_attribute promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating delete_attribute promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyAttributeSet(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; xmlNodePtr docnode = NULL; CfLock thislock; char lockname[CF_BUFSIZE]; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; PromiseResult result = PROMISE_RESULT_NOOP; if (!SanityCheckAttributeSet(&a)) { RecordFailure(ctx, pp, &a, "The promised attribute set '%s', breaks its own promises", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (a.xml.havebuildxpath && !VerifyXPathBuild(ctx, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "Failed to build XPath for setting attribute '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if ((doc = edcontext->xmldoc) == NULL) { RecordFailure(ctx, pp, &a, "Unable to load XML document '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (!XmlSelectNode(ctx, a.xml.select_xpath, doc, &docnode, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "No node to edit selected by XPath '%s' in the XML document '%s'", a.xml.select_xpath, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } snprintf(lockname, CF_BUFSIZE - 1, "setattribute-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return result; } if (SetAttributeInNode(ctx, pp->promiser, a.xml.attribute_value, docnode, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the set_attribute promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "set_attribute promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating set_attribute promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating set_attribute promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyTextDeletions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; xmlNodePtr docnode = NULL; CfLock thislock; char lockname[CF_BUFSIZE]; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; PromiseResult result = PROMISE_RESULT_NOOP; if (!SanityCheckTextDeletions(&a)) { RecordFailure(ctx, pp, &a, "The promised text deletion '%s' is inconsistent", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (a.xml.havebuildxpath && !VerifyXPathBuild(ctx, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "Failed to build XPath for text deletion in '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if ((doc = edcontext->xmldoc) == NULL) { RecordFailure(ctx, pp, &a, "Unable to load XML document '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (!XmlSelectNode(ctx, a.xml.select_xpath, doc, &docnode, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "No node selected by XPath '%s' in XML document '%s'", a.xml.select_xpath, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } snprintf(lockname, CF_BUFSIZE - 1, "deletetext-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return result; } if (DeleteTextInNode(ctx, pp->promiser, doc, docnode, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the delete_text promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "delete_text promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating delete_text promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating delete_text promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyTextSet(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; xmlNodePtr docnode = NULL; CfLock thislock; char lockname[CF_BUFSIZE]; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; PromiseResult result = PROMISE_RESULT_NOOP; if (!SanityCheckTextSet(&a)) { RecordFailure(ctx, pp, &a, "The promised text set '%s' breaks its own promises", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (a.xml.havebuildxpath && !VerifyXPathBuild(ctx, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "Failed to build XPath for changing text in '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if ((doc = edcontext->xmldoc) == NULL) { RecordFailure(ctx, pp, &a, "Unable to load XML document '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (!XmlSelectNode(ctx, a.xml.select_xpath, doc, &docnode, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "No node selected by XPath '%s' in the XML document '%s'", a.xml.select_xpath, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } snprintf(lockname, CF_BUFSIZE - 1, "settext-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return result; } if (SetTextInNode(ctx, pp->promiser, doc, docnode, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the set_text promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "set_text promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating set_text promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating set_text promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyTextInsertions(EvalContext *ctx, const Attributes *attr, const Promise *pp, EditContext *edcontext) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this copy xmlDocPtr doc = NULL; xmlNodePtr docnode = NULL; CfLock thislock; char lockname[CF_BUFSIZE]; a.transaction.ifelapsed = CF_EDIT_IFELAPSED; PromiseResult result = PROMISE_RESULT_NOOP; if (!SanityCheckTextInsertions(&a)) { RecordFailure(ctx, pp, &a, "The promised text insertion '%s' breaks its own promises", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (a.xml.havebuildxpath && !VerifyXPathBuild(ctx, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "Failed to build XPath for text insertion into '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if ((doc = edcontext->xmldoc) == NULL) { RecordFailure(ctx, pp, &a, "Unable to load XML document '%s'", edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (!XmlSelectNode(ctx, a.xml.select_xpath, doc, &docnode, &a, pp, edcontext, &result)) { RecordFailure(ctx, pp, &a, "No node selected by XPath '%s' in XML document '%s'", a.xml.select_xpath, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } snprintf(lockname, CF_BUFSIZE - 1, "inserttext-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return result; } if (InsertTextInNode(ctx, pp->promiser, doc, docnode, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the insert_text promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "insert_text promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating insert_text promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating insert_text promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ /* This should provide pointers to the edit node within the XML document. It returns true if a match was identified, else false. If no such node matches, docnode should point to NULL */ static bool XmlSelectNode(EvalContext *ctx, char *rawxpath, xmlDocPtr doc, xmlNodePtr *docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); xmlNodePtr cur = NULL; xmlXPathContextPtr xpathCtx = NULL; xmlXPathObjectPtr xpathObj = NULL; xmlNodeSetPtr nodes = NULL; const xmlChar* xpathExpr = NULL; int i, size = 0; bool valid = true; *docnode = NULL; if (!XPathVerifyConvergence(rawxpath)) { RecordFailure(ctx, pp, a, "select_xpath expression '%s', is NOT convergent", rawxpath); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if ((xpathExpr = CharToXmlChar(rawxpath)) == NULL) { RecordFailure(ctx, pp, a, "Unable to create new XPath expression"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if ((xpathCtx = xmlXPathNewContext(doc)) == NULL) { RecordFailure(ctx, pp, a, "Unable to create new XPath context '%s'", rawxpath); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if ((xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx)) == NULL) { RecordFailure(ctx, pp, a, "Unable to evaluate XPath expression '%s'", xpathExpr); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); xmlXPathFreeContext(xpathCtx); return false; } nodes = xpathObj->nodesetval; if ((size = nodes ? nodes->nodeNr : 0) == 0) { valid = false; } if (size > 1) { RecordFailure(ctx, pp, a, "Current select_xpath expression '%s' returns %d edit nodes in XML document '%s'," " unique edit node required", xpathExpr, size, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); valid = false; } //select first matching node if (valid) { for (i = 0; i < size; ++i) { if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { cur = nodes->nodeTab[i]; break; } } if (cur == NULL) { RecordFailure(ctx, pp, a, "The promised XPath pattern '%s' was NOT found when selecting an edit node in XML document '%s'", xpathExpr, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); valid = false; } } *docnode = cur; xmlXPathFreeContext(xpathCtx); xmlXPathFreeObject(xpathObj); return valid; } /***************************************************************************/ static bool BuildXPathInFile(EvalContext *ctx, char rawxpath[CF_BUFSIZE], xmlDocPtr doc, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); xmlNodePtr docnode = NULL, head = NULL; char copyxpath[CF_BUFSIZE] = { 0 }; strcpy(copyxpath, rawxpath); if (xmlDocGetRootElement(doc)) { RecordNoChange(ctx, pp, a, "The promised XML document '%s' already exists and contains a root element", edcontext->filename); return false; } //set rootnode if ((docnode = XPathHeadExtractNode(ctx, copyxpath, a, pp, result)) == NULL) { RecordFailure(ctx, pp, a, "Unable to extract root node from XPath '%s', to be inserted into an empty XML document '%s'", rawxpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (docnode == NULL || (docnode->name) == NULL) { RecordFailure(ctx, pp, a, "The extracted root node, from XPath '%s', to be inserted into an empty XML document '%s', is empty", rawxpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (!MakingChanges(ctx, pp, a, result, "build XPath '%s' into an empty XML document '%s'", rawxpath, edcontext->filename)) { return false; } //insert the content into new XML document, beginning from root node if (xmlDocSetRootElement(doc, docnode) != NULL) { RecordFailure(ctx, pp, a, "The promised XPath '%s' was not built successfully into an empty XML document '%s'", rawxpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } XPathRemoveHead(copyxpath); //extract and insert nodes from tail while ((strlen(copyxpath) > 0) && ((head = XPathHeadExtractNode(ctx, copyxpath, a, pp, result)) != NULL)) { xmlAddChild(docnode, head); docnode = head; XPathRemoveHead(copyxpath); } RecordChange(ctx, pp, a, "Built XPath '%s' into an empty XML document '%s'", rawxpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool BuildXPathInNode(EvalContext *ctx, char rawxpath[CF_BUFSIZE], xmlDocPtr doc, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlNodePtr docnode = NULL, head = NULL, tail = NULL; char copyxpath[CF_BUFSIZE] = { 0 }; strcpy(copyxpath, rawxpath); //build XPath from tail while locating insertion node while ((strlen(copyxpath) > 0) && (!XmlSelectNode(ctx, copyxpath, doc, &docnode, a, pp, edcontext, result))) { if (XPathHasTail (copyxpath)) { head = XPathTailExtractNode(ctx, copyxpath, a, pp, result); XPathRemoveTail(copyxpath); } else { head = XPathHeadExtractNode(ctx, copyxpath, a, pp, result); XPathRemoveHead(copyxpath); } if (head && tail) { xmlAddChild(head, tail); } tail = head; } if (!MakingChanges(ctx, pp, a, result, "build XPath '%s' in XML document '%s'", rawxpath, edcontext->filename)) { return false; } //insert the new tree into selected node in XML document if (docnode != NULL) { xmlAddChild(docnode, tail); } //insert the new tree into root, in the case where unique node was not found, in XML document else { docnode = xmlDocGetRootElement(doc); xmlAddChild(docnode, tail); } RecordChange(ctx, pp, a, "Built XPath '%s' in XML document '%s'", rawxpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool InsertTreeInFile(EvalContext *ctx, char *rawtree, xmlDocPtr doc, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlNodePtr treenode = NULL, rootnode = NULL; xmlChar *buf = NULL; //for parsing subtree from memory if ((buf = CharToXmlChar(rawtree)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load tree (to be inserted into the XML document '%s') into a buffer", edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //parse the subtree if (xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, buf, &treenode) != 0) { RecordFailure(ctx, pp, a, "Failed to parse the tree '%s' (to be inserted into the XML document '%s')", rawtree, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (treenode == NULL || (treenode->name) == NULL) { RecordFailure(ctx, pp, a, "The tree '%s' (to be inserted into the XML document '%s') is empty", rawtree, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify treenode does not already exist inside docnode if ((rootnode = xmlDocGetRootElement(doc)) != NULL) { if (!XmlNodesCompare(treenode, rootnode, a, pp)) { RecordFailure(ctx, pp, a, "The tree '%s' requested to be inserted into the XML document '%s'," " however XML document is not empty and tree to be inserted does not match existing content", rawtree, edcontext->filename); Log(LOG_LEVEL_NOTICE, "Specify select_xpath expression insert into a non-empty XML document"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { RecordNoChange(ctx, pp, a, "The promised XML document '%s' already exists and contains the correct root element", edcontext->filename); } return false; } if (!MakingChanges(ctx, pp, a, result, "insert the promised tree '%s' into an empty XML document '%s'", rawtree, edcontext->filename)) { return true; } //insert the content into new XML document if (xmlDocSetRootElement(doc, treenode) != NULL) { Log(LOG_LEVEL_VERBOSE, "Failed to set root element of '%s'", edcontext->filename); RecordFailure(ctx, pp, a, "Failed to insert the tree '%s' into an empty XML document '%s'", rawtree, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify node was inserted if (((rootnode = xmlDocGetRootElement(doc)) == NULL) || !XmlNodesCompare(treenode, rootnode, a, pp)) { if (rootnode == NULL) { Log(LOG_LEVEL_VERBOSE, "No root element in '%s'", edcontext->filename); } else { Log(LOG_LEVEL_VERBOSE, "Wrong root element in '%s'", edcontext->filename); } RecordFailure(ctx, pp, a, "Failed to insert the tree '%s' into an empty XML document '%s'", rawtree, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, a, "Inserted tree '%s' into an empty XML document '%s'", rawtree, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool DeleteTreeInNode(EvalContext *ctx, char *rawtree, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { //for parsing subtree from memory const xmlChar *buf = CharToXmlChar(rawtree); if (!buf) { RecordFailure(ctx, pp, a, "Failed to load tree (to be deleted at XPath '%s' in XML document '%s')" " into an XML buffer", a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //parse the subtree xmlNodePtr treenode = NULL; if (xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, buf, &treenode) != 0) { RecordFailure(ctx, pp, a, "Tree to be deleted '%s' at XPath '%s' in XML document '%s'" " was not parsed successfully", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); xmlFreeNode(treenode); return false; } //verify treenode exists inside docnode xmlNodePtr deletetree = NULL; if ((deletetree = XmlVerifyNodeInNodeSubset(treenode, docnode, a, pp)) == NULL) { RecordNoChange(ctx, pp, a, "The promised tree to be deleted '%s' does not exist at XPath '%s' in XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename); xmlFreeNode(treenode); return false; } if (!MakingChanges(ctx, pp, a, result, "delete tree '%s' at XPath '%s' in XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename)) { xmlFreeNode(treenode); xmlFreeNode(deletetree); return false; } //remove the subtree from XML document xmlUnlinkNode(deletetree); xmlFreeNode(deletetree); //verify treenode no longer exists inside docnode xmlNodePtr ret = XmlVerifyNodeInNodeSubset(treenode, docnode, a, pp); if (ret != NULL) { RecordFailure(ctx, pp, a, "Failed to delete tree '%s' at XPath '%s' in XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); xmlFreeNode(treenode); xmlFreeNode(ret); return false; } else { RecordChange(ctx, pp, a, "Deleted tree '%s' at XPath '%s' in XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); xmlFreeNode(treenode); return true; } } /***************************************************************************/ static bool InsertTreeInNode(EvalContext *ctx, char *rawtree, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlNodePtr treenode = NULL; xmlChar *buf = NULL; //for parsing subtree from memory if ((buf = CharToXmlChar(rawtree)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load the tree (to be inserted at XPath '%s' in the XML document '%s') into a buffer", a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //parse the subtree if (xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, buf, &treenode) != 0) { RecordFailure(ctx, pp, a, "Failed to parse the tree '%s' (to be inserted at XPath '%s' in the XML document '%s')", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (treenode == NULL || (treenode->name) == NULL) { RecordFailure(ctx, pp, a, "The tree '%s' (to be inserted at XPath '%s' in XML document '%s') is empty", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify treenode does not already exist inside docnode if (XmlVerifyNodeInNodeSubset(treenode, docnode, a, pp)) { RecordNoChange(ctx, pp, a, "The tree '%s' already exists at XPath '%s' in XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename); return false; } if (!MakingChanges(ctx, pp, a, result, "insert tree '%s' at XPath '%s' in XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename)) { return false; } //insert the subtree into XML document if (!xmlAddChild(docnode, treenode)) { Log(LOG_LEVEL_VERBOSE, "Failed to add child node into '%s'", edcontext->filename); RecordFailure(ctx, pp, a, "Failed to insert tree '%s' at XPath '%s' into the XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify node was inserted if (!XmlVerifyNodeInNodeSubset(treenode, docnode, a, pp)) { Log(LOG_LEVEL_VERBOSE, "No matching node in '%s'", edcontext->filename); RecordFailure(ctx, pp, a, "Failed to insert tree '%s' at XPath '%s' into the XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, a, "Inserted tree '%s' at XPath '%s' in XML document '%s'", rawtree, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool DeleteAttributeInNode(EvalContext *ctx, char *rawname, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlAttrPtr attr = NULL; xmlChar *name = NULL; if ((name = CharToXmlChar(rawname)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load the name of attribute (to be deleted at XPath '%s' in XML document '%s')" " into a buffer", a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify attribute exists inside docnode if ((attr = xmlHasProp(docnode, name)) == NULL) { RecordNoChange(ctx, pp, a, "Attribute '%s' (to be deleted at XPath '%s' in the XML document '%s') does not exist", rawname, a->xml.select_xpath, edcontext->filename); return false; } if (!MakingChanges(ctx, pp, a, result, "delete the attribute '%s' at XPath '%s' in the XML document '%s'", rawname, a->xml.select_xpath, edcontext->filename)) { return false; } //delete attribute from docnode if ((xmlRemoveProp(attr)) == -1) { Log(LOG_LEVEL_VERBOSE, "Failed to remove attribute '%s' at '%s' in '%s'", rawname, a->xml.select_xpath, edcontext->filename); RecordFailure(ctx, pp, a, "Failed to delete the attribute '%s' at XPath '%s' in the XML document '%s'.", rawname, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify attribute no longer exists inside docnode if ((attr = xmlHasProp(docnode, name)) != NULL) { Log(LOG_LEVEL_VERBOSE, "Attribute '%s' still present at '%s' in '%s'", rawname, a->xml.select_xpath, edcontext->filename); RecordFailure(ctx, pp, a, "Failed to delete the attribute '%s' at XPath '%s' in the XML document '%s'.", rawname, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, a, "Deleted attribute '%s' at XPath '%s' in the XML document '%s'", rawname, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool SetAttributeInNode(EvalContext *ctx, char *rawname, char *rawvalue, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlAttrPtr attr = NULL; xmlChar *name = NULL; xmlChar *value = NULL; if ((name = CharToXmlChar(rawname)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load the name of the attribute (to be set at XPath '%s' in XML document '%s')" "into a buffer", a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if ((value = CharToXmlChar(rawvalue)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load the value of the attribute '%s' (to be set at XPath '%s' in XML document '%s')" "into a buffer", rawname, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify attribute does not already exist inside docnode if ((attr = XmlVerifyAttributeInNode(name, value, docnode)) != NULL) { RecordNoChange(ctx, pp, a, "Attribute with name '%s' and value '%s' already exists at XPath '%s' in XML document '%s'", rawname, rawvalue, a->xml.select_xpath, edcontext->filename); return false; } if (!MakingChanges(ctx, pp, a, result, "set attribute with name '%s' to value '%s' at XPath '%s' in XML document '%s'", rawname, rawvalue, a->xml.select_xpath, edcontext->filename)) { return false; } //set attribute in docnode if ((attr = xmlSetProp(docnode, name, value)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Failed to set the value of the attribute '%s' to '%s' at '%s' in '%s'", rawname, rawvalue, a->xml.select_xpath, edcontext->filename); RecordFailure(ctx, pp, a, "Failed to set the attribute with name '%s' to value '%s' at XPath '%s' in XML document '%s'", rawname, rawvalue, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify attribute was inserted if ((attr = XmlVerifyAttributeInNode(name, value, docnode)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Attribute '%s' with value '%s' not present at '%s' in '%s'", rawname, rawvalue, a->xml.select_xpath, edcontext->filename); RecordFailure(ctx, pp, a, "Failed to set the attribute with name '%s' to value '%s' at XPath '%s' in XML document '%s'", rawname, rawvalue, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, a, "Set attribute with name '%s' to value '%s' at XPath '%s' in XML document '%s'", rawname, rawvalue, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool DeleteTextInNode(EvalContext *ctx, char *rawtext, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlNodePtr elemnode, copynode; xmlChar *text = NULL; if ((text = CharToXmlChar(rawtext)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load the text to be deleted at XPath '%s' in XML document '%s' into a buffer", a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify text exists inside docnode if (!XmlVerifyTextInNodeSubstring(text, docnode)) { RecordNoChange(ctx, pp, a, "Text '%s' does not exist at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); return false; } if (!MakingChanges(ctx, pp, a, result, "delete text '%s' at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename)) { return false; } //delete text from docnode if (xmlNodeIsText(docnode->children)) { //node contains text xmlNodeSetContent(docnode->children, ""); } else { //node does not contain text //remove and set aside the elements in the node elemnode = xmlFirstElementChild(docnode); copynode = xmlDocCopyNodeList(doc, elemnode); xmlNodeSetContent(docnode, ""); //re-insert elements after the inserted text xmlAddChildList(docnode, copynode); } //verify text no longer exists inside docnode if (XmlVerifyTextInNodeSubstring(text, docnode)) { RecordFailure(ctx, pp, a, "Failed to delete text '%s' at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, a, "Deleted text '%s' at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool SetTextInNode(EvalContext *ctx, char *rawtext, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlNodePtr elemnode, copynode; xmlChar *text = NULL; if ((text = CharToXmlChar(rawtext)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load the text to be set at XPath '%s' in XML document '%s' into a buffer", a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify text does not exist inside docnode if (XmlVerifyTextInNodeExact(text, docnode)) { RecordNoChange(ctx, pp, a, "Text '%s' already exists at XPath '%s' in XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); return false; } if (!MakingChanges(ctx, pp, a, result, "set text '%s' at XPath '%s' in XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename)) { return true; } //set text in docnode if (xmlNodeIsText(docnode->children)) { //node already contains text xmlNodeSetContent(docnode->children, text); } else { //node does not contain text //remove and set aside the elements in the node elemnode = xmlFirstElementChild(docnode); copynode = xmlDocCopyNodeList(doc, elemnode); xmlNodeSetContent(docnode, text); //re-insert elements after the inserted text xmlAddChildList(docnode, copynode); } //verify text was inserted if (!XmlVerifyTextInNodeExact(text, docnode)) { RecordFailure(ctx, pp, a, "Failed to set text '%s' at XPath '%s' in XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, a, "Set text '%s' at XPath '%s' in XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool InsertTextInNode(EvalContext *ctx, char *rawtext, xmlDocPtr doc, xmlNodePtr docnode, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { xmlNodePtr elemnode, copynode; xmlChar *text = NULL; if ((text = CharToXmlChar(rawtext)) == NULL) { RecordFailure(ctx, pp, a, "Failed to load text to be inserted at XPath '%s' in XML document '%s' into a buffer", a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } //verify text does not exist inside docnode if (XmlVerifyTextInNodeSubstring(text, docnode)) { RecordNoChange(ctx, pp, a, "Text '%s' already exists at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); return false; } if (!MakingChanges(ctx, pp, a, result, "insert text '%s' at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename)) { return false; } //insert text into docnode if (xmlNodeIsText(docnode->children)) { //node already contains text xmlNodeAddContent(docnode->children, text); } else { //node does not contain text //remove and set aside the elements in the node elemnode = xmlFirstElementChild(docnode); copynode = xmlDocCopyNodeList(doc, elemnode); xmlNodeSetContent(docnode, ""); xmlNodeAddContent(docnode, text); //re-insert elements after the inserted text xmlAddChildList(docnode, copynode); } //verify text was inserted if (!XmlVerifyTextInNodeSubstring(text, docnode)) { RecordFailure(ctx, pp, a, "Failed to insert text '%s' at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, a, "Inserted text '%s' at XPath '%s' in the XML document '%s'", rawtext, a->xml.select_xpath, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } /***************************************************************************/ static bool SanityCheckXPathBuild(EvalContext *ctx, const Attributes *a, const Promise *pp, PromiseResult *result) { char rawxpath[CF_BUFSIZE] = { 0 }; if (a->xml.havebuildxpath) { strcpy(rawxpath, a->xml.build_xpath); } else { strcpy(rawxpath, pp->promiser); } if ((strcmp("build_xpath", PromiseGetPromiseType(pp)) == 0) && (a->xml.havebuildxpath)) { Log(LOG_LEVEL_ERR, "Attribute: build_xpath is not allowed within bundle: build_xpath"); return false; } if (a->xml.haveselectxpath && !a->xml.havebuildxpath) { Log(LOG_LEVEL_ERR, "XPath build does not require select_xpath to be specified"); return false; } if (!XPathVerifyBuildSyntax(ctx, rawxpath, a, pp, result)) { return false; } return true; } /***************************************************************************/ static bool SanityCheckTreeDeletions(const Attributes *a) { assert(a != NULL); if (!a->xml.haveselectxpath) { Log(LOG_LEVEL_ERR, "Tree deletion requires select_xpath to be specified"); return false; } if (!XPathVerifyConvergence(a->xml.select_xpath)) { return false; } return true; } /***************************************************************************/ static bool SanityCheckTreeInsertions(const Attributes *a, EditContext *edcontext) { assert(a != NULL); if ((a->xml.haveselectxpath && !a->xml.havebuildxpath && !xmlDocGetRootElement(edcontext->xmldoc))) { Log(LOG_LEVEL_ERR, "Tree insertion into an empty file, using select_xpath, does not make sense"); return false; } else if ((!a->xml.haveselectxpath && a->xml.havebuildxpath)) { Log(LOG_LEVEL_ERR, "Tree insertion requires select_xpath to be specified, unless inserting into an empty file"); return false; } if (a->xml.haveselectxpath && !XPathVerifyConvergence(a->xml.select_xpath)) { return false; } return true; } /***************************************************************************/ static bool SanityCheckAttributeDeletions(const Attributes *a) { assert(a != NULL); if (!(a->xml.haveselectxpath)) { Log(LOG_LEVEL_ERR, "Attribute deletion requires select_xpath to be specified"); return false; } if (!XPathVerifyConvergence(a->xml.select_xpath)) { return false; } return true; } /***************************************************************************/ static bool SanityCheckAttributeSet(const Attributes *a) { assert(a != NULL); if (!(a->xml.haveselectxpath)) { Log(LOG_LEVEL_ERR, "Attribute insertion requires select_xpath to be specified"); return false; } if (!XPathVerifyConvergence(a->xml.select_xpath)) { return false; } return true; } /***************************************************************************/ static bool SanityCheckTextDeletions(const Attributes *a) { assert(a != NULL); if (!(a->xml.haveselectxpath)) { Log(LOG_LEVEL_ERR, "Tree insertion requires select_xpath to be specified"); return false; } if (!XPathVerifyConvergence(a->xml.select_xpath)) { return false; } return true; } /***************************************************************************/ static bool SanityCheckTextSet(const Attributes *a) { assert(a != NULL); if (!(a->xml.haveselectxpath)) { Log(LOG_LEVEL_ERR, "Tree insertion requires select_xpath to be specified"); return false; } if (!XPathVerifyConvergence(a->xml.select_xpath)) { return false; } return true; } /***************************************************************************/ static bool SanityCheckTextInsertions(const Attributes *a) { assert(a != NULL); if (!(a->xml.haveselectxpath)) { Log(LOG_LEVEL_ERR, "Tree insertion requires select_xpath to be specified"); return false; } if (!XPathVerifyConvergence(a->xml.select_xpath)) { return false; } return true; } /***************************************************************************/ bool XmlCompareToFile(xmlDocPtr doc, char *file, EditDefaults edits) /* returns true if XML on disk is identical to XML in memory */ { struct stat statbuf; xmlDocPtr cmpdoc = NULL; if (stat(file, &statbuf) == -1) { return false; } if (doc == NULL && statbuf.st_size == 0) { return true; } if (doc == NULL) { return false; } if (!LoadFileAsXmlDoc(&cmpdoc, file, edits, false)) { return false; } if (!XmlDocsEqualMem(cmpdoc, doc)) { xmlFreeDoc(cmpdoc); return false; } xmlFreeDoc(cmpdoc); return true; } /*********************************************************************/ static bool XmlDocsEqualMem(xmlDocPtr doc1, xmlDocPtr doc2) { xmlChar *mem1; xmlChar *mem2; int memsize1; int memsize2; bool equal = true; if (!doc1 && !doc2) { return true; } if (!doc1 || !doc2) { return false; } xmlDocDumpMemory(doc1, &mem1, &memsize1); xmlDocDumpMemory(doc2, &mem2, &memsize2); if (!xmlStrEqual(mem1, mem2)) { equal = false; } xmlFree(mem1); xmlFree(mem2); return equal; } /***************************************************************************/ static bool XmlNodesCompare(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp) /* Does node1 contain all content(tag/attributes/text/nodes) found in node2? */ { bool compare = true; if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } if (!XmlNodesCompareTags(node1, node2)) { compare = false; } if (compare && !XmlNodesCompareAttributes(node1, node2)) { compare = false; } if (compare && !XmlNodesCompareText(node1, node2)) { compare = false; } if (compare && !XmlNodesCompareNodes(node1, node2, a, pp)) { compare = false; } return compare; } /*********************************************************************/ static bool XmlNodesCompareAttributes(const xmlNodePtr node1, const xmlNodePtr node2) /* Does node1 contain same attributes found in node2? */ { xmlAttrPtr attr1 = NULL; xmlAttrPtr attr2 = NULL; xmlChar *value = NULL; int count1, count2; bool compare = true; if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } if ((node1->properties) == NULL && (node2->properties) == NULL) { return true; } if ((node1->properties) == NULL || (node2->properties) == NULL) { return false; } count1 = XmlAttributeCount(node1); count2 = XmlAttributeCount(node2); if (count1 != count2) { return false; } //get attribute list from node1 and node2 attr1 = node1->properties; attr2 = node2->properties; //check that each attribute in node1 is in node2 while (attr1) { value = xmlNodeGetContent(attr1->children); if ((XmlVerifyAttributeInNode(attr1->name, value, node2)) == NULL) { xmlFree(value); compare = false; break; } xmlFree(value); attr1 = attr1->next; attr2 = attr2->next; } return compare; } /*********************************************************************/ static bool XmlNodesCompareNodes(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp) /* Does node1 contain same nodes found in node2? */ { if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } int count1 = xmlChildElementCount(node1); int count2 = xmlChildElementCount(node2); if (count1 != count2) { return false; } xmlNodePtr child1 = xmlFirstElementChild(node1); bool compare = true; while (child1 != NULL) { if (!XmlVerifyNodeInNodeExact(child1, node2, a, pp)) { compare = false; break; } child1 = xmlNextElementSibling(child1); } return compare; } /*********************************************************************/ static bool XmlNodesCompareTags(const xmlNodePtr node1, const xmlNodePtr node2) /* Does node1 contain same tag found in node2? */ { bool compare = true; if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } if ((node1->name) == NULL && (node2->name) == NULL) { return true; } if ((node1->name) == NULL || (node2->name) == NULL) { return false; } //check tag in node1 is the same as tag in node2 if (!xmlStrEqual(node1->name, node2->name)) { compare = false; } return compare; } /*********************************************************************/ static bool XmlNodesCompareText(xmlNodePtr node1, xmlNodePtr node2) /* Does node1 contain same text found in node2? */ { xmlChar *text1 = NULL, *text2 = NULL; if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } //get text from nodes text1 = xmlNodeGetContent(node1->children); text2 = xmlNodeGetContent(node2->children); if (!text1 && !text2) { return true; } if (!text2) { return false; } //check text in node1 is the same as text in node2 if (!xmlStrEqual(text1, text2)) { return false; } return true; } /*********************************************************************/ static bool XmlNodesSubset(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp) /* Does node1 contain matching subset of content(tag/attributes/text/nodes) found in node2? */ { bool subset = true; if (!node1 && !node2) { return true; } if (!node2) { return false; } if (!XmlNodesCompareTags(node1, node2)) { subset = false; } if (subset && !XmlNodesSubsetOfAttributes(node1, node2)) { subset = false; } if (subset && !XmlNodesSubstringOfText(node1, node2)) { subset = false; } if (subset && !XmlNodesSubsetOfNodes(node1, node2, a, pp)) { subset = false; } return subset; } /*********************************************************************/ static bool XmlNodesSubsetOfAttributes(const xmlNodePtr node1, const xmlNodePtr node2) /* Does node1 contain matching subset of attributes found in node2? */ { xmlAttrPtr attr1 = NULL; bool subset = true; if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } if ((node1->properties) == NULL && (node2->properties) == NULL) { return true; } if ((node2->properties) == NULL) { return false; } //get attribute list from node1 attr1 = node1->properties; //check that each attribute in node1 is in node2 while (attr1) { xmlChar *value = xmlNodeGetContent(attr1->children); if ((XmlVerifyAttributeInNode(attr1->name, value, node2)) == NULL) { subset = false; xmlFree(value); break; } attr1 = attr1->next; xmlFree(value); } return subset; } /*********************************************************************/ static bool XmlNodesSubsetOfNodes(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp) /* Does node1 contain matching subset of nodes found in node2? */ { if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } //get node list from node1 and node2 xmlNodePtr child1 = xmlFirstElementChild(node1); bool subset = true; while (child1 != NULL) { if (!XmlVerifyNodeInNodeExact(child1, node2, a, pp)) { subset = false; break; } child1 = xmlNextElementSibling(child1); } return subset; } /*********************************************************************/ static bool XmlNodesSubstringOfText(const xmlNodePtr node1, const xmlNodePtr node2) /* Does node1 contain matching substring of text found in node2? */ { if (!node1 && !node2) { return true; } if (!node1 || !node2) { return false; } xmlChar *text1 = xmlNodeGetContent(node1->children); if (!text1) { return true; } xmlChar *text2 = xmlNodeGetContent(node2->children); if (!text2) { xmlFree(text1); return false; } if (!xmlStrstr(text2, text1)) { xmlFree(text1); xmlFree(text2); return false; } xmlFree(text1); xmlFree(text2); return true; } /*********************************************************************/ xmlAttrPtr XmlVerifyAttributeInNode(const xmlChar *name, xmlChar *value, const xmlNodePtr node) /* Does node contain an attribute with given name and value? Returns a pointer to attribute found in node or NULL */ { xmlAttrPtr attr2 = NULL; xmlChar *value2 = NULL; if ((node == NULL) || (name == NULL) || (node->properties == NULL)) { return NULL; } //get attribute with matching name from node, if it exists if ((attr2 = xmlHasProp(node, name)) == NULL) { return NULL; } //compare values value2 = xmlNodeGetContent(attr2->children); if (!xmlStrEqual(value, value2)) { xmlFree(value2); return NULL; } xmlFree(value2); return attr2; } /*********************************************************************/ bool XmlVerifyTextInNodeExact(const xmlChar *text, const xmlNodePtr node) /* Does node contain: text content exactly matching the givin string text? Returns a pointer to text content in node or NULL */ { if (node == NULL) { return false; } xmlChar *text2 = xmlNodeGetContent(node->children); if (!xmlStrEqual(text2, text)) { xmlFree(text2); return false; } xmlFree(text2); return true; } /*********************************************************************/ bool XmlVerifyTextInNodeSubstring(const xmlChar *text, xmlNodePtr node) /* Does node contain: text content, contains substring, matching the given string of text? Returns a pointer to text content in node or NULL */ { if (!node) { return false; } xmlChar *text2 = xmlNodeGetContent(node->children); if (!xmlStrstr(text2, text)) { xmlFree(text2); return false; } xmlFree(text2); return true; } /*********************************************************************/ static bool XmlVerifyNodeInNodeExact(const xmlNodePtr node1, const xmlNodePtr node2, const Attributes *a, const Promise *pp) /* Does node2 contain a node with content matching all content in node1? Returns a pointer to node found in node2 or NULL */ { if ((node1 == NULL) || (node2 == NULL)) { return false; } xmlNodePtr comparenode = xmlFirstElementChild(node2); while (comparenode != NULL) { if (XmlNodesCompare(node1, comparenode, a, pp)) { return true; } comparenode = xmlNextElementSibling(comparenode); } return false; } /*********************************************************************/ static xmlNodePtr XmlVerifyNodeInNodeSubset(xmlNodePtr node1, xmlNodePtr node2, const Attributes *a, const Promise *pp) /* Does node2 contain: node with subset of content matching all content in node1? Returns a pointer to node found in node2 or NULL */ { if ((node1 == NULL) || (node2 == NULL)) { return NULL; } xmlNodePtr comparenode = xmlFirstElementChild(node2); while (comparenode != NULL) { if (XmlNodesSubset(node1, comparenode, a, pp)) { return comparenode; } comparenode = xmlNextElementSibling(comparenode); } return NULL; } /*********************************************************************/ xmlNodePtr PredicateExtractNode(char predicate[CF_BUFSIZE]) { xmlNodePtr node = NULL; xmlChar *name = NULL; xmlChar *value = NULL; char rawname[CF_BUFSIZE] = { 0 }, rawvalue[CF_BUFSIZE] = { 0 }, *tok; char *running_start = xstrdup(predicate); char *running = running_start; //extract node name tok = strsep(&running, "| \"\'="); while (strcmp(tok, "") == 0) { tok = strsep(&running, "| \"\'="); } strcpy(rawname, tok); name = CharToXmlChar(rawname); //extract node value tok = strsep(&running, " \"\'="); while (strcmp(tok, "") == 0) { tok = strsep(&running, " \"\'="); } strcpy(rawvalue, tok); value = CharToXmlChar(rawvalue); //create a new node with name and value node = xmlNewNode(NULL, name); xmlNodeSetContent(node, value); free(running_start); return node; } /*********************************************************************/ static bool PredicateRemoveHead(char predicate[CF_BUFSIZE]) { char copypred[CF_BUFSIZE] = { 0 }, *tail = NULL; strcpy(copypred, predicate); memset(predicate, 0, sizeof(char)*CF_BUFSIZE); if (PredicateHasTail(copypred)) { tail = strchr(copypred+1, '|'); strcpy(predicate, tail); } return true; } /*********************************************************************/ static xmlNodePtr XPathHeadExtractNode(EvalContext *ctx, char xpath[CF_BUFSIZE], const Attributes *a, const Promise *pp, PromiseResult *result) { xmlNodePtr node = NULL; char head[CF_BUFSIZE] = {0}, *tok = NULL; char *running_start = xstrdup(xpath); char *running = running_start; //extract head substring from xpath tok = strsep(&running, "/"); while (strcmp(tok, "") == 0) { tok = strsep(&running, "/"); } strcpy(head, tok); if ((node = XPathSegmentExtractNode(head)) == NULL) { RecordFailure(ctx, pp, a, "Could not extract node '%s'", head); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } free(running_start); return node; } /*********************************************************************/ static xmlNodePtr XPathTailExtractNode(EvalContext *ctx, char xpath[CF_BUFSIZE], const Attributes *a, const Promise *pp, PromiseResult *result) { xmlNodePtr node = NULL; char copyxpath[CF_BUFSIZE] = {0}, tail[CF_BUFSIZE] = {0}, *tok = NULL; strcpy(copyxpath, xpath); //extract tail substring from xpath tok = XPathGetTail(copyxpath); strcpy(tail, tok); if ((node = XPathSegmentExtractNode(tail)) == NULL) { RecordFailure(ctx, pp, a, "Could not extract node '%s'", tail); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } return node; } /*********************************************************************/ static xmlNodePtr XPathSegmentExtractNode(char segment[CF_BUFSIZE]) { xmlNodePtr node = NULL, prednode = NULL; xmlChar *name = NULL, *attrname = NULL, *attrvalue = NULL; char predicate[CF_BUFSIZE] = { 0 }, rawname[CF_BUFSIZE] = { 0 }, rawvalue[CF_BUFSIZE] = { 0 }, *tok; int hasname = false; char *running_start = xstrdup(segment); char *running = running_start; //extract name and predicate substrings from segment if (XPathHeadContainsNode(segment)) { //extract node name tok = strsep(&running, " []"); while (strcmp(tok, "") == 0) { tok = strsep(&running, " []"); } strcpy(rawname, tok); name = CharToXmlChar(rawname); //create a new node with name node = xmlNewNode(NULL, name); hasname = true; } //extract attributes and nodes from predicate if (hasname && XPathHeadContainsPredicate(segment)) { //extract predicate tok = strsep(&running, "[]"); while (strcmp(tok, "") == 0) { tok = strsep(&running, "[]"); } strcpy(predicate, tok); while (strlen(predicate) > 0) { if (PredicateHeadContainsNode(predicate)) { //create a new node within node prednode = PredicateExtractNode(predicate); xmlAddChild(node, prednode); } else if (PredicateHeadContainsAttribute(predicate)) { char *running_start2 = xstrdup(predicate); char *running2 = running_start2; //extract attribute name tok = strsep(&running2, "| @\"\'="); while (strcmp(tok, "") == 0) { tok = strsep(&running2, "| @\"\'="); } strcpy(rawname, tok); attrname = CharToXmlChar(rawname); //extract attribute value tok = strsep(&running2, "| @\"\'="); while (strcmp(tok, "") == 0) { tok = strsep(&running2, "| @\"\'="); } strcpy(rawvalue, tok); attrvalue = CharToXmlChar(rawvalue); //create a new attribute within node xmlNewProp(node, attrname, attrvalue); free(running_start2); } if (PredicateHasTail(predicate)) { PredicateRemoveHead(predicate); } else { memset(predicate, 0, sizeof(char)*CF_BUFSIZE); } } } free(running_start); return node; } /*********************************************************************/ char* XPathGetTail(char xpath[CF_BUFSIZE]) { char tmpstr[CF_BUFSIZE] = {0}, *tok = NULL; char *running_start = xstrdup(xpath); char *running = running_start; memset(xpath, 0, sizeof(char)*CF_BUFSIZE); if (XPathHasTail(running)) { //extract and discard xpath head tok = strsep(&running, "/"); while (strcmp(tok, "") == 0) { tok = strsep(&running, "/"); } //extract xpath tail while ((tok = strsep(&running, "/")) != NULL) { while (strcmp(tok, "") == 0) { tok = strsep(&running, "/"); } if (tok) { strcpy(tmpstr, tok); } } strcpy(xpath, tmpstr); } free(running_start); return xpath; } /*********************************************************************/ static bool XPathRemoveHead(char xpath[CF_BUFSIZE]) { char copyxpath[CF_BUFSIZE] = { 0 }, *tail = NULL; strcpy(copyxpath, xpath); memset(xpath, 0, sizeof(char)*CF_BUFSIZE); if (XPathHasTail(copyxpath)) { tail = strchr(copyxpath+1, '/'); strcpy(xpath, tail); } return true; } /*********************************************************************/ static bool XPathRemoveTail(char xpath[CF_BUFSIZE]) { char copyxpath[CF_BUFSIZE] = { 0 }, *tail = NULL; int len = 0; strcpy(copyxpath, xpath); memset(xpath, 0, sizeof(char)*CF_BUFSIZE); if (XPathHasTail(copyxpath)) { tail = strrchr(copyxpath, '/'); len = tail-copyxpath; copyxpath[len] = '\0'; strcpy(xpath, copyxpath); } return true; } /*********************************************************************/ static bool PredicateHasTail(char *predicate) { const char *regexp = "^\\s*\\[?\\s*@?\\s*(\\w|-|\\.)+\\s*=\\s*(\"|\')?(\\w|-|\\.)+(\"|\')?\\s*\\|"; return (ContainsRegex(predicate, regexp)); } /*********************************************************************/ static bool PredicateHeadContainsAttribute(char *predicate) { const char *regexp = "^\\s*\\[?\\|?(\\s*@\\s*(\\w|-|\\.)+\\s*=\\s*(\"|\')?(\\w|-|\\.)+(\"|\')?)(\\s*(\\||\\]))?"; // i.e. @name='value' or @name = value or @name ="value" return (ContainsRegex(predicate, regexp)); } /*********************************************************************/ static bool PredicateHeadContainsNode(char *predicate) { const char *regexp = "^\\s*\\[?\\|?(\\s*(\\w|-|\\.)+\\s*=\\s*(\"|\')?(\\w|-|\\.)+(\"|\')?)(\\s*(\\||\\]))?"; // i.e. name='value' or name = value or name ="value" return (ContainsRegex(predicate, regexp)); } /*********************************************************************/ static bool XPathHasTail(char *head) { const char *regexp = "^\\s*\\/?\\s*(\\w|-|\\.)+(\\s*::\\s*(\\w|-|\\.)+\\s*)*\\s*(\\[[^\\[\\]\\/]*\\])?\\s*\\/"; return (ContainsRegex(head, regexp)); } /*********************************************************************/ static bool XPathHeadContainsNode(char *head) { const char *regexp = "^(\\/)?(\\w|-|\\.)+((\\s*::\\s*)?(\\w|-|\\.)+)*"; return (ContainsRegex(head, regexp)); } /*********************************************************************/ static bool XPathHeadContainsPredicate(char *head) { const char *regexp = "^\\s*\\/?\\s*(\\w|-|\\.)+(\\s*::\\s*(\\w|-|\\.)+)*\\s*\\" // name // [ name='value' | @name = "value" | name = value] "[\\s*@?\\s*(\\w|-|\\.)+\\s*=\\s*(\"|\')?(\\w|-|\\.)+(\"|\')?\\s*(\\s*\\|\\s*)?(\\s*@?\\s*(\\w|-|\\.)+\\s*=\\s*(\"|\')?(\\w|-|\\.)+(\"|\')?\\s*)*\\]"; return (ContainsRegex(head, regexp)); } /*********************************************************************/ static bool XPathVerifyBuildSyntax(EvalContext *ctx, const char* xpath, const Attributes *a, const Promise *pp, PromiseResult *result) /*verify that XPath does not specify position wrt sibling-axis (such as):[#] [last()] [position()] following-sibling:: preceding-sibling:: */ { char regexp[CF_BUFSIZE] = {'\0'}; //check for convergence if (!XPathVerifyConvergence(xpath)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "Promiser expression (%s) is not convergent", xpath); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return false; } // /name[ name = value | @name='value'| . . . | @name = "value" ]/. . . strcpy (regexp, "^(\\/(( |\\t)*(\\w|-|\\.)+( |\\t)*)" "(\\[( |\\t)*@?(\\w|-|\\.)+( |\\t)*=( |\\t)*(\'|\")?(\\w|-|\\.)+(\'|\")?( |\\t)*" "(\\|( |\\t)*@?(\\w|-|\\.)+( |\\t)*=( |\\t)*(\'|\")?(\\w|-|\\.)+(\'|\")?( |\\t)*)*\\])?)*$"); if (!ContainsRegex(xpath, regexp)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "Promiser expression '%s' contains syntax that is not supported for xpath_build. " "Please refer to users manual for supported syntax specifications.", xpath); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return false; } return true; } /*********************************************************************/ static bool XPathVerifyConvergence(const char* xpath) /*verify that XPath does not specify position wrt sibling-axis (such as):[#] [last()] [position()] following-sibling:: preceding-sibling:: */ { char regexp[CF_BUFSIZE] = {'\0'}; //check in predicate strcpy (regexp, "\\[\\s*([^\\[\\]]*\\s*(\\||(or)|(and)))?\\s*" // [ (stuff) (|/or/and) // position() (=/!=//>=) "((position)\\s*\\(\\s*\\)\\s*((=)|(!=)|(<)|(<=)|(>)|(>=))\\s*)?\\s*" // (number) | (number) (+/-/*/div/mod) (number) | last() | last() (+/-/*/div/mod) (number) "(((\\d+)\\s*|((last)\\s*\\(\\s*\\)\\s*))(((\\+)|(-)|(\\*)|(div)|(mod))\\s*(\\d+)\\s*)*)\\s*" // (|/or/and) (stuff) ] "((\\||(or)|(and))[^\\[\\]]*)?\\]" // following:: preceding:: following-sibling:: preceding-sibling:: "|((following)|(preceding))(-sibling)?\\s*(::)"); if (ContainsRegex(xpath, regexp)) { return false; } return true; } /*********************************************************************/ xmlChar *CharToXmlChar(char c[CF_BUFSIZE]) { return BAD_CAST c; } /*********************************************************************/ static bool ContainsRegex(const char* rawstring, const char* regex) { return StringMatch(regex, rawstring, NULL, NULL); } /*********************************************************************/ static int XmlAttributeCount(const xmlNodePtr node) { if (!node) { return 0; } xmlAttrPtr attr = node->properties; int count = 0; while (attr) { count++; attr = attr->next; } return count; } /*********************************************************************/ #endif cfengine-3.24.2/cf-agent/findhub_priv.h0000644000000000000000000000444115010704253017672 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FINDHUB_PRIV_H #define CFENGINE_FINDHUB_PRIV_H #include #include AvahiSimplePoll *spoll; typedef struct { char Hostname[4096]; char IPAddress[AVAHI_ADDRESS_STR_MAX]; uint16_t Port; } HostProperties; void resolve_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupFlags flags, void* userdata); void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata); void client_callback(AvahiClient *c, AvahiClientState state, void *userdata); #endif cfengine-3.24.2/cf-agent/verify_environments.h0000644000000000000000000000231615010704253021325 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_ENVIRONMENTS_H #define CFENGINE_VERIFY_ENVIRONMENTS_H void NewEnvironmentsContext(void); void DeleteEnvironmentsContext(void); PromiseResult VerifyEnvironmentsPromise(EvalContext *ctx, const Promise *pp); #endif cfengine-3.24.2/cf-agent/verify_acl.c0000644000000000000000000002763215010704253017340 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include // Valid operations (first char of mode) #define CF_VALID_OPS_METHOD_OVERWRITE "=+-" #define CF_VALID_OPS_METHOD_APPEND "=+-" static bool CheckACLSyntax(const char *file, Acl acl, const Promise *pp); static void SetACLDefaults(const char *path, Acl *acl); static bool CheckACESyntax(char *ace, char *valid_nperms, char *valid_ops, int deny_support, int mask_support, const Promise *pp); static bool CheckModeSyntax(char **mode_p, char *valid_nperms, char *valid_ops, const Promise *pp); static bool CheckPermTypeSyntax(char *permt, int deny_support, const Promise *pp); static int CheckAclDefault(const char *path, Acl *acl, const Promise *pp); PromiseResult VerifyACL(EvalContext *ctx, const char *file, const Attributes *attr, const Promise *pp) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this local copy if (!CheckACLSyntax(file, a.acl, pp)) { RecordFailure(ctx, pp, attr, "Syntax error in access control list for '%s'", file); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } SetACLDefaults(file, &a.acl); PromiseResult result = PROMISE_RESULT_NOOP; // decide which ACL API to use switch (a.acl.acl_type) { case ACL_TYPE_NONE: // fallthrough: acl_type defaults to generic case ACL_TYPE_GENERIC: #if defined(__linux__) result = PromiseResultUpdate(result, CheckPosixLinuxACL(ctx, file, a.acl, &a, pp)); #elif defined(__MINGW32__) result = PromiseResultUpdate(result, Nova_CheckNtACL(ctx, file, a.acl, &a, pp)); #else RecordFailure(ctx, pp, attr, "ACLs are not yet supported on this system."); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); #endif break; case ACL_TYPE_POSIX: #if defined(__linux__) result = PromiseResultUpdate(result, CheckPosixLinuxACL(ctx, file, a.acl, &a, pp)); #else RecordFailure(ctx, pp, attr, "Posix ACLs are not supported on this system"); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); #endif break; case ACL_TYPE_NTFS_: #ifdef __MINGW32__ result = PromiseResultUpdate(result, Nova_CheckNtACL(ctx, file, a.acl, &a, pp)); #else RecordFailure(ctx, pp, attr, "NTFS ACLs are not supported on this system"); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); #endif break; default: assert(false); RecordFailure(ctx, pp, attr, "Unknown ACL type - software error"); break; } return result; } static bool CheckACLSyntax(const char *file, Acl acl, const Promise *pp) { bool valid = true; int deny_support = false; int mask_support = false; char *valid_ops = NULL; char *valid_nperms = NULL; Rlist *rp; // set unset fields to defautls SetACLDefaults(file, &acl); // find valid values for op switch (acl.acl_method) { case ACL_METHOD_OVERWRITE: valid_ops = CF_VALID_OPS_METHOD_OVERWRITE; break; case ACL_METHOD_APPEND: valid_ops = CF_VALID_OPS_METHOD_APPEND; break; default: // never executed: should be set to a default value by now break; } switch (acl.acl_type) { case ACL_TYPE_GENERIC: // generic ACL type: cannot include native or deny-type permissions valid_nperms = ""; deny_support = false; mask_support = false; break; case ACL_TYPE_POSIX: valid_nperms = CF_VALID_NPERMS_POSIX; deny_support = false; // posix does not support deny-type permissions mask_support = true; // mask-ACE is allowed in POSIX break; case ACL_TYPE_NTFS_: valid_nperms = CF_VALID_NPERMS_NTFS; deny_support = true; mask_support = false; break; default: // never executed: should be set to a default value by now break; } // check that acl_default is set to a valid value if (!CheckAclDefault(file, &acl, pp)) { return false; } for (rp = acl.acl_entries; rp != NULL; rp = rp->next) { valid = CheckACESyntax(RlistScalarValue(rp), valid_ops, valid_nperms, deny_support, mask_support, pp); if (!valid) // wrong syntax in this ace { Log(LOG_LEVEL_ERR, "ACL: The ACE '%s' contains errors", RlistScalarValue(rp)); PromiseRef(LOG_LEVEL_ERR, pp); break; } } for (rp = acl.acl_default_entries; rp != NULL; rp = rp->next) { valid = CheckACESyntax(RlistScalarValue(rp), valid_ops, valid_nperms, deny_support, mask_support, pp); if (!valid) // wrong syntax in this ace { Log(LOG_LEVEL_ERR, "ACL: The ACE '%s' contains errors", RlistScalarValue(rp)); PromiseRef(LOG_LEVEL_ERR, pp); break; } } return valid; } /** * Set unset fields with documented defaults, to these defaults. **/ static void SetACLDefaults(const char *path, Acl *acl) { // default: acl_method => append if (acl->acl_method == ACL_METHOD_NONE) { acl->acl_method = ACL_METHOD_APPEND; } // default: acl_type => generic if (acl->acl_type == ACL_TYPE_NONE) { acl->acl_type = ACL_TYPE_GENERIC; } // default on directories: acl_default => nochange if ((acl->acl_default == ACL_DEFAULT_NONE) && (IsDir(ToChangesPath(path)))) { acl->acl_default = ACL_DEFAULT_NO_CHANGE; } } static int CheckAclDefault(const char *path, Acl *acl, const Promise *pp) /* Checks that acl_default is set to a valid value for this acl type. Returns true if so, or false otherwise. */ { int valid = false; switch (acl->acl_default) { case ACL_DEFAULT_NONE: // unset is always valid valid = true; break; case ACL_DEFAULT_SPECIFY: // NOTE: we assume all acls support specify // fallthrough case ACL_DEFAULT_ACCESS: // fallthrough default: if (IsDir(path)) { valid = true; } else { Log(LOG_LEVEL_ERR, "acl_default can only be set on directories."); PromiseRef(LOG_LEVEL_ERR, pp); valid = false; } break; } return valid; } static bool CheckACESyntax( char *ace, char *valid_ops, char *valid_nperms, int deny_support, int mask_support, const Promise *pp) { char *str = ace; bool chkid = false; // first element must be "user", "group" or "all" if (strncmp(str, "user:", 5) == 0) { str += 5; chkid = true; } else if (strncmp(str, "group:", 6) == 0) { str += 6; chkid = true; } else if (strncmp(str, "all:", 4) == 0) { str += 4; chkid = false; } else if (strncmp(str, "mask:", 5) == 0) { if (mask_support) { str += 5; chkid = false; } else { Log(LOG_LEVEL_ERR, "This ACL type does not support mask ACE."); PromiseRef(LOG_LEVEL_ERR, pp); return false; } } else { Log(LOG_LEVEL_ERR, "ACL: ACE '%s' does not start with user:/group:/all", ace); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if (chkid) // look for following "id:" { if (*str == ':') { Log(LOG_LEVEL_ERR, "ACL: ACE '%s': id cannot be empty or contain ':'", ace); return false; } // skip id-string (no check: allow any id-string) while (true) { str++; if (*str == ':') { str++; break; } else if (*str == '\0') { Log(LOG_LEVEL_ERR, "ACL: Nothing following id string in ACE '%s'", ace); return false; } } } // check the mode-string (also skips to next field) const bool valid_mode = CheckModeSyntax(&str, valid_ops, valid_nperms, pp); if (!valid_mode) { Log(LOG_LEVEL_ERR, "ACL: Malformed mode-string in ACE '%s'", ace); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if (*str == '\0') // mode was the last field { return true; } str++; // last field; must be a perm_type field const bool valid_permt = CheckPermTypeSyntax(str, deny_support, pp); if (!valid_permt) { Log(LOG_LEVEL_ERR, "ACL: Malformed perm_type syntax in ACE '%s'", ace); return false; } return true; } static bool CheckModeSyntax(char **mode_p, char *valid_ops, char *valid_nperms, const Promise *pp) /* Checks the syntax of a ':' or NULL terminated mode string. Moves the string pointer to the character following the mode (i.e. ':' or '\0') */ { char *mode = *mode_p; bool valid = false; // mode is allowed to be empty if ((*mode == '\0') || (*mode == ':')) { return true; } while (true) { mode = ScanPastChars(valid_ops, mode); mode = ScanPastChars(CF_VALID_GPERMS, mode); if (*mode == CF_NATIVE_PERMS_SEP_START) { mode++; mode = ScanPastChars(valid_nperms, mode); if (*mode == CF_NATIVE_PERMS_SEP_END) { mode++; } else { Log(LOG_LEVEL_ERR, "ACL: Invalid native permission '%c', or missing native end separator", *mode); PromiseRef(LOG_LEVEL_ERR, pp); valid = false; break; } } if ((*mode == '\0') || (*mode == ':')) // end of mode-string { valid = true; break; } else if (*mode == ',') // one more iteration { mode++; } else { Log(LOG_LEVEL_ERR, "ACL: Mode string contains invalid characters"); PromiseRef(LOG_LEVEL_ERR, pp); valid = false; break; } } *mode_p = mode; // move pointer to past mode-field return valid; } static bool CheckPermTypeSyntax(char *permt, int deny_support, const Promise *pp) /* Checks if the given string corresponds to the perm_type syntax. Only "allow" or "deny", followed by NULL-termination are valid. In addition, "deny" is only valid for ACL types supporting it. */ { bool valid = false; if (strcmp(permt, "allow") == 0) { valid = true; } else if (strcmp(permt, "deny") == 0) { if (deny_support) { valid = true; } else { Log(LOG_LEVEL_ERR, "Deny permission not supported by this ACL type"); PromiseRef(LOG_LEVEL_ERR, pp); } } return valid; } cfengine-3.24.2/cf-agent/Makefile.am0000644000000000000000000001014715010704253017076 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-agent.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../cf-check \ @CPPFLAGS@ \ $(ENTERPRISE_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(LIBVIRT_CPPFLAGS) \ $(POSTGRESQL_CPPFLAGS) \ $(MYSQL_CPPFLAGS) \ $(LIBXML2_CPPFLAGS) \ $(PAM_CPPFLAGS) AM_CFLAGS = \ @CFLAGS@ \ $(ENTERPRISE_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(PCRE2_CFLAGS) \ $(LIBVIRT_CFLAGS) \ $(POSTGRESQL_CFLAGS) \ $(MYSQL_CFLAGS) \ $(LIBXML2_CFLAGS) \ $(PAM_CFLAGS) AM_LDFLAGS = \ @LDFLAGS@ \ $(OPENSSL_LDFLAGS) \ $(PCRE2_LDFLAGS) \ $(LIBVIRT_LDFLAGS) \ $(POSTGRESQL_LDFLAGS) \ $(MYSQL_LDFLAGS) \ $(LIBXML2_LDFLAGS) \ $(PAM_LDFLAGS) if FREEBSD AM_LDFLAGS += -lutil endif libcf_agent_la_LIBADD = ../libpromises/libpromises.la \ $(OPENSSL_LIBS) \ $(PCRE2_LIBS) \ $(LIBVIRT_LIBS) \ $(POSTGRESQL_LIBS) \ $(MYSQL_LIBS) \ $(LIBXML2_LIBS) \ $(PAM_LIBS) libcf_agent_la_SOURCES = \ agent-diagnostics.c agent-diagnostics.h \ simulate_mode.c simulate_mode.h \ tokyo_check.c tokyo_check.h \ abstract_dir.c abstract_dir.h \ cf-agent.c \ cf-agent-enterprise-stubs.c cf-agent-enterprise-stubs.h \ comparray.c comparray.h \ acl_posix.c acl_posix.h \ cf_sql.c cf_sql.h \ files_changes.c files_changes.h \ promiser_regex_resolver.c promiser_regex_resolver.h \ retcode.c retcode.h \ verify_acl.c verify_acl.h \ verify_files.c verify_files.h \ verify_files_utils.c verify_files_utils.h \ verify_files_hashes.c verify_files_hashes.h \ verify_storage.c verify_storage.h \ verify_exec.c verify_exec.h \ verify_methods.c verify_methods.h \ verify_databases.c verify_databases.h \ verify_processes.c verify_processes.h \ verify_services.c verify_services.h \ verify_environments.c verify_environments.h \ files_edit.c files_edit.h \ files_editline.c files_editline.h \ files_editxml.c files_editxml.h \ files_properties.c files_properties.h \ files_select.c files_select.h \ vercmp_internal.c vercmp_internal.h \ vercmp.c vercmp.h \ package_module.c package_module.h \ verify_packages.c verify_packages.h \ verify_new_packages.c verify_new_packages.h \ verify_users.c verify_users.h \ cf-agent-windows-functions.h if !NT libcf_agent_la_SOURCES += nfs.c nfs.h if HAVE_USERS_PROMISE_DEPS libcf_agent_la_SOURCES += verify_users_pam.c else libcf_agent_la_SOURCES += verify_users_stub.c endif endif if HAVE_AVAHI_CLIENT if HAVE_AVAHI_COMMON libcf_agent_la_SOURCES += \ findhub.c findhub_priv.h findhub.h \ load_avahi.c load_avahi.h endif endif TESTS = if !NT noinst_PROGRAMS = manifest_file manifest_file_SOURCES = manifest_file.c manifest_file_LDADD = ../libntech/libutils/libutils.la \ ../libpromises/libpromises.la \ libcf-agent.la TESTS += manifest_file endif if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-agent # Workaround for automake madness (try removing it if you want to know why). cf_agent_CFLAGS = $(AM_CFLAGS) # Build both a libcf-agent.la library, and a cf-agent executable cf_agent_LDADD = libcf-agent.la endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-agent/files_select.c0000644000000000000000000003776615010704253017667 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* GetGroupName(), GetUserName() */ static bool SelectTypeMatch(const struct stat *lstatptr, Rlist *crit); static bool SelectOwnerMatch(EvalContext *ctx, char *path, const struct stat *lstatptr, Rlist *crit); static bool SelectModeMatch(const struct stat *lstatptr, Rlist *ls); static bool SelectTimeMatch(time_t stattime, time_t fromtime, time_t totime); static bool SelectNameRegexMatch(EvalContext *ctx, const char *filename, char *crit); static bool SelectPathRegexMatch(EvalContext *ctx, char *filename, char *crit); static bool SelectExecRegexMatch(EvalContext *ctx, char *filename, char *crit, char *prog); static bool SelectIsSymLinkTo(EvalContext *ctx, char *filename, Rlist *crit); static bool SelectExecProgram(char *filename, char *command); static bool SelectSizeMatch(size_t size, size_t min, size_t max); #if !defined(__MINGW32__) static bool SelectGroupMatch(EvalContext *ctx, const struct stat *lstatptr, Rlist *crit); #endif #if defined HAVE_CHFLAGS static bool SelectBSDMatch(const struct stat *lstatptr, Rlist *bsdflags); #endif bool SelectLeaf(EvalContext *ctx, char *path, const struct stat *sb, const FileSelect *fs) { Rlist *rp; StringSet *leaf_attr = StringSetNew(); #ifdef __MINGW32__ if (fs->issymlinkto != NULL) { Log(LOG_LEVEL_VERBOSE, "files_select.issymlinkto is ignored on Windows (symbolic links are not supported by Windows)"); } if (fs->groups != NULL) { Log(LOG_LEVEL_VERBOSE, "files_select.search_groups is ignored on Windows (file groups are not supported by Windows)"); } if (fs->bsdflags != NULL) { Log(LOG_LEVEL_VERBOSE, "files_select.search_bsdflags is ignored on Windows"); } #endif /* __MINGW32__ */ if (fs->name == NULL) { StringSetAdd(leaf_attr, xstrdup("leaf_name")); } for (rp = fs->name; rp != NULL; rp = rp->next) { if (SelectNameRegexMatch(ctx, path, RlistScalarValue(rp))) { StringSetAdd(leaf_attr, xstrdup("leaf_name")); break; } } if (fs->path == NULL) { StringSetAdd(leaf_attr, xstrdup("leaf_path")); } for (rp = fs->path; rp != NULL; rp = rp->next) { if (SelectPathRegexMatch(ctx, path, RlistScalarValue(rp))) { StringSetAdd(leaf_attr, xstrdup("path_name")); break; } } if (SelectTypeMatch(sb, fs->filetypes)) { StringSetAdd(leaf_attr, xstrdup("file_types")); } if ((fs->owners) && (SelectOwnerMatch(ctx, path, sb, fs->owners))) { StringSetAdd(leaf_attr, xstrdup("owner")); } if (fs->owners == NULL) { StringSetAdd(leaf_attr, xstrdup("owner")); } #ifdef __MINGW32__ StringSetAdd(leaf_attr, xstrdup("group")); #else /* !__MINGW32__ */ if ((fs->groups) && (SelectGroupMatch(ctx, sb, fs->groups))) { StringSetAdd(leaf_attr, xstrdup("group")); } if (fs->groups == NULL) { StringSetAdd(leaf_attr, xstrdup("group")); } #endif /* !__MINGW32__ */ if (SelectModeMatch(sb, fs->perms)) { StringSetAdd(leaf_attr, xstrdup("mode")); } #if defined HAVE_CHFLAGS if (SelectBSDMatch(sb, fs->bsdflags)) { StringSetAdd(leaf_attr, xstrdup("bsdflags")); } #endif if (SelectTimeMatch(sb->st_atime, fs->min_atime, fs->max_atime)) { StringSetAdd(leaf_attr, xstrdup("atime")); } if (SelectTimeMatch(sb->st_ctime, fs->min_ctime, fs->max_ctime)) { StringSetAdd(leaf_attr, xstrdup("ctime")); } if (SelectSizeMatch(sb->st_size, fs->min_size, fs->max_size)) { StringSetAdd(leaf_attr, xstrdup("size")); } if (SelectTimeMatch(sb->st_mtime, fs->min_mtime, fs->max_mtime)) { StringSetAdd(leaf_attr, xstrdup("mtime")); } if ((fs->issymlinkto) && (SelectIsSymLinkTo(ctx, path, fs->issymlinkto))) { StringSetAdd(leaf_attr, xstrdup("issymlinkto")); } if ((fs->exec_regex) && (SelectExecRegexMatch(ctx, path, fs->exec_regex, fs->exec_program))) { StringSetAdd(leaf_attr, xstrdup("exec_regex")); } if ((fs->exec_program) && (SelectExecProgram(path, fs->exec_program))) { StringSetAdd(leaf_attr, xstrdup("exec_program")); } bool result = EvalFileResult(fs->result, leaf_attr); Log(LOG_LEVEL_VERBOSE, "file_select result '%s' on '%s' was '%s'", fs->result, path, result ? "true" : "false"); StringSetDestroy(leaf_attr); return result; } /*******************************************************************/ /* Level */ /*******************************************************************/ static bool SelectSizeMatch(size_t size, size_t min, size_t max) { if ((size <= max) && (size >= min)) { return true; } return false; } /*******************************************************************/ static bool SelectTypeMatch(const struct stat *lstatptr, Rlist *crit) { Rlist *rp; StringSet *leafattrib = StringSetNew(); if (S_ISREG(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("reg")); StringSetAdd(leafattrib, xstrdup("plain")); } if (S_ISDIR(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("dir")); } #ifndef __MINGW32__ if (S_ISLNK(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("symlink")); } if (S_ISFIFO(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("fifo")); } if (S_ISSOCK(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("socket")); } if (S_ISCHR(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("char")); } if (S_ISBLK(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("block")); } #endif /* !__MINGW32__ */ #ifdef HAVE_DOOR_CREATE if (S_ISDOOR(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("door")); } #endif for (rp = crit; rp != NULL; rp = rp->next) { if (EvalFileResult(RlistScalarValue(rp), leafattrib)) { StringSetDestroy(leafattrib); return true; } } StringSetDestroy(leafattrib); return false; } static bool SelectOwnerMatch(EvalContext *ctx, char *path, const struct stat *lstatptr, Rlist *crit) { Rlist *rp; char ownerName[CF_BUFSIZE]; StringSet *leafattrib = StringSetNew(); #ifndef __MINGW32__ // no uids on Windows char buffer[CF_SMALLBUF]; snprintf(buffer, CF_SMALLBUF, "%ju", (uintmax_t) lstatptr->st_uid); StringSetAdd(leafattrib, xstrdup(buffer)); #endif /* __MINGW32__ */ bool gotOwner = GetOwnerName(path, lstatptr, ownerName, sizeof(ownerName)); if (gotOwner) { StringSetAdd(leafattrib, xstrdup(ownerName)); } else { StringSetAdd(leafattrib, xstrdup("none")); } for (rp = crit; rp != NULL; rp = rp->next) { if (EvalFileResult(RlistScalarValue(rp), leafattrib)) { Log(LOG_LEVEL_DEBUG, "Select owner match"); StringSetDestroy(leafattrib); return true; } if (gotOwner && (FullTextMatch(ctx, RlistScalarValue(rp), ownerName))) { Log(LOG_LEVEL_DEBUG, "Select owner match"); StringSetDestroy(leafattrib); return true; } #ifndef __MINGW32__ if (FullTextMatch(ctx, RlistScalarValue(rp), buffer)) { Log(LOG_LEVEL_DEBUG, "Select owner match"); StringSetDestroy(leafattrib); return true; } #endif /* !__MINGW32__ */ } StringSetDestroy(leafattrib); return false; } /*******************************************************************/ static bool SelectModeMatch(const struct stat *lstatptr, Rlist *list) { mode_t newperm, plus, minus; Rlist *rp; for (rp = list; rp != NULL; rp = rp->next) { plus = 0; minus = 0; if (!ParseModeString(RlistScalarValue(rp), &plus, &minus)) { Log(LOG_LEVEL_ERR, "Problem validating a mode string '%s' in search filter", RlistScalarValue(rp)); continue; } newperm = (lstatptr->st_mode & 07777); newperm |= plus; newperm &= ~minus; if ((newperm & 07777) == (lstatptr->st_mode & 07777)) { return true; } } return false; } /*******************************************************************/ #if defined HAVE_CHFLAGS static bool SelectBSDMatch(const struct stat *lstatptr, Rlist *bsdflags) { u_long newflags, plus, minus; if (!ParseFlagString(bsdflags, &plus, &minus)) { Log(LOG_LEVEL_ERR, "Problem validating a BSD flag string"); } newflags = (lstatptr->st_flags & CHFLAGS_MASK); newflags |= plus; newflags &= ~minus; if ((newflags & CHFLAGS_MASK) == (lstatptr->st_flags & CHFLAGS_MASK)) /* file okay */ { return true; } return false; } #endif /*******************************************************************/ static bool SelectTimeMatch(time_t stattime, time_t fromtime, time_t totime) { return ((fromtime < stattime) && (stattime < totime)); } /*******************************************************************/ static bool SelectNameRegexMatch(EvalContext *ctx, const char *filename, char *crit) { if (FullTextMatch(ctx, crit, ReadLastNode(filename))) { return true; } return false; } /*******************************************************************/ static bool SelectPathRegexMatch(EvalContext *ctx, char *filename, char *crit) { if (FullTextMatch(ctx, crit, filename)) { return true; } return false; } /*******************************************************************/ static bool SelectExecRegexMatch(EvalContext *ctx, char *filename, char *crit, char *prog) { // insert real value of $(this.promiser) in command char *buf_tmp = SearchAndReplace(prog, "$(this.promiser)", filename); char *buf = SearchAndReplace(buf_tmp, "${this.promiser}", filename); free(buf_tmp); FILE *pp = cf_popen(buf, "r", true); if (pp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", buf, GetErrorStr()); free(buf); return false; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = CfReadLine(&line, &line_size, pp); if (res == -1) { if (!feof(pp)) { Log(LOG_LEVEL_ERR, "Error reading output from command '%s'. (fgets: %s)", buf, GetErrorStr()); } cf_pclose(pp); free(line); free(buf); return false; } if (FullTextMatch(ctx, crit, line)) { cf_pclose(pp); free(line); free(buf); return true; } } cf_pclose(pp); free(line); free(buf); return false; } /*******************************************************************/ static bool SelectIsSymLinkTo(EvalContext *ctx, char *filename, Rlist *crit) { #ifndef __MINGW32__ char buffer[CF_BUFSIZE]; Rlist *rp; for (rp = crit; rp != NULL; rp = rp->next) { memset(buffer, 0, CF_BUFSIZE); struct stat statbuf; // Don't worry if this gives an error, that's handled above us. // We're calling lstat() here to avoid dereferencing the // symlink... and we only care if the inode is a directory. if (lstat(filename, &statbuf) == -1) { // Do nothing. } else if (!S_ISLNK(statbuf.st_mode)) { Log(LOG_LEVEL_DEBUG, "Skipping readlink() on non-symlink %s", filename); return false; } if (readlink(filename, buffer, CF_BUFSIZE - 1) == -1) { Log(LOG_LEVEL_ERR, "Unable to read link '%s' in filter. (readlink: %s)", filename, GetErrorStr()); return false; } if (FullTextMatch(ctx, RlistScalarValue(rp), buffer)) { return true; } } #endif /* !__MINGW32__ */ return false; } /*******************************************************************/ static bool SelectExecProgram(char *filename, char *command) /* command can include $(this.promiser) for the name of the file */ { // insert real value of $(this.promiser) in command char *buf_tmp = SearchAndReplace(command, "$(this.promiser)", filename); char *buf = SearchAndReplace(buf_tmp, "${this.promiser}", filename); free(buf_tmp); bool returns_zero = ShellCommandReturnsZero(buf, SHELL_TYPE_NONE); if (returns_zero) { Log(LOG_LEVEL_DEBUG, "Select ExecProgram match for '%s'", buf); free(buf); return true; } else { free(buf); return false; } } #ifndef __MINGW32__ /*******************************************************************/ /* Unix implementations */ /*******************************************************************/ bool GetOwnerName(char *path, const struct stat *lstatptr, char *owner, int ownerSz) { memset(owner, 0, ownerSz); if (!GetUserName(lstatptr->st_uid, owner, ownerSz, LOG_LEVEL_ERR)) { /* detailed error already logged */ Log(LOG_LEVEL_ERR, "Could not get owner name for '%s'", path); return false; } return true; } /*******************************************************************/ static bool SelectGroupMatch(EvalContext *ctx, const struct stat *lstatptr, Rlist *crit) { char buffer[CF_SMALLBUF]; Rlist *rp; StringSet *leafattrib = StringSetNew(); snprintf(buffer, CF_SMALLBUF, "%ju", (uintmax_t) lstatptr->st_gid); StringSetAdd(leafattrib, xstrdup(buffer)); bool found = GetGroupName(lstatptr->st_gid, buffer, sizeof(buffer), LOG_LEVEL_VERBOSE); if (found) { StringSetAdd(leafattrib, xstrdup(buffer)); } else { StringSetAdd(leafattrib, xstrdup("none")); } for (rp = crit; rp != NULL; rp = rp->next) { if (EvalFileResult(RlistScalarValue(rp), leafattrib)) { Log(LOG_LEVEL_DEBUG, "Select group match"); StringSetDestroy(leafattrib); return true; } if (found && (FullTextMatch(ctx, RlistScalarValue(rp), buffer))) { Log(LOG_LEVEL_DEBUG, "Select group match"); StringSetDestroy(leafattrib); return true; } if (FullTextMatch(ctx, RlistScalarValue(rp), buffer)) { Log(LOG_LEVEL_DEBUG, "Select group match"); StringSetDestroy(leafattrib); return true; } } StringSetDestroy(leafattrib); return false; } #endif /* !__MINGW32__ */ cfengine-3.24.2/cf-agent/vercmp.h0000644000000000000000000000307115010704253016505 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERCMP_H #define CFENGINE_VERCMP_H typedef enum { VERCMP_ERROR = -1, VERCMP_NO_MATCH = false, VERCMP_MATCH = true } VersionCmpResult; /* * a, pp are used for * a.packages.package_select * a.packages.package_version_less_command * a.packages.package_version_equal_command * a.packages.package_commands_useshell * cfPS */ VersionCmpResult CompareVersions(EvalContext *ctx, const char *v1, const char *v2, const Attributes *a, const Promise *pp, PromiseResult *result); const char* PackageVersionComparatorToString(const PackageVersionComparator pvc); #endif cfengine-3.24.2/cf-agent/nfs.c0000644000000000000000000007051315010704253015777 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* seconds */ #define RPCTIMEOUT 60 static int FSTAB_EDITS = 0; /* GLOBAL_X */ static Item *FSTABLIST = NULL; /* GLOBAL_X */ static void GetHostAndSource(const char *buf, char *host, char *source); static void AugmentMountInfo(Seq *list, char *host, char *source, char *mounton, char *options); static bool MatchFSInFstab(char *match); static void DeleteThisItem(Item **liststart, Item *entry); static const char *const VMOUNTCOMM[] = { [PLATFORM_CONTEXT_UNKNOWN] = "", [PLATFORM_CONTEXT_OPENVZ] = "/bin/mount -va", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/sbin/mount -ea", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/usr/sbin/mount -t nfs", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/bin/mount -va", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "/bin/mount -va", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/usr/sbin/mount -a", /* solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/usr/sbin/mount -a", /* solaris */ [PLATFORM_CONTEXT_FREEBSD] = "/sbin/mount -va", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/sbin/mount -a", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/etc/mount -va", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "/bin/sh /etc/fstab", /* NT - possible security issue */ [PLATFORM_CONTEXT_SYSTEMV] = "/sbin/mountall", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/sbin/mount", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/etc/mountall", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "/sbin/mount -va", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/bin/mount -v", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/sbin/mount -va", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "mingw-invalid", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "/bin/mount -a", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "", /* android */ }; static const char *const VUNMOUNTCOMM[] = { [PLATFORM_CONTEXT_UNKNOWN] = "", [PLATFORM_CONTEXT_OPENVZ] = "/bin/umount", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "/sbin/umount", /* hpux */ [PLATFORM_CONTEXT_AIX] = "/usr/sbin/umount", /* aix */ [PLATFORM_CONTEXT_LINUX] = "/bin/umount", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "/bin/umount", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "/etc/umount", /* solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "/etc/umount", /* solaris */ [PLATFORM_CONTEXT_FREEBSD] = "/sbin/umount", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "/sbin/umount", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "/etc/umount", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "/bin/umount", /* NT */ [PLATFORM_CONTEXT_SYSTEMV] = "/sbin/umount", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "/sbin/umount", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "/etc/umount", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "/sbin/umount", /* darwin */ [PLATFORM_CONTEXT_QNX] = "/bin/umount", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "/sbin/umount", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "mingw-invalid", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "/bin/umount", /* vmware */ [PLATFORM_CONTEXT_ANDROID] = "/system/xbin/umount", /* android */ }; static const char *const VMOUNTOPTS[] = { [PLATFORM_CONTEXT_UNKNOWN] = "", [PLATFORM_CONTEXT_OPENVZ] = "defaults", /* virt_host_vz_vzps */ [PLATFORM_CONTEXT_HP] = "bg,hard,intr", /* hpux */ [PLATFORM_CONTEXT_AIX] = "bg,hard,intr", /* aix */ [PLATFORM_CONTEXT_LINUX] = "defaults", /* linux */ [PLATFORM_CONTEXT_BUSYBOX] = "defaults", /* linux */ [PLATFORM_CONTEXT_SOLARIS] = "bg,hard,intr", /* solaris */ [PLATFORM_CONTEXT_SUN_SOLARIS] = "bg,hard,intr", /* solaris */ [PLATFORM_CONTEXT_FREEBSD] = "bg,intr", /* freebsd */ [PLATFORM_CONTEXT_NETBSD] = "-i,-b", /* netbsd */ [PLATFORM_CONTEXT_CRAYOS] = "bg,hard,intr", /* cray */ [PLATFORM_CONTEXT_WINDOWS_NT] = "", /* NT */ [PLATFORM_CONTEXT_SYSTEMV] = "bg,hard,intr", /* Unixware */ [PLATFORM_CONTEXT_OPENBSD] = "-i,-b", /* openbsd */ [PLATFORM_CONTEXT_CFSCO] = "bg,hard,intr", /* sco */ [PLATFORM_CONTEXT_DARWIN] = "-i,-b", /* darwin */ [PLATFORM_CONTEXT_QNX] = "bg,hard,intr", /* qnx */ [PLATFORM_CONTEXT_DRAGONFLY] = "bg,intr", /* dragonfly */ [PLATFORM_CONTEXT_MINGW] = "mingw-invalid", /* mingw */ [PLATFORM_CONTEXT_VMWARE] = "defaults", /* vmstate */ [PLATFORM_CONTEXT_ANDROID] = "defaults", /* android */ }; static void GetHostAndSource(const char *buf, char *host, char *source) /* Extracts from buffer host & source of nfs, cifs and panfs network systems */ { assert(StringStartsWith(buf, "panfs://") || StringStartsWith(buf, "//") || strchr(buf, ':') != NULL); int index = 0; // Index for buf and host int source_index = 0; size_t slashes = 0; // panfs & cifs if (StringStartsWith(buf, "panfs://") || StringStartsWith(buf, "//")) { // copy host while (slashes != 3) { // TODO: Add example of what this string looks like if (buf[index] == '/' || buf[index] == '\\') { slashes++; } host[index] = buf[index]; index++; } host[--index] = '\0'; } // nfs else { while (buf[index] != ':') { host[index] = buf[index]; index++; } host[index++] = '\0'; } // copy source while ((buf[index] != '\0') && (buf[index] != ' ')) { source[source_index++] = buf[index++]; } source[source_index] = '\0'; } bool LoadMountInfo(Seq *list) /* This is, in fact, the most portable way to read the mount info! */ /* Depressing, isn't it? */ { FILE *pp; char buf1[CF_BUFSIZE], buf2[CF_BUFSIZE], buf3[CF_BUFSIZE]; int i; bool nfs = false, panfs = false, cifs = false; // get mount command without parameters for (i = 0; VMOUNTCOMM[VSYSTEMHARDCLASS][i] != ' '; i++) { buf1[i] = VMOUNTCOMM[VSYSTEMHARDCLASS][i]; } buf1[i] = '\0'; SetTimeOut(RPCTIMEOUT); if ((pp = cf_popen(buf1, "r", true)) == NULL) { Log(LOG_LEVEL_ERR, "Can't open '%s'. (cf_popen: %s)", buf1, GetErrorStr()); return false; } size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); for (;;) { buf1[0] = buf2[0] = buf3[0] = '\0'; nfs = false; ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp); if (res == -1) { if (!feof(pp)) { Log(LOG_LEVEL_ERR, "Unable to read list of mounted filesystems. (fread: %s)", GetErrorStr()); cf_pclose(pp); free(vbuff); return false; } else { break; } } Seq *words = SeqStringFromString(vbuff, ' '); if (SeqStringContains(words, "panfs")) { panfs = true; } else if (SeqStringContains(words, "nfs")) { nfs = true; } else if (SeqStringContains(words, "cifs")) { cifs = true; } SeqDestroy(words); // security note: buff is CF_BUFSIZE, so that is the max that can be written to buf1, buf2 or buf3 sscanf(vbuff, "%s%s%s", buf1, buf2, buf3); if ((vbuff[0] == '\0') || (vbuff[0] == '\n')) { break; } if (strstr(vbuff, "not responding")) { Log(LOG_LEVEL_ERR, "%s", vbuff); } if (strstr(vbuff, "be root")) { Log(LOG_LEVEL_ERR, "Mount access is denied. You must be root. Use the -n option to run safely"); } if ((strstr(vbuff, "retrying")) || (strstr(vbuff, "denied")) || (strstr(vbuff, "backgrounding"))) { continue; } if ((strstr(vbuff, "exceeded")) || (strstr(vbuff, "busy"))) { continue; } if (strstr(vbuff, "RPC")) { Log(LOG_LEVEL_INFO, "There was an RPC timeout. Aborting mount operations."); Log(LOG_LEVEL_INFO, "Session failed while trying to talk to remote host"); Log(LOG_LEVEL_INFO, "%s", vbuff); cf_pclose(pp); free(vbuff); return false; } // host: max FQDN is 255 chars (max IPv6 with IPv4 tunneling is 45 chars) // source, mounton: hardcoding max path length to 1023; longer is very unlikely char host[256], source[1024], mounton[1024]; host[0] = source[0] = mounton[0] = '\0'; #if defined(__sun) || defined(__hpux) if (IsAbsoluteFileName(buf3) && !cifs) { strlcpy(host, "localhost", sizeof(host)); strlcpy(mounton, buf1, sizeof(mounton)); } else { if (cifs || panfs) { GetHostAndSource(buf1, host, source); } else { sscanf(buf1, "%255[^:]:%1023s", host, source); } strlcpy(mounton, buf1, sizeof(mounton)); } #elif defined(_AIX) /* skip header */ if (IsAbsoluteFileName(buf1) && !cifs) { strlcpy(host, "localhost", sizeof(host)); strlcpy(mounton, buf2, sizeof(mounton)); } else { strlcpy(host, buf1, sizeof(host)); strlcpy(source, buf1, sizeof(source)); strlcpy(mounton, buf3, sizeof(mounton)); } #elif defined(__CYGWIN__) strlcpy(mounton, buf2, sizeof(mounton)); strlcpy(host, buf1, sizeof(host)); #elif defined(sco) || defined(__SCO_DS) Log(LOG_LEVEL_ERR, "Don't understand SCO mount format, no data"); #else if (IsAbsoluteFileName(buf1) && !cifs) { Log(LOG_LEVEL_VERBOSE, "'%s' is a local absolute file name, setting host to localhost", buf1); strlcpy(host, "localhost", sizeof(host)); strlcpy(mounton, buf3, sizeof(mounton)); } else { if (cifs || panfs) { GetHostAndSource(buf1, host, source); } else { sscanf(buf1, "%255[^:]:%1023s", host, source); } strlcpy(mounton, buf3, sizeof(mounton)); } #endif Log(LOG_LEVEL_DEBUG, "LoadMountInfo: host '%s', source '%s', mounton '%s'", host, source, mounton); if (panfs) { AugmentMountInfo(list, host, source, mounton, "panfs"); } else if (nfs) { AugmentMountInfo(list, host, source, mounton, "nfs"); } else if (cifs) { AugmentMountInfo(list, host, source, mounton, "cifs"); } else { AugmentMountInfo(list, host, source, mounton, NULL); } } free(vbuff); alarm(0); signal(SIGALRM, SIG_DFL); cf_pclose(pp); return true; } /*******************************************************************/ static void AugmentMountInfo(Seq *list, char *host, char *source, char *mounton, char *options) { Mount *entry = xcalloc(1, sizeof(Mount)); if (host) { entry->host = xstrdup(host); } if (source) { entry->source = xstrdup(source); } if (mounton) { entry->mounton = xstrdup(mounton); } if (options) { entry->options = xstrdup(options); } SeqAppend(list, entry); } /*******************************************************************/ void DeleteMountInfo(Seq *list) { for (size_t i = 0; i < SeqLength(list); i++) { Mount *entry = SeqAt(list, i); if (entry->host) { free(entry->host); } if (entry->source) { free(entry->source); } if (entry->mounton) { free(entry->mounton); } if (entry->options) { free(entry->options); } } SeqClear(list); } /*******************************************************************/ int VerifyInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp, PromiseResult *result) /* Ensure filesystem IS in fstab, and return no of changes */ { assert(a != NULL); char fstab[CF_BUFSIZE]; char *host, *rmountpt, *mountpt, *fstype, *opts; if (!FSTABLIST) { if (!LoadFileAsItemList(&FSTABLIST, VFSTAB[VSYSTEMHARDCLASS], a->edits, false)) { Log(LOG_LEVEL_ERR, "Couldn't open '%s'", VFSTAB[VSYSTEMHARDCLASS]); return 0; } else { FSTAB_EDITS = 0; } } if (a->mount.mount_options) { opts = Rlist2String(a->mount.mount_options, ","); } else { opts = xstrdup(VMOUNTOPTS[VSYSTEMHARDCLASS]); } host = a->mount.mount_server; rmountpt = a->mount.mount_source; mountpt = name; fstype = a->mount.mount_type; #if defined(__QNX__) || defined(__QNXNTO__) snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s %s\t%s 0 0", host, rmountpt, mountpt, fstype, opts); #elif defined(_CRAY) char fstype_upper[CF_BUFSIZE]; strlcpy(fstype_upper, fstype, CF_BUFSIZE); ToUpperStrInplace(fstype_upper); snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s %s\t%s", host, rmountpt, mountpt, fstype_upper, opts); break; #elif defined(__hpux) snprintf(fstab, CF_BUFSIZE, "%s:%s %s \t %s \t %s 0 0", host, rmountpt, mountpt, fstype, opts); #elif defined(_AIX) snprintf(fstab, CF_BUFSIZE, "%s:\n\tdev\t= %s\n\ttype\t= %s\n\tvfs\t= %s\n\tnodename\t= %s\n\tmount\t= true\n\toptions\t= %s\n\taccount\t= false\n", mountpt, rmountpt, fstype, fstype, host, opts); #elif defined(__linux__) snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s \t %s \t %s", host, rmountpt, mountpt, fstype, opts); #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__APPLE__) snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s \t %s \t %s 0 0", host, rmountpt, mountpt, fstype, opts); #elif defined(__sun) || defined(sco) || defined(__SCO_DS) snprintf(fstab, CF_BUFSIZE, "%s:%s - %s %s - yes %s", host, rmountpt, mountpt, fstype, opts); #elif defined(__CYGWIN__) snprintf(fstab, CF_BUFSIZE, "/bin/mount %s:%s %s", host, rmountpt, mountpt); #else #error "Could not determine format of fstab entry on this platform." #endif Log(LOG_LEVEL_VERBOSE, "Verifying '%s' in '%s'", mountpt, VFSTAB[VSYSTEMHARDCLASS]); int changes = 0; if (!MatchFSInFstab(mountpt)) { AppendItem(&FSTABLIST, fstab, NULL); FSTAB_EDITS++; cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Adding file system '%s:%s' to '%s'", host, rmountpt, VFSTAB[VSYSTEMHARDCLASS]); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); changes += 1; } free(opts); return changes; } /*******************************************************************/ int VerifyNotInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp, PromiseResult *result) /* Ensure filesystem is NOT in fstab, and return no of changes */ { char regex[CF_BUFSIZE]; char *host, *mountpt; Item *ip; if (!FSTABLIST) { if (!LoadFileAsItemList(&FSTABLIST, VFSTAB[VSYSTEMHARDCLASS], a->edits, false)) { Log(LOG_LEVEL_ERR, "Couldn't open '%s'", VFSTAB[VSYSTEMHARDCLASS]); return 0; } else { FSTAB_EDITS = 0; } } host = a->mount.mount_server; mountpt = name; int changes = 0; if (MatchFSInFstab(mountpt)) { if (a->mount.editfstab) { #if defined(_AIX) FILE *pfp; char aixcomm[CF_BUFSIZE]; snprintf(aixcomm, CF_BUFSIZE, "/usr/sbin/rmnfsmnt -f %s", mountpt); if ((pfp = cf_popen(aixcomm, "r", true)) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Failed to invoke /usr/sbin/rmnfsmnt to edit fstab"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return 0; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = getline(&line, &line_size, pfp); if (res == -1) { if (!feof(pfp)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to read output of /bin/rmnfsmnt"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); cf_pclose(pfp); free(line); return 0; } else { break; } } if (line[0] == '#') { continue; } if (strstr(line, "busy")) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_INTERRUPTED, pp, a, "The device under '%s' cannot be removed from '%s'", mountpt, VFSTAB[VSYSTEMHARDCLASS]); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); free(line); return 0; } } free(line); cf_pclose(pfp); return 0; /* ignore internal editing for aix , always returns 0 changes */ #else Item* next; snprintf(regex, CF_BUFSIZE, ".*[\\s]+%s[\\s]+.*", mountpt); for (ip = FSTABLIST; ip != NULL; ip = next) { next = ip->next; if (FullTextMatch(ctx, regex, ip->name)) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Deleting file system mounted on '%s'", host); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); // Check host name matches too? DeleteThisItem(&FSTABLIST, ip); FSTAB_EDITS++; changes += 1; } } #endif } } return changes; } /*******************************************************************/ PromiseResult VerifyMount(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp) { assert(a != NULL); char comm[CF_BUFSIZE]; FILE *pfp; char *host, *rmountpt, *mountpt, *opts=NULL; host = a->mount.mount_server; rmountpt = a->mount.mount_source; mountpt = name; /* Check for options required for this mount - i.e., -o ro,rsize, etc. */ if (a->mount.mount_options) { opts = Rlist2String(a->mount.mount_options, ","); } else { opts = xstrdup(VMOUNTOPTS[VSYSTEMHARDCLASS]); } PromiseResult result = PROMISE_RESULT_NOOP; if (!DONTDO) { if (StringEqual(a->mount.mount_type, "panfs")) { snprintf(comm, CF_BUFSIZE, "%s -t panfs -o %s %s%s %s", CommandArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]), opts, host, rmountpt, mountpt); } else if (StringEqual(a->mount.mount_type, "cifs")) { snprintf(comm, CF_BUFSIZE, "%s -t cifs -o %s %s%s %s", CommandArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]), opts, host, rmountpt, mountpt); } else { snprintf(comm, CF_BUFSIZE, "%s -o %s %s:%s %s", CommandArg0(VMOUNTCOMM[VSYSTEMHARDCLASS]), opts, host, rmountpt, mountpt); } if ((pfp = cf_popen(comm, "r", true)) == NULL) { Log(LOG_LEVEL_ERR, "Failed to open pipe from '%s'", CommandArg0(VMOUNTCOMM[VSYSTEMHARDCLASS])); return PROMISE_RESULT_FAIL; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); ssize_t res = CfReadLine(&line, &line_size, pfp); if (res == -1) { if (!feof(pfp)) { Log(LOG_LEVEL_ERR, "Unable to read output of mount command. (fread: %s)", GetErrorStr()); cf_pclose(pfp); free(line); return PROMISE_RESULT_FAIL; } } else if ((strstr(line, "busy")) || (strstr(line, "Busy"))) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_INTERRUPTED, pp, a, "The device under '%s' cannot be mounted", mountpt); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); cf_pclose(pfp); free(line); return 1; } free(line); cf_pclose(pfp); } /* Since opts is either Rlist2String or xstrdup'd, we need to always free it */ free(opts); cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Mounting '%s' to keep promise", mountpt); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); return result; } /*******************************************************************/ PromiseResult VerifyUnmount(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp) { char comm[CF_BUFSIZE]; FILE *pfp; char *mountpt; mountpt = name; PromiseResult result = PROMISE_RESULT_NOOP; if (!DONTDO) { snprintf(comm, CF_BUFSIZE, "%s %s", VUNMOUNTCOMM[VSYSTEMHARDCLASS], mountpt); if ((pfp = cf_popen(comm, "r", true)) == NULL) { Log(LOG_LEVEL_ERR, "Failed to open pipe from %s", VUNMOUNTCOMM[VSYSTEMHARDCLASS]); return result; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); ssize_t res = CfReadLine(&line, &line_size, pfp); if (res == -1) { cf_pclose(pfp); free(line); if (!feof(pfp)) { Log(LOG_LEVEL_ERR, "Unable to read output of unmount command. (fread: %s)", GetErrorStr()); return result; } } else if (res > 0 && ((strstr(line, "busy")) || (strstr(line, "Busy")))) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_INTERRUPTED, pp, a, "The device under '%s' cannot be unmounted", mountpt); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); cf_pclose(pfp); free(line); return result; } } cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Unmounting '%s' to keep promise", mountpt); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); return result; } /*******************************************************************/ static bool MatchFSInFstab(char *match) { Item *ip; const char delimit[]=" \t\r\n\v\f"; char *fstab_line, *token; for (ip = FSTABLIST; ip != NULL; ip = ip->next) { fstab_line = xstrdup(ip->name); if(strncmp(fstab_line, "#", 1) != 0) { token = strtok(fstab_line, delimit); while (token != NULL) { if(strcmp(token, match) == 0) { free(fstab_line); return true; } token = strtok(NULL, delimit); } } free(fstab_line); } return false; } /*******************************************************************/ void MountAll() { FILE *pp; if (DONTDO) { Log(LOG_LEVEL_VERBOSE, "Promised to mount filesystem, but not on this trial run"); return; } else { Log(LOG_LEVEL_VERBOSE, "Attempting to mount all filesystems."); } #if defined(__CYGWIN__) /* This is a shell script. Make sure it hasn't been compromised. */ struct stat sb; if (stat("/etc/fstab", &sb) == -1) { int fd; if ((fd = creat("/etc/fstab", 0755)) > 0) { if (write(fd, "#!/bin/sh\n\n", 10) != 10) { UnexpectedError("Failed to write to file '/etc/fstab'"); } close(fd); } else { if (sb.st_mode & (S_IWOTH | S_IWGRP)) { Log(LOG_LEVEL_ERR, "File /etc/fstab was insecure. Cannot mount filesystems."); return; } } } #endif SetTimeOut(RPCTIMEOUT); const char *cmd = VMOUNTCOMM[VSYSTEMHARDCLASS]; if ((pp = cf_popen(cmd, "r", true)) == NULL) { Log(LOG_LEVEL_ERR, "Failed to open pipe from '%s'. (cf_popen: %s)", cmd, GetErrorStr()); return; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = CfReadLine(&line, &line_size, pp); if (res == -1) { if (!feof(pp)) { Log(LOG_LEVEL_ERR, "Error reading output of command '%s' (ferror: %s)", cmd, GetErrorStr()); } break; } if ((strstr(line, "already mounted")) || (strstr(line, "exceeded")) || (strstr(line, "determined"))) { continue; } if (strstr(line, "not supported")) { continue; } if ((strstr(line, "denied")) || (strstr(line, "RPC"))) { Log(LOG_LEVEL_ERR, "There was a mount error while trying to mount the filesystems" " (command '%s')", cmd); break; } if ((strstr(line, "trying")) && (!strstr(line, "NFS version 2")) && (!strstr(line, "vers 3"))) { Log(LOG_LEVEL_ERR, "Attempting filesystems mount aborted because command" " '%s' went into a retry loop", cmd); break; } } free(line); alarm(0); signal(SIGALRM, SIG_DFL); cf_pclose(pp); } /*******************************************************************/ /* Addendum */ /*******************************************************************/ static void DeleteThisItem(Item **liststart, Item *entry) { Item *ip, *sp; if (entry != NULL) { if (entry->name != NULL) { free(entry->name); } sp = entry->next; if (entry == *liststart) { *liststart = sp; } else { for (ip = *liststart; ip->next != entry; ip = ip->next) { } ip->next = sp; } free((char *) entry); } } void CleanupNFS(void) { Log(LOG_LEVEL_VERBOSE, "Number of changes observed in '%s' is %d", VFSTAB[VSYSTEMHARDCLASS], FSTAB_EDITS); if (FSTAB_EDITS && FSTABLIST && !DONTDO) { RawSaveItemList(FSTABLIST, VFSTAB[VSYSTEMHARDCLASS], NewLineMode_Unix); DeleteItemList(FSTABLIST); FSTABLIST = NULL; FSTAB_EDITS = 0; } } cfengine-3.24.2/cf-agent/findhub.h0000644000000000000000000000220315010704253016624 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FINDHUB_H #define CFENGINE_FINDHUB_H #include #include int ListHubs(List **list); void PrintList(List *list); #endif cfengine-3.24.2/cf-agent/verify_methods.h0000644000000000000000000000236415010704253020244 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_METHODS_H #define CFENGINE_VERIFY_METHODS_H #include PromiseResult VerifyMethodsPromise(EvalContext *ctx, const Promise *pp); PromiseResult VerifyMethod(EvalContext *ctx, const Rval call, const Attributes *a, const Promise *pp); #endif cfengine-3.24.2/cf-agent/load_avahi.c0000644000000000000000000000613715010704253017301 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include static const char *paths[] = { "/usr/lib/x86_64-linux-gnu/libavahi-client.so.3", "/usr/lib/libavahi-client.so.3", "/usr/lib64/libavahi-client.so.3", /* 32-bit variants */ "/usr/lib/i386-linux-gnu/libavahi-client.so.3" }; static const char *getavahipath(); int loadavahi() { const char *path = getavahipath(); avahi_handle = dlopen(path, RTLD_LAZY); if (!avahi_handle) { return -1; } avahi_simple_poll_quit_ptr = dlsym(avahi_handle, "avahi_simple_poll_quit"); avahi_address_snprint_ptr = dlsym(avahi_handle, "avahi_address_snprint"); avahi_service_resolver_free_ptr = dlsym(avahi_handle, "avahi_service_resolver_free"); avahi_client_errno_ptr = dlsym(avahi_handle, "avahi_client_errno"); avahi_strerror_ptr = dlsym(avahi_handle, "avahi_strerror"); avahi_service_resolver_new_ptr = dlsym(avahi_handle, "avahi_service_resolver_new"); avahi_service_browser_get_client_ptr = dlsym(avahi_handle, "avahi_service_browser_get_client"); avahi_service_resolver_get_client_ptr = dlsym(avahi_handle, "avahi_service_resolver_get_client"); avahi_simple_poll_new_ptr = dlsym(avahi_handle, "avahi_simple_poll_new"); avahi_simple_poll_get_ptr = dlsym(avahi_handle, "avahi_simple_poll_get"); avahi_client_new_ptr = dlsym(avahi_handle, "avahi_client_new"); avahi_simple_poll_loop_ptr = dlsym(avahi_handle, "avahi_simple_poll_loop"); avahi_service_browser_free_ptr = dlsym(avahi_handle, "avahi_service_browser_free"); avahi_client_free_ptr = dlsym(avahi_handle, "avahi_client_free"); avahi_simple_poll_free_ptr = dlsym(avahi_handle, "avahi_simple_poll_free"); avahi_service_browser_new_ptr = dlsym(avahi_handle, "avahi_service_browser_new"); return 0; } static const char *getavahipath() { const char *env = getenv("AVAHI_PATH"); struct stat sb; if (stat(env, &sb) == 0) { return env; } for (int i = 0; i < sizeof(paths)/sizeof(paths[0]); i++) { if (stat(paths[i], &sb) == 0) { return paths[i]; } } return NULL; } cfengine-3.24.2/cf-agent/files_properties.h0000644000000000000000000000302315010704253020564 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_PROPERTIES_H #define CFENGINE_FILES_PROPERTIES_H #include #include /* AgentConnection */ void AddFilenameToListOfSuspicious(const char *filename); /* * Both functions assume that current working directory is #path, so #filename * can be stat'ed at relative path (if it is a local file). */ bool ConsiderLocalFile(const char *filename, const char *path); bool ConsiderAbstractFile(const char *nodename, const char *path, const FileCopy *fc, AgentConnection *conn); #endif cfengine-3.24.2/cf-agent/verify_storage.c0000644000000000000000000003706515010704253020246 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool CF_MOUNTALL = false; /* GLOBAL_X */ static PromiseResult FindStoragePromiserObjects(EvalContext *ctx, const Promise *pp); static PromiseResult VerifyFileSystem(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp); static PromiseResult VerifyFreeSpace(EvalContext *ctx, char *file, const Attributes *a, const Promise *pp); static PromiseResult VolumeScanArrivals(char *file, const Attributes *a, const Promise *pp); #if !defined(__MINGW32__) static bool FileSystemMountedCorrectly(Seq *list, char *name, const Attributes *a); static bool IsForeignFileSystem(struct stat *childstat, char *dir); #endif #ifndef __MINGW32__ static PromiseResult VerifyMountPromise(EvalContext *ctx, char *file, const Attributes *a, const Promise *pp); #endif /* !__MINGW32__ */ Seq *GetGlobalMountedFSList(void) { static Seq *mounted_fs_list = NULL; /* GLOBAL_X */ if (!mounted_fs_list) { mounted_fs_list = SeqNew(100, free); } return mounted_fs_list; } PromiseResult FindAndVerifyStoragePromises(EvalContext *ctx, const Promise *pp) { PromiseBanner(ctx, pp); return FindStoragePromiserObjects(ctx, pp); } /*****************************************************************************/ static PromiseResult FindStoragePromiserObjects(EvalContext *ctx, const Promise *pp) { /* Check if we are searching over a regular expression */ return LocateFilePromiserGroup(ctx, pp->promiser, pp, VerifyStoragePromise); } /*****************************************************************************/ PromiseResult VerifyStoragePromise(EvalContext *ctx, char *path, const Promise *pp) { CfLock thislock; Attributes a = GetStorageAttributes(ctx, pp); #ifdef __MINGW32__ if (!a.havemount) { Log(LOG_LEVEL_VERBOSE, "storage.mount is not supported on Windows"); } #endif /* No parameter conflicts here */ if (a.mount.unmount) { if ((a.mount.mount_source)) { Log(LOG_LEVEL_VERBOSE, "An unmount promise indicates a mount-source information - probably an error"); } if ((a.mount.mount_server)) { Log(LOG_LEVEL_VERBOSE, "An unmount promise indicates a mount-server information - probably an error"); } } else if (a.havemount) { if ((a.mount.mount_source == NULL) || (a.mount.mount_server == NULL)) { Log(LOG_LEVEL_ERR, "Insufficient specification in mount promise - need source and server"); return PROMISE_RESULT_NOOP; } } thislock = AcquireLock(ctx, path, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, false); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } /* Do mounts first */ PromiseResult result = PROMISE_RESULT_NOOP; #ifndef __MINGW32__ if (SeqLength(GetGlobalMountedFSList()) == 0 && !LoadMountInfo(GetGlobalMountedFSList())) { Log(LOG_LEVEL_ERR, "Couldn't obtain a list of mounted filesystems - aborting"); YieldCurrentLock(thislock); return PROMISE_RESULT_NOOP; } if (a.havemount) { result = PromiseResultUpdate(result, VerifyMountPromise(ctx, path, &a, pp)); } #endif /* !__MINGW32__ */ /* Then check file system */ if (a.havevolume) { result = PromiseResultUpdate(result, VerifyFileSystem(ctx, path, &a, pp)); if (a.volume.freespace != CF_NOINT) { result = PromiseResultUpdate(result, VerifyFreeSpace(ctx, path, &a, pp)); } if (a.volume.scan_arrivals) { result = PromiseResultUpdate(result, VolumeScanArrivals(path, &a, pp)); } } YieldCurrentLock(thislock); return result; } /*******************************************************************/ /** Level */ /*******************************************************************/ static PromiseResult VerifyFileSystem(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp) { struct stat statbuf, localstat; Dir *dirh; const struct dirent *dirp; off_t sizeinbytes = 0; long filecount = 0; char buff[CF_BUFSIZE]; Log(LOG_LEVEL_VERBOSE, "Checking required filesystem %s", name); if (stat(name, &statbuf) == -1) { return PROMISE_RESULT_NOOP; } if (S_ISLNK(statbuf.st_mode)) { PromiseResult result = PROMISE_RESULT_NOOP; KillGhostLink(ctx, name, a, pp, &result); return result; } PromiseResult result = PROMISE_RESULT_NOOP; if (S_ISDIR(statbuf.st_mode)) { if ((dirh = DirOpen(name)) == NULL) { Log(LOG_LEVEL_ERR, "Can't open directory '%s' which checking required/disk. (opendir: %s)", name, GetErrorStr()); return PROMISE_RESULT_NOOP; } for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!ConsiderLocalFile(dirp->d_name, name)) { continue; } filecount++; strcpy(buff, name); if (buff[strlen(buff)] != FILE_SEPARATOR) { strcat(buff, FILE_SEPARATOR_STR); } strcat(buff, dirp->d_name); if (lstat(buff, &localstat) == -1) { if (S_ISLNK(localstat.st_mode)) { KillGhostLink(ctx, buff, a, pp, &result); continue; } Log(LOG_LEVEL_ERR, "Can't stat volume '%s'. (lstat: %s)", buff, GetErrorStr()); continue; } sizeinbytes += localstat.st_size; } DirClose(dirh); if (sizeinbytes < 0) { Log(LOG_LEVEL_ERR, "Internal error: count of byte size was less than zero!"); return result; } if (sizeinbytes < a->volume.sensible_size) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "File system '%s' is suspiciously small! (%jd bytes)", name, (intmax_t) sizeinbytes); return PROMISE_RESULT_INTERRUPTED; } if (filecount < a->volume.sensible_count) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "Filesystem '%s' has only %ld files/directories.", name, filecount); return PROMISE_RESULT_INTERRUPTED; } } cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_NOOP, pp, a, "Filesystem '%s' content seems to be sensible as promised", name); return result; } /*******************************************************************/ static PromiseResult VerifyFreeSpace(EvalContext *ctx, char *file, const Attributes *a, const Promise *pp) { struct stat statbuf; #ifdef __MINGW32__ if (!a->volume.check_foreign) { Log(LOG_LEVEL_VERBOSE, "storage.volume.check_foreign is not supported on Windows (checking every mount)"); } #endif /* __MINGW32__ */ if (stat(file, &statbuf) == -1) { Log(LOG_LEVEL_ERR, "Couldn't stat '%s' while checking diskspace. (stat: %s)", file, GetErrorStr()); return PROMISE_RESULT_NOOP; } #ifndef __MINGW32__ if (!a->volume.check_foreign) { if (IsForeignFileSystem(&statbuf, file)) { Log(LOG_LEVEL_INFO, "Filesystem '%s' is mounted from a foreign system, so skipping it", file); return PROMISE_RESULT_NOOP; } } #endif /* !__MINGW32__ */ if (a->volume.freespace < 0) { int threshold_percentage = -a->volume.freespace; int free_percentage = GetDiskUsage(file, CF_SIZE_PERCENT); if (free_percentage < threshold_percentage) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Free disk space is under %d%% for volume containing '%s', %d%% free", threshold_percentage, file, free_percentage); return PROMISE_RESULT_FAIL; } } else { off_t threshold = a->volume.freespace; off_t free_bytes = GetDiskUsage(file, CF_SIZE_ABS); if (free_bytes < threshold) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Disk space under %jd kB for volume containing '%s' (%jd kB free)", (intmax_t) (threshold / 1024), file, (intmax_t) (free_bytes / 1024)); return PROMISE_RESULT_FAIL; } } return PROMISE_RESULT_NOOP; } /*******************************************************************/ static PromiseResult VolumeScanArrivals(ARG_UNUSED char *file, ARG_UNUSED const Attributes *a, ARG_UNUSED const Promise *pp) { Log(LOG_LEVEL_VERBOSE, "Scan arrival sequence . not yet implemented"); return PROMISE_RESULT_NOOP; } /*******************************************************************/ /*********************************************************************/ /* Unix-specific implementations */ /*********************************************************************/ #if !defined(__MINGW32__) static bool FileSystemMountedCorrectly(Seq *list, char *name, const Attributes *a) { bool found = false; for (size_t i = 0; i < SeqLength(list); i++) { Mount *mp = SeqAt(list, i); if (mp == NULL) { continue; } /* Give primacy to the promised / affected object */ if (strcmp(name, mp->mounton) == 0) { /* We have found something mounted on the promiser dir */ found = true; if ((a->mount.mount_source) && (strcmp(mp->source, a->mount.mount_source) != 0)) { Log(LOG_LEVEL_INFO, "A different file system '%s:%s' is mounted on '%s' than what is promised", mp->host, mp->source, name); return false; } else { Log(LOG_LEVEL_VERBOSE, "File system '%s' seems to be mounted correctly", mp->source); break; } } } if (!found) { if (!a->mount.unmount) { Log(LOG_LEVEL_VERBOSE, "File system '%s' seems not to be mounted correctly", name); CF_MOUNTALL = true; } } return found; } /*********************************************************************/ /* Mounting */ /*********************************************************************/ static bool IsForeignFileSystem(struct stat *childstat, char *dir) // Is file system NFS / PanFS / CIFS mounted ? { struct stat parentstat; char vbuff[CF_BUFSIZE]; strlcpy(vbuff, dir, CF_BUFSIZE); if (vbuff[strlen(vbuff) - 1] == FILE_SEPARATOR) { strcat(vbuff, ".."); } else { strcat(vbuff, FILE_SEPARATOR_STR); strcat(vbuff, ".."); } if (stat(vbuff, &parentstat) == -1) { Log(LOG_LEVEL_VERBOSE, "Unable to stat '%s'. (stat: %s)", vbuff, GetErrorStr()); return false; } if (childstat->st_dev != parentstat.st_dev) { Log(LOG_LEVEL_DEBUG, "'%s' is on a different file system, not descending", dir); for (size_t i = 0; i < SeqLength(GetGlobalMountedFSList()); i++) { Mount *entry = SeqAt(GetGlobalMountedFSList(), i); if (!strcmp(entry->mounton, dir)) { if ((entry->options != NULL) && ((strstr(entry->options, "nfs") != NULL) || (strstr(entry->options, "panfs") != NULL) || (strstr(entry->options, "cifs") != NULL))) { return true; } } } } return false; } static PromiseResult VerifyMountPromise(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp) { char *options; char dir[CF_BUFSIZE]; int changes = 0; Log(LOG_LEVEL_VERBOSE, "Verifying mounted file systems on '%s'", name); snprintf(dir, CF_BUFSIZE, "%s/.", name); if (!IsPrivileged()) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "Only root can mount filesystems"); return PROMISE_RESULT_INTERRUPTED; } options = Rlist2String(a->mount.mount_options, ","); PromiseResult result = PROMISE_RESULT_NOOP; if (!FileSystemMountedCorrectly(GetGlobalMountedFSList(), name, a)) { if (!a->mount.unmount) { if (!MakeParentDirectory(dir, a->move_obstructions, NULL)) { // Could not create parent directory, assume this is okay, // verbose logging in MakeParentDirectory() Log(LOG_LEVEL_DEBUG, "Could not create parent directory '%s' for mount promise", dir); } if (a->mount.editfstab) { changes += VerifyInFstab(ctx, name, a, pp, &result); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Filesystem '%s' was not mounted as promised, and no edits were promised in '%s'", name, VFSTAB[VSYSTEMHARDCLASS]); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); // Mount explicitly result = PromiseResultUpdate(result, VerifyMount(ctx, name, a, pp)); } } else { if (a->mount.editfstab) { changes += VerifyNotInFstab(ctx, name, a, pp, &result); } } if (changes > 0) { CF_MOUNTALL = true; } } else { if (a->mount.unmount) { VerifyUnmount(ctx, name, a, pp); if (a->mount.editfstab) { VerifyNotInFstab(ctx, name, a, pp, &result); } } else { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_NOOP, pp, a, "Filesystem '%s' seems to be mounted as promised", name); } } free(options); return result; } #endif /* !__MINGW32__ */ void DeleteStorageContext(void) { #ifndef __MINGW32__ CleanupNFS(); if (!DONTDO && CF_MOUNTALL) { Log(LOG_LEVEL_VERBOSE, "Mounting all filesystems"); MountAll(); } #endif /* !__MINGW32__ */ } cfengine-3.24.2/cf-agent/cf-agent.c0000644000000000000000000022627515010704253016705 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* ConnCache_Init,ConnCache_Destroy */ #include #include #include #include #include #include /* CheckDBRepairFlagFile() */ #include /* checking umask on writing setxid log */ #include /* checking umask on writing setxid log */ #include /* ManifestChangedFiles(), DiffChangedFiles() */ #include #include /* IsBuiltInPromiseType() */ #include #include /* EvaluateCustomPromise(), Intialize/FinalizeCustomPromises() */ #ifdef HAVE_AVAHI_CLIENT_CLIENT_H #ifdef HAVE_AVAHI_COMMON_ADDRESS_H #include #endif #endif #include extern int PR_KEPT; extern int PR_REPAIRED; extern int PR_NOTKEPT; static bool ALLCLASSESREPORT = false; /* GLOBAL_P */ static bool ALWAYS_VALIDATE = false; /* GLOBAL_P */ static bool CFPARANOID = false; /* GLOBAL_P */ static bool PERFORM_DB_CHECK = false; static const Rlist *ACCESSLIST = NULL; /* GLOBAL_P */ static int CFA_BACKGROUND = 0; /* GLOBAL_X */ static int CFA_BACKGROUND_LIMIT = 1; /* GLOBAL_P */ static Item *PROCESSREFRESH = NULL; /* GLOBAL_P */ static const char *const AGENT_TYPESEQUENCE[] = { "meta", "vars", "defaults", "classes", /* Maelstrom order 2 */ "users", "files", "packages", "guest_environments", "methods", "processes", "services", "commands", "storage", "databases", "reports", NULL }; /*******************************************************************/ /* Agent specific variables */ /*******************************************************************/ static void ThisAgentInit(void); static GenericAgentConfig *CheckOpts(int argc, char **argv); static char **TranslateOldBootstrapOptionsSeparate(int *argc_new, char **argv); static char **TranslateOldBootstrapOptionsConcatenated(int argc, char **argv); static void FreeFixedStringArray(int size, char **array); static void CheckAgentAccess(const Rlist *list, const Policy *policy); static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config); static PromiseResult KeepAgentPromise(EvalContext *ctx, const Promise *pp, void *param); static void NewTypeContext(TypeSequence type); static void DeleteTypeContext(EvalContext *ctx, TypeSequence type); static PromiseResult ParallelFindAndVerifyFilesPromises(EvalContext *ctx, const Promise *pp); static bool VerifyBootstrap(bool skip_cf_execd_check); static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config); static void KeepPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config); static int NoteBundleCompliance(const Bundle *bundle, int save_pr_kept, int save_pr_repaired, int save_pr_notkept, struct timespec start); static void AllClassesReport(const EvalContext *ctx); static bool HasAvahiSupport(void); static int AutomaticBootstrap(GenericAgentConfig *config); static void BannerStatus(PromiseResult status, const char *type, char *name); static PromiseResult DefaultVarPromise(EvalContext *ctx, const Promise *pp); static void WaitForBackgroundProcesses(); /*******************************************************************/ /* Command line options */ /*******************************************************************/ static const char *const CF_AGENT_SHORT_DESCRIPTION = "evaluate CFEngine policy code and actuate change to the system."; static const char *const CF_AGENT_MANPAGE_LONG_DESCRIPTION = "cf-agent evaluates policy code and makes changes to the system. Policy bundles are evaluated in the order of the " "provided bundlesequence (this is normally specified in the common control body). " "For each bundle, cf-agent groups promise statements according to their type. Promise types are then evaluated in a preset " "order to ensure fast system convergence to policy.\n"; static const Component COMPONENT = { .name = "cf-agent", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const struct option OPTIONS[] = { {"bootstrap", required_argument, 0, 'B'}, {"bundlesequence", required_argument, 0, 'b'}, {"workdir", required_argument, 0, 'w'}, {"debug", no_argument, 0, 'd'}, {"define", required_argument, 0, 'D'}, {"self-diagnostics", optional_argument, 0, 'x'}, {"dry-run", no_argument, 0, 'n'}, {"file", required_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, {"inform", no_argument, 0, 'I'}, {"log-level", required_argument, 0, 'g'}, {"negate", required_argument, 0, 'N'}, {"no-lock", no_argument, 0, 'K'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"timing-output", no_argument, 0, 't'}, {"trust-server", optional_argument, 0, 'T'}, {"color", optional_argument, 0, 'C'}, {"no-extensions", no_argument, 0, 'E'}, {"timestamp", no_argument, 0, 'l'}, /* Only long option for the rest */ {"ignore-preferred-augments", no_argument, 0, 0}, {"log-modules", required_argument, 0, 0}, {"no-augments", no_argument, 0, 0}, {"no-host-specific-data", no_argument, 0, 0}, {"show-evaluated-classes", optional_argument, 0, 0 }, {"show-evaluated-vars", optional_argument, 0, 0 }, {"skip-bootstrap-policy-run", no_argument, 0, 0 }, {"skip-bootstrap-service-start", no_argument, 0, 0 }, {"skip-db-check", optional_argument, 0, 0 }, {"simulate", required_argument, 0, 0}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Bootstrap CFEngine to the given policy server IP, hostname or :avahi (automatic detection)", "Set or override bundlesequence from command line", "Override the default /var/cfengine work directory for testing (same as setting CFENGINE_TEST_OVERRIDE_WORKDIR)", "Enable debugging output", "Define a list of comma separated classes to be defined at the start of execution", "Run checks to diagnose a CFEngine agent installation", "All talk and no action mode - make no changes, only inform of promises not kept", "Specify an alternative input file than the default. This option is overridden by FILE if supplied as argument.", "Print the help message", "Print basic information about changes made to the system, i.e. promises repaired", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Define a list of comma separated classes to be undefined at the start of execution", "Ignore locking constraints during execution (ifelapsed/expireafter) if \"too soon\" to run", "Output verbose information about the behaviour of the agent", "Output the version of the software", "Output timing information on console when in verbose mode", "Possible values: 'yes' (default, trust the server when bootstrapping), 'no' (server key must already be trusted)", "Enable colorized output. Possible values: 'always', 'auto', 'never'. If option is used, the default value is 'auto'", "Disable extension loading (used while upgrading)", "Log timestamps on each line of log output", "Ignore def_preferred.json file in favor of def.json", "Enable even more detailed debug logging for specific areas of the implementation. Use together with '-d'. Use --log-modules=help for a list of available modules", "Do not load augments (def.json)", "Do not load host-specific data (host_specific.json)", "Show *final* evaluated classes, including those defined in common bundles in policy. Optionally can take a regular expression.", "Show *final* evaluated variables, including those defined without dependency to user-defined classes in policy. Optionally can take a regular expression.", "Do not run policy as the last step of the bootstrap process", "Do not start CFEngine services as part of the bootstrap process", "Do not run database integrity checks and repairs at startup", "Run in simulate mode, either 'manifest', 'manifest-full' or 'diff'", NULL }; /** @brief Wrapper around DefaultVarPromise to silence cast-function-type compiler warning in ScheduleAgentOperations */ static PromiseResult DefaultVarPromiseWrapper(EvalContext *ctx, const Promise *pp, void *param) { UNUSED(param); return DefaultVarPromise(ctx, pp); } /*******************************************************************/ int main(int argc, char *argv[]) { SetupSignalsForAgent(); #ifdef HAVE_LIBXML2 xmlInitParser(); #endif struct timespec start = BeginMeasure(); GenericAgentConfig *config = CheckOpts(argc, argv); bool force_repair = CheckDBRepairFlagFile(); if (force_repair || PERFORM_DB_CHECK) { repair_lmdb_default(force_repair); } EvalContext *ctx = EvalContextNew(); // Enable only for cf-agent eval context. EvalContextAllClassesLoggingEnable(ctx, true); GenericAgentConfigApply(ctx, config); const char *program_invocation_name = argv[0]; const char *last_dir_sep = strrchr(program_invocation_name, FILE_SEPARATOR); const char *program_name = (last_dir_sep != NULL ? last_dir_sep + 1 : program_invocation_name); GenericAgentDiscoverContext(ctx, config, program_name); /* FIXME: (CFE-2709) ALWAYS_VALIDATE will always be false here, since it can * only change in KeepPromises(), five lines later on. */ Policy *policy = SelectAndLoadPolicy(config, ctx, ALWAYS_VALIDATE, true); if (!policy) { Log(LOG_LEVEL_ERR, "Error reading CFEngine policy. Exiting..."); DoCleanupAndExit(EXIT_FAILURE); } if ((config->agent_specific.agent.bootstrap_argument != NULL) && config->agent_specific.agent.skip_bootstrap_service_start && !EvalContextClassPutHard(ctx, "bootstrap_skip_services", "source=environment")) { Log(LOG_LEVEL_ERR, "Failed to define the 'bootstrap_skip_services' class"); /* not a fatal issue, let's continue the bootstrap process */ } int ret = 0; GenericAgentPostLoadInit(ctx); ThisAgentInit(); ConnCache_Init(); BeginAudit(); KeepPromises(ctx, policy, config); if (EvalAborted(ctx)) { ret = EC_EVAL_ABORTED; } ConnCache_Destroy(); if (ALLCLASSESREPORT) { AllClassesReport(ctx); } Nova_TrackExecution(config->input_file); /* Update packages cache. */ UpdatePackagesCache(ctx, false); /* Finalize custom promises before waiting for background processes because * they can be background processes and need special handling. */ FinalizeCustomPromises(); /* Wait for background processes before generating reports because * GenerateReports() does nothing if it detects multiple cf-agent processes * running. */ WaitForBackgroundProcesses(); GenerateReports(config, ctx); PurgeLocks(); BackupLockDatabase(); if (config->agent_specific.agent.show_evaluated_classes != NULL) { GenericAgentShowContextsFormatted(ctx, config->agent_specific.agent.show_evaluated_classes); free(config->agent_specific.agent.show_evaluated_classes); } if (config->agent_specific.agent.show_evaluated_variables != NULL) { GenericAgentShowVariablesFormatted(ctx, config->agent_specific.agent.show_evaluated_variables); free(config->agent_specific.agent.show_evaluated_variables); } PolicyDestroy(policy); /* Can we safely do this earlier ? */ if (config->agent_specific.agent.bootstrap_argument && !VerifyBootstrap(config->agent_specific.agent.skip_bootstrap_service_start)) { PolicyServerRemoveFile(GetWorkDir()); WriteAmPolicyHubFile(false); ret = 1; } EndAudit(ctx, CFA_BACKGROUND); Nova_NoteAgentExecutionPerformance(config->input_file, start); GenericAgentFinalize(ctx, config); StringSetDestroy(SINGLE_COPY_CACHE); StringSet *audited_files = NULL; if ((EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST) || (EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST_FULL)) { bool success = ManifestChangedFiles(&audited_files); if (!success) { Log(LOG_LEVEL_ERR, "Failed to manifest changed files"); } if (EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST_FULL) { /* Skips the files already manifested above. */ success = ManifestAllFiles(&audited_files); if (!success) { Log(LOG_LEVEL_ERR, "Failed to manifest unmodified files"); } } success = ManifestPkgOperations(); if (!success) { Log(LOG_LEVEL_ERR, "Failed to manifest present and absent packages"); } } else if (EVAL_MODE == EVAL_MODE_SIMULATE_DIFF) { bool success = DiffChangedFiles(&audited_files); if (!success) { Log(LOG_LEVEL_ERR, "Failed to show differences for changed files"); } success = DiffPkgOperations(); if (!success) { Log(LOG_LEVEL_ERR, "Failed to show differences in installed packages"); } } StringSetDestroy(audited_files); #ifdef HAVE_LIBXML2 xmlCleanupParser(); #endif CallCleanupFunctions(); return ret; } /*******************************************************************/ /* Level 1 */ /*******************************************************************/ static void ConfigureBootstrap(GenericAgentConfig *config, const char *argument) { assert(config != NULL); if (!BootstrapAllowed()) { Log(LOG_LEVEL_ERR, "Not enough privileges to bootstrap CFEngine"); DoCleanupAndExit(EXIT_FAILURE); } if(strcmp(optarg, ":avahi") == 0) { if(!HasAvahiSupport()) { Log(LOG_LEVEL_ERR, "Avahi support is not built in, please see options to the configure script and rebuild CFEngine"); DoCleanupAndExit(EXIT_FAILURE); } int err = AutomaticBootstrap(config); if (err < 0) { Log(LOG_LEVEL_ERR, "Automatic bootstrap failed, error code '%d'", err); DoCleanupAndExit(EXIT_FAILURE); } return; } if(StringEqual(argument, "localhost") || StringIsLocalHostIP(argument)) { Log(LOG_LEVEL_WARNING, "Bootstrapping to loopback interface (localhost), other hosts will not be able to bootstrap to this server"); } // temporary assure that network functions are working OpenNetwork(); config->agent_specific.agent.bootstrap_argument = xstrdup(argument); char *host, *port; ParseHostPort(optarg, &host, &port); char ipaddr[CF_MAX_IP_LEN] = ""; if (Hostname2IPString(ipaddr, host,sizeof(ipaddr)) == -1) { Log(LOG_LEVEL_ERR, "Could not resolve hostname '%s', unable to bootstrap", host); DoCleanupAndExit(EXIT_FAILURE); } CloseNetwork(); MINUSF = true; config->ignore_locks = true; GenericAgentConfigSetInputFile(config, GetInputDir(), "promises.cf"); config->agent_specific.agent.bootstrap_ip = xstrdup(ipaddr); config->agent_specific.agent.bootstrap_host = xstrdup(host); if (port == NULL) { config->agent_specific.agent.bootstrap_port = NULL; } else { config->agent_specific.agent.bootstrap_port = xstrdup(port); } } static GenericAgentConfig *CheckOpts(int argc, char **argv) { extern char *optarg; int c; GenericAgentConfig *config = GenericAgentConfigNewDefault(AGENT_TYPE_AGENT, GetTTYInteractive()); bool option_trust_server = false; ; /* DEPRECATED: --policy-server (-s) is deprecated in community version 3.5.0. Support rewrite from some common old bootstrap options (until community version 3.6.0?). */ int argc_new = argc; char **argv_tmp = TranslateOldBootstrapOptionsSeparate(&argc_new, argv); char **argv_new = TranslateOldBootstrapOptionsConcatenated(argc_new, argv_tmp); FreeFixedStringArray(argc_new, argv_tmp); int longopt_idx; while ((c = getopt_long(argc_new, argv_new, "tdvnKIf:g:w:D:N:VxMB:b:hC::ElT::", OPTIONS, &longopt_idx)) != -1) { switch (c) { case 't': TIMING = true; break; case 'w': Log(LOG_LEVEL_INFO, "Setting workdir to '%s'", optarg); setenv_wrapper("CFENGINE_TEST_OVERRIDE_WORKDIR", optarg, 1); break; case 'f': GenericAgentConfigSetInputFile(config, GetInputDir(), optarg); MINUSF = true; break; case 'b': if (optarg) { Rlist *bundlesequence = RlistFromSplitString(optarg, ','); GenericAgentConfigSetBundleSequence(config, bundlesequence); RlistDestroy(bundlesequence); } break; case 'd': LogSetGlobalLevel(LOG_LEVEL_DEBUG); break; case 'B': { ConfigureBootstrap(config, optarg); } break; case 'K': config->ignore_locks = true; break; case 'D': { StringSet *defined_classes = StringSetFromString(optarg, ','); if (! config->heap_soft) { config->heap_soft = defined_classes; } else { StringSetJoin(config->heap_soft, defined_classes, xstrdup); StringSetDestroy(defined_classes); } } break; case 'N': { StringSet *negated_classes = StringSetFromString(optarg, ','); if (! config->heap_negated) { config->heap_negated = negated_classes; } else { StringSetJoin(config->heap_negated, negated_classes, xstrdup); StringSetDestroy(negated_classes); } } break; case 'I': LogSetGlobalLevel(LOG_LEVEL_INFO); break; case 'v': LogSetGlobalLevel(LOG_LEVEL_VERBOSE); break; case 'g': LogSetGlobalLevelArgOrExit(optarg); break; case 'n': EVAL_MODE = EVAL_MODE_DRY_RUN; config->ignore_locks = true; break; case 'V': { Writer *w = FileWriter(stdout); GenericAgentWriteVersion(w); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'h': { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_SUCCESS); case 'M': { Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-agent", time(NULL), CF_AGENT_SHORT_DESCRIPTION, CF_AGENT_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(out); DoCleanupAndExit(EXIT_SUCCESS); } case 'x': { const char *workdir = GetWorkDir(); const char *inputdir = GetInputDir(); const char *logdir = GetLogDir(); const char *statedir = GetStateDir(); Writer *out = FileWriter(stdout); WriterWriteF(out, "self-diagnostics for agent using workdir '%s'\n", workdir); WriterWriteF(out, "self-diagnostics for agent using inputdir '%s'\n", inputdir); WriterWriteF(out, "self-diagnostics for agent using logdir '%s'\n", logdir); WriterWriteF(out, "self-diagnostics for agent using statedir '%s'\n", statedir); AgentDiagnosticsRun(workdir, AgentDiagnosticsAllChecks(), out); AgentDiagnosticsRunAllChecksNova(workdir, out, &AgentDiagnosticsRun, &AgentDiagnosticsResultNew); FileWriterDetach(out); } DoCleanupAndExit(EXIT_SUCCESS); case 'C': if (!GenericAgentConfigParseColor(config, optarg)) { DoCleanupAndExit(EXIT_FAILURE); } break; case 'E': extension_libraries_disable(); break; case 'l': LoggingEnableTimestamps(true); break; case 'T': option_trust_server = true; /* If the argument is missing, we trust by default. */ if (optarg == NULL || strcmp(optarg, "yes") == 0) { config->agent_specific.agent.bootstrap_trust_server = true; } else { config->agent_specific.agent.bootstrap_trust_server = false; } break; /* long options only */ case 0: { const char *const option_name = OPTIONS[longopt_idx].name; if (StringEqual(option_name, "ignore-preferred-augments")) { config->ignore_preferred_augments = true; } else if (StringEqual(option_name, "log-modules")) { bool ret = LogEnableModulesFromString(optarg); if (!ret) { DoCleanupAndExit(EXIT_FAILURE); } } else if (StringEqual(option_name, "no-augments")) { config->agent_specific.common.no_augments = true; } else if (StringEqual(option_name, "no-host-specific-data")) { config->agent_specific.common.no_host_specific = true; } else if (StringEqual(option_name, "show-evaluated-classes")) { if (optarg == NULL) { optarg = ".*"; } config->agent_specific.agent.show_evaluated_classes = xstrdup(optarg); } else if (StringEqual(option_name, "show-evaluated-vars")) { if (optarg == NULL) { optarg = ".*"; } config->agent_specific.agent.show_evaluated_variables = xstrdup(optarg); } else if (StringEqual(option_name, "skip-bootstrap-policy-run")) { config->agent_specific.agent.bootstrap_trigger_policy = false; } else if (StringEqual(option_name, "skip-bootstrap-service-start")) { config->agent_specific.agent.skip_bootstrap_service_start = true; } else if (StringEqual(option_name, "skip-db-check")) { if (optarg == NULL) { PERFORM_DB_CHECK = false; // Skip (no arg), check = false } else if (StringEqual_IgnoreCase(optarg, "yes")) { PERFORM_DB_CHECK = false; // Skip = yes, check = false } else if (StringEqual_IgnoreCase(optarg, "no")) { PERFORM_DB_CHECK = true; // Skip = no, check = true } else { Log(LOG_LEVEL_ERR, "Invalid argument for --skip-db-check(yes/no): '%s'", optarg); DoCleanupAndExit(EXIT_FAILURE); } } else if (StringEqual(option_name, "simulate")) { if (optarg == NULL) { Log(LOG_LEVEL_ERR, "Missing argument for --simulate, 'manifest', 'manifest-full', or 'diff' required"); DoCleanupAndExit(EXIT_FAILURE); } else if (StringEqual_IgnoreCase(optarg, "manifest")) { EVAL_MODE = EVAL_MODE_SIMULATE_MANIFEST; } else if (StringEqual_IgnoreCase(optarg, "manifest-full")) { EVAL_MODE = EVAL_MODE_SIMULATE_MANIFEST_FULL; } else if (StringEqual_IgnoreCase(optarg, "diff")) { EVAL_MODE = EVAL_MODE_SIMULATE_DIFF; } else { Log(LOG_LEVEL_ERR, "Invalid argument for --simulate, 'manifest' or 'diff' required, not '%s'", optarg); DoCleanupAndExit(EXIT_FAILURE); } } break; } default: { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, NULL, false, true); FileWriterDetach(w); } DoCleanupAndExit(EXIT_FAILURE); } } if (!GenericAgentConfigParseArguments(config, argc_new - optind, argv_new + optind)) { Log(LOG_LEVEL_ERR, "Too many arguments"); DoCleanupAndExit(EXIT_FAILURE); } if (option_trust_server && config->agent_specific.agent.bootstrap_argument == NULL) { Log(LOG_LEVEL_ERR, "Option --trust-server can only be used when bootstrapping"); DoCleanupAndExit(EXIT_FAILURE); } FreeFixedStringArray(argc_new, argv_new); return config; } static char **TranslateOldBootstrapOptionsSeparate(int *argc_new, char **argv) { int i; int policy_server_argnum = 0; int server_address_argnum = 0; int bootstrap_argnum = 0; int argc = *argc_new; for(i = 0; i < argc; i++) { if(strcmp(argv[i], "--policy-server") == 0 || strcmp(argv[i], "-s") == 0) { policy_server_argnum = i; } if(strcmp(argv[i], "--bootstrap") == 0 || strcmp(argv[i], "-B") == 0) { bootstrap_argnum = i; } } if(policy_server_argnum > 0) { if(policy_server_argnum + 1 < argc) { server_address_argnum = policy_server_argnum + 1; } } char **argv_new; if(bootstrap_argnum > 0 && server_address_argnum > 0) { Log(LOG_LEVEL_WARNING, "Deprecated bootstrap options detected. The --policy-server (-s) option is deprecated from CFEngine community version 3.5.0." "Please provide the address argument to --bootstrap (-B) instead. Rewriting your arguments now, but you need to adjust them as this support will be removed soon."); *argc_new = argc - 1; // --policy-server deprecated argv_new = xcalloc(1, sizeof(char *) * (*argc_new + 1)); int new_i = 0; for(i = 0; i < argc; i++) { if(i == bootstrap_argnum) { argv_new[new_i++] = xstrdup(argv[bootstrap_argnum]); argv_new[new_i++] = xstrdup(argv[server_address_argnum]); } else if(i == server_address_argnum) { // skip: handled above } else if(i == policy_server_argnum) { // skip: deprecated } else { argv_new[new_i++] = xstrdup(argv[i]); } } } else { argv_new = xcalloc(1, sizeof(char *) * (*argc_new + 1)); for(i = 0; i < argc; i++) { argv_new[i] = xstrdup(argv[i]); } } return argv_new; } static char **TranslateOldBootstrapOptionsConcatenated(int argc, char **argv) { char **argv_new = xcalloc(1, sizeof(char *) * (argc + 1)); for(int i = 0; i < argc; i++) { if(strcmp(argv[i], "-Bs") == 0) { Log(LOG_LEVEL_WARNING, "Deprecated bootstrap options detected. The --policy-server (-s) option is deprecated from CFEngine community version 3.5.0." "Please provide the address argument to --bootstrap (-B) instead. Rewriting your arguments now, but you need to adjust them as this support will be removed soon."); argv_new[i] = xstrdup("-B"); } else { argv_new[i] = xstrdup(argv[i]); } } return argv_new; } static void FreeFixedStringArray(int size, char **array) { for(int i = 0; i < size; i++) { free(array[i]); } free(array); } /*******************************************************************/ static void ThisAgentInit(void) { char filename[CF_BUFSIZE]; #ifdef HAVE_SETSID setsid(); #endif CFA_MAXTHREADS = 30; EDITFILESIZE = 100000; /* do not set signal(SIGCHLD,SIG_IGN) in agent near popen() - or else pclose will fail to return status which we need for setting returns */ snprintf(filename, CF_BUFSIZE, "%s/cfagent.%s.log", GetLogDir(), VSYSNAME.nodename); ToLowerStrInplace(filename); MapName(filename); const mode_t current_umask = umask(0777); // Gets and changes umask umask(current_umask); // Restores umask Log(LOG_LEVEL_DEBUG, "Current umask is %o", current_umask); FILE *fp = safe_fopen(filename, "a"); if (fp != NULL) { fclose(fp); } InitializeCustomPromises(); } /*******************************************************************/ static void KeepPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config) { KeepControlPromises(ctx, policy, config); /* Check if 'abortclasses' aborted evaluation or not. */ if (EvalAborted(ctx)) { return; } KeepPromiseBundles(ctx, policy, config); } /*******************************************************************/ /* Level 2 */ /*******************************************************************/ static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config) { Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_AGENT); if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } if (CommonControlFromString(cp->lval) != COMMON_CONTROL_MAX) { /* Already handled in generic_agent */ continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_agent"); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); /* If var not found */ if (value_type == CF_DATA_TYPE_NONE) { Log(LOG_LEVEL_ERR, "Unknown lval '%s' in agent control body", cp->lval); continue; } /* 'files_single_copy => { }' is a perfectly valid case. */ if (StringEqual(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_FSINGLECOPY].lval)) { assert(value_type == CF_DATA_TYPE_STRING_LIST); SINGLE_COPY_LIST = value; SINGLE_COPY_CACHE = StringSetNew(); if (WouldLog(LOG_LEVEL_VERBOSE)) { char *rlist_str = RlistToString(SINGLE_COPY_LIST); Log(LOG_LEVEL_VERBOSE, "Setting file single copy list to: %s", rlist_str); free(rlist_str); } continue; } /* Empty list is not supported for the other constraints/attributes. */ if (value == NULL) { Log(LOG_LEVEL_ERR, "Empty list is not a valid value for '%s' attribute in agent control body", cp->lval); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_MAXCONNECTIONS].lval) == 0) { CFA_MAXTHREADS = (int) IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting maxconnections to %d", CFA_MAXTHREADS); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_CHECKSUM_ALERT_TIME].lval) == 0) { CF_PERSISTENCE = (int) IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting checksum_alert_time to %d", CF_PERSISTENCE); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_AGENTFACILITY].lval) == 0) { SetFacility(value); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_AGENTACCESS].lval) == 0) { ACCESSLIST = value; CheckAgentAccess(ACCESSLIST, policy); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_COPYFROM_RESTRICT_KEYS].lval) == 0) { EvalContextSetRestrictKeys(ctx, value); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REFRESH_PROCESSES].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "Setting refresh_processes when starting to..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { Log(LOG_LEVEL_VERBOSE, "%s", RlistScalarValue(rp)); // TODO: why is this only done in verbose mode? // original commit says 'optimization'. if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { PrependItem(&PROCESSREFRESH, RlistScalarValue(rp), NULL); } } continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ABORTCLASSES].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "Setting abort classes from ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { char name[CF_MAXVARSIZE] = ""; strlcpy(name, RlistScalarValue(rp), CF_MAXVARSIZE); EvalContextHeapAddAbort(ctx, name, cp->classes); } continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ABORTBUNDLECLASSES].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "Setting abort bundle classes from ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { char name[CF_MAXVARSIZE] = ""; strlcpy(name, RlistScalarValue(rp), CF_MAXVARSIZE); EvalContextHeapAddAbortCurrentBundle(ctx, name, cp->classes); } continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ADDCLASSES].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "Add classes ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { Log(LOG_LEVEL_VERBOSE, "... %s", RlistScalarValue(rp)); EvalContextClassPutSoft(ctx, RlistScalarValue(rp), CONTEXT_SCOPE_NAMESPACE, "source=environment"); } continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ALWAYSVALIDATE].lval) == 0) { ALWAYS_VALIDATE = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting alwaysvalidate to '%s'", ALWAYS_VALIDATE ? "true" : "false"); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ALLCLASSESREPORT].lval) == 0) { ALLCLASSESREPORT = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting allclassesreport to '%s'", ALLCLASSESREPORT ? "true" : "false"); } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_SECUREINPUT].lval) == 0) { CFPARANOID = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting secure input to '%s'", CFPARANOID ? "true" : "false"); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_BINDTOINTERFACE].lval) == 0) { SetBindInterface(value); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_HASHUPDATES].lval) == 0) { bool enabled = BooleanFromString(value); SetChecksumUpdatesDefault(ctx, enabled); Log(LOG_LEVEL_VERBOSE, "Setting checksum updates to '%s'", enabled ? "true" : "false"); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_CHILDLIBPATH].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "Setting 'LD_LIBRARY_PATH=%s'", (const char *)value); setenv_wrapper("LD_LIBRARY_PATH", value, 1); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_DEFAULTCOPYTYPE].lval) == 0) { DEFAULT_COPYTYPE = value; Log(LOG_LEVEL_VERBOSE, "Setting defaultcopytype to '%s'", DEFAULT_COPYTYPE); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_FAUTODEFINE].lval) == 0) { SetFileAutoDefineList(value); Log(LOG_LEVEL_VERBOSE, "Setting file auto define list"); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_DRYRUN].lval) == 0) { EVAL_MODE = BooleanFromString(value) ? EVAL_MODE_DRY_RUN : EVAL_MODE_NORMAL; Log(LOG_LEVEL_VERBOSE, "Setting dryrun to %d", DONTDO); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_INFORM].lval) == 0) { bool inform = BooleanFromString(value); if (inform) { LogSetGlobalLevel(MAX(LOG_LEVEL_INFO, LogGetGlobalLevel())); } else { if (LogGetGlobalLevel() >= LOG_LEVEL_INFO) { LogSetGlobalLevel(LOG_LEVEL_NOTICE); } } Log(LOG_LEVEL_VERBOSE, "body agent control, inform => '%s', sets new log level to '%s'", inform ? "true" : "false", LogLevelToString(LogGetGlobalLevel())); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_VERBOSE].lval) == 0) { bool verbose = BooleanFromString(value); if (verbose) { LogSetGlobalLevel(MAX(LOG_LEVEL_VERBOSE, LogGetGlobalLevel())); } else { if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { LogSetGlobalLevel(LOG_LEVEL_INFO); } } Log(LOG_LEVEL_VERBOSE, "body agent control, verbose => '%s', sets new log level to '%s'", verbose ? "true" : "false", LogLevelToString(LogGetGlobalLevel())); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REPOSITORY].lval) == 0) { SetRepositoryLocation(value); Log(LOG_LEVEL_VERBOSE, "Setting repository to '%s'", (const char *)value); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_SKIPIDENTIFY].lval) == 0) { bool enabled = BooleanFromString(value); SetSkipIdentify(enabled); Log(LOG_LEVEL_VERBOSE, "Setting skipidentify to '%s'", enabled ? "true" : "false"); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_SUSPICIOUSNAMES].lval) == 0) { for (const Rlist *rp = value; rp != NULL; rp = rp->next) { AddFilenameToListOfSuspicious(RlistScalarValue(rp)); Log(LOG_LEVEL_VERBOSE, "Considering '%s' as suspicious file", RlistScalarValue(rp)); } continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REPCHAR].lval) == 0) { char c = *(char *)value; SetRepositoryChar(c); Log(LOG_LEVEL_VERBOSE, "Setting repchar to '%c'", c); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_MOUNTFILESYSTEMS].lval) == 0) { CF_MOUNTALL = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting mountfilesystems to '%s'", CF_MOUNTALL ? "true" : "false"); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_EDITFILESIZE].lval) == 0) { EDITFILESIZE = IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting edit file size to %d", EDITFILESIZE); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_IFELAPSED].lval) == 0) { VIFELAPSED = IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting ifelapsed to %d", VIFELAPSED); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_EXPIREAFTER].lval) == 0) { VEXPIREAFTER = IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting expireafter to %d", VEXPIREAFTER); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_TIMEOUT].lval) == 0) { CONNTIMEOUT = IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting timeout to %jd", (intmax_t) CONNTIMEOUT); continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_MAX_CHILDREN].lval) == 0) { CFA_BACKGROUND_LIMIT = IntFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting max_children to %d", CFA_BACKGROUND_LIMIT); if (CFA_BACKGROUND_LIMIT > 10) { Log(LOG_LEVEL_ERR, "Silly value for max_children in agent control promise (%d > 10)", CFA_BACKGROUND_LIMIT); CFA_BACKGROUND_LIMIT = 1; } continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_ENVIRONMENT].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "Setting environment variables from ..."); for (const Rlist *rp = value; rp != NULL; rp = rp->next) { assert(strchr(RlistScalarValue(rp), '=')); /* Valid for putenv() */ if (putenv_wrapper(RlistScalarValue(rp)) != 0) { Log(LOG_LEVEL_ERR, "Failed to set environment variable '%s'. (putenv: %s)", RlistScalarValue(rp), GetErrorStr()); } } continue; } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_SELECT_END_MATCH_EOF].lval) == 0) { Log(LOG_LEVEL_VERBOSE, "SET select_end_match_eof %s", (char *) value); EvalContextSetSelectEndMatchEof(ctx, BooleanFromString(value)); } if (strcmp(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_REPORTCLASSLOG].lval) == 0) { config->agent_specific.agent.report_class_log = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting report_class_log to %s", config->agent_specific.agent.report_class_log? "true" : "false"); continue; } } } const void *value = NULL; if ((value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER))) { LASTSEENEXPIREAFTER = IntFromString(value) * 60; } if ((value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_FIPS_MODE))) { FIPS_MODE = BooleanFromString(value); Log(LOG_LEVEL_VERBOSE, "Setting FIPS mode to '%s'", FIPS_MODE ? "true" : "false"); } if ((value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_SYSLOG_PORT))) { SetSyslogPort(IntFromString(value)); Log(LOG_LEVEL_VERBOSE, "Setting syslog_port to '%s'", (const char *)value); } if ((value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_SYSLOG_HOST))) { /* Don't resolve syslog_host now, better do it per log request. */ if (!SetSyslogHost(value)) { Log(LOG_LEVEL_ERR, "Failed to set syslog_host to '%s', too long", (const char *)value); } else { Log(LOG_LEVEL_VERBOSE, "Setting syslog_host to '%s'", (const char *)value); } } if ((value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_BWLIMIT))) { double bval; if (DoubleFromString(value, &bval)) { bwlimit_kbytes = (uint32_t) ( bval / 1000.0); Log(LOG_LEVEL_VERBOSE, "Setting rate limit to %d kBytes/sec", bwlimit_kbytes); } } Nova_Initialize(ctx); // If not have been enabled above then should be disabled. // By default it's enabled to catch all set classes on startup stage // before this part of the policy is processed. if (!config->agent_specific.agent.report_class_log) { EvalContextAllClassesLoggingEnable(ctx, false); } } /*********************************************************************/ static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config) { Rlist *bundlesequence = NULL; Banner("Begin policy/promise evaluation"); if (config->bundlesequence != NULL) { Log(LOG_LEVEL_INFO, "Using command line specified bundlesequence"); bundlesequence = RlistCopy(config->bundlesequence); } else { bundlesequence = RlistCopy((Rlist *) EvalContextVariableControlCommonGet( ctx, COMMON_CONTROL_BUNDLESEQUENCE)); if (bundlesequence == NULL) { RlistAppendScalar(&bundlesequence, "main"); } } bool ok = true; for (const Rlist *rp = bundlesequence; rp; rp = rp->next) { const char *name = NULL; switch (rp->val.type) { case RVAL_TYPE_SCALAR: name = RlistScalarValue(rp); break; case RVAL_TYPE_FNCALL: name = RlistFnCallValue(rp)->name; break; default: name = NULL; { Writer *w = StringWriter(); WriterWrite(w, "Illegal item found in bundlesequence: "); RvalWrite(w, rp->val); Log(LOG_LEVEL_ERR, "%s", StringWriterData(w)); WriterClose(w); } ok = false; break; } if (!config->ignore_missing_bundles) { const Bundle *bp = EvalContextResolveBundleExpression(ctx, policy, name, "agent"); if (!bp) { bp = EvalContextResolveBundleExpression(ctx, policy, name, "common"); } if (!bp) { Log(LOG_LEVEL_ERR, "Bundle '%s' listed in the bundlesequence was not found", name); ok = false; } } } if (!ok) { FatalError(ctx, "Errors in agent bundles"); } Writer *w = StringWriter(); WriterWrite(w, "Using bundlesequence => "); RlistWrite(w, bundlesequence); Log(LOG_LEVEL_VERBOSE, "%s", StringWriterData(w)); WriterClose(w); /* If all is okay, go ahead and evaluate */ for (const Rlist *rp = bundlesequence; rp; rp = rp->next) { const char *name = NULL; const Rlist *args = NULL; if (rp->val.type == RVAL_TYPE_FNCALL) { name = RlistFnCallValue(rp)->name; args = RlistFnCallValue(rp)->args; } else { name = RlistScalarValue(rp); args = NULL; } EvalContextSetBundleArgs(ctx, args); const Bundle *bp = EvalContextResolveBundleExpression(ctx, policy, name, "agent"); if (!bp) { bp = EvalContextResolveBundleExpression(ctx, policy, name, "common"); } if (bp) { BundleBanner(bp,args); EvalContextStackPushBundleFrame(ctx, bp, args, false); ScheduleAgentOperations(ctx, bp); EvalContextStackPopFrame(ctx); EndBundleBanner(bp); if (EvalAborted(ctx)) { break; } } else { if (config->ignore_missing_bundles) { Log(LOG_LEVEL_VERBOSE, "Ignoring missing bundle '%s'", name); } else { FatalError(ctx, "Bundlesequence contained unknown bundle reference '%s'", name); } } } RlistDestroy(bundlesequence); } static void AllClassesReport(const EvalContext *ctx) { char context_report_file[CF_BUFSIZE]; snprintf(context_report_file, CF_BUFSIZE, "%s%callclasses.txt", GetStateDir(), FILE_SEPARATOR); FILE *fp = safe_fopen(context_report_file, "w"); if (fp == NULL) { Log(LOG_LEVEL_INFO, "Could not open allclasses cache file '%s' (fopen: %s)", context_report_file, GetErrorStr()); } else { Writer *writer = FileWriter(fp); ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true); Class *cls = NULL; while ((cls = ClassTableIteratorNext(iter))) { char *expr = ClassRefToString(cls->ns, cls->name); WriterWriteF(writer, "%s\n", expr); free(expr); } ClassTableIteratorDestroy(iter); WriterClose(writer); } } PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp) // NB - this function can be called recursively through "methods" { assert(bp != NULL); int save_pr_kept = PR_KEPT; int save_pr_repaired = PR_REPAIRED; int save_pr_notkept = PR_NOTKEPT; struct timespec start = BeginMeasure(); if (PROCESSREFRESH == NULL || (PROCESSREFRESH && IsRegexItemIn(ctx, PROCESSREFRESH, bp->name))) { ClearProcessTable(); } PromiseResult result = PROMISE_RESULT_SKIPPED; for (int pass = 1; pass < CF_DONEPASSES; pass++) { // Evaluate built-in (non-custom) promise types, according to type sequence (normal order): for (TypeSequence type = 0; AGENT_TYPESEQUENCE[type] != NULL; type++) { const BundleSection *sp = BundleGetSection((Bundle *)bp, AGENT_TYPESEQUENCE[type]); if (!sp || SeqLength(sp->promises) == 0) { continue; } NewTypeContext(type); SpecialTypeBanner(type, pass); EvalContextStackPushBundleSectionFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); EvalContextSetPass(ctx, pass); PromiseResult promise_result = ExpandPromise(ctx, pp, KeepAgentPromise, NULL); result = PromiseResultUpdate(result, promise_result); if (EvalAborted(ctx) || BundleAbort(ctx)) { DeleteTypeContext(ctx, type); EvalContextStackPopFrame(ctx); NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start); return result; } } DeleteTypeContext(ctx, type); EvalContextStackPopFrame(ctx); if (type == TYPE_SEQUENCE_CONTEXTS) { BundleResolve(ctx, bp); BundleResolvePromiseType(ctx, bp, "defaults", DefaultVarPromiseWrapper); } } // Custom promises are evaluated at the end of an evaluation pass: const size_t sections = SeqLength(bp->custom_sections); for (size_t i = 0; i < sections; ++i) { BundleSection *section = SeqAt(bp->custom_sections, i); EvalContextStackPushBundleSectionFrame(ctx, section); const size_t promises = SeqLength(section->promises); for (size_t ppi = 0; ppi < promises; ppi++) { Promise *pp = SeqAt(section->promises, ppi); EvalContextSetPass(ctx, pass); PromiseResult promise_result = ExpandPromise(ctx, pp, KeepAgentPromise, NULL); result = PromiseResultUpdate(result, promise_result); if (EvalAborted(ctx) || BundleAbort(ctx)) { EvalContextStackPopFrame(ctx); NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start); return result; } } EvalContextStackPopFrame(ctx); } } NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start); return result; } /*********************************************************************/ #ifdef __MINGW32__ static void CheckAgentAccess(const Rlist *list, const Policy *policy) { } #else static void CheckAgentAccess(const Rlist *list, const Policy *policy) { uid_t uid = getuid(); for (const Rlist *rp = list; rp != NULL; rp = rp->next) { if (Str2Uid(RlistScalarValue(rp), NULL, NULL) == uid) { return; } } { StringSet *input_files = PolicySourceFiles(policy); StringSetIterator iter = StringSetIteratorInit(input_files); const char *input_file = NULL; while ((input_file = StringSetIteratorNext(&iter))) { struct stat sb; stat(input_file, &sb); if (ACCESSLIST) { bool access = false; for (const Rlist *rp2 = ACCESSLIST; rp2 != NULL; rp2 = rp2->next) { if (Str2Uid(RlistScalarValue(rp2), NULL, NULL) == sb.st_uid) { access = true; break; } } if (!access) { Log(LOG_LEVEL_ERR, "File '%s' is not owned by an authorized user (security exception)", input_file); DoCleanupAndExit(EXIT_FAILURE); } } else if (CFPARANOID && IsPrivileged()) { if (sb.st_uid != getuid()) { Log(LOG_LEVEL_ERR, "File '%s' is not owned by uid %ju (security exception)", input_file, (uintmax_t)getuid()); DoCleanupAndExit(EXIT_FAILURE); } } } StringSetDestroy(input_files); } Log(LOG_LEVEL_ERR, "You are denied access to run this policy"); DoCleanupAndExit(EXIT_FAILURE); } #endif /* !__MINGW32__ */ /*********************************************************************/ static PromiseResult DefaultVarPromise(EvalContext *ctx, const Promise *pp) { char *regex = PromiseGetConstraintAsRval(pp, "if_match_regex", RVAL_TYPE_SCALAR); bool okay = true; DataType value_type = CF_DATA_TYPE_NONE; const void *value = NULL; { VarRef *ref = VarRefParseFromScope(pp->promiser, "this"); value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); } switch (value_type) { case CF_DATA_TYPE_STRING: case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: if (regex && !FullTextMatch(ctx, regex, value)) { return PROMISE_RESULT_NOOP; } if (regex == NULL) { return PROMISE_RESULT_NOOP; } break; case CF_DATA_TYPE_STRING_LIST: case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: if (regex) { for (const Rlist *rp = value; rp != NULL; rp = rp->next) { if (FullTextMatch(ctx, regex, RlistScalarValue(rp))) { okay = false; break; } } if (okay) { return PROMISE_RESULT_NOOP; } } break; default: break; } { VarRef *ref = VarRefParseFromBundle(pp->promiser, PromiseGetBundle(pp)); EvalContextVariableRemove(ctx, ref); VarRefDestroy(ref); } return VerifyVarPromise(ctx, pp, NULL); } static void LogVariableValue(const EvalContext *ctx, const Promise *pp) { VarRef *ref = VarRefParseFromBundle(pp->promiser, PromiseGetBundle(pp)); char *out = NULL; DataType type; const void *var = EvalContextVariableGet(ctx, ref, &type); switch (type) { case CF_DATA_TYPE_INT: case CF_DATA_TYPE_REAL: case CF_DATA_TYPE_STRING: out = xstrdup((char *) var); break; case CF_DATA_TYPE_INT_LIST: case CF_DATA_TYPE_REAL_LIST: case CF_DATA_TYPE_STRING_LIST: { size_t siz = CF_BUFSIZE; size_t len = 0; out = xcalloc(1, CF_BUFSIZE); for (Rlist *rp = (Rlist *) var; rp != NULL; rp = rp->next) { const char *s = (char *) rp->val.item; if (strlen(s) + len + 3 >= siz) // ", " + NULL { out = xrealloc(out, siz + CF_BUFSIZE); siz += CF_BUFSIZE; } if (len > 0) { len += strlcat(out, ", ", siz); } len += strlcat(out, s, siz); } break; } case CF_DATA_TYPE_CONTAINER: { Writer *w = StringWriter(); JsonWriteCompact(w, (JsonElement *) var); out = StringWriterClose(w); break; } default: /* TODO is CF_DATA_TYPE_NONE acceptable? Today all meta variables * are of this type. */ /* UnexpectedError("Variable '%s' is of unknown type %d", */ /* pp->promiser, type); */ out = xstrdup("NONE"); break; } Log(LOG_LEVEL_DEBUG, "V: '%s' => '%s'", pp->promiser, out); free(out); VarRefDestroy(ref); } static PromiseResult KeepAgentPromise(EvalContext *ctx, const Promise *pp, ARG_UNUSED void *param) { assert(param == NULL); assert(pp != NULL); struct timespec start = BeginMeasure(); PromiseResult result = PROMISE_RESULT_NOOP; if (strcmp("meta", PromiseGetPromiseType(pp)) == 0 || strcmp("vars", PromiseGetPromiseType(pp)) == 0) { Log(LOG_LEVEL_VERBOSE, "V: Computing value of '%s'", pp->promiser); result = VerifyVarPromise(ctx, pp, NULL); if (result != PROMISE_RESULT_FAIL) { if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG) { LogVariableValue(ctx, pp); } } } else if (strcmp("defaults", PromiseGetPromiseType(pp)) == 0) { result = DefaultVarPromise(ctx, pp); } else if (strcmp("classes", PromiseGetPromiseType(pp)) == 0) { result = VerifyClassPromise(ctx, pp, NULL); } else if (strcmp("processes", PromiseGetPromiseType(pp)) == 0) { if (!LoadProcessTable()) { Log(LOG_LEVEL_ERR, "Unable to read the process table - cannot keep processes: type promises"); return PROMISE_RESULT_FAIL; } result = VerifyProcessesPromise(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("storage", PromiseGetPromiseType(pp)) == 0) { result = FindAndVerifyStoragePromises(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("packages", PromiseGetPromiseType(pp)) == 0) { result = VerifyPackagesPromise(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("users", PromiseGetPromiseType(pp)) == 0) { result = VerifyUsersPromise(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("files", PromiseGetPromiseType(pp)) == 0) { result = ParallelFindAndVerifyFilesPromises(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("commands", PromiseGetPromiseType(pp)) == 0) { result = VerifyExecPromise(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("databases", PromiseGetPromiseType(pp)) == 0) { result = VerifyDatabasePromises(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("methods", PromiseGetPromiseType(pp)) == 0) { result = VerifyMethodsPromise(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("services", PromiseGetPromiseType(pp)) == 0) { result = VerifyServicesPromise(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("guest_environments", PromiseGetPromiseType(pp)) == 0) { result = VerifyEnvironmentsPromise(ctx, pp); if (result != PROMISE_RESULT_SKIPPED) { EndMeasurePromise(start, pp); } } else if (strcmp("reports", PromiseGetPromiseType(pp)) == 0) { result = VerifyReportPromise(ctx, pp); } else if (!IsBuiltInPromiseType(PromiseGetPromiseType(pp))) { result = EvaluateCustomPromise(ctx, pp); } else { result = PROMISE_RESULT_NOOP; } BannerStatus(result, PromiseGetPromiseType(pp), pp->promiser); EvalContextLogPromiseIterationOutcome(ctx, pp, result); return result; } static void BannerStatus(PromiseResult status, const char *type, char *name) { if ((strcmp(type, "vars") == 0) || (strcmp(type, "classes") == 0)) { return; } switch (status) { case PROMISE_RESULT_CHANGE: Log(LOG_LEVEL_VERBOSE, "A: Promise REPAIRED"); break; case PROMISE_RESULT_TIMEOUT: Log(LOG_LEVEL_VERBOSE, "A: Promise TIMED-OUT"); break; case PROMISE_RESULT_WARN: case PROMISE_RESULT_FAIL: case PROMISE_RESULT_INTERRUPTED: Log(LOG_LEVEL_VERBOSE, "A: Promise NOT KEPT!"); break; case PROMISE_RESULT_DENIED: Log(LOG_LEVEL_VERBOSE, "A: Promise NOT KEPT - denied"); break; case PROMISE_RESULT_NOOP: Log(LOG_LEVEL_VERBOSE, "A: Promise was KEPT"); break; default: return; break; } Log(LOG_LEVEL_VERBOSE, "P: END %s promise (%.30s%s)", type, name, (strlen(name) > 30) ? "..." : ""); } /*********************************************************************/ /* Type context */ /*********************************************************************/ static void NewTypeContext(TypeSequence type) { // get maxconnections switch (type) { case TYPE_SEQUENCE_ENVIRONMENTS: NewEnvironmentsContext(); break; case TYPE_SEQUENCE_FILES: break; case TYPE_SEQUENCE_PROCESSES: break; case TYPE_SEQUENCE_STORAGE: #ifndef __MINGW32__ // TODO: Run if implemented on Windows if (SeqLength(GetGlobalMountedFSList())) { DeleteMountInfo(GetGlobalMountedFSList()); SeqClear(GetGlobalMountedFSList()); } #endif /* !__MINGW32__ */ break; default: break; } return; } /*********************************************************************/ static void DeleteTypeContext(EvalContext *ctx, TypeSequence type) { switch (type) { case TYPE_SEQUENCE_ENVIRONMENTS: DeleteEnvironmentsContext(); break; case TYPE_SEQUENCE_FILES: break; case TYPE_SEQUENCE_PROCESSES: break; case TYPE_SEQUENCE_STORAGE: DeleteStorageContext(); break; case TYPE_SEQUENCE_PACKAGES: ExecuteScheduledPackages(ctx); CleanScheduledPackages(); break; default: break; } } /**************************************************************/ /* Thread context */ /**************************************************************/ #ifdef __MINGW32__ static PromiseResult ParallelFindAndVerifyFilesPromises(EvalContext *ctx, const Promise *pp) { int background = PromiseGetConstraintAsBoolean(ctx, "background", pp); if (background) { Log(LOG_LEVEL_VERBOSE, "Background processing of files promises is not supported on Windows"); } return FindAndVerifyFilesPromises(ctx, pp); } #else /* !__MINGW32__ */ static PromiseResult ParallelFindAndVerifyFilesPromises(EvalContext *ctx, const Promise *pp) { int background = PromiseGetConstraintAsBoolean(ctx, "background", pp); pid_t child = 1; PromiseResult result = PROMISE_RESULT_SKIPPED; if (background) { if (CFA_BACKGROUND < CFA_BACKGROUND_LIMIT) { CFA_BACKGROUND++; Log(LOG_LEVEL_VERBOSE, "Spawning new process..."); child = fork(); if (child == 0) { ALARM_PID = -1; result = PromiseResultUpdate(result, FindAndVerifyFilesPromises(ctx, pp)); Log(LOG_LEVEL_VERBOSE, "Exiting backgrounded promise"); PromiseRef(LOG_LEVEL_VERBOSE, pp); _exit(EXIT_SUCCESS); // TODO: need to solve this } } else { Log(LOG_LEVEL_VERBOSE, "Promised parallel execution promised but exceeded the max number of promised background tasks, so serializing"); background = 0; } } else { result = PromiseResultUpdate(result, FindAndVerifyFilesPromises(ctx, pp)); } return result; } #endif /* !__MINGW32__ */ /**************************************************************/ static bool VerifyBootstrap(bool skip_cf_execd_check) { const char *policy_server = PolicyServerGet(); if (NULL_OR_EMPTY(policy_server)) { Log(LOG_LEVEL_ERR, "Bootstrapping failed, no policy server is specified"); return false; } // we should at least have gotten promises.cf from the policy hub { char filename[CF_MAXVARSIZE]; snprintf(filename, sizeof(filename), "%s/promises.cf", GetInputDir()); MapName(filename); struct stat sb; if (stat(filename, &sb) == -1) { Log(LOG_LEVEL_ERR, "Bootstrapping failed, no input file at '%s' after bootstrap", filename); return false; } } // embedded failsafe.cf (bootstrap.c) contains a promise to start cf-execd (executed while running this cf-agent) ClearProcessTable(); LoadProcessTable(); if (!skip_cf_execd_check && !IsProcessNameRunning(".*cf-execd.*")) { Log(LOG_LEVEL_ERR, "Bootstrapping failed, cf-execd is not running"); return false; } Log(LOG_LEVEL_NOTICE, "Bootstrap to '%s' completed successfully!", policy_server); return true; } /**************************************************************/ /* Compliance comp */ /**************************************************************/ static int NoteBundleCompliance(const Bundle *bundle, int save_pr_kept, int save_pr_repaired, int save_pr_notkept, struct timespec start) { double delta_pr_kept, delta_pr_repaired, delta_pr_notkept; double bundle_compliance = 0.0; delta_pr_kept = (double) (PR_KEPT - save_pr_kept); delta_pr_notkept = (double) (PR_NOTKEPT - save_pr_notkept); delta_pr_repaired = (double) (PR_REPAIRED - save_pr_repaired); Log(LOG_LEVEL_VERBOSE, "A: ..................................................."); Log(LOG_LEVEL_VERBOSE, "A: Bundle Accounting Summary for '%s' in namespace %s", bundle->name, bundle->ns); if (delta_pr_kept + delta_pr_notkept + delta_pr_repaired <= 0) { Log(LOG_LEVEL_VERBOSE, "A: Zero promises executed for bundle '%s'", bundle->name); Log(LOG_LEVEL_VERBOSE, "A: ..................................................."); return PROMISE_RESULT_NOOP; } else { Log(LOG_LEVEL_VERBOSE, "A: Promises kept in '%s' = %.0lf", bundle->name, delta_pr_kept); Log(LOG_LEVEL_VERBOSE, "A: Promises not kept in '%s' = %.0lf", bundle->name, delta_pr_notkept); Log(LOG_LEVEL_VERBOSE, "A: Promises repaired in '%s' = %.0lf", bundle->name, delta_pr_repaired); bundle_compliance = (delta_pr_kept + delta_pr_repaired) / (delta_pr_kept + delta_pr_notkept + delta_pr_repaired); Log(LOG_LEVEL_VERBOSE, "A: Aggregate compliance (promises kept/repaired) for bundle '%s' = %.1lf%%", bundle->name, bundle_compliance * 100.0); if (LogGetGlobalLevel() >= LOG_LEVEL_INFO) { char name[CF_MAXVARSIZE]; snprintf(name, CF_MAXVARSIZE, "%s:%s", bundle->ns, bundle->name); EndMeasure(name, start); } else { EndMeasure(NULL, start); } Log(LOG_LEVEL_VERBOSE, "A: ..................................................."); } // return the worst case for the bundle status if (delta_pr_notkept > 0) { return PROMISE_RESULT_FAIL; } if (delta_pr_repaired > 0) { return PROMISE_RESULT_CHANGE; } return PROMISE_RESULT_NOOP; } #if defined(HAVE_AVAHI_CLIENT_CLIENT_H) && defined(HAVE_AVAHI_COMMON_ADDRESS_H) static bool HasAvahiSupport(void) { return true; } static int AutomaticBootstrap(GenericAgentConfig *config) { List *foundhubs = NULL; int hubcount = ListHubs(&foundhubs); int ret; switch(hubcount) { case -1: Log(LOG_LEVEL_ERR, "Error while trying to find a Policy Server"); ret = -1; break; case 0: Log(LOG_LEVEL_ERR, "No hubs were found. Exiting."); ret = -1; break; case 1: { char *hostname = ((HostProperties*)foundhubs)->Hostname; char *ipaddr = ((HostProperties*)foundhubs)->IPAddress; Log(LOG_LEVEL_NOTICE, "Autodiscovered hub installed on hostname '%s', IP address '%s'", hostname, ipaddr); // TODO: This is a very bad way to check for valid IP(?) if (strlen(ipaddr) < CF_MAX_IP_LEN) { config->agent_specific.agent.bootstrap_argument = xstrdup(ipaddr); config->agent_specific.agent.bootstrap_ip = xstrdup(ipaddr); config->agent_specific.agent.bootstrap_host = xstrdup(ipaddr); ret = 0; } else { Log(LOG_LEVEL_ERR, "Invalid autodiscovered hub IP address '%s'", ipaddr); ret = -1; } break; } default: Log(LOG_LEVEL_ERR, "Found more than one hub registered in the network. Please bootstrap manually using IP from the list below."); PrintList(foundhubs); ret = -1; }; if (avahi_handle) { /* * This case happens when dlopen does not manage to open the library. */ dlclose(avahi_handle); } ListDestroy(&foundhubs); return ret; } #else static bool HasAvahiSupport(void) { return false; } static int AutomaticBootstrap(ARG_UNUSED GenericAgentConfig *config) { ProgrammingError("Attempted automated bootstrap on a non-avahi build of CFEngine"); } #endif // Avahi static void WaitForBackgroundProcesses() { #ifdef __MINGW32__ /* no fork() on Windows */ return; #else Log(LOG_LEVEL_VERBOSE, "Waiting for background processes"); bool have_children = true; while (have_children) { pid_t child = wait(NULL); if (child >= 0) { Log(LOG_LEVEL_VERBOSE, "Background process %ju terminated", (uintmax_t) child); } have_children = !((child == -1) && (errno == ECHILD)); } Log(LOG_LEVEL_VERBOSE, "No more background processes to wait for"); return; #endif /* __MINGW32__ */ } cfengine-3.24.2/cf-agent/verify_files_hashes.h0000644000000000000000000000273015010704253021233 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* AgentConnection */ #ifndef CFENGINE_VERIFY_FILES_HASHES_H #define CFENGINE_VERIFY_FILES_HASHES_H bool CompareFileHashes(const char *file1, const char *file2, const struct stat *sstat, const struct stat *dstat, const FileCopy *fc, AgentConnection *conn); bool CompareBinaryFiles(const char *file1, const char *file2, const struct stat *sstat, const struct stat *dstat, const FileCopy *fc, AgentConnection *conn); #endif cfengine-3.24.2/cf-agent/agent-diagnostics.h0000644000000000000000000000473415010704253020623 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_AGENT_DIAGNOSTICS_H #define CFENGINE_AGENT_DIAGNOSTICS_H #include #include typedef struct { bool success; char *message; } AgentDiagnosticsResult; typedef AgentDiagnosticsResult AgentDiagnosticCheckFn(const char *workdir); typedef struct { const char *description; AgentDiagnosticCheckFn *check; } AgentDiagnosticCheck; typedef void (*AgentDiagnosticsRunFunction)(const char *workdir, const AgentDiagnosticCheck checks[], Writer *output); void AgentDiagnosticsRun(const char *workdir, const AgentDiagnosticCheck checks[], Writer *output); // Checks AgentDiagnosticsResult AgentDiagnosticsCheckHavePrivateKey(const char *workdir); AgentDiagnosticsResult AgentDiagnosticsCheckHavePublicKey(const char *workdir); AgentDiagnosticsResult AgentDiagnosticsCheckIsBootstrapped(const char *workdir); AgentDiagnosticsResult AgentDiagnosticsCheckAmPolicyServer(const char *workdir); typedef AgentDiagnosticsResult (*AgentDiagnosticsResultNewFunction)(bool success, char *message); AgentDiagnosticsResult AgentDiagnosticsResultNew(bool success, char *message); const AgentDiagnosticCheck *AgentDiagnosticsAllChecks(void); ENTERPRISE_VOID_FUNC_4ARG_DECLARE(void, AgentDiagnosticsRunAllChecksNova, const char *, workdir, Writer *, output, AgentDiagnosticsRunFunction, AgentDiagnosticsRunPtr, AgentDiagnosticsResultNewFunction, AgentDiagnosticsResultNewPtr); #endif cfengine-3.24.2/cf-agent/verify_packages.h0000644000000000000000000000345715010704253020363 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_PACKAGES_H #define CFENGINE_VERIFY_PACKAGES_H #include #include PromiseResult VerifyPackagesPromise(EvalContext *ctx, const Promise *pp); void ExecuteScheduledPackages(EvalContext *ctx); void CleanScheduledPackages(void); bool PrependPackageItem(EvalContext *ctx, PackageItem **list, const char *name, const char *version, const char *arch, const Promise *pp); // For testing. VersionCmpResult ComparePackages(EvalContext *ctx, const char *n, const char *v, const char *arch, PackageItem *pi, const Attributes *a, const Promise *pp, const char *mode, PromiseResult *result); #endif cfengine-3.24.2/cf-agent/verify_files_utils.c0000644000000000000000000046451115010704253021124 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* remote_stat,StatCacheLookup */ #include #include /* PrepareChangesChroot(), RecordFileChangedInChroot() */ #include /* GetGroupName(), GetUserName() */ #include #define CF_RECURSION_LIMIT 100 static const Rlist *AUTO_DEFINE_LIST = NULL; /* GLOBAL_P */ static Item *VSETXIDLIST = NULL; const Rlist *SINGLE_COPY_LIST = NULL; /* GLOBAL_P */ StringSet *SINGLE_COPY_CACHE = NULL; /* GLOBAL_X */ static bool TransformFile(EvalContext *ctx, char *file, const Attributes *attr, const Promise *pp, PromiseResult *result); static PromiseResult VerifyName(EvalContext *ctx, char *path, const struct stat *sb, const Attributes *attr, const Promise *pp); static PromiseResult VerifyDelete(EvalContext *ctx, const char *path, const struct stat *sb, const Attributes *attr, const Promise *pp); static PromiseResult VerifyCopy(EvalContext *ctx, const char *source, char *destination, const Attributes *attr, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn); static PromiseResult TouchFile(EvalContext *ctx, char *path, const Attributes *attr, const Promise *pp); static PromiseResult VerifyFileAttributes(EvalContext *ctx, const char *file, const struct stat *dstat, const Attributes *attr, const Promise *pp); static bool PushDirState(EvalContext *ctx, const Promise *pp, const Attributes *attr, char *name, const struct stat *sb, PromiseResult *result); static bool PopDirState(EvalContext *ctx, const Promise *pp, const Attributes *attr, int goback, char *name, const struct stat *sb, DirectoryRecursion r, PromiseResult *result); static bool CheckLinkSecurity(const struct stat *sb, const char *name); static bool CompareForFileCopy(char *sourcefile, char *destfile, const struct stat *ssb, const struct stat *dsb, const FileCopy *fc, AgentConnection *conn); static void FileAutoDefine(EvalContext *ctx, char *destfile); static void TruncateFile(const char *name); static void RegisterAHardLink(int i, const char *value, EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, CompressedArray **inode_cache); static PromiseResult VerifyCopiedFileAttributes(EvalContext *ctx, const char *src, const char *dest, const struct stat *sstat, const struct stat *dstat, const Attributes *attr, const Promise *pp); static int cf_stat(const char *file, struct stat *buf, const FileCopy *fc, AgentConnection *conn); #ifndef __MINGW32__ static int cf_readlink(EvalContext *ctx, const char *sourcefile, char *linkbuf, size_t buffsize, const Attributes *attr, const Promise *pp, AgentConnection *conn, PromiseResult *result); #endif static bool SkipDirLinks(EvalContext *ctx, const char *path, const char *lastnode, DirectoryRecursion r); static bool DeviceBoundary(const struct stat *sb, dev_t rootdevice); static PromiseResult LinkCopy(EvalContext *ctx, char *sourcefile, char *destfile, const struct stat *sb, const Attributes *attr, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn); #ifndef __MINGW32__ static void LoadSetxid(void); static void SaveSetxid(bool modified); static PromiseResult VerifySetUidGid(EvalContext *ctx, const char *file, const struct stat *dstat, mode_t newperm, const Promise *pp, const Attributes *attr); #endif #ifdef __APPLE__ static int VerifyFinderType(EvalContext *ctx, const char *file, const Attributes *a, const Promise *pp, PromiseResult *result); #endif static void VerifyFileChanges(EvalContext *ctx, const char *file, const struct stat *sb, const Attributes *attr, const Promise *pp, PromiseResult *result); static PromiseResult VerifyFileIntegrity(EvalContext *ctx, const char *file, const Attributes *attr, const Promise *pp); extern Attributes GetExpandedAttributes(EvalContext *ctx, const Promise *pp, const Attributes *attr); extern void ClearExpandedAttributes(Attributes *a); void SetFileAutoDefineList(const Rlist *auto_define_list) { AUTO_DEFINE_LIST = auto_define_list; } void VerifyFileLeaf(EvalContext *ctx, char *path, const struct stat *sb, ARG_UNUSED const Attributes *attr, const Promise *pp, PromiseResult *result) { // FIXME: This function completely ignores it's attr argument assert(attr != NULL); /* Here we can assume that we are in the parent directory of the leaf */ Log(LOG_LEVEL_VERBOSE, "Handling file existence constraints on '%s'", path); /* Update this.promiser again, and overwrite common attributes (classes, action) accordingly */ EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser", path, CF_DATA_TYPE_STRING, "source=promise"); // Parameters may only be scalars Attributes org_attr = GetFilesAttributes(ctx, pp); Attributes new_attr = GetExpandedAttributes(ctx, pp, &org_attr); if (new_attr.transformer != NULL) { if (!TransformFile(ctx, path, &new_attr, pp, result)) { /* NOP, changes and/or failures are recorded by TransformFile() */ } } else { if (new_attr.haverename) { *result = PromiseResultUpdate(*result, VerifyName(ctx, path, sb, &new_attr, pp)); } if (new_attr.havedelete) { *result = PromiseResultUpdate(*result, VerifyDelete(ctx, path, sb, &new_attr, pp)); } if (new_attr.touch) { *result = PromiseResultUpdate(*result, TouchFile(ctx, path, &new_attr, pp)); // intrinsically non-convergent op } } if (new_attr.haveperms || new_attr.havechange || new_attr.acl.acl_entries) { if (S_ISDIR(sb->st_mode) && new_attr.recursion.depth && !new_attr.recursion.include_basedir && (strcmp(path, pp->promiser) == 0)) { Log(LOG_LEVEL_VERBOSE, "Promise to skip base directory '%s'", path); } else { *result = PromiseResultUpdate(*result, VerifyFileAttributes(ctx, path, sb, &new_attr, pp)); } } ClearExpandedAttributes(&new_attr); } /* Checks whether item matches a list of wildcards */ static bool MatchRlistItem(EvalContext *ctx, const Rlist *listofregex, const char *teststring) { for (const Rlist *rp = listofregex; rp != NULL; rp = rp->next) { /* Avoid using regex if possible, due to memory leak */ if (strcmp(teststring, RlistScalarValue(rp)) == 0) { return true; } /* Make it commutative */ if (FullTextMatch(ctx, RlistScalarValue(rp), teststring)) { return true; } } return false; } /* (conn == NULL) then copy is from localhost. */ static PromiseResult CfCopyFile(EvalContext *ctx, char *sourcefile, char *destfile, const struct stat *ssb, const Attributes *a, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn) { assert(a != NULL); const char *lastnode; struct stat dsb; const mode_t srcmode = ssb->st_mode; const char *server; if (conn != NULL) { server = conn->this_server; } else { server = "localhost"; } #ifdef __MINGW32__ if (a->copy.copy_links != NULL) { Log(LOG_LEVEL_VERBOSE, "copy_from.copylink_patterns is ignored on Windows " "(source files cannot be symbolic links)"); } #endif /* __MINGW32__ */ Attributes attr = *a; // TODO: Avoid this copy attr.link.when_no_file = cfa_force; if (strcmp(sourcefile, destfile) == 0 && strcmp(server, "localhost") == 0) { RecordNoChange(ctx, pp, &attr, "File copy promise loop: file/dir '%s' is its own source", sourcefile); return PROMISE_RESULT_NOOP; } if (attr.haveselect && !SelectLeaf(ctx, sourcefile, ssb, &(attr.select))) { RecordNoChange(ctx, pp, &attr, "Skipping non-selected file '%s'", sourcefile); return PROMISE_RESULT_NOOP; } if ((SINGLE_COPY_CACHE != NULL) && StringSetContains(SINGLE_COPY_CACHE, destfile)) { RecordNoChange(ctx, pp, &attr, "Skipping single-copied file '%s'", destfile); return PROMISE_RESULT_NOOP; } if (attr.copy.link_type != FILE_LINK_TYPE_NONE) { lastnode = ReadLastNode(sourcefile); if (MatchRlistItem(ctx, attr.copy.link_instead, lastnode)) { if (MatchRlistItem(ctx, attr.copy.copy_links, lastnode)) { RecordNoChange(ctx, pp, &attr, "File %s matches both copylink_patterns and linkcopy_patterns" " - promise loop (skipping)!", sourcefile); return PROMISE_RESULT_NOOP; } else { Log(LOG_LEVEL_VERBOSE, "Copy item '%s' marked for linking", sourcefile); #ifdef __MINGW32__ Log(LOG_LEVEL_VERBOSE, "Links are not yet supported on Windows" " - copying '%s' instead", sourcefile); #else return LinkCopy(ctx, sourcefile, destfile, ssb, &attr, pp, inode_cache, conn); #endif } } } const char *changes_destfile = destfile; if (ChrootChanges()) { changes_destfile = ToChangesChroot(destfile); } PromiseResult result = PROMISE_RESULT_NOOP; bool destfile_exists = (lstat(changes_destfile, &dsb) != -1); if (destfile_exists) { if ((S_ISLNK(dsb.st_mode) && attr.copy.link_type == FILE_LINK_TYPE_NONE) || (S_ISLNK(dsb.st_mode) && !S_ISLNK(srcmode))) { if (!S_ISLNK(srcmode) && attr.copy.type_check && attr.copy.link_type != FILE_LINK_TYPE_NONE) { RecordFailure(ctx, pp, &attr, "File image exists but destination type is silly " "(file/dir/link doesn't match)"); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } if (!MakingChanges(ctx, pp, &attr, NULL, "remove old symbolic link '%s' to make way for copy", destfile)) { return PROMISE_RESULT_WARN; } else { if (unlink(changes_destfile) == -1) { RecordFailure(ctx, pp, &attr, "Couldn't remove link '%s'. (unlink: %s)", destfile, GetErrorStr()); return PROMISE_RESULT_FAIL; } RecordChange(ctx, pp, &attr, "Removing old symbolic link '%s' to make way for copy", destfile); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); destfile_exists = false; } } } else { bool dir_created = false; if (!MakeParentDirectoryForPromise(ctx, pp, &attr, &result, destfile, true, &dir_created, DEFAULTMODE)) { return result; } if (dir_created) { RecordChange(ctx, pp, &attr, "Created parent directory for '%s'", destfile); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } if (attr.copy.min_size != (size_t) CF_NOINT) { if (((size_t) ssb->st_size < attr.copy.min_size) || ((size_t) ssb->st_size > attr.copy.max_size)) { RecordNoChange(ctx, pp, &attr, "Source file '%s' size is not in the permitted safety range, skipping", sourcefile); return result; } } if (!destfile_exists) { if (S_ISREG(srcmode) || (S_ISLNK(srcmode) && attr.copy.link_type == FILE_LINK_TYPE_NONE)) { if (!MakingChanges(ctx, pp, &attr, &result, "copy '%s' to '%s'", destfile, sourcefile)) { return result; } Log(LOG_LEVEL_VERBOSE, "'%s' wasn't at destination, copying from '%s:%s'", destfile, server, sourcefile); if (S_ISLNK(srcmode) && attr.copy.link_type != FILE_LINK_TYPE_NONE) { Log(LOG_LEVEL_VERBOSE, "'%s' is a symbolic link", sourcefile); result = PromiseResultUpdate(result, LinkCopy(ctx, sourcefile, destfile, ssb, &attr, pp, inode_cache, conn)); } else if (CopyRegularFile(ctx, sourcefile, destfile, ssb, &attr, pp, inode_cache, conn, &result)) { if (stat(ToChangesPath(destfile), &dsb) == -1) { Log(LOG_LEVEL_ERR, "Can't stat destination file '%s'. (stat: %s)", destfile, GetErrorStr()); } else { result = PromiseResultUpdate(result, VerifyCopiedFileAttributes(ctx, sourcefile, destfile, ssb, &dsb, &attr, pp)); } RecordChange(ctx, pp, &attr, "Updated file '%s' from '%s:%s'", destfile, server, sourcefile); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); if (SINGLE_COPY_LIST) { StringSetAdd(SINGLE_COPY_CACHE, xstrdup(destfile)); } if (MatchRlistItem(ctx, AUTO_DEFINE_LIST, destfile)) { FileAutoDefine(ctx, destfile); } } else { RecordFailure(ctx, pp, &attr, "Copy from '%s:%s' failed", server, sourcefile); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } return result; } if (S_ISFIFO(srcmode)) { #ifdef HAVE_MKFIFO if (!MakingChanges(ctx, pp, &attr, &result, "create FIFO '%s'", destfile)) { return result; } else if (mkfifo(ToChangesPath(destfile), srcmode) != 0) { RecordFailure(ctx, pp, &attr, "Cannot create fifo '%s'. (mkfifo: %s)", destfile, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } RecordChange(ctx, pp, &attr, "Created fifo '%s'", destfile); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); #else RecordWarning(ctx, pp, &attr, "Should create FIFO '%s', but FIFO creation not supported", destfile); result = PromiseResultUpdate(result, PROMISE_RESULT_WARN); return result; #endif } else { #ifndef __MINGW32__ // only regular files on windows if (S_ISBLK(srcmode) || S_ISCHR(srcmode) || S_ISSOCK(srcmode)) { if (!MakingChanges(ctx, pp, &attr, &result, "make special file/device '%s'", destfile)) { return result; } else if (mknod(ToChangesPath(destfile), srcmode, ssb->st_rdev)) { RecordFailure(ctx, pp, &attr, "Cannot create special file '%s'. (mknod: %s)", destfile, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } RecordChange(ctx, pp, &attr, "Created special file/device '%s'.", destfile); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } #endif /* !__MINGW32__ */ } if ((S_ISLNK(srcmode)) && (attr.copy.link_type != FILE_LINK_TYPE_NONE)) { result = PromiseResultUpdate(result, LinkCopy(ctx, sourcefile, destfile, ssb, &attr, pp, inode_cache, conn)); } } else { Log(LOG_LEVEL_VERBOSE, "Destination file '%s' already exists", destfile); if (attr.copy.compare == FILE_COMPARATOR_EXISTS) { RecordNoChange(ctx, pp, &attr, "Existence only is promised, no copying required"); return result; } bool should_copy = (attr.copy.force_update || CompareForFileCopy(sourcefile, destfile, ssb, &dsb, &attr.copy, conn)); if (attr.copy.type_check && attr.copy.link_type != FILE_LINK_TYPE_NONE) { // Mask mode with S_IFMT to extract and compare file types if ((dsb.st_mode & S_IFMT) != (srcmode & S_IFMT)) { RecordFailure(ctx, pp, &attr, "Promised file copy %s exists but type mismatch with source '%s'", destfile, sourcefile); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } } if (should_copy || S_ISLNK(srcmode)) /* Always check links */ { if (S_ISREG(srcmode) || attr.copy.link_type == FILE_LINK_TYPE_NONE) { if (!MakingChanges(ctx, pp, &attr, &result, "update file '%s' from '%s' on '%s'", destfile, sourcefile, server)) { return result; } if (MatchRlistItem(ctx, AUTO_DEFINE_LIST, destfile)) { FileAutoDefine(ctx, destfile); } if (CopyRegularFile(ctx, sourcefile, destfile, ssb, &attr, pp, inode_cache, conn, &result)) { if (stat(ToChangesPath(destfile), &dsb) == -1) { RecordInterruption(ctx, pp, &attr, "Can't stat destination '%s'. (stat: %s)", destfile, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); } else { RecordChange(ctx, pp, &attr, "Updated '%s' from source '%s' on '%s'", destfile, sourcefile, server); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); result = PromiseResultUpdate(result, VerifyCopiedFileAttributes(ctx, sourcefile, destfile, ssb, &dsb, &attr, pp)); } if (RlistIsInListOfRegex(SINGLE_COPY_LIST, destfile)) { StringSetAdd(SINGLE_COPY_CACHE, xstrdup(destfile)); } } else { RecordFailure(ctx, pp, &attr, "Was not able to copy '%s' on '%s' to '%s'", sourcefile, server, destfile); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } return result; } else if (S_ISLNK(srcmode)) { result = PromiseResultUpdate(result, LinkCopy(ctx, sourcefile, destfile, ssb, &attr, pp, inode_cache, conn)); } } else { result = PromiseResultUpdate(result, VerifyCopiedFileAttributes(ctx, sourcefile, destfile, ssb, &dsb, &attr, pp)); /* Now we have to check for single copy, even though nothing was copied otherwise we can get oscillations between multipe versions if type is based on a checksum */ if (RlistIsInListOfRegex(SINGLE_COPY_LIST, destfile)) { StringSetAdd(SINGLE_COPY_CACHE, xstrdup(destfile)); } RecordNoChange(ctx, pp, &attr, "File '%s' is an up to date copy of source", destfile); } } return result; } static PromiseResult PurgeLocalFiles(EvalContext *ctx, Item *filelist, const char *localdir, const Attributes *attr, const Promise *pp, AgentConnection *conn) { assert(attr != NULL); Dir *dirh; struct stat sb; const struct dirent *dirp; char filename[CF_BUFSIZE] = { 0 }; if (strlen(localdir) < 2) { RecordFailure(ctx, pp, attr, "Purge of '%s' denied - too dangerous!", localdir); return PROMISE_RESULT_FAIL; } /* If we purge with no authentication we wipe out EVERYTHING ! */ if (conn && (!conn->authenticated)) { RecordDenial(ctx, pp, attr, "Not purge local files '%s' - no authenticated contact with a source", localdir); return PROMISE_RESULT_DENIED; } if (!attr->havedepthsearch) { RecordNoChange(ctx, pp, attr, "No depth search when copying '%s' so purging does not apply", localdir); return PROMISE_RESULT_NOOP; } /* chdir to minimize the risk of race exploits during copy (which is inherently dangerous) */ const char *changes_localdir = localdir; if (ChrootChanges()) { changes_localdir = ToChangesChroot(localdir); } if (safe_chdir(changes_localdir) == -1) { RecordFailure(ctx, pp, attr, "Can't chdir to local directory '%s'. (chdir: %s)", localdir, GetErrorStr()); return PROMISE_RESULT_FAIL; } if ((dirh = DirOpen(".")) == NULL) { RecordFailure(ctx, pp, attr, "Can't open local directory '%s'. (opendir: %s)", localdir, GetErrorStr()); return PROMISE_RESULT_FAIL; } PromiseResult result = PROMISE_RESULT_NOOP; for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!ConsiderLocalFile(dirp->d_name, changes_localdir)) { Log(LOG_LEVEL_VERBOSE, "Skipping '%s'", dirp->d_name); continue; } if (!IsItemIn(filelist, dirp->d_name)) { strncpy(filename, localdir, CF_BUFSIZE - 2); AddSlash(filename); if (strlcat(filename, dirp->d_name, CF_BUFSIZE) >= CF_BUFSIZE) { RecordFailure(ctx, pp, attr, "Path name '%s%s' is too long in PurgeLocalFiles", filename, dirp->d_name); continue; } const char *changes_filename = filename; if (ChrootChanges()) { changes_filename = ToChangesChroot(filename); } if (MakingChanges(ctx, pp, attr, &result, "purge '%s' from copy dest directory", filename)) { if (lstat(changes_filename, &sb) == -1) { RecordInterruption(ctx, pp, attr, "Couldn't stat '%s' while purging. (lstat: %s)", filename, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); } else if (S_ISDIR(sb.st_mode)) { if (!DeleteDirectoryTree(changes_filename)) { RecordFailure(ctx, pp, attr, "Unable to purge directory tree '%s'", filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else if (rmdir(changes_filename) == -1) { if (errno != ENOENT) { RecordFailure(ctx, pp, attr, "Unable to purge directory '%s'", filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } else { RecordChange(ctx, pp, attr, "Purged directory '%s' in copy dest directory", filename); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } else if (unlink(changes_filename) == -1) { RecordFailure(ctx, pp, attr, "Couldn't delete '%s' while purging", filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else { RecordChange(ctx, pp, attr, "Purged '%s' copy dest directory", filename); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } } } DirClose(dirh); return result; } static PromiseResult SourceSearchAndCopy(EvalContext *ctx, const char *from, char *to, int maxrecurse, const Attributes *attr, const Promise *pp, dev_t rootdevice, CompressedArray **inode_cache, AgentConnection *conn) { /* TODO overflow check all these str*cpy()s in here! */ Item *namecache = NULL; if (maxrecurse == 0) /* reached depth limit */ { RecordFailure(ctx, pp, attr, "Maximum recursion level reached at '%s'", from); return PROMISE_RESULT_FAIL; } if (strlen(from) == 0) /* Check for root dir */ { from = "/"; } /* Check that dest dir exists before starting */ char newto[CF_BUFSIZE]; strlcpy(newto, to, sizeof(newto) - 10); AddSlash(newto); strcat(newto, "dummy"); PromiseResult result = PROMISE_RESULT_NOOP; struct stat tostat; bool dir_created = false; if (!MakeParentDirectoryForPromise(ctx, pp, attr, &result, newto, attr->move_obstructions, &dir_created, DEFAULTMODE)) { return result; } if (dir_created) { RecordChange(ctx, pp, attr, "Created parent directory for '%s'", to); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } /* remove "/dummy" from 'newto' */ ChopLastNode(newto); /* XXX: really delete slash from 'to'??? */ DeleteSlash(to); const char *changes_newto = newto; if (ChrootChanges()) { changes_newto = ToChangesChroot(newto); } /* Set aside symlinks */ if (lstat(changes_newto, &tostat) != 0) { RecordFailure(ctx, pp, attr, "Unable to stat newly created directory '%s'. (lstat: %s)", to, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (S_ISLNK(tostat.st_mode)) { char backup[CF_BUFSIZE]; mode_t mask; if (!attr->move_obstructions) { RecordFailure(ctx, pp, attr, "Path '%s' is a symlink. Unable to move it aside without move_obstructions is set", to); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } strcpy(backup, changes_newto); DeleteSlash(to); /* FIXME: really delete slash from *to*??? */ strcat(backup, ".cf-moved"); if (MakingChanges(ctx, pp, attr, &result, "backup '%s'", to)) { if (rename(changes_newto, backup) == -1) { Log(LOG_LEVEL_ERR, "Unable to backup old '%s'", to); unlink(to); } else { RecordChange(ctx, pp, attr, "Backed up '%s'", to); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } if (MakingChanges(ctx, pp, attr, &result, "create directory '%s'", to)) { mask = umask(0); if (mkdir(changes_newto, DEFAULTMODE) == -1) { RecordFailure(ctx, pp, attr, "Failed to make directory '%s'. (mkdir: %s)", to, GetErrorStr()); umask(mask); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } else { RecordChange(ctx, pp, attr, "Created directory for '%s'", to); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } umask(mask); } } /* (conn == NULL) means copy is from localhost. */ const char *changes_from = from; bool local_changed_from = false; if ((conn == NULL) && ChrootChanges()) { const char *chrooted_from = ToChangesChroot(from); struct stat sb; if (lstat(changes_from, &sb) != -1) { changes_from = chrooted_from; local_changed_from = true; } } /* Send OPENDIR command. */ AbstractDir *dirh; if ((dirh = AbstractDirOpen(changes_from, &(attr->copy), conn)) == NULL) { RecordInterruption(ctx, pp, attr, "Can't open directory '%s' for copying", from); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } /* No backslashes over the network. */ const char sep = (conn != NULL) ? '/' : FILE_SEPARATOR; struct stat sb, dsb; char newfrom[CF_BUFSIZE]; const struct dirent *dirp; for (dirp = AbstractDirRead(dirh); dirp != NULL; dirp = AbstractDirRead(dirh)) { /* This sends 1st STAT command. */ if (!ConsiderAbstractFile(dirp->d_name, from, &(attr->copy), conn)) { if (conn != NULL && conn->conn_info->status != CONNECTIONINFO_STATUS_ESTABLISHED) { RecordInterruption(ctx, pp, attr, "Connection error when checking '%s'", dirp->d_name); AbstractDirClose(dirh); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } else { Log(LOG_LEVEL_VERBOSE, "Skipping '%s'", dirp->d_name); continue; } } if (attr->copy.purge) { /* Append this file to the list of files not to purge */ AppendItem(&namecache, dirp->d_name, NULL); } /* Assemble pathnames. TODO check overflow. */ strlcpy(newfrom, from, sizeof(newfrom)); strlcpy(newto, to, sizeof(newto)); if (!PathAppend(newfrom, sizeof(newfrom), dirp->d_name, sep)) { RecordFailure(ctx, pp, attr, "Internal limit reached in SourceSearchAndCopy()," " source path too long: '%s' + '%s'", newfrom, dirp->d_name); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); AbstractDirClose(dirh); return result; } const char *changes_newfrom = newfrom; if (ChrootChanges() && local_changed_from) { changes_newfrom = ToChangesChroot(newfrom); } /* This issues a 2nd STAT command, hopefully served from cache. */ if ((attr->recursion.travlinks) || (attr->copy.link_type == FILE_LINK_TYPE_NONE)) { /* No point in checking if there are untrusted symlinks here, since this is from a trusted source, by definition */ if (cf_stat(changes_newfrom, &sb, &(attr->copy), conn) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't stat '%s'. (cf_stat: %s)", newfrom, GetErrorStr()); if (conn != NULL && conn->conn_info->status != CONNECTIONINFO_STATUS_ESTABLISHED) { RecordInterruption(ctx, pp, attr, "Connection error when checking '%s'", newfrom); AbstractDirClose(dirh); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } else { Log(LOG_LEVEL_VERBOSE, "Skipping '%s'", newfrom); continue; } } } else { if (cf_lstat(changes_newfrom, &sb, &(attr->copy), conn) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't stat '%s'. (cf_stat: %s)", newfrom, GetErrorStr()); if (conn != NULL && conn->conn_info->status != CONNECTIONINFO_STATUS_ESTABLISHED) { RecordInterruption(ctx, pp, attr, "Connection error when checking '%s'", newfrom); AbstractDirClose(dirh); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } else { Log(LOG_LEVEL_VERBOSE, "Skipping '%s'", newfrom); continue; } } } /* If "collapse_destination_dir" is set, we skip subdirectories, which * means we are not creating them in the destination folder. */ if (!attr->copy.collapse || (attr->copy.collapse && !S_ISDIR(sb.st_mode))) { if (!PathAppend(newto, sizeof(newto), dirp->d_name, FILE_SEPARATOR)) { RecordFailure(ctx, pp, attr, "Internal limit reached in SourceSearchAndCopy()," " dest path too long: '%s' + '%s'", newto, dirp->d_name); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); AbstractDirClose(dirh); return result; } } if (ChrootChanges()) { /* Need to refresh 'changes_newto' because 'newto' could have been * changed above and also the above call of ToChangesChroot() for * 'changes_newfrom' modifies the internal buffer returned by * ToChangesChroot(). */ changes_newto = ToChangesChroot(newto); } if ((attr->recursion.xdev) && (DeviceBoundary(&sb, rootdevice))) { Log(LOG_LEVEL_VERBOSE, "Skipping '%s' on different device", newfrom); continue; } if (S_ISDIR(sb.st_mode)) { if (attr->recursion.travlinks) { Log(LOG_LEVEL_VERBOSE, "Traversing directory links during copy is too dangerous, pruned"); continue; } if (SkipDirLinks(ctx, newfrom, dirp->d_name, attr->recursion)) { continue; } memset(&dsb, 0, sizeof(struct stat)); /* Only copy dirs if we are tracking subdirs */ if ((!attr->copy.collapse) && (stat(newto, &dsb) == -1)) { if (mkdir(changes_newto, 0700) == -1) { RecordInterruption(ctx, pp, attr, "Can't make directory '%s'. (mkdir: %s)", newto, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); /* XXX: return result?!?!?! */ continue; } else { RecordChange(ctx, pp, attr, "Created directory '%s'", newto); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } if (stat(changes_newto, &dsb) == -1) { RecordInterruption(ctx, pp, attr, "Can't stat local copy '%s' - failed to establish directory. (stat: %s)", newto, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); /* XXX: return result?!?!?! */ continue; } } Log(LOG_LEVEL_VERBOSE, "Entering '%s'", newto); if (!attr->copy.collapse) { VerifyCopiedFileAttributes(ctx, newfrom, newto, &sb, &dsb, attr, pp); } result = PromiseResultUpdate(result, SourceSearchAndCopy(ctx, newfrom, newto, maxrecurse - 1, attr, pp, rootdevice, inode_cache, conn)); } else { result = PromiseResultUpdate(result, VerifyCopy(ctx, newfrom, newto, attr, pp, inode_cache, conn)); } if (conn != NULL && conn->conn_info->status != CONNECTIONINFO_STATUS_ESTABLISHED) { RecordInterruption(ctx, pp, attr, "connection error"); AbstractDirClose(dirh); return PROMISE_RESULT_INTERRUPTED; } } if (attr->copy.purge) { PurgeLocalFiles(ctx, namecache, to, attr, pp, conn); DeleteItemList(namecache); } AbstractDirClose(dirh); return result; } static PromiseResult VerifyCopy(EvalContext *ctx, const char *source, char *destination, const Attributes *attr, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn) { assert(attr != NULL); /* (conn == NULL) means copy is from localhost. */ const char *changes_source = source; bool local_changed_src = false; if ((conn == NULL) && ChrootChanges()) { const char *chrooted_source = ToChangesChroot(source); if (access(chrooted_source, F_OK) == 0) { local_changed_src = true; changes_source = chrooted_source; } } int found; struct stat ssb; if (attr->copy.link_type == FILE_LINK_TYPE_NONE) { Log(LOG_LEVEL_DEBUG, "Treating links as files for '%s'", source); found = cf_stat(changes_source, &ssb, &(attr->copy), conn); } else { found = cf_lstat(changes_source, &ssb, &(attr->copy), conn); } if (found == -1) { RecordFailure(ctx, pp, attr, "Can't stat '%s' in verify copy", source); return PROMISE_RESULT_FAIL; } PromiseResult result = PROMISE_RESULT_NOOP; if (ssb.st_nlink > 1) /* Preserve hard link structure when copying */ { RegisterAHardLink(ssb.st_ino, ToChangesPath(destination), ctx, pp, attr, &result, inode_cache); } if (S_ISDIR(ssb.st_mode)) { char sourcedir[CF_BUFSIZE]; strcpy(sourcedir, source); AddSlash(sourcedir); const char *changes_sourcedir = sourcedir; if (local_changed_src) { changes_sourcedir = ToChangesChroot(sourcedir); } AbstractDir *dirh; if ((dirh = AbstractDirOpen(changes_sourcedir, &(attr->copy), conn)) == NULL) { RecordFailure(ctx, pp, attr, "Can't open directory '%s'. (opendir: %s)", sourcedir, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } /* Now check any overrides */ char destdir[CF_BUFSIZE]; strcpy(destdir, destination); AddSlash(destdir); const char *changes_destdir = destdir; if (ChrootChanges()) { changes_destdir = ToChangesChroot(destdir); } struct stat dsb; if (stat(changes_destdir, &dsb) == -1) { RecordFailure(ctx, pp, attr, "Can't stat directory '%s'. (stat: %s)", destdir, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else { result = PromiseResultUpdate(result, VerifyCopiedFileAttributes(ctx, sourcedir, destdir, &ssb, &dsb, attr, pp)); } /* No backslashes over the network. */ const char sep = (conn != NULL) ? '/' : FILE_SEPARATOR; for (const struct dirent *dirp = AbstractDirRead(dirh); dirp != NULL; dirp = AbstractDirRead(dirh)) { if (!ConsiderAbstractFile(dirp->d_name, sourcedir, &(attr->copy), conn)) { if (conn != NULL && conn->conn_info->status != CONNECTIONINFO_STATUS_ESTABLISHED) { RecordInterruption(ctx, pp, attr, "Connection error when checking '%s'", dirp->d_name); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } else { Log(LOG_LEVEL_VERBOSE, "Skipping '%s'", dirp->d_name); } } char sourcefile[CF_BUFSIZE]; strcpy(sourcefile, sourcedir); if (!PathAppend(sourcefile, sizeof(sourcefile), dirp->d_name, sep)) { /* TODO return FAIL */ FatalError(ctx, "VerifyCopy sourcefile buffer limit"); } char destfile[CF_BUFSIZE]; strcpy(destfile, destdir); if (!PathAppend(destfile, sizeof(destfile), dirp->d_name, FILE_SEPARATOR)) { /* TODO return FAIL */ FatalError(ctx, "VerifyCopy destfile buffer limit"); } const char *changes_sourcefile = sourcefile; if (local_changed_src) { changes_sourcefile = ToChangesChroot(sourcefile); } if (attr->copy.link_type == FILE_LINK_TYPE_NONE) { if (cf_stat(changes_sourcefile, &ssb, &(attr->copy), conn) == -1) { RecordFailure(ctx, pp, attr, "Can't stat source file (notlinked) '%s'. (stat: %s)", sourcefile, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } } else { if (cf_lstat(changes_sourcefile, &ssb, &(attr->copy), conn) == -1) { RecordFailure(ctx, pp, attr, "Can't stat source file '%s'. (lstat: %s)", sourcefile, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } } result = PromiseResultUpdate(result, CfCopyFile(ctx, sourcefile, destfile, &ssb, attr, pp, inode_cache, conn)); } AbstractDirClose(dirh); return result; } else { /* TODO: are these copies necessary??? */ char sourcefile[CF_BUFSIZE]; char destfile[CF_BUFSIZE]; strcpy(sourcefile, source); strcpy(destfile, destination); return CfCopyFile(ctx, sourcefile, destfile, &ssb, attr, pp, inode_cache, conn); } } static PromiseResult LinkCopy(EvalContext *ctx, char *sourcefile, char *destfile, const struct stat *sb, const Attributes *attr, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn) /* Link the file to the source, instead of copying */ #ifdef __MINGW32__ { RecordFailure(ctx, pp, attr, "Can't link '%s' to '%s' (Windows does not support symbolic links)", sourcefile, destfile); return PROMISE_RESULT_FAIL; } #else /* !__MINGW32__ */ { assert(attr != NULL); char linkbuf[CF_BUFSIZE - 1]; const char *lastnode; PromiseResult result = PROMISE_RESULT_NOOP; linkbuf[0] = '\0'; /* (conn == NULL) means copy is from localhost. */ const char *changes_sourcefile = sourcefile; bool local_changed_src = false; if ((conn == NULL) && ChrootChanges()) { changes_sourcefile = ToChangesChroot(sourcefile); struct stat src_sb; local_changed_src = (lstat(changes_sourcefile, &src_sb) != -1); } char chrooted_linkbuf[sizeof(linkbuf)]; chrooted_linkbuf[0] = '\0'; if (S_ISLNK(sb->st_mode)) { if (local_changed_src) { if (cf_readlink(ctx, changes_sourcefile, chrooted_linkbuf, sizeof(chrooted_linkbuf), attr, pp, conn, &result) == -1) { RecordFailure(ctx, pp, attr, "Can't read link '%s'", sourcefile); return PROMISE_RESULT_FAIL; } if (IsAbsoluteFileName(chrooted_linkbuf)) { strlcpy(linkbuf, ToNormalRoot(chrooted_linkbuf), sizeof(linkbuf)); } else { strlcpy(linkbuf, chrooted_linkbuf, sizeof(linkbuf)); } } else { if (cf_readlink(ctx, sourcefile, linkbuf, sizeof(linkbuf), attr, pp, conn, &result) == -1) { RecordFailure(ctx, pp, attr, "Can't read link '%s'", sourcefile); return PROMISE_RESULT_FAIL; } } Log(LOG_LEVEL_VERBOSE, "Checking link from '%s' to '%s'", destfile, linkbuf); if ((attr->copy.link_type == FILE_LINK_TYPE_ABSOLUTE) && (!IsAbsoluteFileName(linkbuf))) /* Not absolute path - must fix */ { char vbuff[CF_BUFSIZE]; if (local_changed_src) { strlcpy(vbuff, changes_sourcefile, CF_BUFSIZE); ChopLastNode(vbuff); AddSlash(vbuff); strncat(vbuff, chrooted_linkbuf, CF_BUFSIZE - 1); strlcpy(chrooted_linkbuf, vbuff, CF_BUFSIZE - 1); } else { strlcpy(vbuff, sourcefile, CF_BUFSIZE); ChopLastNode(vbuff); AddSlash(vbuff); strncat(vbuff, linkbuf, CF_BUFSIZE - 1); strlcpy(linkbuf, vbuff, CF_BUFSIZE - 1); } } } else { if (local_changed_src) { strlcpy(chrooted_linkbuf, changes_sourcefile, CF_BUFSIZE - 1); } else { strlcpy(linkbuf, sourcefile, CF_BUFSIZE - 1); } } lastnode = ReadLastNode(sourcefile); if (MatchRlistItem(ctx, attr->copy.copy_links, lastnode)) { if (local_changed_src) { ExpandLinks(chrooted_linkbuf, changes_sourcefile, 0, CF_MAXLINKLEVEL); strlcpy(linkbuf, ToNormalRoot(chrooted_linkbuf), sizeof(linkbuf)); } else { ExpandLinks(linkbuf, sourcefile, 0, CF_MAXLINKLEVEL); } Log(LOG_LEVEL_VERBOSE, "Link item in copy '%s' marked for copying from '%s' instead", sourcefile, linkbuf); struct stat ssb; if (local_changed_src) { stat(chrooted_linkbuf, &ssb); } else { stat(linkbuf, &ssb); } /* CfCopyFiles() does the chrooting (if necessary) on its second * argument so we need to always give it the original path. */ return CfCopyFile(ctx, linkbuf, destfile, &ssb, attr, pp, inode_cache, conn); } int status; switch (attr->copy.link_type) { case FILE_LINK_TYPE_SYMLINK: if (*linkbuf == '.') { status = VerifyRelativeLink(ctx, destfile, linkbuf, attr, pp); } else { status = VerifyLink(ctx, destfile, linkbuf, attr, pp); } break; case FILE_LINK_TYPE_RELATIVE: status = VerifyRelativeLink(ctx, destfile, linkbuf, attr, pp); break; case FILE_LINK_TYPE_ABSOLUTE: status = VerifyAbsoluteLink(ctx, destfile, linkbuf, attr, pp); break; case FILE_LINK_TYPE_HARDLINK: status = VerifyHardLink(ctx, destfile, linkbuf, attr, pp); break; default: ProgrammingError("Unhandled link type in switch: %d", attr->copy.link_type); } if ((status == PROMISE_RESULT_CHANGE) || (status == PROMISE_RESULT_NOOP)) { const char *changes_destfile = destfile; if (ChrootChanges()) { changes_destfile = ToChangesChroot(destfile); } struct stat dsb; if (lstat(changes_destfile, &dsb) == -1) { RecordFailure(ctx, pp, attr, "Can't lstat '%s'. (lstat: %s)", destfile, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } else { result = PromiseResultUpdate(result, VerifyCopiedFileAttributes(ctx, sourcefile, destfile, sb, &dsb, attr, pp)); } } return result; } #endif /* !__MINGW32__ */ bool CopyRegularFile(EvalContext *ctx, const char *source, const char *dest, const struct stat *sstat, const Attributes *attr, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn, PromiseResult *result) { assert(attr != NULL); assert(sstat != NULL); char new[CF_BUFSIZE], *linkable; int remote = false, backupisdir = false, backupok = false, discardbackup; #ifdef HAVE_UTIME_H struct utimbuf timebuf; #endif #ifdef __APPLE__ /* For later copy from new to dest */ char *rsrcbuf; int rsrcbytesr; /* read */ int rsrcbytesw; /* written */ int rsrcbytesl; /* to read */ int rsrcrd; int rsrcwd; /* Keep track of if a resrouce fork */ int rsrcfork = 0; #endif discardbackup = ((attr->copy.backup == BACKUP_OPTION_NO_BACKUP) || (attr->copy.backup == BACKUP_OPTION_REPOSITORY_STORE)); if (!MakingChanges(ctx, pp, attr, result, "copy '%s' to '%s'", source, dest)) { return false; } /* Make an assoc array of inodes used to preserve hard links */ linkable = CompressedArrayValue(*inode_cache, sstat->st_ino); /* If making changes in chroot, we need to make sure the target is in the * changes chroot before we create the hardlink. */ if (ChrootChanges() && (linkable != NULL) && (sstat->st_nlink > 1)) { PrepareChangesChroot(linkable); } if (sstat->st_nlink > 1) /* Preserve hard links, if possible */ { if ((linkable != NULL) && (strcmp(dest, linkable) != 0)) { if (unlink(ToChangesPath(dest)) == 0) { RecordChange(ctx, pp, attr, "Removed '%s'", dest); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } MakeHardLink(ctx, dest, linkable, attr, pp, result); return true; } } if (conn != NULL) { assert(attr->copy.servers && strcmp(RlistScalarValue(attr->copy.servers), "localhost")); Log(LOG_LEVEL_DEBUG, "This is a remote copy from server '%s'", RlistScalarValue(attr->copy.servers)); remote = true; } #ifdef __APPLE__ if (strstr(dest, _PATH_RSRCFORKSPEC)) { char *tmpstr = xstrndup(dest, CF_BUFSIZE); rsrcfork = 1; /* Drop _PATH_RSRCFORKSPEC */ char *forkpointer = strstr(tmpstr, _PATH_RSRCFORKSPEC); *forkpointer = '\0'; strlcpy(new, tmpstr, CF_BUFSIZE); free(tmpstr); } else #endif { strlcpy(new, dest, CF_BUFSIZE); if (!JoinSuffix(new, sizeof(new), CF_NEW)) { Log(LOG_LEVEL_ERR, "Unable to construct filename for copy"); return false; } } struct stat dest_stat; int ret = stat(ToChangesPath(dest), &dest_stat); bool dest_exists = (ret == 0); if (remote) { if (conn->error) { RecordFailure(ctx, pp, attr, "Failed to copy file '%s' from '%s' (connection error)", source, conn->remoteip); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (!CopyRegularFileNet(source, ToChangesPath(new), sstat->st_size, attr->copy.encrypt, conn, sstat->st_mode)) { RecordFailure(ctx, pp, attr, "Failed to copy file '%s' from '%s'", source, conn->remoteip); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, attr, "Copied file '%s' from '%s' to '%s'", source, conn->remoteip, new); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { const char *changes_source = source; char *chrooted_source = NULL; if (ChrootChanges()) { /* Need to create a copy because the next ToChangesChroot() call * will override the internal buffer. */ chrooted_source = xstrdup(ToChangesChroot(source)); struct stat sb; if (lstat(chrooted_source, &sb) != -1) { changes_source = chrooted_source; } } // If preserve is true, retain permissions of source file if (attr->copy.preserve) { if (!CopyRegularFileDisk(changes_source, ToChangesPath(new))) { RecordFailure(ctx, pp, attr, "Failed copying file '%s' to '%s'", source, new); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, attr, "Copied file '%s' to '%s' (permissions preserved)", source, new); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { // Never preserve SUID bit (0777) int mode = dest_exists ? (dest_stat.st_mode & 0777) : CF_PERMS_DEFAULT; if (!CopyRegularFileDiskPerms(changes_source, ToChangesPath(new), mode)) { RecordFailure(ctx, pp, attr, "Failed copying file '%s' to '%s'", source, new); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } RecordChange(ctx, pp, attr, "Copied file '%s' to '%s' (mode '%jo')", source, new, (uintmax_t) mode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } free(chrooted_source); #ifdef HAVE_UTIME_H if (attr->copy.stealth) { timebuf.actime = sstat->st_atime; timebuf.modtime = sstat->st_mtime; utime(source, &timebuf); } #endif } Log(LOG_LEVEL_VERBOSE, "Copy of regular file succeeded '%s' to '%s'", source, new); char backup[CF_BUFSIZE]; char chrooted_backup[CF_BUFSIZE]; const char *changes_backup = backup; backup[0] = '\0'; chrooted_backup[0] = '\0'; /* XXX: Do RecordChange() for the changes done below? They are just "behind * the scenes" changes the user maybe doesn't care about if they just * work? */ if (dest_exists) { if (!discardbackup) { char stamp[CF_BUFSIZE]; time_t stampnow; Log(LOG_LEVEL_DEBUG, "Backup file '%s'", source); strlcpy(backup, dest, CF_BUFSIZE); if (attr->copy.backup == BACKUP_OPTION_TIMESTAMP) { stampnow = time((time_t *) NULL); snprintf(stamp, CF_BUFSIZE - 1, "_%lu_%s", CFSTARTTIME, CanonifyName(ctime(&stampnow))); if (!JoinSuffix(backup, sizeof(backup), stamp)) { RecordFailure(ctx, pp, attr, "Failed to determine file name for the backup of '%s'", dest); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } } if (!JoinSuffix(backup, sizeof(backup), CF_SAVED)) { RecordFailure(ctx, pp, attr, "Failed to determine file name for the backup of '%s'", dest); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (ChrootChanges()) { strlcpy(chrooted_backup, ToChangesChroot(backup), CF_BUFSIZE); changes_backup = chrooted_backup; } Log(LOG_LEVEL_VERBOSE, "Backup for '%s' is '%s'", dest, backup); /* Now in case of multiple copies of same object, * try to avoid overwriting original backup */ if (lstat(changes_backup, &dest_stat) != -1) { /* if there is a dir in the way */ if (S_ISDIR(dest_stat.st_mode)) { backupisdir = true; /* PurgeLocalFiles() does ToChangesChroot() internally (if * needed). */ PurgeLocalFiles(ctx, NULL, backup, attr, pp, conn); if (rmdir(changes_backup) == 0) { RecordChange(ctx, pp, attr, "Removed old backup directory '%s'", backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to remove old backup directory '%s'", backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } if (unlink(changes_backup) == 0) { RecordChange(ctx, pp, attr, "Removed old backup '%s'", backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to remove old backup '%s'", backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } if (CopyRegularFileDisk(dest, changes_backup)) { RecordChange(ctx, pp, attr, "Backed up '%s' as '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to back up '%s' as '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } /* Did the rename() succeed? NFS-safe */ backupok = (lstat(changes_backup, &dest_stat) != -1); } else { /* Discarding backup */ /* Mainly important if there is a dir in the way */ if (S_ISDIR(dest_stat.st_mode)) { /* PurgeLocalFiles does ToChangesChroot(dest) internally. */ PurgeLocalFiles(ctx, NULL, dest, attr, pp, conn); if (rmdir(ToChangesPath(dest)) == 0) { RecordChange(ctx, pp, attr, "Removed directory '%s'", dest); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to remove directory '%s'", dest); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } } } const char *changes_new = new; char *chrooted_new = NULL; if (ChrootChanges()) { chrooted_new = xstrdup(ToChangesChroot(new)); changes_new = chrooted_new; } const char *changes_dest = dest; if (ChrootChanges()) { changes_dest = ToChangesChroot(dest); } struct stat new_stat; if (lstat(changes_new, &new_stat) == -1) { RecordFailure(ctx, pp, attr, "Can't stat new file '%s' - another agent has picked it up?. (stat: %s)", new, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); free(chrooted_new); return false; } if ((S_ISREG(new_stat.st_mode)) && (new_stat.st_size != sstat->st_size)) { RecordFailure(ctx, pp, attr, "New file '%s' seems to have been corrupted in transit," " destination size (%zd) differs from the source size (%zd), aborting.", new, (size_t) new_stat.st_size, (size_t) sstat->st_size); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); if (backupok && (rename(changes_backup, changes_dest) == 0)) { RecordChange(ctx, pp, attr, "Restored '%s' from '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Could not restore '%s' as '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } free(chrooted_new); return false; } if (attr->copy.verify) { Log(LOG_LEVEL_VERBOSE, "Final verification of transmission ..."); if (CompareFileHashes(source, changes_new, sstat, &new_stat, &(attr->copy), conn)) { RecordFailure(ctx, pp, attr, "New file '%s' seems to have been corrupted in transit, aborting.", new); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); if (backupok && (rename(changes_backup, changes_dest) == 0)) { RecordChange(ctx, pp, attr, "Restored '%s' from '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Could not restore '%s' as '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } free(chrooted_new); return false; } else { Log(LOG_LEVEL_VERBOSE, "New file '%s' transmitted correctly - verified", new); } } #ifdef __APPLE__ if (rsrcfork) { /* Can't just "mv" the resource fork, unfortunately */ rsrcrd = safe_open(changes_new, O_RDONLY | O_BINARY); rsrcwd = safe_open(changes_dest, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC); if (rsrcrd == -1 || rsrcwd == -1) { Log(LOG_LEVEL_INFO, "Open of Darwin resource fork rsrcrd/rsrcwd failed. (open: %s)", GetErrorStr()); close(rsrcrd); close(rsrcwd); free(chrooted_new); return (false); } rsrcbuf = xmalloc(CF_BUFSIZE); rsrcbytesr = 0; while (1) { rsrcbytesr = read(rsrcrd, rsrcbuf, CF_BUFSIZE); if (rsrcbytesr == -1) { /* Ck error */ if (errno == EINTR) { continue; } else { RecordFailure(ctx, pp, attr, "Read of Darwin resource fork rsrcrd '%s' failed (read: %s)", new, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); close(rsrcrd); close(rsrcwd); free(rsrcbuf); free(chrooted_new); return (false); } } else if (rsrcbytesr == 0) { /* Reached EOF */ close(rsrcrd); close(rsrcwd); free(rsrcbuf); if (unlink(changes_new) == 0) { RecordChange(ctx, pp, attr, "Moved resource fork '%s' to '%s'", new, dest); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to remove resource fork '%s'", new); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); /* not a fatal failure, just record it and keep moving */ } break; } rsrcbytesl = rsrcbytesr; rsrcbytesw = 0; while (rsrcbytesl > 0) { rsrcbytesw += write(rsrcwd, rsrcbuf, rsrcbytesl); if (rsrcbytesw == -1) { if (errno == EINTR) { continue; } else { RecordFailure(ctx, pp, attr, "Write of Darwin resource fork rsrcwd '%s' failed (write: %s)", dest, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); close(rsrcrd); close(rsrcwd); free(rsrcbuf); free(chrooted_new); return (false); } } rsrcbytesl = rsrcbytesr - rsrcbytesw; } } } else #endif { if (rename(changes_new, changes_dest) == 0) { RecordChange(ctx, pp, attr, "Moved '%s' to '%s'", new, dest); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Could not install copy file as '%s', directory in the way?. (rename: %s)", dest, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); if (backupok && (rename(changes_backup, changes_dest) == 0)) { RecordChange(ctx, pp, attr, "Restored '%s' from '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Could not restore '%s' as '%s'", dest, backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } free(chrooted_new); return false; } } free(chrooted_new); if ((!discardbackup) && backupisdir) { Log(LOG_LEVEL_INFO, "Cannot move a directory to repository, leaving at '%s'", backup); } else if ((!discardbackup) && (ArchiveToRepository(changes_backup, attr))) { RecordChange(ctx, pp, attr, "Archived backup '%s'", backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); if (unlink(changes_backup) != 0) { RecordFailure(ctx, pp, attr, "Failed to clean backup '%s' after archiving", backup); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } #ifdef HAVE_UTIME_H if (attr->copy.stealth) { timebuf.actime = sstat->st_atime; timebuf.modtime = sstat->st_mtime; utime(dest, &timebuf); } #endif return true; } static bool TransformFile(EvalContext *ctx, char *file, const Attributes *attr, const Promise *pp, PromiseResult *result) { assert(attr != NULL); FILE *pop = NULL; int transRetcode = 0; if (attr->transformer == NULL || file == NULL) { return false; } Buffer *command = BufferNew(); ExpandScalar(ctx, PromiseGetBundle(pp)->ns, PromiseGetBundle(pp)->name, attr->transformer, command); if (!IsExecutable(CommandArg0(BufferData(command)))) { RecordFailure(ctx, pp, attr, "Transformer '%s' for file '%s' failed", attr->transformer, file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); BufferDestroy(command); return false; } const char * const command_str = BufferData(command); if (MakingChanges(ctx, pp, attr, result, "transform file '%s' with '%s'", file, command_str)) { CfLock thislock = AcquireLock(ctx, command_str, VUQNAME, CFSTARTTIME, attr->transaction.ifelapsed, attr->transaction.expireafter, pp, false); if (thislock.lock == NULL) { BufferDestroy(command); return false; } const char *changes_command = command_str; char *chrooted_command = NULL; if (ChrootChanges()) { size_t command_len = BufferSize(command); chrooted_command = xmalloc(command_len + PATH_MAX + 1); strncpy(chrooted_command, command_str, command_len + 1); ssize_t ret = StringReplace(chrooted_command, command_len + PATH_MAX + 1, file, ToChangesChroot(file)); if ((ret <= 0) || ((size_t) ret == command_len + PATH_MAX + 1)) { RecordFailure(ctx, pp, attr, "Failed to replace path '%s' in transformer command '%s' for changes chroot", file, command_str); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); YieldCurrentLock(thislock); BufferDestroy(command); free(chrooted_command); return false; } else { changes_command = chrooted_command; } } Log(LOG_LEVEL_INFO, "Transforming '%s' with '%s'", file, command_str); if ((pop = cf_popen(changes_command, "r", true)) == NULL) { RecordFailure(ctx, pp, attr, "Transformer '%s' for file '%s' failed", attr->transformer, file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); YieldCurrentLock(thislock); BufferDestroy(command); free(chrooted_command); return false; } free(chrooted_command); size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = CfReadLine(&line, &line_size, pop); if (res == -1) { if (!feof(pop)) { cf_pclose(pop); RecordFailure(ctx, pp, attr, "Transformer '%s' for file '%s' failed", attr->transformer, file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); YieldCurrentLock(thislock); free(line); BufferDestroy(command); return false; } else { break; } } Log(LOG_LEVEL_INFO, "%s", line); } RecordChange(ctx, pp, attr, "Transformed '%s' with '%s' ", file, command_str); free(line); transRetcode = cf_pclose(pop); if (VerifyCommandRetcode(ctx, transRetcode, attr, pp, result)) { Log(LOG_LEVEL_INFO, "Transformer '%s' => '%s' seemed to work ok", file, command_str); } else { Log(LOG_LEVEL_ERR, "Transformer '%s' => '%s' returned error", file, command_str); } YieldCurrentLock(thislock); } BufferDestroy(command); return true; } static PromiseResult VerifyName(EvalContext *ctx, char *path, const struct stat *sb, const Attributes *attr, const Promise *pp) { assert(attr != NULL); mode_t newperm; struct stat dsb; const char *changes_path = path; char *chrooted_path = NULL; if (ChrootChanges()) { chrooted_path = xstrdup(ToChangesChroot(path)); changes_path = chrooted_path; } if (lstat(changes_path, &dsb) == -1) { RecordNoChange(ctx, pp, attr, "File object named '%s' is not there (promise kept)", path); free(chrooted_path); return PROMISE_RESULT_NOOP; } else { if (attr->rename.disable) { /* XXX: Why should attr->rename.disable imply that the file doesn't exist? */ Log(LOG_LEVEL_WARNING, "File object '%s' exists, contrary to promise", path); } } PromiseResult result = PROMISE_RESULT_NOOP; if (attr->rename.newname != NULL) { char newname[CF_BUFSIZE]; if (IsAbsoluteFileName(attr->rename.newname)) { size_t copied = strlcpy(newname, attr->rename.newname, sizeof(newname)); if (copied > sizeof(newname)) { RecordFailure(ctx, pp, attr, "Internal buffer limit in rename operation, new name too long: '%s'", attr->rename.newname); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); free(chrooted_path); return result; } } else { strncpy(newname, path, sizeof(newname) - 1); ChopLastNode(newname); if (!PathAppend(newname, sizeof(newname), attr->rename.newname, FILE_SEPARATOR)) { RecordFailure(ctx, pp, attr, "Internal buffer limit in rename operation, destination: '%s' + '%s'", newname, attr->rename.newname); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); free(chrooted_path); return result; } } const char *changes_newname = newname; if (ChrootChanges()) { changes_newname = ToChangesChroot(newname); } if (MakingChanges(ctx, pp, attr, &result, "rename file '%s' to '%s'", path, newname)) { if (!FileInRepository(newname)) { if (rename(changes_path, changes_newname) == -1) { RecordFailure(ctx, pp, attr, "Error occurred while renaming '%s'. (rename: %s)", path, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else { if (ChrootChanges()) { RecordFileRenamedInChroot(path, newname); } RecordChange(ctx, pp, attr, "Renamed file '%s' to '%s'", path, newname); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } else { RecordWarning(ctx, pp, attr, "Renaming '%s' to same destination twice would overwrite saved copy - aborting", path); result = PromiseResultUpdate(result, PROMISE_RESULT_WARN); } } free(chrooted_path); return result; } if (S_ISLNK(dsb.st_mode)) { if (attr->rename.disable) { if (MakingChanges(ctx, pp, attr, &result, "disable link '%s'", path)) { if (unlink(changes_path) == -1) { RecordFailure(ctx, pp, attr, "Unable to unlink '%s'. (unlink: %s)", path, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else { RecordChange(ctx, pp, attr, "Disabled symbolic link '%s' by deleting it", path); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } free(chrooted_path); return result; } } /* Normal disable - has priority */ if (attr->rename.disable) { char newname[CF_BUFSIZE]; if (!MakingChanges(ctx, pp, attr, &result, "rename '%s' '%s'", S_ISDIR(sb->st_mode) ? "directory" : "file", path)) { free(chrooted_path); return result; } if (attr->rename.newname && strlen(attr->rename.newname) > 0) { if (IsAbsoluteFileName(attr->rename.newname)) { strlcpy(newname, attr->rename.newname, CF_BUFSIZE); } else { strcpy(newname, path); ChopLastNode(newname); if (!PathAppend(newname, sizeof(newname), attr->rename.newname, FILE_SEPARATOR)) { RecordFailure(ctx, pp, attr, "Internal buffer limit in rename operation, destination: '%s' + '%s'", newname, attr->rename.newname); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); free(chrooted_path); return result; } } } else { strcpy(newname, path); if (attr->rename.disable_suffix) { if (!JoinSuffix(newname, sizeof(newname), attr->rename.disable_suffix)) { RecordFailure(ctx, pp, attr, "Failed to append disable suffix '%s' in rename operation for '%s'", attr->rename.disable_suffix, path); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); free(chrooted_path); return result; } } else { if (!JoinSuffix(newname, sizeof(newname), ".cfdisabled")) { RecordFailure(ctx, pp, attr, "Failed to append disable suffix '.cfdisabled' in rename operation for '%s'", path); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); free(chrooted_path); return result; } } } const char *changes_newname = newname; if (ChrootChanges()) { changes_newname = ToChangesChroot(newname); } if ((attr->rename.plus != CF_SAMEMODE) && (attr->rename.minus != CF_SAMEMODE)) { newperm = (sb->st_mode & 07777); newperm |= attr->rename.plus; newperm &= ~(attr->rename.minus); } else { newperm = (mode_t) 0600; } if (MakingChanges(ctx, pp, attr, &result, "rename file '%s' to '%s'", path, newname)) { if (safe_chmod(changes_path, newperm) == 0) { RecordChange(ctx, pp, attr, "Changed permissions of '%s' to 'mode %04jo'", path, (uintmax_t)newperm); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to change permissions of '%s' to 'mode %04jo' (%s)", path, (uintmax_t)newperm, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } if (!FileInRepository(newname)) { if (rename(changes_path, changes_newname) == -1) { RecordFailure(ctx, pp, attr, "Error occurred while renaming '%s'. (rename: %s)", path, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); free(chrooted_path); return result; } else { if (ChrootChanges()) { RecordFileRenamedInChroot(path, newname); } RecordChange(ctx, pp, attr, "Disabled file '%s' by renaming to '%s' with mode %04jo", path, newname, (uintmax_t)newperm); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } if (ArchiveToRepository(newname, attr)) { /* TODO: ArchiveToRepository() does * Log(LOG_LEVEL_INFO, "Moved '%s' to repository location '%s'", file, destination) * but we should do LogChange() instead. (maybe just add 'char **destination' * argument to the function?) */ unlink(changes_newname); } } else { RecordWarning(ctx, pp, attr, "Disable required twice? Would overwrite saved copy - changing permissions only"); result = PromiseResultUpdate(result, PROMISE_RESULT_WARN); } } free(chrooted_path); return result; } if (attr->rename.rotate == 0) { if (MakingChanges(ctx, pp, attr, &result, "truncate '%s'", path)) { TruncateFile(changes_path); RecordChange(ctx, pp, attr, "Truncated '%s'", path); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } free(chrooted_path); return result; } if (attr->rename.rotate > 0) { if (MakingChanges(ctx, pp, attr, &result, "rotate file '%s' in %d fifo", path, attr->rename.rotate)) { RotateFiles(changes_path, attr->rename.rotate); RecordChange(ctx, pp, attr, "Rotated file '%s' in %d fifo", path, attr->rename.rotate); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } free(chrooted_path); return result; } free(chrooted_path); return result; } static PromiseResult VerifyDelete(EvalContext *ctx, const char *path, const struct stat *sb, const Attributes *attr, const Promise *pp) { assert(attr != NULL); Log(LOG_LEVEL_VERBOSE, "Verifying file deletions for '%s'", path); const char *changes_path = path; if (ChrootChanges()) { changes_path = ToChangesChroot(path); } const char *lastnode = ReadLastNode(changes_path); PromiseResult result = PROMISE_RESULT_NOOP; if (MakingChanges(ctx, pp, attr, &result, "delete %s '%s'", S_ISDIR(sb->st_mode) ? "directory" : "file", path)) { if (!S_ISDIR(sb->st_mode)) /* file,symlink */ { int ret = unlink(lastnode); if (ret == -1) { RecordFailure(ctx, pp, attr, "Couldn't unlink '%s' tidying. (unlink: %s)", path, GetErrorStr()); return PROMISE_RESULT_FAIL; } else { RecordChange(ctx, pp, attr, "Deleted file '%s'", path); return PROMISE_RESULT_CHANGE; } } else /* directory */ { if (!attr->delete.rmdirs) { RecordNoChange(ctx, pp, attr, "Keeping directory '%s' since 'rmdirs' attribute was not specified", path); return PROMISE_RESULT_NOOP; } if (attr->havedepthsearch && strcmp(path, pp->promiser) == 0) { Log(LOG_LEVEL_DEBUG, "Skipping deletion of parent directory for recursive promise '%s', " "you must specify separate promise for deleting", path); return PROMISE_RESULT_NOOP; } int ret = rmdir(lastnode); if (ret == -1 && errno != EEXIST && errno != ENOTEMPTY) { RecordFailure(ctx, pp, attr, "Delete directory '%s' failed (rmdir: %s)", path, GetErrorStr()); return PROMISE_RESULT_FAIL; } else if (ret == -1 && (errno == EEXIST || errno == ENOTEMPTY)) { /* It's never allowed to delete non-empty directories, they * are silently skipped. */ Log(LOG_LEVEL_VERBOSE, "Delete directory '%s' not empty, skipping", path); return PROMISE_RESULT_NOOP; } else { assert(ret != -1); RecordChange(ctx, pp, attr, "Deleted directory '%s'", path); return PROMISE_RESULT_CHANGE; } } } return result; } static PromiseResult TouchFile(EvalContext *ctx, char *path, const Attributes *attr, const Promise *pp) { PromiseResult result = PROMISE_RESULT_NOOP; if (MakingChanges(ctx, pp, attr, &result, "update time stamps for '%s'", path)) { if (utime(ToChangesPath(path), NULL) != -1) { RecordChange(ctx, pp, attr, "Touched (updated time stamps) for path '%s'", path); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Touch '%s' failed to update timestamps. (utime: %s)", path, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } return result; } static inline char *GetFileTypeDescription(const struct stat *const stat_buf, const char *const filename) { /* Use lstat to check if this is a symlink, and don't worry about race * conditions as the returned string is only used for a log message. */ struct stat sb; const bool is_link = (lstat(filename, &sb) == 0 && S_ISLNK(sb.st_mode)); switch (stat_buf->st_mode & S_IFMT) { case S_IFREG: return (is_link) ? "Symbolic link to regular file" : "Regular file"; case S_IFDIR: return (is_link) ? "Symbolic link to directory" : "Directory"; case S_IFSOCK: return (is_link) ? "Symbolic link to socket" : "Socket"; case S_IFIFO: return (is_link) ? "Symbolic link to named pipe" : "Named pipe"; case S_IFBLK: return (is_link) ? "Symbolic link to block device" : "Block device"; case S_IFCHR: return (is_link) ? "Symbolic link to character device" : "Character device"; default: return (is_link) ? "Symbolic link to object" : "Object"; } } static PromiseResult VerifyFileAttributes(EvalContext *ctx, const char *file, const struct stat *dstat, const Attributes *attr, const Promise *pp) { PromiseResult result = PROMISE_RESULT_NOOP; #ifndef __MINGW32__ mode_t newperm = dstat->st_mode, maskvalue; # if defined HAVE_CHFLAGS u_long newflags; # endif maskvalue = umask(0); /* This makes the DEFAULT modes absolute */ newperm = (dstat->st_mode & 07777); if ((attr->perms.plus != CF_SAMEMODE) && (attr->perms.minus != CF_SAMEMODE)) { newperm |= attr->perms.plus; newperm &= ~(attr->perms.minus); /* directories must have x set if r set, regardless */ if (S_ISDIR(dstat->st_mode)) { if (attr->perms.rxdirs) { Log(LOG_LEVEL_DEBUG, "Directory...fixing x bits"); if (newperm & S_IRUSR) { newperm |= S_IXUSR; } if (newperm & S_IRGRP) { newperm |= S_IXGRP; } if (newperm & S_IROTH) { newperm |= S_IXOTH; } } else { Log(LOG_LEVEL_VERBOSE, "NB: rxdirs is set to false - x for r bits not checked"); } } } result = PromiseResultUpdate(result, VerifySetUidGid(ctx, file, dstat, newperm, pp, attr)); # ifdef __APPLE__ if (VerifyFinderType(ctx, file, attr, pp, &result)) { /* nop */ } # endif #endif if (VerifyOwner(ctx, file, pp, attr, dstat, &result)) { /* nop */ } #ifdef __MINGW32__ if (NovaWin_FileExists(file) && !NovaWin_IsDir(file)) #else if (attr->havechange && S_ISREG(dstat->st_mode)) #endif { result = PromiseResultUpdate(result, VerifyFileIntegrity(ctx, file, attr, pp)); } if (attr->havechange) { VerifyFileChanges(ctx, file, dstat, attr, pp, &result); } #ifndef __MINGW32__ if (S_ISLNK(dstat->st_mode)) /* No point in checking permission on a link */ { KillGhostLink(ctx, file, attr, pp, &result); umask(maskvalue); return result; } #endif const char *changes_file = file; #ifndef __MINGW32__ result = PromiseResultUpdate(result, VerifySetUidGid(ctx, file, dstat, dstat->st_mode, pp, attr)); if (ChrootChanges()) { changes_file = ToChangesChroot(file); } if ((newperm & 07777) == (dstat->st_mode & 07777)) /* file okay */ { Log(LOG_LEVEL_DEBUG, "File okay, newperm '%jo', stat '%jo'", (uintmax_t) (newperm & 07777), (uintmax_t) (dstat->st_mode & 07777)); RecordNoChange(ctx, pp, attr, "File permissions on '%s' as promised", file); result = PromiseResultUpdate(result, PROMISE_RESULT_NOOP); } else { Log(LOG_LEVEL_DEBUG, "Trying to fix mode...newperm '%jo', stat '%jo'", (uintmax_t) (newperm & 07777), (uintmax_t) (dstat->st_mode & 07777)); if (MakingChanges(ctx, pp, attr, &result, "change permissions of '%s' from %04jo to %04jo", file, (uintmax_t)dstat->st_mode & 07777, (uintmax_t)newperm & 07777)) { if (safe_chmod(changes_file, newperm & 07777) == -1) { RecordFailure(ctx, pp, attr, "Failed to change permissions of '%s'. (chmod: %s)", file, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else { const char *const object = GetFileTypeDescription(dstat, file); RecordChange(ctx, pp, attr, "%s '%s' had permissions %04jo, changed it to %04jo", object, file, (uintmax_t)dstat->st_mode & 07777, (uintmax_t)newperm & 07777); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } } # if defined HAVE_CHFLAGS /* BSD special flags */ newflags = (dstat->st_flags & CHFLAGS_MASK); newflags |= attr->perms.plus_flags; newflags &= ~(attr->perms.minus_flags); if ((newflags & CHFLAGS_MASK) == (dstat->st_flags & CHFLAGS_MASK)) { RecordNoChange(ctx, pp, attr, "BSD flags of '%s' are as promised ('%jx')", file, (uintmax_t) (dstat->st_flags & CHFLAGS_MASK)); } else { Log(LOG_LEVEL_DEBUG, "BSD Fixing '%s', newflags '%jx', flags '%jx'", file, (uintmax_t) (newflags & CHFLAGS_MASK), (uintmax_t) (dstat->st_flags & CHFLAGS_MASK)); if (MakingChanges(ctx, pp, attr, &result, "change BSD flags of '%s' from %jo to %jo", file, (uintmax_t) (dstat->st_mode & CHFLAGS_MASK), (uintmax_t) (newflags & CHFLAGS_MASK))) { if (chflags(changes_file, newflags & CHFLAGS_MASK) == -1) { RecordDenial(ctx, pp, attr, "Failed setting BSD flags '%jx' on '%s'. (chflags: %s)", (uintmax_t) newflags, file, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_DENIED); } else { RecordChange(ctx, pp, attr, "'%s' had flags %jo, changed it to %jo", file, (uintmax_t) (dstat->st_flags & CHFLAGS_MASK), (uintmax_t) (newflags & CHFLAGS_MASK)); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } } # endif #endif if (attr->acl.acl_entries) { result = PromiseResultUpdate(result, VerifyACL(ctx, file, attr, pp)); } /* Need to refresh 'changes_file' here because VerifyACL() above modifies * the internal buffer used by ToChangesChroot(). */ if (ChrootChanges()) { changes_file = ToChangesChroot(file); } if (attr->touch) { if (utime(changes_file, NULL) == -1) { RecordDenial(ctx, pp, attr, "Updating timestamps on '%s' failed. (utime: %s)", file, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_DENIED); } else { RecordChange(ctx, pp, attr, "Updated timestamps on '%s'", file); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } #ifndef __MINGW32__ umask(maskvalue); #endif return result; } bool DepthSearch(EvalContext *ctx, char *name, const struct stat *sb, int rlevel, const Attributes *attr, const Promise *pp, dev_t rootdevice, PromiseResult *result) { assert(attr != NULL); Dir *dirh; int goback; const struct dirent *dirp; struct stat lsb; Seq *db_file_set = NULL; Seq *selected_files = NULL; bool retval = true; if (!attr->havedepthsearch) /* if the search is trivial, make sure that we are in the parent dir of the leaf */ { char basedir[CF_BUFSIZE]; Log(LOG_LEVEL_DEBUG, "Direct file reference '%s', no search implied", name); strlcpy(basedir, ToChangesPath(name), sizeof(basedir)); ChopLastNode(basedir); if (safe_chdir(basedir)) { Log(LOG_LEVEL_ERR, "Failed to chdir into '%s'. (chdir: '%s')", basedir, GetErrorStr()); return false; } if (!attr->haveselect || SelectLeaf(ctx, name, sb, &(attr->select))) { /* Renames are handled separately. */ if ((EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST_FULL) && !attr->haverename) { RecordFileEvaluatedInChroot(name); } VerifyFileLeaf(ctx, name, sb, attr, pp, result); return true; } else { return false; } } if (rlevel > CF_RECURSION_LIMIT) { RecordWarning(ctx, pp, attr, "Very deep nesting of directories (>%d deep) for '%s' (Aborting files)", rlevel, name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (!PushDirState(ctx, pp, attr, name, sb, result)) { /* PushDirState() reports errors and updates 'result' in case of failures */ return false; } if ((dirh = DirOpen(".")) == NULL) { Log(LOG_LEVEL_INFO, "Could not open existing directory '%s'. (opendir: %s)", name, GetErrorStr()); return false; } if (attr->havechange) { db_file_set = SeqNew(1, &free); if (!FileChangesGetDirectoryList(name, db_file_set)) { RecordFailure(ctx, pp, attr, "Failed to get directory listing for recording file changes in '%s'", name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); SeqDestroy(db_file_set); return false; } selected_files = SeqNew(1, &free); } char path[CF_BUFSIZE]; for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!ConsiderLocalFile(dirp->d_name, name)) { continue; } size_t total_len = strlcpy(path, name, sizeof(path)); if ((total_len >= sizeof(path)) || (JoinPaths(path, sizeof(path), dirp->d_name) == NULL)) { RecordFailure(ctx, pp, attr, "Internal limit reached in DepthSearch(), path too long: '%s' + '%s'", path, dirp->d_name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); retval = false; goto end; } if (lstat(dirp->d_name, &lsb) == -1) { Log(LOG_LEVEL_VERBOSE, "Recurse was looking at '%s' when an error occurred. (lstat: %s)", path, GetErrorStr()); continue; } if (S_ISLNK(lsb.st_mode)) /* should we ignore links? */ { if (KillGhostLink(ctx, path, attr, pp, result)) { if (ChrootChanges()) { RecordFileChangedInChroot(path); } continue; } } /* See if we are supposed to treat links to dirs as dirs and descend */ if ((attr->recursion.travlinks) && (S_ISLNK(lsb.st_mode))) { if ((lsb.st_uid != 0) && (lsb.st_uid != getuid())) { Log(LOG_LEVEL_INFO, "File '%s' is an untrusted link: cfengine will not follow it with a destructive operation", path); continue; } /* if so, hide the difference by replacing with actual object */ if (stat(dirp->d_name, &lsb) == -1) { RecordFailure(ctx, pp, attr, "Recurse was working on '%s' when this failed. (stat: %s)", path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); continue; } } if ((attr->recursion.xdev) && (DeviceBoundary(&lsb, rootdevice))) { Log(LOG_LEVEL_VERBOSE, "Skipping '%s' on different device - use xdev option to change this. (stat: %s)", path, GetErrorStr()); continue; } if (S_ISDIR(lsb.st_mode)) { if (SkipDirLinks(ctx, path, dirp->d_name, attr->recursion)) { continue; } if ((attr->recursion.depth > 1) && (rlevel <= attr->recursion.depth)) { Log(LOG_LEVEL_VERBOSE, "Entering '%s', level %d", path, rlevel); goback = DepthSearch(ctx, path, &lsb, rlevel + 1, attr, pp, rootdevice, result); if (!PopDirState(ctx, pp, attr, goback, name, sb, attr->recursion, result)) { FatalError(ctx, "Not safe to continue"); } } } if (!attr->haveselect || SelectLeaf(ctx, path, &lsb, &(attr->select))) { if (attr->havechange) { if (!SeqBinaryLookup(db_file_set, dirp->d_name, StrCmpWrapper)) { // See comments in FileChangesCheckAndUpdateDirectory(), // regarding this function call. FileChangesLogNewFile(path, pp); } SeqAppend(selected_files, xstrdup(dirp->d_name)); } VerifyFileLeaf(ctx, path, &lsb, attr, pp, result); /* Renames are handled separately. */ if ((EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST_FULL) && !attr->haverename) { RecordFileEvaluatedInChroot(path); } if (ChrootChanges() && (*result == PROMISE_RESULT_CHANGE)) { RecordFileChangedInChroot(path); } } else { Log(LOG_LEVEL_DEBUG, "Skipping non-selected file '%s'", path); } } if (attr->havechange) { FileChangesCheckAndUpdateDirectory(ctx, attr, name, selected_files, db_file_set, attr->change.update, pp, result); } end: SeqDestroy(selected_files); SeqDestroy(db_file_set); DirClose(dirh); return retval; } static bool PushDirState(EvalContext *ctx, const Promise *pp, const Attributes *attr, char *name, const struct stat *sb, PromiseResult *result) { const char *changes_name = (ToChangesPath(name)); if (safe_chdir(changes_name) == -1) { RecordFailure(ctx, pp, attr, "Could not change to directory '%s' (mode '%04jo', chdir: %s)", name, (uintmax_t)(sb->st_mode & 07777), GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (!CheckLinkSecurity(sb, changes_name)) { FatalError(ctx, "Not safe to continue"); } return true; } /** * @return true if safe for agent to continue */ static bool PopDirState(EvalContext *ctx, const Promise *pp, const Attributes *attr, int goback, char *name, const struct stat *sb, DirectoryRecursion r, PromiseResult *result) { const char *changes_name = (ToChangesPath(name)); if (goback && (r.travlinks)) { if (safe_chdir(changes_name) == -1) { RecordFailure(ctx, pp, attr, "Error in backing out of recursive travlink descent securely to '%s'. (chdir: %s)", name, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (!CheckLinkSecurity(sb, changes_name)) { return false; } } else if (goback) { if (safe_chdir("..") == -1) { RecordFailure(ctx, pp, attr, "Error in backing out of recursive descent securely to '%s'. (chdir: %s)", name, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } } return true; } /** * @return true if it is safe for the agent to continue execution */ static bool CheckLinkSecurity(const struct stat *sb, const char *name) { struct stat security; Log(LOG_LEVEL_DEBUG, "Checking the inode and device to make sure we are where we think we are..."); if (stat(".", &security) == -1) { Log(LOG_LEVEL_ERR, "Could not stat directory '%s' after entering. (stat: %s)", name, GetErrorStr()); return true; // continue anyway } if ((sb->st_dev != security.st_dev) || (sb->st_ino != security.st_ino)) { Log(LOG_LEVEL_ERR, "SERIOUS SECURITY ALERT: path race exploited in recursion to/from '%s'. Not safe for agent to continue - aborting", name); return false; // too dangerous } return true; } static PromiseResult VerifyCopiedFileAttributes(EvalContext *ctx, const char *src, const char *dest, const struct stat *sstat, const struct stat *dstat, const Attributes *a, const Promise *pp) { assert(a != NULL); Attributes attr = *a; // TODO: try to remove this copy #ifndef __MINGW32__ mode_t newplus, newminus; uid_t save_uid; gid_t save_gid; // If we get here, there is both a src and dest file save_uid = (attr.perms.owners)->uid; save_gid = (attr.perms.groups)->gid; if (attr.copy.preserve) { Log(LOG_LEVEL_VERBOSE, "Attempting to preserve file permissions from the source: %04jo", (uintmax_t)(sstat->st_mode & 07777)); if ((attr.perms.owners)->uid == CF_SAME_OWNER) /* Preserve uid and gid */ { (attr.perms.owners)->uid = sstat->st_uid; } if ((attr.perms.groups)->gid == CF_SAME_GROUP) { (attr.perms.groups)->gid = sstat->st_gid; } // Will this preserve if no mode set? newplus = (sstat->st_mode & 07777); newminus = ~newplus & 07777; attr.perms.plus = newplus; attr.perms.minus = newminus; } else { if ((attr.perms.owners)->uid == CF_SAME_OWNER) /* Preserve uid and gid */ { (attr.perms.owners)->uid = dstat->st_uid; } if ((attr.perms.groups)->gid == CF_SAME_GROUP) { (attr.perms.groups)->gid = dstat->st_gid; } if (attr.haveperms) { newplus = (dstat->st_mode & 07777) | attr.perms.plus; newminus = ~(newplus & ~(attr.perms.minus)) & 07777; attr.perms.plus = newplus; attr.perms.minus = newminus; } } #endif PromiseResult result = VerifyFileAttributes(ctx, dest, dstat, &attr, pp); #ifndef __MINGW32__ (attr.perms.owners)->uid = save_uid; (attr.perms.groups)->gid = save_gid; #endif const char *changes_src = src; char *chrooted_src = NULL; if (ChrootChanges()) { /* Need to create a copy because the second call will override the * internal buffer used by ToChangesChroot(). */ chrooted_src = xstrdup(ToChangesChroot(src)); changes_src = chrooted_src; } const char *changes_dest = dest; if (ChrootChanges()) { changes_dest = ToChangesChroot(dest); } if (attr.copy.preserve && ( attr.copy.servers == NULL || strcmp(RlistScalarValue(attr.copy.servers), "localhost") == 0)) { bool change = false; if (!CopyFileExtendedAttributesDisk(changes_src, changes_dest, &change)) { RecordFailure(ctx, pp, &attr, "Could not preserve extended attributes" " (ACLs and security contexts) on file '%s'", dest); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else if (change) { RecordChange(ctx, pp, &attr, "Copied extended attributes from '%s' to '%s'", src, dest); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } free(chrooted_src); return result; } static PromiseResult CopyFileSources(EvalContext *ctx, char *destination, const Attributes *attr, const Promise *pp, AgentConnection *conn) { assert(attr != NULL); Buffer *source_buf = BufferNew(); // Expand this.promiser ExpandScalar(ctx, PromiseGetBundle(pp)->ns, PromiseGetBundle(pp)->name, attr->copy.source, source_buf); char vbuff[CF_BUFSIZE]; struct stat ssb, dsb; struct timespec start; const char *source = BufferData(source_buf); const char *changes_source = source; if (ChrootChanges()) { changes_source = ToChangesChroot(changes_source); } if (conn != NULL && (!conn->authenticated)) { RecordFailure(ctx, pp, attr, "Source '%s' not authenticated in copy_from for '%s'", source, destination); BufferDestroy(source_buf); return PROMISE_RESULT_FAIL; } if (cf_stat(changes_source, &ssb, &(attr->copy), conn) == -1) { if (attr->copy.missing_ok) { RecordNoChange(ctx, pp, attr, "Can't stat file '%s' on '%s' but promise is kept because of" " 'missing_ok' in files.copy_from promise", source, conn ? conn->remoteip : "localhost"); BufferDestroy(source_buf); return PROMISE_RESULT_NOOP; } else { RecordFailure(ctx, pp, attr, "Can't stat file '%s' on '%s' in files.copy_from promise", source, conn ? conn->remoteip : "localhost"); BufferDestroy(source_buf); return PROMISE_RESULT_FAIL; } } start = BeginMeasure(); strlcpy(vbuff, destination, CF_BUFSIZE - 3); if (S_ISDIR(ssb.st_mode)) /* could be depth_search */ { AddSlash(vbuff); strcat(vbuff, "."); } PromiseResult result = PROMISE_RESULT_NOOP; bool dir_created = false; if (!MakeParentDirectoryForPromise(ctx, pp, attr, &result, vbuff, attr->move_obstructions, &dir_created, DEFAULTMODE)) { BufferDestroy(source_buf); return result; } if (dir_created) { RecordChange(ctx, pp, attr, "Created parent directory for '%s'", destination); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } CompressedArray *inode_cache = NULL; if (S_ISDIR(ssb.st_mode)) /* could be depth_search */ { if (attr->copy.purge) { Log(LOG_LEVEL_VERBOSE, "Destination purging enabled"); } Log(LOG_LEVEL_VERBOSE, "Entering directory '%s'", source); result = PromiseResultUpdate( result, SourceSearchAndCopy(ctx, source, destination, attr->recursion.depth, attr, pp, ssb.st_dev, &inode_cache, conn)); if (stat(ToChangesPath(destination), &dsb) != -1) { if (attr->copy.check_root) { result = PromiseResultUpdate( result, VerifyCopiedFileAttributes(ctx, source, destination, &ssb, &dsb, attr, pp)); } } } else { result = PromiseResultUpdate( result, VerifyCopy(ctx, source, destination, attr, pp, &inode_cache, conn)); } DeleteCompressedArray(inode_cache); const char *mid = PromiseGetConstraintAsRval(pp, "measurement_class", RVAL_TYPE_SCALAR); if (mid) { char eventname[CF_BUFSIZE]; snprintf(eventname, CF_BUFSIZE - 1, "Copy(%s:%s > %s)", conn ? conn->this_server : "localhost", source, destination); EndMeasure(eventname, start); } else { EndMeasure(NULL, start); } BufferDestroy(source_buf); return result; } /* Decide the protocol version the agent will use to connect: If the user has * specified a copy_from attribute then follow that one, else use the body * common control setting. */ static ProtocolVersion DecideProtocol(const EvalContext *ctx, ProtocolVersion copyfrom_setting) { if (copyfrom_setting == CF_PROTOCOL_UNDEFINED) { /* TODO we would like to get the common control setting from * GenericAgentConfig. Given that we have only access to EvalContext here, * we get the raw string and reparse it every time. */ const char *s = EvalContextVariableControlCommonGet( ctx, COMMON_CONTROL_PROTOCOL_VERSION); ProtocolVersion common_setting = ProtocolVersionParse(s); return common_setting; } else { return copyfrom_setting; } } static AgentConnection *FileCopyConnectionOpen(const EvalContext *ctx, const char *servername, const FileCopy *fc, bool background) { ConnectionFlags flags = { .protocol_version = DecideProtocol(ctx, fc->protocol_version), .cache_connection = !background, .force_ipv4 = fc->force_ipv4, .trust_server = fc->trustkey, .off_the_record = false }; unsigned int conntimeout = fc->timeout; if (fc->timeout == CF_NOINT || fc->timeout < 0) { conntimeout = CONNTIMEOUT; } const char *port = (fc->port != NULL) ? fc->port : CFENGINE_PORT_STR; AgentConnection *conn = NULL; if (flags.cache_connection) { conn = ConnCache_FindIdleMarkBusy(servername, port, flags); if (conn != NULL) /* found idle connection in cache */ { return conn; } else /* not found, open and cache new connection */ { int err = 0; conn = ServerConnection(servername, port, EvalContextGetRestrictKeys(ctx), conntimeout, flags, &err); /* WARNING: if cache already has non-idle connections to that * host, here we add more so that we connect in parallel. */ if (conn == NULL) /* Couldn't connect */ { /* Allocate and add to the cache as failure. */ conn = NewAgentConn(servername, port, flags); conn->conn_info->status = CONNECTIONINFO_STATUS_NOT_ESTABLISHED; ConnCache_Add(conn, CONNCACHE_STATUS_OFFLINE); return NULL; } else { /* Success! Put it in the cache as busy. */ ConnCache_Add(conn, CONNCACHE_STATUS_BUSY); return conn; } } } else { int err = 0; conn = ServerConnection(servername, port, EvalContextGetRestrictKeys(ctx), conntimeout, flags, &err); return conn; } } void FileCopyConnectionClose(AgentConnection *conn) { if (conn->flags.cache_connection) { /* Mark the connection as available in the cache. */ ConnCache_MarkNotBusy(conn); } else { DisconnectServer(conn); } } PromiseResult ScheduleCopyOperation(EvalContext *ctx, char *destination, const Attributes *attr, const Promise *pp) { assert(attr != NULL); /* TODO currently parser allows body copy_from to have no source! See tests/acceptance/10_files/02_maintain/017.cf and https://cfengine.com/bugtracker/view.php?id=687 */ if (attr->copy.source == NULL) { RecordFailure(ctx, pp, attr, "Body copy_from for '%s' has no source", destination); return PROMISE_RESULT_FAIL; } Log(LOG_LEVEL_VERBOSE, "File '%s' copy_from '%s'", destination, attr->copy.source); /* Empty attr->copy.servers means copy from localhost. */ bool copyfrom_localhost = (attr->copy.servers == NULL); AgentConnection *conn = NULL; Rlist *rp = attr->copy.servers; /* Iterate over all copy_from servers until connection succeeds. */ while (rp != NULL && conn == NULL) { const char *servername = RlistScalarValue(rp); if (strcmp(servername, "localhost") == 0) { copyfrom_localhost = true; break; } conn = FileCopyConnectionOpen(ctx, servername, &(attr->copy), attr->transaction.background); if (conn == NULL) { Log(LOG_LEVEL_INFO, "Unable to establish connection to '%s'", servername); } rp = rp->next; } if (!copyfrom_localhost && conn == NULL) { RecordFailure(ctx, pp, attr, "No suitable server found for '%s'", destination); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } /* (conn == NULL) means local copy. */ PromiseResult result = CopyFileSources(ctx, destination, attr, pp, conn); if (conn != NULL) { FileCopyConnectionClose(conn); } return result; } PromiseResult ScheduleLinkOperation(EvalContext *ctx, char *destination, char *source, const Attributes *attr, const Promise *pp) { assert(attr != NULL); const char *lastnode; lastnode = ReadLastNode(destination); PromiseResult result = PROMISE_RESULT_NOOP; if (MatchRlistItem(ctx, attr->link.copy_patterns, lastnode)) { Log(LOG_LEVEL_VERBOSE, "Link '%s' matches copy_patterns", destination); CompressedArray *inode_cache = NULL; result = PromiseResultUpdate(result, VerifyCopy(ctx, attr->link.source, destination, attr, pp, &inode_cache, NULL)); DeleteCompressedArray(inode_cache); return result; } switch (attr->link.link_type) { case FILE_LINK_TYPE_SYMLINK: result = VerifyLink(ctx, destination, source, attr, pp); break; case FILE_LINK_TYPE_HARDLINK: result = VerifyHardLink(ctx, destination, source, attr, pp); break; case FILE_LINK_TYPE_RELATIVE: result = VerifyRelativeLink(ctx, destination, source, attr, pp); break; case FILE_LINK_TYPE_ABSOLUTE: result = VerifyAbsoluteLink(ctx, destination, source, attr, pp); break; default: assert(false); Log(LOG_LEVEL_ERR, "Unknown link type - should not happen."); break; } return result; } PromiseResult ScheduleLinkChildrenOperation(EvalContext *ctx, char *destination, char *source, int recurse, const Attributes *a, const Promise *pp) { assert(a != NULL); Attributes attr = *a; // TODO: Remove this copy Dir *dirh; const struct dirent *dirp; char promiserpath[CF_BUFSIZE], sourcepath[CF_BUFSIZE]; struct stat lsb; int ret; const char *changes_destination = destination; if (ChrootChanges()) { changes_destination = ToChangesChroot(destination); } PromiseResult result = PROMISE_RESULT_NOOP; if ((ret = lstat(changes_destination, &lsb)) != -1) { if (attr.move_obstructions && S_ISLNK(lsb.st_mode)) { if (unlink(changes_destination) == 0) { RecordChange(ctx, pp, a, "Removed obstructing link '%s'", destination); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, a, "Failed to remove obstructing link '%s'", destination); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } else if (!S_ISDIR(lsb.st_mode)) { RecordFailure(ctx, pp, a, "Cannot promise to link files to children of '%s' as it is not a directory", destination); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } } snprintf(promiserpath, sizeof(promiserpath), "%s/.", destination); if ((ret == -1) && !CfCreateFile(ctx, promiserpath, pp, &attr, &result)) { RecordFailure(ctx, pp, a, "Failed to create directory '%s' for linking files as its children", destination); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } if (ChrootChanges()) { /* If making changes in a chroot, we need to make sure 'source' is in * the chroot before we start. */ PrepareChangesChroot(source); } if ((dirh = DirOpen(ToChangesPath(source))) == NULL) { RecordFailure(ctx, pp, a, "Can't open source of children to link '%s'. (opendir: %s)", attr.link.source, GetErrorStr()); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); return result; } for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!ConsiderLocalFile(dirp->d_name, source)) { Log(LOG_LEVEL_VERBOSE, "Skipping '%s'", dirp->d_name); continue; } /* Assemble pathnames */ strlcpy(promiserpath, destination, sizeof(promiserpath)); if (JoinPaths(promiserpath, sizeof(promiserpath), dirp->d_name) == NULL) { RecordInterruption(ctx, pp, a, "Internal buffer limit while verifying child links," " promiser: '%s' + '%s'", promiserpath, dirp->d_name); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); DirClose(dirh); return result; } strlcpy(sourcepath, source, sizeof(sourcepath)); if (JoinPaths(sourcepath, sizeof(sourcepath), dirp->d_name) == NULL) { RecordInterruption(ctx, pp, a, "Internal buffer limit while verifying child links," " source filename: '%s' + '%s'", sourcepath, dirp->d_name); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); DirClose(dirh); return result; } if ((lstat(ToChangesPath(promiserpath), &lsb) != -1) && !S_ISLNK(lsb.st_mode) && !S_ISDIR(lsb.st_mode)) { if (attr.link.when_linking_children == cfa_override) { attr.move_obstructions = true; } else { Log(LOG_LEVEL_VERBOSE, "Have promised not to disturb existing content belonging to '%s'", promiserpath); continue; } } if ((attr.recursion.depth > recurse) && (lstat(ToChangesPath(sourcepath), &lsb) != -1) && S_ISDIR(lsb.st_mode)) { result = PromiseResultUpdate(result, ScheduleLinkChildrenOperation(ctx, promiserpath, sourcepath, recurse + 1, &attr, pp)); } else { result = PromiseResultUpdate(result, ScheduleLinkOperation(ctx, promiserpath, sourcepath, &attr, pp)); } if (ChrootChanges() && (result == PROMISE_RESULT_CHANGE)) { RecordFileChangedInChroot(promiserpath); } } DirClose(dirh); return result; } static PromiseResult VerifyFileIntegrity(EvalContext *ctx, const char *file, const Attributes *attr, const Promise *pp) { assert(attr != NULL); unsigned char digest1[EVP_MAX_MD_SIZE + 1]; unsigned char digest2[EVP_MAX_MD_SIZE + 1]; if ((attr->change.report_changes != FILE_CHANGE_REPORT_CONTENT_CHANGE) && (attr->change.report_changes != FILE_CHANGE_REPORT_ALL)) { return PROMISE_RESULT_NOOP; } memset(digest1, 0, EVP_MAX_MD_SIZE + 1); memset(digest2, 0, EVP_MAX_MD_SIZE + 1); PromiseResult result = PROMISE_RESULT_NOOP; bool changed = false; if (attr->change.hash == HASH_METHOD_BEST) { HashFile(file, digest1, HASH_METHOD_MD5, false); HashFile(file, digest2, HASH_METHOD_SHA1, false); changed = (changed || FileChangesCheckAndUpdateHash(ctx, file, digest1, HASH_METHOD_MD5, attr, pp, &result)); changed = (changed || FileChangesCheckAndUpdateHash(ctx, file, digest2, HASH_METHOD_SHA1, attr, pp, &result)); } else { HashFile(file, digest1, attr->change.hash, false); changed = (changed || FileChangesCheckAndUpdateHash(ctx, file, digest1, attr->change.hash, attr, pp, &result)); } if (changed && MakingInternalChanges(ctx, pp, attr, &result, "record integrity changes in '%s'", file)) { EvalContextHeapPersistentSave(ctx, "checksum_alerts", CF_PERSISTENCE, CONTEXT_STATE_POLICY_PRESERVE, ""); EvalContextClassPutSoft(ctx, "checksum_alerts", CONTEXT_SCOPE_NAMESPACE, ""); if (FileChangesLogChange(file, FILE_STATE_CONTENT_CHANGED, "Content changed", pp)) { RecordChange(ctx, pp, attr, "Recorded integrity changes in '%s'", file); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to record integrity changes in '%s'", file); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } if (attr->change.report_diffs && MakingInternalChanges(ctx, pp, attr, &result, "report diffs in '%s'", file)) { char destination[CF_BUFSIZE]; if (!GetRepositoryPath(file, attr, destination)) { destination[0] = '\0'; } LogFileChange(ctx, file, changed, attr, pp, &CopyRegularFile, destination, &DeleteCompressedArray); } return result; } static bool CompareForFileCopy(char *sourcefile, char *destfile, const struct stat *ssb, const struct stat *dsb, const FileCopy *fc, AgentConnection *conn) { bool ok_to_copy; /* (conn == NULL) means copy is from localhost. */ const char *changes_sourcefile = sourcefile; char *chrooted_sourcefile = NULL; if ((conn == NULL) && ChrootChanges()) { /* Need to create a copy because the later call to ToChangesChroot() * overwrites the internal buffer. */ chrooted_sourcefile = xstrdup(ToChangesChroot(sourcefile)); struct stat sb; if (lstat(changes_sourcefile, &sb) != -1) { changes_sourcefile = chrooted_sourcefile; } } const char *changes_destfile = destfile; if (ChrootChanges()) { changes_destfile = ToChangesChroot(destfile); } switch (fc->compare) { case FILE_COMPARATOR_CHECKSUM: case FILE_COMPARATOR_HASH: if (S_ISREG(dsb->st_mode) && S_ISREG(ssb->st_mode)) { ok_to_copy = CompareFileHashes(changes_sourcefile, changes_destfile, ssb, dsb, fc, conn); } else { Log(LOG_LEVEL_VERBOSE, "Checksum comparison replaced by ctime: files not regular"); ok_to_copy = (dsb->st_ctime < ssb->st_ctime) || (dsb->st_mtime < ssb->st_mtime); } if (ok_to_copy) { Log(LOG_LEVEL_VERBOSE, "Image file '%s' has a wrong digest/checksum, should be copy of '%s'", destfile, sourcefile); free(chrooted_sourcefile); return ok_to_copy; } break; case FILE_COMPARATOR_BINARY: if (S_ISREG(dsb->st_mode) && S_ISREG(ssb->st_mode)) { ok_to_copy = CompareBinaryFiles(changes_sourcefile, changes_destfile, ssb, dsb, fc, conn); } else { Log(LOG_LEVEL_VERBOSE, "Byte comparison replaced by ctime: files not regular"); ok_to_copy = (dsb->st_ctime < ssb->st_ctime) || (dsb->st_mtime < ssb->st_mtime); } if (ok_to_copy) { Log(LOG_LEVEL_VERBOSE, "Image file %s has a wrong binary checksum, should be copy of '%s'", destfile, sourcefile); free(chrooted_sourcefile); return ok_to_copy; } break; case FILE_COMPARATOR_MTIME: ok_to_copy = (dsb->st_mtime < ssb->st_mtime); if (ok_to_copy) { Log(LOG_LEVEL_VERBOSE, "Image file '%s' out of date, should be copy of '%s'", destfile, sourcefile); free(chrooted_sourcefile); return ok_to_copy; } break; case FILE_COMPARATOR_ATIME: ok_to_copy = (dsb->st_ctime < ssb->st_ctime) || (dsb->st_mtime < ssb->st_mtime) || (CompareBinaryFiles(changes_sourcefile, changes_destfile, ssb, dsb, fc, conn)); if (ok_to_copy) { Log(LOG_LEVEL_VERBOSE, "Image file '%s' seems out of date, should be copy of '%s'", destfile, sourcefile); free(chrooted_sourcefile); return ok_to_copy; } break; default: ok_to_copy = (dsb->st_ctime < ssb->st_ctime) || (dsb->st_mtime < ssb->st_mtime); if (ok_to_copy) { Log(LOG_LEVEL_VERBOSE, "Image file '%s' out of date, should be copy of '%s'", destfile, sourcefile); free(chrooted_sourcefile); return ok_to_copy; } break; } free(chrooted_sourcefile); return false; } static void FileAutoDefine(EvalContext *ctx, char *destfile) { char context[CF_MAXVARSIZE]; snprintf(context, CF_MAXVARSIZE, "auto_%s", CanonifyName(destfile)); EvalContextClassPutSoft(ctx, context, CONTEXT_SCOPE_NAMESPACE, "source=promise"); Log(LOG_LEVEL_INFO, "Auto defining class '%s'", context); } #ifndef __MINGW32__ static void LoadSetxid(void) { assert(!VSETXIDLIST); char filename[CF_BUFSIZE]; snprintf(filename, CF_BUFSIZE, "%s/cfagent.%s.log", GetLogDir(), VSYSNAME.nodename); ToLowerStrInplace(filename); MapName(filename); VSETXIDLIST = RawLoadItemList(filename); } static void SaveSetxid(bool modified) { if (!VSETXIDLIST) { return; } if (modified) { char filename[CF_BUFSIZE]; snprintf(filename, CF_BUFSIZE, "%s/cfagent.%s.log", GetLogDir(), VSYSNAME.nodename); ToLowerStrInplace(filename); MapName(filename); PurgeItemList(&VSETXIDLIST, "SETUID/SETGID"); Item *current = RawLoadItemList(filename); if (!ListsCompare(VSETXIDLIST, current)) { mode_t oldmode = umask(077); // This setxidlist file must only be accesible by root Log(LOG_LEVEL_DEBUG, "Updating setxidlist at '%s', umask was %o, will create setxidlist using umask 0077, file perms should be 0600.", filename, oldmode); RawSaveItemList(VSETXIDLIST, filename, NewLineMode_Unix); umask(oldmode); Log(LOG_LEVEL_DEBUG, "Restored umask to %o", oldmode); } DeleteItemList(current); } DeleteItemList(VSETXIDLIST); VSETXIDLIST = NULL; } static bool IsInSetxidList(const char *file) { if (!VSETXIDLIST) { LoadSetxid(); } return IsItemIn(VSETXIDLIST, file); } static PromiseResult VerifySetUidGid(EvalContext *ctx, const char *file, const struct stat *dstat, mode_t newperm, const Promise *pp, const Attributes *attr) { assert(attr != NULL); int amroot = true; PromiseResult result = PROMISE_RESULT_NOOP; bool setxid_modified = false; if (!IsPrivileged()) { amroot = false; } if ((dstat->st_uid == 0) && (dstat->st_mode & S_ISUID)) { if (newperm & S_ISUID) { if (!IsInSetxidList(file)) { if (amroot) { Log(LOG_LEVEL_NOTICE, "NEW SETUID root PROGRAM '%s' ", file); } PrependItem(&VSETXIDLIST, file, NULL); setxid_modified = true; } } else if (MakingChanges(ctx, pp, attr, &result, "remove setuid (root) flag from '%s'", file)) { RecordChange(ctx, pp, attr, "Removed setuid (root) flag from '%s'", file); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } if (dstat->st_uid == 0 && (dstat->st_mode & S_ISGID)) { if (newperm & S_ISGID) { if (S_ISDIR(dstat->st_mode)) { /* setgid directory */ } else if (!IsInSetxidList(file)) { if (amroot) { Log(LOG_LEVEL_NOTICE, "NEW SETGID root PROGRAM '%s' ", file); } PrependItem(&VSETXIDLIST, file, NULL); setxid_modified = true; } } else if (MakingChanges(ctx, pp, attr, &result, "remove setgid (root) flag from '%s'", file)) { RecordChange(ctx, pp, attr, "Removed setgid (root) flag from '%s'", file); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } } SaveSetxid(setxid_modified); return result; } #endif #ifdef __APPLE__ static int VerifyFinderType(EvalContext *ctx, const char *file, const Attributes *a, const Promise *pp, PromiseResult *result) { /* Code modeled after hfstar's extract.c */ assert(a != NULL); typedef struct { long fdType; long fdCreator; short fdFlags; short fdLocationV; short fdLocationH; short fdFldr; short fdIconID; short fdUnused[3]; char fdScript; char fdXFlags; short fdComment; long fdPutAway; } FInfo; struct attrlist attrs; struct { long ssize; struct timespec created; struct timespec modified; struct timespec changed; struct timespec backup; FInfo fi; } fndrInfo; int retval; const char *changes_file = file; if (ChrootChanges()) { changes_file = ToChangesChroot(file); } if (a->perms.findertype == NULL) { return 0; } Log(LOG_LEVEL_DEBUG, "VerifyFinderType of '%s' for '%s'", file, a->perms.findertype); if (strncmp(a->perms.findertype, "*", CF_BUFSIZE) == 0 || strncmp(a->perms.findertype, "", CF_BUFSIZE) == 0) { return 0; } attrs.bitmapcount = ATTR_BIT_MAP_COUNT; attrs.reserved = 0; attrs.commonattr = ATTR_CMN_CRTIME | ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME | ATTR_CMN_BKUPTIME | ATTR_CMN_FNDRINFO; attrs.volattr = 0; attrs.dirattr = 0; attrs.fileattr = 0; attrs.forkattr = 0; memset(&fndrInfo, 0, sizeof(fndrInfo)); getattrlist(changes_file, &attrs, &fndrInfo, sizeof(fndrInfo), 0); if (fndrInfo.fi.fdType != *(long *) a->perms.findertype) { fndrInfo.fi.fdType = *(long *) a->perms.findertype; if (MakingChanges(ctx, pp, a, result, "set Finder Type code of '%s' to '%s'", file, a->perms.findertype)) { /* setattrlist does not take back in the long ssize */ retval = setattrlist(changes_file, &attrs, &fndrInfo.created, 4 * sizeof(struct timespec) + sizeof(FInfo), 0); Log(LOG_LEVEL_DEBUG, "CheckFinderType setattrlist returned '%d'", retval); if (retval >= 0) { RecordChange(ctx, pp, a, "Set Finder Type code of '%s' to '%s'", file, a->perms.findertype); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, a, "Setting Finder Type code of '%s' to '%s' failed", file, a->perms.findertype); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } return retval; } else { return 0; } } else { RecordNoChange(ctx, pp, a, "Finder Type code of '%s' to '%s' is as promised", file, a->perms.findertype); *result = PromiseResultUpdate(*result, PROMISE_RESULT_NOOP); return 0; } } #endif static void TruncateFile(const char *name) { struct stat statbuf; int fd; if (stat(name, &statbuf) == -1) { Log(LOG_LEVEL_DEBUG, "Didn't find '%s' to truncate", name); } else { if ((fd = safe_creat(name, 000)) == -1) /* dummy mode ignored */ { Log(LOG_LEVEL_ERR, "Failed to create or truncate file '%s'. (create: %s)", name, GetErrorStr()); } else { close(fd); } } } static void RegisterAHardLink(int i, const char *value, EvalContext *ctx, const Promise *pp, const Attributes *attr, PromiseResult *result, CompressedArray **inode_cache) { if (!FixCompressedArrayValue(i, value, inode_cache)) { /* Not root hard link, remove to preserve consistency */ if (MakingChanges(ctx, pp, attr, result, "remove old hard link '%s' to preserve structure", value)) { RecordChange(ctx, pp, attr, "Removed old hard link '%s' to preserve structure", value); unlink(value); } } } static int cf_stat(const char *file, struct stat *buf, const FileCopy *fc, AgentConnection *conn) { if (!file) { return -1; } if (conn == NULL) { return stat(file, buf); } else { assert(fc->servers != NULL && strcmp(RlistScalarValue(fc->servers), "localhost") != 0); return cf_remote_stat(conn, fc->encrypt, file, buf, "file"); } } #ifndef __MINGW32__ static int cf_readlink(EvalContext *ctx, const char *sourcefile, char *linkbuf, size_t buffsize, const Attributes *attr, const Promise *pp, AgentConnection *conn, PromiseResult *result) /* wrapper for network access */ { assert(buffsize > 0); assert(attr != NULL); memset(linkbuf, 0, buffsize); if (conn == NULL) { return readlink(sourcefile, linkbuf, buffsize - 1); } assert(attr->copy.servers && strcmp(RlistScalarValue(attr->copy.servers), "localhost")); const Stat *sp = StatCacheLookup(conn, sourcefile, RlistScalarValue(attr->copy.servers)); if (sp) { if (sp->cf_readlink != NULL) { if (strlen(sp->cf_readlink) + 1 > buffsize) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, attr, "readlink value is too large in cfreadlink"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); Log(LOG_LEVEL_ERR, "Contained '%s'", sp->cf_readlink); return -1; } else { memset(linkbuf, 0, buffsize); strcpy(linkbuf, sp->cf_readlink); return 0; } } } return -1; } #endif /* !__MINGW32__ */ static bool SkipDirLinks(EvalContext *ctx, const char *path, const char *lastnode, DirectoryRecursion r) { if (r.exclude_dirs) { if ((MatchRlistItem(ctx, r.exclude_dirs, path)) || (MatchRlistItem(ctx, r.exclude_dirs, lastnode))) { Log(LOG_LEVEL_VERBOSE, "Skipping matched excluded directory '%s'", path); return true; } } if (r.include_dirs) { if (!((MatchRlistItem(ctx, r.include_dirs, path)) || (MatchRlistItem(ctx, r.include_dirs, lastnode)))) { Log(LOG_LEVEL_VERBOSE, "Skipping matched non-included directory '%s'", path); return true; } } return false; } #ifndef __MINGW32__ bool VerifyOwner(EvalContext *ctx, const char *file, const Promise *pp, const Attributes *attr, const struct stat *sb, PromiseResult *result) { assert(sb != NULL); UidList *ulp; GidList *glp; /* The groups to change ownership to, using lchown(uid,gid). */ uid_t uid = CF_UNKNOWN_OWNER; /* just init values */ gid_t gid = CF_UNKNOWN_GROUP; /* SKIP if file is already owned by anyone of the promised owners. */ for (ulp = attr->perms.owners; ulp != NULL; ulp = ulp->next) { if (ulp->uid == CF_SAME_OWNER) /* "same" matches anything */ { uid = CF_SAME_OWNER; break; } if (sb->st_uid == ulp->uid) { RecordNoChange(ctx, pp, attr, "Owner of '%s' as promised (%ju)", file, (uintmax_t) ulp->uid); uid = CF_SAME_OWNER; break; } } if (uid != CF_SAME_OWNER) { /* Change ownership to the first known user in the promised list. */ for (ulp = attr->perms.owners; ulp != NULL; ulp = ulp->next) { if (ulp->uid != CF_UNKNOWN_OWNER) { uid = ulp->uid; break; } } if (ulp == NULL) { RecordFailure(ctx, pp, attr, "None of the promised owners for '%s' exist -- see INFO logs for more", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); uid = CF_SAME_OWNER; /* chown(-1) doesn't change ownership */ } } assert(uid != CF_UNKNOWN_OWNER); /* SKIP if file is already group owned by anyone of the promised groups. */ for (glp = attr->perms.groups; glp != NULL; glp = glp->next) { if (glp->gid == CF_SAME_GROUP) { gid = CF_SAME_GROUP; break; } if (sb->st_gid == glp->gid) { RecordNoChange(ctx, pp, attr, "Group of '%s' as promised (%ju)", file, (uintmax_t) glp->gid); gid = CF_SAME_GROUP; break; } } /* Change group ownership to the first known group in the promised list. */ if (gid != CF_SAME_GROUP) { for (glp = attr->perms.groups; glp != NULL; glp = glp->next) { if (glp->gid != CF_UNKNOWN_GROUP) { gid = glp->gid; break; } } if (glp == NULL) { RecordFailure(ctx, pp, attr, "None of the promised groups for '%s' exist -- see INFO logs for more", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); gid = CF_SAME_GROUP; /* chown(-1) doesn't change ownership */ } } assert(gid != CF_UNKNOWN_GROUP); if ((uid == CF_SAME_OWNER) && (gid == CF_SAME_GROUP)) { /* Owner and group as promised or unspecified, nothing to do. */ return false; } /* else */ char name[CF_SMALLBUF]; if (!GetUserName(sb->st_uid, name, sizeof(name), LOG_LEVEL_VERBOSE)) { RecordWarning(ctx, pp, attr, "File '%s' is not owned by anybody in the passwd database (uid = %ju)", file, (uintmax_t)sb->st_uid); } if (!GetGroupName(sb->st_gid, name, sizeof(name), LOG_LEVEL_VERBOSE)) { RecordWarning(ctx, pp, attr, "File '%s' is not owned by any group in group database (gid = %ju)", file, (uintmax_t)sb->st_gid); } if (uid != CF_SAME_OWNER) { Log(LOG_LEVEL_DEBUG, "Change owner to uid '%ju' if possible", (uintmax_t) uid); } if (gid != CF_SAME_GROUP) { Log(LOG_LEVEL_DEBUG, "Change group to gid '%ju' if possible", (uintmax_t) gid); } if ((uid != CF_SAME_OWNER) && (gid != CF_SAME_GROUP) && !MakingChanges(ctx, pp, attr, result, "change owner and group of '%s' to '%ju:%ju'", file, (uintmax_t) uid, (uintmax_t) gid)) { return false; } else if ((uid != CF_SAME_OWNER) && !MakingChanges(ctx, pp, attr, result, "change owner of '%s' to '%ju'", file, (uintmax_t) uid)) { return false; } else if ((gid != CF_SAME_GROUP) && !MakingChanges(ctx, pp, attr, result, "change group of '%s' to '%ju'", file, (uintmax_t) gid)) { return false; } const char *changes_file = file; if (ChrootChanges()) { changes_file = ToChangesChroot(file); } if (S_ISLNK(sb->st_mode)) { # ifdef HAVE_LCHOWN Log(LOG_LEVEL_DEBUG, "Using lchown function"); if (safe_lchown(changes_file, uid, gid) == -1) { RecordFailure(ctx, pp, attr, "Cannot set ownership on link '%s'. (lchown: %s)", file, GetErrorStr()); } else { if (uid != CF_SAME_OWNER) { RecordChange(ctx, pp, attr, "Owner of link '%s' was %ju, set to %ju", file, (uintmax_t) sb->st_uid, (uintmax_t) uid); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } if (gid != CF_SAME_GROUP) { RecordChange(ctx, pp, attr, "Group of link '%s' was %ju, set to %ju", file, (uintmax_t)sb->st_gid, (uintmax_t)gid); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } # endif } else { if (safe_chown(changes_file, uid, gid) == -1) { RecordDenial(ctx, pp, attr, "Cannot set ownership on file '%s'. (chown: %s)", file, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_DENIED); } else { if (uid != CF_SAME_OWNER) { RecordChange(ctx, pp, attr, "Owner of '%s' was %ju, set to %ju", file, (uintmax_t) sb->st_uid, (uintmax_t) uid); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } if (gid != CF_SAME_GROUP) { RecordChange(ctx, pp, attr, "Group of '%s' was %ju, set to %ju", file, (uintmax_t)sb->st_gid, (uintmax_t)gid); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } } return false; } #endif /* !__MINGW32__ */ static void VerifyFileChanges(EvalContext *ctx, const char *file, const struct stat *sb, const Attributes *attr, const Promise *pp, PromiseResult *result) { if ((attr->change.report_changes != FILE_CHANGE_REPORT_STATS_CHANGE) && (attr->change.report_changes != FILE_CHANGE_REPORT_ALL)) { return; } FileChangesCheckAndUpdateStats(ctx, file, sb, attr->change.update, attr, pp, result); } bool CfCreateFile(EvalContext *ctx, char *file, const Promise *pp, const Attributes *attr, PromiseResult *result) { assert(attr != NULL); if (!IsAbsoluteFileName(file)) { RecordFailure(ctx, pp, attr, "Cannot create a relative filename '%s' - has no invariant meaning. (create: %s)", file, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } const char *changes_file = file; if (ChrootChanges()) { changes_file = ToChangesChroot(file); } /* If name ends in /., or depthsearch is set, then this is a directory */ bool is_dir = attr->havedepthsearch || (strcmp(".", ReadLastNode(file)) == 0); if (is_dir) { Log(LOG_LEVEL_DEBUG, "File object '%s' seems to be a directory", file); if (MakingChanges(ctx, pp, attr, result, "create directory '%s'", file)) { mode_t filemode = DEFAULTMODE; if (PromiseGetConstraintAsRval(pp, "mode", RVAL_TYPE_SCALAR) == NULL) { Log(LOG_LEVEL_VERBOSE, "No mode was set, choosing directory default %04jo", (uintmax_t) filemode); } else { filemode = attr->perms.plus & ~(attr->perms.minus); } bool dir_created = false; if (!MakeParentDirectoryForPromise(ctx, pp, attr, result, file, attr->move_obstructions, &dir_created, filemode)) { return false; } if (dir_created) { RecordChange(ctx, pp, attr, "Created directory '%s', mode %04jo", file, (uintmax_t) filemode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } else { return false; } } else if (attr->file_type && !strncmp(attr->file_type, "fifo", 5)) { #ifndef _WIN32 mode_t filemode = 0600; if (PromiseGetConstraintAsRval(pp, "mode", RVAL_TYPE_SCALAR) == NULL) { Log(LOG_LEVEL_VERBOSE, "No mode was set, choose plain file default %04jo", (uintmax_t)filemode); } else { filemode = attr->perms.plus & ~(attr->perms.minus); } bool dir_created = false; if (!MakeParentDirectoryForPromise(ctx, pp, attr, result, file, attr->move_obstructions, &dir_created, DEFAULTMODE)) { return false; } if (dir_created) { RecordChange(ctx, pp, attr, "Created directory for '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } if (MakingChanges(ctx, pp, attr, result, "create named pipe '%s', mode %04jo", file, (uintmax_t) filemode)) { mode_t saveumask = umask(0); char errormsg[CF_BUFSIZE]; if (mkfifo(changes_file, filemode) != 0) { snprintf(errormsg, sizeof(errormsg), "(mkfifo: %s)", GetErrorStr()); RecordFailure(ctx, pp, attr, "Error creating file '%s', mode '%04jo'. %s", file, (uintmax_t)filemode, errormsg); umask(saveumask); return false; } RecordChange(ctx, pp, attr, "Created named pipe '%s', mode %04jo", file, (uintmax_t) filemode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); umask(saveumask); return true; } else { return false; } #else RecordWarning(ctx, pp, attr, "Named pipe creation not supported on Windows"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); return false; #endif } else { mode_t filemode = 0600; /* Decide the mode for filecreation */ if (PromiseGetConstraintAsRval(pp, "mode", RVAL_TYPE_SCALAR) == NULL) { Log(LOG_LEVEL_VERBOSE, "No mode was set, choose plain file default %04jo", (uintmax_t)filemode); } else { filemode = attr->perms.plus & ~(attr->perms.minus); } bool dir_created = false; if (!MakeParentDirectoryForPromise(ctx, pp, attr, result, file, attr->move_obstructions, &dir_created, DEFAULTMODE)) { return false; } if (dir_created) { RecordChange(ctx, pp, attr, "Created directory for '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } if (MakingChanges(ctx, pp, attr, result, "create file '%s', mode '%04jo'", file, (uintmax_t)filemode)) { mode_t saveumask = umask(0); int fd = safe_open_create_perms(changes_file, O_WRONLY | O_CREAT | O_EXCL, filemode); if (fd == -1) { char errormsg[CF_BUFSIZE]; if (errno == EEXIST) { snprintf(errormsg, sizeof(errormsg), "(open: '%s'). " "Most likely a dangling symlink is in the way. " "Refusing to create the target file of dangling symlink (security risk).", GetErrorStr()); } else { snprintf(errormsg, sizeof(errormsg), "(open: %s)", GetErrorStr()); } RecordFailure(ctx, pp, attr, "Error creating file '%s', mode '%04jo'. %s", file, (uintmax_t)filemode, errormsg); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); umask(saveumask); return false; } else { RecordChange(ctx, pp, attr, "Created file '%s', mode %04jo", file, (uintmax_t)filemode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); close(fd); umask(saveumask); return true; } } else { return false; } } return true; } static bool DeviceBoundary(const struct stat *sb, dev_t rootdevice) { if (sb->st_dev == rootdevice) { return false; } else { Log(LOG_LEVEL_VERBOSE, "Device change from %jd to %jd", (intmax_t) rootdevice, (intmax_t) sb->st_dev); return true; } } cfengine-3.24.2/cf-agent/verify_files_utils.h0000644000000000000000000000513315010704253021120 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_FILES_UTILS_H #define CFENGINE_VERIFY_FILES_UTILS_H #include #include /* AgentConnection */ #include extern const Rlist *SINGLE_COPY_LIST; extern StringSet *SINGLE_COPY_CACHE; void SetFileAutoDefineList(const Rlist *auto_define_list); void VerifyFileLeaf(EvalContext *ctx, char *path, const struct stat *sb, const Attributes *attr, const Promise *pp, PromiseResult *result); bool DepthSearch(EvalContext *ctx, char *name, const struct stat *sb, int rlevel, const Attributes *attr, const Promise *pp, dev_t rootdevice, PromiseResult *result); bool CfCreateFile(EvalContext *ctx, char *file, const Promise *pp, const Attributes *attr, PromiseResult *result_out); void SetSearchDevice(struct stat *sb, const Promise *pp); PromiseResult ScheduleCopyOperation(EvalContext *ctx, char *destination, const Attributes *attr, const Promise *pp); PromiseResult ScheduleLinkChildrenOperation(EvalContext *ctx, char *destination, char *source, int rec, const Attributes *attr, const Promise *pp); PromiseResult ScheduleLinkOperation(EvalContext *ctx, char *destination, char *source, const Attributes *attr, const Promise *pp); bool CopyRegularFile(EvalContext *ctx, const char *source, const char *dest, const struct stat *sstat, const Attributes *attr, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn, PromiseResult *result); /* To be implemented in Nova for Win32 */ bool VerifyOwner(EvalContext *ctx, const char *file, const Promise *pp, const Attributes *attr, const struct stat *sb, PromiseResult *result); #endif cfengine-3.24.2/cf-agent/verify_storage.h0000644000000000000000000000251115010704253020237 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_STORAGE_H #define CFENGINE_VERIFY_STORAGE_H #include extern bool CF_MOUNTALL; PromiseResult FindAndVerifyStoragePromises(EvalContext *ctx, const Promise *pp); PromiseResult VerifyStoragePromise(EvalContext *ctx, char *path, const Promise *pp); Seq *GetGlobalMountedFSList(void); void DeleteStorageContext(void); #endif cfengine-3.24.2/cf-agent/comparray.h0000644000000000000000000000266715010704253017220 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_COMPARRAY_H #define CFENGINE_COMPARRAY_H #include typedef struct CompressedArray_ { int key; char *value; struct CompressedArray_ *next; } CompressedArray; bool FixCompressedArrayValue(int i, const char *value, CompressedArray **start); void DeleteCompressedArray(CompressedArray *start); bool CompressedArrayElementExists(CompressedArray *start, int key); char *CompressedArrayValue(CompressedArray *start, int key); #endif cfengine-3.24.2/cf-agent/verify_databases.c0000644000000000000000000010206515010704253020522 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int CheckDatabaseSanity(const Attributes *a, const Promise *pp); static PromiseResult VerifySQLPromise(EvalContext *ctx, const Attributes *a, const Promise *pp); static bool VerifyDatabasePromise(CfdbConn *cfdb, char *database, const Attributes *a); static bool ValidateSQLTableName(const char *path, char *db, size_t db_size, char *table, size_t table_size); static bool VerifyTablePromise(EvalContext *ctx, CfdbConn *cfdb, char *table_path, Rlist *columns, const Attributes *a, const Promise *pp, PromiseResult *result); static void QueryTableColumns(char *s, char *db, char *table); static bool NewSQLColumns(char *table, Rlist *columns, char ***name_table, char ***type_table, int **size_table, int **done); static void DeleteSQLColumns(char **name_table, char **type_table, int *size_table, int *done, int len); static void CreateDBQuery(DatabaseType type, char *query); static bool CreateTableColumns(CfdbConn *cfdb, char *table, Rlist *columns); static bool CheckSQLDataType(char *type, char *ref_type, const Promise *pp); static int TableExists(CfdbConn *cfdb, char *name); static Rlist *GetSQLTables(CfdbConn *cfdb); static void ListTables(int type, char *query); static bool ValidateRegistryPromiser(char *s, const Promise *pp); static bool CheckRegistrySanity(const Attributes *a, const Promise *pp); /*****************************************************************************/ PromiseResult VerifyDatabasePromises(EvalContext *ctx, const Promise *pp) { PromiseBanner(ctx, pp); Attributes a = GetDatabaseAttributes(ctx, pp); if (!CheckDatabaseSanity(&a, pp)) { return PROMISE_RESULT_FAIL; } if (strcmp(a.database.type, "sql") == 0) { return VerifySQLPromise(ctx, &a, pp); } else if (strcmp(a.database.type, "ms_registry") == 0) { #if defined(__MINGW32__) return VerifyRegistryPromise(ctx, &a, pp); #endif return PROMISE_RESULT_NOOP; } else { ProgrammingError("Unknown database type '%s'", a.database.type); } } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static PromiseResult VerifySQLPromise(EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(a != NULL); char database[CF_MAXDBNAMESIZE]; char table[CF_MAXTABLENAMESIZE]; char db_path[CF_MAXVARSIZE]; // Should have room for both buffers + 1 dot minus 1 NUL byte: nt_static_assert(sizeof(db_path) >= (sizeof(database) + sizeof(table))); char *sp; int count = 0; CfdbConn cfdb; CfLock thislock; char lockname[CF_BUFSIZE]; snprintf(lockname, CF_BUFSIZE - 1, "db-%s", pp->promiser); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a->transaction.ifelapsed, a->transaction.expireafter, pp, false); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } database[0] = '\0'; table[0] = '\0'; for (sp = pp->promiser; *sp != '\0'; sp++) { if (strchr("./\\", *sp)) { count++; strlcpy(table, sp + 1, sizeof(table)); sscanf(pp->promiser, "%[^.\\/]", database); if (strlen(database) == 0) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "SQL database promiser syntax should be of the form \"database.table\""); PromiseRef(LOG_LEVEL_ERR, pp); YieldCurrentLock(thislock); return PROMISE_RESULT_FAIL; } } } PromiseResult result = PROMISE_RESULT_NOOP; if (count > 1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "SQL database promiser syntax should be of the form \"database.table\""); PromiseRef(LOG_LEVEL_ERR, pp); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } if (strlen(database) == 0) { strlcpy(database, pp->promiser, sizeof(database)); } if (a->database.operation == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Missing database_operation in database promise"); PromiseRef(LOG_LEVEL_ERR, pp); YieldCurrentLock(thislock); return PROMISE_RESULT_FAIL; } if (strcmp(a->database.operation, "delete") == 0) { /* Just deal with one */ strcpy(a->database.operation, "drop"); } /* Connect to the server */ CfConnectDB(&cfdb, a->database.db_server_type, a->database.db_server_host, a->database.db_server_owner, a->database.db_server_password, database); if (!cfdb.connected) { /* If we haven't said create then db should already exist */ if ((a->database.operation) && (strcmp(a->database.operation, "create") != 0)) { Log(LOG_LEVEL_ERR, "Could not connect an existing database '%s' - check server configuration?", database); PromiseRef(LOG_LEVEL_ERR, pp); CfCloseDB(&cfdb); YieldCurrentLock(thislock); return PROMISE_RESULT_FAIL; } } /* Check change of existential constraints */ if ((a->database.operation) && (strcmp(a->database.operation, "create") == 0)) { CfConnectDB(&cfdb, a->database.db_server_type, a->database.db_server_host, a->database.db_server_owner, a->database.db_server_password, a->database.db_connect_db); if (!cfdb.connected) { Log(LOG_LEVEL_ERR, "Could not connect to the sql_db server for '%s'", database); YieldCurrentLock(thislock); return PROMISE_RESULT_FAIL; } /* Don't drop the db if we really want to drop a table */ if ((strlen(table) == 0) || ((strlen(table) > 0) && (strcmp(a->database.operation, "drop") != 0))) { VerifyDatabasePromise(&cfdb, database, a); } /* Close the database here to commit the change - might have to reopen */ CfCloseDB(&cfdb); } /* Now check the structure of the named table, if any */ if (strlen(table) == 0) { YieldCurrentLock(thislock); return result; } CfConnectDB(&cfdb, a->database.db_server_type, a->database.db_server_host, a->database.db_server_owner, a->database.db_server_password, database); if (!cfdb.connected) { Log(LOG_LEVEL_INFO, "Database '%s' is not connected", database); } else { snprintf(db_path, sizeof(db_path), "%s.%s", database, table); if (VerifyTablePromise(ctx, &cfdb, db_path, a->database.columns, a, pp, &result)) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_NOOP, pp, a, "Table '%s' is as promised", db_path); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Table '%s' is not as promised", db_path); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } /* Finally check any row constraints on this table */ if (a->database.rows) { Log(LOG_LEVEL_INFO, "Database row operations are not currently supported. Please contact cfengine with suggestions."); } CfCloseDB(&cfdb); } YieldCurrentLock(thislock); return result; } static bool VerifyDatabasePromise(CfdbConn *cfdb, char *database, const Attributes *a) { assert(a != NULL); char query[CF_BUFSIZE], name[CF_MAXVARSIZE]; int found = false; Log(LOG_LEVEL_VERBOSE, "Verifying promised database"); if (!cfdb->connected) { Log(LOG_LEVEL_INFO, "Database '%s' is not connected", database); return false; } CreateDBQuery(cfdb->type, query); CfNewQueryDB(cfdb, query); if (cfdb->maxcolumns < 1) { Log(LOG_LEVEL_ERR, "The schema did not promise the expected number of fields - got %d expected >= %d", cfdb->maxcolumns, 1); return false; } while (CfFetchRow(cfdb)) { strlcpy(name, CfFetchColumn(cfdb, 0), CF_MAXVARSIZE); Log(LOG_LEVEL_VERBOSE, "Discovered a database called '%s'", name); if (strcmp(name, database) == 0) { found = true; } } if (found) { Log(LOG_LEVEL_VERBOSE, "Database '%s' exists on this connection", database); return true; } else { Log(LOG_LEVEL_VERBOSE, "Database '%s' does not seem to exist on this connection", database); } if ((a->database.operation) && (strcmp(a->database.operation, "drop") == 0)) { if (((a->transaction.action) != cfa_warn) && (!DONTDO)) { Log(LOG_LEVEL_VERBOSE, "Attempting to delete the database '%s'", database); snprintf(query, CF_MAXVARSIZE - 1, "drop database %s", database); CfVoidQueryDB(cfdb, query); return cfdb->result; } else { Log(LOG_LEVEL_WARNING, "Need to delete the database '%s' but only a warning was promised", database); return false; } } if ((a->database.operation) && (strcmp(a->database.operation, "create") == 0)) { if (((a->transaction.action) != cfa_warn) && (!DONTDO)) { Log(LOG_LEVEL_VERBOSE, "Attempting to create the database '%s'", database); snprintf(query, CF_MAXVARSIZE - 1, "create database %s", database); CfVoidQueryDB(cfdb, query); return cfdb->result; } else { Log(LOG_LEVEL_WARNING, "Need to create the database '%s' but only a warning was promised", database); return false; } } return false; } /*****************************************************************************/ static int CheckDatabaseSanity(const Attributes *a, const Promise *pp) { assert(a != NULL); Rlist *rp; int retval = true, commas = 0; if ((a->database.type) && (strcmp(a->database.type, "ms_registry") == 0)) { retval = CheckRegistrySanity(a, pp); } else if ((a->database.type) && (strcmp(a->database.type, "sql") == 0)) { if ((strchr(pp->promiser, '.') == NULL) && (strchr(pp->promiser, '/') == NULL) && (strchr(pp->promiser, '\\') == NULL)) { if (a->database.columns) { Log(LOG_LEVEL_ERR, "Row values promised for an SQL table, but only the root database was promised"); retval = false; } if (a->database.rows) { Log(LOG_LEVEL_ERR, "Columns promised for an SQL table, but only the root database was promised"); retval = false; } } if (a->database.db_server_host == NULL) { Log(LOG_LEVEL_ERR, "No server host is promised for connecting to the SQL server"); retval = false; } if (a->database.db_server_owner == NULL) { Log(LOG_LEVEL_ERR, "No database login user is promised for connecting to the SQL server"); retval = false; } if (a->database.db_server_password == NULL) { Log(LOG_LEVEL_ERR, "No database authentication password is promised for connecting to the SQL server"); retval = false; } for (rp = a->database.columns; rp != NULL; rp = rp->next) { commas = CountChar(RlistScalarValue(rp), ','); if ((commas > 2) || (commas < 1)) { Log(LOG_LEVEL_ERR, "SQL Column format should be NAME,TYPE[,SIZE]"); retval = false; } } } if ((a->database.operation) && ((strcmp(a->database.operation, "delete") == 0) || (strcmp(a->database.operation, "drop") == 0))) { if (pp->comment == NULL) { Log(LOG_LEVEL_ERR, "When specifying a delete/drop from an SQL database you must add a comment. Take a backup of the database before making this change. This is a highly destructive operation."); retval = false; } } return retval; } static bool CheckRegistrySanity(const Attributes *a, const Promise *pp) { assert(a != NULL); bool retval = true; ValidateRegistryPromiser(pp->promiser, pp); if ((a->database.operation) && (strcmp(a->database.operation, "create") == 0)) { if (a->database.rows == NULL) { Log(LOG_LEVEL_INFO, "No row values promised for the MS registry database"); } if (a->database.columns != NULL) { Log(LOG_LEVEL_ERR, "Columns are only used to delete promised values for the MS registry database"); retval = false; } } if ((a->database.operation) && ((strcmp(a->database.operation, "delete") == 0) || (strcmp(a->database.operation, "drop") == 0))) { if (a->database.columns == NULL) { Log(LOG_LEVEL_INFO, "No columns were promised deleted in the MS registry database"); } if (a->database.rows != NULL) { Log(LOG_LEVEL_ERR, "Rows cannot be deleted in the MS registry database, only entire columns"); retval = false; } } for (Rlist *rp = a->database.rows; rp != NULL; rp = rp->next) { if (CountChar(RlistScalarValue(rp), ',') != 2) { Log(LOG_LEVEL_ERR, "Registry row format should be NAME,REG_SZ,VALUE, not '%s'", RlistScalarValue(rp)); retval = false; } } for (Rlist *rp = a->database.columns; rp != NULL; rp = rp->next) { if (CountChar(RlistScalarValue(rp), ',') > 0) { Log(LOG_LEVEL_ERR, "MS registry column format should be NAME only in deletion"); retval = false; } } return retval; } static bool ValidateRegistryPromiser(char *key, const Promise *pp) { static char *const valid[] = { "HKEY_CLASSES_ROOT", "HKEY_CURRENT_CONFIG", "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE", "HKEY_USERS", NULL }; char root_key[CF_MAXVARSIZE]; char *sp; int i; /* First remove the root key */ strlcpy(root_key, key, CF_MAXVARSIZE ); sp = strchr(root_key, '\\'); if (sp == NULL) { Log(LOG_LEVEL_ERR, "Cannot locate '\\' in '%s'", root_key); Log(LOG_LEVEL_ERR, "Failed validating registry promiser"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } *sp = '\0'; for (i = 0; valid[i] != NULL; i++) { if (strcmp(root_key, valid[i]) == 0) { return true; } } Log(LOG_LEVEL_ERR, "Non-editable registry prefix '%s'", root_key); PromiseRef(LOG_LEVEL_ERR, pp); return false; } /*****************************************************************************/ /* Linker troubles require this code to be here in the main body */ /*****************************************************************************/ static bool VerifyTablePromise(EvalContext *ctx, CfdbConn *cfdb, char *table_path, Rlist *columns, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); char name[CF_MAXVARSIZE], type[CF_MAXVARSIZE], query[CF_MAXVARSIZE]; char db[CF_MAXDBNAMESIZE]; char table[CF_MAXTABLENAMESIZE]; int i, count, size, no_of_cols, *size_table, *done, identified; bool retval = true; char **name_table, **type_table; Log(LOG_LEVEL_VERBOSE, "Verifying promised table structure for '%s'", table_path); if (!ValidateSQLTableName(table_path, db, sizeof(db), table, sizeof(table))) { Log(LOG_LEVEL_ERR, "The structure of the promiser did not match that for an SQL table, i.e. 'database.table'"); return false; } else { Log(LOG_LEVEL_VERBOSE, "Assuming database '%s' with table '%s'", db, table); } /* Verify the existence of the tables within the database */ if (!TableExists(cfdb, table)) { Log(LOG_LEVEL_ERR, "The database did not contain the promised table '%s'", table_path); if ((a->database.operation) && (strcmp(a->database.operation, "create") == 0)) { if ((!DONTDO) && ((a->transaction.action) != cfa_warn)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, a, "Database.table '%s' doesn't seem to exist, creating", table_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return CreateTableColumns(cfdb, table, columns); } else { Log(LOG_LEVEL_WARNING, "Database.table '%s' doesn't seem to exist, but only a warning was promised", table_path); } } return false; } /* Get a list of the columns in the table */ QueryTableColumns(query, db, table); CfNewQueryDB(cfdb, query); if (cfdb->maxcolumns != 3) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not make sense of the columns"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); CfDeleteQuery(cfdb); return false; } /* Assume that the Rlist has been validated and consists of a,b,c */ count = 0; no_of_cols = RlistLen(columns); if (!NewSQLColumns(table, columns, &name_table, &type_table, &size_table, &done)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not make sense of the columns"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } /* Obtain columns from the named table - if any */ while (CfFetchRow(cfdb)) { char *sizestr; name[0] = '\0'; type[0] = '\0'; size = CF_NOINT; strlcpy(name, CfFetchColumn(cfdb, 0), CF_MAXVARSIZE); strlcpy(type, CfFetchColumn(cfdb, 1), CF_MAXVARSIZE); ToLowerStrInplace(type); sizestr = CfFetchColumn(cfdb, 2); if (sizestr) { size = IntFromString(sizestr); } Log(LOG_LEVEL_VERBOSE, "Discovered database column (%s,%s,%d)", name, type, size); if (sizestr && (size == CF_NOINT)) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Integer size of SQL datatype could not be determined or was not specified - invalid promise."); DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols); CfDeleteQuery(cfdb); return false; } identified = false; for (i = 0; i < no_of_cols; i++) { if (done[i]) { continue; } if (strcmp(name, name_table[i]) == 0) { CheckSQLDataType(type, type_table[i], pp); if (size != size_table[i]) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Promised column '%s' in database.table '%s' has a non-matching array size (%d != %d)", name, table_path, size, size_table[i]); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { Log(LOG_LEVEL_VERBOSE, "Promised column '%s' in database.table '%s' is as promised", name, table_path); } count++; done[i] = true; identified = true; break; } } if (!identified) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Column '%s' found in database.table '%s' is not part of its promise.", name, table_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); if ((a->database.operation) && (strcmp(a->database.operation, "drop") == 0)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "CFEngine will not promise to repair this, as the operation is potentially too destructive."); // Future allow deletion? *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } retval = false; } } CfDeleteQuery(cfdb); /* Now look for deviations - only if we have promised to create missing */ if ((a->database.operation) && (strcmp(a->database.operation, "drop") == 0)) { return retval; } if (count != no_of_cols) { for (i = 0; i < no_of_cols; i++) { if (!done[i]) { Log(LOG_LEVEL_ERR, "Promised column '%s' missing from database table '%s'", name_table[i], pp->promiser); if ((!DONTDO) && ((a->transaction.action) != cfa_warn)) { if (size_table[i] > 0) { snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s(%d)", table, name_table[i], type_table[i], size_table[i]); } else { snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s", table, name_table[i], type_table[i]); } CfVoidQueryDB(cfdb, query); cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, a, "Adding promised column '%s' to database table '%s'", name_table[i], table); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; } else { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Promised column '%s' missing from database table '%s' but only a warning was promised", name_table[i], table); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); retval = false; } } } } DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols); return retval; } /*****************************************************************************/ static int TableExists(CfdbConn *cfdb, char *name) { Rlist *rp, *list = NULL; int match = false; list = GetSQLTables(cfdb); for (rp = list; rp != NULL; rp = rp->next) { if (strcmp(name, RlistScalarValue(rp)) == 0) { match = true; } } RlistDestroy(list); return match; } /*****************************************************************************/ static bool CreateTableColumns(CfdbConn *cfdb, char *table, Rlist *columns) { char entry[CF_MAXVARSIZE], query[CF_BUFSIZE]; int i, *size_table, *done; char **name_table, **type_table; int no_of_cols = RlistLen(columns); Log(LOG_LEVEL_ERR, "Trying to create table '%s'", table); if (!NewSQLColumns(table, columns, &name_table, &type_table, &size_table, &done)) { return false; } if (no_of_cols > 0) { snprintf(query, CF_BUFSIZE - 1, "create table %s(", table); for (i = 0; i < no_of_cols; i++) { Log(LOG_LEVEL_VERBOSE, "Forming column template %s %s %d", name_table[i], type_table[i], size_table[i]);; if (size_table[i] > 0) { snprintf(entry, CF_MAXVARSIZE - 1, "%s %s(%d)", name_table[i], type_table[i], size_table[i]); } else { snprintf(entry, CF_MAXVARSIZE - 1, "%s %s", name_table[i], type_table[i]); } strcat(query, entry); if (i < no_of_cols - 1) { strcat(query, ","); } } strcat(query, ")"); } CfVoidQueryDB(cfdb, query); DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols); return true; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static Rlist *GetSQLTables(CfdbConn *cfdb) { Rlist *list = NULL; char query[CF_MAXVARSIZE]; ListTables(cfdb->type, query); CfNewQueryDB(cfdb, query); if (cfdb->maxcolumns != 1) { Log(LOG_LEVEL_ERR, "Could not make sense of the columns"); CfDeleteQuery(cfdb); return NULL; } while (CfFetchRow(cfdb)) { RlistPrepend(&list, CfFetchColumn(cfdb, 0), RVAL_TYPE_SCALAR); } CfDeleteQuery(cfdb); return list; } /*****************************************************************************/ static void CreateDBQuery(DatabaseType type, char *query) { switch (type) { case DATABASE_TYPE_MYSQL: snprintf(query, CF_MAXVARSIZE - 1, "show databases"); break; case DATABASE_TYPE_POSTGRES: /* This gibberish is the simplest thing I can find in postgres */ snprintf(query, CF_MAXVARSIZE - 1, "SELECT pg_database.datname FROM pg_database"); break; default: snprintf(query, CF_MAXVARSIZE, "NULL QUERY"); break; } } /*****************************************************************************/ static bool ValidateSQLTableName( const char *const path, char *const db, const size_t db_size, char *const table, const size_t table_size) { assert(path != NULL); assert(db != NULL); assert(table != NULL); // path is db + table, for example: cfsettings.table const char *separator = strchr(path, '.'); if (separator == NULL) { Log(LOG_LEVEL_ERR, "No separator found in database path '%s'", path); return false; } // Backwards compatibility with bugs - this would cause false before: if ((strchr(path, '/') != NULL) || (strchr(path, '\\') != NULL)) { Log(LOG_LEVEL_ERR, "Unexpected slash in database path '%s'", path); return false; } assert(separator >= path); const size_t db_length = separator - path; if (db_length >= db_size) { Log(LOG_LEVEL_ERR, "Database name too long (%zu bytes) in '%s'", db_length, path); return false; } const char *table_start = separator + 1; const size_t table_length = strlen(table_start); if (table_length >= table_size) { Log(LOG_LEVEL_ERR, "Database table name too long (%zu bytes) in '%s'", table_length, path); return false; } memcpy(db, path, db_length); memcpy(table, table_start, table_length); db[db_length] = table[table_length] = '\0'; assert(strlen(db) < db_size); assert(strlen(table) < table_size); assert(strlen(db) == db_length); assert(strlen(path) == (strlen(db) + 1 + strlen(table))); return true; } /*****************************************************************************/ static void QueryTableColumns(char *s, char *db, char *table) { snprintf(s, CF_MAXVARSIZE - 1, "SELECT column_name,data_type,character_maximum_length FROM information_schema->columns WHERE table_name ='%s' AND table_schema = '%s'", table, db); } /*****************************************************************************/ static bool NewSQLColumns(char *table, Rlist *columns, char ***name_table, char ***type_table, int **size_table, int **done) { int i, no_of_cols = RlistLen(columns); Rlist *cols, *rp; *name_table = (char **) xmalloc(sizeof(char *) * (no_of_cols + 1)); *type_table = (char **) xmalloc(sizeof(char *) * (no_of_cols + 1)); *size_table = (int *) xmalloc(sizeof(int) * (no_of_cols + 1)); *done = (int *) xmalloc(sizeof(int) * (no_of_cols + 1)); for (i = 0, rp = columns; rp != NULL; rp = rp->next, i++) { (*done)[i] = 0; cols = RlistFromSplitString(RlistScalarValue(rp), ','); if (!cols) { Log(LOG_LEVEL_ERR, "No columns promised for table '%s' - makes no sense", table); return false; } if (cols->val.item == NULL) { Log(LOG_LEVEL_ERR, "Malformed column promise for table '%s' - found not even a name", table); free(*name_table); free(*type_table); free(*size_table); free(*done); return false; } (*name_table)[i] = xstrdup(RlistScalarValue(cols)); if (cols->next == NULL) { Log(LOG_LEVEL_ERR, "Malformed column '%s' promised for table '%s' - missing a type", (*name_table)[i], table); free(*name_table); free(*type_table); free(*size_table); free(*done); return false; } (*type_table)[i] = xstrdup(RlistScalarValue(cols->next)); if (cols->next->next == NULL) { (*size_table)[i] = 0; } else { if (cols->next->next->val.item) { (*size_table)[i] = IntFromString(RlistScalarValue(cols->next->next)); } else { (*size_table)[i] = 0; } } RlistDestroy(cols); } return true; } /*****************************************************************************/ static void DeleteSQLColumns(char **name_table, char **type_table, int *size_table, int *done, int len) { int i; if ((name_table == NULL) || (type_table == NULL) || (size_table == NULL)) { return; } for (i = 0; i < len; i++) { if (name_table[i] != NULL) { free(name_table[i]); } if (type_table[i] != NULL) { free(type_table[i]); } } free(name_table); free(type_table); free(size_table); free(done); } /*****************************************************************************/ static bool CheckSQLDataType(char *type, char *ref_type, const Promise *pp) { static char *const aliases[3][2] = { {"varchar", "character@varying"}, {"varchar", "character varying"}, {NULL, NULL} }; int i; bool ret = true; for (i = 0; aliases[i][0] != NULL; i++) { if ((strcmp(ref_type, aliases[i][0]) == 0) || (strcmp(ref_type, aliases[i][1]) == 0) || (strcmp(type, aliases[i][0]) == 0) || (strcmp(type, aliases[i][1]) == 0)) { if ((strcmp(type, ref_type) != 0) && (strcmp(aliases[i][0], ref_type) != 0)) { Log(LOG_LEVEL_VERBOSE, "Promised column in database '%s' has a non-matching type (%s != %s)", pp->promiser, ref_type, type); ret = false; } } else { if (strcmp(type, ref_type) != 0) { Log(LOG_LEVEL_VERBOSE, "Promised column in database '%s' has a non-matching type (%s != %s)", pp->promiser, ref_type, type); ret = false; } } } return ret; } /*****************************************************************************/ static void ListTables(int type, char *query) { switch (type) { case DATABASE_TYPE_MYSQL: snprintf(query, CF_MAXVARSIZE - 1, "show tables"); break; case DATABASE_TYPE_POSTGRES: /* This gibberish is the simplest thing I can find in postgres */ snprintf(query, CF_MAXVARSIZE - 1, "SELECT c.relname as \"Name\" FROM pg_catalog.pg_class c JOIN pg_catalog.pg_roles r ON r.oid = c.relowner LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'public'"); break; default: snprintf(query, CF_MAXVARSIZE, "NULL QUERY"); break; } } cfengine-3.24.2/cf-agent/package_module.c0000644000000000000000000016443615010704253020161 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* RecordPkgOperationInChroot() */ #include /* CHROOT_PKG_OPERATION_* */ #include /* safely write csv entries */ #define INVENTORY_LIST_BUFFER_SIZE 100 * 80 /* 100 entries with 80 characters * per line */ static bool UpdateSinglePackageModuleCache(EvalContext *ctx, const PackageModuleWrapper *module_wrapper, UpdateType type, bool force_update); static void GetPackageModuleExecInfo(const PackageModuleBody *package_module, char **exec_path, char **script_path, char **script_path_quoted, char **script_exec_opts); static int NegotiateSupportedAPIVersion(PackageModuleWrapper *wrapper); void DeletePackageModuleWrapper(PackageModuleWrapper *wrapper) { if (wrapper != NULL) { free(wrapper->path); free(wrapper->script_path); free(wrapper->script_path_quoted); free(wrapper->script_exec_opts); free(wrapper->name); free(wrapper); } } PackageModuleWrapper *NewPackageModuleWrapper(PackageModuleBody *package_module) { assert(package_module && package_module->name); PackageModuleWrapper *wrapper = xmalloc(sizeof(PackageModuleWrapper)); GetPackageModuleExecInfo(package_module, &(wrapper->path), &(wrapper->script_path), &(wrapper->script_path_quoted), &(wrapper->script_exec_opts)); wrapper->name = SafeStringDuplicate(package_module->name); wrapper->package_module = package_module; if (wrapper->path == NULL) { Log(LOG_LEVEL_ERR, "No executable for the package module '%s'", package_module->name); DeletePackageModuleWrapper(wrapper); return NULL; } /* Check if the given files exist and have the required permissions. */ if (wrapper->script_path != NULL) { /* we were given a path to a script to execute with the given * interpreter */ const char *interpreter_path = wrapper->path; const char *script_path = wrapper->script_path; if (access(interpreter_path, X_OK) != 0) { Log(LOG_LEVEL_ERR, "Cannot find package module interpreter at location '%s'" " or access to the file is restricted: %s", wrapper->path, GetErrorStr()); DeletePackageModuleWrapper(wrapper); return NULL; } if (access(script_path, R_OK) != 0) { Log(LOG_LEVEL_ERR, "Cannot find package module script at location '%s'" " or access to the file is restricted: %s", wrapper->script_path, GetErrorStr()); DeletePackageModuleWrapper(wrapper); return NULL; } } else if (access(wrapper->path, X_OK) != 0) { /* no script path specified --> the given path has to be executable */ Log(LOG_LEVEL_ERR, "Cannot find package module at location '%s' or access to file is restricted: %s", wrapper->path, GetErrorStr()); DeletePackageModuleWrapper(wrapper); return NULL; } /* Negotiate API version */ wrapper->supported_api_version = NegotiateSupportedAPIVersion(wrapper); if (wrapper->supported_api_version != 1) { Log(LOG_LEVEL_ERR, "Unsupported package module wrapper API version: %d", wrapper->supported_api_version); DeletePackageModuleWrapper(wrapper); return NULL; } Log(LOG_LEVEL_DEBUG, "Successfully created package module wrapper for '%s' package module.", package_module->name); return wrapper; } static int PackageWrapperCommunicate(const PackageModuleWrapper *wrapper, const char *args, const char *request, Rlist **response) { char *all_args = NULL; if (wrapper->script_path != NULL) { if (wrapper->script_exec_opts == NULL) { all_args = StringConcatenate(3, wrapper->script_path_quoted, " ", args); args = all_args; } else { all_args = StringConcatenate(5, wrapper->script_exec_opts, " ", wrapper->script_path_quoted, " ", args); args = all_args; } } int ret = PipeReadWriteData(wrapper->path, args, request, response, PACKAGE_PROMISE_SCRIPT_TIMEOUT_SEC, PACKAGE_PROMISE_TERMINATION_CHECK_SEC); free(all_args); return ret; } void UpdatePackagesCache(EvalContext *ctx, bool force_update) { Log(LOG_LEVEL_DEBUG, "Updating package cache."); PackagePromiseGlobalLock package_lock = AcquireGlobalPackagePromiseLock(ctx); if (package_lock.g_lock.lock == NULL) { Log(LOG_LEVEL_INFO, "Can not acquire global lock for package promise. " "Skipping updating cache."); return; } Rlist *default_inventory = GetDefaultInventoryFromContext(ctx); for (const Rlist *rp = default_inventory; rp != NULL; rp = rp->next) { const char *pm_name = RlistScalarValue(rp); PackageModuleBody *module = GetPackageModuleFromContext(ctx, pm_name); if (!module) { Log(LOG_LEVEL_ERR, "Can not find body for package module: %s", pm_name); continue; } PackageModuleWrapper *module_wrapper = NewPackageModuleWrapper(module); if (!module_wrapper) { Log(LOG_LEVEL_ERR, "Can not set up wrapper for module: %s", pm_name); continue; } UpdateSinglePackageModuleCache(ctx, module_wrapper, UPDATE_TYPE_INSTALLED, force_update); UpdateSinglePackageModuleCache(ctx, module_wrapper, force_update ? UPDATE_TYPE_UPDATES : UPDATE_TYPE_LOCAL_UPDATES, force_update); DeletePackageModuleWrapper(module_wrapper); } YieldGlobalPackagePromiseLock(package_lock); } PackagePromiseGlobalLock AcquireGlobalPackagePromiseLock(EvalContext *ctx) { Bundle bundle = {.name = "package_global"}; BundleSection section = {.promise_type = "package_global", .parent_bundle = &bundle}; Promise pp = {.promiser = "package_global", .parent_section = §ion}; CfLock package_promise_global_lock; package_promise_global_lock = AcquireLock(ctx, GLOBAL_PACKAGE_PROMISE_LOCK_NAME, VUQNAME, CFSTARTTIME, 0, VEXPIREAFTER, &pp, false); return (PackagePromiseGlobalLock) {.g_lock = package_promise_global_lock, .lock_ctx = ctx}; } void YieldGlobalPackagePromiseLock(PackagePromiseGlobalLock lock) { Bundle bundle = {.name = "package_global"}; BundleSection section = {.promise_type = "package_global", .parent_bundle = &bundle}; Promise pp = {.promiser = "package_global", .parent_section = §ion}; YieldCurrentLockAndRemoveFromCache(lock.lock_ctx, lock.g_lock, GLOBAL_PACKAGE_PROMISE_LOCK_NAME, &pp); } static void ParseAndLogErrorMessage(const Rlist *data) { for (const Rlist *rp = data; rp != NULL; rp = rp->next) { char *line = RlistScalarValue(rp); if (StringStartsWith(line, "Error=")) { Log(LOG_LEVEL_ERR, "package module: %s", line); } else if (StringStartsWith(line, "ErrorMessage=")) { Log(LOG_LEVEL_ERR, "package module: %s", line); } else { Log(LOG_LEVEL_VERBOSE, "Unsupported response from package module: %s", line); } } } static void FreePackageInfo(PackageInfo *package_info) { if (package_info) { free(package_info->arch); free(package_info->name); free(package_info->version); free(package_info); } } static char *ParseOptions(Rlist *options) { if (RlistIsNullList(options)) { return SafeStringDuplicate(""); } Buffer *data = BufferNew(); for (Rlist *rp = options; rp != NULL; rp = rp->next) { char *value = RlistScalarValue(rp); BufferAppendString(data, "options="); BufferAppendString(data, value); BufferAppendString(data, "\n"); } return BufferClose(data); } static PackageInfo *ParseAndCheckPackageDataReply(const Rlist *data) { PackageInfo * package_data = xcalloc(1, sizeof(PackageInfo)); for (const Rlist *rp = data; rp != NULL; rp = rp->next) { const char *line = RlistScalarValue(rp); if (StringStartsWith(line, "PackageType=")) { const char *type = line + strlen("PackageType="); if (StringEqual(type, "file")) { package_data->type = PACKAGE_TYPE_FILE; } else if (StringEqual(type, "repo")) { package_data->type = PACKAGE_TYPE_REPO; } else { Log(LOG_LEVEL_VERBOSE, "unsupported package type: %s", type); free(package_data); return NULL; } } else if (StringStartsWith(line, "Name=")) { if (package_data->name) { /* Some error occurred as we already have name for * given package. */ Log(LOG_LEVEL_ERR, "Extraneous package name line received: [%s] %s", line, package_data->name); free(package_data); return NULL; } package_data->name = SafeStringDuplicate(line + strlen("Name=")); } else if (StringStartsWith(line, "Version=")) { if (package_data->version) { /* Some error occurred as we already have version for * given package. */ Log(LOG_LEVEL_ERR, "Extraneous package version line received: [%s] %s", line, package_data->version); free(package_data); return NULL; } package_data->version = SafeStringDuplicate(line + strlen("Version=")); } else if (StringStartsWith(line, "Architecture=")) { if (package_data->arch) { /* Some error occurred as we already have arch for * given package. */ Log(LOG_LEVEL_ERR, "Extraneous package architecture line received: [%s] %s", line, package_data->arch); free(package_data); return NULL; } package_data->arch = SafeStringDuplicate(line + strlen("Architecture=")); } /* For handling errors */ else if (StringStartsWith(line, "Error=")) { Log(LOG_LEVEL_ERR, "package module: %s", line); } else if (StringStartsWith(line, "ErrorMessage=")) { Log(LOG_LEVEL_ERR, "package module: %s", line); } else { Log(LOG_LEVEL_VERBOSE, "Unsupported response from package module: %s", line); } } return package_data; } static int NegotiateSupportedAPIVersion(PackageModuleWrapper *wrapper) { assert(wrapper); Log(LOG_LEVEL_DEBUG, "Getting supported API version."); int api_version = -1; Rlist *response = NULL; if (PackageWrapperCommunicate(wrapper, "supports-api-version", "", &response) != 0) { Log(LOG_LEVEL_INFO, "Error occurred while getting supported API version."); return -1; } if (response) { if (RlistLen(response) == 1) { api_version = atoi(RlistScalarValue(response)); Log(LOG_LEVEL_DEBUG, "package wrapper API version: %d", api_version); } RlistDestroy(response); } return api_version; } /* IMPORTANT: this might not return all the data we need like version or architecture but package name MUST be known. */ static PackageInfo *GetPackageData(const char *name, const char *version, const char *architecture, Rlist *options, const PackageModuleWrapper *wrapper) { assert(wrapper); Log(LOG_LEVEL_DEBUG, "Getting package '%s' data.", name); char *options_str = ParseOptions(options); char *ver = version ? StringFormat("Version=%s\n", version) : NULL; char *arch = architecture ? StringFormat("Architecture=%s\n", architecture) : NULL; char *request = StringFormat("%sFile=%s\n%s%s", options_str, name, ver ? ver : "", arch ? arch : ""); free(ver); free(arch); Rlist *response = NULL; if (PackageWrapperCommunicate(wrapper, "get-package-data", request, &response) != 0) { Log(LOG_LEVEL_INFO, "Some error occurred while communicating with " "package module while collecting package data."); free(options_str); free(request); return NULL; } PackageInfo *package_data = NULL; if (response) { package_data = ParseAndCheckPackageDataReply(response); RlistDestroy(response); if (package_data) { /* At this point at least package name and type MUST be known * (if no error) */ if (!package_data->name || package_data->type == PACKAGE_TYPE_NONE) { Log(LOG_LEVEL_INFO, "Unknown package name or type."); FreePackageInfo(package_data); package_data = NULL; } } } free(options_str); free(request); return package_data; } static void GetPackageModuleExecInfo(const PackageModuleBody *package_module, char **exec_path, char **script_path, char **script_path_quoted, char **script_exec_opts) { assert(exec_path != NULL); assert(script_path != NULL); assert(script_path_quoted != NULL); char *package_module_path = NULL; if (package_module->module_path != NULL && !StringEqual(package_module->module_path, "")) { package_module_path = xstrdup(package_module->module_path); } else { package_module_path = StringFormat("%s%c%s%c%s%c%s", GetWorkDir(), FILE_SEPARATOR, "modules", FILE_SEPARATOR, "packages", FILE_SEPARATOR, package_module->name); } if (package_module->interpreter && !StringEqual(package_module->interpreter, "")) { *script_path = package_module_path; *script_path_quoted = Path_GetQuoted(*script_path); if (strchr(package_module->interpreter, ' ') == NULL) { /* No spaces in the 'interpreter' string, easy! Just interpreter path given, no opts. */ *exec_path = xstrdup(package_module->interpreter); *script_exec_opts = NULL; } else { /* we need to split the interpreter command from the (potential) * interpreter args */ ArgGetExecutableAndArgs(package_module->interpreter, exec_path, script_exec_opts); } } else { *exec_path = package_module_path; *script_path = NULL; *script_path_quoted = NULL; *script_exec_opts = NULL; } } static int IsPackageInCache(EvalContext *ctx, const PackageModuleWrapper *module_wrapper, const char *name, const char *ver, const char *arch) { const char *version = ver; /* Handle latest version in specific way for repo packages. * Please note that for file packages 'latest' version is not supported * and check against that is made in CheckPolicyAndPackageInfoMatch(). */ if (version && StringEqual(version, "latest")) { version = NULL; } /* Make sure cache is updated. */ if (ctx) { if (!UpdateSinglePackageModuleCache(ctx, module_wrapper, UPDATE_TYPE_INSTALLED, false)) { Log(LOG_LEVEL_ERR, "Can not update cache."); } } CF_DB *db_cached; if (!OpenSubDB(&db_cached, dbid_packages_installed, module_wrapper->package_module->name)) { Log(LOG_LEVEL_INFO, "Can not open cache database."); return -1; } char *key = NULL; if (version && arch) { key = StringFormat("N<%s>V<%s>A<%s>", name, version, arch); } else if (version) { key = StringFormat("N<%s>V<%s>", name, version); } else if (arch) { key = StringFormat("N<%s>A<%s>", name, arch); } else { key = StringFormat("N<%s>", name); } int is_in_cache = 0; char buff[1]; Log(LOG_LEVEL_DEBUG, "Looking for key in installed packages cache: %s", key); if (ReadDB(db_cached, key, buff, 1)) { /* Just make sure DB is not corrupted. */ if (buff[0] == '1') { is_in_cache = 1; } else { Log(LOG_LEVEL_INFO, "Seem to have corrupted data in cache database"); is_in_cache = -1; } } Log(LOG_LEVEL_DEBUG, "Looking for package %s in cache returned: %d", name, is_in_cache); CloseDB(db_cached); return is_in_cache; } void WritePackageDataToDB(CF_DB *db_installed, const char *name, const char *ver, const char *arch, UpdateType type) { char package_key[strlen(name) + strlen(ver) + strlen(arch) + 11]; xsnprintf(package_key, sizeof(package_key), "N<%s>", name); if (type == UPDATE_TYPE_INSTALLED) { WriteDB(db_installed, package_key, "1", 1); xsnprintf(package_key, sizeof(package_key), "N<%s>V<%s>", name, ver); WriteDB(db_installed, package_key, "1", 1); xsnprintf(package_key, sizeof(package_key), "N<%s>A<%s>", name, arch); WriteDB(db_installed, package_key, "1", 1); xsnprintf(package_key, sizeof(package_key), "N<%s>V<%s>A<%s>", name, ver, arch); WriteDB(db_installed, package_key, "1", 1); } else if (HasKeyDB(db_installed, package_key, strlen(package_key) + 1)) { /* type == UPDATE_TYPE_UPDATES || type == UPDATE_TYPE_LOCAL_UPDATES */ size_t val_size = ValueSizeDB(db_installed, package_key, strlen(package_key) + 1); char buff[val_size + strlen(arch) + strlen(ver) + 8]; ReadDB(db_installed, package_key, buff, val_size); xsnprintf(buff + val_size, sizeof(package_key), "V<%s>A<%s>\n", ver, arch); Log(LOG_LEVEL_DEBUG, "Updating available updates key '%s' with value '%s'", package_key, buff); WriteDB(db_installed, package_key, buff, strlen(buff)); } else { /* type == UPDATE_TYPE_UPDATES || type == UPDATE_TYPE_LOCAL_UPDATES */ char buff[strlen(arch) + strlen(ver) + 8]; xsnprintf(buff, sizeof(package_key), "V<%s>A<%s>\n", ver, arch); WriteDB(db_installed, package_key, buff, strlen(buff)); } } int UpdatePackagesDB(Rlist *data, const char *pm_name, UpdateType type) { assert(pm_name); bool have_error = false; CF_DB *db_cached; dbid db_id = type == UPDATE_TYPE_INSTALLED ? dbid_packages_installed : dbid_packages_updates; if (OpenSubDB(&db_cached, db_id, pm_name)) { CleanDB(db_cached); Writer *idw = StringWriter(); CsvWriter *idcw = CsvWriterOpen(idw); const char *package_data[3] = {NULL, NULL, NULL}; for (const Rlist *rp = data; rp != NULL; rp = rp->next) { const char *line = RlistScalarValue(rp); if (StringStartsWith(line, "Name=")) { if (package_data[0]) { if (package_data[1] && package_data[2]) { WritePackageDataToDB(db_cached, package_data[0], package_data[1], package_data[2], type); CsvWriterField(idcw, package_data[0]); CsvWriterField(idcw, package_data[1]); CsvWriterField(idcw, package_data[2]); CsvWriterNewRecord(idcw); } else { /* some error occurred */ Log(LOG_LEVEL_VERBOSE, "Malformed response from package module for package %s", package_data[0]); } package_data[1] = NULL; package_data[2] = NULL; } /* This must be the first entry on a list */ package_data[0] = line + strlen("Name="); } else if (StringStartsWith(line, "Version=")) { package_data[1] = line + strlen("Version="); } else if (StringStartsWith(line, "Architecture=")) { package_data[2] = line + strlen("Architecture="); } else if (StringStartsWith(line, "Error=")) { Log(LOG_LEVEL_ERR, "package module: %s", line); have_error = true; } else if (StringStartsWith(line, "ErrorMessage=")) { Log(LOG_LEVEL_ERR, "package module: %s", line); have_error = true; } else { Log(LOG_LEVEL_ERR, "Unsupported response from package module: %s", line); have_error = true; } } /* We should have one more entry left or empty 'package_data'. */ if (package_data[0] && package_data[1] && package_data[2]) { WritePackageDataToDB(db_cached, package_data[0], package_data[1], package_data[2], type); CsvWriterField(idcw, package_data[0]); CsvWriterField(idcw, package_data[1]); CsvWriterField(idcw, package_data[2]); CsvWriterNewRecord(idcw); } else if (package_data[0] || package_data[1] || package_data[2]) { Log(LOG_LEVEL_VERBOSE, "Malformed response from package manager: [%s:%s:%s]", package_data[0] ? package_data[0] : "", package_data[1] ? package_data[1] : "", package_data[2] ? package_data[2] : ""); } char *inventory_key = ""; CsvWriterClose(idcw); char *inventory_list = StringWriterClose(idw); // Legacy: the lines are expected to be separated by newlines, not CRLF const size_t buf_size = strlen(inventory_list); NDEBUG_UNUSED const ssize_t num_repl = StringReplace(inventory_list, buf_size, "\r\n", "\n"); assert(num_repl >= 0); /* We can have empty list of installed software or available updates. */ if (inventory_list == NULL) { WriteDB(db_cached, inventory_key, "", 0); } else { WriteDB(db_cached, inventory_key, inventory_list, strlen(inventory_list)); free(inventory_list); } CloseDB(db_cached); return have_error ? -1 : 0; } /* Unable to open database. */ return -1; } bool UpdateCache(Rlist* options, const PackageModuleWrapper *wrapper, UpdateType type) { assert(wrapper); Log(LOG_LEVEL_DEBUG, "Updating cache: %d", type); char *options_str = ParseOptions(options); Rlist *response = NULL; const char *req_type = NULL; if (type == UPDATE_TYPE_INSTALLED) { req_type = "list-installed"; } else if (type == UPDATE_TYPE_UPDATES) { req_type = "list-updates"; } else if (type == UPDATE_TYPE_LOCAL_UPDATES) { req_type = "list-updates-local"; } if (PackageWrapperCommunicate(wrapper, req_type, options_str, &response) != 0) { Log(LOG_LEVEL_VERBOSE, "Some error occurred while communicating with " "package module while updating cache."); free(options_str); return false; } if (!response) { Log(LOG_LEVEL_DEBUG, "Received empty packages list after requesting: %s", req_type); } bool ret = true; /* We still need to update DB with empty data. */ if (UpdatePackagesDB(response, wrapper->name, type) != 0) { Log(LOG_LEVEL_INFO, "Error updating packages cache."); ret = false; } RlistDestroy(response); free(options_str); return ret; } PromiseResult ValidateChangedPackage(const NewPackages *policy_data, const PackageModuleWrapper *wrapper, const PackageInfo *package_info, NewPackageAction action_type) { assert(package_info && package_info->name); Log(LOG_LEVEL_DEBUG, "Validating package: %s", package_info->name); if (!UpdateCache(policy_data->package_options, wrapper, UPDATE_TYPE_INSTALLED)) { Log(LOG_LEVEL_INFO, "Can not update installed packages cache after package installation"); return PROMISE_RESULT_FAIL; } if (!UpdateCache(policy_data->package_options, wrapper, UPDATE_TYPE_LOCAL_UPDATES)) { Log(LOG_LEVEL_INFO, "Can not update available updates cache after package installation"); return PROMISE_RESULT_FAIL; } int is_in_cache = IsPackageInCache(NULL, wrapper, package_info->name, package_info->version, package_info->arch); if (is_in_cache == 1) { return action_type == NEW_PACKAGE_ACTION_PRESENT ? PROMISE_RESULT_CHANGE : PROMISE_RESULT_FAIL; } else if (is_in_cache == 0) { return action_type == NEW_PACKAGE_ACTION_PRESENT ? PROMISE_RESULT_FAIL : PROMISE_RESULT_CHANGE; } else { Log(LOG_LEVEL_INFO, "Some error occurred while reading installed packages cache."); return PROMISE_RESULT_FAIL; } } PromiseResult RemovePackage(const char *name, Rlist* options, const char *version, const char *architecture, const PackageModuleWrapper *wrapper) { assert(wrapper); Log(LOG_LEVEL_DEBUG, "Removing package '%s'", name); char *options_str = ParseOptions(options); char *ver = version ? StringFormat("Version=%s\n", version) : NULL; char *arch = architecture ? StringFormat("Architecture=%s\n", architecture) : NULL; char *request = StringFormat("%sName=%s\n%s%s", options_str, name, ver ? ver : "", arch ? arch : ""); PromiseResult res = PROMISE_RESULT_CHANGE; Rlist *error_message = NULL; if (PackageWrapperCommunicate(wrapper, "remove", request, &error_message) != 0) { Log(LOG_LEVEL_INFO, "Error communicating package module while removing package."); res = PROMISE_RESULT_FAIL; } if (error_message) { ParseAndLogErrorMessage(error_message); res = PROMISE_RESULT_FAIL; RlistDestroy(error_message); } free(request); free(options_str); free(ver); free(arch); /* We assume that at this point package is removed correctly. */ return res; } static PromiseResult InstallPackageGeneric(Rlist *options, PackageType type, const char *packages_list_formatted, const PackageModuleWrapper *wrapper) { assert(wrapper); Log(LOG_LEVEL_DEBUG, "Installing %s type package: '%s'", type == PACKAGE_TYPE_FILE ? "file" : "repo", packages_list_formatted); char *options_str = ParseOptions(options); char *request = StringFormat("%s%s", options_str, packages_list_formatted); PromiseResult res = PROMISE_RESULT_CHANGE; const char *package_install_command = NULL; if (type == PACKAGE_TYPE_FILE) { package_install_command = "file-install"; } else if (type == PACKAGE_TYPE_REPO) { package_install_command = "repo-install"; } else { /* If we end up here something bad has happened. */ ProgrammingError("Unsupported package type"); } Log(LOG_LEVEL_DEBUG, "Sending install command to package module: '%s'", request); Rlist *error_message = NULL; if (PackageWrapperCommunicate(wrapper, package_install_command, request, &error_message) != 0) { Log(LOG_LEVEL_INFO, "Some error occurred while communicating with " "package module while installing package."); res = PROMISE_RESULT_FAIL; } if (error_message) { ParseAndLogErrorMessage(error_message); res = PROMISE_RESULT_FAIL; RlistDestroy(error_message); } free(request); free(options_str); return res; } static PromiseResult InstallPackage(Rlist *options, PackageType type, const char *package_to_install, const char *version, const char *architecture, const PackageModuleWrapper *wrapper) { Log(LOG_LEVEL_DEBUG, "Installing package '%s'", package_to_install); char *ver = version ? StringFormat("Version=%s\n", version) : NULL; char *arch = architecture ? StringFormat("Architecture=%s\n", architecture) : NULL; char *request = NULL; PromiseResult res = PROMISE_RESULT_CHANGE; if (type == PACKAGE_TYPE_FILE) { request = StringFormat("File=%s\n%s%s", package_to_install, ver ? ver : "", arch ? arch : ""); } else if (type == PACKAGE_TYPE_REPO) { request = StringFormat("Name=%s\n%s%s", package_to_install, ver ? ver : "", arch ? arch : ""); } else { /* If we end up here something bad has happened. */ ProgrammingError("Unsupported package type"); } res = InstallPackageGeneric(options, type, request, wrapper); free(request); free(ver); free(arch); return res; } static PromiseResult FileInstallPackage(EvalContext *ctx, const Promise *pp, const Attributes *attr, const char *package_file_path, const PackageInfo *info, const PackageModuleWrapper *wrapper, int is_in_cache) { assert(attr != NULL); const NewPackages *policy_data = &(attr->new_packages); Log(LOG_LEVEL_DEBUG, "Installing file type package."); /* We have some packages matching file package promise in cache. */ if (is_in_cache == 1) { Log(LOG_LEVEL_VERBOSE, "Package exists in cache. Skipping installation."); if (ChrootChanges()) { RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_PRESENT, package_file_path, NULL, NULL); } return PROMISE_RESULT_NOOP; } PromiseResult res; if (MakingChanges(ctx, pp, attr, &res, "install file type package: %s", package_file_path)) { if (ChrootChanges()) { /* TODO: simulate file package installation */ RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_INSTALL, package_file_path, NULL, NULL); return PROMISE_RESULT_CHANGE; } res = InstallPackage(policy_data->package_options, PACKAGE_TYPE_FILE, package_file_path, NULL, NULL, wrapper); if (res == PROMISE_RESULT_CHANGE) { Log(LOG_LEVEL_DEBUG, "Validating package: %s", package_file_path); return ValidateChangedPackage(policy_data, wrapper, info, NEW_PACKAGE_ACTION_PRESENT); } } return res; } static Seq *GetVersionsFromUpdates(EvalContext *ctx, const PackageInfo *info, const PackageModuleWrapper *module_wrapper) { assert(info && info->name); CF_DB *db_updates; dbid db_id = dbid_packages_updates; Seq *updates_list = NULL; /* Make sure cache is updated. */ if (!UpdateSinglePackageModuleCache(ctx, module_wrapper, UPDATE_TYPE_UPDATES, false)) { Log(LOG_LEVEL_INFO, "Can not update packages cache."); } if (OpenSubDB(&db_updates, db_id, module_wrapper->package_module->name)) { char package_key[strlen(info->name) + 4]; xsnprintf(package_key, sizeof(package_key), "N<%s>", info->name); Log(LOG_LEVEL_DEBUG, "Looking for key in updates: %s", package_key); if (HasKeyDB(db_updates, package_key, sizeof(package_key))) { Log(LOG_LEVEL_DEBUG, "Found key in updates database"); updates_list = SeqNew(3, FreePackageInfo); size_t val_size = ValueSizeDB(db_updates, package_key, sizeof(package_key)); char buff[val_size + 1]; buff[val_size] = '\0'; ReadDB(db_updates, package_key, buff, val_size); Seq* updates = SeqStringFromString(buff, '\n'); for (size_t i = 0; i < SeqLength(updates); i++) { char *package_line = SeqAt(updates, i); Log(LOG_LEVEL_DEBUG, "Got line in updates database: '%s", package_line); char version[strlen(package_line)]; char arch[strlen(package_line)]; if (sscanf(package_line, "V<%[^>]>A<%[^>]>", version, arch) == 2) { PackageInfo *package = xcalloc(1, sizeof(PackageInfo)); package->name = SafeStringDuplicate(info->name); package->version = SafeStringDuplicate(version); package->arch = SafeStringDuplicate(arch); SeqAppend(updates_list, package); } else { /* Some error occurred while scanning package updates. */ Log(LOG_LEVEL_INFO, "Unable to parse available updates line: %s", package_line); } } } CloseDB(db_updates); } return updates_list; } static PromiseResult RepoInstall(EvalContext *ctx, const Promise *pp, const Attributes *attr, const PackageInfo *package_info, const PackageModuleWrapper *wrapper, int is_in_cache, bool *verified) { assert(attr != NULL); assert(package_info != NULL); const NewPackages *policy_data = &(attr->new_packages); Log(LOG_LEVEL_DEBUG, "Installing repo type package: %d", is_in_cache); const char *const package_version = package_info->version; const char *const package_name = package_info->name; /* Package is not present in cache. */ if (is_in_cache == 0) { /* Make sure cache is updated. */ if (!UpdateSinglePackageModuleCache(ctx, wrapper, UPDATE_TYPE_UPDATES, false)) { Log(LOG_LEVEL_INFO, "Can not update packages cache."); } const char *version = package_version; if (StringEqual(version, "latest")) { Log(LOG_LEVEL_DEBUG, "Clearing latest package version"); version = NULL; } PromiseResult result = PROMISE_RESULT_FAIL; if (MakingChanges(ctx, pp, attr, &result, "install repo type package: %s", package_name)) { if (ChrootChanges()) { /* TODO: simulate package installation */ RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_INSTALL, package_name, package_version, package_info->arch); return PROMISE_RESULT_CHANGE; } *verified = false; /* Verification will be done in RepoInstallPackage(). */ result = InstallPackage(policy_data->package_options, PACKAGE_TYPE_REPO, package_name, version, package_info->arch, wrapper); } return result; } /* We have some packages matching already installed at this point. */ if (!StringEqual(package_version, "latest")) { /* No version or explicit version specified. */ if (ChrootChanges()) { RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_PRESENT, package_name, package_version, package_info->arch); } Log(LOG_LEVEL_VERBOSE, "Package '%s' already installed", package_name); return PROMISE_RESULT_NOOP; } /* We have 'latest' version in policy. */ /* This can return more than one latest version if we have packages * with different architectures installed. */ Seq *latest_versions = GetVersionsFromUpdates(ctx, package_info, wrapper); if (latest_versions == NULL) { if (ChrootChanges()) { RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_PRESENT, package_name, package_version, package_info->arch); } Log(LOG_LEVEL_VERBOSE, "Package '%s' is already in the latest version. " "Skipping installation.", package_name); return PROMISE_RESULT_NOOP; } PromiseResult res = PROMISE_RESULT_NOOP; Buffer *install_buffer = BufferNew(); Seq *packages_to_install = SeqNew(1, NULL); /* Loop through possible updates. */ size_t length = SeqLength(latest_versions); for (size_t i = 0; i < length; i++) { PackageInfo *update_package = SeqAt(latest_versions, i); /* We can have multiple packages with different architectures * in updates available but we are interested only in updating * package with specific architecture. */ if (package_info->arch && !StringEqual(package_info->arch, update_package->arch)) { Log(LOG_LEVEL_DEBUG, "Skipping update check of package '%s' as updates" "architecure doesn't match specified in policy: %s != %s.", package_name, package_info->arch, update_package->arch); continue; } const char *const update_version = update_package->version; Log(LOG_LEVEL_DEBUG, "Checking for package '%s' version '%s' in available updates", package_name, update_version); /* Just in case some package managers will report highest possible * version in updates list instead of removing entry if package is * already in the latest version. */ const int update_in_cache = IsPackageInCache( ctx, wrapper, package_name, update_version, update_package->arch); if (update_in_cache == 1) { if (ChrootChanges()) { RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_PRESENT, package_name, update_version, update_package->arch); } Log(LOG_LEVEL_VERBOSE, "Package version from updates matches one installed. " "Skipping package installation."); res = PromiseResultUpdate(res, PROMISE_RESULT_NOOP); continue; } else if (update_in_cache == -1) { Log(LOG_LEVEL_INFO, "Skipping package installation due to error with checking " "packages cache."); res = PromiseResultUpdate(res, PROMISE_RESULT_FAIL); continue; } else { PromiseResult result = PROMISE_RESULT_FAIL; if (MakingChanges(ctx, pp, attr, &result, "install repo type package: %s", package_name)) { if (ChrootChanges()) { RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_INSTALL, package_name, update_version, update_package->arch); } else { /* Append package data to buffer. At the end all packages * data that need to be updated will be sent to package module * at once. This is important if we have package in more than * one architecture. If we would update one after another we * may end up with the ones doesn't matching default * architecture being removed. */ BufferAppendF(install_buffer, "Name=%s\nVersion=%s\nArchitecture=%s\n", package_name, update_version, update_package->arch); /* Here we are adding latest_versions elements to different * seq. Make sure to not free those and not free latest_versions * before we are done with packages_to_install. * This is needed for later verification if package was * installed correctly. */ SeqAppend(packages_to_install, update_package); } } else { res = PromiseResultUpdate(res, result); continue; } } } char *install_formatted_list = BufferClose(install_buffer); if (install_formatted_list) { /* If we have some packages to install. */ if (strlen(install_formatted_list) > 0) { Log(LOG_LEVEL_DEBUG, "Formatted list of packages to be send to package module: " "[%s]", install_formatted_list); res = InstallPackageGeneric(policy_data->package_options, PACKAGE_TYPE_REPO, install_formatted_list, wrapper); for (size_t i = 0; i < SeqLength(packages_to_install); i++) { PackageInfo *to_verify = SeqAt(packages_to_install, i); PromiseResult validate = ValidateChangedPackage(policy_data, wrapper, to_verify, NEW_PACKAGE_ACTION_PRESENT); Log(LOG_LEVEL_DEBUG, "Validating package %s:%s:%s installation result: %d", to_verify->name, to_verify->version, to_verify->arch, validate); res = PromiseResultUpdate(res, validate); *verified = true; } } free(install_formatted_list); } SeqDestroy(packages_to_install); SeqDestroy(latest_versions); return res; } static PromiseResult RepoInstallPackage(EvalContext *ctx, const Promise *pp, const Attributes *attr, const PackageInfo *package_info, const PackageModuleWrapper *wrapper, int is_in_cache) { assert(attr != NULL); const NewPackages *policy_data = &(attr->new_packages); bool verified = false; PromiseResult res = RepoInstall(ctx, pp, attr, package_info, wrapper, is_in_cache, &verified); if (res == PROMISE_RESULT_CHANGE && !verified) { return ValidateChangedPackage(policy_data, wrapper, package_info, NEW_PACKAGE_ACTION_PRESENT); } return res; } static bool CheckPolicyAndPackageInfoMatch(const NewPackages *packages_policy, const PackageInfo *info) { if (packages_policy->package_version && StringEqual(packages_policy->package_version, "latest")) { Log(LOG_LEVEL_WARNING, "Unsupported 'latest' version for package " "promise of type file."); return false; } /* Check if file we are having matches what we want in policy. */ if (info->arch && packages_policy->package_architecture && !StringEqual(info->arch, packages_policy->package_architecture)) { Log(LOG_LEVEL_WARNING, "Package arch and one specified in policy doesn't match: %s -> %s", info->arch, packages_policy->package_architecture); return false; } if (info->version && packages_policy->package_version && !StringEqual(info->version, packages_policy->package_version)) { Log(LOG_LEVEL_WARNING, "Package version and one specified in policy doesn't " "match: %s -> %s", info->version, packages_policy->package_version); return false; } return true; } PromiseResult HandlePresentPromiseAction(EvalContext *ctx, const Promise *pp, const Attributes *attr, const PackageModuleWrapper *wrapper) { assert(pp != NULL); assert(attr != NULL); const char *package_name = pp->promiser; const NewPackages *policy_data = &(attr->new_packages); Log(LOG_LEVEL_DEBUG, "Starting evaluating present action promise."); /* Figure out what kind of package we are having. */ PackageInfo *package_info = GetPackageData(package_name, policy_data->package_version, policy_data->package_architecture, policy_data->package_options, wrapper); PromiseResult result = PROMISE_RESULT_FAIL; if (package_info) { /* Check if data in policy matches returned by wrapper (files only). */ if (package_info->type == PACKAGE_TYPE_FILE) { if (!CheckPolicyAndPackageInfoMatch(policy_data, package_info)) { Log(LOG_LEVEL_ERR, "Package data and policy doesn't match"); FreePackageInfo(package_info); return PROMISE_RESULT_FAIL; } } else if (package_info->type == PACKAGE_TYPE_REPO) { /* We are expecting only package name to be returned by * 'get-package-data' in case of repo package */ if (package_info->arch) { Log(LOG_LEVEL_VERBOSE, "Unexpected package architecture received from package module. Ignoring."); free(package_info->arch); package_info->arch = NULL; } if (package_info->version) { Log(LOG_LEVEL_VERBOSE, "Unexpected package version received from package module. Ignoring."); free(package_info->version); package_info->version = NULL; } } /* Fill missing data in package_info from policy. This will allow * to match cache against all known package details we are * interested in */ if (!package_info->arch && policy_data->package_architecture) { package_info->arch = SafeStringDuplicate(policy_data->package_architecture); } if (!package_info->version && policy_data->package_version) { package_info->version = SafeStringDuplicate(policy_data->package_version); } /* Check if package exists in cache */ int is_in_cache = IsPackageInCache(ctx, wrapper, package_info->name, package_info->version, package_info->arch); if (is_in_cache == -1) { Log(LOG_LEVEL_ERR, "Some error occurred while looking for package '%s' in cache.", package_name); return PROMISE_RESULT_FAIL; } switch (package_info->type) { case PACKAGE_TYPE_FILE: result = FileInstallPackage(ctx, pp, attr, package_name, package_info, wrapper, is_in_cache); break; case PACKAGE_TYPE_REPO: result = RepoInstallPackage(ctx, pp, attr, package_info, wrapper, is_in_cache); break; default: /* We shouldn't end up here. If we are having unsupported package type this should be detected and handled in ParseAndCheckPackageDataReply(). */ ProgrammingError("Unsupported package type"); } FreePackageInfo(package_info); } else { Log(LOG_LEVEL_INFO, "Can not obtain package data for promise: %s", package_name); } Log(LOG_LEVEL_DEBUG, "Evaluating present action promise status: %c", result); return result; } PromiseResult HandleAbsentPromiseAction(EvalContext *ctx, const Promise *pp, const Attributes *attr, const PackageModuleWrapper *wrapper) { assert(pp != NULL); assert(attr != NULL); const char *package_name = pp->promiser; const NewPackages *policy_data = &(attr->new_packages); /* Check if we are not having 'latest' version. */ if (policy_data->package_version && StringEqual(policy_data->package_version, "latest")) { Log(LOG_LEVEL_ERR, "Package version 'latest' not supported for" "absent package promise"); return PROMISE_RESULT_FAIL; } /* Check if package exists in cache */ int is_in_cache = IsPackageInCache(ctx, wrapper, package_name, policy_data->package_version, policy_data->package_architecture); if (is_in_cache == 1) { /* Remove package(s) */ PromiseResult res; if (MakingChanges(ctx, pp, attr, &res, "remove package '%s'", package_name)) { if (ChrootChanges()) { /* TODO: simulate removal */ RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_REMOVE, package_name, policy_data->package_version, policy_data->package_architecture); return PROMISE_RESULT_CHANGE; } res = RemovePackage(package_name, policy_data->package_options, policy_data->package_version, policy_data->package_architecture, wrapper); if (res == PROMISE_RESULT_CHANGE) { /* Check if package was removed. */ /* package_name is actually pp->promiser which is 'const char *' * so we need to type-cast it. It's safe because pkg_info is * passed as const *PackageInfo. */ const PackageInfo pkg_info = { .name = (char *) package_name, .version = policy_data->package_version, .arch = policy_data->package_architecture }; return ValidateChangedPackage(policy_data, wrapper, &(pkg_info), NEW_PACKAGE_ACTION_ABSENT); } } return res; } else if (is_in_cache == -1) { Log(LOG_LEVEL_ERR, "Error occurred while checking package '%s' " "existence in cache.", package_name); return PROMISE_RESULT_FAIL; } else { /* Package is not in cache which means it is already removed. */ Log(LOG_LEVEL_DEBUG, "Package '%s' not installed. Skipping removing.", package_name); if (ChrootChanges()) { RecordPkgOperationInChroot(CHROOT_PKG_OPERATION_ABSENT, package_name, policy_data->package_version, policy_data->package_architecture); } return PROMISE_RESULT_NOOP; } } /* IMPORTANT: This must be called under protection of * GLOBAL_PACKAGE_PROMISE_LOCK_NAME lock! */ bool UpdateSinglePackageModuleCache(EvalContext *ctx, const PackageModuleWrapper *module_wrapper, UpdateType type, bool force_update) { assert(module_wrapper->package_module->name); Log(LOG_LEVEL_DEBUG, "Trying to%s update cache type: %d.", force_update ? " force" : "", type); if (!force_update) { if (module_wrapper->package_module->installed_ifelapsed == CF_NOINT || module_wrapper->package_module->updates_ifelapsed == CF_NOINT) { Log(LOG_LEVEL_ERR, "Invalid or missing arguments in package_module body '%s': " "query_installed_ifelapsed = %d query_updates_ifelapsed = %d", module_wrapper->package_module->name, module_wrapper->package_module->installed_ifelapsed, module_wrapper->package_module->updates_ifelapsed); return false; } } Bundle bundle = {.name = "package_cache"}; BundleSection section = {.promise_type = "package_cache", .parent_bundle = &bundle}; Promise pp = {.promiser = "package_cache", .parent_section = §ion}; CfLock cache_updates_lock = {NULL, NULL, false}; char cache_updates_lock_name[CF_BUFSIZE]; int ifelapsed_time = -1; dbid dbid_val; if (type == UPDATE_TYPE_INSTALLED) { dbid_val = dbid_packages_installed; snprintf(cache_updates_lock_name, CF_BUFSIZE - 1, "package-cache-installed-%s", module_wrapper->package_module->name); ifelapsed_time = module_wrapper->package_module->installed_ifelapsed; } else { dbid_val = dbid_packages_updates; snprintf(cache_updates_lock_name, CF_BUFSIZE - 1, "package-cache-updates-%s", module_wrapper->package_module->name); ifelapsed_time = module_wrapper->package_module->updates_ifelapsed; } char *db_name = DBIdToSubPath(dbid_val, module_wrapper->name); struct stat statbuf; if (!force_update) { if (stat(db_name, &statbuf) == -1 && errno == ENOENT) { /* Force update if database file doesn't exist. Not strictly * necessary with the locks we have, but good to have for tests * that delete the database. */ Log(LOG_LEVEL_VERBOSE, "Forcing package list update due to missing database"); force_update = true; /* When the cfengine database containing the cache of package updates * available is initialized we should use the network to get the * current list of updates available. It's not unlikely that the OS * does not yet have a local cache, which simply results in an error * getting a list of package updates available. */ if (type == UPDATE_TYPE_LOCAL_UPDATES) { type = UPDATE_TYPE_UPDATES; } } cache_updates_lock = AcquireLock(ctx, cache_updates_lock_name, VUQNAME, CFSTARTTIME, ifelapsed_time, VEXPIREAFTER, &pp, false); } free(db_name); bool ret = true; if (force_update || cache_updates_lock.lock != NULL) { /* Update available updates cache. */ if (!UpdateCache(module_wrapper->package_module->options, module_wrapper, type)) { Log(LOG_LEVEL_INFO, "Some error occurred while updating available updates cache."); ret = false; } if (cache_updates_lock.lock != NULL) { YieldCurrentLock(cache_updates_lock); } } else { Log(LOG_LEVEL_VERBOSE, "Skipping %s package cache update.", type == UPDATE_TYPE_INSTALLED ? "installed packages" : "available updates"); } return ret; } cfengine-3.24.2/cf-agent/tokyo_check.h0000644000000000000000000000212515010704253017512 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_TOKYO_CHECK_H #define CFENGINE_TOKYO_CHECK_H int CheckTokyoDBCoherence( const char *path ); #endif cfengine-3.24.2/cf-agent/abstract_dir.h0000644000000000000000000000254315010704253017655 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ABSTRACT_DIR_H #define CFENGINE_ABSTRACT_DIR_H /* * Opening and reading directory from either local host or CFEngine server */ typedef struct AbstractDir_ AbstractDir; AbstractDir *AbstractDirOpen(const char *dirname, const FileCopy *fc, AgentConnection *pp); const struct dirent *AbstractDirRead(AbstractDir *dir); void AbstractDirClose(AbstractDir *dir); #endif cfengine-3.24.2/cf-agent/retcode.h0000644000000000000000000000230715010704253016637 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_RETCODE_H #define CFENGINE_RETCODE_H #include #include bool VerifyCommandRetcode(EvalContext *ctx, int retcode, const Attributes *a, const Promise *pp, PromiseResult *result); #endif cfengine-3.24.2/cf-agent/abstract_dir.c0000644000000000000000000000514615010704253017652 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include struct AbstractDir_ { /* Local directories */ Dir *local_dir; /* Remote directories */ Item *list; Item *listpos; }; AbstractDir *AbstractDirOpen(const char *dirname, const FileCopy *fc, AgentConnection *conn) { AbstractDir *d = xcalloc(1, sizeof(AbstractDir)); if (conn == NULL) { d->local_dir = DirOpen(dirname); if (d->local_dir == NULL) { free(d); return NULL; } } else { assert(fc->servers && strcmp(RlistScalarValue(fc->servers), "localhost")); d->list = RemoteDirList(dirname, fc->encrypt, conn); if (d->list == NULL) { free(d); return NULL; } d->listpos = d->list; } return d; } static const struct dirent *RemoteDirRead(AbstractDir *dir) { const struct dirent *ret = NULL; if (dir->listpos != NULL) { ret = (const struct dirent *)dir->listpos->name; dir->listpos = dir->listpos->next; } return ret; } const struct dirent *AbstractDirRead(AbstractDir *dir) { if (dir->local_dir) { return DirRead(dir->local_dir); } else { return RemoteDirRead(dir); } } static void RemoteDirClose(AbstractDir *dir) { if (dir->list) { DeleteItemList(dir->list); } free(dir); } void AbstractDirClose(AbstractDir *dir) { if (dir->local_dir) { DirClose(dir->local_dir); free(dir); } else { RemoteDirClose(dir); } } cfengine-3.24.2/cf-agent/verify_acl.h0000644000000000000000000000261615010704253017340 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef VERIFY_ACL_H #define VERIFY_ACL_H #include // Valid generic permissions #define CF_VALID_GPERMS "rwx" // Native perms separators in mode #define CF_NATIVE_PERMS_SEP_START '(' #define CF_NATIVE_PERMS_SEP_END ')' #define CF_VALID_NPERMS_POSIX "rwx" #define CF_VALID_NPERMS_NTFS "drtxTwabBpcoD" PromiseResult VerifyACL(EvalContext *ctx, const char *file, const Attributes *attr, const Promise *pp); #endif cfengine-3.24.2/cf-agent/verify_new_packages.c0000644000000000000000000001555415010704253021230 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include /* PromiseRef */ static bool NewPackagePromiseSanityCheck(const Attributes *a) { assert(a != NULL); if (!a->new_packages.module_body || !a->new_packages.module_body->name) { Log(LOG_LEVEL_ERR, "Can not find package module body in policy."); return false; } if (a->new_packages.module_body->updates_ifelapsed == CF_NOINT || a->new_packages.module_body->installed_ifelapsed == CF_NOINT) { Log(LOG_LEVEL_ERR, "Invalid or missing arguments in package_module body '%s': " "query_installed_ifelapsed = %d query_updates_ifelapsed = %d", a->new_packages.module_body->name, a->new_packages.module_body->installed_ifelapsed, a->new_packages.module_body->updates_ifelapsed); return false; return false; } if (a->new_packages.package_policy == NEW_PACKAGE_ACTION_NONE) { Log(LOG_LEVEL_ERR, "Unsupported package policy in package promise."); return false; } return true; } PromiseResult HandleNewPackagePromiseType(EvalContext *ctx, const Promise *pp, const Attributes *a) { assert(a != NULL); Log(LOG_LEVEL_DEBUG, "New package promise handler"); if (!NewPackagePromiseSanityCheck(a)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "New package promise failed sanity check."); return PROMISE_RESULT_FAIL; } PromiseBanner(ctx, pp); PackagePromiseGlobalLock global_lock = AcquireGlobalPackagePromiseLock(ctx); CfLock package_promise_lock; char promise_lock[CF_BUFSIZE]; snprintf(promise_lock, sizeof(promise_lock), "new-package-%s-%s", pp->promiser, a->new_packages.module_body->name); if (global_lock.g_lock.lock == NULL) { Log(LOG_LEVEL_DEBUG, "Skipping promise execution due to global packaging locking."); return PROMISE_RESULT_SKIPPED; } package_promise_lock = AcquireLock(ctx, promise_lock, VUQNAME, CFSTARTTIME, a->transaction.ifelapsed, a->transaction.expireafter, pp, false); if (package_promise_lock.lock == NULL) { YieldGlobalPackagePromiseLock(global_lock); Log(LOG_LEVEL_DEBUG, "Skipping promise execution due to promise-specific package locking."); return PROMISE_RESULT_SKIPPED; } PackageModuleWrapper *package_module = NewPackageModuleWrapper(a->new_packages.module_body); if (package_module == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Some error occurred while contacting package module for promise '%s'", pp->promiser); YieldCurrentLock(package_promise_lock); YieldGlobalPackagePromiseLock(global_lock); return PROMISE_RESULT_FAIL; } PromiseResult result = PROMISE_RESULT_FAIL; switch (a->new_packages.package_policy) { case NEW_PACKAGE_ACTION_ABSENT: result = HandleAbsentPromiseAction(ctx, pp, a, package_module); switch (result) { case PROMISE_RESULT_FAIL: cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Error removing package '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Successfully removed package '%s'", pp->promiser); break; case PROMISE_RESULT_NOOP: /* Properly logged in HandleAbsentPromiseAction() */ cfPS(ctx, LOG_LEVEL_NOTHING, PROMISE_RESULT_NOOP, pp, a, NULL); break; case PROMISE_RESULT_WARN: /* Properly logged in HandleAbsentPromiseAction() */ cfPS(ctx, LOG_LEVEL_NOTHING, PROMISE_RESULT_WARN, pp, a, NULL); break; default: ProgrammingError("Absent promise action evaluation returned" " unsupported result: %d", result); break; } break; case NEW_PACKAGE_ACTION_PRESENT: result = HandlePresentPromiseAction(ctx, pp, a, package_module); switch (result) { case PROMISE_RESULT_FAIL: cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Error installing package '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Successfully installed package '%s'", pp->promiser); break; case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Package '%s' already installed", pp->promiser); break; case PROMISE_RESULT_WARN: /* Properly logged in HandlePresentPromiseAction() */ cfPS(ctx, LOG_LEVEL_NOTHING, PROMISE_RESULT_WARN, pp, a, NULL); break; default: ProgrammingError("Present promise action evaluation returned" " unsupported result: %d", result); break; } break; case NEW_PACKAGE_ACTION_NONE: default: ProgrammingError("Unsupported package action: %d", a->new_packages.package_policy); break; } DeletePackageModuleWrapper(package_module); YieldCurrentLock(package_promise_lock); YieldGlobalPackagePromiseLock(global_lock); return result; } cfengine-3.24.2/cf-agent/simulate_mode.c0000644000000000000000000010457415010704253020045 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include /* ToChangesChroot() */ #include /* IsAbsoluteFileName() */ #include /* DirOpen(),...*/ #include /* StringEqual() */ #include /* ReadLenPrefixedString() */ #include /* CHROOT_CHANGES_LIST_FILE */ #include /* GetBinDir() */ #include /* JoinPaths() */ #include /* cf_popen(), cf_pclose() */ #include /* StringSet */ #include /* StringMap */ #include /* GetCsvLineNext() */ #include /* GetGroupName(), GetUserName() */ #include #define DELIM_CHAR '=' /* Taken from coreutils/lib/stat-macros.h. */ #define CHMOD_MODE_BITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) static inline void PrintDelimiter() { char *columns = getenv("COLUMNS"); int n_columns = 0; if (columns != NULL) { n_columns = atoi(columns); } n_columns = MAX(n_columns, 80) - 5; for (int i = n_columns; i > 0; i--) { putchar(DELIM_CHAR); } putchar('\n'); } #ifndef __MINGW32__ static void ManifestStatInfo(const struct stat *st) { assert(st != NULL); /* Inspired by the output from the 'stat' command */ char mode_str[10] = { st->st_mode & S_IRUSR ? 'r' : '-', st->st_mode & S_IWUSR ? 'w' : '-', (st->st_mode & S_ISUID ? (st->st_mode & S_IXUSR ? 's' : 'S') : (st->st_mode & S_IXUSR ? 'x' : '-')), st->st_mode & S_IRGRP ? 'r' : '-', st->st_mode & S_IWGRP ? 'w' : '-', (st->st_mode & S_ISGID ? (st->st_mode & S_IXGRP ? 's' : 'S') : (st->st_mode & S_IXGRP ? 'x' : '-')), st->st_mode & S_IROTH ? 'r' : '-', st->st_mode & S_IWOTH ? 'w' : '-', (st->st_mode & S_ISVTX ? (st->st_mode & S_IXOTH ? 't' : 'T') : (st->st_mode & S_IXOTH ? 'x' : '-')), '\0' }; printf("Size: %ju\n", (uintmax_t) st->st_size); printf("Access: (%04o/%s) ", st->st_mode & CHMOD_MODE_BITS, mode_str); char name[CF_SMALLBUF]; if (GetUserName(st->st_uid, name, sizeof(name), LOG_LEVEL_ERR)) { printf("Uid: (%ju/%s) ", (uintmax_t) st->st_uid, name); } if (GetGroupName(st->st_gid, name, sizeof(name), LOG_LEVEL_ERR)) { printf("Gid: (%ju/%s)\n", (uintmax_t) st->st_gid, name); } #define MAX_TIMESTAMP_SIZE (sizeof("2020-10-05 12:56:18 +0200")) char buf[MAX_TIMESTAMP_SIZE] = {0}; NDEBUG_UNUSED size_t ret = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime((time_t*) &(st->st_atime))); assert((ret > 0) && (ret < MAX_TIMESTAMP_SIZE)); printf("Access: %s\n", buf); ret = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime((time_t*) &(st->st_mtime))); assert((ret > 0) && (ret < MAX_TIMESTAMP_SIZE)); printf("Modify: %s\n", buf); ret = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime((time_t*) &(st->st_ctime))); assert((ret > 0) && (ret < MAX_TIMESTAMP_SIZE)); printf("Change: %s\n", buf); } #else /* !__MINGW32__ */ static void ManifestStatInfo(const struct stat *st) { assert(st != NULL); /* Inspired by the output from the 'stat' command */ char mode_str[10] = { st->st_mode & S_IRUSR ? 'r' : '-', st->st_mode & S_IWUSR ? 'w' : '-', st->st_mode & S_IXUSR ? 'x' : '-', st->st_mode & S_IRGRP ? 'r' : '-', st->st_mode & S_IWGRP ? 'w' : '-', st->st_mode & S_IXGRP ? 'x' : '-', st->st_mode & S_IROTH ? 'r' : '-', st->st_mode & S_IWOTH ? 'w' : '-', st->st_mode & S_IXOTH ? 'x' : '-', '\0' }; printf("Size: %ju\n", (uintmax_t) st->st_size); printf("Access: (%04o/%s) ", st->st_mode, mode_str); printf("Uid: %ju ", (uintmax_t)st->st_uid); printf("Gid: %ju\n", (uintmax_t)st->st_gid); #define MAX_TIMESTAMP_SIZE (sizeof("2020-10-05 12:56:18 +0200")) char buf[MAX_TIMESTAMP_SIZE] = {0}; size_t ret = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime((time_t*) &(st->st_atime))); assert((ret > 0) && (ret < MAX_TIMESTAMP_SIZE)); printf("Access: %s\n", buf); ret = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime((time_t*) &(st->st_mtime))); assert((ret > 0) && (ret < MAX_TIMESTAMP_SIZE)); printf("Modify: %s\n", buf); ret = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", localtime((time_t*) &(st->st_ctime))); assert((ret > 0) && (ret < MAX_TIMESTAMP_SIZE)); printf("Change: %s\n", buf); } #endif /* !__MINGW32__ */ #ifndef __MINGW32__ static inline void ManifestLinkTarget(const char *link_path, bool chrooted) { char target[PATH_MAX] = {0}; if (readlink(link_path, target, sizeof(target)) > 0) { const char *real_target = target; if (chrooted && IsAbsoluteFileName(target)) { real_target = ToNormalRoot(target); } printf("Target: '%s'\n", real_target); } else { printf("Invalid target\n"); } } #endif /* !__MINGW32__ */ static inline void ManifestFileContents(const char *path) { FILE *f = fopen(path, "r"); if (f != NULL) { puts("Contents of the file:"); } else { Log(LOG_LEVEL_ERR, "Failed to open file for reading: %s", GetErrorStr()); return; } bool binary = false; char last_char = '\n'; char buf[CF_BUFSIZE]; size_t n_read; bool done = false; while (!done && ((n_read = fread(buf, 1, sizeof(buf), f)) > 0)) { bool is_ascii = true; for (size_t i = 0; is_ascii && (i < n_read); i++) { is_ascii = isascii(buf[i]); } last_char = buf[n_read - 1]; if (is_ascii) { size_t offset = 0; size_t to_write = n_read; while (to_write > 0) { size_t n_written = fwrite(buf + offset, 1, to_write, stdout); if (n_written > 0) { to_write -= n_written; offset += n_written; } else { Log(LOG_LEVEL_ERR, "Failed to print contents of the file"); break; } } } else { puts("File contains non-ASCII data"); binary = true; done = true; } } if (!binary && (last_char != '\n')) { puts("\n\\no newline at the end of file"); } if (!done && !feof(f)) { Log(LOG_LEVEL_ERR, "Failed to print contents of the file"); } fclose(f); } static inline void ManifestDirectoryListing(const char *path) { Dir *dir = DirOpen(path); if (dir == NULL) { Log(LOG_LEVEL_ERR, "Failed to open the directory: %s", GetErrorStr()); return; } else { puts("Directory contents:"); } for (const struct dirent *dir_p = DirRead(dir); dir_p != NULL; dir_p = DirRead(dir)) { if (StringEqual(dir_p->d_name, ".") || StringEqual(dir_p->d_name, "..")) { continue; } else { puts(dir_p->d_name); } } DirClose(dir); } static inline const char *GetFileTypeDescription(mode_t st_mode) { switch (st_mode & S_IFMT) { case S_IFBLK: return "block device"; case S_IFCHR: return "character device"; case S_IFDIR: return "directory"; case S_IFIFO: return "FIFO/pipe"; #ifndef __MINGW32__ case S_IFLNK: return "symbolic link"; #endif case S_IFREG: return "regular file"; case S_IFSOCK: return "socket"; default: debug_abort_if_reached(); return "unknown"; } } static inline void ManifestFileDetails(const char *path, struct stat *st, bool chrooted) { assert(st != NULL); switch (st->st_mode & S_IFMT) { case S_IFREG: puts(""); /* blank line */ ManifestFileContents(path); break; #ifndef __MINGW32__ case S_IFLNK: puts(""); /* blank line */ ManifestLinkTarget(path, chrooted); break; #endif case S_IFDIR: puts(""); /* blank line */ ManifestDirectoryListing(path); break; default: /* nothing to do for other types */ break; } } bool ManifestFile(const char *path, bool chrooted) { PrintDelimiter(); const char *real_path = path; if (chrooted) { real_path = ToChangesChroot(path); } /* TODO: handle renames */ struct stat st; if (lstat(real_path, &st) == -1) { printf("'%s' no longer exists\n", path); return true; } printf("'%s' is a %s\n", path, GetFileTypeDescription(st.st_mode)); ManifestStatInfo(&st); ManifestFileDetails(real_path, &st, chrooted); return true; } bool ManifestRename(const char *orig_name, const char *new_name) { PrintDelimiter(); printf("'%s' is the new name of '%s'\n", new_name, orig_name); return true; } static bool RunDiff(const char *path1, const char *path2) { char diff_path[PATH_MAX]; strncpy(diff_path, GetBinDir(), sizeof(diff_path) - 1); JoinPaths(diff_path, sizeof(diff_path), "diff"); /* We use the '--label' option to override the paths in the output, for example: * --- original /etc/motd.d/cfengine * +++ changed /etc/motd.d/cfengine * @@ -1,1 +1,1 @@ * -One line * +New line */ char *command; int ret = xasprintf(&command, "%s -u --label 'original %s' --label 'changed %s' '%s' '%s'", diff_path, path1, path1, path1, path2); assert(ret != -1); /* should never happen */ FILE *f = cf_popen(command, "r", true); char buf[CF_BUFSIZE]; size_t n_read; bool failure = false; while (!failure && ((n_read = fread(buf, 1, sizeof(buf), f)) > 0)) { size_t offset = 0; size_t to_write = n_read; while (to_write > 0) { size_t n_written = fwrite(buf + offset, 1, to_write, stdout); if (n_written > 0) { to_write -= n_written; offset += n_written; } else { Log(LOG_LEVEL_ERR, "Failed to print results from 'diff' for '%s' and '%s'", path1, path2); failure = true; break; } } } if (!feof(f)) { Log(LOG_LEVEL_ERR, "Failed to read output from the 'diff' utility"); cf_pclose(f); free(command); return false; } ret = cf_pclose(f); free(command); if (ret == 2) { Log(LOG_LEVEL_ERR, "'diff -u %s %s' failed", path1, path2); return false; } return !failure; } static bool DiffFile(const char *path) { const char *chrooted_path = ToChangesChroot(path); struct stat st_orig; struct stat st_chrooted; if (lstat(path, &st_orig) == -1) { /* Original final doesn't exist, must be a new file in the changes * chroot, let's just manifest it instead of running 'diff' on it. */ ManifestFile(path, true); return true; } PrintDelimiter(); if (lstat(chrooted_path, &st_chrooted) == -1) { /* TODO: should this do print info about the original file? */ printf("'%s' no longer exists\n", path); return true; } if ((st_orig.st_mode & S_IFMT) != (st_chrooted.st_mode & S_IFMT)) { /* File type changed. */ printf("'%s' changed type from %s to %s\n", path, GetFileTypeDescription(st_orig.st_mode), GetFileTypeDescription(st_chrooted.st_mode)); ManifestStatInfo(&st_chrooted); ManifestFileDetails(path, &st_chrooted, true); return true; } else { switch (st_chrooted.st_mode & S_IFMT) { case S_IFREG: case S_IFDIR: return RunDiff(path, chrooted_path); default: printf("'%s' is a %s\n", path, GetFileTypeDescription(st_chrooted.st_mode)); ManifestStatInfo(&st_chrooted); ManifestFileDetails(path, &st_chrooted, true); return true; } } } bool ManifestRenamedFiles() { bool success = true; const char *renamed_files_file = ToChangesChroot(CHROOT_RENAMES_LIST_FILE); if (access(renamed_files_file, F_OK) == 0) { int fd = safe_open(renamed_files_file, O_RDONLY); if (fd == -1) { Log(LOG_LEVEL_ERR, "Failed to open the file with list of renamed files: %s", GetErrorStr()); success = false; } Log(LOG_LEVEL_INFO, "Manifesting renamed files (in the changes chroot)"); bool done = false; while (!done) { /* The CHROOT_RENAMES_LIST_FILE contains lines where two consecutive * lines represent the original and the new name of a file (see * RecordFileRenamedInChroot(). */ /* TODO: read into a PATH_MAX buffers */ char *orig_name; int ret = ReadLenPrefixedString(fd, &orig_name); if (ret > 0) { char *new_name; ret = ReadLenPrefixedString(fd, &new_name); if (ret > 0) { success = (success && ManifestRename(orig_name, new_name)); free(new_name); } else { /* If there was the line with the original name, there * must be a line with the new name. */ Log(LOG_LEVEL_ERR, "Invalid data about renamed files"); success = false; done = true; } free(orig_name); } else if (ret == 0) { /* EOF */ done = true; } else { Log(LOG_LEVEL_ERR, "Failed to read the list of changed files"); success = false; done = true; } } close(fd); } return success; } bool AuditChangedFiles(EvalMode mode, StringSet **audited_files) { assert((mode == EVAL_MODE_SIMULATE_MANIFEST) || (mode == EVAL_MODE_SIMULATE_MANIFEST_FULL) || (mode == EVAL_MODE_SIMULATE_DIFF)); bool success = true; /* Renames are part of the EVAL_MODE_SIMULATE_MANIFEST audit output which * shows changes. */ if (mode != EVAL_MODE_SIMULATE_MANIFEST_FULL) { success = ManifestRenamedFiles(); } const char *action; const char *action_ing; const char *file_category; const char *files_list_file; if (mode == EVAL_MODE_SIMULATE_MANIFEST) { action = "manifest"; action_ing = "Manifesting"; file_category = "changed"; files_list_file = ToChangesChroot(CHROOT_CHANGES_LIST_FILE); } else if (mode == EVAL_MODE_SIMULATE_MANIFEST_FULL) { action = "manifest"; action_ing = "Manifesting"; file_category = "unmodified"; files_list_file = ToChangesChroot(CHROOT_KEPT_LIST_FILE); } else { action = "show diff for"; action_ing = "Showing diff for"; file_category = "changed"; files_list_file = ToChangesChroot(CHROOT_CHANGES_LIST_FILE); } /* If the file doesn't exist, there were no changes recorded. */ if (access(files_list_file, F_OK) != 0) { Log(LOG_LEVEL_INFO, "No %s files to %s", file_category, action); return true; } int fd = safe_open(files_list_file, O_RDONLY); if (fd == -1) { Log(LOG_LEVEL_ERR, "Failed to open the file with list of %s files: %s", file_category, GetErrorStr()); return false; } Log(LOG_LEVEL_INFO, "%s %s files (in the changes chroot)", action_ing, file_category); if (*audited_files == NULL) { *audited_files = StringSetNew(); } bool done = false; while (!done) { /* TODO: read into a PATH_MAX buffer */ char *path; int ret = ReadLenPrefixedString(fd, &path); if (ret > 0) { /* Each file should only be audited once. */ if (!StringSetContains(*audited_files, path)) { if ((mode == EVAL_MODE_SIMULATE_MANIFEST) || (mode == EVAL_MODE_SIMULATE_MANIFEST_FULL)) { success = (success && ManifestFile(path, true)); } else { success = (success && DiffFile(path)); } StringSetAdd(*audited_files, path); } else { free(path); } } else if (ret == 0) { /* EOF */ done = true; } else { Log(LOG_LEVEL_ERR, "Failed to read the list of %s files", file_category); success = false; done = true; } } close(fd); return success; } bool ManifestChangedFiles(StringSet **audited_files) { return AuditChangedFiles(EVAL_MODE_SIMULATE_MANIFEST, audited_files); } bool ManifestAllFiles(StringSet **audited_files) { return AuditChangedFiles(EVAL_MODE_SIMULATE_MANIFEST_FULL, audited_files); } bool DiffChangedFiles(StringSet **audited_files) { return AuditChangedFiles(EVAL_MODE_SIMULATE_DIFF, audited_files); } typedef struct PkgOperationRecord_ { char *msg; char *pkg_ver; } PkgOperationRecord; static PkgOperationRecord *PkgOperationRecordNew(char *msg, char *pkg_ver) { PkgOperationRecord *ret = xmalloc(sizeof(PkgOperationRecord)); ret->msg = msg; ret->pkg_ver = pkg_ver; return ret; } static void PkgOperationRecordDestroy(PkgOperationRecord *pkg_op) { if (pkg_op != NULL) { free(pkg_op->msg); free(pkg_op->pkg_ver); free(pkg_op); } } static inline bool PkgVersionIsGreater(const char *ver1, const char *ver2) { /* Empty/missing versions should be handled separately based on the * operations they appear in */ assert(!NULL_OR_EMPTY(ver1) && !NULL_OR_EMPTY(ver2)); /* "latest" is greater than any version */ if (StringEqual(ver1, "latest")) { return true; } /* TODO: do real version comparison */ return (StringSafeCompare(ver1, ver2) == 1); } static inline char *GetPkgOperationMsg(ChrootPkgOperationCode op, const char *pkg_name, const char *pkg_arch, const char *pkg_ver) { const char *op_str = ""; switch (op) { case CHROOT_PKG_OPERATION_CODE_INSTALL: op_str = "installed"; break; case CHROOT_PKG_OPERATION_CODE_REMOVE: op_str = "removed"; break; case CHROOT_PKG_OPERATION_CODE_PRESENT: op_str = "present"; break; case CHROOT_PKG_OPERATION_CODE_ABSENT: op_str = "absent"; break; default: debug_abort_if_reached(); } char *msg; if (!NULL_OR_EMPTY(pkg_arch) && !NULL_OR_EMPTY(pkg_ver)) { xasprintf(&msg, "Package '%s-%s [%s]' would be %s\n", pkg_name, pkg_arch, pkg_ver, op_str); } else if (!NULL_OR_EMPTY(pkg_arch)) { xasprintf(&msg, "Package '%s-%s' would be %s\n", pkg_name, pkg_arch, op_str); } else if (!NULL_OR_EMPTY(pkg_ver)) { xasprintf(&msg, "Package '%s [%s]' would be %s\n", pkg_name, pkg_ver, op_str); } else { xasprintf(&msg, "Package '%s' would be %s\n", pkg_name, op_str); } return msg; } bool DiffPkgOperations() { const char *pkgs_ops_csv_file = ToChangesChroot(CHROOT_PKGS_OPS_FILE); if (access(pkgs_ops_csv_file, F_OK) != 0) { Log(LOG_LEVEL_INFO, "No package operations done by the agent run"); return true; } FILE *csv_file = safe_fopen(pkgs_ops_csv_file, "r"); if (csv_file == NULL) { Log(LOG_LEVEL_ERR, "Failed to open the file with package operations records"); return false; } Map *installed = MapNew(StringHash_untyped, StringEqual_untyped, free, (MapDestroyDataFn) PkgOperationRecordDestroy); Map *removed = MapNew(StringHash_untyped, StringEqual_untyped, free, (MapDestroyDataFn) PkgOperationRecordDestroy); char *line; while ((line = GetCsvLineNext(csv_file)) != NULL) { Seq *fields = SeqParseCsvString(line); if ((fields == NULL) || (SeqLength(fields) != 4)) { Log(LOG_LEVEL_ERR, "Invalid package operation record: '%s'", line); free(line); SeqDestroy(fields); continue; } free(line); /* See RecordPkgOperationInChroot() */ const char *op = SeqAt(fields, 0); const char *pkg_name = SeqAt(fields, 1); const char *pkg_ver = SeqAt(fields, 2); const char *pkg_arch = SeqAt(fields, 3); /* These two must always be set properly. */ assert(!NULL_OR_EMPTY(op)); assert(!NULL_OR_EMPTY(pkg_name)); /* We need to have a key for the map encoding package name and * architecture. Let's use the sequence "-_-" as a separator to avoid * collisions with possible weird package names. */ char *name_arch; xasprintf(&name_arch, "%s-_-%s", pkg_name, pkg_arch ? pkg_arch : ""); if (*op == CHROOT_PKG_OPERATION_CODE_PRESENT) { /* 'present' operation means that the package was requested to be present and it already * was, so installation didn't happen. However, package operations are not properly * simulated, so the package may have been simulate-removed before and the 'present' * operation would in reality mean the package would be installed back. It's only * recorded as a 'present' operation because the removal doesn't happen in simulate mode * and so the package is still seen as present in the system (package cache). * * This means that a 'present' operation after 'remove' operation results in no * difference (the package would be installed back) so the potential message about the * removal should be removed. */ MapRemove(removed, name_arch); } else if (*op == CHROOT_PKG_OPERATION_CODE_ABSENT) { /* The same logic as above applies here for an originally absent package that is * installed and then reported as absent again. No diff to report, just remove the * message about the package installation. */ /* However, if a different specific version is reported as absent than the version that * would have been installed, this removal would not remove the installed package * (because of version mismatch). */ if (NULL_OR_EMPTY(pkg_ver)) { MapRemove(installed, name_arch); } else { PkgOperationRecord *record = MapGet(installed, name_arch); if ((record != NULL) && StringEqual(pkg_ver, record->pkg_ver)) { /* Matching version being removed -> cancel the installation */ MapRemove(installed, name_arch); } } } else if (*op == CHROOT_PKG_OPERATION_CODE_INSTALL) { /* Package would be installed if there is no previous 'install' operation record with a * higher version. * OR * Package would be removed and now it would be installed. However, if the 'install' * operation had the same version as what is already present in the system (remove in * simulation mode doesn't remove the package), it would be reported as 'present' * operation. So 'install' operation must mean a newer version than what's present would * be installed. */ PkgOperationRecord *prev_record = MapGet(installed, name_arch); if ((prev_record == NULL) || PkgVersionIsGreater(pkg_ver, prev_record->pkg_ver)) { char *msg = GetPkgOperationMsg(CHROOT_PKG_OPERATION_CODE_INSTALL, pkg_name, pkg_arch, pkg_ver); PkgOperationRecord *record = PkgOperationRecordNew(msg, SafeStringDuplicate(pkg_ver)); MapInsert(installed, name_arch, record); name_arch = NULL; /* name_arch is now owned by the map (as a key) */ } /* Package installation cancels a previous removal (if any). */ MapRemove(removed, name_arch); } else { assert(*op == CHROOT_PKG_OPERATION_CODE_REMOVE); /* The only option not covered above. */ /* If there is a previous 'remove' operation record with version specified, prefer that * message over a new message without version specification as the net result would be * the package being removed, in the version that was pressent. */ PkgOperationRecord *prev_record = MapGet(removed, name_arch); bool insert_new_msg = ((prev_record == NULL) || (NULL_OR_EMPTY(prev_record->pkg_ver))); /* If there is a previous 'install' operation and now there is a 'remove' operation it * means that the package was initially present, then updated by the 'install' operation * and now it is attempted to be removed. If the 'remove' operation specifies a version * then in case the versions match, the net result would be no change (install and * remove). If there is a mismatch between the versions, the installation would happen, * but the removal would fail. If no version is specified for the 'remove' operation. it * would remove the installed package. */ if (NULL_OR_EMPTY(pkg_ver)) { /* No version specified, remove the installation message (if any). */ MapRemove(installed, name_arch); } else { PkgOperationRecord *inst_record = MapGet(installed, name_arch); if ((inst_record != NULL) && (StringEqual(pkg_ver, inst_record->pkg_ver))) { MapRemove(installed, name_arch); } else { /* Keeping the install message, the removal would make no change. */ insert_new_msg = false; } } if (insert_new_msg) { char *msg = GetPkgOperationMsg(CHROOT_PKG_OPERATION_CODE_REMOVE, pkg_name, pkg_arch, pkg_ver); PkgOperationRecord *record = PkgOperationRecordNew(msg, SafeStringDuplicate(pkg_ver)); MapInsert(removed, name_arch, record); name_arch = NULL; /* name_arch is now owned by the map (as a key) */ } } SeqDestroy(fields); free(name_arch); } fclose(csv_file); if ((MapSize(installed) == 0) && (MapSize(removed) == 0)) { Log(LOG_LEVEL_INFO, "No differences in installed packages to report"); MapDestroy(installed); MapDestroy(removed); return true; } Log(LOG_LEVEL_INFO, "Showing differences in installed packages"); MapIterator i = MapIteratorInit(installed); MapKeyValue *item; while ((item = MapIteratorNext(&i))) { PkgOperationRecord *value = item->value; const char *msg = value->msg; puts(msg); } i = MapIteratorInit(removed); while ((item = MapIteratorNext(&i))) { PkgOperationRecord *value = item->value; const char *msg = value->msg; puts(msg); } MapDestroy(installed); MapDestroy(removed); return true; } bool ManifestPkgOperations() { const char *pkgs_ops_csv_file = ToChangesChroot(CHROOT_PKGS_OPS_FILE); if (access(pkgs_ops_csv_file, F_OK) != 0) { Log(LOG_LEVEL_INFO, "No package operations done by the agent run"); return true; } FILE *csv_file = safe_fopen(pkgs_ops_csv_file, "r"); if (csv_file == NULL) { Log(LOG_LEVEL_ERR, "Failed to open the file with package operations records"); return false; } Map *present = MapNew(StringHash_untyped, StringEqual_untyped, free, (MapDestroyDataFn) PkgOperationRecordDestroy); Map *absent = MapNew(StringHash_untyped, StringEqual_untyped, free, (MapDestroyDataFn) PkgOperationRecordDestroy); char *line; while ((line = GetCsvLineNext(csv_file)) != NULL) { Seq *fields = SeqParseCsvString(line); if ((fields == NULL) || (SeqLength(fields) != 4)) { Log(LOG_LEVEL_ERR, "Invalid package operation record: '%s'", line); free(line); SeqDestroy(fields); continue; } free(line); /* See RecordPkgOperationInChroot() */ const char *op = SeqAt(fields, 0); const char *pkg_name = SeqAt(fields, 1); const char *pkg_ver = SeqAt(fields, 2); const char *pkg_arch = SeqAt(fields, 3); /* These two must always be set properly. */ assert(!NULL_OR_EMPTY(op)); assert(!NULL_OR_EMPTY(pkg_name)); /* We need to have a key for the map encoding package name and * architecture. Let's use the sequence "-_-" as a separator to avoid * collisions with possible weird package names. */ char *name_arch; xasprintf(&name_arch, "%s-_-%s", pkg_name, pkg_arch ? pkg_arch : ""); if ((*op == CHROOT_PKG_OPERATION_CODE_INSTALL) || (*op == CHROOT_PKG_OPERATION_CODE_PRESENT)) { /* If there is a previous install/present operation, we want to choose the message with * the higher version or the message which has a specific version (if any). */ PkgOperationRecord *prev_record = MapGet(present, name_arch); if ((prev_record == NULL) || (NULL_OR_EMPTY(prev_record->pkg_ver) && !NULL_OR_EMPTY(pkg_ver)) || (!NULL_OR_EMPTY(pkg_ver) && !NULL_OR_EMPTY(prev_record->pkg_ver) && PkgVersionIsGreater(pkg_ver, prev_record->pkg_ver))) { char *msg = GetPkgOperationMsg(CHROOT_PKG_OPERATION_CODE_PRESENT, pkg_name, pkg_arch, pkg_ver); PkgOperationRecord *record = PkgOperationRecordNew(msg, SafeStringDuplicate(pkg_ver)); MapInsert(present, name_arch, record); name_arch = NULL; /* name_arch is now owned by the map (as a key) */ } /* Cancels any previous remove/absent message. */ MapRemove(absent, name_arch); } else { assert((*op == CHROOT_PKG_OPERATION_CODE_REMOVE) || (*op == CHROOT_PKG_OPERATION_CODE_ABSENT)); /* If there is a 'present' message with a different version than the version specified * here (if any), we know that the removal would fail and so it should not be * reported. */ PkgOperationRecord *present_record = MapGet(present, name_arch); if ((present_record == NULL) || NULL_OR_EMPTY(present_record->pkg_ver) || NULL_OR_EMPTY(pkg_ver) || StringEqual(present_record->pkg_ver, pkg_ver)) { /* Remove the 'present' message now that we know the removal would/should work. */ MapRemove(present, name_arch); /* If there is a previous 'absent' message, we want to use the message with no * version specification (if any) because it's more generic. */ PkgOperationRecord *prev_record = MapGet(absent, name_arch); if ((prev_record == NULL) || (!NULL_OR_EMPTY(prev_record->pkg_ver) && NULL_OR_EMPTY(pkg_ver))) { char *msg = GetPkgOperationMsg(CHROOT_PKG_OPERATION_CODE_ABSENT, pkg_name, pkg_arch, pkg_ver); PkgOperationRecord *record = PkgOperationRecordNew(msg, SafeStringDuplicate(pkg_ver)); MapInsert(absent, name_arch, record); name_arch = NULL; /* name_arch is now owned by the map (as a key) */ } } } SeqDestroy(fields); free(name_arch); } fclose(csv_file); /* If there were package operations (the file with the records exists, which is checked above), * there must be something to manifest. Otherwise, there's a flaw in the logic above, * manipulating the maps. */ assert((MapSize(present) != 0) || (MapSize(absent) != 0)); Log(LOG_LEVEL_INFO, "Manifesting present and absent packages"); MapIterator i = MapIteratorInit(present); MapKeyValue *item; while ((item = MapIteratorNext(&i))) { PkgOperationRecord *value = item->value; const char *msg = value->msg; puts(msg); } i = MapIteratorInit(absent); while ((item = MapIteratorNext(&i))) { PkgOperationRecord *value = item->value; const char *msg = value->msg; puts(msg); } MapDestroy(present); MapDestroy(absent); return true; } cfengine-3.24.2/cf-agent/files_editxml.h0000644000000000000000000000242515010704253020043 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_EDITXML_H #define CFENGINE_FILES_EDITXML_H bool ScheduleEditXmlOperations(EvalContext *ctx, const Bundle *bp, const Attributes *a, const Promise *parentp, EditContext *edcontext); #ifdef HAVE_LIBXML2 bool XmlCompareToFile(xmlDocPtr doc, char *file, EditDefaults edits); #endif #endif cfengine-3.24.2/cf-agent/acl_posix.h0000644000000000000000000000226615010704253017177 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ACL_POSIX_H #define CFENGINE_ACL_POSIX_H #include PromiseResult CheckPosixLinuxACL(EvalContext *ctx, const char *file_path, Acl acl, const Attributes *a, const Promise *pp); #endif cfengine-3.24.2/cf-agent/verify_exec.h0000644000000000000000000000220415010704253017516 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_EXEC_H #define CFENGINE_VERIFY_EXEC_H #include PromiseResult VerifyExecPromise(EvalContext *ctx, const Promise *pp); #endif cfengine-3.24.2/cf-agent/verify_databases.h0000644000000000000000000000222315010704253020522 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_DATABASES_H #define CFENGINE_VERIFY_DATABASES_H #include PromiseResult VerifyDatabasePromises(EvalContext *ctx, const Promise *pp); #endif cfengine-3.24.2/cf-agent/verify_files_hashes.c0000644000000000000000000000701715010704253021231 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include bool CompareFileHashes(const char *file1, const char *file2, const struct stat *sstat, const struct stat *dstat, const FileCopy *fc, AgentConnection *conn) { unsigned char digest1[EVP_MAX_MD_SIZE + 1] = { 0 }, digest2[EVP_MAX_MD_SIZE + 1] = { 0 }; int i; if (sstat->st_size != dstat->st_size) { Log(LOG_LEVEL_DEBUG, "File sizes differ, no need to compute checksum"); return true; } if (conn == NULL) { HashFile(file1, digest1, CF_DEFAULT_DIGEST, false); HashFile(file2, digest2, CF_DEFAULT_DIGEST, false); for (i = 0; i < EVP_MAX_MD_SIZE; i++) { if (digest1[i] != digest2[i]) { return true; } } Log(LOG_LEVEL_DEBUG, "Files were identical"); return false; /* only if files are identical */ } else { assert(fc->servers && strcmp(RlistScalarValue(fc->servers), "localhost")); return CompareHashNet(file1, file2, fc->encrypt, conn); /* client.c */ } } bool CompareBinaryFiles(const char *file1, const char *file2, const struct stat *sstat, const struct stat *dstat, const FileCopy *fc, AgentConnection *conn) { int fd1, fd2, bytes1, bytes2; char buff1[BUFSIZ], buff2[BUFSIZ]; if (sstat->st_size != dstat->st_size) { Log(LOG_LEVEL_DEBUG, "File sizes differ, no need to compute checksum"); return true; } if (conn == NULL) { fd1 = safe_open(file1, O_RDONLY | O_BINARY); fd2 = safe_open(file2, O_RDONLY | O_BINARY); do { bytes1 = read(fd1, buff1, BUFSIZ); bytes2 = read(fd2, buff2, BUFSIZ); if ((bytes1 != bytes2) || (memcmp(buff1, buff2, bytes1) != 0)) { Log(LOG_LEVEL_VERBOSE, "Binary Comparison mismatch..."); close(fd2); close(fd1); return true; } } while (bytes1 > 0); close(fd2); close(fd1); return false; /* only if files are identical */ } else { assert(fc->servers && strcmp(RlistScalarValue(fc->servers), "localhost")); Log(LOG_LEVEL_DEBUG, "Using network checksum instead"); return CompareHashNet(file1, file2, fc->encrypt, conn); /* client.c */ } } cfengine-3.24.2/cf-agent/promiser_regex_resolver.c0000644000000000000000000001745515010704253022172 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * This module provides functionality of resolving regular expressions in * promisers, such as in featured by files promise type and storage promise * type. */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* PathAppend */ PromiseResult LocateFilePromiserGroup(EvalContext *ctx, char *wildpath, const Promise *pp, PromiseResult (*fnptr) (EvalContext *ctx, char *path, const Promise *ptr)) { Item *path, *ip, *remainder = NULL; char pbuffer[CF_BUFSIZE]; struct stat statbuf; int count = 0, lastnode = false, expandregex = false; uid_t agentuid = getuid(); int create = PromiseGetConstraintAsBoolean(ctx, "create", pp); char *pathtype = PromiseGetConstraintAsRval(pp, "pathtype", RVAL_TYPE_SCALAR); /* Do a search for promiser objects matching wildpath */ if ((!IsPathRegex(wildpath)) || (pathtype && (strcmp(pathtype, "literal") == 0))) { Log(LOG_LEVEL_VERBOSE, "Using literal pathtype for '%s'", wildpath); return (*fnptr) (ctx, wildpath, pp); } else { Log(LOG_LEVEL_VERBOSE, "Using regex pathtype for '%s' (see pathtype)", wildpath); } pbuffer[0] = '\0'; path = SplitString(wildpath, '/'); // require forward slash in regex on all platforms PromiseResult result = PROMISE_RESULT_SKIPPED; for (ip = path; ip != NULL; ip = ip->next) { if ((ip->name == NULL) || (strlen(ip->name) == 0)) { continue; } if (ip->next == NULL) { lastnode = true; } /* No need to chdir as in recursive descent, since we know about the path here */ if (IsRegex(ip->name)) { remainder = ip->next; expandregex = true; break; } else { expandregex = false; } if (!PathAppend(pbuffer, sizeof(pbuffer), ip->name, FILE_SEPARATOR)) { Log(LOG_LEVEL_ERR, "Internal limit reached in LocateFilePromiserGroup()," " path too long: '%s' + '%s'", pbuffer, ip->name); Log(LOG_LEVEL_ERR, "Buffer has limited size in LocateFilePromiserGroup"); return result; } if (stat(pbuffer, &statbuf) != -1) { if ((S_ISDIR(statbuf.st_mode)) && ((statbuf.st_uid) != agentuid) && ((statbuf.st_uid) != 0)) { Log(LOG_LEVEL_INFO, "Directory '%s' in search path '%s' is controlled by another user (uid %ju) - trusting its content is potentially risky (possible race condition)", pbuffer, wildpath, (uintmax_t)statbuf.st_uid); PromiseRef(LOG_LEVEL_INFO, pp); } } } if (expandregex) /* Expand one regex link and hand down */ { char nextbuffer[CF_BUFSIZE], nextbufferOrig[CF_BUFSIZE], regex[CF_BUFSIZE]; const struct dirent *dirp; Dir *dirh; strlcpy(regex, ip->name, CF_BUFSIZE); if ((dirh = DirOpen(pbuffer)) == NULL) { // Could be a dummy directory to be created so this is not an error. Log(LOG_LEVEL_VERBOSE, "Using best-effort expanded (but non-existent) file base path '%s'", wildpath); result = PromiseResultUpdate(result, (*fnptr) (ctx, wildpath, pp)); DeleteItemList(path); return result; } else { count = 0; for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (!ConsiderLocalFile(dirp->d_name, pbuffer)) { continue; } if ((!lastnode) && (!S_ISDIR(statbuf.st_mode))) { Log(LOG_LEVEL_DEBUG, "Skipping non-directory '%s'", dirp->d_name); continue; } if (FullTextMatch(ctx, regex, dirp->d_name)) { Log(LOG_LEVEL_DEBUG, "Link '%s' matched regex '%s'", dirp->d_name, regex); } else { continue; } count++; strlcpy(nextbuffer, pbuffer, CF_BUFSIZE); AddSlash(nextbuffer); strcat(nextbuffer, dirp->d_name); for (ip = remainder; ip != NULL; ip = ip->next) { AddSlash(nextbuffer); strcat(nextbuffer, ip->name); } /* The next level might still contain regexs, so go again as long as expansion is not nullpotent */ if ((!lastnode) && (strcmp(nextbuffer, wildpath) != 0)) { result = PromiseResultUpdate(result, LocateFilePromiserGroup(ctx, nextbuffer, pp, fnptr)); } else { Promise *pcopy; Log(LOG_LEVEL_VERBOSE, "Using expanded file base path '%s'", nextbuffer); /* Now need to recompute any back references to get the complete path */ snprintf(nextbufferOrig, sizeof(nextbufferOrig), "%s", nextbuffer); MapNameForward(nextbuffer); if (!FullTextMatch(ctx, pp->promiser, nextbuffer)) { Log(LOG_LEVEL_DEBUG, "Error recomputing references for '%s' in '%s'", pp->promiser, nextbuffer); } /* If there were back references there could still be match.x vars to expand */ bool excluded = false; pcopy = ExpandDeRefPromise(ctx, pp, &excluded); if (excluded) { result = PromiseResultUpdate(result, PROMISE_RESULT_SKIPPED); } else { result = PromiseResultUpdate(result, (*fnptr) (ctx, nextbufferOrig, pcopy)); } PromiseDestroy(pcopy); } } DirClose(dirh); } } else { Log(LOG_LEVEL_VERBOSE, "Using file base path '%s'", pbuffer); result = PromiseResultUpdate(result, (*fnptr) (ctx, pbuffer, pp)); } if (count == 0) { Log(LOG_LEVEL_VERBOSE, "No promiser file objects matched as regular expression '%s'", wildpath); if (create) { result = PromiseResultUpdate(result, (*fnptr)(ctx, pp->promiser, pp)); } } DeleteItemList(path); return result; } cfengine-3.24.2/cf-agent/nfs.h0000644000000000000000000000313615010704253016001 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_NFS_H #define CFENGINE_NFS_H #include #include // Seq bool LoadMountInfo(Seq *list); void DeleteMountInfo(Seq *list); int VerifyNotInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp, PromiseResult *result); int VerifyInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp, PromiseResult *result); PromiseResult VerifyMount(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp); PromiseResult VerifyUnmount(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp); void CleanupNFS(void); void MountAll(void); #endif cfengine-3.24.2/cf-agent/agent-diagnostics.c0000644000000000000000000001736615010704253020623 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include AgentDiagnosticsResult AgentDiagnosticsResultNew(bool success, char *message) { return (AgentDiagnosticsResult) { success, message }; } static void AgentDiagnosticsResultDestroy(AgentDiagnosticsResult result) { free(result.message); } void AgentDiagnosticsRun(const char *workdir, const AgentDiagnosticCheck checks[], Writer *output) { { char diagnostics_path[CF_BUFSIZE] = { 0 }; snprintf(diagnostics_path, CF_BUFSIZE, "%s/diagnostics", workdir); MapName(diagnostics_path); struct stat sb; if (stat(diagnostics_path, &sb) != 0) { if (mkdir(diagnostics_path, DEFAULTMODE) != 0) { WriterWriteF(output, "Cannot create diagnostics output directory '%s'", diagnostics_path); return; } } } for (int i = 0; checks[i].description; i++) { AgentDiagnosticsResult result = checks[i].check(workdir); WriterWriteF(output, "[ %s ] %s: %s\n", result.success ? "YES" : "NO ", checks[i].description, result.message); AgentDiagnosticsResultDestroy(result); } } AgentDiagnosticsResult AgentDiagnosticsCheckIsBootstrapped(const char *workdir) { char *policy_server = PolicyServerReadFile(workdir); return AgentDiagnosticsResultNew(policy_server != NULL, policy_server != NULL ? policy_server : xstrdup("Not bootstrapped")); } AgentDiagnosticsResult AgentDiagnosticsCheckAmPolicyServer(ARG_UNUSED const char *workdir) { bool am_policy_server = GetAmPolicyHub(); return AgentDiagnosticsResultNew(am_policy_server, am_policy_server ? xstrdup("Acting as a policy server") : xstrdup("Not acting as a policy server")); } AgentDiagnosticsResult AgentDiagnosticsCheckPrivateKey(const char *workdir) { char *path = PrivateKeyFile(workdir); struct stat sb; AgentDiagnosticsResult res; if (stat(path, &sb) != 0) { res = AgentDiagnosticsResultNew(false, StringFormat("No private key found at '%s'", path)); } else if (sb.st_mode != (S_IFREG | S_IWUSR | S_IRUSR)) { res = AgentDiagnosticsResultNew(false, StringFormat("Private key found at '%s', but had incorrect permissions '%o'", path, sb.st_mode)); } else { res = AgentDiagnosticsResultNew(true, StringFormat("OK at '%s'", path)); } free(path); return res; } AgentDiagnosticsResult AgentDiagnosticsCheckPublicKey(const char *workdir) { char *path = PublicKeyFile(workdir); struct stat sb; AgentDiagnosticsResult res; if (stat(path, &sb) != 0) { res = AgentDiagnosticsResultNew(false, StringFormat("No public key found at '%s'", path)); } else if (sb.st_mode != (S_IFREG | S_IWUSR | S_IRUSR)) { res = AgentDiagnosticsResultNew(false, StringFormat("Public key found at '%s', but had incorrect permissions '%o'", path, sb.st_mode)); } else if (sb.st_size != 426) { res = AgentDiagnosticsResultNew(false, StringFormat("Public key at '%s' had size %lld bytes, expected 426 bytes", path, (long long)sb.st_size)); } else { res = AgentDiagnosticsResultNew(true, StringFormat("OK at '%s'", path)); } free(path); return res; } static AgentDiagnosticsResult AgentDiagnosticsCheckDB(ARG_UNUSED const char *workdir, dbid id) { char *dbpath = DBIdToPath(id); char *error = DBPrivDiagnose(dbpath); if (error) { free(dbpath); return AgentDiagnosticsResultNew(false, error); } else { int ret = CheckTokyoDBCoherence(dbpath); free(dbpath); if (ret) { return AgentDiagnosticsResultNew(false, xstrdup("Internal DB coherence problem")); } else { if (id == dbid_lastseen) { if (IsLastSeenCoherent() == false) { return AgentDiagnosticsResultNew(false, xstrdup("Lastseen DB data coherence problem")); } } return AgentDiagnosticsResultNew(true, xstrdup("OK")); } } } AgentDiagnosticsResult AgentDiagnosticsCheckDBPersistentClasses(const char *workdir) { return AgentDiagnosticsCheckDB(workdir, dbid_state); } AgentDiagnosticsResult AgentDiagnosticsCheckDBChecksums(const char *workdir) { return AgentDiagnosticsCheckDB(workdir, dbid_checksums); } AgentDiagnosticsResult AgentDiagnosticsCheckDBLastSeen(const char *workdir) { return AgentDiagnosticsCheckDB(workdir, dbid_lastseen); } AgentDiagnosticsResult AgentDiagnosticsCheckDBObservations(const char *workdir) { return AgentDiagnosticsCheckDB(workdir, dbid_observations); } AgentDiagnosticsResult AgentDiagnosticsCheckDBFileStats(const char *workdir) { return AgentDiagnosticsCheckDB(workdir, dbid_filestats); } AgentDiagnosticsResult AgentDiagnosticsCheckDBLocks(const char *workdir) { return AgentDiagnosticsCheckDB(workdir, dbid_locks); } AgentDiagnosticsResult AgentDiagnosticsCheckDBPerformance(const char *workdir) { return AgentDiagnosticsCheckDB(workdir, dbid_performance); } const AgentDiagnosticCheck *AgentDiagnosticsAllChecks(void) { static const AgentDiagnosticCheck checks[] = { { "Check that agent is bootstrapped", &AgentDiagnosticsCheckIsBootstrapped }, { "Check if agent is acting as a policy server", &AgentDiagnosticsCheckAmPolicyServer }, { "Check private key", &AgentDiagnosticsCheckPrivateKey }, { "Check public key", &AgentDiagnosticsCheckPublicKey }, { "Check persistent classes DB", &AgentDiagnosticsCheckDBPersistentClasses }, { "Check checksums DB", &AgentDiagnosticsCheckDBChecksums }, { "Check observations DB", &AgentDiagnosticsCheckDBObservations }, { "Check file stats DB", &AgentDiagnosticsCheckDBFileStats }, { "Check locks DB", &AgentDiagnosticsCheckDBLocks }, { "Check performance DB", &AgentDiagnosticsCheckDBPerformance }, { "Check lastseen DB", &AgentDiagnosticsCheckDBLastSeen }, { NULL, NULL } }; return checks; } ENTERPRISE_VOID_FUNC_4ARG_DEFINE_STUB(void, AgentDiagnosticsRunAllChecksNova, ARG_UNUSED const char *, workdir, ARG_UNUSED Writer *, output, ARG_UNUSED AgentDiagnosticsRunFunction, AgentDiagnosticsRunPtr, ARG_UNUSED AgentDiagnosticsResultNewFunction, AgentDiagnosticsResultNewPtr) { } cfengine-3.24.2/cf-agent/vercmp.c0000644000000000000000000001624015010704253016502 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include static VersionCmpResult InvertResult(VersionCmpResult result) { if (result == VERCMP_ERROR) { return VERCMP_ERROR; } else { return !result; } } static VersionCmpResult AndResults(VersionCmpResult lhs, VersionCmpResult rhs) { if ((lhs == VERCMP_ERROR) || (rhs == VERCMP_ERROR)) { return VERCMP_ERROR; } else { return ((VersionCmpResult) (lhs && rhs)); } } static VersionCmpResult RunCmpCommand(EvalContext *ctx, const char *command, const char *v1, const char *v2, const Attributes *a, const Promise *pp, PromiseResult *result) { Buffer *expanded_command = BufferNew(); { VarRef *ref_v1 = VarRefParseFromScope("v1", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_v1, v1, CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_v2 = VarRefParseFromScope("v2", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_v2, v2, CF_DATA_TYPE_STRING, "source=promise"); ExpandScalar(ctx, NULL, PACKAGES_CONTEXT, command, expanded_command); EvalContextVariableRemove(ctx, ref_v1); VarRefDestroy(ref_v1); EvalContextVariableRemove(ctx, ref_v2); VarRefDestroy(ref_v2); } FILE *pfp = a->packages.package_commands_useshell ? cf_popen_sh(BufferData(expanded_command), "w") : cf_popen(BufferData(expanded_command), "w", true); if (pfp == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Can not start package version comparison command '%s'. (cf_popen: %s)", BufferData(expanded_command), GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); BufferDestroy(expanded_command); return VERCMP_ERROR; } Log(LOG_LEVEL_VERBOSE, "Executing '%s'", BufferData(expanded_command)); int retcode = cf_pclose(pfp); Log(LOG_LEVEL_VERBOSE, "returned: %d", retcode); if (retcode == -1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Error during package version comparison command execution '%s'. (cf_pclose: %s)", BufferData(expanded_command), GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); BufferDestroy(expanded_command); return VERCMP_ERROR; } BufferDestroy(expanded_command); if (retcode == 0) { return VERCMP_MATCH; } else { return VERCMP_NO_MATCH; } } static VersionCmpResult CompareVersionsLess(EvalContext *ctx, const char *v1, const char *v2, const Attributes *a, const Promise *pp, PromiseResult *result) { if (a->packages.package_version_less_command) { return RunCmpCommand(ctx, a->packages.package_version_less_command, v1, v2, a, pp, result); } else { return ComparePackageVersionsInternal(v1, v2, PACKAGE_VERSION_COMPARATOR_LT); } } static VersionCmpResult CompareVersionsEqual(EvalContext *ctx, const char *v1, const char *v2, const Attributes *a, const Promise *pp, PromiseResult *result) { if (a->packages.package_version_equal_command) { return RunCmpCommand(ctx, a->packages.package_version_equal_command, v1, v2, a, pp, result); } else if (a->packages.package_version_less_command) { /* emulate v1 == v2 by !(v1 < v2) && !(v2 < v1) */ return AndResults(InvertResult(CompareVersionsLess(ctx, v1, v2, a, pp, result)), InvertResult(CompareVersionsLess(ctx, v2, v1, a, pp, result))); } else { /* Built-in fallback */ return ComparePackageVersionsInternal(v1, v2, PACKAGE_VERSION_COMPARATOR_EQ); } } VersionCmpResult CompareVersions(EvalContext *ctx, const char *v1, const char *v2, const Attributes *a, const Promise *pp, PromiseResult *result) { VersionCmpResult cmp_result; switch (a->packages.package_select) { case PACKAGE_VERSION_COMPARATOR_EQ: case PACKAGE_VERSION_COMPARATOR_NONE: cmp_result = CompareVersionsEqual(ctx, v1, v2, a, pp, result); break; case PACKAGE_VERSION_COMPARATOR_NEQ: cmp_result = InvertResult(CompareVersionsEqual(ctx, v1, v2, a, pp, result)); break; case PACKAGE_VERSION_COMPARATOR_LT: cmp_result = CompareVersionsLess(ctx, v1, v2, a, pp, result); break; case PACKAGE_VERSION_COMPARATOR_GT: cmp_result = CompareVersionsLess(ctx, v2, v1, a, pp, result); break; case PACKAGE_VERSION_COMPARATOR_GE: cmp_result = InvertResult(CompareVersionsLess(ctx, v1, v2, a, pp, result)); break; case PACKAGE_VERSION_COMPARATOR_LE: cmp_result = InvertResult(CompareVersionsLess(ctx, v2, v1, a, pp, result)); break; default: ProgrammingError("Unexpected comparison value: %d", a->packages.package_select); break; } const char *text_result; switch (cmp_result) { case VERCMP_NO_MATCH: text_result = "no"; break; case VERCMP_MATCH: text_result = "yes"; break; default: text_result = "Incompatible version format. Can't decide"; break; } Log(LOG_LEVEL_VERBOSE, "CompareVersions: Checked whether package version %s %s %s: %s", v1, PackageVersionComparatorToString(a->packages.package_select), v2, text_result); return cmp_result; } const char* PackageVersionComparatorToString(const PackageVersionComparator pvc) { switch (pvc) { case PACKAGE_VERSION_COMPARATOR_EQ: return "=="; case PACKAGE_VERSION_COMPARATOR_NONE: return "=="; case PACKAGE_VERSION_COMPARATOR_NEQ: return "!="; case PACKAGE_VERSION_COMPARATOR_LT: return "<"; case PACKAGE_VERSION_COMPARATOR_GT: return ">"; case PACKAGE_VERSION_COMPARATOR_GE: return ">="; case PACKAGE_VERSION_COMPARATOR_LE: return "<="; default: ProgrammingError("Unexpected PackageVersionComparator value: %d", pvc); } return NULL; } cfengine-3.24.2/cf-agent/verify_files.h0000644000000000000000000000253315010704253017701 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_FILES_H #define CFENGINE_VERIFY_FILES_H #include PromiseResult FindAndVerifyFilesPromises(EvalContext *ctx, const Promise *pp); PromiseResult ScheduleEditOperation(EvalContext *ctx, char *filename, bool file_exists, const Attributes *attr, const Promise *pp); #endif cfengine-3.24.2/cf-agent/verify_services.c0000644000000000000000000001551115010704253020415 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static bool ServicesSanityChecks(const Attributes *a, const Promise *pp); static void SetServiceDefaults(Attributes *a); static PromiseResult DoVerifyServices(EvalContext *ctx, const Attributes *attr, const Promise *pp); static PromiseResult VerifyServices(EvalContext *ctx, const Attributes *a, const Promise *pp); /*****************************************************************************/ PromiseResult VerifyServicesPromise(EvalContext *ctx, const Promise *pp) { Attributes a = GetServicesAttributes(ctx, pp); SetServiceDefaults(&a); if (ServicesSanityChecks(&a, pp)) { return VerifyServices(ctx, &a, pp); } else { return PROMISE_RESULT_NOOP; } } /*****************************************************************************/ static bool ServicesSanityChecks(const Attributes *a, const Promise *pp) { Rlist *dep; for (dep = a->service.service_depend; dep != NULL; dep = dep->next) { if (strcmp(pp->promiser, RlistScalarValue(dep)) == 0) { Log(LOG_LEVEL_ERR, "Service promiser '%s' has itself as dependency", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return false; } } if (a->service.service_type == NULL) { Log(LOG_LEVEL_ERR, "Service type for service '%s' is not known", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return false; } #ifdef __MINGW32__ if (strcmp(a->service.service_type, "windows") != 0) { Log(LOG_LEVEL_ERR, "Service type for promiser '%s' must be 'windows' on this system, but is '%s'", pp->promiser, a->service.service_type); PromiseRef(LOG_LEVEL_ERR, pp); return false; } #endif /* __MINGW32__ */ return true; } /*****************************************************************************/ static void SetServiceDefaults(Attributes *a) { if ((a->service.service_policy == NULL) || strcmp(a->service.service_policy, "") == 0) { Log(LOG_LEVEL_VERBOSE, "Attribute 'service_policy' was not set, defaulting to: 'start'"); a->service.service_policy = "start"; } if (a->service.service_autostart_policy == NULL) { a->service.service_autostart_policy = "none"; } if (a->service.service_depend_chain == NULL) { a->service.service_depend_chain = "ignore"; } // default service type to "windows" on windows platforms #ifdef __MINGW32__ if (a->service.service_type == NULL) { a->service.service_type = "windows"; } #else if (a->service.service_type == NULL) { a->service.service_type = "bundle"; } #endif /* __MINGW32__ */ } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static PromiseResult VerifyServices(EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(a != NULL); CfLock thislock; thislock = AcquireLock(ctx, pp->promiser, VUQNAME, CFSTARTTIME, a->transaction.ifelapsed, a->transaction.expireafter, pp, false); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } PromiseBanner(ctx, pp); PromiseResult result = PROMISE_RESULT_SKIPPED; if (strcmp(a->service.service_type, "windows") == 0) { #ifdef __MINGW32__ result = PromiseResultUpdate(result, VerifyWindowsService(ctx, a, pp)); #else Log(LOG_LEVEL_INFO, "Service type windows not supported on this platform."); #endif } else { result = PromiseResultUpdate(result, DoVerifyServices(ctx, a, pp)); } YieldCurrentLock(thislock); return result; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static FnCall *DefaultServiceBundleCall(const Promise *pp, const char *service_policy) { Rlist *args = NULL; FnCall *call = NULL; RlistAppend(&args, pp->promiser, RVAL_TYPE_SCALAR); RlistAppend(&args, service_policy, RVAL_TYPE_SCALAR); Rval name = DefaultBundleConstraint(pp, "service"); if (PolicyGetBundle(PolicyFromPromise(pp), PromiseGetBundle(pp)->ns, "agent", (char *)name.item)) { Log(LOG_LEVEL_VERBOSE, "Found service special bundle %s in ns %s\n", (char *)name.item, PromiseGetBundle(pp)->ns); call = FnCallNew(name.item, args); } else { call = FnCallNew("default:standard_services", args); } return call; } static PromiseResult DoVerifyServices(EvalContext *ctx, const Attributes *attr, const Promise *pp) { assert(attr != NULL); Attributes a = *attr; // TODO: Remove this local copy Rval call; { const Constraint *cp = PromiseGetConstraint(pp, "service_bundle"); if (cp) { call = RvalCopy(cp->rval); } else { call = (Rval) { DefaultServiceBundleCall(pp, a.service.service_policy), RVAL_TYPE_FNCALL }; } } a.havebundle = true; EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "service_policy", a.service.service_policy, CF_DATA_TYPE_STRING, "source=promise"); PromiseResult result = PROMISE_RESULT_NOOP; result = PromiseResultUpdate(result, VerifyMethod(ctx, call, &a, pp)); // Send list of classes to set privately? RvalDestroy(call); return result; } cfengine-3.24.2/cf-agent/vercmp_internal.h0000644000000000000000000000226315010704253020403 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERCMP_INTERNAL_H #define CFENGINE_VERCMP_INTERNAL_H #include VersionCmpResult ComparePackageVersionsInternal(const char *v1, const char *v2, PackageVersionComparator cmp); #endif cfengine-3.24.2/cf-agent/Makefile.in0000644000000000000000000012016715010704300017104 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @FREEBSD_TRUE@am__append_1 = -lutil @NT_FALSE@am__append_2 = nfs.c nfs.h @HAVE_USERS_PROMISE_DEPS_TRUE@@NT_FALSE@am__append_3 = verify_users_pam.c @HAVE_USERS_PROMISE_DEPS_FALSE@@NT_FALSE@am__append_4 = verify_users_stub.c @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@am__append_5 = \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ findhub.c findhub_priv.h findhub.h \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ load_avahi.c load_avahi.h TESTS = $(am__EXEEXT_1) @NT_FALSE@noinst_PROGRAMS = manifest_file$(EXEEXT) @NT_FALSE@am__append_6 = manifest_file @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-agent$(EXEEXT) subdir = cf-agent ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libcf_agent_la_DEPENDENCIES = ../libpromises/libpromises.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__libcf_agent_la_SOURCES_DIST = agent-diagnostics.c \ agent-diagnostics.h simulate_mode.c simulate_mode.h \ tokyo_check.c tokyo_check.h abstract_dir.c abstract_dir.h \ cf-agent.c cf-agent-enterprise-stubs.c \ cf-agent-enterprise-stubs.h comparray.c comparray.h \ acl_posix.c acl_posix.h cf_sql.c cf_sql.h files_changes.c \ files_changes.h promiser_regex_resolver.c \ promiser_regex_resolver.h retcode.c retcode.h verify_acl.c \ verify_acl.h verify_files.c verify_files.h \ verify_files_utils.c verify_files_utils.h \ verify_files_hashes.c verify_files_hashes.h verify_storage.c \ verify_storage.h verify_exec.c verify_exec.h verify_methods.c \ verify_methods.h verify_databases.c verify_databases.h \ verify_processes.c verify_processes.h verify_services.c \ verify_services.h verify_environments.c verify_environments.h \ files_edit.c files_edit.h files_editline.c files_editline.h \ files_editxml.c files_editxml.h files_properties.c \ files_properties.h files_select.c files_select.h \ vercmp_internal.c vercmp_internal.h vercmp.c vercmp.h \ package_module.c package_module.h verify_packages.c \ verify_packages.h verify_new_packages.c verify_new_packages.h \ verify_users.c verify_users.h cf-agent-windows-functions.h \ nfs.c nfs.h verify_users_pam.c verify_users_stub.c findhub.c \ findhub_priv.h findhub.h load_avahi.c load_avahi.h @NT_FALSE@am__objects_1 = nfs.lo @HAVE_USERS_PROMISE_DEPS_TRUE@@NT_FALSE@am__objects_2 = \ @HAVE_USERS_PROMISE_DEPS_TRUE@@NT_FALSE@ verify_users_pam.lo @HAVE_USERS_PROMISE_DEPS_FALSE@@NT_FALSE@am__objects_3 = \ @HAVE_USERS_PROMISE_DEPS_FALSE@@NT_FALSE@ verify_users_stub.lo @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@am__objects_4 = \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ findhub.lo \ @HAVE_AVAHI_CLIENT_TRUE@@HAVE_AVAHI_COMMON_TRUE@ load_avahi.lo am_libcf_agent_la_OBJECTS = agent-diagnostics.lo simulate_mode.lo \ tokyo_check.lo abstract_dir.lo cf-agent.lo \ cf-agent-enterprise-stubs.lo comparray.lo acl_posix.lo \ cf_sql.lo files_changes.lo promiser_regex_resolver.lo \ retcode.lo verify_acl.lo verify_files.lo verify_files_utils.lo \ verify_files_hashes.lo verify_storage.lo verify_exec.lo \ verify_methods.lo verify_databases.lo verify_processes.lo \ verify_services.lo verify_environments.lo files_edit.lo \ files_editline.lo files_editxml.lo files_properties.lo \ files_select.lo vercmp_internal.lo vercmp.lo package_module.lo \ verify_packages.lo verify_new_packages.lo verify_users.lo \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) libcf_agent_la_OBJECTS = $(am_libcf_agent_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) cf_agent_SOURCES = cf-agent.c cf_agent_OBJECTS = cf_agent-cf-agent.$(OBJEXT) @BUILTIN_EXTENSIONS_FALSE@cf_agent_DEPENDENCIES = libcf-agent.la cf_agent_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(cf_agent_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__manifest_file_SOURCES_DIST = manifest_file.c @NT_FALSE@am_manifest_file_OBJECTS = manifest_file.$(OBJEXT) manifest_file_OBJECTS = $(am_manifest_file_OBJECTS) @NT_FALSE@manifest_file_DEPENDENCIES = \ @NT_FALSE@ ../libntech/libutils/libutils.la \ @NT_FALSE@ ../libpromises/libpromises.la libcf-agent.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_agent_la_SOURCES) cf-agent.c \ $(manifest_file_SOURCES) DIST_SOURCES = $(am__libcf_agent_la_SOURCES_DIST) cf-agent.c \ $(am__manifest_file_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } @NT_FALSE@am__EXEEXT_1 = manifest_file$(EXEEXT) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-agent.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ -I$(srcdir)/../cf-check \ @CPPFLAGS@ \ $(ENTERPRISE_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(LIBVIRT_CPPFLAGS) \ $(POSTGRESQL_CPPFLAGS) \ $(MYSQL_CPPFLAGS) \ $(LIBXML2_CPPFLAGS) \ $(PAM_CPPFLAGS) AM_CFLAGS = \ @CFLAGS@ \ $(ENTERPRISE_CFLAGS) \ $(OPENSSL_CFLAGS) \ $(PCRE2_CFLAGS) \ $(LIBVIRT_CFLAGS) \ $(POSTGRESQL_CFLAGS) \ $(MYSQL_CFLAGS) \ $(LIBXML2_CFLAGS) \ $(PAM_CFLAGS) AM_LDFLAGS = @LDFLAGS@ $(OPENSSL_LDFLAGS) $(PCRE2_LDFLAGS) \ $(LIBVIRT_LDFLAGS) $(POSTGRESQL_LDFLAGS) $(MYSQL_LDFLAGS) \ $(LIBXML2_LDFLAGS) $(PAM_LDFLAGS) $(am__append_1) libcf_agent_la_LIBADD = ../libpromises/libpromises.la \ $(OPENSSL_LIBS) \ $(PCRE2_LIBS) \ $(LIBVIRT_LIBS) \ $(POSTGRESQL_LIBS) \ $(MYSQL_LIBS) \ $(LIBXML2_LIBS) \ $(PAM_LIBS) libcf_agent_la_SOURCES = agent-diagnostics.c agent-diagnostics.h \ simulate_mode.c simulate_mode.h tokyo_check.c tokyo_check.h \ abstract_dir.c abstract_dir.h cf-agent.c \ cf-agent-enterprise-stubs.c cf-agent-enterprise-stubs.h \ comparray.c comparray.h acl_posix.c acl_posix.h cf_sql.c \ cf_sql.h files_changes.c files_changes.h \ promiser_regex_resolver.c promiser_regex_resolver.h retcode.c \ retcode.h verify_acl.c verify_acl.h verify_files.c \ verify_files.h verify_files_utils.c verify_files_utils.h \ verify_files_hashes.c verify_files_hashes.h verify_storage.c \ verify_storage.h verify_exec.c verify_exec.h verify_methods.c \ verify_methods.h verify_databases.c verify_databases.h \ verify_processes.c verify_processes.h verify_services.c \ verify_services.h verify_environments.c verify_environments.h \ files_edit.c files_edit.h files_editline.c files_editline.h \ files_editxml.c files_editxml.h files_properties.c \ files_properties.h files_select.c files_select.h \ vercmp_internal.c vercmp_internal.h vercmp.c vercmp.h \ package_module.c package_module.h verify_packages.c \ verify_packages.h verify_new_packages.c verify_new_packages.h \ verify_users.c verify_users.h cf-agent-windows-functions.h \ $(am__append_2) $(am__append_3) $(am__append_4) \ $(am__append_5) @NT_FALSE@manifest_file_SOURCES = manifest_file.c @NT_FALSE@manifest_file_LDADD = ../libntech/libutils/libutils.la \ @NT_FALSE@ ../libpromises/libpromises.la \ @NT_FALSE@ libcf-agent.la # Workaround for automake madness (try removing it if you want to know why). @BUILTIN_EXTENSIONS_FALSE@cf_agent_CFLAGS = $(AM_CFLAGS) # Build both a libcf-agent.la library, and a cf-agent executable @BUILTIN_EXTENSIONS_FALSE@cf_agent_LDADD = libcf-agent.la CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-agent/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-agent/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-agent.la: $(libcf_agent_la_OBJECTS) $(libcf_agent_la_DEPENDENCIES) $(EXTRA_libcf_agent_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_agent_la_OBJECTS) $(libcf_agent_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-agent$(EXEEXT): $(cf_agent_OBJECTS) $(cf_agent_DEPENDENCIES) $(EXTRA_cf_agent_DEPENDENCIES) @rm -f cf-agent$(EXEEXT) $(AM_V_CCLD)$(cf_agent_LINK) $(cf_agent_OBJECTS) $(cf_agent_LDADD) $(LIBS) manifest_file$(EXEEXT): $(manifest_file_OBJECTS) $(manifest_file_DEPENDENCIES) $(EXTRA_manifest_file_DEPENDENCIES) @rm -f manifest_file$(EXEEXT) $(AM_V_CCLD)$(LINK) $(manifest_file_OBJECTS) $(manifest_file_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abstract_dir.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acl_posix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent-diagnostics.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-agent-enterprise-stubs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-agent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_agent-cf-agent.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf_sql.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comparray.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_changes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_edit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_editline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_editxml.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_properties.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_select.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findhub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load_avahi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manifest_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/package_module.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/promiser_regex_resolver.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/retcode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simulate_mode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tokyo_check.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vercmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vercmp_internal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_acl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_databases.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_environments.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_exec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_files.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_files_hashes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_files_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_methods.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_new_packages.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_packages.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_processes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_storage.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_users.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_users_pam.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verify_users_stub.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cf_agent-cf-agent.o: cf-agent.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_agent_CFLAGS) $(CFLAGS) -MT cf_agent-cf-agent.o -MD -MP -MF $(DEPDIR)/cf_agent-cf-agent.Tpo -c -o cf_agent-cf-agent.o `test -f 'cf-agent.c' || echo '$(srcdir)/'`cf-agent.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_agent-cf-agent.Tpo $(DEPDIR)/cf_agent-cf-agent.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-agent.c' object='cf_agent-cf-agent.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_agent_CFLAGS) $(CFLAGS) -c -o cf_agent-cf-agent.o `test -f 'cf-agent.c' || echo '$(srcdir)/'`cf-agent.c cf_agent-cf-agent.obj: cf-agent.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_agent_CFLAGS) $(CFLAGS) -MT cf_agent-cf-agent.obj -MD -MP -MF $(DEPDIR)/cf_agent-cf-agent.Tpo -c -o cf_agent-cf-agent.obj `if test -f 'cf-agent.c'; then $(CYGPATH_W) 'cf-agent.c'; else $(CYGPATH_W) '$(srcdir)/cf-agent.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cf_agent-cf-agent.Tpo $(DEPDIR)/cf_agent-cf-agent.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cf-agent.c' object='cf_agent-cf-agent.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cf_agent_CFLAGS) $(CFLAGS) -c -o cf_agent-cf-agent.obj `if test -f 'cf-agent.c'; then $(CYGPATH_W) 'cf-agent.c'; else $(CYGPATH_W) '$(srcdir)/cf-agent.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ col="$$grn"; \ else \ col="$$red"; \ fi; \ echo "$${col}$$dashes$${std}"; \ echo "$${col}$$banner$${std}"; \ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ test -z "$$report" || echo "$${col}$$report$${std}"; \ echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-agent/verify_packages.c0000644000000000000000000040634515010704253020361 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Called structure: Top-level: cf-agent calls... * CleanScheduledPackages * VerifyPackagesPromise -> all the Verify* functions that schedule operation * ExecuteScheduledPackages -> all the Execute* functions to run operations */ /** Entry points from VerifyPackagesPromise **/ #define REPORT_THIS_PROMISE(__pp) (strncmp(__pp->promiser, "cfe_internal_", 13) != 0) #define cfPS_HELPER_0ARG(__ctx, __log_level, __result, __pp, __a, __str) \ if (REPORT_THIS_PROMISE(__pp)) \ { \ cfPS(__ctx, __log_level, __result, __pp, __a, __str); \ } #define cfPS_HELPER_1ARG(__ctx, __log_level, __result, __pp, __a, __str, __arg1) \ if (REPORT_THIS_PROMISE(__pp)) \ { \ cfPS(__ctx, __log_level, __result, __pp, __a, __str, __arg1); \ } #define cfPS_HELPER_2ARG(__ctx, __log_level, __result, __pp, __a, __str, __arg1, __arg2) \ if (REPORT_THIS_PROMISE(__pp)) \ { \ cfPS(__ctx, __log_level, __result, __pp, __a, __str, __arg1, __arg2); \ } #define cfPS_HELPER_3ARG(__ctx, __log_level, __result, __pp, __a, __str, __arg1, __arg2, __arg3) \ if (REPORT_THIS_PROMISE(__pp)) \ { \ cfPS(__ctx, __log_level, __result, __pp, __a, __str, __arg1, __arg2, __arg3); \ } #define PromiseResultUpdate_HELPER(__pp, __prior, __evidence) \ REPORT_THIS_PROMISE(__pp) ? PromiseResultUpdate(__prior, __evidence) : __evidence typedef enum { PACKAGE_PROMISE_TYPE_OLD = 0, PACKAGE_PROMISE_TYPE_NEW, PACKAGE_PROMISE_TYPE_MIXED, PACKAGE_PROMISE_TYPE_OLD_ERROR, PACKAGE_PROMISE_TYPE_NEW_ERROR } PackagePromiseType; static bool PackageSanityCheck(EvalContext *ctx, const Attributes *a, const Promise *pp); static bool VerifyInstalledPackages(EvalContext *ctx, PackageManager **alllists, const char *default_arch, const Attributes *a, const Promise *pp, PromiseResult *result); static PromiseResult VerifyPromisedPackage(EvalContext *ctx, const Attributes *a, const Promise *pp); static PromiseResult VerifyPromisedPatch(EvalContext *ctx, const Attributes *a, const Promise *pp); /** Utils **/ static char *GetDefaultArch(const char *command); static bool ExecPackageCommand(EvalContext *ctx, char *command, int verify, int setCmdClasses, const Attributes *a, const Promise *pp, PromiseResult *result); static bool PrependPatchItem(EvalContext *ctx, PackageItem ** list, char *item, PackageItem * chklist, const char *default_arch, const Attributes *a, const Promise *pp); static bool PrependMultiLinePackageItem(EvalContext *ctx, PackageItem ** list, char *item, int reset, const char *default_arch, const Attributes *a, const Promise *pp); static bool PrependListPackageItem(EvalContext *ctx, PackageItem ** list, char *item, const char *default_arch, const Attributes *a, const Promise *pp); static PackageManager *GetPackageManager(PackageManager **lists, char *mgr, PackageAction pa, PackageActionPolicy x); static void DeletePackageManagers(PackageManager *morituri); static const char *PrefixLocalRepository(const Rlist *repositories, const char *package); static PromiseResult HandleOldPackagePromiseType(EvalContext *ctx, const Promise *pp, const Attributes *a); ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, ReportPatches, ARG_UNUSED PackageManager *, list) { Log(LOG_LEVEL_VERBOSE, "Patch reporting feature is only available in the enterprise version"); } /*****************************************************************************/ PackageManager *PACKAGE_SCHEDULE = NULL; /* GLOBAL_X */ PackageManager *INSTALLED_PACKAGE_LISTS = NULL; /* GLOBAL_X */ #define PACKAGE_LIST_COMMAND_WINAPI "/Windows_API" /*****************************************************************************/ #define PACKAGE_IGNORED_CFE_INTERNAL "cfe_internal_non_existing_package" /* Returns the old or new package promise type depending on promise constraints. */ static PackagePromiseType GetPackagePromiseVersion(const Packages *packages, const NewPackages *new_packages) { assert(packages != NULL); assert(new_packages != NULL); /* We have mixed packages promise constraints. */ if (!packages->is_empty && !new_packages->is_empty) { return PACKAGE_PROMISE_TYPE_MIXED; } else if (!new_packages->is_empty) /* new packages promise */ { if (new_packages->package_policy == NEW_PACKAGE_ACTION_NONE) { return PACKAGE_PROMISE_TYPE_NEW_ERROR; } return PACKAGE_PROMISE_TYPE_NEW; } else /* old packages promise */ { //TODO: if (!packages->has_package_method) { return PACKAGE_PROMISE_TYPE_OLD_ERROR; } return PACKAGE_PROMISE_TYPE_OLD; } } PromiseResult VerifyPackagesPromise(EvalContext *ctx, const Promise *pp) { assert(pp != NULL); // Dereferenced in cfPS macros PromiseResult result = PROMISE_RESULT_FAIL; Attributes a = GetPackageAttributes(ctx, pp); PackagePromiseType package_promise_type = GetPackagePromiseVersion(&a.packages, &a.new_packages); switch (package_promise_type) { case PACKAGE_PROMISE_TYPE_NEW: Log(LOG_LEVEL_VERBOSE, "Using v2 package promises (package_module)"); result = HandleNewPackagePromiseType(ctx, pp, &a); break; case PACKAGE_PROMISE_TYPE_OLD: Log(LOG_LEVEL_VERBOSE, "Using v1 package promises (package_method)"); result = HandleOldPackagePromiseType(ctx, pp, &a); /* Update v2 package promise cache in case we have mixed v2 and v1 * package promises in policy. */ if (result == PROMISE_RESULT_CHANGE || result == PROMISE_RESULT_FAIL) { UpdatePackagesCache(ctx, false); } break; case PACKAGE_PROMISE_TYPE_NEW_ERROR: cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "v2 package promise (package_method) failed sanity check."); break; case PACKAGE_PROMISE_TYPE_OLD_ERROR: cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "v1 package promise (package_method) failed sanity check."); break; case PACKAGE_PROMISE_TYPE_MIXED: cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Mixed v1 and v2 package promise attributes inside " "one package promise."); break; default: assert(0); //Shouldn't happen } return result; } /******************************************************************************/ /** @brief Executes single packages promise Called by cf-agent. * checks "name", "version", "arch", "firstrepo" variables from the "this" context * gets the package attributes into a * on Windows, if the package_list_command is not defined, use the hard-coded PACKAGE_LIST_COMMAND_WINAPI * do a package sanity check on the promise * print promise banner * reset to root directory (Yum bugfix) * get the default architecture from a.packages.package_default_arch_command into default_arch * call VerifyInstalledPackages with default_arch * if the package action is "patch", call VerifyPromisedPatch and return its result through PromiseResultUpdate_HELPER * for all other package actions, call VerifyPromisedPackage and return its result through PromiseResultUpdate_HELPER @param ctx [in] The evaluation context @param pp [in] the Promise for this operation @returns the promise result */ static PromiseResult HandleOldPackagePromiseType(EvalContext *ctx, const Promise *pp, const Attributes *attr) { assert(attr != NULL); assert(pp != NULL); Attributes a = *attr; // TODO: Remove this local copy, overwritten on windows CfLock thislock; char lockname[CF_BUFSIZE]; PromiseResult result = PROMISE_RESULT_NOOP; const char *reserved_vars[] = { "name", "version", "arch", "firstrepo", NULL }; for (int c = 0; reserved_vars[c]; c++) { const char *reserved = reserved_vars[c]; VarRef *var_ref = VarRefParseFromScope(reserved, "this"); if (EvalContextVariableGet(ctx, var_ref, NULL)) { Log(LOG_LEVEL_WARNING, "$(%s) variable has a special meaning in packages promises. " "Things may not work as expected if it is already defined.", reserved); } VarRefDestroy(var_ref); } #ifdef __MINGW32__ if(!a.packages.package_list_command) { a.packages.package_list_command = PACKAGE_LIST_COMMAND_WINAPI; } #endif if (!PackageSanityCheck(ctx, &a, pp)) { Log(LOG_LEVEL_VERBOSE, "Package promise %s failed sanity check", pp->promiser); result = PROMISE_RESULT_FAIL; goto end; } PromiseBanner(ctx, pp); // Now verify the package itself PackagePromiseGlobalLock package_lock = AcquireGlobalPackagePromiseLock(ctx); if (package_lock.g_lock.lock == NULL) { Log(LOG_LEVEL_VERBOSE, "Can not acquire global lock for package promise. Skipping promise " "evaluation"); result = PROMISE_RESULT_SKIPPED; goto end; } snprintf(lockname, CF_BUFSIZE - 1, "package-%s-%s", pp->promiser, a.packages.package_list_command); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, false); if (thislock.lock == NULL) { YieldGlobalPackagePromiseLock(package_lock); result = PROMISE_RESULT_SKIPPED; goto end; } // Start by reseting the root directory in case yum tries to glob regexs(!) if (safe_chdir("/") != 0) { Log(LOG_LEVEL_ERR, "Failed to chdir into '/'"); } char *default_arch = GetDefaultArch(a.packages.package_default_arch_command); if (default_arch == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Unable to obtain default architecture for package manager - aborting"); YieldCurrentLock(thislock); YieldGlobalPackagePromiseLock(package_lock); result = PROMISE_RESULT_FAIL; goto end; } Log(LOG_LEVEL_VERBOSE, "Default package architecture for promise %s is '%s'", pp->promiser, default_arch); if (!VerifyInstalledPackages(ctx, &INSTALLED_PACKAGE_LISTS, default_arch, &a, pp, &result)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "Unable to obtain a list of installed packages - aborting"); free(default_arch); YieldCurrentLock(thislock); YieldGlobalPackagePromiseLock(package_lock); result = PROMISE_RESULT_FAIL; goto end; } free(default_arch); if (a.packages.package_policy == PACKAGE_ACTION_PATCH) { Log(LOG_LEVEL_VERBOSE, "Verifying patch action for promise %s", pp->promiser); result = PromiseResultUpdate_HELPER(pp, result, VerifyPromisedPatch(ctx, &a, pp)); } else { Log(LOG_LEVEL_VERBOSE, "Verifying action for promise %s", pp->promiser); result = PromiseResultUpdate_HELPER(pp, result, VerifyPromisedPackage(ctx, &a, pp)); } YieldCurrentLock(thislock); YieldGlobalPackagePromiseLock(package_lock); end: if (!REPORT_THIS_PROMISE(pp)) { // This will not be reported elsewhere, so give it kept outcome. result = PROMISE_RESULT_NOOP; cfPS(ctx, LOG_LEVEL_DEBUG, result, pp, &a, "Giving dummy package kept outcome"); } return result; } /** @brief Pre-check of promise contents Called by VerifyPackagesPromise. Does many sanity checks on the promise attributes and semantics. @param ctx [in] The evaluation context @param a [in] the promise Attributes for this operation @param pp [in] the Promise for this operation @returns the promise result */ static bool PackageSanityCheck(EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(a != NULL); assert(pp != NULL); // Dereferenced in cfPS macros const Packages *const pkgs = &(a->packages); #ifndef __MINGW32__ // Windows may use Win32 API for listing and parsing if (pkgs->package_list_name_regex == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must supply a method for determining the name of existing packages e.g. use the standard library generic package_method"); return false; } if (pkgs->package_list_version_regex == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must supply a method for determining the version of existing packages e.g. use the standard library generic package_method"); return false; } if ((!pkgs->package_commands_useshell) && (pkgs->package_list_command) && (!IsExecutable(CommandArg0(pkgs->package_list_command)))) { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "The proposed package list command '%s' was not executable", pkgs->package_list_command); return false; } #endif /* !__MINGW32__ */ if ((pkgs->package_list_command == NULL) && (pkgs->package_file_repositories == NULL)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must supply a method for determining the list of existing packages (a command or repository list) e.g. use the standard library generic package_method"); return false; } if (pkgs->package_file_repositories) { Rlist *rp; for (rp = pkgs->package_file_repositories; rp != NULL; rp = rp->next) { if (strlen(RlistScalarValue(rp)) > CF_MAXVARSIZE - 1) { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "The repository path '%s' is too long", RlistScalarValue(rp)); return false; } } } if ((pkgs->package_name_regex) || (pkgs->package_version_regex) || (pkgs->package_arch_regex)) { if (pkgs->package_name_regex == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must supply name regex if you supplied version or arch regex for parsing promiser string"); return false; } if ((pkgs->package_name_regex) && (pkgs->package_version_regex) && (pkgs->package_arch_regex)) { if ((pkgs->package_version) || (pkgs->package_architectures)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must either supply all regexs for (name,version,arch) or a separate version number and architecture"); return false; } } else { if ((pkgs->package_version) && (pkgs->package_architectures)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must either supply all regexs for (name,version,arch) or a separate version number and architecture"); return false; } } if ((pkgs->package_version_regex) && (pkgs->package_version)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must either supply version regex or a separate version number"); return false; } if ((pkgs->package_arch_regex) && (pkgs->package_architectures)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "You must either supply arch regex or a separate architecture"); return false; } } if (!pkgs->package_installed_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Package installed regex undefined"); return false; } if (pkgs->package_policy == PACKAGE_ACTION_VERIFY) { if (!pkgs->package_verify_command) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Package verify policy is used, but no package_verify_command is defined"); return false; } else if ((pkgs->package_noverify_returncode == CF_NOINT) && (pkgs->package_noverify_regex == NULL)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Package verify policy is used, but no definition of verification failiure is set (package_noverify_returncode or packages.package_noverify_regex)"); return false; } } if ((pkgs->package_noverify_returncode != CF_NOINT) && (pkgs->package_noverify_regex)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Both package_noverify_returncode and package_noverify_regex are defined, pick one of them"); return false; } /* Dependency checks */ if (!pkgs->package_delete_command) { if (pkgs->package_delete_convention) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_delete_command is not used, but package_delete_convention is defined."); return false; } } if (!pkgs->package_list_command) { if (pkgs->package_installed_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_list_command is not used, but package_installed_regex is defined."); return false; } if (pkgs->package_list_arch_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_list_command is not used, but package_arch_regex is defined."); return false; } if (pkgs->package_list_name_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_list_command is not used, but package_name_regex is defined."); return false; } if (pkgs->package_list_version_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_list_command is not used, but package_version_regex is defined."); return false; } } if (!pkgs->package_patch_command) { if (pkgs->package_patch_arch_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_patch_command is not used, but package_patch_arch_regex is defined."); return false; } if (pkgs->package_patch_name_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_patch_command is not used, but package_patch_name_regex is defined."); return false; } if (pkgs->package_patch_version_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_patch_command is not used, but package_patch_version_regex is defined."); return false; } } if (!pkgs->package_patch_list_command) { if (pkgs->package_patch_installed_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_patch_list_command is not used, but package_patch_installed_regex is defined."); return false; } } if (!pkgs->package_verify_command) { if (pkgs->package_noverify_regex) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_verify_command is not used, but package_noverify_regex is defined."); return false; } if (pkgs->package_noverify_returncode != CF_NOINT) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "!! Dependency conflict: package_verify_command is not used, but package_noverify_returncode is defined."); return false; } } return true; } /** @brief Generates the list of installed packages Called by VerifyInstalledPackages * calls pkgs->package_list_update_command if $(sys.statedir)/software_update_timestamp_ is older than the interval specified in package_list_update_ifelapsed. * assembles the package list from a.packages.package_list_command * respects a.packages.package_commands_useshell (boolean) * parses with a.packages.package_multiline_start and if successful, calls PrependMultiLinePackageItem * else, parses with a.packages.package_installed_regex and if successful, calls PrependListPackageItem @param ctx [in] The evaluation context @param installed_list [in] a list of PackageItems @param default_arch [in] the default architecture @param a [in] the promise Attributes for this operation @param pp [in] the Promise for this operation @param result [inout] the PromiseResult for this operation @returns boolean pass/fail of command run */ static bool PackageListInstalledFromCommand(EvalContext *ctx, PackageItem **installed_list, const char *default_arch, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); if (a->packages.package_list_update_command != NULL) { if (!a->packages.package_add_command) { Log(LOG_LEVEL_ERR, "package_add_command missing while trying to " "generate list of installed packages"); return false; } time_t horizon = 24 * 60, now = time(NULL); bool call_update = true; struct stat sb; char update_timestamp_file[PATH_MAX]; snprintf(update_timestamp_file, sizeof(update_timestamp_file), "%s%csoftware_update_timestamp_%s", GetStateDir(), FILE_SEPARATOR, ReadLastNode(RealPackageManager(a->packages.package_add_command))); if (stat(update_timestamp_file, &sb) != -1) { if (a->packages.package_list_update_ifelapsed != CF_NOINT) { horizon = a->packages.package_list_update_ifelapsed; } char *rel, *action; if (now - sb.st_mtime < horizon * 60) { rel = "less"; action = "Not updating"; call_update = false; } else { rel = "more"; action = "Updating"; } Log(LOG_LEVEL_VERBOSE, "'%s' is %s than %i minutes old. %s package list.", update_timestamp_file, rel, a->packages.package_list_update_ifelapsed, action); } else { Log(LOG_LEVEL_VERBOSE, "'%s' does not exist. Updating package list.", update_timestamp_file); } if (call_update) { Log(LOG_LEVEL_VERBOSE, "Calling package list update command: '%s'", a->packages.package_list_update_command); ExecPackageCommand(ctx, a->packages.package_list_update_command, false, false, a, pp, result); // Touch timestamp file. int err = utime(update_timestamp_file, NULL); if (err < 0) { if (errno == ENOENT) { int fd = open(update_timestamp_file, O_WRONLY | O_CREAT, 0600); if (fd >= 0) { close(fd); } else { Log(LOG_LEVEL_ERR, "Could not create timestamp file '%s'. (open: '%s')", update_timestamp_file, GetErrorStr()); } } else { Log(LOG_LEVEL_ERR, "Could not update timestamp file '%s'. (utime: '%s')", update_timestamp_file, GetErrorStr()); } } } } Log(LOG_LEVEL_VERBOSE, "Reading package list from '%s'", a->packages.package_list_command); FILE *fin; if (a->packages.package_commands_useshell) { if ((fin = cf_popen_sh(a->packages.package_list_command, "r")) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open the package list with command '%s'. (cf_popen_sh: %s)", a->packages.package_list_command, GetErrorStr()); return false; } } else if ((fin = cf_popen(a->packages.package_list_command, "r", true)) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open the package list with command '%s'. (cf_popen: %s)", a->packages.package_list_command, GetErrorStr()); return false; } const int reset = true, update = false; size_t buf_size = CF_BUFSIZE; char *buf = xmalloc(buf_size); for (;;) { ssize_t res = CfReadLine(&buf, &buf_size, fin); if (res == -1) { if (!feof(fin)) { Log(LOG_LEVEL_ERR, "Unable to read list of packages from command '%s'. (fread: %s)", a->packages.package_list_command, GetErrorStr()); cf_pclose(fin); free(buf); return false; } else { break; } } if (a->packages.package_multiline_start) { if (FullTextMatch(ctx, a->packages.package_multiline_start, buf)) { PrependMultiLinePackageItem(ctx, installed_list, buf, reset, default_arch, a, pp); } else { PrependMultiLinePackageItem(ctx, installed_list, buf, update, default_arch, a, pp); } } else { if (!FullTextMatch(ctx, a->packages.package_installed_regex, buf)) { Log(LOG_LEVEL_VERBOSE, "Package line '%s' did not match the package_installed_regex pattern", buf); continue; } if (!PrependListPackageItem(ctx, installed_list, buf, default_arch, a, pp)) { Log(LOG_LEVEL_VERBOSE, "Package line '%s' did not match one of the package_list_(name|version|arch)_regex patterns", buf); continue; } } } if (a->packages.package_multiline_start) { PrependMultiLinePackageItem(ctx, installed_list, buf, reset, default_arch, a, pp); } free(buf); return cf_pclose(fin) == 0; } /** @brief Writes the software inventory Called by VerifyInstalledPackages * calls GetSoftwareCacheFilename to get the inventory CSV filename * for each PackageManager in the list * * for each PackageItem in the PackageManager's list * * write name, version, architecture, manager name @param ctx [in] The evaluation context @param list [in] a list of PackageManagers */ static void ReportSoftware(PackageManager *list) { PackageManager *mp = NULL; PackageItem *pi; char name[CF_BUFSIZE]; GetSoftwareCacheFilename(name); FILE *fout = safe_fopen(name, "w"); if (fout == NULL) { Log(LOG_LEVEL_ERR, "Cannot open the destination file '%s'. (fopen: %s)", name, GetErrorStr()); return; } Writer *writer_installed = FileWriter(fout); CsvWriter *c = CsvWriterOpen(writer_installed); if (c) { for (mp = list; mp != NULL; mp = mp->next) { for (pi = mp->pack_list; pi != NULL; pi = pi->next) { CsvWriterField(c, pi->name); CsvWriterField(c, pi->version); CsvWriterField(c, pi->arch); CsvWriterField(c, ReadLastNode(RealPackageManager(mp->manager))); CsvWriterNewRecord(c); } } CsvWriterClose(c); } else { Log(LOG_LEVEL_ERR, "Cannot write CSV to file '%s'", name); } WriterClose(writer_installed); } /** @brief Invalidates the software inventory Called by ExecuteSchedule and ExecutePatch * calls GetSoftwareCacheFilename to get the inventory CSV filename * sets atime and mtime on that file to 0 */ static void InvalidateSoftwareCache(void) { char name[CF_BUFSIZE]; struct utimbuf epoch = { 0, 0 }; GetSoftwareCacheFilename(name); if (utime(name, &epoch) != 0) { if (errno != ENOENT) { Log(LOG_LEVEL_ERR, "Cannot mark software cache as invalid. (utimes: %s)", GetErrorStr()); } } } /** @brief Gets the cached list of installed packages from file Called by VerifyInstalledPackages * calls GetSoftwareCacheFilename to get the inventory CSV filename * respects a.packages.package_list_update_ifelapsed, returns NULL if file is too old * parses the CSV out of the file (name, version, arch, manager) with each limited to 250 chars * for each line * * if architecture is "default", replace it with default_arch * * if the package manager name matches, call PrependPackageItem @param ctx [in] The evaluation context @param manager [in] the PackageManager we want @param default_arch [in] the default architecture @param a [in] the promise Attributes for this operation @param pp [in] the Promise for this operation @returns list of PackageItems */ static PackageItem *GetCachedPackageList(EvalContext *ctx, PackageManager *manager, const char *default_arch, const Attributes *a, const Promise *pp) { assert(a != NULL); assert(manager != NULL); PackageItem *list = NULL; char name[CF_MAXVARSIZE], version[CF_MAXVARSIZE], arch[CF_MAXVARSIZE], mgr[CF_MAXVARSIZE], line[CF_BUFSIZE]; char thismanager[CF_MAXVARSIZE]; FILE *fin; time_t horizon = 24 * 60, now = time(NULL); struct stat sb; GetSoftwareCacheFilename(name); if (stat(name, &sb) == -1) { return NULL; } if (a->packages.package_list_update_ifelapsed != CF_NOINT) { horizon = a->packages.package_list_update_ifelapsed; } if (now - sb.st_mtime < horizon * 60) { Log(LOG_LEVEL_VERBOSE, "Cache file '%s' exists and is sufficiently fresh according to (package_list_update_ifelapsed)", name); } else { Log(LOG_LEVEL_VERBOSE, "Cache file '%s' exists, but it is out of date (package_list_update_ifelapsed)", name); return NULL; } if ((fin = fopen(name, "r")) == NULL) { Log(LOG_LEVEL_ERR, "Cannot open the source log '%s' - you need to run a package discovery promise to create it in cf-agent. (fopen: %s)", name, GetErrorStr()); return NULL; } /* Max 2016 entries - at least a week */ snprintf(thismanager, CF_MAXVARSIZE - 1, "%s", ReadLastNode(RealPackageManager(manager->manager))); int linenumber = 0; for(;;) { if (fgets(line, sizeof(line), fin) == NULL) { if (ferror(fin)) { UnexpectedError("Failed to read line %d from stream '%s'", linenumber+1, name); break; } else /* feof */ { break; } } ++linenumber; int scancount = sscanf(line, "%250[^,],%250[^,],%250[^,],%250[^\r\n]", name, version, arch, mgr); if (scancount != 4) { Log(LOG_LEVEL_VERBOSE, "Could only read %d values from line %d in '%s'", scancount, linenumber, name); } /* * Transition to explicit default architecture, if package manager * supports it. * * If old cache contains entries with 'default' architecture, and * package method is updated to detect this architecture, on next * execution update this architecture to the real one. */ if (!strcmp(arch, "default")) { strlcpy(arch, default_arch, CF_MAXVARSIZE); } if (strcmp(thismanager, mgr) == 0) { PrependPackageItem(ctx, &list, name, version, arch, pp); } } fclose(fin); return list; } /** @brief Verifies installed packages for a single Promise Called by VerifyPackagesPromise * from all_mgrs, gets the package manager matching a.packages.package_list_command * populate manager->pack_list with GetCachedPackageList * on Windows, use NovaWin_PackageListInstalledFromAPI if a.packages.package_list_command is set to PACKAGE_LIST_COMMAND_WINAPI * on other platforms, use PackageListInstalledFromCommand * call ReportSoftware to save the installed packages inventory * if a.packages.package_patch_list_command is set, use it and parse each line with a.packages.package_patch_installed_regex; if it matches, call PrependPatchItem * call ReportPatches to save the available updates inventory (Enterprise only) @param ctx [in] The evaluation context @param all_mgrs [in] a list of PackageManagers @param default_arch [in] the default architecture @param a [in] the promise Attributes for this operation @param pp [in] the Promise for this operation @param result [inout] the PromiseResult for this operation @returns boolean pass/fail of verification */ static bool VerifyInstalledPackages( EvalContext *ctx, PackageManager **all_mgrs, const char *default_arch, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); PackageManager *manager = GetPackageManager(all_mgrs, a->packages.package_list_command, PACKAGE_ACTION_NONE, PACKAGE_ACTION_POLICY_NONE); if (manager == NULL) { Log(LOG_LEVEL_ERR, "Can't create a package manager envelope for '%s'", a->packages.package_list_command); return false; } if (manager->pack_list != NULL) { Log(LOG_LEVEL_VERBOSE, "Already have a package list for this manager"); return true; } manager->pack_list = GetCachedPackageList(ctx, manager, default_arch, a, pp); if (manager->pack_list != NULL) { Log(LOG_LEVEL_VERBOSE, "Already have a (cached) package list for this manager "); return true; } if (a->packages.package_list_command == NULL) { /* skip */ } #ifdef __MINGW32__ else if (strcmp(a->packages.package_list_command, PACKAGE_LIST_COMMAND_WINAPI) == 0) { if (!NovaWin_PackageListInstalledFromAPI(ctx, &(manager->pack_list), a, pp)) { Log(LOG_LEVEL_ERR, "Could not get list of installed packages"); return false; } } #endif /* !__MINGW32__ */ else { if (!PackageListInstalledFromCommand(ctx, &(manager->pack_list), default_arch, a, pp, result)) { Log(LOG_LEVEL_ERR, "Could not get list of installed packages"); return false; } } ReportSoftware(INSTALLED_PACKAGE_LISTS); /* Now get available updates */ if (a->packages.package_patch_list_command != NULL) { Log(LOG_LEVEL_VERBOSE, "Reading patches from '%s'", CommandArg0(a->packages.package_patch_list_command)); if ((!a->packages.package_commands_useshell) && (!IsExecutable(CommandArg0(a->packages.package_patch_list_command)))) { Log(LOG_LEVEL_ERR, "The proposed patch list command '%s' was not executable", a->packages.package_patch_list_command); return false; } FILE *fin; if (a->packages.package_commands_useshell) { if ((fin = cf_popen_sh(a->packages.package_patch_list_command, "r")) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open the patch list with command '%s'. (cf_popen_sh: %s)", a->packages.package_patch_list_command, GetErrorStr()); return false; } } else if ((fin = cf_popen(a->packages.package_patch_list_command, "r", true)) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open the patch list with command '%s'. (cf_popen: %s)", a->packages.package_patch_list_command, GetErrorStr()); return false; } size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); for (;;) { ssize_t res = CfReadLine(&vbuff, &vbuff_size, fin); if (res == -1) { if (!feof(fin)) { Log(LOG_LEVEL_ERR, "Unable to read list of patches from command '%s'. (fread: %s)", a->packages.package_patch_list_command, GetErrorStr()); cf_pclose(fin); free(vbuff); return false; } else { break; } } // assume patch_list_command lists available patches/updates by default if ((a->packages.package_patch_installed_regex == NULL) || (!FullTextMatch(ctx, a->packages.package_patch_installed_regex, vbuff))) { PrependPatchItem(ctx, &(manager->patch_avail), vbuff, manager->patch_list, default_arch, a, pp); continue; } if (!PrependPatchItem(ctx, &(manager->patch_list), vbuff, manager->patch_list, default_arch, a, pp)) { continue; } } cf_pclose(fin); free(vbuff); } if (a->packages.package_patch_list_command != NULL) { ReportPatches(INSTALLED_PACKAGE_LISTS); // Enterprise only } Log(LOG_LEVEL_VERBOSE, "Done checking packages and patches"); return true; } /** Evaluate what needs to be done **/ /** @brief Finds the largest version of a package available in a file repository Called by SchedulePackageOp * match = false * for each directory in repositories * * try to match refAnyVer against each file * * if it matches and CompareVersions says it's the biggest found so far, copy the matched version and name into matchName and matchVers and set match to true * return match @param ctx [in] The evaluation context @param matchName [inout] the matched package name (written on match) @param matchVers [inout] the matched package version (written on match) @param refAnyVer [in] the regex to match against the filename to extract a version @param ver [in] the version sought @param repositories [in] the list of directories (file repositories) @param a [in] the promise Attributes for this operation @param pp [in] the Promise for this operation @param result [inout] the PromiseResult for this operation @returns boolean pass/fail of search */ int FindLargestVersionAvail(EvalContext *ctx, char *matchName, char *matchVers, const char *refAnyVer, const char *ver, Rlist *repositories, const Attributes *a, const Promise *pp, PromiseResult *result) /* Returns true if a version gt/ge ver is found in local repos, false otherwise */ { int match = false; // match any version if (!ver[0] || strcmp(ver, "*") == 0) { matchVers[0] = '\0'; } else { strlcpy(matchVers, ver, CF_MAXVARSIZE); } for (Rlist *rp = repositories; rp != NULL; rp = rp->next) { Dir *dirh = DirOpen(RlistScalarValue(rp)); if (dirh == NULL) { Log(LOG_LEVEL_ERR, "Can't open local directory '%s'. (opendir: %s)", RlistScalarValue(rp), GetErrorStr()); continue; } const struct dirent *dirp; while ((dirp = DirRead(dirh)) != NULL) { if (FullTextMatch(ctx, refAnyVer, dirp->d_name)) { char *matchVer = ExtractFirstReference(refAnyVer, dirp->d_name); // check if match is largest so far if (CompareVersions(ctx, matchVer, matchVers, a, pp, result) == VERCMP_MATCH) { strlcpy(matchVers, matchVer, CF_MAXVARSIZE); strlcpy(matchName, dirp->d_name, CF_MAXVARSIZE); match = true; } } } DirClose(dirh); } Log(LOG_LEVEL_DEBUG, "FindLargestVersionAvail: largest version of '%s' is '%s' (match=%d)", matchName, matchVers, match); return match; } /** @brief Returns true if a package (n,v,a) is installed and v is larger than the installed version Called by SchedulePackageOp * for each known PackageManager, compare to attr.packages.package_list_command * bail out if no manager was found * for each PackageItem pi in the manager's package list * * if pi->name equals n and (a is "*" or a equals pi->arch) * * * record instV and instA * * * copy attr into attr2 and override the attr2.packages.package_select to PACKAGE_VERSION_COMPARATOR_LT * * * return CompareVersions of the new monster * return false if the above found no matches @param ctx [in] The evaluation context @param n [in] the specific name @param v [in] the specific version @param a [in] the specific architecture @param instV [inout] the matched package version (written on match) @param instA [inout] the matched package architecture (written on match) @param attr [in] the promise Attributes for this operation @param pp [in] the Promise for this operation @param result [inout] the PromiseResult for this operation @returns boolean if given (n,v,a) is newer than known packages */ static bool IsNewerThanInstalled( EvalContext *ctx, const char *n, const char *v, const char *a, char *instV, char *instA, const Attributes *attr, const Promise *pp, PromiseResult *result) { assert(attr != NULL); PackageManager *mp = INSTALLED_PACKAGE_LISTS; while (mp != NULL) { if (strcmp(mp->manager, attr->packages.package_list_command) == 0) { break; } mp = mp->next; } if (mp == NULL) { Log(LOG_LEVEL_VERBOSE, "Found no package manager matching attr.packages.package_list_command '%s'", attr->packages.package_list_command == NULL ? "[empty]" : attr->packages.package_list_command); return false; } Log(LOG_LEVEL_VERBOSE, "Looking for an installed package older than (%s,%s,%s) [name,version,arch]", n, v, a); for (PackageItem *pi = mp->pack_list; pi != NULL; pi = pi->next) { if (strcmp(n, pi->name) == 0 && (strcmp(a, "*") == 0 || strcmp(a, pi->arch) == 0)) { Log(LOG_LEVEL_VERBOSE, "Found installed package (%s,%s,%s) [name,version,arch]", pi->name, pi->version, pi->arch); strlcpy(instV, pi->version, CF_MAXVARSIZE); strlcpy(instA, pi->arch, CF_MAXVARSIZE); /* Horrible */ Attributes attr2 = *attr; attr2.packages.package_select = PACKAGE_VERSION_COMPARATOR_LT; return CompareVersions(ctx, pi->version, v, &attr2, pp, result) == VERCMP_MATCH; } } Log(LOG_LEVEL_VERBOSE, "Package (%s,%s) [name,arch] is not installed", n, a); return false; } /** @brief Returns string version of a PackageAction @param pa [in] The PackageAction @returns string representation of pa or a ProgrammingError */ static const char *PackageAction2String(PackageAction pa) { switch (pa) { case PACKAGE_ACTION_ADD: return "installing"; case PACKAGE_ACTION_DELETE: return "uninstalling"; case PACKAGE_ACTION_REINSTALL: return "reinstalling"; case PACKAGE_ACTION_UPDATE: return "updating"; case PACKAGE_ACTION_ADDUPDATE: return "installing/updating"; case PACKAGE_ACTION_PATCH: return "patching"; case PACKAGE_ACTION_VERIFY: return "verifying"; default: ProgrammingError("CFEngine: internal error: illegal package action"); } } /** @brief Adds a specific package (name,version,arch) as specified by Attributes a to the scheduled operations Called by SchedulePackageOp. Either warn or fix, based on a->transaction.action. To fix, calls GetPackageManager and enqueues the desired operation and package with the returned manager @param ctx [in] The evaluation context @param a [in] the Attributes specifying how to compare @param mgr [in] the specific manager name @param pa [in] the PackageAction to enqueue @param name [in] the specific name @param version [in] the specific version @param arch [in] the specific architecture @param pp [in] the Promise for this operation @returns the promise result */ static PromiseResult AddPackageToSchedule(EvalContext *ctx, const Attributes *a, char *mgr, PackageAction pa, const char *name, const char *version, const char *arch, const Promise *pp) { assert(a != NULL); assert(pp != NULL); switch (a->transaction.action) { case cfa_warn: cfPS_HELPER_3ARG(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Need to repair promise '%s' by '%s' package '%s'", pp->promiser, PackageAction2String(pa), name); return PROMISE_RESULT_WARN; case cfa_fix: { PackageManager *manager = GetPackageManager(&PACKAGE_SCHEDULE, mgr, pa, a->packages.package_changes); if (manager == NULL) { ProgrammingError("AddPackageToSchedule: Null package manager found!!!"); } PrependPackageItem(ctx, &(manager->pack_list), name, version, arch, pp); return PROMISE_RESULT_CHANGE; } default: ProgrammingError("CFEngine: internal error: illegal file action"); } } /** @brief Adds a specific patch (name,version,arch) as specified by Attributes a to the scheduled operations Called by SchedulePackageOp. Either warn or fix, based on a->transaction.action. To fix, calls GetPackageManager and enqueues the desired operation and package with the returned manager @param ctx [in] The evaluation context @param a [in] the Attributes specifying how to compare @param mgr [in] the specific manager name @param pa [in] the PackageAction to enqueue @param name [in] the specific name @param version [in] the specific version @param arch [in] the specific architecture @param pp [in] the Promise for this operation @returns the promise result */ static PromiseResult AddPatchToSchedule(EvalContext *ctx, const Attributes *a, char *mgr, PackageAction pa, const char *name, const char *version, const char *arch, const Promise *pp) { assert(a != NULL); assert(pp != NULL); switch (a->transaction.action) { case cfa_warn: cfPS_HELPER_3ARG(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Need to repair promise '%s' by '%s' package '%s'", pp->promiser, PackageAction2String(pa), name); return PROMISE_RESULT_WARN; case cfa_fix: { PackageManager *manager = GetPackageManager(&PACKAGE_SCHEDULE, mgr, pa, a->packages.package_changes); if (manager == NULL) { ProgrammingError("AddPatchToSchedule: Null package manager found!!!"); } PrependPackageItem(ctx, &(manager->patch_list), name, version, arch, pp); return PROMISE_RESULT_CHANGE; } default: ProgrammingError("Illegal file action"); } } /** @brief Schedules a package operation based on the action, package state, and everything else. Called by VerifyPromisedPatch and CheckPackageState. This function has a complexity metric of 3 Googols. * if package_delete_convention or package_name_convention are given and apply to the operation, construct the package name from them (from PACKAGES_CONTEXT) * else, just use the given package name * warn about "*" in the package name * set package_select_in_range with magic * create PackageAction policy from the package_policy and then split ADDUPDATE into ADD or UPDATE based on "installed" * result starts as NOOP * switch(policy) * * case ADD and "installed": * * * if we have package_file_repositories * * * * use the package_name_convention to build the package name (from PACKAGES_CONTEXT_ANYVER, setting version to "*") * * * * if FindLargestVersionAvail finds the latest package version in the file repos, use that as the package name * * * AddPackageToSchedule package_add_command, ADD, package name, etc. * * case DELETE and (matched AND package_select_in_range) OR (installed AND no_version_specified): * * * fail promise unless package_delete_command * * * if we have package_file_repositories * * * * clean up the name string from any "repo" references and add the right file repo * * * AddPackageToSchedule package_delete_command, DELETE, package name, etc. * * case REINSTALL: * * * fail promise unless package_delete_command * * * fail promise if no_version_specified * * * if (matched AND package_select_in_range) OR (installed AND no_version_specified) do AddPackageToSchedule package_delete_command, DELETE, package name, etc. * * * AddPackageToSchedule package_add_command, ADD, package name, etc. * * case UPDATE: * * * if we have package_file_repositories * * * * use the package_name_convention to build the package name (from PACKAGES_CONTEXT_ANYVER, setting version to "*") * * * * if FindLargestVersionAvail finds the latest package version in the file repos, use that as the package name * * * if installed, IsNewerThanInstalled is checked, and if it returns false we don't update an up-to-date package * * * if installed or (matched AND package_select_in_range AND !no_version_specified) (this is the main update condition) * * * * if package_update_command is not given * * * * * if package_delete_convention is given, use it to build id_del (from PACKAGES_CONTEXT) * * * * * fail promise if package_update_command and package_add_command are not given * * * * * AddPackageToSchedule with package_delete_command, DELETE, id_del, etc * * * * * AddPackageToSchedule with package_add_command, ADD, package name, etc * * * * else we have package_update_command, so AddPackageToSchedule with package_update_command, UPDATE, package name, etc * * * else the package is not updateable: no match or not installed, fail promise * * case PATCH: * * * if matched and not installed, AddPatchToSchedule with package_patch_command, PATCH, package name, etc. * * case VERIFY: * * * if (matched and package_select_in_range) OR (installed AND no_version_specified), AddPatchToSchedule with package_verify_command, VERIFY, package name, etc. @param ctx [in] The evaluation context @param name [in] the specific name @param version [in] the specific version @param arch [in] the specific architecture @param installed [in] is the package installed? @param matched [in] is the package matched in the available list? @param no_version_specified [in] no version was specified in the promise @param a [in] the Attributes specifying how to compare @param pp [in] the Promise for this operation @returns the promise result */ static PromiseResult SchedulePackageOp(EvalContext *ctx, const char *name, const char *version, const char *arch, int installed, int matched, int no_version_specified, const Attributes *a, const Promise *pp) { assert(a != NULL); assert(pp != NULL); // Dereferenced by cfPS macros char refAnyVerEsc[CF_EXPANDSIZE]; char largestVerAvail[CF_MAXVARSIZE]; char largestPackAvail[CF_MAXVARSIZE]; char id[CF_EXPANDSIZE]; Log(LOG_LEVEL_VERBOSE, "Checking if package (%s,%s,%s) [name,version,arch] " "is at the desired state (installed=%d,matched=%d)", name, version, arch, installed, matched); /* Now we need to know the name-convention expected by the package manager */ Buffer *expanded = BufferNew(); if ((a->packages.package_name_convention) || (a->packages.package_delete_convention)) { VarRef *ref_name = VarRefParseFromScope("name", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_name, name, CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_version = VarRefParseFromScope("version", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_version, version, CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_arch = VarRefParseFromScope("arch", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_arch, arch, CF_DATA_TYPE_STRING, "source=promise"); if ((a->packages.package_delete_convention) && (a->packages.package_policy == PACKAGE_ACTION_DELETE)) { ExpandScalar(ctx, NULL, PACKAGES_CONTEXT, a->packages.package_delete_convention, expanded); strlcpy(id, BufferData(expanded), CF_EXPANDSIZE); } else if (a->packages.package_name_convention) { ExpandScalar(ctx, NULL, PACKAGES_CONTEXT, a->packages.package_name_convention, expanded); strlcpy(id, BufferData(expanded), CF_EXPANDSIZE); } else { strlcpy(id, name, CF_EXPANDSIZE); } EvalContextVariableRemove(ctx, ref_name); VarRefDestroy(ref_name); EvalContextVariableRemove(ctx, ref_version); VarRefDestroy(ref_version); EvalContextVariableRemove(ctx, ref_arch); VarRefDestroy(ref_arch); } else { strlcpy(id, name, CF_EXPANDSIZE); } Log(LOG_LEVEL_VERBOSE, "Package promises to refer to itself as '%s' to the manager", id); if (strchr(id, '*')) { Log(LOG_LEVEL_VERBOSE, "Package name contains '*' -- perhaps " "a missing attribute (name/version/arch) should be specified"); } // This is very confusing int package_select_in_range; switch (a->packages.package_select) { case PACKAGE_VERSION_COMPARATOR_EQ: case PACKAGE_VERSION_COMPARATOR_GE: case PACKAGE_VERSION_COMPARATOR_LE: case PACKAGE_VERSION_COMPARATOR_NONE: Log(LOG_LEVEL_VERBOSE, "Package version seems to match criteria"); package_select_in_range = true; break; default: package_select_in_range = false; break; } PackageAction policy = a->packages.package_policy; if (policy == PACKAGE_ACTION_ADDUPDATE) /* Work out which: */ { if (installed) { policy = PACKAGE_ACTION_UPDATE; } else { policy = PACKAGE_ACTION_ADD; } } PromiseResult result = PROMISE_RESULT_NOOP; switch (policy) { case PACKAGE_ACTION_ADD: if (installed == 0) { if ((a->packages.package_file_repositories != NULL)) { Log(LOG_LEVEL_VERBOSE, "Package method specifies a file repository"); { VarRef *ref_name = VarRefParseFromScope("name", PACKAGES_CONTEXT_ANYVER); EvalContextVariablePut(ctx, ref_name, name, CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_version = VarRefParseFromScope("version", PACKAGES_CONTEXT_ANYVER); EvalContextVariablePut(ctx, ref_version, "(.*)", CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_arch = VarRefParseFromScope("arch", PACKAGES_CONTEXT_ANYVER); EvalContextVariablePut(ctx, ref_arch, arch, CF_DATA_TYPE_STRING, "source=promise"); BufferClear(expanded); if (a->packages.package_name_convention) { ExpandScalar(ctx, NULL, PACKAGES_CONTEXT_ANYVER, a->packages.package_name_convention, expanded); } EvalContextVariableRemove(ctx, ref_name); VarRefDestroy(ref_name); EvalContextVariableRemove(ctx, ref_version); VarRefDestroy(ref_version); EvalContextVariableRemove(ctx, ref_arch); VarRefDestroy(ref_arch); } EscapeSpecialChars(BufferData(expanded), refAnyVerEsc, sizeof(refAnyVerEsc), "(.*)",""); if (FindLargestVersionAvail(ctx, largestPackAvail, largestVerAvail, refAnyVerEsc, version, a->packages.package_file_repositories, a, pp, &result)) { Log(LOG_LEVEL_VERBOSE, "Using latest version in file repositories; '%s'", largestPackAvail); strlcpy(id, largestPackAvail, CF_EXPANDSIZE); } else { Log(LOG_LEVEL_VERBOSE, "No package in file repositories satisfy version constraint"); break; } } else { Log(LOG_LEVEL_VERBOSE, "Package method does NOT specify a file repository"); } Log(LOG_LEVEL_VERBOSE, "Schedule package for addition"); if (a->packages.package_add_command == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package add command undefined"); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_add_command, PACKAGE_ACTION_ADD, id, "any", "any", pp)); } else { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Package '%s' already installed, so we never add it again", pp->promiser); } break; case PACKAGE_ACTION_DELETE: // we're deleting a matched package found in a range OR an installed package with no version if ((matched && package_select_in_range) || (installed && no_version_specified)) { Log(LOG_LEVEL_VERBOSE, "Schedule package for deletion"); if (a->packages.package_delete_command == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package delete command undefined"); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } // expand local repository in the name convention, if present if (a->packages.package_file_repositories) { Log(LOG_LEVEL_VERBOSE, "Package method specifies a file repository"); // remove any "$(repo)" from the name convention string if (strncmp(id, "$(firstrepo)", 12) == 0) { const char *idBuf = id + 12; // and add the correct repo const char *pathName = PrefixLocalRepository(a->packages.package_file_repositories, idBuf); if (pathName) { strlcpy(id, pathName, CF_EXPANDSIZE); Log(LOG_LEVEL_VERBOSE, "Expanded the package repository to '%s'", id); } else { Log(LOG_LEVEL_ERR, "Package '%s' can't be found " "in any of the listed repositories", idBuf); } } } else { Log(LOG_LEVEL_VERBOSE, "Package method does NOT specify a file repository"); } result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_delete_command, PACKAGE_ACTION_DELETE, id, "any", "any", pp)); } else { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Package deletion is as promised -- no match"); } break; case PACKAGE_ACTION_REINSTALL: if (a->packages.package_delete_command == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package delete command undefined"); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } if (!no_version_specified) { Log(LOG_LEVEL_VERBOSE, "Schedule package for reinstallation"); if (a->packages.package_add_command == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package add command undefined"); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } // we're deleting a matched package found in a range OR an installed package with no version if ((matched && package_select_in_range) || (installed && no_version_specified)) { result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_delete_command, PACKAGE_ACTION_DELETE, id, "any", "any", pp)); } result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_add_command, PACKAGE_ACTION_ADD, id, "any", "any", pp)); } else { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package reinstallation cannot be promised -- insufficient version info or no match"); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } break; case PACKAGE_ACTION_UPDATE: { char inst_arch[CF_MAXVARSIZE]; char inst_ver[CF_MAXVARSIZE]; *inst_ver = '\0'; *inst_arch = '\0'; if ((a->packages.package_file_repositories != NULL)) { Log(LOG_LEVEL_VERBOSE, "Package method specifies a file repository"); { VarRef *ref_name = VarRefParseFromScope("name", PACKAGES_CONTEXT_ANYVER); EvalContextVariablePut(ctx, ref_name, name, CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_version = VarRefParseFromScope("version", PACKAGES_CONTEXT_ANYVER); EvalContextVariablePut(ctx, ref_version, "(.*)", CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_arch = VarRefParseFromScope("arch", PACKAGES_CONTEXT_ANYVER); EvalContextVariablePut(ctx, ref_arch, arch, CF_DATA_TYPE_STRING, "source=promise"); BufferClear(expanded); ExpandScalar(ctx, NULL, PACKAGES_CONTEXT_ANYVER, a->packages.package_name_convention, expanded); EvalContextVariableRemove(ctx, ref_name); VarRefDestroy(ref_name); EvalContextVariableRemove(ctx, ref_version); VarRefDestroy(ref_version); EvalContextVariableRemove(ctx, ref_arch); VarRefDestroy(ref_arch); } EscapeSpecialChars(BufferData(expanded), refAnyVerEsc, sizeof(refAnyVerEsc), "(.*)",""); if (FindLargestVersionAvail(ctx, largestPackAvail, largestVerAvail, refAnyVerEsc, version, a->packages.package_file_repositories, a, pp, &result)) { Log(LOG_LEVEL_VERBOSE, "Using latest version in file repositories; '%s'", largestPackAvail); strlcpy(id, largestPackAvail, CF_EXPANDSIZE); } else { Log(LOG_LEVEL_VERBOSE, "No package in file repositories satisfy version constraint"); break; } } else { Log(LOG_LEVEL_VERBOSE, "Package method does NOT specify a file repository"); strlcpy(largestVerAvail, version, sizeof(largestVerAvail)); // user-supplied version } if (installed) { Log(LOG_LEVEL_VERBOSE, "Checking if latest available version is newer than installed..."); if (IsNewerThanInstalled(ctx, name, largestVerAvail, arch, inst_ver, inst_arch, a, pp, &result)) { Log(LOG_LEVEL_VERBOSE, "Installed package (%s,%s,%s) [name,version,arch] is older than latest available (%s,%s,%s) [name,version,arch] - updating", name, inst_ver, inst_arch, name, largestVerAvail, arch); } else { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Installed packaged '%s' is up to date, not updating", pp->promiser); break; } } if (installed || (matched && package_select_in_range && !no_version_specified)) { if (a->packages.package_update_command == NULL) { Log(LOG_LEVEL_VERBOSE, "Package update command undefined - failing over to delete then add"); // we need to have the version of installed package const char *id_del = id; if (a->packages.package_delete_convention) { if (*inst_ver == '\0') { inst_ver[0] = '*'; inst_ver[1] = '\0'; } if (*inst_arch == '\0') { inst_arch[0] = '*'; inst_arch[1] = '\0'; } VarRef *ref_name = VarRefParseFromScope("name", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_name, name, CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_version = VarRefParseFromScope("version", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_version, inst_ver, CF_DATA_TYPE_STRING, "source=promise"); VarRef *ref_arch = VarRefParseFromScope("arch", PACKAGES_CONTEXT); EvalContextVariablePut(ctx, ref_arch, inst_arch, CF_DATA_TYPE_STRING, "source=promise"); BufferClear(expanded); ExpandScalar(ctx, NULL, PACKAGES_CONTEXT, a->packages.package_delete_convention, expanded); id_del = BufferData(expanded); EvalContextVariableRemove(ctx, ref_name); VarRefDestroy(ref_name); EvalContextVariableRemove(ctx, ref_version); VarRefDestroy(ref_version); EvalContextVariableRemove(ctx, ref_arch); VarRefDestroy(ref_arch); } Log(LOG_LEVEL_VERBOSE, "Scheduling package with id '%s' for deletion", id_del); if (a->packages.package_add_command == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package add command undefined"); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } if (a->packages.package_delete_command == NULL) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package delete command undefined"); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_delete_command, PACKAGE_ACTION_DELETE, id_del, "any", "any", pp)); result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_add_command, PACKAGE_ACTION_ADD, id, "any", "any", pp)); } else { Log(LOG_LEVEL_VERBOSE, "Schedule package for update"); result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_update_command, PACKAGE_ACTION_UPDATE, id, "any", "any", pp)); } } else { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Package '%s' cannot be updated -- no match or not installed", pp->promiser); result = PromiseResultUpdate_HELPER(pp, result, PROMISE_RESULT_FAIL); } break; } case PACKAGE_ACTION_PATCH: if (matched && (!installed)) { Log(LOG_LEVEL_VERBOSE, "Schedule package for patching"); result = PromiseResultUpdate_HELPER(pp, result, AddPatchToSchedule(ctx, a, a->packages.package_patch_command, PACKAGE_ACTION_PATCH, id, "any", "any", pp)); } else { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Package patch state of '%s' is as promised -- already installed", pp->promiser); } break; case PACKAGE_ACTION_VERIFY: if ((matched && package_select_in_range) || (installed && no_version_specified)) { Log(LOG_LEVEL_VERBOSE, "Schedule package for verification"); result = PromiseResultUpdate_HELPER(pp, result, AddPackageToSchedule(ctx, a, a->packages.package_verify_command, PACKAGE_ACTION_VERIFY, id, "any", "any", pp)); } else { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_FAIL, pp, a, "Package '%s' cannot be verified -- no match", pp->promiser); BufferDestroy(expanded); return PROMISE_RESULT_FAIL; } break; default: break; } BufferDestroy(expanded); return result; } /** @brief Compare a PackageItem to a specific package (n,v,arch) as specified by Attributes a Called by PatchMatch and PackageMatch. First, checks the package names are the same (according to CompareCSVName). Second, checks the architectures are the same or arch is "*" Third, checks the versions with CompareVersions or version is "*" @param ctx [in] The evaluation context @param n [in] the specific name @param v [in] the specific version @param arch [in] the specific architecture @param pi [in] the PackageItem to check @param a [in] the Attributes specifying how to compare @param pp [in] the Promise for this operation @param mode [in] the operating mode, informational for logging @returns the version comparison result */ VersionCmpResult ComparePackages(EvalContext *ctx, const char *n, const char *v, const char *arch, PackageItem *pi, const Attributes *a, const Promise *pp, const char *mode, PromiseResult *result) { assert(pi != NULL); assert(a != NULL); Log(LOG_LEVEL_VERBOSE, "Comparing %s package (%s,%s,%s) " "to [%s] with given (%s,%s,%s) [name,version,arch]", mode, pi->name, pi->version, pi->arch, PackageVersionComparatorToString(a->packages.package_select), n, v, arch); if (CompareCSVName(n, pi->name) != 0) { return VERCMP_NO_MATCH; } Log(LOG_LEVEL_VERBOSE, "Matched %s name '%s'", mode, n); if (strcmp(arch, "*") != 0) { if (strcmp(arch, pi->arch) != 0) { return VERCMP_NO_MATCH; } Log(LOG_LEVEL_VERBOSE, "Matched %s arch '%s'", mode, arch); } else { Log(LOG_LEVEL_VERBOSE, "Matched %s wildcard arch '%s'", mode, arch); } if (strcmp(v, "*") == 0) { Log(LOG_LEVEL_VERBOSE, "Matched %s wildcard version '%s'", mode, v); return VERCMP_MATCH; } VersionCmpResult vc = CompareVersions(ctx, pi->version, v, a, pp, result); Log(LOG_LEVEL_VERBOSE, "Version comparison returned %s for %s package (%s,%s,%s) " "to [%s] with given (%s,%s,%s) [name,version,arch]", vc == VERCMP_MATCH ? "MATCH" : vc == VERCMP_NO_MATCH ? "NO_MATCH" : "ERROR", mode, pi->name, pi->version, pi->arch, PackageVersionComparatorToString(a->packages.package_select), n, v, arch); return vc; } /** @brief Finds a specific package (n,v,a) [name, version, architecture] as specified by Attributes attr Called by VerifyPromisedPatch. Goes through all the installed packages to find matches for the given attributes. The package manager is checked against attr.packages.package_list_command. The package name is checked as a regular expression. then (n,v,a) with ComparePackages. @param ctx [in] The evaluation context @param n [in] the specific name @param v [in] the specific version @param a [in] the specific architecture @param attr [in] the Attributes specifying how to compare @param pp [in] the Promise for this operation @param mode [in] the operating mode, informational for logging @returns the version comparison result */ static VersionCmpResult PatchMatch(EvalContext *ctx, const char *n, const char *v, const char *a, const Attributes *attr, const Promise *pp, const char* mode, PromiseResult *result) { assert(attr != NULL); PackageManager *mp; // This REALLY needs some commenting for (mp = INSTALLED_PACKAGE_LISTS; mp != NULL; mp = mp->next) { if (strcmp(mp->manager, attr->packages.package_list_command) == 0) { break; } } Log(LOG_LEVEL_VERBOSE, "PatchMatch: looking for %s to [%s] with given (%s,%s,%s) [name,version,arch] in package manager %s", mode, PackageVersionComparatorToString(attr->packages.package_select), n, v, a, mp->manager); for (PackageItem *pi = mp->patch_list; pi != NULL; pi = pi->next) { if (FullTextMatch(ctx, n, pi->name)) /* Check regexes */ { Log(LOG_LEVEL_VERBOSE, "PatchMatch: regular expression match succeeded for %s against %s", n, pi->name); return VERCMP_MATCH; } else { VersionCmpResult res = ComparePackages(ctx, n, v, a, pi, attr, pp, mode, result); if (res != VERCMP_NO_MATCH) { Log(LOG_LEVEL_VERBOSE, "PatchMatch: patch comparison for %s was decisive: %s", pi->name, res == VERCMP_MATCH ? "MATCH" : "ERROR"); return res; } } } Log(LOG_LEVEL_VERBOSE, "PatchMatch did not match the constraints of promise (%s,%s,%s) [name,version,arch]", n, v, a); return VERCMP_NO_MATCH; } /** @brief Finds a specific package (n,v,a) [name, version, architecture] as specified by Attributes attr Called by CheckPackageState. Goes through all the installed packages to find matches for the given attributes. The package manager is checked against attr.packages.package_list_command. The (n,v,a) search is done with ComparePackages. @param ctx [in] The evaluation context @param n [in] the specific name @param v [in] the specific version @param a [in] the specific architecture @param attr [in] the Attributes specifying how to compare @param pp [in] the Promise for this operation @param mode [in] the operating mode, informational for logging @returns the version comparison result */ static VersionCmpResult PackageMatch(EvalContext *ctx, const char *n, const char *v, const char *a, const Attributes *attr, const Promise *pp, const char* mode, PromiseResult *result) /* * Returns VERCMP_MATCH if any installed packages match (n,v,a), VERCMP_NO_MATCH otherwise, VERCMP_ERROR on error. * The mode is informational */ { assert(attr != NULL); PackageManager *mp = NULL; // This REALLY needs some commenting for (mp = INSTALLED_PACKAGE_LISTS; mp != NULL; mp = mp->next) { if (strcmp(mp->manager, attr->packages.package_list_command) == 0) { break; } } Log(LOG_LEVEL_VERBOSE, "PackageMatch: looking for %s (%s,%s,%s) [name,version,arch] in package manager %s", mode, n, v, a, mp->manager); for (PackageItem *pi = mp->pack_list; pi != NULL; pi = pi->next) { VersionCmpResult res = ComparePackages(ctx, n, v, a, pi, attr, pp, mode, result); if (res != VERCMP_NO_MATCH) { Log(LOG_LEVEL_VERBOSE, "PackageMatch: package comparison for %s %s was decisive: %s", mode, pi->name, res == VERCMP_MATCH ? "MATCH" : "ERROR"); return res; } } Log(LOG_LEVEL_VERBOSE, "PackageMatch did not find %s packages to match the constraints of promise (%s,%s,%s) [name,version,arch]", mode, n, v, a); return VERCMP_NO_MATCH; } /** @brief Check if the operation should be scheduled based on the package policy, if the package matches, and if it's installed Called by CheckPackageState. Uses a.packages.package_policy to determine operating mode. The use of matches and installed depends on the package_policy: * PACKAGE_ACTION_DELETE: schedule if (matches AND installed) * PACKAGE_ACTION_REINSTALL: schedule if (matches AND installed) * all other policies: schedule if (not matches OR not installed) @param ctx [in] The evaluation context @param a [in] the Attributes specifying the package policy @param pp [in] the Promise for this operation @param matches [in] whether the package matches @param installed [in] whether the package is installed @returns whether the package operation should be scheduled */ static bool WillSchedulePackageOperation(EvalContext *ctx, const Attributes *a, const Promise *pp, int matches, int installed) { assert(a != NULL); assert(pp != NULL); PackageAction policy = a->packages.package_policy; Log(LOG_LEVEL_DEBUG, "WillSchedulePackageOperation: on entry, action %s: package %s matches = %s, installed = %s.", PackageAction2String(policy), pp->promiser, matches ? "yes" : "no", installed ? "yes" : "no"); switch (policy) { case PACKAGE_ACTION_DELETE: if (matches && installed) { Log(LOG_LEVEL_VERBOSE, "WillSchedulePackageOperation: Package %s to be deleted is installed.", pp->promiser); return true; } else { Log(LOG_LEVEL_DEBUG, "WillSchedulePackageOperation: Package %s can't be deleted if it's not installed, NOOP.", pp->promiser); cfPS_HELPER_1ARG(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Package %s to be deleted does not exist anywhere", pp->promiser); } break; case PACKAGE_ACTION_REINSTALL: if (matches && installed) { Log(LOG_LEVEL_VERBOSE, "WillSchedulePackageOperation: Package %s to be reinstalled is already installed.", pp->promiser); return true; } else { Log(LOG_LEVEL_DEBUG, "WillSchedulePackageOperation: Package %s already installed, NOOP.", pp->promiser); cfPS_HELPER_1ARG(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Package '%s' already installed and matches criteria", pp->promiser); } break; default: if (!matches) // why do we schedule a 'not matched' operation? { return true; } else if (!installed) // matches and not installed { return true; } else // matches and installed { Log(LOG_LEVEL_DEBUG, "WillSchedulePackageOperation: Package %s already installed, NOOP.", pp->promiser); cfPS_HELPER_1ARG(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Package '%s' already installed and matches criteria", pp->promiser); } break; } return false; } /** @brief Checks the state of a specific package (name,version,arch) as specified by Attributes a Called by VerifyPromisedPackage. * copies a into a2, overrides a2.packages.package_select to PACKAGE_VERSION_COMPARATOR_EQ * VersionCmpResult installed = check if (name,*,arch) is installed with PackageMatch (note version override!) * if PackageMatch returned an error, fail the promise * VersionCmpResult matches = check if (name,version,arch) is installed with PackageMatch * if PackageMatch returned an error, fail the promise * if WillSchedulePackageOperation with "matches" and "installed" passes, call SchedulePackageOp on the package @param ctx [in] The evaluation context @param a [in] the Attributes specifying how to compare @param pp [in] the Promise for this operation @param name [in] the specific name @param version [in] the specific version @param arch [in] the specific architecture @param no_version [in] ignore the version, be cool @returns the promise result */ static PromiseResult CheckPackageState(EvalContext *ctx, const Attributes *a, const Promise *pp, const char *name, const char *version, const char *arch, bool no_version) { assert(a != NULL); assert(pp != NULL); // Dereferenced in cfPS macros PromiseResult result = PROMISE_RESULT_NOOP; /* Horrible */ Attributes a2 = *a; a2.packages.package_select = PACKAGE_VERSION_COMPARATOR_EQ; VersionCmpResult installed = PackageMatch(ctx, name, "*", arch, &a2, pp, "[installed]", &result); Log(LOG_LEVEL_VERBOSE, "CheckPackageState: Installed package match for (%s,%s,%s) [name,version,arch] was decisive: %s", name, "*", arch, installed == VERCMP_MATCH ? "MATCH" : "ERROR-OR-NOMATCH"); if (installed == VERCMP_ERROR) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a2, "Failure trying to compare installed package versions"); result = PromiseResultUpdate_HELPER(pp, result, PROMISE_RESULT_FAIL); return result; } VersionCmpResult matches = PackageMatch(ctx, name, version, arch, &a2, pp, "[available]", &result); Log(LOG_LEVEL_VERBOSE, "CheckPackageState: Available package match for (%s,%s,%s) [name,version,arch] was decisive: %s", name, version, arch, matches == VERCMP_MATCH ? "MATCH" : "ERROR-OR-NOMATCH"); if (matches == VERCMP_ERROR) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a2, "Failure trying to compare available package versions"); result = PromiseResultUpdate_HELPER(pp, result, PROMISE_RESULT_FAIL); return result; } if (WillSchedulePackageOperation(ctx, &a2, pp, matches, installed)) { Log(LOG_LEVEL_VERBOSE, "CheckPackageState: matched package (%s,%s,%s) [name,version,arch]; scheduling operation", name, version, arch); return SchedulePackageOp(ctx, name, version, arch, installed, matches, no_version, a, pp); } return result; } /** @brief Verifies a promised patch operation as defined by a and pp Called by VerifyPackagesPromise for the patch operation. * package name is pp->promiser * installed and matches counts = 0 * copies a into a2 and overrides a2.packages.package_select to PACKAGE_VERSION_COMPARATOR_EQ * promise result starts as NOOP * if package version is given * * for arch = each architecture requested in a2, or (if none given) any architecture "*" * * * installed1 = PatchMatch(a2, name, any version "*", any architecture "*") * * * matches1 = PatchMatch(a2, name, requested version, arch) * * * if either installed1 or matches1 failed, return promise error * * * else, installed += installed1; matches += matches1 * else if package_version_regex is given * * assume that package_name_regex and package_arch_regex are also given and use the 3 regexes to extract name, version, arch * * * installed = PatchMatch(a2, matched name, any version "*", any architecture "*") * * * matches = PatchMatch(a2, matched name, matched version, matched architecture) * * * if either installed or matches failed, return promise error * else (no explicit version is given) (SAME LOOP AS EXPLICIT VERSION LOOP ABOVE) * * no_version = true * * for arch = each architecture requested in a2, or (if none given) any architecture "*" * * * requested version = any version '*' * * * installed1 = PatchMatch(a2, name, any version "*", any architecture "*") * * * matches1 = PatchMatch(a2, name, requested version '*', arch) * * * if either installed1 or matches1 failed, return promise error * * * else, installed += installed1; matches += matches1 * finally, call SchedulePackageOp with the found name, version, arch, installed, matches, no_version @param ctx [in] The evaluation context @param a [in] the Attributes specifying how to compare @param pp [in] the Promise for this operation @returns the promise result (failure or NOOP) */ static PromiseResult VerifyPromisedPatch(EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(a != NULL); assert(pp != NULL); char version[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE]; char arch[CF_MAXVARSIZE]; char *package = pp->promiser; int matches = 0, installed = 0, no_version = false; Rlist *rp; /* Horrible */ Attributes a2 = *a; a2.packages.package_select = PACKAGE_VERSION_COMPARATOR_EQ; PromiseResult result = PROMISE_RESULT_NOOP; if (a2.packages.package_version) /* The version is specified explicitly */ { // Note this loop will run if rp is NULL for (rp = a2.packages.package_architectures; ; rp = rp->next) { strlcpy(name, pp->promiser, CF_MAXVARSIZE); strlcpy(version, a2.packages.package_version, CF_MAXVARSIZE); strlcpy(arch, (rp == NULL) ? "*" : RlistScalarValue(rp), CF_MAXVARSIZE); VersionCmpResult installed1 = PatchMatch(ctx, name, "*", "*", &a2, pp, "[installed1]", &result); VersionCmpResult matches1 = PatchMatch(ctx, name, version, arch, &a2, pp, "[available1]", &result); if ((installed1 == VERCMP_ERROR) || (matches1 == VERCMP_ERROR)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a2, "Failure trying to compare package versions"); result = PromiseResultUpdate_HELPER(pp, result, PROMISE_RESULT_FAIL); return result; } installed += installed1; matches += matches1; if (rp == NULL) break; // Note we exit the loop explicitly here } } else if (a2.packages.package_version_regex) // version is not given, but a version regex is { /* The name, version and arch are to be extracted from the promiser */ strlcpy(version, ExtractFirstReference(a2.packages.package_version_regex, package), CF_MAXVARSIZE); strlcpy(name, ExtractFirstReference(a2.packages.package_name_regex, package), CF_MAXVARSIZE); strlcpy(arch, ExtractFirstReference(a2.packages.package_arch_regex, package), CF_MAXVARSIZE); installed = PatchMatch(ctx, name, "*", "*", &a2, pp, "[installed]", &result); matches = PatchMatch(ctx, name, version, arch, &a2, pp, "[available]", &result); if ((installed == VERCMP_ERROR) || (matches == VERCMP_ERROR)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a2, "Failure trying to compare package versions"); result = PromiseResultUpdate_HELPER(pp, result, PROMISE_RESULT_FAIL); return result; } } else // the desired package version was not specified { no_version = true; // Note this loop will run if rp is NULL for (rp = a2.packages.package_architectures; ; rp = rp->next) { strlcpy(name, pp->promiser, CF_MAXVARSIZE); strlcpy(version, "*", CF_MAXVARSIZE); strlcpy(arch, (rp == NULL) ? "*" : RlistScalarValue(rp), CF_MAXVARSIZE); VersionCmpResult installed1 = PatchMatch(ctx, name, "*", "*", &a2, pp, "[installed1]", &result); VersionCmpResult matches1 = PatchMatch(ctx, name, version, arch, &a2, pp, "[available1]", &result); if ((installed1 == VERCMP_ERROR) || (matches1 == VERCMP_ERROR)) { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a2, "Failure trying to compare package versions"); result = PromiseResultUpdate_HELPER(pp, result, PROMISE_RESULT_FAIL); return result; } installed += installed1; matches += matches1; if (rp == NULL) break; // Note we exit the loop explicitly here } } Log(LOG_LEVEL_VERBOSE, "%d patch(es) matching the name '%s' already installed", installed, name); Log(LOG_LEVEL_VERBOSE, "%d patch(es) match the promise body's criteria fully", matches); SchedulePackageOp(ctx, name, version, arch, installed, matches, no_version, a, pp); return PROMISE_RESULT_NOOP; } /** @brief Verifies a promised package operation as defined by a and pp Called by VerifyPackagesPromise for any non-patch operation. * package name is pp->promiser * promise result starts as NOOP * if package version is given * * if no architecture given, the promise result comes from CheckPackageState with name, version, any architecture '*', no_version=false * * else if architectures were given, the promise result comes from CheckPackageState with name, version, arch, no_version=false FOR EACH ARCHITECTURE * else if package_version_regex is given * * assume that package_name_regex and package_arch_regex are also given and use the 3 regexes to extract name, version, arch * * if the arch extraction failed, use any architecture '*' * * the promise result comes from CheckPackageState with name, version, arch, no_version=false) * else (no explicit version is given) (SAME LOOP AS EXPLICIT VERSION LOOP ABOVE) * * if no architecture given, the promise result comes from CheckPackageState with name, any version "*", any architecture '*', no_version=true * * else if architectures were given, the promise result comes from CheckPackageState with name, any version "*", arch, no_version=true FOR EACH ARCHITECTURE @param ctx [in] The evaluation context @param a [in] the Attributes specifying how to compare @param pp [in] the Promise for this operation @returns the promise result as set by CheckPackageState */ static PromiseResult VerifyPromisedPackage(EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(a != NULL); assert(pp != NULL); const char *package = pp->promiser; const Packages *const pkgs = &(a->packages); PromiseResult result = PROMISE_RESULT_NOOP; if (pkgs->package_version) { /* The version is specified separately */ Log(LOG_LEVEL_VERBOSE, "Package version %s specified explicitly in promise body", pkgs->package_version); if (pkgs->package_architectures == NULL) { Log(LOG_LEVEL_VERBOSE, " ... trying any arch '*'"); result = PromiseResultUpdate_HELPER(pp, result, CheckPackageState(ctx, a, pp, package, pkgs->package_version, "*", false)); } else { for (Rlist *rp = pkgs->package_architectures; rp != NULL; rp = rp->next) { Log(LOG_LEVEL_VERBOSE, " ... trying listed arch '%s'", RlistScalarValue(rp)); result = PromiseResultUpdate_HELPER(pp, result, CheckPackageState(ctx, a, pp, package, pkgs->package_version, RlistScalarValue(rp), false)); } } } else if (pkgs->package_version_regex) { /* The name, version and arch are to be extracted from the promiser */ Log(LOG_LEVEL_VERBOSE, "Package version %s specified implicitly in promiser's name", pkgs->package_version_regex); char version[CF_MAXVARSIZE]; char name[CF_MAXVARSIZE]; char arch[CF_MAXVARSIZE]; strlcpy(version, ExtractFirstReference(pkgs->package_version_regex, package), CF_MAXVARSIZE); strlcpy(name, ExtractFirstReference(pkgs->package_name_regex, package), CF_MAXVARSIZE); strlcpy(arch, ExtractFirstReference(pkgs->package_arch_regex, package), CF_MAXVARSIZE); if (!arch[0]) { strlcpy(arch, "*", CF_MAXVARSIZE); } if (strcmp(arch, "CF_NOMATCH") == 0) // no match on arch regex, use any arch { strlcpy(arch, "*", CF_MAXVARSIZE); } Log(LOG_LEVEL_VERBOSE, " ... trying arch '%s' and version '%s'", arch, version); result = PromiseResultUpdate_HELPER(pp, result, CheckPackageState(ctx, a, pp, name, version, arch, false)); } else { Log(LOG_LEVEL_VERBOSE, "Package version was not specified"); if (pkgs->package_architectures == NULL) { Log(LOG_LEVEL_VERBOSE, " ... trying any arch '*' and any version '*'"); result = PromiseResultUpdate_HELPER(pp, result, CheckPackageState(ctx, a, pp, package, "*", "*", true)); } else { for (Rlist *rp = pkgs->package_architectures; rp != NULL; rp = rp->next) { Log(LOG_LEVEL_VERBOSE, " ... trying listed arch '%s' and any version '*'", RlistScalarValue(rp)); result = PromiseResultUpdate_HELPER(pp, result, CheckPackageState(ctx, a, pp, package, "*", RlistScalarValue(rp), true)); } } } return result; } /** Execute scheduled operations **/ /** @brief Central dispatcher for scheduled operations Called by ExecutePackageSchedule. Almost identical to ExecutePatch. * verify = false * for each PackageManager pm in the schedule * * if pm->pack_list is empty or the scheduled pm->action doesn't match the given action, skip this pm * * estimate the size of the command string from pm->pack_list and pm->policy (SHOULD USE Buffer) * * from the first PackageItem in pm->pack_list, get the Promise pp and its Attributes a * * switch(action) * * * case ADD: * * * * command_string = a.packages.package_add_command + estimated_size room for package names * * * case DELETE: * * * * command_string = a.packages.package_delete_command + estimated_size room for package names * * * case UPDATE: * * * * command_string = a.packages.package_update_command + estimated_size room for package names * * * case VERIFY: * * * * command_string = a.packages.package_verify_command + estimated_size room for package names * * * * verify = true * * if the command string ends with $, run it with ExecPackageCommand(command, verify) and magic the promise evaluation * * else, switch(pm->policy) * * * case INDIVIDUAL: * * * * for each PackageItem in the pack_list, build the command and run it with ExecPackageCommand(command, verify) and magic the promise evaluation * * * * NOTE with file repositories and ADD/UPDATE operations, the package name gets the repo path too * * * * NOTE special treatment of PACKAGE_IGNORED_CFE_INTERNAL * * * case BULK: * * * * for all PackageItems in the pack_list, build the command and run it with ExecPackageCommand(command, verify) and magic the promise evaluation * * * * NOTE with file repositories and ADD/UPDATE operations, the package name gets the repo path too * * * * NOTE special treatment of PACKAGE_IGNORED_CFE_INTERNAL * * clean up command_string * if the operation was not a verification, InvalidateSoftwareCache @param ctx [in] The evaluation context @param schedule [in] the PackageManager list with the operations schedule @param action [in] the PackageAction desired @returns boolean success/fail (fail only on ProgrammingError, should never happen) */ static bool ExecuteSchedule(EvalContext *ctx, const PackageManager *schedule, PackageAction action) { bool verify = false; for (const PackageManager *pm = schedule; pm != NULL; pm = pm->next) { if (pm->action != action) { continue; } if (pm->pack_list == NULL) { continue; } size_t estimated_size = 0; for (const PackageItem *pi = pm->pack_list; pi != NULL; pi = pi->next) { size_t size = strlen(pi->name) + strlen(" "); switch (pm->policy) { case PACKAGE_ACTION_POLICY_INDIVIDUAL: if (size > estimated_size) { estimated_size = size + CF_MAXVARSIZE; } break; case PACKAGE_ACTION_POLICY_BULK: estimated_size += size + CF_MAXVARSIZE; break; default: break; } } const Promise *const pp = pm->pack_list->pp; Attributes a = GetPackageAttributes(ctx, pp); char *command_string = NULL; switch (action) { case PACKAGE_ACTION_ADD: Log(LOG_LEVEL_VERBOSE, "Execute scheduled package addition"); if (a.packages.package_add_command == NULL) { ProgrammingError("Package add command undefined"); return false; } Log(LOG_LEVEL_INFO, "Installing %-.39s...", pp->promiser); estimated_size += strlen(a.packages.package_add_command) + 2; command_string = xmalloc(estimated_size); strcpy(command_string, a.packages.package_add_command); break; case PACKAGE_ACTION_DELETE: Log(LOG_LEVEL_VERBOSE, "Execute scheduled package deletion"); if (a.packages.package_delete_command == NULL) { ProgrammingError("Package delete command undefined"); return false; } Log(LOG_LEVEL_INFO, "Deleting %-.39s...", pp->promiser); estimated_size += strlen(a.packages.package_delete_command) + 2; command_string = xmalloc(estimated_size); strcpy(command_string, a.packages.package_delete_command); break; case PACKAGE_ACTION_UPDATE: Log(LOG_LEVEL_VERBOSE, "Execute scheduled package update"); if (a.packages.package_update_command == NULL) { ProgrammingError("Package update command undefined"); return false; } Log(LOG_LEVEL_INFO, "Updating %-.39s...", pp->promiser); estimated_size += strlen(a.packages.package_update_command) + 2; command_string = xcalloc(1, estimated_size); strcpy(command_string, a.packages.package_update_command); break; case PACKAGE_ACTION_VERIFY: Log(LOG_LEVEL_VERBOSE, "Execute scheduled package verification"); if (a.packages.package_verify_command == NULL) { ProgrammingError("Package verify command undefined"); return false; } estimated_size += strlen(a.packages.package_verify_command) + 2; command_string = xmalloc(estimated_size); strcpy(command_string, a.packages.package_verify_command); verify = true; break; default: ProgrammingError("Unknown action attempted"); return false; } /* if the command ends with $ then we assume the package manager does not accept package names */ if (*(command_string + strlen(command_string) - 1) == '$') { *(command_string + strlen(command_string) - 1) = '\0'; Log(LOG_LEVEL_VERBOSE, "Command does not allow arguments"); PromiseResult result = PROMISE_RESULT_NOOP; EvalContextStackPushPromiseFrame(ctx, pp); if (EvalContextStackPushPromiseIterationFrame(ctx, NULL)) { if (ExecPackageCommand(ctx, command_string, verify, true, &a, pp, &result)) { Log(LOG_LEVEL_VERBOSE, "Package schedule execution ok (outcome cannot be promised by cf-agent)"); } else { Log(LOG_LEVEL_ERR, "Package schedule execution failed"); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); EvalContextLogPromiseIterationOutcome(ctx, pp, result); } else { strcat(command_string, " "); Log(LOG_LEVEL_VERBOSE, "Command prefix '%s'", command_string); if (pm->policy == PACKAGE_ACTION_POLICY_INDIVIDUAL) { for (const PackageItem *pi = pm->pack_list; pi != NULL; pi = pi->next) { const Promise *const ppi = pi->pp; Attributes a = GetPackageAttributes(ctx, ppi); const size_t command_len = strlen(command_string); char *offset = command_string + command_len; if ((a.packages.package_file_repositories) && ((action == PACKAGE_ACTION_ADD) || (action == PACKAGE_ACTION_UPDATE))) { const char *sp = PrefixLocalRepository(a.packages.package_file_repositories, pi->name); if (sp != NULL) { strlcat(offset, sp, estimated_size - command_len); } else { continue; } } else { strcat(offset, pi->name); } PromiseResult result = PROMISE_RESULT_NOOP; EvalContextStackPushPromiseFrame(ctx, ppi); if (EvalContextStackPushPromiseIterationFrame(ctx, NULL)) { bool ok = ExecPackageCommand(ctx, command_string, verify, true, &a, ppi, &result); if (StringEqual(pi->name, PACKAGE_IGNORED_CFE_INTERNAL)) { Log(LOG_LEVEL_DEBUG, "ExecuteSchedule: Ignoring outcome for special package '%s'", pi->name); } else if (ok) { Log(LOG_LEVEL_VERBOSE, "Package schedule execution ok for '%s' (outcome cannot be promised by cf-agent)", pi->name); } else { Log(LOG_LEVEL_ERR, "Package schedule execution failed for '%s'", pi->name); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); EvalContextLogPromiseIterationOutcome(ctx, ppi, result); *offset = '\0'; } } else if (pm->policy == PACKAGE_ACTION_POLICY_BULK) { for (const PackageItem *pi = pm->pack_list; pi != NULL; pi = pi->next) { if (pi->name) { const size_t command_len = strlen(command_string); char *offset = command_string + command_len; if (a.packages.package_file_repositories && (action == PACKAGE_ACTION_ADD || action == PACKAGE_ACTION_UPDATE)) { const char *sp = PrefixLocalRepository(a.packages.package_file_repositories, pi->name); if (sp != NULL) { strlcpy(offset, sp, estimated_size - command_len); } else { break; } } else { strcpy(offset, pi->name); } strcat(command_string, " "); } } PromiseResult result = PROMISE_RESULT_NOOP; EvalContextStackPushPromiseFrame(ctx, pp); if (EvalContextStackPushPromiseIterationFrame(ctx, NULL)) { bool ok = ExecPackageCommand(ctx, command_string, verify, true, &a, pp, &result); for (const PackageItem *pi = pm->pack_list; pi != NULL; pi = pi->next) { if (StringEqual(pi->name, PACKAGE_IGNORED_CFE_INTERNAL)) { Log(LOG_LEVEL_DEBUG, "ExecuteSchedule: Ignoring outcome for special package '%s'", pi->name); } else if (ok) { Log(LOG_LEVEL_VERBOSE, "Bulk package schedule execution ok for '%s' (outcome cannot be promised by cf-agent)", pi->name); } else { Log(LOG_LEVEL_ERR, "Bulk package schedule execution failed somewhere - unknown outcome for '%s'", pi->name); } } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); EvalContextLogPromiseIterationOutcome(ctx, pp, result); } } if (command_string) { free(command_string); } } /* We have performed some modification operation on packages, our cache is invalid */ if (!verify) { InvalidateSoftwareCache(); } return true; } /** @brief Central dispatcher for scheduled patch operations Called by ExecutePackageSchedule. Almost identical to ExecuteSchedule except it only accepts the PATCH PackageAction and operates on the PackageManagers' patch_list. * for each PackageManager pm in the schedule * * if pm->patch_list is empty or the scheduled pm->action doesn't match the given action, skip this pm * * estimate the size of the command string from pm->patch_list and pm->policy (SHOULD USE Buffer) * * from the first PackageItem in pm->patch_list, get the Promise pp and its Attributes a * * switch(action) * * * case PATCH: * * * * command_string = a.packages.package_patch_command + estimated_size room for package names * * if the command string ends with $, run it with ExecPackageCommand(command, verify) and magic the promise evaluation * * else, switch(pm->policy) * * * case INDIVIDUAL: * * * * for each PackageItem in the patch_list, build the command and run it with ExecPackageCommand(command, verify) and magic the promise evaluation * * * * NOTE with file repositories and ADD/UPDATE operations, the package name gets the repo path too * * * * NOTE special treatment of PACKAGE_IGNORED_CFE_INTERNAL * * * case BULK: * * * * for all PackageItems in the patch_list, build the command and run it with ExecPackageCommand(command, verify) and magic the promise evaluation * * * * NOTE with file repositories and ADD/UPDATE operations, the package name gets the repo path too * * * * NOTE special treatment of PACKAGE_IGNORED_CFE_INTERNAL * * clean up command_string * InvalidateSoftwareCache @param ctx [in] The evaluation context @param schedule [in] the PackageManager list with the operations schedule @param action [in] the PackageAction desired @returns boolean success/fail (fail only on ProgrammingError, should never happen) */ static bool ExecutePatch(EvalContext *ctx, const PackageManager *schedule, PackageAction action) { for (const PackageManager *pm = schedule; pm != NULL; pm = pm->next) { if (pm->action != action) { continue; } if (pm->patch_list == NULL) { continue; } size_t estimated_size = 0; for (const PackageItem *pi = pm->patch_list; pi != NULL; pi = pi->next) { size_t size = strlen(pi->name) + strlen(" "); switch (pm->policy) { case PACKAGE_ACTION_POLICY_INDIVIDUAL: if (size > estimated_size) { estimated_size = size; } break; case PACKAGE_ACTION_POLICY_BULK: estimated_size += size; break; default: break; } } char *command_string = NULL; const Promise *const pp = pm->patch_list->pp; Attributes a = GetPackageAttributes(ctx, pp); if (action == PACKAGE_ACTION_PATCH) { Log(LOG_LEVEL_VERBOSE, "Execute scheduled package patch"); if (a.packages.package_patch_command == NULL) { ProgrammingError("Package patch command undefined"); return false; } command_string = xmalloc(estimated_size + strlen(a.packages.package_patch_command) + 2); strcpy(command_string, a.packages.package_patch_command); } else { ProgrammingError("Unknown action attempted"); return false; } /* if the command ends with $ then we assume the package manager does not accept package names */ if (command_string[strlen(command_string) - 1] == '$') { command_string[strlen(command_string) - 1] = '\0'; Log(LOG_LEVEL_VERBOSE, "Command does not allow arguments"); PromiseResult result = PROMISE_RESULT_NOOP; EvalContextStackPushPromiseFrame(ctx, pp); if (EvalContextStackPushPromiseIterationFrame(ctx, NULL)) { if (ExecPackageCommand(ctx, command_string, false, true, &a, pp, &result)) { Log(LOG_LEVEL_VERBOSE, "Package patching seemed to succeed (outcome cannot be promised by cf-agent)"); } else { Log(LOG_LEVEL_ERR, "Package patching failed"); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); EvalContextLogPromiseIterationOutcome(ctx, pp, result); } else { strcat(command_string, " "); Log(LOG_LEVEL_VERBOSE, "Command prefix '%s'", command_string); switch (pm->policy) { case PACKAGE_ACTION_POLICY_INDIVIDUAL: for (const PackageItem *pi = pm->patch_list; pi != NULL; pi = pi->next) { char *offset = command_string + strlen(command_string); strcat(offset, pi->name); PromiseResult result = PROMISE_RESULT_NOOP; EvalContextStackPushPromiseFrame(ctx, pp); if (EvalContextStackPushPromiseIterationFrame(ctx, NULL)) { bool ok = ExecPackageCommand(ctx, command_string, false, true, &a, pp, &result); if (StringEqual(pi->name, PACKAGE_IGNORED_CFE_INTERNAL)) { Log(LOG_LEVEL_DEBUG, "ExecutePatch: Ignoring outcome for special package '%s'", pi->name); } else if (ok) { Log(LOG_LEVEL_VERBOSE, "Package schedule execution ok for '%s' (outcome cannot be promised by cf-agent)", pi->name); } else { Log(LOG_LEVEL_ERR, "Package schedule execution failed for '%s'", pi->name); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); EvalContextLogPromiseIterationOutcome(ctx, pp, result); *offset = '\0'; } break; case PACKAGE_ACTION_POLICY_BULK: for (const PackageItem *pi = pm->patch_list; pi != NULL; pi = pi->next) { if (pi->name) { strcat(command_string, pi->name); strcat(command_string, " "); } } PromiseResult result = PROMISE_RESULT_NOOP; EvalContextStackPushPromiseFrame(ctx, pp); if (EvalContextStackPushPromiseIterationFrame(ctx, NULL)) { bool ok = ExecPackageCommand(ctx, command_string, false, true, &a, pp, &result); for (const PackageItem *pi = pm->patch_list; pi != NULL; pi = pi->next) { if (StringEqual(pi->name, PACKAGE_IGNORED_CFE_INTERNAL)) { Log(LOG_LEVEL_DEBUG, "ExecutePatch: Ignoring outcome for special package '%s'", pi->name); } else if (ok) { Log(LOG_LEVEL_VERBOSE, "Bulk package schedule execution ok for '%s' (outcome cannot be promised by cf-agent)", pi->name); } else { Log(LOG_LEVEL_ERR, "Bulk package schedule execution failed somewhere - unknown outcome for '%s'", pi->name); } } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); EvalContextLogPromiseIterationOutcome(ctx, pp, result); break; default: break; } } if (command_string) { free(command_string); } } /* We have performed some operation on packages, our cache is invalid */ InvalidateSoftwareCache(); return true; } /** @brief Ordering manager for scheduled package operations Called by ExecuteScheduledPackages. * ExecuteSchedule(schedule, DELETE) * ExecuteSchedule(schedule, ADD) * ExecuteSchedule(schedule, UPDATE) * ExecutePatch(schedule, PATCH) * ExecuteSchedule(schedule, VERIFY) @param ctx [in] The evaluation context @param schedule [in] the PackageManager list with the operations schedule */ static void ExecutePackageSchedule(EvalContext *ctx, PackageManager *schedule) { Log(LOG_LEVEL_VERBOSE, "Offering the following package-promise suggestions to the managers"); /* Normal ordering */ Log(LOG_LEVEL_VERBOSE, "Deletion schedule..."); if (!ExecuteSchedule(ctx, schedule, PACKAGE_ACTION_DELETE)) { Log(LOG_LEVEL_ERR, "Aborting package schedule"); return; } Log(LOG_LEVEL_VERBOSE, "Addition schedule..."); if (!ExecuteSchedule(ctx, schedule, PACKAGE_ACTION_ADD)) { return; } Log(LOG_LEVEL_VERBOSE, "Update schedule..."); if (!ExecuteSchedule(ctx, schedule, PACKAGE_ACTION_UPDATE)) { return; } Log(LOG_LEVEL_VERBOSE, "Patch schedule..."); if (!ExecutePatch(ctx, schedule, PACKAGE_ACTION_PATCH)) { return; } Log(LOG_LEVEL_VERBOSE, "Verify schedule..."); if (!ExecuteSchedule(ctx, schedule, PACKAGE_ACTION_VERIFY)) { return; } } /** * @brief Execute the full package schedule. * * Called by cf-agent only. * */ void ExecuteScheduledPackages(EvalContext *ctx) { if (PACKAGE_SCHEDULE) { ExecutePackageSchedule(ctx, PACKAGE_SCHEDULE); } } /** Cleanup **/ /** * @brief Clean the package schedule and installed lists. * * Called by cf-agent only. Cleans bookkeeping data. * */ void CleanScheduledPackages(void) { DeletePackageManagers(PACKAGE_SCHEDULE); PACKAGE_SCHEDULE = NULL; DeletePackageManagers(INSTALLED_PACKAGE_LISTS); INSTALLED_PACKAGE_LISTS = NULL; } /** Utils **/ static PackageManager *GetPackageManager(PackageManager **lists, char *mgr, PackageAction pa, PackageActionPolicy policy) { PackageManager *np; Log(LOG_LEVEL_VERBOSE, "Looking for a package manager called '%s'", mgr); if (mgr == NULL || mgr[0] == '\0') { Log(LOG_LEVEL_ERR, "Attempted to create a package manager with no name"); return NULL; } for (np = *lists; np != NULL; np = np->next) { if ((strcmp(np->manager, mgr) == 0) && (policy == np->policy)) { return np; } } np = xcalloc(1, sizeof(PackageManager)); np->manager = xstrdup(mgr); np->action = pa; np->policy = policy; np->next = *lists; *lists = np; return np; } static void DeletePackageItems(PackageItem * pi) { while (pi != NULL) { PackageItem *next = pi->next; free(pi->name); free(pi->version); free(pi->arch); PromiseDestroy(pi->pp); free(pi); pi = next; } } static void DeletePackageManagers(PackageManager *np) { while (np != NULL) { PackageManager *next = np->next; DeletePackageItems(np->pack_list); DeletePackageItems(np->patch_list); DeletePackageItems(np->patch_avail); free(np->manager); free(np); np = next; } } const char *PrefixLocalRepository(const Rlist *repositories, const char *package) { static char quotedPath[CF_MAXVARSIZE]; /* GLOBAL_R, no need to initialize */ struct stat sb; char path[sizeof(quotedPath) - 2]; for (const Rlist *rp = repositories; rp != NULL; rp = rp->next) { if (strlcpy(path, RlistScalarValue(rp), sizeof(path)) < sizeof(path)) { AddSlash(path); if (strlcat(path, package, sizeof(path)) < sizeof(path) && stat(path, &sb) != -1) { snprintf(quotedPath, sizeof(quotedPath), "\"%s\"", path); return quotedPath; } } } return NULL; } bool ExecPackageCommand(EvalContext *ctx, char *command, int verify, int setCmdClasses, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); // Dereferenced by cfPS macros bool retval = true; char *cmd; FILE *pfp; int packmanRetval = 0; if ((!a->packages.package_commands_useshell) && (!IsExecutable(CommandArg0(command)))) { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "The proposed package schedule command '%s' was not executable", command); *result = PromiseResultUpdate_HELPER(pp, *result, PROMISE_RESULT_FAIL); return false; } if (DONTDO) { return true; } /* Use this form to avoid limited, intermediate argument processing - long lines */ if (a->packages.package_commands_useshell) { Log(LOG_LEVEL_VERBOSE, "Running %s in shell", command); if ((pfp = cf_popen_sh(command, "r")) == NULL) { cfPS_HELPER_2ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Couldn't start command '%20s'. (cf_popen_sh: %s)", command, GetErrorStr()); *result = PromiseResultUpdate_HELPER(pp, *result, PROMISE_RESULT_FAIL); return false; } } else { if ((pfp = cf_popen(command, "r", true)) == NULL) { cfPS_HELPER_2ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Couldn't start command '%20s'. (cf_popen: %s)", command, GetErrorStr()); *result = PromiseResultUpdate_HELPER(pp, *result, PROMISE_RESULT_FAIL); return false; } } Log(LOG_LEVEL_VERBOSE, "Executing %-.60s...", command); /* Look for short command summary */ for (cmd = command; (*cmd != '\0') && (*cmd != ' '); cmd++) { } while (cmd > command && cmd[-1] != FILE_SEPARATOR) { cmd--; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = CfReadLine(&line, &line_size, pfp); if (res == -1) { if (!feof(pfp)) { cfPS_HELPER_2ARG(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to read output from command '%20s'. (fread: %s)", command, GetErrorStr()); *result = PromiseResultUpdate_HELPER(pp, *result, PROMISE_RESULT_FAIL); cf_pclose(pfp); free(line); return false; } else { break; } } /* Need space for 2x buffer and null byte. */ char lineSafe[res * 2 + 1]; memcpy(lineSafe, line, res + 1); ssize_t replace_res = StringReplace(lineSafe, sizeof(lineSafe), "%", "%%"); if (replace_res == -1) { ProgrammingError("StringReplace(): buffer overflow in %s", __FILE__); continue; } Log(LOG_LEVEL_INFO, "Q:%20.20s ...:%s", cmd, lineSafe); if (verify && (line[0] != '\0')) { if (a->packages.package_noverify_regex) { if (FullTextMatch(ctx, a->packages.package_noverify_regex, line)) { cfPS_HELPER_2ARG(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_FAIL, pp, a, "Package verification error in %-.40s ... :%s", cmd, lineSafe); *result = PromiseResultUpdate_HELPER(pp, *result, PROMISE_RESULT_FAIL); retval = false; } } } } free(line); packmanRetval = cf_pclose(pfp); if (verify && (a->packages.package_noverify_returncode != CF_NOINT)) { if (a->packages.package_noverify_returncode == packmanRetval) { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_FAIL, pp, a, "Package verification error (returned %d)", packmanRetval); *result = PromiseResultUpdate_HELPER(pp, *result, PROMISE_RESULT_FAIL); retval = false; } else { cfPS_HELPER_1ARG(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_NOOP, pp, a, "Package verification succeeded (returned %d)", packmanRetval); *result = PromiseResultUpdate_HELPER(pp, *result, PROMISE_RESULT_FAIL); } } else if (verify && (a->packages.package_noverify_regex)) { if (retval) // set status if we succeeded above { cfPS_HELPER_0ARG(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_NOOP, pp, a, "Package verification succeeded (no match with package_noverify_regex)"); } } else if (setCmdClasses) // generic return code check { if (REPORT_THIS_PROMISE(pp)) { retval = VerifyCommandRetcode(ctx, packmanRetval, a, pp, result); } } return retval; } bool PrependPackageItem( EvalContext *ctx, PackageItem ** list, const char *name, const char *version, const char *arch, const Promise *pp) { if (!list || !name[0] || !version[0] || !arch[0]) { return false; } Log(LOG_LEVEL_VERBOSE, "Package (%s,%s,%s) [name,version,arch] found", name, version, arch); PackageItem *pi = xmalloc(sizeof(PackageItem)); pi->next = *list; pi->name = xstrdup(name); pi->version = xstrdup(version); pi->arch = xstrdup(arch); *list = pi; /* Finally we need these for later schedule exec, once this iteration context has gone */ pi->pp = DeRefCopyPromise(ctx, pp); return true; } static bool PackageInItemList( PackageItem * list, char *name, char *version, char *arch) { if (!name[0] || !version[0] || !arch[0]) { return false; } for (PackageItem *pi = list; pi != NULL; pi = pi->next) { if (strcmp(pi->name, name) == 0 && strcmp(pi->version, version) == 0 && strcmp(pi->arch, arch) == 0) { return true; } } return false; } static bool PrependPatchItem( EvalContext *ctx, PackageItem ** list, char *item, PackageItem * chklist, const char *default_arch, const Attributes *a, const Promise *pp) { assert(a != NULL); char name[CF_MAXVARSIZE]; char arch[CF_MAXVARSIZE]; char version[CF_MAXVARSIZE]; char vbuff[CF_MAXVARSIZE]; strlcpy(vbuff, ExtractFirstReference(a->packages.package_patch_name_regex, item), CF_MAXVARSIZE); sscanf(vbuff, "%s", name); /* trim */ strlcpy(vbuff, ExtractFirstReference(a->packages.package_patch_version_regex, item), CF_MAXVARSIZE); sscanf(vbuff, "%s", version); /* trim */ if (a->packages.package_patch_arch_regex) { strlcpy(vbuff, ExtractFirstReference(a->packages.package_patch_arch_regex, item), CF_MAXVARSIZE ); sscanf(vbuff, "%s", arch); /* trim */ } else { strlcpy(arch, default_arch, CF_MAXVARSIZE ); } if ((strcmp(name, "CF_NOMATCH") == 0) || (strcmp(version, "CF_NOMATCH") == 0) || (strcmp(arch, "CF_NOMATCH") == 0)) { return false; } Log(LOG_LEVEL_DEBUG, "PrependPatchItem: Patch line '%s', with name '%s', version '%s', arch '%s'", item, name, version, arch); if (PackageInItemList(chklist, name, version, arch)) { Log(LOG_LEVEL_VERBOSE, "Patch for (%s,%s,%s) [name,version,arch] found, but it appears to be installed already", name, version, arch); return false; } return PrependPackageItem(ctx, list, name, version, arch, pp); } static bool PrependMultiLinePackageItem( EvalContext *ctx, PackageItem ** list, char *item, int reset, const char *default_arch, const Attributes *a, const Promise *pp) { assert(a != NULL); static char name[CF_MAXVARSIZE] = ""; /* GLOBAL_X */ static char arch[CF_MAXVARSIZE] = ""; /* GLOBAL_X */ static char version[CF_MAXVARSIZE] = ""; /* GLOBAL_X */ static char vbuff[CF_MAXVARSIZE] = ""; /* GLOBAL_X */ if (reset) { if ((strcmp(name, "CF_NOMATCH") == 0) || (strcmp(version, "CF_NOMATCH") == 0)) { return false; } if ((strcmp(name, "") != 0) || (strcmp(version, "") != 0)) { Log(LOG_LEVEL_DEBUG, "PrependMultiLinePackageItem: Extracted package name '%s', version '%s', arch '%s'", name, version, arch); PrependPackageItem(ctx, list, name, version, arch, pp); } strcpy(name, "CF_NOMATCH"); strcpy(version, "CF_NOMATCH"); strcpy(arch, default_arch); } if (FullTextMatch(ctx, a->packages.package_list_name_regex, item)) { strlcpy(vbuff, ExtractFirstReference(a->packages.package_list_name_regex, item), CF_MAXVARSIZE); sscanf(vbuff, "%s", name); /* trim */ } if (FullTextMatch(ctx, a->packages.package_list_version_regex, item)) { strlcpy(vbuff, ExtractFirstReference(a->packages.package_list_version_regex, item), CF_MAXVARSIZE ); sscanf(vbuff, "%s", version); /* trim */ } if ((a->packages.package_list_arch_regex) && (FullTextMatch(ctx, a->packages.package_list_arch_regex, item))) { if (a->packages.package_list_arch_regex) { strlcpy(vbuff, ExtractFirstReference(a->packages.package_list_arch_regex, item), CF_MAXVARSIZE); sscanf(vbuff, "%s", arch); /* trim */ } } return true; } static bool PrependListPackageItem( EvalContext *ctx, PackageItem **list, char *item, const char *default_arch, const Attributes *a, const Promise *pp) { assert(a != NULL); char name[CF_MAXVARSIZE]; char arch[CF_MAXVARSIZE]; char version[CF_MAXVARSIZE]; char vbuff[CF_MAXVARSIZE]; strlcpy(vbuff, ExtractFirstReference(a->packages.package_list_name_regex, item), CF_MAXVARSIZE); sscanf(vbuff, "%s", name); /* trim */ strlcpy(vbuff, ExtractFirstReference(a->packages.package_list_version_regex, item), CF_MAXVARSIZE); sscanf(vbuff, "%s", version); /* trim */ if (a->packages.package_list_arch_regex) { strlcpy(vbuff, ExtractFirstReference(a->packages.package_list_arch_regex, item), CF_MAXVARSIZE); sscanf(vbuff, "%s", arch); /* trim */ } else { strlcpy(arch, default_arch, CF_MAXVARSIZE); } if ((strcmp(name, "CF_NOMATCH") == 0) || (strcmp(version, "CF_NOMATCH") == 0) || (strcmp(arch, "CF_NOMATCH") == 0)) { return false; } Log(LOG_LEVEL_DEBUG, "PrependListPackageItem: Package line '%s', name '%s', version '%s', arch '%s'", item, name, version, arch); return PrependPackageItem(ctx, list, name, version, arch, pp); } static char *GetDefaultArch(const char *command) { if (command == NULL) { return xstrdup("default"); } Log(LOG_LEVEL_VERBOSE, "Obtaining default architecture for package manager '%s'", command); FILE *fp = cf_popen_sh(command, "r"); if (fp == NULL) { return NULL; } size_t arch_size = CF_SMALLBUF; char *arch = xmalloc(arch_size); ssize_t res = CfReadLine(&arch, &arch_size, fp); if (res == -1) { cf_pclose(fp); free(arch); return NULL; } Log(LOG_LEVEL_VERBOSE, "Default architecture for package manager is '%s'", arch); cf_pclose(fp); return arch; } cfengine-3.24.2/cf-agent/verify_users_stub.c0000644000000000000000000000315415010704253020770 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include void VerifyOneUsersPromise ( ARG_UNUSED const char *puser, ARG_UNUSED const User *u, ARG_UNUSED PromiseResult *result, ARG_UNUSED enum cfopaction action, ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Attributes *a, ARG_UNUSED const Promise *pp) { Log(LOG_LEVEL_ERR, "Users promise type is not supported on this OS"); } bool IsAccountLocked( ARG_UNUSED const char *puser, ARG_UNUSED const void *passwd_info) { return false; } bool GetPasswordHash( ARG_UNUSED const char *puser, ARG_UNUSED const void *passwd_info, ARG_UNUSED const char **result) { return false; } cfengine-3.24.2/cf-agent/files_editline.h0000644000000000000000000000255315010704253020174 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_EDITLINE_H #define CFENGINE_FILES_EDITLINE_H #include #include bool ScheduleEditLineOperations(EvalContext *ctx, const Bundle *bp, const Attributes *a, const Promise *pp, EditContext *edcontext); Bundle *MakeTemporaryBundleFromTemplate(EvalContext *ctx, Policy *policy, const Attributes *a, const Promise *pp, PromiseResult *result); #endif cfengine-3.24.2/cf-agent/retcode.c0000644000000000000000000001044215010704253016631 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include bool VerifyCommandRetcode(EvalContext *ctx, int retcode, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); bool result_retcode = true; if (a->classes.retcode_kept || a->classes.retcode_repaired || a->classes.retcode_failed) { int matched = false; char retcodeStr[PRINTSIZE(retcode)]; xsnprintf(retcodeStr, sizeof(retcodeStr), "%d", retcode); LogLevel info_or_verbose = LOG_LEVEL_INFO; // inform constraint is only for commands promises, // a->inform is actually false for other promise types, so // checking the promise type here is important: if (StringEqual("commands", PromiseGetPromiseType(pp)) && (!a->inform)) { // for commands promises which don't make changes to the system, // you can use this to make the log messages verbose: // inform => "false"; info_or_verbose = LOG_LEVEL_VERBOSE; } if (RlistKeyIn(a->classes.retcode_kept, retcodeStr)) { cfPS(ctx, info_or_verbose, PROMISE_RESULT_NOOP, pp, a, "Command related to promiser '%s' returned code '%d' defined as promise kept", pp->promiser, retcode); matched = true; } if (RlistKeyIn(a->classes.retcode_repaired, retcodeStr)) { cfPS(ctx, info_or_verbose, PROMISE_RESULT_CHANGE, pp, a, "Command related to promiser '%s' returned code '%d' defined as promise repaired", pp->promiser, retcode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); matched = true; } if (RlistKeyIn(a->classes.retcode_failed, retcodeStr)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Command related to promiser '%s' returned code '%d' defined as promise failed", pp->promiser, retcode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); result_retcode = false; matched = true; } if (!matched) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Command related to promiser '%s' returned code '%d' not defined as promise kept, not kept or repaired; setting to failed", pp->promiser, retcode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); result_retcode = false; } } else // default: 0 is success, != 0 is failure { if (retcode == 0) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Finished command related to promiser '%s' -- succeeded", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Finished command related to promiser '%s' -- an error occurred, returned %d", pp->promiser, retcode); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); result_retcode = false; } } return result_retcode; } cfengine-3.24.2/cf-agent/verify_environments.c0000644000000000000000000010623515010704253021325 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_LIBVIRT /*****************************************************************************/ #include #include /*****************************************************************************/ enum cfhypervisors { cfv_virt_xen, cfv_virt_kvm, cfv_virt_esx, cfv_virt_vbox, cfv_virt_test, cfv_virt_xen_net, cfv_virt_kvm_net, cfv_virt_esx_net, cfv_virt_test_net, cfv_zone, cfv_ec2, cfv_eucalyptus, cfv_none }; /*****************************************************************************/ virConnectPtr CFVC[cfv_none]; #define CF_MAX_CONCURRENT_ENVIRONMENTS 256 int CF_RUNNING[CF_MAX_CONCURRENT_ENVIRONMENTS]; char *CF_SUSPENDED[CF_MAX_CONCURRENT_ENVIRONMENTS]; /*****************************************************************************/ static bool EnvironmentsSanityChecks(const Attributes *a, const Promise *pp); static PromiseResult VerifyEnvironments(EvalContext *ctx, const Attributes *a, const Promise *pp); static PromiseResult VerifyVirtDomain(EvalContext *ctx, char *uri, enum cfhypervisors envtype, const Attributes *a, const Promise *pp); static PromiseResult VerifyVirtNetwork(EvalContext *ctx, char *uri, enum cfhypervisors envtype, const Attributes *a, const Promise *pp); static PromiseResult CreateVirtDom(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp); static PromiseResult DeleteVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp); static PromiseResult RunningVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp); static PromiseResult SuspendedVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp); static PromiseResult DownVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp); static void EnvironmentErrorHandler(void); static void ShowRunList(virConnectPtr vc); static void ShowDormant(void); static PromiseResult CreateVirtNetwork(EvalContext *ctx, virConnectPtr vc, char **networks, const Attributes *a, const Promise *pp); static PromiseResult DeleteVirtNetwork(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp); static enum cfhypervisors Str2Hypervisors(char *s); /*****************************************************************************/ void NewEnvironmentsContext(void) { int i; for (i = 0; i < cfv_none; i++) { CFVC[i] = NULL; } } void DeleteEnvironmentsContext(void) { int i; for (i = 0; i < cfv_none; i++) { if (CFVC[i] != NULL) { virConnectClose(CFVC[i]); CFVC[i] = NULL; } } } /*****************************************************************************/ PromiseResult VerifyEnvironmentsPromise(EvalContext *ctx, const Promise *pp) { CfLock thislock; Attributes a = GetEnvironmentsAttributes(ctx, pp); PromiseResult result = PROMISE_RESULT_NOOP; if (EnvironmentsSanityChecks(&a, pp)) { thislock = AcquireLock(ctx, "virtual", VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, false); if (thislock.lock == NULL) { return PROMISE_RESULT_NOOP; } PromiseBanner(ctx, pp); bool excluded = false; Promise *pexp = ExpandDeRefPromise(ctx, pp, &excluded); if (excluded) { result = PROMISE_RESULT_SKIPPED; } else { result = VerifyEnvironments(ctx, &a, pp); } PromiseDestroy(pexp); YieldCurrentLock(thislock); } return result; } /*****************************************************************************/ static bool EnvironmentsSanityChecks(const Attributes *a, const Promise *pp) { assert(a != NULL); const Environments env = a->env; if (env.spec) { if (env.cpus != CF_NOINT || env.memory != CF_NOINT || env.disk != CF_NOINT) { Log(LOG_LEVEL_ERR, "Conflicting promise of both a spec and cpu/memory/disk resources"); return false; } } if (env.host == NULL) { Log(LOG_LEVEL_ERR, "No environment_host defined for environment promise"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } switch (Str2Hypervisors(env.type)) { case cfv_virt_xen_net: case cfv_virt_kvm_net: case cfv_virt_esx_net: case cfv_virt_test_net: if (env.cpus != CF_NOINT || env.memory != CF_NOINT || env.disk != CF_NOINT || env.name || env.addresses) { Log(LOG_LEVEL_ERR, "Network environment promises computational resources (%d,%d,%d,%s)", env.cpus, env.memory, env.disk, env.name); PromiseRef(LOG_LEVEL_ERR, pp); } break; default: break; } return true; } /*****************************************************************************/ static PromiseResult VerifyEnvironments(EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(a != NULL); char hyper_uri[CF_MAXVARSIZE]; enum cfhypervisors envtype = cfv_none; Environments env= a->env; switch (Str2Hypervisors(env.type)) { case cfv_virt_xen: case cfv_virt_xen_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "xen:///"); envtype = cfv_virt_xen; break; case cfv_virt_kvm: case cfv_virt_kvm_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "qemu:///session"); envtype = cfv_virt_kvm; break; case cfv_virt_esx: case cfv_virt_esx_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "esx://127.0.0.1"); envtype = cfv_virt_esx; break; case cfv_virt_test: case cfv_virt_test_net: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "test:///default"); envtype = cfv_virt_test; break; case cfv_virt_vbox: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "vbox:///session"); envtype = cfv_virt_vbox; break; case cfv_zone: snprintf(hyper_uri, CF_MAXVARSIZE - 1, "solaris_zone"); envtype = cfv_zone; break; default: Log(LOG_LEVEL_ERR, "Environment type '%s' not currently supported", env.type); return PROMISE_RESULT_NOOP; break; } Log(LOG_LEVEL_VERBOSE, "Selecting environment type '%s' '%s'", env.type, hyper_uri); ClassRef environment_host_ref = ClassRefParse(env.host); if (!EvalContextClassGet(ctx, environment_host_ref.ns, environment_host_ref.name)) { switch (env.state) { case ENVIRONMENT_STATE_CREATE: case ENVIRONMENT_STATE_RUNNING: Log(LOG_LEVEL_VERBOSE, "This host ''%s' is not the promised host for the environment '%s', so setting its intended state to 'down'", VFQNAME, env.host); env.state = ENVIRONMENT_STATE_DOWN; break; default: Log(LOG_LEVEL_VERBOSE, "This is not the promised host for the environment, but it does not promise a run state, so take promise as valid"); } } ClassRefDestroy(environment_host_ref); virInitialize(); PromiseResult result = PROMISE_RESULT_NOOP; #if defined(__linux__) switch (Str2Hypervisors(env.type)) { case cfv_virt_xen: case cfv_virt_kvm: case cfv_virt_esx: case cfv_virt_vbox: case cfv_virt_test: result = PromiseResultUpdate(result, VerifyVirtDomain(ctx, hyper_uri, envtype, a, pp)); break; case cfv_virt_xen_net: case cfv_virt_kvm_net: case cfv_virt_esx_net: case cfv_virt_test_net: result = PromiseResultUpdate(result, VerifyVirtNetwork(ctx, hyper_uri, envtype, a, pp)); break; case cfv_ec2: break; case cfv_eucalyptus: break; default: break; } #elif defined(__APPLE__) switch (Str2Hypervisors(env.type)) { case cfv_virt_vbox: case cfv_virt_test: result = PromiseResultUpdate(result, VerifyVirtDomain(ctx, hyper_uri, envtype, a, pp)); break; case cfv_virt_xen_net: case cfv_virt_kvm_net: case cfv_virt_esx_net: case cfv_virt_test_net: result = PromiseResultUpdate(result, VerifyVirtNetwork(ctx, hyper_uri, envtype, a, pp)); break; default: break; } #elif defined(__sun) switch (Str2Hypervisors(env.type)) { case cfv_zone: result = PromiseResultUpdate(result, VerifyZone(a, pp)); break; default: break; } #else Log(LOG_LEVEL_VERBOSE, "Unable to resolve an environment supervisor/monitor for this platform, aborting"); #endif return result; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static PromiseResult VerifyVirtDomain(EvalContext *ctx, char *uri, enum cfhypervisors envtype, const Attributes *a, const Promise *pp) { assert(a != NULL); int num, i; /* set up the library error handler */ virSetErrorFunc(NULL, (void *) EnvironmentErrorHandler); if (CFVC[envtype] == NULL) { if ((CFVC[envtype] = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0)) == NULL) { Log(LOG_LEVEL_ERR, "Failed to connect to virtualization monitor '%s'", uri); return PROMISE_RESULT_NOOP; } } for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++) { CF_RUNNING[i] = -1; CF_SUSPENDED[i] = NULL; } num = virConnectListDomains(CFVC[envtype], CF_RUNNING, CF_MAX_CONCURRENT_ENVIRONMENTS); Log(LOG_LEVEL_VERBOSE, "Found %d running guest environments on this host (including enclosure)", num); ShowRunList(CFVC[envtype]); num = virConnectListDefinedDomains(CFVC[envtype], CF_SUSPENDED, CF_MAX_CONCURRENT_ENVIRONMENTS); Log(LOG_LEVEL_VERBOSE, "Found %d dormant guest environments on this host", num); ShowDormant(); PromiseResult result = PROMISE_RESULT_NOOP; switch (a->env.state) { case ENVIRONMENT_STATE_CREATE: result = PromiseResultUpdate(result, CreateVirtDom(ctx, CFVC[envtype], a, pp)); break; case ENVIRONMENT_STATE_DELETE: result = PromiseResultUpdate(result, DeleteVirt(ctx, CFVC[envtype], a, pp)); break; case ENVIRONMENT_STATE_RUNNING: result = PromiseResultUpdate(result, RunningVirt(ctx, CFVC[envtype], a, pp)); break; case ENVIRONMENT_STATE_SUSPENDED: result = PromiseResultUpdate(result, SuspendedVirt(ctx, CFVC[envtype], a, pp)); break; case ENVIRONMENT_STATE_DOWN: result = PromiseResultUpdate(result, DownVirt(ctx, CFVC[envtype], a, pp)); break; default: Log(LOG_LEVEL_INFO, "No state specified for this environment"); break; } return result; } /*****************************************************************************/ static PromiseResult VerifyVirtNetwork(EvalContext *ctx, char *uri, enum cfhypervisors envtype, const Attributes *a, const Promise *pp) { assert(a != NULL); int num, i; char *networks[CF_MAX_CONCURRENT_ENVIRONMENTS]; if (CFVC[envtype] == NULL) { if ((CFVC[envtype] = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0)) == NULL) { Log(LOG_LEVEL_ERR, "Failed to connect to virtualization monitor '%s'", uri); return PROMISE_RESULT_NOOP; } } for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++) { networks[i] = NULL; } num = virConnectListNetworks(CFVC[envtype], networks, CF_MAX_CONCURRENT_ENVIRONMENTS); Log(LOG_LEVEL_VERBOSE, "Detected %d active networks", num); PromiseResult result = PROMISE_RESULT_NOOP; switch (a->env.state) { case ENVIRONMENT_STATE_CREATE: result = PromiseResultUpdate(result, CreateVirtNetwork(ctx, CFVC[envtype], networks, a, pp)); break; case ENVIRONMENT_STATE_DELETE: result = PromiseResultUpdate(result, DeleteVirtNetwork(ctx, CFVC[envtype], a, pp)); break; default: Log(LOG_LEVEL_INFO, "No recognized state specified for this network environment"); break; } return result; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static PromiseResult CreateVirtDom(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp) { assert(a != NULL); int alloc_file = false; char *xml_file; const char *name; char defaultxml[CF_MAXVARSIZE]; virDomainPtr dom; int i; snprintf(defaultxml, CF_MAXVARSIZE - 1, "" " %s" " 8388608" " 2097152" " 2" " " " hvm" " " "", pp->promiser); for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++) { if (CF_RUNNING[i] > 0) { dom = virDomainLookupByID(vc, CF_RUNNING[i]); name = virDomainGetName(dom); if (name && strcmp(name, pp->promiser) == 0) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Found a running environment called '%s' - promise kept", name); return PROMISE_RESULT_NOOP; } virDomainFree(dom); } } for (i = 0; CF_SUSPENDED[i] != NULL; i++) { if (strcmp(CF_SUSPENDED[i], pp->promiser) == 0) { Log(LOG_LEVEL_INFO, "Found an existing, but suspended, environment id = %s, called '%s'", CF_SUSPENDED[i], CF_SUSPENDED[i]); } } const Environments env = a->env; if (env.spec) { xml_file = xstrdup(env.spec); alloc_file = true; } else { Log(LOG_LEVEL_VERBOSE, "No spec file is promised, so reverting to default settings"); xml_file = defaultxml; } PromiseResult result = PROMISE_RESULT_NOOP; if ((dom = virDomainCreateXML(vc, xml_file, 0))) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Created a virtual domain '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); if (env.cpus != CF_NOINT) { int maxcpus; if ((maxcpus = virConnectGetMaxVcpus(vc, virConnectGetType(vc))) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't determine the available CPU resources"); } else { if (env.cpus > maxcpus) { Log(LOG_LEVEL_INFO, "The promise to allocate %d CPUs in domain '%s' cannot be kept - only %d exist on the host", env.cpus, pp->promiser, maxcpus); } else if (virDomainSetVcpus(dom, (unsigned int) env.cpus) == -1) { Log(LOG_LEVEL_INFO, "Unable to adjust CPU count to %d", env.cpus); } else { Log(LOG_LEVEL_INFO, "Verified that environment CPU count is now %d", env.cpus); } } } if (env.memory != CF_NOINT) { unsigned long maxmem; if ((maxmem = virDomainGetMaxMemory(dom)) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't determine the available CPU resources"); } else { if (virDomainSetMaxMemory(dom, (unsigned long) env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the memory limit to %d", env.memory); } else { Log(LOG_LEVEL_INFO, "Setting the memory limit to %d", env.memory); } if (virDomainSetMemory(dom, (unsigned long) env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the current memory to %d", env.memory); } } } if (env.disk != CF_NOINT) { Log(LOG_LEVEL_VERBOSE, "Info: env_disk parameter is not currently supported on this platform"); } virDomainFree(dom); } else { virErrorPtr vp; vp = virGetLastError(); cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Failed to create a virtual domain '%s' - check spec for errors: '%s'", pp->promiser, vp->message); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); Log(LOG_LEVEL_VERBOSE, "Quoted spec file: %s", xml_file); } if (alloc_file) { free(xml_file); } return result; } /*****************************************************************************/ static PromiseResult DeleteVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp) { assert(a != NULL); virDomainPtr dom; dom = virDomainLookupByName(vc, pp->promiser); PromiseResult result = PROMISE_RESULT_NOOP; if (dom) { if (virDomainDestroy(dom) == -1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Failed to delete virtual domain '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Deleted virtual domain '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } virDomainFree(dom); } else { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "No such virtual domain called '%s' - promise kept", pp->promiser); } return result; } /*****************************************************************************/ static PromiseResult RunningVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp) { assert(a != NULL); virDomainPtr dom; virDomainInfo info; dom = virDomainLookupByName(vc, pp->promiser); PromiseResult result = PROMISE_RESULT_NOOP; if (dom) { if (virDomainGetInfo(dom, &info) == -1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to probe virtual domain '%s'", pp->promiser); virDomainFree(dom); return PROMISE_RESULT_FAIL; } switch (info.state) { case VIR_DOMAIN_RUNNING: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' running - promise kept", pp->promiser); break; case VIR_DOMAIN_BLOCKED: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' running but waiting for a resource - promise kept as far as possible", pp->promiser); break; case VIR_DOMAIN_SHUTDOWN: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' is shutting down", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); Log(LOG_LEVEL_VERBOSE, "It is currently impossible to know whether it will reboot or not - deferring promise check until it has completed its shutdown"); break; case VIR_DOMAIN_PAUSED: if (virDomainResume(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' failed to resume after suspension", pp->promiser); virDomainFree(dom); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' was suspended, resuming", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; case VIR_DOMAIN_SHUTOFF: if (virDomainCreate(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' failed to resume after halting", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' was inactive, booting...", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; case VIR_DOMAIN_CRASHED: if (virDomainReboot(dom, 0) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' has crashed and rebooting failed", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' has crashed, rebooting...", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; default: Log(LOG_LEVEL_VERBOSE, "Virtual domain '%s' is reported as having no state, whatever that means", pp->promiser); break; } const Environments env = a->env; if (env.cpus > 0) { if (virDomainSetVcpus(dom, env.cpus) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the number of cpus to %d", env.cpus); } else { Log(LOG_LEVEL_INFO, "Setting the number of virtual cpus to %d", env.cpus); } } if (env.memory != CF_NOINT) { if (virDomainSetMaxMemory(dom, (unsigned long) env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the memory limit to %d", env.memory); } else { Log(LOG_LEVEL_INFO, "Setting the memory limit to %d", env.memory); } if (virDomainSetMemory(dom, (unsigned long) env.memory) == -1) { Log(LOG_LEVEL_INFO, " Unable to set the current memory to %d", env.memory); } } if (env.disk != CF_NOINT) { Log(LOG_LEVEL_VERBOSE, "Info: env_disk parameter is not currently supported on this platform"); } virDomainFree(dom); } else { Log(LOG_LEVEL_VERBOSE, "Virtual domain '%s' cannot be located, attempting to recreate", pp->promiser); result = PromiseResultUpdate(result, CreateVirtDom(ctx, vc, a, pp)); } return result; } /*****************************************************************************/ static PromiseResult SuspendedVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp) { assert(a != NULL); virDomainPtr dom; virDomainInfo info; dom = virDomainLookupByName(vc, pp->promiser); PromiseResult result = PROMISE_RESULT_NOOP; if (dom) { if (virDomainGetInfo(dom, &info) == -1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to probe virtual domain '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); virDomainFree(dom); return result; } switch (info.state) { case VIR_DOMAIN_BLOCKED: case VIR_DOMAIN_RUNNING: if (virDomainSuspend(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' failed to suspend", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' running, suspending", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; case VIR_DOMAIN_SHUTDOWN: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' is shutting down", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); Log(LOG_LEVEL_VERBOSE, "It is currently impossible to know whether it will reboot or not - deferring promise check until it has completed its shutdown"); break; case VIR_DOMAIN_PAUSED: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' is suspended - promise kept", pp->promiser); break; case VIR_DOMAIN_SHUTOFF: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' is down - promise kept", pp->promiser); break; case VIR_DOMAIN_CRASHED: if (virDomainSuspend(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' is crashed has failed to suspend", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' is in a crashed state, suspending", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; default: Log(LOG_LEVEL_VERBOSE, "Virtual domain '%s' is reported as having no state, whatever that means", pp->promiser); break; } virDomainFree(dom); } else { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' cannot be found - take promise as kept", pp->promiser); } return result; } /*****************************************************************************/ static PromiseResult DownVirt(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp) { virDomainPtr dom; virDomainInfo info; dom = virDomainLookupByName(vc, pp->promiser); PromiseResult result = PROMISE_RESULT_NOOP; if (dom) { if (virDomainGetInfo(dom, &info) == -1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to probe virtual domain '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); virDomainFree(dom); return result; } switch (info.state) { case VIR_DOMAIN_BLOCKED: case VIR_DOMAIN_RUNNING: if (virDomainShutdown(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' failed to shutdown", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' running, terminating", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; case VIR_DOMAIN_SHUTOFF: case VIR_DOMAIN_SHUTDOWN: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' is down - promise kept", pp->promiser); break; case VIR_DOMAIN_PAUSED: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' is suspended - ignoring promise", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); break; case VIR_DOMAIN_CRASHED: if (virDomainSuspend(dom) == -1) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_INTERRUPTED, pp, a, "Virtual domain '%s' is crashed and failed to shutdown", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); virDomainFree(dom); return result; } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Virtual domain '%s' is in a crashed state, terminating", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); break; default: Log(LOG_LEVEL_VERBOSE, "Virtual domain '%s' is reported as having no state, whatever that means", pp->promiser); break; } virDomainFree(dom); } else { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Virtual domain '%s' cannot be found - take promise as kept", pp->promiser); } return result; } /*****************************************************************************/ static PromiseResult CreateVirtNetwork(EvalContext *ctx, virConnectPtr vc, char **networks, const Attributes *a, const Promise *pp) { assert(a != NULL); virNetworkPtr network; char *xml_file; char defaultxml[CF_MAXVARSIZE]; int i, found = false; snprintf(defaultxml, CF_MAXVARSIZE - 1, "" "%s" "" "" "" "" "" "" "" "", pp->promiser); for (i = 0; networks[i] != NULL; i++) { Log(LOG_LEVEL_VERBOSE, "Discovered a running network '%s'", networks[i]); if (strcmp(networks[i], pp->promiser) == 0) { found = true; } } if (found) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Network '%s' exists - promise kept", pp->promiser); return PROMISE_RESULT_NOOP; } if (a->env.spec) { xml_file = xstrdup(a->env.spec); } else { xml_file = xstrdup(defaultxml); } PromiseResult result = PROMISE_RESULT_NOOP; if ((network = virNetworkCreateXML(vc, xml_file)) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to create network '%s'", pp->promiser); free(xml_file); return PROMISE_RESULT_FAIL; } else { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Created network '%s' - promise repaired", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } free(xml_file); virNetworkFree(network); return result; } /*****************************************************************************/ static PromiseResult DeleteVirtNetwork(EvalContext *ctx, virConnectPtr vc, const Attributes *a, const Promise *pp) { virNetworkPtr network; if ((network = virNetworkLookupByName(vc, pp->promiser)) == NULL) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Couldn't find a network called '%s' - promise assumed kept", pp->promiser); return PROMISE_RESULT_NOOP; } PromiseResult result = PROMISE_RESULT_NOOP; if (virNetworkDestroy(network) == 0) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Deleted network '%s' - promise repaired", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Network deletion of '%s' failed", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } virNetworkFree(network); return result; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static void EnvironmentErrorHandler() { } /*****************************************************************************/ static void ShowRunList(virConnectPtr vc) { int i; virDomainPtr dom; const char *name; for (i = 0; i < CF_MAX_CONCURRENT_ENVIRONMENTS; i++) { if (CF_RUNNING[i] > 0) { if ((dom = virDomainLookupByID(vc, CF_RUNNING[i]))) { Log(LOG_LEVEL_VERBOSE, "Found a running virtual domain with id %d", CF_RUNNING[i]); } if ((name = virDomainGetName(dom))) { Log(LOG_LEVEL_VERBOSE, "Found a running virtual domain called '%s'", name); } virDomainFree(dom); } } } /*****************************************************************************/ static void ShowDormant(void) { int i; for (i = 0; CF_SUSPENDED[i] != NULL; i++) { Log(LOG_LEVEL_VERBOSE, "Found a suspended, domain environment called '%s'", CF_SUSPENDED[i]); } } /*****************************************************************************/ static enum cfhypervisors Str2Hypervisors(char *s) { static char *names[] = { "xen", "kvm", "esx", "vbox", "test", "xen_net", "kvm_net", "esx_net", "test_net", "zone", "ec2", "eucalyptus", NULL }; int i; if (s == NULL) { return cfv_virt_test; } for (i = 0; names[i] != NULL; i++) { if (s && (strcmp(s, names[i]) == 0)) { return (enum cfhypervisors) i; } } return (enum cfhypervisors) i; } /*****************************************************************************/ #else /* !HAVE_LIBVIRT */ void NewEnvironmentsContext(void) { } void DeleteEnvironmentsContext(void) { } PromiseResult VerifyEnvironmentsPromise(ARG_UNUSED EvalContext *ctx, ARG_UNUSED const Promise *pp) { return PROMISE_RESULT_NOOP; } #endif cfengine-3.24.2/cf-agent/verify_files.c0000644000000000000000000012042015010704253017670 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* PrepareChangesChroot(), RecordFileChangedInChroot() */ static PromiseResult FindFilePromiserObjects(EvalContext *ctx, const Promise *pp); static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promise *pp); static PromiseResult WriteContentFromString(EvalContext *ctx, const char *path, const Attributes *attr, const Promise *pp); /*****************************************************************************/ static bool FileSanityChecks(char *path, const Attributes *a, const Promise *pp) { assert(a != NULL); if ((a->havelink) && (a->havecopy)) { Log(LOG_LEVEL_ERR, "Promise constraint conflicts - '%s' file cannot both be a copy of and a link to the source", path); PromiseRef(LOG_LEVEL_ERR, pp); return false; } /* We can't do this verification during parsing as we did not yet read the * body, so we can't distinguish between link and copy source. In * post-verification all bodies are already expanded, so we don't have the * information either */ if ((a->havelink) && (!a->link.source)) { Log(LOG_LEVEL_ERR, "Promise to establish a link at '%s' has no source", path); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->haveeditline) && (a->haveeditxml)) { Log(LOG_LEVEL_ERR, "Promise constraint conflicts - '%s' editing file as both line and xml makes no sense", path); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->havedepthsearch) && (a->haveedit)) { Log(LOG_LEVEL_ERR, "Recursive depth_searches are not compatible with general file editing"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->havedelete) && ((a->create) || (a->havecopy) || (a->haveedit) || (a->haverename))) { Log(LOG_LEVEL_ERR, "Promise constraint conflicts - '%s' cannot be deleted and exist at the same time", path); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->haverename) && ((a->create) || (a->havecopy) || (a->haveedit))) { Log(LOG_LEVEL_ERR, "Promise constraint conflicts - '%s' cannot be renamed/moved and exist there at the same time", path); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->havedelete) && (a->havedepthsearch) && (!a->haveselect)) { Log(LOG_LEVEL_ERR, "Dangerous or ambiguous promise - '%s' specifies recursive deletion but has no file selection criteria", path); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->haveselect) && (!a->select.result)) { Log(LOG_LEVEL_ERR, "File select constraint body promised no result (check body definition)"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->havedelete) && (a->haverename)) { Log(LOG_LEVEL_ERR, "File '%s' cannot promise both deletion and renaming", path); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->havecopy) && (a->havedepthsearch) && (a->havedelete)) { Log(LOG_LEVEL_WARNING, "depth_search of '%s' applies to both delete and copy, but these refer to different searches (source/destination)", pp->promiser); PromiseRef(LOG_LEVEL_INFO, pp); } if ((a->transaction.background) && (a->transaction.audit)) { Log(LOG_LEVEL_ERR, "Auditing cannot be performed on backgrounded promises (this might change)."); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if (((a->havecopy) || (a->havelink)) && (a->transformer)) { Log(LOG_LEVEL_ERR, "File object(s) '%s' cannot both be a copy of source and transformed simultaneously", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->haveselect) && (a->select.result == NULL)) { Log(LOG_LEVEL_ERR, "Missing file_result attribute in file_select body"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->havedepthsearch) && (a->change.report_diffs)) { Log(LOG_LEVEL_ERR, "Difference reporting is not allowed during a depth_search"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((a->haveedit) && (a->file_type) && (!strncmp(a->file_type, "fifo", 5))) { Log(LOG_LEVEL_ERR, "Editing is not allowed on fifos"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } return true; } static bool AttrHasNoAction(const Attributes *attr) { assert(attr != NULL); /* Hopefully this includes all "actions" for a files promise. See struct * Attributes for reference. */ if (!(attr->transformer || attr->haverename || attr->havedelete || attr->havecopy || attr->create || attr->touch || attr->havelink || attr->haveperms || attr->havechange || attr->acl.acl_entries || attr->haveedit || attr->haveeditline || attr->haveeditxml || (attr->content != NULL))) { return true; } else { return false; } } /* * Expands source in-place. */ static char *ExpandThisPromiserScalar(EvalContext *ctx, const char *ns, const char *scope, const char *source) { if (!source) { return NULL; } Buffer *expanded = BufferNew(); ExpandScalar(ctx, ns, scope, source, expanded); char *result = strdup(BufferData(expanded)); BufferDestroy(expanded); return result; } /* * Overwrite non-specific attributes with expanded this.promiser. */ Attributes GetExpandedAttributes(EvalContext *ctx, const Promise *pp, const Attributes *attr) { const char *namespace = PromiseGetBundle(pp)->ns; const char *scope = PromiseGetBundle(pp)->name; Attributes a = *attr; // shallow copy a.classes.change = ExpandList(ctx, namespace, scope, attr->classes.change, true); a.classes.failure = ExpandList(ctx, namespace, scope, attr->classes.failure, true); a.classes.denied = ExpandList(ctx, namespace, scope, attr->classes.denied, true); a.classes.timeout = ExpandList(ctx, namespace, scope, attr->classes.timeout, true); a.classes.kept = ExpandList(ctx, namespace, scope, attr->classes.kept, true); a.classes.del_change = ExpandList(ctx, namespace, scope, attr->classes.del_change, true); a.classes.del_kept = ExpandList(ctx, namespace, scope, attr->classes.del_kept, true); a.classes.del_notkept = ExpandList(ctx, namespace, scope, attr->classes.del_notkept, true); a.transaction.log_string = ExpandThisPromiserScalar(ctx, namespace, scope, attr->transaction.log_string); a.transaction.log_kept = ExpandThisPromiserScalar(ctx, namespace, scope, attr->transaction.log_kept); a.transaction.log_repaired = ExpandThisPromiserScalar(ctx, namespace, scope, attr->transaction.log_repaired); a.transaction.log_failed = ExpandThisPromiserScalar(ctx, namespace, scope, attr->transaction.log_failed); a.transaction.measure_id = ExpandThisPromiserScalar(ctx, namespace, scope, attr->transaction.measure_id); // a.transformer = ExpandThisPromiserScalar(ctx, namespace, scope, attr->transformer); a.edit_template = ExpandThisPromiserScalar(ctx, namespace, scope, attr->edit_template); a.edit_template_string = ExpandThisPromiserScalar(ctx, namespace, scope, attr->edit_template_string); return a; } void ClearExpandedAttributes(Attributes *a) { DESTROY_AND_NULL(RlistDestroy, a->classes.change); DESTROY_AND_NULL(RlistDestroy, a->classes.failure); DESTROY_AND_NULL(RlistDestroy, a->classes.denied); DESTROY_AND_NULL(RlistDestroy, a->classes.timeout); DESTROY_AND_NULL(RlistDestroy, a->classes.kept); DESTROY_AND_NULL(RlistDestroy, a->classes.del_change); DESTROY_AND_NULL(RlistDestroy, a->classes.del_kept); DESTROY_AND_NULL(RlistDestroy, a->classes.del_notkept); FREE_AND_NULL(a->transaction.log_string); FREE_AND_NULL(a->transaction.log_kept); FREE_AND_NULL(a->transaction.log_repaired); FREE_AND_NULL(a->transaction.log_failed); FREE_AND_NULL(a->transaction.measure_id); FREE_AND_NULL(a->edit_template); FREE_AND_NULL(a->edit_template_string); ClearFilesAttributes(a); } static inline bool CreateFalseWasSpecified(const Promise *pp) { assert(pp != NULL); const size_t n = SeqLength(pp->conlist); for (size_t i = 0; i < n; i++) { Constraint *cp = SeqAt(pp->conlist, i); if (StringEqual(cp->lval, "create") && (StringEqual(cp->rval.item, "false") || StringEqual(cp->rval.item, "no"))) { return true; } } return false; } static PromiseResult VerifyFilePromise(EvalContext *ctx, char *path, const Promise *pp) { struct stat osb, oslb, dsb; CfLock thislock; int exists; bool link = false; Attributes attr = GetFilesAttributes(ctx, pp); if (!FileSanityChecks(path, &attr, pp)) { ClearFilesAttributes(&attr); return PROMISE_RESULT_NOOP; } thislock = AcquireLock(ctx, path, VUQNAME, CFSTARTTIME, attr.transaction.ifelapsed, attr.transaction.expireafter, pp, false); if (thislock.lock == NULL) { ClearFilesAttributes(&attr); return PROMISE_RESULT_SKIPPED; } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser", path, CF_DATA_TYPE_STRING, "source=promise"); Attributes a = GetExpandedAttributes(ctx, pp, &attr); PromiseResult result = PROMISE_RESULT_NOOP; char *chrooted_path = NULL; /* if template_data was specified, it must have been resolved to a data * container by now */ /* check this early to prevent creation of the file below in case of failure */ const Constraint *template_data_constraint = PromiseGetConstraint(pp, "template_data"); if (template_data_constraint != NULL && template_data_constraint->rval.type != RVAL_TYPE_CONTAINER) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "No template data for the promise '%s'", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); goto exit; } if (ChrootChanges()) { PrepareChangesChroot(path); } const char *changes_path = path; if (ChrootChanges()) { chrooted_path = xstrdup(ToChangesChroot(path)); changes_path = chrooted_path; } if (lstat(changes_path, &oslb) == -1) /* Careful if the object is a link */ { if ((a.create) || (a.touch)) { if (!CfCreateFile(ctx, path, pp, &a, &result)) { goto exit; } else { exists = (lstat(changes_path, &oslb) != -1); } } exists = false; } else { if ((a.create) || (a.touch)) { RecordNoChange(ctx, pp, &a, "File '%s' exists as promised", path); } exists = true; link = true; } if ((a.havedelete) && (!exists)) { RecordNoChange(ctx, pp, &a, "File '%s' does not exist as promised", path); goto exit; } if (!a.havedepthsearch) /* if the search is trivial, make sure that we are in the parent dir of the leaf */ { Log(LOG_LEVEL_DEBUG, "Direct file reference '%s', no search implied", path); char basedir[CF_BUFSIZE]; strlcpy(basedir, path, sizeof(basedir)); if (StringEqual(ReadLastNode(basedir), ".")) { // Handle /. notation for deletion of directories ChopLastNode(basedir); ChopLastNode(path); } ChopLastNode(basedir); if (safe_chdir(ToChangesPath(basedir)) != 0) { /* TODO: PROMISE_RESULT_FAIL?!?!?!?! */ char msg[sizeof(basedir) + 36 + 100]; // 36 for fmt string 100 for error string snprintf(msg, sizeof(msg), "Failed to chdir into '%s'. (chdir: '%s')", basedir, GetErrorStr()); if (errno == ENOLINK) { Log(LOG_LEVEL_ERR, "%s. There may be a symlink in the path that has a different " "owner from the owner of its target (security risk).", msg); } else { Log(LOG_LEVEL_ERR, "%s", msg); } } } /* If file or directory exists but it is not selected by body file_select * (if we have one) then just exit. But continue if it's a directory and * depth_search is on, so that we can file_select into it. */ if (exists && (a.haveselect && !SelectLeaf(ctx, path, &oslb, &(a.select))) && !(a.havedepthsearch && S_ISDIR(oslb.st_mode))) { goto skip; } if (stat(changes_path, &osb) == -1) { if ((a.create) || (a.touch)) { if (!CfCreateFile(ctx, path, pp, &a, &result)) { goto exit; } else { exists = true; } } else { exists = false; } } else { if (!S_ISDIR(osb.st_mode) && a.havedepthsearch) { Log(LOG_LEVEL_WARNING, "depth_search (recursion) is promised for a base object '%s' that is not a directory", path); } exists = true; } if (a.link.link_children) { const char *changes_link_source = a.link.source; if (ChrootChanges()) { /* Make sure the link source is in the changes chroot. */ PrepareChangesChroot(a.link.source); changes_link_source = ToChangesChroot(a.link.source); } if (stat(changes_link_source, &dsb) != -1) { if (!S_ISDIR(dsb.st_mode)) { /* TODO: PROMISE_RESULT_FAIL */ Log(LOG_LEVEL_ERR, "Cannot promise to link the children of '%s' as it is not a directory!", a.link.source); goto exit; } } } /* Phase 1 - */ if ((exists && (a.haverename || a.haveperms || a.havechange || a.transformer || a.acl.acl_entries != NULL) ) || ((exists || link) && a.havedelete)) { lstat(changes_path, &oslb); /* if doesn't exist have to stat again anyway */ DepthSearch(ctx, path, &oslb, 0, &a, pp, oslb.st_dev, &result); /* normally searches do not include the base directory */ if (a.recursion.include_basedir) { int save_search = a.havedepthsearch; /* Handle this node specially */ a.havedepthsearch = false; DepthSearch(ctx, path, &oslb, 0, &a, pp, oslb.st_dev, &result); a.havedepthsearch = save_search; } else { /* unless child nodes were repaired, set a promise kept class */ if (result == PROMISE_RESULT_NOOP) { Log(LOG_LEVEL_VERBOSE, "Basedir '%s' not promising anything", path); } } } /* Phase 2a - copying is potentially threadable if no followup actions */ if (a.havecopy) { result = PromiseResultUpdate(result, ScheduleCopyOperation(ctx, path, &a, pp)); } /* Phase 2b link after copy in case need file first */ if ((a.havelink) && (a.link.link_children)) { result = PromiseResultUpdate(result, ScheduleLinkChildrenOperation(ctx, path, a.link.source, 1, &a, pp)); } else if (a.havelink) { result = PromiseResultUpdate(result, ScheduleLinkOperation(ctx, path, a.link.source, &a, pp)); } /* Phase 3a - direct content */ if (a.content) { if (a.haveedit) { // Disallow edits on top of content creation RecordFailure(ctx, pp, &a, "A file promise with content attribute cannot have edit operations"); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); goto exit; } /* Files promises that promise full file content shall create files by * default, unless `create => "false"` is specified. */ if (!exists && !CreateFalseWasSpecified(pp)) { exists = CfCreateFile(ctx, path, pp, &a, &result); } if (!exists) { Log(LOG_LEVEL_VERBOSE, "Cannot render file '%s' with content '%s': file does not exist", path, a.content); goto exit; } Log(LOG_LEVEL_VERBOSE, "Replacing '%s' with content '%s'", path, a.content); PromiseResult render_result = WriteContentFromString(ctx, path, &a, pp); result = PromiseResultUpdate(result, render_result); goto exit; } /* Phase 3b - content editing */ if (a.haveedit) { /* Files promises that promise full file content shall create files by * default, unless `create => "false"` is specified. */ if (exists || ((StringEqual(a.template_method, "mustache") || StringEqual(a.template_method, "inline_mustache") || StringEqual(a.template_method, "cfengine")) && !CreateFalseWasSpecified(pp))) { result = PromiseResultUpdate(result, ScheduleEditOperation(ctx, path, exists, &a, pp)); } else { Log(LOG_LEVEL_VERBOSE, "Cannot render file '%s': file does not exist", path); goto exit; } } // Once more in case a file has been created as a result of editing or copying exists = (lstat(changes_path, &osb) != -1); if (exists && (S_ISREG(osb.st_mode) || S_ISLNK(osb.st_mode)) && (!a.haveselect || SelectLeaf(ctx, path, &osb, &(a.select)))) { VerifyFileLeaf(ctx, path, &osb, &a, pp, &result); } if (!exists && a.havechange) { RecordFailure(ctx, pp, &a, "Promised to monitor '%s' for changes, but file does not exist", path); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } exit: free(chrooted_path); if (AttrHasNoAction(&a)) { Log(LOG_LEVEL_VERBOSE, "No action was requested for file '%s'. " "Maybe all attributes are skipped due to unresolved arguments in policy functions? " "Maybe a typo in the policy?", path); } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the files promise '%s'", pp->promiser); if (EVAL_MODE == EVAL_MODE_SIMULATE_MANIFEST_FULL) { RecordFileEvaluatedInChroot(path); } break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "files promise '%s' repaired", pp->promiser); if (ChrootChanges() && !a.haverename) { /* Record that file was changed in the changes chroot so that we can * later show the diff or manifest. Renames are reported * separately. */ RecordFileChangedInChroot(path); } break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating files promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating files promise '%s'", pp->promiser); break; } skip: YieldCurrentLock(thislock); ClearExpandedAttributes(&a); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser"); return result; } /*****************************************************************************/ static PromiseResult WriteContentFromString(EvalContext *ctx, const char *path, const Attributes *attr, const Promise *pp) { assert(path != NULL); assert(attr != NULL); assert(attr->content != NULL); const char *changes_path = path; if (ChrootChanges()) { changes_path = ToChangesChroot(path); } PromiseResult result = PROMISE_RESULT_NOOP; unsigned char existing_content_digest[EVP_MAX_MD_SIZE + 1] = { 0 }; if (access(changes_path, R_OK) == 0) { HashFile(changes_path, existing_content_digest, CF_DEFAULT_DIGEST, FileNewLineMode(changes_path) == NewLineMode_Native); } size_t bytes_to_write = strlen(attr->content); unsigned char promised_content_digest[EVP_MAX_MD_SIZE + 1] = { 0 }; HashString(attr->content, strlen(attr->content), promised_content_digest, CF_DEFAULT_DIGEST); if (!HashesMatch(existing_content_digest, promised_content_digest, CF_DEFAULT_DIGEST)) { if (!MakingChanges(ctx, pp, attr, &result, "update file '%s' with content '%s'", path, attr->content)) { return result; } FILE *f = safe_fopen(changes_path, "w"); if (f == NULL) { RecordFailure(ctx, pp, attr, "Cannot open file '%s' for writing", path); return PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } Writer *w = FileWriter(f); if (WriterWriteLen(w, attr->content, bytes_to_write) == bytes_to_write ) { RecordChange(ctx, pp, attr, "Updated file '%s' with content '%s'", path, attr->content); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to update file '%s' with content '%s'", path, attr->content); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } WriterClose(w); } return result; } /*****************************************************************************/ static PromiseResult RenderTemplateCFEngine(EvalContext *ctx, const Promise *pp, const Rlist *bundle_args, const Attributes *attr, EditContext *edcontext, bool file_exists) { assert(edcontext != NULL); assert(attr != NULL); Attributes a = *attr; // TODO: Try to remove this copy PromiseResult result = PROMISE_RESULT_NOOP; Policy *tmp_policy = PolicyNew(); Bundle *bp = NULL; if ((bp = MakeTemporaryBundleFromTemplate(ctx, tmp_policy, &a, pp, &result))) { if (!file_exists && !CfCreateFile(ctx, edcontext->changes_filename, pp, attr, &result)) { RecordFailure(ctx, pp, attr, "Failed to create file '%s' for rendering cfengine template '%s'", edcontext->filename, attr->edit_template); return PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } a.haveeditline = true; EvalContextStackPushBundleFrame(ctx, bp, bundle_args, a.edits.inherit); BundleResolve(ctx, bp); ScheduleEditLineOperations(ctx, bp, &a, pp, edcontext); EvalContextStackPopFrame(ctx); if (edcontext->num_edits == 0) { edcontext->num_edits++; } } PolicyDestroy(tmp_policy); return result; } static bool SaveBufferCallback(const char *dest_filename, void *param, NewLineMode new_line_mode) { FILE *fp = safe_fopen( dest_filename, (new_line_mode == NewLineMode_Native) ? "wt" : "w"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Unable to open destination file '%s' for writing. (fopen: %s)", dest_filename, GetErrorStr()); return false; } Buffer *output_buffer = param; size_t bytes_written = fwrite(BufferData(output_buffer), sizeof(char), BufferSize(output_buffer), fp); if (bytes_written != BufferSize(output_buffer)) { Log(LOG_LEVEL_ERR, "Error writing to output file '%s' when writing. %zu bytes written but expected %zu. (fclose: %s)", dest_filename, bytes_written, BufferSize(output_buffer), GetErrorStr()); fclose(fp); return false; } if (fclose(fp) == -1) { Log(LOG_LEVEL_ERR, "Unable to close file '%s' after writing. (fclose: %s)", dest_filename, GetErrorStr()); return false; } return true; } static PromiseResult RenderTemplateMustache(EvalContext *ctx, const Promise *pp, const Attributes *attr, EditContext *edcontext, const char *template, bool file_exists) { assert(attr != NULL); assert(edcontext != NULL); PromiseResult result = PROMISE_RESULT_NOOP; const JsonElement *template_data = attr->template_data; JsonElement *destroy_this = NULL; if (template_data == NULL) { destroy_this = DefaultTemplateData(ctx, NULL); template_data = destroy_this; } unsigned char existing_output_digest[EVP_MAX_MD_SIZE + 1] = { 0 }; if (access(edcontext->changes_filename, R_OK) == 0) { HashFile(edcontext->changes_filename, existing_output_digest, CF_DEFAULT_DIGEST, edcontext->new_line_mode == NewLineMode_Native); } Buffer *output_buffer = BufferNew(); char *message; if (strcmp("inline_mustache", attr->template_method) == 0) { message = xstrdup("inline"); } else { message = xstrdup(attr->edit_template); } if (MustacheRender(output_buffer, template, template_data)) { unsigned char rendered_output_digest[EVP_MAX_MD_SIZE + 1] = { 0 }; HashString(BufferData(output_buffer), BufferSize(output_buffer), rendered_output_digest, CF_DEFAULT_DIGEST); if (!HashesMatch(existing_output_digest, rendered_output_digest, CF_DEFAULT_DIGEST)) { if (MakingChanges(ctx, pp, attr, &result, "update rendering of '%s' from mustache template '%s'", edcontext->filename, message)) { if (!file_exists && !CfCreateFile(ctx, edcontext->changes_filename, pp, attr, &result)) { RecordFailure(ctx, pp, attr, "Failed to create file '%s' for rendering mustache template '%s'", edcontext->filename, message); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } else if (SaveAsFile(SaveBufferCallback, output_buffer, edcontext->changes_filename, attr, edcontext->new_line_mode)) { RecordChange(ctx, pp, attr, "Updated rendering of '%s' from mustache template '%s'", edcontext->filename, message); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to update rendering of '%s' from mustache template '%s'", edcontext->filename, message); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } } } else { /* Use `edit_template` attribute when template method is "mustache". * Use `edit_template_string` attribute when template method is * "inline_mustache". */ char *tmpl = StringEqual(attr->template_method, "mustache") ? attr->edit_template : attr->edit_template_string; RecordFailure(ctx, pp, attr, "Error rendering mustache template '%s'", tmpl); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } BufferDestroy(output_buffer); JsonDestroy(destroy_this); free(message); return result; } static PromiseResult RenderTemplateMustacheFromFile(EvalContext *ctx, const Promise *pp, const Attributes *a, EditContext *edcontext, bool file_exists) { assert(a != NULL); PromiseResult result = PROMISE_RESULT_NOOP; if (!FileCanOpen(a->edit_template, "r")) { RecordFailure(ctx, pp, a, "Template file '%s' could not be opened for reading", a->edit_template); return PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } int template_fd = safe_open(a->edit_template, O_RDONLY | O_TEXT); Writer *template_writer = NULL; if (template_fd >= 0) { template_writer = FileReadFromFd(template_fd, SIZE_MAX, NULL); close(template_fd); } if (template_writer == NULL) { RecordFailure(ctx, pp, a, "Could not read template file '%s'", a->edit_template); return PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } result = RenderTemplateMustache(ctx, pp, a, edcontext, StringWriterData(template_writer), file_exists); WriterClose(template_writer); return result; } static PromiseResult RenderTemplateMustacheFromString(EvalContext *ctx, const Promise *pp, const Attributes *a, EditContext *edcontext, bool file_exists) { assert(a != NULL); if ( a->edit_template_string == NULL ) { PromiseResult result = PROMISE_RESULT_NOOP; RecordFailure(ctx, pp, a, "'edit_template_string' not set for promiser: '%s'", pp->promiser); return PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } return RenderTemplateMustache(ctx, pp, a, edcontext, a->edit_template_string, file_exists); } PromiseResult ScheduleEditOperation(EvalContext *ctx, char *filename, bool file_exists, const Attributes *a, const Promise *pp) { assert(a != NULL); void *vp; FnCall *fp; Rlist *args = NULL; char edit_bundle_name[CF_BUFSIZE], lockname[CF_BUFSIZE]; CfLock thislock; snprintf(lockname, CF_BUFSIZE - 1, "fileedit-%s", filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a->transaction.ifelapsed, a->transaction.expireafter, pp, false); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } EditContext *edcontext = NewEditContext(filename, a); StartLoggingIntoBuffer(LOG_LEVEL_INFO, LOG_LEVEL_INFO); PromiseResult result = PROMISE_RESULT_NOOP; if (edcontext == NULL) { RecordFailure(ctx, pp, a, "File '%s' was marked for editing but could not be opened", filename); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); goto exit; } const Policy *policy = PolicyFromPromise(pp); if (a->haveeditline) { if ((vp = PromiseGetConstraintAsRval(pp, "edit_line", RVAL_TYPE_FNCALL))) { fp = (FnCall *) vp; strcpy(edit_bundle_name, fp->name); args = fp->args; } else if ((vp = PromiseGetConstraintAsRval(pp, "edit_line", RVAL_TYPE_SCALAR))) { strcpy(edit_bundle_name, (char *) vp); args = NULL; } else { goto exit; } Log(LOG_LEVEL_VERBOSE, "Handling file edits in edit_line bundle '%s'", edit_bundle_name); const Bundle *bp = EvalContextResolveBundleExpression(ctx, policy, edit_bundle_name, "edit_line"); if (bp) { EvalContextStackPushBundleFrame(ctx, bp, args, a->edits.inherit); BundleResolve(ctx, bp); ScheduleEditLineOperations(ctx, bp, a, pp, edcontext); EvalContextStackPopFrame(ctx); } else { Log(LOG_LEVEL_ERR, "Did not find bundle '%s' for edit operation", edit_bundle_name); } } if (a->haveeditxml) { if ((vp = PromiseGetConstraintAsRval(pp, "edit_xml", RVAL_TYPE_FNCALL))) { fp = (FnCall *) vp; strcpy(edit_bundle_name, fp->name); args = fp->args; } else if ((vp = PromiseGetConstraintAsRval(pp, "edit_xml", RVAL_TYPE_SCALAR))) { strcpy(edit_bundle_name, (char *) vp); args = NULL; } else { goto exit; } Log(LOG_LEVEL_VERBOSE, "Handling file edits in edit_xml bundle '%s'", edit_bundle_name); const Bundle *bp = EvalContextResolveBundleExpression(ctx, policy, edit_bundle_name, "edit_xml"); if (bp) { EvalContextStackPushBundleFrame(ctx, bp, args, a->edits.inherit); BundleResolve(ctx, bp); ScheduleEditXmlOperations(ctx, bp, a, pp, edcontext); EvalContextStackPopFrame(ctx); } } if (strcmp("cfengine", a->template_method) == 0) { if (a->edit_template) { Log(LOG_LEVEL_VERBOSE, "Rendering '%s' using template '%s' with method '%s'", filename, a->edit_template, a->template_method); PromiseResult render_result = RenderTemplateCFEngine(ctx, pp, args, a, edcontext, file_exists); result = PromiseResultUpdate(result, render_result); } } else if (strcmp("mustache", a->template_method) == 0) { if (a->edit_template) { Log(LOG_LEVEL_VERBOSE, "Rendering '%s' using template '%s' with method '%s'", filename, a->edit_template, a->template_method); PromiseResult render_result = RenderTemplateMustacheFromFile(ctx, pp, a, edcontext, file_exists); result = PromiseResultUpdate(result, render_result); } } else if (strcmp("inline_mustache", a->template_method) == 0) { if (a->edit_template_string) { Log(LOG_LEVEL_VERBOSE, "Rendering '%s' with method '%s'", filename, a->template_method); PromiseResult render_result = RenderTemplateMustacheFromString(ctx, pp, a, edcontext, file_exists); result = PromiseResultUpdate(result, render_result); } } exit: FinishEditContext(ctx, edcontext, a, pp, &result); YieldCurrentLock(thislock); if (result == PROMISE_RESULT_CHANGE) { CommitLogBuffer(); } else { DiscardLogBuffer(); } return result; } /*****************************************************************************/ PromiseResult FindAndVerifyFilesPromises(EvalContext *ctx, const Promise *pp) { PromiseBanner(ctx, pp); return FindFilePromiserObjects(ctx, pp); } /*****************************************************************************/ static DefineClasses GetExpandedClassDefinitionConstraints(const EvalContext *ctx, const Promise *pp) { const char *namespace = PromiseGetBundle(pp)->ns; const char *scope = PromiseGetBundle(pp)->name; /* Get the unexpanded classes. */ DefineClasses c = GetClassDefinitionConstraints(ctx, pp); /* Expand the classes just like GetExpandedAttributes() does. * NOTE: The original Rlists are owned by the promise, the new ones need to be * RlistDestroy()-ed.*/ c.change = ExpandList(ctx, namespace, scope, c.change, true); c.failure = ExpandList(ctx, namespace, scope, c.failure, true); c.denied = ExpandList(ctx, namespace, scope, c.denied, true); c.timeout = ExpandList(ctx, namespace, scope, c.timeout, true); c.kept = ExpandList(ctx, namespace, scope, c.kept, true); c.del_change = ExpandList(ctx, namespace, scope, c.del_change, true); c.del_kept = ExpandList(ctx, namespace, scope, c.del_kept, true); c.del_notkept = ExpandList(ctx, namespace, scope, c.del_notkept, true); return c; } static void ClearExpandedClassDefinitionConstraints(DefineClasses *c) { assert(c != NULL); RlistDestroy(c->change); RlistDestroy(c->failure); RlistDestroy(c->denied); RlistDestroy(c->timeout); RlistDestroy(c->kept); RlistDestroy(c->del_change); RlistDestroy(c->del_kept); RlistDestroy(c->del_notkept); } static PromiseResult FindFilePromiserObjects(EvalContext *ctx, const Promise *pp) { assert(pp != NULL); char *val = PromiseGetConstraintAsRval(pp, "pathtype", RVAL_TYPE_SCALAR); int literal = (PromiseGetConstraintAsBoolean(ctx, "copy_from", pp)) || ((val != NULL) && (strcmp(val, "literal") == 0)); /* Check if we are searching over a regular expression */ PromiseResult result = PROMISE_RESULT_SKIPPED; if (literal) { // Prime the promiser temporarily, may override later result = PromiseResultUpdate(result, VerifyFilePromise(ctx, pp->promiser, pp)); } else // Default is to expand regex paths { result = PromiseResultUpdate(result, LocateFilePromiserGroup(ctx, pp->promiser, pp, VerifyFilePromise)); /* Now set the outcome classes for the pp->promiser itself (not the expanded paths). */ if (result != PROMISE_RESULT_SKIPPED) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser", pp->promiser, CF_DATA_TYPE_STRING, "source=promise"); Attributes a = ZeroAttributes; a.classes = GetExpandedClassDefinitionConstraints(ctx, pp); SetPromiseOutcomeClasses(ctx, result, &(a.classes)); ClearExpandedClassDefinitionConstraints(&(a.classes)); EvalContextVariableRemoveSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser"); } } return result; } cfengine-3.24.2/cf-agent/files_editline.c0000644000000000000000000024024215010704253020166 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CF_MAX_REPLACE 20 /*****************************************************************************/ enum editlinetypesequence { elp_vars, elp_classes, elp_delete, elp_columns, elp_insert, elp_replace, elp_reports, elp_none }; static const char *const EDITLINETYPESEQUENCE[] = { "vars", "classes", "delete_lines", "field_edits", "insert_lines", "replace_patterns", "reports", NULL }; static PromiseResult KeepEditLinePromise(EvalContext *ctx, const Promise *pp, void *param); static PromiseResult VerifyLineDeletions(EvalContext *ctx, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyColumnEdits(EvalContext *ctx, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyPatterns(EvalContext *ctx, const Promise *pp, EditContext *edcontext); static PromiseResult VerifyLineInsertions(EvalContext *ctx, const Promise *pp, EditContext *edcontext); static bool InsertMultipleLinesToRegion(EvalContext *ctx, Item **start, Item *begin_ptr, Item *end_ptr, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool InsertMultipleLinesAtLocation(EvalContext *ctx, Item **start, Item *begin_ptr, Item *end_ptr, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool DeletePromisedLinesMatching(EvalContext *ctx, Item **start, Item *begin, Item *end, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool InsertLineAtLocation(EvalContext *ctx, char *newline, Item **start, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool InsertCompoundLineAtLocation(EvalContext *ctx, const char *newline, Item **start, Item *begin_ptr, Item *end_ptr, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool ReplacePatterns(EvalContext *ctx, Item *start, Item *end, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool EditColumns(EvalContext *ctx, Item *file_start, Item *file_end, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool EditLineByColumn(EvalContext *ctx, Rlist **columns, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); static bool DoEditColumn(Rlist **columns, EditContext *edcontext, EvalContext *ctx, const Promise *pp, const Attributes *a, PromiseResult *result); static bool SanityCheckInsertions(const Attributes *a); static bool SanityCheckDeletions(const Attributes *a, const Promise *pp); static bool SelectLine(EvalContext *ctx, const char *line, const Attributes *a); static bool NotAnchored(char *s); static bool SelectRegion(EvalContext *ctx, Item *start, Item **begin_ptr, Item **end_ptr, const Attributes *a, EditContext *edcontext); static bool MultiLineString(char *s); static bool InsertFileAtLocation(EvalContext *ctx, Item **start, Item *begin_ptr, Item *end_ptr, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result); /*****************************************************************************/ /* Level */ /*****************************************************************************/ bool ScheduleEditLineOperations(EvalContext *ctx, const Bundle *bp, const Attributes *a, const Promise *parentp, EditContext *edcontext) { assert(a != NULL); assert(bp != NULL); assert(edcontext != NULL); enum editlinetypesequence type; char lockname[CF_BUFSIZE]; CfLock thislock; int pass; assert(StringEqual(bp->type, "edit_line")); snprintf(lockname, CF_BUFSIZE - 1, "masterfilelock-%s", edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a->transaction.ifelapsed, a->transaction.expireafter, parentp, true); if (thislock.lock == NULL) { return false; } EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_EDIT, "filename", edcontext->filename, CF_DATA_TYPE_STRING, "source=promise"); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_EDIT, "empty_before_use", (a->edits.empty_before_use ? "true" : "false"), CF_DATA_TYPE_STRING, "source=promise"); for (pass = 1; pass < CF_DONEPASSES; pass++) { for (type = 0; EDITLINETYPESEQUENCE[type] != NULL; type++) { const BundleSection *sp = BundleGetSection(bp, EDITLINETYPESEQUENCE[type]); if (!sp) { continue; } EvalContextStackPushBundleSectionFrame(ctx, sp); const size_t length = SeqLength(sp->promises); for (size_t ppi = 0; ppi < length; ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepEditLinePromise, edcontext); if (BundleAbort(ctx)) { YieldCurrentLock(thislock); EvalContextStackPopFrame(ctx); return false; } } EvalContextStackPopFrame(ctx); } } YieldCurrentLock(thislock); return true; } /*****************************************************************************/ Bundle *MakeTemporaryBundleFromTemplate(EvalContext *ctx, Policy *policy, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); FILE *fp = NULL; if ((fp = safe_fopen(a->edit_template, "rt" )) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "Unable to open template file '%s' to make '%s'", a->edit_template, pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return NULL; } Bundle *bp = NULL; { char bundlename[CF_MAXVARSIZE]; snprintf(bundlename, CF_MAXVARSIZE, "temp_cf_bundle_%s", CanonifyName(a->edit_template)); bp = PolicyAppendBundle(policy, "default", bundlename, "edit_line", NULL, NULL); } assert(bp); { BundleSection *bsp = BundleAppendSection(bp, "insert_lines"); Promise *np = NULL; Item *lines = NULL; Item *stack = NULL; char context[CF_BUFSIZE] = "any"; int lineno = 0; size_t level = 0; size_t buffer_size = CF_BUFSIZE; char *buffer = xmalloc(buffer_size); for (;;) { if (getline(&buffer, &buffer_size, fp) == -1) { if (!feof(fp)) { Log(LOG_LEVEL_ERR, "While constructing template for '%s', error reading. (getline %s)", pp->promiser, GetErrorStr()); break; } else /* feof */ { break; } } lineno++; // Check closing syntax // Get Action operator if (StringEqualN(buffer, "[%CFEngine", strlen("[%CFEngine"))) { char op[CF_BUFSIZE] = ""; char brack[4] = ""; sscanf(buffer+strlen("[%CFEngine"), "%1024s %3s", op, brack); if (!StringEqual(brack, "%]")) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "Template file '%s' syntax error, missing close \"%%]\" at line %d", a->edit_template, lineno); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return NULL; } if (StringEqual(op, "BEGIN")) { PrependItem(&stack, context, NULL); if (++level > 1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, a, "Template file '%s' contains nested blocks which are not allowed, near line %d", a->edit_template, lineno); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return NULL; } continue; } if (StringEqual(op, "END")) { level--; if (stack != NULL) { strcpy(context, stack->name); DeleteItem(&stack, stack); } } if (StringEqual(op + strlen(op)-2, "::")) { *(op + strlen(op)-2) = '\0'; strcpy(context, op); continue; } size_t size = 0; for (const Item *ip = lines; ip != NULL; ip = ip->next) { size += strlen(ip->name); } char *promiser = NULL; char *sp = promiser = xcalloc(1, size+1); for (const Item *ip = lines; ip != NULL; ip = ip->next) { const int len = strlen(ip->name); memcpy(sp, ip->name, len); sp += len; } int nl = StripTrailingNewline(promiser, size); CF_ASSERT(nl != -1, "StripTrailingNewline failure"); np = BundleSectionAppendPromise(bsp, promiser, (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, context, NULL); np->offset.line = lineno; PromiseAppendConstraint(np, "insert_type", RvalNew("preserve_all_lines", RVAL_TYPE_SCALAR), false); DeleteItemList(lines); free(promiser); lines = NULL; } else { if (IsDefinedClass(ctx, context)) { if (level > 0) { AppendItem(&lines, buffer, context); } else { //install independent promise line StripTrailingNewline(buffer, buffer_size); np = BundleSectionAppendPromise(bsp, buffer, (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, context, NULL); np->offset.line = lineno; PromiseAppendConstraint(np, "insert_type", RvalNew("preserve_all_lines", RVAL_TYPE_SCALAR), false); } } } } free(buffer); } fclose(fp); return bp; } /***************************************************************************/ /* Level */ /***************************************************************************/ static PromiseResult KeepEditLinePromise(EvalContext *ctx, const Promise *pp, void *param) { EditContext *edcontext = param; PromiseBanner(ctx, pp); if (StringEqual("classes", PromiseGetPromiseType(pp))) { return VerifyClassPromise(ctx, pp, NULL); } else if (StringEqual("delete_lines", PromiseGetPromiseType(pp))) { return VerifyLineDeletions(ctx, pp, edcontext); } else if (StringEqual("field_edits", PromiseGetPromiseType(pp))) { return VerifyColumnEdits(ctx, pp, edcontext); } else if (StringEqual("insert_lines", PromiseGetPromiseType(pp))) { return VerifyLineInsertions(ctx, pp, edcontext); } else if (StringEqual("replace_patterns", PromiseGetPromiseType(pp))) { return VerifyPatterns(ctx, pp, edcontext); } else if (StringEqual("reports", PromiseGetPromiseType(pp))) { return VerifyReportPromise(ctx, pp); } return PROMISE_RESULT_NOOP; } /***************************************************************************/ /* Level */ /***************************************************************************/ static PromiseResult VerifyLineDeletions(EvalContext *ctx, const Promise *pp, EditContext *edcontext) { assert(pp != NULL); assert(edcontext != NULL); Item **start = &(edcontext->file_start); Item *begin_ptr, *end_ptr; CfLock thislock; char lockname[CF_BUFSIZE]; Attributes a = GetDeletionAttributes(ctx, pp); a.transaction.ifelapsed = CF_EDIT_IFELAPSED; if (!SanityCheckDeletions(&a, pp)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised line deletion '%s' is inconsistent", pp->promiser); return PROMISE_RESULT_INTERRUPTED; } /* Are we working in a restricted region? */ PromiseResult result = PROMISE_RESULT_NOOP; if (!a.haveregion) { begin_ptr = NULL; end_ptr = NULL; } else if (!SelectRegion(ctx, *start, &begin_ptr, &end_ptr, &a, edcontext)) { if (a.region.include_end || a.region.include_start) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised line deletion '%s' could not select an edit region in '%s'" " (this is a good thing, as policy suggests deleting the markers)", pp->promiser, edcontext->filename); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised line deletion '%s' could not select an edit region in '%s'" " (but the delimiters were expected in the file)", pp->promiser, edcontext->filename); } result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } if (!end_ptr && a.region.select_end && !a.region.select_end_match_eof) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised end pattern '%s' was not found when selecting region to delete in '%s'", a.region.select_end, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } snprintf(lockname, CF_BUFSIZE - 1, "deleteline-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } if (DeletePromisedLinesMatching(ctx, start, begin_ptr, end_ptr, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the delete_lines promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "delete_lines promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating delete_lines promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating delete_lines promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyColumnEdits(EvalContext *ctx, const Promise *pp, EditContext *edcontext) { assert(pp != NULL); assert(edcontext != NULL); Item **start = &(edcontext->file_start); Item *begin_ptr, *end_ptr; CfLock thislock; char lockname[CF_BUFSIZE]; Attributes a = GetColumnAttributes(ctx, pp); a.transaction.ifelapsed = CF_EDIT_IFELAPSED; if (a.column.column_separator == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "No field_separator in promise to edit by column for '%s'", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } if (a.column.select_column <= 0) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "No select_field in promise to edit '%s'", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } if (!a.column.column_value) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "No field_value is promised to column_edit '%s'", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } /* Are we working in a restricted region? */ PromiseResult result = PROMISE_RESULT_NOOP; if (!a.haveregion) { begin_ptr = *start; end_ptr = NULL; // EndOfList(*start); } else if (!SelectRegion(ctx, *start, &begin_ptr, &end_ptr, &a, edcontext)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised column edit '%s' could not select an edit region in '%s'", pp->promiser, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } /* locate and split line */ snprintf(lockname, CF_BUFSIZE - 1, "column-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } if (EditColumns(ctx, begin_ptr, end_ptr, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the fields_edit promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "fields_edit promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating fields_edit promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating fields_edit promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static PromiseResult VerifyPatterns(EvalContext *ctx, const Promise *pp, EditContext *edcontext) { assert(pp != NULL); assert(edcontext != NULL); Item **start = &(edcontext->file_start); Item *begin_ptr, *end_ptr; CfLock thislock; char lockname[CF_BUFSIZE]; Log(LOG_LEVEL_VERBOSE, "Looking at pattern '%s'", pp->promiser); /* Are we working in a restricted region? */ Attributes a = GetReplaceAttributes(ctx, pp); a.transaction.ifelapsed = CF_EDIT_IFELAPSED; if (!a.replace.replace_value) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "The promised pattern replace '%s' has no replacement string", pp->promiser); return PROMISE_RESULT_FAIL; } PromiseResult result = PROMISE_RESULT_NOOP; if (!a.haveregion) { begin_ptr = *start; end_ptr = NULL; //EndOfList(*start); } else if (!SelectRegion(ctx, *start, &begin_ptr, &end_ptr, &a, edcontext)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised pattern replace '%s' could not select an edit region in '%s'", pp->promiser, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } snprintf(lockname, CF_BUFSIZE - 1, "replace-%s-%s", pp->promiser, edcontext->filename); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } /* Make sure back references are expanded */ if (ReplacePatterns(ctx, begin_ptr, end_ptr, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } EvalContextVariableClearMatch(ctx); switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the replace_patterns promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "replace_patterns promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating replace_patterns promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating replace_patterns promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ static bool SelectNextItemMatching(EvalContext *ctx, const char *regexp, Item *begin, Item *end, Item **match, Item **prev) { Item *ip_prev = NULL; *match = NULL; *prev = NULL; for (Item *ip = begin; ip != end; ip = ip->next) { if (ip->name == NULL) { continue; } if (FullTextMatch(ctx, regexp, ip->name)) { *match = ip; *prev = ip_prev; return true; } ip_prev = ip; } return false; } /***************************************************************************/ static bool SelectLastItemMatching(EvalContext *ctx, const char *regexp, Item *begin, Item *end, Item **match, Item **prev) { assert(match != NULL); assert(prev != NULL); Item *ip, *ip_last = NULL, *ip_prev = NULL; *match = NULL; *prev = NULL; for (ip = begin; ip != end; ip = ip->next) { if (ip->name == NULL) { continue; } if (FullTextMatch(ctx, regexp, ip->name)) { *prev = ip_prev; ip_last = ip; } ip_prev = ip; } if (ip_last) { *match = ip_last; return true; } return false; } /***************************************************************************/ static bool SelectItemMatching(EvalContext *ctx, Item *start, char *regex, Item *begin_ptr, Item *end_ptr, Item **match, Item **prev, char *fl) { assert(match != NULL); assert(prev != NULL); Item *ip; bool ret = false; *match = NULL; *prev = NULL; if (regex == NULL) { return false; } if (StringEqual(fl, "first")) { if (SelectNextItemMatching(ctx, regex, begin_ptr, end_ptr, match, prev)) { ret = true; } } else { if (SelectLastItemMatching(ctx, regex, begin_ptr, end_ptr, match, prev)) { ret = true; } } if ((*match != NULL) && (*prev == NULL)) { for (ip = start; (ip != NULL) && (ip != *match); ip = ip->next) { *prev = ip; } } return ret; } /***************************************************************************/ static PromiseResult VerifyLineInsertions(EvalContext *ctx, const Promise *pp, EditContext *edcontext) { assert(pp != NULL); assert(edcontext != NULL); Item **start = &(edcontext->file_start), *match, *prev; Item *begin_ptr, *end_ptr; CfLock thislock; char lockname[CF_BUFSIZE]; Attributes a = GetInsertionAttributes(ctx, pp); int allow_multi_lines = StringEqual(a.sourcetype, "preserve_all_lines"); a.transaction.ifelapsed = CF_EDIT_IFELAPSED; if (!SanityCheckInsertions(&a)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, &a, "The promised line insertion '%s' breaks its own promises", pp->promiser); return PROMISE_RESULT_FAIL; } /* Are we working in a restricted region? */ PromiseResult result = PROMISE_RESULT_NOOP; if (!a.haveregion) { begin_ptr = *start; end_ptr = NULL; //EndOfList(*start); } else if (!SelectRegion(ctx, *start, &begin_ptr, &end_ptr, &a, edcontext)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised line insertion '%s' could not select an edit region in '%s'", pp->promiser, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } if (!end_ptr && a.region.select_end && !a.region.select_end_match_eof) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised end pattern '%s' was not found when selecting region to insert in '%s'", a.region.select_end, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); return result; } if (allow_multi_lines) { // promise to insert duplicates on first pass only snprintf(lockname, CF_BUFSIZE - 1, "insertline-%s-%s-%lu", pp->promiser, edcontext->filename, (long unsigned int) pp->offset.line); } else { snprintf(lockname, CF_BUFSIZE - 1, "insertline-%s-%s", pp->promiser, edcontext->filename); } thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, true); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } /* Are we looking for an anchored line inside the region? */ if (a.location.line_matching == NULL) { if (InsertMultipleLinesToRegion(ctx, start, begin_ptr, end_ptr, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } } else { if (!SelectItemMatching(ctx, *start, a.location.line_matching, begin_ptr, end_ptr, &match, &prev, a.location.first_last)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, &a, "The promised line insertion '%s' could not select a locator matching regex '%s' in '%s'", pp->promiser, a.location.line_matching, edcontext->filename); result = PromiseResultUpdate(result, PROMISE_RESULT_INTERRUPTED); YieldCurrentLock(thislock); return result; } if (InsertMultipleLinesAtLocation(ctx, start, begin_ptr, end_ptr, match, prev, &a, pp, edcontext, &result)) { (edcontext->num_edits)++; } } switch(result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "No changes done for the insert_lines promise '%s'", pp->promiser); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_INFO, result, pp, &a, "insert_lines promise '%s' repaired", pp->promiser); break; case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_WARNING, result, pp, &a, "Warnings encountered when actuating insert_lines promise '%s'", pp->promiser); break; default: cfPS(ctx, LOG_LEVEL_ERR, result, pp, &a, "Errors encountered when actuating insert_lines promise '%s'", pp->promiser); break; } YieldCurrentLock(thislock); return result; } /***************************************************************************/ /* Level */ /***************************************************************************/ static bool SelectRegion(EvalContext *ctx, Item *start, Item **begin_ptr, Item **end_ptr, const Attributes *a, EditContext *edcontext) /* This should provide pointers to the first and last line of text that include the delimiters, since we need to include those in case they are being deleted, etc. It returns true if a match was identified, else false. If no such region matches, begin_ptr and end_ptr should point to NULL */ { assert(a != NULL); assert(edcontext != NULL); assert(begin_ptr != NULL); assert(end_ptr != NULL); const char *const select_start = a->region.select_start; const char *const select_end = a->region.select_end; const int include_start = a->region.include_start; Item *ip, *beg = NULL, *end = NULL; for (ip = start; ip != NULL; ip = ip->next) { if (select_start) { if (!beg && FullTextMatch(ctx, select_start, ip->name)) { if (!include_start) { if (ip->next == NULL) { Log(LOG_LEVEL_VERBOSE, "The promised start pattern '%s' found an empty region at the end of file '%s'", select_start, edcontext->filename); return false; } } beg = ip; continue; } } if (select_end && beg) { if (!end && FullTextMatch(ctx, select_end, ip->name)) { end = ip; break; } } if (beg && end) { break; } } if (!beg && select_start) { Log(LOG_LEVEL_VERBOSE, "The promised start pattern '%s' was not found when selecting edit region in '%s'", select_start, edcontext->filename); return false; } *begin_ptr = beg; *end_ptr = end; return true; } /*****************************************************************************/ static int MatchRegion(EvalContext *ctx, const char *chunk, const Item *begin, const Item *end, bool regex) /* Match a region in between the selection delimiters. It is called after SelectRegion. The end delimiter will be visible here so we have to check for it. Can handle multi-line chunks */ { const Item *ip = begin; const size_t chunk_len = strlen(chunk); size_t buf_size = chunk_len + 1; char *buf = xmalloc(buf_size); int lines = 0; for (const char *sp = chunk; sp <= chunk + chunk_len; sp++) { buf[0] = '\0'; sscanf(sp, "%[^\n]", buf); sp += strlen(buf); if (ip == NULL) { lines = 0; goto bad; } if (!regex && !StringEqual(buf, ip->name)) { lines = 0; goto bad; } if (regex && !FullTextMatch(ctx, buf, ip->name)) { lines = 0; goto bad; } lines++; // We have to manually exclude the marked terminator if (ip == end) { lines = 0; goto bad; } // Now see if there is more if (ip->next) { ip = ip->next; } else // if the region runs out before the end { if (++sp <= chunk + chunk_len) { lines = 0; goto bad; } break; } } bad: free(buf); return lines; } /*****************************************************************************/ static bool InsertMultipleLinesToRegion(EvalContext *ctx, Item **start, Item *begin_ptr, Item *end_ptr, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); assert(edcontext != NULL); Item *ip, *prev = NULL; int allow_multi_lines = StringEqual(a->sourcetype, "preserve_all_lines"); // Insert at the start of the file if (*start == NULL) { return InsertMultipleLinesAtLocation(ctx, start, begin_ptr, end_ptr, *start, prev, a, pp, edcontext, result); } // Insert at the start of the region if (a->location.before_after == EDIT_ORDER_BEFORE) { /* As region was already selected by SelectRegion() and we know * what are the region boundaries (begin_ptr and end_ptr) there * is no reason to iterate over whole file. */ for (ip = begin_ptr; ip != NULL; ip = ip->next) { if (ip == begin_ptr) { return InsertMultipleLinesAtLocation(ctx, start, begin_ptr, end_ptr, ip, prev, a, pp, edcontext, result); } prev = ip; } } // Insert at the end of the region / else end of the file if (a->location.before_after == EDIT_ORDER_AFTER) { /* As region was already selected by SelectRegion() and we know * what are the region boundaries (begin_ptr and end_ptr) there * is no reason to iterate over whole file. It is safe to start from * begin_ptr. * As a bonus Redmine #7640 is fixed as we are not interested in * matching values outside of the region we are iterating over. */ for (ip = begin_ptr; ip != NULL; ip = ip->next) { if (!allow_multi_lines && MatchRegion(ctx, pp->promiser, ip, end_ptr, false)) { RecordNoChange(ctx, pp, a, "Promised chunk '%s' exists within selected region of %s", pp->promiser, edcontext->filename); return false; } if (ip->next != NULL && ip->next == end_ptr) { return InsertMultipleLinesAtLocation(ctx, start, begin_ptr, end_ptr, ip, prev, a, pp, edcontext, result); } if (ip->next == NULL) { return InsertMultipleLinesAtLocation(ctx, start, begin_ptr, end_ptr, ip, prev, a, pp, edcontext, result); } prev = ip; } } return false; } /***************************************************************************/ static bool InsertMultipleLinesAtLocation(EvalContext *ctx, Item **start, Item *begin_ptr, Item *end_ptr, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) // Promises to insert a possibly multi-line promiser at the specificed location convergently, // i.e. no insertion will be made if a neighbouring line matches { assert(pp != NULL); assert(a != NULL); const char *const type = a->sourcetype; bool isfileinsert = StringEqual(type, "file") || StringEqual(type, "file_preserve_block"); if (isfileinsert) { return InsertFileAtLocation(ctx, start, begin_ptr, end_ptr, location, prev, a, pp, edcontext, result); } else { return InsertCompoundLineAtLocation(ctx, pp->promiser, start, begin_ptr, end_ptr, location, prev, a, pp, edcontext, result); } } /***************************************************************************/ static bool DeletePromisedLinesMatching(EvalContext *ctx, Item **start, Item *begin, Item *end, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(pp != NULL); assert(edcontext != NULL); Item *ip, *np = NULL, *lp, *initiator = begin, *terminator = NULL; int i, matches, noedits = true; bool retval = false; if (start == NULL) { return false; } // Get a pointer from before the region so we can patch the hole later if (begin == NULL) { initiator = *start; } else { if (a->region.include_start) { initiator = begin; } else { initiator = begin->next; } } if (end == NULL) { terminator = NULL; } else { if (a->region.include_end) { terminator = end->next; } else { terminator = end; } } // Now do the deletion for (ip = initiator; ip != terminator && ip != NULL; ip = np) { if (a->not_matching) { matches = !MatchRegion(ctx, pp->promiser, ip, terminator, true); } else { matches = MatchRegion(ctx, pp->promiser, ip, terminator, true); } if (matches) { Log(LOG_LEVEL_VERBOSE, "Multi-line region (%d lines) matched text in the file", matches); } else { Log(LOG_LEVEL_DEBUG, "Multi-line region didn't match text in the file"); } if (!SelectLine(ctx, ip->name, a)) // Start search from location { np = ip->next; continue; } if (matches) { Log(LOG_LEVEL_VERBOSE, "Delete chunk of %d lines", matches); if (!MakingChanges(ctx, pp, a, result, "delete line '%s' from %s", ip->name, edcontext->filename)) { np = ip->next; noedits = false; } else { for (i = 1; i <= matches; i++) { RecordChange(ctx, pp, a, "Deleted the promised line %d '%s' from %s", i, ip->name, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; noedits = false; if (ip->name != NULL) { free(ip->name); } np = ip->next; if (ip == *start) { if (initiator == *start) { initiator = np; } *start = np; } else { if (ip == initiator) { initiator = *start; } for (lp = initiator; lp->next != ip; lp = lp->next) { } lp->next = np; } free((char *) ip); (edcontext->num_edits)++; ip = np; } } } else { np = ip->next; } } if (noedits) { RecordNoChange(ctx, pp, a, "No need to delete lines from %s, ok", edcontext->filename); } return retval; } /********************************************************************/ static bool ReplacePatterns(EvalContext *ctx, Item *file_start, Item *file_end, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); assert(edcontext != NULL); char line_buff[CF_EXPANDSIZE]; char after[CF_BUFSIZE]; size_t match_len; int start_off, end_off; bool once_only = false, retval = false; Item *ip; int cutoff = 1; bool notfound = true, replaced = false; if (StringEqual(a->replace.occurrences, "first")) { Log(LOG_LEVEL_WARNING, "Setting replace-occurrences policy to 'first' is not convergent"); once_only = true; } Buffer *replace = BufferNew(); for (ip = file_start; ip != NULL && ip != file_end; ip = ip->next) { if (ip->name == NULL) { continue; } cutoff = 1; strlcpy(line_buff, ip->name, sizeof(line_buff)); replaced = false; match_len = 0; while (BlockTextMatch(ctx, pp->promiser, line_buff, &start_off, &end_off)) { if (match_len == strlen(line_buff)) { Log(LOG_LEVEL_VERBOSE, "Improper convergent expression matches defacto convergence, so accepting"); break; } if (cutoff++ > CF_MAX_REPLACE) { Log(LOG_LEVEL_VERBOSE, "Too many replacements on this line"); break; } match_len = end_off - start_off; BufferClear(replace); ExpandScalar(ctx, PromiseGetBundle(pp)->ns, PromiseGetBundle(pp)->name, a->replace.replace_value, replace); Log(LOG_LEVEL_VERBOSE, "Verifying replacement of '%s' with '%s', cutoff %d", pp->promiser, BufferData(replace), cutoff); // Save portion of line after substitution: strlcpy(after, line_buff + end_off, sizeof(after)); // TODO: gripe if that truncated ! // Substitute into line_buff: snprintf(line_buff + start_off, sizeof(line_buff) - start_off, "%s%s", BufferData(replace), after); // TODO: gripe if that truncated or failed ! notfound = false; replaced = true; if (once_only) { Log(LOG_LEVEL_VERBOSE, "Replace first occurrence only (warning, this is not a convergent policy)"); break; } } if (NotAnchored(pp->promiser) && BlockTextMatch(ctx, pp->promiser, line_buff, &start_off, &end_off)) { RecordInterruption(ctx, pp, a, "Promised replacement '%s' on line '%s' for pattern '%s'" " is not convergent while editing '%s'" " (regular expression matches the replacement string)", line_buff, ip->name, pp->promiser, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); PromiseRef(LOG_LEVEL_ERR, pp); break; } if (!MakingChanges(ctx, pp, a, result, "replace pattern '%s' in '%s'", pp->promiser, edcontext->filename)) { continue; } else if (replaced) { free(ip->name); ip->name = xstrdup(line_buff); RecordChange(ctx, pp, a, "Replaced pattern '%s' in '%s'", pp->promiser, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); (edcontext->num_edits)++; retval = true; Log(LOG_LEVEL_VERBOSE, "cutoff %d, '%s'", cutoff, ip->name); Log(LOG_LEVEL_VERBOSE, "cutoff %d, '%s'", cutoff, line_buff); if (once_only) { Log(LOG_LEVEL_VERBOSE, "Replace first occurrence only (warning, this is not a convergent policy)"); break; } if (BlockTextMatch(ctx, pp->promiser, ip->name, &start_off, &end_off)) { RecordInterruption(ctx, pp, a, "Promised replacement '%s' for pattern '%s' is not properly convergent while editing '%s'" " (pattern still matches the end-state replacement string '%s', consider use" " of a negative look ahead)", ip->name, pp->promiser, edcontext->filename, line_buff); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); PromiseRef(LOG_LEVEL_INFO, pp); } } } BufferDestroy(replace); if (notfound) { RecordNoChange(ctx, pp, a, "No match for pattern '%s' in '%s'", pp->promiser, edcontext->filename); } return retval; } /********************************************************************/ static bool EditColumns(EvalContext *ctx, Item *file_start, Item *file_end, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); assert(edcontext != NULL); char separator[CF_MAXVARSIZE]; int s, e; bool retval = false; Item *ip; Rlist *columns = NULL; if (!ValidateRegEx(pp->promiser)) { return false; } bool found_match = false; for (ip = file_start; ip != file_end; ip = ip->next) { if (ip->name == NULL) { continue; } if (!FullTextMatch(ctx, pp->promiser, ip->name)) { continue; } else { found_match = true; Log(LOG_LEVEL_VERBOSE, "Matched line '%s'", ip->name); } if (!BlockTextMatch(ctx, a->column.column_separator, ip->name, &s, &e)) { RecordInterruption(ctx, pp, a, "Field edit, no fields found by promised pattern '%s' in '%s'", a->column.column_separator, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return false; } if (e - s > CF_MAXVARSIZE / 2) { Log(LOG_LEVEL_ERR, "Line split criterion matches a huge part of the line, seems to be in error"); return false; } strlcpy(separator, ip->name + s, e - s + 1); columns = RlistFromSplitRegex(ip->name, a->column.column_separator, CF_INFINITY, a->column.blanks_ok); retval = EditLineByColumn(ctx, &columns, a, pp, edcontext, result); if (retval) { free(ip->name); ip->name = Rlist2String(columns, separator); } RlistDestroy(columns); } if (!found_match) { RecordFailure(ctx, pp, a, "No matched line to edit fields of for pattern '%s' in '%s'", pp->promiser, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } return retval; } /***************************************************************************/ static bool SanityCheckInsertions(const Attributes *a) { assert(a != NULL); long not = 0; long with = 0; bool ok = true; Rlist *rp; InsertMatchType opt; int exact = false, ignore_something = false; const bool preserve_block = StringEqual(a->sourcetype, "preserve_block"); const LineSelect line_select = a->line_select; if (line_select.startwith_from_list) { with++; } if (line_select.not_startwith_from_list) { not++; } if (line_select.match_from_list) { with++; } if (line_select.not_match_from_list) { not++; } if (line_select.contains_from_list) { with++; } if (line_select.not_contains_from_list) { not++; } if (not > 1) { Log(LOG_LEVEL_ERR, "Line insertion selection promise is meaningless - the alternatives are mutually exclusive (only one is allowed)"); ok = false; } if (with && not) { Log(LOG_LEVEL_ERR, "Line insertion selection promise is meaningless - cannot mix positive and negative constraints"); ok = false; } for (rp = a->insert_match; rp != NULL; rp = rp->next) { opt = InsertMatchTypeFromString(RlistScalarValue(rp)); if (opt == INSERT_MATCH_TYPE_EXACT) { exact = true; } else { ignore_something = true; if (preserve_block) { Log(LOG_LEVEL_ERR, "Line insertion should not use whitespace policy with preserve_block"); ok = false; } } } if (exact && ignore_something) { Log(LOG_LEVEL_ERR, "Line insertion selection promise is meaningless - cannot mix exact_match with other ignore whitespace options"); ok = false; } return ok; } /***************************************************************************/ static bool SanityCheckDeletions(const Attributes *a, const Promise *pp) { assert(a != NULL); assert(pp != NULL); if (MultiLineString(pp->promiser)) { if (a->not_matching) { Log(LOG_LEVEL_ERR, "Makes no sense to promise multi-line delete with not_matching. Cannot be satisfied for all lines as a block."); // FIXME: This function always returns true (!) } } return true; } /***************************************************************************/ /* XXX */ static bool MatchPolicy(EvalContext *ctx, const char *camel, const char *haystack, Rlist *insert_match, const Promise *pp) { char *final = NULL; bool ok = false; bool escaped = false; Item *list = SplitString(camel, '\n'); //Split into separate lines first for (Item *ip = list; ip != NULL; ip = ip->next) { ok = false; bool direct_cmp = StringEqual(camel, haystack); final = xstrdup(ip->name); size_t final_size = strlen(final) + 1; if (insert_match == NULL) { // No whitespace policy means exact_match ok = ok || direct_cmp; break; } for (Rlist *rp = insert_match; rp != NULL; rp = rp->next) { const InsertMatchType opt = InsertMatchTypeFromString(RlistScalarValue(rp)); /* Exact match can be done immediately */ if (opt == INSERT_MATCH_TYPE_EXACT) { if ((rp->next != NULL) || (rp != insert_match)) { Log(LOG_LEVEL_ERR, "Multiple policies conflict with \"exact_match\", using exact match"); PromiseRef(LOG_LEVEL_ERR, pp); } ok = ok || direct_cmp; break; } if (!escaped) { // Need to escape the original string once here in case it contains regex chars when non-exact match // Check size of escaped string, and realloc if necessary size_t escape_regex_len = EscapeRegexCharsLen(ip->name); if (escape_regex_len + 1 > final_size) { final = xrealloc(final, escape_regex_len + 1); final_size = escape_regex_len + 1; } EscapeRegexChars(ip->name, final, final_size); escaped = true; } if (opt == INSERT_MATCH_TYPE_IGNORE_EMBEDDED) { // Strip initial and final first char *firstchar, *lastchar; for (firstchar = final; isspace((int)*firstchar); firstchar++); for (lastchar = final + final_size - 2; (lastchar > firstchar) && (isspace((int)*lastchar)); lastchar--); // Since we're stripping space and replacing it with \s+, we need to account for that // when allocating work size_t work_size = final_size + 6; /* allocated size */ char *work = xcalloc(1, work_size); /* We start only with the terminating '\0'. */ size_t required_size = 1; for (char *sp = final; *sp != '\0'; sp++) { char toadd[4]; if ((sp > firstchar) && (sp < lastchar)) { if (isspace((int)*sp)) { while (isspace((int)*(sp + 1))) { sp++; } required_size += 3; strcpy(toadd, "\\s+"); } else { required_size++; toadd[0] = *sp; toadd[1] = '\0'; } } else { required_size++; toadd[0] = *sp; toadd[1] = '\0'; } if (required_size > work_size) { // Increase by a small amount extra, so we don't // reallocate every iteration work_size = required_size + 12; work = xrealloc(work, work_size); } if (strlcat(work, toadd, work_size) >= work_size) { UnexpectedError("Truncation concatenating '%s' to: %s", toadd, work); } } // Realloc and retry on truncation if (strlcpy(final, work, final_size) >= final_size) { final = xrealloc(final, work_size); final_size = work_size; strlcpy(final, work, final_size); } free(work); } else if (opt == INSERT_MATCH_TYPE_IGNORE_LEADING) { if (!StringEqualN(final, "\\s*", 3)) { char *sp; for (sp = final; isspace((int)*sp); sp++); size_t work_size = final_size + 3; char *work = xcalloc(1, work_size); strcpy(work, sp); int written = snprintf(final, final_size, "\\s*%s", work); if (written < 0) { Log(LOG_LEVEL_ERR, "Unexpected failure from snprintf " "(%d - %s) on '%s' (MatchPolicy)", errno, GetErrorStr(), final); return false; } else if ((size_t) written >= final_size - 1) { final = xrealloc(final, work_size); final_size = work_size; written = snprintf(final, final_size, "\\s*%s", work); if (written < 0) { Log(LOG_LEVEL_ERR, "Unexpected failure from snprintf " "(%d - %s) on '%s' (MatchPolicy)", errno, GetErrorStr(), final); return false; } } free(work); } } else if (opt == INSERT_MATCH_TYPE_IGNORE_TRAILING) { if (!StringEqualN(final + final_size - 5, "\\s*", 3)) { const size_t work_size = final_size + 3; char *work = xcalloc(1, work_size); strcpy(work, final); char *sp; for (sp = work + work_size - 2; (sp > work) && (isspace((int)*sp)); sp--); *++sp = '\0'; int written = snprintf(final, final_size, "%s\\s*", work); if (written < 0) { Log(LOG_LEVEL_ERR, "Unexpected failure from snprintf " "(%d - %s) on '%s' (MatchPolicy)", errno, GetErrorStr(), final); return false; } else if ((size_t) written >= final_size - 1) { final = xrealloc(final, work_size); final_size = work_size; written = snprintf(final, final_size, "%s\\s*", work); if (written < 0) { Log(LOG_LEVEL_ERR, "Unexpected failure from snprintf " "(%d - %s) on '%s' (MatchPolicy)", errno, GetErrorStr(), final); return false; } } free(work); } } ok = ok || (FullTextMatch(ctx, final, haystack)); } assert(final_size > strlen(final)); free(final); final = NULL; if (!ok) // All lines in region need to match to avoid insertions { break; } } free(final); DeleteItemList(list); return ok; } static bool IsItemInRegion(EvalContext *ctx, const char *item, const Item *begin_ptr, const Item *end_ptr, Rlist *insert_match, const Promise *pp) { for (const Item *ip = begin_ptr; ((ip != end_ptr) && (ip != NULL)); ip = ip->next) { if (MatchPolicy(ctx, item, ip->name, insert_match, pp)) { return true; } } return false; } /***************************************************************************/ static bool InsertFileAtLocation(EvalContext *ctx, Item **start, Item *begin_ptr, Item *end_ptr, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); assert(edcontext != NULL); assert(result != NULL); FILE *fin; bool retval = false; Item *loc = NULL; const bool preserve_block = StringEqual(a->sourcetype, "file_preserve_block"); struct stat sb; if ((stat(pp->promiser, &sb) == 0) && S_ISDIR(sb.st_mode)) { RecordInterruption(ctx, pp, a, "Could not insert lines from a directory '%s'", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return false; } if ((fin = safe_fopen(pp->promiser, "rt")) == NULL) { RecordInterruption(ctx, pp, a, "Could not read file '%s'. (fopen: %s)", pp->promiser, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return false; } size_t buf_size = CF_BUFSIZE; char *buf = xmalloc(buf_size); loc = location; Buffer *exp = BufferNew(); while (CfReadLine(&buf, &buf_size, fin) != -1) { BufferClear(exp); if (a->expandvars) { ExpandScalar(ctx, PromiseGetBundle(pp)->ns, PromiseGetBundle(pp)->name, buf, exp); } else { BufferAppend(exp, buf, strlen(buf)); } if (!SelectLine(ctx, BufferData(exp), a)) { free(buf); buf = NULL; continue; } if (!preserve_block && IsItemInRegion(ctx, BufferData(exp), begin_ptr, end_ptr, a->insert_match, pp)) { RecordNoChange(ctx, pp, a, "Promised file line '%s' exists within file '%s'", BufferData(exp), edcontext->filename); free(buf); buf = NULL; continue; } // Need to call CompoundLine here in case ExpandScalar has inserted \n into a string if (InsertCompoundLineAtLocation(ctx, BufferGet(exp), start, begin_ptr, end_ptr, loc, prev, a, pp, edcontext, result)) { retval = true; } if (preserve_block && !prev) { // If we are inserting a preserved block before, need to flip the implied order after the first insertion // to get the order of the block right //a->location.before_after = cfe_after; } if (prev != NULL) { prev = prev->next; } else { prev = *start; } if (loc != NULL) { loc = loc->next; } free(buf); buf = NULL; } if (buf != NULL) { free(buf); } if (ferror(fin)) { if (errno == EISDIR) { RecordInterruption(ctx, pp, a, "'%s' is a directory, cannot lines into it", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); } else { UnexpectedError("Failed to read line from stream"); RecordFailure(ctx, pp, a, "Failed to read line from stream"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } fclose(fin); BufferDestroy(exp); return retval; } /***************************************************************************/ static bool InsertCompoundLineAtLocation(EvalContext *ctx, const char *chunk, Item **start, Item *begin_ptr, Item *end_ptr, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); assert(edcontext != NULL); assert(start != NULL); bool retval = false; const char *const type = a->sourcetype; const bool preserve_all_lines = StringEqual(type, "preserve_all_lines"); const bool preserve_block = type && (preserve_all_lines || StringEqual(type, "preserve_block") || StringEqual(type, "file_preserve_block")); if (!preserve_all_lines && MatchRegion(ctx, chunk, location, NULL, false)) { RecordNoChange(ctx, pp, a, "Promised chunk '%s' exists within selected region of %s (promise kept)", pp->promiser, edcontext->filename); return false; } // Iterate over any lines within the chunk const size_t chunk_len = strlen(chunk); char *buf = NULL; size_t buf_size = 0; for (const char *sp = chunk; sp <= chunk + chunk_len; sp++) { if (chunk_len + 1 > buf_size) { buf_size = chunk_len + 1; buf = xrealloc(buf, buf_size); } memset(buf, 0, buf_size); StringNotMatchingSetCapped(sp, buf_size, "\n", buf); sp += strlen(buf); if (!SelectLine(ctx, buf, a)) { continue; } if (!preserve_block && IsItemInRegion(ctx, buf, begin_ptr, end_ptr, a->insert_match, pp)) { RecordNoChange(ctx, pp, a, "Promised chunk '%s' exists within selected region of '%s'", pp->promiser, edcontext->filename); continue; } if (InsertLineAtLocation(ctx, buf, start, location, prev, a, pp, edcontext, result)) { retval = true; } if (preserve_block && a->location.before_after == EDIT_ORDER_BEFORE && location == NULL && prev == NULL) { // If we are inserting a preserved block before, need to flip the implied order after the first insertion // to get the order of the block right // a.location.before_after = cfe_after; location = *start; } if (prev != NULL) { prev = prev->next; } else { prev = *start; } if (location != NULL) { location = location->next; } else { location = *start; } } free(buf); return retval; } /** * Look for a line matching proposed insert before or after location */ static bool NeighbourItemMatches(EvalContext *ctx, const Item *file_start, const Item *location, const char *string, EditOrder pos, Rlist *insert_match, const Promise *pp) { if (location == NULL) { return false; } if (pos == EDIT_ORDER_AFTER) { return ((location->next != NULL) && (MatchPolicy(ctx, string, location->next->name, insert_match, pp))); } /* else => (pos == EDIT_ORDER_BEFORE) */ for (const Item *ip = file_start; ip != NULL; ip = ip->next) { if ((ip->next != NULL) && (ip->next == location)) { return (MatchPolicy(ctx, string, ip->name, insert_match, pp)); } } return false; } static bool InsertLineAtLocation(EvalContext *ctx, char *newline, Item **start, Item *location, Item *prev, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) /* Check line neighbourhood in whole file to avoid edge effects, iff we are not preseving block structure */ { assert(start != NULL); assert(a != NULL); assert(edcontext != NULL); bool preserve_block = (StringEqual(a->sourcetype, "preserve_block") || StringEqual(a->sourcetype, "file_preserve_block") || StringEqual(a->sourcetype, "preserve_all_lines")); if (!prev) /* Insert at first line */ { if (a->location.before_after == EDIT_ORDER_BEFORE) { if (*start == NULL) { if (!MakingChanges(ctx, pp, a, result, "insert promised line '%s' into '%s'", newline, edcontext->filename)) { return true; } else { PrependItemList(start, newline); (edcontext->num_edits)++; RecordChange(ctx, pp, a, "Inserted the promised line '%s' into '%s'", newline, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } } if (!StringEqual((*start)->name, newline)) { if (!MakingChanges(ctx, pp, a, result, "prepend promised line '%s' to '%s'", newline, edcontext->filename)) { return true; } else { PrependItemList(start, newline); (edcontext->num_edits)++; RecordChange(ctx, pp, a, "Prepended the promised line '%s' to %s", newline, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } } else { RecordNoChange(ctx, pp, a, "Promised line '%s' exists at start of file '%s'", newline, edcontext->filename); return false; } } } if (a->location.before_after == EDIT_ORDER_BEFORE) { if (!preserve_block && NeighbourItemMatches(ctx, *start, location, newline, EDIT_ORDER_BEFORE, a->insert_match, pp)) { RecordNoChange(ctx, pp, a, "Promised line '%s' exists before locator in '%s'", newline, edcontext->filename); return false; } else { if (!MakingChanges(ctx, pp, a, result, "insert line '%s' into '%s' before locator", newline, edcontext->filename)) { return true; } else { InsertAfter(start, prev, newline); (edcontext->num_edits)++; RecordChange(ctx, pp, a, "Inserted the promised line '%s' into '%s' before locator", newline, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } } } else { if (!preserve_block && NeighbourItemMatches(ctx, *start, location, newline, EDIT_ORDER_AFTER, a->insert_match, pp)) { RecordNoChange(ctx, pp, a, "Promised line '%s' exists after locator in '%s'", newline, edcontext->filename); return false; } else { if (!MakingChanges(ctx, pp, a, result, "insert line '%s' into '%s' after locator", newline, edcontext->filename)) { return true; } else { InsertAfter(start, location, newline); RecordChange(ctx, pp, a, "Inserted the promised line '%s' into '%s' after locator", newline, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); (edcontext->num_edits)++; return true; } } } } /***************************************************************************/ static bool EditLineByColumn(EvalContext *ctx, Rlist **columns, const Attributes *a, const Promise *pp, EditContext *edcontext, PromiseResult *result) { assert(a != NULL); assert(edcontext != NULL); Rlist *rp, *this_column = NULL; char sep[CF_MAXVARSIZE]; int i, count = 0; bool retval = false; /* Now break up the line into a list - not we never remove an item/column */ for (rp = *columns; rp != NULL; rp = rp->next) { count++; if (count == a->column.select_column) { Log(LOG_LEVEL_VERBOSE, "Stopped at field %d", count); break; } } if (a->column.select_column > count) { if (!a->column.extend_columns) { RecordInterruption(ctx, pp, a, "The file %s has only %d fields, but there is a promise for field %d", edcontext->filename, count, a->column.select_column); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); return false; } else { for (i = 0; i < (a->column.select_column - count); i++) { RlistAppendScalar(columns, ""); } count = 0; for (rp = *columns; rp != NULL; rp = rp->next) { count++; if (count == a->column.select_column) { Log(LOG_LEVEL_VERBOSE, "Stopped at column/field %d", count); break; } } } } if (a->column.value_separator != '\0') { /* internal separator, single char so split again */ if (strstr(RlistScalarValue(rp), a->column.column_value) || !StringEqual(RlistScalarValue(rp), a->column.column_value)) { if (!MakingChanges(ctx, pp, a, result, "edit field '%s' in '%s'", a->column.column_value, edcontext->filename)) { retval = false; } else { this_column = RlistFromSplitString(RlistScalarValue(rp), a->column.value_separator); retval = DoEditColumn(&this_column, edcontext, ctx, pp, a, result); if (retval) { (edcontext->num_edits)++; free(RlistScalarValue(rp)); sep[0] = a->column.value_separator; sep[1] = '\0'; rp->val.item = Rlist2String(this_column, sep); } } } else { retval = false; } RlistDestroy(this_column); return retval; } else { /* No separator, so we set the whole field to the value */ if (StringEqual(a->column.column_operation, "delete")) { if (!MakingChanges(ctx, pp, a, result, "delete field value '%s' in '%s'", RlistScalarValue(rp), edcontext->filename)) { return false; } else { free(rp->val.item); rp->val.item = xstrdup(""); RecordChange(ctx, pp, a, "Deleted column field value '%s' in '%s'", RlistScalarValue(rp), edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); (edcontext->num_edits)++; return true; } } else { if (!MakingChanges(ctx, pp, a, result, "set column field value '%s' to '%s' in '%s'", RlistScalarValue(rp), a->column.column_value, edcontext->filename)) { return false; } else { RecordChange(ctx, pp, a, "Set whole column field value '%s' to '%s' in '%s'", RlistScalarValue(rp), a->column.column_value, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); free(rp->val.item); rp->val.item = xstrdup(a->column.column_value); (edcontext->num_edits)++; return true; } } } RecordNoChange(ctx, pp, a, "No need to edit column field value '%s' in '%s'", a->column.column_value, edcontext->filename); return false; } /***************************************************************************/ static bool SelectLine(EvalContext *ctx, const char *line, const Attributes *a) { assert(a != NULL); Rlist *rp, *c; int s, e; char *selector; const LineSelect line_select = a->line_select; if ((c = line_select.startwith_from_list)) { for (rp = c; rp != NULL; rp = rp->next) { selector = RlistScalarValue(rp); if (StringStartsWith(line, selector)) { return true; } } return false; } if ((c = line_select.not_startwith_from_list)) { for (rp = c; rp != NULL; rp = rp->next) { selector = RlistScalarValue(rp); if (StringStartsWith(line, selector)) { return false; } } return true; } if ((c = line_select.match_from_list)) { for (rp = c; rp != NULL; rp = rp->next) { selector = RlistScalarValue(rp); if (FullTextMatch(ctx, selector, line)) { return true; } } return false; } if ((c = line_select.not_match_from_list)) { for (rp = c; rp != NULL; rp = rp->next) { selector = RlistScalarValue(rp); if (FullTextMatch(ctx, selector, line)) { return false; } } return true; } if ((c = line_select.contains_from_list)) { for (rp = c; rp != NULL; rp = rp->next) { selector = RlistScalarValue(rp); if (BlockTextMatch(ctx, selector, line, &s, &e)) { return true; } } return false; } if ((c = line_select.not_contains_from_list)) { for (rp = c; rp != NULL; rp = rp->next) { selector = RlistScalarValue(rp); if (BlockTextMatch(ctx, selector, line, &s, &e)) { return false; } } return true; } return true; } /***************************************************************************/ /* Level */ /***************************************************************************/ static bool DoEditColumn(Rlist **columns, EditContext *edcontext, EvalContext *ctx, const Promise *pp, const Attributes *a, PromiseResult *result) { assert(a != NULL); assert(edcontext != NULL); Rlist *rp, *found; bool retval = false; const char *const column_value = a->column.column_value; const char *const column_operation = a->column.column_operation; if (StringEqual(column_operation, "delete")) { while ((found = RlistKeyIn(*columns, column_value))) { RlistDestroyEntry(columns, found); RecordChange(ctx, pp, a, "Deleted column field sub-value '%s' in '%s'", column_value, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; } return retval; } if (StringEqual(column_operation, "set")) { int length = RlistLen(*columns); if (length == 1 && StringEqual(RlistScalarValue(*columns), column_value)) { RecordNoChange(ctx, pp, a, "Field sub-value set as promised"); return false; } else if (length == 0 && StringEqual("", column_value)) { RecordNoChange(ctx, pp, a, "Empty field sub-value set as promised"); return false; } RecordChange(ctx, pp, a, "Set field sub-value '%s' in '%s'", column_value, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); RlistDestroy(*columns); *columns = NULL; RlistPrependScalarIdemp(columns, column_value); return true; } if (StringEqual(column_operation, "prepend")) { if (RlistPrependScalarIdemp(columns, column_value)) { RecordChange(ctx, pp, a, "Prepended field sub-value '%s' in '%s'", column_value, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } else { RecordNoChange(ctx, pp, a, "Field sub-value '%s' already present in '%s'", column_value, edcontext->filename); return false; } } if (StringEqual(column_operation, "alphanum")) { if (RlistPrependScalarIdemp(columns, column_value)) { RecordChange(ctx, pp, a, "Inserted field sub-value '%s' in '%s'", column_value, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; } else { RecordNoChange(ctx, pp, a, "Field sub-value '%s' already present in '%s'", column_value, edcontext->filename); retval = false; } rp = AlphaSortRListNames(*columns); *columns = rp; return retval; } /* default operation is append */ if (RlistAppendScalarIdemp(columns, column_value)) { RecordChange(ctx, pp, a, "Appended field sub-value '%s' in '%s'", column_value, edcontext->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } else { RecordNoChange(ctx, pp, a, "Field sub-value '%s' already present in '%s'", column_value, edcontext->filename); return false; } return false; } /********************************************************************/ static bool NotAnchored(char *s) { assert(s != NULL); if (*s != '^') { return true; } if (*(s + strlen(s) - 1) != '$') { return true; } return false; } /********************************************************************/ static bool MultiLineString(char *s) { assert(s != NULL); return (strchr(s, '\n') != NULL); } cfengine-3.24.2/cf-agent/tokyo_check.c0000644000000000000000000003162215010704253017511 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #ifdef TCDB #include #include #include #include #include #include /* * The idea behind the following code comes from : copiousfreetime@github */ /* * Fields we will need from a TC record */ typedef struct TokyoCabinetRecord { uint64_t offset; uint64_t length; uint64_t left; uint64_t right; uint32_t key_size; uint32_t rec_size; uint16_t pad_size; uint8_t magic; uint8_t hash; } TokyoCabinetRecord; /* meta information from the Hash Database * used to coordinate the other operations */ typedef struct DBMeta { uint64_t bucket_count; /* Number of hash buckets */ uint64_t bucket_offset; /* Start of the bucket list */ uint64_t record_count; /* Number of records */ uint64_t record_offset; /* First record offset in file */ short alignment_pow; /* power of 2 for calculating offsets */ short bytes_per; /* 4 or 8 */ char dbpath[PATH_MAX + 1]; /* full pathname to the database file */ int fd; StringMap *offset_map; StringMap *record_map; } DBMeta; static DBMeta *DBMetaNewDirect(const char *dbfilename) { char hbuf[256]; DBMeta *dbmeta = xcalloc(1, sizeof(*dbmeta)); char *p = realpath(dbfilename, dbmeta->dbpath); if (p == NULL || -1 == (dbmeta->fd = open(dbmeta->dbpath, O_RDONLY))) { Log(LOG_LEVEL_ERR, "Failure opening file '%s' (%s: %s)", (p == NULL) ? dbfilename : dbmeta->dbpath, (p == NULL) ? "realpath" : "open", GetErrorStr()); free(dbmeta); return NULL; } if (256 != read(dbmeta->fd, hbuf, 256)) { Log(LOG_LEVEL_ERR, "Failure reading from database '%s'. (read: %s)", dbmeta->dbpath, GetErrorStr()); close(dbmeta->fd); if (dbmeta) { free(dbmeta); } return NULL; } memcpy(&(dbmeta->bucket_count), hbuf + 40, sizeof(uint64_t)); dbmeta->bucket_offset = 256; uint8_t opts; memcpy(&opts, hbuf + 36, sizeof(uint8_t)); dbmeta->bytes_per = (opts & (1 << 0)) ? sizeof(uint64_t) : sizeof(uint32_t); memcpy(&(dbmeta->record_count), hbuf + 48, sizeof(uint64_t)); memcpy(&(dbmeta->record_offset), hbuf + 64, sizeof(uint64_t)); memcpy(&(dbmeta->alignment_pow), hbuf + 34, sizeof(uint8_t)); dbmeta->offset_map = StringMapNew(); dbmeta->record_map = StringMapNew(); Log(LOG_LEVEL_VERBOSE, "Database : %s", dbmeta->dbpath); Log(LOG_LEVEL_VERBOSE, " number of buckets : %" PRIu64, dbmeta->bucket_count); Log(LOG_LEVEL_VERBOSE, " offset of buckets : %" PRIu64, dbmeta->bucket_offset); Log(LOG_LEVEL_VERBOSE, " bytes per pointer : %hd", dbmeta->bytes_per); Log(LOG_LEVEL_VERBOSE, " alignment power : %hd", dbmeta->alignment_pow); Log(LOG_LEVEL_VERBOSE, " number of records : %" PRIu64, dbmeta->record_count); Log(LOG_LEVEL_VERBOSE, " offset of records : %" PRIu64, dbmeta->record_offset); return dbmeta; } static void DBMetaFree(DBMeta * dbmeta) { StringMapDestroy(dbmeta->offset_map); StringMapDestroy(dbmeta->record_map); close(dbmeta->fd); if (dbmeta) { free(dbmeta); } } static int AddOffsetToMapUnlessExists(StringMap ** tree, uint64_t offset, int64_t bucket_index) { char *tmp; xasprintf(&tmp, "%" PRIu64, offset); char *val; if (StringMapHasKey(*tree, tmp) == false) { xasprintf(&val, "%" PRIu64, bucket_index); StringMapInsert(*tree, tmp, val); } else { Log(LOG_LEVEL_ERR, "Duplicate offset for value %" PRIu64 " at index %" PRId64 ", other value %" PRIu64 ", other index '%s'", offset, bucket_index, offset, (char *) StringMapGet(*tree, tmp)); free(tmp); } return 0; } static int DBMetaPopulateOffsetMap(DBMeta * dbmeta) { uint64_t i; if (lseek(dbmeta->fd, dbmeta->bucket_offset, SEEK_SET) == -1) { Log(LOG_LEVEL_ERR, "Error traversing bucket section to find record offsets '%s'", strerror(errno)); return 1; } for (i = 0; i < dbmeta->bucket_count; i++) { uint64_t offset = 0LL; int b = read(dbmeta->fd, &offset, dbmeta->bytes_per); if (b != dbmeta->bytes_per) { Log(LOG_LEVEL_ERR, "Read the wrong number of bytes (%d)", b); return 2; } /* if the value is > 0 then we have a number so do something with it */ if (offset > 0) { offset = offset << dbmeta->alignment_pow; if (AddOffsetToMapUnlessExists(&(dbmeta->offset_map), offset, i)) { return 3; } } } Log(LOG_LEVEL_VERBOSE, "Found %zu buckets with offsets", StringMapSize(dbmeta->offset_map)); return 0; } typedef enum { // enumeration for magic data MAGIC_DATA_BLOCK = 0xc8, // for data block MAGIC_FREE_BLOCK = 0xb0 // for free block } TypeOfBlock; static int TCReadVaryInt(int fd, uint32_t * result) { uint64_t num = 0; unsigned int base = 1; unsigned int i = 0; int read_bytes = 0; char c; while (true) { read_bytes += read(fd, &c, 1); if (c >= 0) { num += (c * base); break; } num += (base * (c + 1) * -1); base <<= 7; i += 1; } *result = num; return read_bytes; } static bool DBMetaReadOneRecord(DBMeta * dbmeta, TokyoCabinetRecord * rec) { if (lseek(dbmeta->fd, rec->offset, SEEK_SET) == -1) { Log(LOG_LEVEL_ERR, "Error traversing record section to find records : "); } while (true) { // get the location of the current read rec->offset = lseek(dbmeta->fd, 0, SEEK_CUR); if (rec->offset == (off_t) - 1) { Log(LOG_LEVEL_ERR, "Error traversing record section to find records"); } if (1 != read(dbmeta->fd, &(rec->magic), 1)) { Log(LOG_LEVEL_ERR, "Failure reading 1 byte, (read: %s)", GetErrorStr()); return false; } if (MAGIC_DATA_BLOCK == rec->magic) { Log(LOG_LEVEL_VERBOSE, "off=%" PRIu64 "[c8]", rec->offset); int length = 1; length += read(dbmeta->fd, &(rec->hash), 1); length += read(dbmeta->fd, &(rec->left), dbmeta->bytes_per); rec->left = rec->left << dbmeta->alignment_pow; length += read(dbmeta->fd, &(rec->right), dbmeta->bytes_per); rec->right = rec->right << dbmeta->alignment_pow; length += read(dbmeta->fd, &(rec->pad_size), 2); length += rec->pad_size; length += TCReadVaryInt(dbmeta->fd, &(rec->key_size)); length += TCReadVaryInt(dbmeta->fd, &(rec->rec_size)); rec->length = length + rec->key_size + rec->rec_size; return true; } else if (MAGIC_FREE_BLOCK == rec->magic) { Log(LOG_LEVEL_VERBOSE, "off=%" PRIu64 "[b0]", rec->offset); uint32_t length; rec->length = 1; rec->length += read(dbmeta->fd, &length, sizeof(length)); rec->length += length; return true; } else { Log(LOG_LEVEL_VERBOSE, "Read a non-magic byte (skip it)"); } } Log(LOG_LEVEL_ERR, "Read loop reached here"); return false; } static int DBMetaPopulateRecordMap(DBMeta * dbmeta) { off_t offset; uint64_t data_blocks = 0; uint64_t free_blocks = 0; struct stat st; offset = dbmeta->record_offset; if (fstat(dbmeta->fd, &st) == -1) { Log(LOG_LEVEL_ERR, "Error getting file stats. (fstat: %s)", GetErrorStr()); return 1; } while (offset < st.st_size) { TokyoCabinetRecord new_rec; memset(&new_rec, 0, sizeof(TokyoCabinetRecord)); new_rec.offset = offset; // read a variable-length record if (!DBMetaReadOneRecord(dbmeta, &new_rec)) { Log(LOG_LEVEL_ERR, "Unable to fetch a new record from DB file"); return 2; } else { offset = new_rec.offset + new_rec.length; } // if it is a data record then: // for the record, its left and right do: // look up that record in the offset tree // 1) remove it if it exists // 2) add it to the record_tree if it doesn't if (MAGIC_DATA_BLOCK == new_rec.magic) { if (new_rec.offset > 0) { char *key; xasprintf(&key, "%" PRIu64, new_rec.offset); if (StringMapHasKey(dbmeta->offset_map, key) == true) { if (key) { free(key); } } else { StringMapInsert(dbmeta->record_map, key, xstrdup("0")); } } else { Log(LOG_LEVEL_ERR, "new_rec.offset cannot be <= 0 ???"); } if (new_rec.left > 0) { Log(LOG_LEVEL_VERBOSE, "handle left %" PRIu64, new_rec.left); if (AddOffsetToMapUnlessExists (&(dbmeta->offset_map), new_rec.left, -1)) { return 4; } } if (new_rec.right > 0) { Log(LOG_LEVEL_VERBOSE, "handle right %" PRIu64, new_rec.right); if (AddOffsetToMapUnlessExists (&(dbmeta->offset_map), new_rec.right, -1)) { return 4; } } data_blocks++; } else if (MAGIC_FREE_BLOCK == new_rec.magic) { // if it is a fragment record, then skip it free_blocks++; } else { Log(LOG_LEVEL_ERR, "NO record found at offset %" PRIu64, new_rec.offset); } } // if we are not at the end of the file, output the current file offset // with an appropriate message and return Log(LOG_LEVEL_VERBOSE, "Found %" PRIu64 " data records and " "%" PRIu64 " free block records", data_blocks, free_blocks); return 0; } static int DBMetaGetResults(DBMeta * dbmeta) { uint64_t buckets_no_record = StringMapSize(dbmeta->offset_map); uint64_t records_no_bucket = StringMapSize(dbmeta->record_map); int ret = 0; Log(LOG_LEVEL_VERBOSE, "Found %" PRIu64 " offsets listed in buckets that do not have records", buckets_no_record); Log(LOG_LEVEL_VERBOSE, "Found %" PRIu64 " records in data that do not have an offset pointing to them", records_no_bucket); if (buckets_no_record > 0) { ret += 1; } if (records_no_bucket > 0) { ret += 2; } return ret; } int CheckTokyoDBCoherence(const char *path) { int ret = 0; DBMeta *dbmeta; dbmeta = DBMetaNewDirect(path); if (dbmeta == NULL) { return 1; } Log(LOG_LEVEL_VERBOSE, "Populating with bucket section offsets"); ret = DBMetaPopulateOffsetMap(dbmeta); if (ret) { goto clean; } Log(LOG_LEVEL_VERBOSE, "Populating with record section offsets"); ret = DBMetaPopulateRecordMap(dbmeta); if (ret) { goto clean; } ret = DBMetaGetResults(dbmeta); clean: if (dbmeta) { DBMetaFree(dbmeta); } return ret; } #else #include // ARG_UNUSED int CheckTokyoDBCoherence(ARG_UNUSED const char *path) { return 0; } #endif cfengine-3.24.2/cf-agent/cf-agent-enterprise-stubs.h0000644000000000000000000000547715010704253022225 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CF_AGENT_ENTERPRISE_STUBS_H #define CFENGINE_CF_AGENT_ENTERPRISE_STUBS_H #include #include #include #include #if defined(__MINGW32__) PromiseResult VerifyRegistryPromise(EvalContext *ctx, const Attributes *a, const Promise *pp); #endif typedef bool (*CopyRegularFileFunction)(EvalContext *ctx, const char *source, const char *dest, const struct stat *sstat, const Attributes *attr, const Promise *pp, CompressedArray **inode_cache, AgentConnection *conn, PromiseResult *result); typedef void (*DeleteCompressedArrayFunction)(CompressedArray *start); ENTERPRISE_FUNC_8ARG_DECLARE(PromiseResult, LogFileChange, EvalContext *, ctx, const char *, file, int, change, const Attributes *, attr, const Promise *, pp, CopyRegularFileFunction, CopyRegularFilePtr, const char *, destination, DeleteCompressedArrayFunction, DeleteCompressedArrayPtr); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, ReportPatches, PackageManager *, list); ENTERPRISE_VOID_FUNC_1ARG_DECLARE(void, Nova_TrackExecution, const char *, input_file); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, GenerateReports, const GenericAgentConfig *, config, const EvalContext *, ctx); ENTERPRISE_VOID_FUNC_2ARG_DECLARE(void, Nova_NoteAgentExecutionPerformance, const char *, input_file, struct timespec, start); #endif cfengine-3.24.2/cf-agent/files_changes.c0000644000000000000000000007227015010704253020005 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include /* The format of the changes database is as follows: Key: | Value: "D_" | "\0\0..." (SORTED!) | "H_ | "\0" | "S_ | "" Explanation: - The "D" entry contains all the filenames that have been recorded in that directory, stored as the basename. - The "H" entry records the hash of a file. - The "S" entry records the stat information of a file. */ #define CHANGES_HASH_STRING_LEN 7 #define CHANGES_HASH_FILE_NAME_OFFSET CHANGES_HASH_STRING_LEN+1 typedef struct { unsigned char mess_digest[EVP_MAX_MD_SIZE + 1]; /* Content digest */ } ChecksumValue; static bool GetDirectoryListFromDatabase(CF_DB *db, const char * path, Seq *files); static bool FileChangesSetDirectoryList(CF_DB *db, const char *path, const Seq *files, bool *change); /* * Key format: * * 7 bytes hash name, \0 padded at right * 1 byte \0 * N bytes pathname */ static char *NewIndexKey(char type, const char *name, int *size) { char *chk_key; // "H_" plus pathname plus index_str in one block + \0 const size_t len = strlen(name); *size = len + CHANGES_HASH_FILE_NAME_OFFSET + 3; chk_key = xcalloc(1, *size); // Data start after offset for index strlcpy(chk_key, "H_", 2); strlcpy(chk_key + 2, HashNameFromId(type), CHANGES_HASH_STRING_LEN); memcpy(chk_key + 2 + CHANGES_HASH_FILE_NAME_OFFSET, name, len); return chk_key; } static void DeleteIndexKey(char *key) { free(key); } static ChecksumValue *NewHashValue(unsigned char digest[EVP_MAX_MD_SIZE + 1]) { ChecksumValue *chk_val; chk_val = xcalloc(1, sizeof(ChecksumValue)); memcpy(chk_val->mess_digest, digest, EVP_MAX_MD_SIZE + 1); return chk_val; } static void DeleteHashValue(ChecksumValue *chk_val) { free(chk_val); } static bool ReadHash(CF_DB *dbp, HashMethod type, const char *name, unsigned char digest[EVP_MAX_MD_SIZE + 1]) { char *key; int size; ChecksumValue chk_val; key = NewIndexKey(type, name, &size); if (ReadComplexKeyDB(dbp, key, size, (void *) &chk_val, sizeof(ChecksumValue))) { memcpy(digest, chk_val.mess_digest, EVP_MAX_MD_SIZE + 1); DeleteIndexKey(key); return true; } else { DeleteIndexKey(key); return false; } } static int WriteHash(CF_DB *dbp, HashMethod type, const char *name, unsigned char digest[EVP_MAX_MD_SIZE + 1]) { char *key; ChecksumValue *value; int ret, keysize; key = NewIndexKey(type, name, &keysize); value = NewHashValue(digest); ret = WriteComplexKeyDB(dbp, key, keysize, value, sizeof(ChecksumValue)); DeleteIndexKey(key); DeleteHashValue(value); return ret; } static void DeleteHash(CF_DB *dbp, HashMethod type, const char *name) { int size; char *key; key = NewIndexKey(type, name, &size); DeleteComplexKeyDB(dbp, key, size); DeleteIndexKey(key); } static void AddMigratedFileToDirectoryList(CF_DB *changes_db, const char *file, const char *common_msg) { // This is incredibly inefficient, since we add files to the list one by one, // but the migration only ever needs to be done once for each host. size_t file_len = strlen(file); char dir[file_len + 1]; strcpy(dir, file); const char *basefile; char *last_slash = strrchr(dir, '/'); if (last_slash == NULL) { Log(LOG_LEVEL_ERR, "%s: Invalid file entry: '%s'", common_msg, dir); return; } if (last_slash == dir) { // If we only have one slash, it is the root dir, so we need to have // dir be equal to "/". We cannot both have that, and let basefile // point to the the next component in dir (since the first character // will then be '\0'), so point to the original file buffer instead. dir[1] = '\0'; basefile = file + 1; } else { basefile = last_slash + 1; *last_slash = '\0'; } Seq *files = SeqNew(1, free); if (!GetDirectoryListFromDatabase(changes_db, dir, files)) { Log(LOG_LEVEL_ERR, "%s: Not able to get directory index", common_msg); SeqDestroy(files); return; } if (SeqBinaryIndexOf(files, basefile, StrCmpWrapper) == -1) { SeqAppend(files, xstrdup(basefile)); SeqSort(files, StrCmpWrapper, NULL); bool changes; if (!FileChangesSetDirectoryList(changes_db, dir, files, &changes)) { Log(LOG_LEVEL_ERR, "%s: Not able to update directory index", common_msg); } } SeqDestroy(files); } static bool MigrateOldChecksumDatabase(CF_DB *changes_db) { CF_DB *old_db; const char *common_msg = "While converting old checksum database to new format"; if (!OpenDB(&old_db, dbid_checksums)) { Log(LOG_LEVEL_ERR, "%s: Could not open database.", common_msg); return false; } CF_DBC *cursor; if (!NewDBCursor(old_db, &cursor)) { Log(LOG_LEVEL_ERR, "%s: Could not open database cursor.", common_msg); CloseDB(old_db); return false; } char *key; int ksize; char *value; int vsize; while (NextDB(cursor, &key, &ksize, (void **)&value, &vsize)) { char new_key[ksize + 2]; new_key[0] = 'H'; new_key[1] = '_'; memcpy(new_key + 2, key, ksize); if (!WriteComplexKeyDB(changes_db, new_key, sizeof(new_key), value, vsize)) { Log(LOG_LEVEL_ERR, "%s: Could not write file checksum to database", common_msg); // Keep trying for other keys. } AddMigratedFileToDirectoryList(changes_db, key + CHANGES_HASH_FILE_NAME_OFFSET, common_msg); } DeleteDBCursor(cursor); CloseDB(old_db); return true; } static bool MigrateOldStatDatabase(CF_DB *changes_db) { CF_DB *old_db; const char *common_msg = "While converting old filestat database to new format"; if (!OpenDB(&old_db, dbid_filestats)) { Log(LOG_LEVEL_ERR, "%s: Could not open database.", common_msg); return false; } CF_DBC *cursor; if (!NewDBCursor(old_db, &cursor)) { Log(LOG_LEVEL_ERR, "%s: Could not open database cursor.", common_msg); CloseDB(old_db); return false; } char *key; int ksize; char *value; int vsize; while (NextDB(cursor, &key, &ksize, (void **)&value, &vsize)) { char new_key[ksize + 2]; new_key[0] = 'S'; new_key[1] = '_'; memcpy(new_key + 2, key, ksize); if (!WriteComplexKeyDB(changes_db, new_key, sizeof(new_key), value, vsize)) { Log(LOG_LEVEL_ERR, "%s: Could not write filestat to database", common_msg); // Keep trying for other keys. } AddMigratedFileToDirectoryList(changes_db, key, common_msg); } DeleteDBCursor(cursor); CloseDB(old_db); return true; } static bool OpenChangesDB(CF_DB **db) { if (!OpenDB(db, dbid_changes)) { Log(LOG_LEVEL_ERR, "Could not open changes database"); return false; } struct stat statbuf; char *old_checksums_db = DBIdToPath(dbid_checksums); char *old_filestats_db = DBIdToPath(dbid_filestats); if (stat(old_checksums_db, &statbuf) != -1) { Log(LOG_LEVEL_INFO, "Migrating checksum database"); MigrateOldChecksumDatabase(*db); char migrated_db_name[PATH_MAX]; snprintf(migrated_db_name, sizeof(migrated_db_name), "%s.cf-migrated", old_checksums_db); Log(LOG_LEVEL_INFO, "After checksum database migration: Renaming '%s' to '%s'", old_checksums_db, migrated_db_name); if (rename(old_checksums_db, migrated_db_name) != 0) { Log(LOG_LEVEL_ERR, "Could not rename '%s' to '%s'", old_checksums_db, migrated_db_name); } } if (stat(old_filestats_db, &statbuf) != -1) { Log(LOG_LEVEL_INFO, "Migrating filestat database"); MigrateOldStatDatabase(*db); char migrated_db_name[PATH_MAX]; snprintf(migrated_db_name, sizeof(migrated_db_name), "%s.cf-migrated", old_filestats_db); Log(LOG_LEVEL_INFO, "After filestat database migration: Renaming '%s' to '%s'", old_filestats_db, migrated_db_name); if (rename(old_filestats_db, migrated_db_name) != 0) { Log(LOG_LEVEL_ERR, "Could not rename '%s' to '%s'", old_filestats_db, migrated_db_name); } } free(old_checksums_db); free(old_filestats_db); return true; } static void RemoveAllFileTraces(CF_DB *db, const char *path) { for (int c = 0; c < HASH_METHOD_NONE; c++) { DeleteHash(db, c, path); } char key[strlen(path) + 3]; xsnprintf(key, sizeof(key), "S_%s", path); DeleteDB(db, key); } static bool GetDirectoryListFromDatabase(CF_DB *db, const char *path, Seq *files) { char key[strlen(path) + 3]; xsnprintf(key, sizeof(key), "D_%s", path); if (!HasKeyDB(db, key, sizeof(key))) { // Not an error, so successful, but seq remains unchanged. return true; } int size = ValueSizeDB(db, key, sizeof(key)); if (size <= 0) { // Shouldn't happen, since we don't store empty lists, but play it safe // and return empty seq. return true; } char raw_entries[size]; if (!ReadDB(db, key, raw_entries, size)) { Log(LOG_LEVEL_ERR, "Could not read changes database entry"); return false; } char *raw_entries_end = raw_entries + size; for (char *pos = raw_entries; pos < raw_entries_end;) { char *null_pos = memchr(pos, '\0', raw_entries_end - pos); if (!null_pos) { Log(LOG_LEVEL_ERR, "Unexpected end of value in changes database"); return false; } SeqAppend(files, xstrdup(pos)); pos = null_pos + 1; } return true; } bool FileChangesGetDirectoryList(const char *path, Seq *files) { CF_DB *db; if (!OpenChangesDB(&db)) { Log(LOG_LEVEL_ERR, "Could not open changes database"); return false; } bool result = GetDirectoryListFromDatabase(db, path, files); CloseDB(db); return result; } static bool FileChangesSetDirectoryList(CF_DB *db, const char *path, const Seq *files, bool *change) { assert(change != NULL); size_t size = 0; size_t n_files = SeqLength(files); char key[strlen(path) + 3]; xsnprintf(key, sizeof(key), "D_%s", path); if (n_files == 0) { *change = DeleteDB(db, key); return true; } for (int c = 0; c < n_files; c++) { size += strlen(SeqAt(files, c)) + 1; } char raw_entries[size]; char *pos = raw_entries; for (int c = 0; c < n_files; c++) { strcpy(pos, SeqAt(files, c)); pos += strlen(pos) + 1; } if (HasKeyDB(db, key, sizeof(key))) { char old_entries[MAX(size, 2 * CF_BUFSIZE)]; if (ReadDB(db, key, old_entries, sizeof(old_entries)) && (memcmp(old_entries, raw_entries, size) == 0)) { Log(LOG_LEVEL_VERBOSE, "No changes in directory list"); *change = false; return true; } } if (!WriteDB(db, key, raw_entries, size)) { Log(LOG_LEVEL_ERR, "Could not write to changes database"); return false; } *change = true; return true; } /** * @return %false if #filename never seen before, and adds a checksum to the * database; %true if hashes do not match and also updates database to * the new value if #update is true. */ bool FileChangesCheckAndUpdateHash(EvalContext *ctx, const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, const Attributes *attr, const Promise *pp, PromiseResult *result) { assert(attr != NULL); const int size = HashSizeFromId(type); unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; bool found; bool different; bool ret = false; bool update = attr->change.update; if (!OpenChangesDB(&dbp)) { RecordFailure(ctx, pp, attr, "Unable to open the hash database!"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { found = true; different = (memcmp(digest, dbdigest, size) != 0); if (different) { Log(LOG_LEVEL_INFO, "Hash '%s' for '%s' changed!", HashNameFromId(type), filename); if (pp->comment) { Log(LOG_LEVEL_VERBOSE, "Preceding promise '%s'", pp->comment); } } } else { found = false; different = true; } if (different) { /* TODO: Should we compare the stored hash with the digest of the file * in the changes chroot in case of ChrootChanges()? */ if (!MakingInternalChanges(ctx, pp, attr, result, "record change of hash for file '%s'", filename)) { ret = true; } else if (!found || update) { const char *action = found ? "Updated" : "Stored"; char buffer[CF_HOSTKEY_STRING_SIZE]; RecordChange(ctx, pp, attr, "%s %s hash for '%s' (%s)", action, HashNameFromId(type), filename, HashPrintSafe(buffer, sizeof(buffer), digest, type, true)); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); WriteHash(dbp, type, filename, digest); ret = found; } else { /* FIXME: FAIL if found?!?!?! */ RecordFailure(ctx, pp, attr, "Hash for file '%s' changed, but not updating the records", filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); ret = true; } } else { RecordNoChange(ctx, pp, attr, "File hash for %s is correct", filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_NOOP); ret = false; } CloseDB(dbp); return ret; } bool FileChangesLogNewFile(const char *path, const Promise *pp) { Log(LOG_LEVEL_NOTICE, "New file '%s' found", path); return FileChangesLogChange(path, FILE_STATE_NEW, "New file found", pp); } // db_file_set should already be sorted. void FileChangesCheckAndUpdateDirectory(EvalContext *ctx, const Attributes *attr, const char *name, const Seq *file_set, const Seq *db_file_set, bool update, const Promise *pp, PromiseResult *result) { CF_DB *db; if (!OpenChangesDB(&db)) { RecordFailure(ctx, pp, attr, "Could not open changes database"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return; } Seq *disk_file_set = SeqSoftSort(file_set, StrCmpWrapper, NULL); // We'll traverse the union of disk_file_set and db_file_set in merged order. int num_files = SeqLength(disk_file_set); int num_db_files = SeqLength(db_file_set); for (int disk_pos = 0, db_pos = 0; disk_pos < num_files || db_pos < num_db_files;) { int compare_result; if (disk_pos >= num_files) { compare_result = 1; } else if (db_pos >= num_db_files) { compare_result = -1; } else { compare_result = strcmp(SeqAt(disk_file_set, disk_pos), SeqAt(db_file_set, db_pos)); } if (compare_result < 0) { /* We would have called this here, but we assume that DepthSearch() has already done it for us. The reason is that calling it here produces a very unnatural order, with all stat and content changes, as well as all subdirectories, appearing in the log before the message about a new file. This is because we save the list for last and *then* compare it to the saved directory list, *after* traversing the tree. So we let DepthSearch() do it while traversing instead. Removed files will still be listed last. */ #if 0 char *file = SeqAt(disk_file_set, disk_pos); char path[strlen(name) + strlen(file) + 2]; xsnprintf(path, sizeof(path), "%s/%s", name, file); FileChangesLogNewFile(path, pp); #endif /* just make sure the change is reflected in the promise result */ *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); disk_pos++; } else if (compare_result > 0) { char *db_file = SeqAt(db_file_set, db_pos); char path[strlen(name) + strlen(db_file) + 2]; xsnprintf(path, sizeof(path), "%s/%s", name, db_file); Log(LOG_LEVEL_NOTICE, "File '%s' no longer exists", path); if (MakingInternalChanges(ctx, pp, attr, result, "record removal of '%s'", path)) { if (FileChangesLogChange(path, FILE_STATE_REMOVED, "File removed", pp)) { RecordChange(ctx, pp, attr, "Removal of '%s' recorded", path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to record removal of '%s'", path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } RemoveAllFileTraces(db, path); db_pos++; } else { // DB file entry and filesystem file entry matched. disk_pos++; db_pos++; } } if (MakingInternalChanges(ctx, pp, attr, result, "record directory listing for '%s'", name)) { bool changes = false; if (update && FileChangesSetDirectoryList(db, name, disk_file_set, &changes)) { if (changes) { RecordChange(ctx, pp, attr, "Recorded directory listing for '%s'", name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } else { RecordChange(ctx, pp, attr, "Failed to record directory listing for '%s'", name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } SeqSoftDestroy(disk_file_set); CloseDB(db); } void FileChangesCheckAndUpdateStats(EvalContext *ctx, const char *file, const struct stat *sb, bool update, const Attributes *attr, const Promise *pp, PromiseResult *result) { struct stat cmpsb; CF_DB *dbp; if (!OpenChangesDB(&dbp)) { RecordFailure(ctx, pp, attr, "Could not open changes database"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return; } char key[strlen(file) + 3]; xsnprintf(key, sizeof(key), "S_%s", file); if (!ReadDB(dbp, key, &cmpsb, sizeof(struct stat))) { if (MakingInternalChanges(ctx, pp, attr, result, "write stat information for '%s' to database", file)) { if (!WriteDB(dbp, key, sb, sizeof(struct stat))) { RecordFailure(ctx, pp, attr, "Could not write stat information for '%s' to database", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { RecordChange(ctx, pp, attr, "Wrote stat information for '%s' to database", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } CloseDB(dbp); return; } if (cmpsb.st_mode == sb->st_mode && cmpsb.st_uid == sb->st_uid && cmpsb.st_gid == sb->st_gid && cmpsb.st_dev == sb->st_dev && cmpsb.st_ino == sb->st_ino && cmpsb.st_mtime == sb->st_mtime) { RecordNoChange(ctx, pp, attr, "No stat information change for '%s'", file); CloseDB(dbp); return; } if (cmpsb.st_mode != sb->st_mode) { Log(LOG_LEVEL_NOTICE, "Permissions for '%s' changed %04jo -> %04jo", file, (uintmax_t)cmpsb.st_mode, (uintmax_t)sb->st_mode); char msg_temp[CF_MAXVARSIZE]; snprintf(msg_temp, sizeof(msg_temp), "Permission: %04jo -> %04jo", (uintmax_t)cmpsb.st_mode, (uintmax_t)sb->st_mode); if (MakingInternalChanges(ctx, pp, attr, result, "record permissions changes in '%s'", file)) { if (FileChangesLogChange(file, FILE_STATE_STATS_CHANGED, msg_temp, pp)) { RecordChange(ctx, pp, attr, "Recorded permissions changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to record permissions changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } } if (cmpsb.st_uid != sb->st_uid) { Log(LOG_LEVEL_NOTICE, "Owner for '%s' changed %ju -> %ju", file, (uintmax_t) cmpsb.st_uid, (uintmax_t) sb->st_uid); char msg_temp[CF_MAXVARSIZE]; snprintf(msg_temp, sizeof(msg_temp), "Owner: %ju -> %ju", (uintmax_t) cmpsb.st_uid, (uintmax_t) sb->st_uid); if (MakingInternalChanges(ctx, pp, attr, result, "record ownership changes in '%s'", file)) { if (FileChangesLogChange(file, FILE_STATE_STATS_CHANGED, msg_temp, pp)) { RecordChange(ctx, pp, attr, "Recorded ownership changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to record ownership changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } } if (cmpsb.st_gid != sb->st_gid) { Log(LOG_LEVEL_NOTICE, "Group for '%s' changed %ju -> %ju", file, (uintmax_t) cmpsb.st_gid, (uintmax_t) sb->st_gid); char msg_temp[CF_MAXVARSIZE]; snprintf(msg_temp, sizeof(msg_temp), "Group: %ju -> %ju", (uintmax_t)cmpsb.st_gid, (uintmax_t)sb->st_gid); if (MakingInternalChanges(ctx, pp, attr, result, "record group changes in '%s'", file)) { if (FileChangesLogChange(file, FILE_STATE_STATS_CHANGED, msg_temp, pp)) { RecordChange(ctx, pp, attr, "Recorded group changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to record group changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } } if (cmpsb.st_dev != sb->st_dev) { Log(LOG_LEVEL_NOTICE, "Device for '%s' changed %ju -> %ju", file, (uintmax_t) cmpsb.st_dev, (uintmax_t) sb->st_dev); char msg_temp[CF_MAXVARSIZE]; snprintf(msg_temp, sizeof(msg_temp), "Device: %ju -> %ju", (uintmax_t)cmpsb.st_dev, (uintmax_t)sb->st_dev); if (MakingInternalChanges(ctx, pp, attr, result, "record device changes in '%s'", file)) { if (FileChangesLogChange(file, FILE_STATE_STATS_CHANGED, msg_temp, pp)) { RecordChange(ctx, pp, attr, "Recorded device changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to record device changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } } if (cmpsb.st_ino != sb->st_ino) { Log(LOG_LEVEL_NOTICE, "inode for '%s' changed %ju -> %ju", file, (uintmax_t) cmpsb.st_ino, (uintmax_t) sb->st_ino); } if (cmpsb.st_mtime != sb->st_mtime) { char from[25]; // ctime() string is 26 bytes (incl NUL) char to[25]; // we ignore the newline at the end // Example: "Thu Nov 24 18:22:48 1986\n" // TODO: Should be possible using memcpy // but I ran into some weird issues when trying // to assert the contents of ctime() StringCopy(ctime(&(cmpsb.st_mtime)), from, 25); StringCopy(ctime(&(sb->st_mtime)), to, 25); assert(strlen(from) == 24); assert(strlen(to) == 24); Log(LOG_LEVEL_NOTICE, "Last modified time for '%s' changed '%s' -> '%s'", file, from, to); char msg_temp[CF_MAXVARSIZE]; snprintf(msg_temp, sizeof(msg_temp), "Modified time: %s -> %s", from, to); if (MakingInternalChanges(ctx, pp, attr, result, "record mtime changes in '%s'", file)) { if (FileChangesLogChange(file, FILE_STATE_STATS_CHANGED, msg_temp, pp)) { RecordChange(ctx, pp, attr, "Recorded mtime changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, attr, "Failed to record mtime changes in '%s'", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } } if (pp->comment) { Log(LOG_LEVEL_VERBOSE, "Preceding promise '%s'", pp->comment); } if (update) { if (MakingInternalChanges(ctx, pp, attr, result, "write stat information for '%s' to database", file)) { if (!DeleteDB(dbp, key) || !WriteDB(dbp, key, sb, sizeof(struct stat))) { RecordFailure(ctx, pp, attr, "Failed to write stat information for '%s' to database", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { RecordChange(ctx, pp, attr, "Wrote stat information changes for '%s' to database", file); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } } CloseDB(dbp); } static char FileStateToChar(FileState status) { switch(status) { case FILE_STATE_NEW: return 'N'; case FILE_STATE_REMOVED: return 'R'; case FILE_STATE_CONTENT_CHANGED: return 'C'; case FILE_STATE_STATS_CHANGED: return 'S'; default: ProgrammingError("Unhandled file status in switch: %d", status); } } bool FileChangesLogChange(const char *file, FileState status, char *msg, const Promise *pp) { char fname[CF_BUFSIZE]; time_t now = time(NULL); /* This is inefficient but we don't want to lose any data */ snprintf(fname, CF_BUFSIZE, "%s/%s", GetStateDir(), CF_FILECHANGE_NEW); MapName(fname); #ifndef __MINGW32__ struct stat sb; if (stat(fname, &sb) != -1) { if (sb.st_mode & (S_IWGRP | S_IWOTH)) { Log(LOG_LEVEL_ERR, "File '%s' (owner %ju) was writable by others (security exception)", fname, (uintmax_t)sb.st_uid); } } #endif /* !__MINGW32__ */ FILE *fp = safe_fopen(fname, "a"); if (fp == NULL) { Log(LOG_LEVEL_ERR, "Could not write to the hash change log. (fopen: %s)", GetErrorStr()); return false; } const char *handle = PromiseID(pp); fprintf(fp, "%lld,%s,%s,%c,%s\n", (long long) now, handle, file, FileStateToChar(status), msg); fclose(fp); return true; } cfengine-3.24.2/cf-agent/files_edit.c0000644000000000000000000002011315010704253017307 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include /*****************************************************************************/ EditContext *NewEditContext(char *filename, const Attributes *a) { assert(a != NULL); EditContext *ec; if (!IsAbsoluteFileName(filename)) { Log(LOG_LEVEL_ERR, "Relative file name '%s' was marked for editing but has no invariant meaning", filename); return NULL; } ec = xcalloc(1, sizeof(EditContext)); ec->filename = filename; /* If making changes in chroot, we need to load the file from the chroot * instead. */ if (ChrootChanges()) { ec->changes_filename = xstrdup(ToChangesChroot(filename)); } else { ec->changes_filename = xstrdup(filename); } ec->new_line_mode = FileNewLineMode(ec->changes_filename); if (a->haveeditline) { if (!LoadFileAsItemList(&(ec->file_start), ec->changes_filename, a->edits, a->edits.empty_before_use)) { free(ec); return NULL; } } if (a->haveeditxml) { #ifdef HAVE_LIBXML2 if (!LoadFileAsXmlDoc(&(ec->xmldoc), ec->changes_filename, a->edits, a->edits.empty_before_use)) { free(ec); return NULL; } #else Log(LOG_LEVEL_ERR, "Cannot edit XML files without LIBXML2"); free(ec); return NULL; #endif } if (a->edits.empty_before_use) { Log(LOG_LEVEL_VERBOSE, "Build file model from a blank slate"); } return ec; } /*****************************************************************************/ void FinishEditContext(EvalContext *ctx, EditContext *ec, const Attributes *a, const Promise *pp, PromiseResult *result) { if ((*result != PROMISE_RESULT_NOOP) && (*result != PROMISE_RESULT_CHANGE)) { // Failure or skipped. Don't update the file. goto end; } /* If some edits are to be saved, but we are not making changes to * files (dry-run), just log the fact (MakingChanges() does that). */ if ((ec != NULL) && (ec->num_edits > 0) && !CompareToFile(ctx, ec->file_start, ec->changes_filename, a, pp, result) && !MakingChanges(ctx, pp, a, result, "edit file '%s'", ec->filename)) { goto end; } else if (ec && (ec->num_edits > 0)) { if (a->haveeditline || a->edit_template || a->edit_template_string) { if (CompareToFile(ctx, ec->file_start, ec->changes_filename, a, pp, result)) { RecordNoChange(ctx, pp, a, "No edit changes to file '%s' need saving", ec->filename); } else if (SaveItemListAsFile(ec->file_start, ec->changes_filename, a, ec->new_line_mode)) { RecordChange(ctx, pp, a, "Edited file '%s'", ec->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, a, "Unable to save file '%s' after editing", ec->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } } if (a->haveeditxml) { #ifdef HAVE_LIBXML2 if (XmlCompareToFile(ec->xmldoc, ec->changes_filename, a->edits)) { if (ec) { RecordNoChange(ctx, pp, a, "No edit changes to xml file '%s' need saving", ec->filename); } } else if (SaveXmlDocAsFile(ec->xmldoc, ec->changes_filename, a, ec->new_line_mode)) { RecordChange(ctx, pp, a, "Edited xml file '%s'", ec->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } else { RecordFailure(ctx, pp, a, "Failed to edit XML file '%s'", ec->filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } xmlFreeDoc(ec->xmldoc); #else RecordFailure(ctx, pp, a, "Cannot edit XML files without LIBXML2"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); #endif } } else if (ec) { RecordNoChange(ctx, pp, a, "No edit changes to file '%s' need saving", ec->filename); } end: if (ec != NULL) { DeleteItemList(ec->file_start); free(ec->changes_filename); free(ec); } } /*********************************************************************/ /* Level */ /*********************************************************************/ #ifdef HAVE_LIBXML2 /***************************************************************************/ bool LoadFileAsXmlDoc(xmlDocPtr *doc, const char *file, EditDefaults edits, bool only_checks) { assert (doc != NULL); struct stat statbuf; if (stat(file, &statbuf) == -1) { Log(LOG_LEVEL_ERR, "The proposed file '%s' could not be loaded. (stat: %s)", file, GetErrorStr()); return false; } if (edits.maxfilesize != 0 && statbuf.st_size > edits.maxfilesize) { Log(LOG_LEVEL_INFO, "File '%s' is bigger than the edit limit. max_file_size = '%jd' > '%d' bytes", file, (intmax_t) statbuf.st_size, edits.maxfilesize); return false; } if (!S_ISREG(statbuf.st_mode)) { Log(LOG_LEVEL_INFO, "'%s' is not a plain file", file); return false; } if (only_checks || (statbuf.st_size == 0)) { /* Checks done and none of them failed and returned we can just return * an empty doc here. */ if ((*doc = xmlNewDoc(BAD_CAST "1.0")) == NULL) { Log(LOG_LEVEL_INFO, "Document '%s' not parsed successfully. (xmlNewDoc: %s)", file, GetErrorStr()); return false; } return true; } *doc = xmlParseFile(file); if (doc == NULL) { Log(LOG_LEVEL_INFO, "Document '%s' not parsed successfully. (xmlParseFile: %s)", file, GetErrorStr()); return false; } return true; } /*********************************************************************/ static bool SaveXmlCallback(const char *dest_filename, void *param, ARG_UNUSED NewLineMode new_line_mode) { xmlDocPtr doc = param; //saving xml to file if (xmlSaveFile(dest_filename, doc) == -1) { Log(LOG_LEVEL_ERR, "Failed to write xml document to file '%s' after editing. (xmlSaveFile: %s)", dest_filename, GetErrorStr()); return false; } return true; } /*********************************************************************/ bool SaveXmlDocAsFile(xmlDocPtr doc, const char *file, const Attributes *a, NewLineMode new_line_mode) { return SaveAsFile(&SaveXmlCallback, doc, file, a, new_line_mode); } #endif /* HAVE_LIBXML2 */ cfengine-3.24.2/cf-agent/files_properties.c0000644000000000000000000001003215010704253020555 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include static Item *SUSPICIOUSLIST = NULL; /* GLOBAL_P */ void AddFilenameToListOfSuspicious(const char *pattern) { PrependItem(&SUSPICIOUSLIST, pattern, NULL); } static const char *const SKIPFILES[] = { ".", "..", "lost+found", ".cfengine.rm", NULL }; /* TODO rework to accept only one param: path+nodename */ static bool ConsiderFile(const char *nodename, const char *path, struct stat *stat) { int i; if (nodename[0] == '\0') { Log(LOG_LEVEL_ERR, "Empty (null) filename detected in '%s', skipping", path); return false; } if (stat != NULL && (S_ISREG(stat->st_mode) || S_ISLNK(stat->st_mode)) && IsItemIn(SUSPICIOUSLIST, nodename)) { Log(LOG_LEVEL_WARNING, "Filename '%s/%s' is classified as suspiscious, skipping", path, nodename); return false; } /* A file named '...' is likely to be a path traversal attempt, see http://cwe.mitre.org/data/definitions/32.html */ if (strcmp(nodename, "...") == 0) { Log(LOG_LEVEL_WARNING, "Possible path traversal attempt detected in '%s/%s', skipping", path, nodename); return false; } for (i = 0; SKIPFILES[i] != NULL; i++) { if (strcmp(nodename, SKIPFILES[i]) == 0) { Log(LOG_LEVEL_VERBOSE, "Filename '%s/%s' is classified as ignorable, skipping", path, nodename); return false; } } return true; } bool ConsiderLocalFile(const char *filename, const char *directory) { struct stat stat; if (lstat(filename, &stat) == -1) { return ConsiderFile(filename, directory, NULL); } else { return ConsiderFile(filename, directory, &stat); } } bool ConsiderAbstractFile(const char *filename, const char *directory, const FileCopy *fc, AgentConnection *conn) { /* First check if the file should be avoided, e.g. ".." - before sending * anything over the network*/ if (!ConsiderFile(filename, directory, NULL)) { return false; } /* TODO this function should accept the joined path in the first place * since it's joined elsewhere as well, if split needed do it here. */ char buf[CF_BUFSIZE]; int ret = snprintf(buf, sizeof(buf), "%s/%s", directory, filename); if (ret < 0) { Log(LOG_LEVEL_ERR, "Unexpected failure from snprintf (%d - %s) on '%s' " "(ConsiderAbstractFile)", errno, GetErrorStr(), buf); return false; } else if ((size_t) ret >= sizeof(buf)) { Log(LOG_LEVEL_ERR, "Filename too long! Directory '%s' filename '%s'", directory, filename); return false; } /* Second, send the STAT command. */ struct stat stat; if (cf_lstat(buf, &stat, fc, conn) == -1) { return false; /* stat() failed */ } else { /* Reconsider, but using stat info this time. */ return ConsiderFile(filename, directory, &stat); } } cfengine-3.24.2/cf-agent/verify_users.c0000644000000000000000000000674015010704253017737 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include static bool UserSanityCheck(const Attributes *a, const Promise *pp); PromiseResult VerifyUsersPromise(EvalContext *ctx, const Promise *pp) { CfLock thislock; char lockname[CF_BUFSIZE]; Attributes a = GetUserAttributes(ctx, pp); if (!UserSanityCheck(&a, pp)) { return PROMISE_RESULT_FAIL; } PromiseBanner(ctx, pp); snprintf(lockname, CF_BUFSIZE - 1, "user-%s-%d", pp->promiser, a.users.policy); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, false); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } PromiseResult result = PROMISE_RESULT_NOOP; VerifyOneUsersPromise(pp->promiser, &(a.users), &result, a.transaction.action, ctx, &a, pp); switch (result) { case PROMISE_RESULT_NOOP: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, &a, "User promise kept"); break; case PROMISE_RESULT_FAIL: case PROMISE_RESULT_DENIED: case PROMISE_RESULT_TIMEOUT: case PROMISE_RESULT_INTERRUPTED: case PROMISE_RESULT_WARN: cfPS(ctx, LOG_LEVEL_VERBOSE, result, pp, &a, "User promise not kept"); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, &a, "User promise repaired"); break; default: ProgrammingError("Unknown promise result"); break; } YieldCurrentLock(thislock); return result; } /** Pre-check of promise contents **/ static bool UserSanityCheck(const Attributes *a, const Promise *pp) { assert(a != NULL); const User *u = &(a->users); switch (u->policy) { case USER_STATE_PRESENT: case USER_STATE_ABSENT: case USER_STATE_LOCKED: break; default: Log(LOG_LEVEL_ERR, "No policy specified for 'users' promise '%s'", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return false; } if ((SafeStringLength(u->password) == 0 && u->password_format != PASSWORD_FORMAT_NONE) || (SafeStringLength(u->password) != 0 && u->password_format == PASSWORD_FORMAT_NONE)) { Log(LOG_LEVEL_ERR, "Both 'data' and 'format' must be specified in password body for 'users' promise '%s'", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); return false; } return true; } cfengine-3.24.2/cf-agent/verify_processes.c0000644000000000000000000003602315010704253020601 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static PromiseResult VerifyProcesses(EvalContext *ctx, const Attributes *a, const Promise *pp); static bool ProcessSanityChecks(const Attributes *a, const Promise *pp); static PromiseResult VerifyProcessOp(EvalContext *ctx, const Attributes *a, const Promise *pp); static int FindPidMatches(Item **killlist, const Attributes *a, const char *promiser); PromiseResult VerifyProcessesPromise(EvalContext *ctx, const Promise *pp) { Attributes a = GetProcessAttributes(ctx, pp); ProcessSanityChecks(&a, pp); return VerifyProcesses(ctx, &a, pp); } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static bool ProcessSanityChecks(const Attributes *a, const Promise *pp) { assert(a != NULL); assert(pp != NULL); // Note that an undefined match_value results in process_count.min_range and max_range being set to CF_NOINT bool promised_zero = ((a->process_count.min_range == 0) && (a->process_count.max_range == 0)); bool ret = true; if (a->restart_class) { if ((RlistKeyIn(a->signals, "term")) || (RlistKeyIn(a->signals, "kill"))) { Log(LOG_LEVEL_WARNING, "Promise '%s' kills then restarts - never strictly converges", pp->promiser); PromiseRef(LOG_LEVEL_INFO, pp); } if (a->haveprocess_count) { Log(LOG_LEVEL_VERBOSE, "Note both process_count and restart_class define classes. Please exercises caution that there is not a logic error. Review process_count match_range, in_range_define, and out_of_range_define with respect to restart_class."); PromiseRef(LOG_LEVEL_VERBOSE, pp); ret = false; } } if (promised_zero && (a->restart_class)) { Log(LOG_LEVEL_ERR, "Promise constraint conflicts - '%s' processes cannot have zero count if restarted", pp->promiser); PromiseRef(LOG_LEVEL_ERR, pp); ret = false; } if ((a->haveselect) && (!a->process_select.process_result)) { Log(LOG_LEVEL_ERR, "Process select constraint body promised no result (check body definition)"); PromiseRef(LOG_LEVEL_ERR, pp); ret = false; } // CF_NOINT is the value assigned when match_range is not specified if ((a->haveprocess_count) && ((a->process_count.min_range == CF_NOINT) || (a->process_count.max_range == CF_NOINT))) { Log(LOG_LEVEL_ERR, "process_count used without match_range, this promise will not define a class based on a count of matching promises."); PromiseRef(LOG_LEVEL_ERR, pp); ret = false; } if ((a->haveprocess_count) && !((a->process_count.in_range_define) || (a->process_count.out_of_range_define))) { Log(LOG_LEVEL_ERR, "process_count body is insufficiently defined. process_count must specify at least one of in_range_define or out_of_range_define. "); PromiseRef(LOG_LEVEL_ERR, pp); ret = false; } return ret; } /*****************************************************************************/ static PromiseResult VerifyProcesses(EvalContext *ctx, const Attributes *a, const Promise *pp) { CfLock thislock; char lockname[CF_BUFSIZE]; if (a->restart_class) { snprintf(lockname, CF_BUFSIZE - 1, "proc-%s-%s", pp->promiser, a->restart_class); } else { snprintf(lockname, CF_BUFSIZE - 1, "proc-%s-norestart", pp->promiser); } thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a->transaction.ifelapsed, a->transaction.expireafter, pp, false); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } PromiseBanner(ctx, pp); PromiseResult result = VerifyProcessOp(ctx, a, pp); YieldCurrentLock(thislock); return result; } static void ProcessCountMaybeDefineClass( EvalContext *const ctx, const Rlist *const rp, const Promise *const pp, const char *const attribute_name) { assert(ctx != NULL); assert(rp != NULL); assert(pp != NULL); assert(attribute_name != NULL && strlen(attribute_name) > 0); if (rp->val.type == RVAL_TYPE_FNCALL) { Log(LOG_LEVEL_ERR, "Body (process_count), for processes promise %s, has a failing function call (%s) in the %s attribute - cannot define the class", pp->promiser, RlistFnCallValue(rp)->name, attribute_name); return; } assert(rp->val.type == RVAL_TYPE_SCALAR); ClassRef ref = ClassRefParse(RlistScalarValue(rp)); EvalContextClassPutSoft( ctx, RlistScalarValue(rp), CONTEXT_SCOPE_NAMESPACE, "source=promise"); ClassRefDestroy(ref); } static PromiseResult VerifyProcessOp(EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(a != NULL); assert(pp != NULL); Item *matched_procs = NULL; int matches = FindPidMatches(&matched_procs, a, pp->promiser); /* promise based on number of matches */ PromiseResult result = PROMISE_RESULT_NOOP; if (a->process_count.min_range != CF_NOINT) /* if a range is specified */ { if ((matches < a->process_count.min_range) || (matches > a->process_count.max_range)) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Process count for '%s' was out of promised range (%d found)", pp->promiser, matches); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); for (const Rlist *rp = a->process_count.out_of_range_define; rp != NULL; rp = rp->next) { ProcessCountMaybeDefineClass(ctx, rp, pp, "out_of_range_define"); } } else { for (const Rlist *rp = a->process_count.in_range_define; rp != NULL; rp = rp->next) { ProcessCountMaybeDefineClass(ctx, rp, pp, "in_range_define"); } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Process promise for '%s' is kept", pp->promiser); DeleteItemList(matched_procs); return result; } } bool do_signals = (a->transaction.action != cfa_warn); if (!do_signals) { result = PromiseResultUpdate(result, PROMISE_RESULT_WARN); } /* signal/kill promises for existing matches */ bool killed = false; if (do_signals && (matches > 0)) { if (a->process_stop != NULL) { if (DONTDO) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a, "Need to keep process-stop promise for '%s', but only a warning is promised", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_WARN); } else { if (IsExecutable(CommandArg0(a->process_stop))) { Log(LOG_LEVEL_DEBUG, "Found process_stop command '%s' is executable.", a->process_stop); if (ShellCommandReturnsZero(a->process_stop, SHELL_TYPE_NONE)) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Promise to stop '%s' repaired, '%s' returned zero", pp->promiser, a->process_stop); result = PromiseResultUpdate(result, PROMISE_RESULT_CHANGE); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Promise to stop '%s' failed, '%s' returned nonzero", pp->promiser, a->process_stop); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); } } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Process promise to stop '%s' could not be kept because '%s' is not executable", pp->promiser, a->process_stop); result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); DeleteItemList(matched_procs); return result; } } } killed = DoAllSignals(ctx, matched_procs, a, pp, &result); } DeleteItemList(matched_procs); /* delegated promise to restart killed or non-existent entries */ bool need_to_restart = (a->restart_class != NULL) && (killed || (matches == 0)); if (!need_to_restart) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "No restart promised for %s", pp->promiser); return result; } else { if (a->transaction.action == cfa_warn) { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Need to keep restart promise for '%s', but only a warning is promised", pp->promiser); result = PromiseResultUpdate(result, PROMISE_RESULT_WARN); } else { PromiseResult status = killed ? PROMISE_RESULT_CHANGE : PROMISE_RESULT_NOOP; cfPS(ctx, LOG_LEVEL_VERBOSE, status, pp, a, "C: + Global class: %s ", a->restart_class); result = PromiseResultUpdate(result, status); EvalContextClassPutSoft(ctx, a->restart_class, CONTEXT_SCOPE_NAMESPACE, "source=promise"); } } return result; } #ifndef __MINGW32__ bool DoAllSignals(EvalContext *ctx, Item *procs_to_signal, const Attributes *a, const Promise *pp, PromiseResult *result) { Item *ip; Rlist *rp; pid_t pid; bool killed = false; bool failure = false; if (procs_to_signal == NULL) { return false; } if (a->signals == NULL) { Log(LOG_LEVEL_VERBOSE, "No signals to send for '%s'", pp->promiser); return false; } for (ip = procs_to_signal; ip != NULL; ip = ip->next) { pid = ip->counter; for (rp = a->signals; rp != NULL; rp = rp->next) { char *spec = RlistScalarValue(rp); int secs; char s; char next; int ret = sscanf(spec, "%d%c%c", &secs, &s, &next); if (((ret == 1) && (secs >= 0)) || ((ret == 2) && (s == 's') && (secs >= 0))) { /* Some number or some number plus 's' given, and nothing more */ sleep(secs); continue; } /* else something else given => consider it a signal name */ int signal = SignalFromString(spec); if (!DONTDO) { if ((signal == SIGKILL) || (signal == SIGTERM)) { killed = true; } if (kill(pid, signal) < 0) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_FAIL, pp, a, "Couldn't send promised signal '%s' (%d) to pid %jd (might be dead). (kill: %s)", spec, signal, (intmax_t)pid, GetErrorStr()); failure = true; } else { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Signalled '%s' (%d) to process %jd (%s)", spec, signal, (intmax_t) pid, ip->name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); failure = false; } } else { Log(LOG_LEVEL_ERR, "Need to keep signal promise '%s' in process entry '%s'", spec, ip->name); } } } if (failure) { *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } return killed; } #endif static int FindPidMatches(Item **killlist, const Attributes *a, const char *promiser) { int matches = 0; pid_t cfengine_pid = getpid(); Item *matched = SelectProcesses(promiser, &(a->process_select), a->haveselect); for (Item *ip = matched; ip != NULL; ip = ip->next) { pid_t pid = ip->counter; if (a->signals) /* There are some processes we don't want to signal. */ { if (pid == 1) { if (RlistLen(a->signals) == 1 && RlistKeyIn(a->signals, "hup")) { Log(LOG_LEVEL_VERBOSE, "Okay to send only HUP to init"); } else { continue; } } else if (pid < 4) { Log(LOG_LEVEL_VERBOSE, "Will not signal or restart processes 0,1,2,3 (occurred while looking for %s)", promiser); continue; } if (pid == cfengine_pid) { Log(LOG_LEVEL_VERBOSE, "cf-agent will not signal itself!"); continue; } } bool promised_zero = (a->process_count.min_range == 0) && (a->process_count.max_range == 0); if ((a->transaction.action == cfa_warn) && promised_zero) { Log(LOG_LEVEL_WARNING, "Process alert '%s'", GetProcessTableLegend()); Log(LOG_LEVEL_WARNING, "Process alert '%s'", ip->name); continue; } if (a->transaction.action == cfa_warn) { Log(LOG_LEVEL_WARNING, "Matched '%s'", ip->name); } else { Log(LOG_LEVEL_VERBOSE, "Matched '%s'", ip->name); } PrependItem(killlist, ip->name, ""); (*killlist)->counter = pid; matches++; } DeleteItemList(matched); return matches; } cfengine-3.24.2/cf-agent/manifest_file.c0000644000000000000000000000242315010704253020011 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include int main (int argc, char *argv[]) { if (argc < 2) { /* No paths given, manifest self. */ ManifestFile(argv[0], false); } for (int i = 1; i < argc; i++) { ManifestFile(argv[i], false); } } cfengine-3.24.2/cf-agent/simulate_mode.h0000644000000000000000000000347315010704253020046 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #ifndef _SIMULATE_H_ #define _SIMULATE_H_ #include /* StringSet */ #define CHROOT_PKG_OPERATION_PRESENT "p" #define CHROOT_PKG_OPERATION_ABSENT "a" #define CHROOT_PKG_OPERATION_INSTALL "i" #define CHROOT_PKG_OPERATION_REMOVE "r" typedef enum { CHROOT_PKG_OPERATION_CODE_PRESENT = 'p', CHROOT_PKG_OPERATION_CODE_ABSENT = 'a', CHROOT_PKG_OPERATION_CODE_INSTALL = 'i', CHROOT_PKG_OPERATION_CODE_REMOVE = 'r', } ChrootPkgOperationCode; bool ManifestFile(const char *path, bool chrooted); bool ManifestRename(const char *orig_name, const char *new_name); bool ManifestChangedFiles(StringSet **audited_files); bool ManifestAllFiles(StringSet **audited_files); bool DiffChangedFiles(StringSet **audited_files); bool DiffPkgOperations(); bool ManifestPkgOperations(); #endif /* _SIMULATE_H_ */ cfengine-3.24.2/cf-agent/vercmp_internal.c0000644000000000000000000001401415010704253020373 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include static void ParsePackageVersion(char *version, Rlist **num, Rlist **sep); VersionCmpResult ComparePackageVersionsInternal(const char *v1, const char *v2, PackageVersionComparator cmp) { Rlist *rp_pr, *rp_in; int result = true; int break_loop = false; int cmp_result; VersionCmpResult version_matched = VERCMP_NO_MATCH; Rlist *numbers_pr = NULL, *separators_pr = NULL; Rlist *numbers_in = NULL, *separators_in = NULL; ParsePackageVersion(CanonifyChar(v1, ','), &numbers_pr, &separators_pr); ParsePackageVersion(CanonifyChar(v2, ','), &numbers_in, &separators_in); /* If the format of the version string doesn't match, we're already doomed */ Log(LOG_LEVEL_VERBOSE, "Check for compatible versioning model in (%s,%s)", v1, v2); for (rp_pr = separators_pr, rp_in = separators_in; (rp_pr != NULL) && (rp_in != NULL); rp_pr = rp_pr->next, rp_in = rp_in->next) { if (strcmp(RlistScalarValue(rp_pr), RlistScalarValue(rp_in)) != 0) { result = false; break; } if ((rp_pr->next == NULL) && (rp_in->next == NULL)) { result = true; break; } } if (result) { Log(LOG_LEVEL_VERBOSE, "Verified that versioning models are compatible"); } else { Log(LOG_LEVEL_VERBOSE, "Versioning models for (%s,%s) were incompatible", v1, v2); version_matched = VERCMP_ERROR; } int version_equal = (strcmp(v2, v1) == 0); if (result) { for (rp_pr = numbers_pr, rp_in = numbers_in; (rp_pr != NULL) && (rp_in != NULL); rp_pr = rp_pr->next, rp_in = rp_in->next) { cmp_result = strcmp(RlistScalarValue(rp_pr), RlistScalarValue(rp_in)); switch (cmp) { case PACKAGE_VERSION_COMPARATOR_EQ: case PACKAGE_VERSION_COMPARATOR_NONE: if (version_equal) { version_matched = VERCMP_MATCH; } break; case PACKAGE_VERSION_COMPARATOR_NEQ: if (!version_equal) { version_matched = VERCMP_MATCH; } break; case PACKAGE_VERSION_COMPARATOR_GT: if (cmp_result > 0) { version_matched = VERCMP_MATCH; } else if (cmp_result < 0) { break_loop = true; } break; case PACKAGE_VERSION_COMPARATOR_LT: if (cmp_result < 0) { version_matched = VERCMP_MATCH; } else if (cmp_result > 0) { break_loop = true; } break; case PACKAGE_VERSION_COMPARATOR_GE: if ((cmp_result > 0) || version_equal) { version_matched = VERCMP_MATCH; } else if (cmp_result < 0) { break_loop = true; } break; case PACKAGE_VERSION_COMPARATOR_LE: if ((cmp_result < 0) || version_equal) { version_matched = VERCMP_MATCH; } else if (cmp_result > 0) { break_loop = true; } break; default: break; } if ((version_matched == VERCMP_MATCH) || break_loop) { rp_pr = NULL; rp_in = NULL; break; } } if (rp_pr != NULL) { if ((cmp == PACKAGE_VERSION_COMPARATOR_GT) || (cmp == PACKAGE_VERSION_COMPARATOR_GE)) { version_matched = VERCMP_MATCH; } } if (rp_in != NULL) { if ((cmp == PACKAGE_VERSION_COMPARATOR_LT) || (cmp == PACKAGE_VERSION_COMPARATOR_LE)) { version_matched = VERCMP_MATCH; } } } RlistDestroy(numbers_pr); RlistDestroy(numbers_in); RlistDestroy(separators_pr); RlistDestroy(separators_in); return version_matched; } static void ParsePackageVersion(char *version, Rlist **num, Rlist **sep) { char *sp, numeral[30], separator[2]; if (version == NULL) { return; } for (sp = version; *sp != '\0'; sp++) { memset(numeral, 0, 30); memset(separator, 0, 2); /* Split in 2's complement */ sscanf(sp, "%29[0-9a-zA-Z]", numeral); sp += strlen(numeral); /* Append to end up with left->right (major->minor) comparison */ RlistAppendScalar(num, numeral); if (*sp == '\0') { return; } sscanf(sp, "%1[^0-9a-zA-Z]", separator); RlistAppendScalar(sep, separator); } } cfengine-3.24.2/cf-agent/verify_services.h0000644000000000000000000000222015010704253020413 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_SERVICES_H #define CFENGINE_VERIFY_SERVICES_H #include PromiseResult VerifyServicesPromise(EvalContext *ctx, const Promise *pp); #endif cfengine-3.24.2/cf-agent/acl_posix.c0000644000000000000000000010167015010704253017171 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include /* GetGroupID(), GetUserID() */ #ifdef HAVE_ACL_H # include #endif #ifdef HAVE_SYS_ACL_H # include #endif #ifdef HAVE_ACL_LIBACL_H # include #endif #ifdef HAVE_LIBACL static bool CheckPosixLinuxAccessACEs(EvalContext *ctx, Rlist *aces, AclMethod method, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result); static bool CheckPosixLinuxDefaultACEs(EvalContext *ctx, Rlist *aces, AclMethod method, AclDefault acl_default, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result); static bool CheckPosixLinuxACEs(EvalContext *ctx, Rlist *aces, AclMethod method, const char *file_path, acl_type_t acl_type, const Attributes *a, const Promise *pp, PromiseResult *result); static bool CheckDefaultEqualsAccessACL(EvalContext *ctx, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result); static bool CheckDefaultClearACL(EvalContext *ctx, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result); static bool ParseEntityPosixLinux(char **str, acl_entry_t ace, int *is_mask); static bool ParseModePosixLinux(char *mode, acl_permset_t old_perms); static acl_entry_t FindACE(acl_t acl, acl_entry_t ace_find); static int ACLEquals(acl_t first, acl_t second); static int ACECount(acl_t acl); static int PermsetEquals(acl_permset_t first, acl_permset_t second); PromiseResult CheckPosixLinuxACL(EvalContext *ctx, const char *file_path, Acl acl, const Attributes *a, const Promise *pp) { assert(a != NULL); PromiseResult result = PROMISE_RESULT_NOOP; if (!CheckPosixLinuxAccessACEs(ctx, acl.acl_entries, acl.acl_method, file_path, a, pp, &result)) { PromiseRef(LOG_LEVEL_ERR, pp); return result; } if (IsDir(ToChangesPath(file_path))) { if (!CheckPosixLinuxDefaultACEs(ctx, acl.acl_default_entries, acl.acl_method, acl.acl_default, file_path, a, pp, &result)) { PromiseRef(LOG_LEVEL_ERR, pp); return result; } } return result; } static bool CheckPosixLinuxAccessACEs(EvalContext *ctx, Rlist *aces, AclMethod method, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); return CheckPosixLinuxACEs(ctx, aces, method, file_path, ACL_TYPE_ACCESS, a, pp, result); } static bool CheckPosixLinuxDefaultACEs(EvalContext *ctx, Rlist *aces, AclMethod method, AclDefault acl_default, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); bool retval; switch (acl_default) { case ACL_DEFAULT_NO_CHANGE: // no change always succeeds RecordNoChange(ctx, pp, a, "No change required for '%s' with acl_default=nochange", file_path); retval = true; break; case ACL_DEFAULT_SPECIFY: // default ACL is specified in promise /* CheckPosixLinuxACEs() records changes and updates 'result' */ retval = CheckPosixLinuxACEs(ctx, aces, method, file_path, ACL_TYPE_DEFAULT, a, pp, result); break; case ACL_DEFAULT_ACCESS: // default ACL should be the same as access ACL retval = CheckDefaultEqualsAccessACL(ctx, file_path, a, pp, result); break; case ACL_DEFAULT_CLEAR: // default ACL should be empty retval = CheckDefaultClearACL(ctx, file_path, a, pp, result); break; default: // unknown inheritance policy Log(LOG_LEVEL_ERR, "Unknown ACL inheritance policy - shouldn't happen"); debug_abort_if_reached(); retval = false; break; } return retval; } /** * Takes as input CFEngine-syntax ACEs and a path to a file. Checks if the * CFEngine-syntax ACL translates to the POSIX Linux ACL set on the given * file. If it doesn't, the ACL on the file is updated. */ static bool CheckPosixLinuxACEs(EvalContext *ctx, Rlist *aces, AclMethod method, const char *file_path, acl_type_t acl_type, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); acl_t acl_existing; acl_t acl_new; acl_t acl_tmp; acl_entry_t ace_parsed; acl_entry_t ace_current; acl_permset_t perms; char *cf_ace; int retv; int has_mask; Rlist *rp; char *acl_type_str; char *acl_text_str; acl_new = NULL; acl_existing = NULL; acl_tmp = NULL; has_mask = false; acl_type_str = acl_type == ACL_TYPE_ACCESS ? "Access" : "Default"; const char *changes_path = file_path; if (ChrootChanges()) { changes_path = ToChangesChroot(file_path); } // read existing acl if ((acl_existing = acl_get_file(changes_path, acl_type)) == NULL) { RecordFailure(ctx, pp, a, "No %s ACL for '%s' could be read. (acl_get_file: %s)", acl_type_str, file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } // allocate memory for temp ace (it needs to reside in a temp acl) if ((acl_tmp = acl_init(1)) == NULL) { RecordFailure(ctx, pp, a, "New ACL could not be allocated (acl_init: %s)", GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); return false; } if (acl_create_entry(&acl_tmp, &ace_parsed) != 0) { RecordFailure(ctx, pp, a, "New ACL could not be allocated (acl_create_entry: %s)", GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); return false; } // copy existing aces if we are appending if (method == ACL_METHOD_APPEND) { if ((acl_new = acl_dup(acl_existing)) == NULL) { RecordFailure(ctx, pp, a, "Error copying existing ACL (acl_dup: %s)", GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); return false; } } else // overwrite existing acl { if ((acl_new = acl_init(5)) == NULL) // TODO: Always OK with 5 here ? { RecordFailure(ctx, pp, a, "New ACL could not be allocated (acl_init: %s)", GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); return false; } } for (rp = aces; rp != NULL; rp = rp->next) { cf_ace = RlistScalarValue(rp); if (!ParseEntityPosixLinux(&cf_ace, ace_parsed, &has_mask)) { RecordFailure(ctx, pp, a, "ACL: Error parsing entity in '%s'", cf_ace); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } // check if an ACE with this entity-type and id already exist in the Posix Linux ACL ace_current = FindACE(acl_new, ace_parsed); // create new entry in ACL if it did not exist if (ace_current == NULL) { if (acl_create_entry(&acl_new, &ace_current) != 0) { RecordFailure(ctx, pp, a, "Failed to allocate ace (acl_create_entry: %s)", GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } // copy parsed entity-type and id if (acl_copy_entry(ace_current, ace_parsed) != 0) { RecordFailure(ctx, pp, a, "Error copying Linux ACL entry for '%s' (acl_copy_entry: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } // clear ace_current's permissions to avoid ace_parsed from last // loop iteration to be taken into account when applying mode below if ((acl_get_permset(ace_current, &perms) != 0)) { RecordFailure(ctx, pp, a, "Error obtaining permission set for 'ace_current' (acl_get_permset: %s)", GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } if (acl_clear_perms(perms) != 0) { RecordFailure(ctx, pp, a, "Error clearing permission set for 'ace_current'. (acl_clear_perms: %s)", GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } } // mode string should be prefixed with an entry seperator if (*cf_ace != ':') { RecordFailure(ctx, pp, a, "ACL: No separator before mode-string '%s'", cf_ace); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } cf_ace += 1; if (acl_get_permset(ace_current, &perms) != 0) { RecordFailure(ctx, pp, a, "ACL: Error obtaining permission set for '%s'. (acl_get_permset: %s)", cf_ace, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } if (!ParseModePosixLinux(cf_ace, perms)) { RecordFailure(ctx, pp, a, "ACL: Error parsing mode-string in '%s'", cf_ace); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } // only allow permissions exist on posix acls, so we do // not check what follows next } // if no mask exists, calculate one (or both?): run acl_calc_mask and add one if (!has_mask) { if (acl_calc_mask(&acl_new) != 0) { RecordFailure(ctx, pp, a, "Error calculating new ACL mask"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } } if ((retv = ACLEquals(acl_existing, acl_new)) == -1) { RecordFailure(ctx, pp, a, "Error while comparing existing and new ACL, unable to repair"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); return false; } if (retv == 1) // existing and new acl differ, update existing { if (MakingChanges(ctx, pp, a, result, "update ACL %s on file '%s'", acl_type_str, file_path)) { int last = -1; acl_text_str = acl_to_any_text(acl_new, NULL, ',', 0); Log(LOG_LEVEL_DEBUG, "ACL: new acl is `%s'", acl_text_str); if ((retv = acl_check(acl_new, &last)) != 0) { RecordFailure(ctx, pp, a, "Invalid ACL in '%s' at index %d (acl_check: %s)", acl_text_str, last, acl_error(retv)); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); acl_free(acl_text_str); return false; } if ((retv = acl_set_file(changes_path, acl_type, acl_new)) != 0) { RecordFailure(ctx, pp, a, "Error setting new %s ACL(%s) on file '%s' (acl_set_file: %s), are required ACEs present ?", acl_type_str, acl_text_str, file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_existing); acl_free(acl_tmp); acl_free(acl_new); acl_free(acl_text_str); return false; } acl_free(acl_text_str); RecordChange(ctx, pp, a, "%s ACL on '%s' successfully changed", acl_type_str, file_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); } } else { RecordNoChange(ctx, pp, a, "'%s' ACL on '%s' needs no modification.", acl_type_str, file_path); } acl_free(acl_existing); acl_free(acl_new); acl_free(acl_tmp); return true; } /** * Checks if the default ACL of the given file is the same as the access ACL. If * not, the default ACL is set in this way. * * @return 0 on success and -1 on failure. */ static bool CheckDefaultEqualsAccessACL(EvalContext *ctx, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); acl_t acl_access; acl_t acl_default; int equals; bool retval = false; const char *changes_path = file_path; if (ChrootChanges()) { changes_path = ToChangesChroot(file_path); } acl_access = NULL; acl_default = NULL; if ((acl_access = acl_get_file(changes_path, ACL_TYPE_ACCESS)) == NULL) { RecordFailure(ctx, pp, a, "Could not find an ACL for '%s'. (acl_get_file: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } acl_default = acl_get_file(changes_path, ACL_TYPE_DEFAULT); if (acl_default == NULL) { RecordFailure(ctx, pp, a, "Could not find default ACL for '%s'. (acl_get_file: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_access); return false; } equals = ACLEquals(acl_access, acl_default); switch (equals) { case 0: // they equal, as desired RecordNoChange(ctx, pp, a, "Default ACL on '%s' as promised", file_path); retval = true; break; case 1: // set access ACL as default ACL if (MakingChanges(ctx, pp, a, result, "copy default ACL on '%s' from access ACL", file_path)) { if ((acl_set_file(changes_path, ACL_TYPE_DEFAULT, acl_access)) != 0) { RecordFailure(ctx, pp, a, "Could not set default ACL to access on '%s'. (acl_set_file: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); acl_free(acl_access); acl_free(acl_default); return false; } RecordChange(ctx, pp, a, "Default ACL on '%s' successfully copied from access ACL.", file_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; } break; default: RecordFailure(ctx, pp, a, "ACL: Unable to compare access and default ACEs"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); retval = false; } acl_free(acl_access); acl_free(acl_default); return retval; } /* Checks if the default ACL is empty. If not, it is cleared. */ static bool CheckDefaultClearACL(EvalContext *ctx, const char *file_path, const Attributes *a, const Promise *pp, PromiseResult *result) { acl_t acl_existing; acl_t acl_empty; acl_entry_t ace_dummy; int retv; bool retval = false; const char *changes_path = file_path; if (ChrootChanges()) { changes_path = ToChangesChroot(file_path); } acl_existing = NULL; acl_empty = NULL; if ((acl_existing = acl_get_file(changes_path, ACL_TYPE_DEFAULT)) == NULL) { RecordFailure(ctx, pp, a, "Unable to read default acl for '%s'. (acl_get_file: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } retv = acl_get_entry(acl_existing, ACL_FIRST_ENTRY, &ace_dummy); switch (retv) { case -1: RecordFailure(ctx, pp, a, "Couldn't retrieve ACE for '%s'. (acl_get_entry: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); retval = false; break; case 0: // no entries, as desired RecordNoChange(ctx, pp, a, "Default ACL on '%s' as promised", file_path); retval = true; break; case 1: // entries exist, set empty ACL if ((acl_empty = acl_init(0)) == NULL) { RecordFailure(ctx, pp, a, "Could not reinitialize ACL for '%s'. (acl_init: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); retval = false; break; } if (MakingChanges(ctx, pp, a, result, "clean default ACL on '%s'", file_path)) { if (acl_set_file(changes_path, ACL_TYPE_DEFAULT, acl_empty) != 0) { RecordFailure(ctx, pp, a, "Could not reset ACL for '%s'. (acl_set_file: %s)", file_path, GetErrorStr()); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); retval = false; } RecordChange(ctx, pp, a, "Default ACL on '%s' successfully cleared", file_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; } break; default: retval = false; } acl_free(acl_empty); acl_free(acl_existing); return retval; } /* Walks through the acl given as the first parameter, looking for an ACE that has the same entity type and id as the ace in the second parameter. If a match is found, then the matching ace is returned. Else, NULL is returned. */ static acl_entry_t FindACE(acl_t acl, acl_entry_t ace_find) { acl_entry_t ace_curr; acl_tag_t tag_curr; acl_tag_t tag_find; id_t *id_curr; id_t *id_find; int more_aces; int retv_tag; id_find = NULL; more_aces = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace_curr); if (more_aces == -1) { Log(LOG_LEVEL_ERR, "Error reading ACL. (acl_get_entry: %s)", GetErrorStr()); return NULL; } else if (more_aces == 0) { return NULL; } /* find the tag type and id we are looking for */ if (acl_get_tag_type(ace_find, &tag_find) != 0) { Log(LOG_LEVEL_ERR, "Error reading tag type. (acl_get_tag_type: %s)", GetErrorStr()); return NULL; } if (tag_find == ACL_USER || tag_find == ACL_GROUP) { id_find = acl_get_qualifier(ace_find); if (id_find == NULL) { Log(LOG_LEVEL_ERR, "Error reading tag type. (acl_get_qualifier: %s)", GetErrorStr()); return NULL; } } /* check if any of the aces match */ while (more_aces) { if ((retv_tag = acl_get_tag_type(ace_curr, &tag_curr)) != 0) { Log(LOG_LEVEL_ERR, "Unable to get tag type. (acl_get_tag_type: %s)", GetErrorStr()); acl_free(id_find); return NULL; } if (tag_curr == tag_find) { if (id_find == NULL) { return ace_curr; } id_curr = acl_get_qualifier(ace_curr); if (id_curr == NULL) { Log(LOG_LEVEL_ERR, "Couldn't extract qualifier. (acl_get_qualifier: %s)", GetErrorStr()); return NULL; } if (*id_curr == *id_find) { acl_free(id_find); acl_free(id_curr); return ace_curr; } acl_free(id_curr); } more_aces = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace_curr); } if (id_find != NULL) { acl_free(id_find); } return NULL; } /* Checks if the two ACLs contain equal ACEs and equally many. Does not assume that the ACEs lie in the same order. Returns 0 if so, and 1 if they differ, and -1 on error. */ static int ACLEquals(acl_t first, acl_t second) { acl_entry_t ace_first; acl_entry_t ace_second; acl_permset_t perms_first; acl_permset_t perms_second; int first_cnt; int second_cnt; int more_aces; int retv_perms; if ((first_cnt = ACECount(first)) == -1) { Log(LOG_LEVEL_ERR, "Couldn't count ACEs while comparing ACLs"); return -1; } if ((second_cnt = ACECount(second)) == -1) { Log(LOG_LEVEL_ERR, "Couldn't count ACEs while comparing ACLs"); return -1; } if (first_cnt != second_cnt) { return 1; } if (first_cnt == 0) { return 0; } // check that every ace of first acl exist in second acl more_aces = acl_get_entry(first, ACL_FIRST_ENTRY, &ace_first); if (more_aces != 1) // first must contain at least one entry { Log(LOG_LEVEL_ERR, "Unable to read ACE. (acl_get_entry: %s)", GetErrorStr()); return -1; } while (more_aces) { /* no ace in second match entity-type and id of first */ if ((ace_second = FindACE(second, ace_first)) == NULL) { return 1; } /* permissions must also match */ if (acl_get_permset(ace_first, &perms_first) != 0) { Log(LOG_LEVEL_ERR, "Unable to read permissions. (acl_get_permset: %s)", GetErrorStr()); return -1; } if (acl_get_permset(ace_second, &perms_second) != 0) { Log(LOG_LEVEL_ERR, "Unable to read permissions. (acl_get_permset: %s)", GetErrorStr()); return -1; } retv_perms = PermsetEquals(perms_first, perms_second); if (retv_perms == -1) { return -1; } else if (retv_perms == 1) // permissions differ { return 1; } more_aces = acl_get_entry(first, ACL_NEXT_ENTRY, &ace_first); } return 0; } static int ACECount(acl_t acl) { int more_aces; int count; acl_entry_t ace; count = 0; more_aces = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace); if (more_aces <= 0) { return more_aces; } while (more_aces) { more_aces = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace); count++; } return count; } static int PermsetEquals(acl_permset_t first, acl_permset_t second) { acl_perm_t perms_avail[3] = { ACL_READ, ACL_WRITE, ACL_EXECUTE }; int first_set; int second_set; int i; for (i = 0; i < 3; i++) { first_set = acl_get_perm(first, perms_avail[i]); if (first_set == -1) { return -1; } second_set = acl_get_perm(second, perms_avail[i]); if (second_set == -1) { return -1; } if (first_set != second_set) { return 1; } } return 0; } /* Takes a ':' or null-terminated string "entity-type:id", and converts and stores these into a Posix Linux ace data structure (with unset permissions). Sets is_mask to true if this is a mask entry. */ static bool ParseEntityPosixLinux(char **str, acl_entry_t ace, int *is_mask) { acl_tag_t etype; size_t idsz; id_t id; char *ids; char *id_end; bool result = true; size_t i; ids = NULL; // TODO: Support numeric id in addition to (user/group) name ? // Posix language: tag type, qualifier, permissions if (strncmp(*str, "user:", 5) == 0) { *str += 5; // create null-terminated string for entity id id_end = strchr(*str, ':'); if (id_end == NULL) // entity id already null-terminated { idsz = strlen(*str); } else // copy entity-id to new null-terminated string { idsz = id_end - *str; } ids = xmalloc(idsz + 1); for (i = 0; i < idsz; i++) ids[i] = (*str)[i]; ids[idsz] = '\0'; *str += idsz; // file object owner if (strncmp(ids, "*", 2) == 0) { etype = ACL_USER_OBJ; id = 0; } else { etype = ACL_USER; if (!GetUserID(ids, &id, LOG_LEVEL_ERR)) { /* error already logged */ free(ids); return false; } } } else if (strncmp(*str, "group:", 6) == 0) { *str += 6; // create null-terminated string for entity id id_end = strchr(*str, ':'); if (id_end == NULL) // entity id already null-terminated { idsz = strlen(*str); } else // copy entity-id to new null-terminated string { idsz = id_end - *str; } ids = xmalloc(idsz + 1); for (i = 0; i < idsz; i++) ids[i] = (*str)[i]; ids[idsz] = '\0'; *str += idsz; // file group if (strncmp(ids, "*", 2) == 0) { etype = ACL_GROUP_OBJ; id = 0; // TODO: Correct file group id ?? } else { etype = ACL_GROUP; if (!GetGroupID(ids, &id, LOG_LEVEL_ERR)) { /* error already logged */ free(ids); return false; } } } else if (strncmp(*str, "all:", 4) == 0) { *str += 3; etype = ACL_OTHER; } else if (strncmp(*str, "mask:", 5) == 0) { *str += 4; etype = ACL_MASK; *is_mask = true; } else { Log(LOG_LEVEL_ERR, "ACE does not start with user:/group:/all:/mask:"); return false; } if (acl_set_tag_type(ace, etype) != 0) { Log(LOG_LEVEL_ERR, "Could not set ACE tag type. (acl_set_tag_type: %s)", GetErrorStr()); result = false; } else if (etype == ACL_USER || etype == ACL_GROUP) { if ((acl_set_qualifier(ace, &id)) != 0) { Log(LOG_LEVEL_ERR, "Could not set ACE qualifier. (acl_set_qualifier: %s)", GetErrorStr()); result = false; } } if (ids != NULL) { free(ids); } return result; } /* Takes a CFEngine-syntax mode string and existing Posix Linux-formatted permissions on the file system object as arguments. The mode-string will be applied on the permissions. Returns true on success, false otherwise. */ static bool ParseModePosixLinux(char *mode, acl_permset_t perms) { int retv; int more_entries; acl_perm_t perm; enum { add, del } op; op = add; if (*mode == '\0' || *mode == ':') { if (acl_clear_perms(perms) != 0) { Log(LOG_LEVEL_ERR, "Error clearing permissions. (acl_clear_perms: %s)", GetErrorStr()); return false; } else { return true; } } more_entries = true; while (more_entries) { switch (*mode) { case '+': op = add; mode++; break; case '-': op = del; mode++; break; case '=': mode++; // fallthrough default: // if mode does not start with + or -, we clear existing perms op = add; if (acl_clear_perms(perms) != 0) { Log(LOG_LEVEL_ERR, "Unable to clear ACL permissions. (acl_clear_perms: %s)", GetErrorStr()); return false; } } // parse generic perms (they are 1-1 on Posix) while (*mode != '\0' && strchr(CF_VALID_GPERMS, *mode)) { if (*mode == '\0') { break; } switch (*mode) { case 'r': perm = ACL_READ; break; case 'w': perm = ACL_WRITE; break; case 'x': perm = ACL_EXECUTE; break; default: Log(LOG_LEVEL_ERR, "No Linux support for generic permission flag '%c'", *mode); return false; } if (op == add) { retv = acl_add_perm(perms, perm); } else { retv = acl_delete_perm(perms, perm); } if (retv != 0) { Log(LOG_LEVEL_ERR, "Could not change ACE permission. (acl_[add|delete]_perm: %s)", GetErrorStr()); return false; } mode++; } // parse native perms if (*mode == CF_NATIVE_PERMS_SEP_START) { mode++; while (*mode != '\0' && strchr(CF_VALID_NPERMS_POSIX, *mode)) { switch (*mode) { case 'r': perm = ACL_READ; break; case 'w': perm = ACL_WRITE; break; case 'x': perm = ACL_EXECUTE; break; default: Log(LOG_LEVEL_ERR, "No Linux support for native permission flag '%c'", *mode); return false; } if (op == add) { retv = acl_add_perm(perms, perm); } else { retv = acl_delete_perm(perms, perm); } if (retv != 0) { Log(LOG_LEVEL_ERR, "Could not change ACE permission. (acl_[add|delete]_perm: %s)", GetErrorStr()); return false; } mode++; } // scan past native perms end seperator mode++; } if (*mode == ',') { more_entries = true; mode++; } else { more_entries = false; } } return true; } #else /* !HAVE_LIBACL */ PromiseResult CheckPosixLinuxACL(EvalContext *ctx, ARG_UNUSED const char *file_path, ARG_UNUSED Acl acl, const Attributes *a, const Promise *pp) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Posix ACLs are not supported on this Linux system - install the Posix acl library"); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } #endif cfengine-3.24.2/cf-agent/promiser_regex_resolver.h0000644000000000000000000000241415010704253022164 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROMISER_REGEX_RESOLVER_H #define CFENGINE_PROMISER_REGEX_RESOLVER_H PromiseResult LocateFilePromiserGroup(EvalContext *ctx, char *wildpath, const Promise *pp, PromiseResult (*fnptr) (EvalContext *ctx, char *path, const Promise *ptr)); #endif cfengine-3.24.2/cf-agent/cf-agent-windows-functions.h0000644000000000000000000000255215010704253022376 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFAGENT_WINDOWS_FUNCTIONS_H #define CFAGENT_WINDOWS_FUNCTIONS_H #ifdef __MINGW32__ PromiseResult VerifyWindowsService(EvalContext *ctx, const Attributes *a, Promise *pp); PromiseResult Nova_CheckNtACL(EvalContext *ctx, const char *file_path, Acl acl, const Attributes *a, const Promise *pp); #endif // __MINGW32__ #endif // CFAGENT_WINDOWS_FUNCTIONS_H cfengine-3.24.2/cf-agent/cf_sql.c0000644000000000000000000002751715010704253016466 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #ifdef HAVE_MYSQL_H # include #elif defined(HAVE_MYSQL_MYSQL_H) # include #endif #ifdef HAVE_PGSQL_LIBPQ_FE_H # include #elif defined(HAVE_LIBPQ_FE_H) # include #endif /* CFEngine connectors for sql databases. Note that there are significant differences in db admin functions in the various implementations. e.g. sybase/mysql "use database, create database" not in postgres. */ /*****************************************************************************/ #ifdef HAVE_LIBMYSQLCLIENT typedef struct { MYSQL conn; MYSQL_RES *res; } DbMysqlConn; /*****************************************************************************/ static DbMysqlConn *CfConnectMysqlDB(const char *host, const char *user, const char *password, const char *database) { DbMysqlConn *c; Log(LOG_LEVEL_VERBOSE, "This is a MySQL database"); c = xcalloc(1, sizeof(DbMysqlConn)); mysql_init(&c->conn); if (!mysql_real_connect(&c->conn, host, user, password, database, 0, NULL, 0)) { Log(LOG_LEVEL_ERR, "Failed to connect to existing MySQL database '%s'", mysql_error(&c->conn)); free(c); return NULL; } return c; } /*****************************************************************************/ static void CfCloseMysqlDB(DbMysqlConn *c) { mysql_close(&c->conn); free(c); } /*****************************************************************************/ static void CfNewQueryMysqlDb(CfdbConn *cfdb, const char *query) { DbMysqlConn *mc = cfdb->data; if (mysql_query(&mc->conn, query) != 0) { Log(LOG_LEVEL_INFO, "MySQL query failed '%s'. (mysql_query: %s)", query, mysql_error(&mc->conn)); } else { mc->res = mysql_store_result(&mc->conn); if (mc->res) { cfdb->result = true; cfdb->maxcolumns = mysql_num_fields(mc->res); cfdb->maxrows = mysql_num_rows(mc->res); } } } /*****************************************************************************/ static void CfFetchMysqlRow(CfdbConn *cfdb) { int i; MYSQL_ROW thisrow; DbMysqlConn *mc = cfdb->data; if (cfdb->maxrows > 0) { thisrow = mysql_fetch_row(mc->res); if (thisrow) { cfdb->rowdata = xmalloc(sizeof(char *) * cfdb->maxcolumns); for (i = 0; i < cfdb->maxcolumns; i++) { cfdb->rowdata[i] = (char *) thisrow[i]; } } else { cfdb->rowdata = NULL; } } } /*****************************************************************************/ static void CfDeleteMysqlQuery(CfdbConn *cfdb) { DbMysqlConn *mc = cfdb->data; if (mc->res) { mysql_free_result(mc->res); mc->res = NULL; } } #else static void *CfConnectMysqlDB(ARG_UNUSED const char *host, ARG_UNUSED const char *user, ARG_UNUSED const char *password, ARG_UNUSED const char *database) { Log(LOG_LEVEL_INFO, "There is no MySQL support compiled into this version"); return NULL; } static void CfCloseMysqlDB(ARG_UNUSED void *c) { } static void CfNewQueryMysqlDb(ARG_UNUSED CfdbConn *cfdb, ARG_UNUSED const char *query) { } static void CfFetchMysqlRow(ARG_UNUSED CfdbConn *cfdb) { } static void CfDeleteMysqlQuery(ARG_UNUSED CfdbConn *cfdb) { } #endif #if defined(HAVE_LIBPQ) &&\ (defined(HAVE_PGSQL_LIBPQ_FE_H) || defined(HAVE_LIBPQ_FE_H)) typedef struct { PGconn *conn; PGresult *res; } DbPostgresqlConn; /*****************************************************************************/ static DbPostgresqlConn *CfConnectPostgresqlDB(const char *host, const char *user, const char *password, const char *database) { DbPostgresqlConn *cfdb; char format[CF_BUFSIZE]; Log(LOG_LEVEL_VERBOSE, "This is a PotsgreSQL database"); cfdb = xcalloc(1, sizeof(DbPostgresqlConn)); if (strcmp(host, "localhost") == 0) { /* Some authentication problem - ?? */ if (database) { snprintf(format, CF_BUFSIZE - 1, "dbname=%s user=%s password=%s", database, user, password); } else { snprintf(format, CF_BUFSIZE - 1, "user=%s password=%s", user, password); } } else { if (database) { snprintf(format, CF_BUFSIZE - 1, "dbname=%s host=%s user=%s password=%s", database, host, user, password); } else { snprintf(format, CF_BUFSIZE - 1, "host=%s user=%s password=%s", host, user, password); } } cfdb->conn = PQconnectdb(format); if (PQstatus(cfdb->conn) == CONNECTION_BAD) { Log(LOG_LEVEL_ERR, "Failed to connect to existing PostgreSQL database. (PQconnectdb: %s)", PQerrorMessage(cfdb->conn)); free(cfdb); return NULL; } return cfdb; } /*****************************************************************************/ static void CfClosePostgresqlDb(DbPostgresqlConn *c) { PQfinish(c->conn); free(c); } /*****************************************************************************/ static void CfNewQueryPostgresqlDb(CfdbConn *cfdb, const char *query) { DbPostgresqlConn *pc = cfdb->data; pc->res = PQexec(pc->conn, query); if (PQresultStatus(pc->res) != PGRES_COMMAND_OK && PQresultStatus(pc->res) != PGRES_TUPLES_OK) { Log(LOG_LEVEL_INFO, "PostgreSQL query '%s' failed. (PQExec: %s)", query, PQerrorMessage(pc->conn)); } else { cfdb->result = true; cfdb->maxcolumns = PQnfields(pc->res); cfdb->maxrows = PQntuples(pc->res); } } /*****************************************************************************/ static void CfFetchPostgresqlRow(CfdbConn *cfdb) { assert(cfdb != NULL); DbPostgresqlConn *pc = cfdb->data; if (cfdb->row < 0 || (unsigned int) cfdb->row >= cfdb->maxrows) { cfdb->rowdata = NULL; return; } if (cfdb->maxrows > 0) { cfdb->rowdata = xmalloc(sizeof(char *) * cfdb->maxcolumns); } for (unsigned int i = 0; i < cfdb->maxcolumns; i++) { cfdb->rowdata[i] = PQgetvalue(pc->res, cfdb->row, i); } } /*****************************************************************************/ static void CfDeletePostgresqlQuery(CfdbConn *cfdb) { DbPostgresqlConn *pc = cfdb->data; PQclear(pc->res); } /*****************************************************************************/ #else static void *CfConnectPostgresqlDB(ARG_UNUSED const char *host, ARG_UNUSED const char *user, ARG_UNUSED const char *password, ARG_UNUSED const char *database) { Log(LOG_LEVEL_INFO, "There is no PostgreSQL support compiled into this version"); return NULL; } static void CfClosePostgresqlDb(ARG_UNUSED void *c) { } static void CfNewQueryPostgresqlDb(ARG_UNUSED CfdbConn *cfdb, ARG_UNUSED const char *query) { } static void CfFetchPostgresqlRow(ARG_UNUSED CfdbConn *cfdb) { } static void CfDeletePostgresqlQuery(ARG_UNUSED CfdbConn *cfdb) { } #endif /*****************************************************************************/ void CfConnectDB(CfdbConn *cfdb, DatabaseType dbtype, char *remotehost, char *dbuser, char *passwd, char *db) { cfdb->connected = false; cfdb->type = dbtype; /* If db == NULL, no database was specified, so we assume it has not been created yet. Need to open a generic database and create */ if (db == NULL) { db = "no db specified"; } Log(LOG_LEVEL_VERBOSE, "Connect to SQL database '%s', user '%s', host '%s', type %d", db, dbuser, remotehost, dbtype); switch (dbtype) { case DATABASE_TYPE_MYSQL: cfdb->data = CfConnectMysqlDB(remotehost, dbuser, passwd, db); break; case DATABASE_TYPE_POSTGRES: cfdb->data = CfConnectPostgresqlDB(remotehost, dbuser, passwd, db); break; default: Log(LOG_LEVEL_VERBOSE, "There is no SQL database selected"); break; } if (cfdb->data) cfdb->connected = true; } /*****************************************************************************/ void CfCloseDB(CfdbConn *cfdb) { if (!cfdb->connected) { return; } switch (cfdb->type) { case DATABASE_TYPE_MYSQL: CfCloseMysqlDB(cfdb->data); break; case DATABASE_TYPE_POSTGRES: CfClosePostgresqlDb(cfdb->data); break; default: Log(LOG_LEVEL_VERBOSE, "There is no SQL database selected"); break; } cfdb->connected = false; } /*****************************************************************************/ void CfVoidQueryDB(CfdbConn *cfdb, char *query) { if (!cfdb->connected) { return; } /* If we don't need to retrieve table entries...*/ CfNewQueryDB(cfdb, query); CfDeleteQuery(cfdb); } /*****************************************************************************/ void CfNewQueryDB(CfdbConn *cfdb, char *query) { cfdb->result = false; cfdb->row = 0; cfdb->column = 0; cfdb->rowdata = NULL; cfdb->maxcolumns = 0; cfdb->maxrows = 0; Log(LOG_LEVEL_DEBUG, "Before query '%s' succeeded, maxrows %d, maxcolumns %d", query, cfdb->maxrows, cfdb->maxcolumns); switch (cfdb->type) { case DATABASE_TYPE_MYSQL: CfNewQueryMysqlDb(cfdb, query); break; case DATABASE_TYPE_POSTGRES: CfNewQueryPostgresqlDb(cfdb, query); break; default: Log(LOG_LEVEL_VERBOSE, "There is no SQL database selected"); break; } Log(LOG_LEVEL_DEBUG, "Query '%s' succeeded. maxrows %d, maxcolumns %d", query, cfdb->maxrows, cfdb->maxcolumns); } /*****************************************************************************/ char **CfFetchRow(CfdbConn *cfdb) { switch (cfdb->type) { case DATABASE_TYPE_MYSQL: CfFetchMysqlRow(cfdb); break; case DATABASE_TYPE_POSTGRES: CfFetchPostgresqlRow(cfdb); break; default: Log(LOG_LEVEL_VERBOSE, "There is no SQL database selected"); break; } cfdb->row++; return cfdb->rowdata; } /*****************************************************************************/ char *CfFetchColumn(CfdbConn *cfdb, int col) { assert(cfdb != NULL); assert(col >= 0 && (unsigned int) col < cfdb->maxcolumns); if (cfdb->rowdata) { return cfdb->rowdata[col]; } else { return NULL; } } /*****************************************************************************/ void CfDeleteQuery(CfdbConn *cfdb) { switch (cfdb->type) { case DATABASE_TYPE_MYSQL: CfDeleteMysqlQuery(cfdb); break; case DATABASE_TYPE_POSTGRES: CfDeletePostgresqlQuery(cfdb); break; default: Log(LOG_LEVEL_VERBOSE, "There is no SQL database selected"); break; } if (cfdb->rowdata) { free(cfdb->rowdata); cfdb->rowdata = NULL; } } cfengine-3.24.2/cf-agent/files_select.h0000644000000000000000000000242415010704253017653 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_SELECT_H #define CFENGINE_FILES_SELECT_H #include bool SelectLeaf(EvalContext *ctx, char *path, const struct stat *sb, const FileSelect *fs); /* For implementation in Nova */ bool GetOwnerName(char *path, const struct stat *lstatptr, char *owner, int ownerSz); #endif cfengine-3.24.2/cf-agent/verify_new_packages.h0000644000000000000000000000226315010704253021226 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_NEW_PACKAGES_H #define CFENGINE_VERIFY_NEW_PACKAGES_H #include PromiseResult HandleNewPackagePromiseType(EvalContext *ctx, const Promise *pp, const Attributes *a); #endif cfengine-3.24.2/cf-agent/files_changes.h0000644000000000000000000000474215010704253020011 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_CHANGES_H #define CFENGINE_FILES_CHANGES_H #include typedef enum { FILE_STATE_NEW, FILE_STATE_REMOVED, FILE_STATE_CONTENT_CHANGED, FILE_STATE_STATS_CHANGED } FileState; bool FileChangesLogChange(const char *file, FileState status, char *msg, const Promise *pp); bool FileChangesCheckAndUpdateHash(EvalContext *ctx, const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, const Attributes *attr, const Promise *pp, PromiseResult *result); bool FileChangesGetDirectoryList(const char *path, Seq *files); bool FileChangesLogNewFile(const char *path, const Promise *pp); void FileChangesCheckAndUpdateDirectory(EvalContext *ctx, const Attributes *attr, const char *name, const Seq *file_set, const Seq *db_file_set, bool update, const Promise *pp, PromiseResult *result); void FileChangesCheckAndUpdateStats(EvalContext *ctx, const char *file, const struct stat *sb, bool update, const Attributes *attr, const Promise *pp, PromiseResult *result); #endif cfengine-3.24.2/cf-agent/verify_exec.c0000644000000000000000000004026615010704253017523 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef enum { ACTION_RESULT_OK, ACTION_RESULT_TIMEOUT, ACTION_RESULT_FAILED } ActionResult; static bool SyntaxCheckExec(const Attributes *attr, const Promise *pp); static bool PromiseKeptExec(const Attributes *a, const Promise *pp); static char *GetLockNameExec(const Attributes *a, const Promise *pp); static ActionResult RepairExec(EvalContext *ctx, const Attributes *a, const Promise *pp, PromiseResult *result); static void PreviewProtocolLine(char *line, char *comm); char* BuildCommandLine(const Attributes *a, const Promise *pp) { assert(a != NULL); Writer *w = StringWriter(); WriterWriteF(w, "%s", pp->promiser); if (a->args) { WriterWrite(w, " "); WriterWrite(w, a->args); } if (a->arglist) { for (const Rlist *rp = a->arglist; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR) { WriterWrite(w, " "); WriterWrite(w, RlistScalarValue(rp)); } else { Log(LOG_LEVEL_INFO, "GetLockNameExec: invalid rval (not a scalar) in arglist of commands promise '%s'", pp->promiser); } } } return StringWriterClose(w); } PromiseResult VerifyExecPromise(EvalContext *ctx, const Promise *pp) { Attributes a = GetExecAttributes(ctx, pp); if (!SyntaxCheckExec(&a, pp)) { return PROMISE_RESULT_FAIL; } if (PromiseKeptExec(&a, pp)) { return PROMISE_RESULT_NOOP; } char *lock_name = GetLockNameExec(&a, pp); CfLock thislock = AcquireLock(ctx, lock_name, VUQNAME, CFSTARTTIME, a.transaction.ifelapsed, a.transaction.expireafter, pp, false); free(lock_name); if (thislock.lock == NULL) { return PROMISE_RESULT_SKIPPED; } PromiseBanner(ctx,pp); PromiseResult result = PROMISE_RESULT_NOOP; /* See VerifyCommandRetcode for interpretation of return codes. * Unless overridden by attributes in body classes, an exit code 0 means * reparied (PROMISE_RESULT_CHANGE), an exit code != 0 means failure. */ switch (RepairExec(ctx, &a, pp, &result)) { case ACTION_RESULT_OK: result = PromiseResultUpdate(result, PROMISE_RESULT_NOOP); break; case ACTION_RESULT_TIMEOUT: result = PromiseResultUpdate(result, PROMISE_RESULT_TIMEOUT); break; case ACTION_RESULT_FAILED: result = PromiseResultUpdate(result, PROMISE_RESULT_FAIL); break; default: ProgrammingError("Unexpected ActionResult value"); } YieldCurrentLock(thislock); return result; } /*****************************************************************************/ /* Level */ /*****************************************************************************/ static bool SyntaxCheckExec(const Attributes *attr, const Promise *pp) { assert(attr != NULL); Attributes a = *attr; // TODO get rid of this, this function was probably // intended to have side effects on the attr struct if ((a.contain.nooutput) && (a.contain.preview)) { Log(LOG_LEVEL_ERR, "no_output and preview are mutually exclusive (broken promise)"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } #ifdef __MINGW32__ if (a.contain.umask != (mode_t)CF_UNDEFINED) { Log(LOG_LEVEL_VERBOSE, "contain.umask is ignored on Windows"); } if (a.contain.owner != CF_UNDEFINED) { Log(LOG_LEVEL_VERBOSE, "contain.exec_owner is ignored on Windows"); } if (a.contain.group != CF_UNDEFINED) { Log(LOG_LEVEL_VERBOSE, "contain.exec_group is ignored on Windows"); } if (a.contain.chroot != NULL) { Log(LOG_LEVEL_VERBOSE, "contain.chroot is ignored on Windows"); } #else /* !__MINGW32__ */ if (a.contain.umask == (mode_t)CF_UNDEFINED) { a.contain.umask = 077; // FIXME: This has no effect! } #endif /* !__MINGW32__ */ return true; } static bool PromiseKeptExec(ARG_UNUSED const Attributes *a, ARG_UNUSED const Promise *pp) { return false; } static char *GetLockNameExec(const Attributes *a, const Promise *pp) { return BuildCommandLine(a, pp); } /*****************************************************************************/ static ActionResult RepairExec(EvalContext *ctx, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); assert(pp != NULL); char cmdline[CF_BUFSIZE]; char comm[20]; int count = 0; #if !defined(__MINGW32__) mode_t maskval = 0; #endif FILE *pfp; char cmdOutBuf[CF_BUFSIZE]; size_t cmdOutBufPos = 0; size_t lineOutLen; char module_context[CF_BUFSIZE]; module_context[0] = '\0'; if (IsAbsoluteFileName(CommandArg0(pp->promiser)) || a->contain.shelltype == SHELL_TYPE_NONE) { if (!IsExecutable(CommandArg0(pp->promiser))) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "'%s' promises to be executable but isn't", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); if (strchr(pp->promiser, ' ')) { Log(LOG_LEVEL_VERBOSE, "Paths with spaces must be inside escaped quoutes (e.g. \\\"%s\\\")", pp->promiser); } return ACTION_RESULT_FAILED; } else { Log(LOG_LEVEL_VERBOSE, "Promiser string contains a valid executable '%s' - ok", CommandArg0(pp->promiser)); } } char timeout_str[CF_BUFSIZE]; if (a->contain.timeout == CF_NOINT) { snprintf(timeout_str, CF_BUFSIZE, "no timeout"); } else { snprintf(timeout_str, CF_BUFSIZE, "timeout=%ds", a->contain.timeout); } char owner_str[CF_BUFSIZE] = ""; if (a->contain.owner != (uid_t) -1) { snprintf(owner_str, CF_BUFSIZE, ",uid=%ju", (uintmax_t)a->contain.owner); } char group_str[CF_BUFSIZE] = ""; if (a->contain.group != (gid_t) -1) { snprintf(group_str, CF_BUFSIZE, ",gid=%ju", (uintmax_t)a->contain.group); } char* temp = BuildCommandLine(a, pp); snprintf(cmdline, CF_BUFSIZE, "%s", temp); // TODO: remove CF_BUFSIZE limitation free(temp); const LogLevel info_or_verbose = a->inform ? LOG_LEVEL_INFO : LOG_LEVEL_VERBOSE; Log(info_or_verbose, "Executing '%s%s%s' ... '%s'", timeout_str, owner_str, group_str, cmdline); BeginMeasure(); if (DONTDO && (!a->contain.preview)) { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Would execute script '%s'", cmdline); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); return ACTION_RESULT_OK; } if (a->transaction.action != cfa_fix) { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Command '%s' needs to be executed, but only warning was promised", cmdline); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); return ACTION_RESULT_OK; } CommandPrefix(cmdline, comm); bool do_work_here = true; #ifndef __MINGW32__ if (a->transaction.background) { Log(LOG_LEVEL_VERBOSE, "Backgrounding job '%s'", cmdline); do_work_here = (fork() == 0); // true for child, false for parent } #endif if (do_work_here) // work done here: either by child or non-background parent { if (a->contain.timeout != CF_NOINT) { SetTimeOut(a->contain.timeout); } #ifndef __MINGW32__ Log(LOG_LEVEL_VERBOSE, "Setting umask to %jo", (uintmax_t)a->contain.umask); maskval = umask(a->contain.umask); if (a->contain.umask == 0) { Log(LOG_LEVEL_VERBOSE, "Programming '%s' running with umask 0! Use umask= to set", cmdline); } #endif /* !__MINGW32__ */ const char *open_mode = a->module ? "rt" : "r"; if (a->contain.shelltype == SHELL_TYPE_POWERSHELL) { #ifdef __MINGW32__ pfp = cf_popen_powershell_setuid(cmdline, open_mode, a->contain.owner, a->contain.group, a->contain.chdir, a->contain.chroot, a->transaction.background); #else // !__MINGW32__ Log(LOG_LEVEL_ERR, "Powershell is only supported on Windows"); return ACTION_RESULT_FAILED; #endif // !__MINGW32__ } else if (a->contain.shelltype == SHELL_TYPE_USE) { pfp = cf_popen_shsetuid(cmdline, open_mode, a->contain.owner, a->contain.group, a->contain.chdir, a->contain.chroot, a->transaction.background); } else { char *const command = (a->args == NULL) ? xstrdup(pp->promiser) : StringFormat("%s %s", pp->promiser, a->args); Seq *arglist = NULL; if (a->arglist != NULL) { arglist = SeqNew(8, NULL); for (const Rlist *rp = a->arglist; rp != NULL; rp = rp->next) { if (rp->val.type == RVAL_TYPE_SCALAR) { SeqAppend(arglist, RlistScalarValue(rp)); } else { Log(LOG_LEVEL_ERR, "RepairExec: invalid rval (not a scalar) in arglist of commands promise '%s'", pp->promiser); } } } pfp = cf_popensetuid(command, arglist, open_mode, a->contain.owner, a->contain.group, a->contain.chdir, a->contain.chroot, a->transaction.background); free(command); SeqDestroy(arglist); } if (pfp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", cmdline, GetErrorStr()); return ACTION_RESULT_FAILED; } StringSet *module_tags = StringSetNew(); long persistence = 0; size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = CfReadLine(&line, &line_size, pfp); if (res == -1) { if (!feof(pfp)) { Log(LOG_LEVEL_ERR, "Unable to read output from command '%s'. (fread: %s)", cmdline, GetErrorStr()); cf_pclose(pfp); free(line); return ACTION_RESULT_FAILED; } else { break; } } if (strstr(line, "cfengine-die")) { break; } if (a->contain.preview) { PreviewProtocolLine(line, cmdline); } if (a->module) { ModuleProtocol(ctx, cmdline, line, !a->contain.nooutput, module_context, sizeof(module_context), module_tags, &persistence); } if (!a->contain.nooutput && !EmptyString(line)) { lineOutLen = strlen(comm) + strlen(line) + 12; // if buffer is to small for this line, output it directly if (lineOutLen > sizeof(cmdOutBuf)) { Log(LOG_LEVEL_NOTICE, "Q: '%s': %s", comm, line); } else { if (cmdOutBufPos + lineOutLen > sizeof(cmdOutBuf)) { Log(LOG_LEVEL_NOTICE, "%s", cmdOutBuf); cmdOutBufPos = 0; } snprintf(cmdOutBuf + cmdOutBufPos, sizeof(cmdOutBuf) - cmdOutBufPos, "Q: \"...%s\": %s\n", comm, line); cmdOutBufPos += (lineOutLen - 1); } count++; } } StringSetDestroy(module_tags); free(line); #ifdef __MINGW32__ if (a->transaction.background) // only get return value if we waited for command execution { cf_pclose_nowait(pfp); } else #endif /* __MINGW32__ */ { int ret = cf_pclose(pfp); if (ret == -1) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Finished script '%s' - failed (abnormal termination)", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { VerifyCommandRetcode(ctx, ret, a, pp, result); } } } if (count) { if (cmdOutBufPos) { Log(LOG_LEVEL_NOTICE, "%s", cmdOutBuf); } Log(LOG_LEVEL_INFO, "Last %d quoted lines were generated by promiser '%s'", count, cmdline); } if (a->contain.timeout != CF_NOINT) { alarm(0); signal(SIGALRM, SIG_DFL); } Log(info_or_verbose, "Completed execution of '%s'", cmdline); #ifndef __MINGW32__ umask(maskval); #endif #ifndef __MINGW32__ if ((a->transaction.background) && do_work_here) // Child process { Log(LOG_LEVEL_VERBOSE, "Backgrounded command '%s' is done - exiting", cmdline); // _exit() since this is the child and we don't want to run cleanup _exit(EXIT_SUCCESS); } #endif /* !__MINGW32__ */ return ACTION_RESULT_OK; } /*************************************************************/ /* Level */ /*************************************************************/ void PreviewProtocolLine(char *line, char *comm) { int i; char *message = line; /* * Table matching cfoutputlevel enums to log prefixes. */ char *prefixes[] = { ":silent:", ":inform:", ":verbose:", ":editverbose:", ":error:", ":logonly:", }; int precount = sizeof(prefixes) / sizeof(char *); if (line[0] == ':') { /* * Line begins with colon - see if it matches a log prefix. */ for (i = 0; i < precount; i++) { int prelen = 0; prelen = strlen(prefixes[i]); if (strncmp(line, prefixes[i], prelen) == 0) { /* * Found log prefix - set logging level, and remove the * prefix from the log message. */ message += prelen; break; } } } Log(LOG_LEVEL_VERBOSE, "'%s', preview of '%s'", message, comm); } cfengine-3.24.2/cf-agent/verify_users_pam.c0000644000000000000000000015633615010704253020603 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include #include #include #include // CompileRegex() #include // BufferData() #include #include #include #include #include #include #include #include #ifdef HAVE_SHADOW_H # include #endif #ifdef __FreeBSD__ /* Use pw_scan() and gr_scan() to implement fgetpwent() and * fgetgrent() on FreeBSD. */ #include #endif #define CFUSR_CHECKBIT(v,p) ((v) & (1UL << (p))) #define CFUSR_SETBIT(v,p) ((v) |= ((1UL) << (p))) #define CFUSR_CLEARBIT(v,p) ((v) &= ~((1UL) << (p))) typedef enum { i_uid, i_password, i_comment, i_group, i_groups, i_home, i_shell, i_locked } which; static bool SupportsOption(const char *cmd, const char *option); static const char *GetPlatformSpecificExpirationDate() { // 2nd January 1970. #if defined(_AIX) return "0102000070"; #elif defined(__hpux) || defined(__SVR4) return "02/01/70"; #elif defined(__NetBSD__) return "January 02 1970"; #elif defined(__linux__) return "1970-01-02"; #elif defined(__FreeBSD__) return "02-Jan-1970"; #else # error Your operating system lacks the proper string for the "usermod -e" utility. #endif } static int PasswordSupplier(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { // All allocations here will be freed by the pam framework. *resp = xmalloc(num_msg * sizeof(struct pam_response)); for (int i = 0; i < num_msg; i++) { if ((*msg)[i].msg_style == PAM_PROMPT_ECHO_OFF) { (*resp)[i].resp = xstrdup((const char *)appdata_ptr); } else { (*resp)[i].resp = xstrdup(""); } (*resp)[i].resp_retcode = 0; } return PAM_SUCCESS; } #ifdef _AIX /* * Format of passwd file on AIX is: * * user1: * password = hash * lastupdate = 12783612 * user2: * password = hash * lastupdate = 12783612 * <...> */ static bool GetAIXShadowHash(const char *puser, const char **result) { FILE *fptr = safe_fopen("/etc/security/passwd", "r"); if (fptr == NULL) { return false; } // Not super pretty with a static variable, but it is how POSIX functions // getspnam() and friends do it. static char hash_buf[CF_BUFSIZE]; bool ret = false; char *buf = NULL; size_t bufsize = 0; size_t puser_len = strlen(puser); char name_regex_str[strlen(puser) + 3]; Regex *name_regex = CompileRegex("^(\\S+):"); Regex *hash_regex = CompileRegex("^\\s+password\\s*=\\s*(\\S+)"); bool in_user_section = false; while (true) { ssize_t read_result = CfReadLine(&buf, &bufsize, fptr); if (read_result < 0) { if (feof(fptr)) { errno = 0; } goto end; } size_t match_start; size_t match_end; if (StringMatchWithPrecompiledRegex(name_regex, buf, &match_start, &match_end)) { /* Compare the part without the ':' */ if (StringEqualN(buf, puser, match_end - match_start - 1)) { in_user_section = true; } else { in_user_section = false; } continue; } if (!in_user_section) { continue; } Seq *captures = StringMatchCapturesWithPrecompiledRegex(hash_regex, buf, false); if (captures != NULL) { /* captures are buffers, the first one being the full match, the * second being the first capture group, etc. */ StringCopy(BufferData(SeqAt(captures, 1)), hash_buf, sizeof(hash_buf)); *result = hash_buf; ret = true; SeqDestroy(captures); goto end; } } end: RegexDestroy(name_regex); RegexDestroy(hash_regex); free(buf); fclose(fptr); return ret; } #endif // _AIX #if HAVE_FGETSPENT // Uses fgetspent() instead of getspnam(), to guarantee that the returned user // is a local user, and not for example from LDAP. static struct spwd *GetSpEntry(const char *puser) { FILE *fptr = safe_fopen("/etc/shadow", "r"); if (!fptr) { Log(LOG_LEVEL_ERR, "Could not open '/etc/shadow': %s", GetErrorStr()); return NULL; } struct spwd *spwd_info; bool found = false; while ((spwd_info = fgetspent(fptr))) { if (strcmp(puser, spwd_info->sp_namp) == 0) { found = true; break; } } fclose(fptr); if (found) { return spwd_info; } else { // Failure to find the user means we just set errno to zero. // Perhaps not optimal, but we cannot pass ENOENT, because the fopen might // fail for this reason, and that should not be treated the same. errno = 0; return NULL; } } #endif // HAVE_FGETSPENT static bool GetPasswordHash(const char *puser, const struct passwd *passwd_info, const char **result) { // Silence warning. (void)puser; // If the hash is very short, it's probably a stub. Try getting the shadow password instead. if (strlen(passwd_info->pw_passwd) <= 4) { #ifdef HAVE_FGETSPENT struct stat statbuf; if (stat("/etc/shadow", &statbuf) == 0) { Log(LOG_LEVEL_VERBOSE, "Getting user '%s' password hash from shadow database.", puser); struct spwd *spwd_info; errno = 0; spwd_info = GetSpEntry(puser); if (!spwd_info) { if (errno) { Log(LOG_LEVEL_ERR, "Could not get information from user shadow database: %s", GetErrorStr()); return false; } else { Log(LOG_LEVEL_ERR, "Could not find user when checking password."); return false; } } else if (spwd_info) { *result = spwd_info->sp_pwdp; return true; } } #elif defined(_AIX) if (!GetAIXShadowHash(puser, result)) { Log(LOG_LEVEL_ERR, "Could not get information from user shadow database: %s", GetErrorStr()); return false; } return true; #endif } Log(LOG_LEVEL_VERBOSE, "Getting user '%s' password hash from passwd database.", puser); *result = passwd_info->pw_passwd; return true; } static bool IsPasswordCorrect(const char *puser, const char* password, PasswordFormat format, const struct passwd *passwd_info) { /* * Check if password is already correct. If format is 'hash' we just do a simple * comparison with the supplied hash value, otherwise we try a pam login using * the real password. */ if (format == PASSWORD_FORMAT_HASH) { const char *system_hash; if (!GetPasswordHash(puser, passwd_info, &system_hash)) { return false; } bool result = (strcmp(password, system_hash) == 0); Log(LOG_LEVEL_VERBOSE, "Verifying password hash for user '%s': %s.", puser, result ? "correct" : "incorrect"); return result; } else if (format != PASSWORD_FORMAT_PLAINTEXT) { ProgrammingError("Unknown PasswordFormat value"); } int status; pam_handle_t *handle; struct pam_conv conv; conv.conv = PasswordSupplier; conv.appdata_ptr = (void*)password; status = pam_start("login", puser, &conv, &handle); if (status != PAM_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not initialize pam session. (pam_start: '%s')", pam_strerror(NULL, status)); return false; } status = pam_authenticate(handle, PAM_SILENT); pam_end(handle, status); if (status == PAM_SUCCESS) { Log(LOG_LEVEL_VERBOSE, "Verifying plaintext password for user '%s': correct.", puser); return true; } else if (status != PAM_AUTH_ERR) { Log(LOG_LEVEL_ERR, "Could not check password for user '%s' against stored password. (pam_authenticate: '%s')", puser, pam_strerror(NULL, status)); return false; } Log(LOG_LEVEL_VERBOSE, "Verifying plaintext password for user '%s': incorrect.", puser); return false; } static bool ChangePlaintextPasswordUsingLibPam(const char *puser, const char *password) { int status; pam_handle_t *handle; struct pam_conv conv; conv.conv = PasswordSupplier; conv.appdata_ptr = (void*)password; status = pam_start("passwd", puser, &conv, &handle); if (status != PAM_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not initialize pam session. (pam_start: '%s')", pam_strerror(NULL, status)); return false; } Log(LOG_LEVEL_VERBOSE, "Changing password for user '%s'.", puser); status = pam_chauthtok(handle, PAM_SILENT); pam_end(handle, status); if (status == PAM_SUCCESS) { return true; } else { Log(LOG_LEVEL_ERR, "Could not change password for user '%s'. (pam_chauthtok: '%s')", puser, pam_strerror(handle, status)); return false; } } static bool ClearPasswordAdministrationFlags(const char *puser) { (void)puser; // Avoid warning. #ifdef HAVE_PWDADM const char *cmd_str = PWDADM " -c "; char final_cmd[strlen(cmd_str) + strlen(puser) + 1]; xsnprintf(final_cmd, sizeof(final_cmd), "%s%s", cmd_str, puser); Log(LOG_LEVEL_VERBOSE, "Clearing password administration flags for user '%s'. (command: '%s')", puser, final_cmd); int status; status = system(final_cmd); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { Log(LOG_LEVEL_ERR, "Command failed while trying to clear password flags for user '%s'. (Command: '%s')", puser, final_cmd); return false; } #endif // HAVE_PWDADM return true; } #ifdef HAVE_CHPASSWD static bool ChangePasswordHashUsingChpasswd(const char *puser, const char *password) { int status; const char *cmd_str = CHPASSWD " -e"; Log(LOG_LEVEL_VERBOSE, "Changing password hash for user '%s'. (command: '%s')", puser, cmd_str); FILE *cmd = cf_popen_sh(cmd_str, "w"); if (!cmd) { Log(LOG_LEVEL_ERR, "Could not launch password changing command '%s': %s.", cmd_str, GetErrorStr()); return false; } // String lengths plus a ':' and a '\n', but not including '\0'. size_t total_len = strlen(puser) + strlen(password) + 2; char change_string[total_len + 1]; xsnprintf(change_string, total_len + 1, "%s:%s\n", puser, password); clearerr(cmd); if (fwrite(change_string, total_len, 1, cmd) != 1) { const char *error_str; if (ferror(cmd)) { error_str = GetErrorStr(); } else { error_str = "Unknown error"; } Log(LOG_LEVEL_ERR, "Could not write password to password changing command '%s': %s.", cmd_str, error_str); cf_pclose(cmd); return false; } status = cf_pclose(cmd); if (status) { Log(LOG_LEVEL_ERR, "'%s' returned non-zero status: %i\n", cmd_str, status); return false; } return true; } #endif // HAVE_CHPASSWD #if defined(HAVE_LCKPWDF) && defined(HAVE_ULCKPWDF) static bool ChangePasswordHashUsingLckpwdf(const char *puser, const char *password) { bool result = false; struct stat statbuf; const char *passwd_file = "/etc/shadow"; if (stat(passwd_file, &statbuf) == -1) { passwd_file = "/etc/passwd"; } Log(LOG_LEVEL_VERBOSE, "Changing password hash for user '%s' by editing '%s'.", puser, passwd_file); if (lckpwdf() != 0) { Log(LOG_LEVEL_ERR, "Not able to obtain lock on password database."); return false; } char backup_file[strlen(passwd_file) + strlen(".cf-backup") + 1]; xsnprintf(backup_file, sizeof(backup_file), "%s.cf-backup", passwd_file); unlink(backup_file); char edit_file[strlen(passwd_file) + strlen(".cf-edit") + 1]; xsnprintf(edit_file, sizeof(edit_file), "%s.cf-edit", passwd_file); unlink(edit_file); if (!CopyRegularFileDisk(passwd_file, backup_file)) { Log(LOG_LEVEL_ERR, "Could not back up existing password database '%s' to '%s'.", passwd_file, backup_file); goto unlock_passwd; } FILE *passwd_fd = safe_fopen(passwd_file, "r"); if (!passwd_fd) { Log(LOG_LEVEL_ERR, "Could not open password database '%s'. (fopen: '%s')", passwd_file, GetErrorStr()); goto unlock_passwd; } int edit_fd_int = open(edit_file, O_WRONLY | O_CREAT | O_EXCL, S_IWUSR); if (edit_fd_int < 0) { if (errno == EEXIST) { Log(LOG_LEVEL_CRIT, "Temporary file already existed when trying to open '%s'. (open: '%s') " "This should NEVER happen and could mean that someone is trying to break into your system!!", edit_file, GetErrorStr()); } else { Log(LOG_LEVEL_ERR, "Could not open password database temporary file '%s'. (open: '%s')", edit_file, GetErrorStr()); } goto close_passwd_fd; } FILE *edit_fd = fdopen(edit_fd_int, "w"); if (!edit_fd) { Log(LOG_LEVEL_ERR, "Could not open password database temporary file '%s'. (fopen: '%s')", edit_file, GetErrorStr()); close(edit_fd_int); goto close_passwd_fd; } while (true) { size_t line_size = 0; char *line = NULL; int read_result = CfReadLine(&line, &line_size, passwd_fd); if (read_result < 0) { if (!feof(passwd_fd)) { Log(LOG_LEVEL_ERR, "Error while reading password database: %s", GetErrorStr()); free(line); goto close_both; } else { break; } } // Editing the password database is risky business, so do as little parsing as possible. // Just enough to get the hash in there. char *field_start = NULL; char *field_end = NULL; field_start = strchr(line, ':'); if (field_start) { field_end = strchr(field_start + 1, ':'); } if (!field_start || !field_end) { Log(LOG_LEVEL_ERR, "Unexpected format found in password database while editing user '%s'. Not updating.", puser); free(line); goto close_both; } // Worst case length: Existing password is empty plus one '\n' and one '\0'. char new_line[strlen(line) + strlen(password) + 2]; *field_start = '\0'; *field_end = '\0'; if (strcmp(line, puser) == 0) { xsnprintf(new_line, sizeof(new_line), "%s:%s:%s\n", line, password, field_end + 1); } else { xsnprintf(new_line, sizeof(new_line), "%s:%s:%s\n", line, field_start + 1, field_end + 1); } free(line); size_t new_line_size = strlen(new_line); size_t written_so_far = 0; while (written_so_far < new_line_size) { clearerr(edit_fd); size_t written = fwrite(new_line, 1, new_line_size, edit_fd); if (written == 0) { const char *err_str; if (ferror(edit_fd)) { err_str = GetErrorStr(); } else { err_str = "Unknown error"; } Log(LOG_LEVEL_ERR, "Error while writing to file '%s'. (fwrite: '%s')", edit_file, err_str); goto close_both; } written_so_far += written; } } fclose(edit_fd); edit_fd = NULL; // mark as NULL so we don't close it later fclose(passwd_fd); passwd_fd = NULL; // mark as NULL so we don't close it later if (!CopyFilePermissionsDisk(passwd_file, edit_file)) { Log(LOG_LEVEL_ERR, "Could not copy permissions from '%s' to '%s'", passwd_file, edit_file); goto unlock_passwd; } if (rename(edit_file, passwd_file) < 0) { Log(LOG_LEVEL_ERR, "Could not replace '%s' with edited password database '%s'. (rename: '%s')", passwd_file, edit_file, GetErrorStr()); goto unlock_passwd; } result = true; goto unlock_passwd; close_both: if (edit_fd != NULL) { fclose(edit_fd); } unlink(edit_file); close_passwd_fd: if (passwd_fd != NULL) { fclose(passwd_fd); } unlock_passwd: ulckpwdf(); return result; } #endif // defined(HAVE_LCKPWDF) && defined(HAVE_ULCKPWDF) static bool ExecuteUserCommand(const char *puser, const char *cmd, size_t sizeof_cmd, const char *action_msg, const char *cap_action_msg) { if (strlen(cmd) >= sizeof_cmd - 1) { // Instead of checking every StringAppend call, assume that a maxed out // string length overflowed the string. Log(LOG_LEVEL_ERR, "Command line too long while %s user '%s'", action_msg, puser); return false; } Log(LOG_LEVEL_VERBOSE, "%s user '%s'. (command: '%s')", cap_action_msg, puser, cmd); int status = system(cmd); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { Log(LOG_LEVEL_ERR, "Command returned error while %s user '%s'. (Command line: '%s')", action_msg, puser, cmd); return false; } return true; } #ifdef HAVE_CHPASS static bool ChangePasswordHashUsingChpass(const char *puser, const char *password) { char cmd[CF_BUFSIZE]; strcpy(cmd, CHPASS); StringAppend(cmd, " -p \'", sizeof(cmd)); StringAppend(cmd, password, sizeof(cmd)); StringAppend(cmd, "\' ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); Log(LOG_LEVEL_VERBOSE, "Changing password hash for user '%s'. (command: '%s')", puser, cmd); return ExecuteUserCommand(puser, cmd, sizeof(cmd), "changing", "Changing"); } #endif // HAVE_CHPASS static bool ChangePassword(const char *puser, const char *password, PasswordFormat format) { assert(format == PASSWORD_FORMAT_PLAINTEXT || format == PASSWORD_FORMAT_HASH); bool successful = false; if (format == PASSWORD_FORMAT_PLAINTEXT) { successful = ChangePlaintextPasswordUsingLibPam(puser, password); } else { #ifdef HAVE_CHPASSWD struct stat statbuf; if (stat(CHPASSWD, &statbuf) != -1 && SupportsOption(CHPASSWD, "-e")) { successful = ChangePasswordHashUsingChpasswd(puser, password); } else #endif #if defined(HAVE_LCKPWDF) && defined(HAVE_ULCKPWDF) { successful = ChangePasswordHashUsingLckpwdf(puser, password); } #elif defined(HAVE_CHPASS) { successful = ChangePasswordHashUsingChpass(puser, password); } #elif defined(HAVE_CHPASSWD) { Log(LOG_LEVEL_ERR, "No means to set password for user '%s' was found. Tried using the '%s' tool with no luck.", puser, CHPASSWD); successful = false; } #else { Log(LOG_LEVEL_WARNING, "Setting hashed password or locking user '%s' not supported on this platform.", puser); successful = false; } #endif } if (successful) { successful = ClearPasswordAdministrationFlags(puser); } return successful; } static bool IsHashLocked(const char *hash) { #ifdef __FreeBSD__ /* Accounts are locked by prepending "*LOCKED*" to the password * hash on FreeBSD and possibly other systems using pw. */ return (strstr(hash, "*LOCKED*") != NULL); #else /* Accounts are locked by prepending "!" to the password hash on * some systems. */ return (hash[0] == '!'); #endif } static bool IsAccountLocked(const char *puser, const struct passwd *passwd_info) { /* Note that when we lock an account, we do two things, we make the password hash invalid * by adding a '!', and we set the expiry date far in the past. However, we only have the * possibility of checking the password hash, because the expire field is not exposed by * POSIX functions. This is not a problem as long as you stick to CFEngine, but if the user * unlocks the account manually, but forgets to reset the expiry time, CFEngine could think * that the account is unlocked when it really isn't. */ const char *system_hash; if (!GetPasswordHash(puser, passwd_info, &system_hash)) { return false; } return IsHashLocked(system_hash); } static bool PlatformSupportsExpirationLock(void) { #ifdef __sun // Solaris has the concept of account expiration, but it is only possible // to set a date in the future. We need to set it to a past date, so we // have to skip it on that platform. return false; #elif __hpux struct stat statbuf; // "/etc/shadow" signals the so called "trusted model" on HPUX. if (stat("/etc/shadow", &statbuf) == 0) { return true; } else { return false; } #else return true; #endif } #ifdef HAVE_USERMOD static bool SetAccountLockExpirationUsingUsermod(const char *puser, bool lock) { if (!PlatformSupportsExpirationLock()) { return true; } char cmd[CF_BUFSIZE + strlen(puser)]; strcpy (cmd, USERMOD); StringAppend(cmd, " -e \"", sizeof(cmd)); if (lock) { StringAppend(cmd, GetPlatformSpecificExpirationDate(), sizeof(cmd)); } StringAppend(cmd, "\" ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); Log(LOG_LEVEL_VERBOSE, "%s user '%s' by setting expiry date. (command: '%s')", lock ? "Locking" : "Unlocking", puser, cmd); int status; status = system(cmd); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { Log(LOG_LEVEL_ERR, "Command returned error while %s user '%s'. (Command line: '%s')", lock ? "locking" : "unlocking", puser, cmd); return false; } return true; } #endif #ifdef HAVE_PW static bool SetAccountLockExpirationUsingPw(const char *puser, bool lock) { if (!PlatformSupportsExpirationLock()) { return true; } char cmd[CF_BUFSIZE]; strcpy(cmd, PW); StringAppend(cmd, " usermod ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); StringAppend(cmd, " -e \"", sizeof(cmd)); if (lock) { StringAppend(cmd, GetPlatformSpecificExpirationDate(), sizeof(cmd)); } StringAppend(cmd, "\" ", sizeof(cmd)); Log(LOG_LEVEL_VERBOSE, "%s user '%s' by setting expiry date. (command: '%s')", lock ? "Locking" : "Unlocking", puser, cmd); const int status = system(cmd); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { Log(LOG_LEVEL_ERR, "Command returned error while %s user '%s'. (Command line: '%s')", lock ? "locking" : "unlocking", puser, cmd); return false; } return true; } #endif static bool SetAccountLockExpiration(const char *puser, bool lock) { #if defined(HAVE_USERMOD) return SetAccountLockExpirationUsingUsermod(puser, lock); #elif defined(HAVE_PW) return SetAccountLockExpirationUsingPw(puser, lock); #else Log(LOG_LEVEL_WARNING, "Cannot set account lock exporation, not supported on this platform"); return false; #endif } static bool SetAccountLocked(const char *puser, const char *hash, bool lock) { if (hash) { if (lock) { if (!IsHashLocked(hash)) { #ifdef HAVE_PW char new_hash[strlen(hash) + 9]; xsnprintf(new_hash, sizeof(new_hash), "*LOCKED*%s", hash); #else char new_hash[strlen(hash) + 2]; xsnprintf(new_hash, sizeof(new_hash), "!%s", hash); #endif if (!ChangePassword(puser, new_hash, PASSWORD_FORMAT_HASH)) { return false; } } } else { if (IsHashLocked(hash)) { #ifdef HAVE_PW /* Accounts are locked by prepending "*LOCKED*" to the * password hash on FreeBSD. Skip these 8 characters * to obtain only the password hash. */ if (!ChangePassword(puser, &hash[8], PASSWORD_FORMAT_HASH)) #else /* Accounts are locked by prepending "!" to the * password hash on some systems. Skip this 1 * character to obtain only the password hash. */ if (!ChangePassword(puser, &hash[1], PASSWORD_FORMAT_HASH)) #endif { return false; } } } } return SetAccountLockExpiration(puser, lock); } static void TransformGidsToGroups(StringSet **list); static bool GetGroupInfo (const char *user, const User *u, StringSet **groups_to_set, StringSet **groups_missing, StringSet **current_secondary_groups) { assert(u != NULL); bool ret = true; struct group *group_info; FILE *fptr = safe_fopen("/etc/group", "r"); if (!fptr) { Log(LOG_LEVEL_ERR, "Could not open '/etc/group': %s", GetErrorStr()); return false; } StringSet *wanted_groups = StringSetNew(); if (u->groups_secondary_given) { for (Rlist *ptr = u->groups_secondary; ptr != NULL; ptr = ptr->next) { StringSetAdd(*groups_missing, xstrdup(RvalScalarValue(ptr->val))); StringSetAdd(wanted_groups, xstrdup(RvalScalarValue(ptr->val))); } TransformGidsToGroups(groups_missing); TransformGidsToGroups(&wanted_groups); } while (true) { errno = 0; // Use fgetgrent() instead of getgrent(), to guarantee that the // returned group is a local group, and not for example from LDAP. group_info = fgetgrent(fptr); if (!group_info) { // Documentation among Unices is conflicting on return codes. When there // are no more entries, this happens: // Linux = ENOENT // AIX = ESRCH if (errno && errno != ENOENT && errno != ESRCH) { Log(LOG_LEVEL_ERR, "Error while getting group list. (fgetgrent: '%s')", GetErrorStr()); ret = false; } break; } if (StringSetContains(wanted_groups, group_info->gr_name)) { StringSetRemove(*groups_missing, group_info->gr_name); } // At least on FreeBSD, gr_mem can be NULL: if (group_info->gr_mem != NULL) { bool found = false; for (int i = 0; !found && group_info->gr_mem[i] != NULL; i++) { if (strcmp(user, group_info->gr_mem[i]) == 0) { found = true; StringSetAdd(*current_secondary_groups, xstrdup(group_info->gr_name)); if (StringSetContains(wanted_groups, group_info->gr_name)) { StringSetAdd(*groups_to_set, xstrdup(group_info->gr_name)); } } } if (!found && StringSetContains(wanted_groups, group_info->gr_name)) { StringSetAdd(*groups_to_set, xstrdup(group_info->gr_name)); } } #ifdef __FreeBSD__ free(group_info); #endif } StringSetDestroy(wanted_groups); fclose(fptr); return ret; } static bool EqualGid(const char *key, const struct group *entry) { assert(entry != NULL); unsigned long gid; int ret = StringToUlong(key, &gid); if (ret != 0) { LogStringToLongError(key, "EqualGid", ret); return false; } return (gid == entry->gr_gid); } static bool EqualGroupName(const char *key, const struct group *entry) { assert(entry != NULL); return (strcmp(key, entry->gr_name) == 0); } #ifdef __FreeBSD__ struct group *fgetgrent(FILE *stream) { if (stream == NULL) { return NULL; } struct group *gr = NULL; char *line = NULL; size_t linecap = 0; ssize_t linelen; while ((linelen = getline(&line, &linecap, stream)) > 0) { /* Skip comments and empty lines */ if (*line == '\n' || *line == '#') { continue; } /* trim latest \n */ if (line[linelen - 1] == '\n') { line[linelen - 1] = '\0'; } gr = gr_scan(line); if (gr != NULL) { break; } } free(line); return gr; } #endif // Uses fgetgrent() instead of getgrnam(), to guarantee that the returned group // is a local group, and not for example from LDAP. static struct group *GetGrEntry(const char *key, bool (*equal_fn)(const char *key, const struct group *entry)) { FILE *fptr = safe_fopen("/etc/group", "r"); if (!fptr) { Log(LOG_LEVEL_ERR, "Could not open '/etc/group': %s", GetErrorStr()); return NULL; } struct group *group_info; bool found = false; while ((group_info = fgetgrent(fptr))) { if (equal_fn(key, group_info)) { found = true; break; } #ifdef __FreeBSD__ free(group_info); #endif } fclose(fptr); if (found) { return group_info; } else { // Failure to find the user means we just set errno to zero. // Perhaps not optimal, but we cannot pass ENOENT, because the fopen might // fail for this reason, and that should not be treated the same. errno = 0; return NULL; } } static void TransformGidsToGroups(StringSet **list) { StringSet *new_list = StringSetNew(); StringSetIterator i = StringSetIteratorInit(*list); const char *data; for (data = StringSetIteratorNext(&i); data; data = StringSetIteratorNext(&i)) { if (strlen(data) != strspn(data, "0123456789")) { // Cannot possibly be a gid. StringSetAdd(new_list, xstrdup(data)); continue; } // In groups vs gids, groups take precedence. So check if it exists. struct group *group_info = GetGrEntry(data, &EqualGroupName); if (!group_info) { if (errno == 0) { group_info = GetGrEntry(data, &EqualGid); if (!group_info) { if (errno != 0) { Log(LOG_LEVEL_ERR, "Error while checking group name '%s': %s", data, GetErrorStr()); StringSetDestroy(new_list); return; } // Neither group nor gid is found. This will lead to an error later, but we don't // handle that here. } else { // Replace gid with group name. StringSetAdd(new_list, xstrdup(group_info->gr_name)); } } else { Log(LOG_LEVEL_ERR, "Error while checking group name '%s': '%s'", data, GetErrorStr()); StringSetDestroy(new_list); return; } } else { StringSetAdd(new_list, xstrdup(data)); } #ifdef __FreeBSD__ free(group_info); #endif } StringSet *old_list = *list; *list = new_list; StringSetDestroy(old_list); } static bool VerifyIfUserNeedsModifs(const char *puser, const User *u, const struct passwd *passwd_info, uint32_t *changemap, StringSet *groups_to_set, StringSet *current_secondary_groups) { assert(u != NULL); assert(passwd_info != NULL); if (u->description != NULL && !StringEqual(u->description, passwd_info->pw_gecos)) { CFUSR_SETBIT(*changemap, i_comment); } if (u->uid != NULL) { unsigned long uid; int ret = StringToUlong(u->uid, &uid); if (ret != 0 || uid != passwd_info->pw_uid) { CFUSR_SETBIT(*changemap, i_uid); } } if (u->home_dir != NULL && !StringEqual(u->home_dir, passwd_info->pw_dir)) { CFUSR_SETBIT(*changemap, i_home); } if (u->shell != NULL && !StringEqual(u->shell, passwd_info->pw_shell)) { CFUSR_SETBIT(*changemap, i_shell); } bool account_is_locked = IsAccountLocked(puser, passwd_info); if ((!account_is_locked && u->policy == USER_STATE_LOCKED) || (account_is_locked && u->policy != USER_STATE_LOCKED)) { CFUSR_SETBIT(*changemap, i_locked); } // Don't bother with passwords if the account is going to be locked anyway. if (u->password != NULL && !StringEqual(u->password, "") && u->policy != USER_STATE_LOCKED) { if (!IsPasswordCorrect(puser, u->password, u->password_format, passwd_info)) { CFUSR_SETBIT(*changemap, i_password); } } if (u->groups_secondary_given && !StringSetIsEqual(groups_to_set, current_secondary_groups)) { CFUSR_SETBIT(*changemap, i_groups); } if (SafeStringLength(u->group_primary) != 0) { bool group_could_be_gid = (strlen(u->group_primary) == strspn(u->group_primary, "0123456789")); // We try name first, even if it looks like a gid. Only fall back to gid. errno = 0; struct group *group_info = GetGrEntry(u->group_primary, &EqualGroupName); if (group_info == NULL && errno != 0) { Log(LOG_LEVEL_ERR, "Could not obtain information about group '%s': %s", u->group_primary, GetErrorStr()); CFUSR_SETBIT(*changemap, i_group); } else if (group_info == NULL) { if (group_could_be_gid) { unsigned long gid; int ret = StringToUlong(u->group_primary, &gid); if (ret != 0) { LogStringToLongError(u->group_primary, "VerifyIfUserNeedsModifs", ret); CFUSR_SETBIT(*changemap, i_group); } if (gid != passwd_info->pw_gid) { CFUSR_SETBIT(*changemap, i_group); } } else { Log(LOG_LEVEL_ERR, "No such group '%s'.", u->group_primary); CFUSR_SETBIT(*changemap, i_group); } } else { if (group_info->gr_gid != passwd_info->pw_gid) { CFUSR_SETBIT(*changemap, i_group); } } #ifdef __FreeBSD__ free(group_info); #endif } //////////////////////////////////////////// if (*changemap == 0) { return false; } else { return true; } } static bool SupportsOption(const char *cmd, const char *option) { bool supports_option = false; char help_argument[] = " --help"; char help_command[strlen(cmd) + sizeof(help_argument)]; xsnprintf(help_command, sizeof(help_command), "%s%s", cmd, help_argument); FILE *fptr = cf_popen(help_command, "r", true); char *buf = NULL; size_t bufsize = 0; size_t optlen = strlen(option); while (CfReadLine(&buf, &bufsize, fptr) >= 0) { char *m_pos = buf; while ((m_pos = strstr(m_pos, option))) { // Check against false alarms, e.g. hyphenated words in normal text or an // option (say, "-M") that is part of "--M". if ((m_pos == buf || (m_pos[-1] != '-' && (isspace(m_pos[-1]) || ispunct(m_pos[-1])))) && (m_pos[optlen] == '\0' || (isspace(m_pos[optlen]) || ispunct(m_pos[optlen])))) { supports_option = true; // Break out of strstr loop, but read till the end to avoid broken pipes. break; } m_pos++; } } cf_pclose(fptr); free(buf); return supports_option; } #ifdef HAVE_USERADD static bool DoCreateUserUsingUseradd(const char *puser, const User *u, enum cfopaction action, EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(u != NULL); char cmd[CF_BUFSIZE]; char sec_group_args[CF_BUFSIZE]; if (puser == NULL || !strcmp (puser, "")) { return false; } strcpy (cmd, USERADD); if (u->uid != NULL && strcmp (u->uid, "")) { StringAppend(cmd, " -u \"", sizeof(cmd)); StringAppend(cmd, u->uid, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->description != NULL) { StringAppend(cmd, " -c \"", sizeof(cmd)); StringAppend(cmd, u->description, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->group_primary != NULL && strcmp (u->group_primary, "")) { // TODO: Should check that group exists StringAppend(cmd, " -g \"", sizeof(cmd)); StringAppend(cmd, u->group_primary, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->groups_secondary_given) { // TODO: Should check that groups exist strlcpy(sec_group_args, " -G \"", sizeof(sec_group_args)); char sep[2] = { '\0', '\0' }; for (Rlist *i = u->groups_secondary; i; i = i->next) { StringAppend(sec_group_args, sep, sizeof(sec_group_args)); StringAppend(sec_group_args, RvalScalarValue(i->val), sizeof(sec_group_args)); sep[0] = ','; } StringAppend(sec_group_args, "\"", sizeof(sec_group_args)); StringAppend(cmd, sec_group_args, sizeof(cmd)); } if (u->home_dir != NULL && strcmp (u->home_dir, "")) { StringAppend(cmd, " -d \"", sizeof(cmd)); StringAppend(cmd, u->home_dir, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->shell != NULL && strcmp (u->shell, "")) { StringAppend(cmd, " -s \"", sizeof(cmd)); StringAppend(cmd, u->shell, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } #ifndef __hpux // HP-UX has two variants of useradd, the normal one which does // not support -M and one variant to modify default values which // does take -M and yes or no // Since both are output with -h SupportOption incorrectly reports // -M as supported if (SupportsOption(USERADD, "-M")) { // Prevents creation of home_dir. // We want home_bundle to do that. StringAppend(cmd, " -M", sizeof(cmd)); } #endif StringAppend(cmd, " ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); if (action == cfa_warn || DONTDO) { Log(LOG_LEVEL_WARNING, "Need to create user '%s'.", puser); return false; } else { if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "creating", "Creating")) { return false; } if (u->groups_secondary_given) { // Work around issue on AIX. Always set secondary groups a second time, because AIX // likes to assign the primary group as the secondary group as well, even if we didn't // ask for it. strlcpy(cmd, USERMOD, sizeof(cmd)); StringAppend(cmd, sec_group_args, sizeof(cmd)); StringAppend(cmd, " ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "modifying", "Modifying")) { return false; } } // Initially, "useradd" may set the password to '!', which confuses our detection for // locked accounts. So reset it to 'x' hash instead, which will never match anything. if (!ChangePassword(puser, "x", PASSWORD_FORMAT_HASH)) { return false; } if (u->policy == USER_STATE_LOCKED) { if (!SetAccountLocked(puser, "x", true)) { return false; } } if (a->havebundle) { const Constraint *method_attrib = PromiseGetConstraint(pp, "home_bundle"); if (method_attrib == NULL) { Log(LOG_LEVEL_ERR, "Cannot create user (home_bundle not found)"); return false; } VerifyMethod(ctx, method_attrib->rval, a, pp); } if (u->policy != USER_STATE_LOCKED && u->password != NULL && strcmp (u->password, "")) { if (!ChangePassword(puser, u->password, u->password_format)) { return false; } } } return true; } #endif #ifdef HAVE_PW static bool DoCreateUserUsingPw(const char *puser, const User *u, enum cfopaction action, EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(u != NULL); char cmd[CF_BUFSIZE]; char sec_group_args[CF_BUFSIZE]; if (NULL_OR_EMPTY(puser)) { return false; } strcpy (cmd, PW); StringAppend(cmd, " useradd ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); if (!NULL_OR_EMPTY(u->uid)) { StringAppend(cmd, " -u \"", sizeof(cmd)); StringAppend(cmd, u->uid, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->description != NULL) { StringAppend(cmd, " -c \"", sizeof(cmd)); StringAppend(cmd, u->description, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->group_primary != NULL && strcmp (u->group_primary, "")) { // TODO: Should check that group exists StringAppend(cmd, " -g \"", sizeof(cmd)); StringAppend(cmd, u->group_primary, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->groups_secondary_given) { // TODO: Should check that groups exist strlcpy(sec_group_args, " -G \"", sizeof(sec_group_args)); char sep[2] = { '\0', '\0' }; for (Rlist *i = u->groups_secondary; i != NULL; i = i->next) { StringAppend(sec_group_args, sep, sizeof(sec_group_args)); StringAppend(sec_group_args, RvalScalarValue(i->val), sizeof(sec_group_args)); sep[0] = ','; } StringAppend(sec_group_args, "\"", sizeof(sec_group_args)); StringAppend(cmd, sec_group_args, sizeof(cmd)); } if (u->home_dir != NULL && strcmp(u->home_dir, "")) { StringAppend(cmd, " -d \"", sizeof(cmd)); StringAppend(cmd, u->home_dir, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (u->shell != NULL && strcmp (u->shell, "")) { StringAppend(cmd, " -s \"", sizeof(cmd)); StringAppend(cmd, u->shell, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (action == cfa_warn || DONTDO) { Log(LOG_LEVEL_WARNING, "Need to create user '%s'", puser); return false; } else { if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "creating", "Creating")) { return false; } if (!ChangePassword(puser, "x", PASSWORD_FORMAT_HASH)) { return false; } if (u->policy == USER_STATE_LOCKED) { if (!SetAccountLocked(puser, "x", true)) { return false; } } if (a->havebundle) { const Constraint *method_attrib = PromiseGetConstraint(pp, "home_bundle"); if (method_attrib == NULL) { Log(LOG_LEVEL_ERR, "Cannot create user (home_bundle not found)"); return false; } VerifyMethod(ctx, method_attrib->rval, a, pp); } if (u->policy != USER_STATE_LOCKED && u->password != NULL && strcmp (u->password, "")) { if (!ChangePassword(puser, u->password, u->password_format)) { return false; } } } return true; } #endif static bool DoCreateUser(const char *puser, const User *u, enum cfopaction action, EvalContext *ctx, const Attributes *a, const Promise *pp) { #if defined(HAVE_USERADD) return DoCreateUserUsingUseradd(puser, u, action, ctx, a, pp); #elif defined(HAVE_PW) return DoCreateUserUsingPw(puser, u, action, ctx, a, pp); #else Log(LOG_LEVEL_WARNING, "Cannot create user, not supported on this platform."); return false; #endif } #ifdef HAVE_PW static bool DoRemoveUserUsingPw (const char *puser, enum cfopaction action) { char cmd[CF_BUFSIZE]; strcpy(cmd, PW); StringAppend(cmd, " userdel ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); if (action == cfa_warn || DONTDO) { Log(LOG_LEVEL_WARNING, "Need to remove user '%s'.", puser); return false; } return ExecuteUserCommand(puser, cmd, sizeof(cmd), "removing", "Removing"); } #endif #ifdef HAVE_USERDEL static bool DoRemoveUserUsingUserdel (const char *puser, enum cfopaction action) { char cmd[CF_BUFSIZE]; strcpy (cmd, USERDEL); StringAppend(cmd, " ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); if (action == cfa_warn || DONTDO) { Log(LOG_LEVEL_WARNING, "Need to remove user '%s'.", puser); return false; } return ExecuteUserCommand(puser, cmd, sizeof(cmd), "removing", "Removing"); } #endif static bool DoRemoveUser (const char *puser, enum cfopaction action) { #if defined(HAVE_PW) return DoRemoveUserUsingPw(puser, action); #elif defined(HAVE_USERDEL) return DoRemoveUserUsingUserdel(puser, action); #else Log(LOG_LEVEL_WARNING, "Removing user '%s' not supported on this platform.", puser); return false; #endif } static bool DoModifyUser (const char *puser, const User *u, const struct passwd *passwd_info, uint32_t changemap, enum cfopaction action, StringSet *groups_to_set) { assert(u != NULL); char cmd[CF_BUFSIZE]; #ifdef HAVE_PW strcpy (cmd, PW); StringAppend(cmd, " usermod -n \"", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); StringAppend(cmd, "\" ", sizeof(cmd)); #else strcpy (cmd, USERMOD); #endif if (CFUSR_CHECKBIT (changemap, i_uid) != 0) { StringAppend(cmd, " -u \"", sizeof(cmd)); StringAppend(cmd, u->uid, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (CFUSR_CHECKBIT (changemap, i_comment) != 0) { StringAppend(cmd, " -c \"", sizeof(cmd)); StringAppend(cmd, u->description, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (CFUSR_CHECKBIT (changemap, i_group) != 0) { StringAppend(cmd, " -g \"", sizeof(cmd)); StringAppend(cmd, u->group_primary, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (CFUSR_CHECKBIT (changemap, i_home) != 0) { StringAppend(cmd, " -d \"", sizeof(cmd)); StringAppend(cmd, u->home_dir, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (CFUSR_CHECKBIT (changemap, i_shell) != 0) { StringAppend(cmd, " -s \"", sizeof(cmd)); StringAppend(cmd, u->shell, sizeof(cmd)); StringAppend(cmd, "\"", sizeof(cmd)); } if (CFUSR_CHECKBIT (changemap, i_password) != 0) { if (action == cfa_warn || DONTDO) { Log(LOG_LEVEL_WARNING, "Need to change password for user '%s'.", puser); return false; } else { if (!ChangePassword(puser, u->password, u->password_format)) { return false; } } } if (CFUSR_CHECKBIT (changemap, i_locked) != 0) { if (action == cfa_warn || DONTDO) { Log(LOG_LEVEL_WARNING, "Need to %s account for user '%s'.", (u->policy == USER_STATE_LOCKED) ? "lock" : "unlock", puser); return false; } else { const char *hash; if (CFUSR_CHECKBIT(changemap, i_password) == 0) { if (!GetPasswordHash(puser, passwd_info, &hash)) { return false; } } else { // Don't unlock the hash if we already set the password. Our // cached value in passwd_info->pw_passwd will be wrong, and the // account will already have been unlocked anyway. hash = NULL; } if (!SetAccountLocked(puser, hash, (u->policy == USER_STATE_LOCKED))) { return false; } } } if (CFUSR_CHECKBIT (changemap, i_groups) != 0) { StringAppend(cmd, " -G \"", sizeof(cmd)); Buffer *buf = BufferNew(); buf = StringSetToBuffer(groups_to_set, ','); StringAppend(cmd, buf->buffer, sizeof(cmd)); BufferDestroy(buf); StringAppend(cmd, "\" ", sizeof(cmd)); } #ifndef HAVE_PW StringAppend(cmd, " ", sizeof(cmd)); StringAppend(cmd, puser, sizeof(cmd)); #endif // If password and locking were the only things changed, don't run the command. CFUSR_CLEARBIT(changemap, i_password); CFUSR_CLEARBIT(changemap, i_locked); if (action == cfa_warn || DONTDO) { Log(LOG_LEVEL_WARNING, "Need to update user attributes (command '%s').", cmd); return false; } else if (changemap != 0) { if (!ExecuteUserCommand(puser, cmd, sizeof(cmd), "modifying", "Modifying")) { return false; } } return true; } #ifdef __FreeBSD__ struct passwd *fgetpwent(FILE *stream) { if (stream == NULL) { return NULL; } struct passwd *pw = NULL; char *line = NULL; size_t linecap = 0; ssize_t linelen; int pwd_scanflag = 0; while ((linelen = getline(&line, &linecap, stream)) > 0) { /* Skip comments and empty lines */ if (*line == '\n' || *line == '#') { continue; } /* trim latest \n */ if (line[linelen - 1 ] == '\n') { line[linelen - 1] = '\0'; } pw = pw_scan(line, pwd_scanflag); if (pw != NULL) { break; } } free(line); return pw; } #endif // Uses fgetpwent() instead of getpwnam(), to guarantee that the returned user // is a local user, and not for example from LDAP. static struct passwd *GetPwEntry(const char *puser) { FILE *fptr = safe_fopen("/etc/passwd", "r"); if (!fptr) { Log(LOG_LEVEL_ERR, "Could not open '/etc/passwd': %s", GetErrorStr()); return NULL; } struct passwd *passwd_info; bool found = false; while ((passwd_info = fgetpwent(fptr))) { if (strcmp(puser, passwd_info->pw_name) == 0) { found = true; break; } #ifdef __FreeBSD__ free(passwd_info); #endif } fclose(fptr); if (found) { return passwd_info; } else { // Failure to find the user means we just set errno to zero. // Perhaps not optimal, but we cannot pass ENOENT, because the fopen might // fail for this reason, and that should not be treated the same. errno = 0; return NULL; } } void VerifyOneUsersPromise (const char *puser, const User *u, PromiseResult *result, enum cfopaction action, EvalContext *ctx, const Attributes *a, const Promise *pp) { assert(u != NULL); struct passwd *passwd_info = GetPwEntry(puser); if (!passwd_info && errno != 0) { Log(LOG_LEVEL_ERR, "Could not get information from user database."); return; } bool res; if (u->policy == USER_STATE_PRESENT || u->policy == USER_STATE_LOCKED) { if (passwd_info != NULL) { StringSet *groups_to_set = StringSetNew(); StringSet *current_secondary_groups = StringSetNew(); StringSet *groups_missing = StringSetNew(); res = GetGroupInfo(puser, u, &groups_to_set, &groups_missing, ¤t_secondary_groups); if (res) { uint32_t cmap = 0; if (VerifyIfUserNeedsModifs (puser, u, passwd_info, &cmap, groups_to_set, current_secondary_groups)) { res = DoModifyUser (puser, u, passwd_info, cmap, action, groups_to_set); if (res) { Log(LOG_LEVEL_INFO, "Modified user '%s'", puser); *result = PROMISE_RESULT_CHANGE; } else { Log(LOG_LEVEL_ERR, "Failed to modify user '%s'", puser); *result = PROMISE_RESULT_FAIL; } } else { *result = PROMISE_RESULT_NOOP; } } else { *result = PROMISE_RESULT_FAIL; } StringSetDestroy(groups_to_set); StringSetDestroy(current_secondary_groups); StringSetDestroy(groups_missing); } else { res = DoCreateUser (puser, u, action, ctx, a, pp); if (res) { Log(LOG_LEVEL_INFO, "Created user '%s'", puser); *result = PROMISE_RESULT_CHANGE; } else { Log(LOG_LEVEL_ERR, "Failed to create user '%s'", puser); *result = PROMISE_RESULT_FAIL; } } } else if (u->policy == USER_STATE_ABSENT) { if (passwd_info != NULL) { res = DoRemoveUser (puser, action); if (res) { Log(LOG_LEVEL_INFO, "Removed user '%s'", puser); *result = PROMISE_RESULT_CHANGE; } else { Log(LOG_LEVEL_ERR, "Failed to remove user '%s'", puser); *result = PROMISE_RESULT_FAIL; } } else { *result = PROMISE_RESULT_NOOP; } } #ifdef __FreeBSD__ free(passwd_info); #endif } cfengine-3.24.2/cf-agent/files_edit.h0000644000000000000000000000443015010704253017320 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_FILES_EDIT_H #define CFENGINE_FILES_EDIT_H #include #include #ifdef HAVE_LIBXML2 #include #include #endif #define CF_EDIT_IFELAPSED 1 /* NOTE: If doing copy template then edit working copy, the edit ifelapsed must not be higher than the copy ifelapsed. This will make the working copy equal to the copied template file - not the copied + edited file. */ typedef struct { char *filename; char *changes_filename; Item *file_start; int num_edits; #ifdef HAVE_LIBXML2 xmlDocPtr xmldoc; #endif NewLineMode new_line_mode; } EditContext; // filename must not be freed until FinishEditContext. EditContext *NewEditContext(char *filename, const Attributes *a); void FinishEditContext(EvalContext *ctx, EditContext *ec, const Attributes *a, const Promise *pp, PromiseResult *result); #ifdef HAVE_LIBXML2 bool LoadFileAsXmlDoc(xmlDocPtr *doc, const char *file, EditDefaults ed, bool only_checks); bool SaveXmlDocAsFile(xmlDocPtr doc, const char *file, const Attributes *a, NewLineMode new_line_mode); #endif #endif cfengine-3.24.2/cf-agent/load_avahi.h0000644000000000000000000000525015010704253017301 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_LOAD_AVAHI_H #define CFENGINE_LOAD_AVAHI_H #include #include #include #include #include #include #include #include #include #include #include #include #include void (*avahi_simple_poll_quit_ptr)(AvahiSimplePoll *); char* (*avahi_address_snprint_ptr)(char *, size_t , const AvahiAddress *); int (*avahi_service_resolver_free_ptr)(AvahiServiceResolver *); int (*avahi_client_errno_ptr)(AvahiClient *); const char* (*avahi_strerror_ptr)(int); AvahiServiceResolver* (*avahi_service_resolver_new_ptr)(AvahiClient *, AvahiIfIndex, AvahiProtocol, const char *, const char *, const char *, AvahiProtocol, AvahiLookupFlags, AvahiServiceResolverCallback, void *); AvahiClient* (*avahi_service_browser_get_client_ptr)(AvahiServiceBrowser *); AvahiClient* (*avahi_service_resolver_get_client_ptr)(AvahiServiceResolver *); AvahiSimplePoll* (*avahi_simple_poll_new_ptr)(); const AvahiPoll* (*avahi_simple_poll_get_ptr)(AvahiSimplePoll *s); AvahiClient* (*avahi_client_new_ptr)(const AvahiPoll *, AvahiClientFlags, AvahiClientCallback, void *, int *); int (*avahi_simple_poll_loop_ptr)(AvahiSimplePoll *); int (*avahi_service_browser_free_ptr)(AvahiServiceBrowser *); void (*avahi_client_free_ptr)(AvahiClient *client); void (*avahi_simple_poll_free_ptr)(AvahiSimplePoll *); AvahiServiceBrowser* (*avahi_service_browser_new_ptr)(AvahiClient *, AvahiIfIndex, AvahiProtocol, const char *, const char *, AvahiLookupFlags, AvahiServiceBrowserCallback, void*); void *avahi_handle; int loadavahi(); #endif cfengine-3.24.2/cf-agent/comparray.c0000644000000000000000000000544415010704253017207 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /*******************************************************************/ /* */ /* Compressed Arrays */ /* */ /*******************************************************************/ #include /*******************************************************************/ bool FixCompressedArrayValue(int i, const char *value, CompressedArray **start) { CompressedArray *ap; for (ap = *start; ap != NULL; ap = ap->next) { if (ap->key == i) { /* value already fixed */ return false; } } ap = xmalloc(sizeof(CompressedArray)); ap->key = i; ap->value = xstrdup(value); ap->next = *start; *start = ap; return true; } /*******************************************************************/ void DeleteCompressedArray(CompressedArray *start) { if (start != NULL) { DeleteCompressedArray(start->next); start->next = NULL; if (start->value != NULL) { free(start->value); } free(start); } } /*******************************************************************/ bool CompressedArrayElementExists(CompressedArray *start, int key) { CompressedArray *ap; for (ap = start; ap != NULL; ap = ap->next) { if (ap->key == key) { return true; } } return false; } /*******************************************************************/ char *CompressedArrayValue(CompressedArray *start, int key) { CompressedArray *ap; for (ap = start; ap != NULL; ap = ap->next) { if (ap->key == key) { return ap->value; } } return NULL; } cfengine-3.24.2/cf-agent/cf-agent-enterprise-stubs.c0000644000000000000000000000453615010704253022213 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include ENTERPRISE_FUNC_8ARG_DEFINE_STUB(PromiseResult, LogFileChange, ARG_UNUSED EvalContext *, ctx, ARG_UNUSED const char *, file, ARG_UNUSED int, change, ARG_UNUSED const Attributes *, attr, ARG_UNUSED const Promise *, pp, ARG_UNUSED CopyRegularFileFunction, CopyRegularFilePtr, ARG_UNUSED const char *, destination, ARG_UNUSED DeleteCompressedArrayFunction, DeleteCompressedArrayPtr) { RecordNoChange(ctx, pp, attr, "Logging file differences requires version Nova or above"); return PROMISE_RESULT_NOOP; } ENTERPRISE_VOID_FUNC_1ARG_DEFINE_STUB(void, Nova_TrackExecution, ARG_UNUSED const char *, input_file) { } ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, GenerateReports, ARG_UNUSED const GenericAgentConfig *, config, ARG_UNUSED const EvalContext *, ctx) { } ENTERPRISE_VOID_FUNC_2ARG_DEFINE_STUB(void, Nova_NoteAgentExecutionPerformance, ARG_UNUSED const char *, input_file, ARG_UNUSED struct timespec, start) { } cfengine-3.24.2/cf-agent/cf_sql.h0000644000000000000000000000324115010704253016457 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_SQL_H #define CFENGINE_SQL_H #include typedef struct { int connected; bool result; int row; unsigned int maxcolumns; unsigned int maxrows; int column; char **rowdata; DatabaseType type; void *data; /* Generic pointer to RDBMS-specific data */ } CfdbConn; void CfConnectDB(CfdbConn *cfdb, DatabaseType dbtype, char *remotehost, char *dbuser, char *passwd, char *db); void CfCloseDB(CfdbConn *cfdb); void CfVoidQueryDB(CfdbConn *cfdb, char *query); void CfNewQueryDB(CfdbConn *cfdb, char *query); char **CfFetchRow(CfdbConn *cfdb); char *CfFetchColumn(CfdbConn *cfdb, int col); void CfDeleteQuery(CfdbConn *cfdb); #endif cfengine-3.24.2/cf-agent/verify_processes.h0000644000000000000000000000240615010704253020604 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_VERIFY_PROCESSES_H #define CFENGINE_VERIFY_PROCESSES_H #include PromiseResult VerifyProcessesPromise(EvalContext *ctx, const Promise *pp); bool DoAllSignals(EvalContext *ctx, Item *siglist, const Attributes *a, const Promise *pp, PromiseResult *result); #endif cfengine-3.24.2/aclocal.m40000644000000000000000000011657315010704276015235 0ustar00rootroot00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Copyright (C) 1998-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_LEX # ----------- # Autoconf leaves LEX=: if lex or flex can't be found. Change that to a # "missing" invocation, for better error output. AC_DEFUN([AM_PROG_LEX], [AC_PREREQ([2.50])dnl AC_REQUIRE([AM_MISSING_HAS_RUN])dnl AC_REQUIRE([AC_PROG_LEX])dnl if test "$LEX" = :; then LEX=${am_missing_run}flex fi]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) m4_include([m4/acinclude.m4]) m4_include([m4/adl_recursive_eval.m4]) m4_include([m4/cf3_check_proper_func.m4]) m4_include([m4/cf3_path_root_prog.m4]) m4_include([m4/cf3_with_library.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/old-autoconf.m4]) m4_include([m4/snprintf.m4]) m4_include([m4/tar.m4]) cfengine-3.24.2/libcfnet/0000755000000000000000000000000015010704322015136 5ustar00rootroot00000000000000cfengine-3.24.2/libcfnet/addr_lib.h0000644000000000000000000000276315010704253017062 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_ADDR_LIB_H #define CFENGINE_ADDR_LIB_H #include bool IsLoopbackAddress(const char *address); int FuzzySetMatch(const char *s1, const char *s2); bool FuzzyHostParse(const char *arg2); int FuzzyHostMatch(const char *arg0, const char *arg1, const char *basename); bool FuzzyMatchParse(const char *item); typedef enum { ADDRESS_TYPE_OTHER, // Hostname or invalid ADDRESS_TYPE_IPV4, ADDRESS_TYPE_IPV6 } AddressType; AddressType ParseHostPort(char *s, char **hostname, char **port); #endif cfengine-3.24.2/libcfnet/communication.c0000644000000000000000000001622215010704253020155 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include /* Stat */ #include /* xmalloc,... */ #include /* Log */ #include /* ProgrammingError */ #include /* Buffer */ #include /* IPAddress */ AgentConnection *NewAgentConn(const char *server, const char *port, ConnectionFlags flags) { AgentConnection *conn = xcalloc(1, sizeof(AgentConnection)); conn->conn_info = ConnectionInfoNew(); conn->this_server = xstrdup(server); conn->this_port = (port == NULL) ? NULL : xstrdup(port); conn->flags = flags; conn->encryption_type = 'c'; conn->authenticated = false; return conn; } void DeleteAgentConn(AgentConnection *conn) { Stat *sp = conn->cache; while (sp != NULL) { Stat *previous = sp; sp = sp->next; DestroyStatCache(previous); } ConnectionInfoDestroy(&conn->conn_info); free(conn->this_server); free(conn->this_port); free(conn->session_key); *conn = (AgentConnection) {0}; free(conn); } bool IsIPV6Address(char *name) { if (!name) { return false; } Buffer *buffer = BufferNewFrom(name, strlen(name)); if (!buffer) { return false; } IPAddress *ip_address = NULL; bool is_ip = false; is_ip = IPAddressIsIPAddress(buffer, &ip_address); if (!is_ip) { BufferDestroy(buffer); return false; } if (IPAddressType(ip_address) != IP_ADDRESS_TYPE_IPV6) { BufferDestroy(buffer); IPAddressDestroy(&ip_address); return false; } BufferDestroy(buffer); IPAddressDestroy(&ip_address); return true; } /*******************************************************************/ bool IsIPV4Address(char *name) { if (!name) { return false; } Buffer *buffer = BufferNewFrom(name, strlen(name)); if (!buffer) { return false; } IPAddress *ip_address = NULL; bool is_ip = false; is_ip = IPAddressIsIPAddress(buffer, &ip_address); if (!is_ip) { BufferDestroy(buffer); return false; } if (IPAddressType(ip_address) != IP_ADDRESS_TYPE_IPV4) { BufferDestroy(buffer); IPAddressDestroy(&ip_address); return false; } BufferDestroy(buffer); IPAddressDestroy(&ip_address); return true; } /*****************************************************************************/ /** * @brief DNS lookup of hostname, store the address as string into dst of size * dst_size. * @return -1 in case of unresolvable hostname or other error. */ int Hostname2IPString(char *dst, const char *hostname, size_t dst_size) { int ret; struct addrinfo *response = NULL, *ap; struct addrinfo query = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; if (dst_size < CF_MAX_IP_LEN) { ProgrammingError("Hostname2IPString got %zu, needs at least" " %d length buffer for IPv6 portability!", dst_size, CF_MAX_IP_LEN); } ret = getaddrinfo(hostname, NULL, &query, &response); if (ret != 0) { Log(LOG_LEVEL_INFO, "Unable to lookup hostname '%s' or cfengine service. (getaddrinfo: %s)", hostname, gai_strerror(ret)); if (response != NULL) { freeaddrinfo(response); } return -1; } for (ap = response; ap != NULL; ap = ap->ai_next) { /* No lookup, just convert numeric IP to string. */ int ret2 = getnameinfo(ap->ai_addr, ap->ai_addrlen, dst, dst_size, NULL, 0, NI_NUMERICHOST); if (ret2 == 0) { freeaddrinfo(response); return 0; /* Success */ } } assert(response != NULL); /* getaddrinfo() was successful */ freeaddrinfo(response); Log(LOG_LEVEL_ERR, "Hostname2IPString: ERROR even though getaddrinfo returned success!"); return -1; } /*****************************************************************************/ /** * @brief Reverse DNS lookup of ipaddr, store the address as string into dst * of size dst_size. * @return -1 in case of unresolvable IP address or other error. */ int IPString2Hostname(char *dst, const char *ipaddr, size_t dst_size) { int ret; struct addrinfo *response = NULL; /* First convert ipaddr string to struct sockaddr, with no DNS query. */ struct addrinfo query = { .ai_flags = AI_NUMERICHOST }; ret = getaddrinfo(ipaddr, NULL, &query, &response); if (ret != 0) { Log(LOG_LEVEL_ERR, "Unable to convert IP address '%s'. (getaddrinfo: %s)", ipaddr, gai_strerror(ret)); if (response != NULL) { freeaddrinfo(response); } return -1; } /* response should only have one reply, so no need to iterate over the * response struct addrinfo. */ /* Reverse DNS lookup. NI_NAMEREQD forces an error if not resolvable. */ ret = getnameinfo(response->ai_addr, response->ai_addrlen, dst, dst_size, NULL, 0, NI_NAMEREQD); if (ret != 0) { Log(LOG_LEVEL_INFO, "Couldn't reverse resolve '%s'. (getaddrinfo: %s)", ipaddr, gai_strerror(ret)); freeaddrinfo(response); return -1; } assert(response != NULL); /* getaddrinfo() was successful */ freeaddrinfo(response); return 0; /* Success */ } /*****************************************************************************/ unsigned short SocketFamily(int sd) { struct sockaddr_storage ss = {0}; socklen_t len = sizeof(ss); if (getsockname(sd, (struct sockaddr *) &ss, &len) == -1) { Log(LOG_LEVEL_ERR, "Could not get socket family. (getsockname: %s)", GetErrorStr()); } return ss.ss_family; } cfengine-3.24.2/libcfnet/policy_server.c0000644000000000000000000002327215010704253020200 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include //******************************************************************* // POLICY SERVER VARIABLES: //******************************************************************* static char *POLICY_SERVER = NULL; // full bootstrap argument static char *POLICY_SERVER_HOST = NULL; // only host part, if present static char POLICY_SERVER_PORT[CF_MAX_PORT_LEN]; // only port part static char POLICY_SERVER_IP[CF_MAX_IP_LEN]; // resolved IP //******************************************************************* // POLICY SERVER SET FUNCTION: //******************************************************************* static bool is_whitespace_empty(const char *str) { if(NULL_OR_EMPTY(str)) { return true; } while (str[0] != '\0') { if (!isspace(str[0])) { return false; } ++str; } return true; } /** * @brief Sets the POLICY_SERVER, POLICY_SERVER_HOST and POLICY_SERVER_PORT global variables */ void PolicyServerSet(const char *new_policy_server) { // Clean up static variables: free(POLICY_SERVER); free(POLICY_SERVER_HOST); POLICY_SERVER = NULL; POLICY_SERVER_HOST = NULL; POLICY_SERVER_IP[0] = '\0'; POLICY_SERVER_PORT[0] = '\0'; if (is_whitespace_empty(new_policy_server)) { return; } else {// Set POLICY_SERVER to be bootstrap argument/policy_server.dat contents POLICY_SERVER = xstrdup(new_policy_server); } // Parse policy server in a separate buffer: char *host_or_ip, *port; char *buffer = xstrdup(new_policy_server); AddressType address_type = ParseHostPort(buffer, &host_or_ip, &port); if (address_type == ADDRESS_TYPE_OTHER) { POLICY_SERVER_HOST = xstrdup(host_or_ip); } else // ADDRESS_TYPE_IPV4 or ADDRESS_TYPE_IPV6 { assert(strlen(host_or_ip) < sizeof(POLICY_SERVER_IP)); StringCopy(host_or_ip, POLICY_SERVER_IP, sizeof(POLICY_SERVER_IP)); } if ( ! NULL_OR_EMPTY(port) ) { if(strlen(port) < CF_MAX_PORT_LEN) { strcpy(POLICY_SERVER_PORT, port); } else { Log(LOG_LEVEL_WARNING, "Too long port number in PolicyServerSet: '%s'", port); } } free(buffer); } //******************************************************************* // POLICY SERVER GET FUNCTIONS: //******************************************************************* static char *CheckEmptyReturn(char *s) { return (NULL_OR_EMPTY(s)) ? NULL : s; } /** * @brief Used to access the internal POLICY_SERVER variable. * @return Read-only string, can be 'host:port', same as policy_server.dat * NULL if not bootstrapped ( not set ). */ const char *PolicyServerGet() { return POLICY_SERVER; // Don't use CheckedReturn, var should be NULL! } /** * @brief Gets the IP address of policy server, does lookup if necessary. * @return Read-only string, can be IPv4 or IPv6. * NULL if not bootstrapped or lookup failed. */ const char *PolicyServerGetIP() { if (POLICY_SERVER_HOST == NULL) { return CheckEmptyReturn(POLICY_SERVER_IP); } assert(POLICY_SERVER_HOST[0] != '\0'); int ret = Hostname2IPString(POLICY_SERVER_IP, POLICY_SERVER_HOST, CF_MAX_IP_LEN); if (ret != 0) // Lookup failed { return NULL; } return CheckEmptyReturn(POLICY_SERVER_IP); } /** * @brief Gets the host part of what was bootstrapped to (without port). * @return Read-only string, hostname part of bootstrap argument. * NULL if not bootstrapped or bootstrapped to IP. */ const char *PolicyServerGetHost() { return POLICY_SERVER_HOST; // Don't use CheckedReturn, var should be NULL! } /** * @brief Gets the port part of the policy server. * @return Read-only null terminated string of port number. * NULL if port not specified, or not bootstrapped at all. */ const char *PolicyServerGetPort() { return CheckEmptyReturn(POLICY_SERVER_PORT); } //******************************************************************* // POLICY SERVER FILE FUNCTIONS: //******************************************************************* static char *PolicyServerFilename(const char *workdir) { return StringFormat("%s%cpolicy_server.dat", workdir, FILE_SEPARATOR); } /** * @brief Reads the policy_server.dat file. * @param[in] workdir the directory of policy_server.dat usually GetWorkDir() * @return Trimmed contents of policy_server.dat file. Null terminated. */ char *PolicyServerReadFile(const char *workdir) { char contents[CF_MAX_SERVER_LEN] = ""; char *filename = PolicyServerFilename(workdir); FILE *fp = safe_fopen(filename, "r"); if (fp == NULL) { Log( LOG_LEVEL_VERBOSE, "Could not open file '%s' (fopen: %s)", filename, GetErrorStr() ); free(filename); return NULL; } if (fgets(contents, CF_MAX_SERVER_LEN, fp) == NULL) { Log( LOG_LEVEL_VERBOSE, "Could not read file '%s' (fgets: %s)", filename, GetErrorStr() ); free(filename); fclose(fp); return NULL; } free(filename); fclose(fp); char *start = TrimWhitespace(contents); return xstrdup(start); } /** * @brief Reads and parses the policy_server.dat file. * * @code{.c} * //Typical usage: * char *host, *port; * bool file_read = PolicyServerParseFile(GetWorkDir(), &host, &port); * printf( "host is %s", file_read ? host : "unavailable" ); * free(host); free(port); * @endcode * * @param[in] workdir The directory of policy_server.dat usually GetWorkDir() * @param[out] host pointer at this address will be hostname string (strdup) * @param[out] port pointer at this address will be port string (strdup) * @attention host* and port* must be freed. * @return Boolean indicating success. */ bool PolicyServerParseFile(const char *workdir, char **host, char **port) { char *contents = PolicyServerReadFile(workdir); if (contents == NULL) { return false; } (*host) = NULL; (*port) = NULL; ParseHostPort(contents, host, port); // The file did not contain a host if (*host == NULL) { return false; } (*host) = xstrdup(*host); if (*port != NULL) { (*port) = xstrdup(*port); } free(contents); return true; } /** * @brief Reads and parses the policy_server.dat file. * * @param[in] workdir The directory of policy_server.dat usually GetWorkDir() * @param[out] ipaddr pointer at this address will be hostname string (strdup) * @param[out] port pointer at this address will be port string (strdup) * @attention ipaddr* and port* must be freed. * @return Boolean indicating success. * @see PolicyServerParseFile */ bool PolicyServerLookUpFile(const char *workdir, char **ipaddr, char **port) { char *host; bool file_read = PolicyServerParseFile(workdir, &host, port); if (file_read == false) { return false; } char tmp_ipaddr[CF_MAX_IP_LEN]; if (Hostname2IPString(tmp_ipaddr, host, sizeof(tmp_ipaddr)) == -1) { Log(LOG_LEVEL_ERR, "Unable to resolve policy server host: %s", host); free(host); free(*port); (*port) = NULL; return false; } (*ipaddr) = xstrdup(tmp_ipaddr); free(host); return true; } /** * @brief Write new_policy_server to the policy_server.dat file. * @param[in] workdir The directory of policy_server.dat, usually GetWorkDir() * @param[in] new_policy_server The host:port string defining the server * @return True if successful */ bool PolicyServerWriteFile(const char *workdir, const char *new_policy_server) { char *filename = PolicyServerFilename(workdir); FILE *file = safe_fopen(filename, "w"); if (file == NULL) { Log(LOG_LEVEL_ERR, "Unable to write policy server file '%s' (fopen: %s)", filename, GetErrorStr()); free(filename); return false; } fprintf(file, "%s\n", new_policy_server); fclose(file); free(filename); return true; } /** * @brief Remove the policy_server.dat file * @param[in] workdir The directory of policy_server.dat, usually GetWorkDir() * @return True if successful */ bool PolicyServerRemoveFile(const char *workdir) { char *filename = PolicyServerFilename(workdir); if (unlink(filename) != 0) { Log(LOG_LEVEL_ERR, "Unable to remove file '%s'. (unlink: %s)", filename, GetErrorStr()); free(filename); return false; } free(filename); return true; } cfengine-3.24.2/libcfnet/cfnet.h0000644000000000000000000000736515010704253016424 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CFNET_H #define CFENGINE_CFNET_H #include #include /* CF_BUFSIZE, CF_SMALLBUF */ #include // ProtocolVersion /* Only set with DetermineCfenginePort() and from cf-serverd */ extern char CFENGINE_PORT_STR[16]; /* GLOBAL_P GLOBAL_E */ extern int CFENGINE_PORT; /* GLOBAL_P GLOBAL_E */ #define CF_MAX_IP_LEN 64 /* max IPv4/IPv6 address length */ #define CF_MAX_PORT_LEN 6 #define CF_MAX_HOST_LEN 256 // Since both have 1 extra for null byte, we don't need to add 1 for ':' #define CF_MAX_SERVER_LEN (CF_MAX_HOST_LEN + CF_MAX_PORT_LEN) #define CF_DONE 't' #define CF_MORE 'm' #define SOCKET_INVALID -1 #define MAXIP4CHARLEN 16 #define CF_RSA_PROTO_OFFSET 24 #define CF_PROTO_OFFSET 16 #define CF_INBAND_OFFSET 8 #define CF_MSGSIZE (CF_BUFSIZE - CF_INBAND_OFFSET) typedef struct { ProtocolVersion protocol_version : 3; bool cache_connection : 1; bool force_ipv4 : 1; bool trust_server : 1; bool off_the_record : 1; } ConnectionFlags; static inline bool ConnectionFlagsEqual(const ConnectionFlags *f1, const ConnectionFlags *f2) { if (f1->protocol_version == f2->protocol_version && f1->cache_connection == f2->cache_connection && f1->force_ipv4 == f2->force_ipv4 && f1->trust_server == f2->trust_server && f1->off_the_record == f2->off_the_record) { return true; } else { return false; } } #include "connection_info.h" /* needs ProtocolVersion */ /* * TLS support */ #define DEFAULT_TLS_TIMEOUT_SECONDS 5 #define DEFAULT_TLS_TIMEOUT_USECONDS 0 #define SET_DEFAULT_TLS_TIMEOUT(x) \ x.tv_sec = DEFAULT_TLS_TIMEOUT_SECONDS; \ x.tv_usec = DEFAULT_TLS_TIMEOUT_USECONDS #define DEFAULT_TLS_TRIES 5 struct Stat_; /* defined in stat_cache.h, typedef'ed to "Stat" */ typedef struct { ConnectionInfo *conn_info; int authenticated; char username[CF_SMALLBUF]; /* Unused for now... */ /* char localip[CF_MAX_IP_LEN]; */ char remoteip[CF_MAX_IP_LEN]; unsigned char *session_key; char encryption_type; short error; struct Stat_ *cache; /* cache for remote STATs */ /* The following consistutes the ID of a server host, mostly taken from * the copy_from connection attributes. */ ConnectionFlags flags; char *this_server; char *this_port; } AgentConnection; /* misc.c */ void EnforceBwLimit(int tosend); int cf_closesocket(int sd); /* client_protocol.c */ void SetSkipIdentify(bool enabled); /* net.c */ void SetBindInterface(const char *ip); #endif cfengine-3.24.2/libcfnet/key.h0000644000000000000000000000520115010704253016100 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef KEY_H #define KEY_H #include #include /** @brief Structure to simplify the key management. */ typedef struct Key Key; /** @brief Creates a new Key structure. @param key RSA structure @param hash Hash method to use when hashing the key. @return A fully initialized Key structure or NULL in case of error. */ Key *KeyNew(RSA *rsa, HashMethod method); /** @brief Destroys a structure of type Key. @param key Structure to be destroyed. */ void KeyDestroy(Key **key); /** @brief Constant pointer to the key data. @param key Key @return A pointer to the RSA structure. */ RSA *KeyRSA(const Key *key); /** @brief Binary hash of the key @param key Key structure @param length Length of the binary hash @return A pointer to the binary hash or NULL in case of error. */ const unsigned char *KeyBinaryHash(const Key *key, unsigned int *length); /** @brief Printable hash of the key. @param key @return A pointer to the printable hash of the key. */ const char *KeyPrintableHash(const Key *key); /** @brief Method use to hash the key. @param key Structure @return Method used to hash the key. */ HashMethod KeyHashMethod(const Key *key); /** @brief Changes the method used to hash the key. This method triggers a rehashing of the key. This can be an expensive operation. @param key Structure @param hash New hashing mechanism. @return 0 if successful, -1 in case of error. */ int KeySetHashMethod(Key *key, HashMethod method); /** @brief Internal Hash data @param key Structure @return A pointer to the Hash structure or NULL in case of error. */ const Hash *KeyData(Key *key); #endif // KEY_H cfengine-3.24.2/libcfnet/stat_cache.c0000644000000000000000000003010215010704253017377 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* AgentConnection */ #include /* {Send,Receive}Transaction */ #include /* BadProtoReply,OKProtoReply */ #include /* xmemdup */ #include /* Log */ #include /* EncryptString */ #include /* ProgrammingError */ static void NewStatCache(Stat *data, AgentConnection *conn) { Stat *sp = xmemdup(data, sizeof(Stat)); sp->next = conn->cache; conn->cache = sp; } void DestroyStatCache(Stat *data) { if (data != NULL) { free(data->cf_readlink); free(data->cf_filename); free(data->cf_server); free(data); } } /** * @brief Find remote stat information for #file in cache and * return it in #statbuf. * @return 0 if found, 1 if not found, -1 in case of error. */ static int StatFromCache(AgentConnection *conn, const char *file, struct stat *statbuf, const char *stattype) { for (Stat *sp = conn->cache; sp != NULL; sp = sp->next) { /* TODO differentiate ports etc in this stat cache! */ if (strcmp(conn->this_server, sp->cf_server) == 0 && strcmp(file, sp->cf_filename) == 0) { if (sp->cf_failed) /* cached failure from cfopendir */ { errno = EPERM; return -1; } if ((strcmp(stattype, "link") == 0) && (sp->cf_lmode != 0)) { statbuf->st_mode = sp->cf_lmode; } else { statbuf->st_mode = sp->cf_mode; } statbuf->st_uid = sp->cf_uid; statbuf->st_gid = sp->cf_gid; statbuf->st_size = sp->cf_size; statbuf->st_atime = sp->cf_atime; statbuf->st_mtime = sp->cf_mtime; statbuf->st_ctime = sp->cf_ctime; statbuf->st_ino = sp->cf_ino; statbuf->st_dev = sp->cf_dev; statbuf->st_nlink = sp->cf_nlink; return 0; } } return 1; /* not found */ } /** * @param #stattype should be either "link" or "file". If a link, this reads * readlink and sends it back in the same packet. It then * caches the value for each copy command. * */ int cf_remote_stat(AgentConnection *conn, bool encrypt, const char *file, struct stat *statbuf, const char *stattype) { assert(conn != NULL); assert(file != NULL); assert(statbuf != NULL); assert(strcmp(stattype, "file") == 0 || strcmp(stattype, "link") == 0); /* We encrypt only for CLASSIC protocol. The TLS protocol is always over * encrypted layer, so it does not support encrypted (S*) commands. */ encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC; if (strlen(file) > CF_BUFSIZE - 30) { Log(LOG_LEVEL_ERR, "Filename too long"); return -1; } int ret = StatFromCache(conn, file, statbuf, stattype); if (ret == 0 || ret == -1) /* found or error */ { return ret; } /* Not found in cache */ char recvbuffer[CF_BUFSIZE]; memset(recvbuffer, 0, CF_BUFSIZE); time_t tloc = time(NULL); if (tloc == (time_t) -1) { Log(LOG_LEVEL_ERR, "Couldn't read system clock (time: %s)", GetErrorStr()); tloc = 0; } char sendbuffer[CF_BUFSIZE]; int tosend; sendbuffer[0] = '\0'; if (encrypt) { if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "Cannot do encrypted copy without keys (use cf-key)"); return -1; } char in[CF_BUFSIZE], out[CF_BUFSIZE]; snprintf(in, CF_BUFSIZE - 1, "SYNCH %jd STAT %s", (intmax_t) tloc, file); int cipherlen = EncryptString(out, sizeof(out), in, strlen(in) + 1, conn->encryption_type, conn->session_key); tosend = cipherlen + CF_PROTO_OFFSET; if (tosend < 0) { ProgrammingError("cf_remote_stat: tosend (%d) < 0", tosend); } else if((unsigned int) tosend > sizeof(sendbuffer)) { ProgrammingError("cf_remote_stat: tosend (%d) > sendbuffer (%zd)", tosend, sizeof(sendbuffer)); } snprintf(sendbuffer, CF_BUFSIZE - 1, "SSYNCH %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); } else { snprintf(sendbuffer, CF_BUFSIZE, "SYNCH %jd STAT %s", (intmax_t) tloc, file); tosend = strlen(sendbuffer); } if (SendTransaction(conn->conn_info, sendbuffer, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_INFO, "Transmission failed/refused talking to %.255s:%.255s. (stat: %s)", conn->this_server, file, GetErrorStr()); return -1; } if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { /* TODO mark connection in the cache as closed. */ return -1; } if (strstr(recvbuffer, "unsynchronized")) { Log(LOG_LEVEL_ERR, "Clocks differ too much to do copy by date (security), server reported: %s", recvbuffer + strlen("BAD: ")); return -1; } if (BadProtoReply(recvbuffer)) { Log(LOG_LEVEL_VERBOSE, "Server returned error: %s", recvbuffer + strlen("BAD: ")); errno = EPERM; return -1; } if (!OKProtoReply(recvbuffer)) { Log(LOG_LEVEL_ERR, "Transmission refused or failed statting '%s', got '%s'", file, recvbuffer); errno = EPERM; return -1; } Stat cfst; ret = StatParseResponse(recvbuffer, &cfst); if (!ret) { Log(LOG_LEVEL_ERR, "Cannot read STAT reply from '%s'", conn->this_server); return -1; } // If remote path is symbolic link, receive actual path here int recv_len = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); if (recv_len == -1) { /* TODO mark connection in the cache as closed. */ return -1; } int ok_len = sizeof("OK:"); /* Received a link destination from server (recv_len greater than OK response + NUL-byte) */ if (recv_len > ok_len) { // Read from after "OK:" cfst.cf_readlink = xstrdup(recvbuffer + (ok_len - 1)); } else { cfst.cf_readlink = NULL; } mode_t file_type = FileTypeToMode(cfst.cf_type); if (file_type == 0) { Log(LOG_LEVEL_ERR, "Invalid file type identifier for file %s:%s, %u", conn->this_server, file, cfst.cf_type); return -1; } cfst.cf_mode |= file_type; cfst.cf_filename = xstrdup(file); cfst.cf_server = xstrdup(conn->this_server); cfst.cf_failed = false; if (cfst.cf_lmode != 0) { cfst.cf_lmode |= (mode_t) S_IFLNK; } NewStatCache(&cfst, conn); if ((cfst.cf_lmode != 0) && (strcmp(stattype, "link") == 0)) { statbuf->st_mode = cfst.cf_lmode; } else { statbuf->st_mode = cfst.cf_mode; } statbuf->st_uid = cfst.cf_uid; statbuf->st_gid = cfst.cf_gid; statbuf->st_size = cfst.cf_size; statbuf->st_mtime = cfst.cf_mtime; statbuf->st_ctime = cfst.cf_ctime; statbuf->st_atime = cfst.cf_atime; statbuf->st_ino = cfst.cf_ino; statbuf->st_dev = cfst.cf_dev; statbuf->st_nlink = cfst.cf_nlink; return 0; } /*********************************************************************/ /* TODO only a server_name is not enough for stat'ing of files... */ const Stat *StatCacheLookup(const AgentConnection *conn, const char *file_name, const char *server_name) { for (const Stat *sp = conn->cache; sp != NULL; sp = sp->next) { if (strcmp(server_name, sp->cf_server) == 0 && strcmp(file_name, sp->cf_filename) == 0) { return sp; } } return NULL; } /*********************************************************************/ mode_t FileTypeToMode(const FileType type) { /* TODO Match the order of the actual stat struct for easier mode */ int mode = 0; switch (type) { case FILE_TYPE_REGULAR: mode |= (mode_t) S_IFREG; break; case FILE_TYPE_DIR: mode |= (mode_t) S_IFDIR; break; case FILE_TYPE_CHAR_: mode |= (mode_t) S_IFCHR; break; case FILE_TYPE_FIFO: mode |= (mode_t) S_IFIFO; break; case FILE_TYPE_SOCK: mode |= (mode_t) S_IFSOCK; break; case FILE_TYPE_BLOCK: mode |= (mode_t) S_IFBLK; break; case FILE_TYPE_LINK: mode |= (mode_t) S_IFLNK; break; } // mode is 0 if no file types matched return mode; } /*********************************************************************/ bool StatParseResponse(const char *const buf, Stat *const statbuf) { assert(buf != NULL); assert(statbuf != NULL); // use intmax_t here to provide enough space for large values coming over the protocol intmax_t d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12 = 0, d13 = 0; int res = sscanf(buf, "OK:" " %1" PRIdMAX // 01 statbuf->cf_type " %5" PRIdMAX // 02 statbuf->cf_mode " %14" PRIdMAX // 03 statbuf->cf_lmode " %14" PRIdMAX // 04 statbuf->cf_uid " %14" PRIdMAX // 05 statbuf->cf_gid " %18" PRIdMAX // 06 statbuf->cf_size " %14" PRIdMAX // 07 statbuf->cf_atime " %14" PRIdMAX // 08 statbuf->cf_mtime " %14" PRIdMAX // 09 statbuf->cf_ctime " %1" PRIdMAX // 10 statbuf->cf_makeholes " %14" PRIdMAX // 11 statbuf->cf_ino " %14" PRIdMAX // 12 statbuf->cf_nlink " %18" PRIdMAX, // 13 statbuf->cf_dev &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13); if (res < 13) { if (res >= 0) { Log(LOG_LEVEL_VERBOSE, "STAT response parsing failed, only %d/13 elements parsed", res); } return false; } statbuf->cf_type = (FileType) d1; statbuf->cf_mode = (mode_t) d2; statbuf->cf_lmode = (mode_t) d3; statbuf->cf_uid = (uid_t) d4; statbuf->cf_gid = (gid_t) d5; statbuf->cf_size = (off_t) d6; statbuf->cf_atime = (time_t) d7; statbuf->cf_mtime = (time_t) d8; statbuf->cf_ctime = (time_t) d9; statbuf->cf_makeholes = (char) d10; statbuf->cf_ino = d11; statbuf->cf_nlink = d12; statbuf->cf_dev = (dev_t)d13; return true; } cfengine-3.24.2/libcfnet/connection_info.c0000644000000000000000000000712315010704253020462 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include ConnectionInfo *ConnectionInfoNew(void) { struct ConnectionInfo *info = xcalloc(1, sizeof(struct ConnectionInfo)); info->sd = SOCKET_INVALID; return info; } void ConnectionInfoDestroy(ConnectionInfo **info) { if (!info || !*info) { return; } /* Destroy everything */ if ((*info)->ssl) { SSL_free((*info)->ssl); } KeyDestroy(&(*info)->remote_key); free(*info); *info = NULL; } ProtocolVersion ConnectionInfoProtocolVersion(const ConnectionInfo *info) { assert(info != NULL); return info ? info->protocol : CF_PROTOCOL_UNDEFINED; } void ConnectionInfoSetProtocolVersion(ConnectionInfo *info, ProtocolVersion version) { assert(info != NULL); if (info == NULL) { return; } switch (version) { case CF_PROTOCOL_UNDEFINED: case CF_PROTOCOL_CLASSIC: case CF_PROTOCOL_TLS: info->protocol = version; break; default: break; } } int ConnectionInfoSocket(const ConnectionInfo *info) { assert(info != NULL); return info ? info->sd : -1; } void ConnectionInfoSetSocket(ConnectionInfo *info, int s) { assert(info != NULL); if (info == NULL) { return; } info->sd = s; } SSL *ConnectionInfoSSL(const ConnectionInfo *info) { assert(info != NULL); return info ? info->ssl : NULL; } void ConnectionInfoSetSSL(ConnectionInfo *info, SSL *ssl) { assert(info != NULL); if (info == NULL) { return; } info->ssl = ssl; } const Key *ConnectionInfoKey(const ConnectionInfo *info) { assert(info != NULL); const Key *key = info ? info->remote_key : NULL; return key; } void ConnectionInfoSetKey(ConnectionInfo *info, Key *key) { assert(info != NULL); if (info == NULL) { return; } /* The key can be assigned only once on a session */ if (info->remote_key) { return; } if (!key) { return; } info->remote_key = key; } const unsigned char *ConnectionInfoBinaryKeyHash(ConnectionInfo *info, unsigned int *length) { assert(info != NULL); if (info == NULL) { return NULL; } Key *connection_key = info->remote_key; unsigned int real_length = 0; const unsigned char *binary = KeyBinaryHash(connection_key, &real_length); if (length) { *length = real_length; } return binary; } const char *ConnectionInfoPrintableKeyHash(ConnectionInfo *info) { assert(info != NULL); return info ? KeyPrintableHash(info->remote_key) : NULL; } cfengine-3.24.2/libcfnet/Makefile.am0000644000000000000000000000324615010704253017202 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcfnet.la AM_CPPFLAGS = -I$(top_srcdir)/libntech/libutils \ -I$(top_srcdir)/libpromises \ $(PCRE2_CPPFLAGS) \ $(SYSTEMD_SOCKET_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) libcfnet_la_SOURCES = \ addr_lib.c addr_lib.h \ client_protocol.c client_protocol.h cfnet.h\ client_code.c client_code.h \ classic.c classic.h \ communication.c communication.h \ connection_info.c connection_info.h \ conn_cache.c conn_cache.h \ key.c key.h \ misc.c \ net.c net.h \ policy_server.c policy_server.h \ protocol.c protocol.h \ protocol_version.c protocol_version.h \ server_code.c server_code.h \ stat_cache.c stat_cache.h \ tls_client.c tls_client.h \ tls_generic.c tls_generic.h cfengine-3.24.2/libcfnet/tls_generic.h0000644000000000000000000000351615010704253017615 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_TLS_GENERIC_H #define CFENGINE_TLS_GENERIC_H #include #include #include /* LogLevel */ extern int CONNECTIONINFO_SSL_IDX; bool TLSGenericInitialize(void); int TLSVerifyCallback(X509_STORE_CTX *ctx, void *arg); int TLSVerifyPeer(ConnectionInfo *conn_info, const char *remoteip, const char *username); X509 *TLSGenerateCertFromPrivKey(RSA *privkey); int TLSLogError(SSL *ssl, LogLevel level, const char *prepend, int code); int TLSSend(SSL *ssl, const char *buffer, int length); int TLSRecv(SSL *ssl, char *buffer, int toget); int TLSRecvLines(SSL *ssl, char *buf, size_t buf_size); void TLSSetDefaultOptions(SSL_CTX *ssl_ctx, const char *min_version); const char *TLSErrorString(intmax_t errcode); bool TLSSetCipherList(SSL_CTX *ssl_ctx, const char *cipher_list); #endif cfengine-3.24.2/libcfnet/protocol_version.h0000644000000000000000000000700715010704253020724 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROTOCOL_VERSION_H #define CFENGINE_PROTOCOL_VERSION_H /** Available protocol versions. When connection is initialised ProtocolVersion is 0, i.e. undefined. It is after the call to ServerConnection() that protocol version is decided, according to body copy_from and body common control. All protocol numbers are numbered incrementally starting from 1. */ typedef enum { CF_PROTOCOL_UNDEFINED = 0, CF_PROTOCOL_CLASSIC = 1, /* --- Greater versions use TLS as secure communications layer --- */ CF_PROTOCOL_TLS = 2, CF_PROTOCOL_COOKIE = 3, } ProtocolVersion; /* We use CF_PROTOCOL_LATEST as the default for new connections. */ #define CF_PROTOCOL_LATEST CF_PROTOCOL_COOKIE static inline const char *ProtocolVersionString(const ProtocolVersion p) { switch (p) { case CF_PROTOCOL_COOKIE: return "cookie"; case CF_PROTOCOL_TLS: return "tls"; case CF_PROTOCOL_CLASSIC: return "classic"; default: return "undefined"; } } static inline bool ProtocolIsKnown(const ProtocolVersion p) { return ((p > CF_PROTOCOL_UNDEFINED) && (p <= CF_PROTOCOL_LATEST)); } static inline bool ProtocolIsTLS(const ProtocolVersion p) { return ((p >= CF_PROTOCOL_TLS) && (p <= CF_PROTOCOL_LATEST)); } static inline bool ProtocolIsTooNew(const ProtocolVersion p) { return (p > CF_PROTOCOL_LATEST); } static inline bool ProtocolIsUndefined(const ProtocolVersion p) { return (p <= CF_PROTOCOL_UNDEFINED); } static inline bool ProtocolIsClassic(const ProtocolVersion p) { return (p == CF_PROTOCOL_CLASSIC); } static inline bool ProtocolTerminateCSV(const ProtocolVersion p) { return (p < CF_PROTOCOL_COOKIE); } /** * Returns CF_PROTOCOL_TLS or CF_PROTOCOL_CLASSIC (or CF_PROTOCOL_UNDEFINED) * Maps all versions using TLS to CF_PROTOCOL_TLS for convenience * in switch statements. */ static inline ProtocolVersion ProtocolClassicOrTLS(const ProtocolVersion p) { if (ProtocolIsTLS(p)) { return CF_PROTOCOL_TLS; } if (ProtocolIsClassic(p)) { return CF_PROTOCOL_CLASSIC; } return CF_PROTOCOL_UNDEFINED; } /** * Parses the version string sent over network to enum, e.g. "CFE_v1" -> 1 */ ProtocolVersion ParseProtocolVersionNetwork(const char *s); /** * Parses the version string set in policy to enum, e.g. "classic" -> 1 */ ProtocolVersion ParseProtocolVersionPolicy(const char *s); // Old name for compatibility (enterprise), TODO remove: #define ProtocolVersionParse ParseProtocolVersionPolicy #endif // CFENGINE_PROTOCOL_VERSION_H cfengine-3.24.2/libcfnet/client_protocol.h0000644000000000000000000000244515010704253020516 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CLIENT_PROTOCOL_H #define CFENGINE_CLIENT_PROTOCOL_H #include bool IdentifyAgent(ConnectionInfo *connection); bool AuthenticateAgent(AgentConnection *conn, bool trust_key); bool BadProtoReply(const char *buf); bool OKProtoReply(const char *buf); bool FailedProtoReply(const char *buf); #endif cfengine-3.24.2/libcfnet/communication.h0000644000000000000000000000322615010704253020162 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_COMMUNICATION_H #define CFENGINE_COMMUNICATION_H #include /** @brief Allocates a new AgentConnection (stores a connection from Agent to Server). */ AgentConnection *NewAgentConn(const char *server, const char *port, ConnectionFlags flags); /** @brief Destroys an AgentConnection. @param ap AgentConnection structure. */ void DeleteAgentConn(AgentConnection *ap); bool IsIPV6Address(char *name); bool IsIPV4Address(char *name); int Hostname2IPString(char *dst, const char *hostname, size_t dst_size); int IPString2Hostname(char *dst, const char *ipaddr, size_t dst_size); unsigned short SocketFamily(int sd); #endif cfengine-3.24.2/libcfnet/tls_generic.c0000644000000000000000000010432215010704253017605 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include // CF_DEFAULT_DIGEST #include #include #include #include #include /* LogLevel */ #include #include /* TODO move crypto.h to libutils */ #include /* HavePublicKeyByIP */ #include /* HashPubKey */ #include /* known TLS versions */ enum tls_version { TLS_1_0 = 0, TLS_1_1 = 1, TLS_1_2 = 2, TLS_1_3 = 3, }; #define TLS_LAST TLS_1_3 /* determine the highest TLS version supported by the available/used version of * OpenSSL */ #if defined(SSL_OP_NO_TLSv1_3) #define TLS_HIGHEST_SUPPORTED TLS_1_3 #elif defined(SSL_OP_NO_TLSv1_2) #define TLS_HIGHEST_SUPPORTED TLS_1_2 #elif defined(SSL_OP_NO_TLSv1_1) #define TLS_HIGHEST_SUPPORTED TLS_1_1 #else #define TLS_HIGHEST_SUPPORTED TLS_1_0 #endif /* the lowest version of TLS we always require */ #define TLS_LOWEST_REQUIRED TLS_1_0 /* the lowest version of TLS we recommend (also the default) */ #define TLS_LOWEST_RECOMMENDED TLS_1_1 #ifndef SSL_OP_NO_TLSv1_3 #define SSL_OP_NO_TLSv1_3 0 /* no-op when ORed with bit flags */ #endif #ifndef SSL_OP_NO_TLSv1_2 #define SSL_OP_NO_TLSv1_2 0 #endif #ifndef SSL_OP_NO_TLSv1_1 #define SSL_OP_NO_TLSv1_1 0 #endif static const char *const tls_version_strings[TLS_LAST + 1] = {"1.0", "1.1", "1.2", "1.3"}; static unsigned int tls_disable_flags[TLS_LAST + 1] = {SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_3}; int CONNECTIONINFO_SSL_IDX = -1; #define MAX_READ_RETRIES 5 #define MAX_WRITE_RETRIES 5 const char *TLSErrorString(intmax_t errcode) { const char *errmsg = ERR_reason_error_string((unsigned long) errcode); return (errmsg != NULL) ? errmsg : "no error message"; } bool TLSGenericInitialize() { static bool is_initialised = false; /* We must make sure that SSL_get_ex_new_index() is called only once! */ if (is_initialised) { return true; } /* OpenSSL is needed for TLS. */ SSL_library_init(); SSL_load_error_strings(); /* Register a unique place to store ConnectionInfo within SSL struct. */ CONNECTIONINFO_SSL_IDX = SSL_get_ex_new_index(0, "Pointer to ConnectionInfo", NULL, NULL, NULL); is_initialised = true; return true; } /** * @retval 1 equal * @retval 0 not equal * @retval -1 error */ static int CompareCertToRSA(X509 *cert, RSA *rsa_key) { int ret; int retval = -1; /* ERROR */ EVP_PKEY *cert_pkey = X509_get_pubkey(cert); if (cert_pkey == NULL) { Log(LOG_LEVEL_ERR, "X509_get_pubkey: %s", TLSErrorString(ERR_get_error())); goto ret1; } if (EVP_PKEY_base_id(cert_pkey) != EVP_PKEY_RSA) { Log(LOG_LEVEL_ERR, "Received key of unknown type, only RSA currently supported!"); goto ret2; } RSA *cert_rsa_key = EVP_PKEY_get1_RSA(cert_pkey); if (cert_rsa_key == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_get1_RSA failed!"); goto ret2; } EVP_PKEY *rsa_pkey = EVP_PKEY_new(); if (rsa_pkey == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_new allocation failed!"); goto ret3; } ret = EVP_PKEY_set1_RSA(rsa_pkey, rsa_key); if (ret == 0) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_set1_RSA failed!"); goto ret4; } ret = EVP_PKEY_cmp(cert_pkey, rsa_pkey); if (ret == 1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare equal"); retval = 1; /* EQUAL */ } else if (ret == 0 || ret == -1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare different"); retval = 0; /* NOT EQUAL */ } else { Log(LOG_LEVEL_ERR, "OpenSSL EVP_PKEY_cmp: %d %s", ret, TLSErrorString(ERR_get_error())); } ret4: EVP_PKEY_free(rsa_pkey); ret3: RSA_free(cert_rsa_key); ret2: EVP_PKEY_free(cert_pkey); ret1: return retval; } /** * The only thing we make sure here is that any key change is not allowed. All * the rest of authentication happens separately *after* the initial * handshake, thus *after* this callback has returned successfully and TLS * session has been established. * @return 0 on error, 1 on success * @note This is an SSL callback, return type has to be int, not bool */ int TLSVerifyCallback(X509_STORE_CTX *store_ctx, void *arg ARG_UNUSED) { /* It's kind of tricky to get custom connection-specific info in this * callback. We first acquire a pointer to the SSL struct of the * connection and... */ int ssl_idx = SSL_get_ex_data_X509_STORE_CTX_idx(); SSL *ssl = X509_STORE_CTX_get_ex_data(store_ctx, ssl_idx); if (ssl == NULL) { UnexpectedError("No SSL context during handshake, denying!"); return 0; } /* ...and then we ask for the custom data we attached there. */ ConnectionInfo *conn_info = SSL_get_ex_data(ssl, CONNECTIONINFO_SSL_IDX); if (conn_info == NULL) { UnexpectedError("No conn_info at index %d", CONNECTIONINFO_SSL_IDX); return 0; } /* From that data get the key if the connection is already established. */ RSA *already_negotiated_key = KeyRSA(conn_info->remote_key); /* Is there an already negotiated certificate? */ X509 *previous_tls_cert = SSL_get_peer_certificate(ssl); if (previous_tls_cert == NULL) { Log(LOG_LEVEL_DEBUG, "TLSVerifyCallback: no ssl->peer_cert"); if (already_negotiated_key == NULL) { Log(LOG_LEVEL_DEBUG, "TLSVerifyCallback: no conn_info->key"); Log(LOG_LEVEL_DEBUG, "This must be the initial TLS handshake, accepting"); return 1; /* ACCEPT HANDSHAKE */ } else { UnexpectedError("Initial handshake, but old keys differ, denying!"); return 0; } } else /* TLS renegotiation handshake */ { if (already_negotiated_key == NULL) { Log(LOG_LEVEL_DEBUG, "TLSVerifyCallback: no conn_info->key"); Log(LOG_LEVEL_ERR, "Renegotiation handshake before trust was established, denying!"); X509_free(previous_tls_cert); return 0; /* fishy */ } else { /* previous_tls_cert key should match already_negotiated_key. */ if (CompareCertToRSA(previous_tls_cert, already_negotiated_key) != 1) { UnexpectedError("Renegotiation caused keys to differ, denying!"); X509_free(previous_tls_cert); return 0; } else { /* THIS IS THE ONLY WAY TO CONTINUE */ } } } assert(previous_tls_cert != NULL); assert(already_negotiated_key != NULL); /* At this point we have ensured that previous_tls_cert->key is equal * to already_negotiated_key, so we might as well forget the former. */ X509_free(previous_tls_cert); /* We want to compare already_negotiated_key to the one the peer * negotiates in this TLS renegotiation. So, extract first certificate out * of the chain the peer sent. It should be the only one since we do not * support certificate chains, we just want the RSA key. */ STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(store_ctx); if (chain == NULL) { Log(LOG_LEVEL_ERR, "No certificate chain inside TLS handshake, denying!"); return 0; } int chain_len = sk_X509_num(chain); if (chain_len != 1) { Log(LOG_LEVEL_ERR, "More than one certificate presented in TLS handshake, refusing handshake!"); return 0; } X509 *new_cert = sk_X509_value(chain, 0); if (new_cert == NULL) { UnexpectedError("NULL certificate at the beginning of chain!"); return 0; } if (CompareCertToRSA(new_cert, already_negotiated_key) != 1) { Log(LOG_LEVEL_ERR, "Peer attempted to change key during TLS renegotiation, denying!"); return 0; } Log(LOG_LEVEL_DEBUG, "TLS renegotiation occurred but keys are still the same, accepting"); return 1; /* ACCEPT HANDSHAKE */ } /** * @retval 1 if the public key used by the peer in the TLS handshake is the * same with the one stored for that host. * @retval 0 if stored key for the host is missing or differs from the one * received. * @retval -1 in case of other error (error will be Log()ed). * @note When return value is != -1 (so no error occurred) the #conn_info struct * should have been populated, with key received and its hash. */ int TLSVerifyPeer(ConnectionInfo *conn_info, const char *remoteip, const char *username) { int ret, retval; X509 *received_cert = SSL_get_peer_certificate(conn_info->ssl); if (received_cert == NULL) { Log(LOG_LEVEL_ERR, "No certificate presented by remote peer (openssl: %s)", TLSErrorString(ERR_get_error())); retval = -1; goto ret1; } EVP_PKEY *received_pubkey = X509_get_pubkey(received_cert); if (received_pubkey == NULL) { Log(LOG_LEVEL_ERR, "X509_get_pubkey: %s", TLSErrorString(ERR_get_error())); retval = -1; goto ret2; } if (EVP_PKEY_base_id(received_pubkey) != EVP_PKEY_RSA) { Log(LOG_LEVEL_ERR, "Received key of unknown type, only RSA currently supported!"); retval = -1; goto ret3; } RSA *remote_key = EVP_PKEY_get1_RSA(received_pubkey); if (remote_key == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_get1_RSA failed!"); retval = -1; goto ret3; } Key *key = KeyNew(remote_key, CF_DEFAULT_DIGEST); conn_info->remote_key = key; /* * Compare the key received with the one stored. */ const char *key_hash = KeyPrintableHash(key); RSA *expected_rsa_key = HavePublicKey(username, remoteip, key_hash); if (expected_rsa_key == NULL) { /* TODO LOG_LEVEL_NOTICE once cf-serverd logs to a different file. */ Log(LOG_LEVEL_VERBOSE, "Received key '%s' not found in ppkeys", key_hash); retval = 0; goto ret4; } EVP_PKEY *expected_pubkey = EVP_PKEY_new(); if (expected_pubkey == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_new allocation failed!"); retval = -1; goto ret5; } ret = EVP_PKEY_set1_RSA(expected_pubkey, expected_rsa_key); if (ret == 0) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_set1_RSA failed!"); retval = -1; goto ret6; } ret = EVP_PKEY_cmp(received_pubkey, expected_pubkey); if (ret == 1) { Log(LOG_LEVEL_VERBOSE, "Received public key compares equal to the one we have stored"); retval = 1; /* TRUSTED KEY, equal to the expected one */ goto ret6; } else if (ret == 0 || ret == -1) { Log(LOG_LEVEL_NOTICE, "Received key '%s' compares different to the one in ppkeys", key_hash); retval = 0; goto ret6; } else { Log(LOG_LEVEL_ERR, "OpenSSL EVP_PKEY_cmp: %d %s", ret, TLSErrorString(ERR_get_error())); retval = -1; goto ret6; } UnexpectedError("Unreachable!"); return 0; ret6: EVP_PKEY_free(expected_pubkey); ret5: RSA_free(expected_rsa_key); ret4: if (retval == -1) { /* We won't be needing conn_info->remote_key */ KeyDestroy(&key); conn_info->remote_key = NULL; } ret3: EVP_PKEY_free(received_pubkey); ret2: X509_free(received_cert); ret1: return retval; } /** * @brief Generate and return a dummy in-memory X509 certificate signed with * the private key passed. It is valid from now to 50 years later... */ X509 *TLSGenerateCertFromPrivKey(RSA *privkey) { int ret; X509 *x509 = X509_new(); if (x509 == NULL) { Log(LOG_LEVEL_ERR, "X509_new: %s", TLSErrorString(ERR_get_error())); goto err1; } ASN1_TIME *t1 = X509_gmtime_adj(X509_get_notBefore(x509), 0); ASN1_TIME *t2 = X509_gmtime_adj(X509_get_notAfter(x509), 60*60*24*365*10); if (t1 == NULL || t2 == NULL) { Log(LOG_LEVEL_ERR, "X509_gmtime_adj: %s", TLSErrorString(ERR_get_error())); goto err2; } EVP_PKEY *pkey = EVP_PKEY_new(); if (pkey == NULL) { Log(LOG_LEVEL_ERR, "EVP_PKEY_new: %s", TLSErrorString(ERR_get_error())); goto err2; } ret = EVP_PKEY_set1_RSA(pkey, privkey); if (ret != 1) { Log(LOG_LEVEL_ERR, "EVP_PKEY_set1_RSA: %s", TLSErrorString(ERR_get_error())); goto err3; } X509_NAME *name = X509_get_subject_name(x509); if (name == NULL) { Log(LOG_LEVEL_ERR, "X509_get_subject_name: %s", TLSErrorString(ERR_get_error())); goto err3; } ret = 0; ret += X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const unsigned char *) "a", -1, -1, 0); ret += X509_set_issuer_name(x509, name); ret += X509_set_pubkey(x509, pkey); if (ret < 3) { Log(LOG_LEVEL_ERR, "Failed to set certificate details: %s", TLSErrorString(ERR_get_error())); goto err3; } const EVP_MD *md = EVP_get_digestbyname("sha384"); if (md == NULL) { Log(LOG_LEVEL_ERR, "OpenSSL: Unknown digest algorithm %s", "sha384"); goto err3; } if (getenv("CFENGINE_TEST_PURIFY_OPENSSL") != NULL) { RSA_blinding_off(privkey); } /* Not really needed since the other side does not verify the signature. */ ret = X509_sign(x509, pkey, md); /* X509_sign obscurely returns the length of the signature... */ if (ret == 0) { Log(LOG_LEVEL_ERR, "X509_sign: %s", TLSErrorString(ERR_get_error())); goto err3; } EVP_PKEY_free(pkey); assert(x509 != NULL); return x509; err3: EVP_PKEY_free(pkey); err2: X509_free(x509); err1: return NULL; } static const char *TLSPrimarySSLError(int code) { switch (code) { case SSL_ERROR_NONE: return "TLSGetSSLErrorString: No SSL error!"; case SSL_ERROR_ZERO_RETURN: return "TLS session has been terminated (SSL_ERROR_ZERO_RETURN)"; case SSL_ERROR_WANT_READ: return "SSL_ERROR_WANT_READ"; case SSL_ERROR_WANT_WRITE: return "SSL_ERROR_WANT_WRITE"; case SSL_ERROR_WANT_CONNECT: return "SSL_ERROR_WANT_CONNECT"; case SSL_ERROR_WANT_ACCEPT: return "SSL_ERROR_WANT_ACCEPT"; case SSL_ERROR_WANT_X509_LOOKUP: return "SSL_ERROR_WANT_X509_LOOKUP"; case SSL_ERROR_SYSCALL: return "SSL_ERROR_SYSCALL"; case SSL_ERROR_SSL: return "SSL_ERROR_SSL"; } return "Unknown OpenSSL error code!"; } /** * @brief OpenSSL is missing an SSL_reason_error_string() like * ERR_reason_error_string(). Provide missing functionality here, * since it's kind of complicated. * @param #prepend String to prepend to the SSL error. * @param #code Return code from the OpenSSL function call. * @warning Use only for SSL_connect(), SSL_accept(), SSL_do_handshake(), * SSL_read(), SSL_peek(), SSL_write(), see SSL_get_error man page. */ int TLSLogError(SSL *ssl, LogLevel level, const char *prepend, int retcode) { assert(prepend != NULL); /* For when retcode==SSL_ERROR_SYSCALL. */ const char *syserr = (errno != 0) ? GetErrorStr() : ""; int errcode = SSL_get_error(ssl, retcode); const char *errstr1 = TLSPrimarySSLError(errcode); /* For SSL_ERROR_SSL, SSL_ERROR_SYSCALL (man SSL_get_error). It's not * useful for SSL_read() and SSL_write(). */ const char *errstr2 = ERR_reason_error_string(ERR_get_error()); /* We know the socket is always blocking. However our blocking sockets * have a timeout set via means of setsockopt(SO_RCVTIMEO), so internally * OpenSSL can still get the EWOULDBLOCK error code from recv(). In that * case OpenSSL gives us SSL_ERROR_WANT_READ despite the socket being * blocking. So we log a proper error message! */ if (errcode == SSL_ERROR_WANT_READ) { Log(level, "%s: receive timeout", prepend); } else if (errcode == SSL_ERROR_WANT_WRITE) { Log(level, "%s: send timeout", prepend); } /* if we got SSL_ERROR_SYSCALL and ERR_get_error() returned 0 then take * ret into account (man SSL_get_error). */ else if (errcode == SSL_ERROR_SYSCALL && errstr2 == NULL && (retcode == 0 || retcode == -1)) { /* This is not described in SSL_get_error manual, but play it safe. */ if ((SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) != 0) { Log(level, "%s: remote peer terminated TLS session", prepend); } /* "an EOF was observed that violates the protocol" */ else if (retcode == 0) { Log(level, "%s: socket closed", prepend); } /* "the underlying BIO reported an I/O error" */ else if (retcode == -1) { Log(level, "%s: underlying network error (%s)", prepend, syserr); } } else /* generic error printing fallback */ { Log(level, "%s: (%d %s) %s %s", prepend, retcode, errstr1, (errstr2 == NULL) ? "" : errstr2, /* most likely empty */ syserr); } return errcode; } static void assert_SSLIsBlocking(const SSL *ssl) { #if !defined(NDEBUG) && !defined(__MINGW32__) int fd = SSL_get_fd(ssl); if (fd >= 0) { int flags = fcntl(fd, F_GETFL, 0); if (flags != -1 && (flags & O_NONBLOCK) != 0) { ProgrammingError("OpenSSL socket is non-blocking!"); } } #else // silence compiler warning ssl = NULL; #endif } /** * @brief Sends the data stored on the buffer using a TLS session. * @param ssl SSL information. * @param buffer Data to send. * @param length Length of the data to send. * @return The length of the data sent (always equals #length if SSL is set * up correctly, see note), or -1 in case of error, or 0 for connection * closed. * * @note Use only for *blocking* sockets. Set * SSL_CTX_set_mode(SSL_MODE_AUTO_RETRY) and make sure you haven't * turned on SSL_MODE_ENABLE_PARTIAL_WRITE so that either the * operation is completed (retval==length) or an error occurred. * * @TODO ERR_get_error is only meaningful for some error codes, so check and * return empty string otherwise. */ int TLSSend(SSL *ssl, const char *buffer, int length) { assert(length >= 0); assert_SSLIsBlocking(ssl); if (length == 0) { UnexpectedError("TLSSend: Zero length buffer!"); return 0; } EnforceBwLimit(length); int sent = -1; bool should_retry = true; int remaining_tries = MAX_WRITE_RETRIES; while ((sent < 0) && should_retry) { sent = SSL_write(ssl, buffer, length); if (sent <= 0) { if ((SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) != 0) { Log(LOG_LEVEL_ERR, "Remote peer terminated TLS session (SSL_write)"); return 0; } /* else */ int code = TLSLogError(ssl, LOG_LEVEL_VERBOSE, "SSL write failed", sent); /* If renegotiation happens, SSL_ERROR_WANT_READ or * SSL_ERROR_WANT_WRITE can be reported. See man:SSL_write(3).*/ should_retry = ((remaining_tries > 0) && ((code == SSL_ERROR_WANT_READ) || (code == SSL_ERROR_WANT_WRITE))); } if ((sent < 0) && should_retry) { sleep(1); remaining_tries--; } } if (sent < 0) { TLSLogError(ssl, LOG_LEVEL_ERR, "SSL_write", sent); return -1; } return sent; } /** * @brief Receives at most #length bytes of data from the SSL session * and stores it in the buffer. * @param ssl SSL information. * @param buffer Buffer, of size at least #toget + 1 to store received data. * @param toget Length of the data to receive, must be < CF_BUFSIZE. * * @return The length of the received data, which should be equal or less * than the requested amount. * -1 in case of timeout or error - SSL session is unusable * 0 if connection was closed * * @note Use only for *blocking* sockets. Set * SSL_CTX_set_mode(SSL_MODE_AUTO_RETRY) to make sure that either * operation completed or an error occurred. * @note Still, it may happen for #retval to be less than #toget, if the * opposite side completed a TLSSend() with number smaller than #toget. */ int TLSRecv(SSL *ssl, char *buffer, int toget) { assert(toget > 0); assert(toget < CF_BUFSIZE); assert_SSLIsBlocking(ssl); int received = -1; bool should_retry = true; int remaining_tries = MAX_READ_RETRIES; while ((received < 0) && should_retry) { received = SSL_read(ssl, buffer, toget); if (received < 0) { int code = TLSLogError(ssl, LOG_LEVEL_VERBOSE, "SSL read failed", received); /* SSL_read() might get an internal recv() timeout, since we've set * SO_RCVTIMEO. In that case SSL_read() returns SSL_ERROR_WANT_READ. * Also, if renegotiation happens, SSL_ERROR_WANT_READ or * SSL_ERROR_WANT_WRITE can be reported. See man:SSL_read(3).*/ should_retry = ((remaining_tries > 0) && ((code == SSL_ERROR_WANT_READ) || (code == SSL_ERROR_WANT_WRITE))); } if ((received < 0) && should_retry) { sleep(1); remaining_tries--; } } if (received < 0) { int errcode = TLSLogError(ssl, LOG_LEVEL_ERR, "SSL read after retries", received); /* if all the retries didn't help, let's at least make sure proper * cleanup is done */ if ((errcode == SSL_ERROR_WANT_READ) || (errcode == SSL_ERROR_WANT_WRITE)) { /* Make sure that the peer will send us no more data. */ SSL_shutdown(ssl); shutdown(SSL_get_fd(ssl), SHUT_RDWR); /* Empty possible SSL_read() buffers. */ int ret = 1; int bytes_still_buffered = SSL_pending(ssl); while (bytes_still_buffered > 0 && ret > 0) { char tmpbuf[bytes_still_buffered]; ret = SSL_read(ssl, tmpbuf, bytes_still_buffered); bytes_still_buffered -= ret; } } return -1; } else if (received == 0) { if ((SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) != 0) { Log(LOG_LEVEL_VERBOSE, "Remote peer terminated TLS session (SSL_read)"); } else { TLSLogError(ssl, LOG_LEVEL_ERR, "Connection unexpectedly closed (SSL_read)", received); } } assert(received < CF_BUFSIZE); buffer[received] = '\0'; return received; } /** * @brief Repeat receiving until last byte received is '\n'. * * @param #buf on return will contain all received lines, and '\0' will be * appended to it. * @return Return value is #buf 's length (excluding manually appended '\0') * or -1 in case of error. * * @note This function is intended for line-oriented communication, this means * the peer sends us one line (or a bunch of lines) and waits for reply, * so that '\n' is the last character in the underlying SSL_read(). */ int TLSRecvLines(SSL *ssl, char *buf, size_t buf_size) { int ret; size_t got = 0; buf_size -= 1; /* Reserve one space for terminating '\0' */ /* Repeat until we receive end of line. */ do { buf[got] = '\0'; ret = TLSRecv(ssl, &buf[got], buf_size - got); if (ret <= 0) { Log(LOG_LEVEL_ERR, "Connection was hung up while receiving line: %s", buf); return -1; } got += ret; } while ((buf[got-1] != '\n') && (got < buf_size)); assert(got <= buf_size); /* Append '\0', there is room because buf_size has been decremented. */ buf[got] = '\0'; if ((got == buf_size) && (buf[got-1] != '\n')) { Log(LOG_LEVEL_ERR, "Received line too long, hanging up! Length %zu, line: %s", got, buf); return -1; } LogRaw(LOG_LEVEL_DEBUG, "TLSRecvLines(): ", buf, got); return (got <= INT_MAX) ? (int) got : -1; } /** * Set safe OpenSSL defaults commonly used by both clients and servers. * * @param min_version the minimum acceptable TLS version for incoming or * outgoing connections (depending on ssl_ctx), for example * "1", "1.1", "1.2". */ void TLSSetDefaultOptions(SSL_CTX *ssl_ctx, const char *min_version) { #if HAVE_DECL_SSL_CTX_CLEAR_OPTIONS /* Clear all flags, we do not want compatibility tradeoffs like * SSL_OP_LEGACY_SERVER_CONNECT. */ SSL_CTX_clear_options(ssl_ctx, SSL_CTX_get_options(ssl_ctx)); #else /* According to OpenSSL code v.0.9.8m, the first option to be added * by default (SSL_OP_LEGACY_SERVER_CONNECT) was added at the same * time SSL_CTX_clear_options appeared. Therefore, it is OK not to * clear options if they are not set. * If this assertion is proven to be false, output a clear warning * to let the user know what happens. */ if (SSL_CTX_get_options(ssl_ctx) != 0) { Log(LOG_LEVEL_WARNING, "This version of CFEngine was compiled against OpenSSL < 0.9.8m, " "using it with a later OpenSSL version is insecure. " "The current version uses compatibility workarounds that may allow " "CVE-2009-3555 exploitation."); Log(LOG_LEVEL_WARNING, "Please update your CFEngine package or " "compile it against your current OpenSSL version."); } #endif /* In any case use only TLS v1 or later. */ long options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; assert(TLS_LOWEST_RECOMMENDED >= TLS_LOWEST_REQUIRED); enum tls_version min_tls_version = TLS_LOWEST_RECOMMENDED; if (!NULL_OR_EMPTY(min_version)) { bool found = false; for (enum tls_version v = TLS_1_0; !found && v <= TLS_LAST; v++) { if (StringEqual(min_version, tls_version_strings[v])) { found = true; if (v < TLS_LOWEST_REQUIRED) { Log(LOG_LEVEL_WARNING, "Minimum requested TLS version is %s," " but minimum version required by CFEngine is %s." " Using the minimum required version.", min_version, tls_version_strings[TLS_LOWEST_REQUIRED]); min_tls_version = TLS_LOWEST_REQUIRED; } else if (v < TLS_LOWEST_RECOMMENDED) { Log(LOG_LEVEL_WARNING, "Minimum requested TLS version is %s," " but minimum version recommended by CFEngine is %s.", min_version, tls_version_strings[TLS_LOWEST_RECOMMENDED]); min_tls_version = v; } else if (v > TLS_HIGHEST_SUPPORTED) { Log(LOG_LEVEL_WARNING, "Minimum requested TLS version is %s," " but maximum version supported by OpenSSL is %s." " Using the maximum supported version.", min_version, tls_version_strings[TLS_HIGHEST_SUPPORTED]); min_tls_version = TLS_HIGHEST_SUPPORTED; } else { min_tls_version = v; } } } if (!found) { Log(LOG_LEVEL_WARNING, "Unrecognized requested minimum TLS version '%s'," " using the minimum required version %s.", min_version, tls_version_strings[TLS_LOWEST_REQUIRED]); min_tls_version = TLS_LOWEST_REQUIRED; } } Log(LOG_LEVEL_VERBOSE, "Setting minimum acceptable TLS version: %s", tls_version_strings[min_tls_version]); /* disable all the lower versions than the minimum requested/determined */ for (enum tls_version v = TLS_1_0; v < min_tls_version; v++) { options |= tls_disable_flags[v]; } /* No session resumption or renegotiation for now. */ options |= SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; #ifdef SSL_OP_NO_TICKET /* Disable another way of resumption, session tickets (RFC 5077). */ options |= SSL_OP_NO_TICKET; #endif SSL_CTX_set_options(ssl_ctx, options); /* Disable both server-side and client-side session caching, to complement the previous options. Safe for now, might enable for performance in the future. */ SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_OFF); /* Never bother with retransmissions, SSL_write() should * always either write the whole amount or fail. */ SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); /* Set options to always request a certificate from the peer, either we are client or server. */ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); /* Always accept that certificate, we do proper checking after TLS * connection is established since OpenSSL can't pass a connection * specific pointer to the callback (so we would have to lock). */ SSL_CTX_set_cert_verify_callback(ssl_ctx, TLSVerifyCallback, NULL); } bool TLSSetCipherList(SSL_CTX *ssl_ctx, const char *cipher_list) { assert(ssl_ctx); if (NULL_OR_EMPTY(cipher_list)) { Log(LOG_LEVEL_VERBOSE, "Using the OpenSSL's default cipher list"); /* nothing more to do */ return true; } Log(LOG_LEVEL_VERBOSE, "Setting cipher list for TLS connections to: %s", cipher_list); const size_t max_len = strlen(cipher_list) + 1; /* NUL byte */ size_t n_specs = StringCountTokens(cipher_list, max_len - 1, ":"); /* TLS 1.3 defines cipher suites, they start with "TLS_" */ char ciphers[max_len]; ciphers[0] = '\0'; size_t ciphers_len = 0; char cipher_suites[max_len]; cipher_suites[0] = '\0'; size_t cipher_suites_len = 0; for (size_t i = 0; i < n_specs; i++) { StringRef spec_ref = StringGetToken(cipher_list, max_len, i, ":"); if (StringStartsWith(spec_ref.data, "TLS_")) { StrCat(cipher_suites, max_len, &cipher_suites_len, spec_ref.data, spec_ref.len + 1); } else { StrCat(ciphers, max_len, &ciphers_len, spec_ref.data, spec_ref.len + 1); } } /* The above code can leave a trailing colon in the lists because it copies * the items over *with* the colons splitting them. */ if ((ciphers_len > 0) && (ciphers[ciphers_len - 1] == ':')) { ciphers[ciphers_len - 1] = '\0'; ciphers_len--; } if ((cipher_suites_len > 0) && (cipher_suites[cipher_suites_len - 1] == ':')) { cipher_suites[cipher_suites_len - 1] = '\0'; cipher_suites_len--; } if (ciphers_len != 0) /* TLS <= 1.2 ciphers */ { Log(LOG_LEVEL_VERBOSE, "Enabling ciphers '%s' for TLS 1.2 and older", ciphers); int ret = SSL_CTX_set_cipher_list(ssl_ctx, ciphers); if (ret != 1) { Log(LOG_LEVEL_ERR, "No valid ciphers in the cipher list: %s", cipher_list); return false; } } #ifdef HAVE_TLS_1_3 if (cipher_suites_len != 0) /* TLS >= 1.3 ciphers */ { Log(LOG_LEVEL_VERBOSE, "Enabling cipher suites '%s' for TLS 1.3 and newer", cipher_suites); int ret = SSL_CTX_set_ciphersuites(ssl_ctx, cipher_suites); if (ret != 1) { Log(LOG_LEVEL_ERR, "No valid cipher suites in the list: %s", cipher_list); return false; } } else { /* Allowed ciphers specified, but no TLS 1.3 ciphersuites among them. Let's disable TLS 1.3 because otherwise OpenSSL uses the default ciphersuites for TLS 1.3 and thus effectively extends the specified list of allowed ciphers behind our back. */ Log(LOG_LEVEL_WARNING, "Disabling TLS 1.3 because no TLS 1.3 ciphersuites specified in allowed ciphers: '%s'", cipher_list); SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_TLSv1_3); } #else if (cipher_suites_len != 0) { Log(LOG_LEVEL_WARNING, "Ignoring requested TLS 1.3 ciphersuites '%s', TLS 1.3 not supported", cipher_suites); } #endif return true; } cfengine-3.24.2/libcfnet/client_protocol.c0000644000000000000000000004252715010704253020516 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* BN_* */ #include /* ERR_get_error */ #include #include #include /* libutils */ #include /* Log */ /* TODO remove all includes from libpromises. */ extern char VIPADDRESS[CF_MAX_IP_LEN]; extern char VDOMAIN[]; extern char VFQNAME[]; #include /* GetCurrentUsername */ #include /* LastSaw */ #include /* PublicKeyFile */ #include /* HashString,HashesMatch,HashPubKey*/ #include #include #include /* TLSErrorString */ /*********************************************************************/ static bool SKIPIDENTIFY = false; /* GLOBAL_P */ /*********************************************************************/ void SetSkipIdentify(bool enabled) { SKIPIDENTIFY = enabled; } /*********************************************************************/ bool IdentifyAgent(ConnectionInfo *conn_info) { assert(conn_info != NULL); char uname[CF_MAXVARSIZE], sendbuff[CF_BUFSIZE]; char dnsname[CF_MAXVARSIZE], localip[CF_MAX_IP_LEN]; int ret; if ((!SKIPIDENTIFY) && (strcmp(VDOMAIN, CF_START_DOMAIN) == 0)) { Log(LOG_LEVEL_ERR, "Undefined domain name"); return false; } if (!SKIPIDENTIFY) { /* First we need to find out the IP address and DNS name of the socket we are sending from. This is not necessarily the same as VFQNAME if the machine has a different uname from its IP name (!) This can happen on poorly set up machines or on hosts with multiple interfaces, with different names on each interface ... */ struct sockaddr_storage myaddr = {0}; socklen_t myaddr_len = sizeof(myaddr); if (getsockname(conn_info->sd, (struct sockaddr *) &myaddr, &myaddr_len) == -1) { Log(LOG_LEVEL_ERR, "Couldn't get socket address. (getsockname: %s)", GetErrorStr()); return false; } /* No lookup, just convert the bound address to string. */ ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len, localip, sizeof(localip), NULL, 0, NI_NUMERICHOST); if (ret != 0) { Log(LOG_LEVEL_ERR, "During agent identification. (getnameinfo: %s)", gai_strerror(ret)); return false; } /* dnsname: Reverse lookup of the bound IP address. */ ret = getnameinfo((struct sockaddr *) &myaddr, myaddr_len, dnsname, sizeof(dnsname), NULL, 0, 0); if (ret != 0) { /* getnameinfo doesn't fail on resolution failure, it just prints * the IP, so here something else is wrong. */ Log(LOG_LEVEL_ERR, "During agent identification for '%s'. (getnameinfo: %s)", localip, gai_strerror(ret)); return false; } /* Append a hostname if getnameinfo() does not return FQDN. Might only * happen if the host has no domainname, in which case VDOMAIN might * also be empty! In addition, missing PTR will give numerical result, * so use it either it's IPv4 or IPv6. Finally don't append the * VDOMAIN if "localhost" is resolved name, it means we're connecting * via loopback. */ if ((strlen(VDOMAIN) > 0) && !IsIPV6Address(dnsname) && (strchr(dnsname, '.') == NULL) && strcmp(dnsname, "localhost") != 0) { strcat(dnsname, "."); strlcat(dnsname, VDOMAIN, sizeof(dnsname)); } /* Seems to be a bug in some resolvers that adds garbage, when it just * returns the input. */ if (strncmp(dnsname, localip, strlen(localip)) == 0 && dnsname[strlen(localip)] != '\0') { dnsname[strlen(localip)] = '\0'; Log(LOG_LEVEL_WARNING, "getnameinfo() seems to append garbage to unresolvable IPs, bug mitigated by CFEngine but please report your platform!"); } } else { nt_static_assert(sizeof(localip) >= sizeof(VIPADDRESS)); strcpy(localip, VIPADDRESS); Log(LOG_LEVEL_VERBOSE, "skipidentify was promised, so we are trusting and simply announcing the identity as '%s' for this host", strlen(VFQNAME) > 0 ? VFQNAME : "skipident"); if (strlen(VFQNAME) > 0) { strcpy(dnsname, VFQNAME); } else { strcpy(dnsname, "skipident"); } } /* client always identifies as root on windows */ #ifdef __MINGW32__ snprintf(uname, sizeof(uname), "%s", "root"); #else GetCurrentUserName(uname, sizeof(uname)); #endif snprintf(sendbuff, sizeof(sendbuff), "CAUTH %s %s %s %d", localip, dnsname, uname, 0); if (SendTransaction(conn_info, sendbuff, 0, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "During identify agent, could not send auth response. (SendTransaction: %s)", GetErrorStr()); return false; } return true; } /*********************************************************************/ static bool SetSessionKey(AgentConnection *conn) { BIGNUM *bp; int session_size = CfSessionKeySize(conn->encryption_type); bp = BN_new(); if (bp == NULL) { Log(LOG_LEVEL_ERR, "Could not allocate session key"); return false; } // session_size is in bytes if (!BN_rand(bp, session_size * 8, -1, 0)) { Log(LOG_LEVEL_ERR, "Can't generate cryptographic key"); BN_clear_free(bp); return false; } conn->session_key = xmalloc(BN_num_bytes(bp)); BN_bn2bin(bp, conn->session_key); BN_clear_free(bp); return true; } bool AuthenticateAgent(AgentConnection *conn, bool trust_key) { char *decrypted_cchall; unsigned char sendbuffer[CF_EXPANDSIZE]; unsigned char *out; unsigned char in[CF_BUFSIZE]; BIGNUM *nonce_challenge, *bn = NULL; unsigned char digest[EVP_MAX_MD_SIZE + 1]; int encrypted_len, nonce_len = 0, len, session_size; bool need_to_implicitly_trust_server; char enterprise_field = 'c'; if (PRIVKEY == NULL || PUBKEY == NULL) { Log(LOG_LEVEL_ERR, "No public/private key pair is loaded," " please create one using cf-key"); return false; } enterprise_field = CfEnterpriseOptions(); session_size = CfSessionKeySize(enterprise_field); /* Generate a random challenge to authenticate the server */ nonce_challenge = BN_new(); if (nonce_challenge == NULL) { Log(LOG_LEVEL_ERR, "Cannot allocate BIGNUM structure for server challenge"); return false; } BN_rand(nonce_challenge, CF_NONCELEN, 0, 0); nonce_len = BN_bn2mpi(nonce_challenge, in); if (FIPS_MODE) { HashString((const char *) in, nonce_len, digest, CF_DEFAULT_DIGEST); } else { HashString((const char *) in, nonce_len, digest, HASH_METHOD_MD5); } /* We assume that the server bound to the remote socket is the official one i.e. = root's */ /* Ask the server to send us the public key if we don't have it. */ RSA *server_pubkey = HavePublicKeyByIP(conn->username, conn->remoteip); if (server_pubkey) { need_to_implicitly_trust_server = false; encrypted_len = RSA_size(server_pubkey); } else { need_to_implicitly_trust_server = true; encrypted_len = nonce_len; } // Server pubkey is what we want to has as a unique ID snprintf((char *) sendbuffer, sizeof(sendbuffer), "SAUTH %c %d %d %c", need_to_implicitly_trust_server ? 'n': 'y', encrypted_len, nonce_len, enterprise_field); out = xmalloc(encrypted_len); if (server_pubkey != NULL) { if (RSA_public_encrypt(nonce_len, in, out, server_pubkey, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Public encryption failed. (RSA_public_encrypt: %s)", CryptoLastErrorString()); free(out); RSA_free(server_pubkey); return false; } memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, out, encrypted_len); } else { memcpy(sendbuffer + CF_RSA_PROTO_OFFSET, in, nonce_len); } /* proposition C1 - Send challenge / nonce */ SendTransaction(conn->conn_info, (const char *) sendbuffer, CF_RSA_PROTO_OFFSET + encrypted_len, CF_DONE); BN_free(bn); BN_free(nonce_challenge); free(out); /*Send the public key - we don't know if server has it */ /* proposition C2 */ const BIGNUM *pubkey_n, *pubkey_e; RSA_get0_key(PUBKEY, &pubkey_n, &pubkey_e, NULL); memset(sendbuffer, 0, CF_EXPANDSIZE); len = BN_bn2mpi(pubkey_n, sendbuffer); SendTransaction(conn->conn_info, (const char *) sendbuffer, len, CF_DONE); /* No need to encrypt the public key ... */ /* proposition C3 */ memset(sendbuffer, 0, CF_EXPANDSIZE); len = BN_bn2mpi(pubkey_e, sendbuffer); SendTransaction(conn->conn_info, (const char *) sendbuffer, len, CF_DONE); /* check reply about public key - server can break conn_info here */ /* proposition S1 */ memset(in, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, (char *) in, NULL) == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction broken off (1). (ReceiveTransaction: %s)", GetErrorStr()); RSA_free(server_pubkey); return false; } if (BadProtoReply((const char *) in)) { Log(LOG_LEVEL_ERR, "Bad protocol reply: %s", in); RSA_free(server_pubkey); return false; } /* Get challenge response - should be CF_DEFAULT_DIGEST of challenge */ /* proposition S2 */ memset(in, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, (char *) in, NULL) == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction broken off (2). (ReceiveTransaction: %s)", GetErrorStr()); RSA_free(server_pubkey); return false; } /* Check if challenge reply was correct */ if ((HashesMatch(digest, in, CF_DEFAULT_DIGEST)) || (HashesMatch(digest, in, HASH_METHOD_MD5))) // Legacy { if (need_to_implicitly_trust_server == false) { /* The IP was found in lastseen. */ Log(LOG_LEVEL_VERBOSE, ".....................[.h.a.i.l.]................................."); Log(LOG_LEVEL_VERBOSE, "Strong authentication of server '%s' connection confirmed", conn->this_server); } else /* IP was not found in lastseen */ { if (trust_key) { Log(LOG_LEVEL_VERBOSE, "Trusting server identity, promise to accept key from '%s' = '%s'", conn->this_server, conn->remoteip); } else { Log(LOG_LEVEL_ERR, "Not authorized to trust public key of server '%s' (trustkey = false)", conn->this_server); RSA_free(server_pubkey); return false; } } } else { Log(LOG_LEVEL_ERR, "Challenge response from server '%s/%s' was incorrect", conn->this_server, conn->remoteip); RSA_free(server_pubkey); return false; } /* Receive counter challenge from server */ /* proposition S3 */ memset(in, 0, CF_BUFSIZE); encrypted_len = ReceiveTransaction(conn->conn_info, (char *) in, NULL); if (encrypted_len == -1) { Log(LOG_LEVEL_ERR, "Protocol transaction sent illegal cipher length"); RSA_free(server_pubkey); return false; } decrypted_cchall = xmalloc(encrypted_len); if (RSA_private_decrypt(encrypted_len, in, (unsigned char *) decrypted_cchall, PRIVKEY, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Private decrypt failed, abandoning. (RSA_private_decrypt: %s)", CryptoLastErrorString()); RSA_free(server_pubkey); return false; } /* proposition C4 */ if (FIPS_MODE) { HashString(decrypted_cchall, nonce_len, digest, CF_DEFAULT_DIGEST); } else { HashString(decrypted_cchall, nonce_len, digest, HASH_METHOD_MD5); } if (FIPS_MODE) { SendTransaction(conn->conn_info, (const char *) digest, CF_DEFAULT_DIGEST_LEN, CF_DONE); } else { SendTransaction(conn->conn_info, (const char *) digest, CF_MD5_LEN, CF_DONE); } free(decrypted_cchall); /* If we don't have the server's public key, it will be sent */ if (server_pubkey == NULL) { RSA *newkey = RSA_new(); Log(LOG_LEVEL_VERBOSE, "Collecting public key from server!"); /* proposition S4 - conditional */ if ((len = ReceiveTransaction(conn->conn_info, (char *) in, NULL)) == -1) { Log(LOG_LEVEL_ERR, "Protocol error in RSA authentation from IP '%s'", conn->this_server); return false; } BIGNUM *newkey_n, *newkey_e; if ((newkey_n = BN_mpi2bn(in, len, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Private key decrypt failed. (BN_mpi2bn: %s)", CryptoLastErrorString()); RSA_free(newkey); return false; } /* proposition S5 - conditional */ if ((len = ReceiveTransaction(conn->conn_info, (char *) in, NULL)) == -1) { Log(LOG_LEVEL_INFO, "Protocol error in RSA authentation from IP '%s'", conn->this_server); BN_clear_free(newkey_n); RSA_free(newkey); return false; } if ((newkey_e = BN_mpi2bn(in, len, NULL)) == NULL) { Log(LOG_LEVEL_ERR, "Public key decrypt failed. (BN_mpi2bn: %s)", CryptoLastErrorString()); BN_clear_free(newkey_n); RSA_free(newkey); return false; } if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { Log(LOG_LEVEL_ERR, "Failed to set RSA key: %s", TLSErrorString(ERR_get_error())); BN_clear_free(newkey_e); BN_clear_free(newkey_n); RSA_free(newkey); return false; } server_pubkey = RSAPublicKey_dup(newkey); RSA_free(newkey); } assert(server_pubkey != NULL); /* proposition C5 */ if (!SetSessionKey(conn)) { Log(LOG_LEVEL_ERR, "Unable to set session key"); return false; } if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "A random session key could not be established"); RSA_free(server_pubkey); return false; } encrypted_len = RSA_size(server_pubkey); out = xmalloc(encrypted_len); if (RSA_public_encrypt(session_size, conn->session_key, out, server_pubkey, RSA_PKCS1_PADDING) <= 0) { Log(LOG_LEVEL_ERR, "Public encryption failed. (RSA_public_encrypt: %s)", CryptoLastErrorString()); free(out); RSA_free(server_pubkey); return false; } SendTransaction(conn->conn_info, (const char *) out, encrypted_len, CF_DONE); Key *key = KeyNew(server_pubkey, CF_DEFAULT_DIGEST); conn->conn_info->remote_key = key; Log(LOG_LEVEL_VERBOSE, "Public key identity of host '%s' is: %s", conn->remoteip, KeyPrintableHash(conn->conn_info->remote_key)); SavePublicKey(conn->username, KeyPrintableHash(conn->conn_info->remote_key), server_pubkey); unsigned int length = 0; LastSaw(conn->remoteip, KeyBinaryHash(conn->conn_info->remote_key, &length), LAST_SEEN_ROLE_CONNECT); free(out); return true; } /*********************************************************************/ bool BadProtoReply(const char *const buf) { return (strncmp(buf, "BAD: ", 5) == 0); } /*********************************************************************/ bool OKProtoReply(const char *const buf) { return (strncmp(buf, "OK:", 3) == 0); } /*********************************************************************/ bool FailedProtoReply(const char *const buf) { return (strncmp(buf, CF_FAILEDSTR, strlen(CF_FAILEDSTR)) == 0); } cfengine-3.24.2/libcfnet/protocol_version.c0000644000000000000000000000212315010704253020711 0ustar00rootroot00000000000000#include #include #include ProtocolVersion ParseProtocolVersionNetwork(const char *const s) { int version; const int ret = sscanf(s, "CFE_v%d", &version); if (ret != 1 || version <= CF_PROTOCOL_UNDEFINED) { return CF_PROTOCOL_UNDEFINED; } // Note that `version` may be above CF_PROTOCOL_LATEST, if the other side // supports a newer protocol return version; } ProtocolVersion ParseProtocolVersionPolicy(const char *const s) { if ((s == NULL) || StringEqual(s, "0") || StringEqual(s, "undefined")) { return CF_PROTOCOL_UNDEFINED; } if (StringEqual(s, "1") || StringEqual(s, "classic")) { return CF_PROTOCOL_CLASSIC; } else if (StringEqual(s, "2") || StringEqual(s, "tls")) { return CF_PROTOCOL_TLS; } else if (StringEqual(s, "3") || StringEqual(s, "cookie")) { return CF_PROTOCOL_COOKIE; } else if (StringEqual(s, "latest")) { return CF_PROTOCOL_LATEST; } else { return CF_PROTOCOL_UNDEFINED; } } cfengine-3.24.2/libcfnet/conn_cache.c0000644000000000000000000001723615010704253017376 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* AgentConnection */ #include /* DisconnectServer */ #include /* Seq */ #include /* ThreadLock */ #include /* Hostname2IPString */ #include /* CF_ASSERT */ #include /* StringEqual */ /** Global cache for connections to servers, currently only used in cf-agent. @note THREAD-SAFETY: yes this connection cache *is* thread-safe, but is extremely slow if used intensely from multiple threads. It needs to be redesigned from scratch for that, not a priority for single-threaded cf-agent! */ typedef struct { AgentConnection *conn; enum ConnCacheStatus status; /* TODO unify with conn->conn_info->status */ } ConnCache_entry; static pthread_mutex_t cft_conncache = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; static Seq *conn_cache = NULL; void ConnCache_Init() { ThreadLock(&cft_conncache); assert(conn_cache == NULL); conn_cache = SeqNew(100, free); ThreadUnlock(&cft_conncache); } void ConnCache_Destroy() { ThreadLock(&cft_conncache); for (size_t i = 0; i < SeqLength(conn_cache); i++) { ConnCache_entry *svp = SeqAt(conn_cache, i); CF_ASSERT(svp != NULL, "Destroy: NULL ConnCache_entry!"); CF_ASSERT(svp->conn != NULL, "Destroy: NULL connection in ConnCache_entry!"); DisconnectServer(svp->conn); } SeqDestroy(conn_cache); conn_cache = NULL; ThreadUnlock(&cft_conncache); } static bool ConnCacheEntryMatchesConnection(ConnCache_entry *entry, const char *server, const char *port, ConnectionFlags flags) { return ConnectionFlagsEqual(&flags, &entry->conn->flags) && StringEqual(port, entry->conn->this_port) && StringEqual(server, entry->conn->this_server); } AgentConnection *ConnCache_FindIdleMarkBusy(const char *server, const char *port, ConnectionFlags flags) { ThreadLock(&cft_conncache); AgentConnection *ret_conn = NULL; for (size_t i = 0; i < SeqLength(conn_cache); i++) { ConnCache_entry *svp = SeqAt(conn_cache, i); CF_ASSERT(svp != NULL, "FindIdle: NULL ConnCache_entry!"); CF_ASSERT(svp->conn != NULL, "FindIdle: NULL connection in ConnCache_entry!"); if (svp->status == CONNCACHE_STATUS_BUSY) { Log(LOG_LEVEL_DEBUG, "FindIdle: connection %p seems to be busy.", svp->conn); } else if (svp->status == CONNCACHE_STATUS_OFFLINE) { Log(LOG_LEVEL_DEBUG, "FindIdle: connection %p is marked as offline.", svp->conn); } else if (svp->status == CONNCACHE_STATUS_BROKEN) { Log(LOG_LEVEL_DEBUG, "FindIdle: connection %p is marked as broken.", svp->conn); } else if (ConnCacheEntryMatchesConnection(svp, server, port, flags)) { if (svp->conn->conn_info->sd >= 0) { assert(svp->status == CONNCACHE_STATUS_IDLE); // Check connection state before returning it int error = 0; socklen_t len = sizeof(error); if (getsockopt(svp->conn->conn_info->sd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { Log(LOG_LEVEL_DEBUG, "FindIdle: found connection to '%s' but could not get socket status, skipping.", server); svp->status = CONNCACHE_STATUS_BROKEN; continue; } if (error != 0) { Log(LOG_LEVEL_DEBUG, "FindIdle: found connection to '%s' but connection is broken, skipping.", server); svp->status = CONNCACHE_STATUS_BROKEN; continue; } Log(LOG_LEVEL_VERBOSE, "FindIdle:" " found connection to '%s' already open and ready.", server); svp->status = CONNCACHE_STATUS_BUSY; ret_conn = svp->conn; break; } else { Log(LOG_LEVEL_VERBOSE, "FindIdle:" " connection to '%s' has invalid socket descriptor %d!", server, svp->conn->conn_info->sd); svp->status = CONNCACHE_STATUS_BROKEN; } } } ThreadUnlock(&cft_conncache); if (ret_conn == NULL) { Log(LOG_LEVEL_VERBOSE, "FindIdle:" " no existing connection to '%s' is established.", server); } return ret_conn; } void ConnCache_MarkNotBusy(AgentConnection *conn) { Log(LOG_LEVEL_DEBUG, "Searching for specific busy connection to: %s", conn->this_server); ThreadLock(&cft_conncache); bool found = false; for (size_t i = 0; i < SeqLength(conn_cache); i++) { ConnCache_entry *svp = SeqAt(conn_cache, i); CF_ASSERT(svp != NULL, "MarkNotBusy: NULL ConnCache_entry!"); CF_ASSERT(svp->conn != NULL, "MarkNotBusy: NULL connection in ConnCache_entry!"); if (svp->conn == conn) { /* There might be many connections to the same server, some busy * some not. But here we're searching by the address of the * AgentConnection object. There can be only one. */ CF_ASSERT(svp->status == CONNCACHE_STATUS_BUSY, "MarkNotBusy: status is not busy, it is %d!", svp->status); svp->status = CONNCACHE_STATUS_IDLE; found = true; break; } } ThreadUnlock(&cft_conncache); if (!found) { ProgrammingError("MarkNotBusy: No busy connection found!"); } Log(LOG_LEVEL_DEBUG, "Busy connection just became free"); } /* First time we open a connection, so store it. */ void ConnCache_Add(AgentConnection *conn, enum ConnCacheStatus status) { ConnCache_entry *svp = xmalloc(sizeof(*svp)); svp->status = status; svp->conn = conn; ThreadLock(&cft_conncache); SeqAppend(conn_cache, svp); ThreadUnlock(&cft_conncache); } cfengine-3.24.2/libcfnet/connection_info.h0000644000000000000000000001163315010704253020470 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CONNECTION_INFO_H #define CONNECTION_INFO_H #include #include #include /** @brief ConnectionInfo Structure and support routines ConnectionInfo is used to abstract the underlying type of connection from our protocol implementation. It can hold both a normal socket connection and a TLS stream. */ /** * @brief Status of the connection, for the connection cache and for * propagating errors up in function callers. */ typedef enum { CONNECTIONINFO_STATUS_NOT_ESTABLISHED, CONNECTIONINFO_STATUS_ESTABLISHED, /* used to propagate connection errors up in function calls */ CONNECTIONINFO_STATUS_BROKEN /* TODO ESTABLISHED==IDLE, BUSY, OFFLINE */ } ConnectionStatus; struct ConnectionInfo { ProtocolVersion protocol; ConnectionStatus status; int sd; /* Socket descriptor */ SSL *ssl; /* OpenSSL struct for TLS connections */ Key *remote_key; socklen_t ss_len; struct sockaddr_storage ss; bool is_call_collect; /* Maybe replace with a bitfield later ... */ }; typedef struct ConnectionInfo ConnectionInfo; /** @brief Creates a new ConnectionInfo structure. @return A initialized ConnectionInfo structure, needs to be populated. */ ConnectionInfo *ConnectionInfoNew(void); /** @brief Destroys a ConnectionInfo structure. @param info Pointer to the ConectionInfo structure to be destroyed. */ void ConnectionInfoDestroy(ConnectionInfo **info); /** @brief Protocol Version @param info ConnectionInfo structure @return Returns the protocol version or CF_PROTOCOL_UNDEFINED in case of error. */ ProtocolVersion ConnectionInfoProtocolVersion(const ConnectionInfo *info); /** @brief Sets the protocol version Notice that if an invalid protocol version is passed, the value will not be changed. @param info ConnectionInfo structure. @param version New protocol version */ void ConnectionInfoSetProtocolVersion(ConnectionInfo *info, ProtocolVersion version); /** @brief Connection socket For practical reasons there is no difference between an invalid socket and an error on this routine. @param info ConnectionInfo structure. @return Returns the connection socket or -1 in case of error. */ int ConnectionInfoSocket(const ConnectionInfo *info); /** @brief Sets the connection socket. @param info ConnectionInfo structure. @param s New connection socket. */ void ConnectionInfoSetSocket(ConnectionInfo *info, int s); /** @brief SSL structure. @param info ConnectionInfo structure. @return The SSL structure attached to this connection or NULL in case of error. */ SSL *ConnectionInfoSSL(const ConnectionInfo *info); /** @brief Sets the SSL structure. @param info ConnectionInfo structure. @param ssl SSL structure to attached to this connection. */ void ConnectionInfoSetSSL(ConnectionInfo *info, SSL *ssl); /** @brief RSA key @param info ConnectionInfo structure. @return Returns the RSA key or NULL in case of error. */ const Key *ConnectionInfoKey(const ConnectionInfo *info); /** @brief Sets the key for the connection structure. This triggers a calculation of two other fields. @param info ConnectionInfo structure. @param key RSA key. */ void ConnectionInfoSetKey(ConnectionInfo *info, Key *key); /** @brief A constant pointer to the binary hash of the key @param info ConnectionInfo structure @param length Length of the hash @return Returns a constant pointer to the binary hash and if length is not NULL the size is stored there. */ const unsigned char *ConnectionInfoBinaryKeyHash(ConnectionInfo *info, unsigned int *length); /** @brief A constant pointer to the binary hash of the key @param info ConnectionInfo structure @return Returns a printable representation of the hash. The string is '\0' terminated or NULL in case of failure. */ const char *ConnectionInfoPrintableKeyHash(ConnectionInfo *info); #endif // CONNECTION_INFO_H cfengine-3.24.2/libcfnet/tls_client.c0000644000000000000000000002541615010704253017455 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include #include /* SendTransaction, ReceiveTransaction */ #include /* ParseProtocolVersionNetwork() */ /* TODO move crypto.h to libutils */ #include /* LoadSecretKeys */ #define MAX_CONNECT_RETRIES 10 extern RSA *PRIVKEY, *PUBKEY; /** * Global SSL context for initiated connections over the TLS protocol. For the * agent, they are written only once, *after* the common control bundles have * been evaluated. I.e. GenericAgentPostLoadInit() is called * after LoadPolicy(). * * 1. Common bundles evaluation: LoadPolicy()->PolicyResolve() * 2. Create TLS contexts: GenericAgentPostLoadInit()->cfnet_init() */ static SSL_CTX *SSLCLIENTCONTEXT = NULL; static X509 *SSLCLIENTCERT = NULL; bool TLSClientIsInitialized() { return (SSLCLIENTCONTEXT != NULL); } /** * @warning Make sure you've called CryptoInitialize() first! * * @TODO if this function is called a second time, it just returns true, and * does not do nothing more. What if the settings (e.g. tls_min_version) have * changed? This can happen when cf-serverd reloads policy. Fixing this goes * much deeper though, as it would require cf-serverd to call * GenericAgentDiscoverContext() when reloading policy. */ bool TLSClientInitialize(const char *tls_min_version, const char *ciphers) { int ret; static bool is_initialised = false; if (is_initialised) { return true; } if (PRIVKEY == NULL || PUBKEY == NULL) { /* VERBOSE in case it's a custom, local-only installation. */ Log(LOG_LEVEL_VERBOSE, "No public/private key pair is loaded," " please create one using cf-key"); return false; } if (!TLSGenericInitialize()) { return false; } SSLCLIENTCONTEXT = SSL_CTX_new(SSLv23_client_method()); if (SSLCLIENTCONTEXT == NULL) { Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s", TLSErrorString(ERR_get_error())); goto err1; } TLSSetDefaultOptions(SSLCLIENTCONTEXT, tls_min_version); if (!TLSSetCipherList(SSLCLIENTCONTEXT, ciphers)) { goto err2; } /* Create cert into memory and load it into SSL context. */ SSLCLIENTCERT = TLSGenerateCertFromPrivKey(PRIVKEY); if (SSLCLIENTCERT == NULL) { Log(LOG_LEVEL_ERR, "Failed to generate in-memory-certificate from private key"); goto err2; } SSL_CTX_use_certificate(SSLCLIENTCONTEXT, SSLCLIENTCERT); ret = SSL_CTX_use_RSAPrivateKey(SSLCLIENTCONTEXT, PRIVKEY); if (ret != 1) { Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s", TLSErrorString(ERR_get_error())); goto err3; } /* Verify cert consistency. */ ret = SSL_CTX_check_private_key(SSLCLIENTCONTEXT); if (ret != 1) { Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s", TLSErrorString(ERR_get_error())); goto err3; } is_initialised = true; return true; err3: X509_free(SSLCLIENTCERT); SSLCLIENTCERT = NULL; err2: SSL_CTX_free(SSLCLIENTCONTEXT); SSLCLIENTCONTEXT = NULL; err1: return false; } void TLSDeInitialize() { if (PUBKEY) { RSA_free(PUBKEY); PUBKEY = NULL; } if (PRIVKEY) { RSA_free(PRIVKEY); PRIVKEY = NULL; } if (SSLCLIENTCERT != NULL) { X509_free(SSLCLIENTCERT); SSLCLIENTCERT = NULL; } if (SSLCLIENTCONTEXT != NULL) { SSL_CTX_free(SSLCLIENTCONTEXT); SSLCLIENTCONTEXT = NULL; } } /** * 1. Receive "CFE_v%d" server hello * 2. Send two lines: one "CFE_v%d" with the protocol version we wish to have, * and another with id, e.g. "IDENTITY USERNAME=blah". * 3. Receive "OK WELCOME" * * @return > 0: success. #conn_info->type has been updated with the negotiated * protocol version. * 0: server denial * -1: error */ int TLSClientIdentificationDialog(ConnectionInfo *conn_info, const char *username) { char line[1024] = ""; int ret; /* Receive CFE_v%d ... That's the first thing the server sends. */ ret = TLSRecvLines(conn_info->ssl, line, sizeof(line)); if (ret == -1) { Log(LOG_LEVEL_ERR, "Connection was hung up during identification! (0)"); return -1; } ProtocolVersion wanted_version; if (conn_info->protocol == CF_PROTOCOL_UNDEFINED) { wanted_version = CF_PROTOCOL_LATEST; } else { wanted_version = conn_info->protocol; } const ProtocolVersion received_version = ParseProtocolVersionNetwork(line); if (received_version < wanted_version && ProtocolIsTLS(received_version)) { // Downgrade as long as it's still TLS wanted_version = received_version; } else if (ProtocolIsUndefined(received_version) || ProtocolIsClassic(received_version)) { Log(LOG_LEVEL_ERR, "Server sent a bad version number! (0a)"); return -1; } assert(wanted_version <= received_version); // Server supported version assert(ProtocolIsTLS(wanted_version)); /* Send "CFE_v%d cf-agent version". */ char version_string[128]; int len = snprintf(version_string, sizeof(version_string), "CFE_v%d %s %s\n", wanted_version, "cf-agent", VERSION); /* TODO argv[0] */ ret = TLSSend(conn_info->ssl, version_string, len); if (ret != len) { Log(LOG_LEVEL_ERR, "Connection was hung up during identification! (1)"); return -1; } strcpy(line, "IDENTITY"); size_t line_len = strlen(line); if (username != NULL) { ret = snprintf(&line[line_len], sizeof(line) - line_len, " USERNAME=%s", username); if (ret < 0) { Log(LOG_LEVEL_ERR, "snprintf failed: %s", GetErrorStr()); return -1; } else if ((unsigned int) ret >= sizeof(line) - line_len) { Log(LOG_LEVEL_ERR, "Sending IDENTITY truncated: %s", line); return -1; } line_len += ret; } /* Overwrite the terminating '\0', we don't need it anyway. */ line[line_len] = '\n'; line_len++; ret = TLSSend(conn_info->ssl, line, line_len); if (ret == -1) { Log(LOG_LEVEL_ERR, "Connection was hung up during identification! (2)"); return -1; } /* Server might hang up here, after we sent identification! We * must get the "OK WELCOME" message for everything to be OK. */ static const char OK[] = "OK WELCOME"; size_t OK_len = sizeof(OK) - 1; ret = TLSRecvLines(conn_info->ssl, line, sizeof(line)); if (ret < 0) { Log(LOG_LEVEL_ERR, "Connection was hung up during identification! (3)"); return -1; } else if ((size_t) ret < OK_len || strncmp(line, OK, OK_len) != 0) { Log(LOG_LEVEL_ERR, "Peer did not accept our identity! Responded: %s", line); return 0; } /* Before it contained the protocol version we requested from the server, * now we put in the value that was negotiated. */ conn_info->protocol = wanted_version; return 1; } /** * We directly initiate a TLS handshake with the server. If the server is old * version (does not speak TLS) the connection will be denied. * @note the socket file descriptor in #conn_info must be connected and *not* * non-blocking * @return -1 in case of error */ int TLSTry(ConnectionInfo *conn_info) { assert(conn_info != NULL); if (PRIVKEY == NULL || PUBKEY == NULL) { Log(LOG_LEVEL_ERR, "No public/private key pair is loaded," " please create one using cf-key"); return -1; } assert(SSLCLIENTCONTEXT != NULL); conn_info->ssl = SSL_new(SSLCLIENTCONTEXT); if (conn_info->ssl == NULL) { Log(LOG_LEVEL_ERR, "SSL_new: %s", TLSErrorString(ERR_get_error())); return -1; } /* Pass conn_info inside the ssl struct for TLSVerifyCallback(). */ SSL_set_ex_data(conn_info->ssl, CONNECTIONINFO_SSL_IDX, conn_info); /* Initiate the TLS handshake over the already open TCP socket. */ SSL_set_fd(conn_info->ssl, conn_info->sd); bool connected = false; bool should_retry = true; int remaining_tries = MAX_CONNECT_RETRIES; int ret; while (!connected && should_retry) { ret = SSL_connect(conn_info->ssl); /* 1 means connected, 0 means shut down, <0 means error * (see man:SSL_connect(3)) */ connected = (ret == 1); if (ret == 0) { should_retry = false; } else if (ret < 0) { int code = TLSLogError(conn_info->ssl, LOG_LEVEL_VERBOSE, "Attempt to establish TLS connection failed", ret); /* see man:SSL_connect(3) */ should_retry = ((remaining_tries > 0) && ((code == SSL_ERROR_WANT_READ) || (code == SSL_ERROR_WANT_WRITE))); } if (!connected && should_retry) { sleep(1); remaining_tries--; } } if (!connected) { TLSLogError(conn_info->ssl, LOG_LEVEL_ERR, "Failed to establish TLS connection", ret); return -1; } Log(LOG_LEVEL_VERBOSE, "TLS version negotiated: %8s; Cipher: %s,%s", SSL_get_version(conn_info->ssl), SSL_get_cipher_name(conn_info->ssl), SSL_get_cipher_version(conn_info->ssl)); Log(LOG_LEVEL_VERBOSE, "TLS session established, checking trust..."); return 0; } cfengine-3.24.2/libcfnet/client_code.h0000644000000000000000000000410015010704253017555 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CLIENT_CODE_H #define CFENGINE_CLIENT_CODE_H #include #include #include bool cfnet_init(const char *tls_min_version, const char *ciphers); void cfnet_shut(void); bool cfnet_IsInitialized(void); void DetermineCfenginePort(void); bool SetCfenginePort(const char *port_str); /** @param err Set to 0 on success, -1 no server response, -2 authentication failure. */ AgentConnection *ServerConnection(const char *server, const char *port, const Rlist *restrict_keys, unsigned int connect_timeout, ConnectionFlags flags, int *err); void DisconnectServer(AgentConnection *conn); bool CompareHashNet(const char *file1, const char *file2, bool encrypt, AgentConnection *conn); bool CopyRegularFileNet(const char *source, const char *dest, off_t size, bool encrypt, AgentConnection *conn, mode_t mode); Item *RemoteDirList(const char *dirname, bool encrypt, AgentConnection *conn); int TLSConnectCallCollect(ConnectionInfo *conn_info, const char *username); #endif cfengine-3.24.2/libcfnet/stat_cache.h0000644000000000000000000000553415010704253017417 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_STAT_CACHE_H #define CFENGINE_STAT_CACHE_H #include #include typedef enum { FILE_TYPE_REGULAR, FILE_TYPE_LINK, FILE_TYPE_DIR, FILE_TYPE_FIFO, FILE_TYPE_BLOCK, FILE_TYPE_CHAR_, /* Conflict with winbase.h */ FILE_TYPE_SOCK } FileType; typedef struct Stat_ Stat; struct Stat_ { char *cf_filename; /* What file are we statting? */ char *cf_server; /* Which server did this come from? */ //WHY? Isn't this in AgentConn? FileType cf_type; /* enum filetype */ mode_t cf_lmode; /* Mode of link, if link */ mode_t cf_mode; /* Mode of remote file, not link */ uid_t cf_uid; /* User ID of the file's owner */ gid_t cf_gid; /* Group ID of the file's group */ off_t cf_size; /* File size in bytes */ time_t cf_atime; /* Time of last access */ time_t cf_mtime; /* Time of last data modification */ time_t cf_ctime; /* Time of last file status change */ char cf_makeholes; /* what we need to know from blksize and blks */ char *cf_readlink; /* link value or NULL */ int cf_failed; /* stat returned -1 */ int cf_nlink; /* Number of hard links */ int cf_ino; /* inode number on server */ dev_t cf_dev; /* device number */ Stat *next; }; void DestroyStatCache(Stat *data); int cf_remote_stat(AgentConnection *conn, bool encrypt, const char *file, struct stat *statbuf, const char *stattype); const Stat *StatCacheLookup(const AgentConnection *conn, const char *file_name, const char *server_name); mode_t FileTypeToMode(const FileType type); bool StatParseResponse(const char *const buf, Stat *statbuf); #endif cfengine-3.24.2/libcfnet/misc.c0000644000000000000000000000305215010704253016240 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include /* GetErrorStr */ int cf_closesocket(int sd) { int res; #ifdef __MINGW32__ res = closesocket(sd); if (res == SOCKET_ERROR) { Log(LOG_LEVEL_VERBOSE, "Failed to close socket (closesocket: %s)", GetErrorStrFromCode(WSAGetLastError())); } #else res = close(sd); if (res == -1) { Log(LOG_LEVEL_VERBOSE, "Failed to close socket (close: %s)", GetErrorStr()); } #endif return res; } cfengine-3.24.2/libcfnet/Makefile.in0000644000000000000000000006016715010704300017211 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = libcfnet ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcfnet_la_LIBADD = am_libcfnet_la_OBJECTS = addr_lib.lo client_protocol.lo client_code.lo \ classic.lo communication.lo connection_info.lo conn_cache.lo \ key.lo misc.lo net.lo policy_server.lo protocol.lo \ protocol_version.lo server_code.lo stat_cache.lo tls_client.lo \ tls_generic.lo libcfnet_la_OBJECTS = $(am_libcfnet_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcfnet_la_SOURCES) DIST_SOURCES = $(libcfnet_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcfnet.la AM_CPPFLAGS = -I$(top_srcdir)/libntech/libutils \ -I$(top_srcdir)/libpromises \ $(PCRE2_CPPFLAGS) \ $(SYSTEMD_SOCKET_CPPFLAGS) \ $(OPENSSL_CPPFLAGS) libcfnet_la_SOURCES = \ addr_lib.c addr_lib.h \ client_protocol.c client_protocol.h cfnet.h\ client_code.c client_code.h \ classic.c classic.h \ communication.c communication.h \ connection_info.c connection_info.h \ conn_cache.c conn_cache.h \ key.c key.h \ misc.c \ net.c net.h \ policy_server.c policy_server.h \ protocol.c protocol.h \ protocol_version.c protocol_version.h \ server_code.c server_code.h \ stat_cache.c stat_cache.h \ tls_client.c tls_client.h \ tls_generic.c tls_generic.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libcfnet/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libcfnet/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcfnet.la: $(libcfnet_la_OBJECTS) $(libcfnet_la_DEPENDENCIES) $(EXTRA_libcfnet_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcfnet_la_OBJECTS) $(libcfnet_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addr_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/classic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_code.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_protocol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/communication.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn_cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection_info.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/policy_server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol_version.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_code.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stat_cache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_generic.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/libcfnet/conn_cache.h0000644000000000000000000000325515010704253017377 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_CONN_CACHE_H #define CFENGINE_CONN_CACHE_H #include /* AgentConnection */ enum ConnCacheStatus { CONNCACHE_STATUS_IDLE = 0, CONNCACHE_STATUS_BUSY, CONNCACHE_STATUS_OFFLINE, CONNCACHE_STATUS_BROKEN, }; void ConnCache_Init(void); void ConnCache_Destroy(void); AgentConnection *ConnCache_FindIdleMarkBusy(const char *server, const char *port, ConnectionFlags flags); void ConnCache_MarkNotBusy(AgentConnection *conn); void ConnCache_Add(AgentConnection *conn, enum ConnCacheStatus status); void ConnCache_IsBusy(AgentConnection *conn); #endif cfengine-3.24.2/libcfnet/protocol.h0000644000000000000000000001361715010704253017163 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_PROTOCOL_H #define CFENGINE_PROTOCOL_H #include #include #include // ProtocolVersion /** * Receives a directory listing from a remote host. * * The server will use "/var/cfengine" as working directory if absolute path * is not specified. The server sends the directory entries as a string * separated by NUL-bytes, and ending with the magic string CFD_TERMINATOR. * * The function shall fail if connection is not established, or if the server * gives a bad response (denoted by a message preceded by "BAD"). * * @param [in] conn The connection to use * @param [in] path Path on remote host * @return A sequence of filenames in the requested directory on success, NULL * on failure. * * Example (for printing each directory entry): * @code * AgentConnection *conn = ServerConnection("127.0.0.1", "666", ...); * Seq *dir = ProtocolOpenDir(conn, "masterfiles"); * for (int i = 0; i < SeqLength(dir); i++) * { * char *entry = SeqAt(i); * printf("%s\n", entry); * } * @endcode * * In the protocol, this will look like this on the server side: * Received: OPENDIR masterfiles * Translated to: OPENDIR /var/cfengine/masterfiles * Sends string: * ".\0..\0cfe_internal\0cf_promises_release_id\0... * ...templates\0update.cf\0" CFD_TERMINATOR */ Seq *ProtocolOpenDir(AgentConnection *conn, const char *path); /** * Receives a file from a remote host. * * The server will use "/var/cfengine" as working directory if absolute path * is not specified. The client will send a request that looks like this: * `GET ` * * `buf_size` is the local buffer size: how much of the file to receive in * each transaction. It should be aligned to block size (which is usually * 4096), but currently the protocol only allows _exactly_ 4095 bytes per * transaction. * * The function shall fail if connection is not established, or if the server * gives a bad response (denoted by a message preceded by "BAD"). * * @param [in] conn The connection to use * @param [in] remote_path Path on remote host * @param [in] local_path Path of received file * @param [in] file_size Size of file to get * @param [in] perms Permissions of local file * @return True if file was successfully transferred, false otherwise * * Example (for printing each directory entry): * @code * AgentConnection *conn = ServerConnection("127.0.0.1", "666", ...); * bool got_file = ProtocolGet(conn, "masterfiles/update.cf", * "update.cf", CF_MSGSIZE, 0644); * if (got_file) * { * struct stat sb; * stat("update.cf", &sb); * printf("This file is %ld big!\n", sb.st_size); * } * @endcode * * In the protocol, this will look like this on the server side: * Received: GET masterfiles/update.cf * Translated to: GET /var/cfengine/masterfiles/update.cf */ bool ProtocolGet(AgentConnection *conn, const char *remote_path, const char *local_path, const uint32_t file_size, int perms); /** * Receives a file from a remote host, see documentation for #ProtocolGet * * This funtion will first stat the remote path before attempting to receive * it. */ bool ProtocolStatGet(AgentConnection *conn, const char *remote_path, const char *local_path, int perms); /** * Receives statistics about a remote file. * * This is a cacheless version of #cf_remote_stat from stat_cache.c. This * only supports sending with the latest cfnet protocol. * * When the `STAT` request is sent, it is sent together with the current time * since the Epoch given by the `time` syscall denoted by `SYNCH `. If * the server is set to deny bad clocks (which is default), it will reject * `STAT` requests from hosts where the clocks differ too much. * * When the server accepts the `STAT` request, it will send each field of the * `Stat` struct from `stat_cache.h` as numbers delimited by spaces in a * single string. Since the `Stat` struct is not cached, its fields are * transferred to the \p stat_buf parameter. * * Example * @code * AgentConnection *conn = ServerConnection("127.0.0.1", "666", ...); * struct stat stat_buf; * ProtocolStat(conn, "masterfiles/update.cf", &stat_buf); * assert((stat_buf.st_mode & S_IFMT) == S_IFREG); * @endcode * * This is how the above example looks on the server side: * Received: SYNCH 12356789 STAT masterfiles/update.cf * Translated to: STAT /var/cfengine/masterfiles/update.cf * Sends string: * "OK: 0 33188 0 ..." etc. * * @param [in] conn The connection to use * @param [in] remote_path Path on remote host * @param [out] stat_buf Where to store statistics * @return true on success, false on failure. */ bool ProtocolStat(AgentConnection *conn, const char *remote_path, struct stat *stat_buf); #endif cfengine-3.24.2/libcfnet/classic.h0000644000000000000000000000225515010704253016737 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CLASSIC_H #define CLASSIC_H #include int RecvSocketStream(int sd, char *buffer, int toget); int SendSocketStream(int sd, const char buffer[CF_BUFSIZE], int tosend); #endif // CLASSIC_H cfengine-3.24.2/libcfnet/classic.c0000644000000000000000000001162415010704253016732 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include static bool LastRecvTimedOut(void) { #ifndef __MINGW32__ if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { return true; } #else int lasterror = GetLastError(); if (lasterror == EAGAIN || lasterror == WSAEWOULDBLOCK) { return true; } #endif return false; } /** * @brief Receive up to #toget bytes, plus a '\0', into buffer from sd. * @param sd Socket descriptor * @param buffer Buffer into which to read data * @param toget Number of bytes to read; a '\0' shall be written after * the data; buffer must have space for that. * * @note Writes up to buffer[toget] (toget + 1 bytes total) * @return number of bytes actually received, must be equal to #toget * -1 in case of timeout or error - socket is unusable * 0 connection was closed (not an error, that's how clients * normally terminate) * CF_BUFSIZE - 1 || toget <= 0) { Log(LOG_LEVEL_ERR, "Bad software request to receive %d bytes", toget); return -1; } /* Repeat recv() until we get "toget" bytes. */ for (already = 0; already < toget; already += got) { got = recv(sd, buffer + already, toget - already, 0); if (got == -1) { if (errno != EINTR) /* recv() again in case of signal */ { if (LastRecvTimedOut()) { Log(LOG_LEVEL_ERR, "Receive timeout" " (received=%dB, expecting=%dB) (recv: %s)", already, toget, GetErrorStr()); Log(LOG_LEVEL_VERBOSE, "Consider increasing body agent control" " \"default_timeout\" setting"); /* Shutdown() TCP connection despite of EAGAIN error, in * order to avoid receiving this delayed response later on * (Redmine #6027). */ shutdown(sd, SHUT_RDWR); } else { Log(LOG_LEVEL_ERR, "Couldn't receive (recv: %s)", GetErrorStr()); } return -1; } } else if (got == 0) { Log(LOG_LEVEL_VERBOSE, "Peer has closed the connection"); buffer[already] = '\0'; return 0; } } assert(already == toget); buffer[already] = '\0'; return already; } /*************************************************************************/ /** * @brief Send #tosend bytes from buffer to sd. * @param sd Socket descriptor * @param buffer Buffer from which to read data * @param tosend Number of bytes to write. * * @return number of bytes actually sent, must be equal to #tosend * -1 in case of timeout or error - socket is unusable * -1 also in case of early proper connection close * 0 NEVER * /* struct ConnectionInfo */ #include #include #include #include /* RecvSocketStream */ #include /* SendTransaction,ReceiveTransaction */ #include /* ERR_get_error */ #include /* ProtocolIsUndefined() */ #include /* TLSTry */ #include /* TLSVerifyPeer */ #include #include #include /* AllocateDirentForFilename */ #include #include /* CryptoInitialize,SavePublicKey,EncryptString */ #include #include /* HashFile */ #include /* ThreadLock */ #include /* FullWrite,safe_open */ #include /* MemSpan,MemSpanInverse */ #include /* ProgrammingError */ #include /* PRINTSIZE */ #include /* LastSaw */ #define CFENGINE_SERVICE "cfengine" /** * Initialize client's network library. */ bool cfnet_init(const char *tls_min_version, const char *ciphers) { CryptoInitialize(); return TLSClientInitialize(tls_min_version, ciphers); } void cfnet_shut() { TLSDeInitialize(); CryptoDeInitialize(); } bool cfnet_IsInitialized() { return TLSClientIsInitialized(); } #define MAX_PORT_NUMBER 65535 /* 2^16 - 1 */ /* These should only be modified by the two functions below! */ int CFENGINE_PORT = 5308; char CFENGINE_PORT_STR[16] = "5308"; void DetermineCfenginePort() { nt_static_assert(sizeof(CFENGINE_PORT_STR) >= PRINTSIZE(CFENGINE_PORT)); /* ... but we leave more space, as service names can be longer */ errno = 0; struct servent *server = getservbyname(CFENGINE_SERVICE, "tcp"); if (server != NULL) { CFENGINE_PORT = ntohs(server->s_port); snprintf(CFENGINE_PORT_STR, sizeof(CFENGINE_PORT_STR), "%d", CFENGINE_PORT); } else if (errno == 0) { Log(LOG_LEVEL_VERBOSE, "No registered cfengine service, using default"); } else { Log(LOG_LEVEL_VERBOSE, "Unable to query services database, using default. (getservbyname: %s)", GetErrorStr()); } Log(LOG_LEVEL_VERBOSE, "Default port for cfengine is %d", CFENGINE_PORT); } bool SetCfenginePort(const char *port_str) { /* parse and store the new value (use the string representation of the * parsed value because it may potentially be better/nicer/more * canonical) */ long int port; int ret = StringToLong(port_str, &port); if (ret != 0) { LogStringToLongError(port_str, "CFENGINE_PORT", ret); return false; } if (port > MAX_PORT_NUMBER) { Log(LOG_LEVEL_ERR, "Invalid port number given, must be <= %d", MAX_PORT_NUMBER); return false; } CFENGINE_PORT = port; Log(LOG_LEVEL_VERBOSE, "Setting default port number to %d", CFENGINE_PORT); xsnprintf(CFENGINE_PORT_STR, sizeof(CFENGINE_PORT_STR), "%d", CFENGINE_PORT); return true; } /** * @return 1 success, 0 auth/ID error, -1 other error */ int TLSConnect(ConnectionInfo *conn_info, bool trust_server, const Rlist *restrict_keys, const char *ipaddr, const char *username) { int ret; ret = TLSTry(conn_info); if (ret == -1) { return -1; } /* TODO username is local, fix. */ ret = TLSVerifyPeer(conn_info, ipaddr, username); if (ret == -1) /* error */ { return -1; } const char *key_hash = KeyPrintableHash(conn_info->remote_key); // If restrict_key is defined, check if the key is there if (restrict_keys != NULL) { if (RlistContainsString(restrict_keys, key_hash)) { Log(LOG_LEVEL_VERBOSE, "Server key in allowed list: %s", key_hash); } else { Log(LOG_LEVEL_ERR, "Server key not in allowed keys, server presented: %s", key_hash); return -1; } } if (ret == 1) { Log(LOG_LEVEL_VERBOSE, "Server is TRUSTED, received key '%s' MATCHES stored one.", key_hash); } else /* ret == 0 */ { if (trust_server) /* We're most probably bootstrapping. */ { Log(LOG_LEVEL_NOTICE, "Trusting new key: %s", key_hash); SavePublicKey(username, KeyPrintableHash(conn_info->remote_key), KeyRSA(conn_info->remote_key)); } else { Log(LOG_LEVEL_ERR, "TRUST FAILED, server presented untrusted key: %s", key_hash); return -1; } } /* TLS CONNECTION IS ESTABLISHED, negotiate protocol version and send * identification data. */ ret = TLSClientIdentificationDialog(conn_info, username); return ret; } /** * @NOTE if #flags.protocol_version is CF_PROTOCOL_UNDEFINED, then latest * protocol is used by default. */ AgentConnection *ServerConnection(const char *server, const char *port, const Rlist *restrict_keys, unsigned int connect_timeout, ConnectionFlags flags, int *err) { AgentConnection *conn = NULL; int ret; *err = 0; conn = NewAgentConn(server, port, flags); #if !defined(__MINGW32__) && !defined(__ANDROID__) signal(SIGPIPE, SIG_IGN); sigset_t signal_mask; sigemptyset(&signal_mask); sigaddset(&signal_mask, SIGPIPE); pthread_sigmask(SIG_BLOCK, &signal_mask, NULL); /* FIXME: username is local */ GetCurrentUserName(conn->username, sizeof(conn->username)); #else /* Always say "root" if windows or termux. */ strlcpy(conn->username, "root", sizeof(conn->username)); #endif if (port == NULL || *port == '\0') { port = CFENGINE_PORT_STR; } char txtaddr[CF_MAX_IP_LEN] = ""; conn->conn_info->sd = SocketConnect(server, port, connect_timeout, flags.force_ipv4, txtaddr, sizeof(txtaddr)); if (conn->conn_info->sd == -1) { Log(LOG_LEVEL_INFO, "No server is responding on port: %s", port); DisconnectServer(conn); *err = -1; return NULL; } nt_static_assert(sizeof(conn->remoteip) >= sizeof(txtaddr)); strcpy(conn->remoteip, txtaddr); ProtocolVersion protocol_version = flags.protocol_version; if (ProtocolIsUndefined(protocol_version)) { protocol_version = CF_PROTOCOL_LATEST; } if (ProtocolIsTLS(protocol_version)) { /* Set the version to request during protocol negotiation. After * TLSConnect() it will have the version we finally ended up with. */ conn->conn_info->protocol = protocol_version; ret = TLSConnect(conn->conn_info, flags.trust_server, restrict_keys, conn->remoteip, conn->username); if (ret == -1) /* Error */ { DisconnectServer(conn); *err = -1; return NULL; } else if (ret == 0) /* Auth/ID error */ { DisconnectServer(conn); errno = EPERM; *err = -2; return NULL; } assert(ret == 1); conn->conn_info->status = CONNECTIONINFO_STATUS_ESTABLISHED; if (!flags.off_the_record) { LastSaw1(conn->remoteip, KeyPrintableHash(conn->conn_info->remote_key), LAST_SEEN_ROLE_CONNECT); } } else if (ProtocolIsClassic(protocol_version)) { conn->conn_info->protocol = CF_PROTOCOL_CLASSIC; conn->encryption_type = CfEnterpriseOptions(); if (!IdentifyAgent(conn->conn_info)) { Log(LOG_LEVEL_ERR, "Id-authentication for '%s' failed", VFQNAME); errno = EPERM; DisconnectServer(conn); *err = -2; // auth err return NULL; } if (!AuthenticateAgent(conn, flags.trust_server)) { Log(LOG_LEVEL_ERR, "Authentication dialogue with '%s' failed", server); errno = EPERM; DisconnectServer(conn); *err = -2; // auth err return NULL; } conn->conn_info->status = CONNECTIONINFO_STATUS_ESTABLISHED; } else { ProgrammingError("ServerConnection: ProtocolVersion %d!", protocol_version); } conn->authenticated = true; return conn; } /*********************************************************************/ void DisconnectServer(AgentConnection *conn) { /* Socket needs to be closed even after SSL_shutdown. */ if (conn->conn_info->sd >= 0) /* Not INVALID or OFFLINE */ { if (conn->conn_info->protocol >= CF_PROTOCOL_TLS && conn->conn_info->ssl != NULL) { SSL_shutdown(conn->conn_info->ssl); } cf_closesocket(conn->conn_info->sd); conn->conn_info->sd = SOCKET_INVALID; Log(LOG_LEVEL_VERBOSE, "Connection to %s is closed", conn->remoteip); } DeleteAgentConn(conn); } /*********************************************************************/ /* Returning NULL (an empty list) does not mean empty directory but ERROR, * since every directory has to contain at least . and .. */ Item *RemoteDirList(const char *dirname, bool encrypt, AgentConnection *conn) { char sendbuffer[CF_BUFSIZE]; char recvbuffer[CF_BUFSIZE]; char in[CF_BUFSIZE]; char out[CF_BUFSIZE]; int cipherlen = 0, tosend; if (strlen(dirname) > CF_BUFSIZE - 20) { Log(LOG_LEVEL_ERR, "Directory name too long"); return NULL; } /* We encrypt only for CLASSIC protocol. The TLS protocol is always over * encrypted layer, so it does not support encrypted (S*) commands. */ encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC; if (encrypt) { if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "Cannot do encrypted copy without keys (use cf-key)"); return NULL; } snprintf(in, CF_BUFSIZE, "OPENDIR %s", dirname); cipherlen = EncryptString(out, sizeof(out), in, strlen(in) + 1, conn->encryption_type, conn->session_key); tosend = cipherlen + CF_PROTO_OFFSET; if (tosend < 0) { ProgrammingError("RemoteDirList: tosend (%d) < 0", tosend); } else if ((unsigned long) tosend > sizeof(sendbuffer)) { ProgrammingError("RemoteDirList: tosend (%d) > sendbuffer (%zd)", tosend, sizeof(sendbuffer)); } snprintf(sendbuffer, CF_BUFSIZE - 1, "SOPENDIR %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); } else { snprintf(sendbuffer, CF_BUFSIZE, "OPENDIR %s", dirname); tosend = strlen(sendbuffer); } if (SendTransaction(conn->conn_info, sendbuffer, tosend, CF_DONE) == -1) { return NULL; } Item *start = NULL, *end = NULL; /* NULL is empty list */ while (true) { /* TODO check the CF_MORE flag, no need for CFD_TERMINATOR. */ int nbytes = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); /* If recv error or socket closed before receiving CFD_TERMINATOR. */ if (nbytes == -1) { /* TODO mark connection in the cache as closed. */ goto err; } if (encrypt) { memcpy(in, recvbuffer, nbytes); DecryptString(recvbuffer, sizeof(recvbuffer), in, nbytes, conn->encryption_type, conn->session_key); } if (recvbuffer[0] == '\0') { Log(LOG_LEVEL_ERR, "Empty%s server packet when listing directory '%s'!", (start == NULL) ? " first" : "", dirname); goto err; } if (FailedProtoReply(recvbuffer)) { Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, dirname); goto err; } if (BadProtoReply(recvbuffer)) { Log(LOG_LEVEL_INFO, "%s", recvbuffer + strlen("BAD: ")); goto err; } /* Double '\0' means end of packet. */ for (char *sp = recvbuffer; *sp != '\0'; sp += strlen(sp) + 1) { if (strcmp(sp, CFD_TERMINATOR) == 0) /* end of all packets */ { return start; } Item *ip = xcalloc(1, sizeof(Item)); ip->name = (char *) AllocateDirentForFilename(sp); if (start == NULL) /* First element */ { start = ip; end = ip; } else { end->next = ip; end = ip; } } } return start; err: /* free list */ for (Item *ip = start; ip != NULL; ip = start) { start = ip->next; free(ip->name); free(ip); } return NULL; } /*********************************************************************/ bool CompareHashNet(const char *file1, const char *file2, bool encrypt, AgentConnection *conn) { unsigned char d[EVP_MAX_MD_SIZE + 1]; char *sp; char sendbuffer[CF_BUFSIZE] = {0}; char recvbuffer[CF_BUFSIZE] = {0}; int i, tosend, cipherlen; HashFile(file2, d, CF_DEFAULT_DIGEST, false); memset(recvbuffer, 0, CF_BUFSIZE); /* We encrypt only for CLASSIC protocol. The TLS protocol is always over * encrypted layer, so it does not support encrypted (S*) commands. */ encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC; if (encrypt) { char in[CF_BUFSIZE] = {0}; char out[CF_BUFSIZE] = {0}; snprintf(in, CF_BUFSIZE, "MD5 %s", file1); sp = in + strlen(in) + CF_SMALL_OFFSET; for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++) { *sp++ = d[i]; } cipherlen = EncryptString(out, sizeof(out), in, strlen(in) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN, conn->encryption_type, conn->session_key); tosend = cipherlen + CF_PROTO_OFFSET; if (tosend < 0) { ProgrammingError("CompareHashNet: tosend (%d) < 0", tosend); } else if ((unsigned long) tosend > sizeof(sendbuffer)) { ProgrammingError("CompareHashNet: tosend (%d) > sendbuffer (%zd)", tosend, sizeof(sendbuffer)); } snprintf(sendbuffer, CF_BUFSIZE, "SMD5 %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); } else { snprintf(sendbuffer, CF_BUFSIZE, "MD5 %s", file1); sp = sendbuffer + strlen(sendbuffer) + CF_SMALL_OFFSET; for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++) { *sp++ = d[i]; } tosend = strlen(sendbuffer) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN; } if (SendTransaction(conn->conn_info, sendbuffer, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Failed send. (SendTransaction: %s)", GetErrorStr()); Log(LOG_LEVEL_VERBOSE, "Networking error, assuming different checksum"); return true; } if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { /* TODO mark connection in the cache as closed. */ Log(LOG_LEVEL_ERR, "Failed receive. (ReceiveTransaction: %s)", GetErrorStr()); Log(LOG_LEVEL_VERBOSE, "No answer from host, assuming different checksum"); return true; } if (strcmp(CFD_TRUE, recvbuffer) == 0) { return true; /* mismatch */ } else { return false; } /* Not reached */ } /*********************************************************************/ static bool EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size, AgentConnection *conn) { int blocksize = 2048, n_read = 0, plainlen, more = true, finlen; int tosend, cipherlen = 0; char *buf, in[CF_BUFSIZE], out[CF_BUFSIZE], workbuf[CF_BUFSIZE], cfchangedstr[265]; unsigned char iv[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; snprintf(cfchangedstr, 255, "%s%s", CF_CHANGEDSTR1, CF_CHANGEDSTR2); if ((strlen(dest) > CF_BUFSIZE - 20)) { Log(LOG_LEVEL_ERR, "Filename too long"); return false; } unlink(dest); /* To avoid link attacks */ int dd = safe_open_create_perms(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY, CF_PERMS_DEFAULT); if (dd == -1) { Log(LOG_LEVEL_ERR, "Copy from server '%s' to destination '%s' failed (open: %s)", conn->this_server, dest, GetErrorStr()); unlink(dest); return false; } if (size == 0) { // No sense in copying an empty file close(dd); return true; } workbuf[0] = '\0'; snprintf(in, CF_BUFSIZE - CF_PROTO_OFFSET, "GET dummykey %s", source); cipherlen = EncryptString(out, sizeof(out), in, strlen(in) + 1, conn->encryption_type, conn->session_key); tosend = cipherlen + CF_PROTO_OFFSET; if (tosend < 0) { ProgrammingError("EncryptCopyRegularFileNet: tosend (%d) < 0", tosend); } else if ((unsigned long) tosend > sizeof(workbuf)) { ProgrammingError("EncryptCopyRegularFileNet: tosend (%d) > workbuf (%zd)", tosend, sizeof(workbuf)); } snprintf(workbuf, CF_BUFSIZE, "SGET %4d %4d", cipherlen, blocksize); memcpy(workbuf + CF_PROTO_OFFSET, out, cipherlen); /* Send proposition C0 - query */ if (SendTransaction(conn->conn_info, workbuf, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Couldn't send data. (SendTransaction: %s)", GetErrorStr()); close(dd); return false; } EVP_CIPHER_CTX *crypto_ctx = EVP_CIPHER_CTX_new(); if (crypto_ctx == NULL) { Log(LOG_LEVEL_ERR, "Failed to allocate cipher: %s", TLSErrorString(ERR_get_error())); close(dd); return false; } buf = xmalloc(CF_BUFSIZE + sizeof(int)); bool last_write_made_hole = false; size_t n_wrote_total = 0; while (more) { if ((cipherlen = ReceiveTransaction(conn->conn_info, buf, &more)) == -1) { close(dd); free(buf); EVP_CIPHER_CTX_free(crypto_ctx); return false; } /* If the first thing we get is an error message, break. */ if (n_wrote_total == 0 && strncmp(buf + CF_INBAND_OFFSET, CF_FAILEDSTR, strlen(CF_FAILEDSTR)) == 0) { Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, source); close(dd); free(buf); EVP_CIPHER_CTX_free(crypto_ctx); return false; } if (strncmp(buf + CF_INBAND_OFFSET, cfchangedstr, strlen(cfchangedstr)) == 0) { Log(LOG_LEVEL_INFO, "Source '%s:%s' changed while copying", conn->this_server, source); close(dd); free(buf); EVP_CIPHER_CTX_free(crypto_ctx); return false; } EVP_DecryptInit_ex(crypto_ctx, CfengineCipher(CfEnterpriseOptions()), NULL, conn->session_key, iv); if (!EVP_DecryptUpdate(crypto_ctx, (unsigned char *) workbuf, &plainlen, (unsigned char *) buf, cipherlen)) { close(dd); free(buf); EVP_CIPHER_CTX_free(crypto_ctx); return false; } if (!EVP_DecryptFinal_ex(crypto_ctx, (unsigned char *) workbuf + plainlen, &finlen)) { close(dd); free(buf); EVP_CIPHER_CTX_free(crypto_ctx); return false; } n_read = plainlen + finlen; bool w_ok = FileSparseWrite(dd, workbuf, n_read, &last_write_made_hole); if (!w_ok) { Log(LOG_LEVEL_ERR, "Local disk write failed copying '%s:%s' to '%s'", conn->this_server, source, dest); free(buf); unlink(dest); close(dd); conn->error = true; EVP_CIPHER_CTX_free(crypto_ctx); return false; } n_wrote_total += n_read; } const bool do_sync = false; bool ret = FileSparseClose(dd, dest, do_sync, n_wrote_total, last_write_made_hole); if (!ret) { unlink(dest); free(buf); EVP_CIPHER_CTX_free(crypto_ctx); return false; } free(buf); EVP_CIPHER_CTX_free(crypto_ctx); return true; } static void FlushFileStream(int sd, int toget) { int i; char buffer[2]; Log(LOG_LEVEL_VERBOSE, "Flushing rest of file...%d bytes", toget); for (i = 0; i < toget; i++) { recv(sd, buffer, 1, 0); /* flush to end of current file */ } } /* TODO finalise socket or TLS session in all cases that this function fails * and the transaction protocol is out of sync. */ bool CopyRegularFileNet(const char *source, const char *dest, off_t size, bool encrypt, AgentConnection *conn, mode_t mode) { char *buf, workbuf[CF_BUFSIZE], cfchangedstr[265]; const int buf_size = 2048; /* We encrypt only for CLASSIC protocol. The TLS protocol is always over * encrypted layer, so it does not support encrypted (S*) commands. */ encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC; if (encrypt) { return EncryptCopyRegularFileNet(source, dest, size, conn); } snprintf(cfchangedstr, 255, "%s%s", CF_CHANGEDSTR1, CF_CHANGEDSTR2); if ((strlen(dest) > CF_BUFSIZE - 20)) { Log(LOG_LEVEL_ERR, "Filename too long"); return false; } unlink(dest); /* To avoid link attacks */ int dd = safe_open_create_perms(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY, mode); if (dd == -1) { Log(LOG_LEVEL_ERR, "Copy from server '%s' to destination '%s' failed (open: %s)", conn->this_server, dest, GetErrorStr()); unlink(dest); return false; } workbuf[0] = '\0'; int tosend = snprintf(workbuf, CF_BUFSIZE, "GET %d %s", buf_size, source); if (tosend <= 0 || tosend >= CF_BUFSIZE) { Log(LOG_LEVEL_ERR, "Failed to compose GET command for file %s", source); close(dd); return false; } /* Send proposition C0 */ if (SendTransaction(conn->conn_info, workbuf, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Couldn't send GET command"); close(dd); return false; } buf = xmalloc(CF_BUFSIZE + sizeof(int)); /* Note CF_BUFSIZE not buf_size !! */ Log(LOG_LEVEL_VERBOSE, "Copying remote file '%s:%s', expecting %jd bytes", conn->this_server, source, (intmax_t)size); int n_wrote_total = 0; bool last_write_made_hole = false; while (n_wrote_total < size) { int toget = MIN(size - n_wrote_total, buf_size); assert(toget > 0); /* Stage C1 - receive */ int n_read; const ProtocolVersion version = conn->conn_info->protocol; if (ProtocolIsClassic(version)) { n_read = RecvSocketStream(conn->conn_info->sd, buf, toget); } else if (ProtocolIsTLS(version)) { n_read = TLSRecv(conn->conn_info->ssl, buf, toget); } else { UnexpectedError("CopyRegularFileNet: ProtocolVersion %d!", conn->conn_info->protocol); n_read = -1; } /* TODO what if 0 < n_read < toget? Might happen with TLS. */ if (n_read <= 0) { /* This may happen on race conditions, where the file has shrunk * since we asked for its size in SYNCH ... STAT source */ Log(LOG_LEVEL_ERR, "Error in client-server stream, has %s:%s shrunk? (code %d)", conn->this_server, source, n_read); close(dd); free(buf); return false; } /* If the first thing we get is an error message, break. */ if (n_wrote_total == 0 && strncmp(buf, CF_FAILEDSTR, strlen(CF_FAILEDSTR)) == 0) { Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, source); close(dd); free(buf); return false; } if (strncmp(buf, cfchangedstr, strlen(cfchangedstr)) == 0) { Log(LOG_LEVEL_INFO, "Source '%s:%s' changed while copying", conn->this_server, source); close(dd); free(buf); return false; } /* Check for mismatch between encryption here and on server. */ int value = -1; sscanf(buf, "t %d", &value); if ((value > 0) && (strncmp(buf + CF_INBAND_OFFSET, "BAD: ", 5) == 0)) { Log(LOG_LEVEL_INFO, "Network access to cleartext '%s:%s' denied", conn->this_server, source); close(dd); free(buf); return false; } bool w_ok = FileSparseWrite(dd, buf, n_read, &last_write_made_hole); if (!w_ok) { Log(LOG_LEVEL_ERR, "Local disk write failed copying '%s:%s' to '%s'", conn->this_server, source, dest); free(buf); unlink(dest); close(dd); FlushFileStream(conn->conn_info->sd, size - n_wrote_total - n_read); conn->error = true; return false; } n_wrote_total += n_read; } const bool do_sync = false; bool ret = FileSparseClose(dd, dest, do_sync, n_wrote_total, last_write_made_hole); if (!ret) { unlink(dest); free(buf); FlushFileStream(conn->conn_info->sd, size - n_wrote_total); return false; } free(buf); return true; } cfengine-3.24.2/libcfnet/policy_server.h0000644000000000000000000000352015010704253020177 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /** @file * @brief Access to Policy Server IP Address, hostname and port number. * * Provides a simple get/set interface for the policy server variables. * Does hostname resolution behind the scenes. */ #ifndef CFENGINE_POLICYSERVER_H #define CFENGINE_POLICYSERVER_H #include // GET/SET FUNCTIONS: void PolicyServerSet(const char *new_policy_server); const char *PolicyServerGet(); const char *PolicyServerGetIP(); const char *PolicyServerGetHost(); const char *PolicyServerGetPort(); // POLICY SERVER FILE FUNCTIONS: char* PolicyServerReadFile(const char *workdir); bool PolicyServerParseFile(const char *workdir, char **host, char **port); bool PolicyServerLookUpFile(const char *workdir, char **ipaddr, char **port); bool PolicyServerWriteFile(const char *workdir, const char *new_policy_server); bool PolicyServerRemoveFile(const char *workdir); #endif cfengine-3.24.2/libcfnet/net.h0000644000000000000000000000340615010704253016103 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* Low Level networking routines. */ #ifndef CFENGINE_NET_H #define CFENGINE_NET_H #include extern uint32_t bwlimit_kbytes; int SendTransaction(ConnectionInfo *conn_info, const char *buffer, int len, char status); int ReceiveTransaction(ConnectionInfo *conn_info, char *buffer, int *more); int SetReceiveTimeout(int fd, unsigned long ms); int SocketConnect(const char *host, const char *port, unsigned int connect_timeout, bool force_ipv4, char *txtaddr, size_t txtaddr_size); /** * @NOTE DO NOT USE THIS FUNCTION. The only reason it is non-static is because * of a separate implementation for windows in Enterprise. */ bool TryConnect(int sd, unsigned long timeout_ms, const struct sockaddr *sa, socklen_t sa_len); #endif cfengine-3.24.2/libcfnet/key.c0000644000000000000000000000523115010704253016076 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ // platform.h / config.h / bool.h has bool type // which is needed before including key.h // TODO: Fix this, including key.h shouldn't require bool type defined #include #include #include struct Key { RSA *key; Hash *hash; }; Key *KeyNew(RSA *rsa, HashMethod method) { if (!rsa) { return NULL; } Key *key = xmalloc (sizeof(Key)); key->key = rsa; /* Hash the key */ key->hash = HashNewFromKey(rsa, method); if (key->hash == NULL) { free (key); return NULL; } return key; } void KeyDestroy(Key **key) { if (!key || !*key) { return; } if ((*key)->key) { RSA_free((*key)->key); } HashDestroy(&(*key)->hash); free (*key); *key = NULL; } RSA *KeyRSA(const Key *key) { return key ? key->key : NULL; } const unsigned char *KeyBinaryHash(const Key *key, unsigned int *length) { if (!key || !length) { return NULL; } return HashData(key->hash, length); } const char *KeyPrintableHash(const Key *key) { return key ? HashPrintable(key->hash) : NULL; } HashMethod KeyHashMethod(const Key *key) { return key ? HashType(key->hash) : HASH_METHOD_NONE; } int KeySetHashMethod(Key *key, HashMethod method) { if (!key) { return -1; } /* We calculate the new hash before changing the value, in case there is an error. */ Hash *hash = NULL; hash = HashNewFromKey(key->key, method); if (hash == NULL) { return -1; } if (key->hash) { HashDestroy(&key->hash); } key->hash = hash; return 0; } const Hash *KeyData(Key *key) { return key ? key->hash : NULL; } cfengine-3.24.2/libcfnet/tls_client.h0000644000000000000000000000310315010704253017447 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #ifndef CFENGINE_TLS_CLIENT_H #define CFENGINE_TLS_CLIENT_H #include #include bool TLSClientInitialize(const char *tls_min_version, const char *ciphers); void TLSDeInitialize(void); bool TLSClientIsInitialized(void); int TLSClientIdentificationDialog(ConnectionInfo *conn_info, const char *username); int TLSTry(ConnectionInfo *conn_info); /* Exported for enterprise. */ int TLSConnect(ConnectionInfo *conn_info, bool trust_server, const Rlist *restrict_keys, const char *ipaddr, const char *username); #endif cfengine-3.24.2/libcfnet/addr_lib.c0000644000000000000000000003637515010704253017063 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #define CF_ADDRSIZE 128 /* Match two IP strings - with : or . in hex or decimal s1 is the test string, and s2 is the reference e.g. FuzzySetMatch("128.39.74.10/23","128.39.75.56") == 0 Returns 0 on match. */ /* TODO rename to AddrSubnetMatch() */ int FuzzySetMatch(const char *s1, const char *s2) { short isCIDR = false, isrange = false, isv6 = false, isv4 = false; char address[CF_ADDRSIZE]; if (strcmp(s1, s2) == 0) { return 0; } if (strstr(s1, "/") != 0) { isCIDR = true; } if (strstr(s1, "-") != 0) { isrange = true; } if (strstr(s1, ".") != 0) { isv4 = true; } if (strstr(s1, ":") != 0) { isv6 = true; } if (strstr(s2, ".") != 0) { isv4 = true; } if (strstr(s2, ":") != 0) { isv6 = true; } if (isv4 && isv6) { /* This is just wrong */ return -1; } if (isCIDR && isrange) { Log(LOG_LEVEL_ERR, "Cannot mix CIDR notation with xxx-yyy range notation '%s'", s1); return -1; } if (!(isv6 || isv4)) { Log(LOG_LEVEL_ERR, "Not a valid address range - or not a fully qualified name '%s'", s1); return -1; } if (!(isrange || isCIDR)) { if (strlen(s2) > strlen(s1)) { if (*(s2 + strlen(s1)) != '.') { return -1; // Because xxx.1 should not match xxx.12 in the same octet } } return strncmp(s1, s2, strlen(s1)); /* do partial string match */ } if (isv4) { if (isCIDR) { struct sockaddr_in addr1, addr2; unsigned long mask; address[0] = '\0'; int ret = sscanf(s1, "%16[^/]/%lu", address, &mask); if (ret != 2 || mask > 32) { Log(LOG_LEVEL_ERR, "Invalid IPv4 CIDR: %s", s1); return -1; } else if (mask == 0) { return 0; /* /0 CIDR matches everything */ } inet_pton(AF_INET, address, &addr1.sin_addr); inet_pton(AF_INET, s2, &addr2.sin_addr); unsigned long a1 = htonl(addr1.sin_addr.s_addr); unsigned long a2 = htonl(addr2.sin_addr.s_addr); unsigned long shift = 32 - mask; assert(shift < 32); /* Undefined behaviour if 32 */ a1 = a1 >> shift; a2 = a2 >> shift; if (a1 == a2) { return 0; } else { return -1; } } else { long i, from = -1, to = -1, cmp = -1; char buffer1[64], buffer2[64]; const char *sp1 = s1; const char *sp2 = s2; for (i = 0; i < 4; i++) { buffer1[0] = '\0'; sscanf(sp1, "%63[^.]", buffer1); buffer1[63] = '\0'; if (strlen(buffer1) == 0) { break; } sp1 += strlen(buffer1) + 1; sscanf(sp2, "%63[^.]", buffer2); buffer2[63] = '\0'; sp2 += strlen(buffer2) + 1; if (strstr(buffer1, "-")) { sscanf(buffer1, "%ld-%ld", &from, &to); sscanf(buffer2, "%ld", &cmp); if ((from < 0) || (to < 0)) { Log(LOG_LEVEL_DEBUG, "Couldn't read range"); return -1; } if ((from > cmp) || (cmp > to)) { Log(LOG_LEVEL_DEBUG, "Out of range %ld > %ld > %ld, range '%s'", from, cmp, to, buffer2); return -1; } } else { sscanf(buffer1, "%ld", &from); sscanf(buffer2, "%ld", &cmp); if (from != cmp) { Log(LOG_LEVEL_DEBUG, "Unequal"); return -1; } } Log(LOG_LEVEL_DEBUG, "Matched octet '%s' with '%s'", buffer1, buffer2); } Log(LOG_LEVEL_DEBUG, "Matched IP range"); return 0; } } if (isv6) { int i; if (isCIDR) { int blocks; struct sockaddr_in6 addr1 = {0}; struct sockaddr_in6 addr2 = {0}; unsigned long mask; address[0] = '\0'; int ret = sscanf(s1, "%40[^/]/%lu", address, &mask); if (ret != 2 || mask > 128) { Log(LOG_LEVEL_ERR, "Invalid IPv6 CIDR: %s", s1); return -1; } blocks = mask / 8; if (mask % 8 != 0) { Log(LOG_LEVEL_ERR, "Cannot handle ipv6 masks which are not 8 bit multiples (fix me)"); return -1; } addr1.sin6_family = AF_INET6; inet_pton(AF_INET6, address, &addr1.sin6_addr); addr2.sin6_family = AF_INET6; inet_pton(AF_INET6, s2, &addr2.sin6_addr); for (i = 0; i < blocks; i++) /* blocks < 16 */ { if (addr1.sin6_addr.s6_addr[i] != addr2.sin6_addr.s6_addr[i]) { return -1; } } return 0; } else { long i, from = -1, to = -1, cmp = -1; char buffer1[64], buffer2[64]; const char *sp1 = s1; const char *sp2 = s2; for (i = 0; i < 8; i++) { sscanf(sp1, "%63[^:]", buffer1); buffer1[63] = '\0'; sp1 += strlen(buffer1) + 1; sscanf(sp2, "%63[^:]", buffer2); buffer2[63] = '\0'; sp2 += strlen(buffer2) + 1; if (strstr(buffer1, "-")) { sscanf(buffer1, "%lx-%lx", &from, &to); sscanf(buffer2, "%lx", &cmp); if (from < 0 || to < 0) { return -1; } if ((from >= cmp) || (cmp > to)) { Log(LOG_LEVEL_DEBUG, "%lx < %lx < %lx", from, cmp, to); return -1; } } else { sscanf(buffer1, "%ld", &from); sscanf(buffer2, "%ld", &cmp); if (from != cmp) { return -1; } } } return 0; } } return -1; } bool FuzzyHostParse(const char *arg2) { long start = -1, end = -1; int n; n = sscanf(arg2, "%ld-%ld", &start, &end); if (n != 2) { Log(LOG_LEVEL_ERR, "HostRange syntax error: second arg should have X-Y format where X and Y are decimal numbers"); return false; } return true; } int FuzzyHostMatch(const char *arg0, const char *arg1, const char *refhost) { char *sp, refbase[1024]; long cmp = -1, start = -1, end = -1; char buf1[CF_BUFSIZE], buf2[CF_BUFSIZE]; strlcpy(refbase, refhost, sizeof(refbase)); sp = refbase + strlen(refbase) - 1; while (isdigit((int) *sp)) { sp--; } sp++; sscanf(sp, "%ld", &cmp); *sp = '\0'; if (cmp < 0) { return 1; } if (strlen(refbase) == 0) { return 1; } sscanf(arg1, "%ld-%ld", &start, &end); if ((cmp < start) || (cmp > end)) { return 1; } strlcpy(buf1, refbase, CF_BUFSIZE); strlcpy(buf2, arg0, CF_BUFSIZE); ToLowerStrInplace(buf1); ToLowerStrInplace(buf2); if (strcmp(buf1, buf2) != 0) { return 1; } return 0; } bool FuzzyMatchParse(const char *s) { short isCIDR = false, isrange = false, isv6 = false, isv4 = false, isADDR = false; char address[CF_ADDRSIZE]; int mask, count = 0; for (const char *sp = s; *sp != '\0'; sp++) /* Is this an address or hostname */ { if (!isxdigit((int) *sp)) { isADDR = false; break; } if (*sp == ':') /* Catches any ipv6 address */ { isADDR = true; break; } if (isdigit((int) *sp)) /* catch non-ipv4 address - no more than 3 digits */ { count++; if (count > 3) { isADDR = false; break; } } else { count = 0; } } if (!isADDR) { return true; } if (strstr(s, "/") != 0) { isCIDR = true; } if (strstr(s, "-") != 0) { isrange = true; } if (strstr(s, ".") != 0) { isv4 = true; } if (strstr(s, ":") != 0) { isv6 = true; } if (isv4 && isv6) { Log(LOG_LEVEL_ERR, "Mixture of IPv6 and IPv4 addresses"); return false; } if (isCIDR && isrange) { Log(LOG_LEVEL_ERR, "Cannot mix CIDR notation with xx-yy range notation"); return false; } if (isv4 && isCIDR) { if (strlen(s) > 4 + 3 * 4 + 1 + 2) /* xxx.yyy.zzz.mmm/cc */ { Log(LOG_LEVEL_ERR, "IPv4 address looks too long"); return false; } address[0] = '\0'; mask = 0; sscanf(s, "%16[^/]/%d", address, &mask); if (mask < 8) { Log(LOG_LEVEL_ERR, "Mask value %d in '%s' is less than 8", mask, s); return false; } if (mask > 30) { Log(LOG_LEVEL_ERR, "Mask value %d in '%s' is silly (> 30)", mask, s); return false; } } if (isv4 && isrange) { long i, from = -1, to = -1; char buffer1[64]; const char *sp1 = s; for (i = 0; i < 4; i++) { buffer1[0] = '\0'; sscanf(sp1, "%63[^.]", buffer1); sp1 += strlen(buffer1) + 1; if (strstr(buffer1, "-")) { sscanf(buffer1, "%ld-%ld", &from, &to); if ((from < 0) || (to < 0)) { Log(LOG_LEVEL_ERR, "Error in IP range - looks like address, or bad hostname"); return false; } if (to < from) { Log(LOG_LEVEL_ERR, "Bad IP range"); return false; } } } } if (isv6 && isCIDR) { char address[CF_ADDRSIZE]; int mask; if (strlen(s) < 20) { Log(LOG_LEVEL_ERR, "IPv6 address looks too short"); return false; } if (strlen(s) > 42) { Log(LOG_LEVEL_ERR, "IPv6 address looks too long"); return false; } address[0] = '\0'; mask = 0; sscanf(s, "%40[^/]/%d", address, &mask); if (mask % 8 != 0) { Log(LOG_LEVEL_ERR, "Cannot handle ipv6 masks which are not 8 bit multiples (fix me)"); return false; } if (mask > 15) { Log(LOG_LEVEL_ERR, "IPv6 CIDR mask is too large"); return false; } } return true; } /** * Simple check to avoid writing to illegal memory addresses. * NOT a proper test for valid IP. */ static AddressType AddressTypeCheckValidity(char *s, AddressType address_type) { if(NULL_OR_EMPTY(s)) { return ADDRESS_TYPE_OTHER; } if(strlen(s) >= CF_MAX_IP_LEN) { return ADDRESS_TYPE_OTHER; } return address_type; } /** * Parses "hostname:port" or "[hostname]:port", where hostname may also be * IPv4 or IPv6 address string. * * @param hostname will point to the hostname, or NULL if no or empty hostname * @param port will point to the port, or NULL if no or empty port * @WARNING modifies #s to '\0' terminate hostname if followed by port. */ AddressType ParseHostPort(char *s, char **hostname, char **port) { s = TrimWhitespace(s); if ( NULL_OR_EMPTY(s) ) { *hostname = NULL; *port = NULL; return ADDRESS_TYPE_OTHER; } AddressType address_type = ADDRESS_TYPE_OTHER; char *h, *p; // hostname, port temporaries h = s; p = NULL; char *first_colon = strchr(s, ':'); char *first_dot = strchr(s, '.'); if (s[0] == '[') // [host or ip]:port { h = s + 1; p = strchr(h, ']'); if (p != NULL) { if (first_colon != NULL && first_colon < p) { address_type = ADDRESS_TYPE_IPV6; } else if (isdigit(h[0])) { address_type = ADDRESS_TYPE_IPV4; } // (else it's other by default) *p = '\0'; // '\0' terminate host name if (p[1] == ':') // move port* forward { p += 2; } } } else if (first_colon == NULL) // localhost, 192.168.0.1 { if (isdigit(h[0])) { address_type = ADDRESS_TYPE_IPV4; } } else if (first_dot == NULL || first_colon < first_dot) { // If only one colon: (cfengine.com:222 or localhost:) if (strchr(first_colon + 1, ':') == NULL) { *first_colon = '\0'; p = first_colon + 1; } else // Multiple colons: { address_type = ADDRESS_TYPE_IPV6; } } else // (first_dot < first_colon) : IPv4 or hostname { p = strchr(h, ':'); if (p != NULL) { *p = '\0'; // '\0'-terminate hostname p++; } if (isdigit(h[0])) { address_type = ADDRESS_TYPE_IPV4; } } *hostname = (h[0] != '\0') ? h : NULL; *port = (p != NULL && p[0] != '\0') ? p : NULL; return AddressTypeCheckValidity(*hostname, address_type); } cfengine-3.24.2/libcfnet/server_code.c0000644000000000000000000002240415010704253017607 0ustar00rootroot00000000000000 #include #include #include // BINDINTERFACE #include // PRINTSIZE #include // CLASSTEXT #include // GetSignalPipe #include // DoCleanupAndExit #include // isdigit #if HAVE_SYSTEMD_SD_DAEMON_H #include // sd_listen_fds #endif /* Wait up to a minute for an in-coming connection. * * @param sd The listening socket or -1. * @param tm_sec timeout in seconds * @retval > 0 In-coming connection. * @retval 0 No in-coming connection. * @retval -1 Error (other than interrupt). * @retval < -1 Interrupted while waiting. */ int WaitForIncoming(int sd, time_t tm_sec) { Log(LOG_LEVEL_DEBUG, "Waiting at incoming select..."); struct timeval timeout = { .tv_sec = tm_sec }; int signal_pipe = GetSignalPipe(); fd_set rset; FD_ZERO(&rset); FD_SET(signal_pipe, &rset); /* sd might be -1 if "listen" attribute in body server control is set * to off (enterprise feature for call-collected clients). */ if (sd != -1) { FD_SET(sd, &rset); } int result = select(MAX(sd, signal_pipe) + 1, &rset, NULL, NULL, &timeout); if (result == -1) { return (errno == EINTR) ? -2 : -1; } assert(result >= 0); /* Empty the signal pipe, it is there to only detect missed * signals in-between checking IsPendingTermination() and calling * select(). */ unsigned char buf; while (recv(signal_pipe, &buf, 1, 0) > 0) { /* skip */ } /* We have an incoming connection if select() marked sd as ready: */ if (sd != -1 && result > 0 && FD_ISSET(sd, &rset)) { return 1; } return 0; } /** * Orders 'struct addrinfo *' linked list in a descending order based on the * ai_family, prefering IPV6. */ static void OrderAddrInfoResponsesByAIfamily(struct addrinfo **first_response) { /* Below is just a trivial implementation of the Bubble-sort algorithm to * sort the linked list. */ struct addrinfo *first = *first_response; bool change = true; while (change) { change = false; struct addrinfo *item = first; struct addrinfo *prev = NULL; while (item->ai_next != NULL) { /* AF_INET6 should be greater than AF_INET, but let's not rely on * that and use a direct comparison. */ if ((item->ai_family == AF_INET) && (item->ai_next->ai_family == AF_INET6)) { struct addrinfo *orig_next = item->ai_next; item->ai_next = orig_next->ai_next; orig_next->ai_next = item; if (prev != NULL) { prev->ai_next = orig_next; } else { first = orig_next; } prev = orig_next; change = true; } else { item = item->ai_next; } } } *first_response = first; } /** * @param bind_address address to bind to or %NULL to use the default BINDINTERFACE */ static int OpenReceiverChannel(char *bind_address) { struct addrinfo *response = NULL, *ap; struct addrinfo query = { .ai_flags = AI_PASSIVE, .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; if (bind_address == NULL) { bind_address = BINDINTERFACE; } /* Listen to INADDR(6)_ANY if BINDINTERFACE unset. */ char *ptr = NULL; if (bind_address[0] != '\0') { ptr = bind_address; /* Just a quick check if the string looks like an IPv4 address to see if * we should use AI_NUMERICHOST or not. IPv6 addresses could use it too, * but they are not so easy to recognize and the proper check would be * more expensive than the optimization. */ bool is_numeric_host = true; for (char *c = ptr; is_numeric_host && (*c != '\0'); c++) { is_numeric_host = ((*c == '.') || isdigit(*c)); } if (is_numeric_host) { query.ai_flags |= AI_NUMERICHOST; } } /* Resolve listening interface. */ int gres = getaddrinfo(ptr, CFENGINE_PORT_STR, &query, &response); if (gres != 0) { Log(LOG_LEVEL_ERR, "DNS/service lookup failure. (getaddrinfo: %s)", gai_strerror(gres)); if (response) { freeaddrinfo(response); } return -1; } /* Make sure IPV6 addresses/interfaces are preferred over IPV4 ones (binding * to the IPV6 address makes connections to the IPV4 equivalent work too, in * particular for INADDR6_ANY (::) and INADDR_ANY (0.0.0.0/0). */ OrderAddrInfoResponsesByAIfamily(&response); int sd = -1; for (ap = response; ap != NULL; ap = ap->ai_next) { sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol); if (sd == -1) { if (ap->ai_family == AF_INET) { Log(LOG_LEVEL_VERBOSE, "Failed to create socket for binding to an IPV4 interface"); } else if (ap->ai_family == AF_INET6) { Log(LOG_LEVEL_VERBOSE, "Failed to create socket for binding to an IPV6 interface"); } else { Log(LOG_LEVEL_VERBOSE, "Failed to create socket for binding to an interface of ai_family %d", ap->ai_family); } continue; } #ifdef IPV6_V6ONLY /* Properly implemented getaddrinfo(AI_PASSIVE) should return the IPV6 loopback address first. Some platforms (notably Windows) don't listen to both address families when binding to it and need this flag. Some other platforms won't even honour this flag (openbsd). */ if (bind_address[0] == '\0' && ap->ai_family == AF_INET6) { int no = 0; if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &no, sizeof(no)) == -1) { Log(LOG_LEVEL_VERBOSE, "Failed to clear IPv6-only flag on listening socket" " (setsockopt: %s)", GetErrorStr()); } } #endif int yes = 1; if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { Log(LOG_LEVEL_VERBOSE, "Socket option SO_REUSEADDR was not accepted. (setsockopt: %s)", GetErrorStr()); } struct linger cflinger = { .l_onoff = 1, .l_linger = 60 }; if (setsockopt(sd, SOL_SOCKET, SO_LINGER, &cflinger, sizeof(cflinger)) == -1) { Log(LOG_LEVEL_INFO, "Socket option SO_LINGER was not accepted. (setsockopt: %s)", GetErrorStr()); } if (bind(sd, ap->ai_addr, ap->ai_addrlen) != -1) { if (WouldLog(LOG_LEVEL_DEBUG)) { /* Convert IP address to string, no DNS lookup performed. */ char txtaddr[CF_MAX_IP_LEN] = ""; getnameinfo(ap->ai_addr, ap->ai_addrlen, txtaddr, sizeof(txtaddr), NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_DEBUG, "Bound to address '%s' on '%s' = %d", txtaddr, CLASSTEXT[VSYSTEMHARDCLASS], VSYSTEMHARDCLASS); } break; } Log(LOG_LEVEL_ERR, "Could not bind server address. (bind: %s)", GetErrorStr()); cf_closesocket(sd); sd = -1; } if (sd == -1) { Log(LOG_LEVEL_ERR, "Failed to bind to all attempted addresses (bind specification: '%s'", bind_address); } assert(response != NULL); /* getaddrinfo() was successful */ freeaddrinfo(response); return sd; } /** * @param queue_size length of the queue for pending connections * @param bind_address address to bind to or %NULL to use the default BINDINTERFACE */ int InitServer(size_t queue_size, char *bind_address) { #if HAVE_SYSTEMD_SD_DAEMON_H int n = sd_listen_fds(0); if (n > 1) { Log(LOG_LEVEL_ERR, "Too many file descriptors received from systemd"); } else if (n == 1) { // we can check here that we have a socket with sd_is_socket_inet(3) // but why should we limit ourselves return SD_LISTEN_FDS_START; } else #endif // HAVE_SYSTEMD_SD_DAEMON_H { int sd = OpenReceiverChannel(bind_address); if (sd == -1) { /* More detailed info is logged in case of error in * OpenReceiverChannel() */ Log(LOG_LEVEL_ERR, "Unable to start server"); } else if (listen(sd, queue_size) == -1) { Log(LOG_LEVEL_ERR, "Failed to listen on the '%s' address (listen: %s)", bind_address, GetErrorStr()); cf_closesocket(sd); } else { return sd; } } DoCleanupAndExit(EXIT_FAILURE); } cfengine-3.24.2/libcfnet/server_code.h0000644000000000000000000000031515010704253017611 0ustar00rootroot00000000000000#ifndef CFENGINE_CFNET_SERVER_CODE_H #define CFENGINE_CFNET_SERVER_CODE_H #include int InitServer(size_t queue_size, char *bind_address); int WaitForIncoming(int sd, time_t tm_sec); #endif cfengine-3.24.2/libcfnet/protocol.c0000644000000000000000000002073515010704253017155 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include #include #include #include #include #include #include Seq *ProtocolOpenDir(AgentConnection *conn, const char *path) { assert(conn != NULL); assert(path != NULL); char buf[CF_MSGSIZE] = {0}; int tosend = snprintf(buf, CF_MSGSIZE, "OPENDIR %s", path); if (tosend < 0 || tosend >= CF_MSGSIZE) { return NULL; } int ret = SendTransaction(conn->conn_info, buf, tosend, CF_DONE); if (ret == -1) { return NULL; } Seq *seq = SeqNew(0, free); int more = 1; while (more != 0) { int len = ReceiveTransaction(conn->conn_info, buf, &more); if (len == -1) { break; } if (BadProtoReply(buf)) { Log(LOG_LEVEL_ERR, "Protocol error: %s", buf); SeqDestroy(seq); return NULL; } /* * Iterates over each string in the received transaction and appends * it to the Seq list, until it either finds the CFD_TERMINATOR * string, or reaches the end of the message. */ for (int i = 0; i < len && buf[i] != '\0'; i += strlen(buf + i) + 1) { if (StringEqualN(buf + i, CFD_TERMINATOR, sizeof(CFD_TERMINATOR) - 1)) { more = 0; break; } char *str = xstrdup(buf + i); SeqAppend(seq, str); } } return seq; } bool ProtocolGet(AgentConnection *conn, const char *remote_path, const char *local_path, const uint32_t file_size, int perms) { assert(conn != NULL); assert(remote_path != NULL); assert(local_path != NULL); assert(file_size != 0); perms = (perms == 0) ? CF_PERMS_DEFAULT : perms; unlink(local_path); FILE *file_ptr = safe_fopen_create_perms(local_path, "wx", perms); if (file_ptr == NULL) { Log(LOG_LEVEL_WARNING, "Failed to open file %s (fopen: %s)", local_path, GetErrorStr()); return false; } char buf[CF_MSGSIZE] = {0}; int to_send = snprintf(buf, CF_MSGSIZE, "GET %d %s", CF_MSGSIZE, remote_path); int ret = SendTransaction(conn->conn_info, buf, to_send, CF_DONE); if (ret == -1) { Log(LOG_LEVEL_WARNING, "Failed to send request for remote file %s:%s", conn->this_server, remote_path); unlink(local_path); fclose(file_ptr); return false; } char cfchangedstr[sizeof(CF_CHANGEDSTR1 CF_CHANGEDSTR2)]; snprintf(cfchangedstr, sizeof(cfchangedstr), "%s%s", CF_CHANGEDSTR1, CF_CHANGEDSTR2); bool success = true; uint32_t received_bytes = 0; while (received_bytes < file_size) { int len = TLSRecv(conn->conn_info->ssl, buf, CF_MSGSIZE); if (len == -1) { Log(LOG_LEVEL_WARNING, "Failed to GET file %s:%s", conn->this_server, remote_path); success = false; break; } else if (len > CF_MSGSIZE) { Log(LOG_LEVEL_WARNING, "Incorrect length of incoming packet " "while retrieving %s:%s, %d > %d", conn->this_server, remote_path, len, CF_MSGSIZE); success = false; break; } if (BadProtoReply(buf)) { Log(LOG_LEVEL_ERR, "Error from server while retrieving file %s:%s: %s", conn->this_server, remote_path, buf); success = false; break; } if (StringEqualN(buf, cfchangedstr, sizeof(cfchangedstr) - 1)) { Log(LOG_LEVEL_ERR, "Remote file %s:%s changed during file transfer", conn->this_server, remote_path); success = false; break; } ret = fwrite(buf, sizeof(char), len, file_ptr); if (ret < 0) { Log(LOG_LEVEL_ERR, "Failed to write during retrieval of file %s:%s (fwrite: %s)", conn->this_server, remote_path, GetErrorStr()); success = false; break; } received_bytes += len; } if (!success) { unlink(local_path); } fclose(file_ptr); return success; } bool ProtocolStatGet(AgentConnection *conn, const char *remote_path, const char *local_path, int perms) { assert(conn != NULL); assert(remote_path != NULL); struct stat sb; bool ret = ProtocolStat(conn, remote_path, &sb); if (!ret) { Log(LOG_LEVEL_ERR, "Failed to stat remote file %s:%s", conn->this_server, remote_path); return false; } return ProtocolGet(conn, remote_path, local_path, sb.st_size, perms); } bool ProtocolStat(AgentConnection *const conn, const char *const remote_path, struct stat *const stat_buf) { assert(conn != NULL); assert(remote_path != NULL); assert(stat_buf != NULL); time_t tloc = time(NULL); if (tloc == (time_t) -1) { Log(LOG_LEVEL_WARNING, "Couldn't read system clock, defaulting to 0 in case server " "does not care about clock differences (time: %s)", GetErrorStr()); tloc = 0; } char buf[CF_BUFSIZE] = {0}; int to_send = snprintf(buf, CF_BUFSIZE, "SYNCH %jd STAT %s", (intmax_t) tloc, remote_path); int ret = SendTransaction(conn->conn_info, buf, to_send, CF_DONE); if (ret == -1) { Log(LOG_LEVEL_WARNING, "Could not send stat request for remote file %s:%s.", conn->this_server, remote_path); return false; } int recvd_len = ReceiveTransaction(conn->conn_info, buf, NULL) == -1; if (recvd_len == -1) { Log(LOG_LEVEL_WARNING, "Receiving file statistics from %s failed!", conn->this_server); return false; } if (BadProtoReply(buf)) { Log(LOG_LEVEL_WARNING, "Could not stat remote file %s:%s, response: %s", conn->this_server, remote_path, buf); return false; } if (!OKProtoReply(buf)) { Log(LOG_LEVEL_WARNING, "Illegal response from server while statting %s:%s", conn->this_server, remote_path); return false; } Stat cf_stat; ret = StatParseResponse(buf, &cf_stat); if (!ret) { Log(LOG_LEVEL_WARNING, "Failed to parse the response from the server " "while statting %s:%s", conn->this_server, remote_path); return false; } mode_t file_type = FileTypeToMode(cf_stat.cf_type); if (file_type == 0) { Log(LOG_LEVEL_VERBOSE, "Invalid file type identifier for file %s:%s, %u", conn->this_server, remote_path, cf_stat.cf_type); return false; } stat_buf->st_mode = file_type | cf_stat.cf_mode; stat_buf->st_uid = cf_stat.cf_uid; stat_buf->st_gid = cf_stat.cf_gid; stat_buf->st_size = cf_stat.cf_size; stat_buf->st_mtime = cf_stat.cf_mtime; stat_buf->st_ctime = cf_stat.cf_ctime; stat_buf->st_atime = cf_stat.cf_atime; stat_buf->st_ino = cf_stat.cf_ino; stat_buf->st_dev = cf_stat.cf_dev; stat_buf->st_nlink = cf_stat.cf_nlink; // Receive link destination, but do nothing ReceiveTransaction(conn->conn_info, buf, NULL); return true; } cfengine-3.24.2/libcfnet/net.c0000644000000000000000000005403315010704253016100 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #include #include /* CF_BUFSIZE */ #include #include #include #include #include #include #include #include /* TODO remove libpromises dependency. */ extern char BINDINTERFACE[CF_MAXVARSIZE]; /* cf3globals.c, cf3.extern.h */ void SetBindInterface(const char *ip) { strlcpy(BINDINTERFACE, ip, sizeof(BINDINTERFACE)); Log(LOG_LEVEL_VERBOSE, "Setting bindtointerface to '%s'", BINDINTERFACE); } /** * @param len is the number of bytes to send, or 0 if buffer is a * '\0'-terminated string so strlen(buffer) can be used. * @return -1 in case of error or connection closed * (also currently returns 0 for success but don't count on it) * @NOTE #buffer can't be of zero length, our protocol * does not allow empty transactions! * @NOTE (len <= CF_BUFSIZE - CF_INBAND_OFFSET) * * @TODO Currently only transactions up to CF_BUFSIZE-CF_INBAND_OFFSET are * allowed to be sent. This function should be changed to allow up to * CF_BUFSIZE-1 (since '\0' is not sent, but the receiver needs space to * append it). So transaction length will be at most 4095! */ int SendTransaction(ConnectionInfo *conn_info, const char *buffer, int len, char status) { assert(status == CF_MORE || status == CF_DONE); char work[CF_BUFSIZE] = { 0 }; int ret; if (len == 0) { len = strlen(buffer); } /* Not allowed to send zero-payload packets */ assert(len > 0); if (len > CF_BUFSIZE - CF_INBAND_OFFSET) { Log(LOG_LEVEL_ERR, "SendTransaction: len (%d) > %d - %d", len, CF_BUFSIZE, CF_INBAND_OFFSET); return -1; } snprintf(work, CF_INBAND_OFFSET, "%c %d", status, len); memcpy(work + CF_INBAND_OFFSET, buffer, len); Log(LOG_LEVEL_DEBUG, "SendTransaction header: %s", work); LogRaw(LOG_LEVEL_DEBUG, "SendTransaction data: ", work + CF_INBAND_OFFSET, len); switch (ProtocolClassicOrTLS(conn_info->protocol)) { case CF_PROTOCOL_CLASSIC: ret = SendSocketStream(conn_info->sd, work, len + CF_INBAND_OFFSET); break; case CF_PROTOCOL_TLS: ret = TLSSend(conn_info->ssl, work, len + CF_INBAND_OFFSET); if (ret <= 0) { ret = -1; } break; default: UnexpectedError("SendTransaction: ProtocolVersion %d!", conn_info->protocol); ret = -1; } if (ret == -1) { /* We are experiencing problems with sending data to server. * This might lead to packages being not delivered in correct * order and unexpected issues like directories being replaced * with files. * In order to make sure that file transfer is reliable we have to * close connection to avoid broken packages being received. */ conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } else { /* SSL_MODE_AUTO_RETRY guarantees no partial writes. */ assert(ret == len + CF_INBAND_OFFSET); return 0; } } /*************************************************************************/ /** * Receive a transaction packet of at most CF_BUFSIZE-1 bytes, and * NULL-terminate it. * * @param #buffer must be of size at least CF_BUFSIZE. * * @return -1 in case of closed socket, other error or timeout. * The connection MAY NOT BE FINALISED! * >0 the number of bytes read, transaction was successfully received. * * @TODO shutdown() the connection in all cases were this function returns -1, * in order to protect against future garbage reads. */ int ReceiveTransaction(ConnectionInfo *conn_info, char *buffer, int *more) { char proto[CF_INBAND_OFFSET + 1] = { 0 }; int ret; /* Get control channel. */ switch (ProtocolClassicOrTLS(conn_info->protocol)) { case CF_PROTOCOL_CLASSIC: ret = RecvSocketStream(conn_info->sd, proto, CF_INBAND_OFFSET); break; case CF_PROTOCOL_TLS: ret = TLSRecv(conn_info->ssl, proto, CF_INBAND_OFFSET); break; default: UnexpectedError("ReceiveTransaction: ProtocolVersion %d!", conn_info->protocol); ret = -1; } /* If error occurred or recv() timeout or if connection was gracefully * closed. Connection has been finalised. */ if (ret <= 0) { /* We are experiencing problems with receiving data from server. * This might lead to packages being not delivered in correct * order and unexpected issues like directories being replaced * with files. * In order to make sure that file transfer is reliable we have to * close connection to avoid broken packages being received. */ conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } else if (ret != CF_INBAND_OFFSET) { /* If we received less bytes than expected. Might happen * with TLSRecv(). */ Log(LOG_LEVEL_ERR, "ReceiveTransaction: bogus short header (%d bytes: '%s')", ret, proto); conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } LogRaw(LOG_LEVEL_DEBUG, "ReceiveTransaction header: ", proto, ret); char status = 'x'; int len = 0; ret = sscanf(proto, "%c %d", &status, &len); if (ret != 2) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: bogus header: %s", proto); conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } if (status != CF_MORE && status != CF_DONE) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: bogus header (more='%c')", status); conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } if (len > CF_BUFSIZE - CF_INBAND_OFFSET) { Log(LOG_LEVEL_ERR, "ReceiveTransaction: packet too long (len=%d)", len); conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } else if (len <= 0) { /* Zero-length packets are disallowed, because * ReceiveTransaction() == 0 currently means connection closed. */ Log(LOG_LEVEL_ERR, "ReceiveTransaction: packet too short (len=%d)", len); conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } if (more != NULL) { switch (status) { case CF_MORE: *more = true; break; case CF_DONE: *more = false; break; default: ProgrammingError("Unreachable, " "bogus headers have already been checked!"); } } /* Get data. */ switch (ProtocolClassicOrTLS(conn_info->protocol)) { case CF_PROTOCOL_CLASSIC: ret = RecvSocketStream(conn_info->sd, buffer, len); break; case CF_PROTOCOL_TLS: ret = TLSRecv(conn_info->ssl, buffer, len); break; default: UnexpectedError("ReceiveTransaction: ProtocolVersion %d!", conn_info->protocol); ret = -1; } /* Connection gracefully closed (ret==0) or connection error (ret==-1) or * just partial receive of bytestream.*/ if (ret != len) { /* * Should never happen except with TLS, given that we are using * SSL_MODE_AUTO_RETRY and that transaction payload < CF_BUFSIZE < TLS * record size, it can currently only happen if the other side does * TLSSend(wrong_number) for the transaction. * * TODO IMPORTANT terminate TLS session in that case. */ Log(LOG_LEVEL_ERR, "Partial transaction read %d != %d bytes!", ret, len); conn_info->status = CONNECTIONINFO_STATUS_BROKEN; return -1; } LogRaw(LOG_LEVEL_DEBUG, "ReceiveTransaction data: ", buffer, ret); return ret; } /* BWlimit global variables Throttling happens for all network interfaces, all traffic being sent for any connection of this process (cf-agent or cf-serverd). We need a lock, to avoid concurrent writes to "bwlimit_next". Then, "bwlimit_next" is the absolute time (as of clock_gettime() ) that we are clear to send, after. It is incremented with the delay for every packet scheduled for sending. Thus, integer arithmetic will make sure we wait for the correct amount of time, in total. */ #ifndef _WIN32 static pthread_mutex_t bwlimit_lock = PTHREAD_MUTEX_INITIALIZER; static struct timespec bwlimit_next = {0, 0L}; #endif uint32_t bwlimit_kbytes = 0; /* desired limit, in kB/s */ /** Throttle traffic, if next packet happens too soon after the previous one * * This function is global, across all network operations (and interfaces, perhaps) * @param tosend Length of current packet being sent out (in bytes) */ #ifdef CLOCK_MONOTONIC # define PREFERRED_CLOCK CLOCK_MONOTONIC #else /* Some OS-es don't have monotonic clock, but we can still use the * next available one */ # define PREFERRED_CLOCK CLOCK_REALTIME #endif void EnforceBwLimit(int tosend) { if (!bwlimit_kbytes) { /* early return, before any expensive syscalls */ return; } #ifdef _WIN32 Log(LOG_LEVEL_WARNING, "Bandwidth limiting with \"bwlimit\" is not supported on Windows."); (void)tosend; // Avoid "unused" warning. return; #else const uint32_t u_10e6 = 1000000L; const uint32_t u_10e9 = 1000000000L; struct timespec clock_now = {0, 0L}; if (pthread_mutex_lock(&bwlimit_lock) == 0) { clock_gettime(PREFERRED_CLOCK, &clock_now); if ((bwlimit_next.tv_sec < clock_now.tv_sec) || ( (bwlimit_next.tv_sec == clock_now.tv_sec) && (bwlimit_next.tv_nsec < clock_now.tv_nsec) ) ) { /* penalty has expired, we can immediately send data. But reset the timestamp */ bwlimit_next = clock_now; clock_now.tv_sec = 0; clock_now.tv_nsec = 0L; } else { clock_now.tv_sec = bwlimit_next.tv_sec - clock_now.tv_sec; clock_now.tv_nsec = bwlimit_next.tv_nsec - clock_now.tv_nsec; if (clock_now.tv_nsec < 0L) { clock_now.tv_sec --; clock_now.tv_nsec += u_10e9; } } uint64_t delay = ((uint64_t) tosend * u_10e6) / bwlimit_kbytes; /* in ns */ bwlimit_next.tv_sec += (delay / u_10e9); bwlimit_next.tv_nsec += (long) (delay % u_10e9); if (bwlimit_next.tv_nsec >= u_10e9) { bwlimit_next.tv_sec++; bwlimit_next.tv_nsec -= u_10e9; } if (bwlimit_next.tv_sec > 20) { /* Upper limit of 20sec for penalty. This will avoid huge wait if * our clock has jumped >minutes back in time. Still, assuming that * most of our packets are <= 2048 bytes, the lower bwlimit is bound * to 102.4 Bytes/sec. With 65k packets (rare) is 3.7kBytes/sec in * that extreme case. * With more clients hitting a single server, this lower bound is * multiplied by num of clients, eg. 102.4kBytes/sec for 1000 reqs. * simultaneously. */ bwlimit_next.tv_sec = 20; } pthread_mutex_unlock(&bwlimit_lock); } /* Even if we push our data every few bytes to the network interface, the software+hardware buffers will queue it and send it in bursts, anyway. It is more likely that we will waste CPU sys-time calling nanosleep() for such short delays. So, sleep only if we have >1ms penalty */ if (clock_now.tv_sec > 0 || ( (clock_now.tv_sec == 0) && (clock_now.tv_nsec >= u_10e6)) ) { nanosleep(&clock_now, NULL); } #endif // !_WIN32 } /*************************************************************************/ /** Tries to connect() to server #host, returns the socket descriptor and the IP address that succeeded in #txtaddr. @param #connect_timeout how long to wait for connect(), zero blocks forever @param #txtaddr If connected successfully return the IP connected in textual representation @return Connected socket descriptor or -1 in case of failure. */ int SocketConnect(const char *host, const char *port, unsigned int connect_timeout, bool force_ipv4, char *txtaddr, size_t txtaddr_size) { struct addrinfo *response = NULL, *ap; bool connected = false; int sd = -1; struct addrinfo query = { .ai_family = force_ipv4 ? AF_INET : AF_UNSPEC, .ai_socktype = SOCK_STREAM }; int ret = getaddrinfo(host, port, &query, &response); if (ret != 0) { Log(LOG_LEVEL_INFO, "Unable to find host '%s' service '%s' (%s)", host, port, gai_strerror(ret)); if (response != NULL) { freeaddrinfo(response); } return -1; } for (ap = response; !connected && ap != NULL; ap = ap->ai_next) { /* Convert address to string. */ getnameinfo(ap->ai_addr, ap->ai_addrlen, txtaddr, txtaddr_size, NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_VERBOSE, "Connecting to host %s, port %s as address %s", host, port, txtaddr); sd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol); if (sd == -1) { Log(LOG_LEVEL_ERR, "Couldn't open a socket to '%s' (socket: %s)", txtaddr, GetErrorStr()); } else { /* Bind socket to specific interface, if requested. */ if (BINDINTERFACE[0] != '\0') { struct addrinfo query2 = { .ai_family = force_ipv4 ? AF_INET : AF_UNSPEC, .ai_socktype = SOCK_STREAM, /* returned address is for bind() */ .ai_flags = AI_PASSIVE }; struct addrinfo *response2 = NULL, *ap2; int ret2 = getaddrinfo(BINDINTERFACE, NULL, &query2, &response2); if (ret2 != 0) { Log(LOG_LEVEL_ERR, "Unable to lookup interface '%s' to bind. (getaddrinfo: %s)", BINDINTERFACE, gai_strerror(ret2)); if (response2 != NULL) { freeaddrinfo(response2); } assert(response); /* first getaddrinfo was successful */ freeaddrinfo(response); cf_closesocket(sd); return -1; } for (ap2 = response2; ap2 != NULL; ap2 = ap2->ai_next) { if (bind(sd, ap2->ai_addr, ap2->ai_addrlen) == 0) { break; } } if (ap2 == NULL) { Log(LOG_LEVEL_ERR, "Unable to bind to interface '%s'. (bind: %s)", BINDINTERFACE, GetErrorStr()); } assert(response2); /* second getaddrinfo was successful */ freeaddrinfo(response2); } connected = TryConnect(sd, connect_timeout * 1000, ap->ai_addr, ap->ai_addrlen); if (!connected) { Log(LOG_LEVEL_VERBOSE, "Unable to connect to address %s (%s)", txtaddr, GetErrorStr()); cf_closesocket(sd); sd = -1; } } } assert(response != NULL); /* first getaddrinfo was successful */ freeaddrinfo(response); if (connected) { Log(LOG_LEVEL_VERBOSE, "Connected to host %s address %s port %s (socket descriptor %d)", host, txtaddr, port, sd); } else { Log(LOG_LEVEL_VERBOSE, "Unable to connect to host %s port %s (socket descriptor %d)", host, port, sd); } return sd; } #if !defined(__MINGW32__) #if defined(__hpux) && defined(__GNUC__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" // HP-UX GCC type-pun warning on FD_SET() macro: // While the "fd_set" type is defined in /usr/include/sys/_fd_macros.h as a // struct of an array of "long" values in accordance with the XPG4 standard's // requirements, the macros for the FD operations "pretend it is an array of // int32_t's so the binary layout is the same for both Narrow and Wide // processes," as described in _fd_macros.h. In the FD_SET, FD_CLR, and // FD_ISSET macros at line 101, the result is cast to an "__fd_mask *" type, // which is defined as int32_t at _fd_macros.h:82. // // This conflict between the "long fds_bits[]" array in the XPG4-compliant // fd_set structure, and the cast to an int32_t - not long - pointer in the // macros, causes a type-pun warning if -Wstrict-aliasing is enabled. // The warning is merely a side effect of HP-UX working as designed, // so it can be ignored. #endif /** * Tries to connect for #timeout_ms milliseconds. On success sets the recv() * timeout to #timeout_ms as well. * * @param #timeout_ms How long to wait for connect(), if zero wait forever. * @return true on success, false otherwise. **/ bool TryConnect(int sd, unsigned long timeout_ms, const struct sockaddr *sa, socklen_t sa_len) { assert(sd != -1); assert(sa != NULL); if (sd >= FD_SETSIZE) { Log(LOG_LEVEL_ERR, "Open connections exceed FD_SETSIZE limit (%d >= %d)", sd, FD_SETSIZE); return false; } /* set non-blocking socket */ int arg = fcntl(sd, F_GETFL, NULL); int ret = fcntl(sd, F_SETFL, arg | O_NONBLOCK); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to set socket to non-blocking mode (fcntl: %s)", GetErrorStr()); } ret = connect(sd, sa, sa_len); if (ret == -1) { if (errno != EINPROGRESS) { Log(LOG_LEVEL_INFO, "Failed to connect to server (connect: %s)", GetErrorStr()); return false; } int errcode; socklen_t opt_len = sizeof(errcode); fd_set myset; FD_ZERO(&myset); FD_SET(sd, &myset); Log(LOG_LEVEL_VERBOSE, "Waiting to connect..."); struct timeval tv, *tvp; if (timeout_ms > 0) { tv.tv_sec = timeout_ms / 1000; tv.tv_usec = (timeout_ms % 1000) * 1000; tvp = &tv; } else { tvp = NULL; /* wait indefinitely */ } ret = select(sd + 1, NULL, &myset, NULL, tvp); if (ret == 0) { Log(LOG_LEVEL_INFO, "Timeout connecting to server"); return false; } if (ret == -1) { if (errno == EINTR) { Log(LOG_LEVEL_ERR, "Socket connect was interrupted by signal"); } else { Log(LOG_LEVEL_ERR, "Failure while connecting (select: %s)", GetErrorStr()); } return false; } ret = getsockopt(sd, SOL_SOCKET, SO_ERROR, (void *) &errcode, &opt_len); if (ret == -1) { Log(LOG_LEVEL_ERR, "Could not check connection status (getsockopt: %s)", GetErrorStr()); return false; } if (errcode != 0) { Log(LOG_LEVEL_INFO, "Failed to connect to server: %s", GetErrorStrFromCode(errcode)); return false; } } /* Connection succeeded, return to blocking mode. */ ret = fcntl(sd, F_SETFL, arg); if (ret == -1) { Log(LOG_LEVEL_ERR, "Failed to set socket back to blocking mode (fcntl: %s)", GetErrorStr()); } if (timeout_ms > 0) { SetReceiveTimeout(sd, timeout_ms); } return true; } #if defined(__hpux) && defined(__GNUC__) #pragma GCC diagnostic warning "-Wstrict-aliasing" #endif #endif /* !defined(__MINGW32__) */ /** * Set timeout for recv(), in milliseconds. * @param ms must be > 0. */ int SetReceiveTimeout(int fd, unsigned long ms) { assert(ms > 0); Log(LOG_LEVEL_VERBOSE, "Setting socket timeout to %lu seconds.", ms/1000); /* On windows SO_RCVTIMEO is set by a DWORD indicating the timeout in * milliseconds, on UNIX it's a struct timeval. */ #if !defined(__MINGW32__) struct timeval tv = { .tv_sec = ms / 1000, .tv_usec = (ms % 1000) * 1000 }; int ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); #else int ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &ms, sizeof(ms)); #endif if (ret != 0) { Log(LOG_LEVEL_VERBOSE, "Failed to set socket timeout to %lu milliseconds.", ms); return -1; } return 0; } cfengine-3.24.2/configure.ac0000644000000000000000000016775115010704253015662 0ustar00rootroot00000000000000dnl dnl Copyright 2021 Northern.tech AS dnl dnl This file is part of CFEngine 3 - written and maintained by Northern.tech AS. dnl dnl This program is free software; you can redistribute it and/or modify it dnl under the terms of the GNU General Public License as published by the dnl Free Software Foundation; version 3. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA dnl dnl To the extent this program is licensed as part of the Enterprise dnl versions of CFEngine, the applicable Commercial Open Source License dnl (COSL) may apply to this file if you as a licensee so wish it. See dnl included file COSL.txt. dnl dnl ########################################################################## dnl # dnl # Build CFEngine dnl # dnl # Run ./autogen.sh to build configure script dnl # dnl ########################################################################## AC_PREREQ(2.63) m4_define([cfversion_from_env], m4_normalize(m4_esyscmd([echo $EXPLICIT_VERSION]))) m4_define([cfversion_from_file], m4_normalize(m4_esyscmd([cat CFVERSION]))) m4_ifval(cfversion_from_env, [ m4_define([cfversion], cfversion_from_env) ], [ m4_ifval(cfversion_from_file, [ m4_define([cfversion], cfversion_from_file) ], [ m4_fatal([Could not determine CFEngine version; please set EXPLICIT_VERSION in the environment, or make sure all git tags are up to date and rerun autogen.sh]) ]) ]) AC_INIT(cfengine, cfversion) AC_CONFIG_SRCDIR([libpromises/generic_agent.c]) AC_CANONICAL_TARGET dnl dnl This program needs to be checked early, as MAKEINFO variable is expanded in dnl AM_INIT_AUTOMAKE. dnl AC_CHECK_PROG(MAKEINFO, makeinfo, makeinfo) dnl Parallel unit tests are causing spurious failures across several systems, dnl particularly those doing process testing. dnl Unfortunately the option to disable parallel tests (serial-tests) doesn't dnl exist in automake 1.11 and earlier, so we need to do this complicated logic dnl to determine whether we can disable it or not. If it doesn't exist as an dnl option, then serial tests are already the default. AC_MSG_CHECKING([automake version]) m4_define(AUTOMAKE_VERSION, m4_normalize(m4_esyscmd([automake --version 2>&1 | sed -ne '/^automake/{s/^automake.* \([^ ][^ ]*\)$/\1/; p;}']))) m4_define(SERIAL_TESTS, m4_bmatch(AUTOMAKE_VERSION, [^1\.\([0-9]\|1[0-1]\)\(\.\|$\)], [], [serial-tests])) AC_MSG_RESULT(AUTOMAKE_VERSION) AM_INIT_AUTOMAKE([tar-ustar] SERIAL_TESTS) AM_MAINTAINER_MODE([enable]) m4_divert_text([DEFAULTS], [: "${AR_FLAGS=cr}"]) cfengine_version=cfversion m4_undefine([cfversion]) m4_undefine([cfversion_from_file]) m4_undefine([cfversion_from_env]) AS_IF([test -n "$RELEASE"], [AC_DEFINE_UNQUOTED(RELEASE, ["$RELEASE"], [Release number])], [AC_DEFINE(RELEASE, ["1"], [Release number])]) AC_DEFINE(BUILD_YEAR, esyscmd([date +%Y | tr -d '\n']), "Software build year") AC_DEFINE(CF_WEBSITE, "https://cfengine.com", "Website. To be used in help screens") AC_DEFINE(CF_COPYRIGHT, "2023 Northern.tech AS", "Copyright. To be used in help screens") AC_DEFINE_UNQUOTED(ABS_TOP_SRCDIR, "`cd -- "$srcdir"; pwd`", [Absolute path of source tree]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS([config.h]) dnl Libtool madness AC_CONFIG_MACRO_DIR([m4]) dnl dnl hide [s]include macros, so old aclocal (automake < 1.10) won't find them and dnl won't complain about something/something.m4 not found dnl m4_define(incstart,sinc) m4_define(incend,lude) dnl dnl Save environment CFLAGS before autoconf starts messing with it. dnl It is restored later. dnl ENV_CFLAGS="$CFLAGS" dnl ###################################################################### dnl Checks for programs. dnl ###################################################################### AC_PROG_CC AC_PROG_MKDIR_P AC_EXEEXT dnl GCC specific flags m4_include([m4/cf3_gcc_flags.m4]) # Use either new LT_INIT or old AC_DISABLE_STATIC/AC_PROG_LIBTOOL macros m4_ifdef([LT_INIT], [LT_INIT([disable-static])], [AC_DISABLE_STATIC AC_PROG_LIBTOOL]) AM_PROG_LEX AC_PROG_YACC AC_PROG_INSTALL AC_PATH_PROG([PERL], [perl]) AC_CONFIG_LIBOBJ_DIR(libcfecompat) CFECOMPAT_CPPFLAGS="-I$srcdir/libcfecompat" AC_PATH_PROG(GETCONF, getconf, false, $PATH:$prefix/bin:/usr/bin:/usr/local/bin:/sw/bin) AM_CONDITIONAL(CROSS_COMPILING, test "x$cross_compiling" = "xyes") # Check whether `pkg-config' is available AC_ARG_VAR([PKG_CONFIG], [path to pkg-config]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to the pkg-config search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi dnl ###################################################################### dnl Use pthreads if available dnl ###################################################################### AC_ARG_WITH([pthreads], [AS_HELP_STRING([--with-pthreads[[=PATH]]], [Specify path to pthreads, if not the part of operating system])]) if test "x$with_pthreads" != x && test "x$with_pthreads" != "xyes" && test "x$with_pthreads" != "xno"; then LIBS="$LIBS -L$with_pthreads/lib" CPPFLAGS="-I$with_pthreads/include $CPPFLAGS" fi ACX_PTHREAD([], [AC_MSG_ERROR(pthread-compatible library is required to build CFEngine)]) CC="$PTHREAD_CC" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" dnl ###################################################################### dnl Whether to build extensions as builtin extensions or a separate dnl plugin. The default is plugin. dnl --enable-builtin-extensions is the default on Windows, and can be dnl used on other platforms for debugging purposes, but isn't otherwise dnl supported. dnl ###################################################################### AC_ARG_ENABLE([builtin-extensions], [AS_HELP_STRING([Build binaries with builtin extensions])], [], [ AS_CASE([${target_os}], [mingw*], [enable_builtin_extensions=yes], [enable_builtin_extensions=no]) ]) AM_CONDITIONAL([BUILTIN_EXTENSIONS], [test "x$enable_builtin_extensions" = "xyes"]) AS_IF([test "x$enable_builtin_extensions" = "xyes"], [AC_DEFINE([BUILTIN_EXTENSIONS], [1], [Define if you want builtin Enterprise extensions])]) AC_SUBST([enable_builtin_extensions]) dnl ###################################################################### dnl Configure files layout dnl ###################################################################### AC_ARG_ENABLE([fhs], [AS_HELP_STRING([--enable-fhs], [Enable FHS compliance. Defaults to custom CFEngine files layout])]) # # pkglibdir/pkgdatadir are not overridable, so use our own invention instead. # AS_IF([test x"$enable_fhs" = xyes], [ projlibdir='${pkglibdir}' WORKDIR='${localstatedir}/lib/${PACKAGE}' MASTERDIR='default' INPUTDIR='default' DATADIR='default' LOGDIR='${localstatedir}/log/${PACKAGE}' PIDDIR='${runstatedir:-${localstatedir}/run}/${PACKAGE}' STATEDIR='default' ], [ if test x"$prefix" = xNONE || test x"$prefix" = x/var/cfengine; then prefix=/var/cfengine case "$target_os" in mingw*) WORKDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') PIDDIR=$(cmd /c "echo %PROGRAMFILES%\\Cfengine" | sed 's/\\/\\\\/g') STATEDIR=default ;; *) WORKDIR=/var/cfengine MASTERDIR=default INPUTDIR=default DATADIR=default LOGDIR=/var/cfengine PIDDIR=/var/cfengine STATEDIR=default ;; esac else WORKDIR="${localstatedir}/${PACKAGE}" MASTERDIR="default" INPUTDIR="default" DATADIR="default" LOGDIR="${localstatedir}/${PACKAGE}" PIDDIR="${localstatedir}/${PACKAGE}" STATEDIR="default" fi bindir="${bindir:-${exec_prefix}/bin}" projlibdir='${libdir}' ]) AC_SUBST(projlibdir) dnl ###################################################################### dnl Platform specific compiler flags. dnl ###################################################################### AS_CASE([${target_os}], [mingw*], # Disable printf format warnings, because our wrapper supports more # flags than vanilla Windows version, so they are false positives. [CFLAGS="$CFLAGS -Wno-format"]) AS_CASE([${target_os}], [mingw*], [AM_CONDITIONAL([WINDOWS], [true])], [AM_CONDITIONAL([WINDOWS], [false])]) dnl ###################################################################### dnl Enable debugging dnl ###################################################################### AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enable debugging]), [debug=$enableval], [debug=no]) AM_CONDITIONAL([NDEBUG], [test x"$debug" = x"no"]) dnl Even though CFLAGS should contain the command-line CFLAGS dnl as last, some macro seem to messes the order up and insert dnl its own optimisation flags as well. So we append ENV_CFLAGS dnl at the end manually, causing a bit of flag duplication. AC_MSG_CHECKING([for debug option]) if test x"$debug" = x"yes" then AC_MSG_RESULT(yes) CFLAGS="$CFLAGS -g3 -O0 $ENV_CFLAGS" else AC_MSG_RESULT(no) CFLAGS="$CFLAGS -O2 -DNDEBUG $ENV_CFLAGS" fi dnl ###################################################################### dnl Checks for libraries. dnl ###################################################################### dnl Now check for database connectors # TODO remove AC_ARG_WITH([sql], [AS_HELP_STRING([--with-sql[[=PATH]]], [Enable SQL database connectors (deprecated, use \ --with[[out]]-postgresql and --with[[out]]-mysql instead)]) ], [with_postgresql=$with_sql; with_mysql=$with_sql], []) dnl PostgreSQL AC_ARG_WITH([postgresql], [AS_HELP_STRING([--with-postgresql[[=PATH]]], [Enable PostgreSQL connector]) ], [], [with_postgresql=check]) if test "x$with_postgresql" != "xno" then if test "x$with_postgresql" != xyes && test "x$with_postgresql" != xcheck then PG_CONFIG=$with_postgresql/bin/pg_config else PG_CONFIG=pg_config fi # pg_config is only for native builds if test "x$cross_compiling" = "xno" then if test x`which $PG_CONFIG` != x then pg_include_dir=`$PG_CONFIG --includedir` if test -n "$pg_include_dir" then POSTGRESQL_CPPFLAGS="-I$pg_include_dir" fi fi fi CF3_WITH_LIBRARY(postgresql, [AC_CHECK_LIB(pq, PQconnectdb, [], [if test "x$with_postgresql" != xcheck; then AC_MSG_ERROR(Cannot find PostgreSQL client library); fi] ) AC_CHECK_HEADERS(libpq-fe.h, [], [if test "x$with_postgresql" != xcheck; then AC_MSG_ERROR(Cannot find PostgreSQL client library); fi] )] ) fi dnl MySQL AC_ARG_WITH([mysql], [AS_HELP_STRING([--with-mysql[[=PATH]]], [Enable MySQL connector]) ], [], [with_mysql=check]) if test "x$with_mysql" != "xno" then if test "x$with_mysql" != xyes && test "x$with_mysql" != xcheck then MYSQL_CONFIG=$with_mysql/bin/mysql_config else MYSQL_CONFIG=mysql_config fi # mysql_config is only for native builds if test "x$cross_compiling" = "xno" then if test x`which $MYSQL_CONFIG` != x then mysql_include_dir=`$MYSQL_CONFIG --include` if test -n "$mysql_include_dir" then MYSQL_CPPFLAGS="$mysql_include_dir" fi fi fi CF3_WITH_LIBRARY(mysql, [AC_CHECK_LIB(mysqlclient, mysql_real_connect, [], [if test "x$with_mysql" != xcheck; then AC_MSG_ERROR(Cannot find MySQL client library); fi] ) AC_CHECK_HEADERS(mysql.h, [], [if test "x$with_mysql" != xcheck; then AC_MSG_ERROR(Cannot find MySQL clientlibrary); fi] ) AC_CHECK_LIB(mysqlclient, EVP_CIPHER_CTX_init, [AC_MSG_ERROR([MySQL client library exports symbols clashing \ with OpenSSL. Get the update from distribution provider, \ recompile MySQL library or disable MySQL connector. See \ http://bugs.mysql.com/bug.php?id=65055 for details.]) ] )] ) fi dnl dnl In-process databases dnl dnl QDBM AC_ARG_WITH([qdbm], [AS_HELP_STRING([--with-qdbm[[=PATH]]], [use QDBM to store runtime data])]) AS_IF([test -n "$with_qdbm" && test "x$with_qdbm" != "xno"], [WITH_QDBM=1], [WITH_QDBM=0]) if test $WITH_QDBM = 1; then CF3_WITH_LIBRARY(qdbm, [ AC_CHECK_LIB(qdbm, dpopen, [], [AC_MSG_ERROR(Cannot find QDBM)]) AC_CHECK_HEADERS(qdbm/depot.h, [], [AC_MSG_ERROR(Cannot find QDBM)]) AC_DEFINE(QDB, 1, [Define if QDBM is available]) ]) fi dnl Tokyo Cabinet AC_ARG_WITH([tokyocabinet], [AS_HELP_STRING([--with-tokyocabinet[[=PATH]]], [use Tokyo Cabinet to store runtime data])]) AS_IF([test $WITH_QDBM -eq 0 && test -n "$with_tokyocabinet" && test "x$with_tokyocabinet" != "xno"], [WITH_TOKYO=1], [WITH_TOKYO=0]) if test $WITH_TOKYO = 1; then CF3_WITH_LIBRARY(tokyocabinet, [ AC_CHECK_LIB(tokyocabinet, tchdbnew, [], [AC_MSG_ERROR(Cannot find Tokyo Cabinet)]) AC_CHECK_HEADERS(tcutil.h, [], [AC_MSG_ERROR(Cannot find Tokyo Cabinet)]) AC_CHECK_HEADERS(tchdb.h, [], [AC_MSG_ERROR(Cannot find Tokyo Cabinet)]) AC_DEFINE(TCDB, 1, [Define if Tokyo Cabinet is available.]) ]) fi dnl OpenLDAP Lightning MDB AC_ARG_WITH([lmdb], [AS_HELP_STRING([--with-lmdb[[=PATH]]], [use Lightning MDB to store runtime data])]) AS_IF([test $WITH_TOKYO -eq 0 && test $WITH_QDBM -eq 0 && (! test -n "$with_lmdb" || test "x$with_lmdb" != "xno")], [WITH_LMDB=1], [WITH_LMDB=0]) if test $WITH_LMDB = 1; then CF3_WITH_LIBRARY(lmdb, [ AC_CHECK_LIB(lmdb, mdb_dbi_open, [], [AC_MSG_ERROR(Cannot find Lightning MDB)]) AC_CHECK_HEADERS(lmdb.h, [], [AC_MSG_ERROR(Cannot find Lightning MDB)]) AC_DEFINE(LMDB, 1, [Define if Lightning MDB is available]) ]) fi if test $WITH_QDBM -eq 0 && test $WITH_TOKYO -eq 0 && test $WITH_LMDB -eq 0; then AC_MSG_ERROR(Either Tokyo Cabinet, LMDB, or QDBM must be selected to compile CFEngine) fi dnl dnl OpenSSL dnl AC_ARG_WITH(openssl, [AS_HELP_STRING([--with-openssl[[=PATH]]], [Specify OpenSSL path])], [], [with_openssl=yes]) if test x"$with_openssl" = xno ; then AC_MSG_ERROR([This release of CFEngine requires OpenSSL >= 0.9.7]) fi if test -d /usr/local/Cellar/ && \ test -d /usr/local/opt/openssl/ && \ test "x$with_openssl" = "xyes" ; then with_openssl=$(brew --prefix openssl) echo "OS X Homebrew detected" echo "Defaulting to: --with-openssl=$with_openssl" fi CF3_WITH_LIBRARY(openssl, [ AC_CHECK_LIB(crypto, RSA_generate_key_ex, [], []) AC_CHECK_LIB(ssl, SSL_free, [], []) AC_CHECK_DECLS([SSL_CTX_clear_options], [], [], [[#include ]]) AC_CHECK_HEADERS([openssl/opensslv.h], [], [AC_MSG_ERROR(Cannot find OpenSSL)]) AC_MSG_CHECKING(for OpenSSL version) AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ #include #if OPENSSL_VERSION_NUMBER < 0x1000000fL #This OpenSSL is too old #endif ]])],[AC_MSG_RESULT(OK)],[AC_MSG_ERROR(This release of CFEngine requires OpenSSL >= 1.0.0)]) if test "x$ac_cv_lib_crypto_RSA_generate_key_ex" = "xno" ; then AC_MSG_ERROR(Cannot find OpenSSL) fi AC_DEFINE([OPENSSL_SUPPRESS_DEPRECATED], [1], [Suppress deprecation warnings from OpenSSL 3]) AC_CHECK_DECL([SSL_OP_NO_TLSv1_1], [AC_DEFINE([HAVE_TLS_1_1], [1], [Define if TLS 1.1 is supported by OpenSSL])], [], [[#include ]] ) AC_CHECK_DECL([SSL_OP_NO_TLSv1_2], [AC_DEFINE([HAVE_TLS_1_2], [1], [Define if TLS 1.2 is supported by OpenSSL])], [], [[#include ]] ) AC_CHECK_DECL([SSL_OP_NO_TLSv1_3], [AC_DEFINE([HAVE_TLS_1_3], [1], [Define if TLS 1.3 is supported by OpenSSL])], [], [[#include ]] ) ]) dnl PCRE2 AC_ARG_WITH([pcre2], [AS_HELP_STRING([--with-pcre2[[=PATH]]], [Specify PCRE2 path])], [], [with_pcre2=yes]) if test "x$with_pcre2" = "xno"; then AC_MSG_ERROR([PCRE2 is required]) fi CF3_WITH_LIBRARY(pcre2, [ AC_CHECK_LIB(pcre2-8, pcre2_compile_8, [], [AC_MSG_ERROR(Cannot find PCRE2)]) AC_CHECK_HEADERS( [pcre2.h], [], AC_MSG_ERROR(Cannot find PCRE2), [#define PCRE2_CODE_UNIT_WIDTH 8] )] ) dnl defined for libntech AC_DEFINE(WITH_PCRE2, 1, [Define if PCRE2 is being used]) dnl libvirt AC_ARG_WITH([libvirt], [AS_HELP_STRING([--with-libvirt[[=PATH]]], [support virtual machine management])], [], [with_libvirt=check]) if test "x$with_libvirt" != xno then CF3_WITH_LIBRARY(libvirt, [ AC_CHECK_LIB(virt, virConnectOpen, [], [if test "x$with_libvirt" != xcheck; then AC_MSG_ERROR(Cannot find libvirt library); fi]) AC_CHECK_HEADERS(libvirt/libvirt.h, [], [if test "x$with_libvirt" != xcheck; then AC_MSG_ERROR(Cannot find libvirt library headers); fi]) ]) fi dnl BIG FAT WARNING FOR AC_CHECK_LIB: *always* leave the dnl "action-if-yes" parameter empty else LIBS is not changed and C dnl define is not generated! Or use AC_SEARCH_LIBS for a better dnl interface. dnl libacl dnl It is enough for any of the header files [acl.h sys/acl.h acl/libacl.h] to be present AC_ARG_WITH([libacl], [AS_HELP_STRING([--with-libacl[[=PATH]]], [Specify libacl path])], [], [with_libacl=check]) if test "x$with_libacl" != xno then CF3_WITH_LIBRARY(libacl, [ AC_CHECK_LIB(acl, acl_init, [], [if test "x$with_libacl" != xcheck; then AC_MSG_ERROR(Cannot find libacl library); fi]) AC_CHECK_HEADERS([acl.h sys/acl.h acl/libacl.h], [libacl_header_found=yes]) if test "x$libacl_header_found" != "xyes" && test "x$with_libacl" != xcheck; then AC_MSG_ERROR(Cannot find libacl library headers); fi ]) fi dnl libcurl AC_ARG_WITH([libcurl], [AS_HELP_STRING([--with-libcurl[[=PATH]]], [Specify libcurl path])], [], [with_libcurl=check]) if test "x$with_libcurl" != xno then CF3_WITH_LIBRARY(libcurl, [ AC_CHECK_LIB(curl, curl_global_init, [], [ libcurl_lib_found=no; if test "x$with_libcurl" != xcheck; then AC_MSG_ERROR(Cannot find libcurl library); fi ]) AC_CHECK_HEADERS([curl/curl.h], [libcurl_header_found=yes], [if test "x$with_libcurl" != xcheck; then AC_MSG_ERROR(Cannot find libcurl header files); fi]) ]) fi AM_CONDITIONAL(HAVE_LIBCURL, [test "x$libcurl_lib_found" != xno && test "x$libcurl_header_found" = xyes]) dnl libyaml AC_ARG_WITH([libyaml], [AS_HELP_STRING([--with-libyaml[[=PATH]]], [Specify libyaml path])], [], [with_libyaml=check]) if test "x$with_libyaml" != xno then CF3_WITH_LIBRARY(libyaml, [ AC_CHECK_LIB(yaml, yaml_parser_initialize, [], [if test "x$with_libyaml" != xcheck; then AC_MSG_ERROR(Cannot find libyaml library); fi]) AC_CHECK_HEADERS(yaml.h, [libyaml_header_found=yes], [if test "x$with_libyaml" != xcheck; then AC_MSG_ERROR(Cannot find libyaml header files); fi]) ]) fi dnl libxml2 AC_ARG_WITH([libxml2], [AS_HELP_STRING([--with-libxml2[[=PATH]]], [Specify libxml2 path]) ], [], [with_libxml2=check]) have_libxml2="no" if test "x$with_libxml2" != "xno"; then if test -n "$PKG_CONFIG"; then AC_MSG_CHECKING([for libxml2 via pkg-config]) if `$PKG_CONFIG --exists libxml-2.0`; then LIBXML2_CFLAGS=`$PKG_CONFIG --cflags libxml-2.0` LIBXML2_CPPFLAGS="$LIBXML2_CFLAGS" LIBXML2_LIBS=`$PKG_CONFIG --libs libxml-2.0` LIBXML2_VERSION=`$PKG_CONFIG --modversion libxml-2.0` AC_MSG_RESULT([found version $LIBXML2_VERSION]) have_libxml2="yes" else AC_MSG_RESULT([not found]) fi fi if test "x$have_libxml2" = "xno"; then if test "x$with_libxml2" != "xyes" && test "x$with_libxml2" != "xcheck" && test -x "$with_libxml2/bin/xml2-config" then XML2_CONFIG=$with_libxml2/bin/xml2-config else AC_PATH_PROG([XML2_CONFIG], [xml2-config]) fi # xml2-config is only for native builds if test "x$cross_compiling" = "xno" && test -n "$XML2_CONFIG"; then xml2_include_dir=`$XML2_CONFIG --cflags` if test -n "$xml2_include_dir"; then LIBXML2_CPPFLAGS="$xml2_include_dir" fi else # xml2-config not found # if a path, e.g. /var/cfengine was given, then we # must take into account that libxml2 includes are in # /var/cfengine/include/libxml2 LIBXML2_CPPFLAGS=-I$with_libxml2/include/libxml2 fi fi CF3_WITH_LIBRARY(libxml2, [AC_CHECK_LIB(xml2, xmlFirstElementChild, [], [if test "x$with_libxml2" != xcheck; then AC_MSG_ERROR(Cannot find libxml2); fi] ) AC_CHECK_HEADERS([libxml/xmlwriter.h], [break], [if test "x$with_libxml2" != xcheck; then AC_MSG_ERROR(Cannot find libxml2); fi] )] ) fi AM_CONDITIONAL([HAVE_LIBXML2], [test "x$with_libxml2" != xno && test "x$ac_cv_lib_xml2_xmlFirstElementChild" = xyes]) dnl avahi AC_ARG_WITH([avahi], [AS_HELP_STRING([--with-avahi@<:@=yes/no/check@:>@], [Compile with Avahi support @<:@default=no@:>@])], [], [with_avahi=no]) if test "x$with_avahi" != xno then AC_CHECK_HEADERS([avahi-client/client.h], [AM_CONDITIONAL(HAVE_AVAHI_CLIENT, true)], [AM_CONDITIONAL(HAVE_AVAHI_CLIENT, false) test "x$with_avahi" != "xcheck" && AC_MSG_ERROR(Cannot find avahi-client/client.h)]) AC_CHECK_HEADERS([avahi-common/address.h], [AM_CONDITIONAL(HAVE_AVAHI_COMMON, true)], [AM_CONDITIONAL(HAVE_AVAHI_COMMON, false) test "x$with_avahi" != "xcheck" && AC_MSG_ERROR(Cannot find avahi-common/address.h)]) else AM_CONDITIONAL(HAVE_AVAHI_CLIENT, false) AM_CONDITIONAL(HAVE_AVAHI_COMMON, false) fi dnl dnl ###################################################################### dnl Checks for header files. dnl ###################################################################### AC_CHECK_HEADERS(unistd.h stdlib.h sys/loadavg.h) AC_CHECK_HEADERS(sys/param.h sys/resource.h) # sys/param.h is required for sys/mount.h on OpenBSD AC_CHECK_HEADERS(sys/mount.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) # Required on BSD to get struct sockaddr_dl (for retrieving MAC addresses from getifaddrs()) AC_CHECK_HEADERS(net/if_dl.h) # Required on Solaris to get struct arpreq (for retrieving MAC addresses) AC_CHECK_HEADERS(net/if_arp.h, , , [AC_INCLUDES_DEFAULT #include ]) AC_CHECK_HEADERS(getopt.h, [system_getopt_h=1], [system_getopt_h=0]) AM_CONDITIONAL([NO_SYSTEM_GETOPT_H], [test x$system_getopt_h = x0]) AC_CHECK_HEADERS(utime.h) AC_CHECK_HEADERS(time.h) AC_CHECK_HEADERS(sys/time.h) AC_CHECK_HEADERS(malloc.h sys/malloc.h) AC_CHECK_HEADERS(vfs.h) AC_CHECK_HEADERS(sys/vfs.h) AC_CHECK_HEADERS(sys/sockio.h) AC_CHECK_HEADERS(sys/statvfs.h) AC_CHECK_HEADERS(sys/statfs.h) AC_CHECK_HEADERS(fcntl.h) AC_CHECK_HEADERS(sys/filesys.h) AC_CHECK_HEADERS(dustat.h) AC_CHECK_HEADERS(sys/systeminfo.h) AC_CHECK_HEADERS(ieeefp.h) AC_CHECK_HEADERS(winsock2.h) AC_CHECK_HEADERS(ws2tcpip.h) AC_CHECK_HEADERS(zone.h) AC_CHECK_HEADERS(sys/uio.h) AC_CHECK_HEADERS_ONCE([sys/sysmacros.h]) dnl glibc deprecated inclusion in sys/type.h AC_CHECK_HEADERS(sys/types.h) AC_CHECK_HEADERS(sys/mpctl.h) dnl For HP-UX $(sys.cpus) - Mantis #1069 AC_CHECK_HEADERS(shadow.h) AC_CHECK_HEADERS(sys/jail.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) AC_CHECK_HEADERS(net/route.h netinet/in.h netinet/ip.h) AC_HEADER_STDC AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_HEADER_DIRENT AC_HEADER_STDBOOL dnl ###################################################################### dnl Checks for data types dnl ###################################################################### AC_TYPE_MODE_T AC_TYPE_SIZE_T AC_TYPE_UID_T AC_TYPE_PID_T AC_CHECK_TYPES(clockid_t, [], [], [[ #ifdef HAVE_TIME_H # include #endif ]]) AC_CHECK_TYPES(socklen_t, [], [], [[ #ifdef HAVE_SYS_TYPES_H # include #endif #include ]]) dnl ###################################################################### dnl Checks for typedefs, structures, and compiler characteristics. dnl ###################################################################### AC_C_CONST AC_SYS_LARGEFILE AC_TYPE_OFF_T # # AC_SYS_LARGEFILE correctly figures out necessary macros for large files, but # on AIX there is a gotcha: # # Code generated by flex #includes at the beginning of the file, which # picks up 32-bit wide off_t. Then it #includes which provides LFS # macros, and finally it includes another system header, now with 64-bit wide # off_t, which causes a conflict. # if test "x$ac_cv_sys_large_files" = x1; then CPPFLAGS="-D_LARGE_FILES=1 $CPPFLAGS" fi dnl ###################################################################### dnl Check for libraries dnl ###################################################################### AC_CHECK_LIB(m, sqrt) AC_CHECK_LIB(rt, clock_gettime) AC_CHECK_LIB(dl, dlopen) dnl ###################################################################### dnl Check for special functions dnl ###################################################################### AC_CHECK_DECLS(clock_gettime, [], [], [[#include ]]) AC_CHECK_DECLS(unsetenv) AC_CHECK_DECLS(strnlen) AC_CHECK_DECLS(seteuid) AC_CHECK_DECLS(setlinebuf) AC_CHECK_DECLS(strlcat) AC_CHECK_DECLS(strlcpy) AC_CHECK_DECLS(realpath) AC_CHECK_DECLS(strdup) AC_CHECK_DECLS(memrchr) AC_CHECK_DECLS(round, [], [], [[#include ]]) AC_CHECK_DECLS(nanosleep) AC_CHECK_DECLS(memdup) AC_CHECK_DECLS(memmem) AC_CHECK_DECLS(srand48) AC_CHECK_DECLS(drand48) AC_CHECK_DECLS(strerror) AC_CHECK_DECLS(strstr) AC_CHECK_DECLS(strcasestr) AC_CHECK_DECLS(strcasecmp) AC_CHECK_DECLS(strncasecmp) AC_CHECK_DECLS(strsep) AC_CHECK_DECLS(strsignal) AC_CHECK_DECLS(gmtime_r, [], [], [[#include ]]) AC_CHECK_DECLS(getline, [], [], [#define _GNU_SOURCE 1 AC_INCLUDES_DEFAULT]) AC_CHECK_DECLS(strchrnul, [], [], [#define _GNU_SOURCE 1 AC_INCLUDES_DEFAULT]) AC_CHECK_DECLS(localtime_r, [], [], [[#include ]]) AC_CHECK_DECLS(fgetgrent, [], [], [[#include ]]) AC_CHECK_DECLS(isfinite, [], [], [[#include ]]) AC_CHECK_FUNCS(getpwent setpwent endpwent) AC_CHECK_FUNCS(fgetspent lckpwdf ulckpwdf) AC_CHECK_LIB([sec], [fgetspent], [ AC_DEFINE([HAVE_LIBSEC], 1, [Define if -lsec is available]) AC_DEFINE([HAVE_FGETSPENT], 1, [Define if fgetspent is available]) LIBS="-lsec $LIBS" ]) AC_CHECK_DECLS(getloadavg) AC_FUNC_GETLOADAVG AC_C_BIGENDIAN AC_CHECK_HEADERS([endian.h]) AC_CHECK_DECLS(le32toh, [], [], [[#include ]]) AC_CHECK_DECLS(closefrom, [], [], [[#include #include ]]) AC_CHECK_HEADERS([sys/pstat.h]) AC_CHECK_FUNCS(pstat_getfile2) CF3_PATH_ROOT_PROG([CHPASSWD], [chpasswd], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$CHPASSWD" != "x"], [AC_DEFINE(HAVE_CHPASSWD, 1, [Define if chpasswd tool is present])] [AC_DEFINE_UNQUOTED(CHPASSWD, ["$CHPASSWD"], [Path to chpasswd tool])] ) dnl AIX has this. CF3_PATH_ROOT_PROG([PWDADM], [pwdadm], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$PWDADM" != "x"], [AC_DEFINE(HAVE_PWDADM, 1, [Define if pwdadm tool is present])] [AC_DEFINE_UNQUOTED(PWDADM, ["$PWDADM"], [Path to pwdadm tool])] ) CF3_PATH_ROOT_PROG([USERADD], [useradd], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$USERADD" != "x"], [AC_DEFINE(HAVE_USERADD, 1, [Define if useradd tool is present])] [AC_DEFINE_UNQUOTED(USERADD, ["$USERADD"], [Path to useradd tool])] ) CF3_PATH_ROOT_PROG([USERMOD], [usermod], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$USERMOD" != "x"], [AC_DEFINE(HAVE_USERMOD, 1, [Define if usermod tool is present])] [AC_DEFINE_UNQUOTED(USERMOD, ["$USERMOD"], [Path to usermod tool])] ) CF3_PATH_ROOT_PROG([USERDEL], [userdel], [], [/sbin:/usr/sbin:/bin:/usr/bin:$PATH]) AS_IF([test "x$USERDEL" != "x"], [AC_DEFINE(HAVE_USERDEL, 1, [Define if userdel tool is present])] [AC_DEFINE_UNQUOTED(USERDEL, ["$USERDEL"], [Path to userdel tool])] ) AS_IF([test "x$USERADD" != x && \ test "x$USERMOD" != x && test "x$USERDEL" != x], [have_userprogs=yes], [have_userprogs=no] ) dnl FreeBSD CF3_PATH_ROOT_PROG([CHPASS], [chpass], [], [/usr/bin:$PATH]) AS_IF([test "x$CHPASS" != "x"], [AC_DEFINE(HAVE_CHPASS, 1, [Define if chpass tool is present])] [AC_DEFINE_UNQUOTED(CHPASS, ["$CHPASS"], [Path to chpass tool])] ) CF3_PATH_ROOT_PROG([PW], [pw], [], [/usr/sbin:$PATH]) AS_IF([test "x$PW" != "x"], [AC_DEFINE(HAVE_PW, 1, [Define if pw tool is present])] [AC_DEFINE_UNQUOTED(PW, ["$PW"], [Path to pw tool])] ) AS_IF([test "x$CHPASS" != x && \ test "x$PW" != x], [have_userprogs=yes], [have_userprogs=no] ) AC_ARG_WITH([pam], AS_HELP_STRING([--with-pam], [Compile with PAM support])) AS_IF([test x$with_pam != xno], [ CF3_WITH_LIBRARY(pam, [ AC_CHECK_LIB(pam, pam_start) AC_CHECK_HEADERS([security/pam_appl.h]) ]) dnl These platforms must have pam, others can have it, but not required. AS_CASE([$target_os], [*gnu*|*solaris*|*aix*|*hpux*|*hp-ux*], [ AS_IF([test "x$ac_cv_lib_pam_pam_start" != "xyes"], [AC_MSG_ERROR(Cannot find PAM library)] ) AS_IF([test "x$ac_cv_header_security_pam_appl_h" != "xyes"], [AC_MSG_ERROR(Cannot find PAM headers)] )] ) AS_IF([test "x$ac_cv_lib_pam_pam_start" = "xyes" && \ test "x$ac_cv_header_security_pam_appl_h" = "xyes"], [have_pam=yes], [have_pam=no] ) AC_CHECK_FUNCS(fgetpwent fgetgrent) AS_IF([test "x$ac_cv_func_fgetpwent" = "xyes" && \ test "x$ac_cv_func_fgetgrent" = "xyes"], [have_fgetpwent_fgetgrent=yes] [AC_DEFINE(HAVE_FGETPWENT_FGETGRENT, 1, [Define if fgetpwent and fgetgrent functions are present])], [have_fgetpwent_fgetgrent=no] ) AS_CASE(["$target_os"], [freebsd*], [ AS_IF([test "x$have_pam" = "xyes" && \ test "x$have_userprogs" = "xyes"], [users_promises_ok=yes], [users_promises_ok=no]) ], [ AS_IF([test "x$have_pam" = "xyes" && \ test "x$have_userprogs" = "xyes" test "x$ac_cv_func_fgetpwent" = "xyes" && \ test "x$ac_cv_func_fgetgrent" = "xyes"], [users_promises_ok=yes], [users_promises_ok=no]) ]) ], [ users_promises_ok=no ]) AM_CONDITIONAL(HAVE_USERS_PROMISE_DEPS, [test "x$users_promises_ok" = "xyes"]) AC_CHECK_DECLS(getnetgrent, [], [], [[#include ]]) AC_CHECK_FUNCS(getnetgrent) AC_CHECK_DECLS(setnetgrent, [], [], [[#include ]]) AC_CHECK_FUNCS(setnetgrent) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[extern int setnetgrent(const char *)]])], [AC_DEFINE([SETNETGRENT_RETURNS_INT], 1, [Whether setnetgrent returns int])], [AC_DEFINE([SETNETGRENT_RETURNS_INT], 0, [Whether setnetgrent returns int])]) AC_CHECK_DECLS(endnetgrent, [], [], [[#include ]]) AC_CHECK_FUNCS(endnetgrent) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[extern int endnetgrent(const char *)]])], [AC_DEFINE([ENDNETGRENT_RETURNS_INT], 1, [Whether endnetgrent returns int])], [AC_DEFINE([ENDNETGRENT_RETURNS_INT], 0, [Whether endnetgrent returns int])]) AC_CHECK_FUNCS(sendto) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)]])], [AC_DEFINE([SENDTO_RETURNS_SSIZE_T], 1, [Whether sendto returns ssize_t])], [AC_DEFINE([SENDTO_RETURNS_SSIZE_T], 0, [Whether sendto does not returns ssize_t])]) CF3_CHECK_PROPER_FUNC([ctime], [], [[#error ctime(3) may produce different results on different OSes. Let's have our POSIX-compliant implementation all the time]], [#define ctime rpl_ctime]) dnl Check whether mkdir accepts two parameters CF3_CHECK_PROPER_FUNC([mkdir], [[#include #include ]], [[int mkdir(const char *pathname, mode_t mode);]], [#define mkdir rpl_mkdir]) dnl Check for Win32 stat. We don't know to detect improper stat during dnl compilation, so we resort to OS type detection. CF3_CHECK_PROPER_FUNC([stat], [[#include #include ]], [[#if defined(__MINGW32__) #error stat in Windows CRT ill-behaves #endif]], []) dnl Check for Win32 rename. We don't know how to detect improper rename (not dnl removing target file if it exists) during cross-compilation, so we resort to dnl OS type detection. CF3_CHECK_PROPER_FUNC([rename], [], [[#if defined(__MINGW32__) #error rename in Windows CRT ill-behaves #endif]], [#define rename rpl_rename]) AC_CHECK_DECLS(mkdtemp) AC_CHECK_DECLS(strrstr) AC_CHECK_DECLS(stpncpy) AC_CHECK_FUNCS(seteuid setegid setreuid setregid) AC_CHECK_FUNCS(uname gethostname chflags) AC_CHECK_FUNCS(mkfifo statfs statvfs door) AC_CHECK_FUNCS(sysinfo setsid sysconf) AC_CHECK_FUNCS(getzoneid getzonenamebyid) AC_CHECK_FUNCS(fpathconf) AC_CHECK_MEMBERS([struct stat.st_mtim, struct stat.st_mtimespec]) AC_CHECK_MEMBERS([struct stat.st_blocks]) AC_MSG_CHECKING([for PRIuMAX/PRIdMAX macros]) AC_EGREP_CPP([primacros_found], AC_INCLUDES_DEFAULT [#include #if defined(PRIuMAX) && defined(PRIdMAX) primacros_found #endif ], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) AC_MSG_RESULT(Unable to find out how to scan intmax_t/uintmax_t types)]) HW_FUNC_VSNPRINTF HW_FUNC_SNPRINTF HW_FUNC_VASPRINTF HW_FUNC_ASPRINTF dnl dirfd might be a function or a macro AC_CHECK_DECLS(dirfd, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_DIRENT_H # include #endif ]) AC_CHECK_FUNCS(dirfd, [], [ AC_MSG_CHECKING([for dirfd macro]) AC_EGREP_CPP([dirfd_found], AC_INCLUDES_DEFAULT [#ifdef HAVE_DIRENT_H # include #endif #ifdef dirfd dirfd_found #endif ], [AC_MSG_RESULT(yes) DIRFD_MACRO_FOUND=1], [AC_MSG_RESULT(no)]) ]) AC_CHECK_FUNCS(jail_get) dnl dnl Various functions dnl AC_SEARCH_LIBS(setsockopt, socket) AC_SEARCH_LIBS(gethostent, nsl) AC_CHECK_FUNCS(socket) AC_CHECK_FUNCS(setsockopt) AC_CHECK_FUNCS(gethostent) AC_CHECK_TYPES(struct sockaddr_storage, [], [], [[ #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif]]) AC_CHECK_DECLS(getaddrinfo, [], [], [[ #if HAVE_WINSOCK2_H #include #endif #if HAVE_WS2TCPIP_H #include #else #include #include #endif ]]) AC_CHECK_DECLS([[inet_ntop], [inet_pton]], [], [], [[#include ]]) AC_CHECK_FUNCS(getifaddrs) AC_CHECK_FUNCS(getprocs64) AC_CHECK_FUNC(lchown, AC_DEFINE(HAVE_LCHOWN, 1, [Whether to use lchown(3) to change ownerships])) AC_CHECK_DECLS(pthread_attr_setstacksize, [], [], [[#include ]]) AC_CHECK_DECLS(pthread_sigmask, [], [], [[#include ]]) AC_CHECK_DECLS(sched_yield, [], [], [[#include ]]) AC_CHECK_FUNCS(sched_yield) AC_CHECK_DECLS([openat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([fstatat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([fchownat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([fchmodat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([readlinkat], [], [], [[#define _GNU_SOURCE 1 #include ]]) AC_CHECK_DECLS([log2], [], [], [[#include ]]) dnl ###################################################################### dnl Required by cf-upgrade. It cannot be implemented in libcompat because dnl cf-upgrade does not link to any libraries except libutils and only dnl statically. dnl ###################################################################### AC_CHECK_FUNC(fexecve, AC_DEFINE(HAVE_FEXECVE, 1, [Whether to use fexecve(3) to execute a new process])) dnl ###################################################################### dnl These need declarations here, but will be defined in the dnl Enterprise Windows code. dnl ###################################################################### AC_CHECK_DECLS(alarm) AC_CHECK_DECLS(chmod) AC_CHECK_DECLS(chown) AC_CHECK_DECLS(fchmod) AC_CHECK_FUNCS(fchmod) AC_CHECK_DECLS(uname) AC_CHECK_DECLS(getuid) AC_CHECK_DECLS(getgid) AC_CHECK_DECLS(lstat) AC_CHECK_FUNCS(sleep) AC_CHECK_DECLS(socketpair, [], [], [[#include ]]) AC_CHECK_DECLS(fsync) AC_CHECK_DECLS(glob, [], [], [[#include ]]) AC_CHECK_DECLS(gettid, [], [], [[ #define _GNU_SOURCE #include ]]) dnl ###################################################################### dnl Check for sa_len in struct sockaddr dnl ###################################################################### AC_CHECK_MEMBERS([struct sockaddr.sa_len], , , [ #include #include ]) AC_CHECK_MEMBERS([struct ifreq.ifr_hwaddr],,, [ #include #include ]) dnl BSD uses sys/sysctl.h for CPU counting AC_CHECK_HEADERS(sys/sysctl.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) dnl ###################################################################### dnl Requirements for GetUptimeMinutes() to set $(sys.uptime) dnl ###################################################################### dnl Linux sysinfo() call AC_CHECK_MEMBERS([struct sysinfo.uptime], , , [#include ]) dnl BSD uses sys/sysctl.h to get time-of-boot AC_CHECK_HEADERS(sys/sysctl.h, [], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_PARAM_H # include #endif ]) dnl Solaris uses kstat.h to get time-of-boot AC_CHECK_HEADERS(kstat.h) dnl SystemV way to get uptime, highly portable AC_CHECK_HEADERS(utmp.h) dnl POSIX way to get uptime AC_CHECK_HEADERS(utmpx.h) dnl ###################################################################### dnl Fancy new Linux syscalls for file/data copying (config for libntech) dnl ###################################################################### AC_CHECK_HEADERS([linux/fs.h]) AC_CHECK_DECLS([FICLONE], [], [], [#include ]) AC_CHECK_DECLS([SEEK_DATA], [], [], [ #define _GNU_SOURCE #include ]) AC_CHECK_DECLS([FALLOC_FL_PUNCH_HOLE], [], [], [ #define _GNU_SOURCE #include ]) AC_CHECK_HEADERS([sys/sendfile.h]) AC_CHECK_FUNCS([sendfile]) AC_CHECK_FUNCS([copy_file_range]) dnl ####################################################################### dnl Newer BSD systems don't have a compatible rtentry - use ortentry dnl ####################################################################### rtry=none AC_MSG_CHECKING(for either struct rtentry or struct ortentry) AC_EGREP_HEADER(rtentry, net/route.h, rtry=rtentry) if test "$rtry" = rtentry; then AC_DEFINE(HAVE_RTENTRY, 1, [Do we have any route entry structure?]) fi AC_EGREP_HEADER(ortentry, net/route.h, rtry=ortentry) if test "$rtry" = ortentry; then AC_DEFINE(HAVE_ORTENTRY, 1, [The old route entry structure in newer BSDs]) fi AC_MSG_RESULT([$rtry]) dnl ####################################################################### dnl Enable extended attributes. Used for SELinux and ACLs dnl ####################################################################### AC_CHECK_FUNCS(llistxattr, [AC_DEFINE(WITH_XATTR, 1, [Define if you have a libc that supports extended attributes])]) AC_CHECK_HEADERS([attr/xattr.h sys/xattr.h]) AC_MSG_CHECKING([whether xattr functions have extra arguments]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include #include ], [(void)llistxattr("", 0, 0, 0); (void)lgetxattr("", "", 0, 0, 0, 0); (void)lsetxattr("", "", "", 0, 0, 0); (void)lremovexattr("", "", 0);])], [AC_DEFINE(WITH_XATTR_EXTRA_ARGS, 1, [Define if your xattr implementation has extra arguments])] [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) dnl ###################################################################### dnl Give the chance to enable SELINUX dnl ###################################################################### AC_ARG_ENABLE([selinux], [AS_HELP_STRING([--enable-selinux], [Deprecated. SELinux support is always enabled])]) dnl ###################################################################### dnl Collect all the options dnl ###################################################################### CORE_CPPFLAGS="$LMDB_CPPFLAGS $TOKYOCABINET_CPPFLAGS $QDBM_CPPFLAGS $PCRE2_CPPFLAGS $OPENSSL_CPPFLAGS $SQLITE3_CPPFLAGS $LIBACL_CPPFLAGS $LIBCURL_CPPFLAGS $LIBYAML_CPPFLAGS $POSTGRESQL_CPPFLAGS $MYSQL_CPPFLAGS $LIBXML2_CPPFLAGS $CPPFLAGS $CFECOMPAT_CPPFLAGS" CORE_CFLAGS="$LMDB_CFLAGS $TOKYOCABINET_CFLAGS $QDBM_CFLAGS $PCRE2_CFLAGS $OPENSSL_CFLAGS $SQLITE3_CFLAGS $LIBACL_CFLAGS $LIBCURL_CFLAGS $LIBYAML_CFLAGS $POSTGRESQL_CFLAGS $MYSQL_CFLAGS $LIBXML2_CFLAGS $CFLAGS" CORE_LDFLAGS="$LMDB_LDFLAGS $TOKYOCABINET_LDFLAGS $QDBM_LDFLAGS $PCRE2_LDFLAGS $OPENSSL_LDFLAGS $SQLITE3_LDFLAGS $LIBACL_LDFLAGS $LIBCURL_LDFLAGS $LIBYAML_LDFLAGS $POSTGRESQL_LDFLAGS $MYSQL_LDFLAGS $LIBXML2_LDFLAGS $LDFLAGS" CORE_LIBS="$LMDB_LIBS $TOKYOCABINET_LIBS $QDBM_LIBS $PCRE2_LIBS $OPENSSL_LIBS $SQLITE3_LIBS $LIBACL_LIBS $LIBCURL_LIBS $LIBYAML_LIBS $POSTGRESQL_LIBS $MYSQL_LIBS $LIBXML2_LIBS $LIBS" dnl ###################################################################### dnl Make them available to subprojects. dnl ###################################################################### AC_SUBST([CORE_CPPFLAGS]) AC_SUBST([CORE_CFLAGS]) AC_SUBST([CORE_LDFLAGS]) AC_SUBST([CORE_LIBS]) AC_CONFIG_FILES([configure_flags.env]) dnl ###################################################################### dnl OS specific stuff dnl ###################################################################### case "$target_os" in solaris2.8|solaris2.9) AC_DEFINE(_XOPEN_SOURCE, 500, [UNIX 98]) AC_DEFINE(__EXTENSIONS__, 1, [Extended UNIX 98 interfaces]) ;; solaris2.10|solaris2.11) AC_DEFINE(_XOPEN_SOURCE, 600, [SUSv3]) AC_DEFINE(__EXTENSIONS__, 1, [Extended UNIX 98 interfaces]) ;; hpux*|hp-ux*) dnl pstat* functions may fail with EOVERFLOW without this. AC_DEFINE(_PSTAT64, 1, [Enable wide data structures everywhere]) ;; aix*) CPPFLAGS="$CPPFLAGS -w" ;; linux*|*bsd*|*gnu*) AC_CHECK_LIB(nss_nis, yp_get_default_domain) ;; freebsd*|dragonfly*) AM_CONDITIONAL([FREEBSD], true) ;; netbsd*) ;; unicos*) ;; cray*) ;; qnx*) ;; openbsd*|obsd*) ;; sysv4.2MP|unix_sv*) ;; cygwin*) ;; mingw*) ;; sco*) ;; darwin*) ;; *) AC_MSG_ERROR(Unknown system type $target_os) ;; esac m4_include([m4/cf3_platforms.m4]) dnl ##################################################################### dnl Configure directories dnl ##################################################################### AC_ARG_WITH(workdir, [ --with-workdir=WORKDIR default for internal (trusted) working directory ], [ if test "x$withval" != x ; then WORKDIR="$withval" LOGDIR="$withval" PIDDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in WORKDIR adl_RECURSIVE_EVAL("${WORKDIR}", WORKDIR) AC_DEFINE_UNQUOTED(WORKDIR, "${WORKDIR}", [Workdir location]) AC_SUBST(workdir, "${WORKDIR}") AC_ARG_WITH(masterdir, [ --with-masterdir=MASTERDIR default for internal masterfiles directory ], [ if test "x$withval" != x ; then MASTERDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in MASTERDIR adl_RECURSIVE_EVAL("${MASTERDIR}", MASTERDIR) AC_DEFINE_UNQUOTED(MASTERDIR, "${MASTERDIR}", [Masterfiles directory location]) AC_SUBST(masterdir, "${MASTERDIR}") AC_ARG_WITH(inputdir, [ --with-inputdir=INPUTDIR default for internal inputs directory ], [ if test "x$withval" != x ; then INPUTDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in INPUTDIR adl_RECURSIVE_EVAL("${INPUTDIR}", INPUTDIR) AC_DEFINE_UNQUOTED(INPUTDIR, "${INPUTDIR}", [Inputs directory location]) AC_SUBST(inputdir, "${INPUTDIR}") AC_ARG_WITH(datadir, [ --with-datadir=DATADIR default for internal data directory ], [ if test "x$withval" != x ; then DATADIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in DATADIR adl_RECURSIVE_EVAL("${DATADIR}", DATADIR) dnl There's a conflict on mingw where they have a type called DATADIR! AC_DEFINE_UNQUOTED(CF_DATADIR, "${DATADIR}", [Datadir location]) AC_SUBST(datadir, "${DATADIR}") AC_ARG_WITH(logdir, [ --with-logdir=LOGDIR default for internal log directory ], [ if test "x$withval" != x ; then LOGDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in LOGDIR adl_RECURSIVE_EVAL("${LOGDIR}", LOGDIR) AC_DEFINE_UNQUOTED(LOGDIR, "${LOGDIR}", [Logdir location]) AC_SUBST(logdir, "${LOGDIR}") AC_ARG_WITH(piddir, [ --with-piddir=LOGDIR default for internal pid directory ], [ if test "x$withval" != x ; then PIDDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in PIDDIR adl_RECURSIVE_EVAL("${PIDDIR}", PIDDIR) AC_DEFINE_UNQUOTED(PIDDIR, "${PIDDIR}", [piddir location]) AC_SUBST(piddir, "${PIDDIR}") AC_ARG_WITH(statedir, [ --with-statedir=STATEDIR default for internal state directory ], [ if test "x$withval" != x ; then STATEDIR="$withval" fi ], ) dnl Expand ${prefix} and whatnot in STATEDIR adl_RECURSIVE_EVAL("${STATEDIR}", STATEDIR) AC_DEFINE_UNQUOTED(STATEDIR, "${STATEDIR}", [State directory location]) AC_SUBST(statedir, "${STATEDIR}") AC_ARG_WITH(shell, [AS_HELP_STRING([--with-shell=PATH], [Specify path to POSIX-compatible shell (if not /bin/sh)])], [], [with_shell=/bin/sh]) dnl Expand ${prefix} and whatnot in bindir adl_RECURSIVE_EVAL("${bindir}", bindir) AC_DEFINE_UNQUOTED(BINDIR, "${bindir}", [binaries location]) AC_SUBST(bindir, "${bindir}") if test "x$with_shell" = "xno"; then AC_MSG_ERROR([Please specify full path to POSIX-compatible shell]) fi AC_DEFINE_UNQUOTED(SHELL_PATH, "$with_shell", [Path to the POSIX-compatible shell]) dnl ###################################################################### dnl init.d script installation dnl ###################################################################### AC_ARG_WITH(init-script, AS_HELP_STRING([--with-init-script=PATH], [Install init.d script in given path. The default is no, but if specified, the default path is platform specific.]), [ if test -n "$withval" && test "x$withval" != "xno"; then if test "x$withval" = "xyes"; then AS_CASE(["$target_os"], [aix*], [ INIT_D_PATH=/etc/rc.d/init.d ], [hpux*], [ INIT_D_PATH=/sbin/init.d ], [ INIT_D_PATH=/etc/init.d ]) else INIT_D_PATH="$withval" fi AC_SUBST([INIT_D_PATH]) AC_CONFIG_FILES([misc/init.d/cfengine3], [chmod +x misc/init.d/cfengine3]) fi ]) AM_CONDITIONAL([WITH_INIT_D_SCRIPT], [test -n "$INIT_D_PATH"]) dnl ###################################################################### dnl systemd unit file installation dnl ###################################################################### SYSTEMD_SERVICE_PATH="" AC_ARG_WITH(systemd-service, AS_HELP_STRING([--with-systemd-service=PATH], [Install systemd service file in given path. The default is no, but if specified, the default path is /usr/lib/systemd/system.]), [ if test -n "$withval" && test "x$withval" != "xno"; then if test "x$withval" = "xyes"; then SYSTEMD_SERVICE_PATH=/usr/lib/systemd/system else SYSTEMD_SERVICE_PATH="$withval" fi fi ] , [ AC_PATH_PROG([systemctl], [systemctl], [no]) AS_IF([test "x$systemctl" == "xno"], [AC_MSG_CHECKING([Not a systemd system])], [ SYSTEMD_SERVICE_PATH=/usr/lib/systemd/system ]) ]) AS_IF([test "x$SYSTEMD_SERVICE_PATH" = "x"], [], [ AC_SUBST([SYSTEMD_SERVICE_PATH]) AC_CONFIG_FILES([misc/systemd/cfengine3.service]) AC_CONFIG_FILES([misc/systemd/cf-apache.service]) AC_CONFIG_FILES([misc/systemd/cf-execd.service]) AC_CONFIG_FILES([misc/systemd/cf-hub.service]) AC_CONFIG_FILES([misc/systemd/cf-reactor.service]) AC_CONFIG_FILES([misc/systemd/cf-monitord.service]) AC_CONFIG_FILES([misc/systemd/cf-postgres.service]) AC_CONFIG_FILES([misc/systemd/cf-serverd.service]) ]) AM_CONDITIONAL([WITH_SYSTEMD_SERVICE], [test -n "$SYSTEMD_SERVICE_PATH"]) AC_ARG_WITH(environment-path, AS_HELP_STRING([--with-environment-path=PATH], [Specifies the location of the environment files for the platform. Currently used only by systemd.])) OS_ENVIRONMENT_PATH= if test -z "$with_environment_path" || test "$with_environment_path" = "yes"; then if test -n "$SYSTEMD_SERVICE_PATH"; then for i in /etc/sysconfig /etc/default; do if test -d $i; then OS_ENVIRONMENT_PATH=$i break fi done if test -z "$OS_ENVIRONMENT_PATH"; then AC_MSG_ERROR([Unable to detect location of environment files on the platform (e.g. '/etc/sysconfig'). Please specify it using --with-environment-path, or turn off systemd support.]) fi fi else if test "$with_environment_path" = "no"; then if test -n "$SYSTEMD_SERVICE_PATH"; then AC_MSG_ERROR([It is not possible to both specify systemd support and not provide an environment path with --without-environment-path.]) fi else OS_ENVIRONMENT_PATH="$with_environment_path" fi fi AC_SUBST([OS_ENVIRONMENT_PATH]) dnl systemd-socket activation AC_ARG_WITH([systemd-socket], [AS_HELP_STRING([--with-systemd-socket[[=PATH]]], [support systemd socket activation])], [], [with_systemd_socket=check]) dnl ######################################################################## dnl systemd socket feature, only available if systemd init scripts requested dnl ######################################################################## if test "x$with_systemd_service" != xno && test "x$with_systemd_socket" != xno then CF3_WITH_LIBRARY(systemd_socket, [ AC_CHECK_LIB(systemd, sd_listen_fds, [], [if test "x$with_systemd_socket" != xcheck; then AC_MSG_ERROR(Cannot find systemd library); fi]) AC_CHECK_LIB(systemd, sd_notify_barrier, [AC_DEFINE([HAVE_SD_NOTIFY_BARRIER],[1],[sd_notify_barrier on recent systemd])]) AC_CHECK_HEADERS(systemd/sd-daemon.h, [], [if test "x$with_systemd_socket" != xcheck; then AC_MSG_ERROR(Cannot find systemd headers); fi]) ]) fi dnl ##################################################################### dnl SELinux policy build and installation dnl ##################################################################### AC_ARG_WITH(selinux-policy, AS_HELP_STRING([--with-selinux-policy], [Whether to build and install SELinux policy (default: no)]), [], [with_selinux_policy=no]) AM_CONDITIONAL([WITH_SELINUX], [test "x$with_selinux_policy" != "xno"]) if test "x$with_selinux_policy" != "xno"; then platform_id=$(sed -r -e '/PLATFORM_ID/!d;s/PLATFORM_ID="platform:(@<:@^"@:>@+)"/\1/' < /etc/os-release) if test -f ${srcdir}/misc/selinux/cfengine-enterprise.te.$platform_id; then PLATFORM_SELINUX_POLICIES=cfengine-enterprise.te.$platform_id AC_SUBST(PLATFORM_SELINUX_POLICIES) fi fi dnl ##################################################################### dnl Hostname and Version stuff dnl ##################################################################### AC_PATH_PROG(HOSTNAME, hostname, "", $PATH) AC_DEFINE_UNQUOTED(AUTOCONF_HOSTNAME, "`$HOSTNAME`", [Special CFEngine symbol]) AC_DEFINE_UNQUOTED(AUTOCONF_SYSNAME, "$target_os", [Speial CFEngine symbol]) dnl ##################################################################### dnl xen cpuid-based hvm detection dnl ##################################################################### AC_MSG_CHECKING(for Xen cpuid-based HVM detection) if test x"$GCC" = "xyes"; then case $host_cpu in i[[3456]]86*|x86_64*|amd64) AC_DEFINE(XEN_CPUID_SUPPORT, 1, [Define if XEN cpuid-based HVM detection is available.]) AC_MSG_RESULT(yes) ;; *) AC_MSG_RESULT(no) ;; esac else AC_MSG_RESULT(no) fi dnl dnl Code coverage dnl AC_ARG_ENABLE(coverage, AS_HELP_STRING([--enable-coverage], [Enable code coverage]), [use_coverage=$enableval], [use_coverage=no]) if test "x$use_coverage" = "xyes"; then if test "$GCC" != "yes"; then AC_MSG_ERROR([GCC is required for --enable-coverage]) fi if test "$debug" != "yes"; then AC_MSG_ERROR([--enable-debug is required for --enable-coverage]) fi AC_CHECK_PROG(LCOV, lcov, lcov) AC_CHECK_PROG(LCOV_GENHTML, genhtml, genhtml) if test -z "$LCOV"; then AC_MSG_ERROR([Cannot find lcov from the LTP package]) fi if test -z "$LCOV_GENHTML"; then AC_MSG_ERROR([Could not find genhtml from the LTP package]) fi dnl Remove all optimization flags from CFLAGS changequote({,}) CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` changequote([,]) dnl Add the special gcc flags CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov" # Need to set ENABLE_COVERAGE so that tests/unit/Makefile.am can adapt for one # test which needs gcov stubs if core not built with coverage. AM_CONDITIONAL([ENABLE_COVERAGE], true) else AM_CONDITIONAL([ENABLE_COVERAGE], false) fi # # Populate contents of config.post.h # AC_SUBST(post_macros) AM_SUBST_NOTMAKE(post_macros) dnl ###################################################################### dnl Check how file descriptor transfers are supported between proceses. dnl ###################################################################### AC_CHECK_MEMBER([struct msghdr.msg_control], [AC_DEFINE([HAVE_MSGHDR_MSG_CONTROL], [1], [Define to 1 if SCM_RIGHTS supported])], [AC_DEFINE([HAVE_NO_MSGHDR_MSG_CONTROL], [1], [Define to 1 if SCM_RIGHTS support])], [[#include #include ]]) AC_CHECK_MEMBER([struct msghdr.msg_accrights], [AC_DEFINE([HAVE_MSGHDR_ACCRIGHTS], [1], [Define to 1 if BSD .msg_accrights supported])], [AC_DEFINE([HAVE_NO_MSGHDR_ACCRIGHTS], [1], [Define to 1 if no BSD .msg_accrights support])], [[#include #include ]]) dnl ###################################################################### dnl Summarize dnl ###################################################################### AC_MSG_RESULT( ) AC_MSG_RESULT(Summary:) AC_MSG_RESULT(> Version: $cfengine_version) AC_MSG_RESULT([> Required libraries]) AC_MSG_RESULT([-> OpenSSL: $OPENSSL_PATH]) AC_MSG_RESULT([-> PCRE2: $PCRE2_PATH]) if test $WITH_TOKYO = 1; then AC_MSG_RESULT([-> DB: Tokyo Cabinet: $TOKYOCABINET_PATH]) elif test $WITH_QDBM = 1; then AC_MSG_RESULT([-> DB: QDBM: $QDBM_PATH]) fi AC_MSG_RESULT([> Optional libraries]) if test "x$ac_cv_lib_mysqlclient_mysql_real_connect" = "xyes"; then AC_MSG_RESULT([-> MySQL connector: $MYSQL_PATH]) else AC_MSG_RESULT([-> MySQL connector: disabled]) fi if test "x$ac_cv_lib_pq_PQconnectdb" = "xyes"; then AC_MSG_RESULT([-> PostgreSQL connector: $POSTGRESQL_PATH]) else AC_MSG_RESULT([-> PostgreSQL connector: disabled]) fi if test $WITH_LMDB = 1; then AC_MSG_RESULT([-> DB: Lightning MDB: $LMDB_PATH]) elif test $WITH_TOKYO = 1; then AC_MSG_RESULT([-> DB: Tokyo Cabinet: $TOKYOCABINET_PATH]) elif test $WITH_QDBM = 1; then AC_MSG_RESULT([-> DB: QDBM: $QDBM_PATH]) fi if test "x$ac_cv_lib_virt_virConnectOpen" = xyes; then AC_MSG_RESULT([-> libvirt: $LIBVIRT_PATH]) else AC_MSG_RESULT([-> libvirt: disabled]) fi if test "x$ac_cv_lib_acl_acl_init" = xyes; then AC_MSG_RESULT([-> libacl: $LIBACL_PATH]) else AC_MSG_RESULT([-> libacl: disabled]) fi if test "x$ac_cv_lib_curl_curl_global_init" = xyes; then AC_MSG_RESULT([-> libcurl: $LIBCURL_PATH]) else AC_MSG_RESULT([-> libcurl: disabled]) fi if test "x$ac_cv_lib_yaml_yaml_parser_initialize" = xyes; then AC_MSG_RESULT([-> libyaml: $LIBYAML_PATH]) else AC_MSG_RESULT([-> libyaml: disabled]) fi if test "x$ac_cv_lib_xml2_xmlFirstElementChild" = xyes; then AC_MSG_RESULT([-> libxml2: $LIBXML2_PATH]) else AC_MSG_RESULT([-> libxml2: disabled]) fi if test "x$users_promises_ok" = "xyes"; then AC_MSG_RESULT([-> User promises: PAM/user* tools]) else AC_MSG_RESULT([-> User promises: disabled]) fi if test "x$enable_builtin_extensions" = "xyes"; then AC_MSG_RESULT([-> Enterprise extensions: Built in]) else AC_MSG_RESULT([-> Enterprise extensions: Plugin or not included]) fi if test -n "$INIT_D_PATH"; then AC_MSG_RESULT([-> init.d script: $INIT_D_PATH]) else AC_MSG_RESULT([-> init.d script: disabled]) fi if test -n "$SYSTEMD_SERVICE_PATH"; then AC_MSG_RESULT([-> Systemd service: $SYSTEMD_SERVICE_PATH]) else AC_MSG_RESULT([-> Systemd service: disabled]) fi if test -n "$OS_ENVIRONMENT_PATH"; then AC_MSG_RESULT([-> Path of platform environment files: $OS_ENVIRONMENT_PATH]) fi if test "x$with_selinux_policy" != "xno"; then AC_MSG_RESULT([-> SELinux policy: enabled]) AC_MSG_RESULT([-> SELinux platform policies: $PLATFORM_SELINUX_POLICIES]) else AC_MSG_RESULT([-> SELinux policy: disabled]) fi m4_indir(incstart[]incend, [nova/config.m4]) AC_MSG_RESULT([-> Workdir: $WORKDIR]) AC_MSG_RESULT([-> Masterdir: $MASTERDIR]) AC_MSG_RESULT([-> Inputdir: $INPUTDIR]) AC_MSG_RESULT([-> Datadir: $DATADIR]) AC_MSG_RESULT([-> Logdir: $LOGDIR]) AC_MSG_RESULT([-> Piddir: $PIDDIR]) AC_MSG_RESULT([-> Statedir: $STATEDIR]) AC_MSG_RESULT([-> bindir: $bindir]) AC_MSG_RESULT( ) dnl ###################################################################### dnl Now make the Makefiles dnl ###################################################################### AC_CONFIG_FILES([Makefile libcfnet/Makefile libenv/Makefile libpromises/Makefile libcfecompat/Makefile cf-agent/Makefile cf-check/Makefile cf-promises/Makefile cf-execd/Makefile cf-key/Makefile cf-monitord/Makefile cf-upgrade/Makefile cf-runagent/Makefile cf-serverd/Makefile cf-testd/Makefile cf-net/Makefile cf-secret/Makefile config.post.h contrib/vagrant-ci/centos-9s-x64/Makefile misc/Makefile misc/selinux/Makefile python/Makefile ext/Makefile examples/Makefile tests/Makefile tests/acceptance/Makefile tests/acceptance/25_cf-execd/Makefile tests/unit/Makefile tests/load/Makefile tests/static-check/Makefile tests/valgrind-check/Makefile]) # Run autoconf/configure in libutils, generating necessary makefiles: AC_CONFIG_SUBDIRS([libntech]) AC_OUTPUT AC_MSG_RESULT(DONE: Configuration done. Run make/gmake to build CFEngine Community.) cfengine-3.24.2/configure_flags.env.in0000644000000000000000000000135615010704253017634 0ustar00rootroot00000000000000CORE_CPPFLAGS="@CORE_CPPFLAGS@" CORE_CFLAGS="@CORE_CFLAGS@" CORE_LDFLAGS="@CORE_LDFLAGS@" CORE_LIBS="@CORE_LIBS@" CORE_VERSION="@VERSION@" AGENT_CPPFLAGS="@LIBVIRT_CPPFLAGS@ @POSTGRESQL_CPPFLAGS@ @MYSQL_CPPFLAGS@ @LIBXML2_CPPFLAGS@ @PAM_CPPFLAGS@" AGENT_CFLAGS="@LIBVIRT_CFLAGS@ @POSTGRESQL_CFLAGS@ @MYSQL_CFLAGS@ @LIBXML2_CFLAGS@ @PAM_CFLAGS@" AGENT_LDFLAGS="@LIBVIRT_LDFLAGS@ @POSTGRESQL_LDFLAGS@ @MYSQL_LDFLAGS@ @LIBXML2_LDFLAGS@ @PAM_LDFLAGS@" AGENT_LDADD="@LIBVIRT_LIBS@ @POSTGRESQL_LIBS@ @MYSQL_LIBS@ @LIBXML2_LIBS@ @PAM_LIBS@" hw_cv_func_mkdir_proper="@hw_cv_func_mkdir_proper@" hw_cv_func_stat_proper="@hw_cv_func_stat_proper@" hw_cv_func_rename_proper="@hw_cv_func_rename_proper@" enable_builtin_extensions="@enable_builtin_extensions@" cfengine-3.24.2/ChangeLog0000644000000000000000000051752715010704253015146 0ustar00rootroot000000000000003.24.2: - Fixed issue where rhel >8 packages would not have correct openssl dependency version (ENT-12587) - Added http_port and getattr selinux permissions as needed for selinux policy on rhel-8 and rhel-9 (ENT-12954) - Fixed bug in parsing process_select for Windows (ENT-12751) - Added "acknowledged" field to lastseen DB (ENT-11838) - Adjusted cf-support for exotic UNIX platforms (ENT-9786) - Adjusted cf-support to not fail if core dumps are available and gdb is missing (ENT-9786) - Fixed bug causing LMDB database corruption - Fixed incorrect exit code handling in cf-runagent (ENT-12712) - Fixed possible segmentation fault when backing up LMDB databases - In case of LMDB migration failures, the respective database file is now moved to the side, and a fresh database is created. - cf-agent now creates backup before LMDB migration - Re-enabled DB migration support for LMDB - SELinux: Allow cf-serverd to set its own limits (ENT-12446) 3.24.1: - Fixed multiple issues in cfengine-enterprise SELinux policy which could cause AVC denials / warnings for various CFEngine components. (ENT-12466, ENT-12446) - Added logging CFEngine component related SELinux denials in cf-support (ENT-12137) - Agent now also ignores interfaces listed in ignore_interfaces.rx when looking for IPv6 interface info. Variables such as 'default:sys.hardware_mac[]' will no longer be defined for ignored interfaces. (ENT-11840) - Atomic copy_from in files promise Changes to 'files' promise in 'copy_from' attribute: - The new file (i.e., '.cfnew') is now created with correct permission during remote copy. Previously it would be created with default permissions. - The destination file (i.e., '') is no longer deleted on backup during file copy. Previously it would be renamed to '.cfsaved', causing the original file to dissappear. Now an actual copy of the original file with the same permissions is created instead. As a result, there will no longer be a brief moment where the original file is inaccessible. (ENT-11988) - commands promises with exit codes not matching any _returncodes attributes from classes body now log and error message not just an info message (CFE-4429, ENT-12103) 3.24.0: - Added a sanity check to policy parser that checks for and warns in case of promise declarations with no actions. The motivation for this check is to aid policy writers in detecting semantic errors early. (ENT-11137) - Added sys.os_name_human for Alpine, postmarketOS, OpenBSD and NetBSD - Added warning log message when OS is not recognized (CFE-4342) - Adjusted locale settings in masterfiles stage common script to handle more cases (ENT-11885) - Adjusted package module inventory to include quotes around fields when needed (CFE-4341) - Added 'sys.os_name_human' and 'sys.os_version_major' variables for Amazon. Additionally changed value of 'sys.flavor' from 'AmazonLinux' to 'amazon_linux_2', so that it is similar to other supported Linux distros. This change was necessary, due to the fact that the 'sys.os_version_major' variable is derived from it. However, the 'AmazonLinux' class previously derived from 'sys.flavor' is still defined for backwards compatibility. (ENT-10817) - CFEngine now uses PCRE2 for regular expressions (ENT-10629) - CFEngine processes no longer suffer from the "Invalid argument" issues when working with LMDB (ENT-11543) - Changed cf-apache systemd unit to reload configuration gracefully (ENT-11526) - Changed cf-execd's sleep behavior so it attempts to wake up at the beginning of every minute (ENT-11765) - File copying now uses more efficient implementation on Linux platforms (CFE-4380) - Fixed bug in double expansion of foreign list variables with namespaces (ENT-11923) - Fixed bug related to failing backwards directory traversial when using forward slashes in path argument of the findfiles_up() policy function on Windows. - Fixed bug where 'default:sys.fqhost' contained many spaces when domain is set in body common control (CFE-4053) - Fixed cf-support call to cf-promises to collect all classes and vars (CFE-4300) - Fixed package promises with only promisers and no other attributes (CFE-4315, CFE-4398, CFE-4408) - Modified package promise default. If platform_default is present use that package module. (CFE-4315) - Ownership of symlinks is now handled properly (ENT-11235) - SELinux no longer breaks exporting large reports as PDF (ENT-11154) - The 'arglist' attribute in the 'commands' promises now preserves whitespaces in the arguments. Whitespaces are currently not preserved on Windows, or if the 'useshell' attribute is set to anything other than '"noshell"'. (CFE-2724, CFE-4294) - Trailing newline on insert_tree promisers no longer removes ending tag for select_xpath (CFE-3806) - cf-agent has two new options --no-augments and --no-host-specific-data to skip loading augments (def.json or def_preferred.json) and host-specific data (host_specific.json), respectively (ENT-10792) - cf-agent now has a new option --skip-bootstrap-service-start to skip starting CFEngine services during the bootstrap process (ENT-11932) - cf-runalerts.service no longer exists, alerts are now periodically run by cf-reactor (ENT-11538) - depth_search acting on a non-directory promiser now handles such file as if the promise didn't use depth_search. A warning is issued in this case. (ENT-8996) - masterfiles-stage.sh now supports a new --check-only option (ENT-9386) - Added new policy variable 'sys.cfengine_roles'. This variable is a string list, containing "Reporting hub" if cf-hub exists (hub package installed), "Policy server" if the host is bootstrapped to itself ('policy_server' class defined), and just "Client" if none of the other options are true. - Added 2 new classes correlating to the values in 'sys.cfengine_roles': 'cfengine_reporting_hub' and 'cfengine_client'. 3.23.0: - Added selinux policy to allow cf-hub to initiate scheduled reports (ENT-10696, ENT-9825) - Added version_compare() policy function (CFE-3991) - Bodies can now inherit attributes containing global variables (CFE-4254) - Cached policy function results now take into account number of arguments and function name (CFE-4244) - Fixed infinite loop on error bug while reading interface exception file - Fixed inventoried policy release id when masterfiles-stage.sh deploys with cfbs (ENT-10832) - Improved locale override in masterfiles stage scripts (ENT-10753) - Improved syntax description for validjson() (ENT-9759) - Made cf-support use coredumpctl for core analysis only when configured in kerenl.core_pattern (ENT-9985) - Modified classesmatching() function to search parent bundles with inherit => true (ENT-5850) - Moved expected location of ignore_interfaces.rx from $(sys.inputdir) to $(sys.workdir). If the file is found in $(sys.inputdir) but not in $(sys.workdir), we will still process it for backwards compatability, but issue a warning prompting the user to move it to the appropriate location. (ENT-9402) - Only CFEngine processes are now killed as expired lock owners (CFE-3982) - SELinux no longer blocks CFEngine deamons in reading security parameters from /proc/sys/kernel (ENT-9684) - cf-hub is now allowed to use the TLS kernel module on SELinux-enabled systems (ENT-9727) - cf_lock.lmdb is no longer restored from backup on every boot (CFE-3982) - packagesmatching() and packageupdatesmatching() now look for the software inventory databases in the state directory and use them if found. This change enables the usage of these functions in standalone policy files without the demand for specifying the default package inventory attribute in body common control. However, you still need the default package inventory attribute specified in the policy framework for the software inventory databases to exist in the first place and to be maintained. (ENT-9083) - CFEngine locks are now purged dynamically based on the local locks DB usage/size ranging from no purging (<=25% usage) (ENT-8201, CFE-2136, ENT-5898) - `cf-check repair` now rotates DB files with high usage (>95%) (CFE-3374) - Full LMDB files are now handled gracefully by moving them aside and using new empty LMDB files (ENT-8201) - `cf-check repair` now supports the `--test-write` option to check if DBs can be written to as part of identifying DBs that need repairing (CFE-3375) - `cf-check diagnose` now shows DB usage and a hint if rotation is required - /usr/bin/getent is now attempted to be used if /bin/getent doesn't exist (CFE-4256) 3.22.0: - Added --help option to cf-support and aligned output with other components (ENT-9740) - Added classes and vars to cf-support (CFE-4160) - Added condition to runalerts service to require stamp directory (ENT-9711) - Added mctp_socket class to selinux policy (ENT-10206) - Added native core dump handling in cf-support for Solaris (ENT-9786) - Added needed SELinux class lockdown for latest RHEL 9 hosts (ENT-9685) - Adjusted cf-support for exotic/legacy POSIX systems (ENT-9340) - Adjusted cf-support for hpux mktemp command (ENT-9786) - Directories are now created with correct perms (CFE-4114) - Variables & classes modules automatically tagged (ENT-7725) - Changed bootstrap policy to preserve log level for debug, verbose, and info (CFE-4121) - Created new policy function isreadable (ENT-9380) - Enabled expireafter attribute for custom promise types (CFE-4083) - Enabled install-time SELinux policy compiling (ENT-9685) - Expired agents now terminate custom promise modules (CFE-4083) - Fixed debug module expand logging for scalars (CFE-4122) - Fixed syntax description of validjson() (ENT-9759) - Prevented cf-support from searching more than 1 level for core files (ENT-9981) - Started checking status of all cf- prefixed systemd services in cf-support (ENT-9804) - validjson() no longer accepts trailing bogus data (CFE-4080) 3.21.0: - Added cf-support utility for generating support information (ENT-9037) - Adjusted cf-check and package module code for empty updates list (ENT-9050) - '$(this.promiser)' can now be used in 'files' promise attributes 'if', 'ifvarclass' and 'unless' (CFE-2262, ENT-7008) - Fixed storage promise for nfs on MacOS (CFE-4093) - Fixed definition of _low_ldt class from cf-monitord (CFE-4022) - Insertion of contents of a file with blank lines into another file with blank lines no longer results in mixed content (ENT-8788) - Added suggestion to use a negative lookahead when non-convergent edits are attempted (CFE-192) - Unresolved function calls that return scalar values are now considered OK for constraints expecting strings during syntax check (CFE-4094) - cf-monitord now honors monitorfacility in body monitor control (ENT-4492) - cf-serverd now periodically reloads its policy if it contains unresolved variables (e.g. $(sys.policy_hub) in 'allowconnect'). (ENT-8456) - cf-serverd now starts in the network-online.target on systemd-based systems (ENT-8456) - edit_line bundles can now use the new $(edit.empty_before_use) variable mirroring the value of edit_defaults=>empty_before_use of the related files promise (ENT-5866) - Package modules with unresolved variables in their names are now skipped in package queries (ENT-9377) - Removed unsupported name_connect capability for udp_socket class (ENT-8824) - 'meta' attribute can now be used in custom promises (CFE-3440) - Custom promise modules can now support the 'action_policy' feature allowing promises of their custom types to be used in dry-run and simulation modes and in combination with 'action_policy => "warn"'. (CFE-3433) - Use of custom promise modules that don't fully specify protocol now results in warning (CFE-3433) - Warnings are logged if levels of log messages from custom promise modules don't match results of their related promises (CFE-3433) - Adjusted SELinux policy for RHEL 9 (ENT-8824) - Fixed SELinux policy to allow hub to send emails (ENT-9557, ENT-9473) - SELinux no longer breaks SQL queries with large result sets on RHEL 8 hubs (ENT-9496) - Added SELinux LDAP port access for Mission Portal (ENT-9694) - Allowed ciphers are now properly split into TLS 1.3 cipher suites and ciphers used for TLS 1.2 and older (ENT-9018) - Fixed git_cfbs_deploy_refspec in masterfiles_stage leaving temp dir (ENT-9039) 3.20.0: - 'rxdirs' now defaults to "false". This means that the read permission bit no longer implies execute bit for directories, by default. Permission bits will be exactly as specified. To restore the old behavior you can still enable 'rxdirs' explicitly. (CFE-951) - 'N' or 'Ns' signal specs can now be used to sleep between signals sent by 'processes' promises (CFE-2207, ENT-5899) - Directories named .no-distrib are no longer copied from policy server (in bootstrap/failsafe) (ENT-8079) - Files promises using content attribute or template method now create files by default unless `create => "false"` is specified. (CFE-3955, CFE-3916) - template_method mustache and inline_mustache now create file in promiser, if template rendering was successfull and file does not exist. (ENT-4792) - Added support for use of custom bodies in custom promise types (CFE-3574) - Custom promise modules now never get promise data with unresolved variables (CFE-3434) - Custom promises now use standard promise locking and support ifelapsed (CFE-3434) - Enable comment-attribute for custom promise types (CFE-3432) - cf-secret encrypt now encrypts for localhost if no key or host is specified (CFE-3874) - CFEngine now builds with OpenSSL 3 (ENT-8355) - CFEngine now requires OpenSSL 1.0.0 or newer (ENT-8355) - Moved Skipping loading of duplicate policy file messages from VERBOSE to DEBUG (CFE-3934) - CFEngine processes now try to use getent if the builtin user/group info lookup fails (CFE-3937) - No longer possible to undefine reserved hard classes (ENT-7718) - Unspecified 'rxdirs' now produces a warning (CFE-951) - Fixed wrong use of log level in users promises log messages (CFE-3906) - Fixed default for ignore_missing_bundles and ignore_missing_inputs The issue here was that these attributes should default to false, but when they are assigned with an unresolved variable, they would default to true. (ENT-8430) - Added protocol 3 (cookie) to syntax description (ENT-8560) - Moved errors from data_sysctlvalues from inform to verbose (CFE-3818) - Fixed inconsistencies with methods promises and missing bundles Previously, methods promises acted differently depending on if you specify the bundle with usebundle or in the promiser string. This change removes the inconsistent checking which was only happening on promises with usebundle. It also ensures that the agent will abort if trying to use an undefined bundle, regardless of whether it was using promiser string or usebundle. This change, combined with the fix for ignore_missing_bundles and ignore_missing_inputs, allow you to use inputs and bundles conditionally (like we do for the enterprise federation policy) and still have the agent abort in the correct situations (when a bundle is actually missing and you haven't enabled ignore_missing_bundles). The downside is that there are some potential situations where undefined bundles would be detected earlier previously (both correctly and incorrectly). (ENT-8430) 3.19.0: - -N/--negate now prevents persistent classes from being defined (ENT-5886) - 'null' JSON value is now handled as empty data in augments/host-specific data (ENT-7434) - Added a new common control attribute 'system_log_level' For specifying the minimum log level required for log messages to go to the system log. (ENT-7594) - Added support for cfbs managed policy set to masterfiles staging script (ENT-7709) - Trailing commas can now be used in policy argument lists (CFE-3734) - Changed cf-key option --print-digest to take an optional argument. cf-key now defaults to the public key file in workdir, if no argument is specified or an empty string is given as the argument. (CFE-3682) - Cached functions are now always called inside promises with 'iflapsed => "0"' (CFE-3754) - Enabled 'handle' attribute for custom promise types (CFE-3439) - Enabled 'depends_on' attribute for custom promise types (CFE-3438) - Enabled 'with' attribute for custom promise types (CFE-3441) - Don't fail on new file creation when backups are enabled (CFE-3640) - Extended 'hostsseen()' policy function to return host keys (CFE-2546) - Moved httpd.pid to root of httpd workdir (ENT-7966) - Only real changes in files now produce info messages (CFE-3708) - Reports with unexpanded variable references are now attempted to be held off until the reference expands (CFE-3776) - Set apache umask to 0177 (ENT-7948) - The --skip-bootstrap-policy-run option now skips the update policy (ENT-7500, ENT-7511) - Added measurement names in cf-check dump (ENT-7452) - Value of '$(with)' is now expanded even if it contains unresolved variable references (CFE-3776) - cf-serverd now binds to both IPV6 and IPV4 if bindtointerface is unspecified (ENT-7362) - cf-serverd now reports if fails to bind to all possible addresses/interfaces (ENT-7362) - Fixed dbm_quick.c DBPrivRead() argument type (CFE-3737) - Fixed dbm_tokyocab.c DBPrivRead() argument type (CFE-3737) - Fixed crashes (Segfaults) in VariableIsSecret() (ENT-7678) - Fixed crashes (Segfaults) in VariablesMatching() (ENT-7678) 3.18.0: - "No action for file" warning is no longer triggered when only 'content => "something"' is used (CFE-3507) - "source=promise_iteration" variables are no longer created in foreign bundles (ENT-7029) - 'cf-remote install' now supports the '--trust-keys' option for pre-establishing trust before bootstrap (CFE-3485) - 'cf-remote spawn' now supports adding new VMs to an existing group (CFE-3502) - 'rename => newname()' now supports relative paths (CFE-3537) - 'variables' and 'classes' in CMDB and augments data now support 'comment' fields (CFE-3638) - Included custom promise type libraries in src tarball (CFE-3575, CFE-3576) - --ignore-preferred-augments now sets a hard class; ignore_preferred_augments This class makes it easy for cf-agent / cf-execd policy to propagate the option to other binaries (CFE-3656) - Added 'classes' body support for custom promises (CFE-3437) - Added a new --simulate=manifest-full mode New simulation mode that manifests all changed files as well as all other files evaluated by the agent run which were not skipped (by file selection rules) (CFE-3506) - Added a new runagent_socket_allow_users body executor control attribute A new attribute that tells cf-execd to grant access to the runagent.socket to the specified users (ENT-6735) - Added checks to return value from getpwuid & getgrgid (CFE-3521) - Added int() policy function (CFE-3616) - Added new command line option: --ignore-preferred-augments This option causes the agent to ignore def_preferred.json always reading def.json (old behavior) (CFE-3656) - Added policy function type() - Added policy function findfiles_up (CFE-3577) - Added policy variable sys.os_name_human (CFE-3569) - Added policy variable sys.os_version_major (CFE-3569) - Added shell library for custom promise types with cp example (CFE-3516) - Added string() policy function (CFE-3476) - Augments data now supports meta information for classes and a new 'variables' object for variables with meta information (CFE-3633) - Fixed case where malformed input could trigger buffer overflow in policy function format (CFE-3525) - Ability to report some number of lines from the END of a file by specifying number_of_lines as a negative number using printfile (CFE-3558) - CFEngine binaries now load host specific data ($(sys.workdir)/data/host_specific.json) before Augments relative to policy entry (def.json) (ENT-6789) - CFEngine processes are now properly identified in syslog on non-GNU/Linux systems (ENT-7100) - CMDB data now supports meta information for classes and a new 'variables' object for variables with meta information (CFE-3633) - Changed custom promise type interpreter attribute to be optional (CFE-3562) - Changed files promise repaired log level to verbose (CFE-3631) - Changed log message about whitespace in class expressions to be error (CFE-3560) - Changed sys var attribute names: "OS type" was changed to "Kernel", "OS kernel" was changed to "Kernel Release" (ENT-6551) - Clarified error log message about untrusted state directory not being private (CFE-3599) - Classes from augments are now defined as soft classes within the 'namespace' context instead of being hard classes. Policies using classes from augments in policy files using namespaces need to be updated to refer to the augments classes with the 'default:' prefix (CFE-3632) - Custom promise modules using JSON protocol now support data attributes (CFE-3654) - Custom promise modules using JSON protocol now support slist attributes (CFE-3444) - Custom promise types can now be declared in separate files (CFE-3510) - Custom promise types can now report back result classes (CFE-3515) - Custom promises now support the 'log_level' attribute (CFE-3436) - Each custom promise module is now only spawned once and handles all promises of its matching type(s) (CFE-3572) - Early failing custom promises now properly set result classes (CFE-3645) - Exit code from remote agent run is now sent to cf-runagent (CFE-3594) - Fixed crash when attempting to put methods promises in bundles which are not agent bundles (CFE-3672) - Fixed memory leak in package module code (ENT-5752) - Fixed memory leak in simulate mode (CFE-3498) - Fixed some more sign-compare warnings (CFE-3415) - Improved error handling / logging of data received from promise module - Improved log messages for commands promise outcomes and return codes (CFE-3604) - Made errors about failed validation of custom promises less noisy - Namespace and bundle can now be specified in augments and CMDB data (CFE-3633) - New observations of root owned SETUID programs moved from WARN to NOTICE (ENT-6519) - Policy function format() no longer truncates strings lager than 4KiB (CFE-2686) - Policy function storejson() no longer truncates strings lager than 4096 bytes (CFE-2507) - Promise type is now sent to custom promise modules (CFE-3563) - Reduced the noise caused by packages promises being skipped in evaluation passes 2 and 3 (ENT-6553) - Set Filedescriptor Limit to a more practial Size (CFE-3625) - Stopped emitting warning and recording result when observing new SETGID files (ENT-6750) - Stopped updating files promise result with WARN (notkept) when setuid files are encountered (ENT-6519) - Unspecified 'files' constraints no longer cause '_kept' classes to be defined (CFE-3578) - Updated contrib/masterfiles-stage scripts and instructions to be accurate (ENT-6165) - Fixed using a custom promise module with two different interpreters results in an error (CFE-3572) - Value of the 'files_single_copy' body control attribute is now logged in verbose logging mode (CFE-3622) - Variables and classes defined in cmdb cannot be re-defined in augments (ENT-7079) - Verbose log now contains comments associated with 'vars' and 'classes' promises (CFE-2442, CFE-2443) - cf-agent now checks that promise module logs expected errors - cf-agent now sends correct information to promise module in header - cf-execd now executes cf-agent for "localhost" requests via the runagent.socket (ENT-7090) - cf-execd now handles requests to run cf-runagent on given hosts (ENT-6182) - cf-execd now runs cf-agent from a child process instead of a thread on POSIX systems (ENT-6182) - cf-runagent now exits with a code reflecting remote agent run status(es) (CFE-3594) - cf-serverd now supports systemd-based socket activation - def_preferred.json is now used instead of def.json if it exists Old clients will ignore it, allowing you to have 2 versions of the augments file, 1 for compatibility with old clients, and 1 for utilizing the new feautres. (CFE-3656) - files_single_copy body agent control attribute can now be an empty list (CFE-3622) - files_single_copy no longer treats paths of copied files as regular expressions (CFE-3621) - log_level is properly sent to promise modules in both validate and evaluate requests (CFE-3564) - unless can now be used with custom promise types (CFE-3431) - CFEngine processes now reuse log facility from previous run for early logging before policy is loaded (ENT-6955) 3.17.0: - cf-agent can now simulate the changes done to files in a chroot, printing diff or manifest information about what it would do in a normal evaluation. Use the new command line option: `--simulate=diff` or `--simulate=manifest`. Please note that only files and packages promises are simulated currently. - Custom promise types can now be added using promise modules (CFE-3273) - cf-monitord now uses /proc/net/* files to get network information if possible (CFE-2945) - Added new policy function execresult_as_data() (CFE-3315) - Added optional argument to execresult for choosing between stdout and stderr (CFE-3108) - Outcome classes are now always defined for promiser in files promises (CFE-3369) - and(), or(), not() now return boolean and cannot be used directly in slist vars. They can now be used in other places where a boolean is expected. (Most notably and / or promise attributes). The return values can be converted to strings using concat(), if necessary (CFE-3470) - Backgrounded commands are now correctly executed in the child process (CFE-3379) - CFEngine policy bodies can now be completely empty - Directory listings in files changes monitoring are now only updated when there is a change (CFE-3382) - Promises with 'action => bg()' no longer break reporting data (ENT-6042) - Spaces inside square brackets (slist/data index) are now allowed in class expressions (CFE-3320) - Variables specifying data/list names in @() references are now expanded (CFE-2434) - Added warnings when trying to use {{.}} to expand containers in mustache templates (CFE-3457, CFE-3489) - Limited unqualified host and domain name to 511 characters (CFE-3409) - AVCs are no longer produced for CFEngine processes accessing /proc/net (CFE-3240) - Fixed how we check for `--cols` argument to `ps` (ENT-6098) - Fixed a memory leak in users promises - Fixed a small memory leak in cf-promises (CFE-3461) - Fixed expansion of variables in data/list references (CFE-3299) 3.16.0: - Added 'cf-secret' binary for host-specific encryption (CFE-2613) - 'cf-check diagnose --test-write' can now be used to test writing into LMDB files (ENT-4484) - 'if' constraint now works in combination with class contexts (CFE-2615) - Added $(sys.cf_version_release) variable (ENT-5348) - Added new macros to parser: else, maximum_version, between_versions, before_version, at_version and after_version. Version macros now accept single digits (CFE-3198) - Added cf-postgres requirement to cf-apache and cf-hub systemd units (ENT-5125) - Added files promise content attribute (CFE-3276) - Added string_trim() policy function (CFE-3074) - Added warning if CSV parser parses nothing from non-empty file (CFE-3256) - All changes made by 'files' promises are now reported. Also, directory and file creations are now properly reported as 'info' messages. And failures in edit_xml result in promises marked as failed not interrupted. Purged dirs and files are reported as repaired (ENT-5291, CFE-3260) - Bootstrap to loopback interface is now allowed, with a warning (CFE-3304) - Client initiated reporting was fixed on RHEL 8.1 (ENT-5415) - Fixed rare crashing bug when parsing zombie entries in ps output. The problem was only ever observed on AIX, but could theoretically happen on any platform depending on exact libc behavior. (ENT-5329) - Fixed an issue causing duplicate entries in sys.interfaces, and sys.hardware. (CFE-3046) - Fixed ifelse() to return fallback in case of unresolved variables (ENT-4653) - Fixed locking of promises using log_repaired / log_string with timestamps (CFE-3376) - Fixed memory leak in handling of inline JSON in policy evaluation - Fixed memory leak in readlist functions (CFE-3263) - Fixed race condition when multiple agents are acquiring critical section locks simultaneously (CFE-3361) - Fixed selection of standard_services when used from non-default namespace (ENT-5406) - Fixed service status cfengine3 on systemd managed hosts (ENT-5528) - Fixed some memory leaks and crashes in policy evaluation (CFE-3263) - Improved error message for invalid body attribute names (CFE-3273) - Improved management of secondary groups to avoid intermediary state failures (ENT-3710) - LMDB files are now created with correct permissions (ENT-5986) - Log messages about broken Mustache templates are now errors (CFE-3263) - Made classfiltercsv() fail properly on invalid class expression index - Measurements promises with no match no longer produce errors (ENT-5171) - Moved error reading file in countlinesmatching() from verbose to error (CFE-3234) - Added new data validation policy functions validdata() and validjson() (CFE-2898) - New version checking convenience policy functions (CFE-3197) Added the following policy functions to check against local CFEngine version: - cf_version_maximum() - cf_version_minimum() - cf_version_after() - cf_version_before() - cf_version_at() - cf_version_between() - Removed (USE AT YOUR OWN RISK) from cf-key help menu for -x (ENT-5090) - Rewrote helloworld.cf to use files promises content attribute (CFE-3276) - The outcome classes are now defined for the top-level directory when 'include_basedir' is 'false' (ENT-5291) - Variable references with nested parentheses no longer cause errors (CFE-3242) - cf-check: Added a more user friendly message when trying to print unknown binary data (ENT-5234) - cf-check: Added data validation for cf_lastseen.lmdb (CFE-2988) - cf-check: Added nice printing for nova_agent_executions.lmdb (ENT-5234) - cf-check: Added validation for timestamps in cf_lock.lmdb (CFE-2988) - cf-check: Added validation for timestamps in lastseen.lmdb (CFE-2988) - cf-check: Fixed issue causing repair to target the wrong database file (ENT-5309) - cf-check: Symlinked LMDB databases are now preserved in repair Performs diagnosis and repair on symlink target instead of symlink. Repaired files / copies are placed alongside symlink target. In some cases, the symlink target is deleted to repair a corrupt database, and the symlink is left as a broken symlink. This is handled gracefully by the agent, it will be recreated. Broken symlinks are now detected as an acceptable condition in diagnose, it won't try to repair them or delete them. (ENT-5162) - storage promises managing nfs mounts should now correctly mount after editing fstab entries 3.15.0: - New policy function basename() added (CFE-3196) - Added read_module_protocol() policy function This function reads module protocol from a file, and can be used for caching the results of commands modules. (CFE-2973) - The @ character is now allowed in the key of classic arrays defined by the module protocol (CFE-3099) - nth() policy function now supports negative indices (CFE-3194) - Fixed .xy floating point numbers parsing in eval() (CFE-2762) - Added inform constraint to commands promises, to allow suppression of INFO log messages (CFE-2973) - Changed unless constraint to be more consistent with if For any situation where if would NOT skip a promise, unless will cause the promise to be skipped. When there are unresolved variables / function calls, if will skip, unless will NOT skip. (CFE-3160) - Default minimum allowed TLS version is now 1.1 (ENT-4616) - Network protocol version 2 is now called "tls" "tls" or "2" can be used in places where you specify network protocol. Log messages were altered, to show "tls" instead of "latest". (ENT-4406) - Introduced protocol version 3 - "cookie" This protocol is identical to version 2 ("tls"), except it allows the enterprise reporting hub to send the COOKIE command to enterprise hosts. This command is used for detecting hosts using duplicate identities. Protocol version "latest" now points to version 3. For community installations, it should not make a difference, policy servers will not send this command. The only visible difference is the new version number (in logs and policy). (ENT-4406) - Package modules now hit network when package cache is first initialized (CFE-3094) - Fixed promise skipping bug in unless (CFE-2689) - Fixed error message for unexpanded variables in function calls in unless (CFE-2689) - Prevented buffer overflow when policy variable names are longer than 1024 bytes - Zero bytes in class guards no longer cause crashes (CFE-3028) - Fixed bug in ps parsing on OpenBSD / NetBSD causing bootstrap to fail - Fixed crash in policy/JSON parsing of numbers with too many decimal points (CFE-3138) - copy_from without preserve now respects destination mode (ENT-4016) - Removed stime_range and ttime_range constraints from promise hash (ENT-4921) - Fixed promise result when using process_stop in processes type promises (ENT-4988) - cf-execd now sends SIGKILL to the agent process in case of agent_expireafter, after attempting SIGINT and SIGTERM (CFE-2664) - cf-serverd now tries to accept connection multiple times (CFE-3066) - Fixed multiple measurements tracking growth of same file (ENT-4814) - Set create permissions of monitord files in state directory to 0600 0600 matches the permissions enforced by policy. Affected files: * state/cf_incoming.* * state/cf_outgoing.* * state/cf_users * state/env_data (ENT-4863) - Clarified descriptions of io_writtendata and io_readdata (ENT-5127) - Clarified log message about process_count and restart_class being used concurrently (CFE-208) - Agent runs that hit abortclasses now record results (ENT-2471) - An ID of rhel in os-release file will now define both rhel and redhat classes (CFE-3140) - Version specific distro classes are now collected by default in Enterprise (ENT-4752) - redhat_8 and redhat_8_0 are now defined on RHEL 8 (CFE-3140) - Added derived-from-file tag to hard classes based on /etc/redhat-release (CFE-3140) - Added sys.bootstrap_id policy variable containing the ID from /var/cfengine/bootstrap_id.dat, if present (CFE-2977) - sys.interfaces now contains interfaces even when they only have IPv6 addresses (ENT-4858) - IPv6-only interfaces added to sys.hardware_(addresses,mac) (CFE-3164) - IPv6 addresses are now added to policy variable sys.ip_addresses (CFE-682) - IPv6 addresses now respect ignored_interfaces.rx (CFE-3156) - Hostname now allowed in bindtoaddress (CFE-3190) - Fixed issue when removing comments from files in various policy functions This also fixes many erroneous occurences of the error message mentioning: [...] because it legally matches nothing (A warning can still appear if a comment regex actually matches nothing). Also made this comment removing logic faster. Affected functions include: * readstringlist() * readintlist() * readreallist() * peers() * peerleader() * peerleaders() * data_readstringarray() * data_readstringarrayidx() * data_expand() * readstringarray() * readstringarrayidx() * readintarray() * readrealarray() * parsestringarray() * parsestringarrayidx() * parseintarray() * parserealarray() (CFE-3188, ENT-5019) - Fixed memory leak in JSON / env file parsing (CFE-3210) - Fixed memory leak in handling of nfs / fstab (CFE-3210) - Fixed memory leak in string_replace() and regex_replace() (CFE-3210) - Fixed memory leak when using with constraint (CFE-3210) - Fixed minor memory leak in policy evaluation (CFE-3210) - Fixed small memory leak in SQL database promises (CFE-3210) - Received SIGBUS now triggers a repair of local DBs (CFE-3127) - Corrupted LMDB files are now automatically repaired (CFE-3127) - Keys in the lock database, cf_lock.lmdb, are now human-readable (CFE-2596) - Local databases now use synchronous access on AIX and Solaris (ENT-4002) - Report corrupted local database with a critical log message (CFE-2469) - Local DB errors are now logged with the particular DB file path (CFE-2469) - cf-check: repair now preserves readable data in corrupted LMDB files (CFE-3127) - cf-check: --dump option was added to the backup command - cf-check: Added --no-fork to diagnose command (CFE-3145) - cf-check: Added -M manpage option and other common options (CFE-3082) - cf-check: No DB files in state dir now causes errors - cf-check: dump command now dumps DB contents to JSON5 (CFE-3126) - cf-check: help command can now take a topic as argument 3.14.0: - A bootstrap_id.dat file is now generated on every bootstrap (CFE-2977) - Added options to cf-net to set minimum TLS version and ciphers (ENT-4617) - Added --no-truncate option to cf-key This option, when used with --show-hosts changes the formatting of the output. Instead of padding and truncating each of the fields, they are printed, in full, with no padding, and separated by a single tab character. The output is not as pretty, but should be more useful for parsing by other scripts / tooling. (CFE-3036) - Added a new option --skip-db-check to agent and execd This option allows you to enable/disable database (LMDB) consistency checks. Initially it is disabled by default, but this will likely change. (CFE-2893) - Added a new utility to contrib: cf-remote cf-remote is a python + fabric tool to log in to remote hosts you have ssh access to. It can be used to download, transfer, and install CFEngine packages as well as bootstrapping etc. At this point, cf-remote is not packaged with CFEngine, but can be installed separately from: https://github.com/cfengine/cf-remote (CFE-2889) - Added derived-from-file tags to hard classes based on /etc/debian_version and /etc/issue - Added a function to filter CSV-files by classes (CFE-2768) - Forward slash is now an allowed character in module protocol commands (CFE-2478) - Augments files can now handle class expressions by appending '::' A condition in an augments file is treated as a class expression if it ends in ::. Otherwise it is treated as a regular expression. (CFE-2954) - Internal ps command can now handle longer usernames (CFE-2951) - Made copylink_pattern honor '/../' in copy source (CFE-2960) - CSV parser now supports CRLF inside double quotes (ENT-4504) - Added an error when a function defining a variables still fails at pass 3 (CFE-2983) - Documented cf-execd and cf-serverd response to SIGHUP in manpage (CFE-2853) - Stopped trimming leading zeroes in ubuntu minor version class The old version detection logic (using /etc/debian_version) was converting the minor version part to an integer, defining ubuntu_18_4 instead of ubuntu_18_04. The new platform detection (based on /etc/os-release) defines ubuntu_18_04. Since both old and new methods are running to maximize compatibility, both ubuntu_18_04 and ubuntu_18_4 were defined. This commit ensures that the old detection logic treats the minor version (the 04 part) as a string, not an integer. The change is specific to Ubuntu, and should affect Ubuntu 18.04, 16.04, 14.04, etc. (CFE-2882) - SUID log permissions are now properly enforced (CFE-2919) - Agent log file names are now always lowercase - Extended module with file protocol for data (CFE-3050) - Fixed a segfault in 'cf-promises -p json-full' (CFE-3019) - Added cf-key help output to indicate ability to delete by key digest (CFE-2997) - Fixed disabling TLS 1.0 (CFE-3068) - Fixed growing memory footprint of daemons (CFE-3032) - Fixed the log message about setting collect_window (ENT-4238) - Fixed the log message when parsing TIME in 'ps' output fails - Fixed parsing of YAML values starting with numbers (CFE-2033) - Fixed sys.flavor on AIX (ENT-3970) - Fixed 6 cases where promises could get the wrong outcome All cases were related to error handling and detected using static code analysis (LGTM). They were limited to cf-monitord and cf-agent (guest_environments and files promise types). Due to a programming mistake, promise results would sometimes be overwritten with 'skipped' outcome. Keeping the previous value or making the promises 'not kept' is expected behavior. Added a query to our CI (LGTM) to make sure we catch this error on new contributions. - Fixed an issue while parsing ps output on AIX (ENT-4295) - Fixed a memory leak in filesexist function (ENT-4313) - Fixed a memory leak in mustache rendering (ENT-4313) - Fixed a memory leak in: differences(), intersection(), unique() (ENT-4586) - Fixed a segfault in policy parser (ENT-4022) - Connection cache is now global (CFE-2678) - Increased verbosity of AcquireLock permission error (ENT-4395) - Message about invalid class characters from module protocol moved to VERBOSE (CFE-2887, CFE-3008) - Prevented buffer overflows in cf-monitord data parsing - Private keys generated by cf-key are no longer encrypted Private key files encrypted with a broken cipher and default hard coded passphrase provide no real security, and is only an inconvenience. Maybe it was intended to add a password prompt later, but it's been 10 years now, and the cipher and passphrase remain untouched. The function which reads keys still supports both encrypted and unencrypted keys, it will decrypt if necessary. - Reduce SSL/TLS shutdowns on bad networks (CFE-3023) - Removed programming error in handling of process_count body Previously, having a failing function call inside in_range_define or out_of_range_define would cause a programming error when trying to define that as a class. Fixed it by detecting the case, printing a normal error, and skipping defining the class. (CFE-2067) - Set policy->release_id to "failsafe"/"bootstrap" when running failsafe.cf (CFE-3031) - Switched permissions of various temporary files in state to 0600 These files were created with 0644 permissions, and then repaired in policy. However, since they are deleted / recreated periodically, it causes INFO noise. Safer and better user experience to create them with restricted permissions to begin with. Affected files: * $(sys.statedir)/cf_procs * $(sys.statedir)/cf_rootprocs * $(sys.statedir)/cf_otherprocs (ENT-4601) - string_split segments are now truncated to 1024 bytes instead of crashing (CFE-3047) - Unresolved function calls in process_select body are now skipped Function calls which always fail, like getuid("nosuchuser"), are never resolved. Previously this would cause a programming error, since the body is expected to have a list of strings, not unresolved function calls. The function calls are silently skipped (with a verbose message) as this matches the behavior of calling the functions in a vars promise, and using that as a body parameter. (CFE-1968) - cf-check directories can now be controlled from ENV vars (CFE-2994) - cf-check: Added backup command This command copies lmdb files to a timestamped backup directory. (ENT-4064) - cf-check: diagnose and backup now use state directory by default (ENT-4064) 3.13.0: - Add support for TLS 1.3 and its ciphersuites - Add 'feature' hard classes for supported TLS versions Different versions of TLS are supported depending on what version of OpenSSL CFEngine was compiled and linked with. Newly added feature hard classes bring that information to the policy. Classes like these are now defined (for supported versions of TLS): feature_tls source=agent,hardclass feature_tls_1 source=agent,hardclass feature_tls_1_0 source=agent,hardclass feature_tls_1_1 source=agent,hardclass feature_tls_1_2 source=agent,hardclass feature_tls_1_3 source=agent,hardclass - Add a new variable $(sys.default_policy_path) A new sys variable that provides the path of the default policy file evaluated when no file is specified with the '-f' option. - Add an option to skip the initial policy run on bootstrap In some cases it may not be desired to run the policy as the last step of the bootstrap. This can be done with the new '--skip-bootstrap-policy-run' option for cf-agent. (CFE-2826) - Trigger promises.cf as the last step of bootstrap (CFE-2826) - Add support for overriding the package module's path (CFE-2103) - Add support for setting package module interpreter (CFE-2880) - Added --log-level option to all components This allows you to specify any log level (info, verbose, debug etc.). It is also less strict, allowing different spelling. As an example, --log-level i, --log-level INFO, --log-level inform are all the same. - Added a new binary: cf-check Corrupt local databases (LMDB) continues to be a problem. cf-check will be used to diagnose and remediate problems with corrupt databases. It is a standalone binary, which doesn't evaluate policy or use the local databases, thus it can be used in situations where the other binaries like cf-agent would hang. cf-check replaces our lmdb database dumper, lmdump. cf-check lmdump or symlinking / renaming it to lmdump will make cf-check have the exact same behavior as lmdump. cf-check will include much more functionality in the future and some of the code will be added to other binaries, for example to do health checks of databases on startup. Ticket: (ENT-4064) - Added function string_replace. (CFE-2850) - Allow dots in variable identifiers with no such bundle As described and discussed in CFE-1915, defining remote variables (injecting variables into remote bundles) is dangerous and must be blocked. However, using a dot-separated common prefix for variables raises no security concerns and can be considered valid. (CFE-1915) - Allow requiring TLS 1.3 as the minimum version - Apply augments after vars, classes and inputs in def.json (CFE-2741, CFE-2844) - Bundle name is now part of the log message when aborting a bundle (CFE-2793) - Class names set by module protocol are automatically canonified (CFE-2877, CFE-2887) - Classes failsafe_fallback and bootstrap_mode are now reported by default - Correct log level for data_readstringarray* (CFE-2922) - Do not iterate over JSON objects' properties in mustache (CFE-2125) - Do not render templates when passed invalid data (CFE-2194) - Eliminated error messages caused by attempting to kill expired processes (CFE-2824) - Fix cf-runalerts systemd unit conditions so the service will run (ENT-3929) - Fix the off-by-one error in cf-runagent background process spawning (CFE-2873) - Fixed OOB read / heap buffer overflow in evaluator (ENT-4136) - Fixed a memory leak which occured when reloading RSA keys from disk (CFE-2857) - Fixed a memory leak which occured while loading augments files (CFE-2913) - Fixed an issue with splay time in cf-execd (CFE-2931) - Fixed error handling and memory leak in cf-key (CFE-2918) - Fixed memory leak in JSON to policy conversion (ENT-4136) - Fixed memory leak in lmdb cleanup (CFE-2918) - Fixed memory leaks in cf-agent during bootstrap (CFE-2918) - Fixed memory leaks in variablesmatching() and findfiles() (CFE-2918) - Fixed missing class with mustache templates in warn_only mode (CFE-2600) - Fixed small memory leak in cf-serverd (CFE-2918) - Fixed small memory leak in cf-upgrade (ENT-4136) - Fixed small memory leaks of environment variable strings (CFE-2918) - LMDB database dumper, lmdump, no longer creates empty databases (ENT-4064) - Made variablesmatching functions treat args regexes more correctly variablesmatching() and variablesmatching_as_data() no longer use string comparison to find matches. The documentation is clear; arguments should be regexes (so you have to escape special characters). bundle agent main { vars: "myvar" string => "example", meta => {"os[linux]"}; "matches" slist => variablesmatching(".*", "os\[linux\]"); reports: "Match: $(matches)"; } The above example is correct. If you don't escape the brackets like above, it will no longer work. (You probably shouldn't use brackets in tags anyway). - Prevent the init script from managing processes inside containers (ENT-3800) - Read mustache-rendered files in text mode when comparing digest (ENT-2526) - Reload persistent classes on config reload in cf-execd and cf-serverd (CFE-2857) - Fixed issue with @if macro failing when it is on the first line. (CFE-2817) - Fixed issue with cf-agent intermittently hanging on windows sometimes (ENT-3756) - Change GIT_BRANCH to GIT_REFSPEC and remove Design Center vars (ENT-4023) - os-release file is now used for hard classes and sys.flavor on all linuxes This will improve platform detection on newer operating systems where /etc/os-release (or /usr/lib/os-release) is present. A hard class will be set for the value of the ID key (canonified with underscores), if it exists. If both ID and VERSION_ID exist, multiple hard classes will be set for all parts of the version number. The special variable sys.flavor will also be set by determining major version from VERSION_ID. Example os-release file: ID=coreos VERSION_ID=1185.3.0 For the example above, sys.flavor will be coreos_1185 and 4 hard classes will be set; coreos_1185_3_0, coreos_1185_3, coreos_1185, and coreos. For backwards compatibility, older distribution specific logic is still executed and may overwrite sys.flavor and define hard classes as before. - Refactor use of atexit to use custom cleanup function instead. On Windows atexit() unloads DLLs before and/or during atexit functions being called which causes bad behavior. (ENT-3756) 3.12.0b1: New Features: - Add a --key-type option to specify RSA key size to cf-key - New hash_to_int policy function (CFE-2733) - Issue a warning on ignored locking attributes (CFE-2748) - Add IPv6 hard classes with the "ipv6_" prefix (CFE-2310) - Introduce "missing_ok" attribute in body copy_from This allows to ignore missing sources in file copy operations (CFE-2365) - Enable Xen hypervisor detection on all x86 platforms (CFE-2203) - Add sys.policy_entry variables (CFE-2572) - Added inline_mustache template method (CFE-1846) - New component cf-net (cf-net is a CLI for the CFEngine network protocol, useful for debugging, testing etc) and accompanying policy variable sys.cf_net containing path to cf-net binary Changes: - Load augments at the end of context discovery This means that classes defined as part of the context discovery (e.g. 'am_policy_hub' and 'policy_server') can be used in the augments (CFE-2482) - Open measurements promise type from enterprise cf-monitord - Transform filesexist() into a collecting function (CFE-2744) - Load process table when actually needed for a processes promise (ENT-2536) - Ignore commented out entries in fstab when edit_fstab is true (CFE-2198) - Do not move obstructions in warn policy mode (CFE-2740) - Made the max bytes parameter to file reading functions optional (CFE-2656) - Do not tag large volatile variables for inventory sys.interfaces_data, sys.inet and sys.inet6 are commonly larger than the maximum data size allowed to be collected by cf-hub. Data larger than 1k is truncated. Instead of reporting truncated data this change stops tagging the variable so that it will not be collected to the Enterprise hub and will not be available in Mission Portal. (ENT-3483) - cf-execd now re-parses augments on policy reload (CFE-2406) - Improve misleading verbose message For constraints if/ifvarclass/unless, we now print the whole rval of the constraint. Previously the message was just "skipping variable because ifvarclass is not defined" while the variable itself was defined. Old message example: verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined Changed to: verbose: Skipping promise 'mailto' because 'ifvarclass => not(isvariable("mailto"))' is not defined (CFE-2697) - Promise comments for file changes moved to verbose (ENT-3414) - Suppress output from systemctl based restart of services in bootstrap/failsafe (CFE-1459) - Parser can now handle larger inbut buffers (CFE-1886) - Improve logging of ACL errors (ENT-3455) - cf-execd systemd service now only kills cf-execd itself (ENT-3395) - Load multiple augments from "augments" string array in def.json (CFE-2084) - Improve support for Alpine Linux - Set the exit value when running cf-key When running cf-key to generate new keys, set the exit value of the program to be 0 on success and 1 on failure. This makes it easier to catch errors during setup of a new machine. Change the default behavior of the program to not write anything to stdout, opting to use the Log() function which can write to stdout and will also allow output to be sent to syslog. Add a --inform option to set the global log level to LOG_LEVEL_INFO. Change the permissions of the randseed file to 600 and catch the exception if the chmod call fails. - Properly reverse-resolve DNS names longer than 63 chars (ENT-3379) - Properly redirect init script to systemd on debian systems (ENT-3326) Bug fixes: - Disallow modifications of variables from a remote bundle (CFE-1915) - Speedup evalution by not copying variables table when expanding a promise (CFE-2524) - Resolve subkey conflicts when converting to JSON Whenever there is a conflict of array variable definitions prefer the container subkeys over simple values when converting to JSON (CFE-2536) - Do not ignore meta promises in server bundles (CFE-2066) - Add a debug log for computed class in splayclass - Don't error when calling isexecutable on broken link (CFE-741) - Fix segfault when no show-evaluated-vars/classes is specified - Fix memory leak in cf-execd, triggered when sending email failed (CFE-2712) - Fix IPv6 parsing to be un-reversed (CFE-2580) - Fix bug preventing permission changes on Unix sockets (CFE-1782) - Fix storage mount promise when existing mountpoint has a similar path (CFE-1960) - Fix segfault when cf-promises -p is called against a file with syntax errors (CFE-2696) - Fix rare cf-execd hang (CFE-2719) - Fix mergedata segfault when called on a non-container (CFE-2704) - Do not segfault if policy_server.dat only contains whitespaces and/or line breaks - Fix segfault on JSON policy files with no bundles and bodies (CFE-2754) 3.11.0: New Features: - Allow function calls in promiser using universal "with" attribute (CFE-1092) - Add example of with attribute (CFE-1092) - Detect Amazon Linux and set "AmazonLinux" hard class and sys.flavour variable - New sysctlvalue() and data_sysctlvalues() functions from /proc/sys (CFE-2513) - readdata() also auto-detects .yml files as YAML - Added support for ENV and CSV file parsing (CFE-1881) - Added vars and classes for CoreOS (ENT-3043) - cf-agent: implement --show-evaluated-vars and --show-evaluated-classes - Support for custom ports and host names as policy hub (CFE-953) - cf-promises: allows --show-vars and --show-classes to take an optional filter - Added a new tool: cf-net. cf-net is a CLI for the CFEngine network protocol, useful for debugging, testing etc (CFE-2493) - New policy variable: sys.cf_net contains path to cf-net binary - Read /etc/os-release into sys.os_release (CFE-1881) Changes: - readintlist() now prints an error if the file contains real numbers, not integers, and aborts; previously it was printing an info-level error message, was half-reading an integer out of the real, and was continuing successfully. - "make tar-package" should create a tarball with the contents of "make install" (ENT-3041) - Allow opening symlinks owned by root or by the current user (CFE-2516) - Change warning message about depth_search on a non directory to DEBUG level - Ensure synchronous start and stop with systmectl (ENT-2841) - Put logs in /var/log and PID files in /var/run when using FHS layout (CFE-2449) - readstringlist(), readintlist(), readreallist(): Print verbose instead of error message if file can not be read - cf-serverd: Do not close connection when file does not exist (CFE-2532) - policy_server.dat now appends a newline and supports host & port - Allow string_head and string_tail to take negative arguments - getvalues(inexistent_var) returns an empty list. Restores 3.7.x and earlier behaviour. (CFE-2479) - Partially restore old getvalues(array) behaviour Bugfix: getvalues() now behaves correctly for old CFEngine arrays of depth 1 Behaviour change: it always returns a list now. Even when v is a simple string (i.e. not an iterable) it will return an slist with one element: the value of the string variable. Known issues: getvalues() still misbehaves with double-indexed arrays (see CFE-2504, CFE-2536) - The source version of CFEngine now installs binaries into bin folder instead of sbin folder (CFE-2448) - Don't error during dry run for proposed execution (CFE-2561) - Print verbose instead of error message when readfile() fails (CFE-2512) - cf-serverd: Auto configure max open files ulimit according to maxconnections (CFE-2575) - Made the max bytes parameter to file reading functions optional. Affects readfile(), readenvfile(), readcsv() Bug fixes: - Fix insert_lines related memory corruption (CFE-2520) - Prevent LMDB assertion on AIX by ensuring nested DB calls are not occuring during signal handler cleanup (CFE-1996) - Fix a bug which could cause cf-execd to believe there was an error when sending the email report, when there really wasn't - zendesk#3204: Fix "lastseenexpireafter" 32-bit signed int overflow - Fix cf-execd not exiting immediately with SIGTERM on AIX (ENT-3147) - Fix automatic service stops based on runlevel (redhat/centos) (CFE-2611) - Fix cf-serverd crash when reporting corrupted data (ENT-3023) - Fix rare output truncation on Solaris 10/11 (CFE-2527) - Fix crash on Solaris when ps ucb variant is not available (CFE-2506) - Fix logic to detect when running under a Xen Hypervisor (CFE-1563) - Fix "lastseenexpireafter" 32-bit signed int overflow (zendesk#3204) - Fix IPv6 parsing to be un-reversed (CFE-2580) 3.10.0: New features/additions: - All new features/additions for 3.8 and 3.9 are also included in 3.10. - Add: Classes body tailored for use with diff - New feature: Classes promise: allow classes without an expression to default to defined. - Support for custom ports and host names as policy hub (CFE-953) - Add: Definition of from_cfexecd for cf-execd initiated runs (CFE-2386) - Add < <= > >= operators to eval(). - Add testing jUnit and TAP bundles and include them in stdlib.cf - New function isipinsubnet() (ENT-7949) - LogDebug(): implement module-based debug logging. Now most DEBUG messages are *not* printed even when "-d" is in use, but the specific debug module has to be enabled on the command line. For example to enable all log modules, run: cf-agent -d --log-modules=all - Add: edit_line contains_literal_string to stdlib - Add variablesmatching_as_data() function paralleling variablesmatching() (Redmine #7885) - Allow specifying agent maxconnections via def.json (CFE-2461) - Add getuserinfo() function - Add body agent control select_end_match_eof option. (CFE-2390) - Add class to enable post transfer verification during policy updates - Add ability to append to bundlesequnece with def.json (CFE-2460) - policy_server.dat now appends a newline and supports host & port Changes: - Rewrite iteration engine to avoid combinatorial explosion with nested variable expansions. This speeds up enormously the execution of policies that included long slists or JSON containers, that in the past didn't even terminate. Change: "cf_null" string literal was changed to not be something special, and it's now a string that can be used anywhere, like in slists or part of bundlesequence etc. NOTE: Old policy should be grep'ed for "cf_null" and in case such occurences were handled specially, they should be reworked. Change: "--empty-list--" is now never printed by format(), an empty list is now printed as "{ }". Change: Order of pre-evaluation was slightly changed, A new "vars" pass at the beginning of pre-evaluation was added. It used to be classes-vars, but it was changed to vars-classes-vars. As a result some classes or variables might be evaluated at a different time than before. As always try to write policy code that works no matter what the order of execution is. One way is to always *guard* the execution of functions to avoid bogus function results. For example the following will avoid running execresult() bevore the file has been created: execresult("cmd /path/to/filename") if => fileexists("/path/to/filename"); C internals: NULL Rlist is now perfectly valid, in fact it is the only way to denote an empty Rlist. C internals: Since a slist variable can be NULL, API of EvalContextVariableGet() changed: The way to detect if a variable is found, is not to check return value for NULL, but to check returned *type* for CF_DATA_TYPE_NONE. Fixed what I could find as wrong API uses. (CFE-2162) - Allow arbitrary service policies (CFE-2402) - Behaviour change: cf-execd: Do not append -Dfrom_cfexecd to exec_command . (CFE-2386) - Failsafe/Bootstrap no longer copy files starting with .git (like .gitignore) or .mailmap (CFE-2439) - Change: Enable strict transport security - Change: Disable http TRACE method - Change: Verify transfered files during policy update - Allow getvariablemetatags() and getclassmetatags() to get a specific tag key - Change: Use more restrictive unix socket perms (ENT-2705) - Add sys.user_data container for user starting agent. - Pass package promise options to underlying apt-get call (#802) (CFE-2468) - Change: Enable agent component management policy on systemd hosts (CFE-2429) - Change: Switch processes restart_class logging to verbose - Change: Log level for keeping verbatim JSON to DEBUG (CFE-2141) - Change: Require network before CFEngine services (CFE-2435) - Behaviour change: getvalues(inexistent_var) returns an empty list. Restores 3.7.x and earlier behaviour. (CFE-2479) - Behaviour change: when used with CFEngine 3.10.0 or greater, bundles set_config_values() and set_line_based() are appending a trailing space when inserting a configuration option with empty value. (CFE-2466) - Behaviour change: getvalues() always returns a list now. Even when v is a simple string (i.e. not an iterable) it will return an slist with one element: the value of the string variable. - Behaviour change: readintlist() now prints an error if the file contains real numbers, not integers, and aborts; previously it was printing an info-level error message, was half-reading an integer out of the real, and was continuing successfully. - Ensure synchronous start and stop with systemctl (ENT-2841) - Change select_region INI_section to match end of section or end of file (CFE-2519) Bug fixes: - Fix files promise not setting ACL properly on directories. (CFE-616) - Upgrade CFEngine dependencies to the following versions: - lixml2 2.9.4 - OpenSSL 1.0.2j - LibYAML 0.1.7 - Curl 7.50.3 - Fix cumulative() to accept up to 1000 years, like it's documented. - Fixed parsing of host name/IP and port number in cf-runagent (CFE-546) - Fix intermittent error message of type: "error: Process table lacks space for last columns: " (CFE-2371) - storage: Properly initialize the list of current mounts (CFE-1803) - Fix 'contain' attribute 'no_output' having no effect when the 'commands' promise is using 'module => "true"'. (CFE-2412) - Fix bug which caused empty emails to be sent from cf-execd if there was no previous output log and the new log was fully filtered by email filters. (ENT-2739) - Allow ifelse(FALSE, $(x), "something else") to work. (CFE-2260) - Fix connection cache, reuse connections when possible. (CFE-2447) - Fix rare bug that would sometimes prevent redis-server from launching. - Fix bug in files promise when multiple owners are promised but first one doesn't exist, and improve logging . (CFE-2432) - Define kept outcome with action warn if edit_line is as expected (CFE-2424) - Example using getvariablemetatags() and getclassmetatags() to get a specific tag key - Remove 2k limit on strings length when writing JSON policies (CFE-2383) - Fix ttime_range constraint to go higher than 2G as number of seconds. - Change: cronjob bundle tolerates different spacing - Allow editing fields in lines longer than 4k (CFE-2438) - Don't send empty emails for logs where everything is filtered. (ENT-2739) - Allow maplist(), maparray(), and mapdata() to evaluate function calls during iteration (ARCHIVE-1619) - insert_lines is no longer implicitly matching EOF as end of the region if 'select_end' pattern is not matched . (CFE-2263) - Change: Remove executable bit from systemd units (CFE-2436) - cf-serverd should reload def.json when reloading policy (CFE-2406) - Fix cf-monitord detection of usernames of the process table on AIX. - Speed up local and remote file copying and fix spurious errors. (ENT-2769) - Fix occasional segfault when running getindices() on a variable that has indices of multiple depths (e.g. both "a[x]" and "a[x][y]"). (CFE-2397) - When no file is provided when calling cf-promises with cf or json output, use promises.cf by default. This restores the previous behavior. (CFE-2375) - Fix: Services starting or stopping unnecessarily (CFE-2421) - Change: Split systemd units (CFE-2278) - EOF is matched as an end of the region in edit_line promises only if 'select_end_match_eof' parameter is true. (CFE-2263) - Fix double logging of output_prefix, and log process name for cf-agent syslog messages. (CFE-2225) - Be less verbose if a network interface doesn't have a MAC address. (CFE-1995) - Fix: CFEngine choking on standard services (CFE-2806) - Fix insert_lines related memory corruption (CFE-2520) - Fix cf-serverd crash when reporting corrupted data. (ENT-3023) - Fix ability to manage INI sections with metachars for manage_variable_values_ini and set_variable_values_ini (CFE-2519) - Fix apt_get package module incorrectly using interactive mode. - Fix crash on Solaris when ps ucb variant is not available. (CFE-2506) - cf-serverd: Do not close connection when file does not exist. (CFE-2532) - getvalues() now behaves correctly for old CFEngine arrays of depth 1. Known issues: getvalues() still misbehaves with double-indexed arrays (see (CFE-2504, CFE-2536) 3.9.0: New features/additions: - Add optional interface parameter to iprange() to match only one interface. - Allow '=' in symbolic modes (Redmine #7826) - Add: FreeBSD ports package module - New package module for FreeBSD pkg package manager. - Add support for adding/removing fifos in policy - Add Linux parsing of /proc/net/ data. - sys.inet - sys.inet6 - sys.interface_data - Data is returned as a data container. - See documentation for more details. (Jira CFE-1991) - sys.ip2iface: new reverse mapping variable from IP to interface name - Namespaced classes can now be specified on the command line. - Namespaces can now be passed to cf-runagent -D and --remote-bundles (Redmine #7856) - Add 'cf-full' and 'json-full' to cf-promises '-p' option. They generate output based on the entire policy. The existing 'cf' already behaved this way, and it has now been changed to generate output only for a single file, which the existing 'json' option already does. - New language functions: processexists() and findprocesses() (Redmine #7633) - Implement new regex_replace() function. (Redmine #7346) - Add log rotation policy for state/classes.jsonl log. (Redmine #7951) - Added collect_vars utility bundle to stdlib - Intoduce report_class_log attribute to body agent control. (Redmine #7951) - Add standard_services service_method allowing for explicit usage - cf-promises --show-vars can now show JSON variables. - Add json_pipe mode to mapdata(), which allows piping a JSON container to an external program for manipulation and receiving JSON back. The jq tool is a good example where this mode can be useful. A corresponding $(def.jq) variable has also been added with a default path to this tool. See documentation for mapdata() for more information and examples. (Jira CFE-2071) - Behaviour change: "true" is always defined and "false" is never defined in a context expression. - Add: nimclient package module for AIX This module provides basic functionality for using nimclient as a means to ensure packages are either present or absent. It does not support listing package updates available or provide any special caching. - Add callstack_callers() and callstack_promisers() functions. - Log variable definitions in debug output. (Redmine #7137) - Add: Memory information to host info report (Jira CFE-1177) - In Mustache templates, one can now use {{#-top-}} and {{/-top-}} tags to iterate over the top level element in a container. (Redmine #6545) - Add network_connections() function that parses /proc/net - Provide new -w argument to override the workdir for testing - New feature: Emails sent by cf-execd can be filtered to get rid of emails for unwanted log messages. The attributes mailfilter_include and mailfilter_exclude in body executor control control what to include. See documentation for cf-execd for more information. (Jira CFE-2283) - Add: file_make_mustache bundle to render mustache templates - Add '-n' flag to cf-key to avoid host name lookups. - cf-agent, cf-execd, cf-promises, cf-runagent and cf-serverd honor multiple -D, -N and -s arguments (Redmine #7191) - Add "canonify" mode to mapdata(). - Add: printfile bodies to stdlib - Add: New results classes body [] (Redmine #7418, #7481) - Implement cf-runagent --remote-bundles and cf-serverd "bundle" access promise. (Redmine #7581) - Add commands promise arglist attribute, augmenting args attribute. - It's now possible to reference variables in inline JSON, for example: mergedata('[ thing, { "mykey": otherthing[123] } ]'). thing and otherthing[123] will be resolved as variables, since they are unquoted. See the documentation for more details. (Redmine #7871) - Allow inline JSON to be used in the following function calls: - data_expand() - difference() - every() - filter() - format() - getindices() - getvalues() - grep() - intersection() - join() - length() - makerule() - mapdata() - maplist() - mean() - mergedata() - none() - nth() - parsejson() - product() - regarray() - reglist() - reverse() - shuffle() - some() - sort() - storejson() - string_mustache() - sublist() - sum() - unique() - url_get() - variance() For example: mergedata('[ "thing", { "mykey": "myvalue" } ]') See the documentation for more details. (Jira CFE-2253) - Add: edit_line contains_literal_string to stdlib - Add body agent control select_end_match_eof option. (Jira CFE-2390) Changes: - Change: classesmatching(): order of classes changed - Change: getindices(), getvalues(), variablesmatching(), maparray(): order of variables returned has changed - Change: set_quoted_values uses bundle scoped classes - Change: set_config_values uses bundle scoped classes - Change: set_variable_values uses bundle scoped classes - Change: set_config_values_matching uses bundle scoped classes - Change: manage_variable_values_ini uses bundle scoped classes - Change: set_line_based should use bundle scoped classes (Jira CFE-1959) - getvalues() will now return a list also for data containers, and will descend recursively into the containers. (Redmine #7116) - Change: Improve git drop user support - Use new package promise as default package promise implementation. (Jira CFE-2332) - Don't follow symbolic links when copying extended attributes. - When a bodydefault:_ body is defined, it will be used by all promises of type unless another body is explicitly used. - cf-serverd no longer appends "-I -Dcfruncommand" to cfruncommand, this has to be done manually in masterfiles body server control. (Redmine #7732) - eval() function arguments mode and options are now optional. - sort() function argument mode is now optional. - Change: returnszero() no longer outputs the output of a command. The output can be seen by enabling info mode (-I). - cfruncommand is not executed under shell. (Redmine #7409) - Remove: Apache CGI module - Change: Make maxbytes arg of readjson() and readyaml() optional - Classes matching agent control's abortclasses are now printed before exit, even if they are defined in common bundles. Previously the regex (in abortclasses) that matched the class was printed if the class was defined in a common bundle, but the class itself was printed if it was defined in an agent bundle. With this change, the defined class that caused the abort is always printed. - Remove: Support for email settings from augments_file (Redmine #7682) - Change: set_variable_values_ini uses bundle scoped classes - findfiles() now skips relative paths. (Redmine #7981) - Clients connections using non TLS protocol are rejected by default. . (Jira CFE-2339) - Change: Policy files specified in the "inputs" section of def.json will no longer be auto-loaded. One has to refer to the which are using the "inputs" field inside def.json. (Redmine #7961) - Change: Separate binary details from policy update (Redmine #7662) - Add guard for binary upgrade during bootstrap (Redmine #7861) - Change: Modernize pkg module and package_method - Remove: Userdir apache module - filestat(path, "linktarget") now follows non-absolute links and returns full path of target. This introduces a change in behaviour. Here is an example: $ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Jun 4 2015 /bin/sh -> dash Previously the filestat function would return "dash", and would also log an error that the file can not be read. Now it will return "/bin/dash" (or the final destination if it happens that /bin/dash is also a symlink). You can still get the previous behaviour by using filestat(path, "linktarget_shallow"). (Redmine #7404) - Define (bootstrap|failsafe)_mode during update.cf when triggerd from failsafe.cf (Redmine #7861) - Behavior change: The promise string of a processes promise now matches just the command line of each process instead of the line that is output by ps. This was done to reduce fragmentation between platforms, since ps is a very nonstandardized tool. (Jira CFE-2161) - Allowed namespace names made more strict, to disallow namespaces that cannot be reached. (Redmine #7903) - Behavior change: When using readintlist(), readreallist() or readstringlist(), parsing an empty file will no longer result in a failed function call, but instead an empty list. Failure to open the file will still result in a failed function call. - insert_lines is no longer implicitly matching EOF as end of the region if 'select_end' pattern is not matched . (Jira CFE-2263) - EOF is matched as an end of the region in edit_line promises only if 'select_end_match_eof' parameter is true. (Jira CFE-2263) Bug fixes: - Upgrade CFEngine dependencies to the following versions: - Curl 7.48.0 - libxml2 2.9.4 - LMDB 0.9.18 - OpenLDAP 2.4.44 - OpenSSL 1.0.2h - PCRE 8.38 (Jira ENT-2720) - Upgrade dependencies to latest minor versions. For Community / Enterprise: For Enterprise: - Fix bug which sometimes misparses user names in ps output. - Fix: Problem with git not dropping privileges soon enough - Allow def.json up to 5MB instead of 4K. - It is possible to edit the same value in multiple regions of one file. (Redmine #7460) - CFEngine on Windows no longer truncates log messages if the program in question is killed halfway through. - Fixed a bug which caused def.json not being able to define classes based on other hard classes. (Jira CFE-2333) - Change: Tighten Enterprise hub permissions (Jira ENT-2708) - Fix a regression which would sometimes cause "Permission denied" errors on files inside directories with very restricted permissions. (Redmine #7808) - Fix use-after-free in ArrayMap and HashMap (Redmine #7952) - Package repositories are no more hit every time package promise is evaluated on SUSE. - Fix a bug which sometimes caused package promises to be skipped with "XX Another cf-agent seems to have done this since I started" messages in the log, most notably in long running cf-agent runs (longer than one minute). (Redmine #7933) - TTY detection should be more reliable. (Redmine #7606) - cf-promises -p cf now produces valid CFEngine code (Redmine #7956) - Fix ps options for FreeBSD to check processes only in current host and not in jails - cf-runagent now properly supports multiple -D or -s arguments (Redmine #7191) - Fix: Work around impaired class definition from augments (Jira CFE-2333) - Fix "No such file or directory" LMDB error on heavily loaded hosts. (Jira CFE-2300) - Check for empty server response in RemoteDirList after decryption (Redmine #7908) - Small performance optimization when cf-execd scans emails before sending. - Fix handling of closed connections during transactions (Redmine #7926) - The core ps parsing engine used for processes promises has been rewritten from scratch, and should be more robust than before. (Jira CFE-2161) - Fix the lexer which could not handle empty newline(s) before a @endif. - groupexists() no longer fails to detect a group name starting with a digit. (Jira CFE-2351) - Fix HP-UX specific bug that caused a lot of log output to disappear. - Fix unresolved variable (Redmine #7931) - Change: Suppress standard services noise on SUSE (Redmine #6968) - Reduce verbosity of yum package module (Redmine #7485) - cf-runagent: Allow connections to localhost instead of failing silently. - Show errors regarding failure to copy extended attributes when doing a local file copy. Errors could happen when copying across two different mount points where the support for extended attributes is different between the mount points. - Fix classes being set because of hash collision in the implementation. (Redmine #7912) - Fix build failure on FreeBSD 7.1 (Redmine #7415) - Improve logging when managing setuid/setgid - Reduce verbosity of apt_get package module (Redmine #7485) - packagesmatching() and packageupdatesmatching() should work when new package promise is used. (Jira CFE-2246) - Fix bug which could render host unable to recover from a syntax error, even if failsafe.cf was utilized. This could happen if the file containing the syntax error was specified in the def.json special file. (Redmine #7961) - Prevent crash in cf-execd email code when policy server is not set. - In case of networking error, assume checksum is wrong - Fix two cases where action_policy warn still produces errors (Redmine #7274) - Fix bad option nlwp to vzps on Proxmox / OpenVZ. (Redmine #6961) - @if minimum_version now correctly ignores lines starting with '@' (Redmine #7862) - No longer hang when changing permissions/ownership on fifos (Redmine #7030) - readfile() and read*list() should print an error if they fail to read file. (Redmine #7702) - The isvariable() function call now correctly accepts all array variables when specified inline. Previously it would not accept certain special characters, even though they could be specified indirectly by using a variable to hold it. (Redmine #7088) - Fix file descriptor leak when there are network errors. - Improve robustness of process table parsing on Solaris. (Jira CFE-2161) - Installing packages containing version numbers using yum now works correctly. (Redmine #7825) - Parse def.json vars, classes and inputs from the C code. This fixes a bug where certain entries in this file would be parsed too late to have any effect on the evaluation. (Redmine #7453, #7615) - Change package modules permissions on hub package so that hub can execute package promises. (Redmine #7602) - Fix: CFEngine choking on standard services (Jira CFE-2086) - Fix: cf-upgrade on SUSE - Fix: Stop CFEngine choking on systemctl output (Jira CFE-2806) - storage: Properly initialize the list of current mounts (Jira CFE-1803) - Fix bug which caused empty emails to be sent from cf-execd if there was no previous output log and the new log was fully filtered by email filters. (Jira ENT-2739) - Don't send empty emails for logs where everything is filtered. (Jira ENT-2739) - Fix intermittent error message of type: "error: Process table lacks space for last columns: " (Jira CFE-2371) - Be less verbose if a network interface doesn't have a MAC address. (Jira CFE-1995) 3.8.2: Fixes: - Update library dependencies to latest version. Libraries upgraded: - curl 7.47.0 - LMDB 0.9.18 - MySQL 5.1.72 - OpenLDAP 2.4.44 - OpenSSL 1.0.2g - PostgreSQL 9.3.11 - Redis 3.0.7 - rsync 3.1.2 PHP was kept at 5.6.17 because of problems with the 5.6.19 version. - Reduce verbosity of apt_get package module (Redmine #7485) - Reduce verbosity of yum package module (Redmine #7485) - The isvariable() function call now correctly accepts all array variables when specified inline. Previously it would not accept certain special characters, even though they could be specified indirectly by using a variable to hold it. (Redmine #7088) - Don't follow symbolic links when copying extended attributes. - Fix a bug which sometimes caused package promises to be skipped with "XX Another cf-agent seems to have done this since I started" messages in the log, most notably in long running cf-agent runs (longer than one minute). (Redmine #7933) - Fix bug which could render host unable to recover from a syntax error, even if failsafe.cf was utilized. This could happen if the file containing the syntax error was specified in the def.json special file. (Redmine #7961) - Change: Policy files specified in the "inputs" section of def.json will no longer be auto-loaded. One has to refer to the $(def.augments_inputs) variable in the policy (the standard masterfiles policies include this by default). This only affects installations which are not based on the standard masterfiles, and which are using the "inputs" field inside def.json. (Redmine #7961) - Fix file descriptor leak when there are network errors. - Fix cf-serverd error messages with classic protocol clients (Redmine #7818) - Installing packages containing version numbers using yum now works correctly. (Redmine #7825) - Fix ps options for FreeBSD to check processes only in current host and not in jails - Fix build failure on FreeBSD 7.1 (Redmine #7415) - Show errors regarding failure to copy extended attributes when doing a local file copy. Errors could happen when copying across two different mount points where the support for extended attributes is different between the mount points. - Fix classes being set because of hash collision in the implementation. (Redmine #7912) - Allow def.json up to 5MB instead of 4K. - Fix a regression which would sometimes cause "Permission denied" errors on files inside directories with very restricted permissions. (Redmine #7808) - Change: Suppress standard services noise on SUSE (Redmine #6968) Changes: - Change: classesmatching(): order of classes changed 3.8.1: Changes: - Upgrade CFEngine dependencies to the following versions: - OpenSSL 1.0.2e - PCRE 8.38 - libxml2 2.9.3 - OpenLDAP 2.4.43 - libcurl 7.46.0 - Upgrade LMDB to version 0.9.17. (Redmine #7879) Bug fixes: - @if minimum_version now correctly ignores lines starting with '@' (Redmine #7862) - Add guard for binary upgrade during bootstrap (Redmine #7861) - Namespaced classes can now be specified on the command line. - Fix bad option nlwp to vzps on Proxmox / OpenVZ. (Redmine #6961) - Fix two cases where action_policy warn still produces errors (Redmine #7274) - Parse def.json vars, classes and inputs from the C code. This fixes a bug where certain entries in this file would be parsed too late to have any effect on the evaluation. (Redmine #7453, #7615) - Fix HP-UX specific bug that caused a lot of log output to disappear. - Check for empty server response in RemoteDirList after decryption (Redmine #7908) - getvalues() will now return a list also for data containers, and will descend recursively into the containers. (Redmine #7116) - Define (bootstrap|failsafe)_mode during update.cf when triggerd from failsafe.cf (Redmine #7861) 3.8.0: New features/additions: - New feature: Bodies can now inherit attribute values from other bodies by specifying "inherit_from" with the name of the body to inherit from, plus any arguments it accepts. For example: body classes myclasses { inherit_from => classes_generic("myname"); } (Redmine #4309) - Add url_get() function. (Redmine #6480) - Add @if feature() syntax @if feature work like @if minimum_version but allows distinguishing between features chosen at compile time. - Extend module protocol to create persistent classes. To use it, have the module print a line with "^persistence=" before printing any class names. "persistence=0" goes back to non- persistent classes. (Redmine #7302) - Add: New results classes body (Redmine #7418) - Add: Debug reports in cfe_internal_cleanup_agent_reports - Add: Path to svcprop in stdlib - Add: masterfiles-stage script to contrib - Whitespace is now allowed in class expressions for readability, between class names and operators. (Redmine #7152) Changes: - Change: Clarify bootstrap/failsafe reports - Change: Improve in-line docs for internal log maintenance - Change: Improve efficiency and debug reports (Redmine #7527) - Remove: 3.5 support from masterfiles policy framework - Long promiser strings with multiple lines are now abbreviated in logs. (Redmine #3964) - Change: Reunify Version based policy split - Change: Separate binary details from policy update (Redmine #7662) - Remove /var/cfengine/cf3..runlog. (Redmine #6957) - Change: sys.libdir and sys.local_libdir to non version specific path - sys.libdir now resolves to $(sys.inputdir)/lib - sys.local_libdir now resolves to lib (Redmine #7559) - Moved the following files to /var/cfengine/log/: - /var/cfengine/promise_summary.log - /var/cfengine/cfagent..log - Change: Separate binary details from policy update (Redmine #7662) - Remove: Support for email settings from augments_file (Redmine #7682) Bug fixes: - It is possible to edit the same value in multiple regions of one file. (Redmine #7460) - Change package modules permissions on hub package so that hub can execute package promises. (Rednime #7602) (Redmine #7602) - Fix exporting CSV reports through HTTPS. (Redmine #7267) - cf-agent, cf-execd, cf-promises, cf-runagent and cf-serverd honor multiple -D, -N and -s arguments (Redmine #7191) - readfile() and read*list() should print an error if they fail to read file. (Redmine #7702) - No longer hang when changing permissions/ownership on fifos (Redmine #7030) - Fix broken HA policy for 3rd disaster-recovery node. - Fix: Policy errors for 3.5 and 3.6 - Mustache templates: Fix {{@}} key when value is not a primitive. The old behavior, when iterating across a map or array of maps, was to abort if the key was requested with {{@}}. The new behavior is to always replace {{@}} with either the key name or the iteration position in the array. An error is printed if {{@}} is used outside of a Mustache iteration section. - Fix build with musl libc. (Redmine #7455) - Fixed a bug which could cause daemons to not to be killed correctly when upgrading or manually running "service cfengine3 stop". (Redmine #7193) - Fix daemons not restarting correctly on upgrade on AIX. - Package promise: Fix inability to install certain packages with numbers. (Redmine #7421) - Redmine #6027 Directories should no more be changed randomly into files. (Redmine #6027) - Improve cf-serverd's lock contention because of getpwnam() call. (Redmine #7643) (Redmine #7643) - action_policy "warn" now correctly produces warnings instead of various other verbosity levels. (Redmine #7274) - If there is an error saving a mustache template file it is now logged with log-level error (was inform). - The JSON parser now supports unquoted strings as keys. - Reduce malloc() thread contention on heavily loaded cf-serverd, by not exiting early in the logging function, if no message is to be printed. (Redmine #7624) (Redmine #7624) - Fix a bug which caused daemons not to be restarted on upgrade. (Redmine #7528) - Include latest security updates for dependencies. - Fixed bug which would cause bff and depot packages not to run package scripts on removal. (Redmine #7193) - Fix upgrade causing error message under systemd because of open ports. - Fixed several bugs which prevented CFEngine from loading libraries from the correct location. This affected several platforms. (Redmine #6708) - Legacy package promise: Result classes are now defined if the package being promised is already up to date. (Redmine #7399) - failsafe.cf will be created when needed. (Redmine #7634) (Redmine #7634) - If file_select.file_types is set to symlink and there are regular files in the scanned directory, CFEngine no longer produces an unnecessary error message. (Redmine #6996) - Fix 'AIX_PREINSTALL_ALREADY_DONE.txt: cannot create' error message on AIX. - Fix package promise not removing dependent packages. (Redmine #7424) - Fix: Solaris packages no longer contain duplicate library files, but instead symlinks to them. (Redmine #7591) - Fix select_class not setting class when used in common bundle with slist. (Redmine #7482) - Fix "@endif" keyword sometimes being improperly processed by policy parser. (Redmine #7413) - Fix noise from internal policy to upgrade windows agents (Redmine #7456) - cfruncommand now works if it contains spaces, with the TLS protocol. (Redmine #7405) - Fix warning "Failed to parse csv file entry" with certain very long commands promises. (Redmine #7400) - CFEngine no longer erronously passes -M to useradd on HP-UX. (Redmine #6734) - cf-monitord no longer complains about missing thermal zone files. (Redmine #7238) - systemd is now detected correctly if it is a symlink (Redmine #7297) - TTY detection should be more reliable. (Redmine #7606) (Redmine #7606) 3.7.3 Fixes: - Reduce verbosity of yum package module (Redmine #7485) - Reduce verbosity of apt_get package module (Redmine #7485) - Upgrade dependencies to latest patch versions. Upgraded libraries: - curl 7.47.0 - libxml2 2.9.3 - LMDB 0.9.18 - MySQL 5.1.72 - OpenLDAP 2.4.44 - OpenSSL 1.0.2g - PCRE 8.38 - PostgreSQL 9.3.11 - Redis 2.8.24 - rsync 3.1.2 PHP was kept at 5.6.17 because of problems with the 5.6.19 version. - Parse def.json vars, classes, and inputs in C (Redmine #7453) - Namespaced classes can now be specified on the command line. - getvalues() will now return a list also for data containers, and will descend recursively into the containers. (Redmine #7116) - @if minimum_version now correctly ignores lines starting with '@' (Redmine #7862) - Fix definition of classes from augments file - Don't follow symbolic links when copying extended attributes. - Fix ps options for FreeBSD to check processes only in current host and not in jails - Fix cf-serverd error messages with classic protocol clients (Redmine #7818) - Change: Suppress standard services noise on SUSE (Redmine #6968) - The isvariable() function call now correctly accepts all array variables when specified inline. Previously it would not accept certain special characters, even though they could be specified indirectly by using a variable to hold it. (Redmine #7088) - Show errors regarding failure to copy extended attributes when doing a local file copy. Errors could happen when copying across two different mount points where the support for extended attributes is different between the mount points. - Fix bad option nlwp to vzps on Proxmox / OpenVZ. (Redmine #6961) - Fix file descriptor leak when there are network errors. - Fix a regression which would sometimes cause "Permission denied" errors on files inside directories with very restricted permissions. (Redmine #7808) - Check for empty server response in RemoteDirList after decryption (Redmine #7908) - Allow def.json up to 5MB instead of 4K. - Add guard for binary upgrade during bootstrap (Redmine #7861) - Fix HP-UX specific bug that caused a lot of log output to disappear. - Fix a bug which sometimes caused package promises to be skipped with "XX Another cf-agent seems to have done this since I started" messages in the log, most notably in long running cf-agent runs (longer than one minute). (Redmine #7933) - Define (bootstrap|failsafe)_mode during update.cf when triggerd from failsafe.cf (Redmine #7861) - Fix two cases where action_policy warn still produces errors (Redmine #7274) - Fix classes being set because of hash collision in the implementation. (Redmine #7912) - Fix build failure on FreeBSD 7.1 (Redmine #7415) - Installing packages containing version numbers using yum now works correctly. (Redmine #7825) Changes: - Change: classesmatching(): order of classes changed 3.7.3 Fixes: - Reduce verbosity of yum package module (Redmine #7485) - Reduce verbosity of apt_get package module (Redmine #7485) - Upgrade dependencies to latest patch versions. Upgraded libraries: - curl 7.47.0 - libxml2 2.9.3 - LMDB 0.9.18 - MySQL 5.1.72 - OpenLDAP 2.4.44 - OpenSSL 1.0.2g - PCRE 8.38 - PostgreSQL 9.3.11 - Redis 2.8.24 - rsync 3.1.2 PHP was kept at 5.6.17 because of problems with the 5.6.19 version. - Parse def.json vars, classes, and inputs in C (Redmine #7453) - Namespaced classes can now be specified on the command line. - getvalues() will now return a list also for data containers, and will descend recursively into the containers. (Redmine #7116) - @if minimum_version now correctly ignores lines starting with '@' (Redmine #7862) - Fix definition of classes from augments file - Don't follow symbolic links when copying extended attributes. - Fix ps options for FreeBSD to check processes only in current host and not in jails - Fix cf-serverd error messages with classic protocol clients (Redmine #7818) - Change: Suppress standard services noise on SUSE (Redmine #6968) - The isvariable() function call now correctly accepts all array variables when specified inline. Previously it would not accept certain special characters, even though they could be specified indirectly by using a variable to hold it. (Redmine #7088) - Show errors regarding failure to copy extended attributes when doing a local file copy. Errors could happen when copying across two different mount points where the support for extended attributes is different between the mount points. - Fix bad option nlwp to vzps on Proxmox / OpenVZ. (Redmine #6961) - Fix file descriptor leak when there are network errors. - Fix a regression which would sometimes cause "Permission denied" errors on files inside directories with very restricted permissions. (Redmine #7808) - Check for empty server response in RemoteDirList after decryption (Redmine #7908) - Allow def.json up to 5MB instead of 4K. - Add guard for binary upgrade during bootstrap (Redmine #7861) - Fix HP-UX specific bug that caused a lot of log output to disappear. - Fix a bug which sometimes caused package promises to be skipped with "XX Another cf-agent seems to have done this since I started" messages in the log, most notably in long running cf-agent runs (longer than one minute). (Redmine #7933) - Define (bootstrap|failsafe)_mode during update.cf when triggerd from failsafe.cf (Redmine #7861) - Fix two cases where action_policy warn still produces errors (Redmine #7274) - Fix classes being set because of hash collision in the implementation. (Redmine #7912) - Fix build failure on FreeBSD 7.1 (Redmine #7415) - Installing packages containing version numbers using yum now works correctly. (Redmine #7825) Changes: - Change: classesmatching(): order of classes changed 3.7.2: Bug fixes: - readfile() and read*list() should print an error if they fail to read file. (Redmine #7702) - Fix 'AIX_PREINSTALL_ALREADY_DONE.txt: cannot create' error message on AIX. - If there is an error saving a mustache template file it is now logged with log-level error (was inform). - Change: Clarify bootstrap/failsafe reports - Fixed several bugs which prevented CFEngine from loading libraries from the correct location. This affected several platforms. (Redmine #6708) - If file_select.file_types is set to symlink and there are regular files in the scanned directory, CFEngine no longer produces an unnecessary error message. (Redmine #6996) - Fix: Solaris packages no longer contain duplicate library files, but instead symlinks to them. (Redmine #7591) - cf-agent, cf-execd, cf-promises, cf-runagent and cf-serverd honor multiple -D, -N and -s arguments (Redmine #7191) - Fix "@endif" keyword sometimes being improperly processed by policy parser. (Redmine #7413) - It is possible to edit the same value in multiple regions of one file. (Redmine #7460) - Fix select_class not setting class when used in common bundle with slist. (Redmine #7482) - Fix broken HA policy for 3rd disaster-recovery node. - Directories should no more be changed randomly into files. (Redmine #6027) - Include latest security updates for 3.7. - Reduce malloc() thread contention on heavily loaded cf-serverd, by not exiting early in the logging function, if no message is to be printed. (Redmine #7624) - Improve cf-serverd's lock contention because of getpwnam() call. (Redmine #7643) - action_policy "warn" now correctly produces warnings instead of various other verbosity levels. (Redmine #7274) - Change: Improve efficiency and debug reports (Redmine #7527) - Change package modules permissions on hub package so that hub can execute package promises. (Redmine #7602) - No longer hang when changing permissions/ownership on fifos (Redmine #7030) - Fix exporting CSV reports through HTTPS. (Redmine #7267) - failsafe.cf will be created when needed. (Redmine #7634) - Mustache templates: Fix {{@}} key when value is not a primitive. The old behavior, when iterating across a map or array of maps, was to abort if the key was requested with {{@}}. The new behavior is to always replace {{@}} with either the key name or the iteration position in the array. An error is printed if {{@}} is used outside of a Mustache iteration section. - Legacy package promise: Result classes are now defined if the package being promised is already up to date. (Redmine #7399) - TTY detection should be more reliable. (Redmine #7606) Masterfiles: - Add: Path to svcprop in stdlib - Add: New results classes body [] (Redmine #7418, #7481) - Remove: Support for email settings from augments_file (Redmine #7682) 3.7.1: Bug fixes: - Fix daemons not restarting correctly on upgrade on AIX. (Redmine #7550) - Fix upgrade causing error message under systemd because of open ports. - Fix build with musl libc. (Redmine #7455) - Long promiser strings with multiple lines are now abbreviated in logs. (Redmine #3964) - Fixed a bug which could cause daemons to not to be killed correctly when upgrading or manually running "service cfengine3 stop". (Redmine #7193) - Package promise: Fix inability to install certain packages with numbers. - Fix package promise not removing dependent packages. (Redmine #7424) - Fix warning "Failed to parse csv file entry" with certain very long commands promises. (Redmine #7400) - Fix misaligned help output in cf-hub. (Redmine #7273) - Augmenting inputs from the augments_file (Redmine #7420) - Add support for failover to 3rd HA node located outside cluster. - Upgrade all dependencies for patch release. - Fix a bug which caused daemons not to be restarted on upgrade. (Redmine #7528) 3.7.0: New features: - New package promise implementation. The syntax is much simpler, to try it out, check out the syntax: packages: "mypackage" policy => "absent/present", # Optional, default taken from common control package_module => apt_get, # Optional, will only match exact version. May be # "latest". version => "32.0", # Optional. architecture => "x86_64"; - Full systemd support for all relevant platforms - New classes to determine whether certain features are enabled: * feature_yaml * feature_xml For the official CFEngine packages, these are always enabled, but packages from other sources may be built without the support. - New readdata() support for generic data input (CSV, YAML, JSON, or auto) - YAML support: new readyaml() function and in readdata() - CSV support: new readcsv() function and in readdata() - New string_mustache() function - New data_regextract() function - eval() can now be called with "class" as the "mode" argument, which will cause it to return true ("any") if the calculated result is non-zero, and false ("!any") if it is zero. - New list_ifelse() function - New mapdata() function as well as JSON support in maparray(). - filestat() function now supports "xattr" argument for extended attributes. - "ifvarclass" now has "if" as an alias, and "unless" as an inverse alias. - Ability to expand JSON variables directory in Mustache templates: Prefix the name with '%' for multiline expansion, '$' for compact expansion. - Ability to expand the iteration *key* in Mustache templates with @ - Canonical JSON output: JSON output has reliably sorted keys so the same data structure will produce the same JSON every time. - New "@if minimum_version(x.x)" syntax in order to hide future language improvements from versions that don't understand them. - Compile time option (--with-statedir) to override the default state/ directory path. - Fix error messages/ handling in process signalling which no longer allowed any signals to fail silently - Also enable shortcut keyword for cf-serverd classic protocol, eg to simplify the bootstrap process for clients that have different sys.masterdir settings (Redmine #3697) - methods promises now accepts the bundle name in the promiser string, as long as it doesn't have any parameters. - In a services promise, if the service_method bundle is not specified, it defaults to the promiser string (canonified) with "service_" as a prefix. The bundle must be in the same namespace as the promise. - Inline JSON in policy files: surrounding with parsejson() is now optional *when creating a new data container*. - New data_expand() function to interpolate variables in a data container. - Add configurable network bandwidth limit for all outgoing connections ("bwlimit" attribute in "body common control") . To enforce it in both directions, make sure the attribute is set on both sides of the connection. - Secure bootstrap has been facilitated by use of "cf-agent --boostrap HUB_ADDRESS --trust-server=no" - Implement new TLS-relevant options (Redmine #6883): - body common control: tls_min_version - body server control: allowtlsversion - body common control: tls_ciphers - body server control: allowciphers (preexisting) Changes: - Improved output format, less verbose, and messages are grouped. - cf-execd: agent_expireafter default was changed to 120 minutes (Redmine #7113) - All embedded databases are now rooted in the state/ directory. - TLS used as default for all outgoing connections. - process promise now reports kept status instead of repaired if a signal is not sent, even if the restart_class is set. The old behavior was to set the repaired status whenever the process was not running. (Redmine#7216). - Bootstrapping requires keys to be generated in advance using cf-key. - Disable class set on reverse lookup of interfaces IP addresses. (Redmine #3993, Redmine #6870) - Define a hard class with just the OS major version on FreeBSD. - Abort cf-agent if OpenSSL's random number generator can't be seeded securely. - Masterfiles source tarball now installs using the usual commands "./configure; make install". - Updated Emacs syntax highlighting template to support the latest syntax enhancements in 3.7. Deprecations: - Arbitrary arguments to cfruncommand (using "cf-runagent -o") are not acceptable any more. (Redmine #6978) - 3.4 is no longer supported in masterfiles. Bug fixes: - Fix server common bundles evaluation order (Redmine#7211). - Limit LMDB disk usage by preserving sparse areas in LMDB files (Redmine#7242). - Fixed LMDB corruption on HP-UX 11.23. (Redmine #6994) - Fixed insert_lines failing to converge if preserve_block was used. (Redmine #7094) - Fixed init script failing to stop/restart daemons on openvz/lxc hosts. (Redmine #3394) - rm_rf_depth now deletes base directory as advertised. (Redmine #7009) - Refactored cf-agent's connection cache to properly differentiate hosts using all needed attributes like host and port. (Redmine #4646) - Refactored lastseen database handling to avoid inconsistencies. (Redmine #6660) - cf-key --trust-key now supports new syntax to also update the lastseen database, so that clients using old protocol will trust the server correctly. - Fixed a bug which sometimes caused an agent or daemon to kill or stop itself. (Redmine #7075, #7244) - Fixed a bug which made it difficult to kill CFEngine daemons, particularly cf-execd. (Redmine #6659, #7193) - Fixed a bug causing systemd not to be detected correctly on Debian. (Redmine #7297) - "cf-promises -T" will now correctly report the checked out commit, even if you haven't checked out a Git branch. (Redmine #7332) - Reduce verbosity of harmless errors related to socket timeouts and missing thermal zone files. (Redmine #6486 and #7238) Masterfiles: Added: - Support for user specified overring of framework defaults without modifying policy supplied by the framework itself (see example_def.json) - Support for def.json class augmentation in update policy - Run vacuum operation on postgresql every night as a part of maintenance. - Add measure_promise_time action body to lib (3.5, 3.6, 3.7, 3.8) - New negative class guard cfengine_internal_disable_agent_email so that agent email can be easily disabled by augmenting def.json Changed: - Relocate def.cf to controls/VER/ - Relocate update_def to controls/VER - Relocate all controls to controls/VER - Only load cf_hub and reports.cf on CFEngine Enterprise installs - Relocate acls related to report collection from bundle server access_rules to controls/VER/reports.cf into bundle server report_access_rules - Re-organize cfe_internal splitting core from enterprise specific policies and loading the appropriate inputs only when necessary - Moved update directory into cfe_internal as it is not generally intended to be modified - services/autorun.cf moved to lib/VER/ as it is not generally intended to be modified - To improve predictibility autorun bundles are activated in lexicographical order - Relocate services/file_change.cf to cfe_internal/enterprise. This policy is most useful for a good OOTB experience with CFEngine Enterprise Mission Portal. - Relocate service_catalogue from promsies.cf to services/main.cf. It is intended to be a user entry. This name change correlates with the main bundle being activated by default if there is no bundlesequence specified. - Reduce benchmarks sample history to 1 day. - Update policy no longer generates a keypair if one is not found. (Redmine: #7167) - Relocate cfe_internal_postgresql_maintenance bundle to lib/VER/ - Set postgresql_monitoring_maintenance only for versions 3.6.0 and 3.6.1 - Move hub specific bundles from lib/VER/cfe_internal.cf into lib/VER/cfe_internal_hub.cf and load them only if policy_server policy if set. - Re-organize lib/VER/stdlib.cf from lists into classic array for use with getvalues Removed: - Diff reporting on /etc/shadow (Enterprise) - Update policy from promise.cf inputs. There is no reason to include the update policy into promsies.cf, update.cf is the entry for the update policy - _not_repaired outcome from classes_generic and scoped_classes generic (Redmine: # 7022) Fixes: - standard_services now restarts the service if it was not already running when using service_policy => restart with chkconfig (Redmine #7258) 3.6.5: Features: - Introduced "systemd" hard class. (Redmine #6995) - Added paths to dtrace, zfs and zpool on FreeBSD in masterfiles. Bug fixes: - Fixed build error on certain RHEL5 and SLES10 setups. (Redmine #6841) - Fixed a bug which caused dangling symlinks not to be removed. (Redmine #6582) - Fixed data_readstringarrayidx function not preserving the order of the array it's producing. (Redmine #6920) - Fixed a bug which sometimes caused CFEngine to kill the wrong daemon if both the host and a container inside the host were running CFEngine. (Redmine #6906) - Made sure the rm_rf_depth bundle also deletes the base directory. (Redmine #7009) - Fixed monitord reporting wrongly on open ports. (Redmine #6926) - Skip adding the class when its name is longer than 1024 characters. Fixed core dump when the name is too large. (Redmine #7013) - Fixed detection of stopped process on Solaris. (Redmine #6946) - Fixed infinite loop (Redmine #6992) plus a couple more minor bugs in edit_xml promises. 3.6.4: Features: - Introduced users promises support on HP-UX platform. - Introduced process promises support on HP-UX platform. Bug fixes: - Fixed bug on FreeBSD which sometimes led to the wrong process being killed (Redmine #2330) - Fixed package version comparison sometimes failing with rpm package manager (Redmine #6807) - Fixed a bug in users promises which would sometimes set the wrong password hash if the user would also be unlocked at the same time. - Fixed a bug on AIX which would occasionally kill the wrong process. - Improved error message for functions that require an absolute path. (Redmine #6877) - Fixed some spelling errors in examples. - Fixed error in out-of-tree builds when building cf-upgrade. - Fixed a bug which would make cf-agent exit with an error if it was built with a custom log directory, and that directory did not exist. - Fixed ordering of evaluating promises when depends_on is used. (Redmine #6484, Redmine #5462) - Skip non-empty directories silently when recursively deleting. (Redmine #6331) - Fix memory exhaustion with list larger than 4994 items. (Redmine # 6672) - Fix cf-execd segfault on IP address detection (Redmine #6905). - Fix hard class detection of RHEL6 ComputeNode (Redmine #3148). 3.6.3 New features: - Support for HP-UX 11.23 and later - Experimental support for Red Hat Enterprise Linux 7 Bug fixes: - Fix getindices on multi-dimensional arrays (Redmine #6779) - Fix mustache template method to run in dryrun mode (Redmine #6739) - Set mailto and mailfrom settings for execd in def.cf (Redmine #6702) - Fix conflation of multi-index entries in arrays (Redmine #6674) - Fix promise locking when transferring using update.cf (Redmine #6623) - Update JSON parser to return an error on truncation (Redmine #6608) - Fix sys.hardware_addresses not expanded (Redmine #6603) - Fix opening database txn /var/cfengine/cf_lastseen.lmdb: MDB_READERS_FULL when running cf-keys --show-hosts (Redmine #6602) - Fix segfault (Null pointer dereference) when select_end in delete_lines never matches (Redmine #6589) - Fix max_file_size => "0" not disabling or allowing any size (Redmine #6588) - Fix ifvarclass, with iteration over list, failing when deleting files with time condition (Redmine #6577) - Fix classes defined with "or" constraint are never set if any value doesn't evaluate to a scalar (Redmine #6569) - Update "mailfrom" default in default policy (Redmine #6567) - Fix logrotate ambiguity of filename (Redmine #6563) - Fix parsing JSON files (Redmine #6549) - Reduce write count activity to /var partition (Redmine #6523) - Fix files delete attribute incorrectly triggering promise_kept (Redmine #6509) - Update services bundle output related to chkconfig when run in inform mode. (Redmine #6492) - Fix Solaris serverd tests (Redmine #6406) - Fix broken bechaviour of merging arrays with readstringarray (Redmine #6369) - Fix ifelapsed bug with bundle nesting (Redmine #6334) - Fix handling cf_null in bundlesequence (Redmine #6119) - Fix maparray reading whole input array when using subarray (Redmine #6033) - Fix directories being randomly changed to files (Redmine #6027) - Update defaults promise type to work with classes (Redmine #5748) - systemd integration in services promises (Redmine #5415) - Fix touch attribute ignoring action = warn_only (Redmine #3172) - Fix 4KB string limit in functions readfile, string_downcase, string_head, string_reverse, string_length, string_tail, string_upcase (Redmine #2912) 3.6.2 Bug fixes: - Don't regenerate software_packages.csv every time (Redmine #6441) - Improve verbose message for package_list_command - Fix missing log output on AIX (Redmine #6434) - Assorted fixes to dirname() esp on Windows (Redmine #4716) - Fix package manager detection - Fix build issues on FreeBSD - Allow copying of dead symbolic links (Redmine #6175) - Preserve order in readstringarrayidx (Redmine #6466) - Fix passing of unexpanded variable references to arrays (Redmine #5893) - Use entries for new {admin,deny}_{ips,hostnames} constraints in the relevant legacy lists (Redmine #6542) - Cope with ps's numeric fields overflowing to the right - Interpret failing function calls in ifvarclass as class not set (Redmine #6327) - Remove unexpanded lists when extending lists (Redmine #6541) - Infer start-time of a process from elapsed when needed (Redmine #4094) - Fix input range definition for laterthan() function (Redmine #6530) - Don't add trailing delimiter when join()'ing lists ending with a null-value (Redmine #6552) - 9999999999 (ten 9s) or higher has been historically used as an upper bound in CFEngine code and policy but because of overflow on 32-bit platforms it caused problems with big numbers. Fixed in two ways: first change all existing policy uses to 999999999 (nine 9s instead of eleven 9s), second fix the C code to not wrap-around in case of overflow, but use the LONG_MAX value (Redmine #6531). - cf-serverd and other daemons no longer reload their configuration every minute if CFEngine is built with an inputs directory outside of the work directory (not the default). (Redmine #6551) 3.6.1 New features: - Introduced Solaris and AIX support into the 3.6 series, with many associated build and bug fixes. Changes: - Short-circuit evaluation of classes promises if class is already set (Redmine #5241) - Fix to assume all non-specified return codes are failed in commands promises (Redmine #5986) - cf-serverd logs reconfiguration message to NOTICE (was INFO) so that it's always logged in syslog Bug fixes: - File monitoring has been completely rewritten (changes attribute in files promise), which eliminates many bugs, particularly regarding files that are deleted. Upgrading will keep all monitoring data, but downgrading again will reinitialize the DB, so all files will be reported as if they were new. (Redmine #2917) - $(this.promiser) expands in files promises for 'transformer', 'edit_template', 'copy_from.source', 'file_select.exec_program', 'classes' and 'action' bodies (Redmine #1554, #1496, #3530, #1563) - 'body changes' notifies about disappeared files in file monitoring (Redmine #2917) - Fixed CFEngine template producing a zero sized file (Redmine #6088) - Add 0-9 A-Z _ to allowed context of module protocol (Redmine #6063) - Extend ps command column width and prepend zone name on Solaris - Fixed strftime() function on Solaris when called with certain specifiers. - Fixed users promise bug regarding password hashes in a NIS/NSS setup. - Fixed $(sys.uptime), $(sys.systime) and $(sys.sysday) in AIX. (Redmine #5148, #5206) - Fixed processes_select complaining about "Unacceptable model uncertainty examining processes" (Redmine #6337) - ps command for linux has been changed to cope with big rss values (Redmine #6337) - Address ps -axo shift on FreeBSD 10 and later (Redmine #5667) - methods and services promises respect action_policy => "warn" (Redmine #5924) - LMDB should no longer deadlock if an agent is killed on the hub while holding the DB lock. Note that the change only affects binary packages shipped by CFEngine, since the upstream LMDB project has not yet integrated the change. (Redmine #6013) 3.6.0 Changes: - Changes to logging output - Add process name and pid in syslog message (GitHub #789) - cf-serverd logging levels are now more standardised: - INFO logs only failures - VERBOSE logs successful requests as well - DEBUG logs actual protocol traffic. - cf-serverd now logs the relevant client IP address on each message. - Logging contexts to local database (cf_classes.tcdb) has been deprecated. - 'usebundle' promisees are logged for all the bundle promises - output from 'reports' promises has nothing prefixed except 'R: ' - a log line with stack path is generated when the promise type evaluated changes - LMDB (symas.com/mdb) is the default database for local data storage : use version 0.9.9 or later cf-agent --self-diagnostics (-x) is only implemented for TCDB, not for LMDB - port argument in readtcp() and selectservers() may be a service name (e.g. "http", "pop3"). - Enable source file in agent copy_from promises to be a relative path. - file "changes" reporting now reports with log level "notice", instead of "error". - process_results default to AND'ing of set attributes if not specified (Redmine #3224) - interface is now canonified in sys.hardware_mac[interface] to align with sys.ipv4[interface] (Redmine #3418) - cf-promises no longer errors on missing bodies when run without --full-check (-c) - Linux flavor "SUSE" now correctly spelled with all uppercase in variables and class names (Redmine #3734). The "suse" lowercase version is also provided for convenience (Redmine #5417). - $(this.promise_filename) and $(..._dirname) variables are now absolute paths. (Redmine #3839) - Including the same file multiple times in 'body control inputs' is not an error - portnumber in body copy_from now supports service names like "cfengine", "pop3" etc, check /etc/services for more. - The failsafe.cf policy, run on bootstrap and in some other unusual cases, has been extracted from C code into libpromises/failsafe.cf - masterfiles - cf_promises_validated is now in JSON format - timestamp key is timestamp (sec since unix epoch) of last time validated - the masterfiles now come from https://github.com/cfengine/masterfiles and are not in the core repository - cf-serverd calls cf-agent with -Dcfruncommand when executing cf-runagent requests - Mark as removed: promise_notkept_log_include, promise_notkept_log_exclude, promise_repaired_log_include, promise_repaired_log_exclude, classes_include, classes_exclude, variables_include, variables_exclude attributes from report_data_select body (syntax is valid but not functional). They have been replaced by the following attributes: promise_handle_include, promise_handle_exclude, metatags_include, metatags_exclude. New features: - New promise type "users" for managing local user accounts. - TLS authentication and fully encrypted network protocol. Additions specific to the new type of connections: - New attribute "allowlegacyconnects" in body server control, which enables serving policy via non-latest CFEngine protocol, to the given list of hosts. If the option is absent, it defaults to allow all hosts. To refuse non-TLS connections, specify an empty list. - New attribute "protocol_version" in body copy_from, and body common control, which defines the preferred protocol for outgoing connections.. Allowed values at the moment: "0" or "undefined", "classic" or "1", "latest" or "2". By leaving the copy_from option as undefined the common control option is used, and if both are undefined then classic protocol is used by default. - The new networking protocol uses TLS for authentication, after which all dialog is encrypted within the established TLS session. cf-serverd is still able to speak the legacy protocol with old agents. - The 'skipverify' option in 'body server control' is deprecated and only left for compatibility; it does nothing - cf-serverd does not hang up the connection if some request fails, so that the client can add more requests. - For the connections using the new protocol, all of the paths in bundle server access_rules now differentiate between a directory and a file using the trailing slash. If the path exists then this is auto-detected and trailing slash appended automatically. You have to append a trailing slash manually to an inexistent or symbolic path (e.g. "/path/to/$(connection.ip)/") to force recursive access. - New in 'access' promises for 'bundle server access_rules' - Attributes "admit_ips", "admit_hostnames", "admit_keys", "deny_ips", "deny_hostnames", "deny_keys" - "admit_keys" and "deny_keys" add the new functionality of controlling access according to host identity, regardless of the connecting IP. - For these new attributes, regular expressions are not allowed, only CIDR notation for "admit/deny_ips", exact "SHA=..." strings for "admit/deny_keys", and exact hostnames (e.g. "cfengine.com") or subdomains (starting with dot, e.g. ".cfengine.com") for "admit/deny"_hostnames. Same rules apply to 'deny_*' attributes. - These new constraints and the paths in access_rules, can contain special variables "$(connection.ip)", "$(connection.hostname)", "$(connection.key)", which are expanded dynamically for every received connection. - For connections using the new protocol, "admit" and "deny" constraints in bundle server access_rules are being phased out, preferred attributes are now "admit_ips", "deny_ips", "admit_hostnames", "deny_hostnames", "admit_keys", "deny_keys". - New "shortcut" attribute in bundle server access_rules used to dynamically expand non-absolute request paths. - masterfiles - standard library split: lib/3.5 (compatibility) and lib/3.6 (mainline) - many standard library bundles and bodies, especially packages- and file-related, were revised and fixed - supports both Community and Enterprise - new 'inventory/' structure to provide OS, dmidecode, LSB, etc. system inventory (configured mainly in def.cf) - cf_promises_release_id contains the policy release ID which is the GIT HEAD SHA if available or hash of tree - a bunch'o'bundles to make starting with CFEngine easier: - file-related: file_mustache, file_mustache_jsonstring, file_tidy, dir_sync, file_copy, file_link, file_hardlink, file_empty, file_make - packages-related: package_absent, package_present, package_latest, package_specific_present, package_specific_absent, package_specific_latest, package_specific - XML-related: xml_insert_tree_nopath, xml_insert_tree, xml_set_value, xml_set_attribute - VCS-related: git_init, git_add, git_checkout, git_checkout_new_branch, git_clean, git_stash, git_stash_and_clean, git_commit, git - process-related: process_kill - other: cmerge, url_ping, logrotate, prunedir - New command line options for agent binaries - New options to cf-promises - '--show-classes' and '--show-vars' - '--eval-functions' controls whether cf-promises should evaluate functions - Colorized output for agent binaries with command line option '--color' (auto-enabled if you set CFENGINE_COLOR=1) - New language features - New variable type 'data' for handling of structured data (ie JSON), including supporting functions: - 'data_readstringarray' - read a delimited file into a data map - 'data_readstringarrayidx' - read a delimited file into a data array - 'datastate' - create a data variable with currently set classes and variables - 'datatype' - determine the type of the top element of a container - 'format' - %S can be used to serialize 'data' containers into a string - 'mergedata' - merge two data containers, slists/ilists/rlists, or "classic" arrays into a data container - 'parsejson' - create a data container from a JSON string - 'readjson' - create a data container from a file that contains JSON - 'storejson' - serialize a data container into a string - Most functions operating on lists can also operate on data containers - pass a data container to a bundle with the @(container) notation - the module protocol accepts JSON for data containers with the '%' sigil - Tagging of classes and variables allows annotating of language construct with meta data; supporting functionality: - The module protocol in 'commands' promises has been extended to allow setting of tags of created variables and classes, and the context of created variables - 'getclassmetatags' - returns list of meta tags for a class - 'getvariablemetatags' - returns list of meta tags for a variable - 'body file control' has an 'inputs' attribute to include library files and other dependencies - bundlesequences can be built with bundlesmatching() based on bundle name and tags - New attributes in existing promise types and bodies - New option 'preserve_all_lines' for insert_type in insert_lines promises - Caching of expensive system functions to avoid multiple executions of execresult() etc, can be controlled via cache_system_functions attribute in body common control - New option 'mailsubject' in body executor control allows defining the subject in emails sent by CFEngine - Support for Mustache templates in 'files' promises; use 'template_method' and 'template_data' attributes. Without 'template_data' specified, uses datastate(). - New and improved functions - 'bundlesmatching' - returns list of defined bundles matching a regex and tags - 'canonifyuniquely' - converts a string into a unique, legal class name - 'classesmatching' - returns list of set classes matching a regex and tags - 'eval' - evaluates mathematical expressions; knows SI k, m, g quantifiers, e.g. "100k" - 'findfiles' - list files matching a search pattern; use "**" for recursive searches - 'makerule' - evaluates whether a target file needs to be rebuilt from sources - 'max', 'min' - returns maximum and minimum of the numbers in a container or list (sorted by a 'sort' method) - 'mean' - returns the mean of the numbers in a container or list - 'nth' - learned to look up by key in a data container holding a map - 'packagesmatching' - returns a filtered list of installed packages. - 'readfile' - learned to read system files of unknown size like those in /proc - 'sort' - can sort lexicographically, numerically (int or real), by IP, or by MAC - 'string_downcase', 'string_upcase' - returns the lower-/upper-case version of a string - 'string_head', 'string_tail' - returns the beginning/end of a string - 'string_length' - returns the length of a string - 'string_reverse' - reverses a string - 'string_split' - improved implementation, deprecates 'splitstring' - 'variablesmatching' - returns a list of variables matching a regex and tags - 'variance' - returns the variance of numbers in a list or container - New hard classes - Introduced alias 'policy_server' for context 'am_policy_hub' (the latter will be deprecated) - all the time-based classes have GMT equivalents - New variables - 'sys.bindir' - the location of the CFEngine binaries - 'sys.failsafe_policy_path' - the location of the failsafe policy file - 'sys.inputdir' - the directory where CFEngine searches for policy files - 'sys.key_digest' - the digest of the host's cryptographic key - 'sys.libdir', 'sys.local_libdir' - the location of the CFEngine libraries - 'sys.logdir' - the directory where the CFEngine log files are saved - 'sys.masterdir' - the location of masterfiles on the policy server - 'sys.piddir' - the directory where the daemon pid files are saved - 'sys.sysday' - the number of days since the beginning of the UNIX epoch - 'sys.systime' - the number of seconds since the beginning of the UNIX epoch - 'sys.update_policy_path' - the name of the update policy file - 'sys.uptime' - the number of minutes the host has been online - 'this.promise_dirname' - the name of the file in which the current promise is defined - 'this.promiser_uid' - the ID of the user running cf-agent - 'this.promiser_gid' - the group ID of the user running cf-agent - 'this.promiser_ppid' - the ID of the parent process running cf-agent Deprecations: - 'splitstring' - deprecated by 'string_split' - 'track_value' - 'skipverify' Bug fixes: for a complete list of fixed bugs, see Redmine at https://cfengine.com/dev - Various fixes in evaluation and variable resolution - Improve performance of list iteration (Redmine #1875) - Removed limitation of input length to internal buffer sizes - directories ending with "/" are not ignored - lsdir() always return a list now, never a scalar - 'abortclasses' fixed to work in common bundles and other cases - Namespaced 'edit_line' bundles now work (Redmine#3781) - Lists are interpolated in correct order (Redmine#3122) - cf-serverd reloads policies properly when they change - Lots of leaks (memory and file descriptor) fixed 3.5.3 Changes: - Improved security checks of symlink ownership. A symlink created by a user pointing to resources owned by a different user will no longer be followed. - Changed the way package versions are compared in package promises. (Redmine #3314) In previous versions the comparison was inconsistent. This has been fixed, but may also lead to behavior changes in certain cases. In CFEngine 3.5.3, the comparison works as follows: For instance: apache-2.2.31 ">=" "2.2.0" will result in the package being installed. Bug fixes: - Fix cf-monitord crash due to incorrect array initialization (Redmine #3180) - Fix cf-serverd stat()'ing the file tree every second (Redmine #3479) - Correctly populate sys.hardware_addresses variable (Redmine #2936) - Add support for Debian's GNU/kfreebsd to build system (Redmine #3500) - Fix possible stack corruption in guest_environments promises (Redmine #3552) - Work-around hostname trunctation in HP-UX's uname (Redmine #3517) - Fix body copy purging of empty directories (Redmine #3429) - Make discovery and loading of avahi libraries more robust - Compile and packaging fixes for HP-UX, AIX and Solaris - Fix fatal error in lsdir() when directory doesn't exist (Redmine #3273) - Fix epoch calculation for stime inrange calculation (Redmine #2921) 3.5.2 Bug fixes: - Fix delayed abortclasses checking (Redmine #2316, #3114, #3003) - Fix maplist arguments bug (Redmine #3256) - Fix segfaults in cf-pomises (Redmine #3173, 3194) - Fix build on Solaris 10/SmartOS (Redmine #3097) - Sanitize characters from /etc/issue in sys.flavor for Debian (Redmine #2988) - Fix segfault when dealing with files or data > 4K (Redmine #2912, 2698) - Don't truncate keys to 126 characters in getindices (Redmine #2626) - Files created via log_* actions now have mode 600 (Redmine #1578) - Fix wrong log message when a promise is ignored due to 'ifvarclass' not matching - Fix lifetime of persistent classes (Redmine #3259) - Fix segfault when process_select body had no process_result attribute Default to AND'ed expression of all specified attributes (Redmine #3224) - Include system message in output when acl promises fail - Fix invocation of standard_services bundle and corresponding promise compliance (Redmine #2869) 3.5.1 Changes: - File changes are logged with log level Notice, not Error - The CFEngine Standard Library in masterfiles/libraries is now split into promise-type specific policy files, and lives in a version-specific directory. This should have no impact on current code, but allows more granular include of needed stdlib elements (Redmine #3044) Bug fixes: - Fix recursive copying of files (Redmine #2965) - Respect classes in templates (Redmine ##2928) - Fix timestamps on Windows (Redmine #2933) - Fix non-root cf-agent flooding syslog (Redmine #2980) - Fix email flood from cf-execd due to timestamps in agent output (Redmine #3011) - Preserve security context when editing or copying local files (Redmine #2728) - Fix path for sys.crontab on redhat systems (Redmine #2553) - Prevent incorrect "insert_lines promise uses the same select_line_matching anchor" warning (Redmine #2778) - Fix regression of setting VIPADDRESS to 127.0.0.1 (Redmine #3010) - Fix "changes" promise not receiving status when file is missing (Redmine #2820) - Fix symlinks being destroyed when editing them (Redmine #2363) - Fix missing "promise kept" status for the last line in a file (Redmine #2943) 3.5.0 New features: - classes promises now take an optional scope constraint. - New built-in functions: every, none, some, nth, sublist, uniq, filter - every - none - some - nth - sublist - uniq - filter - classesmatching - strftime - filestat - ifelse - maparray - format - cf-promises flag --parse-tree is replaced by --policy-output-format=, requiring the user to specify the output format (none, cf, json) - cf-promises allows partial check of policy (without body common control) without integrity check; --full-check enforces integrity check - Agent binaries support JSON input format (.json file as generated by cf-promises) - cf-key: new options --trust-key/-t and --print-digest/-p - Class "failsafe_fallback" is defined in failsafe.cf when main policy contains errors and failsafe is run because of this - Add scope attribute for body classes (Redmine #2013) - Better diagnostics of parsing errors - Error messages from parser now show the context of error - New cf-agent option: --self-diagnostics - New output format, and --legacy-output - Warnings for cf-promises. - Enable zeroconf-discovery of policy hubs for automatic bootstrapping if Avahi is present - Support for sys.cpus on more platforms than Linux & HPUX Changes: - Parser no longer allows ',' after promiser or promisee. must be either ';' or lval - Make parser output in GCC compatible format the only supported format (remove --gcc-brief-format flag) - Silence license warnings in Enterprise Free25 installations - action_policy => "warn" causes not_kept classes to be set on promise needing repair. - Command line option version (-V) now prints a shorter parsable version without graphic - Implicit execution of server and common bundles taking arguments is skipped in cf-serverd. - WARNING: option --policy-server removed, require option to --bootstrap instead - process promises don't log if processes are out of range unless you run in verbose mode - reports promises are now allowed in any context (Redmine #2005) - cf-report has been removed - cf-execd: --once implies --no-fork - Version info removed from mail subject in the emails sent by cf-execd. The subject will only contain "[fqname/ipaddress]" instead of "communnity/nova [fqname/ipaddress]" Please change your email filters accordingly if necessary. - "outputs" promise type is retired. Their semantics was not clear, and the functionality is better suited for control body setting, not a promise. - Tokyo Cabinet databases are now automatically checked for correctness during opening. It should prevent a number of issues with corrupted TC databases causing binaries to hang. - Improved ACL handling on Windows, which led to some syntax changes. We now consistently use the term "default" to describe ACLs that can be inherited by child objects. These keywords have received new names: acl_directory_inherit -> acl_default specify_inherit_aces -> specify_default_aces The old keywords are deprecated, but still valid. In addition, a new keyword "acl_inherit" controls inheritance behavior on Windows. This feature does not exist on Unix platforms. (Redmine #1832) - Networking code is moved from libpromises to its own library, libcfnet. Work has begun on making the API more sane and thread-safe. Lots of legacy code was removed. - Add getaddrinfo() replacement in libcompat (borrowed from PostgreSQL). - Replace old deprecated and non thread-safe resolver calls with getaddrinfo() and getnameinfo(). - Hostname2IPString(), IPString2Hostname() are now thread-safe, and are returning error when resolution fails. - Running cf-execd --once now implies --no-fork, and also does not wait for splaytime to pass. - execresult(), returnszero() and commands promises no longer requires the first word word to be an absolute path when using the shell. (Part of Redmine #2143) - commands promises useshell attribute now accepts "noshell" and "useshell" values. Boolean values are accepted but deprecated. (Part of Redmine #2143) - returnszero() now correctly sets the class name in this scenario (Part of Redmine #2143): classes: "commandfailed" not => returnszero("/bin/nosuchcommand", "noshell"); Bugfixes: - Bundles are allowed to be empty (Redmine #2411) - Fixed '.' and '-' not being accepted by a commands module. (Redmine #2384) - Correct parsing of list variables by a command module. (Redmine #2239) - Fixed issue with package management and warn. (Redmine #1831) - Fixed JSON crash. (Redmine #2151) - Improved error checking when using fgets(). (Redmine #2451) - Fixed error message when deleting nonexistent files. (Redmine #2448) - Honor warn-only when purging from local directory. (Redmine #2162) - Make sure "restart" and "reload" are recognized keywords in packages. (Redmine #2468) - Allocate memory dynamically to avoid out-of-buffer or out-of-hash situations - Fix edit_xml update of existing attributes (Redmine #2034) - Use failsafe policy from compile-time specified workdir (Redmine #1991) - ifvarclass checked from classes promises in common bundles - Do not wait for splaytime when executing only once - Disable xml editing functionality when libxml2 doesn't provide necessary APIs (Redmine #1937) - Out-of-tree builds should work again, fixed a bunch of related bugs. - Fixed race condition in file editing. (Redmine #2545) - Fixed memory leak in cf-serverd and others (Redmine #1758) 3.4.5: (Bugfix and stability release) Bugfixes: - Make qualified arrays expand correcty (Redmine #1998, Mantis #1128) - Correct possible errors in tcdb files when opening - Avoid possible db corruption when mixing read/write and cursor operations - Allow umask value of 002 (Redmine #2496) 3.4.4: (Bugfix and stability release) Bugfixes: - Prevent possible crash when archiving files (GitHub #316) - Don't create symlinks to cf-know in update policy - Don't enable xml support if libxml2 is too old (Redmine #1937) 3.4.3: (Bugfix and stability release) Bugfixes: - Don't flood error messages when processes are out of defined range - Prevent segmentation fault in cf-monitord -x (Redmine #2021) - When copying files, use same file mode as source file, rather than 0600 (Redmine #1804) - Include xpath in messages generated by edit_xml operations (Redmine #2057) 3.4.2: (Bugfix and stability release) Bugfixes: - Fixes to policies in masterfiles (see masterfiles/Changelog for details) - Fixes for OpenBSD (GitHub #278) - Do not canonify values specified in abortbundleclasses/abortclasses (Redmine #1786) - Fix build issues on NetBSD, SLES 12.2 - Improve error message when libxml2 support is not compiled (Redmine #1799) - Fix potential segmentation fault when trimming network socket data (GitHub #233) - Fix potential segmentation fault when address-lookups in lastseen db failed (GitHub #233) - Execute background promise serially when max_children was reached, rather than skipping them (GitHub #233) - Fix segmentation fault in cf-promises when invoked with --reports (Redmine #1931) - Fix compilation with Sun Studio 12 (Redmine #1901) - Silence type-pun warning when building on HP-UX (GitHub #287) 3.4.1: (Bugfix and stability release) New feature/behavior: - cf-execd terminates agent processes that are not responsive for a configurable amount of time (see agent_expireafter in body executor control), defaulting to 1 week Bugfixes: - Fix regression of classmatch() failing with hard classes (Redmine #1834) - Create promise-defined and persistent classes in correct namespace (Redmine #1836) - Several fixes to namespace support - Fix several crash bugs caused by buffer overflow and race conditions in cf-serverd - Regenerate time classes in cf-execd for each run (Redmine #1838) - edit_xml: fix select_xpath implementation and update documentation NOTE: code that uses select_xpath_region needs to be changed to select_xpath - edit_xml: make sure that text-modification functions don't overwrite child nodes - edit_xml: improve error logging 3.4.0 New features: - Added rpmvercmp utility to compare versions of RPM packages for accurate sorting of RPM packages for packages promises. - Implement network timeout on server side to avoid keeping stale connections for hours. - XML editing capabilities. See the documentation for edit_xml body. Note the new dependency: libxml2. - Implement inheritance of local classes by bundles called using "usebundle". By default classes are not inherited. See the examples/unit_inherit.cf for an example. - Moved from Nova/Enterprise: - POSIX ACL support, - "outputs" promise type, - remote syslog support. - packages_default_arch_command hook in packages promises, to specify default architecture of the packages on the system. - packages_version_less_command / packages_version_equal_command hooks in packages promises, to specify external command for native package manager versions comparison - agent_expireafter in body executor control allows you to set a timeout on all cf-agent runs, to enforce a threshold on the number of concurrent agents - Running in Solaris zone is now detected and classes "zone" and "zone_" are created in this case. - VirtualBox support added to guest_environment promises. - guest_environment promises are supported under OS X. - The "depends_on" attribute is now active, for the partal ordering of promises. If a promise depends on another (referred by handle) it will only be considered if the depends_on list is either kept or repaired already. ** WARNING: When upgrading, make sure that any existing use of depends_on does not make some promises being unintentionally ignored. This can happen if you are currently referring to non-existent or never-run handles in depends_on attributes. - methods return values, initial implementation - New format for cf-key -s, includes timestamp of last connection - cf-promises --parse-tree option to parse policy file and dump it in JSON format - Namespaces support for bundles and bodies. See the examples/unit_namespace*.cf for the usage. - Default arguments for bundles. See the examples/unit_defaults.cf - Metadata promise type. See the examples/unit_meta.cf New semantics: - Methods promises now return the status of promises kept within them. If any promise was not kept, the method is not kept, else if any promise is repaired, the method was repaired else it was kept. - Remote variable access in namespaces by $(namespace:bundle.variable) Changed functionality: - cf-execd -F switch no longer implies 'run once'. New -O/--once option is added to achieve this behaviour. This makes cf-execd easier to run from systemd, launchd and other supervision systems. Misc: - Support for the following outdated platforms and corresponding classes has been removed. De facto those platforms were unsupported for a long time, as CFEngine codebase uses C99 language features unavailable on old platforms: - SunOS 3.x (sun3) - SunOS 4.x (sun4) - Ultrix (ultrix) - DEC OSF/1 AXP (osf) - Digital UNIX (digital) - Sony NEWS (newsos) - 4.3BSD (bsd4_3) - IRIX (irix, irix4, irix64) - IBM Academic Operating System (aos) - BSD/OS / BSDi / BSD/386 (bsdos) - NeXTSTEP (nextstep) - GNU Hurd (gnu) - NEC UX/4800 (ux4800) - (Old news) Since 3.3.0 the layout of CFEngine Community packages has changed slightly. cf-* binaries have been moved to /var/cfengine/bin, due to the following reasons: - cf-* binaries are linked to libraries installed to /var/cfengine/lib, so placing binaries in /usr/local/sbin does not increase reliability of the CFEngine, - keeping whole CFEngine under single prefix (/var/cfengine) makes packaging simpler, - it matches the layout of CFEngine Enterprise packages. Please adjust your policies (the recommended ways to deal with the move are either to adjust $PATH to include /var/cfengine or to create symlinks in /usr/local/sbin in case you are relying on binaries to be available in $PATH). - Workdir location is properly changed if --prefix or --enable-fhs options are supplied to configure (Mantis #1195). - Added check for broken libmysqlclient implementations (Mantis #1217). - Standard library is updated from COPBL repository. - cf-know is no longer built in Community releases. The only functionality useful in Community, namely the reference manual generation, is provided by new compile-time cf-gendoc tool. - Filename (for storing filechanges) changed from file_change.log -> file_changes.log (in /var/cfengine/state) New format for storing file changes introduced: [timestamp,filename,,Message] N = New file found C = Content Changed S = Stats changed R = File removed - Acceptance test suite passes on Mac OS X. - Changed some port numbers to replace old services with imap(s) - archlinux hard class on Arch Linux. - Detect BSD Make and automatically switch to GNU Make during build. Bugfixes: - cfruncommand for cf-execd is an arbitrary shell command now (Mantis #1268). - Fixed broken "daily" splayclasses (Mantis #1307). - Allow filenames up to 4096 bytes in network transfers (Redmine #1199). - Fix stale state preserved during cf-serverd reload (Redmine #1487). - Free disk space calculation is fixed (Mantis #1120). - Numerous portability bugfixes (especially OpenBSD, Solaris, AIX-related). - Compatibility fixes for AIX, HP-UX, Solaris (Mantis #1185, Mantis #1177, Mantis #1109). - Fixed broken socklen_t configure check under OpenBSD (Mantis #1168). - Fixed hang in cf-promises under OpenBSD (Mantis #1113). - Fixed endless loop in evaluating "$()" construct (Mantis #1023). - Fixed check for old PCRE versions (Mantis #1262). - Fixed insertion of multi-line blocks at the start of file (Mantis #809). - Fixed numerous memory leaks. - Fixes for metadata that were not resolvable - Fixes for namespaces that would not support metadata and variable expansion - Point-to-point network interfaces are detected and reported by CFEngine (Mantis #1246) - Partial non-GNU userspace support in acceptance testsuite (Mantis #1255) Full list of issues fixed is available on https://cfengine.com/bugtracker/changelog_page.php (old bug tracker) and https://cfengine.com/dev/projects/core/versions/34 (new bug tracker) 3.3.9: (Bugfix and stability release) Bugfixes: - Do not lose hard classes in cf-serverd during policy reload (Mantis #1218). - Implement receive network timeout in cf-serverd. Prevents overloading cf-serverd with stale connections. 3.3.8: (Bugfix and stability release) Versions 3.3.6, 3.3.7 were internal and weren't released. Bugfixes: - Propery set sys.domain variable if hostname is fully-qualified. - Fixed several small memory leaks. - Make network timeout for network reads configurable. Previously it was hardcoded to be 30 seconds, which was not enough for cf-runagent invoking cf-agent on big policies (Mantis #1028). 3.3.5: (Bugfix and stability release) Bugfixes: - Fixed cf-execd memory leak on hosts with cf-monitord running. - Robustify against wrongly-sized entires in embedded databases. Standard library: - Bugfixes from upstream COPBL repository. - standard_services bundle from upstream COPBL repository. 3.3.4: (Bugfix and stability release) Evaluation of policies: - Fix wrong classes set after installation of several packages using packages promises (Mantis #829). - Fix segfault using edit_template on existing file (Mantis #1155). Misc: - Fix memory leak during re-read of network interfaces' information in cf-execd/cf-serverd. 3.3.3: (Bugfix and stability release) Evaluation of policies: - Zero-length files are valid for readfile() and similar functions (Mantis #1136). - Unchoke agent in case it encounters symlinks in form ./foo (Similar to Mantis #1117). Misc: - Fix generation of reference manual on machines with umask more relaxed than 022. - Use statvfs(3) on OpenBSD to obtain filesystem information (Mantis #1135). 3.3.2: (Bugfix and stability release) Evaluation of policies: - Do not segfault if file copy was interrupted due to network connectivity or server going away (Mantis #1089). - Do not segfault if log_failed attribute is present in body, but log_kept is not (Mantis #1107). - Do not mangle relative paths in symlinks during file copy Previously symlink a -> b was mangled to a -> ./b. (Mantis #1117) - Properly compare 1.0 and 1.0.1 in packages promises. Previously only versions with equal amount of "segments" were comparable (Mantis #890, #1066). Base policy: - Properly set permissions on files for /var/cfengine/lib on HP-UX (Mantis #1114). - Standard library (cfengine_stdlib.cf) is synced with COPBL repository. Misc: - Do not create huge file in case corrupted TokyoCabinet database is detected (Mantis #1106). - Fix file descriptor leak on error paths, may have caused crashes of cf-execd and cf-serverd (Issue #1096). - Fix intermittent segfault in cf-execd (Mantis #1116). - Impose an upper limit on amount of listening sockets reported by cf-monitord. Huge amounts of listening sockets caused cf-agent to segfault on next run (Mantis #1098). - Add missing function prototypes caused errors during compilation on HP-UX (Mantis #1109). - Fix compilation on Solaris 11 (Mantis #1091). 3.3.1: (Bugfix and stability release) Evaluation of policies: - Do not cut off name of bundle in variables interpolation (Mantis #975). - Do not segfault in function evaluation guarded by ifvaclass clause (Mantis #1084, #864). - Do not segfault if "classes" promise does not declare any value to be evaluated (Mantis #1074). - Do not segfault in database promises if there is no database_operation provided (Mantis #1046). Built-in functions: - Fix countclassesmatching() function which was misbehaving trying to match classes starting with alphanumeric symbol (Mantis #1073). - Fix diskfree() to return kilobytes, as described in documentation (Mantis #980, #955). - Fix hostsseen() function to avoid treating all hosts as not being seen since 1970 (Mantis #886). - Do not output misleading error message if readtcp() is unable to connect (Mantis #1085). Command-line interface: - -d option previously reqired an argument, though help message disagreed (Mantis #1053). - Disable --parse-tree option, not ready for the release (Mantis #1063). - Acept -h as a --help option. - Ensure that cf-execd might be started right after being shut down. Misc: - Plug file descriptor leak after failed file copy (Mantis #990). - Fix unsafe admit rules in default promises.cf (Mantis #1040). - Fix splaytime to match documentation: it is specified in minutes, not seconds (Mantis #1099). Packaging: - Fix owner/group of initscript and profile.d snippet in RPM builds (Mantis #1061, #1058). - Fix location of libvirt socket CFEngine uses to connect to libvirtd (Mantis #1072). - Install CoreBase to /var/cfengine/masterfiles during installation (Mantis #1075). - Do not leave old cf-twin around after upgrade (Mantis #1068) - Do not leave rcS.d symlinks after purging .deb package (Mantis #1092). 3.3.0 New promise types: - Guest environments promises, which allow to manipulate virtual machines using libvirt. - Database promises, which allow to maintain schema of MySQL and PostgreSQL databases. Database promises are in "technical preview" status: this promise type is subject to change in future. - Services promises for Unix, allows abstraction of details on managing any service New built-in functions: - dirname() to complement lastnode() - lsdir() - maplist() to apply functions over lists New features: - Allow defining arrays from modules. - Allow both process_stop' and signals' constraints in processes' promises at the same time. - cf-promises --gcc-brief-format option to output warnings and errors in gcc-compatible syntax which to ease use "go to next error" feature of text editors. - Iteration over lists is now allowed for qualified (non-local) lists. New built-in variables and classes (Linux): - Number of CPUs: $(sys.cpus), 1_cpu, 2_cpus etc New built-in variables and classes (Unices): - $(sys.last_policy_update) - timestamp when last policy change was seen by host - $(sys.hardware_addresses) - list of MAC adresses - $(sys.ip_addresses) - list of IP addresses - $(sys.interfaces) - list of network interfaces - $(sys.hardware_mac[$iface]) - MAC address for network interface - mac_:: - discovered MAC addresses Changes: - Major cleanup of database handling code. Should radically decrease amount of database issues experienced under heavy load. *WARNING*: Berkeley DB and SQLite backends are *removed*, use Tokyo Cabinet or QDBM instead. Both Tokyo Cabinet and QDBM are faster than Berkeley DB in typical CFEngine workloads. Tokyo Cabinet requires C99 environment, so it should be available on every contemporary operating system. For the older systems QDBM, which relies only on C89, is a better replacement, and deemed to be as portable, as Berkeley DB. - Change of lastseen database schema. Should radically decrease I/O contention on lasteen database. - Automatic reload of policies by cf-execd. - Documentation is generated during build, PDF and HTML files are retired from repository. - Rarely used feature retired: peer connectivity intermittency calculation. - Memory and CPU usage improvements. - Testsuite now uses 'make check' convention and does not need root privileges anymore. - cf_promises_validated now filled with timestamp, allows digest-copy for policy instead of mtime copy which is safer when clocks are unsynchronised - The bundled failsafe.cf policy now has trustkey=false to avoid IP spoofing attacks in default policy - See the full list of bugfixes at https://cfengine.com/bugtracker/changelog_page.php 3.2.4: (Bugfix and stability release) - Fixed failure in network transfer in case of misbehaving peer - A few tiny memory leaks on error paths fixed 3.2.3: (Bugfix and stability release) - A few tiny memory leaks fixed - Improved performance of cf-serverd under heavy load with TokyoCabinet database - Full list of issues fixed is available on https://cfengine.com/bugtracker/changelog_page.php 3.2.2: (Bugfix and stability release) - Enabled compilation in "large files" mode under AIX - Alleviated problem with broken file transfers over unstable internet links. - Full list of issues fixed is available on https://cfengine.com/bugtracker/changelog_page.php 3.2.1: (Bugfix and stability release) - Fixed compilation under HP-UX and Solaris - Enabled compilation using HP ANSI C compiler - Full list of issues fixed is available on - https://cfengine.com/bugtracker/changelog_page.php 3.2.0: New bootstrap method with single-command bootstrapping: - cf-agent --bootstrap --policy-server 123.456.789.123 - Associated policy template files are added, partially maintained by CFEngine - Bug fixes for file-editing, package versioning, and embedded database corruption (We recommend using TokyoCabinet instead of BerkeleyDB if building from source). - Improved upgrade path for Nova. - Patches for improved run-agent concurrency - Reorganization of documentation and community resources - 100% on regression test suite on 3 operating systems (Ubuntu, Debian, SuSE on x86-64 hardware) - Support for multiple release environments - package_policy update and addupdate now check if user-supplied version is larger than currently installed - updates only if so - Help text of cf-report -r corrected - a list of key hashes is required, not ip addresses. - New Emacs mode for CFEngine policy files (thanks to Ted Zlatanov!) - Warnings are on edit_line changes can now give greater degree of information without spamming promise logs - Class expressions parser accepts '||' as an alias for '|' again. - Invalidation of package list cache on installation/removal of packages. - New option cf-key -r to remove host key by IP or hostname. - Added detection of network interfaces which belong to BSD jails. - Improve robustness of multi-threaded code, in particular fix problems with spurious access denials in server and losing of authentication rules after policy reload. - cf-promises accepts option -b matching cf-agent, which causes it to do not complain about missing bundlesequence. - New functions and(), not(), or() and concat() to ease use of ifvarclass() clause. - Full list of issues fixed is available on https://cfengine.com/bugtracker/changelog_page.php 3.1.5: - New class parser, '||' is no longer allowed in expressions (use '|'). - Class setting in the promise types insert_lines, delete_lines, replace_patterns, field_edits, vars, classes is restored. - suspiciousnames implemented. - New function getvalues(). - New functions parse{read,int,string}array to match read{read,int,string}array. - Testsuite added to check for core functionality. - Syslog prefix is fixed to say 'cf3' instead of 'community'. 3.1.4: (Bugfix and stability release) - Some urgent patches to 3.1.3. - Class validation parse bug fixed. - Global zone handling error for solaris fixed. - Package architectures handled correctly (bug #456). - Reading and writing of key name "root-.pub" eliminated (bug #442, #453). - cf-serverd crash because of race condition on SERVER_KEYSEEN fixed. - Lock purging to avoid remnant complexity explosion (bug #430). - Some copyright notices added that got lost. 3.1.3: (Stability release) - Major memory leaks in cf-monitord, cf-execd, cf-serverd fixed (bug #427). The daemons now show no growth even with very complex policies. - cf-serverd crash due to race condition in DeleteScope() fixed (bug #406). - Added 30 second timeout on recv() on Linux. - package_noverify_returncode implemented (bug #256). - A flexible mechanism for setting classes based on return codes of commands has been introduced. Allows for setting promise kept, repaired or failed based on any return codes. This is currently implemented for commands-promises, package-manager commands and transformer in files. In classes body, see attributes kept_returncodes, repaired_returncodes, failed_returncodes (bug #248, #329). - New function ip2host - reverse DNS lookup (bug #146). 3.1.2: (Scalability/efficiency release) - Big efficiency improvements by caching output from cf-promises. Can also be used for much more efficient policy deployment (only pull if changed). - Caching state of ps command for greater efficiency. Reloaded for each bundle. - Index class lookup improves efficiency of class evaluation for huge configurations. - Fixed issue where certain promiser strings got corrupted. - Minor memory access issues fixed. - Iterator bug introduced in 3.1.0 fixed 3.1.1: (Bugfix release) - Memory leaks in server tracked down and fixed. - List expansion bug (one list items not executed) fixed. - Security issue introduced by change of runcommand shell policy fixed. If users defined a runcommand for cf-runagent/cf-serverd communication, possible to execute commands. - cf-key -s command for showing key hash/IP address identity pairs 3.1.0: - Change in storage of public keys. Cfengine now hashes the public key and uses this as the keyname. Keys will be converted automatically. - The old dynamic addresses lists are deprecated. Caching of dns and key information for greater server speed. Change in last-seen format reflects the public key usage. - New package policy addupdate - installs package if not there and updates it otherwise. - Support for package_changes => "bulk" in file repository as well. - New special function readstringarrayidx, similar to readstringarray, but uses integer indices. Very useful if first row elements are not good identifiers (e.g. contains spaces, non-unique, etc.). - Change two log formats to use time() instead of date() - filechanges - total compliance - Change from using md5 to sha256 as default digest for commercial version, community retains md5 for compat. - Commands not returning 0 in commands-promises are flagged as repair_failed. - Adjustable timeout on connect(). Defaults to 10 seconds, adjustable with default_timeout in agent control. - Redesign of the knowledge map infrastructure. - Now possible to use variables to call methods, e.g methods: "name $(list)" usebundle => $(list)("abc"); See reference manual notes - Changes to normal ordering to optimize execution. - Increased stability by always initializing Attribute and Promise structures. - When running cf-promises in dry-run mode (-n), the user does not need to put binaries in WORKDIR/bin. For example, non-privileged users can verify root policies. - Source control revision added in version string if run in verbose mode (e.g. "cf-promises -vV"). This needs some refining, uses revision of a header now. - New semantics in return values of list functions. Null values are now allowed and there is no iteration over empty lists. The value "cf_null" is reserved for use as a null iterator. 3.0.5p1: - Showing paths allowed/denied access to when cf-serverd is run in verbose mode. - Bug in server fixed for dynamic addresses. - File handle closure bugfix - too many open databases. - Seg fault in mount files fix. - Twin used in cf-execd without checking. - Check_root set wrong directory permissions at source not destination. - Error message degraded in body definition. - Undefined body not warned as error. - Various build enahncements. - Package_list_update called only once per manager, and fixed crash. - Version number bug in packages. 3.0.5: - Encryption problems fixed - client key buffer was uninitialized. - Classes-promisers are now automatically canonified when class strings are defined, to simplifying the use of variables in classes. - New scalars sys.cf_version and sys.nova_version that hold Cfengine version information. - Attribute package_delete_convention added, to allow customizable package name in delete command during update. - package_list_update_ifelapsed limit added. - Private variable $(firstrepo) is available in package_name_convention and package_delete_convention in order to expand the full path to a package, which is required by some managers. - Some of the threading code is rewritten and made more robust. This includes synchronizing access to the lastseen database from the server. - Bad initialization of BSD flags fixed - Multiple variable expansion issues in control fixed for server and agent - Allow ignore_missing_bundles to affect methods: bundles too - Run agent trust dialogue fixed - Bug in CPU monitoring, increasing time scale caused linear decay of CPU measurement. - Bug in Setuid log storage, fix. - Hooks added for new Nova virtualization promises. - Multithreading mutex failed to collide during cfservd leading to dropped authentication under heavy load. 3.0.4: - Class cancellation in promises to create better class feedback, allows emulation of switch/case semantics etc - Value of SA measurement promises - Special function getenv() which returns the contents of an environment variable (on all platforms). - New function translatepath for generic Windows - New function escape() to escape literals as regular expressions (like SQL) - New function host2ip for caching IP address lookup - New function regextract for setting variables with backreferences - New variables for the components $(sys.cf_agent), $(sys.cf_know) etc pointing to the binaries. - More robust integrated database implementation; closing all handles when receiving signals, self-healing on corruption. - Package installation on localhost without a manager like yum completed, multiple repositories searched, and universal methods. - Numerous bugfixes 3.0.3: - sha256 .. new hashes in openssl included in syntax tree. - End of line autocropping in readfile (hopefully intelligent) - hashmatch function incorrectly implemented - old debugging code left behind. Fix. - sys.crontab variable - Unknown user is now interpretated as "same user", so that we give CFEngine a chance to fix - Unregistered addresses no longer report "(Non registered IP)", but return as the address itself when doing reverse lookups. 3.0.2: - IMPORTANT: Change in normal ordering of editing. replace comes after insert lines Much testing and minor bug fixing - Memory leaks fixed - Many hooks added for Nova enterprise extensions. - promise_output reports now placed in WORKDIR/reports directory - Initialization correction and self-correx in monitord - Many new body constraints added. - Code readied for enterprise version Nova. - -b option can override the bundlesequence (must not contain parameters yet) - collapse_destination_dir option added to copy so that files can be aggregated from subdirectories into a single destination. 3.0.1: - First standalone release, independent of CFEngine 2 Purge old definitions and check consistency. - NB: changed search_mode to be a list of matching values - Reporting rationalized in cf-promises with -r only to avoid leaving output files everywhere. - Hooks added for upcoming commercial additions to CFEngine. - Added classify() and hostinnetgroup() functions - Added additional change management options for change detection - Package management added - generic mechanisms. - Limits on backgrounding added to avoid resource contention during CFEngine runs. - Image type added to cf-know. - New classes for quartly shifts: Morning,Afternoon,Evening,Night - Bug fixes in editfiles - line insertion for multiple line objects - Change the name of the variables and context from the monitord for better separation of data, and shorter names. sys -> mon average -> av, stddev -> dev - Canonical name for windows changed from "nt" to "windows", also version names added "vista","xp" etc.. - License notices updated for dual license editions. 3.0.0: - First release of CFEngine 3. Known omissions: - no support for ACLs - no support for packages - no support for interface configuration - These will be added in the next release. cfengine-3.24.2/config.post.h.in0000644000000000000000000000225115010704253016362 0ustar00rootroot00000000000000/* Copyright 2021 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ /* * Macros which cannot be declared before inclusion of system headers from config.h * (say, #define mkdir rpl_mkdir) due to conflicts arising from it, are declared here. */ @post_macros@ cfengine-3.24.2/ylwrap0000755000000000000000000001531215010704300014612 0ustar00rootroot00000000000000#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2013-01-12.17; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . get_dirname () { case $1 in */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; # Otherwise, we want the empty string (not "."). esac } # guard FILE # ---------- # The CPP macro used to guard inclusion of FILE. guard () { printf '%s\n' "$1" \ | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ -e 's/__*/_/g' } # quote_for_sed [STRING] # ---------------------- # Return STRING (or stdin) quoted to be used as a sed pattern. quote_for_sed () { case $# in 0) cat;; 1) printf '%s\n' "$1";; esac \ | sed -e 's|[][\\.*]|\\&|g' } case "$1" in '') echo "$0: No files given. Try '$0 --help' for more information." 1>&2 exit 1 ;; --basedir) basedir=$2 shift 2 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . EOF exit $? ;; -v|--v*) echo "ylwrap $scriptversion" exit $? ;; esac # The input. input=$1 shift # We'll later need for a correct munging of "#line" directives. input_sub_rx=`get_dirname "$input" | quote_for_sed` case $input in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input=`pwd`/$input ;; esac input_rx=`get_dirname "$input" | quote_for_sed` # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot=false if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot=true fi # The parser itself, the first file, is the destination of the .y.c # rule in the Makefile. parser=$1 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for # instance, we rename #include "y.tab.h" into #include "parse.h" # during the conversion from y.tab.c to parse.c. sed_fix_filenames= # Also rename header guards, as Bison 2.7 for instance uses its header # guard in its implementation file. sed_fix_header_guards= while test $# -ne 0; do if test x"$1" = x"--"; then shift break fi from=$1 # Handle y_tab.c and y_tab.h output by DOS if $y_tab_nodot; then case $from in "y.tab.c") from=y_tab.c;; "y.tab.h") from=y_tab.h;; esac fi shift to=$1 shift sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" done # The program to run. prog=$1 shift # Make any relative path in $prog absolute. case $prog in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog=`pwd`/$prog ;; esac dirname=ylwrap$$ do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 mkdir $dirname || exit 1 cd $dirname case $# in 0) "$prog" "$input" ;; *) "$prog" "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then for from in * do to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend '../'. case $to in [\\/]* | ?:[\\/]*) target=$to;; *) target=../$to;; esac # Do not overwrite unchanged header files to avoid useless # recompilations. Always update the parser itself: it is the # destination of the .y.c rule in the Makefile. Divert the # output of all other files to a temporary file so we can # compare them to existing versions. if test $from != $parser; then realtarget=$target target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` fi # Munge "#line" or "#" directives. Don't let the resulting # debug information point at an absolute srcdir. Use the real # output file name, not yy.lex.c for instance. Adjust the # include guards too. sed -e "/^#/!b" \ -e "s|$input_rx|$input_sub_rx|" \ -e "$sed_fix_filenames" \ -e "$sed_fix_header_guards" \ "$from" >"$target" || ret=$? # Check whether files must be updated. if test "$from" != "$parser"; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$to is unchanged" rm -f "$target" else echo "updating $to" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the parser. This is a # blatant hack to let us support using "yacc -d". If -d is not # specified, don't fail when the header file is "missing". if test "$from" = "$parser"; then ret=1 fi fi done fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-3.24.2/LICENSE0000644000000000000000000012635415010704253014373 0ustar00rootroot00000000000000This file contains a copy of: 1) The GNU General Public License version 3 1) The Commercial Open Source License (COSL) ---------------------------------------------------------------------------- CFEngine is provided under the terms of the GNU General Public License version 3 (below), with explicit permission to link with the OpenSSL library, BerkeleyDB library and PCRE2 library. On some systems, code under the Frontier Artistic License (/libcompat/snprintf) might become compiled. This is compatible with the GPL. Users of the software may, at their option, choose the COSL license below as part of the enterprise CFEngine product. ---------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ------------------------------------------------------------------------------ COMMERCIAL OPEN SOURCE LICENSE This CFEngine commercial open source license ("COSL") is entered into between Northern.tech AS, a Norwegian company, as licensor and a) the Customer entity stipulated on a complete agreement front page (“Front pageâ€), b) any entity or natural person downloading, installing or taking the Software or any part of it into use, or c) any entity or person who otherwise has agreed to be bound by these terms (collectively the "Licensee"). 1 LICENSE 1.1 General The Software is licensed on a consecutive basis (rental) or perpetually, as stipulated on the Front page. See 1.2 and 1.3 below respectively. The following shall apply to either type of license grants. Subject to the terms of this COSL and other agreement between the parties, Northern.tech hereby grants to Licensee a non-exclusive, non-transferable, non-sublicensable and limited license to install, use, study and modify the number of copies of the Software on the number of Instances stipulated on the Front page for use within its organization. The number of Instances the Software may be installed on may be changed by the Customer from time to time, provided ample notice is given to Northern.tech. See Front page for reporting. The Licensee may modify, adapt and create derivative works based upon the Software, for use within its organisation and for sharing between other consecutive licensees under the COSL. Therefore, the Licensee shall have access to the source code of the Software. However, the Licensee shall not reproduce, distribute, resell, rent, lease or disclose the Software in any manner or form to any other third party not holding a COSL to the Software. Licensee may not transfer any of its rights under this COSL without the prior and express written consent of Northern.tech. Any CFEngine software component used by both the CFEngine enterprise version and CFEngine community edition is licensed under the terms of this COSL if the Licensee does not state in writing to Northern.tech that the Licensee instead wish to license the component in question under the GNU General Public License (GPL) v.3.0 or other applicable license. Third party software is licensed under the license of such third party. 1.2 Consecutive license grant (subscription) If the license grant is agreed to be consecutive (see stipulation on Front page), it shall be effective for the period the consecutive license fee (subscription fee) is paid and this license is otherwise complied to. The payment of the consecutive license fee entitles the Customer to Updates and New versions of the Software (as stipulated in appendix 1). 1.3 Perpetual license grant If the license grant is agreed to be perpetual (see stipulation on Front page), the grant is for ever, provided the license terms are complied to. The perpetual license grant is limited to current the version of the Software at the Effective date. Updates or New versions of the Software are not included, unless stated on the Front page (subject to additional fee). 2 DEFINITIONS The following definitions shall apply to the COSL: “Instances†means each physical or virtual computer (server or client), onto which an installation of the Software takes place. “New version†(of the Software) means a new edition of the Software containing functionality or properties not present in the previous edition of the Software. "Software" means: a) the CFEngine Enterprise data centre administration software downloaded by the Licensee or otherwise given access to including bundled documentation and other material, as described at http://www.cfengine.com/; and b) new versions and updates to such software provided by Northern.tech, and “Update†(of Software) means smaller adjustments of the Software with the existing functionality, normally by way of installation of new copy of the Software. 3 FEES The Licensee shall pay a license fee per Instance the Software is installed on for the license granted herein; either: a) per time unit (as agreed) e.g. year, for consecutive license grants, or b) once, for perpetual license grants, for the number of Instances stated on the Front page, or any later adjustments. See the Front page for further details. 4 INTELLECTUAL PROPERTY RIGHTS Northern.tech and its suppliers do not by this COSL transfer any copyrights or other intellectual property rights relating to the Software to the Licensee. Such rights are protected by intellectual property legislation in the United States, Europe and other jurisdictions and by international treaty provisions. Northern.tech and its suppliers retain all rights in the Software that are not expressly granted to the Licensee through this COSL. Licensee is not allowed to remove, alter or destroy any proprietary, trademark or copyright markings or notices placed upon or contained within the Software. 5 TERMINATION Northern.tech may terminate the COSL if the Licensee fails to comply with the terms of this COSL, hereunder fails to pay the stipulated fees. In the event of such termination, the Licensee shall immediately stop using the Software, return any received media and documentation, and destroy or permanently delete any installed versions of the Software, and confirm such destruction or deletion in writing within 7 days. 6 IDEMNIFICATION If the Software (except for third party software) during the term of the license grant is held by a court of competent jurisdiction to infringe any third party intellectual property rights and the Licensee incurs loss or expense as a result of such holding, then Licenee's sole remedy shall be, and Northern.tech will, at its option: (i) obtain the right for Licensse to continue to use the Software consistent with the COSL; (ii) modify the Software so that it becomes non-infringing; (iii) replace the infringing component with a non-infringing component, or (iv) refund monies paid by Licensee under the Agreement during the prior six (6) months to the court holding (for consecutive license grants) or a forth of any perpetual license fee paid, and all Licensees rights and licenses under this Agreement shall automatically terminate. The Licensee is aware that the Software is also comprised of third party software, mostly open source software. Such third party software are subject to its individual license terms, and any claims shall be directed at the ultimate right holder to that software. Consequently Northern.tech is not liable for any defective title in such third party software. See schedule 5 for a list of software contained by the Software with related licenses. 7 NO WARRANTY To the maximum extent permitted by law, Northern.tech disclaims any warranty for the Software (except as stated in clause 6). The Software, any services and any related documentation is provided on an "as is" basis without warranty of any kind, whether express or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose or non-infringement (except as stated in clause 6). Hereunder the parties acknowledges that Northern.tech does not warrant for the performance of any data centre on which the Software runs, or the absence of any errors in the Software, and that any such errors does not constitute a contractual defect. 8 LIABILITY The liability of the parties in contract, tort (including negligence) or otherwise shall for all incidents during the entire term of the COSL be limited to a fifth of the fees paid for a perpetual license or the annual consecutive license fees paid for the Software causing the damage or loss, up to a maximum of NOK 100 000. Northern.tech or its suppliers shall not be liable for any special, incidental, indirect or consequential damages whatsoever (including, without limitation, damages for loss of business profits, lost savings, business interruption, loss of business information, personal injury, loss of privacy, loss of goodwill or any other financial loss) arising out of the use of or inability to use the Software, even if advised of the possibility of such damages. 9 THIRD-PARTY TERMS For third-party software that is made available to the Licensee by Northern.tech, the current terms of the relevant third party software supplier shall apply. cfengine-3.24.2/cf-net/0000755000000000000000000000000015010704323014525 5ustar00rootroot00000000000000cfengine-3.24.2/cf-net/Makefile.am0000644000000000000000000000305515010704253016566 0ustar00rootroot00000000000000# # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-net.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_net_la_LIBADD = ../libpromises/libpromises.la libcf_net_la_SOURCES = cf-net.c if !BUILTIN_EXTENSIONS bin_PROGRAMS = cf-net cf_net_LDADD = libcf-net.la cf_net_SOURCES = endif CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej cfengine-3.24.2/cf-net/Makefile.in0000644000000000000000000006247515010704300016603 0ustar00rootroot00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @BUILTIN_EXTENSIONS_FALSE@bin_PROGRAMS = cf-net$(EXEEXT) subdir = cf-net ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/cf3_check_proper_func.m4 \ $(top_srcdir)/m4/cf3_path_root_prog.m4 \ $(top_srcdir)/m4/cf3_with_library.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/old-autoconf.m4 $(top_srcdir)/m4/snprintf.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_gcc_flags.m4 \ $(top_srcdir)/m4/cf3_platforms.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcf_net_la_DEPENDENCIES = ../libpromises/libpromises.la am_libcf_net_la_OBJECTS = cf-net.lo libcf_net_la_OBJECTS = $(am_libcf_net_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_cf_net_OBJECTS = cf_net_OBJECTS = $(am_cf_net_OBJECTS) @BUILTIN_EXTENSIONS_FALSE@cf_net_DEPENDENCIES = libcf-net.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcf_net_la_SOURCES) $(cf_net_SOURCES) DIST_SOURCES = $(libcf_net_la_SOURCES) $(cf_net_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CORE_CFLAGS = @CORE_CFLAGS@ CORE_CPPFLAGS = @CORE_CPPFLAGS@ CORE_LDFLAGS = @CORE_LDFLAGS@ CORE_LIBS = @CORE_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETCONF = @GETCONF@ GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ GREP = @GREP@ HOSTNAME = @HOSTNAME@ INIT_D_PATH = @INIT_D_PATH@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KMEM_GROUP = @KMEM_GROUP@ LCOV = @LCOV@ LCOV_GENHTML = @LCOV_GENHTML@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBACL_CFLAGS = @LIBACL_CFLAGS@ LIBACL_CPPFLAGS = @LIBACL_CPPFLAGS@ LIBACL_LDFLAGS = @LIBACL_LDFLAGS@ LIBACL_LIBS = @LIBACL_LIBS@ LIBACL_PATH = @LIBACL_PATH@ LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@ LIBCURL_LIBS = @LIBCURL_LIBS@ LIBCURL_PATH = @LIBCURL_PATH@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBVIRT_CFLAGS = @LIBVIRT_CFLAGS@ LIBVIRT_CPPFLAGS = @LIBVIRT_CPPFLAGS@ LIBVIRT_LDFLAGS = @LIBVIRT_LDFLAGS@ LIBVIRT_LIBS = @LIBVIRT_LIBS@ LIBVIRT_PATH = @LIBVIRT_PATH@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_CPPFLAGS = @LIBXML2_CPPFLAGS@ LIBXML2_LDFLAGS = @LIBXML2_LDFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIBXML2_PATH = @LIBXML2_PATH@ LIBYAML_CFLAGS = @LIBYAML_CFLAGS@ LIBYAML_CPPFLAGS = @LIBYAML_CPPFLAGS@ LIBYAML_LDFLAGS = @LIBYAML_LDFLAGS@ LIBYAML_LIBS = @LIBYAML_LIBS@ LIBYAML_PATH = @LIBYAML_PATH@ LIPO = @LIPO@ LMDB_CFLAGS = @LMDB_CFLAGS@ LMDB_CPPFLAGS = @LMDB_CPPFLAGS@ LMDB_LDFLAGS = @LMDB_LDFLAGS@ LMDB_LIBS = @LMDB_LIBS@ LMDB_PATH = @LMDB_PATH@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_LIBS = @MYSQL_LIBS@ MYSQL_PATH = @MYSQL_PATH@ NEED_SETGID = @NEED_SETGID@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_CPPFLAGS = @OPENSSL_CPPFLAGS@ OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OPENSSL_PATH = @OPENSSL_PATH@ OS_ENVIRONMENT_PATH = @OS_ENVIRONMENT_PATH@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_CFLAGS = @PAM_CFLAGS@ PAM_CPPFLAGS = @PAM_CPPFLAGS@ PAM_LDFLAGS = @PAM_LDFLAGS@ PAM_LIBS = @PAM_LIBS@ PAM_PATH = @PAM_PATH@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE2_CFLAGS = @PCRE2_CFLAGS@ PCRE2_CPPFLAGS = @PCRE2_CPPFLAGS@ PCRE2_LDFLAGS = @PCRE2_LDFLAGS@ PCRE2_LIBS = @PCRE2_LIBS@ PCRE2_PATH = @PCRE2_PATH@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLATFORM_SELINUX_POLICIES = @PLATFORM_SELINUX_POLICIES@ POSTGRESQL_CFLAGS = @POSTGRESQL_CFLAGS@ POSTGRESQL_CPPFLAGS = @POSTGRESQL_CPPFLAGS@ POSTGRESQL_LDFLAGS = @POSTGRESQL_LDFLAGS@ POSTGRESQL_LIBS = @POSTGRESQL_LIBS@ POSTGRESQL_PATH = @POSTGRESQL_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ QDBM_CFLAGS = @QDBM_CFLAGS@ QDBM_CPPFLAGS = @QDBM_CPPFLAGS@ QDBM_LDFLAGS = @QDBM_LDFLAGS@ QDBM_LIBS = @QDBM_LIBS@ QDBM_PATH = @QDBM_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSTEMD_SERVICE_PATH = @SYSTEMD_SERVICE_PATH@ SYSTEMD_SOCKET_CFLAGS = @SYSTEMD_SOCKET_CFLAGS@ SYSTEMD_SOCKET_CPPFLAGS = @SYSTEMD_SOCKET_CPPFLAGS@ SYSTEMD_SOCKET_LDFLAGS = @SYSTEMD_SOCKET_LDFLAGS@ SYSTEMD_SOCKET_LIBS = @SYSTEMD_SOCKET_LIBS@ SYSTEMD_SOCKET_PATH = @SYSTEMD_SOCKET_PATH@ TOKYOCABINET_CFLAGS = @TOKYOCABINET_CFLAGS@ TOKYOCABINET_CPPFLAGS = @TOKYOCABINET_CPPFLAGS@ TOKYOCABINET_LDFLAGS = @TOKYOCABINET_LDFLAGS@ TOKYOCABINET_LIBS = @TOKYOCABINET_LIBS@ TOKYOCABINET_PATH = @TOKYOCABINET_PATH@ VERSION = @VERSION@ XML2_CONFIG = @XML2_CONFIG@ YACC = @YACC@ YFLAGS = @YFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ acx_pthread_config = @acx_pthread_config@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enable_builtin_extensions = @enable_builtin_extensions@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ hw_cv_func_ctime_proper = @hw_cv_func_ctime_proper@ hw_cv_func_mkdir_proper = @hw_cv_func_mkdir_proper@ hw_cv_func_rename_proper = @hw_cv_func_rename_proper@ hw_cv_func_stat_proper = @hw_cv_func_stat_proper@ includedir = @includedir@ infodir = @infodir@ inputdir = @inputdir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ mandir = @mandir@ masterdir = @masterdir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ prefix = @prefix@ program_transform_name = @program_transform_name@ projlibdir = @projlibdir@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ statedir = @statedir@ subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemctl = @systemctl@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ workdir = @workdir@ # # Copyright 2021 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. # noinst_LTLIBRARIES = libcf-net.la AM_CPPFLAGS = -I$(srcdir)/../libpromises -I$(srcdir)/../libntech/libutils \ -I$(srcdir)/../libcfecompat \ -I$(srcdir)/../libcfnet \ $(OPENSSL_CPPFLAGS) \ $(PCRE2_CPPFLAGS) \ $(ENTERPRISE_CPPFLAGS) AM_CFLAGS = @CFLAGS@ \ $(OPENSSL_CFLAGS) \ $(ENTERPRISE_CFLAGS) libcf_net_la_LIBADD = ../libpromises/libpromises.la libcf_net_la_SOURCES = cf-net.c @BUILTIN_EXTENSIONS_FALSE@cf_net_LDADD = libcf-net.la @BUILTIN_EXTENSIONS_FALSE@cf_net_SOURCES = CLEANFILES = *.gcno *.gcda # # Some basic clean ups # MOSTLYCLEANFILES = *~ *.orig *.rej all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cf-net/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cf-net/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libcf-net.la: $(libcf_net_la_OBJECTS) $(libcf_net_la_DEPENDENCIES) $(EXTRA_libcf_net_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcf_net_la_OBJECTS) $(libcf_net_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cf-net$(EXEEXT): $(cf_net_OBJECTS) $(cf_net_DEPENDENCIES) $(EXTRA_cf_net_DEPENDENCIES) @rm -f cf-net$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cf_net_OBJECTS) $(cf_net_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cf-net.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-3.24.2/cf-net/cf-net.c0000644000000000000000000006761615010704253016067 0ustar00rootroot00000000000000/* Copyright 2024 Northern.tech AS This file is part of CFEngine 3 - written and maintained by Northern.tech AS. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA To the extent this program is licensed as part of the Enterprise versions of CFEngine, the applicable Commercial Open Source License (COSL) may apply to this file if you as a licensee so wish it. See included file COSL.txt. */ #define CF_NET_VERSION "0.1.2" #include #include #include #include // ServerConnection #include // Log, LogSetGlobalLevel #include // ManPageWrite #include // CryptoInitialize #include // ParseHostPort #include // SocketConnect() SendTransaction() #include // time_t, time, difftime #include // ToLowerStrInplace #include #include // PolicyServerReadFile #include // GenericAgentSetDefaultDigest TODO: rm dep #include // TODO: move this out of libpromises #include // TODO: move this 'out of libpromises #include #include #include #define ARG_UNUSED __attribute__((unused)) typedef struct { bool debug; bool verbose; bool inform; bool used_default; char *min_tls_version; char *allow_ciphers; } CFNetOptions; //******************************************************************* // DOCUMENTATION / GETOPT CONSTS: //******************************************************************* static const char *const CF_NET_SHORT_DESCRIPTION = "Command-Line Interface (CLI) for libcfnet."; static const char *const CF_NET_MANPAGE_LONG_DESCRIPTION = "cf-net is a testing/debugging tool intended for developers as well " "as CFEngine users. cf-net connects to cf-serverd on a specified host " "and can issue arbitrary CFEngine protocol commands. Currently 4 " "commands are supported; connect, stat, opendir and get. This tool can " "be useful to check if a host is online, see if you can fetch policy or " "even stress test the host by running many instances of cf-net. " "cf-net is much more lightweight and easy to use than cf-agent, as it " "does not include any policy functionality. Please note that in order to " "connect to a host cf-net needs access to the key-pair generated by " "cf-key. For now, it is much easier to use cf-net on a bootstrapped " "host. This is due to ACLs and key-pairs and can be made easier in the " "future."; static const Component COMPONENT = { .name = "cf-net", .website = CF_WEBSITE, .copyright = CF_COPYRIGHT }; static const Description COMMANDS[] = { {"help", "Prints general help or per topic", "cf-net help [command]"}, {"connect", "Checks if host(s) is available by connecting", "cf-net -H 192.168.50.50,192.168.50.51 connect"}, {"stat", "Look at type of file", "cf-net stat masterfiles/update.cf"}, {"get", "Get file from server", "cf-net get masterfiles/update.cf -o download.cf [-jNTHREADS]\n" "\t\t\t(%d can be used in both the remote and output file paths when '-j' is used)"}, {"opendir", "List files and folders in a directory", "cf-net opendir masterfiles"}, {NULL, NULL, NULL} }; static const struct option OPTIONS[] = { {"help", no_argument, 0, 'h'}, {"manpage", no_argument, 0, 'M'}, {"host", required_argument, 0, 'H'}, {"debug", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"log-level", required_argument, 0, 'g'}, {"inform", no_argument, 0, 'I'}, {"tls-version", required_argument, 0, 't'}, {"ciphers", required_argument, 0, 'c'}, {NULL, 0, 0, '\0'} }; static const char *const HINTS[] = { "Print the help message", "Print the man page", "Server hostnames or IPs, comma-separated (defaults to policy server)", "Enable debugging output", "Enable verbose output", "Specify how detailed logs should be. Possible values: 'error', 'warning', 'notice', 'info', 'verbose', 'debug'", "Enable basic information output", "Minimum TLS version to use", "TLS ciphers to use (comma-separated list)", NULL }; //******************************************************************* // COMMAND ENUMS: //******************************************************************* #define CF_NET_COMMANDS(generator_macro) \ generator_macro(CONNECT) \ generator_macro(STAT) \ generator_macro(GET) \ generator_macro(OPENDIR) \ generator_macro(MULTI) \ generator_macro(MULTITLS) \ generator_macro(HELP) \ generator_macro(INVALID) \ #define GENERATE_ENUM(CMD_NAME) CFNET_CMD_##CMD_NAME, #define GENERATE_STRING(CMD_NAME) #CMD_NAME, enum command_enum { CF_NET_COMMANDS(GENERATE_ENUM) command_enum_max }; static const char *command_strings[] = { CF_NET_COMMANDS(GENERATE_STRING) NULL }; //******************************************************************* // FUNCTION DECLARATIONS: //******************************************************************* // INIT: static void CFNetSetDefault(CFNetOptions *opts); static void CFNetInit(const char *min_tls_version, const char *allow_ciphers); static void CFNetOptionsClear(CFNetOptions *opts); // MAIN LOGIC: static int CFNetParse(int argc, char **argv, // INPUTS CFNetOptions *opts, char ***args, char **hostnames); // OUTPUTS static int CFNetCommandSwitch(CFNetOptions *opts, const char *hostname, char **args, enum command_enum cmd); static int CFNetRun(CFNetOptions *opts, char **args, char *hostnames); static char *RequireHostname(char *hostnames); // PROTOCOL: static AgentConnection *CFNetOpenConnection(const char *server); static void CFNetDisconnect(AgentConnection *conn); static int JustConnect(const char *server, char *port); // COMMANDS: static int CFNetHelpTopic(const char *topic); static int CFNetHelp(const char *topic); static int CFNetConnectSingle(const char *server, bool print); static int CFNetConnect(const char *hostname, char **args); static void CFNetStatPrint(const char *file, int st_mode, const char *server); static int CFNetStat(CFNetOptions *opts, const char *hostname, char **args); static int CFNetGet(CFNetOptions *opts, const char *hostname, char **args); static int CFNetOpenDir(CFNetOptions *opts, const char *hostname, char **args); static int CFNetMulti(const char *server); static int CFNetMultiTLS(const char *server); //******************************************************************* // MAIN: //******************************************************************* int main(int argc, char **argv) { CFNetOptions opts; CFNetSetDefault(&opts); char **args = NULL; char *hostnames = NULL; int ret = CFNetParse(argc, argv, // Inputs &opts, &args, &hostnames); // Outputs GenericAgentSetDefaultDigest(&CF_DEFAULT_DIGEST, &CF_DEFAULT_DIGEST_LEN); if (ret != 0) { DoCleanupAndExit(EXIT_FAILURE); } ret = CFNetRun(&opts, args, hostnames); // Commands return exit code free(hostnames); CFNetOptionsClear(&opts); ret = (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; DoCleanupAndExit(ret); } //******************************************************************* // INIT: //******************************************************************* static void CFNetSetDefault(CFNetOptions *opts){ assert(opts != NULL); opts->debug = false; opts->verbose = false; opts->inform = false; opts->used_default= false; opts->min_tls_version = NULL; opts->allow_ciphers = NULL; } static void CFNetOptionsClear(CFNetOptions *opts) { assert(opts != NULL); free(opts->min_tls_version); free(opts->allow_ciphers); } static void CFNetInit(const char *min_tls_version, const char *allow_ciphers) { #ifdef __MINGW32__ InitializeWindows(); OpenNetwork(); #endif CryptoInitialize(); LoadSecretKeys(NULL, NULL, NULL, NULL); cfnet_init(min_tls_version, allow_ciphers); } //******************************************************************* // MAIN LOGIC: //******************************************************************* static char *RequireHostname(char *hostnames) { if (hostnames == NULL) { char *policy_server = PolicyServerReadFile(GetWorkDir()); if (policy_server == NULL) { printf("Error: no host name (and no policy_server.dat)\n"); DoCleanupAndExit(EXIT_FAILURE); } return policy_server; } return xstrdup(hostnames); } static int CFNetParse(int argc, char **argv, CFNetOptions *opts, char ***args, char **hostnames) { assert(opts != NULL); if (argc <= 1) { CFNetHelp(NULL); return 0; } extern int optind; extern char *optarg; *hostnames = NULL; int c = 0; int start_index = 1; const char *optstr = "+hMg:H:dvI"; // + means stop for non opt arg. :) while ((c = getopt_long(argc, argv, optstr, OPTIONS, &start_index)) != -1) { switch (c) { case 'h': { CFNetHelp(NULL); break; } case 'M': { // TODO: How do we actually add a man page Writer *out = FileWriter(stdout); ManPageWrite(out, "cf-net", time(NULL), CF_NET_SHORT_DESCRIPTION, CF_NET_MANPAGE_LONG_DESCRIPTION, OPTIONS, HINTS, COMMANDS, false, true); FileWriterDetach(out); DoCleanupAndExit(EXIT_SUCCESS); break; } case 'H': { if (*hostnames != NULL) { Log(LOG_LEVEL_INFO, "Warning: multiple occurences of -H in command, "\ "only last one will be used."); free(*hostnames); } *hostnames = xstrdup(optarg); break; } case 'd': { opts->debug = true; break; } case 'v': { opts->verbose = true; break; } case 'I': { opts->inform = true; break; } case 'g': { LogSetGlobalLevelArgOrExit(optarg); break; } case 't': { opts->min_tls_version = xstrdup(optarg); break; } case 'c': { opts->allow_ciphers = xstrdup(optarg); break; } default: { // printf("Default optarg = '%s', c = '%c' = %i\n", // optarg, c, (int)c); DoCleanupAndExit(EXIT_FAILURE); break; } } } (*args) = &(argv[optind]); return 0; } // This converts a command string to an enum: "HELP" -> HELP static int CFNetCommandNumber(char *command) { for (int i = 0; i < command_enum_max; ++i) { if (strcmp(command, command_strings[i]) == 0) { return i; } } return CFNET_CMD_INVALID; } // ^ Macro returns on match(!) static int CFNetCommandSwitch(CFNetOptions *opts, const char *hostname, char **args, enum command_enum cmd) { switch (cmd) { case CFNET_CMD_CONNECT: return CFNetConnect(hostname, args); case CFNET_CMD_STAT: return CFNetStat(opts, hostname, args); case CFNET_CMD_GET: return CFNetGet(opts, hostname, args); case CFNET_CMD_OPENDIR: return CFNetOpenDir(opts, hostname, args); case CFNET_CMD_MULTI: return CFNetMulti(hostname); case CFNET_CMD_MULTITLS: return CFNetMultiTLS(hostname); default: break; } printf("Bug: CFNetCommandSwitch() is unable to pick a command\n"); DoCleanupAndExit(EXIT_FAILURE); return -1; } static void CFNetSetVerbosity(CFNetOptions *opts) { assert(opts); if(opts->debug) { LogSetGlobalLevel(LOG_LEVEL_DEBUG); Log(LOG_LEVEL_DEBUG, "Debug log level enabled"); } else if(opts->verbose) { LogSetGlobalLevel(LOG_LEVEL_VERBOSE); Log(LOG_LEVEL_VERBOSE, "Verbose log level enabled"); } else if(opts->inform) { LogSetGlobalLevel(LOG_LEVEL_INFO); Log(LOG_LEVEL_INFO, "Inform log level enabled"); } } static int CFNetRun(CFNetOptions *opts, char **args, char *hostnames) { assert(opts != NULL); assert(args != NULL); CFNetSetVerbosity(opts); char *command_name = args[0]; if (NULL_OR_EMPTY(command_name)) { printf("Error: Command missing, use cf-net --help for more info.\n"); DoCleanupAndExit(EXIT_FAILURE); } ToUpperStrInplace(command_name); Log(LOG_LEVEL_VERBOSE, "Running command '%s' with argument(s):\n", command_name); for (int i = 1; args[i] != NULL; ++i) { Log(LOG_LEVEL_VERBOSE, "argv[%i]=%s\n", i, args[i]); } enum command_enum cmd = CFNetCommandNumber(command_name); if (cmd == CFNET_CMD_INVALID) { Log(LOG_LEVEL_ERR, "'%s' is not a valid cf-net command\n", args[0]); return -1; } else if (cmd == CFNET_CMD_HELP) { return CFNetHelp(args[1]); } CFNetInit(opts->min_tls_version, opts->allow_ciphers); char *hosts = RequireHostname(hostnames); int ret = 0; char *hostname = strtok(hosts, ","); while (hostname != NULL){ CFNetCommandSwitch(opts, hostname, args, cmd); hostname = strtok(NULL, ","); } free(hosts); return ret; } //******************************************************************* // PROTOCOL: //******************************************************************* static AgentConnection *CFNetOpenConnection(const char *server) { AgentConnection *conn = NULL; ConnectionFlags connflags = { .protocol_version = CF_PROTOCOL_LATEST, .trust_server = true, .off_the_record = true }; int err; char *buf = xstrdup(server); char *host, *port; ParseHostPort(buf, &host, &port); if (port == NULL) { port = CFENGINE_PORT_STR; } conn = ServerConnection(host, port, NULL, 30, connflags, &err); free(buf); if (conn == NULL) { printf("Failed to connect to '%s'\n", server); return NULL; } return conn; } static int JustConnect(const char *server, char *port) { char txtaddr[CF_MAX_IP_LEN] = ""; return SocketConnect(server, port, 100, true, txtaddr, sizeof(txtaddr)); } //******************************************************************* // COMMANDS: //******************************************************************* static int CFNetHelpTopic(const char *topic) { assert(topic != NULL); bool found = false; for (int i = 0; COMMANDS[i].name != NULL; ++i) { if (strcmp(COMMANDS[i].name, topic) == 0) { printf("Command: %s\n", COMMANDS[i].name); printf("Usage: %s\n", COMMANDS[i].usage); printf("Description: %s\n", COMMANDS[i].description); found = true; break; } } // Add more detailed explanation here if necessary: if (strcmp("help", topic) == 0) { printf("\nYou did it, you used the help command!\n"); } else if (strcmp("stat", topic) == 0) { printf("\nFor security reasons the server doesn't give any additional" "\ninformation if unsuccessful. 'Could not stat' message can" "\nindicate wrong path, the file doesn't exist, permission " "\ndenied, or something else.\n"); } else if (strcmp("get", topic) == 0) { printf("\ncf-net get is comprised of two requests, STAT and GET." "\nThe CFEngine GET protocol command requires a STAT first to" "\ndetermine file size. By default the file is saved as its" "\nbasename in current working directory (cwd). Override this" "\nusing the -o filename option (-o - for stdout).\n"); } else { if (found == false) { printf("Unknown help topic: '%s'\n", topic); return -1; } } return 0; } static int CFNetHelp(const char *topic) { if (topic != NULL) { CFNetHelpTopic(topic); } else { Writer *w = FileWriter(stdout); WriterWriteHelp(w, &COMPONENT, OPTIONS, HINTS, COMMANDS, false, false); FileWriterDetach(w); DoCleanupAndExit(EXIT_SUCCESS); } return 0; } static int CFNetConnectSingle(const char *server, bool print) { AgentConnection *conn = CFNetOpenConnection(server); if (conn == NULL) { return -1; } if (print == true) { printf("Connected & authenticated successfully to '%s'\n", server); } CFNetDisconnect(conn); return 0; } static int CFNetConnect(const char *hostname, char **args) { assert(args != NULL); if (args[1] != NULL) { Log(LOG_LEVEL_ERR, "connect does not take any arguments\n"\ "(See cf-net --help)"); return -1; } if (NULL_OR_EMPTY(hostname)) { Log(LOG_LEVEL_ERR, "No hostname specified"); return -1; } CFNetConnectSingle(hostname, true); return 0; } static void CFNetDisconnect(AgentConnection *conn) { DisconnectServer(conn); } static void CFNetStatPrint(const char *file, int st_mode, const char *server) { printf("%s:", server); if (S_ISDIR(st_mode)) { printf("'%s' is a directory\n", file); } else if (S_ISREG(st_mode)) { printf("'%s' is a regular file\n", file); } else if (S_ISSOCK(st_mode)) { printf("'%s' is a socket\n", file); } else if (S_ISCHR(st_mode)) { printf("'%s' is a character device file\n", file); } else if (S_ISBLK(st_mode)) { printf("'%s' is a block device file\n", file); } else if (S_ISFIFO(st_mode)) { printf("'%s' is a named pipe (FIFO)\n", file); } else if (S_ISLNK(st_mode)) { printf("'%s' is a symbolic link\n", file); } else { printf("'%s' has an unrecognized st_mode\n", file); } } static int CFNetStat(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **args) { assert(opts); char *file = args[1]; AgentConnection *conn = CFNetOpenConnection(hostname); if (conn == NULL) { return -1; } struct stat sb; bool ret = ProtocolStat(conn, file, &sb); if (!ret) { printf("Could not stat: '%s'\n", file); } else { Log(LOG_LEVEL_INFO, "Detailed stat output:\n" "mode = %jo, \tsize = %jd,\n" "uid = %ju, \tgid = %ju,\n" "atime = %jd, \tmtime = %jd\n", (uintmax_t) sb.st_mode, (intmax_t) sb.st_size, (uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid, (intmax_t) sb.st_atime, (intmax_t) sb.st_mtime); CFNetStatPrint(file, sb.st_mode, hostname); } CFNetDisconnect(conn); return 0; } static int invalid_command(const char *cmd) { Log(LOG_LEVEL_ERR, "Invalid, see: 'cf-net help %s' for more info\n", cmd); return -1; } typedef struct _GetFileData { const char *hostname; char remote_file[PATH_MAX]; char local_file[PATH_MAX]; bool ret; } GetFileData; static void *CFNetGetFile(void *arg) { GetFileData *data = (GetFileData *) arg; AgentConnection *conn = CFNetOpenConnection(data->hostname); if (conn == NULL) { data->ret = false; return NULL; } data->ret = ProtocolStatGet(conn, data->remote_file, data->local_file, 0644); if (!data->ret) { printf("Could not stat: '%s'\n", data->remote_file); } CFNetDisconnect(conn); return NULL; } typedef struct _CFNetThreadData { pthread_t id; GetFileData *data; } CFNetThreadData; static int CFNetGet(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **args) { assert(opts); assert(hostname); assert(args); char *local_file = NULL; // TODO: Propagate argv and argc from main() int argc = 0; while (args[argc] != NULL) { ++argc; } static struct option longopts[] = { { "output", required_argument, NULL, 'o' }, { "jobs", required_argument, NULL, 'j' }, { NULL, 0, NULL, 0 } }; assert(opts != NULL); if (argc <= 1) { return invalid_command("get"); } extern int optind; optind = 0; extern char *optarg; int c = 0; // TODO: Experiment with more user friendly leading - optstring const char *optstr = "o:j:"; bool specified_path = false; long n_threads = 1; while ((c = getopt_long(argc, args, optstr, longopts, NULL)) != -1) { switch (c) { case 'o': { if (local_file != NULL) { Log(LOG_LEVEL_INFO, "Warning: multiple occurences of -o in command, "\ "only last one will be used."); free(local_file); } local_file = xstrdup(optarg); specified_path = true; break; } case 'j': { int ret = StringToLong(optarg, &n_threads); if (ret != 0) { printf("Failed to parse number of threads/jobs from '%s'\n", optarg); n_threads = 1; } break; } case ':': { return invalid_command("get"); break; } case '?': { return invalid_command("get"); break; } default: { printf("Default optarg = '%s', c = '%c' = %i\n", optarg, c, (int)c); break; } } } args = &(args[optind]); argc -= optind; char *remote_file = args[0]; if(local_file == NULL) { local_file = xstrdup(basename(remote_file)); } if (specified_path && strcmp(local_file, "-") == 0) { // TODO: Should rewrite CopyRegularFileNet etc. to take fd argument // and a simple helper function to open a file as well. printf("Output to stdout not yet implemented (TODO)\n"); free(local_file); return -1; } CFNetThreadData **threads = (CFNetThreadData**) xcalloc((size_t) n_threads, sizeof(CFNetThreadData*)); for (int i = 0; i < n_threads; i++) { threads[i] = (CFNetThreadData*) xcalloc(1, sizeof(CFNetThreadData)); threads[i]->data = (GetFileData*) xcalloc(1, sizeof(GetFileData)); threads[i]->data->hostname = hostname; if (n_threads > 1) { if (strstr(local_file, "%d") != NULL) { snprintf(threads[i]->data->local_file, PATH_MAX, local_file, i); } else { snprintf(threads[i]->data->local_file, PATH_MAX, "%s.%d", local_file, i); } if (strstr(remote_file, "%d") != NULL) { snprintf(threads[i]->data->remote_file, PATH_MAX, remote_file, i); } else { snprintf(threads[i]->data->remote_file, PATH_MAX, "%s", remote_file); } } else { snprintf(threads[i]->data->local_file, PATH_MAX, "%s", local_file); snprintf(threads[i]->data->remote_file, PATH_MAX, "%s", remote_file); } } bool failure = false; for (int i = 0; !failure && (i < n_threads); i++) { int ret = pthread_create(&(threads[i]->id), NULL, CFNetGetFile, threads[i]->data); if (ret != 0) { printf("Failed to create a new thread to get the file in: %s\n", strerror(ret)); failure = true; } } for (int i = 0; i < n_threads; i++) { int ret = pthread_join(threads[i]->id, NULL); if (ret != 0) { printf("Failed to join the thread: %s\n", strerror(ret)); } else { failure = failure && !threads[i]->data->ret; } } for (int i = 0; i < n_threads; i++) { free(threads[i]->data); free(threads[i]); } free(threads); free(local_file); return failure ? -1 : 0; } static void PrintDirs(const Seq *list) { for (size_t i = 0; i < SeqLength(list); i++) { char *dir_entry = SeqAt(list, i); printf("%s\n", dir_entry); } } static int CFNetOpenDir(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **args) { assert(opts); assert(hostname); assert(args); AgentConnection *conn = CFNetOpenConnection(hostname); if (conn == NULL) { return -1; } // TODO: Propagate argv and argc from main() int argc = 1; while (args[argc] != NULL) { ++argc; } if (argc <= 1) { return invalid_command("opendir"); } const char *remote_path = args[1]; Seq *seq = ProtocolOpenDir(conn, remote_path); if (seq == NULL) { return -1; } PrintDirs(seq); SeqDestroy(seq); CFNetDisconnect(conn); return 0; } static int CFNetMulti(const char *server) { time_t start; time(&start); int ret = 0; int attempts = 0; printf("Connecting repeatedly to '%s' without handshakes\n",server); attempts = 0; char *buf = xstrdup(server); char *host, *port; ParseHostPort(buf, &host, &port); if (port == NULL) { port = CFENGINE_PORT_STR; } ret = 0; while(ret != 1) { ret = JustConnect(host, port); attempts++; } free(buf); printf("Server unavailable after %i attempts\n", attempts); time_t stop; time(&stop); double seconds = difftime(stop,start); printf("'%s' unavailable after %.f seconds (%i attempts)\n", server, seconds, attempts); return 0; } static int CFNetMultiTLS(const char *server) { time_t start; time(&start); printf("Multiple handshakes to '%s'\n", server); int ret = 0; int attempts = 0; while(ret == 0) { ret = CFNetConnectSingle(server, false); ++attempts; } time_t stop; time(&stop); double seconds = difftime(stop,start); printf("'%s' unavailable after %.f seconds (%i attempts)\n", server, seconds, attempts); CFNetMulti(server); return 0; }